[pnetcdf] 01/08: upstream 1.7.0pre1
Alastair McKinstry
mckinstry at moszumanska.debian.org
Sun Jan 24 09:06:30 UTC 2016
This is an automated email from the git hooks/post-receive script.
mckinstry pushed a commit to branch debian/master
in repository pnetcdf.
commit 4ada7d7360ae92b1600180a3246891f415ec882f
Author: Alastair McKinstry <mckinstry at debian.org>
Date: Sun Jan 17 04:11:42 2016 +0000
upstream 1.7.0pre1
---
COPYRIGHT | 34 +
CREDITS | 34 +
INSTALL | 319 +
Makefile.in | 242 +
README | 55 +
README.CRAY | 110 +
README.IBM | 269 +
README.LINUX | 62 +
README.SGI | 46 +
README.SX | 37 +
README.large_files | 48 +
RELEASE_NOTES | 859 ++
aclocal.m4 | 1727 +++
benchmarks/C/Makefile.in | 59 +
benchmarks/C/aggregation.c | 592 +
benchmarks/C/depend | 2 +
benchmarks/C/write_block_read_column.c | 401 +
benchmarks/FLASH-IO/Makefile.in | 93 +
benchmarks/FLASH-IO/README | 81 +
benchmarks/FLASH-IO/block_boundary_data.fh | 83 +
benchmarks/FLASH-IO/checkpoint_ncmpi_parallel.F90 | 639 +
benchmarks/FLASH-IO/common.fh | 58 +
benchmarks/FLASH-IO/configure.in | 225 +
benchmarks/FLASH-IO/definitions.fh | 98 +
benchmarks/FLASH-IO/flash_benchmark_io.F90 | 273 +
benchmarks/FLASH-IO/flash_release.F90 | 10 +
benchmarks/FLASH-IO/get_mfluid_property.F90 | 34 +
benchmarks/FLASH-IO/numfluids.fh | 3 +
benchmarks/FLASH-IO/physicaldata.fh | 196 +
benchmarks/FLASH-IO/plotfile_ncmpi_parallel.F90 | 698 +
benchmarks/FLASH-IO/tree.fh | 144 +
benchmarks/Makefile.in | 54 +
benchmarks/README | 29 +
cobalt.script | 16 +
configure | 15165 ++++++++++++++++++++
configure.in | 1269 ++
doc/Makefile.in | 45 +
doc/c_api.tex | 203 +
doc/data_mode_api.tex | 513 +
doc/flexible_api.tex | 73 +
doc/latex8.sty | 175 +
doc/multiple_io.tex | 152 +
doc/nonblocking.tex | 362 +
doc/pnetcdf-api.bbl | 10 +
doc/pnetcdf-api.tex | 655 +
doc/porting_notes.txt | 50 +
doc/symbol_renaming.txt | 23 +
examples/C/Makefile.in | 162 +
examples/C/block_cyclic.c | 301 +
examples/C/bput_varn_uint.c | 347 +
examples/C/collective_write.c | 231 +
examples/C/column_wise.c | 222 +
examples/C/create_open.c | 105 +
examples/C/depend | 22 +
examples/C/fill_mode.c | 206 +
examples/C/flexible_api.c | 272 +
examples/C/get_info.c | 145 +
examples/C/get_vara.c | 188 +
examples/C/ghost_cell.c | 206 +
examples/C/global_attributes.c | 186 +
examples/C/hints.c | 196 +
examples/C/i_varn_int64.c | 371 +
examples/C/mput.c | 232 +
examples/C/nonblocking_write.c | 276 +
examples/C/nonblocking_write_in_def.c | 268 +
examples/C/put_vara.c | 194 +
examples/C/put_varn_float.c | 218 +
examples/C/put_varn_int.c | 219 +
examples/C/req_all.c | 185 +
examples/C/transpose.c | 235 +
examples/C/vard_int.c | 192 +
examples/CXX/Makefile.in | 130 +
examples/CXX/block_cyclic.cpp | 301 +
examples/CXX/collective_write.cpp | 217 +
examples/CXX/column_wise.cpp | 200 +
examples/CXX/depend | 14 +
examples/CXX/fill_mode.cpp | 213 +
examples/CXX/flexible_api.cpp | 228 +
examples/CXX/get_info.cpp | 137 +
examples/CXX/get_vara.cpp | 190 +
examples/CXX/hints.cpp | 212 +
examples/CXX/nonblocking_write.cpp | 262 +
examples/CXX/put_vara.cpp | 180 +
examples/CXX/put_varn_float.cpp | 222 +
examples/CXX/put_varn_int.cpp | 223 +
examples/CXX/transpose.cpp | 226 +
examples/CXX/vard_int.cpp | 209 +
examples/F77/Makefile.in | 135 +
examples/F77/block_cyclic.f | 284 +
examples/F77/bput_varn_int8.f | 344 +
examples/F77/column_wise.f | 196 +
examples/F77/depend | 14 +
examples/F77/fill_mode.f | 227 +
examples/F77/flexible_api.f | 194 +
examples/F77/get_info.f | 141 +
examples/F77/hints.f | 251 +
examples/F77/i_varn_real.f | 323 +
examples/F77/nonblocking_write.f | 204 +
examples/F77/put_vara.f | 159 +
examples/F77/put_varn_int.f | 257 +
examples/F77/put_varn_real.f | 261 +
examples/F77/transpose.f | 290 +
examples/F77/utils.F90 | 53 +
examples/F77/vard_int.F | 233 +
examples/F90/Makefile.in | 123 +
examples/F90/block_cyclic.f90 | 278 +
examples/F90/column_wise.f90 | 186 +
examples/F90/depend | 12 +
examples/F90/fill_mode.f90 | 218 +
examples/F90/flexible_api.f90 | 182 +
examples/F90/get_info.f90 | 139 +
examples/F90/hints.f90 | 248 +
examples/F90/nonblocking_write.f90 | 197 +
examples/F90/put_var.f90 | 152 +
examples/F90/put_varn_int.f90 | 259 +
examples/F90/put_varn_real.f90 | 253 +
examples/F90/transpose.f90 | 235 +
examples/F90/utils.F90 | 53 +
examples/F90/vard_int.f90 | 225 +
examples/Makefile.in | 72 +
examples/README | 322 +
examples/tutorial/Makefile.in | 114 +
examples/tutorial/depend | 14 +
examples/tutorial/pnetcdf-permute.c | 158 +
examples/tutorial/pnetcdf-read-flexible.c | 127 +
examples/tutorial/pnetcdf-read-from-master.c | 159 +
examples/tutorial/pnetcdf-read-nb.c | 150 +
examples/tutorial/pnetcdf-read-nfiles.c | 137 +
examples/tutorial/pnetcdf-read-standard.c | 126 +
examples/tutorial/pnetcdf-write-buffered.c | 129 +
examples/tutorial/pnetcdf-write-bufferedf.f90 | 147 +
examples/tutorial/pnetcdf-write-bufferedf77.f | 149 +
examples/tutorial/pnetcdf-write-flexible.c | 111 +
examples/tutorial/pnetcdf-write-from-master.c | 117 +
examples/tutorial/pnetcdf-write-nb.c | 126 +
examples/tutorial/pnetcdf-write-nfiles.c | 218 +
examples/tutorial/pnetcdf-write-standard.c | 108 +
macros.make.in | 138 +
man/Makefile.in | 60 +
man/pnetcdf.m4 | 1269 ++
man/pnetcdf_f90.m4 | 768 +
pbs.script | 18 +
rules.make | 260 +
scripts/Makefile.in | 24 +
scripts/config.guess | 1519 ++
scripts/config.sub | 1767 +++
scripts/install-sh | 527 +
src/Makefile.in | 49 +
src/lib/Makefile.in | 117 +
src/lib/attr.m4 | 1282 ++
src/lib/bput.m4 | 551 +
src/lib/convert_swap.m4 | 311 +
src/lib/depend | 31 +
src/lib/dim.c | 525 +
src/lib/error.c | 761 +
src/lib/fbits.h | 26 +
src/lib/filetype.c | 967 ++
src/lib/fill.c | 523 +
src/lib/getput.m4 | 1246 ++
src/lib/header.c | 2530 ++++
src/lib/i_getput.m4 | 939 ++
src/lib/i_varn.m4 | 336 +
src/lib/m_getput_varx.m4 | 1090 ++
src/lib/macro.h | 188 +
src/lib/malloc.c | 275 +
src/lib/mpincio.c | 592 +
src/lib/mpinetcdf.c | 1183 ++
src/lib/nc.c | 1635 +++
src/lib/nc.h | 939 ++
src/lib/ncconfig.h.in | 483 +
src/lib/ncio.h | 95 +
src/lib/ncmpidtype.c | 575 +
src/lib/ncmpidtype.h | 24 +
src/lib/nctypes.h | 46 +
src/lib/ncx.h | 979 ++
src/lib/ncx.m4 | 3551 +++++
src/lib/nonblocking.c | 2201 +++
src/lib/pnetcdf.h.in | 3906 +++++
src/lib/rnd.h | 19 +
src/lib/string.c | 351 +
src/lib/subfile.c | 1109 ++
src/lib/subfile.h | 53 +
src/lib/utf8proc.c | 600 +
src/lib/utf8proc.h | 407 +
src/lib/utf8proc_data.h | 13389 +++++++++++++++++
src/lib/util.c | 92 +
src/lib/var.c | 939 ++
src/lib/vard.c | 407 +
src/lib/varn.m4 | 368 +
src/libcxx/Makefile.in | 83 +
src/libcxx/depend | 67 +
src/libcxx/ncmpiAtt.cpp | 224 +
src/libcxx/ncmpiAtt.h | 121 +
src/libcxx/ncmpiByte.cpp | 24 +
src/libcxx/ncmpiByte.h | 30 +
src/libcxx/ncmpiChar.cpp | 22 +
src/libcxx/ncmpiChar.h | 27 +
src/libcxx/ncmpiCheck.cpp | 94 +
src/libcxx/ncmpiCheck.h | 35 +
src/libcxx/ncmpiCompoundType.cpp | 156 +
src/libcxx/ncmpiCompoundType.h | 107 +
src/libcxx/ncmpiDim.cpp | 125 +
src/libcxx/ncmpiDim.h | 84 +
src/libcxx/ncmpiDouble.cpp | 22 +
src/libcxx/ncmpiDouble.h | 28 +
src/libcxx/ncmpiEnumType.cpp | 111 +
src/libcxx/ncmpiEnumType.h | 109 +
src/libcxx/ncmpiException.cpp | 308 +
src/libcxx/ncmpiException.h | 437 +
src/libcxx/ncmpiFile.cpp | 205 +
src/libcxx/ncmpiFile.h | 125 +
src/libcxx/ncmpiFloat.cpp | 22 +
src/libcxx/ncmpiFloat.h | 28 +
src/libcxx/ncmpiGroup.cpp | 1456 ++
src/libcxx/ncmpiGroup.h | 596 +
src/libcxx/ncmpiGroupAtt.cpp | 65 +
src/libcxx/ncmpiGroupAtt.h | 44 +
src/libcxx/ncmpiInt.cpp | 22 +
src/libcxx/ncmpiInt.h | 28 +
src/libcxx/ncmpiInt64.cpp | 22 +
src/libcxx/ncmpiInt64.h | 28 +
src/libcxx/ncmpiOpaqueType.cpp | 68 +
src/libcxx/ncmpiOpaqueType.h | 58 +
src/libcxx/ncmpiShort.cpp | 22 +
src/libcxx/ncmpiShort.h | 28 +
src/libcxx/ncmpiType.cpp | 179 +
src/libcxx/ncmpiType.h | 157 +
src/libcxx/ncmpiUbyte.cpp | 22 +
src/libcxx/ncmpiUbyte.h | 28 +
src/libcxx/ncmpiUint.cpp | 22 +
src/libcxx/ncmpiUint.h | 28 +
src/libcxx/ncmpiUint64.cpp | 22 +
src/libcxx/ncmpiUint64.h | 28 +
src/libcxx/ncmpiUshort.cpp | 22 +
src/libcxx/ncmpiUshort.h | 28 +
src/libcxx/ncmpiVar.cpp | 3289 +++++
src/libcxx/ncmpiVar.h | 3322 +++++
src/libcxx/ncmpiVarAtt.cpp | 63 +
src/libcxx/ncmpiVarAtt.h | 46 +
src/libcxx/ncmpiVlenType.cpp | 91 +
src/libcxx/ncmpiVlenType.h | 57 +
src/libcxx/ncmpi_notyet.cpp | 318 +
src/libcxx/ncmpi_notyet.h | 214 +
src/libcxx/pnetcdf.in | 14 +
src/libf/Makefile.in | 403 +
src/libf/buildiface | 4068 ++++++
src/libf/createffiles | 24 +
src/libf/defs | 2547 ++++
src/libf/inq_libversf.f | 10 +
src/libf/mpinetcdf_impl.h | 77 +
src/libf/nfconfig_inc.in | 91 +
src/libf/pnetcdf.inc.in | 1512 ++
src/libf/strerrorf.f | 10 +
src/libf90/Makefile.in | 84 +
src/libf90/api.f90.in | 4110 ++++++
src/libf90/attributes.f90 | 352 +
src/libf90/dims.f90 | 56 +
src/libf90/file.f90 | 331 +
src/libf90/getput_text.m4 | 251 +
src/libf90/getput_var.m4 | 678 +
src/libf90/getput_vard.m4 | 375 +
src/libf90/getput_varn.m4 | 666 +
src/libf90/nf90_constants.f90 | 302 +
src/libf90/nfmpi_constants.f90.in | 423 +
src/libf90/overloads.f90 | 693 +
src/libf90/pnetcdf.f90 | 40 +
src/libf90/variables.f90 | 229 +
src/libf90/visibility.f90 | 617 +
src/utils/Makefile.in | 34 +
src/utils/ncmpidiff/Makefile.in | 63 +
src/utils/ncmpidiff/depend | 1 +
src/utils/ncmpidiff/ncmpidiff.1 | 41 +
src/utils/ncmpidiff/ncmpidiff.c | 782 +
src/utils/ncmpidump/Makefile.in | 74 +
src/utils/ncmpidump/depend | 3 +
src/utils/ncmpidump/dumplib.c | 225 +
src/utils/ncmpidump/dumplib.h | 73 +
src/utils/ncmpidump/ncmpidump.1 | 200 +
src/utils/ncmpidump/ncmpidump.c | 823 ++
src/utils/ncmpidump/ncmpidump.h | 83 +
src/utils/ncmpidump/test0.cdl | 41 +
src/utils/ncmpidump/vardata.c | 738 +
src/utils/ncmpidump/vardata.h | 28 +
src/utils/ncmpigen/Makefile.in | 179 +
src/utils/ncmpigen/c0.cdl | 331 +
src/utils/ncmpigen/depend | 9 +
src/utils/ncmpigen/escapes.c | 96 +
src/utils/ncmpigen/generic.h | 23 +
src/utils/ncmpigen/genlib.c | 2043 +++
src/utils/ncmpigen/genlib.h | 98 +
src/utils/ncmpigen/getfill.c | 151 +
src/utils/ncmpigen/init.c | 43 +
src/utils/ncmpigen/load.c | 835 ++
src/utils/ncmpigen/main.c | 223 +
src/utils/ncmpigen/ncmpigen.1 | 373 +
src/utils/ncmpigen/ncmpigen.h | 57 +
src/utils/ncmpigen/ncmpigen.l | 216 +
src/utils/ncmpigen/ncmpigen.y | 1317 ++
src/utils/ncmpigen/ncmpigentab.c | 1919 +++
src/utils/ncmpigen/ncmpigentab.h | 30 +
src/utils/ncmpigen/ncmpigenyy.c | 2294 +++
src/utils/ncmpivalid/Makefile.in | 65 +
src/utils/ncmpivalid/depend | 1 +
src/utils/ncmpivalid/ncmpivalid.1 | 28 +
src/utils/ncmpivalid/ncmpivalid.c | 870 ++
src/utils/ncoffsets/Makefile.in | 38 +
src/utils/ncoffsets/ncoffsets.1 | 109 +
src/utils/ncoffsets/ncoffsets.c | 2099 +++
src/utils/pnetcdf_version/Makefile.in | 56 +
src/utils/pnetcdf_version/depend | 1 +
src/utils/pnetcdf_version/pnetcdf_version.1 | 61 +
src/utils/pnetcdf_version/pnetcdf_version.c | 107 +
stamp-h.in | 1 +
test/C/Makefile.in | 76 +
test/C/pres_temp_4D_rd.c | 205 +
test/C/pres_temp_4D_wr.c | 262 +
test/CXX/Makefile.in | 79 +
test/CXX/nctst.cpp | 560 +
test/CXX/test_classic.cpp | 96 +
test/F90/Makefile.in | 142 +
test/F90/depend | 13 +
test/F90/f90tst_parallel.f90 | 169 +
test/F90/f90tst_parallel2.f90 | 176 +
test/F90/f90tst_parallel3.f90 | 196 +
test/F90/f90tst_parallel4.f90 | 105 +
test/F90/f90tst_vars.f90 | 139 +
test/F90/f90tst_vars2.f90 | 194 +
test/F90/f90tst_vars3.f90 | 193 +
test/F90/f90tst_vars4.f90 | 131 +
test/F90/test_intent.f90 | 150 +
test/F90/tst_f90.f90 | 207 +
test/F90/tst_f90_cdf5.f90 | 79 +
test/F90/tst_flarge.f90 | 102 +
test/F90/tst_io.f90 | 176 +
test/F90/tst_types2.f90 | 293 +
test/Makefile.in | 106 +
test/cdf_format/Makefile.in | 77 +
test/cdf_format/cdf_type.c | 126 +
test/cdf_format/depend | 3 +
test/cdf_format/dim_cdf12.c | 202 +
test/cdf_format/test_cdf1.nc | Bin 0 -> 32 bytes
test/cdf_format/test_cdf2.nc | Bin 0 -> 32 bytes
test/cdf_format/test_cdf5.nc | Bin 0 -> 48 bytes
test/cdf_format/test_inq_format.c | 110 +
test/common/Makefile.in | 55 +
test/common/testutils.c | 207 +
test/common/testutils.h | 35 +
test/common/testutilsf.F90 | 59 +
test/fandc/Makefile.in | 88 +
test/fandc/csnap.c | 475 +
test/fandc/depend | 2 +
test/fandc/fixedform.f90 | 27 +
test/fandc/freeform.f | 27 +
test/fandc/pnctest.c | 70 +
test/fandc/pnctestf.f | 74 +
test/fandc/pnf_test.f | 696 +
test/header/Makefile.in | 64 +
test/header/header_consistency.c | 621 +
test/largefile/Makefile.in | 86 +
test/largefile/large_files.c | 194 +
test/largefile/large_var.c | 293 +
test/nc_test/Makefile.in | 138 +
test/nc_test/README | 9 +
test/nc_test/depend | 41 +
test/nc_test/error.c | 80 +
test/nc_test/error.h | 37 +
test/nc_test/nc_test.c | 549 +
test/nc_test/t_nc.c | 664 +
test/nc_test/test_get.m4 | 958 ++
test/nc_test/test_iget.m4 | 1547 ++
test/nc_test/test_iput.m4 | 1732 +++
test/nc_test/test_put.m4 | 1265 ++
test/nc_test/test_read.c | 1792 +++
test/nc_test/test_write.c | 2185 +++
test/nc_test/tests.h | 793 +
test/nc_test/tst_atts.c | 2246 +++
test/nc_test/tst_atts3.c | 804 ++
test/nc_test/tst_misc.c | 100 +
test/nc_test/tst_names.c | 327 +
test/nc_test/tst_nofill.c | 484 +
test/nc_test/tst_norm.c | 218 +
test/nc_test/tst_small.c | 481 +
test/nc_test/util.c | 1055 ++
test/nf90_test/Makefile.in | 92 +
test/nf90_test/README | 3 +
test/nf90_test/depend | 28 +
test/nf90_test/fortlib.c | 289 +
test/nf90_test/nf90_error.F90 | 80 +
test/nf90_test/nf90_test.F90 | 849 ++
test/nf90_test/test_get.m4 | 1163 ++
test/nf90_test/test_iget.m4 | 1018 ++
test/nf90_test/test_iput.m4 | 1087 ++
test/nf90_test/test_put.m4 | 1518 ++
test/nf90_test/test_read.F90 | 1454 ++
test/nf90_test/test_write.F90 | 1755 +++
test/nf90_test/tests.inc | 230 +
test/nf90_test/util.F90 | 1514 ++
test/nf_test/Makefile.in | 93 +
test/nf_test/README | 9 +
test/nf_test/depend | 31 +
test/nf_test/fortlib.c | 289 +
test/nf_test/nf_error.F | 81 +
test/nf_test/nf_test.F | 861 ++
test/nf_test/test_get.m4 | 1149 ++
test/nf_test/test_iget.m4 | 1033 ++
test/nf_test/test_iput.m4 | 1108 ++
test/nf_test/test_put.m4 | 1518 ++
test/nf_test/test_read.F | 1437 ++
test/nf_test/test_write.F | 1740 +++
test/nf_test/tests.inc.in | 234 +
test/nf_test/util.F | 1531 ++
test/nonblocking/Makefile.in | 140 +
test/nonblocking/README | 12 +
test/nonblocking/bput_varn_uint.c | 494 +
test/nonblocking/column_wise.c | 227 +
test/nonblocking/depend | 14 +
test/nonblocking/flexible_bput.c | 270 +
test/nonblocking/i_varn_indef.c | 574 +
test/nonblocking/i_varn_int64.c | 501 +
test/nonblocking/interleaved.c | 195 +
test/nonblocking/mcoll_perf.c | 685 +
test/nonblocking/mcoll_testf.f90 | 461 +
test/nonblocking/mcoll_testf77.f | 521 +
test/nonblocking/req_all.c | 157 +
test/nonblocking/test_bput.c | 145 +
test/nonblocking/test_bputf.f90 | 175 +
test/nonblocking/test_bputf77.f | 190 +
test/nonblocking/wait_after_indep.c | 98 +
test/subfile/Makefile.in | 79 +
test/subfile/README | 15 +
test/subfile/depend | 2 +
test/subfile/test_subfile.c | 417 +
test/testcases/Makefile.in | 251 +
test/testcases/add_var.c | 116 +
test/testcases/alignment_test.c | 295 +
test/testcases/attrf.f | 156 +
test/testcases/bigrecords.f | 338 +
test/testcases/buftype_free.c | 126 +
test/testcases/buftype_freef.f | 169 +
test/testcases/check_striping.c | 99 +
test/testcases/check_type.c | 249 +
test/testcases/collective_error.c | 128 +
test/testcases/depend | 37 +
test/testcases/flexible.c | 205 +
test/testcases/flexible2.c | 279 +
test/testcases/flexible_varm.c | 247 +
test/testcases/geopotential.ncdump | 48 +
test/testcases/inq_num_vars.c | 135 +
test/testcases/inq_num_varsf.f90 | 166 +
test/testcases/inq_recsize.c | 115 +
test/testcases/inq_recsizef.f90 | 142 +
test/testcases/interop1.sh | 37 +
test/testcases/ivarn.c | 447 +
test/testcases/last_large_var.c | 260 +
test/testcases/modes.c | 156 +
test/testcases/ncmpi_vars_null_stride.c | 88 +
test/testcases/noclobber.c | 76 +
test/testcases/nonblocking.c | 163 +
test/testcases/one_record.c | 118 +
test/testcases/put_parameter.f | 166 +
test/testcases/record.c | 299 +
test/testcases/redef-good.ncdump | 63 +
test/testcases/redef1.c | 197 +
test/testcases/redef1.sh | 22 +
test/testcases/test_erange.c | 100 +
test/testcases/test_vard.c | 322 +
test/testcases/test_vardf.F | 392 +
test/testcases/test_vardf90.f90 | 372 +
test/testcases/test_varm.c | 201 +
test/testcases/varn_contig.c | 240 +
test/testcases/varn_int.c | 320 +
test/testcases/varn_intf.f | 288 +
test/testcases/varn_real.f90 | 299 +
test/testcases/vectors.c | 133 +
474 files changed, 203901 insertions(+)
diff --git a/COPYRIGHT b/COPYRIGHT
new file mode 100644
index 0000000..0482a47
--- /dev/null
+++ b/COPYRIGHT
@@ -0,0 +1,34 @@
+Copyright (c) 2003 Northwestern University and Argonne National Laboratory
+All rights reserved.
+
+Portions of this software were developed by the Unidata Program at the
+University Corporation for Atmospheric Research.
+
+Access and use of this software shall impose the following obligations and
+understandings on the user. The user is granted the right, without any fee or
+cost, to use, copy, modify, alter, enhance and distribute this software, and
+any derivative works thereof, and its supporting documentation for any purpose
+whatsoever, provided that this entire notice appears in all copies of the
+software, derivative works and supporting documentation. Further, Northwestern
+University and Argonne National Laboratory request that the user credit
+Northwestern University and Argonne National Laboratory in any publications
+that result from the use of this software or in any product that includes this
+software. The names Northwestern University and Argonne National Laboratory,
+however, may not be used in any advertising or publicity to endorse or promote
+any products or commercial entity unless specific written permission is
+obtained from Northwestern University and Argonne National Laboratory. The user
+also understands that Northwestern University and Argonne National Laboratory
+are not obligated to provide the user with any support, consulting, training or
+assistance of any kind with regard to the use, operation and performance of
+this software nor to provide the user with any updates, revisions, new versions
+or "bug fixes."
+
+THIS SOFTWARE IS PROVIDED BY NORTHWESTERN UNIVERSITY AND ARGONNE NATIONAL
+LABORATORY "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NORTHWESTERN UNIVERSITY
+AND ARGONNE NATIONAL LABORATORY BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ACTION, ARISING OUT OF OR IN CONNECTION WITH THE ACCESS, USE OR PERFORMANCE OF
+THIS SOFTWARE.
diff --git a/CREDITS b/CREDITS
new file mode 100644
index 0000000..1687829
--- /dev/null
+++ b/CREDITS
@@ -0,0 +1,34 @@
+Parallel-netCDF is a joint effort between Northwestern University and Argonne
+National Laboratory. We have also been fortunate to receive a great deal of
+help from the community. A partial list follows. Thanks everyone!
+
+- Parallel-NetCDF uses a great deal of NetCDF code, so the project would not
+ have gotten as far as it did as quickly as it did without the efforts of the
+ Unidata group.
+
+- Joachim Worringen <joachim at ccrl-nece.de> and Rene Redler
+ <redler at ccrl-nece.de> helped us build and run correctly on NEC SX-6
+
+- John Tannahill <tannahill1 at llnl.gov> contributed a great deal of effort
+ testing and improving our Fortran bindings
+
+- Richard Hedges <richard-hedges at llnl.gov> was another early adopter and
+ offered a lot of configuration tips, particularly for IFC
+
+- Renier Vogelsang <reiner at sgi.com> provided valuable assistance with the IRIX
+ port
+
+- Greg Sjaardema's <gdsjaar at sandia.gov> CDF-2 patch gave us and serial NetCDF
+ large file support
+
+- Jim Edwards <jedwards at ucar.edu> provided a great deal of assistance with our
+ AIX port, and testing the nonblocking APIs.
+
+- Tyce Mclarty <mclarty3 at llnl.gov> also did a lot of AIX work for us
+
+- Christopher Subich <csubich at math.uwaterloo.ca> contributed several configure
+ fixes, improving our handling of cross-compile environments.
+
+- Kurt Glaesemann <kurt.glaesemann at pnl.gov> contributed numerous cleanups for
+ PnetCDF on ia64 with HP-MPI
+
diff --git a/INSTALL b/INSTALL
new file mode 100644
index 0000000..d0eadef
--- /dev/null
+++ b/INSTALL
@@ -0,0 +1,319 @@
+PnetCDF Installation Guide
+=====================
+
+1. Getting Started
+2. Alternate Configure Options
+3. Testing the PnetCDF installation
+4. Reporting Installation or Usage Problems
+
+
+-------------------------------------------------------------------------
+
+1. Getting Started
+==================
+
+The following instructions take you through a sequence of steps to get the
+default configuration of PnetCDF up and running.
+
+(a) You will need the following prerequisites.
+
+ - REQUIRED: This tar file
+
+ - REQUIRED: An MPI C compiler
+
+ - REQUIRED: GNU m4 (https://www.gnu.org/software/m4/m4.html)
+
+ - OPTIONAL: An MPI C++ compiler, if C++ applications are to be used.
+ If you do not require support for C++ applications, you can disable this
+ support using the configure option --disable-cxx (configuring PnetCDF is
+ described in step 1(d) below).
+
+ - OPTIONAL: An MPI Fortran 77 compiler, if Fortran 77 applications are to
+ be used. If you do not require support for Fortran 77 applications, you
+ can disable this support using --disable-fortran (configuring PnetCDF is
+ described in step 1(d) below).
+
+ - OPTIONAL: An MPI Fortran 90 compiler, if Fortran 90 applications are to
+ be used. If you do not require support for Fortran 90 applications, you
+ can disable this support using --disable-fortran. Note that Fortran 77
+ support is a prerequisite for Fortran 90 support (configuring PnetCDF is
+ described in step 1(d) below).
+
+ Also, you need to know what shell you are using since different shell has
+ different command syntax. Command "echo $SHELL" prints out the current
+ shell used by your terminal program.
+
+(b) Unpack the tar file and go to the top level directory:
+
+ gunzip parallel-netcdf-1.6.0.tar.gz
+ tar xf parallel-netcdf-1.6.0.tar
+ cd parallel-netcdf-1.6.0
+
+(c) Choose an installation directory, say $HOME/PnetCDF
+
+(d) Configure PnetCDF specifying the installation directory:
+
+ ./configure --prefix=$HOME/PnetCDF
+
+(e) Build PnetCDF:
+
+ make
+
+ Or if "make" runs slow, try parallel make, e.g. (using 8 simultaneous jobs)
+
+ make -j8
+
+(f) Install PnetCDF
+
+ make install
+
+ If a non-default install directory is desired, use command:
+
+ make install prefix=/OTHER/INSTALL/DIRECTORY
+
+(g) Add the bin subdirectory of the installation directory to your path in your
+ startup script (.bashrc for bash, .cshrc for csh, etc.):
+
+ for csh and tcsh:
+
+ setenv PATH $HOME/PnetCDF/bin:$PATH
+
+ for bash and sh:
+
+ PATH=$HOME/PnetCDF/bin:$PATH ; export PATH
+
+ Check that everything is in order at this point by doing:
+
+ which ncmpidump
+ which ncmpidiff
+
+ These commands should display the path to your bin subdirectory of your
+ install directory.
+
+If you have completed all of the above steps, you have successfully installed
+PnetCDF.
+
+-------------------------------------------------------------------------
+
+2. Alternate Configure Options
+=================
+
+PnetCDF has a number of configure features. A complete list of configuration
+options can be found using:
+
+ ./configure --help
+
+Here lists a few important options:
+
+ --prefix=PREFIX install PnetCDF files in PREFIX [/usr/local]
+ --enable-echo Turn on strong echoing. [default: disabled]
+ --disable-largefile omit support for large files
+ --disable-mpi-io-test Disable check for MPI-IO support in MPI
+ implementation, if you know your MPI implementation
+ has MPI-IO support but the configure test fails to
+ find it. [default: enabled]
+ --disable-cxx Turn off support for the C++ interface, if you only
+ need the C interface. [default: enabled]
+ --enable-strict Turn on strict debugging with gcc. [default:
+ disabled]
+ --disable-fortran Turn off support for the Fortran interface, if you
+ only need the C interface. [default: enabled]
+ --enable-debug Enable PnetCDF internal debug mode. This also
+ enables safe mode. [default: disabled]
+ --disable-in-place-swap Disable memory in-place byte swap on Little Endian
+ machines. [default: enabled]. See note below.
+ --enable-coverage Compile with coverage support (gcc-based only).
+ [default: disabled]
+ --disable-subfiling Turns off subfiling support. [default: disabled]
+ --disable-file-sync Disable MPI file sync if you know your file system
+ can provide data consistency. [default: enabled]
+ --enable-large-file-test
+ Enable testing for large (>4GB) file/variable I/O.
+ This can run very slow. [default: disabled]
+
+Optional Packages:
+ --with-mpi=/path/to/implementation
+ installation prefix for MPI implementation
+
+PnetCDF can automatically detect the available MPI compilers and compile flags.
+If alternate compilers or flags are desired, they can be specified by the
+following environment variables and/or configure options.
+
+Some influential environment variables:
+ CFLAGS, CPPFLAGS, CXXFLAGS, FFLAGS, FCFLAGS, LDFLAGS and LIBS
+ Setting these compile flags would result in the PnetCDF library being built
+ with these flags.
+
+ MPICC, MPICXX, MPIF77, MPIF90
+ Setting these variables would result in the PnetCDF library being built
+ with these compilers. CC, CXX, F77, and F90 will be ignored if these MPI
+ variables are present.
+
+ Note the compile flags, such as -O2 or -g, should be given in CFLAGS and
+ other flag environment variables. Please do not set them in compiler
+ variable. For instance, setting MPICC="mpcc -O2" may result in the error
+ of compiler not found.
+
+ - For platform-specific build instructions, see one of the README.<ARCH>
+ files.
+
+
+----
+Note on configure option "--disable-in-place-swap"
+----
+ This option disables the byte-swap operations running in-place on the user's
+ write buffers. The purpose of providing this option is to deal with the
+ problem when a Fortran program uses a immutable buffer for put APIs, e.g.
+ the buffer is declared as a PARAMETER, and in-place byte swap on this buffer
+ causes segmentation fault. See discussion threads of
+ http://lists.mcs.anl.gov/pipermail/parallel-netcdf/2013-July/001498.html
+
+ Impacts:
+ 1. It takes effect only on Little Endian machines.
+ 2. It only affects put/iput data APIs, but not attribute APIs.
+ 3. The INTENT of buffer arguments in all Fortran 90 put/iput APIs will be
+ declared as "IN". Without this setting, the default is "INOUT".
+ 4. It has an impact on performance, as an extra internal temporary buffer
+ will be allocated to copy data over from user's put buffer, so byte
+ swap can be run on the temporary buffer.
+
+ The default setting is to enable in-place byte swap. PnetCDF tries not to
+ allocate additional memory space, due to performance concern. Users are
+ discouraged to use Fortran PARAMETER buffers in put APIs.
+
+-------------------------------------------------------------------------
+
+3. Testing the PnetCDF installation
+==================================
+
+Two type of testings are implemented in PnetCDF: sequential and parallel.
+For testing sequential programs, the command is
+ make check
+For testing parallel programs, the command is
+ make ptest
+The parallel test uses up to 10 MPI processes.
+
+Command "make tests" will build executables of all the test programs. This can
+be handy if testing must run through a batch job system. Having the testing
+executables built before submitting a batch job could save a lot of time.
+
+There are three environment variables that can be used to run make check/ptest
+on a cross compile platform.
+ - TEST_MPIRUN : command to launch MPI jobs. default: mpiexec
+ - TEST_SEQRUN : command to run MPI executable sequentially. default: ./
+ - TEST_OUTDIR : output directory. default: ./
+
+Examples:
+ make check TEST_OUTDIR=/scratch
+ make ptest TEST_MPIRUN="aprun -n NP" TEST_OUTDIR=/scratch
+
+Note the keyword "NP" used in the environment variable string TEST_MPIRUN. It
+will be replaced with the different numbers of MPI processes used in testing.
+Currently, the testing uses up to 8 processes. Hence, please make sure the
+process allocation at least contains 8 processes.
+
+One can also run "make ptest" on batch queue systems. One example PBS script is
+provide "pbs.script". It is recommended to build all the testing executables
+before submitting the batch job. This can be done by running the below command.
+ cd test ; make ; cd ../examples ; make ; cd ..
+
+Note on setting TEST_OUTDIR. In order to run parallel test correctly, the
+output directory must be on a file system accessible to all MPI processes. We
+recommend to use parallel file systems or POSIX compliant file systems (Using
+NFS will most likely fail the parallel test.)
+
+Issue with older MPI-IO implementation.
+ During "make check", one may encounter the following error message:
+ "MPI error (MPI_File_delete) : MPI_ERR_IO: input/output error"
+ This is due to the underneath MPI-IO libraries fail to return the correct
+ error class MPI_ERR_NO_SUCH_FILE when trying to delete a non-existing file.
+ This message can be ignored.
+
+-------------------------------------------------------------------------
+
+4. Reporting Installation or Usage Problems
+===========================================
+
+Please send an email to parallel-netcdf at mcs.anl.gov
+
+
+
+-----------------------------------------------------------------------------
+Notes from previous releases
+-----------------------------------------------------------------------------
+
+To INSTALL parallel netCDF library:
+
+ 1. 'autoreconf' (only necessary if you make changes to configure.in or
+ other configure-related files)
+
+ 2. ./configure --prefix=<install dir> --with-mpi=/path/to/implementation
+ the --with-mpi argument should specify the prefix of where the mpi
+ implementation was installed. If your mpicc is in
+ /usr/local/mpich-1.2.3/bin/mpicc then use the prefix
+ --with-mpi=/usr/local/mpich-1.2.3
+
+ NOTE: If configure cannot find your MPI implementation's C and/or
+ Fortran compilers, define MPICC, MPICXX, MPIF77 and MPIF90
+ environment variables to be the name of those compilers. The
+ configure script will then use those values instead of trying
+ to guess.
+
+ 3. make
+
+ We have tried to make the Makefiles platform-independent.
+ However, each platform has its own make quirks: if you run into
+ problems, please send a report to the developers at
+ parallel-netcdf at mcs.anl.gov. If you have GNU Make, try using
+ that.
+
+ 4. make install
+
+IF THIS DOESN'T WORK:
+
+Autoconf should do the right thing: using the system compiler to perform
+autoconf tests and then use the MPI compilers to build parallel-netcdf.
+If you need to set specific flags for a platform, and autoconf does not
+set them for you, then you will have to set some environment variables
+to help out the configure script. Here are some suggested settings:
+
+ For Solaris
+ MPICC=mpicc
+
+ For SGI Origin2000
+ MPICC = mpicc
+ ------------ OR -------------
+ CC='/bin/cc -64 -mips4 -lmpi'
+ CPPFLAGS=-DNDEBUG
+ CFLAGS=-O
+ FC='/bin/f90 -64'
+ FFLAGS=-O
+ F90='/bin/f90 -64'
+ CXX='/bin/CC -64'
+ CXXFLAGS=-O
+
+ For Linux
+ MPICC=mpicc
+ CPPFLAGS='-DNDEBUG -Df2cFortran'
+ CFLAGS=-O
+ CXX=g++
+ FFLAGS='-O -W'
+
+ For IBM SP-2
+ MPICC mpcc_r
+ MPIF77 /bin/mpxlf_r
+ F90 /bin/mpxlf90_r
+ F90FLAGS -qsuffix=f=f90
+ CXX /bin/mpxlC_r
+ ------------- OR -------------
+ CC xlc
+ FC /bin/xlf
+ F90 /bin/xlf90
+ F90FLAGS -qsuffix=f=f90
+ CXX /bin/xlC
+ then manually edit macros.make:
+ CC = mpcc_r
+ FC = mpxlf_r
+ F90 = mpxlf90_r
+ F90FLAGS = -qsuffix=f=f90
+ CXX = mpxlC_r
diff --git a/Makefile.in b/Makefile.in
new file mode 100644
index 0000000..5edbea0
--- /dev/null
+++ b/Makefile.in
@@ -0,0 +1,242 @@
+#
+# Copyright (C) 2003, Northwestern University and Argonne National Laboratory
+# See COPYRIGHT notice in top-level directory.
+#
+# $Id: Makefile.in 2298 2016-01-07 07:33:10Z wkliao $
+#
+# @configure_input@
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+include macros.make
+
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+
+PACKAGE_FILENAME = $(PACKAGE_NAME)-$(PACKAGE_VERSION)
+
+INSTALL_SUBDIRS = src man
+
+SUBDIRS = src \
+ test \
+ scripts \
+ doc \
+ man \
+ benchmarks \
+ examples
+
+GARBAGE =
+
+DIST_GARBAGE = config.cache \
+ config.status \
+ config.log \
+ macros.make \
+ stamp-h
+
+PACKING_LIST = Makefile.in \
+ aclocal.m4 \
+ configure \
+ configure.in \
+ macros.make.in \
+ rules.make \
+ COPYRIGHT \
+ CREDITS \
+ INSTALL \
+ README \
+ README.CRAY \
+ README.IBM \
+ README.LINUX \
+ README.SGI \
+ README.SX \
+ README.large_files \
+ RELEASE_NOTES \
+ pbs.script \
+ cobalt.script \
+ stamp-h.in
+
+PACKING_SUBDIRS = $(SUBDIRS)
+
+all:
+ $(MAKE) $(MFLAGS) -C src
+
+TESTS_SUBDIRS = test examples benchmarks
+TESTS_DIRS = $(TESTS_SUBDIRS:%=tests-%)
+tests: $(TESTS_DIRS)
+$(TESTS_DIRS):
+ $(MAKE) $(MFLAGS) -C $(@:tests-%=%)
+
+check testing:
+ $(MAKE) $(MFLAGS) -C test testing
+
+verbose_check verbose_testing:
+ $(MAKE) $(MFLAGS) -C test verbose_testing
+
+PTEST_SUBDIRS = test examples benchmarks
+PTEST_DIRS = $(PTEST_SUBDIRS:%=ptest-%)
+ptest: tests $(PTEST_DIRS)
+$(PTEST_DIRS):
+ifeq (@enable_coverage@, yes)
+ echo "Parallel test is disabled because coverage analysis was enabled"
+else
+ $(MAKE) $(MFLAGS) -C $(@:ptest-%=%) ptest
+endif
+# make sure ptest runs one directory after another
+ptest-examples: ptest-test
+ptest-benchmarks: ptest-examples
+
+PTESTS_DIRS = $(PTEST_SUBDIRS:%=ptests-%)
+ptests: tests $(PTESTS_DIRS)
+$(PTESTS_DIRS):
+ifeq (@enable_coverage@, yes)
+ echo "Parallel test is disabled because coverage analysis was enabled"
+else
+ $(MAKE) $(MFLAGS) -C $(@:ptests-%=%) ptests
+endif
+# make sure ptests runs one directory after another
+ptests-examples: ptests-test
+ptests-benchmarks: ptests-examples
+
+INSTALLDIRS = $(INSTALL_SUBDIRS:%=install-%)
+install: $(INSTALLDIRS)
+ @echo '+----------------------------------------------------------------------------+'
+ @echo '|'
+ @echo '| PnetCDF has been successfully installed under $(prefix)'
+ @echo '|'
+ @echo '| * PnetCDF header files are installed in $(prefix)/include'
+ @echo '| * PnetCDF library file is installed in $(prefix)/lib'
+ @echo '| * PnetCDF utility programs are installed in $(prefix)/bin'
+ @echo '| * PnetCDF man pages are installed in $(prefix)/man/man1 and'
+ @echo '| $(prefix)/man/man3'
+ @echo '|'
+ @echo '| To compile your PnetCDF programs, please add the following to the command'
+ @echo '| line, so the compiler can find the PnetCDF header files:'
+ @echo '| -I$(prefix)/include'
+ @echo '|'
+ @echo '| Add the following line to link your program to PnetCDF library:'
+ @echo '| -L$(prefix)/lib -lpnetcdf'
+ @echo '|'
+ @echo '| PnetCDF is jointly developed by a team at Northwestern University and'
+ @echo '| Argonne National Laboratory.'
+ @echo '|'
+ @echo '| Vist PnetCDF web sites for more information'
+ @echo '| http://cucis.ece.northwestern.edu/projects/PnetCDF'
+ @echo '| http://trac.mcs.anl.gov/projects/parallel-netcdf'
+ @echo '|'
+ @echo '+----------------------------------------------------------------------------+'
+
+$(INSTALLDIRS):
+ $(MAKE) $(MFLAGS) -C $(@:install-%=%) install
+
+UNINSTALLDIRS = $(INSTALL_SUBDIRS:%=uninstall-%)
+uninstall: $(UNINSTALLDIRS)
+$(UNINSTALLDIRS):
+ $(MAKE) $(MFLAGS) -C $(@:uninstall-%=%) uninstall
+
+################################################################################
+# Distribution:
+
+# The following rule checks to see that were on the right system. If we're
+# not, then the distribution mightn't contain the intended ncgen(1) (not
+# to mention that dvips(1) is necessary for building the C++ User's Guide).
+#
+check_system: FORCE
+ @case "$(OVERRIDE)" in \
+ '') case `uname -sr` in \
+ 'SunOS 5'*) \
+ exit 0;; \
+ *) echo 1>&2 "Error: Not on a SunOS 5 system."; \
+ echo 1>&2 "Set macro OVERRIDE to override."; \
+ exit 1;; \
+ esac;; \
+ *) exit 0;; \
+ esac
+
+# Make a compressed, tar(1) file of the source distribution in the current
+# directory.
+#
+tar.Z: check_system FORCE
+ $(MAKE) $(MFLAGS) $(PACKAGE_FILENAME).tar.Z
+
+dist: ensure_manifest MANIFEST
+ id=$(PACKAGE_FILENAME) \
+ && $(RM) -fr $$id \
+ && $(LN_S) $(srcdir) $$id \
+ && tar $(TARFLAGS) - `$(SED) "s|^|$$id/|" MANIFEST` | gzip > $(PACKAGE_FILENAME).tar.gz \
+ && tar $(TARFLAGS) - `$(SED) "s|^|$$id/|" MANIFEST` | bzip2 > $(PACKAGE_FILENAME).tar.bz2 \
+ && $(RM) -f $$id MANIFEST
+
+MANIFEST: FORCE
+ $(MAKE) $(MFLAGS) -s MANIFEST.echo >$@
+
+# Make a compressed, tar(1) file of the source distribution in the
+# appropriate FTP directory.
+#
+# NOTE: Making "ftp" will cause the "tar.Z" file to be made even if it
+# already exists. This is because the MANIFEST file upon which it
+# depends must be remade every time. This is not a waste of time,
+# however, if the "tar.Z" target is made in private directories and the
+# "ftp" target is made in the "/upc/$(PACKAGE_FILENAME)/build/" directory.
+#
+ftp: check_system FORCE
+ $(MAKE) $(MFLAGS) $(FTPDIR)/$(PACKAGE_FILENAME).tar.Z \
+ test -r $(FTPDIR)/$(PACKAGE_FILENAME).tar.Z || exit 0; \
+ cd $(FTPDIR) || exit 1;
+
+$(FTPDIR)/$(PACKAGE_FILENAME).tar.Z: $(PACKAGE_FILENAME).tar.Z
+ $(RM) -f $@
+ cp $(PACKAGE_FILENAME).tar.Z $@
+ chmod u+rw,g+rw,o=r $@
+
+# Make a compressed, tar(1) file of the binary distribution in the
+# appropriate FTP directory.
+#
+binftp: FORCE
+ $(MAKE) $(MFLAGS) $(FTPBINDIR)/$(PACKAGE_FILENAME).tar.Z \
+
+ftpbin: binftp
+
+$(FTPBINDIR)/$(PACKAGE_FILENAME).tar.Z:
+ $(RM) -f $@
+ id=$(PACKAGE_FILENAME) \
+ && $(RM) -f $$id \
+ && $(LN_S) $(prefix) $$id \
+ && tar $(TARFLAGS) - README $$id/bin $$id/include \
+ $$id/lib $$id/man | compress > $@ \
+ && $(RM) -f $$id
+ chmod u+rw,g+rw,o=r $@
+ test -r $(FTPBINDIR)/$(PACKAGE_FILENAME).tar.Z || exit 0; \
+ cd $(FTPBINDIR) || exit 1;
+
+
+# rule for generating cscope information
+cscope:
+ find $(srcdir) -iname "*.[ch]" > $(srcdir)/cscope.files
+ ( cd $(srcdir); cscope -be -i $(srcdir)/cscope.files )
+
+# The following dependency is for configure.in and configure
+# See autoconf manual 2.69, Section 4.8.5 Automatic Remaking
+$(srcdir)/configure: configure.in aclocal.m4
+ cd '$(srcdir)' && autoconf
+
+# autoheader might not change src/lib/ncconfig.h.in so touch a stamp file.
+$(srcdir)/src/lib/ncconfig.h.in: stamp-h.in
+$(srcdir)/stamp-h.in: configure.in aclocal.m4
+ cd '$(srcdir)' && autoheader
+ echo timestamp > '$(srcdir)/stamp-h.in'
+
+src/lib/ncconfig.h: stamp-h
+stamp-h: src/lib/ncconfig.h.in config.status
+ ./config.status
+
+Makefile: Makefile.in config.status
+ ./config.status
+
+config.status: configure
+ ./config.status --recheck
+
+include $(srcdir)/rules.make
+
+
diff --git a/README b/README
new file mode 100644
index 0000000..cfed149
--- /dev/null
+++ b/README
@@ -0,0 +1,55 @@
+
+Parallel netCDF (PnetCDF) is a library providing high-performance parallel I/O
+while still maintaining file-format compatibility with Unidata's NetCDF,
+specifically the CDF and CDF-2 formats. Although NetCDF supports parallel I/O
+starting from version 4, the files must be in HDF5 format. PnetCDF is currently
+the only choice for carrying out parallel I/O on files that are in classic
+formats (CDF-1 and 2).
+
+In addition, PnetCDF supports the CDF-5 file format, an extension of CDF-2,
+that supports more data types and allows users to define large dimensions,
+attributes, and variables (>2B elements).
+
+NetCDF gives scientific programmers a space-efficient and portable means for
+storing data. However, it does so in a serial manner, making it difficult to
+achieve high I/O performance. By making some small changes to the NetCDF APIs,
+PnetCDF can use MPI-IO to achieve high-performance parallel I/O.
+
+More extensive installation guides can be found in file INSTALL. Additional
+information regarding the contents of the release can be found in
+the RELEASE_NOTES file in the top-level directory. Finally, the PnetCDF web
+site,
+ http://trac.mcs.anl.gov/projects/parallel-netcdf
+contains information on bug fixes and new releases.
+
+
+Requirements:
+
+ - Parallel-NetCDF relies on MPI-IO. ROMIO, the most common MPI-IO
+ implementation, can make use of a prefix in front of the file name to
+ specify the underlying file system and override ROMIO's auto detection. A
+ typical prefix would look like "nfs:" or "pvfs2:". Bear this in mind if
+ you use a file name with ':' characters. In some cases, ROMIO might
+ think you are passing in a prefix and will complain about an unsupported
+ file system type. If that happens, add a file-system prefix to your file
+ name.
+
+ - To build parallel-netcdf you will need some additional programs:
+ - either yacc or bison
+ - either lex or flex
+ These are usually part of your operating system's development tools.
+
+
+Note on supporting large files and large variables.
+
+ - Fortran routines will pass in a 64 bit integer for some parameters (those
+ corresponding to MPI_Offset type in the C routines). Declare those
+ parameters as 'integer(kind=MPI_OFFSET_KIND)'
+
+ - In places where you might use NF_UNLIMITED to define an unlimited
+ dimension in one of the nfmpi_ routines, use NFMPI_UNLIMITED.
+ NFMPI_UNLIMITED will be defined as the proper type for nfmpi_def_dim,
+ whereas nf_unlimited might be too small. Similarly, for Fortran 90,
+ use NF90MPI_UNLIMITED instead of NF90_UNLIMITED.
+
+Please send an email to parallel-netcdf at mcs.anl.gov
diff --git a/README.CRAY b/README.CRAY
new file mode 100644
index 0000000..5c3094c
--- /dev/null
+++ b/README.CRAY
@@ -0,0 +1,110 @@
+# $Id: README.CRAY 1605 2014-05-01 20:22:23Z wkliao $
+
+===============================================================================
+ Cray XC30
+===============================================================================
+
+Building PnetCDF on the Cray XC30 (tested on Edison @ NERSC)
+http://www.nersc.gov/systems/edison-cray-xc30/
+
+The configure options are the same as Cray XE6, except when using the Intel
+compiler (the default on Edison) with optimization flag "-fast". According
+to the NERSC URL below, the flag "-no-ipo" must be used together with flag
+"-fast" to build a library.
+http://www.nersc.gov/users/software/compilers/intel-fortran-c-and-c/
+
+./configure --prefix=/path/to/install \
+ --with-mpi=/path/to/mpi/implementation \
+ CFLAGS="-fast -no-ipo" CXXFLAGS="-fast -no-ipo" \
+ FFLAGS="-fast -no-ipo" FCFLAGS="-fast -no-ipo"
+
+
+Note if running make is slow, try parallel make, e.g.
+
+ make -j8
+
+===============================================================================
+ Cray XE6
+===============================================================================
+
+Building PnetCDF on the Cray XE6 (tested on Hopper @ NERSC)
+http://www.nersc.gov/systems/hopper-cray-xe6/
+
+./configure --prefix=/path/to/install \
+ --with-mpi=/path/to/mpi/implementation \
+ CFLAGS=-fast CXXFLAGS=-fast FFLAGS=-fast FCFLAGS=-fast
+
+
+The configure command above works for PGI, GNU, and Intel
+compilers, i.e. when one of the module load commands below is used:
+
+ module load PrgEnv-pgi
+ module load PrgEnv-gnu
+ module load PrgEnv-intel
+
+
+For Pathscale compilers, i.e.
+ module load PrgEnv-pathscale
+ use command below:
+ ./configure --prefix=/path/to/install \
+ --with-mpi=/path/to/mpi/implementation \
+ CFLAGS=-Ofast CXXFLAGS=-Ofast FFLAGS=-Ofast FCFLAGS=-Ofast
+
+
+For Cray compilers, i.e.
+ module load PrgEnv-cray
+ use command below:
+ ./configure --prefix=/path/to/install \
+ --with-mpi=/path/to/mpi/implementation \
+ CFLAGS=-O2 CXXFLAGS=-O2 FFLAGS=-O2 FCFLAGS="-O2 -emf" \
+ LDFLAGS=-Wl,-z,muldefs
+
+ Check crayftn man page for using option "-emf" in FCFLAGS:
+ to creates .mod files to hold module and allows the creation
+ of lower-case module .mod file names.
+
+ Option "-Wl,-z,muldefs" in LDFLAGS is to get around the
+ error of multiple definitions of `tc_version', etc.
+
+
+===============================================================================
+ Cray X1
+===============================================================================
+
+2 May 2005
+
+I performed the following steps to get Parallel-NetCDF to build on the Cray X1
+at Oak Ridge (phoenix.ccs.ornl.gov). Note that out-of-tree (or VPATH) builds
+do not work for the Fortran interface as of 1.0.0-pre2, but we will try to
+address this issue in a future release.
+
+prompt:$ module load mpt
+prompt:$ export CC=cc
+prompt:$ export FC=ftn
+prompt:$ export MPIF77=$FC
+prompt:$ export MPICC=$CC
+prompt:$ export FFLAGS="-eh"
+prompt:$ ./configure --prefix=/path/to/install
+# note: configure takes a fairly long time.
+prompt:$ make
+
+The "nc_test" test will exhaust the available MPI datatypes on the X1. Your
+application might see this error:
+
+ MPI has run out of internal datatype entries.
+ Please set the environment variable MPI_TYPE_MAX for additional space.
+ The current value of MPI_TYPE_MAX is 2098
+
+I did as asked and nc_test completed with MPI_TYPE_MAX set to 4096
+
+If you run on the login node, expect to see a lot of these messages:
+
+ Process [nc_test] 89345 generated trap, but has signal 8 held or ignored
+ epc 0x1219bb4 ra 0x1219b94 badvaddr 0x40004f0004000020
+
+The messages don't *appear* to impact the program results, and additionally do
+not show up if you submit the job to PBS.
+
+Fortran codes should use '-eh' so that the Cray ftn compiler will use 1 byte
+for int*1 and 2 bytes for int*2. Otherwise, our Fortran bindings will pass
+incorrect values to the C routines.
diff --git a/README.IBM b/README.IBM
new file mode 100644
index 0000000..3c4af3b
--- /dev/null
+++ b/README.IBM
@@ -0,0 +1,269 @@
+# $Id: README.IBM 1741 2014-08-23 16:13:13Z wkliao $
+
+1. Building PnetCDF on BGQ
+2. Building PnetCDF on BGP
+3. Building PnetCDF on BGL
+4. Building PnetCDF on UCAR BlueFire
+5. Building PnetCDF on IBM SP
+
+-------------------------------------------------------------------------------
+1. Building PnetCDF on BGQ
+-------------------------------------------------------------------------------
+
+Building for BGQ is not so different from BGP or BGL: front end node is still a
+cross compile host for the back end. (as of this writing, the "log in io
+nodes", a.k.a lion nodes, are not on line for the Mira BGQ machine)
+
+Be sure to run configure with the --build and --host flags to put it in "cross
+compile mode". This will make configure use compile-only tests, instead of the
+usual compile-and-run tests (running tests on the BGP login node won't work as
+the compute nodes are totally different. This will change if/when lion
+nodes are available).
+
+./configure --host powerpc64-bgq-linux --build ppc64-redhat-linux \
+ MPICC=mpicc MPICXX=mpicxx MPIF77=mpif77 MPIF90=mpif90
+
+Note if running make is slow, try parallel make, e.g.
+
+ make -j8
+
+It's possible to build PnetCDF with the IBM xl compilers:
+
+./configure --host powerpc64-bgq-linux --build ppc64-redhat-linux \
+ --with-mpi=/bgsys/drivers/ppcfloor/comm/xl \
+ MPICC=mpixlc MPICXX=mpixlcxx MPIF77=mpixlf77 MPIF90=mpixlf90 \
+ FFLAGS="-qsuppress=cmpmsg" FCFLAGS="-qsuppress=cmpmsg"
+
+Fortran flag "-qsuppress=cmpmsg" can suppresses XLF compile informational
+messages that report compilation progress and a successful completion.
+
+
+Another possibility that uses thread-safe XL compilers is:
+
+./configure --host powerpc64-bgq-linux --build ppc64-redhat-linux \
+ --with-mpi=/bgsys/drivers/ppcfloor/comm/xl \
+ MPICC=mpixlc_r MPICXX=mpixlcxx_r \
+ MPIF77=mpixlf77_r MPIF90=mpixlf90_r \
+ CFLAGS=-O2 CXXFLAGS=-O2 FFLAGS=-O2 FCFLAGS=-O2 \
+ --prefix=/path/to/install
+
+
+As far as we know, there are no issues with PnetCDF on BGQ, but should you
+find any, email parallel-netcdf at mcs.anl.gov
+
+----
+Note on compiling Fortran 90 programs on Intrepid @ ANL
+----
+https://www.alcf.anl.gov/user-guides/bgp-faqs-compiling-and-linking#how-do-i-use-xlf-and-"use-mpi"
+
+If you attempt to do a "use mpi" from XL Fortran, and build with the default
+compiler wrappers, you will encounter this error:
+
+ XL Fortran90 error: Module symbol file for module mpi is in a format not
+recognized by this compiler
+
+The cause of the error is that the mpi.mod referenced in the "default" software
+stack (/bgsys/drivers/ppcfloor/comm/default) is built with GNU Fortran.
+
+A work-around to the problem using mpif.h instead of "use mpi.mod", e.g.:
+
+program test
+include "mpif.h"
+
+... your MPI stuff ...
+
+end program test
+
+The proper solution is to use an alternate software stack with MPI built using
+the XL compilers instead of the GNU compilers, thus containing a Fortran mpi
+module (mpi.mod) generated by XLF. This software stack was introduced in
+V1R4M1. You may build with it using the wrappers in comm/xl:
+
+ /bgsys/drivers/ppcfloor/comm/xl/bin/mpixlf90
+
+
+----
+* Note on running PnetCDF testing programs on Mira/Cetus @ ALCF, ANL
+----
+Mira and Cetus are IBM BlueGene Q, a cross-compile system. Hence, one cannot
+run PnetCDF test programs on the login nodes. Test programs must run on the
+compute nodes through submitting a batch job. An example batch script file is
+provided in cobalt.script. The submission command for allocating 8 node with 90
+minutes is given below. Note the testing requires at least 8 MPI processes and
+in this example the command requests 8 nodes and the script runs 1 MPI process
+per node.
+
+qsub -A YOUR_ACCOUNT -n 8 -t 30 --mode script ./cobalt.script
+
+Running "make testing" can take a while (more than one hour on Mira/Cetus).
+This is because the testing performs many small read/write requests and under
+BlueGene's I/O forwarding architecture, local file-system caching is not
+available on the compute nodes.
+
+Running "make ptest" will take approximately 10 minutes.
+
+-------------------------------------------------------------------------------
+2. Building PnetCDF on BGP
+-------------------------------------------------------------------------------
+
+Building for BGP is not so different from BGL: front end node is still a cross
+compile host for the back end.
+
+Be sure to run configure with the --build and --host flags to put it in "cross
+compile mode". This will make configure use compile-only tests, instead of the
+usual compile-and-run tests (running tests on the bgp login node won't work as
+the compute nodes are totally different).
+
+There is one run-time check for MPI-IO support of resized types. Unfortunately
+we have to test for this with a runtime test, but you can set the environment
+variable "ac_cv_MPI_TYPE_RESIZED_WORKS" .
+
+./configure --host powerpc-bgp-linux --build powerpc64-suse-linux \
+ --with-mpi=/bgsys/drivers/ppcfloor/comm
+
+It's possible to build PnetCDF with the IBM xl compilers:
+
+./configure --host powerpc-bgp-linux --build powerpc64-suse-linux \
+ --with-mpi=/bgsys/drivers/ppcfloor/comm/xl \
+ MPICC=mpixlc MPICXX=mpixlcxx MPIF77=mpixlf77 MPIF90=mpixlf90 \
+ FFLAGS="-qsuppress=cmpmsg" FCFLAGS="-qsuppress=cmpmsg"
+
+Fortran flag "-qsuppress=cmpmsg" can suppresses XLF compile informational
+messages that report compilation progress and a successful completion.
+
+As far as we know, there are no issues with PnetCDF on BGP, but should you
+find any, email parallel-netcdf at mcs.anl.gov
+
+----
+Note on compiling Fortran 90 programs on Intrepid @ ANL
+----
+https://www.alcf.anl.gov/user-guides/bgp-faqs-compiling-and-linking#how-do-i-use-xlf-and-"use-mpi"
+
+If you attempt to do a "use mpi" from XL Fortran, and build with the default
+compiler wrappers, you will encounter this error:
+
+ XL Fortran90 error: Module symbol file for module mpi is in a format not
+recognized by this compiler
+
+The cause of the error is that the mpi.mod referenced in the "default" software
+stack (/bgsys/drivers/ppcfloor/comm/default) is built with GNU Fortran.
+
+A work-around to the problem using mpif.h instead of "use mpi.mod", e.g.:
+
+program test
+include "mpif.h"
+
+... your MPI stuff ...
+
+end program test
+
+The proper solution is to use an alternate software stack with MPI built using
+the XL compilers instead of the GNU compilers, thus containing a Fortran mpi
+module (mpi.mod) generated by XLF. This software stack was introduced in
+V1R4M1. You may build with it using the wrappers in comm/xl:
+
+ /bgsys/drivers/ppcfloor/comm/xl/bin/mpixlf90
+
+
+-------------------------------------------------------------------------------
+3. Building PnetCDF on BGL
+-------------------------------------------------------------------------------
+
+Be sure to run configure with the --build and --host flags to put it in "cross
+compile mode". This will make configure use compile-only tests, instead of the
+usual compile-and-run tests (running tests on the bgl login node won't work as
+the compute nodes are totally different).
+
+configure --build powerpc32-unknown-gnu --host powerpc-suse-linux \
+ --with-mpi=/bgl/BlueLight/ppcfloor/bglsys/
+
+It's possible to build PnetCDF with the IBM xl compilers, but you have to set
+quite a few environment variables
+
+export CC=blrts_xlc
+export MPICC=blrts_xlc
+export CXX=blrts_xlC
+export MPICXX=blrts_xlC
+export FC=blrts_xlf
+export F77=blrts_xlf
+export MPIF77=blrts_xlf
+
+export CFLAGS="-I/bgl/BlueLight/ppcfloor/bglsys/include"
+export LIBS="-L/bgl/BlueLight/ppcfloor/bglsys/lib -lmpich.rts -lmsglayer.rts -ldevices.rts -lrts.rts -ldevices.rts -lrts.rts"
+
+configure --build powerpc32-unknown-gnu --host powerpc-suse-linux
+
+Several early versions of IBM's MPI-IO implementation would segfault under
+certain workloads. If you are running driver version "V1R3M0_240_2006-060623"
+or newer, the segfault issue should be resolved. If you are running an older
+driver, read on:
+
+When built against some older BlueGene drivers, nc_test does not run
+completely without setting a special environment variable, hitting a seg fault
+deep inside ROMIO. We first noticed this in IBM's "Driver 202" MPI and also in
+"V1R1M1_253_2005-051003" and "V1R2M1_020_2006-060110" We have told IBM
+developers about the problem. Code that makes use of the ncmpi_get_vara_*_all
+or ncmpi_put_vara_*_all routines will likely trigger a seg fault. IBM has
+provided a workaround: if your code seg-faults, try setting the
+"BGLMPIO_TUNEBLOCKING" environment variable to 0. With this environment
+variable set, nc_tests runs to completion and passes. For one real-world
+example, the FLASH-IO benchmark with 8 processors sees a 5% performance hit
+when writing out plotfiles. That increases to 22% with 16 processors. Again, upgrading to the latest BlueGene drivers should fix this issue.
+
+
+
+-------------------------------------------------------------------------------
+4. Building PnetCDF on UCAR BlueFire
+-------------------------------------------------------------------------------
+
+- the nc_test and nf_test tests use M4 to generate code. AIX-m4 won't
+ generate correct code, so use gnu M4.
+
+- We had a report of a build failure when building the 'ncmpigen' utility. The
+ system 'bison' tool (bison-1.875) did not produce output files, but when the
+ user installed a new version of gnu bison, everything worked fine.
+
+- the PnetCDF code is slowly taking on more and more c99 features.
+
+On BlueFire, the commands I used look like this:
+
+$ module add m4-1.4.14
+
+$ configure --prefix=/path/to/install \
+ CFLAGS=-qlanglvl=stdc99 \
+ CC=xlc FC=xlf F77=xlf F90=xlf90 \
+ MPICC=mpcc_r MPIF77=mpxlf_r MPIF90=mpxlf90_r CXX=xlC MPICXX=mpCC_r
+
+
+-------------------------------------------------------------------------------
+5. Building PnetCDF on IBM SP
+-------------------------------------------------------------------------------
+# John Tannahill <tannahill1 at llnl.gov> reported success building
+# parallel-netcdf on the 'seaborg' cluster (an IBM-SP at NERSC) and Tyce
+# Mclarty <mclarty3 at llnl.gov> reported success on LLNL's 'frost' cluster by
+# setting these environment variables:
+
+ setenv MPICC mpcc_r
+ setenv MPIF77 mpxlf_r
+ setenv F77 xlf
+ setenv FC xlf
+ setenv CC xlc
+ setenv CXX xlC
+
+# after setting these variables, configure/make/make install should "just work"
+
+
+# We also successfully tested 64-bit mode on 'DataStar' (an IBM-SP at SDSC)
+# with environment variables:
+
+ setenv OBJECT_MODE 64
+ setenv MPICC mpcc_r
+ setenv MPIF77 mpxlf_r
+ setenv F77 xlf
+ setenv FC xlf
+ setenv CC xlc
+ setenv CXX xlC
+ setenv CFLAGS -q64
+ setenv FFLAGS -q64
+ setenv F90FLAGS -q64
+ setenv CXXFLAGS -q64
diff --git a/README.LINUX b/README.LINUX
new file mode 100644
index 0000000..4ee9afe
--- /dev/null
+++ b/README.LINUX
@@ -0,0 +1,62 @@
+# $Id: README.LINUX 2082 2015-08-22 00:01:53Z wkliao $
+
+
+-----------------------------------------------------------------------------
+ Linux cluster using Intel compilers
+-----------------------------------------------------------------------------
+
+# here are the steps John Tannahill <tannahill1 at llnl.gov> used when
+# building PnetCDF on the "mcr" cluster at LLNL. It is a Linux cluster
+# with the Intel compilers.
+
+ setenv MPICC mpiicc
+ setenv MPIF77 mpiifc
+ setenv F77 ifc
+ setenv FC ifc
+ setenv CC icc
+
+# then run the usual "configure; make ; make install"
+
+On 5 October 2005, Richard Hedges reported that FFLAGS and CFLAGS needed the -O
+and -mp options or the test suite would report errors in the
+n[c,f]mpi_put_var*_float routines:
+
+FFLAGS = -O -mp
+CFLAGS = -O -mp
+
+
+-----------------------------------------------------------------------------
+ Jazz, a Linux cluster @ANL using Intel compilers
+-----------------------------------------------------------------------------
+# ;cat ~/.soft
+# #
+# # This is the .soft file.
+# # It is used to customize your environment by setting up environment
+# # variables such as PATH and MANPATH.
+# # To learn what can be in this file, use 'man softenv'.
+# #
+# #
+# @default
+# +pbs
+# +intel-7.0
+#
+# ---
+#
+# ;which mpicc
+# /soft/apps/packages/mpich-gm-1.2.5..9-pre6-gm-1.6.3-intel-7.0/bin/mpicc
+# ;which mpif77
+# /soft/apps/packages/mpich-gm-1.2.5..9-pre6-gm-1.6.3-intel-7.0/bin/mpif77
+# ;which icc
+# /soft/com/packages/intel-7/compiler70/ia32/bin/icc
+# ;which ifc
+# /soft/com/packages/intel-7/compiler70/ia32/bin/ifc
+#
+# ---
+
+setenv CC icc
+setenv FC ifc
+setenv F90 ifc
+setenv CXX icc
+setenv MPICC mpicc
+setenv MPIF77 mpif77
+
diff --git a/README.SGI b/README.SGI
new file mode 100644
index 0000000..88d6f96
--- /dev/null
+++ b/README.SGI
@@ -0,0 +1,46 @@
+# $Id: README.SGI 2082 2015-08-22 00:01:53Z wkliao $
+
+===============================================================================
+ SGI UV 2000
+===============================================================================
+Endeavour @ NASA
+http://www.nas.nasa.gov/hecc/resources/endeavour.html
+
+There are 2 compilers available on Endeavour: Intel and GNU.
+Intel compiler is recommended.
+
+To use Intel compiler, run command below to load the Intel compiler module.
+
+module load comp-intel
+module load mpi-intel
+
+run configure command:
+
+./configure --prefix=/path/to/install \
+ MPICC=icc MPICXX=icpc MPIF77=ifort MPIF90=ifort \
+ CFLAGS="-O2" FFLAGS="-O2" FCFLAGS="-O2" \
+ LIBS=-lmpi LDFLAGS=
+
+* Some users have their environment variable LDFLAGS set to "-shared",
+ which can prevent PnetCDF to build correctly. Please note PnetCDF
+ currently supports to build a static library only.
+
+It is also possible to build PnetCDF with GNU-based MPI compilers on Endeavour.
+Here is configure command.
+
+./configure --prefix=/path/to/install \
+ CFLAGS="-O2" FFLAGS="-O2" FCFLAGS="-O2" \
+ LDFLAGS=
+
+
+===============================================================================
+ SGI IRIX64
+===============================================================================
+The PnetCDF library should build fine under IRIX. There are just a few
+issues not directly related to the library:
+
+. The IRIX compiler does not like the cnap.c test. gcc compiles the
+ file without any warnings, even when the tests are configured with
+ "--enable-strict". Renier Vogelsang <reiner at sgi.com> reports that the
+ latest MIPSpro compiler release fixes this issue, so upgrade if
+ possible.
diff --git a/README.SX b/README.SX
new file mode 100644
index 0000000..5bee293
--- /dev/null
+++ b/README.SX
@@ -0,0 +1,37 @@
+# Current notes for NEC SX; based on pnetcdf version 1.0.0; 28 July, 2005
+
+. SX Cross compiler environment is not supported yet (the check for a working
+ ftruncate is not possible). Configure steps have to be invoked on the SX directly.
+ Configuring on the target host and then cross-compiling works fine when setting
+ up necessary aliases on the configure host (cc -> sxcc, etc) or vice versa
+ on the compile host (sxcc -> cc).
+
+. With the following environment variables a libpnetcdf.a has been
+ built successfully
+
+ MPICC=mpic++
+ MPIF77=mpif90
+ FC=f90
+ CC=c++
+ FFLAGS=-dW
+
+. Built on NEC SX6 with:
+ - Operating system SUPER-UX 14.1
+ - C++/SX compiler rev.061 2004/01/06
+ - f90/SX compiler rev.285 2003/09/25
+
+. Note on nf_test
+ -dW disables promotion of Integer*2. However no interfaces
+ for Integer*1 are built. This causes 2 compile time errors
+ in util.F . Lines 1158 and 1226 have to be turned into valid
+ Fortran syntax.
+
+. Note on test_dtype
+ The executables have to be compiled with -pvctl loopcnt=186048.
+ To avoid run time error in test_array the vectorisation of the
+ loop starting at line 256 needs to be disabled with
+ #pragma cdir novector
+
+Rob Latham <robl at mcs.anl.gov>
+Rene Redler <redler at ccrl-nece.de>
+Joachim Worringen <joachim at ccrl-nece.de>
diff --git a/README.large_files b/README.large_files
new file mode 100644
index 0000000..09096de
--- /dev/null
+++ b/README.large_files
@@ -0,0 +1,48 @@
+==== BACKGROUND
+
+The "traditional" netcdf file format (CDF-1) uses a 4-byte value to hold
+the offset into the file where one can find a variable's data
+
+Recently (October 2003), Greg Sjaardema <gdsjaar at sandia.gov> proposed a
+new file format (CDF-2) which uses an 8-byte value for the offset.
+We use his approach in parallel netcdf, though we have modified his
+patch against netcdf-3.5-beta1 to apply to our codebase.
+
+I couldn't find a URL to Greg's original message, but here's Russ Rew's
+followup:
+http://www.unidata.ucar.edu/projects/coohl/mhonarc/MailArchives/netcdf/msg04811.html
+
+This means there are two different but compatible implementations of the
+CDF-2 file format. We (the parallel netcdf developers) will make our
+best effort to keep our implementation compatible with the serial netcdf
+implementation. Please report any incompatibilities to the developers
+at parallel-netcdf at mcs.anl.gov.
+
+==== PRELIMINARIES
+
+First, it is important that your MPI-IO implementation uses an 8 byte
+type to represent the 'MPI_Offset'
+
+Second, your platform should use an 8 byte type to represent the 'off_t'
+type. On Linux, solaris, IRIX64 (and quite possibly others), parallel-netcdf
+will automatically add the right options to the compiler to make this
+happen.
+
+Run configure as you normally would. Let the developers know if
+configure says your 'off_t' is 4 bytes. Proceed to compile and install
+the library.
+
+==== USAGE
+
+By default, parallel-netcdf will create CDF-1 formatted files. This
+will ensure that datasets created by our library will be compatible with
+the large body of applications which expect NetCDF files to be CDF-1
+formatted.
+
+To write a CDF-2 formatted file, add the flag 'NC_64BIT_OFFSET' to the
+ncmpi_create() function call ( or nfmpi_create() if using the Fortran
+interface)
+
+The parallel-netcdf library will detect the format of the dataset.
+There are no special options needed to read back files created with the
+NC_64BIT_OFFSET flag set.
diff --git a/RELEASE_NOTES b/RELEASE_NOTES
new file mode 100644
index 0000000..8aff83d
--- /dev/null
+++ b/RELEASE_NOTES
@@ -0,0 +1,859 @@
+Parallel NetCDF Release Notes:
+=====================================
+
+-------------------------------------
+version 1.6.1 (June 1, 2015)
+-------------------------------------
+
+ o New features
+ * PnetCDF now supports fill mode. ncmpi_set_fill() can be used to set the
+ fill mode for the entire data set. Note the differences from netCDF:
+ 1. The default mode in PnetCDF is NC_NOFILL.
+ 2. Setting fill mode for the entire file or individual variables must be
+ done in define mode.
+ 3. For non-record variables, they are filled at the time ncmpi_enddef()
+ is called.
+ 4. For record variables, users must explicitly call ncmpi_fill_var_rec()
+ to fill one record at a time before writing to the record of that
+ variable.
+
+ o New APIs
+ * ncmpi_def_var_fill() sets fill mode for an individual variable. This API
+ must be called in define mode.
+ * ncmpi_inq_var_fill() inquires fill mode of a variable.
+ * ncmpi_fill_var_rec() is a collective API that fills a record of a record
+ variable. This API must be called at data mode.
+ * ncmpi_inq_default_format() for inquiring the default file format for
+ new file creation. Note the default format can be changed by
+ ncmpi_set_default_format().
+ * The above new API are also available in Fortran and C++ versions.
+
+ o New error code
+ * NC_ENOTRECVAR when attempting operation only for record variables
+ * NC_ENOTFILL when attempting to fill a variable when its fill mode is off
+ * NC_EMULTIDEFINE_FILL_MODE when inconsistent dataset fill mode is detected
+ * NC_EMULTIDEFINE_VAR_FILL_MODE when inconsistent variable fill mode is
+ detected
+ * NC_EMULTIDEFINE_VAR_FILL_VALUE when inconsistent variable fill value is
+ detected
+ * Fortran versions of the above error codes are also added.
+
+ o New example programs
+ * C/fill_mode.c shows the use of ncmpi_set_fill(), ncmpi_def_var_fill(),
+ ncmpi_inq_var_fill() and ncmpi_fill_var_rec()
+ F77/fill_mode.f is the Fortran version.
+ F90/fill_mode.f90 is the Fortran 90 version.
+ CXX/fill_mode.cpp is the C++ version.
+ * C/ghost_cell.c shows how to use varm API for writing from a user buffer
+ as a 2D array with ghost cells on both ends of every dimension.
+
+ o New test programs
+ * nc_test/tst_nofill.c borrowed from netCDF
+ * testcases/ivarn.c tests bug fix r2023 when the request IDs stored in
+ argument array_of_requests[] of ncmpi_wait_all() are not in an
+ increasing order.
+
+ o Other updates:
+ * Change the chunk size used for moving variable data when the file header
+ extent expands. The default is now 1MB. If the file's striping unit
+ size is known (from MPI-IO hint striping_unit) then the chunk size is
+ set to the striping unit size.
+
+ o Bug fixes
+ * Add missing F90 function overloading for f90mpi_put_var_all,
+ f90mpi_get_var_all, f90mpi_put_vard_all, and f90mpi_get_vard_all,
+ when the user buffer is a scalar.
+ * Fix when the request IDs passed in argument array_of_requests[] of
+ ncmpi_wait_all() are not in an increasing order. See r2023.
+ * Fix C++ compile error for converting NULL to string. See r2039.
+
+-------------------------------------
+version 1.6.0 (February 2, 2015)
+-------------------------------------
+
+ o Format conformation updates:
+ * Conform with netCDF4 on CDF-1 and CDF-2 formats. The only difference now
+ between the two formats are the OFFSET item in the format spec (32 vs.
+ 64 bit integers.) All names (variable, dimension, attribute) now allow
+ extended characters (e.g. special2 and MUTF8).
+
+ o New APIs
+ * Nonblocking buffered varn API family.
+ For C, ncmpi_bput_varn_<type>()
+ For F77, nfmpi_bput_varn_<type>()
+ For F90, nf90mpi_bput_varn()
+ For C++, NcmpiVar::bputVarn()
+ * Nonblocking varn API family.
+ For C, ncmpi_iput_varn_<type>() and ncmpi_iget_varn_<type>()
+ For F77, nfmpi_iput_varn_<type>() and nfmpi_iget_varn_<type>()
+ For F90, nf90mpi_iput_varn() and nf90mpi_iget_varn()
+ For C++, NcmpiVar::iputVarn() and NcmpiVar::igetVarn()
+ * Blocking vard API family takes an argument of MPI derived data type that
+ describes the file access layout, as opposed to vara and vars APIs that
+ use start[] and count[].
+ For C, ncmpi_put_vard() and ncmpi_get_vard()
+ For F77, nfmpi_put_vard() and nfmpi_get_vard()
+ For F90, nf90mpi_put_vard() and nf90mpi_get_vard()
+ For C++, NcmpiVar::putVard() and NcmpiVar::getVard()
+ * Collective var1 API family
+ For C, ncmpi_put_var1_all() ncmpi_get_var1_all()
+ ncmpi_put_var1_<type>_all() ncmpi_get_var1_<type>_all()
+ For F77, nfmpi_put_var1_all() nfmpi_get_var1_all()
+ nfmpi_put_var1_<type>_all() nfmpi_get_var1_<type>_all()
+ For F90, nf90mpi_put_var_all() nf90mpi_get_var_all()
+ For C++, NcmpiVar::putVar_all() NcmpiVar::getVar_all()
+ * ncmpi_inq_buffer_size() returns the size of buffer previously attached
+ for use of bput APIs. With ncmpi_inq_buffer_usage() one can calculate
+ the space remaining for additional bput requests.
+ For F77, nfmpi_inq_buffer_size()
+ For F90, nf90mpi_inq_buffer_size()
+ For C++, NcmpiFile::Inq_buffer_size()
+ * ncmpi_inq_recsize() returns the size of record block, i.e. the sum of
+ single records of all record variables.
+ For F77, nfmpi_inq_recsize()
+ For F90, nf90mpi_inq_recsize()
+ For C++, NcmpiGroup::getRecSize()
+ * ncmpi_inq_num_rec_vars() and ncmpi_inq_num_fix_vars() report the number
+ of record and fixed-size variables, respectively.
+ For F77, nfmpi_inq_num_rec_vars() and nfmpi_inq_num_fix_vars()
+ For F90, nf90mpi_inq_num_rec_vars() and nf90mpi_inq_num_fix_vars()
+ For C++, NcmpiGroup::getRecVarCount() and NcmpiGroup::getFixVarCount()
+
+ o New PnetCDF hint
+ * pnetcdf_subfiling -- it can be set in an MPI info object or in the
+ environment variable PNETCDF_HINTS to enable/disable subfiling.
+ The value is either "enable" or "disable".
+
+ o PnetCDF hint priority
+ * The alignment hints set in the environment variable "PNETCDF_HINTS" have
+ the highest priority, which overwrite the alignment hints set in
+ ncmpi__enddef(), which overwrite the alignment hints set in the MPI_Info
+ object used in the call of ncmpi_create() and ncmpi_open().
+
+ o New error code
+ * NC_ESTRICTCDF2 for attempting CDF-5 operation on CDF-2 file. For
+ example, define a variable of type NC_INT64 in a CDF-2 file.
+ * NC_ETYPESIZE when filetype size is bigger than the variable size
+ * NC_ETYPE_MISMATCH when the element type of filetype mismatches the
+ variable type
+ * NC_ETYPESIZE_MISMATCH when filetype size mismatches buffer type size
+ * NC_ENULLSTART when argument start is a NULL pointer
+ * NC_ENULLCOUNT when argument count is a NULL pointer
+ * NC_EINVAL_CMODE when invalid file create mode is set, (e.g. cannot have
+ both NC_64BIT_OFFSET & NC_64BIT_DATA. In PnetCDF 1.5.0 and earlier
+ versions, if both flags were set, then NC_64BIT_DATA triumphs
+ NC_64BIT_OFFSET.)
+
+ o New example programs
+ * C/bput_varn_uint.c and F77/bput_varn_int8.f show the use of
+ nonblocking bput_varn APIs
+ * C/i_varn_int64.c and F77/i_varn_real.f show the use of nonblocking
+ iput_varn and iget_varn APIs
+ * C/vard_int.c F77/vard_int.f F90/vard_int.f90 CXX/vard_int.cpp show the
+ use of vard API to write/read record and fixed-size variables.
+ * C/transpose.c shows the use of ncmpi_put_vara_int_all to write a 3D array
+ that is dimensional-transposed from the one stored in memory. Six
+ transposed 3D arrays are saved whose dimensions are organized as ZYX,
+ ZXY, YZX, YXZ, XZY, and XYZ. The C++, Fortran 77, and Fortran 90
+ versions are also provided.
+
+ o New test program
+ * nonblocking/wait_after_indep.c tests if ncmpi_end_indep_data() returns
+ properly when nonblocking APIs are called in independent data mode and
+ the wait call is made after exiting the independent mode.
+ * nonblocking/flexible_bput.c tests flexible bput APIs that use
+ noncontiguous buffer type, noncontiguous imap and require type conversion
+ * testcases/flexible2.c tests flexible APIs that perform type conversion
+ * testcases/flexible_varm.c tests flexible varm APIs
+ * testcases/varn_contig.c tests the case when the fileview is actually a
+ contiguous chunk. PnetCDF should be able to merge all.
+ * nonblocking/bput_varn_uint.c tests nonblocking bput_varn APIs
+ * nonblocking/i_varn_int64.c tests nonblocking iput_varn and iget_varn APIs
+ * test/testcases/test_vard.c test/testcases/test_vardf.f
+ test/testcases/test_vardf90.f90 test the new vard APIs.
+ * test/testcases/inq_recsize.c tests if one can correctly inquire the
+ size of record block from in a netCDF file. A similar program in F90,
+ named inq_recsizef.f90, is also added.
+ * In test/nc_test, the test programs below are borrowed from netCDF test
+ programs: t_nc.c tst_misc.c tst_norm.c tst_small.c tst_names.c
+ tst_atts3.c tst_atts.c
+ * test/testcases/one_record.c tests the special case defined in CDF-1 and
+ CDF-2 specification that "A special case: Where there is exactly one
+ record variable, we drop the requirement that each record be four-byte
+ aligned, so in this case there is no record padding."
+ * test/testcases/modes.c tests if correct error codes are returned when
+ various file create/open modes are used.
+ * Under test/testcases, varn_int.c varn_intf.f varn_real.f90 test varn APIs
+ * test/testcases/inq_num_vars.c test if one can correctly inquire the
+ numbers of record and fixed-size variables defined in a netCDF file.
+ A similar program in F90, named inq_num_varsf.f90, is also added.
+ * test/nonblocking/interleaved.c tests a combination of interleaved
+ file types. This is to test the bug fix in r1758.
+
+ o New optimization
+ * Prior to this release, PnetCDF wraps each MPI read/write call in put/get
+ APIs with two MPI_File_set_view(). One is before the MPI read/write call
+ to take advantage of MPI's fileview feature for accessing non-contiguous
+ file locations. The other is after the MPI read/write call to make the
+ whole file visible, as the root process may write to file header later
+ in the data mode and it alone cannot make a call to MPI_File_set_view()
+ because the function is collective.
+
+ In this release, the second MPI_File_set_view() has been removed. The
+ root process's fileview is changed to always keep the whole file header
+ visible. Saving a collective call to MPI_File_set_view() is expected to
+ improve some performance.
+
+ o Semantics updates
+ * Header consistency mechanism has been updated. See README.consistency for
+ details.
+ * The use of NC_SHARE is also revised. See README.consistency for details.
+
+ o Other updates:
+ * The subfiling feature is now disabled in ncmpidump and ncmpidiff until
+ a bug fix to allow reading the master file with the number of processes
+ that is smaller than the number of subfiles.
+ * The attribute names reserved for subfiling feature are now changed to
+ use a prefix of "_PnetCDF_SubFiling". The leading "_" underscore is a CDL
+ convention.
+ * The flexible APIs now allow argument buftype to be MPI_DATATYPE_NULL.
+ In this case, argument bufcount is ignored and argument buf's data type
+ must match the data type of variable defined in the file - no data
+ conversion will be done. This extension makes the flexible APIs be
+ able to correspond to the netCDF APIs whose names do not contain a data
+ type, e.g. nc_put_vara().
+ * Type conversion between NC_BYTE and unsigned char no longer checks for
+ out of range error (NC_ERANGE). CDF file format specification make a
+ special case for this kind of data type conversion. See: "Note on byte
+ data" in the format specification.
+ * Conform with the CDF-2 and CDF-5 formats that names are normalized
+ according to Unicode NFC normalization rules during encoding as UTF-8
+ for storing in the file header.
+ * A new configure option, --enable-large-file-test, to enable testing
+ I/O on large files and large variables. Note the testing programs will
+ run very slowly.
+
+ o Bug fixes
+ * fix the bug for flexible get_varn API. When buftype is noncontiguous, the
+ bug forgot to "unpacks" the temporary buffer that reads data from file to
+ the user buffer using buftype.
+ * fix the bug in blocking flexible get APIs when buftype is noncontiguous,
+ swap is needed, type conversion is not. The bug sets a NULL pointer to
+ the read buffer and passes it to MPI_File_read functions. See r1815.
+ * fix the bug for the NetCDF special case when there is only one record
+ variable and the record size is not four-byte aligned. In this case,
+ NetCDF spec says the alignment must dropped (no padding). See r1791.
+ * fix the bug in nonblocking APIs when requests are resorted into
+ nonoverlapping groups and the first group of file types are interleaved,
+ it was mistakenly identified as non-interleaved. See r1758.
+ * fix the setting for PNETCDF_RELEASE_DATE in configure.in. Using read
+ command together with IFS does not work as expected in bash 4.3.11. See
+ http://lists.mcs.anl.gov/pipermail/parallel-netcdf/2014-July/001586.html
+ for further detailed discussion.
+
+-------------------------------------
+version 1.5.0 (July 8, 2014)
+-------------------------------------
+
+ o New features
+ * A new configure option "--disable-in-place-swap" is added. It disables
+ the byte-swap operations running in-place on the user's write buffers.
+ The purpose of providing this option is to deal with the problem when a
+ Fortran program uses a immutable buffer for put APIs, e.g. the buffer is
+ declared as a PARAMETER, and in-place byte swap on this buffer causes
+ segmentation fault. See discussion threads of
+ http://lists.mcs.anl.gov/pipermail/parallel-netcdf/2013-July/001498.html
+
+ Impacts:
+ 1. It takes effect only on Little Endian machines.
+ 2. It only affects put/iput data APIs, but not attribute APIs.
+ 3. The INTENT of buffer arguments in all Fortran 90 put/iput APIs will be
+ declared as "IN". Without this setting, the default is "INOUT".
+ 4. It has an impact on performance, as an extra internal temporary buffer
+ will be allocated to copy data over from user's put buffer, so byte
+ swap can be run on the temporary buffer.
+
+ The default setting is to enable in-place byte swap. PnetCDF tries not to
+ allocate additional memory space, due to performance concern. Users are
+ discouraged to use Fortran PARAMETER buffers in put APIs.
+
+ * A new configure option "--enable-debug" is added. It enables a memory
+ allocation tracing mechanism internal in PnetCDF. In addition, it enables
+ the PnetCDF safe mode. (Note that setting the environment variable
+ PNETCDF_SAFE_MODE at the run time can still overwrite the safe mode.)
+ Default debug mode is disabled. When enabled, a user program can call
+ three new APIs below: ncmpi_inq_malloc_size, ncmpi_inq_malloc_max_size,
+ and ncmpi_inq_malloc_list to obtain the size in bytes of current memory
+ allocated internally. This feature uses a binary tree to manage all
+ malloc buffers, e.g. tsearch() and tdelete().
+
+ * Add three Fortran parameters for PnetCDF library version numbers:
+ PNETCDF_VERSION_MAJOR, PNETCDF_VERSION_MINOR, and PNETCDF_VERSION_SUB.
+ Similarly in C programs, these are defined in pnetcdf.h as constants.
+
+ o New APIs
+ * C++ APIs are now available. They are developed based on netCDF-4 C++
+ library. However, users are encouraged to use C APIs, instead C++.
+
+ * ncmpi_put_att, ncmpi_get_att, nfmpi_put_att, and nfmpi_get_att - these
+ APIs correspond to nc_put_att, nc_get_att, nf_put_att, and nf_get_att.
+ Note they are not the "flexible" APIs. Flexible APIs have an MPI derived
+ datatype argument.
+
+ * ncmpi__enddef, nfmpi__enddef, and nf90mpi_enddef - these APIs correspond
+ to netCDF nc__enddef, nf__enddef, and nf90_enddef (with additional
+ optional arguments).
+
+ * ncmpi_inq_file_info - the naming for ncmpi_get_file_info may cause
+ confusion, as "get" has a different meaning on PnetCDF. The correct
+ name should use "inq". However, ncmpi_get_file_info is kept for backward
+ compatibility.
+
+ * ncmpi_inq_striping, nfmpi_inq_striping, nf90mpi_inq_striping report the
+ file system striping settings of the opened file: striping size and
+ striping count, if the underneath MPI-IO can find their values from the
+ file system in use.
+
+ * ncmpi_inq_malloc_size, ncmpi_inq_malloc_max_size, ncmpi_inq_malloc_list
+ report the size in bytes of current memory allocated internally by
+ PnetCDF. Similar APIs for Fortran 77 and 90 are also available. These
+ APIs are enabled only when PnetCDF is configured with option
+ --enable-debug. When this option is not enabled, calling these APIs will
+ return the error code NC_ENOTENABLED. These APIs are usefully for
+ debugging.
+
+ * ncmpi_inq_files_opened reports the number of files that are currently
+ opened. Similar API for Fortran 77 and 90 are also available. The API
+ takes 2 arguments: number of files and array of file IDs. If the second
+ argument, array of IDs, is not NULL, then it will filled with the netCDF
+ dataset IDs. This API is useful for debugging.
+
+ o Syntax changes
+ * For all Fortran put/iput APIs, the INTENT of write buffer arguments is
+ changed to "INOUT" on Little Endian machines, if option
+ "--disable-in-place-swap" is not used at configuration. Otherwise, i.e.
+ on Big Endian machines or PnetCDF is configured with
+ "--disable-in-place-swap" on Little Endian machines, the INTENT is "IN".
+
+ o New PnetCDF hint
+ * nc_record_align_size - aligns the starting file offset of the record
+ variable section. Note this is for the entire section, not individual
+ records.
+
+ o New error code
+ * NC_ENOTENABLED indicates the API is available only when the corresponding
+ feature is enabled. For example, nfmpi_inq_malloc_size() returns this
+ error code when "--enable-debug" is not used at configure.
+
+ * NC_EBAD_FILE corresponds to MPI error code MPI_ERR_BAD_FILE, meaning
+ "Invalid file name (e.g., path name too long)."
+
+ * NC_ENO_SPACE corresponds to MPI error code MPI_ERR_NO_SPACE, meaning
+ "Not enough space."
+
+ * NC_EQUOTA corresponds to MPI error code MPI_ERR_QUOTA, meaning
+ "Quota exceeded."
+
+ * NC_EMULTIDEFINE_FNC_ARGS corresponds to MPI error code MPI_ERR_NOT_SAME,
+ meaning "inconsistent function arguments used in collective API."
+
+ o New run-time environment variables
+ * none
+
+ o New example programs
+ * Example programs now report if there is any PnetCDF internal malloc
+ residues yet to be freed, if --enable-debug option is used at
+ configure.
+
+ * Under examples/C, three examples are added: create_open.c, get_vara.c,
+ and global_attributes.c. File examples/README contains their
+ descriptions.
+
+ * Under examples/CXX, several example programs corresponding to those in
+ examples/C are added.
+
+ o New programs for I/O benchmarks
+ * none
+
+ o New test program
+ * Many test programs now report if there is any PnetCDF internal malloc
+ residues yet to be freed, if --enable-debug option is used at configure.
+
+ * add tests for flexible APIs. The tests borrow from nc_test/test_write.c
+ that tests nc_put_var1, nc_put_vara, nc_put_vars, and nc_put_varm.
+ Similarly for get APIs.
+
+ * testcases/record.c checks if the number of records is updated correctly.
+ It writes to a variable's 2nd record followed by the 1st record. A call
+ to ncmpi_inq_dim() or ncmpi_inq_dimlen() should report 2 records after
+ the writes complete.
+
+ * testcases/noclobber.c checks if error code NC_EEXIST can be returned
+ correctly when NC_NOCLOBBER modes is used in ncmpi_create and in the
+ meantime the file exists.
+
+ * Some test programs are developed to run in parallel. The test mechanism
+ for parallel runs is command "make ptest". Two environment variables
+ can be used to set the MPI run command and output file directory:
+ TEST_MPIRUN and TEST_OUTDIR. Their defaults are mpiexec and "." (current
+ directory), respectively. For example,
+ make ptest TEST_MPIRUN="aprun -n NP" TEST_OUTDIR=/scratch
+ Note the keyword "NP" will be replaced by the different numbers of
+ processes used to run the tests. The testing uses up to 8 MPI processes.
+
+ * A sample PBS script file is provided to test "make ptest" on machines
+ with a batch queue system: pbs.script. This example script can be
+ submitted from the build root directory (where you run "make" command to
+ build PnetCDF library).
+
+ * For cross compile environment (and batch queue system), the environment
+ variable TEST_SEQRUN can be used to set the MPI run command. For example,
+ the command for testing sequential programs:
+ make check TEST_SEQRUN="aprun -n 1" TEST_OUTDIR=/scratch
+
+ For non-cross compile environment, there is no need to set the environment
+ variables, as long as one can run the MPI executable without mpirun or
+ mpiexec.
+
+ o New optimization
+ * none
+
+ o New utility program
+ * pnetcdf_version prints the version information of the PnetCDF library and
+ command-line arguments used at configure
+
+ o Other updates:
+ * Revise FLASH-IO benchmark to use nonblocking APIs for both checkpoint and
+ plot writes. The control variable to switch between nonblocking and
+ blocking API is "use_nonblocking_io". Set it to .FALSE. in
+ flash_benchmark_io.F90 to switch to blocking APIs. Using nonblocking APIs
+ is now the default.
+
+ * To match ncdump, ncmpidump now only supports one input file.
+
+ * Makefiles are revised for better recursive make and fixed some build
+ target dependency for parallel make.
+
+ * File creation was revised for handling NC_CLOBBER and NC_NOCLOBBER modes.
+ On systems where Unix calls access() and unlink() are available, they
+ are used to check if a file exits and to delete an existing file.
+
+ * subfiling is now enabled by default. Users can use --disable-subfiling to
+ disable it
+
+ * man page of ncmpigen is updated to add the description for option "-v"
+ which lets users to specify the desired output file formats, e.g.
+ CDF-1, CDF-2, or CDF-5.
+
+ * flex, lex, bison, or yacc are no longer needed for building ncmpigen.
+
+ o Bug fixes
+ * fix ncmpigen.y on parsing CDL file to get the number of records. The bug
+ failed the command "make b-test", due to getting a wrong number of
+ records (current value for the unlimited dimension).
+
+ * fix the update for number of records when writing to a record that is
+ not the last record.
+
+-------------------------------------
+version 1.4.1 (December 23, 2013)
+-------------------------------------
+
+ o Bug fix:
+ * Improve pnetcdf.inc portability for fixed/free-form Fortran programs
+
+ o Fortran API syntax changes
+ * For nfmpi_put_att and nf90mpi_put_att family, the intent modifier for
+ the put buffer arguments are now declared as INTENT(IN).
+ * For nfmpi_put_var* and nf90mpi_put_var family
+ + On Big Endian machines, the the intent modifier for the put buffer
+ arguments are now declared as INTENT(IN).
+ + On Little Endian machines, the the intent modifier for the put buffer
+ arguments are still declared as INTENT(INOUT). This is because PnetCDF
+ does in-place byte-swap on user's put buffer. If user's buffer is
+ declared as parameter, then segment fault can happen when PnetCDF
+ tries to byte-swap a read-only memory.
+
+ o Subfiling
+ * Subfiling is a new PnetCDF feature that divides a file transparently
+ into several smaller subfiles, each of which stores subarrays
+ in CDF file formats. The file name supplied by the users serves as a
+ master file that contains all metadata about array partitioning
+ information among the subfiles. Because data partitioning is made
+ transparently from users, data accessing is kept the same through
+ the conventional PnetCDF APIs and the master file.
+ * To enable this feature at configure time, add configure option
+ "--enable-subfiling".
+
+
+-------------------------------------
+version 1.4.0 (November 17, 2013)
+-------------------------------------
+
+ o New APIs
+ * Fortran 90 APIs (adopted from netcdf-fortran-4.2). All F90 APIs have
+ prefix name "nf90mpi_". The APIs support function overloading.
+ * get/put_varn_<type> for reading/writing a list of subrequests (each is
+ specified by starts[i][ndims] and counts[i][ndims] for subrequest i.
+ ndims is the number of dimension of the variable) to a single variable.
+ * multiple put/get requests with explicit buffer type names:
+ ncmpi_mput_var_type(), ncmpi_mput_var1_type(), ncmpi_mput_vara_type(),
+ ncmpi_mput_vars_type(), ncmpi_mput_varm_type(). Similar for get APIs.
+ "type" is one of the followings: text, schar, uchar, short, ushort, int,
+ uint, long, float, double, longlong, or ulonglong.
+ * ncmpi_inq_nreqs() reports the number of pending nonblocking requests
+ * ncmpi_inq_header_size() reports the size of the file header
+ * ncmpi_inq_header_extent() reports the space currently allocated for the
+ file header, (also the file offset of the first variable)
+ * ncmpi_inq_put_size() reports the write amount committed by far
+ * ncmpi_inq_get_size() reports the read amount committed by far
+ * ncmpi_sync_numrecs() a collective API that can be called in independent
+ data mode to synchronize the number of records in memory across all
+ processes, and update to the file if NC_SHARE is set.
+
+ o Syntax change for Fortran put APIs
+ * intent of buffer argument in all Fortran APIs is changed to inout, as
+ byte-swap might be performed directly on the buffer. This change is
+ for performance consideration. For example, if the buffer is declared
+ as Fortran parameter, then compile will fail.
+
+ o New PnetCDF hint
+ * nc_header_read_chunk_size: PnetCDF reads the file headers in chunks. This
+ hint indicates the chunk size (in bytes). The default is 256 KB.
+
+ o New error code
+ * NC_EINTOVERFLOW reports the error of 4-byte integer overflow. This
+ usually happens due to MPI-IO data type constructor APIs' arguments using
+ 4-byte integers.
+ * Error codes to report metadata defined inconsistently across processes.
+ NC_EMULTIDEFINE_OMODE - create/open mode
+ NC_EMULTIDEFINE_DIM_NUM - number of dimensions
+ NC_EMULTIDEFINE_DIM_SIZE - size of dimension
+ NC_EMULTIDEFINE_DIM_NAME - dimension names
+ NC_EMULTIDEFINE_VAR_NUM - number of variables
+ NC_EMULTIDEFINE_VAR_NAME - variable name
+ NC_EMULTIDEFINE_VAR_NDIMS - variable's number of dimensions
+ NC_EMULTIDEFINE_VAR_DIMIDS - variable's dimid
+ NC_EMULTIDEFINE_VAR_TYPE - variable's data type
+ NC_EMULTIDEFINE_VAR_LEN - variable's size
+ NC_EMULTIDEFINE_NUMRECS - number of records
+ NC_EMULTIDEFINE_VAR_BEGIN - variable file begin offset
+ NC_EMULTIDEFINE_ATTR_NUM - number of attributes
+ NC_EMULTIDEFINE_ATTR_SIZE - memory space used by attribute
+ NC_EMULTIDEFINE_ATTR_NAME - attribute name
+ NC_EMULTIDEFINE_ATTR_TYPE - attribute type
+ NC_EMULTIDEFINE_ATTR_LEN - attribute length
+ NC_EMULTIDEFINE_ATTR_VAL - attribute value
+
+ o New run-time environment variables
+ * PNETCDF_SAFE_MODE environment variable can be used to enable/disable the
+ internal checking for data/argument consistency across all processes (by
+ calling collective MPI_Allreduce). Set it to 1 to enable the checking.
+ Default is 0, i.e. disabled.
+ * PNETCDF_HINTS environment variable can be used to pass the I/O hints to
+ PnetCDF library. Hints include both PnetCDF and MPI-IO hints.
+ PNETCDF_HINTS is a string of hints separated by ";" and each hint is in
+ the form of hint=value. E.g.
+ romio_ds_write=disable;nc_header_align_size=1048576
+ If this environment variable is set, it overrides any values that
+ were set by using calls to MPI_Info_set in the application code.
+
+ o New example programs
+ * example programs are now categorized into C, F77, and F90 directories
+ * nonblocking_write.f and nonblocking_write.f90 are the Fortran version of
+ nonblocking_write.c
+ * put_varn_float.c for using the new APIs ncmpi_put_varn_float_all()
+ put_varn_real.f and put_varn_real.f90 are the Fortran versions
+ * put_varn_int.c, put_varn_int.f, and put_varn_int.f90, for using the new
+ APIs ncmpi_put_varn_int_all() and nfmpi_put_varn_int_all()
+ * hints.c, hints.f, and hints.f90 for using PnetCDF hints
+ * flexible_api.c, flexible_api.f, and flexible_api.f90, for using blocking
+ and nonblocking flexible APIs
+ * mput.c for using ncmpi_mput_vara_all() to write a series of arbitrary
+ start[] and count[]
+ * block_cyclic.c, block_cyclic.f, and block_cyclic.f90 are for a
+ *-(block-cyclic) 2D partitioning pattern
+ * column_wise.c, for a *-cyclic 2D partitioning pattern
+ * put_vara.c, put_vara.f, and put_var.f90 for using for
+ nfmpi_put_vara_int_all()
+
+ o New programs for I/O benchmarks
+ * benchmarks/C/aggregation.c -- evaluate PnetCDF's performance on I/O
+ aggregation across multiple requests with different data access patterns.
+ * benchmarks/C/write_block_read_column.c -- writes variables and reads back
+ using different data partitioning patterns
+ * benchmarks/FLASH-IO -- I/O kernel of FLASH, a reacting hydrodynamics code
+ developed at University of Chicago. This benchmark can be built
+ independently from PnetCDF release.
+
+ o New test program
+ * test/F90 contains test programs adopted from netcdf-fortran-4.2
+ * test/nf90_test contains test programs adopted from test/nf_test
+ * testcases/alignment_test.c -- test for header and fixed variable file
+ offset alignments when entering redef mode
+ * testcases/nonblocking.c -- test nonblocking APIs ncmpi_iput_vara_int()
+ and ncmpi_iget_vara_int()
+ * testcases/flexible.c -- test flexible API ncmpi_get_vara_int_all() using
+ an MPI derived data type created by MPI_Type_create_hindex()
+ * test/header/header_consistency.c -- test header inconsistency and see if
+ inconsistent metadata is overwritten by root's
+
+ o New semantics for attribute APIs in data mode
+ The following APIs can modify file header while being called in data mode.
+ Note that these APIs can only modify existing attributes, rename variables
+ or dimensions, given that the new attributes and names do not take more
+ file space than the old ones. Otherwise, these APIs are prohibited in data
+ mode.
+ ncmpi_rename_dim(),
+ ncmpi_rename_var(),
+ ncmpi_copy_att(),
+ ncmpi_rename_att(), and
+ ncmpi_put_att_<type>()
+ Starting from this release of PnetCDF, these APIs must be called
+ collectively when in data mode. This new requirement is to ensure the
+ file header cached in memory is consistent across all processes.
+
+ o New synchronization for number of records
+ In collective data mode, the number of records cached in memory is
+ always synchronized across all processes. In independent mode, the value
+ can be inconsistent, unless ncmpi_sync_numrecs() (a collective API) is
+ called explicitly. Otherwise, the synchronization will have to wait until
+ the call to ncmpi_end_indep_data().
+
+ Flushing the number of records to file when it is changed used to be
+ delayed until ncmpi_close() or ncmpi_sync() is called. If a strong file
+ consistency is desired, users must enable NC_SHARE mode when opening the
+ file. However, note that in this mode any header change will cause file
+ I/O to flush the dirty header data (not just number of records). For
+ programs that do not change header frequently, enabling NC_SHARE should
+ have no significant performance impact.
+
+ This flushing behavior has been changed in 1.4.0 to the following. At the
+ end of collective calls, if the number of records increases, the changed
+ value will be written to the file, no matter if NC_SHARE mode is used or
+ not. This change is to ensure the number of records is up-to-dated in
+ file, in case the application program does not close file (due to crash
+ or programming error). Note this change applies to collective APIs only.
+
+ o New optimization: I/O request aggregation
+ The original design of nonblocking I/O is to concatenate the fileviews of
+ individual nonblocking requests and serve them with a single MPI-IO call,
+ if possible. However, because MPI-IO requires the file displacements of
+ the flattened fileview be in an monotonically nondecreasing order, the
+ original approach (in v1.3.1 and prior) divides the nonblocking requests
+ into groups such that each group abides by this MPI-IO fileview
+ requirement. Each group is then carried out by a separate MPI-IO call.
+ Performance can be poor if there are multiple groups and each group's
+ aggregate access region is non-contiguous in the file.
+
+ This revision fixes this problem by 1) sorting the starting offset of all
+ nonblocking requests into a non-decreasing order; 2) dividing the requests
+ into groups (two types of groups are identified: interleaving and
+ non-interleaving); 3) for each non-interleaving group, concatenating
+ fileviews of all requests in the group; 4) for each interleaving group,
+ flattening fileviews of all requests in the group, merging the
+ offset-length pairs, and concatenating them into a new integrated fileview;
+ 5) concatenating the fileviews of all groups into a single one; 6) the
+ final combined fileview is used by a single MPI-IO call to carry out the
+ requests. Performance is expected to be improved as the number of MPI-IO
+ calls is reduced to one.
+
+ However, be warned about the additional memory requirement. The additional
+ memory needed for flattening the fileviews might be more than the I/O data
+ itself. For example, a request to accessing a single column of a 2D integer
+ array will result in offset-length pairs, each representing only a 4-byte
+ integer where the C struct in PnetCDF for storing an offset-length pair
+ takes 3*sizeof(MPI_Offset)=24 bytes (offset, length, and I/O buffer
+ pointer).
+
+ o Other updates:
+ * configure.in and Makefile.in have been revised to detect MPI compilers
+ and other compile options automatically.
+ * A new configure option "--disable-file-sync" to disable calling file
+ sync. This is to be used when the underlying file system provides data
+ consistency control.
+ * add build recipe for IBM BGQ (e.g. Vesta/Mira/Cetus @ANL) in README.IBM
+ * add build recipe for CRAY-XE6, Hopper @NERSC in README.CRAY
+ * add build recipe for CRAY-XC30, Edison @NERSC in README.CRAY
+ * add build recipe for Endeavour @ NASA in README.SGI
+ * add declaration of flexible APIs for Fortran90
+ * "make testing" now hides most of the stdout. Use "make verbose_testing"
+ for verbose output.
+ * ncmpidump: add the command-line option "-k" to report the format of
+ netCDF file.
+ * ncvalid is renamed to ncmpivalid, a tool to validate the structure of
+ netCDF files for conforming with CDF formats.
+ * Fortran type NFMPI_OFFSET is removed. It was merely a shortcut to
+ integer(KIND=MPI_OFFSET_KIND). Some Fortran 77 compiler does not
+ recognize keyword KIND. In that case, please set MPIF77 to the MPI
+ Fortran 90 compiler, e.g. ./configure MPIF77=mpif90
+ * configure now automatically checks Fortran module compile flags
+ * Support additional Fortran netCDF data types: nf_ubyte, nf_ushort,
+ nf_uint, nf_uint64, nf90_ubyte, nf90_ushort, nf90_uint, nf90_uint64.
+ * Error codes and messages conform with netCDF's
+
+ o Bug fixes
+ * Argument unlimdimid of nfmpi_inq() returns -1 when no unlimited length
+ dimension has been defined (to conform nf_inq()).
+ * Argument varid of nfmpi_inq_varoffset() is fixed to be the C's varid
+ plus one.
+ * For collective APIs, many places have been changed to prevent program
+ from hanging if a subset of the processes got errors. The fix will allow
+ all processes participating the MPI collective calls in the PnetCDF, even
+ if errors are detected on a subset of processes.
+ * set the nonblocking request ID to NULL when the request length is zero
+ * report error when bogus request IDs are passed in ncmpi_wait
+ * when entering redef with different alignment hints, fixed-size
+ variables' file starting offsets will only be changed when it is bigger
+ than the old ones
+ * Fix some Fortran API intent in/out argument declarations
+ * ncmpi_def_var is fixed to detect if CDF-5 data types is used on CDF-1 or
+ CDF-2 files. Error code NC_ESTRICTNC3 will return.
+
+
+
+-------------------------------------
+version 1.3.1 (September 24, 2012)
+-------------------------------------
+
+ This release is primarily a bug-fix release, tidying up a few issues and
+ incorporating some early feedback on our "buffered put" interface (see
+ http://trac.mcs.anl.gov/projects/parallel-netcdf/wiki/BufferedInterface for
+ more information)
+
+ - add a new API ncmpi_inq_buffer_usage/nfmpi_inq_buffer_usage for inquiring
+ the current usage of the internal buffer allocated by the "buffered"-put
+ APIs.
+ - bug fix to make bput APIs properly return error code NC_EINSUFFBUF.
+ - bug fixes for ncmpidump to avoid residue contents from a previous read
+ when it read beyond EOF.
+ - bug fixes in the tutorial example codes.
+ - add more in-line comments for the tutorial example codes.
+ - add the error string for error code NC_ENOENT.
+
+-------------------------------------
+version 1.3.0 (June 26, 2012)
+-------------------------------------
+
+ - Bug fixes in new ncmpidiff tool.
+ - Small optimizations to reduce communication in library.
+ - Improved documentation, including more test programs and a QuickTutorial.
+ - Bug fixes in our Fortran90 support.
+ - Better compatibility with NetCDF-4: no need for a modified pnetcdf.h from
+ Unidata when building NetCDF-4 with PnetCDF support.
+ - PnetCDF now duplicates the MPI communicator internally, which fixed at
+ least one odd behavior seen in a PnetCDF-using application.
+ - Improvements to PnetCDF header and variable alignment (see wiki page
+ VariableAlignment).
+ - Add a checking for file create mode consistency across all processes and
+ an error code for it, NC_ECMODE.
+ - Bug fix for updating the number of record variables in nonblocking APIs.
+ - Bug fix for variable starting file offsets when defining multiple large
+ variables (> 232 elements) in one CDF-5 file.
+ - Add a new configure option that takes environment variable $RM to replace
+ the default "rm" command in all Makefiles.
+ - Bug fix for nonblocking varm APIs.
+ - Support for CDF-2's special2 characters in names (variables, attributes,
+ dimensions, etc.)
+ - Release of the official CDF-5 file format specification (see wiki page
+ CD-5).
+ - Support for CDF-5 data types: NC_UBYTE, NC_USHORT, NC_UINT, NC_INT64,
+ NC_UINT64, and NF_INT64.
+ - New C APIs: ncmpi_put_vara_ushort, ncmpi_put_vara_uint,
+ ncmpi_put_vara_longlong, and ncmpi_put_vara_ulonglong. Similarly for
+ var1, var, vars and varm APIs. Also for get and nonblocking APIs.
+ - New Fortran APIs: nfmpi_put_vars_int8 and similarly for var1, var, vars,
+ varm, get, and nonblocking APIs.
+ - Add a new error code, NC_ENOTSUPPORT, for not-yet-supported features.
+ - A new set of buffered put APIs (eg. ncmpi_bput_vara_float) is added (see
+ BufferedInterface). They make a copy of the user's buffer internally, so
+ the user's buffer can be reused when the call returns. Their usage are
+ similar to the iput APIs.
+ - Add new error codes for buffered put APIs: NC_ENULLBUF,
+ NC_EPREVATTACHBUF, NC_ENULLABUF, NC_EPENDINGBPUT, and NC_EINSUFFBUF.
+ - Add new test and example programs for the buffered put APIs.
+ - The error string returned by ncmpi_strerror() for an undefined error code
+ is updated from "Unknown Error" to "Unknown Error: Unrecognized PnetCDF
+ error code ID" to be more descriptive.
+ - Remove the use of POSIX error codes: EINVAL, ENOERR, ERANGE, and ENOMEM.
+ They are replaced by NC error codes now: NC_EINVAL, NC_NOERR, NC_ERANGE,
+ and NC_ENOMEM.
+ - A better translation of MPI-IO error classes to netCDF/PnetCDF error
+ codes. For example, MPI-IO error class MPI_ERR_NO_SUCH_FILE is translated
+ to NC_ENOENT.
+
+ - Compatibility note
+
+ - In testing with version 11.7 of the Portland Group compiler, some of the
+ Fortran test programs fail to compile if built with pgf77. The tests work
+ if built with the Fortran90 compiler.
+
+-------------------------------------
+version 1.2.0 (August 19, 2010)
+-------------------------------------
+
+ - Several bugs fixed, memory leaks reduced,
+
+ - Internal housekeeping
+
+ - Reduce the places where PnetCDF will call MPI_FILE_SYNC
+
+ - A new 'ncmpidiff' utility to compare two datasets in parallel
+
+ - Addressed a build failure when compiling with some versions of MVAPICH2.
+ See
+ http://lists.mcs.anl.gov/pipermail/parallel-netcdf/2010-July/001045.html
+ for an example of the build failure.
+
+ - If you build this release and still get "undefined reference to 'yyin'",
+ then you have some stale object files. "make clean" and re-build.
+
+ - Additional error checking for collective routines
+
+ - We have also made API changes to our non-blocking interface. Our
+ non-blocking semantics have been relaxed somewhat, and should be more
+ usable in more situations.
+
+
+-------------------------------------
+version 1.1.0 (November 2, 2009)
+-------------------------------------
+
+ - A new file format, CDF-5, is introduced. This format allows defining
+ large array variables with more than 2^32 elements.
+
+ - A new optimization in parallel-netcdf with this release. If the hint
+ "striping_unit" is set, then PnetCDF will align the start of non-record
+ variables to a multiple of that value.
+
+ - A new set of APIs for reading/writing multiple variables. The existing
+ asynchronous APIs have also been improved to enable combination of
+ multiple variable access into fewer I/O requests.
+
+ - There is now a simple pnetcdf.F90 module for F90 codes. Please consider
+ this as an "early feedback" version and not a hard guarantee of a fixed
+ F90 API (though we don't expect it to change drastically if at all).
+ This module is generated from the F77 'pnetcdf.inc': thanks to
+ Annette Koontz for the idea.
+
+ - The 'ncmpigen' utility can now create "big variable" (CDF-5) files, in
+ addition to the older "big file" (CDF-2) files.
+
+-------------------------------------
+version 1.0.0 (July 27, 2005)
+-------------------------------------
+
+ - The Parallel-NetCDF developers are quite happy to announce our 1.0.0
+ release. This release reflects the culmination of several years of
+ work and lots of community feedback.
+
+ A brief list of the major changes since 0.9.4:
+
+ - Has both the high level and flexible data mode interfaces
+ - Improved support for many more platforms
+ - Support for all serial NetCDF access patterns (var, vara, vars,
+ varm) and types (text, char, uchar, schar, short, int, float, long,
+ double)
+ - Synced up with netcdf-3.6.0
+ - The usual array of bug fixes and improvements.
+
diff --git a/aclocal.m4 b/aclocal.m4
new file mode 100644
index 0000000..da9d2a1
--- /dev/null
+++ b/aclocal.m4
@@ -0,0 +1,1727 @@
+dnl $Id: aclocal.m4 2280 2015-12-26 17:41:38Z wkliao $
+dnl UD macros for netcdf configure
+
+
+dnl Convert a string to all uppercase.
+dnl
+define([uppercase],
+[translit($1, abcdefghijklmnopqrstuvwxyz, ABCDEFGHIJKLMNOPQRSTUVWXYZ)])
+
+dnl
+dnl Check for an m4(1) preprocessor utility.
+dnl
+AC_DEFUN(UD_PROG_M4,
+[
+ dnl AS_MESSAGE([checking for m4 preprocessor...])
+ case "${M4-unset}" in
+ unset) AC_CHECK_PROGS(M4, m4 gm4, m4) ;;
+ *) AC_CHECK_PROGS(M4, $M4 m4 gm4, m4) ;;
+ esac
+ AC_MSG_CHECKING(m4 flags)
+ case "${M4FLAGS-unset}" in
+ unset) dnl test if M4 runs fine without option -B10000
+ `${M4} /dev/null > conftest.err 2>&1`
+ ac_cv_m4_stdout=`cat conftest.err`
+ if test "x$ac_cv_m4_stdout" != x; then
+ M4FLAGS=-B10000
+ fi
+ ${RM} -f conftest.err
+ ;;
+ esac
+ AC_MSG_RESULT($M4FLAGS)
+ AC_SUBST(M4FLAGS)
+])
+
+dnl
+dnl Check for an ar(1) utility.
+dnl
+AC_DEFUN(UD_PROG_AR,
+[
+ dnl AS_MESSAGE([checking for ar utility...])
+ case "${AR-unset}" in
+ unset) AC_CHECK_PROGS(AR, ar, ar) ;;
+ *) AC_CHECK_PROGS(AR, $AR ar, ar) ;;
+ esac
+ AC_MSG_CHECKING(ar flags)
+ case "${ARFLAGS-unset}" in
+ unset) ARFLAGS=cru ;;
+ esac
+ AC_MSG_RESULT($ARFLAGS)
+ AC_SUBST(ARFLAGS)
+])
+
+dnl
+dnl Check for an nm(1) utility.
+dnl
+AC_DEFUN(UD_PROG_NM,
+[
+ dnl AS_MESSAGE([checking for nm utility...])
+ case "${NM-unset}" in
+ unset) AC_CHECK_PROGS(NM, nm, nm) ;;
+ *) AC_CHECK_PROGS(NM, $NM nm, nm) ;;
+ esac
+ AC_MSG_CHECKING(nm flags)
+ case "${NMFLAGS-unset}" in
+ unset) NMFLAGS= ;;
+ esac
+ AC_MSG_RESULT($NMFLAGS)
+ AC_SUBST(NMFLAGS)
+])
+
+dnl
+dnl Set the top-level source-directory.
+dnl
+AC_DEFUN(UD_SRCDIR,
+[
+ AC_MSG_CHECKING(for top-level source-directory)
+ SRCDIR=`(cd $srcdir && pwd)`
+ AC_MSG_RESULT($SRCDIR)
+ AC_SUBST(SRCDIR)
+])
+
+dnl
+dnl Check for a Standard C compiler. Prefer a native one over the
+dnl GNU one to reduce the chance that the environment variable LIBS
+dnl will have to be set to reference the GNU C runtime library.
+dnl
+AC_DEFUN(UD_PROG_CC,
+[
+ # Because we must have a C compiler, we treat an unset CC
+ # the same as an empty CC.
+ case "${CC}" in
+ '')
+ case `uname` in
+ ULTRIX)
+ # The native ULTRIX C compiler isn't standard.
+ ccs='gcc cc'
+ ;;
+ *)
+ # xlc is before c89 because AIX's sizeof(long long)
+ # differs between the two.
+ #
+ ccs='xlc c89 acc cc gcc'
+ ;;
+ esac
+ for cc in $ccs; do
+ AC_CHECK_PROG(CC, $cc, $cc)
+ case "$CC" in
+ '') ;;
+ *) break
+ ;;
+ esac
+ done
+ case "${CC}" in
+ '')
+ AC_MSG_ERROR("Could not find C compiler")
+ ;;
+ esac
+ ;;
+ esac
+ #
+ # On some systems, a discovered compiler nevertheless won't
+ # work (due to licensing, for example); thus, we check the
+ # compiler with a test program.
+ #
+ AC_MSG_CHECKING([C compiler "$CC"])
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
+ [AC_MSG_RESULT(works)],
+ [AC_MSG_RESULT(failed to compile test program)])
+ AC_SUBST(CC)
+ case "$CC" in
+ *gcc*)
+ GCC=yes # Expected by autoconf(1) macros
+ ;;
+ esac
+ case `uname -sr` in
+ 'HP-UX A.09'*)
+ AC_DEFINE(_HPUX_SOURCE)
+ ;;
+ esac
+])
+
+dnl
+dnl Check for a C++ compiler. Prefer a native one over the
+dnl GNU one to reduce the chance that the environment variable LIBS
+dnl will have to be set to reference the GNU C runtime library.
+dnl
+AC_DEFUN(UD_PROG_CXX,
+[
+ case "${CXX-unset}" in
+ unset)
+ case `uname` in
+ AIX)
+ preferred_cxx='xlC'
+ ;;
+ esac
+ possible_cxxs="${preferred_cxx} CC cxx c++ g++ gcc"
+ ;;
+ '') AC_MSG_WARN("Empty CXX variable")
+ possible_cxxs=
+ ;;
+ *) possible_cxxs=$CXX
+ ;;
+ esac
+ case "${possible_cxxs}" in
+ '') CXX=
+ ;;
+ *) AC_LANG_PUSH([C++])
+ for cxx in $possible_cxxs; do
+ AC_CHECK_PROG(CXX, $cxx, $cxx)
+ case "$CXX" in
+ '') ;;
+ *) # On some systems, a discovered compiler nevertheless
+ # won't work (because it's a script to a non-existent
+ # executable, for example); thus, we check the
+ # compiler with a test program. We also test
+ # for <iostream.h> and the standard C++ library
+ # because we need these to work.
+ #
+ AC_MSG_CHECKING(C++ compiler \"$CXX\")
+ AC_RUN_IFELSE([AC_LANG_SOURCE([[
+ #include <iostream.h>
+ int main() {
+ cout << "";
+ return 0;
+ }
+ ]])],[
+ AC_MSG_RESULT(works)
+ break
+ ],[
+ AC_MSG_WARN($CXX failed on test program)
+ CXX=
+ unset ac_cv_prog_CXX
+ ],[])
+ ;;
+ esac
+ done
+ AC_LANG_POP([C++])
+ case "${CXX}" in
+ '') AC_MSG_WARN("Could not find working C++ compiler")
+ AC_MSG_WARN(Setting CXX to the empty string)
+ ;;
+ esac
+ ;;
+ esac
+ case "${CXX}" in
+ '') AC_MSG_WARN(The C++ interface will not be built)
+ ;;
+ esac
+ AC_SUBST(CXX)
+ case `uname` in
+ 'HP-UX A.09'*)
+ AC_DEFINE(_HPUX_SOURCE)
+ ;;
+ esac
+])
+
+
+dnl
+dnl like AC_TYPE_LONG_DOUBLE, except checks for 'long long'
+dnl
+AC_DEFUN(UD_C_LONG_LONG,
+[AC_MSG_CHECKING(for long long)
+AC_CACHE_VAL(ac_cv_c_long_long,
+[if test "$GCC" = yes; then
+ ac_cv_c_long_long=yes
+else
+AC_RUN_IFELSE([AC_LANG_SOURCE([[int main() {
+long long foo = 0;
+return(sizeof(long long) < sizeof(long)); }]])],
+[ac_cv_c_long_long=yes],
+[ac_cv_c_long_long=no],[:])
+fi])dnl
+AC_MSG_RESULT($ac_cv_c_long_long)
+if test $ac_cv_c_long_long = yes; then
+ AC_DEFINE(HAVE_LONG_LONG)
+fi
+])
+
+dnl
+dnl UD_CHECK_IEEE
+dnl If the 'double' is not an IEEE double
+dnl or the 'float' is not and IEEE single,
+dnl define NO_IEEE_FLOAT
+dnl
+AC_DEFUN(UD_CHECK_IEEE,
+[
+AC_MSG_CHECKING(for IEEE floating point format)
+AC_RUN_IFELSE([AC_LANG_SOURCE([[#ifndef NO_FLOAT_H
+#include <float.h>
+#endif
+
+#define EXIT_NOTIEEE 1
+#define EXIT_MAYBEIEEE 0
+
+int
+main()
+{
+#if defined(FLT_RADIX) && FLT_RADIX != 2
+ return EXIT_NOTIEEE;
+#elif defined(DBL_MAX_EXP) && DBL_MAX_EXP != 1024
+ return EXIT_NOTIEEE;
+#elif defined(DBL_MANT_DIG) && DBL_MANT_DIG != 53
+ return EXIT_NOTIEEE;
+#elif defined(FLT_MAX_EXP) && !(FLT_MAX_EXP == 1024 || FLT_MAX_EXP == 128)
+ return EXIT_NOTIEEE;
+#elif defined(FLT_MANT_DIG) && !(FLT_MANT_DIG == 53 || FLT_MANT_DIG == 24)
+ return EXIT_NOTIEEE;
+#else
+ /* (assuming eight bit char) */
+ if(sizeof(double) != 8)
+ return EXIT_NOTIEEE;
+ if(!(sizeof(float) == 4 || sizeof(float) == 8))
+ return EXIT_NOTIEEE;
+
+ return EXIT_MAYBEIEEE;
+#endif
+}]])],[ac_cv_c_ieeefloat=yes],[ac_cv_c_ieeefloat=no],[:])
+AC_MSG_RESULT($ac_cv_c_ieeefloat)
+if test x$ac_cv_c_ieeefloat = xno; then
+ AC_DEFINE(NO_IEEE_FLOAT)
+fi
+])
+
+dnl Check for utility for generating makefile dependencies.
+dnl Should only be used at the UPC.
+dnl
+AC_DEFUN(UD_PROG_CC_MAKEDEPEND,
+[
+ AC_MSG_CHECKING(how to make dependencies)
+ case `uname -s` in
+ IRIX*|OSF1)
+ CC_MAKEDEPEND='cc -M'
+ ;;
+ SunOS)
+ case `uname -r` in
+ 4*)
+ CC_MAKEDEPEND='cc -M'
+ ;;
+ 5*|*)
+ CC_MAKEDEPEND='cc -xM'
+ ;;
+ esac
+ ;;
+ ULTRIX)
+ case `uname -m` in
+ RISC)
+ CC_MAKEDEPEND='cc -M'
+ ;;
+ VAX) # Can't handle prototypes in netcdf.h
+ ;;
+ esac
+ ;;
+ AIX) # Writes to .u files rather than standard out
+ ;;
+ HP-UX) # Writes escaped newlines to standard error
+ ;;
+ esac
+ case "${CC_MAKEDEPEND}" in
+ '')
+ CC_MAKEDEPEND=false
+ ;;
+ esac
+ AC_MSG_RESULT($CC_MAKEDEPEND)
+ AC_SUBST(CC_MAKEDEPEND)
+])
+
+
+dnl Check for Fortran-90 compiler.
+dnl
+AC_DEFUN(UD_PROG_F90,
+[
+ case "${F90+set}" in
+ set)
+ AC_MSG_CHECKING(user-defined Fortran-90 compiler \"$F90\")
+ AC_LANG_PUSH([Fortran])
+ AC_COMPILE_IFELSE(
+ [AC_LANG_SOURCE([
+ subroutine foo(bar)
+ integer, intent(in) :: bar
+ end subroutine foo
+ ])],
+ [AC_MSG_RESULT(works)],
+ [AC_MSG_RESULT(failed to compile test program)
+ unset F90
+ ]
+ )
+ AC_LANG_POP([Fortran])
+ ;;
+ *)
+ case "${FC+set}" in
+ set)
+ F90=$FC
+ F90FLAGS="${F90FLAGS-${FFLAGS--O}}"
+ F90LIBS="${F90LIBS-${FLIBS}}"
+ cat <<EOF >conftest.f90
+ program foo
+ call bar(1)
+ end
+ subroutine bar(bof)
+ integer, intent(in) :: bof
+ end
+EOF
+ AC_MSG_CHECKING(\"$F90\" as Fortran-90 compiler)
+ doit='$F90 -o conftest ${F90FLAGS} conftest.f90 ${F90LIBS}'
+ if AC_TRY_EVAL(doit); then
+ doit=./conftest
+ if AC_TRY_EVAL(doit); then
+ AC_MSG_RESULT(works)
+ else
+ AC_MSG_RESULT(failed to build executable program)
+ unset F90
+ fi
+ else
+ AC_MSG_RESULT(failed to build test program)
+ unset F90
+ fi
+ ${RM} -f conftest*
+ ;;
+ esac
+ case "${F90-unset}" in
+ unset)
+ cat <<EOF >conftest.f90
+ program foo
+ call bar(1)
+ end
+ subroutine bar(bof)
+ integer, intent(in) :: bof
+ end
+EOF
+ for f90 in xlf90 pgf90 f90; do
+ AC_CHECK_PROG(F90, $f90, $f90)
+ case "${F90}" in
+ '')
+ ;;
+ *)
+ AC_MSG_CHECKING(Fortran-90 compiler \"$F90\")
+ doit='$F90 -o conftest ${F90FLAGS} conftest.f90 ${F90LIBS}'
+ if AC_TRY_EVAL(doit); then
+ doit=./conftest
+ if AC_TRY_EVAL(doit); then
+ AC_MSG_RESULT(works)
+ break
+ else
+ AC_MSG_RESULT(
+ failed to build executable program)
+ unset F90
+ unset ac_cv_prog_F90
+ fi
+ else
+ AC_MSG_RESULT(failed to build test program)
+ unset F90
+ unset ac_cv_prog_F90
+ fi
+ ;;
+ esac
+ done
+ ${RM} -f conftest*
+ case "${F90}" in
+ '') AC_MSG_WARN(
+ "Could not find working Fortran-90 compiler")
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+ esac
+ case "${F90}" in
+ '')
+ AC_MSG_WARN("The Fortran-90 interface will not be built")
+ ;;
+ *f90*)
+ case `uname -s` in
+ IRIX*)
+ NETCDF_MOD=NETCDF.mod
+ ;;
+ *)
+ NETCDF_MOD=netcdf.mod
+ ;;
+ esac
+ AC_SUBST(NETCDF_MOD)
+ ;;
+ esac
+ AC_SUBST(F90)
+ AC_SUBST(F90FLAGS)
+ AC_SUBST(F90LIBS)
+])
+
+dnl Check for Fortran-77 compiler.
+dnl
+AC_DEFUN(UD_PROG_FC,
+[
+ AC_BEFORE([UD_FORTRAN_TYPES])
+ case "${FC+set}" in
+ set)
+ case "$FC" in
+ '')
+ AC_MSG_WARN(Fortran-77 compiler is explicitly set to null)
+ ;;
+ *)
+ AC_MSG_CHECKING(user-defined Fortran-77 compiler \"$FC\")
+ AC_LANG_PUSH([Fortran 77])
+ AC_COMPILE_IFELSE([AC_LANG_CALL([],[FOO])],
+ [AC_MSG_RESULT(works)],
+ [AC_MSG_RESULT(failed to compile test program)
+ FC=
+ ]
+ )
+ AC_LANG_POP([Fortran 77])
+ ;;
+ esac
+ ;;
+ *)
+ dnl FC is not set, let's try F90 as FC if F90 is set
+ case "${F90+set}" in
+ set)
+ FC=$F90
+ FFLAGS="${FFLAGS-${F90FLAGS--O}}"
+ FLIBS="${FLIBS-${F90LIBS-}}"
+ AC_MSG_CHECKING(\"$FC\" as Fortran-77 compiler)
+ AC_LANG_PUSH([Fortran])
+ AC_COMPILE_IFELSE([AC_LANG_CALL([],[FOO])],
+ [AC_MSG_RESULT(works)],
+ [AC_MSG_RESULT(failed to compile test program)
+ unset FC
+ ]
+ )
+ AC_LANG_POP([Fortran])
+ ;;
+ *)
+ ;;
+ esac
+ case "${FC-unset}" in
+ unset)
+ case `uname -sr` in
+ AIX*)
+ # xlf90(1) thinks fortran/ftest.F has bad syntax.
+ forts="xlf f77 gfortran"
+ ;;
+ BSD/OS*|FreeBSD*)
+ forts="f77 fort77 g77 gfortran"
+ ;;
+ HP-UX*)
+ # f77(1) doesn't have the -L option.
+ forts=fort77
+ FLIBS=-lU77
+ ;;
+ IRIX*)
+ # f90(1) can't link with c89(1)-compiled objects
+ forts=f77
+ ;;
+ IRIX64*)
+ forts='f77 g77 gfortran fort77 '
+ ;;
+ Linux*)
+ forts="pgf90 f77 fort77 g77 gfortran"
+ ;;
+ OSF1*)
+ # The use of f90(1) results in the following for
+ # an unknown reason (`make' works in the fortran/
+ # directory):
+ # f90 -c -I../libsrc ftest.F
+ # Last chance handler: pc = 0xa971b8,
+ # sp = 0x3fece0, ra = 0xa971b8
+ # Last chance handler: internal exception: unwinding
+ forts="f77 gfortran"
+ ;;
+ 'SunOS 4'*)
+ forts='f77 g77 gfortran fort77'
+ ;;
+ 'SunOS 5'*)
+ # SunOS's f90(1) has problems passing a C `char'
+ # as a Fortran `integer*1' => use f77(1)
+ forts="pgf90 f77"
+ ;;
+ sn*|UNICOS*|unicos*)
+ forts="fort77 cf77 f77 g77 gfortran f90"
+ ;;
+ *)
+ forts="xlf fort77 ghf77 f77 cf77 g77 gfortran xlf90 f90"
+ ;;
+ esac
+ for fc in $forts; do
+ AC_CHECK_PROG(FC, $fc, $fc)
+ case "${FC}" in
+ '')
+ ;;
+ *)
+ #
+ # On some systems, a discovered compiler
+ # nevertheless won't work (due to licensing,
+ # for example); thus, we check the compiler
+ # with a test program.
+ #
+ AC_LANG_PUSH([Fortran])
+ AC_COMPILE_IFELSE([AC_LANG_CALL([],[FOO])],
+ [AC_MSG_RESULT(works)],
+ [AC_MSG_RESULT(failed to compile test program)
+ unset FC
+ unset ac_cv_prog_FC
+ ]
+ )
+ AC_LANG_POP([Fortran])
+ ;;
+ esac
+ done
+ ${RM} -f conftest.*
+ case "${FC}" in
+ '') AC_MSG_WARN(
+ "Could not find working Fortran-77 compiler")
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+ esac
+ case "${FC}" in
+ '') AC_MSG_WARN("The Fortran-77 interface will not be built")
+ ;;
+ esac
+ AC_SUBST(FC)
+ AC_SUBST(FFLAGS)
+ AC_SUBST(FLIBS)
+ #
+ # Set the make(1) macro for compiling a .F file.
+ #
+ case "${FPP-}" in
+ '')
+ AC_MSG_CHECKING(for Fortran .F compiler)
+ AC_MSG_RESULT($COMPILE_F)
+ case "${COMPILE_F-unset}" in
+ unset)
+ case "${FC}" in
+ '')
+ COMPILE_F=
+ ;;
+ *)
+ cat >conftest.h <<\EOF
+#define J 1
+EOF
+ AC_LANG_PUSH([Fortran])
+ AC_FC_SRCEXT([F])
+ AC_MSG_CHECKING(if Fortran-77 compiler handles *.F files)
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],[
+#include "conftest.h"
+#define N 5
+ real r(J,N)
+ ])],
+ [AC_MSG_RESULT(yes)
+ COMPILE_F='$(COMPILE.f)'],
+ [AC_MSG_RESULT(no)
+ COMPILE_F=
+ ]
+ )
+ AC_FC_SRCEXT([f])
+ AC_LANG_POP([Fortran])
+ ${RM} -f conftest.h
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+ *)
+ unset COMPILE_F
+ ;;
+ esac
+ case "${COMPILE_F-}" in
+ '') UD_PROG_FPP;;
+ esac
+ AC_SUBST(COMPILE_F)
+ FPPFLAGS=${FPPFLAGS-}
+ AC_SUBST(FPPFLAGS)
+])
+
+
+dnl Check for Fortran preprocessor.
+dnl
+AC_DEFUN(UD_PROG_FPP,
+[
+ AC_MSG_CHECKING(for Fortran preprocessor)
+ case "$FPP" in
+ '')
+ AC_REQUIRE([AC_PROG_CPP])
+ FPP="$CPP"
+ ;;
+ esac
+ AC_MSG_RESULT($FPP)
+ AC_SUBST(FPP)
+])
+
+
+dnl Check for a Fortran type equivalent to a netCDF type.
+dnl
+dnl UD_CHECK_FORTRAN_NCTYPE(forttype, possibs, nctype)
+dnl
+AC_DEFUN(UD_CHECK_FORTRAN_NCTYPE,
+[
+ AC_MSG_CHECKING([for Fortran-equivalent to netCDF "$3"])
+dnl for type in $2; do
+dnl cat >conftest.f <<EOF
+dnl $type foo
+dnl end
+dnl EOF
+dnl doit='$FC -c ${FFLAGS} conftest.f'
+dnl if AC_TRY_EVAL(doit); then
+dnl break
+dnl fi
+dnl done
+dnl ${RM} -f conftest.f conftest.o
+
+ AC_LANG_PUSH([Fortran])
+ for type in $2; do
+ AC_COMPILE_IFELSE(
+ [AC_LANG_SOURCE([
+ $type foo
+ end
+ ])],
+ [break]
+ )
+ done
+ AC_LANG_POP([Fortran])
+ AC_DEFINE_UNQUOTED($1, $type)
+ AC_MSG_RESULT($type)
+ $1=$type
+])
+
+
+dnl Check for a Fortran type equivalent to a C type.
+dnl
+dnl UD_CHECK_FORTRAN_CTYPE(v3forttype, v2forttype, ctype, min, max)
+dnl
+AC_DEFUN(UD_CHECK_FORTRAN_CTYPE,
+[
+ AC_MSG_CHECKING([for Fortran-equivalent to C "$3"])
+ AC_LANG_PUSH([Fortran])
+ AC_COMPILE_IFELSE(
+ [AC_LANG_SOURCE([
+ subroutine sub(values, minval, maxval)
+ implicit none
+ $2 values(5), minval, maxval
+ minval = values(2)
+ maxval = values(4)
+ if (values(2) .ge. values(4)) then
+ minval = values(4)
+ maxval = values(2)
+ endif
+ end
+ ])],
+ [found_f2c=yes], [found_f2c=no]
+ )
+ AC_LANG_POP([Fortran])
+ if test "x${found_f2c}" = xyes ; then
+dnl cat >conftest.f <<EOF
+dnl subroutine sub(values, minval, maxval)
+dnl implicit none
+dnl $2 values(5), minval, maxval
+dnl minval = values(2)
+dnl maxval = values(4)
+dnl if (values(2) .ge. values(4)) then
+dnl minval = values(4)
+dnl maxval = values(2)
+dnl endif
+dnl end
+dnl EOF
+dnl doit='$FC -c ${FFLAGS} conftest.f'
+dnl if AC_TRY_EVAL(doit); then
+dnl mv conftest.o conftestf.o
+ cat >conftest.c <<EOF
+#include <limits.h>
+#include <float.h>
+void main()
+{
+$3 values[[]] = {0, $4, 0, $5, 0};
+$3 minval, maxval;
+int $FCALLSCSUB($3*, $3*, $3*);
+$FCALLSCSUB(values, &minval, &maxval);
+return(!(minval == $4 && maxval == $5));
+}
+EOF
+ doit='$CC -o conftest ${CPPFLAGS} ${CFLAGS} ${LDFLAGS} conftest.c conftestf.o ${LIBS}'
+ if AC_TRY_EVAL(doit); then
+ doit=./conftest
+ if AC_TRY_EVAL(doit); then
+ AC_MSG_RESULT($2)
+ $1=$2
+ AC_DEFINE_UNQUOTED($1,$2)
+ else
+ AC_MSG_RESULT(no equivalent type)
+ unset $1
+ fi
+ else
+ AC_MSG_ERROR(Could not compile-and-link conftest.c and conftestf.o)
+ fi
+ else
+ AC_MSG_ERROR(Could not compile conftest.f)
+ fi
+ ${RM} -f conftest*
+ unset found_f2c
+])
+
+
+dnl Check for a Fortran data type.
+dnl
+dnl UD_CHECK_FORTRAN_TYPE(varname, ftypes)
+dnl
+AC_DEFUN(UD_CHECK_FORTRAN_TYPE,
+[
+ AC_LANG_PUSH([Fortran])
+ for ftype in $2; do
+ AC_MSG_CHECKING([for Fortran "$ftype"])
+ AC_COMPILE_IFELSE(
+ [AC_LANG_SOURCE([
+ subroutine sub(value)
+ $ftype value
+ end
+ ])],
+ [AC_MSG_RESULT(yes)
+ $1=$ftype
+ AC_DEFINE_UNQUOTED([$1], [$ftype])
+ break],
+ [AC_MSG_RESULT(no)]
+ )
+ done
+ AC_LANG_POP([Fortran])
+])
+
+
+dnl Check for the name format of a Fortran-callable C routine.
+dnl
+dnl UD_CHECK_FCALLSCSUB
+AC_DEFUN([UD_CHECK_FCALLSCSUB],
+[
+ dnl AC_REQUIRE([UD_PROG_FC])
+ case "$FC" in
+ '') ;;
+ *)
+ AC_REQUIRE([UD_PROG_NM])
+ AC_BEFORE([UD_CHECK_FORTRAN_CTYPE])
+ AC_BEFORE([UD_CHECK_CTYPE_FORTRAN])
+ AC_MSG_CHECKING([for C-equivalent to Fortran routine "SUB"])
+ AC_FC_FUNC([sub], [FCALLSCSUB])
+ AC_MSG_RESULT([$FCALLSCSUB])
+ ;;
+ esac
+])
+
+
+dnl Check for a C type equivalent to a Fortran type.
+dnl
+dnl UD_CHECK_CTYPE_FORTRAN(ftype, ctypes, fmacro_root)
+dnl
+AC_DEFUN(UD_CHECK_CTYPE_FORTRAN,
+[
+ cat >conftestf.f <<EOF
+ $1 values(4)
+ integer status, sub
+ data values /-1, -2, -3, -4/
+ status = sub(values)
+ end
+EOF
+ ac_cv_ctype_fortran=no
+ AC_MSG_CHECKING([if Fortran "$1" is ])
+ for ctype in $2; do
+ dnl AC_MSG_CHECKING(if Fortran \"$1\" is C \"$ctype\")
+ cat >conftest.c <<EOF
+ int $FCALLSCSUB($ctype values[[4]])
+ {
+ return(values[[1]] != -2 || values[[2]] != -3);
+ }
+EOF
+ doit='$CC -c ${CPPFLAGS} ${CFLAGS} conftest.c'
+ if AC_TRY_EVAL(doit); then
+ doit='$FC ${FFLAGS} -c conftestf.f'
+ if AC_TRY_EVAL(doit); then
+ doit='$FC -o conftest ${FFLAGS} ${FLDFLAGS} conftestf.o conftest.o ${LDFLAGS} ${LIBS}'
+ if AC_TRY_EVAL(doit); then
+ doit=./conftest
+ if AC_TRY_EVAL(doit); then
+ dnl AC_MSG_RESULT(yes)
+ AC_MSG_RESULT(["$ctype" in C])
+ cname=`echo $ctype | tr ' abcdefghijklmnopqrstuvwxyz' \
+ _ABCDEFGHIJKLMNOPQRSTUVWXYZ`
+ AC_DEFINE_UNQUOTED(NF_$3[]_IS_C_$cname)
+ ac_cv_ctype_fortran=yes
+ break
+ fi
+ else
+ AC_MSG_ERROR([Could not link conftestf.o and conftest.o])
+ fi
+ else
+ AC_MSG_ERROR([Could not compile conftestf.f])
+ fi
+ else
+ AC_MSG_ERROR([Could not compile conftest.c])
+ fi
+ done
+ ${RM} -f conftest*
+
+ if test "$ac_cv_ctype_fortran" = no ; then
+ AC_MSG_RESULT(no correspond data type in C)
+ fi
+ unset ac_cv_ctype_fortran
+])
+
+
+dnl Get information about Fortran data types.
+dnl
+AC_DEFUN([UD_FORTRAN_TYPES],
+[
+ dnl AC_REQUIRE([UD_PROG_FC])
+ case "$FC" in
+ '')
+ ;;
+ *)
+ AC_REQUIRE([UD_CHECK_FCALLSCSUB])
+ UD_CHECK_FORTRAN_TYPE([NF_INT1_T], [integer*1 byte "integer(kind=1)"])
+ UD_CHECK_FORTRAN_TYPE([NF_INT2_T], [integer*2 "integer(kind=2)"])
+ UD_CHECK_FORTRAN_TYPE([NF_INT8_T], [integer*8 "integer(kind=8)"])
+
+ case "${NF_INT1_T}" in
+ '') ;;
+ *) UD_CHECK_CTYPE_FORTRAN($NF_INT1_T, "signed char" short int long, INT1)
+ ;;
+ esac
+ case "${NF_INT2_T}" in
+ '') ;;
+ *) UD_CHECK_CTYPE_FORTRAN($NF_INT2_T, short int long, INT2)
+ ;;
+ esac
+ case "${NF_INT8_T}" in
+ '') ;;
+ *) UD_CHECK_CTYPE_FORTRAN($NF_INT8_T, int long "long long", INT8)
+ ;;
+ esac
+ UD_CHECK_CTYPE_FORTRAN(integer, int long, INT)
+ UD_CHECK_CTYPE_FORTRAN(real, float double, REAL)
+ UD_CHECK_CTYPE_FORTRAN(doubleprecision, double float, DOUBLEPRECISION)
+
+ UD_CHECK_FORTRAN_NCTYPE(NCBYTE_T, byte integer*1 integer, byte)
+
+ UD_CHECK_FORTRAN_NCTYPE(NCSHORT_T, integer*2 integer, short)
+dnl UD_CHECK_FORTRAN_CTYPE(NF_SHORT_T, $NCSHORT_T, short, SHRT_MIN, SHRT_MAX)
+
+dnl UD_CHECK_FORTRAN_NCTYPE(NCLONG_T, integer*4 integer, long)
+dnl UD_CHECK_FORTRAN_CTYPE(NF_INT_T, integer, int, INT_MIN, INT_MAX)
+
+dnl UD_CHECK_FORTRAN_NCTYPE(NCFLOAT_T, real*4 real, float)
+dnl UD_CHECK_FORTRAN_CTYPE(NF_FLOAT_T, $NCFLOAT_T, float, FLT_MIN, FLT_MAX)
+
+dnl UD_CHECK_FORTRAN_NCTYPE(NCDOUBLE_T, real*8 doubleprecision real, double)
+dnl UD_CHECK_FORTRAN_CTYPE(NF_DOUBLE_T, $NCDOUBLE_T, double, DBL_MIN, DBL_MAX)
+ ;;
+ esac
+])
+
+
+dnl Setup for making a manual-page database.
+dnl
+AC_DEFUN(UD_MAKEWHATIS,
+[
+ #
+ # NB: We always want to define WHATIS to prevent the
+ # $(MANDIR)/$(WHATIS) make(1) target from being just $(MANDIR)/ and
+ # conflicting with the (directory creation) target with the same name.
+ #
+ WHATIS=whatis
+ case `uname -sr` in
+ BSD/OS*|FreeBSD*)
+ # Can't generate a user-database -- only /usr/share/man/whatis.db.
+ MAKEWHATIS_CMD=
+ ;;
+ 'IRIX64 6.5'|'IRIX 6.5')
+ MAKEWHATIS_CMD='/usr/lib/makewhatis -M $(MANDIR) $(MANDIR)/whatis'
+ ;;
+ 'IRIX 6'*)
+ # Can't generate a user-database.
+ MAKEWHATIS_CMD=
+ ;;
+ HP-UX*)
+ # Can't generate a user-database -- only /usr/lib/whatis.
+ MAKEWHATIS_CMD=
+ ;;
+ 'Linux '*)
+ # /usr/sbin/makewhatis doesn't work
+ MAKEWHATIS_CMD=
+ ;;
+ ULTRIX*)
+ # Can't generate a user-database -- only /usr/lib/whatis.
+ MAKEWHATIS_CMD=
+ ;;
+ *)
+ if test -r /usr/man/windex; then
+ WHATIS=windex
+ fi
+ AC_CHECK_PROGS(prog, catman makewhatis /usr/lib/makewhatis)
+ case "$prog" in
+ *catman*)
+ MAKEWHATIS_CMD=$prog' -w -M $(MANDIR)'
+ ;;
+ *makewhatis*)
+ MAKEWHATIS_CMD=$prog' $(MANDIR)'
+ ;;
+ esac
+ ;;
+ esac
+ AC_SUBST(WHATIS)
+ AC_SUBST(MAKEWHATIS_CMD)
+ AC_MSG_CHECKING(for manual-page index command)
+ AC_MSG_RESULT($MAKEWHATIS_CMD)
+])
+
+
+dnl Check for the math library.
+dnl
+AC_DEFUN(UD_CHECK_LIB_MATH,
+[
+ dnl AS_MESSAGE([checking for math library...])
+ case "${MATHLIB}" in
+ '')
+ AC_CHECK_LIB(c, floor, MATHLIB=,
+ AC_CHECK_LIB(m, floor, MATHLIB=-lm, MATHLIB=))
+ ;;
+ *)
+ AC_MSG_RESULT($MATHLIB (user defined))
+ ;;
+ esac
+ AC_SUBST(MATHLIB)
+])
+
+dnl steal from autoconf 2.69
+AC_DEFUN([UD_FC_PP_SRCEXT],
+[AC_LANG_PUSH(Fortran)dnl
+AC_CACHE_CHECK([for Fortran flag to compile preprocessed .$1 files],
+ ac_cv_fc_pp_srcext_$1,
+[ac_ext=$1
+FCFLAGS_SRCEXT_save=$FCFLAGS_SRCEXT
+FCFLAGS_SRCEXT=
+ac_fcflags_pp_srcext_save=$ac_fcflags_srcext
+ac_fcflags_srcext=
+ac_cv_fc_pp_srcext_$1=unknown
+case $ac_ext in #(
+ [[fF]]77) ac_try=f77-cpp-input;; #(
+ [[fF]]) ac_try=f77-cpp-input;; #(
+ *) ac_try=f95-cpp-input;;
+esac
+for ac_flag in none -ftpp -fpp -Tf "-fpp -Tf" -xpp=fpp -Mpreprocess "-e Z" \
+ -cpp -xpp=cpp -qsuffix=cpp=$1 "-x $ac_try" +cpp -Cpp; do
+ test "x$ac_flag" != xnone && FCFLAGS_SRCEXT="$ac_flag" && ac_fcflags_srcext="$ac_flag"
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [[
+#if 0
+#include <ac_nonexistent.h>
+ choke me
+#endif]])],
+ [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [[
+#if 1
+#include <ac_nonexistent.h>
+ choke me
+#endif]])],
+ [],
+ [ac_cv_fc_pp_srcext_$1=$ac_flag; break])])
+done
+${RM} -f conftest.$ac_objext conftest.$1
+FCFLAGS_SRCEXT=$FCFLAGS_SRCEXT_save
+ac_fcflags_srcext=$ac_fcflags_pp_srcext_save
+])
+if test "x$ac_cv_fc_pp_srcext_$1" = xunknown; then
+ m4_default([$3],
+ [AC_MSG_ERROR([Fortran could not compile preprocessed .$1 files])])
+else
+ ac_fc_srcext=$1
+ if test "x$ac_cv_fc_pp_srcext_$1" = xnone; then
+ FCFLAGS_SRCEXT=""
+ ac_cv_fc_pp_srcext_$1=""
+ dnl FCPPFLAGS_[]$1[]=""
+ else
+ FCFLAGS_SRCEXT=$ac_cv_fc_pp_srcext_$1
+ dnl FCPPFLAGS_[]$1[]=$ac_cv_fc_pp_srcext_$1
+ fi
+ dnl AC_SUBST(FCPPFLAGS_[]$1)
+ $2
+fi
+AC_LANG_POP(Fortran)dnl
+])# UD_FC_PP_SRCEXT
+
+dnl steal from autoconf 2.69
+AC_DEFUN([UD_FC_PP_DEFINE],
+[AC_LANG_PUSH([Fortran])dnl
+ac_fc_pp_define_srcext_save=$ac_fc_srcext
+ac_ext_saved=$ac_ext
+UD_FC_PP_SRCEXT([F])
+ac_ext=F
+AC_CACHE_CHECK([how to define symbols for preprocessed Fortran],
+ [ac_cv_fc_pp_define],
+[ac_fc_pp_define_srcext_save=$ac_fc_srcext
+ac_cv_fc_pp_define=unknown
+ac_fc_pp_define_FCFLAGS_save=$FCFLAGS
+for ac_flag in -D -WF,-D -Wp,-D -Wc,-D
+do
+ FCFLAGS="$ac_fc_pp_define_FCFLAGS_save ${ac_flag}FOOBAR ${ac_flag}ZORK=42"
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [[
+#ifndef FOOBAR
+ choke me
+#endif
+#if ZORK != 42
+ choke me
+#endif]])],
+ [ac_cv_fc_pp_define=$ac_flag])
+ test x"$ac_cv_fc_pp_define" != xunknown && break
+done
+FCFLAGS=$ac_fc_pp_define_FCFLAGS_save
+])
+ac_fc_srcext=$ac_fc_pp_define_srcext_save
+if test "x$ac_cv_fc_pp_define" = xunknown; then
+ FC_DEFINE=
+ m4_default([$2],
+ [AC_MSG_ERROR([Fortran does not allow to define preprocessor symbols], 77)])
+else
+ FC_DEFINE=$ac_cv_fc_pp_define
+ $1
+fi
+ac_ext=$ac_ext_saved
+AC_SUBST([FC_DEFINE])dnl
+AC_LANG_POP([Fortran])dnl
+])
+
+# AC_PROG_FC_MOD
+# ---------------
+dnl Note that Mac OSX file system is case-insensitive, so this function does
+dnl not work precisely on Mac. Hence, we check whether the file system can
+dnl find the file with name in lowercase. If not, we say the mod file is in
+dnl uppercase.
+AC_DEFUN([UD_PROG_FC_UPPERCASE_MOD],
+[
+AC_REQUIRE([UD_FC_MODULE_EXTENSION])
+AC_LANG_PUSH(Fortran)
+AC_MSG_CHECKING([if Fortran 90 compiler capitalizes .mod filenames])
+AC_COMPILE_IFELSE(
+ [AC_LANG_SOURCE([
+ module conftest
+ end module conftest
+ ])]
+)
+dnl ac_try='$F90 ${F90FLAGS} conftest.f90 ${F90LIBS}>&AS_MESSAGE_LOG_FD'
+dnl AC_TRY_EVAL(ac_try)
+if test -f conftest.${FC_MODEXT} ; then
+ ac_cv_prog_f90_uppercase_mod=no
+else
+ ac_cv_prog_f90_uppercase_mod=yes
+ ${RM} -f CONFTEST.${FC_MODEXT}
+fi
+AC_MSG_RESULT($ac_cv_prog_f90_uppercase_mod)
+${RM} -f conftest*
+AC_LANG_POP(Fortran)
+])
+
+dnl steal from autoconf 2.69
+# UD_FC_MODULE_EXTENSION
+# ----------------------
+# Find the Fortran 90 module file extension. The module extension is stored
+# in the variable FC_MODEXT and empty if it cannot be determined. The result
+# or "unknown" is cached in the cache variable ac_cv_fc_module_ext.
+AC_DEFUN([UD_FC_MODULE_EXTENSION],
+[AC_CACHE_CHECK([Fortran 90 module extension], [ac_cv_fc_module_ext],
+[AC_LANG_PUSH(Fortran)
+mkdir conftest.dir
+cd conftest.dir
+ac_cv_fc_module_ext=unknown
+AC_COMPILE_IFELSE([[
+ module conftest_module
+ contains
+ subroutine conftest_routine
+ write(*,'(a)') 'gotcha!'
+ end subroutine
+ end module]],
+ [ac_cv_fc_module_ext=`ls | sed -n 's,conftest_module\.,,p'`
+ if test x$ac_cv_fc_module_ext = x; then
+dnl Some F90 compilers use upper case characters for the module file name.
+ ac_cv_fc_module_ext=`ls | sed -n 's,CONFTEST_MODULE\.,,p'`
+ fi])
+cd ..
+${RM} -rf conftest.dir
+AC_LANG_POP(Fortran)
+])
+FC_MODEXT=$ac_cv_fc_module_ext
+if test "$FC_MODEXT" = unknown; then
+ FC_MODEXT=
+fi
+AC_SUBST([FC_MODEXT])dnl
+])
+
+dnl steal from autoconf 2.69
+# UD_FC_MODULE_FLAG([ACTION-IF-SUCCESS], [ACTION-IF-FAILURE = FAILURE])
+# ---------------------------------------------------------------------
+# Find a flag to include Fortran 90 modules from another directory.
+# If successful, run ACTION-IF-SUCCESS (defaults to nothing), otherwise
+# run ACTION-IF-FAILURE (defaults to failing with an error message).
+# The module flag is cached in the ac_cv_fc_module_flag variable.
+# It may contain significant trailing whitespace.
+#
+# Known flags:
+# gfortran: -Idir, -I dir (-M dir, -Mdir (deprecated), -Jdir for writing)
+# g95: -I dir (-fmod=dir for writing)
+# SUN: -Mdir, -M dir (-moddir=dir for writing;
+# -Idir for includes is also searched)
+# HP: -Idir, -I dir (+moddir=dir for writing)
+# IBM: -Idir (-qmoddir=dir for writing)
+# Intel: -Idir -I dir (-mod dir for writing)
+# Absoft: -pdir
+# Lahey: -mod dir
+# Cray: -module dir, -p dir (-J dir for writing)
+# -e m is needed to enable writing .mod files at all
+# Compaq: -Idir
+# NAGWare: -I dir (-mdir dir for writing)
+# PathScale: -I dir (but -module dir is looked at first)
+# Portland: -module dir (first -module also names dir for writing)
+# Fujitsu: -Am -Idir (-Mdir for writing is searched first, then '.', then -I)
+# (-Am indicates how module information is saved)
+AC_DEFUN([UD_FC_MODULE_FLAG],[
+AC_CACHE_CHECK([Fortran 90 module inclusion flag], [ac_cv_fc_module_flag],
+[AC_LANG_PUSH([Fortran])
+ac_cv_fc_module_flag=unknown
+mkdir conftest.dir
+cd conftest.dir
+AC_COMPILE_IFELSE([[
+ module conftest_module
+ contains
+ subroutine conftest_routine
+ write(*,'(a)') 'gotcha!'
+ end subroutine
+ end module]],
+ [cd ..
+ ac_fc_module_flag_FCFLAGS_save=$FCFLAGS
+ # Flag ordering is significant for gfortran and Sun.
+ for ac_flag in -I '-I ' -M '-M ' -p '-mod ' '-mdir ' '-module ' '-Am -I'; do
+ # Add the flag twice to prevent matching an output flag.
+ FCFLAGS="$ac_fc_module_flag_FCFLAGS_save ${ac_flag}conftest.dir ${ac_flag}conftest.dir"
+ AC_COMPILE_IFELSE([[
+ program main
+ use conftest_module
+ call conftest_routine
+ end]],
+ [ac_cv_fc_module_flag="$ac_flag"])
+ if test "$ac_cv_fc_module_flag" != unknown; then
+ break
+ fi
+ done
+ FCFLAGS=$ac_fc_module_flag_FCFLAGS_save
+])
+${RM} -rf conftest.dir
+AC_LANG_POP([Fortran])
+])
+if test "$ac_cv_fc_module_flag" != unknown; then
+ FC_MODINC=$ac_cv_fc_module_flag
+ $1
+else
+ FC_MODINC=
+ m4_default([$2],
+ [AC_MSG_ERROR([unable to find compiler flag for module search path])])
+fi
+AC_SUBST([FC_MODINC])
+# Ensure trailing whitespace is preserved in a Makefile.
+AC_SUBST([ac_empty], [""])
+AC_CONFIG_COMMANDS_PRE([case $FC_MODINC in #(
+ *\ ) FC_MODINC=$FC_MODINC'${ac_empty}' ;;
+esac])dnl
+])
+
+
+dnl steal from autoconf 2.69
+# UD_FC_MODULE_OUTPUT_FLAG([ACTION-IF-SUCCESS], [ACTION-IF-FAILURE = FAILURE])
+# ----------------------------------------------------------------------------
+# Find a flag to write Fortran 90 module information to another directory.
+# If successful, run ACTION-IF-SUCCESS (defaults to nothing), otherwise
+# run ACTION-IF-FAILURE (defaults to failing with an error message).
+# The module flag is cached in the ac_cv_fc_module_output_flag variable.
+# It may contain significant trailing whitespace.
+#
+# For known flags, see the documentation of AC_FC_MODULE_FLAG above.
+AC_DEFUN([UD_FC_MODULE_OUTPUT_FLAG],[
+AC_CACHE_CHECK([Fortran 90 module output flag], [ac_cv_fc_module_output_flag],
+[AC_LANG_PUSH([Fortran])
+mkdir conftest.dir conftest.dir/sub
+cd conftest.dir
+ac_cv_fc_module_output_flag=unknown
+ac_fc_module_output_flag_FCFLAGS_save=$FCFLAGS
+# Flag ordering is significant: put flags late which some compilers use
+# for the search path.
+for ac_flag in -J '-J ' -fmod= -moddir= +moddir= -qmoddir= '-mod ' \
+ '-mdir ' '-module ' -M '-Am -M' '-e m -J '; do
+ FCFLAGS="$ac_fc_module_output_flag_FCFLAGS_save ${ac_flag}sub"
+ AC_COMPILE_IFELSE([[
+ module conftest_module
+ contains
+ subroutine conftest_routine
+ write(*,'(a)') 'gotcha!'
+ end subroutine
+ end module]],
+ [cd sub
+ AC_COMPILE_IFELSE([[
+ program main
+ use conftest_module
+ call conftest_routine
+ end]],
+ [ac_cv_fc_module_output_flag="$ac_flag"])
+ cd ..
+ if test "$ac_cv_fc_module_output_flag" != unknown; then
+ break
+ fi])
+done
+FCFLAGS=$ac_fc_module_output_flag_FCFLAGS_save
+cd ..
+${RM} -rf conftest.dir
+AC_LANG_POP([Fortran])
+])
+if test "$ac_cv_fc_module_output_flag" != unknown; then
+ FC_MODOUT=$ac_cv_fc_module_output_flag
+ $1
+else
+ FC_MODOUT=
+ m4_default([$2],
+ [AC_MSG_ERROR([unable to find compiler flag to write module information to])])
+fi
+AC_SUBST([FC_MODOUT])
+# Ensure trailing whitespace is preserved in a Makefile.
+AC_SUBST([ac_empty], [""])
+AC_CONFIG_COMMANDS_PRE([case $FC_MODOUT in #(
+ *\ ) FC_MODOUT=$FC_MODOUT'${ac_empty}' ;;
+esac])dnl
+])
+
+dnl steal from autoconf 2.69
+# AC_FC_FREEFORM([ACTION-IF-SUCCESS], [ACTION-IF-FAILURE = FAILURE])
+# ------------------------------------------------------------------
+# Look for a compiler flag to make the Fortran (FC) compiler accept
+# free-format source code, and adds it to FCFLAGS. Call
+# ACTION-IF-SUCCESS (defaults to nothing) if successful (i.e. can
+# compile code using new extension) and ACTION-IF-FAILURE (defaults to
+# failing with an error message) if not. (Defined via DEFUN_ONCE to
+# prevent flag from being added to FCFLAGS multiple times.)
+#
+# The known flags are:
+# -ffree-form: GNU g77, gfortran, g95
+# -FR, -free: Intel compiler (icc, ecc, ifort)
+# -free: Compaq compiler (fort), Sun compiler (f95)
+# -qfree=f90, -qfree: IBM compiler (xlf)
+# -Mfree, -Mfreeform: Portland Group compiler
+# -freeform: SGI compiler
+# -8, -f free: Absoft Fortran
+# +source=free: HP Fortran
+# (-)-nfix, -Free: Lahey/Fujitsu Fortran
+# -free: NAGWare
+# -f, -Wf,-f: f2c (but only a weak form of "free-form" and long lines)
+# We try to test the "more popular" flags first, by some prejudiced
+# notion of popularity.
+AC_DEFUN_ONCE([UD_FC_FREEFORM],
+[AC_LANG_PUSH([Fortran])dnl
+AC_CACHE_CHECK([for Fortran flag needed to accept free-form source],
+ [ac_cv_fc_freeform],
+[ac_cv_fc_freeform=unknown
+ac_fc_freeform_FCFLAGS_save=$FCFLAGS
+for ac_flag in none -ffree-form -FR -free -qfree=f90 -qfree -Mfree -Mfreeform \
+ -freeform "-f free" -8 +source=free -nfix --nfix -Free
+do
+ test "x$ac_flag" != xnone && FCFLAGS="$ac_fc_freeform_FCFLAGS_save $ac_flag"
+dnl Use @&t@ below to ensure that editors don't turn 8+ spaces into tab.
+ AC_COMPILE_IFELSE([[
+ program freeform
+ ! FIXME: how to best confuse non-freeform compilers?
+ print *, 'Hello ', &
+ @&t@ 'world.'
+ end]],
+ [ac_cv_fc_freeform=$ac_flag; break])
+done
+${RM} -f conftest.err conftest.$ac_objext conftest.$ac_ext
+FCFLAGS=$ac_fc_freeform_FCFLAGS_save
+])
+if test "x$ac_cv_fc_freeform" = xunknown; then
+ m4_default([$2],
+ [AC_MSG_WARN([Fortran $FC does not accept free-form source], 77)])
+else
+ dnl Do not append to FCFLAGS
+ dnl if test "x$ac_cv_fc_freeform" != xnone; then
+ dnl FCFLAGS="$FCFLAGS $ac_cv_fc_freeform"
+ dnl fi
+ if test "x$ac_cv_fc_freeform" = xnone; then
+ ac_cv_fc_freeform=
+ fi
+ $1
+fi
+AC_LANG_POP([Fortran])dnl
+])# AC_FC_FREEFORM
+
+dnl steal from autoconf 2.69
+# AC_FC_FIXEDFORM([ACTION-IF-SUCCESS], [ACTION-IF-FAILURE = FAILURE])
+# ------------------------------------------------------------------
+# Look for a compiler flag to make the Fortran (FC) compiler accept
+# fixed-format source code, and adds it to FCFLAGS. Call
+# ACTION-IF-SUCCESS (defaults to nothing) if successful (i.e. can
+# compile code using new extension) and ACTION-IF-FAILURE (defaults to
+# failing with an error message) if not. (Defined via DEFUN_ONCE to
+# prevent flag from being added to FCFLAGS multiple times.)
+#
+# The known flags are:
+# -ffixed-form: GNU g77, gfortran, g95
+# -fixed: Intel compiler (ifort), Sun compiler (f95)
+# -qfixed: IBM compiler (xlf*)
+# -Mfixed: Portland Group compiler
+# -fixedform: SGI compiler
+# -f fixed: Absoft Fortran
+# +source=fixed: HP Fortran
+# (-)-fix, -Fixed: Lahey/Fujitsu Fortran
+# -fixed: NAGWare
+# Since compilers may accept fixed form based on file name extension,
+# but users may want to use it with others as well, call AC_FC_SRCEXT
+# with the respective source extension before calling this macro.
+AC_DEFUN_ONCE([UD_FC_FIXEDFORM],
+[AC_LANG_PUSH([Fortran])dnl
+AC_CACHE_CHECK([for Fortran flag needed to accept fixed-form source],
+ [ac_cv_fc_fixedform],
+[ac_cv_fc_fixedform=unknown
+ac_fc_fixedform_FCFLAGS_save=$FCFLAGS
+for ac_flag in none -ffixed-form -fixed -qfixed -Mfixed -fixedform "-f fixed" \
+ +source=fixed -fix --fix -Fixed
+do
+ test "x$ac_flag" != xnone && FCFLAGS="$ac_fc_fixedform_FCFLAGS_save $ac_flag"
+ AC_COMPILE_IFELSE([[
+C This comment should confuse free-form compilers.
+ program main
+ end]],
+ [ac_cv_fc_fixedform=$ac_flag; break])
+done
+${RM} -f conftest.err conftest.$ac_objext conftest.$ac_ext
+FCFLAGS=$ac_fc_fixedform_FCFLAGS_save
+])
+if test "x$ac_cv_fc_fixedform" = xunknown; then
+ m4_default([$2],
+ [AC_MSG_WARN([Fortran does not accept fixed-form source], 77)])
+ ac_cv_fc_fixedform=
+else
+ dnl Do not append to FCFLAGS
+ dnl if test "x$ac_cv_fc_fixedform" != xnone; then
+ dnl FCFLAGS="$FCFLAGS $ac_cv_fc_fixedform"
+ dnl fi
+ if test "x$ac_cv_fc_fixedform" = xnone; then
+ ac_cv_fc_fixedform=
+ fi
+ $1
+fi
+AC_LANG_POP([Fortran])dnl
+])# AC_FC_FIXEDFORM
+
+# AX_C_FLOAT_WORDS_BIGENDIAN# added by:
+# Warren Turkal <wt at penguintechs.org>
+#
+# Copyright © 2006 Daniel Amelang <dan at amelang.net>
+#
+# Copying and distribution of this file, with or without modification, are
+# permitted in any medium without royalty provided the copyright notice and
+# this notice are preserved.
+#
+# This macro will detect if double variables are words packed in big endian
+# order while the bits in the words are arranged in little endian order. This
+# macro was added to support the ARM architecture. The FLOAT_WORDS_BIGENDIAN
+# macro will be set to 1 if the word order is big endian. If the word order is
+# not big endian, FLOAT_WORDS_BIGENDIAN will be not be set.
+AC_DEFUN([AX_C_FLOAT_WORDS_BIGENDIAN],
+ [AC_CACHE_CHECK(whether float word ordering is bigendian,
+ ax_cv_c_float_words_bigendian, [
+
+ax_cv_c_float_words_bigendian=unknown
+AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
+
+double d = 9090423496703681033747047890550501147621169273561563201479712084405348
+886581669527372346909785805625751702019124748742951693213050356065000232756451757
+0778480236724525140520121371739201496540132640109977779420565776568942592.0;
+
+]])], [
+
+if grep noonsees conftest.$ac_objext >/dev/null ; then
+ ax_cv_c_float_words_bigendian=yes
+fi
+if grep seesnoon conftest.$ac_objext >/dev/null ; then
+ if test "$ax_cv_c_float_words_bigendian" = unknown; then
+ ax_cv_c_float_words_bigendian=no
+ else
+ ax_cv_c_float_words_bigendian=unknown
+ fi
+fi
+
+])])
+
+case $ax_cv_c_float_words_bigendian in
+ yes)
+ m4_default([$1],
+ [AC_DEFINE([FLOAT_WORDS_BIGENDIAN], 1,
+ [Define to 1 if your system stores words within floats
+ with the most significant word first])]) ;;
+ no)
+ $2 ;;
+ *)
+ m4_default([$3],
+ [AC_MSG_ERROR([
+
+Unknown float word ordering. You need to manually preset
+ax_cv_c_float_words_bigendian=no (or yes) according to your system.
+
+ ])]) ;;
+esac
+
+])# AX_C_FLOAT_WORDS_BIGENDIAN
+
+dnl Find the full path of a header file
+dnl
+dnl UD_CHECK_HEADER_PATH(file, [action-if-found], [action-if-not-found])
+dnl Example:
+dnl UD_CHECK_HEADER_PATH([math.h])
+dnl AC_MSG_NOTICE([ac_cv_header_path_math_h=$ac_cv_header_path_math_h])
+dnl
+dnl
+AC_DEFUN([UD_CHECK_HEADER_PATH],
+[
+ AS_VAR_PUSHDEF([ac_Path], [ac_cv_header_path_$1])dnl
+ AC_CACHE_CHECK(
+ [for full path of header file \"$1\"], [ac_Path],
+ [AC_PREPROC_IFELSE(
+ [AC_LANG_PROGRAM([[#include <$1>]])],
+ [AS_VAR_SET([ac_Path], [`sed -n '/\.h"/s/.*"\(.*\)".*/\1/p' conftest.i | grep -m 1 $1`])],
+ [AC_MSG_RESULT([not found])]
+ )])
+ AS_VAR_SET_IF([ac_Path], [$2], [$3])
+ dnl eval AS_TR_SH([ac_cv_header_path_$1])=$ac_Path
+ AS_VAR_POPDEF([ac_Path])dnl
+])
+
+dnl Check if Fortran 77 compiler allows _8 modifier (a Fortran 90 feature)
+dnl for integer*8 parameter
+dnl NAG nagfor requires a modifier but does not like _8
+dnl xlf is OK with _8 but when none is used it strangely passes the
+dnl compilation with a warning message
+dnl
+AC_DEFUN([UD_FC_CONSTANT_MODIFIER],[
+ AC_CACHE_CHECK([Fortran compiler treating constant modifier], [ac_cv_fc_constant_modifier],
+ [AC_LANG_PUSH([Fortran 77])
+ AC_COMPILE_IFELSE([[
+ program main
+ integer*8 nf_fill_uint
+ integer*8 nf_fill_int64
+ parameter (nf_fill_uint = 4294967295_8)
+ parameter (nf_fill_int64 = -9223372036854775806_8)
+ end]],
+ [ac_cv_fc_constant_modifier=8],
+ [AC_COMPILE_IFELSE([[
+ program main
+ integer*8 nf_fill_uint
+ integer*8 nf_fill_int64
+ parameter (nf_fill_uint = 4294967295)
+ parameter (nf_fill_int64 = -9223372036854775806)
+ end]],
+ [ac_cv_fc_constant_modifier=none],
+ [AC_COMPILE_IFELSE([[
+ program main
+ integer, parameter :: EightByteInt = selected_int_kind(18)
+ integer*8 nf_fill_uint
+ integer*8 nf_fill_int64
+ parameter (nf_fill_uint = 4294967295_EightByteInt)
+ parameter (nf_fill_int64 = -9223372036854775806_EightByteInt)
+ end]],
+ [ac_cv_fc_constant_modifier=EightByteInt],
+ [AC_MSG_ERROR([no appropriate modifier found])])
+ ])
+ ])
+ ])
+ AC_LANG_POP([Fortran 77])
+])
+
+dnl Check if Fortran 77 compiler is pgf77
+dnl According to pgf77 manual the command-line option to should version is -V
+dnl
+AC_DEFUN([UD_CHECK_PGF77],[
+ AC_CACHE_CHECK([if Fortran 77 compiler is pgf77], [ac_cv_fc_compiler_pgf77],
+ [ac_cv_fc_compiler_pgf77=no
+ eval $MPIF77 -V </dev/null >& conftest.ver
+ _F77_VENDOR=`head -c 5 conftest.ver`
+ if test "x${_F77_VENDOR}" = xpgf77 ; then
+ ac_cv_fc_compiler_pgf77=yes
+ fi
+ ${RM} -f conftest.ver
+ unset _F77_VENDOR
+ ])
+])
+
+dnl Check if Fortran compiler is NAG
+dnl According to nagfor manual the command-line option to should version is -V
+dnl
+AC_DEFUN([UD_CHECK_FC_NAG],[
+ AC_CACHE_CHECK([if Fortran compiler is NAG], [ac_cv_fc_compiler_nag],
+ [ac_cv_fc_compiler_nag=no
+ eval $MPIF90 -V </dev/null >& conftest.ver
+ _FC_VENDOR=`head -c 3 conftest.ver`
+ if test "x${_FC_VENDOR}" = xNAG ; then
+ ac_cv_fc_compiler_nag=yes
+ fi
+ ${RM} -f conftest.ver
+ unset _FC_VENDOR
+ ])
+])
+
+AC_DEFUN([UD_CXX_MACRO_FUNC],[
+ AC_CACHE_CHECK([if C++ macro __func__ or __FUNCTION__ is defined], [ac_cv_cxx_macro_func],
+ [ac_cv_cxx_macro_func=no
+ ac_cv_cxx_macro_function=no
+ AC_LANG_PUSH([C++])
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <iostream>]],
+ [[std::cout << __func__;]])],
+ [ac_cv_cxx_macro_func=yes],[])
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <iostream>]],
+ [[std::cout << __FUNCTION__;]])],
+ [ac_cv_cxx_macro_function=yes],[])
+ AC_LANG_POP([C++])
+ ])
+])
+
+dnl
+dnl Borrowed macros from MPICH: aclocal_f77.m4
+dnl
+
+dnl
+dnl Check to see if a C program can be linked when using the libraries
+dnl needed by C programs
+dnl
+AC_DEFUN([PAC_PROG_FC_CHECK_FCLIBS],[
+AC_REQUIRE([AC_FC_LIBRARY_LDFLAGS])
+AC_MSG_CHECKING([whether $CC links with FCLIBS found by autoconf])
+AC_LANG_PUSH([C])
+# Create a simple C program for the tests.
+AC_LANG_CONFTEST([
+ AC_LANG_PROGRAM([],[int a;])
+])
+# Try to link a C program with all of these libraries
+saved_LIBS="$LIBS"
+LIBS="$FCLIBS $saved_LIBS"
+AC_LINK_IFELSE([],[
+ AC_MSG_RESULT([yes])
+],[
+ AC_MSG_RESULT([no])
+ AC_MSG_CHECKING([for which libraries can be used])
+ pac_ldirs=""
+ pac_libs=""
+ pac_other=""
+ for name in $FCLIBS ; do
+ case $name in
+ -l*) pac_libs="$pac_libs $name" ;;
+ -L*) pac_ldirs="$pac_ldirs $name" ;;
+ *) pac_other="$pac_other $name" ;;
+ esac
+ done
+ keep_libs=""
+ for name in $pac_libs ; do
+ LIBS="$saved_LIBS $pac_ldirs $pac_other $name"
+ AC_LINK_IFELSE([],[
+ keep_libs="$keep_libs $name"
+ ])
+ done
+ AC_MSG_RESULT($keep_libs)
+ FCLIBS="$pac_ldirs $pac_other $keep_libs"
+])
+LIBS="$saved_LIBS"
+rm -f conftest.$ac_ext
+AC_LANG_PUSH([C])
+])
+
+
+AC_DEFUN([UD_CHECK_MPI_COMPILER], [
+ if test "x$MPI_INSTALL" != x ; then
+ UD_MSG_DEBUG(--with-mpi=$MPI_INSTALL is used)
+ if test "x$$1" = x ; then
+ if test "x$$1" = x && (test -d "${MPI_INSTALL}/bin") ; then
+ UD_MSG_DEBUG(search possible $1 under $MPI_INSTALL/bin)
+ AC_PATH_PROGS([$1], [$2], [], [$MPI_INSTALL/bin])
+ fi
+ if test "x$$1" = x ; then
+ UD_MSG_DEBUG(search possible $1 under $MPI_INSTALL)
+ AC_PATH_PROGS([$1], [$2], [], [$MPI_INSTALL])
+ fi
+ else
+ UD_MSG_DEBUG(check if file $$1 exists)
+ if ! test -f "$$1" ; then
+ dnl file does not exist, check under MPI_INSTALL
+ UD_MSG_DEBUG(File $1= $$1 cannot be found ... check under $MPI_INSTALL)
+ if test -f "$MPI_INSTALL/$$1" ; then
+ UD_MSG_DEBUG(File $1= $$1 is found under $MPI_INSTALL)
+ $1="$MPI_INSTALL/$$1"
+ elif test -f "$MPI_INSTALL/bin/$$1" ; then
+ UD_MSG_DEBUG(File $1= $$1 is found under $MPI_INSTALL/bin)
+ $1="$MPI_INSTALL/bin/$$1"
+ else
+ UD_MSG_DEBUG(File $1= $$1 cannot be found under $MPI_INSTALL)
+ $1=
+ fi
+ fi
+ fi
+ else
+ UD_MSG_DEBUG(--with-mpi=$MPI_INSTALL is NOT used)
+ UD_MSG_DEBUG([check if $1 is defined. If yes, check if file exists])
+ if test "x$$1" != x && (! test -f "$$1") ; then
+ UD_MSG_DEBUG(check if file $$1 exists under user's PATH)
+ AC_PATH_PROGS([$1], [$$1])
+ fi
+ fi
+ dnl if $$1 is not empty, then compiler file does exist
+ dnl if $$1 is empty, search under user's PATH
+ if test "x$$1" = x ; then
+ UD_MSG_DEBUG(find possible $1 under user's PATH)
+ AC_PATH_PROGS([$1], [$2])
+ fi
+])
+
+dnl Check for presence of an MPI constant.
+dnl These could be enums, so we have to do compile checks.
+AC_DEFUN([UD_HAS_MPI_CONST], [
+ AC_MSG_CHECKING(if MPI constant $1 is defined )
+ AC_COMPILE_IFELSE(
+ [AC_LANG_SOURCE([
+ #include <mpi.h>
+ int dummy = $1;
+ ])],
+ [AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_$1, 1, available)
+ ],
+ [AC_MSG_RESULT(no)]
+ )]
+)
+
+dnl Check for presence of an MPI datatype.
+dnl These could be enums, so we have to do compile checks.
+AC_DEFUN([UD_HAS_MPI_DATATYPE], [
+ AC_MSG_CHECKING(if MPI datatype $1 is defined )
+ AC_COMPILE_IFELSE(
+ [AC_LANG_SOURCE([
+ #include <mpi.h>
+ MPI_Datatype dummy = $1;
+ ])],
+ [AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_$1$2, 1, available)
+ ],
+ [AC_MSG_RESULT(no)]
+ )]
+)
+
+dnl Check if older Intel MPI C compiler (4.x) for issue of redefined SEEK_SET
+dnl See https://software.intel.com/en-us/articles/intel-cluster-toolkit-for-linux-error-when-compiling-c-aps-using-intel-mpi-library-compilation-driver-mpiicpc
+AC_DEFUN([UD_CHECK_MPI_CPP_SEEK_SET], [
+ AC_MSG_CHECKING(if MPI C++ compiler redefines SEEK_SET )
+ CXX=${MPICXX}
+ AC_LANG_PUSH(C++)
+ AC_COMPILE_IFELSE(
+ [AC_LANG_SOURCE([
+ #include <stdio.h>
+ #include <mpi.h>
+ int main() { return 0; }
+ ])],
+ [ac_cv_CHECK_MPI_CPP_SEEK_SET=no],
+ [ac_cv_CHECK_MPI_CPP_SEEK_SET=yes]
+ )
+ AC_MSG_RESULT([$ac_cv_CHECK_MPI_CPP_SEEK_SET])
+ AC_LANG_POP(C++)]
+)
+
diff --git a/benchmarks/C/Makefile.in b/benchmarks/C/Makefile.in
new file mode 100644
index 0000000..a1c697d
--- /dev/null
+++ b/benchmarks/C/Makefile.in
@@ -0,0 +1,59 @@
+#
+# Copyright (C) 2012, Northwestern University and Argonne National Laboratory
+# See COPYRIGHT notice in top-level directory.
+#
+# $Id: Makefile.in 2215 2015-12-08 04:58:04Z wkliao $
+#
+# @configure_input@
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+include ../../macros.make
+
+# note the order of -L list matters
+INCLUDES = -I../../src/lib
+LDFLAGS := -L../../src/lib $(LDFLAGS)
+LIBS := -lpnetcdf $(LIBS)
+
+C_SRCS = aggregation.c \
+ write_block_read_column.c
+
+PROGS = $(C_SRCS:.c=)
+OBJS = $(C_SRCS:.c=.o)
+
+GARBAGE = $(PROGS) *.nc
+
+PACKING_LIST = $(C_SRCS) Makefile.in depend
+
+all: $(PROGS)
+
+install:
+
+uninstall:
+
+aggregation: aggregation.o $(LIBRARY)
+ $(LINK.c) $< $(LDFLAGS) $(LIBS)
+
+write_block_read_column: write_block_read_column.o $(LIBRARY)
+ $(LINK.c) $< $(LDFLAGS) $(LIBS)
+
+TEST_MPIRUN_4 = $(subst NP,4,$(TEST_MPIRUN))
+
+ptest: $(PROGS)
+ @for i in $(PROGS); do ( \
+ echo "-----------------------------------------------------" ; \
+ echo "$(TEST_MPIRUN_4) ./$$i 10 $(TEST_OUTDIR)/testfile.nc" ; \
+ echo "-----------------------------------------------------" ; \
+ $(TEST_MPIRUN_4) ./$$i 10 $(TEST_OUTDIR)/testfile.nc \
+ ; ) ; done
+ @echo "-----------------------------------------------------"
+
+ptests:
+
+include $(srcdir)/depend
+
+include $(srcdir)/../../rules.make
+
+$(LIBRARY): ;
+
diff --git a/benchmarks/C/aggregation.c b/benchmarks/C/aggregation.c
new file mode 100644
index 0000000..f5c8e20
--- /dev/null
+++ b/benchmarks/C/aggregation.c
@@ -0,0 +1,592 @@
+/*********************************************************************
+ *
+ * Copyright (C) 2013, Northwestern University
+ * See COPYRIGHT notice in top-level directory.
+ *
+ *********************************************************************/
+/* $Id: aggregation.c 2215 2015-12-08 04:58:04Z wkliao $ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <mpi.h>
+#include <pnetcdf.h>
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * This program writes a series of 2D variables with data partitioning patterns
+ * of block-block, *-cyclic, block-*, and *-block, round-robinly. The block-*
+ * partitioning case writes 1st half followed by 2nd half. The same partitioning
+ * patterns are used for read. In both cases, nonblocking APIs are used to
+ * evaluate the performance.
+ *
+ * The compile and run commands are given below, together with an ncmpidump of
+ * the output file. In this example, NVARS = 5.
+ *
+ * % mpicc -O2 -o aggregation aggregation.c -lpnetcdf
+ *
+ * % mpiexec -l -n 4 ./aggregation 5 /pvfs2/wkliao/testfile.nc
+ *
+ * % ncmpidump /pvfs2/wkliao/testfile.nc
+ * netcdf testfile {
+ * // file format: CDF-5 (big variables)
+ * dimensions:
+ * Block_BLOCK_Y = 10 ;
+ * Block_BLOCK_X = 10 ;
+ * Star_Y = 5 ;
+ * Cyclic_X = 20 ;
+ * Block_Y = 20 ;
+ * Star_X = 5 ;
+ * variables:
+ * int block_block_var_0(Block_BLOCK_Y, Block_BLOCK_X) ;
+ * float star_cyclic_var_1(Star_Y, Cyclic_X) ;
+ * short block_star_var_2(Block_Y, Star_X) ;
+ * double star_block_var_3(Star_Y, Cyclic_X) ;
+ * int block_block_var_4(Block_BLOCK_Y, Block_BLOCK_X) ;
+ * data:
+ *
+ * block_block_var_0 =
+ * 0, 0, 0, 0, 0, 2, 2, 2, 2, 2,
+ * 0, 0, 0, 0, 0, 2, 2, 2, 2, 2,
+ * 0, 0, 0, 0, 0, 2, 2, 2, 2, 2,
+ * 0, 0, 0, 0, 0, 2, 2, 2, 2, 2,
+ * 0, 0, 0, 0, 0, 2, 2, 2, 2, 2,
+ * 1, 1, 1, 1, 1, 3, 3, 3, 3, 3,
+ * 1, 1, 1, 1, 1, 3, 3, 3, 3, 3,
+ * 1, 1, 1, 1, 1, 3, 3, 3, 3, 3,
+ * 1, 1, 1, 1, 1, 3, 3, 3, 3, 3,
+ * 1, 1, 1, 1, 1, 3, 3, 3, 3, 3 ;
+ *
+ * star_cyclic_var_1 =
+ * 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3,
+ * 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3,
+ * 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3,
+ * 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3,
+ * 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3 ;
+ *
+ * block_star_var_2 =
+ * 0, 0, 0, 0, 0,
+ * 0, 0, 0, 0, 0,
+ * 0, 0, 0, 0, 0,
+ * 0, 0, 0, 0, 0,
+ * 0, 0, 0, 0, 0,
+ * 1, 1, 1, 1, 1,
+ * 1, 1, 1, 1, 1,
+ * 1, 1, 1, 1, 1,
+ * 1, 1, 1, 1, 1,
+ * 1, 1, 1, 1, 1,
+ * 2, 2, 2, 2, 2,
+ * 2, 2, 2, 2, 2,
+ * 2, 2, 2, 2, 2,
+ * 2, 2, 2, 2, 2,
+ * 2, 2, 2, 2, 2,
+ * 3, 3, 3, 3, 3,
+ * 3, 3, 3, 3, 3,
+ * 3, 3, 3, 3, 3,
+ * 3, 3, 3, 3, 3,
+ * 3, 3, 3, 3, 3 ;
+ *
+ * star_block_var_3 =
+ * 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3,
+ * 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3,
+ * 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3,
+ * 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3,
+ * 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3 ;
+ *
+ * block_block_var_4 =
+ * 0, 0, 0, 0, 0, 2, 2, 2, 2, 2,
+ * 0, 0, 0, 0, 0, 2, 2, 2, 2, 2,
+ * 0, 0, 0, 0, 0, 2, 2, 2, 2, 2,
+ * 0, 0, 0, 0, 0, 2, 2, 2, 2, 2,
+ * 0, 0, 0, 0, 0, 2, 2, 2, 2, 2,
+ * 1, 1, 1, 1, 1, 3, 3, 3, 3, 3,
+ * 1, 1, 1, 1, 1, 3, 3, 3, 3, 3,
+ * 1, 1, 1, 1, 1, 3, 3, 3, 3, 3,
+ * 1, 1, 1, 1, 1, 3, 3, 3, 3, 3,
+ * 1, 1, 1, 1, 1, 3, 3, 3, 3, 3 ;
+ * }
+ *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#define NVARS 5
+
+#define ERR(e) {if((e)!=NC_NOERR)printf("Error at line=%d: %s\n", __LINE__, ncmpi_strerror(e));}
+
+/*----< print_info() >------------------------------------------------------*/
+static
+void print_info(MPI_Info *info_used)
+{
+ int i, nkeys;
+
+ MPI_Info_get_nkeys(*info_used, &nkeys);
+ printf("MPI File Info: nkeys = %d\n",nkeys);
+ for (i=0; i<nkeys; i++) {
+ char key[MPI_MAX_INFO_KEY], value[MPI_MAX_INFO_VAL];
+ int valuelen, flag;
+
+ MPI_Info_get_nthkey(*info_used, i, key);
+ MPI_Info_get_valuelen(*info_used, key, &valuelen, &flag);
+ MPI_Info_get(*info_used, key, valuelen+1, value, &flag);
+ printf("MPI File Info: [%2d] key = %24s, value = %s\n",i,key,value);
+ }
+}
+
+/*----< benchmark_write() >---------------------------------------------------*/
+static
+int benchmark_write(char *filename,
+ MPI_Offset len,
+ MPI_Offset *w_size,
+ MPI_Info *w_info_used,
+ double *timing) /* [6] */
+{
+ int i, j, k, verbose, rank, nprocs, err, num_reqs;
+ int ncid, cmode, varid[NVARS], dimid[6], *reqs, *sts, psizes[2];
+ void *buf[NVARS];
+ double start_t, end_t;
+ MPI_Comm comm=MPI_COMM_WORLD;
+ MPI_Offset gsizes[2], start[2], count[2];
+ MPI_Info info=MPI_INFO_NULL;
+
+ verbose = 0;
+ MPI_Comm_rank(comm, &rank);
+ MPI_Comm_size(comm, &nprocs);
+
+ /* set PnetCDF I/O hints */
+ MPI_Info_create(&info);
+ /* To disable the header and fixed-size variable alignments, set the
+ following hints.
+ MPI_Info_set(info, "nc_header_align_size", "1"); size in bytes
+ MPI_Info_set(info, "nc_var_align_size", "1"); size in bytes
+ */
+
+ /* initialize I/O buffer with random numbers */
+ srand(rank);
+ for (i=0; i<NVARS; i++) {
+ if (i % 4 == 0) {
+ int *int_b = (int*) malloc(len * len * sizeof(int));
+ for (j=0; j<len*len; j++) int_b[j] = rank; /* rand(); */
+ buf[i] = (void*)int_b;
+ }
+ else if (i % 4 == 1) {
+ float *flt_b = (float*) malloc(len * len * sizeof(float));
+ for (j=0; j<len*len; j++) flt_b[j] = rank; /* rand(); */
+ buf[i] = (void*)flt_b;
+ }
+ else if (i % 4 == 2) {
+ short *shr_b = (short*) malloc(len * len * sizeof(short));
+ for (j=0; j<len*len; j++) shr_b[j] = rank; /* rand(); */
+ buf[i] = (void*)shr_b;
+ }
+ else {
+ double *dbl_b = (double*) malloc(len * len * sizeof(double));
+ for (j=0; j<len*len; j++) dbl_b[j] = rank; /* rand(); */
+ buf[i] = (void*)dbl_b;
+ }
+ }
+ MPI_Barrier(comm);
+ timing[0] = MPI_Wtime();
+
+ /* create a new file for writing -----------------------------------------*/
+ cmode = NC_CLOBBER | NC_64BIT_DATA;
+ err = ncmpi_create(comm, filename, cmode, info, &ncid); ERR(err)
+ start_t = MPI_Wtime();
+ timing[1] = start_t - timing[0];
+ MPI_Info_free(&info);
+
+ psizes[0] = psizes[1] = 0;
+ MPI_Dims_create(nprocs, 2, psizes);
+
+ gsizes[0] = len * psizes[0];
+ gsizes[1] = len * psizes[1];
+
+ err = ncmpi_def_dim(ncid, "Block_BLOCK_Y", gsizes[0], &dimid[0]); ERR(err)
+ err = ncmpi_def_dim(ncid, "Block_BLOCK_X", gsizes[1], &dimid[1]); ERR(err)
+ err = ncmpi_def_dim(ncid, "Star_Y", len, &dimid[2]); ERR(err)
+ err = ncmpi_def_dim(ncid, "Cyclic_X", len*nprocs, &dimid[3]); ERR(err)
+ err = ncmpi_def_dim(ncid, "Block_Y", len*nprocs, &dimid[4]); ERR(err)
+ err = ncmpi_def_dim(ncid, "Star_X", len, &dimid[5]); ERR(err)
+
+ /* define variables */
+ num_reqs = 0;
+ for (i=0; i<NVARS; i++) {
+ char var_name[32];
+ if (i % 4 == 0) {
+ /* variables are block-block partitioned */
+ sprintf(var_name,"block_block_var_%d",i);
+ err = ncmpi_def_var(ncid, var_name, NC_INT, 2, dimid, &varid[i]);
+ ERR(err)
+ num_reqs++; /* complete in 1 nonblocking call */
+ }
+ else if (i % 4 == 1) {
+ /* variables are *-cyclic partitioned */
+ sprintf(var_name,"star_cyclic_var_%d",i);
+ err = ncmpi_def_var(ncid, var_name, NC_FLOAT, 2, dimid+2, &varid[i]);
+ ERR(err)
+ num_reqs += len; /* complete in len nonblocking calls */
+ }
+ else if (i % 4 == 2) {
+ /* variables are block-* partitioned */
+ sprintf(var_name,"block_star_var_%d",i);
+ err = ncmpi_def_var(ncid, var_name, NC_SHORT, 2, dimid+4, &varid[i]);
+ ERR(err)
+ num_reqs += 2; /* write 1st half followed by 2nd half */
+ }
+ else {
+ /* variables are *-block partitioned */
+ sprintf(var_name,"star_block_var_%d",i);
+ err = ncmpi_def_var(ncid, var_name, NC_DOUBLE, 2, dimid+2, &varid[i]);
+ ERR(err)
+ num_reqs++; /* complete in 1 nonblocking call */
+ }
+ }
+ reqs = (int*) malloc(num_reqs * sizeof(int));
+
+ err = ncmpi_enddef(ncid); ERR(err)
+ end_t = MPI_Wtime();
+ timing[2] = end_t - start_t;
+ start_t = end_t;
+
+ k = 0;
+ for (i=0; i<NVARS; i++) {
+ if (i % 4 == 0) {
+ int *int_b = (int*) buf[i];
+ start[0] = len * (rank % psizes[0]);
+ start[1] = len * ((rank / psizes[1]) % psizes[1]);
+ count[0] = len;
+ count[1] = len;
+ err = ncmpi_iput_vara_int(ncid, varid[i], start, count, int_b,
+ &reqs[k++]);
+ ERR(err)
+ if (verbose) printf("block-block %d: start=%lld %lld count=%lld %lld\n",i,start[0],start[1],count[0],count[1]);
+ }
+ else if (i % 4 == 1) {
+ float *flt_b = (float*) buf[i];
+ start[0] = 0;
+ count[0] = len;
+ count[1] = 1;
+ for (j=0; j<len; j++) {
+ start[1] = rank + j * nprocs;
+ err = ncmpi_iput_vara_float(ncid, varid[i], start, count,
+ flt_b, &reqs[k++]);
+ ERR(err)
+ flt_b += len;
+ if (verbose) printf("*-cyclic i=%d j=%d: start=%lld %lld count=%lld %lld\n",i,j,start[0],start[1],count[0],count[1]);
+ }
+ }
+ else if (i % 4 == 2) {
+ short *shr_b = (short*) buf[i];
+ start[0] = len * rank;
+ start[1] = 0;
+ count[0] = len;
+ count[1] = len/2;
+ err = ncmpi_iput_vara_short(ncid, varid[i], start, count,
+ shr_b, &reqs[k++]);
+ ERR(err)
+ if (verbose) printf("block-* i=0 start=%lld %lld count=%lld %lld\n",start[0],start[1],count[0],count[1]);
+
+ shr_b += len * (len/2);
+ start[1] = len/2;
+ count[1] = len - len/2;
+ err = ncmpi_iput_vara_short(ncid, varid[i], start, count,
+ shr_b, &reqs[k++]);
+ ERR(err)
+ if (verbose) printf("block-* i=1 start=%lld %lld count=%lld %lld\n",start[0],start[1],count[0],count[1]);
+ }
+ else {
+ double *dbl_b = (double*) buf[i];
+ start[0] = 0;
+ start[1] = len * rank;
+ count[0] = len;
+ count[1] = len;
+ err = ncmpi_iput_vara_double(ncid, varid[i], start, count, dbl_b,
+ &reqs[k++]);
+ ERR(err)
+ if (verbose) printf("*-block %d: start=%lld %lld count=%lld %lld\n",i,start[0],start[1],count[0],count[1]);
+ }
+ }
+ num_reqs = k;
+
+ end_t = MPI_Wtime();
+ timing[3] = end_t - start_t;
+ start_t = end_t;
+
+ sts = (int*) malloc(num_reqs * sizeof(int));
+
+#ifdef USE_INDEP_MODE
+ err = ncmpi_begin_indep_data(ncid); ERR(err)
+ err = ncmpi_wait(ncid, num_reqs, reqs, sts); ERR(err)
+ err = ncmpi_end_indep_data(ncid); ERR(err)
+#else
+ err = ncmpi_wait_all(ncid, num_reqs, reqs, sts); ERR(err)
+#endif
+ /* check status of all requests */
+ for (i=0; i<num_reqs; i++) ERR(sts[i])
+
+ end_t = MPI_Wtime();
+ timing[4] = end_t - start_t;
+ start_t = end_t;
+
+ /* get the true I/O amount committed */
+ err = ncmpi_inq_put_size(ncid, w_size); ERR(err)
+
+ /* get all the hints used */
+ err = ncmpi_get_file_info(ncid, w_info_used); ERR(err)
+
+ err = ncmpi_close(ncid); ERR(err)
+
+ end_t = MPI_Wtime();
+ timing[5] = end_t - start_t;
+ timing[0] = end_t - timing[0];
+
+ free(sts);
+ free(reqs);
+ for (i=0; i<NVARS; i++) free(buf[i]);
+
+ return 1;
+}
+
+/*----< benchmark_read() >---------------------------------------------------*/
+static
+int benchmark_read(char *filename,
+ MPI_Offset len,
+ MPI_Offset *r_size,
+ MPI_Info *r_info_used,
+ double *timing) /* [5] */
+{
+ int i, j, k, verbose, rank, nprocs, s_rank, err, num_reqs;
+ int ncid, omode, varid[NVARS], *reqs, *sts, psizes[2];
+ void *buf[NVARS];
+ double start_t, end_t;
+ MPI_Comm comm=MPI_COMM_WORLD;
+ MPI_Offset start[2], count[2];
+ MPI_Info info=MPI_INFO_NULL;
+
+ verbose = 0;
+ MPI_Comm_rank(comm, &rank);
+ MPI_Comm_size(comm, &nprocs);
+ s_rank = (rank + nprocs / 2 ) % nprocs;
+
+ psizes[0] = psizes[1] = 0;
+ MPI_Dims_create(nprocs, 2, psizes);
+
+ /* allocate I/O buffer */
+ for (i=0; i<NVARS; i++) {
+ if (i % 4 == 0)
+ buf[i] = malloc(len * len * sizeof(int));
+ else if (i % 4 == 1)
+ buf[i] = (float*) malloc(len * len * sizeof(float));
+ else if (i % 4 == 2)
+ buf[i] = (short*) malloc(len * len * sizeof(short));
+ else
+ buf[i] = (double*) malloc(len * len * sizeof(double));
+ }
+ MPI_Barrier(comm);
+ timing[0] = MPI_Wtime();
+
+ /* open file for reading -----------------------------------------*/
+ omode = NC_NOWRITE;
+ err = ncmpi_open(comm, filename, omode, info, &ncid); ERR(err)
+ start_t = MPI_Wtime();
+ timing[1] = start_t - timing[0];
+
+ /* Note that PnetCDF read the file in chunks of size 256KB, thus the read
+ * amount may be more than the file header size
+ */
+ if (verbose) {
+ MPI_Offset h_size, h_extent;
+ ncmpi_inq_header_size(ncid, &h_size);
+ ncmpi_inq_header_extent(ncid, &h_extent);
+ printf("File header size=%lld extent=%lld\n",h_size,h_extent);
+ }
+
+ num_reqs = 0;
+ for (i=0; i<NVARS; i++) {
+ varid[i] = i;
+ if (i % 4 == 0)
+ num_reqs++; /* complete in 1 nonblocking call */
+ else if (i % 4 == 1)
+ num_reqs += len; /* complete in len nonblocking calls */
+ else if (i % 4 == 2)
+ num_reqs += 2; /* write 1st half followed by 2nd half */
+ else
+ num_reqs++; /* complete in 1 nonblocking call */
+ }
+ reqs = (int*) malloc(num_reqs * sizeof(int));
+
+ k = 0;
+ for (i=0; i<NVARS; i++) {
+ if (i % 4 == 0) {
+ int *int_b = (int*) buf[i];
+ start[0] = len * (s_rank % psizes[0]);
+ start[1] = len * ((s_rank / psizes[1]) % psizes[1]);
+ count[0] = len;
+ count[1] = len;
+ err = ncmpi_iget_vara_int(ncid, varid[i], start, count, int_b,
+ &reqs[k++]);
+ ERR(err)
+ }
+ else if (i % 4 == 1) {
+ float *flt_b = (float*) buf[i];
+ start[0] = 0;
+ count[0] = len;
+ count[1] = 1;
+ for (j=0; j<len; j++) {
+ start[1] = s_rank + j * nprocs;
+ err = ncmpi_iget_vara_float(ncid, varid[i], start, count,
+ flt_b, &reqs[k++]);
+ ERR(err)
+ flt_b += len;
+ }
+ }
+ else if (i % 4 == 2) {
+ short *shr_b = (short*) buf[i];
+ start[0] = len * s_rank;
+ start[1] = 0;
+ count[0] = len;
+ count[1] = len/2;
+ err = ncmpi_iget_vara_short(ncid, varid[i], start, count,
+ shr_b, &reqs[k++]);
+ ERR(err)
+
+ shr_b += len * (len/2);
+ start[1] = len/2;
+ count[1] = len - len/2;
+ err = ncmpi_iget_vara_short(ncid, varid[i], start, count,
+ shr_b, &reqs[k++]);
+ ERR(err)
+ }
+ else {
+ double *dbl_b = (double*) buf[i];
+ start[0] = 0;
+ start[1] = len * s_rank;
+ count[0] = len;
+ count[1] = len;
+ err = ncmpi_iget_vara_double(ncid, varid[i], start, count, dbl_b,
+ &reqs[k++]);
+ ERR(err)
+ }
+ }
+ num_reqs = k;
+
+ end_t = MPI_Wtime();
+ timing[2] = end_t - start_t;
+ start_t = end_t;
+
+ sts = (int*) malloc(num_reqs * sizeof(int));
+
+#ifdef USE_INDEP_MODE
+ err = ncmpi_begin_indep_data(ncid); ERR(err)
+ err = ncmpi_wait(ncid, num_reqs, reqs, sts); ERR(err)
+ err = ncmpi_end_indep_data(ncid); ERR(err)
+#else
+ err = ncmpi_wait_all(ncid, num_reqs, reqs, sts); ERR(err)
+#endif
+ /* check status of all requests */
+ for (i=0; i<num_reqs; i++) ERR(sts[i])
+
+ end_t = MPI_Wtime();
+ timing[3] = end_t - start_t;
+ start_t = end_t;
+
+ /* get the true I/O amount committed */
+ err = ncmpi_inq_get_size(ncid, r_size); ERR(err)
+
+ /* get all the hints used */
+ err = ncmpi_get_file_info(ncid, r_info_used); ERR(err)
+
+ err = ncmpi_close(ncid); ERR(err)
+
+ end_t = MPI_Wtime();
+ timing[4] = end_t - start_t;
+ timing[0] = end_t - timing[0];
+
+ free(sts);
+ free(reqs);
+ for (i=0; i<NVARS; i++) free(buf[i]);
+
+ return 1;
+}
+
+/*----< main() >--------------------------------------------------------------*/
+int main(int argc, char** argv) {
+ int rank, nprocs;
+ double timing[11], max_t[11];
+ MPI_Offset len, w_size=0, r_size=0, sum_w_size, sum_r_size;
+ MPI_Comm comm=MPI_COMM_WORLD;
+ MPI_Info w_info_used, r_info_used;
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_rank(comm, &rank);
+ MPI_Comm_size(comm, &nprocs);
+
+ if (argc != 3) {
+ if (!rank) printf("Usage: %s len filename\n",argv[0]);
+ MPI_Finalize();
+ return 0;
+ }
+ len = atoll(argv[1]);
+
+ benchmark_write(argv[2], len, &w_size, &w_info_used, timing);
+ benchmark_read (argv[2], len, &r_size, &r_info_used, timing+6);
+
+ MPI_Reduce(&timing, &max_t, 11, MPI_DOUBLE, MPI_MAX, 0, comm);
+#ifdef MPI_OFFSET
+ MPI_Reduce(&w_size, &sum_w_size, 1, MPI_OFFSET, MPI_SUM, 0, comm);
+ MPI_Reduce(&r_size, &sum_r_size, 1, MPI_OFFSET, MPI_SUM, 0, comm);
+#else
+ MPI_Reduce(&w_size, &sum_w_size, 1, MPI_LONG_LONG, MPI_SUM, 0, comm);
+ MPI_Reduce(&r_size, &sum_r_size, 1, MPI_LONG_LONG, MPI_SUM, 0, comm);
+#endif
+ if (rank == 0) {
+ double bw = sum_w_size;
+ bw /= 1048576.0;
+ print_info(&w_info_used);
+ printf("-----------------------------------------------------------\n");
+ printf("Write %d variables using nonblocking APIs\n", NVARS);
+ printf("In each process, the local variable size is %lld x %lld\n", len,len);
+ printf("Total write amount = %13lld B\n", sum_w_size);
+ printf(" amount = %16.4f MiB\n", bw);
+ printf(" amount = %16.4f GiB\n", bw/1024);
+ printf("Max file open/create time = %16.4f sec\n", max_t[1]);
+ printf("Max PnetCDF define time = %16.4f sec\n", max_t[2]);
+ printf("Max nonblocking post time = %16.4f sec\n", max_t[3]);
+ printf("Max nonblocking wait time = %16.4f sec\n", max_t[4]);
+ printf("Max file close time = %16.4f sec\n", max_t[5]);
+ printf("Max open-to-close time = %16.4f sec\n", max_t[0]);
+ printf("Write bandwidth = %16.4f MiB/s\n", bw/max_t[0]);
+ bw /= 1024.0;
+ printf("Write bandwidth = %16.4f GiB/s\n", bw/max_t[0]);
+
+ bw = sum_r_size;
+ bw /= 1048576.0;
+ printf("-----------------------------------------------------------\n");
+ printf("Read %d variables using nonblocking APIs\n", NVARS);
+ printf("In each process, the local variable size is %lld x %lld\n", len,len);
+ printf("Total read amount = %13lld B\n", sum_r_size);
+ printf(" amount = %16.4f MiB\n", bw);
+ printf(" amount = %16.4f GiB\n", bw/1024);
+ printf("Max file open/create time = %16.4f sec\n", max_t[7]);
+ printf("Max nonblocking post time = %16.4f sec\n", max_t[8]);
+ printf("Max nonblocking wait time = %16.4f sec\n", max_t[9]);
+ printf("Max file close time = %16.4f sec\n", max_t[10]);
+ printf("Max open-to-close time = %16.4f sec\n", max_t[6]);
+ printf("Read bandwidth = %16.4f MiB/s\n", bw/max_t[6]);
+ bw /= 1024.0;
+ printf("Read bandwidth = %16.4f GiB/s\n", bw/max_t[6]);
+ }
+ MPI_Info_free(&w_info_used);
+ MPI_Info_free(&r_info_used);
+
+ /* check if there is any PnetCDF internal malloc residue */
+ MPI_Offset malloc_size, sum_size;
+ int err = ncmpi_inq_malloc_size(&malloc_size);
+ if (err == NC_NOERR) {
+ MPI_Reduce(&malloc_size, &sum_size, 1, MPI_OFFSET, MPI_SUM, 0, MPI_COMM_WORLD);
+ if (rank == 0 && sum_size > 0)
+ printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n",
+ sum_size);
+ }
+
+ MPI_Finalize();
+ return 0;
+}
+
diff --git a/benchmarks/C/depend b/benchmarks/C/depend
new file mode 100644
index 0000000..04d0b02
--- /dev/null
+++ b/benchmarks/C/depend
@@ -0,0 +1,2 @@
+aggregation.o: aggregation.c
+write_block_read_column.o: write_block_read_column.c
diff --git a/benchmarks/C/write_block_read_column.c b/benchmarks/C/write_block_read_column.c
new file mode 100644
index 0000000..d756391
--- /dev/null
+++ b/benchmarks/C/write_block_read_column.c
@@ -0,0 +1,401 @@
+/*********************************************************************
+ *
+ * Copyright (C) 2013, Northwestern University
+ * See COPYRIGHT notice in top-level directory.
+ *
+ *********************************************************************/
+/* $Id: write_block_read_column.c 2215 2015-12-08 04:58:04Z wkliao $ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <mpi.h>
+#include <pnetcdf.h>
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * This program writes a series of 2D variables with a block-block data
+ * partitioning pattern. The 2D variables are read back in a *-block pattern.
+ *
+ * The compile and run commands are given below, together with an ncmpidump of
+ * the output file. In this example, NVARS = 4.
+ *
+ * % mpicc -O2 -o write_block_read_column write_block_read_column.c -lpnetcdf
+ *
+ * % mpiexec -l -n 4 ./write_block_read_column 128 /pvfs2/wkliao/testfile.nc
+ *
+ * % ncmpidump -h /pvfs2/wkliao/testfile.nc
+ * netcdf testfile {
+ * // file format: CDF-5 (big variables)
+ * dimensions:
+ * Y = 256 ;
+ * X = 256 ;
+ * variables:
+ * int block_block_var_0(Y, X) ;
+ * float block_block_var_1(Y, X) ;
+ * short block_block_var_2(Y, X) ;
+ * double block_block_var_3(Y, X) ;
+ * }
+ *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#define NVARS 4
+
+#define ERR(e) {if((e)!=NC_NOERR)printf("Error at line=%d: %s\n", __LINE__, ncmpi_strerror(e));}
+
+/*----< print_info() >------------------------------------------------------*/
+static
+void print_info(MPI_Info *info_used)
+{
+ int i, nkeys;
+
+ MPI_Info_get_nkeys(*info_used, &nkeys);
+ printf("MPI File Info: nkeys = %d\n",nkeys);
+ for (i=0; i<nkeys; i++) {
+ char key[MPI_MAX_INFO_KEY], value[MPI_MAX_INFO_VAL];
+ int valuelen, flag;
+
+ MPI_Info_get_nthkey(*info_used, i, key);
+ MPI_Info_get_valuelen(*info_used, key, &valuelen, &flag);
+ MPI_Info_get(*info_used, key, valuelen+1, value, &flag);
+ printf("MPI File Info: [%2d] key = %25s, value = %s\n",i,key,value);
+ }
+}
+
+/*----< benchmark_write() >---------------------------------------------------*/
+static
+int benchmark_write(char *filename,
+ MPI_Offset len,
+ MPI_Offset *w_size,
+ MPI_Info *w_info_used,
+ double *timing) /* [6] */
+{
+ int i, j, rank, nprocs, err;
+ int ncid, cmode, varid[NVARS], dimid[2], psizes[2];
+ void *buf[NVARS];
+ double start_t, end_t;
+ MPI_Comm comm=MPI_COMM_WORLD;
+ MPI_Offset gsizes[2], start[2], count[2];
+ MPI_Info info=MPI_INFO_NULL;
+
+ MPI_Comm_rank(comm, &rank);
+ MPI_Comm_size(comm, &nprocs);
+
+ /* set PnetCDF I/O hints */
+ MPI_Info_create(&info);
+ MPI_Info_set(info, "nc_header_align_size", "1"); /* size in bytes */
+ MPI_Info_set(info, "nc_var_align_size", "1"); /* size in bytes */
+ MPI_Info_set(info, "nc_header_read_chunk_size", "512"); /* size in bytes */
+ /* note that set the above values to 1 to disable the alignment */
+
+ /* initialize I/O buffer with random numbers */
+ srand(rank);
+ for (i=0; i<NVARS; i++) {
+ if (i % 4 == 0) {
+ int *int_b = (int*) malloc(len * len * sizeof(int));
+ for (j=0; j<len*len; j++) int_b[j] = rank; /* rand(); */
+ buf[i] = (void*)int_b;
+ }
+ else if (i % 4 == 1) {
+ float *flt_b = (float*) malloc(len * len * sizeof(float));
+ for (j=0; j<len*len; j++) flt_b[j] = rank; /* rand(); */
+ buf[i] = (void*)flt_b;
+ }
+ else if (i % 4 == 2) {
+ short *shr_b = (short*) malloc(len * len * sizeof(short));
+ for (j=0; j<len*len; j++) shr_b[j] = rank; /* rand(); */
+ buf[i] = (void*)shr_b;
+ }
+ else {
+ double *dbl_b = (double*) malloc(len * len * sizeof(double));
+ for (j=0; j<len*len; j++) dbl_b[j] = rank; /* rand(); */
+ buf[i] = (void*)dbl_b;
+ }
+ }
+ MPI_Barrier(comm);
+ timing[0] = MPI_Wtime();
+
+ /* create a new file for writing -----------------------------------------*/
+ cmode = NC_CLOBBER | NC_64BIT_DATA;
+ err = ncmpi_create(comm, filename, cmode, info, &ncid); ERR(err)
+ start_t = MPI_Wtime();
+ timing[1] = start_t - timing[0];
+ MPI_Info_free(&info);
+
+ psizes[0] = psizes[1] = 0;
+ MPI_Dims_create(nprocs, 2, psizes);
+
+ gsizes[0] = len * psizes[0];
+ gsizes[1] = len * psizes[1];
+
+ err = ncmpi_def_dim(ncid, "Y", gsizes[0], &dimid[0]); ERR(err)
+ err = ncmpi_def_dim(ncid, "X", gsizes[1], &dimid[1]); ERR(err)
+
+ /* define variables */
+ for (i=0; i<NVARS; i++) {
+ char var_name[32];
+ sprintf(var_name,"block_block_var_%d",i);
+ if (i % 4 == 0) {
+ err = ncmpi_def_var(ncid, var_name, NC_INT, 2, dimid, &varid[i]);
+ ERR(err)
+ }
+ else if (i % 4 == 1) {
+ err = ncmpi_def_var(ncid, var_name, NC_FLOAT, 2, dimid, &varid[i]);
+ ERR(err)
+ }
+ else if (i % 4 == 2) {
+ err = ncmpi_def_var(ncid, var_name, NC_SHORT, 2, dimid, &varid[i]);
+ ERR(err)
+ }
+ else {
+ err = ncmpi_def_var(ncid, var_name, NC_DOUBLE, 2, dimid, &varid[i]);
+ ERR(err)
+ }
+ }
+
+ err = ncmpi_enddef(ncid); ERR(err)
+ end_t = MPI_Wtime();
+ timing[2] = end_t - start_t;
+ start_t = end_t;
+
+ start[0] = len * (rank % psizes[0]);
+ start[1] = len * ((rank / psizes[1]) % psizes[1]);
+ count[0] = len;
+ count[1] = len;
+
+ for (i=0; i<NVARS; i++) {
+ if (i % 4 == 0) {
+ err = ncmpi_put_vara_int_all(ncid, varid[i], start, count, (int*)buf[i]);
+ ERR(err)
+ }
+ else if (i % 4 == 1) {
+ err = ncmpi_put_vara_float_all(ncid, varid[i], start, count, (float*)buf[i]);
+ ERR(err)
+ }
+ else if (i % 4 == 2) {
+ err = ncmpi_put_vara_short_all(ncid, varid[i], start, count, (short*)buf[i]);
+ ERR(err)
+ }
+ else {
+ err = ncmpi_put_vara_double_all(ncid, varid[i], start, count, (double*)buf[i]);
+ ERR(err)
+ }
+ }
+
+ end_t = MPI_Wtime();
+ timing[3] = end_t - start_t;
+ start_t = end_t;
+
+ /* get the true I/O amount committed */
+ err = ncmpi_inq_put_size(ncid, w_size); ERR(err)
+
+ /* get all the hints used */
+ err = ncmpi_get_file_info(ncid, w_info_used); ERR(err)
+
+ err = ncmpi_close(ncid); ERR(err)
+
+ end_t = MPI_Wtime();
+ timing[4] = end_t - start_t;
+ timing[0] = end_t - timing[0];
+
+ for (i=0; i<NVARS; i++) free(buf[i]);
+
+ return 1;
+}
+
+/*----< benchmark_read() >---------------------------------------------------*/
+static
+int benchmark_read(char *filename,
+ MPI_Offset len,
+ MPI_Offset *r_size,
+ MPI_Info *r_info_used,
+ double *timing) /* [5] */
+{
+ int i, rank, nprocs, err;
+ int ncid, omode, nvars, dimid[2], *varid;
+ void **buf;
+ double start_t, end_t;
+ MPI_Offset gsizes[2], start[2], count[2];
+ MPI_Comm comm=MPI_COMM_WORLD;
+ MPI_Info info=MPI_INFO_NULL;
+
+ MPI_Comm_rank(comm, &rank);
+ MPI_Comm_size(comm, &nprocs);
+
+ /* set PnetCDF I/O hints */
+ MPI_Info_create(&info);
+ MPI_Info_set(info, "nc_header_read_chunk_size", "512"); /* size in bytes */
+
+ MPI_Barrier(comm);
+ timing[0] = MPI_Wtime();
+
+ /* open file for reading -----------------------------------------*/
+ omode = NC_NOWRITE;
+ err = ncmpi_open(comm, filename, omode, info, &ncid); ERR(err)
+ start_t = MPI_Wtime();
+ timing[1] = start_t - timing[0];
+ MPI_Info_free(&info);
+
+ err = ncmpi_inq_nvars(ncid, &nvars); ERR(err)
+ err = ncmpi_inq_dimid(ncid, "Y", &dimid[0]); ERR(err)
+ err = ncmpi_inq_dimid(ncid, "X", &dimid[1]); ERR(err)
+ err = ncmpi_inq_dimlen(ncid, dimid[0], &gsizes[0]); ERR(err)
+ err = ncmpi_inq_dimlen(ncid, dimid[1], &gsizes[1]); ERR(err)
+
+ varid = (int*) malloc(nvars * sizeof(int));
+ buf = (void**) malloc(nvars * sizeof(void*));
+
+ /* construct *-block partitioning pattern */
+ start[0] = 0;
+ start[1] = (gsizes[1] / nprocs) * rank;
+ count[0] = gsizes[0];
+ count[1] = gsizes[1] / nprocs;
+ if (rank < gsizes[1] % nprocs) {
+ start[1] += rank;
+ count[1]++;
+ }
+ else
+ start[1] += gsizes[1] % nprocs;
+
+ /* allocate I/O buffer */
+ len = count[0] * count[1];
+ for (i=0; i<nvars; i++) {
+ varid[i] = i;
+ if (i % 4 == 0)
+ buf[i] = malloc(len * sizeof(int));
+ else if (i % 4 == 1)
+ buf[i] = (float*) malloc(len * sizeof(float));
+ else if (i % 4 == 2)
+ buf[i] = (short*) malloc(len * sizeof(short));
+ else
+ buf[i] = (double*) malloc(len * sizeof(double));
+ }
+ end_t = MPI_Wtime();
+ timing[2] = end_t - start_t;
+ start_t = end_t;
+
+ for (i=0; i<nvars; i++) {
+ if (i % 4 == 0) {
+ err = ncmpi_get_vara_int_all(ncid, varid[i], start, count, (int*)buf[i]);
+ ERR(err)
+ }
+ else if (i % 4 == 1) {
+ err = ncmpi_get_vara_float_all(ncid, varid[i], start, count, (float*)buf[i]);
+ ERR(err)
+ }
+ else if (i % 4 == 2) {
+ err = ncmpi_get_vara_short_all(ncid, varid[i], start, count, (short*)buf[i]);
+ ERR(err)
+ }
+ else {
+ err = ncmpi_get_vara_double_all(ncid, varid[i], start, count, (double*)buf[i]);
+ ERR(err)
+ }
+ }
+
+ end_t = MPI_Wtime();
+ timing[3] = end_t - start_t;
+ start_t = end_t;
+
+ /* get the true I/O amount committed */
+ err = ncmpi_inq_get_size(ncid, r_size); ERR(err)
+
+ /* get all the hints used */
+ err = ncmpi_get_file_info(ncid, r_info_used); ERR(err)
+
+ err = ncmpi_close(ncid); ERR(err)
+
+ end_t = MPI_Wtime();
+ timing[4] = end_t - start_t;
+ timing[0] = end_t - timing[0];
+
+ for (i=0; i<nvars; i++) free(buf[i]);
+ free(buf);
+ free(varid);
+
+ return 1;
+}
+
+/*----< main() >--------------------------------------------------------------*/
+int main(int argc, char** argv) {
+ int rank, nprocs;
+ double timing[10], max_t[10];
+ MPI_Offset len, w_size, r_size, sum_w_size, sum_r_size;
+ MPI_Comm comm=MPI_COMM_WORLD;
+ MPI_Info w_info_used, r_info_used;
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_rank(comm, &rank);
+ MPI_Comm_size(comm, &nprocs);
+
+ if (argc != 3) {
+ if (!rank) printf("Usage: %s len filename\n",argv[0]);
+ MPI_Finalize();
+ return 0;
+ }
+ len = atoll(argv[1]);
+
+ benchmark_write(argv[2], len, &w_size, &w_info_used, timing);
+ benchmark_read (argv[2], len, &r_size, &r_info_used, timing+5);
+
+ MPI_Reduce(&timing, &max_t, 10, MPI_DOUBLE, MPI_MAX, 0, comm);
+#ifdef MPI_OFFSET
+ MPI_Reduce(&w_size, &sum_w_size, 1, MPI_OFFSET, MPI_SUM, 0, comm);
+ MPI_Reduce(&r_size, &sum_r_size, 1, MPI_OFFSET, MPI_SUM, 0, comm);
+#else
+ MPI_Reduce(&w_size, &sum_w_size, 1, MPI_LONG_LONG, MPI_SUM, 0, comm);
+ MPI_Reduce(&r_size, &sum_r_size, 1, MPI_LONG_LONG, MPI_SUM, 0, comm);
+#endif
+ if (rank == 0) {
+ double bw = sum_w_size;
+ bw /= 1048576.0;
+ print_info(&w_info_used);
+
+ printf("-----------------------------------------------------------\n");
+ printf("Write %d variables using blocking APIs\n", NVARS);
+ printf("In each process, the local variable size is %lld x %lld\n", len,len);
+ printf("Total write amount = %13lld B\n", sum_w_size);
+ printf(" amount = %16.4f MiB\n", bw);
+ printf(" amount = %16.4f GiB\n", bw/1024);
+ printf("Max file open/create time = %16.4f sec\n", max_t[1]);
+ printf("Max PnetCDF define time = %16.4f sec\n", max_t[2]);
+ printf("Max PnetCDF put time = %16.4f sec\n", max_t[3]);
+ printf("Max file close time = %16.4f sec\n", max_t[4]);
+ printf("Max open-to-close time = %16.4f sec\n", max_t[0]);
+ printf("Write bandwidth = %16.4f MiB/s\n", bw/max_t[0]);
+ bw /= 1024.0;
+ printf("Write bandwidth = %16.4f GiB/s\n", bw/max_t[0]);
+
+ bw = sum_r_size;
+ bw /= 1048576.0;
+ printf("-----------------------------------------------------------\n");
+ printf("Read %d variables using blocking APIs\n", NVARS);
+ printf("In each process, the local variable size is %lld x %lld\n", len,len);
+ printf("Total read amount = %13lld B\n", sum_r_size);
+ printf(" amount = %16.4f MiB\n", bw);
+ printf(" amount = %16.4f GiB\n", bw/1024);
+ printf("Max file open/create time = %16.4f sec\n", max_t[6]);
+ printf("Max PnetCDF inquire time = %16.4f sec\n", max_t[7]);
+ printf("Max PnetCDF get time = %16.4f sec\n", max_t[8]);
+ printf("Max file close time = %16.4f sec\n", max_t[9]);
+ printf("Max open-to-close time = %16.4f sec\n", max_t[5]);
+ printf("Read bandwidth = %16.4f MiB/s\n", bw/max_t[5]);
+ bw /= 1024.0;
+ printf("Read bandwidth = %16.4f GiB/s\n", bw/max_t[5]);
+ }
+ MPI_Info_free(&w_info_used);
+ MPI_Info_free(&r_info_used);
+
+ /* check if there is any PnetCDF internal malloc residue */
+ MPI_Offset malloc_size, sum_size;
+ int err = ncmpi_inq_malloc_size(&malloc_size);
+ if (err == NC_NOERR) {
+ MPI_Reduce(&malloc_size, &sum_size, 1, MPI_OFFSET, MPI_SUM, 0, MPI_COMM_WORLD);
+ if (rank == 0 && sum_size > 0)
+ printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n",
+ sum_size);
+ }
+
+ MPI_Finalize();
+ return 0;
+}
+
diff --git a/benchmarks/FLASH-IO/Makefile.in b/benchmarks/FLASH-IO/Makefile.in
new file mode 100644
index 0000000..032e791
--- /dev/null
+++ b/benchmarks/FLASH-IO/Makefile.in
@@ -0,0 +1,93 @@
+#
+# Copyright (C) 2012, Northwestern University and Argonne National Laboratory
+# See COPYRIGHT notice in top-level directory.
+#
+# $Id: Makefile.in 2219 2015-12-11 22:30:03Z wkliao $
+#
+# @configure_input@
+
+.SUFFIXES: .o .F90
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+RM = @RM@
+F90 = @MPIF90@
+
+FPPFLAGS = @FPPFLAGS@ @FC_MODINC@@PNETCDF_INC@ -I$(srcdir) @NAGf90FPPFLAGS@
+FPPFLAGS += @FC_DEFINE at N_DIM=3 @FC_DEFINE at MAXBLOCKS=100 @FC_DEFINE at IONMAX=13
+FPPFLAGS += @NAG_FCFLAGS@
+
+FCFLAGS = @FCFLAGS@
+COMPILE.F90 = $(F90) -c $(FCFLAGS) $(FPPFLAGS)
+FCLDFLAGS = @PNETCDF_LIB@ @LDFLAGS@
+FCLIBS = -lpnetcdf @LIBS@ @LCOV_LIB@
+LINK.F90 = $(F90) $(FCFLAGS) -o $@
+
+TEST_MPIRUN = @TEST_MPIRUN@
+TEST_OUTDIR = @TEST_OUTDIR@
+
+PROGS = flash_benchmark_io
+
+SRCS = get_mfluid_property.F90 \
+ flash_release.F90 \
+ flash_benchmark_io.F90 \
+ checkpoint_ncmpi_parallel.F90 \
+ plotfile_ncmpi_parallel.F90
+
+HEADERS = block_boundary_data.fh \
+ common.fh \
+ definitions.fh \
+ numfluids.fh \
+ physicaldata.fh \
+ tree.fh
+
+PACKING_LIST = $(SRCS) $(HEADERS) configure.in Makefile.in README
+
+GARBAGE = $(PROGS) *.nc
+DIST_GARBAGE = config.log config.status config.cache autom4te.cache \
+ Makefile
+
+OBJS = $(SRCS:.F90=.o)
+
+all: $(PROGS)
+
+.F90.o:
+ $(COMPILE.F90) $<
+
+$(PROGS): $(OBJS)
+ $(LINK.F90) $(OBJS) $(FCLDFLAGS) $(FCLIBS)
+
+TEST_MPIRUN_4 = $(subst NP,4,$(TEST_MPIRUN))
+
+ptest: $(PROGS)
+ $(TEST_MPIRUN_4) ./$(PROGS) $(TEST_OUTDIR)/flash_io_test_
+
+ptests:
+
+MANIFEST.echo: FORCE
+ echo $(PACKING_LIST) | fmt -1
+
+ensure_manifest:
+
+dist:
+ id=FLASH-IO-PnetCDF \
+ && $(RM) -rf $$id \
+ && mkdir $$id \
+ && cp $(PACKING_LIST) $$id \
+ && tar -c $$id | gzip > $$id.tar.gz \
+ && $(RM) -rf $$id
+
+install:
+
+uninstall:
+
+clean:
+ @$(RM) -f *.o core core.* $(GARBAGE) \
+ *.gcda *.gcno gmon.out
+
+distclean: clean
+ @$(RM) -rf $(DIST_GARBAGE)
+
+.PHONY: FORCE all clean distclean install uninstall dist ptest
+
diff --git a/benchmarks/FLASH-IO/README b/benchmarks/FLASH-IO/README
new file mode 100644
index 0000000..47bbee1
--- /dev/null
+++ b/benchmarks/FLASH-IO/README
@@ -0,0 +1,81 @@
+#
+# Copyright (C) 2013, Northwestern University
+# See COPYRIGHT notice in top-level directory.
+#
+# $Id: README 1468 2013-10-26 16:53:18Z wkliao $
+
+This software benchmarks the performance of Parallel NetCDF method
+for the I/O and data partitioning pattern from the FLASH I/O benchmark,
+developed at the Flash Center for Computational Science, University of
+Chicago (http://flash.uchicago.edu/site). The URL of the FLASH I/O
+benchmark suite is available from the following URL.
+http://www.ucolick.org/~zingale/flash_benchmark_io/
+
+The FLASH I/O benchmark suite is the I/O kernel of a block-structured adaptive
+mesh hydrodynamics code developed mainly for the study of nuclear flashes on
+neutron stars and white dwarfs. The computational domain is divided into
+blocks that are distributed across a number of MPI processes. A block is a
+three-dimensional array with an additional 4 elements as guard cells in each
+dimension on both sides to hold information from its neighbors. There are 24
+variables per array element, and about 80 blocks on each MPI process. A
+variation in block numbers, 80, 81, or 82, per MPI process is used to simulate
+a slightly unbalanced I/O load in real runs. Since the number of blocks is
+fixed for each process, increase in the number of MPI processes increases the
+aggregate I/O amount as well. FLASH I/O produces a checkpoint file containing
+all 24 variables and two visualization files containing centered and corner
+data covering only four plot variables. The largest file is the checkpoint
+and the I/O time of which dominates the entire benchmark.
+
+For some detailed description and an illustration of data partitioning pattern,
+please refer to the following paper.
+ Wei-keng Liao and Alok Choudhary. Dynamically Adapting File Domain
+ Partitioning Methods for Collective I/O Based on Underlying Parallel File
+ System Locking Protocols. In the Proceedings of International Conference
+ for High Performance Computing, Networking, Storage and Analysis, Austin,
+ Texas, November 2008.
+
+To compile:
+ run configure command first, eg.
+ autoreconf
+ ./configure --with-pnetcdf=/path/PnetCDF MPIF90=/path/mpi/F90/compiler
+ make
+
+To run:
+ mpiexec -n 512 flash_benchmark_io
+ (this will use the default file base name prefix: "")
+ or
+ mpiexec -n 512 flash_benchmark_io /pvfs2/flash_io_test_
+ (this will use file base name prefix: "/pvfs2/flash_io_test_")
+
+Example output from stdout:
+
+ number of guards : 4
+ number of blocks : 80
+ number of variables : 24
+ checkpoint time : 7.52 sec
+ max header : 1.76 sec
+ max unknown : 5.76 sec
+ max close : 0.00 sec
+ I/O amount : 31109.74 MiB
+ plot no corner : 1.28 sec
+ max header : 0.29 sec
+ max unknown : 0.99 sec
+ max close : 0.00 sec
+ I/O amount : 5190.36 MiB
+ plot corner : 1.56 sec
+ max header : 0.30 sec
+ max unknown : 1.27 sec
+ max close : 0.00 sec
+ I/O amount : 6224.35 MiB
+ -------------------------------------------------------
+ File base name : /scratch2/scratchdirs/wkliao/FS_1M_128/flash_io_test_
+ file striping count : 128
+ file striping size : 1048576 bytes
+ Total I/O amount : 42524.45 MiB
+ -------------------------------------------------------
+ nproc array size exec (sec) bandwidth (MiB/s)
+ 512 16 x 16 x 16 10.36 4103.52
+
+
+
+
diff --git a/benchmarks/FLASH-IO/block_boundary_data.fh b/benchmarks/FLASH-IO/block_boundary_data.fh
new file mode 100644
index 0000000..d8f1e33
--- /dev/null
+++ b/benchmarks/FLASH-IO/block_boundary_data.fh
@@ -0,0 +1,83 @@
+!
+! This file defines a data structure to be used for quantities
+! which may need to be defined at grid block interfaces, eg fluxes,
+! pressures.
+!
+
+
+! storage used for fluxes at block boundaries. This is used when conservation
+! constraints need to be imposed.
+
+! updated 2-15-00 -- allocate storage for the internal energy flux
+ integer nfluxvar
+ parameter(nfluxvar=nuc2+7) !<<< USER EDIT
+
+ integer nfluxes
+ parameter(nfluxes=max(1,nfluxvar))
+
+ integer maxblocksfl
+ parameter(maxblocksfl= 1+(maxblocks-1)*min(1,nfluxvar) )
+
+
+
+!..in 1d the flux_y, flux_z, tflux_y, and tflux_z arrays are not used,
+!..but do need to be declared. thus, in 1d the parameter maxblocksfl
+!..has been replaced with a 1. this significantly reduces the
+!..memory footprint for 1d simulations.
+
+!..in 2d the flux_z and tflux_z arrays are not used,
+!..but do need to be declared. thus, in 2d the parameter maxblocksfl
+!..has been replaced with a 1. this significantly reduces the
+!..memory footprint for 2d simulations.
+
+
+
+! storage used for cell edges at block boundaries.
+! This is used when quantities located at cell edge centers need to
+! be used consistently at the boundaries between blocks at different
+! refinement levels.
+
+ integer nedgevar
+ parameter(nedgevar=1) !<<< USER EDIT
+
+ integer nedges
+ parameter(nedges=max(1,nedgevar))
+
+ integer maxblockse
+ parameter(maxblockse= 1+(maxblocks-1)*min(1,nedgevar) )
+
+
+
+
+
+! workspace arrays used for inter-block communications
+ integer nbndmax
+ parameter(nbndmax=max(nbndvar,nfluxes))
+ common/blockbnd/ &
+ recvarx1(nbndmax,1:2,jl_bnd:ju_bnd,kl_bnd:ku_bnd) &
+ ,recvary1(nbndmax,il_bnd:iu_bnd,1:2,kl_bnd:ku_bnd) &
+ ,recvarz1(nbndmax,il_bnd:iu_bnd,jl_bnd:ju_bnd,1:2) &
+ ,bndtempx1(nfluxes,1:2,jl_bnd:ju_bnd,kl_bnd:ku_bnd) &
+ ,bndtempy1(nfluxes,il_bnd:iu_bnd,1:2,kl_bnd:ku_bnd) &
+ ,bndtempz1(nfluxes,il_bnd:iu_bnd,jl_bnd:ju_bnd,1:2)
+ double precision recvarx1,recvary1,recvarz1
+ double precision bndtempx1,bndtempy1,bndtempz1
+
+
+
+
+! parameters used in communication calls
+ integer len_block_bndx,len_block_bndy,len_block_bndz
+ parameter(len_block_bndx=2*(nyb+2*nguard*k2d)* &
+ (nzb+2*nguard*k3d))
+ parameter(len_block_bndy=2*(nxb+2*nguard*k2d)* &
+ (nzb+2*nguard*k3d))
+ parameter(len_block_bndz=2*(nxb+2*nguard)*(nyb+2*nguard))
+
+ integer len_block_ex,len_block_ey,len_block_ez
+ parameter(len_block_ex=2*(nyb+k2d+2*nguard*k2d)* &
+ (nzb+k3d+2*nguard*k3d))
+ parameter(len_block_ey=2*(nxb+1+2*nguard)* &
+ (nzb+k3d+2*nguard*k3d))
+ parameter(len_block_ez=2*(nxb+1+2*nguard)* &
+ (nyb+k2d+2*nguard))
diff --git a/benchmarks/FLASH-IO/checkpoint_ncmpi_parallel.F90 b/benchmarks/FLASH-IO/checkpoint_ncmpi_parallel.F90
new file mode 100644
index 0000000..b602a3e
--- /dev/null
+++ b/benchmarks/FLASH-IO/checkpoint_ncmpi_parallel.F90
@@ -0,0 +1,639 @@
+#define MDIM 3
+! 3-d problem */
+#if N_DIM == 3
+#define NDIM 3
+#define NGID 15
+! 2-d problem */
+#elif N_DIM == 2
+#define NDIM 2
+#define NGID 9
+! 1-d problem */
+#else
+#define NDIM 1
+#define NGID 5
+#endif
+
+ subroutine check(err, message)
+ use mpi
+ use pnetcdf
+ implicit none
+
+ integer err
+ character(len=*) message
+
+ ! It is a good idea to check returned value for possible error
+ write(6,*) trim(message), trim(nfmpi_strerror(err))
+ call MPI_Abort(MPI_COMM_WORLD, -1, err)
+ end subroutine check
+
+ subroutine write_header_info(nvar_out, ncid, file_creation_time, &
+ flash_version, total_blocks, time, &
+ nsteps, nzones_block, unk_labels, &
+ varid)
+ use mpi
+ use pnetcdf
+ implicit none
+
+ integer nvar_out ! num vars to store
+ integer ncid ! file handle
+ character(len=*) file_creation_time ! time and date stamp
+ character(len=*) flash_version ! FLASH version num
+ integer total_blocks ! total # of blocks
+ double precision time ! simulation time
+ integer nsteps ! total # of timestep
+ integer nzones_block(3) ! nxb, nyb, nzb
+ character(len=4) unk_labels(*) ! unknown labels
+ integer varid(*) ! output: var ids
+
+ ! local variables
+ integer i, k, err
+ integer dim_tot_blocks, dim_nxb, dim_nyb, dim_nzb
+ integer dim_NGID, dim_NDIM, dim_2
+ integer dimids(4)
+ character(len=5) record_label
+ integer(kind=MPI_OFFSET_KIND) i8NDIM, i8NGID, i8total_blocks
+ integer(kind=MPI_OFFSET_KIND) i8nzones_block(3), string_size
+ integer atotal_blocks(1), ansteps(1)
+ double precision atime(1)
+
+ i8NDIM = NDIM
+ i8NGID = NGID
+ i8total_blocks = total_blocks
+ i8nzones_block(:) = nzones_block(:)
+ atotal_blocks(1) = total_blocks
+ ansteps(1) = nsteps
+
+ ! to avoid inconsistent header metadata warning from PnetCDF
+ atime(1) = time
+ call MPI_Bcast(atime, 1, MPI_DOUBLE_PRECISION, 0, MPI_COMM_WORLD, err)
+
+ err = nfmpi_def_dim(ncid, "dim_tot_blocks", i8total_blocks, dim_tot_blocks)
+ if (err .NE. NF_NOERR) call check(err, "nfmpi_def_dim: dim_tot_blocks")
+ err = nfmpi_def_dim(ncid, "dim_nxb", i8nzones_block(1), dim_nxb)
+ if (err .NE. NF_NOERR) call check(err, "nfmpi_def_dim: dim_nxb")
+ err = nfmpi_def_dim(ncid, "dim_nyb", i8nzones_block(2), dim_nyb)
+ if (err .NE. NF_NOERR) call check(err, "nfmpi_def_dim: dim_nyb")
+ err = nfmpi_def_dim(ncid, "dim_nzb", i8nzones_block(3), dim_nzb)
+ if (err .NE. NF_NOERR) call check(err, "nfmpi_def_dim: dim_nzb")
+ err = nfmpi_def_dim(ncid, "dim_NGID", i8NGID, dim_NGID)
+ if (err .NE. NF_NOERR) call check(err, "nfmpi_def_dim: dim_NGID")
+ err = nfmpi_def_dim(ncid, "dim_NDIM", i8NDIM, dim_NDIM)
+ if (err .NE. NF_NOERR) call check(err, "nfmpi_def_dim: dim_NDIM")
+ err = nfmpi_def_dim(ncid, "dim_2", 2_MPI_OFFSET_KIND, dim_2)
+ if (err .NE. NF_NOERR) call check(err, "nfmpi_def_dim: dim_2")
+
+ dimids(1) = dim_tot_blocks
+
+ ! define var for refinement level
+ err = nfmpi_def_var(ncid, "lrefine", NF_INT, 1, dimids, varid(1))
+ if (err .NE. NF_NOERR) call check(err, "nfmpi_def_var: lrefine")
+
+ ! define var for nodetype
+ err = nfmpi_def_var(ncid, "nodetype", NF_INT, 1, dimids, varid(2))
+ if (err .NE. NF_NOERR) call check(err, "nfmpi_def_var: nodetype")
+
+ ! define var for global id
+ dimids(1) = dim_NGID
+ dimids(2) = dim_tot_blocks
+ err = nfmpi_def_var(ncid, "gid", NF_INT, 2, dimids, varid(3))
+ if (err .NE. NF_NOERR) call check(err, "nfmpi_def_var: grid")
+
+ ! define var for grid coordinates
+ dimids(1) = dim_NDIM
+ dimids(2) = dim_tot_blocks
+ err = nfmpi_def_var(ncid, "coordinates", NF_DOUBLE, 2, dimids, varid(4))
+ if (err .NE. NF_NOERR) call check(err, "nfmpi_def_var: coordinates")
+
+ ! define var for grid block size
+ dimids(1) = dim_NDIM
+ dimids(2) = dim_tot_blocks
+ err = nfmpi_def_var(ncid, "blocksize", NF_DOUBLE, 2, dimids, varid(5))
+ if (err .NE. NF_NOERR) call check(err, "nfmpi_def_var: blocksize")
+
+ ! define var for grid bounding box
+ dimids(1) = dim_2
+ dimids(2) = dim_NDIM
+ dimids(3) = dim_tot_blocks
+ err = nfmpi_def_var(ncid, "bndbox", NF_DOUBLE, 3, dimids, varid(6))
+ if (err .NE. NF_NOERR) call check(err, "nfmpi_def_var: bndbox")
+
+ ! define var for unknown array
+ dimids(1) = dim_nxb
+ dimids(2) = dim_nyb
+ dimids(3) = dim_nzb
+ dimids(4) = dim_tot_blocks
+
+ do i=1, nvar_out
+ record_label = unk_labels(i)
+ do k=1, 4
+ if (record_label(k:k) .EQ. ' ') record_label(k:k) = '_'
+ enddo
+ record_label(5:5) = char(0) ! string terminate char
+ err = nfmpi_def_var(ncid, record_label, NF_DOUBLE, 4, dimids, varid(i+6))
+ if (err .NE. NF_NOERR) call check(err, "nfmpi_def_var: record_label")
+ enddo
+
+ string_size = LEN_TRIM(file_creation_time)
+ err = nfmpi_put_att_text(ncid, NF_GLOBAL, "file_creation_time", string_size, file_creation_time)
+ if (err .NE. NF_NOERR) call check(err, "nfmpi_put_att_text: file_creation_time")
+ string_size = LEN_TRIM(flash_version)
+ err = nfmpi_put_att_text(ncid, NF_GLOBAL, "flash_version", string_size, flash_version)
+ if (err .NE. NF_NOERR) call check(err, "nfmpi_put_att_text: flash_version")
+ err = nfmpi_put_att_int(ncid, NF_GLOBAL, "total_blocks", NF_INT, 1_MPI_OFFSET_KIND, atotal_blocks)
+ if (err .NE. NF_NOERR) call check(err, "nfmpi_put_att_int: total_blocks")
+ err = nfmpi_put_att_int(ncid, NF_GLOBAL, "nsteps", NF_INT, 1_MPI_OFFSET_KIND, ansteps)
+ if (err .NE. NF_NOERR) call check(err, "nfmpi_put_att_int: nsteps")
+ err = nfmpi_put_att_int(ncid, NF_GLOBAL, "nxb", NF_INT, 1_MPI_OFFSET_KIND, nzones_block(1))
+ if (err .NE. NF_NOERR) call check(err, "nfmpi_put_att_int: nxb")
+ err = nfmpi_put_att_int(ncid, NF_GLOBAL, "nyb", NF_INT, 1_MPI_OFFSET_KIND, nzones_block(2))
+ if (err .NE. NF_NOERR) call check(err, "nfmpi_put_att_int: nyb")
+ err = nfmpi_put_att_int(ncid, NF_GLOBAL, "nzb", NF_INT, 1_MPI_OFFSET_KIND, nzones_block(3))
+ if (err .NE. NF_NOERR) call check(err, "nfmpi_put_att_int: nzb")
+ err = nfmpi_put_att_double(ncid, NF_GLOBAL, "time", NF_DOUBLE, 1_MPI_OFFSET_KIND, atime)
+ if (err .NE. NF_NOERR) call check(err, "nfmpi_put_att_double: time")
+
+ err = nfmpi_enddef(ncid)
+ if (err .NE. NF_NOERR) call check(err, "nfmpi_enddef")
+ end subroutine write_header_info
+
+!----------------------------------------------------------------------------
+! subroutine checkpoint_wr
+!----------------------------------------------------------------------------
+
+ double precision function checkpoint_wr_ncmpi_par (filenum, simtime)
+!
+! Do parallel i/o using Parallel netCDF
+!
+! MZ -- 2-20-00
+! Jianwei -- 11/15/02
+!
+! This version of checkpoint uses Parallel netCDF to store the PARAMESH data.
+! The IO is done in parallel -- no copying of the data to a single processor
+! to do the writing is performed.
+!
+! Parallel netCDF uses MPI-IO (via ROMIO) to support parallel IO. Each
+! processor must open the file, define the dataspaces for each netCDF
+! variables.
+!
+! A single record for each of the PARAMESH data structures is created. A
+! processor only writes to a subset of this record. Each record has a
+! dimension with length = tot_blocks. The offset of a processor into this
+! dimension is computed by looking at the total number of blocks that are
+! below the current processor.
+!
+! In this version of the checkpoint, each variable is given its own
+! record -- this makes it easier to change the variable list in the
+! future without disturbing the format of the file.
+!
+! The include file -- ncmpi_flash.h is used for the C routines and mirrors
+! the necessary data from physicaldata.fh
+!
+! written for netCDF 3.0
+!
+!---------------------------------------------------------------------------
+
+ use pnetcdf
+
+#include "common.fh"
+
+ integer filenum
+ double precision simtime
+
+ integer block_no
+ integer i, j
+ integer ngid
+ integer err
+
+ integer n_to_left(0:16383) ! must extend from 0 to NumPEs-1
+
+! 2-20-00 -- we don't need to allocate more space than necessary
+! integer gid(mfaces+1+mchild,maxblocks_tr)
+ integer gid(nfaces+1+nchild,maxblocks_tr)
+
+ integer tot_blocks
+
+ save gid, n_to_left
+
+ integer nzones_block(3)
+
+! create a character variable to hold the string representation of the block
+! number. Note this is set to be 4 characters long (i.e. max = 9999).
+ character*4 fnum_string
+ character*80 filename
+ character*8 str
+
+! create a temporary array to hold the 4 character variable names
+! this will include those defined in definitions.fh and network_common.fh
+ character*4 unklabels(nvar)
+
+! storage for the current date and time
+ character date_string*40
+
+ character(len=4) :: ionam(ionmax), record_label
+
+ integer varid(6+nvar)
+
+ integer global_offset
+
+ character (len=40) :: flash_release
+ double precision unk_buf(1,nxb,nyb,nzb,maxblocks)
+#ifdef TIMERS
+ double precision time_start, time_io
+#endif
+ double precision coord_buf(ndim,lnblocks)
+ double precision bs_buf(ndim,lnblocks)
+ double precision bb_buf(2,ndim,lnblocks)
+
+ integer ncid, cmode, file_info
+ integer(kind=MPI_OFFSET_KIND) starts(5), counts(4), put_size
+ integer gsizes(5), subsizes(5), buftype, reqs(nvar+6), stats(nvar+6)
+
+!-----------------------------------------------------------------------------
+! compute the total number of blocks left of a given processor number
+!-----------------------------------------------------------------------------
+ chk_t(1) = MPI_Wtime()
+
+! use an allgather routine here
+ call MPI_Allgather(lnblocks, 1,MPI_INTEGER, &
+ n_to_left,1,MPI_INTEGER, &
+ MPI_COMM_WORLD,err)
+
+
+! compute the total number of blocks
+ tot_blocks = 0
+
+ do i = 0,NumPEs-1
+ tot_blocks = tot_blocks + n_to_left(i)
+ end do
+
+! compute the number of procssors to the left of a processor
+ do i = NumPEs-1,1,-1
+ n_to_left(i) = n_to_left(i-1)
+ end do
+
+ n_to_left(0) = 0
+ do i = 2,NumPEs-1
+ n_to_left(i) = n_to_left(i) + n_to_left(i-1)
+ end do
+
+
+!-----------------------------------------------------------------------------
+! compute the global id -- this is a single array which stores the
+! neighbor block numbers, the parent, and the children of a given block
+!-----------------------------------------------------------------------------
+ do block_no = 1,lnblocks
+
+ ngid = 0
+
+! loop over the faces and store the neighbors
+ do j = 1,nfaces
+ ngid = ngid + 1
+
+! if the neighbor exists, then store the block number of the neighbor
+! -- take into account the number of blocks below the processor that the
+! neighbor is on, so the block number is global
+ if (neigh(1,j,block_no).gt.0) then
+ gid(ngid,block_no) = neigh(1,j,block_no) + &
+ n_to_left(neigh(2,j,block_no))
+ else
+
+! the neighbor is either a physical boundary or does not exist at that
+! level of refinement
+ gid(ngid,block_no) = neigh(1,j,block_no)
+ end if
+ end do
+
+! store the parent of the current block
+ ngid = ngid + 1
+ if (parent(1,block_no).gt.0) then
+ gid(ngid,block_no) = parent(1,block_no) + &
+ n_to_left(parent(2,block_no))
+ else
+ gid(ngid,block_no) = parent(1,block_no)
+ end if
+
+! store the children of the current block
+ do j = 1,nchild
+ ngid = ngid + 1
+ if (child(1,j,block_no).gt.0) then
+ gid(ngid,block_no) = child(1,j,block_no) + &
+ n_to_left(child(2,j,block_no))
+ else
+ gid(ngid,block_no) = child(1,j,block_no)
+ end if
+ end do
+
+ end do
+
+!-----------------------------------------------------------------------------
+! open the netCDF file
+!-----------------------------------------------------------------------------
+ write (fnum_string, '(i4.4)') filenum
+ filename = trim(basenm) // 'ncmpi_chk_'//fnum_string//'.nc'
+
+ ! set up MPI I/O hints for performance enhancement
+ call MPI_Info_create(file_info, err)
+
+ ! use some ROMIO hints
+ call MPI_Info_set(file_info, 'romio_no_indep_rw', 'true', err)
+
+ cmode = IOR(NF_CLOBBER, NF_64BIT_DATA)
+ err = nfmpi_create(MPI_COMM_WORLD, trim(filename), cmode, &
+ file_info, ncid)
+ if (err .NE. NF_NOERR) call check(err, "nfmpi_create")
+
+ call MPI_Info_free(file_info, err)
+
+ err = nfmpi_get_file_info(ncid, info_used)
+
+!-----------------------------------------------------------------------------
+! store the scalar information -- # of blocks, simulation time, etc
+!-----------------------------------------------------------------------------
+
+! get the current time and date
+ date_string = 'now'
+
+! store the number of zones / block in each direction
+ nzones_block(1) = nxb
+ nzones_block(2) = nyb
+ nzones_block(3) = nzb
+
+! get the names of the fluids being followed
+ call get_mfluid_property ("short name", ionam)
+
+! merge the two variable lists into one for storage
+ unklabels(1:nvar-nuc2) = varnam(:)
+ unklabels(nvar-nuc2+1:nvar) = ionam(:)
+
+#ifdef TIMERS
+ time_start = MPI_Wtime()
+#endif
+
+ call write_header_info(nvar, &
+ ncid, &
+ date_string, &
+ flash_release(), &
+ tot_blocks, &
+ simtime, &
+ nstep, &
+ nzones_block, &
+ unklabels, &
+ varid)
+
+#ifdef TIMERS
+ print *, 'header: MyPE = ', MyPE, ' time = ', &
+ MPI_Wtime() - time_start
+#endif
+
+ global_offset = n_to_left(MyPE)
+
+!-----------------------------------------------------------------------------
+! store the tree information
+!-----------------------------------------------------------------------------
+
+! store the refinement level
+#ifdef TIMERS
+ time_start = MPI_Wtime()
+#endif
+
+ starts(1) = global_offset+1
+ counts(1) = lnblocks
+ if (use_nonblocking_io) then
+ err = nfmpi_iput_vara_int(ncid, varid(1), starts, counts, lrefine, reqs(1))
+ if (err .NE. NF_NOERR) call check(err, "nfmpi_iput_vara_int: lrefine")
+ else
+ err = nfmpi_put_vara_int_all(ncid, varid(1), starts, counts, lrefine)
+ if (err .NE. NF_NOERR) call check(err, "nfmpi_put_vara_int_all: lrefine")
+ endif
+
+#ifdef TIMERS
+ print *, 'lrefine: MyPE = ', MyPE, ' time = ', &
+ MPI_Wtime() - time_start
+#endif
+
+! store the nodetype
+#ifdef TIMERS
+ time_start = MPI_Wtime()
+#endif
+
+ if (use_nonblocking_io) then
+ err = nfmpi_iput_vara_int(ncid, varid(2), starts, counts, nodetype, reqs(2))
+ if (err .NE. NF_NOERR) call check(err, "nfmpi_put_vara_int: nodetype")
+ else
+ err = nfmpi_put_vara_int_all(ncid, varid(2), starts, counts, nodetype)
+ if (err .NE. NF_NOERR) call check(err, "nfmpi_put_vara_int_all: nodetype")
+ endif
+
+#ifdef TIMERS
+ print *, 'nodetype: MyPE = ', MyPE, ' time = ', &
+ MPI_Wtime() - time_start
+#endif
+
+! store the global id
+#ifdef TIMERS
+ time_start = MPI_Wtime()
+#endif
+
+ starts(1) = 1
+ starts(2) = global_offset+1
+ counts(1) = NGID
+ counts(2) = lnblocks
+ if (use_nonblocking_io) then
+ err = nfmpi_iput_vara_int(ncid, varid(3), starts, counts, gid, reqs(3))
+ if (err .NE. NF_NOERR) call check(err, "nfmpi_iput_vara_int: gid")
+ else
+ err = nfmpi_put_vara_int_all(ncid, varid(3), starts, counts, gid)
+ if (err .NE. NF_NOERR) call check(err, "nfmpi_put_vara_int_all: gid")
+ endif
+
+#ifdef TIMERS
+ print *, 'gid: MyPE = ', MyPE, ' time = ', &
+ MPI_Wtime() - time_start
+#endif
+
+!-----------------------------------------------------------------------------
+! store the grid information
+!-----------------------------------------------------------------------------
+
+! store the coordinates
+#ifdef TIMERS
+ time_start = MPI_Wtime()
+#endif
+ coord_buf(1:ndim,1:lnblocks) = coord(1:ndim,1:lnblocks)
+
+ starts(1) = 1
+ starts(2) = global_offset+1
+ counts(1) = NDIM
+ counts(2) = lnblocks
+ if (use_nonblocking_io) then
+ err = nfmpi_iput_vara_double(ncid, varid(4), starts, counts, coord_buf, reqs(4))
+ if (err .NE. NF_NOERR) call check(err, "nfmpi_iput_vara_double: coord")
+ else
+ err = nfmpi_put_vara_double_all(ncid, varid(4), starts, counts, coord_buf)
+ if (err .NE. NF_NOERR) call check(err, "nfmpi_put_vara_double_all: coord")
+ endif
+
+#ifdef TIMERS
+ print *, 'coord: MyPE = ', MyPE, ' time = ', &
+ MPI_Wtime() - time_start
+#endif
+
+! store the block size
+#ifdef TIMERS
+ time_start = MPI_Wtime()
+#endif
+ bs_buf(1:ndim,1:lnblocks) = size(1:ndim,1:lnblocks)
+
+ starts(1) = 1
+ starts(2) = global_offset+1
+ counts(1) = NDIM
+ counts(2) = lnblocks
+ if (use_nonblocking_io) then
+ err = nfmpi_iput_vara_double(ncid, varid(5), starts, counts, bs_buf, reqs(5))
+ if (err .NE. NF_NOERR) call check(err, "nfmpi_iput_vara_double: size")
+ else
+ err = nfmpi_put_vara_double_all(ncid, varid(5), starts, counts, bs_buf)
+ if (err .NE. NF_NOERR) call check(err, "nfmpi_put_vara_double_all: size")
+ endif
+
+#ifdef TIMERS
+ print *, 'size: MyPE = ', MyPE, ' time = ', &
+ MPI_Wtime() - time_start
+#endif
+
+! store the bounding box
+#ifdef TIMERS
+ time_start = MPI_Wtime()
+#endif
+ bb_buf(1:2,1:ndim,1:lnblocks) = bnd_box(1:2,1:ndim,1:lnblocks)
+
+ starts(1) = 1
+ starts(2) = 1
+ starts(3) = global_offset+1
+ counts(1) = 2
+ counts(2) = NDIM
+ counts(3) = lnblocks
+ if (use_nonblocking_io) then
+ err = nfmpi_iput_vara_double(ncid, varid(6), starts, counts, bb_buf, reqs(6))
+ if (err .NE. NF_NOERR) call check(err, "nfmpi_iput_vara_double: bnd_box")
+ else
+ err = nfmpi_put_vara_double_all(ncid, varid(6), starts, counts, bb_buf)
+ if (err .NE. NF_NOERR) call check(err, "nfmpi_put_vara_double_all: bnd_box")
+ endif
+
+#ifdef TIMERS
+ print *, 'bb1: MyPE = ', MyPE, ' time = ', &
+ MPI_Wtime() - time_start
+#endif
+
+ chk_t(2) = MPI_Wtime()
+ chk_t(1) = chk_t(2) - chk_t(1)
+
+!-----------------------------------------------------------------------------
+! store the unknowns -- here we will pass the entire unk array on each
+! processor. The HDF 5 memory space functionality will pick just the
+! interior cells to write to disk.
+!-----------------------------------------------------------------------------
+#ifdef TIMERS
+ time_io = 0.e0
+ time_start = MPI_Wtime()
+#endif
+
+ if (use_nonblocking_io) then
+ ! create a derive data type for buffer unk
+ gsizes(1) = nvar
+ gsizes(2) = iu_bnd - il_bnd + 1
+ gsizes(3) = ju_bnd - jl_bnd + 1
+ gsizes(4) = ku_bnd - kl_bnd + 1
+ gsizes(5) = maxblocks
+ subsizes(1) = 1
+ subsizes(2) = nxb
+ subsizes(3) = nyb
+ subsizes(4) = nzb
+ subsizes(5) = lnblocks
+ starts(1) = 0
+ starts(2) = nguard
+ starts(3) = nguard*k2d
+ starts(4) = nguard*k3d
+ starts(5) = 0
+ call MPI_Type_create_subarray(5, gsizes, subsizes, starts, &
+ MPI_ORDER_FORTRAN, &
+ MPI_DOUBLE_PRECISION, buftype, &
+ err)
+ call MPI_Type_commit(buftype, err)
+ endif
+
+ starts(1) = 1
+ starts(2) = 1
+ starts(3) = 1
+ starts(4) = global_offset+1
+ counts(1) = nxb
+ counts(2) = nyb
+ counts(3) = nzb
+ counts(4) = lnblocks
+
+ do i = 1, nvar
+ record_label = unklabels(i)
+
+ if (.NOT. use_nonblocking_io) then
+ ! when using nonblocking flexible API, we don't even need unk_buf
+ unk_buf(1, 1:nxb, 1:nyb, 1:nzb, :) = &
+ unk(i, nguard+1 : nguard+nxb, &
+ nguard*k2d+1 : nguard*k2d+nyb, &
+ nguard*k3d+1 : nguard*k3d+nzb, :)
+ endif
+
+ if (use_nonblocking_io) then
+ err = nfmpi_iput_vara(ncid, varid(6+i), starts, counts, &
+ unk(i, 1, 1, 1, 1), 1_MPI_OFFSET_KIND, buftype, reqs(i+6))
+ if (err .NE. NF_NOERR) &
+ call check(err, "nfmpi_iput_vara: unknowns")
+ else
+ err = nfmpi_put_vara_double_all(ncid, varid(6+i), starts, counts, unk_buf)
+ if (err .NE. NF_NOERR) &
+ call check(err, "nfmpi_put_vara_double_all: unknowns")
+ endif
+ enddo
+
+ if (use_nonblocking_io) then
+ ! wait for the nonblocking I/O to complete
+ err = nfmpi_wait_all(ncid, nvar+6, reqs, stats)
+ if (err .NE. NF_NOERR) &
+ call check(err, "nfmpi_wait_all: unknowns")
+
+ ! check the status of each nonblocking request
+ do i=1, nvar+6
+ write(str,'(I2)') i
+ if (stats(i) .NE. NF_NOERR) &
+ call check(stats(i), 'In nfmpi_wait_all req '//trim(str))
+ enddo
+ call MPI_Type_free(buftype, err)
+ endif
+
+#ifdef TIMERS
+ time_io = time_io + (MPI_Wtime() - time_start)
+ print *, 'unk: MyPE = ', MyPE, ' time = ', time_io
+#endif
+
+!-----------------------------------------------------------------------------
+! close the file
+!-----------------------------------------------------------------------------
+
+ chk_t(3) = MPI_Wtime()
+ chk_t(2) = chk_t(3) - chk_t(2)
+
+ err = nfmpi_inq_put_size(ncid, put_size)
+ if (err .NE. NF_NOERR) call check(err, "nfmpi_inq_put_size")
+
+ err = nfmpi_close(ncid);
+ if (err .NE. NF_NOERR) call check(err, "nfmpi_close")
+
+ chk_t(3) = MPI_Wtime() - chk_t(3)
+
+ checkpoint_wr_ncmpi_par = put_size
+
+ return
+ end
+
+
+
diff --git a/benchmarks/FLASH-IO/common.fh b/benchmarks/FLASH-IO/common.fh
new file mode 100644
index 0000000..2848d6e
--- /dev/null
+++ b/benchmarks/FLASH-IO/common.fh
@@ -0,0 +1,58 @@
+!******************************************************************************
+
+! File: common.fh
+
+! Purpose: This file is the global common, visible to all modules,
+! containing such things as physical constants, runtime
+! parameters, etc.
+
+ implicit none
+
+
+
+#include "physicaldata.fh"
+
+! Simulation time and timestep
+
+ double precision time, dt
+
+! Simulation step number and beginning step number; my processing
+! element (PE) number, the PE number of the "master" processor,
+! and the total number of PEs
+
+ integer nstep, nbegin, MyPE, MasterPE, NumPEs
+
+ common /floats/ time, dt
+
+ common /intgrs/ nstep, nbegin, MyPE, MasterPE, NumPEs
+
+! add the runtime parameters needed explicitly
+ character*128 basenm
+
+ common /runtime_char/ basenm
+
+!==============================================================================
+
+! Numerical constants
+
+ include 'definitions.fh'
+
+!==============================================================================
+
+! PARAMESH adaptive mesh refinement (AMR) declarations
+
+ include 'tree.fh'
+
+!==============================================================================
+
+! Message-Passing Interface (MPI) library subroutines & constants
+
+ include 'mpif.h'
+
+ integer info_used
+ logical use_nonblocking_io
+
+ double precision chk_t(3), corner_t(3), nocorner_t(3)
+ common /timers/ chk_t, corner_t, nocorner_t, info_used, use_nonblocking_io
+
+
diff --git a/benchmarks/FLASH-IO/configure.in b/benchmarks/FLASH-IO/configure.in
new file mode 100644
index 0000000..49593b4
--- /dev/null
+++ b/benchmarks/FLASH-IO/configure.in
@@ -0,0 +1,225 @@
+AC_REVISION($Id: configure.in 2281 2015-12-26 17:43:34Z wkliao $)dnl
+dnl -*- Mode: shell-script-mode; -*-
+dnl Process this file with GNU autoconf(1) to produce a configure script.
+dnl
+
+AC_PREREQ(2.69)
+AC_INIT([PnetCDF-FLASH-IO], [1.0.0], [parallel-netcdf at mcs.anl.gov])
+
+dnl user defined macro for printing messages for debugging
+_DEBUG=no
+AC_DEFUN([UD_MSG_DEBUG],
+ [if test "x${_DEBUG}" = xyes ; then
+ AC_MSG_NOTICE(DEBUG: $1)
+ fi
+ ]
+)
+
+dnl an option to use a customized rm command
+if test "x${RM}" != x ; then
+ AC_MSG_CHECKING(rm )
+ if ! test -f ${RM} ; then
+ AC_CHECK_PROG([rm_cmd], [${RM}], [yes], [no])
+ if test "x${rm_cmd}" = xyes ; then
+ RM=${RM}
+ fi
+ else
+ RM=${RM}
+ fi
+ AC_MSG_RESULT(using $RM)
+else
+ RM="rm"
+fi
+AC_SUBST(RM)
+
+AC_ARG_ENABLE(echo,
+ [AS_HELP_STRING([--enable-echo],
+ [Turn on strong echoing. @<:@default: no@:>@])],
+ [set -x]
+)
+
+AC_ARG_VAR(MPIF90, MPI Fortran 90 compiler)
+# Check env variable $MPIF90 set by the users
+if test "x${MPIF90}" != x ; then
+ UD_MSG_DEBUG(MPIF90 is set to $MPIF90)
+ if test ! -x "${MPIF90}" ; then
+ UD_MSG_DEBUG(MPIF90 is defined as ${MPIF90} but file does not exist)
+ # MPIF90 may not be an absolute path, check MPIF90 from $PATH
+ MPIF90_ISVALID=""
+ AC_PATH_PROGS(MPIF90_ISVALID, [${MPIF90}])
+ if test "x${MPIF90_ISVALID}" = x ; then
+ AC_MSG_WARN(File ${MPIF90} does not exist)
+ MPIF90=""
+ else
+ MPIF90=$MPIF90_ISVALID
+ fi
+ fi
+fi
+
+dnl if MPIF90 is still empty, search under user's PATH
+CANDIDATE_MPIF90="mpif90 mpixlf90_r mpixlf90 blrts_xlf90 mpxlf90_r mpxlf90 mpxlf95_r mpxlf95 ftn mpiifort mpiifc mpifrtpx"
+if test "x${MPIF90}" = x ; then
+ UD_MSG_DEBUG(find possible MPIF90 under user's PATH)
+ AC_PATH_PROGS([MPIF90], [$CANDIDATE_MPIF90])
+fi
+
+if test "x${MPIF90}" = x ; then
+ AC_MSG_ERROR([
+ -----------------------------------------------------------------------
+ No MPI F90 compiler can be found. FLASH I/O kernel requires an MPI F90
+ compiler. Please specify the location of one with the MPIF90 environment
+ variable
+ -----------------------------------------------------------------------])
+fi
+
+dnl Check if MPIF90 is a valid MPI compiler
+FC=${MPIF90}
+AC_PROG_FC
+
+dnl Check if Fortran compiler is NAG
+dnl According to nagfor manual the command-line option to should version is -V
+dnl
+AC_DEFUN([UD_CHECK_FC_NAG],[
+ AC_CACHE_CHECK([if Fortran compiler is NAG], [ac_cv_fc_compiler_nag],
+ [ac_cv_fc_compiler_nag=no
+ eval $MPIF90 -V </dev/null >& conftest.ver
+ _FC_VENDOR=`head -c 3 conftest.ver`
+ if test "x${_FC_VENDOR}" = xNAG ; then
+ ac_cv_fc_compiler_nag=yes
+ fi
+ ${RM} -f conftest.ver
+ unset _FC_VENDOR
+ ])
+])
+
+dnl Check if the Fortran compiler is an NAG
+UD_CHECK_FC_NAG
+if test "x${ac_cv_fc_compiler_nag}" = xyes ; then
+ NAGf90FPPFLAGS="-DNAGf90Fortran"
+ NAG_FCFLAGS="-mismatch"
+ AC_SUBST(NAGf90FPPFLAGS)
+ AC_SUBST(NAG_FCFLAGS)
+fi
+
+dnl find compile flags for handling files with .F .F90 .f90 extensions
+dnl steal AC_FC_PP_SRCEXT from autoconf V2.69 to make AC_FC_PP_SRCEXT
+AC_FC_PP_SRCEXT([F90])
+AC_SUBST(FCFLAGS_F90)
+
+FPPFLAGS=${FPPFLAGS-}
+AC_SUBST(FPPFLAGS)
+
+dnl compiler command-line define preprocess flag, result in FC_DEFINE
+AC_FC_PP_DEFINE
+
+AC_LANG_PUSH([Fortran])
+AC_FC_SRCEXT([f90])
+AC_SUBST(FCFLAGS_f90)
+
+AC_COMPILE_IFELSE([AC_LANG_CALL([],[MPI_Comm_rank])],
+ [valid_mpif90=yes],[valid_mpif90=no]
+)
+AC_LANG_POP([Fortran])
+if test "x${valid_mpif90}" = xno && test "x${enable_fortran}" = xyes ; then
+ AC_MSG_ERROR([
+ ------------------------------------------------------------
+ Invalid MPI Fortran 90 compiler specified: "${MPIF90}"
+ A working MPI compiler is required. Please specify the
+ location of one either with the MPIF90 environment
+ variable or the --with-mpi configure flag
+ ------------------------------------------------------------])
+fi
+AC_SUBST(MPIF90)
+FC=$MPIF90
+
+AC_FC_MODULE_FLAG
+dnl AC_FC_MODULE_FLAG defines FC_MODINC
+UD_MSG_DEBUG([FC_MODINC=$FC_MODINC])
+
+PNETCDF_INSTALL=""
+AC_ARG_WITH(pnetcdf,
+ [AS_HELP_STRING([--with-pnetcdf=/path/to/implementation],
+ [installation prefix for PnetCDF implementation])],
+ if test "x${withval}" = xyes ; then
+ AC_MSG_ERROR(--with-pnetcdf must be given a pathname)
+ else
+ PNETCDF_INSTALL=${withval}
+ fi
+)
+
+AC_MSG_CHECKING(PnetCDF Fortran library)
+if test "x${PNETCDF_INSTALL}" != x ; then
+ PNETCDF_INC=${PNETCDF_INSTALL}/include
+ PNETCDF_LIB="-L${PNETCDF_INSTALL}/lib"
+fi
+
+have_pnetcdf=no
+
+AC_LANG_PUSH([Fortran])
+FCFLAGS_save=${FCFLAGS}
+LIBS_save=${LIBS}
+if test "x${PNETCDF_INC}" != x ; then
+ FCFLAGS="${FCFLAGS} ${FPPFLAGS} ${FC_MODINC}${PNETCDF_INC}"
+fi
+if test "x${PNETCDF_LIB}" != x ; then
+ LDFLAGS="${LDFLAGS} ${PNETCDF_LIB}"
+fi
+LIBS="-lpnetcdf ${LIBS}"
+AC_LINK_IFELSE([AC_LANG_CALL([], [nfmpi_create])],
+ [AC_MSG_RESULT(works)
+ have_pnetcdf=yes],
+ [AC_MSG_RESULT(failed to compile test program)
+ unset FC
+ ]
+)
+FCFLAGS=${FCFLAGS_save}
+LIBS=${LIBS_save}
+AC_LANG_POP([Fortran])
+AC_SUBST(PNETCDF_INC)
+AC_SUBST(PNETCDF_LIB)
+
+if test "x${have_pnetcdf}" = xno ; then
+ AC_MSG_ERROR([
+ ------------------------------------------------------------
+ The PnetCDF library and header file are required to build
+ the FLASH I/O kernel. Use option
+ --with-pnetcdf=/path/to/implementation
+ to specify the location of PnetCDF build. Stopping ...
+ Check 'config.log' for more information.
+ ------------------------------------------------------------])
+fi
+
+AC_ARG_VAR(TEST_MPIRUN, [MPI run command for running test])
+AC_ARG_VAR(TEST_OUTDIR, [Output file directory for running test])
+if test "x${TEST_MPIRUN}" = x ; then
+ dnl set default to mpiexec
+ TEST_MPIRUN=mpiexec
+fi
+if test "x${TEST_OUTDIR}" = x ; then
+ dnl set default to current directory
+ TEST_OUTDIR=.
+fi
+AC_SUBST(TEST_MPIRUN)
+AC_SUBST(TEST_OUTDIR)
+
+LCOV_LIB=
+AC_SUBST(LCOV_LIB)
+
+AC_CONFIG_FILES(Makefile)
+AC_OUTPUT
+echo "--------------------------------------------------------------------"
+echo \
+"
+ FLASH I/O kernel with PnetCDF I/O method
+
+ Compilers:
+ MPIF90 = ${MPIF90}
+ FFLAGS = ${FFLAGS}
+ FCFLAGS = ${FCFLAGS}
+ F90FLAGS = ${F90FLAGS}
+ LDFLAGS = ${LDFLAGS}
+ LIBS = ${LIBS}
+
+ Now type 'make' to produce executable
+---------------------------------------------------------------------"
+
diff --git a/benchmarks/FLASH-IO/definitions.fh b/benchmarks/FLASH-IO/definitions.fh
new file mode 100644
index 0000000..0d29554
--- /dev/null
+++ b/benchmarks/FLASH-IO/definitions.fh
@@ -0,0 +1,98 @@
+!*******************************************************************************
+
+! File: definitions.h
+! Purpose: Define constants used for array indices, boundary conditions,
+! geometries, etc.
+
+! Pointers for the unk array (AMR fluid variable data structure)
+
+ integer idens, ivelx, ively, ivelz, ipres, iener, itemp, &
+ igame, igamc, ienuc, igpot, inuc_begin
+
+ parameter (idens = 1, &
+ ivelx = 2, &
+ ively = 3, &
+ ivelz = 4, &
+ ipres = 5, &
+ iener = 6, &
+ itemp = 7, &
+ igamc = 8, &
+ igame = 9, &
+ ienuc = 10, &
+ igpot = 11, &
+ inuc_begin = 12)
+
+! labels for the hydro variables, for storage in the HDF output files
+! the abundance labels are defined in the nuclear burner
+ character*4 varnam(nvar-nuc2)
+
+ data varnam /'dens', &
+ 'velx', &
+ 'vely', &
+ 'velz', &
+ 'pres', &
+ 'ener', &
+ 'temp', &
+ 'gamc', &
+ 'game', &
+ 'enuc', &
+ 'gpot'/
+
+!-------------------------------------------------------------------------------
+
+! Pointers for the unk2 array (x coordinate information)
+
+ integer ixznl, ixzn, ixznr, iugridx
+
+ parameter (ixznl = 1, &
+ ixzn = 2, &
+ ixznr = 3, &
+ iugridx = 4)
+
+! Pointers for the unk3 array (y coordinate information)
+
+ integer iyznl, iyzn, iyznr, iugridy
+
+ parameter (iyznl = 1, &
+ iyzn = 2, &
+ iyznr = 3, &
+ iugridy = 4)
+
+! Pointers for the unk4 array (z coordinate information)
+
+ integer izznl, izzn, izznr, iugridz
+
+ parameter (izznl = 1, &
+ izzn = 2, &
+ izznr = 3, &
+ iugridz = 4)
+
+
+! Constants for use by geometry-dependent code
+
+ integer geom_cartesian, geom_planar, geom_cylrad, geom_sphrad, &
+ geom_cylang, geom_sphtheta, geom_sphphi
+
+ parameter (geom_cartesian = 0, &
+ geom_planar = 0, &
+ geom_cylrad = 1, &
+ geom_sphrad = 2, &
+ geom_cylang = 3, &
+ geom_sphtheta = 4, &
+ geom_sphphi = 5)
+
+!-------------------------------------------------------------------------------
+
+! Constants to indicate which sweep we're doing, for
+! dimensionally split hydro solvers
+
+ integer sweep_x, sweep_y, sweep_z, sweep_order_xyz, &
+ sweep_order_zyx, sweep_all
+
+ parameter (sweep_all = 0, &
+ sweep_x = 1, &
+ sweep_y = 2, &
+ sweep_z = 3, &
+ sweep_order_xyz = 1, &
+ sweep_order_zyx = 2)
+
diff --git a/benchmarks/FLASH-IO/flash_benchmark_io.F90 b/benchmarks/FLASH-IO/flash_benchmark_io.F90
new file mode 100644
index 0000000..ce2195d
--- /dev/null
+++ b/benchmarks/FLASH-IO/flash_benchmark_io.F90
@@ -0,0 +1,273 @@
+ program flash_benchmark_io
+!
+! This is a sample program that setups the FLASH data structures and
+! drives the I/O routines. It is intended for benchmarking the I/O
+! performance.
+!
+
+#ifdef NAGf90Fortran
+ USE F90_UNIX_ENV, only : iargc, getarg
+#endif
+
+! the main data structures are contained in common blocks, defined in the
+! include files
+
+#include "common.fh"
+
+#ifndef NAGf90Fortran
+ integer iargc
+#endif
+ integer i, argc, ierr
+ character(len=128) executable
+ logical isArgvRight
+
+ double precision time_io(3), time_begin
+ double precision chk_io, corner_io, nocorner_io
+ double precision checkpoint_wr_ncmpi_par
+ double precision plotfile_ncmpi_par
+
+ integer, parameter :: local_blocks = INT(0.8*maxblocks)
+
+! initialize MPI and get the rank and size
+ call MPI_INIT(ierr)
+ call MPI_Comm_Rank (MPI_Comm_World, MyPE, ierr)
+ call MPI_Comm_Size (MPI_Comm_World, NumPEs, ierr)
+
+ MasterPE = 0
+
+ ! root process reads command-line arguments
+ if (MyPE .EQ. MasterPE) then
+ isArgvRight = .TRUE.
+ argc = IARGC()
+ call getarg(0, executable)
+ if (argc .GT. 1) then
+ print *, &
+ 'Usage: ',trim(executable),' <ouput file base name>'
+ isArgvRight = .FALSE.
+ else
+ if (argc .EQ. 1) then
+ call getarg(1, basenm)
+ else ! default file name prefix
+ basenm = "flash_io_test_"
+ endif
+ endif
+ endif
+
+ ! broadcast if command-line arguments are valid
+ call MPI_Bcast(isArgvRight, 1, MPI_LOGICAL, MasterPE, &
+ MPI_COMM_WORLD, ierr)
+ if (.NOT. isArgvRight) goto 999
+
+ ! broadcast file base name prefix
+ call MPI_Bcast(basenm, 128, MPI_CHARACTER, MasterPE, &
+ MPI_COMM_WORLD, ierr)
+
+! put ~100 blocks on each processor -- make it vary a little, since it does
+! in the real application. This is the maximum that we can fit on Blue
+! Pacific comfortably.
+ lnblocks = local_blocks + mod(MyPE,3)
+
+! just fill the tree stucture with dummy information -- we are just going to
+! dump it out
+ size(:,:) = 0.5e0
+ lrefine(:) = 1
+ nodetype(:) = 1
+ refine(:) = .FALSE.
+ derefine(:) = .FALSE.
+ parent(:,:) = -1
+ child(:,:,:) = -1
+ coord(:,:) = 0.25e0
+ bnd_box(:,:,:) = 0.e0
+ neigh(:,:,:) = -1
+ empty(:) = 0
+
+ ! use nonblocking APIs
+ use_nonblocking_io = .TRUE.
+
+! initialize the unknowns with the index of the variable
+ do i = 1, nvar
+ unk(i,:,:,:,:) = float(i)
+ enddo
+
+!---------------------------------------------------------------------------
+! netCDF checkpoint file
+!---------------------------------------------------------------------------
+ time_begin = MPI_Wtime()
+ chk_io = checkpoint_wr_ncmpi_par(0,0.e0)
+ time_io(1) = MPI_Wtime() - time_begin
+
+!---------------------------------------------------------------------------
+! netCDF plotfile -- no corners
+!---------------------------------------------------------------------------
+ time_begin = MPI_Wtime()
+ nocorner_io = plotfile_ncmpi_par(0,0.e0,.false.)
+ time_io(2) = MPI_Wtime() - time_begin
+
+!---------------------------------------------------------------------------
+! netCDF plotfile -- corners
+!---------------------------------------------------------------------------
+ time_begin = MPI_Wtime()
+ corner_io = plotfile_ncmpi_par(0,0.e0,.true.)
+ time_io(3) = MPI_Wtime() - time_begin
+
+ call report_io_performance(local_blocks, time_io, chk_io, &
+ corner_io, nocorner_io)
+
+ 999 call MPI_Finalize(ierr)
+
+ end program flash_benchmark_io
+
+
+! ---------------------------------------------------------------------------
+! get the file striping information from the MPI info objects
+! ---------------------------------------------------------------------------
+ subroutine get_file_striping(info, striping_factor, striping_unit)
+ implicit none
+ include 'mpif.h'
+ integer, intent(in) :: info
+ integer, intent(out) :: striping_factor
+ integer, intent(out) :: striping_unit
+
+ ! local variables
+ character*(MPI_MAX_INFO_VAL) key, value
+ integer i, nkeys, valuelen, ierr
+ logical flag
+
+ call MPI_Info_get_nkeys(info, nkeys, ierr)
+ do i=0, nkeys-1
+ key(:) = ' '
+ call MPI_Info_get_nthkey(info, i, key, ierr)
+ call MPI_Info_get(info, key, MPI_MAX_INFO_VAL, value, &
+ flag, ierr)
+ call MPI_Info_get_valuelen(info, key, valuelen, flag, &
+ ierr)
+ value(valuelen+1:) = ' '
+ if (key(len_trim(key):len_trim(key)) .EQ. char(0)) &
+ key(len_trim(key):) = ' '
+ if (trim(key) .EQ. 'striping_factor') &
+ read(value, '(i10)') striping_factor
+ if (trim(key) .EQ. 'striping_unit') &
+ read(value, '(i10)') striping_unit
+ enddo
+ end subroutine get_file_striping
+
+
+!---------------------------------------------------------------------------
+! print I/O performance numbers
+!---------------------------------------------------------------------------
+ subroutine report_io_performance(local_blocks, time_io, chk_io, &
+ corner_io, nocorner_io)
+ use pnetcdf
+#include "common.fh"
+
+ integer local_blocks
+ double precision time_io(3)
+ double precision chk_io, corner_io, nocorner_io
+
+ ! local variables
+ integer ierr, striping_factor, striping_unit
+ double precision tmax(3), time_total, io_amount, bw
+ integer(kind=MPI_OFFSET_KIND) malloc_size, sum_size
+
+ call MPI_Reduce(chk_t, tmax, 3, MPI_DOUBLE_PRECISION, MPI_MAX, &
+ MasterPE, MPI_COMM_WORLD, ierr)
+ chk_t(:) = tmax(:)
+
+ call MPI_Reduce(corner_t, tmax, 3, MPI_DOUBLE_PRECISION, MPI_MAX, &
+ MasterPE, MPI_COMM_WORLD, ierr)
+ corner_t(:) = tmax(:)
+
+ call MPI_Reduce(nocorner_t, tmax, 3, MPI_DOUBLE_PRECISION, MPI_MAX, &
+ MasterPE, MPI_COMM_WORLD, ierr)
+ nocorner_t(:) = tmax(:)
+
+ call MPI_Reduce(time_io, tmax, 3, MPI_DOUBLE_PRECISION, MPI_MAX, &
+ MasterPE, MPI_COMM_WORLD, ierr)
+
+ call MPI_Reduce(chk_io, bw, 1, MPI_DOUBLE_PRECISION, MPI_SUM, &
+ MasterPE, MPI_COMM_WORLD, ierr)
+ chk_io = bw
+ call MPI_Reduce(nocorner_io, bw, 1, MPI_DOUBLE_PRECISION, MPI_SUM, &
+ MasterPE, MPI_COMM_WORLD, ierr)
+ nocorner_io = bw
+ call MPI_Reduce(corner_io, bw, 1, MPI_DOUBLE_PRECISION, MPI_SUM, &
+ MasterPE, MPI_COMM_WORLD, ierr)
+ corner_io = bw
+
+ if (MyPE .EQ. MasterPE) then
+
+ striping_factor = 0
+ striping_unit = 0
+ call get_file_striping(info_used, striping_factor, striping_unit)
+
+ time_total = tmax(1) + tmax(2) + tmax(3)
+ io_amount = chk_io + nocorner_io + corner_io
+ bw = io_amount / 1048576.0
+ io_amount = bw
+ bw = bw / time_total
+
+ 1001 format(A,I13)
+ 1002 format(A,I13,A)
+ 1003 format(A,F16.2,A)
+ 1004 format(' -------------------------------------------------------')
+ 1005 format(' nproc array size exec (sec) bandwidth (MiB/s)')
+ 1006 format(I5, 3x, i3,' x ',i3,' x ',i3, 3x, F7.2 , 2x,F10.2 /)
+ 1007 format(A,A)
+
+ print 1001,' number of guards : ',nguard
+ print 1001,' number of blocks : ',local_blocks
+ print 1001,' number of variables : ',nvar
+ print 1003,' checkpoint time : ',tmax(1), ' sec'
+ print 1003,' max header : ',chk_t(1),' sec'
+ print 1003,' max unknown : ',chk_t(2),' sec'
+ print 1003,' max close : ',chk_t(3),' sec'
+ print 1003,' I/O amount : ',chk_io/1048576, ' MiB'
+ print 1003,' plot no corner : ',tmax(2), ' sec'
+ print 1003,' max header : ',nocorner_t(1),' sec'
+ print 1003,' max unknown : ',nocorner_t(2),' sec'
+ print 1003,' max close : ',nocorner_t(3),' sec'
+ print 1003,' I/O amount : ',nocorner_io/1048576, ' MiB'
+ print 1003,' plot corner : ',tmax(3), ' sec'
+ print 1003,' max header : ',corner_t(1),' sec'
+ print 1003,' max unknown : ',corner_t(2),' sec'
+ print 1003,' max close : ',corner_t(3),' sec'
+ print 1003,' I/O amount : ',corner_io/1048576, ' MiB'
+ print 1004
+ print 1007,' File base name : ', trim(basenm)
+ if (striping_factor .GT. 0) then
+ print 1001,' file striping count : ',striping_factor
+ print 1002,' file striping size : ',striping_unit, ' bytes'
+ endif
+ print 1003,' Total I/O amount : ',io_amount,' MiB'
+ print 1004
+ print 1005
+ print 1006, NumPEs, nxb, nyb, nzb, time_total, bw
+ print *
+
+ endif
+ call MPI_Info_free(info_used, ierr)
+
+ ! print info about PnetCDF internal malloc usage
+ ierr = nfmpi_inq_malloc_max_size(malloc_size)
+ if (ierr .EQ. NF_NOERR) then
+ call MPI_Reduce(malloc_size, sum_size, 1, MPI_OFFSET, MPI_SUM, &
+ MasterPE, MPI_COMM_WORLD, ierr)
+ if (MyPE .EQ. MasterPE) &
+ print 1002, &
+ 'maximum heap memory allocted by PnetCDF internally is', &
+ sum_size/1048576, ' MiB'
+
+ ierr = nfmpi_inq_malloc_size(malloc_size)
+ call MPI_Reduce(malloc_size, sum_size, 1, MPI_OFFSET, MPI_SUM, &
+ MasterPE, MPI_COMM_WORLD, ierr)
+ if (MyPE .EQ. MasterPE .AND. sum_size .GT. 0_MPI_OFFSET_KIND) &
+ print 1002, &
+ 'heap memory allocated by PnetCDF internally has ', &
+ sum_size/1048576, ' MiB yet to be freed'
+ endif
+
+ end subroutine report_io_performance
+
+
+
+
diff --git a/benchmarks/FLASH-IO/flash_release.F90 b/benchmarks/FLASH-IO/flash_release.F90
new file mode 100644
index 0000000..62937d9
--- /dev/null
+++ b/benchmarks/FLASH-IO/flash_release.F90
@@ -0,0 +1,10 @@
+ function flash_release()
+
+ implicit none
+
+ character (len = 40) :: flash_release
+
+ flash_release = 'FLASH I/O bench Parallel-Netcdf'
+
+ return
+ end
diff --git a/benchmarks/FLASH-IO/get_mfluid_property.F90 b/benchmarks/FLASH-IO/get_mfluid_property.F90
new file mode 100644
index 0000000..dfa6c3b
--- /dev/null
+++ b/benchmarks/FLASH-IO/get_mfluid_property.F90
@@ -0,0 +1,34 @@
+subroutine get_mfluid_property(property, value)
+
+! stub function to fill the need for get_mfluid_property from the
+! FLASH I/O routines that are used in this benchmark. All they need
+! is a routine to return the names of the isotopes, so do that here
+
+#include "common.fh"
+
+ character (len=*) :: property
+ character (len=4) :: value(ionmax)
+
+ if (ionmax == 2) then
+ value(1) = "f1"
+ value(2) = "f2"
+ else if (ionmax == 13) then
+ value(1) = "f1"
+ value(2) = "f2"
+ value(3) = "f3"
+ value(4) = "f4"
+ value(5) = "f5"
+ value(6) = "f6"
+ value(7) = "f7"
+ value(8) = "f8"
+ value(9) = "f9"
+ value(10) = "f10"
+ value(11) = "f11"
+ value(12) = "f12"
+ value(13) = "f13"
+ endif
+
+ return
+end subroutine get_mfluid_property
+
+
diff --git a/benchmarks/FLASH-IO/numfluids.fh b/benchmarks/FLASH-IO/numfluids.fh
new file mode 100644
index 0000000..2fc7709
--- /dev/null
+++ b/benchmarks/FLASH-IO/numfluids.fh
@@ -0,0 +1,3 @@
+! Number of fluids to track.
+
+ integer, parameter :: ionmax = IONMAX
diff --git a/benchmarks/FLASH-IO/physicaldata.fh b/benchmarks/FLASH-IO/physicaldata.fh
new file mode 100644
index 0000000..6055812
--- /dev/null
+++ b/benchmarks/FLASH-IO/physicaldata.fh
@@ -0,0 +1,196 @@
+!------------------------------------------------------------------------------
+! physicaldata.fh
+!------------------------------------------------------------------------------
+
+
+
+
+!Pre-Processor Control
+
+ integer k1d
+ parameter(k1d=1)
+
+!-----------------------------------------------------------------
+! physicaldata.fh
+
+
+! set physical dimension of model and number of edges on each grid block
+ integer ndim,nbedges
+#if N_DIM == 3
+ parameter(ndim=3)
+#endif
+#if N_DIM == 2
+ parameter(ndim=2)
+#endif
+#if N_DIM == 1
+ parameter(ndim=1)
+#endif
+
+! l2p5d needs to be declared not matter what the dimension of the
+! problem is set to !
+ integer l2p5d
+ parameter(l2p5d=0) !<<< USER EDIT
+ ! 1 if 2.5D
+ ! 0 if 2 or 3D
+
+ parameter(nbedges=ndim*2**(ndim-1))
+
+
+
+! an increment variable for the z dimension to enable the same code to
+! work for 2D or 3D models.
+ integer k3d
+ parameter(k3d=(ndim-1)/2)
+
+ integer k2d
+ parameter(k2d=ndim/2)
+
+
+! set size of grid blocks
+! The spatial relationship between grid points in parents
+! and their children is subtly different depending on whether
+! the block dimensions (ie nxb,nyb,nzb) are even or odd. This has
+! significant consequences when defining interpolation within
+! restriction or prolongation operations.
+
+ integer nxb,nyb,nzb,maxdim
+
+ parameter(nxb=16) !<<< USER EDIT
+
+#if N_DIM >= 2
+ parameter(nyb=16) !<<< USER EDIT
+#else
+ parameter(nyb=1)
+#endif
+
+#if N_DIM == 3
+ parameter(nzb=16) !<<< USER EDIT
+#else
+ parameter(nzb=1)
+#endif
+
+ parameter(maxdim=max(nxb,nyb,nzb))
+
+
+! these guard cell offsets are required to accomodate differences
+! in cases when block dimensions are odd or even
+ integer gc_off_x,gc_off_y,gc_off_z
+ parameter(gc_off_x=mod(nxb,2))
+ parameter(gc_off_y=mod(nyb,2))
+ parameter(gc_off_z=mod(nzb,2))
+
+! set the maximum number of blocks per processor
+ integer maxblocks
+#ifdef MAXBLOCKS
+ parameter (maxblocks = MAXBLOCKS)
+#else
+#if N_DIM == 3
+ parameter (maxblocks = 200) !<<< USER EDIT
+#else /* N_DIM < 3 */
+ parameter (maxblocks = 500) !<<< USER EDIT
+#endif /*N_DIM*/
+#endif /*MAXBLOCKS*/
+
+
+
+
+!..this include file is very important at this location, as it sets a
+!..parameter (ionmax) that determines the array sizes and do-loop limits
+!..of the mesh, hydro, eos and burn modules. it touches just about everything.
+
+#include "numfluids.fh"
+ integer nuc2
+ parameter (nuc2 = ionmax)
+
+
+! set number of unknowns associated with each grid cell
+ integer nvar
+ parameter(nvar=nuc2+11) !<<< USER EDIT
+ integer nvar2
+ parameter(nvar2=6)
+ integer nvarsm
+ parameter (nvarsm=2)
+
+! set the number of guard cell layers at each boundary
+ integer nguard
+ parameter(nguard=4) !<<< USER EDIT
+
+
+! common block storing the solution for cell-centered quantities.
+! unksm stores copies of global variables which DO NOT need guard cells
+! AND do not need to be saved from one timestep to the next !!!
+
+ integer il_bnd,iu_bnd
+ integer jl_bnd,ju_bnd
+ integer kl_bnd,ku_bnd
+ parameter(il_bnd=1, iu_bnd=nxb+2*nguard)
+ parameter(jl_bnd=1, ju_bnd=nyb+2*nguard*k2d)
+ parameter(kl_bnd=1, ku_bnd=nzb+2*nguard*k3d)
+ integer nxlo,nylo,nzlo,nxhi,nyhi,nzhi
+ parameter (nxlo=nguard+1,nylo=nguard*k2d+1,nzlo=nguard*k3d+1)
+ parameter (nxhi=nguard+nxb)
+ parameter (nyhi=nguard*k2d+nyb)
+ parameter (nzhi=nguard*k3d+nzb)
+ common/solution_cc/ &
+ unk(nvar,il_bnd:iu_bnd,jl_bnd:ju_bnd,kl_bnd:ku_bnd,maxblocks), &
+ unk2(nvar2,il_bnd:iu_bnd,maxblocks), &
+ unk3(nvar2,jl_bnd:ju_bnd,maxblocks), &
+ unk4(nvar2,kl_bnd:ku_bnd,maxblocks), &
+ unksm(nvarsm,nxlo:nxhi,nylo:nyhi,nzlo:nzhi,maxblocks)
+ double precision unk,unk2,unk3,unk4,unksm
+
+
+
+! The number of data words needed on a cell face is set by nfacevar.
+!
+
+ integer nfacevar
+! 2 added to store strong fields at faces for all components of B
+ parameter(nfacevar=0) !<<< USER EDIT
+
+ integer nbndvar
+ parameter(nbndvar=max(1,nfacevar))
+
+ integer maxblocksf
+ parameter(maxblocksf= 1+(maxblocks-1)*min(1,nfacevar) )
+
+
+! set data length of grid blocks
+ integer len_block
+ parameter(len_block=iu_bnd*ju_bnd*ku_bnd*nvar)
+
+
+! common block for timestep control
+ integer maxlevels
+ parameter(maxlevels=20)
+ common/timecntl/ time_loc(maxblocks),dtlevel(maxlevels),ldtcomplete(maxblocks)
+ double precision time_loc,dtlevel
+ logical ldtcomplete
+
+
+
+! To average fluxes set red_f = .25.
+! To sum fluxes set red_f = 1.0.
+
+! changed -- 2-24-00
+! we are now converting the flux densities to fluxes before the call to
+! amr_flux_conserve. This is to get the proper geometry factors included
+! in non-cartesian cases. The fluxes are converted back after the call.
+!
+! red_f is set according to dimension, to sum instead of average
+ double precision red_f
+! parameter(red_f = 0.25)
+
+#if N_DIM == 1
+ parameter (red_f = 0.25)
+#elif N_DIM == 2
+ parameter (red_f = 0.5)
+#elif N_DIM == 3
+ parameter (red_f = 1.0)
+#endif
+
+!-----------------------------------------------------------------
+! include header file defining data structure on cell faces
+#include "block_boundary_data.fh"
+
+!-----------------------------------------------------------------
diff --git a/benchmarks/FLASH-IO/plotfile_ncmpi_parallel.F90 b/benchmarks/FLASH-IO/plotfile_ncmpi_parallel.F90
new file mode 100644
index 0000000..2b210d7
--- /dev/null
+++ b/benchmarks/FLASH-IO/plotfile_ncmpi_parallel.F90
@@ -0,0 +1,698 @@
+#define MDIM 3
+! 3-d problem */
+#if N_DIM == 3
+#define NDIM 3
+#define NGID 15
+#define ik2d 1
+#define ik3d 1
+! 2-d problem */
+#elif N_DIM == 2
+#define NDIM 2
+#define NGID 9
+#define ik2d 1
+#define ik3d 0
+! 1-d problem */
+#else
+#define NDIM 1
+#define NGID 5
+#define ik2d 0
+#define ik3d 0
+#endif
+
+
+ subroutine write_header_info_sp(nvar_out, ncid, file_creation_time, &
+ flash_version, total_blocks, time, &
+ nsteps, nzones_block, unk_labels, &
+ varid)
+ use mpi
+ use pnetcdf
+ implicit none
+
+ integer nvar_out ! num vars to store
+ integer ncid ! file handle
+ character(len=*) file_creation_time ! time and date stamp
+ character(len=*) flash_version ! FLASH version num
+ integer total_blocks ! total # of blocks
+ real time ! simulation time
+ integer nsteps ! total # of timestep
+ integer nzones_block(3) ! nxb, nyb, nzb
+ character(len=4) unk_labels(*) ! unknown labels
+ integer varid(*) ! output: var ids
+
+ ! local variables
+ integer i, k, err
+ integer dim_tot_blocks, dim_nxb, dim_nyb, dim_nzb
+ integer dim_NGID, dim_NDIM, dim_2
+ integer dimids(4)
+ character(len=5) record_label
+ integer(kind=MPI_OFFSET_KIND) i8NDIM, i8NGID, i8total_blocks
+ integer(kind=MPI_OFFSET_KIND) i8nzones_block(3), string_size
+ integer atotal_blocks(1), ansteps(1)
+ double precision atime(1)
+
+ i8NDIM = NDIM
+ i8NGID = NGID
+ i8total_blocks = total_blocks
+ i8nzones_block(:) = nzones_block(:)
+ atotal_blocks(1) = total_blocks
+ ansteps(1) = nsteps
+
+ ! to avoid inconsistent header metadata warning from PnetCDF
+ atime(1) = time
+ call MPI_Bcast(atime, 1, MPI_DOUBLE_PRECISION, 0, MPI_COMM_WORLD, err)
+
+ err = nfmpi_def_dim(ncid, "dim_tot_blocks", i8total_blocks, dim_tot_blocks)
+ if (err .NE. NF_NOERR) call check(err, "nfmpi_def_dim: dim_tot_blocks")
+ err = nfmpi_def_dim(ncid, "dim_nxb", i8nzones_block(1), dim_nxb)
+ if (err .NE. NF_NOERR) call check(err, "nfmpi_def_dim: dim_nxb")
+ err = nfmpi_def_dim(ncid, "dim_nyb", i8nzones_block(2), dim_nyb)
+ if (err .NE. NF_NOERR) call check(err, "nfmpi_def_dim: dim_nyb")
+ err = nfmpi_def_dim(ncid, "dim_nzb", i8nzones_block(3), dim_nzb)
+ if (err .NE. NF_NOERR) call check(err, "nfmpi_def_dim: dim_nzb")
+ err = nfmpi_def_dim(ncid, "dim_NGID", i8NGID, dim_NGID)
+ if (err .NE. NF_NOERR) call check(err, "nfmpi_def_dim: dim_NGID")
+ err = nfmpi_def_dim(ncid, "dim_NDIM", i8NDIM, dim_NDIM)
+ if (err .NE. NF_NOERR) call check(err, "nfmpi_def_dim: dim_NDIM")
+ err = nfmpi_def_dim(ncid, "dim_2", 2_MPI_OFFSET_KIND, dim_2)
+ if (err .NE. NF_NOERR) call check(err, "nfmpi_def_dim: dim_2")
+
+ dimids(1) = dim_tot_blocks
+
+ ! define var for refinement level
+ err = nfmpi_def_var(ncid, "lrefine", NF_INT, 1, dimids, varid(1))
+ if (err .NE. NF_NOERR) call check(err, "nfmpi_def_var: lrefine")
+
+ ! define var for nodetype
+ err = nfmpi_def_var(ncid, "nodetype", NF_INT, 1, dimids, varid(2))
+ if (err .NE. NF_NOERR) call check(err, "nfmpi_def_var: nodetype")
+
+ ! define var for global id
+ dimids(1) = dim_NGID
+ dimids(2) = dim_tot_blocks
+ err = nfmpi_def_var(ncid, "gid", NF_INT, 2, dimids, varid(3))
+ if (err .NE. NF_NOERR) call check(err, "nfmpi_def_var: grid")
+
+ ! define var for grid coordinates
+ dimids(1) = dim_NDIM
+ dimids(2) = dim_tot_blocks
+ err = nfmpi_def_var(ncid, "coordinates", NF_FLOAT, 2, dimids, varid(4))
+ if (err .NE. NF_NOERR) call check(err, "nfmpi_def_var: coordinates")
+
+ ! define var for grid block size
+ dimids(1) = dim_NDIM
+ dimids(2) = dim_tot_blocks
+ err = nfmpi_def_var(ncid, "blocksize", NF_FLOAT, 2, dimids, varid(5))
+ if (err .NE. NF_NOERR) call check(err, "nfmpi_def_var: blocksize")
+
+ ! define var for grid bounding box
+ dimids(1) = dim_2
+ dimids(2) = dim_NDIM
+ dimids(3) = dim_tot_blocks
+ err = nfmpi_def_var(ncid, "bndbox", NF_FLOAT, 3, dimids, varid(6))
+ if (err .NE. NF_NOERR) call check(err, "nfmpi_def_var: bndbox")
+
+ ! define var for unknown array
+ dimids(1) = dim_nxb
+ dimids(2) = dim_nyb
+ dimids(3) = dim_nzb
+ dimids(4) = dim_tot_blocks
+
+ do i=1, nvar_out
+ record_label = unk_labels(i)
+ do k=1, 4
+ if (record_label(k:k) .EQ. ' ') record_label(k:k) = '_'
+ enddo
+ record_label(5:5) = char(0)
+ err = nfmpi_def_var(ncid, record_label, NF_FLOAT, 4, dimids, varid(i+6))
+ if (err .NE. NF_NOERR) call check(err, "nfmpi_def_var: record_label")
+ enddo
+
+ string_size = LEN_TRIM(file_creation_time)
+ err = nfmpi_put_att_text(ncid, NF_GLOBAL, "file_creation_time", string_size, file_creation_time)
+ if (err .NE. NF_NOERR) call check(err, "nfmpi_put_att_text: file_creation_time")
+ string_size = LEN_TRIM(flash_version)
+ err = nfmpi_put_att_text(ncid, NF_GLOBAL, "flash_version", string_size, flash_version)
+ if (err .NE. NF_NOERR) call check(err, "nfmpi_put_att_text: flash_version")
+ err = nfmpi_put_att_int(ncid, NF_GLOBAL, "total_blocks", NF_INT, 1_MPI_OFFSET_KIND, atotal_blocks)
+ if (err .NE. NF_NOERR) call check(err, "nfmpi_put_att_int: total_blocks")
+ err = nfmpi_put_att_int(ncid, NF_GLOBAL, "nsteps", NF_INT, 1_MPI_OFFSET_KIND, ansteps)
+ if (err .NE. NF_NOERR) call check(err, "nfmpi_put_att_int: nsteps")
+ err = nfmpi_put_att_int(ncid, NF_GLOBAL, "nxb", NF_INT, 1_MPI_OFFSET_KIND, nzones_block(1))
+ if (err .NE. NF_NOERR) call check(err, "nfmpi_put_att_int: nxb")
+ err = nfmpi_put_att_int(ncid, NF_GLOBAL, "nyb", NF_INT, 1_MPI_OFFSET_KIND, nzones_block(2))
+ if (err .NE. NF_NOERR) call check(err, "nfmpi_put_att_int: nyb")
+ err = nfmpi_put_att_int(ncid, NF_GLOBAL, "nzb", NF_INT, 1_MPI_OFFSET_KIND, nzones_block(3))
+ if (err .NE. NF_NOERR) call check(err, "nfmpi_put_att_int: nzb")
+ err = nfmpi_put_att_double(ncid, NF_GLOBAL, "time", NF_DOUBLE, 1_MPI_OFFSET_KIND, atime)
+ if (err .NE. NF_NOERR) call check(err, "nfmpi_put_att_double: time")
+
+ err = nfmpi_enddef(ncid)
+ if (err .NE. NF_NOERR) call check(err, "nfmpi_enddef")
+ end subroutine write_header_info_sp
+
+!----------------------------------------------------------------------------
+! subroutine plotfile
+!----------------------------------------------------------------------------
+
+ double precision function plotfile_ncmpi_par(filenum, simtime, corners)
+!
+! plotfile using parallel i/o using Parallel netCDF
+!
+! MZ -- 4-29-00
+! Jianwei -- 11/15/02
+!
+! This version of the plotfile routine is based on the Parallel netCDF
+! checkpoint. The IO is done in parallel -- no copying of the data to
+! a single processor to do the writing is performed.
+!
+! This is the SINGLE PRECISION version of the plotfile -- temporary
+! storage is used to recast a variable (for every zone/block) into
+! single precision before passing it onto the SP version of the C netCDF
+! write routines.
+!
+! The data for all blocks is recast and written together. This makes the
+! amount of data that is written very large, which should perform better
+! on the parallel filesystems. The overhead for storing an entire
+! variable (with corners) is small, <~ 1%.
+!
+! Parallel netCDF uses MPI-IO (via ROMIO) to support parallel IO. Each
+! processor must open the file, define the dataspaces for each netCDF variable.
+!
+! A single record for each of the PARAMESH data structures is created. A
+! processor only writes to a subset of this record. Each record has a
+! dimension with length = tot_blocks. The offset of a processor into this
+! dimension is computed by looking at the total number of blocks that are
+! below the current processor.
+!
+! In this version of the plotfile, each variable is given its own
+! record -- this makes it easier to change the variable list in the
+! future without disturbing the format of the file.
+!
+! The include file -- ncmpi_flash.h is used for the C routines and mirrors
+! the necessary data from physicaldata.fh
+!
+! written for netCDF 3.0
+!
+!---------------------------------------------------------------------------
+
+ use pnetcdf
+
+#include "common.fh"
+
+ integer filenum
+ real simtime
+
+ integer block_no
+ integer i, j, k, ivar, i_store, j_store, k_store
+ integer ngid
+ integer err
+
+ integer n_to_left(0:16383) ! must extend from 0 to NumPEs-1
+
+! 2-20-00 -- we don't need to allocate more space than necessary
+! integer gid(mfaces+1+mchild,maxblocks_tr)
+ integer gid(nfaces+1+nchild,maxblocks_tr)
+
+ integer tot_blocks
+
+ save gid, n_to_left
+
+ integer nzones_block(3)
+
+! create a character variable to hold the string representation of the block
+! number. Note this is set to be 4 characters long (i.e. max = 9999).
+ character*4 fnum_string
+ character*80 filename
+ character*8 str
+
+! set the number of variables we are going to write out
+ integer, parameter :: num_out = 4
+
+! create a temporary array to hold the 4 character variable names
+! this will include those defined in definitions.fh and network_common.fh
+ character*4 unklabels(nvar), sunklabels(num_out)
+
+! storage for the current date and time
+ character date_string*40
+
+ character(len=4) :: ionam(ionmax), record_label
+
+ integer varid(6+num_out)
+
+ integer global_offset
+
+
+! hold pointers to the location in unk of the variables we are writing out
+ integer iout(num_out)
+
+! allocate storage to hold a single variable information
+! this should only be a small memory overhead
+ integer, parameter :: single = SELECTED_REAL_KIND(p=6)
+ real (kind=single) :: unkt_crn(1,nxb+1,nyb+k2d,nzb+k3d,maxblocks)
+ real (kind=single) :: unkt(1,nxb,nyb,nzb,maxblocks)
+
+! allocate storage to hold the coordinate information and bounding box
+! information
+ real (kind=single) :: coord_single(mdim,maxblocks_tr)
+ real (kind=single) :: blk_sz_single(mdim,maxblocks_tr)
+ real (kind=single) :: bnd_single(2,mdim,maxblocks_tr)
+ real (kind=single) :: sp_var1, sp_var2
+
+ integer, parameter :: release_len = 40
+ character (len=release_len) :: flash_release
+
+ logical corners
+
+ integer ncid, cmode, file_info, reqs(num_out+6), stats(num_out+6)
+ integer(kind=MPI_OFFSET_KIND) starts(4), counts(4), put_size, buf_size
+
+ if (corners) then
+ corner_t(1) = MPI_Wtime()
+ else
+ nocorner_t(1) = MPI_Wtime()
+ endif
+
+!-----------------------------------------------------------------------------
+! set the variables we are going to store
+!-----------------------------------------------------------------------------
+ iout(1) = idens
+ iout(2) = itemp
+ iout(3) = ipres
+
+! store the first abundance
+ iout(4) = inuc_begin
+
+
+!-----------------------------------------------------------------------------
+! compute the total number of blocks left of a given processor number
+!-----------------------------------------------------------------------------
+
+! use an allgather routine here to get the number of blocks on each proc.
+ call MPI_Allgather(lnblocks, 1,MPI_INTEGER, &
+ n_to_left,1,MPI_INTEGER, &
+ MPI_COMM_WORLD,err)
+
+! compute the total number of blocks
+ tot_blocks = 0
+
+ do i = 0,NumPEs-1
+ tot_blocks = tot_blocks + n_to_left(i)
+ end do
+
+! compute the number of procssors to the left of a processor
+ do i = NumPEs-1,1,-1
+ n_to_left(i) = n_to_left(i-1)
+ end do
+
+ n_to_left(0) = 0
+ do i = 2,NumPEs-1
+ n_to_left(i) = n_to_left(i) + n_to_left(i-1)
+ end do
+
+
+!-----------------------------------------------------------------------------
+! compute the global id -- this is a single array which stores the
+! neighbor block numbers, the parent, and the children of a given block
+!-----------------------------------------------------------------------------
+ do block_no = 1,lnblocks
+
+ ngid = 0
+
+! loop over the faces and store the neighbors
+ do j = 1,nfaces
+ ngid = ngid + 1
+
+! if the neighbor exists, then store the block number of the neighbor
+! -- take into account the number of blocks below the processor that the
+! neighbor is on, so the block number is global
+ if (neigh(1,j,block_no).gt.0) then
+ gid(ngid,block_no) = neigh(1,j,block_no) + &
+ n_to_left(neigh(2,j,block_no))
+ else
+
+! the neighbor is either a physical boundary or does not exist at that
+! level of refinement
+ gid(ngid,block_no) = neigh(1,j,block_no)
+ end if
+ end do
+
+! store the parent of the current block
+ ngid = ngid + 1
+ if (parent(1,block_no).gt.0) then
+ gid(ngid,block_no) = parent(1,block_no) + &
+ n_to_left(parent(2,block_no))
+ else
+ gid(ngid,block_no) = parent(1,block_no)
+ end if
+
+! store the children of the current block
+ do j = 1,nchild
+ ngid = ngid + 1
+ if (child(1,j,block_no).gt.0) then
+ gid(ngid,block_no) = child(1,j,block_no) + &
+ n_to_left(child(2,j,block_no))
+ else
+ gid(ngid,block_no) = child(1,j,block_no)
+ end if
+ end do
+
+ end do
+
+
+!-----------------------------------------------------------------------------
+! open the netCDF file
+!-----------------------------------------------------------------------------
+ write (fnum_string, '(i4.4)') filenum
+
+ if (corners) then
+ filename = trim(basenm)//'ncmpi_plt_crn_'//fnum_string//'.nc'
+ else
+ filename = trim(basenm)//'ncmpi_plt_cnt_'//fnum_string//'.nc'
+ endif
+
+ ! set up MPI I/O hints for performance enhancement
+ call MPI_Info_create(file_info, err)
+
+ ! use some ROMIO hints
+ call MPI_Info_set(file_info, 'romio_no_indep_rw', 'true', err)
+
+ cmode = IOR(NF_CLOBBER, NF_64BIT_DATA)
+ err = nfmpi_create(MPI_COMM_WORLD, trim(filename), cmode, &
+ file_info, ncid)
+ if (err .NE. NF_NOERR) call check(err, "nfmpi_create")
+
+ call MPI_Info_free(file_info, err)
+
+!-----------------------------------------------------------------------------
+! store the scalar information -- # of blocks, simulation time, etc
+!-----------------------------------------------------------------------------
+ date_string = 'now'
+
+! store the number of zones / block in each direction
+ if (corners) then
+ nzones_block(1) = nxb+1
+ nzones_block(2) = nyb+k2d
+ nzones_block(3) = nzb+k3d
+ else
+ nzones_block(1) = nxb
+ nzones_block(2) = nyb
+ nzones_block(3) = nzb
+ endif
+
+! get the names of the fluids being followed
+ call get_mfluid_property ("short name", ionam)
+
+! merge the two variable lists into one for storage
+ unklabels(1:nvar-ionmax) = varnam(:)
+ unklabels(nvar-ionmax+1:nvar) = ionam(:)
+
+! get the subset of the variable labels, corresponding to what we are storing
+ do i = 1, num_out
+ sunklabels(i) = unklabels(iout(i))
+ enddo
+
+ sp_var1 = real(simtime, kind = single)
+ sp_var2 = real(dt, kind = single)
+
+ call write_header_info_sp(num_out, &
+ ncid, &
+ date_string, &
+ flash_release(), &
+ tot_blocks, &
+ sp_var1, &
+ nstep, &
+ nzones_block, &
+ sunklabels, &
+ varid)
+
+ global_offset = n_to_left(MyPE)
+!-----------------------------------------------------------------------------
+! store the tree information
+!-----------------------------------------------------------------------------
+
+! store the refinement level
+ starts(1) = global_offset+1
+ counts(1) = lnblocks
+ if (use_nonblocking_io) then
+ err = nfmpi_iput_vara_int(ncid, varid(1), starts, counts, lrefine, reqs(1))
+ if (err .NE. NF_NOERR) call check(err, "nfmpi_iput_vara_int: lrefine sp")
+ else
+ err = nfmpi_put_vara_int_all(ncid, varid(1), starts, counts, lrefine)
+ if (err .NE. NF_NOERR) call check(err, "nfmpi_put_vara_int_all: lrefine sp")
+ endif
+
+! store the nodetype
+ if (use_nonblocking_io) then
+ err = nfmpi_iput_vara_int(ncid, varid(2), starts, counts, nodetype, reqs(2))
+ if (err .NE. NF_NOERR) call check(err, "nfmpi_iput_vara_int: nodetype sp")
+ else
+ err = nfmpi_put_vara_int_all(ncid, varid(2), starts, counts, nodetype)
+ if (err .NE. NF_NOERR) call check(err, "nfmpi_put_vara_int_all: nodetype sp")
+ endif
+
+! store the global id
+ starts(1) = 1
+ starts(2) = global_offset+1
+ counts(1) = NGID
+ counts(2) = lnblocks
+ if (use_nonblocking_io) then
+ err = nfmpi_iput_vara_int(ncid, varid(3), starts, counts, gid, reqs(3))
+ if (err .NE. NF_NOERR) call check(err, "nfmpi_iput_vara_int: gid sp")
+ else
+ err = nfmpi_put_vara_int_all(ncid, varid(3), starts, counts, gid)
+ if (err .NE. NF_NOERR) call check(err, "nfmpi_put_vara_int_all: gid sp")
+ endif
+
+!-----------------------------------------------------------------------------
+! store the grid information
+!-----------------------------------------------------------------------------
+
+! store the coordinates
+ do block_no = 1, lnblocks
+ coord_single(:,block_no) = real(coord(:,block_no), kind = single)
+ enddo
+ starts(1) = 1
+ starts(2) = global_offset+1
+ counts(1) = NDIM
+ counts(2) = lnblocks
+ if (use_nonblocking_io) then
+ err = nfmpi_iput_vara_real(ncid, varid(4), starts, counts, coord_single, reqs(4))
+ if (err .NE. NF_NOERR) call check(err, "nfmpi_iput_vara_real: coord sp")
+ else
+ err = nfmpi_put_vara_real_all(ncid, varid(4), starts, counts, coord_single)
+ if (err .NE. NF_NOERR) call check(err, "nfmpi_put_vara_read_all: coord sp")
+ endif
+
+! store the block size
+ do block_no = 1, lnblocks
+ blk_sz_single(:,block_no) = real(size(:,block_no), kind = single)
+ enddo
+
+ starts(1) = 1
+ starts(2) = global_offset+1
+ counts(1) = NDIM
+ counts(2) = lnblocks
+ if (use_nonblocking_io) then
+ err = nfmpi_iput_vara_real(ncid, varid(5), starts, counts, blk_sz_single, reqs(5))
+ if (err .NE. NF_NOERR) call check(err, "nfmpi_iput_vara_real: size sp")
+ else
+ err = nfmpi_put_vara_real_all(ncid, varid(5), starts, counts, blk_sz_single)
+ if (err .NE. NF_NOERR) call check(err, "nfmpi_put_vara_real_all: size sp")
+ endif
+
+! store the bounding box
+
+ do block_no = 1, lnblocks
+ bnd_single(:,:,block_no) = &
+ real(bnd_box(:,:,block_no), kind = single)
+ enddo
+
+ starts(1) = 1
+ starts(2) = 1
+ starts(3) = global_offset+1
+ counts(1) = 2
+ counts(2) = NDIM
+ counts(3) = lnblocks
+ if (use_nonblocking_io) then
+ err = nfmpi_iput_vara_real(ncid, varid(6), starts, counts, bnd_single, reqs(6))
+ if (err .NE. NF_NOERR) call check(err, "nfmpi_iput_vara_real: bnd_box")
+ else
+ err = nfmpi_put_vara_real_all(ncid, varid(6), starts, counts, bnd_single)
+ if (err .NE. NF_NOERR) call check(err, "nfmpi_put_vara_real_all: bnd_box")
+ endif
+
+ if (use_nonblocking_io) then
+ ! calculate attach buffer size for using buffered PnetCDF APIs
+ buf_size = (nxb+1) * (nyb+k2d) * (nzb+k3d) * maxblocks
+ buf_size = buf_size + nxb * nyb * nzb * maxblocks
+ buf_size = buf_size * num_out * 4
+ err = nfmpi_buffer_attach(ncid, buf_size)
+ endif
+
+!-----------------------------------------------------------------------------
+! store the unknowns -- here we will pass the entire unk array on each
+! processor. The HDF 5 memory space functionality will pick just the
+! interior cells to write to disk.
+!-----------------------------------------------------------------------------
+
+ if (corners) then
+ corner_t(2) = MPI_Wtime()
+ corner_t(1) = corner_t(2) - corner_t(1)
+ else
+ nocorner_t(2) = MPI_Wtime()
+ nocorner_t(1) = nocorner_t(2) - nocorner_t(1)
+ endif
+
+ do ivar = 1, num_out
+ record_label = unklabels(iout(ivar))
+
+! put the data at the corners if necessary
+ if (corners) then
+
+! interpolate only the variable we are storing to the corners
+
+! ** Important, the limits of the unkt_crn array do not include
+! guard cells, so we need to map the interior of the unk array
+! into the unkt_crn array.
+ do block_no = 1, lnblocks
+
+ do k = nguard*k3d+1,nguard*k3d+nzb+k3d
+ k_store = k - nguard*k3d
+
+ do j = nguard*k2d+1,nguard*k2d+nyb+k2d
+ j_store = j - nguard*k2d
+
+ do i = nguard+1,nguard+nxb+1
+ i_store = i - nguard
+
+#if N_DIM == 2
+ unkt_crn(1,i_store,j_store,k_store,block_no) = &
+ real( &
+ .25*(unk(iout(ivar),i-1,j, k,block_no) + &
+ unk(iout(ivar),i ,j, k,block_no) + &
+ unk(iout(ivar),i ,j-1,k,block_no) + &
+ unk(iout(ivar),i-1,j-1,k,block_no)), &
+ kind = single)
+#endif
+#if N_DIM == 3
+ unkt_crn(1,i_store,j_store,k_store,block_no) = &
+ real( &
+ .125*(unk(iout(ivar),i-1,j ,k ,block_no) + &
+ unk(iout(ivar),i ,j ,k ,block_no) + &
+ unk(iout(ivar),i ,j-1,k ,block_no) + &
+ unk(iout(ivar),i-1,j-1,k ,block_no) + &
+ unk(iout(ivar),i-1,j ,k-1,block_no) + &
+ unk(iout(ivar),i ,j ,k-1,block_no) + &
+ unk(iout(ivar),i ,j-1,k-1,block_no) + &
+ unk(iout(ivar),i-1,j-1,k-1,block_no)), &
+ kind = single)
+#endif
+
+ end do
+ end do
+ end do
+
+ enddo
+
+
+! we now have the data at the corners, in a 4-byte real array
+
+ starts(1) = 1
+ starts(2) = 1
+ starts(3) = 1
+ starts(4) = global_offset+1
+ counts(1) = nxb+1
+ counts(2) = nyb+ik2d
+ counts(3) = nzb+ik3d
+ counts(4) = lnblocks
+ if (use_nonblocking_io) then
+ err = nfmpi_bput_vara_real(ncid, varid(6+ivar), starts, counts, unkt_crn, reqs(ivar+6))
+ if (err .NE. NF_NOERR) call check(err, "nfmpi_bput_vara_real: unknowns sp")
+ else
+ err = nfmpi_put_vara_real_all(ncid, varid(6+ivar), starts, counts, unkt_crn)
+ if (err .NE. NF_NOERR) call check(err, "nfmpi_put_vara_real_all: unknowns sp")
+ endif
+
+ else
+
+ unkt(1,:,:,:,:) = real(unk(iout(ivar), &
+ nguard+1:nguard+nxb, &
+ nguard*k2d+1:nguard*k2d+nyb, &
+ nguard*k3d+1:nguard*k3d+nzb,:), &
+ kind = single)
+
+ starts(1) = 1
+ starts(2) = 1
+ starts(3) = 1
+ starts(4) = global_offset+1
+ counts(1) = nxb
+ counts(2) = nyb
+ counts(3) = nzb
+ counts(4) = lnblocks
+ if (use_nonblocking_io) then
+ err = nfmpi_bput_vara_real(ncid, varid(6+ivar), starts, counts, unkt, reqs(ivar+6))
+ if (err .NE. NF_NOERR) call check(err, "nfmpi_bput_vara_real: unknowns sp")
+ else
+ err = nfmpi_put_vara_real_all(ncid, varid(6+ivar), starts, counts, unkt)
+ if (err .NE. NF_NOERR) call check(err, "nfmpi_put_vara_real_all: unknowns sp")
+ endif
+ endif
+
+ enddo
+
+ ! wait for all nonblocking requests to complete
+ if (use_nonblocking_io) then
+ ! wait for the nonblocking I/O to complete
+ err = nfmpi_wait_all(ncid, num_out+6, reqs, stats)
+ if (err .NE. NF_NOERR) &
+ call check(err, "(sp) nfmpi_wait_all: ")
+
+ ! check the status of each nonblocking request
+ do i=1, num_out+6
+ write(str,'(I2)') i
+ if (stats(i) .NE. NF_NOERR) &
+ call check(stats(i), '(sp) nfmpi_wait_all req '//trim(str))
+ enddo
+
+ ! detach the temporary buffer
+ err = nfmpi_buffer_detach(ncid)
+ if (err .NE. NF_NOERR) &
+ call check(err, "(sp) nfmpi_buffer_detach: ")
+ endif
+
+!-----------------------------------------------------------------------------
+! close the file
+!-----------------------------------------------------------------------------
+
+ if (corners) then
+ corner_t(3) = MPI_Wtime()
+ corner_t(2) = corner_t(3) - corner_t(2)
+ else
+ nocorner_t(3) = MPI_Wtime()
+ nocorner_t(2) = nocorner_t(3) - nocorner_t(2)
+ endif
+
+ err = nfmpi_inq_put_size(ncid, put_size)
+ if (err .NE. NF_NOERR) &
+ call check(err, "(sp) nfmpi_inq_put_size: ")
+
+ err = nfmpi_close(ncid)
+ if (err .NE. NF_NOERR) call check(err, "nfmpi_close_file sp")
+
+ if (corners) then
+ corner_t(3) = MPI_Wtime() - corner_t(3)
+ else
+ nocorner_t(3) = MPI_Wtime() - nocorner_t(3)
+ endif
+
+ plotfile_ncmpi_par = put_size
+
+ return
+ end
+
+
+
+
+
+
+
diff --git a/benchmarks/FLASH-IO/tree.fh b/benchmarks/FLASH-IO/tree.fh
new file mode 100644
index 0000000..281075d
--- /dev/null
+++ b/benchmarks/FLASH-IO/tree.fh
@@ -0,0 +1,144 @@
+!-----------------------------------------------------------------
+! tree.fh
+
+
+
+! $RCSfile: tree.fh,v $
+! $Revision: 1468 $
+! $Date: 2013-10-26 11:53:18 -0500 (Sat, 26 Oct 2013) $
+
+
+
+ integer maxblocks_tr
+ parameter(maxblocks_tr=10*maxblocks)
+
+! Number of children of a node
+ integer nchild
+ parameter(nchild=2**ndim)
+
+! Number of faces on a grid block
+ integer nfaces
+ parameter(nfaces=2*ndim)
+
+! Parameters used to define array sizes
+ integer mdim,mchild,mfaces
+ parameter(mdim=3,mchild=2**mdim,mfaces=2*mdim)
+
+! Common block storing tree datastructure
+ common/tree/ neigh,child,parent,coord,size,bnd_box, &
+ lrefine,nodetype,empty, &
+ lnblocks,new_lnblocks,newchild,derefine,refine, &
+ stay,work_block, &
+ neigh_type,child_type
+
+ integer neigh(2,mfaces,maxblocks_tr)
+ integer child(2,mchild,maxblocks_tr)
+ integer parent(2,maxblocks_tr),lrefine(maxblocks_tr)
+ integer lnblocks,new_lnblocks
+
+ integer nodetype(maxblocks_tr)
+ integer neigh_type(mfaces,maxblocks_tr)
+ integer child_type(mchild,maxblocks_tr)
+ integer empty(maxblocks_tr)
+ logical newchild(maxblocks_tr)
+ logical derefine(maxblocks_tr),refine(maxblocks_tr)
+ logical stay(maxblocks_tr)
+
+ double precision work_block(maxblocks_tr)
+ double precision coord(mdim,maxblocks_tr)
+ double precision size(mdim,maxblocks_tr)
+ double precision bnd_box(2,mdim,maxblocks_tr)
+
+!--------------------------------------------
+!
+! A convention is established for numbering the neighbors (or faces
+! of a block. The first neighbor is at lower x coordinate, the
+! second at higher x, the third at lower y, fourth at higher y, fifth
+! at lower z and the sixth at higher z.
+!
+! The convention by which the children of a block are numbered is the
+! same as the fortran array ordering, so that the first child is
+! at lower x, y and z coordinate, the second child is at upper x
+! but lower y and z, the third is at lower x, upper y and lower z,
+! and so on.
+!
+! When a block has a refined neighbor we will need to know which children
+! of this neighbor are to provide guard cell information. The id's of the
+! correct children are stored in kchild using the conventions described
+! above. For example, if we are working on the 3rd neighbor of the
+! current block and it is at finer refinement level, then we must access
+! the children designated by kchild(:,3), in this case children 1, 2, 5
+! and 6.
+
+!--------------------------------------------
+!
+!
+! Description:
+! This is the include file for a quad or oct-tree data structure,
+! implemented on a parallel computer.
+!
+! The tree organizes a set of up to maxblocks_tr grids on each processor.
+! All the grids are assumed to be cartesian with a uniform size. Each
+! grid has a level of refinement associated with it. The set of level 0
+! grids cover the computational domain without overlap. Each grid
+! can be the parent of 2**d offspring grids which completely cover
+! the sub-domain of their parents, where d is the physical dimension
+! of the simulation. The linear resolution varies by a factor of 2
+! between successive levels of refinement. At no point do we allow the
+! resolution to jump by more than one level of refinement.
+!
+!
+! In the following list the index i ranges from 1 to maxblocks.
+!
+! neigh(2,nfaces,i) local and processor ids of block i's neighbors,
+! at i's refinement level. If a neighbor does
+! not exist both values are set to -1, unless
+! that face is at an external domain boundary
+! where non-periodic boundary conditions are to
+! be applied, in which case these are set to -20
+! or less, depending on the boundary conditions
+! to be applied on the boundary in question.
+! child(2,nchild,i) local and processor ids of block i's children
+! parent(2,i) local and processor ids of block i's parent
+! coord(ndim,i) array storing x,y and z coordinates of the
+! center of block i.
+! bnd_box(2,ndim,i) bounding box information for block i. The
+! lower edge of block i along the j-th coordinate
+! axis is at bnd_box(1,j,i) and the upper edge
+! at bnd_box(2,j,i).
+! size(ndim,i) size of block i in the x, y and z directions.
+! lrefine(i) refinement level of block i.
+! nodetype(i) defines the node type, if 1 then the node is a
+! leaf node, if 2 then the node is a parent but
+! with at least 1 leaf child, otherwise it is
+! set to 3 and it does not have any up-to-date
+! data.
+! empty(i) used to designate empty blocks, for example
+! when an obstacle is inserted inside the
+! computational domain. normal blocks have
+! empty=0, empty blocks have empty=1.
+!
+! new_child(i) if true then child has just been produced by
+! a refinement step, otherwise false.
+! lnblocks number of blocks on the local processor
+! new_lnblocks the new number of blocks on the local
+! processor after a refinement or derefinement
+! step.
+! refine(i) refinement flag. If set to .true. block i
+! will be refined during the next call to
+! REFINE_DEREFINE.
+! derefine(i) derefinement flag. If set to .true. block i
+! will be derefined during the next call to
+! REFINE_DEREFINE, provided this blocks parent
+! is not marked for refinement.
+! ADDED FOR EASIER AND MORE EFFICIENT MPI MESSAGING (KMO)
+! neigh_type(nfaces,i) types of the neighbors of block i
+! child_type(nchild,i) types of the children of block i
+!
+!
+!-----------------------------------------------------------------
+
+
+
+
+
diff --git a/benchmarks/Makefile.in b/benchmarks/Makefile.in
new file mode 100644
index 0000000..41e3bfd
--- /dev/null
+++ b/benchmarks/Makefile.in
@@ -0,0 +1,54 @@
+#
+# Copyright (C) 2012, Northwestern University and Argonne National Laboratory
+# See COPYRIGHT notice in top-level directory.
+#
+# $Id: Makefile.in 2219 2015-12-11 22:30:03Z wkliao $
+#
+# @configure_input@
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+include ../macros.make
+
+SUBDIRS = C
+
+ifeq (@has_fortran@, yes)
+SUBDIRS += FLASH-IO
+endif
+
+PACKING_LIST = Makefile.in README
+
+PACKING_SUBDIRS = C FLASH-IO
+
+GARBAGE =
+
+all: $(SUBDIRS)
+$(SUBDIRS):
+ $(MAKE) $(MFLAGS) -C $@
+
+PTEST_DIRS = $(SUBDIRS:%=ptest-%)
+ptest: all $(PTEST_DIRS)
+$(PTEST_DIRS):
+ifeq (@enable_coverage@, yes)
+ echo "Parallel test is disabled because coverage analysis was enabled"
+else
+ $(MAKE) $(MFLAGS) -C $(@:ptest-%=%) ptest
+endif
+# make sure ptest runs one directory after another
+ptest-FLASH-IO: ptest-C
+
+ptests: ptest
+
+INSTALLDIRS = $(SUBDIRS:%=install-%)
+install: all $(INSTALLDIRS)
+$(INSTALLDIRS):
+ $(MAKE) $(MFLAGS) -C $(@:install-%=%) install
+
+UNINSTALLDIRS = $(SUBDIRS:%=uninstall-%)
+uninstall: $(UNINSTALLDIRS)
+$(UNINSTALLDIRS):
+ $(MAKE) $(MFLAGS) -C $(@:uninstall-%=%) uninstall
+
+include $(srcdir)/../rules.make
+
diff --git a/benchmarks/README b/benchmarks/README
new file mode 100644
index 0000000..f90313d
--- /dev/null
+++ b/benchmarks/README
@@ -0,0 +1,29 @@
+# $Id: README 1468 2013-10-26 16:53:18Z wkliao $
+
+The programs in this directory are designed to measure the I/O performance for
+various of APIs as well as access patterns.
+
+C/aggregation.c
+ o This program writes a series of 2D variables with data partitioning
+ patterns of block-block, *-cyclic, block-*, and *-block, round-robinly.
+ The block-* partitioning case writes 1st half followed by 2nd half. The
+ same partitioning patterns are used for read. In both cases, nonblocking
+ APIs are used to evaluate the performance.
+ o Parameters:
+ * NVARS: a defined C macro, the number of variables
+ * len: dimension size of local variables, len x len
+ o Write and read performance are measured and reported separately.
+
+
+C/write_block_read_column.c
+ o This program writes a series of 2D variables partitioned in a block-block
+ pattern into a new file. The file is re-opened to read all the 2D variables
+ but in a 2D *-block pattern.
+ o Write and read performance are measured and reported separately.
+
+
+FLASH
+ o This benchmark is algorithmically identical to the FLASH-IO kernel.
+ FLASH is a reacting hydrodynamics code developed at University of Chicago.
+ http://flash.uchicago.edu
+ o This distribution contains only PnetCDF I/O method.
diff --git a/cobalt.script b/cobalt.script
new file mode 100755
index 0000000..69438d6
--- /dev/null
+++ b/cobalt.script
@@ -0,0 +1,16 @@
+#!/bin/sh
+echo "Starting Cobalt job script"
+# see runjob --help for more options
+
+
+# test seqential programs
+make check TEST_MPIRUN="runjob --block $COBALT_PARTNAME --ranks-per-node 1 --np NP : " \
+ TEST_SEQRUN="runjob --block $COBALT_PARTNAME --ranks-per-node 1 --np 1 : " \
+ TEST_OUTDIR=/path/to/GPFS/directory
+
+# test parallel programs
+make ptest TEST_MPIRUN="runjob --block $COBALT_PARTNAME --ranks-per-node 1 --np NP : " \
+ TEST_SEQRUN="runjob --block $COBALT_PARTNAME --ranks-per-node 1 --np 1 : " \
+ TEST_OUTDIR=/path/to/GPFS/directory
+
+
diff --git a/configure b/configure
new file mode 100755
index 0000000..fd3fafb
--- /dev/null
+++ b/configure
@@ -0,0 +1,15165 @@
+#! /bin/sh
+# From configure.in Id: configure.in 2304 2016-01-12 18:39:01Z wkliao .
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.69 for parallel-netcdf 1.7.0.pre1.
+#
+# Report bugs to <parallel-netcdf at mcs.anl.gov>.
+#
+#
+# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
+#
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in #(
+ *posix*) :
+ set -o posix ;; #(
+ *) :
+ ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='print -r --'
+ as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='printf %s\n'
+ as_echo_n='printf %s'
+else
+ if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+ as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+ as_echo_n='/usr/ucb/echo -n'
+ else
+ as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+ as_echo_n_body='eval
+ arg=$1;
+ case $arg in #(
+ *"$as_nl"*)
+ expr "X$arg" : "X\\(.*\\)$as_nl";
+ arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+ esac;
+ expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+ '
+ export as_echo_n_body
+ as_echo_n='sh -c $as_echo_n_body as_echo'
+ fi
+ export as_echo_body
+ as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ PATH_SEPARATOR=:
+ (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+ (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+ PATH_SEPARATOR=';'
+ }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order. Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" "" $as_nl"
+
+# Find who we are. Look in the path if we contain no directory separator.
+as_myself=
+case $0 in #((
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+ as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+ $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+ exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there. '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+# Use a proper internal environment variable to ensure we don't fall
+ # into an infinite loop, continuously re-executing ourselves.
+ if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then
+ _as_can_reexec=no; export _as_can_reexec;
+ # We cannot yet assume a decent shell, so we have to provide a
+# neutralization value for shells without unset; and this also
+# works around shells that cannot unset nonexistent variables.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+ *v*x* | *x*v* ) as_opts=-vx ;;
+ *v* ) as_opts=-v ;;
+ *x* ) as_opts=-x ;;
+ * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+as_fn_exit 255
+ fi
+ # We don't want this to propagate to other subprocesses.
+ { _as_can_reexec=; unset _as_can_reexec;}
+if test "x$CONFIG_SHELL" = x; then
+ as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '\${1+\"\$@\"}'='\"\$@\"'
+ setopt NO_GLOB_SUBST
+else
+ case \`(set -o) 2>/dev/null\` in #(
+ *posix*) :
+ set -o posix ;; #(
+ *) :
+ ;;
+esac
+fi
+"
+ as_required="as_fn_return () { (exit \$1); }
+as_fn_success () { as_fn_return 0; }
+as_fn_failure () { as_fn_return 1; }
+as_fn_ret_success () { return 0; }
+as_fn_ret_failure () { return 1; }
+
+exitcode=0
+as_fn_success || { exitcode=1; echo as_fn_success failed.; }
+as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; }
+as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; }
+as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; }
+if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then :
+
+else
+ exitcode=1; echo positional parameters were not saved.
+fi
+test x\$exitcode = x0 || exit 1
+test -x / || exit 1"
+ as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
+ as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
+ eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
+ test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1
+test \$(( 1 + 1 )) = 2 || exit 1"
+ if (eval "$as_required") 2>/dev/null; then :
+ as_have_required=yes
+else
+ as_have_required=no
+fi
+ if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then :
+
+else
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+as_found=false
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ as_found=:
+ case $as_dir in #(
+ /*)
+ for as_base in sh bash ksh sh5; do
+ # Try only shells that exist, to save several forks.
+ as_shell=$as_dir/$as_base
+ if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
+ { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then :
+ CONFIG_SHELL=$as_shell as_have_required=yes
+ if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then :
+ break 2
+fi
+fi
+ done;;
+ esac
+ as_found=false
+done
+$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } &&
+ { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then :
+ CONFIG_SHELL=$SHELL as_have_required=yes
+fi; }
+IFS=$as_save_IFS
+
+
+ if test "x$CONFIG_SHELL" != x; then :
+ export CONFIG_SHELL
+ # We cannot yet assume a decent shell, so we have to provide a
+# neutralization value for shells without unset; and this also
+# works around shells that cannot unset nonexistent variables.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+ *v*x* | *x*v* ) as_opts=-vx ;;
+ *v* ) as_opts=-v ;;
+ *x* ) as_opts=-x ;;
+ * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+exit 255
+fi
+
+ if test x$as_have_required = xno; then :
+ $as_echo "$0: This script requires a shell more modern than all"
+ $as_echo "$0: the shells that I found on your system."
+ if test x${ZSH_VERSION+set} = xset ; then
+ $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should"
+ $as_echo "$0: be upgraded to zsh 4.3.4 or later."
+ else
+ $as_echo "$0: Please tell bug-autoconf at gnu.org and
+$0: parallel-netcdf at mcs.anl.gov about your system,
+$0: including any error possibly output before this
+$0: message. Then install a modern shell, or manually run
+$0: the script under such a shell if you do have one."
+ fi
+ exit 1
+fi
+fi
+fi
+SHELL=${CONFIG_SHELL-/bin/sh}
+export SHELL
+# Unset more variables known to interfere with behavior of common tools.
+CLICOLOR_FORCE= GREP_OPTIONS=
+unset CLICOLOR_FORCE GREP_OPTIONS
+
+## --------------------- ##
+## M4sh Shell Functions. ##
+## --------------------- ##
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+ { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+ return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+ set +e
+ as_fn_set_status $1
+ exit $1
+} # as_fn_exit
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+ case $as_dir in #(
+ -*) as_dir=./$as_dir;;
+ esac
+ test -d "$as_dir" || eval $as_mkdir_p || {
+ as_dirs=
+ while :; do
+ case $as_dir in #(
+ *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+ *) as_qdir=$as_dir;;
+ esac
+ as_dirs="'$as_qdir' $as_dirs"
+ as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ test -d "$as_dir" && break
+ done
+ test -z "$as_dirs" || eval "mkdir $as_dirs"
+ } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+ test -f "$1" && test -x "$1"
+} # as_fn_executable_p
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+ eval 'as_fn_append ()
+ {
+ eval $1+=\$2
+ }'
+else
+ as_fn_append ()
+ {
+ eval $1=\$$1\$2
+ }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+ eval 'as_fn_arith ()
+ {
+ as_val=$(( $* ))
+ }'
+else
+ as_fn_arith ()
+ {
+ as_val=`expr "$@" || test $? -eq 1`
+ }
+fi # as_fn_arith
+
+
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with STATUS, using 1 if that was 0.
+as_fn_error ()
+{
+ as_status=$1; test $as_status -eq 0 && as_status=1
+ if test "$4"; then
+ as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+ fi
+ $as_echo "$as_me: error: $2" >&2
+ as_fn_exit $as_status
+} # as_fn_error
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+ as_dirname=dirname
+else
+ as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+
+ as_lineno_1=$LINENO as_lineno_1a=$LINENO
+ as_lineno_2=$LINENO as_lineno_2a=$LINENO
+ eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" &&
+ test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || {
+ # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-)
+ sed -n '
+ p
+ /[$]LINENO/=
+ ' <$as_myself |
+ sed '
+ s/[$]LINENO.*/&-/
+ t lineno
+ b
+ :lineno
+ N
+ :loop
+ s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
+ t loop
+ s/-\n.*//
+ ' >$as_me.lineno &&
+ chmod +x "$as_me.lineno" ||
+ { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
+
+ # If we had to re-execute with $CONFIG_SHELL, we're ensured to have
+ # already done that, so ensure we don't try to do so again and fall
+ # in an infinite loop. This has already happened in practice.
+ _as_can_reexec=no; export _as_can_reexec
+ # Don't try to exec as it changes $[0], causing all sort of problems
+ # (the dirname of $[0] is not the place where we might find the
+ # original and so on. Autoconf is especially sensitive to this).
+ . "./$as_me.lineno"
+ # Exit status is that of the last command.
+ exit
+}
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+ case `echo 'xy\c'` in
+ *c*) ECHO_T=' ';; # ECHO_T is single tab character.
+ xy) ECHO_C='\c';;
+ *) echo `echo ksh88 bug on AIX 6.1` > /dev/null
+ ECHO_T=' ';;
+ esac;;
+*)
+ ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+ rm -f conf$$.dir/conf$$.file
+else
+ rm -f conf$$.dir
+ mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+ if ln -s conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s='ln -s'
+ # ... but there are two gotchas:
+ # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+ # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+ # In both cases, we have to default to `cp -pR'.
+ ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+ as_ln_s='cp -pR'
+ elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+ else
+ as_ln_s='cp -pR'
+ fi
+else
+ as_ln_s='cp -pR'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p='mkdir -p "$as_dir"'
+else
+ test -d ./-p && rmdir ./-p
+ as_mkdir_p=false
+fi
+
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+test -n "$DJDIR" || exec 7<&0 </dev/null
+exec 6>&1
+
+# Name of the host.
+# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_clean_files=
+ac_config_libobj_dir=.
+LIBOBJS=
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+
+# Identity of this package.
+PACKAGE_NAME='parallel-netcdf'
+PACKAGE_TARNAME='parallel-netcdf'
+PACKAGE_VERSION='1.7.0.pre1'
+PACKAGE_STRING='parallel-netcdf 1.7.0.pre1'
+PACKAGE_BUGREPORT='parallel-netcdf at mcs.anl.gov'
+PACKAGE_URL=''
+
+ac_unique_file="src/lib/pnetcdf.h.in"
+# Factoring default headers for most tests.
+ac_includes_default="\
+#include <stdio.h>
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+# include <stdlib.h>
+# endif
+#endif
+#ifdef HAVE_STRING_H
+# if !defined STDC_HEADERS && defined HAVE_MEMORY_H
+# include <memory.h>
+# endif
+# include <string.h>
+#endif
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#ifdef HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif"
+
+ac_subst_vars='LTLIBOBJS
+LIBOBJS
+SEQ_CC
+TEST_OUTDIR
+TEST_MPIRUN
+TEST_SEQRUN
+PNETCDF_LIB
+PNETCDF_INC
+large_file_test
+BUILDDIR
+has_latex
+DVIPDF
+LATEX
+enable_subfiling
+enable_coverage
+LCOV_LIB
+MAKEWHATIS_CMD
+WHATIS
+prog
+has_fortran
+F90LDFLAGS
+FLDFLAGS
+F90LIBS
+UPPER_CASE_MOD
+FC_MODOUT
+ac_empty
+FC_MODINC
+FC_MODEXT
+SIZEOF_MPI_OFFSET
+INTENTV
+is_bigendian
+SIZEOF_MPI_AINT_IS_4
+PNC_DEBUG
+CPP
+RANLIB
+NMFLAGS
+NM
+ARFLAGS
+AR
+M4FLAGS
+M4
+EGREP
+GREP
+SET_MAKE
+LN_S
+have_yacc_lex
+INSTALL_DATA
+INSTALL_SCRIPT
+INSTALL_PROGRAM
+PNF_X_UINT8_MAX
+PNF_X_INT8_MAX
+PNF_X_INT8_MIN
+PNF_X_UINT_MAX
+PNF_FILL_UINT64
+PNF_FILL_INT64
+PNF_FILL_UINT
+PNF_INT8_MODIFIER
+NAG_FCFLAGS
+NAGf90FPPFLAGS
+FFIXEDFORMFLAG
+F90FLAGS_F90
+F90FLAGS_f90
+F77FLAGS_F
+F77FLAGS_f
+FCFLAGS_F90
+FCFLAGS_f90
+FCFLAGS_F
+FCFLAGS_f
+FC_DEFINE
+FPPFLAGS
+FPP
+F90PPFLAGS_F90
+F90PPFLAGS_f90
+F77PPFLAGS_F
+F77PPFLAGS_f
+F77_SUPPORT_FREEFORM
+FFREEFORMFLAG
+F77FLAGS
+FLIBS
+ac_ct_F77
+F90FLAGS
+FCLIBS
+host_os
+host_vendor
+host_cpu
+host
+build_os
+build_vendor
+build_cpu
+build
+ac_ct_FC
+CXXCPPFLAGS
+has_mpicxx
+ac_ct_CXX
+CC_MAKEDEPEND
+OBJEXT
+EXEEXT
+ac_ct_CC
+LDFLAGS
+FCFLAGS
+FFLAGS
+CXXFLAGS
+CPPFLAGS
+CFLAGS
+FC
+F77
+CXX
+CC
+MPIF90
+MPIF77
+MPICXX
+MPICC
+rm_cmd
+RM
+CONFIGURE_ARGS_CLEAN
+PNETCDF_RELEASE_DATE2
+PNETCDF_RELEASE_DATE
+PNETCDF_VERSION
+PNETCDF_VERSION_PRE
+PNETCDF_VERSION_SUB
+PNETCDF_VERSION_MINOR
+PNETCDF_VERSION_MAJOR
+target_alias
+host_alias
+build_alias
+LIBS
+ECHO_T
+ECHO_N
+ECHO_C
+DEFS
+mandir
+localedir
+libdir
+psdir
+pdfdir
+dvidir
+htmldir
+infodir
+docdir
+oldincludedir
+includedir
+localstatedir
+sharedstatedir
+sysconfdir
+datadir
+datarootdir
+libexecdir
+sbindir
+bindir
+program_transform_name
+prefix
+exec_prefix
+PACKAGE_URL
+PACKAGE_BUGREPORT
+PACKAGE_STRING
+PACKAGE_VERSION
+PACKAGE_TARNAME
+PACKAGE_NAME
+PATH_SEPARATOR
+SHELL'
+ac_subst_files=''
+ac_user_opts='
+enable_option_checking
+enable_echo
+with_mpi
+enable_largefile
+enable_mpi_io_test
+enable_cxx
+enable_strict
+enable_fortran
+enable_debug
+enable_in_place_swap
+enable_coverage
+enable_subfiling
+enable_file_sync
+enable_large_file_test
+'
+ ac_precious_vars='build_alias
+host_alias
+target_alias
+RM
+MPICC
+MPICXX
+MPIF77
+MPIF90
+CC
+CXX
+F77
+FC
+CFLAGS
+CPPFLAGS
+CXXFLAGS
+FFLAGS
+FCFLAGS
+LDFLAGS
+LIBS
+CCC
+CPP
+TEST_SEQRUN
+TEST_MPIRUN
+TEST_OUTDIR'
+
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+ac_unrecognized_opts=
+ac_unrecognized_sep=
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+# (The list follows the same order as the GNU Coding Standards.)
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datarootdir='${prefix}/share'
+datadir='${datarootdir}'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
+infodir='${datarootdir}/info'
+htmldir='${docdir}'
+dvidir='${docdir}'
+pdfdir='${docdir}'
+psdir='${docdir}'
+libdir='${exec_prefix}/lib'
+localedir='${datarootdir}/locale'
+mandir='${datarootdir}/man'
+
+ac_prev=
+ac_dashdash=
+for ac_option
+do
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval $ac_prev=\$ac_option
+ ac_prev=
+ continue
+ fi
+
+ case $ac_option in
+ *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
+ *=) ac_optarg= ;;
+ *) ac_optarg=yes ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case $ac_dashdash$ac_option in
+ --)
+ ac_dashdash=yes ;;
+
+ -bindir | --bindir | --bindi | --bind | --bin | --bi)
+ ac_prev=bindir ;;
+ -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+ bindir=$ac_optarg ;;
+
+ -build | --build | --buil | --bui | --bu)
+ ac_prev=build_alias ;;
+ -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+ build_alias=$ac_optarg ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+ cache_file=$ac_optarg ;;
+
+ --config-cache | -C)
+ cache_file=config.cache ;;
+
+ -datadir | --datadir | --datadi | --datad)
+ ac_prev=datadir ;;
+ -datadir=* | --datadir=* | --datadi=* | --datad=*)
+ datadir=$ac_optarg ;;
+
+ -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \
+ | --dataroo | --dataro | --datar)
+ ac_prev=datarootdir ;;
+ -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \
+ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)
+ datarootdir=$ac_optarg ;;
+
+ -disable-* | --disable-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error $? "invalid feature name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"enable_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval enable_$ac_useropt=no ;;
+
+ -docdir | --docdir | --docdi | --doc | --do)
+ ac_prev=docdir ;;
+ -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*)
+ docdir=$ac_optarg ;;
+
+ -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv)
+ ac_prev=dvidir ;;
+ -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)
+ dvidir=$ac_optarg ;;
+
+ -enable-* | --enable-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error $? "invalid feature name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"enable_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval enable_$ac_useropt=\$ac_optarg ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix=$ac_optarg ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he | -h)
+ ac_init_help=long ;;
+ -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+ ac_init_help=recursive ;;
+ -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+ ac_init_help=short ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host_alias ;;
+ -host=* | --host=* | --hos=* | --ho=*)
+ host_alias=$ac_optarg ;;
+
+ -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht)
+ ac_prev=htmldir ;;
+ -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \
+ | --ht=*)
+ htmldir=$ac_optarg ;;
+
+ -includedir | --includedir | --includedi | --included | --include \
+ | --includ | --inclu | --incl | --inc)
+ ac_prev=includedir ;;
+ -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+ | --includ=* | --inclu=* | --incl=* | --inc=*)
+ includedir=$ac_optarg ;;
+
+ -infodir | --infodir | --infodi | --infod | --info | --inf)
+ ac_prev=infodir ;;
+ -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+ infodir=$ac_optarg ;;
+
+ -libdir | --libdir | --libdi | --libd)
+ ac_prev=libdir ;;
+ -libdir=* | --libdir=* | --libdi=* | --libd=*)
+ libdir=$ac_optarg ;;
+
+ -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+ | --libexe | --libex | --libe)
+ ac_prev=libexecdir ;;
+ -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+ | --libexe=* | --libex=* | --libe=*)
+ libexecdir=$ac_optarg ;;
+
+ -localedir | --localedir | --localedi | --localed | --locale)
+ ac_prev=localedir ;;
+ -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*)
+ localedir=$ac_optarg ;;
+
+ -localstatedir | --localstatedir | --localstatedi | --localstated \
+ | --localstate | --localstat | --localsta | --localst | --locals)
+ ac_prev=localstatedir ;;
+ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*)
+ localstatedir=$ac_optarg ;;
+
+ -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+ ac_prev=mandir ;;
+ -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+ mandir=$ac_optarg ;;
+
+ -nfp | --nfp | --nf)
+ # Obsolete; use --without-fp.
+ with_fp=no ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c | -n)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+ no_recursion=yes ;;
+
+ -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+ | --oldin | --oldi | --old | --ol | --o)
+ ac_prev=oldincludedir ;;
+ -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+ oldincludedir=$ac_optarg ;;
+
+ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+ ac_prev=prefix ;;
+ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+ prefix=$ac_optarg ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix=$ac_optarg ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix=$ac_optarg ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name=$ac_optarg ;;
+
+ -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd)
+ ac_prev=pdfdir ;;
+ -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*)
+ pdfdir=$ac_optarg ;;
+
+ -psdir | --psdir | --psdi | --psd | --ps)
+ ac_prev=psdir ;;
+ -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)
+ psdir=$ac_optarg ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ silent=yes ;;
+
+ -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+ ac_prev=sbindir ;;
+ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+ | --sbi=* | --sb=*)
+ sbindir=$ac_optarg ;;
+
+ -sharedstatedir | --sharedstatedir | --sharedstatedi \
+ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+ | --sharedst | --shareds | --shared | --share | --shar \
+ | --sha | --sh)
+ ac_prev=sharedstatedir ;;
+ -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+ | --sha=* | --sh=*)
+ sharedstatedir=$ac_optarg ;;
+
+ -site | --site | --sit)
+ ac_prev=site ;;
+ -site=* | --site=* | --sit=*)
+ site=$ac_optarg ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+ srcdir=$ac_optarg ;;
+
+ -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+ | --syscon | --sysco | --sysc | --sys | --sy)
+ ac_prev=sysconfdir ;;
+ -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+ sysconfdir=$ac_optarg ;;
+
+ -target | --target | --targe | --targ | --tar | --ta | --t)
+ ac_prev=target_alias ;;
+ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+ target_alias=$ac_optarg ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers | -V)
+ ac_init_version=: ;;
+
+ -with-* | --with-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error $? "invalid package name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"with_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval with_$ac_useropt=\$ac_optarg ;;
+
+ -without-* | --without-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error $? "invalid package name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"with_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval with_$ac_useropt=no ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes=$ac_optarg ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries=$ac_optarg ;;
+
+ -*) as_fn_error $? "unrecognized option: \`$ac_option'
+Try \`$0 --help' for more information"
+ ;;
+
+ *=*)
+ ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+ # Reject names that are not valid shell variable names.
+ case $ac_envvar in #(
+ '' | [0-9]* | *[!_$as_cr_alnum]* )
+ as_fn_error $? "invalid variable name: \`$ac_envvar'" ;;
+ esac
+ eval $ac_envvar=\$ac_optarg
+ export $ac_envvar ;;
+
+ *)
+ # FIXME: should be removed in autoconf 3.0.
+ $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+ expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+ $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+ : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}"
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+ as_fn_error $? "missing argument to $ac_option"
+fi
+
+if test -n "$ac_unrecognized_opts"; then
+ case $enable_option_checking in
+ no) ;;
+ fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;;
+ *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
+ esac
+fi
+
+# Check all directory arguments for consistency.
+for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
+ datadir sysconfdir sharedstatedir localstatedir includedir \
+ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
+ libdir localedir mandir
+do
+ eval ac_val=\$$ac_var
+ # Remove trailing slashes.
+ case $ac_val in
+ */ )
+ ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'`
+ eval $ac_var=\$ac_val;;
+ esac
+ # Be sure to have absolute directory names.
+ case $ac_val in
+ [\\/$]* | ?:[\\/]* ) continue;;
+ NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
+ esac
+ as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val"
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+ if test "x$build_alias" = x; then
+ cross_compiling=maybe
+ elif test "x$build_alias" != "x$host_alias"; then
+ cross_compiling=yes
+ fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+ac_pwd=`pwd` && test -n "$ac_pwd" &&
+ac_ls_di=`ls -di .` &&
+ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
+ as_fn_error $? "working directory cannot be determined"
+test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
+ as_fn_error $? "pwd does not report name of working directory"
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then the parent directory.
+ ac_confdir=`$as_dirname -- "$as_myself" ||
+$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_myself" : 'X\(//\)[^/]' \| \
+ X"$as_myself" : 'X\(//\)$' \| \
+ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_myself" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ srcdir=$ac_confdir
+ if test ! -r "$srcdir/$ac_unique_file"; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r "$srcdir/$ac_unique_file"; then
+ test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
+ as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir"
+fi
+ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
+ac_abs_confdir=`(
+ cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg"
+ pwd)`
+# When building in place, set srcdir=.
+if test "$ac_abs_confdir" = "$ac_pwd"; then
+ srcdir=.
+fi
+# Remove unnecessary trailing slashes from srcdir.
+# Double slashes in file names in object file debugging info
+# mess up M-x gdb in Emacs.
+case $srcdir in
+*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;;
+esac
+for ac_var in $ac_precious_vars; do
+ eval ac_env_${ac_var}_set=\${${ac_var}+set}
+ eval ac_env_${ac_var}_value=\$${ac_var}
+ eval ac_cv_env_${ac_var}_set=\${${ac_var}+set}
+ eval ac_cv_env_${ac_var}_value=\$${ac_var}
+done
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat <<_ACEOF
+\`configure' configures parallel-netcdf 1.7.0.pre1 to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE. See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+ -h, --help display this help and exit
+ --help=short display options specific to this package
+ --help=recursive display the short help of all the included packages
+ -V, --version display version information and exit
+ -q, --quiet, --silent do not print \`checking ...' messages
+ --cache-file=FILE cache test results in FILE [disabled]
+ -C, --config-cache alias for \`--cache-file=config.cache'
+ -n, --no-create do not create output files
+ --srcdir=DIR find the sources in DIR [configure dir or \`..']
+
+Installation directories:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_prefix]
+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
+ [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+ --bindir=DIR user executables [EPREFIX/bin]
+ --sbindir=DIR system admin executables [EPREFIX/sbin]
+ --libexecdir=DIR program executables [EPREFIX/libexec]
+ --sysconfdir=DIR read-only single-machine data [PREFIX/etc]
+ --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
+ --localstatedir=DIR modifiable single-machine data [PREFIX/var]
+ --libdir=DIR object code libraries [EPREFIX/lib]
+ --includedir=DIR C header files [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc [/usr/include]
+ --datarootdir=DIR read-only arch.-independent data root [PREFIX/share]
+ --datadir=DIR read-only architecture-independent data [DATAROOTDIR]
+ --infodir=DIR info documentation [DATAROOTDIR/info]
+ --localedir=DIR locale-dependent data [DATAROOTDIR/locale]
+ --mandir=DIR man documentation [DATAROOTDIR/man]
+ --docdir=DIR documentation root [DATAROOTDIR/doc/parallel-netcdf]
+ --htmldir=DIR html documentation [DOCDIR]
+ --dvidir=DIR dvi documentation [DOCDIR]
+ --pdfdir=DIR pdf documentation [DOCDIR]
+ --psdir=DIR ps documentation [DOCDIR]
+_ACEOF
+
+ cat <<\_ACEOF
+
+System types:
+ --build=BUILD configure for building on BUILD [guessed]
+ --host=HOST cross-compile to build programs to run on HOST [BUILD]
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+ case $ac_init_help in
+ short | recursive ) echo "Configuration of parallel-netcdf 1.7.0.pre1:";;
+ esac
+ cat <<\_ACEOF
+
+Optional Features:
+ --disable-option-checking ignore unrecognized --enable/--with options
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --enable-echo Turn on strong echoing. [default: disabled]
+ --disable-largefile omit support for large files
+ --disable-mpi-io-test Disable check for MPI-IO support in MPI
+ implementation, if you know your MPI implementation
+ has MPI-IO support but the configure test fails to
+ find it. [default: enabled]
+ --disable-cxx Turn off support for the C++ interface, if you only
+ need the C interface. [default: enabled]
+ --enable-strict Turn on strict debugging with gcc. [default:
+ disabled]
+ --disable-fortran Turn off support for the Fortran interface, if you
+ only need the C interface. [default: enabled]
+ --enable-debug Enable PnetCDF internal debug mode. This also
+ enables safe mode. [default: disabled]
+ --disable-in-place-swap Disable memory in-place byte swap on Little Endian
+ machines. [default: enabled]
+ --enable-coverage Compile with coverage support (gcc-based only).
+ [default: disabled]
+ --enable-subfiling Enable subfiling support. [default: disabled]
+ --disable-file-sync Disable MPI file sync if you know your file system
+ can provide data consistency. [default: enabled]
+ --enable-large-file-test
+ Enable testing for large (>4GB) file/variable I/O.
+ Note "make testing" can run very slow. [default:
+ disabled]
+
+Optional Packages:
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --with-mpi=/path/to/implementation
+ installation prefix for MPI implementation
+
+Some influential environment variables:
+ RM Command for deleting files or directories. default: rm
+ MPICC MPI C compiler
+ MPICXX MPI C++ compiler
+ MPIF77 MPI Fortran 77 compiler
+ MPIF90 MPI Fortran 90 compiler
+ CC Overwritten by MPICC if MPICC is set
+ CXX Overwritten by MPICXX if MPICXX is set
+ F77 Overwritten by MPIF77 if MPIF77 is set
+ FC Overwritten by MPIF90 if MPIF90 is set
+ CFLAGS Debugging and optimization options for the C compiler
+ CPPFLAGS Preprocessor options for the C and C++ compilers, e.g.
+ -I<include dir> if you have headers in a nonstandard directory
+ <include dir>
+ CXXFLAGS Debugging and optimization options for the C compiler
+ FFLAGS Debugging and optimization options for the Fortran 77 compiler
+ FCFLAGS Debugging and optimization options for the Fortran 90 compiler
+ LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a
+ nonstandard directory <lib dir>
+ LIBS libraries to pass to the linker, e.g. -l<library>
+ CPP C preprocessor
+ TEST_SEQRUN Run command (on one process) for make target check on
+ cross-compile environment. Example: "aprun -n 1". [default:
+ none]
+ TEST_MPIRUN MPI run command for make target ptest, [default: mpiexec -n NP]
+ TEST_OUTDIR Output file directory for make target ptest, [default: ./]
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+Report bugs to <parallel-netcdf at mcs.anl.gov>.
+_ACEOF
+ac_status=$?
+fi
+
+if test "$ac_init_help" = "recursive"; then
+ # If there are subdirs, report their specific --help.
+ for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+ test -d "$ac_dir" ||
+ { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } ||
+ continue
+ ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+ ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+ # A ".." for each directory in $ac_dir_suffix.
+ ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+ case $ac_top_builddir_sub in
+ "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+ *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+ esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+ .) # We are building in place.
+ ac_srcdir=.
+ ac_top_srcdir=$ac_top_builddir_sub
+ ac_abs_top_srcdir=$ac_pwd ;;
+ [\\/]* | ?:[\\/]* ) # Absolute name.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir
+ ac_abs_top_srcdir=$srcdir ;;
+ *) # Relative name.
+ ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_build_prefix$srcdir
+ ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+ cd "$ac_dir" || { ac_status=$?; continue; }
+ # Check for guested configure.
+ if test -f "$ac_srcdir/configure.gnu"; then
+ echo &&
+ $SHELL "$ac_srcdir/configure.gnu" --help=recursive
+ elif test -f "$ac_srcdir/configure"; then
+ echo &&
+ $SHELL "$ac_srcdir/configure" --help=recursive
+ else
+ $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+ fi || ac_status=$?
+ cd "$ac_pwd" || { ac_status=$?; break; }
+ done
+fi
+
+test -n "$ac_init_help" && exit $ac_status
+if $ac_init_version; then
+ cat <<\_ACEOF
+parallel-netcdf configure 1.7.0.pre1
+generated by GNU Autoconf 2.69
+
+Copyright (C) 2012 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+ exit
+fi
+
+## ------------------------ ##
+## Autoconf initialization. ##
+## ------------------------ ##
+
+# ac_fn_c_try_compile LINENO
+# --------------------------
+# Try to compile conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_compile ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ rm -f conftest.$ac_objext
+ if { { ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compile") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_compile
+
+# ac_fn_c_try_link LINENO
+# -----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_link ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ rm -f conftest.$ac_objext conftest$ac_exeext
+ if { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext && {
+ test "$cross_compiling" = yes ||
+ test -x conftest$ac_exeext
+ }; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
+ # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
+ # interfere with the next link command; also delete a directory that is
+ # left behind by Apple's compiler. We do this before executing the actions.
+ rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_link
+
+# ac_fn_c_check_func LINENO FUNC VAR
+# ----------------------------------
+# Tests whether FUNC exists, setting the cache variable VAR accordingly
+ac_fn_c_check_func ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+/* Define $2 to an innocuous variant, in case <limits.h> declares $2.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $2 innocuous_$2
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $2 (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $2
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $2 ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined __stub_$2 || defined __stub___$2
+choke me
+#endif
+
+int
+main ()
+{
+return $2 ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ eval "$3=yes"
+else
+ eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_func
+
+# ac_fn_cxx_try_compile LINENO
+# ----------------------------
+# Try to compile conftest.$ac_ext, and return whether this succeeded.
+ac_fn_cxx_try_compile ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ rm -f conftest.$ac_objext
+ if { { ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compile") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_cxx_try_compile
+
+# ac_fn_cxx_try_link LINENO
+# -------------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded.
+ac_fn_cxx_try_link ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ rm -f conftest.$ac_objext conftest$ac_exeext
+ if { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext && {
+ test "$cross_compiling" = yes ||
+ test -x conftest$ac_exeext
+ }; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
+ # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
+ # interfere with the next link command; also delete a directory that is
+ # left behind by Apple's compiler. We do this before executing the actions.
+ rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_cxx_try_link
+
+# ac_fn_cxx_check_func LINENO FUNC VAR
+# ------------------------------------
+# Tests whether FUNC exists, setting the cache variable VAR accordingly
+ac_fn_cxx_check_func ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+/* Define $2 to an innocuous variant, in case <limits.h> declares $2.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $2 innocuous_$2
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $2 (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $2
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $2 ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined __stub_$2 || defined __stub___$2
+choke me
+#endif
+
+int
+main ()
+{
+return $2 ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+ eval "$3=yes"
+else
+ eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_cxx_check_func
+
+# ac_fn_fc_try_compile LINENO
+# ---------------------------
+# Try to compile conftest.$ac_ext, and return whether this succeeded.
+ac_fn_fc_try_compile ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ rm -f conftest.$ac_objext
+ if { { ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compile") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && {
+ test -z "$ac_fc_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_fc_try_compile
+
+# ac_fn_f77_try_compile LINENO
+# ----------------------------
+# Try to compile conftest.$ac_ext, and return whether this succeeded.
+ac_fn_f77_try_compile ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ rm -f conftest.$ac_objext
+ if { { ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compile") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && {
+ test -z "$ac_f77_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_f77_try_compile
+
+# ac_fn_c_check_type LINENO TYPE VAR INCLUDES
+# -------------------------------------------
+# Tests whether TYPE exists after having included INCLUDES, setting cache
+# variable VAR accordingly.
+ac_fn_c_check_type ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ eval "$3=no"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+#ifdef FC_DUMMY_MAIN
+#ifndef FC_DUMMY_MAIN_EQ_F77
+# ifdef __cplusplus
+ extern "C"
+# endif
+ int FC_DUMMY_MAIN() { return 1; }
+#endif
+#endif
+int
+main ()
+{
+if (sizeof ($2))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+#ifdef FC_DUMMY_MAIN
+#ifndef FC_DUMMY_MAIN_EQ_F77
+# ifdef __cplusplus
+ extern "C"
+# endif
+ int FC_DUMMY_MAIN() { return 1; }
+#endif
+#endif
+int
+main ()
+{
+if (sizeof (($2)))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+ eval "$3=yes"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_type
+
+# ac_fn_c_try_cpp LINENO
+# ----------------------
+# Try to preprocess conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_cpp ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if { { ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } > conftest.i && {
+ test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ }; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_cpp
+
+# ac_fn_c_try_run LINENO
+# ----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes
+# that executables *can* be run.
+ac_fn_c_try_run ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && { ac_try='./conftest$ac_exeext'
+ { { case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: program exited with status $ac_status" >&5
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=$ac_status
+fi
+ rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_run
+
+# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES
+# -------------------------------------------------------
+# Tests whether HEADER exists and can be compiled using the include files in
+# INCLUDES, setting the cache variable VAR accordingly.
+ac_fn_c_check_header_compile ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ eval "$3=yes"
+else
+ eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_header_compile
+
+# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES
+# -------------------------------------------------------
+# Tests whether HEADER exists, giving a warning if it cannot be compiled using
+# the include files in INCLUDES and setting the cache variable VAR
+# accordingly.
+ac_fn_c_check_header_mongrel ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if eval \${$3+:} false; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+else
+ # Is the header compilable?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5
+$as_echo_n "checking $2 usability... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_header_compiler=yes
+else
+ ac_header_compiler=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5
+$as_echo "$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5
+$as_echo_n "checking $2 presence... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <$2>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+ ac_header_preproc=yes
+else
+ ac_header_preproc=no
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5
+$as_echo "$ac_header_preproc" >&6; }
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #((
+ yes:no: )
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5
+$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+ ;;
+ no:yes:* )
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5
+$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5
+$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5
+$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5
+$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+( $as_echo "## ------------------------------------------ ##
+## Report this to parallel-netcdf at mcs.anl.gov ##
+## ------------------------------------------ ##"
+ ) | sed "s/^/$as_me: WARNING: /" >&2
+ ;;
+esac
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ eval "$3=\$ac_header_compiler"
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+fi
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_header_mongrel
+
+# ac_fn_c_compute_int LINENO EXPR VAR INCLUDES
+# --------------------------------------------
+# Tries to find the compile-time value of EXPR in a program that includes
+# INCLUDES, setting VAR accordingly. Returns whether the value could be
+# computed
+ac_fn_c_compute_int ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if test "$cross_compiling" = yes; then
+ # Depending upon the size, compute the lo and hi bounds.
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+#ifdef FC_DUMMY_MAIN
+#ifndef FC_DUMMY_MAIN_EQ_F77
+# ifdef __cplusplus
+ extern "C"
+# endif
+ int FC_DUMMY_MAIN() { return 1; }
+#endif
+#endif
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) >= 0)];
+test_array [0] = 0;
+return test_array [0];
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_lo=0 ac_mid=0
+ while :; do
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+#ifdef FC_DUMMY_MAIN
+#ifndef FC_DUMMY_MAIN_EQ_F77
+# ifdef __cplusplus
+ extern "C"
+# endif
+ int FC_DUMMY_MAIN() { return 1; }
+#endif
+#endif
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) <= $ac_mid)];
+test_array [0] = 0;
+return test_array [0];
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_hi=$ac_mid; break
+else
+ as_fn_arith $ac_mid + 1 && ac_lo=$as_val
+ if test $ac_lo -le $ac_mid; then
+ ac_lo= ac_hi=
+ break
+ fi
+ as_fn_arith 2 '*' $ac_mid + 1 && ac_mid=$as_val
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ done
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+#ifdef FC_DUMMY_MAIN
+#ifndef FC_DUMMY_MAIN_EQ_F77
+# ifdef __cplusplus
+ extern "C"
+# endif
+ int FC_DUMMY_MAIN() { return 1; }
+#endif
+#endif
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) < 0)];
+test_array [0] = 0;
+return test_array [0];
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_hi=-1 ac_mid=-1
+ while :; do
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+#ifdef FC_DUMMY_MAIN
+#ifndef FC_DUMMY_MAIN_EQ_F77
+# ifdef __cplusplus
+ extern "C"
+# endif
+ int FC_DUMMY_MAIN() { return 1; }
+#endif
+#endif
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) >= $ac_mid)];
+test_array [0] = 0;
+return test_array [0];
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_lo=$ac_mid; break
+else
+ as_fn_arith '(' $ac_mid ')' - 1 && ac_hi=$as_val
+ if test $ac_mid -le $ac_hi; then
+ ac_lo= ac_hi=
+ break
+ fi
+ as_fn_arith 2 '*' $ac_mid && ac_mid=$as_val
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ done
+else
+ ac_lo= ac_hi=
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+# Binary search between lo and hi bounds.
+while test "x$ac_lo" != "x$ac_hi"; do
+ as_fn_arith '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo && ac_mid=$as_val
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+#ifdef FC_DUMMY_MAIN
+#ifndef FC_DUMMY_MAIN_EQ_F77
+# ifdef __cplusplus
+ extern "C"
+# endif
+ int FC_DUMMY_MAIN() { return 1; }
+#endif
+#endif
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) <= $ac_mid)];
+test_array [0] = 0;
+return test_array [0];
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_hi=$ac_mid
+else
+ as_fn_arith '(' $ac_mid ')' + 1 && ac_lo=$as_val
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+case $ac_lo in #((
+?*) eval "$3=\$ac_lo"; ac_retval=0 ;;
+'') ac_retval=1 ;;
+esac
+ else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+static long int longval () { return $2; }
+static unsigned long int ulongval () { return $2; }
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef FC_DUMMY_MAIN
+#ifndef FC_DUMMY_MAIN_EQ_F77
+# ifdef __cplusplus
+ extern "C"
+# endif
+ int FC_DUMMY_MAIN() { return 1; }
+#endif
+#endif
+int
+main ()
+{
+
+ FILE *f = fopen ("conftest.val", "w");
+ if (! f)
+ return 1;
+ if (($2) < 0)
+ {
+ long int i = longval ();
+ if (i != ($2))
+ return 1;
+ fprintf (f, "%ld", i);
+ }
+ else
+ {
+ unsigned long int i = ulongval ();
+ if (i != ($2))
+ return 1;
+ fprintf (f, "%lu", i);
+ }
+ /* Do not output a trailing newline, as this causes \r\n confusion
+ on some platforms. */
+ return ferror (f) || fclose (f) != 0;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ echo >>conftest.val; read $3 <conftest.val; ac_retval=0
+else
+ ac_retval=1
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+rm -f conftest.val
+
+ fi
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_c_compute_int
+cat >config.log <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by parallel-netcdf $as_me 1.7.0.pre1, which was
+generated by GNU Autoconf 2.69. Invocation command line was
+
+ $ $0 $@
+
+_ACEOF
+exec 5>>config.log
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown`
+
+/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown`
+/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown`
+/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown`
+/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown`
+/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ $as_echo "PATH: $as_dir"
+ done
+IFS=$as_save_IFS
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+ for ac_arg
+ do
+ case $ac_arg in
+ -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ continue ;;
+ *\'*)
+ ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ esac
+ case $ac_pass in
+ 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;;
+ 2)
+ as_fn_append ac_configure_args1 " '$ac_arg'"
+ if test $ac_must_keep_next = true; then
+ ac_must_keep_next=false # Got value, back to normal.
+ else
+ case $ac_arg in
+ *=* | --config-cache | -C | -disable-* | --disable-* \
+ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+ | -with-* | --with-* | -without-* | --without-* | --x)
+ case "$ac_configure_args0 " in
+ "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+ esac
+ ;;
+ -* ) ac_must_keep_next=true ;;
+ esac
+ fi
+ as_fn_append ac_configure_args " '$ac_arg'"
+ ;;
+ esac
+ done
+done
+{ ac_configure_args0=; unset ac_configure_args0;}
+{ ac_configure_args1=; unset ac_configure_args1;}
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log. We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Use '\'' to represent an apostrophe within the trap.
+# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
+trap 'exit_status=$?
+ # Save into config.log some information that might help in debugging.
+ {
+ echo
+
+ $as_echo "## ---------------- ##
+## Cache variables. ##
+## ---------------- ##"
+ echo
+ # The following way of writing the cache mishandles newlines in values,
+(
+ for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do
+ eval ac_val=\$$ac_var
+ case $ac_val in #(
+ *${as_nl}*)
+ case $ac_var in #(
+ *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+ esac
+ case $ac_var in #(
+ _ | IFS | as_nl) ;; #(
+ BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+ *) { eval $ac_var=; unset $ac_var;} ;;
+ esac ;;
+ esac
+ done
+ (set) 2>&1 |
+ case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #(
+ *${as_nl}ac_space=\ *)
+ sed -n \
+ "s/'\''/'\''\\\\'\'''\''/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p"
+ ;; #(
+ *)
+ sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+ ;;
+ esac |
+ sort
+)
+ echo
+
+ $as_echo "## ----------------- ##
+## Output variables. ##
+## ----------------- ##"
+ echo
+ for ac_var in $ac_subst_vars
+ do
+ eval ac_val=\$$ac_var
+ case $ac_val in
+ *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+ esac
+ $as_echo "$ac_var='\''$ac_val'\''"
+ done | sort
+ echo
+
+ if test -n "$ac_subst_files"; then
+ $as_echo "## ------------------- ##
+## File substitutions. ##
+## ------------------- ##"
+ echo
+ for ac_var in $ac_subst_files
+ do
+ eval ac_val=\$$ac_var
+ case $ac_val in
+ *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+ esac
+ $as_echo "$ac_var='\''$ac_val'\''"
+ done | sort
+ echo
+ fi
+
+ if test -s confdefs.h; then
+ $as_echo "## ----------- ##
+## confdefs.h. ##
+## ----------- ##"
+ echo
+ cat confdefs.h
+ echo
+ fi
+ test "$ac_signal" != 0 &&
+ $as_echo "$as_me: caught signal $ac_signal"
+ $as_echo "$as_me: exit $exit_status"
+ } >&5
+ rm -f core *.core core.conftest.* &&
+ rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
+ exit $exit_status
+' 0
+for ac_signal in 1 2 13 15; do
+ trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -f -r conftest* confdefs.h
+
+$as_echo "/* confdefs.h */" > confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_URL "$PACKAGE_URL"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer an explicitly selected file to automatically selected ones.
+ac_site_file1=NONE
+ac_site_file2=NONE
+if test -n "$CONFIG_SITE"; then
+ # We do not want a PATH search for config.site.
+ case $CONFIG_SITE in #((
+ -*) ac_site_file1=./$CONFIG_SITE;;
+ */*) ac_site_file1=$CONFIG_SITE;;
+ *) ac_site_file1=./$CONFIG_SITE;;
+ esac
+elif test "x$prefix" != xNONE; then
+ ac_site_file1=$prefix/share/config.site
+ ac_site_file2=$prefix/etc/config.site
+else
+ ac_site_file1=$ac_default_prefix/share/config.site
+ ac_site_file2=$ac_default_prefix/etc/config.site
+fi
+for ac_site_file in "$ac_site_file1" "$ac_site_file2"
+do
+ test "x$ac_site_file" = xNONE && continue
+ if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5
+$as_echo "$as_me: loading site script $ac_site_file" >&6;}
+ sed 's/^/| /' "$ac_site_file" >&5
+ . "$ac_site_file" \
+ || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "failed to load site script $ac_site_file
+See \`config.log' for more details" "$LINENO" 5; }
+ fi
+done
+
+if test -r "$cache_file"; then
+ # Some versions of bash will fail to source /dev/null (special files
+ # actually), so we avoid doing that. DJGPP emulates it as a regular file.
+ if test /dev/null != "$cache_file" && test -f "$cache_file"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5
+$as_echo "$as_me: loading cache $cache_file" >&6;}
+ case $cache_file in
+ [\\/]* | ?:[\\/]* ) . "$cache_file";;
+ *) . "./$cache_file";;
+ esac
+ fi
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5
+$as_echo "$as_me: creating cache $cache_file" >&6;}
+ >$cache_file
+fi
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in $ac_precious_vars; do
+ eval ac_old_set=\$ac_cv_env_${ac_var}_set
+ eval ac_new_set=\$ac_env_${ac_var}_set
+ eval ac_old_val=\$ac_cv_env_${ac_var}_value
+ eval ac_new_val=\$ac_env_${ac_var}_value
+ case $ac_old_set,$ac_new_set in
+ set,)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,set)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,);;
+ *)
+ if test "x$ac_old_val" != "x$ac_new_val"; then
+ # differences in whitespace do not lead to failure.
+ ac_old_val_w=`echo x $ac_old_val`
+ ac_new_val_w=`echo x $ac_new_val`
+ if test "$ac_old_val_w" != "$ac_new_val_w"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5
+$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+ ac_cache_corrupted=:
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5
+$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;}
+ eval $ac_var=\$ac_old_val
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5
+$as_echo "$as_me: former value: \`$ac_old_val'" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5
+$as_echo "$as_me: current value: \`$ac_new_val'" >&2;}
+ fi;;
+ esac
+ # Pass precious variables to config.status.
+ if test "$ac_new_set" = set; then
+ case $ac_new_val in
+ *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+ *) ac_arg=$ac_var=$ac_new_val ;;
+ esac
+ case " $ac_configure_args " in
+ *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy.
+ *) as_fn_append ac_configure_args " '$ac_arg'" ;;
+ esac
+ fi
+done
+if $ac_cache_corrupted; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5
+$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+ as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5
+fi
+## -------------------- ##
+## Main body of script. ##
+## -------------------- ##
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+ac_config_headers="$ac_config_headers src/lib/ncconfig.h"
+
+
+
+ac_aux_dir=
+for ac_dir in ./scripts "$srcdir"/./scripts; do
+ if test -f "$ac_dir/install-sh"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f "$ac_dir/install.sh"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ elif test -f "$ac_dir/shtool"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/shtool install -c"
+ break
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ as_fn_error $? "cannot find install-sh, install.sh, or shtool in ./scripts \"$srcdir\"/./scripts" "$LINENO" 5
+fi
+
+# These three variables are undocumented and unsupported,
+# and are intended to be withdrawn in a future Autoconf release.
+# They can cause serious problems if a builder's source tree is in a directory
+# whose full name contains unusual characters.
+ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var.
+ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var.
+ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var.
+
+
+
+CONFIGURE_ARGS_CLEAN=`echo $* | tr '"' ' '`
+
+PNETCDF_VERSION_MAJOR=`echo ${PACKAGE_VERSION} | cut -d. -f1`
+PNETCDF_VERSION_MINOR=`echo ${PACKAGE_VERSION} | cut -d. -f2`
+PNETCDF_VERSION_SUB=`echo ${PACKAGE_VERSION} | cut -d. -f3`
+PNETCDF_VERSION_PRE=`echo ${PACKAGE_VERSION} | cut -d. -f4`
+
+PNETCDF_VERSION=${PACKAGE_VERSION}
+
+SVN_DATE="$LastChangedDate: 2016-01-12 12:39:01 -0600 (Tue, 12 Jan 2016) $"
+PNETCDF_RELEASE_DATE2=`echo $SVN_DATE | cut -d' ' -f2`
+PNETCDF_RELEASE_DATE=`echo $SVN_DATE | cut -d' ' -f6,7,8 | cut -d')' -f1`
+
+_DEBUG=no
+
+
+if test "x${_DEBUG}" = xyes ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: DEBUG: PNETCDF_VERSION_MAJOR=$PNETCDF_VERSION_MAJOR" >&5
+$as_echo "$as_me: DEBUG: PNETCDF_VERSION_MAJOR=$PNETCDF_VERSION_MAJOR" >&6;}
+ fi
+
+
+if test "x${_DEBUG}" = xyes ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: DEBUG: PNETCDF_VERSION_MINOR=$PNETCDF_VERSION_MINOR" >&5
+$as_echo "$as_me: DEBUG: PNETCDF_VERSION_MINOR=$PNETCDF_VERSION_MINOR" >&6;}
+ fi
+
+
+if test "x${_DEBUG}" = xyes ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: DEBUG: PNETCDF_VERSION_SUB=$PNETCDF_VERSION_SUB" >&5
+$as_echo "$as_me: DEBUG: PNETCDF_VERSION_SUB=$PNETCDF_VERSION_SUB" >&6;}
+ fi
+
+
+if test "x${_DEBUG}" = xyes ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: DEBUG: PNETCDF_VERSION_PRE=$PNETCDF_VERSION_PRE" >&5
+$as_echo "$as_me: DEBUG: PNETCDF_VERSION_PRE=$PNETCDF_VERSION_PRE" >&6;}
+ fi
+
+
+if test "x${_DEBUG}" = xyes ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: DEBUG: PNETCDF_VERSION=$PNETCDF_VERSION" >&5
+$as_echo "$as_me: DEBUG: PNETCDF_VERSION=$PNETCDF_VERSION" >&6;}
+ fi
+
+
+if test "x${_DEBUG}" = xyes ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: DEBUG: PNETCDF_RELEASE_DATE=$PNETCDF_RELEASE_DATE" >&5
+$as_echo "$as_me: DEBUG: PNETCDF_RELEASE_DATE=$PNETCDF_RELEASE_DATE" >&6;}
+ fi
+
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define PNETCDF_VERSION_MAJOR $PNETCDF_VERSION_MAJOR
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PNETCDF_VERSION_MINOR $PNETCDF_VERSION_MINOR
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PNETCDF_VERSION_SUB $PNETCDF_VERSION_SUB
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PNETCDF_VERSION_PRE $PNETCDF_VERSION_PRE
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PNETCDF_VERSION "$PNETCDF_VERSION"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PNETCDF_RELEASE_DATE "$PNETCDF_RELEASE_DATE"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define CONFIGURE_ARGS_CLEAN "$CONFIGURE_ARGS_CLEAN"
+_ACEOF
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+if test "x${RM}" != x ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking rm " >&5
+$as_echo_n "checking rm ... " >&6; }
+ if ! test -f ${RM} ; then
+ # Extract the first word of "${RM}", so it can be a program name with args.
+set dummy ${RM}; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_rm_cmd+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$rm_cmd"; then
+ ac_cv_prog_rm_cmd="$rm_cmd" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_rm_cmd="yes"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ test -z "$ac_cv_prog_rm_cmd" && ac_cv_prog_rm_cmd="no"
+fi
+fi
+rm_cmd=$ac_cv_prog_rm_cmd
+if test -n "$rm_cmd"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $rm_cmd" >&5
+$as_echo "$rm_cmd" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ if test "x${rm_cmd}" = xyes ; then
+ RM=${RM}
+ fi
+ else
+ RM=${RM}
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: using $RM" >&5
+$as_echo "using $RM" >&6; }
+else
+ RM="rm"
+fi
+
+
+# Check whether --enable-echo was given.
+if test "${enable_echo+set}" = set; then :
+ enableval=$enable_echo; set -x
+
+fi
+
+
+MPI_INSTALL=
+
+# Check whether --with-mpi was given.
+if test "${with_mpi+set}" = set; then :
+ withval=$with_mpi; if test x"$withval" = xyes; then
+ as_fn_error $? "--with-mpi must be given a pathname" "$LINENO" 5
+ else
+ MPI_INSTALL=${withval}
+ fi
+
+fi
+
+if test "x${MPI_INSTALL}" != x && (! test -d "${MPI_INSTALL}") ; then
+ as_fn_error $? "Directory '${MPI_INSTALL}' specified in --with-mpi does not exist" "$LINENO" 5
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+if test "x$MPICC" = x && test "x$CC" != x ; then MPICC=$CC ; fi
+if test "x$MPICXX" = x && test "x$CXX" != x ; then MPICXX=$CXX ; fi
+if test "x$MPIF77" = x && test "x$F77" != x ; then MPIF77=$F77 ; fi
+if test "x$MPIF77" = x && test "x$FC" != x ; then MPIF77=$FC ; fi
+if test "x$MPIF90" = x && test "x$F90" != x ; then MPIF90=$F90 ; fi
+if test "x$MPIF90" = x && test "x$FC" != x ; then MPIF90=$FC ; fi
+
+CANDIDATE_MPICC="${MPICC} mpicc"
+CANDIDATE_MPICXX="${MPICXX} mpicxx mpic++ mpiCC"
+CANDIDATE_MPIF77="${MPIF77} mpif77"
+CANDIDATE_MPIF90="${MPIF90} mpif90"
+
+CANDIDATE_MPICC="${CANDIDATE_MPICC} mpcc_r mpcc mpixlc_r mpixlc"
+CANDIDATE_MPICXX="${CANDIDATE_MPICXX} mpCC_r mpCC mpixlcxx_r mpixlcxx mpixlC_r mpixlC"
+CANDIDATE_MPIF77="${CANDIDATE_MPIF77} mpixlf77_r mpixlf77"
+CANDIDATE_MPIF90="${CANDIDATE_MPIF90} mpixlf90_r mpixlf90"
+
+CANDIDATE_MPICC="${CANDIDATE_MPICC} blrts_xlc mpxlc_r mpxlc"
+CANDIDATE_MPICXX="${CANDIDATE_MPICXX} blrts_xlC mpxlC_r mpxlC"
+CANDIDATE_MPIF77="${CANDIDATE_MPIF77} blrts_xlf mpxlf_r mpxlf"
+CANDIDATE_MPIF90="${CANDIDATE_MPIF90} blrts_xlf90 mpxlf90_r mpxlf90 mpxlf95_r mpxlf95"
+
+CANDIDATE_MPICC="${CANDIDATE_MPICC} mpifccpx"
+CANDIDATE_MPICXX="${CANDIDATE_MPICXX} mpiFCCpx"
+CANDIDATE_MPIF77="${CANDIDATE_MPIF77} mpifrtpx"
+CANDIDATE_MPIF90="${CANDIDATE_MPIF90} mpifrtpx"
+
+CANDIDATE_MPICC="${CANDIDATE_MPICC} cc"
+CANDIDATE_MPICXX="${CANDIDATE_MPICXX} CC"
+CANDIDATE_MPIF77="${CANDIDATE_MPIF77} ftn"
+CANDIDATE_MPIF90="${CANDIDATE_MPIF90} ftn"
+
+CANDIDATE_MPICC="${CANDIDATE_MPICC} mpiicc icc"
+CANDIDATE_MPICXX="${CANDIDATE_MPICXX} mpiicpc icpc"
+CANDIDATE_MPIF77="${CANDIDATE_MPIF77} mpiifort mpiifc ifort"
+CANDIDATE_MPIF90="${CANDIDATE_MPIF90} mpiifort mpiifc ifort"
+
+
+ if test "x$MPI_INSTALL" != x ; then
+ if test "x${_DEBUG}" = xyes ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: DEBUG: --with-mpi=$MPI_INSTALL is used" >&5
+$as_echo "$as_me: DEBUG: --with-mpi=$MPI_INSTALL is used" >&6;}
+ fi
+
+
+ if test "x$MPICC" = x ; then
+ if test "x$MPICC" = x && (test -d "${MPI_INSTALL}/bin") ; then
+ if test "x${_DEBUG}" = xyes ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: DEBUG: search possible MPICC under $MPI_INSTALL/bin" >&5
+$as_echo "$as_me: DEBUG: search possible MPICC under $MPI_INSTALL/bin" >&6;}
+ fi
+
+
+ for ac_prog in $CANDIDATE_MPICC
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_MPICC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $MPICC in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_MPICC="$MPICC" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $MPI_INSTALL/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_MPICC="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+MPICC=$ac_cv_path_MPICC
+if test -n "$MPICC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MPICC" >&5
+$as_echo "$MPICC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$MPICC" && break
+done
+
+ fi
+ if test "x$MPICC" = x ; then
+ if test "x${_DEBUG}" = xyes ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: DEBUG: search possible MPICC under $MPI_INSTALL" >&5
+$as_echo "$as_me: DEBUG: search possible MPICC under $MPI_INSTALL" >&6;}
+ fi
+
+
+ for ac_prog in $CANDIDATE_MPICC
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_MPICC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $MPICC in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_MPICC="$MPICC" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $MPI_INSTALL
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_MPICC="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+MPICC=$ac_cv_path_MPICC
+if test -n "$MPICC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MPICC" >&5
+$as_echo "$MPICC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$MPICC" && break
+done
+
+ fi
+ else
+ if test "x${_DEBUG}" = xyes ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: DEBUG: check if file $MPICC exists" >&5
+$as_echo "$as_me: DEBUG: check if file $MPICC exists" >&6;}
+ fi
+
+
+ if ! test -f "$MPICC" ; then
+ if test "x${_DEBUG}" = xyes ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: DEBUG: File MPICC= $MPICC cannot be found ... check under $MPI_INSTALL" >&5
+$as_echo "$as_me: DEBUG: File MPICC= $MPICC cannot be found ... check under $MPI_INSTALL" >&6;}
+ fi
+
+
+ if test -f "$MPI_INSTALL/$MPICC" ; then
+ if test "x${_DEBUG}" = xyes ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: DEBUG: File MPICC= $MPICC is found under $MPI_INSTALL" >&5
+$as_echo "$as_me: DEBUG: File MPICC= $MPICC is found under $MPI_INSTALL" >&6;}
+ fi
+
+
+ MPICC="$MPI_INSTALL/$MPICC"
+ elif test -f "$MPI_INSTALL/bin/$MPICC" ; then
+ if test "x${_DEBUG}" = xyes ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: DEBUG: File MPICC= $MPICC is found under $MPI_INSTALL/bin" >&5
+$as_echo "$as_me: DEBUG: File MPICC= $MPICC is found under $MPI_INSTALL/bin" >&6;}
+ fi
+
+
+ MPICC="$MPI_INSTALL/bin/$MPICC"
+ else
+ if test "x${_DEBUG}" = xyes ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: DEBUG: File MPICC= $MPICC cannot be found under $MPI_INSTALL" >&5
+$as_echo "$as_me: DEBUG: File MPICC= $MPICC cannot be found under $MPI_INSTALL" >&6;}
+ fi
+
+
+ MPICC=
+ fi
+ fi
+ fi
+ else
+ if test "x${_DEBUG}" = xyes ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: DEBUG: --with-mpi=$MPI_INSTALL is NOT used" >&5
+$as_echo "$as_me: DEBUG: --with-mpi=$MPI_INSTALL is NOT used" >&6;}
+ fi
+
+
+ if test "x${_DEBUG}" = xyes ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: DEBUG: check if MPICC is defined. If yes, check if file exists" >&5
+$as_echo "$as_me: DEBUG: check if MPICC is defined. If yes, check if file exists" >&6;}
+ fi
+
+
+ if test "x$MPICC" != x && (! test -f "$MPICC") ; then
+ if test "x${_DEBUG}" = xyes ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: DEBUG: check if file $MPICC exists under user's PATH" >&5
+$as_echo "$as_me: DEBUG: check if file $MPICC exists under user's PATH" >&6;}
+ fi
+
+
+ for ac_prog in $MPICC
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_MPICC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $MPICC in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_MPICC="$MPICC" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_MPICC="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+MPICC=$ac_cv_path_MPICC
+if test -n "$MPICC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MPICC" >&5
+$as_echo "$MPICC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$MPICC" && break
+done
+
+ fi
+ fi
+ if test "x$MPICC" = x ; then
+ if test "x${_DEBUG}" = xyes ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: DEBUG: find possible MPICC under user's PATH" >&5
+$as_echo "$as_me: DEBUG: find possible MPICC under user's PATH" >&6;}
+ fi
+
+
+ for ac_prog in $CANDIDATE_MPICC
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_MPICC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $MPICC in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_MPICC="$MPICC" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_MPICC="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+MPICC=$ac_cv_path_MPICC
+if test -n "$MPICC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MPICC" >&5
+$as_echo "$MPICC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$MPICC" && break
+done
+
+ fi
+
+if test "x${MPICC}" = x ; then
+ as_fn_error $? "
+ -----------------------------------------------------------------------
+ No MPI C compiler can be found. Parallel netCDF requires an MPI C
+ compiler. Please specify the location of one either with the MPICC
+ environment variable or the --with-mpi configure flag
+ -----------------------------------------------------------------------" "$LINENO" 5
+fi
+
+CC=${MPICC}
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="${ac_tool_prefix}gcc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+ ac_ct_CC=$CC
+ # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CC="gcc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_CC" = x; then
+ CC=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CC=$ac_ct_CC
+ fi
+else
+ CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="${ac_tool_prefix}cc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ fi
+fi
+if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+if test $ac_prog_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $ac_cv_prog_CC
+ shift
+ if test $# != 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+ ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+ fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in cl.exe
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$CC" && break
+ done
+fi
+if test -z "$CC"; then
+ ac_ct_CC=$CC
+ for ac_prog in cl.exe
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CC="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$ac_ct_CC" && break
+done
+
+ if test "x$ac_ct_CC" = x; then
+ CC=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CC=$ac_ct_CC
+ fi
+fi
+
+fi
+
+
+test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "no acceptable C compiler found in \$PATH
+See \`config.log' for more details" "$LINENO" 5; }
+
+# Provide some information about the compiler.
+$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion; do
+ { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compiler $ac_option >&5") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ sed '10a\
+... rest of stderr output deleted ...
+ 10q' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ fi
+ rm -f conftest.er1 conftest.err
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+done
+
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5
+$as_echo_n "checking whether the C compiler works... " >&6; }
+ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+
+# The possible output files:
+ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*"
+
+ac_rmfiles=
+for ac_file in $ac_files
+do
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+ * ) ac_rmfiles="$ac_rmfiles $ac_file";;
+ esac
+done
+rm -f $ac_rmfiles
+
+if { { ac_try="$ac_link_default"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link_default") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then :
+ # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.
+# So ignore a value of `no', otherwise this would lead to `EXEEXT = no'
+# in a Makefile. We should not override ac_cv_exeext if it was cached,
+# so that the user can short-circuit this test for compilers unknown to
+# Autoconf.
+for ac_file in $ac_files ''
+do
+ test -f "$ac_file" || continue
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj )
+ ;;
+ [ab].out )
+ # We found the default executable, but exeext='' is most
+ # certainly right.
+ break;;
+ *.* )
+ if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no;
+ then :; else
+ ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+ fi
+ # We set ac_cv_exeext here because the later test for it is not
+ # safe: cross compilers may not add the suffix if given an `-o'
+ # argument, so we may need to know it at that point already.
+ # Even if this section looks crufty: it has the advantage of
+ # actually working.
+ break;;
+ * )
+ break;;
+ esac
+done
+test "$ac_cv_exeext" = no && ac_cv_exeext=
+
+else
+ ac_file=''
+fi
+if test -z "$ac_file"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+$as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "C compiler cannot create executables
+See \`config.log' for more details" "$LINENO" 5; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5
+$as_echo_n "checking for C compiler default output file name... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5
+$as_echo "$ac_file" >&6; }
+ac_exeext=$ac_cv_exeext
+
+rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5
+$as_echo_n "checking for suffix of executables... " >&6; }
+if { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then :
+ # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+ test -f "$ac_file" || continue
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+ *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+ break;;
+ * ) break;;
+ esac
+done
+else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+rm -f conftest conftest$ac_cv_exeext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
+$as_echo "$ac_cv_exeext" >&6; }
+
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdio.h>
+int
+main ()
+{
+FILE *f = fopen ("conftest.out", "w");
+ return ferror (f) || fclose (f) != 0;
+
+ ;
+ return 0;
+}
+_ACEOF
+ac_clean_files="$ac_clean_files conftest.out"
+# Check that the compiler produces executables we can run. If not, either
+# the compiler is broken, or we cross compile.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5
+$as_echo_n "checking whether we are cross compiling... " >&6; }
+if test "$cross_compiling" != yes; then
+ { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ if { ac_try='./conftest$ac_cv_exeext'
+ { { case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then
+ cross_compiling=no
+ else
+ if test "$cross_compiling" = maybe; then
+ cross_compiling=yes
+ else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details" "$LINENO" 5; }
+ fi
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5
+$as_echo "$cross_compiling" >&6; }
+
+rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out
+ac_clean_files=$ac_clean_files_save
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5
+$as_echo_n "checking for suffix of object files... " >&6; }
+if ${ac_cv_objext+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { { ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compile") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then :
+ for ac_file in conftest.o conftest.obj conftest.*; do
+ test -f "$ac_file" || continue;
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;;
+ *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+ break;;
+ esac
+done
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot compute suffix of object files: cannot compile
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5
+$as_echo "$ac_cv_objext" >&6; }
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5
+$as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
+if ${ac_cv_c_compiler_gnu+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+#ifndef __GNUC__
+ choke me
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_compiler_gnu=yes
+else
+ ac_compiler_gnu=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
+$as_echo "$ac_cv_c_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+ GCC=yes
+else
+ GCC=
+fi
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
+$as_echo_n "checking whether $CC accepts -g... " >&6; }
+if ${ac_cv_prog_cc_g+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_save_c_werror_flag=$ac_c_werror_flag
+ ac_c_werror_flag=yes
+ ac_cv_prog_cc_g=no
+ CFLAGS="-g"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_g=yes
+else
+ CFLAGS=""
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+ ac_c_werror_flag=$ac_save_c_werror_flag
+ CFLAGS="-g"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_g=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_c_werror_flag=$ac_save_c_werror_flag
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
+$as_echo "$ac_cv_prog_cc_g" >&6; }
+if test "$ac_test_CFLAGS" = set; then
+ CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+ if test "$GCC" = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-g"
+ fi
+else
+ if test "$GCC" = yes; then
+ CFLAGS="-O2"
+ else
+ CFLAGS=
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
+$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
+if ${ac_cv_prog_cc_c89+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_prog_cc_c89=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdarg.h>
+#include <stdio.h>
+struct stat;
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+ char **p;
+ int i;
+{
+ return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+ char *s;
+ va_list v;
+ va_start (v,p);
+ s = g (p, va_arg (v,int));
+ va_end (v);
+ return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has
+ function prototypes and stuff, but not '\xHH' hex character constants.
+ These don't provoke an error unfortunately, instead are silently treated
+ as 'x'. The following induces an error, until -std is added to get
+ proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an
+ array size at least. It's necessary to write '\x00'==0 to get something
+ that's true only with -std. */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
+ inside strings and character constants. */
+#define FOO(x) 'x'
+int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1];
+ ;
+ return 0;
+}
+_ACEOF
+for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
+ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+ CC="$ac_save_CC $ac_arg"
+ if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_c89=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext
+ test "x$ac_cv_prog_cc_c89" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+
+fi
+# AC_CACHE_VAL
+case "x$ac_cv_prog_cc_c89" in
+ x)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+$as_echo "none needed" >&6; } ;;
+ xno)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+$as_echo "unsupported" >&6; } ;;
+ *)
+ CC="$CC $ac_cv_prog_cc_c89"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
+$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
+esac
+if test "x$ac_cv_prog_cc_c89" != xno; then :
+
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+
+# Check whether --enable-largefile was given.
+if test "${enable_largefile+set}" = set; then :
+ enableval=$enable_largefile;
+fi
+
+if test "$enable_largefile" != no; then
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for special C compiler options needed for large files" >&5
+$as_echo_n "checking for special C compiler options needed for large files... " >&6; }
+if ${ac_cv_sys_largefile_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_sys_largefile_CC=no
+ if test "$GCC" != yes; then
+ ac_save_CC=$CC
+ while :; do
+ # IRIX 6.2 and later do not support large files by default,
+ # so use the C compiler's -n32 option if that helps.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h>
+ /* Check that off_t can represent 2**63 - 1 correctly.
+ We can't simply define LARGE_OFF_T to be 9223372036854775807,
+ since some C++ compilers masquerading as C compilers
+ incorrectly reject 9223372036854775807. */
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+ int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+ && LARGE_OFF_T % 2147483647 == 1)
+ ? 1 : -1];
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+ if ac_fn_c_try_compile "$LINENO"; then :
+ break
+fi
+rm -f core conftest.err conftest.$ac_objext
+ CC="$CC -n32"
+ if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_sys_largefile_CC=' -n32'; break
+fi
+rm -f core conftest.err conftest.$ac_objext
+ break
+ done
+ CC=$ac_save_CC
+ rm -f conftest.$ac_ext
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_largefile_CC" >&5
+$as_echo "$ac_cv_sys_largefile_CC" >&6; }
+ if test "$ac_cv_sys_largefile_CC" != no; then
+ CC=$CC$ac_cv_sys_largefile_CC
+ fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _FILE_OFFSET_BITS value needed for large files" >&5
+$as_echo_n "checking for _FILE_OFFSET_BITS value needed for large files... " >&6; }
+if ${ac_cv_sys_file_offset_bits+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ while :; do
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h>
+ /* Check that off_t can represent 2**63 - 1 correctly.
+ We can't simply define LARGE_OFF_T to be 9223372036854775807,
+ since some C++ compilers masquerading as C compilers
+ incorrectly reject 9223372036854775807. */
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+ int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+ && LARGE_OFF_T % 2147483647 == 1)
+ ? 1 : -1];
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_sys_file_offset_bits=no; break
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#define _FILE_OFFSET_BITS 64
+#include <sys/types.h>
+ /* Check that off_t can represent 2**63 - 1 correctly.
+ We can't simply define LARGE_OFF_T to be 9223372036854775807,
+ since some C++ compilers masquerading as C compilers
+ incorrectly reject 9223372036854775807. */
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+ int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+ && LARGE_OFF_T % 2147483647 == 1)
+ ? 1 : -1];
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_sys_file_offset_bits=64; break
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_cv_sys_file_offset_bits=unknown
+ break
+done
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_file_offset_bits" >&5
+$as_echo "$ac_cv_sys_file_offset_bits" >&6; }
+case $ac_cv_sys_file_offset_bits in #(
+ no | unknown) ;;
+ *)
+cat >>confdefs.h <<_ACEOF
+#define _FILE_OFFSET_BITS $ac_cv_sys_file_offset_bits
+_ACEOF
+;;
+esac
+rm -rf conftest*
+ if test $ac_cv_sys_file_offset_bits = unknown; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _LARGE_FILES value needed for large files" >&5
+$as_echo_n "checking for _LARGE_FILES value needed for large files... " >&6; }
+if ${ac_cv_sys_large_files+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ while :; do
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h>
+ /* Check that off_t can represent 2**63 - 1 correctly.
+ We can't simply define LARGE_OFF_T to be 9223372036854775807,
+ since some C++ compilers masquerading as C compilers
+ incorrectly reject 9223372036854775807. */
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+ int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+ && LARGE_OFF_T % 2147483647 == 1)
+ ? 1 : -1];
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_sys_large_files=no; break
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#define _LARGE_FILES 1
+#include <sys/types.h>
+ /* Check that off_t can represent 2**63 - 1 correctly.
+ We can't simply define LARGE_OFF_T to be 9223372036854775807,
+ since some C++ compilers masquerading as C compilers
+ incorrectly reject 9223372036854775807. */
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+ int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+ && LARGE_OFF_T % 2147483647 == 1)
+ ? 1 : -1];
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_sys_large_files=1; break
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_cv_sys_large_files=unknown
+ break
+done
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_large_files" >&5
+$as_echo "$ac_cv_sys_large_files" >&6; }
+case $ac_cv_sys_large_files in #(
+ no | unknown) ;;
+ *)
+cat >>confdefs.h <<_ACEOF
+#define _LARGE_FILES $ac_cv_sys_large_files
+_ACEOF
+;;
+esac
+rm -rf conftest*
+ fi
+
+
+fi
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to make dependencies" >&5
+$as_echo_n "checking how to make dependencies... " >&6; }
+ case `uname -s` in
+ IRIX*|OSF1)
+ CC_MAKEDEPEND='cc -M'
+ ;;
+ SunOS)
+ case `uname -r` in
+ 4*)
+ CC_MAKEDEPEND='cc -M'
+ ;;
+ 5*|*)
+ CC_MAKEDEPEND='cc -xM'
+ ;;
+ esac
+ ;;
+ ULTRIX)
+ case `uname -m` in
+ RISC)
+ CC_MAKEDEPEND='cc -M'
+ ;;
+ VAX) # Can't handle prototypes in netcdf.h
+ ;;
+ esac
+ ;;
+ AIX) # Writes to .u files rather than standard out
+ ;;
+ HP-UX) # Writes escaped newlines to standard error
+ ;;
+ esac
+ case "${CC_MAKEDEPEND}" in
+ '')
+ CC_MAKEDEPEND=false
+ ;;
+ esac
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC_MAKEDEPEND" >&5
+$as_echo "$CC_MAKEDEPEND" >&6; }
+
+
+
+
+# check if MPICC works for basic MPI call: MPI_Comm_rank()
+ac_fn_c_check_func "$LINENO" "MPI_Comm_rank" "ac_cv_func_MPI_Comm_rank"
+if test "x$ac_cv_func_MPI_Comm_rank" = xyes; then :
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing MPI_Comm_rank" >&5
+$as_echo_n "checking for library containing MPI_Comm_rank... " >&6; }
+if ${ac_cv_search_MPI_Comm_rank+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char MPI_Comm_rank ();
+int
+main ()
+{
+return MPI_Comm_rank ();
+ ;
+ return 0;
+}
+_ACEOF
+for ac_lib in '' mpi mpich; do
+ if test -z "$ac_lib"; then
+ ac_res="none required"
+ else
+ ac_res=-l$ac_lib
+ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
+ fi
+ if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_search_MPI_Comm_rank=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext
+ if ${ac_cv_search_MPI_Comm_rank+:} false; then :
+ break
+fi
+done
+if ${ac_cv_search_MPI_Comm_rank+:} false; then :
+
+else
+ ac_cv_search_MPI_Comm_rank=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_MPI_Comm_rank" >&5
+$as_echo "$ac_cv_search_MPI_Comm_rank" >&6; }
+ac_res=$ac_cv_search_MPI_Comm_rank
+if test "$ac_res" != no; then :
+ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+else
+ as_fn_error $? "
+ ------------------------------------------------------------
+ Invalid MPI compiler specified or detected: \"${MPICC}\"
+ A working MPI compiler is required. Please specify the location
+ of one either with the MPICC environment variable or the
+ --with-mpi configure flag
+ ------------------------------------------------------------" "$LINENO" 5
+
+fi
+
+fi
+
+
+
+# Check whether --enable-mpi-io-test was given.
+if test "${enable_mpi_io_test+set}" = set; then :
+ enableval=$enable_mpi_io_test; enable_mpi_io_test=${enableval}
+else
+ enable_mpi_io_test=yes
+
+fi
+
+
+if test "x${enable_mpi_io_test}" = xyes ; then
+ ac_fn_c_check_func "$LINENO" "MPI_File_open" "ac_cv_func_MPI_File_open"
+if test "x$ac_cv_func_MPI_File_open" = xyes; then :
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing MPI_File_open" >&5
+$as_echo_n "checking for library containing MPI_File_open... " >&6; }
+if ${ac_cv_search_MPI_File_open+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char MPI_File_open ();
+int
+main ()
+{
+return MPI_File_open ();
+ ;
+ return 0;
+}
+_ACEOF
+for ac_lib in '' mpio; do
+ if test -z "$ac_lib"; then
+ ac_res="none required"
+ else
+ ac_res=-l$ac_lib
+ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
+ fi
+ if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_search_MPI_File_open=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext
+ if ${ac_cv_search_MPI_File_open+:} false; then :
+ break
+fi
+done
+if ${ac_cv_search_MPI_File_open+:} false; then :
+
+else
+ ac_cv_search_MPI_File_open=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_MPI_File_open" >&5
+$as_echo "$ac_cv_search_MPI_File_open" >&6; }
+ac_res=$ac_cv_search_MPI_File_open
+if test "$ac_res" != no; then :
+ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+else
+ as_fn_error $? "
+ ------------------------------------------------------------
+ MPI implementation does not support MPI-IO
+ PnetCDF requires MPI-IO support to work properly.
+ ------------------------------------------------------------" "$LINENO" 5
+
+fi
+
+fi
+
+fi
+
+# Check whether --enable-cxx was given.
+if test "${enable_cxx+set}" = set; then :
+ enableval=$enable_cxx; enable_cxx=${enableval}
+else
+ enable_cxx=auto
+
+fi
+
+
+if test "x${enable_cxx}" != xno ; then
+
+ if test "x$MPI_INSTALL" != x ; then
+ if test "x${_DEBUG}" = xyes ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: DEBUG: --with-mpi=$MPI_INSTALL is used" >&5
+$as_echo "$as_me: DEBUG: --with-mpi=$MPI_INSTALL is used" >&6;}
+ fi
+
+
+ if test "x$MPICXX" = x ; then
+ if test "x$MPICXX" = x && (test -d "${MPI_INSTALL}/bin") ; then
+ if test "x${_DEBUG}" = xyes ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: DEBUG: search possible MPICXX under $MPI_INSTALL/bin" >&5
+$as_echo "$as_me: DEBUG: search possible MPICXX under $MPI_INSTALL/bin" >&6;}
+ fi
+
+
+ for ac_prog in $CANDIDATE_MPICXX
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_MPICXX+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $MPICXX in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_MPICXX="$MPICXX" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $MPI_INSTALL/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_MPICXX="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+MPICXX=$ac_cv_path_MPICXX
+if test -n "$MPICXX"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MPICXX" >&5
+$as_echo "$MPICXX" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$MPICXX" && break
+done
+
+ fi
+ if test "x$MPICXX" = x ; then
+ if test "x${_DEBUG}" = xyes ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: DEBUG: search possible MPICXX under $MPI_INSTALL" >&5
+$as_echo "$as_me: DEBUG: search possible MPICXX under $MPI_INSTALL" >&6;}
+ fi
+
+
+ for ac_prog in $CANDIDATE_MPICXX
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_MPICXX+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $MPICXX in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_MPICXX="$MPICXX" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $MPI_INSTALL
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_MPICXX="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+MPICXX=$ac_cv_path_MPICXX
+if test -n "$MPICXX"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MPICXX" >&5
+$as_echo "$MPICXX" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$MPICXX" && break
+done
+
+ fi
+ else
+ if test "x${_DEBUG}" = xyes ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: DEBUG: check if file $MPICXX exists" >&5
+$as_echo "$as_me: DEBUG: check if file $MPICXX exists" >&6;}
+ fi
+
+
+ if ! test -f "$MPICXX" ; then
+ if test "x${_DEBUG}" = xyes ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: DEBUG: File MPICXX= $MPICXX cannot be found ... check under $MPI_INSTALL" >&5
+$as_echo "$as_me: DEBUG: File MPICXX= $MPICXX cannot be found ... check under $MPI_INSTALL" >&6;}
+ fi
+
+
+ if test -f "$MPI_INSTALL/$MPICXX" ; then
+ if test "x${_DEBUG}" = xyes ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: DEBUG: File MPICXX= $MPICXX is found under $MPI_INSTALL" >&5
+$as_echo "$as_me: DEBUG: File MPICXX= $MPICXX is found under $MPI_INSTALL" >&6;}
+ fi
+
+
+ MPICXX="$MPI_INSTALL/$MPICXX"
+ elif test -f "$MPI_INSTALL/bin/$MPICXX" ; then
+ if test "x${_DEBUG}" = xyes ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: DEBUG: File MPICXX= $MPICXX is found under $MPI_INSTALL/bin" >&5
+$as_echo "$as_me: DEBUG: File MPICXX= $MPICXX is found under $MPI_INSTALL/bin" >&6;}
+ fi
+
+
+ MPICXX="$MPI_INSTALL/bin/$MPICXX"
+ else
+ if test "x${_DEBUG}" = xyes ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: DEBUG: File MPICXX= $MPICXX cannot be found under $MPI_INSTALL" >&5
+$as_echo "$as_me: DEBUG: File MPICXX= $MPICXX cannot be found under $MPI_INSTALL" >&6;}
+ fi
+
+
+ MPICXX=
+ fi
+ fi
+ fi
+ else
+ if test "x${_DEBUG}" = xyes ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: DEBUG: --with-mpi=$MPI_INSTALL is NOT used" >&5
+$as_echo "$as_me: DEBUG: --with-mpi=$MPI_INSTALL is NOT used" >&6;}
+ fi
+
+
+ if test "x${_DEBUG}" = xyes ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: DEBUG: check if MPICXX is defined. If yes, check if file exists" >&5
+$as_echo "$as_me: DEBUG: check if MPICXX is defined. If yes, check if file exists" >&6;}
+ fi
+
+
+ if test "x$MPICXX" != x && (! test -f "$MPICXX") ; then
+ if test "x${_DEBUG}" = xyes ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: DEBUG: check if file $MPICXX exists under user's PATH" >&5
+$as_echo "$as_me: DEBUG: check if file $MPICXX exists under user's PATH" >&6;}
+ fi
+
+
+ for ac_prog in $MPICXX
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_MPICXX+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $MPICXX in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_MPICXX="$MPICXX" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_MPICXX="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+MPICXX=$ac_cv_path_MPICXX
+if test -n "$MPICXX"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MPICXX" >&5
+$as_echo "$MPICXX" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$MPICXX" && break
+done
+
+ fi
+ fi
+ if test "x$MPICXX" = x ; then
+ if test "x${_DEBUG}" = xyes ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: DEBUG: find possible MPICXX under user's PATH" >&5
+$as_echo "$as_me: DEBUG: find possible MPICXX under user's PATH" >&6;}
+ fi
+
+
+ for ac_prog in $CANDIDATE_MPICXX
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_MPICXX+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $MPICXX in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_MPICXX="$MPICXX" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_MPICXX="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+MPICXX=$ac_cv_path_MPICXX
+if test -n "$MPICXX"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MPICXX" >&5
+$as_echo "$MPICXX" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$MPICXX" && break
+done
+
+ fi
+
+
+ if test "x${MPICXX}" = x ; then
+ as_fn_error $? "
+ ------------------------------------------------------------
+ configure cannot find a C++ compiler. Please specify the
+ locations of the compiler either with the MPICXX
+ environment variable or the --with-mpi configure flag.
+ ------------------------------------------------------------" "$LINENO" 5
+ has_mpicxx=no
+ else
+ CXX=${MPICXX}
+
+ has_mpicxx=yes
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+if test -z "$CXX"; then
+ if test -n "$CCC"; then
+ CXX=$CCC
+ else
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in ${MPICXX}
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CXX+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CXX"; then
+ ac_cv_prog_CXX="$CXX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CXX="$ac_tool_prefix$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CXX=$ac_cv_prog_CXX
+if test -n "$CXX"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5
+$as_echo "$CXX" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$CXX" && break
+ done
+fi
+if test -z "$CXX"; then
+ ac_ct_CXX=$CXX
+ for ac_prog in ${MPICXX}
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CXX+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_CXX"; then
+ ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CXX="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CXX=$ac_cv_prog_ac_ct_CXX
+if test -n "$ac_ct_CXX"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5
+$as_echo "$ac_ct_CXX" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$ac_ct_CXX" && break
+done
+
+ if test "x$ac_ct_CXX" = x; then
+ CXX="g++"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CXX=$ac_ct_CXX
+ fi
+fi
+
+ fi
+fi
+# Provide some information about the compiler.
+$as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion; do
+ { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compiler $ac_option >&5") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ sed '10a\
+... rest of stderr output deleted ...
+ 10q' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ fi
+ rm -f conftest.er1 conftest.err
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+done
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5
+$as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; }
+if ${ac_cv_cxx_compiler_gnu+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+#ifndef __GNUC__
+ choke me
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ ac_compiler_gnu=yes
+else
+ ac_compiler_gnu=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_cxx_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5
+$as_echo "$ac_cv_cxx_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+ GXX=yes
+else
+ GXX=
+fi
+ac_test_CXXFLAGS=${CXXFLAGS+set}
+ac_save_CXXFLAGS=$CXXFLAGS
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5
+$as_echo_n "checking whether $CXX accepts -g... " >&6; }
+if ${ac_cv_prog_cxx_g+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_save_cxx_werror_flag=$ac_cxx_werror_flag
+ ac_cxx_werror_flag=yes
+ ac_cv_prog_cxx_g=no
+ CXXFLAGS="-g"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ ac_cv_prog_cxx_g=yes
+else
+ CXXFLAGS=""
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+
+else
+ ac_cxx_werror_flag=$ac_save_cxx_werror_flag
+ CXXFLAGS="-g"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ ac_cv_prog_cxx_g=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_cxx_werror_flag=$ac_save_cxx_werror_flag
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5
+$as_echo "$ac_cv_prog_cxx_g" >&6; }
+if test "$ac_test_CXXFLAGS" = set; then
+ CXXFLAGS=$ac_save_CXXFLAGS
+elif test $ac_cv_prog_cxx_g = yes; then
+ if test "$GXX" = yes; then
+ CXXFLAGS="-g -O2"
+ else
+ CXXFLAGS="-g"
+ fi
+else
+ if test "$GXX" = yes; then
+ CXXFLAGS="-O2"
+ else
+ CXXFLAGS=
+ fi
+fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+ if test "x${enable_mpi_io_test}" = xyes ; then
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+
+ac_fn_cxx_check_func "$LINENO" "MPI_File_close" "ac_cv_func_MPI_File_close"
+if test "x$ac_cv_func_MPI_File_close" = xyes; then :
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing MPI_File_close" >&5
+$as_echo_n "checking for library containing MPI_File_close... " >&6; }
+if ${ac_cv_search_MPI_File_close+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char MPI_File_close ();
+int
+main ()
+{
+return MPI_File_close ();
+ ;
+ return 0;
+}
+_ACEOF
+for ac_lib in '' mpi++ mpichcxx mpi_cxx; do
+ if test -z "$ac_lib"; then
+ ac_res="none required"
+ else
+ ac_res=-l$ac_lib
+ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
+ fi
+ if ac_fn_cxx_try_link "$LINENO"; then :
+ ac_cv_search_MPI_File_close=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext
+ if ${ac_cv_search_MPI_File_close+:} false; then :
+ break
+fi
+done
+if ${ac_cv_search_MPI_File_close+:} false; then :
+
+else
+ ac_cv_search_MPI_File_close=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_MPI_File_close" >&5
+$as_echo "$ac_cv_search_MPI_File_close" >&6; }
+ac_res=$ac_cv_search_MPI_File_close
+if test "$ac_res" != no; then :
+ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+else
+ has_mpicxx=no
+ MPICXX=
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING:
+ ----------------------------------------------------------
+ MPI C++ implementation does not support MPI-IO
+ Disabling C++ testing programs
+ ----------------------------------------------------------" >&5
+$as_echo "$as_me: WARNING:
+ ----------------------------------------------------------
+ MPI C++ implementation does not support MPI-IO
+ Disabling C++ testing programs
+ ----------------------------------------------------------" >&2;}
+
+fi
+
+fi
+
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ fi
+ fi
+ if test "x${has_mpicxx}" = xyes ; then
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if MPI C++ compiler redefines SEEK_SET " >&5
+$as_echo_n "checking if MPI C++ compiler redefines SEEK_SET ... " >&6; }
+ CXX=${MPICXX}
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+ #include <stdio.h>
+ #include <mpi.h>
+ int main() { return 0; }
+
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ ac_cv_CHECK_MPI_CPP_SEEK_SET=no
+else
+ ac_cv_CHECK_MPI_CPP_SEEK_SET=yes
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_CHECK_MPI_CPP_SEEK_SET" >&5
+$as_echo "$ac_cv_CHECK_MPI_CPP_SEEK_SET" >&6; }
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+ if test "x${_DEBUG}" = xyes ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: DEBUG: ac_cv_CHECK_MPI_CPP_SEEK_SET=$ac_cv_CHECK_MPI_CPP_SEEK_SET" >&5
+$as_echo "$as_me: DEBUG: ac_cv_CHECK_MPI_CPP_SEEK_SET=$ac_cv_CHECK_MPI_CPP_SEEK_SET" >&6;}
+ fi
+
+
+ if test "x${ac_cv_CHECK_MPI_CPP_SEEK_SET}" = xyes ; then
+ CXXCPPFLAGS="${CXXCPPFLAGS} -DMPICH_IGNORE_CXX_SEEK -DMPICH_SKIP_MPICXX"
+ fi
+ fi
+else
+has_mpicxx=no
+fi
+
+
+# Check whether --enable-strict was given.
+if test "${enable_strict+set}" = set; then :
+ enableval=$enable_strict; enable_strict=${enableval}
+else
+ enable_strict=no
+
+fi
+
+
+if test "x${enable_strict}" = xyes; then
+ if test "x${GCC}" = xyes; then
+ CPPFLAGS="${CPPFLAGS} -Wall -Wstrict-prototypes -Wmissing-prototypes -Wundef -Wpointer-arith -Wbad-function-cast"
+ CXXCPPFLAGS="${CXXCPPFLAGS} -Wall -Wundef -Wpointer-arith"
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: --enable-strict is for GNU compiler only" >&5
+$as_echo "$as_me: WARNING: --enable-strict is for GNU compiler only" >&2;}
+ enable_strict=no
+ fi
+fi
+
+
+# Check whether --enable-fortran was given.
+if test "${enable_fortran+set}" = set; then :
+ enableval=$enable_fortran; enable_fortran=${enableval}
+else
+ enable_fortran=auto
+
+fi
+
+
+if test "x${enable_fortran}" != xno ; then
+
+ if test "x$MPI_INSTALL" != x ; then
+ if test "x${_DEBUG}" = xyes ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: DEBUG: --with-mpi=$MPI_INSTALL is used" >&5
+$as_echo "$as_me: DEBUG: --with-mpi=$MPI_INSTALL is used" >&6;}
+ fi
+
+
+ if test "x$MPIF77" = x ; then
+ if test "x$MPIF77" = x && (test -d "${MPI_INSTALL}/bin") ; then
+ if test "x${_DEBUG}" = xyes ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: DEBUG: search possible MPIF77 under $MPI_INSTALL/bin" >&5
+$as_echo "$as_me: DEBUG: search possible MPIF77 under $MPI_INSTALL/bin" >&6;}
+ fi
+
+
+ for ac_prog in $CANDIDATE_MPIF77
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_MPIF77+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $MPIF77 in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_MPIF77="$MPIF77" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $MPI_INSTALL/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_MPIF77="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+MPIF77=$ac_cv_path_MPIF77
+if test -n "$MPIF77"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MPIF77" >&5
+$as_echo "$MPIF77" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$MPIF77" && break
+done
+
+ fi
+ if test "x$MPIF77" = x ; then
+ if test "x${_DEBUG}" = xyes ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: DEBUG: search possible MPIF77 under $MPI_INSTALL" >&5
+$as_echo "$as_me: DEBUG: search possible MPIF77 under $MPI_INSTALL" >&6;}
+ fi
+
+
+ for ac_prog in $CANDIDATE_MPIF77
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_MPIF77+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $MPIF77 in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_MPIF77="$MPIF77" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $MPI_INSTALL
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_MPIF77="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+MPIF77=$ac_cv_path_MPIF77
+if test -n "$MPIF77"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MPIF77" >&5
+$as_echo "$MPIF77" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$MPIF77" && break
+done
+
+ fi
+ else
+ if test "x${_DEBUG}" = xyes ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: DEBUG: check if file $MPIF77 exists" >&5
+$as_echo "$as_me: DEBUG: check if file $MPIF77 exists" >&6;}
+ fi
+
+
+ if ! test -f "$MPIF77" ; then
+ if test "x${_DEBUG}" = xyes ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: DEBUG: File MPIF77= $MPIF77 cannot be found ... check under $MPI_INSTALL" >&5
+$as_echo "$as_me: DEBUG: File MPIF77= $MPIF77 cannot be found ... check under $MPI_INSTALL" >&6;}
+ fi
+
+
+ if test -f "$MPI_INSTALL/$MPIF77" ; then
+ if test "x${_DEBUG}" = xyes ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: DEBUG: File MPIF77= $MPIF77 is found under $MPI_INSTALL" >&5
+$as_echo "$as_me: DEBUG: File MPIF77= $MPIF77 is found under $MPI_INSTALL" >&6;}
+ fi
+
+
+ MPIF77="$MPI_INSTALL/$MPIF77"
+ elif test -f "$MPI_INSTALL/bin/$MPIF77" ; then
+ if test "x${_DEBUG}" = xyes ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: DEBUG: File MPIF77= $MPIF77 is found under $MPI_INSTALL/bin" >&5
+$as_echo "$as_me: DEBUG: File MPIF77= $MPIF77 is found under $MPI_INSTALL/bin" >&6;}
+ fi
+
+
+ MPIF77="$MPI_INSTALL/bin/$MPIF77"
+ else
+ if test "x${_DEBUG}" = xyes ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: DEBUG: File MPIF77= $MPIF77 cannot be found under $MPI_INSTALL" >&5
+$as_echo "$as_me: DEBUG: File MPIF77= $MPIF77 cannot be found under $MPI_INSTALL" >&6;}
+ fi
+
+
+ MPIF77=
+ fi
+ fi
+ fi
+ else
+ if test "x${_DEBUG}" = xyes ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: DEBUG: --with-mpi=$MPI_INSTALL is NOT used" >&5
+$as_echo "$as_me: DEBUG: --with-mpi=$MPI_INSTALL is NOT used" >&6;}
+ fi
+
+
+ if test "x${_DEBUG}" = xyes ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: DEBUG: check if MPIF77 is defined. If yes, check if file exists" >&5
+$as_echo "$as_me: DEBUG: check if MPIF77 is defined. If yes, check if file exists" >&6;}
+ fi
+
+
+ if test "x$MPIF77" != x && (! test -f "$MPIF77") ; then
+ if test "x${_DEBUG}" = xyes ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: DEBUG: check if file $MPIF77 exists under user's PATH" >&5
+$as_echo "$as_me: DEBUG: check if file $MPIF77 exists under user's PATH" >&6;}
+ fi
+
+
+ for ac_prog in $MPIF77
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_MPIF77+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $MPIF77 in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_MPIF77="$MPIF77" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_MPIF77="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+MPIF77=$ac_cv_path_MPIF77
+if test -n "$MPIF77"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MPIF77" >&5
+$as_echo "$MPIF77" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$MPIF77" && break
+done
+
+ fi
+ fi
+ if test "x$MPIF77" = x ; then
+ if test "x${_DEBUG}" = xyes ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: DEBUG: find possible MPIF77 under user's PATH" >&5
+$as_echo "$as_me: DEBUG: find possible MPIF77 under user's PATH" >&6;}
+ fi
+
+
+ for ac_prog in $CANDIDATE_MPIF77
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_MPIF77+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $MPIF77 in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_MPIF77="$MPIF77" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_MPIF77="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+MPIF77=$ac_cv_path_MPIF77
+if test -n "$MPIF77"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MPIF77" >&5
+$as_echo "$MPIF77" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$MPIF77" && break
+done
+
+ fi
+
+
+ if test "x$MPI_INSTALL" != x ; then
+ if test "x${_DEBUG}" = xyes ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: DEBUG: --with-mpi=$MPI_INSTALL is used" >&5
+$as_echo "$as_me: DEBUG: --with-mpi=$MPI_INSTALL is used" >&6;}
+ fi
+
+
+ if test "x$MPIF90" = x ; then
+ if test "x$MPIF90" = x && (test -d "${MPI_INSTALL}/bin") ; then
+ if test "x${_DEBUG}" = xyes ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: DEBUG: search possible MPIF90 under $MPI_INSTALL/bin" >&5
+$as_echo "$as_me: DEBUG: search possible MPIF90 under $MPI_INSTALL/bin" >&6;}
+ fi
+
+
+ for ac_prog in $CANDIDATE_MPIF90
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_MPIF90+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $MPIF90 in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_MPIF90="$MPIF90" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $MPI_INSTALL/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_MPIF90="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+MPIF90=$ac_cv_path_MPIF90
+if test -n "$MPIF90"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MPIF90" >&5
+$as_echo "$MPIF90" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$MPIF90" && break
+done
+
+ fi
+ if test "x$MPIF90" = x ; then
+ if test "x${_DEBUG}" = xyes ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: DEBUG: search possible MPIF90 under $MPI_INSTALL" >&5
+$as_echo "$as_me: DEBUG: search possible MPIF90 under $MPI_INSTALL" >&6;}
+ fi
+
+
+ for ac_prog in $CANDIDATE_MPIF90
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_MPIF90+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $MPIF90 in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_MPIF90="$MPIF90" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $MPI_INSTALL
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_MPIF90="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+MPIF90=$ac_cv_path_MPIF90
+if test -n "$MPIF90"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MPIF90" >&5
+$as_echo "$MPIF90" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$MPIF90" && break
+done
+
+ fi
+ else
+ if test "x${_DEBUG}" = xyes ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: DEBUG: check if file $MPIF90 exists" >&5
+$as_echo "$as_me: DEBUG: check if file $MPIF90 exists" >&6;}
+ fi
+
+
+ if ! test -f "$MPIF90" ; then
+ if test "x${_DEBUG}" = xyes ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: DEBUG: File MPIF90= $MPIF90 cannot be found ... check under $MPI_INSTALL" >&5
+$as_echo "$as_me: DEBUG: File MPIF90= $MPIF90 cannot be found ... check under $MPI_INSTALL" >&6;}
+ fi
+
+
+ if test -f "$MPI_INSTALL/$MPIF90" ; then
+ if test "x${_DEBUG}" = xyes ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: DEBUG: File MPIF90= $MPIF90 is found under $MPI_INSTALL" >&5
+$as_echo "$as_me: DEBUG: File MPIF90= $MPIF90 is found under $MPI_INSTALL" >&6;}
+ fi
+
+
+ MPIF90="$MPI_INSTALL/$MPIF90"
+ elif test -f "$MPI_INSTALL/bin/$MPIF90" ; then
+ if test "x${_DEBUG}" = xyes ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: DEBUG: File MPIF90= $MPIF90 is found under $MPI_INSTALL/bin" >&5
+$as_echo "$as_me: DEBUG: File MPIF90= $MPIF90 is found under $MPI_INSTALL/bin" >&6;}
+ fi
+
+
+ MPIF90="$MPI_INSTALL/bin/$MPIF90"
+ else
+ if test "x${_DEBUG}" = xyes ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: DEBUG: File MPIF90= $MPIF90 cannot be found under $MPI_INSTALL" >&5
+$as_echo "$as_me: DEBUG: File MPIF90= $MPIF90 cannot be found under $MPI_INSTALL" >&6;}
+ fi
+
+
+ MPIF90=
+ fi
+ fi
+ fi
+ else
+ if test "x${_DEBUG}" = xyes ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: DEBUG: --with-mpi=$MPI_INSTALL is NOT used" >&5
+$as_echo "$as_me: DEBUG: --with-mpi=$MPI_INSTALL is NOT used" >&6;}
+ fi
+
+
+ if test "x${_DEBUG}" = xyes ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: DEBUG: check if MPIF90 is defined. If yes, check if file exists" >&5
+$as_echo "$as_me: DEBUG: check if MPIF90 is defined. If yes, check if file exists" >&6;}
+ fi
+
+
+ if test "x$MPIF90" != x && (! test -f "$MPIF90") ; then
+ if test "x${_DEBUG}" = xyes ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: DEBUG: check if file $MPIF90 exists under user's PATH" >&5
+$as_echo "$as_me: DEBUG: check if file $MPIF90 exists under user's PATH" >&6;}
+ fi
+
+
+ for ac_prog in $MPIF90
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_MPIF90+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $MPIF90 in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_MPIF90="$MPIF90" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_MPIF90="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+MPIF90=$ac_cv_path_MPIF90
+if test -n "$MPIF90"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MPIF90" >&5
+$as_echo "$MPIF90" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$MPIF90" && break
+done
+
+ fi
+ fi
+ if test "x$MPIF90" = x ; then
+ if test "x${_DEBUG}" = xyes ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: DEBUG: find possible MPIF90 under user's PATH" >&5
+$as_echo "$as_me: DEBUG: find possible MPIF90 under user's PATH" >&6;}
+ fi
+
+
+ for ac_prog in $CANDIDATE_MPIF90
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_MPIF90+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $MPIF90 in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_MPIF90="$MPIF90" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_MPIF90="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+MPIF90=$ac_cv_path_MPIF90
+if test -n "$MPIF90"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MPIF90" >&5
+$as_echo "$MPIF90" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$MPIF90" && break
+done
+
+ fi
+
+fi
+if test "x${enable_fortran}" = xyes ; then
+ if test "x${MPIF77}" = x && test "x${MPIF90}" = x ; then
+ as_fn_error $? "
+ ------------------------------------------------------------
+ Fortran support is explicitly requested, but configure
+ cannot find a Fortran77 or Fortran90 compiler. Please
+ specify the locations of the compilers either with the
+ MPIF77 MPIF90 environment variables or the --with-mpi
+ configure flag.
+ ------------------------------------------------------------" "$LINENO" 5
+ fi
+fi
+
+
+if test "x${MPIF90}" != x ; then
+ FC=${MPIF90}
+ ac_ext=${ac_fc_srcext-f}
+ac_compile='$FC -c $FCFLAGS $ac_fcflags_srcext conftest.$ac_ext >&5'
+ac_link='$FC -o conftest$ac_exeext $FCFLAGS $LDFLAGS $ac_fcflags_srcext conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_fc_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+ for ac_prog in gfortran g95 xlf95 f95 fort ifort ifc efc pgfortran pgf95 lf95 ftn nagfor xlf90 f90 pgf90 pghpf epcf90 g77 xlf f77 frt pgf77 cf77 fort77 fl32 af77
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_FC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$FC"; then
+ ac_cv_prog_FC="$FC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_FC="$ac_tool_prefix$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+FC=$ac_cv_prog_FC
+if test -n "$FC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $FC" >&5
+$as_echo "$FC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$FC" && break
+ done
+fi
+if test -z "$FC"; then
+ ac_ct_FC=$FC
+ for ac_prog in gfortran g95 xlf95 f95 fort ifort ifc efc pgfortran pgf95 lf95 ftn nagfor xlf90 f90 pgf90 pghpf epcf90 g77 xlf f77 frt pgf77 cf77 fort77 fl32 af77
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_FC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_FC"; then
+ ac_cv_prog_ac_ct_FC="$ac_ct_FC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_FC="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_FC=$ac_cv_prog_ac_ct_FC
+if test -n "$ac_ct_FC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_FC" >&5
+$as_echo "$ac_ct_FC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$ac_ct_FC" && break
+done
+
+ if test "x$ac_ct_FC" = x; then
+ FC=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ FC=$ac_ct_FC
+ fi
+fi
+
+
+# Provide some information about the compiler.
+$as_echo "$as_me:${as_lineno-$LINENO}: checking for Fortran compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion; do
+ { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compiler $ac_option >&5") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ sed '10a\
+... rest of stderr output deleted ...
+ 10q' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ fi
+ rm -f conftest.er1 conftest.err
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+done
+rm -f a.out
+
+# If we don't use `.F' as extension, the preprocessor is not run on the
+# input file. (Note that this only needs to work for GNU compilers.)
+ac_save_ext=$ac_ext
+ac_ext=F
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU Fortran compiler" >&5
+$as_echo_n "checking whether we are using the GNU Fortran compiler... " >&6; }
+if ${ac_cv_fc_compiler_gnu+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat > conftest.$ac_ext <<_ACEOF
+ program main
+#ifndef __GNUC__
+ choke me
+#endif
+
+ end
+_ACEOF
+if ac_fn_fc_try_compile "$LINENO"; then :
+ ac_compiler_gnu=yes
+else
+ ac_compiler_gnu=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_fc_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_fc_compiler_gnu" >&5
+$as_echo "$ac_cv_fc_compiler_gnu" >&6; }
+ac_ext=$ac_save_ext
+ac_test_FCFLAGS=${FCFLAGS+set}
+ac_save_FCFLAGS=$FCFLAGS
+FCFLAGS=
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $FC accepts -g" >&5
+$as_echo_n "checking whether $FC accepts -g... " >&6; }
+if ${ac_cv_prog_fc_g+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ FCFLAGS=-g
+cat > conftest.$ac_ext <<_ACEOF
+ program main
+
+ end
+_ACEOF
+if ac_fn_fc_try_compile "$LINENO"; then :
+ ac_cv_prog_fc_g=yes
+else
+ ac_cv_prog_fc_g=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_fc_g" >&5
+$as_echo "$ac_cv_prog_fc_g" >&6; }
+if test "$ac_test_FCFLAGS" = set; then
+ FCFLAGS=$ac_save_FCFLAGS
+elif test $ac_cv_prog_fc_g = yes; then
+ if test "x$ac_cv_fc_compiler_gnu" = xyes; then
+ FCFLAGS="-g -O2"
+ else
+ FCFLAGS="-g"
+ fi
+else
+ if test "x$ac_cv_fc_compiler_gnu" = xyes; then
+ FCFLAGS="-O2"
+ else
+ FCFLAGS=
+ fi
+fi
+
+if test $ac_compiler_gnu = yes; then
+ GFC=yes
+else
+ GFC=
+fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+ FCLIBS_save="$FCLIBS"
+ FCLIBS=""
+ # Make sure we can run config.sub.
+$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 ||
+ as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5
+$as_echo_n "checking build system type... " >&6; }
+if ${ac_cv_build+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_build_alias=$build_alias
+test "x$ac_build_alias" = x &&
+ ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"`
+test "x$ac_build_alias" = x &&
+ as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5
+ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` ||
+ as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5
+$as_echo "$ac_cv_build" >&6; }
+case $ac_cv_build in
+*-*-*) ;;
+*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;;
+esac
+build=$ac_cv_build
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_build
+shift
+build_cpu=$1
+build_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+build_os=$*
+IFS=$ac_save_IFS
+case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5
+$as_echo_n "checking host system type... " >&6; }
+if ${ac_cv_host+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "x$host_alias" = x; then
+ ac_cv_host=$ac_cv_build
+else
+ ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` ||
+ as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5
+$as_echo "$ac_cv_host" >&6; }
+case $ac_cv_host in
+*-*-*) ;;
+*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;;
+esac
+host=$ac_cv_host
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_host
+shift
+host_cpu=$1
+host_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+host_os=$*
+IFS=$ac_save_IFS
+case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac
+
+
+
+ac_ext=${ac_fc_srcext-f}
+ac_compile='$FC -c $FCFLAGS $ac_fcflags_srcext conftest.$ac_ext >&5'
+ac_link='$FC -o conftest$ac_exeext $FCFLAGS $LDFLAGS $ac_fcflags_srcext conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_fc_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to get verbose linking output from $FC" >&5
+$as_echo_n "checking how to get verbose linking output from $FC... " >&6; }
+if ${ac_cv_prog_fc_v+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat > conftest.$ac_ext <<_ACEOF
+ program main
+
+ end
+_ACEOF
+if ac_fn_fc_try_compile "$LINENO"; then :
+ ac_cv_prog_fc_v=
+# Try some options frequently used verbose output
+for ac_verb in -v -verbose -V -\#\#\# --verbose; do
+ cat > conftest.$ac_ext <<_ACEOF
+ program main
+
+ end
+_ACEOF
+
+# Compile and link our simple test program by passing a flag (argument
+# 1 to this macro) to the Fortran compiler in order to get
+# "verbose" output that we can then parse for the Fortran linker
+# flags.
+ac_save_FCFLAGS=$FCFLAGS
+FCFLAGS="$FCFLAGS $ac_verb"
+eval "set x $ac_link"
+shift
+$as_echo "$as_me:${as_lineno-$LINENO}: $*" >&5
+# gfortran 4.3 outputs lines setting COLLECT_GCC_OPTIONS, COMPILER_PATH,
+# LIBRARY_PATH; skip all such settings.
+ac_fc_v_output=`eval $ac_link 5>&1 2>&1 |
+ sed '/^Driving:/d; /^Configured with:/d;
+ '"/^[_$as_cr_Letters][_$as_cr_alnum]*=/d"`
+$as_echo "$ac_fc_v_output" >&5
+FCFLAGS=$ac_save_FCFLAGS
+
+rm -rf conftest*
+
+# On HP/UX there is a line like: "LPATH is: /foo:/bar:/baz" where
+# /foo, /bar, and /baz are search directories for the Fortran linker.
+# Here, we change these into -L/foo -L/bar -L/baz (and put it first):
+ac_fc_v_output="`echo $ac_fc_v_output |
+ grep 'LPATH is:' |
+ sed 's|.*LPATH is\(: *[^ ]*\).*|\1|;s|: */| -L/|g'` $ac_fc_v_output"
+
+# FIXME: we keep getting bitten by quoted arguments; a more general fix
+# that detects unbalanced quotes in FLIBS should be implemented
+# and (ugh) tested at some point.
+case $ac_fc_v_output in
+ # With xlf replace commas with spaces,
+ # and remove "-link" and closing parenthesis.
+ *xlfentry*)
+ ac_fc_v_output=`echo $ac_fc_v_output |
+ sed '
+ s/,/ /g
+ s/ -link / /g
+ s/) *$//
+ '
+ ` ;;
+
+ # With Intel ifc, ignore the quoted -mGLOB_options_string stuff (quoted
+ # $LIBS confuse us, and the libraries appear later in the output anyway).
+ *mGLOB_options_string*)
+ ac_fc_v_output=`echo $ac_fc_v_output | sed 's/"-mGLOB[^"]*"/ /g'` ;;
+
+ # Portland Group compiler has singly- or doubly-quoted -cmdline argument
+ # Singly-quoted arguments were reported for versions 5.2-4 and 6.0-4.
+ # Doubly-quoted arguments were reported for "PGF90/x86 Linux/x86 5.0-2".
+ *-cmdline\ * | *-ignore\ * | *-def\ *)
+ ac_fc_v_output=`echo $ac_fc_v_output | sed "\
+ s/-cmdline *'[^']*'/ /g; s/-cmdline *\"[^\"]*\"/ /g
+ s/-ignore *'[^']*'/ /g; s/-ignore *\"[^\"]*\"/ /g
+ s/-def *'[^']*'/ /g; s/-def *\"[^\"]*\"/ /g"` ;;
+
+ # If we are using fort77 (the f2c wrapper) then filter output and delete quotes.
+ *fort77*f2c*gcc*)
+ ac_fc_v_output=`echo "$ac_fc_v_output" | sed -n '
+ /:[ ]\+Running[ ]\{1,\}"gcc"/{
+ /"-c"/d
+ /[.]c"*/d
+ s/^.*"gcc"/"gcc"/
+ s/"//gp
+ }'` ;;
+
+ # If we are using Cray Fortran then delete quotes.
+ *cft90*)
+ ac_fc_v_output=`echo $ac_fc_v_output | sed 's/"//g'` ;;
+esac
+
+
+ # look for -l* and *.a constructs in the output
+ for ac_arg in $ac_fc_v_output; do
+ case $ac_arg in
+ [\\/]*.a | ?:[\\/]*.a | -[lLRu]*)
+ ac_cv_prog_fc_v=$ac_verb
+ break 2 ;;
+ esac
+ done
+done
+if test -z "$ac_cv_prog_fc_v"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cannot determine how to obtain linking information from $FC" >&5
+$as_echo "$as_me: WARNING: cannot determine how to obtain linking information from $FC" >&2;}
+fi
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: compilation failed" >&5
+$as_echo "$as_me: WARNING: compilation failed" >&2;}
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_fc_v" >&5
+$as_echo "$ac_cv_prog_fc_v" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Fortran libraries of $FC" >&5
+$as_echo_n "checking for Fortran libraries of $FC... " >&6; }
+if ${ac_cv_fc_libs+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "x$FCLIBS" != "x"; then
+ ac_cv_fc_libs="$FCLIBS" # Let the user override the test.
+else
+
+cat > conftest.$ac_ext <<_ACEOF
+ program main
+
+ end
+_ACEOF
+
+# Compile and link our simple test program by passing a flag (argument
+# 1 to this macro) to the Fortran compiler in order to get
+# "verbose" output that we can then parse for the Fortran linker
+# flags.
+ac_save_FCFLAGS=$FCFLAGS
+FCFLAGS="$FCFLAGS $ac_cv_prog_fc_v"
+eval "set x $ac_link"
+shift
+$as_echo "$as_me:${as_lineno-$LINENO}: $*" >&5
+# gfortran 4.3 outputs lines setting COLLECT_GCC_OPTIONS, COMPILER_PATH,
+# LIBRARY_PATH; skip all such settings.
+ac_fc_v_output=`eval $ac_link 5>&1 2>&1 |
+ sed '/^Driving:/d; /^Configured with:/d;
+ '"/^[_$as_cr_Letters][_$as_cr_alnum]*=/d"`
+$as_echo "$ac_fc_v_output" >&5
+FCFLAGS=$ac_save_FCFLAGS
+
+rm -rf conftest*
+
+# On HP/UX there is a line like: "LPATH is: /foo:/bar:/baz" where
+# /foo, /bar, and /baz are search directories for the Fortran linker.
+# Here, we change these into -L/foo -L/bar -L/baz (and put it first):
+ac_fc_v_output="`echo $ac_fc_v_output |
+ grep 'LPATH is:' |
+ sed 's|.*LPATH is\(: *[^ ]*\).*|\1|;s|: */| -L/|g'` $ac_fc_v_output"
+
+# FIXME: we keep getting bitten by quoted arguments; a more general fix
+# that detects unbalanced quotes in FLIBS should be implemented
+# and (ugh) tested at some point.
+case $ac_fc_v_output in
+ # With xlf replace commas with spaces,
+ # and remove "-link" and closing parenthesis.
+ *xlfentry*)
+ ac_fc_v_output=`echo $ac_fc_v_output |
+ sed '
+ s/,/ /g
+ s/ -link / /g
+ s/) *$//
+ '
+ ` ;;
+
+ # With Intel ifc, ignore the quoted -mGLOB_options_string stuff (quoted
+ # $LIBS confuse us, and the libraries appear later in the output anyway).
+ *mGLOB_options_string*)
+ ac_fc_v_output=`echo $ac_fc_v_output | sed 's/"-mGLOB[^"]*"/ /g'` ;;
+
+ # Portland Group compiler has singly- or doubly-quoted -cmdline argument
+ # Singly-quoted arguments were reported for versions 5.2-4 and 6.0-4.
+ # Doubly-quoted arguments were reported for "PGF90/x86 Linux/x86 5.0-2".
+ *-cmdline\ * | *-ignore\ * | *-def\ *)
+ ac_fc_v_output=`echo $ac_fc_v_output | sed "\
+ s/-cmdline *'[^']*'/ /g; s/-cmdline *\"[^\"]*\"/ /g
+ s/-ignore *'[^']*'/ /g; s/-ignore *\"[^\"]*\"/ /g
+ s/-def *'[^']*'/ /g; s/-def *\"[^\"]*\"/ /g"` ;;
+
+ # If we are using fort77 (the f2c wrapper) then filter output and delete quotes.
+ *fort77*f2c*gcc*)
+ ac_fc_v_output=`echo "$ac_fc_v_output" | sed -n '
+ /:[ ]\+Running[ ]\{1,\}"gcc"/{
+ /"-c"/d
+ /[.]c"*/d
+ s/^.*"gcc"/"gcc"/
+ s/"//gp
+ }'` ;;
+
+ # If we are using Cray Fortran then delete quotes.
+ *cft90*)
+ ac_fc_v_output=`echo $ac_fc_v_output | sed 's/"//g'` ;;
+esac
+
+
+
+ac_cv_fc_libs=
+
+# Save positional arguments (if any)
+ac_save_positional="$@"
+
+set X $ac_fc_v_output
+while test $# != 1; do
+ shift
+ ac_arg=$1
+ case $ac_arg in
+ [\\/]*.a | ?:[\\/]*.a)
+ ac_exists=false
+ for ac_i in $ac_cv_fc_libs; do
+ if test x"$ac_arg" = x"$ac_i"; then
+ ac_exists=true
+ break
+ fi
+ done
+
+ if test x"$ac_exists" = xtrue; then :
+
+else
+ ac_cv_fc_libs="$ac_cv_fc_libs $ac_arg"
+fi
+ ;;
+ -bI:*)
+ ac_exists=false
+ for ac_i in $ac_cv_fc_libs; do
+ if test x"$ac_arg" = x"$ac_i"; then
+ ac_exists=true
+ break
+ fi
+ done
+
+ if test x"$ac_exists" = xtrue; then :
+
+else
+ if test "$ac_compiler_gnu" = yes; then
+ for ac_link_opt in $ac_arg; do
+ ac_cv_fc_libs="$ac_cv_fc_libs -Xlinker $ac_link_opt"
+ done
+else
+ ac_cv_fc_libs="$ac_cv_fc_libs $ac_arg"
+fi
+fi
+ ;;
+ # Ignore these flags.
+ -lang* | -lcrt*.o | -lc | -lgcc* | -lSystem | -libmil | -little \
+ |-LANG:=* | -LIST:* | -LNO:* | -link)
+ ;;
+ -lkernel32)
+ case $host_os in
+ *cygwin*) ;;
+ *) ac_cv_fc_libs="$ac_cv_fc_libs $ac_arg"
+ ;;
+ esac
+ ;;
+ -[LRuYz])
+ # These flags, when seen by themselves, take an argument.
+ # We remove the space between option and argument and re-iterate
+ # unless we find an empty arg or a new option (starting with -)
+ case $2 in
+ "" | -*);;
+ *)
+ ac_arg="$ac_arg$2"
+ shift; shift
+ set X $ac_arg "$@"
+ ;;
+ esac
+ ;;
+ -YP,*)
+ for ac_j in `$as_echo "$ac_arg" | sed -e 's/-YP,/-L/;s/:/ -L/g'`; do
+ ac_exists=false
+ for ac_i in $ac_cv_fc_libs; do
+ if test x"$ac_j" = x"$ac_i"; then
+ ac_exists=true
+ break
+ fi
+ done
+
+ if test x"$ac_exists" = xtrue; then :
+
+else
+ ac_arg="$ac_arg $ac_j"
+ ac_cv_fc_libs="$ac_cv_fc_libs $ac_j"
+fi
+ done
+ ;;
+ -[lLR]*)
+ ac_exists=false
+ for ac_i in $ac_cv_fc_libs; do
+ if test x"$ac_arg" = x"$ac_i"; then
+ ac_exists=true
+ break
+ fi
+ done
+
+ if test x"$ac_exists" = xtrue; then :
+
+else
+ ac_cv_fc_libs="$ac_cv_fc_libs $ac_arg"
+fi
+ ;;
+ -zallextract*| -zdefaultextract)
+ ac_cv_fc_libs="$ac_cv_fc_libs $ac_arg"
+ ;;
+ # Ignore everything else.
+ esac
+done
+# restore positional arguments
+set X $ac_save_positional; shift
+
+# We only consider "LD_RUN_PATH" on Solaris systems. If this is seen,
+# then we insist that the "run path" must be an absolute path (i.e. it
+# must begin with a "/").
+case `(uname -sr) 2>/dev/null` in
+ "SunOS 5"*)
+ ac_ld_run_path=`$as_echo "$ac_fc_v_output" |
+ sed -n 's,^.*LD_RUN_PATH *= *\(/[^ ]*\).*$,-R\1,p'`
+ test "x$ac_ld_run_path" != x &&
+ if test "$ac_compiler_gnu" = yes; then
+ for ac_link_opt in $ac_ld_run_path; do
+ ac_cv_fc_libs="$ac_cv_fc_libs -Xlinker $ac_link_opt"
+ done
+else
+ ac_cv_fc_libs="$ac_cv_fc_libs $ac_ld_run_path"
+fi
+ ;;
+esac
+fi # test "x$[]_AC_LANG_PREFIX[]LIBS" = "x"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_fc_libs" >&5
+$as_echo "$ac_cv_fc_libs" >&6; }
+FCLIBS="$ac_cv_fc_libs"
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ if test "x${_DEBUG}" = xyes ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: DEBUG: before FCLIBS=$FCLIBS" >&5
+$as_echo "$as_me: DEBUG: before FCLIBS=$FCLIBS" >&6;}
+ fi
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC links with FCLIBS found by autoconf" >&5
+$as_echo_n "checking whether $CC links with FCLIBS found by autoconf... " >&6; }
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+# Create a simple C program for the tests.
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+
+int
+main ()
+{
+int a;
+ ;
+ return 0;
+}
+
+_ACEOF
+# Try to link a C program with all of these libraries
+saved_LIBS="$LIBS"
+LIBS="$FCLIBS $saved_LIBS"
+if ac_fn_c_try_link "$LINENO"; then :
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+else
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for which libraries can be used" >&5
+$as_echo_n "checking for which libraries can be used... " >&6; }
+ pac_ldirs=""
+ pac_libs=""
+ pac_other=""
+ for name in $FCLIBS ; do
+ case $name in
+ -l*) pac_libs="$pac_libs $name" ;;
+ -L*) pac_ldirs="$pac_ldirs $name" ;;
+ *) pac_other="$pac_other $name" ;;
+ esac
+ done
+ keep_libs=""
+ for name in $pac_libs ; do
+ LIBS="$saved_LIBS $pac_ldirs $pac_other $name"
+ if ac_fn_c_try_link "$LINENO"; then :
+
+ keep_libs="$keep_libs $name"
+
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext
+ done
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $keep_libs" >&5
+$as_echo "$keep_libs" >&6; }
+ FCLIBS="$pac_ldirs $pac_other $keep_libs"
+
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext
+LIBS="$saved_LIBS"
+rm -f conftest.$ac_ext
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+ if test "x${_DEBUG}" = xyes ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: DEBUG: after FCLIBS=$FCLIBS" >&5
+$as_echo "$as_me: DEBUG: after FCLIBS=$FCLIBS" >&6;}
+ fi
+
+
+ FLIBS="$FCLIBS"
+ F90LIBS="$FCLIBS"
+
+ F90FLAGS=${FCFLAGS}
+
+
+ ac_ext=${ac_fc_srcext-f}
+ac_compile='$FC -c $FCFLAGS $ac_fcflags_srcext conftest.$ac_ext >&5'
+ac_link='$FC -o conftest$ac_exeext $FCFLAGS $LDFLAGS $ac_fcflags_srcext conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_fc_compiler_gnu
+
+ cat > conftest.$ac_ext <<_ACEOF
+ program main
+ call MPI_Comm_rank
+ end
+_ACEOF
+if ac_fn_fc_try_compile "$LINENO"; then :
+ valid_mpif90=yes
+else
+ valid_mpif90=no
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if mpi.mod is valid" >&5
+$as_echo_n "checking if mpi.mod is valid... " >&6; }
+ cat > conftest.$ac_ext <<_ACEOF
+ program main
+ use mpi
+ end
+_ACEOF
+if ac_fn_fc_try_compile "$LINENO"; then :
+ valid_mpi_mod=yes
+else
+ valid_mpi_mod=no
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $valid_mpi_mod" >&5
+$as_echo "$valid_mpi_mod" >&6; }
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ if test "x${valid_mpif90}" = xno && test "x${enable_fortran}" = xyes ; then
+ as_fn_error $? "
+ ------------------------------------------------------------
+ Invalid MPI Fortran 90 compiler specified: \"${MPIF90}\"
+ A working MPI compiler is required. Please specify the
+ location of one either with the MPIF90 environment
+ variable or the --with-mpi configure flag.
+ ------------------------------------------------------------" "$LINENO" 5
+ fi
+ if test "x${valid_mpi_mod}" = xno && test "x${enable_fortran}" = xyes ; then
+ as_fn_error $? "
+ ------------------------------------------------------------
+ Invalid MPI Fortran module. The mpi.mod file in the include path
+ may not be generated by the same Fortran compiler used to build
+ \"${MPIF90}\". Please make sure the same Fortran compiler is used.
+ ------------------------------------------------------------" "$LINENO" 5
+ fi
+fi
+
+F77_SUPPORT_FREEFORM=no
+if test "x${MPIF77}" != x ; then
+ F77=${MPIF77}
+ ac_ext=f
+ac_compile='$F77 -c $FFLAGS conftest.$ac_ext >&5'
+ac_link='$F77 -o conftest$ac_exeext $FFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_f77_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+ for ac_prog in g77 xlf f77 frt pgf77 cf77 fort77 fl32 af77 xlf90 f90 pgf90 pghpf epcf90 gfortran g95 xlf95 f95 fort ifort ifc efc pgfortran pgf95 lf95 ftn nagfor
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_F77+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$F77"; then
+ ac_cv_prog_F77="$F77" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_F77="$ac_tool_prefix$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+F77=$ac_cv_prog_F77
+if test -n "$F77"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $F77" >&5
+$as_echo "$F77" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$F77" && break
+ done
+fi
+if test -z "$F77"; then
+ ac_ct_F77=$F77
+ for ac_prog in g77 xlf f77 frt pgf77 cf77 fort77 fl32 af77 xlf90 f90 pgf90 pghpf epcf90 gfortran g95 xlf95 f95 fort ifort ifc efc pgfortran pgf95 lf95 ftn nagfor
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_F77+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_F77"; then
+ ac_cv_prog_ac_ct_F77="$ac_ct_F77" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_F77="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_F77=$ac_cv_prog_ac_ct_F77
+if test -n "$ac_ct_F77"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_F77" >&5
+$as_echo "$ac_ct_F77" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$ac_ct_F77" && break
+done
+
+ if test "x$ac_ct_F77" = x; then
+ F77=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ F77=$ac_ct_F77
+ fi
+fi
+
+
+# Provide some information about the compiler.
+$as_echo "$as_me:${as_lineno-$LINENO}: checking for Fortran 77 compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion; do
+ { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compiler $ac_option >&5") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ sed '10a\
+... rest of stderr output deleted ...
+ 10q' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ fi
+ rm -f conftest.er1 conftest.err
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+done
+rm -f a.out
+
+# If we don't use `.F' as extension, the preprocessor is not run on the
+# input file. (Note that this only needs to work for GNU compilers.)
+ac_save_ext=$ac_ext
+ac_ext=F
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU Fortran 77 compiler" >&5
+$as_echo_n "checking whether we are using the GNU Fortran 77 compiler... " >&6; }
+if ${ac_cv_f77_compiler_gnu+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat > conftest.$ac_ext <<_ACEOF
+ program main
+#ifndef __GNUC__
+ choke me
+#endif
+
+ end
+_ACEOF
+if ac_fn_f77_try_compile "$LINENO"; then :
+ ac_compiler_gnu=yes
+else
+ ac_compiler_gnu=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_f77_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_f77_compiler_gnu" >&5
+$as_echo "$ac_cv_f77_compiler_gnu" >&6; }
+ac_ext=$ac_save_ext
+ac_test_FFLAGS=${FFLAGS+set}
+ac_save_FFLAGS=$FFLAGS
+FFLAGS=
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $F77 accepts -g" >&5
+$as_echo_n "checking whether $F77 accepts -g... " >&6; }
+if ${ac_cv_prog_f77_g+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ FFLAGS=-g
+cat > conftest.$ac_ext <<_ACEOF
+ program main
+
+ end
+_ACEOF
+if ac_fn_f77_try_compile "$LINENO"; then :
+ ac_cv_prog_f77_g=yes
+else
+ ac_cv_prog_f77_g=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_f77_g" >&5
+$as_echo "$ac_cv_prog_f77_g" >&6; }
+if test "$ac_test_FFLAGS" = set; then
+ FFLAGS=$ac_save_FFLAGS
+elif test $ac_cv_prog_f77_g = yes; then
+ if test "x$ac_cv_f77_compiler_gnu" = xyes; then
+ FFLAGS="-g -O2"
+ else
+ FFLAGS="-g"
+ fi
+else
+ if test "x$ac_cv_f77_compiler_gnu" = xyes; then
+ FFLAGS="-O2"
+ else
+ FFLAGS=
+ fi
+fi
+
+if test $ac_compiler_gnu = yes; then
+ G77=yes
+else
+ G77=
+fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+ac_ext=f
+ac_compile='$F77 -c $FFLAGS conftest.$ac_ext >&5'
+ac_link='$F77 -o conftest$ac_exeext $FFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_f77_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to get verbose linking output from $F77" >&5
+$as_echo_n "checking how to get verbose linking output from $F77... " >&6; }
+if ${ac_cv_prog_f77_v+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat > conftest.$ac_ext <<_ACEOF
+ program main
+
+ end
+_ACEOF
+if ac_fn_f77_try_compile "$LINENO"; then :
+ ac_cv_prog_f77_v=
+# Try some options frequently used verbose output
+for ac_verb in -v -verbose -V -\#\#\# --verbose; do
+ cat > conftest.$ac_ext <<_ACEOF
+ program main
+
+ end
+_ACEOF
+
+# Compile and link our simple test program by passing a flag (argument
+# 1 to this macro) to the Fortran compiler in order to get
+# "verbose" output that we can then parse for the Fortran linker
+# flags.
+ac_save_FFLAGS=$FFLAGS
+FFLAGS="$FFLAGS $ac_verb"
+eval "set x $ac_link"
+shift
+$as_echo "$as_me:${as_lineno-$LINENO}: $*" >&5
+# gfortran 4.3 outputs lines setting COLLECT_GCC_OPTIONS, COMPILER_PATH,
+# LIBRARY_PATH; skip all such settings.
+ac_f77_v_output=`eval $ac_link 5>&1 2>&1 |
+ sed '/^Driving:/d; /^Configured with:/d;
+ '"/^[_$as_cr_Letters][_$as_cr_alnum]*=/d"`
+$as_echo "$ac_f77_v_output" >&5
+FFLAGS=$ac_save_FFLAGS
+
+rm -rf conftest*
+
+# On HP/UX there is a line like: "LPATH is: /foo:/bar:/baz" where
+# /foo, /bar, and /baz are search directories for the Fortran linker.
+# Here, we change these into -L/foo -L/bar -L/baz (and put it first):
+ac_f77_v_output="`echo $ac_f77_v_output |
+ grep 'LPATH is:' |
+ sed 's|.*LPATH is\(: *[^ ]*\).*|\1|;s|: */| -L/|g'` $ac_f77_v_output"
+
+# FIXME: we keep getting bitten by quoted arguments; a more general fix
+# that detects unbalanced quotes in FLIBS should be implemented
+# and (ugh) tested at some point.
+case $ac_f77_v_output in
+ # With xlf replace commas with spaces,
+ # and remove "-link" and closing parenthesis.
+ *xlfentry*)
+ ac_f77_v_output=`echo $ac_f77_v_output |
+ sed '
+ s/,/ /g
+ s/ -link / /g
+ s/) *$//
+ '
+ ` ;;
+
+ # With Intel ifc, ignore the quoted -mGLOB_options_string stuff (quoted
+ # $LIBS confuse us, and the libraries appear later in the output anyway).
+ *mGLOB_options_string*)
+ ac_f77_v_output=`echo $ac_f77_v_output | sed 's/"-mGLOB[^"]*"/ /g'` ;;
+
+ # Portland Group compiler has singly- or doubly-quoted -cmdline argument
+ # Singly-quoted arguments were reported for versions 5.2-4 and 6.0-4.
+ # Doubly-quoted arguments were reported for "PGF90/x86 Linux/x86 5.0-2".
+ *-cmdline\ * | *-ignore\ * | *-def\ *)
+ ac_f77_v_output=`echo $ac_f77_v_output | sed "\
+ s/-cmdline *'[^']*'/ /g; s/-cmdline *\"[^\"]*\"/ /g
+ s/-ignore *'[^']*'/ /g; s/-ignore *\"[^\"]*\"/ /g
+ s/-def *'[^']*'/ /g; s/-def *\"[^\"]*\"/ /g"` ;;
+
+ # If we are using fort77 (the f2c wrapper) then filter output and delete quotes.
+ *fort77*f2c*gcc*)
+ ac_f77_v_output=`echo "$ac_f77_v_output" | sed -n '
+ /:[ ]\+Running[ ]\{1,\}"gcc"/{
+ /"-c"/d
+ /[.]c"*/d
+ s/^.*"gcc"/"gcc"/
+ s/"//gp
+ }'` ;;
+
+ # If we are using Cray Fortran then delete quotes.
+ *cft90*)
+ ac_f77_v_output=`echo $ac_f77_v_output | sed 's/"//g'` ;;
+esac
+
+
+ # look for -l* and *.a constructs in the output
+ for ac_arg in $ac_f77_v_output; do
+ case $ac_arg in
+ [\\/]*.a | ?:[\\/]*.a | -[lLRu]*)
+ ac_cv_prog_f77_v=$ac_verb
+ break 2 ;;
+ esac
+ done
+done
+if test -z "$ac_cv_prog_f77_v"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cannot determine how to obtain linking information from $F77" >&5
+$as_echo "$as_me: WARNING: cannot determine how to obtain linking information from $F77" >&2;}
+fi
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: compilation failed" >&5
+$as_echo "$as_me: WARNING: compilation failed" >&2;}
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_f77_v" >&5
+$as_echo "$ac_cv_prog_f77_v" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Fortran 77 libraries of $F77" >&5
+$as_echo_n "checking for Fortran 77 libraries of $F77... " >&6; }
+if ${ac_cv_f77_libs+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "x$FLIBS" != "x"; then
+ ac_cv_f77_libs="$FLIBS" # Let the user override the test.
+else
+
+cat > conftest.$ac_ext <<_ACEOF
+ program main
+
+ end
+_ACEOF
+
+# Compile and link our simple test program by passing a flag (argument
+# 1 to this macro) to the Fortran compiler in order to get
+# "verbose" output that we can then parse for the Fortran linker
+# flags.
+ac_save_FFLAGS=$FFLAGS
+FFLAGS="$FFLAGS $ac_cv_prog_f77_v"
+eval "set x $ac_link"
+shift
+$as_echo "$as_me:${as_lineno-$LINENO}: $*" >&5
+# gfortran 4.3 outputs lines setting COLLECT_GCC_OPTIONS, COMPILER_PATH,
+# LIBRARY_PATH; skip all such settings.
+ac_f77_v_output=`eval $ac_link 5>&1 2>&1 |
+ sed '/^Driving:/d; /^Configured with:/d;
+ '"/^[_$as_cr_Letters][_$as_cr_alnum]*=/d"`
+$as_echo "$ac_f77_v_output" >&5
+FFLAGS=$ac_save_FFLAGS
+
+rm -rf conftest*
+
+# On HP/UX there is a line like: "LPATH is: /foo:/bar:/baz" where
+# /foo, /bar, and /baz are search directories for the Fortran linker.
+# Here, we change these into -L/foo -L/bar -L/baz (and put it first):
+ac_f77_v_output="`echo $ac_f77_v_output |
+ grep 'LPATH is:' |
+ sed 's|.*LPATH is\(: *[^ ]*\).*|\1|;s|: */| -L/|g'` $ac_f77_v_output"
+
+# FIXME: we keep getting bitten by quoted arguments; a more general fix
+# that detects unbalanced quotes in FLIBS should be implemented
+# and (ugh) tested at some point.
+case $ac_f77_v_output in
+ # With xlf replace commas with spaces,
+ # and remove "-link" and closing parenthesis.
+ *xlfentry*)
+ ac_f77_v_output=`echo $ac_f77_v_output |
+ sed '
+ s/,/ /g
+ s/ -link / /g
+ s/) *$//
+ '
+ ` ;;
+
+ # With Intel ifc, ignore the quoted -mGLOB_options_string stuff (quoted
+ # $LIBS confuse us, and the libraries appear later in the output anyway).
+ *mGLOB_options_string*)
+ ac_f77_v_output=`echo $ac_f77_v_output | sed 's/"-mGLOB[^"]*"/ /g'` ;;
+
+ # Portland Group compiler has singly- or doubly-quoted -cmdline argument
+ # Singly-quoted arguments were reported for versions 5.2-4 and 6.0-4.
+ # Doubly-quoted arguments were reported for "PGF90/x86 Linux/x86 5.0-2".
+ *-cmdline\ * | *-ignore\ * | *-def\ *)
+ ac_f77_v_output=`echo $ac_f77_v_output | sed "\
+ s/-cmdline *'[^']*'/ /g; s/-cmdline *\"[^\"]*\"/ /g
+ s/-ignore *'[^']*'/ /g; s/-ignore *\"[^\"]*\"/ /g
+ s/-def *'[^']*'/ /g; s/-def *\"[^\"]*\"/ /g"` ;;
+
+ # If we are using fort77 (the f2c wrapper) then filter output and delete quotes.
+ *fort77*f2c*gcc*)
+ ac_f77_v_output=`echo "$ac_f77_v_output" | sed -n '
+ /:[ ]\+Running[ ]\{1,\}"gcc"/{
+ /"-c"/d
+ /[.]c"*/d
+ s/^.*"gcc"/"gcc"/
+ s/"//gp
+ }'` ;;
+
+ # If we are using Cray Fortran then delete quotes.
+ *cft90*)
+ ac_f77_v_output=`echo $ac_f77_v_output | sed 's/"//g'` ;;
+esac
+
+
+
+ac_cv_f77_libs=
+
+# Save positional arguments (if any)
+ac_save_positional="$@"
+
+set X $ac_f77_v_output
+while test $# != 1; do
+ shift
+ ac_arg=$1
+ case $ac_arg in
+ [\\/]*.a | ?:[\\/]*.a)
+ ac_exists=false
+ for ac_i in $ac_cv_f77_libs; do
+ if test x"$ac_arg" = x"$ac_i"; then
+ ac_exists=true
+ break
+ fi
+ done
+
+ if test x"$ac_exists" = xtrue; then :
+
+else
+ ac_cv_f77_libs="$ac_cv_f77_libs $ac_arg"
+fi
+ ;;
+ -bI:*)
+ ac_exists=false
+ for ac_i in $ac_cv_f77_libs; do
+ if test x"$ac_arg" = x"$ac_i"; then
+ ac_exists=true
+ break
+ fi
+ done
+
+ if test x"$ac_exists" = xtrue; then :
+
+else
+ if test "$ac_compiler_gnu" = yes; then
+ for ac_link_opt in $ac_arg; do
+ ac_cv_f77_libs="$ac_cv_f77_libs -Xlinker $ac_link_opt"
+ done
+else
+ ac_cv_f77_libs="$ac_cv_f77_libs $ac_arg"
+fi
+fi
+ ;;
+ # Ignore these flags.
+ -lang* | -lcrt*.o | -lc | -lgcc* | -lSystem | -libmil | -little \
+ |-LANG:=* | -LIST:* | -LNO:* | -link)
+ ;;
+ -lkernel32)
+ case $host_os in
+ *cygwin*) ;;
+ *) ac_cv_f77_libs="$ac_cv_f77_libs $ac_arg"
+ ;;
+ esac
+ ;;
+ -[LRuYz])
+ # These flags, when seen by themselves, take an argument.
+ # We remove the space between option and argument and re-iterate
+ # unless we find an empty arg or a new option (starting with -)
+ case $2 in
+ "" | -*);;
+ *)
+ ac_arg="$ac_arg$2"
+ shift; shift
+ set X $ac_arg "$@"
+ ;;
+ esac
+ ;;
+ -YP,*)
+ for ac_j in `$as_echo "$ac_arg" | sed -e 's/-YP,/-L/;s/:/ -L/g'`; do
+ ac_exists=false
+ for ac_i in $ac_cv_f77_libs; do
+ if test x"$ac_j" = x"$ac_i"; then
+ ac_exists=true
+ break
+ fi
+ done
+
+ if test x"$ac_exists" = xtrue; then :
+
+else
+ ac_arg="$ac_arg $ac_j"
+ ac_cv_f77_libs="$ac_cv_f77_libs $ac_j"
+fi
+ done
+ ;;
+ -[lLR]*)
+ ac_exists=false
+ for ac_i in $ac_cv_f77_libs; do
+ if test x"$ac_arg" = x"$ac_i"; then
+ ac_exists=true
+ break
+ fi
+ done
+
+ if test x"$ac_exists" = xtrue; then :
+
+else
+ ac_cv_f77_libs="$ac_cv_f77_libs $ac_arg"
+fi
+ ;;
+ -zallextract*| -zdefaultextract)
+ ac_cv_f77_libs="$ac_cv_f77_libs $ac_arg"
+ ;;
+ # Ignore everything else.
+ esac
+done
+# restore positional arguments
+set X $ac_save_positional; shift
+
+# We only consider "LD_RUN_PATH" on Solaris systems. If this is seen,
+# then we insist that the "run path" must be an absolute path (i.e. it
+# must begin with a "/").
+case `(uname -sr) 2>/dev/null` in
+ "SunOS 5"*)
+ ac_ld_run_path=`$as_echo "$ac_f77_v_output" |
+ sed -n 's,^.*LD_RUN_PATH *= *\(/[^ ]*\).*$,-R\1,p'`
+ test "x$ac_ld_run_path" != x &&
+ if test "$ac_compiler_gnu" = yes; then
+ for ac_link_opt in $ac_ld_run_path; do
+ ac_cv_f77_libs="$ac_cv_f77_libs -Xlinker $ac_link_opt"
+ done
+else
+ ac_cv_f77_libs="$ac_cv_f77_libs $ac_ld_run_path"
+fi
+ ;;
+esac
+fi # test "x$[]_AC_LANG_PREFIX[]LIBS" = "x"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_f77_libs" >&5
+$as_echo "$ac_cv_f77_libs" >&6; }
+FLIBS="$ac_cv_f77_libs"
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+ F77FLAGS=${FFLAGS}
+
+
+ FC_saved=${FC}
+ FC=${F77}
+ ac_ext=${ac_fc_srcext-f}
+ac_compile='$FC -c $FCFLAGS $ac_fcflags_srcext conftest.$ac_ext >&5'
+ac_link='$FC -o conftest$ac_exeext $FCFLAGS $LDFLAGS $ac_fcflags_srcext conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_fc_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Fortran flag needed to accept free-form source" >&5
+$as_echo_n "checking for Fortran flag needed to accept free-form source... " >&6; }
+if ${ac_cv_fc_freeform+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_fc_freeform=unknown
+ac_fc_freeform_FCFLAGS_save=$FCFLAGS
+for ac_flag in none -ffree-form -FR -free -qfree=f90 -qfree -Mfree -Mfreeform \
+ -freeform "-f free" -8 +source=free -nfix --nfix -Free
+do
+ test "x$ac_flag" != xnone && FCFLAGS="$ac_fc_freeform_FCFLAGS_save $ac_flag"
+ cat > conftest.$ac_ext <<_ACEOF
+
+ program freeform
+ ! FIXME: how to best confuse non-freeform compilers?
+ print *, 'Hello ', &
+ 'world.'
+ end
+_ACEOF
+if ac_fn_fc_try_compile "$LINENO"; then :
+ ac_cv_fc_freeform=$ac_flag; break
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+${RM} -f conftest.err conftest.$ac_objext conftest.$ac_ext
+FCFLAGS=$ac_fc_freeform_FCFLAGS_save
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_fc_freeform" >&5
+$as_echo "$ac_cv_fc_freeform" >&6; }
+if test "x$ac_cv_fc_freeform" = xunknown; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Fortran $FC does not accept free-form source" >&5
+$as_echo "$as_me: WARNING: Fortran $FC does not accept free-form source" >&2;}
+else
+ if test "x$ac_cv_fc_freeform" = xnone; then
+ ac_cv_fc_freeform=
+ fi
+
+fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ if test "x${ac_cv_fc_freeform}" != xunknown ; then
+ F77_SUPPORT_FREEFORM=yes
+ FFREEFORMFLAG=${ac_cv_fc_freeform}
+ fi
+ if test "x${_DEBUG}" = xyes ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: DEBUG: FC=$FC F90FLAGS=$F90FLAGS FFREEFORMFLAG=$FFREEFORMFLAG" >&5
+$as_echo "$as_me: DEBUG: FC=$FC F90FLAGS=$F90FLAGS FFREEFORMFLAG=$FFREEFORMFLAG" >&6;}
+ fi
+
+
+
+ FC=${FC_saved}
+
+ ac_ext=f
+ac_compile='$F77 -c $FFLAGS conftest.$ac_ext >&5'
+ac_link='$F77 -o conftest$ac_exeext $FFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_f77_compiler_gnu
+
+ cat > conftest.$ac_ext <<_ACEOF
+ program main
+ call MPI_Comm_rank
+ end
+_ACEOF
+if ac_fn_f77_try_compile "$LINENO"; then :
+ valid_mpif77=yes
+else
+ valid_mpif77=no
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ if test "x${valid_mpif77}" = xno && test "x${enable_fortran}" = xyes ; then
+ as_fn_error $? "
+ ------------------------------------------------------------
+ Invalid MPI Fortran 77 compiler specified: \"${MPIF77}\"
+ A working MPI compiler is required. Please specify the
+ location of one either with the MPIF77 environment
+ variable or the --with-mpi configure flag
+ ------------------------------------------------------------" "$LINENO" 5
+ fi
+fi
+
+
+if test "x${enable_fortran}" = xauto ; then
+ if test "x${valid_mpif77}" = xyes && test "x${valid_mpif90}" = xyes ; then
+ enable_fortran=yes
+ else
+ enable_fortran=no
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING:
+ ------------------------------------------------------------
+ Either MPI Fortran 77 or 90 compiler is not working:
+ \"MPIF77 = ${MPIF77}\"
+ \"MPIF90 = ${MPIF90}\"
+ Disable Fortran feature ...
+ ------------------------------------------------------------" >&5
+$as_echo "$as_me: WARNING:
+ ------------------------------------------------------------
+ Either MPI Fortran 77 or 90 compiler is not working:
+ \"MPIF77 = ${MPIF77}\"
+ \"MPIF90 = ${MPIF90}\"
+ Disable Fortran feature ...
+ ------------------------------------------------------------" >&2;}
+ fi
+fi
+
+if test "x${enable_fortran}" = xyes ; then
+ ac_ext=${ac_fc_srcext-f}
+ac_compile='$FC -c $FCFLAGS $ac_fcflags_srcext conftest.$ac_ext >&5'
+ac_link='$FC -o conftest$ac_exeext $FCFLAGS $LDFLAGS $ac_fcflags_srcext conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_fc_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Fortran flag to compile preprocessed .f files" >&5
+$as_echo_n "checking for Fortran flag to compile preprocessed .f files... " >&6; }
+if ${ac_cv_fc_pp_srcext_f+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_ext=f
+FCFLAGS_SRCEXT_save=$FCFLAGS_SRCEXT
+FCFLAGS_SRCEXT=
+ac_fcflags_pp_srcext_save=$ac_fcflags_srcext
+ac_fcflags_srcext=
+ac_cv_fc_pp_srcext_f=unknown
+case $ac_ext in #(
+ [fF]77) ac_try=f77-cpp-input;; #(
+ [fF]) ac_try=f77-cpp-input;; #(
+ *) ac_try=f95-cpp-input;;
+esac
+for ac_flag in none -ftpp -fpp -Tf "-fpp -Tf" -xpp=fpp -Mpreprocess "-e Z" \
+ -cpp -xpp=cpp -qsuffix=cpp=f "-x $ac_try" +cpp -Cpp; do
+ test "x$ac_flag" != xnone && FCFLAGS_SRCEXT="$ac_flag" && ac_fcflags_srcext="$ac_flag"
+ cat > conftest.$ac_ext <<_ACEOF
+ program main
+
+#if 0
+#include <ac_nonexistent.h>
+ choke me
+#endif
+ end
+_ACEOF
+if ac_fn_fc_try_compile "$LINENO"; then :
+ cat > conftest.$ac_ext <<_ACEOF
+ program main
+
+#if 1
+#include <ac_nonexistent.h>
+ choke me
+#endif
+ end
+_ACEOF
+if ac_fn_fc_try_compile "$LINENO"; then :
+
+else
+ ac_cv_fc_pp_srcext_f=$ac_flag; break
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+${RM} -f conftest.$ac_objext conftest.f
+FCFLAGS_SRCEXT=$FCFLAGS_SRCEXT_save
+ac_fcflags_srcext=$ac_fcflags_pp_srcext_save
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_fc_pp_srcext_f" >&5
+$as_echo "$ac_cv_fc_pp_srcext_f" >&6; }
+if test "x$ac_cv_fc_pp_srcext_f" = xunknown; then
+ as_fn_error $? "Fortran could not compile preprocessed .f files" "$LINENO" 5
+else
+ ac_fc_srcext=f
+ if test "x$ac_cv_fc_pp_srcext_f" = xnone; then
+ FCFLAGS_SRCEXT=""
+ ac_cv_fc_pp_srcext_f=""
+ else
+ FCFLAGS_SRCEXT=$ac_cv_fc_pp_srcext_f
+ fi
+
+fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+ ac_ext=${ac_fc_srcext-f}
+ac_compile='$FC -c $FCFLAGS $ac_fcflags_srcext conftest.$ac_ext >&5'
+ac_link='$FC -o conftest$ac_exeext $FCFLAGS $LDFLAGS $ac_fcflags_srcext conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_fc_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Fortran flag to compile preprocessed .F files" >&5
+$as_echo_n "checking for Fortran flag to compile preprocessed .F files... " >&6; }
+if ${ac_cv_fc_pp_srcext_F+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_ext=F
+FCFLAGS_SRCEXT_save=$FCFLAGS_SRCEXT
+FCFLAGS_SRCEXT=
+ac_fcflags_pp_srcext_save=$ac_fcflags_srcext
+ac_fcflags_srcext=
+ac_cv_fc_pp_srcext_F=unknown
+case $ac_ext in #(
+ [fF]77) ac_try=f77-cpp-input;; #(
+ [fF]) ac_try=f77-cpp-input;; #(
+ *) ac_try=f95-cpp-input;;
+esac
+for ac_flag in none -ftpp -fpp -Tf "-fpp -Tf" -xpp=fpp -Mpreprocess "-e Z" \
+ -cpp -xpp=cpp -qsuffix=cpp=F "-x $ac_try" +cpp -Cpp; do
+ test "x$ac_flag" != xnone && FCFLAGS_SRCEXT="$ac_flag" && ac_fcflags_srcext="$ac_flag"
+ cat > conftest.$ac_ext <<_ACEOF
+ program main
+
+#if 0
+#include <ac_nonexistent.h>
+ choke me
+#endif
+ end
+_ACEOF
+if ac_fn_fc_try_compile "$LINENO"; then :
+ cat > conftest.$ac_ext <<_ACEOF
+ program main
+
+#if 1
+#include <ac_nonexistent.h>
+ choke me
+#endif
+ end
+_ACEOF
+if ac_fn_fc_try_compile "$LINENO"; then :
+
+else
+ ac_cv_fc_pp_srcext_F=$ac_flag; break
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+${RM} -f conftest.$ac_objext conftest.F
+FCFLAGS_SRCEXT=$FCFLAGS_SRCEXT_save
+ac_fcflags_srcext=$ac_fcflags_pp_srcext_save
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_fc_pp_srcext_F" >&5
+$as_echo "$ac_cv_fc_pp_srcext_F" >&6; }
+if test "x$ac_cv_fc_pp_srcext_F" = xunknown; then
+ as_fn_error $? "Fortran could not compile preprocessed .F files" "$LINENO" 5
+else
+ ac_fc_srcext=F
+ if test "x$ac_cv_fc_pp_srcext_F" = xnone; then
+ FCFLAGS_SRCEXT=""
+ ac_cv_fc_pp_srcext_F=""
+ else
+ FCFLAGS_SRCEXT=$ac_cv_fc_pp_srcext_F
+ fi
+
+fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+ ac_ext=${ac_fc_srcext-f}
+ac_compile='$FC -c $FCFLAGS $ac_fcflags_srcext conftest.$ac_ext >&5'
+ac_link='$FC -o conftest$ac_exeext $FCFLAGS $LDFLAGS $ac_fcflags_srcext conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_fc_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Fortran flag to compile preprocessed .f90 files" >&5
+$as_echo_n "checking for Fortran flag to compile preprocessed .f90 files... " >&6; }
+if ${ac_cv_fc_pp_srcext_f90+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_ext=f90
+FCFLAGS_SRCEXT_save=$FCFLAGS_SRCEXT
+FCFLAGS_SRCEXT=
+ac_fcflags_pp_srcext_save=$ac_fcflags_srcext
+ac_fcflags_srcext=
+ac_cv_fc_pp_srcext_f90=unknown
+case $ac_ext in #(
+ [fF]77) ac_try=f77-cpp-input;; #(
+ [fF]) ac_try=f77-cpp-input;; #(
+ *) ac_try=f95-cpp-input;;
+esac
+for ac_flag in none -ftpp -fpp -Tf "-fpp -Tf" -xpp=fpp -Mpreprocess "-e Z" \
+ -cpp -xpp=cpp -qsuffix=cpp=f90 "-x $ac_try" +cpp -Cpp; do
+ test "x$ac_flag" != xnone && FCFLAGS_SRCEXT="$ac_flag" && ac_fcflags_srcext="$ac_flag"
+ cat > conftest.$ac_ext <<_ACEOF
+ program main
+
+#if 0
+#include <ac_nonexistent.h>
+ choke me
+#endif
+ end
+_ACEOF
+if ac_fn_fc_try_compile "$LINENO"; then :
+ cat > conftest.$ac_ext <<_ACEOF
+ program main
+
+#if 1
+#include <ac_nonexistent.h>
+ choke me
+#endif
+ end
+_ACEOF
+if ac_fn_fc_try_compile "$LINENO"; then :
+
+else
+ ac_cv_fc_pp_srcext_f90=$ac_flag; break
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+${RM} -f conftest.$ac_objext conftest.f90
+FCFLAGS_SRCEXT=$FCFLAGS_SRCEXT_save
+ac_fcflags_srcext=$ac_fcflags_pp_srcext_save
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_fc_pp_srcext_f90" >&5
+$as_echo "$ac_cv_fc_pp_srcext_f90" >&6; }
+if test "x$ac_cv_fc_pp_srcext_f90" = xunknown; then
+ as_fn_error $? "Fortran could not compile preprocessed .f90 files" "$LINENO" 5
+else
+ ac_fc_srcext=f90
+ if test "x$ac_cv_fc_pp_srcext_f90" = xnone; then
+ FCFLAGS_SRCEXT=""
+ ac_cv_fc_pp_srcext_f90=""
+ else
+ FCFLAGS_SRCEXT=$ac_cv_fc_pp_srcext_f90
+ fi
+
+fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+ ac_ext=${ac_fc_srcext-f}
+ac_compile='$FC -c $FCFLAGS $ac_fcflags_srcext conftest.$ac_ext >&5'
+ac_link='$FC -o conftest$ac_exeext $FCFLAGS $LDFLAGS $ac_fcflags_srcext conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_fc_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Fortran flag to compile preprocessed .F90 files" >&5
+$as_echo_n "checking for Fortran flag to compile preprocessed .F90 files... " >&6; }
+if ${ac_cv_fc_pp_srcext_F90+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_ext=F90
+FCFLAGS_SRCEXT_save=$FCFLAGS_SRCEXT
+FCFLAGS_SRCEXT=
+ac_fcflags_pp_srcext_save=$ac_fcflags_srcext
+ac_fcflags_srcext=
+ac_cv_fc_pp_srcext_F90=unknown
+case $ac_ext in #(
+ [fF]77) ac_try=f77-cpp-input;; #(
+ [fF]) ac_try=f77-cpp-input;; #(
+ *) ac_try=f95-cpp-input;;
+esac
+for ac_flag in none -ftpp -fpp -Tf "-fpp -Tf" -xpp=fpp -Mpreprocess "-e Z" \
+ -cpp -xpp=cpp -qsuffix=cpp=F90 "-x $ac_try" +cpp -Cpp; do
+ test "x$ac_flag" != xnone && FCFLAGS_SRCEXT="$ac_flag" && ac_fcflags_srcext="$ac_flag"
+ cat > conftest.$ac_ext <<_ACEOF
+ program main
+
+#if 0
+#include <ac_nonexistent.h>
+ choke me
+#endif
+ end
+_ACEOF
+if ac_fn_fc_try_compile "$LINENO"; then :
+ cat > conftest.$ac_ext <<_ACEOF
+ program main
+
+#if 1
+#include <ac_nonexistent.h>
+ choke me
+#endif
+ end
+_ACEOF
+if ac_fn_fc_try_compile "$LINENO"; then :
+
+else
+ ac_cv_fc_pp_srcext_F90=$ac_flag; break
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+${RM} -f conftest.$ac_objext conftest.F90
+FCFLAGS_SRCEXT=$FCFLAGS_SRCEXT_save
+ac_fcflags_srcext=$ac_fcflags_pp_srcext_save
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_fc_pp_srcext_F90" >&5
+$as_echo "$ac_cv_fc_pp_srcext_F90" >&6; }
+if test "x$ac_cv_fc_pp_srcext_F90" = xunknown; then
+ as_fn_error $? "Fortran could not compile preprocessed .F90 files" "$LINENO" 5
+else
+ ac_fc_srcext=F90
+ if test "x$ac_cv_fc_pp_srcext_F90" = xnone; then
+ FCFLAGS_SRCEXT=""
+ ac_cv_fc_pp_srcext_F90=""
+ else
+ FCFLAGS_SRCEXT=$ac_cv_fc_pp_srcext_F90
+ fi
+
+fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ F77PPFLAGS_f=${ac_cv_fc_pp_srcext_f}
+ F77PPFLAGS_F=${ac_cv_fc_pp_srcext_F}
+ F90PPFLAGS_f90=${ac_cv_fc_pp_srcext_f90}
+ F90PPFLAGS_F90=${ac_cv_fc_pp_srcext_F90}
+
+
+
+
+
+ FPPFLAGS=${FPPFLAGS-}
+
+
+
+ ac_ext=${ac_fc_srcext-f}
+ac_compile='$FC -c $FCFLAGS $ac_fcflags_srcext conftest.$ac_ext >&5'
+ac_link='$FC -o conftest$ac_exeext $FCFLAGS $LDFLAGS $ac_fcflags_srcext conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_fc_compiler_gnu
+ac_fc_pp_define_srcext_save=$ac_fc_srcext
+ac_ext_saved=$ac_ext
+ac_ext=${ac_fc_srcext-f}
+ac_compile='$FC -c $FCFLAGS $ac_fcflags_srcext conftest.$ac_ext >&5'
+ac_link='$FC -o conftest$ac_exeext $FCFLAGS $LDFLAGS $ac_fcflags_srcext conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_fc_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Fortran flag to compile preprocessed .F files" >&5
+$as_echo_n "checking for Fortran flag to compile preprocessed .F files... " >&6; }
+if ${ac_cv_fc_pp_srcext_F+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_ext=F
+FCFLAGS_SRCEXT_save=$FCFLAGS_SRCEXT
+FCFLAGS_SRCEXT=
+ac_fcflags_pp_srcext_save=$ac_fcflags_srcext
+ac_fcflags_srcext=
+ac_cv_fc_pp_srcext_F=unknown
+case $ac_ext in #(
+ [fF]77) ac_try=f77-cpp-input;; #(
+ [fF]) ac_try=f77-cpp-input;; #(
+ *) ac_try=f95-cpp-input;;
+esac
+for ac_flag in none -ftpp -fpp -Tf "-fpp -Tf" -xpp=fpp -Mpreprocess "-e Z" \
+ -cpp -xpp=cpp -qsuffix=cpp=F "-x $ac_try" +cpp -Cpp; do
+ test "x$ac_flag" != xnone && FCFLAGS_SRCEXT="$ac_flag" && ac_fcflags_srcext="$ac_flag"
+ cat > conftest.$ac_ext <<_ACEOF
+ program main
+
+#if 0
+#include <ac_nonexistent.h>
+ choke me
+#endif
+ end
+_ACEOF
+if ac_fn_fc_try_compile "$LINENO"; then :
+ cat > conftest.$ac_ext <<_ACEOF
+ program main
+
+#if 1
+#include <ac_nonexistent.h>
+ choke me
+#endif
+ end
+_ACEOF
+if ac_fn_fc_try_compile "$LINENO"; then :
+
+else
+ ac_cv_fc_pp_srcext_F=$ac_flag; break
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+${RM} -f conftest.$ac_objext conftest.F
+FCFLAGS_SRCEXT=$FCFLAGS_SRCEXT_save
+ac_fcflags_srcext=$ac_fcflags_pp_srcext_save
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_fc_pp_srcext_F" >&5
+$as_echo "$ac_cv_fc_pp_srcext_F" >&6; }
+if test "x$ac_cv_fc_pp_srcext_F" = xunknown; then
+ as_fn_error $? "Fortran could not compile preprocessed .F files" "$LINENO" 5
+else
+ ac_fc_srcext=F
+ if test "x$ac_cv_fc_pp_srcext_F" = xnone; then
+ FCFLAGS_SRCEXT=""
+ ac_cv_fc_pp_srcext_F=""
+ else
+ FCFLAGS_SRCEXT=$ac_cv_fc_pp_srcext_F
+ fi
+
+fi
+ac_ext=${ac_fc_srcext-f}
+ac_compile='$FC -c $FCFLAGS $ac_fcflags_srcext conftest.$ac_ext >&5'
+ac_link='$FC -o conftest$ac_exeext $FCFLAGS $LDFLAGS $ac_fcflags_srcext conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_fc_compiler_gnu
+
+ac_ext=F
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to define symbols for preprocessed Fortran" >&5
+$as_echo_n "checking how to define symbols for preprocessed Fortran... " >&6; }
+if ${ac_cv_fc_pp_define+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_fc_pp_define_srcext_save=$ac_fc_srcext
+ac_cv_fc_pp_define=unknown
+ac_fc_pp_define_FCFLAGS_save=$FCFLAGS
+for ac_flag in -D -WF,-D -Wp,-D -Wc,-D
+do
+ FCFLAGS="$ac_fc_pp_define_FCFLAGS_save ${ac_flag}FOOBAR ${ac_flag}ZORK=42"
+ cat > conftest.$ac_ext <<_ACEOF
+ program main
+
+#ifndef FOOBAR
+ choke me
+#endif
+#if ZORK != 42
+ choke me
+#endif
+ end
+_ACEOF
+if ac_fn_fc_try_compile "$LINENO"; then :
+ ac_cv_fc_pp_define=$ac_flag
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ test x"$ac_cv_fc_pp_define" != xunknown && break
+done
+FCFLAGS=$ac_fc_pp_define_FCFLAGS_save
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_fc_pp_define" >&5
+$as_echo "$ac_cv_fc_pp_define" >&6; }
+ac_fc_srcext=$ac_fc_pp_define_srcext_save
+if test "x$ac_cv_fc_pp_define" = xunknown; then
+ FC_DEFINE=
+ as_fn_error 77 "Fortran does not allow to define preprocessor symbols" "$LINENO" 5
+else
+ FC_DEFINE=$ac_cv_fc_pp_define
+
+fi
+ac_ext=$ac_ext_saved
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+ ac_ext=${ac_fc_srcext-f}
+ac_compile='$FC -c $FCFLAGS $ac_fcflags_srcext conftest.$ac_ext >&5'
+ac_link='$FC -o conftest$ac_exeext $FCFLAGS $LDFLAGS $ac_fcflags_srcext conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_fc_compiler_gnu
+
+ ac_ext=${ac_fc_srcext-f}
+ac_compile='$FC -c $FCFLAGS $ac_fcflags_srcext conftest.$ac_ext >&5'
+ac_link='$FC -o conftest$ac_exeext $FCFLAGS $LDFLAGS $ac_fcflags_srcext conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_fc_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Fortran flag to compile .f files" >&5
+$as_echo_n "checking for Fortran flag to compile .f files... " >&6; }
+if ${ac_cv_fc_srcext_f+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_ext=f
+ac_fcflags_srcext_save=$ac_fcflags_srcext
+ac_fcflags_srcext=
+ac_cv_fc_srcext_f=unknown
+case $ac_ext in #(
+ [fF]77) ac_try=f77;; #(
+ *) ac_try=f95;;
+esac
+for ac_flag in none -qsuffix=f=f -Tf "-x $ac_try"; do
+ test "x$ac_flag" != xnone && ac_fcflags_srcext="$ac_flag"
+ cat > conftest.$ac_ext <<_ACEOF
+ program main
+
+ end
+_ACEOF
+if ac_fn_fc_try_compile "$LINENO"; then :
+ ac_cv_fc_srcext_f=$ac_flag; break
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+rm -f conftest.$ac_objext conftest.f
+ac_fcflags_srcext=$ac_fcflags_srcext_save
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_fc_srcext_f" >&5
+$as_echo "$ac_cv_fc_srcext_f" >&6; }
+if test "x$ac_cv_fc_srcext_f" = xunknown; then
+ as_fn_error $? "Fortran could not compile .f files" "$LINENO" 5
+else
+ ac_fc_srcext=f
+ if test "x$ac_cv_fc_srcext_f" = xnone; then
+ ac_fcflags_srcext=""
+ FCFLAGS_f=""
+ else
+ ac_fcflags_srcext=$ac_cv_fc_srcext_f
+ FCFLAGS_f=$ac_cv_fc_srcext_f
+ fi
+
+
+fi
+ac_ext=${ac_fc_srcext-f}
+ac_compile='$FC -c $FCFLAGS $ac_fcflags_srcext conftest.$ac_ext >&5'
+ac_link='$FC -o conftest$ac_exeext $FCFLAGS $LDFLAGS $ac_fcflags_srcext conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_fc_compiler_gnu
+
+ ac_ext=${ac_fc_srcext-f}
+ac_compile='$FC -c $FCFLAGS $ac_fcflags_srcext conftest.$ac_ext >&5'
+ac_link='$FC -o conftest$ac_exeext $FCFLAGS $LDFLAGS $ac_fcflags_srcext conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_fc_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Fortran flag to compile .F files" >&5
+$as_echo_n "checking for Fortran flag to compile .F files... " >&6; }
+if ${ac_cv_fc_srcext_F+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_ext=F
+ac_fcflags_srcext_save=$ac_fcflags_srcext
+ac_fcflags_srcext=
+ac_cv_fc_srcext_F=unknown
+case $ac_ext in #(
+ [fF]77) ac_try=f77;; #(
+ *) ac_try=f95;;
+esac
+for ac_flag in none -qsuffix=f=F -Tf "-x $ac_try"; do
+ test "x$ac_flag" != xnone && ac_fcflags_srcext="$ac_flag"
+ cat > conftest.$ac_ext <<_ACEOF
+ program main
+
+ end
+_ACEOF
+if ac_fn_fc_try_compile "$LINENO"; then :
+ ac_cv_fc_srcext_F=$ac_flag; break
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+rm -f conftest.$ac_objext conftest.F
+ac_fcflags_srcext=$ac_fcflags_srcext_save
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_fc_srcext_F" >&5
+$as_echo "$ac_cv_fc_srcext_F" >&6; }
+if test "x$ac_cv_fc_srcext_F" = xunknown; then
+ as_fn_error $? "Fortran could not compile .F files" "$LINENO" 5
+else
+ ac_fc_srcext=F
+ if test "x$ac_cv_fc_srcext_F" = xnone; then
+ ac_fcflags_srcext=""
+ FCFLAGS_F=""
+ else
+ ac_fcflags_srcext=$ac_cv_fc_srcext_F
+ FCFLAGS_F=$ac_cv_fc_srcext_F
+ fi
+
+
+fi
+ac_ext=${ac_fc_srcext-f}
+ac_compile='$FC -c $FCFLAGS $ac_fcflags_srcext conftest.$ac_ext >&5'
+ac_link='$FC -o conftest$ac_exeext $FCFLAGS $LDFLAGS $ac_fcflags_srcext conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_fc_compiler_gnu
+
+ ac_ext=${ac_fc_srcext-f}
+ac_compile='$FC -c $FCFLAGS $ac_fcflags_srcext conftest.$ac_ext >&5'
+ac_link='$FC -o conftest$ac_exeext $FCFLAGS $LDFLAGS $ac_fcflags_srcext conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_fc_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Fortran flag to compile .f90 files" >&5
+$as_echo_n "checking for Fortran flag to compile .f90 files... " >&6; }
+if ${ac_cv_fc_srcext_f90+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_ext=f90
+ac_fcflags_srcext_save=$ac_fcflags_srcext
+ac_fcflags_srcext=
+ac_cv_fc_srcext_f90=unknown
+case $ac_ext in #(
+ [fF]77) ac_try=f77;; #(
+ *) ac_try=f95;;
+esac
+for ac_flag in none -qsuffix=f=f90 -Tf "-x $ac_try"; do
+ test "x$ac_flag" != xnone && ac_fcflags_srcext="$ac_flag"
+ cat > conftest.$ac_ext <<_ACEOF
+ program main
+
+ end
+_ACEOF
+if ac_fn_fc_try_compile "$LINENO"; then :
+ ac_cv_fc_srcext_f90=$ac_flag; break
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+rm -f conftest.$ac_objext conftest.f90
+ac_fcflags_srcext=$ac_fcflags_srcext_save
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_fc_srcext_f90" >&5
+$as_echo "$ac_cv_fc_srcext_f90" >&6; }
+if test "x$ac_cv_fc_srcext_f90" = xunknown; then
+ as_fn_error $? "Fortran could not compile .f90 files" "$LINENO" 5
+else
+ ac_fc_srcext=f90
+ if test "x$ac_cv_fc_srcext_f90" = xnone; then
+ ac_fcflags_srcext=""
+ FCFLAGS_f90=""
+ else
+ ac_fcflags_srcext=$ac_cv_fc_srcext_f90
+ FCFLAGS_f90=$ac_cv_fc_srcext_f90
+ fi
+
+
+fi
+ac_ext=${ac_fc_srcext-f}
+ac_compile='$FC -c $FCFLAGS $ac_fcflags_srcext conftest.$ac_ext >&5'
+ac_link='$FC -o conftest$ac_exeext $FCFLAGS $LDFLAGS $ac_fcflags_srcext conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_fc_compiler_gnu
+
+ ac_ext=${ac_fc_srcext-f}
+ac_compile='$FC -c $FCFLAGS $ac_fcflags_srcext conftest.$ac_ext >&5'
+ac_link='$FC -o conftest$ac_exeext $FCFLAGS $LDFLAGS $ac_fcflags_srcext conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_fc_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Fortran flag to compile .F90 files" >&5
+$as_echo_n "checking for Fortran flag to compile .F90 files... " >&6; }
+if ${ac_cv_fc_srcext_F90+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_ext=F90
+ac_fcflags_srcext_save=$ac_fcflags_srcext
+ac_fcflags_srcext=
+ac_cv_fc_srcext_F90=unknown
+case $ac_ext in #(
+ [fF]77) ac_try=f77;; #(
+ *) ac_try=f95;;
+esac
+for ac_flag in none -qsuffix=f=F90 -Tf "-x $ac_try"; do
+ test "x$ac_flag" != xnone && ac_fcflags_srcext="$ac_flag"
+ cat > conftest.$ac_ext <<_ACEOF
+ program main
+
+ end
+_ACEOF
+if ac_fn_fc_try_compile "$LINENO"; then :
+ ac_cv_fc_srcext_F90=$ac_flag; break
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+rm -f conftest.$ac_objext conftest.F90
+ac_fcflags_srcext=$ac_fcflags_srcext_save
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_fc_srcext_F90" >&5
+$as_echo "$ac_cv_fc_srcext_F90" >&6; }
+if test "x$ac_cv_fc_srcext_F90" = xunknown; then
+ as_fn_error $? "Fortran could not compile .F90 files" "$LINENO" 5
+else
+ ac_fc_srcext=F90
+ if test "x$ac_cv_fc_srcext_F90" = xnone; then
+ ac_fcflags_srcext=""
+ FCFLAGS_F90=""
+ else
+ ac_fcflags_srcext=$ac_cv_fc_srcext_F90
+ FCFLAGS_F90=$ac_cv_fc_srcext_F90
+ fi
+
+
+fi
+ac_ext=${ac_fc_srcext-f}
+ac_compile='$FC -c $FCFLAGS $ac_fcflags_srcext conftest.$ac_ext >&5'
+ac_link='$FC -o conftest$ac_exeext $FCFLAGS $LDFLAGS $ac_fcflags_srcext conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_fc_compiler_gnu
+
+
+
+
+
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+ ac_ext=${ac_fc_srcext-f}
+ac_compile='$FC -c $FCFLAGS $ac_fcflags_srcext conftest.$ac_ext >&5'
+ac_link='$FC -o conftest$ac_exeext $FCFLAGS $LDFLAGS $ac_fcflags_srcext conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_fc_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Fortran flag needed to accept fixed-form source" >&5
+$as_echo_n "checking for Fortran flag needed to accept fixed-form source... " >&6; }
+if ${ac_cv_fc_fixedform+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_fc_fixedform=unknown
+ac_fc_fixedform_FCFLAGS_save=$FCFLAGS
+for ac_flag in none -ffixed-form -fixed -qfixed -Mfixed -fixedform "-f fixed" \
+ +source=fixed -fix --fix -Fixed
+do
+ test "x$ac_flag" != xnone && FCFLAGS="$ac_fc_fixedform_FCFLAGS_save $ac_flag"
+ cat > conftest.$ac_ext <<_ACEOF
+
+C This comment should confuse free-form compilers.
+ program main
+ end
+_ACEOF
+if ac_fn_fc_try_compile "$LINENO"; then :
+ ac_cv_fc_fixedform=$ac_flag; break
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+${RM} -f conftest.err conftest.$ac_objext conftest.$ac_ext
+FCFLAGS=$ac_fc_fixedform_FCFLAGS_save
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_fc_fixedform" >&5
+$as_echo "$ac_cv_fc_fixedform" >&6; }
+if test "x$ac_cv_fc_fixedform" = xunknown; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Fortran does not accept fixed-form source" >&5
+$as_echo "$as_me: WARNING: Fortran does not accept fixed-form source" >&2;}
+ ac_cv_fc_fixedform=
+else
+ if test "x$ac_cv_fc_fixedform" = xnone; then
+ ac_cv_fc_fixedform=
+ fi
+
+fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ FFIXEDFORMFLAG=${ac_cv_fc_fixedform}
+ if test "x${_DEBUG}" = xyes ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: DEBUG: FC=$FC F90FLAGS=$F90FLAGS FFIXEDFORMFLAG=$FFIXEDFORMFLAG" >&5
+$as_echo "$as_me: DEBUG: FC=$FC F90FLAGS=$F90FLAGS FFIXEDFORMFLAG=$FFIXEDFORMFLAG" >&6;}
+ fi
+
+
+
+
+ # Checking for Fortran types also determines the Fortran name mangling
+ # and places the value into FCALLSCSUB as the C name corresponding
+ # to the Fortran name SUB
+ ac_ext=${ac_fc_srcext-f}
+ac_compile='$FC -c $FCFLAGS $ac_fcflags_srcext conftest.$ac_ext >&5'
+ac_link='$FC -o conftest$ac_exeext $FCFLAGS $LDFLAGS $ac_fcflags_srcext conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_fc_compiler_gnu
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for dummy main to link with Fortran libraries" >&5
+$as_echo_n "checking for dummy main to link with Fortran libraries... " >&6; }
+if ${ac_cv_fc_dummy_main+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_fc_dm_save_LIBS=$LIBS
+ LIBS="$LIBS $FCLIBS"
+ ac_fortran_dm_var=FC_DUMMY_MAIN
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ # First, try linking without a dummy main:
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#ifdef FC_DUMMY_MAIN
+#ifndef FC_DUMMY_MAIN_EQ_F77
+# ifdef __cplusplus
+ extern "C"
+# endif
+ int FC_DUMMY_MAIN() { return 1; }
+#endif
+#endif
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_fortran_dummy_main=none
+else
+ ac_cv_fortran_dummy_main=unknown
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+
+ if test $ac_cv_fortran_dummy_main = unknown; then
+ for ac_func in MAIN__ MAIN_ __main MAIN _MAIN __MAIN main_ main__ _main; do
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#define $ac_fortran_dm_var $ac_func
+#ifdef FC_DUMMY_MAIN
+#ifndef FC_DUMMY_MAIN_EQ_F77
+# ifdef __cplusplus
+ extern "C"
+# endif
+ int FC_DUMMY_MAIN() { return 1; }
+#endif
+#endif
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_fortran_dummy_main=$ac_func; break
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ done
+ fi
+ ac_ext=${ac_fc_srcext-f}
+ac_compile='$FC -c $FCFLAGS $ac_fcflags_srcext conftest.$ac_ext >&5'
+ac_link='$FC -o conftest$ac_exeext $FCFLAGS $LDFLAGS $ac_fcflags_srcext conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_fc_compiler_gnu
+ ac_cv_fc_dummy_main=$ac_cv_fortran_dummy_main
+ rm -rf conftest*
+ LIBS=$ac_fc_dm_save_LIBS
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_fc_dummy_main" >&5
+$as_echo "$ac_cv_fc_dummy_main" >&6; }
+FC_DUMMY_MAIN=$ac_cv_fc_dummy_main
+if test "$FC_DUMMY_MAIN" != unknown; then :
+ if test $FC_DUMMY_MAIN != none; then
+
+cat >>confdefs.h <<_ACEOF
+#define FC_DUMMY_MAIN $FC_DUMMY_MAIN
+_ACEOF
+
+ if test "x$ac_cv_fc_dummy_main" = "x$ac_cv_f77_dummy_main"; then
+
+$as_echo "#define FC_DUMMY_MAIN_EQ_F77 1" >>confdefs.h
+
+ fi
+fi
+else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "linking to Fortran libraries from C fails
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ac_ext=${ac_fc_srcext-f}
+ac_compile='$FC -c $FCFLAGS $ac_fcflags_srcext conftest.$ac_ext >&5'
+ac_link='$FC -o conftest$ac_exeext $FCFLAGS $LDFLAGS $ac_fcflags_srcext conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_fc_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Fortran name-mangling scheme" >&5
+$as_echo_n "checking for Fortran name-mangling scheme... " >&6; }
+if ${ac_cv_fc_mangling+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat > conftest.$ac_ext <<_ACEOF
+ subroutine foobar()
+ return
+ end
+ subroutine foo_bar()
+ return
+ end
+_ACEOF
+if ac_fn_fc_try_compile "$LINENO"; then :
+ mv conftest.$ac_objext cfortran_test.$ac_objext
+
+ ac_save_LIBS=$LIBS
+ LIBS="cfortran_test.$ac_objext $LIBS $FCLIBS"
+
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+ ac_success=no
+ for ac_foobar in foobar FOOBAR; do
+ for ac_underscore in "" "_"; do
+ ac_func="$ac_foobar$ac_underscore"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $ac_func ();
+#ifdef FC_DUMMY_MAIN
+#ifndef FC_DUMMY_MAIN_EQ_F77
+# ifdef __cplusplus
+ extern "C"
+# endif
+ int FC_DUMMY_MAIN() { return 1; }
+#endif
+#endif
+int
+main ()
+{
+return $ac_func ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_success=yes; break 2
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ done
+ done
+ ac_ext=${ac_fc_srcext-f}
+ac_compile='$FC -c $FCFLAGS $ac_fcflags_srcext conftest.$ac_ext >&5'
+ac_link='$FC -o conftest$ac_exeext $FCFLAGS $LDFLAGS $ac_fcflags_srcext conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_fc_compiler_gnu
+
+ if test "$ac_success" = "yes"; then
+ case $ac_foobar in
+ foobar)
+ ac_case=lower
+ ac_foo_bar=foo_bar
+ ;;
+ FOOBAR)
+ ac_case=upper
+ ac_foo_bar=FOO_BAR
+ ;;
+ esac
+
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+ ac_success_extra=no
+ for ac_extra in "" "_"; do
+ ac_func="$ac_foo_bar$ac_underscore$ac_extra"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $ac_func ();
+#ifdef FC_DUMMY_MAIN
+#ifndef FC_DUMMY_MAIN_EQ_F77
+# ifdef __cplusplus
+ extern "C"
+# endif
+ int FC_DUMMY_MAIN() { return 1; }
+#endif
+#endif
+int
+main ()
+{
+return $ac_func ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_success_extra=yes; break
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ done
+ ac_ext=${ac_fc_srcext-f}
+ac_compile='$FC -c $FCFLAGS $ac_fcflags_srcext conftest.$ac_ext >&5'
+ac_link='$FC -o conftest$ac_exeext $FCFLAGS $LDFLAGS $ac_fcflags_srcext conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_fc_compiler_gnu
+
+ if test "$ac_success_extra" = "yes"; then
+ ac_cv_fc_mangling="$ac_case case"
+ if test -z "$ac_underscore"; then
+ ac_cv_fc_mangling="$ac_cv_fc_mangling, no underscore"
+ else
+ ac_cv_fc_mangling="$ac_cv_fc_mangling, underscore"
+ fi
+ if test -z "$ac_extra"; then
+ ac_cv_fc_mangling="$ac_cv_fc_mangling, no extra underscore"
+ else
+ ac_cv_fc_mangling="$ac_cv_fc_mangling, extra underscore"
+ fi
+ else
+ ac_cv_fc_mangling="unknown"
+ fi
+ else
+ ac_cv_fc_mangling="unknown"
+ fi
+
+ LIBS=$ac_save_LIBS
+ rm -rf conftest*
+ rm -f cfortran_test*
+else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot compile a simple Fortran program
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_fc_mangling" >&5
+$as_echo "$ac_cv_fc_mangling" >&6; }
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ac_ext=${ac_fc_srcext-f}
+ac_compile='$FC -c $FCFLAGS $ac_fcflags_srcext conftest.$ac_ext >&5'
+ac_link='$FC -o conftest$ac_exeext $FCFLAGS $LDFLAGS $ac_fcflags_srcext conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_fc_compiler_gnu
+case $ac_cv_fc_mangling in
+ upper*) ac_val="SUB" ;;
+ lower*) ac_val="sub" ;;
+ *) ac_val="unknown" ;;
+esac
+case $ac_cv_fc_mangling in *," underscore"*) ac_val="$ac_val"_ ;; esac
+
+FCALLSCSUB="$ac_val"
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+ # determine the correct name mapping
+ case $FCALLSCSUB in
+ SUB)
+
+$as_echo "#define F77_NAME_UPPER /**/" >>confdefs.h
+
+ ;;
+ sub_)
+ # This is the hard case. Gcc uses one _ unless the name includes
+ # an underscore, in which case it gets two trailing underscores.
+ # Use essentially the same configure code that the original configure
+ # used to determine SUB
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for C-equivalent to Fortran routine \"SUB_A\"" >&5
+$as_echo_n "checking for C-equivalent to Fortran routine \"SUB_A\"... " >&6; }
+ ac_ext=${ac_fc_srcext-f}
+ac_compile='$FC -c $FCFLAGS $ac_fcflags_srcext conftest.$ac_ext >&5'
+ac_link='$FC -o conftest$ac_exeext $FCFLAGS $LDFLAGS $ac_fcflags_srcext conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_fc_compiler_gnu
+case $ac_cv_fc_mangling in
+ upper*) ac_val="SUB_A" ;;
+ lower*) ac_val="sub_a" ;;
+ *) ac_val="unknown" ;;
+esac
+case $ac_cv_fc_mangling in *," underscore"*) ac_val="$ac_val"_ ;; esac
+case $ac_cv_fc_mangling in *," extra underscore"*) ac_val="$ac_val"_ ;; esac
+
+FCALLSCSUBA="$ac_val"
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $FCALLSCSUBA" >&5
+$as_echo "$FCALLSCSUBA" >&6; }
+ case $FCALLSCSUBA in
+ sub_a__)
+
+$as_echo "#define F77_NAME_LOWER_2USCORE /**/" >>confdefs.h
+
+ ;;
+ sub_a_)
+
+$as_echo "#define F77_NAME_LOWER_USCORE /**/" >>confdefs.h
+
+ ;;
+ *)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unrecognized Fortran name mapping" >&5
+$as_echo "$as_me: WARNING: Unrecognized Fortran name mapping" >&2;}
+ ;;
+ esac
+ ;;
+ sub)
+
+$as_echo "#define F77_NAME_LOWER /**/" >>confdefs.h
+
+ ;;
+ *)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unrecognized Fortran name mapping" >&5
+$as_echo "$as_me: WARNING: Unrecognized Fortran name mapping" >&2;}
+ ;;
+ esac
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if Fortran compiler is NAG" >&5
+$as_echo_n "checking if Fortran compiler is NAG... " >&6; }
+if ${ac_cv_fc_compiler_nag+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_fc_compiler_nag=no
+ eval $MPIF90 -V </dev/null >& conftest.ver
+ _FC_VENDOR=`head -c 3 conftest.ver`
+ if test "x${_FC_VENDOR}" = xNAG ; then
+ ac_cv_fc_compiler_nag=yes
+ fi
+ ${RM} -f conftest.ver
+ unset _FC_VENDOR
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_fc_compiler_nag" >&5
+$as_echo "$ac_cv_fc_compiler_nag" >&6; }
+
+ if test "x${ac_cv_fc_compiler_nag}" = xyes ; then
+ NAGf90FPPFLAGS="-DNAGf90Fortran"
+ NAG_FCFLAGS="-mismatch"
+
+
+ fi
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking Fortran compiler treating constant modifier" >&5
+$as_echo_n "checking Fortran compiler treating constant modifier... " >&6; }
+if ${ac_cv_fc_constant_modifier+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_ext=f
+ac_compile='$F77 -c $FFLAGS conftest.$ac_ext >&5'
+ac_link='$F77 -o conftest$ac_exeext $FFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_f77_compiler_gnu
+
+ cat > conftest.$ac_ext <<_ACEOF
+
+ program main
+ integer*8 nf_fill_uint
+ integer*8 nf_fill_int64
+ parameter (nf_fill_uint = 4294967295_8)
+ parameter (nf_fill_int64 = -9223372036854775806_8)
+ end
+_ACEOF
+if ac_fn_f77_try_compile "$LINENO"; then :
+ ac_cv_fc_constant_modifier=8
+else
+ cat > conftest.$ac_ext <<_ACEOF
+
+ program main
+ integer*8 nf_fill_uint
+ integer*8 nf_fill_int64
+ parameter (nf_fill_uint = 4294967295)
+ parameter (nf_fill_int64 = -9223372036854775806)
+ end
+_ACEOF
+if ac_fn_f77_try_compile "$LINENO"; then :
+ ac_cv_fc_constant_modifier=none
+else
+ cat > conftest.$ac_ext <<_ACEOF
+
+ program main
+ integer, parameter :: EightByteInt = selected_int_kind(18)
+ integer*8 nf_fill_uint
+ integer*8 nf_fill_int64
+ parameter (nf_fill_uint = 4294967295_EightByteInt)
+ parameter (nf_fill_int64 = -9223372036854775806_EightByteInt)
+ end
+_ACEOF
+if ac_fn_f77_try_compile "$LINENO"; then :
+ ac_cv_fc_constant_modifier=EightByteInt
+else
+ as_fn_error $? "no appropriate modifier found" "$LINENO" 5
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_fc_constant_modifier" >&5
+$as_echo "$ac_cv_fc_constant_modifier" >&6; }
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+ if test "x${_DEBUG}" = xyes ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: DEBUG: ac_cv_fc_constant_modifier=$ac_cv_fc_constant_modifier" >&5
+$as_echo "$as_me: DEBUG: ac_cv_fc_constant_modifier=$ac_cv_fc_constant_modifier" >&6;}
+ fi
+
+
+ PNF_INT8_MODIFIER=""
+ if test "x${ac_cv_fc_constant_modifier}" = xnone ; then
+ PNF_FILL_UINT=4294967295
+ PNF_FILL_INT64=-9223372036854775806
+ PNF_FILL_UINT64=18446744073709551614
+ PNF_X_UINT_MAX=4294967295
+ PNF_X_INT8_MIN=-9223372036854775807
+ PNF_X_INT8_MAX=9223372036854775807
+ PNF_X_UINT8_MAX=18446744073709551615
+ else
+ if test "x${ac_cv_fc_constant_modifier}" = xEightByteInt ; then
+ PNF_INT8_MODIFIER=" integer, parameter :: EightByteInt = selected_int_kind(18)"
+ fi
+ PNF_FILL_UINT=4294967295_${ac_cv_fc_constant_modifier}
+ PNF_FILL_INT64=-9223372036854775806_${ac_cv_fc_constant_modifier}
+ PNF_FILL_UINT64=18446744073709551614_${ac_cv_fc_constant_modifier}
+ PNF_X_UINT_MAX=4294967295_${ac_cv_fc_constant_modifier}
+ PNF_X_INT8_MIN=-9223372036854775807_${ac_cv_fc_constant_modifier}
+ PNF_X_INT8_MAX=9223372036854775807_${ac_cv_fc_constant_modifier}
+ PNF_X_UINT8_MAX=18446744073709551615_${ac_cv_fc_constant_modifier}
+ fi
+
+
+
+
+
+
+
+
+
+
+
+fi
+
+# Find a good install program. We prefer a C program (faster),
+# so one script is as good as another. But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AmigaOS /C/install, which installs bootblocks on floppy discs
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# OS/2's system install, which has a completely different semantic
+# ./install, which can be erroneously created by make from ./install.sh.
+# Reject install programs that cannot install multiple files.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5
+$as_echo_n "checking for a BSD-compatible install... " >&6; }
+if test -z "$INSTALL"; then
+if ${ac_cv_path_install+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ # Account for people who put trailing slashes in PATH elements.
+case $as_dir/ in #((
+ ./ | .// | /[cC]/* | \
+ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+ ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \
+ /usr/ucb/* ) ;;
+ *)
+ # OSF1 and SCO ODT 3.0 have their own names for install.
+ # Don't use installbsd from OSF since it installs stuff as root
+ # by default.
+ for ac_prog in ginstall scoinst install; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
+ if test $ac_prog = install &&
+ grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+ # AIX install. It has an incompatible calling convention.
+ :
+ elif test $ac_prog = install &&
+ grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+ # program-specific install script used by HP pwplus--don't use.
+ :
+ else
+ rm -rf conftest.one conftest.two conftest.dir
+ echo one > conftest.one
+ echo two > conftest.two
+ mkdir conftest.dir
+ if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" &&
+ test -s conftest.one && test -s conftest.two &&
+ test -s conftest.dir/conftest.one &&
+ test -s conftest.dir/conftest.two
+ then
+ ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+ break 3
+ fi
+ fi
+ fi
+ done
+ done
+ ;;
+esac
+
+ done
+IFS=$as_save_IFS
+
+rm -rf conftest.one conftest.two conftest.dir
+
+fi
+ if test "${ac_cv_path_install+set}" = set; then
+ INSTALL=$ac_cv_path_install
+ else
+ # As a last resort, use the slow shell script. Don't cache a
+ # value for INSTALL within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the value is a relative name.
+ INSTALL=$ac_install_sh
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5
+$as_echo "$INSTALL" >&6; }
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+
+have_yacc_lex=no
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5
+$as_echo_n "checking whether ln -s works... " >&6; }
+LN_S=$as_ln_s
+if test "$LN_S" = "ln -s"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5
+$as_echo "no, using $LN_S" >&6; }
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5
+$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; }
+set x ${MAKE-make}
+ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'`
+if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat >conftest.make <<\_ACEOF
+SHELL = /bin/sh
+all:
+ @echo '@@@%%%=$(MAKE)=@@@%%%'
+_ACEOF
+# GNU make sometimes prints "make[1]: Entering ...", which would confuse us.
+case `${MAKE-make} -f conftest.make 2>/dev/null` in
+ *@@@%%%=?*=@@@%%%*)
+ eval ac_cv_prog_make_${ac_make}_set=yes;;
+ *)
+ eval ac_cv_prog_make_${ac_make}_set=no;;
+esac
+rm -f conftest.make
+fi
+if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ SET_MAKE=
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
+$as_echo_n "checking for grep that handles long lines and -e... " >&6; }
+if ${ac_cv_path_GREP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -z "$GREP"; then
+ ac_path_GREP_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in grep ggrep; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
+ as_fn_executable_p "$ac_path_GREP" || continue
+# Check for GNU ac_path_GREP and select it if it is found.
+ # Check for GNU $ac_path_GREP
+case `"$ac_path_GREP" --version 2>&1` in
+*GNU*)
+ ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo 'GREP' >> "conftest.nl"
+ "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
+ if test $ac_count -gt ${ac_path_GREP_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_GREP="$ac_path_GREP"
+ ac_path_GREP_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_GREP_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_GREP"; then
+ as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+ fi
+else
+ ac_cv_path_GREP=$GREP
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5
+$as_echo "$ac_cv_path_GREP" >&6; }
+ GREP="$ac_cv_path_GREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
+$as_echo_n "checking for egrep... " >&6; }
+if ${ac_cv_path_EGREP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
+ then ac_cv_path_EGREP="$GREP -E"
+ else
+ if test -z "$EGREP"; then
+ ac_path_EGREP_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in egrep; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
+ as_fn_executable_p "$ac_path_EGREP" || continue
+# Check for GNU ac_path_EGREP and select it if it is found.
+ # Check for GNU $ac_path_EGREP
+case `"$ac_path_EGREP" --version 2>&1` in
+*GNU*)
+ ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo 'EGREP' >> "conftest.nl"
+ "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
+ if test $ac_count -gt ${ac_path_EGREP_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_EGREP="$ac_path_EGREP"
+ ac_path_EGREP_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_EGREP_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_EGREP"; then
+ as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+ fi
+else
+ ac_cv_path_EGREP=$EGREP
+fi
+
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5
+$as_echo "$ac_cv_path_EGREP" >&6; }
+ EGREP="$ac_cv_path_EGREP"
+
+
+
+
+
+
+ case "${M4-unset}" in
+ unset) for ac_prog in m4 gm4
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_M4+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$M4"; then
+ ac_cv_prog_M4="$M4" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_M4="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+M4=$ac_cv_prog_M4
+if test -n "$M4"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $M4" >&5
+$as_echo "$M4" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$M4" && break
+done
+test -n "$M4" || M4="m4"
+ ;;
+ *) for ac_prog in $M4 m4 gm4
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_M4+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$M4"; then
+ ac_cv_prog_M4="$M4" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_M4="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+M4=$ac_cv_prog_M4
+if test -n "$M4"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $M4" >&5
+$as_echo "$M4" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$M4" && break
+done
+test -n "$M4" || M4="m4"
+ ;;
+ esac
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking m4 flags" >&5
+$as_echo_n "checking m4 flags... " >&6; }
+ case "${M4FLAGS-unset}" in
+ unset) `${M4} /dev/null > conftest.err 2>&1`
+ ac_cv_m4_stdout=`cat conftest.err`
+ if test "x$ac_cv_m4_stdout" != x; then
+ M4FLAGS=-B10000
+ fi
+ ${RM} -f conftest.err
+ ;;
+ esac
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $M4FLAGS" >&5
+$as_echo "$M4FLAGS" >&6; }
+
+
+
+ case "${AR-unset}" in
+ unset) for ac_prog in ar
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_AR+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$AR"; then
+ ac_cv_prog_AR="$AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_AR="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+AR=$ac_cv_prog_AR
+if test -n "$AR"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5
+$as_echo "$AR" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$AR" && break
+done
+test -n "$AR" || AR="ar"
+ ;;
+ *) for ac_prog in $AR ar
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_AR+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$AR"; then
+ ac_cv_prog_AR="$AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_AR="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+AR=$ac_cv_prog_AR
+if test -n "$AR"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5
+$as_echo "$AR" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$AR" && break
+done
+test -n "$AR" || AR="ar"
+ ;;
+ esac
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking ar flags" >&5
+$as_echo_n "checking ar flags... " >&6; }
+ case "${ARFLAGS-unset}" in
+ unset) ARFLAGS=cru ;;
+ esac
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ARFLAGS" >&5
+$as_echo "$ARFLAGS" >&6; }
+
+
+
+ case "${NM-unset}" in
+ unset) for ac_prog in nm
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_NM+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$NM"; then
+ ac_cv_prog_NM="$NM" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_NM="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+NM=$ac_cv_prog_NM
+if test -n "$NM"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NM" >&5
+$as_echo "$NM" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$NM" && break
+done
+test -n "$NM" || NM="nm"
+ ;;
+ *) for ac_prog in $NM nm
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_NM+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$NM"; then
+ ac_cv_prog_NM="$NM" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_NM="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+NM=$ac_cv_prog_NM
+if test -n "$NM"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NM" >&5
+$as_echo "$NM" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$NM" && break
+done
+test -n "$NM" || NM="nm"
+ ;;
+ esac
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking nm flags" >&5
+$as_echo_n "checking nm flags... " >&6; }
+ case "${NMFLAGS-unset}" in
+ unset) NMFLAGS= ;;
+ esac
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMFLAGS" >&5
+$as_echo "$NMFLAGS" >&6; }
+
+
+# We could use the PAC check for ranlib (it also makes sure that ranlib works,
+# which is not always true, particularly when GNU tools are installed on
+# a system that doesn't have (or need) ranlib
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ranlib; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_RANLIB+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$RANLIB"; then
+ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+RANLIB=$ac_cv_prog_RANLIB
+if test -n "$RANLIB"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5
+$as_echo "$RANLIB" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_RANLIB"; then
+ ac_ct_RANLIB=$RANLIB
+ # Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_RANLIB+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_RANLIB"; then
+ ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_RANLIB="ranlib"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
+if test -n "$ac_ct_RANLIB"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5
+$as_echo "$ac_ct_RANLIB" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_RANLIB" = x; then
+ RANLIB=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ RANLIB=$ac_ct_RANLIB
+ fi
+else
+ RANLIB="$ac_cv_prog_RANLIB"
+fi
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5
+$as_echo_n "checking how to run the C preprocessor... " >&6; }
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+ CPP=
+fi
+if test -z "$CPP"; then
+ if ${ac_cv_prog_CPP+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ # Double quotes because CPP needs to be expanded
+ for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+ do
+ ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+ # Broken: success on invalid input.
+continue
+else
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+ break
+fi
+
+ done
+ ac_cv_prog_CPP=$CPP
+
+fi
+ CPP=$ac_cv_prog_CPP
+else
+ ac_cv_prog_CPP=$CPP
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5
+$as_echo "$CPP" >&6; }
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+ # Broken: success on invalid input.
+continue
+else
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+
+else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
+$as_echo_n "checking for ANSI C header files... " >&6; }
+if ${ac_cv_header_stdc+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+#ifdef FC_DUMMY_MAIN
+#ifndef FC_DUMMY_MAIN_EQ_F77
+# ifdef __cplusplus
+ extern "C"
+# endif
+ int FC_DUMMY_MAIN() { return 1; }
+#endif
+#endif
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_header_stdc=yes
+else
+ ac_cv_header_stdc=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "memchr" >/dev/null 2>&1; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "free" >/dev/null 2>&1; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+ if test "$cross_compiling" = yes; then :
+ :
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ctype.h>
+#include <stdlib.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+ (('a' <= (c) && (c) <= 'i') \
+ || ('j' <= (c) && (c) <= 'r') \
+ || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+ int i;
+ for (i = 0; i < 256; i++)
+ if (XOR (islower (i), ISLOWER (i))
+ || toupper (i) != TOUPPER (i))
+ return 2;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5
+$as_echo "$ac_cv_header_stdc" >&6; }
+if test $ac_cv_header_stdc = yes; then
+
+$as_echo "#define STDC_HEADERS 1" >>confdefs.h
+
+fi
+
+# On IRIX 5.3, sys/types and inttypes.h are conflicting.
+for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
+ inttypes.h stdint.h unistd.h
+do :
+ as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
+"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdbool.h that conforms to C99" >&5
+$as_echo_n "checking for stdbool.h that conforms to C99... " >&6; }
+if ${ac_cv_header_stdbool_h+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+ #include <stdbool.h>
+ #ifndef bool
+ "error: bool is not defined"
+ #endif
+ #ifndef false
+ "error: false is not defined"
+ #endif
+ #if false
+ "error: false is not 0"
+ #endif
+ #ifndef true
+ "error: true is not defined"
+ #endif
+ #if true != 1
+ "error: true is not 1"
+ #endif
+ #ifndef __bool_true_false_are_defined
+ "error: __bool_true_false_are_defined is not defined"
+ #endif
+
+ struct s { _Bool s: 1; _Bool t; } s;
+
+ char a[true == 1 ? 1 : -1];
+ char b[false == 0 ? 1 : -1];
+ char c[__bool_true_false_are_defined == 1 ? 1 : -1];
+ char d[(bool) 0.5 == true ? 1 : -1];
+ /* See body of main program for 'e'. */
+ char f[(_Bool) 0.0 == false ? 1 : -1];
+ char g[true];
+ char h[sizeof (_Bool)];
+ char i[sizeof s.t];
+ enum { j = false, k = true, l = false * true, m = true * 256 };
+ /* The following fails for
+ HP aC++/ANSI C B3910B A.05.55 [Dec 04 2003]. */
+ _Bool n[m];
+ char o[sizeof n == m * sizeof n[0] ? 1 : -1];
+ char p[-1 - (_Bool) 0 < 0 && -1 - (bool) 0 < 0 ? 1 : -1];
+ /* Catch a bug in an HP-UX C compiler. See
+ http://gcc.gnu.org/ml/gcc-patches/2003-12/msg02303.html
+ http://lists.gnu.org/archive/html/bug-coreutils/2005-11/msg00161.html
+ */
+ _Bool q = true;
+ _Bool *pq = &q;
+
+#ifdef FC_DUMMY_MAIN
+#ifndef FC_DUMMY_MAIN_EQ_F77
+# ifdef __cplusplus
+ extern "C"
+# endif
+ int FC_DUMMY_MAIN() { return 1; }
+#endif
+#endif
+int
+main ()
+{
+
+ bool e = &s;
+ *pq |= q;
+ *pq |= ! q;
+ /* Refer to every declared value, to avoid compiler optimizations. */
+ return (!a + !b + !c + !d + !e + !f + !g + !h + !i + !!j + !k + !!l
+ + !m + !n + !o + !p + !q + !pq);
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_header_stdbool_h=yes
+else
+ ac_cv_header_stdbool_h=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdbool_h" >&5
+$as_echo "$ac_cv_header_stdbool_h" >&6; }
+ ac_fn_c_check_type "$LINENO" "_Bool" "ac_cv_type__Bool" "$ac_includes_default"
+if test "x$ac_cv_type__Bool" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE__BOOL 1
+_ACEOF
+
+
+fi
+
+
+if test $ac_cv_header_stdbool_h = yes; then
+
+$as_echo "#define HAVE_STDBOOL_H 1" >>confdefs.h
+
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inline" >&5
+$as_echo_n "checking for inline... " >&6; }
+if ${ac_cv_c_inline+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_c_inline=no
+for ac_kw in inline __inline__ __inline; do
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifndef __cplusplus
+typedef int foo_t;
+static $ac_kw foo_t static_foo () {return 0; }
+$ac_kw foo_t foo () {return 0; }
+#endif
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_c_inline=$ac_kw
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ test "$ac_cv_c_inline" != no && break
+done
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_inline" >&5
+$as_echo "$ac_cv_c_inline" >&6; }
+
+case $ac_cv_c_inline in
+ inline | yes) ;;
+ *)
+ case $ac_cv_c_inline in
+ no) ac_val=;;
+ *) ac_val=$ac_cv_c_inline;;
+ esac
+ cat >>confdefs.h <<_ACEOF
+#ifndef __cplusplus
+#define inline $ac_val
+#endif
+_ACEOF
+ ;;
+esac
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for IEEE floating point format" >&5
+$as_echo_n "checking for IEEE floating point format... " >&6; }
+if test "$cross_compiling" = yes; then :
+ :
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifndef NO_FLOAT_H
+#include <float.h>
+#endif
+
+#define EXIT_NOTIEEE 1
+#define EXIT_MAYBEIEEE 0
+
+int
+main()
+{
+#if defined(FLT_RADIX) && FLT_RADIX != 2
+ return EXIT_NOTIEEE;
+#elif defined(DBL_MAX_EXP) && DBL_MAX_EXP != 1024
+ return EXIT_NOTIEEE;
+#elif defined(DBL_MANT_DIG) && DBL_MANT_DIG != 53
+ return EXIT_NOTIEEE;
+#elif defined(FLT_MAX_EXP) && !(FLT_MAX_EXP == 1024 || FLT_MAX_EXP == 128)
+ return EXIT_NOTIEEE;
+#elif defined(FLT_MANT_DIG) && !(FLT_MANT_DIG == 53 || FLT_MANT_DIG == 24)
+ return EXIT_NOTIEEE;
+#else
+ /* (assuming eight bit char) */
+ if(sizeof(double) != 8)
+ return EXIT_NOTIEEE;
+ if(!(sizeof(float) == 4 || sizeof(float) == 8))
+ return EXIT_NOTIEEE;
+
+ return EXIT_MAYBEIEEE;
+#endif
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ ac_cv_c_ieeefloat=yes
+else
+ ac_cv_c_ieeefloat=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_ieeefloat" >&5
+$as_echo "$ac_cv_c_ieeefloat" >&6; }
+if test x$ac_cv_c_ieeefloat = xno; then
+ $as_echo "#define NO_IEEE_FLOAT 1" >>confdefs.h
+
+fi
+
+
+
+for ac_func in strerror access unlink
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+# Check whether --enable-debug was given.
+if test "${enable_debug+set}" = set; then :
+ enableval=$enable_debug; debug=${enableval}
+else
+ debug=no
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking PnetCDF debug mode" >&5
+$as_echo_n "checking PnetCDF debug mode... " >&6; }
+if test "x${debug}" = xyes; then
+ $as_echo "#define PNC_DEBUG 1" >>confdefs.h
+
+
+ for ac_header in search.h
+do :
+ ac_fn_c_check_header_mongrel "$LINENO" "search.h" "ac_cv_header_search_h" "$ac_includes_default"
+if test "x$ac_cv_header_search_h" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_SEARCH_H 1
+_ACEOF
+
+fi
+
+done
+
+ for ac_func in tsearch tdelete
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+ if (test "x${ac_cv_func_tsearch}" = xyes) &&
+ (test "x${ac_cv_func_tdelete}" = xyes) ; then
+ $as_echo "#define PNC_MALLOC_TRACE 1" >>confdefs.h
+
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $debug" >&5
+$as_echo "$debug" >&6; }
+PNC_DEBUG=${debug}
+
+
+ac_fn_c_check_type "$LINENO" "MPI_Offset" "ac_cv_type_MPI_Offset" "#include <mpi.h>
+"
+if test "x$ac_cv_type_MPI_Offset" = xyes; then :
+
+fi
+
+if test "x${ac_cv_type_MPI_Offset}" = xyes; then
+ # The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of MPI_Offset" >&5
+$as_echo_n "checking size of MPI_Offset... " >&6; }
+if ${ac_cv_sizeof_MPI_Offset+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (MPI_Offset))" "ac_cv_sizeof_MPI_Offset" "#include <mpi.h>
+"; then :
+
+else
+ if test "$ac_cv_type_MPI_Offset" = yes; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (MPI_Offset)
+See \`config.log' for more details" "$LINENO" 5; }
+ else
+ ac_cv_sizeof_MPI_Offset=0
+ fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_MPI_Offset" >&5
+$as_echo "$ac_cv_sizeof_MPI_Offset" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_MPI_OFFSET $ac_cv_sizeof_MPI_Offset
+_ACEOF
+
+
+else
+ as_fn_error $? "Unable to find type MPI_Offset in mpi.h" "$LINENO" 5
+fi
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of MPI_Aint" >&5
+$as_echo_n "checking size of MPI_Aint... " >&6; }
+if ${ac_cv_sizeof_MPI_Aint+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (MPI_Aint))" "ac_cv_sizeof_MPI_Aint" "#include <mpi.h>
+"; then :
+
+else
+ if test "$ac_cv_type_MPI_Aint" = yes; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (MPI_Aint)
+See \`config.log' for more details" "$LINENO" 5; }
+ else
+ ac_cv_sizeof_MPI_Aint=0
+ fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_MPI_Aint" >&5
+$as_echo "$ac_cv_sizeof_MPI_Aint" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_MPI_AINT $ac_cv_sizeof_MPI_Aint
+_ACEOF
+
+
+
+if test "$ac_cv_sizeof_MPI_Offset" -lt "8"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \"Unable to support CDF-5 format\"" >&5
+$as_echo "$as_me: WARNING: \"Unable to support CDF-5 format\"" >&2;};
+ enable_cdf5=no
+else
+
+$as_echo "#define ENABLE_CDF5 /**/" >>confdefs.h
+
+ enable_cdf5=yes
+fi
+
+SIZEOF_MPI_AINT_IS_4=no
+if test "x$ac_cv_sizeof_MPI_Aint" = x4; then
+ SIZEOF_MPI_AINT_IS_4=yes
+fi
+
+
+if test "$ac_cv_sizeof_MPI_Offset" -ne "$ac_cv_sizeof_MPI_Aint"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: MPI_Offset and MPI_Aint have different sizes: non-blocking APIs now behave like blocking ones" >&5
+$as_echo "$as_me: WARNING: MPI_Offset and MPI_Aint have different sizes: non-blocking APIs now behave like blocking ones" >&2;}
+ enable_nonblocking=no
+else
+
+$as_echo "#define ENABLE_NONBLOCKING /**/" >>confdefs.h
+
+ enable_nonblocking=yes
+fi
+
+# check for MPI-2 only functions
+for ac_func in MPI_Info_dup MPI_Info_free MPI_Get_address
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in MPI_Type_create_subarray MPI_Type_create_hvector MPI_Type_create_hindexed MPI_Type_create_struct MPI_Type_create_resized MPI_Type_get_extent
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if MPI constant MPI_COMBINER_DUP is defined " >&5
+$as_echo_n "checking if MPI constant MPI_COMBINER_DUP is defined ... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+ #include <mpi.h>
+ int dummy = MPI_COMBINER_DUP;
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_MPI_COMBINER_DUP 1" >>confdefs.h
+
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if MPI constant MPI_COMBINER_HVECTOR_INTEGER is defined " >&5
+$as_echo_n "checking if MPI constant MPI_COMBINER_HVECTOR_INTEGER is defined ... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+ #include <mpi.h>
+ int dummy = MPI_COMBINER_HVECTOR_INTEGER;
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_MPI_COMBINER_HVECTOR_INTEGER 1" >>confdefs.h
+
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if MPI constant MPI_COMBINER_HINDEXED_INTEGER is defined " >&5
+$as_echo_n "checking if MPI constant MPI_COMBINER_HINDEXED_INTEGER is defined ... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+ #include <mpi.h>
+ int dummy = MPI_COMBINER_HINDEXED_INTEGER;
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_MPI_COMBINER_HINDEXED_INTEGER 1" >>confdefs.h
+
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if MPI constant MPI_COMBINER_SUBARRAY is defined " >&5
+$as_echo_n "checking if MPI constant MPI_COMBINER_SUBARRAY is defined ... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+ #include <mpi.h>
+ int dummy = MPI_COMBINER_SUBARRAY;
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_MPI_COMBINER_SUBARRAY 1" >>confdefs.h
+
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if MPI constant MPI_COMBINER_DARRAY is defined " >&5
+$as_echo_n "checking if MPI constant MPI_COMBINER_DARRAY is defined ... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+ #include <mpi.h>
+ int dummy = MPI_COMBINER_DARRAY;
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_MPI_COMBINER_DARRAY 1" >>confdefs.h
+
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if MPI constant MPI_COMBINER_RESIZED is defined " >&5
+$as_echo_n "checking if MPI constant MPI_COMBINER_RESIZED is defined ... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+ #include <mpi.h>
+ int dummy = MPI_COMBINER_RESIZED;
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_MPI_COMBINER_RESIZED 1" >>confdefs.h
+
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if MPI constant MPI_COMBINER_STRUCT_INTEGER is defined " >&5
+$as_echo_n "checking if MPI constant MPI_COMBINER_STRUCT_INTEGER is defined ... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+ #include <mpi.h>
+ int dummy = MPI_COMBINER_STRUCT_INTEGER;
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_MPI_COMBINER_STRUCT_INTEGER 1" >>confdefs.h
+
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if MPI constant MPI_COMBINER_INDEXED_BLOCK is defined " >&5
+$as_echo_n "checking if MPI constant MPI_COMBINER_INDEXED_BLOCK is defined ... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+ #include <mpi.h>
+ int dummy = MPI_COMBINER_INDEXED_BLOCK;
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_MPI_COMBINER_INDEXED_BLOCK 1" >>confdefs.h
+
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if MPI constant MPI_COMBINER_F90_REAL is defined " >&5
+$as_echo_n "checking if MPI constant MPI_COMBINER_F90_REAL is defined ... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+ #include <mpi.h>
+ int dummy = MPI_COMBINER_F90_REAL;
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_MPI_COMBINER_F90_REAL 1" >>confdefs.h
+
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if MPI constant MPI_COMBINER_F90_INTEGER is defined " >&5
+$as_echo_n "checking if MPI constant MPI_COMBINER_F90_INTEGER is defined ... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+ #include <mpi.h>
+ int dummy = MPI_COMBINER_F90_INTEGER;
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_MPI_COMBINER_F90_INTEGER 1" >>confdefs.h
+
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if MPI constant MPI_COMBINER_F90_COMPLEX is defined " >&5
+$as_echo_n "checking if MPI constant MPI_COMBINER_F90_COMPLEX is defined ... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+ #include <mpi.h>
+ int dummy = MPI_COMBINER_F90_COMPLEX;
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_MPI_COMBINER_F90_COMPLEX 1" >>confdefs.h
+
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if MPI constant MPI_ERR_FILE_EXISTS is defined " >&5
+$as_echo_n "checking if MPI constant MPI_ERR_FILE_EXISTS is defined ... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+ #include <mpi.h>
+ int dummy = MPI_ERR_FILE_EXISTS;
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_MPI_ERR_FILE_EXISTS 1" >>confdefs.h
+
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if MPI constant MPI_ERR_NO_SUCH_FILE is defined " >&5
+$as_echo_n "checking if MPI constant MPI_ERR_NO_SUCH_FILE is defined ... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+ #include <mpi.h>
+ int dummy = MPI_ERR_NO_SUCH_FILE;
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_MPI_ERR_NO_SUCH_FILE 1" >>confdefs.h
+
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if MPI constant MPI_ERR_AMODE is defined " >&5
+$as_echo_n "checking if MPI constant MPI_ERR_AMODE is defined ... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+ #include <mpi.h>
+ int dummy = MPI_ERR_AMODE;
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_MPI_ERR_AMODE 1" >>confdefs.h
+
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if MPI constant MPI_ERR_NOT_SAME is defined " >&5
+$as_echo_n "checking if MPI constant MPI_ERR_NOT_SAME is defined ... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+ #include <mpi.h>
+ int dummy = MPI_ERR_NOT_SAME;
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_MPI_ERR_NOT_SAME 1" >>confdefs.h
+
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if MPI constant MPI_ERR_BAD_FILE is defined " >&5
+$as_echo_n "checking if MPI constant MPI_ERR_BAD_FILE is defined ... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+ #include <mpi.h>
+ int dummy = MPI_ERR_BAD_FILE;
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_MPI_ERR_BAD_FILE 1" >>confdefs.h
+
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if MPI constant MPI_ERR_READ_ONLY is defined " >&5
+$as_echo_n "checking if MPI constant MPI_ERR_READ_ONLY is defined ... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+ #include <mpi.h>
+ int dummy = MPI_ERR_READ_ONLY;
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_MPI_ERR_READ_ONLY 1" >>confdefs.h
+
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if MPI constant MPI_ERR_ACCESS is defined " >&5
+$as_echo_n "checking if MPI constant MPI_ERR_ACCESS is defined ... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+ #include <mpi.h>
+ int dummy = MPI_ERR_ACCESS;
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_MPI_ERR_ACCESS 1" >>confdefs.h
+
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if MPI constant MPI_ERR_NO_SPACE is defined " >&5
+$as_echo_n "checking if MPI constant MPI_ERR_NO_SPACE is defined ... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+ #include <mpi.h>
+ int dummy = MPI_ERR_NO_SPACE;
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_MPI_ERR_NO_SPACE 1" >>confdefs.h
+
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if MPI constant MPI_ERR_QUOTA is defined " >&5
+$as_echo_n "checking if MPI constant MPI_ERR_QUOTA is defined ... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+ #include <mpi.h>
+ int dummy = MPI_ERR_QUOTA;
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_MPI_ERR_QUOTA 1" >>confdefs.h
+
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if MPI datatype MPI_CHAR is defined " >&5
+$as_echo_n "checking if MPI datatype MPI_CHAR is defined ... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+ #include <mpi.h>
+ MPI_Datatype dummy = MPI_CHAR;
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_MPI_CHAR 1" >>confdefs.h
+
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if MPI datatype MPI_BYTE is defined " >&5
+$as_echo_n "checking if MPI datatype MPI_BYTE is defined ... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+ #include <mpi.h>
+ MPI_Datatype dummy = MPI_BYTE;
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_MPI_BYTE 1" >>confdefs.h
+
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if MPI datatype MPI_SIGNED_CHAR is defined " >&5
+$as_echo_n "checking if MPI datatype MPI_SIGNED_CHAR is defined ... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+ #include <mpi.h>
+ MPI_Datatype dummy = MPI_SIGNED_CHAR;
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_MPI_SIGNED_CHAR 1" >>confdefs.h
+
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if MPI datatype MPI_UNSIGNED_CHAR is defined " >&5
+$as_echo_n "checking if MPI datatype MPI_UNSIGNED_CHAR is defined ... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+ #include <mpi.h>
+ MPI_Datatype dummy = MPI_UNSIGNED_CHAR;
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_MPI_UNSIGNED_CHAR 1" >>confdefs.h
+
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if MPI datatype MPI_SHORT is defined " >&5
+$as_echo_n "checking if MPI datatype MPI_SHORT is defined ... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+ #include <mpi.h>
+ MPI_Datatype dummy = MPI_SHORT;
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_MPI_SHORT 1" >>confdefs.h
+
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if MPI datatype MPI_UNSIGNED_SHORT is defined " >&5
+$as_echo_n "checking if MPI datatype MPI_UNSIGNED_SHORT is defined ... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+ #include <mpi.h>
+ MPI_Datatype dummy = MPI_UNSIGNED_SHORT;
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_MPI_UNSIGNED_SHORT 1" >>confdefs.h
+
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if MPI datatype MPI_INT is defined " >&5
+$as_echo_n "checking if MPI datatype MPI_INT is defined ... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+ #include <mpi.h>
+ MPI_Datatype dummy = MPI_INT;
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_MPI_INT 1" >>confdefs.h
+
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if MPI datatype MPI_UNSIGNED is defined " >&5
+$as_echo_n "checking if MPI datatype MPI_UNSIGNED is defined ... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+ #include <mpi.h>
+ MPI_Datatype dummy = MPI_UNSIGNED;
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_MPI_UNSIGNED 1" >>confdefs.h
+
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if MPI datatype MPI_LONG is defined " >&5
+$as_echo_n "checking if MPI datatype MPI_LONG is defined ... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+ #include <mpi.h>
+ MPI_Datatype dummy = MPI_LONG;
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_MPI_LONG 1" >>confdefs.h
+
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if MPI datatype MPI_FLOAT is defined " >&5
+$as_echo_n "checking if MPI datatype MPI_FLOAT is defined ... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+ #include <mpi.h>
+ MPI_Datatype dummy = MPI_FLOAT;
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_MPI_FLOAT 1" >>confdefs.h
+
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if MPI datatype MPI_DOUBLE is defined " >&5
+$as_echo_n "checking if MPI datatype MPI_DOUBLE is defined ... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+ #include <mpi.h>
+ MPI_Datatype dummy = MPI_DOUBLE;
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_MPI_DOUBLE 1" >>confdefs.h
+
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if MPI datatype MPI_LONG_LONG_INT is defined " >&5
+$as_echo_n "checking if MPI datatype MPI_LONG_LONG_INT is defined ... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+ #include <mpi.h>
+ MPI_Datatype dummy = MPI_LONG_LONG_INT;
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_MPI_LONG_LONG_INT 1" >>confdefs.h
+
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if MPI datatype MPI_UNSIGNED_LONG_LONG is defined " >&5
+$as_echo_n "checking if MPI datatype MPI_UNSIGNED_LONG_LONG is defined ... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+ #include <mpi.h>
+ MPI_Datatype dummy = MPI_UNSIGNED_LONG_LONG;
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_MPI_UNSIGNED_LONG_LONG 1" >>confdefs.h
+
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if MPI datatype MPI_UB is defined " >&5
+$as_echo_n "checking if MPI datatype MPI_UB is defined ... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+ #include <mpi.h>
+ MPI_Datatype dummy = MPI_UB;
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_MPI_UB 1" >>confdefs.h
+
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if MPI datatype MPI_LB is defined " >&5
+$as_echo_n "checking if MPI datatype MPI_LB is defined ... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+ #include <mpi.h>
+ MPI_Datatype dummy = MPI_LB;
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_MPI_LB 1" >>confdefs.h
+
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if MPI datatype MPI_OFFSET is defined " >&5
+$as_echo_n "checking if MPI datatype MPI_OFFSET is defined ... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+ #include <mpi.h>
+ MPI_Datatype dummy = MPI_OFFSET;
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_MPI_OFFSET_DATATYPE 1" >>confdefs.h
+
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+
+if test "x${enable_fortran}" = xyes ; then
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if MPI datatype MPI_CHARACTER is defined " >&5
+$as_echo_n "checking if MPI datatype MPI_CHARACTER is defined ... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+ #include <mpi.h>
+ MPI_Datatype dummy = MPI_CHARACTER;
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_MPI_CHARACTER 1" >>confdefs.h
+
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if MPI datatype MPI_REAL is defined " >&5
+$as_echo_n "checking if MPI datatype MPI_REAL is defined ... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+ #include <mpi.h>
+ MPI_Datatype dummy = MPI_REAL;
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_MPI_REAL 1" >>confdefs.h
+
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if MPI datatype MPI_INTEGER is defined " >&5
+$as_echo_n "checking if MPI datatype MPI_INTEGER is defined ... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+ #include <mpi.h>
+ MPI_Datatype dummy = MPI_INTEGER;
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_MPI_INTEGER 1" >>confdefs.h
+
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if MPI datatype MPI_DOUBLE_PRECISION is defined " >&5
+$as_echo_n "checking if MPI datatype MPI_DOUBLE_PRECISION is defined ... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+ #include <mpi.h>
+ MPI_Datatype dummy = MPI_DOUBLE_PRECISION;
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_MPI_DOUBLE_PRECISION 1" >>confdefs.h
+
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if MPI datatype MPI_INTEGER1 is defined " >&5
+$as_echo_n "checking if MPI datatype MPI_INTEGER1 is defined ... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+ #include <mpi.h>
+ MPI_Datatype dummy = MPI_INTEGER1;
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_MPI_INTEGER1 1" >>confdefs.h
+
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if MPI datatype MPI_INTEGER2 is defined " >&5
+$as_echo_n "checking if MPI datatype MPI_INTEGER2 is defined ... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+ #include <mpi.h>
+ MPI_Datatype dummy = MPI_INTEGER2;
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_MPI_INTEGER2 1" >>confdefs.h
+
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if MPI datatype MPI_INTEGER4 is defined " >&5
+$as_echo_n "checking if MPI datatype MPI_INTEGER4 is defined ... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+ #include <mpi.h>
+ MPI_Datatype dummy = MPI_INTEGER4;
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_MPI_INTEGER4 1" >>confdefs.h
+
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if MPI datatype MPI_INTEGER8 is defined " >&5
+$as_echo_n "checking if MPI datatype MPI_INTEGER8 is defined ... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+ #include <mpi.h>
+ MPI_Datatype dummy = MPI_INTEGER8;
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_MPI_INTEGER8 1" >>confdefs.h
+
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if MPI datatype MPI_INTEGER16 is defined " >&5
+$as_echo_n "checking if MPI datatype MPI_INTEGER16 is defined ... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+ #include <mpi.h>
+ MPI_Datatype dummy = MPI_INTEGER16;
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_MPI_INTEGER16 1" >>confdefs.h
+
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if MPI datatype MPI_REAL4 is defined " >&5
+$as_echo_n "checking if MPI datatype MPI_REAL4 is defined ... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+ #include <mpi.h>
+ MPI_Datatype dummy = MPI_REAL4;
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_MPI_REAL4 1" >>confdefs.h
+
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if MPI datatype MPI_REAL8 is defined " >&5
+$as_echo_n "checking if MPI datatype MPI_REAL8 is defined ... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+ #include <mpi.h>
+ MPI_Datatype dummy = MPI_REAL8;
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_MPI_REAL8 1" >>confdefs.h
+
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if MPI datatype MPI_REAL16 is defined " >&5
+$as_echo_n "checking if MPI datatype MPI_REAL16 is defined ... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+ #include <mpi.h>
+ MPI_Datatype dummy = MPI_REAL16;
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_MPI_REAL16 1" >>confdefs.h
+
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if MPI datatype MPI_COMPLEX8 is defined " >&5
+$as_echo_n "checking if MPI datatype MPI_COMPLEX8 is defined ... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+ #include <mpi.h>
+ MPI_Datatype dummy = MPI_COMPLEX8;
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_MPI_COMPLEX8 1" >>confdefs.h
+
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if MPI datatype MPI_COMPLEX16 is defined " >&5
+$as_echo_n "checking if MPI datatype MPI_COMPLEX16 is defined ... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+ #include <mpi.h>
+ MPI_Datatype dummy = MPI_COMPLEX16;
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_MPI_COMPLEX16 1" >>confdefs.h
+
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if MPI datatype MPI_COMPLEX32 is defined " >&5
+$as_echo_n "checking if MPI datatype MPI_COMPLEX32 is defined ... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+ #include <mpi.h>
+ MPI_Datatype dummy = MPI_COMPLEX32;
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_MPI_COMPLEX32 1" >>confdefs.h
+
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+
+# Check whether --enable-in-place-swap was given.
+if test "${enable_in_place_swap+set}" = set; then :
+ enableval=$enable_in_place_swap; in_place_swap=${enableval}
+else
+ in_place_swap=yes
+
+fi
+
+if test "x${in_place_swap}" = xno ; then
+ $as_echo "#define DISABLE_IN_PLACE_SWAP 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether char is unsigned" >&5
+$as_echo_n "checking whether char is unsigned... " >&6; }
+if ${ac_cv_c_char_unsigned+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$ac_includes_default
+#ifdef FC_DUMMY_MAIN
+#ifndef FC_DUMMY_MAIN_EQ_F77
+# ifdef __cplusplus
+ extern "C"
+# endif
+ int FC_DUMMY_MAIN() { return 1; }
+#endif
+#endif
+int
+main ()
+{
+static int test_array [1 - 2 * !(((char) -1) < 0)];
+test_array [0] = 0;
+return test_array [0];
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_c_char_unsigned=no
+else
+ ac_cv_c_char_unsigned=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_char_unsigned" >&5
+$as_echo "$ac_cv_c_char_unsigned" >&6; }
+if test $ac_cv_c_char_unsigned = yes && test "$GCC" != yes; then
+ $as_echo "#define __CHAR_UNSIGNED__ 1" >>confdefs.h
+
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5
+$as_echo_n "checking whether byte ordering is bigendian... " >&6; }
+if ${ac_cv_c_bigendian+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_c_bigendian=unknown
+ # See if we're dealing with a universal compiler.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifndef __APPLE_CC__
+ not a universal capable compiler
+ #endif
+ typedef int dummy;
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+ # Check for potential -arch flags. It is not universal unless
+ # there are at least two -arch flags with different values.
+ ac_arch=
+ ac_prev=
+ for ac_word in $CC $CFLAGS $CPPFLAGS $LDFLAGS; do
+ if test -n "$ac_prev"; then
+ case $ac_word in
+ i?86 | x86_64 | ppc | ppc64)
+ if test -z "$ac_arch" || test "$ac_arch" = "$ac_word"; then
+ ac_arch=$ac_word
+ else
+ ac_cv_c_bigendian=universal
+ break
+ fi
+ ;;
+ esac
+ ac_prev=
+ elif test "x$ac_word" = "x-arch"; then
+ ac_prev=arch
+ fi
+ done
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ if test $ac_cv_c_bigendian = unknown; then
+ # See if sys/param.h defines the BYTE_ORDER macro.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h>
+ #include <sys/param.h>
+
+#ifdef FC_DUMMY_MAIN
+#ifndef FC_DUMMY_MAIN_EQ_F77
+# ifdef __cplusplus
+ extern "C"
+# endif
+ int FC_DUMMY_MAIN() { return 1; }
+#endif
+#endif
+int
+main ()
+{
+#if ! (defined BYTE_ORDER && defined BIG_ENDIAN \
+ && defined LITTLE_ENDIAN && BYTE_ORDER && BIG_ENDIAN \
+ && LITTLE_ENDIAN)
+ bogus endian macros
+ #endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ # It does; now see whether it defined to BIG_ENDIAN or not.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h>
+ #include <sys/param.h>
+
+#ifdef FC_DUMMY_MAIN
+#ifndef FC_DUMMY_MAIN_EQ_F77
+# ifdef __cplusplus
+ extern "C"
+# endif
+ int FC_DUMMY_MAIN() { return 1; }
+#endif
+#endif
+int
+main ()
+{
+#if BYTE_ORDER != BIG_ENDIAN
+ not big endian
+ #endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_c_bigendian=yes
+else
+ ac_cv_c_bigendian=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ fi
+ if test $ac_cv_c_bigendian = unknown; then
+ # See if <limits.h> defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris).
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <limits.h>
+
+#ifdef FC_DUMMY_MAIN
+#ifndef FC_DUMMY_MAIN_EQ_F77
+# ifdef __cplusplus
+ extern "C"
+# endif
+ int FC_DUMMY_MAIN() { return 1; }
+#endif
+#endif
+int
+main ()
+{
+#if ! (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN)
+ bogus endian macros
+ #endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ # It does; now see whether it defined to _BIG_ENDIAN or not.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <limits.h>
+
+#ifdef FC_DUMMY_MAIN
+#ifndef FC_DUMMY_MAIN_EQ_F77
+# ifdef __cplusplus
+ extern "C"
+# endif
+ int FC_DUMMY_MAIN() { return 1; }
+#endif
+#endif
+int
+main ()
+{
+#ifndef _BIG_ENDIAN
+ not big endian
+ #endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_c_bigendian=yes
+else
+ ac_cv_c_bigendian=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ fi
+ if test $ac_cv_c_bigendian = unknown; then
+ # Compile a test program.
+ if test "$cross_compiling" = yes; then :
+ # Try to guess by grepping values from an object file.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+short int ascii_mm[] =
+ { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 };
+ short int ascii_ii[] =
+ { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 };
+ int use_ascii (int i) {
+ return ascii_mm[i] + ascii_ii[i];
+ }
+ short int ebcdic_ii[] =
+ { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 };
+ short int ebcdic_mm[] =
+ { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 };
+ int use_ebcdic (int i) {
+ return ebcdic_mm[i] + ebcdic_ii[i];
+ }
+ extern int foo;
+
+#ifdef FC_DUMMY_MAIN
+#ifndef FC_DUMMY_MAIN_EQ_F77
+# ifdef __cplusplus
+ extern "C"
+# endif
+ int FC_DUMMY_MAIN() { return 1; }
+#endif
+#endif
+int
+main ()
+{
+return use_ascii (foo) == use_ebcdic (foo);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ if grep BIGenDianSyS conftest.$ac_objext >/dev/null; then
+ ac_cv_c_bigendian=yes
+ fi
+ if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then
+ if test "$ac_cv_c_bigendian" = unknown; then
+ ac_cv_c_bigendian=no
+ else
+ # finding both strings is unlikely to happen, but who knows?
+ ac_cv_c_bigendian=unknown
+ fi
+ fi
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$ac_includes_default
+#ifdef FC_DUMMY_MAIN
+#ifndef FC_DUMMY_MAIN_EQ_F77
+# ifdef __cplusplus
+ extern "C"
+# endif
+ int FC_DUMMY_MAIN() { return 1; }
+#endif
+#endif
+int
+main ()
+{
+
+ /* Are we little or big endian? From Harbison&Steele. */
+ union
+ {
+ long int l;
+ char c[sizeof (long int)];
+ } u;
+ u.l = 1;
+ return u.c[sizeof (long int) - 1] == 1;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ ac_cv_c_bigendian=no
+else
+ ac_cv_c_bigendian=yes
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_bigendian" >&5
+$as_echo "$ac_cv_c_bigendian" >&6; }
+ case $ac_cv_c_bigendian in #(
+ yes)
+ $as_echo "#define WORDS_BIGENDIAN 1" >>confdefs.h
+;; #(
+ no)
+ ;; #(
+ universal)
+
+$as_echo "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h
+
+ ;; #(
+ *)
+ as_fn_error $? "unknown endianness
+ presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;;
+ esac
+
+is_bigendian=no
+if test "x${ac_cv_c_bigendian}" = xyes ; then
+ is_bigendian=yes
+fi
+
+
+if test "x${ac_cv_c_bigendian}" = xyes || (test "x${in_place_swap}" = xno) ; then
+ INTENTV="IN"
+else
+ INTENTV="INOUT"
+fi
+
+
+ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default"
+if test "x$ac_cv_type_size_t" = xyes; then :
+
+else
+
+cat >>confdefs.h <<_ACEOF
+#define size_t unsigned int
+_ACEOF
+
+fi
+
+ac_fn_c_check_type "$LINENO" "off_t" "ac_cv_type_off_t" "$ac_includes_default"
+if test "x$ac_cv_type_off_t" = xyes; then :
+
+else
+
+cat >>confdefs.h <<_ACEOF
+#define off_t long int
+_ACEOF
+
+fi
+
+ac_fn_c_check_type "$LINENO" "ssize_t" "ac_cv_type_ssize_t" "$ac_includes_default"
+if test "x$ac_cv_type_ssize_t" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_SSIZE_T 1
+_ACEOF
+
+
+fi
+ac_fn_c_check_type "$LINENO" "ptrdiff_t" "ac_cv_type_ptrdiff_t" "$ac_includes_default"
+if test "x$ac_cv_type_ptrdiff_t" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_PTRDIFF_T 1
+_ACEOF
+
+
+fi
+ac_fn_c_check_type "$LINENO" "uchar" "ac_cv_type_uchar" "$ac_includes_default"
+if test "x$ac_cv_type_uchar" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_UCHAR 1
+_ACEOF
+
+
+fi
+ac_fn_c_check_type "$LINENO" "ushort" "ac_cv_type_ushort" "$ac_includes_default"
+if test "x$ac_cv_type_ushort" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_USHORT 1
+_ACEOF
+
+
+fi
+ac_fn_c_check_type "$LINENO" "uint" "ac_cv_type_uint" "$ac_includes_default"
+if test "x$ac_cv_type_uint" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_UINT 1
+_ACEOF
+
+
+fi
+ac_fn_c_check_type "$LINENO" "longlong" "ac_cv_type_longlong" "$ac_includes_default"
+if test "x$ac_cv_type_longlong" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_LONGLONG 1
+_ACEOF
+
+
+fi
+ac_fn_c_check_type "$LINENO" "ulonglong" "ac_cv_type_ulonglong" "$ac_includes_default"
+if test "x$ac_cv_type_ulonglong" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_ULONGLONG 1
+_ACEOF
+
+
+fi
+ac_fn_c_check_type "$LINENO" "int64" "ac_cv_type_int64" "$ac_includes_default"
+if test "x$ac_cv_type_int64" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_INT64 1
+_ACEOF
+
+
+fi
+ac_fn_c_check_type "$LINENO" "uint64" "ac_cv_type_uint64" "$ac_includes_default"
+if test "x$ac_cv_type_uint64" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_UINT64 1
+_ACEOF
+
+
+fi
+
+
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of size_t" >&5
+$as_echo_n "checking size of size_t... " >&6; }
+if ${ac_cv_sizeof_size_t+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (size_t))" "ac_cv_sizeof_size_t" "$ac_includes_default"; then :
+
+else
+ if test "$ac_cv_type_size_t" = yes; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (size_t)
+See \`config.log' for more details" "$LINENO" 5; }
+ else
+ ac_cv_sizeof_size_t=0
+ fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_size_t" >&5
+$as_echo "$ac_cv_sizeof_size_t" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_SIZE_T $ac_cv_sizeof_size_t
+_ACEOF
+
+
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of off_t" >&5
+$as_echo_n "checking size of off_t... " >&6; }
+if ${ac_cv_sizeof_off_t+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (off_t))" "ac_cv_sizeof_off_t" "$ac_includes_default"; then :
+
+else
+ if test "$ac_cv_type_off_t" = yes; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (off_t)
+See \`config.log' for more details" "$LINENO" 5; }
+ else
+ ac_cv_sizeof_off_t=0
+ fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_off_t" >&5
+$as_echo "$ac_cv_sizeof_off_t" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_OFF_T $ac_cv_sizeof_off_t
+_ACEOF
+
+
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of signed char" >&5
+$as_echo_n "checking size of signed char... " >&6; }
+if ${ac_cv_sizeof_signed_char+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (signed char))" "ac_cv_sizeof_signed_char" "$ac_includes_default"; then :
+
+else
+ if test "$ac_cv_type_signed_char" = yes; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (signed char)
+See \`config.log' for more details" "$LINENO" 5; }
+ else
+ ac_cv_sizeof_signed_char=0
+ fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_signed_char" >&5
+$as_echo "$ac_cv_sizeof_signed_char" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_SIGNED_CHAR $ac_cv_sizeof_signed_char
+_ACEOF
+
+
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of unsigned char" >&5
+$as_echo_n "checking size of unsigned char... " >&6; }
+if ${ac_cv_sizeof_unsigned_char+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (unsigned char))" "ac_cv_sizeof_unsigned_char" "$ac_includes_default"; then :
+
+else
+ if test "$ac_cv_type_unsigned_char" = yes; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (unsigned char)
+See \`config.log' for more details" "$LINENO" 5; }
+ else
+ ac_cv_sizeof_unsigned_char=0
+ fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_unsigned_char" >&5
+$as_echo "$ac_cv_sizeof_unsigned_char" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_UNSIGNED_CHAR $ac_cv_sizeof_unsigned_char
+_ACEOF
+
+
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of short" >&5
+$as_echo_n "checking size of short... " >&6; }
+if ${ac_cv_sizeof_short+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (short))" "ac_cv_sizeof_short" "$ac_includes_default"; then :
+
+else
+ if test "$ac_cv_type_short" = yes; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (short)
+See \`config.log' for more details" "$LINENO" 5; }
+ else
+ ac_cv_sizeof_short=0
+ fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_short" >&5
+$as_echo "$ac_cv_sizeof_short" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_SHORT $ac_cv_sizeof_short
+_ACEOF
+
+
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of unsigned short" >&5
+$as_echo_n "checking size of unsigned short... " >&6; }
+if ${ac_cv_sizeof_unsigned_short+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (unsigned short))" "ac_cv_sizeof_unsigned_short" "$ac_includes_default"; then :
+
+else
+ if test "$ac_cv_type_unsigned_short" = yes; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (unsigned short)
+See \`config.log' for more details" "$LINENO" 5; }
+ else
+ ac_cv_sizeof_unsigned_short=0
+ fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_unsigned_short" >&5
+$as_echo "$ac_cv_sizeof_unsigned_short" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_UNSIGNED_SHORT $ac_cv_sizeof_unsigned_short
+_ACEOF
+
+
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of int" >&5
+$as_echo_n "checking size of int... " >&6; }
+if ${ac_cv_sizeof_int+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (int))" "ac_cv_sizeof_int" "$ac_includes_default"; then :
+
+else
+ if test "$ac_cv_type_int" = yes; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (int)
+See \`config.log' for more details" "$LINENO" 5; }
+ else
+ ac_cv_sizeof_int=0
+ fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_int" >&5
+$as_echo "$ac_cv_sizeof_int" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_INT $ac_cv_sizeof_int
+_ACEOF
+
+
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of unsigned int" >&5
+$as_echo_n "checking size of unsigned int... " >&6; }
+if ${ac_cv_sizeof_unsigned_int+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (unsigned int))" "ac_cv_sizeof_unsigned_int" "$ac_includes_default"; then :
+
+else
+ if test "$ac_cv_type_unsigned_int" = yes; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (unsigned int)
+See \`config.log' for more details" "$LINENO" 5; }
+ else
+ ac_cv_sizeof_unsigned_int=0
+ fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_unsigned_int" >&5
+$as_echo "$ac_cv_sizeof_unsigned_int" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_UNSIGNED_INT $ac_cv_sizeof_unsigned_int
+_ACEOF
+
+
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long" >&5
+$as_echo_n "checking size of long... " >&6; }
+if ${ac_cv_sizeof_long+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long))" "ac_cv_sizeof_long" "$ac_includes_default"; then :
+
+else
+ if test "$ac_cv_type_long" = yes; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (long)
+See \`config.log' for more details" "$LINENO" 5; }
+ else
+ ac_cv_sizeof_long=0
+ fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long" >&5
+$as_echo "$ac_cv_sizeof_long" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_LONG $ac_cv_sizeof_long
+_ACEOF
+
+
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of float" >&5
+$as_echo_n "checking size of float... " >&6; }
+if ${ac_cv_sizeof_float+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (float))" "ac_cv_sizeof_float" "$ac_includes_default"; then :
+
+else
+ if test "$ac_cv_type_float" = yes; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (float)
+See \`config.log' for more details" "$LINENO" 5; }
+ else
+ ac_cv_sizeof_float=0
+ fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_float" >&5
+$as_echo "$ac_cv_sizeof_float" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_FLOAT $ac_cv_sizeof_float
+_ACEOF
+
+
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of double" >&5
+$as_echo_n "checking size of double... " >&6; }
+if ${ac_cv_sizeof_double+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (double))" "ac_cv_sizeof_double" "$ac_includes_default"; then :
+
+else
+ if test "$ac_cv_type_double" = yes; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (double)
+See \`config.log' for more details" "$LINENO" 5; }
+ else
+ ac_cv_sizeof_double=0
+ fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_double" >&5
+$as_echo "$ac_cv_sizeof_double" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_DOUBLE $ac_cv_sizeof_double
+_ACEOF
+
+
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long long" >&5
+$as_echo_n "checking size of long long... " >&6; }
+if ${ac_cv_sizeof_long_long+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long long))" "ac_cv_sizeof_long_long" "$ac_includes_default"; then :
+
+else
+ if test "$ac_cv_type_long_long" = yes; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (long long)
+See \`config.log' for more details" "$LINENO" 5; }
+ else
+ ac_cv_sizeof_long_long=0
+ fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long_long" >&5
+$as_echo "$ac_cv_sizeof_long_long" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_LONG_LONG $ac_cv_sizeof_long_long
+_ACEOF
+
+
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of unsigned long long" >&5
+$as_echo_n "checking size of unsigned long long... " >&6; }
+if ${ac_cv_sizeof_unsigned_long_long+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (unsigned long long))" "ac_cv_sizeof_unsigned_long_long" "$ac_includes_default"; then :
+
+else
+ if test "$ac_cv_type_unsigned_long_long" = yes; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (unsigned long long)
+See \`config.log' for more details" "$LINENO" 5; }
+ else
+ ac_cv_sizeof_unsigned_long_long=0
+ fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_unsigned_long_long" >&5
+$as_echo "$ac_cv_sizeof_unsigned_long_long" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_UNSIGNED_LONG_LONG $ac_cv_sizeof_unsigned_long_long
+_ACEOF
+
+
+
+if test "$ac_cv_type_ushort" = yes ; then
+ # The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of ushort" >&5
+$as_echo_n "checking size of ushort... " >&6; }
+if ${ac_cv_sizeof_ushort+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (ushort))" "ac_cv_sizeof_ushort" "$ac_includes_default"; then :
+
+else
+ if test "$ac_cv_type_ushort" = yes; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (ushort)
+See \`config.log' for more details" "$LINENO" 5; }
+ else
+ ac_cv_sizeof_ushort=0
+ fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_ushort" >&5
+$as_echo "$ac_cv_sizeof_ushort" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_USHORT $ac_cv_sizeof_ushort
+_ACEOF
+
+
+fi
+if test "$ac_cv_type_uint" = yes ; then
+ # The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of uint" >&5
+$as_echo_n "checking size of uint... " >&6; }
+if ${ac_cv_sizeof_uint+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (uint))" "ac_cv_sizeof_uint" "$ac_includes_default"; then :
+
+else
+ if test "$ac_cv_type_uint" = yes; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (uint)
+See \`config.log' for more details" "$LINENO" 5; }
+ else
+ ac_cv_sizeof_uint=0
+ fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_uint" >&5
+$as_echo "$ac_cv_sizeof_uint" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_UINT $ac_cv_sizeof_uint
+_ACEOF
+
+
+fi
+if test "$ac_cv_type_longlong" = yes ; then
+ # The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of longlong" >&5
+$as_echo_n "checking size of longlong... " >&6; }
+if ${ac_cv_sizeof_longlong+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (longlong))" "ac_cv_sizeof_longlong" "$ac_includes_default"; then :
+
+else
+ if test "$ac_cv_type_longlong" = yes; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (longlong)
+See \`config.log' for more details" "$LINENO" 5; }
+ else
+ ac_cv_sizeof_longlong=0
+ fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_longlong" >&5
+$as_echo "$ac_cv_sizeof_longlong" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_LONGLONG $ac_cv_sizeof_longlong
+_ACEOF
+
+
+fi
+if test "$ac_cv_type_ulonglong" = yes ; then
+ # The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of ulonglong" >&5
+$as_echo_n "checking size of ulonglong... " >&6; }
+if ${ac_cv_sizeof_ulonglong+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (ulonglong))" "ac_cv_sizeof_ulonglong" "$ac_includes_default"; then :
+
+else
+ if test "$ac_cv_type_ulonglong" = yes; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (ulonglong)
+See \`config.log' for more details" "$LINENO" 5; }
+ else
+ ac_cv_sizeof_ulonglong=0
+ fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_ulonglong" >&5
+$as_echo "$ac_cv_sizeof_ulonglong" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_ULONGLONG $ac_cv_sizeof_ulonglong
+_ACEOF
+
+
+fi
+
+if test "x${enable_fortran}" = xyes ; then
+ if test "$cross_compiling" = yes; then
+
+ ac_ext=${ac_fc_srcext-f}
+ac_compile='$FC -c $FCFLAGS $ac_fcflags_srcext conftest.$ac_ext >&5'
+ac_link='$FC -o conftest$ac_exeext $FCFLAGS $LDFLAGS $ac_fcflags_srcext conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_fc_compiler_gnu
+
+ for ftype in integer*1 byte "integer(kind=1)"; do
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Fortran \"$ftype\"" >&5
+$as_echo_n "checking for Fortran \"$ftype\"... " >&6; }
+ cat > conftest.$ac_ext <<_ACEOF
+
+ subroutine sub(value)
+ $ftype value
+ end
+
+_ACEOF
+if ac_fn_fc_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ NF_INT1_T=$ftype
+ cat >>confdefs.h <<_ACEOF
+#define NF_INT1_T $ftype
+_ACEOF
+
+ break
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ done
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+ ac_ext=${ac_fc_srcext-f}
+ac_compile='$FC -c $FCFLAGS $ac_fcflags_srcext conftest.$ac_ext >&5'
+ac_link='$FC -o conftest$ac_exeext $FCFLAGS $LDFLAGS $ac_fcflags_srcext conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_fc_compiler_gnu
+
+ for ftype in integer*2 "integer(kind=2)"; do
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Fortran \"$ftype\"" >&5
+$as_echo_n "checking for Fortran \"$ftype\"... " >&6; }
+ cat > conftest.$ac_ext <<_ACEOF
+
+ subroutine sub(value)
+ $ftype value
+ end
+
+_ACEOF
+if ac_fn_fc_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ NF_INT2_T=$ftype
+ cat >>confdefs.h <<_ACEOF
+#define NF_INT2_T $ftype
+_ACEOF
+
+ break
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ done
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+ ac_ext=${ac_fc_srcext-f}
+ac_compile='$FC -c $FCFLAGS $ac_fcflags_srcext conftest.$ac_ext >&5'
+ac_link='$FC -o conftest$ac_exeext $FCFLAGS $LDFLAGS $ac_fcflags_srcext conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_fc_compiler_gnu
+
+ for ftype in integer*8 "integer(kind=8)"; do
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Fortran \"$ftype\"" >&5
+$as_echo_n "checking for Fortran \"$ftype\"... " >&6; }
+ cat > conftest.$ac_ext <<_ACEOF
+
+ subroutine sub(value)
+ $ftype value
+ end
+
+_ACEOF
+if ac_fn_fc_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ NF_INT8_T=$ftype
+ cat >>confdefs.h <<_ACEOF
+#define NF_INT8_T $ftype
+_ACEOF
+
+ break
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ done
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+ else
+
+ case "$FC" in
+ '') ;;
+ *)
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for C-equivalent to Fortran routine \"SUB\"" >&5
+$as_echo_n "checking for C-equivalent to Fortran routine \"SUB\"... " >&6; }
+ ac_ext=${ac_fc_srcext-f}
+ac_compile='$FC -c $FCFLAGS $ac_fcflags_srcext conftest.$ac_ext >&5'
+ac_link='$FC -o conftest$ac_exeext $FCFLAGS $LDFLAGS $ac_fcflags_srcext conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_fc_compiler_gnu
+case $ac_cv_fc_mangling in
+ upper*) ac_val="SUB" ;;
+ lower*) ac_val="sub" ;;
+ *) ac_val="unknown" ;;
+esac
+case $ac_cv_fc_mangling in *," underscore"*) ac_val="$ac_val"_ ;; esac
+
+FCALLSCSUB="$ac_val"
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $FCALLSCSUB" >&5
+$as_echo "$FCALLSCSUB" >&6; }
+ ;;
+ esac
+
+
+ case "$FC" in
+ '')
+ ;;
+ *)
+
+
+ ac_ext=${ac_fc_srcext-f}
+ac_compile='$FC -c $FCFLAGS $ac_fcflags_srcext conftest.$ac_ext >&5'
+ac_link='$FC -o conftest$ac_exeext $FCFLAGS $LDFLAGS $ac_fcflags_srcext conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_fc_compiler_gnu
+
+ for ftype in integer*1 byte "integer(kind=1)"; do
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Fortran \"$ftype\"" >&5
+$as_echo_n "checking for Fortran \"$ftype\"... " >&6; }
+ cat > conftest.$ac_ext <<_ACEOF
+
+ subroutine sub(value)
+ $ftype value
+ end
+
+_ACEOF
+if ac_fn_fc_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ NF_INT1_T=$ftype
+ cat >>confdefs.h <<_ACEOF
+#define NF_INT1_T $ftype
+_ACEOF
+
+ break
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ done
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+ ac_ext=${ac_fc_srcext-f}
+ac_compile='$FC -c $FCFLAGS $ac_fcflags_srcext conftest.$ac_ext >&5'
+ac_link='$FC -o conftest$ac_exeext $FCFLAGS $LDFLAGS $ac_fcflags_srcext conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_fc_compiler_gnu
+
+ for ftype in integer*2 "integer(kind=2)"; do
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Fortran \"$ftype\"" >&5
+$as_echo_n "checking for Fortran \"$ftype\"... " >&6; }
+ cat > conftest.$ac_ext <<_ACEOF
+
+ subroutine sub(value)
+ $ftype value
+ end
+
+_ACEOF
+if ac_fn_fc_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ NF_INT2_T=$ftype
+ cat >>confdefs.h <<_ACEOF
+#define NF_INT2_T $ftype
+_ACEOF
+
+ break
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ done
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+ ac_ext=${ac_fc_srcext-f}
+ac_compile='$FC -c $FCFLAGS $ac_fcflags_srcext conftest.$ac_ext >&5'
+ac_link='$FC -o conftest$ac_exeext $FCFLAGS $LDFLAGS $ac_fcflags_srcext conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_fc_compiler_gnu
+
+ for ftype in integer*8 "integer(kind=8)"; do
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Fortran \"$ftype\"" >&5
+$as_echo_n "checking for Fortran \"$ftype\"... " >&6; }
+ cat > conftest.$ac_ext <<_ACEOF
+
+ subroutine sub(value)
+ $ftype value
+ end
+
+_ACEOF
+if ac_fn_fc_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ NF_INT8_T=$ftype
+ cat >>confdefs.h <<_ACEOF
+#define NF_INT8_T $ftype
+_ACEOF
+
+ break
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ done
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+ case "${NF_INT1_T}" in
+ '') ;;
+ *)
+ cat >conftestf.f <<EOF
+ $NF_INT1_T values(4)
+ integer status, sub
+ data values /-1, -2, -3, -4/
+ status = sub(values)
+ end
+EOF
+ ac_cv_ctype_fortran=no
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if Fortran \"$NF_INT1_T\" is " >&5
+$as_echo_n "checking if Fortran \"$NF_INT1_T\" is ... " >&6; }
+ for ctype in "signed char" short int long; do
+ cat >conftest.c <<EOF
+ int $FCALLSCSUB($ctype values[4])
+ {
+ return(values[1] != -2 || values[2] != -3);
+ }
+EOF
+ doit='$CC -c ${CPPFLAGS} ${CFLAGS} conftest.c'
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$doit\""; } >&5
+ (eval $doit) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ doit='$FC ${FFLAGS} -c conftestf.f'
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$doit\""; } >&5
+ (eval $doit) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ doit='$FC -o conftest ${FFLAGS} ${FLDFLAGS} conftestf.o conftest.o ${LDFLAGS} ${LIBS}'
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$doit\""; } >&5
+ (eval $doit) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ doit=./conftest
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$doit\""; } >&5
+ (eval $doit) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: \"$ctype\" in C" >&5
+$as_echo "\"$ctype\" in C" >&6; }
+ cname=`echo $ctype | tr ' abcdefghijklmnopqrstuvwxyz' \
+ _ABCDEFGHIJKLMNOPQRSTUVWXYZ`
+ cat >>confdefs.h <<_ACEOF
+#define NF_INT1_IS_C_$cname 1
+_ACEOF
+
+ ac_cv_ctype_fortran=yes
+ break
+ fi
+ else
+ as_fn_error $? "Could not link conftestf.o and conftest.o" "$LINENO" 5
+ fi
+ else
+ as_fn_error $? "Could not compile conftestf.f" "$LINENO" 5
+ fi
+ else
+ as_fn_error $? "Could not compile conftest.c" "$LINENO" 5
+ fi
+ done
+ ${RM} -f conftest*
+
+ if test "$ac_cv_ctype_fortran" = no ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no correspond data type in C" >&5
+$as_echo "no correspond data type in C" >&6; }
+ fi
+ unset ac_cv_ctype_fortran
+
+ ;;
+ esac
+ case "${NF_INT2_T}" in
+ '') ;;
+ *)
+ cat >conftestf.f <<EOF
+ $NF_INT2_T values(4)
+ integer status, sub
+ data values /-1, -2, -3, -4/
+ status = sub(values)
+ end
+EOF
+ ac_cv_ctype_fortran=no
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if Fortran \"$NF_INT2_T\" is " >&5
+$as_echo_n "checking if Fortran \"$NF_INT2_T\" is ... " >&6; }
+ for ctype in short int long; do
+ cat >conftest.c <<EOF
+ int $FCALLSCSUB($ctype values[4])
+ {
+ return(values[1] != -2 || values[2] != -3);
+ }
+EOF
+ doit='$CC -c ${CPPFLAGS} ${CFLAGS} conftest.c'
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$doit\""; } >&5
+ (eval $doit) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ doit='$FC ${FFLAGS} -c conftestf.f'
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$doit\""; } >&5
+ (eval $doit) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ doit='$FC -o conftest ${FFLAGS} ${FLDFLAGS} conftestf.o conftest.o ${LDFLAGS} ${LIBS}'
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$doit\""; } >&5
+ (eval $doit) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ doit=./conftest
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$doit\""; } >&5
+ (eval $doit) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: \"$ctype\" in C" >&5
+$as_echo "\"$ctype\" in C" >&6; }
+ cname=`echo $ctype | tr ' abcdefghijklmnopqrstuvwxyz' \
+ _ABCDEFGHIJKLMNOPQRSTUVWXYZ`
+ cat >>confdefs.h <<_ACEOF
+#define NF_INT2_IS_C_$cname 1
+_ACEOF
+
+ ac_cv_ctype_fortran=yes
+ break
+ fi
+ else
+ as_fn_error $? "Could not link conftestf.o and conftest.o" "$LINENO" 5
+ fi
+ else
+ as_fn_error $? "Could not compile conftestf.f" "$LINENO" 5
+ fi
+ else
+ as_fn_error $? "Could not compile conftest.c" "$LINENO" 5
+ fi
+ done
+ ${RM} -f conftest*
+
+ if test "$ac_cv_ctype_fortran" = no ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no correspond data type in C" >&5
+$as_echo "no correspond data type in C" >&6; }
+ fi
+ unset ac_cv_ctype_fortran
+
+ ;;
+ esac
+ case "${NF_INT8_T}" in
+ '') ;;
+ *)
+ cat >conftestf.f <<EOF
+ $NF_INT8_T values(4)
+ integer status, sub
+ data values /-1, -2, -3, -4/
+ status = sub(values)
+ end
+EOF
+ ac_cv_ctype_fortran=no
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if Fortran \"$NF_INT8_T\" is " >&5
+$as_echo_n "checking if Fortran \"$NF_INT8_T\" is ... " >&6; }
+ for ctype in int long "long long"; do
+ cat >conftest.c <<EOF
+ int $FCALLSCSUB($ctype values[4])
+ {
+ return(values[1] != -2 || values[2] != -3);
+ }
+EOF
+ doit='$CC -c ${CPPFLAGS} ${CFLAGS} conftest.c'
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$doit\""; } >&5
+ (eval $doit) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ doit='$FC ${FFLAGS} -c conftestf.f'
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$doit\""; } >&5
+ (eval $doit) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ doit='$FC -o conftest ${FFLAGS} ${FLDFLAGS} conftestf.o conftest.o ${LDFLAGS} ${LIBS}'
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$doit\""; } >&5
+ (eval $doit) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ doit=./conftest
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$doit\""; } >&5
+ (eval $doit) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: \"$ctype\" in C" >&5
+$as_echo "\"$ctype\" in C" >&6; }
+ cname=`echo $ctype | tr ' abcdefghijklmnopqrstuvwxyz' \
+ _ABCDEFGHIJKLMNOPQRSTUVWXYZ`
+ cat >>confdefs.h <<_ACEOF
+#define NF_INT8_IS_C_$cname 1
+_ACEOF
+
+ ac_cv_ctype_fortran=yes
+ break
+ fi
+ else
+ as_fn_error $? "Could not link conftestf.o and conftest.o" "$LINENO" 5
+ fi
+ else
+ as_fn_error $? "Could not compile conftestf.f" "$LINENO" 5
+ fi
+ else
+ as_fn_error $? "Could not compile conftest.c" "$LINENO" 5
+ fi
+ done
+ ${RM} -f conftest*
+
+ if test "$ac_cv_ctype_fortran" = no ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no correspond data type in C" >&5
+$as_echo "no correspond data type in C" >&6; }
+ fi
+ unset ac_cv_ctype_fortran
+
+ ;;
+ esac
+
+ cat >conftestf.f <<EOF
+ integer values(4)
+ integer status, sub
+ data values /-1, -2, -3, -4/
+ status = sub(values)
+ end
+EOF
+ ac_cv_ctype_fortran=no
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if Fortran \"integer\" is " >&5
+$as_echo_n "checking if Fortran \"integer\" is ... " >&6; }
+ for ctype in int long; do
+ cat >conftest.c <<EOF
+ int $FCALLSCSUB($ctype values[4])
+ {
+ return(values[1] != -2 || values[2] != -3);
+ }
+EOF
+ doit='$CC -c ${CPPFLAGS} ${CFLAGS} conftest.c'
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$doit\""; } >&5
+ (eval $doit) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ doit='$FC ${FFLAGS} -c conftestf.f'
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$doit\""; } >&5
+ (eval $doit) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ doit='$FC -o conftest ${FFLAGS} ${FLDFLAGS} conftestf.o conftest.o ${LDFLAGS} ${LIBS}'
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$doit\""; } >&5
+ (eval $doit) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ doit=./conftest
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$doit\""; } >&5
+ (eval $doit) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: \"$ctype\" in C" >&5
+$as_echo "\"$ctype\" in C" >&6; }
+ cname=`echo $ctype | tr ' abcdefghijklmnopqrstuvwxyz' \
+ _ABCDEFGHIJKLMNOPQRSTUVWXYZ`
+ cat >>confdefs.h <<_ACEOF
+#define NF_INT_IS_C_$cname 1
+_ACEOF
+
+ ac_cv_ctype_fortran=yes
+ break
+ fi
+ else
+ as_fn_error $? "Could not link conftestf.o and conftest.o" "$LINENO" 5
+ fi
+ else
+ as_fn_error $? "Could not compile conftestf.f" "$LINENO" 5
+ fi
+ else
+ as_fn_error $? "Could not compile conftest.c" "$LINENO" 5
+ fi
+ done
+ ${RM} -f conftest*
+
+ if test "$ac_cv_ctype_fortran" = no ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no correspond data type in C" >&5
+$as_echo "no correspond data type in C" >&6; }
+ fi
+ unset ac_cv_ctype_fortran
+
+
+ cat >conftestf.f <<EOF
+ real values(4)
+ integer status, sub
+ data values /-1, -2, -3, -4/
+ status = sub(values)
+ end
+EOF
+ ac_cv_ctype_fortran=no
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if Fortran \"real\" is " >&5
+$as_echo_n "checking if Fortran \"real\" is ... " >&6; }
+ for ctype in float double; do
+ cat >conftest.c <<EOF
+ int $FCALLSCSUB($ctype values[4])
+ {
+ return(values[1] != -2 || values[2] != -3);
+ }
+EOF
+ doit='$CC -c ${CPPFLAGS} ${CFLAGS} conftest.c'
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$doit\""; } >&5
+ (eval $doit) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ doit='$FC ${FFLAGS} -c conftestf.f'
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$doit\""; } >&5
+ (eval $doit) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ doit='$FC -o conftest ${FFLAGS} ${FLDFLAGS} conftestf.o conftest.o ${LDFLAGS} ${LIBS}'
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$doit\""; } >&5
+ (eval $doit) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ doit=./conftest
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$doit\""; } >&5
+ (eval $doit) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: \"$ctype\" in C" >&5
+$as_echo "\"$ctype\" in C" >&6; }
+ cname=`echo $ctype | tr ' abcdefghijklmnopqrstuvwxyz' \
+ _ABCDEFGHIJKLMNOPQRSTUVWXYZ`
+ cat >>confdefs.h <<_ACEOF
+#define NF_REAL_IS_C_$cname 1
+_ACEOF
+
+ ac_cv_ctype_fortran=yes
+ break
+ fi
+ else
+ as_fn_error $? "Could not link conftestf.o and conftest.o" "$LINENO" 5
+ fi
+ else
+ as_fn_error $? "Could not compile conftestf.f" "$LINENO" 5
+ fi
+ else
+ as_fn_error $? "Could not compile conftest.c" "$LINENO" 5
+ fi
+ done
+ ${RM} -f conftest*
+
+ if test "$ac_cv_ctype_fortran" = no ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no correspond data type in C" >&5
+$as_echo "no correspond data type in C" >&6; }
+ fi
+ unset ac_cv_ctype_fortran
+
+
+ cat >conftestf.f <<EOF
+ doubleprecision values(4)
+ integer status, sub
+ data values /-1, -2, -3, -4/
+ status = sub(values)
+ end
+EOF
+ ac_cv_ctype_fortran=no
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if Fortran \"doubleprecision\" is " >&5
+$as_echo_n "checking if Fortran \"doubleprecision\" is ... " >&6; }
+ for ctype in double float; do
+ cat >conftest.c <<EOF
+ int $FCALLSCSUB($ctype values[4])
+ {
+ return(values[1] != -2 || values[2] != -3);
+ }
+EOF
+ doit='$CC -c ${CPPFLAGS} ${CFLAGS} conftest.c'
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$doit\""; } >&5
+ (eval $doit) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ doit='$FC ${FFLAGS} -c conftestf.f'
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$doit\""; } >&5
+ (eval $doit) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ doit='$FC -o conftest ${FFLAGS} ${FLDFLAGS} conftestf.o conftest.o ${LDFLAGS} ${LIBS}'
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$doit\""; } >&5
+ (eval $doit) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ doit=./conftest
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$doit\""; } >&5
+ (eval $doit) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: \"$ctype\" in C" >&5
+$as_echo "\"$ctype\" in C" >&6; }
+ cname=`echo $ctype | tr ' abcdefghijklmnopqrstuvwxyz' \
+ _ABCDEFGHIJKLMNOPQRSTUVWXYZ`
+ cat >>confdefs.h <<_ACEOF
+#define NF_DOUBLEPRECISION_IS_C_$cname 1
+_ACEOF
+
+ ac_cv_ctype_fortran=yes
+ break
+ fi
+ else
+ as_fn_error $? "Could not link conftestf.o and conftest.o" "$LINENO" 5
+ fi
+ else
+ as_fn_error $? "Could not compile conftestf.f" "$LINENO" 5
+ fi
+ else
+ as_fn_error $? "Could not compile conftest.c" "$LINENO" 5
+ fi
+ done
+ ${RM} -f conftest*
+
+ if test "$ac_cv_ctype_fortran" = no ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no correspond data type in C" >&5
+$as_echo "no correspond data type in C" >&6; }
+ fi
+ unset ac_cv_ctype_fortran
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Fortran-equivalent to netCDF \"byte\"" >&5
+$as_echo_n "checking for Fortran-equivalent to netCDF \"byte\"... " >&6; }
+
+ ac_ext=${ac_fc_srcext-f}
+ac_compile='$FC -c $FCFLAGS $ac_fcflags_srcext conftest.$ac_ext >&5'
+ac_link='$FC -o conftest$ac_exeext $FCFLAGS $LDFLAGS $ac_fcflags_srcext conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_fc_compiler_gnu
+
+ for type in byte integer*1 integer; do
+ cat > conftest.$ac_ext <<_ACEOF
+
+ $type foo
+ end
+
+_ACEOF
+if ac_fn_fc_try_compile "$LINENO"; then :
+ break
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ done
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ cat >>confdefs.h <<_ACEOF
+#define NCBYTE_T $type
+_ACEOF
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $type" >&5
+$as_echo "$type" >&6; }
+ NCBYTE_T=$type
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Fortran-equivalent to netCDF \"short\"" >&5
+$as_echo_n "checking for Fortran-equivalent to netCDF \"short\"... " >&6; }
+
+ ac_ext=${ac_fc_srcext-f}
+ac_compile='$FC -c $FCFLAGS $ac_fcflags_srcext conftest.$ac_ext >&5'
+ac_link='$FC -o conftest$ac_exeext $FCFLAGS $LDFLAGS $ac_fcflags_srcext conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_fc_compiler_gnu
+
+ for type in integer*2 integer; do
+ cat > conftest.$ac_ext <<_ACEOF
+
+ $type foo
+ end
+
+_ACEOF
+if ac_fn_fc_try_compile "$LINENO"; then :
+ break
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ done
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ cat >>confdefs.h <<_ACEOF
+#define NCSHORT_T $type
+_ACEOF
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $type" >&5
+$as_echo "$type" >&6; }
+ NCSHORT_T=$type
+
+
+
+
+ ;;
+ esac
+
+ fi
+
+ NFMPI_OFFSET="integer*$ac_cv_sizeof_MPI_Offset"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Fortran NFMPI_OFFSET \"$NFMPI_OFFSET\"" >&5
+$as_echo_n "checking for Fortran NFMPI_OFFSET \"$NFMPI_OFFSET\"... " >&6; }
+ ac_ext=f
+ac_compile='$F77 -c $FFLAGS conftest.$ac_ext >&5'
+ac_link='$F77 -o conftest$ac_exeext $FFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_f77_compiler_gnu
+
+ cat > conftest.$ac_ext <<_ACEOF
+
+ subroutine sub(value)
+ $NFMPI_OFFSET value
+ end
+
+_ACEOF
+if ac_fn_f77_try_compile "$LINENO"; then :
+ ac_cv_NFMPI_OFFSET=yes
+else
+ ac_cv_NFMPI_OFFSET=no
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ if test "$ac_cv_NFMPI_OFFSET" = yes ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ as_fn_error $? "F77 does not support \"$NFMPI_OFFSET\"" "$LINENO" 5
+ fi
+ ${RM} -rf conftest*
+fi
+
+SIZEOF_MPI_OFFSET=$ac_cv_sizeof_MPI_Offset
+
+
+if test "x${enable_fortran}" = xyes ; then
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking Fortran 90 module extension" >&5
+$as_echo_n "checking Fortran 90 module extension... " >&6; }
+if ${ac_cv_fc_module_ext+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_ext=${ac_fc_srcext-f}
+ac_compile='$FC -c $FCFLAGS $ac_fcflags_srcext conftest.$ac_ext >&5'
+ac_link='$FC -o conftest$ac_exeext $FCFLAGS $LDFLAGS $ac_fcflags_srcext conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_fc_compiler_gnu
+
+mkdir conftest.dir
+cd conftest.dir
+ac_cv_fc_module_ext=unknown
+cat > conftest.$ac_ext <<_ACEOF
+
+ module conftest_module
+ contains
+ subroutine conftest_routine
+ write(*,'(a)') 'gotcha!'
+ end subroutine
+ end module
+_ACEOF
+if ac_fn_fc_try_compile "$LINENO"; then :
+ ac_cv_fc_module_ext=`ls | sed -n 's,conftest_module\.,,p'`
+ if test x$ac_cv_fc_module_ext = x; then
+ ac_cv_fc_module_ext=`ls | sed -n 's,CONFTEST_MODULE\.,,p'`
+ fi
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+cd ..
+${RM} -rf conftest.dir
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_fc_module_ext" >&5
+$as_echo "$ac_cv_fc_module_ext" >&6; }
+FC_MODEXT=$ac_cv_fc_module_ext
+if test "$FC_MODEXT" = unknown; then
+ FC_MODEXT=
+fi
+
+ if test "x${FC_MODEXT}" = x ; then
+ as_fn_error $? "cannot determine Fortran module file extension!" "$LINENO" 5
+ fi
+ if test "x${_DEBUG}" = xyes ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: DEBUG: FC_MODEXT=$FC_MODEXT" >&5
+$as_echo "$as_me: DEBUG: FC_MODEXT=$FC_MODEXT" >&6;}
+ fi
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking Fortran 90 module inclusion flag" >&5
+$as_echo_n "checking Fortran 90 module inclusion flag... " >&6; }
+if ${ac_cv_fc_module_flag+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_ext=${ac_fc_srcext-f}
+ac_compile='$FC -c $FCFLAGS $ac_fcflags_srcext conftest.$ac_ext >&5'
+ac_link='$FC -o conftest$ac_exeext $FCFLAGS $LDFLAGS $ac_fcflags_srcext conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_fc_compiler_gnu
+
+ac_cv_fc_module_flag=unknown
+mkdir conftest.dir
+cd conftest.dir
+cat > conftest.$ac_ext <<_ACEOF
+
+ module conftest_module
+ contains
+ subroutine conftest_routine
+ write(*,'(a)') 'gotcha!'
+ end subroutine
+ end module
+_ACEOF
+if ac_fn_fc_try_compile "$LINENO"; then :
+ cd ..
+ ac_fc_module_flag_FCFLAGS_save=$FCFLAGS
+ # Flag ordering is significant for gfortran and Sun.
+ for ac_flag in -I '-I ' -M '-M ' -p '-mod ' '-mdir ' '-module ' '-Am -I'; do
+ # Add the flag twice to prevent matching an output flag.
+ FCFLAGS="$ac_fc_module_flag_FCFLAGS_save ${ac_flag}conftest.dir ${ac_flag}conftest.dir"
+ cat > conftest.$ac_ext <<_ACEOF
+
+ program main
+ use conftest_module
+ call conftest_routine
+ end
+_ACEOF
+if ac_fn_fc_try_compile "$LINENO"; then :
+ ac_cv_fc_module_flag="$ac_flag"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ if test "$ac_cv_fc_module_flag" != unknown; then
+ break
+ fi
+ done
+ FCFLAGS=$ac_fc_module_flag_FCFLAGS_save
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+${RM} -rf conftest.dir
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_fc_module_flag" >&5
+$as_echo "$ac_cv_fc_module_flag" >&6; }
+if test "$ac_cv_fc_module_flag" != unknown; then
+ FC_MODINC=$ac_cv_fc_module_flag
+
+else
+ FC_MODINC=
+ as_fn_error $? "unable to find compiler flag for module search path" "$LINENO" 5
+fi
+
+# Ensure trailing whitespace is preserved in a Makefile.
+ac_empty=""
+
+
+ if test "x${_DEBUG}" = xyes ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: DEBUG: FC_MODINC=$FC_MODINC" >&5
+$as_echo "$as_me: DEBUG: FC_MODINC=$FC_MODINC" >&6;}
+ fi
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking Fortran 90 module output flag" >&5
+$as_echo_n "checking Fortran 90 module output flag... " >&6; }
+if ${ac_cv_fc_module_output_flag+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_ext=${ac_fc_srcext-f}
+ac_compile='$FC -c $FCFLAGS $ac_fcflags_srcext conftest.$ac_ext >&5'
+ac_link='$FC -o conftest$ac_exeext $FCFLAGS $LDFLAGS $ac_fcflags_srcext conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_fc_compiler_gnu
+
+mkdir conftest.dir conftest.dir/sub
+cd conftest.dir
+ac_cv_fc_module_output_flag=unknown
+ac_fc_module_output_flag_FCFLAGS_save=$FCFLAGS
+# Flag ordering is significant: put flags late which some compilers use
+# for the search path.
+for ac_flag in -J '-J ' -fmod= -moddir= +moddir= -qmoddir= '-mod ' \
+ '-mdir ' '-module ' -M '-Am -M' '-e m -J '; do
+ FCFLAGS="$ac_fc_module_output_flag_FCFLAGS_save ${ac_flag}sub"
+ cat > conftest.$ac_ext <<_ACEOF
+
+ module conftest_module
+ contains
+ subroutine conftest_routine
+ write(*,'(a)') 'gotcha!'
+ end subroutine
+ end module
+_ACEOF
+if ac_fn_fc_try_compile "$LINENO"; then :
+ cd sub
+ cat > conftest.$ac_ext <<_ACEOF
+
+ program main
+ use conftest_module
+ call conftest_routine
+ end
+_ACEOF
+if ac_fn_fc_try_compile "$LINENO"; then :
+ ac_cv_fc_module_output_flag="$ac_flag"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ cd ..
+ if test "$ac_cv_fc_module_output_flag" != unknown; then
+ break
+ fi
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+FCFLAGS=$ac_fc_module_output_flag_FCFLAGS_save
+cd ..
+${RM} -rf conftest.dir
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_fc_module_output_flag" >&5
+$as_echo "$ac_cv_fc_module_output_flag" >&6; }
+if test "$ac_cv_fc_module_output_flag" != unknown; then
+ FC_MODOUT=$ac_cv_fc_module_output_flag
+
+else
+ FC_MODOUT=
+ as_fn_error $? "unable to find compiler flag to write module information to" "$LINENO" 5
+fi
+
+# Ensure trailing whitespace is preserved in a Makefile.
+ac_empty=""
+
+
+ if test "x${_DEBUG}" = xyes ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: DEBUG: FC_MODOUT=$FC_MODOUT" >&5
+$as_echo "$as_me: DEBUG: FC_MODOUT=$FC_MODOUT" >&6;}
+ fi
+
+
+fi
+
+if test "x${enable_fortran}" = xyes ; then
+
+
+ac_ext=${ac_fc_srcext-f}
+ac_compile='$FC -c $FCFLAGS $ac_fcflags_srcext conftest.$ac_ext >&5'
+ac_link='$FC -o conftest$ac_exeext $FCFLAGS $LDFLAGS $ac_fcflags_srcext conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_fc_compiler_gnu
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if Fortran 90 compiler capitalizes .mod filenames" >&5
+$as_echo_n "checking if Fortran 90 compiler capitalizes .mod filenames... " >&6; }
+cat > conftest.$ac_ext <<_ACEOF
+
+ module conftest
+ end module conftest
+
+
+_ACEOF
+if ac_fn_fc_try_compile "$LINENO"; then :
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+if test -f conftest.${FC_MODEXT} ; then
+ ac_cv_prog_f90_uppercase_mod=no
+else
+ ac_cv_prog_f90_uppercase_mod=yes
+ ${RM} -f CONFTEST.${FC_MODEXT}
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_f90_uppercase_mod" >&5
+$as_echo "$ac_cv_prog_f90_uppercase_mod" >&6; }
+${RM} -f conftest*
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+UPPER_CASE_MOD=no
+if test "x$ac_cv_prog_f90_uppercase_mod" = xyes ; then
+ UPPER_CASE_MOD=yes
+fi
+
+
+if test "x${enable_fortran}" = xyes ; then
+ if test "x${enable_strict}" = xyes; then
+ FPPFLAGS="${FPPFLAGS} -Wall"
+ fi
+
+
+
+
+
+fi
+
+has_fortran=${enable_fortran}
+
+
+
+ #
+ # NB: We always want to define WHATIS to prevent the
+ # $(MANDIR)/$(WHATIS) make(1) target from being just $(MANDIR)/ and
+ # conflicting with the (directory creation) target with the same name.
+ #
+ WHATIS=whatis
+ case `uname -sr` in
+ BSD/OS*|FreeBSD*)
+ # Can't generate a user-database -- only /usr/share/man/whatis.db.
+ MAKEWHATIS_CMD=
+ ;;
+ 'IRIX64 6.5'|'IRIX 6.5')
+ MAKEWHATIS_CMD='/usr/lib/makewhatis -M $(MANDIR) $(MANDIR)/whatis'
+ ;;
+ 'IRIX 6'*)
+ # Can't generate a user-database.
+ MAKEWHATIS_CMD=
+ ;;
+ HP-UX*)
+ # Can't generate a user-database -- only /usr/lib/whatis.
+ MAKEWHATIS_CMD=
+ ;;
+ 'Linux '*)
+ # /usr/sbin/makewhatis doesn't work
+ MAKEWHATIS_CMD=
+ ;;
+ ULTRIX*)
+ # Can't generate a user-database -- only /usr/lib/whatis.
+ MAKEWHATIS_CMD=
+ ;;
+ *)
+ if test -r /usr/man/windex; then
+ WHATIS=windex
+ fi
+ for ac_prog in catman makewhatis /usr/lib/makewhatis
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_prog+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$prog"; then
+ ac_cv_prog_prog="$prog" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_prog="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+prog=$ac_cv_prog_prog
+if test -n "$prog"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $prog" >&5
+$as_echo "$prog" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$prog" && break
+done
+
+ case "$prog" in
+ *catman*)
+ MAKEWHATIS_CMD=$prog' -w -M $(MANDIR)'
+ ;;
+ *makewhatis*)
+ MAKEWHATIS_CMD=$prog' $(MANDIR)'
+ ;;
+ esac
+ ;;
+ esac
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for manual-page index command" >&5
+$as_echo_n "checking for manual-page index command... " >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAKEWHATIS_CMD" >&5
+$as_echo "$MAKEWHATIS_CMD" >&6; }
+
+
+# Check whether --enable-coverage was given.
+if test "${enable_coverage+set}" = set; then :
+ enableval=$enable_coverage; enable_coverage=${enableval}
+else
+ enable_coverage=no
+
+fi
+
+if test "x${enable_coverage}" = xyes; then
+ if test "x${GCC}" = xyes; then
+ LCOV_FLAGS="-pg -fprofile-arcs -ftest-coverage --coverage -O0"
+ CFLAGS="${CFLAGS} ${LCOV_FLAGS}"
+ if test "x${has_mpicxx}" = xyes ; then
+ CXXFLAGS="${CXXFLAGS} ${LCOV_FLAGS}"
+ fi
+ if test "x${enable_fortran}" = xyes ; then
+ FCFLAGS="${FCFLAGS} ${LCOV_FLAGS}"
+ F77FLAGS="${F77FLAGS} ${LCOV_FLAGS}"
+ F90FLAGS="${F90FLAGS} ${LCOV_FLAGS}"
+ fi
+ LCOV_LIB=-lgcov
+
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: --enable-coverage is for GNU compiler only" >&5
+$as_echo "$as_me: WARNING: --enable-coverage is for GNU compiler only" >&2;}
+ enable_coverage=no
+ fi
+fi
+
+
+if test "x${has_mpicxx}" = xyes ; then
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if C++ macro __func__ or __FUNCTION__ is defined" >&5
+$as_echo_n "checking if C++ macro __func__ or __FUNCTION__ is defined... " >&6; }
+if ${ac_cv_cxx_macro_func+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_cxx_macro_func=no
+ ac_cv_cxx_macro_function=no
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <iostream>
+#ifdef FC_DUMMY_MAIN
+#ifndef FC_DUMMY_MAIN_EQ_F77
+# ifdef __cplusplus
+ extern "C"
+# endif
+ int FC_DUMMY_MAIN() { return 1; }
+#endif
+#endif
+int
+main ()
+{
+std::cout << __func__;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ ac_cv_cxx_macro_func=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <iostream>
+#ifdef FC_DUMMY_MAIN
+#ifndef FC_DUMMY_MAIN_EQ_F77
+# ifdef __cplusplus
+ extern "C"
+# endif
+ int FC_DUMMY_MAIN() { return 1; }
+#endif
+#endif
+int
+main ()
+{
+std::cout << __FUNCTION__;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ ac_cv_cxx_macro_function=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_macro_func" >&5
+$as_echo "$ac_cv_cxx_macro_func" >&6; }
+
+ if test "x${ac_cv_cxx_macro_func}" == xyes ; then
+ $as_echo "#define HAVE_FUNC_MACRO 1" >>confdefs.h
+
+ fi
+ if test "x${ac_cv_cxx_macro_function}" == xyes ; then
+ $as_echo "#define HAVE_FUNCTION_MACRO 1" >>confdefs.h
+
+ fi
+fi
+
+if test "x${debug}" = xyes; then
+ if ! echo "${CFLAGS}" | ${EGREP} -q -- "-g" ; then
+ CFLAGS="${CFLAGS} -g"
+ fi
+ CFLAGS=`echo $CFLAGS | sed 's/-O. *//g' | sed 's/-fast *//g'`
+ CFLAGS="${CFLAGS} -O0"
+
+ if test "x${has_mpicxx}" = xyes ; then
+ if ! echo "${CXXFLAGS}" | ${EGREP} -q -- "-g" ; then
+ CXXFLAGS="${CXXFLAGS} -g"
+ fi
+ CXXFLAGS=`echo $CXXFLAGS | sed 's/-O. *//g' | sed 's/-fast *//g'`
+ CXXFLAGS="${CXXFLAGS} -O0"
+ fi
+
+ if test "x${enable_fortran}" = xyes ; then
+ if ! echo "${FCFLAGS}" | ${EGREP} -q -- "-g" ; then
+ FCFLAGS="${FCFLAGS} -g"
+ fi
+ if ! echo "${F77FLAGS}" | ${EGREP} -q -- "-g" ; then
+ F77FLAGS="${F77FLAGS} -g"
+ fi
+ if ! echo "${F90FLAGS}" | ${EGREP} -q -- "-g" ; then
+ F90FLAGS="${F90FLAGS} -g"
+ fi
+
+ FCFLAGS=`echo $FCFLAGS | sed 's/-O. *//g' | sed 's/-fast *//g'`
+ F77FLAGS=`echo $F77FLAGS | sed 's/-O. *//g' | sed 's/-fast *//g'`
+ F90FLAGS=`echo $F90FLAGS | sed 's/-O. *//g' | sed 's/-fast *//g'`
+ FCFLAGS="${FCFLAGS} -O0"
+ F77FLAGS="${F77FLAGS} -O0"
+ F90FLAGS="${F90FLAGS} -O0"
+ fi
+fi
+
+chmod u+x ${srcdir}/scripts/install-sh
+
+# Check whether --enable-subfiling was given.
+if test "${enable_subfiling+set}" = set; then :
+ enableval=$enable_subfiling; enable_subfiling=${enableval}
+else
+ enable_subfiling=no
+
+fi
+
+if test "x$enable_subfiling" = "xyes" ; then
+ $as_echo "#define ENABLE_SUBFILING 1" >>confdefs.h
+
+
+fi
+
+# Extract the first word of "latex", so it can be a program name with args.
+set dummy latex; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_LATEX+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $LATEX in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_LATEX="$LATEX" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_LATEX="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+LATEX=$ac_cv_path_LATEX
+if test -n "$LATEX"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LATEX" >&5
+$as_echo "$LATEX" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+# Extract the first word of "dvipdf", so it can be a program name with args.
+set dummy dvipdf; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_DVIPDF+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $DVIPDF in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_DVIPDF="$DVIPDF" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_DVIPDF="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+DVIPDF=$ac_cv_path_DVIPDF
+if test -n "$DVIPDF"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DVIPDF" >&5
+$as_echo "$DVIPDF" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+has_latex=no
+if test "x${LATEX}" != x ; then
+ has_latex=yes
+fi
+
+
+
+
+BUILDDIR=`pwd`
+
+
+# Check whether --enable-file-sync was given.
+if test "${enable_file_sync+set}" = set; then :
+ enableval=$enable_file_sync; file_sync=${enableval}
+else
+ file_sync=yes
+
+fi
+
+if test "x${file_sync}" = xno ; then
+ $as_echo "#define DISABLE_FILE_SYNC 1" >>confdefs.h
+
+fi
+
+# Check whether --enable-large-file-test was given.
+if test "${enable_large_file_test+set}" = set; then :
+ enableval=$enable_large_file_test; large_file_test=${enableval}
+else
+ large_file_test=no
+
+fi
+
+
+
+PNETCDF_INC=${BUILDDIR}/src/libf90
+PNETCDF_LIB="-L${BUILDDIR}/src/lib"
+
+
+
+
+
+
+if test "x${TEST_MPIRUN}" = x ; then
+ TEST_MPIRUN="mpiexec -n NP"
+fi
+if test "x${TEST_OUTDIR}" = x ; then
+ TEST_OUTDIR=.
+fi
+
+
+
+
+# Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_SEQ_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $SEQ_CC in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_SEQ_CC="$SEQ_CC" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_path_SEQ_CC="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ test -z "$ac_cv_path_SEQ_CC" && ac_cv_path_SEQ_CC="$MPICC"
+ ;;
+esac
+fi
+SEQ_CC=$ac_cv_path_SEQ_CC
+if test -n "$SEQ_CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $SEQ_CC" >&5
+$as_echo "$SEQ_CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+
+
+ac_config_headers="$ac_config_headers src/libf/nfconfig_inc"
+
+ac_config_files="$ac_config_files macros.make Makefile src/Makefile src/lib/Makefile src/lib/pnetcdf.h src/utils/Makefile src/utils/ncmpidump/Makefile src/utils/ncmpidiff/Makefile src/utils/ncmpigen/Makefile src/utils/ncmpivalid/Makefile src/utils/pnetcdf_version/Makefile src/utils/ncoffsets/Makefile test/Makefile test/common/Makefile test/nc_test/Makefile test/C/Makefile test/fandc/Makefile test/testcases/Makefile test/nonblocking/Makefile test/header/Makefile test/cdf_format/Makefile t [...]
+
+
+# The following dependency is for configure.in and configure
+# See autoconf manual 2.69, Section 4.8.5 Automatic Remaking
+ac_config_files="$ac_config_files stamp-h"
+
+
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems. If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, we kill variables containing newlines.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(
+ for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do
+ eval ac_val=\$$ac_var
+ case $ac_val in #(
+ *${as_nl}*)
+ case $ac_var in #(
+ *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+ esac
+ case $ac_var in #(
+ _ | IFS | as_nl) ;; #(
+ BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+ *) { eval $ac_var=; unset $ac_var;} ;;
+ esac ;;
+ esac
+ done
+
+ (set) 2>&1 |
+ case $as_nl`(ac_space=' '; set) 2>&1` in #(
+ *${as_nl}ac_space=\ *)
+ # `set' does not quote correctly, so add quotes: double-quote
+ # substitution turns \\\\ into \\, and sed turns \\ into \.
+ sed -n \
+ "s/'/'\\\\''/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+ ;; #(
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+ ;;
+ esac |
+ sort
+) |
+ sed '
+ /^ac_cv_env_/b end
+ t clear
+ :clear
+ s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+ t end
+ s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+ :end' >>confcache
+if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
+ if test -w "$cache_file"; then
+ if test "x$cache_file" != "x/dev/null"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
+$as_echo "$as_me: updating cache $cache_file" >&6;}
+ if test ! -f "$cache_file" || test -h "$cache_file"; then
+ cat confcache >"$cache_file"
+ else
+ case $cache_file in #(
+ */* | ?:*)
+ mv -f confcache "$cache_file"$$ &&
+ mv -f "$cache_file"$$ "$cache_file" ;; #(
+ *)
+ mv -f confcache "$cache_file" ;;
+ esac
+ fi
+ fi
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5
+$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;}
+ fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+DEFS=-DHAVE_CONFIG_H
+
+ac_libobjs=
+ac_ltlibobjs=
+U=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+ # 1. Remove the extension, and $U if already installed.
+ ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
+ ac_i=`$as_echo "$ac_i" | sed "$ac_script"`
+ # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR
+ # will be set to the directory where LIBOBJS objects are built.
+ as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext"
+ as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+
+case $FC_MODINC in #(
+ *\ ) FC_MODINC=$FC_MODINC'${ac_empty}' ;;
+esac
+case $FC_MODOUT in #(
+ *\ ) FC_MODOUT=$FC_MODOUT'${ac_empty}' ;;
+esac
+
+: "${CONFIG_STATUS=./config.status}"
+ac_write_fail=0
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5
+$as_echo "$as_me: creating $CONFIG_STATUS" >&6;}
+as_write_fail=0
+cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+
+SHELL=\${CONFIG_SHELL-$SHELL}
+export SHELL
+_ASEOF
+cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in #(
+ *posix*) :
+ set -o posix ;; #(
+ *) :
+ ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='print -r --'
+ as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='printf %s\n'
+ as_echo_n='printf %s'
+else
+ if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+ as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+ as_echo_n='/usr/ucb/echo -n'
+ else
+ as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+ as_echo_n_body='eval
+ arg=$1;
+ case $arg in #(
+ *"$as_nl"*)
+ expr "X$arg" : "X\\(.*\\)$as_nl";
+ arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+ esac;
+ expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+ '
+ export as_echo_n_body
+ as_echo_n='sh -c $as_echo_n_body as_echo'
+ fi
+ export as_echo_body
+ as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ PATH_SEPARATOR=:
+ (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+ (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+ PATH_SEPARATOR=';'
+ }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order. Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" "" $as_nl"
+
+# Find who we are. Look in the path if we contain no directory separator.
+as_myself=
+case $0 in #((
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+ as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+ $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+ exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there. '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with STATUS, using 1 if that was 0.
+as_fn_error ()
+{
+ as_status=$1; test $as_status -eq 0 && as_status=1
+ if test "$4"; then
+ as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+ fi
+ $as_echo "$as_me: error: $2" >&2
+ as_fn_exit $as_status
+} # as_fn_error
+
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+ return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+ set +e
+ as_fn_set_status $1
+ exit $1
+} # as_fn_exit
+
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+ { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+ eval 'as_fn_append ()
+ {
+ eval $1+=\$2
+ }'
+else
+ as_fn_append ()
+ {
+ eval $1=\$$1\$2
+ }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+ eval 'as_fn_arith ()
+ {
+ as_val=$(( $* ))
+ }'
+else
+ as_fn_arith ()
+ {
+ as_val=`expr "$@" || test $? -eq 1`
+ }
+fi # as_fn_arith
+
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+ as_dirname=dirname
+else
+ as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+ case `echo 'xy\c'` in
+ *c*) ECHO_T=' ';; # ECHO_T is single tab character.
+ xy) ECHO_C='\c';;
+ *) echo `echo ksh88 bug on AIX 6.1` > /dev/null
+ ECHO_T=' ';;
+ esac;;
+*)
+ ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+ rm -f conf$$.dir/conf$$.file
+else
+ rm -f conf$$.dir
+ mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+ if ln -s conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s='ln -s'
+ # ... but there are two gotchas:
+ # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+ # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+ # In both cases, we have to default to `cp -pR'.
+ ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+ as_ln_s='cp -pR'
+ elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+ else
+ as_ln_s='cp -pR'
+ fi
+else
+ as_ln_s='cp -pR'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+ case $as_dir in #(
+ -*) as_dir=./$as_dir;;
+ esac
+ test -d "$as_dir" || eval $as_mkdir_p || {
+ as_dirs=
+ while :; do
+ case $as_dir in #(
+ *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+ *) as_qdir=$as_dir;;
+ esac
+ as_dirs="'$as_qdir' $as_dirs"
+ as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ test -d "$as_dir" && break
+ done
+ test -z "$as_dirs" || eval "mkdir $as_dirs"
+ } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p='mkdir -p "$as_dir"'
+else
+ test -d ./-p && rmdir ./-p
+ as_mkdir_p=false
+fi
+
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+ test -f "$1" && test -x "$1"
+} # as_fn_executable_p
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+exec 6>&1
+## ----------------------------------- ##
+## Main body of $CONFIG_STATUS script. ##
+## ----------------------------------- ##
+_ASEOF
+test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# Save the log message, to keep $0 and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling.
+ac_log="
+This file was extended by parallel-netcdf $as_me 1.7.0.pre1, which was
+generated by GNU Autoconf 2.69. Invocation command line was
+
+ CONFIG_FILES = $CONFIG_FILES
+ CONFIG_HEADERS = $CONFIG_HEADERS
+ CONFIG_LINKS = $CONFIG_LINKS
+ CONFIG_COMMANDS = $CONFIG_COMMANDS
+ $ $0 $@
+
+on `(hostname || uname -n) 2>/dev/null | sed 1q`
+"
+
+_ACEOF
+
+case $ac_config_files in *"
+"*) set x $ac_config_files; shift; ac_config_files=$*;;
+esac
+
+case $ac_config_headers in *"
+"*) set x $ac_config_headers; shift; ac_config_headers=$*;;
+esac
+
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+# Files that config.status was made for.
+config_files="$ac_config_files"
+config_headers="$ac_config_headers"
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+ac_cs_usage="\
+\`$as_me' instantiates files and other configuration actions
+from templates according to the current configuration. Unless the files
+and actions are specified as TAGs, all are instantiated by default.
+
+Usage: $0 [OPTION]... [TAG]...
+
+ -h, --help print this help, then exit
+ -V, --version print version number and configuration settings, then exit
+ --config print configuration, then exit
+ -q, --quiet, --silent
+ do not print progress messages
+ -d, --debug don't remove temporary files
+ --recheck update $as_me by reconfiguring in the same conditions
+ --file=FILE[:TEMPLATE]
+ instantiate the configuration file FILE
+ --header=FILE[:TEMPLATE]
+ instantiate the configuration header FILE
+
+Configuration files:
+$config_files
+
+Configuration headers:
+$config_headers
+
+Report bugs to <parallel-netcdf at mcs.anl.gov>."
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
+ac_cs_version="\\
+parallel-netcdf config.status 1.7.0.pre1
+configured by $0, generated by GNU Autoconf 2.69,
+ with options \\"\$ac_cs_config\\"
+
+Copyright (C) 2012 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+
+ac_pwd='$ac_pwd'
+srcdir='$srcdir'
+INSTALL='$INSTALL'
+test -n "\$AWK" || AWK=awk
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# The default lists apply if the user does not specify any file.
+ac_need_defaults=:
+while test $# != 0
+do
+ case $1 in
+ --*=?*)
+ ac_option=`expr "X$1" : 'X\([^=]*\)='`
+ ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
+ ac_shift=:
+ ;;
+ --*=)
+ ac_option=`expr "X$1" : 'X\([^=]*\)='`
+ ac_optarg=
+ ac_shift=:
+ ;;
+ *)
+ ac_option=$1
+ ac_optarg=$2
+ ac_shift=shift
+ ;;
+ esac
+
+ case $ac_option in
+ # Handling of the options.
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ ac_cs_recheck=: ;;
+ --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
+ $as_echo "$ac_cs_version"; exit ;;
+ --config | --confi | --conf | --con | --co | --c )
+ $as_echo "$ac_cs_config"; exit ;;
+ --debug | --debu | --deb | --de | --d | -d )
+ debug=: ;;
+ --file | --fil | --fi | --f )
+ $ac_shift
+ case $ac_optarg in
+ *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ '') as_fn_error $? "missing file argument" ;;
+ esac
+ as_fn_append CONFIG_FILES " '$ac_optarg'"
+ ac_need_defaults=false;;
+ --header | --heade | --head | --hea )
+ $ac_shift
+ case $ac_optarg in
+ *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ esac
+ as_fn_append CONFIG_HEADERS " '$ac_optarg'"
+ ac_need_defaults=false;;
+ --he | --h)
+ # Conflict between --help and --header
+ as_fn_error $? "ambiguous option: \`$1'
+Try \`$0 --help' for more information.";;
+ --help | --hel | -h )
+ $as_echo "$ac_cs_usage"; exit ;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil | --si | --s)
+ ac_cs_silent=: ;;
+
+ # This is an error.
+ -*) as_fn_error $? "unrecognized option: \`$1'
+Try \`$0 --help' for more information." ;;
+
+ *) as_fn_append ac_config_targets " $1"
+ ac_need_defaults=false ;;
+
+ esac
+ shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+ exec 6>/dev/null
+ ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+if \$ac_cs_recheck; then
+ set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+ shift
+ \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
+ CONFIG_SHELL='$SHELL'
+ export CONFIG_SHELL
+ exec "\$@"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+exec 5>>config.log
+{
+ echo
+ sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+ $as_echo "$ac_log"
+} >&5
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+
+# Handling of arguments.
+for ac_config_target in $ac_config_targets
+do
+ case $ac_config_target in
+ "src/lib/ncconfig.h") CONFIG_HEADERS="$CONFIG_HEADERS src/lib/ncconfig.h" ;;
+ "src/libf/nfconfig_inc") CONFIG_HEADERS="$CONFIG_HEADERS src/libf/nfconfig_inc" ;;
+ "macros.make") CONFIG_FILES="$CONFIG_FILES macros.make" ;;
+ "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+ "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;;
+ "src/lib/Makefile") CONFIG_FILES="$CONFIG_FILES src/lib/Makefile" ;;
+ "src/lib/pnetcdf.h") CONFIG_FILES="$CONFIG_FILES src/lib/pnetcdf.h" ;;
+ "src/utils/Makefile") CONFIG_FILES="$CONFIG_FILES src/utils/Makefile" ;;
+ "src/utils/ncmpidump/Makefile") CONFIG_FILES="$CONFIG_FILES src/utils/ncmpidump/Makefile" ;;
+ "src/utils/ncmpidiff/Makefile") CONFIG_FILES="$CONFIG_FILES src/utils/ncmpidiff/Makefile" ;;
+ "src/utils/ncmpigen/Makefile") CONFIG_FILES="$CONFIG_FILES src/utils/ncmpigen/Makefile" ;;
+ "src/utils/ncmpivalid/Makefile") CONFIG_FILES="$CONFIG_FILES src/utils/ncmpivalid/Makefile" ;;
+ "src/utils/pnetcdf_version/Makefile") CONFIG_FILES="$CONFIG_FILES src/utils/pnetcdf_version/Makefile" ;;
+ "src/utils/ncoffsets/Makefile") CONFIG_FILES="$CONFIG_FILES src/utils/ncoffsets/Makefile" ;;
+ "test/Makefile") CONFIG_FILES="$CONFIG_FILES test/Makefile" ;;
+ "test/common/Makefile") CONFIG_FILES="$CONFIG_FILES test/common/Makefile" ;;
+ "test/nc_test/Makefile") CONFIG_FILES="$CONFIG_FILES test/nc_test/Makefile" ;;
+ "test/C/Makefile") CONFIG_FILES="$CONFIG_FILES test/C/Makefile" ;;
+ "test/fandc/Makefile") CONFIG_FILES="$CONFIG_FILES test/fandc/Makefile" ;;
+ "test/testcases/Makefile") CONFIG_FILES="$CONFIG_FILES test/testcases/Makefile" ;;
+ "test/nonblocking/Makefile") CONFIG_FILES="$CONFIG_FILES test/nonblocking/Makefile" ;;
+ "test/header/Makefile") CONFIG_FILES="$CONFIG_FILES test/header/Makefile" ;;
+ "test/cdf_format/Makefile") CONFIG_FILES="$CONFIG_FILES test/cdf_format/Makefile" ;;
+ "test/largefile/Makefile") CONFIG_FILES="$CONFIG_FILES test/largefile/Makefile" ;;
+ "examples/C/Makefile") CONFIG_FILES="$CONFIG_FILES examples/C/Makefile" ;;
+ "examples/tutorial/Makefile") CONFIG_FILES="$CONFIG_FILES examples/tutorial/Makefile" ;;
+ "examples/Makefile") CONFIG_FILES="$CONFIG_FILES examples/Makefile" ;;
+ "doc/Makefile") CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;;
+ "man/Makefile") CONFIG_FILES="$CONFIG_FILES man/Makefile" ;;
+ "scripts/Makefile") CONFIG_FILES="$CONFIG_FILES scripts/Makefile" ;;
+ "benchmarks/Makefile") CONFIG_FILES="$CONFIG_FILES benchmarks/Makefile" ;;
+ "benchmarks/C/Makefile") CONFIG_FILES="$CONFIG_FILES benchmarks/C/Makefile" ;;
+ "test/nf_test/Makefile") CONFIG_FILES="$CONFIG_FILES test/nf_test/Makefile" ;;
+ "test/nf_test/tests.inc") CONFIG_FILES="$CONFIG_FILES test/nf_test/tests.inc" ;;
+ "test/nf90_test/Makefile") CONFIG_FILES="$CONFIG_FILES test/nf90_test/Makefile" ;;
+ "test/F90/Makefile") CONFIG_FILES="$CONFIG_FILES test/F90/Makefile" ;;
+ "examples/F77/Makefile") CONFIG_FILES="$CONFIG_FILES examples/F77/Makefile" ;;
+ "examples/F90/Makefile") CONFIG_FILES="$CONFIG_FILES examples/F90/Makefile" ;;
+ "src/libf90/Makefile") CONFIG_FILES="$CONFIG_FILES src/libf90/Makefile" ;;
+ "src/libf90/api.f90") CONFIG_FILES="$CONFIG_FILES src/libf90/api.f90" ;;
+ "src/libf90/nfmpi_constants.f90") CONFIG_FILES="$CONFIG_FILES src/libf90/nfmpi_constants.f90" ;;
+ "src/libf/Makefile") CONFIG_FILES="$CONFIG_FILES src/libf/Makefile" ;;
+ "src/libf/pnetcdf.inc") CONFIG_FILES="$CONFIG_FILES src/libf/pnetcdf.inc" ;;
+ "src/libcxx/Makefile") CONFIG_FILES="$CONFIG_FILES src/libcxx/Makefile" ;;
+ "examples/CXX/Makefile") CONFIG_FILES="$CONFIG_FILES examples/CXX/Makefile" ;;
+ "test/CXX/Makefile") CONFIG_FILES="$CONFIG_FILES test/CXX/Makefile" ;;
+ "benchmarks/FLASH-IO/Makefile") CONFIG_FILES="$CONFIG_FILES benchmarks/FLASH-IO/Makefile" ;;
+ "test/subfile/Makefile") CONFIG_FILES="$CONFIG_FILES test/subfile/Makefile" ;;
+ "stamp-h") CONFIG_FILES="$CONFIG_FILES stamp-h" ;;
+
+ *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
+ esac
+done
+
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used. Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+ test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+ test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers
+fi
+
+# Have a temporary directory for convenience. Make it in the build tree
+# simply because there is no reason against having it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Hook for its removal unless debugging.
+# Note that there is a small window in which the directory will not be cleaned:
+# after its creation but before its name has been assigned to `$tmp'.
+$debug ||
+{
+ tmp= ac_tmp=
+ trap 'exit_status=$?
+ : "${ac_tmp:=$tmp}"
+ { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status
+' 0
+ trap 'as_fn_exit 1' 1 2 13 15
+}
+# Create a (secure) tmp directory for tmp files.
+
+{
+ tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
+ test -d "$tmp"
+} ||
+{
+ tmp=./conf$$-$RANDOM
+ (umask 077 && mkdir "$tmp")
+} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5
+ac_tmp=$tmp
+
+# Set up the scripts for CONFIG_FILES section.
+# No need to generate them if there are no CONFIG_FILES.
+# This happens for instance with `./config.status config.h'.
+if test -n "$CONFIG_FILES"; then
+
+
+ac_cr=`echo X | tr X '\015'`
+# On cygwin, bash can eat \r inside `` if the user requested igncr.
+# But we know of no other shell where ac_cr would be empty at this
+# point, so we can use a bashism as a fallback.
+if test "x$ac_cr" = x; then
+ eval ac_cr=\$\'\\r\'
+fi
+ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null`
+if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then
+ ac_cs_awk_cr='\\r'
+else
+ ac_cs_awk_cr=$ac_cr
+fi
+
+echo 'BEGIN {' >"$ac_tmp/subs1.awk" &&
+_ACEOF
+
+
+{
+ echo "cat >conf$$subs.awk <<_ACEOF" &&
+ echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' &&
+ echo "_ACEOF"
+} >conf$$subs.sh ||
+ as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'`
+ac_delim='%!_!# '
+for ac_last_try in false false false false false :; do
+ . ./conf$$subs.sh ||
+ as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+
+ ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X`
+ if test $ac_delim_n = $ac_delim_num; then
+ break
+ elif $ac_last_try; then
+ as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+ else
+ ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+ fi
+done
+rm -f conf$$subs.sh
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK &&
+_ACEOF
+sed -n '
+h
+s/^/S["/; s/!.*/"]=/
+p
+g
+s/^[^!]*!//
+:repl
+t repl
+s/'"$ac_delim"'$//
+t delim
+:nl
+h
+s/\(.\{148\}\)..*/\1/
+t more1
+s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/
+p
+n
+b repl
+:more1
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t nl
+:delim
+h
+s/\(.\{148\}\)..*/\1/
+t more2
+s/["\\]/\\&/g; s/^/"/; s/$/"/
+p
+b
+:more2
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t delim
+' <conf$$subs.awk | sed '
+/^[^""]/{
+ N
+ s/\n//
+}
+' >>$CONFIG_STATUS || ac_write_fail=1
+rm -f conf$$subs.awk
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+_ACAWK
+cat >>"\$ac_tmp/subs1.awk" <<_ACAWK &&
+ for (key in S) S_is_set[key] = 1
+ FS = ""
+
+}
+{
+ line = $ 0
+ nfields = split(line, field, "@")
+ substed = 0
+ len = length(field[1])
+ for (i = 2; i < nfields; i++) {
+ key = field[i]
+ keylen = length(key)
+ if (S_is_set[key]) {
+ value = S[key]
+ line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3)
+ len += length(value) + length(field[++i])
+ substed = 1
+ } else
+ len += 1 + keylen
+ }
+
+ print line
+}
+
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then
+ sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g"
+else
+ cat
+fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \
+ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5
+_ACEOF
+
+# VPATH may cause trouble with some makes, so we remove sole $(srcdir),
+# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{
+h
+s///
+s/^/:/
+s/[ ]*$/:/
+s/:\$(srcdir):/:/g
+s/:\${srcdir}:/:/g
+s/:@srcdir@:/:/g
+s/^:*//
+s/:*$//
+x
+s/\(=[ ]*\).*/\1/
+G
+s/\n//
+s/^[^=]*=[ ]*$//
+}'
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+fi # test -n "$CONFIG_FILES"
+
+# Set up the scripts for CONFIG_HEADERS section.
+# No need to generate them if there are no CONFIG_HEADERS.
+# This happens for instance with `./config.status Makefile'.
+if test -n "$CONFIG_HEADERS"; then
+cat >"$ac_tmp/defines.awk" <<\_ACAWK ||
+BEGIN {
+_ACEOF
+
+# Transform confdefs.h into an awk script `defines.awk', embedded as
+# here-document in config.status, that substitutes the proper values into
+# config.h.in to produce config.h.
+
+# Create a delimiter string that does not exist in confdefs.h, to ease
+# handling of long lines.
+ac_delim='%!_!# '
+for ac_last_try in false false :; do
+ ac_tt=`sed -n "/$ac_delim/p" confdefs.h`
+ if test -z "$ac_tt"; then
+ break
+ elif $ac_last_try; then
+ as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5
+ else
+ ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+ fi
+done
+
+# For the awk script, D is an array of macro values keyed by name,
+# likewise P contains macro parameters if any. Preserve backslash
+# newline sequences.
+
+ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]*
+sed -n '
+s/.\{148\}/&'"$ac_delim"'/g
+t rset
+:rset
+s/^[ ]*#[ ]*define[ ][ ]*/ /
+t def
+d
+:def
+s/\\$//
+t bsnl
+s/["\\]/\\&/g
+s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\
+D["\1"]=" \3"/p
+s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p
+d
+:bsnl
+s/["\\]/\\&/g
+s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\
+D["\1"]=" \3\\\\\\n"\\/p
+t cont
+s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p
+t cont
+d
+:cont
+n
+s/.\{148\}/&'"$ac_delim"'/g
+t clear
+:clear
+s/\\$//
+t bsnlc
+s/["\\]/\\&/g; s/^/"/; s/$/"/p
+d
+:bsnlc
+s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p
+b cont
+' <confdefs.h | sed '
+s/'"$ac_delim"'/"\\\
+"/g' >>$CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ for (key in D) D_is_set[key] = 1
+ FS = ""
+}
+/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ {
+ line = \$ 0
+ split(line, arg, " ")
+ if (arg[1] == "#") {
+ defundef = arg[2]
+ mac1 = arg[3]
+ } else {
+ defundef = substr(arg[1], 2)
+ mac1 = arg[2]
+ }
+ split(mac1, mac2, "(") #)
+ macro = mac2[1]
+ prefix = substr(line, 1, index(line, defundef) - 1)
+ if (D_is_set[macro]) {
+ # Preserve the white space surrounding the "#".
+ print prefix "define", macro P[macro] D[macro]
+ next
+ } else {
+ # Replace #undef with comments. This is necessary, for example,
+ # in the case of _POSIX_SOURCE, which is predefined and required
+ # on some systems where configure will not decide to define it.
+ if (defundef == "undef") {
+ print "/*", prefix defundef, macro, "*/"
+ next
+ }
+ }
+}
+{ print }
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+ as_fn_error $? "could not setup config headers machinery" "$LINENO" 5
+fi # test -n "$CONFIG_HEADERS"
+
+
+eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS "
+shift
+for ac_tag
+do
+ case $ac_tag in
+ :[FHLC]) ac_mode=$ac_tag; continue;;
+ esac
+ case $ac_mode$ac_tag in
+ :[FHL]*:*);;
+ :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;;
+ :[FH]-) ac_tag=-:-;;
+ :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
+ esac
+ ac_save_IFS=$IFS
+ IFS=:
+ set x $ac_tag
+ IFS=$ac_save_IFS
+ shift
+ ac_file=$1
+ shift
+
+ case $ac_mode in
+ :L) ac_source=$1;;
+ :[FH])
+ ac_file_inputs=
+ for ac_f
+ do
+ case $ac_f in
+ -) ac_f="$ac_tmp/stdin";;
+ *) # Look for the file first in the build tree, then in the source tree
+ # (if the path is not absolute). The absolute path cannot be DOS-style,
+ # because $ac_f cannot contain `:'.
+ test -f "$ac_f" ||
+ case $ac_f in
+ [\\/$]*) false;;
+ *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
+ esac ||
+ as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;;
+ esac
+ case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
+ as_fn_append ac_file_inputs " '$ac_f'"
+ done
+
+ # Let's still pretend it is `configure' which instantiates (i.e., don't
+ # use $as_me), people would be surprised to read:
+ # /* config.h. Generated by config.status. */
+ configure_input='Generated from '`
+ $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
+ `' by configure.'
+ if test x"$ac_file" != x-; then
+ configure_input="$ac_file. $configure_input"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5
+$as_echo "$as_me: creating $ac_file" >&6;}
+ fi
+ # Neutralize special characters interpreted by sed in replacement strings.
+ case $configure_input in #(
+ *\&* | *\|* | *\\* )
+ ac_sed_conf_input=`$as_echo "$configure_input" |
+ sed 's/[\\\\&|]/\\\\&/g'`;; #(
+ *) ac_sed_conf_input=$configure_input;;
+ esac
+
+ case $ac_tag in
+ *:-:* | *:-) cat >"$ac_tmp/stdin" \
+ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;;
+ esac
+ ;;
+ esac
+
+ ac_dir=`$as_dirname -- "$ac_file" ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$ac_file" : 'X\(//\)[^/]' \| \
+ X"$ac_file" : 'X\(//\)$' \| \
+ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$ac_file" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ as_dir="$ac_dir"; as_fn_mkdir_p
+ ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+ ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+ # A ".." for each directory in $ac_dir_suffix.
+ ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+ case $ac_top_builddir_sub in
+ "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+ *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+ esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+ .) # We are building in place.
+ ac_srcdir=.
+ ac_top_srcdir=$ac_top_builddir_sub
+ ac_abs_top_srcdir=$ac_pwd ;;
+ [\\/]* | ?:[\\/]* ) # Absolute name.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir
+ ac_abs_top_srcdir=$srcdir ;;
+ *) # Relative name.
+ ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_build_prefix$srcdir
+ ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+
+ case $ac_mode in
+ :F)
+ #
+ # CONFIG_FILE
+ #
+
+ case $INSTALL in
+ [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
+ *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;;
+ esac
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# If the template does not know about datarootdir, expand it.
+# FIXME: This hack should be removed a few years after 2.60.
+ac_datarootdir_hack=; ac_datarootdir_seen=
+ac_sed_dataroot='
+/datarootdir/ {
+ p
+ q
+}
+/@datadir@/p
+/@docdir@/p
+/@infodir@/p
+/@localedir@/p
+/@mandir@/p'
+case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in
+*datarootdir*) ac_datarootdir_seen=yes;;
+*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
+$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ ac_datarootdir_hack='
+ s&@datadir@&$datadir&g
+ s&@docdir@&$docdir&g
+ s&@infodir@&$infodir&g
+ s&@localedir@&$localedir&g
+ s&@mandir@&$mandir&g
+ s&\\\${datarootdir}&$datarootdir&g' ;;
+esac
+_ACEOF
+
+# Neutralize VPATH when `$srcdir' = `.'.
+# Shell code in configure.ac might set extrasub.
+# FIXME: do we really want to maintain this feature?
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_sed_extra="$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s|@configure_input@|$ac_sed_conf_input|;t t
+s&@top_builddir@&$ac_top_builddir_sub&;t t
+s&@top_build_prefix@&$ac_top_build_prefix&;t t
+s&@srcdir@&$ac_srcdir&;t t
+s&@abs_srcdir@&$ac_abs_srcdir&;t t
+s&@top_srcdir@&$ac_top_srcdir&;t t
+s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t
+s&@builddir@&$ac_builddir&;t t
+s&@abs_builddir@&$ac_abs_builddir&;t t
+s&@abs_top_builddir@&$ac_abs_top_builddir&;t t
+s&@INSTALL@&$ac_INSTALL&;t t
+$ac_datarootdir_hack
+"
+eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \
+ >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+
+test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
+ { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } &&
+ { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \
+ "$ac_tmp/out"`; test -z "$ac_out"; } &&
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined. Please make sure it is defined" >&5
+$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined. Please make sure it is defined" >&2;}
+
+ rm -f "$ac_tmp/stdin"
+ case $ac_file in
+ -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";;
+ *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";;
+ esac \
+ || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+ ;;
+ :H)
+ #
+ # CONFIG_HEADER
+ #
+ if test x"$ac_file" != x-; then
+ {
+ $as_echo "/* $configure_input */" \
+ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs"
+ } >"$ac_tmp/config.h" \
+ || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+ if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5
+$as_echo "$as_me: $ac_file is unchanged" >&6;}
+ else
+ rm -f "$ac_file"
+ mv "$ac_tmp/config.h" "$ac_file" \
+ || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+ fi
+ else
+ $as_echo "/* $configure_input */" \
+ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \
+ || as_fn_error $? "could not create -" "$LINENO" 5
+ fi
+ ;;
+
+
+ esac
+
+
+ case $ac_file$ac_mode in
+ "stamp-h":F) echo timestamp > stamp-h ;;
+
+ esac
+done # for ac_tag
+
+
+as_fn_exit 0
+_ACEOF
+ac_clean_files=$ac_clean_files_save
+
+test $ac_write_fail = 0 ||
+ as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded. So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status. When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+ ac_cs_success=:
+ ac_config_status_args=
+ test "$silent" = yes &&
+ ac_config_status_args="$ac_config_status_args --quiet"
+ exec 5>/dev/null
+ $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+ exec 5>>config.log
+ # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+ # would make configure fail if this is the last instruction.
+ $ac_cs_success || as_fn_exit 1
+fi
+if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
+$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
+fi
+
+echo "--------------------------------------------------------------------"
+
+if test "x${enable_mpi_io_test}" = xno ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING:
+ NOTE: disabling the MPI-IO test is a VERY bad idea.
+ Please make sure you know what you are doing" >&5
+$as_echo "$as_me: WARNING:
+ NOTE: disabling the MPI-IO test is a VERY bad idea.
+ Please make sure you know what you are doing" >&2;}
+fi
+
+msg_large_files=no
+if test "$ac_cv_sizeof_off_t" -gt 4 ; then
+ msg_large_files=yes
+fi
+
+echo \
+"
+ ${PACKAGE_NAME} Version ${PACKAGE_VERSION}
+
+ Features: Support for large files (> 4 GB) - ${msg_large_files}
+ Build C++ APIs - ${has_mpicxx}
+ Build Fortran APIs - ${enable_fortran}
+ Build nonblocking APIs - ${enable_nonblocking}
+ Build CDF-5 support - ${enable_cdf5}
+ Build subfiling support - ${enable_subfiling}"
+if test "x${ac_cv_c_bigendian}" = xno && (test "x${in_place_swap}" = xno) ; then
+ echo "\
+ Memory in-place byte swap - disabled"
+fi
+if test "x${large_file_test}" = xyes; then
+ echo "\
+ Testing large file/variable I/O - enabled"
+fi
+if test "x${debug}" = xyes; then
+ echo "\
+ PnetCDF internal debug mode - enabled"
+fi
+if test "x${enable_fortran}" = xyes && (test "x${F77_SUPPORT_FREEFORM}" = xno) ; then
+ echo "\
+ Support free form in Fortran 77 - no"
+fi
+
+echo "\
+
+ Compilers: MPICC = ${MPICC}"
+if test "${has_mpicxx}" = yes ; then
+ echo "\
+ MPICXX = ${MPICXX}"
+fi
+if test "${enable_fortran}" = yes ; then
+ echo "\
+ MPIF77 = ${MPIF77}
+ MPIF90 = ${MPIF90}"
+fi
+echo "\
+ CFLAGS = ${CFLAGS}"
+if test "x${CPPFLAGS}" != x ; then
+ echo "\
+ CPPFLAGS = ${CPPFLAGS}"
+fi
+if test "${has_mpicxx}" = yes ; then
+ echo "\
+ CXXFLAGS = ${CXXFLAGS}"
+ if test "x${CXXCPPFLAGS}" != x ; then
+ echo "\
+ CXXCPPFLAGS = ${CXXCPPFLAGS}"
+ fi
+fi
+if test "${enable_fortran}" = yes ; then
+ echo "\
+ F77FLAGS = ${F77FLAGS}
+ F90FLAGS = ${F90FLAGS}"
+ if test "x${FPPFLAGS}" != x ; then
+ echo "\
+ FPPFLAGS = ${FPPFLAGS}"
+ fi
+fi
+if test "x${LDFLAGS}" != x ; then
+ echo "\
+ LDFLAGS = ${LDFLAGS}"
+fi
+if test "x${LIBS}" != x ; then
+ echo "\
+ LIBS = ${LIBS}"
+fi
+echo "\
+
+ Now type 'make' to build the library and utility tools.
+ Type 'make [<target>]'
+ where the optional <target> is:
+ testing - test PnetCDF build for sequential run
+ ptest - test PnetCDF build for parallel run
+ install - install PnetCDF
+---------------------------------------------------------------------"
+
diff --git a/configure.in b/configure.in
new file mode 100644
index 0000000..3a5dff8
--- /dev/null
+++ b/configure.in
@@ -0,0 +1,1269 @@
+AC_REVISION($Id: configure.in 2304 2016-01-12 18:39:01Z wkliao $)dnl
+dnl -*- Mode: shell-script-mode; -*-
+dnl Process this file with GNU autoconf(1) to produce a configure script.
+dnl
+
+AC_PREREQ([2.59])
+AC_INIT([parallel-netcdf],[1.7.0.pre1],[parallel-netcdf at mcs.anl.gov])
+
+dnl ncconfig.h.in will be created by autoreconf (autoheader)
+AC_CONFIG_HEADERS([src/lib/ncconfig.h])
+AC_CONFIG_SRCDIR([src/lib/pnetcdf.h.in])
+
+AC_CONFIG_AUX_DIR([./scripts])
+
+CONFIGURE_ARGS_CLEAN=`echo $* | tr '"' ' '`
+
+dnl parse the version numbers to 4 env variables
+PNETCDF_VERSION_MAJOR=`echo ${PACKAGE_VERSION} | cut -d. -f1`
+PNETCDF_VERSION_MINOR=`echo ${PACKAGE_VERSION} | cut -d. -f2`
+PNETCDF_VERSION_SUB=`echo ${PACKAGE_VERSION} | cut -d. -f3`
+PNETCDF_VERSION_PRE=`echo ${PACKAGE_VERSION} | cut -d. -f4`
+
+dnl Note major, minor, and sub are required, but pre is not.
+PNETCDF_VERSION=${PACKAGE_VERSION}
+
+dnl Do not change the following line, It is set by SVN automatically.
+dnl It defines PNETCDF_RELEASE_DATE, a string that will be used in
+dnl ncmpi_inq_libvers() to generate release date
+SVN_DATE="$LastChangedDate: 2016-01-12 12:39:01 -0600 (Tue, 12 Jan 2016) $"
+PNETCDF_RELEASE_DATE2=`echo $SVN_DATE | cut -d' ' -f2`
+PNETCDF_RELEASE_DATE=`echo $SVN_DATE | cut -d' ' -f6,7,8 | cut -d')' -f1`
+
+dnl user defined macro for printing messages for debugging
+_DEBUG=no
+AC_DEFUN([UD_MSG_DEBUG],
+ [if test "x${_DEBUG}" = xyes ; then
+ AC_MSG_NOTICE([DEBUG: $1])
+ fi
+ ]
+)
+
+UD_MSG_DEBUG([PNETCDF_VERSION_MAJOR=$PNETCDF_VERSION_MAJOR])
+UD_MSG_DEBUG([PNETCDF_VERSION_MINOR=$PNETCDF_VERSION_MINOR])
+UD_MSG_DEBUG([PNETCDF_VERSION_SUB=$PNETCDF_VERSION_SUB])
+UD_MSG_DEBUG([PNETCDF_VERSION_PRE=$PNETCDF_VERSION_PRE])
+UD_MSG_DEBUG([PNETCDF_VERSION=$PNETCDF_VERSION])
+UD_MSG_DEBUG([PNETCDF_RELEASE_DATE=$PNETCDF_RELEASE_DATE])
+
+AC_DEFINE_UNQUOTED(PNETCDF_VERSION_MAJOR, $PNETCDF_VERSION_MAJOR, major version number)
+AC_DEFINE_UNQUOTED(PNETCDF_VERSION_MINOR, $PNETCDF_VERSION_MINOR, minor version number)
+AC_DEFINE_UNQUOTED(PNETCDF_VERSION_SUB, $PNETCDF_VERSION_SUB, sub version number)
+AC_DEFINE_UNQUOTED(PNETCDF_VERSION_PRE, $PNETCDF_VERSION_PRE, pre-release string)
+AC_DEFINE_UNQUOTED(PNETCDF_VERSION, ["$PNETCDF_VERSION"], full PnetCDF version string)
+AC_DEFINE_UNQUOTED(PNETCDF_RELEASE_DATE, ["$PNETCDF_RELEASE_DATE"], PnetCDF release date string)
+AC_DEFINE_UNQUOTED(CONFIGURE_ARGS_CLEAN, ["$CONFIGURE_ARGS_CLEAN"], configure command-line arguments used)
+
+AC_SUBST(PNETCDF_VERSION_MAJOR)
+AC_SUBST(PNETCDF_VERSION_MINOR)
+AC_SUBST(PNETCDF_VERSION_SUB)
+AC_SUBST(PNETCDF_VERSION_PRE)
+AC_SUBST(PNETCDF_VERSION)
+AC_SUBST(PNETCDF_RELEASE_DATE)
+AC_SUBST(PNETCDF_RELEASE_DATE2)
+AC_SUBST(PACKAGE_VERSION)
+AC_SUBST(CONFIGURE_ARGS_CLEAN)
+
+dnl these used to live in acconfig.h
+dnl autoheader only adds these templates to the first invocation of AC_CONFIG_HEADERS
+AH_TEMPLATE([NCBYTE_T], [Type of NC_BYTE])
+AH_TEMPLATE([NCSHORT_T], [Type of NC_SHORT])
+AH_TEMPLATE([NF_DOUBLEPRECISION_IS_C_], [C type for Fortran double])
+AH_TEMPLATE([NF_INT1_IS_C_], [C type for Fortran INT1])
+AH_TEMPLATE([NF_INT1_T], [Type for Fortran INT1])
+AH_TEMPLATE([NF_INT2_IS_C_], [C type for Fortran INT2])
+AH_TEMPLATE([NF_INT2_T], [Type for Fortran INT2])
+AH_TEMPLATE([NF_INT_IS_C_], [C type for Fortran INT])
+AH_TEMPLATE([NF_INT8_IS_C_], [C type for Fortran INT8])
+AH_TEMPLATE([NF_INT8_T], [Type for Fortran INT8])
+AH_TEMPLATE([NF_REAL_IS_C_], [C type for Fortran REAL])
+AH_TEMPLATE([NO_IEEE_FLOAT], [Does system have IEEE FLOAT])
+AH_TEMPLATE([DISABLE_FILE_SYNC], [Define if to disable MPI_File_sync])
+AH_TEMPLATE([DISABLE_IN_PLACE_SWAP], [Define if to disable in-place byte swap])
+AH_TEMPLATE([ENABLE_SUBFILING], [Define if to enable subfiling feature])
+AH_TEMPLATE([PNC_DEBUG], [Define if to enable debugging])
+AH_TEMPLATE([PNC_MALLOC_TRACE], [Define if to enable malloc tracing])
+AH_TEMPLATE([HAVE_FUNC_MACRO], [Define if C++ macro __func__ is defined])
+AH_TEMPLATE([HAVE_FUNCTION_MACRO], [Define if C++ macro __FUNCTION__ is defined])
+
+dnl an option to use a customized rm command
+AC_ARG_VAR(RM, Command for deleting files or directories. default: rm)
+if test "x${RM}" != x ; then
+ AC_MSG_CHECKING(rm )
+ if ! test -f ${RM} ; then
+ AC_CHECK_PROG([rm_cmd], [${RM}], [yes], [no])
+ if test "x${rm_cmd}" = xyes ; then
+ RM=${RM}
+ fi
+ else
+ RM=${RM}
+ fi
+ AC_MSG_RESULT(using $RM)
+else
+ RM="rm"
+fi
+AC_SUBST(RM)
+
+AC_ARG_ENABLE(echo,
+ [AS_HELP_STRING([--enable-echo],
+ [Turn on strong echoing. @<:@default: disabled@:>@])],
+ [set -x]
+)
+
+MPI_INSTALL=
+AC_ARG_WITH(mpi,
+ [AS_HELP_STRING([--with-mpi=/path/to/implementation],
+ [installation prefix for MPI implementation])],
+ if test x"$withval" = xyes; then
+ AC_MSG_ERROR(--with-mpi must be given a pathname)
+ else
+ MPI_INSTALL=${withval}
+ fi
+)
+if test "x${MPI_INSTALL}" != x && (! test -d "${MPI_INSTALL}") ; then
+ AC_MSG_ERROR(Directory '${MPI_INSTALL}' specified in --with-mpi does not exist)
+fi
+
+AC_ARG_VAR(MPICC, MPI C compiler)
+AC_ARG_VAR(MPICXX, MPI C++ compiler)
+AC_ARG_VAR(MPIF77, MPI Fortran 77 compiler)
+AC_ARG_VAR(MPIF90, MPI Fortran 90 compiler)
+AC_ARG_VAR(CC, Overwritten by MPICC if MPICC is set)
+AC_ARG_VAR(CXX, Overwritten by MPICXX if MPICXX is set)
+AC_ARG_VAR(F77, Overwritten by MPIF77 if MPIF77 is set)
+AC_ARG_VAR(FC, Overwritten by MPIF90 if MPIF90 is set)
+AC_ARG_VAR(CFLAGS, Debugging and optimization options for the C compiler)
+AC_ARG_VAR(CPPFLAGS, [Preprocessor options for the C and C++ compilers, e.g. -I<include dir> if you have headers in a nonstandard directory <include dir>])
+AC_ARG_VAR(CXXFLAGS, Debugging and optimization options for the C compiler)
+AC_ARG_VAR(FFLAGS, Debugging and optimization options for the Fortran 77 compiler)
+AC_ARG_VAR(FCFLAGS, Debugging and optimization options for the Fortran 90 compiler)
+
+dnl Check if MPICC, MPICXX, MPIF77, MPIF90 are set by the user.
+dnl If not, set MPICC equal to CC. Similarly, for MPICXX, MPIF77, and MPIF90
+if test "x$MPICC" = x && test "x$CC" != x ; then MPICC=$CC ; fi
+if test "x$MPICXX" = x && test "x$CXX" != x ; then MPICXX=$CXX ; fi
+if test "x$MPIF77" = x && test "x$F77" != x ; then MPIF77=$F77 ; fi
+if test "x$MPIF77" = x && test "x$FC" != x ; then MPIF77=$FC ; fi
+if test "x$MPIF90" = x && test "x$F90" != x ; then MPIF90=$F90 ; fi
+if test "x$MPIF90" = x && test "x$FC" != x ; then MPIF90=$FC ; fi
+
+CANDIDATE_MPICC="${MPICC} mpicc"
+CANDIDATE_MPICXX="${MPICXX} mpicxx mpic++ mpiCC"
+CANDIDATE_MPIF77="${MPIF77} mpif77"
+CANDIDATE_MPIF90="${MPIF90} mpif90"
+
+dnl add IBM MPI compilers
+CANDIDATE_MPICC="${CANDIDATE_MPICC} mpcc_r mpcc mpixlc_r mpixlc"
+CANDIDATE_MPICXX="${CANDIDATE_MPICXX} mpCC_r mpCC mpixlcxx_r mpixlcxx mpixlC_r mpixlC"
+CANDIDATE_MPIF77="${CANDIDATE_MPIF77} mpixlf77_r mpixlf77"
+CANDIDATE_MPIF90="${CANDIDATE_MPIF90} mpixlf90_r mpixlf90"
+
+dnl add IBM BGL MPI compilers
+CANDIDATE_MPICC="${CANDIDATE_MPICC} blrts_xlc mpxlc_r mpxlc"
+CANDIDATE_MPICXX="${CANDIDATE_MPICXX} blrts_xlC mpxlC_r mpxlC"
+CANDIDATE_MPIF77="${CANDIDATE_MPIF77} blrts_xlf mpxlf_r mpxlf"
+CANDIDATE_MPIF90="${CANDIDATE_MPIF90} blrts_xlf90 mpxlf90_r mpxlf90 mpxlf95_r mpxlf95"
+
+dnl add Fujitsu MPI compilers
+CANDIDATE_MPICC="${CANDIDATE_MPICC} mpifccpx"
+CANDIDATE_MPICXX="${CANDIDATE_MPICXX} mpiFCCpx"
+CANDIDATE_MPIF77="${CANDIDATE_MPIF77} mpifrtpx"
+CANDIDATE_MPIF90="${CANDIDATE_MPIF90} mpifrtpx"
+
+dnl add Cray MPI compiler wrappers
+CANDIDATE_MPICC="${CANDIDATE_MPICC} cc"
+CANDIDATE_MPICXX="${CANDIDATE_MPICXX} CC"
+CANDIDATE_MPIF77="${CANDIDATE_MPIF77} ftn"
+CANDIDATE_MPIF90="${CANDIDATE_MPIF90} ftn"
+
+dnl add Intel MPI compiler wrappers
+CANDIDATE_MPICC="${CANDIDATE_MPICC} mpiicc icc"
+CANDIDATE_MPICXX="${CANDIDATE_MPICXX} mpiicpc icpc"
+CANDIDATE_MPIF77="${CANDIDATE_MPIF77} mpiifort mpiifc ifort"
+CANDIDATE_MPIF90="${CANDIDATE_MPIF90} mpiifort mpiifc ifort"
+
+UD_CHECK_MPI_COMPILER([MPICC], [$CANDIDATE_MPICC])
+if test "x${MPICC}" = x ; then
+ AC_MSG_ERROR([
+ -----------------------------------------------------------------------
+ No MPI C compiler can be found. Parallel netCDF requires an MPI C
+ compiler. Please specify the location of one either with the MPICC
+ environment variable or the --with-mpi configure flag
+ -----------------------------------------------------------------------])
+fi
+
+CC=${MPICC}
+AC_SUBST(MPICC)
+
+dnl Now MPICC is configured, let's do some basic compiler tests
+AC_PROG_CC
+
+dnl this call needs at least autoconf version 2.60
+dnl AC_USE_SYSTEM_EXTENSIONS
+
+dnl enable large file support
+AC_SYS_LARGEFILE
+
+UD_PROG_CC_MAKEDEPEND
+
+dnl AC_HEADER_STDC
+dnl AC_CHECK_HEADERS([malloc.h])
+
+# check if MPICC works for basic MPI call: MPI_Comm_rank()
+AC_CHECK_FUNC([MPI_Comm_rank], [],
+ dnl maybe -lmpi is needed at link stage
+ [AC_SEARCH_LIBS([MPI_Comm_rank], [mpi mpich], [],
+ [AC_MSG_ERROR([
+ ------------------------------------------------------------
+ Invalid MPI compiler specified or detected: "${MPICC}"
+ A working MPI compiler is required. Please specify the location
+ of one either with the MPICC environment variable or the
+ --with-mpi configure flag
+ ------------------------------------------------------------])
+])])
+
+
+AC_ARG_ENABLE([mpi-io-test],
+ [AS_HELP_STRING([--disable-mpi-io-test],
+ [Disable check for MPI-IO support in MPI implementation,
+ if you know your MPI implementation has MPI-IO support
+ but the configure test fails to find it.
+ @<:@default: enabled@:>@])],
+ [enable_mpi_io_test=${enableval}], [enable_mpi_io_test=yes]
+)
+
+if test "x${enable_mpi_io_test}" = xyes ; then
+ AC_CHECK_FUNC([MPI_File_open], [],
+ dnl maybe -lmpio is needed at link stage
+ [AC_SEARCH_LIBS([MPI_File_open], [mpio], [],
+ [AC_MSG_ERROR([
+ ------------------------------------------------------------
+ MPI implementation does not support MPI-IO
+ PnetCDF requires MPI-IO support to work properly.
+ ------------------------------------------------------------])]
+ )])
+fi
+
+dnl check MPI C++ compiler
+AC_ARG_ENABLE(cxx,
+ [AS_HELP_STRING([--disable-cxx],
+ [Turn off support for the C++ interface,
+ if you only need the C interface. @<:@default: enabled@:>@])],
+ [enable_cxx=${enableval}], [enable_cxx=auto]
+)
+
+if test "x${enable_cxx}" != xno ; then
+ UD_CHECK_MPI_COMPILER([MPICXX], [$CANDIDATE_MPICXX])
+
+ if test "x${MPICXX}" = x ; then
+ AC_MSG_ERROR([
+ ------------------------------------------------------------
+ configure cannot find a C++ compiler. Please specify the
+ locations of the compiler either with the MPICXX
+ environment variable or the --with-mpi configure flag.
+ ------------------------------------------------------------])
+ has_mpicxx=no
+ else
+ CXX=${MPICXX}
+ AC_SUBST(MPICXX)
+ has_mpicxx=yes
+
+ dnl UD_PROG_CXX
+ AC_PROG_CXX(${MPICXX})
+ dnl autoconf 2.5.9 has not yet implemented AC_PROG_CXX_C_O
+ dnl AC_PROG_CXX_C_O
+
+ dnl test if MPICXX can compile an MPI-IO program
+ if test "x${enable_mpi_io_test}" = xyes ; then
+ AC_LANG_PUSH(C++)
+ AC_CHECK_FUNC([MPI_File_close], [],
+ dnl maybe -lmpi++ is needed at link stage
+ [AC_SEARCH_LIBS([MPI_File_close], [mpi++ mpichcxx mpi_cxx], [],
+ [has_mpicxx=no
+ MPICXX=
+ AC_MSG_WARN([
+ ----------------------------------------------------------
+ MPI C++ implementation does not support MPI-IO
+ Disabling C++ testing programs
+ ----------------------------------------------------------])]
+ )])
+ AC_LANG_POP(C++)
+ fi
+ fi
+ if test "x${has_mpicxx}" = xyes ; then
+ UD_CHECK_MPI_CPP_SEEK_SET
+ UD_MSG_DEBUG(ac_cv_CHECK_MPI_CPP_SEEK_SET=$ac_cv_CHECK_MPI_CPP_SEEK_SET)
+ if test "x${ac_cv_CHECK_MPI_CPP_SEEK_SET}" = xyes ; then
+ CXXCPPFLAGS="${CXXCPPFLAGS} -DMPICH_IGNORE_CXX_SEEK -DMPICH_SKIP_MPICXX"
+ fi
+ fi
+else
+has_mpicxx=no
+fi
+AC_SUBST(has_mpicxx)
+
+dnl I took the "-ansi" off the CFLAGS for the strict case, as it was
+dnl preventing PATH_MAX from being defined for some of the test files,
+dnl and I was having a tough time figuring out how to get it back! -- RobR
+dnl Note this must be done after the type of C compiler is determined
+AC_ARG_ENABLE(strict,
+ [AS_HELP_STRING([--enable-strict],
+ [Turn on strict debugging with gcc. @<:@default: disabled@:>@])],
+ [enable_strict=${enableval}], [enable_strict=no]
+)
+
+if test "x${enable_strict}" = xyes; then
+ if test "x${GCC}" = xyes; then
+ CPPFLAGS="${CPPFLAGS} -Wall -Wstrict-prototypes -Wmissing-prototypes -Wundef -Wpointer-arith -Wbad-function-cast"
+ CXXCPPFLAGS="${CXXCPPFLAGS} -Wall -Wundef -Wpointer-arith"
+ else
+ AC_MSG_WARN([--enable-strict is for GNU compiler only])
+ enable_strict=no
+ fi
+fi
+AC_SUBST(CXXCPPFLAGS)
+
+AC_ARG_ENABLE(fortran,
+ [AS_HELP_STRING([--disable-fortran],
+ [Turn off support for the Fortran interface,
+ if you only need the C interface. @<:@default: enabled@:>@])],
+ [enable_fortran=${enableval}], [enable_fortran=auto]
+)
+
+if test "x${enable_fortran}" != xno ; then
+ UD_CHECK_MPI_COMPILER([MPIF77], [$CANDIDATE_MPIF77])
+ UD_CHECK_MPI_COMPILER([MPIF90], [$CANDIDATE_MPIF90])
+fi
+if test "x${enable_fortran}" = xyes ; then
+ dnl user explicitly requests to build Fortran APIs
+ if test "x${MPIF77}" = x && test "x${MPIF90}" = x ; then
+ AC_MSG_ERROR([
+ ------------------------------------------------------------
+ Fortran support is explicitly requested, but configure
+ cannot find a Fortran77 or Fortran90 compiler. Please
+ specify the locations of the compilers either with the
+ MPIF77 MPIF90 environment variables or the --with-mpi
+ configure flag.
+ ------------------------------------------------------------])
+ fi
+fi
+
+dnl AC_MSG_NOTICE(enable_fortran=${enable_fortran})
+
+dnl Check if MPIF90 is a valid MPI compiler
+if test "x${MPIF90}" != x ; then
+ FC=${MPIF90}
+ AC_PROG_FC
+ dnl FCFLAGS is set in AC_PROG_FC
+
+ FCLIBS_save="$FCLIBS"
+ FCLIBS=""
+ AC_FC_LIBRARY_LDFLAGS
+ UD_MSG_DEBUG([before FCLIBS=$FCLIBS])
+ dnl The autoconf macro for finding FCLIBS sometimes makes mistakes
+ dnl (particularly with the Fujitsu frt compiler). This next step
+ dnl first sees if the FCLIBS is valid with the Fortran compiler
+ dnl This also happens to Solaris Studio Fortran compilers
+ dnl AC_PROG_FC_FCLIBS_VALID
+ dnl Now see if FCLIBS works with the C compiler (remove invalid ones)
+ PAC_PROG_FC_CHECK_FCLIBS
+
+ dnl replace FLIBS and F90LIBS with FCLIBS
+ UD_MSG_DEBUG([after FCLIBS=$FCLIBS])
+ FLIBS="$FCLIBS"
+ F90LIBS="$FCLIBS"
+
+ dnl We use F90FLAGS for debugging and optimization options for Fortran 90 programs
+ F90FLAGS=${FCFLAGS}
+ AC_SUBST(F90FLAGS)
+
+ AC_LANG_PUSH([Fortran])
+ AC_COMPILE_IFELSE([AC_LANG_CALL([],[MPI_Comm_rank])],
+ [valid_mpif90=yes],[valid_mpif90=no]
+ )
+ AC_MSG_CHECKING([if mpi.mod is valid])
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [[ use mpi]])],
+ [valid_mpi_mod=yes], [valid_mpi_mod=no]
+ )
+ AC_MSG_RESULT($valid_mpi_mod)
+ AC_LANG_POP([Fortran])
+ if test "x${valid_mpif90}" = xno && test "x${enable_fortran}" = xyes ; then
+ AC_MSG_ERROR([
+ ------------------------------------------------------------
+ Invalid MPI Fortran 90 compiler specified: "${MPIF90}"
+ A working MPI compiler is required. Please specify the
+ location of one either with the MPIF90 environment
+ variable or the --with-mpi configure flag.
+ ------------------------------------------------------------])
+ fi
+ if test "x${valid_mpi_mod}" = xno && test "x${enable_fortran}" = xyes ; then
+ AC_MSG_ERROR([
+ ------------------------------------------------------------
+ Invalid MPI Fortran module. The mpi.mod file in the include path
+ may not be generated by the same Fortran compiler used to build
+ "${MPIF90}". Please make sure the same Fortran compiler is used.
+ ------------------------------------------------------------])
+ fi
+fi
+
+dnl Check if MPIF77 is a valid MPI compiler
+F77_SUPPORT_FREEFORM=no
+if test "x${MPIF77}" != x ; then
+ F77=${MPIF77}
+ AC_PROG_F77
+ dnl FFLAGS is set in AC_PROG_F77
+
+ AC_F77_LIBRARY_LDFLAGS
+
+ dnl We use F77FLAGS for debugging and optimization options for Fortran 77 programs
+ F77FLAGS=${FFLAGS}
+ AC_SUBST(F77FLAGS)
+
+ dnl get flag for Fortran free form (this flag is only used in testing)
+ FC_saved=${FC}
+ FC=${F77}
+ UD_FC_FREEFORM
+ if test "x${ac_cv_fc_freeform}" != xunknown ; then
+ F77_SUPPORT_FREEFORM=yes
+ FFREEFORMFLAG=${ac_cv_fc_freeform}
+ fi
+ UD_MSG_DEBUG([FC=$FC F90FLAGS=$F90FLAGS FFREEFORMFLAG=$FFREEFORMFLAG])
+ AC_SUBST(FFREEFORMFLAG)
+ FC=${FC_saved}
+
+ AC_LANG_PUSH([Fortran 77])
+ AC_COMPILE_IFELSE([AC_LANG_CALL([],[MPI_Comm_rank])],
+ [valid_mpif77=yes],[valid_mpif77=no]
+ )
+ AC_LANG_POP([Fortran 77])
+ if test "x${valid_mpif77}" = xno && test "x${enable_fortran}" = xyes ; then
+ AC_MSG_ERROR([
+ ------------------------------------------------------------
+ Invalid MPI Fortran 77 compiler specified: "${MPIF77}"
+ A working MPI compiler is required. Please specify the
+ location of one either with the MPIF77 environment
+ variable or the --with-mpi configure flag
+ ------------------------------------------------------------])
+ fi
+fi
+AC_SUBST(F77_SUPPORT_FREEFORM)
+
+if test "x${enable_fortran}" = xauto ; then
+ if test "x${valid_mpif77}" = xyes && test "x${valid_mpif90}" = xyes ; then
+ enable_fortran=yes
+ else
+ enable_fortran=no
+ AC_MSG_WARN([
+ ------------------------------------------------------------
+ Either MPI Fortran 77 or 90 compiler is not working:
+ "MPIF77 = ${MPIF77}"
+ "MPIF90 = ${MPIF90}"
+ Disable Fortran feature ...
+ ------------------------------------------------------------])
+ fi
+fi
+
+if test "x${enable_fortran}" = xyes ; then
+ dnl GNU Fortran compiler automatically invokes preprocessor for files with
+ dnl extension .F and .F90. To manually invoke the preprocessor on any file,
+ dnl use compiler flag -cpp. To disable, use -nocpp.
+ dnl For other compilers, we need to find the compile flags for Fortran
+ dnl preprocessor.
+ dnl steal AC_FC_PP_SRCEXT from autoconf V2.69 to make UD_FC_PP_SRCEXT
+ UD_FC_PP_SRCEXT([f]) dnl sets ac_cv_fc_pp_srcext_f
+ UD_FC_PP_SRCEXT([F]) dnl sets ac_cv_fc_pp_srcext_F
+ UD_FC_PP_SRCEXT([f90]) dnl sets ac_cv_fc_pp_srcext_f90
+ UD_FC_PP_SRCEXT([F90]) dnl sets ac_cv_fc_pp_srcext_F90
+
+ F77PPFLAGS_f=${ac_cv_fc_pp_srcext_f}
+ F77PPFLAGS_F=${ac_cv_fc_pp_srcext_F}
+ F90PPFLAGS_f90=${ac_cv_fc_pp_srcext_f90}
+ F90PPFLAGS_F90=${ac_cv_fc_pp_srcext_F90}
+ AC_SUBST(F77PPFLAGS_f)
+ AC_SUBST(F77PPFLAGS_F)
+ AC_SUBST(F90PPFLAGS_f90)
+ AC_SUBST(F90PPFLAGS_F90)
+
+ FPPFLAGS=${FPPFLAGS-}
+ AC_SUBST(FPP)
+ AC_SUBST(FPPFLAGS)
+
+ dnl compiler command-line define preprocess flag, result in FC_DEFINE
+ UD_FC_PP_DEFINE
+
+ dnl check compiler flags for file extensions in .f .F .f90 .F90
+ AC_LANG_PUSH([Fortran])
+ AC_FC_SRCEXT([f])
+ AC_FC_SRCEXT([F])
+ AC_FC_SRCEXT([f90])
+ AC_FC_SRCEXT([F90])
+ AC_SUBST(F77FLAGS_f)
+ AC_SUBST(F77FLAGS_F)
+ AC_SUBST(F90FLAGS_f90)
+ AC_SUBST(F90FLAGS_F90)
+ AC_LANG_POP([Fortran])
+
+ dnl get flag for Fortran fixed form (this flag is only used in testing)
+ UD_FC_FIXEDFORM
+ FFIXEDFORMFLAG=${ac_cv_fc_fixedform}
+ UD_MSG_DEBUG([FC=$FC F90FLAGS=$F90FLAGS FFIXEDFORMFLAG=$FFIXEDFORMFLAG])
+ AC_SUBST(FFIXEDFORMFLAG)
+
+ # Checking for Fortran types also determines the Fortran name mangling
+ # and places the value into FCALLSCSUB as the C name corresponding
+ # to the Fortran name SUB
+ AC_FC_FUNC(sub, [FCALLSCSUB])
+
+ # determine the correct name mapping
+ case $FCALLSCSUB in
+ SUB)
+ AC_DEFINE(F77_NAME_UPPER,,[Define if Fortran names are uppercase])
+ ;;
+ sub_)
+ # This is the hard case. Gcc uses one _ unless the name includes
+ # an underscore, in which case it gets two trailing underscores.
+ # Use essentially the same configure code that the original configure
+ # used to determine SUB
+ AC_MSG_CHECKING([for C-equivalent to Fortran routine "SUB_A"])
+ dnl "
+ AC_FC_FUNC(sub_a, [FCALLSCSUBA])
+ AC_MSG_RESULT($FCALLSCSUBA)
+ case $FCALLSCSUBA in
+ sub_a__)
+ AC_DEFINE(F77_NAME_LOWER_2USCORE,,[Define if Fortran names are lower case with two trailing underscore2])
+ ;;
+ sub_a_)
+ AC_DEFINE(F77_NAME_LOWER_USCORE,,[Define if Fortran names are lower case with one trailing underscore])
+ ;;
+ *)
+ AC_MSG_WARN([Unrecognized Fortran name mapping])
+ ;;
+ esac
+ ;;
+ sub)
+ AC_DEFINE(F77_NAME_LOWER,,[Define if Fortran names are lower case])
+ ;;
+ *)
+ AC_MSG_WARN([Unrecognized Fortran name mapping])
+ ;;
+ esac
+
+ dnl Some Fortran 77 compilers, such as pgf77, do not allow "_8" modifier,
+ dnl because _8 modifier is a Fortran 90 feature
+ dnl UD_CHECK_PGF77
+ dnl UD_MSG_DEBUG([ac_cv_fc_compiler_pgf77=$ac_cv_fc_compiler_pgf77])
+
+ dnl Check if the Fortran compiler is an NAG
+ UD_CHECK_FC_NAG
+ if test "x${ac_cv_fc_compiler_nag}" = xyes ; then
+ NAGf90FPPFLAGS="-DNAGf90Fortran"
+ NAG_FCFLAGS="-mismatch"
+ AC_SUBST(NAGf90FPPFLAGS)
+ AC_SUBST(NAG_FCFLAGS)
+ fi
+
+ dnl check Fortran parameter modifier for 8-byte integer type
+ dnl We need this to set the max constants for UINT INT64 and UINT64
+ UD_FC_CONSTANT_MODIFIER
+ UD_MSG_DEBUG([ac_cv_fc_constant_modifier=$ac_cv_fc_constant_modifier])
+ PNF_INT8_MODIFIER=""
+ if test "x${ac_cv_fc_constant_modifier}" = xnone ; then
+ PNF_FILL_UINT=4294967295
+ PNF_FILL_INT64=-9223372036854775806
+ PNF_FILL_UINT64=18446744073709551614
+ PNF_X_UINT_MAX=4294967295
+ PNF_X_INT8_MIN=-9223372036854775807
+ PNF_X_INT8_MAX=9223372036854775807
+ PNF_X_UINT8_MAX=18446744073709551615
+ else
+ if test "x${ac_cv_fc_constant_modifier}" = xEightByteInt ; then
+ PNF_INT8_MODIFIER=" integer, parameter :: EightByteInt = selected_int_kind(18)"
+ fi
+ PNF_FILL_UINT=4294967295_${ac_cv_fc_constant_modifier}
+ PNF_FILL_INT64=-9223372036854775806_${ac_cv_fc_constant_modifier}
+ PNF_FILL_UINT64=18446744073709551614_${ac_cv_fc_constant_modifier}
+ PNF_X_UINT_MAX=4294967295_${ac_cv_fc_constant_modifier}
+ PNF_X_INT8_MIN=-9223372036854775807_${ac_cv_fc_constant_modifier}
+ PNF_X_INT8_MAX=9223372036854775807_${ac_cv_fc_constant_modifier}
+ PNF_X_UINT8_MAX=18446744073709551615_${ac_cv_fc_constant_modifier}
+ fi
+ AC_SUBST(PNF_INT8_MODIFIER)
+ AC_SUBST(PNF_FILL_UINT)
+ AC_SUBST(PNF_FILL_INT64)
+ AC_SUBST(PNF_FILL_UINT64)
+ AC_SUBST(PNF_X_UINT_MAX)
+ AC_SUBST(PNF_X_INT8_MIN)
+ AC_SUBST(PNF_X_INT8_MAX)
+ AC_SUBST(PNF_X_UINT8_MAX)
+
+ AC_SUBST(MPIF77)
+ AC_SUBST(MPIF90)
+fi
+
+AC_PROG_INSTALL
+
+have_yacc_lex=no
+dnl Starting from PnetCDF 1.5.0, yacc and lex is no longer needed
+dnl see comments in src/utils/ncmpigen/Makefile.in for build rules for
+dnl ncmpigenyy.c and ncmpigentab.c. If rebuild is desired, uncomment
+dnl below checking to check availability of yacc/lex/bison
+dnl AC_PROG_YACC
+dnl dnl if neither bison nor byacc is found, YACC will be set to yacc
+dnl have_yacc_lex=yes
+dnl if test "x$YACC" = xyacc; then
+dnl AC_CHECK_PROGS(YACC_PATH, yacc)
+dnl if test "x$YACC_PATH" = x; then
+dnl dnl cannot find bison or yacc required to build ncmpigentab.c
+dnl have_yacc_lex=no
+dnl fi
+dnl fi
+dnl
+dnl AC_PROG_LEX
+dnl if (test "x$LEX" != xflex) && (test "x$LEX" != xlex) ; then
+dnl dnl cannot find flex or lex required to build ncmpigenyy.c
+dnl have_yacc_lex=no
+dnl fi
+AC_SUBST(have_yacc_lex)
+
+dnl AC_PROG_AWK
+AC_PROG_LN_S
+AC_PROG_MAKE_SET
+AC_SUBST(SET_MAKE)
+AC_PROG_EGREP
+
+dnl AC_PROG_SED and AC_PROG_GREP are only available on autoconf 2.60 and later
+dnl AC_PROG_SED
+dnl AC_PROG_GREP
+
+dnl YACC and LEX are required to build PnetCDF utility tool ncmpigen
+dnl if configure finds bison then YACC is set to bison -y, so we need to clean
+dnl up the output a bit before testing
+dnl Below checks commands yacc and lex availability under PATH. However, this
+dnl checking is redundant, as AC_PROG_* did that already
+dnl YACC_CMD="${YACC% *}"
+dnl AC_CHECK_PROG([yacc_cmd], [${YACC_CMD}], [yes], [no])
+dnl AC_CHECK_PROG([lex_cmd], [${LEX}], [yes], [no])
+dnl if test "x${yacc_cmd}" = no ; then
+dnl AC_MSG_ERROR([could not find bison/yacc required by PnetCDF])
+dnl fi
+dnl if test "x${lex_cmd}" = no ; then
+dnl AC_MSG_ERROR([could not find flex/lex required by PnetCDF])
+dnl fi
+
+UD_PROG_M4
+UD_PROG_AR()
+UD_PROG_NM()
+# We could use the PAC check for ranlib (it also makes sure that ranlib works,
+# which is not always true, particularly when GNU tools are installed on
+# a system that doesn't have (or need) ranlib
+AC_PROG_RANLIB
+
+dnl Check for <stdbool.h> that conforms to C99 requirements
+dnl this is also for using bool type in utf8proc.h/utf8proc.c to support
+dnl special characters in CDF-2 and CDF-5
+AC_HEADER_STDBOOL
+
+dnl AC_C_CONST
+AC_C_INLINE
+
+dnl we do not use struct stat yet
+dnl AC_CHECK_MEMBERS([struct stat.st_blksize])
+
+UD_CHECK_IEEE
+
+dnl cross compile fails with undefined reference to rpl_realloc and rpl_malloc
+dnl AC_FUNC_MALLOC
+dnl AC_FUNC_REALLOC
+
+dnl below checks availability of a bunch C functions, but we have not yet
+dnl implemented alternative calls
+dnl AC_FUNC_ERROR_AT_LINE
+dnl AC_FUNC_MEMCMP
+dnl AC_FUNC_STRTOD
+dnl AC_FUNC_VPRINTF
+dnl AC_CHECK_FUNCS([memset setlocale sqrt strchr strrchr strtol])
+dnl AC_CHECK_LIB([m], [tanh])
+dnl UD_CHECK_LIB_MATH
+AC_CHECK_FUNCS([strerror access unlink])
+
+AC_ARG_ENABLE([debug],
+ [AS_HELP_STRING([--enable-debug],
+ [Enable PnetCDF internal debug mode. This also enables safe mode.
+ @<:@default: disabled@:>@])],
+ [debug=${enableval}], [debug=no]
+)
+AC_MSG_CHECKING(PnetCDF debug mode)
+if test "x${debug}" = xyes; then
+ AC_DEFINE(PNC_DEBUG)
+
+ dnl malloc memory allocation tracing relies on tdelete and tsearch
+ AC_CHECK_HEADERS([search.h])
+ AC_CHECK_FUNCS([tsearch tdelete])
+
+ dnl check required functions for enabling malloc tracing
+ if (test "x${ac_cv_func_tsearch}" = xyes) &&
+ (test "x${ac_cv_func_tdelete}" = xyes) ; then
+ AC_DEFINE(PNC_MALLOC_TRACE)
+ fi
+fi
+AC_MSG_RESULT($debug)
+PNC_DEBUG=${debug}
+AC_SUBST(PNC_DEBUG)
+
+AC_CHECK_TYPE([MPI_Offset], [], [], [#include <mpi.h>])
+if test "x${ac_cv_type_MPI_Offset}" = xyes; then
+ AC_CHECK_SIZEOF([MPI_Offset], [], [#include <mpi.h>])
+else
+ AC_MSG_ERROR([Unable to find type MPI_Offset in mpi.h])
+fi
+AC_CHECK_SIZEOF([MPI_Aint], [], [#include <mpi.h>])
+
+dnl ok, now we know how big MPI_Offset is. If it's less than 8 bytes
+dnl we have to disable the new "CDF-5" (variables larger than 4gb) support
+if test "$ac_cv_sizeof_MPI_Offset" -lt "8"; then
+ AC_MSG_WARN("Unable to support CDF-5 format");
+ enable_cdf5=no
+else
+ AC_DEFINE(ENABLE_CDF5,,[Define if able to support CDF-5 file format])
+ enable_cdf5=yes
+fi
+
+SIZEOF_MPI_AINT_IS_4=no
+if test "x$ac_cv_sizeof_MPI_Aint" = x4; then
+ SIZEOF_MPI_AINT_IS_4=yes
+fi
+AC_SUBST(SIZEOF_MPI_AINT_IS_4)
+
+dnl the nonblocking routines build up lists of requests with MPI_Type_struct.
+dnl If MPI_Offset not the same size as MPI_Aint, the arrays passed around will
+dnl get mangled.
+if test "$ac_cv_sizeof_MPI_Offset" -ne "$ac_cv_sizeof_MPI_Aint"; then
+ AC_MSG_WARN(MPI_Offset and MPI_Aint have different sizes: non-blocking APIs now behave like blocking ones)
+ enable_nonblocking=no
+else
+ AC_DEFINE(ENABLE_NONBLOCKING,,[Define if able to support nonblocking routines])
+ enable_nonblocking=yes
+fi
+
+# check for MPI-2 only functions
+AC_CHECK_FUNCS(MPI_Info_dup MPI_Info_free MPI_Get_address)
+AC_CHECK_FUNCS(MPI_Type_create_subarray MPI_Type_create_hvector MPI_Type_create_hindexed MPI_Type_create_struct MPI_Type_create_resized MPI_Type_get_extent)
+
+dnl Check for presence of MPI COMBINERS.
+UD_HAS_MPI_CONST(MPI_COMBINER_DUP)
+UD_HAS_MPI_CONST(MPI_COMBINER_HVECTOR_INTEGER)
+UD_HAS_MPI_CONST(MPI_COMBINER_HINDEXED_INTEGER)
+UD_HAS_MPI_CONST(MPI_COMBINER_SUBARRAY)
+UD_HAS_MPI_CONST(MPI_COMBINER_DARRAY)
+UD_HAS_MPI_CONST(MPI_COMBINER_RESIZED)
+UD_HAS_MPI_CONST(MPI_COMBINER_STRUCT_INTEGER)
+UD_HAS_MPI_CONST(MPI_COMBINER_INDEXED_BLOCK)
+UD_HAS_MPI_CONST(MPI_COMBINER_F90_REAL)
+UD_HAS_MPI_CONST(MPI_COMBINER_F90_INTEGER)
+UD_HAS_MPI_CONST(MPI_COMBINER_F90_COMPLEX)
+
+dnl Check for presence of various MPI error classes.
+dnl These could be enums, so we have to do compile checks.
+UD_HAS_MPI_CONST(MPI_ERR_FILE_EXISTS)
+UD_HAS_MPI_CONST(MPI_ERR_NO_SUCH_FILE)
+UD_HAS_MPI_CONST(MPI_ERR_AMODE)
+UD_HAS_MPI_CONST(MPI_ERR_NOT_SAME)
+UD_HAS_MPI_CONST(MPI_ERR_BAD_FILE)
+UD_HAS_MPI_CONST(MPI_ERR_READ_ONLY)
+UD_HAS_MPI_CONST(MPI_ERR_ACCESS)
+UD_HAS_MPI_CONST(MPI_ERR_NO_SPACE)
+UD_HAS_MPI_CONST(MPI_ERR_QUOTA)
+
+dnl Check for presence of C types
+UD_HAS_MPI_DATATYPE(MPI_CHAR)
+UD_HAS_MPI_DATATYPE(MPI_BYTE)
+UD_HAS_MPI_DATATYPE(MPI_SIGNED_CHAR)
+UD_HAS_MPI_DATATYPE(MPI_UNSIGNED_CHAR)
+UD_HAS_MPI_DATATYPE(MPI_SHORT)
+UD_HAS_MPI_DATATYPE(MPI_UNSIGNED_SHORT)
+UD_HAS_MPI_DATATYPE(MPI_INT)
+UD_HAS_MPI_DATATYPE(MPI_UNSIGNED)
+UD_HAS_MPI_DATATYPE(MPI_LONG)
+UD_HAS_MPI_DATATYPE(MPI_FLOAT)
+UD_HAS_MPI_DATATYPE(MPI_DOUBLE)
+UD_HAS_MPI_DATATYPE(MPI_LONG_LONG_INT)
+UD_HAS_MPI_DATATYPE(MPI_UNSIGNED_LONG_LONG)
+UD_HAS_MPI_DATATYPE(MPI_UB)
+UD_HAS_MPI_DATATYPE(MPI_LB)
+dnl UD_HAS_MPI_DATATYPE(MPI_OFFSET)
+dnl HAVE_MPI_OFFSET might have already been defined in mpi.h
+dnl Add "_DATATYPE" suffix to distinguish from checking MPI_Offset
+UD_HAS_MPI_DATATYPE(MPI_OFFSET, _DATATYPE)
+
+dnl Check for presence of Fortran types
+dnl These could be enums, so we have to do compile checks.
+dnl
+dnl We do this for a couple of reasons. First, the MPI might have been
+dnl built without Fortran support, in which case these types might not
+dnl exist. Second, we need to map these types to corresponding C types
+dnl where possible to simplify processing at run time.
+if test "x${enable_fortran}" = xyes ; then
+ UD_HAS_MPI_DATATYPE(MPI_CHARACTER)
+ UD_HAS_MPI_DATATYPE(MPI_REAL)
+ UD_HAS_MPI_DATATYPE(MPI_INTEGER)
+ UD_HAS_MPI_DATATYPE(MPI_DOUBLE_PRECISION)
+ UD_HAS_MPI_DATATYPE(MPI_INTEGER1)
+ UD_HAS_MPI_DATATYPE(MPI_INTEGER2)
+ UD_HAS_MPI_DATATYPE(MPI_INTEGER4)
+ UD_HAS_MPI_DATATYPE(MPI_INTEGER8)
+ UD_HAS_MPI_DATATYPE(MPI_INTEGER16)
+ UD_HAS_MPI_DATATYPE(MPI_REAL4)
+ UD_HAS_MPI_DATATYPE(MPI_REAL8)
+ UD_HAS_MPI_DATATYPE(MPI_REAL16)
+ UD_HAS_MPI_DATATYPE(MPI_COMPLEX8)
+ UD_HAS_MPI_DATATYPE(MPI_COMPLEX16)
+ UD_HAS_MPI_DATATYPE(MPI_COMPLEX32)
+fi
+
+AC_ARG_ENABLE([in-place-swap],
+ [AS_HELP_STRING([--disable-in-place-swap],
+ [Disable memory in-place byte swap on Little Endian
+ machines. @<:@default: enabled@:>@])],
+ [in_place_swap=${enableval}], [in_place_swap=yes]
+)
+if test "x${in_place_swap}" = xno ; then
+ AC_DEFINE(DISABLE_IN_PLACE_SWAP)
+fi
+
+AC_C_CHAR_UNSIGNED
+AC_C_BIGENDIAN
+is_bigendian=no
+if test "x${ac_cv_c_bigendian}" = xyes ; then
+ is_bigendian=yes
+fi
+AC_SUBST(is_bigendian)
+
+dnl For big endian, put buffer needs no byte swap and hence can be declared as
+dnl INTENT(IN). For little endian, put buffer may be used for byte swap in
+dnl place and hence must be declared as INTENT(INOUT).
+dnl This will configure/produce the file src/libf90/api.f90
+if test "x${ac_cv_c_bigendian}" = xyes || (test "x${in_place_swap}" = xno) ; then
+ INTENTV="IN"
+else
+ INTENTV="INOUT"
+fi
+AC_SUBST(INTENTV)
+
+AC_TYPE_SIZE_T
+AC_TYPE_OFF_T
+AC_CHECK_TYPES([ssize_t, ptrdiff_t, uchar, ushort, uint, longlong, ulonglong, int64, uint64])
+
+AC_CHECK_SIZEOF(size_t)
+AC_CHECK_SIZEOF(off_t)
+AC_CHECK_SIZEOF(signed char)
+AC_CHECK_SIZEOF(unsigned char)
+AC_CHECK_SIZEOF(short)
+AC_CHECK_SIZEOF(unsigned short)
+AC_CHECK_SIZEOF(int)
+AC_CHECK_SIZEOF(unsigned int)
+AC_CHECK_SIZEOF(long)
+AC_CHECK_SIZEOF(float)
+AC_CHECK_SIZEOF(double)
+AC_CHECK_SIZEOF(long long)
+AC_CHECK_SIZEOF(unsigned long long)
+
+if test "$ac_cv_type_ushort" = yes ; then
+ AC_CHECK_SIZEOF(ushort)
+fi
+if test "$ac_cv_type_uint" = yes ; then
+ AC_CHECK_SIZEOF(uint)
+fi
+if test "$ac_cv_type_longlong" = yes ; then
+ AC_CHECK_SIZEOF(longlong)
+fi
+if test "$ac_cv_type_ulonglong" = yes ; then
+ AC_CHECK_SIZEOF(ulonglong)
+fi
+
+if test "x${enable_fortran}" = xyes ; then
+ if test "$cross_compiling" = yes; then
+ UD_CHECK_FORTRAN_TYPE([NF_INT1_T], [integer*1 byte "integer(kind=1)"])
+ UD_CHECK_FORTRAN_TYPE([NF_INT2_T], [integer*2 "integer(kind=2)"])
+ UD_CHECK_FORTRAN_TYPE([NF_INT8_T], [integer*8 "integer(kind=8)"])
+ else
+ UD_FORTRAN_TYPES
+ fi
+
+ NFMPI_OFFSET="integer*$ac_cv_sizeof_MPI_Offset"
+ AC_MSG_CHECKING([for Fortran NFMPI_OFFSET "$NFMPI_OFFSET"])
+ dnl "
+ AC_LANG_PUSH([Fortran 77])
+ AC_COMPILE_IFELSE(
+ [AC_LANG_SOURCE([
+ subroutine sub(value)
+ $NFMPI_OFFSET value
+ end
+ ])],
+ [ac_cv_NFMPI_OFFSET=yes], [ac_cv_NFMPI_OFFSET=no]
+ )
+ AC_LANG_POP([Fortran 77])
+ if test "$ac_cv_NFMPI_OFFSET" = yes ; then
+ AC_MSG_RESULT(yes)
+ else
+ AC_MSG_RESULT(no)
+ AC_MSG_ERROR([F77 does not support "$NFMPI_OFFSET"])
+ dnl "
+ fi
+ ${RM} -rf conftest*
+fi
+
+SIZEOF_MPI_OFFSET=$ac_cv_sizeof_MPI_Offset
+AC_SUBST(SIZEOF_MPI_OFFSET)
+
+if test "x${enable_fortran}" = xyes ; then
+
+ UD_FC_MODULE_EXTENSION
+ dnl UD_FC_MODULE_EXTENSION defines FC_MODEXT
+ if test "x${FC_MODEXT}" = x ; then
+ AC_MSG_ERROR([cannot determine Fortran module file extension!])
+ fi
+ UD_MSG_DEBUG([FC_MODEXT=$FC_MODEXT])
+
+ UD_FC_MODULE_FLAG
+ dnl UD_FC_MODULE_FLAG defines FC_MODINC
+ UD_MSG_DEBUG([FC_MODINC=$FC_MODINC])
+
+ UD_FC_MODULE_OUTPUT_FLAG
+ dnl UD_FC_MODULE_OUTPUT_FLAG defines FC_MODOUT
+ UD_MSG_DEBUG([FC_MODOUT=$FC_MODOUT])
+fi
+
+dnl
+dnl Below is to check if a Fortran compiler produces module files with upper
+dnl case file name, eg. PNETCDF.mod. However, this does not work for Mac OSX
+dnl file system which is case insensitive
+dnl
+if test "x${enable_fortran}" = xyes ; then
+ UD_PROG_FC_UPPERCASE_MOD
+fi
+UPPER_CASE_MOD=no
+if test "x$ac_cv_prog_f90_uppercase_mod" = xyes ; then
+ UPPER_CASE_MOD=yes
+fi
+AC_SUBST(UPPER_CASE_MOD)
+
+if test "x${enable_fortran}" = xyes ; then
+ if test "x${enable_strict}" = xyes; then
+ FPPFLAGS="${FPPFLAGS} -Wall"
+ fi
+ AC_SUBST(FLIBS)
+ AC_SUBST(FCLIBS)
+ AC_SUBST(F90LIBS)
+ AC_SUBST(FLDFLAGS)
+ AC_SUBST(F90LDFLAGS)
+fi
+
+has_fortran=${enable_fortran}
+AC_SUBST(has_fortran)
+
+UD_MAKEWHATIS
+
+dnl
+dnl GNU coverage
+dnl
+dnl This is for internal testing only. It should not be enabled for building a
+dnl production PnetCDF. This is because when run an executable compiled with
+dnl coverage will produce an output file named "gmon.out". Since coverage is
+dnl not parallelized, running a program compiled with coverage may cause
+dnl problems on concurrently writing to gmon.out in conflicts, possible
+dnl corrupting the file or program hanging. Thus, make target "ptest" should
+dnl also be disabled when coverage is enabled.
+dnl
+dnl After all other tests, optionally enable coverage, we do this last
+dnl because legend has it that sometimes on some compilers the coverage flags
+dnl mess up other checks
+dnl
+AC_ARG_ENABLE([coverage],
+ [AS_HELP_STRING([--enable-coverage],
+ [Compile with coverage support (gcc-based only). @<:@default: disabled@:>@])],
+ [enable_coverage=${enableval}], [enable_coverage=no]
+)
+if test "x${enable_coverage}" = xyes; then
+ if test "x${GCC}" = xyes; then
+ dnl it is GNU compiler
+ LCOV_FLAGS="-pg -fprofile-arcs -ftest-coverage --coverage -O0"
+ CFLAGS="${CFLAGS} ${LCOV_FLAGS}"
+ if test "x${has_mpicxx}" = xyes ; then
+ CXXFLAGS="${CXXFLAGS} ${LCOV_FLAGS}"
+ fi
+ if test "x${enable_fortran}" = xyes ; then
+ FCFLAGS="${FCFLAGS} ${LCOV_FLAGS}"
+ F77FLAGS="${F77FLAGS} ${LCOV_FLAGS}"
+ F90FLAGS="${F90FLAGS} ${LCOV_FLAGS}"
+ fi
+ LCOV_LIB=-lgcov
+ AC_SUBST(LCOV_LIB)
+ else
+ AC_MSG_WARN([--enable-coverage is for GNU compiler only])
+ enable_coverage=no
+ fi
+fi
+AC_SUBST(enable_coverage)
+
+if test "x${has_mpicxx}" = xyes ; then
+ UD_CXX_MACRO_FUNC
+ if test "x${ac_cv_cxx_macro_func}" == xyes ; then
+ AC_DEFINE(HAVE_FUNC_MACRO)
+ fi
+ if test "x${ac_cv_cxx_macro_function}" == xyes ; then
+ AC_DEFINE(HAVE_FUNCTION_MACRO)
+ fi
+fi
+
+if test "x${debug}" = xyes; then
+ dnl add -g flag if not presented
+ dnl remove all -O and -fast flags
+ dnl add -O0 to all flags
+ if ! echo "${CFLAGS}" | ${EGREP} -q -- "-g" ; then
+ CFLAGS="${CFLAGS} -g"
+ fi
+ CFLAGS=`echo $CFLAGS | sed 's/-O. *//g' | sed 's/-fast *//g'`
+ CFLAGS="${CFLAGS} -O0"
+
+ if test "x${has_mpicxx}" = xyes ; then
+ if ! echo "${CXXFLAGS}" | ${EGREP} -q -- "-g" ; then
+ CXXFLAGS="${CXXFLAGS} -g"
+ fi
+ CXXFLAGS=`echo $CXXFLAGS | sed 's/-O. *//g' | sed 's/-fast *//g'`
+ CXXFLAGS="${CXXFLAGS} -O0"
+ fi
+
+ if test "x${enable_fortran}" = xyes ; then
+ if ! echo "${FCFLAGS}" | ${EGREP} -q -- "-g" ; then
+ FCFLAGS="${FCFLAGS} -g"
+ fi
+ if ! echo "${F77FLAGS}" | ${EGREP} -q -- "-g" ; then
+ F77FLAGS="${F77FLAGS} -g"
+ fi
+ if ! echo "${F90FLAGS}" | ${EGREP} -q -- "-g" ; then
+ F90FLAGS="${F90FLAGS} -g"
+ fi
+
+ FCFLAGS=`echo $FCFLAGS | sed 's/-O. *//g' | sed 's/-fast *//g'`
+ F77FLAGS=`echo $F77FLAGS | sed 's/-O. *//g' | sed 's/-fast *//g'`
+ F90FLAGS=`echo $F90FLAGS | sed 's/-O. *//g' | sed 's/-fast *//g'`
+ FCFLAGS="${FCFLAGS} -O0"
+ F77FLAGS="${F77FLAGS} -O0"
+ F90FLAGS="${F90FLAGS} -O0"
+ fi
+fi
+
+chmod u+x ${srcdir}/scripts/install-sh
+
+AC_ARG_ENABLE([subfiling],
+ [AS_HELP_STRING([--enable-subfiling],
+ [Enable subfiling support. @<:@default: disabled@:>@])],
+ [enable_subfiling=${enableval}], [enable_subfiling=no]
+)
+if test "x$enable_subfiling" = "xyes" ; then
+ AC_DEFINE(ENABLE_SUBFILING)
+ AC_SUBST(enable_subfiling)
+fi
+
+AC_PATH_PROG([LATEX], [latex])
+AC_PATH_PROG([DVIPDF], [dvipdf])
+has_latex=no
+if test "x${LATEX}" != x ; then
+ has_latex=yes
+fi
+AC_SUBST(LATEX)
+AC_SUBST(DVIPDF)
+AC_SUBST(has_latex)
+
+BUILDDIR=`pwd`
+AC_SUBST(BUILDDIR)
+
+AC_ARG_ENABLE([file-sync],
+ [AS_HELP_STRING([--disable-file-sync],
+ [Disable MPI file sync if you know your file system can
+ provide data consistency. @<:@default: enabled@:>@])],
+ [file_sync=${enableval}], [file_sync=yes]
+)
+if test "x${file_sync}" = xno ; then
+ AC_DEFINE(DISABLE_FILE_SYNC)
+fi
+
+AC_ARG_ENABLE([large-file-test],
+ [AS_HELP_STRING([--enable-large-file-test],
+ [Enable testing for large (>4GB) file/variable I/O. Note
+ "make testing" can run very slow. @<:@default: disabled@:>@])],
+ [large_file_test=${enableval}], [large_file_test=no]
+)
+AC_SUBST(large_file_test)
+
+dnl PNETCDF_INC and PNETCDF_LIB are for benchmark programs use only
+PNETCDF_INC=${BUILDDIR}/src/libf90
+PNETCDF_LIB="-L${BUILDDIR}/src/lib"
+AC_SUBST(PNETCDF_INC)
+AC_SUBST(PNETCDF_LIB)
+
+AC_ARG_VAR(TEST_SEQRUN, [Run command (on one process) for make target check on cross-compile environment. Example: "aprun -n 1". @<:@default: none@:>@])
+AC_ARG_VAR(TEST_MPIRUN, [MPI run command for make target ptest, @<:@default: mpiexec -n NP@:>@])
+AC_ARG_VAR(TEST_OUTDIR, [Output file directory for make target ptest, @<:@default: ./@:>@])
+if test "x${TEST_MPIRUN}" = x ; then
+ dnl set default to mpiexec
+ TEST_MPIRUN="mpiexec -n NP"
+fi
+if test "x${TEST_OUTDIR}" = x ; then
+ dnl set default to current directory
+ TEST_OUTDIR=.
+fi
+AC_SUBST(TEST_SEQRUN)
+AC_SUBST(TEST_MPIRUN)
+AC_SUBST(TEST_OUTDIR)
+
+dnl find if gcc is available for compiling ncoffsets to run in sequential
+AC_PATH_PROG([SEQ_CC], [gcc], [$MPICC])
+AC_SUBST(SEQ_CC)
+
+AC_CONFIG_HEADERS([src/libf/nfconfig_inc])
+AC_CONFIG_FILES(macros.make \
+ Makefile \
+ src/Makefile \
+ src/lib/Makefile \
+ src/lib/pnetcdf.h \
+ src/utils/Makefile \
+ src/utils/ncmpidump/Makefile \
+ src/utils/ncmpidiff/Makefile \
+ src/utils/ncmpigen/Makefile \
+ src/utils/ncmpivalid/Makefile \
+ src/utils/pnetcdf_version/Makefile \
+ src/utils/ncoffsets/Makefile \
+ test/Makefile \
+ test/common/Makefile \
+ test/nc_test/Makefile \
+ test/C/Makefile \
+ test/fandc/Makefile \
+ test/testcases/Makefile \
+ test/nonblocking/Makefile \
+ test/header/Makefile \
+ test/cdf_format/Makefile \
+ test/largefile/Makefile \
+ examples/C/Makefile \
+ examples/tutorial/Makefile \
+ examples/Makefile \
+ doc/Makefile \
+ man/Makefile \
+ scripts/Makefile \
+ benchmarks/Makefile \
+ benchmarks/C/Makefile \
+ test/nf_test/Makefile \
+ test/nf_test/tests.inc \
+ test/nf90_test/Makefile \
+ test/F90/Makefile \
+ examples/F77/Makefile \
+ examples/F90/Makefile \
+ src/libf90/Makefile \
+ src/libf90/api.f90 \
+ src/libf90/nfmpi_constants.f90 \
+ src/libf/Makefile \
+ src/libf/pnetcdf.inc \
+ src/libcxx/Makefile \
+ examples/CXX/Makefile \
+ test/CXX/Makefile \
+ benchmarks/FLASH-IO/Makefile \
+ test/subfile/Makefile)
+
+# The following dependency is for configure.in and configure
+# See autoconf manual 2.69, Section 4.8.5 Automatic Remaking
+AC_CONFIG_FILES([stamp-h], [echo timestamp > stamp-h])
+
+AC_OUTPUT
+echo "--------------------------------------------------------------------"
+
+if test "x${enable_mpi_io_test}" = xno ; then
+ AC_MSG_WARN([
+ NOTE: disabling the MPI-IO test is a VERY bad idea.
+ Please make sure you know what you are doing])
+fi
+
+msg_large_files=no
+if test "$ac_cv_sizeof_off_t" -gt 4 ; then
+ msg_large_files=yes
+fi
+
+echo \
+"
+ ${PACKAGE_NAME} Version ${PACKAGE_VERSION}
+
+ Features: Support for large files (> 4 GB) - ${msg_large_files}
+ Build C++ APIs - ${has_mpicxx}
+ Build Fortran APIs - ${enable_fortran}
+ Build nonblocking APIs - ${enable_nonblocking}
+ Build CDF-5 support - ${enable_cdf5}
+ Build subfiling support - ${enable_subfiling}"
+if test "x${ac_cv_c_bigendian}" = xno && (test "x${in_place_swap}" = xno) ; then
+ echo "\
+ Memory in-place byte swap - disabled"
+fi
+if test "x${large_file_test}" = xyes; then
+ echo "\
+ Testing large file/variable I/O - enabled"
+fi
+if test "x${debug}" = xyes; then
+ echo "\
+ PnetCDF internal debug mode - enabled"
+fi
+if test "x${enable_fortran}" = xyes && (test "x${F77_SUPPORT_FREEFORM}" = xno) ; then
+ echo "\
+ Support free form in Fortran 77 - no"
+fi
+
+echo "\
+
+ Compilers: MPICC = ${MPICC}"
+if test "${has_mpicxx}" = yes ; then
+ echo "\
+ MPICXX = ${MPICXX}"
+fi
+if test "${enable_fortran}" = yes ; then
+ echo "\
+ MPIF77 = ${MPIF77}
+ MPIF90 = ${MPIF90}"
+fi
+echo "\
+ CFLAGS = ${CFLAGS}"
+if test "x${CPPFLAGS}" != x ; then
+ echo "\
+ CPPFLAGS = ${CPPFLAGS}"
+fi
+if test "${has_mpicxx}" = yes ; then
+ echo "\
+ CXXFLAGS = ${CXXFLAGS}"
+ if test "x${CXXCPPFLAGS}" != x ; then
+ echo "\
+ CXXCPPFLAGS = ${CXXCPPFLAGS}"
+ fi
+fi
+if test "${enable_fortran}" = yes ; then
+ echo "\
+ F77FLAGS = ${F77FLAGS}
+ F90FLAGS = ${F90FLAGS}"
+ if test "x${FPPFLAGS}" != x ; then
+ echo "\
+ FPPFLAGS = ${FPPFLAGS}"
+ fi
+fi
+if test "x${LDFLAGS}" != x ; then
+ echo "\
+ LDFLAGS = ${LDFLAGS}"
+fi
+if test "x${LIBS}" != x ; then
+ echo "\
+ LIBS = ${LIBS}"
+fi
+echo "\
+
+ Now type 'make' to build the library and utility tools.
+ Type 'make @<:@<target>@:>@'
+ where the optional <target> is:
+ testing - test PnetCDF build for sequential run
+ ptest - test PnetCDF build for parallel run
+ install - install PnetCDF
+---------------------------------------------------------------------"
+
diff --git a/doc/Makefile.in b/doc/Makefile.in
new file mode 100644
index 0000000..1880b80
--- /dev/null
+++ b/doc/Makefile.in
@@ -0,0 +1,45 @@
+#
+# Copyright (C) 2012, Northwestern University and Argonne National Laboratory
+# See COPYRIGHT notice in top-level directory.
+#
+# $Id: Makefile.in 1468 2013-10-26 16:53:18Z wkliao $
+#
+# @configure_input@
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+include ../macros.make
+
+LATEX = @LATEX@
+DVIPDF = @DVIPDF@
+ifeq (@has_latex@, yes)
+ API_GUIDE = pnetcdf-api.pdf
+else
+ API_GUIDE =
+endif
+
+all: $(API_GUIDE)
+
+pnetcdf-api.pdf: $(srcdir)/pnetcdf-api.tex
+ $(LATEX) $<
+ $(LATEX) $<
+ $(DVIPDF) pnetcdf-api
+
+PACKING_LIST = Makefile.in \
+ c_api.tex \
+ data_mode_api.tex \
+ flexible_api.tex \
+ latex8.sty \
+ Makefile.in \
+ multiple_io.tex \
+ nonblocking.tex \
+ pnetcdf-api.bbl \
+ pnetcdf-api.tex \
+ porting_notes.txt \
+ symbol_renaming.txt
+
+GARBAGE = *.dvi *.log *.aux *.ps $(API_GUIDE)
+
+include $(srcdir)/../rules.make
+
diff --git a/doc/c_api.tex b/doc/c_api.tex
new file mode 100644
index 0000000..9e1b1ef
--- /dev/null
+++ b/doc/c_api.tex
@@ -0,0 +1,203 @@
+%
+% DATASET FUNCTIONS
+%
+\subsection*{A.1 Dataset Functions}
+
+\begin{verbatim}
+int ncmpi_create(MPI_Comm comm, const char *path, int cmode, MPI_Info info, int *ncidp);
+
+int ncmpi_open(MPI_Comm comm, const char *path, int omode, MPI_Info info, int *ncidp);
+
+int ncmpi_enddef(int ncid);
+
+int ncmpi_redef(int ncid);
+
+int ncmpi_get_file_info(int ncid, MPI_Info *info_used);
+
+int ncmpi_sync(int ncid);
+
+int ncmpi_abort(int ncid);
+
+int ncmpi_begin_indep_data(int ncid);
+
+int ncmpi_end_indep_data(int ncid);
+
+int ncmpi_close(int ncid);
+\end{verbatim}
+
+% ncmpi_set_fill has not yet implemented
+% int ncmpi_set_fill(int ncid, int fillmode, int *old_modep);
+
+%
+% DEFINE FUNCTIONS
+%
+\subsection*{A.2 Define Mode Functions}
+
+\begin{verbatim}
+int ncmpi_def_dim(int ncid, const char *name, MPI_Offset len, int *idp);
+
+int ncmpi_def_var(int ncid, const char *name, nc_type xtype, int ndims,
+ const int *dimidsp, int *varidp);
+
+int ncmpi_rename_dim(int ncid, int dimid, const char *name);
+
+int ncmpi_rename_var(int ncid, int varid, const char *name);
+\end{verbatim}
+
+%
+% INQUIRY FUNCTIONS
+%
+\subsection*{A.3 Inquiry Functions}
+
+\begin{verbatim}
+int ncmpi_inq(int ncid, int *ndimsp, int *nvarsp, int *ngattsp, int *unlimdimidp);
+
+int ncmpi_inq_ndims(int ncid, int *ndimsp);
+
+int ncmpi_inq_nvars(int ncid, int *nvarsp);
+
+int ncmpi_inq_natts(int ncid, int *ngattsp);
+
+int ncmpi_inq_unlimdim(int ncid, int *unlimdimidp);
+
+int ncmpi_inq_dimid(int ncid, const char *name, int *idp);
+
+int ncmpi_inq_dim(int ncid, int dimid, char *name, MPI_Offset *lenp);
+
+int ncmpi_inq_dimname(int ncid, int dimid, char *name);
+
+int ncmpi_inq_dimlen(int ncid, int dimid, MPI_Offset *lenp);
+
+int ncmpi_inq_var(int ncid, int varid, char *name, nc_type *xtypep,
+ int *ndimsp, int *dimidsp, int *nattsp);
+
+int ncmpi_inq_varid(int ncid, const char *name, int *varidp);
+
+int ncmpi_inq_varname(int ncid, int varid, char *name);
+
+int ncmpi_inq_vartype(int ncid, int varid, nc_type *xtypep);
+
+int ncmpi_inq_varndims(int ncid, int varid, int *ndimsp);
+
+int ncmpi_inq_vardimid(int ncid, int varid, int *dimidsp);
+
+int ncmpi_inq_varnatts(int ncid, int varid, int *nattsp);
+
+\end{verbatim}
+
+%
+% ATTRIBUTE FUNCTIONS
+%
+\subsection*{A.4 Attribute Functions}
+
+\begin{verbatim}
+int ncmpi_inq_att(int ncid, int varid, const char *name, nc_type *xtypep,
+ MPI_Offset *lenp);
+
+int ncmpi_inq_attid(int ncid, int varid, const char *name, int *idp);
+
+int ncmpi_inq_atttype(int ncid, int varid, const char *name, nc_type *xtypep);
+
+int ncmpi_inq_attlen(int ncid, int varid, const char *name, MPI_Offset *lenp);
+
+int ncmpi_inq_attname(int ncid, int varid, int attnum, char *name);
+
+int ncmpi_copy_att(int ncid_in, int varid_in, const char *name, int ncid_out,
+ int varid_out);
+
+int ncmpi_rename_att(int ncid, int varid, const char *name, const char *newname);
+
+int ncmpi_del_att(int ncid, int varid, const char *name);
+
+int ncmpi_put_att_text(int ncid, int varid, const char *name, MPI_Offset len,
+ const char *op);
+
+int ncmpi_get_att_text(int ncid, int varid, const char *name, char *ip);
+
+int ncmpi_put_att_uchar(int ncid, int varid, const char *name, nc_type xtype,
+ MPI_Offset len, const unsigned char *op);
+
+int ncmpi_get_att_uchar(int ncid, int varid, const char *name, unsigned char *ip);
+
+int ncmpi_put_att_schar(int ncid, int varid, const char *name, nc_type xtype,
+ MPI_Offset len, const signed char *op);
+
+int ncmpi_get_att_schar(int ncid, int varid, const char *name, signed char *ip);
+
+int ncmpi_put_att_short(int ncid, int varid, const char *name, nc_type xtype,
+ MPI_Offset len, const short *op);
+
+int ncmpi_get_att_short(int ncid, int varid, const char *name, short *ip);
+
+int ncmpi_put_att_int(int ncid, int varid, const char *name, nc_type xtype,
+ MPI_Offset len, const int *op);
+
+int ncmpi_get_att_int(int ncid, int varid, const char *name, int *ip);
+
+int ncmpi_put_att_long(int ncid, int varid, const char *name,
+ nc_type xtype, MPI_Offset len, const long *op);
+
+int ncmpi_get_att_long(int ncid, int varid, const char *name, long *ip);
+
+int ncmpi_put_att_float(int ncid, int varid, const char *name,
+ nc_type xtype, MPI_Offset len, const float *op);
+
+int ncmpi_get_att_float(int ncid, int varid, const char *name, float *ip);
+
+int ncmpi_put_att_double(int ncid, int varid, const char *name, nc_type xtype,
+ MPI_Offset len, const double *op);
+
+int ncmpi_get_att_double(int ncid, int varid, const char *name, double *ip);
+\end{verbatim}
+
+%
+% DATA FUNCTIONS
+%
+\subsection*{A.5 Data Mode Functions}
+
+Recall that the data mode functions are split into the High Level data mode interface and the
+Flexible data mode interface.
+
+\subsubsection*{A.5.1 High Level Data Mode Interface}
+
+The High Level functions most closely mimic the original NetCDF data mode interface.
+
+% \emph{What about the single variable and varm functions? Are they important?}
+
+\input data_mode_api
+
+\subsubsection*{A.5.2 Flexible Data Mode Interface}
+
+Note that there are considerably fewer functions in the flexible data mode
+inteface, because these functions can handle all different types with the same
+call. All of the high level functions are written in terms of these
+functions.
+
+\input flexible_api
+
+\subsubsection*{A.5.3 Multiple Variable Data Mode Interface}
+
+\input multiple_io
+
+\subsubsection*{A.5.4 Nonblocking Data Mode Interface}
+
+\input nonblocking
+
+\subsubsection*{A.6 Other Utility Interface}
+
+\begin{verbatim}
+const char* ncmpi_strerror(int err);
+
+int ncmpi_delete(char *filename, MPI_Info info);
+
+int ncmpi_set_default_format(int format, int *old_formatp);
+
+const char* ncmpi_inq_libvers(void);
+
+int ncmpi_inq_format(int ncid, int *formatp);
+
+int ncmpi_inq_file_format(char *filename, int *formatp);
+
+int ncmpi_inq_version(int ncid, int *NC_mode);
+\end{verbatim}
+
diff --git a/doc/data_mode_api.tex b/doc/data_mode_api.tex
new file mode 100644
index 0000000..1ec38da
--- /dev/null
+++ b/doc/data_mode_api.tex
@@ -0,0 +1,513 @@
+{\bf ncmpi\_put\_var1\_TYPE()}: Write a Single Data Value
+
+\begin{verbatim}
+int ncmpi_put_var1_schar(int ncid, int varid, const MPI_Offset index[],
+ const signed char *op);
+
+int ncmpi_put_var1_text(int ncid, int varid, const MPI_Offset index[],
+ const char *op);
+
+int ncmpi_put_var1_short(int ncid, int varid, const MPI_Offset index[],
+ const short *op);
+
+int ncmpi_put_var1_int(int ncid, int varid, const MPI_Offset index[],
+ const int *op);
+
+int ncmpi_put_var1_uchar(int ncid, int varid, const MPI_Offset index[],
+ const unsigned char *op);
+
+int ncmpi_put_var1_long(int ncid, int varid, const MPI_Offset index[],
+ const long *ip);
+
+int ncmpi_put_var1_float(int ncid, int varid, const MPI_Offset index[],
+ const float *op);
+
+int ncmpi_put_var1_double(int ncid, int varid, const MPI_Offset index[],
+ const double *op);
+\end{verbatim}
+
+
+{\bf ncmpi\_get\_var1\_TYPE()}: Read a Single Data Value
+
+\begin{verbatim}
+int ncmpi_get_var1_schar(int ncid, int varid, const MPI_Offset index[],
+ signed char *ip);
+
+int ncmpi_get_var1_text(int ncid, int varid, const MPI_Offset index[],
+ char *ip);
+
+int ncmpi_get_var1_short(int ncid, int varid, const MPI_Offset index[],
+ short *ip);
+
+int ncmpi_get_var1_int(int ncid, int varid, const MPI_Offset index[],
+ int *ip);
+
+int ncmpi_get_var1_uchar(int ncid, int varid, const MPI_Offset index[],
+ unsigned char *ip);
+
+int ncmpi_get_var1_long(int ncid, int varid, const MPI_Offset index[],
+ long *ip);
+
+int ncmpi_get_var1_float(int ncid, int varid, const MPI_Offset index[],
+ float *ip);
+
+int ncmpi_get_var1_double(int ncid, int varid, const MPI_Offset index[],
+ double *ip);
+\end{verbatim}
+
+
+{\bf ncmpi\_put\_var\_TYPE()}: Write an Entire Variable
+
+\begin{verbatim}
+int ncmpi_put_var_schar(int ncid, int varid, const signed char *op);
+
+int ncmpi_put_var_schar_all(int ncid, int varid, const signed char *op);
+
+int ncmpi_put_var_text(int ncid, int varid, const char *op);
+
+int ncmpi_put_var_text_all(int ncid, int varid, const char *op);
+
+int ncmpi_put_var_short(int ncid, int varid, const short *op);
+
+int ncmpi_put_var_short_all(int ncid, int varid, const short *op);
+
+int ncmpi_put_var_int(int ncid, int varid, const int *op);
+
+int ncmpi_put_var_int_all(int ncid, int varid, const int *op);
+
+int ncmpi_put_var_uchar(int ncid, int varid, const unsigned char *op);
+
+int ncmpi_put_var_uchar_all(int ncid, int varid, const unsigned char *op);
+
+int ncmpi_put_var_long(int ncid, int varid, const long *op);
+
+int ncmpi_put_var_long_all(int ncid, int varid, const long *op);
+
+int ncmpi_put_var_float(int ncid, int varid, const float *op);
+
+int ncmpi_put_var_float_all(int ncid, int varid, const float *op);
+
+int ncmpi_put_var_double(int ncid, int varid, const double *op);
+
+int ncmpi_put_var_double_all(int ncid, int varid, const double *op);
+
+\end{verbatim}
+
+
+{\bf ncmpi\_get\_var\_TYPE()}: Read an Entire Variable
+
+\begin{verbatim}
+int ncmpi_get_var_schar(int ncid, int varid, signed char *ip);
+
+int ncmpi_get_var_schar_all(int ncid, int varid, signed char *ip);
+
+int ncmpi_get_var_text(int ncid, int varid, char *ip);
+
+int ncmpi_get_var_text_all(int ncid, int varid, char *ip);
+
+int ncmpi_get_var_short(int ncid, int varid, short *ip);
+
+int ncmpi_get_var_short_all(int ncid, int varid, short *ip);
+
+int ncmpi_get_var_int(int ncid, int varid, int *ip);
+
+int ncmpi_get_var_int_all(int ncid, int varid, int *ip);
+
+int ncmpi_get_var_uchar(int ncid, int varid, unsigned char *ip);
+
+int ncmpi_get_var_uchar_all(int ncid, int varid, unsigned char *ip);
+
+int ncmpi_get_var_long(int ncid, int varid, long *ip);
+
+int ncmpi_get_var_long_all(int ncid, int varid, long *ip);
+
+int ncmpi_get_var_float(int ncid, int varid, float *ip);
+
+int ncmpi_get_var_float_all(int ncid, int varid, float *ip);
+
+int ncmpi_get_var_double(int ncid, int varid, double *ip);
+
+int ncmpi_get_var_double_all(int ncid, int varid, double *ip);
+\end{verbatim}
+
+
+{\bf ncmpi\_put\_vara\_TYPE()}: Write an Array of Values
+
+\begin{verbatim}
+int ncmpi_put_vara_schar(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const signed char *op);
+
+int ncmpi_put_vara_schar_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const signed char *op);
+
+int ncmpi_put_vara_text(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const char *op);
+
+int ncmpi_put_vara_text_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const char *op);
+
+int ncmpi_put_vara_short(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const short *op);
+
+int ncmpi_put_vara_short_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const short *op);
+
+int ncmpi_put_vara_int(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const int *op);
+
+int ncmpi_put_vara_int_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const int *op);
+
+int ncmpi_put_vara_uchar(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const unsigned char *op);
+
+int ncmpi_put_vara_uchar_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const unsigned char *op);
+
+int ncmpi_put_vara_long(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const long *op);
+
+int ncmpi_put_vara_long_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const long *op);
+
+int ncmpi_put_vara_float(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const float *op);
+
+int ncmpi_put_vara_float_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const float *op);
+
+int ncmpi_put_vara_double(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const double *op);
+
+int ncmpi_put_vara_double_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const double *op);
+\end{verbatim}
+
+
+{\bf ncmpi\_get\_vara\_TYPE()}: Read an Array of Values
+
+\begin{verbatim}
+int ncmpi_get_vara_schar(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], signed char *ip);
+
+int ncmpi_get_vara_schar_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], signed char *ip);
+
+int ncmpi_get_vara_text(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], char *ip);
+
+int ncmpi_get_vara_text_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], char *ip);
+
+int ncmpi_get_vara_short(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], short *ip);
+
+int ncmpi_get_vara_short_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], short *ip);
+
+int ncmpi_get_vara_int(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], int *ip);
+
+int ncmpi_get_vara_int_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], int *ip);
+
+int ncmpi_get_vara_uchar(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], unsigned char *ip);
+
+int ncmpi_get_vara_uchar_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], unsigned char *ip);
+
+int ncmpi_get_vara_long(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], long *ip);
+
+int ncmpi_get_vara_long_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], long *ip);
+
+int ncmpi_get_vara_float(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], float *ip);
+
+int ncmpi_get_vara_float_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], float *ip);
+
+int ncmpi_get_vara_double(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], double *ip);
+
+int ncmpi_get_vara_double_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], double *ip);
+\end{verbatim}
+
+
+{\bf ncmpi\_put\_vars\_TYPE()}: Write a Subsampled Array of Values
+
+\begin{verbatim}
+int ncmpi_put_vars_schar(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const signed char *op);
+
+int ncmpi_put_vars_schar_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const signed char *op);
+
+int ncmpi_put_vars_text(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const char *op);
+
+int ncmpi_put_vars_text_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const char *op);
+
+int ncmpi_put_vars_short(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const short *op);
+
+int ncmpi_put_vars_short_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const short *op);
+
+int ncmpi_put_vars_int(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const int *op);
+
+int ncmpi_put_vars_int_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const int *op);
+
+int ncmpi_put_vars_uchar(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const unsigned char *op);
+
+int ncmpi_put_vars_uchar_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const unsigned char *op);
+
+int ncmpi_put_vars_long(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const long *op);
+
+int ncmpi_put_vars_long_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const long *op);
+
+int ncmpi_put_vars_float(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const float *op);
+
+int ncmpi_put_vars_float_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const float *op);
+
+int ncmpi_put_vars_double(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const double *op);
+
+int ncmpi_put_vars_double_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const double *op);
+\end{verbatim}
+
+
+{\bf ncmpi\_get\_vars\_TYPE()}: Read a Subsampled Array of Values
+
+\begin{verbatim}
+int ncmpi_get_vars_schar(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ signed char *ip);
+
+int ncmpi_get_vars_schar_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ signed char *ip);
+
+int ncmpi_get_vars_text(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ char *ip);
+
+int ncmpi_get_vars_text_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ char *ip);
+
+int ncmpi_get_vars_short(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ short *ip);
+
+int ncmpi_get_vars_short_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ short *ip);
+
+int ncmpi_get_vars_int(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ int *ip);
+
+int ncmpi_get_vars_int_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ int *ip);
+
+int ncmpi_get_vars_uchar(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ unsigned char *ip);
+
+int ncmpi_get_vars_uchar_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ unsigned char *ip);
+
+int ncmpi_get_vars_long(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ long *ip);
+
+int ncmpi_get_vars_long_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ long *ip);
+
+int ncmpi_get_vars_float(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ float *ip);
+
+int ncmpi_get_vars_float_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ float *ip);
+
+int ncmpi_get_vars_double(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ double *ip);
+
+int ncmpi_get_vars_double_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ double *ip);
+\end{verbatim}
+
+
+{\bf ncmpi\_put\_varm\_TYPE()}: Write a Mapped Array of Values
+
+\begin{verbatim}
+int ncmpi_put_varm_schar(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], const signed char *op);
+
+int ncmpi_put_varm_schar_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], const signed char *op);
+
+int ncmpi_put_varm_text(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], const char *op);
+
+int ncmpi_put_varm_text_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], const char *op);
+
+int ncmpi_put_varm_short(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], const short *op);
+
+int ncmpi_put_varm_short_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], const short *op);
+
+int ncmpi_put_varm_int(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], const int *op);
+
+int ncmpi_put_varm_int_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], const int *op);
+
+int ncmpi_put_varm_uchar(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], const unsigned char *op);
+
+int ncmpi_put_varm_uchar_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], const unsigned char *op);
+
+int ncmpi_put_varm_long(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], const long *op);
+
+int ncmpi_put_varm_long_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], const long *op);
+
+int ncmpi_put_varm_float(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], const float *op);
+
+int ncmpi_put_varm_float_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], const float *op);
+
+int ncmpi_put_varm_double(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], const double *op);
+
+int ncmpi_put_varm_double_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], const double *op);
+\end{verbatim}
+
+
+{\bf ncmpi\_get\_varm\_TYPE()}: Read a Mapped Array of Values
+
+\begin{verbatim}
+int ncmpi_get_varm_schar(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], signed char *ip);
+
+int ncmpi_get_varm_schar_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], signed char *ip);
+
+int ncmpi_get_varm_text(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], char *ip);
+
+int ncmpi_get_varm_text_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], char *ip);
+
+int ncmpi_get_varm_short(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], short *ip);
+
+int ncmpi_get_varm_short_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], short *ip);
+
+int ncmpi_get_varm_int(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], int *ip);
+
+int ncmpi_get_varm_int_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], int *ip);
+
+int ncmpi_get_varm_uchar(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], unsigned char *ip);
+
+int ncmpi_get_varm_uchar_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], unsigned char *ip);
+
+int ncmpi_get_varm_long(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], long *ip);
+
+int ncmpi_get_varm_long_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], long *ip);
+
+int ncmpi_get_varm_float(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], float *ip);
+
+int ncmpi_get_varm_float_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], float *ip);
+
+int ncmpi_get_varm_double(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], double *ip);
+
+int ncmpi_get_varm_double_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], double *ip);
+\end{verbatim}
diff --git a/doc/flexible_api.tex b/doc/flexible_api.tex
new file mode 100644
index 0000000..ddd5deb
--- /dev/null
+++ b/doc/flexible_api.tex
@@ -0,0 +1,73 @@
+\begin{verbatim}
+int ncmpi_put_var1(int ncid, int varid, const MPI_Offset index[],
+ const void *buf, MPI_Offset bufcount, MPI_Datatype datatype);
+
+int ncmpi_get_var1(int ncid, int varid, const MPI_Offset index[],
+ void *buf, MPI_Offset bufcount, MPI_Datatype datatype);
+
+int ncmpi_put_var(int ncid, int varid, const void *buf, MPI_Offset bufcount,
+ MPI_Datatype datatype);
+
+int ncmpi_put_var_all(int ncid, int varid, const void *buf, MPI_Offset bufcount,
+ MPI_Datatype datatype);
+
+int ncmpi_get_var(int ncid, int varid, void *buf, MPI_Offset bufcount,
+ MPI_Datatype datatype);
+
+int ncmpi_get_var_all(int ncid, int varid, void *buf, MPI_Offset bufcount,
+ MPI_Datatype datatype);
+
+int ncmpi_put_vara(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const void *buf,
+ MPI_Offset bufcount, MPI_Datatype datatype);
+int ncmpi_put_vara_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const void *buf,
+ MPI_Offset bufcount, MPI_Datatype datatype);
+
+int ncmpi_get_vara(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], void *buf, MPI_Offset bufcount,
+ MPI_Datatype datatype);
+
+int ncmpi_get_vara_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], void *buf, MPI_Offset bufcount,
+ MPI_Datatype datatype);
+
+int ncmpi_put_vars(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const void *buf, MPI_Offset bufcount,
+ MPI_Datatype datatype);
+
+int ncmpi_put_vars_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const void *buf, MPI_Offset bufcount,
+ MPI_Datatype datatype);
+
+int ncmpi_get_vars(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ void *buf, MPI_Offset bufcount, MPI_Datatype datatype);
+
+int ncmpi_get_vars_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ void *buf, MPI_Offset bufcount, MPI_Datatype datatype);
+
+int ncmpi_put_varm(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], const void *buf,
+ MPI_Offset bufcount, MPI_Datatype datatype);
+
+int ncmpi_put_varm_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], const void *buf,
+ MPI_Offset bufcount, MPI_Datatype datatype);
+
+int ncmpi_get_varm(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], void *buf, MPI_Offset bufcount,
+ MPI_Datatype datatype);
+
+int ncmpi_get_varm_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], void *buf, MPI_Offset bufcount,
+ MPI_Datatype datatype);
+\end{verbatim}
+
diff --git a/doc/latex8.sty b/doc/latex8.sty
new file mode 100644
index 0000000..c9e4df3
--- /dev/null
+++ b/doc/latex8.sty
@@ -0,0 +1,175 @@
+% ---------------------------------------------------------------
+%
+% $Id: latex8.sty 93 2003-04-14 15:00:43Z robl $
+%
+% by Paolo.Ienne at di.epfl.ch
+%
+% ---------------------------------------------------------------
+%
+% no guarantee is given that the format corresponds perfectly to
+% IEEE 8.5" x 11" Proceedings, but most features should be ok.
+%
+% ---------------------------------------------------------------
+% with LaTeX2e:
+% =============
+%
+% use as
+% \documentclass[10pt,twocolumn]{article}
+% \usepackage{latex8}
+% \usepackage{times}
+%
+% ---------------------------------------------------------------
+
+% with LaTeX 2.09:
+% ================
+%
+% use as
+% \documentstyle[times,twocolumn,latex8]{article}
+%
+% ---------------------------------------------------------------
+% with both versions:
+% ===================
+%
+% specify \pagestyle{empty} to omit page numbers in the final
+% version
+%
+% specify references as
+% \bibliographystyle{latex8}
+% \bibliography{...your files...}
+%
+% use Section{} and SubSection{} instead of standard section{}
+% and subsection{} to obtain headings in the form
+% "1.3. My heading"
+%
+% ---------------------------------------------------------------
+
+\typeout{IEEE 8.5 x 11-Inch Proceedings Style `latex8.sty'.}
+
+% ten point helvetica bold required for captions
+% in some sites the name of the helvetica bold font may differ,
+% change the name here:
+\font\tenhv = phvb at 10pt
+%\font\tenhv = phvb7t at 10pt
+
+% eleven point times bold required for second-order headings
+% \font\elvbf = cmbx10 scaled 1100
+\font\elvbf = ptmb scaled 1100
+
+% set dimensions of columns, gap between columns, and paragraph indent
+\setlength{\textheight}{8.875in}
+\setlength{\textwidth}{6.875in}
+\setlength{\columnsep}{0.3125in}
+\setlength{\topmargin}{0in}
+\setlength{\headheight}{0in}
+\setlength{\headsep}{0in}
+\setlength{\parindent}{1pc}
+\setlength{\oddsidemargin}{-.19in}
+\setlength{\evensidemargin}{-.19in}
+%\setlength{\evensidemargin}{-.304in}
+
+% memento from size10.clo
+% \normalsize{\@setfontsize\normalsize\@xpt\@xiipt}
+% \small{\@setfontsize\small\@ixpt{11}}
+% \footnotesize{\@setfontsize\footnotesize\@viiipt{9.5}}
+% \scriptsize{\@setfontsize\scriptsize\@viipt\@viiipt}
+% \tiny{\@setfontsize\tiny\@vpt\@vipt}
+% \large{\@setfontsize\large\@xiipt{14}}
+% \Large{\@setfontsize\Large\@xivpt{18}}
+% \LARGE{\@setfontsize\LARGE\@xviipt{22}}
+% \huge{\@setfontsize\huge\@xxpt{25}}
+% \Huge{\@setfontsize\Huge\@xxvpt{30}}
+
+\def\@maketitle
+ {
+ \newpage
+ \null
+ \vskip .375in
+ \begin{center}
+ {\Large \bf \@title \par}
+ % additional two empty lines at the end of the title
+ \vspace*{24pt}
+ {
+ \large
+ \lineskip .5em
+ \begin{tabular}[t]{c}
+ \@author
+ \end{tabular}
+ \par
+ }
+ % additional small space at the end of the author name
+ \vskip .5em
+ {
+ \large
+ \begin{tabular}[t]{c}
+ \@affiliation
+ \end{tabular}
+ \par
+ \ifx \@empty \@email
+ \else
+ \begin{tabular}{r@{~}l}
+ E-mail: & {\tt \@email}
+ \end{tabular}
+ \par
+ \fi
+ }
+ % additional empty line at the end of the title block
+ \vspace*{12pt}
+ \end{center}
+ }
+
+\def\abstract
+ {%
+ \centerline{\large\bf Abstract}%
+ \vspace*{12pt}%
+ \it%
+ }
+
+\def\endabstract
+ {
+ % additional empty line at the end of the abstract
+ \vspace*{12pt}
+ }
+
+\def\affiliation#1{\gdef\@affiliation{#1}} \gdef\@affiliation{}
+
+\def\email#1{\gdef\@email{#1}}
+\gdef\@email{}
+
+\newlength{\@ctmp}
+\newlength{\@figindent}
+\setlength{\@figindent}{1pc}
+
+\long\def\@makecaption#1#2{
+ \vskip 10pt
+ \setbox\@tempboxa\hbox{\tenhv\noindent #1.~#2}
+ \setlength{\@ctmp}{\hsize}
+ \addtolength{\@ctmp}{-\@figindent}\addtolength{\@ctmp}{-\@figindent}
+ % IF longer than one indented paragraph line
+ \ifdim \wd\@tempboxa >\@ctmp
+ % THEN set as an indented paragraph
+ \begin{list}{}{\leftmargin\@figindent \rightmargin\leftmargin}
+ \item[]\tenhv #1.~#2\par
+ \end{list}
+ \else
+ % ELSE center
+ \hbox to\hsize{\hfil\box\@tempboxa\hfil}
+ \fi}
+
+% correct heading spacing and type
+\def\section{\@startsection {section}{1}{\z@}
+ {14pt plus 1pt minus 1pt}{14pt plus 1pt minus 1pt} {\large\bf}}
+\def\subsection{\@startsection {subsection}{2}{\z@}
+ {13pt plus 1pt minus 1pt}{13pt plus 1pt minus 1pt} {\elvbf}}
+\def\subsubsection{\@startsection {subsubsection}{3}{\z@}{12pt plus 1pt minus 1pt}
+{12pt plus 1pt minus 1pt}{\normalsize\bf}}
+\def\subsubsubsection{\@startsection {paragraph}{3}{\z@}{11pt plus 1pt minus 1pt}
+{11pt plus 1pt minus 1pt}{\small\bf}}
+
+% add the period after section numbers
+\newcommand{\Section}[1]{\section{\hskip -1em.~#1}}
+\newcommand{\SubSection}[1]{\subsection{\hskip -1em.~#1}}
+\newcommand{\SubSubSection}[1]{\subsubsection{\hskip -1em.~#1}}
+\newcommand{\SubSubSubSection}[1]{\subsubsubsection{\hskip -1em.~#1}}
+
+% end of file latex8.sty
+% ---------------------------------------------------------------
diff --git a/doc/multiple_io.tex b/doc/multiple_io.tex
new file mode 100644
index 0000000..66ab26e
--- /dev/null
+++ b/doc/multiple_io.tex
@@ -0,0 +1,152 @@
+{\bf ncmpi\_mput\_var1()}: Write Multiple Single Data Values
+
+\begin{verbatim}
+int ncmpi_mput_var1(int ncid, int ntimes, int varids[],
+ MPI_Offset* const starts[],
+ void *bufs[], MPI_Offset bufcounts[],
+ MPI_Datatype datatypes[]);
+
+int ncmpi_mput_var1_all(int ncid, int ntimes, int varids[],
+ MPI_Offset* const starts[],
+ void *bufs[], MPI_Offset bufcounts[],
+ MPI_Datatype datatypes[]);
+\end{verbatim}
+
+
+{\bf ncmpi\_mget\_var1()}: Read Multiple Single Data Values
+
+\begin{verbatim}
+int ncmpi_mget_var1(int ncid, int ntimes, int varids[],
+ MPI_Offset* const starts[],
+ void *bufs[], MPI_Offset bufcounts[],
+ MPI_Datatype datatypes[]);
+
+int ncmpi_mget_var1_all(int ncid, int ntimes, int varids[],
+ MPI_Offset* const starts[],
+ void *bufs[], MPI_Offset bufcounts[],
+ MPI_Datatype datatypes[]);
+\end{verbatim}
+
+
+{\bf ncmpi\_mput\_var()}: Write Multiple Entire Variables
+
+\begin{verbatim}
+int ncmpi_mput_var(int ncid, int ntimes, int varids[],
+ void *bufs[], MPI_Offset bufcounts[],
+ MPI_Datatype datatypes[]);
+
+int ncmpi_mput_var_all(int ncid, int ntimes, int varids[],
+ void *bufs[], MPI_Offset bufcounts[],
+ MPI_Datatype datatypes[]);
+\end{verbatim}
+
+
+{\bf ncmpi\_mget\_var()}: Read Multiple Entire Variables
+
+\begin{verbatim}
+int ncmpi_mget_var(int ncid, int ntimes, int varids[],
+ void *bufs[], MPI_Offset bufcounts[],
+ MPI_Datatype datatypes[]);
+
+int ncmpi_mget_var_all(int ncid, int ntimes, int varids[],
+ void *bufs[], MPI_Offset bufcounts[],
+ MPI_Datatype datatypes[]);
+\end{verbatim}
+
+
+{\bf ncmpi\_mput\_vara()}: Write Multiple Arrays of Values
+
+\begin{verbatim}
+int ncmpi_mput_vara(int ncid, int ntimes, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ void *bufs[], MPI_Offset bufcounts[],
+ MPI_Datatype datatypes[]);
+
+int ncmpi_mput_vara_all(int ncid, int ntimes, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ void *bufs[], MPI_Offset bufcounts[],
+ MPI_Datatype datatypes[]);
+\end{verbatim}
+
+
+{\bf ncmpi\_mget\_vara()}: Read Multiple Arrays of Values
+
+\begin{verbatim}
+int ncmpi_mget_vara(int ncid, int ntimes, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ void *bufs[], MPI_Offset bufcounts[],
+ MPI_Datatype datatypes[]);
+
+int ncmpi_mget_vara_all(int ncid, int ntimes, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ void *bufs[], MPI_Offset bufcounts[],
+ MPI_Datatype datatypes[]);
+\end{verbatim}
+
+
+{\bf ncmpi\_mput\_vars()}: Write Multiple Subsampled Arrays of Values
+
+\begin{verbatim}
+int ncmpi_mput_vars(int ncid, int ntimes, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[],
+ void *bufs[], MPI_Offset bufcounts[],
+ MPI_Datatype datatypes[]);
+
+int ncmpi_mput_vars_all(int ncid, int ntimes, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[],
+ void *bufs[], MPI_Offset bufcounts[],
+ MPI_Datatype datatypes[]);
+\end{verbatim}
+
+
+{\bf ncmpi\_mget\_vars()}: Read Multiple Subsampled Arrays of Values
+
+\begin{verbatim}
+int ncmpi_mget_vars(int ncid, int ntimes, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[],
+ void *bufs[], MPI_Offset bufcounts[],
+ MPI_Datatype datatypes[]);
+
+int ncmpi_mget_vars_all(int ncid, int ntimes, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[],
+ void *bufs[], MPI_Offset bufcounts[],
+ MPI_Datatype datatypes[]);
+\end{verbatim}
+
+
+{\bf ncmpi\_mput\_varm()}: Write Multiple Mapped Arrays of Values
+
+\begin{verbatim}
+int ncmpi_mput_varm(int ncid, int ntimes, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], MPI_Offset* const imaps[],
+ void *bufs[], MPI_Offset bufcounts[],
+ MPI_Datatype datatypes[]);
+
+int ncmpi_mput_varm_all(int ncid, int ntimes, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], MPI_Offset* const imaps[],
+ void *bufs[], MPI_Offset bufcounts[],
+ MPI_Datatype datatypes[]);
+\end{verbatim}
+
+
+{\bf ncmpi\_mget\_varm()}: Read Multiple Mapped Arrays of Values
+
+\begin{verbatim}
+int ncmpi_mget_varm(int ncid, int ntimes, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], MPI_Offset* const imaps[],
+ void *bufs[], MPI_Offset bufcounts[],
+ MPI_Datatype datatypes[]);
+
+int ncmpi_mget_varm_all(int ncid, int ntimes, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], MPI_Offset* const imaps[],
+ void *bufs[], MPI_Offset bufcounts[],
+ MPI_Datatype datatypes[]);
+\end{verbatim}
diff --git a/doc/nonblocking.tex b/doc/nonblocking.tex
new file mode 100644
index 0000000..4efac66
--- /dev/null
+++ b/doc/nonblocking.tex
@@ -0,0 +1,362 @@
+\begin{verbatim}
+int ncmpi_wait(int ncid, int count, int array_of_requests[],
+ int array_of_statuses[]);
+
+int ncmpi_wait_all(int ncid, int count, int array_of_requests[],
+ int array_of_statuses[]);
+
+int ncmpi_cancel(int ncid, int num, int *requests, int *statuses);
+\end{verbatim}
+
+
+{\bf ncmpi\_iput\_var1\_TYPE()}: Post a Nonblocking Write for a Single Data Value
+
+\begin{verbatim}
+int ncmpi_iput_var1(int ncid, int varid, const MPI_Offset index[],
+ const void *buf, MPI_Offset bufcount,
+ MPI_Datatype datatype, int *request);
+
+int ncmpi_iput_var1_schar(int ncid, int varid, const MPI_Offset index[],
+ const signed char *op, int *request);
+
+int ncmpi_iput_var1_text(int ncid, int varid, const MPI_Offset index[],
+ const char *op, int *request);
+
+int ncmpi_iput_var1_short(int ncid, int varid, const MPI_Offset index[],
+ const short *op, int *request);
+
+int ncmpi_iput_var1_int(int ncid, int varid, const MPI_Offset index[],
+ const int *op, int *request);
+
+int ncmpi_iput_var1_uchar(int ncid, int varid, const MPI_Offset index[],
+ const unsigned char *op, int *request);
+
+int ncmpi_iput_var1_long(int ncid, int varid, const MPI_Offset index[],
+ const long *ip, int *request);
+
+int ncmpi_iput_var1_float(int ncid, int varid, const MPI_Offset index[],
+ const float *op, int *request);
+
+int ncmpi_iput_var1_double(int ncid, int varid, const MPI_Offset index[],
+ const double *op, int *request);
+\end{verbatim}
+
+
+{\bf ncmpi\_iget\_var1\_TYPE()}: Post a Nonblocking Read for a Single Data Value
+
+\begin{verbatim}
+int ncmpi_iget_var1(int ncid, int varid, const MPI_Offset index[], void *buf,
+ MPI_Offset bufcount, MPI_Datatype datatype, int *request);
+
+int ncmpi_iget_var1_schar(int ncid, int varid, const MPI_Offset index[],
+ signed char *ip, int *request);
+
+int ncmpi_iget_var1_text(int ncid, int varid, const MPI_Offset index[],
+ char *ip, int *request);
+
+int ncmpi_iget_var1_short(int ncid, int varid, const MPI_Offset index[],
+ short *ip, int *request);
+
+int ncmpi_iget_var1_int(int ncid, int varid, const MPI_Offset index[],
+ int *ip, int *request);
+
+int ncmpi_iget_var1_uchar(int ncid, int varid, const MPI_Offset index[],
+ unsigned char *ip, int *request);
+
+int ncmpi_iget_var1_long(int ncid, int varid, const MPI_Offset index[],
+ long *ip, int *request);
+
+int ncmpi_iget_var1_float(int ncid, int varid, const MPI_Offset index[],
+ float *ip, int *request);
+
+int ncmpi_iget_var1_double(int ncid, int varid, const MPI_Offset index[],
+ double *ip, int *request);
+\end{verbatim}
+
+
+{\bf ncmpi\_iput\_var\_TYPE()}: Post a Nonblocking Write for an Entire Variable
+
+\begin{verbatim}
+int ncmpi_iput_var(int ncid, int varid, const void *buf, MPI_Offset bufcount,
+ MPI_Datatype datatype, int *request);
+
+int ncmpi_iput_var_schar(int ncid, int varid, const signed char *op,
+ int *request);
+
+int ncmpi_iput_var_text(int ncid, int varid, const char *op, int *request);
+
+int ncmpi_iput_var_short(int ncid, int varid, const short *op, int *request);
+
+int ncmpi_iput_var_int(int ncid, int varid, const int *op, int *request);
+
+int ncmpi_iput_var_uchar(int ncid, int varid, const unsigned char *op,
+ int *request);
+
+int ncmpi_iput_var_long(int ncid, int varid, const long *op, int *request);
+
+int ncmpi_iput_var_float(int ncid, int varid, const float *op, int *request);
+
+int ncmpi_iput_var_double(int ncid, int varid, const double *op, int *request);
+\end{verbatim}
+
+
+{\bf ncmpi\_iget\_var\_TYPE()}: Post a Nonblocking Read for an Entire Variable
+
+\begin{verbatim}
+int ncmpi_iget_var(int ncid, int varid, void *buf, MPI_Offset bufcount,
+ MPI_Datatype datatype, int *request);
+
+int ncmpi_iget_var_schar(int ncid, int varid, signed char *ip, int *request);
+
+int ncmpi_iget_var_text(int ncid, int varid, char *ip, int *request);
+
+int ncmpi_iget_var_short(int ncid, int varid, short *ip, int *request);
+
+int ncmpi_iget_var_int(int ncid, int varid, int *ip, int *request);
+
+int ncmpi_iget_var_uchar(int ncid, int varid, unsigned char *ip, int *request);
+
+int ncmpi_iget_var_long(int ncid, int varid, long *ip, int *request);
+
+int ncmpi_iget_var_float(int ncid, int varid, float *ip, int *request);
+
+int ncmpi_iget_var_double(int ncid, int varid, double *ip, int *request);
+\end{verbatim}
+
+
+{\bf ncmpi\_iput\_vara\_TYPE()}: Post a Nonblocking Write for Array of Values
+
+\begin{verbatim}
+int ncmpi_iput_vara(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const void *buf,
+ MPI_Offset bufcount, MPI_Datatype datatype, int *request);
+
+int ncmpi_iput_vara_schar(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const signed char *op,
+ int *request);
+
+int ncmpi_iput_vara_text(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const char *op, int *request);
+
+int ncmpi_iput_vara_short(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const short *op, int *request);
+
+int ncmpi_iput_vara_int(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const int *op, int *request);
+
+int ncmpi_iput_vara_uchar(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const unsigned char *op,
+ int *request);
+
+int ncmpi_iput_vara_long(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const long *op, int *request);
+
+int ncmpi_iput_vara_float(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const float *op, int *request);
+
+int ncmpi_iput_vara_double(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const double *op, int *request);
+\end{verbatim}
+
+
+{\bf ncmpi\_iget\_vara\_TYPE()}: Post a Nonblocking Read for Array of Values
+
+\begin{verbatim}
+int ncmpi_iget_vara(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], void *buf, MPI_Offset bufcount,
+ MPI_Datatype datatype, int *request);
+
+int ncmpi_iget_vara_schar(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], signed char *ip, int *request);
+
+int ncmpi_iget_vara_text(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], char *ip, int *request);
+
+int ncmpi_iget_vara_short(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], short *ip, int *request);
+
+int ncmpi_iget_vara_int(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], int *ip, int *request);
+
+int ncmpi_iget_vara_uchar(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], unsigned char *ip, int *request);
+
+int ncmpi_iget_vara_long(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], long *ip, int *request);
+
+int ncmpi_iget_vara_float(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], float *ip, int *request);
+
+int ncmpi_iget_vara_double(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], double *ip, int *request);
+\end{verbatim}
+
+
+{\bf ncmpi\_iput\_vars\_TYPE()}: Post a Nonblocking Write for Subsampled Array of Values
+
+\begin{verbatim}
+int ncmpi_iput_vars(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const void *buf, MPI_Offset bufcount,
+ MPI_Datatype datatype, int *request);
+
+int ncmpi_iput_vars_schar(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const signed char *op, int *request);
+
+int ncmpi_iput_vars_text(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const char *op, int *request);
+
+int ncmpi_iput_vars_short(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const short *op, int *request);
+
+int ncmpi_iput_vars_int(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const int *op, int *request);
+
+int ncmpi_iput_vars_uchar(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const unsigned char *op, int *request);
+
+int ncmpi_iput_vars_long(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const long *op, int *request);
+\end{verbatim}
+
+
+{\bf ncmpi\_iget\_vars\_TYPE()}: Post a Nonblocking Read for Subsampled Array of Values
+
+\begin{verbatim}
+int ncmpi_iget_vars(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ void *buf, MPI_Offset bufcount, MPI_Datatype datatype,
+ int *request);
+
+int ncmpi_iput_vars_float(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const float *op, int *request);
+
+int ncmpi_iput_vars_double(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const double *op, int *request);
+
+int ncmpi_iget_vars_schar(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ signed char *ip, int *request);
+
+int ncmpi_iget_vars_text(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ char *ip, int *request);
+
+int ncmpi_iget_vars_short(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ short *ip, int *request);
+
+int ncmpi_iget_vars_int(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ int *ip, int *request);
+
+int ncmpi_iget_vars_uchar(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ unsigned char *ip, int *request);
+
+int ncmpi_iget_vars_long(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ long *ip, int *request);
+
+int ncmpi_iget_vars_float(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ float *ip, int *request);
+
+int ncmpi_iget_vars_double(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ double *ip, int *request);
+\end{verbatim}
+
+
+{\bf ncmpi\_iput\_varm\_TYPE()}: Post a Nonblocking Write for Mapped Array of Values
+
+\begin{verbatim}
+int ncmpi_iput_varm(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], const void *buf,
+ MPI_Offset bufcount, MPI_Datatype datatype, int *request);
+
+int ncmpi_iput_varm_schar(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], const signed char *op,
+ int *request);
+
+int ncmpi_iput_varm_text(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], const char *op, int *request);
+
+int ncmpi_iput_varm_short(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], const short *op, int *request);
+
+int ncmpi_iput_varm_int(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], const int *op, int *request);
+
+int ncmpi_iput_varm_uchar(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], const unsigned char *op,
+ int *request);
+
+int ncmpi_iput_varm_long(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], const long *op, int *request);
+
+int ncmpi_iput_varm_float(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], const float *op, int *request);
+
+int ncmpi_iput_varm_double(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], const double *op, int *request);
+\end{verbatim}
+
+
+{\bf ncmpi\_iget\_varm\_TYPE()}: Post a Nonblocking Read for Mapped Array of Values
+
+\begin{verbatim}
+int ncmpi_iget_varm(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], void *buf, MPI_Offset bufcount,
+ MPI_Datatype datatype, int *request);
+
+int ncmpi_iget_varm_schar(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], signed char *ip, int *request);
+
+int ncmpi_iget_varm_text(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], char *ip, int *request);
+
+int ncmpi_iget_varm_short(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], short *ip, int *request);
+
+int ncmpi_iget_varm_int(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], int *ip, int *request);
+
+int ncmpi_iget_varm_uchar(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], unsigned char *ip, int *request);
+
+int ncmpi_iget_varm_long(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], long *ip, int *request);
+
+int ncmpi_iget_varm_float(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], float *ip, int *request);
+
+int ncmpi_iget_varm_double(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], double *ip, int *request);
+\end{verbatim}
diff --git a/doc/pnetcdf-api.bbl b/doc/pnetcdf-api.bbl
new file mode 100644
index 0000000..858537f
--- /dev/null
+++ b/doc/pnetcdf-api.bbl
@@ -0,0 +1,10 @@
+\begin{thebibliography}{1}
+
+\bibitem{thakur:romio}
+Rajeev Thakur, William Gropp, and Ewing Lusk.
+\newblock Data sieving and collective {I/O} in {ROMIO}.
+\newblock In {\em Proceedings of the Seventh Symposium on the Frontiers of
+ Massively Parallel Computation}, pages 182--189. IEEE Computer Society Press,
+ February 1999.
+
+\end{thebibliography}
diff --git a/doc/pnetcdf-api.tex b/doc/pnetcdf-api.tex
new file mode 100644
index 0000000..695ca71
--- /dev/null
+++ b/doc/pnetcdf-api.tex
@@ -0,0 +1,655 @@
+\documentclass[10pt]{article}
+% \usepackage{utopia}
+
+\pagestyle{plain}
+
+\addtolength{\hoffset}{-2cm}
+\addtolength{\textwidth}{4cm}
+
+\addtolength{\voffset}{-1.5cm}
+\addtolength{\textheight}{3cm}
+
+\setlength{\parindent}{0pt}
+\setlength{\parskip}{11pt}
+
+\title{A Parallel API for Creating and Reading NetCDF Files}
+
+\begin{document}
+
+\maketitle
+
+\begin{abstract}
+Scientists recognize the importance of portable and efficient mechanisms for
+storing datasets created and used by their applications. NetCDF is one such
+mechanism and is popular in a number of applicaiton domains because of its
+availability on a wide variety of platforms and its easy to use API. However,
+this API was originally designed for use in serial codes, and so the semantics
+of the interface are not designed to allow for high performance parallel
+access.
+
+In this work we present a new API for creating and reading NetCDF datasets,
+the \emph{Parallel NetCDF API}. This interface builds on the original NetCDF
+interface and defines semantics for parallel access to NetCDF datasets. The
+interface is built on top of MPI-IO, allowing for further performance gains
+through the use of collective I/O optimizations that already exist in MPI-IO
+implementations.
+
+\end{abstract}
+
+\section{Introduction}
+
+NetCDF is a popular package for storing data files in scientific applications.
+NetCDF consists of both an API and a portable file format. The API provides a
+consistent interface for access NetCDF files across multiple platforms, while
+the NetCDF file format guarantees data portability.
+
+The NetCDF API provides a convenient mechanism for a single process to define
+and access variables and attributes in a NetCDF file. However, it does not
+define a parallel access mechanism. In particular there is no mechanism for
+concurrently writing to a NetCDF data file. Because of this, parallel
+applications operating on NetCDF files must serialize access. This is
+typically accomplished by shipping all data to and from a single process that
+performs NetCDF operations. This mode of access is both cumbersome to the
+application programmer and considerably slower than parallel access to the
+NetCDF file. This mode can be particularly inconvenient when data set sizes
+exceed the size of available memory on a single node; in this case the data
+must be split into pieces to be shipped and written.
+
+In this document we propose an alternative API for accessing NetCDF format
+files in a parallel application. This API allows all processes in a parallel
+application to access the NetCDF file simultaneously, which is considerably
+more convenient than the serial API and allows for significantly higher
+performance.
+
+\emph{Note subset of interface that we are implementing, including both what
+types we support and any functions that we might be leaving out.}
+
+\section{Preliminaries}
+
+In MPI, communicators are typically used to describe collections of processes
+to MPI calls (e.g. the collective MPI-1 calls). In our parallel NetCDF API we
+will similarly use a communicator to denote a collection of MPI processes that
+will access a NetCDF file. By describing this collection of processes, we
+provide the underlying implementation (of our parallel NetCDF API) with
+information that it can use to ensure that the file is kept in a consistent
+state.
+
+Further, by using the collective operations provided in our parallel NetCDF
+API (ones in which all processes in this collection participate), application
+programmers provide the underlying implementation with an opportunity to
+further optimize access to the NetCDF file. These optimizations are performed
+without further intervention by the application programmer and have been
+proven to provide huge performance wins in multidimensional dataset access \cite{thakur:romio},
+exactly the kinds of accesses used in NetCDF.
+
+All this said, the original NetCDF interface is made available with a minimum
+of changes so that users migrating from the original NetCDF interface will
+have little trouble moving to this new, parallel NetCDF interface.
+
+The decision to slightly modify the API was not made lightly. It is
+relatively trivial to port NetCDF to use MPI-IO through the use of the MPI-IO
+independent access calls. However, it was only though adding this concept of
+a collection of processes simultaneously accessing the file and adding
+collective access semantics that we could hope to eliminate the serialization
+step necessary in the original API or gain the performance advantages
+available from the use of collective optimizations. Thus our performance
+requirements mandated these small adjustments.
+
+% Finally, some of the calls in our API utilize MPI datatypes. These datatypes
+% allow one to describe noncontiguous regions of data (in this case memory
+% regions) as an endpoint of a data transfer.
+
+\section{Parallel NetCDF API}
+
+The NetCDF interface breaks access into two \emph{modes}, ``define'' mode and
+``data'' mode. The define mode is used to describe the data set to be stored,
+while the data mode is used for storing and retrieving data values.
+
+We maintain these modes and (for the most part) maintain the operations when
+in define mode. We will discuss the API for opening and closing a dataset and
+for moving between modes first, next cover inquiry functions, then cover the
+define mode, attribute functions, and finally discuss the API for data mode.
+
+%
+% PREFIX
+%
+We will prefix our C interface calls with ``ncmpi'' and our Fortran interface
+calls with ``nfmpi''. This ensures no naming clashes with existing NetCDF
+libraries and does not conflict with the desire to reserve the ``MPI'' prefix
+for functions that are part of the MPI standard.
+
+All of our functions return integer NetCDF status values, just as the original
+NetCDF interface does.
+
+We will only discuss points where our interface deviates from the original
+interface in the following sections. A complete function listing is included
+in Appendix A.
+
+\subsection{Variable and Parameter Types}
+
+%
+% MPI_Offset
+%
+Rather than using \texttt{size\_t} types for size parameters passed in to our
+functions, we choose to use \texttt{MPI\_Offset} type instead. For many
+systems \texttt{size\_t} is a 32-bit unsigned value, which limits the maximum
+range of values to 4~GBytes. The \texttt{MPI\_Offset} is typically a 64-bit
+value, so it does not have this limitation. This gives us room to extend the
+file size capabilities of NetCDF at a later date.
+
+\emph{Add mapping of MPI types to NetCDF types.}
+
+\emph{Is NetCDF already exactly in external32 format?}
+
+\subsection{Dataset Functions}
+
+As mentioned before, we will define a collection of processes that are
+operating on the file by passing in a MPI communicator. This communicator is
+passed in the call to \texttt{ncmpi\_create} or \texttt{ncmpi\_open}. These
+calls are collective across all processes in the communicator. The second
+additional parameter is an \texttt{MPI\_Info}. This is used to pass hints in
+to the implementation (e.g. expected access pattern, aggregation
+information). The value \texttt{MPI\_INFO\_NULL} may be passed in if the user
+does not want to take advantage of this feature.
+
+\begin{verbatim}
+int ncmpi_create(MPI_Comm comm,
+ const char *path,
+ int cmode,
+ MPI_Info info,
+ int *ncidp)
+
+int ncmpi_open(MPI_Comm comm,
+ const char *path,
+ int omode,
+ MPI_Info info,
+ int *ncidp)
+\end{verbatim}
+
+\subsection{Define Mode Functions}
+
+\emph{All define mode functions are collective} (see Appendix B for
+rationale).
+
+All processes in the communicator must call them with the same values. At the
+end of the define mode the values passed in by all processes are checked to
+verify that they match, and if they do not then an error is returned from the
+\texttt{ncmpi\_enddef}.
+
+
+\subsection{Inquiry Functions}
+
+\emph{These calls are all collective operations} (see Appendix B for
+rationale).
+
+As in the original NetCDF interface, they may be called from either define or
+data mode. \emph{ They return information stored prior to the last open,
+enddef, or sync.}
+
+% In the original NetCDF interface the inquiry functions could be called from
+% either data or define mode. To aid in the implementation of these functions
+% in a parallel library, \emph{inquiry functions may only be called in data mode
+% in the parallel NetCDF API}. They return information stored prior to the last
+% open, enddef, or sync. This ensures that the NetCDF metadata need only be
+% kept up-to-date on all nodes when in data mode.
+%
+
+\subsection{Attribute Functions}
+
+\emph{These calls are all collective operations} (see Appendix B for
+rationale).
+
+Attributes in NetCDF are intended for storing scalar or vector values that
+describe a variable in some way. As such the expectation is that these
+attributes will be small enough to fit into memory.
+
+In the original interface, attribute operations can be performed in either
+define or data mode; however, it is possible for attribute operations that
+modify attributes (e.g. copy or create attributes) to fail if in data mode.
+This is possible because such operations can cause the amount of space needed
+to grow. In this case the cost of the operation can be on the order of a copy
+of the entire dataset. We will maintain these semantics.
+
+\subsection{Data Mode Functions}
+
+The most important change from the original NetCDF interface with respect to
+data mode functions is the split of data mode into two distinct modes:
+\emph{collective data mode} and \emph{independent data mode}. \emph{By default when
+a user calls \texttt{ncmpi\_enddef} or \texttt{ncmpi\_open}, the user will be
+in collective data mode.} The expectation is that most users will be using the
+collective operations; these users will never need to switch to independent
+data mode. In collective data mode, all processes must call the same function
+on the same ncid at the same point in the code. Different parameters for
+values such as start, count, and stride, are acceptable. Knowledge that all
+processes will be calling the function allows for additional optimization
+under the API. In independent mode processes do not need to coordinate calls
+to the API; however, this limits the optimizations that can be applied to I/O operations.
+
+A pair of new dataset operations \texttt{ncmpi\_begin\_indep\_data} and
+\texttt{ncmpi\_end\_indep\_data} switch into and out of independent data mode.
+These calls are collective. Calling \texttt{ncmpi\_close} or
+\texttt{ncmpi\_redef} also leaves independent data mode.
+Note that it is illegal to enter independent data mode while in define mode.
+Users are reminded to call {\tt ncmpi\_enddef} to leave define mode and enter data mode.
+
+\begin{verbatim}
+int ncmpi_begin_indep_data(int ncid)
+
+int ncmpi_end_indep_data(int ncid)
+\end{verbatim}
+
+The separation of the data mode into two distinct data modes is necessary to
+provide consistent views of file data when moving between MPI-IO collective
+and independent operations.
+
+We have chosen to implement two collections of data mode functions. The first
+collection closely mimics the original NetCDF access functions and is intended
+to serve as an easy path of migration from the original NetCDF interface to
+the parallel NetCDF interface. We call this subset of our parallel NetCDF
+interface the \emph{high level data mode} interface.
+
+The second collection uses more MPI functionality in order to provide better
+handling of internal data representations and to more fully expose the
+capabilities of MPI-IO to the application programmer. All of the first
+collection will be implemented in terms of these calls. We will denote this
+the \emph{flexible data mode} interface.
+
+In both collections, both independent and collective operations are provided.
+Collective function names end with \texttt{\_all}. They are collective across
+the communicator associated with the ncid, so all those processes must call
+the function at the same time.
+
+Remember that in all cases the input data type is converted into the
+appropriate type for the variable stored in the NetCDF file.
+
+\subsubsection{High Level Data Mode Interface}
+
+The independent calls in this interface closely resemble the NetCDF data mode
+interface. The only major change is the use of \texttt{MPI\_Offset} types in
+place of \texttt{size\_t} types, as described previously.
+
+The collective calls have the same arguments as their independent
+counterparts, but they must be called by all processes in the communicator
+associated with the ncid.
+
+Here are the example prototypes for accessing a strided subarray of a variable
+in a NetCDF file; the remainder of the functions are listed in Appendix A.
+
+In our initial implementation the following data function types will be
+implemented for independent access: single data value read and write (var1),
+entire variable read and write (var), array of values read and write (vara),
+and subsampled array of values read and write (vars). Collective versions of
+these types will also be provided, with the exception of a collective entire
+variable write; semantically this doesn't make sense.
+
+We could use the same function names for both independent and collective
+operations (relying instead on the mode associated with the ncid); however, we
+feel that the interface is cleaner, and it will be easier to detect bugs, with
+separate calls for independent and collective access.
+
+% \textbf{Strided Subarray Access}
+%
+Independent calls for writing or reading a strided subarray of values to/from
+a NetCDF variable (values are contiguous in memory):
+\begin{verbatim}
+int ncmpi_put_vars_uchar(int ncid,
+ int varid,
+ const MPI_Offset start[],
+ const MPI_Offset count[],
+ const MPI_Offset stride[],
+ const unsigned char *up)
+
+int ncmpi_get_vars_uchar(int ncid,
+ int varid,
+ const MPI_Offset start[],
+ const MPI_Offset count[],
+ const MPI_Offset stride[],
+ unsigned char *up)
+\end{verbatim}
+
+Collective calls for writing or reading a strided subarray of values to/from a
+NetCDF variable (values are contiguous in memory).
+\begin{verbatim}
+int ncmpi_put_vars_uchar_all(int ncid,
+ int varid,
+ const MPI_Offset start[],
+ const MPI_Offset count[],
+ const MPI_Offset stride[],
+ unsigned char *up)
+
+int ncmpi_get_vars_uchar_all(int ncid,
+ int varid,
+ const MPI_Offset start[],
+ const MPI_Offset count[],
+ const MPI_Offset stride[],
+ unsigned char *up)
+\end{verbatim}
+
+\emph{Note what calls are and aren't implemented at this time.}
+
+\subsubsection{Flexible Data Mode Interface}
+
+This smaller set of functions is all that is needed to implement the data mode
+functions. These are also made available to the application programmer.
+
+The advantage of these functions is that they allow the programmer to use MPI
+datatypes to describe the in-memory organization of the values. The only
+mechanism provides in the original NetCDF interface for such a description is
+the mapped array calls. Mapped arrays are a suboptimal method of describing
+any regular pattern in memory.
+
+In all these functions the varid, start, count, and stride values refer to the
+data in the file (just as in a NetCDF vars-type call). The buf, count, and
+datatype fields refer to data in memory.
+
+Here are examples for subarray access:
+\begin{verbatim}
+int ncmpi_put_vars(int ncid,
+ int varid,
+ MPI_Offset start[],
+ MPI_Offset count[],
+ MPI_Offset stride[],
+ const void *buf,
+ int count,
+ MPI_Datatype datatype)
+
+int ncmpi_get_vars(int ncid,
+ int varid,
+ MPI_Offset start[],
+ MPI_Offset count[],
+ MPI_Offset stride[],
+ void *buf,
+ int count,
+ MPI_Datatype datatype)
+
+int ncmpi_put_vars_all(int ncid,
+ int varid,
+ MPI_Offset start[],
+ MPI_Offset count[],
+ MPI_Offset stride[],
+ void *buf,
+ int count,
+ MPI_Datatype datatype)
+
+int ncmpi_get_vars_all(int ncid,
+ int varid,
+ MPI_Offset start[],
+ MPI_Offset count[],
+ MPI_Offset stride[],
+ void *buf,
+ int count,
+ MPI_Datatype datatype)
+\end{verbatim}
+
+
+\subsubsection{Mapping Between NetCDF and MPI Types}
+
+It is assumed here that the datatypes passed to the flexible NetCDF interface
+use only one basic datatype. For example, the datatype can be arbitrarily
+complex, but it cannot consist of both \texttt{MPI\_FLOAT} and
+\texttt{MPI\_INT} values, but only one of these basic types.
+
+\emph{Describe status of type support.}
+
+
+\subsection{Missing}
+
+Calls that were in John M.'s list but that we haven't mentioned here yet.
+
+Attribute functions, strerror, text functions, get\_vara\_text (?).
+
+\section{Examples}
+
+This section will hopefully soon hold some examples, perhaps based on writing
+out the 1D and 2D Jacobi examples in the Using MPI book using our interface?
+
+\section{Implementation Notes}
+
+Here we will keep any particular implementation details. As the
+implementation matures, this section should discuss implementation decisions.
+
+One trend that will be seen throughout here is the use of collective I/O
+routines when it would be possible to use independent operations. There are
+two reasons for this. First, for some operations (such as reading the
+header), there are important optimizations that can be made to more
+efficiently read data from the I/O system, especially as the number of NetCDF
+application processes increases. Second, the use of collective routines
+allows for the use of aggregation routines in the MPI-IO implementation. This
+allows us to redirect I/O to nodes that have access to I/O resources in
+systems where not all processes have access. This isn't currently possible
+using the independent I/O calls.
+
+See the ROMIO User's Guide for more information on the aggregation hints, in
+particular the \texttt{cb\_config\_list} hint.
+
+\subsection{Questions for Users on Implementation}
+\begin{itemize}
+\item Is this emphasis on collective operations appropriate or problematic?
+\item Is C or Fortran the primary language for NetCDF programs?
+\end{itemize}
+
+\subsection{I/O routines}
+
+All I/O within our implementation will be performed through MPI-IO.
+
+No temporary files will be created at any time.
+
+%
+% HEADER I/O
+%
+\subsection{Header I/O}
+
+\emph{It is assumed that headers are too small to benefit from parallel I/O.}
+
+All header updates will be performed with collective I/O, but only rank 0 will
+provide any input data. This is important because only through the collective
+calls can our \texttt{cb\_config\_list} hint be used to control what hosts
+actually do writing. Otherwise we could pick some arbitrary process to do
+I/O, but we have no way of knowing if that was a process that the user
+intended to do I/O in the first place (thus that process might not even be
+able to write to the file!)
+
+Headers are written all at once at \texttt{ncmpi\_enddef}.
+
+Likewise collective I/O will be used when reading the header, which should
+simply be used to read the entire header to everyone on open.
+
+\emph{First cut might not do this.}
+
+\subsection{Code Reuse}
+We will not reuse any NetCDF code. This will give us an opportunity to leave
+out any code pertaining to optimizations on specific machines (e.g. Cray) that
+we will not need and, more importantly, cannot test.
+
+\subsection{Providing Independent and Collective I/O}
+In order to make use of \texttt{MPI\_File\_set\_view} for both independent and
+collective NetCDF operations, we will need to open the NetCDF file separately
+for both, with the input communicator for collective I/O and with
+MPI\_COMM\_SELF for independent I/O. However, we can defer opening the file
+for independent access until an independent access call is made if we like.
+This can be an important optimization as we scale.
+
+Synchronization when switching between collective and independent access is
+mandatory to ensure correctness under the MPI I/O model.
+
+\subsection{Outline of I/O}
+
+Outline of steps to I/O:
+\begin{itemize}
+\item MPI\_File is extracted from ncid
+\item variable type is extracted from varid
+\item file view is created from:
+ \begin{itemize}
+ \item metadata associated with ncid
+ \item variable index info, array size, limited/unlimited, type from varid
+ \item start/count/stride info
+ \end{itemize}
+\item datatype/count must match number of elements specified by
+ start/count/stride
+\item status returns normal mpi status information, which is mapped to a
+ NetCDF error code.
+\end{itemize}
+
+
+\section{Future Work}
+
+More to add.
+
+%
+% BIBLIOGRAPHY
+%
+\bibliography{pnetcdf-api}
+\bibliographystyle{plain}
+
+%
+% APPENDIX A: FUNCTION LISTING
+%
+\section*{Appendix A: C API Listing}
+
+\input c_api
+
+%
+% APPENDIX B: RATIONALE
+%
+\section*{Appendix B: Rationale}
+
+This section covers the rationale behind our decisions on API specifics.
+
+%
+% define mode function semantics
+%
+\subsection*{B.1 Define Mode Function Semantics}
+
+There are two options to choose from here, either forcing a single process to
+make these calls (funnelled) or forcing all these calls to be collective with
+the same data. Note that making them collective does \emph{not} imply any
+communication at the time the call is made.
+
+Both of these options allow for better error detection than what we
+previously described (functions independent, anyone could call, only node
+0's data was used). Error detection could be performed at the end of the
+define mode to minimize costs.
+
+In fact, it is only fractionally more costly to implement collectives than
+funneled (including the error detection). To do this one simply bcast's
+process 0's values out (which one would have to do anyway) and then
+allgathers a single char or int from everyone indicating if there was a
+problem.
+
+There has to be some synchronization at the end of the define mode in any
+case, so this extra error detection comes at an especially low cost.
+
+\subsection*{B.2 Attribute and Inquiry Function Semantics}
+
+There are similar options here to the ones for define mode functions.
+
+One option would be to make these functions independent. This would be easy
+for read operations, but would be more difficult for write operations. In
+particular we would need to gather up modifications at some point in order to
+distribute them out to all processes. Ordering of modifications might also be
+an issue. Finally, we would want to constrain use of these independent
+operations to the define mode so that we would have an obvious point at which
+to perform this collect and distribute operation (e.g. \texttt{ncmpi\_enddef}).
+
+Another option would be to make all of these functions collective. This is an
+unnecessary constraint for the read operations, but it helps in implementing
+the write operations (we can distribute modifications right away) and allows
+us to maintain the use of these functions outside define mode if we wish.
+This is also more consistent with the SPMD model that (we think) our users are
+using.
+
+The final option would be to allow independent use of the read operations but
+force collective use of the write operations. This would result in confusing
+semantics.
+
+For now we will implement the second option, all collective operation. Based
+on feedback from users we will consider relaxing this constraint.
+
+\subsubsection*{Questions for Users Regarding Attribute and Inquiry Functions}
+\begin{itemize}
+\item Are attribute calls used in data mode?
+\item Is it inconvenient that the inquiry functions are collective?
+\end{itemize}
+
+\subsection*{B.3 Splitting Data Mode into Collective and Independent Data Modes}
+
+In both independent and collective MPI-IO operations, it is important to be
+able to set the file view to allow for noncontiguous file regions. However,
+since the \texttt{MPI\_File\_set\_view} is a collective operation, it is
+impossible to use a single file handle to perform collective I/O and still be
+able to arbitrarily reset the file view before an independent operation
+(because all the processes would need to participate in the file set view).
+
+For this reason it is necessary to have two file handles in the case where
+both independent and collective I/O will be performed. One file handle is
+opened with \texttt{MPI\_COMM\_SELF} and is used for independent operations,
+while the other is opened with the communicator containing all the processes
+for the collective operations.
+
+It is difficult if not impossible in the general case to ensure consistency of
+access when a collection of processes are using multiple MPI\_File handles to
+access the same file with mixed independent and collective operations.
+However, if explicit and collective synchronization points are introduced
+between phases where collective and independent I/O operations will be
+performed, then the correct set of operations to ensure a consistent view can
+be inserted at this point.
+
+\emph{Does this explanation make any sense? I think we need to document this.}
+
+\subsection*{B.4 Even More MPI-Like Data Mode Functions}
+
+Recall that our flexible NetCDF interface has functions such as:
+\begin{verbatim}
+int ncmpi_put_vars(int ncid,
+ int varid,
+ MPI_Offset start[],
+ MPI_Offset count[],
+ MPI_Offset stride[],
+ void *buf,
+ int count,
+ MPI_Datatype datatype)
+\end{verbatim}
+
+It is possible to move to an even more MPI-like interface by using an MPI
+datatype to describe the file region in addition to using datatypes for the
+memory region:
+\begin{verbatim}
+int ncmpi_put(int ncid,
+ int varid,
+ MPI_Datatype file_dtype,
+ void *buf,
+ int count,
+ MPI_Datatype mem_dtype)
+\end{verbatim}
+
+At first glance this looks rather elegant. However, this isn't as clean as it
+seems. The \texttt{file\_dtype} in this case has to describe the variable
+layout \emph{in terms of the variable array}, not in terms of the file,
+because the user doesn't know about the internal file layout. So the
+underlying implementation would need to tear apart \texttt{file\_dtype} and
+rebuild a new datatype, on the fly, that corresponded to the data layout in
+the file as a whole. This is complicated by the fact that
+\texttt{file\_dtype} could be arbitrarily complex.
+
+The flexible NetCDF interface parameters, \texttt{start}, \texttt{count}, and
+\texttt{stride} must also be used to build a file type, but the process is
+considerably simpler.
+
+\subsection*{B.5 MPI and NetCDF Types}
+
+\subsubsection*{Questions for Users Regarding MPI and NetCDF Types}
+
+\begin{itemize}
+\item How do users use text strings?
+\item What types are our users using?
+\end{itemize}
+
+\end{document}
+
+
+
+
+
+
+
+
diff --git a/doc/porting_notes.txt b/doc/porting_notes.txt
new file mode 100644
index 0000000..f091ec8
--- /dev/null
+++ b/doc/porting_notes.txt
@@ -0,0 +1,50 @@
+
+ these are some rough notes for porting code from the serial netcdf api to
+ the pnetcdf API. Pnetcdf is very similar but there are some changes that
+ have to be made:
+
+
+. the nc_* functions are called ncmpi_*
+
+. the nf_* functions are called nfmpi_*
+
+. ncmpi_open takes a communicator and an info structure, in addition to the
+ parameters in the serial nc_open()
+
+For example:
+ status = nc_open(path, NC_NOWRITE, &ncid);
+becomes
+ status = ncmpi_open(MPI_COMM_WORLD, path, NC_NOWRITE,
+ MPI_INFO_NULL, &ncid);
+
+. if you make any independent calls ( those not ending in _all), you must put
+ yourself into independent data mode with ncmpi_begin_indep_data(ncid) and
+ ncmpi_end_indep_data(ncid)
+
+. FILL_DOUBLE and FILL_FLOAT are called NC_FILL_DOUBLE and NC_FILL_FLOAT
+ respectively. We do not define these NetCDF-2.x era constants in pnetcdf.
+
+. #include <mpi.h> . If you want, define a communicator. MPI_COMM_WORLD
+ should work ok for most things.
+
+. somewhere near main, call MPI_Init(): pnetcdf won't do that for you.
+
+. pnetcdf does not implement nc_advise
+
+. pnetcdf does not support all types that serial netcdf supports. see
+ src/lib/TODO for more specifics
+
+. If for some reason your code uses 'ptrdiff_t' types, consider using
+ MPI_Offset types
+
+. likewise, in many places where serial netcdf takes size_t types, we instead
+ take MPI_Offset types
+
+. Fortran users should use '#include <mpif.h>' and '#include "pnetcdf.inc"',
+ instead of using the Fortran INCLUDE directive.
+
+. Fortran 90 users can use 'use mpi' and 'use pnetcdf'.
+
+. Fortran dimension sizes should be declared as type
+ INTEGER(KIND=MPI_OFFSET_KIND)
+
diff --git a/doc/symbol_renaming.txt b/doc/symbol_renaming.txt
new file mode 100644
index 0000000..6179f94
--- /dev/null
+++ b/doc/symbol_renaming.txt
@@ -0,0 +1,23 @@
+#
+# We want apps to be able to link with both serial NetCDF and Parallel-NetCDF,
+# so we had to alter some symbols in the library. The following list is a
+# start at documenting the changes. I found such a list helpful when merging
+# netcdf-3.5 patches to pnetcdf
+#
+
+serial parallel
+-------------------------
+ncx_len_NC ncmpii_hdr_len_NC
+ncx_put_NC ncmpii_hdr_put_NC
+nc_get_NC ncmpii_hdr_get_NC
+ncx_get_size_t ncmpix_get_size_t
+new_NC ncmpii_new_NC
+v1h_get_NC_attarray hdr_len_NC_attarray
+ncx_len_NC_var hdr_len_NC_var
+ncx_len_NC_vararray hdr_len_NC_vararray
+check_v1hs hdr_check_buffer
+struct v1hs struct bufferinfo
+NC_* ncmpii_NC_*
+nc__
+ncx_* ncmpix_*
+
diff --git a/examples/C/Makefile.in b/examples/C/Makefile.in
new file mode 100644
index 0000000..6c02932
--- /dev/null
+++ b/examples/C/Makefile.in
@@ -0,0 +1,162 @@
+#
+# Copyright (C) 2012, Northwestern University and Argonne National Laboratory
+# See COPYRIGHT notice in top-level directory.
+#
+# $Id: Makefile.in 2245 2015-12-20 18:39:52Z wkliao $
+#
+# @configure_input@
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+include ../../macros.make
+
+# note the order of -L list matters
+INCLUDES = -I../../src/lib
+LDFLAGS := -L../../src/lib $(LDFLAGS)
+LIBS := -lpnetcdf $(LIBS)
+
+C_SRCS = collective_write.c \
+ nonblocking_write.c \
+ nonblocking_write_in_def.c \
+ column_wise.c \
+ block_cyclic.c \
+ flexible_api.c \
+ get_info.c \
+ hints.c \
+ mput.c \
+ put_varn_float.c \
+ put_varn_int.c \
+ create_open.c \
+ global_attributes.c \
+ put_vara.c \
+ get_vara.c \
+ transpose.c \
+ vard_int.c \
+ i_varn_int64.c \
+ bput_varn_uint.c \
+ fill_mode.c \
+ ghost_cell.c \
+ req_all.c
+
+# Note: put_vara must be run immediately before get_vara
+
+PROGS = $(C_SRCS:.c=)
+OBJS = $(C_SRCS:.c=.o)
+
+GARBAGE = $(PROGS) *.nc
+
+PACKING_LIST = $(C_SRCS) depend Makefile.in
+
+all: $(PROGS)
+
+install:
+
+uninstall:
+
+collective_write: collective_write.o $(LIBRARY)
+ $(LINK.c) $< $(LDFLAGS) $(LIBS)
+
+nonblocking_write: nonblocking_write.o $(LIBRARY)
+ $(LINK.c) $< $(LDFLAGS) $(LIBS)
+
+nonblocking_write_in_def: nonblocking_write_in_def.o $(LIBRARY)
+ $(LINK.c) $< $(LDFLAGS) $(LIBS)
+
+get_info: get_info.o $(LIBRARY)
+ $(LINK.c) $< $(LDFLAGS) $(LIBS)
+
+column_wise: column_wise.o $(LIBRARY)
+ $(LINK.c) $< $(LDFLAGS) $(LIBS)
+
+block_cyclic: block_cyclic.o $(LIBRARY)
+ $(LINK.c) $< $(LDFLAGS) $(LIBS)
+
+put_vara: put_vara.o $(LIBRARY)
+ $(LINK.c) $< $(LDFLAGS) $(LIBS)
+
+mput: mput.o $(LIBRARY)
+ $(LINK.c) $< $(LDFLAGS) $(LIBS)
+
+hints: hints.o $(LIBRARY)
+ $(LINK.c) $< $(LDFLAGS) $(LIBS)
+
+flexible_api: flexible_api.o $(LIBRARY)
+ $(LINK.c) $< $(LDFLAGS) $(LIBS)
+
+put_varn_int: put_varn_int.o $(LIBRARY)
+ $(LINK.c) $< $(LDFLAGS) $(LIBS)
+
+put_varn_float: put_varn_float.o $(LIBRARY)
+ $(LINK.c) $< $(LDFLAGS) $(LIBS)
+
+create_open: create_open.o $(LIBRARY)
+ $(LINK.c) $< $(LDFLAGS) $(LIBS)
+
+global_attributes: global_attributes.o $(LIBRARY)
+ $(LINK.c) $< $(LDFLAGS) $(LIBS)
+
+get_vara: get_vara.o $(LIBRARY)
+ $(LINK.c) $< $(LDFLAGS) $(LIBS)
+
+transpose: transpose.o $(LIBRARY)
+ $(LINK.c) $< $(LDFLAGS) $(LIBS)
+
+vard_int: vard_int.o $(LIBRARY)
+ $(LINK.c) $< $(LDFLAGS) $(LIBS)
+
+i_varn_int64: i_varn_int64.o $(LIBRARY)
+ $(LINK.c) $< $(LDFLAGS) $(LIBS)
+
+bput_varn_uint: bput_varn_uint.o $(LIBRARY)
+ $(LINK.c) $< $(LDFLAGS) $(LIBS)
+
+fill_mode: fill_mode.o $(LIBRARY)
+ $(LINK.c) $< $(LDFLAGS) $(LIBS)
+
+ghost_cell: ghost_cell.o $(LIBRARY)
+ $(LINK.c) $< $(LDFLAGS) $(LIBS)
+
+req_all: req_all.o $(LIBRARY)
+ $(LINK.c) $< $(LDFLAGS) $(LIBS)
+
+TEST_MPIRUN_4 = $(subst NP,4,$(TEST_MPIRUN))
+TEST_MPIRUN_8 = $(subst NP,8,$(TEST_MPIRUN))
+TEST_MPIRUN_3 = $(subst NP,3,$(TEST_MPIRUN))
+
+ptest4: $(PROGS)
+ @for i in $(PROGS); do ( \
+ $(TEST_MPIRUN_4) ./$$i -q $(TEST_OUTDIR)/testfile.nc ; \
+ if [ $$? = 0 ] ; then \
+ echo "PASS: C parallel run on 4 processes --------------- $$i"; \
+ else \
+ echo "FAILED: C parallel run on 4 processes ------------- $$i"; \
+ fi ; ) ; done
+
+ptest8: $(PROGS)
+ @for i in $(PROGS); do ( \
+ $(TEST_MPIRUN_8) ./$$i -q $(TEST_OUTDIR)/testfile.nc ; \
+ if [ $$? = 0 ] ; then \
+ echo "PASS: C parallel run on 8 processes --------------- $$i"; \
+ else \
+ echo "FAILED: C parallel run on 8 processes ------------- $$i"; \
+ fi ; ) ; done
+
+ptest3: $(PROGS)
+ @for i in $(PROGS) ; do ( \
+ $(TEST_MPIRUN_3) ./$$i -q $(TEST_OUTDIR)/testfile.nc ; \
+ if [ $$? = 0 ] ; then \
+ echo "PASS: C parallel run on 3 processes --------------- $$i"; \
+ else \
+ echo "FAILED: C parallel run on 3 processes ------------- $$i"; \
+ fi ; ) ; done
+
+ptest: ptest4
+ptests: ptest3 ptest4 ptest8
+ptest2 ptest6 ptest10:
+
+include $(srcdir)/depend
+include $(srcdir)/../../rules.make
+
+$(LIBRARY): ;
+
diff --git a/examples/C/block_cyclic.c b/examples/C/block_cyclic.c
new file mode 100644
index 0000000..c2d056f
--- /dev/null
+++ b/examples/C/block_cyclic.c
@@ -0,0 +1,301 @@
+/*********************************************************************
+ *
+ * Copyright (C) 2013, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ *
+ *********************************************************************/
+/* $Id: block_cyclic.c 2245 2015-12-20 18:39:52Z wkliao $ */
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * This example, generalized from column_wise.c, makes a number of nonblocking
+ * API calls, each writes a block of columns into a 2D integer array. In other
+ * words, the I/O pattern is a blocked cyclic along X dimension.
+ *
+ * Each process writes NX columns in total. The block length is controlled by
+ * block_len. In this example, block_len is set to 2. Blocks are layout in a
+ * cyclic fashion in the file. This example can test if PnetCDF can coalesce
+ * file offsets and lengths when constructing a merged filetype.
+ *
+ * The compile and run commands are given below, together with an ncmpidump of
+ * the output file. In this example, block_len = 2.
+ *
+ * % mpicc -O2 -o block_cyclic block_cyclic.c -lpnetcdf
+ * % mpiexec -l -n 4 ./block_cyclic /pvfs2/wkliao/testfile.nc
+ * 0: 0: NY=10 myNX= 4 myOff= 0
+ * 1: 1: NY=10 myNX= 4 myOff= 4
+ * 2: 2: NY=10 myNX= 4 myOff= 8
+ * 3: 3: NY=10 myNX= 4 myOff= 12
+ * 0: [i=0] iput() start= 0 0 count= 10 1
+ * 0: [i=1] iput() start= 0 1 count= 10 1
+ * 0: [i=2] iput() start= 0 8 count= 10 1
+ * 0: [i=3] iput() start= 0 9 count= 10 1
+ * 1: [i=0] iput() start= 0 2 count= 10 1
+ * 1: [i=1] iput() start= 0 3 count= 10 1
+ * 1: [i=2] iput() start= 0 10 count= 10 1
+ * 1: [i=3] iput() start= 0 11 count= 10 1
+ * 2: [i=0] iput() start= 0 4 count= 10 1
+ * 2: [i=1] iput() start= 0 5 count= 10 1
+ * 2: [i=2] iput() start= 0 12 count= 10 1
+ * 2: [i=3] iput() start= 0 13 count= 10 1
+ * 3: [i=0] iput() start= 0 6 count= 10 1
+ * 3: [i=1] iput() start= 0 7 count= 10 1
+ * 3: [i=2] iput() start= 0 14 count= 10 1
+ * 3: [i=3] iput() start= 0 15 count= 10 1
+ *
+ * % ncmpidump /pvfs2/wkliao/testfile.nc
+ * netcdf testfile {
+ * // file format: CDF-5 (big variables)
+ * dimensions:
+ * Y = 10 ;
+ * X = 16 ;
+ * variables:
+ * int var(Y, X) ;
+ * data:
+ *
+ * var =
+ * 10, 10, 11, 11, 12, 12, 13, 13, 10, 10, 11, 11, 12, 12, 13, 13,
+ * 10, 10, 11, 11, 12, 12, 13, 13, 10, 10, 11, 11, 12, 12, 13, 13,
+ * 10, 10, 11, 11, 12, 12, 13, 13, 10, 10, 11, 11, 12, 12, 13, 13,
+ * 10, 10, 11, 11, 12, 12, 13, 13, 10, 10, 11, 11, 12, 12, 13, 13,
+ * 10, 10, 11, 11, 12, 12, 13, 13, 10, 10, 11, 11, 12, 12, 13, 13,
+ * 10, 10, 11, 11, 12, 12, 13, 13, 10, 10, 11, 11, 12, 12, 13, 13,
+ * 10, 10, 11, 11, 12, 12, 13, 13, 10, 10, 11, 11, 12, 12, 13, 13,
+ * 10, 10, 11, 11, 12, 12, 13, 13, 10, 10, 11, 11, 12, 12, 13, 13,
+ * 10, 10, 11, 11, 12, 12, 13, 13, 10, 10, 11, 11, 12, 12, 13, 13,
+ * 10, 10, 11, 11, 12, 12, 13, 13, 10, 10, 11, 11, 12, 12, 13, 13 ;
+ * }
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h> /* strcpy() */
+#include <unistd.h> /* getopt() */
+#include <assert.h>
+#include <mpi.h>
+#include <pnetcdf.h>
+
+#define NY 10
+#define NX 4
+
+#ifndef MIN
+#define MIN(a,b) (((a)<(b))?(a):(b))
+#endif
+
+#define ERR {if(err!=NC_NOERR)printf("Error at line=%d: %s\n", __LINE__, ncmpi_strerror(err));}
+
+static void
+usage(char *argv0)
+{
+ char *help =
+ "Usage: %s [-h] | [-q] [file_name]\n"
+ " [-h] Print help\n"
+ " [-q] Quiet mode (reports when fail)\n"
+ " [filename] output netCDF file name\n";
+ fprintf(stderr, help, argv0);
+}
+
+int main(int argc, char** argv) {
+ extern int optind;
+ char *filename="testfile.nc";
+ int i, j, verbose=1, rank, nprocs, err, num_reqs;
+ int ncid, cmode, varid, dimid[2], *reqs, *sts, **buf;
+ MPI_Offset myNX, G_NX, myOff, block_start, block_len;
+ MPI_Offset start[2], count[2];
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+
+ /* get command-line arguments */
+ while ((i = getopt(argc, argv, "hq")) != EOF)
+ switch(i) {
+ case 'q': verbose = 0;
+ break;
+ case 'h':
+ default: if (rank==0) usage(argv[0]);
+ MPI_Finalize();
+ return 0;
+ }
+ argc -= optind;
+ argv += optind;
+ if (argc == 1) filename = argv[0]; /* optional argument */
+
+ /* create a new file for writing ----------------------------------------*/
+ cmode = NC_CLOBBER | NC_64BIT_DATA;
+ err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, MPI_INFO_NULL, &ncid);
+ ERR
+
+ /* the global array is NY * (NX * nprocs) */
+ G_NX = NX * nprocs;
+ myOff = NX * rank;
+ myNX = NX;
+ if (verbose) printf("%2d: NY=%d myNX=%3lld myOff=%3lld\n",rank,NY,myNX,myOff);
+
+ err = ncmpi_def_dim(ncid, "Y", NY, &dimid[0]);
+ ERR
+ err = ncmpi_def_dim(ncid, "X", G_NX, &dimid[1]);
+ ERR
+ err = ncmpi_def_var(ncid, "var", NC_INT, 2, dimid, &varid);
+ ERR
+ err = ncmpi_enddef(ncid);
+ ERR
+
+ /* First, fill the entire array with zeros, using a blocking I/O.
+ Every process writes a subarray of size NY * myNX */
+ buf = (int**) malloc(myNX * sizeof(int*));
+ buf[0] = (int*) calloc(NY * myNX, sizeof(int));
+ start[0] = 0; start[1] = myOff;
+ count[0] = NY; count[1] = myNX;
+ err = ncmpi_put_vara_int_all(ncid, varid, start, count, buf[0]);
+ free(buf[0]);
+
+ /* initialize the buffer with rank ID. Also make the case interesting,
+ by allocating buffers separately */
+ for (i=0; i<myNX; i++) {
+ buf[i] = (int*) malloc(NY * sizeof(int));
+ for (j=0; j<NY; j++) buf[i][j] = rank+10;
+ }
+
+ reqs = (int*) malloc(myNX * sizeof(int));
+ sts = (int*) malloc(myNX * sizeof(int));
+
+ /* each proc writes myNX columns of the 2D array, block_len controls the
+ number of contiguous columns at a time */
+ block_start = 0;
+ block_len = 2; /* can be 1, 2, 3, ..., myNX */
+ if (block_len > myNX) block_len = myNX;
+
+ start[0] = 0; start[1] = rank * block_len;
+ count[0] = NY; count[1] = 1;
+ num_reqs = 0;
+ for (i=0; i<myNX; i++) {
+ err = ncmpi_iput_vara_int(ncid, varid, start, count, buf[i],
+ &reqs[num_reqs++]);
+ ERR
+
+ if (verbose)
+ printf("[i=%d] iput() start=%3lld %3lld count=%3lld %3lld\n",
+ i, start[0],start[1], count[0],count[1]);
+
+ if (i % block_len == block_len-1) {
+ int stride = MIN(myNX-1-i, block_len);
+ block_start += block_len * nprocs;
+ start[1] = block_start + stride * rank;
+ }
+ else
+ start[1]++;
+ }
+
+ err = ncmpi_wait_all(ncid, num_reqs, reqs, sts);
+ ERR
+
+ /* check status of all requests */
+ for (i=0; i<num_reqs; i++)
+ if (sts[i] != NC_NOERR)
+ printf("Error: nonblocking write fails on request %d (%s)\n",
+ i, ncmpi_strerror(sts[i]));
+
+ err = ncmpi_close(ncid);
+ ERR
+
+ free(sts);
+ free(reqs);
+ for (i=0; i<myNX; i++) free(buf[i]);
+ free(buf);
+
+ /* open an existing file created earlier for read -----------------------*/
+ cmode = NC_NOWRITE;
+ err = ncmpi_open(MPI_COMM_WORLD, filename, cmode, MPI_INFO_NULL, &ncid);
+ ERR
+
+ /* the global array is NY * (NX * nprocs) */
+ MPI_Offset global_ny, global_nx;
+ err = ncmpi_inq_dimid(ncid, "Y", &dimid[0]);
+ ERR
+ err = ncmpi_inq_dimlen(ncid, dimid[0], &global_ny);
+ ERR
+ assert(global_ny == NY);
+
+ err = ncmpi_inq_dimid(ncid, "X", &dimid[1]);
+ ERR
+ err = ncmpi_inq_dimlen(ncid, dimid[1], &global_nx);
+ ERR
+ assert(global_nx == G_NX);
+
+ myNX = global_nx / nprocs;
+
+ err = ncmpi_inq_varid(ncid, "var", &varid);
+ ERR
+
+ /* initialize the buffer with -1, so a read error can be pinpointed */
+ buf = (int**) malloc(myNX * sizeof(int*));
+ buf[0] = (int*) malloc(global_ny * myNX * sizeof(int));
+ for (i=0; i<myNX; i++) {
+ if (i > 0) buf[i] = buf[i-1] + global_ny;
+ for (j=0; j<global_ny; j++) buf[i][j] = -1;
+ }
+
+ reqs = (int*) malloc(myNX * sizeof(int));
+ sts = (int*) malloc(myNX * sizeof(int));
+
+ /* each proc reads myNX columns of the 2D array, block_len controls the
+ number of contiguous columns at a time */
+ block_start = 0;
+ block_len = 2; /* can be 1, 2, 3, ..., myNX */
+ if (block_len > myNX) block_len = myNX;
+
+ start[0] = 0; start[1] = rank * block_len;
+ count[0] = global_ny; count[1] = 1;
+ num_reqs = 0;
+ for (i=0; i<myNX; i++) {
+ err = ncmpi_iget_vara_int(ncid, varid, start, count, buf[i],
+ &reqs[num_reqs++]);
+ ERR
+
+ if (i % block_len == block_len-1) {
+ int stride = MIN(myNX-1-i, block_len);
+ block_start += block_len * nprocs;
+ start[1] = block_start + stride * rank;
+ }
+ else
+ start[1]++;
+ }
+ err = ncmpi_wait_all(ncid, num_reqs, reqs, sts);
+ ERR
+
+ /* check status of all requests */
+ for (i=0; i<num_reqs; i++)
+ if (sts[i] != NC_NOERR)
+ printf("Error: nonblocking read fails on request %d (%s)\n",
+ i, ncmpi_strerror(sts[i]));
+
+ err = ncmpi_close(ncid);
+ ERR
+
+ /* check the read contents */
+ for (i=0; i<myNX; i++) {
+ for (j=0; j<global_ny; j++)
+ if (buf[i][j] != rank+10) {
+ printf("Read contents mismatch at buf[%d][%d] = %d (should be %d)\n", i,j,buf[i][j],rank+10);
+ }
+ }
+
+ free(sts);
+ free(reqs);
+ free(buf[0]);
+ free(buf);
+
+ /* check if there is any PnetCDF internal malloc residue */
+ MPI_Offset malloc_size, sum_size;
+ err = ncmpi_inq_malloc_size(&malloc_size);
+ if (err == NC_NOERR) {
+ MPI_Reduce(&malloc_size, &sum_size, 1, MPI_OFFSET, MPI_SUM, 0, MPI_COMM_WORLD);
+ if (rank == 0 && sum_size > 0)
+ printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n",
+ sum_size);
+ }
+
+ MPI_Finalize();
+ return 0;
+}
+
diff --git a/examples/C/bput_varn_uint.c b/examples/C/bput_varn_uint.c
new file mode 100644
index 0000000..78e699e
--- /dev/null
+++ b/examples/C/bput_varn_uint.c
@@ -0,0 +1,347 @@
+/*********************************************************************
+ *
+ * Copyright (C) 2014, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ *
+ *********************************************************************/
+/* $Id: bput_varn_uint.c 2245 2015-12-20 18:39:52Z wkliao $ */
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * This example tests nonblocking buffered write varn APIs, including
+ * ncmpi_bput_varn_uint() and ncmpi_bput_varn(),
+ * It first writes a sequence of requests with arbitrary array indices and
+ * lengths to four variables of type NC_UINT, and reads back.
+ *
+ * The compile and run commands are given below, together with an ncmpidump of
+ * the output file.
+ *
+ * % mpicc -O2 -o i_varn_uint i_varn_uint.c -lpnetcdf
+ * % mpiexec -n 4 ./i_varn_uint /pvfs2/wkliao/testfile.nc
+ * % ncmpidump /pvfs2/wkliao/testfile.nc
+ * netcdf testfile {
+ * // file format: CDF-5 (big variables)
+ * dimensions:
+ * Y = 4 ;
+ * X = 10 ;
+ * variables:
+ * uint var0(Y, X) ;
+ * uint var1(Y, X) ;
+ * uint var2(Y, X) ;
+ * uint var3(Y, X) ;
+ * data:
+ *
+ * var0 =
+ * 1, 1, 1, 3, 3, 0, 0, 2, 3, 3,
+ * 0, 2, 2, 2, 1, 3, 3, 2, 2, 2,
+ * 3, 3, 2, 1, 1, 1, 0, 0, 3, 3,
+ * 0, 0, 0, 2, 3, 3, 3, 1, 1, 1 ;
+ *
+ * var1 =
+ * 2, 2, 2, 0, 0, 1, 1, 3, 0, 0,
+ * 1, 3, 3, 3, 2, 0, 0, 3, 3, 3,
+ * 0, 0, 3, 2, 2, 2, 1, 1, 0, 0,
+ * 1, 1, 1, 3, 0, 0, 0, 2, 2, 2 ;
+ *
+ * var2 =
+ * 3, 3, 3, 1, 1, 2, 2, 0, 1, 1,
+ * 2, 0, 0, 0, 3, 1, 1, 0, 0, 0,
+ * 1, 1, 0, 3, 3, 3, 2, 2, 1, 1,
+ * 2, 2, 2, 0, 1, 1, 1, 3, 3, 3 ;
+ *
+ * var3 =
+ * 0, 0, 0, 2, 2, 3, 3, 1, 2, 2,
+ * 3, 1, 1, 1, 0, 2, 2, 1, 1, 1,
+ * 2, 2, 1, 0, 0, 0, 3, 3, 2, 2,
+ * 3, 3, 3, 1, 2, 2, 2, 0, 0, 0 ;
+ * }
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h> /* getopt() */
+#include <string.h> /* strcpy() */
+#include <mpi.h>
+#include <pnetcdf.h>
+
+#define NY 4
+#define NX 10
+#define NDIMS 2
+
+#define ERR \
+ if (err != NC_NOERR) { \
+ printf("Error at line=%d: %s\n", __LINE__, ncmpi_strerror(err)); \
+ }
+
+#define ERRS(n,a) { \
+ int _i; \
+ for (_i=0; _i<(n); _i++) { \
+ if ((a)[_i] != NC_NOERR) { \
+ printf("Error at line=%d: err[%d] %s\n", __LINE__, _i, \
+ ncmpi_strerror((a)[_i])); \
+ } \
+ } \
+}
+
+static MPI_Offset *** calloc_3D(size_t z, size_t y, size_t x)
+{
+ int _j, _k;
+ MPI_Offset ***buf = (MPI_Offset***) malloc(z * sizeof(MPI_Offset**));
+ MPI_Offset **bufy = (MPI_Offset**) malloc(z*y * sizeof(MPI_Offset*));
+ MPI_Offset *bufx = (MPI_Offset*) calloc(z*y*x, sizeof(MPI_Offset));
+ for (_k=0; _k<z; _k++, bufy+=y) {
+ buf[_k] = bufy;
+ for (_j=0; _j<y; _j++, bufx+=x)
+ buf[_k][_j] = bufx;
+ }
+ return buf;
+}
+
+static void free_3D(MPI_Offset ***buf)
+{
+ free(buf[0][0]);
+ free(buf[0]);
+ free(buf);
+}
+
+static void
+usage(char *argv0)
+{
+ char *help =
+ "Usage: %s [-h] | [-q] [file_name]\n"
+ " [-h] Print help\n"
+ " [-q] Quiet mode (reports when fail)\n"
+ " [filename] output netCDF file name\n";
+ fprintf(stderr, help, argv0);
+}
+
+static void check_contents(int ncid, int *varid)
+{
+ int i, j, err;
+ unsigned int expected[4][NY*NX] = {{1, 1, 1, 3, 3, 0, 0, 2, 3, 3,
+ 0, 2, 2, 2, 1, 3, 3, 2, 2, 2,
+ 3, 3, 2, 1, 1, 1, 0, 0, 3, 3,
+ 0, 0, 0, 2, 3, 3, 3, 1, 1, 1},
+ {2, 2, 2, 0, 0, 1, 1, 3, 0, 0,
+ 1, 3, 3, 3, 2, 0, 0, 3, 3, 3,
+ 0, 0, 3, 2, 2, 2, 1, 1, 0, 0,
+ 1, 1, 1, 3, 0, 0, 0, 2, 2, 2},
+ {3, 3, 3, 1, 1, 2, 2, 0, 1, 1,
+ 2, 0, 0, 0, 3, 1, 1, 0, 0, 0,
+ 1, 1, 0, 3, 3, 3, 2, 2, 1, 1,
+ 2, 2, 2, 0, 1, 1, 1, 3, 3, 3},
+ {0, 0, 0, 2, 2, 3, 3, 1, 2, 2,
+ 3, 1, 1, 1, 0, 2, 2, 1, 1, 1,
+ 2, 2, 1, 0, 0, 0, 3, 3, 2, 2,
+ 3, 3, 3, 1, 2, 2, 2, 0, 0, 0}};
+
+ unsigned int *r_buffer = (unsigned int*) malloc(NY*NX*sizeof(unsigned int));
+
+ for (i=0; i<4; i++) {
+ for (j=0; j<NY*NX; j++) r_buffer[j] = 99999;
+ err = ncmpi_get_var_uint_all(ncid, varid[i], r_buffer);
+ ERR
+
+ /* check if the contents of buf are expected */
+ for (j=0; j<NY*NX; j++)
+ if (r_buffer[j] != expected[i][j])
+ printf("Expected file contents [%d][%d]=%u, but got %u\n",
+ i,j,expected[i][j],r_buffer[j]);
+ }
+ free(r_buffer);
+}
+
+int main(int argc, char** argv)
+{
+ extern int optind;
+ char *filename="testfile.nc", exec[128];
+ int i, j, k, n, rank, nprocs, verbose=1, err;
+ int ncid, cmode, varid[4], dimid[2], nreqs, reqs[4], sts[4];
+ unsigned int *buffer[4];
+ int num_segs[4], req_lens[4];
+ MPI_Offset ***starts, ***counts;
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+ strcpy(exec, argv[0]);
+
+ /* get command-line arguments */
+ while ((i = getopt(argc, argv, "hq")) != EOF)
+ switch(i) {
+ case 'q': verbose = 0;
+ break;
+ case 'h':
+ default: if (rank==0) usage(argv[0]);
+ MPI_Finalize();
+ return 0;
+ }
+ argc -= optind;
+ argv += optind;
+ if (argc == 1) filename = argv[0]; /* optional argument */
+
+ if (nprocs != 4 && rank == 0 && verbose)
+ printf("Warning: %s is intended to run on 4 processes\n",exec);
+
+ /* create a new file for writing ----------------------------------------*/
+ cmode = NC_CLOBBER | NC_64BIT_DATA;
+ err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, MPI_INFO_NULL, &ncid);
+ ERR
+
+ /* create a global array of size NY * NX */
+ err = ncmpi_def_dim(ncid, "Y", NY, &dimid[0]); ERR
+ err = ncmpi_def_dim(ncid, "X", NX, &dimid[1]); ERR
+ err = ncmpi_def_var(ncid, "var0", NC_UINT, NDIMS, dimid, &varid[0]); ERR
+ err = ncmpi_def_var(ncid, "var1", NC_UINT, NDIMS, dimid, &varid[1]); ERR
+ err = ncmpi_def_var(ncid, "var2", NC_UINT, NDIMS, dimid, &varid[2]); ERR
+ err = ncmpi_def_var(ncid, "var3", NC_UINT, NDIMS, dimid, &varid[3]); ERR
+ err = ncmpi_enddef(ncid); ERR
+
+ /* allocate space for starts and counts */
+ starts = calloc_3D(4, 6, NDIMS);
+ counts = calloc_3D(4, 6, NDIMS);
+
+ n = rank % 4;
+ num_segs[n] = 4; /* number of segments for this request */
+ starts[n][0][0]=0; starts[n][0][1]=5; counts[n][0][0]=1; counts[n][0][1]=2;
+ starts[n][1][0]=1; starts[n][1][1]=0; counts[n][1][0]=1; counts[n][1][1]=1;
+ starts[n][2][0]=2; starts[n][2][1]=6; counts[n][2][0]=1; counts[n][2][1]=2;
+ starts[n][3][0]=3; starts[n][3][1]=0; counts[n][3][0]=1; counts[n][3][1]=3;
+ /* starts[n][][] n_counts[n][][] indicate the following: ("-" means skip)
+ - - - - - X X - - -
+ X - - - - - - - - -
+ - - - - - - X X - -
+ X X X - - - - - - -
+ */
+ n = (rank+1) % 4;
+ num_segs[n] = 6; /* number of segments for this request */
+ starts[n][0][0]=0; starts[n][0][1]=3; counts[n][0][0]=1; counts[n][0][1]=2;
+ starts[n][1][0]=0; starts[n][1][1]=8; counts[n][1][0]=1; counts[n][1][1]=2;
+ starts[n][2][0]=1; starts[n][2][1]=5; counts[n][2][0]=1; counts[n][2][1]=2;
+ starts[n][3][0]=2; starts[n][3][1]=0; counts[n][3][0]=1; counts[n][3][1]=2;
+ starts[n][4][0]=2; starts[n][4][1]=8; counts[n][4][0]=1; counts[n][4][1]=2;
+ starts[n][5][0]=3; starts[n][5][1]=4; counts[n][5][0]=1; counts[n][5][1]=3;
+ /* starts[n][][] counts[n][][] indicate the following pattern.
+ - - - X X - - - X X
+ - - - - - X X - - -
+ X X - - - - - - X X
+ - - - - X X X - - -
+ */
+ n = (rank+2) % 4;
+ num_segs[n] = 5; /* number of segments for this request */
+ starts[n][0][0]=0; starts[n][0][1]=7; counts[n][0][0]=1; counts[n][0][1]=1;
+ starts[n][1][0]=1; starts[n][1][1]=1; counts[n][1][0]=1; counts[n][1][1]=3;
+ starts[n][2][0]=1; starts[n][2][1]=7; counts[n][2][0]=1; counts[n][2][1]=3;
+ starts[n][3][0]=2; starts[n][3][1]=2; counts[n][3][0]=1; counts[n][3][1]=1;
+ starts[n][4][0]=3; starts[n][4][1]=3; counts[n][4][0]=1; counts[n][4][1]=1;
+ /* starts[n][][] counts[n][][] indicate the following pattern.
+ - - - - - - - X - -
+ - X X X - - - X X X
+ - - X - - - - - - -
+ - - - X - - - - - -
+ */
+ n = (rank+3) % 4;
+ num_segs[n] = 4; /* number of segments for this request */
+ starts[n][0][0]=0; starts[n][0][1]=0; counts[n][0][0]=1; counts[n][0][1]=3;
+ starts[n][1][0]=1; starts[n][1][1]=4; counts[n][1][0]=1; counts[n][1][1]=1;
+ starts[n][2][0]=2; starts[n][2][1]=3; counts[n][2][0]=1; counts[n][2][1]=3;
+ starts[n][3][0]=3; starts[n][3][1]=7; counts[n][3][0]=1; counts[n][3][1]=3;
+ /*starts[n][][] counts[n][][] indicate the following pattern.
+ X X X - - - - - - -
+ - - - - X - - - - -
+ - - - X X X - - - -
+ - - - - - - - X X X
+ */
+
+ /* only rank 0, 1, 2, and 3 do I/O:
+ * each of ranks 0 to 3 write 4 nonblocking requests */
+ nreqs = 4;
+ if (rank >= 4) nreqs = 0;
+
+ /* bufsize must be max of data type converted before and after */
+ MPI_Offset bufsize = 0;
+
+ /* calculate length of each varn request, number of segments in each
+ * varn request, and allocate write buffer */
+ for (i=0; i<nreqs; i++) {
+ req_lens[i] = 0; /* total length this request */
+ for (j=0; j<num_segs[i]; j++) {
+ MPI_Offset req_len=1;
+ for (k=0; k<NDIMS; k++)
+ req_len *= counts[i][j][k];
+ req_lens[i] += req_len;
+ }
+ if (verbose) printf("req_lens[%d]=%d\n",i,req_lens[i]);
+
+ /* allocate I/O buffer and initialize its contents */
+ buffer[i] = (unsigned int*) malloc(req_lens[i] * sizeof(unsigned int));
+ for (j=0; j<req_lens[i]; j++) buffer[i][j] = rank;
+
+ bufsize += req_lens[i];
+ }
+ bufsize *= sizeof(unsigned int);
+ if (verbose) printf("%d: Attach buffer size %lld\n", rank, bufsize);
+
+ /* give PnetCDF a space to buffer the nonblocking requests */
+ if (bufsize > 0) {
+ err = ncmpi_buffer_attach(ncid, bufsize); ERR
+ }
+
+ /* write using varn API */
+ for (i=0; i<nreqs; i++) {
+ err = ncmpi_bput_varn_uint(ncid, varid[i], num_segs[i], starts[i],
+ counts[i], buffer[i], &reqs[i]);
+ ERR
+ }
+ err = ncmpi_wait_all(ncid, nreqs, reqs, sts);
+ ERRS(nreqs, sts)
+
+ /* check file contents */
+ if (nprocs >= 4) check_contents(ncid, varid);
+
+ for (i=0; i<nreqs; i++) free(buffer[i]);
+
+ /* test flexible put API, using a noncontiguous buftype */
+ for (i=0; i<nreqs; i++) {
+ MPI_Datatype buftype;
+ MPI_Type_vector(req_lens[i], 1, 2, MPI_UNSIGNED, &buftype);
+ MPI_Type_commit(&buftype);
+ buffer[i] = (unsigned int*) malloc(req_lens[i] * 2 * sizeof(unsigned int));
+ for (j=0; j<req_lens[i]*2; j++) buffer[i][j] = rank;
+
+ err = ncmpi_bput_varn(ncid, varid[i], num_segs[i], starts[i],
+ counts[i], buffer[i], 1, buftype, &reqs[i]);
+ ERR
+ MPI_Type_free(&buftype);
+ }
+ err = ncmpi_wait_all(ncid, nreqs, reqs, sts);
+ ERRS(nreqs, sts)
+
+ /* check file contents */
+ if (nprocs >= 4) check_contents(ncid, varid);
+
+ /* free the buffer space for bput */
+ if (bufsize > 0) {
+ err = ncmpi_buffer_detach(ncid); ERR
+ }
+
+ err = ncmpi_close(ncid);
+ ERR
+
+ for (i=0; i<nreqs; i++) free(buffer[i]);
+ free_3D(starts);
+ free_3D(counts);
+
+ /* check if there is any PnetCDF internal malloc residue */
+ MPI_Offset malloc_size, sum_size;
+ err = ncmpi_inq_malloc_size(&malloc_size);
+ if (err == NC_NOERR) {
+ MPI_Reduce(&malloc_size, &sum_size, 1, MPI_OFFSET, MPI_SUM, 0, MPI_COMM_WORLD);
+ if (rank == 0 && sum_size > 0)
+ printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n",
+ sum_size);
+ }
+
+ MPI_Finalize();
+ return 0;
+}
+
diff --git a/examples/C/collective_write.c b/examples/C/collective_write.c
new file mode 100644
index 0000000..86b13df
--- /dev/null
+++ b/examples/C/collective_write.c
@@ -0,0 +1,231 @@
+/*********************************************************************
+ *
+ * Copyright (C) 2012, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ *
+ *********************************************************************/
+/* $Id: collective_write.c 2245 2015-12-20 18:39:52Z wkliao $ */
+
+/*
+ * This example mimics the coll_perf.c from ROMIO.
+ * It creates a netcdf file in CD-5 format and writes a number of
+ * 3D integer non-record variables. The measured write bandwidth is reported
+ * at the end. Usage:
+ * To compile:
+ * mpicc -O2 collective_write.c -o collective_write -lpnetcdf
+ * To run:
+ * mpiexec -n num_processes ./collective_write [filename] [len]
+ * where len decides the size of each local array, which is len x len x len.
+ * So, each non-record variable is of size len*len*len * nprocs * sizeof(int)
+ * All variables are partitioned among all processes in a 3D
+ * block-block-block fashion. Below is an example standard output from
+ * command:
+ * mpiexec -n 32 ./collective_write /pvfs2/wkliao/testfile.nc 100
+ *
+ * MPI hint: cb_nodes = 2
+ * MPI hint: cb_buffer_size = 16777216
+ * MPI hint: striping_factor = 32
+ * MPI hint: striping_unit = 1048576
+ * Local array size 100 x 100 x 100 integers, size = 3.81 MB
+ * Global array size 400 x 400 x 200 integers, write size = 0.30 GB
+ * procs Global array size exec(sec) write(MB/s)
+ * ------- ------------------ --------- -----------
+ * 32 400 x 400 x 200 6.67 45.72
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h> /* strcpy() */
+#include <unistd.h> /* getopt() */
+#include <mpi.h>
+#include <pnetcdf.h>
+
+#define NDIMS 3
+#define NUM_VARS 10
+
+#define HANDLE_ERROR { \
+ if (err != NC_NOERR) \
+ printf("Error at line %d (%s)\n", __LINE__, \
+ ncmpi_strerror(err)); \
+}
+
+static void
+usage(char *argv0)
+{
+ char *help =
+ "Usage: %s [-h] | [-q] [file_name] [len]\n"
+ " [-h] Print help\n"
+ " [-q] Quiet mode (reports when fail)\n"
+ " [filename] output netCDF file name\n"
+ " [len] size of each dimension of the local array\n";
+ fprintf(stderr, help, argv0);
+}
+
+/*----< print_info() >------------------------------------------------------*/
+static
+void print_info(MPI_Info *info_used)
+{
+ int flag;
+ char info_cb_nodes[64], info_cb_buffer_size[64];
+ char info_striping_factor[64], info_striping_unit[64];
+
+ strcpy(info_cb_nodes, "undefined");
+ strcpy(info_cb_buffer_size, "undefined");
+ strcpy(info_striping_factor, "undefined");
+ strcpy(info_striping_unit, "undefined");
+
+ MPI_Info_get(*info_used, "cb_nodes", 64, info_cb_nodes, &flag);
+ MPI_Info_get(*info_used, "cb_buffer_size", 64, info_cb_buffer_size, &flag);
+ MPI_Info_get(*info_used, "striping_factor", 64, info_striping_factor, &flag);
+ MPI_Info_get(*info_used, "striping_unit", 64, info_striping_unit, &flag);
+
+ printf("MPI hint: cb_nodes = %s\n", info_cb_nodes);
+ printf("MPI hint: cb_buffer_size = %s\n", info_cb_buffer_size);
+ printf("MPI hint: striping_factor = %s\n", info_striping_factor);
+ printf("MPI hint: striping_unit = %s\n", info_striping_unit);
+}
+
+/*----< main() >------------------------------------------------------------*/
+int main(int argc, char **argv)
+{
+ extern int optind;
+ char *filename="testfile.nc", str[512];
+ int i, j, rank, nprocs, len, ncid, bufsize, verbose=1, err;
+ int *buf[NUM_VARS], psizes[NDIMS], dimids[NDIMS], varids[NUM_VARS];
+ double write_timing, max_write_timing, write_bw;
+ MPI_Offset gsizes[NDIMS], starts[NDIMS], counts[NDIMS];
+ MPI_Offset write_size, sum_write_size;
+ MPI_Info info_used;
+
+ MPI_Init(&argc,&argv);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+
+ /* get command-line arguments */
+ while ((i = getopt(argc, argv, "hq")) != EOF)
+ switch(i) {
+ case 'q': verbose = 0;
+ break;
+ case 'h':
+ default: if (rank==0) usage(argv[0]);
+ MPI_Finalize();
+ return 0;
+ }
+ argc -= optind;
+ argv += optind;
+ if (argc >= 1) filename = argv[0]; /* optional argument */
+ len = 10;
+ if (argc >= 2) len = atoi(argv[1]); /* optional argument */
+
+ for (i=0; i<NDIMS; i++)
+ psizes[i] = 0;
+
+ MPI_Dims_create(nprocs, NDIMS, psizes);
+ starts[0] = rank % psizes[0];
+ starts[1] = (rank / psizes[1]) % psizes[1];
+ starts[2] = (rank / (psizes[0] * psizes[1])) % psizes[2];
+
+ bufsize = 1;
+ for (i=0; i<NDIMS; i++) {
+ gsizes[i] = len * psizes[i];
+ starts[i] *= len;
+ counts[i] = len;
+ bufsize *= len;
+ }
+
+ /* allocate buffer and initialize with random numbers */
+ srand(rank);
+ for (i=0; i<NUM_VARS; i++) {
+ buf[i] = (int *) malloc(bufsize * sizeof(int));
+ for (j=0; j<bufsize; j++) buf[i][j] = rand();
+ }
+
+ MPI_Barrier(MPI_COMM_WORLD);
+ write_timing = MPI_Wtime();
+
+ /* create the file */
+ err = ncmpi_create(MPI_COMM_WORLD, filename, NC_CLOBBER|NC_64BIT_DATA,
+ MPI_INFO_NULL, &ncid);
+ if (err != NC_NOERR) {
+ printf("Error: ncmpi_create() file %s (%s)\n",filename,ncmpi_strerror(err));
+ MPI_Abort(MPI_COMM_WORLD, -1);
+ exit(1);
+ }
+
+ /* define dimensions */
+ for (i=0; i<NDIMS; i++) {
+ sprintf(str, "%c", 'x'+i);
+ err = ncmpi_def_dim(ncid, str, gsizes[i], &dimids[i]);
+ HANDLE_ERROR
+ }
+
+ /* define variables */
+ for (i=0; i<NUM_VARS; i++) {
+ sprintf(str, "var%d", i);
+ err = ncmpi_def_var(ncid, str, NC_INT, NDIMS, dimids, &varids[i]);
+ HANDLE_ERROR
+ }
+
+ /* exit the define mode */
+ err = ncmpi_enddef(ncid);
+ HANDLE_ERROR
+
+ /* get all the hints used */
+ err = ncmpi_inq_file_info(ncid, &info_used);
+ HANDLE_ERROR
+
+ /* write one variable at a time */
+ for (i=0; i<NUM_VARS; i++) {
+ err = ncmpi_put_vara_int_all(ncid, varids[i], starts, counts, buf[i]);
+ HANDLE_ERROR
+ }
+
+ /* close the file */
+ err = ncmpi_close(ncid);
+ HANDLE_ERROR
+
+ write_timing = MPI_Wtime() - write_timing;
+
+ write_size = bufsize * NUM_VARS * sizeof(int);
+ for (i=0; i<NUM_VARS; i++) free(buf[i]);
+
+ MPI_Reduce(&write_size, &sum_write_size, 1, MPI_LONG_LONG, MPI_SUM, 0, MPI_COMM_WORLD);
+ MPI_Reduce(&write_timing, &max_write_timing, 1, MPI_DOUBLE, MPI_MAX, 0, MPI_COMM_WORLD);
+
+ if (rank == 0 && verbose) {
+ float subarray_size = (float)bufsize*sizeof(int)/1048576.0;
+ print_info(&info_used);
+ printf("Local array size %d x %d x %d integers, size = %.2f MB\n",len,len,len,subarray_size);
+ sum_write_size /= 1048576.0;
+ printf("Global array size %lld x %lld x %lld integers, write size = %.2f GB\n",
+ gsizes[0], gsizes[1], gsizes[2], sum_write_size/1024.0);
+
+ write_bw = sum_write_size/max_write_timing;
+ printf(" procs Global array size exec(sec) write(MB/s)\n");
+ printf("------- ------------------ --------- -----------\n");
+ printf(" %4d %4lld x %4lld x %4lld %8.2f %10.2f\n", nprocs,
+ gsizes[0], gsizes[1], gsizes[2], max_write_timing, write_bw);
+ }
+ MPI_Info_free(&info_used);
+
+ /* print info about PnetCDF internal malloc usage */
+ MPI_Offset malloc_size, sum_size;
+ err = ncmpi_inq_malloc_max_size(&malloc_size);
+ if (err == NC_NOERR) {
+ MPI_Reduce(&malloc_size, &sum_size, 1, MPI_OFFSET, MPI_SUM, 0, MPI_COMM_WORLD);
+ if (rank == 0 && verbose)
+ printf("maximum heap memory allocted by PnetCDF internally is %lld bytes\n",
+ sum_size);
+
+ /* check if there is any PnetCDF internal malloc residue */
+ err = ncmpi_inq_malloc_size(&malloc_size);
+ MPI_Reduce(&malloc_size, &sum_size, 1, MPI_OFFSET, MPI_SUM, 0, MPI_COMM_WORLD);
+ if (rank == 0 && sum_size > 0)
+ printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n",
+ sum_size);
+ }
+
+ MPI_Finalize();
+ return 0;
+}
+
diff --git a/examples/C/column_wise.c b/examples/C/column_wise.c
new file mode 100644
index 0000000..9deeb27
--- /dev/null
+++ b/examples/C/column_wise.c
@@ -0,0 +1,222 @@
+/*********************************************************************
+ *
+ * Copyright (C) 2013, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ *
+ *********************************************************************/
+/* $Id: column_wise.c 2245 2015-12-20 18:39:52Z wkliao $ */
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * This example makes a number of nonblocking API calls, each writes a single
+ * column of a 2D integer array. Each process writes NX columns and any two
+ * consecutive columns are of nprocs columns distance apart from each other. In
+ * this case, the fileview of each process interleaves with all other processes.
+ * If simply concatenating fileviews of all the nonblocking calls will result
+ * in a fileview that violates the MPI-IO requirement on the fileview of which
+ * flattened file offsets must be monotonically non-decreasing. PnetCDF handles
+ * this case by breaking down each nonblocking call into a list of offset-length
+ * pairs, merging the pairs across multiple nonblocking calls, and sorting
+ * them into an increasing order. The sorted pairs are used to construct a
+ * fileview that meets the monotonically non-decreasing offset requirement,
+ * and thus the nonblocking requests can be serviced by a single MPI-IO call.
+ *
+ * The compile and run commands are given below, together with an ncmpidump of
+ * the output file.
+ *
+ * % mpicc -O2 -o column_wise column_wise.c -lpnetcdf
+ * % mpiexec -l -n 4 ./column_wise /pvfs2/wkliao/testfile.nc
+ * 0: 0: myOff= 0 myNX= 4
+ * 1: 1: myOff= 4 myNX= 4
+ * 2: 2: myOff= 8 myNX= 4
+ * 3: 3: myOff= 12 myNX= 4
+ * 0: 0: start= 0 0 count= 10 1
+ * 1: 1: start= 0 1 count= 10 1
+ * 2: 2: start= 0 2 count= 10 1
+ * 3: 3: start= 0 3 count= 10 1
+ *
+ * % ncmpidump /pvfs2/wkliao/testfile.nc
+ * netcdf testfile {
+ * // file format: CDF-5 (big variables)
+ * dimensions:
+ * Y = 10 ;
+ * X = 16 ;
+ * variables:
+ * int var(Y, X) ;
+ * data:
+ *
+ * var =
+ * 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3,
+ * 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3,
+ * 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3,
+ * 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3,
+ * 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3,
+ * 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3,
+ * 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3,
+ * 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3,
+ * 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3,
+ * 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3 ;
+ * }
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h> /* strcpy() */
+#include <unistd.h> /* getopt() */
+#include <mpi.h>
+#include <pnetcdf.h>
+
+#define NY 10
+#define NX 4
+
+#define ERR {if(err!=NC_NOERR)printf("Error at line=%d: %s\n", __LINE__, ncmpi_strerror(err));}
+
+static void
+usage(char *argv0)
+{
+ char *help =
+ "Usage: %s [-h] | [-q] [file_name]\n"
+ " [-h] Print help\n"
+ " [-q] Quiet mode (reports when fail)\n"
+ " [filename] output netCDF file name\n";
+ fprintf(stderr, help, argv0);
+}
+
+int main(int argc, char** argv)
+{
+ extern int optind;
+ char *filename = "testfile.nc";
+ int i, j, verbose=1, rank, nprocs, err, myNX, G_NX, myOff, num_reqs;
+ int ncid, cmode, varid, dimid[2], *reqs, *sts, **buf;
+ MPI_Offset start[2], count[2];
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+
+ /* get command-line arguments */
+ while ((i = getopt(argc, argv, "hq")) != EOF)
+ switch(i) {
+ case 'q': verbose = 0;
+ break;
+ case 'h':
+ default: if (rank==0) usage(argv[0]);
+ MPI_Finalize();
+ return 0;
+ }
+ argc -= optind;
+ argv += optind;
+ if (argc == 1) filename = argv[0]; /* optional argument */
+
+ cmode = NC_CLOBBER | NC_64BIT_DATA;
+ err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, MPI_INFO_NULL, &ncid);
+ ERR
+
+ /* the global array is NY * (NX * nprocs) */
+ G_NX = NX * nprocs;
+ myOff = NX * rank;
+ myNX = NX;
+ if (verbose) printf("%2d: myOff=%3d myNX=%3d\n",rank,myOff,myNX);
+
+ err = ncmpi_def_dim(ncid, "Y", NY, &dimid[0]);
+ ERR
+ err = ncmpi_def_dim(ncid, "X", G_NX, &dimid[1]);
+ ERR
+ err = ncmpi_def_var(ncid, "var", NC_INT, 2, dimid, &varid);
+ ERR
+ err = ncmpi_enddef(ncid);
+ ERR
+
+ /* First, fill the entire array with zeros, using a blocking I/O.
+ Every process writes a subarray of size NY * myNX */
+ buf = (int**) malloc(myNX * sizeof(int*));
+ buf[0] = (int*) calloc(NY * myNX, sizeof(int));
+ start[0] = 0; start[1] = myOff;
+ count[0] = NY; count[1] = myNX;
+ err = ncmpi_put_vara_int_all(ncid, varid, start, count, buf[0]);
+ free(buf[0]);
+
+ /* initialize the buffer with rank ID. Also make the case interesting,
+ by allocating buffers separately */
+ for (i=0; i<myNX; i++) {
+ buf[i] = (int*) malloc(NY * sizeof(int));
+ for (j=0; j<NY; j++) buf[i][j] = rank;
+ }
+
+ reqs = (int*) malloc(myNX * sizeof(int));
+ sts = (int*) malloc(myNX * sizeof(int));
+
+ /* each proc writes myNX single columns of the 2D array */
+ start[0] = 0; start[1] = rank;
+ count[0] = NY; count[1] = 1;
+ if (verbose)
+ printf("%2d: start=%3lld %3lld count=%3lld %3lld\n",
+ rank, start[0],start[1], count[0],count[1]);
+
+ num_reqs = 0;
+ for (i=0; i<myNX; i++) {
+ err = ncmpi_iput_vara_int(ncid, varid, start, count, buf[i],
+ &reqs[num_reqs++]);
+ ERR
+ start[1] += nprocs;
+ }
+ err = ncmpi_wait_all(ncid, num_reqs, reqs, sts);
+ ERR
+
+ /* check status of all requests */
+ for (i=0; i<num_reqs; i++)
+ if (sts[i] != NC_NOERR)
+ printf("Error: nonblocking write fails on request %d (%s)\n",
+ i, ncmpi_strerror(sts[i]));
+
+ /* read back using the same access pattern */
+ for (i=0; i<myNX; i++)
+ for (j=0; j<NY; j++) buf[i][j] = -1;
+
+ /* each proc reads myNX single columns of the 2D array */
+ start[0] = 0; start[1] = rank;
+ count[0] = NY; count[1] = 1;
+
+ num_reqs = 0;
+ for (i=0; i<myNX; i++) {
+ err = ncmpi_iget_vara_int(ncid, varid, start, count, buf[i],
+ &reqs[num_reqs++]);
+ ERR
+ start[1] += nprocs;
+ }
+ err = ncmpi_wait_all(ncid, num_reqs, reqs, sts);
+ ERR
+
+ /* check status of all requests */
+ for (i=0; i<num_reqs; i++)
+ if (sts[i] != NC_NOERR)
+ printf("Error: nonblocking write fails on request %d (%s)\n",
+ i, ncmpi_strerror(sts[i]));
+
+ for (i=0; i<myNX; i++) {
+ for (j=0; j<NY; j++)
+ if (buf[i][j] != rank)
+ printf("Error: expect buf[%d][%d]=%d but got %d\n",i,j,rank,buf[i][j]);
+ }
+
+ err = ncmpi_close(ncid);
+ ERR
+
+ free(sts);
+ free(reqs);
+ for (i=0; i<myNX; i++) free(buf[i]);
+ free(buf);
+
+ /* check if there is any PnetCDF internal malloc residue */
+ MPI_Offset malloc_size, sum_size;
+ err = ncmpi_inq_malloc_size(&malloc_size);
+ if (err == NC_NOERR) {
+ MPI_Reduce(&malloc_size, &sum_size, 1, MPI_OFFSET, MPI_SUM, 0, MPI_COMM_WORLD);
+ if (rank == 0 && sum_size > 0)
+ printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n",
+ sum_size);
+ }
+
+ MPI_Finalize();
+ return 0;
+}
+
diff --git a/examples/C/create_open.c b/examples/C/create_open.c
new file mode 100644
index 0000000..1a133fa
--- /dev/null
+++ b/examples/C/create_open.c
@@ -0,0 +1,105 @@
+/*********************************************************************
+ *
+ * Copyright (C) 2014, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ *
+ *********************************************************************/
+/* $Id: create_open.c 2150 2015-10-10 05:52:57Z wkliao $ */
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * This example shows how to use ncmpi_create() to create a new file and
+ * ncmpi_open() to open the file for read only.
+ *
+ * To compile:
+ * mpicc -O2 create_open.c -o create_open -lpnetcdf
+ *
+ * Example commands for MPI run and outputs from running ncmpidump on the
+ * netCDF file produced by this example program:
+ *
+ * % mpiexec -n 4 ./create_open /pvfs2/wkliao/testfile.nc
+ *
+ * % ncmpidump /pvfs2/wkliao/testfile.nc
+ * netcdf testfile {
+ * // file format: CDF-1
+ * }
+ *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h> /* strcpy() */
+#include <unistd.h> /* getopt() */
+#include <mpi.h>
+#include <pnetcdf.h>
+
+#define ERR {if(err!=NC_NOERR)printf("Error at line=%d: %s\n", __LINE__, ncmpi_strerror(err));}
+
+static void
+usage(char *argv0)
+{
+ char *help =
+ "Usage: %s [-h] | [-q] [file_name]\n"
+ " [-h] Print help\n"
+ " [-q] Quiet mode (reports when fail)\n"
+ " [filename] output netCDF file name\n";
+ fprintf(stderr, help, argv0);
+}
+
+int main(int argc, char** argv)
+{
+ extern int optind;
+ char *filename="testfile.nc";
+ int i, rank, verbose=1, err;
+ int ncid, cmode, omode;
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+
+ /* get command-line arguments */
+ while ((i = getopt(argc, argv, "hq")) != EOF)
+ switch(i) {
+ case 'q': verbose = 0;
+ break;
+ case 'h':
+ default: if (rank==0) usage(argv[0]);
+ MPI_Finalize();
+ return 0;
+ }
+ argc -= optind;
+ argv += optind;
+ if (argc == 1) filename = argv[0]; /* optional argument */
+
+ if (verbose && rank == 0) printf("%s: example of file create and open\n",__FILE__);
+
+ /* create a new file using clobber mode ----------------------------------*/
+ cmode = NC_CLOBBER;
+ err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, MPI_INFO_NULL, &ncid);
+ ERR
+
+ /* close file */
+ err = ncmpi_close(ncid);
+ ERR
+
+ /* open the newly created file for read only -----------------------------*/
+ omode = NC_NOWRITE;
+ err = ncmpi_open(MPI_COMM_WORLD, filename, omode, MPI_INFO_NULL, &ncid);
+ ERR
+
+ /* close file */
+ err = ncmpi_close(ncid);
+ ERR
+
+ /* check if there is any PnetCDF internal malloc residue */
+ MPI_Offset malloc_size, sum_size;
+ err = ncmpi_inq_malloc_size(&malloc_size);
+ if (err == NC_NOERR) {
+ MPI_Reduce(&malloc_size, &sum_size, 1, MPI_OFFSET, MPI_SUM, 0, MPI_COMM_WORLD);
+ if (rank == 0 && sum_size > 0)
+ printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n",
+ sum_size);
+ }
+
+ MPI_Finalize();
+ return 0;
+}
+
diff --git a/examples/C/depend b/examples/C/depend
new file mode 100644
index 0000000..52b6997
--- /dev/null
+++ b/examples/C/depend
@@ -0,0 +1,22 @@
+block_cyclic.o: block_cyclic.c
+collective_write.o: collective_write.c
+column_wise.o: column_wise.c
+flexible_api.o: flexible_api.c
+get_info.o: get_info.c
+hints.o: hints.c
+nonblocking_write.o: nonblocking_write.c
+nonblocking_write_in_def.o: nonblocking_write_in_def.c
+put_vara.o: put_vara.c
+put_varn_float.o: put_varn_float.c
+put_varn_int.o: put_varn_int.c
+mput.o: mput.c
+create_open.o: create_open.c
+global_attributes.o: global_attributes.c
+get_vara.o: get_vara.c
+transpose.o: transpose.c
+vard_int.o: vard_int.c
+i_varn_int64.o: i_varn_int64.c
+bput_varn_uint.o: bput_varn_uint.c
+fill_mode.o: fill_mode.c
+ghost_cell.o: ghost_cell.c
+req_all.o: req_all.c
diff --git a/examples/C/fill_mode.c b/examples/C/fill_mode.c
new file mode 100644
index 0000000..fc48375
--- /dev/null
+++ b/examples/C/fill_mode.c
@@ -0,0 +1,206 @@
+/*********************************************************************
+ *
+ * Copyright (C) 2015, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ *
+ *********************************************************************/
+/* $Id: fill_mode.c 2245 2015-12-20 18:39:52Z wkliao $ */
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * This example shows how to use
+ * 1. ncmpi_set_fill() to enable fill mode
+ * 2. ncmpi_def_var_fill() to define the variable's fill value
+ * 3. ncmpi_inq_var_fill() to inquire the variable's fill mode information
+ * 4. ncmpi_put_vara_int_all() to write two 2D 4-byte integer array in parallel.
+ * It first defines a netCDF record variable of size NC_UNLIMITED * global_ny
+ * where
+ * global_nx == (NX * number of MPI processes).
+ * It then defines a netCDF fixed-size variable of size global_nx * global_ny
+ * where
+ * global_ny == NY and
+ * global_nx == (NX * number of MPI processes).
+ * The data partitioning pattern for both variables are a column-wise
+ * partitioning across all processes. Each process writes a subarray of size
+ * ny * nx.
+ *
+ * To compile:
+ * mpicc -O2 fill_mode.c -o fill_mode -lpnetcdf
+ *
+ * Example commands for MPI run and outputs from running ncmpidump on the
+ * NC file produced by this example program:
+ *
+ * % mpiexec -n 4 ./fill_mode -q /pvfs2/wkliao/testfile.nc
+ *
+ * % ncmpidump /pvfs2/wkliao/testfile.nc
+ * netcdf testfile {
+ * // file format: CDF-1
+ * dimensions:
+ * REC_DIM = UNLIMITED ; // (2 currently)
+ * X = 16 ;
+ * Y = 3 ;
+ * variables:
+ * int rec_var(REC_DIM, X) ;
+ * rec_var:_FillValue = -1 ;
+ * int fix_var(Y, X) ;
+ * data:
+ *
+ * rec_var =
+ * 0, 0, 0, _, 1, 1, 1, _, 2, 2, 2, _, 3, 3, 3, _,
+ * 0, 0, 0, _, 1, 1, 1, _, 2, 2, 2, _, 3, 3, 3, _ ;
+ *
+ * fix_var =
+ * 0, 0, 0, _, 1, 1, 1, _, 2, 2, 2, _, 3, 3, 3, _,
+ * 0, 0, 0, _, 1, 1, 1, _, 2, 2, 2, _, 3, 3, 3, _,
+ * 0, 0, 0, _, 1, 1, 1, _, 2, 2, 2, _, 3, 3, 3, _ ;
+ * }
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h> /* strcpy() */
+#include <unistd.h> /* getopt() */
+#include <assert.h>
+#include <mpi.h>
+#include <pnetcdf.h>
+
+#define NY 3
+#define NX 4
+
+
+#define ERR {if(err!=NC_NOERR)printf("Error at %s line=%d: %s\n",__FILE__,__LINE__, ncmpi_strerror(err));}
+
+static void
+usage(char *argv0)
+{
+ char *help =
+ "Usage: %s [-h] | [-q] [file_name]\n"
+ " [-h] Print help\n"
+ " [-q] Quiet mode (reports when fail)\n"
+ " [filename] output netCDF file name\n";
+ fprintf(stderr, help, argv0);
+}
+
+int main(int argc, char** argv)
+{
+ extern int optind;
+ char filename[256];
+ int i, j, rank, nprocs, verbose=1, err, rec_varid, fix_varid;
+ int ncid, cmode, dimid[2], buf[NY][NX], no_fill, fill_value, old_mode;
+ MPI_Offset global_ny, global_nx;
+ MPI_Offset start[2], count[2];
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+
+ /* get command-line arguments */
+ while ((i = getopt(argc, argv, "hq")) != EOF)
+ switch(i) {
+ case 'q': verbose = 0;
+ break;
+ case 'h':
+ default: if (rank==0) usage(argv[0]);
+ MPI_Finalize();
+ return 0;
+ }
+ argc -= optind;
+ argv += optind;
+ if (argc == 1) strcpy(filename, argv[0]); /* optional argument */
+ else strcpy(filename, "testfile.nc");
+
+ MPI_Bcast(filename, 256, MPI_CHAR, 0, MPI_COMM_WORLD);
+
+ /* create a new file for writing ----------------------------------------*/
+ cmode = NC_CLOBBER;
+ err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, MPI_INFO_NULL, &ncid);
+ ERR
+
+ /* the global array is NY * (NX * nprocs) */
+ global_ny = NY;
+ global_nx = NX * nprocs;
+
+ /* define dimensions x and y */
+ err = ncmpi_def_dim(ncid, "REC_DIM", NC_UNLIMITED, &dimid[0]); ERR
+ err = ncmpi_def_dim(ncid, "X", global_nx, &dimid[1]); ERR
+
+ /* define a 2D variable of integer type */
+ err = ncmpi_def_var(ncid, "rec_var", NC_INT, 2, dimid, &rec_varid); ERR
+
+ err = ncmpi_def_dim(ncid, "Y", global_ny, &dimid[0]); ERR
+ err = ncmpi_def_var(ncid, "fix_var", NC_INT, 2, dimid, &fix_varid); ERR
+
+ /* set the fill mode to NC_FILL for entire file */
+ err = ncmpi_set_fill(ncid, NC_FILL, &old_mode); ERR
+ if (verbose) {
+ if (old_mode == NC_FILL) printf("The old fill mode is NC_FILL\n");
+ else printf("The old fill mode is NC_NOFILL\n");
+ }
+
+ /* set the fill mode back to NC_NOFILL for entire file */
+ err = ncmpi_set_fill(ncid, NC_NOFILL, NULL); ERR
+
+ /* set the variable's fill mode to NC_FILL with default fill value */
+ err = ncmpi_def_var_fill(ncid, fix_varid, 0, NULL); ERR
+
+ /* set a customized fill value -1 */
+ fill_value = -1;
+ err = ncmpi_put_att_int(ncid, rec_varid, "_FillValue", NC_INT, 1, &fill_value);
+ ERR
+
+ /* do not forget to exit define mode */
+ err = ncmpi_enddef(ncid);
+ ERR
+
+ /* now we are in data mode */
+ start[0] = 0;
+ start[1] = NX * rank;
+ count[0] = NY;
+ count[1] = NX;
+
+ /* initialize user buffer */
+ for (i=0; i<NY; i++)
+ for (j=0; j<NX; j++)
+ buf[i][j] = rank;
+
+ /* do not write the variable in full */
+ count[1]--;
+ err = ncmpi_put_vara_int_all(ncid, fix_varid, start, count, &buf[0][0]); ERR
+
+ err = ncmpi_inq_var_fill(ncid, fix_varid, &no_fill, &fill_value); ERR
+ if (no_fill != 0)
+ printf("Error: expecting no_fill to be 0\n");
+ if (fill_value != NC_FILL_INT)
+ printf("Error: expecting no_fill to be %ld but got %d\n",NC_FILL_INT,fill_value);
+
+ /* fill the 1st record of the record variable */
+ start[0] = 0;
+ err = ncmpi_fill_var_rec(ncid, rec_varid, start[0]); ERR
+
+ /* write to the 1st record */
+ count[0] = 1;
+ err = ncmpi_put_vara_int_all(ncid, rec_varid, start, count, &buf[0][0]); ERR
+
+ /* fill the 2nd record of the record variable */
+ start[0] = 1;
+ err = ncmpi_fill_var_rec(ncid, rec_varid, start[0]); ERR
+
+ /* write to the 2nd record */
+ err = ncmpi_put_vara_int_all(ncid, rec_varid, start, count, &buf[0][0]); ERR
+
+ err = ncmpi_close(ncid);
+ ERR
+
+ /* check if there is any PnetCDF internal malloc residue */
+ MPI_Offset malloc_size, sum_size;
+ err = ncmpi_inq_malloc_size(&malloc_size);
+ if (err == NC_NOERR) {
+ MPI_Reduce(&malloc_size, &sum_size, 1, MPI_OFFSET, MPI_SUM, 0, MPI_COMM_WORLD);
+ if (rank == 0 && sum_size > 0)
+ printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n",
+ sum_size);
+ }
+
+ MPI_Finalize();
+ return 0;
+}
+
diff --git a/examples/C/flexible_api.c b/examples/C/flexible_api.c
new file mode 100644
index 0000000..f331dcf
--- /dev/null
+++ b/examples/C/flexible_api.c
@@ -0,0 +1,272 @@
+/*********************************************************************
+ *
+ * Copyright (C) 2013, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ *
+ *********************************************************************/
+/* $Id: flexible_api.c 2150 2015-10-10 05:52:57Z wkliao $ */
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ *
+ * This example shows how to use PnetCDF flexible APIs, ncmpi_put_vara_all()
+ * and ncmpi_iput_vara() to write two 2D array variables (one is of 4-byte
+ * integer byte and the other float type) in parallel. It first defines 2 netCDF
+ * variables of sizes
+ * var_zy: NZ*nprocs x NY
+ * var_yx: NY x NX*nprocs
+ *
+ * The data partitioning patterns on the 2 variables are row-wise and
+ * column-wise, respectively. Each process writes a subarray of size
+ * NZ x NY and NY x NX to var_zy and var_yx, respectively.
+ * Both local buffers have a ghost cell of length 3 surrounded along each
+ * dimension.
+ *
+ * The compile and run commands are given below.
+ *
+ * % mpicc -O2 -o flexible_api flexible_api.c -lpnetcdf
+ *
+ * % mpiexec -l -n 4 ./flexible_api /pvfs2/wkliao/testfile.nc
+ *
+ * % ncmpidump /pvfs2/wkliao/testfile.nc
+ * netcdf testfile {
+ * // file format: CDF-5 (big variables)
+ * dimensions:
+ * Z = 20 ;
+ * Y = 5 ;
+ * X = 20 ;
+ * variables:
+ * int var_zy(Z, Y) ;
+ * float var_yx(Y, X) ;
+ * data:
+ *
+ * var_zy =
+ * 0, 0, 0, 0, 0,
+ * 0, 0, 0, 0, 0,
+ * 0, 0, 0, 0, 0,
+ * 0, 0, 0, 0, 0,
+ * 0, 0, 0, 0, 0,
+ * 1, 1, 1, 1, 1,
+ * 1, 1, 1, 1, 1,
+ * 1, 1, 1, 1, 1,
+ * 1, 1, 1, 1, 1,
+ * 1, 1, 1, 1, 1,
+ * 2, 2, 2, 2, 2,
+ * 2, 2, 2, 2, 2,
+ * 2, 2, 2, 2, 2,
+ * 2, 2, 2, 2, 2,
+ * 2, 2, 2, 2, 2,
+ * 3, 3, 3, 3, 3,
+ * 3, 3, 3, 3, 3,
+ * 3, 3, 3, 3, 3,
+ * 3, 3, 3, 3, 3,
+ * 3, 3, 3, 3, 3 ;
+ *
+ * var_yx =
+ * 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3,
+ * 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3,
+ * 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3,
+ * 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3,
+ * 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3 ;
+ * }
+ *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h> /* strcpy() */
+#include <unistd.h> /* getopt() */
+#include <assert.h>
+#include <mpi.h>
+#include <pnetcdf.h>
+
+#define NZ 5
+#define NY 5
+#define NX 5
+
+#define ERR {if(err!=NC_NOERR)printf("Error at line=%d: %s\n", __LINE__, ncmpi_strerror(err));}
+
+static void
+usage(char *argv0)
+{
+ char *help =
+ "Usage: %s [-h] | [-q] [file_name]\n"
+ " [-h] Print help\n"
+ " [-q] Quiet mode (reports when fail)\n"
+ " [filename] output netCDF file name\n";
+ fprintf(stderr, help, argv0);
+}
+
+int main(int argc, char** argv)
+{
+ extern int optind;
+ char *filename="testfile.nc";
+ int i, j, rank, nprocs, verbose=1, err, req, status, ghost_len=3;
+ int ncid, cmode, varid0, varid1, dimid[3], *buf_zy;
+ int array_of_sizes[2], array_of_subsizes[2], array_of_starts[2];
+ double *buf_yx;
+ MPI_Offset start[2], count[2];
+ MPI_Datatype subarray;
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+
+ /* get command-line arguments */
+ while ((i = getopt(argc, argv, "hq")) != EOF)
+ switch(i) {
+ case 'q': verbose = 0;
+ break;
+ case 'h':
+ default: if (rank==0) usage(argv[0]);
+ MPI_Finalize();
+ return 0;
+ }
+ argc -= optind;
+ argv += optind;
+ if (argc == 1) filename = argv[0]; /* optional argument */
+
+ if (verbose && rank == 0) printf("%s: example of using flexible APIs\n",__FILE__);
+
+ /* create a new file for writing ----------------------------------------*/
+ cmode = NC_CLOBBER | NC_64BIT_DATA;
+ err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, MPI_INFO_NULL, &ncid);
+ ERR
+
+ /* define 3 dimensions */
+ err = ncmpi_def_dim(ncid, "Z", NZ*nprocs, &dimid[0]); ERR
+ err = ncmpi_def_dim(ncid, "Y", NY, &dimid[1]); ERR
+ err = ncmpi_def_dim(ncid, "X", NX*nprocs, &dimid[2]); ERR
+
+ /* define a variable of size (NZ * nprocs) * NY */
+ err = ncmpi_def_var(ncid, "var_zy", NC_INT, 2, &dimid[0], &varid0); ERR
+ /* define a variable of size NY * (NX * nprocs) */
+ err = ncmpi_def_var(ncid, "var_yx", NC_FLOAT, 2, &dimid[1], &varid1); ERR
+ err = ncmpi_enddef(ncid); ERR
+
+ /* var_zy is partitioned along Z dimension */
+ array_of_sizes[0] = NZ + 2*ghost_len;
+ array_of_sizes[1] = NY + 2*ghost_len;
+ array_of_subsizes[0] = NZ;
+ array_of_subsizes[1] = NY;
+ array_of_starts[0] = ghost_len;
+ array_of_starts[1] = ghost_len;
+ MPI_Type_create_subarray(2, array_of_sizes, array_of_subsizes,
+ array_of_starts, MPI_ORDER_C, MPI_INT, &subarray);
+ MPI_Type_commit(&subarray);
+
+ int buffer_len = (NZ+2*ghost_len) * (NY+2*ghost_len);
+ buf_zy = (int*) malloc(buffer_len * sizeof(int));
+ for (i=0; i<buffer_len; i++) buf_zy[i] = rank;
+
+ start[0] = NZ * rank; start[1] = 0;
+ count[0] = NZ; count[1] = NY;
+ /* calling a blocking flexible API */
+ err = ncmpi_put_vara_all(ncid, varid0, start, count, buf_zy, 1, subarray);
+ ERR
+
+ /* check the contents of put buffer */
+ for (i=0; i<buffer_len; i++) {
+ if (buf_zy[i] != rank)
+ printf("Error put buffer[%d] is altered\n",i);
+ }
+
+ for (i=0; i<buffer_len; i++) buf_zy[i] = -1;
+ /* calling a blocking flexible API */
+ err = ncmpi_get_vara_all(ncid, varid0, start, count, buf_zy, 1, subarray);
+ ERR
+
+ /* check the contents of get buffer */
+ for (i=0; i<array_of_sizes[0]; i++) {
+ for (j=0; j<array_of_sizes[1]; j++) {
+ int index = i*array_of_sizes[1] + j;
+ if (i < ghost_len || ghost_len+array_of_subsizes[0] <= i ||
+ j < ghost_len || ghost_len+array_of_subsizes[1] <= j) {
+ if (buf_zy[index] != -1)
+ printf("Unexpected get buffer[%d][%d]=%d\n",
+ i,j,buf_zy[index]);
+ }
+ else {
+ if (buf_zy[index] != rank)
+ printf("Unexpected get buffer[%d][%d]=%d\n",
+ i,j,buf_zy[index]);
+ }
+ }
+ }
+ free(buf_zy);
+ MPI_Type_free(&subarray);
+
+ /* var_yx is partitioned along X dimension */
+ array_of_sizes[0] = NY + 2*ghost_len;
+ array_of_sizes[1] = NX + 2*ghost_len;
+ array_of_subsizes[0] = NY;
+ array_of_subsizes[1] = NX;
+ array_of_starts[0] = ghost_len;
+ array_of_starts[1] = ghost_len;
+ MPI_Type_create_subarray(2, array_of_sizes, array_of_subsizes,
+ array_of_starts, MPI_ORDER_C, MPI_DOUBLE,
+ &subarray);
+ MPI_Type_commit(&subarray);
+
+ buffer_len = (NY+2*ghost_len) * (NX+2*ghost_len);
+ buf_yx = (double*) malloc(buffer_len * sizeof(double));
+ for (i=0; i<buffer_len; i++) buf_yx[i] = rank;
+
+ start[0] = 0; start[1] = NX * rank;
+ count[0] = NY; count[1] = NX;
+
+ /* calling a non-blocking flexible API */
+ err = ncmpi_iput_vara(ncid, varid1, start, count, buf_yx, 1, subarray,&req);
+ ERR
+ err = ncmpi_wait_all(ncid, 1, &req, &status); ERR
+ err = status; ERR
+
+ /* check the contents of put buffer */
+ for (i=0; i<buffer_len; i++) {
+ if (buf_yx[i] != rank)
+ printf("Error iput buffer[%d]=%f is altered\n",i,buf_yx[i]);
+ }
+
+ for (i=0; i<buffer_len; i++) buf_yx[i] = -1;
+
+ /* calling a non-blocking flexible API */
+ err = ncmpi_iget_vara(ncid, varid1, start, count, buf_yx, 1, subarray,&req);
+ ERR
+ err = ncmpi_wait_all(ncid, 1, &req, &status); ERR
+ err = status; ERR
+
+ /* check the contents of iget buffer */
+ for (i=0; i<array_of_sizes[0]; i++) {
+ for (j=0; j<array_of_sizes[1]; j++) {
+ int index = i*array_of_sizes[1] + j;
+ if (i < ghost_len || ghost_len+array_of_subsizes[0] <= i ||
+ j < ghost_len || ghost_len+array_of_subsizes[1] <= j) {
+ if (buf_yx[index] != -1)
+ printf("Unexpected get buffer[%d][%d]=%f\n",
+ i,j,buf_yx[index]);
+ }
+ else {
+ if (buf_yx[index] != rank)
+ printf("Unexpected get buffer[%d][%d]=%f\n",
+ i,j,buf_yx[index]);
+ }
+ }
+ }
+ free(buf_yx);
+ MPI_Type_free(&subarray);
+
+ err = ncmpi_close(ncid); ERR
+
+ /* check if there is any PnetCDF internal malloc residue */
+ MPI_Offset malloc_size, sum_size;
+ err = ncmpi_inq_malloc_size(&malloc_size);
+ if (err == NC_NOERR) {
+ MPI_Reduce(&malloc_size, &sum_size, 1, MPI_OFFSET, MPI_SUM, 0, MPI_COMM_WORLD);
+ if (rank == 0 && sum_size > 0)
+ printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n",
+ sum_size);
+ }
+
+ MPI_Finalize();
+ return 0;
+}
+
diff --git a/examples/C/get_info.c b/examples/C/get_info.c
new file mode 100644
index 0000000..1a655d3
--- /dev/null
+++ b/examples/C/get_info.c
@@ -0,0 +1,145 @@
+/*********************************************************************
+ *
+ * Copyright (C) 2012, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ *
+ *********************************************************************/
+/* $Id: get_info.c 1669 2014-05-24 18:28:16Z wkliao $ */
+
+/*
+ * prints all MPI-IO hints used
+ * To compile:
+ * mpicc -O2 get_info.c -o get_info -lpnetcdf
+ * To run:
+ * mpiexec -n 4 ./get_info [filename]
+ *
+ * Example standard output:
+
+ MPI File Info: nkeys = 18
+ MPI File Info: [ 0] key = cb_buffer_size, value = 16777216
+ MPI File Info: [ 1] key = romio_cb_read, value = automatic
+ MPI File Info: [ 2] key = romio_cb_write, value = automatic
+ MPI File Info: [ 3] key = cb_nodes, value = 1
+ MPI File Info: [ 4] key = romio_no_indep_rw, value = false
+ MPI File Info: [ 5] key = romio_cb_pfr, value = disable
+ MPI File Info: [ 6] key = romio_cb_fr_types, value = aar
+ MPI File Info: [ 7] key = romio_cb_fr_alignment, value = 1
+ MPI File Info: [ 8] key = romio_cb_ds_threshold, value = 0
+ MPI File Info: [ 9] key = romio_cb_alltoall, value = automatic
+ MPI File Info: [10] key = ind_rd_buffer_size, value = 4194304
+ MPI File Info: [11] key = ind_wr_buffer_size, value = 524288
+ MPI File Info: [12] key = romio_ds_read, value = automatic
+ MPI File Info: [13] key = romio_ds_write, value = automatic
+ MPI File Info: [14] key = cb_config_list, value = *:1
+ MPI File Info: [15] key = nc_header_align_size, value = 512
+ MPI File Info: [16] key = nc_var_align_size, value = 512
+ MPI File Info: [17] key = nc_header_read_chunk_size, value = 0
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h> /* strcpy() */
+#include <unistd.h> /* getopt() */
+#include <mpi.h>
+#include <pnetcdf.h>
+
+
+#define HANDLE_ERROR { \
+ if (err != NC_NOERR) \
+ printf("Error at line %d (%s)\n", __LINE__, \
+ ncmpi_strerror(err)); \
+}
+
+static void
+usage(char *argv0)
+{
+ char *help =
+ "Usage: %s [-h] | [-q] [file_name]\n"
+ " [-h] Print help\n"
+ " [-q] Quiet mode (reports when fail)\n"
+ " [filename] output netCDF file name\n";
+ fprintf(stderr, help, argv0);
+}
+
+/*----< print_info() >------------------------------------------------------*/
+static
+void print_info(MPI_Info *info_used)
+{
+ int i, nkeys;
+
+ MPI_Info_get_nkeys(*info_used, &nkeys);
+ printf("MPI File Info: nkeys = %d\n",nkeys);
+ for (i=0; i<nkeys; i++) {
+ char key[MPI_MAX_INFO_KEY], value[MPI_MAX_INFO_VAL];
+ int valuelen, flag;
+
+ MPI_Info_get_nthkey(*info_used, i, key);
+ MPI_Info_get_valuelen(*info_used, key, &valuelen, &flag);
+ MPI_Info_get(*info_used, key, valuelen+1, value, &flag);
+ printf("MPI File Info: [%2d] key = %25s, value = %s\n",i,key,value);
+ }
+}
+
+/*----< main() >------------------------------------------------------------*/
+int main(int argc, char **argv)
+{
+ extern int optind;
+ char *filename="testfile.nc";
+ int i, rank, ncid, verbose=1, err;
+ MPI_Info info_used;
+
+ MPI_Init(&argc,&argv);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+
+ /* get command-line arguments */
+ while ((i = getopt(argc, argv, "hq")) != EOF)
+ switch(i) {
+ case 'q': verbose = 0;
+ break;
+ case 'h':
+ default: if (rank==0) usage(argv[0]);
+ MPI_Finalize();
+ return 0;
+ }
+ argc -= optind;
+ argv += optind;
+ if (argc == 1) filename = argv[0]; /* optional argument */
+
+ /* create the file */
+ err = ncmpi_create(MPI_COMM_WORLD, filename, NC_CLOBBER|NC_64BIT_DATA,
+ MPI_INFO_NULL, &ncid);
+ if (err != NC_NOERR) {
+ printf("Error: ncmpi_create() file %s (%s)\n",filename,ncmpi_strerror(err));
+ MPI_Abort(MPI_COMM_WORLD, -1);
+ exit(1);
+ }
+
+ /* exit the define mode */
+ err = ncmpi_enddef(ncid);
+ HANDLE_ERROR
+
+ /* get all the hints used */
+ err = ncmpi_inq_file_info(ncid, &info_used);
+ HANDLE_ERROR
+
+ /* close the file */
+ err = ncmpi_close(ncid);
+ HANDLE_ERROR
+
+ if (rank == 0 && verbose) print_info(&info_used);
+ MPI_Info_free(&info_used);
+
+ /* check if there is any PnetCDF internal malloc residue */
+ MPI_Offset malloc_size, sum_size;
+ err = ncmpi_inq_malloc_size(&malloc_size);
+ if (err == NC_NOERR) {
+ MPI_Reduce(&malloc_size, &sum_size, 1, MPI_OFFSET, MPI_SUM, 0, MPI_COMM_WORLD);
+ if (rank == 0 && sum_size > 0)
+ printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n",
+ sum_size);
+ }
+
+ MPI_Finalize();
+ return 0;
+}
+
diff --git a/examples/C/get_vara.c b/examples/C/get_vara.c
new file mode 100644
index 0000000..0260426
--- /dev/null
+++ b/examples/C/get_vara.c
@@ -0,0 +1,188 @@
+/*********************************************************************
+ *
+ * Copyright (C) 2014, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ *
+ *********************************************************************/
+/* $Id: get_vara.c 2245 2015-12-20 18:39:52Z wkliao $ */
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * This example is the read counterpart of example put_vara.c. It shows how to
+ * use ncmpi_get_vara_int_all() to read a 2D 4-byte integer array in parallel.
+ * It also reads a global attribute and two attribute of variable named "var".
+ * The data partitioning pattern is a column-wise partitioning across all
+ * processes. Each process reads a subarray of size local_ny * local_nx.
+ *
+ * To compile:
+ * mpicc -O2 get_vara.c -o get_vara -lpnetcdf
+ *
+ * Input file is the output file produced by put_vara.c. Here is the CDL dumped
+ * from running ncmpidump.
+ *
+ * % ncmpidump /pvfs2/wkliao/testfile.nc
+ * netcdf testfile {
+ * // file format: CDF-1
+ * dimensions:
+ * y = 10 ;
+ * x = 16 ;
+ * variables:
+ * int var(y, x) ;
+ * var:str_att_name = "example attribute of type text." ;
+ * var:float_att_name = 0.f, 1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 7.f ;
+ * // global attributes:
+ * :history = "Wed Apr 30 11:18:58 2014\n",
+ * "" ;
+ * data:
+ *
+ * var =
+ * 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3,
+ * 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3,
+ * 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3,
+ * 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3,
+ * 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3,
+ * 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3,
+ * 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3,
+ * 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3,
+ * 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3,
+ * 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3 ;
+ * }
+ *
+ * Example command for MPI run:
+ *
+ * % mpiexec -n 4 ./get_vara /pvfs2/wkliao/testfile.nc
+ *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h> /* strcpy() */
+#include <unistd.h> /* getopt() */
+#include <mpi.h>
+#include <pnetcdf.h>
+
+#define CHECK_ERR { \
+ if (err!=NC_NOERR) { \
+ printf("Error at line=%d: %s\n", __LINE__, ncmpi_strerror(err)); \
+ goto fn_exit; \
+ } \
+}
+
+static void
+usage(char *argv0)
+{
+ char *help =
+ "Usage: %s [-h] | [-q] [file_name]\n"
+ " [-h] Print help\n"
+ " [-q] Quiet mode (reports when fail)\n"
+ " [filename] input netCDF file name\n";
+ fprintf(stderr, help, argv0);
+}
+
+int main(int argc, char** argv)
+{
+ extern int optind;
+ char *filename="testfile.nc", str_att[NC_MAX_NAME];
+ int i, rank, nprocs, err, verbose=1, ncid, varid, dimid[2], *buf;
+ float *float_att;
+ MPI_Offset len, global_ny, global_nx, local_ny, local_nx;
+ MPI_Offset start[2], count[2];
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+
+ /* get command-line arguments */
+ while ((i = getopt(argc, argv, "hq")) != EOF)
+ switch(i) {
+ case 'q': verbose = 0;
+ break;
+ case 'h':
+ default: if (rank==0) usage(argv[0]);
+ MPI_Finalize();
+ return 0;
+ }
+ argc -= optind;
+ argv += optind;
+ if (argc == 1) filename = argv[0]; /* optional argument */
+
+ /* open an existing file for reading -------------------------------------*/
+ err = ncmpi_open(MPI_COMM_WORLD, filename, NC_NOWRITE, MPI_INFO_NULL, &ncid);
+ CHECK_ERR
+
+ /* get global attribute named "history" */
+ err = ncmpi_get_att_text(ncid, NC_GLOBAL, "history", str_att);
+ CHECK_ERR
+ err = ncmpi_inq_attlen(ncid, NC_GLOBAL, "history", &len);
+ CHECK_ERR
+ str_att[len] = '\0'; /* add a NULL char at the end */
+ if (rank == 0 && verbose)
+ printf("global attribute \"history\" of text: %s\n",str_att);
+
+ /* get dimension IDs for dimensions Y and X */
+ err = ncmpi_inq_dimid(ncid, "Y", &dimid[0]);
+ CHECK_ERR
+ err = ncmpi_inq_dimid(ncid, "X", &dimid[1]);
+ CHECK_ERR
+
+ /* get dimension lengths for dimensions Y and X */
+ err = ncmpi_inq_dimlen(ncid, dimid[0], &global_ny);
+ CHECK_ERR
+ err = ncmpi_inq_dimlen(ncid, dimid[1], &global_nx);
+ CHECK_ERR
+
+ /* get the variable ID of a 2D variable of integer type */
+ err = ncmpi_inq_varid(ncid, "var", &varid);
+ CHECK_ERR
+
+ /* get variable's attribute named "str_att_name" */
+ err = ncmpi_get_att_text(ncid, varid, "str_att_name", str_att);
+ CHECK_ERR
+ err = ncmpi_inq_attlen(ncid, varid, "str_att_name", &len);
+ CHECK_ERR
+ str_att[len] = '\0'; /* add a NULL char at the end */
+ if (rank == 0 && verbose)
+ printf("variable attribute \"str_att_name\" of type text = \"%s\"\n",
+ str_att);
+
+ /* get the length of variable's attribute named "float_att_name" */
+ err = ncmpi_inq_attlen(ncid, varid, "float_att_name", &len);
+ CHECK_ERR
+
+ /* get attribute contents */
+ float_att = (float*) malloc(len * sizeof(float));
+ err = ncmpi_get_att_float(ncid, varid, "float_att_name", float_att);
+ CHECK_ERR
+
+ /* the local array size */
+ local_ny = global_ny;
+ local_nx = global_nx / nprocs;
+ buf = (int*) malloc(local_nx * local_ny * sizeof(int));
+
+ /* prepare reading subarray */
+ start[0] = 0;
+ start[1] = local_nx * rank;
+ count[0] = local_ny;
+ count[1] = local_nx;
+
+ /* read a subarray in collective mode */
+ err = ncmpi_get_vara_int_all(ncid, varid, start, count, buf);
+ CHECK_ERR
+
+ err = ncmpi_close(ncid);
+ CHECK_ERR
+
+ /* check if there is any PnetCDF internal malloc residue */
+ MPI_Offset malloc_size, sum_size;
+ err = ncmpi_inq_malloc_size(&malloc_size);
+ if (err == NC_NOERR) {
+ MPI_Reduce(&malloc_size, &sum_size, 1, MPI_OFFSET, MPI_SUM, 0, MPI_COMM_WORLD);
+ if (rank == 0 && sum_size > 0)
+ printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n",
+ sum_size);
+ }
+
+fn_exit:
+ MPI_Finalize();
+ return 0;
+}
+
diff --git a/examples/C/ghost_cell.c b/examples/C/ghost_cell.c
new file mode 100644
index 0000000..6c1116c
--- /dev/null
+++ b/examples/C/ghost_cell.c
@@ -0,0 +1,206 @@
+/*********************************************************************
+ *
+ * Copyright (C) 2015, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ *
+ *********************************************************************/
+/* $Id: ghost_cell.c 2010 2015-02-14 19:45:48Z wkliao $ */
+
+/*
+ * This example shows how to use varm API to write a 2D array buffer with ghost
+ * cells to a variables. The size of ghost cells is nghosts and the ghost cells
+ * cells appear on both ends of each dimension. The contents of ghost cells are
+ * -8s and non-ghost cells are the process rank IDs.
+ *
+ * To compile:
+ * mpicc -O2 ghost_cell.c -o ghost_cell -lpnetcdf
+ * To run:
+ * mpiexec -n num_processes ./ghost_cell [filename] [len]
+ * where len decides the size of local array, which is len x len+1.
+ * So, the variable is of size len*(len+1) * nprocs * sizeof(int)
+ *
+ * The screen outputs from running ncmpidump on the output file produced by
+ * command:
+ * % mpiexec -n 4 ./ghost_cell -q /pvfs2/wkliao/testfile.nc 4
+ *
+ * % ncmpidump /pvfs2/wkliao/testfile.nc
+ * netcdf testfile {
+ * // file format: CDF-5 (big variables)
+ * dimensions:
+ * Y = 8 ;
+ * X = 10 ;
+ * variables:
+ * int var(Y, X) ;
+ * data:
+ *
+ * var =
+ * 0, 0, 0, 0, 0, 1, 1, 1, 1, 1,
+ * 0, 0, 0, 0, 0, 1, 1, 1, 1, 1,
+ * 0, 0, 0, 0, 0, 1, 1, 1, 1, 1,
+ * 0, 0, 0, 0, 0, 1, 1, 1, 1, 1,
+ * 2, 2, 2, 2, 2, 3, 3, 3, 3, 3,
+ * 2, 2, 2, 2, 2, 3, 3, 3, 3, 3,
+ * 2, 2, 2, 2, 2, 3, 3, 3, 3, 3,
+ * 2, 2, 2, 2, 2, 3, 3, 3, 3, 3 ;
+ * }
+ *
+ * In this case, the contents of local buffers are shown below.
+ *
+ * rank 0: rank 1:
+ * -8, -8, -8, -8, -8, -8, -8, -8, -8 -8, -8, -8, -8, -8, -8, -8, -8, -8
+ * -8, -8, -8, -8, -8, -8, -8, -8, -8 -8, -8, -8, -8, -8, -8, -8, -8, -8
+ * -8, -8, 0, 0, 0, 0, 0, -8, -8 -8, -8, 1, 1, 1, 1, 1, -8, -8
+ * -8, -8, 0, 0, 0, 0, 0, -8, -8 -8, -8, 1, 1, 1, 1, 1, -8, -8
+ * -8, -8, 0, 0, 0, 0, 0, -8, -8 -8, -8, 1, 1, 1, 1, 1, -8, -8
+ * -8, -8, 0, 0, 0, 0, 0, -8, -8 -8, -8, 1, 1, 1, 1, 1, -8, -8
+ * -8, -8, -8, -8, -8, -8, -8, -8, -8 -8, -8, -8, -8, -8, -8, -8, -8, -8
+ * -8, -8, -8, -8, -8, -8, -8, -8, -8 -8, -8, -8, -8, -8, -8, -8, -8, -8
+ *
+ * rank 2: rank 3:
+ * -8, -8, -8, -8, -8, -8, -8, -8, -8 -8, -8, -8, -8, -8, -8, -8, -8, -8
+ * -8, -8, -8, -8, -8, -8, -8, -8, -8 -8, -8, -8, -8, -8, -8, -8, -8, -8
+ * -8, -8, 2, 2, 2, 2, 2, -8, -8 -8, -8, 3, 3, 3, 3, 3, -8, -8
+ * -8, -8, 2, 2, 2, 2, 2, -8, -8 -8, -8, 3, 3, 3, 3, 3, -8, -8
+ * -8, -8, 2, 2, 2, 2, 2, -8, -8 -8, -8, 3, 3, 3, 3, 3, -8, -8
+ * -8, -8, 2, 2, 2, 2, 2, -8, -8 -8, -8, 3, 3, 3, 3, 3, -8, -8
+ * -8, -8, -8, -8, -8, -8, -8, -8, -8 -8, -8, -8, -8, -8, -8, -8, -8, -8
+ * -8, -8, -8, -8, -8, -8, -8, -8, -8 -8, -8, -8, -8, -8, -8, -8, -8, -8
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h> /* strlen() */
+#include <unistd.h> /* getopt() */
+#include <mpi.h>
+#include <pnetcdf.h>
+
+#define HANDLE_ERROR { \
+ if (err != NC_NOERR) \
+ printf("Error at %s line %d (%s)\n",__FILE__,__LINE__, \
+ ncmpi_strerror(err)); \
+}
+
+static void
+usage(char *argv0)
+{
+ char *help =
+ "Usage: %s [-h] | [-q] [file_name] [len]\n"
+ " [-h] Print this help\n"
+ " [-q] quiet mode\n"
+ " [filename] output netCDF file name\n"
+ " [len] size of each dimension of the local array\n";
+ fprintf(stderr, help, argv0);
+}
+
+
+/*----< main() >------------------------------------------------------------*/
+int main(int argc, char **argv)
+{
+ extern int optind;
+ char *filename="testfile.nc";
+ int i, j, rank, nprocs, len, ncid, bufsize, verbose=1, err;
+ int psizes[2], local_rank[2], dimids[2], varid, nghosts;
+ int *buf, *buf_ptr;
+ MPI_Offset gsizes[2], starts[2], counts[2], imap[2];
+
+ MPI_Init(&argc,&argv);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+
+ /* get command-line arguments */
+ while ((i = getopt(argc, argv, "hq")) != EOF)
+ switch(i) {
+ case 'q': verbose = 0;
+ break;
+ case 'h':
+ default: if (rank==0) usage(argv[0]);
+ MPI_Finalize();
+ return 0;
+ }
+ argc -= optind;
+ argv += optind;
+ if (argc >= 1) filename = argv[0]; /* optional argument */
+ len = 4;
+ if (argc >= 2) len = atoi(argv[1]); /* optional argument */
+
+ /* calculate number of processes along each dimension */
+ psizes[0] = psizes[1] = 0;
+ MPI_Dims_create(nprocs, 2, psizes);
+ if (verbose && rank == 0)
+ printf("psizes=%d %d\n", psizes[0], psizes[1]);
+
+ gsizes[0] = len * psizes[0]; /* global array size */
+ gsizes[1] = (len+1) * psizes[1];
+ if (verbose && rank == 0)
+ printf("global variable shape: %lld %lld\n", gsizes[0],gsizes[1]);
+
+ /* find its local rank IDs along each dimension */
+ local_rank[0] = rank / psizes[1];
+ local_rank[1] = rank % psizes[1];
+ if (verbose)
+ printf("rank %d: dim rank=%d %d\n", rank,local_rank[0],local_rank[1]);
+
+ counts[0] = len;
+ counts[1] = len+1;
+ starts[0] = local_rank[0] * counts[0];
+ starts[1] = local_rank[1] * counts[1];
+ if (verbose)
+ printf("starts=%lld %lld counts=%lld %lld\n",starts[0],starts[1],counts[0],counts[1]);
+
+ /* allocate and initialize buffer with ghost cells on both ends of each dim */
+ nghosts = 2;
+ bufsize = (counts[0] + 2 * nghosts) * (counts[1] + 2 * nghosts);
+ buf = (int *) malloc(bufsize * sizeof(int));
+ for (i=0; i<counts[0]+2*nghosts; i++)
+ for (j=0; j<counts[1]+2*nghosts; j++) {
+ if (nghosts <= i && i < counts[0]+nghosts &&
+ nghosts <= j && j < counts[1]+nghosts)
+ buf[i*(counts[1]+2*nghosts) + j] = rank;
+ else
+ buf[i*(counts[1]+2*nghosts) + j] = -8; /* all ghost cells have value -8 */
+ }
+
+ /* create the file */
+ err = ncmpi_create(MPI_COMM_WORLD, filename, NC_CLOBBER|NC_64BIT_DATA,
+ MPI_INFO_NULL, &ncid);
+ if (err != NC_NOERR) {
+ printf("Error: ncmpi_create() file %s (%s)\n",filename,ncmpi_strerror(err));
+ MPI_Abort(MPI_COMM_WORLD, -1);
+ exit(1);
+ }
+
+ /* define dimensions */
+ err = ncmpi_def_dim(ncid, "Y", gsizes[0], &dimids[0]);
+ HANDLE_ERROR
+ err = ncmpi_def_dim(ncid, "X", gsizes[1], &dimids[1]);
+ HANDLE_ERROR
+
+ /* define variable */
+ err = ncmpi_def_var(ncid, "var", NC_INT, 2, dimids, &varid);
+ HANDLE_ERROR
+
+ /* exit the define mode */
+ err = ncmpi_enddef(ncid);
+ HANDLE_ERROR
+
+ /* set up imap[] for excluding ghost cells */
+ imap[1] = 1;
+ imap[0] = counts[1] + 2 * nghosts;
+
+ /* find the first non-ghost cell of the user buf */
+ buf_ptr = buf + nghosts * (counts[1]+2*nghosts + 1);
+
+ /* write the whole variable in file */
+ err = ncmpi_put_varm_int_all(ncid, varid, starts, counts, NULL, imap, buf_ptr);
+ HANDLE_ERROR
+
+ /* close the file */
+ err = ncmpi_close(ncid);
+ HANDLE_ERROR
+
+ free(buf);
+
+ MPI_Finalize();
+ return 0;
+}
+
diff --git a/examples/C/global_attributes.c b/examples/C/global_attributes.c
new file mode 100644
index 0000000..180d6e5
--- /dev/null
+++ b/examples/C/global_attributes.c
@@ -0,0 +1,186 @@
+/*********************************************************************
+ *
+ * Copyright (C) 2014, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ *
+ *********************************************************************/
+/* $Id: global_attributes.c 1713 2014-07-06 04:23:57Z wkliao $ */
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * This example creates a new file and add 2 global attributes, one is of text
+ * type and the other 10 short integers. The file is closed and re-opened to
+ * read back the attributes.
+ *
+ * To compile:
+ * mpicc -O2 global_attributes.c -o global_attributes -lpnetcdf
+ *
+ * Example commands for MPI run and outputs from running ncmpidump on the
+ * netCDF file produced by this example program:
+ *
+ * % mpiexec -n 4 ./global_attributes /pvfs2/wkliao/testfile.nc
+ *
+ * % ncmpidump /pvfs2/wkliao/testfile.nc
+ * netcdf testfile {
+ * // file format: CDF-1
+ *
+ * // global attributes:
+ * :history = "Sun May 4 13:11:47 2014\n",
+ * "" ;
+ * :digits = 0s, 1s, 2s, 3s, 4s, 5s, 6s, 7s, 8s, 9s ;
+ * }
+ *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h> /* strlen(), strcpy() */
+#include <unistd.h> /* getopt() */
+#include <time.h> /* time() localtime(), asctime() */
+#include <mpi.h>
+#include <pnetcdf.h>
+
+#define ERR { \
+ if(err!=NC_NOERR) { \
+ printf("Error at line=%d: %s\n", __LINE__, ncmpi_strerror(err)); \
+ goto fn_exit; \
+ } \
+}
+
+static void
+usage(char *argv0)
+{
+ char *help =
+ "Usage: %s [-h] | [-q] [file_name]\n"
+ " [-h] Print help\n"
+ " [-q] Quiet mode (reports when fail)\n"
+ " [filename] output netCDF file name\n";
+ fprintf(stderr, help, argv0);
+}
+
+int main(int argc, char** argv)
+{
+ extern int optind;
+ char *filename="testfile.nc";
+ char str_att[128], att_name[NC_MAX_NAME];
+ int i, rank, err, verbose=0, ncid, cmode, omode, ngatts;
+ short short_att[10], digit[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+ time_t ltime;
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+
+ /* get command-line arguments */
+ while ((i = getopt(argc, argv, "hq")) != EOF)
+ switch(i) {
+ case 'q': verbose = 0;
+ break;
+ case 'h':
+ default: if (rank==0) usage(argv[0]);
+ MPI_Finalize();
+ return 0;
+ }
+ argc -= optind;
+ argv += optind;
+ if (argc == 1) filename = argv[0]; /* optional argument */
+
+ /* create a new file for writing ----------------------------------------*/
+ cmode = NC_CLOBBER;
+ err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, MPI_INFO_NULL, &ncid);
+ ERR
+
+ /* add a global attribute named "history": a time stamp at rank 0 */
+ ltime = time(NULL); /* get the current calendar time */
+ asctime_r(localtime(<ime), str_att);
+
+ /* make sure the time string are consistent among all processes */
+ MPI_Bcast(str_att, strlen(str_att), MPI_CHAR, 0, MPI_COMM_WORLD);
+
+ err = ncmpi_put_att_text(ncid, NC_GLOBAL, "history", strlen(str_att),
+ &str_att[0]);
+ ERR
+ if (rank == 0 && verbose)
+ printf("writing global attribute \"history\" of text %s\n",
+ str_att);
+
+ /* add another global attribute named "digits": an array of short type */
+ err = ncmpi_put_att_short(ncid, NC_GLOBAL, "digits", NC_SHORT, 10,
+ &digit[0]);
+ ERR
+ if (rank == 0 && verbose)
+ printf("writing global attribute \"digits\" of 10 short integers\n");
+
+ /* close file */
+ err = ncmpi_close(ncid);
+ ERR
+
+ /* open the newly created file for read only -----------------------------*/
+ omode = NC_NOWRITE;
+ err = ncmpi_open(MPI_COMM_WORLD, filename, omode, MPI_INFO_NULL, &ncid);
+ ERR
+
+ /* find the number of global attributes */
+ err = ncmpi_inq_natts(ncid, &ngatts);
+ ERR
+
+ err = 0;
+ if (ngatts != 2) {
+ printf("Error: expected number of global attributes is 2, but got %d\n",
+ ngatts);
+ err = -1;
+ }
+ MPI_Allreduce(MPI_IN_PLACE, &err, 1, MPI_INT, MPI_MIN, MPI_COMM_WORLD);
+ if (err < 0) goto fn_exit;
+
+ /* find the name of first global attribute */
+ err = ncmpi_inq_attname(ncid, NC_GLOBAL, 0, att_name);
+ ERR
+
+ err = 0;
+ if (strncmp(att_name, "history", strlen("history"))) {
+ printf("Error: expected attribute name \"history\", but got %s\n",
+ att_name);
+ err = -1;
+ }
+ MPI_Allreduce(MPI_IN_PLACE, &err, 1, MPI_INT, MPI_MIN, MPI_COMM_WORLD);
+ if (err < 0) goto fn_exit;
+
+ /* read attribute value */
+ err = ncmpi_get_att_text(ncid, NC_GLOBAL, att_name, &str_att[0]);
+ ERR
+
+ /* find the name of second global attribute */
+ err = ncmpi_inq_attname(ncid, NC_GLOBAL, 1, att_name);
+ ERR
+
+ err = 0;
+ if (strncmp(att_name, "digits", strlen("digits"))) {
+ printf("Error: expected attribute name \"digits\", but got %s\n",
+ att_name);
+ err = -1;
+ }
+ MPI_Allreduce(MPI_IN_PLACE, &err, 1, MPI_INT, MPI_MIN, MPI_COMM_WORLD);
+ if (err < 0) goto fn_exit;
+
+ /* read attribute value */
+ err = ncmpi_get_att_short(ncid, NC_GLOBAL, att_name, &short_att[0]);
+ ERR
+
+ /* close file */
+ err = ncmpi_close(ncid);
+ ERR
+
+ /* check if there is any PnetCDF internal malloc residue */
+ MPI_Offset malloc_size, sum_size;
+ err = ncmpi_inq_malloc_size(&malloc_size);
+ if (err == NC_NOERR) {
+ MPI_Reduce(&malloc_size, &sum_size, 1, MPI_OFFSET, MPI_SUM, 0, MPI_COMM_WORLD);
+ if (rank == 0 && sum_size > 0)
+ printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n",
+ sum_size);
+ }
+
+fn_exit:
+ MPI_Finalize();
+ return 0;
+}
+
diff --git a/examples/C/hints.c b/examples/C/hints.c
new file mode 100644
index 0000000..b6c1d29
--- /dev/null
+++ b/examples/C/hints.c
@@ -0,0 +1,196 @@
+/*********************************************************************
+ *
+ * Copyright (C) 2013, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ *
+ *********************************************************************/
+/* $Id: hints.c 1669 2014-05-24 18:28:16Z wkliao $ */
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * This example sets two PnetCDF hints:
+ * nc_header_align_size and nc_var_align_size
+ * and prints the hint values as well as the header size, header extent, and
+ * two variables' starting file offsets.
+ *
+ * The compile and run commands are given below.
+ *
+ * % mpicc -O2 -o hints hints.c -lpnetcdf
+ *
+ * % mpiexec -l -n 4 ./hints /pvfs2/wkliao/testfile.nc
+ *
+ * nc_header_align_size set to = 1024
+ * nc_var_align_size set to = 512
+ * nc_header_read_chunk_size set to = 256
+ * header size = 252
+ * header extent = 1024
+ * var_zy start file offset = 1024
+ * var_yx start file offset = 3072
+ *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h> /* strcpy() */
+#include <unistd.h> /* getopt() */
+#include <assert.h>
+#include <mpi.h>
+#include <pnetcdf.h>
+
+#define NZ 5
+#define NY 5
+#define NX 5
+
+#define ERR {if(err!=NC_NOERR)printf("Error at line=%d: %s\n", __LINE__, ncmpi_strerror(err));}
+
+static void
+usage(char *argv0)
+{
+ char *help =
+ "Usage: %s [-h] | [-q] [file_name]\n"
+ " [-h] Print help\n"
+ " [-q] Quiet mode (reports when fail)\n"
+ " [filename] output netCDF file name\n";
+ fprintf(stderr, help, argv0);
+}
+
+static
+void print_hints(int ncid,
+ int varid0,
+ int varid1)
+{
+ char value[MPI_MAX_INFO_VAL];
+ int err, len, flag;
+ MPI_Offset header_size, header_extent, var_zy_start, var_yx_start;
+ MPI_Offset h_align=-1, v_align=-1, h_chunk=-1;
+ MPI_Info info_used;
+
+ err = ncmpi_inq_header_size (ncid, &header_size); ERR
+ err = ncmpi_inq_header_extent(ncid, &header_extent); ERR
+ err = ncmpi_inq_varoffset(ncid, varid0, &var_zy_start); ERR
+ err = ncmpi_inq_varoffset(ncid, varid1, &var_yx_start); ERR
+
+ err = ncmpi_inq_file_info(ncid, &info_used); ERR
+ MPI_Info_get_valuelen(info_used, "nc_header_align_size", &len, &flag);
+ if (flag) {
+ MPI_Info_get(info_used, "nc_header_align_size", len+1, value, &flag);
+ h_align = atoll(value);
+ }
+ MPI_Info_get_valuelen(info_used, "nc_var_align_size", &len, &flag);
+ if (flag) {
+ MPI_Info_get(info_used, "nc_var_align_size", len+1, value, &flag);
+ v_align = atoll(value);
+ }
+ MPI_Info_get_valuelen(info_used, "nc_header_read_chunk_size", &len, &flag);
+ if (flag) {
+ MPI_Info_get(info_used, "nc_header_read_chunk_size", len+1, value,&flag);
+ h_chunk = atoll(value);
+ }
+ MPI_Info_free(&info_used);
+
+ if (h_align == -1)
+ printf("nc_header_align_size is NOT set\n");
+ else
+ printf("nc_header_align_size set to = %lld\n", h_align);
+
+ if (v_align == -1)
+ printf("nc_var_align_size is NOT set\n");
+ else
+ printf("nc_var_align_size set to = %lld\n", v_align);
+ if (h_chunk == -1)
+ printf("nc_header_read_chunk_size is NOT set\n");
+ else
+ printf("nc_header_read_chunk_size set to = %lld\n", h_chunk);
+
+ printf("header size = %lld\n", header_size);
+ printf("header extent = %lld\n", header_extent);
+ printf("var_zy start file offset = %lld\n", var_zy_start);
+ printf("var_yx start file offset = %lld\n", var_yx_start);
+}
+
+int main(int argc, char** argv)
+{
+ extern int optind;
+ char *filename="testfile.nc";
+ int i, rank, nprocs, verbose=1, err;
+ int ncid, cmode, varid0, varid1, dimid[3], *buf_zy;
+ float *buf_yx;
+ MPI_Offset start[2], count[2];
+ MPI_Info info;
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+
+ /* get command-line arguments */
+ while ((i = getopt(argc, argv, "hq")) != EOF)
+ switch(i) {
+ case 'q': verbose = 0;
+ break;
+ case 'h':
+ default: if (rank==0) usage(argv[0]);
+ MPI_Finalize();
+ return 0;
+ }
+ argc -= optind;
+ argv += optind;
+ if (argc == 1) filename = argv[0]; /* optional argument */
+
+ MPI_Info_create(&info);
+ MPI_Info_set(info, "nc_header_align_size", "1024"); /* size in bytes */
+ MPI_Info_set(info, "nc_var_align_size", "512"); /* size in bytes */
+ MPI_Info_set(info, "nc_header_read_chunk_size", "256"); /* size in bytes */
+ /* note that set the above values to 1 to disable the alignment */
+
+ /* create a new file for writing ----------------------------------------*/
+ cmode = NC_CLOBBER | NC_64BIT_DATA;
+ err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, info, &ncid); ERR
+ MPI_Info_free(&info);
+
+ /* define 3 dimensions */
+ err = ncmpi_def_dim(ncid, "Z", NZ*nprocs, &dimid[0]); ERR
+ err = ncmpi_def_dim(ncid, "Y", NY*nprocs, &dimid[1]); ERR
+ err = ncmpi_def_dim(ncid, "X", NX*nprocs, &dimid[2]); ERR
+
+ /* define a variable of size (NZ * nprocs) * (NY * nprocs) */
+ err = ncmpi_def_var(ncid, "var_zy", NC_INT, 2, &dimid[0], &varid0); ERR
+ /* define a variable of size (NY * nprocs) * (NX * nprocs) */
+ err = ncmpi_def_var(ncid, "var_yx", NC_FLOAT, 2, &dimid[1], &varid1); ERR
+ err = ncmpi_enddef(ncid); ERR
+
+ /* var_zy is partitioned along Z dimension */
+ buf_zy = (int*) malloc(NZ * (NY * nprocs) * sizeof(int));
+ for (i=0; i<NZ*(NY*nprocs); i++) buf_zy[i] = i;
+
+ start[0] = NZ * rank; start[1] = 0;
+ count[0] = NZ; count[1] = NY * nprocs;
+ err = ncmpi_put_vara_int_all(ncid, varid0, start, count, buf_zy); ERR
+
+ /* var_yx is partitioned along X dimension */
+ buf_yx = (float*) malloc((NY * nprocs) * NX * sizeof(float));
+ for (i=0; i<(NY*nprocs)*NX; i++) buf_yx[i] = i;
+
+ start[0] = 0; start[1] = NX * rank;
+ count[0] = NY * nprocs; count[1] = NX;
+ err = ncmpi_put_vara_float_all(ncid, varid1, start, count, buf_yx); ERR
+
+ if (rank == 0 && verbose) print_hints(ncid, varid0, varid1);
+
+ err = ncmpi_close(ncid); ERR
+
+ free(buf_zy);
+ free(buf_yx);
+
+ /* check if there is any PnetCDF internal malloc residue */
+ MPI_Offset malloc_size, sum_size;
+ err = ncmpi_inq_malloc_size(&malloc_size);
+ if (err == NC_NOERR) {
+ MPI_Reduce(&malloc_size, &sum_size, 1, MPI_OFFSET, MPI_SUM, 0, MPI_COMM_WORLD);
+ if (rank == 0 && sum_size > 0)
+ printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n",
+ sum_size);
+ }
+
+ MPI_Finalize();
+ return 0;
+}
+
diff --git a/examples/C/i_varn_int64.c b/examples/C/i_varn_int64.c
new file mode 100644
index 0000000..1d7c1d8
--- /dev/null
+++ b/examples/C/i_varn_int64.c
@@ -0,0 +1,371 @@
+/*********************************************************************
+ *
+ * Copyright (C) 2014, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ *
+ *********************************************************************/
+/* $Id: i_varn_int64.c 2245 2015-12-20 18:39:52Z wkliao $ */
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * This example tests nonblocking varn APIs, including
+ * ncmpi_iput_varn_longlong(), ncmpi_iget_varn_longlong(), ncmpi_iput_varn(),
+ * and ncmpi_iget_varn().
+ * It first writes a sequence of requests with arbitrary array indices and
+ * lengths to four variables of type NC_INT64, and reads back.
+ *
+ * The compile and run commands are given below, together with an ncmpidump of
+ * the output file.
+ *
+ * % mpicc -O2 -o i_varn_int64 i_varn_int64.c -lpnetcdf
+ * % mpiexec -n 4 ./i_varn_int64 /pvfs2/wkliao/testfile.nc
+ * % ncmpidump /pvfs2/wkliao/testfile.nc
+ * netcdf testfile {
+ * // file format: CDF-5 (big variables)
+ * dimensions:
+ * Y = 4 ;
+ * X = 10 ;
+ * variables:
+ * int64 var0(Y, X) ;
+ * int64 var1(Y, X) ;
+ * int64 var2(Y, X) ;
+ * int64 var3(Y, X) ;
+ * data:
+ *
+ * var0 =
+ * 1, 1, 1, 3, 3, 0, 0, 2, 3, 3,
+ * 0, 2, 2, 2, 1, 3, 3, 2, 2, 2,
+ * 3, 3, 2, 1, 1, 1, 0, 0, 3, 3,
+ * 0, 0, 0, 2, 3, 3, 3, 1, 1, 1 ;
+ *
+ * var1 =
+ * 2, 2, 2, 0, 0, 1, 1, 3, 0, 0,
+ * 1, 3, 3, 3, 2, 0, 0, 3, 3, 3,
+ * 0, 0, 3, 2, 2, 2, 1, 1, 0, 0,
+ * 1, 1, 1, 3, 0, 0, 0, 2, 2, 2 ;
+ *
+ * var2 =
+ * 3, 3, 3, 1, 1, 2, 2, 0, 1, 1,
+ * 2, 0, 0, 0, 3, 1, 1, 0, 0, 0,
+ * 1, 1, 0, 3, 3, 3, 2, 2, 1, 1,
+ * 2, 2, 2, 0, 1, 1, 1, 3, 3, 3 ;
+ *
+ * var3 =
+ * 0, 0, 0, 2, 2, 3, 3, 1, 2, 2,
+ * 3, 1, 1, 1, 0, 2, 2, 1, 1, 1,
+ * 2, 2, 1, 0, 0, 0, 3, 3, 2, 2,
+ * 3, 3, 3, 1, 2, 2, 2, 0, 0, 0 ;
+ * }
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h> /* getopt() */
+#include <string.h> /* strcpy() */
+#include <mpi.h>
+#include <pnetcdf.h>
+
+#define NY 4
+#define NX 10
+#define NDIMS 2
+
+#define ERR \
+ if (err != NC_NOERR) { \
+ printf("Error at line=%d: %s\n", __LINE__, ncmpi_strerror(err)); \
+ }
+
+#define ERRS(n,a) { \
+ int _i; \
+ for (_i=0; _i<(n); _i++) { \
+ if ((a)[_i] != NC_NOERR) { \
+ printf("Error at line=%d: err[%d] %s\n", __LINE__, _i, \
+ ncmpi_strerror((a)[_i])); \
+ } \
+ } \
+}
+
+static MPI_Offset *** calloc_3D(size_t z, size_t y, size_t x)
+{
+ int _j, _k;
+ MPI_Offset ***buf = (MPI_Offset***) malloc(z * sizeof(MPI_Offset**));
+ MPI_Offset **bufy = (MPI_Offset**) malloc(z*y * sizeof(MPI_Offset*));
+ MPI_Offset *bufx = (MPI_Offset*) calloc(z*y*x, sizeof(MPI_Offset));
+ for (_k=0; _k<z; _k++, bufy+=y) {
+ buf[_k] = bufy;
+ for (_j=0; _j<y; _j++, bufx+=x)
+ buf[_k][_j] = bufx;
+ }
+ return buf;
+}
+
+static void free_3D(MPI_Offset ***buf)
+{
+ free(buf[0][0]);
+ free(buf[0]);
+ free(buf);
+}
+
+static void
+usage(char *argv0)
+{
+ char *help =
+ "Usage: %s [-h] | [-q] [file_name]\n"
+ " [-h] Print help\n"
+ " [-q] Quiet mode (reports when fail)\n"
+ " [filename] output netCDF file name\n";
+ fprintf(stderr, help, argv0);
+}
+
+static void check_contents(int ncid, int *varid)
+{
+ int i, j, err;
+ long long expected[4][NY*NX] = {{1, 1, 1, 3, 3, 0, 0, 2, 3, 3,
+ 0, 2, 2, 2, 1, 3, 3, 2, 2, 2,
+ 3, 3, 2, 1, 1, 1, 0, 0, 3, 3,
+ 0, 0, 0, 2, 3, 3, 3, 1, 1, 1},
+ {2, 2, 2, 0, 0, 1, 1, 3, 0, 0,
+ 1, 3, 3, 3, 2, 0, 0, 3, 3, 3,
+ 0, 0, 3, 2, 2, 2, 1, 1, 0, 0,
+ 1, 1, 1, 3, 0, 0, 0, 2, 2, 2},
+ {3, 3, 3, 1, 1, 2, 2, 0, 1, 1,
+ 2, 0, 0, 0, 3, 1, 1, 0, 0, 0,
+ 1, 1, 0, 3, 3, 3, 2, 2, 1, 1,
+ 2, 2, 2, 0, 1, 1, 1, 3, 3, 3},
+ {0, 0, 0, 2, 2, 3, 3, 1, 2, 2,
+ 3, 1, 1, 1, 0, 2, 2, 1, 1, 1,
+ 2, 2, 1, 0, 0, 0, 3, 3, 2, 2,
+ 3, 3, 3, 1, 2, 2, 2, 0, 0, 0}};
+
+ long long *r_buffer = (long long*) malloc(NY*NX * sizeof(long long));
+
+ for (i=0; i<4; i++) {
+ for (j=0; j<NY*NX; j++) r_buffer[j] = -1;
+ err = ncmpi_get_var_longlong_all(ncid, varid[i], r_buffer);
+ ERR
+
+ /* check if the contents of buf are expected */
+ for (j=0; j<NY*NX; j++)
+ if (r_buffer[j] != expected[i][j])
+ printf("Expected file contents [%d][%d]=%lld, but got %lld\n",
+ i,j,expected[i][j],r_buffer[j]);
+ }
+ free(r_buffer);
+}
+
+int main(int argc, char** argv)
+{
+ extern int optind;
+ char *filename="testfile.nc", exec[128];
+ int i, j, k, n, rank, nprocs, verbose=1, err;
+ int ncid, cmode, varid[4], dimid[2], nreqs, reqs[4], sts[4];
+ long long *buffer[4];
+ int num_segs[4], req_lens[4];
+ MPI_Offset ***starts, ***counts;
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+ strcpy(exec, argv[0]);
+
+ /* get command-line arguments */
+ while ((i = getopt(argc, argv, "hq")) != EOF)
+ switch(i) {
+ case 'q': verbose = 0;
+ break;
+ case 'h':
+ default: if (rank==0) usage(argv[0]);
+ MPI_Finalize();
+ return 0;
+ }
+ argc -= optind;
+ argv += optind;
+ if (argc == 1) filename = argv[0]; /* optional argument */
+
+ if (nprocs != 4 && rank == 0 && verbose)
+ printf("Warning: %s is intended to run on 4 processes\n",exec);
+
+ /* create a new file for writing ----------------------------------------*/
+ cmode = NC_CLOBBER | NC_64BIT_DATA;
+ err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, MPI_INFO_NULL, &ncid);
+ ERR
+
+ /* create a global array of size NY * NX */
+ err = ncmpi_def_dim(ncid, "Y", NY, &dimid[0]); ERR
+ err = ncmpi_def_dim(ncid, "X", NX, &dimid[1]); ERR
+ err = ncmpi_def_var(ncid, "var0", NC_INT64, NDIMS, dimid, &varid[0]); ERR
+ err = ncmpi_def_var(ncid, "var1", NC_INT64, NDIMS, dimid, &varid[1]); ERR
+ err = ncmpi_def_var(ncid, "var2", NC_INT64, NDIMS, dimid, &varid[2]); ERR
+ err = ncmpi_def_var(ncid, "var3", NC_INT64, NDIMS, dimid, &varid[3]); ERR
+ err = ncmpi_enddef(ncid); ERR
+
+ /* allocate space for starts and counts */
+ starts = calloc_3D(4, 6, NDIMS);
+ counts = calloc_3D(4, 6, NDIMS);
+
+ n = rank % 4;
+ num_segs[n] = 4; /* number of segments for this request */
+ starts[n][0][0]=0; starts[n][0][1]=5; counts[n][0][0]=1; counts[n][0][1]=2;
+ starts[n][1][0]=1; starts[n][1][1]=0; counts[n][1][0]=1; counts[n][1][1]=1;
+ starts[n][2][0]=2; starts[n][2][1]=6; counts[n][2][0]=1; counts[n][2][1]=2;
+ starts[n][3][0]=3; starts[n][3][1]=0; counts[n][3][0]=1; counts[n][3][1]=3;
+ /* starts[n][][] n_counts[n][][] indicate the following: ("-" means skip)
+ - - - - - X X - - -
+ X - - - - - - - - -
+ - - - - - - X X - -
+ X X X - - - - - - -
+ */
+ n = (rank+1) % 4;
+ num_segs[n] = 6; /* number of segments for this request */
+ starts[n][0][0]=0; starts[n][0][1]=3; counts[n][0][0]=1; counts[n][0][1]=2;
+ starts[n][1][0]=0; starts[n][1][1]=8; counts[n][1][0]=1; counts[n][1][1]=2;
+ starts[n][2][0]=1; starts[n][2][1]=5; counts[n][2][0]=1; counts[n][2][1]=2;
+ starts[n][3][0]=2; starts[n][3][1]=0; counts[n][3][0]=1; counts[n][3][1]=2;
+ starts[n][4][0]=2; starts[n][4][1]=8; counts[n][4][0]=1; counts[n][4][1]=2;
+ starts[n][5][0]=3; starts[n][5][1]=4; counts[n][5][0]=1; counts[n][5][1]=3;
+ /* starts[n][][] counts[n][][] indicate the following pattern.
+ - - - X X - - - X X
+ - - - - - X X - - -
+ X X - - - - - - X X
+ - - - - X X X - - -
+ */
+ n = (rank+2) % 4;
+ num_segs[n] = 5; /* number of segments for this request */
+ starts[n][0][0]=0; starts[n][0][1]=7; counts[n][0][0]=1; counts[n][0][1]=1;
+ starts[n][1][0]=1; starts[n][1][1]=1; counts[n][1][0]=1; counts[n][1][1]=3;
+ starts[n][2][0]=1; starts[n][2][1]=7; counts[n][2][0]=1; counts[n][2][1]=3;
+ starts[n][3][0]=2; starts[n][3][1]=2; counts[n][3][0]=1; counts[n][3][1]=1;
+ starts[n][4][0]=3; starts[n][4][1]=3; counts[n][4][0]=1; counts[n][4][1]=1;
+ /* starts[n][][] counts[n][][] indicate the following pattern.
+ - - - - - - - X - -
+ - X X X - - - X X X
+ - - X - - - - - - -
+ - - - X - - - - - -
+ */
+ n = (rank+3) % 4;
+ num_segs[n] = 4; /* number of segments for this request */
+ starts[n][0][0]=0; starts[n][0][1]=0; counts[n][0][0]=1; counts[n][0][1]=3;
+ starts[n][1][0]=1; starts[n][1][1]=4; counts[n][1][0]=1; counts[n][1][1]=1;
+ starts[n][2][0]=2; starts[n][2][1]=3; counts[n][2][0]=1; counts[n][2][1]=3;
+ starts[n][3][0]=3; starts[n][3][1]=7; counts[n][3][0]=1; counts[n][3][1]=3;
+ /*starts[n][][] counts[n][][] indicate the following pattern.
+ X X X - - - - - - -
+ - - - - X - - - - -
+ - - - X X X - - - -
+ - - - - - - - X X X
+ */
+
+ /* only rank 0, 1, 2, and 3 do I/O:
+ * each of ranks 0 to 3 write 4 nonblocking requests */
+ nreqs = 4;
+ if (rank >= 4) nreqs = 0;
+
+ /* calculate length of each varn request, number of segments in each
+ * varn request, and allocate write buffer */
+ for (i=0; i<nreqs; i++) {
+ req_lens[i] = 0; /* total length this request */
+ for (j=0; j<num_segs[i]; j++) {
+ MPI_Offset req_len=1;
+ for (k=0; k<NDIMS; k++)
+ req_len *= counts[i][j][k];
+ req_lens[i] += req_len;
+ }
+ if (verbose) printf("req_lens[%d]=%d\n",i,req_lens[i]);
+
+ /* allocate I/O buffer and initialize its contents */
+ buffer[i] = (long long*) malloc(req_lens[i] * sizeof(long long));
+ for (j=0; j<req_lens[i]; j++) buffer[i][j] = rank;
+ }
+
+ /* write using varn API */
+ for (i=0; i<nreqs; i++) {
+ err = ncmpi_iput_varn_longlong(ncid, varid[i], num_segs[i], starts[i],
+ counts[i], buffer[i], &reqs[i]);
+ ERR
+ }
+ err = ncmpi_wait_all(ncid, nreqs, reqs, sts);
+ ERRS(nreqs, sts)
+
+ /* check file contents */
+ if (nprocs >= 4) check_contents(ncid, varid);
+
+ /* read using get_varn API and check contents */
+ for (i=0; i<nreqs; i++) {
+ for (j=0; j<req_lens[i]; j++) buffer[i][j] = -1;
+ err = ncmpi_iget_varn_longlong(ncid, varid[i], num_segs[i], starts[i],
+ counts[i], buffer[i], &reqs[i]);
+ ERR
+ }
+ err = ncmpi_wait_all(ncid, nreqs, reqs, sts);
+ ERRS(nreqs, sts)
+
+ /* check buffer contents */
+ for (i=0; i<nreqs; i++) {
+ for (j=0; j<req_lens[i]; j++)
+ if (buffer[i][j] != rank)
+ printf("Expected read buf[%d][%d]=%d, but got %lld\n",
+ i,j,rank,buffer[i][j]);
+ }
+
+ for (i=0; i<nreqs; i++) free(buffer[i]);
+
+ /* test flexible put API, using a noncontiguous buftype */
+ for (i=0; i<nreqs; i++) {
+ MPI_Datatype buftype;
+ MPI_Type_vector(req_lens[i], 1, 2, MPI_LONG_LONG, &buftype);
+ MPI_Type_commit(&buftype);
+ buffer[i] = (long long*) malloc(req_lens[i] * 2 * sizeof(long long));
+ for (j=0; j<req_lens[i]*2; j++) buffer[i][j] = rank;
+
+ err = ncmpi_iput_varn(ncid, varid[i], num_segs[i], starts[i],
+ counts[i], buffer[i], 1, buftype, &reqs[i]);
+ ERR
+ MPI_Type_free(&buftype);
+ }
+ err = ncmpi_wait_all(ncid, nreqs, reqs, sts);
+ ERRS(nreqs, sts)
+
+ /* check file contents */
+ if (nprocs >= 4) check_contents(ncid, varid);
+
+ /* test flexible get API, using a noncontiguous buftype */
+ for (i=0; i<nreqs; i++) {
+ MPI_Datatype buftype;
+ MPI_Type_vector(req_lens[i], 1, 2, MPI_LONG_LONG, &buftype);
+ MPI_Type_commit(&buftype);
+ for (j=0; j<req_lens[i]*2; j++) buffer[i][j] = -1;
+ err = ncmpi_iget_varn(ncid, varid[i], num_segs[i], starts[i],
+ counts[i], buffer[i], 1, buftype, &reqs[i]);
+ ERR
+ MPI_Type_free(&buftype);
+ }
+ err = ncmpi_wait_all(ncid, nreqs, reqs, sts);
+ ERRS(nreqs, sts)
+
+ /* check buffer contents */
+ for (i=0; i<nreqs; i++) {
+ for (j=0; j<req_lens[i]; j++)
+ if (buffer[i][j*2] != rank)
+ printf("Expected read buf[%d][%d]=%d, but got %lld\n",
+ i,j*2,rank,buffer[i][j*2]);
+ }
+
+ err = ncmpi_close(ncid);
+ ERR
+
+ for (i=0; i<nreqs; i++) free(buffer[i]);
+ free_3D(starts);
+ free_3D(counts);
+
+ /* check if there is any PnetCDF internal malloc residue */
+ MPI_Offset malloc_size, sum_size;
+ err = ncmpi_inq_malloc_size(&malloc_size);
+ if (err == NC_NOERR) {
+ MPI_Reduce(&malloc_size, &sum_size, 1, MPI_OFFSET, MPI_SUM, 0, MPI_COMM_WORLD);
+ if (rank == 0 && sum_size > 0)
+ printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n",
+ sum_size);
+ }
+
+ MPI_Finalize();
+ return 0;
+}
+
diff --git a/examples/C/mput.c b/examples/C/mput.c
new file mode 100644
index 0000000..fe0ad16
--- /dev/null
+++ b/examples/C/mput.c
@@ -0,0 +1,232 @@
+/*********************************************************************
+ *
+ * Copyright (C) 2013, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ *
+ *********************************************************************/
+/* $Id: mput.c 1669 2014-05-24 18:28:16Z wkliao $ */
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * This example shows how to use a single call of ncmpi_mput_vara_all() to
+ * write a sequence of requests with arbitrary array indices and lengths.
+ * Using ncmpi_mput_vara_all() can achieve the same effect of HDF5 writing
+ * a sequence of selected file locations through the following 2 APIs.
+ *
+ * H5Sselect_elements(fid, H5S_SELECT_SET, NUMP, (const hssize_t **)coord);
+ * H5Dwrite(dataset, H5T_NATIVE_INT, mid, fid, H5P_DEFAULT, val);
+ *
+ * Note that in ncmpi_mput_vara_all(), users can write more than one element
+ * starting at each selected location.
+ *
+ * The compile and run commands are given below, together with an ncmpidump of
+ * the output file.
+ *
+ * % mpicc -O2 -o mput mput.c -lpnetcdf
+ * % mpiexec -l -n 4 ./mput /pvfs2/wkliao/testfile.nc
+ * % ncmpidump /pvfs2/wkliao/testfile.nc
+ * netcdf testfile {
+ * // file format: CDF-5 (big variables)
+ * dimensions:
+ * Y = 4 ;
+ * X = 10 ;
+ * variables:
+ * int var(Y, X) ;
+ * data:
+ *
+ * var =
+ * 3, 3, 3, 1, 1, 0, 0, 2, 1, 1,
+ * 0, 2, 2, 2, 3, 1, 1, 2, 2, 2,
+ * 1, 1, 2, 3, 3, 3, 0, 0, 1, 1,
+ * 0, 0, 0, 2, 1, 1, 1, 3, 3, 3 ;
+ * }
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h> /* strcpy() */
+#include <unistd.h> /* getopt() */
+#include <assert.h>
+#include <mpi.h>
+#include <pnetcdf.h>
+
+#define NY 4
+#define NX 10
+#define NDIMS 2
+
+
+#define ERR {if(err!=NC_NOERR)printf("Error at line=%d: %s\n", __LINE__, ncmpi_strerror(err));}
+
+static void
+usage(char *argv0)
+{
+ char *help =
+ "Usage: %s [-h] | [-q] [file_name]\n"
+ " [-h] Print help\n"
+ " [-q] Quiet mode (reports when fail)\n"
+ " [filename] output netCDF file name\n";
+ fprintf(stderr, help, argv0);
+}
+
+int main(int argc, char** argv)
+{
+ extern int optind;
+ char *filename="testfile.nc";
+ int i, rank, nprocs, verbose=1, err;
+ int ncid, cmode, varid, dimid[2], num_reqs, *buffer, **bufs, *nvarids;
+ MPI_Offset w_len, **starts, **counts, *bufcounts;
+ MPI_Datatype *datatypes;
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+
+ /* get command-line arguments */
+ while ((i = getopt(argc, argv, "hq")) != EOF)
+ switch(i) {
+ case 'q': verbose = 0;
+ break;
+ case 'h':
+ default: if (rank==0) usage(argv[0]);
+ MPI_Finalize();
+ return 0;
+ }
+ argc -= optind;
+ argv += optind;
+ if (argc == 1) filename = argv[0]; /* optional argument */
+
+ if (nprocs != 4 && rank == 0 && verbose)
+ printf("Warning: this program is intended to run on 4 processes\n");
+
+ /* create a new file for writing ----------------------------------------*/
+ cmode = NC_CLOBBER | NC_64BIT_DATA;
+ err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, MPI_INFO_NULL, &ncid);
+ ERR
+
+ /* create a global array of size NY * NX */
+ err = ncmpi_def_dim(ncid, "Y", NY, &dimid[0]);
+ ERR
+ err = ncmpi_def_dim(ncid, "X", NX, &dimid[1]);
+ ERR
+ err = ncmpi_def_var(ncid, "var", NC_INT, NDIMS, dimid, &varid);
+ ERR
+ err = ncmpi_enddef(ncid);
+ ERR
+
+ /* pick arbitrary numbers of requests for 4 processes */
+ num_reqs = 0;
+ if (rank == 0) num_reqs = 4;
+ else if (rank == 1) num_reqs = 6;
+ else if (rank == 2) num_reqs = 5;
+ else if (rank == 3) num_reqs = 4;
+
+ starts = (MPI_Offset**) malloc(num_reqs * sizeof(MPI_Offset*));
+ counts = (MPI_Offset**) malloc(num_reqs * sizeof(MPI_Offset*));
+ starts[0] = (MPI_Offset*) calloc(num_reqs * NDIMS, sizeof(MPI_Offset));
+ counts[0] = (MPI_Offset*) calloc(num_reqs * NDIMS, sizeof(MPI_Offset));
+ for (i=1; i<num_reqs; i++) {
+ starts[i] = starts[i-1] + NDIMS;
+ counts[i] = counts[i-1] + NDIMS;
+ }
+
+ /* assign arbitrary starts and counts */
+ const int y=0, x=1;
+ if (rank == 0) {
+ starts[0][y] = 0; starts[0][x] = 5; counts[0][y] = 1; counts[0][x] = 2;
+ starts[1][y] = 1; starts[1][x] = 0; counts[1][y] = 1; counts[1][x] = 1;
+ starts[2][y] = 2; starts[2][x] = 6; counts[2][y] = 1; counts[2][x] = 2;
+ starts[3][y] = 3; starts[3][x] = 0; counts[3][y] = 1; counts[3][x] = 3;
+ /* rank 0 is writing the followings: ("-" means skip)
+ - - - - - 0 0 - - -
+ 0 - - - - - - - - -
+ - - - - - - 0 0 - -
+ 0 0 0 - - - - - - -
+ */
+ } else if (rank ==1) {
+ starts[0][y] = 0; starts[0][x] = 3; counts[0][y] = 1; counts[0][x] = 2;
+ starts[1][y] = 0; starts[1][x] = 8; counts[1][y] = 1; counts[1][x] = 2;
+ starts[2][y] = 1; starts[2][x] = 5; counts[2][y] = 1; counts[2][x] = 2;
+ starts[3][y] = 2; starts[3][x] = 0; counts[3][y] = 1; counts[3][x] = 2;
+ starts[4][y] = 2; starts[4][x] = 8; counts[4][y] = 1; counts[4][x] = 2;
+ starts[5][y] = 3; starts[5][x] = 4; counts[5][y] = 1; counts[5][x] = 3;
+ /* rank 1 is writing the followings: ("-" means skip)
+ - - - 1 1 - - - 1 1
+ - - - - - 1 1 - - -
+ 1 1 - - - - - - 1 1
+ - - - - 1 1 1 - - -
+ */
+ } else if (rank ==2) {
+ starts[0][y] = 0; starts[0][x] = 7; counts[0][y] = 1; counts[0][x] = 1;
+ starts[1][y] = 1; starts[1][x] = 1; counts[1][y] = 1; counts[1][x] = 3;
+ starts[2][y] = 1; starts[2][x] = 7; counts[2][y] = 1; counts[2][x] = 3;
+ starts[3][y] = 2; starts[3][x] = 2; counts[3][y] = 1; counts[3][x] = 1;
+ starts[4][y] = 3; starts[4][x] = 3; counts[4][y] = 1; counts[4][x] = 1;
+ /* rank 2 is writing the followings: ("-" means skip)
+ - - - - - - - 2 - -
+ - 2 2 2 - - - 2 2 2
+ - - 2 - - - - - - -
+ - - - 2 - - - - - -
+ */
+ } else if (rank ==3) {
+ starts[0][y] = 0; starts[0][x] = 0; counts[0][y] = 1; counts[0][x] = 3;
+ starts[1][y] = 1; starts[1][x] = 4; counts[1][y] = 1; counts[1][x] = 1;
+ starts[2][y] = 2; starts[2][x] = 3; counts[2][y] = 1; counts[2][x] = 3;
+ starts[3][y] = 3; starts[3][x] = 7; counts[3][y] = 1; counts[3][x] = 3;
+ /* rank 3 is writing the followings: ("-" means skip)
+ 3 3 3 - - - - - - -
+ - - - - 3 - - - - -
+ - - - 3 3 3 - - - -
+ - - - - - - - 3 3 3
+ */
+ }
+
+ nvarids = (int*) malloc(num_reqs * sizeof(int));
+ bufcounts = (MPI_Offset*) malloc(num_reqs * sizeof(MPI_Offset));
+ datatypes = (MPI_Datatype*) malloc(num_reqs * sizeof(MPI_Datatype));
+ w_len = 0;
+ for (i=0; i<num_reqs; i++) {
+ nvarids[i] = varid;
+ bufcounts[i] = counts[i][x];
+ datatypes[i] = MPI_INT;
+ w_len += bufcounts[i];
+ }
+
+ /* allocate I/O buffer and initialize its contents */
+ buffer = (int*) malloc(w_len * sizeof(int));
+ for (i=0; i<w_len; i++) buffer[i] = rank;
+
+ /* set the buffer pointers to different offsets to the I/O buffer */
+ bufs = (int**) malloc(num_reqs * sizeof(int*));
+ bufs[0] = buffer;
+ for (i=1; i<num_reqs; i++) bufs[i] = bufs[i-1] + bufcounts[i-1];
+
+ err = ncmpi_mput_vara_all(ncid, num_reqs, nvarids, starts, counts,
+ (void**)bufs, bufcounts, datatypes);
+ ERR
+
+ err = ncmpi_close(ncid);
+ ERR
+
+ free(buffer);
+ free(bufs);
+ free(nvarids);
+ free(bufcounts);
+ free(datatypes);
+ free(starts[0]);
+ free(counts[0]);
+ free(starts);
+ free(counts);
+
+ /* check if there is any PnetCDF internal malloc residue */
+ MPI_Offset malloc_size, sum_size;
+ err = ncmpi_inq_malloc_size(&malloc_size);
+ if (err == NC_NOERR) {
+ MPI_Reduce(&malloc_size, &sum_size, 1, MPI_OFFSET, MPI_SUM, 0, MPI_COMM_WORLD);
+ if (rank == 0 && sum_size > 0)
+ printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n",
+ sum_size);
+ }
+
+ MPI_Finalize();
+ return 0;
+}
+
diff --git a/examples/C/nonblocking_write.c b/examples/C/nonblocking_write.c
new file mode 100644
index 0000000..cf7bda2
--- /dev/null
+++ b/examples/C/nonblocking_write.c
@@ -0,0 +1,276 @@
+/*********************************************************************
+ *
+ * Copyright (C) 2012, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ *
+ *********************************************************************/
+/* $Id: nonblocking_write.c 2245 2015-12-20 18:39:52Z wkliao $ */
+
+/* wkliao:
+ * This example is similar to collective_write.c but using nonblocking APIs.
+ * It creates a netcdf file in CD-5 format and writes a number of
+ * 3D integer non-record variables. The measured write bandwidth is reported
+ * at the end. Usage: (for example)
+ * To compile:
+ * mpicc -O2 nonblocking_write.c -o nonblocking_write -lpnetcdf
+ * To run:
+ * mpiexec -n num_processes ./nonblocking_write [filename] [len]
+ * where len decides the size of each local array, which is len x len x len.
+ * So, each non-record variable is of size len*len*len * nprocs * sizeof(int)
+ * All variables are partitioned among all processes in a 3D
+ * block-block-block fashion. Below is an example standard output from
+ * command:
+ * mpiexec -n 32 ./nonblocking_write /pvfs2/wkliao/testfile.nc 100
+ *
+ * MPI hint: cb_nodes = 2
+ * MPI hint: cb_buffer_size = 16777216
+ * MPI hint: striping_factor = 32
+ * MPI hint: striping_unit = 1048576
+ * Local array size 100 x 100 x 100 integers, size = 3.81 MB
+ * Global array size 400 x 400 x 200 integers, write size = 0.30 GB
+ * procs Global array size exec(sec) write(MB/s)
+ * ------- ------------------ --------- -----------
+ * 32 400 x 400 x 200 6.67 45.72
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h> /* strcpy() */
+#include <unistd.h> /* getopt() */
+#include <mpi.h>
+#include <pnetcdf.h>
+
+#define NDIMS 3
+#define NUM_VARS 10
+
+#define HANDLE_ERROR { \
+ if (err != NC_NOERR) \
+ printf("Error at line %d (%s)\n", __LINE__, \
+ ncmpi_strerror(err)); \
+}
+
+static void
+usage(char *argv0)
+{
+ char *help =
+ "Usage: %s [-h] | [-q] [file_name] [len]\n"
+ " [-h] Print help\n"
+ " [-q] Quiet mode (reports when fail)\n"
+ " [filename] output netCDF file name\n"
+ " [len] size of each dimension of the local array\n";
+ fprintf(stderr, help, argv0);
+}
+
+/*----< print_info() >------------------------------------------------------*/
+static
+void print_info(MPI_Info *info_used)
+{
+ int flag;
+ char info_cb_nodes[64], info_cb_buffer_size[64];
+ char info_striping_factor[64], info_striping_unit[64];
+
+ strcpy(info_cb_nodes, "undefined");
+ strcpy(info_cb_buffer_size, "undefined");
+ strcpy(info_striping_factor, "undefined");
+ strcpy(info_striping_unit, "undefined");
+
+ MPI_Info_get(*info_used, "cb_nodes", 64, info_cb_nodes, &flag);
+ MPI_Info_get(*info_used, "cb_buffer_size", 64, info_cb_buffer_size, &flag);
+ MPI_Info_get(*info_used, "striping_factor", 64, info_striping_factor, &flag);
+ MPI_Info_get(*info_used, "striping_unit", 64, info_striping_unit, &flag);
+
+ printf("MPI hint: cb_nodes = %s\n", info_cb_nodes);
+ printf("MPI hint: cb_buffer_size = %s\n", info_cb_buffer_size);
+ printf("MPI hint: striping_factor = %s\n", info_striping_factor);
+ printf("MPI hint: striping_unit = %s\n", info_striping_unit);
+}
+
+/*----< main() >------------------------------------------------------------*/
+int main(int argc, char **argv)
+{
+ extern int optind;
+ int i, j, verbose=1, err;
+ int nprocs, len, *buf[NUM_VARS], bufsize, rank;
+ int gsizes[NDIMS], psizes[NDIMS];
+ double write_timing, max_write_timing, write_bw;
+ char *filename="testfile.nc", str[512];
+ int ncid, dimids[NDIMS], varids[NUM_VARS], req[NUM_VARS], st[NUM_VARS];
+ MPI_Offset starts[NDIMS], counts[NDIMS], write_size, sum_write_size;
+ MPI_Offset bbufsize;
+ MPI_Info info_used;
+
+ MPI_Init(&argc,&argv);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+
+ /* get command-line arguments */
+ while ((i = getopt(argc, argv, "hq")) != EOF)
+ switch(i) {
+ case 'q': verbose = 0;
+ break;
+ case 'h':
+ default: if (rank==0) usage(argv[0]);
+ MPI_Finalize();
+ return 0;
+ }
+ argc -= optind;
+ argv += optind;
+ if (argc >= 1) filename = argv[0]; /* optional argument */
+ len = 10;
+ if (argc >= 2) len = atoi(argv[1]); /* optional argument */
+
+ for (i=0; i<NDIMS; i++) psizes[i] = 0;
+
+ MPI_Dims_create(nprocs, NDIMS, psizes);
+ starts[0] = rank % psizes[0];
+ starts[1] = (rank / psizes[1]) % psizes[1];
+ starts[2] = (rank / (psizes[0] * psizes[1])) % psizes[2];
+
+ bufsize = 1;
+ for (i=0; i<NDIMS; i++) {
+ gsizes[i] = len * psizes[i];
+ starts[i] *= len;
+ counts[i] = len;
+ bufsize *= len;
+ }
+
+ /* allocate buffer and initialize with random numbers */
+ srand(rank);
+ for (i=0; i<NUM_VARS; i++) {
+ buf[i] = (int *) malloc(bufsize * sizeof(int));
+ for (j=0; j<bufsize; j++) buf[i][j] = rand();
+ }
+
+ MPI_Barrier(MPI_COMM_WORLD);
+ write_timing = MPI_Wtime();
+
+ /* create the file */
+ err = ncmpi_create(MPI_COMM_WORLD, filename, NC_CLOBBER|NC_64BIT_DATA,
+ MPI_INFO_NULL, &ncid);
+ if (err != NC_NOERR) {
+ printf("Error: ncmpi_create() file %s (%s)\n",filename,ncmpi_strerror(err));
+ MPI_Abort(MPI_COMM_WORLD, -1);
+ exit(1);
+ }
+
+ /* define dimensions */
+ for (i=0; i<NDIMS; i++) {
+ sprintf(str, "%c", 'x'+i);
+ err = ncmpi_def_dim(ncid, str, gsizes[i], &dimids[i]);
+ HANDLE_ERROR
+ }
+
+ /* define variables */
+ for (i=0; i<NUM_VARS; i++) {
+ sprintf(str, "var%d", i);
+ err = ncmpi_def_var(ncid, str, NC_INT, NDIMS, dimids, &varids[i]);
+ HANDLE_ERROR
+ }
+
+ /* exit the define mode */
+ err = ncmpi_enddef(ncid);
+ HANDLE_ERROR
+
+ /* get all the hints used */
+ err = ncmpi_inq_file_info(ncid, &info_used);
+ HANDLE_ERROR
+
+ /* write one variable at a time using iput */
+ for (i=0; i<NUM_VARS; i++) {
+ err = ncmpi_iput_vara_int(ncid, varids[i], starts, counts, buf[i], &req[i]);
+ HANDLE_ERROR
+ }
+
+ /* wait for the nonblocking I/O to complete */
+ err = ncmpi_wait_all(ncid, NUM_VARS, req, st);
+ HANDLE_ERROR
+ for (i=0; i<NUM_VARS; i++) {
+ if (st[i] != NC_NOERR)
+ printf("Error: nonblocking write fails on request %d (%s)\n",
+ i, ncmpi_strerror(st[i]));
+ }
+
+ /* write one variable at a time using bput */
+
+ /* bbufsize must be max of data type converted before and after */
+ bbufsize = bufsize * NUM_VARS * sizeof(int);
+ err = ncmpi_buffer_attach(ncid, bbufsize);
+ HANDLE_ERROR
+
+ for (i=0; i<NUM_VARS; i++) {
+ err = ncmpi_bput_vara_int(ncid, varids[i], starts, counts, buf[i], &req[i]);
+ HANDLE_ERROR
+ /* can safely change contents or free up the buf[i] here */
+ }
+
+ /* wait for the nonblocking I/O to complete */
+ err = ncmpi_wait_all(ncid, NUM_VARS, req, st);
+ HANDLE_ERROR
+ for (i=0; i<NUM_VARS; i++) {
+ if (st[i] != NC_NOERR)
+ printf("Error: nonblocking write fails on request %d (%s)\n",
+ i, ncmpi_strerror(st[i]));
+ }
+
+ /* detach the temporary buffer */
+ err = ncmpi_buffer_detach(ncid);
+ HANDLE_ERROR
+
+ MPI_Offset put_size;
+ ncmpi_inq_put_size(ncid, &put_size);
+#ifdef MPI_OFFSET
+ MPI_Allreduce(MPI_IN_PLACE, &put_size, 1, MPI_OFFSET, MPI_SUM, MPI_COMM_WORLD);
+#else
+ MPI_Allreduce(MPI_IN_PLACE, &put_size, 1, MPI_LONG_LONG, MPI_SUM, MPI_COMM_WORLD);
+#endif
+
+ /* close the file */
+ err = ncmpi_close(ncid);
+ HANDLE_ERROR
+
+ write_timing = MPI_Wtime() - write_timing;
+
+ write_size = bufsize * NUM_VARS * sizeof(int);
+ for (i=0; i<NUM_VARS; i++) free(buf[i]);
+
+#ifdef MPI_OFFSET
+ MPI_Reduce(&write_size, &sum_write_size, 1, MPI_OFFSET, MPI_SUM, 0, MPI_COMM_WORLD);
+#else
+ MPI_Reduce(&write_size, &sum_write_size, 1, MPI_LONG_LONG, MPI_SUM, 0, MPI_COMM_WORLD);
+#endif
+ MPI_Reduce(&write_timing, &max_write_timing, 1, MPI_DOUBLE, MPI_MAX, 0, MPI_COMM_WORLD);
+
+ if (rank == 0 && verbose) {
+ printf("\n");
+ printf("Total amount writes to variables only (exclude header) = %lld bytes\n", sum_write_size);
+ printf("Total amount writes reported by pnetcdf (include header) = %lld bytes\n", put_size);
+ printf("\n");
+ float subarray_size = (float)bufsize*sizeof(int)/1048576.0;
+ print_info(&info_used);
+ printf("Local array size %d x %d x %d integers, size = %.2f MB\n",len,len,len,subarray_size);
+ sum_write_size /= 1048576.0;
+ printf("Global array size %d x %d x %d integers, write size = %.2f GB\n",
+ gsizes[0], gsizes[1], gsizes[2], sum_write_size/1024.0);
+
+ write_bw = sum_write_size/max_write_timing;
+ printf(" procs Global array size exec(sec) write(MB/s)\n");
+ printf("------- ------------------ --------- -----------\n");
+ printf(" %4d %4d x %4d x %4d %8.2f %10.2f\n", nprocs,
+ gsizes[0], gsizes[1], gsizes[2], max_write_timing, write_bw);
+ }
+ MPI_Info_free(&info_used);
+
+ /* check if there is any PnetCDF internal malloc residue */
+ MPI_Offset malloc_size, sum_size;
+ err = ncmpi_inq_malloc_size(&malloc_size);
+ if (err == NC_NOERR) {
+ MPI_Reduce(&malloc_size, &sum_size, 1, MPI_OFFSET, MPI_SUM, 0, MPI_COMM_WORLD);
+ if (rank == 0 && sum_size > 0)
+ printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n",
+ sum_size);
+ }
+
+ MPI_Finalize();
+ return 0;
+}
+
diff --git a/examples/C/nonblocking_write_in_def.c b/examples/C/nonblocking_write_in_def.c
new file mode 100644
index 0000000..6c66101
--- /dev/null
+++ b/examples/C/nonblocking_write_in_def.c
@@ -0,0 +1,268 @@
+/*********************************************************************
+ *
+ * Copyright (C) 2015, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ *
+ *********************************************************************/
+/* $Id$ */
+
+/* This example is the same as nonblocking_write.c expect all nonblocking
+ * write requests (calls to iput and bput) are posted in define mode.
+ * It creates a netcdf file in CD-5 format and writes a number of
+ * 3D integer non-record variables. The measured write bandwidth is reported
+ * at the end. Usage: (for example)
+ * To compile:
+ * mpicc -O2 nonblocking_write_in_def.c -o nonblocking_write_in_def -lpnetcdf
+ * To run:
+ * mpiexec -n num_processes ./nonblocking_write_in_def [filename] [len]
+ * where len decides the size of each local array, which is len x len x len.
+ * So, each non-record variable is of size len*len*len * nprocs * sizeof(int)
+ * All variables are partitioned among all processes in a 3D
+ * block-block-block fashion. Below is an example standard output from
+ * command:
+ * mpiexec -n 32 ./nonblocking_write_in_def /pvfs2/wkliao/testfile.nc 100
+ *
+ * MPI hint: cb_nodes = 2
+ * MPI hint: cb_buffer_size = 16777216
+ * MPI hint: striping_factor = 32
+ * MPI hint: striping_unit = 1048576
+ * Local array size 100 x 100 x 100 integers, size = 3.81 MB
+ * Global array size 400 x 400 x 200 integers, write size = 0.30 GB
+ * procs Global array size exec(sec) write(MB/s)
+ * ------- ------------------ --------- -----------
+ * 32 400 x 400 x 200 6.67 45.72
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h> /* strcpy() */
+#include <unistd.h> /* getopt() */
+#include <mpi.h>
+#include <pnetcdf.h>
+
+#define NDIMS 3
+#define NUM_VARS 10
+
+#define HANDLE_ERROR { \
+ if (err != NC_NOERR) \
+ printf("Error at line %d (%s)\n", __LINE__, \
+ ncmpi_strerror(err)); \
+}
+
+static void
+usage(char *argv0)
+{
+ char *help =
+ "Usage: %s [-h] | [-q] [file_name] [len]\n"
+ " [-h] Print help\n"
+ " [-q] Quiet mode (reports when fail)\n"
+ " [filename] output netCDF file name\n"
+ " [len] size of each dimension of the local array\n";
+ fprintf(stderr, help, argv0);
+}
+
+/*----< print_info() >------------------------------------------------------*/
+static
+void print_info(MPI_Info *info_used)
+{
+ int flag;
+ char info_cb_nodes[64], info_cb_buffer_size[64];
+ char info_striping_factor[64], info_striping_unit[64];
+
+ strcpy(info_cb_nodes, "undefined");
+ strcpy(info_cb_buffer_size, "undefined");
+ strcpy(info_striping_factor, "undefined");
+ strcpy(info_striping_unit, "undefined");
+
+ MPI_Info_get(*info_used, "cb_nodes", 64, info_cb_nodes, &flag);
+ MPI_Info_get(*info_used, "cb_buffer_size", 64, info_cb_buffer_size, &flag);
+ MPI_Info_get(*info_used, "striping_factor", 64, info_striping_factor, &flag);
+ MPI_Info_get(*info_used, "striping_unit", 64, info_striping_unit, &flag);
+
+ printf("MPI hint: cb_nodes = %s\n", info_cb_nodes);
+ printf("MPI hint: cb_buffer_size = %s\n", info_cb_buffer_size);
+ printf("MPI hint: striping_factor = %s\n", info_striping_factor);
+ printf("MPI hint: striping_unit = %s\n", info_striping_unit);
+}
+
+/*----< main() >------------------------------------------------------------*/
+int main(int argc, char **argv)
+{
+ extern int optind;
+ int i, j, verbose=1, err;
+ int nprocs, len, *buf[NUM_VARS], bufsize, rank;
+ int gsizes[NDIMS], psizes[NDIMS];
+ double write_timing, max_write_timing, write_bw;
+ char *filename="testfile.nc", str[512];
+ int ncid, dimids[NDIMS], varids[NUM_VARS];
+ MPI_Offset start[NDIMS], count[NDIMS], write_size, sum_write_size;
+ MPI_Offset bbufsize;
+ MPI_Info info_used;
+ MPI_Comm comm=MPI_COMM_WORLD;
+
+ MPI_Init(&argc,&argv);
+ MPI_Comm_rank(comm, &rank);
+ MPI_Comm_size(comm, &nprocs);
+
+ /* get command-line arguments */
+ while ((i = getopt(argc, argv, "hq")) != EOF)
+ switch(i) {
+ case 'q': verbose = 0;
+ break;
+ case 'h':
+ default: if (rank==0) usage(argv[0]);
+ MPI_Finalize();
+ return 0;
+ }
+ argc -= optind;
+ argv += optind;
+ if (argc >= 1) filename = argv[0]; /* optional argument */
+ len = 10;
+ if (argc >= 2) len = atoi(argv[1]); /* optional argument */
+
+ for (i=0; i<NDIMS; i++) psizes[i] = 0;
+
+ MPI_Dims_create(nprocs, NDIMS, psizes);
+ start[0] = rank % psizes[0];
+ start[1] = (rank / psizes[1]) % psizes[1];
+ start[2] = (rank / (psizes[0] * psizes[1])) % psizes[2];
+
+ bufsize = 1;
+ for (i=0; i<NDIMS; i++) {
+ gsizes[i] = len * psizes[i];
+ start[i] *= len;
+ count[i] = len;
+ bufsize *= len;
+ }
+
+ /* allocate buffer and initialize with random numbers */
+ srand(rank);
+ for (i=0; i<NUM_VARS; i++) {
+ buf[i] = (int *) malloc(bufsize * sizeof(int));
+ for (j=0; j<bufsize; j++) buf[i][j] = rand();
+ }
+
+ MPI_Barrier(comm);
+ write_timing = MPI_Wtime();
+
+ /* create the file */
+ err = ncmpi_create(comm, filename, NC_CLOBBER|NC_64BIT_DATA, MPI_INFO_NULL,
+ &ncid);
+ if (err != NC_NOERR) {
+ printf("Error: ncmpi_create() file %s (%s)\n",filename,ncmpi_strerror(err));
+ MPI_Abort(comm, -1);
+ exit(1);
+ }
+
+ /* define dimensions */
+ for (i=0; i<NDIMS; i++) {
+ sprintf(str, "%c", 'x'+i);
+ err = ncmpi_def_dim(ncid, str, gsizes[i], &dimids[i]);
+ HANDLE_ERROR
+ }
+
+ /* define variables */
+ for (i=0; i<NUM_VARS; i++) {
+ sprintf(str, "var%d", i);
+ err = ncmpi_def_var(ncid, str, NC_INT, NDIMS, dimids, &varids[i]);
+ HANDLE_ERROR
+ }
+
+ /* post a nonblocking request for writing one variable at a time using
+ * iput and ignore the request ID, as we will flush all pending request
+ * in one ncmpi_wait_all() call */
+ for (i=0; i<NUM_VARS; i++) {
+ err = ncmpi_iput_vara_int(ncid, varids[i], start, count, buf[i], NULL);
+ HANDLE_ERROR
+ }
+
+ /* write one variable at a time using bput */
+
+ /* bbufsize must be max of data type converted before and after */
+ bbufsize = bufsize * NUM_VARS * sizeof(int);
+ err = ncmpi_buffer_attach(ncid, bbufsize);
+ HANDLE_ERROR
+
+ /* post a nonblocking request for writing one variable at a time using
+ * bput and ignore the request ID, as we will flush all pending request
+ * in one ncmpi_wait_all() call */
+ for (i=0; i<NUM_VARS; i++) {
+ err = ncmpi_bput_vara_int(ncid, varids[i], start, count, buf[i], NULL);
+ HANDLE_ERROR
+ /* can safely change contents or free up the buf[i] here */
+ }
+
+ /* exit the define mode */
+ err = ncmpi_enddef(ncid);
+ HANDLE_ERROR
+
+ /* wait for all the nonblocking I/O to complete */
+ err = ncmpi_wait_all(ncid, NC_REQ_ALL, NULL, NULL);
+ HANDLE_ERROR
+
+ /* detach the temporary buffer */
+ err = ncmpi_buffer_detach(ncid);
+ HANDLE_ERROR
+
+ /* get all the hints used */
+ err = ncmpi_inq_file_info(ncid, &info_used);
+ HANDLE_ERROR
+
+ MPI_Offset put_size;
+ ncmpi_inq_put_size(ncid, &put_size);
+#ifdef MPI_OFFSET
+ MPI_Allreduce(MPI_IN_PLACE, &put_size, 1, MPI_OFFSET, MPI_SUM, comm);
+#else
+ MPI_Allreduce(MPI_IN_PLACE, &put_size, 1, MPI_LONG_LONG, MPI_SUM, comm);
+#endif
+
+ /* close the file */
+ err = ncmpi_close(ncid);
+ HANDLE_ERROR
+
+ write_timing = MPI_Wtime() - write_timing;
+
+ write_size = bufsize * NUM_VARS * sizeof(int);
+ for (i=0; i<NUM_VARS; i++) free(buf[i]);
+
+#ifdef MPI_OFFSET
+ MPI_Reduce(&write_size, &sum_write_size, 1, MPI_OFFSET, MPI_SUM, 0, comm);
+#else
+ MPI_Reduce(&write_size, &sum_write_size, 1, MPI_LONG_LONG, MPI_SUM, 0, comm);
+#endif
+ MPI_Reduce(&write_timing, &max_write_timing, 1, MPI_DOUBLE, MPI_MAX, 0, comm);
+
+ if (rank == 0 && verbose) {
+ printf("\n");
+ printf("Total amount writes to variables only (exclude header) = %lld bytes\n", sum_write_size);
+ printf("Total amount writes reported by pnetcdf (include header) = %lld bytes\n", put_size);
+ printf("\n");
+ float subarray_size = (float)bufsize*sizeof(int)/1048576.0;
+ print_info(&info_used);
+ printf("Local array size %d x %d x %d integers, size = %.2f MB\n",len,len,len,subarray_size);
+ sum_write_size /= 1048576.0;
+ printf("Global array size %d x %d x %d integers, write size = %.2f GB\n",
+ gsizes[0], gsizes[1], gsizes[2], sum_write_size/1024.0);
+
+ write_bw = sum_write_size/max_write_timing;
+ printf(" procs Global array size exec(sec) write(MB/s)\n");
+ printf("------- ------------------ --------- -----------\n");
+ printf(" %4d %4d x %4d x %4d %8.2f %10.2f\n", nprocs,
+ gsizes[0], gsizes[1], gsizes[2], max_write_timing, write_bw);
+ }
+ MPI_Info_free(&info_used);
+
+ /* check if there is any PnetCDF internal malloc residue */
+ MPI_Offset malloc_size, sum_size;
+ err = ncmpi_inq_malloc_size(&malloc_size);
+ if (err == NC_NOERR) {
+ MPI_Reduce(&malloc_size, &sum_size, 1, MPI_OFFSET, MPI_SUM, 0, comm);
+ if (rank == 0 && sum_size > 0)
+ printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n",
+ sum_size);
+ }
+
+ MPI_Finalize();
+ return 0;
+}
+
diff --git a/examples/C/put_vara.c b/examples/C/put_vara.c
new file mode 100644
index 0000000..baed78f
--- /dev/null
+++ b/examples/C/put_vara.c
@@ -0,0 +1,194 @@
+/*********************************************************************
+ *
+ * Copyright (C) 2013, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ *
+ *********************************************************************/
+/* $Id: put_vara.c 2245 2015-12-20 18:39:52Z wkliao $ */
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * This example shows how to use ncmpi_put_vara_int_all() to write a 2D
+ * 4-byte integer array in parallel. It first defines a netCDF variable of
+ * size global_nx * global_ny where
+ * global_ny == NY and
+ * global_nx == (NX * number of MPI processes).
+ * The data partitioning pattern is a column-wise partitioning across all
+ * processes. Each process writes a subarray of size ny * nx.
+ *
+ * To compile:
+ * mpicc -O2 put_vara.c -o put_vara -lpnetcdf
+ *
+ * Example commands for MPI run and outputs from running ncmpidump on the
+ * NC file produced by this example program:
+ *
+ * % mpiexec -n 4 ./put_vara /pvfs2/wkliao/testfile.nc
+ *
+ * % ncmpidump /pvfs2/wkliao/testfile.nc
+ * netcdf testfile {
+ * // file format: CDF-5 (big variables)
+ * dimensions:
+ * y = 10 ;
+ * x = 16 ;
+ * variables:
+ * int var(y, x) ;
+ * var:str_att_name = "example attribute of type text." ;
+ * var:float_att_name = 0.f, 1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 7.f ;
+ * var:int64_att_name = 10000000000L ;
+ * // global attributes:
+ * :history = "Wed Apr 30 11:18:58 2014\n",
+ * "" ;
+ * data:
+ *
+ * var =
+ * 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3,
+ * 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3,
+ * 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3,
+ * 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3,
+ * 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3,
+ * 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3,
+ * 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3,
+ * 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3,
+ * 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3,
+ * 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3 ;
+ * }
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h> /* strcpy() */
+#include <unistd.h> /* getopt() */
+#include <time.h> /* time() localtime(), asctime() */
+#include <assert.h>
+#include <mpi.h>
+#include <pnetcdf.h>
+
+#define NY 10
+#define NX 4
+
+
+#define ERR {if(err!=NC_NOERR)printf("Error at line=%d: %s\n", __LINE__, ncmpi_strerror(err));}
+
+static void
+usage(char *argv0)
+{
+ char *help =
+ "Usage: %s [-h] | [-q] [file_name]\n"
+ " [-h] Print help\n"
+ " [-q] Quiet mode (reports when fail)\n"
+ " [filename] output netCDF file name\n";
+ fprintf(stderr, help, argv0);
+}
+
+int main(int argc, char** argv)
+{
+ extern int optind;
+ char filename[256];
+ int i, j, rank, nprocs, verbose=1, err;
+ int ncid, cmode, varid, dimid[2], buf[NY][NX];
+ char str_att[128];
+ float float_att[100];
+ MPI_Offset global_ny, global_nx;
+ MPI_Offset start[2], count[2];
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+
+ /* get command-line arguments */
+ while ((i = getopt(argc, argv, "hq")) != EOF)
+ switch(i) {
+ case 'q': verbose = 0;
+ break;
+ case 'h':
+ default: if (rank==0) usage(argv[0]);
+ MPI_Finalize();
+ return 0;
+ }
+ argc -= optind;
+ argv += optind;
+ if (argc == 1) strcpy(filename, argv[0]); /* optional argument */
+ else strcpy(filename, "testfile.nc");
+
+ MPI_Bcast(filename, 256, MPI_CHAR, 0, MPI_COMM_WORLD);
+
+ if (verbose && rank == 0) printf("%s: example of using put_vara APIs\n",__FILE__);
+
+ /* create a new file for writing ----------------------------------------*/
+ cmode = NC_CLOBBER | NC_64BIT_DATA;
+ err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, MPI_INFO_NULL, &ncid);
+ ERR
+
+ /* the global array is NY * (NX * nprocs) */
+ global_ny = NY;
+ global_nx = NX * nprocs;
+
+ for (i=0; i<NY; i++)
+ for (j=0; j<NX; j++)
+ buf[i][j] = rank;
+
+ /* add a global attribute: a time stamp at rank 0 */
+ time_t ltime = time(NULL); /* get the current calendar time */
+ asctime_r(localtime(<ime), str_att);
+
+ /* make sure the time string are consistent among all processes */
+ MPI_Bcast(str_att, strlen(str_att), MPI_CHAR, 0, MPI_COMM_WORLD);
+
+ err = ncmpi_put_att_text(ncid, NC_GLOBAL, "history", strlen(str_att),
+ &str_att[0]);
+ ERR
+
+ /* define dimensions x and y */
+ err = ncmpi_def_dim(ncid, "Y", global_ny, &dimid[0]);
+ ERR
+ err = ncmpi_def_dim(ncid, "X", global_nx, &dimid[1]);
+ ERR
+
+ /* define a 2D variable of integer type */
+ err = ncmpi_def_var(ncid, "var", NC_INT, 2, dimid, &varid);
+ ERR
+
+ /* add attributes to the variable */
+ strcpy(str_att, "example attribute of type text.");
+ err = ncmpi_put_att_text(ncid, varid, "str_att_name", strlen(str_att),
+ &str_att[0]);
+ ERR
+
+ for (i=0; i<8; i++) float_att[i] = i;
+ err = ncmpi_put_att_float(ncid, varid, "float_att_name", NC_FLOAT, 8,
+ &float_att[0]);
+ ERR
+ long long int64_att=10000000000LL;
+ err = ncmpi_put_att_longlong(ncid, varid, "int64_att_name", NC_INT64, 1,
+ &int64_att);
+ ERR
+
+ /* do not forget to exit define mode */
+ err = ncmpi_enddef(ncid);
+ ERR
+
+ /* now we are in data mode */
+ start[0] = 0;
+ start[1] = NX * rank;
+ count[0] = NY;
+ count[1] = NX;
+
+ err = ncmpi_put_vara_int_all(ncid, varid, start, count, &buf[0][0]);
+ ERR
+
+ err = ncmpi_close(ncid);
+ ERR
+
+ /* check if there is any PnetCDF internal malloc residue */
+ MPI_Offset malloc_size, sum_size;
+ err = ncmpi_inq_malloc_size(&malloc_size);
+ if (err == NC_NOERR) {
+ MPI_Reduce(&malloc_size, &sum_size, 1, MPI_OFFSET, MPI_SUM, 0, MPI_COMM_WORLD);
+ if (rank == 0 && sum_size > 0)
+ printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n",
+ sum_size);
+ }
+
+ MPI_Finalize();
+ return 0;
+}
+
diff --git a/examples/C/put_varn_float.c b/examples/C/put_varn_float.c
new file mode 100644
index 0000000..d269373
--- /dev/null
+++ b/examples/C/put_varn_float.c
@@ -0,0 +1,218 @@
+/*********************************************************************
+ *
+ * Copyright (C) 2013, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ *
+ *********************************************************************/
+/* $Id: put_varn_float.c 1669 2014-05-24 18:28:16Z wkliao $ */
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * This example shows how to use a single call of ncmpi_put_varn_float_all()
+ * to write a sequence of one-element requests with arbitrary array indices.
+ *
+ * The compile and run commands are given below, together with an ncmpidump of
+ * the output file.
+ *
+ * % mpicc -O2 -o put_varn_float put_varn_float.c -lpnetcdf
+ * % mpiexec -n 4 ./put_varn_float /pvfs2/wkliao/testfile.nc
+ * % ncmpidump /pvfs2/wkliao/testfile.nc
+ * netcdf testfile {
+ * // file format: CDF-5 (big variables)
+ * dimensions:
+ * Y = 4 ;
+ * X = 10 ;
+ * variables:
+ * int var(Y, X) ;
+ * data:
+ *
+ * var =
+ * 3, 3, 3, 1, 1, 0, 0, 2, 1, 1,
+ * 0, 2, 2, 2, 3, 1, 1, 2, 2, 2,
+ * 1, 1, 2, 3, 3, 3, 0, 0, 1, 1,
+ * 0, 0, 0, 2, 1, 1, 1, 3, 3, 3 ;
+ * }
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h> /* strcpy() */
+#include <unistd.h> /* getopt() */
+#include <assert.h>
+#include <mpi.h>
+#include <pnetcdf.h>
+
+#define NY 4
+#define NX 10
+#define NDIMS 2
+
+#define ERR {if(err!=NC_NOERR)printf("Error at line=%d: %s\n", __LINE__, ncmpi_strerror(err));}
+
+static void
+usage(char *argv0)
+{
+ char *help =
+ "Usage: %s [-h] | [-q] [file_name]\n"
+ " [-h] Print help\n"
+ " [-q] Quiet mode (reports when fail)\n"
+ " [filename] output netCDF file name\n";
+ fprintf(stderr, help, argv0);
+}
+
+int main(int argc, char** argv)
+{
+ extern int optind;
+ char *filename="testfile.nc";
+ int i, rank, nprocs, verbose=1, err;
+ int ncid, cmode, varid, dimid[2], num_reqs;
+ float *buffer;
+ MPI_Offset **starts;
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+
+ /* get command-line arguments */
+ while ((i = getopt(argc, argv, "hq")) != EOF)
+ switch(i) {
+ case 'q': verbose = 0;
+ break;
+ case 'h':
+ default: if (rank==0) usage(argv[0]);
+ MPI_Finalize();
+ return 0;
+ }
+ argc -= optind;
+ argv += optind;
+ if (argc == 1) filename = argv[0]; /* optional argument */
+
+ if (nprocs != 4 && rank == 0 && verbose)
+ printf("Warning: this program is intended to run on 4 processes\n");
+
+ /* create a new file for writing ----------------------------------------*/
+ cmode = NC_CLOBBER;
+ err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, MPI_INFO_NULL, &ncid);
+ ERR
+
+ /* create a global array of size NY * NX */
+ err = ncmpi_def_dim(ncid, "Y", NY, &dimid[0]);
+ ERR
+ err = ncmpi_def_dim(ncid, "X", NX, &dimid[1]);
+ ERR
+ err = ncmpi_def_var(ncid, "var", NC_FLOAT, NDIMS, dimid, &varid);
+ ERR
+ err = ncmpi_enddef(ncid);
+ ERR
+
+ /* pick arbitrary numbers of requests for 4 processes */
+ num_reqs = 0;
+ if (rank == 0) num_reqs = 8;
+ else if (rank == 1) num_reqs = 13;
+ else if (rank == 2) num_reqs = 9;
+ else if (rank == 3) num_reqs = 10;
+
+ starts = (MPI_Offset**) malloc(num_reqs * sizeof(MPI_Offset*));
+ starts[0] = (MPI_Offset*) calloc(num_reqs * NDIMS, sizeof(MPI_Offset));
+ for (i=1; i<num_reqs; i++)
+ starts[i] = starts[i-1] + NDIMS;
+
+ /* assign arbitrary starts */
+ const int y=0, x=1;
+ if (rank == 0) {
+ starts[0][y] = 0; starts[0][x] = 5;
+ starts[1][y] = 1; starts[1][x] = 0;
+ starts[2][y] = 2; starts[2][x] = 6;
+ starts[3][y] = 3; starts[3][x] = 0;
+ starts[4][y] = 0; starts[4][x] = 6;
+ starts[5][y] = 2; starts[5][x] = 7;
+ starts[6][y] = 3; starts[6][x] = 1;
+ starts[7][y] = 3; starts[7][x] = 2;
+ /* rank 0 is writing the following locations: ("-" means skip)
+ - - - - - 0 0 - - -
+ 0 - - - - - - - - -
+ - - - - - - 0 0 - -
+ 0 0 0 - - - - - - -
+ */
+ } else if (rank ==1) {
+ starts[ 0][y] = 0; starts[ 0][x] = 3;
+ starts[ 1][y] = 0; starts[ 1][x] = 8;
+ starts[ 2][y] = 1; starts[ 2][x] = 5;
+ starts[ 3][y] = 2; starts[ 3][x] = 0;
+ starts[ 4][y] = 2; starts[ 4][x] = 8;
+ starts[ 5][y] = 3; starts[ 5][x] = 4;
+ starts[ 6][y] = 0; starts[ 6][x] = 4;
+ starts[ 7][y] = 0; starts[ 7][x] = 9;
+ starts[ 8][y] = 1; starts[ 8][x] = 6;
+ starts[ 9][y] = 2; starts[ 9][x] = 1;
+ starts[10][y] = 2; starts[10][x] = 9;
+ starts[11][y] = 3; starts[11][x] = 5;
+ starts[12][y] = 3; starts[12][x] = 6;
+ /* rank 1 is writing the following locations: ("-" means skip)
+ - - - 1 1 - - - 1 1
+ - - - - - 1 1 - - -
+ 1 1 - - - - - - 1 1
+ - - - - 1 1 1 - - -
+ */
+ } else if (rank ==2) {
+ starts[0][y] = 0; starts[0][x] = 7;
+ starts[1][y] = 1; starts[1][x] = 1;
+ starts[2][y] = 1; starts[2][x] = 7;
+ starts[3][y] = 2; starts[3][x] = 2;
+ starts[4][y] = 3; starts[4][x] = 3;
+ starts[5][y] = 1; starts[5][x] = 2;
+ starts[6][y] = 1; starts[6][x] = 8;
+ starts[7][y] = 1; starts[7][x] = 3;
+ starts[8][y] = 1; starts[8][x] = 9;
+ /* rank 2 is writing the following locations: ("-" means skip)
+ - - - - - - - 2 - -
+ - 2 2 2 - - - 2 2 2
+ - - 2 - - - - - - -
+ - - - 2 - - - - - -
+ */
+ } else if (rank ==3) {
+ starts[0][y] = 0; starts[0][x] = 0;
+ starts[1][y] = 1; starts[1][x] = 4;
+ starts[2][y] = 2; starts[2][x] = 3;
+ starts[3][y] = 3; starts[3][x] = 7;
+ starts[4][y] = 0; starts[4][x] = 1;
+ starts[5][y] = 2; starts[5][x] = 4;
+ starts[6][y] = 3; starts[6][x] = 8;
+ starts[7][y] = 0; starts[7][x] = 2;
+ starts[8][y] = 2; starts[8][x] = 5;
+ starts[9][y] = 3; starts[9][x] = 9;
+ /* rank 3 is writing the following locations: ("-" means skip)
+ 3 3 3 - - - - - - -
+ - - - - 3 - - - - -
+ - - - 3 3 3 - - - -
+ - - - - - - - 3 3 3
+ */
+ }
+
+ /* allocate I/O buffer and initialize its contents */
+ buffer = (float*) malloc(num_reqs * sizeof(float));
+ for (i=0; i<num_reqs; i++) buffer[i] = (float)rank;
+
+ /* set the buffer pointers to different offsets to the I/O buffer */
+ err = ncmpi_put_varn_float_all(ncid, varid, num_reqs, starts, NULL, buffer);
+ ERR
+
+ err = ncmpi_close(ncid);
+ ERR
+
+ free(buffer);
+ free(starts[0]);
+ free(starts);
+
+ /* check if there is any PnetCDF internal malloc residue */
+ MPI_Offset malloc_size, sum_size;
+ err = ncmpi_inq_malloc_size(&malloc_size);
+ if (err == NC_NOERR) {
+ MPI_Reduce(&malloc_size, &sum_size, 1, MPI_OFFSET, MPI_SUM, 0, MPI_COMM_WORLD);
+ if (rank == 0 && sum_size > 0)
+ printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n",
+ sum_size);
+ }
+
+ MPI_Finalize();
+ return 0;
+}
+
diff --git a/examples/C/put_varn_int.c b/examples/C/put_varn_int.c
new file mode 100644
index 0000000..1159a11
--- /dev/null
+++ b/examples/C/put_varn_int.c
@@ -0,0 +1,219 @@
+/*********************************************************************
+ *
+ * Copyright (C) 2013, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ *
+ *********************************************************************/
+/* $Id: put_varn_int.c 1669 2014-05-24 18:28:16Z wkliao $ */
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * This example shows how to use a single call of ncmpi_put_varn_int_all() to
+ * write a sequence of requests with arbitrary array indices and lengths.
+ * Using ncmpi_put_varn_int_all() can achieve the same effect of HDF5 writing
+ * a sequence of selected file locations through the following 2 APIs.
+ *
+ * H5Sselect_elements(fid, H5S_SELECT_SET, NUMP, (const hssize_t **)coord);
+ * H5Dwrite(dataset, H5T_NATIVE_INT, mid, fid, H5P_DEFAULT, val);
+ *
+ * Note that in ncmpi_put_varn_int_all(), users can write more than one
+ * element starting at each selected location.
+ *
+ * The compile and run commands are given below, together with an ncmpidump of
+ * the output file.
+ *
+ * % mpicc -O2 -o put_varn_int put_varn_int.c -lpnetcdf
+ * % mpiexec -n 4 ./put_varn_int /pvfs2/wkliao/testfile.nc
+ * % ncmpidump /pvfs2/wkliao/testfile.nc
+ * netcdf testfile {
+ * // file format: CDF-5 (big variables)
+ * dimensions:
+ * Y = 4 ;
+ * X = 10 ;
+ * variables:
+ * int var(Y, X) ;
+ * data:
+ *
+ * var =
+ * 3, 3, 3, 1, 1, 0, 0, 2, 1, 1,
+ * 0, 2, 2, 2, 3, 1, 1, 2, 2, 2,
+ * 1, 1, 2, 3, 3, 3, 0, 0, 1, 1,
+ * 0, 0, 0, 2, 1, 1, 1, 3, 3, 3 ;
+ * }
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h> /* strcpy() */
+#include <unistd.h> /* getopt() */
+#include <assert.h>
+#include <mpi.h>
+#include <pnetcdf.h>
+
+#define NY 4
+#define NX 10
+#define NDIMS 2
+
+#define ERR {if(err!=NC_NOERR)printf("Error at line=%d: %s\n", __LINE__, ncmpi_strerror(err));}
+
+static void
+usage(char *argv0)
+{
+ char *help =
+ "Usage: %s [-h] | [-q] [file_name]\n"
+ " [-h] Print help\n"
+ " [-q] Quiet mode (reports when fail)\n"
+ " [filename] output netCDF file name\n";
+ fprintf(stderr, help, argv0);
+}
+
+int main(int argc, char** argv)
+{
+ extern int optind;
+ char *filename="testfile.nc";
+ int i, j, rank, nprocs, verbose=1, err;
+ int ncid, cmode, varid, dimid[2], num_reqs, *buffer;
+ MPI_Offset w_len, **starts, **counts;
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+
+ /* get command-line arguments */
+ while ((i = getopt(argc, argv, "hq")) != EOF)
+ switch(i) {
+ case 'q': verbose = 0;
+ break;
+ case 'h':
+ default: if (rank==0) usage(argv[0]);
+ MPI_Finalize();
+ return 0;
+ }
+ argc -= optind;
+ argv += optind;
+ if (argc == 1) filename = argv[0]; /* optional argument */
+
+ if (nprocs != 4 && rank == 0 && verbose)
+ printf("Warning: this program is intended to run on 4 processes\n");
+
+ /* create a new file for writing ----------------------------------------*/
+ cmode = NC_CLOBBER | NC_64BIT_DATA;
+ err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, MPI_INFO_NULL, &ncid);
+ ERR
+
+ /* create a global array of size NY * NX */
+ err = ncmpi_def_dim(ncid, "Y", NY, &dimid[0]);
+ ERR
+ err = ncmpi_def_dim(ncid, "X", NX, &dimid[1]);
+ ERR
+ err = ncmpi_def_var(ncid, "var", NC_INT, NDIMS, dimid, &varid);
+ ERR
+ err = ncmpi_enddef(ncid);
+ ERR
+
+ /* pick arbitrary numbers of requests for 4 processes */
+ num_reqs = 0;
+ if (rank == 0) num_reqs = 4;
+ else if (rank == 1) num_reqs = 6;
+ else if (rank == 2) num_reqs = 5;
+ else if (rank == 3) num_reqs = 4;
+
+ starts = (MPI_Offset**) malloc(num_reqs * sizeof(MPI_Offset*));
+ counts = (MPI_Offset**) malloc(num_reqs * sizeof(MPI_Offset*));
+ starts[0] = (MPI_Offset*) calloc(num_reqs * NDIMS, sizeof(MPI_Offset));
+ counts[0] = (MPI_Offset*) calloc(num_reqs * NDIMS, sizeof(MPI_Offset));
+ for (i=1; i<num_reqs; i++) {
+ starts[i] = starts[i-1] + NDIMS;
+ counts[i] = counts[i-1] + NDIMS;
+ }
+
+ /* assign arbitrary starts and counts */
+ const int y=0, x=1;
+ if (rank == 0) {
+ starts[0][y] = 0; starts[0][x] = 5; counts[0][y] = 1; counts[0][x] = 2;
+ starts[1][y] = 1; starts[1][x] = 0; counts[1][y] = 1; counts[1][x] = 1;
+ starts[2][y] = 2; starts[2][x] = 6; counts[2][y] = 1; counts[2][x] = 2;
+ starts[3][y] = 3; starts[3][x] = 0; counts[3][y] = 1; counts[3][x] = 3;
+ /* rank 0 is writing the followings: ("-" means skip)
+ - - - - - 0 0 - - -
+ 0 - - - - - - - - -
+ - - - - - - 0 0 - -
+ 0 0 0 - - - - - - -
+ */
+ } else if (rank ==1) {
+ starts[0][y] = 0; starts[0][x] = 3; counts[0][y] = 1; counts[0][x] = 2;
+ starts[1][y] = 0; starts[1][x] = 8; counts[1][y] = 1; counts[1][x] = 2;
+ starts[2][y] = 1; starts[2][x] = 5; counts[2][y] = 1; counts[2][x] = 2;
+ starts[3][y] = 2; starts[3][x] = 0; counts[3][y] = 1; counts[3][x] = 2;
+ starts[4][y] = 2; starts[4][x] = 8; counts[4][y] = 1; counts[4][x] = 2;
+ starts[5][y] = 3; starts[5][x] = 4; counts[5][y] = 1; counts[5][x] = 3;
+ /* rank 1 is writing the followings: ("-" means skip)
+ - - - 1 1 - - - 1 1
+ - - - - - 1 1 - - -
+ 1 1 - - - - - - 1 1
+ - - - - 1 1 1 - - -
+ */
+ } else if (rank ==2) {
+ starts[0][y] = 0; starts[0][x] = 7; counts[0][y] = 1; counts[0][x] = 1;
+ starts[1][y] = 1; starts[1][x] = 1; counts[1][y] = 1; counts[1][x] = 3;
+ starts[2][y] = 1; starts[2][x] = 7; counts[2][y] = 1; counts[2][x] = 3;
+ starts[3][y] = 2; starts[3][x] = 2; counts[3][y] = 1; counts[3][x] = 1;
+ starts[4][y] = 3; starts[4][x] = 3; counts[4][y] = 1; counts[4][x] = 1;
+ /* rank 2 is writing the followings: ("-" means skip)
+ - - - - - - - 2 - -
+ - 2 2 2 - - - 2 2 2
+ - - 2 - - - - - - -
+ - - - 2 - - - - - -
+ */
+ } else if (rank ==3) {
+ starts[0][y] = 0; starts[0][x] = 0; counts[0][y] = 1; counts[0][x] = 3;
+ starts[1][y] = 1; starts[1][x] = 4; counts[1][y] = 1; counts[1][x] = 1;
+ starts[2][y] = 2; starts[2][x] = 3; counts[2][y] = 1; counts[2][x] = 3;
+ starts[3][y] = 3; starts[3][x] = 7; counts[3][y] = 1; counts[3][x] = 3;
+ /* rank 3 is writing the followings: ("-" means skip)
+ 3 3 3 - - - - - - -
+ - - - - 3 - - - - -
+ - - - 3 3 3 - - - -
+ - - - - - - - 3 3 3
+ */
+ }
+
+ w_len = 0; /* total write length for this process */
+ for (i=0; i<num_reqs; i++) {
+ MPI_Offset w_req_len=1;
+ for (j=0; j<NDIMS; j++)
+ w_req_len *= counts[i][j];
+ w_len += w_req_len;
+ }
+
+ /* allocate I/O buffer and initialize its contents */
+ buffer = (int*) malloc(w_len * sizeof(int));
+ for (i=0; i<w_len; i++) buffer[i] = rank;
+
+ /* set the buffer pointers to different offsets to the I/O buffer */
+ err = ncmpi_put_varn_int_all(ncid, varid, num_reqs, starts,
+ counts, buffer);
+ ERR
+
+ err = ncmpi_close(ncid);
+ ERR
+
+ free(buffer);
+ free(starts[0]);
+ free(counts[0]);
+ free(starts);
+ free(counts);
+
+ /* check if there is any PnetCDF internal malloc residue */
+ MPI_Offset malloc_size, sum_size;
+ err = ncmpi_inq_malloc_size(&malloc_size);
+ if (err == NC_NOERR) {
+ MPI_Reduce(&malloc_size, &sum_size, 1, MPI_OFFSET, MPI_SUM, 0, MPI_COMM_WORLD);
+ if (rank == 0 && sum_size > 0)
+ printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n",
+ sum_size);
+ }
+
+ MPI_Finalize();
+ return 0;
+}
+
diff --git a/examples/C/req_all.c b/examples/C/req_all.c
new file mode 100644
index 0000000..5704b0b
--- /dev/null
+++ b/examples/C/req_all.c
@@ -0,0 +1,185 @@
+/*********************************************************************
+ *
+ * Copyright (C) 2015, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ *
+ *********************************************************************/
+/* $Id$ */
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * This example is mostly the same as column_wise.c but shows how to use
+ * NC_REQ_ALL to commit all pending nonblocking I/O without checking the status
+ * of individual requests. In this case, the first encountered error will be
+ * returned in ncmpi_wait_all().
+ *
+ * The compile and run commands are given below, together with an ncmpidump of
+ * the output file.
+ *
+ * % mpicc -O2 -o req_all req_all.c -lpnetcdf
+ * % mpiexec -l -n 4 ./column_wise /pvfs2/wkliao/testfile.nc
+ * 0: 0: myOff= 0 myNX= 4
+ * 1: 1: myOff= 4 myNX= 4
+ * 2: 2: myOff= 8 myNX= 4
+ * 3: 3: myOff= 12 myNX= 4
+ * 0: 0: start= 0 0 count= 10 1
+ * 1: 1: start= 0 1 count= 10 1
+ * 2: 2: start= 0 2 count= 10 1
+ * 3: 3: start= 0 3 count= 10 1
+ *
+ * % ncmpidump /pvfs2/wkliao/testfile.nc
+ * netcdf testfile {
+ * // file format: CDF-1
+ * dimensions:
+ * Y = 10 ;
+ * X = 16 ;
+ * variables:
+ * int var(Y, X) ;
+ * data:
+ *
+ * var =
+ * 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3,
+ * 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3,
+ * 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3,
+ * 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3,
+ * 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3,
+ * 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3,
+ * 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3,
+ * 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3,
+ * 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3,
+ * 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3 ;
+ * }
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h> /* strcpy() */
+#include <unistd.h> /* getopt() */
+#include <mpi.h>
+#include <pnetcdf.h>
+
+#define NY 10
+#define NX 4
+
+#define ERR {if(err!=NC_NOERR)printf("Error at line=%d: %s\n", __LINE__, ncmpi_strerror(err));}
+
+static void
+usage(char *argv0)
+{
+ char *help =
+ "Usage: %s [-h] | [-q] [file_name]\n"
+ " [-h] Print help\n"
+ " [-q] Quiet mode (reports when fail)\n"
+ " [filename] output netCDF file name\n";
+ fprintf(stderr, help, argv0);
+}
+
+int main(int argc, char** argv)
+{
+ extern int optind;
+ char *filename = "testfile.nc";
+ int i, j, verbose=1, rank, nprocs, err, myNX, G_NX, myOff;
+ int ncid, cmode, varid, dimid[2], **buf;
+ MPI_Offset start[2], count[2];
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+
+ /* get command-line arguments */
+ while ((i = getopt(argc, argv, "hq")) != EOF)
+ switch(i) {
+ case 'q': verbose = 0;
+ break;
+ case 'h':
+ default: if (rank==0) usage(argv[0]);
+ MPI_Finalize();
+ return 0;
+ }
+ argc -= optind;
+ argv += optind;
+ if (argc == 1) filename = argv[0]; /* optional argument */
+
+ cmode = NC_CLOBBER;
+ err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, MPI_INFO_NULL, &ncid);
+ ERR
+
+ /* the global array is NY * (NX * nprocs) */
+ G_NX = NX * nprocs;
+ myOff = NX * rank;
+ myNX = NX;
+ if (verbose) printf("%2d: myOff=%3d myNX=%3d\n",rank,myOff,myNX);
+
+ err = ncmpi_def_dim(ncid, "Y", NY, &dimid[0]);
+ ERR
+ err = ncmpi_def_dim(ncid, "X", G_NX, &dimid[1]);
+ ERR
+ err = ncmpi_def_var(ncid, "var", NC_INT, 2, dimid, &varid);
+ ERR
+ err = ncmpi_enddef(ncid);
+ ERR
+
+ /* initialize the buffer with rank ID */
+ buf = (int**) malloc(myNX * sizeof(int*));
+ for (i=0; i<myNX; i++) {
+ buf[i] = (int*) malloc(NY * sizeof(int));
+ for (j=0; j<NY; j++) buf[i][j] = rank;
+ }
+
+ /* each proc writes myNX single columns of the 2D array */
+ start[0] = 0; start[1] = rank;
+ count[0] = NY; count[1] = 1;
+ if (verbose)
+ printf("%2d: start=%3lld %3lld count=%3lld %3lld\n",
+ rank, start[0],start[1], count[0],count[1]);
+
+ for (i=0; i<myNX; i++) {
+ err = ncmpi_iput_vara_int(ncid, varid, start, count, buf[i], NULL);
+ ERR
+ start[1] += nprocs;
+ }
+ err = ncmpi_wait_all(ncid, NC_REQ_ALL, NULL, NULL);
+ ERR
+
+ /* read back using the same access pattern */
+ for (i=0; i<myNX; i++)
+ for (j=0; j<NY; j++) buf[i][j] = -1;
+
+ /* each proc reads myNX single columns of the 2D array */
+ start[0] = 0; start[1] = rank;
+ count[0] = NY; count[1] = 1;
+
+ for (i=0; i<myNX; i++) {
+ err = ncmpi_iget_vara_int(ncid, varid, start, count, buf[i], NULL);
+ ERR
+ start[1] += nprocs;
+ }
+ err = ncmpi_wait_all(ncid, NC_REQ_ALL, NULL, NULL);
+ ERR
+
+ /* check contents of read data of all requests */
+ for (i=0; i<myNX; i++) {
+ for (j=0; j<NY; j++)
+ if (buf[i][j] != rank)
+ printf("Error: expect buf[%d][%d]=%d but got %d\n",i,j,rank,buf[i][j]);
+ }
+
+ err = ncmpi_close(ncid);
+ ERR
+
+ for (i=0; i<myNX; i++) free(buf[i]);
+ free(buf);
+
+ /* check if there is any PnetCDF internal malloc residue */
+ MPI_Offset malloc_size, sum_size;
+ err = ncmpi_inq_malloc_size(&malloc_size);
+ if (err == NC_NOERR) {
+ MPI_Reduce(&malloc_size, &sum_size, 1, MPI_OFFSET, MPI_SUM, 0, MPI_COMM_WORLD);
+ if (rank == 0 && sum_size > 0)
+ printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n",
+ sum_size);
+ }
+
+ MPI_Finalize();
+ return 0;
+}
+
diff --git a/examples/C/transpose.c b/examples/C/transpose.c
new file mode 100644
index 0000000..6228ca0
--- /dev/null
+++ b/examples/C/transpose.c
@@ -0,0 +1,235 @@
+/*********************************************************************
+ *
+ * Copyright (C) 2014, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ *
+ *********************************************************************/
+/* $Id: transpose.c 1744 2014-08-23 19:19:58Z wkliao $ */
+
+/*
+ * This example shows how to use varm API to write six 3D integer array
+ * variables into a file. Each variable in the file is a dimensional
+ * transposed array from the one stored in memory. In memory, a 3D array is
+ * partitioned among all processes in a block-block-block fashion and in
+ * ZYX (i.e. C) order. The dimension structures of the transposed six
+ * arrays are
+ * int ZYX_var(Z, Y, X) ; ZYX -> ZYX
+ * int ZXY_var(Z, X, Y) ; ZYX -> ZXY
+ * int YZX_var(Y, Z, X) ; ZYX -> YZX
+ * int YXZ_var(Y, X, Z) ; ZYX -> YXZ
+ * int XZY_var(X, Z, Y) ; ZYX -> XZY
+ * int XYZ_var(X, Y, Z) ; ZYX -> XYZ
+ *
+ * To compile:
+ * mpicc -O2 transpose.c -o transpose -lpnetcdf
+ * To run:
+ * mpiexec -n num_processes ./transpose [filename] [len]
+ * where len decides the size of local array, which is len x len+1 x len+2.
+ * So, each variable is of size len*(len+1)*(len+2) * nprocs * sizeof(int)
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h> /* strlen() */
+#include <unistd.h> /* getopt() */
+#include <mpi.h>
+#include <pnetcdf.h>
+
+#define NDIMS 3
+
+#define HANDLE_ERROR { \
+ if (err != NC_NOERR) \
+ printf("Error at line %d (%s)\n", __LINE__, \
+ ncmpi_strerror(err)); \
+}
+
+static void
+usage(char *argv0)
+{
+ char *help =
+ "Usage: %s [-h] | [-q] [file_name] [len]\n"
+ " [-h] Print this help\n"
+ " [-q] quiet mode\n"
+ " [filename] output netCDF file name\n"
+ " [len] size of each dimension of the local array\n";
+ fprintf(stderr, help, argv0);
+}
+
+
+/*----< main() >------------------------------------------------------------*/
+int main(int argc, char **argv)
+{
+ extern int optind;
+ char *filename="testfile.nc", str[512];
+ int i, j, k, rank, nprocs, len, ncid, bufsize, verbose=1, err;
+ int *buf, psizes[NDIMS], dimids[NDIMS], dimidsT[NDIMS];
+ int XYZ_id, XZY_id, YZX_id, YXZ_id, ZYX_id, ZXY_id;
+ MPI_Offset gsizes[NDIMS], starts[NDIMS], counts[NDIMS], imap[NDIMS];
+ MPI_Offset startsT[NDIMS], countsT[NDIMS];
+
+ MPI_Init(&argc,&argv);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+
+ /* get command-line arguments */
+ while ((i = getopt(argc, argv, "hq")) != EOF)
+ switch(i) {
+ case 'q': verbose = 0;
+ break;
+ case 'h':
+ default: if (rank==0) usage(argv[0]);
+ MPI_Finalize();
+ return 0;
+ }
+ argc -= optind;
+ argv += optind;
+ if (argc >= 1) filename = argv[0]; /* optional argument */
+ len = 2;
+ if (argc >= 2) len = atoi(argv[1]); /* optional argument */
+
+ for (i=0; i<NDIMS; i++)
+ psizes[i] = 0;
+
+ /* calculate number of processes along each dimension */
+ MPI_Dims_create(nprocs, NDIMS, psizes);
+ if (verbose && rank == 0) {
+ sprintf(str, "psizes= ");
+ for (i=0; i<NDIMS; i++) sprintf(str+strlen(str), "%d ",psizes[i]);
+ printf("%s\n",str);
+ }
+
+ /* for each MPI rank, find its local rank IDs along each dimension in
+ * starts[] */
+ int lower_dims=1;
+ for (i=NDIMS-1; i>=0; i--) {
+ starts[i] = rank / lower_dims % psizes[i];
+ lower_dims *= psizes[i];
+ }
+ if (verbose) {
+ sprintf(str, "proc %d: dim rank= ", rank);
+ for (i=0; i<NDIMS; i++) sprintf(str+strlen(str), "%lld ",starts[i]);
+ printf("%s\n",str);
+ }
+
+ bufsize = 1;
+ for (i=0; i<NDIMS; i++) {
+ gsizes[i] = (len + i) * psizes[i]; /* global array size */
+ starts[i] *= (len + i); /* start indices */
+ counts[i] = (len + i); /* array elements */
+ bufsize *= (len + i);
+ }
+
+ /* allocate buffer and initialize with contiguous numbers */
+ buf = (int *) malloc(bufsize * sizeof(int));
+ for (k=0; k<counts[0]; k++)
+ for (j=0; j<counts[1]; j++)
+ for (i=0; i<counts[2]; i++)
+ buf[k*counts[1]*counts[2] +
+ j*counts[2] + i] = (starts[0]+k)*gsizes[1]*gsizes[2]
+ + (starts[1]+j)*gsizes[2]
+ + (starts[2]+i);
+
+ /* create the file */
+ err = ncmpi_create(MPI_COMM_WORLD, filename, NC_CLOBBER|NC_64BIT_DATA,
+ MPI_INFO_NULL, &ncid);
+ if (err != NC_NOERR) {
+ printf("Error: ncmpi_create() file %s (%s)\n",filename,ncmpi_strerror(err));
+ MPI_Abort(MPI_COMM_WORLD, -1);
+ exit(1);
+ }
+
+ /* define dimensions */
+ for (i=0; i<NDIMS; i++) {
+ sprintf(str, "%c", 'Z'-i);
+ err = ncmpi_def_dim(ncid, str, gsizes[i], &dimids[i]);
+ HANDLE_ERROR
+ }
+
+ /* define variable with no transposed file layout: ZYX */
+ err = ncmpi_def_var(ncid, "ZYX_var", NC_INT, NDIMS, dimids, &ZYX_id);
+ HANDLE_ERROR
+
+ /* define variable with transposed file layout: ZYX -> ZXY */
+ dimidsT[0] = dimids[0]; dimidsT[1] = dimids[2]; dimidsT[2] = dimids[1];
+ err = ncmpi_def_var(ncid, "ZXY_var", NC_INT, NDIMS, dimidsT, &ZXY_id);
+ HANDLE_ERROR
+
+ /* define variable with transposed file layout: ZYX -> YZX */
+ dimidsT[0] = dimids[1]; dimidsT[1] = dimids[0]; dimidsT[2] = dimids[2];
+ err = ncmpi_def_var(ncid, "YZX_var", NC_INT, NDIMS, dimidsT, &YZX_id);
+ HANDLE_ERROR
+
+ /* define variable with transposed file layout: ZYX -> YXZ */
+ dimidsT[0] = dimids[1]; dimidsT[1] = dimids[2]; dimidsT[2] = dimids[0];
+ err = ncmpi_def_var(ncid, "YXZ_var", NC_INT, NDIMS, dimidsT, &YXZ_id);
+ HANDLE_ERROR
+
+ /* define variable with transposed file layout: ZYX -> XZY */
+ dimidsT[0] = dimids[2]; dimidsT[1] = dimids[0]; dimidsT[2] = dimids[1];
+ err = ncmpi_def_var(ncid, "XZY_var", NC_INT, NDIMS, dimidsT, &XZY_id);
+ HANDLE_ERROR
+
+ /* define variable with transposed file layout: ZYX -> XYZ */
+ dimidsT[0] = dimids[2]; dimidsT[1] = dimids[1]; dimidsT[2] = dimids[0];
+ err = ncmpi_def_var(ncid, "XYZ_var", NC_INT, NDIMS, dimidsT, &XYZ_id);
+ HANDLE_ERROR
+
+ /* exit the define mode */
+ err = ncmpi_enddef(ncid);
+ HANDLE_ERROR
+
+ /* write the whole variable in file: ZYX */
+ err = ncmpi_put_vara_int_all(ncid, ZYX_id, starts, counts, buf);
+ HANDLE_ERROR
+
+ /* ZYX -> ZXY: */
+ imap[1] = 1; imap[2] = counts[2]; imap[0] = counts[1]*counts[2];
+ startsT[0] = starts[0]; startsT[1] = starts[2]; startsT[2] = starts[1];
+ countsT[0] = counts[0]; countsT[1] = counts[2]; countsT[2] = counts[1];
+ /* write the transposed variable */
+ err = ncmpi_put_varm_int_all(ncid, ZXY_id, startsT, countsT, NULL, imap, buf);
+ HANDLE_ERROR
+
+ /* ZYX -> YZX: */
+ imap[2] = 1; imap[0] = counts[2]; imap[1] = counts[1]*counts[2];
+ startsT[0] = starts[1]; startsT[1] = starts[0]; startsT[2] = starts[2];
+ countsT[0] = counts[1]; countsT[1] = counts[0]; countsT[2] = counts[2];
+ /* write the transposed variable */
+ err = ncmpi_put_varm_int_all(ncid, YZX_id, startsT, countsT, NULL, imap, buf);
+ HANDLE_ERROR
+
+ /* ZYX -> YXZ: */
+ imap[1] = 1; imap[0] = counts[2]; imap[2] = counts[1]*counts[2];
+ startsT[0] = starts[1]; startsT[1] = starts[2]; startsT[2] = starts[0];
+ countsT[0] = counts[1]; countsT[1] = counts[2]; countsT[2] = counts[0];
+ /* write the transposed variable */
+ err = ncmpi_put_varm_int_all(ncid, YXZ_id, startsT, countsT, NULL, imap, buf);
+ HANDLE_ERROR
+
+ /* ZYX -> XZY: */
+ imap[0] = 1; imap[2] = counts[2]; imap[1] = counts[1]*counts[2];
+ startsT[0] = starts[2]; startsT[1] = starts[0]; startsT[2] = starts[1];
+ countsT[0] = counts[2]; countsT[1] = counts[0]; countsT[2] = counts[1];
+ /* write the transposed variable */
+ err = ncmpi_put_varm_int_all(ncid, XZY_id, startsT, countsT, NULL, imap, buf);
+ HANDLE_ERROR
+
+ /* ZYX -> XYZ: */
+ imap[0] = 1; imap[1] = counts[2]; imap[2] = counts[1]*counts[2];
+ startsT[0] = starts[2]; startsT[1] = starts[1]; startsT[2] = starts[0];
+ countsT[0] = counts[2]; countsT[1] = counts[1]; countsT[2] = counts[0];
+ /* write the transposed variable */
+ err = ncmpi_put_varm_int_all(ncid, XYZ_id, startsT, countsT, NULL, imap, buf);
+ HANDLE_ERROR
+
+ /* close the file */
+ err = ncmpi_close(ncid);
+ HANDLE_ERROR
+
+ free(buf);
+
+ MPI_Finalize();
+ return 0;
+}
+
diff --git a/examples/C/vard_int.c b/examples/C/vard_int.c
new file mode 100644
index 0000000..486e58c
--- /dev/null
+++ b/examples/C/vard_int.c
@@ -0,0 +1,192 @@
+/*********************************************************************
+ *
+ * Copyright (C) 2014, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ *
+ *********************************************************************/
+/* $Id: vard_int.c 2239 2015-12-18 18:21:09Z wkliao $ */
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * This example shows how to use the vard API ncmpi_put_vard() and
+ * ncmpi_get_vard() to write and read 2D record and fixed-size variables.
+ *
+ * To compile:
+ * mpicc -O2 vard_int.c -o vard_int -lpnetcdf
+ *
+ * Example commands for MPI run and outputs from running ncmpidump on the
+ * NC file produced by this example program:
+ *
+ * % mpiexec -n 4 ./vard_int /pvfs2/wkliao/testfile.nc
+ *
+ * The expected results from the output file contents are:
+ *
+ * % ncmpidump /pvfs2/wkliao/testfile.nc
+ * netcdf testfile {
+ * // file format: CDF-1
+ * dimensions:
+ * REC_DIM = UNLIMITED ; // (2 currently)
+ * X = 12 ;
+ * FIX_DIM = 2 ;
+ * variables:
+ * int rec_var(REC_DIM, X) ;
+ * int fix_var(FIX_DIM, X) ;
+ * data:
+ *
+ * rec_var =
+ * 0, 1, 2, 100, 101, 102, 200, 201, 202, 300, 301, 302,
+ * 10, 11, 12, 110, 111, 112, 210, 211, 212, 310, 311, 312 ;
+ *
+ * fix_var =
+ * 0, 1, 2, 100, 101, 102, 200, 201, 202, 300, 301, 302,
+ * 10, 11, 12, 110, 111, 112, 210, 211, 212, 310, 311, 312 ;
+ * }
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h> /* getopt() */
+#include <mpi.h>
+#include <pnetcdf.h>
+
+#define NY 2
+#define NX 3
+#define ERR if (err!=NC_NOERR) {printf("Error at line %d: %s\n", __LINE__,ncmpi_strerror(err));}
+
+static void
+usage(char *argv0)
+{
+ char *help =
+ "Usage: %s [-h] | [-q] [file_name]\n"
+ " [-h] Print help\n"
+ " [-q] Quiet mode (reports when fail)\n"
+ " [filename] output netCDF file name\n";
+ fprintf(stderr, help, argv0);
+}
+
+/*----< main() >------------------------------------------------------------*/
+int main(int argc, char **argv) {
+
+ extern int optind;
+ char filename[256];
+ int i, j, err, ncid, verbose=1, varid0, varid1, dimids[2];
+ int rank, nprocs, array_of_blocklengths[2], buf[NY][NX];
+ int array_of_sizes[2], array_of_subsizes[2], array_of_starts[2];
+ MPI_Offset start[2], count[2], recsize, bufcount, len;
+ MPI_Aint array_of_displacements[2];
+ MPI_Datatype buftype, rec_filetype, fix_filetype;
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+
+ /* get command-line arguments */
+ while ((i = getopt(argc, argv, "hq")) != EOF)
+ switch(i) {
+ case 'q': verbose = 0;
+ break;
+ case 'h':
+ default: if (rank==0) usage(argv[0]);
+ MPI_Finalize();
+ return 0;
+ }
+ argc -= optind;
+ argv += optind;
+ if (argc == 1) strcpy(filename, argv[0]); /* optional argument */
+ else strcpy(filename, "testfile.nc");
+
+ MPI_Bcast(filename, 256, MPI_CHAR, 0, MPI_COMM_WORLD);
+
+ if (verbose && rank == 0) printf("%s: example of using vard APIs\n",__FILE__);
+
+ start[0] = 0; start[1] = NX*rank;
+ count[0] = 2; count[1] = NX;
+
+ /* create a new file for write */
+ err = ncmpi_create(MPI_COMM_WORLD, filename, NC_CLOBBER, MPI_INFO_NULL,
+ &ncid); ERR
+
+ /* define a 2D array */
+ err = ncmpi_def_dim(ncid, "REC_DIM", NC_UNLIMITED, &dimids[0]); ERR
+ err = ncmpi_def_dim(ncid, "X", NX*nprocs, &dimids[1]); ERR
+ err = ncmpi_def_var(ncid, "rec_var", NC_INT, 2, dimids, &varid0); ERR
+ err = ncmpi_def_dim(ncid, "FIX_DIM", 2, &dimids[0]); ERR
+ err = ncmpi_def_var(ncid, "fix_var", NC_INT, 2, dimids, &varid1); ERR
+ err = ncmpi_enddef(ncid); ERR
+
+ /* create a file type for the record variable */
+ err = ncmpi_inq_recsize(ncid, &recsize);
+ for (i=0; i<count[0]; i++) {
+ array_of_blocklengths[i] = count[1];
+ array_of_displacements[i] = start[1]*sizeof(int) + recsize * i;
+ }
+ MPI_Type_create_hindexed(2, array_of_blocklengths, array_of_displacements,
+ MPI_INT, &rec_filetype);
+ MPI_Type_commit(&rec_filetype);
+
+ /* create a file type for the fixed-size variable */
+ array_of_sizes[0] = 2;
+ array_of_sizes[1] = NX*nprocs;
+ array_of_subsizes[0] = count[0];
+ array_of_subsizes[1] = count[1];
+ array_of_starts[0] = start[0];
+ array_of_starts[1] = start[1];
+ MPI_Type_create_subarray(2, array_of_sizes, array_of_subsizes,
+ array_of_starts, MPI_ORDER_C,
+ MPI_INT, &fix_filetype);
+ MPI_Type_commit(&fix_filetype);
+
+ buftype = MPI_INT;
+ bufcount = count[0] * count[1];
+
+ /* initialize the contents of the array */
+ for (j=0; j<NY; j++) for (i=0; i<NX; i++) buf[j][i] = rank*100 + j*10 + i;
+
+ /* write the record variable */
+ err = ncmpi_put_vard_all(ncid, varid0, rec_filetype, buf, bufcount,buftype);
+ ERR
+
+ /* check if the number of records changed to 2 */
+ err = ncmpi_inq_unlimdim(ncid, &dimids[0]); ERR
+ err = ncmpi_inq_dimlen(ncid, dimids[0], &len); ERR
+ if (len != 2)
+ printf("Error: number of records should be 2 but got %lld\n", len);
+
+ /* write the fixed-size variable */
+ err = ncmpi_put_vard_all(ncid, varid1, fix_filetype, buf, bufcount,buftype);
+ ERR
+
+ err = ncmpi_close(ncid); ERR
+
+ /* open the same file and read back for validate */
+ err = ncmpi_open(MPI_COMM_WORLD, filename, NC_NOWRITE, MPI_INFO_NULL,
+ &ncid); ERR
+
+ err = ncmpi_inq_varid(ncid, "rec_var", &varid0); ERR
+ err = ncmpi_inq_varid(ncid, "fix_var", &varid1); ERR
+
+ /* read back fixed-size variable */
+ err = ncmpi_get_vard_all(ncid, varid1, fix_filetype, buf, bufcount,buftype);
+ ERR
+
+ /* read back record variable */
+ err = ncmpi_get_vard_all(ncid, varid0, rec_filetype, buf, bufcount,buftype);
+ ERR
+
+ err = ncmpi_close(ncid); ERR
+ MPI_Type_free(&rec_filetype);
+ MPI_Type_free(&fix_filetype);
+
+ /* check if there is any PnetCDF internal malloc residue */
+ MPI_Offset malloc_size, sum_size;
+ err = ncmpi_inq_malloc_size(&malloc_size);
+ if (err == NC_NOERR) {
+ MPI_Reduce(&malloc_size, &sum_size, 1, MPI_OFFSET, MPI_SUM, 0, MPI_COMM_WORLD);
+ if (rank == 0 && sum_size > 0)
+ printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n",
+ sum_size);
+ }
+
+ MPI_Finalize();
+ return 0;
+}
diff --git a/examples/CXX/Makefile.in b/examples/CXX/Makefile.in
new file mode 100644
index 0000000..5f68a5d
--- /dev/null
+++ b/examples/CXX/Makefile.in
@@ -0,0 +1,130 @@
+#
+# Copyright (C) 2014, Northwestern University and Argonne National Laboratory
+# See COPYRIGHT notice in top-level directory.
+#
+# $Id: Makefile.in 2236 2015-12-18 03:49:41Z wkliao $
+#
+# @configure_input@
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+include ../../macros.make
+
+# note the order of -L list matters
+INCLUDES = -I../../src/lib -I../../src/libcxx
+LDFLAGS := -L../../src/lib $(LDFLAGS)
+LIBS := -lpnetcdf $(LIBS)
+
+C_SRCS = collective_write.cpp \
+ nonblocking_write.cpp \
+ column_wise.cpp \
+ block_cyclic.cpp \
+ flexible_api.cpp \
+ get_info.cpp \
+ hints.cpp \
+ put_varn_float.cpp \
+ put_varn_int.cpp \
+ put_vara.cpp \
+ get_vara.cpp \
+ transpose.cpp \
+ vard_int.cpp \
+ fill_mode.cpp
+
+PROGS = $(C_SRCS:.cpp=)
+OBJS = $(C_SRCS:.cpp=.o)
+
+PAR_PROGS = $(PROGS)
+
+GARBAGE = $(PROGS) *.nc
+
+PACKING_LIST = $(C_SRCS) depend Makefile.in
+
+all: $(PROGS)
+
+install:
+
+uninstall:
+
+collective_write: collective_write.o $(LIBRARY)
+ $(LINK.cxx) $< $(LDFLAGS) $(LIBS)
+
+nonblocking_write: nonblocking_write.o $(LIBRARY)
+ $(LINK.cxx) $< $(LDFLAGS) $(LIBS)
+
+get_info: get_info.o $(LIBRARY)
+ $(LINK.cxx) $< $(LDFLAGS) $(LIBS)
+
+column_wise: column_wise.o $(LIBRARY)
+ $(LINK.cxx) $< $(LDFLAGS) $(LIBS)
+
+block_cyclic: block_cyclic.o $(LIBRARY)
+ $(LINK.cxx) $< $(LDFLAGS) $(LIBS)
+
+put_vara: put_vara.o $(LIBRARY)
+ $(LINK.cxx) $< $(LDFLAGS) $(LIBS)
+
+hints: hints.o $(LIBRARY)
+ $(LINK.cxx) $< $(LDFLAGS) $(LIBS)
+
+flexible_api: flexible_api.o $(LIBRARY)
+ $(LINK.cxx) $< $(LDFLAGS) $(LIBS)
+
+put_varn_int: put_varn_int.o $(LIBRARY)
+ $(LINK.cxx) $< $(LDFLAGS) $(LIBS)
+
+put_varn_float: put_varn_float.o $(LIBRARY)
+ $(LINK.cxx) $< $(LDFLAGS) $(LIBS)
+
+get_vara: get_vara.o $(LIBRARY)
+ $(LINK.cxx) $< $(LDFLAGS) $(LIBS)
+
+transpose: transpose.o $(LIBRARY)
+ $(LINK.cxx) $< $(LDFLAGS) $(LIBS)
+
+vard_int: vard_int.o $(LIBRARY)
+ $(LINK.cxx) $< $(LDFLAGS) $(LIBS)
+
+fill_mode: fill_mode.o $(LIBRARY)
+ $(LINK.cxx) $< $(LDFLAGS) $(LIBS)
+
+TEST_MPIRUN_4 = $(subst NP,4,$(TEST_MPIRUN))
+TEST_MPIRUN_8 = $(subst NP,8,$(TEST_MPIRUN))
+TEST_MPIRUN_3 = $(subst NP,3,$(TEST_MPIRUN))
+
+ptest4: $(PAR_PROGS)
+ @for i in $(PAR_PROGS); do ( \
+ $(TEST_MPIRUN_4) ./$$i -q $(TEST_OUTDIR)/testfile.nc ; \
+ if [ $$? = 0 ] ; then \
+ echo "PASS: C++ parallel run on 4 processes --------------- $$i"; \
+ else \
+ echo "FAILED: C++ parallel run on 4 processes ------------- $$i"; \
+ fi ; ) ; done
+
+ptest8: $(PAR_PROGS)
+ @for i in $(PAR_PROGS) ; do ( \
+ $(TEST_MPIRUN_8) ./$$i -q $(TEST_OUTDIR)/testfile.nc ; \
+ if [ $$? = 0 ] ; then \
+ echo "PASS: C++ parallel run on 8 processes --------------- $$i"; \
+ else \
+ echo "FAILED: C++ parallel run on 8 processes ------------- $$i"; \
+ fi ; ) ; done
+
+ptest3: $(PAR_PROGS)
+ @for i in $(PAR_PROGS) ; do ( \
+ $(TEST_MPIRUN_3) ./$$i -q $(TEST_OUTDIR)/testfile.nc ; \
+ if [ $$? = 0 ] ; then \
+ echo "PASS: C++ parallel run on 3 processes --------------- $$i"; \
+ else \
+ echo "FAILED: C++ parallel run on 3 processes ------------- $$i"; \
+ fi ; ) ; done
+
+ptest: ptest4
+ptests: ptest3 ptest4 ptest8
+ptest2 ptest6 ptest10:
+
+include $(srcdir)/depend
+include $(srcdir)/../../rules.make
+
+$(LIBRARY): ;
+
diff --git a/examples/CXX/block_cyclic.cpp b/examples/CXX/block_cyclic.cpp
new file mode 100644
index 0000000..be3dc56
--- /dev/null
+++ b/examples/CXX/block_cyclic.cpp
@@ -0,0 +1,301 @@
+/*********************************************************************
+ *
+ * Copyright (C) 2014, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ *
+ *********************************************************************/
+/* $Id: block_cyclic.cpp 2245 2015-12-20 18:39:52Z wkliao $ */
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * This example, generalized from column_wise.cpp, makes a number of nonblocking
+ * API calls, each writes a block of columns into a 2D integer array. In other
+ * words, the I/O pattern is a blocked cyclic along X dimension.
+ *
+ * Each process writes NX columns in total. The block length is controlled by
+ * block_len. In this example, block_len is set to 2. Blocks are layout in a
+ * cyclic fashion in the file. This example can test if PnetCDF can coalesce
+ * file offsets and lengths when constructing a merged filetype.
+ *
+ * The compile and run commands are given below, together with an ncmpidump of
+ * the output file. In this example, block_len = 2.
+ *
+ * % mpicxx -O2 -o block_cyclic block_cyclic.cpp -lpnetcdf
+ * % mpiexec -l -n 4 ./block_cyclic /pvfs2/wkliao/testfile.nc
+ * 0: 0: NY=10 myNX= 4 myOff= 0
+ * 1: 1: NY=10 myNX= 4 myOff= 4
+ * 2: 2: NY=10 myNX= 4 myOff= 8
+ * 3: 3: NY=10 myNX= 4 myOff= 12
+ * 0: [i=0] iput() start= 0 0 count= 10 1
+ * 0: [i=1] iput() start= 0 1 count= 10 1
+ * 0: [i=2] iput() start= 0 8 count= 10 1
+ * 0: [i=3] iput() start= 0 9 count= 10 1
+ * 1: [i=0] iput() start= 0 2 count= 10 1
+ * 1: [i=1] iput() start= 0 3 count= 10 1
+ * 1: [i=2] iput() start= 0 10 count= 10 1
+ * 1: [i=3] iput() start= 0 11 count= 10 1
+ * 2: [i=0] iput() start= 0 4 count= 10 1
+ * 2: [i=1] iput() start= 0 5 count= 10 1
+ * 2: [i=2] iput() start= 0 12 count= 10 1
+ * 2: [i=3] iput() start= 0 13 count= 10 1
+ * 3: [i=0] iput() start= 0 6 count= 10 1
+ * 3: [i=1] iput() start= 0 7 count= 10 1
+ * 3: [i=2] iput() start= 0 14 count= 10 1
+ * 3: [i=3] iput() start= 0 15 count= 10 1
+ *
+ * % ncmpidump /pvfs2/wkliao/testfile.nc
+ * netcdf testfile {
+ * // file format: CDF-5 (big variables)
+ * dimensions:
+ * Y = 10 ;
+ * X = 16 ;
+ * variables:
+ * int var(Y, X) ;
+ * data:
+ *
+ * var =
+ * 10, 10, 11, 11, 12, 12, 13, 13, 10, 10, 11, 11, 12, 12, 13, 13,
+ * 10, 10, 11, 11, 12, 12, 13, 13, 10, 10, 11, 11, 12, 12, 13, 13,
+ * 10, 10, 11, 11, 12, 12, 13, 13, 10, 10, 11, 11, 12, 12, 13, 13,
+ * 10, 10, 11, 11, 12, 12, 13, 13, 10, 10, 11, 11, 12, 12, 13, 13,
+ * 10, 10, 11, 11, 12, 12, 13, 13, 10, 10, 11, 11, 12, 12, 13, 13,
+ * 10, 10, 11, 11, 12, 12, 13, 13, 10, 10, 11, 11, 12, 12, 13, 13,
+ * 10, 10, 11, 11, 12, 12, 13, 13, 10, 10, 11, 11, 12, 12, 13, 13,
+ * 10, 10, 11, 11, 12, 12, 13, 13, 10, 10, 11, 11, 12, 12, 13, 13,
+ * 10, 10, 11, 11, 12, 12, 13, 13, 10, 10, 11, 11, 12, 12, 13, 13,
+ * 10, 10, 11, 11, 12, 12, 13, 13, 10, 10, 11, 11, 12, 12, 13, 13 ;
+ * }
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <iostream>
+using namespace std;
+
+#include <string.h> /* strcpy() */
+#include <unistd.h> /* getopt() */
+#include <pnetcdf>
+
+using namespace PnetCDF;
+using namespace PnetCDF::exceptions;
+
+#define NY 10
+#define NX 4
+
+#define MIN(a,b) (((a)<(b))?(a):(b))
+
+static void
+usage(char *argv0)
+{
+ cerr <<
+ "Usage: %s [-h] | [-q] [file_name]\n"
+ " [-h] Print help\n"
+ " [-q] Quiet mode (reports when fail)\n"
+ " [filename] output netCDF file name\n"
+ << argv0;
+}
+
+int main(int argc, char** argv)
+{
+ extern int optind;
+ char filename[128];
+ int i, j, verbose=1, rank, nprocs, num_reqs;
+ int *reqs, *sts, **buf;
+ MPI_Offset myNX, G_NX, myOff, block_start, block_len;
+ vector<MPI_Offset> start(2), count(2);
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+
+ /* get command-line arguments */
+ while ((i = getopt(argc, argv, "hq")) != EOF)
+ switch(i) {
+ case 'q': verbose = 0;
+ break;
+ case 'h':
+ default: if (rank==0) usage(argv[0]);
+ MPI_Finalize();
+ return 0;
+ }
+ argc -= optind;
+ argv += optind;
+ if (argc == 1) strcpy(filename, argv[0]); /* optional argument */
+ else strcpy(filename, "testfile.nc");
+
+ try {
+ /* create a new file for writing ------------------------------------*/
+ NcmpiFile nc(MPI_COMM_WORLD, filename, NcmpiFile::replace,
+ NcmpiFile::classic5);
+
+ /* the global array is NY * (NX * nprocs) */
+ G_NX = NX * nprocs;
+ myOff = NX * rank;
+ myNX = NX;
+ if (verbose)
+ printf("%2d: NY=%d myNX=%3lld myOff=%3lld\n",rank,NY,myNX,myOff);
+
+ /* define dimensions x and y */
+ vector<NcmpiDim> dimid(2);
+
+ dimid[0] = nc.addDim("Y", NY);
+ dimid[1] = nc.addDim("X", G_NX);
+
+ /* define a 2D variable of integer type */
+ NcmpiVar var = nc.addVar("var", ncmpiInt, dimid);
+
+ /* First, fill the entire array with zeros, using a blocking I/O.
+ Every process writes a subarray of size NY * myNX */
+ buf = (int**) malloc(myNX * sizeof(int*));
+ buf[0] = (int*) calloc(NY * myNX, sizeof(int));
+ start[0] = 0; start[1] = myOff;
+ count[0] = NY; count[1] = myNX;
+
+ var.putVar_all(start, count, &buf[0][0]);
+
+ free(buf[0]);
+
+ /* initialize the buffer with rank ID. Also make the case interesting,
+ by allocating buffers separately */
+ for (i=0; i<myNX; i++) {
+ buf[i] = (int*) malloc(NY * sizeof(int));
+ for (j=0; j<NY; j++) buf[i][j] = rank+10;
+ }
+
+ reqs = (int*) malloc(myNX * sizeof(int));
+ sts = (int*) malloc(myNX * sizeof(int));
+
+ /* each proc writes myNX columns of the 2D array, block_len controls the
+ the number of contiguous columns at a time */
+ block_start = 0;
+ block_len = 2; /* can be 1, 2, 3, ..., myNX */
+ if (block_len > myNX) block_len = myNX;
+
+ start[0] = 0; start[1] = rank * block_len;
+ count[0] = NY; count[1] = 1;
+ num_reqs = 0;
+ for (i=0; i<myNX; i++) {
+ var.iputVar(start, count, &buf[i][0], &reqs[num_reqs++]);
+
+ if (verbose)
+ printf("[i=%d] iput() start=%3lld %3lld count=%3lld %3lld\n",
+ i, start[0],start[1], count[0],count[1]);
+
+ if (i % block_len == block_len-1) {
+ int stride = MIN(myNX-1-i, block_len);
+ block_start += block_len * nprocs;
+ start[1] = block_start + stride * rank;
+ }
+ else
+ start[1]++;
+ }
+
+ nc.Wait_all(num_reqs, reqs, sts);
+
+ /* check status of all requests */
+ for (i=0; i<num_reqs; i++)
+ if (sts[i] != NC_NOERR)
+ printf("Error: nonblocking write fails on request %d (%s)\n",
+ i, ncmpi_strerror(sts[i]));
+
+ free(sts);
+ free(reqs);
+ for (i=0; i<myNX; i++) free(buf[i]);
+ free(buf);
+
+ /* file is close implicitly */
+ }
+ catch(NcmpiException& e) {
+ cout << e.what() << " error code=" << e.errorCode() << " Error!\n";
+ return 1;
+ }
+
+ try {
+ /* open an existing file created earlier for read -------------------*/
+ NcmpiFile nc(MPI_COMM_WORLD, filename, NcmpiFile::read);
+
+ /* the global array is NY * (NX * nprocs) */
+ NcmpiDim dimY = nc.getDim("Y");
+ if (dimY.isNull() || dimY.getSize() != NY || dimY.isUnlimited())
+ throw NcmpiException("read Error: dimension Y ",__FILE__,__LINE__);
+
+ NcmpiDim dimX = nc.getDim("X");
+ if (dimX.isNull() || dimX.getSize() != G_NX || dimX.isUnlimited())
+ throw NcmpiException("read Error: dimension X ",__FILE__,__LINE__);
+
+ myNX = G_NX / nprocs;
+
+ NcmpiVar var = nc.getVar("var");
+
+ /* initialize the buffer with -1, so a read error can be pinpointed */
+ buf = (int**) malloc(myNX * sizeof(int*));
+ buf[0] = (int*) malloc(NY * myNX * sizeof(int));
+ for (i=0; i<myNX; i++) {
+ if (i > 0) buf[i] = buf[i-1] + NY;
+ for (j=0; j<NY; j++) buf[i][j] = -1;
+ }
+
+ reqs = (int*) malloc(myNX * sizeof(int));
+ sts = (int*) malloc(myNX * sizeof(int));
+
+ /* each proc reads myNX columns of the 2D array, block_len controls the
+ the number of contiguous columns at a time */
+ block_start = 0;
+ block_len = 2; /* can be 1, 2, 3, ..., myNX */
+ if (block_len > myNX) block_len = myNX;
+
+ start[0] = 0; start[1] = rank * block_len;
+ count[0] = NY; count[1] = 1;
+ num_reqs = 0;
+ for (i=0; i<myNX; i++) {
+ var.igetVar(start, count, &buf[i][0], &reqs[num_reqs++]);
+
+ if (i % block_len == block_len-1) {
+ int stride = MIN(myNX-1-i, block_len);
+ block_start += block_len * nprocs;
+ start[1] = block_start + stride * rank;
+ }
+ else
+ start[1]++;
+ }
+ nc.Wait_all(num_reqs, reqs, sts);
+
+ /* check status of all requests */
+ for (i=0; i<num_reqs; i++)
+ if (sts[i] != NC_NOERR)
+ printf("Error: nonblocking read fails on request %d (%s)\n",
+ i, ncmpi_strerror(sts[i]));
+
+ /* check the read contents */
+ for (i=0; i<myNX; i++) {
+ for (j=0; j<NY; j++)
+ if (buf[i][j] != rank+10) {
+ printf("Read contents mismatch at buf[%d][%d] = %d (should be %d)\n", i,j,buf[i][j],rank+10);
+ }
+ }
+
+ free(sts);
+ free(reqs);
+ free(buf[0]);
+ free(buf);
+
+ /* file is close implicitly */
+ }
+ catch(NcmpiException& e) {
+ cout << e.what() << " error code=" << e.errorCode() << " Error!\n";
+ }
+
+ /* check if there is any PnetCDF internal malloc residue */
+ MPI_Offset malloc_size, sum_size;
+ int err = ncmpi_inq_malloc_size(&malloc_size);
+ if (err == NC_NOERR) {
+ MPI_Reduce(&malloc_size, &sum_size, 1, MPI_OFFSET, MPI_SUM, 0, MPI_COMM_WORLD);
+ if (rank == 0 && sum_size > 0)
+ printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n",
+ sum_size);
+ }
+
+ MPI_Finalize();
+ return 0;
+}
+
diff --git a/examples/CXX/collective_write.cpp b/examples/CXX/collective_write.cpp
new file mode 100644
index 0000000..e2a7b9b
--- /dev/null
+++ b/examples/CXX/collective_write.cpp
@@ -0,0 +1,217 @@
+/*********************************************************************
+ *
+ * Copyright (C) 2014, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ *
+ *********************************************************************/
+/* $Id: collective_write.cpp 2245 2015-12-20 18:39:52Z wkliao $ */
+
+/*
+ * This example mimics the coll_perf.c from ROMIO.
+ * It creates a netcdf file in CD-5 format and writes a number of
+ * 3D integer non-record variables. The measured write bandwidth is reported
+ * at the end. Usage:
+ * To compile:
+ * mpiccxx -O2 collective_write.cpp -o collective_write -lpnetcdf
+ * To run:
+ * mpiexec -n num_processes ./collective_write [filename] [len]
+ * where len decides the size of each local array, which is len x len x len.
+ * So, each non-record variable is of size len*len*len * nprocs * sizeof(int)
+ * All variables are partitioned among all processes in a 3D
+ * block-block-block fashion. Below is an example standard output from
+ * command:
+ * mpiexec -n 32 ./collective_write /pvfs2/wkliao/testfile.nc 100
+ *
+ * MPI hint: cb_nodes = 2
+ * MPI hint: cb_buffer_size = 16777216
+ * MPI hint: striping_factor = 32
+ * MPI hint: striping_unit = 1048576
+ * Local array size 100 x 100 x 100 integers, size = 3.81 MB
+ * Global array size 400 x 400 x 200 integers, write size = 0.30 GB
+ * procs Global array size exec(sec) write(MB/s)
+ * ------- ------------------ --------- -----------
+ * 32 400 x 400 x 200 6.67 45.72
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <iostream>
+using namespace std;
+
+#include <string.h> /* strcpy() */
+#include <unistd.h> /* getopt() */
+#include <pnetcdf>
+
+using namespace PnetCDF;
+using namespace PnetCDF::exceptions;
+
+#define NDIMS 3
+#define NUM_VARS 10
+
+static void
+usage(char *argv0)
+{
+ cerr <<
+ "Usage: %s [-h] | [-q] [file_name] [len]\n"
+ " [-h] Print help\n"
+ " [-q] Quiet mode (reports when fail)\n"
+ " [filename] output netCDF file name\n"
+ " [len] size of each dimension of the local array\n"
+ << argv0;
+}
+
+/*----< print_info() >------------------------------------------------------*/
+static
+void print_info(MPI_Info *info_used)
+{
+ int flag;
+ char info_cb_nodes[64], info_cb_buffer_size[64];
+ char info_striping_factor[64], info_striping_unit[64];
+
+ strcpy(info_cb_nodes, "undefined");
+ strcpy(info_cb_buffer_size, "undefined");
+ strcpy(info_striping_factor, "undefined");
+ strcpy(info_striping_unit, "undefined");
+
+ MPI_Info_get(*info_used, (char*)"cb_nodes", 64, info_cb_nodes, &flag);
+ MPI_Info_get(*info_used, (char*)"cb_buffer_size", 64, &info_cb_buffer_size[0], &flag);
+ MPI_Info_get(*info_used, (char*)"striping_factor", 64, &info_striping_factor[0], &flag);
+ MPI_Info_get(*info_used, (char*)"striping_unit", 64, info_striping_unit, &flag);
+
+ printf("MPI hint: cb_nodes = %s\n", info_cb_nodes);
+ printf("MPI hint: cb_buffer_size = %s\n", info_cb_buffer_size);
+ printf("MPI hint: striping_factor = %s\n", info_striping_factor);
+ printf("MPI hint: striping_unit = %s\n", info_striping_unit);
+}
+
+/*----< main() >------------------------------------------------------------*/
+int main(int argc, char **argv)
+{
+ extern int optind;
+ char filename[128], str[512];
+ int i, j, rank, nprocs, len, bufsize, verbose=1;
+ int *buf[NUM_VARS], psizes[NDIMS];
+ double write_timing, max_write_timing, write_bw;
+ vector<MPI_Offset> starts(NDIMS), counts(NDIMS);
+ MPI_Offset gsizes[NDIMS];
+ MPI_Offset write_size, sum_write_size;
+ MPI_Info info_used;
+
+ MPI_Init(&argc,&argv);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+
+ /* get command-line arguments */
+ while ((i = getopt(argc, argv, "hq")) != EOF)
+ switch(i) {
+ case 'q': verbose = 0;
+ break;
+ case 'h':
+ default: if (rank==0) usage(argv[0]);
+ MPI_Finalize();
+ return 0;
+ }
+ argc -= optind;
+ argv += optind;
+ if (argc >= 1) strcpy(filename, argv[0]); /* optional argument */
+ else strcpy(filename, "testfile.nc");
+ len = 10;
+ if (argc >= 2) len = atoi(argv[1]); /* optional argument */
+
+ for (i=0; i<NDIMS; i++)
+ psizes[i] = 0;
+
+ MPI_Dims_create(nprocs, NDIMS, psizes);
+ starts[0] = rank % psizes[0];
+ starts[1] = (rank / psizes[1]) % psizes[1];
+ starts[2] = (rank / (psizes[0] * psizes[1])) % psizes[2];
+
+ bufsize = 1;
+ for (i=0; i<NDIMS; i++) {
+ gsizes[i] = len * psizes[i];
+ starts[i] *= len;
+ counts[i] = len;
+ bufsize *= len;
+ }
+
+ /* allocate buffer and initialize with random numbers */
+ srand(rank);
+ for (i=0; i<NUM_VARS; i++) {
+ buf[i] = (int *) malloc(bufsize * sizeof(int));
+ for (j=0; j<bufsize; j++) buf[i][j] = rand();
+ }
+
+ MPI_Barrier(MPI_COMM_WORLD);
+ write_timing = MPI_Wtime();
+
+ try {
+ /* create the file */
+ NcmpiFile nc(MPI_COMM_WORLD, filename, NcmpiFile::replace,
+ NcmpiFile::classic5);
+
+ /* define dimensions */
+ vector<NcmpiDim> dimids(NDIMS);
+ for (i=0; i<NDIMS; i++) {
+ sprintf(str, "%c", 'x'+i);
+ dimids[i] = nc.addDim(str, gsizes[i]);
+ }
+
+ /* define variables */
+ vector<NcmpiVar> vars(NUM_VARS);
+ for (i=0; i<NUM_VARS; i++) {
+ sprintf(str, "var%d", i);
+ vars[i] = nc.addVar(str, ncmpiInt, dimids);
+ }
+
+ /* get all the hints used */
+ nc.Inq_file_info(&info_used);
+
+ /* write one variable at a time */
+ for (i=0; i<NUM_VARS; i++)
+ vars[i].putVar_all(starts, counts, &buf[i][0]);
+ }
+ catch(NcmpiException& e) {
+ cout << e.what() << " error code=" << e.errorCode() << " Error!\n";
+ return 1;
+ }
+
+ write_timing = MPI_Wtime() - write_timing;
+
+ write_size = bufsize * NUM_VARS * sizeof(int);
+ for (i=0; i<NUM_VARS; i++) free(buf[i]);
+
+ MPI_Reduce(&write_size, &sum_write_size, 1, MPI_LONG_LONG, MPI_SUM, 0, MPI_COMM_WORLD);
+ MPI_Reduce(&write_timing, &max_write_timing, 1, MPI_DOUBLE, MPI_MAX, 0, MPI_COMM_WORLD);
+
+ if (rank == 0 && verbose) {
+ double write_amount = sum_write_size;
+ float subarray_size = (float)bufsize*sizeof(int)/1048576.0;
+ print_info(&info_used);
+ printf("Local array size %d x %d x %d integers, size = %.2f MB\n",len,len,len,subarray_size);
+ write_amount /= 1048576.0;
+ printf("Global array size %lld x %lld x %lld integers, write size = %.2f GB\n",
+ gsizes[0], gsizes[1], gsizes[2], write_amount/1024.0);
+
+ write_bw = write_amount/max_write_timing;
+ printf(" procs Global array size exec(sec) write(MB/s)\n");
+ printf("------- ------------------ --------- -----------\n");
+ printf(" %4d %4lld x %4lld x %4lld %8.2f %10.2f\n", nprocs,
+ gsizes[0], gsizes[1], gsizes[2], max_write_timing, write_bw);
+ }
+ MPI_Info_free(&info_used);
+
+ /* check if there is any PnetCDF internal malloc residue */
+ MPI_Offset malloc_size, sum_size;
+ int err = ncmpi_inq_malloc_size(&malloc_size);
+ if (err == NC_NOERR) {
+ MPI_Reduce(&malloc_size, &sum_size, 1, MPI_OFFSET, MPI_SUM, 0, MPI_COMM_WORLD);
+ if (rank == 0 && sum_size > 0)
+ printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n",
+ sum_size);
+ }
+
+ MPI_Finalize();
+ return 0;
+}
+
diff --git a/examples/CXX/column_wise.cpp b/examples/CXX/column_wise.cpp
new file mode 100644
index 0000000..f0a05f5
--- /dev/null
+++ b/examples/CXX/column_wise.cpp
@@ -0,0 +1,200 @@
+/*********************************************************************
+ *
+ * Copyright (C) 2014, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ *
+ *********************************************************************/
+/* $Id: column_wise.cpp 2245 2015-12-20 18:39:52Z wkliao $ */
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * This example makes a number of nonblocking API calls, each writes a single
+ * column of a 2D integer array. Each process writes NX columns and any two
+ * consecutive columns are of nprocs columns distance apart from each other.
+ * In this case, the fileview of each process interleaves with all other
+ * processes.
+ * If simply concatenating fileviews of all the nonblocking calls will result
+ * in a fileview that violates the MPI-IO requirement on the fileview of which
+ * flattened file offsets must be monotonically non-decreasing. PnetCDF handles
+ * this case by breaking down each nonblocking call into a list of offset-length
+ * pairs, merging the pairs across multiple nonblocking calls, and sorting
+ * them into an increasing order. The sorted pairs are used to construct a
+ * fileview that meets the monotonically non-decreasing offset requirement,
+ * and thus the nonblocking requests can be serviced by a single MPI-IO call.
+ *
+ * The compile and run commands are given below, together with an ncmpidump of
+ * the output file.
+ *
+ * % mpicxx -O2 -o column_wise column_wise.cpp -lpnetcdf
+ * % mpiexec -l -n 4 ./column_wise /pvfs2/wkliao/testfile.nc
+ * 0: 0: myOff= 0 myNX= 4
+ * 1: 1: myOff= 4 myNX= 4
+ * 2: 2: myOff= 8 myNX= 4
+ * 3: 3: myOff= 12 myNX= 4
+ * 0: 0: start= 0 0 count= 10 1
+ * 1: 1: start= 0 1 count= 10 1
+ * 2: 2: start= 0 2 count= 10 1
+ * 3: 3: start= 0 3 count= 10 1
+ *
+ * % ncmpidump /pvfs2/wkliao/testfile.nc
+ * netcdf testfile {
+ * // file format: CDF-5 (big variables)
+ * dimensions:
+ * Y = 10 ;
+ * X = 16 ;
+ * variables:
+ * int var(Y, X) ;
+ * data:
+ *
+ * var =
+ * 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3,
+ * 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3,
+ * 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3,
+ * 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3,
+ * 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3,
+ * 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3,
+ * 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3,
+ * 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3,
+ * 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3,
+ * 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3 ;
+ * }
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <iostream>
+using namespace std;
+
+#include <string.h> /* strcpy() */
+#include <unistd.h> /* getopt() */
+#include <pnetcdf>
+
+using namespace PnetCDF;
+using namespace PnetCDF::exceptions;
+
+#define NY 10
+#define NX 4
+
+static void
+usage(char *argv0)
+{
+ cerr <<
+ "Usage: %s [-h] | [-q] [file_name]\n"
+ " [-h] Print help\n"
+ " [-q] Quiet mode (reports when fail)\n"
+ " [filename] output netCDF file name\n"
+ << argv0;
+}
+
+int main(int argc, char** argv)
+{
+ extern int optind;
+ char filename[128];
+ int i, j, verbose=1, rank, nprocs, myNX, G_NX, myOff, num_reqs;
+ int *reqs, *sts, **buf;
+ vector<MPI_Offset> start(2), count(2);
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+
+ /* get command-line arguments */
+ while ((i = getopt(argc, argv, "hq")) != EOF)
+ switch(i) {
+ case 'q': verbose = 0;
+ break;
+ case 'h':
+ default: if (rank==0) usage(argv[0]);
+ MPI_Finalize();
+ return 0;
+ }
+ argc -= optind;
+ argv += optind;
+ if (argc == 1) strcpy(filename, argv[0]); /* optional argument */
+ else strcpy(filename, "testfile.nc");
+
+ try {
+ NcmpiFile nc(MPI_COMM_WORLD, filename, NcmpiFile::replace,
+ NcmpiFile::classic5);
+
+ /* the global array is NY * (NX * nprocs) */
+ G_NX = NX * nprocs;
+ myOff = NX * rank;
+ myNX = NX;
+ if (verbose) printf("%2d: myOff=%3d myNX=%3d\n",rank,myOff,myNX);
+
+ /* define dimensions Y and X */
+ vector<NcmpiDim> dimid(2);
+
+ dimid[0] = nc.addDim("Y", NY);
+ dimid[1] = nc.addDim("X", G_NX);
+
+ /* define a 2D variable of integer type */
+ NcmpiVar var = nc.addVar("var", ncmpiInt, dimid);
+
+ /* First, fill the entire array with zeros, using a blocking I/O.
+ Every process writes a subarray of size NY * myNX */
+ buf = (int**) malloc(myNX * sizeof(int*));
+ buf[0] = (int*) calloc(NY * myNX, sizeof(int));
+ start[0] = 0; start[1] = myOff;
+ count[0] = NY; count[1] = myNX;
+
+ var.putVar_all(start, count, &buf[0][0]);
+
+ free(buf[0]);
+
+ /* initialize the buffer with rank ID. Also make the case interesting,
+ by allocating buffers separately */
+ for (i=0; i<myNX; i++) {
+ buf[i] = (int*) malloc(NY * sizeof(int));
+ for (j=0; j<NY; j++) buf[i][j] = rank;
+ }
+
+ reqs = (int*) malloc(myNX * sizeof(int));
+ sts = (int*) malloc(myNX * sizeof(int));
+
+ /* each proc writes myNX single columns of the 2D array */
+ start[0] = 0; start[1] = rank;
+ count[0] = NY; count[1] = 1;
+ if (verbose)
+ printf("%2d: start=%3lld %3lld count=%3lld %3lld\n",
+ rank, start[0],start[1], count[0],count[1]);
+
+ num_reqs = 0;
+ for (i=0; i<myNX; i++) {
+ var.iputVar(start, count, &buf[0][0], &reqs[num_reqs++]);
+ start[1] += nprocs;
+ }
+ nc.Wait_all(num_reqs, reqs, sts);
+
+ /* check status of all requests */
+ for (i=0; i<num_reqs; i++)
+ if (sts[i] != NC_NOERR)
+ printf("Error: nonblocking write fails on request %d (%s)\n",
+ i, ncmpi_strerror(sts[i]));
+
+ free(sts);
+ free(reqs);
+ for (i=0; i<myNX; i++) free(buf[i]);
+ free(buf);
+
+ /* file is close implicitly */
+ }
+ catch(NcmpiException& e) {
+ cout << e.what() << " error code=" << e.errorCode() << " Error!\n";
+ }
+
+ /* check if there is any PnetCDF internal malloc residue */
+ MPI_Offset malloc_size, sum_size;
+ int err = ncmpi_inq_malloc_size(&malloc_size);
+ if (err == NC_NOERR) {
+ MPI_Reduce(&malloc_size, &sum_size, 1, MPI_OFFSET, MPI_SUM, 0, MPI_COMM_WORLD);
+ if (rank == 0 && sum_size > 0)
+ printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n",
+ sum_size);
+ }
+
+ MPI_Finalize();
+ return 0;
+}
+
diff --git a/examples/CXX/depend b/examples/CXX/depend
new file mode 100644
index 0000000..cfd6d2b
--- /dev/null
+++ b/examples/CXX/depend
@@ -0,0 +1,14 @@
+collective_write.o: collective_write.cpp
+nonblocking_write.o: nonblocking_write.cpp
+column_wise.o: column_wise.cpp
+block_cyclic.o: block_cyclic.cpp
+flexible_api.o: flexible_api.cpp
+get_info.o: get_info.cpp
+hints.o: hints.cpp
+put_vara.o: put_vara.cpp
+get_vara.o: get_vara.cpp
+put_varn_float.o: put_varn_float.cpp
+put_varn_int.o: put_varn_int.cpp
+transpose.o: transpose.cpp
+vard_int.o: vard_int.cpp
+fill_mode.o: fill_mode.cpp
diff --git a/examples/CXX/fill_mode.cpp b/examples/CXX/fill_mode.cpp
new file mode 100644
index 0000000..24dd0cd
--- /dev/null
+++ b/examples/CXX/fill_mode.cpp
@@ -0,0 +1,213 @@
+/*********************************************************************
+ *
+ * Copyright (C) 2015, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ *
+ *********************************************************************/
+/* $Id: fill_mode.cpp 2012 2015-02-16 05:52:44Z wkliao $ */
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * This example shows how to use
+ * 1. NcmpiVar::setFill() to define the variable's fill value
+ * 2. NcmpiVar::getFillModeParameters() to inquire the variable's fill mode
+ * information
+ * 3. NcmpiVar::fillVar() to write two 2D 4-byte integer array in parallel.
+ * It first defines a netCDF record variable of size NC_UNLIMITED * global_ny
+ * where
+ * global_nx == (NX * number of MPI processes).
+ * It then defines a netCDF fixed-size variable of size global_nx * global_ny
+ * where
+ * global_ny == NY and
+ * global_nx == (NX * number of MPI processes).
+ *
+ * To compile:
+ * mpicxx -O2 fill_mode.cpp -o fill_mode -lpnetcdf
+ *
+ * Example commands for MPI run and outputs from running ncmpidump on the
+ * NC file produced by this example program:
+ *
+ * % mpiexec -n 4 ./fill_mode /pvfs2/wkliao/testfile.nc
+ *
+ * % ncmpidump /pvfs2/wkliao/testfile.nc
+ * netcdf testfile {
+ * // file format: CDF-5 (big variables)
+ * dimensions:
+ * REC_DIM = UNLIMITED ; // (2 currently)
+ * X = 16 ;
+ * Y = 3 ;
+ * variables:
+ * int rec_var(REC_DIM, X) ;
+ * rec_var:_FillValue = -1 ;
+ * int fix_var(Y, X) ;
+ *
+ * // global attributes:
+ * :history = "Thu Feb 12 01:28:34 2015\n",
+ * "" ;
+ * data:
+ *
+ * rec_var =
+ * 0, 0, 0, _, 1, 1, 1, _, 2, 2, 2, _, 3, 3, 3, _,
+ * 0, 0, 0, _, 1, 1, 1, _, 2, 2, 2, _, 3, 3, 3, _ ;
+ *
+ * fix_var =
+ * 0, 0, 0, _, 1, 1, 1, _, 2, 2, 2, _, 3, 3, 3, _,
+ * 0, 0, 0, _, 1, 1, 1, _, 2, 2, 2, _, 3, 3, 3, _,
+ * 0, 0, 0, _, 1, 1, 1, _, 2, 2, 2, _, 3, 3, 3, _ ;
+ * }
+ *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <iostream>
+using namespace std;
+
+#include <string.h> /* strcpy() */
+#include <unistd.h> /* getopt() */
+#include <time.h> /* time() localtime(), asctime() */
+
+#include <pnetcdf>
+
+using namespace PnetCDF;
+using namespace PnetCDF::exceptions;
+
+#define NY 3
+#define NX 4
+
+static void
+usage(char *argv0)
+{
+ cerr <<
+ "Usage: %s [-h] | [-q] [file_name]\n"
+ " [-h] Print help\n"
+ " [-q] Quiet mode (reports when fail)\n"
+ " [filename] output netCDF file name\n"
+ << argv0;
+}
+
+int main(int argc, char** argv)
+{
+ extern int optind;
+ char filename[128], str_att[128];
+ int i, j, verbose=1, rank, nprocs, buf[NY][NX];
+ MPI_Offset global_ny, global_nx;
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+
+ /* get command-line arguments */
+ while ((i = getopt(argc, argv, "hq")) != EOF)
+ switch(i) {
+ case 'q': verbose = 0;
+ break;
+ case 'h':
+ default: if (rank==0) usage(argv[0]);
+ MPI_Finalize();
+ return 0;
+ }
+ argc -= optind;
+ argv += optind;
+ if (argc == 1) strcpy(filename, argv[0]); /* optional argument */
+ else strcpy(filename, "testfile.nc");
+
+ try {
+ /* create a new file for writing ------------------------------------*/
+ NcmpiFile ncFile(MPI_COMM_WORLD, filename, NcmpiFile::replace,
+ NcmpiFile::classic5);
+
+ /* the global array is NY * (NX * nprocs) */
+ global_ny = NY;
+ global_nx = NX * nprocs;
+
+ for (i=0; i<NY; i++)
+ for (j=0; j<NX; j++)
+ buf[i][j] = rank;
+
+ /* add a global attribute: a time stamp at rank 0 */
+ time_t ltime = time(NULL); /* get the current calendar time */
+ asctime_r(localtime(<ime), str_att);
+
+ /* make sure the time string are consistent among all processes */
+ MPI_Bcast(str_att, 128, MPI_CHAR, 0, MPI_COMM_WORLD);
+
+ ncFile.putAtt(string("history"), string(str_att));
+
+ /* define dimensions Y and X */
+ vector<NcmpiDim> dimid(2);
+
+ dimid[0] = ncFile.addDim("REC_DIM", NC_UNLIMITED);
+ dimid[1] = ncFile.addDim("X", global_nx);
+
+ /* define a 2D record variable of integer type */
+ NcmpiVar rec_var = ncFile.addVar("rec_var", ncmpiInt, dimid);
+
+ dimid[0] = ncFile.addDim("Y", global_ny);
+
+ /* define a 2D fixed-size variable of integer type */
+ NcmpiVar fix_var = ncFile.addVar("fix_var", ncmpiInt, dimid);
+
+ /* set the variable's fill mode to NC_FILL with default fill value */
+ fix_var.setFill(true);
+
+ /* set a customized fill value -1 */
+ int fill_value = -1;
+ rec_var.setFill(true, &fill_value);
+
+ /* now we are in data mode */
+ vector<MPI_Offset> start(2), count(2);
+ start[0] = 0;
+ start[1] = NX * rank;
+ count[0] = NY;
+ count[1] = NX;
+ if (verbose)
+ printf("%d: start=%lld %lld count=%lld %lld\n",rank,
+ start[0],start[1],count[0],count[1]);
+
+ /* do not write the variable in full */
+ count[1]--;
+ fix_var.putVar_all(start, count, &buf[0][0]);
+
+ bool fillMode=true;
+ fix_var.getFillModeParameters(fillMode, &fill_value);
+ if (!fillMode)
+ printf("Error: expecting fillMode to be false\n");
+ if (fill_value != NC_FILL_INT)
+ printf("Error: expecting fillMode to be %ld but got %d\n",NC_FILL_INT,fill_value);
+
+ /* fill the 1st record of the record variable */
+ start[0] = 0;
+ rec_var.fillRec(start[0]);
+
+ /* write to the 1st record */
+ count[0] = 1;
+ rec_var.putVar_all(start, count, &buf[0][0]);
+
+ /* fill the 2nd record of the record variable */
+ start[0] = 1;
+ rec_var.fillRec(start[0]);
+
+ /* write to the 2nd record */
+ rec_var.putVar_all(start, count, &buf[0][0]);
+
+ /* file is close implicitly */
+ }
+ catch(NcmpiException& e) {
+ cout << e.what() << " error code=" << e.errorCode() << " Error!\n";
+ }
+
+ /* check if there is any PnetCDF internal malloc residue */
+ MPI_Offset malloc_size, sum_size;
+ int err = ncmpi_inq_malloc_size(&malloc_size);
+ if (err == NC_NOERR) {
+ MPI_Reduce(&malloc_size, &sum_size, 1, MPI_OFFSET, MPI_SUM, 0, MPI_COMM_WORLD);
+ if (rank == 0 && sum_size > 0)
+ printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n",
+ sum_size);
+ }
+
+ MPI_Finalize();
+ return 0;
+}
+
diff --git a/examples/CXX/flexible_api.cpp b/examples/CXX/flexible_api.cpp
new file mode 100644
index 0000000..12c4987
--- /dev/null
+++ b/examples/CXX/flexible_api.cpp
@@ -0,0 +1,228 @@
+/*********************************************************************
+ *
+ * Copyright (C) 2014, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ *
+ *********************************************************************/
+/* $Id: flexible_api.cpp 2245 2015-12-20 18:39:52Z wkliao $ */
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ *
+ * This example shows how to use PnetCDF flexible APIs, NcmpiVar::putVar_all()
+ * to write two 2D array variables (one is of 4-byte integer byte and the
+ * other float type) in parallel. It first defines 2 netCDF variables of sizes
+ * var_zy: NZ*nprocs x NY
+ * var_yx: NY x NX*nprocs
+ *
+ * The data partitioning patterns on the 2 variables are row-wise and
+ * column-wise, respectively. Each process writes a subarray of size
+ * NZ x NY and NY x NX to var_zy and var_yx, respectively.
+ * Both local buffers have a ghost cell of length 3 surrounded along each
+ * dimension.
+ *
+ * The compile and run commands are given below.
+ *
+ * % mpicxx -O2 -o flexible_api flexible_api.cpp -lpnetcdf
+ *
+ * % mpiexec -l -n 4 ./flexible_api /pvfs2/wkliao/testfile.nc
+ *
+ * % ncmpidump /pvfs2/wkliao/testfile.nc
+ * netcdf testfile {
+ * // file format: CDF-5 (big variables)
+ * dimensions:
+ * Z = 20 ;
+ * Y = 5 ;
+ * X = 20 ;
+ * variables:
+ * int var_zy(Z, Y) ;
+ * float var_yx(Y, X) ;
+ * data:
+ *
+ * var_zy =
+ * 0, 0, 0, 0, 0,
+ * 0, 0, 0, 0, 0,
+ * 0, 0, 0, 0, 0,
+ * 0, 0, 0, 0, 0,
+ * 0, 0, 0, 0, 0,
+ * 1, 1, 1, 1, 1,
+ * 1, 1, 1, 1, 1,
+ * 1, 1, 1, 1, 1,
+ * 1, 1, 1, 1, 1,
+ * 1, 1, 1, 1, 1,
+ * 2, 2, 2, 2, 2,
+ * 2, 2, 2, 2, 2,
+ * 2, 2, 2, 2, 2,
+ * 2, 2, 2, 2, 2,
+ * 2, 2, 2, 2, 2,
+ * 3, 3, 3, 3, 3,
+ * 3, 3, 3, 3, 3,
+ * 3, 3, 3, 3, 3,
+ * 3, 3, 3, 3, 3,
+ * 3, 3, 3, 3, 3 ;
+ *
+ * var_yx =
+ * 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3,
+ * 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3,
+ * 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3,
+ * 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3,
+ * 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3 ;
+ * }
+ *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <iostream>
+using namespace std;
+
+#include <string.h> /* strcpy() */
+#include <unistd.h> /* getopt() */
+#include <pnetcdf>
+
+using namespace PnetCDF;
+using namespace PnetCDF::exceptions;
+
+#define NZ 5
+#define NY 5
+#define NX 5
+
+static void
+usage(char *argv0)
+{
+ cerr <<
+ "Usage: %s [-h] | [-q] [file_name]\n"
+ " [-h] Print help\n"
+ " [-q] Quiet mode (reports when fail)\n"
+ " [filename] output netCDF file name\n"
+ << argv0;
+}
+
+int main(int argc, char** argv)
+{
+ extern int optind;
+ char filename[128];
+ int i, rank, nprocs, verbose=1, ghost_len=3;
+ int *buf_zy;
+ float *buf_yx;
+ MPI_Datatype subarray;
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+
+ /* get command-line arguments */
+ while ((i = getopt(argc, argv, "hq")) != EOF)
+ switch(i) {
+ case 'q': verbose = 0;
+ break;
+ case 'h':
+ default: if (rank==0) usage(argv[0]);
+ MPI_Finalize();
+ return 0;
+ }
+ argc -= optind;
+ argv += optind;
+ if (argc == 1) strcpy(filename, argv[0]); /* optional argument */
+ else strcpy(filename, "testfile.nc");
+
+ try {
+ /* create a new file for writing ------------------------------------*/
+ NcmpiFile nc(MPI_COMM_WORLD, filename, NcmpiFile::replace,
+ NcmpiFile::classic5);
+
+ /* define 3 dimensions */
+ vector<NcmpiDim> dimid(3);
+ dimid[0] = nc.addDim("Z", NZ*nprocs);
+ dimid[1] = nc.addDim("Y", NY);
+ dimid[2] = nc.addDim("X", NX*nprocs);
+
+ vector<NcmpiDim> dimid0(2), dimid1(2);
+ dimid0[0] = dimid[0];
+ dimid0[1] = dimid1[0] = dimid[1];
+ dimid1[1] = dimid[2];
+
+ /* define a variable of size (NZ * nprocs) * NY */
+ NcmpiVar var0 = nc.addVar("var_zy", ncmpiInt, dimid0);
+
+ /* define a variable of size NY * (NX * nprocs) */
+ NcmpiVar var1 = nc.addVar("var_yx", ncmpiFloat, dimid1);
+
+ /* var_zy is partitioned along Z dimension */
+ int array_of_sizes[2], array_of_subsizes[2], array_of_starts[2];
+ array_of_sizes[0] = NZ + 2*ghost_len;
+ array_of_sizes[1] = NY + 2*ghost_len;
+ array_of_subsizes[0] = NZ;
+ array_of_subsizes[1] = NY;
+ array_of_starts[0] = ghost_len;
+ array_of_starts[1] = ghost_len;
+ MPI_Type_create_subarray(2, array_of_sizes, array_of_subsizes,
+ array_of_starts, MPI_ORDER_C, MPI_INT,
+ &subarray);
+ MPI_Type_commit(&subarray);
+
+ /* allocate buffer buf_zy and initialize its contents */
+ int buffer_len = (NZ+2*ghost_len) * (NY+2*ghost_len);
+ buf_zy = (int*) malloc(buffer_len * sizeof(int));
+ for (i=0; i<buffer_len; i++) buf_zy[i] = rank;
+
+ vector <MPI_Offset> start(2), count(2);
+ start[0] = NZ * rank; start[1] = 0;
+ count[0] = NZ; count[1] = NY;
+ if (verbose)
+ printf("%d: start=%lld %lld count=%lld %lld\n",rank,
+ start[0],start[1],count[0],count[1]);
+
+ /* calling a blocking flexible API */
+ var0.putVar_all(start, count, &buf_zy[0], 1, subarray);
+ free(buf_zy);
+ MPI_Type_free(&subarray);
+
+ /* var_yx is partitioned along X dimension */
+ array_of_sizes[0] = NY + 2*ghost_len;
+ array_of_sizes[1] = NX + 2*ghost_len;
+ array_of_subsizes[0] = NY;
+ array_of_subsizes[1] = NX;
+ array_of_starts[0] = ghost_len;
+ array_of_starts[1] = ghost_len;
+ MPI_Type_create_subarray(2, array_of_sizes, array_of_subsizes,
+ array_of_starts, MPI_ORDER_C, MPI_FLOAT,
+ &subarray);
+ MPI_Type_commit(&subarray);
+
+ /* allocate buffer buf_yx and initialize its contents */
+ buffer_len = (NY+2*ghost_len) * (NX+2*ghost_len);
+ buf_yx = (float*) malloc(buffer_len * sizeof(float));
+ for (i=0; i<buffer_len; i++) buf_yx[i] = rank;
+
+ start[0] = 0; start[1] = NX * rank;
+ count[0] = NY; count[1] = NX;
+ if (verbose)
+ printf("%d: start=%lld %lld count=%lld %lld\n",rank,
+ start[0],start[1],count[0],count[1]);
+
+ /* calling a non-blocking flexible API */
+ var1.putVar_all(start, count, buf_yx, 1, subarray);
+ free(buf_yx);
+ MPI_Type_free(&subarray);
+
+ /* file is close implicitly */
+ }
+ catch(NcmpiException& e) {
+ cout << e.what() << " error code=" << e.errorCode() << " Error!\n";
+ }
+
+ /* check if there is any PnetCDF internal malloc residue */
+ MPI_Offset malloc_size, sum_size;
+ int err = ncmpi_inq_malloc_size(&malloc_size);
+ if (err == NC_NOERR) {
+ MPI_Reduce(&malloc_size, &sum_size, 1, MPI_OFFSET, MPI_SUM, 0, MPI_COMM_WORLD);
+ if (rank == 0 && sum_size > 0)
+ printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n",
+ sum_size);
+ }
+
+ MPI_Finalize();
+ return 0;
+}
+
diff --git a/examples/CXX/get_info.cpp b/examples/CXX/get_info.cpp
new file mode 100644
index 0000000..4e96427
--- /dev/null
+++ b/examples/CXX/get_info.cpp
@@ -0,0 +1,137 @@
+/*********************************************************************
+ *
+ * Copyright (C) 2014, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ *
+ *********************************************************************/
+/* $Id: get_info.cpp 1839 2014-10-30 20:22:37Z wkliao $ */
+
+/*
+ * prints all MPI-IO hints used
+ * To compile:
+ * mpicxx -O2 get_info.c -o get_info -lpnetcdf
+ * To run:
+ * mpiexec -n 4 ./get_info [filename]
+ *
+ * Example standard output:
+
+ MPI File Info: nkeys = 18
+ MPI File Info: [ 0] key = cb_buffer_size, value = 16777216
+ MPI File Info: [ 1] key = romio_cb_read, value = automatic
+ MPI File Info: [ 2] key = romio_cb_write, value = automatic
+ MPI File Info: [ 3] key = cb_nodes, value = 1
+ MPI File Info: [ 4] key = romio_no_indep_rw, value = false
+ MPI File Info: [ 5] key = romio_cb_pfr, value = disable
+ MPI File Info: [ 6] key = romio_cb_fr_types, value = aar
+ MPI File Info: [ 7] key = romio_cb_fr_alignment, value = 1
+ MPI File Info: [ 8] key = romio_cb_ds_threshold, value = 0
+ MPI File Info: [ 9] key = romio_cb_alltoall, value = automatic
+ MPI File Info: [10] key = ind_rd_buffer_size, value = 4194304
+ MPI File Info: [11] key = ind_wr_buffer_size, value = 524288
+ MPI File Info: [12] key = romio_ds_read, value = automatic
+ MPI File Info: [13] key = romio_ds_write, value = automatic
+ MPI File Info: [14] key = cb_config_list, value = *:1
+ MPI File Info: [15] key = nc_header_align_size, value = 512
+ MPI File Info: [16] key = nc_var_align_size, value = 512
+ MPI File Info: [17] key = nc_header_read_chunk_size, value = 0
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <iostream>
+using namespace std;
+
+#include <string.h> /* strcpy() */
+#include <unistd.h> /* getopt() */
+#include <pnetcdf>
+
+using namespace PnetCDF;
+using namespace PnetCDF::exceptions;
+
+static void
+usage(char *argv0)
+{
+ cerr <<
+ "Usage: %s [-h] | [-q] [file_name]\n"
+ " [-h] Print help\n"
+ " [-q] Quiet mode (reports when fail)\n"
+ " [filename] output netCDF file name\n"
+ << argv0;
+}
+
+/*----< print_info() >------------------------------------------------------*/
+static
+void print_info(MPI_Info *info_used)
+{
+ int i, nkeys;
+
+ MPI_Info_get_nkeys(*info_used, &nkeys);
+ printf("MPI File Info: nkeys = %d\n",nkeys);
+ for (i=0; i<nkeys; i++) {
+ char key[MPI_MAX_INFO_KEY], value[MPI_MAX_INFO_VAL];
+ int valuelen, flag;
+
+ MPI_Info_get_nthkey(*info_used, i, key);
+ MPI_Info_get_valuelen(*info_used, key, &valuelen, &flag);
+ MPI_Info_get(*info_used, key, valuelen+1, value, &flag);
+ printf("MPI File Info: [%2d] key = %25s, value = %s\n",i,key,value);
+ }
+}
+
+/*----< main() >------------------------------------------------------------*/
+int main(int argc, char **argv)
+{
+ extern int optind;
+ char filename[128];
+ int i, rank, verbose=1;
+ MPI_Info info_used;
+
+ MPI_Init(&argc,&argv);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+
+ /* get command-line arguments */
+ while ((i = getopt(argc, argv, "hq")) != EOF)
+ switch(i) {
+ case 'q': verbose = 0;
+ break;
+ case 'h':
+ default: if (rank==0) usage(argv[0]);
+ MPI_Finalize();
+ return 0;
+ }
+ argc -= optind;
+ argv += optind;
+ if (argc == 1) strcpy(filename, argv[0]); /* optional argument */
+ else strcpy(filename, "testfile.nc");
+
+ try {
+ /* create the file */
+ NcmpiFile ncFile(MPI_COMM_WORLD, filename, NcmpiFile::replace,
+ NcmpiFile::classic5);
+
+ /* get all the default hints used */
+ ncFile.Inq_file_info(&info_used);
+ }
+ catch(NcmpiException& e) {
+ cout << e.what() << " error code=" << e.errorCode() << " Error!\n";
+ return 1;
+ }
+
+ if (rank == 0 && verbose) print_info(&info_used);
+ MPI_Info_free(&info_used);
+
+ /* check if there is any PnetCDF internal malloc residue */
+ MPI_Offset malloc_size, sum_size;
+ int err = ncmpi_inq_malloc_size(&malloc_size);
+ if (err == NC_NOERR) {
+ MPI_Reduce(&malloc_size, &sum_size, 1, MPI_OFFSET, MPI_SUM, 0, MPI_COMM_WORLD);
+ if (rank == 0 && sum_size > 0)
+ printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n",
+ sum_size);
+ }
+
+ MPI_Finalize();
+ return 0;
+}
+
diff --git a/examples/CXX/get_vara.cpp b/examples/CXX/get_vara.cpp
new file mode 100644
index 0000000..0c1ec56
--- /dev/null
+++ b/examples/CXX/get_vara.cpp
@@ -0,0 +1,190 @@
+/*********************************************************************
+ *
+ * Copyright (C) 2014, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ *
+ *********************************************************************/
+/* $Id: get_vara.cpp 2245 2015-12-20 18:39:52Z wkliao $ */
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * This example is the read counterpart of example put_vara.cpp. It shows how to
+ * use NcmpiVar::getVar_all() to read a 2D 4-byte integer array in parallel.
+ * It also reads a global attribute and two attribute of variable named "var".
+ * The data partitioning pattern is a column-wise partitioning across all
+ * processes. Each process reads a subarray of size local_ny * local_nx.
+ *
+ * To compile:
+ * mpicxx -O2 get_vara.cpp -o get_vara -lpnetcdf
+ *
+ * Input file is the output file produced by put_vara.cpp. Here is the CDL
+ * dumped from running ncmpidump.
+ *
+ * % ncmpidump /pvfs2/wkliao/testfile.nc
+ * netcdf testfile {
+ * // file format: CDF-1
+ * dimensions:
+ * y = 10 ;
+ * x = 16 ;
+ * variables:
+ * int var(y, x) ;
+ * var:str_att_name = "example attribute of type text." ;
+ * var:float_att_name = 0.f, 1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 7.f ;
+ * // global attributes:
+ * :history = "Wed Apr 30 11:18:58 2014\n",
+ * "" ;
+ * data:
+ *
+ * var =
+ * 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3,
+ * 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3,
+ * 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3,
+ * 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3,
+ * 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3,
+ * 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3,
+ * 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3,
+ * 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3,
+ * 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3,
+ * 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3 ;
+ * }
+ *
+ * Example command for MPI run:
+ *
+ * % mpiexec -n 4 ./get_vara /pvfs2/wkliao/testfile.nc
+ *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <iostream>
+using namespace std;
+
+#include <string.h> /* strcpy() */
+#include <unistd.h> /* getopt() */
+#include <pnetcdf>
+
+using namespace PnetCDF;
+using namespace PnetCDF::exceptions;
+
+static void
+usage(char *argv0)
+{
+ cerr <<
+ "Usage: %s [-h] | [-q] [file_name]\n"
+ " [-h] Print help\n"
+ " [-q] Quiet mode (reports when fail)\n"
+ " [filename] input netCDF file name\n"
+ << argv0;
+}
+
+int main(int argc, char** argv)
+{
+ extern int optind;
+ char filename[128], str_att[NC_MAX_NAME];
+ int i, rank, nprocs, err, verbose=1;
+ MPI_Offset len, global_ny, global_nx, local_ny, local_nx;
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+
+ /* get command-line arguments */
+ while ((i = getopt(argc, argv, "hq")) != EOF)
+ switch(i) {
+ case 'q': verbose = 0;
+ break;
+ case 'h':
+ default: if (rank==0) usage(argv[0]);
+ MPI_Finalize();
+ return 0;
+ }
+ argc -= optind;
+ argv += optind;
+ if (argc == 1) strcpy(filename, argv[0]); /* optional argument */
+ else strcpy(filename, "testfile.nc");
+
+ try {
+ /* open an existing file for reading --------------------------------*/
+ NcmpiFile ncFile(MPI_COMM_WORLD, filename, NcmpiFile::read);
+
+ // Check the format.
+ if (ncFile.getFormat() != NcmpiFile::classic5) {
+ cout << "unexpected file format"<<endl;
+ throw NcmpiException("read Error ",__FILE__,__LINE__);
+ }
+
+ /* get global attribute named "history" */
+ NcmpiGroupAtt att = ncFile.getAtt("history");
+ att.getValues(str_att);
+ len = att.getAttLength();
+ str_att[len] = '\0'; /* add a NULL char at the end */
+ if (rank == 0 && verbose)
+ printf("global attribute \"history\" of text: %s\n",str_att);
+
+ /* get dimension IDs for dimensions Y and X */
+ NcmpiDim yDim = ncFile.getDim("Y");
+ NcmpiDim xDim = ncFile.getDim("X");
+
+ /* get dimension lengths for dimensions Y and X */
+ global_ny = yDim.getSize();
+ global_nx = xDim.getSize();
+
+ /* get the variable ID of a 2D variable of integer type */
+ NcmpiVar var = ncFile.getVar("var");
+
+ /* get variable's attribute named "str_att_name" */
+ NcmpiVarAtt vatt = var.getAtt("str_att_name");
+ vatt.getValues(str_att);
+ len = vatt.getAttLength();
+ str_att[len] = '\0'; /* add a NULL char at the end */
+ if (rank == 0 && verbose)
+ printf("variable attribute \"str_att_name\" of type text = \"%s\"\n",
+ str_att);
+
+ /* get the length of variable's attribute named "float_att_name" */
+ NcmpiVarAtt flt_vatt = var.getAtt("float_att_name");
+ len = flt_vatt.getAttLength();
+
+ /* get attribute contents */
+ float *float_att = (float*) malloc(len * sizeof(float));
+ flt_vatt.getValues(float_att);
+
+ /* the local array size */
+ local_ny = global_ny;
+ local_nx = global_nx / nprocs;
+ int *buf = (int*) malloc(local_nx * local_ny * sizeof(int));
+
+ /* prepare reading subarray */
+ vector<MPI_Offset> start(2), count(2);
+ start[0] = 0;
+ start[1] = local_nx * rank;
+ count[0] = local_ny;
+ count[1] = local_nx;
+
+ /* read a subarray in collective mode */
+
+ // var.getVar_all(start, count, &buf[0][0]);
+ var.getVar_all(start, count, buf);
+
+ free(buf);
+ free(float_att);
+ /* file is close implicitly */
+ }
+ catch(NcmpiException& e) {
+ cout << e.what() << " error code=" << e.errorCode() << " Error!\n";
+ }
+
+ /* check if there is any PnetCDF internal malloc residue */
+ MPI_Offset malloc_size, sum_size;
+ err = ncmpi_inq_malloc_size(&malloc_size);
+ if (err == NC_NOERR) {
+ MPI_Reduce(&malloc_size, &sum_size, 1, MPI_OFFSET, MPI_SUM, 0, MPI_COMM_WORLD);
+ if (rank == 0 && sum_size > 0)
+ printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n",
+ sum_size);
+ }
+
+ MPI_Finalize();
+ return 0;
+}
+
diff --git a/examples/CXX/hints.cpp b/examples/CXX/hints.cpp
new file mode 100644
index 0000000..a9eb356
--- /dev/null
+++ b/examples/CXX/hints.cpp
@@ -0,0 +1,212 @@
+/*********************************************************************
+ *
+ * Copyright (C) 2014, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ *
+ *********************************************************************/
+/* $Id: hints.cpp 1839 2014-10-30 20:22:37Z wkliao $ */
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * This example sets two PnetCDF hints:
+ * nc_header_align_size and nc_var_align_size
+ * and prints the hint values as well as the header size, header extent, and
+ * two variables' starting file offsets.
+ *
+ * The compile and run commands are given below.
+ *
+ * % mpicxx -O2 -o hints hints.c -lpnetcdf
+ *
+ * % mpiexec -l -n 4 ./hints /pvfs2/wkliao/testfile.nc
+ *
+ * nc_header_align_size set to = 1024
+ * nc_var_align_size set to = 512
+ * nc_header_read_chunk_size set to = 256
+ * header size = 252
+ * header extent = 1024
+ * var_zy start file offset = 1024
+ * var_yx start file offset = 3072
+ *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <iostream>
+using namespace std;
+
+#include <string.h> /* strcpy() */
+#include <unistd.h> /* getopt() */
+#include <pnetcdf>
+
+using namespace PnetCDF;
+using namespace PnetCDF::exceptions;
+
+#define NZ 5
+#define NY 5
+#define NX 5
+
+static void
+usage(char *argv0)
+{
+ cerr <<
+ "Usage: %s [-h] | [-q] [file_name]\n"
+ " [-h] Print help\n"
+ " [-q] Quiet mode (reports when fail)\n"
+ " [filename] output netCDF file name\n"
+ << argv0;
+}
+
+static
+void print_hints(NcmpiFile &ncFile,
+ NcmpiVar &var0,
+ NcmpiVar &var1)
+{
+ char value[MPI_MAX_INFO_VAL];
+ int len, flag;
+ MPI_Offset header_size, header_extent, var_zy_start, var_yx_start;
+ MPI_Offset h_align=-1, v_align=-1, h_chunk=-1;
+ MPI_Info info_used;
+
+ ncFile.Inq_header_size(&header_size);
+ ncFile.Inq_header_extent(&header_extent);
+
+ var0.Inq_file_offset(&var_zy_start);
+ var1.Inq_file_offset(&var_yx_start);
+
+ /* get all the hints used */
+ ncFile.Inq_file_info(&info_used);
+
+ MPI_Info_get_valuelen(info_used, (char*)"nc_header_align_size", &len, &flag);
+ if (flag) {
+ MPI_Info_get(info_used, (char*)"nc_header_align_size", len+1, value, &flag);
+ h_align = atoll(value);
+ }
+ MPI_Info_get_valuelen(info_used, (char*)"nc_var_align_size", &len, &flag);
+ if (flag) {
+ MPI_Info_get(info_used, (char*)"nc_var_align_size", len+1, value, &flag);
+ v_align = atoll(value);
+ }
+ MPI_Info_get_valuelen(info_used, (char*)"nc_header_read_chunk_size", &len, &flag);
+ if (flag) {
+ MPI_Info_get(info_used, (char*)"nc_header_read_chunk_size", len+1, value,&flag);
+ h_chunk = atoll(value);
+ }
+ MPI_Info_free(&info_used);
+
+ if (h_align == -1)
+ printf("nc_header_align_size is NOT set\n");
+ else
+ printf("nc_header_align_size set to = %lld\n", h_align);
+
+ if (v_align == -1)
+ printf("nc_var_align_size is NOT set\n");
+ else
+ printf("nc_var_align_size set to = %lld\n", v_align);
+ if (h_chunk == -1)
+ printf("nc_header_read_chunk_size is NOT set\n");
+ else
+ printf("nc_header_read_chunk_size set to = %lld\n", h_chunk);
+
+ printf("header size = %lld\n", header_size);
+ printf("header extent = %lld\n", header_extent);
+ printf("var_zy start file offset = %lld\n", var_zy_start);
+ printf("var_yx start file offset = %lld\n", var_yx_start);
+}
+
+int main(int argc, char** argv)
+{
+ extern int optind;
+ char filename[128];
+ int i, rank, nprocs, verbose=1, *buf_zy;
+ float *buf_yx;
+ vector<MPI_Offset> start(2), count(2);
+ MPI_Info info;
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+
+ /* get command-line arguments */
+ while ((i = getopt(argc, argv, "hq")) != EOF)
+ switch(i) {
+ case 'q': verbose = 0;
+ break;
+ case 'h':
+ default: if (rank==0) usage(argv[0]);
+ MPI_Finalize();
+ return 0;
+ }
+ argc -= optind;
+ argv += optind;
+ if (argc == 1) strcpy(filename, argv[0]); /* optional argument */
+ else strcpy(filename, "testfile.nc");
+
+ try {
+ MPI_Info_create(&info);
+ MPI_Info_set(info, (char*)"nc_header_align_size", (char*)"1024");
+ MPI_Info_set(info, (char*)"nc_var_align_size", (char*)"512");
+ MPI_Info_set(info, (char*)"nc_header_read_chunk_size", (char*)"256");
+ /* note that set the above values to 1 to disable the alignment */
+
+ /* create a new file for writing -------------------------------------*/
+ NcmpiFile ncFile(MPI_COMM_WORLD, filename, NcmpiFile::replace,
+ NcmpiFile::classic5, info);
+ MPI_Info_free(&info);
+
+ /* define 3 dimensions */
+ vector<NcmpiDim> dimid(3);
+ dimid[0] = ncFile.addDim("Z", NZ*nprocs);
+ dimid[1] = ncFile.addDim("Y", NY*nprocs);
+ dimid[2] = ncFile.addDim("X", NX*nprocs);
+
+ /* define a variable of size (NZ * nprocs) * (NY * nprocs) */
+ vector<NcmpiDim> dimid_zy(2);
+ dimid_zy[0] = dimid[0];
+ dimid_zy[1] = dimid[1];
+ NcmpiVar var0 = ncFile.addVar("var_zy", ncmpiInt, dimid_zy);
+
+ /* define a variable of size (NY * nprocs) * (NX * nprocs) */
+ vector<NcmpiDim> dimid_yx(2);
+ dimid_yx[0] = dimid[1];
+ dimid_yx[1] = dimid[2];
+ NcmpiVar var1 = ncFile.addVar("var_yx", ncmpiFloat, dimid_yx);
+
+ /* var_zy is partitioned along Z dimension */
+ buf_zy = (int*) malloc(NZ * (NY * nprocs) * sizeof(int));
+ for (i=0; i<NZ*(NY*nprocs); i++) buf_zy[i] = i;
+
+ start[0] = NZ * rank; start[1] = 0;
+ count[0] = NZ; count[1] = NY * nprocs;
+ var0.putVar_all(start, count, buf_zy);
+
+ /* var_yx is partitioned along X dimension */
+ buf_yx = (float*) malloc((NY * nprocs) * NX * sizeof(float));
+ for (i=0; i<(NY*nprocs)*NX; i++) buf_yx[i] = i;
+
+ start[0] = 0; start[1] = NX * rank;
+ count[0] = NY * nprocs; count[1] = NX;
+ var1.putVar_all(start, count, buf_yx);
+
+ if (rank == 0 && verbose) print_hints(ncFile, var0, var1);
+
+ free(buf_zy);
+ free(buf_yx);
+ }
+ catch(NcmpiException& e) {
+ cout << e.what() << " error code=" << e.errorCode() << " Error!\n";
+ }
+
+ /* check if there is any PnetCDF internal malloc residue */
+ MPI_Offset malloc_size, sum_size;
+ int err = ncmpi_inq_malloc_size(&malloc_size);
+ if (err == NC_NOERR) {
+ MPI_Reduce(&malloc_size, &sum_size, 1, MPI_OFFSET, MPI_SUM, 0, MPI_COMM_WORLD);
+ if (rank == 0 && sum_size > 0)
+ printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n",
+ sum_size);
+ }
+
+ MPI_Finalize();
+ return 0;
+}
+
diff --git a/examples/CXX/nonblocking_write.cpp b/examples/CXX/nonblocking_write.cpp
new file mode 100644
index 0000000..fb92bd1
--- /dev/null
+++ b/examples/CXX/nonblocking_write.cpp
@@ -0,0 +1,262 @@
+/*********************************************************************
+ *
+ * Copyright (C) 2014, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ *
+ *********************************************************************/
+/* $Id: nonblocking_write.cpp 2245 2015-12-20 18:39:52Z wkliao $ */
+
+/* This example is similar to collective_write.c but using nonblocking APIs.
+ * It creates a netcdf file in CD-5 format and writes a number of
+ * 3D integer non-record variables. The measured write bandwidth is reported
+ * at the end. Usage: (for example)
+ * To compile:
+ * mpicxx -O2 nonblocking_write.cpp -o nonblocking_write -lpnetcdf
+ * To run:
+ * mpiexec -n num_processes ./nonblocking_write [filename] [len]
+ * where len decides the size of each local array, which is len x len x len.
+ * So, each non-record variable is of size len*len*len * nprocs * sizeof(int)
+ * All variables are partitioned among all processes in a 3D
+ * block-block-block fashion. Below is an example standard output from
+ * command:
+ * mpiexec -n 32 ./nonblocking_write /pvfs2/wkliao/testfile.nc 100
+ *
+ * MPI hint: cb_nodes = 2
+ * MPI hint: cb_buffer_size = 16777216
+ * MPI hint: striping_factor = 32
+ * MPI hint: striping_unit = 1048576
+ * Local array size 100 x 100 x 100 integers, size = 3.81 MB
+ * Global array size 400 x 400 x 200 integers, write size = 0.30 GB
+ * procs Global array size exec(sec) write(MB/s)
+ * ------- ------------------ --------- -----------
+ * 32 400 x 400 x 200 6.67 45.72
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <iostream>
+using namespace std;
+
+#include <string.h> /* strcpy() */
+#include <unistd.h> /* getopt() */
+#include <pnetcdf>
+
+using namespace PnetCDF;
+using namespace PnetCDF::exceptions;
+
+#define NDIMS 3
+#define NUM_VARS 10
+
+static void
+usage(char *argv0)
+{
+ cerr <<
+ "Usage: %s [-h] | [-q] [file_name] [len]\n"
+ " [-h] Print help\n"
+ " [-q] Quiet mode (reports when fail)\n"
+ " [filename] output netCDF file name\n"
+ " [len] size of each dimension of the local array\n"
+ << argv0;
+}
+
+/*----< print_info() >------------------------------------------------------*/
+static
+void print_info(MPI_Info *info_used)
+{
+ int flag;
+ char info_cb_nodes[64], info_cb_buffer_size[64];
+ char info_striping_factor[64], info_striping_unit[64];
+
+ strcpy(info_cb_nodes, "undefined");
+ strcpy(info_cb_buffer_size, "undefined");
+ strcpy(info_striping_factor, "undefined");
+ strcpy(info_striping_unit, "undefined");
+
+ MPI_Info_get(*info_used, (char*)"cb_nodes", 64, info_cb_nodes, &flag);
+ MPI_Info_get(*info_used, (char*)"cb_buffer_size", 64, info_cb_buffer_size, &flag);
+ MPI_Info_get(*info_used, (char*)"striping_factor", 64, info_striping_factor, &flag);
+ MPI_Info_get(*info_used, (char*)"striping_unit", 64, info_striping_unit, &flag);
+
+ printf("MPI hint: cb_nodes = %s\n", info_cb_nodes);
+ printf("MPI hint: cb_buffer_size = %s\n", info_cb_buffer_size);
+ printf("MPI hint: striping_factor = %s\n", info_striping_factor);
+ printf("MPI hint: striping_unit = %s\n", info_striping_unit);
+}
+
+/*----< main() >------------------------------------------------------------*/
+int main(int argc, char **argv)
+{
+ extern int optind;
+ int i, j, verbose=1;
+ int nprocs, len, *buf[NUM_VARS], bufsize, rank;
+ int gsizes[NDIMS], psizes[NDIMS];
+ double write_timing, max_write_timing, write_bw;
+ char filename[128], str[512];
+ int req[NUM_VARS], st[NUM_VARS];
+ MPI_Offset write_size, sum_write_size;
+ vector<MPI_Offset> starts(NDIMS), counts(NDIMS);
+ MPI_Offset bbufsize, put_size;
+ MPI_Info info_used;
+
+ MPI_Init(&argc,&argv);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+
+ /* get command-line arguments */
+ while ((i = getopt(argc, argv, "hq")) != EOF)
+ switch(i) {
+ case 'q': verbose = 0;
+ break;
+ case 'h':
+ default: if (rank==0) usage(argv[0]);
+ MPI_Finalize();
+ return 0;
+ }
+ argc -= optind;
+ argv += optind;
+ if (argc >= 1) strcpy(filename, argv[0]); /* optional argument */
+ else strcpy(filename, "testfile.nc");
+ len = 10;
+ if (argc >= 2) len = atoi(argv[1]); /* optional argument */
+
+ for (i=0; i<NDIMS; i++) psizes[i] = 0;
+
+ MPI_Dims_create(nprocs, NDIMS, psizes);
+ starts[0] = rank % psizes[0];
+ starts[1] = (rank / psizes[1]) % psizes[1];
+ starts[2] = (rank / (psizes[0] * psizes[1])) % psizes[2];
+
+ bufsize = 1;
+ for (i=0; i<NDIMS; i++) {
+ gsizes[i] = len * psizes[i];
+ starts[i] *= len;
+ counts[i] = len;
+ bufsize *= len;
+ }
+
+ /* allocate buffer and initialize with random numbers */
+ srand(rank);
+ for (i=0; i<NUM_VARS; i++) {
+ buf[i] = (int *) malloc(bufsize * sizeof(int));
+ for (j=0; j<bufsize; j++) buf[i][j] = rand();
+ }
+
+ MPI_Barrier(MPI_COMM_WORLD);
+ write_timing = MPI_Wtime();
+
+ try {
+ /* create the file */
+ NcmpiFile nc(MPI_COMM_WORLD, filename, NcmpiFile::replace,
+ NcmpiFile::classic5);
+
+ /* define dimensions */
+ vector<NcmpiDim> dimids(NDIMS);
+ for (i=0; i<NDIMS; i++) {
+ sprintf(str, "%c", 'x'+i);
+ dimids[i] = nc.addDim(str, gsizes[i]);
+ }
+
+ /* define variables */
+ vector<NcmpiVar> vars(NUM_VARS);
+ for (i=0; i<NUM_VARS; i++) {
+ sprintf(str, "var%d", i);
+ vars[i] = nc.addVar(str, ncmpiInt, dimids);
+ }
+
+ /* get all the hints used */
+ nc.Inq_file_info(&info_used);
+
+ /* write one variable at a time using iput */
+ for (i=0; i<NUM_VARS; i++)
+ vars[i].iputVar(starts, counts, &buf[i][0], &req[i]);
+
+ /* wait for the nonblocking I/O to complete */
+ nc.Wait_all(NUM_VARS, req, st);
+
+ for (i=0; i<NUM_VARS; i++) {
+ if (st[i] != NC_NOERR)
+ printf("Error: nonblocking write fails on request %d (%s)\n",
+ i, ncmpi_strerror(st[i]));
+ }
+
+ /* write one variable at a time using bput */
+
+ /* bbufsize must be max of data type converted before and after */
+ bbufsize = bufsize * NUM_VARS * sizeof(int);
+ nc.Buffer_attach(bbufsize);
+
+ for (i=0; i<NUM_VARS; i++) {
+ vars[i].bputVar(starts, counts, buf[i], &req[i]);
+ /* can safely change contents or free up the buf[i] here */
+ }
+
+ /* wait for the nonblocking I/O to complete */
+ nc.Wait_all(NUM_VARS, req, st);
+ for (i=0; i<NUM_VARS; i++) {
+ if (st[i] != NC_NOERR)
+ printf("Error: nonblocking write fails on request %d (%s)\n",
+ i, ncmpi_strerror(st[i]));
+ }
+
+ /* detach the temporary buffer */
+ nc.Buffer_detach();
+
+ nc.Inq_put_size(&put_size);
+#ifdef MPI_OFFSET
+ MPI_Allreduce(MPI_IN_PLACE, &put_size, 1, MPI_OFFSET, MPI_SUM, MPI_COMM_WORLD);
+#else
+ MPI_Allreduce(MPI_IN_PLACE, &put_size, 1, MPI_LONG_LONG, MPI_SUM, MPI_COMM_WORLD);
+#endif
+ }
+ catch(NcmpiException& e) {
+ cout << e.what() << " error code=" << e.errorCode() << " Error!\n";
+ return 1;
+ }
+ write_timing = MPI_Wtime() - write_timing;
+
+ write_size = bufsize * NUM_VARS * sizeof(int);
+ for (i=0; i<NUM_VARS; i++) free(buf[i]);
+
+#ifdef MPI_OFFSET
+ MPI_Reduce(&write_size, &sum_write_size, 1, MPI_OFFSET, MPI_SUM, 0, MPI_COMM_WORLD);
+#else
+ MPI_Reduce(&write_size, &sum_write_size, 1, MPI_LONG_LONG, MPI_SUM, 0, MPI_COMM_WORLD);
+#endif
+ MPI_Reduce(&write_timing, &max_write_timing, 1, MPI_DOUBLE, MPI_MAX, 0, MPI_COMM_WORLD);
+
+ if (rank == 0 && verbose) {
+ double write_amount = sum_write_size;
+ float subarray_size = (float)bufsize*sizeof(int)/1048576.0;
+ printf("\n");
+ printf("Total amount writes to variables only (exclude header) = %lld bytes\n", sum_write_size);
+ printf("Total amount writes reported by pnetcdf (include header) = %lld bytes\n", put_size);
+ printf("\n");
+ print_info(&info_used);
+ printf("Local array size %d x %d x %d integers, size = %.2f MB\n",len,len,len,subarray_size);
+ write_amount /= 1048576.0;
+ printf("Global array size %d x %d x %d integers, write size = %.2f GB\n",
+ gsizes[0], gsizes[1], gsizes[2], write_amount/1024.0);
+
+ write_bw = write_amount/max_write_timing;
+ printf(" procs Global array size exec(sec) write(MB/s)\n");
+ printf("------- ------------------ --------- -----------\n");
+ printf(" %4d %4d x %4d x %4d %8.2f %10.2f\n", nprocs,
+ gsizes[0], gsizes[1], gsizes[2], max_write_timing, write_bw);
+ }
+ MPI_Info_free(&info_used);
+
+ /* check if there is any PnetCDF internal malloc residue */
+ MPI_Offset malloc_size, sum_size;
+ int err = ncmpi_inq_malloc_size(&malloc_size);
+ if (err == NC_NOERR) {
+ MPI_Reduce(&malloc_size, &sum_size, 1, MPI_OFFSET, MPI_SUM, 0, MPI_COMM_WORLD);
+ if (rank == 0 && sum_size > 0)
+ printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n",
+ sum_size);
+ }
+
+ MPI_Finalize();
+ return 0;
+}
+
diff --git a/examples/CXX/put_vara.cpp b/examples/CXX/put_vara.cpp
new file mode 100644
index 0000000..edb65d9
--- /dev/null
+++ b/examples/CXX/put_vara.cpp
@@ -0,0 +1,180 @@
+/*********************************************************************
+ *
+ * Copyright (C) 2014, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ *
+ *********************************************************************/
+/* $Id: put_vara.cpp 2245 2015-12-20 18:39:52Z wkliao $ */
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * This example shows how to use NcmpiVar::putVar_all() to write a 2D
+ * 4-byte integer array in parallel. It first defines a netCDF variable of
+ * size global_nx * global_ny where
+ * global_ny == NY and
+ * global_nx == (NX * number of MPI processes).
+ * The data partitioning pattern is a column-wise partitioning across all
+ * processes. Each process writes a subarray of size ny * nx.
+ *
+ * To compile:
+ * mpicxx -O2 put_vara.cpp -o put_vara -lpnetcdf
+ *
+ * Example commands for MPI run and outputs from running ncmpidump on the
+ * NC file produced by this example program:
+ *
+ * % mpiexec -n 4 ./put_vara /pvfs2/wkliao/testfile.nc
+ *
+ * % ncmpidump /pvfs2/wkliao/testfile.nc
+ * netcdf testfile {
+ * // file format: CDF-5 (big variables)
+ * dimensions:
+ * y = 10 ;
+ * x = 16 ;
+ * variables:
+ * int var(y, x) ;
+ * var:str_att_name = "example attribute of type text." ;
+ * var:float_att_name = 0.f, 1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 7.f ;
+ * // global attributes:
+ * :history = "Wed Apr 30 11:18:58 2014\n",
+ * "" ;
+ * data:
+ *
+ * var =
+ * 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3,
+ * 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3,
+ * 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3,
+ * 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3,
+ * 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3,
+ * 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3,
+ * 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3,
+ * 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3,
+ * 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3,
+ * 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3 ;
+ *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <iostream>
+using namespace std;
+
+#include <string.h> /* strcpy() */
+#include <unistd.h> /* getopt() */
+#include <time.h> /* time() localtime(), asctime() */
+
+#include <pnetcdf>
+
+using namespace PnetCDF;
+using namespace PnetCDF::exceptions;
+
+#define NY 10
+#define NX 4
+
+static void
+usage(char *argv0)
+{
+ cerr <<
+ "Usage: %s [-h] | [-q] [file_name]\n"
+ " [-h] Print help\n"
+ " [-q] Quiet mode (reports when fail)\n"
+ " [filename] output netCDF file name\n"
+ << argv0;
+}
+
+int main(int argc, char** argv)
+{
+ extern int optind;
+ char filename[128], str_att[128];
+ int i, j, verbose=1, rank, nprocs, buf[NY][NX];
+ float float_att[100];
+ MPI_Offset global_ny, global_nx;
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+
+ /* get command-line arguments */
+ while ((i = getopt(argc, argv, "hq")) != EOF)
+ switch(i) {
+ case 'q': verbose = 0;
+ break;
+ case 'h':
+ default: if (rank==0) usage(argv[0]);
+ MPI_Finalize();
+ return 0;
+ }
+ argc -= optind;
+ argv += optind;
+ if (argc == 1) strcpy(filename, argv[0]); /* optional argument */
+ else strcpy(filename, "testfile.nc");
+
+ try {
+ /* create a new file for writing ------------------------------------*/
+ NcmpiFile ncFile(MPI_COMM_WORLD, filename, NcmpiFile::replace,
+ NcmpiFile::classic5);
+
+ /* the global array is NY * (NX * nprocs) */
+ global_ny = NY;
+ global_nx = NX * nprocs;
+
+ for (i=0; i<NY; i++)
+ for (j=0; j<NX; j++)
+ buf[i][j] = rank;
+
+ /* add a global attribute: a time stamp at rank 0 */
+ time_t ltime = time(NULL); /* get the current calendar time */
+ asctime_r(localtime(<ime), str_att);
+
+ /* make sure the time string are consistent among all processes */
+ MPI_Bcast(str_att, 128, MPI_CHAR, 0, MPI_COMM_WORLD);
+
+ ncFile.putAtt(string("history"), string(str_att));
+
+ /* define dimensions Y and X */
+ vector<NcmpiDim> dimid(2);
+
+ dimid[0] = ncFile.addDim("Y", global_ny);
+ dimid[1] = ncFile.addDim("X", global_nx);
+
+ /* define a 2D variable of integer type */
+ NcmpiVar var = ncFile.addVar("var", ncmpiInt, dimid);
+
+ /* add attributes to the variable */
+ var.putAtt(string("str_att_name"),
+ string("example attribute of type text."));
+
+ for (i=0; i<8; i++) float_att[i] = i;
+ var.putAtt(string("float_att_name"), ncmpiFloat, 8, float_att);
+
+ /* now we are in data mode */
+ vector<MPI_Offset> start(2), count(2);
+ start[0] = 0;
+ start[1] = NX * rank;
+ count[0] = NY;
+ count[1] = NX;
+ if (verbose)
+ printf("%d: start=%lld %lld count=%lld %lld\n",rank,
+ start[0],start[1],count[0],count[1]);
+
+ var.putVar_all(start, count, &buf[0][0]);
+
+ /* file is close implicitly */
+ }
+ catch(NcmpiException& e) {
+ cout << e.what() << " error code=" << e.errorCode() << " Error!\n";
+ }
+
+ /* check if there is any PnetCDF internal malloc residue */
+ MPI_Offset malloc_size, sum_size;
+ int err = ncmpi_inq_malloc_size(&malloc_size);
+ if (err == NC_NOERR) {
+ MPI_Reduce(&malloc_size, &sum_size, 1, MPI_OFFSET, MPI_SUM, 0, MPI_COMM_WORLD);
+ if (rank == 0 && sum_size > 0)
+ printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n",
+ sum_size);
+ }
+
+ MPI_Finalize();
+ return 0;
+}
+
diff --git a/examples/CXX/put_varn_float.cpp b/examples/CXX/put_varn_float.cpp
new file mode 100644
index 0000000..5003878
--- /dev/null
+++ b/examples/CXX/put_varn_float.cpp
@@ -0,0 +1,222 @@
+/*********************************************************************
+ *
+ * Copyright (C) 2014, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ *
+ *********************************************************************/
+/* $Id: put_varn_float.cpp 1669 2014-05-24 18:28:16Z wkliao $ */
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * This example shows how to use a single call of NcmpiVar::putVarn_all()
+ * to write a sequence of one-element requests with arbitrary array indices.
+ *
+ * The compile and run commands are given below, together with an ncmpidump of
+ * the output file.
+ *
+ * % mpicxx -O2 -o put_varn_float put_varn_float.cpp -lpnetcdf
+ * % mpiexec -n 4 ./put_varn_float /pvfs2/wkliao/testfile.nc
+ * % ncmpidump /pvfs2/wkliao/testfile.nc
+ * netcdf testfile {
+ * // file format: CDF-5 (big variables)
+ * dimensions:
+ * Y = 4 ;
+ * X = 10 ;
+ * variables:
+ * int var(Y, X) ;
+ * data:
+ *
+ * var =
+ * 3, 3, 3, 1, 1, 0, 0, 2, 1, 1,
+ * 0, 2, 2, 2, 3, 1, 1, 2, 2, 2,
+ * 1, 1, 2, 3, 3, 3, 0, 0, 1, 1,
+ * 0, 0, 0, 2, 1, 1, 1, 3, 3, 3 ;
+ * }
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <iostream>
+using namespace std;
+
+#include <string.h> /* strcpy() */
+#include <unistd.h> /* getopt() */
+#include <pnetcdf>
+
+using namespace PnetCDF;
+using namespace PnetCDF::exceptions;
+
+#define NY 4
+#define NX 10
+#define NDIMS 2
+
+static void
+usage(char *argv0)
+{
+ cerr <<
+ "Usage: %s [-h] | [-q] [file_name]\n"
+ " [-h] Print help\n"
+ " [-q] Quiet mode (reports when fail)\n"
+ " [filename] output netCDF file name\n"
+ << argv0;
+}
+
+int main(int argc, char** argv)
+{
+ extern int optind;
+ char filename[128];
+ int i, verbose=1, rank, nprocs, num_reqs;
+ float *buffer;
+ MPI_Offset **starts;
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+
+ /* get command-line arguments */
+ while ((i = getopt(argc, argv, "hq")) != EOF)
+ switch(i) {
+ case 'q': verbose = 0;
+ break;
+ case 'h':
+ default: if (rank==0) usage(argv[0]);
+ MPI_Finalize();
+ return 0;
+ }
+ argc -= optind;
+ argv += optind;
+ if (argc == 1) strcpy(filename, argv[0]); /* optional argument */
+ else strcpy(filename, "testfile.nc");
+
+ if (nprocs != 4 && rank == 0 && verbose)
+ printf("Warning: this program is intended to run on 4 processes\n");
+
+ try {
+ /* create a new file for writing -------------------------------------*/
+ NcmpiFile nc(MPI_COMM_WORLD, filename, NcmpiFile::replace,
+ NcmpiFile::classic);
+
+ /* define dimensions Y and X */
+ vector<NcmpiDim> dimid(2);
+
+ dimid[0] = nc.addDim("Y", NY);
+ dimid[1] = nc.addDim("X", NX);
+
+ /* define a 2D variable of integer type */
+ NcmpiVar var = nc.addVar("var", ncmpiFloat, dimid);
+
+ /* pick arbitrary numbers of requests for 4 processes */
+ num_reqs = 0;
+ if (rank == 0) num_reqs = 8;
+ else if (rank == 1) num_reqs = 13;
+ else if (rank == 2) num_reqs = 9;
+ else if (rank == 3) num_reqs = 10;
+
+ starts = (MPI_Offset**) malloc(num_reqs * sizeof(MPI_Offset*));
+ starts[0] = (MPI_Offset*) calloc(num_reqs * NDIMS, sizeof(MPI_Offset));
+ for (i=1; i<num_reqs; i++)
+ starts[i] = starts[i-1] + NDIMS;
+
+ /* assign arbitrary starts */
+ const int y=0, x=1;
+ if (rank == 0) {
+ starts[0][y] = 0; starts[0][x] = 5;
+ starts[1][y] = 1; starts[1][x] = 0;
+ starts[2][y] = 2; starts[2][x] = 6;
+ starts[3][y] = 3; starts[3][x] = 0;
+ starts[4][y] = 0; starts[4][x] = 6;
+ starts[5][y] = 2; starts[5][x] = 7;
+ starts[6][y] = 3; starts[6][x] = 1;
+ starts[7][y] = 3; starts[7][x] = 2;
+ /* rank 0 is writing the following locations: ("-" means skip)
+ - - - - - 0 0 - - -
+ 0 - - - - - - - - -
+ - - - - - - 0 0 - -
+ 0 0 0 - - - - - - -
+ */
+ } else if (rank ==1) {
+ starts[ 0][y] = 0; starts[ 0][x] = 3;
+ starts[ 1][y] = 0; starts[ 1][x] = 8;
+ starts[ 2][y] = 1; starts[ 2][x] = 5;
+ starts[ 3][y] = 2; starts[ 3][x] = 0;
+ starts[ 4][y] = 2; starts[ 4][x] = 8;
+ starts[ 5][y] = 3; starts[ 5][x] = 4;
+ starts[ 6][y] = 0; starts[ 6][x] = 4;
+ starts[ 7][y] = 0; starts[ 7][x] = 9;
+ starts[ 8][y] = 1; starts[ 8][x] = 6;
+ starts[ 9][y] = 2; starts[ 9][x] = 1;
+ starts[10][y] = 2; starts[10][x] = 9;
+ starts[11][y] = 3; starts[11][x] = 5;
+ starts[12][y] = 3; starts[12][x] = 6;
+ /* rank 1 is writing the following locations: ("-" means skip)
+ - - - 1 1 - - - 1 1
+ - - - - - 1 1 - - -
+ 1 1 - - - - - - 1 1
+ - - - - 1 1 1 - - -
+ */
+ } else if (rank ==2) {
+ starts[0][y] = 0; starts[0][x] = 7;
+ starts[1][y] = 1; starts[1][x] = 1;
+ starts[2][y] = 1; starts[2][x] = 7;
+ starts[3][y] = 2; starts[3][x] = 2;
+ starts[4][y] = 3; starts[4][x] = 3;
+ starts[5][y] = 1; starts[5][x] = 2;
+ starts[6][y] = 1; starts[6][x] = 8;
+ starts[7][y] = 1; starts[7][x] = 3;
+ starts[8][y] = 1; starts[8][x] = 9;
+ /* rank 2 is writing the following locations: ("-" means skip)
+ - - - - - - - 2 - -
+ - 2 2 2 - - - 2 2 2
+ - - 2 - - - - - - -
+ - - - 2 - - - - - -
+ */
+ } else if (rank ==3) {
+ starts[0][y] = 0; starts[0][x] = 0;
+ starts[1][y] = 1; starts[1][x] = 4;
+ starts[2][y] = 2; starts[2][x] = 3;
+ starts[3][y] = 3; starts[3][x] = 7;
+ starts[4][y] = 0; starts[4][x] = 1;
+ starts[5][y] = 2; starts[5][x] = 4;
+ starts[6][y] = 3; starts[6][x] = 8;
+ starts[7][y] = 0; starts[7][x] = 2;
+ starts[8][y] = 2; starts[8][x] = 5;
+ starts[9][y] = 3; starts[9][x] = 9;
+ /* rank 3 is writing the following locations: ("-" means skip)
+ 3 3 3 - - - - - - -
+ - - - - 3 - - - - -
+ - - - 3 3 3 - - - -
+ - - - - - - - 3 3 3
+ */
+ }
+
+ /* allocate I/O buffer and initialize its contents */
+ buffer = (float*) malloc(num_reqs * sizeof(float));
+ for (i=0; i<num_reqs; i++) buffer[i] = (float)rank;
+
+ /* set the buffer pointers to different offsets to the I/O buffer */
+ var.putVarn_all(num_reqs, starts, NULL, buffer);
+
+ free(buffer);
+ free(starts[0]);
+ free(starts);
+
+ /* file is close implicitly */
+ }
+ catch(NcmpiException& e) {
+ cout << e.what() << " error code=" << e.errorCode() << " Error!\n";
+ }
+
+ /* check if there is any PnetCDF internal malloc residue */
+ MPI_Offset malloc_size, sum_size;
+ int err = ncmpi_inq_malloc_size(&malloc_size);
+ if (err == NC_NOERR) {
+ MPI_Reduce(&malloc_size, &sum_size, 1, MPI_OFFSET, MPI_SUM, 0, MPI_COMM_WORLD);
+ if (rank == 0 && sum_size > 0)
+ printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n",
+ sum_size);
+ }
+
+ MPI_Finalize();
+ return 0;
+}
+
diff --git a/examples/CXX/put_varn_int.cpp b/examples/CXX/put_varn_int.cpp
new file mode 100644
index 0000000..279e71a
--- /dev/null
+++ b/examples/CXX/put_varn_int.cpp
@@ -0,0 +1,223 @@
+/*********************************************************************
+ *
+ * Copyright (C) 2014, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ *
+ *********************************************************************/
+/* $Id: put_varn_int.cpp 1839 2014-10-30 20:22:37Z wkliao $ */
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * This example shows how to use a single call of NcmpiVar::putVarn_all() to
+ * write a sequence of requests with arbitrary array indices and lengths.
+ * Using ncmpi_put_varn_int_all() can achieve the same effect of HDF5 writing
+ * a sequence of selected file locations through the following 2 APIs.
+ *
+ * H5Sselect_elements(fid, H5S_SELECT_SET, NUMP, (const hssize_t **)coord);
+ * H5Dwrite(dataset, H5T_NATIVE_INT, mid, fid, H5P_DEFAULT, val);
+ *
+ * Note that in NcmpiVar::putVarn_all(), users can write more than one
+ * element starting at each selected location.
+ *
+ * The compile and run commands are given below, together with an ncmpidump of
+ * the output file.
+ *
+ * % mpicc -O2 -o put_varn_int put_varn_int.cpp -lpnetcdf
+ * % mpiexec -n 4 ./put_varn_int /pvfs2/wkliao/testfile.nc
+ * % ncmpidump /pvfs2/wkliao/testfile.nc
+ * netcdf testfile {
+ * // file format: CDF-5 (big variables)
+ * dimensions:
+ * Y = 4 ;
+ * X = 10 ;
+ * variables:
+ * int var(Y, X) ;
+ * data:
+ *
+ * var =
+ * 3, 3, 3, 1, 1, 0, 0, 2, 1, 1,
+ * 0, 2, 2, 2, 3, 1, 1, 2, 2, 2,
+ * 1, 1, 2, 3, 3, 3, 0, 0, 1, 1,
+ * 0, 0, 0, 2, 1, 1, 1, 3, 3, 3 ;
+ * }
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <iostream>
+using namespace std;
+
+#include <string.h> /* strcpy() */
+#include <unistd.h> /* getopt() */
+#include <pnetcdf>
+
+using namespace PnetCDF;
+using namespace PnetCDF::exceptions;
+
+#define NY 4
+#define NX 10
+#define NDIMS 2
+
+static void
+usage(char *argv0)
+{
+ cerr <<
+ "Usage: %s [-h] | [-q] [file_name]\n"
+ " [-h] Print help\n"
+ " [-q] Quiet mode (reports when fail)\n"
+ " [filename] output netCDF file name\n"
+ << argv0;
+}
+
+int main(int argc, char** argv)
+{
+ extern int optind;
+ char filename[128];
+ int i, j, rank, nprocs, verbose=1;
+ int num_reqs, *buffer;
+ MPI_Offset w_len, **starts, **counts;
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+
+ /* get command-line arguments */
+ while ((i = getopt(argc, argv, "hq")) != EOF)
+ switch(i) {
+ case 'q': verbose = 0;
+ break;
+ case 'h':
+ default: if (rank==0) usage(argv[0]);
+ MPI_Finalize();
+ return 0;
+ }
+ argc -= optind;
+ argv += optind;
+ if (argc == 1) strcpy(filename, argv[0]); /* optional argument */
+ else strcpy(filename, "testfile.nc");
+
+ if (nprocs != 4 && rank == 0 && verbose)
+ printf("Warning: this program is intended to run on 4 processes\n");
+
+ try {
+ /* create a new file for writing ------------------------------------*/
+ NcmpiFile nc(MPI_COMM_WORLD, filename, NcmpiFile::replace,
+ NcmpiFile::classic5);
+
+ /* define dimensions Y and X */
+ vector<NcmpiDim> dimid(2);
+
+ dimid[0] = nc.addDim("Y", NY);
+ dimid[1] = nc.addDim("X", NX);
+
+ /* define a 2D variable of integer type */
+ NcmpiVar var = nc.addVar("var", ncmpiInt, dimid);
+
+ /* pick arbitrary numbers of requests for 4 processes */
+ num_reqs = 0;
+ if (rank == 0) num_reqs = 4;
+ else if (rank == 1) num_reqs = 6;
+ else if (rank == 2) num_reqs = 5;
+ else if (rank == 3) num_reqs = 4;
+
+ starts = (MPI_Offset**) malloc(num_reqs * sizeof(MPI_Offset*));
+ counts = (MPI_Offset**) malloc(num_reqs * sizeof(MPI_Offset*));
+ starts[0] = (MPI_Offset*) calloc(num_reqs * NDIMS, sizeof(MPI_Offset));
+ counts[0] = (MPI_Offset*) calloc(num_reqs * NDIMS, sizeof(MPI_Offset));
+ for (i=1; i<num_reqs; i++) {
+ starts[i] = starts[i-1] + NDIMS;
+ counts[i] = counts[i-1] + NDIMS;
+ }
+
+ /* assign arbitrary starts and counts */
+ const int y=0, x=1;
+ if (rank == 0) {
+ starts[0][y] = 0; starts[0][x] = 5; counts[0][y] = 1; counts[0][x] = 2;
+ starts[1][y] = 1; starts[1][x] = 0; counts[1][y] = 1; counts[1][x] = 1;
+ starts[2][y] = 2; starts[2][x] = 6; counts[2][y] = 1; counts[2][x] = 2;
+ starts[3][y] = 3; starts[3][x] = 0; counts[3][y] = 1; counts[3][x] = 3;
+ /* rank 0 is writing the followings: ("-" means skip)
+ - - - - - 0 0 - - -
+ 0 - - - - - - - - -
+ - - - - - - 0 0 - -
+ 0 0 0 - - - - - - -
+ */
+ } else if (rank ==1) {
+ starts[0][y] = 0; starts[0][x] = 3; counts[0][y] = 1; counts[0][x] = 2;
+ starts[1][y] = 0; starts[1][x] = 8; counts[1][y] = 1; counts[1][x] = 2;
+ starts[2][y] = 1; starts[2][x] = 5; counts[2][y] = 1; counts[2][x] = 2;
+ starts[3][y] = 2; starts[3][x] = 0; counts[3][y] = 1; counts[3][x] = 2;
+ starts[4][y] = 2; starts[4][x] = 8; counts[4][y] = 1; counts[4][x] = 2;
+ starts[5][y] = 3; starts[5][x] = 4; counts[5][y] = 1; counts[5][x] = 3;
+ /* rank 1 is writing the followings: ("-" means skip)
+ - - - 1 1 - - - 1 1
+ - - - - - 1 1 - - -
+ 1 1 - - - - - - 1 1
+ - - - - 1 1 1 - - -
+ */
+ } else if (rank ==2) {
+ starts[0][y] = 0; starts[0][x] = 7; counts[0][y] = 1; counts[0][x] = 1;
+ starts[1][y] = 1; starts[1][x] = 1; counts[1][y] = 1; counts[1][x] = 3;
+ starts[2][y] = 1; starts[2][x] = 7; counts[2][y] = 1; counts[2][x] = 3;
+ starts[3][y] = 2; starts[3][x] = 2; counts[3][y] = 1; counts[3][x] = 1;
+ starts[4][y] = 3; starts[4][x] = 3; counts[4][y] = 1; counts[4][x] = 1;
+ /* rank 2 is writing the followings: ("-" means skip)
+ - - - - - - - 2 - -
+ - 2 2 2 - - - 2 2 2
+ - - 2 - - - - - - -
+ - - - 2 - - - - - -
+ */
+ } else if (rank ==3) {
+ starts[0][y] = 0; starts[0][x] = 0; counts[0][y] = 1; counts[0][x] = 3;
+ starts[1][y] = 1; starts[1][x] = 4; counts[1][y] = 1; counts[1][x] = 1;
+ starts[2][y] = 2; starts[2][x] = 3; counts[2][y] = 1; counts[2][x] = 3;
+ starts[3][y] = 3; starts[3][x] = 7; counts[3][y] = 1; counts[3][x] = 3;
+ /* rank 3 is writing the followings: ("-" means skip)
+ 3 3 3 - - - - - - -
+ - - - - 3 - - - - -
+ - - - 3 3 3 - - - -
+ - - - - - - - 3 3 3
+ */
+ }
+
+ w_len = 0; /* total write length for this process */
+ for (i=0; i<num_reqs; i++) {
+ MPI_Offset w_req_len=1;
+ for (j=0; j<NDIMS; j++)
+ w_req_len *= counts[i][j];
+ w_len += w_req_len;
+ }
+
+ /* allocate I/O buffer and initialize its contents */
+ buffer = (int*) malloc(w_len * sizeof(int));
+ for (i=0; i<w_len; i++) buffer[i] = rank;
+
+ /* set the buffer pointers to different offsets to the I/O buffer */
+ var.putVarn_all(num_reqs, starts, counts, buffer);
+
+ free(buffer);
+ free(starts[0]);
+ free(counts[0]);
+ free(starts);
+ free(counts);
+
+ /* file is close implicitly */
+ }
+ catch(NcmpiException& e) {
+ cout << e.what() << " error code=" << e.errorCode() << " Error!\n";
+ }
+
+ /* check if there is any PnetCDF internal malloc residue */
+ MPI_Offset malloc_size, sum_size;
+ int err = ncmpi_inq_malloc_size(&malloc_size);
+ if (err == NC_NOERR) {
+ MPI_Reduce(&malloc_size, &sum_size, 1, MPI_OFFSET, MPI_SUM, 0, MPI_COMM_WORLD);
+ if (rank == 0 && sum_size > 0)
+ printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n",
+ sum_size);
+ }
+
+ MPI_Finalize();
+ return 0;
+}
+
diff --git a/examples/CXX/transpose.cpp b/examples/CXX/transpose.cpp
new file mode 100644
index 0000000..0c6361f
--- /dev/null
+++ b/examples/CXX/transpose.cpp
@@ -0,0 +1,226 @@
+/*********************************************************************
+ *
+ * Copyright (C) 2014, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ *
+ *********************************************************************/
+/* $Id: transpose.cpp 1839 2014-10-30 20:22:37Z wkliao $ */
+
+/*
+ * This example shows how to use varm API to write six 3D integer array
+ * variables into a file. Each variable in the file is a dimensional
+ * transposed array from the one stored in memory. In memory, a 3D array is
+ * partitioned among all processes in a block-block-block fashion and in
+ * ZYX (i.e. C) order. The dimension structures of the transposed six
+ * arrays are
+ * int ZYX_var(Z, Y, X) ; ZYX -> ZYX
+ * int ZXY_var(Z, X, Y) ; ZYX -> ZXY
+ * int YZX_var(Y, Z, X) ; ZYX -> YZX
+ * int YXZ_var(Y, X, Z) ; ZYX -> YXZ
+ * int XZY_var(X, Z, Y) ; ZYX -> XZY
+ * int XYZ_var(X, Y, Z) ; ZYX -> XYZ
+ *
+ * To compile:
+ * mpicxx -O2 transpose.cpp -o transpose -lpnetcdf
+ * To run:
+ * mpiexec -n num_processes ./transpose [filename] [len]
+ * where len decides the size of local array, which is len x len+1 x len+2.
+ * So, each variable is of size len*(len+1)*(len+2) * nprocs * sizeof(int)
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <iostream>
+using namespace std;
+
+#include <string.h> /* strlen() */
+#include <unistd.h> /* getopt() */
+#include <pnetcdf>
+
+using namespace PnetCDF;
+using namespace PnetCDF::exceptions;
+
+#define NDIMS 3
+
+#define HANDLE_ERROR { \
+ if (err != NC_NOERR) \
+ printf("Error at line %d (%s)\n", __LINE__, \
+ ncmpi_strerror(err)); \
+}
+
+static void
+usage(char *argv0)
+{
+ cerr <<
+ "Usage: %s [-h] | [-q] [file_name] [len]\n"
+ " [-h] Print this help\n"
+ " [-q] Quiet mode\n"
+ " [filename] output netCDF file name\n"
+ " [len] size of each dimension of the local array\n"
+ << argv0;
+}
+
+
+/*----< main() >------------------------------------------------------------*/
+int main(int argc, char **argv)
+{
+ extern int optind;
+ char filename[128], str[512];
+ int i, j, k, rank, nprocs, len, bufsize, verbose=1;
+ int *buf, psizes[NDIMS];
+ vector<MPI_Offset> gsizes(NDIMS), starts(NDIMS), counts(NDIMS), imap(NDIMS);
+ vector<MPI_Offset> startsT(NDIMS), countsT(NDIMS), strides(NDIMS);
+
+ MPI_Init(&argc,&argv);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+
+ /* get command-line arguments */
+ while ((i = getopt(argc, argv, "hq")) != EOF)
+ switch(i) {
+ case 'q': verbose = 0;
+ break;
+ case 'h':
+ default: if (rank==0) usage(argv[0]);
+ MPI_Finalize();
+ return 0;
+ }
+ argc -= optind;
+ argv += optind;
+ if (argc >= 1) strcpy(filename, argv[0]); /* optional argument */
+ else strcpy(filename, "testfile.nc");
+ len = 2;
+ if (argc >= 2) len = atoi(argv[1]); /* optional argument */
+
+ for (i=0; i<NDIMS; i++)
+ psizes[i] = 0;
+
+ /* calculate number of processes along each dimension */
+ MPI_Dims_create(nprocs, NDIMS, psizes);
+ if (verbose && rank == 0) {
+ sprintf(str, "psizes= ");
+ for (i=0; i<NDIMS; i++) sprintf(str+strlen(str), "%d ",psizes[i]);
+ printf("%s\n",str);
+ }
+
+ /* for each MPI rank, find its local rank IDs along each dimension in
+ * starts[] */
+ int lower_dims=1;
+ for (i=NDIMS-1; i>=0; i--) {
+ starts[i] = rank / lower_dims % psizes[i];
+ lower_dims *= psizes[i];
+ }
+ if (verbose) {
+ sprintf(str, "proc %d: dim rank= ", rank);
+ for (i=0; i<NDIMS; i++) sprintf(str+strlen(str), "%lld ",starts[i]);
+ printf("%s\n",str);
+ }
+
+ bufsize = 1;
+ for (i=0; i<NDIMS; i++) {
+ gsizes[i] = (len + i) * psizes[i]; /* global array size */
+ starts[i] *= (len + i); /* start indices */
+ counts[i] = (len + i); /* array elements */
+ bufsize *= (len + i);
+ }
+
+ /* allocate buffer and initialize with contiguous numbers */
+ buf = (int *) malloc(bufsize * sizeof(int));
+ for (k=0; k<counts[0]; k++)
+ for (j=0; j<counts[1]; j++)
+ for (i=0; i<counts[2]; i++)
+ buf[k*counts[1]*counts[2] +
+ j*counts[2] + i] = (starts[0]+k)*gsizes[1]*gsizes[2]
+ + (starts[1]+j)*gsizes[2]
+ + (starts[2]+i);
+
+ try {
+ /* create the file */
+ NcmpiFile nc(MPI_COMM_WORLD, filename, NcmpiFile::replace,
+ NcmpiFile::classic5);
+
+ /* define dimensions */
+ vector<NcmpiDim> dimids(NDIMS);
+ for (i=0; i<NDIMS; i++) {
+ sprintf(str, "%c", 'Z'-i);
+ dimids[i] = nc.addDim(str, gsizes[i]);
+ }
+
+
+ /* define variable with no transposed file layout: ZYX */
+ NcmpiVar ZYX_id = nc.addVar("ZYX_var", ncmpiInt, dimids);
+
+ /* define variable with transposed file layout: ZYX -> ZXY */
+ vector<NcmpiDim> dimidsT(NDIMS);
+ dimidsT[0] = dimids[0]; dimidsT[1] = dimids[2]; dimidsT[2] = dimids[1];
+ NcmpiVar ZXY_id = nc.addVar("ZXY_var", ncmpiInt, dimidsT);
+
+ /* define variable with transposed file layout: ZYX -> YZX */
+ dimidsT[0] = dimids[1]; dimidsT[1] = dimids[0]; dimidsT[2] = dimids[2];
+ NcmpiVar YZX_id = nc.addVar("YZX_var", ncmpiInt, dimidsT);
+
+ /* define variable with transposed file layout: ZYX -> YXZ */
+ dimidsT[0] = dimids[1]; dimidsT[1] = dimids[2]; dimidsT[2] = dimids[0];
+ NcmpiVar YXZ_id = nc.addVar("YXZ_var", ncmpiInt, dimidsT);
+
+ /* define variable with transposed file layout: ZYX -> XZY */
+ dimidsT[0] = dimids[2]; dimidsT[1] = dimids[0]; dimidsT[2] = dimids[1];
+ NcmpiVar XZY_id = nc.addVar("XZY_var", ncmpiInt, dimidsT);
+
+ /* define variable with transposed file layout: ZYX -> XYZ */
+ dimidsT[0] = dimids[2]; dimidsT[1] = dimids[1]; dimidsT[2] = dimids[0];
+ NcmpiVar XYZ_id = nc.addVar("XYZ_var", ncmpiInt, dimidsT);
+
+ /* write the whole variable in file: ZYX */
+ ZYX_id.putVar_all(starts, counts, &buf[0]);
+
+ strides[0] = strides[1] = strides[2] = 1;
+ /* ZYX -> ZXY: */
+ imap[1] = 1; imap[2] = counts[2]; imap[0] = counts[1]*counts[2];
+ startsT[0] = starts[0]; startsT[1] = starts[2]; startsT[2] = starts[1];
+ countsT[0] = counts[0]; countsT[1] = counts[2]; countsT[2] = counts[1];
+ /* write the transposed variable */
+ ZXY_id.putVar_all(startsT, countsT, strides, imap, &buf[0]);
+
+ /* ZYX -> YZX: */
+ imap[2] = 1; imap[0] = counts[2]; imap[1] = counts[1]*counts[2];
+ startsT[0] = starts[1]; startsT[1] = starts[0]; startsT[2] = starts[2];
+ countsT[0] = counts[1]; countsT[1] = counts[0]; countsT[2] = counts[2];
+ /* write the transposed variable */
+ YZX_id.putVar_all(startsT, countsT, strides, imap, &buf[0]);
+
+ /* ZYX -> YXZ: */
+ imap[1] = 1; imap[0] = counts[2]; imap[2] = counts[1]*counts[2];
+ startsT[0] = starts[1]; startsT[1] = starts[2]; startsT[2] = starts[0];
+ countsT[0] = counts[1]; countsT[1] = counts[2]; countsT[2] = counts[0];
+ /* write the transposed variable */
+ YXZ_id.putVar_all(startsT, countsT, strides, imap, &buf[0]);
+
+ /* ZYX -> XZY: */
+ imap[0] = 1; imap[2] = counts[2]; imap[1] = counts[1]*counts[2];
+ startsT[0] = starts[2]; startsT[1] = starts[0]; startsT[2] = starts[1];
+ countsT[0] = counts[2]; countsT[1] = counts[0]; countsT[2] = counts[1];
+ /* write the transposed variable */
+ XZY_id.putVar_all(startsT, countsT, strides, imap, &buf[0]);
+
+ /* ZYX -> XYZ: */
+ imap[0] = 1; imap[1] = counts[2]; imap[2] = counts[1]*counts[2];
+ startsT[0] = starts[2]; startsT[1] = starts[1]; startsT[2] = starts[0];
+ countsT[0] = counts[2]; countsT[1] = counts[1]; countsT[2] = counts[0];
+ /* write the transposed variable */
+ XYZ_id.putVar_all(startsT, countsT, strides, imap, &buf[0]);
+
+ /* file is close implicitly */
+ }
+ catch(NcmpiException& e) {
+ cout << e.what() << " error code=" << e.errorCode() << " Error!\n";
+ }
+
+ free(buf);
+
+ MPI_Finalize();
+ return 0;
+}
+
diff --git a/examples/CXX/vard_int.cpp b/examples/CXX/vard_int.cpp
new file mode 100644
index 0000000..d685ee2
--- /dev/null
+++ b/examples/CXX/vard_int.cpp
@@ -0,0 +1,209 @@
+/*********************************************************************
+ *
+ * Copyright (C) 2014, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ *
+ *********************************************************************/
+/* $Id: vard_int.cpp 2239 2015-12-18 18:21:09Z wkliao $ */
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * This example shows how to use the vard API ncmpi_put_vard() and
+ * ncmpi_get_vard() to write and read 2D record and fixed-size variables.
+ *
+ * To compile:
+ * mpicxx -O2 vard_int.cpp -o vard_int -lpnetcdf
+ *
+ * Example commands for MPI run and outputs from running ncmpidump on the
+ * NC file produced by this example program:
+ *
+ * % mpiexec -n 4 ./vard_int /pvfs2/wkliao/testfile.nc
+ *
+ * The expected results from the output file contents are:
+ *
+ * % ncmpidump /pvfs2/wkliao/testfile.nc
+ * netcdf testfile {
+ * // file format: CDF-1
+ * dimensions:
+ * REC_DIM = UNLIMITED ; // (2 currently)
+ * X = 12 ;
+ * FIX_DIM = 2 ;
+ * variables:
+ * int rec_var(REC_DIM, X) ;
+ * int fix_var(FIX_DIM, X) ;
+ * data:
+ *
+ * rec_var =
+ * 0, 1, 2, 100, 101, 102, 200, 201, 202, 300, 301, 302,
+ * 10, 11, 12, 110, 111, 112, 210, 211, 212, 310, 311, 312 ;
+ *
+ * fix_var =
+ * 0, 1, 2, 100, 101, 102, 200, 201, 202, 300, 301, 302,
+ * 10, 11, 12, 110, 111, 112, 210, 211, 212, 310, 311, 312 ;
+ * }
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <iostream>
+using namespace std;
+
+#include <string.h> /* strcpy() */
+#include <unistd.h> /* getopt() */
+#include <pnetcdf>
+
+using namespace PnetCDF;
+using namespace PnetCDF::exceptions;
+
+#define NY 2
+#define NX 3
+
+static void
+usage(char *argv0)
+{
+ cerr <<
+ "Usage: %s [-h] | [-q] [file_name]\n"
+ " [-h] Print help\n"
+ " [-q] Quiet mode (reports when fail)\n"
+ " [filename] output netCDF file name\n"
+ << argv0;
+}
+
+int main(int argc, char** argv)
+{
+ extern int optind;
+ char filename[128];
+ int i, j, verbose=1;
+ int rank, nprocs, array_of_blocklengths[2], buf[NY][NX];
+ int array_of_sizes[2], array_of_subsizes[2], array_of_starts[2];
+ MPI_Offset recsize, bufcount, len;
+ MPI_Aint array_of_displacements[2];
+ MPI_Datatype buftype, rec_filetype, fix_filetype;
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+
+ /* get command-line arguments */
+ while ((i = getopt(argc, argv, "hq")) != EOF)
+ switch(i) {
+ case 'q': verbose = 0;
+ break;
+ case 'h':
+ default: if (rank==0) usage(argv[0]);
+ MPI_Finalize();
+ return 0;
+ }
+ argc -= optind;
+ argv += optind;
+ if (argc == 1) strcpy(filename, argv[0]); /* optional argument */
+ else strcpy(filename, "testfile.nc");
+
+ vector <MPI_Offset> start(2), count(2);
+ start[0] = 0; start[1] = NX*rank;
+ count[0] = 2; count[1] = NX;
+ if (verbose)
+ printf("%d: start=%lld %lld count=%lld %lld\n",rank,
+ start[0],start[1],count[0],count[1]);
+
+ /* create a file type for the fixed-size variable */
+ array_of_sizes[0] = 2;
+ array_of_sizes[1] = NX*nprocs;
+ array_of_subsizes[0] = count[0];
+ array_of_subsizes[1] = count[1];
+ array_of_starts[0] = start[0];
+ array_of_starts[1] = start[1];
+ MPI_Type_create_subarray(2, array_of_sizes, array_of_subsizes,
+ array_of_starts, MPI_ORDER_C,
+ MPI_INT, &fix_filetype);
+ MPI_Type_commit(&fix_filetype);
+
+ buftype = MPI_INT;
+ bufcount = count[0] * count[1];
+
+ try {
+ /* create a new file for writing ------------------------------------*/
+ NcmpiFile nc(MPI_COMM_WORLD, filename, NcmpiFile::replace);
+
+ /* define 3 dimensions */
+ vector<NcmpiDim> recdimid(2);
+ recdimid[0] = nc.addDim("REC_DIM", NC_UNLIMITED);
+ recdimid[1] = nc.addDim("X", NX*nprocs);
+
+ vector<NcmpiDim> fixdimid(2);
+ fixdimid[0] = nc.addDim("FIX_DIM", 2);
+ fixdimid[1] = recdimid[1];
+
+ /* define a variable of size (NZ * nprocs) * NY */
+ NcmpiVar var0 = nc.addVar("rec_var", ncmpiInt, recdimid);
+
+ /* define a variable of size NY * (NX * nprocs) */
+ NcmpiVar var1 = nc.addVar("fix_var", ncmpiInt, fixdimid);
+
+ nc.enddef();
+
+ /* create a file type for the record variable */
+ recsize = nc.getRecSize();
+ for (i=0; i<count[0]; i++) {
+ array_of_blocklengths[i] = count[1];
+ array_of_displacements[i] = start[1]*sizeof(int) + recsize * i;
+ }
+ MPI_Type_create_hindexed(2, array_of_blocklengths,
+ array_of_displacements, MPI_INT, &rec_filetype);
+ MPI_Type_commit(&rec_filetype);
+
+ /* initialize the contents of the array */
+ for (j=0; j<NY; j++) for (i=0; i<NX; i++)
+ buf[j][i] = rank*100 + j*10 + i;
+
+ /* write the record variable */
+ var0.putVard_all(rec_filetype, buf, bufcount, buftype);
+
+ /* check if the number of records changed to 2 */
+ len = recdimid[0].getSize();
+ if (len != 2)
+ cout << "Error: number of records should be 2 but got " << len << "\n";
+
+ /* write the fixed-size variable */
+ var1.putVard_all(fix_filetype, buf, bufcount, buftype);
+
+ /* file is close implicitly */
+ }
+ catch(NcmpiException& e) {
+ cout << e.what() << " error code=" << e.errorCode() << " Error!\n";
+ }
+
+ try {
+ /* open file for reading -----------------------------------------*/
+ NcmpiFile nc(MPI_COMM_WORLD, filename, NcmpiFile::read);
+
+ NcmpiVar var0 = nc.getVar("rec_var");
+ NcmpiVar var1 = nc.getVar("fix_var");
+
+ /* read the record variable */
+ var0.getVard_all(rec_filetype, buf, bufcount, buftype);
+
+ /* read the fixed-size variable */
+ var1.getVard_all(fix_filetype, buf, bufcount, buftype);
+ }
+ catch(NcmpiException& e) {
+ cout << e.what() << " error code=" << e.errorCode() << " Error!\n";
+ }
+
+ MPI_Type_free(&rec_filetype);
+ MPI_Type_free(&fix_filetype);
+
+ /* check if there is any PnetCDF internal malloc residue */
+ MPI_Offset malloc_size, sum_size;
+ int err = ncmpi_inq_malloc_size(&malloc_size);
+ if (err == NC_NOERR) {
+ MPI_Reduce(&malloc_size, &sum_size, 1, MPI_OFFSET, MPI_SUM, 0, MPI_COMM_WORLD);
+ if (rank == 0 && sum_size > 0)
+ printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n",
+ sum_size);
+ }
+
+ MPI_Finalize();
+ return 0;
+}
+
diff --git a/examples/F77/Makefile.in b/examples/F77/Makefile.in
new file mode 100644
index 0000000..b033cab
--- /dev/null
+++ b/examples/F77/Makefile.in
@@ -0,0 +1,135 @@
+#
+# Copyright (C) 2012, Northwestern University and Argonne National Laboratory
+# See COPYRIGHT notice in top-level directory.
+#
+# $Id: Makefile.in 2236 2015-12-18 03:49:41Z wkliao $
+#
+# @configure_input@
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+include ../../macros.make
+
+# note the order of -L list matters
+INCLUDES = -I../../src/lib -I../../src/libf
+ifeq (@SIZEOF_MPI_AINT_IS_4@, yes)
+FPPFLAGS += -DSIZEOF_MPI_AINT_IS_4
+endif
+FLDFLAGS := -L../../src/lib $(FLDFLAGS) $(LDFLAGS)
+LIBS := -lpnetcdf $(LIBS)
+
+F77_SRCS = nonblocking_write.f \
+ column_wise.f \
+ block_cyclic.f \
+ flexible_api.f \
+ get_info.f \
+ hints.f \
+ put_vara.f \
+ put_varn_real.f \
+ put_varn_int.f \
+ transpose.f \
+ i_varn_real.f \
+ bput_varn_int8.f \
+ fill_mode.f
+
+F77F_SRCS = vard_int.F
+
+PROGS = $(F77_SRCS:.f=) $(F77F_SRCS:.F=)
+OBJS = $(F77_SRCS:.f=.o) $(F77F_SRCS:.F=.o)
+
+UTIL_SRCS = utils.F90
+UTIL_OBJS = $(UTIL_SRCS:.F90=.o)
+
+GARBAGE = $(PROGS) *.nc
+
+PACKING_LIST = $(F77_SRCS) $(F77F_SRCS) $(UTIL_SRCS) depend Makefile.in
+
+all: $(PROGS)
+
+install:
+
+uninstall:
+
+nonblocking_write: nonblocking_write.o $(UTIL_OBJS) $(LIBRARY)
+ $(LINK.F90) $< $(UTIL_OBJS) $(FLDFLAGS) $(LIBS)
+
+get_info: get_info.o $(UTIL_OBJS) $(LIBRARY)
+ $(LINK.F90) $< $(UTIL_OBJS) $(FLDFLAGS) $(LIBS)
+
+column_wise: column_wise.o $(UTIL_OBJS) $(LIBRARY)
+ $(LINK.F90) $< $(UTIL_OBJS) $(FLDFLAGS) $(LIBS)
+
+block_cyclic: block_cyclic.o $(UTIL_OBJS) $(LIBRARY)
+ $(LINK.F90) $< $(UTIL_OBJS) $(FLDFLAGS) $(LIBS)
+
+put_vara: put_vara.o $(UTIL_OBJS) $(LIBRARY)
+ $(LINK.F90) $< $(UTIL_OBJS) $(FLDFLAGS) $(LIBS)
+
+hints: hints.o $(UTIL_OBJS) $(LIBRARY)
+ $(LINK.F90) $< $(UTIL_OBJS) $(FLDFLAGS) $(LIBS)
+
+flexible_api: flexible_api.o $(UTIL_OBJS) $(LIBRARY)
+ $(LINK.F90) $< $(UTIL_OBJS) $(FLDFLAGS) $(LIBS)
+
+put_varn_int: put_varn_int.o $(UTIL_OBJS) $(LIBRARY)
+ $(LINK.F90) $< $(UTIL_OBJS) $(FLDFLAGS) $(LIBS)
+
+put_varn_real: put_varn_real.o $(UTIL_OBJS) $(LIBRARY)
+ $(LINK.F90) $< $(UTIL_OBJS) $(FLDFLAGS) $(LIBS)
+
+transpose: transpose.o $(UTIL_OBJS) $(LIBRARY)
+ $(LINK.F90) $< $(UTIL_OBJS) $(FLDFLAGS) $(LIBS)
+
+vard_int: vard_int.o $(UTIL_OBJS) $(LIBRARY)
+ $(LINK.F90) $< $(UTIL_OBJS) $(FLDFLAGS) $(LIBS)
+
+i_varn_real: i_varn_real.o $(UTIL_OBJS) $(LIBRARY)
+ $(LINK.F90) $< $(UTIL_OBJS) $(FLDFLAGS) $(LIBS)
+
+bput_varn_int8: bput_varn_int8.o $(UTIL_OBJS) $(LIBRARY)
+ $(LINK.F90) $< $(UTIL_OBJS) $(FLDFLAGS) $(LIBS)
+
+fill_mode: fill_mode.o $(UTIL_OBJS) $(LIBRARY)
+ $(LINK.F90) $< $(UTIL_OBJS) $(FLDFLAGS) $(LIBS)
+
+TEST_MPIRUN_4 = $(subst NP,4,$(TEST_MPIRUN))
+TEST_MPIRUN_8 = $(subst NP,8,$(TEST_MPIRUN))
+TEST_MPIRUN_3 = $(subst NP,3,$(TEST_MPIRUN))
+
+ptest4: $(PROGS)
+ @for i in $(PROGS); do ( \
+ $(TEST_MPIRUN_4) ./$$i -q $(TEST_OUTDIR)/testfile.nc ; \
+ if [ $$? = 0 ] ; then \
+ echo "PASS: F77 parallel run on 4 processes --------------- $$i"; \
+ else \
+ echo "FAILED: F77 parallel run on 4 processes ------------- $$i"; \
+ fi ; ) ; done
+
+ptest8: $(PROGS)
+ @for i in $(PROGS); do ( \
+ $(TEST_MPIRUN_8) ./$$i -q $(TEST_OUTDIR)/testfile.nc ; \
+ if [ $$? = 0 ] ; then \
+ echo "PASS: F77 parallel run on 8 processes --------------- $$i"; \
+ else \
+ echo "FAILED: F77 parallel run on 8 processes ------------- $$i"; \
+ fi ; ) ; done
+
+ptest3: $(PROGS)
+ @for i in $(PROGS); do ( \
+ $(TEST_MPIRUN_3) ./$$i -q $(TEST_OUTDIR)/testfile.nc ; \
+ if [ $$? = 0 ] ; then \
+ echo "PASS: F77 parallel run on 3 processes --------------- $$i"; \
+ else \
+ echo "FAILED: F77 parallel run on 3 processes ------------- $$i"; \
+ fi ; ) ; done
+
+ptest: ptest4
+ptests: ptest3 ptest4 ptest8
+ptest2 ptest6 ptest10:
+
+include $(srcdir)/depend
+include $(srcdir)/../../rules.make
+
+$(LIBRARY): ;
+
diff --git a/examples/F77/block_cyclic.f b/examples/F77/block_cyclic.f
new file mode 100644
index 0000000..66d3843
--- /dev/null
+++ b/examples/F77/block_cyclic.f
@@ -0,0 +1,284 @@
+!
+! Copyright (C) 2012, Northwestern University and Argonne National Laboratory
+! See COPYRIGHT notice in top-level directory.
+!
+! $Id: block_cyclic.f 2245 2015-12-20 18:39:52Z wkliao $
+
+
+! This example, generalized from column_wise.f, makes a number of nonblocking
+! API calls, each writes a block of columns into a 2D integer array. In other
+! words, the I/O pattern is a blocked cyclic along X dimension.
+!
+! Each process writes NX rows in total. The block length is controlled by
+! block_len. In this example, block_len is set to 2. Blocks are layout in a
+! cyclic fashion in the file. This example can test if PnetCDF can coalesce
+! file offsets and lengths when constructing a merged filetype.
+!
+! The compile and run commands are given below, together with an ncmpidump of
+! the output file. In this example, block_len = 2.
+!
+! % mpif77 -O2 -o block_cyclic block_cyclic.f -lpnetcdf
+! % mpiexec -n 4 ./block_cyclic /pvfs2/wkliao/testfile.nc
+!
+! % ncmpidump /pvfs2/wkliao/testfile.nc
+! netcdf testfile {
+! // file format: CDF-5 (big variables)
+! dimensions:
+! Y = 10 ;
+! X = 16 ;
+! variables:
+! int var(Y, X) ;
+! data:
+!
+! var =
+! 10, 10, 11, 11, 12, 12, 13, 13, 10, 10, 11, 11, 12, 12, 13, 13,
+! 10, 10, 11, 11, 12, 12, 13, 13, 10, 10, 11, 11, 12, 12, 13, 13,
+! 10, 10, 11, 11, 12, 12, 13, 13, 10, 10, 11, 11, 12, 12, 13, 13,
+! 10, 10, 11, 11, 12, 12, 13, 13, 10, 10, 11, 11, 12, 12, 13, 13,
+! 10, 10, 11, 11, 12, 12, 13, 13, 10, 10, 11, 11, 12, 12, 13, 13,
+! 10, 10, 11, 11, 12, 12, 13, 13, 10, 10, 11, 11, 12, 12, 13, 13,
+! 10, 10, 11, 11, 12, 12, 13, 13, 10, 10, 11, 11, 12, 12, 13, 13,
+! 10, 10, 11, 11, 12, 12, 13, 13, 10, 10, 11, 11, 12, 12, 13, 13,
+! 10, 10, 11, 11, 12, 12, 13, 13, 10, 10, 11, 11, 12, 12, 13, 13,
+! 10, 10, 11, 11, 12, 12, 13, 13, 10, 10, 11, 11, 12, 12, 13, 13 ;
+! }
+!
+
+ subroutine check(err, message)
+ implicit none
+ include "mpif.h"
+ include "pnetcdf.inc"
+ integer err
+ character message*(*)
+
+ ! It is a good idea to check returned value for possible error
+ if (err .NE. NF_NOERR) then
+ write(6,*) message//' '//nfmpi_strerror(err)
+ call MPI_Abort(MPI_COMM_WORLD, -1, err)
+ endif
+ end ! subroutine check
+
+ program main
+ implicit none
+ include "mpif.h"
+ include "pnetcdf.inc"
+
+ integer NY, NX
+ PARAMETER(NX=10, NY=4)
+
+ character*128 filename, cmd
+ integer i, j, rank, nprocs, err, ierr, num_reqs, get_args
+ integer ncid, cmode, varid, dimid(2), stride, block_len
+ integer buf(NX, NY)
+ integer reqs(NY), sts(NY)
+ integer*8 G_NY, myOff, block_start,
+ + global_nx, global_ny
+ integer*8 start(2), count(2)
+ integer*8 malloc_size, sum_size
+ logical verbose
+ integer dummy
+
+ call MPI_Init(err)
+ call MPI_Comm_rank(MPI_COMM_WORLD, rank, err)
+ call MPI_Comm_size(MPI_COMM_WORLD, nprocs, err)
+
+ ! take filename from command-line argument if there is any
+ if (rank .EQ. 0) then
+ verbose = .TRUE.
+ filename = "testfile.nc"
+ ierr = get_args(2, cmd, filename, verbose, dummy)
+ endif
+ call MPI_Bcast(ierr, 1, MPI_INTEGER, 0, MPI_COMM_WORLD, err)
+ if (ierr .EQ. 0) goto 999
+
+ call MPI_Bcast(verbose, 1, MPI_LOGICAL, 0, MPI_COMM_WORLD,
+ + err)
+ call MPI_Bcast(filename, 256, MPI_CHARACTER, 0,
+ + MPI_COMM_WORLD, err)
+
+ ! create file, truncate it if exists
+ cmode = IOR(NF_CLOBBER, NF_64BIT_DATA)
+ err = nfmpi_create(MPI_COMM_WORLD, filename, cmode,
+ + MPI_INFO_NULL, ncid)
+ call check(err, 'In nfmpi_create: ')
+
+ ! the global array is NX * (NY * nprocs) */
+ G_NY = NY * nprocs
+ myOff = NY * rank
+
+ ! define dimensions
+ global_nx = NX
+ err = nfmpi_def_dim(ncid, 'Y', global_nx, dimid(2))
+ call check(err, 'In nfmpi_def_dim Y')
+
+ err = nfmpi_def_dim(ncid, 'X', G_NY, dimid(1))
+ call check(err, 'In nfmpi_def_dim X')
+
+ err = nfmpi_def_var(ncid, 'var', NF_INT, 2, dimid, varid)
+ call check(err, 'In nfmpi_def_var var')
+
+ ! do not forget to exit define mode
+ err = nfmpi_enddef(ncid)
+ call check(err, 'In nfmpi_enddef: ')
+
+ ! First, fill the entire array with zeros, using a blocking I/O.
+ ! Every process writes a subarray of size NX * NY
+ do i=1, NY
+ do j=1, NX
+ buf(j,i) = 0
+ enddo
+ enddo
+ start(1) = myOff+1
+ start(2) = 1
+ count(1) = NY
+ count(2) = NX
+ err = nfmpi_put_vara_int_all(ncid, varid, start, count, buf)
+ call check(err, 'In nfmpi_put_vara_int_all: ')
+
+ ! initialize the buffer with rank ID
+ do i=1, NY
+ do j=1, NX
+ buf(j,i) = rank+10
+ enddo
+ enddo
+
+ ! each proc writes NY columns of the 2D array, block_len controls the
+ ! the number of contiguous columns at a time
+ block_start = 0
+ block_len = 2 ! can be 1, 2, 3, ..., NY
+ if (block_len .GT. NY) block_len = NY
+
+ start(1) = rank * block_len + 1
+ start(2) = 1
+ count(1) = 1
+ count(2) = NX
+ num_reqs = 0
+
+ do i=1, NY
+ num_reqs = num_reqs + 1
+ err = nfmpi_iput_vara_int(ncid, varid, start, count,
+ + buf(1,i), reqs(num_reqs))
+ call check(err, 'In nfmpi_iput_vara_int: ')
+
+ if (MOD(i, block_len) .EQ. 0) then
+ stride = NY-i
+ if (stride .GT. block_len) stride = block_len
+ block_start = block_start + block_len * nprocs
+ start(1) = block_start + stride * rank + 1
+ else
+ start(1) = start(1) + 1
+ endif
+ enddo
+
+ err = nfmpi_wait_all(ncid, num_reqs, reqs, sts)
+ call check(err, 'In nfmpi_wait_all: ')
+
+ ! check status of all requests
+ do i=1, num_reqs
+ if (sts(i) .NE. NF_NOERR) then
+ print*, "Error: nonblocking write fails on request",
+ + i, ' ', nfmpi_strerror(sts(i))
+ endif
+ enddo
+
+ err = nfmpi_close(ncid)
+ call check(err, 'In nfmpi_close: ')
+
+ ! open an existing file created earlier for read
+ err = nfmpi_open(MPI_COMM_WORLD, filename, NF_NOWRITE,
+ + MPI_INFO_NULL, ncid)
+ call check(err, 'In nfmpi_open: ')
+
+ ! the global array is NX * (NY * nprocs) */
+ err = nfmpi_inq_dimid(ncid, "X", dimid(1))
+ call check(err, 'In nfmpi_inq_dimid X: ')
+ err = nfmpi_inq_dimlen(ncid, dimid(1), global_ny)
+ call check(err, 'In nfmpi_inq_dimlen: ')
+ ! G_NY must == NY * nprocs
+ ! myNY must == global_ny / nprocs
+
+ err = nfmpi_inq_dimid(ncid, "Y", dimid(2))
+ call check(err, 'In nfmpi_inq_dimid Y: ')
+ err = nfmpi_inq_dimlen(ncid, dimid(2), global_nx)
+ call check(err, 'In nfmpi_inq_dimlen: ')
+ ! global_nx must == NX
+
+ err = nfmpi_inq_varid(ncid, "var", varid)
+ call check(err, 'In nfmpi_inq_varid: ')
+
+ ! initialize the buffer with -1, so a read error can be pinpointed
+ do i=1, NY
+ do j=1, NX
+ buf(j,i) = -1
+ enddo
+ enddo
+
+ ! each proc reads NY columns of the 2D array, block_len controls the
+ ! the number of contiguous columns at a time */
+ block_start = 0
+ block_len = 2 ! can be 1, 2, 3, ..., NY
+ if (block_len .GT. NY) block_len = NY
+
+ start(1) = rank * block_len + 1
+ start(2) = 1
+ count(1) = 1
+ count(2) = global_nx
+ num_reqs = 0
+
+ do i=1, NY
+ num_reqs = num_reqs + 1
+ err = nfmpi_iget_vara_int(ncid, varid, start, count,
+ + buf(1,i), reqs(num_reqs))
+ call check(err, 'In nfmpi_iget_vara_int: ')
+
+ if (MOD(i, block_len) .EQ. 0) then
+ stride = NY-i
+ if (stride .GT. block_len) stride = block_len
+ block_start = block_start + block_len * nprocs
+ start(1) = block_start + stride * rank + 1
+ else
+ start(1) = start(1) + 1
+ endif
+ enddo
+
+ err = nfmpi_wait_all(ncid, num_reqs, reqs, sts)
+ call check(err, 'In nfmpi_wait_all: ')
+
+ ! check status of all requests
+ do i=1, num_reqs
+ if (sts(i) .NE. NF_NOERR) then
+ print*, "Error: nonblocking write fails on request",
+ + i, ' ', nfmpi_strerror(sts(i))
+ endif
+ enddo
+
+ err = nfmpi_close(ncid)
+ call check(err, 'In nfmpi_close: ')
+
+ ! check the read contents */
+ do j=1, NY
+ do i=1, NX
+ if (buf(i,j) .NE. rank+10) then
+ print*, 'Read contents mismatch at buf i=', i,
+ + ' j=',j,' =', buf(i,j),' (should be ',
+ + rank+10, ')\n'
+ endif
+ enddo
+ enddo
+
+ ! check if there is any PnetCDF internal malloc residue
+ 998 format(A,I13,A)
+ err = nfmpi_inq_malloc_size(malloc_size)
+ if (err .EQ. NF_NOERR) then
+ call MPI_Reduce(malloc_size, sum_size, 1, MPI_OFFSET,
+ + MPI_SUM, 0, MPI_COMM_WORLD, err)
+ if (rank .EQ. 0 .AND. sum_size .GT. 0)
+ + print 998,
+ + 'heap memory allocated by PnetCDF internally has ',
+ + sum_size/1048576, ' MiB yet to be freed'
+ endif
+
+ 999 call MPI_Finalize(err)
+ ! call EXIT(0) ! EXIT() is a GNU extension
+
+ end ! program main
diff --git a/examples/F77/bput_varn_int8.f b/examples/F77/bput_varn_int8.f
new file mode 100644
index 0000000..6cb2a42
--- /dev/null
+++ b/examples/F77/bput_varn_int8.f
@@ -0,0 +1,344 @@
+!
+! Copyright (C) 2014, Northwestern University
+! See COPYRIGHT notice in top-level directory.
+!
+! $Id: bput_varn_int8.f 2224 2015-12-16 06:10:36Z wkliao $
+
+! This example tests nonblocking varn API: nfmpi_bput_varn_int8()
+! It writes a sequence of requests with arbitrary array indices and
+! lengths to four variables of type NF_INT64
+!
+! The compile and run commands are given below, together with an
+! ncmpidump of the output file.
+!
+! The compile and run commands are given below, together with an ncmpidump of
+! the output file.
+!
+! % mpif77 -O2 -o bput_varn_int8 bput_varn_int8.f -lpnetcdf
+! % mpiexec -n 4 ./bput_varn_int8 /pvfs2/wkliao/testfile.nc
+! % ncmpidump /pvfs2/wkliao/testfile.nc
+! netcdf testfile {
+! // file format: CDF-5 (big variables)
+! dimensions:
+! Y = 4 ;
+! X = 10 ;
+! variables:
+! int64 var0(Y, X) ;
+! int64 var1(Y, X) ;
+! int64 var2(Y, X) ;
+! int64 var3(Y, X) ;
+! data:
+!
+! var0 =
+! 1, 0, 3, 0,
+! 1, 2, 3, 0,
+! 1, 2, 2, 0,
+! 3, 2, 1, 2,
+! 3, 1, 1, 3,
+! 0, 3, 1, 3,
+! 0, 3, 0, 3,
+! 2, 2, 0, 1,
+! 3, 2, 3, 1,
+! 3, 2, 3, 1 ;
+!
+! var1 =
+! 2, 1, 0, 1,
+! 2, 3, 0, 1,
+! 2, 3, 3, 1,
+! 0, 3, 2, 3,
+! 0, 2, 2, 0,
+! 1, 0, 2, 0,
+! 1, 0, 1, 0,
+! 3, 3, 1, 2,
+! 0, 3, 0, 2,
+! 0, 3, 0, 2 ;
+!
+! var2 =
+! 3, 2, 1, 2,
+! 3, 0, 1, 2,
+! 3, 0, 0, 2,
+! 1, 0, 3, 0,
+! 1, 3, 3, 1,
+! 2, 1, 3, 1,
+! 2, 1, 2, 1,
+! 0, 0, 2, 3,
+! 1, 0, 1, 3,
+! 1, 0, 1, 3 ;
+!
+! var3 =
+! 0, 3, 2, 3,
+! 0, 1, 2, 3,
+! 0, 1, 1, 3,
+! 2, 1, 0, 1,
+! 2, 0, 0, 2,
+! 3, 2, 0, 2,
+! 3, 2, 3, 2,
+! 1, 1, 3, 0,
+! 2, 1, 2, 0,
+! 2, 1, 2, 0 ;
+! }
+!
+! Note the above dump is in C order
+!
+ subroutine check(err, message)
+ implicit none
+ include "mpif.h"
+ include "pnetcdf.inc"
+ integer err
+ character message*(*)
+
+ ! It is a good idea to check returned value for possible error
+ if (err .NE. NF_NOERR) then
+ write(6,*) message//' '//nfmpi_strerror(err)
+ call MPI_Abort(MPI_COMM_WORLD, -1, err)
+ endif
+ end
+
+ program main
+ implicit none
+ include "mpif.h"
+ include "pnetcdf.inc"
+
+ integer NDIMS
+ integer*8 NX, NY
+ PARAMETER(NDIMS=2, NX=4, NY=10)
+
+ character*128 filename, cmd
+ integer i, j, k, n, err, ierr, nprocs, rank, get_args
+ integer cmode, ncid, varid(4), dimid(NDIMS), nreqs
+ integer reqs(4), sts(4), num_segs(4)
+
+ integer*8 start(NDIMS, 6, 4), count(NDIMS, 6, 4)
+ integer*8 malloc_size, sum_size, two
+ integer*8 req_len, bbufsize
+ integer*8 buffer(NX*NY,4)
+ logical verbose
+ integer dummy
+
+ call MPI_Init(err)
+ call MPI_Comm_rank(MPI_COMM_WORLD, rank, err)
+ call MPI_Comm_size(MPI_COMM_WORLD, nprocs, err)
+
+ two = 2
+ ! take filename from command-line argument if there is any
+ if (rank .EQ. 0) then
+ verbose = .TRUE.
+ filename = "testfile.nc"
+ ierr = get_args(2, cmd, filename, verbose, dummy)
+ endif
+ call MPI_Bcast(ierr, 1, MPI_INTEGER, 0, MPI_COMM_WORLD, err)
+ if (ierr .EQ. 0) goto 999
+
+ call MPI_Bcast(verbose, 1, MPI_LOGICAL, 0, MPI_COMM_WORLD,
+ + err)
+ call MPI_Bcast(filename, 256, MPI_CHARACTER, 0,
+ + MPI_COMM_WORLD, err)
+
+ if (nprocs .NE. 4 .AND. rank .EQ. 0 .AND. verbose)
+ + print*,'Warning: ',cmd,' is intended to run on ',
+ + '4 processes'
+
+ ! create file, truncate it if exists
+ cmode = IOR(NF_CLOBBER, NF_64BIT_DATA)
+ err = nfmpi_create(MPI_COMM_WORLD, filename, cmode,
+ + MPI_INFO_NULL, ncid)
+ call check(err, 'In nfmpi_create: ')
+
+ ! define dimensions x and y
+ err = nfmpi_def_dim(ncid, "Y", NY, dimid(2))
+ call check(err, 'In nfmpi_def_dim Y: ')
+ err = nfmpi_def_dim(ncid, "X", NX, dimid(1))
+ call check(err, 'In nfmpi_def_dim X: ')
+
+ ! define 4 2D variables of int64 type
+ err = nfmpi_def_var(ncid, "var0", NF_INT64, two,
+ + dimid,varid(1))
+ call check(err, 'In nfmpi_def_var var0: ')
+ err = nfmpi_def_var(ncid, "var1", NF_INT64, two,
+ + dimid,varid(2))
+ call check(err, 'In nfmpi_def_var var1: ')
+ err = nfmpi_def_var(ncid, "var2", NF_INT64, two,
+ + dimid,varid(3))
+ call check(err, 'In nfmpi_def_var var2: ')
+ err = nfmpi_def_var(ncid, "var3", NF_INT64, two,
+ + dimid,varid(4))
+ call check(err, 'In nfmpi_def_var var3: ')
+
+ ! do not forget to exit define mode
+ err = nfmpi_enddef(ncid)
+ call check(err, 'In nfmpi_enddef: ')
+
+ ! now we are in data mode
+ n = mod(rank, 4) + 1
+ num_segs(n) = 4 ! number of segments for this request
+ start(1,1,n)=1
+ start(2,1,n)=6
+ count(1,1,n)=1
+ count(2,1,n)=2
+ start(1,2,n)=2
+ start(2,2,n)=1
+ count(1,2,n)=1
+ count(2,2,n)=1
+ start(1,3,n)=3
+ start(2,3,n)=7
+ count(1,3,n)=1
+ count(2,3,n)=2
+ start(1,4,n)=4
+ start(2,4,n)=1
+ count(1,4,n)=1
+ count(2,4,n)=3
+ ! start(:,:,n) n_count(:,:,n) indicate the following:
+ ! ("-" means skip)
+ ! - - - - - X X - - -
+ ! X - - - - - - - - -
+ ! - - - - - - X X - -
+ ! X X X - - - - - - -
+
+ n = mod(rank+1, 4) + 1
+ num_segs(n) = 6 ! number of segments for this request
+ start(1,1,n)=1
+ start(2,1,n)=4
+ count(1,1,n)=1
+ count(2,1,n)=2
+ start(1,2,n)=1
+ start(2,2,n)=9
+ count(1,2,n)=1
+ count(2,2,n)=2
+ start(1,3,n)=2
+ start(2,3,n)=6
+ count(1,3,n)=1
+ count(2,3,n)=2
+ start(1,4,n)=3
+ start(2,4,n)=1
+ count(1,4,n)=1
+ count(2,4,n)=2
+ start(1,5,n)=3
+ start(2,5,n)=9
+ count(1,5,n)=1
+ count(2,5,n)=2
+ start(1,6,n)=4
+ start(2,6,n)=5
+ count(1,6,n)=1
+ count(2,6,n)=3
+ ! start(:,:,n) n_count(:,:,n) indicate the following:
+ ! - - - X X - - - X X
+ ! - - - - - X X - - -
+ ! X X - - - - - - X X
+ ! - - - - X X X - - -
+
+ n = mod(rank+2, 4) + 1
+ num_segs(n) = 5 ! number of segments for this request
+ start(1,1,n)=1
+ start(2,1,n)=8
+ count(1,1,n)=1
+ count(2,1,n)=1
+ start(1,2,n)=2
+ start(2,2,n)=2
+ count(1,2,n)=1
+ count(2,2,n)=3
+ start(1,3,n)=2
+ start(2,3,n)=8
+ count(1,3,n)=1
+ count(2,3,n)=3
+ start(1,4,n)=3
+ start(2,4,n)=3
+ count(1,4,n)=1
+ count(2,4,n)=1
+ start(1,5,n)=4
+ start(2,5,n)=4
+ count(1,5,n)=1
+ count(2,5,n)=1
+ ! start(:,:,n) n_count(:,:,n) indicate the following:
+ ! - - - - - - - X - -
+ ! - X X X - - - X X X
+ ! - - X - - - - - - -
+ ! - - - X - - - - - -
+
+ n = mod(rank+3, 4) + 1
+ num_segs(n) = 4 ! number of segments for this request
+ start(1,1,n)=1
+ start(2,1,n)=1
+ count(1,1,n)=1
+ count(2,1,n)=3
+ start(1,2,n)=2
+ start(2,2,n)=5
+ count(1,2,n)=1
+ count(2,2,n)=1
+ start(1,3,n)=3
+ start(2,3,n)=4
+ count(1,3,n)=1
+ count(2,3,n)=3
+ start(1,4,n)=4
+ start(2,4,n)=8
+ count(1,4,n)=1
+ count(2,4,n)=3
+ ! start(:,:,n) n_count(:,:,n) indicate the following:
+ ! X X X - - - - - - -
+ ! - - - - X - - - - -
+ ! - - - X X X - - - -
+ ! - - - - - - - X X X
+
+ ! only rank 0, 1, 2, and 3 do I/O:
+ ! each of ranks 0 to 3 write 4 nonblocking requests
+ nreqs = 4
+ if (rank .GE. 4) nreqs = 0
+
+ ! initialize buffer contents
+ do i=1, 4
+ do j=1, NX*NY
+ buffer(j,i) = rank
+ enddo
+ enddo
+
+ ! bbufsize must be max of data type converted before and after
+ bbufsize = 0
+ do i=1, nreqs
+ do j=1, num_segs(i)
+ req_len = 1
+ do k=1, NDIMS
+ req_len = req_len * count(k,j,i)
+ enddo
+ bbufsize = bbufsize + req_len
+ enddo
+ enddo
+ bbufsize = bbufsize * 8 ! 8 is size of integer(kind=8)
+ if (bbufsize .GT. 0) then
+ err = nfmpi_buffer_attach(ncid, bbufsize)
+ call check(err, 'In nfmpi_buffer_attach')
+ endif
+
+ do i=1, nreqs
+ err = nfmpi_bput_varn_int8(ncid, varid(i), num_segs(i),
+ + start(1,1,i), count(1,1,i),
+ + buffer(1,i), reqs(i))
+ call check(err, 'In nfmpi_bput_varn_int8: ')
+ enddo
+ err = nfmpi_wait_all(ncid, nreqs, reqs, sts)
+ call check(err, 'In nfmpi_wait_all: ')
+
+ ! detach the temporary buffer
+ if (bbufsize .GT. 0) then
+ err = nfmpi_buffer_detach(ncid)
+ call check(err, 'In nfmpi_buffer_detach: ')
+ endif
+
+ ! close the file
+ err = nfmpi_close(ncid)
+ call check(err, 'In nfmpi_close: ')
+
+ ! check if there is any PnetCDF internal malloc residue
+ 998 format(A,I13,A)
+ err = nfmpi_inq_malloc_size(malloc_size)
+ if (err .EQ. NF_NOERR) then
+ call MPI_Reduce(malloc_size, sum_size, 1, MPI_OFFSET,
+ + MPI_SUM, 0, MPI_COMM_WORLD, err)
+ if (rank .EQ. 0 .AND. sum_size .GT. 0)
+ + print 998,
+ + 'heap memory allocated by PnetCDF internally has ',
+ + sum_size, ' B yet to be freed'
+ endif
+
+ 999 call MPI_Finalize(err)
+ ! call EXIT(0) ! EXIT() is a GNU extension
+ end
+
diff --git a/examples/F77/column_wise.f b/examples/F77/column_wise.f
new file mode 100644
index 0000000..613b5c7
--- /dev/null
+++ b/examples/F77/column_wise.f
@@ -0,0 +1,196 @@
+!
+! Copyright (C) 2012, Northwestern University and Argonne National Laboratory
+! See COPYRIGHT notice in top-level directory.
+!
+! $Id: column_wise.f 2245 2015-12-20 18:39:52Z wkliao $
+
+! This example makes a number of nonblocking API calls, each writes a single
+! row of a 2D integer array. Each process writes NY rows and any two
+! consecutive rows are of nprocs-row distance apart from each other.
+! In this case, the fileview of each process interleaves with all other processes.
+! If simply concatenating fileviews of all the nonblocking calls will result
+! in a fileview that violates the MPI-IO requirement on the fileview of which
+! flattened file offsets must be monotonically non-decreasing. PnetCDF handles
+! this case by breaking down each nonblocking call into a list of offset-length
+! pairs, merging the pairs across multiple nonblocking calls, and sorting
+! them into an increasing order. The sorted pairs are used to construct a
+! fileview that meets the monotonically non-decreasing offset requirement,
+! and thus the nonblocking requests can be serviced by a single MPI-IO call.
+!
+! The compile and run commands are given below, together with an ncmpidump of
+! the output file. Note ncdump is in C order (row major).
+!
+! % mpif77 -O2 -o column_wise column_wise.f -lpnetcdf
+! % mpiexec -n 4 ./column_wise /pvfs2/wkliao/testfile.nc
+!
+! % ncmpidump /pvfs2/wkliao/testfile.nc
+! netcdf testfile {
+! // file format: CDF-5 (big variables)
+! dimensions:
+! Y = 10 ;
+! X = 16 ;
+! variables:
+! int var(Y, X) ;
+! data:
+!
+! var =
+! 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3,
+! 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3,
+! 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3,
+! 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3,
+! 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3,
+! 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3,
+! 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3,
+! 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3,
+! 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3,
+! 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3 ;
+! }
+!
+
+ subroutine check(err, message)
+ implicit none
+ include "mpif.h"
+ include "pnetcdf.inc"
+ integer err
+ character message*(*)
+
+ ! It is a good idea to check returned value for possible error
+ if (err .NE. NF_NOERR) then
+ write(6,*) message//' '//nfmpi_strerror(err)
+ call MPI_Abort(MPI_COMM_WORLD, -1, err)
+ end if
+ end ! subroutine check
+
+ program main
+ implicit none
+ include "mpif.h"
+ include "pnetcdf.inc"
+
+ integer NY, NX
+ PARAMETER(NX=10, NY=4)
+
+ character*128 filename, cmd
+ integer i, j, rank, nprocs, err, ierr, num_reqs, get_args
+ integer ncid, cmode, varid, dimid(2)
+ integer buf(NX, NY)
+ integer reqs(NY), sts(NY)
+ integer*8 G_NY, myOff, block_start, block_len, global_nx
+ integer*8 start(2), count(2)
+ integer*8 malloc_size, sum_size
+ logical verbose
+ integer dummy
+
+ call MPI_Init(err)
+ call MPI_Comm_rank(MPI_COMM_WORLD, rank, err)
+ call MPI_Comm_size(MPI_COMM_WORLD, nprocs, err)
+
+ ! take filename from command-line argument if there is any
+ if (rank .EQ. 0) then
+ verbose = .TRUE.
+ filename = "testfile.nc"
+ ierr = get_args(2, cmd, filename, verbose, dummy)
+ endif
+ call MPI_Bcast(ierr, 1, MPI_INTEGER, 0, MPI_COMM_WORLD, err)
+ if (ierr .EQ. 0) goto 999
+
+ call MPI_Bcast(verbose, 1, MPI_LOGICAL, 0, MPI_COMM_WORLD,
+ + err)
+ call MPI_Bcast(filename, 256, MPI_CHARACTER, 0,
+ + MPI_COMM_WORLD, err)
+
+ ! create file, truncate it if exists
+ cmode = IOR(NF_CLOBBER, NF_64BIT_DATA)
+ err = nfmpi_create(MPI_COMM_WORLD, filename, cmode,
+ + MPI_INFO_NULL, ncid)
+ call check(err, 'In nfmpi_create: ')
+
+ ! the global array is NX * (NY * nprocs) */
+ G_NY = NY * nprocs
+ myOff = NY * rank
+
+ ! define dimensions
+ global_nx = NX
+ err = nfmpi_def_dim(ncid, 'Y', global_nx, dimid(2))
+ call check(err, 'In nfmpi_def_dim Y')
+
+ err = nfmpi_def_dim(ncid, 'X', G_NY, dimid(1))
+ call check(err, 'In nfmpi_def_dim X')
+
+ err = nfmpi_def_var(ncid, 'var', NF_INT, 2, dimid, varid)
+ call check(err, 'In nfmpi_def_var var')
+
+ ! do not forget to exit define mode
+ err = nfmpi_enddef(ncid)
+ call check(err, 'In nfmpi_enddef: ')
+
+ ! First, fill the entire array with zeros, using a blocking I/O.
+ ! Every process writes a subarray of size NX * NY
+ do i=1, NY
+ do j=1, NX
+ buf(j,i) = 0
+ enddo
+ enddo
+ start(1) = myOff+1
+ start(2) = 1
+ count(1) = NY
+ count(2) = NX
+ err = nfmpi_put_vara_int_all(ncid, varid, start, count, buf)
+ call check(err, 'In nfmpi_put_vara_int_all: ')
+
+ ! initialize the buffer with rank ID
+ do i=1, NY
+ do j=1, NX
+ buf(j,i) = rank
+ enddo
+ enddo
+
+ ! each proc writes NY columns of the 2D array, block_len controls the
+ ! the number of contiguous columns at a time
+ block_start = 0
+ block_len = 2 ! can be 1, 2, 3, ..., NY
+ if (block_len .GT. NY) block_len = NY
+
+ start(1) = rank + 1
+ start(2) = 1
+ count(1) = 1
+ count(2) = NX
+ num_reqs = 0
+
+ do i=1, NY
+ num_reqs = num_reqs + 1
+ err = nfmpi_iput_vara_int(ncid, varid, start, count,
+ + buf(1,i), reqs(num_reqs))
+ call check(err, 'In nfmpi_iput_vara_int: ')
+
+ start(1) = start(1) + nprocs
+ enddo
+
+ err = nfmpi_wait_all(ncid, num_reqs, reqs, sts)
+ call check(err, 'In nfmpi_wait_all: ')
+
+ ! check status of all requests
+ do i=1, num_reqs
+ if (sts(i) .NE. NF_NOERR) then
+ print*, "Error: nonblocking write fails on request",
+ + i, ' ', nfmpi_strerror(sts(i))
+ endif
+ enddo
+
+ err = nfmpi_close(ncid)
+ call check(err, 'In nfmpi_close: ')
+
+ ! check if there is any PnetCDF internal malloc residue
+ 998 format(A,I13,A)
+ err = nfmpi_inq_malloc_size(malloc_size)
+ if (err .EQ. NF_NOERR) then
+ call MPI_Reduce(malloc_size, sum_size, 1, MPI_OFFSET,
+ + MPI_SUM, 0, MPI_COMM_WORLD, err)
+ if (rank .EQ. 0 .AND. sum_size .GT. 0)
+ + print 998,
+ + 'heap memory allocated by PnetCDF internally has ',
+ + sum_size/1048576, ' MiB yet to be freed'
+ endif
+
+ 999 call MPI_Finalize(err)
+ ! call EXIT(0) ! EXIT() is a GNU extension
+ end ! program main
diff --git a/examples/F77/depend b/examples/F77/depend
new file mode 100644
index 0000000..63b2521
--- /dev/null
+++ b/examples/F77/depend
@@ -0,0 +1,14 @@
+block_cyclic.o: block_cyclic.f
+column_wise.o: column_wise.f
+flexible_api.o: flexible_api.f
+get_info.o: get_info.f
+hints.o: hints.f
+nonblocking_write.o: nonblocking_write.f
+put_vara.o: put_vara.f
+put_varn_real.o: put_varn_real.f
+put_varn_int.o: put_varn_int.f
+transpose.o: transpose.f
+vard_int.o: vard_int.F
+i_varn_real.o: i_varn_real.f
+bput_varn_int8.o: bput_varn_int8.f
+fill_mode.o: fill_mode.f
diff --git a/examples/F77/fill_mode.f b/examples/F77/fill_mode.f
new file mode 100644
index 0000000..3d20c8b
--- /dev/null
+++ b/examples/F77/fill_mode.f
@@ -0,0 +1,227 @@
+!
+! Copyright (C) 2015, Northwestern University
+! See COPYRIGHT notice in top-level directory.
+!
+! $Id: fill_mode.f 2245 2015-12-20 18:39:52Z wkliao $
+
+!
+! This example shows how to use
+! 1. nfmpi_set_fill() to enable fill mode
+! 2. nfmpi_def_var_fill() to define the variable's fill value
+! 3. nfmpi_inq_var_fill() to inquire the variable's fill mode information
+! 4. nfmpi_put_vara_int_all() to write two 2D 4-byte integer array in parallel.
+! It first defines a netCDF record variable of size global_nx * NFMPI_UNLIMITED
+! where
+! global_nx == (nx * number of MPI processes) and
+! It then defines a netCDF variable of size global_nx * global_ny where
+! global_nx == (nx * number of MPI processes) and
+! global_ny == ny
+! The data partitioning pattern for both variables are a column-wise
+! partitioning across all processes. Each process writes a subarray of size
+! nx * ny. Note the description above follows the Fortran array index order.
+!
+! Example commands for MPI run and outputs from running ncmpidump on the
+! NC file produced by this example program:
+!
+! % mpif77 -O2 -o fill_mode fill_mode.f -lpnetcdf
+! % mpiexec -n 4 ./fill_mode /pvfs2/wkliao/testfile.nc
+!
+! % ncmpidump /pvfs2/wkliao/testfile.nc
+! netcdf testfile {
+! // file format: CDF-5 (big variables)
+! dimensions:
+! REC_DIM = UNLIMITED ; // (2 currently)
+! X = 20 ;
+! Y = 3 ;
+! variables:
+! int rec_var(REC_DIM, X) ;
+! rec_var:_FillValue = -1 ;
+! int fix_var(Y, X) ;
+! fix_var:_FillValue = -2147483647 ;
+! data:
+!
+! rec_var =
+! 0, 0, 0, 0, _, 1, 1, 1, 1, _, 2, 2, 2, 2, _, 3, 3, 3, 3, _,
+! 0, 0, 0, 0, _, 1, 1, 1, 1, _, 2, 2, 2, 2, _, 3, 3, 3, 3, _ ;
+!
+! fix_var =
+! 0, 0, 0, 0, _, 1, 1, 1, 1, _, 2, 2, 2, 2, _, 3, 3, 3, 3, _,
+! 0, 0, 0, 0, _, 1, 1, 1, 1, _, 2, 2, 2, 2, _, 3, 3, 3, 3, _,
+! 0, 0, 0, 0, _, 1, 1, 1, 1, _, 2, 2, 2, 2, _, 3, 3, 3, 3, _ ;
+! }
+!
+ subroutine check(err, message)
+ implicit none
+ include 'mpif.h'
+ include 'pnetcdf.inc'
+ integer err
+ character message*(*)
+
+ ! It is a good idea to check returned value for possible error
+ if (err .NE. NF_NOERR) then
+ write(6,*) message//' '//nfmpi_strerror(err)
+ call MPI_Abort(MPI_COMM_WORLD, -1, err)
+ end if
+ end ! subroutine check
+
+ program main
+ implicit none
+ include 'mpif.h'
+ include 'pnetcdf.inc'
+
+ character*128 filename, cmd
+ integer i, j, err, ierr, nprocs, rank, get_args
+ integer cmode, ncid, rec_varid, fix_varid, dimid(2)
+ integer no_fill, fill_value, old_mode
+ integer*8 nx, ny, global_nx, global_ny, one
+ integer*8 starts(2), counts(2)
+ PARAMETER(nx=5, ny=3)
+ integer buf(nx,ny)
+ integer*8 malloc_size, sum_size
+ logical verbose
+ integer dummy
+
+ call MPI_Init(err)
+ call MPI_Comm_rank(MPI_COMM_WORLD, rank, err)
+ call MPI_Comm_size(MPI_COMM_WORLD, nprocs, err)
+
+ one = 1
+ ! take filename from command-line argument if there is any
+ if (rank .EQ. 0) then
+ verbose = .TRUE.
+ filename = "testfile.nc"
+ ierr = get_args(2, cmd, filename, verbose, dummy)
+ endif
+ call MPI_Bcast(ierr, 1, MPI_INTEGER, 0, MPI_COMM_WORLD, err)
+ if (ierr .EQ. 0) goto 999
+
+ call MPI_Bcast(verbose, 1, MPI_LOGICAL, 0, MPI_COMM_WORLD,
+ + err)
+ call MPI_Bcast(filename, 256, MPI_CHARACTER, 0,
+ + MPI_COMM_WORLD, err)
+
+ ! set parameters
+ global_nx = nx * nprocs
+ global_ny = ny
+
+ do i=1, ny
+ do j=1, nx
+ buf(j,i) = rank
+ enddo
+ enddo
+
+ ! create file, truncate it if exists
+ cmode = IOR(NF_CLOBBER, NF_64BIT_DATA)
+ err = nfmpi_create(MPI_COMM_WORLD, filename, cmode,
+ + MPI_INFO_NULL, ncid)
+ call check(err, 'In nfmpi_create: ')
+
+ ! define dimensions x and y
+ err = nfmpi_def_dim(ncid, "REC_DIM", NFMPI_UNLIMITED,dimid(2))
+ call check(err, 'In nfmpi_def_dim REC_DIM: ')
+ err = nfmpi_def_dim(ncid, "X", global_nx, dimid(1))
+ call check(err, 'In nfmpi_def_dim X: ')
+
+ ! define a 2D record variable of integer type
+ err = nfmpi_def_var(ncid, "rec_var", NF_INT, 2, dimid,
+ + rec_varid)
+ call check(err, 'In nfmpi_def_var: ')
+
+ err = nfmpi_def_dim(ncid, "Y", global_ny, dimid(2))
+ call check(err, 'In nfmpi_def_dim Y: ')
+
+ ! define a 2D fixed-size variable of integer type
+ err = nfmpi_def_var(ncid, "fix_var", NF_INT, 2, dimid,
+ + fix_varid)
+ call check(err, 'In nfmpi_def_var: ')
+
+ ! set the fill mode to NF_FILL for entire file
+ err = nfmpi_set_fill(ncid, NF_FILL, old_mode)
+ call check(err, 'In nfmpi_set_fill: ')
+ if (verbose) then
+ if (old_mode .EQ. NF_FILL) then
+ print*,"The old fill mode is NF_FILL"
+ else
+ print*,"The old fill mode is NF_NOFILL"
+ endif
+ endif
+
+ ! set the fill mode back to NF_NOFILL for entire file
+ err = nfmpi_set_fill(ncid, NF_NOFILL, old_mode)
+ call check(err, 'In nfmpi_set_fill: ')
+
+ ! set the variable's fill mode to NF_FILL with default fill value
+ err = nfmpi_def_var_fill(ncid, fix_varid, 0, NF_FILL_INT)
+ call check(err, 'In nfmpi_def_var_fill: ')
+
+ ! set a customized fill value -1
+ fill_value = -1
+ err = nfmpi_put_att_int(ncid, rec_varid, "_FillValue", NF_INT,
+ + one, fill_value)
+ call check(err, 'In nfmpi_put_att_int: ')
+
+ ! do not forget to exit define mode
+ err = nfmpi_enddef(ncid)
+ call check(err, 'In nfmpi_enddef: ')
+
+ ! now we are in data mode
+
+ ! Note that in Fortran, array indices start with 1
+ starts(1) = nx * rank + 1
+ starts(2) = 1
+ counts(1) = nx
+ counts(2) = ny
+
+ ! do not write the variable in full
+ counts(1) = counts(1) - 1
+ err = nfmpi_put_vara_int_all(ncid, fix_varid, starts, counts,
+ + buf)
+ call check(err, 'In nfmpi_put_vara_int_all: ')
+
+ err = nfmpi_inq_var_fill(ncid, fix_varid, no_fill, fill_value)
+ if (no_fill .NE. 0)
+ + print*,"Error: expecting no_fill to be 0"
+ if (fill_value .NE. NF_FILL_INT)
+ + print*,"Error: expecting no_fill to be ",NF_FILL_INT,
+ + " but got ", fill_value
+
+ ! fill the 1st record of the record variable
+ starts(2) = 1
+ err = nfmpi_fill_var_rec(ncid, rec_varid, starts(2))
+ call check(err, 'In nfmpi_fill_var_rec: ')
+
+ ! write to the 1st record
+ counts(2) = 1
+ err = nfmpi_put_vara_int_all(ncid, rec_varid, starts, counts,
+ + buf)
+ call check(err, 'In nfmpi_put_vara_int_all: ')
+
+ ! fill the 2nd record of the record variable
+ starts(2) = 2
+ err = nfmpi_fill_var_rec(ncid, rec_varid, starts(2))
+ call check(err, 'In nfmpi_fill_var_rec: ')
+
+ ! write to the 2nd record
+ err = nfmpi_put_vara_int_all(ncid, rec_varid, starts, counts,
+ + buf)
+
+ ! close the file
+ err = nfmpi_close(ncid)
+ call check(err, 'In nfmpi_close: ')
+
+ ! check if there is any PnetCDF internal malloc residue
+ 998 format(A,I13,A)
+ err = nfmpi_inq_malloc_size(malloc_size)
+ if (err .EQ. NF_NOERR) then
+ call MPI_Reduce(malloc_size, sum_size, 1, MPI_OFFSET,
+ + MPI_SUM, 0, MPI_COMM_WORLD, err)
+ if (rank .EQ. 0 .AND. sum_size .GT. 0)
+ + print 998,
+ + 'heap memory allocated by PnetCDF internally has ',
+ + sum_size/1048576, ' MiB yet to be freed'
+ endif
+
+ 999 call MPI_Finalize(err)
+ ! call EXIT(0) ! EXIT() is a GNU extension
+ end ! program main
+
diff --git a/examples/F77/flexible_api.f b/examples/F77/flexible_api.f
new file mode 100644
index 0000000..b82c0e3
--- /dev/null
+++ b/examples/F77/flexible_api.f
@@ -0,0 +1,194 @@
+!
+! Copyright (C) 2013, Northwestern University
+! See COPYRIGHT notice in top-level directory.
+!
+! $Id: flexible_api.f 2235 2015-12-18 03:38:49Z wkliao $
+
+!
+! This example shows how to use PnetCDF flexible API, nfmpi_put_vara_all()
+! to write a 2D 4-byte integer array in parallel.
+! It first defines a netCDF variable of size global_nx * global_ny where
+! global_nx == 5 and
+! global_ny == (4 * number of MPI processes).
+! The data partitioning pattern is a column-wise partitioning across all
+! proceses. Each process writes a subarray of size nx * ny.
+! The local buffer has a ghost cell of length 3 surrounding the 2D array
+! integer buf(nx+2*ghost_len, ny+2*ghost_len)
+! Note the description above follows the Fortran array index order.
+!
+! Example commands for MPI run and outputs from running ncmpidump on the
+! NC file produced by this example program:
+!
+! % mpif77 -O2 -o flexible_api flexible_api.f -lpnetcdf
+! % mpiexec -n 4 ./flexible_api /pvfs2/wkliao/testfile.nc
+!
+! % ncmpidump /pvfs2/wkliao/testfile.nc
+! netcdf testfile {
+! // file format: CDF-5 (big variables)
+! dimensions:
+! x = 5 ;
+! y = 16 ;
+! variables:
+! int var(y, x) ;
+! data:
+!
+! var =
+! 0, 0, 0, 0, 0,
+! 0, 0, 0, 0, 0,
+! 0, 0, 0, 0, 0,
+! 0, 0, 0, 0, 0,
+! 1, 1, 1, 1, 1,
+! 1, 1, 1, 1, 1,
+! 1, 1, 1, 1, 1,
+! 1, 1, 1, 1, 1,
+! 2, 2, 2, 2, 2,
+! 2, 2, 2, 2, 2,
+! 2, 2, 2, 2, 2,
+! 2, 2, 2, 2, 2,
+! 3, 3, 3, 3, 3,
+! 3, 3, 3, 3, 3,
+! 3, 3, 3, 3, 3,
+! 3, 3, 3, 3, 3 ;
+! }
+!
+ subroutine check(err, message)
+ implicit none
+ include "mpif.h"
+ include "pnetcdf.inc"
+ integer err
+ character message*(*)
+
+ ! It is a good idea to check returned value for possible error
+ if (err .NE. NF_NOERR) then
+ write(6,*) message//' '//nfmpi_strerror(err)
+ call MPI_Abort(MPI_COMM_WORLD, -1, err)
+ end if
+ end ! subroutine check
+
+ program main
+ implicit none
+ include "mpif.h"
+ include "pnetcdf.inc"
+
+ character*128 filename, cmd
+ integer err, ierr, nprocs, rank, i, j, ghost_len, get_args
+ integer cmode, ncid, varid, dimid(2)
+ integer*8 nx, ny, global_nx, global_ny
+ integer*8 starts(2), counts(2), nTypes
+ PARAMETER(nx=5, ny=4, ghost_len=3)
+ integer buf(nx+2*ghost_len, ny+2*ghost_len)
+ integer subarray
+ integer array_of_sizes(2), array_of_subsizes(2)
+ integer array_of_starts(2)
+ integer*8 malloc_size, sum_size
+ logical verbose
+ integer dummy
+
+ call MPI_Init(err)
+ call MPI_Comm_rank(MPI_COMM_WORLD, rank, err)
+ call MPI_Comm_size(MPI_COMM_WORLD, nprocs, err)
+
+ ! take filename from command-line argument if there is any
+ if (rank .EQ. 0) then
+ verbose = .TRUE.
+ filename = "testfile.nc"
+ ierr = get_args(2, cmd, filename, verbose, dummy)
+ endif
+ call MPI_Bcast(ierr, 1, MPI_INTEGER, 0, MPI_COMM_WORLD, err)
+ if (ierr .EQ. 0) goto 999
+
+ call MPI_Bcast(verbose, 1, MPI_LOGICAL, 0, MPI_COMM_WORLD,
+ + err)
+ call MPI_Bcast(filename, 256, MPI_CHARACTER, 0,
+ + MPI_COMM_WORLD, err)
+
+ ! set parameters
+ global_nx = nx
+ global_ny = ny * nprocs
+
+ ! first initialize the entire buffer to -1
+ do i=1, ny+2*ghost_len
+ do j=1, nx+2*ghost_len
+ buf(j,i) = -1
+ enddo
+ enddo
+ ! assign values for non-ghost cells
+ do j=ghost_len+1, ny+ghost_len
+ do i=ghost_len+1, nx+ghost_len
+ buf(i, j) = rank
+ enddo
+ enddo
+
+ ! define an MPI datatype using MPI_Type_create_subarray()
+ array_of_sizes(1) = nx + 2*ghost_len
+ array_of_sizes(2) = ny + 2*ghost_len
+ array_of_subsizes(1) = nx
+ array_of_subsizes(2) = ny
+ array_of_starts(1) = ghost_len ! MPI start index starts with 0
+ array_of_starts(2) = ghost_len
+ call MPI_Type_create_subarray(2, array_of_sizes,
+ + array_of_subsizes, array_of_starts, MPI_ORDER_FORTRAN,
+ + MPI_INTEGER, subarray, err)
+ call MPI_Type_commit(subarray, err)
+
+ ! create file, truncate it if exists
+ cmode = IOR(NF_CLOBBER, NF_64BIT_DATA)
+ err = nfmpi_create(MPI_COMM_WORLD, filename, cmode,
+ + MPI_INFO_NULL, ncid)
+ call check(err, 'In nfmpi_create: ')
+
+ ! define dimensions x and y
+ err = nfmpi_def_dim(ncid, "y", global_ny, dimid(2))
+ call check(err, 'In nfmpi_def_dim y: ')
+ err = nfmpi_def_dim(ncid, "x", global_nx, dimid(1))
+ call check(err, 'In nfmpi_def_dim x: ')
+
+ ! define a 2D variable of integer type
+ err = nfmpi_def_var(ncid, "var", NF_INT, 2, dimid, varid)
+ call check(err, 'In nfmpi_def_var: ')
+
+ ! do not forget to exit define mode
+ err = nfmpi_enddef(ncid)
+ call check(err, 'In nfmpi_enddef: ')
+
+ ! now we are in data mode
+
+ ! Note that in Fortran, array indices start with 1
+ starts(1) = 1
+ starts(2) = ny * rank + 1
+ counts(1) = nx
+ counts(2) = ny
+ nTypes = 1
+
+ ! In Fortran, subarray buffer type can also use array index ranges
+ ! for example in this case
+ ! buf(1+ghost_len:nx+ghost_len, 1+ghost_len:ny+ghost_len)
+ ! However, this does not work for nonblocking APIs because
+ ! wait/wait_all is called separately from the nonblocking calls
+ ! Fortran the subarray indexing is lost in the wait call
+ err = nfmpi_put_vara_all(ncid, varid, starts, counts, buf,
+ + nTypes, subarray)
+ call check(err, 'In nfmpi_put_vara_all: ')
+
+ call MPI_Type_free(subarray, err)
+
+ ! close the file
+ err = nfmpi_close(ncid)
+ call check(err, 'In nfmpi_close: ')
+
+ ! check if there is any PnetCDF internal malloc residue
+ 998 format(A,I13,A)
+ err = nfmpi_inq_malloc_size(malloc_size)
+ if (err .EQ. NF_NOERR) then
+ call MPI_Reduce(malloc_size, sum_size, 1, MPI_OFFSET,
+ + MPI_SUM, 0, MPI_COMM_WORLD, err)
+ if (rank .EQ. 0 .AND. sum_size .GT. 0)
+ + print 998,
+ + 'heap memory allocated by PnetCDF internally has ',
+ + sum_size/1048576, ' MiB yet to be freed'
+ endif
+
+ 999 call MPI_Finalize(err)
+ ! call EXIT(0) ! EXIT() is a GNU extension
+ end ! program main
+
diff --git a/examples/F77/get_info.f b/examples/F77/get_info.f
new file mode 100644
index 0000000..e14ed90
--- /dev/null
+++ b/examples/F77/get_info.f
@@ -0,0 +1,141 @@
+!
+! Copyright (C) 2012, Northwestern University and Argonne National
+! Laboratory
+! See COPYRIGHT notice in top-level directory.
+!
+! $Id: get_info.f 2224 2015-12-16 06:10:36Z wkliao $
+
+!
+! To compile:
+! mpif77 -O2 get_info.f -o get_info -lpnetcdf
+! To run:
+! mpiexec -n 4 ./get_info /pvfs2/wkliao/testfile.nc
+!
+! prints all MPI-IO hints used
+!
+! Example standard output:
+!
+! MPI File Info: nkeys = 18
+! MPI File Info: [ 0] key = cb_buffer_size, value =16777216
+! MPI File Info: [ 1] key = romio_cb_read, value =automatic
+! MPI File Info: [ 2] key = romio_cb_write, value =automatic
+! MPI File Info: [ 3] key = cb_nodes, value =1
+! MPI File Info: [ 4] key = romio_no_indep_rw, value =false
+! MPI File Info: [ 5] key = romio_cb_pfr, value =disable
+! MPI File Info: [ 6] key = romio_cb_fr_types, value =aar
+! MPI File Info: [ 7] key = romio_cb_fr_alignment, value =1
+! MPI File Info: [ 8] key = romio_cb_ds_threshold, value =0
+! MPI File Info: [ 9] key = romio_cb_alltoall, value =automatic
+! MPI File Info: [10] key = ind_rd_buffer_size, value =4194304
+! MPI File Info: [11] key = ind_wr_buffer_size, value =524288
+! MPI File Info: [12] key = romio_ds_read, value =automatic
+! MPI File Info: [13] key = romio_ds_write, value =automatic
+! MPI File Info: [14] key = cb_config_list, value =*:1
+! MPI File Info: [15] key = nc_header_align_size, value =0
+! MPI File Info: [16] key = nc_var_align_size, value =0
+! MPI File Info: [17] key = nc_header_read_chunk_size, value =0
+
+
+ program main
+ implicit none
+ include "mpif.h"
+ include "pnetcdf.inc"
+
+ character*256 filename, cmd
+ integer ncid, rank, info, omode, err, ierr, get_args
+ integer*8 malloc_size, sum_size
+ logical verbose
+ integer dummy
+
+ call MPI_Init(err)
+ call MPI_Comm_rank (MPI_COMM_WORLD, rank, err)
+
+ if (rank .EQ. 0) then
+ verbose = .TRUE.
+ filename = "testfile.nc"
+ ierr = get_args(2, cmd, filename, verbose, dummy)
+ endif
+ call MPI_Bcast(ierr, 1, MPI_INTEGER, 0, MPI_COMM_WORLD, err)
+ if (ierr .EQ. 0) goto 999
+
+ call MPI_Bcast(verbose, 1, MPI_LOGICAL, 0, MPI_COMM_WORLD,
+ + err)
+ call MPI_Bcast(filename, 256, MPI_CHARACTER, 0,
+ + MPI_COMM_WORLD, err)
+
+ omode = NF_NOWRITE + NF_64BIT_OFFSET
+ err = nfmpi_open(MPI_COMM_WORLD, filename, omode,
+ + MPI_INFO_NULL, ncid)
+ if (err .ne. NF_NOERR) call handle_err('nfmpi_open',err)
+
+
+ err = nfmpi_inq_file_info(ncid, info)
+ if (err .ne. NF_NOERR) call handle_err('nfmpi_inq_file_info',
+ + err)
+
+ err = nfmpi_close(ncid)
+ if (err .ne. NF_NOERR) call handle_err('nfmpi_close',err)
+
+ if (rank .EQ. 0 .AND. verbose) call print_info(info)
+ call MPI_Info_free(info, err)
+
+ ! check if there is any PnetCDF internal malloc residue
+ 998 format(A,I13,A)
+ err = nfmpi_inq_malloc_size(malloc_size)
+ if (err .EQ. NF_NOERR) then
+ call MPI_Reduce(malloc_size, sum_size, 1, MPI_OFFSET,
+ + MPI_SUM, 0, MPI_COMM_WORLD, err)
+ if (rank .EQ. 0 .AND. sum_size .GT. 0)
+ + print 998,
+ + 'heap memory allocated by PnetCDF internally has ',
+ + sum_size/1048576, ' MiB yet to be freed'
+ endif
+
+ 999 call MPI_Finalize(err)
+ ! call EXIT(0) ! EXIT() is a GNU extension
+
+ end ! program main
+
+ subroutine print_info(info_used)
+ implicit none
+ include "mpif.h"
+ include "pnetcdf.inc"
+
+ integer info_used
+
+ ! local variables
+ character*(MPI_MAX_INFO_VAL) key, value
+ integer nkeys, i, err
+ logical flag
+
+ call MPI_Info_get_nkeys(info_used, nkeys, err)
+ print *, 'MPI File Info: nkeys =', nkeys
+ do i=0, nkeys-1
+ call MPI_Info_get_nthkey(info_used, i, key, err)
+ call MPI_Info_get(info_used, key, MPI_MAX_INFO_VAL,
+ + value, flag, err)
+ 123 format('MPI File Info: [',I2,'] key = ',A25,
+ + ', value =',A)
+ print 123, i, key, value
+ enddo
+ print *
+
+ return
+ end ! subroutine print_info
+
+ subroutine handle_err(err_msg, errcode)
+ implicit none
+ include "mpif.h"
+ include "pnetcdf.inc"
+
+ character*(*) err_msg
+ integer errcode
+
+ ! local variables
+ integer err
+
+ print *, 'Error: ',err_msg//' '//nfmpi_strerror(errcode)
+ call MPI_Abort(MPI_COMM_WORLD, -1, err)
+ return
+ end ! subroutine handle_err
+
diff --git a/examples/F77/hints.f b/examples/F77/hints.f
new file mode 100644
index 0000000..2f068ef
--- /dev/null
+++ b/examples/F77/hints.f
@@ -0,0 +1,251 @@
+!
+! Copyright (C) 2012, Northwestern University and Argonne National
+! Laboratory
+! See COPYRIGHT notice in top-level directory.
+!
+! $Id: hints.f 2224 2015-12-16 06:10:36Z wkliao $
+
+!
+! This example sets two PnetCDF hints:
+! nc_header_align_size and nc_var_align_size
+! and prints the hint values as well as the header size, header extent, and
+! two variables' starting file offsets.
+!
+! The compile and run commands are given below.
+!
+! % mpif77 -O2 -o hints hints.f -lpnetcdf
+!
+! % mpiexec -n 4 ./hints /pvfs2/wkliao/testfile.nc
+!
+! nc_header_align_size set to = 1024
+! nc_var_align_size set to = 512
+! nc_header_read_chunk_size set to = 256
+! header size = 252
+! header extent = 1024
+! var_zy start file offset = 1024
+! var_yx start file offset = 3072
+!
+
+
+ subroutine check(err, message)
+ implicit none
+ include "mpif.h"
+ include "pnetcdf.inc"
+ integer err
+ character message*(*)
+
+ ! It is a good idea to check returned value for possible error
+ if (err .NE. NF_NOERR) then
+ write(6,*) message//' '//nfmpi_strerror(err)
+ call MPI_Abort(MPI_COMM_WORLD, -1, err)
+ end if
+ end ! subroutine check
+
+ subroutine print_hints(ncid, varid0, varid1)
+ implicit none
+ include "mpif.h"
+ include "pnetcdf.inc"
+
+ integer ncid, varid0, varid1
+
+ ! local variables
+ character*(MPI_MAX_INFO_VAL) value
+ integer err, len, info_used
+ logical flag
+ integer*8 header_size, header_extent
+ integer*8 var_zy_start, var_yx_start
+ integer*8 h_align, v_align, h_chunk
+
+ h_align=-1
+ v_align=-1
+ h_chunk=-1
+
+ err = nfmpi_inq_header_size (ncid, header_size)
+ call check(err, 'In nfmpi_inq_header_size: ')
+ err = nfmpi_inq_header_extent(ncid, header_extent)
+ call check(err, 'In nfmpi_inq_header_extent: ')
+ err = nfmpi_inq_varoffset(ncid, varid0, var_zy_start)
+ call check(err, 'In nfmpi_inq_varoffset varid0: ')
+ err = nfmpi_inq_varoffset(ncid, varid1, var_yx_start)
+ call check(err, 'In nfmpi_inq_varoffset varid1: ')
+
+ err = nfmpi_inq_file_info(ncid, info_used)
+ call check(err, 'In nfmpi_inq_file_info : ')
+
+ call MPI_Info_get_valuelen(info_used, "nc_header_align_size",
+ + len, flag, err)
+ if (flag) then
+ call MPI_Info_get(info_used, "nc_header_align_size",
+ + len+1, value, flag, err)
+ read(value, '(i16)') h_align
+ endif
+ call MPI_Info_get_valuelen(info_used, "nc_var_align_size",
+ + len, flag, err)
+ if (flag) then
+ call MPI_Info_get(info_used, "nc_var_align_size", len+1,
+ + value, flag, err)
+ read(value, '(i16)') v_align
+ endif
+ call MPI_Info_get_valuelen(info_used,
+ + "nc_header_read_chunk_size",
+ + len, flag, err)
+ if (flag) then
+ call MPI_Info_get(info_used, "nc_header_read_chunk_size",
+ + len+1, value, flag, err)
+ read(value, '(i16)') h_chunk
+ endif
+ call MPI_Info_free(info_used, err)
+
+ if (h_align .EQ. -1) then
+ print*,"nc_header_align_size is NOT set"
+ else
+ print*,"nc_header_align_size set to = ", h_align
+ endif
+ if (v_align .EQ. -1) then
+ print*,"nc_var_align_size is NOT set"
+ else
+ print*,"nc_var_align_size set to = ", v_align
+ endif
+ if (h_chunk .EQ. -1) then
+ print*,"nc_header_read_chunk_size is NOT set"
+ else
+ print*,"nc_header_read_chunk_size set to = ", h_chunk
+ endif
+
+ print*,"header size = ", header_size
+ print*,"header extent = ", header_extent
+ print*,"var_zy start file offset = ", var_zy_start
+ print*,"var_yx start file offset = ", var_yx_start
+ end ! subroutine print_hints
+
+ subroutine put_vara(ncid, varid, ny, nx, start, count)
+ implicit none
+ include "mpif.h"
+ include "pnetcdf.inc"
+
+ integer ncid, varid, ny, nx
+ integer*8 start(2), count(2)
+
+ integer i, j, rank, err
+ integer buf(nx, ny)
+
+ call MPI_Comm_rank(MPI_COMM_WORLD, rank, err)
+
+ do j=1, ny
+ do i=1, nx
+ buf(i,j) = rank ! j*nx + i
+ enddo
+ enddo
+
+ err = nfmpi_put_vara_int_all(ncid, varid, start, count, buf)
+ call check(err, 'In nfmpi_put_vara_int_all : ')
+
+ end ! subroutine put_vara
+
+ program main
+ implicit none
+ include "mpif.h"
+ include "pnetcdf.inc"
+
+ character*256 filename, cmd
+ integer NZ, NY, NX
+ integer ncid, rank, nprocs, info, cmode, err, ierr, get_args
+ integer varid0, varid1, dimid(3), dimid2(2)
+ integer*8 start(2), count(2), llen
+ integer*8 malloc_size, sum_size
+ logical verbose
+ integer dummy
+
+ call MPI_Init(err)
+ call MPI_Comm_rank(MPI_COMM_WORLD, rank, err)
+ call MPI_Comm_size(MPI_COMM_WORLD, nprocs, err)
+
+ NZ = 5
+ NY = 5
+ NX = 5
+
+ if (rank .EQ. 0) then
+ verbose = .TRUE.
+ filename = "testfile.nc"
+ ierr = get_args(2, cmd, filename, verbose, dummy)
+ endif
+ call MPI_Bcast(ierr, 1, MPI_INTEGER, 0, MPI_COMM_WORLD, err)
+ if (ierr .EQ. 0) goto 999
+
+ call MPI_Bcast(verbose, 1, MPI_LOGICAL, 0, MPI_COMM_WORLD,
+ + err)
+ call MPI_Bcast(filename, 256, MPI_CHARACTER, 0,
+ + MPI_COMM_WORLD, err)
+
+ call MPI_Info_create(info, err)
+ call MPI_Info_set(info, "nc_header_align_size", "1024", err)
+ call MPI_Info_set(info, "nc_var_align_size", "512", err)
+ call MPI_Info_set(info, "nc_header_read_chunk_size", "256", err)
+ ! note that set the above values to 1 to disable the alignment
+
+ ! create a new file for writing
+ cmode = NF_CLOBBER + NF_64BIT_DATA
+ err = nfmpi_create(MPI_COMM_WORLD, filename, cmode, info, ncid)
+ call check(err, 'In nfmpi_create : ')
+ call MPI_Info_free(info, err)
+
+ ! define 3 dimensions
+ llen = NZ*nprocs
+ err = nfmpi_def_dim(ncid, "Z", llen, dimid(1))
+ call check(err, 'In nfmpi_def_dim Z : ')
+ llen = NY*nprocs
+ err = nfmpi_def_dim(ncid, "Y", llen, dimid(2))
+ call check(err, 'In nfmpi_def_dim Y : ')
+ llen = NX*nprocs
+ err = nfmpi_def_dim(ncid, "X", llen, dimid(3))
+ call check(err, 'In nfmpi_def_dim X : ')
+
+ ! define a variable of size (NZ * nprocs) * (NY * nprocs)
+ dimid2(1) = dimid(1)
+ dimid2(2) = dimid(2)
+ err = nfmpi_def_var(ncid, "var_zy", NF_INT, 2, dimid2, varid0)
+ call check(err, 'In nfmpi_def_var var_zy : ')
+ ! define a variable of size (NY * nprocs) * (NX * nprocs)
+ dimid2(1) = dimid(2)
+ dimid2(2) = dimid(3)
+ err = nfmpi_def_var(ncid, "var_yx", NF_FLOAT, 2, dimid2, varid1)
+ call check(err, 'In nfmpi_def_var var_yx : ')
+
+ err = nfmpi_enddef(ncid)
+ call check(err, 'In nfmpi_enddef : ')
+
+ ! var_zy is partitioned along Z dimension
+ start(1) = NZ * rank + 1
+ start(2) = 1
+ count(1) = NZ
+ count(2) = NY * nprocs
+ call put_vara(ncid, varid0, NZ, NY * nprocs, start, count)
+
+ ! var_yx is partitioned along X dimension
+ start(1) = 1
+ start(2) = NX * rank + 1
+ count(1) = NY * nprocs
+ count(2) = NX
+ call put_vara(ncid, varid1, NY * nprocs, NX, start, count)
+
+ if (rank .EQ. 0 .AND. verbose)
+ + call print_hints(ncid, varid0, varid1)
+
+ err = nfmpi_close(ncid)
+
+ ! check if there is any PnetCDF internal malloc residue
+ 998 format(A,I13,A)
+ err = nfmpi_inq_malloc_size(malloc_size)
+ if (err .EQ. NF_NOERR) then
+ call MPI_Reduce(malloc_size, sum_size, 1, MPI_OFFSET,
+ + MPI_SUM, 0, MPI_COMM_WORLD, err)
+ if (rank .EQ. 0 .AND. sum_size .GT. 0)
+ + print 998,
+ + 'heap memory allocated by PnetCDF internally has ',
+ + sum_size/1048576, ' MiB yet to be freed'
+ endif
+
+ 999 call MPI_Finalize(err)
+ ! call EXIT(0) ! EXIT() is a GNU extension
+ end ! program
+
diff --git a/examples/F77/i_varn_real.f b/examples/F77/i_varn_real.f
new file mode 100644
index 0000000..bea1f0d
--- /dev/null
+++ b/examples/F77/i_varn_real.f
@@ -0,0 +1,323 @@
+!
+! Copyright (C) 2014, Northwestern University
+! See COPYRIGHT notice in top-level directory.
+!
+! $Id: i_varn_real.f 2224 2015-12-16 06:10:36Z wkliao $
+
+! This example tests nonblocking varn API, nfmpi_iput_varn_real()
+! It writes a sequence of requests with arbitrary array indices and
+! lengths to four variables of type NF_REAL
+!
+! The compile and run commands are given below, together with an
+! ncmpidump of the output file.
+!
+! The compile and run commands are given below, together with an ncmpidump of
+! the output file.
+!
+! % mpif77 -O2 -o i_varn_real i_varn_real.f -lpnetcdf
+! % mpiexec -n 4 ./i_varn_real /pvfs2/wkliao/testfile.nc
+! % ncmpidump /pvfs2/wkliao/testfile.nc
+! netcdf testfile {
+! // file format: CDF-5 (big variables)
+! dimensions:
+! Y = 4 ;
+! X = 10 ;
+! variables:
+! float var0(Y, X) ;
+! float var1(Y, X) ;
+! float var2(Y, X) ;
+! float var3(Y, X) ;
+! data:
+!
+! var0 =
+! 1, 0, 3, 0,
+! 1, 2, 3, 0,
+! 1, 2, 2, 0,
+! 3, 2, 1, 2,
+! 3, 1, 1, 3,
+! 0, 3, 1, 3,
+! 0, 3, 0, 3,
+! 2, 2, 0, 1,
+! 3, 2, 3, 1,
+! 3, 2, 3, 1 ;
+!
+! var1 =
+! 2, 1, 0, 1,
+! 2, 3, 0, 1,
+! 2, 3, 3, 1,
+! 0, 3, 2, 3,
+! 0, 2, 2, 0,
+! 1, 0, 2, 0,
+! 1, 0, 1, 0,
+! 3, 3, 1, 2,
+! 0, 3, 0, 2,
+! 0, 3, 0, 2 ;
+!
+! var2 =
+! 3, 2, 1, 2,
+! 3, 0, 1, 2,
+! 3, 0, 0, 2,
+! 1, 0, 3, 0,
+! 1, 3, 3, 1,
+! 2, 1, 3, 1,
+! 2, 1, 2, 1,
+! 0, 0, 2, 3,
+! 1, 0, 1, 3,
+! 1, 0, 1, 3 ;
+!
+! var3 =
+! 0, 3, 2, 3,
+! 0, 1, 2, 3,
+! 0, 1, 1, 3,
+! 2, 1, 0, 1,
+! 2, 0, 0, 2,
+! 3, 2, 0, 2,
+! 3, 2, 3, 2,
+! 1, 1, 3, 0,
+! 2, 1, 2, 0,
+! 2, 1, 2, 0 ;
+! }
+!
+! Note the above dump is in C order
+!
+ subroutine check(err, message)
+ implicit none
+ include "mpif.h"
+ include "pnetcdf.inc"
+ integer err
+ character message*(*)
+
+ ! It is a good idea to check returned value for possible error
+ if (err .NE. NF_NOERR) then
+ write(6,*) message//' '//nfmpi_strerror(err)
+ call MPI_Abort(MPI_COMM_WORLD, -1, err)
+ end if
+ end ! subroutine check
+
+ program main
+ implicit none
+ include "mpif.h"
+ include "pnetcdf.inc"
+
+ integer NDIMS
+ integer*8 NX, NY
+ PARAMETER(NDIMS=2, NX=4, NY=10)
+
+ character*128 filename, cmd
+ integer i, j, n, err, ierr, nprocs, rank, get_args
+ integer cmode, ncid, varid(4), dimid(NDIMS), nreqs
+ integer reqs(4), sts(4), num_segs(4)
+
+ integer*8 start(NDIMS, 6, 4)
+ integer*8 count(NDIMS, 6, 4)
+ integer*8 malloc_size, sum_size, two
+ real buffer(NX*NY,4)
+ logical verbose
+ integer dummy
+
+ call MPI_Init(err)
+ call MPI_Comm_rank(MPI_COMM_WORLD, rank, err)
+ call MPI_Comm_size(MPI_COMM_WORLD, nprocs, err)
+
+ two = 2
+ ! take filename from command-line argument if there is any
+ if (rank .EQ. 0) then
+ verbose = .TRUE.
+ filename = "testfile.nc"
+ ierr = get_args(2, cmd, filename, verbose, dummy)
+ endif
+ call MPI_Bcast(ierr, 1, MPI_INTEGER, 0, MPI_COMM_WORLD, err)
+ if (ierr .EQ. 0) goto 999
+
+ call MPI_Bcast(verbose, 1, MPI_LOGICAL, 0, MPI_COMM_WORLD,
+ + err)
+ call MPI_Bcast(filename, 256, MPI_CHARACTER, 0,
+ + MPI_COMM_WORLD, err)
+
+ if (nprocs .NE. 4 .AND. rank .EQ. 0 .AND. verbose)
+ + print*,'Warning: ',cmd,' is intended to run on ',
+ + '4 processes'
+
+ ! create file, truncate it if exists
+ cmode = IOR(NF_CLOBBER, NF_64BIT_DATA)
+ err = nfmpi_create(MPI_COMM_WORLD, filename, cmode,
+ + MPI_INFO_NULL, ncid)
+ call check(err, 'In nfmpi_create: ')
+
+ ! define dimensions x and y
+ err = nfmpi_def_dim(ncid, "Y", NY, dimid(2))
+ call check(err, 'In nfmpi_def_dim Y: ')
+ err = nfmpi_def_dim(ncid, "X", NX, dimid(1))
+ call check(err, 'In nfmpi_def_dim X: ')
+
+ ! define 4 2D variables of real type
+ err = nfmpi_def_var(ncid, "var0", NF_REAL, two,
+ + dimid,varid(1))
+ call check(err, 'In nfmpi_def_var var0: ')
+ err = nfmpi_def_var(ncid, "var1", NF_REAL, two,
+ + dimid,varid(2))
+ call check(err, 'In nfmpi_def_var var1: ')
+ err = nfmpi_def_var(ncid, "var2", NF_REAL, two,
+ + dimid,varid(3))
+ call check(err, 'In nfmpi_def_var var2: ')
+ err = nfmpi_def_var(ncid, "var3", NF_REAL, two,
+ + dimid,varid(4))
+ call check(err, 'In nfmpi_def_var var3: ')
+
+ ! do not forget to exit define mode
+ err = nfmpi_enddef(ncid)
+ call check(err, 'In nfmpi_enddef: ')
+
+ if (rank .GE. 4) goto 123
+
+ ! now we are in data mode
+ n = rank+1
+ num_segs(n) = 4 ! number of segments for this request
+ start(1,1,n)=1
+ start(2,1,n)=6
+ count(1,1,n)=1
+ count(2,1,n)=2
+ start(1,2,n)=2
+ start(2,2,n)=1
+ count(1,2,n)=1
+ count(2,2,n)=1
+ start(1,3,n)=3
+ start(2,3,n)=7
+ count(1,3,n)=1
+ count(2,3,n)=2
+ start(1,4,n)=4
+ start(2,4,n)=1
+ count(1,4,n)=1
+ count(2,4,n)=3
+ ! start(:,:,n) n_count(:,:,n) indicate the following:
+ ! ("-" means skip)
+ ! - - - - - X X - - -
+ ! X - - - - - - - - -
+ ! - - - - - - X X - -
+ ! X X X - - - - - - -
+
+ n = mod(rank+1, 4) + 1
+ num_segs(n) = 6 ! number of segments for this request
+ start(1,1,n)=1
+ start(2,1,n)=4
+ count(1,1,n)=1
+ count(2,1,n)=2
+ start(1,2,n)=1
+ start(2,2,n)=9
+ count(1,2,n)=1
+ count(2,2,n)=2
+ start(1,3,n)=2
+ start(2,3,n)=6
+ count(1,3,n)=1
+ count(2,3,n)=2
+ start(1,4,n)=3
+ start(2,4,n)=1
+ count(1,4,n)=1
+ count(2,4,n)=2
+ start(1,5,n)=3
+ start(2,5,n)=9
+ count(1,5,n)=1
+ count(2,5,n)=2
+ start(1,6,n)=4
+ start(2,6,n)=5
+ count(1,6,n)=1
+ count(2,6,n)=3
+ ! start(:,:,n) n_count(:,:,n) indicate the following:
+ ! - - - X X - - - X X
+ ! - - - - - X X - - -
+ ! X X - - - - - - X X
+ ! - - - - X X X - - -
+
+ n = mod(rank+2, 4) + 1
+ num_segs(n) = 5 ! number of segments for this request
+ start(1,1,n)=1
+ start(2,1,n)=8
+ count(1,1,n)=1
+ count(2,1,n)=1
+ start(1,2,n)=2
+ start(2,2,n)=2
+ count(1,2,n)=1
+ count(2,2,n)=3
+ start(1,3,n)=2
+ start(2,3,n)=8
+ count(1,3,n)=1
+ count(2,3,n)=3
+ start(1,4,n)=3
+ start(2,4,n)=3
+ count(1,4,n)=1
+ count(2,4,n)=1
+ start(1,5,n)=4
+ start(2,5,n)=4
+ count(1,5,n)=1
+ count(2,5,n)=1
+ ! start(:,:,n) n_count(:,:,n) indicate the following:
+ ! - - - - - - - X - -
+ ! - X X X - - - X X X
+ ! - - X - - - - - - -
+ ! - - - X - - - - - -
+
+ n = mod(rank+3, 4) + 1
+ num_segs(n) = 4 ! number of segments for this request
+ start(1,1,n)=1
+ start(2,1,n)=1
+ count(1,1,n)=1
+ count(2,1,n)=3
+ start(1,2,n)=2
+ start(2,2,n)=5
+ count(1,2,n)=1
+ count(2,2,n)=1
+ start(1,3,n)=3
+ start(2,3,n)=4
+ count(1,3,n)=1
+ count(2,3,n)=3
+ start(1,4,n)=4
+ start(2,4,n)=8
+ count(1,4,n)=1
+ count(2,4,n)=3
+ ! start(:,:,n) n_count(:,:,n) indicate the following:
+ ! X X X - - - - - - -
+ ! - - - - X - - - - -
+ ! - - - X X X - - - -
+ ! - - - - - - - X X X
+
+ ! only rank 0, 1, 2, and 3 do I/O:
+ ! each of ranks 0 to 3 write 4 nonblocking requests
+ 123 nreqs = 4
+ if (rank .GE. 4) nreqs = 0
+
+ ! initialize buffer contents
+ do i=1, 4
+ do j=1, NX*NY
+ buffer(j,i) = rank
+ enddo
+ enddo
+
+ do i=1, nreqs
+ err = nfmpi_iput_varn_real(ncid, varid(i), num_segs(i),
+ + start(1,1,i), count(1,1,i),
+ + buffer(1,i), reqs(i))
+ call check(err, 'In nfmpi_iput_varn_real: ')
+ enddo
+ err = nfmpi_wait_all(ncid, nreqs, reqs, sts)
+ call check(err, 'In nfmpi_wait_all: ')
+
+ ! close the file
+ err = nfmpi_close(ncid)
+ call check(err, 'In nfmpi_close: ')
+
+ ! check if there is any PnetCDF internal malloc residue
+ 998 format(A,I13,A)
+ err = nfmpi_inq_malloc_size(malloc_size)
+ if (err .EQ. NF_NOERR) then
+ call MPI_Reduce(malloc_size, sum_size, 1, MPI_OFFSET,
+ + MPI_SUM, 0, MPI_COMM_WORLD, err)
+ if (rank .EQ. 0 .AND. sum_size .GT. 0)
+ + print 998,
+ + 'heap memory allocated by PnetCDF internally has ',
+ + sum_size, ' B yet to be freed'
+ endif
+
+ 999 call MPI_Finalize(err)
+ ! call EXIT(0) ! EXIT() is a GNU extension
+ end ! program main
+
diff --git a/examples/F77/nonblocking_write.f b/examples/F77/nonblocking_write.f
new file mode 100644
index 0000000..0a1923e
--- /dev/null
+++ b/examples/F77/nonblocking_write.f
@@ -0,0 +1,204 @@
+!
+! Copyright (C) 2012, Northwestern University and Argonne National Laboratory
+! See COPYRIGHT notice in top-level directory.
+!
+! $Id: nonblocking_write.f 2245 2015-12-20 18:39:52Z wkliao $
+
+! This example is the Fortran 77 version of nonblocking_write.c
+! It creates a netcdf file in CD-5 format and writes a number of
+! 3D integer non-record variables.
+! Usage: (for example)
+! To compile:
+! mpif77 -O2 nonblocking_write.f -o nonblocking_write -lpnetcdf
+! To run (for example):
+! mpiexec -n 32 ./nonblocking_write /pvfs2/wkliao/testfile.nc 10
+! The size of each local array is len x len x len. Each non-record
+! variable is of size len*len*len * nprocs * sizeof(int)
+! All variables are partitioned among all processes in a 3D
+! block-block-block fashion.
+!
+
+ subroutine check(err, message)
+ implicit none
+ include "mpif.h"
+ include "pnetcdf.inc"
+ integer err
+ character message*(*)
+
+ ! It is a good idea to check returned value for possible error
+ if (err .NE. NF_NOERR) then
+ write(6,*) message//' '//nfmpi_strerror(err)
+ call MPI_Abort(MPI_COMM_WORLD, -1, err)
+ end if
+ end
+
+ program main
+ implicit none
+ include "mpif.h"
+ include "pnetcdf.inc"
+
+ integer NDIMS, NUM_VARS, BUFSIZE
+ PARAMETER(NDIMS=3, NUM_VARS=10, BUFSIZE=1000)
+
+ character*128 filename, cmd, str
+ integer i, j, cmode, err, ierr, get_args
+ integer rank, nprocs, ncid, len
+ integer buf(BUFSIZE, NUM_VARS), buf1d(BUFSIZE)
+ integer psizes(NDIMS), dimids(NDIMS), varids(NUM_VARS)
+ integer req(NUM_VARS), st(NUM_VARS)
+ integer*8 gsizes(NDIMS)
+ integer*8 starts(NDIMS), counts(NDIMS)
+ integer*8 bbufsize
+ integer*8 malloc_size, sum_size
+ logical verbose
+
+ call MPI_Init(err)
+ call MPI_Comm_rank(MPI_COMM_WORLD, rank, err)
+ call MPI_Comm_size(MPI_COMM_WORLD, nprocs, err)
+
+ ! take filename from command-line argument if there is any
+ if (rank .EQ. 0) then
+ verbose = .TRUE.
+ filename = "testfile.nc"
+ len = 10
+ ierr = get_args(3, cmd, filename, verbose, len)
+ endif
+ call MPI_Bcast(ierr, 1, MPI_INTEGER, 0, MPI_COMM_WORLD, err)
+ if (ierr .EQ. 0) goto 999
+
+ call MPI_Bcast(verbose, 1, MPI_LOGICAL, 0, MPI_COMM_WORLD,
+ + err)
+ call MPI_Bcast(filename, 256, MPI_CHARACTER, 0,
+ + MPI_COMM_WORLD, err)
+ call MPI_Bcast(len, 1, MPI_INTEGER, 0, MPI_COMM_WORLD, err)
+
+ if (len .GT. BUFSIZE) then
+ print*,'Maximum len is 10, change it to 10'
+ len = BUFSIZE
+ endif
+
+ do i=1,NDIMS
+ psizes(i) = 0
+ enddo
+
+ ! create a block-block-block data partitioning
+ call MPI_Dims_create(nprocs, NDIMS, psizes, err)
+ starts(1) = mod(rank, psizes(1))
+ starts(2) = mod((rank / psizes(2)), psizes(2))
+ starts(3) = mod((rank / (psizes(1) * psizes(2))), psizes(3))
+
+ bbufsize = 1
+ do i=1,NDIMS
+ gsizes(i) = len * psizes(i)
+ starts(i) = starts(i) * len + 1
+ counts(i) = len
+ bbufsize = bbufsize * len
+ enddo
+
+ do i=1,NUM_VARS
+ do j=1,BUFSIZE
+ buf(j,i) = rank
+ enddo
+ enddo
+
+ ! create file, truncate it if exists
+ cmode = IOR(NF_CLOBBER, NF_64BIT_DATA)
+ err = nfmpi_create(MPI_COMM_WORLD, filename, cmode,
+ + MPI_INFO_NULL, ncid)
+ call check(err, 'In nfmpi_create: ')
+
+ ! define dimensions
+ do i=1, NDIMS
+ write(str,'(I1)') i-1
+ err = nfmpi_def_dim(ncid, "x"//str,
+ + gsizes(i), dimids(i))
+ call check(err, 'In nfmpi_def_dim x'//str)
+ enddo
+
+ !define variables
+ do i=1, NUM_VARS
+ write(str,'(I1)') i-1
+ err = nfmpi_def_var(ncid, "var"//str,
+ + NF_INT, NDIMS, dimids, varids(i))
+ call check(err, 'In nfmpi_def_var var'//str)
+ enddo
+
+ ! do not forget to exit define mode
+ err = nfmpi_enddef(ncid)
+ call check(err, 'In nfmpi_enddef: ')
+
+ ! write one variable at a time using iput
+ do i=1, NUM_VARS
+ do j=1,BUFSIZE
+ buf1d(j) = buf(j,i)
+ enddo
+ write(str,'(I1)') i-1
+ err = nfmpi_iput_vara_int(ncid, varids(i), starts,
+ + counts, buf1d, req(i))
+ call check(err, 'In nfmpi_iput_vara_int '//str)
+ enddo
+
+ ! wait for the nonblocking I/O to complete
+ err = nfmpi_wait_all(ncid, NUM_VARS, req, st)
+ call check(err, 'In nfmpi_wait_all')
+
+ ! check the status of each nonblocking request
+ do i=1, NUM_VARS
+ write(str,'(I1)') i-1
+ call check(st(i), 'In nfmpi_wait_all req '//str)
+ enddo
+
+ ! write one variable at a time using bput
+
+ ! bbufsize must be max of data type converted before and after
+ bbufsize = bbufsize * NUM_VARS * 4 ! 4 is size of integer
+ err = nfmpi_buffer_attach(ncid, bbufsize)
+ call check(err, 'In nfmpi_buffer_attach')
+
+ do i=1, NUM_VARS
+ do j=1,BUFSIZE
+ buf1d(j) = buf(j,i)
+ enddo
+ write(str,'(I1)') i-1
+ err = nfmpi_bput_vara_int(ncid, varids(i), starts,
+ + counts, buf1d, req(i))
+ call check(err, 'In nfmpi_bput_vara_int '//str)
+
+ ! can safely change the contents of buf(:,i) now
+ enddo
+
+ ! wait for the nonblocking I/O to complete
+ err = nfmpi_wait_all(ncid, NUM_VARS, req, st)
+ call check(err, 'In nfmpi_wait_all')
+
+ ! check the status of each nonblocking request
+ do i=1, NUM_VARS
+ write(str,'(I1)') i-1
+ call check(st(i), 'In nfmpi_wait_all req '//str)
+ enddo
+
+ ! detach the temporary buffer
+ err = nfmpi_buffer_detach(ncid)
+ call check(err, 'In nfmpi_buffer_detach')
+
+ ! close the file
+ err = nfmpi_close(ncid)
+ call check(err, 'In nfmpi_close')
+
+ ! check if there is any PnetCDF internal malloc residue
+ 998 format(A,I13,A)
+ err = nfmpi_inq_malloc_size(malloc_size)
+ if (err .EQ. NF_NOERR) then
+ call MPI_Reduce(malloc_size, sum_size, 1, MPI_OFFSET,
+ + MPI_SUM, 0, MPI_COMM_WORLD, err)
+ if (rank .EQ. 0 .AND. sum_size .GT. 0)
+ + print 998,
+ + 'heap memory allocated by PnetCDF internally has ',
+ + sum_size/1048576, ' MiB yet to be freed'
+ endif
+
+ 999 call MPI_Finalize(err)
+ ! call EXIT(0) ! EXIT() is a GNU extension
+
+ end
+
diff --git a/examples/F77/put_vara.f b/examples/F77/put_vara.f
new file mode 100644
index 0000000..0225e49
--- /dev/null
+++ b/examples/F77/put_vara.f
@@ -0,0 +1,159 @@
+!
+! Copyright (C) 2013, Northwestern University
+! See COPYRIGHT notice in top-level directory.
+!
+! $Id: put_vara.f 2245 2015-12-20 18:39:52Z wkliao $
+
+!
+! This example shows how to use nfmpi_put_vara_int_all() to write a 2D
+! 4-byte integer array in parallel. It first defines a netCDF variable of
+! size global_nx * global_ny where
+! global_nx == 5 and
+! global_ny == (4 * number of MPI processes).
+! The data partitioning pattern is a column-wise partitioning across all
+! processes. Each process writes a subarray of size nx * ny.
+! Note the description above follows the Fortran array index order.
+!
+! Example commands for MPI run and outputs from running ncmpidump on the
+! NC file produced by this example program:
+!
+! % mpif77 -O2 -o put_vara put_vara.f -lpnetcdf
+! % mpiexec -n 4 ./put_vara /pvfs2/wkliao/testfile.nc
+!
+! % ncmpidump /pvfs2/wkliao/testfile.nc
+! netcdf testfile {
+! // file format: CDF-5 (big variables)
+! dimensions:
+! x = 5 ;
+! y = 16 ;
+! variables:
+! int var(y, x) ;
+! data:
+!
+! var =
+! 0, 0, 0, 0, 0,
+! 0, 0, 0, 0, 0,
+! 0, 0, 0, 0, 0,
+! 0, 0, 0, 0, 0,
+! 1, 1, 1, 1, 1,
+! 1, 1, 1, 1, 1,
+! 1, 1, 1, 1, 1,
+! 1, 1, 1, 1, 1,
+! 2, 2, 2, 2, 2,
+! 2, 2, 2, 2, 2,
+! 2, 2, 2, 2, 2,
+! 2, 2, 2, 2, 2,
+! 3, 3, 3, 3, 3,
+! 3, 3, 3, 3, 3,
+! 3, 3, 3, 3, 3,
+! 3, 3, 3, 3, 3 ;
+! }
+!
+ subroutine check(err, message)
+ implicit none
+ include 'mpif.h'
+ include 'pnetcdf.inc'
+ integer err
+ character message*(*)
+
+ ! It is a good idea to check returned value for possible error
+ if (err .NE. NF_NOERR) then
+ write(6,*) message//' '//nfmpi_strerror(err)
+ call MPI_Abort(MPI_COMM_WORLD, -1, err)
+ end if
+ end ! subroutine check
+
+ program main
+ implicit none
+ include 'mpif.h'
+ include 'pnetcdf.inc'
+
+ character*128 filename, cmd
+ integer i, j, err, ierr, nprocs, rank, get_args, dummy
+ integer cmode, ncid, varid, dimid(2)
+ integer*8 nx, ny, global_nx, global_ny
+ integer*8 starts(2), counts(2)
+ PARAMETER(nx=5, ny=4)
+ integer buf(nx,ny)
+ integer*8 malloc_size, sum_size
+ logical verbose
+
+ call MPI_Init(err)
+ call MPI_Comm_rank(MPI_COMM_WORLD, rank, err)
+ call MPI_Comm_size(MPI_COMM_WORLD, nprocs, err)
+
+ ! take filename from command-line argument if there is any
+ if (rank .EQ. 0) then
+ verbose = .TRUE.
+ filename = "testfile.nc"
+ ierr = get_args(2, cmd, filename, verbose, dummy)
+ endif
+ call MPI_Bcast(ierr, 1, MPI_INTEGER, 0, MPI_COMM_WORLD, err)
+ if (ierr .EQ. 0) goto 999
+
+ call MPI_Bcast(verbose, 1, MPI_LOGICAL, 0, MPI_COMM_WORLD,
+ + err)
+ call MPI_Bcast(filename, 256, MPI_CHARACTER, 0,
+ + MPI_COMM_WORLD, err)
+
+ ! set parameters
+ global_nx = nx
+ global_ny = ny * nprocs
+
+ do i=1, ny
+ do j=1, nx
+ buf(j,i) = rank
+ enddo
+ enddo
+
+ ! create file, truncate it if exists
+ cmode = IOR(NF_CLOBBER, NF_64BIT_DATA)
+ err = nfmpi_create(MPI_COMM_WORLD, filename, cmode,
+ + MPI_INFO_NULL, ncid)
+ call check(err, 'In nfmpi_create: ')
+
+ ! define dimensions x and y
+ err = nfmpi_def_dim(ncid, "x", global_nx, dimid(1))
+ call check(err, 'In nfmpi_def_dim x: ')
+ err = nfmpi_def_dim(ncid, "y", global_ny, dimid(2))
+ call check(err, 'In nfmpi_def_dim y: ')
+
+ ! define a 2D variable of integer type
+ err = nfmpi_def_var(ncid, "var", NF_INT, 2, dimid, varid)
+ call check(err, 'In nfmpi_def_var: ')
+
+ ! do not forget to exit define mode
+ err = nfmpi_enddef(ncid)
+ call check(err, 'In nfmpi_enddef: ')
+
+ ! now we are in data mode
+
+ ! Note that in Fortran, array indices start with 1
+ starts(1) = 1
+ starts(2) = ny * rank + 1
+ counts(1) = nx
+ counts(2) = ny
+
+ err = nfmpi_put_vara_int_all(ncid, varid, starts, counts, buf)
+ call check(err, 'In nfmpi_put_vara_int_all: ')
+
+ ! close the file
+ err = nfmpi_close(ncid)
+ call check(err, 'In nfmpi_close: ')
+
+ ! check if there is any PnetCDF internal malloc residue
+ 998 format(A,I13,A)
+ err = nfmpi_inq_malloc_size(malloc_size)
+ if (err .EQ. NF_NOERR) then
+ call MPI_Reduce(malloc_size, sum_size, 1, MPI_OFFSET,
+ + MPI_SUM, 0, MPI_COMM_WORLD, err)
+ if (rank .EQ. 0 .AND. sum_size .GT. 0)
+ + print 998,
+ + 'heap memory allocated by PnetCDF internally has ',
+ + sum_size/1048576, ' MiB yet to be freed'
+ endif
+
+ 999 call MPI_Finalize(err)
+ ! call EXIT(0) ! EXIT() is a GNU extension
+ end ! program main
+
diff --git a/examples/F77/put_varn_int.f b/examples/F77/put_varn_int.f
new file mode 100644
index 0000000..a9af29d
--- /dev/null
+++ b/examples/F77/put_varn_int.f
@@ -0,0 +1,257 @@
+!
+! Copyright (C) 2013, Northwestern University
+! See COPYRIGHT notice in top-level directory.
+!
+! $Id: put_varn_int.f 2224 2015-12-16 06:10:36Z wkliao $
+
+! This example shows how to use a single call of nfmpi_put_varn_int_all() to
+! write a sequence of requests with arbitrary array indices and lengths.
+! Using nfmpi_put_varn_int_all() can achieve the same effect of HDF5 writing
+! a sequence of selected file locations through the following 2 APIs.
+!
+! H5Sselect_elements(fid, H5S_SELECT_SET, NUMP, (const hssize_t **)coord);
+! H5Dwrite(dataset, H5T_NATIVE_INT, mid, fid, H5P_DEFAULT, val);
+!
+! Note that in nfmpi_put_varn_int_all(), users can write more than one element
+! starting at each selected location.
+!
+! The compile and run commands are given below, together with an ncmpidump of
+! the output file.
+!
+! % mpif77 -O2 -o put_varn_int put_varn_int.f -lpnetcdf
+! % mpiexec -n 4 ./put_varn_int /pvfs2/wkliao/testfile.nc
+! % ncmpidump /pvfs2/wkliao/testfile.nc
+! netcdf testfile {
+! // file format: CDF-5 (big variables)
+! dimensions:
+! X = 4 ;
+! Y = 10 ;
+! variables:
+! int var(Y, X) ;
+! data:
+!
+! var =
+! 2, 2, 1, 1,
+! 2, 2, 0, 0,
+! 1, 1, 0, 0,
+! 1, 1, 3, 3,
+! 3, 3, 2, 2,
+! 0, 0, 1, 1,
+! 0, 0, 1, 1,
+! 2, 2, 0, 0,
+! 3, 3, 3, 3,
+! 3, 3, 3, 3 ;
+! }
+!
+! Note the above dump is in C order
+!
+ subroutine check(err, message)
+ implicit none
+ include "mpif.h"
+ include "pnetcdf.inc"
+ integer err
+ character message*(*)
+
+ ! It is a good idea to check returned value for possible error
+ if (err .NE. NF_NOERR) then
+ write(6,*) message//' '//nfmpi_strerror(err)
+ call MPI_Abort(MPI_COMM_WORLD, -1, err)
+ end if
+ end ! subroutine check
+
+ program main
+ implicit none
+ include "mpif.h"
+ include "pnetcdf.inc"
+
+ integer NDIMS
+ integer*8 NX, NY
+ PARAMETER(NDIMS=2, NX=4, NY=10)
+
+ character*128 filename, cmd
+ integer i, j, err, ierr, nprocs, rank, get_args, dummy
+ integer cmode, ncid, varid, dimid(NDIMS), num_reqs
+
+ integer*8 w_len, w_req_len
+ integer*8 starts(NDIMS,5)
+ integer*8 counts(NDIMS,5)
+ integer*8 malloc_size, sum_size
+ integer buffer(1024)
+ logical verbose
+
+ call MPI_Init(err)
+ call MPI_Comm_rank(MPI_COMM_WORLD, rank, err)
+ call MPI_Comm_size(MPI_COMM_WORLD, nprocs, err)
+
+ ! take filename from command-line argument if there is any
+ if (rank .EQ. 0) then
+ verbose = .TRUE.
+ filename = "testfile.nc"
+ ierr = get_args(2, cmd, filename, verbose, dummy)
+ endif
+ call MPI_Bcast(ierr, 1, MPI_INTEGER, 0, MPI_COMM_WORLD, err)
+ if (ierr .EQ. 0) goto 999
+
+ call MPI_Bcast(verbose, 1, MPI_LOGICAL, 0, MPI_COMM_WORLD,
+ + err)
+ call MPI_Bcast(filename, 256, MPI_CHARACTER, 0,
+ + MPI_COMM_WORLD, err)
+
+ if (nprocs .NE. 4 .AND. rank .EQ. 0 .AND. verbose)
+ + print*,'Warning: ',cmd,' is intended to run on ',
+ + '4 processes'
+
+ ! create file, truncate it if exists
+ cmode = IOR(NF_CLOBBER, NF_64BIT_DATA)
+ err = nfmpi_create(MPI_COMM_WORLD, filename, cmode,
+ + MPI_INFO_NULL, ncid)
+ call check(err, 'In nfmpi_create: ')
+
+ ! define dimensions x and y
+ err = nfmpi_def_dim(ncid, "X", NX, dimid(1))
+ call check(err, 'In nfmpi_def_dim X: ')
+ err = nfmpi_def_dim(ncid, "Y", NY, dimid(2))
+ call check(err, 'In nfmpi_def_dim Y: ')
+
+ ! define a 2D variable of integer type
+ err = nfmpi_def_var(ncid, "var", NF_INT, NDIMS, dimid, varid)
+ call check(err, 'In nfmpi_def_var: ')
+
+ ! do not forget to exit define mode
+ err = nfmpi_enddef(ncid)
+ call check(err, 'In nfmpi_enddef: ')
+
+ ! now we are in data mode
+
+ ! pick arbitrary numbers of requests for 4 processes
+ num_reqs = 0
+ if (rank .EQ. 0) then
+ num_reqs = 3
+ elseif (rank .EQ. 1) then
+ num_reqs = 3
+ elseif (rank .EQ. 2) then
+ num_reqs = 3
+ elseif (rank .EQ. 3) then
+ num_reqs = 3
+ endif
+
+ ! Note that in Fortran, array indices start with 1
+
+ ! assign arbitrary starts and counts
+ if (rank .EQ. 0) then
+ ! rank 0 is writing the followings: ("-" means skip)
+ ! - - - - - 0 0 - - -
+ ! - - - - - 0 0 - - -
+ ! - 0 0 - - - - 0 - -
+ ! - 0 0 - - - - 0 - -
+ ! Note this is in Fortran order
+ starts(1, 1) = 1
+ starts(2, 1) = 6
+ counts(1, 1) = 2
+ counts(2, 1) = 2
+ starts(1, 2) = 3
+ starts(2, 2) = 2
+ counts(1, 2) = 2
+ counts(2, 2) = 2
+ starts(1, 3) = 3
+ starts(2, 3) = 8
+ counts(1, 3) = 2
+ counts(2, 3) = 1
+ elseif (rank .EQ. 1) then
+ ! rank 1 is writing the followings: ("-" means skip)
+ ! - - 1 1 - - - - - -
+ ! - - 1 1 - - - - - -
+ ! 1 - - - - 1 1 - - -
+ ! 1 - - - - 1 1 - - -
+ ! Note this is in Fortran order
+ starts(1, 1) = 1
+ starts(2, 1) = 3
+ counts(1, 1) = 2
+ counts(2, 1) = 2
+ starts(1, 2) = 3
+ starts(2, 2) = 1
+ counts(1, 2) = 2
+ counts(2, 2) = 1
+ starts(1, 3) = 3
+ starts(2, 3) = 6
+ counts(1, 3) = 2
+ counts(2, 3) = 2
+ elseif (rank .EQ. 2) then
+ ! rank 2 is writing the followings: ("-" means skip)
+ ! 2 2 - - - - - 2 - -
+ ! 2 2 - - - - - 2 - -
+ ! - - - - 2 - - - - -
+ ! - - - - 2 - - - - -
+ ! Note this is in Fortran order
+ starts(1, 1) = 1
+ starts(2, 1) = 1
+ counts(1, 1) = 2
+ counts(2, 1) = 2
+ starts(1, 2) = 1
+ starts(2, 2) = 8
+ counts(1, 2) = 2
+ counts(2, 2) = 1
+ starts(1, 3) = 3
+ starts(2, 3) = 5
+ counts(1, 3) = 2
+ counts(2, 3) = 1
+ elseif (rank .EQ. 3) then
+ ! rank 3 is writing the followings: ("-" means skip)
+ ! - - - - 3 - - - 3 3
+ ! - - - - 3 - - - 3 3
+ ! - - - 3 - - - - 3 3
+ ! - - - 3 - - - - 3 3
+ ! Note this is in Fortran order
+ starts(1, 1) = 1
+ starts(2, 1) = 5
+ counts(1, 1) = 2
+ counts(2, 1) = 1
+ starts(1, 2) = 1
+ starts(2, 2) = 9
+ counts(1, 2) = 4
+ counts(2, 2) = 2
+ starts(1, 3) = 3
+ starts(2, 3) = 4
+ counts(1, 3) = 2
+ counts(2, 3) = 1
+ endif
+
+ ! w_len is total write length for this process
+ w_len = 0
+ do i=1, num_reqs
+ w_req_len = 1
+ do j=1, NDIMS
+ w_req_len = w_req_len * counts(j, i)
+ enddo
+ w_len = w_len + w_req_len
+ enddo
+
+ ! initialize buffer contents
+ do i=1, 1024
+ buffer(i) = rank
+ enddo
+
+ err = nfmpi_put_varn_int_all(ncid, varid, num_reqs, starts,
+ + counts, buffer)
+ call check(err, 'In nfmpi_put_varn_int_all: ')
+
+ ! close the file
+ err = nfmpi_close(ncid)
+ call check(err, 'In nfmpi_close: ')
+
+ ! check if there is any PnetCDF internal malloc residue
+ 998 format(A,I13,A)
+ err = nfmpi_inq_malloc_size(malloc_size)
+ if (err .EQ. NF_NOERR) then
+ call MPI_Reduce(malloc_size, sum_size, 1, MPI_OFFSET,
+ + MPI_SUM, 0, MPI_COMM_WORLD, err)
+ if (rank .EQ. 0 .AND. sum_size .GT. 0)
+ + print 998,
+ + 'heap memory allocated by PnetCDF internally has ',
+ + sum_size/1048576, ' MiB yet to be freed'
+ endif
+
+ 999 call MPI_Finalize(err)
+ ! call EXIT(0) ! EXIT() is a GNU extension
+ end ! program main
+
diff --git a/examples/F77/put_varn_real.f b/examples/F77/put_varn_real.f
new file mode 100644
index 0000000..d2dd79f
--- /dev/null
+++ b/examples/F77/put_varn_real.f
@@ -0,0 +1,261 @@
+!
+! Copyright (C) 2012, Northwestern University and Argonne National Laboratory
+! See COPYRIGHT notice in top-level directory.
+!
+! $Id: put_varn_real.f 2224 2015-12-16 06:10:36Z wkliao $
+
+!
+! This example shows how to use a single call of nfmpi_put_varn_real_all()
+! to write a sequence of one-element requests with arbitrary array indices.
+!
+! The compile and run commands are given below, together with an ncmpidump of
+! the output file.
+!
+! % mpif77 -O2 -o put_varn_real put_varn_real.f -lpnetcdf
+! % mpiexec -n 4 ./put_varn_real /pvfs2/wkliao/testfile.nc
+! % ncmpidump /pvfs2/wkliao/testfile.nc
+! netcdf testfile {
+! // file format: CDF-5 (big variables)
+! dimensions:
+! Y = 4 ;
+! X = 10 ;
+! variables:
+! int var(Y, X) ;
+! data:
+!
+! var =
+! 3, 3, 3, 1, 1, 0, 0, 2, 1, 1,
+! 0, 2, 2, 2, 3, 1, 1, 2, 2, 2,
+! 1, 1, 2, 3, 3, 3, 0, 0, 1, 1,
+! 0, 0, 0, 2, 1, 1, 1, 3, 3, 3 ;
+! }
+!
+
+ subroutine check(err, message)
+ implicit none
+ include "mpif.h"
+ include "pnetcdf.inc"
+ integer err
+ character message*(*)
+
+ ! It is a good idea to check returned value for possible error
+ if (err .NE. NF_NOERR) then
+ write(6,*) message//' '//nfmpi_strerror(err)
+ call MPI_Abort(MPI_COMM_WORLD, -1, err)
+ end if
+ end ! subroutine check
+
+ program main
+ implicit none
+ include "mpif.h"
+ include "pnetcdf.inc"
+
+ integer NDIMS
+ PARAMETER(NDIMS=2)
+
+ character*128 filename, cmd
+ integer rank, nprocs, err, num_reqs, ierr, get_args, dummy
+ integer i, j, ncid, cmode, varid, dimid(2), y, x
+ real buffer(13)
+ integer*8 NY, NX
+ integer*8 starts(NDIMS, 13)
+ integer*8 counts(NDIMS, 13)
+ integer*8 malloc_size, sum_size
+ logical verbose
+
+ NY = 4
+ NX = 10
+
+ call MPI_Init(err)
+ call MPI_Comm_rank(MPI_COMM_WORLD, rank, err)
+ call MPI_Comm_size(MPI_COMM_WORLD, nprocs, err)
+
+ ! take filename from command-line argument if there is any
+ if (rank .EQ. 0) then
+ verbose = .TRUE.
+ filename = "testfile.nc"
+ ierr = get_args(2, cmd, filename, verbose, dummy)
+ endif
+ call MPI_Bcast(ierr, 1, MPI_INTEGER, 0, MPI_COMM_WORLD, err)
+ if (ierr .EQ. 0) goto 999
+
+ call MPI_Bcast(verbose, 1, MPI_LOGICAL, 0, MPI_COMM_WORLD,
+ + err)
+ call MPI_Bcast(filename, 256, MPI_CHARACTER, 0,
+ + MPI_COMM_WORLD, err)
+
+ if (nprocs .NE. 4 .AND. rank .EQ. 0 .AND. verbose)
+ + print*,'Warning: ',cmd,' is intended to run on ',
+ + '4 processes'
+
+ ! create file, truncate it if exists
+ cmode = IOR(NF_CLOBBER, NF_64BIT_DATA)
+ err = nfmpi_create(MPI_COMM_WORLD, filename, cmode,
+ + MPI_INFO_NULL, ncid)
+ call check(err, 'In nfmpi_create: ')
+
+ ! create a global array of size NY * NX */
+ err = nfmpi_def_dim(ncid, "Y", NY, dimid(2))
+ call check(err, 'In nfmpi_def_dim Y: ')
+ err = nfmpi_def_dim(ncid, "X", NX, dimid(1))
+ call check(err, 'In nfmpi_def_dim X: ')
+ err = nfmpi_def_var(ncid, "var", NF_FLOAT, NDIMS, dimid,
+ + varid)
+ call check(err, 'In nfmpi_def_var var: ')
+ err = nfmpi_enddef(ncid)
+ call check(err, 'In nfmpi_enddef: ')
+
+ ! pick arbitrary numbers of requests for 4 processes
+ num_reqs = 0
+ if (rank .EQ. 0) then
+ num_reqs = 8
+ elseif (rank .EQ. 1) then
+ num_reqs = 13
+ elseif (rank .EQ. 2) then
+ num_reqs = 9
+ elseif (rank .EQ. 3) then
+ num_reqs = 10
+ endif
+
+ ! assign arbitrary starts
+ y=2
+ x=1
+ if (rank .EQ. 0) then
+ starts(y, 1) = 1
+ starts(x, 1) = 6
+ starts(y, 2) = 2
+ starts(x, 2) = 1
+ starts(y, 3) = 3
+ starts(x, 3) = 7
+ starts(y, 4) = 4
+ starts(x, 4) = 1
+ starts(y, 5) = 1
+ starts(x, 5) = 7
+ starts(y, 6) = 3
+ starts(x, 6) = 8
+ starts(y, 7) = 4
+ starts(x, 7) = 2
+ starts(y, 8) = 4
+ starts(x, 8) = 3
+ ! rank 0 is writing the following locations: ("-" means skip)
+ ! - - - - - 0 0 - - -
+ ! 0 - - - - - - - - -
+ ! - - - - - - 0 0 - -
+ ! 0 0 0 - - - - - - -
+ elseif (rank .EQ. 1) then
+ starts(y, 1) = 1
+ starts(x, 1) = 4
+ starts(y, 2) = 1
+ starts(x, 2) = 9
+ starts(y, 3) = 2
+ starts(x, 3) = 6
+ starts(y, 4) = 3
+ starts(x, 4) = 1
+ starts(y, 5) = 3
+ starts(x, 5) = 9
+ starts(y, 6) = 4
+ starts(x, 6) = 5
+ starts(y, 7) = 1
+ starts(x, 7) = 5
+ starts(y, 8) = 1
+ starts(x, 8) = 10
+ starts(y, 9) = 2
+ starts(x, 9) = 7
+ starts(y, 10) = 3
+ starts(x, 10) = 2
+ starts(y, 11) = 3
+ starts(x, 11) = 10
+ starts(y, 12) = 4
+ starts(x, 12) = 6
+ starts(y, 13) = 4
+ starts(x, 13) = 7
+ ! rank 1 is writing the following locations: ("-" means skip)
+ ! - - - 1 1 - - - 1 1
+ ! - - - - - 1 1 - - -
+ ! 1 1 - - - - - - 1 1
+ ! - - - - 1 1 1 - - -
+ elseif (rank .EQ. 2) then
+ starts(y, 1) = 1
+ starts(x, 1) = 8
+ starts(y, 2) = 2
+ starts(x, 2) = 2
+ starts(y, 3) = 2
+ starts(x, 3) = 8
+ starts(y, 4) = 3
+ starts(x, 4) = 3
+ starts(y, 5) = 4
+ starts(x, 5) = 4
+ starts(y, 6) = 2
+ starts(x, 6) = 3
+ starts(y, 7) = 2
+ starts(x, 7) = 9
+ starts(y, 8) = 2
+ starts(x, 8) = 4
+ starts(y, 9) = 2
+ starts(x, 9) = 10
+ ! rank 2 is writing the following locations: ("-" means skip)
+ ! - - - - - - - 2 - -
+ ! - 2 2 2 - - - 2 2 2
+ ! - - 2 - - - - - - -
+ ! - - - 2 - - - - - -
+ elseif (rank .EQ. 3) then
+ starts(y, 1) = 1
+ starts(x, 1) = 1
+ starts(y, 2) = 2
+ starts(x, 2) = 5
+ starts(y, 3) = 3
+ starts(x, 3) = 4
+ starts(y, 4) = 4
+ starts(x, 4) = 8
+ starts(y, 5) = 1
+ starts(x, 5) = 2
+ starts(y, 6) = 3
+ starts(x, 6) = 5
+ starts(y, 7) = 4
+ starts(x, 7) = 9
+ starts(y, 8) = 1
+ starts(x, 8) = 3
+ starts(y, 9) = 3
+ starts(x, 9) = 6
+ starts(y, 10) = 4
+ starts(x, 10) = 10
+ ! rank 3 is writing the following locations: ("-" means skip)
+ ! 3 3 3 - - - - - - -
+ ! - - - - 3 - - - - -
+ ! - - - 3 3 3 - - - -
+ ! - - - - - - - 3 3 3
+ endif
+
+ ! allocate I/O buffer and initialize its contents
+ do i=1, 13
+ buffer(i) = rank
+ do j=1, NDIMS
+ counts(j,i) = 1
+ enddo
+ enddo
+
+ ! set the buffer pointers to different offsets to the I/O buffer
+ err = nfmpi_put_varn_real_all(ncid, varid, num_reqs, starts,
+ + counts, buffer)
+ call check(err, 'In nfmpi_put_varn_real_all: ')
+
+ err = nfmpi_close(ncid)
+ call check(err, 'In nfmpi_close: ')
+
+ ! check if there is any PnetCDF internal malloc residue
+ 998 format(A,I13,A)
+ err = nfmpi_inq_malloc_size(malloc_size)
+ if (err .EQ. NF_NOERR) then
+ call MPI_Reduce(malloc_size, sum_size, 1, MPI_OFFSET,
+ + MPI_SUM, 0, MPI_COMM_WORLD, err)
+ if (rank .EQ. 0 .AND. sum_size .GT. 0)
+ + print 998,
+ + 'heap memory allocated by PnetCDF internally has ',
+ + sum_size/1048576, ' MiB yet to be freed'
+ endif
+
+ 999 call MPI_Finalize(err)
+ ! call EXIT(0) ! EXIT() is a GNU extension
+
+ end ! program
+
diff --git a/examples/F77/transpose.f b/examples/F77/transpose.f
new file mode 100644
index 0000000..73bd1b8
--- /dev/null
+++ b/examples/F77/transpose.f
@@ -0,0 +1,290 @@
+!
+! Copyright (C) 2014, Northwestern University
+! See COPYRIGHT notice in top-level directory.
+!
+! $Id: transpose.f 2224 2015-12-16 06:10:36Z wkliao $
+
+!
+! This example shows how to use varm API to write six 3D integer
+! array variables into a file. Each variable in the file is a
+! dimensional transposed array from the one stored in memory. In
+! memory, a 3D array is partitioned among all processes in a
+! block-block-block fashion and in XYZ (i.e. Fortran) order. Note
+! the variable and dimension naming below is in Fortran order. The
+! dimension structures of the transposed six arrays are
+! integer XYZ_var(X, Y, Z) XYZ -> XYZ (no transpose)
+! integer XZY_var(X, Z, Y) XYZ -> XZY
+! integer YXZ_var(Y, X, Z) XYZ -> YXZ
+! integer YZX_var(Y, Z, X) XYZ -> YZX
+! integer ZXY_var(Z, X, Y) XYZ -> ZXY
+! integer ZYX_var(Z, Y, X) XYZ -> ZYX
+!
+! To compile:
+! mpif77 -O2 transpose.f -o transpose -lpnetcdf
+! To run:
+! mpiexec -n num_processes ./transpose [filename] [len]
+! where len decides the size of local array, which is
+! (len+2) x (len+1) x len. So, each variable is of size
+! (len+2)*(len+1)*len * nprocs * sizeof(int)
+!
+ subroutine check(err, message)
+ implicit none
+ include 'mpif.h'
+ include 'pnetcdf.inc'
+ integer err
+ character message*(*)
+
+ ! It is a good idea to check returned value for possible error
+ if (err .NE. NF_NOERR) then
+ write(6,*) message//' '//nfmpi_strerror(err)
+ call MPI_Abort(MPI_COMM_WORLD, -1, err)
+ end if
+ end ! subroutine check
+
+ program main
+ implicit none
+ include 'mpif.h'
+ include 'pnetcdf.inc'
+
+ character*128 filename, cmd
+ integer err, ierr, nprocs, rank, lower_dims, get_args, dummy
+ integer cmode, ncid, psizes(3), dimids(3), dimidsT(3)
+ integer XYZ_id, XZY_id, YZX_id, YXZ_id, ZYX_id, ZXY_id
+ integer*8 gsizes(3), starts(3)
+ integer*8 counts(3), strides(3), imap(3)
+ integer*8 startsT(3), countsT(3)
+ integer*8 malloc_size, sum_size, one
+ integer i, j, k, nx, ny, nz
+ PARAMETER(nx=4, ny=3, nz=2)
+ integer buf(nx,ny,nz)
+ logical verbose
+
+ call MPI_Init(err)
+ call MPI_Comm_rank(MPI_COMM_WORLD, rank, err)
+ call MPI_Comm_size(MPI_COMM_WORLD, nprocs, err)
+
+ one = 1
+ ! take filename from command-line argument if there is any
+ if (rank .EQ. 0) then
+ verbose = .TRUE.
+ filename = "testfile.nc"
+ ierr = get_args(2, cmd, filename, verbose, dummy)
+ endif
+ call MPI_Bcast(ierr, 1, MPI_INTEGER, 0, MPI_COMM_WORLD, err)
+ if (ierr .EQ. 0) goto 999
+
+ call MPI_Bcast(verbose, 1, MPI_LOGICAL, 0, MPI_COMM_WORLD,
+ + err)
+ call MPI_Bcast(filename, 256, MPI_CHARACTER, 0,
+ + MPI_COMM_WORLD, err)
+
+ ! calculate number of processes along each dimension
+ psizes(1) = 0
+ psizes(2) = 0
+ psizes(3) = 0
+ call MPI_Dims_create(nprocs, 3, psizes, err)
+ if (verbose .AND. rank .EQ. 0) print*, "psizes= ",psizes(1),
+ + psizes(2),psizes(3)
+
+ ! for each MPI rank, find its local rank IDs along each dimension in
+ ! starts()
+ lower_dims = 1
+ do i=1, 3
+ starts(i) = MOD(rank / lower_dims, psizes(i))
+ lower_dims = lower_dims * psizes(i)
+ enddo
+ if (verbose)
+ + print*, "proc ",rank,": dim rank= ",starts(1),starts(2),
+ + starts(3)
+
+ strides(1) = 1
+ strides(2) = 1
+ strides(3) = 1
+ gsizes(1) = nx
+ gsizes(2) = ny
+ gsizes(3) = nz
+ do i=1, 3
+ starts(i) = starts(i) * gsizes(i) + 1 ! start indices
+ counts(i) = gsizes(i) ! array elements
+ gsizes(i) = gsizes(i) * psizes(i) ! global array size
+ enddo
+
+ if (verbose) then
+ print*, "proc ",rank,": starts= ",starts(1),starts(2),
+ + starts(3)
+ print*, "proc ",rank,": counts= ",counts(1),counts(2),
+ + counts(3)
+ endif
+
+ ! initialize buffer with contiguous numbers
+ do k=1, nz
+ do j=1, ny
+ do i=1, nx
+ buf(i, j, k) = INT((starts(3)+k-2)*gsizes(2)*gsizes(1) +
+ + (starts(2)+j-2)*gsizes(1) +
+ + (starts(1)+i-2))
+ enddo
+ enddo
+ enddo
+ if (verbose .AND. rank .EQ. 0) print*, "buf= ",buf
+
+ ! create file, truncate it if exists
+ cmode = IOR(NF_CLOBBER, NF_64BIT_DATA)
+ cmode = NF_CLOBBER
+ err = nfmpi_create(MPI_COMM_WORLD, filename, cmode,
+ + MPI_INFO_NULL, ncid)
+ call check(err, 'In nfmpi_create: ')
+
+ ! define dimensions X, Y, Z
+ err = nfmpi_def_dim(ncid, "X", gsizes(1), dimids(1))
+ call check(err, 'In nfmpi_def_dim X: ')
+ err = nfmpi_def_dim(ncid, "Y", gsizes(2), dimids(2))
+ call check(err, 'In nfmpi_def_dim Y: ')
+ err = nfmpi_def_dim(ncid, "Z", gsizes(3), dimids(3))
+ call check(err, 'In nfmpi_def_dim Z: ')
+
+ ! define variable with no transposed file layout: XYZ
+ err = nfmpi_def_var(ncid, "XYZ_var", NF_INT, 3, dimids,
+ + XYZ_id)
+ call check(err, 'In nfmpi_def_var XYZ_var: ')
+
+ ! define variable with transposed file layout: XYZ -> XZY
+ dimidsT(1) = dimids(1)
+ dimidsT(2) = dimids(3)
+ dimidsT(3) = dimids(2)
+ err = nfmpi_def_var(ncid, "XZY_var", NF_INT, 3, dimidsT,
+ + XZY_id)
+ call check(err, 'In nfmpi_def_var XZY_var: ')
+
+ ! define variable with transposed file layout: XYZ -> YXZ
+ dimidsT(1) = dimids(2)
+ dimidsT(2) = dimids(1)
+ dimidsT(3) = dimids(3)
+ err = nfmpi_def_var(ncid, "YXZ_var", NF_INT, 3, dimidsT,
+ + YXZ_id)
+ call check(err, 'In nfmpi_def_var YXZ_var: ')
+
+ ! define variable with transposed file layout: XYZ -> YZX
+ dimidsT(1) = dimids(2)
+ dimidsT(2) = dimids(3)
+ dimidsT(3) = dimids(1)
+ err = nfmpi_def_var(ncid, "YZX_var", NF_INT, 3, dimidsT,
+ + YZX_id)
+ call check(err, 'In nfmpi_def_var YZX_var: ')
+
+ ! define variable with transposed file layout: XYZ -> ZXY
+ dimidsT(1) = dimids(3)
+ dimidsT(2) = dimids(1)
+ dimidsT(3) = dimids(2)
+ err = nfmpi_def_var(ncid, "ZXY_var", NF_INT, 3, dimidsT,
+ + ZXY_id)
+ call check(err, 'In nfmpi_def_var ZXY_var: ')
+
+ ! define variable with transposed file layout: XYZ -> ZYX
+ dimidsT(1) = dimids(3)
+ dimidsT(2) = dimids(2)
+ dimidsT(3) = dimids(1)
+ err = nfmpi_def_var(ncid, "ZYX_var", NF_INT, 3, dimidsT,
+ + ZYX_id)
+ call check(err, 'In nfmpi_def_var ZYX_var: ')
+
+ ! do not forget to exit define mode
+ err = nfmpi_enddef(ncid)
+ call check(err, 'In nfmpi_enddef: ')
+
+ ! now we are in data mode
+
+ ! write the whole variable in file: XYZ
+ err = nfmpi_put_vara_int_all(ncid, XYZ_id, starts, counts,buf)
+ call check(err, 'In nfmpi_put_vara_int_all XYZ: ')
+
+ ! write the transposed variable: XYZ -> XZY
+ imap(1) = one
+ imap(2) = counts(1)*counts(2)
+ imap(3) = counts(1)
+ startsT(1) = starts(1)
+ startsT(2) = starts(3)
+ startsT(3) = starts(2)
+ countsT(1) = counts(1)
+ countsT(2) = counts(3)
+ countsT(3) = counts(2)
+ err = nfmpi_put_varm_int_all(ncid, XZY_id, startsT, countsT,
+ + strides, imap, buf)
+ call check(err, 'In nfmpi_put_varm_int_all XZY: ')
+
+ ! write the transposed variable: XYZ -> YXZ
+ imap(1) = counts(1)
+ imap(2) = one
+ imap(3) = counts(1)*counts(2)
+ startsT(1) = starts(2)
+ startsT(2) = starts(1)
+ startsT(3) = starts(3)
+ countsT(1) = counts(2)
+ countsT(2) = counts(1)
+ countsT(3) = counts(3)
+ err = nfmpi_put_varm_int_all(ncid, YXZ_id, startsT, countsT,
+ + strides, imap, buf)
+ call check(err, 'In nfmpi_put_varm_int_all YZX: ')
+
+ ! write the transposed variable: XYZ -> YZX
+ imap(1) = counts(1)
+ imap(2) = counts(1)*counts(2)
+ imap(3) = one
+ startsT(1) = starts(2)
+ startsT(2) = starts(3)
+ startsT(3) = starts(1)
+ countsT(1) = counts(2)
+ countsT(2) = counts(3)
+ countsT(3) = counts(1)
+ err = nfmpi_put_varm_int_all(ncid, YZX_id, startsT, countsT,
+ + strides, imap, buf)
+ call check(err, 'In nfmpi_put_varm_int_all YZX: ')
+
+ ! write the transposed variable: XYZ -> ZXY
+ imap(1) = counts(1)*counts(2)
+ imap(2) = one
+ imap(3) = counts(1)
+ startsT(1) = starts(3)
+ startsT(2) = starts(1)
+ startsT(3) = starts(2)
+ countsT(1) = counts(3)
+ countsT(2) = counts(1)
+ countsT(3) = counts(2)
+ err = nfmpi_put_varm_int_all(ncid, ZXY_id, startsT, countsT,
+ + strides, imap, buf)
+ call check(err, 'In nfmpi_put_varm_int_all ZXY: ')
+
+ ! write the transposed variable: XYZ -> ZYX
+ imap(1) = counts(1)*counts(2)
+ imap(2) = counts(1)
+ imap(3) = one
+ startsT(1) = starts(3)
+ startsT(2) = starts(2)
+ startsT(3) = starts(1)
+ countsT(1) = counts(3)
+ countsT(2) = counts(2)
+ countsT(3) = counts(1)
+ err = nfmpi_put_varm_int_all(ncid, ZYX_id, startsT, countsT,
+ + strides, imap, buf)
+ call check(err, 'In nfmpi_put_varm_int_all ZYX: ')
+
+ ! close the file
+ err = nfmpi_close(ncid)
+ call check(err, 'In nfmpi_close: ')
+
+ ! check if there is any PnetCDF internal malloc residue
+ 998 format(A,I13,A)
+ err = nfmpi_inq_malloc_size(malloc_size)
+ if (err .EQ. NF_NOERR) then
+ call MPI_Reduce(malloc_size, sum_size, 1, MPI_OFFSET,
+ + MPI_SUM, 0, MPI_COMM_WORLD, err)
+ if (rank .EQ. 0 .AND. sum_size .GT. 0)
+ + print 998,
+ + 'heap memory allocated by PnetCDF internally has ',
+ + sum_size/1048576, ' MiB yet to be freed'
+ endif
+
+ 999 call MPI_Finalize(err)
+ ! call EXIT(0) ! EXIT() is a GNU extension
+ end ! program main
+
diff --git a/examples/F77/utils.F90 b/examples/F77/utils.F90
new file mode 100644
index 0000000..d83aeca
--- /dev/null
+++ b/examples/F77/utils.F90
@@ -0,0 +1,53 @@
+!
+! Copyright (C) 2015, Northwestern University and Argonne National Laboratory
+! See COPYRIGHT notice in top-level directory.
+!
+! This is part of the PnetCDF package.
+!
+! $Id: utils.F90 2120 2015-09-22 07:11:58Z wkliao $
+
+ ! This function gets the executable name and output file name from the
+ ! command line.
+ integer function get_args(max_argc, cmd, filename, verbose, len)
+#ifdef NAGf90Fortran
+ USE F90_UNIX_ENV, only : iargc, getarg
+ implicit none
+#else
+ implicit none
+ integer iargc
+#endif
+ integer max_argc, len
+ character(len=*) cmd, filename
+ logical verbose
+
+ ! local variables
+ integer argc
+ character(len=16) quiet_mode, str
+
+
+ call getarg(0, cmd)
+ argc = IARGC()
+ if (argc .GT. max_argc) then
+ if (max_argc .EQ. 3) &
+ print*,'Usage: ',trim(cmd),' [-q] [filename] [len]'
+ if (max_argc .EQ. 2) &
+ print*,'Usage: ',trim(cmd),' [-q] [filename]'
+ get_args = 0
+ return
+ endif
+ call getarg(1, quiet_mode)
+ if (quiet_mode(1:2) .EQ. '-q') then
+ verbose = .FALSE.
+ if (argc .GE. 2) call getarg(2, filename)
+ if (argc .EQ. 3) then
+ call getarg(3, str)
+ read (str,'(I10)') len
+ endif
+ else
+ if (argc .GE. 1) call getarg(1, filename)
+ if (argc .EQ. 2) then
+ call getarg(2, str)
+ read (str,'(I10)') len
+ endif
+ endif
+ end function get_args
diff --git a/examples/F77/vard_int.F b/examples/F77/vard_int.F
new file mode 100644
index 0000000..814f8f9
--- /dev/null
+++ b/examples/F77/vard_int.F
@@ -0,0 +1,233 @@
+!
+! Copyright (C) 2014, Northwestern University and Argonne National Laboratory
+! See COPYRIGHT notice in top-level directory.
+!
+! $Id: vard_int.F 2239 2015-12-18 18:21:09Z wkliao $
+
+!
+! This example shows how to use the vard API nfmpi_put_vard() and
+! nfmpi_get_vard() to write and read 2D record and fixed-size
+! variables.
+!
+! To compile:
+! mpif77 -O2 vard_int.f -o vard_int -lpnetcdf
+!
+! Example commands for MPI run and outputs from running ncmpidump on
+! the NC file produced by this example program:
+!
+! % mpiexec -n 4 ./vard_int /pvfs2/wkliao/testfile.nc
+!
+! The expected results from the output file contents are:
+!
+! % ncmpidump /pvfs2/wkliao/testfile.nc
+! netcdf testfile {
+! // file format: CDF-1
+! dimensions:
+! REC_DIM = UNLIMITED ; // (2 currently)
+! X = 12 ;
+! FIX_DIM = 2 ;
+! variables:
+! int rec_var(REC_DIM, X) ;
+! int fix_var(FIX_DIM, X) ;
+! data:
+!
+! rec_var =
+! 0, 1, 2, 100, 101, 102, 200, 201, 202, 300, 301, 302,
+! 10, 11, 12, 110, 111, 112, 210, 211, 212, 310, 311, 312 ;
+!
+! fix_var =
+! 0, 1, 2, 100, 101, 102, 200, 201, 202, 300, 301, 302,
+! 10, 11, 12, 110, 111, 112, 210, 211, 212, 310, 311, 312 ;
+! }
+!
+ subroutine check(err, message)
+ implicit none
+ include "mpif.h"
+ include "pnetcdf.inc"
+ integer err
+ character message*(*)
+
+ ! It is a good idea to check returned value for possible error
+ if (err .NE. NF_NOERR) then
+ write(6,*) message//' '//nfmpi_strerror(err)
+ call MPI_Abort(MPI_COMM_WORLD, -1, err)
+ end if
+ end ! subroutine check
+
+ program main
+ implicit none
+ include "mpif.h"
+ include "pnetcdf.inc"
+ character*128 filename, cmd
+ integer err, ierr, nprocs, rank, i, j, get_args, dummy
+ integer cmode, ncid, varid0, varid1, dimid(2)
+ integer*8 NX, NY, len, bufcount
+ integer*8 start(2), count(2)
+ PARAMETER(NX=3, NY=2)
+ integer buf(NX, NY)
+ integer buftype, rec_filetype, fix_filetype
+ integer array_of_sizes(2), array_of_subsizes(2)
+ integer array_of_starts(2), blocklengths(2)
+ integer*8 malloc_size, sum_size, recsize, two
+#ifdef SIZEOF_MPI_AINT_IS_4
+ integer disps(2)
+#else
+ integer*8 disps(2)
+#endif
+ logical verbose
+
+ call MPI_Init(err)
+ call MPI_Comm_rank(MPI_COMM_WORLD, rank, err)
+ call MPI_Comm_size(MPI_COMM_WORLD, nprocs, err)
+
+ two = 2
+ ! take filename from command-line argument if there is any
+ if (rank .EQ. 0) then
+ verbose = .TRUE.
+ filename = "testfile.nc"
+ ierr = get_args(2, cmd, filename, verbose, dummy)
+ endif
+ call MPI_Bcast(ierr, 1, MPI_INTEGER, 0, MPI_COMM_WORLD, err)
+ if (ierr .EQ. 0) goto 999
+
+ call MPI_Bcast(verbose, 1, MPI_LOGICAL, 0, MPI_COMM_WORLD,
+ + err)
+ call MPI_Bcast(filename, 256, MPI_CHARACTER, 0,
+ + MPI_COMM_WORLD, err)
+
+ start(1) = NX * rank
+ start(2) = 0
+ count(1) = NX
+ count(2) = 2
+
+ ! initialized buffer contents
+ do j=1, INT(count(2))
+ do i=1, INT(count(1))
+ buf(i, j) = rank*100 + j*10 + i
+ enddo
+ enddo
+
+ ! create file, truncate it if exists
+ cmode = NF_CLOBBER
+ err = nfmpi_create(MPI_COMM_WORLD, filename, cmode,
+ + MPI_INFO_NULL, ncid)
+ call check(err, 'In nfmpi_create: ')
+
+ ! define 2 dimensions
+ err = nfmpi_def_dim(ncid, "REC_DIM", NFMPI_UNLIMITED,dimid(2))
+ call check(err, 'In nfmpi_def_dim REC_DIM: ')
+ len = NX * nprocs
+ err = nfmpi_def_dim(ncid, "X", len, dimid(1))
+ call check(err, 'In nfmpi_def_dim X: ')
+
+ ! define 2D record variables of integer type
+ err = nfmpi_def_var(ncid, "rec_var", NF_INT, 2, dimid, varid0)
+ call check(err, 'In nfmpi_def_var: rec_var ')
+
+ ! define 2D fixed-size variable of integer type
+ err = nfmpi_def_dim(ncid, "FIX_DIM", two, dimid(2))
+ call check(err, 'In nfmpi_def_dim RECV_DIM: ')
+ err = nfmpi_def_var(ncid, "fix_var", NF_INT, 2, dimid, varid1)
+ call check(err, 'In nfmpi_def_var: fix_var ')
+
+ ! do not forget to exit define mode
+ err = nfmpi_enddef(ncid)
+ call check(err, 'In nfmpi_enddef: ')
+
+ ! create a file type for the record variable */
+ err = nfmpi_inq_recsize(ncid, recsize)
+ call check(err, 'In nfmpi_inq_recsize: ')
+ blocklengths(1) = INT(count(1))
+ blocklengths(2) = INT(count(1))
+ disps(1) = start(1)*4
+ disps(2) = recsize + start(1)*4
+ call MPI_Type_create_hindexed(2, blocklengths, disps,
+ + MPI_INTEGER, rec_filetype, err)
+ call MPI_Type_commit(rec_filetype, err)
+
+ ! create a file type for the fixed-size variable
+ array_of_sizes(1) = INT(NX*nprocs)
+ array_of_sizes(2) = 2
+ array_of_subsizes(1) = INT(count(1))
+ array_of_subsizes(2) = INT(count(2))
+ array_of_starts(1) = INT(start(1))
+ array_of_starts(2) = INT(start(2))
+ call MPI_Type_create_subarray(2, array_of_sizes,
+ + array_of_subsizes, array_of_starts, MPI_ORDER_FORTRAN,
+ + MPI_INTEGER, fix_filetype, err)
+ call MPI_Type_commit(fix_filetype, err)
+
+ bufcount = count(1) * count(2)
+ buftype = MPI_INTEGER
+
+ ! write the record variable */
+ err = nfmpi_put_vard_all(ncid, varid0, rec_filetype, buf,
+ + bufcount, buftype)
+ call check(err, 'In nfmpi_put_vard_all: ')
+
+ ! check if the number of records changed to 2
+ err = nfmpi_inq_unlimdim(ncid, dimid(2))
+ call check(err, 'In nfmpi_inq_unlimdim: ')
+ err = nfmpi_inq_dimlen(ncid, dimid(2), len)
+ call check(err, 'In nfmpi_inq_dimlen: ')
+ if (len .NE. 2) then
+ print*, 'Error: number of records should be 2 but got ',
+ + len
+ endif
+
+ ! write the fixed-size variable
+ err = nfmpi_put_vard_all(ncid, varid1, fix_filetype, buf,
+ + bufcount, buftype)
+ call check(err, 'In nfmpi_put_vard_all: ')
+
+ ! close the file
+ err = nfmpi_close(ncid)
+ call check(err, 'In nfmpi_close: ')
+
+ ! open the same file and read back for validate */
+ err = nfmpi_open(MPI_COMM_WORLD, filename, NF_NOWRITE,
+ + MPI_INFO_NULL, ncid)
+ call check(err, 'In nfmpi_open: ')
+
+ err = nfmpi_inq_varid(ncid, "rec_var", varid0)
+ call check(err, 'In nfmpi_inq_varid rec_var: ')
+ err = nfmpi_inq_varid(ncid, "fix_var", varid1)
+ call check(err, 'In nfmpi_inq_varid fix_var: ')
+
+ ! PnetCDF start() argument starts with 1
+ start(1) = start(1) + 1
+ start(2) = start(2) + 1
+
+ ! read back record variable
+ err = nfmpi_get_vard_all(ncid, varid0, rec_filetype, buf,
+ + bufcount, buftype)
+ call check(err, 'In nfmpi_get_vard_all: ')
+
+ ! read back fixed-size variable
+ err = nfmpi_get_vard_all(ncid, varid1, fix_filetype, buf,
+ + bufcount, buftype)
+ call check(err, 'In nfmpi_get_vard_all: ')
+
+ ! close the file
+ err = nfmpi_close(ncid)
+ call check(err, 'In nfmpi_close: ')
+
+ call MPI_Type_free(rec_filetype, err)
+ call MPI_Type_free(fix_filetype, err)
+
+ ! check if there is any PnetCDF internal malloc residue
+ 998 format(A,I13,A)
+ err = nfmpi_inq_malloc_size(malloc_size)
+ if (err .EQ. NF_NOERR) then
+ call MPI_Reduce(malloc_size, sum_size, 1, MPI_OFFSET,
+ + MPI_SUM, 0, MPI_COMM_WORLD, err)
+ if (rank .EQ. 0 .AND. sum_size .GT. 0)
+ + print 998,
+ + 'heap memory allocated by PnetCDF internally has ',
+ + sum_size/1048576, ' MiB yet to be freed'
+ endif
+
+ 999 call MPI_Finalize(err)
+ ! call EXIT(0) ! EXIT() is a GNU extension
+ end ! program main
+
diff --git a/examples/F90/Makefile.in b/examples/F90/Makefile.in
new file mode 100644
index 0000000..e5736fc
--- /dev/null
+++ b/examples/F90/Makefile.in
@@ -0,0 +1,123 @@
+#
+# Copyright (C) 2012, Northwestern University and Argonne National Laboratory
+# See COPYRIGHT notice in top-level directory.
+#
+# $Id: Makefile.in 2236 2015-12-18 03:49:41Z wkliao $
+#
+# @configure_input@
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+include ../../macros.make
+
+# note the order of -L list matters
+INCLUDES = @FC_MODINC at ../../src/libf90
+F90LDFLAGS := -L../../src/lib $(F90LDFLAGS) $(LDFLAGS)
+LIBS := -lpnetcdf $(LIBS)
+
+F90_SRCS = nonblocking_write.f90 \
+ column_wise.f90 \
+ block_cyclic.f90 \
+ flexible_api.f90 \
+ get_info.f90 \
+ hints.f90 \
+ put_var.f90 \
+ put_varn_real.f90 \
+ put_varn_int.f90 \
+ transpose.f90 \
+ vard_int.f90 \
+ fill_mode.f90
+
+PROGS = $(F90_SRCS:.f90=)
+OBJS = $(F90_SRCS:.f90=.o)
+
+UTIL_SRCS = utils.F90
+UTIL_OBJS = $(UTIL_SRCS:.F90=.o)
+
+GARBAGE = $(PROGS) *.nc
+
+PACKING_LIST = $(F90_SRCS) $(UTIL_SRCS) depend Makefile.in
+
+all: $(PROGS)
+
+install:
+
+uninstall:
+
+nonblocking_write: nonblocking_write.o $(UTIL_OBJS) $(LIBRARY)
+ $(LINK.F90) $< $(UTIL_OBJS) $(F90LDFLAGS) $(LIBS)
+
+get_info: get_info.o $(UTIL_OBJS) $(LIBRARY)
+ $(LINK.F90) $< $(UTIL_OBJS) $(F90LDFLAGS) $(LIBS)
+
+column_wise: column_wise.o $(UTIL_OBJS) $(LIBRARY)
+ $(LINK.F90) $< $(UTIL_OBJS) $(F90LDFLAGS) $(LIBS)
+
+block_cyclic: block_cyclic.o $(UTIL_OBJS) $(LIBRARY)
+ $(LINK.F90) $< $(UTIL_OBJS) $(F90LDFLAGS) $(LIBS)
+
+put_var: put_var.o $(UTIL_OBJS) $(LIBRARY)
+ $(LINK.F90) $< $(UTIL_OBJS) $(F90LDFLAGS) $(LIBS)
+
+hints: hints.o $(UTIL_OBJS) $(LIBRARY)
+ $(LINK.F90) $< $(UTIL_OBJS) $(F90LDFLAGS) $(LIBS)
+
+flexible_api: flexible_api.o $(UTIL_OBJS) $(LIBRARY)
+ $(LINK.F90) $< $(UTIL_OBJS) $(F90LDFLAGS) $(LIBS)
+
+put_varn_int: put_varn_int.o $(UTIL_OBJS) $(LIBRARY)
+ $(LINK.F90) $< $(UTIL_OBJS) $(F90LDFLAGS) $(LIBS)
+
+put_varn_real: put_varn_real.o $(UTIL_OBJS) $(LIBRARY)
+ $(LINK.F90) $< $(UTIL_OBJS) $(F90LDFLAGS) $(LIBS)
+
+transpose: transpose.o $(UTIL_OBJS) $(LIBRARY)
+ $(LINK.F90) $< $(UTIL_OBJS) $(F90LDFLAGS) $(LIBS)
+
+vard_int: vard_int.o $(UTIL_OBJS) $(LIBRARY)
+ $(LINK.F90) $< $(UTIL_OBJS) $(F90LDFLAGS) $(LIBS)
+
+fill_mode: fill_mode.o $(UTIL_OBJS) $(LIBRARY)
+ $(LINK.F90) $< $(UTIL_OBJS) $(F90LDFLAGS) $(LIBS)
+
+TEST_MPIRUN_4 = $(subst NP,4,$(TEST_MPIRUN))
+TEST_MPIRUN_8 = $(subst NP,8,$(TEST_MPIRUN))
+TEST_MPIRUN_3 = $(subst NP,3,$(TEST_MPIRUN))
+
+ptest4: $(PROGS)
+ @for i in $(PROGS); do ( \
+ $(TEST_MPIRUN_4) ./$$i -q $(TEST_OUTDIR)/testfile.nc ; \
+ if [ $$? = 0 ] ; then \
+ echo "PASS: F90 parallel run on 4 processes --------------- $$i"; \
+ else \
+ echo "FAILED: F90 parallel run on 4 processes ------------- $$i"; \
+ fi ; ) ; done
+
+ptest8: $(PROGS)
+ @for i in $(PROGS); do ( \
+ $(TEST_MPIRUN_8) ./$$i -q $(TEST_OUTDIR)/testfile.nc ; \
+ if [ $$? = 0 ] ; then \
+ echo "PASS: F90 parallel run on 8 processes --------------- $$i"; \
+ else \
+ echo "FAILED: F90 parallel run on 8 processes ------------- $$i"; \
+ fi ; ) ; done
+
+ptest3: $(PROGS)
+ @for i in $(PROGS); do ( \
+ $(TEST_MPIRUN_3) ./$$i -q $(TEST_OUTDIR)/testfile.nc ; \
+ if [ $$? = 0 ] ; then \
+ echo "PASS: F90 parallel run on 3 processes --------------- $$i"; \
+ else \
+ echo "FAILED: F90 parallel run on 3 processes ------------- $$i"; \
+ fi ; ) ; done
+
+ptest: ptest4
+ptests: ptest3 ptest4 ptest8
+ptest2 ptest6 ptest10:
+
+include $(srcdir)/depend
+include $(srcdir)/../../rules.make
+
+$(LIBRARY): ;
+
diff --git a/examples/F90/block_cyclic.f90 b/examples/F90/block_cyclic.f90
new file mode 100644
index 0000000..6ef74f5
--- /dev/null
+++ b/examples/F90/block_cyclic.f90
@@ -0,0 +1,278 @@
+!
+! Copyright (C) 2012, Northwestern University and Argonne National Laboratory
+! See COPYRIGHT notice in top-level directory.
+!
+! $Id: block_cyclic.f90 2245 2015-12-20 18:39:52Z wkliao $
+
+
+! This example, generalized from column_wise.f, makes a number of nonblocking
+! API calls, each writes a block of columns into a 2D integer array. In other
+! words, the I/O pattern is a blocked cyclic along X dimension.
+!
+! Each process writes NX rows in total. The block length is controlled by
+! block_len. In this example, block_len is set to 2. Blocks are layout in a
+! cyclic fashion in the file. This example can test if PnetCDF can coalesce
+! file offsets and lengths when constructing a merged filetype.
+!
+! The compile and run commands are given below, together with an ncmpidump of
+! the output file. In this example, block_len = 2.
+!
+! % mpif90 -O2 -o block_cyclic block_cyclic.f90 -lpnetcdf
+! % mpiexec -n 4 ./block_cyclic /pvfs2/wkliao/testfile.nc
+!
+! % ncmpidump /pvfs2/wkliao/testfile.nc
+! netcdf testfile {
+! // file format: CDF-5 (big variables)
+! dimensions:
+! Y = 10 ;
+! X = 16 ;
+! variables:
+! int var(Y, X) ;
+! data:
+!
+! var =
+! 10, 10, 11, 11, 12, 12, 13, 13, 10, 10, 11, 11, 12, 12, 13, 13,
+! 10, 10, 11, 11, 12, 12, 13, 13, 10, 10, 11, 11, 12, 12, 13, 13,
+! 10, 10, 11, 11, 12, 12, 13, 13, 10, 10, 11, 11, 12, 12, 13, 13,
+! 10, 10, 11, 11, 12, 12, 13, 13, 10, 10, 11, 11, 12, 12, 13, 13,
+! 10, 10, 11, 11, 12, 12, 13, 13, 10, 10, 11, 11, 12, 12, 13, 13,
+! 10, 10, 11, 11, 12, 12, 13, 13, 10, 10, 11, 11, 12, 12, 13, 13,
+! 10, 10, 11, 11, 12, 12, 13, 13, 10, 10, 11, 11, 12, 12, 13, 13,
+! 10, 10, 11, 11, 12, 12, 13, 13, 10, 10, 11, 11, 12, 12, 13, 13,
+! 10, 10, 11, 11, 12, 12, 13, 13, 10, 10, 11, 11, 12, 12, 13, 13,
+! 10, 10, 11, 11, 12, 12, 13, 13, 10, 10, 11, 11, 12, 12, 13, 13 ;
+! }
+!
+
+ subroutine check(err, message)
+ use mpi
+ use pnetcdf
+ implicit none
+ integer err
+ character(len=*) message
+
+ ! It is a good idea to check returned value for possible error
+ if (err .NE. NF90_NOERR) then
+ write(6,*) trim(message), trim(nf90mpi_strerror(err))
+ call MPI_Abort(MPI_COMM_WORLD, -1, err)
+ end if
+ end subroutine check
+
+ program main
+ use mpi
+ use pnetcdf
+ implicit none
+
+ integer NY, NX
+ PARAMETER(NX=10, NY=4)
+
+ character(LEN=128) filename, cmd
+ integer i, j, rank, nprocs, err, num_reqs, ierr, get_args, dummy
+ integer ncid, cmode, varid, dimid(2), stride, block_len
+ integer, dimension(:,:), allocatable :: buf
+ integer, dimension(:), allocatable :: reqs, sts
+ integer(kind=MPI_OFFSET_KIND) G_NY, myOff, block_start, &
+ global_nx, global_ny
+ integer(kind=MPI_OFFSET_KIND) start(2), count(2)
+ integer(kind=MPI_OFFSET_KIND) malloc_size, sum_size
+ logical verbose
+
+ call MPI_Init(err)
+ call MPI_Comm_rank(MPI_COMM_WORLD, rank, err)
+ call MPI_Comm_size(MPI_COMM_WORLD, nprocs, err)
+
+ ! take filename from command-line argument if there is any
+ if (rank .EQ. 0) then
+ verbose = .TRUE.
+ filename = "testfile.nc"
+ ierr = get_args(2, cmd, filename, verbose, dummy)
+ endif
+ call MPI_Bcast(ierr, 1, MPI_INTEGER, 0, MPI_COMM_WORLD, err)
+ if (ierr .EQ. 0) goto 999
+
+ call MPI_Bcast(verbose, 1, MPI_LOGICAL, 0, MPI_COMM_WORLD, err)
+ call MPI_Bcast(filename, 256, MPI_CHARACTER, 0, MPI_COMM_WORLD, err)
+
+ ! create file, truncate it if exists
+ cmode = IOR(NF90_CLOBBER, NF90_64BIT_DATA)
+ err = nf90mpi_create(MPI_COMM_WORLD, filename, cmode, &
+ MPI_INFO_NULL, ncid)
+ call check(err, 'In nf90mpi_create: ')
+
+ ! the global array is NX * (NY * nprocs) */
+ G_NY = NY * nprocs
+ myOff = NY * rank
+
+ ! define dimensions
+ global_nx = NX
+ err = nf90mpi_def_dim(ncid, 'Y', global_nx, dimid(2))
+ call check(err, 'In nf90mpi_def_dim Y')
+
+ err = nf90mpi_def_dim(ncid, 'X', G_NY, dimid(1))
+ call check(err, 'In nf90mpi_def_dim X')
+
+ err = nf90mpi_def_var(ncid, 'var', NF90_INT, dimid, varid)
+ call check(err, 'In nf90mpi_def_var var')
+
+ ! do not forget to exit define mode
+ err = nf90mpi_enddef(ncid)
+ call check(err, 'In nf90mpi_enddef: ')
+
+ ! First, fill the entire array with zeros, using a blocking I/O.
+ ! Every process writes a subarray of size NX * NY
+ allocate(buf(NX, NY))
+ buf = 0
+
+ allocate(reqs(NY))
+ allocate(sts(NY))
+
+ start(1) = myOff+1
+ start(2) = 1
+ count(1) = NY
+ count(2) = NX
+ err = nf90mpi_put_var_all(ncid, varid, buf, start, count)
+ call check(err, 'In nf90mpi_put_vara_int_all: ')
+
+ ! initialize the buffer with rank ID
+ buf = rank+10
+
+ ! each proc writes NY columns of the 2D array, block_len controls the
+ ! the number of contiguous columns at a time
+ block_start = 0
+ block_len = 2 ! can be 1, 2, 3, ..., NY
+ if (block_len > NY) block_len = NY
+
+ start(1) = rank * block_len + 1
+ start(2) = 1
+ count(1) = 1
+ count(2) = NX
+ num_reqs = 0
+
+ do i=1, NY
+ num_reqs = num_reqs + 1
+ err = nf90mpi_iput_var(ncid, varid, buf(:,i), &
+ reqs(num_reqs), start, &
+ count)
+ call check(err, 'In nf90mpi_iput_vara_int: ')
+
+ if (MOD(i, block_len) .EQ. 0) then
+ stride = NY-i
+ if (stride .GT. block_len) stride = block_len
+ block_start = block_start + block_len * nprocs
+ start(1) = block_start + stride * rank + 1;
+ else
+ start(1) = start(1) + 1
+ endif
+ enddo
+
+ err = nf90mpi_wait_all(ncid, num_reqs, reqs, sts)
+ call check(err, 'In nf90mpi_wait_all: ')
+
+ ! check status of all requests
+ do i=1, num_reqs
+ if (sts(i) .NE. NF90_NOERR) then
+ print*, "Error: nonblocking write fails on request", &
+ i, ' ', nf90mpi_strerror(sts(i))
+ endif
+ enddo
+
+ err = nf90mpi_close(ncid)
+ call check(err, 'In nf90mpi_close: ')
+
+ ! open an existing file created earlier for read
+ err = nf90mpi_open(MPI_COMM_WORLD, filename, NF90_NOWRITE, &
+ MPI_INFO_NULL, ncid)
+ call check(err, 'In nf90mpi_open: ')
+
+ ! the global array is NX * (NY * nprocs) */
+ err = nf90mpi_inq_dimid(ncid, "X", dimid(1))
+ call check(err, 'In nf90mpi_inq_dimid X: ')
+ err = nf90mpi_inquire_dimension(ncid, dimid(1), len=global_ny)
+ call check(err, 'In nf90mpi_inq_dimlen: ')
+ ! G_NY must == NY * nprocs
+ ! myNY must == global_ny / nprocs
+
+ err = nf90mpi_inq_dimid(ncid, "Y", dimid(2))
+ call check(err, 'In nf90mpi_inq_dimid Y: ')
+ err = nf90mpi_inquire_dimension(ncid, dimid(2), len=global_nx)
+ call check(err, 'In nf90mpi_inq_dimlen: ')
+ ! global_nx must == NX
+
+ err = nf90mpi_inq_varid(ncid, "var", varid)
+ call check(err, 'In nf90mpi_inq_varid: ')
+
+ ! initialize the buffer with -1, so a read error can be pinpointed
+ buf = -1
+
+ ! each proc reads NY columns of the 2D array, block_len controls the
+ ! the number of contiguous columns at a time */
+ block_start = 0
+ block_len = 2 ! can be 1, 2, 3, ..., NY
+ if (block_len .GT. NY) block_len = NY
+
+ start(1) = rank * block_len + 1
+ start(2) = 1
+ count(1) = 1
+ count(2) = global_nx
+ num_reqs = 0
+
+ do i=1, NY
+ num_reqs = num_reqs + 1
+ err = nf90mpi_iget_var(ncid, varid, buf(:,i), &
+ reqs(num_reqs), start, count)
+ call check(err, 'In nf90mpi_iget_vara_int: ')
+
+ if (MOD(i, block_len) .EQ. 0) then
+ stride = NY-i
+ if (stride .GT. block_len) stride = block_len
+ block_start = block_start + block_len * nprocs
+ start(1) = block_start + stride * rank + 1;
+ else
+ start(1) = start(1) + 1
+ endif
+ enddo
+
+ err = nf90mpi_wait_all(ncid, num_reqs, reqs, sts)
+ call check(err, 'In nf90mpi_wait_all: ')
+
+ ! check status of all requests
+ do i=1, num_reqs
+ if (sts(i) .NE. NF90_NOERR) then
+ print*, "Error: nonblocking write fails on request", &
+ i, ' ', nf90mpi_strerror(sts(i))
+ endif
+ enddo
+
+ err = nf90mpi_close(ncid)
+ call check(err, 'In nf90mpi_close: ')
+
+ ! check the read contents */
+ do j=1, NY
+ do i=1, NX
+ if (buf(i,j) .NE. rank+10) then
+ print*, 'Read contents mismatch at buf i=', i, &
+ ' j=',j,' =', buf(i,j),' (should be ', &
+ rank+10, ')\n'
+ endif
+ enddo
+ enddo
+
+ deallocate(buf)
+ deallocate(reqs)
+ deallocate(sts)
+
+ ! check if there is any PnetCDF internal malloc residue
+ 998 format(A,I13,A)
+ err = nf90mpi_inq_malloc_size(malloc_size)
+ if (err == NF90_NOERR) then
+ call MPI_Reduce(malloc_size, sum_size, 1, MPI_OFFSET, &
+ MPI_SUM, 0, MPI_COMM_WORLD, err)
+ if (rank .EQ. 0 .AND. sum_size .GT. 0_MPI_OFFSET_KIND) print 998, &
+ 'heap memory allocated by PnetCDF internally has ', &
+ sum_size/1048576, ' MiB yet to be freed'
+ endif
+
+ 999 call MPI_Finalize(err)
+ ! call EXIT(0) ! EXIT() is a GNU extension
+
+ end program main
diff --git a/examples/F90/column_wise.f90 b/examples/F90/column_wise.f90
new file mode 100644
index 0000000..2ce5a13
--- /dev/null
+++ b/examples/F90/column_wise.f90
@@ -0,0 +1,186 @@
+!
+! Copyright (C) 2012, Northwestern University and Argonne National Laboratory
+! See COPYRIGHT notice in top-level directory.
+!
+! $Id: column_wise.f90 2245 2015-12-20 18:39:52Z wkliao $
+
+! This example makes a number of nonblocking API calls, each writes a single
+! row of a 2D integer array. Each process writes NY rows and any two
+! consecutive rows are of nprocs-row distance apart from each other.
+! In this case, the fileview of each process interleaves with all other processes.
+! If simply concatenating fileviews of all the nonblocking calls will result
+! in a fileview that violates the MPI-IO requirement on the fileview of which
+! flattened file offsets must be monotonically non-decreasing. PnetCDF handles
+! this case by breaking down each nonblocking call into a list of offset-length
+! pairs, merging the pairs across multiple nonblocking calls, and sorting
+! them into an increasing order. The sorted pairs are used to construct a
+! fileview that meets the monotonically non-decreasing offset requirement,
+! and thus the nonblocking requests can be serviced by a single MPI-IO call.
+!
+! The compile and run commands are given below, together with an ncmpidump of
+! the output file. Note ncdump is in C order (row major).
+!
+! % mpif90 -O2 -o column_wise column_wise.f90 -lpnetcdf
+! % mpiexec -n 4 ./column_wise /pvfs2/wkliao/testfile.nc
+!
+! % ncmpidump /pvfs2/wkliao/testfile.nc
+! netcdf testfile {
+! // file format: CDF-5 (big variables)
+! dimensions:
+! Y = 10 ;
+! X = 16 ;
+! variables:
+! int var(Y, X) ;
+! data:
+!
+! var =
+! 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3,
+! 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3,
+! 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3,
+! 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3,
+! 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3,
+! 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3,
+! 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3,
+! 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3,
+! 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3,
+! 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3 ;
+! }
+!
+
+ subroutine check(err, message)
+ use mpi
+ use pnetcdf
+ implicit none
+ integer err
+ character(len=*) message
+
+ ! It is a good idea to check returned value for possible error
+ if (err .NE. NF90_NOERR) then
+ write(6,*) trim(message), trim(nf90mpi_strerror(err))
+ call MPI_Abort(MPI_COMM_WORLD, -1, err)
+ end if
+ end subroutine check
+
+ program main
+ use mpi
+ use pnetcdf
+ implicit none
+
+ integer NY, NX
+ PARAMETER(NX=10, NY=4)
+
+ character(LEN=128) filename, cmd
+ integer i, rank, nprocs, err, num_reqs, ierr, get_args, dummy
+ integer ncid, cmode, varid, dimid(2)
+ integer buf(NX, NY)
+ integer reqs(NY), sts(NY)
+ integer(kind=MPI_OFFSET_KIND) G_NY, myOff, block_start, &
+ block_len, global_nx
+ integer(kind=MPI_OFFSET_KIND) start(2), count(2)
+ integer(kind=MPI_OFFSET_KIND) malloc_size, sum_size
+ logical verbose
+
+ call MPI_Init(err)
+ call MPI_Comm_rank(MPI_COMM_WORLD, rank, err)
+ call MPI_Comm_size(MPI_COMM_WORLD, nprocs, err)
+
+ ! take filename from command-line argument if there is any
+ if (rank .EQ. 0) then
+ verbose = .TRUE.
+ filename = "testfile.nc"
+ ierr = get_args(2, cmd, filename, verbose, dummy)
+ endif
+ call MPI_Bcast(ierr, 1, MPI_INTEGER, 0, MPI_COMM_WORLD, err)
+ if (ierr .EQ. 0) goto 999
+
+ call MPI_Bcast(verbose, 1, MPI_LOGICAL, 0, MPI_COMM_WORLD, err)
+ call MPI_Bcast(filename, 256, MPI_CHARACTER, 0, MPI_COMM_WORLD, err)
+
+ ! create file, truncate it if exists
+ cmode = IOR(NF90_CLOBBER, NF90_64BIT_DATA)
+ err = nf90mpi_create(MPI_COMM_WORLD, filename, cmode, &
+ MPI_INFO_NULL, ncid)
+ call check(err, 'In nf90mpi_create: ')
+
+ ! the global array is NX * (NY * nprocs) */
+ G_NY = NY * nprocs
+ myOff = NY * rank
+
+ ! define dimensions
+ global_nx = NX
+ err = nf90mpi_def_dim(ncid, 'Y', global_nx, dimid(2))
+ call check(err, 'In nf90mpi_def_dim Y')
+
+ err = nf90mpi_def_dim(ncid, 'X', G_NY, dimid(1))
+ call check(err, 'In nf90mpi_def_dim X')
+
+ err = nf90mpi_def_var(ncid, 'var', NF90_INT, dimid, varid)
+ call check(err, 'In nf90mpi_def_var var')
+
+ ! do not forget to exit define mode
+ err = nf90mpi_enddef(ncid)
+ call check(err, 'In nf90mpi_enddef: ')
+
+ ! First, fill the entire array with zeros, using a blocking I/O.
+ ! Every process writes a subarray of size NX * NY
+ buf = 0
+ start(1) = myOff+1
+ start(2) = 1
+ count(1) = NY
+ count(2) = NX
+ err = nf90mpi_put_var_all(ncid, varid, buf, start, count)
+ call check(err, 'In nf90mpi_put_var_all: ')
+
+ ! initialize the buffer with rank ID
+ buf = rank
+
+ ! each proc writes NY columns of the 2D array, block_len controls the
+ ! the number of contiguous columns at a time
+ block_start = 0
+ block_len = 2 ! can be 1, 2, 3, ..., NY
+ if (block_len > NY) block_len = NY
+
+ start(1) = rank + 1
+ start(2) = 1
+ count(1) = 1
+ count(2) = NX
+ num_reqs = 0
+
+ do i=1, NY
+ num_reqs = num_reqs + 1
+ err = nf90mpi_iput_var(ncid, varid, buf(:,i), &
+ reqs(num_reqs), start, count)
+ call check(err, 'In nf90mpi_iput_var: ')
+
+ start(1) = start(1) + nprocs
+ enddo
+
+ err = nf90mpi_wait_all(ncid, num_reqs, reqs, sts)
+ call check(err, 'In nf90mpi_wait_all: ')
+
+ ! check status of all requests
+ do i=1, num_reqs
+ if (sts(i) .NE. NF90_NOERR) then
+ print*, "Error: nonblocking write fails on request", &
+ i, ' ', nf90mpi_strerror(sts(i))
+ endif
+ enddo
+
+ err = nf90mpi_close(ncid)
+ call check(err, 'In nf90mpi_close: ')
+
+ ! check if there is any PnetCDF internal malloc residue
+ 998 format(A,I13,A)
+ err = nf90mpi_inq_malloc_size(malloc_size)
+ if (err == NF90_NOERR) then
+ call MPI_Reduce(malloc_size, sum_size, 1, MPI_OFFSET, &
+ MPI_SUM, 0, MPI_COMM_WORLD, err)
+ if (rank .EQ. 0 .AND. sum_size .GT. 0_MPI_OFFSET_KIND) print 998, &
+ 'heap memory allocated by PnetCDF internally has ', &
+ sum_size/1048576, ' MiB yet to be freed'
+ endif
+
+ 999 call MPI_Finalize(err)
+ ! call EXIT(0) ! EXIT() is a GNU extension
+
+ end program main
diff --git a/examples/F90/depend b/examples/F90/depend
new file mode 100644
index 0000000..3954e90
--- /dev/null
+++ b/examples/F90/depend
@@ -0,0 +1,12 @@
+block_cyclic.o: block_cyclic.f90
+column_wise.o: column_wise.f90
+flexible_api.o: flexible_api.f90
+get_info.o: get_info.f90
+hints.o: hints.f90
+nonblocking_write.o: nonblocking_write.f90
+put_var.o: put_var.f90
+put_varn_real.o: put_varn_real.f90
+put_varn_int.o: put_varn_int.f90
+transpose.o: transpose.f90
+vard_int.o: vard_int.f90
+fill_mode.o: fill_mode.f90
diff --git a/examples/F90/fill_mode.f90 b/examples/F90/fill_mode.f90
new file mode 100644
index 0000000..f3e2a79
--- /dev/null
+++ b/examples/F90/fill_mode.f90
@@ -0,0 +1,218 @@
+!
+! Copyright (C) 2015, Northwestern University and Argonne National Laboratory
+! See COPYRIGHT notice in top-level directory.
+!
+! $Id: fill_mode.f90 2245 2015-12-20 18:39:52Z wkliao $
+
+! This example shows how to use
+! 1. nf90mpi_set_fill() to enable fill mode
+! 2. nf90mpi_def_var_fill() to define the variable's fill value
+! 3. nf90mpi_inq_var_fill() to inquire the variable's fill mode
+! information
+! 4. nf90mpi_put_vara_int_all() to write two 2D 4-byte integer array in
+! parallel.
+! It first defines a netCDF record variable of size global_nx *
+! NFMPI_UNLIMITED
+! where
+! global_nx == (nx * number of MPI processes) and
+! It then defines a netCDF variable of size global_nx * global_ny where
+! global_nx == (nx * number of MPI processes) and
+! global_ny == ny
+! The data partitioning pattern for both variables are a column-wise
+! partitioning across all processes. Each process writes a subarray of
+! size
+! nx * ny. Note the description above follows the Fortran array index
+! order.
+
+! Example commands for MPI run and outputs from running ncmpidump on the
+! NC file produced by this example program:
+!
+! % mpif90 -O2 -o fill_mode fill_mode.f90 -lpnetcdf
+! % mpiexec -n 4 ./fill_mode /pvfs2/wkliao/testfile.nc
+!
+! % ncmpidump /pvfs2/wkliao/testfile.nc
+! netcdf testfile {
+! // file format: CDF-5 (big variables)
+! dimensions:
+! REC_DIM = UNLIMITED ; // (2 currently)
+! X = 20 ;
+! Y = 3 ;
+! variables:
+! int rec_var(REC_DIM, X) ;
+! rec_var:_FillValue = -1 ;
+! int fix_var(Y, X) ;
+! fix_var:_FillValue = -2147483647 ;
+! data:
+!
+! rec_var =
+! 0, 0, 0, 0, _, 1, 1, 1, 1, _, 2, 2, 2, 2, _, 3, 3, 3, 3, _,
+! 0, 0, 0, 0, _, 1, 1, 1, 1, _, 2, 2, 2, 2, _, 3, 3, 3, 3, _ ;
+!
+! fix_var =
+! 0, 0, 0, 0, _, 1, 1, 1, 1, _, 2, 2, 2, 2, _, 3, 3, 3, 3, _,
+! 0, 0, 0, 0, _, 1, 1, 1, 1, _, 2, 2, 2, 2, _, 3, 3, 3, 3, _,
+! 0, 0, 0, 0, _, 1, 1, 1, 1, _, 2, 2, 2, 2, _, 3, 3, 3, 3, _ ;
+! }
+!
+ subroutine check(err, message)
+ use mpi
+ use pnetcdf
+ implicit none
+ integer err
+ character(len=*) message
+
+ ! It is a good idea to check returned value for possible error
+ if (err .NE. NF90_NOERR) then
+ write(6,*) trim(message), trim(nf90mpi_strerror(err))
+ call MPI_Abort(MPI_COMM_WORLD, -1, err)
+ end if
+ end subroutine check
+
+ program main
+ use mpi
+ use pnetcdf
+ implicit none
+
+ character(LEN=128) filename, cmd
+ integer err, nprocs, rank, ierr, get_args, dummy
+ integer cmode, ncid, rec_varid, fix_varid, dimid(2)
+ integer no_fill, fill_value, old_mode
+ integer(kind=MPI_OFFSET_KIND) nx, ny, global_nx, global_ny
+ integer(kind=MPI_OFFSET_KIND) starts(2), counts(2)
+ integer(kind=MPI_OFFSET_KIND) malloc_size, sum_size
+ PARAMETER(nx=5, ny=4)
+ integer buf(nx,ny)
+ logical verbose
+
+ call MPI_Init(err)
+ call MPI_Comm_rank(MPI_COMM_WORLD, rank, err)
+ call MPI_Comm_size(MPI_COMM_WORLD, nprocs, err)
+
+ ! take filename from command-line argument if there is any
+ if (rank .EQ. 0) then
+ verbose = .TRUE.
+ filename = "testfile.nc"
+ ierr = get_args(2, cmd, filename, verbose, dummy)
+ endif
+ call MPI_Bcast(ierr, 1, MPI_INTEGER, 0, MPI_COMM_WORLD, err)
+ if (ierr .EQ. 0) goto 999
+
+ call MPI_Bcast(verbose, 1, MPI_LOGICAL, 0, MPI_COMM_WORLD, err)
+ call MPI_Bcast(filename, 256, MPI_CHARACTER, 0, MPI_COMM_WORLD, err)
+
+ ! set parameters
+ global_nx = nx * nprocs
+ global_ny = ny
+
+ buf = rank;
+
+ ! create file, truncate it if exists
+ cmode = IOR(NF90_CLOBBER, NF90_64BIT_DATA)
+ err = nf90mpi_create(MPI_COMM_WORLD, filename, cmode, &
+ MPI_INFO_NULL, ncid)
+ call check(err, 'In nf90mpi_create: ')
+
+ ! define dimensions x and y
+ err = nf90mpi_def_dim(ncid, "REC_DIM", NFMPI_UNLIMITED, dimid(2))
+ call check(err, 'In nf90mpi_def_dim REC_DIM: ')
+ err = nf90mpi_def_dim(ncid, "X", global_nx, dimid(1))
+ call check(err, 'In nf90mpi_def_dim X: ')
+
+ ! define a 2D variable of integer type
+ err = nf90mpi_def_var(ncid, "rec_var", NF90_INT, dimid, rec_varid)
+ call check(err, 'In nf90mpi_def_var rec_var: ')
+
+ err = nf90mpi_def_dim(ncid, "Y", global_ny, dimid(2))
+ call check(err, 'In nf90mpi_def_dim Y: ')
+
+ ! define a 2D variable of integer type
+ err = nf90mpi_def_var(ncid, "fix_var", NF90_INT, dimid, fix_varid)
+ call check(err, 'In nf90mpi_def_var fix_var: ')
+
+ ! set the fill mode to NF90_FILL for entire file
+ err = nf90mpi_set_fill(ncid, NF90_FILL, old_mode)
+ call check(err, 'In nf90mpi_set_fill: ')
+ if (verbose) then
+ if (old_mode .EQ. NF90_FILL) then
+ print*,"The old fill mode is NF90_FILL"
+ else
+ print*,"The old fill mode is NF90_NOFILL"
+ endif
+ endif
+
+ ! set the fill mode back to NF90_NOFILL for entire file
+ err = nf90mpi_set_fill(ncid, NF90_NOFILL, old_mode)
+ call check(err, 'In nf90mpi_set_fill: ')
+
+ ! set the variable's fill mode to NF90_FILL with default fill
+ ! value
+ err = nf90mpi_def_var_fill(ncid, fix_varid, 0, NF90_FILL_INT)
+ call check(err, 'In nf90mpi_def_var_fill: ')
+
+ ! set a customized fill value -1
+ fill_value = -1
+ err = nf90mpi_put_att(ncid, rec_varid, "_FillValue", fill_value)
+ call check(err, 'In nf90mpi_put_att: ')
+
+ ! do not forget to exit define mode
+ err = nf90mpi_enddef(ncid)
+ call check(err, 'In nf90mpi_enddef: ')
+
+ ! now we are in data mode
+
+ ! Note that in Fortran, array indices start with 1
+ starts(1) = nx * rank + 1
+ starts(2) = 1
+ counts(1) = nx
+ counts(2) = ny
+
+ ! do not write the variable in full
+ counts(1) = counts(1) - 1
+ err = nf90mpi_put_var_all(ncid, fix_varid, buf, starts, counts)
+ call check(err, 'In nf90mpi_put_var_all: ')
+
+ err = nf90mpi_inq_var_fill(ncid, fix_varid, no_fill, fill_value)
+ if (no_fill .NE. 0) &
+ print*,"Error: expecting no_fill to be 0"
+ if (fill_value .NE. NF90_FILL_INT) &
+ print*,"Error: expecting no_fill to be ",NF90_FILL_INT, &
+ " but got ", fill_value
+
+ ! fill the 1st record of the record variable
+ starts(2) = 1
+ err = nf90mpi_fill_var_rec(ncid, rec_varid, starts(2))
+ call check(err, 'In nf90mpi_fill_var_rec: ')
+
+ ! write to the 1st record
+ counts(2) = 1;
+ err = nf90mpi_put_var_all(ncid, rec_varid, buf, starts, counts)
+ call check(err, 'In nf90mpi_put_var_all: ')
+
+ ! fill the 2nd record of the record variable
+ starts(2) = 2
+ err = nf90mpi_fill_var_rec(ncid, rec_varid, starts(2))
+ call check(err, 'In nf90mpi_fill_var_rec: ')
+
+ ! write to the 2nd record
+ err = nf90mpi_put_var_all(ncid, rec_varid, buf, starts, counts)
+ call check(err, 'In nf90mpi_put_var_all: ')
+
+ ! close the file
+ err = nf90mpi_close(ncid)
+ call check(err, 'In nf90mpi_close: ')
+
+ ! check if there is any PnetCDF internal malloc residue
+ 998 format(A,I13,A)
+ err = nf90mpi_inq_malloc_size(malloc_size)
+ if (err == NF90_NOERR) then
+ call MPI_Reduce(malloc_size, sum_size, 1, MPI_OFFSET, &
+ MPI_SUM, 0, MPI_COMM_WORLD, err)
+ if (rank .EQ. 0 .AND. sum_size .GT. 0_MPI_OFFSET_KIND) print 998, &
+ 'heap memory allocated by PnetCDF internally has ', &
+ sum_size/1048576, ' MiB yet to be freed'
+ endif
+
+ 999 call MPI_Finalize(err)
+ ! call EXIT(0) ! EXIT() is a GNU extension
+ end program main
+
diff --git a/examples/F90/flexible_api.f90 b/examples/F90/flexible_api.f90
new file mode 100644
index 0000000..aa779c3
--- /dev/null
+++ b/examples/F90/flexible_api.f90
@@ -0,0 +1,182 @@
+!
+! Copyright (C) 2013, Northwestern University and Argonne National Laboratory
+! See COPYRIGHT notice in top-level directory.
+!
+! $Id: flexible_api.f90 2245 2015-12-20 18:39:52Z wkliao $
+
+!
+! This example shows how to use PnetCDF flexible API, nf90mpi_put_var_all()
+! to write a 2D 4-byte integer array in parallel. It first defines a netCDF
+! variable of size global_nx * global_ny where
+! global_nx == 5 and
+! global_ny == (4 * number of MPI processes).
+! The data partitioning pattern is a column-wise partitioning across all
+! processes. Each process writes a subarray of size nx * ny.
+! The local buffer has a ghost cell of length 3 surrounding the 2D array
+! integer buf(nx+2*ghost_len, ny+2*ghost_len)
+! Note the description above follows the Fortran array index order.
+!
+! Example commands for MPI run and outputs from running ncmpidump on the
+! NC file produced by this example program:
+!
+! % mpif90 -O2 -o flexible_api flexible_api.f90 -lpnetcdf
+! % mpiexec -n 4 ./flexible_api /pvfs2/wkliao/testfile.nc
+!
+! % ncmpidump /pvfs2/wkliao/testfile.nc
+! netcdf testfile {
+! // file format: CDF-5 (big variables)
+! dimensions:
+! x = 5 ;
+! y = 16 ;
+! variables:
+! int var(y, x) ;
+! data:
+!
+! var =
+! 0, 0, 0, 0, 0,
+! 0, 0, 0, 0, 0,
+! 0, 0, 0, 0, 0,
+! 0, 0, 0, 0, 0,
+! 1, 1, 1, 1, 1,
+! 1, 1, 1, 1, 1,
+! 1, 1, 1, 1, 1,
+! 1, 1, 1, 1, 1,
+! 2, 2, 2, 2, 2,
+! 2, 2, 2, 2, 2,
+! 2, 2, 2, 2, 2,
+! 2, 2, 2, 2, 2,
+! 3, 3, 3, 3, 3,
+! 3, 3, 3, 3, 3,
+! 3, 3, 3, 3, 3,
+! 3, 3, 3, 3, 3 ;
+! }
+!
+ subroutine check(err, message)
+ use mpi
+ use pnetcdf
+ implicit none
+ integer err
+ character(len=*) message
+
+ ! It is a good idea to check returned value for possible error
+ if (err .NE. NF90_NOERR) then
+ write(6,*) trim(message), trim(nf90mpi_strerror(err))
+ call MPI_Abort(MPI_COMM_WORLD, -1, err)
+ end if
+ end subroutine check
+
+ program main
+ use mpi
+ use pnetcdf
+ implicit none
+
+ character(LEN=128) filename, cmd
+ integer err, nprocs, rank, i, j, ghost_len, ierr, get_args, dummy
+ integer cmode, ncid, varid, dimid(2)
+ integer(kind=MPI_OFFSET_KIND) nx, ny, global_nx, global_ny
+ integer(kind=MPI_OFFSET_KIND) starts(2), counts(2), nTypes
+ PARAMETER(nx=5, ny=4, ghost_len=3)
+ integer buf(nx+2*ghost_len, ny+2*ghost_len)
+ integer subarray
+ integer array_of_sizes(2), array_of_subsizes(2)
+ integer array_of_starts(2)
+ integer(kind=MPI_OFFSET_KIND) malloc_size, sum_size
+ logical verbose
+
+ call MPI_Init(err)
+ call MPI_Comm_rank(MPI_COMM_WORLD, rank, err)
+ call MPI_Comm_size(MPI_COMM_WORLD, nprocs, err)
+
+ ! take filename from command-line argument if there is any
+ if (rank .EQ. 0) then
+ verbose = .TRUE.
+ filename = "testfile.nc"
+ ierr = get_args(2, cmd, filename, verbose, dummy)
+ endif
+ call MPI_Bcast(ierr, 1, MPI_INTEGER, 0, MPI_COMM_WORLD, err)
+ if (ierr .EQ. 0) goto 999
+
+ call MPI_Bcast(verbose, 1, MPI_LOGICAL, 0, MPI_COMM_WORLD, err)
+ call MPI_Bcast(filename, 256, MPI_CHARACTER, 0, MPI_COMM_WORLD, err)
+
+ ! set parameters
+ global_nx = nx
+ global_ny = ny * nprocs
+
+ ! first initialize the entire buffer to -1
+ buf = -1;
+ ! assign values for non-ghost cells
+ do j=ghost_len+1, ny+ghost_len
+ do i=ghost_len+1, nx+ghost_len
+ buf(i, j) = rank
+ enddo
+ enddo
+
+ ! define an MPI datatype using MPI_Type_create_subarray()
+ array_of_sizes(1) = nx + 2*ghost_len
+ array_of_sizes(2) = ny + 2*ghost_len
+ array_of_subsizes(1) = nx
+ array_of_subsizes(2) = ny
+ array_of_starts(1) = ghost_len ! MPI start index starts with 0
+ array_of_starts(2) = ghost_len
+ call MPI_Type_create_subarray(2, array_of_sizes, &
+ array_of_subsizes, array_of_starts, MPI_ORDER_FORTRAN, &
+ MPI_INTEGER, subarray, err)
+ call MPI_Type_commit(subarray, err)
+
+ ! create file, truncate it if exists
+ cmode = IOR(NF90_CLOBBER, NF90_64BIT_DATA)
+ err = nf90mpi_create(MPI_COMM_WORLD, filename, cmode, &
+ MPI_INFO_NULL, ncid)
+ call check(err, 'In nf90mpi_create: ')
+
+ ! define dimensions x and y
+ err = nf90mpi_def_dim(ncid, "y", global_ny, dimid(2))
+ call check(err, 'In nf90mpi_def_dim y: ')
+ err = nf90mpi_def_dim(ncid, "x", global_nx, dimid(1))
+ call check(err, 'In nf90mpi_def_dim x: ')
+
+ ! define a 2D variable of integer type
+ err = nf90mpi_def_var(ncid, "var", NF90_INT, dimid, varid)
+ call check(err, 'In nf90mpi_def_var: ')
+
+ ! do not forget to exit define mode
+ err = nf90mpi_enddef(ncid)
+ call check(err, 'In nf90mpi_enddef: ')
+
+ ! now we are in data mode
+
+ ! Note that in Fortran, array indices start with 1
+ starts(1) = 1
+ starts(2) = ny * rank + 1
+ counts(1) = nx
+ counts(2) = ny
+ nTypes = 1
+
+ ! must explicitly use the argument keywords for the buffer type and
+ ! number of buffer types, if any previous argument is skipped
+ err = nf90mpi_put_var_all(ncid, varid, buf, starts, counts, &
+ BUFCOUNT=nTypes, BUFTYPE=subarray)
+ call check(err, 'In nf90mpi_put_var_all: ')
+
+ call MPI_Type_free(subarray, err)
+
+ ! close the file
+ err = nf90mpi_close(ncid)
+ call check(err, 'In nf90mpi_close: ')
+
+ ! check if there is any PnetCDF internal malloc residue
+ 998 format(A,I13,A)
+ err = nf90mpi_inq_malloc_size(malloc_size)
+ if (err == NF90_NOERR) then
+ call MPI_Reduce(malloc_size, sum_size, 1, MPI_OFFSET, &
+ MPI_SUM, 0, MPI_COMM_WORLD, err)
+ if (rank .EQ. 0 .AND. sum_size .GT. 0_MPI_OFFSET_KIND) print 998, &
+ 'heap memory allocated by PnetCDF internally has ', &
+ sum_size/1048576, ' MiB yet to be freed'
+ endif
+
+ 999 call MPI_Finalize(err)
+ ! call EXIT(0) ! EXIT() is a GNU extension
+ end program main
+
diff --git a/examples/F90/get_info.f90 b/examples/F90/get_info.f90
new file mode 100644
index 0000000..86c8e9c
--- /dev/null
+++ b/examples/F90/get_info.f90
@@ -0,0 +1,139 @@
+!*********************************************************************
+!*
+!* Copyright (C) 2012, Northwestern University and Argonne National
+!* Laboratory
+!* See COPYRIGHT notice in top-level directory.
+!*
+!*********************************************************************/
+! $Id: get_info.f90 2139 2015-10-08 01:59:10Z wkliao $
+
+! To compile:
+! mpif90 -O2 get_info.f90 -o get_info -lpnetcdf
+! To run:
+! mpiexec -n 4 ./get_info /pvfs2/wkliao/filename
+!
+! prints all MPI-IO hints used
+!
+! Example standard output:
+!
+! MPI File Info: nkeys = 18
+! MPI File Info: [ 0] key = cb_buffer_size, value =16777216
+! MPI File Info: [ 1] key = romio_cb_read, value =automatic
+! MPI File Info: [ 2] key = romio_cb_write, value =automatic
+! MPI File Info: [ 3] key = cb_nodes, value =1
+! MPI File Info: [ 4] key = romio_no_indep_rw, value =false
+! MPI File Info: [ 5] key = romio_cb_pfr, value =disable
+! MPI File Info: [ 6] key = romio_cb_fr_types, value =aar
+! MPI File Info: [ 7] key = romio_cb_fr_alignment, value =1
+! MPI File Info: [ 8] key = romio_cb_ds_threshold, value =0
+! MPI File Info: [ 9] key = romio_cb_alltoall, value =automatic
+! MPI File Info: [10] key = ind_rd_buffer_size, value =4194304
+! MPI File Info: [11] key = ind_wr_buffer_size, value =524288
+! MPI File Info: [12] key = romio_ds_read, value =automatic
+! MPI File Info: [13] key = romio_ds_write, value =automatic
+! MPI File Info: [14] key = cb_config_list, value =*:1
+! MPI File Info: [15] key = nc_header_align_size, value =0
+! MPI File Info: [16] key = nc_var_align_size, value =0
+! MPI File Info: [17] key = nc_header_read_chunk_size, value =0
+
+
+ program main
+ use mpi
+ use pnetcdf
+ implicit none
+
+ character(len = 256) :: filename, cmd
+ integer ncid, rank, info, omode, err, ierr, get_args, dummy
+ integer(kind=MPI_OFFSET_KIND) malloc_size, sum_size
+ logical verbose
+
+ call MPI_Init(err)
+ call MPI_Comm_rank(MPI_COMM_WORLD, rank, err)
+
+ if (rank .EQ. 0) then
+ verbose = .TRUE.
+ filename = "testfile.nc"
+ ierr = get_args(2, cmd, filename, verbose, dummy)
+ endif
+ call MPI_Bcast(ierr, 1, MPI_INTEGER, 0, MPI_COMM_WORLD, err)
+ if (ierr .EQ. 0) goto 999
+
+ call MPI_Bcast(verbose, 1, MPI_LOGICAL, 0, MPI_COMM_WORLD, err)
+ call MPI_Bcast(filename, 256, MPI_CHARACTER, 0, MPI_COMM_WORLD, err)
+
+ omode = NF90_NOWRITE + NF90_64BIT_OFFSET
+ err = nf90mpi_open(MPI_COMM_WORLD, trim(filename), omode, &
+ MPI_INFO_NULL, ncid)
+ if (err .ne. NF90_NOERR) call handle_err('nf90mpi_open',err)
+
+
+ err = nf90mpi_inq_file_info(ncid, info)
+ if (err .ne. NF90_NOERR) then
+ call handle_err('nf90mpi_inq_file_info', err)
+ endif
+
+ err = nf90mpi_close(ncid)
+ if (err .ne. NF90_NOERR) call handle_err('nf90mpi_close',err)
+
+ if (rank .EQ. 0 .AND. verbose) call print_info(info)
+ call MPI_Info_free(info, err)
+
+ ! check if there is any PnetCDF internal malloc residue
+ 998 format(A,I13,A)
+ err = nf90mpi_inq_malloc_size(malloc_size)
+ if (err == NF90_NOERR) then
+ call MPI_Reduce(malloc_size, sum_size, 1, MPI_OFFSET, &
+ MPI_SUM, 0, MPI_COMM_WORLD, err)
+ if (rank .EQ. 0 .AND. sum_size .GT. 0_MPI_OFFSET_KIND) print 998, &
+ 'heap memory allocated by PnetCDF internally has ', &
+ sum_size/1048576, ' MiB yet to be freed'
+ endif
+
+ 999 call MPI_Finalize(err)
+ ! call EXIT(0) ! EXIT() is a GNU extension
+
+ end program main
+
+ subroutine print_info(info_used)
+ use mpi
+ use pnetcdf
+ implicit none
+
+ integer, intent(in) :: info_used
+
+ ! local variables
+ character*(MPI_MAX_INFO_VAL) key, value
+ integer nkeys, i, err
+ logical flag
+
+ call MPI_Info_get_nkeys(info_used, nkeys, err)
+ print *, 'MPI File Info: nkeys =', nkeys
+ do i=0, nkeys-1
+ call MPI_Info_get_nthkey(info_used, i, key, err)
+ call MPI_Info_get(info_used, key, MPI_MAX_INFO_VAL, &
+ value, flag, err)
+ 123 format('MPI File Info: [',I2,'] key = ',A25, &
+ ', value =',A)
+ print 123, i, trim(key), trim(value)
+ enddo
+ print *, ''
+
+ return
+ end subroutine print_info
+
+ subroutine handle_err(err_msg, errcode)
+ use mpi
+ use pnetcdf
+ implicit none
+
+ character*(*), intent(in) :: err_msg
+ integer, intent(in) :: errcode
+
+ ! local variables
+ integer err
+
+ print *, 'Error: ',trim(err_msg),' ',nf90mpi_strerror(errcode)
+ call MPI_Abort(MPI_COMM_WORLD, -1, err)
+ return
+ end subroutine handle_err
+
diff --git a/examples/F90/hints.f90 b/examples/F90/hints.f90
new file mode 100644
index 0000000..05198f4
--- /dev/null
+++ b/examples/F90/hints.f90
@@ -0,0 +1,248 @@
+!
+!
+! Copyright (C) 2012, Northwestern University and Argonne National
+! Laboratory
+! See COPYRIGHT notice in top-level directory.
+!
+! $Id: hints.f90 2139 2015-10-08 01:59:10Z wkliao $
+
+!
+! This example sets two PnetCDF hints:
+! nc_header_align_size and nc_var_align_size
+! and prints the hint values as well as the header size, header extent, and
+! two variables' starting file offsets.
+!
+! The compile and run commands are given below.
+!
+! % mpif90 -O2 -o hints hints.f90 -lpnetcdf
+!
+! % mpiexec -n 4 ./hints /pvfs2/wkliao/testfile.nc
+!
+! nc_header_align_size set to = 1024
+! nc_var_align_size set to = 512
+! nc_header_read_chunk_size set to = 256
+! header size = 252
+! header extent = 1024
+! var_zy start file offset = 1024
+! var_yx start file offset = 3072
+!
+
+
+ subroutine check(err, message)
+ use mpi
+ use pnetcdf
+ implicit none
+ integer err
+ character(len=*) message
+
+ ! It is a good idea to check returned value for possible error
+ if (err .NE. NF90_NOERR) then
+ write(6,*) trim(message), trim(nf90mpi_strerror(err))
+ call MPI_Abort(MPI_COMM_WORLD, -1, err)
+ end if
+ end subroutine check
+
+ subroutine print_hints(ncid, varid0, varid1)
+ use mpi
+ use pnetcdf
+ implicit none
+
+ integer ncid, varid0, varid1
+
+ ! local variables
+ character*(MPI_MAX_INFO_VAL) value
+ integer err, len, info_used
+ logical flag
+ integer(kind=MPI_OFFSET_KIND) header_size, header_extent
+ integer(kind=MPI_OFFSET_KIND) var_zy_start, var_yx_start
+ integer(kind=MPI_OFFSET_KIND) h_align, v_align, h_chunk
+
+ h_align=-1
+ v_align=-1
+ h_chunk=-1
+
+ err = nf90mpi_inq_header_size (ncid, header_size)
+ call check(err, 'In nf90mpi_inq_header_size: ')
+ err = nf90mpi_inq_header_extent(ncid, header_extent)
+ call check(err, 'In nf90mpi_inq_header_extent: ')
+ err = nf90mpi_inq_varoffset(ncid, varid0, var_zy_start)
+ call check(err, 'In nf90mpi_inq_varoffset varid0: ')
+ err = nf90mpi_inq_varoffset(ncid, varid1, var_yx_start)
+ call check(err, 'In nf90mpi_inq_varoffset varid1: ')
+
+ err = nf90mpi_inq_file_info(ncid, info_used)
+ call check(err, 'In nf90mpi_inq_file_info : ')
+
+ call MPI_Info_get_valuelen(info_used, "nc_header_align_size", &
+ len, flag, err)
+ if (flag) then
+ call MPI_Info_get(info_used, "nc_header_align_size", &
+ len+1, value, flag, err)
+ read(value, '(i16)') h_align
+ endif
+ call MPI_Info_get_valuelen(info_used, "nc_var_align_size", &
+ len, flag, err)
+ if (flag) then
+ call MPI_Info_get(info_used, "nc_var_align_size", len+1, &
+ value, flag, err)
+ read(value, '(i16)') v_align
+ endif
+ call MPI_Info_get_valuelen(info_used, &
+ "nc_header_read_chunk_size", &
+ len, flag, err)
+ if (flag) then
+ call MPI_Info_get(info_used, "nc_header_read_chunk_size", &
+ len+1, value, flag, err)
+ read(value, '(i16)') h_chunk
+ endif
+ call MPI_Info_free(info_used, err)
+
+ if (h_align .EQ. -1) then
+ print*,"nc_header_align_size is NOT set"
+ else
+ print*,"nc_header_align_size set to = ", h_align
+ endif
+ if (v_align .EQ. -1) then
+ print*,"nc_var_align_size is NOT set"
+ else
+ print*,"nc_var_align_size set to = ", v_align
+ endif
+ if (h_chunk .EQ. -1) then
+ print*,"nc_header_read_chunk_size is NOT set"
+ else
+ print*,"nc_header_read_chunk_size set to = ", h_chunk
+ endif
+
+ print*,"header size = ", header_size
+ print*,"header extent = ", header_extent
+ print*,"var_zy start file offset = ", var_zy_start
+ print*,"var_yx start file offset = ", var_yx_start
+ end subroutine print_hints
+
+ subroutine put_vara(ncid, varid, ny, nx, start, count)
+ use mpi
+ use pnetcdf
+ implicit none
+
+ integer ncid, varid, ny, nx
+ integer(KIND=MPI_OFFSET_KIND) start(2), count(2)
+
+ integer i, j, rank, err
+ integer buf(nx, ny)
+
+ call MPI_Comm_rank(MPI_COMM_WORLD, rank, err)
+
+ do j=1, ny
+ do i=1, nx
+ buf(i,j) = rank ! j*nx + i
+ enddo
+ enddo
+
+ err = nf90mpi_put_var_all(ncid, varid, buf, start, count)
+ call check(err, 'In nf90mpi_put_var_all : ')
+
+ end subroutine put_vara
+
+ program main
+ use mpi
+ use pnetcdf
+ implicit none
+
+ character(len = 256) :: filename, cmd
+ integer NZ, NY, NX
+ integer ncid, rank, nprocs, info, cmode, err, ierr, get_args, dummy
+ integer varid0, varid1, dimid(3), dimid2(2)
+ integer(KIND=MPI_OFFSET_KIND) start(2), count(2), llen
+ integer(kind=MPI_OFFSET_KIND) malloc_size, sum_size
+ logical verbose
+
+ call MPI_Init(err)
+ call MPI_Comm_rank(MPI_COMM_WORLD, rank, err)
+ call MPI_Comm_size(MPI_COMM_WORLD, nprocs, err)
+
+ NZ = 5
+ NY = 5
+ NX = 5
+
+ if (rank .EQ. 0) then
+ verbose = .TRUE.
+ filename = "testfile.nc"
+ ierr = get_args(2, cmd, filename, verbose, dummy)
+ endif
+ call MPI_Bcast(ierr, 1, MPI_INTEGER, 0, MPI_COMM_WORLD, err)
+ if (ierr .EQ. 0) goto 999
+
+ call MPI_Bcast(verbose, 1, MPI_LOGICAL, 0, MPI_COMM_WORLD, err)
+ call MPI_Bcast(filename, 256, MPI_CHARACTER, 0, MPI_COMM_WORLD, err)
+
+ call MPI_Info_create(info, err)
+ call MPI_Info_set(info, "nc_header_align_size", "1024", err)
+ call MPI_Info_set(info, "nc_var_align_size", "512", err)
+ call MPI_Info_set(info, "nc_header_read_chunk_size", "256", err)
+ ! note that set the above values to 1 to disable the alignment
+
+ ! create a new file for writing
+ cmode = NF90_CLOBBER + NF90_64BIT_DATA
+ err = nf90mpi_create(MPI_COMM_WORLD, filename, cmode, info, ncid)
+ call check(err, 'In nf90mpi_create : ')
+ call MPI_Info_free(info, err)
+
+ ! define 3 dimensions
+ llen = NZ*nprocs
+ err = nf90mpi_def_dim(ncid, "Z", llen, dimid(1))
+ call check(err, 'In nf90mpi_def_dim Z : ')
+ llen = NY*nprocs
+ err = nf90mpi_def_dim(ncid, "Y", llen, dimid(2))
+ call check(err, 'In nf90mpi_def_dim Y : ')
+ llen = NX*nprocs
+ err = nf90mpi_def_dim(ncid, "X", llen, dimid(3))
+ call check(err, 'In nf90mpi_def_dim X : ')
+
+ ! define a variable of size (NZ * nprocs) * (NY * nprocs)
+ dimid2(1) = dimid(1)
+ dimid2(2) = dimid(2)
+ err = nf90mpi_def_var(ncid, "var_zy", NF90_INT, dimid2, varid0)
+ call check(err, 'In nf90mpi_def_var var_zy : ')
+ ! define a variable of size (NY * nprocs) * (NX * nprocs)
+ dimid2(1) = dimid(2)
+ dimid2(2) = dimid(3)
+ err = nf90mpi_def_var(ncid, "var_yx", NF90_FLOAT, dimid2, varid1)
+ call check(err, 'In nf90mpi_def_var var_yx : ')
+
+ err = nf90mpi_enddef(ncid)
+ call check(err, 'In nf90mpi_enddef : ')
+
+ ! var_zy is partitioned along Z dimension
+ start(1) = NZ * rank + 1
+ start(2) = 1
+ count(1) = NZ
+ count(2) = NY * nprocs
+ call put_vara(ncid, varid0, NZ, NY * nprocs, start, count)
+
+ ! var_yx is partitioned along X dimension
+ start(1) = 1
+ start(2) = NX * rank + 1
+ count(1) = NY * nprocs
+ count(2) = NX
+ call put_vara(ncid, varid1, NY * nprocs, NX, start, count)
+
+ if (rank .EQ. 0 .AND. verbose) call print_hints(ncid, varid0, varid1)
+
+ err = nf90mpi_close(ncid)
+
+ ! check if there is any PnetCDF internal malloc residue
+ 998 format(A,I13,A)
+ err = nf90mpi_inq_malloc_size(malloc_size)
+ if (err == NF90_NOERR) then
+ call MPI_Reduce(malloc_size, sum_size, 1, MPI_OFFSET, &
+ MPI_SUM, 0, MPI_COMM_WORLD, err)
+ if (rank .EQ. 0 .AND. sum_size .GT. 0_MPI_OFFSET_KIND) print 998, &
+ 'heap memory allocated by PnetCDF internally has ', &
+ sum_size/1048576, ' MiB yet to be freed'
+ endif
+
+ 999 call MPI_Finalize(err)
+ ! call EXIT(0) ! EXIT() is a GNU extension
+
+ end program
+
diff --git a/examples/F90/nonblocking_write.f90 b/examples/F90/nonblocking_write.f90
new file mode 100644
index 0000000..bd28db3
--- /dev/null
+++ b/examples/F90/nonblocking_write.f90
@@ -0,0 +1,197 @@
+!
+! Copyright (C) 2012, Northwestern University and Argonne National Laboratory
+! See COPYRIGHT notice in top-level directory.
+!
+! $Id: nonblocking_write.f90 2245 2015-12-20 18:39:52Z wkliao $
+
+! This example is the Fortran 90 version of nonblocking_write.c
+! It creates a netcdf file in CD-5 format and writes a number of
+! 3D integer non-record variables.
+! Usage: (for example)
+! To compile:
+! mpif90 -O2 nonblocking_write.f90 -o nonblocking_write -lpnetcdf
+! To run:
+! mpiexec -n num_processes ./nonblocking_write [filename] [len]
+! where len decides the size of each local array, which is
+! len x len x len. Each non-record variable is of size
+! len*len*len * nprocs * sizeof(int)
+! All variables are partitioned among all processes in a 3D
+! block-block-block fashion.
+!
+
+ subroutine check(err, message)
+ use mpi
+ use pnetcdf
+ implicit none
+ integer err
+ character(len=*) message
+
+ ! It is a good idea to check returned value for possible error
+ if (err .NE. NF90_NOERR) then
+ write(6,*) trim(message), trim(nf90mpi_strerror(err))
+ call MPI_Abort(MPI_COMM_WORLD, -1, err)
+ end if
+ end subroutine check
+
+ program main
+ use mpi
+ use pnetcdf
+ implicit none
+
+ integer NDIMS, NUM_VARS
+ PARAMETER(NDIMS=3, NUM_VARS=10)
+
+ character(LEN=256) filename, cmd, str
+ integer i, cmode, err, ierr, get_args
+ integer rank, nprocs, len, bufsize, ncid
+ integer psizes(NDIMS), dimids(NDIMS), varids(NUM_VARS)
+ integer req(NUM_VARS), st(NUM_VARS)
+ integer(kind=MPI_OFFSET_KIND) gsizes(NDIMS)
+ integer(kind=MPI_OFFSET_KIND) starts(NDIMS), counts(NDIMS)
+ integer(kind=MPI_OFFSET_KIND) bbufsize
+ integer(kind=MPI_OFFSET_KIND) malloc_size, sum_size
+ logical verbose
+
+ ! define an array of pointers
+ type intp
+ integer, dimension(:), pointer :: p
+ end type intp
+ type(intp) buf(NUM_VARS)
+
+ call MPI_Init(err)
+ call MPI_Comm_rank(MPI_COMM_WORLD, rank, err)
+ call MPI_Comm_size(MPI_COMM_WORLD, nprocs, err)
+
+ ! take filename from command-line argument if there is any
+ if (rank .EQ. 0) then
+ verbose = .TRUE.
+ filename = "testfile.nc"
+ len = 10
+ ierr = get_args(3, cmd, filename, verbose, len)
+ endif
+ call MPI_Bcast(ierr, 1, MPI_INTEGER, 0, MPI_COMM_WORLD, err)
+ if (ierr .EQ. 0) goto 999
+
+ call MPI_Bcast(verbose, 1, MPI_LOGICAL, 0, MPI_COMM_WORLD, err)
+ call MPI_Bcast(filename, 256, MPI_CHARACTER, 0, MPI_COMM_WORLD, err)
+ call MPI_Bcast(len, 1, MPI_INTEGER, 0, MPI_COMM_WORLD, err)
+
+ do i=1,NDIMS
+ psizes(i) = 0
+ enddo
+
+ ! create a block-block-block data partitioning
+ call MPI_Dims_create(nprocs, NDIMS, psizes, err);
+ starts(1) = mod(rank, psizes(1))
+ starts(2) = mod((rank / psizes(2)), psizes(2))
+ starts(3) = mod((rank / (psizes(1) * psizes(2))), psizes(3))
+
+ bufsize = 1
+ do i=1,NDIMS
+ gsizes(i) = len * psizes(i)
+ starts(i) = starts(i) * len + 1;
+ counts(i) = len;
+ bufsize = bufsize * len;
+ enddo
+
+ ! allocate buffer and initialize with rank IDs
+ do i=1, NUM_VARS
+ allocate(buf(i)%p(bufsize))
+ buf(i)%p(:) = rank
+ enddo
+
+ ! create file, truncate it if exists
+ cmode = IOR(NF90_CLOBBER, NF90_64BIT_DATA)
+ err = nf90mpi_create(MPI_COMM_WORLD, filename, cmode, &
+ MPI_INFO_NULL, ncid)
+ call check(err, 'In nf90mpi_create: ')
+
+ ! define dimensions
+ do i=1, NDIMS
+ write(str,'(I2)') i
+ err = nf90mpi_def_dim(ncid, "x"//trim(ADJUSTL(str)), &
+ gsizes(i), dimids(i))
+ call check(err, 'In nf90mpi_def_dim x'//trim(str))
+ enddo
+
+ !define variables
+ do i=1, NUM_VARS
+ write(str,'(I2)') i
+ err = nf90mpi_def_var(ncid, "var"//trim(ADJUSTL(str)), &
+ NF90_INT, dimids, varids(i))
+ call check(err, 'In nf90mpi_def_var var'//trim(str))
+ enddo
+
+ ! do not forget to exit define mode
+ err = nf90mpi_enddef(ncid)
+ call check(err, 'In nf90mpi_enddef: ')
+
+ ! write one variable at a time using iput
+ do i=1, NUM_VARS
+ write(str,'(I2)') i
+ err = nf90mpi_iput_var(ncid, varids(i), buf(i)%p, req(i), &
+ starts, counts)
+ call check(err, 'In nf90mpi_iput_var '//trim(str))
+ enddo
+
+ ! wait for the nonblocking I/O to complete
+ err = nf90mpi_wait_all(ncid, NUM_VARS, req, st)
+ call check(err, 'In nf90mpi_wait_all')
+
+ ! check the status of each nonblocking request
+ do i=1, NUM_VARS
+ write(str,'(I2)') i
+ call check(st(i), 'In nf90mpi_wait_all req '//trim(str))
+ enddo
+
+ ! write one variable at a time using bput
+
+ ! bbufsize must be max of data type converted before and after
+ bbufsize = bufsize * NUM_VARS * 4 ! 4 is size of integer
+ err = nf90mpi_buffer_attach(ncid, bbufsize)
+ call check(err, 'In nf90mpi_buffer_attach')
+
+ do i=1, NUM_VARS
+ write(str,'(I2)') i
+ err = nf90mpi_bput_var(ncid, varids(i), buf(i)%p, req(i), &
+ starts, counts)
+ call check(err, 'In nf90mpi_bput_var '//trim(str))
+
+ ! can safely free up the buffer here
+ deallocate(buf(i)%p)
+ enddo
+
+ ! wait for the nonblocking I/O to complete
+ err = nf90mpi_wait_all(ncid, NUM_VARS, req, st)
+ call check(err, 'In nf90mpi_wait_all')
+
+ ! check the status of each nonblocking request
+ do i=1, NUM_VARS
+ write(str,'(I2)') i
+ call check(st(i), 'In nf90mpi_wait_all req '//trim(str))
+ enddo
+
+ ! detach the temporary buffer
+ err = nf90mpi_buffer_detach(ncid)
+ call check(err, 'In nf90mpi_buffer_detach')
+
+ ! close the file
+ err = nf90mpi_close(ncid);
+ call check(err, 'In nf90mpi_close')
+
+ ! check if there is any PnetCDF internal malloc residue
+ 998 format(A,I13,A)
+ err = nf90mpi_inq_malloc_size(malloc_size)
+ if (err == NF90_NOERR) then
+ call MPI_Reduce(malloc_size, sum_size, 1, MPI_OFFSET, &
+ MPI_SUM, 0, MPI_COMM_WORLD, err)
+ if (rank .EQ. 0 .AND. sum_size .GT. 0_MPI_OFFSET_KIND) print 998, &
+ 'heap memory allocated by PnetCDF internally has ', &
+ sum_size/1048576, ' MiB yet to be freed'
+ endif
+
+ 999 call MPI_Finalize(err)
+ ! call EXIT(0) ! EXIT() is a GNU extension
+
+ end program main
+
diff --git a/examples/F90/put_var.f90 b/examples/F90/put_var.f90
new file mode 100644
index 0000000..957cbd9
--- /dev/null
+++ b/examples/F90/put_var.f90
@@ -0,0 +1,152 @@
+!
+! Copyright (C) 2013, Northwestern University and Argonne National Laboratory
+! See COPYRIGHT notice in top-level directory.
+!
+! $Id: put_var.f90 2245 2015-12-20 18:39:52Z wkliao $
+
+!
+! This example shows how to use nf90mpi_put_var_all() to write a 2D
+! 4-byte integer array in parallel. It first defines a netCDF variable of
+! size global_nx * global_ny where
+! global_nx == 5 and
+! global_ny == (4 * number of MPI processes).
+! The data partitioning pattern is a column-wise partitioning across all
+! processes. Each process writes a subarray of size nx * ny.
+! Note the description above follows the Fortran array index order.
+!
+! Example commands for MPI run and outputs from running ncmpidump on the
+! NC file produced by this example program:
+!
+! % mpif90 -O2 -o put_var put_var.f90 -lpnetcdf
+! % mpiexec -n 4 ./put_var /pvfs2/wkliao/testfile.nc
+!
+! % ncmpidump /pvfs2/wkliao/testfile.nc
+! netcdf testfile {
+! // file format: CDF-5 (big variables)
+! dimensions:
+! x = 5 ;
+! y = 16 ;
+! variables:
+! int var(y, x) ;
+! data:
+!
+! var =
+! 0, 0, 0, 0, 0,
+! 0, 0, 0, 0, 0,
+! 0, 0, 0, 0, 0,
+! 0, 0, 0, 0, 0,
+! 1, 1, 1, 1, 1,
+! 1, 1, 1, 1, 1,
+! 1, 1, 1, 1, 1,
+! 1, 1, 1, 1, 1,
+! 2, 2, 2, 2, 2,
+! 2, 2, 2, 2, 2,
+! 2, 2, 2, 2, 2,
+! 2, 2, 2, 2, 2,
+! 3, 3, 3, 3, 3,
+! 3, 3, 3, 3, 3,
+! 3, 3, 3, 3, 3,
+! 3, 3, 3, 3, 3 ;
+! }
+!
+ subroutine check(err, message)
+ use mpi
+ use pnetcdf
+ implicit none
+ integer err
+ character(len=*) message
+
+ ! It is a good idea to check returned value for possible error
+ if (err .NE. NF90_NOERR) then
+ write(6,*) trim(message), trim(nf90mpi_strerror(err))
+ call MPI_Abort(MPI_COMM_WORLD, -1, err)
+ end if
+ end subroutine check
+
+ program main
+ use mpi
+ use pnetcdf
+ implicit none
+
+ character(LEN=128) filename, cmd
+ integer err, nprocs, rank, ierr, get_args, dummy
+ integer cmode, ncid, varid, dimid(2)
+ integer(kind=MPI_OFFSET_KIND) nx, ny, global_nx, global_ny
+ integer(kind=MPI_OFFSET_KIND) starts(2), counts(2)
+ integer(kind=MPI_OFFSET_KIND) malloc_size, sum_size
+ PARAMETER(nx=5, ny=4)
+ integer buf(nx,ny)
+ logical verbose
+
+ call MPI_Init(err)
+ call MPI_Comm_rank(MPI_COMM_WORLD, rank, err)
+ call MPI_Comm_size(MPI_COMM_WORLD, nprocs, err)
+
+ ! take filename from command-line argument if there is any
+ if (rank .EQ. 0) then
+ verbose = .TRUE.
+ filename = "testfile.nc"
+ ierr = get_args(2, cmd, filename, verbose, dummy)
+ endif
+ call MPI_Bcast(ierr, 1, MPI_INTEGER, 0, MPI_COMM_WORLD, err)
+ if (ierr .EQ. 0) goto 999
+
+ call MPI_Bcast(verbose, 1, MPI_LOGICAL, 0, MPI_COMM_WORLD, err)
+ call MPI_Bcast(filename, 256, MPI_CHARACTER, 0, MPI_COMM_WORLD, err)
+
+ ! set parameters
+ global_nx = nx
+ global_ny = ny * nprocs
+
+ buf = rank;
+
+ ! create file, truncate it if exists
+ cmode = IOR(NF90_CLOBBER, NF90_64BIT_DATA)
+ err = nf90mpi_create(MPI_COMM_WORLD, filename, cmode, &
+ MPI_INFO_NULL, ncid)
+ call check(err, 'In nf90mpi_create: ')
+
+ ! define dimensions x and y
+ err = nf90mpi_def_dim(ncid, "x", global_nx, dimid(1))
+ call check(err, 'In nf90mpi_def_dim x: ')
+ err = nf90mpi_def_dim(ncid, "y", global_ny, dimid(2))
+ call check(err, 'In nf90mpi_def_dim y: ')
+
+ ! define a 2D variable of integer type
+ err = nf90mpi_def_var(ncid, "var", NF90_INT, dimid, varid)
+ call check(err, 'In nf90mpi_def_var: ')
+
+ ! do not forget to exit define mode
+ err = nf90mpi_enddef(ncid)
+ call check(err, 'In nf90mpi_enddef: ')
+
+ ! now we are in data mode
+
+ ! Note that in Fortran, array indices start with 1
+ starts(1) = 1
+ starts(2) = ny * rank + 1
+ counts(1) = nx
+ counts(2) = ny
+
+ err = nf90mpi_put_var_all(ncid, varid, buf, starts, counts)
+ call check(err, 'In nf90mpi_put_var_all: ')
+
+ ! close the file
+ err = nf90mpi_close(ncid)
+ call check(err, 'In nf90mpi_close: ')
+
+ ! check if there is any PnetCDF internal malloc residue
+ 998 format(A,I13,A)
+ err = nf90mpi_inq_malloc_size(malloc_size)
+ if (err == NF90_NOERR) then
+ call MPI_Reduce(malloc_size, sum_size, 1, MPI_OFFSET, &
+ MPI_SUM, 0, MPI_COMM_WORLD, err)
+ if (rank .EQ. 0 .AND. sum_size .GT. 0_MPI_OFFSET_KIND) print 998, &
+ 'heap memory allocated by PnetCDF internally has ', &
+ sum_size/1048576, ' MiB yet to be freed'
+ endif
+
+ 999 call MPI_Finalize(err)
+ ! call EXIT(0) ! EXIT() is a GNU extension
+ end program main
+
diff --git a/examples/F90/put_varn_int.f90 b/examples/F90/put_varn_int.f90
new file mode 100644
index 0000000..0c15021
--- /dev/null
+++ b/examples/F90/put_varn_int.f90
@@ -0,0 +1,259 @@
+!
+! Copyright (C) 2013, Northwestern University and Argonne National Laboratory
+! See COPYRIGHT notice in top-level directory.
+!
+! $Id: put_varn_int.f90 2139 2015-10-08 01:59:10Z wkliao $
+
+! This example shows how to use a single call of nf90mpi_put_varn_all() to
+! write a sequence of requests with arbitrary array indices and lengths.
+! Using nf90mpi_put_varn_all() can achieve the same effect of HDF5 writing
+! a sequence of selected file locations through the following 2 APIs.
+!
+! H5Sselect_elements(fid, H5S_SELECT_SET, NUMP, (const hssize_t **)coord);
+! H5Dwrite(dataset, H5T_NATIVE_INT, mid, fid, H5P_DEFAULT, val);
+!
+! Note that in nf90mpi_put_varn_all(), users can write more than one element
+! starting at each selected location.
+!
+! The compile and run commands are given below, together with an ncmpidump of
+! the output file.
+!
+! % mpif90 -O2 -o put_varn_int put_varn_int.f90 -lpnetcdf
+! % mpiexec -n 4 ./put_varn_int /pvfs2/wkliao/testfile.nc
+! % ncmpidump /pvfs2/wkliao/testfile.nc
+! netcdf testfile {
+! // file format: CDF-5 (big variables)
+! dimensions:
+! X = 4 ;
+! Y = 10 ;
+! variables:
+! int var(Y, X) ;
+! data:
+!
+! var =
+! 2, 2, 1, 1,
+! 2, 2, 0, 0,
+! 1, 1, 0, 0,
+! 1, 1, 3, 3,
+! 3, 3, 2, 2,
+! 0, 0, 1, 1,
+! 0, 0, 1, 1,
+! 2, 2, 0, 0,
+! 3, 3, 3, 3,
+! 3, 3, 3, 3 ;
+! }
+!
+! Note the above dump is in C order
+!
+ subroutine check(err, message)
+ use mpi
+ use pnetcdf
+ implicit none
+ integer err
+ character(len=*) message
+
+ ! It is a good idea to check returned value for possible error
+ if (err .NE. NF90_NOERR) then
+ write(6,*) trim(message), trim(nf90mpi_strerror(err))
+ call MPI_Abort(MPI_COMM_WORLD, -1, err)
+ end if
+ end subroutine check
+
+ program main
+ use mpi
+ use pnetcdf
+ implicit none
+
+ integer NDIMS
+ integer(kind=MPI_OFFSET_KIND) NX, NY
+ PARAMETER(NDIMS=2, NX=4, NY=10)
+
+ character(LEN=128) filename, cmd
+ integer i, j, err, nprocs, rank, ierr, get_args, dummy
+ integer cmode, ncid, varid, dimid(NDIMS), num_reqs
+
+ integer(kind=MPI_OFFSET_KIND) w_len, w_req_len
+ integer(kind=MPI_OFFSET_KIND), allocatable :: starts(:,:)
+ integer(kind=MPI_OFFSET_KIND), allocatable :: counts(:,:)
+ integer(kind=MPI_OFFSET_KIND) malloc_size, sum_size
+ integer, allocatable :: buffer(:)
+ logical verbose
+
+ call MPI_Init(err)
+ call MPI_Comm_rank(MPI_COMM_WORLD, rank, err)
+ call MPI_Comm_size(MPI_COMM_WORLD, nprocs, err)
+
+ ! take filename from command-line argument if there is any
+ if (rank .EQ. 0) then
+ verbose = .TRUE.
+ filename = "testfile.nc"
+ ierr = get_args(2, cmd, filename, verbose, dummy)
+ endif
+ call MPI_Bcast(ierr, 1, MPI_INTEGER, 0, MPI_COMM_WORLD, err)
+ if (ierr .EQ. 0) goto 999
+
+ call MPI_Bcast(verbose, 1, MPI_LOGICAL, 0, MPI_COMM_WORLD, err)
+ call MPI_Bcast(filename, 256, MPI_CHARACTER, 0, MPI_COMM_WORLD, err)
+
+ if (nprocs .NE. 4 .AND. rank .EQ. 0 .AND. verbose) &
+ print*,'Warning: ',trim(cmd),' is intended to run on ', &
+ '4 processes'
+
+ ! create file, truncate it if exists
+ cmode = IOR(NF90_CLOBBER, NF90_64BIT_DATA)
+ err = nf90mpi_create(MPI_COMM_WORLD, filename, cmode, &
+ MPI_INFO_NULL, ncid)
+ call check(err, 'In nf90mpi_create: ')
+
+ ! define dimensions x and y
+ err = nf90mpi_def_dim(ncid, "X", NX, dimid(1))
+ call check(err, 'In nf90mpi_def_dim X: ')
+ err = nf90mpi_def_dim(ncid, "Y", NY, dimid(2))
+ call check(err, 'In nf90mpi_def_dim Y: ')
+
+ ! define a 2D variable of integer type
+ err = nf90mpi_def_var(ncid, "var", NF90_INT, dimid, varid)
+ call check(err, 'In nf90mpi_def_var: ')
+
+ ! do not forget to exit define mode
+ err = nf90mpi_enddef(ncid)
+ call check(err, 'In nf90mpi_enddef: ')
+
+ ! now we are in data mode
+
+ ! pick arbitrary numbers of requests for 4 processes
+ num_reqs = 0
+ if (rank .EQ. 0) then
+ num_reqs = 3
+ elseif (rank .EQ. 1) then
+ num_reqs = 3
+ elseif (rank .EQ. 2) then
+ num_reqs = 3
+ elseif (rank .EQ. 3) then
+ num_reqs = 3
+ endif
+
+ ! Note that in Fortran, array indices start with 1
+ ALLOCATE(starts(NDIMS, num_reqs))
+ ALLOCATE(counts(NDIMS, num_reqs))
+
+ ! assign arbitrary starts and counts
+ if (rank .EQ. 0) then
+ ! rank 0 is writing the followings: ("-" means skip)
+ ! - - - - - 0 0 - - -
+ ! - - - - - 0 0 - - -
+ ! - 0 0 - - - - 0 - -
+ ! - 0 0 - - - - 0 - -
+ ! Note this is in Fortran order
+ starts(1, 1) = 1
+ starts(2, 1) = 6
+ counts(1, 1) = 2
+ counts(2, 1) = 2
+ starts(1, 2) = 3
+ starts(2, 2) = 2
+ counts(1, 2) = 2
+ counts(2, 2) = 2
+ starts(1, 3) = 3
+ starts(2, 3) = 8
+ counts(1, 3) = 2
+ counts(2, 3) = 1
+ elseif (rank .EQ. 1) then
+ ! rank 1 is writing the followings: ("-" means skip)
+ ! - - 1 1 - - - - - -
+ ! - - 1 1 - - - - - -
+ ! 1 - - - - 1 1 - - -
+ ! 1 - - - - 1 1 - - -
+ ! Note this is in Fortran order
+ starts(1, 1) = 1
+ starts(2, 1) = 3
+ counts(1, 1) = 2
+ counts(2, 1) = 2
+ starts(1, 2) = 3
+ starts(2, 2) = 1
+ counts(1, 2) = 2
+ counts(2, 2) = 1
+ starts(1, 3) = 3
+ starts(2, 3) = 6
+ counts(1, 3) = 2
+ counts(2, 3) = 2
+ elseif (rank .EQ. 2) then
+ ! rank 2 is writing the followings: ("-" means skip)
+ ! 2 2 - - - - - 2 - -
+ ! 2 2 - - - - - 2 - -
+ ! - - - - 2 - - - - -
+ ! - - - - 2 - - - - -
+ ! Note this is in Fortran order
+ starts(1, 1) = 1
+ starts(2, 1) = 1
+ counts(1, 1) = 2
+ counts(2, 1) = 2
+ starts(1, 2) = 1
+ starts(2, 2) = 8
+ counts(1, 2) = 2
+ counts(2, 2) = 1
+ starts(1, 3) = 3
+ starts(2, 3) = 5
+ counts(1, 3) = 2
+ counts(2, 3) = 1
+ elseif (rank .EQ. 3) then
+ ! rank 3 is writing the followings: ("-" means skip)
+ ! - - - - 3 - - - 3 3
+ ! - - - - 3 - - - 3 3
+ ! - - - 3 - - - - 3 3
+ ! - - - 3 - - - - 3 3
+ ! Note this is in Fortran order
+ starts(1, 1) = 1
+ starts(2, 1) = 5
+ counts(1, 1) = 2
+ counts(2, 1) = 1
+ starts(1, 2) = 1
+ starts(2, 2) = 9
+ counts(1, 2) = 4
+ counts(2, 2) = 2
+ starts(1, 3) = 3
+ starts(2, 3) = 4
+ counts(1, 3) = 2
+ counts(2, 3) = 1
+ endif
+
+ ! w_len is total write length for this process
+ w_len = 0
+ do i=1, num_reqs
+ w_req_len = 1
+ do j=1, NDIMS
+ w_req_len = w_req_len * counts(j, i)
+ enddo
+ w_len = w_len + w_req_len;
+ enddo
+ ALLOCATE(buffer(w_len))
+
+ ! initialize buffer contents
+ buffer = rank;
+
+ err = nf90mpi_put_varn_all(ncid, varid, buffer, num_reqs, &
+ starts, counts)
+ call check(err, 'In nf90mpi_put_varn_int_all: ')
+
+ ! close the file
+ err = nf90mpi_close(ncid)
+ call check(err, 'In nf90mpi_close: ')
+
+ DEALLOCATE(buffer);
+ DEALLOCATE(starts);
+ DEALLOCATE(counts);
+
+ ! check if there is any PnetCDF internal malloc residue
+ 998 format(A,I13,A)
+ err = nf90mpi_inq_malloc_size(malloc_size)
+ if (err == NF90_NOERR) then
+ call MPI_Reduce(malloc_size, sum_size, 1, MPI_OFFSET, &
+ MPI_SUM, 0, MPI_COMM_WORLD, err)
+ if (rank .EQ. 0 .AND. sum_size .GT. 0_MPI_OFFSET_KIND) print 998, &
+ 'heap memory allocated by PnetCDF internally has ', &
+ sum_size/1048576, ' MiB yet to be freed'
+ endif
+
+ 999 call MPI_Finalize(err)
+ ! call EXIT(0) ! EXIT() is a GNU extension
+ end program main
+
diff --git a/examples/F90/put_varn_real.f90 b/examples/F90/put_varn_real.f90
new file mode 100644
index 0000000..8f0c293
--- /dev/null
+++ b/examples/F90/put_varn_real.f90
@@ -0,0 +1,253 @@
+!
+! Copyright (C) 2012, Northwestern University and Argonne National Laboratory
+! See COPYRIGHT notice in top-level directory.
+!
+! $Id: put_varn_real.f90 2139 2015-10-08 01:59:10Z wkliao $
+
+!
+! This example shows how to use a single call of nf90mpi_put_varn_all()
+! to write a sequence of one-element requests with arbitrary array indices.
+!
+! The compile and run commands are given below, together with an ncmpidump of
+! the output file.
+!
+! % mpif90 -O2 -o put_varn_real put_varn_real.f90 -lpnetcdf
+! % mpiexec -n 4 ./put_varn_real /pvfs2/wkliao/testfile.nc
+! % ncmpidump /pvfs2/wkliao/testfile.nc
+! netcdf testfile {
+! // file format: CDF-5 (big variables)
+! dimensions:
+! Y = 4 ;
+! X = 10 ;
+! variables:
+! int var(Y, X) ;
+! data:
+!
+! var =
+! 3, 3, 3, 1, 1, 0, 0, 2, 1, 1,
+! 0, 2, 2, 2, 3, 1, 1, 2, 2, 2,
+! 1, 1, 2, 3, 3, 3, 0, 0, 1, 1,
+! 0, 0, 0, 2, 1, 1, 1, 3, 3, 3 ;
+! }
+!
+
+ subroutine check(err, message)
+ use mpi
+ use pnetcdf
+ implicit none
+ integer err
+ character(len=*) message
+
+ ! It is a good idea to check returned value for possible error
+ if (err .NE. NF90_NOERR) then
+ write(6,*) trim(message), trim(nf90mpi_strerror(err))
+ call MPI_Abort(MPI_COMM_WORLD, -1, err)
+ end if
+ end subroutine check
+
+ program main
+ use mpi
+ use pnetcdf
+ implicit none
+
+ integer NDIMS
+ PARAMETER(NDIMS=2)
+
+ character(LEN=128) filename, cmd
+ integer rank, nprocs, err, num_reqs, ierr, get_args, dummy
+ integer ncid, cmode, varid, dimid(2), y, x
+ real buffer(13)
+ integer(kind=MPI_OFFSET_KIND) NY, NX
+ integer(kind=MPI_OFFSET_KIND) starts(NDIMS, 13)
+ integer(kind=MPI_OFFSET_KIND) counts(NDIMS, 13)
+ integer(kind=MPI_OFFSET_KIND) malloc_size, sum_size
+ logical verbose
+
+ NY = 4
+ NX = 10
+
+ call MPI_Init(err)
+ call MPI_Comm_rank(MPI_COMM_WORLD, rank, err)
+ call MPI_Comm_size(MPI_COMM_WORLD, nprocs, err)
+
+ ! take filename from command-line argument if there is any
+ if (rank .EQ. 0) then
+ verbose = .TRUE.
+ filename = "testfile.nc"
+ ierr = get_args(2, cmd, filename, verbose, dummy)
+ endif
+ call MPI_Bcast(ierr, 1, MPI_INTEGER, 0, MPI_COMM_WORLD, err)
+ if (ierr .EQ. 0) goto 999
+
+ call MPI_Bcast(verbose, 1, MPI_LOGICAL, 0, MPI_COMM_WORLD, err)
+ call MPI_Bcast(filename, 256, MPI_CHARACTER, 0, MPI_COMM_WORLD, err)
+
+ if (nprocs .NE. 4 .AND. rank .EQ. 0 .AND. verbose) &
+ print*,'Warning: ',trim(cmd),' is intended to run on ', &
+ '4 processes'
+
+ ! create file, truncate it if exists
+ cmode = IOR(NF90_CLOBBER, NF90_64BIT_DATA)
+ err = nf90mpi_create(MPI_COMM_WORLD, filename, cmode, &
+ MPI_INFO_NULL, ncid)
+ call check(err, 'In nf90mpi_create: ')
+
+ ! create a global array of size NY * NX */
+ err = nf90mpi_def_dim(ncid, "Y", NY, dimid(2))
+ call check(err, 'In nf90mpi_def_dim Y: ')
+ err = nf90mpi_def_dim(ncid, "X", NX, dimid(1))
+ call check(err, 'In nf90mpi_def_dim X: ')
+ err = nf90mpi_def_var(ncid, "var", NF90_FLOAT, dimid, varid)
+ call check(err, 'In nf90mpi_def_var var: ')
+ err = nf90mpi_enddef(ncid)
+ call check(err, 'In nf90mpi_enddef: ')
+
+ ! pick arbitrary numbers of requests for 4 processes
+ num_reqs = 0
+ if (rank .EQ. 0) then
+ num_reqs = 8
+ elseif (rank .EQ. 1) then
+ num_reqs = 13
+ elseif (rank .EQ. 2) then
+ num_reqs = 9
+ elseif (rank .EQ. 3) then
+ num_reqs = 10
+ endif
+
+ ! assign arbitrary starts
+ y=2
+ x=1
+ if (rank .EQ. 0) then
+ starts(y, 1) = 1
+ starts(x, 1) = 6
+ starts(y, 2) = 2
+ starts(x, 2) = 1
+ starts(y, 3) = 3
+ starts(x, 3) = 7
+ starts(y, 4) = 4
+ starts(x, 4) = 1
+ starts(y, 5) = 1
+ starts(x, 5) = 7
+ starts(y, 6) = 3
+ starts(x, 6) = 8
+ starts(y, 7) = 4
+ starts(x, 7) = 2
+ starts(y, 8) = 4
+ starts(x, 8) = 3
+ ! rank 0 is writing the following locations: ("-" means skip)
+ ! - - - - - 0 0 - - -
+ ! 0 - - - - - - - - -
+ ! - - - - - - 0 0 - -
+ ! 0 0 0 - - - - - - -
+ elseif (rank .EQ. 1) then
+ starts(y, 1) = 1
+ starts(x, 1) = 4
+ starts(y, 2) = 1
+ starts(x, 2) = 9
+ starts(y, 3) = 2
+ starts(x, 3) = 6
+ starts(y, 4) = 3
+ starts(x, 4) = 1
+ starts(y, 5) = 3
+ starts(x, 5) = 9
+ starts(y, 6) = 4
+ starts(x, 6) = 5
+ starts(y, 7) = 1
+ starts(x, 7) = 5
+ starts(y, 8) = 1
+ starts(x, 8) = 10
+ starts(y, 9) = 2
+ starts(x, 9) = 7
+ starts(y, 10) = 3
+ starts(x, 10) = 2
+ starts(y, 11) = 3
+ starts(x, 11) = 10
+ starts(y, 12) = 4
+ starts(x, 12) = 6
+ starts(y, 13) = 4
+ starts(x, 13) = 7
+ ! rank 1 is writing the following locations: ("-" means skip)
+ ! - - - 1 1 - - - 1 1
+ ! - - - - - 1 1 - - -
+ ! 1 1 - - - - - - 1 1
+ ! - - - - 1 1 1 - - -
+ elseif (rank .EQ. 2) then
+ starts(y, 1) = 1
+ starts(x, 1) = 8
+ starts(y, 2) = 2
+ starts(x, 2) = 2
+ starts(y, 3) = 2
+ starts(x, 3) = 8
+ starts(y, 4) = 3
+ starts(x, 4) = 3
+ starts(y, 5) = 4
+ starts(x, 5) = 4
+ starts(y, 6) = 2
+ starts(x, 6) = 3
+ starts(y, 7) = 2
+ starts(x, 7) = 9
+ starts(y, 8) = 2
+ starts(x, 8) = 4
+ starts(y, 9) = 2
+ starts(x, 9) = 10
+ ! rank 2 is writing the following locations: ("-" means skip)
+ ! - - - - - - - 2 - -
+ ! - 2 2 2 - - - 2 2 2
+ ! - - 2 - - - - - - -
+ ! - - - 2 - - - - - -
+ elseif (rank .EQ. 3) then
+ starts(y, 1) = 1
+ starts(x, 1) = 1
+ starts(y, 2) = 2
+ starts(x, 2) = 5
+ starts(y, 3) = 3
+ starts(x, 3) = 4
+ starts(y, 4) = 4
+ starts(x, 4) = 8
+ starts(y, 5) = 1
+ starts(x, 5) = 2
+ starts(y, 6) = 3
+ starts(x, 6) = 5
+ starts(y, 7) = 4
+ starts(x, 7) = 9
+ starts(y, 8) = 1
+ starts(x, 8) = 3
+ starts(y, 9) = 3
+ starts(x, 9) = 6
+ starts(y, 10) = 4
+ starts(x, 10) = 10
+ ! rank 3 is writing the following locations: ("-" means skip)
+ ! 3 3 3 - - - - - - -
+ ! - - - - 3 - - - - -
+ ! - - - 3 3 3 - - - -
+ ! - - - - - - - 3 3 3
+ endif
+ counts = 1
+
+ ! allocate I/O buffer and initialize its contents
+ buffer = rank
+
+ ! set the buffer pointers to different offsets to the I/O buffer
+ err = nf90mpi_put_varn_all(ncid, varid, buffer, num_reqs, &
+ starts, counts)
+ call check(err, 'In nf90mpi_put_varn_all: ')
+
+ err = nf90mpi_close(ncid);
+ call check(err, 'In nf90mpi_close: ')
+
+ ! check if there is any PnetCDF internal malloc residue
+ 998 format(A,I13,A)
+ err = nf90mpi_inq_malloc_size(malloc_size)
+ if (err == NF90_NOERR) then
+ call MPI_Reduce(malloc_size, sum_size, 1, MPI_OFFSET, &
+ MPI_SUM, 0, MPI_COMM_WORLD, err)
+ if (rank .EQ. 0 .AND. sum_size .GT. 0_MPI_OFFSET_KIND) print 998, &
+ 'heap memory allocated by PnetCDF internally has ', &
+ sum_size/1048576, ' MiB yet to be freed'
+ endif
+
+ 999 call MPI_Finalize(err)
+ ! call EXIT(0) ! EXIT() is a GNU extension
+
+ end program
+
diff --git a/examples/F90/transpose.f90 b/examples/F90/transpose.f90
new file mode 100644
index 0000000..44b4331
--- /dev/null
+++ b/examples/F90/transpose.f90
@@ -0,0 +1,235 @@
+!
+! Copyright (C) 2014, Northwestern University
+! See COPYRIGHT notice in top-level directory.
+!
+! $Id: transpose.f90 2139 2015-10-08 01:59:10Z wkliao $
+
+!
+! This example shows how to use varm API to write six 3D integer
+! array variables into a file. Each variable in the file is a
+! dimensional transposed array from the one stored in memory. In
+! memory, a 3D array is partitioned among all processes in a
+! block-block-block fashion and in XYZ (i.e. Fortran) order. Note
+! the variable and dimension naming below is in Fortran order. The
+! dimension structures of the transposed six arrays are
+! integer XYZ_var(X, Y, Z) XYZ -> XYZ (no transpose)
+! integer XZY_var(X, Z, Y) XYZ -> XZY
+! integer YXZ_var(Y, X, Z) XYZ -> YXZ
+! integer YZX_var(Y, Z, X) XYZ -> YZX
+! integer ZXY_var(Z, X, Y) XYZ -> ZXY
+! integer ZYX_var(Z, Y, X) XYZ -> ZYX
+!
+! To compile:
+! mpif90 -O2 transpose.f90 -o transpose -lpnetcdf
+! To run:
+! mpiexec -n num_processes ./transpose [filename] [len]
+! where len decides the size of local array, which is
+! (len+2) x (len+1) x len. So, each variable is of size
+! (len+2)*(len+1)*len * nprocs * sizeof(int)
+!
+ subroutine check(err, message)
+ use mpi
+ use pnetcdf
+ implicit none
+ integer err
+ character(len=*) message
+
+ ! It is a good idea to check returned value for possible error
+ if (err .NE. NF90_NOERR) then
+ write(6,*) trim(message), trim(nf90mpi_strerror(err))
+ call MPI_Abort(MPI_COMM_WORLD, -1, err)
+ end if
+ end subroutine check
+
+ program main
+ use mpi
+ use pnetcdf
+ implicit none
+
+ character(LEN=128) filename, cmd
+ integer err, nprocs, rank, lower_dims, ierr, get_args, dummy
+ integer cmode, ncid, psizes(3), dimids(3), dimidsT(3)
+ integer XYZ_id, XZY_id, YZX_id, YXZ_id, ZYX_id, ZXY_id
+ integer(kind=MPI_OFFSET_KIND) gsizes(3), starts(3)
+ integer(kind=MPI_OFFSET_KIND) counts(3), strides(3), imap(3)
+ integer(kind=MPI_OFFSET_KIND) startsT(3), countsT(3)
+ integer(kind=MPI_OFFSET_KIND) malloc_size, sum_size
+ integer i, j, k, nx, ny, nz
+ PARAMETER(nx=4, ny=3, nz=2)
+ integer buf(nx,ny,nz)
+ logical verbose
+
+ call MPI_Init(err)
+ call MPI_Comm_rank(MPI_COMM_WORLD, rank, err)
+ call MPI_Comm_size(MPI_COMM_WORLD, nprocs, err)
+
+ ! take filename from command-line argument if there is any
+ if (rank .EQ. 0) then
+ verbose = .TRUE.
+ filename = "testfile.nc"
+ ierr = get_args(2, cmd, filename, verbose, dummy)
+ endif
+ call MPI_Bcast(ierr, 1, MPI_INTEGER, 0, MPI_COMM_WORLD, err)
+ if (ierr .EQ. 0) goto 999
+
+ call MPI_Bcast(verbose, 1, MPI_LOGICAL, 0, MPI_COMM_WORLD, err)
+ call MPI_Bcast(filename, 256, MPI_CHARACTER, 0, MPI_COMM_WORLD, err)
+
+ ! calculate number of processes along each dimension
+ psizes = 0
+ call MPI_Dims_create(nprocs, 3, psizes, err)
+ if (verbose .AND. rank .EQ. 0) print*, "psizes= ",psizes(1:3)
+
+ ! for each MPI rank, find its local rank IDs along each dimension in
+ ! starts()
+ lower_dims = 1
+ do i=1, 3
+ starts(i) = MOD(rank / lower_dims, psizes(i))
+ lower_dims = lower_dims * psizes(i)
+ enddo
+ if (verbose) print*, "proc ",rank,": dim rank= ",starts(1:3)
+
+ strides = 1
+ gsizes = (/ nx, ny, nz /)
+ do i=1, 3
+ starts(i) = starts(i) * gsizes(i) + 1 ! start indices
+ counts(i) = gsizes(i) ! array elements
+ gsizes(i) = gsizes(i) * psizes(i) ! global array size
+ enddo
+
+ if (verbose) then
+ print*, "proc ",rank,": starts= ",starts(1:3)
+ print*, "proc ",rank,": counts= ",counts(1:3)
+ endif
+
+ ! initialize buffer with contiguous numbers
+ do k=1, nz
+ do j=1, ny
+ do i=1, nx
+ buf(i, j, k) = INT((starts(3)+k-2)*gsizes(2)*gsizes(1) + &
+ (starts(2)+j-2)*gsizes(1) + &
+ (starts(1)+i-2))
+ enddo
+ enddo
+ enddo
+ if (verbose .AND. rank .EQ. 0) print*, "buf= ",buf
+
+ ! create file, truncate it if exists
+ cmode = IOR(NF90_CLOBBER, NF90_64BIT_DATA)
+ cmode = NF90_CLOBBER
+ err = nf90mpi_create(MPI_COMM_WORLD, filename, cmode, &
+ MPI_INFO_NULL, ncid)
+ call check(err, 'In nf90mpi_create: ')
+
+ ! define dimensions X, Y, Z
+ err = nf90mpi_def_dim(ncid, "X", gsizes(1), dimids(1))
+ call check(err, 'In nf90mpi_def_dim X: ')
+ err = nf90mpi_def_dim(ncid, "Y", gsizes(2), dimids(2))
+ call check(err, 'In nf90mpi_def_dim Y: ')
+ err = nf90mpi_def_dim(ncid, "Z", gsizes(3), dimids(3))
+ call check(err, 'In nf90mpi_def_dim Z: ')
+
+ ! define variable with no transposed file layout: XYZ
+ err = nf90mpi_def_var(ncid, "XYZ_var", NF90_INT, dimids, &
+ XYZ_id)
+ call check(err, 'In nf90mpi_def_var XYZ_var: ')
+
+ ! define variable with transposed file layout: XYZ -> XZY
+ dimidsT = (/ dimids(1), dimids(3), dimids(2) /)
+ err = nf90mpi_def_var(ncid, "XZY_var", NF90_INT, dimidsT, &
+ XZY_id)
+ call check(err, 'In nf90mpi_def_var XZY_var: ')
+
+ ! define variable with transposed file layout: XYZ -> YXZ
+ dimidsT = (/ dimids(2), dimids(1), dimids(3) /)
+ err = nf90mpi_def_var(ncid, "YXZ_var", NF90_INT, dimidsT, &
+ YXZ_id)
+ call check(err, 'In nf90mpi_def_var YXZ_var: ')
+
+ ! define variable with transposed file layout: XYZ -> YZX
+ dimidsT = (/ dimids(2), dimids(3), dimids(1) /)
+ err = nf90mpi_def_var(ncid, "YZX_var", NF90_INT, dimidsT, &
+ YZX_id)
+ call check(err, 'In nf90mpi_def_var YZX_var: ')
+
+ ! define variable with transposed file layout: XYZ -> ZXY
+ dimidsT = (/ dimids(3), dimids(1), dimids(2) /)
+ err = nf90mpi_def_var(ncid, "ZXY_var", NF90_INT, dimidsT, &
+ ZXY_id)
+ call check(err, 'In nf90mpi_def_var ZXY_var: ')
+
+ ! define variable with transposed file layout: XYZ -> ZYX
+ dimidsT = (/ dimids(3), dimids(2), dimids(1) /)
+ err = nf90mpi_def_var(ncid, "ZYX_var", NF90_INT, dimidsT, &
+ ZYX_id)
+ call check(err, 'In nf90mpi_def_var ZYX_var: ')
+
+ ! do not forget to exit define mode
+ err = nf90mpi_enddef(ncid)
+ call check(err, 'In nf90mpi_enddef: ')
+
+ ! now we are in data mode
+
+ ! write the whole variable in file: XYZ
+ err = nf90mpi_put_var_all(ncid, XYZ_id, buf, starts, counts)
+ call check(err, 'In nf90mpi_put_vara_int_all XYZ: ')
+
+ ! write the transposed variable: XYZ -> XZY
+ imap = (/ 1_MPI_OFFSET_KIND, counts(1)*counts(2), counts(1) /)
+ startsT = (/ starts(1), starts(3), starts(2) /)
+ countsT = (/ counts(1), counts(3), counts(2) /)
+ err = nf90mpi_put_var_all(ncid, XZY_id, buf, startsT, &
+ countsT, strides, imap)
+ call check(err, 'In nf90mpi_put_var_all XZY: ')
+
+ ! write the transposed variable: XYZ -> YXZ
+ imap = (/ counts(1), 1_MPI_OFFSET_KIND, counts(1)*counts(2) /)
+ startsT = (/ starts(2), starts(1), starts(3) /)
+ countsT = (/ counts(2), counts(1), counts(3) /)
+ err = nf90mpi_put_var_all(ncid, YXZ_id, buf, startsT, &
+ countsT, strides, imap)
+ call check(err, 'In nf90mpi_put_var_all YZX: ')
+
+ ! write the transposed variable: XYZ -> YZX
+ imap = (/ counts(1), counts(1)*counts(2), 1_MPI_OFFSET_KIND /)
+ startsT = (/ starts(2), starts(3), starts(1) /)
+ countsT = (/ counts(2), counts(3), counts(1) /)
+ err = nf90mpi_put_var_all(ncid, YZX_id, buf, startsT, &
+ countsT, strides, imap)
+ call check(err, 'In nf90mpi_put_var_all YZX: ')
+
+ ! write the transposed variable: XYZ -> ZXY
+ imap = (/ counts(1)*counts(2), 1_MPI_OFFSET_KIND, counts(1) /)
+ startsT = (/ starts(3), starts(1), starts(2) /)
+ countsT = (/ counts(3), counts(1), counts(2) /)
+ err = nf90mpi_put_var_all(ncid, ZXY_id, buf, startsT, &
+ countsT, strides, imap)
+ call check(err, 'In nf90mpi_put_var_all ZXY: ')
+
+ ! write the transposed variable: XYZ -> ZYX
+ imap = (/ counts(1)*counts(2), counts(1), 1_MPI_OFFSET_KIND /)
+ startsT = (/ starts(3), starts(2), starts(1) /)
+ countsT = (/ counts(3), counts(2), counts(1) /)
+ err = nf90mpi_put_var_all(ncid, ZYX_id, buf, startsT, &
+ countsT, strides, imap)
+ call check(err, 'In nf90mpi_put_var_all ZYX: ')
+
+ ! close the file
+ err = nf90mpi_close(ncid)
+ call check(err, 'In nf90mpi_close: ')
+
+ ! check if there is any PnetCDF internal malloc residue
+ 998 format(A,I13,A)
+ err = nf90mpi_inq_malloc_size(malloc_size)
+ if (err == NF90_NOERR) then
+ call MPI_Reduce(malloc_size, sum_size, 1, MPI_OFFSET, &
+ MPI_SUM, 0, MPI_COMM_WORLD, err)
+ if (rank .EQ. 0 .AND. sum_size .GT. 0_MPI_OFFSET_KIND) print 998, &
+ 'heap memory allocated by PnetCDF internally has ', &
+ sum_size/1048576, ' MiB yet to be freed'
+ endif
+
+ 999 call MPI_Finalize(err)
+ ! call EXIT(0) ! EXIT() is a GNU extension
+ end program main
+
diff --git a/examples/F90/utils.F90 b/examples/F90/utils.F90
new file mode 100644
index 0000000..d83aeca
--- /dev/null
+++ b/examples/F90/utils.F90
@@ -0,0 +1,53 @@
+!
+! Copyright (C) 2015, Northwestern University and Argonne National Laboratory
+! See COPYRIGHT notice in top-level directory.
+!
+! This is part of the PnetCDF package.
+!
+! $Id: utils.F90 2120 2015-09-22 07:11:58Z wkliao $
+
+ ! This function gets the executable name and output file name from the
+ ! command line.
+ integer function get_args(max_argc, cmd, filename, verbose, len)
+#ifdef NAGf90Fortran
+ USE F90_UNIX_ENV, only : iargc, getarg
+ implicit none
+#else
+ implicit none
+ integer iargc
+#endif
+ integer max_argc, len
+ character(len=*) cmd, filename
+ logical verbose
+
+ ! local variables
+ integer argc
+ character(len=16) quiet_mode, str
+
+
+ call getarg(0, cmd)
+ argc = IARGC()
+ if (argc .GT. max_argc) then
+ if (max_argc .EQ. 3) &
+ print*,'Usage: ',trim(cmd),' [-q] [filename] [len]'
+ if (max_argc .EQ. 2) &
+ print*,'Usage: ',trim(cmd),' [-q] [filename]'
+ get_args = 0
+ return
+ endif
+ call getarg(1, quiet_mode)
+ if (quiet_mode(1:2) .EQ. '-q') then
+ verbose = .FALSE.
+ if (argc .GE. 2) call getarg(2, filename)
+ if (argc .EQ. 3) then
+ call getarg(3, str)
+ read (str,'(I10)') len
+ endif
+ else
+ if (argc .GE. 1) call getarg(1, filename)
+ if (argc .EQ. 2) then
+ call getarg(2, str)
+ read (str,'(I10)') len
+ endif
+ endif
+ end function get_args
diff --git a/examples/F90/vard_int.f90 b/examples/F90/vard_int.f90
new file mode 100644
index 0000000..4644d63
--- /dev/null
+++ b/examples/F90/vard_int.f90
@@ -0,0 +1,225 @@
+!
+! Copyright (C) 2014, Northwestern University and Argonne National Laboratory
+! See COPYRIGHT notice in top-level directory.
+!
+! $Id: vard_int.f90 2239 2015-12-18 18:21:09Z wkliao $
+
+!
+! This example shows how to use the vard API nf90mpi_put_vard() and
+! nf90mpi_get_vard() to write and read 2D record and fixed-size
+! variables.
+!
+! To compile:
+! mpif90 -O2 vard_int.f90 -o vard_int -lpnetcdf
+!
+! Example commands for MPI run and outputs from running ncmpidump on
+! the NC file produced by this example program:
+!
+! % mpiexec -n 4 ./vard_int /pvfs2/wkliao/testfile.nc
+!
+! The expected results from the output file contents are:
+!
+! % ncmpidump /pvfs2/wkliao/testfile.nc
+! netcdf testfile {
+! // file format: CDF-1
+! dimensions:
+! REC_DIM = UNLIMITED ; // (2 currently)
+! X = 12 ;
+! FIX_DIM = 2 ;
+! variables:
+! int rec_var(REC_DIM, X) ;
+! int fix_var(FIX_DIM, X) ;
+! data:
+!
+! rec_var =
+! 0, 1, 2, 100, 101, 102, 200, 201, 202, 300, 301, 302,
+! 10, 11, 12, 110, 111, 112, 210, 211, 212, 310, 311, 312 ;
+!
+! fix_var =
+! 0, 1, 2, 100, 101, 102, 200, 201, 202, 300, 301, 302,
+! 10, 11, 12, 110, 111, 112, 210, 211, 212, 310, 311, 312 ;
+! }
+!
+ subroutine check(err, message)
+ use mpi
+ use pnetcdf
+ implicit none
+ integer err
+ character(len=*) message
+
+ ! It is a good idea to check returned value for possible error
+ if (err .NE. NF90_NOERR) then
+ write(6,*) trim(message), trim(nf90mpi_strerror(err))
+ call MPI_Abort(MPI_COMM_WORLD, -1, err)
+ end if
+ end subroutine check
+
+ program main
+ use mpi
+ use pnetcdf
+ implicit none
+
+ character(LEN=128) filename, cmd
+ integer err, nprocs, rank, i, j, ierr, get_args, dummy
+ integer cmode, ncid, varid0, varid1, dimid(2)
+ integer(kind=MPI_OFFSET_KIND) NX, NY
+ integer(kind=MPI_OFFSET_KIND) start(2), count(2), bufcount
+ PARAMETER(NX=5, NY=2)
+ integer buf(NX, NY)
+ integer buftype, rec_filetype, fix_filetype
+ integer array_of_sizes(2), array_of_subsizes(2)
+ integer array_of_starts(2), blocklengths(2)
+ integer(kind=MPI_OFFSET_KIND) len, malloc_size, sum_size, recsize
+ integer(kind=MPI_ADDRESS_KIND) disps(2)
+ logical verbose
+
+ call MPI_Init(err)
+ call MPI_Comm_rank(MPI_COMM_WORLD, rank, err)
+ call MPI_Comm_size(MPI_COMM_WORLD, nprocs, err)
+
+ ! take filename from command-line argument if there is any
+ if (rank .EQ. 0) then
+ verbose = .TRUE.
+ filename = "testfile.nc"
+ ierr = get_args(2, cmd, filename, verbose, dummy)
+ endif
+ call MPI_Bcast(ierr, 1, MPI_INTEGER, 0, MPI_COMM_WORLD, err)
+ if (ierr .EQ. 0) goto 999
+
+ call MPI_Bcast(verbose, 1, MPI_LOGICAL, 0, MPI_COMM_WORLD, err)
+ call MPI_Bcast(filename, 256, MPI_CHARACTER, 0, MPI_COMM_WORLD, err)
+
+ start(1) = NX * rank
+ start(2) = 0
+ count(1) = NX
+ count(2) = 2
+
+ ! initialized buffer contents
+ do j=1, INT(count(2))
+ do i=1, INT(count(1))
+ buf(i, j) = rank*100 + j*10 + i
+ enddo
+ enddo
+
+ ! create file, truncate it if exists
+ cmode = NF90_CLOBBER
+ err = nf90mpi_create(MPI_COMM_WORLD, filename, cmode, &
+ MPI_INFO_NULL, ncid)
+ call check(err, 'In nf90mpi_create: ')
+
+ ! define 2 dimensions
+ err = nf90mpi_def_dim(ncid, "RECV_DIM", NF90MPI_UNLIMITED, dimid(2))
+ call check(err, 'In nf90mpi_def_dim RECV_DIM: ')
+ len = NX * nprocs
+ err = nf90mpi_def_dim(ncid, "X", len, dimid(1))
+ call check(err, 'In nf90mpi_def_dim X: ')
+
+ ! define 2D record variables of integer type
+ err = nf90mpi_def_var(ncid, "rec_var", NF90_INT, dimid, varid0)
+ call check(err, 'In nf90mpi_def_var: rec_var ')
+
+ ! define 2D fixed-size variable of integer type
+ err = nf90mpi_def_dim(ncid, "FIX_DIM", 2_MPI_OFFSET_KIND, dimid(2))
+ call check(err, 'In nf90mpi_def_dim RECV_DIM: ')
+ err = nf90mpi_def_var(ncid, "fix_var", NF90_INT, dimid, varid1)
+ call check(err, 'In nf90mpi_def_var: fix_var ')
+
+ ! do not forget to exit define mode
+ err = nf90mpi_enddef(ncid)
+ call check(err, 'In nf90mpi_enddef: ')
+
+ ! create a file type for the record variable */
+ err = nf90mpi_inq_recsize(ncid, recsize)
+ call check(err, 'In nf90mpi_inq_recsize: ')
+ blocklengths(1) = INT(count(1))
+ blocklengths(2) = INT(count(1))
+ disps(1) = start(1)*4
+ disps(2) = recsize + start(1)*4
+ call MPI_Type_create_hindexed(2, blocklengths, disps, &
+ MPI_INTEGER, rec_filetype, err)
+ call MPI_Type_commit(rec_filetype, err)
+
+ ! create a file type for the fixed-size variable
+ array_of_sizes(1) = INT(NX*nprocs)
+ array_of_sizes(2) = 2
+ array_of_subsizes(1) = INT(count(1))
+ array_of_subsizes(2) = INT(count(2))
+ array_of_starts(1) = INT(start(1))
+ array_of_starts(2) = INT(start(2))
+ call MPI_Type_create_subarray(2, array_of_sizes, array_of_subsizes, &
+ array_of_starts, MPI_ORDER_FORTRAN, MPI_INTEGER, fix_filetype,&
+ err)
+ call MPI_Type_commit(fix_filetype, err)
+
+ bufcount = count(1) * count(2)
+ buftype = MPI_INTEGER
+
+ ! write the record variable */
+ err = nf90mpi_put_vard_all(ncid, varid0, rec_filetype, buf, &
+ bufcount, buftype)
+ call check(err, 'In nf90mpi_put_vard_all: ')
+
+ ! check if the number of records changed to 2
+ err = nf90mpi_inquire(ncid, unlimitedDimId=dimid(2))
+ call check(err, 'In nf90mpi_inquire: ')
+ err = nf90mpi_inquire_dimension(ncid, dimid(2), len=len)
+ call check(err, 'In nf90mpi_inquire_dimension: ')
+ if (len .NE. 2) then
+ print*, 'Error: number of records should be 2 but got ', &
+ len
+ endif
+
+ ! write the fixed-size variable
+ err = nf90mpi_put_vard_all(ncid, varid1, fix_filetype, buf, &
+ bufcount, buftype)
+ call check(err, 'In nf90mpi_put_vard_all: ')
+
+ ! close the file
+ err = nf90mpi_close(ncid)
+ call check(err, 'In nf90mpi_close: ')
+
+ ! open the same file and read back for validate */
+ err = nf90mpi_open(MPI_COMM_WORLD, filename, NF90_NOWRITE, &
+ MPI_INFO_NULL, ncid)
+ call check(err, 'In nf90mpi_open: ')
+
+ err = nf90mpi_inq_varid(ncid, "rec_var", varid0)
+ call check(err, 'In nf90mpi_inq_varid rec_var: ')
+ err = nf90mpi_inq_varid(ncid, "fix_var", varid1)
+ call check(err, 'In nf90mpi_inq_varid fix_var: ')
+
+ ! PnetCDF start() argument starts with 1
+ start = start + 1
+
+ ! read back record variable
+ err = nf90mpi_get_vard_all(ncid, varid0, rec_filetype, buf, &
+ bufcount, buftype)
+ call check(err, 'In nf90mpi_get_vard_all: ')
+
+ ! read back fixed-size variable
+ err = nf90mpi_get_vard_all(ncid, varid1, fix_filetype, buf, &
+ bufcount, buftype)
+ call check(err, 'In nf90mpi_get_vard_all: ')
+
+ ! close the file
+ err = nf90mpi_close(ncid)
+ call check(err, 'In nf90mpi_close: ')
+
+ call MPI_Type_free(rec_filetype, err)
+ call MPI_Type_free(fix_filetype, err)
+
+ ! check if there is any PnetCDF internal malloc residue
+ 998 format(A,I13,A)
+ err = nf90mpi_inq_malloc_size(malloc_size)
+ if (err == NF90_NOERR) then
+ call MPI_Reduce(malloc_size, sum_size, 1, MPI_OFFSET, &
+ MPI_SUM, 0, MPI_COMM_WORLD, err)
+ if (rank .EQ. 0 .AND. sum_size .GT. 0_MPI_OFFSET_KIND) print 998, &
+ 'heap memory allocated by PnetCDF internally has ', &
+ sum_size/1048576, ' MiB yet to be freed'
+ endif
+
+ 999 call MPI_Finalize(err)
+ ! call EXIT(0) ! EXIT() is a GNU extension
+ end program main
+
diff --git a/examples/Makefile.in b/examples/Makefile.in
new file mode 100644
index 0000000..3a82558
--- /dev/null
+++ b/examples/Makefile.in
@@ -0,0 +1,72 @@
+#
+# Copyright (C) 2012, Northwestern University and Argonne National Laboratory
+# See COPYRIGHT notice in top-level directory.
+#
+# $Id: Makefile.in 2219 2015-12-11 22:30:03Z wkliao $
+#
+# @configure_input@
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+include ../macros.make
+
+GARBAGE =
+
+SUBDIRS = C tutorial
+
+ifeq (@has_mpicxx@, yes)
+SUBDIRS += CXX
+endif
+
+ifeq (@has_fortran@, yes)
+SUBDIRS += F77
+SUBDIRS += F90
+endif
+
+PACKING_LIST = Makefile.in README
+
+PACKING_SUBDIRS = C tutorial F77 F90 CXX
+
+all: $(SUBDIRS)
+$(SUBDIRS):
+ $(MAKE) $(MFLAGS) -C $@
+
+ptest: all
+ifeq (@enable_coverage@, yes)
+ echo "Parallel test is disabled because coverage analysis was enabled"
+else
+ (echo "=============================================") && \
+ (echo " Parallel testing on 4 MPI processes") && \
+ (echo "=============================================") && \
+ ( for d in $(SUBDIRS) ; do \
+ $(MAKE) $(MFLAGS) -C $$d ptest4 ; \
+ done ) ;
+endif
+
+ptests: all
+ifeq (@enable_coverage@, yes)
+ echo "Parallel test is disabled because coverage analysis was enabled"
+else
+ for i in 3 4 8 ; do \
+ (echo "=============================================") && \
+ (echo " Parallel testing on $$i MPI processes") && \
+ (echo "=============================================") && \
+ ( for d in $(SUBDIRS) ; do \
+ $(MAKE) $(MFLAGS) -C $$d ptest$$i ; \
+ done ) ; \
+ done ;
+endif
+
+INSTALLDIRS = $(SUBDIRS:%=install-%)
+install: all $(INSTALLDIRS)
+$(INSTALLDIRS):
+ $(MAKE) $(MFLAGS) -C $(@:install-%=%) install
+
+UNINSTALLDIRS = $(SUBDIRS:%=uninstall-%)
+uninstall: $(UNINSTALLDIRS)
+$(UNINSTALLDIRS):
+ $(MAKE) $(MFLAGS) -C $(@:uninstall-%=%) uninstall
+
+include $(srcdir)/../rules.make
+
diff --git a/examples/README b/examples/README
new file mode 100644
index 0000000..eba19f5
--- /dev/null
+++ b/examples/README
@@ -0,0 +1,322 @@
+#
+# Copyright (C) 2012, Northwestern University and Argonne National Laboratory
+# See COPYRIGHT notice in top-level directory.
+#
+# $Id: README 2245 2015-12-20 18:39:52Z wkliao $
+#
+
+This directory contains several example programs. Detailed descriptions of
+each program, compile and run instructions, and sample outputs are provided
+at the beginning of each file. Most of the example programs are developed
+with C, C++, F77, and F90 versions.
+
+
+./tutorial
+ A directory contains example programs that use different parallel I/O
+ strategies, including:
+ Parallel I/O from the master process
+ Concurrent I/O on separate files
+ Real parallel I/O on shared files
+ Using "flexible" APIs
+ Using non-blocking APIs
+ Using non-blocking buffered write APIs
+
+ Detailed descriptions for these programs can be found in
+ http://trac.mcs.anl.gov/projects/parallel-netcdf/wiki/QuickTutorial
+
+
+ ./C/block_cyclic.c
+./CXX/block_cyclic.cpp
+./F77/block_cyclic.f
+./F90/block_cyclic.f90
+
+ This example makes a number of nonblocking API calls, each to write a
+ block of columns into a 2D integer variable in a file. In other words,
+ data partitioning pattern is a block-cyclic along X dimension.
+ The pattern is described by the rank IDs if run with 4 processes.
+
+ 0, 0, 1, 1, 2, 2, 3, 3, 0, 0, 1, 1, 2, 2, 3, 3,
+ 0, 0, 1, 1, 2, 2, 3, 3, 0, 0, 1, 1, 2, 2, 3, 3,
+ 0, 0, 1, 1, 2, 2, 3, 3, 0, 0, 1, 1, 2, 2, 3, 3,
+ 0, 0, 1, 1, 2, 2, 3, 3, 0, 0, 1, 1, 2, 2, 3, 3,
+ 0, 0, 1, 1, 2, 2, 3, 3, 0, 0, 1, 1, 2, 2, 3, 3,
+ 0, 0, 1, 1, 2, 2, 3, 3, 0, 0, 1, 1, 2, 2, 3, 3,
+ 0, 0, 1, 1, 2, 2, 3, 3, 0, 0, 1, 1, 2, 2, 3, 3,
+ 0, 0, 1, 1, 2, 2, 3, 3, 0, 0, 1, 1, 2, 2, 3, 3,
+ 0, 0, 1, 1, 2, 2, 3, 3, 0, 0, 1, 1, 2, 2, 3, 3,
+ 0, 0, 1, 1, 2, 2, 3, 3, 0, 0, 1, 1, 2, 2, 3, 3 ;
+
+
+./C/collective_write.c
+./CXX/collective_write.cpp
+ This example defined NUM_VARS 3D integer non-record variables in a file.
+ All variables are partitioned among processes in a 3D block-block-block
+ fashion. The I/O is carried out by making NUM_VARS calls to
+ ncmpi_put_vara_int_all(), one for each variable. Performance measurements
+ are reported in the standard output.
+
+
+ ./C/column_wise.c
+./CXX/column_wise.cpp
+./F77/column_wise.f
+./F90/column_wise.f90
+ This example makes a number of nonblocking API calls, each writes a single
+ column of a 2D integer variable defined in a file. The data partitioning
+ pattern among processes is a cyclic along dimension X, illustrated below
+ by the process rank IDs if run with 4 processes
+
+ 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3,
+ 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3,
+ 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3,
+ 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3,
+ 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3,
+ 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3,
+ 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3,
+ 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3,
+ 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3,
+ 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3 ;
+
+
+ ./C/flexible_api.c
+./CXX/flexible_api.cpp
+./F77/flexible_api.f
+./F90/flexible_api.f90
+ This example shows how to use PnetCDF flexible APIs, ncmpi_put_vara_all()
+ and ncmpi_iput_vara() to write two 2D array variables (one is of 4-byte
+ integer byte and the other float type) in parallel.
+ Local buffers have a ghost cell of length 3 surrounded along each
+ dimension.
+
+
+ ./C/get_info.c
+./CXX/get_info.cpp
+./F77/get_info.f
+./F90/get_info.f90
+ These two example programs print the PnetCDF and MPI-IO hints to the
+ standard output.
+
+
+ ./C/hints.c
+./CXX/hints.cpp
+./F77/hints.f
+./F90/hints.f90
+ This example sets two PnetCDF hints:
+ nc_header_align_size and
+ nc_var_align_size
+ and prints the hint values, the header size, header extent, and
+ variables' starting file offsets.
+
+
+./C/mput.c
+ This example shows how to use a single call of ncmpi_mput_vara_all() to
+ write a sequence of requests with arbitrary array indices and lengths.
+ It is intended to run on 4 processes. If more processes were allocated,
+ the extra processes write zero-length requests. The offsets and lengths
+ are just some random numbers to make the output look like:
+
+ 3, 3, 3, 1, 1, 0, 0, 2, 1, 1,
+ 0, 2, 2, 2, 3, 1, 1, 2, 2, 2,
+ 1, 1, 2, 3, 3, 3, 0, 0, 1, 1,
+ 0, 0, 0, 2, 1, 1, 1, 3, 3, 3 ;
+
+
+
+ ./C/nonblocking_write.c
+./CXX/nonblocking_write.cpp
+./F77/nonblocking_write.f
+./F90/nonblocking_write.f90
+ This example is almost the same as to collective_write.c but using
+ nonblocking APIs instead.
+
+
+ ./C/put_vara.c
+./CXX/put_vara.cpp
+./F77/put_vara.f
+./F90/put_var.f90
+ This example shows how to use nfmpi_put_vara_int_all() to write a 2D
+ 4-byte integer array in parallel. The data partitioning pattern among
+ processes is a *-block in Fortran order. It is described by the process
+ rank IDs as below if run on 4 processes.
+
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1,
+ 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2,
+ 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3 ;
+
+
+ ./C/put_varn_float.c
+./CXX/put_varn_float.cpp
+./F77/put_varn_real.f
+./F90/put_varn_real.f90
+ This example makes a single call of ncmpi_put_varn_float_all() to write a
+ sequence of one-element requests with arbitrary array indices. All
+ subrequest indices, starts[], are within the boundaries of a single
+ variable. See comments at the beginning of the source file for compile,
+ run instructions, and example output.
+
+
+ ./C/put_varn_int.c
+./CXX/put_varn_int.cpp
+./F77/put_varn_int.f
+./F90/put_varn_int.f90
+ This example makes a single call of ncmpi_put_varn_int_all() to write a
+ sequence of requests with arbitrary array indices and lengths. All
+ subrequests (starts[] and counts[]) are within the boundaries of a single
+ variable. See comments at the beginning of the source file for compile,
+ run instructions, and example output.
+
+
+./C/create_open.c
+ This example shows how to use to create a new file, close it, and
+ open the file for read only.
+
+
+./C/global_attributes.c
+ This example creates a new file and add 2 global attributes, one is of text
+ type and the other 10 short integers. The file is closed and re-opened to
+ read back the attributes.
+
+ ./C/get_vara.c
+./CXX/get_vara.cpp
+ This example is the read counterpart of example put_vara.c. It shows how to
+ use ncmpi_get_vara_int_all() to read a 2D 4-byte integer array in parallel.
+ It also reads a global attribute and two attribute of variable named "var".
+ The data partitioning pattern is a column-wise partitioning across all
+ processes.
+
+ ./C/transpose.c
+./CXX/transpose.cpp
+./F77/transpose.f
+./F90/transpose.f90
+ This example writes dimensional-transposed 3D arrays using varm APIs.
+
+ For example, when Z=4, Y=6, and X=8, an array partitioned among 4 processes
+ (P0,P1,P2,P3) and organized in dimension ZYX are illustrated below:
+ P0: var[Z=0][*][*]= 0, 1, 2, 3, P1: var[Z=0][*][*]= 4, 5, 6, 7,
+ 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22, 23,
+ 24, 25, 26, 27, 28, 29, 30, 31,
+ 32, 33, 34, 35, 36, 37, 38, 39,
+ 40, 41, 42, 43, 44, 45, 46, 47,
+
+ P2: var[Z=0][*][*]= 48, 49, 50, 51, P3: var[Z=0][*][*]= 52, 53, 54, 55,
+ 56, 57, 58, 59, 60, 61, 62, 63,
+ 64, 65, 66, 67, 68, 69, 70, 71,
+ 72, 73, 74, 75, 76, 77, 78, 79,
+ 80, 81, 82, 83, 84, 85, 86, 87,
+ 88, 89, 90, 91, 92, 93, 94, 95,
+
+ P0: var[Z=1][*][*]= 96, 97, 98, 99, P1: var[Z=1][*][*]=100, 101, 102, 103,
+ 104, 105, 106, 107, 108, 109, 110, 111,
+ 112, 113, 114, 115, 116, 117, 118, 119,
+ 120, 121, 122, 123, 124, 125, 126, 127,
+ 128, 129, 130, 131, 132, 133, 134, 135,
+ 136, 137, 138, 139, 140, 141, 142, 143,
+
+ P2: var[Z=1][*][*]=144, 145, 146, 147, P3: var[Z=1][*][*]=148, 149, 150, 151,
+ 152, 153, 154, 155, 156, 157, 158, 159,
+ 160, 161, 162, 163, 164, 165, 166, 167,
+ 168, 169, 170, 171, 172, 173, 174, 175,
+ 176, 177, 178, 179, 180, 181, 182, 183,
+ 184, 185, 186, 187, 188, 189, 190, 191 ;
+
+ When writing the subarray in parallel to a file, the array contents in file are:
+ var[Z=0][*][*]: 0, 1, 2, 3, 4, 5, 6, 7,
+ 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22, 23,
+ 24, 25, 26, 27, 28, 29, 30, 31,
+ 32, 33, 34, 35, 36, 37, 38, 39,
+ 40, 41, 42, 43, 44, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55,
+ 56, 57, 58, 59, 60, 61, 62, 63,
+ 64, 65, 66, 67, 68, 69, 70, 71,
+ 72, 73, 74, 75, 76, 77, 78, 79,
+ 80, 81, 82, 83, 84, 85, 86, 87,
+ 88, 89, 90, 91, 92, 93, 94, 95,
+
+ var[Z=1][*][*]: 96, 97, 98, 99, 100, 101, 102, 103,
+ 104, 105, 106, 107, 108, 109, 110, 111,
+ 112, 113, 114, 115, 116, 117, 118, 119,
+ 120, 121, 122, 123, 124, 125, 126, 127,
+ 128, 129, 130, 131, 132, 133, 134, 135,
+ 136, 137, 138, 139, 140, 141, 142, 143,
+ 144, 145, 146, 147, 148, 149, 150, 151,
+ 152, 153, 154, 155, 156, 157, 158, 159,
+ 160, 161, 162, 163, 164, 165, 166, 167,
+ 168, 169, 170, 171, 172, 173, 174, 175,
+ 176, 177, 178, 179, 180, 181, 182, 183,
+ 184, 185, 186, 187, 188, 189, 190, 191 ;
+
+ When writing the transposed subarray (XYZ) in parallel to a file, the file contents are:
+ var[Z=0][*][*]= 0, 48, 96, 144, var[Z=1][*][*]= 1, 49, 97, 145,
+ 8, 56, 104, 152, 9, 57, 105, 153,
+ 16, 64, 112, 160, 17, 65, 113, 161,
+ 24, 72, 120, 168, 25, 73, 121, 169,
+ 32, 80, 128, 176, 33, 81, 129, 177,
+ 40, 88, 136, 184, 41, 89, 137, 185,
+
+ var[Z=2][*][*]= 2, 50, 98, 146, var[Z=3][*][*]= 3, 51, 99, 147,
+ 10, 58, 106, 154, 11, 59, 107, 155,
+ 18, 66, 114, 162, 19, 67, 115, 163,
+ 26, 74, 122, 170, 27, 75, 123, 171,
+ 34, 82, 130, 178, 35, 83, 131, 179,
+ 42, 90, 138, 186, 43, 91, 139, 187,
+
+ var[Z=4][*][*]= 4, 52, 100, 148, var[Z=5][*][*]= 5, 53, 101, 149,
+ 12, 60, 108, 156, 13, 61, 109, 157,
+ 20, 68, 116, 164, 21, 69, 117, 165,
+ 28, 76, 124, 172, 29, 77, 125, 173,
+ 36, 84, 132, 180, 37, 85, 133, 181,
+ 44, 92, 140, 188, 45, 93, 141, 189,
+
+ var[Z=6][*][*]= 6, 54, 102, 150, var[Z=7][*][*]= 7, 55, 103, 151,
+ 14, 62, 110, 158, 15, 63, 111, 159,
+ 22, 70, 118, 166, 23, 71, 119, 167,
+ 30, 78, 126, 174, 31, 79, 127, 175,
+ 38, 86, 134, 182, 39, 87, 135, 183,
+ 46, 94, 142, 190, 47, 95, 143, 191 ;
+
+
+ ./C/vard_int.c
+./CXX/vard_int.cpp
+./F77/vard_int.f
+./F90/vard_int.f90
+ These examples show how to use vard APIs to write/read record and fixed-size
+ variables.
+
+ ./C/bput_varn_uint.c
+./F77/bput_varn_int8.f
+ These examples show how to use nonblocking bput_varn APIs
+
+ ./C/i_varn_int64.c
+./F77/i_varn_real.f
+ These examples show how to use nonblocking iput_varn and iget_varn APIs
+
+ ./C/fill_mode.c
+./CXX/fill_mode.cpp
+./F77/fill_mode.f
+./F90/fill_mode.f90
+ These examples show how to enable file mode
+
+ ./C/req_all.c
+ This example show how to use NC_REQ_ALL to flush all pending nonblocking
+ requests without providing the request IDs and status array.
+
+ ./C/nonblocking_write_in_def.c
+ This example is the same as nonblocking_write.c except all nonblocking
+ write requests (calls to iput and bput) are posted in define mode. After
+ entering to data mode, a single call to ncmpi_wait_all() to flush all pending
+ nonblocking requests.
+
diff --git a/examples/tutorial/Makefile.in b/examples/tutorial/Makefile.in
new file mode 100644
index 0000000..a0947d6
--- /dev/null
+++ b/examples/tutorial/Makefile.in
@@ -0,0 +1,114 @@
+#
+# Copyright (C) 2012, Northwestern University and Argonne National Laboratory
+# See COPYRIGHT notice in top-level directory.
+#
+# $Id: Makefile.in 2237 2015-12-18 07:11:47Z wkliao $
+#
+# @configure_input@
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+include ../../macros.make
+
+# note the order of -L list matters
+INCLUDES = -I../../src/lib
+FPPFLAGS += -I../../src/libf @FC_MODINC at ../../src/libf90
+LDFLAGS := -L../../src/lib $(LDFLAGS)
+FLDFLAGS += $(LDFLAGS)
+F90LDFLAGS += $(LDFLAGS)
+LIBS := -lpnetcdf $(LIBS)
+
+C_SRCS = pnetcdf-write-from-master.c \
+ pnetcdf-read-from-master.c \
+ pnetcdf-write-nfiles.c \
+ pnetcdf-read-nfiles.c \
+ pnetcdf-write-standard.c \
+ pnetcdf-read-standard.c \
+ pnetcdf-write-flexible.c \
+ pnetcdf-read-flexible.c \
+ pnetcdf-write-nb.c \
+ pnetcdf-read-nb.c \
+ pnetcdf-write-buffered.c \
+ pnetcdf-permute.c
+
+F77_SRCS = pnetcdf-write-bufferedf77.f
+
+F90_SRCS = pnetcdf-write-bufferedf.f90
+
+PROGS = $(C_SRCS:.c=)
+OBJS = $(C_SRCS:.c=.o)
+ifeq (@has_fortran@, yes)
+PROGS += $(F77_SRCS:.f=)
+OBJS += $(F77_SRCS:.f=.o)
+PROGS += $(F90_SRCS:.f90=)
+OBJS += $(F90_SRCS:.f90=.o)
+endif
+
+GARBAGE = $(PROGS) *.nc
+PACKING_LIST = $(C_SRCS) $(F77_SRCS) $(F90_SRCS) Makefile.in depend
+
+all: $(PROGS)
+
+pnetcdf-write-from-master: pnetcdf-write-from-master.o $(LIBRARY)
+ $(LINK.c) $< $(LDFLAGS) $(LIBS)
+
+pnetcdf-read-from-master: pnetcdf-read-from-master.o $(LIBRARY)
+ $(LINK.c) $< $(LDFLAGS) $(LIBS)
+
+pnetcdf-write-nfiles: pnetcdf-write-nfiles.o $(LIBRARY)
+ $(LINK.c) $< $(LDFLAGS) $(LIBS)
+
+pnetcdf-read-nfiles: pnetcdf-read-nfiles.o $(LIBRARY)
+ $(LINK.c) $< $(LDFLAGS) $(LIBS)
+
+pnetcdf-write-standard: pnetcdf-write-standard.o $(LIBRARY)
+ $(LINK.c) $< $(LDFLAGS) $(LIBS)
+
+pnetcdf-read-standard: pnetcdf-read-standard.o $(LIBRARY)
+ $(LINK.c) $< $(LDFLAGS) $(LIBS)
+
+pnetcdf-write-flexible: pnetcdf-write-flexible.o $(LIBRARY)
+ $(LINK.c) $< $(LDFLAGS) $(LIBS)
+
+pnetcdf-read-flexible: pnetcdf-read-flexible.o $(LIBRARY)
+ $(LINK.c) $< $(LDFLAGS) $(LIBS)
+
+pnetcdf-write-nb: pnetcdf-write-nb.o $(LIBRARY)
+ $(LINK.c) $< $(LDFLAGS) $(LIBS)
+
+pnetcdf-read-nb: pnetcdf-read-nb.o $(LIBRARY)
+ $(LINK.c) $< $(LDFLAGS) $(LIBS)
+
+pnetcdf-write-buffered: pnetcdf-write-buffered.o $(LIBRARY)
+ $(LINK.c) $< $(LDFLAGS) $(LIBS)
+
+pnetcdf-write-bufferedf: pnetcdf-write-bufferedf.o $(LIBRARY)
+ $(LINK.F90) $< $(F90LDFLAGS) $(LIBS)
+
+pnetcdf-write-bufferedf77: pnetcdf-write-bufferedf77.o $(LIBRARY)
+ $(LINK.F77) $< $(FLDFLAGS) $(LIBS)
+
+pnetcdf-permute: pnetcdf-permute.o $(LIBRARY)
+ $(LINK.c) $< $(LDFLAGS) $(LIBS)
+
+TEST_MPIRUN_4 = $(subst NP,4,$(TEST_MPIRUN))
+
+ptest4: $(PROGS)
+ @for i in $(PROGS); do ( \
+ $(TEST_MPIRUN_4) ./$$i $(TEST_OUTDIR)/testfile.nc ; \
+ if [ $$? = 0 ] ; then \
+ echo "PASS: parallel run on 4 processes --------------- $$i"; \
+ else \
+ echo "FAILED: parallel run on 4 processes ------------- $$i"; \
+ fi ; ) ; done
+
+ptest: ptest4
+ptests: ptest4
+ptest2 ptest3 ptest6 ptest8 ptest10:
+
+include $(srcdir)/depend
+include $(srcdir)/../../rules.make
+
+$(LIBRARY): ;
+
diff --git a/examples/tutorial/depend b/examples/tutorial/depend
new file mode 100644
index 0000000..609c3bf
--- /dev/null
+++ b/examples/tutorial/depend
@@ -0,0 +1,14 @@
+pnetcdf-permute.o: pnetcdf-permute.c
+pnetcdf-read-flexible.o: pnetcdf-read-flexible.c
+pnetcdf-read-from-master.o: pnetcdf-read-from-master.c
+pnetcdf-read-nb.o: pnetcdf-read-nb.c
+pnetcdf-read-nfiles.o: pnetcdf-read-nfiles.c
+pnetcdf-read-standard.o: pnetcdf-read-standard.c
+pnetcdf-write-bufferedf77.o: pnetcdf-write-bufferedf77.f
+pnetcdf-write-bufferedf.o: pnetcdf-write-bufferedf.f90
+pnetcdf-write-buffered.o: pnetcdf-write-buffered.c
+pnetcdf-write-flexible.o: pnetcdf-write-flexible.c
+pnetcdf-write-from-master.o: pnetcdf-write-from-master.c
+pnetcdf-write-nb.o: pnetcdf-write-nb.c
+pnetcdf-write-nfiles.o: pnetcdf-write-nfiles.c
+pnetcdf-write-standard.o: pnetcdf-write-standard.c
diff --git a/examples/tutorial/pnetcdf-permute.c b/examples/tutorial/pnetcdf-permute.c
new file mode 100644
index 0000000..98d3cc5
--- /dev/null
+++ b/examples/tutorial/pnetcdf-permute.c
@@ -0,0 +1,158 @@
+/*********************************************************************
+ *
+ * Copyright (C) 2012, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ *
+ *********************************************************************/
+/* $Id: pnetcdf-permute.c 2245 2015-12-20 18:39:52Z wkliao $ */
+
+/* simple demonstration of pnetcdf
+ * knowing nothing about the file, read in the variables.
+ *
+ * This example demonstrates the flexible interface, using the MPI derived
+ * datatype to transpose the matrix.
+ *
+ * Note this program demonstrates transposition for one process only
+ */
+
+#include <stdlib.h>
+#include <mpi.h>
+#include <pnetcdf.h>
+#include <stdio.h>
+
+#include <assert.h>
+
+static void handle_error(int status, int lineno)
+{
+ fprintf(stderr, "Error at line %d: %s\n", lineno, ncmpi_strerror(status));
+ MPI_Abort(MPI_COMM_WORLD, 1);
+}
+
+int main(int argc, char **argv) {
+
+#define NDIMS 3
+ int i, j, k, rank, nprocs, ret;
+ int ncfile, ndims=NDIMS;
+ MPI_Offset dim_sizes[NDIMS];
+ MPI_Offset start[NDIMS], count[NDIMS], nitems;
+ int dimids[NDIMS], transposed_dims[NDIMS];
+ int varid1, transposed_varid, flexible_varid;
+ double *data, *transposed_data;
+ MPI_Datatype transposed_type, one_d, two_d;
+
+ MPI_Init(&argc, &argv);
+
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+
+ if (argc != 2) {
+ if (rank == 0) printf("Usage: %s filename\n", argv[0]);
+ MPI_Finalize();
+ exit(-1);
+ }
+
+ ret = ncmpi_create(MPI_COMM_WORLD, argv[1],
+ NC_CLOBBER|NC_64BIT_OFFSET, MPI_INFO_NULL, &ncfile);
+ if (ret != NC_NOERR) handle_error(ret, __LINE__);
+
+ dim_sizes[0] = 4;
+ dim_sizes[1] = 5;
+ dim_sizes[2] = 6;
+
+ ret = ncmpi_def_dim(ncfile, "x", dim_sizes[0], &(dimids[0]));
+ if (ret != NC_NOERR) handle_error(ret, __LINE__);
+
+ ret = ncmpi_def_dim(ncfile, "y", dim_sizes[1], &(dimids[1]));
+ if (ret != NC_NOERR) handle_error(ret, __LINE__);
+
+ ret = ncmpi_def_dim(ncfile, "z", dim_sizes[2], &(dimids[2]));
+ if (ret != NC_NOERR) handle_error(ret, __LINE__);
+
+ ret = ncmpi_def_var(ncfile, "v1", NC_INT, ndims, dimids, &varid1);
+ if (ret != NC_NOERR) handle_error(ret, __LINE__);
+
+ /* moab wants to permute {i,j,k} to {j,k,i} */
+ transposed_dims[0] = dimids[1];
+ transposed_dims[1] = dimids[2];
+ transposed_dims[2] = dimids[0];
+ ret = ncmpi_def_var(ncfile, "transposed-v1", NC_INT, ndims, transposed_dims,
+ &transposed_varid);
+ if (ret != NC_NOERR) handle_error(ret, __LINE__);
+
+ /* want this to end up looking like transposed-v1 */
+ ret = ncmpi_def_var(ncfile, "flexible-v1", NC_INT, ndims, transposed_dims,
+ &flexible_varid);
+ if (ret != NC_NOERR) handle_error(ret, __LINE__);
+
+ ret = ncmpi_enddef(ncfile);
+ if (ret != NC_NOERR) handle_error(ret, __LINE__);
+
+ nitems = dim_sizes[0]*dim_sizes[1]*dim_sizes[2];
+ data = (double*) calloc(nitems, sizeof(double));
+ transposed_data = (double*) calloc(nitems, sizeof(double));
+
+ for (i=0; i<dim_sizes[0]; i++) {
+ for (j=0; j<dim_sizes[1]; j++) {
+ for (k=0; k<dim_sizes[2]; k++) {
+ /* data in x,y,z order */
+ data[i*dim_sizes[1]*dim_sizes[2] + j*dim_sizes[2] + k] =
+ 100*i*dim_sizes[1]*dim_sizes[2] + 10*j*dim_sizes[2] + k;
+ /* permute the array data[X][Y][Z] to transpose[Y][Z][X] */
+ assert((j*dim_sizes[2]*dim_sizes[0] + k*dim_sizes[0] + i) < nitems);
+ transposed_data[j*dim_sizes[2]*dim_sizes[0] + k*dim_sizes[0] + i] =
+ 100*i*dim_sizes[1]*dim_sizes[2] + 10*j*dim_sizes[2] + k;
+ }
+ }
+ }
+
+ /* initial array written in i,j,k order */
+
+ start[0] = start[1] = start[2] = 0;
+ count[0] = dim_sizes[0];
+ count[1] = dim_sizes[1];
+ count[2] = dim_sizes[2];
+ if (rank > 0) nitems = count[0] = count[1] = count[2] = 0;
+ ret = ncmpi_put_vara_all(ncfile, varid1, start, count, data, nitems, MPI_DOUBLE);
+ if (ret != NC_NOERR) handle_error(ret, __LINE__);
+
+ count[0] = dim_sizes[1];
+ count[1] = dim_sizes[2];
+ count[2] = dim_sizes[0];
+ if (rank > 0) nitems = count[0] = count[1] = count[2] = 0;
+ ret = ncmpi_put_vara_all(ncfile, transposed_varid, start, count,
+ transposed_data, nitems, MPI_DOUBLE);
+ if (ret != NC_NOERR) handle_error(ret, __LINE__);
+
+ /* permute ijk (4x5x6) into jki (5x6x4)*/
+ /* new innermost dimension is I items, strided across the old JK face*/
+ MPI_Type_vector(dim_sizes[0], 1, dim_sizes[1]*dim_sizes[2], MPI_DOUBLE, &one_d);
+ /* new middle dimension is K items, strided over the K row, which isn't
+ * actually a stride in this case. We use hvector here because we
+ * operate directly in terms of array items */
+ MPI_Type_create_hvector(dim_sizes[2], 1, sizeof(double), one_d, &two_d);
+ /* new outermost dimension is J items, strided over the old J row */
+ MPI_Type_create_hvector(dim_sizes[1], 1, dim_sizes[2]*sizeof(double), two_d, &transposed_type);
+
+ MPI_Type_commit(&transposed_type);
+ MPI_Type_free(&one_d);
+ MPI_Type_free(&two_d);
+
+ nitems = 1;
+ if (rank > 0) nitems = 0;
+ ret = ncmpi_put_vara_all(ncfile, flexible_varid, start, count,
+ data, nitems, transposed_type);
+
+ MPI_Type_free(&transposed_type);
+
+ ret = ncmpi_close(ncfile);
+ if (ret != NC_NOERR) handle_error(ret, __LINE__);
+
+ free(data);
+ free(transposed_data);
+
+ MPI_Finalize();
+ return 0;
+}
+
+/*
+ *vim: ts=8 sts=4 sw=4 noexpandtab */
diff --git a/examples/tutorial/pnetcdf-read-flexible.c b/examples/tutorial/pnetcdf-read-flexible.c
new file mode 100644
index 0000000..7a34695
--- /dev/null
+++ b/examples/tutorial/pnetcdf-read-flexible.c
@@ -0,0 +1,127 @@
+/*********************************************************************
+ *
+ * Copyright (C) 2012, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ *
+ *********************************************************************/
+/* $Id: pnetcdf-read-flexible.c 2245 2015-12-20 18:39:52Z wkliao $ */
+
+/* simple demonstration of pnetcdf
+ * knowing nothing about the file, read in the variables.
+ *
+ * This example demonstrates the flexible interface */
+
+#include <stdlib.h>
+#include <mpi.h>
+#include <pnetcdf.h>
+#include <stdio.h>
+
+static void handle_error(int status, int lineno)
+{
+ fprintf(stderr, "Error at line %d: %s\n", lineno, ncmpi_strerror(status));
+ MPI_Abort(MPI_COMM_WORLD, 1);
+}
+
+int main(int argc, char **argv) {
+
+ int i, j, rank, nprocs, ret;
+ int ncfile, ndims, nvars, ngatts, unlimited;
+ int var_ndims, var_natts;;
+ MPI_Offset *dim_sizes, var_size;
+ MPI_Offset *start, *count;
+ char varname[NC_MAX_NAME+1];
+ int dimids[NC_MAX_VAR_DIMS];
+ nc_type type;
+ int *data=NULL;
+
+ MPI_Init(&argc, &argv);
+
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+
+ if (argc != 2) {
+ if (rank == 0) printf("Usage: %s filename\n", argv[0]);
+ MPI_Finalize();
+ exit(-1);
+ }
+
+ ret = ncmpi_open(MPI_COMM_WORLD, argv[1], NC_NOWRITE, MPI_INFO_NULL,
+ &ncfile);
+ if (ret != NC_NOERR) handle_error(ret, __LINE__);
+
+ /* reader knows nothing about dataset, but we can interrogate with query
+ * routines: ncmpi_inq tells us how many of each kind of "thing"
+ * (dimension, variable, attribute) we will find in the file */
+
+ /* no communication needed after ncmpi_open: all processors have a cached
+ * view of the metadata once ncmpi_open returns */
+
+ ret = ncmpi_inq(ncfile, &ndims, &nvars, &ngatts, &unlimited);
+ if (ret != NC_NOERR) handle_error(ret, __LINE__);
+
+ /* we do not really need the name of the dimension or the variable for
+ * reading in this example. we could, in a different example, take the
+ * name of a variable on the command line and read just that one */
+
+ dim_sizes = (MPI_Offset*) calloc(ndims, sizeof(MPI_Offset));
+ /* netcdf dimension identifiers are allocated sequentially starting
+ * at zero; same for variable identifiers */
+ for(i=0; i<ndims; i++) {
+ ret = ncmpi_inq_dimlen(ncfile, i, &(dim_sizes[i]) );
+ if (ret != NC_NOERR) handle_error(ret, __LINE__);
+ }
+
+ for(i=0; i<nvars; i++) {
+ /* much less coordination in this case compared to rank 0 doing all
+ * the i/o: everyone already has the necessary information */
+ ret = ncmpi_inq_var(ncfile, i, varname, &type, &var_ndims, dimids,
+ &var_natts);
+ if (ret != NC_NOERR) handle_error(ret, __LINE__);
+
+ start = (MPI_Offset*) calloc(var_ndims, sizeof(MPI_Offset));
+ count = (MPI_Offset*) calloc(var_ndims, sizeof(MPI_Offset));
+
+ /* we will simply decompose along one dimension. Generally the
+ * application has some algorithm for domain decomposition. Note
+ * that data decomposition can have an impact on i/o performance.
+ * Often it's best just to do what is natural for the application,
+ * but something to consider if performance is not what was
+ * expected/desired */
+
+ start[0] = (dim_sizes[dimids[0]]/nprocs)*rank;
+ count[0] = (dim_sizes[dimids[0]]/nprocs);
+ var_size = count[0];
+
+ for (j=1; j<var_ndims; j++) {
+ start[j] = 0;
+ count[j] = dim_sizes[dimids[j]];
+ var_size *= count[j];
+ }
+
+ switch(type) {
+ case NC_INT:
+ data = (int*) calloc(var_size, sizeof(int));
+ ret = ncmpi_get_vara_all(ncfile, i, start, count, data,
+ var_size, MPI_INT);
+ if (ret != NC_NOERR) handle_error(ret, __LINE__);
+ break;
+ default:
+ /* we can do this for all the known netcdf types but this
+ * example is already getting too long */
+ fprintf(stderr, "unsupported NetCDF type \n");
+ }
+
+ free(start);
+ free(count);
+ if (data != NULL) free(data);
+ }
+
+ ret = ncmpi_close(ncfile);
+ if (ret != NC_NOERR) handle_error(ret, __LINE__);
+
+ MPI_Finalize();
+ return 0;
+}
+
+/*
+ *vim: ts=8 sts=4 sw=4 noexpandtab */
diff --git a/examples/tutorial/pnetcdf-read-from-master.c b/examples/tutorial/pnetcdf-read-from-master.c
new file mode 100644
index 0000000..397cca6
--- /dev/null
+++ b/examples/tutorial/pnetcdf-read-from-master.c
@@ -0,0 +1,159 @@
+/*********************************************************************
+ *
+ * Copyright (C) 2012, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ *
+ *********************************************************************/
+/* $Id: pnetcdf-read-from-master.c 1723 2014-07-06 05:41:41Z wkliao $ */
+
+/* simple demonstration of pnetcdf
+ * text attribute on dataset
+ * rank 0 reads into 1-d array, broadcasts to all. This is a dumb way
+ * to do parallel I/O, but folks do this sometimes... */
+
+/* This program reads a file created by pnetcdf-write-from-master.c, say file
+ named output.nc with the following contents, shown by running ncmpidump command .
+
+ % mpiexec -n 4 pnetcdf-read-from-master /orangefs/wkliao/output.nc
+
+ % ncmpidump /orangefs/wkliao/output.nc
+ netcdf output {
+ // file format: CDF-2 (large file)
+ dimensions:
+ d1 = 4 ;
+ variables:
+ int v1(d1) ;
+ int v2(d1) ;
+
+ // global attributes:
+ :string = "Hello World\n",
+ "" ;
+ data:
+
+ v1 = 0, 1, 2, 3 ;
+
+ v2 = 0, 1, 2, 3 ;
+ }
+*/
+
+#include <stdlib.h>
+#include <mpi.h>
+#include <pnetcdf.h>
+#include <stdio.h>
+
+static void handle_error(int status, int lineno)
+{
+ fprintf(stderr, "Error at line %d: %s\n", lineno, ncmpi_strerror(status));
+ MPI_Abort(MPI_COMM_WORLD, 1);
+}
+
+
+int main(int argc, char **argv) {
+
+ int i, j=0, rank, nprocs, ret;
+ int ncfile, ndims, nvars, ngatts, unlimited, var_ndims, var_natts;;
+ int dimids[NC_MAX_VAR_DIMS];
+ char varname[NC_MAX_NAME+1];
+ MPI_Offset *dim_sizes=NULL, var_size;
+ nc_type type;
+ int *data=NULL;
+
+ MPI_Init(&argc, &argv);
+
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+
+ if (argc != 2) {
+ if (rank == 0) printf("Usage: %s filename\n", argv[0]);
+ MPI_Finalize();
+ exit(-1);
+ }
+
+ if (rank == 0) {
+ ret = ncmpi_open(MPI_COMM_SELF, argv[1],
+ NC_NOWRITE, MPI_INFO_NULL, &ncfile);
+ if (ret != NC_NOERR) handle_error(ret, __LINE__);
+
+ /* reader knows nothing about dataset, but we can interrogate with
+ * query routines: ncmpi_inq tells us how many of each kind of
+ * "thing" (dimension, variable, attribute) we will find in the
+ * file */
+
+ ret = ncmpi_inq(ncfile, &ndims, &nvars, &ngatts, &unlimited);
+ if (ret != NC_NOERR) handle_error(ret, __LINE__);
+
+ /* we do not really need the name of the dimension or the variable
+ * for reading in this example. we could, in a different example,
+ * take the name of a variable on the command line and read just
+ * that one */
+
+ dim_sizes = (MPI_Offset*) calloc(ndims, sizeof(MPI_Offset));
+ /* netcdf dimension identifiers are allocated sequentially starting
+ * at zero; same for variable identifiers */
+ for(i=0; i<ndims; i++) {
+ ret = ncmpi_inq_dimlen(ncfile, i, &(dim_sizes[i]) );
+ if (ret != NC_NOERR) handle_error(ret, __LINE__);
+ }
+ }
+
+ /* need to inform other MPI processors how many variables we will send */
+ MPI_Bcast(&nvars, 1, MPI_INT, 0, MPI_COMM_WORLD);
+
+ for(i=0; i<nvars; i++) {
+ /* rank 0 will find out the size of each variable, read it, and
+ * broadcast it to the rest of the processors */
+ if (rank == 0) {
+ ret = ncmpi_inq_var(ncfile, i, varname, &type, &var_ndims, dimids,
+ &var_natts);
+ if (ret != NC_NOERR) handle_error(ret, __LINE__);
+
+ for (j=0, var_size=1; j<var_ndims; j++) {
+ var_size *= dim_sizes[dimids[j]];
+ }
+ }
+ /* oddity: there's no predefined MPI_Offset type */
+ MPI_Bcast(&var_size, 1, MPI_OFFSET, 0, MPI_COMM_WORLD);
+
+ data = (int*) calloc(var_size, sizeof(int));
+
+ if (rank == 0) {
+ switch(type) {
+ case NC_INT:
+ /* now we have the variable identifiers and we know how big
+ * they are */
+
+ /* this approach is not scalable: i/o happens from a single
+ * processor. This approach can be ok if the amount of
+ * data is quite small, but almost always the underlying
+ * MPI-IO library can do a better job */
+
+ ret = ncmpi_get_var_int_all(ncfile, j, data);
+ if (ret != NC_NOERR) handle_error(ret, __LINE__);
+ break;
+ default:
+ /* we can do this for all the known netcdf types but this
+ * example is already getting too long */
+ fprintf(stderr, "unsupported NetCDF type \n");
+ }
+ }
+
+ /*and finally all processors have the data */
+ MPI_Bcast(data, var_size, MPI_INT, 0, MPI_COMM_WORLD);
+
+ /* Here, every process can do computation on the local buffer, data,
+ or copy the contents to somewhere else */
+
+ free(data);
+ }
+
+ if (rank == 0) {
+ ret = ncmpi_close(ncfile);
+ if (ret != NC_NOERR) handle_error(ret, __LINE__);
+ }
+
+ MPI_Finalize();
+ return 0;
+}
+
+/*
+ *vim: ts=8 sts=4 sw=4 noexpandtab */
diff --git a/examples/tutorial/pnetcdf-read-nb.c b/examples/tutorial/pnetcdf-read-nb.c
new file mode 100644
index 0000000..d29d82a
--- /dev/null
+++ b/examples/tutorial/pnetcdf-read-nb.c
@@ -0,0 +1,150 @@
+/*********************************************************************
+ *
+ * Copyright (C) 2012, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ *
+ *********************************************************************/
+/* $Id: pnetcdf-read-nb.c 2245 2015-12-20 18:39:52Z wkliao $ */
+
+/* simple demonstration of pnetcdf:
+ * knowing nothing about the file, read in the variables.
+ *
+ * This example demonstrates the non-blocking read interface */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <mpi.h>
+#include <pnetcdf.h>
+
+static void handle_error(int status, int lineno)
+{
+ fprintf(stderr, "Error at line %d: %s\n", lineno, ncmpi_strerror(status));
+ MPI_Abort(MPI_COMM_WORLD, 1);
+}
+
+int main(int argc, char **argv) {
+
+ int i, j, rank, nprocs, ret;
+ int ncfile, ndims, nvars, ngatts, unlimited, var_ndims, var_natts;;
+ MPI_Offset *dim_sizes, var_size, *start, *count;
+ int *requests, *statuses, dimids[NC_MAX_VAR_DIMS], **data;
+ char varname[NC_MAX_NAME+1];
+ nc_type type;
+
+ MPI_Init(&argc, &argv);
+
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+
+ if (argc != 2) {
+ if (rank == 0) printf("Usage: %s filename\n", argv[0]);
+ MPI_Finalize();
+ exit(-1);
+ }
+
+ ret = ncmpi_open(MPI_COMM_WORLD, argv[1], NC_NOWRITE, MPI_INFO_NULL,
+ &ncfile);
+ if (ret != NC_NOERR) handle_error(ret, __LINE__);
+
+ /* reader knows nothing about dataset, but we can interrogate with query
+ * routines: ncmpi_inq tells us how many of each kind of "thing"
+ * (dimension, variable, attribute) we will find in the file */
+
+ /* no communication needed after ncmpi_open: all processors have a cached
+ * view of the metadata once ncmpi_open returns */
+
+ ret = ncmpi_inq(ncfile, &ndims, &nvars, &ngatts, &unlimited);
+ if (ret != NC_NOERR) handle_error(ret, __LINE__);
+
+ /* we do not really need the name of the dimension or the variable for
+ * reading in this example. we could, in a different example, take the
+ * name of a variable on the command line and read just that one */
+
+ dim_sizes = (MPI_Offset*) calloc(ndims, sizeof(MPI_Offset));
+ /* netcdf dimension identifiers are allocated sequentially starting
+ * at zero; same for variable identifiers */
+ for(i=0; i<ndims; i++) {
+ ret = ncmpi_inq_dimlen(ncfile, i, &(dim_sizes[i]) );
+ if (ret != NC_NOERR) handle_error(ret, __LINE__);
+ }
+
+ requests = (int*) calloc(nvars, sizeof(int));
+ statuses = (int*) calloc(nvars, sizeof(int));
+
+ data = (int**) calloc(nvars, sizeof(int*));
+
+ for(i=0; i<nvars; i++) {
+ /* much less coordination in this case compared to rank 0 doing all
+ * the i/o: everyone already has the necessary information */
+ ret = ncmpi_inq_var(ncfile, i, varname, &type, &var_ndims, dimids,
+ &var_natts);
+ if (ret != NC_NOERR) handle_error(ret, __LINE__);
+
+ start = (MPI_Offset*) calloc(var_ndims, sizeof(MPI_Offset));
+ count = (MPI_Offset*) calloc(var_ndims, sizeof(MPI_Offset));
+
+ /* we will simply decompose along one dimension. Generally the
+ * application has some algorithm for domain decomposition. Note
+ * that data decomposition can have an impact on i/o performance.
+ * Often it's best just to do what is natural for the application,
+ * but something to consider if performance is not what was
+ * expected/desired */
+
+ start[0] = (dim_sizes[dimids[0]]/nprocs)*rank;
+ count[0] = (dim_sizes[dimids[0]]/nprocs);
+ var_size = count[0];
+
+ for (j=1; j<var_ndims; j++) {
+ start[j] = 0;
+ count[j] = dim_sizes[dimids[j]];
+ var_size *= count[j];
+ }
+
+ switch(type) {
+ case NC_INT:
+ data[i] = (int*) calloc(var_size, sizeof(int));
+ /* as with the writes, this call is independent: we
+ * will do any coordination (if desired) in a
+ * subsequent ncmpi_wait_all() call */
+ ret = ncmpi_iget_vara(ncfile, i, start, count, data[i],
+ var_size, MPI_INT, &requests[i]);
+ if (ret != NC_NOERR) handle_error(ret, __LINE__);
+ break;
+ default:
+ /* we can do this for all the known netcdf types but this
+ * example is already getting too long */
+ fprintf(stderr, "unsupported NetCDF type \n");
+ }
+
+ free(start);
+ free(count);
+ }
+
+ ret = ncmpi_wait_all(ncfile, nvars, requests, statuses);
+ if (ret != NC_NOERR) handle_error(ret, __LINE__);
+
+ /* check status of each nonblocking call */
+ for (i=0; i<nvars; i++)
+ if (statuses[i] != NC_NOERR) handle_error(statuses[i], __LINE__);
+
+ /* now that the ncmpi_wait_all has returned, the caller can do stuff with
+ * the buffers passed in to the non-blocking operations. The buffer reuse
+ * rules are similar to MPI non-blocking messages */
+
+ for (i=0; i<nvars; i++) {
+ if (data[i] != NULL) free(data[i]);
+ }
+ free(data);
+ free(dim_sizes);
+ free(requests);
+ free(statuses);
+
+ ret = ncmpi_close(ncfile);
+ if (ret != NC_NOERR) handle_error(ret, __LINE__);
+
+ MPI_Finalize();
+ return 0;
+}
+
+/*
+ *vim: ts=8 sts=4 sw=4 noexpandtab */
diff --git a/examples/tutorial/pnetcdf-read-nfiles.c b/examples/tutorial/pnetcdf-read-nfiles.c
new file mode 100644
index 0000000..5f9442a
--- /dev/null
+++ b/examples/tutorial/pnetcdf-read-nfiles.c
@@ -0,0 +1,137 @@
+/*********************************************************************
+ *
+ * Copyright (C) 2012, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ *
+ *********************************************************************/
+/* $Id: pnetcdf-read-nfiles.c 2245 2015-12-20 18:39:52Z wkliao $ */
+
+/* simple demonstration of pnetcdf
+ * text attribute on dataset
+ * rank 0 reads into 1-d array, broadcasts to all. This is a dumb way
+ * to do parallel I/O but folks do this sometimes...
+ *
+ * This program reads the files generated from its counterpart program
+ * pnetcdf-write-nfiles.c. See comments in pnetcdf-write-nfiles.c for
+ * the contents of the netCDF files.
+ */
+
+#include <stdlib.h>
+#include <mpi.h>
+#include <pnetcdf.h>
+#include <stdio.h>
+
+static void handle_error(int status, int lineno)
+{
+ fprintf(stderr, "Error at line %d: %s\n", lineno, ncmpi_strerror(status));
+ MPI_Abort(MPI_COMM_WORLD, 1);
+}
+
+#define DSET_NAME_LEN 1024
+
+int main(int argc, char **argv) {
+
+ int i, j, rank, nprocs, ret;
+ int ncfile, ndims, nvars, ngatts, unlimited;
+ int var_ndims, var_natts;;
+ MPI_Offset *dim_sizes, var_size;
+ MPI_Offset *count;
+ char filename[DSET_NAME_LEN];
+ char varname[NC_MAX_NAME+1];
+ int dimids[NC_MAX_VAR_DIMS];
+ nc_type type;
+ int *data=NULL;
+
+ MPI_Init(&argc, &argv);
+
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+
+ if (argc != 2) {
+ if (rank == 0) printf("Usage: %s filename\n", argv[0]);
+ MPI_Finalize();
+ exit(-1);
+ }
+
+ /* the most significant challenge with the "one file per processor"
+ * approach is the challenge in reading back on a different number of
+ * processors. For example, 4k processors output data during a simulation.
+ * Later on, 100 processors do analysis or visualization of the data.
+ * Stitching together the many smaller files into a form usable by other
+ * programs poses a challenge */
+
+ ret = snprintf(filename, DSET_NAME_LEN, "%s.%d-%d.nc", argv[1], rank, nprocs);
+ if (ret >= DSET_NAME_LEN) {
+ fprintf(stderr, "name too long \n");
+ exit(-1);
+ }
+ ret = ncmpi_open(MPI_COMM_SELF, filename, NC_NOWRITE, MPI_INFO_NULL, &ncfile);
+ if (ret != NC_NOERR) handle_error(ret, __LINE__);
+
+ /* reader knows nothing about dataset, but we can interrogate with query
+ * routines: ncmpi_inq tells us how many of each kind of "thing"
+ * (dimension, variable, attribute) we will find in the file */
+
+ /* In the "one file per processor case" all processors open a file and
+ * interrogate it */
+
+ ret = ncmpi_inq(ncfile, &ndims, &nvars, &ngatts, &unlimited);
+ if (ret != NC_NOERR) handle_error(ret, __LINE__);
+
+ /* we do not really need the name of the dimension or the variable for
+ * reading in this example. we could, in a different example, take the
+ * name of a variable on the command line and read just that one */
+
+ dim_sizes = (MPI_Offset*) calloc(ndims, sizeof(MPI_Offset));
+ /* netcdf dimension identifiers are allocated sequentially starting
+ * at zero; same for variable identifiers */
+ for (i=0; i<ndims; i++) {
+ ret = ncmpi_inq_dimlen(ncfile, i, &(dim_sizes[i]) );
+ if (ret != NC_NOERR) handle_error(ret, __LINE__);
+ }
+
+ for (i=0; i<nvars; i++) {
+ /* much less coordination in this case compared to rank 0 doing all
+ * the i/o: everyone already has the necessary information */
+ ret = ncmpi_inq_var(ncfile, i, varname, &type, &var_ndims, dimids,
+ &var_natts);
+ if (ret != NC_NOERR) handle_error(ret, __LINE__);
+
+ count = (MPI_Offset*) calloc(var_ndims, sizeof(MPI_Offset));
+
+ /* as long as the number of readers is identical to the number of
+ * writers, we can simply read entire variables back */
+
+ count[0] = dim_sizes[dimids[0]];
+
+ var_size = count[0];
+ for (j=1; j<var_ndims; j++) {
+ count[j] = dim_sizes[dimids[j]];
+ var_size *= count[j];
+ }
+
+ switch(type) {
+ case NC_INT:
+ data = (int*) calloc(var_size, sizeof(int));
+ ret = ncmpi_get_var_int_all(ncfile, i, data);
+ if (ret != NC_NOERR) handle_error(ret, __LINE__);
+ break;
+ default:
+ /* we can do this for all the known netcdf types but this
+ * example is already getting too long */
+ fprintf(stderr, "unsupported NetCDF type \n");
+ }
+
+ free(count);
+ if (data != NULL) free(data);
+ }
+
+ ret = ncmpi_close(ncfile);
+ if (ret != NC_NOERR) handle_error(ret, __LINE__);
+
+ MPI_Finalize();
+ return 0;
+}
+
+/*
+ *vim: ts=8 sts=4 sw=4 noexpandtab */
diff --git a/examples/tutorial/pnetcdf-read-standard.c b/examples/tutorial/pnetcdf-read-standard.c
new file mode 100644
index 0000000..952ddab
--- /dev/null
+++ b/examples/tutorial/pnetcdf-read-standard.c
@@ -0,0 +1,126 @@
+/*********************************************************************
+ *
+ * Copyright (C) 2012, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ *
+ *********************************************************************/
+/* $Id: pnetcdf-read-standard.c 2245 2015-12-20 18:39:52Z wkliao $ */
+
+/* simple demonstration of pnetcdf:
+ * knowing nothing about the file, read in the variables.
+ *
+ * This example demonstrates the standard read interface */
+
+#include <stdlib.h>
+#include <mpi.h>
+#include <pnetcdf.h>
+#include <stdio.h>
+
+static void handle_error(int status, int lineno)
+{
+ fprintf(stderr, "Error at line %d: %s\n", lineno, ncmpi_strerror(status));
+ MPI_Abort(MPI_COMM_WORLD, 1);
+}
+
+int main(int argc, char **argv) {
+
+ int i, j, rank, nprocs, ret;
+ int ncfile, ndims, nvars, ngatts, unlimited;
+ int var_ndims, var_natts;;
+ MPI_Offset *dim_sizes, var_size;
+ MPI_Offset *start, *count;
+ char varname[NC_MAX_NAME+1];
+ int dimids[NC_MAX_VAR_DIMS];
+ nc_type type;
+ int *data=NULL;
+
+ MPI_Init(&argc, &argv);
+
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+
+ if (argc != 2) {
+ if (rank == 0) printf("Usage: %s filename\n", argv[0]);
+ MPI_Finalize();
+ exit(-1);
+ }
+
+ ret = ncmpi_open(MPI_COMM_WORLD, argv[1], NC_NOWRITE, MPI_INFO_NULL,
+ &ncfile);
+ if (ret != NC_NOERR) handle_error(ret, __LINE__);
+
+ /* reader knows nothing about dataset, but we can interrogate with query
+ * routines: ncmpi_inq tells us how many of each kind of "thing"
+ * (dimension, variable, attribute) we will find in the file */
+
+ /* no communication needed after ncmpi_open: all processors have a cached
+ * view of the metadata once ncmpi_open returns */
+
+ ret = ncmpi_inq(ncfile, &ndims, &nvars, &ngatts, &unlimited);
+ if (ret != NC_NOERR) handle_error(ret, __LINE__);
+
+ /* we do not really need the name of the dimension or the variable for
+ * reading in this example. we could, in a different example, take the
+ * name of a variable on the command line and read just that one */
+
+ dim_sizes = (MPI_Offset*) calloc(ndims, sizeof(MPI_Offset));
+ /* netcdf dimension identifiers are allocated sequentially starting
+ * at zero; same for variable identifiers */
+ for(i=0; i<ndims; i++) {
+ ret = ncmpi_inq_dimlen(ncfile, i, &(dim_sizes[i]) );
+ if (ret != NC_NOERR) handle_error(ret, __LINE__);
+ }
+
+ for(i=0; i<nvars; i++) {
+ /* much less coordination in this case compared to rank 0 doing all
+ * the i/o: everyone already has the necessary information */
+ ret = ncmpi_inq_var(ncfile, i, varname, &type, &var_ndims, dimids,
+ &var_natts);
+ if (ret != NC_NOERR) handle_error(ret, __LINE__);
+
+ start = (MPI_Offset*) calloc(var_ndims, sizeof(MPI_Offset));
+ count = (MPI_Offset*) calloc(var_ndims, sizeof(MPI_Offset));
+
+ /* we will simply decompose along one dimension. Generally the
+ * application has some algorithm for domain decomposition. Note
+ * that data decomposition can have an impact on i/o performance.
+ * Often it's best just to do what is natural for the application,
+ * but something to consider if performance is not what was
+ * expected/desired */
+
+ start[0] = (dim_sizes[dimids[0]]/nprocs)*rank;
+ count[0] = (dim_sizes[dimids[0]]/nprocs);
+ var_size = count[0];
+
+ for (j=1; j<var_ndims; j++) {
+ start[j] = 0;
+ count[j] = dim_sizes[dimids[j]];
+ var_size *= count[j];
+ }
+
+ switch(type) {
+ case NC_INT:
+ data = (int*) calloc(var_size, sizeof(int));
+ ret = ncmpi_get_vara_int_all(ncfile, i, start, count, data);
+ if (ret != NC_NOERR) handle_error(ret, __LINE__);
+ break;
+ default:
+ /* we can do this for all the known netcdf types but this
+ * example is already getting too long */
+ fprintf(stderr, "unsupported NetCDF type \n");
+ }
+
+ free(start);
+ free(count);
+ if (data != NULL) free(data);
+ }
+
+ ret = ncmpi_close(ncfile);
+ if (ret != NC_NOERR) handle_error(ret, __LINE__);
+
+ MPI_Finalize();
+ return 0;
+}
+
+/*
+ *vim: ts=8 sts=4 sw=4 noexpandtab */
diff --git a/examples/tutorial/pnetcdf-write-buffered.c b/examples/tutorial/pnetcdf-write-buffered.c
new file mode 100644
index 0000000..cdc0b87
--- /dev/null
+++ b/examples/tutorial/pnetcdf-write-buffered.c
@@ -0,0 +1,129 @@
+/*********************************************************************
+ *
+ * Copyright (C) 2012, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ *
+ *********************************************************************/
+/* $Id: pnetcdf-write-buffered.c 1153 2013-02-03 17:45:55Z wkliao $ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <pnetcdf.h>
+
+#define ERRCODE 2
+#define ERR(e) {printf("Error at line %d: err=%d %s\n", __LINE__, e, ncmpi_strerror(e)); exit(ERRCODE);}
+
+/*----< main() >------------------------------------------------------------*/
+int main(int argc, char **argv) {
+ int i, j, ncid, dimid[2], varid, err, rank, nprocs, cmode;
+ int req[2], status[2];
+ float var[4][6];
+ MPI_Offset start[2], count[2], stride[2], imap[2];
+ MPI_Offset bufsize;
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+
+ if (argc != 2) {
+ if (rank == 0) printf("Usage: %s filename\n", argv[0]);
+ MPI_Finalize();
+ exit(-1);
+ }
+
+ cmode = NC_CLOBBER | NC_64BIT_DATA;
+ if (NC_NOERR != (err = ncmpi_create(MPI_COMM_WORLD, argv[1],
+ cmode, MPI_INFO_NULL, &ncid)))
+ ERR(err);
+
+ /* define a variable of a 6 x (4*nprocs) int64 array in the nc file */
+ if (NC_NOERR != (err = ncmpi_def_dim(ncid, "Y", 6, &dimid[0])))
+ ERR(err);
+ if (NC_NOERR != (err = ncmpi_def_dim(ncid, "X", 4*nprocs, &dimid[1])))
+ ERR(err);
+ if (NC_NOERR != (err = ncmpi_def_var(ncid, "var", NC_INT64, 2, dimid,
+ &varid)))
+ ERR(err);
+ if (NC_NOERR != (err = ncmpi_enddef(ncid)))
+ ERR(err);
+
+ /* set the contents of the local write buffer var, a 4 x 6 float array
+ for example, for rank == 2, var[4][6] =
+ 48, 49, 50, 51, 52, 53,
+ 54, 55, 56, 57, 58, 59,
+ 60, 61, 62, 63, 64, 65,
+ 66, 67, 68, 69, 70, 71
+ */
+ for (j=0; j<4; j++)
+ for (i=0; i<6; i++)
+ var[j][i] = j*6+i + rank*24;
+
+ /* bufsize must be the max of data type converted before and after */
+ bufsize = 4*6*sizeof(long long); /* as var is of NC_INT64 */
+ if (NC_NOERR != (err = ncmpi_buffer_attach(ncid, bufsize)))
+ ERR(err);
+
+ /* write var to the NC variable in the matrix transposed way */
+ count[0] = 6; count[1] = 2;
+ stride[0] = 1; stride[1] = 1;
+ imap[0] = 1; imap[1] = 6;
+
+ /* write to the 1st two columns of the variable in matrix transposed way */
+ start[0] = 0;
+ start[1] = rank*4;
+ if (NC_NOERR != (err = ncmpi_bput_varm_float(ncid, varid, start, count,
+ stride, imap, &var[0][0], &req[0])))
+ ERR(err);
+
+ /* write to the 2nd two columns of the variable in transposed way */
+ start[0] = 0;
+ start[1] = rank*4+2;
+ if (NC_NOERR != (err = ncmpi_bput_varm_float(ncid, varid, start, count,
+ stride, imap, &var[2][0], &req[1])))
+ ERR(err);
+
+ /* You are now free to change contents of the buffer, var.
+ It will not change the data supposed to be written in the file.
+ */
+ for (j=0; j<4; j++)
+ for (i=0; i<6; i++)
+ var[j][i] = -1.1; /* or any numbers */
+
+ if (NC_NOERR != (err = ncmpi_wait_all(ncid, 2, req, status)))
+ ERR(err);
+
+ /* check each bput status */
+ for (i=0; i<2; i++)
+ if (status[i] != NC_NOERR) ERR(status[i]);
+
+ if (NC_NOERR != (err = ncmpi_buffer_detach(ncid)))
+ ERR(err);
+
+ if (NC_NOERR != (err = ncmpi_close(ncid))) ERR(err);
+
+ /* The output from command "ncmpidump test.nc" is shown below if run
+ this example on 4 processes.
+
+ netcdf test {
+ // file format: CDF-5 (big variables)
+ dimensions:
+ Y = 6 ;
+ X = 16 ;
+ variables:
+ int64 var(Y, X) ;
+ data:
+
+ var =
+ 0, 6, 12, 18, 24, 30, 36, 42, 48, 54, 60, 66, 72, 78, 84, 90,
+ 1, 7, 13, 19, 25, 31, 37, 43, 49, 55, 61, 67, 73, 79, 85, 91,
+ 2, 8, 14, 20, 26, 32, 38, 44, 50, 56, 62, 68, 74, 80, 86, 92,
+ 3, 9, 15, 21, 27, 33, 39, 45, 51, 57, 63, 69, 75, 81, 87, 93,
+ 4, 10, 16, 22, 28, 34, 40, 46, 52, 58, 64, 70, 76, 82, 88, 94,
+ 5, 11, 17, 23, 29, 35, 41, 47, 53, 59, 65, 71, 77, 83, 89, 95 ;
+ <---- P0 ---->|<---- P1 ----->|<---- P2 ----->|<---- P3 ---->
+ */
+ MPI_Finalize();
+ return 0;
+}
+
diff --git a/examples/tutorial/pnetcdf-write-bufferedf.f90 b/examples/tutorial/pnetcdf-write-bufferedf.f90
new file mode 100644
index 0000000..8540ecb
--- /dev/null
+++ b/examples/tutorial/pnetcdf-write-bufferedf.f90
@@ -0,0 +1,147 @@
+!
+! Copyright (C) 2012, Northwestern University and Argonne National Laboratory
+! See COPYRIGHT notice in top-level directory.
+!
+! $Id: pnetcdf-write-bufferedf.f90 2245 2015-12-20 18:39:52Z wkliao $
+
+ program main
+
+ use mpi
+ use pnetcdf
+ implicit none
+
+ integer i, j, ncid, varid, cmode, err, rank, nprocs
+ integer dimid(2), req(2), status(2)
+ integer(kind=MPI_OFFSET_KIND) start(2)
+ integer(kind=MPI_OFFSET_KIND) count(2)
+ integer(kind=MPI_OFFSET_KIND) stride(2)
+ integer(kind=MPI_OFFSET_KIND) imap(2)
+ integer(kind=MPI_OFFSET_KIND) bufsize
+ integer(kind=MPI_OFFSET_KIND) put_size
+ real var(6,4)
+ character(len=256) filename
+
+ call MPI_INIT(err)
+ call MPI_COMM_RANK(MPI_COMM_WORLD, rank, err)
+ call MPI_COMM_SIZE(MPI_COMM_WORLD, nprocs, err)
+
+ filename = "testfile.nc"
+ cmode = IOR(NF90_CLOBBER, NF90_64BIT_DATA)
+ err = nf90mpi_create(MPI_COMM_WORLD, filename, cmode, &
+ MPI_INFO_NULL, ncid)
+ if (err < NF90_NOERR) print*,'Error at nf90mpi_create ', &
+ nf90mpi_strerror(err)
+
+ ! define a variable of a (4*nprocs) x 6 integer array in the nc file
+ err = nf90mpi_def_dim(ncid, 'X', 4_MPI_OFFSET_KIND*nprocs, dimid(1))
+ if (err < NF90_NOERR) print*,'Error at nf90mpi_def_dim ', &
+ nf90mpi_strerror(err)
+
+ err = nf90mpi_def_dim(ncid, 'Y', 6_MPI_OFFSET_KIND, dimid(2))
+ if (err < NF90_NOERR) print*,'Error at nf90mpi_def_dim ', &
+ nf90mpi_strerror(err)
+
+ err = nf90mpi_def_var(ncid, 'var', NF90_INT64, dimid, varid)
+ if (err < NF90_NOERR) print*,'Error at nf90mpi_def_var ', &
+ nf90mpi_strerror(err)
+
+ err = nf90mpi_enddef(ncid)
+ if (err < NF90_NOERR) print*,'Error at nf90mpi_enddef ', &
+ nf90mpi_strerror(err)
+
+ ! set the contents of the local write buffer var, a 4 x 6 real array
+ ! for example, for rank == 2, var(4,6) =
+ ! 48, 54, 60, 65,
+ ! 49, 55, 61, 67,
+ ! 50, 56, 62, 68,
+ ! 51, 57, 63, 69,
+ ! 52, 58, 64, 70,
+ ! 53, 59, 65, 71
+ do j = 1, 4
+ do i = 1, 6
+ var(i,j) = (j-1)*6+(i-1) + rank*24
+ enddo
+ enddo
+
+ ! bufsize must be max of data type converted before and after
+ bufsize = 4*6*8
+ err = nf90mpi_buffer_attach(ncid, bufsize)
+ if (err < NF90_NOERR) print*,'Error at nf90mpi_buffer_attach ', &
+ nf90mpi_strerror(err)
+
+ ! write var to the NC variable in the matrix transposed way
+ count(1) = 2
+ count(2) = 6
+ stride(1) = 1
+ stride(2) = 1
+ imap(1) = 6
+ imap(2) = 1
+
+ req(:) = NF90_REQ_NULL ! actually not necessary, added for testing
+
+ ! write to the 1st two columns of the variable in matrix transposed way
+ start(1) = 1 + rank*4
+ start(2) = 1
+ err = nf90mpi_bput_var(ncid, varid, var(1:,1:), req(1), &
+ start, count, stride, imap)
+ if (err < NF90_NOERR) print*,'Error at nf90mpi_bput_varm_real ', &
+ nf90mpi_strerror(err)
+
+ ! write to the 2nd two columns of the variable in transposed way
+ start(1) = 3 + rank*4
+ start(2) = 1
+ err = nf90mpi_bput_var(ncid, varid, var(1:,3:), req(2), &
+ start, count, stride, imap)
+ if (err < NF90_NOERR) print*,'Error at nf90mpi_bput_varm_real ', &
+ nf90mpi_strerror(err)
+
+ err = nf90mpi_wait_all(ncid, 2, req, status)
+ if (err < NF90_NOERR) print*,'Error at nf90mpi_wait_all ', &
+ nf90mpi_strerror(err)
+
+ ! check each bput status
+ do i = 1, 2
+ if (status(i) .ne. NF90_NOERR) then
+ print*,'Error at bput status ', &
+ nf90mpi_strerror(status(i))
+ endif
+ enddo
+
+ err = nf90mpi_buffer_detach(ncid)
+ if (err < NF90_NOERR) print*,'Error at nf90mpi_buffer_detach ', &
+ nf90mpi_strerror(err)
+
+ ! The output from command "ncmpidump test.nc" is shown below if run
+ ! this example on 4 processes.
+ !
+ ! netcdf test {
+ ! // file format: CDF-5 (big variables)
+ ! dimensions:
+ ! Y = 6 ;
+ ! X = 16 ;
+ ! variables:
+ ! int64 var(Y, X) ;
+ !data:
+ !
+ ! var =
+ ! 0, 6, 12, 18, 24, 30, 36, 42, 48, 54, 60, 66, 72, 78, 84, 90,
+ ! 1, 7, 13, 19, 25, 31, 37, 43, 49, 55, 61, 67, 73, 79, 85, 91,
+ ! 2, 8, 14, 20, 26, 32, 38, 44, 50, 56, 62, 68, 74, 80, 86, 92,
+ ! 3, 9, 15, 21, 27, 33, 39, 45, 51, 57, 63, 69, 75, 81, 87, 93,
+ ! 4, 10, 16, 22, 28, 34, 40, 46, 52, 58, 64, 70, 76, 82, 88, 94,
+ ! 5, 11, 17, 23, 29, 35, 41, 47, 53, 59, 65, 71, 77, 83, 89, 95 ;
+ !
+ ! note that the display of ncmpidump is in C array dimensional order
+
+ err = nf90mpi_inq_put_size(ncid, put_size)
+ if (err < NF90_NOERR) print*,'Error at nf90mpi_inq_put_size ', &
+ nf90mpi_strerror(err)
+ ! print*,'pnetcdf reports total put size by this proc =', put_size
+
+ err = nf90mpi_close(ncid)
+ if (err < NF90_NOERR) print*,'Error at nf90mpi_close ', &
+ nf90mpi_strerror(err)
+
+ CALL MPI_Finalize(err)
+ end program
+
diff --git a/examples/tutorial/pnetcdf-write-bufferedf77.f b/examples/tutorial/pnetcdf-write-bufferedf77.f
new file mode 100644
index 0000000..6b12b0e
--- /dev/null
+++ b/examples/tutorial/pnetcdf-write-bufferedf77.f
@@ -0,0 +1,149 @@
+!
+! Copyright (C) 2012, Northwestern University and Argonne National Laboratory
+! See COPYRIGHT notice in top-level directory.
+!
+! $Id: pnetcdf-write-bufferedf77.f 2245 2015-12-20 18:39:52Z wkliao $
+
+ program main
+
+ implicit none
+ include "mpif.h"
+ include "pnetcdf.inc"
+
+ integer i, j, ncid, varid, cmode, err, rank, nprocs
+ integer dimid(2), req(2), status(2)
+ integer*8 start(2)
+ integer*8 count(2)
+ integer*8 stride(2)
+ integer*8 imap(2)
+ integer*8 bufsize
+ integer*8 put_size, dim_size
+ real var(6,4)
+ character*256 filename
+
+ call MPI_INIT(err)
+ call MPI_COMM_RANK(MPI_COMM_WORLD, rank, err)
+ call MPI_COMM_SIZE(MPI_COMM_WORLD, nprocs, err)
+
+ filename = "testfile.nc"
+ cmode = IOR(NF_CLOBBER, NF_64BIT_DATA)
+ err = nfmpi_create(MPI_COMM_WORLD, filename, cmode,
+ + MPI_INFO_NULL, ncid)
+ if (err .NE. NF_NOERR) print*,'Error at nfmpi_create ',
+ + nfmpi_strerror(err)
+
+ ! define a variable of a (4*nprocs) x 6 integer array in the nc file
+ dim_size = 4
+ err = nfmpi_def_dim(ncid, 'X', dim_size*nprocs, dimid(1))
+ if (err .NE. NF_NOERR) print*,'Error at nfmpi_def_dim ',
+ + nfmpi_strerror(err)
+
+ dim_size = 6
+ err = nfmpi_def_dim(ncid, 'Y', dim_size, dimid(2))
+ if (err .NE. NF_NOERR) print*,'Error at nfmpi_def_dim ',
+ + nfmpi_strerror(err)
+
+ err = nfmpi_def_var(ncid, 'var', NF_INT64, 2, dimid, varid)
+ if (err .NE. NF_NOERR) print*,'Error at nfmpi_def_var ',
+ + nfmpi_strerror(err)
+
+ err = nfmpi_enddef(ncid)
+ if (err .NE. NF_NOERR) print*,'Error at nfmpi_enddef ',
+ + nfmpi_strerror(err)
+
+ ! set the contents of the local write buffer var, a 4 x 6 real array
+ ! for example, for rank == 2, var(4,6) =
+ ! 48, 54, 60, 65,
+ ! 49, 55, 61, 67,
+ ! 50, 56, 62, 68,
+ ! 51, 57, 63, 69,
+ ! 52, 58, 64, 70,
+ ! 53, 59, 65, 71
+ do j = 1, 4
+ do i = 1, 6
+ var(i,j) = (j-1)*6+(i-1) + rank*24
+ enddo
+ enddo
+
+ ! bufsize must be max of data type converted before and after
+ bufsize = 4*6*8
+ err = nfmpi_buffer_attach(ncid, bufsize)
+ if (err .NE. NF_NOERR) print*,'Error at nfmpi_buffer_attach ',
+ + nfmpi_strerror(err)
+
+ ! write var to the NC variable in the matrix transposed way
+ count(1) = 2
+ count(2) = 6
+ stride(1) = 1
+ stride(2) = 1
+ imap(1) = 6
+ imap(2) = 1
+
+ req(1) = NF_REQ_NULL ! actually not necessary, added for testing
+ req(2) = NF_REQ_NULL ! actually not necessary, added for testing
+
+ ! write to the 1st two columns of the variable in matrix transposed way
+ start(1) = 1 + rank*4
+ start(2) = 1
+ err = nfmpi_bput_varm_real(ncid, varid, start, count, stride,
+ + imap, var(1,1), req(1))
+ if (err .NE. NF_NOERR) print*,'Error at nfmpi_bput_varm_real ',
+ + nfmpi_strerror(err)
+
+ ! write to the 2nd two columns of the variable in transposed way
+ start(1) = 3 + rank*4
+ start(2) = 1
+ err = nfmpi_bput_varm_real(ncid, varid, start, count, stride,
+ + imap, var(1,3), req(2))
+ if (err .NE. NF_NOERR) print*,'Error at nfmpi_bput_varm_real ',
+ + nfmpi_strerror(err)
+
+ err = nfmpi_wait_all(ncid, 2, req, status)
+ if (err .NE. NF_NOERR) print*,'Error at nfmpi_wait_all ',
+ + nfmpi_strerror(err)
+
+ ! check each bput status
+ do i = 1, 2
+ if (status(i) .ne. NF_NOERR) then
+ print*,'Error at bput status ', nfmpi_strerror(status(i))
+ endif
+ enddo
+
+ err = nfmpi_buffer_detach(ncid)
+ if (err .NE. NF_NOERR) print*,'Error at nfmpi_buffer_detach ',
+ + nfmpi_strerror(err)
+
+ ! The output from command "ncmpidump test.nc" is shown below if run
+ ! this example on 4 processes.
+ !
+ ! netcdf test {
+ ! // file format: CDF-5 (big variables)
+ ! dimensions:
+ ! Y = 6 ;
+ ! X = 16 ;
+ ! variables:
+ ! int64 var(Y, X) ;
+ !data:
+ !
+ ! var =
+ ! 0, 6, 12, 18, 24, 30, 36, 42, 48, 54, 60, 66, 72, 78, 84, 90,
+ ! 1, 7, 13, 19, 25, 31, 37, 43, 49, 55, 61, 67, 73, 79, 85, 91,
+ ! 2, 8, 14, 20, 26, 32, 38, 44, 50, 56, 62, 68, 74, 80, 86, 92,
+ ! 3, 9, 15, 21, 27, 33, 39, 45, 51, 57, 63, 69, 75, 81, 87, 93,
+ ! 4, 10, 16, 22, 28, 34, 40, 46, 52, 58, 64, 70, 76, 82, 88, 94,
+ ! 5, 11, 17, 23, 29, 35, 41, 47, 53, 59, 65, 71, 77, 83, 89, 95 ;
+ !
+ ! note that the display of ncmpidump is in C array dimensional order
+
+ err = nfmpi_inq_put_size(ncid, put_size)
+ if (err .NE. NF_NOERR) print*,'Error at nfmpi_inq_put_size ',
+ + nfmpi_strerror(err)
+ ! print*,'pnetcdf reports total put size by this proc =', put_size
+
+ err = nfmpi_close(ncid)
+ if (err .NE. NF_NOERR) print*,'Error at nfmpi_close ',
+ + nfmpi_strerror(err)
+
+ CALL MPI_Finalize(err)
+ end ! program
+
diff --git a/examples/tutorial/pnetcdf-write-flexible.c b/examples/tutorial/pnetcdf-write-flexible.c
new file mode 100644
index 0000000..23bf02d
--- /dev/null
+++ b/examples/tutorial/pnetcdf-write-flexible.c
@@ -0,0 +1,111 @@
+/*********************************************************************
+ *
+ * Copyright (C) 2012, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ *
+ *********************************************************************/
+/* $Id: pnetcdf-write-flexible.c 1123 2013-01-26 17:35:03Z wkliao $ */
+
+/* simple demonstration of pnetcdf
+ * text attribute on dataset
+ * write out rank into 1-d array collectively.
+ * This example demonstrates the flexible interface */
+
+/* This program creates a file, say named output.nc, with the following
+ contents, shown by running ncmpidump command .
+
+ % mpiexec -n 4 pnetcdf-write-flexible /orangefs/wkliao/output.nc
+
+ % ncmpidump /orangefs/wkliao/output.nc
+ netcdf output {
+ // file format: CDF-2 (large file)
+ dimensions:
+ d1 = 4 ;
+ variables:
+ int v1(d1) ;
+ int v2(d1) ;
+
+ // global attributes:
+ :string = "Hello World\n",
+ "" ;
+ data:
+
+ v1 = 0, 1, 2, 3 ;
+
+ v2 = 0, 1, 2, 3 ;
+ }
+*/
+
+#include <stdlib.h>
+#include <mpi.h>
+#include <pnetcdf.h>
+#include <stdio.h>
+
+static void handle_error(int status, int lineno)
+{
+ fprintf(stderr, "Error at line %d: %s\n", lineno, ncmpi_strerror(status));
+ MPI_Abort(MPI_COMM_WORLD, 1);
+}
+
+int main(int argc, char **argv) {
+
+ int ret, ncfile, nprocs, rank, dimid, varid1, varid2, ndims=1;
+ MPI_Offset start, count=1;
+ char buf[13] = "Hello World\n";
+ int data;
+
+ MPI_Init(&argc, &argv);
+
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+
+ if (argc != 2) {
+ if (rank == 0) printf("Usage: %s filename\n", argv[0]);
+ MPI_Finalize();
+ exit(-1);
+ }
+
+ ret = ncmpi_create(MPI_COMM_WORLD, argv[1],
+ NC_CLOBBER|NC_64BIT_OFFSET, MPI_INFO_NULL, &ncfile);
+ if (ret != NC_NOERR) handle_error(ret, __LINE__);
+
+ ret = ncmpi_def_dim(ncfile, "d1", nprocs, &dimid);
+ if (ret != NC_NOERR) handle_error(ret, __LINE__);
+
+ ret = ncmpi_def_var(ncfile, "v1", NC_INT, ndims, &dimid, &varid1);
+ if (ret != NC_NOERR) handle_error(ret, __LINE__);
+
+ ret = ncmpi_def_var(ncfile, "v2", NC_INT, ndims, &dimid, &varid2);
+ if (ret != NC_NOERR) handle_error(ret, __LINE__);
+
+ ret = ncmpi_put_att_text(ncfile, NC_GLOBAL, "string", 13, buf);
+ if (ret != NC_NOERR) handle_error(ret, __LINE__);
+
+ /* all processors defined the dimensions, attributes, and variables,
+ * but here in ncmpi_enddef is the one place where metadata I/O
+ * happens. Behind the scenes, rank 0 takes the information and writes
+ * the netcdf header. All processes communicate to ensure they have
+ * the same (cached) view of the dataset */
+
+ ret = ncmpi_enddef(ncfile);
+ if (ret != NC_NOERR) handle_error(ret, __LINE__);
+
+ start=rank, count=1, data=rank;
+
+ /* in this simple example every process writes its rank to two 1d variables */
+ /* we used a basic MPI_INT type to this flexible mode call, but could
+ * have used any derived MPI datatype that describes application data
+ * structures */
+ ret = ncmpi_put_vara_all(ncfile, varid1, &start, &count, &data, count, MPI_INT);
+ if (ret != NC_NOERR) handle_error(ret, __LINE__);
+
+ ret = ncmpi_put_vara_all(ncfile, varid2, &start, &count, &data, count, MPI_INT);
+ if (ret != NC_NOERR) handle_error(ret, __LINE__);
+
+ ret = ncmpi_close(ncfile);
+ if (ret != NC_NOERR) handle_error(ret, __LINE__);
+
+ MPI_Finalize();
+
+ return 0;
+}
diff --git a/examples/tutorial/pnetcdf-write-from-master.c b/examples/tutorial/pnetcdf-write-from-master.c
new file mode 100644
index 0000000..d4add24
--- /dev/null
+++ b/examples/tutorial/pnetcdf-write-from-master.c
@@ -0,0 +1,117 @@
+/*********************************************************************
+ *
+ * Copyright (C) 2012, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ *
+ *********************************************************************/
+/* $Id: pnetcdf-write-from-master.c 2245 2015-12-20 18:39:52Z wkliao $ */
+
+/* simple demonstration of pnetcdf
+ * text attribute on dataset
+ * write out rank into 1-d array after sending to rank 0. This is a dumb way
+ * to do parallel I/O, but folks do this sometimes... */
+
+/* This program creates a file, say named output.nc, with the following
+ contents, shown by running ncmpidump command .
+
+ % mpiexec -n 4 pnetcdf-write-from-master /orangefs/wkliao/output.nc
+
+ % ncmpidump /orangefs/wkliao/output.nc
+ netcdf output {
+ // file format: CDF-2 (large file)
+ dimensions:
+ d1 = 4 ;
+ variables:
+ int v1(d1) ;
+ int v2(d1) ;
+
+ // global attributes:
+ :string = "Hello World\n",
+ "" ;
+ data:
+
+ v1 = 0, 1, 2, 3 ;
+
+ v2 = 0, 1, 2, 3 ;
+ }
+*/
+
+#include <stdlib.h>
+#include <mpi.h>
+#include <pnetcdf.h>
+#include <stdio.h>
+
+static void handle_error(int status, int lineno)
+{
+ fprintf(stderr, "Error at line %d: %s\n", lineno, ncmpi_strerror(status));
+ MPI_Abort(MPI_COMM_WORLD, 1);
+}
+
+int main(int argc, char **argv) {
+ int ret, ncfile, nprocs, rank, dimid, varid1, varid2, ndims=1;
+ MPI_Offset start, count=1;
+ char buf[13] = "Hello World\n";
+ int *data=NULL;
+
+ MPI_Init(&argc, &argv);
+
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+
+ if (argc != 2) {
+ if (rank == 0) printf("Usage: %s filename\n", argv[0]);
+ MPI_Finalize();
+ exit(-1);
+ }
+
+ if (rank == 0) {
+ ret = ncmpi_create(MPI_COMM_SELF, argv[1],
+ NC_CLOBBER|NC_64BIT_OFFSET, MPI_INFO_NULL, &ncfile);
+ if (ret != NC_NOERR) handle_error(ret, __LINE__);
+
+ ret = ncmpi_def_dim(ncfile, "d1", nprocs, &dimid);
+ if (ret != NC_NOERR) handle_error(ret, __LINE__);
+
+ ret = ncmpi_def_var(ncfile, "v1", NC_INT, ndims, &dimid, &varid1);
+ if (ret != NC_NOERR) handle_error(ret, __LINE__);
+
+ ret = ncmpi_def_var(ncfile, "v2", NC_INT, ndims, &dimid, &varid2);
+ if (ret != NC_NOERR) handle_error(ret, __LINE__);
+
+ ret = ncmpi_put_att_text(ncfile, NC_GLOBAL, "string", 13, buf);
+ if (ret != NC_NOERR) handle_error(ret, __LINE__);
+
+ ret = ncmpi_enddef(ncfile);
+ if (ret != NC_NOERR) handle_error(ret, __LINE__);
+
+ /* first reason this approach is not scalable: need to allocate
+ * enough memory to hold data from all processors */
+ data = (int*)calloc(nprocs, sizeof(int));
+ }
+
+ /* second reason this approach is not scalable: sending to rank 0
+ * introduces a serialization point, even if using an optimized
+ * collective routine */
+ MPI_Gather(&rank, 1, MPI_INT, data, 1, MPI_INT, 0, MPI_COMM_WORLD);
+
+ if (rank == 0) {
+ /* and lastly, the third reason this approach is not scalable: I/O
+ * happens from a single processor. This approach can be ok if the
+ * amount of data is quite small, but almost always the underlying
+ * MPI-IO library can do a better job */
+ start=0, count=nprocs;
+ ret = ncmpi_put_vara_int_all(ncfile, varid1, &start, &count, data);
+ if (ret != NC_NOERR) handle_error(ret, __LINE__);
+
+ ret = ncmpi_put_vara_int_all(ncfile, varid2, &start, &count, data);
+ if (ret != NC_NOERR) handle_error(ret, __LINE__);
+
+ ret = ncmpi_close(ncfile);
+ if (ret != NC_NOERR) handle_error(ret, __LINE__);
+
+ free(data);
+ }
+
+ MPI_Finalize();
+ return 0;
+}
diff --git a/examples/tutorial/pnetcdf-write-nb.c b/examples/tutorial/pnetcdf-write-nb.c
new file mode 100644
index 0000000..c0dc3ef
--- /dev/null
+++ b/examples/tutorial/pnetcdf-write-nb.c
@@ -0,0 +1,126 @@
+/*********************************************************************
+ *
+ * Copyright (C) 2012, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ *
+ *********************************************************************/
+/* $Id: pnetcdf-write-nb.c 2095 2015-09-07 21:15:24Z wkliao $ */
+
+/* simple demonstration of pnetcdf
+ * text attribute on dataset
+ * write out rank into 1-d array collectively.
+ * This example demonstrates the non-blocking write interface */
+
+/* This program creates a file, say named output.nc, with the following
+ contents, shown by running ncmpidump command .
+
+ % mpiexec -n 4 pnetcdf-write-nb /orangefs/wkliao/output.nc
+
+ % ncmpidump /orangefs/wkliao/output.nc
+ netcdf output {
+ // file format: CDF-2 (large file)
+ dimensions:
+ d1 = 4 ;
+ variables:
+ int v1(d1) ;
+ int v2(d1) ;
+
+ // global attributes:
+ :string = "Hello World\n",
+ "" ;
+ data:
+
+ v1 = 0, 1, 2, 3 ;
+
+ v2 = 0, 1, 2, 3 ;
+ }
+*/
+
+#include <stdlib.h>
+#include <mpi.h>
+#include <pnetcdf.h>
+#include <stdio.h>
+
+static void handle_error(int status, int lineno)
+{
+ fprintf(stderr, "Error at line %d: %s\n", lineno, ncmpi_strerror(status));
+ MPI_Abort(MPI_COMM_WORLD, 1);
+}
+
+int main(int argc, char **argv) {
+
+ int ret, ncfile, nprocs, rank, dimid, varid1, varid2, ndims=1;
+ MPI_Offset start, count=1;
+ char buf[13] = "Hello World\n";
+ int data1, data2;
+ int requests[2], statuses[2];
+
+ MPI_Init(&argc, &argv);
+
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+
+ if (argc != 2) {
+ if (rank == 0) printf("Usage: %s filename\n", argv[0]);
+ MPI_Finalize();
+ exit(-1);
+ }
+
+ ret = ncmpi_create(MPI_COMM_WORLD, argv[1],
+ NC_CLOBBER|NC_64BIT_OFFSET, MPI_INFO_NULL, &ncfile);
+ if (ret != NC_NOERR) handle_error(ret, __LINE__);
+
+ ret = ncmpi_def_dim(ncfile, "d1", nprocs, &dimid);
+ if (ret != NC_NOERR) handle_error(ret, __LINE__);
+
+ ret = ncmpi_def_var(ncfile, "v1", NC_INT, ndims, &dimid, &varid1);
+ if (ret != NC_NOERR) handle_error(ret, __LINE__);
+
+ ret = ncmpi_def_var(ncfile, "v2", NC_INT, ndims, &dimid, &varid2);
+ if (ret != NC_NOERR) handle_error(ret, __LINE__);
+
+ ret = ncmpi_put_att_text(ncfile, NC_GLOBAL, "string", 13, buf);
+ if (ret != NC_NOERR) handle_error(ret, __LINE__);
+
+ /* all processors defined the dimensions, attributes, and variables,
+ * but here in ncmpi_enddef is the one place where metadata I/O
+ * happens. Behind the scenes, rank 0 takes the information and writes
+ * the netcdf header. All processes communicate to ensure they have
+ * the same (cached) view of the dataset */
+
+ ret = ncmpi_enddef(ncfile);
+ if (ret != NC_NOERR) handle_error(ret, __LINE__);
+
+ start=rank, count=1, data1=rank, data2=rank;
+
+ /* in this simple example every process writes its rank to two 1d variables */
+
+ /* we used a basic MPI_INT type to this flexible mode call, but could
+ * have used any derived MPI datatype that describes application data
+ * structures */
+
+ /* furthermore, we use the non-blocking interface to essentially
+ * schedule the two write operations. No i/o actually happens here,
+ * which is why these routines do not need to be collective. */
+ ret = ncmpi_iput_vara(ncfile, varid1, &start, &count, &data1, count,
+ MPI_INT, &requests[0]);
+ if (ret != NC_NOERR) handle_error(ret, __LINE__);
+
+ ret = ncmpi_iput_vara(ncfile, varid2, &start, &count, &data2, count,
+ MPI_INT, &requests[1]);
+ if (ret != NC_NOERR) handle_error(ret, __LINE__);
+
+ ret = ncmpi_wait_all(ncfile, 2, requests, statuses);
+ if (ret != NC_NOERR) handle_error(ret, __LINE__);
+
+ /* check status of each nonblocking call */
+ if (statuses[0] != NC_NOERR) handle_error(statuses[0], __LINE__);
+ if (statuses[1] != NC_NOERR) handle_error(statuses[1], __LINE__);
+
+ ret = ncmpi_close(ncfile);
+ if (ret != NC_NOERR) handle_error(ret, __LINE__);
+
+ MPI_Finalize();
+
+ return 0;
+}
diff --git a/examples/tutorial/pnetcdf-write-nfiles.c b/examples/tutorial/pnetcdf-write-nfiles.c
new file mode 100644
index 0000000..790cd5f
--- /dev/null
+++ b/examples/tutorial/pnetcdf-write-nfiles.c
@@ -0,0 +1,218 @@
+/*********************************************************************
+ *
+ * Copyright (C) 2012, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ *
+ *********************************************************************/
+/* $Id: pnetcdf-write-nfiles.c 2245 2015-12-20 18:39:52Z wkliao $ */
+
+/* simple demonstration of pnetcdf
+ * text attribute on dataset
+ * Each process writes out rank into 1-d array to a separate file.
+ * This is not a good way to do parallel I/O */
+
+/*
+To run on 4 processes for example,
+% mpiexec -l -n 4 pnetcdf-write-nfiles output.nc
+
+There will be 4+1 files created.
+ output.nc
+ output.nc.0-4.nc
+ output.nc.1-4.nc
+ output.nc.2-4.nc
+ output.nc.3-4.nc
+
+The contents of files are shown at the bottom of this files.
+*/
+
+#include <stdlib.h>
+#include <mpi.h>
+#include <pnetcdf.h>
+#include <stdio.h>
+
+
+static void handle_error(int status, int lineno)
+{
+ fprintf(stderr, "Error at line %d: %s\n", lineno, ncmpi_strerror(status));
+ MPI_Abort(MPI_COMM_WORLD, 1);
+}
+
+#define DSET_NAME_LEN 1024
+
+int main(int argc, char **argv) {
+
+ int ret, ncfile, nprocs, rank, dimid, varid1, varid2, ndims=1;
+ char buf[13] = "Hello World\n";
+ int data;
+ char filename[DSET_NAME_LEN];
+
+ MPI_Init(&argc, &argv);
+
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+
+ if (argc != 2) {
+ if (rank == 0) printf("Usage: %s filename\n", argv[0]);
+ MPI_Finalize();
+ exit(-1);
+ }
+
+ /* Many applications find "one file per process" easy, but there are
+ * several deficiencies with that approach:
+ * - here we need to construct a unique file name for each processor */
+ ret = snprintf(filename, DSET_NAME_LEN, "%s.%d-%d.nc", argv[1], rank, nprocs);
+ if (ret >= DSET_NAME_LEN) {
+ fprintf(stderr, "name too long \n");
+ exit(-1);
+ }
+
+ /* note that the communicator is still needed but now it is
+ * MPI_COMM_SELF: since each processor opens its own file we cannot use
+ * MPI_COMM_WORLD */
+ ret = ncmpi_create(MPI_COMM_SELF, filename,
+ NC_CLOBBER|NC_64BIT_OFFSET, MPI_INFO_NULL, &ncfile);
+ if (ret != NC_NOERR) handle_error(ret, __LINE__);
+
+ /* each processor writes its data to a file, so instead of an "nprocs"
+ * sized array, we just have an array big enough to hold one
+ * processor's data */
+ ret = ncmpi_def_dim(ncfile, "d1", 1, &dimid);
+ if (ret != NC_NOERR) handle_error(ret, __LINE__);
+
+ ret = ncmpi_def_var(ncfile, "v1", NC_INT, ndims, &dimid, &varid1);
+ if (ret != NC_NOERR) handle_error(ret, __LINE__);
+
+ ret = ncmpi_def_var(ncfile, "v2", NC_INT, ndims, &dimid, &varid2);
+ if (ret != NC_NOERR) handle_error(ret, __LINE__);
+
+ ret = ncmpi_put_att_text(ncfile, NC_GLOBAL, "string", 13, buf);
+ if (ret != NC_NOERR) handle_error(ret, __LINE__);
+
+ /* ncmpi_enddef writes the header out as in other examples, but because
+ * each processor opened the file independently, there can be no "write
+ * and broadcast" optimization. Instead, every processor does header
+ * i/o. */
+ ret = ncmpi_enddef(ncfile); if (ret != NC_NOERR) handle_error(ret, __LINE__);
+
+ /* the one advantage to this approach: data decomposition is easy the
+ * application does not need to worry about the shape and location of
+ * the data (the 'start' and 'count' parameters in the 'vara' family of
+ * functions) and can instead just write the entire (small) variable */
+
+ data=rank;
+
+ /* in this simple example every process writes its rank to two 1d
+ * variables */
+ /* When each processor writes to its own file, a whole host of
+ * optimizations cannot take place. */
+
+ ret = ncmpi_put_var_int_all(ncfile, varid1, &data);
+ if (ret != NC_NOERR) handle_error(ret, __LINE__);
+
+ ret = ncmpi_put_var_int_all(ncfile, varid2, &data);
+ if (ret != NC_NOERR) handle_error(ret, __LINE__);
+
+ ret = ncmpi_close(ncfile);
+ if (ret != NC_NOERR) handle_error(ret, __LINE__);
+
+ MPI_Finalize();
+
+ return 0;
+}
+
+/* The contents of files created by this program are:
+% ncmpidump output.nc
+netcdf output {
+// file format: CDF-2 (large file)
+dimensions:
+ d1 = 4 ;
+variables:
+ int v1(d1) ;
+ int v2(d1) ;
+
+// global attributes:
+ :string = "Hello World\n",
+ "" ;
+data:
+
+ v1 = 0, 1, 2, 3 ;
+
+ v2 = 0, 1, 2, 3 ;
+}
+
+% ncmpidump output.nc.0-4.nc
+netcdf output.nc.0-4 {
+// file format: CDF-2 (large file)
+dimensions:
+ d1 = 1 ;
+variables:
+ int v1(d1) ;
+ int v2(d1) ;
+
+// global attributes:
+ :string = "Hello World\n",
+ "" ;
+data:
+
+ v1 = 0 ;
+
+ v2 = 0 ;
+}
+
+% ncmpidump output.nc.1-4.nc
+netcdf output.nc.1-4 {
+// file format: CDF-2 (large file)
+dimensions:
+ d1 = 1 ;
+variables:
+ int v1(d1) ;
+ int v2(d1) ;
+
+// global attributes:
+ :string = "Hello World\n",
+ "" ;
+data:
+
+ v1 = 1 ;
+
+ v2 = 1 ;
+}
+
+% ncmpidump output.nc.2-4.nc
+netcdf output.nc.2-4 {
+// file format: CDF-2 (large file)
+dimensions:
+ d1 = 1 ;
+variables:
+ int v1(d1) ;
+ int v2(d1) ;
+
+// global attributes:
+ :string = "Hello World\n",
+ "" ;
+data:
+
+ v1 = 2 ;
+
+ v2 = 2 ;
+}
+
+% ncmpidump output.nc.3-4.nc
+netcdf output.nc.3-4 {
+// file format: CDF-2 (large file)
+dimensions:
+ d1 = 1 ;
+variables:
+ int v1(d1) ;
+ int v2(d1) ;
+
+// global attributes:
+ :string = "Hello World\n",
+ "" ;
+data:
+
+ v1 = 3 ;
+
+ v2 = 3 ;
+}
+*/
diff --git a/examples/tutorial/pnetcdf-write-standard.c b/examples/tutorial/pnetcdf-write-standard.c
new file mode 100644
index 0000000..cfeaca4
--- /dev/null
+++ b/examples/tutorial/pnetcdf-write-standard.c
@@ -0,0 +1,108 @@
+/*********************************************************************
+ *
+ * Copyright (C) 2012, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ *
+ *********************************************************************/
+/* $Id: pnetcdf-write-standard.c 1123 2013-01-26 17:35:03Z wkliao $ */
+
+/* simple demonstration of pnetcdf
+ * text attribute on dataset
+ * write out rank into 1-d array collectively.
+ * The most basic way to do parallel i/o with pnetcdf */
+
+/* This program creates a file, say named output.nc, with the following
+ contents, shown by running ncmpidump command .
+
+ % mpiexec -n 4 pnetcdf-write-standard /orangefs/wkliao/output.nc
+
+ % ncmpidump /orangefs/wkliao/output.nc
+ netcdf output {
+ // file format: CDF-2 (large file)
+ dimensions:
+ d1 = 4 ;
+ variables:
+ int v1(d1) ;
+ int v2(d1) ;
+
+ // global attributes:
+ :string = "Hello World\n",
+ "" ;
+ data:
+
+ v1 = 0, 1, 2, 3 ;
+
+ v2 = 0, 1, 2, 3 ;
+ }
+*/
+
+#include <stdlib.h>
+#include <mpi.h>
+#include <pnetcdf.h>
+#include <stdio.h>
+
+static void handle_error(int status, int lineno)
+{
+ fprintf(stderr, "Error at line %d: %s\n", lineno, ncmpi_strerror(status));
+ MPI_Abort(MPI_COMM_WORLD, 1);
+}
+
+int main(int argc, char **argv) {
+
+ int ret, ncfile, nprocs, rank, dimid, varid1, varid2, ndims=1;
+ MPI_Offset start, count=1;
+ char buf[13] = "Hello World\n";
+ int data;
+
+ MPI_Init(&argc, &argv);
+
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+
+ if (argc != 2) {
+ if (rank == 0) printf("Usage: %s filename\n", argv[0]);
+ MPI_Finalize();
+ exit(-1);
+ }
+
+ ret = ncmpi_create(MPI_COMM_WORLD, argv[1],
+ NC_CLOBBER|NC_64BIT_OFFSET, MPI_INFO_NULL, &ncfile);
+ if (ret != NC_NOERR) handle_error(ret, __LINE__);
+
+ ret = ncmpi_def_dim(ncfile, "d1", nprocs, &dimid);
+ if (ret != NC_NOERR) handle_error(ret, __LINE__);
+
+ ret = ncmpi_def_var(ncfile, "v1", NC_INT, ndims, &dimid, &varid1);
+ if (ret != NC_NOERR) handle_error(ret, __LINE__);
+
+ ret = ncmpi_def_var(ncfile, "v2", NC_INT, ndims, &dimid, &varid2);
+ if (ret != NC_NOERR) handle_error(ret, __LINE__);
+
+ ret = ncmpi_put_att_text(ncfile, NC_GLOBAL, "string", 13, buf);
+ if (ret != NC_NOERR) handle_error(ret, __LINE__);
+
+ /* all processors defined the dimensions, attributes, and variables,
+ * but here in ncmpi_enddef is the one place where metadata I/O
+ * happens. Behind the scenes, rank 0 takes the information and writes
+ * the netcdf header. All processes communicate to ensure they have
+ * the same (cached) view of the dataset */
+
+ ret = ncmpi_enddef(ncfile);
+ if (ret != NC_NOERR) handle_error(ret, __LINE__);
+
+ start=rank, count=1, data=rank;
+
+ /* in this simple example every process writes its rank to two 1d variables */
+ ret = ncmpi_put_vara_int_all(ncfile, varid1, &start, &count, &data);
+ if (ret != NC_NOERR) handle_error(ret, __LINE__);
+
+ ret = ncmpi_put_vara_int_all(ncfile, varid2, &start, &count, &data);
+ if (ret != NC_NOERR) handle_error(ret, __LINE__);
+
+ ret = ncmpi_close(ncfile);
+ if (ret != NC_NOERR) handle_error(ret, __LINE__);
+
+ MPI_Finalize();
+
+ return 0;
+}
diff --git a/macros.make.in b/macros.make.in
new file mode 100644
index 0000000..3e0acbd
--- /dev/null
+++ b/macros.make.in
@@ -0,0 +1,138 @@
+# $Id: macros.make.in 2264 2015-12-22 15:42:59Z wkliao $
+
+# The purpose of this file is to contain common make(1) macros.
+# It should be processed by every execution of that utility.
+
+ at SET_MAKE@
+
+# POSIX shell. Shouldn't be necessary -- but is under IRIX 5.3.
+SHELL = /bin/sh
+RM = @RM@
+LN_S = @LN_S@
+
+# Installation Directories:
+# SRCDIR = @SRCDIR@
+prefix = @prefix@
+INCDIR = $(prefix)/include
+LIBDIR = $(prefix)/lib
+BINDIR = $(prefix)/bin
+MANDIR = $(prefix)/man
+BUILDDIR = @BUILDDIR@
+LIBRARY = @BUILDDIR@/src/lib/libpnetcdf.a
+
+
+# Useful tools
+M4 = @M4@
+M4FLAGS = @M4FLAGS@
+EGREP = @EGREP@
+
+# AC_PROG_SED and AC_PROG_GREP are only available on autoconf 2.60 and later
+# SED = @SED@
+# GREP = @GREP@
+SED = sed
+GREP = grep
+
+# Preprocessing:
+DEFS = @DEFS@
+FC_DEFINE = @FC_DEFINE@
+CPP = @CPP@
+CPPFLAGS = $(INCLUDES) $(DEFS) @CPPFLAGS@
+CXXCPPFLAGS = $(INCLUDES) $(DEFS) @CXXCPPFLAGS@
+FPP = @FPP@
+FPPFLAGS = $(INCLUDES) @FPPFLAGS@ @NAGf90FPPFLAGS@
+
+
+# Compilation:
+MPICC = @MPICC@
+MPICXX = @MPICXX@
+MPIF77 = @MPIF77@
+MPIF90 = @MPIF90@
+
+SEQ_CC = @SEQ_CC@
+
+# debugging and optimization options for compiling and linking
+CFLAGS = @CFLAGS@
+CXXFLAGS = @CXXFLAGS@
+F77FLAGS = @F77FLAGS@ @NAG_FCFLAGS@
+F90FLAGS = @F90FLAGS@ @NAG_FCFLAGS@
+
+# compiler options for different file extensions: .f .F .f90 .F90
+F77FLAGS_f = @F77FLAGS_f@
+F77FLAGS_F = @F77FLAGS_F@
+F90FLAGS_f90 = @F90FLAGS_f90@
+F90FLAGS_F90 = @F90FLAGS_F90@
+
+# preprocessor options for different file extensions: .f .F .f90 .F90
+F77PPFLAGS_f = @F77PPFLAGS_f@
+F77PPFLAGS_F = @F77PPFLAGS_F@
+F90PPFLAGS_f90 = @F90PPFLAGS_f90@
+F90PPFLAGS_F90 = @F90PPFLAGS_F90@
+
+# NETCDF.MOD = @NETCDF_MOD@
+CC_MAKEDEPEND = @CC_MAKEDEPEND@
+
+COMPILE.c = $(MPICC) $(CFLAGS) $(CPPFLAGS) -c
+COMPILE.cxx = $(MPICXX) $(CXXFLAGS) $(CXXCPPFLAGS) -c
+COMPILE.f = $(MPIF77) $(F77FLAGS_f) $(FPPFLAGS) $(F77FLAGS) -c
+COMPILE.f90 = $(MPIF90) $(F90FLAGS_f90) $(FPPFLAGS) $(F90FLAGS) -c
+COMPILE.F = $(MPIF77) $(F77FLAGS_F) $(FPPFLAGS) $(F77FLAGS) $(F77PPFLAGS_F) -c
+COMPILE.F90 = $(MPIF90) $(F90FLAGS_F90) $(FPPFLAGS) $(F90FLAGS) $(F90PPFLAGS_F90) -c
+# In PnetCDF, we follow the file extension convention that .F and .F90 files
+# require preprocessing, while .f and .f90 do not.
+
+
+# Linking:
+FLIBS = @FLIBS@
+FCLIBS = @FCLIBS@
+F90LIBS = @F90LIBS@
+FLDFLAGS = @FLDFLAGS@
+F90LDFLAGS = @F90LDFLAGS@
+LDFLAGS = @LDFLAGS@
+LIBS = @LIBS@
+
+LINK.c = $(MPICC) $(CFLAGS) -o $@
+LINK.cxx = $(MPICXX) $(CXXFLAGS) -o $@
+LINK.F77 = $(MPIF77) $(F77FLAGS) -o $@
+LINK.F90 = $(MPIF90) $(F90FLAGS) -o $@
+
+TEST_MPIRUN = @TEST_MPIRUN@
+TEST_OUTDIR = @TEST_OUTDIR@
+TEST_SEQRUN = @TEST_SEQRUN@
+
+# Manual pages:
+WHATIS = @WHATIS@
+# The following macro should be empty on systems that don't
+# allow users to create their own manual-page indexes.
+MAKEWHATIS_CMD = @MAKEWHATIS_CMD@
+
+
+# Misc. Utilities:
+AR = @AR@
+ARFLAGS = @ARFLAGS@
+AWK = @AWK@
+RANLIB = @RANLIB@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+TARFLAGS = -chf
+
+
+# Dummy macros: used only as placeholders to silence GNU make. They are
+# redefined, as necessary, in subdirectory makefiles.
+HEADER = dummy_header
+HEADER1 = dummy_header1
+HEADER2 = dummy_header2
+HEADER3 = dummy_header3
+MANUAL = dummy_manual
+PROGRAM = dummy_program
+
+
+# Distribution macros:
+FTPDIR = /home/ftp/pub/$(PACKAGE)
+FTPBINDIR = @FTPBINDIR@
+
+PNETCDF_VERSION_MAJOR = @PNETCDF_VERSION_MAJOR@
+PNETCDF_VERSION_MINOR = @PNETCDF_VERSION_MINOR@
+PNETCDF_VERSION_SUB = @PNETCDF_VERSION_SUB@
+PNETCDF_VERSION_PRE = @PNETCDF_VERSION_PRE@
+PNETCDF_VERSION = @PNETCDF_VERSION@
+
diff --git a/man/Makefile.in b/man/Makefile.in
new file mode 100644
index 0000000..1d0db89
--- /dev/null
+++ b/man/Makefile.in
@@ -0,0 +1,60 @@
+#
+# Copyright (C) 2012, Northwestern University and Argonne National Laboratory
+# See COPYRIGHT notice in top-level directory.
+#
+# $Id: Makefile.in 1507 2013-11-17 05:18:16Z wkliao $
+#
+# @configure_input@
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+include ../macros.make
+
+MANUAL_C = pnetcdf.3
+MANUAL_F77 = pnetcdf_f77.3
+MANUAL_F90 = pnetcdf_f90.3
+
+MANUAL = $(MANUAL_C)
+ifeq (@has_fortran@, yes)
+MANUAL += $(MANUAL_F77)
+MANUAL += $(MANUAL_F90)
+endif
+
+PACKING_LIST = pnetcdf.m4 pnetcdf_f90.m4 \
+ Makefile.in
+
+GARBAGE = $(MANUAL)
+
+all: $(MANUAL)
+
+RELEASE_DATE = "@PNETCDF_RELEASE_DATE2@"
+RELEASE_STR = "@PNETCDF_VERSION@ of @PNETCDF_RELEASE_DATE@"
+
+pnetcdf.3: pnetcdf.m4
+ $(M4) $(M4FLAGS) -DAPI=C -DRELEASE_STR=$(RELEASE_STR) -DRELEASE_DATE=$(RELEASE_DATE) $? > $@ || $(RM) -f $@
+
+pnetcdf_f77.3: pnetcdf.m4
+ $(M4) $(M4FLAGS) -DAPI=F -DRELEASE_STR=$(RELEASE_STR) -DRELEASE_DATE=$(RELEASE_DATE) $? > $@ || $(RM) -f $@
+
+pnetcdf_f90.3: pnetcdf_f90.m4
+ $(M4) $(M4FLAGS) -DRELEASE_STR=$(RELEASE_STR) -DRELEASE_DATE=$(RELEASE_DATE) $? > $@ || $(RM) -f $@
+
+test:
+
+install: $(MANUAL)
+ $(INSTALL) -d -m 755 $(MANDIR)/man3
+ @for i in $(MANUAL) ; do ( \
+ if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \
+ else file=$$i; fi; \
+ fn=`basename $$i` ; \
+ $(INSTALL_DATA) $$file $(MANDIR)/man3/$$fn \
+ ; ) ; done
+
+uninstall:
+ @for i in $(MANUAL) ; do ( \
+ fn=`basename $$i` ; \
+ $(RM) -f $(MANDIR)/man3/$$fn \
+ ; ) ; done
+
+include $(srcdir)/../rules.make
diff --git a/man/pnetcdf.m4 b/man/pnetcdf.m4
new file mode 100644
index 0000000..1791ad6
--- /dev/null
+++ b/man/pnetcdf.m4
@@ -0,0 +1,1269 @@
+divert(-1)
+
+changequote(<<,>>)
+define(<<index>>, defn(index))
+
+define(<<CODE>>, <<\fB$1\fR>>)
+
+define(<<ARG>>, <<\fI$1\fP>>)
+
+define(<<HEADER_FILE>>,
+ <<ifelse(API,C,
+ $1.h,
+ $1.inc)>>)
+
+define(<<INCLUDE>>,
+ <<ifelse(API,C,
+ <<#include>> <HEADER_FILE($1)>,
+ <<<<include>>>> "HEADER_FILE($1)")>>)
+
+define(<<COMPILER>>,
+ <<ifelse(API,C,
+ mpicc,
+ mpif77)>>)
+
+define(<<LANGUAGE>>,
+ <<ifelse(API,C,
+ C,
+ FORTRAN)>>)
+
+define(<<RETSTR>>,
+ <<ifelse(API,C,
+ const char*,
+ character*80)>>)
+
+define(<<FNAME>>,
+ <<ifelse(API,C,
+ ncmpi_$1,
+ nfmpi_$1)>>)
+
+define(<<VOID_ARG>>,
+ <<ifelse(API,C,,void)>>)
+
+define(<<MACRO>>,
+ <<CODE(ifelse(API,C,
+ NC_$1,
+ NF_$1))>>)
+
+dnl AQUAL(io, rank)
+define(<<AQUAL>>, <<ifelse(API,C,
+ <<ifelse($1, output, , <<ifelse($2, 0, , const )>>)>>)>>)
+
+dnl CTYPE(type)
+define(<<CTYPE>>,
+ <<ifelse($1,text,char,
+ <<ifelse($1,uchar,unsigned char,
+ <<ifelse($1,schar,signed char,
+ <<ifelse($1,short,short,
+ <<ifelse($1,int,int,
+ <<ifelse($1,nc_type,nc_type,
+ <<ifelse($1,size_t,MPI_Offset,
+ <<ifelse($1,ptrdiff_t,MPI_Offset,
+ <<ifelse($1,long,long,
+ <<ifelse($1,int64,long long,
+ <<ifelse($1,float,float,
+ <<ifelse($1,double,double,
+ <<ifelse($1,ubyte,unsigned char,
+ <<ifelse($1,ushort,unsigned short,
+ <<ifelse($1,uint,unsigned int,
+ <<ifelse($1,int64,long long,
+ <<ifelse($1,uint64,unsigned long long,
+ <<ifelse($1,string,char *,
+ <<ifelse($1,voidp,void *,
+ <<ifelse($1,MPI_Comm,MPI_Comm,
+ <<ifelse($1,MPI_Info,MPI_Info,
+ )>>)>>)>>)>>)>>)>>)>>)>>)>>)>>)>>)>>)>>)>>)>>)>>)>>)>>)>>)>>)>>)
+
+dnl CSTAR(io, rank)
+define(<<CSTAR>>, <<ifelse($1,input,,<<ifelse($2,0,*)>>)>>)
+
+dnl FTYPE(type, rank)
+define(<<FTYPE>>,
+ <<ifelse($1,text,<<character*ifelse($2,0,1,(*))>>,
+ <<ifelse($1,schar,integer*1,
+ <<ifelse($1,short,integer*2,
+ <<ifelse($1,int,integer,
+ <<ifelse($1,nc_type,integer,
+ <<ifelse($1,size_t,integer(kind=MPI_OFFSET),
+ <<ifelse($1,ptrdiff_t,integer(kind=MPI_OFFSET),
+ <<ifelse($1,long,integer,
+ <<ifelse($1,int64,integer*8,
+ <<ifelse($1,float,real,
+ <<ifelse($1,double,doubleprecision,
+ <<ifelse($1,ubyte,integer*1,
+ <<ifelse($1,ushort,integer*2,
+ <<ifelse($1,uint,integer*4,
+ <<ifelse($1,int64,integer*8,
+ <<ifelse($1,uint64,integer*8,
+ <<ifelse($1,string,character*,
+ <<ifelse($1,voidp,void *,
+ <<ifelse($1,MPI_Comm,integer,
+ <<ifelse($1,MPI_Info,integer,
+)>>)>>)>>)>>)>>)>>)>>)>>)>>)>>)>>)>>)>>)>>)>>)>>)>>)>>)>>)>>)
+
+dnl ATYPE(io,rank,type)
+define(<<ATYPE>>, <<ifelse(API,C,
+ <<CTYPE($3)<<>>CSTAR($1,$2)>>,
+ <<FTYPE($3,$2)>>)>>)
+
+dnl AID(name, rank, type)
+define(<<AID>>, <<ARG($1)<<>>ifelse(API,C,
+ <<ifelse($2,0,,[])>>,
+ <<ifelse($3,text,,<<ifelse($2,0,,(1))>>)>>)>>)
+
+dnl ADECL(io, rank, type, name)
+define(<<ADECL>>, <<AQUAL($1,$2)ATYPE($1,$2,$3) AID($4,$2,$3)>>)
+
+define(<<ITEXT>>, <<ADECL(input,0,text,$1)>>)
+define(<<ITEXTV>>, <<ADECL(input,1,text,$1)>>)
+define(<<OTEXT>>, <<ADECL(output,0,text,$1)>>)
+define(<<OTEXTV>>, <<ADECL(output,1,text,$1)>>)
+
+define(<<IUCHAR>>, <<ADECL(input,0,uchar,$1)>>)
+define(<<IUCHARV>>, <<ADECL(input,1,uchar,$1)>>)
+define(<<OUCHAR>>, <<ADECL(output,0,uchar,$1)>>)
+define(<<OUCHARV>>, <<ADECL(output,1,uchar,$1)>>)
+
+define(<<ISCHAR>>, <<ADECL(input,0,schar,$1)>>)
+define(<<ISCHARV>>, <<ADECL(input,1,schar,$1)>>)
+define(<<OSCHAR>>, <<ADECL(output,0,schar,$1)>>)
+define(<<OSCHARV>>, <<ADECL(output,1,schar,$1)>>)
+
+define(<<ISHORT>>, <<ADECL(input,0,short,$1)>>)
+define(<<ISHORTV>>, <<ADECL(input,1,short,$1)>>)
+define(<<OSHORT>>, <<ADECL(output,0,short,$1)>>)
+define(<<OSHORTV>>, <<ADECL(output,1,short,$1)>>)
+
+define(<<IINT>>, <<ADECL(input,0,int,$1)>>)
+define(<<IINTV>>, <<ADECL(input,1,int,$1)>>)
+define(<<OINT>>, <<ADECL(output,0,int,$1)>>)
+define(<<OINTV>>, <<ADECL(output,1,int,$1)>>)
+
+define(<<IINT64>>, <<ADECL(input,0,int64,$1)>>)
+define(<<IINT64V>>, <<ADECL(input,1,int64,$1)>>)
+define(<<OINT64>>, <<ADECL(output,0,int64,$1)>>)
+define(<<OINT64V>>, <<ADECL(output,1,int64,$1)>>)
+
+define(<<INCTYPE>>, <<ADECL(input,0,nc_type,$1)>>)
+define(<<INCTYPEV>>, <<ADECL(input,1,nc_type,$1)>>)
+define(<<ONCTYPE>>, <<ADECL(output,0,nc_type,$1)>>)
+define(<<ONCTYPEV>>, <<ADECL(output,1,nc_type,$1)>>)
+
+define(<<ISIZET>>, <<ADECL(input,0,size_t,$1)>>)
+define(<<ISIZETV>>, <<ADECL(input,1,size_t,$1)>>)
+define(<<OSIZET>>, <<ADECL(output,0,size_t,$1)>>)
+define(<<OSIZETV>>, <<ADECL(output,1,size_t,$1)>>)
+
+define(<<IPTRDIFFT>>, <<ADECL(input,0,ptrdiff_t,$1)>>)
+define(<<IPTRDIFFTV>>, <<ADECL(input,1,ptrdiff_t,$1)>>)
+define(<<ISIZETV>>, <<ADECL(input,1,size_t,$1)>>)
+define(<<OPTRDIFFT>>, <<ADECL(output,0,ptrdiff_t,$1)>>)
+define(<<OPTRDIFFTV>>, <<ADECL(output,1,ptrdiff_t,$1)>>)
+
+define(<<ILONG>>, <<ADECL(input,0,long,$1)>>)
+define(<<ILONGV>>, <<ADECL(input,1,long,$1)>>)
+define(<<OLONG>>, <<ADECL(output,0,long,$1)>>)
+define(<<OLONGV>>, <<ADECL(output,1,long,$1)>>)
+
+define(<<IFLOAT>>, <<ADECL(input,0,float,$1)>>)
+define(<<IFLOATV>>, <<ADECL(input,1,float,$1)>>)
+define(<<OFLOAT>>, <<ADECL(output,0,float,$1)>>)
+define(<<OFLOATV>>, <<ADECL(output,1,float,$1)>>)
+
+define(<<IDOUBLE>>, <<ADECL(input,0,double,$1)>>)
+define(<<IDOUBLEV>>, <<ADECL(input,1,double,$1)>>)
+define(<<ODOUBLE>>, <<ADECL(output,0,double,$1)>>)
+define(<<ODOUBLEV>>, <<ADECL(output,1,double,$1)>>)
+
+define(<<IUBYTE>>, <<ADECL(input,0,ubyte,$1)>>)
+define(<<IUBYTEV>>, <<ADECL(input,1,ubyte,$1)>>)
+define(<<OUBYTE>>, <<ADECL(output,0,ubyte,$1)>>)
+define(<<OUBYTEV>>, <<ADECL(output,1,ubyte,$1)>>)
+
+define(<<IUSHORT>>, <<ADECL(input,0,ushort,$1)>>)
+define(<<IUSHORTV>>, <<ADECL(input,1,ushort,$1)>>)
+define(<<OUSHORT>>, <<ADECL(output,0,ushort,$1)>>)
+define(<<OUSHORTV>>, <<ADECL(output,1,ushort,$1)>>)
+
+define(<<IUINT>>, <<ADECL(input,0,uint,$1)>>)
+define(<<IUINTV>>, <<ADECL(input,1,uint,$1)>>)
+define(<<OUINT>>, <<ADECL(output,0,uint,$1)>>)
+define(<<OUINTV>>, <<ADECL(output,1,uint,$1)>>)
+
+define(<<IINT64>>, <<ADECL(input,0,int64,$1)>>)
+define(<<IINT64V>>, <<ADECL(input,1,int64,$1)>>)
+define(<<OINT64>>, <<ADECL(output,0,int64,$1)>>)
+define(<<OINT64V>>, <<ADECL(output,1,int64,$1)>>)
+
+define(<<IUINT64>>, <<ADECL(input,0,uint64,$1)>>)
+define(<<IUINT64V>>, <<ADECL(input,1,uint64,$1)>>)
+define(<<OUINT64>>, <<ADECL(output,0,uint64,$1)>>)
+define(<<OUINT64V>>, <<ADECL(output,1,uint64,$1)>>)
+
+define(<<ISTRING>>, <<ADECL(input,0,string,$1)>>)
+define(<<ISTRINGV>>, <<ADECL(input,1,string,$1)>>)
+define(<<OSTRING>>, <<ADECL(output,0,string,$1)>>)
+define(<<OSTRINGV>>, <<ADECL(output,1,string,$1)>>)
+
+define(<<IVOIDP>>, <<ADECL(input,0,voidp,$1)>>)
+define(<<IVOIDPV>>, <<ADECL(input,1,voidp,$1)>>)
+define(<<OVOIDP>>, <<ADECL(output,0,voidp,$1)>>)
+define(<<OVOIDPV>>, <<ADECL(output,1,voidp,$1)>>)
+
+define(<<IMPICOMM>>, <<ADECL(input,0,MPI_Comm,$1)>>)
+define(<<OMPICOMM>>, <<ADECL(output,0,MPI_Comm,$1)>>)
+define(<<IMPIINFO>>, <<ADECL(input,0,MPI_Info,$1)>>)
+define(<<OMPIINFO>>, <<ADECL(output,0,MPI_Info,$1)>>)
+
+dnl CCOMP(type)
+define(<<CCOMP>>,
+ <<ifelse($1,text,text,
+ <<ifelse($1,uchar,uchar,
+ <<ifelse($1,schar,schar,
+ <<ifelse($1,short,short,
+ <<ifelse($1,int,int,
+ <<ifelse($1,long,long,
+ <<ifelse($1,float,float,
+ <<ifelse($1,double,double,
+ <<ifelse($1,ubyte,ubyte,
+ <<ifelse($1,ushort,ushort,
+ <<ifelse($1,uint,uint,
+ <<ifelse($1,int64,int64,
+ <<ifelse($1,uint64,uint64,
+ <<ifelse($1,string,string,
+ <<ifelse($1,voidp,void *,
+)>>)>>)>>)>>)>>)>>)>>)>>)>>)>>)>>)>>)>>)>>)>>)
+
+dnl FCOMP(type)
+define(<<FCOMP>>,
+ <<ifelse($1,text,text,
+ <<ifelse($1,schar,int1,
+ <<ifelse($1,short,int2,
+ <<ifelse($1,int,int,
+ <<ifelse($1,float,real,
+ <<ifelse($1,double,double,
+ <<ifelse($1,ubyte,ubyte,
+ <<ifelse($1,ushort,ushort,
+ <<ifelse($1,uint,uint,
+ <<ifelse($1,uint64,uint64,
+ <<ifelse($1,string,string,
+ <<ifelse($1,voidp,any,
+)>>)>>)>>)>>)>>)>>)>>)>>)>>)>>)>>)>>)
+
+dnl COMP(type)
+define(<<COMP>>, <<ifelse(API,C,<<CCOMP($1)>>,<<FCOMP($1)>>)>>)
+
+define(<<FDECL_TYPE>>,
+ <<ifelse(API,C,
+ int,
+ integer function)>>)
+
+dnl DECL(return-type, name, argument-list)
+define(<<DECL>>, <<CODE($1 FNAME($2)$3)>>)
+
+dnl FDECL(name, argument-list)
+define(<<FDECL>>, <<DECL(FDECL_TYPE, $1, $2)
+
+FOLD($1)>>)
+
+dnl IODECL(name, type, argument-list)
+define(<<IODECL>>, <<FDECL($1_<<>>COMP($2), $3)>>)
+
+dnl FREF(name)
+define(<<FREF>>, <<CODE(FNAME($1)(\|))>>)
+
+dnl FOLD(cname, fname)
+define(<<FOLD>>, <<(Corresponds to CODE(ifelse(API,C, nc_$1, nf_$1)(\|)) in netCDF)>>)
+
+dnl Function Input Arguments:
+define(<<IATTNUM>>, <<IINT(attnum)>>)
+define(<<ICMODE>>, <<IINT(cmode)>>)
+define(<<ICOUNT>>, <<ISIZETV(count)>>)
+define(<<IDIMID>>, <<IINT(dimid)>>)
+define(<<IDIMIDS>>, <<IINTV(dimids)>>)
+define(<<IFILLMODE>>, <<IINT(fillmode)>>)
+define(<<IH_MINFREE>>, <<ISIZET(h_minfree)>>)
+define(<<IINDEX>>, <<ISIZETV(index)>>)
+define(<<IINITSIZE>>, <<ISIZET(initialsize)>>)
+define(<<ILEN>>, <<ISIZET(<<len>>)>>)
+define(<<IIMAP>>, <<IPTRDIFFTV(imap)>>)
+define(<<IMODE>>, <<IINT(mode)>>)
+define(<<INAME>>, <<ITEXTV(name)>>)
+define(<<INCID>>, <<IINT(ncid)>>)
+define(<<INCIDIN>>, <<IINT(ncid_in)>>)
+define(<<INCIDOUT>>, <<IINT(ncid_out)>>)
+define(<<INDIMS>>, <<IINT(ndims)>>)
+define(<<INEWNAME>>, <<ITEXTV(newname)>>)
+define(<<IPATH>>, ITEXTV(path))
+define(<<IPE>>, <<IINT(pe)>>)
+define(<<IR_ALIGN>>, <<ISIZET(r_align)>>)
+define(<<ISTART>>, <<ISIZETV(start)>>)
+define(<<ISTATUS>>, <<IINT(status)>>)
+define(<<ISTRIDE>>, <<ISIZETV(stride)>>)
+define(<<IV_ALIGN>>, <<ISIZET(v_align)>>)
+define(<<IV_MINFREE>>, <<ISIZET(v_minfree)>>)
+define(<<IVARID>>, <<IINT(varid)>>)
+define(<<IVARIDIN>>, <<IINT(varid_in)>>)
+define(<<IVARIDOUT>>, <<IINT(varid_out)>>)
+define(<<IXTYPE>>, <<INCTYPE(xtype)>>)
+define(<<IPARACCESS>>, <<IINT(par_access)>>)
+
+define(<<ICOMM>>, <<IMPICOMM(comm)>>)
+define(<<IINFO>>, <<IMPIINFO(info)>>)
+
+dnl Function Output Arguments:
+define(<<OATTNUM>>, <<OINT(attnum)>>)
+define(<<OCHUNKSIZE>>, <<OSIZET(chunksize)>>)
+define(<<ODIMID>>, <<OINT(dimid)>>)
+define(<<ODIMIDS>>, <<OINTV(dimids)>>)
+define(<<OLEN>>, <<OSIZET(<<len>>)>>)
+define(<<ONAME>>, <<OTEXTV(name)>>)
+define(<<ONATTS>>, <<OINT(natts)>>)
+define(<<ONCID>>, <<OINT(ncid)>>)
+define(<<ONDIMS>>, <<OINT(ndims)>>)
+define(<<ONVARS>>, <<OINT(nvars)>>)
+define(<<OOLDFILLMODE>>, <<OINT(old_fillemode)>>)
+define(<<OPE>>, <<OINT(pe)>>)
+define(<<OVARID>>, <<OINT(varid)>>)
+define(<<OUNLIMDIMID>>, <<OINT(unlimdimid)>>)
+define(<<OFORMATN>>, <<OINT(formatn)>>)
+define(<<OXTYPE>>, <<ONCTYPE(xtype)>>)
+
+dnl Argument References:
+define(<<ATTNUM>>, <<ARG(attnum)>>)
+define(<<COUNT>>, <<ARG(count)>>)
+define(<<DIMID>>, <<ARG(dimid)>>)
+define(<<DIMIDS>>, <<ARG(dimids)>>)
+define(<<FILLMODE>>, <<ARG(fillmode)>>)
+define(<<IN>>, <<ARG(in)>>)
+define(<<INDEX>>, <<ARG(index)>>)
+define(<<LEN>>, <<ARG(<<len>>)>>)
+define(<<IMAP>>, <<ARG(imap)>>)
+define(<<NAME>>, <<ARG(name)>>)
+define(<<NATTS>>, <<ARG(natts)>>)
+define(<<NCID>>, <<ARG(ncid)>>)
+define(<<NCIDIN>>, <<ARG(ncid_in)>>)
+define(<<NCIDOUT>>, <<ARG(ncid_out)>>)
+define(<<NDIMS>>, <<ARG(ndims)>>)
+define(<<NEWNAME>>, <<ARG(newname)>>)
+define(<<NULL>>, <<CODE(<<<<NULL>>>>)>>)
+define(<<NVARS>>, <<ARG(nvars)>>)
+define(<<NVATTS>>, <<ARG(nvatts)>>)
+define(<<OLDFILLMODE>>, <<ARG(old_fillmode)>>)
+define(<<OUT>>, <<ARG(out)>>)
+define(<<START>>, <<ARG(start)>>)
+define(<<STRIDE>>, <<ARG(stride)>>)
+define(<<UNLIMDIMID>>, <<ARG(unlimdimid)>>)
+define(<<FORMATN>>, <<ARG(formatn)>>)
+define(<<VARID>>, <<ARG(varid)>>)
+define(<<VARIDIN>>, <<ARG(varid_in)>>)
+define(<<VARIDOUT>>, <<ARG(varid_out)>>)
+define(<<XTYPE>>, <<ARG(xtype)>>)
+
+define(<<UPCASE>>,
+<<translit($1,abcdefghijklmnopqrstuvwxyz,ABCDEFGHIJKLMNOPQRSTUVWXYZ)>>)
+
+dnl Variable "Put" Functions:
+define(<<VOUT>>, <<I<<>>UPCASE($1)<<>>ifelse($2,1,,V)(ifelse($2,1,*)out)>>)
+define(<<VPUT>>, <<IODECL(put_var$1, $2, (INCID(), IVARID()$3, VOUT($2,$1)))>>)
+define(<<PUT_VAR>>, <<VPUT(,$1)>>)
+define(<<PUT_VAR1>>,<<VPUT(1,$1,<<, IINDEX()>>)>>)
+define(<<PUT_VARA>>,<<VPUT(a,$1,<<, ISTART(), ICOUNT()>>)>>)
+define(<<PUT_VARS>>,<<VPUT(s,$1,<<, ISTART(), ICOUNT(), ISTRIDE()>>)>>)
+define(<<PUT_VARM>>,<<VPUT(m,$1,<<, ISTART(), ICOUNT(), ISTRIDE(), IIMAP()>>)>>)
+
+dnl Variable "Get" Functions:
+define(<<VIN>>, <<O<<>>UPCASE($1)<<>>ifelse($2,1,,V)(in)>>)
+define(<<VGET>>, <<IODECL(get_var$1, $2, (INCID(), IVARID()$3, VIN($2,$1)))>>)
+define(<<GET_VAR>>, <<VGET(,$1)>>)
+define(<<GET_VAR1>>,<<VGET(1,$1,<<, IINDEX()>>)>>)
+define(<<GET_VARA>>,<<VGET(a,$1,<<, ISTART(), ICOUNT()>>)>>)
+define(<<GET_VARS>>,<<VGET(s,$1,<<, ISTART(), ICOUNT(), ISTRIDE()>>)>>)
+define(<<GET_VARM>>,<<VGET(m,$1,<<, ISTART(), ICOUNT(), ISTRIDE(), IIMAP()>>)>>)
+
+dnl Attribute "Put" Functions:
+define(<<AOUT>>, <<I<<>>UPCASE($1)<<>>V(out)>>)
+define(<<APUT>>,<<IODECL(put_att,$1,(INCID(), IVARID(), INAME(), IXTYPE(), ILEN(), AOUT($1)))>>)
+
+dnl Attribute "Get" Functions:
+define(<<AIN>>, <<O<<>>UPCASE($1)<<>>V(in)>>)
+define(<<AGET>>,<<IODECL(get_att,$1,(INCID(), IVARID(), INAME(), AIN($1)))>>)
+
+dnl Function Family Listing:
+define(<<FUNC_FAMILY>>,
+<<.HP
+$1(text)
+ifelse(API,C,
+<<.HP
+$1(uchar)>>)
+.HP
+$1(schar)
+.HP
+$1(short)
+.HP
+$1(int)
+ifelse(API,C,
+<<.HP
+$1(long)>>)
+.HP
+$1(float)
+.HP
+$1(double)
+ifelse(NETCDF4,TRUE,
+<<.HP
+$1(ubyte)
+.HP
+$1(ushort)
+.HP
+$1(uint)
+.HP
+$1(int64)
+.HP
+$1(uint64)
+.HP
+$1(string)>>
+)
+>>)
+
+divert(0)dnl
+.nr yr \n(yr+1900
+.af mo 01
+.af dy 01
+.TH PNETCDF 3 RELEASE_DATE "Printed: \n(yr-\n(mo-\n(dy" "LIBRARY FUNCTIONS"
+.SH N<<>>AME
+PnetCDF \- Parallel library for accessing files in Network Common Data Form (CDF, CDF-2 and CDF-5 formats)
+.SH SYNOPSIS
+.ft B
+.na
+.nh
+INCLUDE(pnetcdf)
+.sp
+ifelse(API,C,,
+.SS Most Systems:)
+COMPILER() ... -lpnetcdf
+ifelse(API,C,,
+.sp
+.SS CRAY PVP Systems:
+f90 -dp -i64 ... -lnetcdf
+)
+.ad
+.hy
+Complete documentation for the PnetCDF libraries can be found at the PnetCDF website: http://cucis.ece.northwestern.edu/projects/PnetCDF/.
+.sp
+.SH "LIBRARY VERSION"
+.LP
+This document describes Parallel netCDF APIs
+for the LANGUAGE() programming language.
+.HP
+DECL(RETSTR(), inq_libvers, (VOID_ARG))
+.sp
+FOLD(inq_libvers)
+.sp
+Returns a string identifying the version of the PnetCDF library, and
+when it was built, like: "RELEASE_STR".
+.LP
+The RCS \fBident(1)\fP command will find a string like
+"$\|Id: @\|(#) PnetCDF library version
+RELEASE_STR $"
+in the library. The SCCS \fBwhat(1)\fP command will find a string like
+"PnetCDF library version RELEASE_STR".
+.SH "RETURN VALUES"
+.LP
+All PnetCDF functions (except
+FREF(inq_libvers) and FREF(strerror)) return an integer status.
+
+If this returned status value is not equal to
+MACRO(NOERR) (zero), it
+indicates that an error occurred. The possible status values are defined in
+ifelse(API,C, system <<<<include>>>> file <errno.h> and in )<<>>dnl
+ifelse(API,C,")HEADER_FILE(pnetcdf)<<>>ifelse(API,C,").
+.HP
+DECL(RETSTR(), strerror, (ISTATUS()))
+.sp
+FOLD(strerror)
+.sp
+Returns a string textual translation of the \fIstatus\fP
+value, like "Attribute or variable name contains illegal characters"
+or "No such file or directory".
+.sp
+.SH "FILE OPERATIONS"
+.LP
+.HP
+FDECL(create, (ICOMM(), IPATH(), ICMODE(), IINFO(), ONCID()))
+.sp
+Creates a new netCDF dataset at ARG(path) collectively by a group of MPI
+processes specified by ARG(comm), returning a netCDF ID in ARG(ncid). The
+argument ARG(cmode) may <<include>> the bitwise-or of the following flags:
+MACRO(NOCLOBBER) to protect existing datasets (default is MACRO(CLOBBER),
+silently blows them away), MACRO(SHARE) for stronger metadata data consistency
+control, MACRO(64BIT_OFFSET) to create a file in the 64-bit offset format
+(CDF-2), as opposed to classic format, the default, or MACRO(64BIT_DATA) to
+create a file in the 64-bit data format (CDF-5).
+Use either MACRO(64BIT_OFFSET) or MACRO(64BIT_DATA).
+The 64-bit offset format allows the creation of very large files with far fewer
+restrictions than netCDF classic format, but can only be read by the netCDF
+library version 3.6 or greater. Users are cautioned that files that use the
+64-bit offset format will not be recognized by netCDF applications linked to an
+earlier version of the netCDF library than 3.6. Applications linked to version
+3.6 or later will be able to transparently access either the classic format or
+64-bit offset format.
+The 64-bit data format allows the creation of very large array variables.
+CDF-5 files currently will not be recognized by netCDF 3 or 4 library.
+ifelse(NETCDF4,TRUE,
+<<MACRO(NETCDF4) to create a netCDF-4/HDF5 file,
+and MACRO(CLASSIC_MODEL) to guarantee that netCDF-4/HDF5 files maintain compatibility
+with the netCDF classic data model.>>,
+.
+)
+The argument ARG(cmode) must be consistent among all MPI processes that
+collectively create the file. The argument ARG(info) is an MPI info object.
+Users can use it to supply the file access hints further performance
+improvement. The hints include existing MPI-IO hints as well as hints defined
+and used in PnetCDF.
+.sp
+When a netCDF dataset is created, it is opened in MACRO(WRITE) mode.
+When this function returns, the new netCDF dataset is in <<define>> mode.
+.HP
+FDECL(open, (ICOMM(), IPATH(), IMODE(), IINFO(), ONCID()))
+.sp
+Opens an existing netCDF dataset at ARG(path) collectively by a group of MPI
+processes specified by ARG(comm), returning a netCDF ID in ARG(ncid). The type
+of access is described by the ARG(mode) parameter, which may <<include>> the
+bitwise-or of the following flags: MACRO(WRITE) for read-write access (default
+read-only), MACRO(SHARE) for stronger metadata data consistency control.
+.sp
+ifelse(DAP,TRUE,
+<<As of NetCDF version 4.1, and if DAP support was enabled
+when the NetCDF library was built, the path parameter
+may specify a DAP URL. In this case, the access mode is
+forced to be read-only.>>)
+The argument ARG(mode) must be consistent among all MPI processes that
+collectively open the file. The argument ARG(info) is an MPI info object.
+Users can use it to supply the file access hints further performance
+improvement. The hints include existing MPI-IO hints as well as hints defined
+and used in PnetCDF.
+.HP
+FDECL(redef, (INCID()))
+.sp
+Puts an open netCDF dataset into <<define>> mode,
+so dimensions, variables, and attributes can be added or renamed and
+attributes can be deleted.
+.HP
+FDECL(enddef, (INCID()))
+.sp
+Takes an open netCDF dataset out of <<define>> mode.
+The changes made to the netCDF dataset
+while it was in <<define>> mode are checked and committed to disk if no
+problems occurred.
+After a successful call, variable data can be read or written to the dataset.
+.HP
+FDECL(sync, (INCID()))
+.sp
+Unless the
+MACRO(SHARE)
+bit is set in
+FREF(open) or FREF(create),
+data written by PnetCDF APIs may be cached by local file system on each compute
+node. This <<API>> flushes cached data by calling MPI_File_sync.
+.HP
+FDECL(abort, (INCID()))
+.sp
+You don't need to call this function. This function is called automatically by
+FREF(close) if the netCDF was in <<define>> mode and something goes wrong with
+the commit. If the netCDF dataset isn't in <<define>> mode, then this function
+is equivalent to FREF(close). If it is called after FREF(redef), but before
+FREF(enddef), the new definitions are not committed and the dataset is closed.
+If it is called after FREF(create) but before FREF(enddef), the dataset
+disappears.
+.HP
+FDECL(close, (INCID()))
+.sp
+Closes an open netCDF dataset. If the dataset is in <<define>> mode,
+FREF(enddef) will be called before closing. After a dataset is closed, its ID
+may be reassigned to another dataset.
+.HP
+FDECL(inq, (INCID(), ONDIMS(), ONVARS(),
+ONATTS(), OUNLIMDIMID()))
+.HP
+FDECL(inq_ndims, (INCID(), ONDIMS()))
+.HP
+FDECL(inq_nvars, (INCID(), ONVARS()))
+.HP
+FDECL(inq_natts, (INCID(), ONATTS()))
+.HP
+FDECL(inq_unlimdim, (INCID(), OUNLIMDIMID()))
+.HP
+FDECL(inq_format, (INCID(), OFORMATN()))
+.sp
+Use these functions to find out what is in a netCDF dataset.
+Upon successful return,
+NDIMS() will contain the
+number of dimensions defined for this netCDF dataset,
+NVARS() will contain the number of variables,
+NATTS() will contain the number of attributes, and
+UNLIMDIMID() will contain the
+dimension ID of the unlimited dimension if one exists, or
+ifelse(API,C, <<-1>>, <<0>>) otherwise.
+FORMATN() will contain the version number of the dataset <format>, one of
+MACRO(FORMAT_CLASSIC), MACRO(FORMAT_64BIT), or MACRO(FORMAT_64BIT_DATA).
+ifelse(API,C,
+<<If any of the
+return parameters is a NULL() pointer, then the corresponding information
+will not be returned; hence, no space need be allocated for it.>>)
+.HP
+FDECL(def_dim, (INCID(), INAME(), ILEN(), ODIMID()))
+.sp
+Adds a new dimension to an open netCDF dataset, which must be
+in <<define>> mode.
+NAME() is the dimension name.
+ifelse(API,C,dnl
+<<If DIMID() is not a NULL() pointer then upon successful completion >>)<<>>dnl
+DIMID() will contain the dimension ID of the newly created dimension.
+ifelse(NETCDF4,TRUE,
+<<
+.SH "USER DEFINED TYPES"
+.LP
+Users many define types for a netCDF-4/HDF5 file (unless the
+MACRO(CLASSIC_MODEL) was used when the file was creates). Users may
+define compound types, variable length arrays, enumeration types, and
+opaque types.
+.sp
+
+.HP
+FDECL(def_compound, (INCID(), ISIZET(size), INAME(), OINT(typeidp)))
+.sp
+Define a compound type.
+.HP
+FDECL(insert_compound, (INCID(), INCTYPE(), INAME(), ISIZET(offset), INCTYPE(field_typeid)))
+.sp
+Insert an element into a compound type. May not be done after type has been used, or after the type has been written by an enddef.
+.HP
+FDECL(insert_array_compound, (INCID(), INCTYPE(), INAME(), ISIZET(offset), INCTYPE(field_typeid), INDIMS(), IINTV(dim_sizes)))
+.sp
+Insert an array into a compound type.
+.HP
+FDECL(inq_type, (INCID(), INCTYPE(), ONAME(), OSIZET(sizep)))
+.sp
+Learn about a type.
+.HP
+FDECL(inq_compound, (INCID(), INCTYPE(), ONAME(), OSIZET(sizep), OSIZET(nfieldsp)))
+.HP
+FDECL(inq_compound_name, (INCID(), INCTYPE(), ONAME()))
+.HP
+FDECL(inq_compound_size, (INCID(), INCTYPE(), OSIZET(sizep)))
+.HP
+FDECL(inq_compound_nfields, (INCID(), INCTYPE(), OSIZET(nfieldsp)))
+.HP
+FDECL(inq_compound_fieldname, (INCID(), INCTYPE(), IINT(fieldid), ONAME()))
+.HP
+FDECL(inq_compound_fieldindex, (INCID(), INCTYPE(), INAME(), OINT(fieldidp)))
+.HP
+FDECL(inq_compound_fieldoffset, (INCID(), INCTYPE(), IINT(fieldid), OSIZET(offsetp)))
+.HP
+FDECL(inq_compound_fieldtype, (INCID(), INCTYPE(), IINT(fieldid), ONCTYPE(field_typeid)))
+.HP
+FDECL(inq_compound_fieldndims, (INCID(), INCTYPE(), IINT(fieldid), ONDIMS()))
+.HP
+FDECL(inq_compound_fielddim_sizes, (INCID(), INCTYPE(), IINT(fieldid), OINTV(dim_sizes)))
+.sp
+Learn about a compound type.
+.HP
+FDECL(def_vlen, (INCID(), INAME(), INCTYPE(base_typeid), ONCTYPE(xtypep)))
+.sp
+Create a varaible length array type.
+.HP
+FDECL(inq_vlen, (INCID(), INCTYPE(), ONAME(), OSIZET(datum_sizep), ONCTYPE(base_nc_typep)))
+.sp
+Learn about a varaible length array type.
+.HP
+FDECL(free_vlen, (nc_vlen_t *vl))
+.sp
+Free memory consumed by reading data of a variable length array type.
+.HP
+FDECL(put_vlen_element, (INCID(), INCTYPE(), IVOIDP(vlen_element), ISIZET(len), IVOIDP(data)))
+.sp
+Write one VLEN.
+.HP
+FDECL(get_vlen_element, (INCID(), INCTYPE(), OVOIDP(vlen_element), ISIZET(len), OVOIDP(data)))
+.sp
+Read one VLEN.
+.HP
+FDECL(free_string, (ISIZET(len), char **data))
+.sp
+Free memory consumed by reading data of a string type.
+.HP
+FDECL(inq_user_type, (INCID(), INCTYPE(), ONAME(), OSIZET(), ONCTYPE(), OSIZET(), OINT()))
+.sp
+Learn about a user define type.
+.HP
+FDECL(def_enum, (INCID(), INCTYPE(base_typeid), INAME(), ONCTYPE(typeidp)))
+.sp
+Define an enumeration type.
+.HP
+FDECL(insert_enum, (INCID(), INCTYPE(base_typeid), INAME(), const void *value))
+.sp
+Insert a name-value pair into enumeration type.
+.HP
+FDECL(inq_enum_member, (INCID(), INCTYPE(xtype), IINT(idx), ONAME(), void *value))
+.HP
+FDECL(inq_enum_ident, (INCID(), INCTYPE(xtype), IINT(idx), IINT64(value), OTEXTV(identifier)))
+.sp
+Learn about a name-value pair into enumeration type.
+.HP
+FDECL(def_opaque, (INCID(), ISIZET(size), INAME(), ONCTYPE(xtypep)))
+.sp
+Create an opaque type.
+.HP
+FDECL(inq_opaque, (INCID(), INCTYPE(xtype), ONAME(), OSIZET(sizep)))
+.sp
+Learn about opaque type.
+.HP
+.SH "GROUPS"
+.sp
+Users may organize data into hierarchical groups in netCDF-4/HDF5 files (unless MACRO(CLASSIC_MODEL) was used when creating the file).
+.HP
+FDECL(inq_grps, (INCID(), OINT(numgrps), OINTV(ncids)))
+.sp
+Learn how many groups (and their ncids) are available from the group represented by ncid.
+.HP
+FDECL(inq_grpname, (INCID(), ONAME()))
+.HP
+FDECL(inq_grpname_full, (INCID(), OLEN(), ONAME()))
+.HP
+FDECL(inq_grpname_len, (INCID(), OLEN()))
+.HP
+FDECL(inq_grp_parent, (INCID(), ONCID()))
+.HP
+FDECL(inq_grp_ncid, (INCID(), ONAME(), ONCID()))
+.HP
+FDECL(inq_full_ncid, (INCID(), ONAME(), ONCID()))
+.sp
+Learn about a group.
+.HP
+FDECL(inq_varids, (INCID(), ONVARS(), OINT()))
+.sp
+Get the varids in a group.
+.HP
+FDECL(inq_dimids, (INCID(), ONDIMS(), OINT(dimids), IINT(include_parents)))
+.sp
+Get the dimids in a group and (potentially) its parents.
+.HP
+FDECL(inq_typeids, (INCID(), OINT(ntypes), OINTV(typeids)))
+.sp
+Get the typeids of user-defined types in a group.
+.HP
+FDECL(def_grp, (INCID(), ONAME(), ONCID()))
+.sp
+Create a group.
+.LP
+>>)
+.SH "DIMENSIONS"
+.LP
+.HP
+FDECL(inq_dimid, (INCID(), INAME(), ODIMID()))
+.sp
+Given a dimension name, returns the ID of a netCDF dimension in DIMID().
+.HP
+FDECL(inq_dim, (INCID(), IDIMID(), ONAME(), OLEN()))
+.HP
+FDECL(inq_dimname, (INCID(), IDIMID(), ONAME()))
+.HP
+FDECL(inq_dimlen, (INCID(), IDIMID(), OLEN()))
+.sp
+Use these functions to find out about a dimension.
+ifelse(API,C,
+<<If either the NAME()
+argument or LEN() argument is a NULL() pointer, then
+the associated information will not be returned. Otherwise,>>)
+NAME() should be big enough (MACRO(MAX_NAME))
+to hold the dimension name as the name will be copied into your storage.
+The length return parameter, LEN()
+will contain the size of the dimension.
+For the unlimited dimension, the returned length is the current
+maximum value used for writing into any of the variables which use
+the dimension.
+.HP
+FDECL(rename_dim, (INCID(), IDIMID(), INAME()))
+.sp
+Renames an existing dimension in an open netCDF dataset.
+If the new name is longer than the old name, the netCDF dataset must be in
+<<define>> mode.
+You cannot rename a dimension to have the same name as another dimension.
+.SH "VARIABLES"
+.LP
+.HP
+FDECL(def_var, (INCID(), INAME(), IXTYPE(), INDIMS(), IDIMIDS(), OVARID()))
+.sp
+Adds a new variable to a netCDF dataset. The netCDF must be in <<define>> mode.
+ifelse(API,C, <<If not NULL(), then >>)dnl
+VARID() will be set to the netCDF variable ID.
+\fIndims\fP will be the number of dimensions for the variable.
+\fIname\fP will be the name of the netCDF variable.
+\fIxtype\fP is the external, netCDF type of the variable and should be one of
+MACRO(BYTE)
+MACRO(CHAR),
+MACRO(SHORT),
+MACRO(INT),
+MACRO(FLOAT), or
+MACRO(DOUBLE),
+for CDF-1 and CDF-2 file formats.
+CDF-5 defines additional external types:
+MACRO(UBYTE),
+MACRO(USHORT),
+MACRO(UINT),
+MACRO(INT64), and
+MACRO(UINT64).
+\fIdimids\fP argument is a vector of ndims dimension IDs corresponding to the
+variable dimensions.
+.HP
+FDECL(inq_varid, (INCID(), INAME(), OVARID()))
+.sp
+Returns the ID of a netCDF variable in VARID() given its name.
+.HP
+FDECL(inq_var, (INCID(), IVARID(), ONAME(), OXTYPE(), ONDIMS(), ODIMIDS(),
+ONATTS()))
+.HP
+FDECL(inq_varname, (INCID(), IVARID(), ONAME()))
+.HP
+FDECL(inq_vartype, (INCID(), IVARID(), OXTYPE()))
+.HP
+FDECL(inq_varndims, (INCID(), IVARID(), ONDIMS()))
+.HP
+FDECL(inq_vardimid, (INCID(), IVARID(), ODIMIDS()))
+.HP
+FDECL(inq_varnatts, (INCID(), IVARID(), ONATTS()))
+.sp
+Returns information about a netCDF variable, given its ID.
+ifelse(API,C,
+<<If any of the
+return parameters (NAME(), XTYPE(), NDIMS(), DIMIDS(), or
+NATTS()) is a NULL() pointer, then the corresponding information
+will not be returned; hence, no space need be allocated for it.>>)
+.HP
+FDECL(rename_var, (INCID(), IVARID(), INAME()))
+.sp
+Changes the name of a netCDF variable.
+If the new name is longer than the old name, the netCDF must be in <<define>> mode.
+You cannot rename a variable to have the name of any existing variable.
+ifelse(NETCDF4,TRUE,
+<<
+.SH "VARIABLES IN NETCDF-4 FILES"
+.LP
+The following functions may only be used on variables in a
+netCDF-4/HDF5 data file. These functions must be called after the
+variable is defined, but before an enddef call.
+.sp
+FDECL(def_var_deflate, (INCID(), IVARID(), IINT(shuffle), IINT(deflate), IINT(deflate_level)))
+.sp
+Turn on compression and/or shuffle filter. (Shuffle filter is only useful for integer data.)
+.HP
+FDECL(inq_var_deflate, (INCID(), IVARID(), OINT(shufflep), OINT(deflatep), OINT(deflate_levelp)))
+.sp
+Learn about a variable's deflate settings.
+.HP
+FDECL(def_var_fletcher32, (INCID(), IVARID(), IINT(fletcher32)))
+.sp
+Turn on checksumming for a variable.
+.HP
+FDECL(inq_var_fletcher32, (INCID(), IVARID(), OINT(fletcher32)))
+.sp
+Learn about checksumming for a variable.
+.HP
+FDECL(def_var_chunking, (INCID(), IVARID(), IINT(storage), ISIZETV(chunksizesp)))
+.sp
+Set chunksizes for a variable.
+.HP
+FDECL(inq_var_chunking, (INCID(), IVARID(), OINT(storagep), OSIZETV(chunksizesp)))
+.sp
+Learn about chunksizes for a variable.
+.HP
+FDECL(def_var_fill, (INCID(), IVARID(), IINT(no_fill), ISIZETV(chunksizesp)))
+.sp
+Set a fill value for a variable.
+.HP
+FDECL(inq_var_fill, (INCID(), IVARID(), OINT(storagep), OSIZETV(chunksizesp)))
+.sp
+Learn the fill value for a variable.
+.HP
+FDECL(def_var_endian, (INCID(), IVARID(), IINT(endian)))
+.sp
+Set endianness of variable.
+.HP
+FDECL(inq_var_endian, (INCID(), IVARID(), OINT(endianp)))
+.sp
+Learn the endianness of a variable.
+.HP
+>>)
+.SH "WRITING AND READING WHOLE VARIABLES"
+.LP
+FUNC_FAMILY(<<PUT_VAR>>)
+.sp
+Writes an entire netCDF variable (i.e. all the values). The netCDF
+dataset must be open and in data mode. The type of the data is
+specified in the function name, and it is converted to the external
+type of the specified variable, if possible, otherwise an
+MACRO(ERANGE) error is returned. Note that rounding is not performed
+during the conversion. Floating point numbers are truncated when
+converted to integers.
+FUNC_FAMILY(<<GET_VAR>>)
+.sp
+Reads an entire netCDF variable (i.e. all the values).
+The netCDF dataset must be open and in data mode.
+The data is converted from the external type of the specified variable,
+if necessary, to the type specified in the function name. If conversion is
+not possible, an MACRO(ERANGE) error is returned.
+.SH "WRITING AND READING ONE DATUM"
+.LP
+FUNC_FAMILY(<<PUT_VAR1>>)
+.sp
+Puts a single data value into a variable at the position INDEX() of an
+open netCDF dataset that is in data mode. The type of the data is
+specified in the function name, and it is converted to the external type
+of the specified variable, if possible, otherwise an MACRO(ERANGE)
+error is returned.
+FUNC_FAMILY(<<GET_VAR1>>)
+.sp
+Gets a single data value from a variable at the position INDEX()
+of an open netCDF dataset that is in data mode.
+The data is converted from the external type of the specified variable,
+if necessary, to the type specified in the function name. If conversion is
+not possible, an MACRO(ERANGE) error is returned.
+.SH "WRITING AND READING AN ARRAY"
+.LP
+FUNC_FAMILY(<<PUT_VARA>>)
+.sp
+Writes an array section of values into a netCDF variable of an open
+netCDF dataset, which must be in data mode. The array section is specified
+by the START() and COUNT() vectors, which give the starting <<index>>
+and count of values along each dimension of the specified variable.
+The type of the data is
+specified in the function name and is converted to the external type
+of the specified variable, if possible, otherwise an MACRO(ERANGE)
+error is returned.
+FUNC_FAMILY(<<GET_VARA>>)
+.sp
+Reads an array section of values from a netCDF variable of an open
+netCDF dataset, which must be in data mode. The array section is specified
+by the START() and COUNT() vectors, which give the starting <<index>>
+and count of values along each dimension of the specified variable.
+The data is converted from the external type of the specified variable,
+if necessary, to the type specified in the function name. If conversion is
+not possible, an MACRO(ERANGE) error is returned.
+.SH "WRITING AND READING A SLICED ARRAY"
+.LP
+FUNC_FAMILY(<<PUT_VARS>>)
+.sp
+These functions are used for \fIstrided output\fP, which is like the
+array section output described above, except that
+the sampling stride (the interval between accessed values) is
+specified for each dimension.
+For an explanation of the sampling stride
+vector, see COMMON ARGUMENTS DESCRIPTIONS below.
+FUNC_FAMILY(<<GET_VARS>>)
+.sp
+These functions are used for \fIstrided input\fP, which is like the
+array section input described above, except that
+the sampling stride (the interval between accessed values) is
+specified for each dimension.
+For an explanation of the sampling stride
+vector, see COMMON ARGUMENTS DESCRIPTIONS below.
+.SH "WRITING AND READING A MAPPED ARRAY"
+.LP
+FUNC_FAMILY(<<PUT_VARM>>)
+.sp
+These functions are used for \fImapped output\fP, which is like
+strided output described above, except that an additional <<index>> mapping
+vector is provided to specify the in-memory arrangement of the data
+values.
+For an explanation of the <<index>>
+mapping vector, see COMMON ARGUMENTS DESCRIPTIONS below.
+FUNC_FAMILY(<<GET_VARM>>)
+.sp
+These functions are used for \fImapped input\fP, which is like
+strided input described above, except that an additional <<index>> mapping
+vector is provided to specify the in-memory arrangement of the data
+values.
+For an explanation of the <<index>>
+mapping vector, see COMMON ARGUMENTS DESCRIPTIONS below.
+.SH "ATTRIBUTES"
+.LP
+FUNC_FAMILY(<<APUT>>)
+.HP
+FDECL(put_att, (INCID(), IVARID(), INAME(), INCTYPE(xtype), ISIZET(len), IVOIDP(ip)))
+.HP
+FDECL(get_att, (INCID(), IVARID(), INAME(), OVOIDP(ip)))
+.sp
+Unlike variables, attributes do not have
+separate functions for defining and writing values.
+This family of functions defines a new attribute with a value or changes
+the value of an existing attribute.
+If the attribute is new, or if the space required to
+store the attribute value is greater than before,
+the netCDF dataset must be in <<define>> mode.
+The parameter LEN() is the number of values from OUT() to transfer.
+It is often one, except that for
+FREF(put_att_text) it will usually be
+ifelse(API,C, <<CODE(strlen(OUT())).>>, <<CODE(len_trim(OUT())).>>)
+.sp
+For these functions, the type component of the function name refers to
+the in-memory type of the value, whereas the XTYPE() argument refers to the
+external type for storing the value. An MACRO(ERANGE)
+error results if
+a conversion between these types is not possible. In this case the value
+is represented with the appropriate fill-value for the associated
+external type.
+.HP
+FDECL(inq_attname, (INCID(), IVARID(), IATTNUM(), ONAME()))
+.sp
+Gets the
+name of an attribute, given its variable ID and attribute number.
+This function is useful in generic applications that
+need to get the names of all the attributes associated with a variable,
+since attributes are accessed by name rather than number in all other
+attribute functions. The number of an attribute is more volatile than
+the name, since it can change when other attributes of the same variable
+are deleted. The attributes for each variable are numbered
+from ifelse(API,C,0,1) (the first attribute) to
+NVATTS()<<>>ifelse(API,C,-1),
+where NVATTS() is
+the number of attributes for the variable, as returned from a call to
+FREF(inq_varnatts).
+ifelse(API,C,
+<<If the NAME() parameter is a NULL() pointer, no name will be
+returned and no space need be allocated.>>)
+.HP
+FDECL(inq_att, (INCID(), IVARID(), INAME(), OXTYPE(), OLEN()))
+.HP
+FDECL(inq_attid, (INCID(), IVARID(), INAME(), OATTNUM()))
+.HP
+FDECL(inq_atttype, (INCID(), IVARID(), INAME(), OXTYPE()))
+.HP
+FDECL(inq_attlen, (INCID(), IVARID(), INAME(), OLEN()))
+.sp
+These functions return information about a netCDF attribute,
+given its variable ID and name. The information returned is the
+external type in XTYPE()
+and the number of elements in the attribute as LEN().
+ifelse(API,C,
+<<If any of the return arguments is a NULL() pointer,
+the specified information will not be returned.>>)
+.HP
+FDECL(copy_att, (INCID(), IVARIDIN(), INAME(), INCIDOUT(), IVARIDOUT()))
+.sp
+Copies an
+attribute from one netCDF dataset to another. It can also be used to
+copy an attribute from one variable to another within the same netCDF.
+NCIDIN() is the netCDF ID of an input netCDF dataset from which the
+attribute will be copied.
+VARIDIN()
+is the ID of the variable in the input netCDF dataset from which the
+attribute will be copied, or MACRO(GLOBAL)
+for a global attribute.
+NAME()
+is the name of the attribute in the input netCDF dataset to be copied.
+NCIDOUT()
+is the netCDF ID of the output netCDF dataset to which the attribute will be
+copied.
+It is permissible for the input and output netCDF ID's to be the same. The
+output netCDF dataset should be in <<define>> mode if the attribute to be
+copied does not already exist for the target variable, or if it would
+cause an existing target attribute to grow.
+VARIDOUT()
+is the ID of the variable in the output netCDF dataset to which the attribute will
+be copied, or MACRO(GLOBAL) to copy to a global attribute.
+.HP
+FDECL(rename_att, (INCID(), IVARID(), INAME(), INEWNAME()))
+.sp
+Changes the
+name of an attribute. If the new name is longer than the original name,
+the netCDF must be in <<define>> mode. You cannot rename an attribute to
+have the same name as another attribute of the same variable.
+NAME() is the original attribute name.
+NEWNAME()
+is the new name to be assigned to the specified attribute. If the new name
+is longer than the old name, the netCDF dataset must be in <<define>> mode.
+.HP
+FDECL(del_att, (INCID(), IVARID(), INAME()))
+.sp
+Deletes an attribute from a netCDF dataset. The dataset must be in
+<<define>> mode.
+FUNC_FAMILY(<<AGET>>)
+.sp
+Gets the value(s) of a netCDF attribute, given its
+variable ID and name. Converts from the external type to the type
+specified in
+the function name, if possible, otherwise returns an MACRO(ERANGE)
+error.
+All elements of the vector of attribute
+values are returned, so you must allocate enough space to hold
+them. If you don't know how much space to reserve, call
+FREF(inq_attlen)
+first to find out the length of the attribute.
+.SH "COMMON ARGUMENT DESCRIPTIONS"
+.LP
+In this section we <<define>> some common arguments which are used in the
+"FUNCTION DESCRIPTIONS" section.
+.TP
+INCID()
+is the netCDF ID returned from a previous, successful call to
+FREF(open) or FREF(create)
+.TP
+ONAME()
+is the name of a dimension, variable, or attribute. The names of
+dimensions, variables and attributes consist of arbitrary
+sequences of alphanumeric characters (as well as underscore '_',
+period '.' and hyphen '-'), beginning with a letter or
+underscore. (However names commencing with underscore are reserved for
+system use.) Case is significant in netCDF names. A zero-length name
+is not allowed.
+ifelse(API,C,<<As an input argument,
+it shall be a pointer to a 0-terminated string; as an output argument, it
+shall be the address of a buffer in which to hold such a string.>>)
+The maximum allowable number of characters
+ifelse(API,C,(excluding the terminating 0)) is MACRO(MAX_NAME).
+.TP
+IXTYPE()
+specifies the external data type of a netCDF variable or attribute and
+is one of the following:
+MACRO(BYTE), MACRO(CHAR), MACRO(SHORT), MACRO(INT),
+MACRO(FLOAT), or MACRO(DOUBLE) for CDF-1 and CDF-2 file formats.
+These are used to specify 8-bit integers,
+characters, 16-bit integers, 32-bit integers, 32-bit IEEE floating point
+numbers, and 64-bit IEEE floating-point numbers, respectively.
+ifelse(API,C,
+<<(MACRO(LONG) in netCDF version 2 is now obsolete and set to MACRO(INT)).>>)
+CDF-5 defines additional external types:
+MACRO(UBYTE), MACRO(USHORT), MACRO(UINT), MACRO(INT64), and MACRO(UINT64).
+.TP
+ODIMIDS()
+is a vector of dimension ID's and defines the shape of a netCDF variable.
+The size of the vector shall be greater than or equal to the
+rank (i.e. the number of dimensions) of the variable (NDIMS()).
+The vector shall be ordered by the speed with which a dimension varies:
+DIMIDS()<<>>ifelse(API,C,<<[NDIMS()-1]>>,<<(1)>>)
+shall be the dimension ID of the most rapidly
+varying dimension and
+DIMIDS()<<>>ifelse(API,C,<<[0]>>,<<(NDIMS())>>)
+shall be the dimension ID of the most slowly
+varying dimension.
+The maximum possible number of
+dimensions for a variable is given by the symbolic constant
+MACRO(MAX_VAR_DIMS).
+.TP
+IDIMID()
+is the ID of a netCDF dimension.
+netCDF dimension ID's are allocated sequentially from the
+ifelse(API,C,non-negative, positive)
+integers beginning with ifelse(API,C,0,1).
+.TP
+INDIMS()
+is either the total number of dimensions in a netCDF dataset or the rank
+(i.e. the number of dimensions) of a netCDF variable.
+The value shall not be negative or greater than the symbolic constant
+MACRO(MAX_VAR_DIMS).
+.TP
+IVARID()
+is the ID of a netCDF variable or (for the attribute-access functions)
+the symbolic constant
+MACRO(GLOBAL),
+which is used to reference global attributes.
+netCDF variable ID's are allocated sequentially from the
+ifelse(API,C,non-negative,positive)
+integers beginning with ifelse(API,C,0,1).
+.TP
+ONATTS()
+is the number of global attributes in a netCDF dataset for the
+FREF(inquire)
+function or the number
+of attributes associated with a netCDF variable for the
+FREF(varinq)
+function.
+.TP
+IINDEX()
+specifies the coordinates of the netCDF data value to be accessed.
+The indices start at ifelse(API,C,0,1);
+thus, for example, the first data value of a
+two-dimensional variable is ifelse(API,C,(0,0),(1,1)).
+The size of the vector shall be at least the rank of the associated
+netCDF variable and its elements shall correspond, in order, to the
+variable's dimensions.
+.TP
+ISTART()
+specifies the starting point
+for accessing a netCDF variable's data values
+in terms of the indicial coordinates of
+the corner of the array section.
+The indices start at ifelse(API,C,0,1);
+thus, the first data
+value of a variable is ifelse(API,C,(0, 0, ..., 0),(1, 1, ..., 1)).
+The size of the vector shall be at least the rank of the associated
+netCDF variable and its elements shall correspond, in order, to the
+variable's dimensions.
+.TP
+ICOUNT()
+specifies the number of indices selected along each dimension of the
+array section.
+Thus, to access a single value, for example, specify COUNT() as
+(1, 1, ..., 1).
+Note that, for strided I/O, this argument must be adjusted
+to be compatible with the STRIDE() and START() arguments so that
+the interaction of the
+three does not attempt to access an invalid data co-ordinate.
+The elements of the
+COUNT() vector correspond, in order, to the variable's dimensions.
+.TP
+ISTRIDE()
+specifies the sampling interval along each dimension of the netCDF
+variable. The elements of the stride vector correspond, in order,
+to the netCDF variable's dimensions (ARG(stride)<<>>ifelse(API,C,[0],<<(1)>>))
+gives the sampling interval along the most ifelse(API,C,slowly,rapidly)
+varying dimension of the netCDF variable). Sampling intervals are
+specified in type-independent units of elements (a value of 1 selects
+consecutive elements of the netCDF variable along the corresponding
+dimension, a value of 2 selects every other element, etc.).
+ifelse(API,C,<<A NULL() stride argument is treated as (1, 1, ... , 1).>>)
+.TP
+IIMAP()
+specifies the mapping between the dimensions of a netCDF variable and
+the in-memory structure of the internal data array. The elements of
+the <<index>> mapping vector correspond, in order, to the netCDF variable's
+dimensions (ARG(imap)<<>>ifelse(API,C,[0],<<(1)>>) gives the distance
+between elements of the internal array corresponding to the most
+ifelse(API,C,slowly,rapidly) varying dimension of the netCDF variable).
+Distances between elements are specified in type-independent units of
+elements (the distance between internal elements that occupy adjacent
+memory locations is 1 and not the element's byte-length as in netCDF 2).
+ifelse(API,C,<<A NULL() pointer means the memory-resident values have
+the same structure as the associated netCDF variable.>>)
+.SH "VARIABLE PREFILLING"
+.LP
+PnetCDF does not support data filling.
+.SH "ENVIRONMENT VARIABLES"
+.TP 4
+.B PNETCDF_SAFE_MODE
+Set to 1 to enable metadata consistency check. Warning messages will
+be printed to stdout if any inconsistency is detected.
+.SH "MAILING-LISTS"
+.LP
+A mailing list is available for
+discussion of the PnetCDF interface and announcements about PnetCDF bugs,
+fixes, and enhancements.
+To subscribe or unsubscribe to the PnetCDF mailing list,
+visit https://lists.mcs.anl.gov/mailman/listinfo/parallel-netcdf
+.RE
+.SH "SEE ALSO"
+.LP
+.BR ncmpidump (1),
+.BR ncmpigen (1),
+.BR ncmpidiff (1),
+.BR ncmpivalid (1),
+.BR pnetcdf (3<<>>ifelse(API,C,,f)).
+.LP
+\fIPnetCDF User's Guide\fP, published
+by Northwestern University and Argonne National Laboratory.
+This document is adopted from the
+\fInetCDF User's Guide\fP, developed at
+the Unidata Program Center, University Corporation for Atmospheric
+Research, located in Boulder, Colorado.
+
+PnetCDF home page at http://cucis.ece.northwestern.edu/projects/PnetCDF/.
diff --git a/man/pnetcdf_f90.m4 b/man/pnetcdf_f90.m4
new file mode 100644
index 0000000..101cc4f
--- /dev/null
+++ b/man/pnetcdf_f90.m4
@@ -0,0 +1,768 @@
+.nr yr \n(yr+1900
+.af mo 01
+.af dy 01
+.TH PNETCDF 3f90 "RELEASE_DATE" "Printed: \n(yr.\n(mo.\n(dy" "LIBRARY FUNCTIONS"
+.SH NAME
+PnetCDF \- Parallel library for accessing files in Network Common Data Form (CDF, CDF-2 and CDF-5 formats)
+.SH SYNOPSIS
+.ft B
+.na
+.nh
+use pnetcdf
+.sp
+.SS Most Systems:
+mpif90 ... -lpnetcdf
+.sp
+.SS CRAY PVP Systems:
+f90 -dp -i64 ... -lpnetcdf
+
+.ad
+.hy
+.SH "LIBRARY VERSION"
+.LP
+This document describes Parallel netCDF APIs
+for the Fortran-90 programming language.
+.HP
+\fBcharacter*80 nf90mpi_inq_libvers(\|)
+.RS
+character(len=80) :: nf90mpi_inq_libvers\fR
+.RE
+.sp
+Returns a string identifying the version of the PnetCDF library, and
+when it was built, like: "RELEASE_STR".
+.LP
+The RCS \fBident(1)\fP command will find a string like
+"$\|Id: @\|(#) PnetCDF library version
+RELEASE_STR $"
+in the library. The SCCS \fBwhat(1)\fP command will find a string like
+"PnetCDF library version RELEASE_STR".
+.SH "ROUTINE DESCRIPTIONS"
+.LP
+All PnetCDF functions (except
+\fBnf90mpi_inq_libvers(\|)\fR and \fBnf90mpi_strerror(\|)\fR) return an integer
+status.
+This behavior replaces the \fBrcode\fR argument
+used in previous versions of the library.
+If this returned status value is not equal to
+\fBnf90_noerr\fR (zero), it
+indicates that an error occurred. The possible status values are defined in
+the module \fBpnetcdf\fP.
+.HP
+\fBfunction nf90mpi_strerror(\fIncerr\fP)\fR
+.RS
+.nf
+integer, intent(in) :: ncerr
+character(len=80) :: nf90mpi_strerror
+.fi
+.sp
+Returns a string textual translation of the \fIncerr\fP
+value, like "Attribute or variable name contains illegal characters"
+or "No such file or directory".
+.RE
+.HP
+\fBfunction nf90mpi_create(\fIcomm\fP, \fIpath\fP, \fIcmode\fP, \fIinfo\fP, \fIncid\fP)\fR
+.RS
+.nf
+integer, intent(in) :: comm
+character(len=*), intent(in) :: path
+integer, intent(in) :: cmode
+integer, intent(in) :: info
+integer, intent(out) :: ncid
+integer :: nf90mpi_create
+.fi
+.sp
+Creates a new netCDF dataset at \fIpath\fP collectively by a group of MPI
+processes specified by \fIcomm\fP, returning a netCDF ID in \fIncid\fP. The
+argument \fIcmode\fP may include the bitwise-or of the following flags:
+\fBnf90_noclobber\fR to protect existing datasets (default is \fBnf90_clobber\fR,
+silently blows them away), \fBnf90_share\fR for stronger metadata data consistency
+control, \fBnf90_64bit_offset\fR to create a file in the 64-bit offset format
+(CDF-2), as opposed to classic format, the default, or \fBnf90_64bit_data\fR to
+create a file in the 64-bit data format (CDF-5).
+Use either \fBnf90_64bit_offset\fR or \fBnf90_64bit_data\fR.
+The 64-bit offset format allows the creation of very large files with far fewer
+restrictions than netCDF classic format, but can only be read by the netCDF
+library version 3.6 or greater. Users are cautioned that files that use the
+64-bit offset format will not be recognized by netCDF applications linked to an
+earlier version of the netCDF library than 3.6. Applications linked to version
+3.6 or later will be able to transparently access either the classic format or
+64-bit offset format.
+The 64-bit data format allows the creation of very large array variables.
+CDF-5 files currently will not be recognized by netCDF 3 or 4 library.
+.
+
+The argument \fIcmode\fP must be consistent among all MPI processes that
+collectively create the file. The argument \fIinfo\fP is an MPI info object.
+Users can use it to supply the file access hints further performance
+improvement. The hints include existing MPI-IO hints as well as hints defined
+and used in PnetCDF.
+.sp
+When a netCDF dataset is created, it is opened in \fbnf90_write\fR mode.
+When this function returns, the new netCDF dataset is in define mode.
+.RE
+.HP
+\fBfunction nf90mpi_open(\fIcomm\fP, \fIpath\fP, \fImode\fP, \fIinfo\fP, \fIncid\fP)\fR
+.RS
+.nf
+integer, intent(in) :: comm
+character(len=*), intent(in) :: path
+integer, intent(in) :: mode
+integer, intent(in) :: info
+integer, intent(out) :: ncid
+integer :: nf90mpi_open
+.fi
+.sp
+Opens an existing netCDF dataset at \fIpath\fP collectively by a group of MPI
+processes specified by \fIcomm\fP, returning a netCDF ID in \fIncid\fP. The type
+of access is described by the \fImode\fP parameter, which may include the
+bitwise-or of the following flags: \fBnf90_write\fR for read-write access (default
+read-only), \fBnf90_share\fR for stronger metadata data consistency control.
+.sp
+
+The argument \fImode\fP must be consistent among all MPI processes that
+collectively open the file. The argument \fIinfo\fP is an MPI info object.
+Users can use it to supply the file access hints further performance
+improvement. The hints include existing MPI-IO hints as well as hints defined
+and used in PnetCDF.
+.RE
+.HP
+\fBfunction nf90mpi_redef(\fIncid\fP)\fR
+.RS
+.nf
+integer, intent(in) :: ncid
+integer :: nf90mpi_redef
+.fi
+.sp
+Puts an open netCDF dataset into define mode,
+so dimensions, variables, and attributes can be added or renamed and
+attributes can be deleted.
+.RE
+.HP
+\fBfunction nf90mpi_enddef(\fIncid\fP)\fR
+.RS
+.nf
+integer, intent(in) :: ncid
+integer :: nf90mpi_enddef
+.fi
+.sp
+Takes an open netCDF dataset out of define mode.
+The changes made to the netCDF dataset
+while it was in define mode are checked and committed to disk if no
+problems occurred.
+After a successful call, variable data can be read or written to the dataset.
+.RE
+.HP
+\fBfunction nf90mpi_sync(\fIncid\fP)\fR
+.RS
+.nf
+integer, intent(in) :: ncid
+integer :: nf90mpi_sync
+.fi
+.sp
+Unless the
+\fBnf90_share\fR
+bit is set in
+\fBnf90mpi_open(\|)\fR or \fBnf90mpi_create(\|)\fR,
+data written by PnetCDF APIs may be cached by local file system on each compute
+node. This API flushes cached data by calling MPI_File_sync.
+.RE
+.HP
+\fBfunction nf90mpi_abort(\fIncid\fP)\fR
+.RS
+.nf
+integer, intent(in) :: ncid
+integer :: nf90mpi_abort
+.fi
+.sp
+You don't need to call this function.
+This function is called automatically by
+\fBnf90mpi_close(\|)\fR
+if the netCDF dataset was in define mode and something
+goes wrong with the commit.
+If the netCDF dataset isn't in define mode, then this function is equivalent to
+\fBnf90mpi_close(\|)\fR.
+If it is called after
+\fBnf90mpi_redef(\|)\fR,
+but before
+\fBnf90mpi_enddef(\|)\fR,
+the new definitions are not committed and the dataset is closed.
+If it is called after
+\fBnf90mpi_create(\|)\fR
+but before
+\fBnf90mpi_enddef(\|)\fR,
+the dataset disappears.
+.RE
+.HP
+\fBfunction nf90mpi_close(\fIncid\fP)\fR
+.RS
+.nf
+integer, intent(in) :: ncid
+integer :: nf90mpi_close
+.fi
+.sp
+.sp
+Closes an open netCDF dataset.
+If the dataset is in define mode,
+\fBnf90mpi_enddef(\|)\fR
+will be called before closing.
+After a dataset is closed, its ID may be reassigned to another dataset.
+.RE
+.HP
+\fBfunction nf90mpi_inquire(\fIncid\fP, \fIndims\fP, \fInvars\fP,
+\fInatts\fP, \fIunlimdimid\fP, \fInformat\fP)\fR
+.RS
+.nf
+integer, intent(in) :: ncid
+integer, optional, intent(out) :: ndims, nvars
+integer, optional, intent(out) :: natts, unlimdimid
+integer, optional, intent(out) :: nformat
+integer :: nf90mpi_inquire
+.fi
+.sp
+Inquire about an open netCDF dataset.
+\fIncid\fP is the netCDF ID of the open dataset.
+Upon successful return,
+\fIndims\fP will contain the
+number of dimensions defined for this netCDF dataset,
+\fInvars\fP will contain the number of variables,
+\fInatts\fP will contain the number of attributes, and
+\fIunlimdimid\fP will contain the
+dimension ID of the unlimited dimension if one exists, or
+0 otherwise.
+\fInformat\fP will contain the format version number, rarely needed
+because the library detects the format version and behaves
+appropriately.
+.RE
+.HP
+\fBfunction nf90mpi_def_dim(\fIncid\fP, \fIname\fP, \fIlen\fP, \fIdimid\fP)\fR
+.RS
+.nf
+integer, intent(in) :: ncid
+character(len=*), intent(in) :: name
+integer, intent(in) :: len
+integer, intent(out) :: dimid
+integer :: nf90mpi_def_dim
+.fi
+.sp
+Adds a new dimension to an open netCDF dataset, which must be
+in define mode.
+\fIname\fP is the dimension name.
+\fIlen\fP is the size of the new dimension or \fBnf90mpi_unlimited\fP to define
+the unlimited dimension.
+On return, \fIdimid\fP will contain the dimension ID of the newly created
+dimension.
+.RE
+.HP
+\fBfunction nf90mpi_inq_dimid(\fIncid\fP, \fIname\fP, \fIdimid\fP)\fR
+.RS
+.nf
+integer, intent(in) :: ncid
+character(len=*), intent(in) :: name
+integer, intent(out) :: dimid
+integer :: nf90mpi_inq_dimid
+.fi
+.sp
+Given an open netCDF dataset and dimension name, returns the dimension ID of the
+netCDF dimension in \fIdimid\fP.
+.RE
+.HP
+\fBfunction nf90mpi_inquire_dimension(\fIncid\fP, \fIdimid\fP, \fIname\fP, \fIlen\fP)\fR
+.RS
+.nf
+integer, intent(in) :: ncid, dimid
+character(len=*), optional, intent(out) :: name
+integer, optional, intent(out) :: len
+integer :: nf90mpi_inquire_dimension
+.fi
+.sp
+Inquire about a dimension.
+\fIname\fP should be big enough (\fBnf90_max_name\fR)
+to hold the dimension name as the name will be copied into your storage.
+The length return parameter, \fIlen\fP
+will contain the size of the dimension.
+For the unlimited dimension, the returned length is the current
+maximum value used for writing into any of the variables which use
+the dimension.
+.RE
+.HP
+\fBfunction nf90mpi_rename_dim(\fIncid\fP, \fIdimid\fP, \fIname\fP)\fR
+.RS
+.nf
+integer, intent(in) :: ncid
+character(len=*), intent(in) :: name
+integer, intent(in) :: dimid
+integer :: nf90mpi_rename_dim
+.fi
+.sp
+Renames an existing dimension in an open netCDF dataset.
+If the new name is longer than the old name, the netCDF dataset must be in
+define mode.
+You cannot rename a dimension to have the same name as another dimension.
+.RE
+.HP
+\fBfunction nf90mpi_def_var(\fIncid\fP, \fIname\fP, \fIxtype\fP, \fIdimids\fP, \fIvarid\fP)\fR
+.RS
+.nf
+integer, intent(in) :: ncid
+character(len=*), intent(in) :: name
+integer, intent(in) :: xtype
+integer, optional, dimension(:), intent(in) :: dimids
+integer :: nf90mpi_def_var
+.fi
+.sp
+Adds a new variable to a netCDF dataset. The netCDF must be in define mode.
+\fIname\fP will be the name of the netCDF variable.
+\fIxtype\fP is the external, netCDF type of the variable and should be one of
+\fBnf90_byte\fP,
+\fBnf90_char\fP,
+\fBnf90_short\fP,
+\fBnf90_int\fP,
+\fBnf90_float\fP, or
+\fBnf90_double\fP
+for CDF-1 and CDF-2 file formats.
+CDF-5 defines additional external types:
+\fBnf90_ubyte\fP,
+\fBnf90_ushort\fP,
+\fBnf90_uint\fP,
+\fBnf90_int64\fP, and
+\fBnf90_uint64\fP.
+The optional \fIdimids\fP argument contains the dimension ID-s of the domain
+of the netCDF variable and, consequently, determines the rank of the
+created variable:
+if \fIdimids\fP is omitted, then the netCDF variable will be a scalar;
+if \fIdimids\fP is a scalar, then the netCDF variable will be 1 dimensional;
+and if \fIdimids\fP is a vector, then the netCDF variable will
+have rank equal to the number of elements in \fIdimids\fP.
+\fIvarid\fP will be set to the netCDF variable ID.
+.RE
+.HP
+\fBfunction nf90mpi_inq_varid(\fIncid\fP, \fIname\fP, \fIvarid\fP)\fR
+.RS
+.nf
+integer, intent(in) :: ncid
+character(len=*), intent(in) :: name
+integer, intent(out) :: varid
+integer :: nf90mpi_inq_varid
+.fi
+.sp
+Returns the ID of a netCDF variable in \fIvarid\fP given an open netCDF dataset
+and the name of the variable.
+.RE
+.HP
+\fBfunction nf90mpi_inquire_variable(\fIncid\fP, \fIvarid\fP, \fIname\fP,
+\fIxtype\fP, \fIndims\fP, \fIdimids\fP, \fInatts\fP)\fR
+.RS
+.nf
+integer, intent(in) :: ncid, varid
+character(len=*), optional, intent(out) :: name
+integer, optional, intent(out) :: xtype, ndims
+integer, dimension(*), optional, intent(out) :: dimids
+integer, optional, intent(out) :: natts
+integer :: nf90mpi_inquire_variable
+.fi
+.sp
+Inquire about a netCDF variable in an open netCDF dataset, given its
+variable ID.
+On return, \fIname\fP will contain the name of the variable and should
+be capacious enough (\fBnf90_max_name\fP).
+\fIxtype\fP will contain the external, netCDF type of the variable.
+\fIndims\fP will contain the dimensionality of the netCDF variable: if the
+variable is a scalar, then size(\fIndims\fP) will be zero; otherwise,
+size(\fIndims\fP) will be the rank of the variable and \fIndims\fP will contain
+the dimension ID-s of the netCDF dimensions that constitute the domain of the
+variable.
+\fInatts\fP will contain the number of attributes associated with the netCDF
+variable.
+.RE
+.HP
+\fBfunction nf90mpi_rename_var(\fIncid\fP, \fIvarid\fP, \fIname\fP)\fR
+.RS
+.nf
+integer, intent9in) :: ncid, varid
+character(len=*), intent(in) :: newname
+integer :: nf90mpi_rename_var
+.fi
+.sp
+Changes the name of a netCDF variable.
+If the new name is longer than the old name, the netCDF must be in define mode.
+You cannot rename a variable to have the name of any existing variable.
+.RE
+.HP
+\fBfunction nf90mpi_put_var(\fIncid\fP, \fIvarid\fP, \fIvalues\fP,
+\fIstart\fP, \fIstride\fP, \fIimap\fP)\fR
+.RS
+.nf
+integer, intent(in) :: ncid, varid
+<<whatever>>, intent(in) :: values
+integer, dimension(:), optional, intent(in) :: start
+integer, dimension(:), optional, intent(in) :: stride
+integer, dimension(:), optional, intent(in) :: imap
+integer :: nf90mpi_put_var
+.fi
+.sp
+Writes a value or values to a netCDF variable.
+The netCDF dataset must be open and in data mode.
+\fIvalues\fP contains the value(s) what will be written to the netCDF variable
+identified by \fIncid\fP and \fIvarid\fP; it may be a scalar or an array and
+must be of type
+\fBcharacter\fP,
+\fBinteger(kind=OneByteInt)\fP,
+\fBinteger(kind=TwoByteInt)\fP,
+\fBinteger(kind=FourByteInt)\fP,
+\fBinteger(kind=EightByteInt)\fP,
+\fBreal(kind=FourByteReal)\fP, or
+\fBreal(kind=EightByteReal)\fP.
+All values are converted to the external type
+of the netCDF variable, if possible; otherwise, an
+\fBnf90_erange\fR error is returned.
+The optional argument \fIstart\fP specifies
+the starting index in the netCDF variable for writing for each
+dimension of the netCDF variable.
+The optional argument \fIstride\fP specifies the sampling stride
+(the interval between accessed values in the netCDF variable)
+for each dimension of the netCDF variable (see COMMON ARGUMENT DESCRIPTIONS
+below).
+The optional argument \fIimap\fP specifies the in-memory arrangement of the data
+values (see COMMON ARGUMENT DESCRIPTIONS below).
+.RE
+.HP
+\fBfunction nf90mpi_get_var(\fIncid\fP, \fIvarid\fP, \fIvalues\fP,
+\fIstart\fP, \fIstride\fP, \fIimap\fP)\fR
+.RS
+.nf
+integer, intent(in) :: ncid, varid
+<<whatever>>, intent(out) :: values
+integer, dimension(:), optional, intent(in) :: start
+integer, dimension(:), optional, intent(in) :: stride
+integer, dimension(:), optional, intent(in) :: imap
+integer :: nf90mpi_get_var
+.fi
+.sp
+Reads a value or values from a netCDF variable.
+The netCDF dataset must be open and in data mode.
+\fIvalues\fP will receive the value(s) what will be read from the netCDF
+ variable
+identified by \fIncid\fP and \fIvarid\fP; it may be a scalar or an array and
+must be of type
+\fBcharacter\fP,
+\fBinteger(kind=OneByteInt)\fP,
+\fBinteger(kind=TwoByteInt)\fP,
+\fBinteger(kind=FourByteInt)\fP,
+\fBinteger(kind=EightByteInt)\fP,
+\fBreal(kind=FourByteReal)\fP, or
+\fBreal(kind=EightByteReal)\fP.
+All values are converted from the external type
+of the netCDF variable, if possible; otherwise, an
+\fBnf90_erange\fR error is returned.
+The optional argument \fIstart\fP specifies
+the starting index in the netCDF variable for reading for each
+dimension of the netCDF variable.
+The optional argument \fIstride\fP specifies the sampling stride
+(the interval between accessed values in the netCDF variable)
+for each dimension of the netCDF variable (see COMMON ARGUMENT DESCRIPTIONS
+below).
+The optional argument \fIimap\fP specifies the in-memory arrangement of the data
+values (see COMMON ARGUMENT DESCRIPTIONS below).
+.RE
+.HP
+\fBfunction nf90mpi_inquire_attribute(\fIncid\fP, \fIvarid\fP, \fIname\fP,
+\fIxtype\fP, \fIlen\fP, \fIattnum\fP)\fR
+.RS
+.nf
+integer, intent(in) :: ncid, varid
+character(len=*), intent(in) :: name
+integer, optional, intent(out) :: xtype, len, attnum
+integer :: nf90mpi_inquire_attribute
+.fi
+.sp
+Inquires about the netCDF attribute named \fIname\fP, of variable \fIvarid\fP,
+in the open netCDF dataset \fIncid\fP.
+\fIxtype\fP will contain the external, netCDF type of the variable.
+\fIlen\fP will contain the number of elements in the attribute.
+\fIattnum\fP will contain the attribute number.
+.RE
+.HP
+\fBfunction nf90mpi_inq_attname(\fIncid\fP, \fIvarid\fP, \fIattnum\fP,
+\fIname\fP)\fR
+.RS
+.nf
+integer, intent(in) :: ncid, varid, attnum
+character(len=*), intent(out) :: name
+integer :: nf90mpi_inq_attname
+.fi
+.sp
+Gets the
+name of an attribute, given its variable ID and attribute number.
+This function is useful in generic applications that
+need to get the names of all the attributes associated with a variable
+because attributes are accessed by name rather than number in all other
+attribute functions (the number of an attribute is more volatile than
+the name because it can change when other attributes of the same variable
+are deleted). The attributes for each variable are numbered
+from 1 (the first attribute) to
+\fInatts\fP, where \fInatts\fP is
+the number of attributes for the variable, as returned from a call to
+\fBnf90mpi_inquire_variable(\|)\fR.
+.RE
+.HP
+\fBfunction nf90mpi_put_att(\fIncid\fP, \fIvarid\fP, \fIname\fP,
+\fIvalues\fP)\fR
+.RS
+.nf
+integer, intent(in) :: ncid, varid
+character(len=*), intent(in) :: name
+<<whatever>>, intent(in) :: values
+integer :: nf90mpi_put_att
+.fi
+.sp
+Unlike variables, attributes do not have
+separate functions for defining and writing values.
+This function defines a new attribute with a value or changes
+the value of an existing attribute.
+If the attribute is new, or if the space required to
+store the attribute value is greater than before,
+the netCDF dataset must be in define mode.
+\fIvalues\fP contains the attribute values to be written; it may be a scalar
+or a vector and must be of type
+\fBcharacter\fP,
+\fBinteger(kind=OneByteInt)\fP,
+\fBinteger(kind=TwoByteInt)\fP,
+\fBinteger(kind=FourByteInt)\fP,
+\fBinteger(kind=EightByteInt)\fP,
+\fBreal(kind=FourByteReal)\fP, or
+\fBreal(kind=EightByteReal)\fP.
+.RE
+.HP
+\fBfunction nf90mpi_get_att(\fIncid\fP, \fIvarid\fP, \fIname\fP, \
+fIvalues\fP)\fR
+.RS
+.nf
+integer, intent(in) :: ncid, varid
+character(len=*), intent(in) :: name
+<<whatever>>, intent(out) :: values
+integer :: nf90mpi_get_att
+.fi
+.sp
+Gets the value(s) of a netCDF attribute, given its
+variable ID and name.
+The values are returned in \fIvalues\fP, which must be of type
+\fBcharacter\fP,
+\fBinteger(kind=OneByteInt)\fP,
+\fBinteger(kind=TwoByteInt)\fP,
+\fBinteger(kind=FourByteInt)\fP,
+\fBinteger(kind=EightByteInt)\fP,
+\fBreal(kind=FourByteReal)\fP, or
+\fBreal(kind=EightByteReal)\fP.
+Converts from the external type to the type
+of the receiving variable, if possible; otherwise returns an \fBnf90_erange\fR
+error.
+All values of the attribute
+are returned, so you must allocate enough space to hold
+them. If you don't know how much space to reserve, call
+\fBnf90mpi_inquire_attribute(\|)\fR
+first to find out the length of the attribute.
+.RE
+.HP
+\fBfunction nf90mpi_copy_att(\fIncid_in\fP, \fIvarid_in\fP, \fIname\fP,
+\fIncid_out\fP, \fIvarid_out\fP)\fR
+.RS
+.nf
+integer, intent(in) :: ncid_in, varid_in
+character(len=*), intent(in) :: name
+integer, intent(in) :: ncid_out, varid_out
+integer :: nf90mpi_copy_att
+.fi
+.sp
+Copies an
+attribute from one netCDF dataset to another. It can also be used to
+copy an attribute from one variable to another within the same netCDF
+dataset.
+\fIncid_in\fP is the netCDF ID of an input netCDF dataset from which the
+attribute will be copied.
+\fIvarid_in\fP
+is the ID of the variable in the input netCDF dataset from which the
+attribute will be copied, or \fBnf90_global\fR
+for a global attribute.
+\fIname\fP
+is the name of the attribute in the input netCDF dataset to be copied.
+\fIncid_out\fP
+is the netCDF ID of the output netCDF dataset to which the attribute will be
+copied.
+It is permissible for the input and output netCDF ID's to be the same. The
+output netCDF dataset should be in define mode if the attribute to be
+copied does not already exist for the target variable, or if it would
+cause an existing target attribute to grow.
+\fIvarid_out\fP
+is the ID of the variable in the output netCDF dataset to which the
+attribute will
+be copied, or \fBnf90_global\fR to copy to a global attribute.
+.RE
+.HP
+\fBfunction nf90mpi_rename_att(\fIncid\fP, \fIvarid\fP, \fIname\fP,
+\fInewname\fP)\fR
+.RS
+.nf
+integer, intent(in) :: ncid, varid
+character(len=*), intent(in) :: name, newname
+integer :: nf90mpi_rename_att
+.fi
+.sp
+Changes the
+name of an attribute. If the new name is longer than the original name,
+the netCDF must be in define mode. You cannot rename an attribute to
+have the same name as another attribute of the same variable.
+\fIname\fP is the original attribute name.
+\fInewname\fP
+is the new name to be assigned to the specified attribute. If the new name
+is longer than the old name, the netCDF dataset must be in define mode.
+.RE
+.HP
+\fBfunction nf90mpi_del_att(\fIncid\fP, \fIvarid\fP, \fIname\fP)\fR
+.RS
+.nf
+integer, intent(in) :: ncid, varid
+character(len=*), intent(in) :: name
+integer :: nf90mpi_del_att
+.fi
+.sp
+Deletes an attribute from a netCDF dataset. The dataset must be in
+define mode.
+.RE
+.SH "COMMON ARGUMENT DESCRIPTIONS"
+.LP
+In this section we define some common arguments which are used in the
+"FUNCTION DESCRIPTIONS" section.
+.TP
+integer \fIncid\fP
+is the netCDF ID returned from a previous, successful call to
+\fBnf90mpi_open(\|)\fR or \fBnf90mpi_create(\|)\fR
+.TP
+character(len=*) \fIname\fP
+is the name of a dimension, variable, or attribute.
+It shall begin with an alphabetic character, followed by
+zero or more alphanumeric characters including the underscore
+(`_') or hyphen (`-'). Case is significant.
+The maximum allowable number of characters
+is \fBnf90_max_name\fR.
+Names that begin with an underscore (`_') are reserved for use
+by the netCDF and PnetCDF interfaces.
+.TP
+integer \fIxtype\fP
+specifies the external data type of a netCDF variable or attribute and
+is one of the following:
+\fBnf90_byte\fR, \fBnf90_char\fR, \fBnf90_short\fR, \fBnf90_int\fR,
+\fBnf90_float\fR, or \fBnf90_double\fR.
+These are used to specify 8-bit integers,
+characters, 16-bit integers, 32-bit integers, 32-bit IEEE floating point
+numbers, and 64-bit IEEE floating-point numbers, respectively.
+
+.TP
+integer \fIdimids\fP
+is a vector of dimension ID's and defines the shape of a netCDF variable.
+The size of the vector shall be greater than or equal to the
+rank (i.e. the number of dimensions) of the variable (\fIndims\fP).
+The vector shall be ordered by the speed with which a dimension varies:
+\fIdimids\fP(\|1) shall be the dimension ID of the most rapidly
+varying dimension and
+\fIdimids\fP(\fIndims\fP)
+shall be the dimension ID of the most slowly
+varying dimension.
+The maximum possible number of
+dimensions for a variable is given by the symbolic constant
+\fBnf90_max_var_dims\fR.
+.TP
+integer \fIdimid\fP
+is the ID of a netCDF dimension.
+netCDF dimension ID's are allocated sequentially from the
+positive
+integers beginning with 1.
+.TP
+integer \fIndims\fP
+is either the total number of dimensions in a netCDF dataset or the rank
+(i.e. the number of dimensions) of a netCDF variable.
+The value shall not be negative or greater than the symbolic constant
+\fBnf90_max_var_dims\fR.
+.TP
+integer \fIvarid\fP
+is the ID of a netCDF variable or (for the attribute-access functions)
+the symbolic constant
+\fBnf90_global\fR,
+which is used to reference global attributes.
+netCDF variable ID's are allocated sequentially from the
+positive
+integers beginning with 1.
+.TP
+integer \fInatts\fP
+is the number of global attributes in a netCDF dataset for the
+\fBnf90mpi_inquire(\|)\fR
+function or the number
+of attributes associated with a netCDF variable for the
+\fBnf90mpi_varinq(\|)\fR
+function.
+.TP
+integer(kind=MPI_OFFSET) \fIstart\fP
+specifies the starting point
+for accessing a netCDF variable's data values
+in terms of the indicial coordinates of
+the corner of the array section.
+The indices start at 1;
+thus, the first data
+value of a variable is (1, 1, ..., 1).
+The size of the vector shall be at least the rank of the associated
+netCDF variable and its elements shall correspond, in order, to the
+variable's dimensions.
+.TP
+integer(kind=MPI_OFFSET) \fIstride\fP
+specifies the sampling interval along each dimension of the netCDF
+variable. The elements of the stride vector correspond, in order,
+to the netCDF variable's dimensions (\fIstride\fP(1))
+gives the sampling interval along the most rapidly
+varying dimension of the netCDF variable). Sampling intervals are
+specified in type-independent units of elements (a value of 1 selects
+consecutive elements of the netCDF variable along the corresponding
+dimension, a value of 2 selects every other element, etc.).
+
+.TP
+integer(kind=MPI_OFFSET) \fIimap\fP
+specifies the mapping between the dimensions of a netCDF variable and
+the in-memory structure of the internal data array. The elements of
+the index mapping vector correspond, in order, to the netCDF variable's
+dimensions (\fIimap\fP gives the distance
+between elements of the internal array corresponding to the most
+rapidly varying dimension of the netCDF variable).
+Distances between elements are specified in type-independent units of
+elements (the distance between internal elements that occupy adjacent
+memory locations is 1 and not the element's byte-length as in netCDF 2).
+
+.SH "VARIABLE PREFILLING"
+.LP
+PnetCDF does not support data filling.
+.SH "ENVIRONMENT VARIABLES"
+.TP 4
+.B PNETCDF_SAFE_MODE
+Set to 1 to enable metadata consistency check. Warning messages will
+be printed to stdout if any inconsistency is detected.
+.SH "MAILING-LISTS"
+.LP
+A mailing list is available for
+discussion of the PnetCDF interface and announcements about PnetCDF bugs,
+fixes, and enhancements.
+To subscribe or unsubscribe to the PnetCDF mailing list,
+visit https://lists.mcs.anl.gov/mailman/listinfo/parallel-netcdf
+.RE
+.SH "SEE ALSO"
+.LP
+.BR ncmpidump (1),
+.BR ncmpigen (1),
+.BR ncmpidiff (1),
+.BR ncmpivalid (1),
+.BR pnetcdf (3f90).
+.LP
+\fIPnetCDF User's Guide\fP, published
+by Northwestern University and Argonne National Laboratory.
+This document is adopted from the
+\fInetCDF User's Guide\fP, developed at
+the Unidata Program Center, University Corporation for Atmospheric
+Research, located in Boulder, Colorado.
+
+PnetCDF home page at http://cucis.ece.northwestern.edu/projects/PnetCDF/.
diff --git a/pbs.script b/pbs.script
new file mode 100644
index 0000000..8494a0d
--- /dev/null
+++ b/pbs.script
@@ -0,0 +1,18 @@
+#PBS -q debug
+#PBS -l walltime=00:10:00
+#PBS -l mppwidth=8
+#PBS -N pnetcdf_test
+#PBS -j oe
+#PBS -V
+
+cd $PBS_O_WORKDIR
+
+set OUT_DIR = /output/file/directory
+
+# test seqential programs
+make check TEST_MPIRUN="aprun -n NP" TEST_OUTDIR=$OUT_DIR TEST_SEQRUN="aprun -n 1"
+
+# test parallel programs
+make ptest TEST_MPIRUN="aprun -n NP" TEST_OUTDIR=$OUT_DIR TEST_SEQRUN="aprun -n 1"
+
+
diff --git a/rules.make b/rules.make
new file mode 100644
index 0000000..6e88e3d
--- /dev/null
+++ b/rules.make
@@ -0,0 +1,260 @@
+# $Id: rules.make 2285 2015-12-30 20:48:25Z wkliao $
+
+# The purpose of this file is to contain common make(1) rules.
+# It should be processed by every execution of the that utility.
+
+.SUFFIXES:
+.SUFFIXES: .a .o .i .f .c .cpp .F .y .l .m4 .f90 .F90
+
+
+################################################################################
+# Compilation (including preprocessing):
+
+.c.o:
+ $(COMPILE.c) $<
+
+.c.i:
+ $(CPP) $(CPPFLAGS) $< >$@
+
+.cpp.o:
+ $(COMPILE.cxx) $<
+
+.f.o:
+ $(COMPILE.f) $<
+
+.f90.o:
+ $(COMPILE.f90) $<
+
+.F90.o:
+ $(COMPILE.F90) $<
+
+.F.o:
+ $(COMPILE.F) $<
+
+# Not all FORTRAN compilers support C-preprocessing of *.F files; ergo, a
+# relatively complicated rule ensues.
+# .F.o:
+# @case "$(COMPILE.F)" in \
+# '') \
+# set -x; \
+# $(FPP) $(FPPFLAGS) -C $*.F | grep -v '^#' >$*-tmp.f || \
+# ($(RM) -f $*-tmp.f ; exit 1); \
+# $(COMPILE.f) -o $@ $*-tmp.f || ($(RM) -f $*-tmp.f; exit 1); \
+# $(RM) -f $*-tmp.f; \
+# ;; \
+# *) \
+# $(COMPILE.F) $<; \
+# ;; \
+# esac
+
+#.F.f:
+# $(FPP) $(FPPFLAGS) $*.F | grep -v '^#' >$*.f || ($(RM) -f $*.f; exit 1)
+
+.m4.c:
+ $(M4) $(M4FLAGS) $< >$@
+
+.m4.F:
+ $(M4) $(M4FLAGS) $< >$@
+
+.m4.f90:
+ $(M4) $(M4FLAGS) $< >$@
+
+.m4.F90:
+ $(M4) $(M4FLAGS) $< >$@
+
+
+################################################################################
+# Libraries:
+
+# lib: $(LIBRARY)
+
+#-------------------------------------------------------------------------------
+# Shared Libraries:
+#
+# Here only as a place holder and notebook. Don't try to use this stuff
+# unless you really, really know what you're doing! (And even then we
+# guarantee nothing!)
+#
+shared_library:
+ @case `uname -sr` in \
+ HP-UX*) \
+ $(MAKE) $(MFLAGS) hpux_shared_library;; \
+ IRIX*) \
+ $(MAKE) $(MFLAGS) irix_shared_library;; \
+ Linux*) \
+ $(MAKE) $(MFLAGS) linux_shared_library;; \
+ OSF1*) \
+ $(MAKE) $(MFLAGS) osf1_shared_library;; \
+ 'SunOS 4'*) \
+ $(MAKE) $(MFLAGS) sunos4_shared_library;; \
+ 'SunOS 5'*) \
+ $(MAKE) $(MFLAGS) sunos5_shared_library;; \
+ *) \
+ echo 1>&2 "Don't know how to make a shared library" \
+ "on this system"; \
+ exit 1;; \
+ esac
+
+hpux_shared_library:
+ nm libpnetcdf.a | grep extern | grep entry | \
+ awk '-F|' '{print $$1}' | sed 's/^/-u /' >symbols.log
+ ld -o $(LIBRARY:.a=.sl) -b -c symbols.log $(LIBRARY)
+ $(RM) -f symbols.log
+irix_shared_library:
+ ld -o $(LIBRARY:.a=.so) -shared -no_archive \
+ -all $(LIBRARY) -none -lc -lC $(LIBS)
+linux_shared_library:
+ ld -o $(LIBRARY:.a=.so) -shared --whole-archive $(LIBRARY)
+osf1_shared_library:
+ ld -o $(LIBRARY:.a=.so) -shared -all $(LIBRARY)
+sunos4_shared_library:
+ undefopts=`/bin/nm $(LIBRARY) | awk '$$2~/^T$$/{print $$3}' | \
+ sed 's/^/-u /'` && \
+ ld -o $(LIBRARY:.a=.so) $$undefopts $(LIBRARY)
+sunos5_shared_library:
+ undefopts=`/usr/ccs/bin/nm $(LIBRARY) | grep GLOB | grep FUNC | \
+ awk '-F|' '{print $$8}' | sed 's/^/-u /'` && \
+ ld -o $(LIBRARY:.a=.so) -G $$undefopts $(LIBRARY)
+
+
+################################################################################
+# Linking:
+
+
+################################################################################
+# $(INSTALL)ation:
+
+$(INCDIR)/$(HEADER): $(INCDIR) $(HEADER)
+ $(INSTALL) $(srcdir)/$(HEADER) $@
+$(INCDIR)/$(HEADER1): $(INCDIR) $(HEADER1)
+ $(INSTALL) $(srcdir)/$(HEADER1) $@
+$(INCDIR)/$(HEADER2): $(INCDIR) $(HEADER2)
+ $(INSTALL) $(srcdir)/$(HEADER2) $@
+$(INCDIR)/$(HEADER3): $(INCDIR) $(HEADER3)
+ $(INSTALL) $(srcdir)/$(HEADER3) $@
+
+$(LIBDIR)/$(LIBRARY): $(LIBDIR) $(LIBRARY)
+ $(INSTALL) -d -m 755 $(LIBDIR)
+ $(INSTALL) -m 644 $(LIBRARY) $@
+
+$(BINDIR)/$(PROGRAM): $(BINDIR) $(PROGRAM)
+ $(INSTALL) -d -m 755 $(BINDIR)
+ $(INSTALL) -m 755 $(PROGRAM) $@
+
+#$(BINDIR) \
+#$(INCDIR) \
+#$(LIBDIR) \
+#$(MANDIR) :
+# -test -d $@ || mkdir $@
+
+#$(MANDIR)/man1 \
+#$(MANDIR)/man3 \
+#$(MANDIR)/man3f \
+#$(MANDIR)/man3f90 : $(MANDIR)
+# -test -d $@ || mkdir $@
+
+# $(MANDIR)/man1/$(MANUAL): $(MANDIR)/man1 $(MANUAL)
+# $(INSTALL) $(srcdir)/$(MANUAL) $@
+# $(MANDIR)/man3/$(MANUAL): $(MANDIR)/man3 $(MANUAL)
+# $(INSTALL) $(srcdir)/$(MANUAL) $@
+# $(MANDIR)/man3f/$(MANUAL): $(MANDIR)/man3 $(MANDIR)/man3/$(MANUAL) \
+# $(MANDIR)/man3f
+# $(RM) -f $@
+# $(LN_S) $(MANDIR)/man3/$(MANUAL) $@
+# $(MANDIR)/man3f90/$(MANUAL): $(MANDIR)/man3 $(MANDIR)/man3/$(MANUAL) \
+# $(MANDIR)/man3f90
+# $(RM) -f $@
+# $(LN_S) $(MANDIR)/man3/$(MANUAL) $@
+
+################################################################################
+# Cleanup:
+
+clean: FORCE
+ @if [ -n "$(SUBDIRS)" ]; then \
+ subdirs="$(SUBDIRS)"; \
+ for subdir in $$subdirs; do \
+ (cd $$subdir && $(MAKE) $(MFLAGS) clean) ; \
+ done; \
+ fi
+ @$(RM) -f *.o *.a *.so *.sl *.i *.Z core core.* $(GARBAGE) \
+ *.gcda *.gcno gmon.out
+
+distclean: FORCE
+ @if [ -n "$(PACKING_SUBDIRS)" ]; then \
+ subdirs="$(PACKING_SUBDIRS)"; \
+ for subdir in $$subdirs; do \
+ (cd $$subdir && $(MAKE) $(MFLAGS) distclean) ; \
+ done; \
+ fi
+ @if [ -n "$(PACKING_SUBDIRS)" ]; then \
+ subdirs="$(PACKING_SUBDIRS)"; \
+ for subdir in $$subdirs; do \
+ if ! [ $(srcdir) -ef `pwd` ] ; then rmdir $$subdir ; fi \
+ done; \
+ fi
+ @$(RM) -rf SunWS_cache
+ @$(RM) -f *.o *.a *.so *.sl *.i *.Z core core.* $(GARBAGE) \
+ *.gcda *.gcno gmon.out \
+ MANIFEST *.log $(DIST_GARBAGE) cscope.out cscope.files
+ @$(RM) -f Makefile
+
+################################################################################
+# Dependencies:
+
+# This target should only need to be made at the UPC.
+# NOTES:
+# * The target file might be a symbolic link.
+# * The name of the target doesn't match the name of the created file to
+# prevent constant updating of the included file `depend' by make(1).
+#
+deps: FORCE
+ $(CC_MAKEDEPEND) $(CPPFLAGS) *.c | grep -v '/usr/include' >>depend
+ sort -u -o depend depend
+
+
+################################################################################
+# Distribution:
+
+# The following rule echoes the contents of $(PACKING_LIST) in the
+# current directory and in all subdirectories. All pathnames are made
+# relative to the current directory.
+#
+MANIFEST.echo: FORCE
+ echo $(PACKING_LIST) | fmt -1
+ if [ -n "$(PACKING_SUBDIRS)" ]; then \
+ subdirs="$(PACKING_SUBDIRS)"; \
+ for subdir in $$subdirs; do \
+ (cd $$subdir && \
+ echo 1>&2 Creating $@ in `pwd` && \
+ $(MAKE) $(MFLAGS) MANIFEST.echo | sed "s|^|$$subdir/|") || exit 1; \
+ done; \
+ else \
+ :; \
+ fi
+
+# The following rule ensures that all files in $(PACKING_LIST) exist in
+# the current directory and in all subdirectories.
+#
+ensure_manifest: $(PACKING_LIST) FORCE
+ if [ -n "$(SUBDIRS)" ]; then \
+ subdirs="$(SUBDIRS)"; \
+ for subdir in $$subdirs; do \
+ (cd $$subdir && \
+ echo 1>&2 Creating $@ in `pwd` && \
+ $(MAKE) $(MFLAGS) ensure_manifest) || exit 1; \
+ done; \
+ else \
+ :; \
+ fi
+
+
+################################################################################
+# Misc:
+
+FORCE:
+
+.PHONY: FORCE all library clean distclean TAGS clean_macros rmdir_src_test b-test c-test f-test
+.PHONY: subdirs $(SUBDIRS) install $(INSTALLDIRS) uninstall $(UNINSTALLDIRS)
+.PHONY: tests check testing $(CHECK_DIRS) $(PTEST_DIRS) verbose_check verbose_testing $(VCHECK_DIRS)
+.PHONY: ptest ptests ptest2 ptest4 ptest6 ptest8 ptest10
+
diff --git a/scripts/Makefile.in b/scripts/Makefile.in
new file mode 100644
index 0000000..99fe19e
--- /dev/null
+++ b/scripts/Makefile.in
@@ -0,0 +1,24 @@
+#
+# Copyright (C) 2012, Northwestern University and Argonne National Laboratory
+# See COPYRIGHT notice in top-level directory.
+#
+# $Id: Makefile.in 1388 2013-08-30 19:25:21Z wkliao $
+#
+# @configure_input@
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+include ../macros.make
+
+GARBAGE =
+
+PACKING_LIST = config.guess \
+ config.sub \
+ install-sh \
+ Makefile.in
+
+all:
+
+include $(srcdir)/../rules.make
+
diff --git a/scripts/config.guess b/scripts/config.guess
new file mode 100755
index 0000000..43f0cdb
--- /dev/null
+++ b/scripts/config.guess
@@ -0,0 +1,1519 @@
+#! /bin/sh
+# Attempt to guess a canonical system name.
+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
+# 2011 Free Software Foundation, Inc.
+
+timestamp='2011-10-01'
+
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+# 02110-1301, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+
+# Originally written by Per Bothner. Please send patches (context
+# diff format) to <config-patches at gnu.org> and include a ChangeLog
+# entry.
+#
+# This script attempts to guess a canonical system name similar to
+# config.sub. If it succeeds, it prints the system name on stdout, and
+# exits with 0. Otherwise, it exits with 1.
+#
+# You can get the latest version of this script from:
+# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION]
+
+Output the configuration name of the system \`$me' is run on.
+
+Operation modes:
+ -h, --help print this help, then exit
+ -t, --time-stamp print date of last modification, then exit
+ -v, --version print version number, then exit
+
+Report bugs and patches to <config-patches at gnu.org>."
+
+version="\
+GNU config.guess ($timestamp)
+
+Originally written by Per Bothner.
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
+2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free
+Software Foundation, Inc.
+
+This is free software; see the source for copying conditions. There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+ case $1 in
+ --time-stamp | --time* | -t )
+ echo "$timestamp" ; exit ;;
+ --version | -v )
+ echo "$version" ; exit ;;
+ --help | --h* | -h )
+ echo "$usage"; exit ;;
+ -- ) # Stop option processing
+ shift; break ;;
+ - ) # Use stdin as input.
+ break ;;
+ -* )
+ echo "$me: invalid option $1$help" >&2
+ exit 1 ;;
+ * )
+ break ;;
+ esac
+done
+
+if test $# != 0; then
+ echo "$me: too many arguments$help" >&2
+ exit 1
+fi
+
+trap 'exit 1' 1 2 15
+
+# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
+# compiler to aid in system detection is discouraged as it requires
+# temporary files to be created and, as you can see below, it is a
+# headache to deal with in a portable fashion.
+
+# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
+# use `HOST_CC' if defined, but it is deprecated.
+
+# Portable tmp directory creation inspired by the Autoconf team.
+
+set_cc_for_build='
+trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
+trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
+: ${TMPDIR=/tmp} ;
+ { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
+ { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
+ { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
+ { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
+dummy=$tmp/dummy ;
+tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
+case $CC_FOR_BUILD,$HOST_CC,$CC in
+ ,,) echo "int x;" > $dummy.c ;
+ for c in cc gcc c89 c99 ; do
+ if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
+ CC_FOR_BUILD="$c"; break ;
+ fi ;
+ done ;
+ if test x"$CC_FOR_BUILD" = x ; then
+ CC_FOR_BUILD=no_compiler_found ;
+ fi
+ ;;
+ ,,*) CC_FOR_BUILD=$CC ;;
+ ,*,*) CC_FOR_BUILD=$HOST_CC ;;
+esac ; set_cc_for_build= ;'
+
+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
+# (ghazi at noc.rutgers.edu 1994-08-24)
+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+ PATH=$PATH:/.attbin ; export PATH
+fi
+
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+
+# Note: order is significant - the case branches are not exclusive.
+
+case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+ *:NetBSD:*:*)
+ # NetBSD (nbsd) targets should (where applicable) match one or
+ # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
+ # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently
+ # switched to ELF, *-*-netbsd* would select the old
+ # object file format. This provides both forward
+ # compatibility and a consistent mechanism for selecting the
+ # object file format.
+ #
+ # Note: NetBSD doesn't particularly care about the vendor
+ # portion of the name. We always set it to "unknown".
+ sysctl="sysctl -n hw.machine_arch"
+ UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
+ /usr/sbin/$sysctl 2>/dev/null || echo unknown)`
+ case "${UNAME_MACHINE_ARCH}" in
+ armeb) machine=armeb-unknown ;;
+ arm*) machine=arm-unknown ;;
+ sh3el) machine=shl-unknown ;;
+ sh3eb) machine=sh-unknown ;;
+ sh5el) machine=sh5le-unknown ;;
+ *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
+ esac
+ # The Operating System including object format, if it has switched
+ # to ELF recently, or will in the future.
+ case "${UNAME_MACHINE_ARCH}" in
+ arm*|i386|m68k|ns32k|sh3*|sparc|vax)
+ eval $set_cc_for_build
+ if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
+ | grep -q __ELF__
+ then
+ # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
+ # Return netbsd for either. FIX?
+ os=netbsd
+ else
+ os=netbsdelf
+ fi
+ ;;
+ *)
+ os=netbsd
+ ;;
+ esac
+ # The OS release
+ # Debian GNU/NetBSD machines have a different userland, and
+ # thus, need a distinct triplet. However, they do not need
+ # kernel version information, so it can be replaced with a
+ # suitable tag, in the style of linux-gnu.
+ case "${UNAME_VERSION}" in
+ Debian*)
+ release='-gnu'
+ ;;
+ *)
+ release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+ ;;
+ esac
+ # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
+ # contains redundant information, the shorter form:
+ # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
+ echo "${machine}-${os}${release}"
+ exit ;;
+ *:OpenBSD:*:*)
+ UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
+ echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
+ exit ;;
+ *:ekkoBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
+ exit ;;
+ *:SolidBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE}
+ exit ;;
+ macppc:MirBSD:*:*)
+ echo powerpc-unknown-mirbsd${UNAME_RELEASE}
+ exit ;;
+ *:MirBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
+ exit ;;
+ alpha:OSF1:*:*)
+ case $UNAME_RELEASE in
+ *4.0)
+ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+ ;;
+ *5.*)
+ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
+ ;;
+ esac
+ # According to Compaq, /usr/sbin/psrinfo has been available on
+ # OSF/1 and Tru64 systems produced since 1995. I hope that
+ # covers most systems running today. This code pipes the CPU
+ # types through head -n 1, so we only detect the type of CPU 0.
+ ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1`
+ case "$ALPHA_CPU_TYPE" in
+ "EV4 (21064)")
+ UNAME_MACHINE="alpha" ;;
+ "EV4.5 (21064)")
+ UNAME_MACHINE="alpha" ;;
+ "LCA4 (21066/21068)")
+ UNAME_MACHINE="alpha" ;;
+ "EV5 (21164)")
+ UNAME_MACHINE="alphaev5" ;;
+ "EV5.6 (21164A)")
+ UNAME_MACHINE="alphaev56" ;;
+ "EV5.6 (21164PC)")
+ UNAME_MACHINE="alphapca56" ;;
+ "EV5.7 (21164PC)")
+ UNAME_MACHINE="alphapca57" ;;
+ "EV6 (21264)")
+ UNAME_MACHINE="alphaev6" ;;
+ "EV6.7 (21264A)")
+ UNAME_MACHINE="alphaev67" ;;
+ "EV6.8CB (21264C)")
+ UNAME_MACHINE="alphaev68" ;;
+ "EV6.8AL (21264B)")
+ UNAME_MACHINE="alphaev68" ;;
+ "EV6.8CX (21264D)")
+ UNAME_MACHINE="alphaev68" ;;
+ "EV6.9A (21264/EV69A)")
+ UNAME_MACHINE="alphaev69" ;;
+ "EV7 (21364)")
+ UNAME_MACHINE="alphaev7" ;;
+ "EV7.9 (21364A)")
+ UNAME_MACHINE="alphaev79" ;;
+ esac
+ # A Pn.n version is a patched version.
+ # A Vn.n version is a released version.
+ # A Tn.n version is a released field test version.
+ # A Xn.n version is an unreleased experimental baselevel.
+ # 1.2 uses "1.2" for uname -r.
+ echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+ # Reset EXIT trap before exiting to avoid spurious non-zero exit code.
+ exitcode=$?
+ trap '' 0
+ exit $exitcode ;;
+ Alpha\ *:Windows_NT*:*)
+ # How do we know it's Interix rather than the generic POSIX subsystem?
+ # Should we change UNAME_MACHINE based on the output of uname instead
+ # of the specific Alpha model?
+ echo alpha-pc-interix
+ exit ;;
+ 21064:Windows_NT:50:3)
+ echo alpha-dec-winnt3.5
+ exit ;;
+ Amiga*:UNIX_System_V:4.0:*)
+ echo m68k-unknown-sysv4
+ exit ;;
+ *:[Aa]miga[Oo][Ss]:*:*)
+ echo ${UNAME_MACHINE}-unknown-amigaos
+ exit ;;
+ *:[Mm]orph[Oo][Ss]:*:*)
+ echo ${UNAME_MACHINE}-unknown-morphos
+ exit ;;
+ *:OS/390:*:*)
+ echo i370-ibm-openedition
+ exit ;;
+ *:z/VM:*:*)
+ echo s390-ibm-zvmoe
+ exit ;;
+ *:OS400:*:*)
+ echo powerpc-ibm-os400
+ exit ;;
+ arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+ echo arm-acorn-riscix${UNAME_RELEASE}
+ exit ;;
+ arm:riscos:*:*|arm:RISCOS:*:*)
+ echo arm-unknown-riscos
+ exit ;;
+ SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
+ echo hppa1.1-hitachi-hiuxmpp
+ exit ;;
+ Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
+ # akee at wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
+ if test "`(/bin/universe) 2>/dev/null`" = att ; then
+ echo pyramid-pyramid-sysv3
+ else
+ echo pyramid-pyramid-bsd
+ fi
+ exit ;;
+ NILE*:*:*:dcosx)
+ echo pyramid-pyramid-svr4
+ exit ;;
+ DRS?6000:unix:4.0:6*)
+ echo sparc-icl-nx6
+ exit ;;
+ DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)
+ case `/usr/bin/uname -p` in
+ sparc) echo sparc-icl-nx7; exit ;;
+ esac ;;
+ s390x:SunOS:*:*)
+ echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ sun4H:SunOS:5.*:*)
+ echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+ echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)
+ echo i386-pc-auroraux${UNAME_RELEASE}
+ exit ;;
+ i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
+ eval $set_cc_for_build
+ SUN_ARCH="i386"
+ # If there is a compiler, see if it is configured for 64-bit objects.
+ # Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
+ # This test works for both compilers.
+ if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+ if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
+ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+ grep IS_64BIT_ARCH >/dev/null
+ then
+ SUN_ARCH="x86_64"
+ fi
+ fi
+ echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ sun4*:SunOS:6*:*)
+ # According to config.sub, this is the proper way to canonicalize
+ # SunOS6. Hard to guess exactly what SunOS6 will be like, but
+ # it's likely to be more like Solaris than SunOS4.
+ echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ sun4*:SunOS:*:*)
+ case "`/usr/bin/arch -k`" in
+ Series*|S4*)
+ UNAME_RELEASE=`uname -v`
+ ;;
+ esac
+ # Japanese Language versions have a version number like `4.1.3-JL'.
+ echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+ exit ;;
+ sun3*:SunOS:*:*)
+ echo m68k-sun-sunos${UNAME_RELEASE}
+ exit ;;
+ sun*:*:4.2BSD:*)
+ UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+ test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+ case "`/bin/arch`" in
+ sun3)
+ echo m68k-sun-sunos${UNAME_RELEASE}
+ ;;
+ sun4)
+ echo sparc-sun-sunos${UNAME_RELEASE}
+ ;;
+ esac
+ exit ;;
+ aushp:SunOS:*:*)
+ echo sparc-auspex-sunos${UNAME_RELEASE}
+ exit ;;
+ # The situation for MiNT is a little confusing. The machine name
+ # can be virtually everything (everything which is not
+ # "atarist" or "atariste" at least should have a processor
+ # > m68000). The system name ranges from "MiNT" over "FreeMiNT"
+ # to the lowercase version "mint" (or "freemint"). Finally
+ # the system name "TOS" denotes a system which is actually not
+ # MiNT. But MiNT is downward compatible to TOS, so this should
+ # be no problem.
+ atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit ;;
+ atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit ;;
+ *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit ;;
+ milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
+ echo m68k-milan-mint${UNAME_RELEASE}
+ exit ;;
+ hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
+ echo m68k-hades-mint${UNAME_RELEASE}
+ exit ;;
+ *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
+ echo m68k-unknown-mint${UNAME_RELEASE}
+ exit ;;
+ m68k:machten:*:*)
+ echo m68k-apple-machten${UNAME_RELEASE}
+ exit ;;
+ powerpc:machten:*:*)
+ echo powerpc-apple-machten${UNAME_RELEASE}
+ exit ;;
+ RISC*:Mach:*:*)
+ echo mips-dec-mach_bsd4.3
+ exit ;;
+ RISC*:ULTRIX:*:*)
+ echo mips-dec-ultrix${UNAME_RELEASE}
+ exit ;;
+ VAX*:ULTRIX*:*:*)
+ echo vax-dec-ultrix${UNAME_RELEASE}
+ exit ;;
+ 2020:CLIX:*:* | 2430:CLIX:*:*)
+ echo clipper-intergraph-clix${UNAME_RELEASE}
+ exit ;;
+ mips:*:*:UMIPS | mips:*:*:RISCos)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+#ifdef __cplusplus
+#include <stdio.h> /* for printf() prototype */
+ int main (int argc, char *argv[]) {
+#else
+ int main (argc, argv) int argc; char *argv[]; {
+#endif
+ #if defined (host_mips) && defined (MIPSEB)
+ #if defined (SYSTYPE_SYSV)
+ printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+ #endif
+ #if defined (SYSTYPE_SVR4)
+ printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+ #endif
+ #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
+ printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+ #endif
+ #endif
+ exit (-1);
+ }
+EOF
+ $CC_FOR_BUILD -o $dummy $dummy.c &&
+ dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` &&
+ SYSTEM_NAME=`$dummy $dummyarg` &&
+ { echo "$SYSTEM_NAME"; exit; }
+ echo mips-mips-riscos${UNAME_RELEASE}
+ exit ;;
+ Motorola:PowerMAX_OS:*:*)
+ echo powerpc-motorola-powermax
+ exit ;;
+ Motorola:*:4.3:PL8-*)
+ echo powerpc-harris-powermax
+ exit ;;
+ Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
+ echo powerpc-harris-powermax
+ exit ;;
+ Night_Hawk:Power_UNIX:*:*)
+ echo powerpc-harris-powerunix
+ exit ;;
+ m88k:CX/UX:7*:*)
+ echo m88k-harris-cxux7
+ exit ;;
+ m88k:*:4*:R4*)
+ echo m88k-motorola-sysv4
+ exit ;;
+ m88k:*:3*:R3*)
+ echo m88k-motorola-sysv3
+ exit ;;
+ AViiON:dgux:*:*)
+ # DG/UX returns AViiON for all architectures
+ UNAME_PROCESSOR=`/usr/bin/uname -p`
+ if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
+ then
+ if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
+ [ ${TARGET_BINARY_INTERFACE}x = x ]
+ then
+ echo m88k-dg-dgux${UNAME_RELEASE}
+ else
+ echo m88k-dg-dguxbcs${UNAME_RELEASE}
+ fi
+ else
+ echo i586-dg-dgux${UNAME_RELEASE}
+ fi
+ exit ;;
+ M88*:DolphinOS:*:*) # DolphinOS (SVR3)
+ echo m88k-dolphin-sysv3
+ exit ;;
+ M88*:*:R3*:*)
+ # Delta 88k system running SVR3
+ echo m88k-motorola-sysv3
+ exit ;;
+ XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+ echo m88k-tektronix-sysv3
+ exit ;;
+ Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+ echo m68k-tektronix-bsd
+ exit ;;
+ *:IRIX*:*:*)
+ echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+ exit ;;
+ ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+ echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id
+ exit ;; # Note that: echo "'`uname -s`'" gives 'AIX '
+ i*86:AIX:*:*)
+ echo i386-ibm-aix
+ exit ;;
+ ia64:AIX:*:*)
+ if [ -x /usr/bin/oslevel ] ; then
+ IBM_REV=`/usr/bin/oslevel`
+ else
+ IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+ fi
+ echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
+ exit ;;
+ *:AIX:2:3)
+ if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #include <sys/systemcfg.h>
+
+ main()
+ {
+ if (!__power_pc())
+ exit(1);
+ puts("powerpc-ibm-aix3.2.5");
+ exit(0);
+ }
+EOF
+ if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy`
+ then
+ echo "$SYSTEM_NAME"
+ else
+ echo rs6000-ibm-aix3.2.5
+ fi
+ elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+ echo rs6000-ibm-aix3.2.4
+ else
+ echo rs6000-ibm-aix3.2
+ fi
+ exit ;;
+ *:AIX:*:[4567])
+ IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
+ if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
+ IBM_ARCH=rs6000
+ else
+ IBM_ARCH=powerpc
+ fi
+ if [ -x /usr/bin/oslevel ] ; then
+ IBM_REV=`/usr/bin/oslevel`
+ else
+ IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+ fi
+ echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+ exit ;;
+ *:AIX:*:*)
+ echo rs6000-ibm-aix
+ exit ;;
+ ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+ echo romp-ibm-bsd4.4
+ exit ;;
+ ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and
+ echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to
+ exit ;; # report: romp-ibm BSD 4.3
+ *:BOSX:*:*)
+ echo rs6000-bull-bosx
+ exit ;;
+ DPX/2?00:B.O.S.:*:*)
+ echo m68k-bull-sysv3
+ exit ;;
+ 9000/[34]??:4.3bsd:1.*:*)
+ echo m68k-hp-bsd
+ exit ;;
+ hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+ echo m68k-hp-bsd4.4
+ exit ;;
+ 9000/[34678]??:HP-UX:*:*)
+ HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+ case "${UNAME_MACHINE}" in
+ 9000/31? ) HP_ARCH=m68000 ;;
+ 9000/[34]?? ) HP_ARCH=m68k ;;
+ 9000/[678][0-9][0-9])
+ if [ -x /usr/bin/getconf ]; then
+ sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
+ sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+ case "${sc_cpu_version}" in
+ 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
+ 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+ 532) # CPU_PA_RISC2_0
+ case "${sc_kernel_bits}" in
+ 32) HP_ARCH="hppa2.0n" ;;
+ 64) HP_ARCH="hppa2.0w" ;;
+ '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20
+ esac ;;
+ esac
+ fi
+ if [ "${HP_ARCH}" = "" ]; then
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+
+ #define _HPUX_SOURCE
+ #include <stdlib.h>
+ #include <unistd.h>
+
+ int main ()
+ {
+ #if defined(_SC_KERNEL_BITS)
+ long bits = sysconf(_SC_KERNEL_BITS);
+ #endif
+ long cpu = sysconf (_SC_CPU_VERSION);
+
+ switch (cpu)
+ {
+ case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+ case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+ case CPU_PA_RISC2_0:
+ #if defined(_SC_KERNEL_BITS)
+ switch (bits)
+ {
+ case 64: puts ("hppa2.0w"); break;
+ case 32: puts ("hppa2.0n"); break;
+ default: puts ("hppa2.0"); break;
+ } break;
+ #else /* !defined(_SC_KERNEL_BITS) */
+ puts ("hppa2.0"); break;
+ #endif
+ default: puts ("hppa1.0"); break;
+ }
+ exit (0);
+ }
+EOF
+ (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
+ test -z "$HP_ARCH" && HP_ARCH=hppa
+ fi ;;
+ esac
+ if [ ${HP_ARCH} = "hppa2.0w" ]
+ then
+ eval $set_cc_for_build
+
+ # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating
+ # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler
+ # generating 64-bit code. GNU and HP use different nomenclature:
+ #
+ # $ CC_FOR_BUILD=cc ./config.guess
+ # => hppa2.0w-hp-hpux11.23
+ # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess
+ # => hppa64-hp-hpux11.23
+
+ if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
+ grep -q __LP64__
+ then
+ HP_ARCH="hppa2.0w"
+ else
+ HP_ARCH="hppa64"
+ fi
+ fi
+ echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+ exit ;;
+ ia64:HP-UX:*:*)
+ HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+ echo ia64-hp-hpux${HPUX_REV}
+ exit ;;
+ 3050*:HI-UX:*:*)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #include <unistd.h>
+ int
+ main ()
+ {
+ long cpu = sysconf (_SC_CPU_VERSION);
+ /* The order matters, because CPU_IS_HP_MC68K erroneously returns
+ true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct
+ results, however. */
+ if (CPU_IS_PA_RISC (cpu))
+ {
+ switch (cpu)
+ {
+ case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
+ case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
+ case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
+ default: puts ("hppa-hitachi-hiuxwe2"); break;
+ }
+ }
+ else if (CPU_IS_HP_MC68K (cpu))
+ puts ("m68k-hitachi-hiuxwe2");
+ else puts ("unknown-hitachi-hiuxwe2");
+ exit (0);
+ }
+EOF
+ $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` &&
+ { echo "$SYSTEM_NAME"; exit; }
+ echo unknown-hitachi-hiuxwe2
+ exit ;;
+ 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+ echo hppa1.1-hp-bsd
+ exit ;;
+ 9000/8??:4.3bsd:*:*)
+ echo hppa1.0-hp-bsd
+ exit ;;
+ *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
+ echo hppa1.0-hp-mpeix
+ exit ;;
+ hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+ echo hppa1.1-hp-osf
+ exit ;;
+ hp8??:OSF1:*:*)
+ echo hppa1.0-hp-osf
+ exit ;;
+ i*86:OSF1:*:*)
+ if [ -x /usr/sbin/sysversion ] ; then
+ echo ${UNAME_MACHINE}-unknown-osf1mk
+ else
+ echo ${UNAME_MACHINE}-unknown-osf1
+ fi
+ exit ;;
+ parisc*:Lites*:*:*)
+ echo hppa1.1-hp-lites
+ exit ;;
+ C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+ echo c1-convex-bsd
+ exit ;;
+ C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+ if getsysinfo -f scalar_acc
+ then echo c32-convex-bsd
+ else echo c2-convex-bsd
+ fi
+ exit ;;
+ C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+ echo c34-convex-bsd
+ exit ;;
+ C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+ echo c38-convex-bsd
+ exit ;;
+ C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+ echo c4-convex-bsd
+ exit ;;
+ CRAY*Y-MP:*:*:*)
+ echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ CRAY*[A-Z]90:*:*:*)
+ echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
+ -e 's/\.[^.]*$/.X/'
+ exit ;;
+ CRAY*TS:*:*:*)
+ echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ CRAY*T3E:*:*:*)
+ echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ CRAY*SV1:*:*:*)
+ echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ *:UNICOS/mp:*:*)
+ echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
+ FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+ FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+ FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+ echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+ exit ;;
+ 5000:UNIX_System_V:4.*:*)
+ FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+ FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
+ echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+ exit ;;
+ i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
+ echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+ exit ;;
+ sparc*:BSD/OS:*:*)
+ echo sparc-unknown-bsdi${UNAME_RELEASE}
+ exit ;;
+ *:BSD/OS:*:*)
+ echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+ exit ;;
+ *:FreeBSD:*:*)
+ UNAME_PROCESSOR=`/usr/bin/uname -p`
+ case ${UNAME_PROCESSOR} in
+ amd64)
+ echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+ *)
+ echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+ esac
+ exit ;;
+ i*:CYGWIN*:*)
+ echo ${UNAME_MACHINE}-pc-cygwin
+ exit ;;
+ *:MINGW*:*)
+ echo ${UNAME_MACHINE}-pc-mingw32
+ exit ;;
+ i*:windows32*:*)
+ # uname -m includes "-pc" on this system.
+ echo ${UNAME_MACHINE}-mingw32
+ exit ;;
+ i*:PW*:*)
+ echo ${UNAME_MACHINE}-pc-pw32
+ exit ;;
+ *:Interix*:*)
+ case ${UNAME_MACHINE} in
+ x86)
+ echo i586-pc-interix${UNAME_RELEASE}
+ exit ;;
+ authenticamd | genuineintel | EM64T)
+ echo x86_64-unknown-interix${UNAME_RELEASE}
+ exit ;;
+ IA64)
+ echo ia64-unknown-interix${UNAME_RELEASE}
+ exit ;;
+ esac ;;
+ [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
+ echo i${UNAME_MACHINE}-pc-mks
+ exit ;;
+ 8664:Windows_NT:*)
+ echo x86_64-pc-mks
+ exit ;;
+ i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
+ # How do we know it's Interix rather than the generic POSIX subsystem?
+ # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
+ # UNAME_MACHINE based on the output of uname instead of i386?
+ echo i586-pc-interix
+ exit ;;
+ i*:UWIN*:*)
+ echo ${UNAME_MACHINE}-pc-uwin
+ exit ;;
+ amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)
+ echo x86_64-unknown-cygwin
+ exit ;;
+ p*:CYGWIN*:*)
+ echo powerpcle-unknown-cygwin
+ exit ;;
+ prep*:SunOS:5.*:*)
+ echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ *:GNU:*:*)
+ # the GNU system
+ echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+ exit ;;
+ *:GNU/*:*:*)
+ # other systems with GNU libc and userland
+ echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu
+ exit ;;
+ i*86:Minix:*:*)
+ echo ${UNAME_MACHINE}-pc-minix
+ exit ;;
+ alpha:Linux:*:*)
+ case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+ EV5) UNAME_MACHINE=alphaev5 ;;
+ EV56) UNAME_MACHINE=alphaev56 ;;
+ PCA56) UNAME_MACHINE=alphapca56 ;;
+ PCA57) UNAME_MACHINE=alphapca56 ;;
+ EV6) UNAME_MACHINE=alphaev6 ;;
+ EV67) UNAME_MACHINE=alphaev67 ;;
+ EV68*) UNAME_MACHINE=alphaev68 ;;
+ esac
+ objdump --private-headers /bin/sh | grep -q ld.so.1
+ if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
+ echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
+ exit ;;
+ arm*:Linux:*:*)
+ eval $set_cc_for_build
+ if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
+ | grep -q __ARM_EABI__
+ then
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ else
+ if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
+ | grep -q __ARM_PCS_VFP
+ then
+ echo ${UNAME_MACHINE}-unknown-linux-gnueabi
+ else
+ echo ${UNAME_MACHINE}-unknown-linux-gnueabihf
+ fi
+ fi
+ exit ;;
+ avr32*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ cris:Linux:*:*)
+ echo cris-axis-linux-gnu
+ exit ;;
+ crisv32:Linux:*:*)
+ echo crisv32-axis-linux-gnu
+ exit ;;
+ frv:Linux:*:*)
+ echo frv-unknown-linux-gnu
+ exit ;;
+ hexagon:Linux:*:*)
+ echo hexagon-unknown-linux-gnu
+ exit ;;
+ i*86:Linux:*:*)
+ LIBC=gnu
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #ifdef __dietlibc__
+ LIBC=dietlibc
+ #endif
+EOF
+ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'`
+ echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
+ exit ;;
+ ia64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ m32r*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ m68*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ mips:Linux:*:* | mips64:Linux:*:*)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #undef CPU
+ #undef ${UNAME_MACHINE}
+ #undef ${UNAME_MACHINE}el
+ #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+ CPU=${UNAME_MACHINE}el
+ #else
+ #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+ CPU=${UNAME_MACHINE}
+ #else
+ CPU=
+ #endif
+ #endif
+EOF
+ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
+ test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
+ ;;
+ or32:Linux:*:*)
+ echo or32-unknown-linux-gnu
+ exit ;;
+ padre:Linux:*:*)
+ echo sparc-unknown-linux-gnu
+ exit ;;
+ parisc64:Linux:*:* | hppa64:Linux:*:*)
+ echo hppa64-unknown-linux-gnu
+ exit ;;
+ parisc:Linux:*:* | hppa:Linux:*:*)
+ # Look for CPU level
+ case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
+ PA7*) echo hppa1.1-unknown-linux-gnu ;;
+ PA8*) echo hppa2.0-unknown-linux-gnu ;;
+ *) echo hppa-unknown-linux-gnu ;;
+ esac
+ exit ;;
+ ppc64:Linux:*:*)
+ echo powerpc64-unknown-linux-gnu
+ exit ;;
+ ppc:Linux:*:*)
+ echo powerpc-unknown-linux-gnu
+ exit ;;
+ s390:Linux:*:* | s390x:Linux:*:*)
+ echo ${UNAME_MACHINE}-ibm-linux
+ exit ;;
+ sh64*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ sh*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ sparc:Linux:*:* | sparc64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ tile*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ vax:Linux:*:*)
+ echo ${UNAME_MACHINE}-dec-linux-gnu
+ exit ;;
+ x86_64:Linux:*:*)
+ echo x86_64-unknown-linux-gnu
+ exit ;;
+ xtensa*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ i*86:DYNIX/ptx:4*:*)
+ # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
+ # earlier versions are messed up and put the nodename in both
+ # sysname and nodename.
+ echo i386-sequent-sysv4
+ exit ;;
+ i*86:UNIX_SV:4.2MP:2.*)
+ # Unixware is an offshoot of SVR4, but it has its own version
+ # number series starting with 2...
+ # I am not positive that other SVR4 systems won't match this,
+ # I just have to hope. -- rms.
+ # Use sysv4.2uw... so that sysv4* matches it.
+ echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+ exit ;;
+ i*86:OS/2:*:*)
+ # If we were able to find `uname', then EMX Unix compatibility
+ # is probably installed.
+ echo ${UNAME_MACHINE}-pc-os2-emx
+ exit ;;
+ i*86:XTS-300:*:STOP)
+ echo ${UNAME_MACHINE}-unknown-stop
+ exit ;;
+ i*86:atheos:*:*)
+ echo ${UNAME_MACHINE}-unknown-atheos
+ exit ;;
+ i*86:syllable:*:*)
+ echo ${UNAME_MACHINE}-pc-syllable
+ exit ;;
+ i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*)
+ echo i386-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ i*86:*DOS:*:*)
+ echo ${UNAME_MACHINE}-pc-msdosdjgpp
+ exit ;;
+ i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
+ UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
+ if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+ echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
+ else
+ echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
+ fi
+ exit ;;
+ i*86:*:5:[678]*)
+ # UnixWare 7.x, OpenUNIX and OpenServer 6.
+ case `/bin/uname -X | grep "^Machine"` in
+ *486*) UNAME_MACHINE=i486 ;;
+ *Pentium) UNAME_MACHINE=i586 ;;
+ *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
+ esac
+ echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
+ exit ;;
+ i*86:*:3.2:*)
+ if test -f /usr/options/cb.name; then
+ UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+ echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+ elif /bin/uname -X 2>/dev/null >/dev/null ; then
+ UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
+ (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
+ (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
+ && UNAME_MACHINE=i586
+ (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
+ && UNAME_MACHINE=i686
+ (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
+ && UNAME_MACHINE=i686
+ echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+ else
+ echo ${UNAME_MACHINE}-pc-sysv32
+ fi
+ exit ;;
+ pc:*:*:*)
+ # Left here for compatibility:
+ # uname -m prints for DJGPP always 'pc', but it prints nothing about
+ # the processor, so we play safe by assuming i586.
+ # Note: whatever this is, it MUST be the same as what config.sub
+ # prints for the "djgpp" host, or else GDB configury will decide that
+ # this is a cross-build.
+ echo i586-pc-msdosdjgpp
+ exit ;;
+ Intel:Mach:3*:*)
+ echo i386-pc-mach3
+ exit ;;
+ paragon:*:*:*)
+ echo i860-intel-osf1
+ exit ;;
+ i860:*:4.*:*) # i860-SVR4
+ if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+ echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+ else # Add other i860-SVR4 vendors below as they are discovered.
+ echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4
+ fi
+ exit ;;
+ mini*:CTIX:SYS*5:*)
+ # "miniframe"
+ echo m68010-convergent-sysv
+ exit ;;
+ mc68k:UNIX:SYSTEM5:3.51m)
+ echo m68k-convergent-sysv
+ exit ;;
+ M680?0:D-NIX:5.3:*)
+ echo m68k-diab-dnix
+ exit ;;
+ M68*:*:R3V[5678]*:*)
+ test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;;
+ 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)
+ OS_REL=''
+ test -r /etc/.relid \
+ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+ /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+ 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && { echo i486-ncr-sysv4; exit; } ;;
+ NCR*:*:4.2:* | MPRAS*:*:4.2:*)
+ OS_REL='.3'
+ test -r /etc/.relid \
+ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+ /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+ && { echo i586-ncr-sysv4.3${OS_REL}; exit; }
+ /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \
+ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+ m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
+ echo m68k-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ mc68030:UNIX_System_V:4.*:*)
+ echo m68k-atari-sysv4
+ exit ;;
+ TSUNAMI:LynxOS:2.*:*)
+ echo sparc-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ rs6000:LynxOS:2.*:*)
+ echo rs6000-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*)
+ echo powerpc-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ SM[BE]S:UNIX_SV:*:*)
+ echo mips-dde-sysv${UNAME_RELEASE}
+ exit ;;
+ RM*:ReliantUNIX-*:*:*)
+ echo mips-sni-sysv4
+ exit ;;
+ RM*:SINIX-*:*:*)
+ echo mips-sni-sysv4
+ exit ;;
+ *:SINIX-*:*:*)
+ if uname -p 2>/dev/null >/dev/null ; then
+ UNAME_MACHINE=`(uname -p) 2>/dev/null`
+ echo ${UNAME_MACHINE}-sni-sysv4
+ else
+ echo ns32k-sni-sysv
+ fi
+ exit ;;
+ PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+ # says <Richard.M.Bartel at ccMail.Census.GOV>
+ echo i586-unisys-sysv4
+ exit ;;
+ *:UNIX_System_V:4*:FTX*)
+ # From Gerald Hewes <hewes at openmarket.com>.
+ # How about differentiating between stratus architectures? -djm
+ echo hppa1.1-stratus-sysv4
+ exit ;;
+ *:*:*:FTX*)
+ # From seanf at swdc.stratus.com.
+ echo i860-stratus-sysv4
+ exit ;;
+ i*86:VOS:*:*)
+ # From Paul.Green at stratus.com.
+ echo ${UNAME_MACHINE}-stratus-vos
+ exit ;;
+ *:VOS:*:*)
+ # From Paul.Green at stratus.com.
+ echo hppa1.1-stratus-vos
+ exit ;;
+ mc68*:A/UX:*:*)
+ echo m68k-apple-aux${UNAME_RELEASE}
+ exit ;;
+ news*:NEWS-OS:6*:*)
+ echo mips-sony-newsos6
+ exit ;;
+ R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
+ if [ -d /usr/nec ]; then
+ echo mips-nec-sysv${UNAME_RELEASE}
+ else
+ echo mips-unknown-sysv${UNAME_RELEASE}
+ fi
+ exit ;;
+ BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
+ echo powerpc-be-beos
+ exit ;;
+ BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only.
+ echo powerpc-apple-beos
+ exit ;;
+ BePC:BeOS:*:*) # BeOS running on Intel PC compatible.
+ echo i586-pc-beos
+ exit ;;
+ BePC:Haiku:*:*) # Haiku running on Intel PC compatible.
+ echo i586-pc-haiku
+ exit ;;
+ SX-4:SUPER-UX:*:*)
+ echo sx4-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-5:SUPER-UX:*:*)
+ echo sx5-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-6:SUPER-UX:*:*)
+ echo sx6-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-7:SUPER-UX:*:*)
+ echo sx7-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-8:SUPER-UX:*:*)
+ echo sx8-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-8R:SUPER-UX:*:*)
+ echo sx8r-nec-superux${UNAME_RELEASE}
+ exit ;;
+ Power*:Rhapsody:*:*)
+ echo powerpc-apple-rhapsody${UNAME_RELEASE}
+ exit ;;
+ *:Rhapsody:*:*)
+ echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
+ exit ;;
+ *:Darwin:*:*)
+ UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
+ case $UNAME_PROCESSOR in
+ i386)
+ eval $set_cc_for_build
+ if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+ if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
+ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+ grep IS_64BIT_ARCH >/dev/null
+ then
+ UNAME_PROCESSOR="x86_64"
+ fi
+ fi ;;
+ unknown) UNAME_PROCESSOR=powerpc ;;
+ esac
+ echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
+ exit ;;
+ *:procnto*:*:* | *:QNX:[0123456789]*:*)
+ UNAME_PROCESSOR=`uname -p`
+ if test "$UNAME_PROCESSOR" = "x86"; then
+ UNAME_PROCESSOR=i386
+ UNAME_MACHINE=pc
+ fi
+ echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
+ exit ;;
+ *:QNX:*:4*)
+ echo i386-pc-qnx
+ exit ;;
+ NEO-?:NONSTOP_KERNEL:*:*)
+ echo neo-tandem-nsk${UNAME_RELEASE}
+ exit ;;
+ NSE-?:NONSTOP_KERNEL:*:*)
+ echo nse-tandem-nsk${UNAME_RELEASE}
+ exit ;;
+ NSR-?:NONSTOP_KERNEL:*:*)
+ echo nsr-tandem-nsk${UNAME_RELEASE}
+ exit ;;
+ *:NonStop-UX:*:*)
+ echo mips-compaq-nonstopux
+ exit ;;
+ BS2000:POSIX*:*:*)
+ echo bs2000-siemens-sysv
+ exit ;;
+ DS/*:UNIX_System_V:*:*)
+ echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
+ exit ;;
+ *:Plan9:*:*)
+ # "uname -m" is not consistent, so use $cputype instead. 386
+ # is converted to i386 for consistency with other x86
+ # operating systems.
+ if test "$cputype" = "386"; then
+ UNAME_MACHINE=i386
+ else
+ UNAME_MACHINE="$cputype"
+ fi
+ echo ${UNAME_MACHINE}-unknown-plan9
+ exit ;;
+ *:TOPS-10:*:*)
+ echo pdp10-unknown-tops10
+ exit ;;
+ *:TENEX:*:*)
+ echo pdp10-unknown-tenex
+ exit ;;
+ KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
+ echo pdp10-dec-tops20
+ exit ;;
+ XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
+ echo pdp10-xkl-tops20
+ exit ;;
+ *:TOPS-20:*:*)
+ echo pdp10-unknown-tops20
+ exit ;;
+ *:ITS:*:*)
+ echo pdp10-unknown-its
+ exit ;;
+ SEI:*:*:SEIUX)
+ echo mips-sei-seiux${UNAME_RELEASE}
+ exit ;;
+ *:DragonFly:*:*)
+ echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+ exit ;;
+ *:*VMS:*:*)
+ UNAME_MACHINE=`(uname -p) 2>/dev/null`
+ case "${UNAME_MACHINE}" in
+ A*) echo alpha-dec-vms ; exit ;;
+ I*) echo ia64-dec-vms ; exit ;;
+ V*) echo vax-dec-vms ; exit ;;
+ esac ;;
+ *:XENIX:*:SysV)
+ echo i386-pc-xenix
+ exit ;;
+ i*86:skyos:*:*)
+ echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//'
+ exit ;;
+ i*86:rdos:*:*)
+ echo ${UNAME_MACHINE}-pc-rdos
+ exit ;;
+ i*86:AROS:*:*)
+ echo ${UNAME_MACHINE}-pc-aros
+ exit ;;
+esac
+
+#echo '(No uname command or uname output not recognized.)' 1>&2
+#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
+
+eval $set_cc_for_build
+cat >$dummy.c <<EOF
+#ifdef _SEQUENT_
+# include <sys/types.h>
+# include <sys/utsname.h>
+#endif
+main ()
+{
+#if defined (sony)
+#if defined (MIPSEB)
+ /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed,
+ I don't know.... */
+ printf ("mips-sony-bsd\n"); exit (0);
+#else
+#include <sys/param.h>
+ printf ("m68k-sony-newsos%s\n",
+#ifdef NEWSOS4
+ "4"
+#else
+ ""
+#endif
+ ); exit (0);
+#endif
+#endif
+
+#if defined (__arm) && defined (__acorn) && defined (__unix)
+ printf ("arm-acorn-riscix\n"); exit (0);
+#endif
+
+#if defined (hp300) && !defined (hpux)
+ printf ("m68k-hp-bsd\n"); exit (0);
+#endif
+
+#if defined (NeXT)
+#if !defined (__ARCHITECTURE__)
+#define __ARCHITECTURE__ "m68k"
+#endif
+ int version;
+ version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+ if (version < 4)
+ printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+ else
+ printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
+ exit (0);
+#endif
+
+#if defined (MULTIMAX) || defined (n16)
+#if defined (UMAXV)
+ printf ("ns32k-encore-sysv\n"); exit (0);
+#else
+#if defined (CMU)
+ printf ("ns32k-encore-mach\n"); exit (0);
+#else
+ printf ("ns32k-encore-bsd\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (__386BSD__)
+ printf ("i386-pc-bsd\n"); exit (0);
+#endif
+
+#if defined (sequent)
+#if defined (i386)
+ printf ("i386-sequent-dynix\n"); exit (0);
+#endif
+#if defined (ns32000)
+ printf ("ns32k-sequent-dynix\n"); exit (0);
+#endif
+#endif
+
+#if defined (_SEQUENT_)
+ struct utsname un;
+
+ uname(&un);
+
+ if (strncmp(un.version, "V2", 2) == 0) {
+ printf ("i386-sequent-ptx2\n"); exit (0);
+ }
+ if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+ printf ("i386-sequent-ptx1\n"); exit (0);
+ }
+ printf ("i386-sequent-ptx\n"); exit (0);
+
+#endif
+
+#if defined (vax)
+# if !defined (ultrix)
+# include <sys/param.h>
+# if defined (BSD)
+# if BSD == 43
+ printf ("vax-dec-bsd4.3\n"); exit (0);
+# else
+# if BSD == 199006
+ printf ("vax-dec-bsd4.3reno\n"); exit (0);
+# else
+ printf ("vax-dec-bsd\n"); exit (0);
+# endif
+# endif
+# else
+ printf ("vax-dec-bsd\n"); exit (0);
+# endif
+# else
+ printf ("vax-dec-ultrix\n"); exit (0);
+# endif
+#endif
+
+#if defined (alliant) && defined (i860)
+ printf ("i860-alliant-bsd\n"); exit (0);
+#endif
+
+ exit (1);
+}
+EOF
+
+$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` &&
+ { echo "$SYSTEM_NAME"; exit; }
+
+# Apollos put the system type in the environment.
+
+test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; }
+
+# Convex versions that predate uname can use getsysinfo(1)
+
+if [ -x /usr/convex/getsysinfo ]
+then
+ case `getsysinfo -f cpu_type` in
+ c1*)
+ echo c1-convex-bsd
+ exit ;;
+ c2*)
+ if getsysinfo -f scalar_acc
+ then echo c32-convex-bsd
+ else echo c2-convex-bsd
+ fi
+ exit ;;
+ c34*)
+ echo c34-convex-bsd
+ exit ;;
+ c38*)
+ echo c38-convex-bsd
+ exit ;;
+ c4*)
+ echo c4-convex-bsd
+ exit ;;
+ esac
+fi
+
+cat >&2 <<EOF
+$0: unable to guess system type
+
+This script, last modified $timestamp, has failed to recognize
+the operating system you are using. It is advised that you
+download the most up to date version of the config scripts from
+
+ http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
+and
+ http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
+
+If the version you run ($0) is already up to date, please
+send the following data and any information you think might be
+pertinent to <config-patches at gnu.org> in order to provide the needed
+information to handle your system.
+
+config.guess timestamp = $timestamp
+
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
+/bin/uname -X = `(/bin/uname -X) 2>/dev/null`
+
+hostinfo = `(hostinfo) 2>/dev/null`
+/bin/universe = `(/bin/universe) 2>/dev/null`
+/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null`
+/bin/arch = `(/bin/arch) 2>/dev/null`
+/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
+
+UNAME_MACHINE = ${UNAME_MACHINE}
+UNAME_RELEASE = ${UNAME_RELEASE}
+UNAME_SYSTEM = ${UNAME_SYSTEM}
+UNAME_VERSION = ${UNAME_VERSION}
+EOF
+
+exit 1
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/scripts/config.sub b/scripts/config.sub
new file mode 100755
index 0000000..5b87368
--- /dev/null
+++ b/scripts/config.sub
@@ -0,0 +1,1767 @@
+#! /bin/sh
+# Configuration validation subroutine script.
+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
+# 2011 Free Software Foundation, Inc.
+
+timestamp='2011-10-08'
+
+# This file is (in principle) common to ALL GNU software.
+# The presence of a machine in this file suggests that SOME GNU software
+# can handle that machine. It does not imply ALL GNU software can.
+#
+# This file is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+# 02110-1301, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+
+# Please send patches to <config-patches at gnu.org>. Submit a context
+# diff and a properly formatted GNU ChangeLog entry.
+#
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# You can get the latest version of this script from:
+# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support. The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION] CPU-MFR-OPSYS
+ $0 [OPTION] ALIAS
+
+Canonicalize a configuration name.
+
+Operation modes:
+ -h, --help print this help, then exit
+ -t, --time-stamp print date of last modification, then exit
+ -v, --version print version number, then exit
+
+Report bugs and patches to <config-patches at gnu.org>."
+
+version="\
+GNU config.sub ($timestamp)
+
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
+2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free
+Software Foundation, Inc.
+
+This is free software; see the source for copying conditions. There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+ case $1 in
+ --time-stamp | --time* | -t )
+ echo "$timestamp" ; exit ;;
+ --version | -v )
+ echo "$version" ; exit ;;
+ --help | --h* | -h )
+ echo "$usage"; exit ;;
+ -- ) # Stop option processing
+ shift; break ;;
+ - ) # Use stdin as input.
+ break ;;
+ -* )
+ echo "$me: invalid option $1$help"
+ exit 1 ;;
+
+ *local*)
+ # First pass through any local machine types.
+ echo $1
+ exit ;;
+
+ * )
+ break ;;
+ esac
+done
+
+case $# in
+ 0) echo "$me: missing argument$help" >&2
+ exit 1;;
+ 1) ;;
+ *) echo "$me: too many arguments$help" >&2
+ exit 1;;
+esac
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+ nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
+ linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
+ knetbsd*-gnu* | netbsd*-gnu* | \
+ kopensolaris*-gnu* | \
+ storm-chaos* | os2-emx* | rtmk-nova*)
+ os=-$maybe_os
+ basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+ ;;
+ *)
+ basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+ if [ $basic_machine != $1 ]
+ then os=`echo $1 | sed 's/.*-/-/'`
+ else os=; fi
+ ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work. We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+ -sun*os*)
+ # Prevent following clause from handling this invalid input.
+ ;;
+ -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+ -apple | -axis | -knuth | -cray | -microblaze)
+ os=
+ basic_machine=$1
+ ;;
+ -bluegene*)
+ os=-cnk
+ ;;
+ -sim | -cisco | -oki | -wec | -winbond)
+ os=
+ basic_machine=$1
+ ;;
+ -scout)
+ ;;
+ -wrs)
+ os=-vxworks
+ basic_machine=$1
+ ;;
+ -chorusos*)
+ os=-chorusos
+ basic_machine=$1
+ ;;
+ -chorusrdb)
+ os=-chorusrdb
+ basic_machine=$1
+ ;;
+ -hiux*)
+ os=-hiuxwe2
+ ;;
+ -sco6)
+ os=-sco5v6
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco5)
+ os=-sco3.2v5
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco4)
+ os=-sco3.2v4
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco3.2.[4-9]*)
+ os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco3.2v[4-9]*)
+ # Don't forget version if it is 3.2v4 or newer.
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco5v6*)
+ # Don't forget version if it is 3.2v4 or newer.
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco*)
+ os=-sco3.2v2
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -udk*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -isc)
+ os=-isc2.2
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -clix*)
+ basic_machine=clipper-intergraph
+ ;;
+ -isc*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -lynx*)
+ os=-lynxos
+ ;;
+ -ptx*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+ ;;
+ -windowsnt*)
+ os=`echo $os | sed -e 's/windowsnt/winnt/'`
+ ;;
+ -psos*)
+ os=-psos
+ ;;
+ -mint | -mint[0-9]*)
+ basic_machine=m68k-atari
+ os=-mint
+ ;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+ # Recognize the basic CPU types without company name.
+ # Some are omitted here because they have special meanings below.
+ 1750a | 580 \
+ | a29k \
+ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
+ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
+ | am33_2.0 \
+ | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \
+ | be32 | be64 \
+ | bfin \
+ | c4x | clipper \
+ | d10v | d30v | dlx | dsp16xx \
+ | epiphany \
+ | fido | fr30 | frv \
+ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+ | hexagon \
+ | i370 | i860 | i960 | ia64 \
+ | ip2k | iq2000 \
+ | le32 | le64 \
+ | lm32 \
+ | m32c | m32r | m32rle | m68000 | m68k | m88k \
+ | maxq | mb | microblaze | mcore | mep | metag \
+ | mips | mipsbe | mipseb | mipsel | mipsle \
+ | mips16 \
+ | mips64 | mips64el \
+ | mips64octeon | mips64octeonel \
+ | mips64orion | mips64orionel \
+ | mips64r5900 | mips64r5900el \
+ | mips64vr | mips64vrel \
+ | mips64vr4100 | mips64vr4100el \
+ | mips64vr4300 | mips64vr4300el \
+ | mips64vr5000 | mips64vr5000el \
+ | mips64vr5900 | mips64vr5900el \
+ | mipsisa32 | mipsisa32el \
+ | mipsisa32r2 | mipsisa32r2el \
+ | mipsisa64 | mipsisa64el \
+ | mipsisa64r2 | mipsisa64r2el \
+ | mipsisa64sb1 | mipsisa64sb1el \
+ | mipsisa64sr71k | mipsisa64sr71kel \
+ | mipstx39 | mipstx39el \
+ | mn10200 | mn10300 \
+ | moxie \
+ | mt \
+ | msp430 \
+ | nds32 | nds32le | nds32be \
+ | nios | nios2 \
+ | ns16k | ns32k \
+ | open8 \
+ | or32 \
+ | pdp10 | pdp11 | pj | pjl \
+ | powerpc | powerpc64 | powerpc64le | powerpcle \
+ | pyramid \
+ | rx \
+ | score \
+ | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
+ | sh64 | sh64le \
+ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
+ | sparcv8 | sparcv9 | sparcv9b | sparcv9v \
+ | spu \
+ | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
+ | ubicom32 \
+ | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
+ | we32k \
+ | x86 | xc16x | xstormy16 | xtensa \
+ | z8k | z80)
+ basic_machine=$basic_machine-unknown
+ ;;
+ c54x)
+ basic_machine=tic54x-unknown
+ ;;
+ c55x)
+ basic_machine=tic55x-unknown
+ ;;
+ c6x)
+ basic_machine=tic6x-unknown
+ ;;
+ m6811 | m68hc11 | m6812 | m68hc12 | picochip)
+ # Motorola 68HC11/12.
+ basic_machine=$basic_machine-unknown
+ os=-none
+ ;;
+ m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
+ ;;
+ ms1)
+ basic_machine=mt-unknown
+ ;;
+
+ strongarm | thumb | xscale)
+ basic_machine=arm-unknown
+ ;;
+
+ xscaleeb)
+ basic_machine=armeb-unknown
+ ;;
+
+ xscaleel)
+ basic_machine=armel-unknown
+ ;;
+
+ # We use `pc' rather than `unknown'
+ # because (1) that's what they normally are, and
+ # (2) the word "unknown" tends to confuse beginning users.
+ i*86 | x86_64)
+ basic_machine=$basic_machine-pc
+ ;;
+ # Object if more than one company name word.
+ *-*-*)
+ echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+ exit 1
+ ;;
+ # Recognize the basic CPU types with company name.
+ 580-* \
+ | a29k-* \
+ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
+ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
+ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
+ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \
+ | avr-* | avr32-* \
+ | be32-* | be64-* \
+ | bfin-* | bs2000-* \
+ | c[123]* | c30-* | [cjt]90-* | c4x-* \
+ | clipper-* | craynv-* | cydra-* \
+ | d10v-* | d30v-* | dlx-* \
+ | elxsi-* \
+ | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
+ | h8300-* | h8500-* \
+ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
+ | hexagon-* \
+ | i*86-* | i860-* | i960-* | ia64-* \
+ | ip2k-* | iq2000-* \
+ | le32-* | le64-* \
+ | lm32-* \
+ | m32c-* | m32r-* | m32rle-* \
+ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
+ | m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \
+ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
+ | mips16-* \
+ | mips64-* | mips64el-* \
+ | mips64octeon-* | mips64octeonel-* \
+ | mips64orion-* | mips64orionel-* \
+ | mips64r5900-* | mips64r5900el-* \
+ | mips64vr-* | mips64vrel-* \
+ | mips64vr4100-* | mips64vr4100el-* \
+ | mips64vr4300-* | mips64vr4300el-* \
+ | mips64vr5000-* | mips64vr5000el-* \
+ | mips64vr5900-* | mips64vr5900el-* \
+ | mipsisa32-* | mipsisa32el-* \
+ | mipsisa32r2-* | mipsisa32r2el-* \
+ | mipsisa64-* | mipsisa64el-* \
+ | mipsisa64r2-* | mipsisa64r2el-* \
+ | mipsisa64sb1-* | mipsisa64sb1el-* \
+ | mipsisa64sr71k-* | mipsisa64sr71kel-* \
+ | mipstx39-* | mipstx39el-* \
+ | mmix-* \
+ | mt-* \
+ | msp430-* \
+ | nds32-* | nds32le-* | nds32be-* \
+ | nios-* | nios2-* \
+ | none-* | np1-* | ns16k-* | ns32k-* \
+ | open8-* \
+ | orion-* \
+ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
+ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
+ | pyramid-* \
+ | romp-* | rs6000-* | rx-* \
+ | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
+ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
+ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
+ | sparclite-* \
+ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \
+ | tahoe-* \
+ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
+ | tile*-* \
+ | tron-* \
+ | ubicom32-* \
+ | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
+ | vax-* \
+ | we32k-* \
+ | x86-* | x86_64-* | xc16x-* | xps100-* \
+ | xstormy16-* | xtensa*-* \
+ | ymp-* \
+ | z8k-* | z80-*)
+ ;;
+ # Recognize the basic CPU types without company name, with glob match.
+ xtensa*)
+ basic_machine=$basic_machine-unknown
+ ;;
+ # Recognize the various machine names and aliases which stand
+ # for a CPU type and a company and sometimes even an OS.
+ 386bsd)
+ basic_machine=i386-unknown
+ os=-bsd
+ ;;
+ 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+ basic_machine=m68000-att
+ ;;
+ 3b*)
+ basic_machine=we32k-att
+ ;;
+ a29khif)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ abacus)
+ basic_machine=abacus-unknown
+ ;;
+ adobe68k)
+ basic_machine=m68010-adobe
+ os=-scout
+ ;;
+ alliant | fx80)
+ basic_machine=fx80-alliant
+ ;;
+ altos | altos3068)
+ basic_machine=m68k-altos
+ ;;
+ am29k)
+ basic_machine=a29k-none
+ os=-bsd
+ ;;
+ amd64)
+ basic_machine=x86_64-pc
+ ;;
+ amd64-*)
+ basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ amdahl)
+ basic_machine=580-amdahl
+ os=-sysv
+ ;;
+ amiga | amiga-*)
+ basic_machine=m68k-unknown
+ ;;
+ amigaos | amigados)
+ basic_machine=m68k-unknown
+ os=-amigaos
+ ;;
+ amigaunix | amix)
+ basic_machine=m68k-unknown
+ os=-sysv4
+ ;;
+ apollo68)
+ basic_machine=m68k-apollo
+ os=-sysv
+ ;;
+ apollo68bsd)
+ basic_machine=m68k-apollo
+ os=-bsd
+ ;;
+ aros)
+ basic_machine=i386-pc
+ os=-aros
+ ;;
+ aux)
+ basic_machine=m68k-apple
+ os=-aux
+ ;;
+ balance)
+ basic_machine=ns32k-sequent
+ os=-dynix
+ ;;
+ blackfin)
+ basic_machine=bfin-unknown
+ os=-linux
+ ;;
+ blackfin-*)
+ basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
+ bluegene*)
+ basic_machine=powerpc-ibm
+ os=-cnk
+ ;;
+ c54x-*)
+ basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ c55x-*)
+ basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ c6x-*)
+ basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ c90)
+ basic_machine=c90-cray
+ os=-unicos
+ ;;
+ cegcc)
+ basic_machine=arm-unknown
+ os=-cegcc
+ ;;
+ convex-c1)
+ basic_machine=c1-convex
+ os=-bsd
+ ;;
+ convex-c2)
+ basic_machine=c2-convex
+ os=-bsd
+ ;;
+ convex-c32)
+ basic_machine=c32-convex
+ os=-bsd
+ ;;
+ convex-c34)
+ basic_machine=c34-convex
+ os=-bsd
+ ;;
+ convex-c38)
+ basic_machine=c38-convex
+ os=-bsd
+ ;;
+ cray | j90)
+ basic_machine=j90-cray
+ os=-unicos
+ ;;
+ craynv)
+ basic_machine=craynv-cray
+ os=-unicosmp
+ ;;
+ cr16 | cr16-*)
+ basic_machine=cr16-unknown
+ os=-elf
+ ;;
+ crds | unos)
+ basic_machine=m68k-crds
+ ;;
+ crisv32 | crisv32-* | etraxfs*)
+ basic_machine=crisv32-axis
+ ;;
+ cris | cris-* | etrax*)
+ basic_machine=cris-axis
+ ;;
+ crx)
+ basic_machine=crx-unknown
+ os=-elf
+ ;;
+ da30 | da30-*)
+ basic_machine=m68k-da30
+ ;;
+ decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+ basic_machine=mips-dec
+ ;;
+ decsystem10* | dec10*)
+ basic_machine=pdp10-dec
+ os=-tops10
+ ;;
+ decsystem20* | dec20*)
+ basic_machine=pdp10-dec
+ os=-tops20
+ ;;
+ delta | 3300 | motorola-3300 | motorola-delta \
+ | 3300-motorola | delta-motorola)
+ basic_machine=m68k-motorola
+ ;;
+ delta88)
+ basic_machine=m88k-motorola
+ os=-sysv3
+ ;;
+ dicos)
+ basic_machine=i686-pc
+ os=-dicos
+ ;;
+ djgpp)
+ basic_machine=i586-pc
+ os=-msdosdjgpp
+ ;;
+ dpx20 | dpx20-*)
+ basic_machine=rs6000-bull
+ os=-bosx
+ ;;
+ dpx2* | dpx2*-bull)
+ basic_machine=m68k-bull
+ os=-sysv3
+ ;;
+ ebmon29k)
+ basic_machine=a29k-amd
+ os=-ebmon
+ ;;
+ elxsi)
+ basic_machine=elxsi-elxsi
+ os=-bsd
+ ;;
+ encore | umax | mmax)
+ basic_machine=ns32k-encore
+ ;;
+ es1800 | OSE68k | ose68k | ose | OSE)
+ basic_machine=m68k-ericsson
+ os=-ose
+ ;;
+ fx2800)
+ basic_machine=i860-alliant
+ ;;
+ genix)
+ basic_machine=ns32k-ns
+ ;;
+ gmicro)
+ basic_machine=tron-gmicro
+ os=-sysv
+ ;;
+ go32)
+ basic_machine=i386-pc
+ os=-go32
+ ;;
+ h3050r* | hiux*)
+ basic_machine=hppa1.1-hitachi
+ os=-hiuxwe2
+ ;;
+ h8300hms)
+ basic_machine=h8300-hitachi
+ os=-hms
+ ;;
+ h8300xray)
+ basic_machine=h8300-hitachi
+ os=-xray
+ ;;
+ h8500hms)
+ basic_machine=h8500-hitachi
+ os=-hms
+ ;;
+ harris)
+ basic_machine=m88k-harris
+ os=-sysv3
+ ;;
+ hp300-*)
+ basic_machine=m68k-hp
+ ;;
+ hp300bsd)
+ basic_machine=m68k-hp
+ os=-bsd
+ ;;
+ hp300hpux)
+ basic_machine=m68k-hp
+ os=-hpux
+ ;;
+ hp3k9[0-9][0-9] | hp9[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hp9k2[0-9][0-9] | hp9k31[0-9])
+ basic_machine=m68000-hp
+ ;;
+ hp9k3[2-9][0-9])
+ basic_machine=m68k-hp
+ ;;
+ hp9k6[0-9][0-9] | hp6[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hp9k7[0-79][0-9] | hp7[0-79][0-9])
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k78[0-9] | hp78[0-9])
+ # FIXME: really hppa2.0-hp
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
+ # FIXME: really hppa2.0-hp
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[0-9][13679] | hp8[0-9][13679])
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[0-9][0-9] | hp8[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hppa-next)
+ os=-nextstep3
+ ;;
+ hppaosf)
+ basic_machine=hppa1.1-hp
+ os=-osf
+ ;;
+ hppro)
+ basic_machine=hppa1.1-hp
+ os=-proelf
+ ;;
+ i370-ibm* | ibm*)
+ basic_machine=i370-ibm
+ ;;
+# I'm not sure what "Sysv32" means. Should this be sysv3.2?
+ i*86v32)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv32
+ ;;
+ i*86v4*)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv4
+ ;;
+ i*86v)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv
+ ;;
+ i*86sol2)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-solaris2
+ ;;
+ i386mach)
+ basic_machine=i386-mach
+ os=-mach
+ ;;
+ i386-vsta | vsta)
+ basic_machine=i386-unknown
+ os=-vsta
+ ;;
+ iris | iris4d)
+ basic_machine=mips-sgi
+ case $os in
+ -irix*)
+ ;;
+ *)
+ os=-irix4
+ ;;
+ esac
+ ;;
+ isi68 | isi)
+ basic_machine=m68k-isi
+ os=-sysv
+ ;;
+ m68knommu)
+ basic_machine=m68k-unknown
+ os=-linux
+ ;;
+ m68knommu-*)
+ basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
+ m88k-omron*)
+ basic_machine=m88k-omron
+ ;;
+ magnum | m3230)
+ basic_machine=mips-mips
+ os=-sysv
+ ;;
+ merlin)
+ basic_machine=ns32k-utek
+ os=-sysv
+ ;;
+ microblaze)
+ basic_machine=microblaze-xilinx
+ ;;
+ mingw32)
+ basic_machine=i386-pc
+ os=-mingw32
+ ;;
+ mingw32ce)
+ basic_machine=arm-unknown
+ os=-mingw32ce
+ ;;
+ miniframe)
+ basic_machine=m68000-convergent
+ ;;
+ *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
+ basic_machine=m68k-atari
+ os=-mint
+ ;;
+ mips3*-*)
+ basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+ ;;
+ mips3*)
+ basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+ ;;
+ monitor)
+ basic_machine=m68k-rom68k
+ os=-coff
+ ;;
+ morphos)
+ basic_machine=powerpc-unknown
+ os=-morphos
+ ;;
+ msdos)
+ basic_machine=i386-pc
+ os=-msdos
+ ;;
+ ms1-*)
+ basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
+ ;;
+ mvs)
+ basic_machine=i370-ibm
+ os=-mvs
+ ;;
+ nacl)
+ basic_machine=le32-unknown
+ os=-nacl
+ ;;
+ ncr3000)
+ basic_machine=i486-ncr
+ os=-sysv4
+ ;;
+ netbsd386)
+ basic_machine=i386-unknown
+ os=-netbsd
+ ;;
+ netwinder)
+ basic_machine=armv4l-rebel
+ os=-linux
+ ;;
+ news | news700 | news800 | news900)
+ basic_machine=m68k-sony
+ os=-newsos
+ ;;
+ news1000)
+ basic_machine=m68030-sony
+ os=-newsos
+ ;;
+ news-3600 | risc-news)
+ basic_machine=mips-sony
+ os=-newsos
+ ;;
+ necv70)
+ basic_machine=v70-nec
+ os=-sysv
+ ;;
+ next | m*-next )
+ basic_machine=m68k-next
+ case $os in
+ -nextstep* )
+ ;;
+ -ns2*)
+ os=-nextstep2
+ ;;
+ *)
+ os=-nextstep3
+ ;;
+ esac
+ ;;
+ nh3000)
+ basic_machine=m68k-harris
+ os=-cxux
+ ;;
+ nh[45]000)
+ basic_machine=m88k-harris
+ os=-cxux
+ ;;
+ nindy960)
+ basic_machine=i960-intel
+ os=-nindy
+ ;;
+ mon960)
+ basic_machine=i960-intel
+ os=-mon960
+ ;;
+ nonstopux)
+ basic_machine=mips-compaq
+ os=-nonstopux
+ ;;
+ np1)
+ basic_machine=np1-gould
+ ;;
+ neo-tandem)
+ basic_machine=neo-tandem
+ ;;
+ nse-tandem)
+ basic_machine=nse-tandem
+ ;;
+ nsr-tandem)
+ basic_machine=nsr-tandem
+ ;;
+ op50n-* | op60c-*)
+ basic_machine=hppa1.1-oki
+ os=-proelf
+ ;;
+ openrisc | openrisc-*)
+ basic_machine=or32-unknown
+ ;;
+ os400)
+ basic_machine=powerpc-ibm
+ os=-os400
+ ;;
+ OSE68000 | ose68000)
+ basic_machine=m68000-ericsson
+ os=-ose
+ ;;
+ os68k)
+ basic_machine=m68k-none
+ os=-os68k
+ ;;
+ pa-hitachi)
+ basic_machine=hppa1.1-hitachi
+ os=-hiuxwe2
+ ;;
+ paragon)
+ basic_machine=i860-intel
+ os=-osf
+ ;;
+ parisc)
+ basic_machine=hppa-unknown
+ os=-linux
+ ;;
+ parisc-*)
+ basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
+ pbd)
+ basic_machine=sparc-tti
+ ;;
+ pbb)
+ basic_machine=m68k-tti
+ ;;
+ pc532 | pc532-*)
+ basic_machine=ns32k-pc532
+ ;;
+ pc98)
+ basic_machine=i386-pc
+ ;;
+ pc98-*)
+ basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentium | p5 | k5 | k6 | nexgen | viac3)
+ basic_machine=i586-pc
+ ;;
+ pentiumpro | p6 | 6x86 | athlon | athlon_*)
+ basic_machine=i686-pc
+ ;;
+ pentiumii | pentium2 | pentiumiii | pentium3)
+ basic_machine=i686-pc
+ ;;
+ pentium4)
+ basic_machine=i786-pc
+ ;;
+ pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
+ basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentiumpro-* | p6-* | 6x86-* | athlon-*)
+ basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
+ basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentium4-*)
+ basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pn)
+ basic_machine=pn-gould
+ ;;
+ power) basic_machine=power-ibm
+ ;;
+ ppc | ppcbe) basic_machine=powerpc-unknown
+ ;;
+ ppc-* | ppcbe-*)
+ basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppcle | powerpclittle | ppc-le | powerpc-little)
+ basic_machine=powerpcle-unknown
+ ;;
+ ppcle-* | powerpclittle-*)
+ basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppc64) basic_machine=powerpc64-unknown
+ ;;
+ ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppc64le | powerpc64little | ppc64-le | powerpc64-little)
+ basic_machine=powerpc64le-unknown
+ ;;
+ ppc64le-* | powerpc64little-*)
+ basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ps2)
+ basic_machine=i386-ibm
+ ;;
+ pw32)
+ basic_machine=i586-unknown
+ os=-pw32
+ ;;
+ rdos)
+ basic_machine=i386-pc
+ os=-rdos
+ ;;
+ rom68k)
+ basic_machine=m68k-rom68k
+ os=-coff
+ ;;
+ rm[46]00)
+ basic_machine=mips-siemens
+ ;;
+ rtpc | rtpc-*)
+ basic_machine=romp-ibm
+ ;;
+ s390 | s390-*)
+ basic_machine=s390-ibm
+ ;;
+ s390x | s390x-*)
+ basic_machine=s390x-ibm
+ ;;
+ sa29200)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ sb1)
+ basic_machine=mipsisa64sb1-unknown
+ ;;
+ sb1el)
+ basic_machine=mipsisa64sb1el-unknown
+ ;;
+ sde)
+ basic_machine=mipsisa32-sde
+ os=-elf
+ ;;
+ sei)
+ basic_machine=mips-sei
+ os=-seiux
+ ;;
+ sequent)
+ basic_machine=i386-sequent
+ ;;
+ sh)
+ basic_machine=sh-hitachi
+ os=-hms
+ ;;
+ sh5el)
+ basic_machine=sh5le-unknown
+ ;;
+ sh64)
+ basic_machine=sh64-unknown
+ ;;
+ sparclite-wrs | simso-wrs)
+ basic_machine=sparclite-wrs
+ os=-vxworks
+ ;;
+ sps7)
+ basic_machine=m68k-bull
+ os=-sysv2
+ ;;
+ spur)
+ basic_machine=spur-unknown
+ ;;
+ st2000)
+ basic_machine=m68k-tandem
+ ;;
+ stratus)
+ basic_machine=i860-stratus
+ os=-sysv4
+ ;;
+ strongarm-* | thumb-*)
+ basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ sun2)
+ basic_machine=m68000-sun
+ ;;
+ sun2os3)
+ basic_machine=m68000-sun
+ os=-sunos3
+ ;;
+ sun2os4)
+ basic_machine=m68000-sun
+ os=-sunos4
+ ;;
+ sun3os3)
+ basic_machine=m68k-sun
+ os=-sunos3
+ ;;
+ sun3os4)
+ basic_machine=m68k-sun
+ os=-sunos4
+ ;;
+ sun4os3)
+ basic_machine=sparc-sun
+ os=-sunos3
+ ;;
+ sun4os4)
+ basic_machine=sparc-sun
+ os=-sunos4
+ ;;
+ sun4sol2)
+ basic_machine=sparc-sun
+ os=-solaris2
+ ;;
+ sun3 | sun3-*)
+ basic_machine=m68k-sun
+ ;;
+ sun4)
+ basic_machine=sparc-sun
+ ;;
+ sun386 | sun386i | roadrunner)
+ basic_machine=i386-sun
+ ;;
+ sv1)
+ basic_machine=sv1-cray
+ os=-unicos
+ ;;
+ symmetry)
+ basic_machine=i386-sequent
+ os=-dynix
+ ;;
+ t3e)
+ basic_machine=alphaev5-cray
+ os=-unicos
+ ;;
+ t90)
+ basic_machine=t90-cray
+ os=-unicos
+ ;;
+ tile*)
+ basic_machine=$basic_machine-unknown
+ os=-linux-gnu
+ ;;
+ tx39)
+ basic_machine=mipstx39-unknown
+ ;;
+ tx39el)
+ basic_machine=mipstx39el-unknown
+ ;;
+ toad1)
+ basic_machine=pdp10-xkl
+ os=-tops20
+ ;;
+ tower | tower-32)
+ basic_machine=m68k-ncr
+ ;;
+ tpf)
+ basic_machine=s390x-ibm
+ os=-tpf
+ ;;
+ udi29k)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ ultra3)
+ basic_machine=a29k-nyu
+ os=-sym1
+ ;;
+ v810 | necv810)
+ basic_machine=v810-nec
+ os=-none
+ ;;
+ vaxv)
+ basic_machine=vax-dec
+ os=-sysv
+ ;;
+ vms)
+ basic_machine=vax-dec
+ os=-vms
+ ;;
+ vpp*|vx|vx-*)
+ basic_machine=f301-fujitsu
+ ;;
+ vxworks960)
+ basic_machine=i960-wrs
+ os=-vxworks
+ ;;
+ vxworks68)
+ basic_machine=m68k-wrs
+ os=-vxworks
+ ;;
+ vxworks29k)
+ basic_machine=a29k-wrs
+ os=-vxworks
+ ;;
+ w65*)
+ basic_machine=w65-wdc
+ os=-none
+ ;;
+ w89k-*)
+ basic_machine=hppa1.1-winbond
+ os=-proelf
+ ;;
+ xbox)
+ basic_machine=i686-pc
+ os=-mingw32
+ ;;
+ xps | xps100)
+ basic_machine=xps100-honeywell
+ ;;
+ xscale-* | xscalee[bl]-*)
+ basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'`
+ ;;
+ ymp)
+ basic_machine=ymp-cray
+ os=-unicos
+ ;;
+ z8k-*-coff)
+ basic_machine=z8k-unknown
+ os=-sim
+ ;;
+ z80-*-coff)
+ basic_machine=z80-unknown
+ os=-sim
+ ;;
+ none)
+ basic_machine=none-none
+ os=-none
+ ;;
+
+# Here we handle the default manufacturer of certain CPU types. It is in
+# some cases the only manufacturer, in others, it is the most popular.
+ w89k)
+ basic_machine=hppa1.1-winbond
+ ;;
+ op50n)
+ basic_machine=hppa1.1-oki
+ ;;
+ op60c)
+ basic_machine=hppa1.1-oki
+ ;;
+ romp)
+ basic_machine=romp-ibm
+ ;;
+ mmix)
+ basic_machine=mmix-knuth
+ ;;
+ rs6000)
+ basic_machine=rs6000-ibm
+ ;;
+ vax)
+ basic_machine=vax-dec
+ ;;
+ pdp10)
+ # there are many clones, so DEC is not a safe bet
+ basic_machine=pdp10-unknown
+ ;;
+ pdp11)
+ basic_machine=pdp11-dec
+ ;;
+ we32k)
+ basic_machine=we32k-att
+ ;;
+ sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
+ basic_machine=sh-unknown
+ ;;
+ sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
+ basic_machine=sparc-sun
+ ;;
+ cydra)
+ basic_machine=cydra-cydrome
+ ;;
+ orion)
+ basic_machine=orion-highlevel
+ ;;
+ orion105)
+ basic_machine=clipper-highlevel
+ ;;
+ mac | mpw | mac-mpw)
+ basic_machine=m68k-apple
+ ;;
+ pmac | pmac-mpw)
+ basic_machine=powerpc-apple
+ ;;
+ *-unknown)
+ # Make sure to match an already-canonicalized machine name.
+ ;;
+ *)
+ echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+ exit 1
+ ;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+ *-digital*)
+ basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+ ;;
+ *-commodore*)
+ basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+ ;;
+ *)
+ ;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+ # First match some system type aliases
+ # that might get confused with valid system types.
+ # -solaris* is a basic system type, with this one exception.
+ -auroraux)
+ os=-auroraux
+ ;;
+ -solaris1 | -solaris1.*)
+ os=`echo $os | sed -e 's|solaris1|sunos4|'`
+ ;;
+ -solaris)
+ os=-solaris2
+ ;;
+ -svr4*)
+ os=-sysv4
+ ;;
+ -unixware*)
+ os=-sysv4.2uw
+ ;;
+ -gnu/linux*)
+ os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+ ;;
+ # First accept the basic system types.
+ # The portable systems comes first.
+ # Each alternative MUST END IN A *, to match a version number.
+ # -sysv* is not here because it comes later, after sysvr4.
+ -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+ | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
+ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
+ | -sym* | -kopensolaris* \
+ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+ | -aos* | -aros* \
+ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
+ | -openbsd* | -solidbsd* \
+ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
+ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+ | -chorusos* | -chorusrdb* | -cegcc* \
+ | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+ | -mingw32* | -linux-gnu* | -linux-android* \
+ | -linux-newlib* | -linux-uclibc* \
+ | -uxpv* | -beos* | -mpeix* | -udk* \
+ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
+ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
+ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
+ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
+ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
+ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
+ | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*)
+ # Remember, each alternative MUST END IN *, to match a version number.
+ ;;
+ -qnx*)
+ case $basic_machine in
+ x86-* | i*86-*)
+ ;;
+ *)
+ os=-nto$os
+ ;;
+ esac
+ ;;
+ -nto-qnx*)
+ ;;
+ -nto*)
+ os=`echo $os | sed -e 's|nto|nto-qnx|'`
+ ;;
+ -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
+ | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \
+ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+ ;;
+ -mac*)
+ os=`echo $os | sed -e 's|mac|macos|'`
+ ;;
+ -linux-dietlibc)
+ os=-linux-dietlibc
+ ;;
+ -linux*)
+ os=`echo $os | sed -e 's|linux|linux-gnu|'`
+ ;;
+ -sunos5*)
+ os=`echo $os | sed -e 's|sunos5|solaris2|'`
+ ;;
+ -sunos6*)
+ os=`echo $os | sed -e 's|sunos6|solaris3|'`
+ ;;
+ -opened*)
+ os=-openedition
+ ;;
+ -os400*)
+ os=-os400
+ ;;
+ -wince*)
+ os=-wince
+ ;;
+ -osfrose*)
+ os=-osfrose
+ ;;
+ -osf*)
+ os=-osf
+ ;;
+ -utek*)
+ os=-bsd
+ ;;
+ -dynix*)
+ os=-bsd
+ ;;
+ -acis*)
+ os=-aos
+ ;;
+ -atheos*)
+ os=-atheos
+ ;;
+ -syllable*)
+ os=-syllable
+ ;;
+ -386bsd)
+ os=-bsd
+ ;;
+ -ctix* | -uts*)
+ os=-sysv
+ ;;
+ -nova*)
+ os=-rtmk-nova
+ ;;
+ -ns2 )
+ os=-nextstep2
+ ;;
+ -nsk*)
+ os=-nsk
+ ;;
+ # Preserve the version number of sinix5.
+ -sinix5.*)
+ os=`echo $os | sed -e 's|sinix|sysv|'`
+ ;;
+ -sinix*)
+ os=-sysv4
+ ;;
+ -tpf*)
+ os=-tpf
+ ;;
+ -triton*)
+ os=-sysv3
+ ;;
+ -oss*)
+ os=-sysv3
+ ;;
+ -svr4)
+ os=-sysv4
+ ;;
+ -svr3)
+ os=-sysv3
+ ;;
+ -sysvr4)
+ os=-sysv4
+ ;;
+ # This must come after -sysvr4.
+ -sysv*)
+ ;;
+ -ose*)
+ os=-ose
+ ;;
+ -es1800*)
+ os=-ose
+ ;;
+ -xenix)
+ os=-xenix
+ ;;
+ -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+ os=-mint
+ ;;
+ -aros*)
+ os=-aros
+ ;;
+ -kaos*)
+ os=-kaos
+ ;;
+ -zvmoe)
+ os=-zvmoe
+ ;;
+ -dicos*)
+ os=-dicos
+ ;;
+ -nacl*)
+ ;;
+ -none)
+ ;;
+ *)
+ # Get rid of the `-' at the beginning of $os.
+ os=`echo $os | sed 's/[^-]*-//'`
+ echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+ exit 1
+ ;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system. Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+ score-*)
+ os=-elf
+ ;;
+ spu-*)
+ os=-elf
+ ;;
+ *-acorn)
+ os=-riscix1.2
+ ;;
+ arm*-rebel)
+ os=-linux
+ ;;
+ arm*-semi)
+ os=-aout
+ ;;
+ c4x-* | tic4x-*)
+ os=-coff
+ ;;
+ tic54x-*)
+ os=-coff
+ ;;
+ tic55x-*)
+ os=-coff
+ ;;
+ tic6x-*)
+ os=-coff
+ ;;
+ # This must come before the *-dec entry.
+ pdp10-*)
+ os=-tops20
+ ;;
+ pdp11-*)
+ os=-none
+ ;;
+ *-dec | vax-*)
+ os=-ultrix4.2
+ ;;
+ m68*-apollo)
+ os=-domain
+ ;;
+ i386-sun)
+ os=-sunos4.0.2
+ ;;
+ m68000-sun)
+ os=-sunos3
+ # This also exists in the configure program, but was not the
+ # default.
+ # os=-sunos4
+ ;;
+ m68*-cisco)
+ os=-aout
+ ;;
+ mep-*)
+ os=-elf
+ ;;
+ mips*-cisco)
+ os=-elf
+ ;;
+ mips*-*)
+ os=-elf
+ ;;
+ or32-*)
+ os=-coff
+ ;;
+ *-tti) # must be before sparc entry or we get the wrong os.
+ os=-sysv3
+ ;;
+ sparc-* | *-sun)
+ os=-sunos4.1.1
+ ;;
+ *-be)
+ os=-beos
+ ;;
+ *-haiku)
+ os=-haiku
+ ;;
+ *-ibm)
+ os=-aix
+ ;;
+ *-knuth)
+ os=-mmixware
+ ;;
+ *-wec)
+ os=-proelf
+ ;;
+ *-winbond)
+ os=-proelf
+ ;;
+ *-oki)
+ os=-proelf
+ ;;
+ *-hp)
+ os=-hpux
+ ;;
+ *-hitachi)
+ os=-hiux
+ ;;
+ i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+ os=-sysv
+ ;;
+ *-cbm)
+ os=-amigaos
+ ;;
+ *-dg)
+ os=-dgux
+ ;;
+ *-dolphin)
+ os=-sysv3
+ ;;
+ m68k-ccur)
+ os=-rtu
+ ;;
+ m88k-omron*)
+ os=-luna
+ ;;
+ *-next )
+ os=-nextstep
+ ;;
+ *-sequent)
+ os=-ptx
+ ;;
+ *-crds)
+ os=-unos
+ ;;
+ *-ns)
+ os=-genix
+ ;;
+ i370-*)
+ os=-mvs
+ ;;
+ *-next)
+ os=-nextstep3
+ ;;
+ *-gould)
+ os=-sysv
+ ;;
+ *-highlevel)
+ os=-bsd
+ ;;
+ *-encore)
+ os=-bsd
+ ;;
+ *-sgi)
+ os=-irix
+ ;;
+ *-siemens)
+ os=-sysv4
+ ;;
+ *-masscomp)
+ os=-rtu
+ ;;
+ f30[01]-fujitsu | f700-fujitsu)
+ os=-uxpv
+ ;;
+ *-rom68k)
+ os=-coff
+ ;;
+ *-*bug)
+ os=-coff
+ ;;
+ *-apple)
+ os=-macos
+ ;;
+ *-atari*)
+ os=-mint
+ ;;
+ *)
+ os=-none
+ ;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer. We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+ *-unknown)
+ case $os in
+ -riscix*)
+ vendor=acorn
+ ;;
+ -sunos*)
+ vendor=sun
+ ;;
+ -cnk*|-aix*)
+ vendor=ibm
+ ;;
+ -beos*)
+ vendor=be
+ ;;
+ -hpux*)
+ vendor=hp
+ ;;
+ -mpeix*)
+ vendor=hp
+ ;;
+ -hiux*)
+ vendor=hitachi
+ ;;
+ -unos*)
+ vendor=crds
+ ;;
+ -dgux*)
+ vendor=dg
+ ;;
+ -luna*)
+ vendor=omron
+ ;;
+ -genix*)
+ vendor=ns
+ ;;
+ -mvs* | -opened*)
+ vendor=ibm
+ ;;
+ -os400*)
+ vendor=ibm
+ ;;
+ -ptx*)
+ vendor=sequent
+ ;;
+ -tpf*)
+ vendor=ibm
+ ;;
+ -vxsim* | -vxworks* | -windiss*)
+ vendor=wrs
+ ;;
+ -aux*)
+ vendor=apple
+ ;;
+ -hms*)
+ vendor=hitachi
+ ;;
+ -mpw* | -macos*)
+ vendor=apple
+ ;;
+ -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+ vendor=atari
+ ;;
+ -vos*)
+ vendor=stratus
+ ;;
+ esac
+ basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+ ;;
+esac
+
+echo $basic_machine$os
+exit
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/scripts/install-sh b/scripts/install-sh
new file mode 100755
index 0000000..a9244eb
--- /dev/null
+++ b/scripts/install-sh
@@ -0,0 +1,527 @@
+#!/bin/sh
+# install - install a program, script, or datafile
+
+scriptversion=2011-01-19.21; # UTC
+
+# This originates from X11R5 (mit/util/scripts/install.sh), which was
+# later released in X11R6 (xc/config/util/install.sh) with the
+# following copyright and license.
+#
+# Copyright (C) 1994 X Consortium
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to
+# deal in the Software without restriction, including without limitation the
+# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+# sell copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
+# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+# Except as contained in this notice, the name of the X Consortium shall not
+# be used in advertising or otherwise to promote the sale, use or other deal-
+# ings in this Software without prior written authorization from the X Consor-
+# tium.
+#
+#
+# FSF changes to this file are in the public domain.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.
+
+nl='
+'
+IFS=" "" $nl"
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit=${DOITPROG-}
+if test -z "$doit"; then
+ doit_exec=exec
+else
+ doit_exec=$doit
+fi
+
+# Put in absolute file names if you don't have them in your path;
+# or use environment vars.
+
+chgrpprog=${CHGRPPROG-chgrp}
+chmodprog=${CHMODPROG-chmod}
+chownprog=${CHOWNPROG-chown}
+cmpprog=${CMPPROG-cmp}
+cpprog=${CPPROG-cp}
+mkdirprog=${MKDIRPROG-mkdir}
+mvprog=${MVPROG-mv}
+rmprog=${RMPROG-rm}
+stripprog=${STRIPPROG-strip}
+
+posix_glob='?'
+initialize_posix_glob='
+ test "$posix_glob" != "?" || {
+ if (set -f) 2>/dev/null; then
+ posix_glob=
+ else
+ posix_glob=:
+ fi
+ }
+'
+
+posix_mkdir=
+
+# Desired mode of installed file.
+mode=0755
+
+chgrpcmd=
+chmodcmd=$chmodprog
+chowncmd=
+mvcmd=$mvprog
+rmcmd="$rmprog -f"
+stripcmd=
+
+src=
+dst=
+dir_arg=
+dst_arg=
+
+copy_on_change=false
+no_target_directory=
+
+usage="\
+Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
+ or: $0 [OPTION]... SRCFILES... DIRECTORY
+ or: $0 [OPTION]... -t DIRECTORY SRCFILES...
+ or: $0 [OPTION]... -d DIRECTORIES...
+
+In the 1st form, copy SRCFILE to DSTFILE.
+In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
+In the 4th, create DIRECTORIES.
+
+Options:
+ --help display this help and exit.
+ --version display version info and exit.
+
+ -c (ignored)
+ -C install only if different (preserve the last data modification time)
+ -d create directories instead of installing files.
+ -g GROUP $chgrpprog installed files to GROUP.
+ -m MODE $chmodprog installed files to MODE.
+ -o USER $chownprog installed files to USER.
+ -s $stripprog installed files.
+ -t DIRECTORY install into DIRECTORY.
+ -T report an error if DSTFILE is a directory.
+
+Environment variables override the default commands:
+ CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
+ RMPROG STRIPPROG
+"
+
+while test $# -ne 0; do
+ case $1 in
+ -c) ;;
+
+ -C) copy_on_change=true;;
+
+ -d) dir_arg=true;;
+
+ -g) chgrpcmd="$chgrpprog $2"
+ shift;;
+
+ --help) echo "$usage"; exit $?;;
+
+ -m) mode=$2
+ case $mode in
+ *' '* | *' '* | *'
+'* | *'*'* | *'?'* | *'['*)
+ echo "$0: invalid mode: $mode" >&2
+ exit 1;;
+ esac
+ shift;;
+
+ -o) chowncmd="$chownprog $2"
+ shift;;
+
+ -s) stripcmd=$stripprog;;
+
+ -t) dst_arg=$2
+ # Protect names problematic for `test' and other utilities.
+ case $dst_arg in
+ -* | [=\(\)!]) dst_arg=./$dst_arg;;
+ esac
+ shift;;
+
+ -T) no_target_directory=true;;
+
+ --version) echo "$0 $scriptversion"; exit $?;;
+
+ --) shift
+ break;;
+
+ -*) echo "$0: invalid option: $1" >&2
+ exit 1;;
+
+ *) break;;
+ esac
+ shift
+done
+
+if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
+ # When -d is used, all remaining arguments are directories to create.
+ # When -t is used, the destination is already specified.
+ # Otherwise, the last argument is the destination. Remove it from $@.
+ for arg
+ do
+ if test -n "$dst_arg"; then
+ # $@ is not empty: it contains at least $arg.
+ set fnord "$@" "$dst_arg"
+ shift # fnord
+ fi
+ shift # arg
+ dst_arg=$arg
+ # Protect names problematic for `test' and other utilities.
+ case $dst_arg in
+ -* | [=\(\)!]) dst_arg=./$dst_arg;;
+ esac
+ done
+fi
+
+if test $# -eq 0; then
+ if test -z "$dir_arg"; then
+ echo "$0: no input file specified." >&2
+ exit 1
+ fi
+ # It's OK to call `install-sh -d' without argument.
+ # This can happen when creating conditional directories.
+ exit 0
+fi
+
+if test -z "$dir_arg"; then
+ do_exit='(exit $ret); exit $ret'
+ trap "ret=129; $do_exit" 1
+ trap "ret=130; $do_exit" 2
+ trap "ret=141; $do_exit" 13
+ trap "ret=143; $do_exit" 15
+
+ # Set umask so as not to create temps with too-generous modes.
+ # However, 'strip' requires both read and write access to temps.
+ case $mode in
+ # Optimize common cases.
+ *644) cp_umask=133;;
+ *755) cp_umask=22;;
+
+ *[0-7])
+ if test -z "$stripcmd"; then
+ u_plus_rw=
+ else
+ u_plus_rw='% 200'
+ fi
+ cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
+ *)
+ if test -z "$stripcmd"; then
+ u_plus_rw=
+ else
+ u_plus_rw=,u+rw
+ fi
+ cp_umask=$mode$u_plus_rw;;
+ esac
+fi
+
+for src
+do
+ # Protect names problematic for `test' and other utilities.
+ case $src in
+ -* | [=\(\)!]) src=./$src;;
+ esac
+
+ if test -n "$dir_arg"; then
+ dst=$src
+ dstdir=$dst
+ test -d "$dstdir"
+ dstdir_status=$?
+ else
+
+ # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
+ # might cause directories to be created, which would be especially bad
+ # if $src (and thus $dsttmp) contains '*'.
+ if test ! -f "$src" && test ! -d "$src"; then
+ echo "$0: $src does not exist." >&2
+ exit 1
+ fi
+
+ if test -z "$dst_arg"; then
+ echo "$0: no destination specified." >&2
+ exit 1
+ fi
+ dst=$dst_arg
+
+ # If destination is a directory, append the input filename; won't work
+ # if double slashes aren't ignored.
+ if test -d "$dst"; then
+ if test -n "$no_target_directory"; then
+ echo "$0: $dst_arg: Is a directory" >&2
+ exit 1
+ fi
+ dstdir=$dst
+ dst=$dstdir/`basename "$src"`
+ dstdir_status=0
+ else
+ # Prefer dirname, but fall back on a substitute if dirname fails.
+ dstdir=`
+ (dirname "$dst") 2>/dev/null ||
+ expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$dst" : 'X\(//\)[^/]' \| \
+ X"$dst" : 'X\(//\)$' \| \
+ X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
+ echo X"$dst" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'
+ `
+
+ test -d "$dstdir"
+ dstdir_status=$?
+ fi
+ fi
+
+ obsolete_mkdir_used=false
+
+ if test $dstdir_status != 0; then
+ case $posix_mkdir in
+ '')
+ # Create intermediate dirs using mode 755 as modified by the umask.
+ # This is like FreeBSD 'install' as of 1997-10-28.
+ umask=`umask`
+ case $stripcmd.$umask in
+ # Optimize common cases.
+ *[2367][2367]) mkdir_umask=$umask;;
+ .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
+
+ *[0-7])
+ mkdir_umask=`expr $umask + 22 \
+ - $umask % 100 % 40 + $umask % 20 \
+ - $umask % 10 % 4 + $umask % 2
+ `;;
+ *) mkdir_umask=$umask,go-w;;
+ esac
+
+ # With -d, create the new directory with the user-specified mode.
+ # Otherwise, rely on $mkdir_umask.
+ if test -n "$dir_arg"; then
+ mkdir_mode=-m$mode
+ else
+ mkdir_mode=
+ fi
+
+ posix_mkdir=false
+ case $umask in
+ *[123567][0-7][0-7])
+ # POSIX mkdir -p sets u+wx bits regardless of umask, which
+ # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
+ ;;
+ *)
+ tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
+ trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
+
+ if (umask $mkdir_umask &&
+ exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
+ then
+ if test -z "$dir_arg" || {
+ # Check for POSIX incompatibilities with -m.
+ # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
+ # other-writeable bit of parent directory when it shouldn't.
+ # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
+ ls_ld_tmpdir=`ls -ld "$tmpdir"`
+ case $ls_ld_tmpdir in
+ d????-?r-*) different_mode=700;;
+ d????-?--*) different_mode=755;;
+ *) false;;
+ esac &&
+ $mkdirprog -m$different_mode -p -- "$tmpdir" && {
+ ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
+ test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
+ }
+ }
+ then posix_mkdir=:
+ fi
+ rmdir "$tmpdir/d" "$tmpdir"
+ else
+ # Remove any dirs left behind by ancient mkdir implementations.
+ rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
+ fi
+ trap '' 0;;
+ esac;;
+ esac
+
+ if
+ $posix_mkdir && (
+ umask $mkdir_umask &&
+ $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
+ )
+ then :
+ else
+
+ # The umask is ridiculous, or mkdir does not conform to POSIX,
+ # or it failed possibly due to a race condition. Create the
+ # directory the slow way, step by step, checking for races as we go.
+
+ case $dstdir in
+ /*) prefix='/';;
+ [-=\(\)!]*) prefix='./';;
+ *) prefix='';;
+ esac
+
+ eval "$initialize_posix_glob"
+
+ oIFS=$IFS
+ IFS=/
+ $posix_glob set -f
+ set fnord $dstdir
+ shift
+ $posix_glob set +f
+ IFS=$oIFS
+
+ prefixes=
+
+ for d
+ do
+ test X"$d" = X && continue
+
+ prefix=$prefix$d
+ if test -d "$prefix"; then
+ prefixes=
+ else
+ if $posix_mkdir; then
+ (umask=$mkdir_umask &&
+ $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
+ # Don't fail if two instances are running concurrently.
+ test -d "$prefix" || exit 1
+ else
+ case $prefix in
+ *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
+ *) qprefix=$prefix;;
+ esac
+ prefixes="$prefixes '$qprefix'"
+ fi
+ fi
+ prefix=$prefix/
+ done
+
+ if test -n "$prefixes"; then
+ # Don't fail if two instances are running concurrently.
+ (umask $mkdir_umask &&
+ eval "\$doit_exec \$mkdirprog $prefixes") ||
+ test -d "$dstdir" || exit 1
+ obsolete_mkdir_used=true
+ fi
+ fi
+ fi
+
+ if test -n "$dir_arg"; then
+ { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
+ { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
+ { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
+ test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
+ else
+
+ # Make a couple of temp file names in the proper directory.
+ dsttmp=$dstdir/_inst.$$_
+ rmtmp=$dstdir/_rm.$$_
+
+ # Trap to clean up those temp files at exit.
+ trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
+
+ # Copy the file name to the temp name.
+ (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
+
+ # and set any options; do chmod last to preserve setuid bits.
+ #
+ # If any of these fail, we abort the whole thing. If we want to
+ # ignore errors from any of these, just make sure not to ignore
+ # errors from the above "$doit $cpprog $src $dsttmp" command.
+ #
+ { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
+ { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
+ { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
+ { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
+
+ # If -C, don't bother to copy if it wouldn't change the file.
+ if $copy_on_change &&
+ old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` &&
+ new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` &&
+
+ eval "$initialize_posix_glob" &&
+ $posix_glob set -f &&
+ set X $old && old=:$2:$4:$5:$6 &&
+ set X $new && new=:$2:$4:$5:$6 &&
+ $posix_glob set +f &&
+
+ test "$old" = "$new" &&
+ $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
+ then
+ rm -f "$dsttmp"
+ else
+ # Rename the file to the real destination.
+ $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
+
+ # The rename failed, perhaps because mv can't rename something else
+ # to itself, or perhaps because mv is so ancient that it does not
+ # support -f.
+ {
+ # Now remove or move aside any old file at destination location.
+ # We try this two ways since rm can't unlink itself on some
+ # systems and the destination file might be busy for other
+ # reasons. In this case, the final cleanup might fail but the new
+ # file should still install successfully.
+ {
+ test ! -f "$dst" ||
+ $doit $rmcmd -f "$dst" 2>/dev/null ||
+ { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
+ { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
+ } ||
+ { echo "$0: cannot unlink or rename $dst" >&2
+ (exit 1); exit 1
+ }
+ } &&
+
+ # Now rename the file to the real destination.
+ $doit $mvcmd "$dsttmp" "$dst"
+ }
+ fi || exit 1
+
+ trap '' 0
+ fi
+done
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/src/Makefile.in b/src/Makefile.in
new file mode 100644
index 0000000..ed50fc2
--- /dev/null
+++ b/src/Makefile.in
@@ -0,0 +1,49 @@
+#
+# Copyright (C) 2003, Northwestern University and Argonne National Laboratory
+# See COPYRIGHT notice in top-level directory.
+#
+# $Id: Makefile.in 2285 2015-12-30 20:48:25Z wkliao $
+#
+# @configure_input@
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+include ../macros.make
+
+OPT_DIRS =
+ifeq (@has_mpicxx@, yes)
+ OPT_DIRS += libcxx
+endif
+ifeq (@has_fortran@, yes)
+ OPT_DIRS += libf
+ OPT_DIRS += libf90
+endif
+SUBDIRS = lib utils $(OPT_DIRS)
+
+PACKING_LIST = Makefile.in
+
+PACKING_SUBDIRS = lib libcxx libf libf90 utils
+
+all: $(SUBDIRS) library
+$(SUBDIRS):
+ $(MAKE) $(MFLAGS) -C $@
+
+library: $(SUBDIRS)
+ @set -e; for i in $(OPT_DIRS); do ( $(MAKE) $(MFLAGS) -C $$i library; ) ; done
+
+# utils must be built after lib
+utils: lib
+
+INSTALLDIRS = $(SUBDIRS:%=install-%)
+install: $(INSTALLDIRS)
+$(INSTALLDIRS): all
+ $(MAKE) $(MFLAGS) -C $(@:install-%=%) install
+
+UNINSTALLDIRS = $(SUBDIRS:%=uninstall-%)
+uninstall: $(UNINSTALLDIRS)
+$(UNINSTALLDIRS):
+ $(MAKE) $(MFLAGS) -C $(@:uninstall-%=%) uninstall
+
+include $(srcdir)/../rules.make
+
diff --git a/src/lib/Makefile.in b/src/lib/Makefile.in
new file mode 100644
index 0000000..b4fd504
--- /dev/null
+++ b/src/lib/Makefile.in
@@ -0,0 +1,117 @@
+#
+# Copyright (C) 2012, Northwestern University and Argonne National Laboratory
+# See COPYRIGHT notice in top-level directory.
+#
+# $Id: Makefile.in 2285 2015-12-30 20:48:25Z wkliao $
+#
+# @configure_input@
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+# generated by configure, so it's in the build dir, not srcdirr
+include ../../macros.make
+
+# For VPATH build:
+# Add . into search path because ./pnetcdf.h and ./ncconfig.h are created at
+# the configure time in this folder and they are included by many C source
+# files in this folder.
+# Add $(srcdir) into search path because those C files created from their m4
+# source files at the configure time include some header files in $(srcdir).
+INCLUDES = -I. -I$(srcdir)
+
+LIBRARY = libpnetcdf.a
+HEADER = pnetcdf.h
+
+M4_SRCS = getput.m4 \
+ i_getput.m4 \
+ bput.m4 \
+ ncx.m4 \
+ m_getput_varx.m4 \
+ varn.m4 \
+ i_varn.m4 \
+ attr.m4 \
+ convert_swap.m4
+
+HEADER_SRCS = fbits.h \
+ nc.h \
+ nctypes.h \
+ ncio.h \
+ ncx.h \
+ rnd.h \
+ ncmpidtype.h \
+ macro.h \
+ utf8proc_data.h \
+ utf8proc.h
+
+LIB_CSRCS = mpinetcdf.c \
+ header.c \
+ mpincio.c \
+ dim.c \
+ error.c \
+ nc.c \
+ string.c \
+ var.c \
+ ncmpidtype.c \
+ filetype.c \
+ nonblocking.c \
+ malloc.c \
+ utf8proc.c \
+ vard.c \
+ fill.c \
+ util.c
+
+ifeq (@enable_subfiling@, yes)
+LIB_CSRCS += subfile.c
+HEADER_SRCS += subfile.h
+endif
+
+PACKING_LIST = $(LIB_CSRCS) \
+ $(M4_SRCS) \
+ $(HEADER_SRCS) \
+ pnetcdf.h.in \
+ depend \
+ Makefile.in \
+ ncconfig.h.in
+
+ifeq (@enable_subfiling@, no)
+PACKING_LIST += subfile.c subfile.h
+endif
+
+LIB_OBJS = $(LIB_CSRCS:.c=.o) $(M4_SRCS:.m4=.o)
+
+GARBAGE = $(LIBRARY) $(M4_SRCS:.m4=.c)
+
+DIST_GARBAGE = ncconfig.h pnetcdf.h
+
+all: $(LIBRARY)
+
+$(LIBRARY): $(LIB_OBJS)
+ $(AR) $(ARFLAGS) $(LIBRARY) $(LIB_OBJS)
+ $(RANLIB) $(LIBRARY)
+
+install: $(LIBRARY)
+ $(INSTALL) -d -m 755 $(LIBDIR)
+ $(INSTALL_DATA) $(LIBRARY) $(LIBDIR)/$(LIBRARY)
+ $(INSTALL) -d -m 755 $(INCDIR)
+ $(INSTALL_DATA) $(HEADER) $(INCDIR)/$(HEADER)
+
+uninstall:
+ $(RM) -f $(LIBDIR)/$(LIBRARY)
+ $(RM) -f $(INCDIR)/$(HEADER)
+
+include $(srcdir)/../../rules.make
+
+.SUFFIXES: .ln
+LINT = lint
+LINT.c = $(LINT) $(LINTFLAGS) $(CPPFLAGS)
+.c.ln:
+ $(LINT.c) -c $<
+
+llib-lpnetcdf.ln: $(LIB_CSRCS)
+ $(LINT.c) $(LIB_CSRCS) -y -o pnetcdf
+
+lint: llib-lpnetcdf.ln
+ $(LINT.c) t_nc.c llib-lpnetcdf.ln
+
+include $(srcdir)/depend
diff --git a/src/lib/attr.m4 b/src/lib/attr.m4
new file mode 100644
index 0000000..124c64b
--- /dev/null
+++ b/src/lib/attr.m4
@@ -0,0 +1,1282 @@
+dnl Process this m4 file to produce 'C' language file.
+dnl
+dnl If you see this line, you can ignore the next one.
+/* Do not edit this file. It is produced from the corresponding .m4 source */
+dnl
+/*
+ * Copyright (C) 2003, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ */
+/* $Id$ */
+
+#if HAVE_CONFIG_H
+# include "ncconfig.h"
+#endif
+
+#include <stdio.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#include <string.h>
+#include <assert.h>
+
+#include <mpi.h>
+
+#include "nc.h"
+#include "ncx.h"
+#include "fbits.h"
+#include "rnd.h"
+#include "macro.h"
+#include "utf8proc.h"
+
+/*----< ncmpii_free_NC_attr() >-----------------------------------------------*/
+/*
+ * Free attr
+ * Formerly
+NC_free_attr()
+ */
+inline void
+ncmpii_free_NC_attr(NC_attr *attrp)
+{
+ if (attrp == NULL) return;
+
+ ncmpii_free_NC_string(attrp->name);
+
+ NCI_Free(attrp);
+}
+
+
+/*----< ncmpix_len_NC_attrV() >----------------------------------------------*/
+/*
+ * How much space will 'nelems' of 'type' take in
+ * external representation (as the values of an attribute)?
+ */
+inline static MPI_Offset
+ncmpix_len_NC_attrV(nc_type type,
+ MPI_Offset nelems)
+{
+ switch(type) {
+ case NC_BYTE:
+ case NC_CHAR:
+ case NC_UBYTE: return ncmpix_len_char(nelems);
+ case NC_SHORT: return ncmpix_len_short(nelems);
+ case NC_USHORT: return ncmpix_len_ushort(nelems);
+ case NC_INT: return ncmpix_len_int(nelems);
+ case NC_UINT: return ncmpix_len_uint(nelems);
+ case NC_FLOAT: return ncmpix_len_float(nelems);
+ case NC_DOUBLE: return ncmpix_len_double(nelems);
+ case NC_INT64: return ncmpix_len_int64(nelems);
+ case NC_UINT64: return ncmpix_len_uint64(nelems);
+ default: assert("ncmpix_len_NC_attr bad type" == 0);
+ }
+ return 0;
+}
+
+
+NC_attr *
+ncmpii_new_x_NC_attr(NC_string *strp,
+ nc_type type,
+ MPI_Offset nelems)
+{
+ NC_attr *attrp;
+ const MPI_Offset xsz = ncmpix_len_NC_attrV(type, nelems);
+ size_t sz = M_RNDUP(sizeof(NC_attr));
+
+ assert(!(xsz == 0 && nelems != 0));
+
+ sz += (size_t)xsz;
+
+ attrp = (NC_attr *) NCI_Malloc(sz);
+ if (attrp == NULL ) return NULL;
+
+ attrp->xsz = xsz;
+ attrp->name = strp;
+ attrp->type = type;
+ attrp->nelems = nelems;
+
+ if (xsz != 0)
+ attrp->xvalue = (char *)attrp + M_RNDUP(sizeof(NC_attr));
+ else
+ attrp->xvalue = NULL;
+
+ return(attrp);
+}
+
+
+/*----< ncmpii_new_NC_attr() >------------------------------------------------*/
+/*
+ * Formerly
+NC_new_attr(name,type,count,value)
+ */
+static NC_attr *
+ncmpii_new_NC_attr(const char *uname, /* attribute name (NULL terminated) */
+ nc_type type,
+ MPI_Offset nelems)
+{
+ NC_string *strp;
+ NC_attr *attrp;
+
+ char *name = (char *)utf8proc_NFC((const unsigned char *)uname);
+ if (name == NULL) return NULL;
+
+ assert(name != NULL && *name != 0);
+
+ strp = ncmpii_new_NC_string(strlen(name), name);
+ free(name);
+ if (strp == NULL) return NULL;
+
+ attrp = ncmpii_new_x_NC_attr(strp, type, nelems);
+ if (attrp == NULL) {
+ ncmpii_free_NC_string(strp);
+ return NULL;
+ }
+
+ return(attrp);
+}
+
+
+/*----< dup_NC_attr() >-------------------------------------------------------*/
+NC_attr *
+dup_NC_attr(const NC_attr *rattrp)
+{
+ NC_attr *attrp = ncmpii_new_NC_attr(rattrp->name->cp,
+ rattrp->type,
+ rattrp->nelems);
+ if (attrp == NULL) return NULL;
+ memcpy(attrp->xvalue, rattrp->xvalue, (size_t)rattrp->xsz);
+ return attrp;
+}
+
+/* attrarray */
+
+/*----< ncmpii_free_NC_attrarray() >------------------------------------------*/
+/*
+ * Free NC_attrarray values.
+ * formerly
+NC_free_array()
+ */
+void
+ncmpii_free_NC_attrarray(NC_attrarray *ncap)
+{
+ int i;
+
+ assert(ncap != NULL);
+
+ if (ncap->nalloc == 0) return;
+
+ assert(ncap->value != NULL);
+
+ for (i=0; i<ncap->ndefined; i++)
+ ncmpii_free_NC_attr(ncap->value[i]);
+
+ NCI_Free(ncap->value);
+ ncap->value = NULL;
+ ncap->nalloc = 0;
+ ncap->ndefined = 0;
+}
+
+/*----< ncmpii_dup_NC_attrarray() >-------------------------------------------*/
+int
+ncmpii_dup_NC_attrarray(NC_attrarray *ncap, const NC_attrarray *ref)
+{
+ int i, status=NC_NOERR;
+
+ assert(ref != NULL);
+ assert(ncap != NULL);
+
+ if (ref->nalloc == 0) {
+ ncap->nalloc = 0;
+ ncap->ndefined = 0;
+ ncap->value = NULL;
+ return NC_NOERR;
+ }
+
+ if (ref->nalloc > 0) {
+ ncap->value = (NC_attr **) NCI_Calloc((size_t)ref->nalloc, sizeof(NC_attr*));
+ if (ncap->value == NULL) DEBUG_RETURN_ERROR(NC_ENOMEM)
+ ncap->nalloc = ref->nalloc;
+ }
+
+ ncap->ndefined = 0;
+ for (i=0; i<ref->ndefined; i++) {
+ ncap->value[i] = dup_NC_attr(ref->value[i]);
+ if (ncap->value[i] == NULL) {
+ DEBUG_ASSIGN_ERROR(status, NC_ENOMEM)
+ break;
+ }
+ }
+
+ if (status != NC_NOERR) {
+ ncmpii_free_NC_attrarray(ncap);
+ return status;
+ }
+
+ ncap->ndefined = ref->ndefined;
+
+ return NC_NOERR;
+}
+
+
+/*
+ * Add a new handle on the end of an array of handles
+ * Formerly
+NC_incr_array(array, tail)
+ */
+int
+incr_NC_attrarray(NC_attrarray *ncap, NC_attr *newelemp)
+{
+ NC_attr **vp;
+
+ assert(ncap != NULL);
+
+ if(ncap->nalloc == 0)
+ {
+ assert(ncap->ndefined == 0);
+ vp = (NC_attr **) NCI_Malloc(sizeof(NC_attr*) * NC_ARRAY_GROWBY);
+ if(vp == NULL) DEBUG_RETURN_ERROR(NC_ENOMEM)
+
+ ncap->value = vp;
+ ncap->nalloc = NC_ARRAY_GROWBY;
+ }
+ else if(ncap->ndefined +1 > ncap->nalloc)
+ {
+ vp = (NC_attr **) NCI_Realloc(ncap->value,
+ (size_t)(ncap->nalloc + NC_ARRAY_GROWBY) * sizeof(NC_attr*));
+ if(vp == NULL) DEBUG_RETURN_ERROR(NC_ENOMEM)
+
+ ncap->value = vp;
+ ncap->nalloc += NC_ARRAY_GROWBY;
+ }
+
+ if(newelemp != NULL)
+ {
+ ncap->value[ncap->ndefined] = newelemp;
+ ncap->ndefined++;
+ }
+ return NC_NOERR;
+}
+
+
+static NC_attr *
+elem_NC_attrarray(const NC_attrarray *ncap, MPI_Offset elem)
+{
+ assert(ncap != NULL);
+ if((elem < 0) || ncap->ndefined == 0 || elem >= ncap->ndefined)
+ return NULL;
+
+ assert(ncap->value != NULL);
+
+ return ncap->value[elem];
+}
+
+/* End attrarray per se */
+
+/*----< NC_attrarray0() >----------------------------------------------------*/
+/*
+ * Given ncp and varid, return ptr to array of attributes
+ * else NULL on error. This is equivalent to validate varid.
+ */
+static NC_attrarray *
+NC_attrarray0(NC *ncp,
+ int varid)
+{
+ if (varid == NC_GLOBAL) /* Global attribute, attach to cdf */
+ return &ncp->attrs;
+
+ if (varid >= 0 && varid < ncp->vars.ndefined)
+ return &ncp->vars.value[varid]->attrs;
+
+ return NULL;
+}
+
+
+/*----< ncmpii_NC_findattr() >------------------------------------------------*/
+/*
+ * Step thru NC_ATTRIBUTE array, seeking match on name.
+ * return match or -1 if Not Found.
+ */
+int
+ncmpii_NC_findattr(const NC_attrarray *ncap,
+ const char *uname)
+{
+ int i;
+ size_t nchars;
+ char *name;
+
+ assert(ncap != NULL);
+
+ if (ncap->ndefined == 0) return -1; /* none created yet */
+
+ name = (char *)utf8proc_NFC((const unsigned char *)uname);
+ nchars = strlen(name);
+
+ for (i=0; i<ncap->ndefined; i++) {
+ if (ncap->value[i]->name->nchars == nchars &&
+ strncmp(ncap->value[i]->name->cp, name, nchars) == 0) {
+ free(name);
+ return i;
+ }
+ }
+ free(name);
+
+ return -1;
+}
+
+
+/*
+ * Look up by ncid, varid and name, return NULL if not found
+ */
+static int
+NC_lookupattr(int ncid,
+ int varid,
+ const char *name, /* attribute name */
+ NC_attr **attrpp) /* modified on return */
+{
+ int indx, status;
+ NC *ncp;
+ NC_attrarray *ncap;
+
+ status = ncmpii_NC_check_id(ncid, &ncp);
+ if(status != NC_NOERR)
+ return status;
+
+ ncap = NC_attrarray0(ncp, varid);
+ if(ncap == NULL) DEBUG_RETURN_ERROR(NC_ENOTVAR)
+
+ indx = ncmpii_NC_findattr(ncap, name);
+ if(indx == -1) DEBUG_RETURN_ERROR(NC_ENOTATT)
+
+ if(attrpp != NULL)
+ *attrpp = ncap->value[indx];
+
+ return NC_NOERR;
+}
+
+/* Public */
+
+/*----< ncmpi_inq_attname() >------------------------------------------------*/
+int
+ncmpi_inq_attname(int ncid,
+ int varid,
+ int attid,
+ char *name)
+
+{
+ int status;
+ NC *ncp;
+ NC_attrarray *ncap;
+ NC_attr *attrp;
+
+ status = ncmpii_NC_check_id(ncid, &ncp);
+ if (status != NC_NOERR) return status;
+
+ ncap = NC_attrarray0(ncp, varid);
+ if (ncap == NULL) DEBUG_RETURN_ERROR(NC_ENOTVAR)
+
+ attrp = elem_NC_attrarray(ncap, attid);
+ if (attrp == NULL) DEBUG_RETURN_ERROR(NC_ENOTATT)
+
+ /* in PnetCDF, name->cp is always NULL character terminated */
+ assert(name != NULL);
+ strcpy(name, attrp->name->cp);
+
+ return NC_NOERR;
+}
+
+
+/*----< ncmpi_inq_attid() >--------------------------------------------------*/
+int
+ncmpi_inq_attid(int ncid,
+ int varid,
+ const char *name,
+ int *attidp)
+{
+ int indx, status;
+ NC *ncp;
+ NC_attrarray *ncap;
+
+ status = ncmpii_NC_check_id(ncid, &ncp);
+ if (status != NC_NOERR) return status;
+
+ ncap = NC_attrarray0(ncp, varid);
+ if (ncap == NULL) DEBUG_RETURN_ERROR(NC_ENOTVAR)
+
+ indx = ncmpii_NC_findattr(ncap, name);
+ if (indx == -1) DEBUG_RETURN_ERROR(NC_ENOTATT)
+
+ if (attidp != NULL)
+ *attidp = indx;
+
+ return NC_NOERR;
+}
+
+/*----< ncmpi_inq_att() >----------------------------------------------------*/
+int
+ncmpi_inq_att(int ncid,
+ int varid,
+ const char *name, /* input, attribute name */
+ nc_type *datatypep,
+ MPI_Offset *lenp)
+{
+ int status;
+ NC_attr *attrp;
+
+ status = NC_lookupattr(ncid, varid, name, &attrp);
+ if (status != NC_NOERR) return status;
+
+ if (datatypep != NULL)
+ *datatypep = attrp->type;
+
+ if (lenp != NULL)
+ *lenp = attrp->nelems;
+
+ return NC_NOERR;
+}
+
+/*----< ncmpi_inq_atttype() >------------------------------------------------*/
+int
+ncmpi_inq_atttype(int ncid,
+ int varid,
+ const char *name,
+ nc_type *datatypep)
+{
+ return ncmpi_inq_att(ncid, varid, name, datatypep, NULL);
+}
+
+/*----< ncmpi_inq_attlen() >-------------------------------------------------*/
+int
+ncmpi_inq_attlen(int ncid,
+ int varid,
+ const char *name,
+ MPI_Offset *lenp)
+{
+ return ncmpi_inq_att(ncid, varid, name, NULL, lenp);
+}
+
+
+/*----< ncmpi_rename_att() >--------------------------------------------------*/
+/* This API is collective if called in data mode */
+int
+ncmpi_rename_att(int ncid,
+ int varid,
+ const char *name,
+ const char *newname)
+{
+ int indx, file_ver, status, err, mpireturn;
+ NC *ncp;
+ NC_attrarray *ncap;
+ NC_attr *attrp;
+
+ /* sortof inline clone of NC_lookupattr() */
+ status = ncmpii_NC_check_id(ncid, &ncp);
+ if (status != NC_NOERR) return status;
+
+ if (NC_readonly(ncp)) DEBUG_RETURN_ERROR(NC_EPERM)
+
+ ncap = NC_attrarray0(ncp, varid);
+ if (ncap == NULL) DEBUG_RETURN_ERROR(NC_ENOTVAR)
+
+ file_ver = 1;
+ if (fIsSet(ncp->flags, NC_64BIT_OFFSET))
+ file_ver = 2;
+ else if (fIsSet(ncp->flags, NC_64BIT_DATA))
+ file_ver = 5;
+
+ status = ncmpii_NC_check_name(newname, file_ver);
+ if (status != NC_NOERR) return status;
+
+ indx = ncmpii_NC_findattr(ncap, name);
+ if (indx < 0) DEBUG_RETURN_ERROR(NC_ENOTATT)
+
+ attrp = ncap->value[indx];
+ /* end inline clone NC_lookupattr() */
+
+ if (ncmpii_NC_findattr(ncap, newname) >= 0)
+ /* name in use */
+ DEBUG_RETURN_ERROR(NC_ENAMEINUSE)
+
+ if (NC_indef(ncp)) {
+ NC_string *newStr = ncmpii_new_NC_string(strlen(newname), newname);
+ if (newStr == NULL) DEBUG_RETURN_ERROR(NC_ENOMEM)
+
+ ncmpii_free_NC_string(attrp->name);
+ attrp->name = newStr;
+ return NC_NOERR;
+ }
+ /* else, not in define mode.
+ * If called in data mode (collective or independent), this function must
+ * be called collectively, i.e. all processes must participate
+ */
+
+ if (ncp->safe_mode) {
+ int nchars = (int) strlen(newname);
+ TRACE_COMM(MPI_Bcast)(&nchars, 1, MPI_INT, 0, ncp->nciop->comm);
+ if (mpireturn != MPI_SUCCESS)
+ return ncmpii_handle_error(mpireturn, "MPI_Bcast");
+
+ if (nchars != strlen(newname)) {
+ /* newname's length is inconsistent with root's */
+ printf("Warning: attribute name(%s) used in %s() is inconsistent\n",
+ newname, __func__);
+ if (status == NC_NOERR) DEBUG_ASSIGN_ERROR(status, NC_EMULTIDEFINE_ATTR_NAME)
+ }
+ }
+
+ /* ncmpii_set_NC_string() will check for strlen(newname) > nchars error */
+ err = ncmpii_set_NC_string(attrp->name, newname);
+ if (status == NC_NOERR) status = err;
+
+ /* PnetCDF expects all processes use the same name, However, when names
+ * are not the same, only root's value is significant. Broadcast the
+ * new name at root to overwrite new names at other processes.
+ * (This API is collective if called in data mode)
+ */
+ TRACE_COMM(MPI_Bcast)(attrp->name->cp, (int)attrp->name->nchars, MPI_CHAR, 0,
+ ncp->nciop->comm);
+
+ /* Let root write the entire header to the file. Note that we cannot just
+ * update the variable name in its space occupied in the file header,
+ * because if the file space occupied by the name shrinks, all the metadata
+ * following it must be moved ahead.
+ */
+ err = ncmpii_write_header(ncp);
+ if (status == NC_NOERR) status = err;
+
+ return status;
+}
+
+
+/*----< ncmpi_copy_att() >----------------------------------------------------*/
+/* This API is collective if called in data mode */
+int
+ncmpi_copy_att(int ncid_in,
+ int varid_in,
+ const char *name,
+ int ncid_out,
+ int varid_out)
+{
+ int indx, status, mpireturn;
+ NC *ncp;
+ NC_attrarray *ncap;
+ NC_attr *iattrp, *attrp, *old=NULL;
+
+ status = NC_lookupattr(ncid_in, varid_in, name, &iattrp);
+ if (status != NC_NOERR) return status;
+
+ status = ncmpii_NC_check_id(ncid_out, &ncp);
+ if (status != NC_NOERR) return status;
+
+ if (NC_readonly(ncp)) DEBUG_RETURN_ERROR(NC_EPERM)
+
+ ncap = NC_attrarray0(ncp, varid_out);
+ if (ncap == NULL) DEBUG_RETURN_ERROR(NC_ENOTVAR)
+
+ indx = ncmpii_NC_findattr(ncap, name);
+ if (indx >= 0) { /* name in use */
+ if (!NC_indef(ncp)) {
+ /* if called in data mode (collective or independent), this
+ * function must be called collectively, i.e. all processes must
+ * participate
+ */
+
+ attrp = ncap->value[indx]; /* convenience */
+
+ if (iattrp->xsz > attrp->xsz) DEBUG_RETURN_ERROR(NC_ENOTINDEFINE)
+ /* else, we can reuse existing without redef */
+
+ if (iattrp->xsz != (int)iattrp->xsz) DEBUG_RETURN_ERROR(NC_EINTOVERFLOW)
+
+ attrp->xsz = iattrp->xsz;
+ attrp->type = iattrp->type;
+ attrp->nelems = iattrp->nelems;
+
+ memcpy(attrp->xvalue, iattrp->xvalue, (size_t)iattrp->xsz);
+
+ /* PnetCDF expects all processes use the same name, However, when
+ * new attributes are not the same, only root's value is
+ * significant. Broadcast the new attribute at root to overwrite
+ * new names at other processes.
+ */
+ TRACE_COMM(MPI_Bcast)((void*)attrp->xvalue, (int)attrp->xsz,
+ MPI_CHAR, 0, ncp->nciop->comm);
+ if (mpireturn != MPI_SUCCESS)
+ return ncmpii_handle_error(mpireturn, "MPI_Bcast");
+
+ /* Let root write the entire header to the file. Note that we
+ * cannot just update the variable name in its space occupied in
+ * the file header, because if the file space occupied by the name
+ * shrinks, all the metadata following it must be moved ahead.
+ */
+ return ncmpii_write_header(ncp);
+ }
+ /* else, redefine using existing array slot */
+ old = ncap->value[indx];
+ }
+ else {
+ if (!NC_indef(ncp)) /* add new attribute is not allowed in data mode */
+ DEBUG_RETURN_ERROR(NC_ENOTINDEFINE)
+
+ if (ncap->ndefined >= NC_MAX_ATTRS)
+ DEBUG_RETURN_ERROR(NC_EMAXATTS)
+ }
+
+ attrp = ncmpii_new_NC_attr(name, iattrp->type, iattrp->nelems);
+ if (attrp == NULL) DEBUG_RETURN_ERROR(NC_ENOMEM)
+
+ memcpy(attrp->xvalue, iattrp->xvalue, (size_t)iattrp->xsz);
+
+ if (indx >= 0) {
+ assert(old != NULL);
+ ncap->value[indx] = attrp;
+ ncmpii_free_NC_attr(old);
+ }
+ else {
+ status = incr_NC_attrarray(ncap, attrp);
+ if (status != NC_NOERR) {
+ ncmpii_free_NC_attr(attrp);
+ return status;
+ }
+ }
+ return NC_NOERR;
+}
+
+/*----< ncmpi_del_att() >---------------------------------------------------*/
+int
+ncmpi_del_att(int ncid,
+ int varid,
+ const char *name)
+{
+ int status, attrid;
+ NC *ncp;
+ NC_attrarray *ncap;
+
+ status = ncmpii_NC_check_id(ncid, &ncp);
+ if (status != NC_NOERR) return status;
+
+ if (!NC_indef(ncp)) DEBUG_RETURN_ERROR(NC_ENOTINDEFINE)
+
+ ncap = NC_attrarray0(ncp, varid);
+ if (ncap == NULL) DEBUG_RETURN_ERROR(NC_ENOTVAR)
+
+ attrid = ncmpii_NC_findattr(ncap, name);
+ if (attrid == -1) DEBUG_RETURN_ERROR(NC_ENOTATT)
+
+ /* deleting attribute _FillValue means disabling fill mode */
+ if (!strcmp(name, _FillValue)) {
+ NC_var *varp;
+ status = ncmpii_NC_lookupvar(ncp, varid, &varp);
+ if (status != NC_NOERR) return status;
+ varp->no_fill = 1;
+ }
+
+ ncmpii_free_NC_attr(ncap->value[attrid]);
+
+ /* shuffle down */
+ for (; attrid < ncap->ndefined; attrid++)
+ ncap->value[attrid] = ncap->value[attrid+1];
+
+ /* decrement count */
+ ncap->ndefined--;
+
+ return NC_NOERR;
+}
+
+static nc_type longtype = (SIZEOF_LONG == SIZEOF_INT ? NC_INT : NC_INT64);
+
+/* ncmpi_pad_xxx APIs are only applicable for filetypes of size smaller
+ * than 4 bytes
+ */
+dnl
+dnl PAD_GETN_FILETYPE(filetype)
+dnl
+define(`PAD_GETN_FILETYPE',dnl
+`dnl
+/*----< ncmpix_pad_getn_$1() >-----------------------------------------------*/
+inline static int
+ncmpix_pad_getn_$1(const void **xpp,
+ MPI_Offset nelems,
+ void *tp,
+ nc_type buftype)
+{
+ switch(buftype) {
+ case NC_CHAR:
+ case NC_BYTE:
+ return ncmpix_pad_getn_$1_schar (xpp, nelems, (schar*)tp);
+ case NC_UBYTE:
+ return ncmpix_pad_getn_$1_uchar (xpp, nelems, (uchar*)tp);
+ case NC_SHORT:
+ return ncmpix_pad_getn_$1_short (xpp, nelems, (short*)tp);
+ case NC_USHORT:
+ return ncmpix_pad_getn_$1_ushort(xpp, nelems, (ushort*)tp);
+ case NC_INT:
+ return ncmpix_pad_getn_$1_int (xpp, nelems, (int*)tp);
+ case NC_UINT:
+ return ncmpix_pad_getn_$1_uint (xpp, nelems, (uint*)tp);
+ case NC_FLOAT:
+ return ncmpix_pad_getn_$1_float (xpp, nelems, (float*)tp);
+ case NC_DOUBLE:
+ return ncmpix_pad_getn_$1_double(xpp, nelems, (double*)tp);
+ case NC_INT64:
+ return ncmpix_pad_getn_$1_longlong (xpp, nelems, (longlong*)tp);
+ case NC_UINT64:
+ return ncmpix_pad_getn_$1_ulonglong(xpp, nelems, (ulonglong*)tp);
+ default:
+ assert("ncmpix_pad_getn_$1 invalid buffer type" == 0);
+ DEBUG_RETURN_ERROR(NC_EBADTYPE)
+ }
+}
+')dnl
+
+PAD_GETN_FILETYPE(schar)
+PAD_GETN_FILETYPE(uchar)
+PAD_GETN_FILETYPE(short)
+PAD_GETN_FILETYPE(ushort)
+
+dnl
+dnl GETN_FILETYPE(filetype)
+dnl
+define(`GETN_FILETYPE',dnl
+`dnl
+/*----< ncmpix_getn_$1() >---------------------------------------------------*/
+inline static int
+ncmpix_getn_$1(const void **xpp,
+ MPI_Offset nelems,
+ void *tp,
+ nc_type buftype)
+{
+ switch(buftype) {
+ case NC_CHAR:
+ case NC_BYTE:
+ return ncmpix_getn_$1_schar (xpp, nelems, (schar*)tp);
+ case NC_UBYTE:
+ return ncmpix_getn_$1_uchar (xpp, nelems, (uchar*)tp);
+ case NC_SHORT:
+ return ncmpix_getn_$1_short (xpp, nelems, (short*)tp);
+ case NC_USHORT:
+ return ncmpix_getn_$1_ushort(xpp, nelems, (ushort*)tp);
+ case NC_INT:
+ return ncmpix_getn_$1_int (xpp, nelems, (int*)tp);
+ case NC_UINT:
+ return ncmpix_getn_$1_uint (xpp, nelems, (uint*)tp);
+ case NC_FLOAT:
+ return ncmpix_getn_$1_float (xpp, nelems, (float*)tp);
+ case NC_DOUBLE:
+ return ncmpix_getn_$1_double(xpp, nelems, (double*)tp);
+ case NC_INT64:
+ return ncmpix_getn_$1_longlong (xpp, nelems, (longlong*)tp);
+ case NC_UINT64:
+ return ncmpix_getn_$1_ulonglong(xpp, nelems, (ulonglong*)tp);
+ default:
+ assert("ncmpix_pad_getn_$1 invalid buffer type" == 0);
+ DEBUG_RETURN_ERROR(NC_EBADTYPE)
+ }
+}
+')dnl
+
+GETN_FILETYPE(int)
+GETN_FILETYPE(uint)
+GETN_FILETYPE(float)
+GETN_FILETYPE(double)
+GETN_FILETYPE(int64)
+GETN_FILETYPE(uint64)
+
+/*----< ncmpix_pad_getn() >--------------------------------------------------*/
+/* padding only applicable to file types of size smaller than 4 bytes */
+inline static int
+ncmpix_pad_getn(const void **xpp,
+ MPI_Offset nelems,
+ void *tp,
+ nc_type filetype,
+ nc_type buftype)
+{
+ /* get n elements from (filetype*)*xpp to (buftype*)tp */
+ /* Checking for character-number conversion should have already been done */
+
+ switch(filetype) {
+ case NC_CHAR:
+ case NC_BYTE:
+ return ncmpix_pad_getn_schar (xpp, nelems, tp, buftype);
+ case NC_UBYTE:
+ return ncmpix_pad_getn_uchar (xpp, nelems, tp, buftype);
+ case NC_SHORT:
+ return ncmpix_pad_getn_short (xpp, nelems, tp, buftype);
+ case NC_USHORT:
+ return ncmpix_pad_getn_ushort(xpp, nelems, tp, buftype);
+ case NC_INT:
+ return ncmpix_getn_int (xpp, nelems, tp, buftype);
+ case NC_UINT:
+ return ncmpix_getn_uint (xpp, nelems, tp, buftype);
+ case NC_FLOAT:
+ return ncmpix_getn_float (xpp, nelems, tp, buftype);
+ case NC_DOUBLE:
+ return ncmpix_getn_double (xpp, nelems, tp, buftype);
+ case NC_INT64:
+ return ncmpix_getn_int64 (xpp, nelems, tp, buftype);
+ case NC_UINT64:
+ return ncmpix_getn_uint64 (xpp, nelems, tp, buftype);
+ default:
+ assert("ncmpix_pad_getn invalid filetype" == 0);
+ DEBUG_RETURN_ERROR(NC_EBADTYPE)
+ }
+}
+
+/*----< ncmpii_get_att() >---------------------------------------------------*/
+static int
+ncmpii_get_att(int ncid,
+ int varid,
+ const char *name,
+ void *tp, /* I/O buffer */
+ nc_type buftype) /* I/O buffer data type */
+{
+ int status;
+ NC_attr *attrp;
+
+ status = NC_lookupattr(ncid, varid, name, &attrp);
+ if (status != NC_NOERR) return status;
+
+ if (attrp->nelems == 0) return NC_NOERR;
+
+ /* No character conversions are allowed. */
+ if (attrp->type != buftype &&
+ (attrp->type == NC_CHAR || buftype == NC_CHAR))
+ DEBUG_RETURN_ERROR(NC_ECHAR)
+
+ const void *xp = attrp->xvalue;
+ return ncmpix_pad_getn(&xp, attrp->nelems, tp, attrp->type, buftype);
+}
+
+/*----< ncmpi_get_att() >-----------------------------------------------------*/
+int
+ncmpi_get_att(int ncid,
+ int varid,
+ const char *name,
+ void *value)
+{
+ int status;
+ nc_type atttype;
+
+ status = ncmpi_inq_atttype(ncid, varid, name, &atttype);
+ if (status != NC_NOERR) return status;
+
+ return ncmpii_get_att(ncid, varid, name, value, atttype);
+}
+
+dnl
+dnl GET_ATT_TYPE(fntype, ext_buftype, nc_buftype)
+dnl
+define(`GET_ATT_TYPE',dnl
+`dnl
+/*----< ncmpi_get_att_$1() >-------------------------------------------------*/
+int
+ncmpi_get_att_$1(int ncid, int varid, const char *name, $2 *value)
+{
+ return ncmpii_get_att(ncid, varid, name, value, $3);
+}
+')dnl
+
+GET_ATT_TYPE(text, char, NC_CHAR)
+GET_ATT_TYPE(schar, signed char, NC_BYTE)
+GET_ATT_TYPE(uchar, unsigned char, NC_UBYTE)
+GET_ATT_TYPE(ubyte, unsigned char, NC_UBYTE)
+GET_ATT_TYPE(short, short, NC_SHORT)
+GET_ATT_TYPE(ushort, unsigned short, NC_USHORT)
+GET_ATT_TYPE(int, int, NC_INT)
+GET_ATT_TYPE(uint, unsigned int, NC_UINT)
+GET_ATT_TYPE(long, long, longtype)
+GET_ATT_TYPE(float, float, NC_FLOAT)
+GET_ATT_TYPE(double, double, NC_DOUBLE)
+GET_ATT_TYPE(longlong, long long, NC_INT64)
+GET_ATT_TYPE(ulonglong, unsigned long long, NC_UINT64)
+
+dnl
+dnl PAD_PUTN_FILETYPE(ftype)
+dnl
+define(`PAD_PUTN_FILETYPE',dnl
+`dnl
+/*----< ncmpix_pad_putn_$1() >-----------------------------------------------*/
+inline static int
+ncmpix_pad_putn_$1(void **xpp,
+ MPI_Offset nelems,
+ const void *tp,
+ nc_type btype)
+{
+ switch(btype) {
+ case NC_CHAR:
+ case NC_BYTE:
+ return ncmpix_pad_putn_$1_schar (xpp, nelems, (schar*)tp);
+ case NC_UBYTE:
+ return ncmpix_pad_putn_$1_uchar (xpp, nelems, (uchar*)tp);
+ case NC_SHORT:
+ return ncmpix_pad_putn_$1_short (xpp, nelems, (short*)tp);
+ case NC_USHORT:
+ return ncmpix_pad_putn_$1_ushort(xpp, nelems, (ushort*)tp);
+ case NC_INT:
+ return ncmpix_pad_putn_$1_int (xpp, nelems, (int*)tp);
+ case NC_UINT:
+ return ncmpix_pad_putn_$1_uint (xpp, nelems, (uint*)tp);
+ case NC_FLOAT:
+ return ncmpix_pad_putn_$1_float (xpp, nelems, (float*)tp);
+ case NC_DOUBLE:
+ return ncmpix_pad_putn_$1_double(xpp, nelems, (double*)tp);
+ case NC_INT64:
+ return ncmpix_pad_putn_$1_longlong (xpp, nelems, (longlong*)tp);
+ case NC_UINT64:
+ return ncmpix_pad_putn_$1_ulonglong(xpp, nelems, (ulonglong*)tp);
+ default:
+ assert("ncmpix_pad_putn_$1 invalid type" == 0);
+ DEBUG_RETURN_ERROR(NC_EBADTYPE)
+ }
+}
+')dnl
+
+PAD_PUTN_FILETYPE(schar)
+PAD_PUTN_FILETYPE(uchar)
+PAD_PUTN_FILETYPE(short)
+PAD_PUTN_FILETYPE(ushort)
+
+dnl
+dnl PUTN_FILETYPE(ftype)
+dnl
+define(`PUTN_FILETYPE',dnl
+`dnl
+/*----< ncmpix_putn_$1() >---------------------------------------------------*/
+inline static int
+ncmpix_putn_$1(void **xpp,
+ MPI_Offset nelems,
+ const void *tp,
+ nc_type btype)
+{
+ switch(btype) {
+ case NC_CHAR:
+ case NC_BYTE:
+ return ncmpix_putn_$1_schar (xpp, nelems, (schar*)tp);
+ case NC_UBYTE:
+ return ncmpix_putn_$1_uchar (xpp, nelems, (uchar*)tp);
+ case NC_SHORT:
+ return ncmpix_putn_$1_short (xpp, nelems, (short*)tp);
+ case NC_USHORT:
+ return ncmpix_putn_$1_ushort(xpp, nelems, (ushort*)tp);
+ case NC_INT:
+ return ncmpix_putn_$1_int (xpp, nelems, (int*)tp);
+ case NC_UINT:
+ return ncmpix_putn_$1_uint (xpp, nelems, (uint*)tp);
+ case NC_FLOAT:
+ return ncmpix_putn_$1_float (xpp, nelems, (float*)tp);
+ case NC_DOUBLE:
+ return ncmpix_putn_$1_double(xpp, nelems, (double*)tp);
+ case NC_INT64:
+ return ncmpix_putn_$1_longlong (xpp, nelems, (longlong*)tp);
+ case NC_UINT64:
+ return ncmpix_putn_$1_ulonglong(xpp, nelems, (ulonglong*)tp);
+ default:
+ assert("ncmpix_putn_$1 invalid type" == 0);
+ DEBUG_RETURN_ERROR(NC_EBADTYPE)
+ }
+}
+')dnl
+
+PUTN_FILETYPE(int)
+PUTN_FILETYPE(uint)
+PUTN_FILETYPE(float)
+PUTN_FILETYPE(double)
+PUTN_FILETYPE(int64)
+PUTN_FILETYPE(uint64)
+
+/*----< ncmpix_pad_putn() >--------------------------------------------------*/
+/* padding only applicable to file types of size smaller than 4 bytes */
+inline static int
+ncmpix_pad_putn(void **xpp,
+ MPI_Offset nelems,
+ const void *tp,
+ nc_type filetype,
+ nc_type buftype)
+{
+ /* put n elements from (buftype*)tp to (filetype*)*xpp */
+ /* Checking for character-number conversion should have been done */
+
+ switch(filetype) {
+ case NC_CHAR:
+ case NC_BYTE:
+ return ncmpix_pad_putn_schar (xpp, nelems, tp, buftype);
+ case NC_UBYTE:
+ return ncmpix_pad_putn_uchar (xpp, nelems, tp, buftype);
+ case NC_SHORT:
+ return ncmpix_pad_putn_short (xpp, nelems, tp, buftype);
+ case NC_USHORT:
+ return ncmpix_pad_putn_ushort(xpp, nelems, tp, buftype);
+ case NC_INT:
+ return ncmpix_putn_int (xpp, nelems, tp, buftype);
+ case NC_UINT:
+ return ncmpix_putn_uint (xpp, nelems, tp, buftype);
+ case NC_FLOAT:
+ return ncmpix_putn_float (xpp, nelems, tp, buftype);
+ case NC_DOUBLE:
+ return ncmpix_putn_double (xpp, nelems, tp, buftype);
+ case NC_INT64:
+ return ncmpix_putn_int64 (xpp, nelems, tp, buftype);
+ case NC_UINT64:
+ return ncmpix_putn_uint64 (xpp, nelems, tp, buftype);
+ default:
+ assert("ncmpix_pad_putn invalid filetype" == 0);
+ DEBUG_RETURN_ERROR(NC_EBADTYPE)
+ }
+}
+
+/*----< ncmpii_put_att() >---------------------------------------------------*/
+/* Note from netCDF user guide:
+ * Attributes are always single values or one-dimensional arrays. This works
+ * out well for a string, which is a one-dimensional array of ASCII characters
+ *
+ * This PnetCDF API is collective if called in data mode.
+ */
+static int
+ncmpii_put_att(int ncid,
+ int varid,
+ const char *name, /* attribute name */
+ nc_type filetype, /* type defined in file header */
+ MPI_Offset nelems, /* number of elements of type buftype */
+ const void *buf, /* I/O buffer */
+ nc_type buftype) /* I/O buffer type */
+{
+ int indx, file_ver, err, status=NC_NOERR, mpireturn;
+ NC *ncp;
+ NC_attrarray *ncap;
+ NC_attr *attrp, *old=NULL;
+
+ if (!name || strlen(name) > NC_MAX_NAME)
+ DEBUG_RETURN_ERROR(NC_EBADNAME)
+
+ /* Should CDF-5 allow very large file header? */
+ /* if (len > X_INT_MAX) DEBUG_RETURN_ERROR(NC_EINVAL) */
+
+ /* get the file ID */
+ status = ncmpii_NC_check_id(ncid, &ncp);
+ if (status != NC_NOERR) return status;
+
+ /* file should be opened with writable permission */
+ if (NC_readonly(ncp)) DEBUG_RETURN_ERROR(NC_EPERM)
+
+ /* nelems can be zero, i.e. an attribute with only its name */
+ if (nelems > 0 && buf == NULL)
+ DEBUG_RETURN_ERROR(NC_EINVAL) /* Null arg */
+
+ /* If this is the _FillValue attribute, then let PnetCDF return the
+ * same error codes as netCDF
+ */
+ if (!strcmp(name, "_FillValue")) {
+ NC_var *varp;
+ status = ncmpii_NC_lookupvar(ncp, varid, &varp);
+ if (status != NC_NOERR) return status;
+
+ /* Fill value must be same type and have exactly one value */
+ if (filetype != varp->type)
+ DEBUG_RETURN_ERROR(NC_EBADTYPE)
+
+ if (nelems != 1)
+ DEBUG_RETURN_ERROR(NC_EINVAL)
+ }
+
+ /* get the file format version */
+ file_ver = 1;
+ if (fIsSet(ncp->flags, NC_64BIT_OFFSET))
+ file_ver = 2;
+ else if (fIsSet(ncp->flags, NC_64BIT_DATA))
+ file_ver = 5;
+
+ if (nelems < 0 || (nelems > X_INT_MAX && file_ver <= 2))
+ DEBUG_RETURN_ERROR(NC_EINVAL) /* Invalid nelems */
+
+ /* check if filetype is valid, as filetype is given by user
+ * no need to check buftype, as buftype is set internally
+ */
+ status = ncmpii_cktype(file_ver, filetype);
+ if (status != NC_NOERR) return status;
+
+ /* No character conversions are allowed. */
+ if (filetype != buftype &&
+ (filetype == NC_CHAR || buftype == NC_CHAR))
+ DEBUG_RETURN_ERROR(NC_ECHAR)
+
+ /* check if the attribute name is legal */
+ status = ncmpii_NC_check_name(name, file_ver);
+ if (status != NC_NOERR) return status;
+
+ /* get the pointer to the attribute array */
+ ncap = NC_attrarray0(ncp, varid);
+ if (ncap == NULL) DEBUG_RETURN_ERROR(NC_ENOTVAR)
+
+ indx = ncmpii_NC_findattr(ncap, name);
+ if (indx >= 0) { /* name in use */
+ if (!NC_indef(ncp)) {
+ /* in data mode, meaning to over-write an existing attribute
+ * if called in data mode (collective or independent), this
+ * function must be called collectively, i.e. all processes must
+ * participate
+ */
+
+ const MPI_Offset xsz = ncmpix_len_NC_attrV(filetype, nelems);
+ /* xsz is the total size of this attribute */
+
+ attrp = ncap->value[indx]; /* convenience */
+
+ if (xsz > attrp->xsz) /* new attribute requires a larger space */
+ DEBUG_RETURN_ERROR(NC_ENOTINDEFINE)
+ /* else, we can reuse existing without redef */
+
+ if (xsz != (int)xsz) DEBUG_RETURN_ERROR(NC_EINTOVERFLOW)
+
+ attrp->xsz = xsz;
+ attrp->type = filetype;
+ attrp->nelems = nelems;
+
+ if (nelems != 0) {
+ void *xp = attrp->xvalue;
+ /* using xp to prevent change the pointer attr->xvalue,
+ * as ncmpix_pad_putn() advances the first argument
+ * with nelems elements
+ */
+ status = ncmpix_pad_putn(&xp, nelems, buf, filetype, buftype);
+ /* wkliao: why not return here if status != NC_NOERR? */
+
+ /* PnetCDF expects all processes use the same argument values.
+ * However, when argument values are not the same, only root's
+ * value is significant. Broadcast the new attribute at root to
+ * overwrite new attribute at other processes.
+ */
+ TRACE_COMM(MPI_Bcast)(attrp->xvalue, (int)attrp->xsz, MPI_BYTE,
+ 0, ncp->nciop->comm);
+ if (mpireturn != MPI_SUCCESS) {
+ err = ncmpii_handle_error(mpireturn, "MPI_Bcast");
+ if (status == NC_NOERR) status = err;
+ }
+ }
+
+ /* Let root write the entire header to the file. Note that we
+ * cannot just update the attribute in its space occupied in the
+ * file header, because if the file space occupied by the attribute
+ * shrinks, all the metadata following it must be moved ahead.
+ */
+ err = ncmpii_write_header(ncp);
+ return (status == NC_NOERR) ? err : status;
+ }
+ /* else, redefine using existing array slot */
+ old = ncap->value[indx];
+ }
+ else { /* name never been used */
+ /* creating new attributes must be done in define mode */
+ if (!NC_indef(ncp)) DEBUG_RETURN_ERROR(NC_ENOTINDEFINE)
+
+ if (ncap->ndefined >= NC_MAX_ATTRS)
+ DEBUG_RETURN_ERROR(NC_EMAXATTS)
+ }
+
+ /* create a new attribute object */
+ attrp = ncmpii_new_NC_attr(name, filetype, nelems);
+ if (attrp == NULL) DEBUG_RETURN_ERROR(NC_ENOMEM)
+
+ if (nelems != 0) { /* non-zero length attribute */
+ void *xp = attrp->xvalue;
+ status = ncmpix_pad_putn(&xp, nelems, buf, filetype, buftype);
+ /* wkliao: no immediately return error code here? Strange ...
+ * Instead, we continue and call incr_NC_attrarray() to add
+ * this attribute (for create case) as it is legal. But if
+ * we return error and reject this attribute, then nc_test will
+ * fail with this error message below:
+ * FAILURE at line 252 of test_read.c: ncmpi_inq: wrong number
+ * of global atts returned, 3
+ * Check netCDF-4, it is doing the same thing!
+ *
+ * One of the error codes returned from ncmpix_pad_putn() is
+ * NC_ERANGE, meaning one or more elements are type overflow.
+ * Should we reject the entire attribute array if only part of
+ * the array overflow? For netCDF4, the answer is NO.
+ */
+/*
+ if (status != NC_NOERR) {
+ ncmpii_free_NC_attr(attrp);
+ return status;
+ }
+*/
+ }
+
+ if (indx >= 0) { /* modify the existing attribute */
+ assert(old != NULL);
+ ncap->value[indx] = attrp;
+ ncmpii_free_NC_attr(old);
+ }
+ else { /* creating a new attribute */
+ err = incr_NC_attrarray(ncap, attrp);
+ if (err != NC_NOERR) {
+ ncmpii_free_NC_attr(attrp);
+ return err;
+ }
+ }
+
+ return status;
+}
+
+/*----< ncmpi_put_att() >-----------------------------------------------------*/
+int
+ncmpi_put_att(int ncid,
+ int varid,
+ const char *name,
+ nc_type xtype,
+ MPI_Offset nelems,
+ const void *value)
+{
+ return ncmpii_put_att(ncid, varid, name, xtype, nelems, value, xtype);
+}
+
+/*----< ncmpi_put_att_text() >-----------------------------------------------*/
+int
+ncmpi_put_att_text(int ncid, int varid, const char *name,
+ MPI_Offset nelems, const char *value)
+{
+ return ncmpii_put_att(ncid, varid, name, NC_CHAR,
+ nelems, value, NC_CHAR);
+}
+
+dnl
+dnl PUT_ATT_TYPE(fntype, ext_buftype, nc_buftype)
+dnl
+define(`PUT_ATT_TYPE',dnl
+`dnl
+/*----< ncmpi_put_att_$1() >-------------------------------------------------*/
+int
+ncmpi_put_att_$1(int ncid, int varid, const char *name, nc_type xtype,
+ MPI_Offset nelems, const $2 *value)
+{
+ return ncmpii_put_att(ncid, varid, name, xtype, nelems, value, $3);
+}
+')dnl
+
+PUT_ATT_TYPE(schar, signed char, NC_BYTE)
+PUT_ATT_TYPE(uchar, unsigned char, NC_UBYTE)
+PUT_ATT_TYPE(ubyte, unsigned char, NC_UBYTE)
+PUT_ATT_TYPE(short, short, NC_SHORT)
+PUT_ATT_TYPE(ushort, unsigned short, NC_USHORT)
+PUT_ATT_TYPE(int, int, NC_INT)
+PUT_ATT_TYPE(uint, unsigned int, NC_UINT)
+PUT_ATT_TYPE(long, long, longtype)
+PUT_ATT_TYPE(float, float, NC_FLOAT)
+PUT_ATT_TYPE(double, double, NC_DOUBLE)
+PUT_ATT_TYPE(longlong, long long, NC_INT64)
+PUT_ATT_TYPE(ulonglong, unsigned long long, NC_UINT64)
+
+/* For netCDF, the type mapping between file types and buffer types
+ * are based on netcdf4. Check APIs of nc_put_att_xxx from source files
+ * netCDF/netcdf-4.1.3/libdispatch/att.c
+ * netCDF/netcdf-4.1.3/libsrc4/nc4attr.c
+ *
+ * Note that schar means signed 1-byte integers in attributes. Hence the call
+ * below is illegal. NC_ECHAR will return, indicating the error on trying
+ * type conversion between characters and numbers.
+ *
+ * ncmpi_put_att_schar(ncid, varid, "attr name", NC_CHAR, strlen(attrp), attrp);
+ *
+ * This rule and mapping apply for variables as well. See APIs of
+ * nc_put_vara_xxx from source files
+ * netCDF/netcdf-4.1.3/libdispatch/var.c
+ * netCDF/netcdf-4.1.3/libsrc4/nc4var.c
+ *
+ */
diff --git a/src/lib/bput.m4 b/src/lib/bput.m4
new file mode 100644
index 0000000..5e69fea
--- /dev/null
+++ b/src/lib/bput.m4
@@ -0,0 +1,551 @@
+dnl Process this m4 file to produce 'C' language file.
+dnl
+dnl If you see this line, you can ignore the next one.
+/* Do not edit this file. It is produced from the corresponding .m4 source */
+dnl
+/*
+ * Copyright (C) 2003, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ */
+/* $Id: bput.m4 2290 2016-01-02 18:37:46Z wkliao $ */
+
+#if HAVE_CONFIG_H
+# include "ncconfig.h"
+#endif
+
+#include <stdio.h>
+#include <unistd.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#include <assert.h>
+
+#include <mpi.h>
+
+#include "nc.h"
+#include "ncx.h"
+#include "ncmpidtype.h"
+#include "macro.h"
+
+
+/*----< ncmpi_bput_var() >----------------------------------------------------*/
+int
+ncmpi_bput_var(int ncid,
+ int varid,
+ const void *buf,
+ MPI_Offset bufcount,
+ MPI_Datatype buftype,
+ int *reqid)
+{
+ int status;
+ NC *ncp;
+ NC_var *varp=NULL;
+ MPI_Offset *start, *count;
+
+ if (reqid != NULL) *reqid = NC_REQ_NULL;
+ status = ncmpii_sanity_check(ncid, varid, NULL, NULL, bufcount, API_VAR,
+ 0, 1, WRITE_REQ, NONBLOCKING_IO, &ncp, &varp);
+ if (status != NC_NOERR) return status;
+
+ if (ncp->abuf == NULL) DEBUG_RETURN_ERROR(NC_ENULLABUF)
+
+ GET_FULL_DIMENSIONS(start, count)
+
+ /* bput_var is a special case of bput_varm */
+ status = ncmpii_igetput_varm(ncp, varp, start, count, NULL, NULL,
+ (void*)buf, bufcount, buftype, reqid,
+ WRITE_REQ, 1, 0);
+ if (varp->ndims > 0) NCI_Free(start);
+ return status;
+}
+
+
+dnl
+dnl BPUT_VAR_TYPE(ncid, varid, op, reqid)
+dnl
+define(`BPUT_VAR_TYPE',dnl
+`dnl
+/*----< ncmpi_bput_var_$1() >-------------------------------------------------*/
+int
+ncmpi_bput_var_$1(int ncid,
+ int varid,
+ const $2 *op,
+ int *reqid)
+{
+ int status;
+ NC *ncp;
+ NC_var *varp=NULL;
+ MPI_Offset *start, *count;
+
+ if (reqid != NULL) *reqid = NC_REQ_NULL;
+ status = ncmpii_sanity_check(ncid, varid, NULL, NULL, 0, API_VAR,
+ 0, 0, WRITE_REQ, NONBLOCKING_IO, &ncp, &varp);
+ if (status != NC_NOERR) return status;
+
+ if (ncp->abuf == NULL) DEBUG_RETURN_ERROR(NC_ENULLABUF)
+
+ GET_FULL_DIMENSIONS(start, count)
+
+ /* bput_var is a special case of bput_varm */
+ status = ncmpii_igetput_varm(ncp, varp, start, count, NULL, NULL,
+ (void*)op, -1, $3, reqid, WRITE_REQ, 1, 0);
+ if (varp->ndims > 0) NCI_Free(start);
+ return status;
+}
+')dnl
+
+BPUT_VAR_TYPE(text, char, MPI_CHAR)
+BPUT_VAR_TYPE(schar, schar, MPI_SIGNED_CHAR)
+BPUT_VAR_TYPE(uchar, uchar, MPI_UNSIGNED_CHAR)
+BPUT_VAR_TYPE(short, short, MPI_SHORT)
+BPUT_VAR_TYPE(ushort, ushort, MPI_UNSIGNED_SHORT)
+BPUT_VAR_TYPE(int, int, MPI_INT)
+BPUT_VAR_TYPE(uint, uint, MPI_UNSIGNED)
+BPUT_VAR_TYPE(long, long, MPI_LONG)
+BPUT_VAR_TYPE(float, float, MPI_FLOAT)
+BPUT_VAR_TYPE(double, double, MPI_DOUBLE)
+BPUT_VAR_TYPE(longlong, long long, MPI_LONG_LONG_INT)
+BPUT_VAR_TYPE(ulonglong, unsigned long long, MPI_UNSIGNED_LONG_LONG)
+
+
+/*----< ncmpi_bput_var1() >---------------------------------------------------*/
+int
+ncmpi_bput_var1(int ncid,
+ int varid,
+ const MPI_Offset *start,
+ const void *buf,
+ MPI_Offset bufcount,
+ MPI_Datatype buftype,
+ int *reqid)
+{
+ int status;
+ NC *ncp;
+ NC_var *varp=NULL;
+ MPI_Offset *count;
+
+ if (reqid != NULL) *reqid = NC_REQ_NULL;
+ status = ncmpii_sanity_check(ncid, varid, start, NULL, bufcount, API_VAR1,
+ 0, 1, WRITE_REQ, NONBLOCKING_IO, &ncp, &varp);
+ if (status != NC_NOERR) return status;
+
+ if (ncp->abuf == NULL) DEBUG_RETURN_ERROR(NC_ENULLABUF)
+
+ GET_ONE_COUNT(count)
+
+ status = ncmpii_igetput_varm(ncp, varp, start, count, NULL, NULL,
+ (void*)buf, bufcount, buftype, reqid,
+ WRITE_REQ, 1, 0);
+ if (varp->ndims > 0) NCI_Free(count);
+ return status;
+}
+
+dnl
+dnl BPUT_VAR1_TYPE(ncid, varid, start, op, reqid)
+dnl
+define(`BPUT_VAR1_TYPE',dnl
+`dnl
+/*----< ncmpi_bput_var1_$1() >------------------------------------------------*/
+int
+ncmpi_bput_var1_$1(int ncid,
+ int varid,
+ const MPI_Offset start[],
+ const $2 *op,
+ int *reqid)
+{
+ int status;
+ NC *ncp;
+ NC_var *varp=NULL;
+ MPI_Offset *count;
+
+ if (reqid != NULL) *reqid = NC_REQ_NULL;
+ status = ncmpii_sanity_check(ncid, varid, start, NULL, 0, API_VAR1,
+ 0, 0, WRITE_REQ, NONBLOCKING_IO, &ncp, &varp);
+ if (status != NC_NOERR) return status;
+
+ if (ncp->abuf == NULL) DEBUG_RETURN_ERROR(NC_ENULLABUF)
+
+ GET_ONE_COUNT(count)
+
+ status = ncmpii_igetput_varm(ncp, varp, start, count, NULL, NULL,
+ (void*)op, -1, $3, reqid, WRITE_REQ, 1, 0);
+ if (varp->ndims > 0) NCI_Free(count);
+ return status;
+}
+')dnl
+
+BPUT_VAR1_TYPE(text, char, MPI_CHAR)
+BPUT_VAR1_TYPE(schar, schar, MPI_SIGNED_CHAR)
+BPUT_VAR1_TYPE(uchar, uchar, MPI_UNSIGNED_CHAR)
+BPUT_VAR1_TYPE(short, short, MPI_SHORT)
+BPUT_VAR1_TYPE(ushort, ushort, MPI_UNSIGNED_SHORT)
+BPUT_VAR1_TYPE(int, int, MPI_INT)
+BPUT_VAR1_TYPE(uint, uint, MPI_UNSIGNED)
+BPUT_VAR1_TYPE(long, long, MPI_LONG)
+BPUT_VAR1_TYPE(float, float, MPI_FLOAT)
+BPUT_VAR1_TYPE(double, double, MPI_DOUBLE)
+BPUT_VAR1_TYPE(longlong, long long, MPI_LONG_LONG_INT)
+BPUT_VAR1_TYPE(ulonglong, unsigned long long, MPI_UNSIGNED_LONG_LONG)
+
+
+/*----< ncmpi_bput_vara() >---------------------------------------------------*/
+int
+ncmpi_bput_vara(int ncid,
+ int varid,
+ const MPI_Offset *start,
+ const MPI_Offset *count,
+ const void *buf,
+ MPI_Offset bufcount,
+ MPI_Datatype buftype,
+ int *reqid)
+{
+ int status;
+ NC *ncp;
+ NC_var *varp=NULL;
+
+ if (reqid != NULL) *reqid = NC_REQ_NULL;
+ status = ncmpii_sanity_check(ncid, varid, start, count, bufcount, API_VARA,
+ 0, 1, WRITE_REQ, NONBLOCKING_IO, &ncp, &varp);
+ if (status != NC_NOERR) return status;
+
+ if (ncp->abuf == NULL) DEBUG_RETURN_ERROR(NC_ENULLABUF)
+
+ return ncmpii_igetput_varm(ncp, varp, start, count, NULL, NULL,
+ (void*)buf, bufcount, buftype, reqid,
+ WRITE_REQ, 1, 0);
+}
+
+dnl
+dnl BPUT_VARA_TYPE(ncid, varid, start, count, op, reqid)
+dnl
+define(`BPUT_VARA_TYPE',dnl
+`dnl
+/*----< ncmpi_bput_vara_$1() >------------------------------------------------*/
+int
+ncmpi_bput_vara_$1(int ncid,
+ int varid,
+ const MPI_Offset start[],
+ const MPI_Offset count[],
+ const $2 *op,
+ int *reqid)
+{
+ int status;
+ NC *ncp;
+ NC_var *varp=NULL;
+
+ if (reqid != NULL) *reqid = NC_REQ_NULL;
+ status = ncmpii_sanity_check(ncid, varid, start, count, 0, API_VARA,
+ 0, 0, WRITE_REQ, NONBLOCKING_IO, &ncp, &varp);
+ if (status != NC_NOERR) return status;
+
+ if (ncp->abuf == NULL) DEBUG_RETURN_ERROR(NC_ENULLABUF)
+
+ return ncmpii_igetput_varm(ncp, varp, start, count, NULL, NULL,
+ (void*)op, -1, $3, reqid, WRITE_REQ, 1, 0);
+}
+')dnl
+
+BPUT_VARA_TYPE(text, char, MPI_CHAR)
+BPUT_VARA_TYPE(schar, schar, MPI_SIGNED_CHAR)
+BPUT_VARA_TYPE(uchar, uchar, MPI_UNSIGNED_CHAR)
+BPUT_VARA_TYPE(short, short, MPI_SHORT)
+BPUT_VARA_TYPE(ushort, ushort, MPI_UNSIGNED_SHORT)
+BPUT_VARA_TYPE(int, int, MPI_INT)
+BPUT_VARA_TYPE(uint, uint, MPI_UNSIGNED)
+BPUT_VARA_TYPE(long, long, MPI_LONG)
+BPUT_VARA_TYPE(float, float, MPI_FLOAT)
+BPUT_VARA_TYPE(double, double, MPI_DOUBLE)
+BPUT_VARA_TYPE(longlong, long long, MPI_LONG_LONG_INT)
+BPUT_VARA_TYPE(ulonglong, unsigned long long, MPI_UNSIGNED_LONG_LONG)
+
+
+/*----< ncmpi_bput_vars() >---------------------------------------------------*/
+int
+ncmpi_bput_vars(int ncid,
+ int varid,
+ const MPI_Offset start[],
+ const MPI_Offset count[],
+ const MPI_Offset stride[],
+ const void *buf,
+ MPI_Offset bufcount,
+ MPI_Datatype buftype,
+ int *reqid)
+{
+ int status;
+ NC *ncp;
+ NC_var *varp=NULL;
+
+ if (reqid != NULL) *reqid = NC_REQ_NULL;
+ status = ncmpii_sanity_check(ncid, varid, start, count, bufcount, API_VARS,
+ 0, 1, WRITE_REQ, NONBLOCKING_IO, &ncp, &varp);
+ if (status != NC_NOERR) return status;
+
+ if (ncp->abuf == NULL) DEBUG_RETURN_ERROR(NC_ENULLABUF)
+
+ return ncmpii_igetput_varm(ncp, varp, start, count, stride, NULL,
+ (void*)buf, bufcount, buftype, reqid,
+ WRITE_REQ, 1, 0);
+}
+
+dnl
+dnl BPUT_VARS_TYPE(ncid, varid, start, count, stride, op, reqid)
+dnl
+define(`BPUT_VARS_TYPE',dnl
+`dnl
+/*----< ncmpi_bput_vars_$1() >------------------------------------------------*/
+int
+ncmpi_bput_vars_$1(int ncid,
+ int varid,
+ const MPI_Offset start[],
+ const MPI_Offset count[],
+ const MPI_Offset stride[],
+ const $2 *op,
+ int *reqid)
+{
+ int status;
+ NC *ncp;
+ NC_var *varp=NULL;
+
+ if (reqid != NULL) *reqid = NC_REQ_NULL;
+ status = ncmpii_sanity_check(ncid, varid, start, count, 0, API_VARS,
+ 0, 0, WRITE_REQ, NONBLOCKING_IO, &ncp, &varp);
+ if (status != NC_NOERR) return status;
+
+ if (ncp->abuf == NULL) DEBUG_RETURN_ERROR(NC_ENULLABUF)
+
+ return ncmpii_igetput_varm(ncp, varp, start, count, stride, NULL,
+ (void*)op, -1, $3, reqid, WRITE_REQ, 1, 0);
+}
+')dnl
+
+BPUT_VARS_TYPE(text, char, MPI_CHAR)
+BPUT_VARS_TYPE(schar, schar, MPI_SIGNED_CHAR)
+BPUT_VARS_TYPE(uchar, uchar, MPI_UNSIGNED_CHAR)
+BPUT_VARS_TYPE(short, short, MPI_SHORT)
+BPUT_VARS_TYPE(ushort, ushort, MPI_UNSIGNED_SHORT)
+BPUT_VARS_TYPE(int, int, MPI_INT)
+BPUT_VARS_TYPE(uint, uint, MPI_UNSIGNED)
+BPUT_VARS_TYPE(long, long, MPI_LONG)
+BPUT_VARS_TYPE(float, float, MPI_FLOAT)
+BPUT_VARS_TYPE(double, double, MPI_DOUBLE)
+BPUT_VARS_TYPE(longlong, long long, MPI_LONG_LONG_INT)
+BPUT_VARS_TYPE(ulonglong, unsigned long long, MPI_UNSIGNED_LONG_LONG)
+
+/*----< ncmpi_bput_varm() >---------------------------------------------------*/
+int
+ncmpi_bput_varm(int ncid,
+ int varid,
+ const MPI_Offset start[],
+ const MPI_Offset count[],
+ const MPI_Offset stride[],
+ const MPI_Offset imap[],
+ const void *buf,
+ MPI_Offset bufcount,
+ MPI_Datatype buftype,
+ int *reqid)
+{
+ int status;
+ NC *ncp;
+ NC_var *varp=NULL;
+
+ if (reqid != NULL) *reqid = NC_REQ_NULL;
+ status = ncmpii_sanity_check(ncid, varid, start, count, bufcount, API_VARM,
+ 0, 1, WRITE_REQ, NONBLOCKING_IO, &ncp, &varp);
+ if (status != NC_NOERR) return status;
+
+ if (ncp->abuf == NULL) DEBUG_RETURN_ERROR(NC_ENULLABUF)
+
+ return ncmpii_igetput_varm(ncp, varp, start, count, stride, imap,
+ (void*)buf, bufcount, buftype, reqid,
+ WRITE_REQ, 1, 0);
+}
+
+dnl
+dnl BPUT_VARM_TYPE(ncid, varid, start, count, stride, imap, op, reqid)
+dnl
+define(`BPUT_VARM_TYPE',dnl
+`dnl
+/*----< ncmpi_bput_varm_$1() >------------------------------------------------*/
+int
+ncmpi_bput_varm_$1(int ncid,
+ int varid,
+ const MPI_Offset start[],
+ const MPI_Offset count[],
+ const MPI_Offset stride[],
+ const MPI_Offset imap[],
+ const $2 *op,
+ int *reqid)
+{
+ int status;
+ NC *ncp;
+ NC_var *varp=NULL;
+
+ if (reqid != NULL) *reqid = NC_REQ_NULL;
+ status = ncmpii_sanity_check(ncid, varid, start, count, 0, API_VARM,
+ 0, 0, WRITE_REQ, NONBLOCKING_IO, &ncp, &varp);
+ if (status != NC_NOERR) return status;
+
+ if (ncp->abuf == NULL) DEBUG_RETURN_ERROR(NC_ENULLABUF)
+
+ return ncmpii_igetput_varm(ncp, varp, start, count, stride, imap,
+ (void*)op, -1, $3, reqid, WRITE_REQ, 1, 0);
+}
+')dnl
+
+BPUT_VARM_TYPE(text, char, MPI_CHAR)
+BPUT_VARM_TYPE(schar, schar, MPI_SIGNED_CHAR)
+BPUT_VARM_TYPE(uchar, uchar, MPI_UNSIGNED_CHAR)
+BPUT_VARM_TYPE(short, short, MPI_SHORT)
+BPUT_VARM_TYPE(ushort, ushort, MPI_UNSIGNED_SHORT)
+BPUT_VARM_TYPE(int, int, MPI_INT)
+BPUT_VARM_TYPE(uint, uint, MPI_UNSIGNED)
+BPUT_VARM_TYPE(long, long, MPI_LONG)
+BPUT_VARM_TYPE(float, float, MPI_FLOAT)
+BPUT_VARM_TYPE(double, double, MPI_DOUBLE)
+BPUT_VARM_TYPE(longlong, long long, MPI_LONG_LONG_INT)
+BPUT_VARM_TYPE(ulonglong, unsigned long long, MPI_UNSIGNED_LONG_LONG)
+
+
+/*----< ncmpi_buffer_attach() >-----------------------------------------------*/
+int
+ncmpi_buffer_attach(int ncid,
+ MPI_Offset bufsize)
+{
+ int status;
+ NC *ncp;
+
+ if (bufsize <= 0) DEBUG_RETURN_ERROR(NC_ENULLBUF)
+
+ status = ncmpii_NC_check_id(ncid, &ncp);
+ if (status != NC_NOERR) return status;
+
+ /* check if the buffer has been previously attached
+ * note that in nc.c, the NC object is allocated with calloc, so
+ * abuf should be initialized to NULL then
+ */
+ if (ncp->abuf != NULL) DEBUG_RETURN_ERROR(NC_EPREVATTACHBUF)
+
+ ncp->abuf = (NC_buf*) NCI_Malloc(sizeof(NC_buf));
+
+ ncp->abuf->size_allocated = bufsize;
+ ncp->abuf->size_used = 0;
+ ncp->abuf->table_size = NC_ABUF_DEFAULT_TABLE_SIZE;
+ ncp->abuf->occupy_table = (NC_buf_status*)
+ NCI_Calloc(NC_ABUF_DEFAULT_TABLE_SIZE, sizeof(NC_buf_status));
+ ncp->abuf->tail = 0;
+ ncp->abuf->buf = NCI_Malloc((size_t)bufsize);
+ return NC_NOERR;
+}
+
+/*----< ncmpi_buffer_detach() >-----------------------------------------------*/
+int
+ncmpi_buffer_detach(int ncid)
+{
+ int status;
+ NC *ncp;
+ NC_req *cur_req;
+
+ status = ncmpii_NC_check_id(ncid, &ncp);
+ if (status != NC_NOERR) return status;
+
+ /* check if the buffer has been previously attached */
+ if (ncp->abuf == NULL) DEBUG_RETURN_ERROR(NC_ENULLABUF)
+
+ /* this API assumes users are responsible for no pending bput */
+ cur_req = ncp->head;
+ while (cur_req != NULL) { /* check if there is a pending bput */
+ if (cur_req->abuf_index >= 0)
+ DEBUG_RETURN_ERROR(NC_EPENDINGBPUT)
+ /* return now, so users can call wait and try detach again */
+ cur_req = cur_req->next;
+ }
+
+ NCI_Free(ncp->abuf->buf);
+ NCI_Free(ncp->abuf->occupy_table);
+ NCI_Free(ncp->abuf);
+ ncp->abuf = NULL;
+
+ return NC_NOERR;
+}
+
+#ifdef THIS_SEEMS_OVER_DONE_IT
+/*----< ncmpi_buffer_detach() >-----------------------------------------------*/
+/* mimic MPI_Buffer_detach()
+ * Note from MPI: Even though the 'bufferptr' argument is declared as
+ * 'void *', it is really the address of a void pointer.
+ */
+int
+ncmpi_buffer_detach(int ncid,
+ void *bufptr,
+ MPI_Offset *bufsize)
+{
+ int status;
+ NC *ncp;
+ NC_req *cur_req;
+
+ status = ncmpii_NC_check_id(ncid, &ncp);
+ if (status != NC_NOERR) return status;
+
+ /* check if the buffer has been previously attached */
+ if (ncp->abuf == NULL) DEBUG_RETURN_ERROR(NC_ENULLABUF)
+
+ /* check MPICH2 src/mpi/pt2pt/bsendutil.c for why the bufptr is void* */
+ *(void **)bufptr = ncp->abuf->buf;
+ *bufsize = ncp->abuf->size_allocated;
+
+ /* this API assumes users are responsible for no pending bput when called */
+ cur_req = ncp->head;
+ while (cur_req != NULL) { /* check if there is a pending bput */
+ if (cur_req->abuf_index >= 0)
+ DEBUG_RETURN_ERROR(NC_EPENDINGBPUT)
+ cur_req = cur_req->next;
+ }
+
+ NCI_Free(ncp->abuf->occupy_table);
+ NCI_Free(ncp->abuf);
+ ncp->abuf = NULL;
+
+ return NC_NOERR;
+}
+#endif
+
+
+/*----< ncmpi_inq_buffer_usage() >--------------------------------------------*/
+int
+ncmpi_inq_buffer_usage(int ncid,
+ MPI_Offset *usage) /* OUT: in bytes */
+{
+ int status;
+ NC *ncp;
+
+ status = ncmpii_NC_check_id(ncid, &ncp);
+ if (status != NC_NOERR) return status;
+
+ /* check if the buffer has been previously attached */
+ if (ncp->abuf == NULL) DEBUG_RETURN_ERROR(NC_ENULLABUF)
+
+ /* return the current usage in bytes */
+ *usage = ncp->abuf->size_used;
+
+ return NC_NOERR;
+}
+
+/*----< ncmpi_inq_buffer_size() >---------------------------------------------*/
+int
+ncmpi_inq_buffer_size(int ncid,
+ MPI_Offset *buf_size) /* OUT: in bytes */
+{
+ int status;
+ NC *ncp;
+
+ status = ncmpii_NC_check_id(ncid, &ncp);
+ if (status != NC_NOERR) return status;
+
+ /* check if the buffer has been previously attached */
+ if (ncp->abuf == NULL) DEBUG_RETURN_ERROR(NC_ENULLABUF)
+
+ /* return the current usage in bytes */
+ *buf_size = ncp->abuf->size_allocated;
+
+ return NC_NOERR;
+}
+
diff --git a/src/lib/convert_swap.m4 b/src/lib/convert_swap.m4
new file mode 100644
index 0000000..25792f1
--- /dev/null
+++ b/src/lib/convert_swap.m4
@@ -0,0 +1,311 @@
+dnl Process this m4 file to produce 'C' language file.
+dnl
+dnl If you see this line, you can ignore the next one.
+/* Do not edit this file. It is produced from the corresponding .m4 source */
+dnl
+/*
+ * Copyright (C) 2014, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ */
+/* $Id: convert_swap.m4 2290 2016-01-02 18:37:46Z wkliao $ */
+
+#if HAVE_CONFIG_H
+# include "ncconfig.h"
+#endif
+
+#include <stdio.h>
+#include <unistd.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#include <assert.h>
+#include <arpa/inet.h> /* htonl(), htons() */
+
+#include <mpi.h>
+
+#include "nc.h"
+#include "ncx.h"
+#include "macro.h"
+
+/* Prototypes for functions used only in this file */
+#if 0
+static void swapn(void *dst, const void *src, MPI_Offset nn, int xsize);
+#endif
+
+/*
+ * Datatype Mapping:
+ *
+ * NETCDF <--> MPI Description
+ * NC_BYTE MPI_SIGNED_CHAR signed 1-byte integer
+ * NC_CHAR MPI_CHAR char, text (cannot convert to other types)
+ * NC_SHORT MPI_SHORT signed 2-byte integer
+ * NC_INT MPI_INT signed 4-byte integer
+ * NC_FLOAT MPI_FLOAT single precision floating point
+ * NC_DOUBLE MPI_DOUBLE double precision floating point
+ * NC_UBYTE MPI_UNSIGNED_CHAR unsigned 1-byte int
+ * NC_USHORT MPI_UNSIGNED_SHORT unsigned 2-byte int
+ * NC_UINT MPI_UNSIGNED unsigned 4-byte int
+ * NC_INT64 MPI_LONG_LONG_INT signed 8-byte int
+ * NC_UINT64 MPI_UNSIGNED_LONG_LONG unsigned 8-byte int
+ *
+ * Assume: MPI_Datatype and nc_type are both enumerable types
+ * (this might not conform with MPI, as MPI_Datatype is intended to be
+ * an opaque data type.)
+ *
+ * In OpenMPI, this assumption will fail
+ */
+
+inline MPI_Datatype
+ncmpii_nc2mpitype(nc_type type)
+{
+ switch(type){
+ case NC_BYTE : return MPI_SIGNED_CHAR;
+ case NC_CHAR : return MPI_CHAR;
+ case NC_SHORT : return MPI_SHORT;
+ case NC_INT : return MPI_INT;
+ case NC_FLOAT : return MPI_FLOAT;
+ case NC_DOUBLE : return MPI_DOUBLE;
+ case NC_UBYTE : return MPI_UNSIGNED_CHAR;
+ case NC_USHORT : return MPI_UNSIGNED_SHORT;
+ case NC_UINT : return MPI_UNSIGNED;
+ case NC_INT64 : return MPI_LONG_LONG_INT;
+ case NC_UINT64 : return MPI_UNSIGNED_LONG_LONG;
+ default: return MPI_DATATYPE_NULL;
+ }
+}
+
+/*----< ncmpii_need_convert() >----------------------------------------------*/
+/* netCDF specification make a special case for type conversion between
+ * uchar and scahr: do not check for range error. See
+ * http://www.unidata.ucar.edu/software/netcdf/docs_rc/data_type.html#type_conversion
+ */
+inline int
+ncmpii_need_convert(nc_type nctype,MPI_Datatype mpitype) {
+ return !( (nctype == NC_CHAR && mpitype == MPI_CHAR) ||
+ (nctype == NC_BYTE && mpitype == MPI_SIGNED_CHAR) ||
+ (nctype == NC_BYTE && mpitype == MPI_UNSIGNED_CHAR) ||
+#if defined(__CHAR_UNSIGNED__) && __CHAR_UNSIGNED__ != 0
+ (nctype == NC_BYTE && mpitype == MPI_CHAR) ||
+#endif
+ (nctype == NC_SHORT && mpitype == MPI_SHORT) ||
+ (nctype == NC_INT && mpitype == MPI_INT) ||
+ (nctype == NC_INT && mpitype == MPI_LONG &&
+ X_SIZEOF_INT == SIZEOF_LONG) ||
+ (nctype == NC_FLOAT && mpitype == MPI_FLOAT) ||
+ (nctype == NC_DOUBLE && mpitype == MPI_DOUBLE) ||
+ (nctype == NC_UBYTE && mpitype == MPI_UNSIGNED_CHAR) ||
+ (nctype == NC_USHORT && mpitype == MPI_UNSIGNED_SHORT) ||
+ (nctype == NC_UINT && mpitype == MPI_UNSIGNED) ||
+ (nctype == NC_INT64 && mpitype == MPI_LONG_LONG_INT) ||
+ (nctype == NC_UINT64 && mpitype == MPI_UNSIGNED_LONG_LONG)
+ );
+}
+
+/*----< ncmpii_need_swap() >-------------------------------------------------*/
+inline int
+ncmpii_need_swap(nc_type nctype,
+ MPI_Datatype mpitype)
+{
+#ifdef WORDS_BIGENDIAN
+ return 0;
+#else
+ if ((nctype == NC_CHAR && mpitype == MPI_CHAR) ||
+ (nctype == NC_BYTE && mpitype == MPI_SIGNED_CHAR) ||
+ (nctype == NC_UBYTE && mpitype == MPI_UNSIGNED_CHAR))
+ return 0;
+
+ return 1;
+#endif
+}
+
+#if 0
+/*----< swapn() >------------------------------------------------------------*/
+inline static void
+swapn(void *dst,
+ const void *src,
+ MPI_Offset nn,
+ int xsize)
+{
+ int i;
+ uchar *op = dst;
+ const uchar *ip = src;
+ while (nn-- != 0) {
+ for (i=0; i<xsize; i++)
+ op[i] = ip[xsize-1-i];
+ op += xsize;
+ ip += xsize;
+ }
+}
+#endif
+
+/* Endianness byte swap: done in-place */
+#define SWAP(x,y) {tmp = (x); (x) = (y); (y) = tmp;}
+
+/*----< ncmpii_swap() >-------------------------------------------------------*/
+void
+ncmpii_swapn(void *dest_p, /* destination array */
+ const void *src_p, /* source array */
+ MPI_Offset nelems, /* number of elements in buf[] */
+ int esize) /* byte size of each element */
+{
+ int i;
+
+ if (esize <= 1 || nelems <= 0) return; /* no need */
+
+ if (esize == 4) { /* this is the most common case */
+ uint32_t *dest = (uint32_t*) dest_p;
+ const uint32_t *src = (const uint32_t*) src_p;
+ for (i=0; i<nelems; i++)
+ dest[i] = htonl(src[i]);
+ }
+ else if (esize == 2) {
+ uint16_t *dest = (uint16_t*) dest_p;
+ const uint16_t *src = (const uint16_t*) src_p;
+ for (i=0; i<nelems; i++)
+ dest[i] = htons(src[i]);
+ }
+ else {
+ uchar *op = (uchar*) dest_p;
+ const uchar *ip = (uchar*) src_p;
+ /* for esize is not 1, 2, or 4 */
+ while (nelems-- > 0) {
+ for (i=0; i<esize; i++)
+ op[i] = ip[esize-1-i];
+ op += esize;
+ ip += esize;
+ }
+ }
+}
+
+/*----< ncmpii_in_swap() >---------------------------------------------------*/
+void
+ncmpii_in_swapn(void *buf,
+ MPI_Offset nelems, /* number of elements in buf[] */
+ int esize) /* byte size of each element */
+{
+ int i;
+ uchar tmp, *op = (uchar*)buf;
+
+ if (esize <= 1 || nelems <= 0) return; /* no need */
+
+ if (esize == 4) { /* this is the most common case */
+ uint32_t *dest = (uint32_t*) buf;
+ for (i=0; i<nelems; i++)
+ dest[i] = htonl(dest[i]);
+ }
+ else if (esize == 2) {
+ uint16_t *dest = (uint16_t*) buf;
+ for (i=0; i<nelems; i++)
+ dest[i] = htons(dest[i]);
+ }
+ else {
+ /* for esize is not 1, 2, or 4 */
+ while (nelems-- > 0) {
+ for (i=0; i<esize/2; i++)
+ SWAP(op[i], op[esize-1-i])
+ op += esize;
+ }
+ }
+}
+
+
+dnl
+dnl X_PUTN_FILETYPE(xtype)
+dnl
+define(`X_PUTN_FILETYPE',dnl
+`dnl
+/*----< ncmpii_x_putn_$1() >--------------------------------------------------*/
+inline int
+ncmpii_x_putn_$1(void *xp, /* file buffer of type schar */
+ const void *putbuf, /* put buffer of type puttype */
+ MPI_Offset nelems,
+ MPI_Datatype puttype)
+{
+ if (puttype == MPI_CHAR || /* assume ECHAR has been checked before */
+ puttype == MPI_SIGNED_CHAR)
+ return ncmpix_putn_$1_schar (&xp, nelems, (const schar*) putbuf);
+ else if (puttype == MPI_UNSIGNED_CHAR)
+ return ncmpix_putn_$1_uchar (&xp, nelems, (const uchar*) putbuf);
+ else if (puttype == MPI_SHORT)
+ return ncmpix_putn_$1_short (&xp, nelems, (const short*) putbuf);
+ else if (puttype == MPI_UNSIGNED_SHORT)
+ return ncmpix_putn_$1_ushort (&xp, nelems, (const ushort*) putbuf);
+ else if (puttype == MPI_INT)
+ return ncmpix_putn_$1_int (&xp, nelems, (const int*) putbuf);
+ else if (puttype == MPI_UNSIGNED)
+ return ncmpix_putn_$1_uint (&xp, nelems, (const uint*) putbuf);
+ else if (puttype == MPI_LONG)
+ return ncmpix_putn_$1_long (&xp, nelems, (const long*) putbuf);
+ else if (puttype == MPI_FLOAT)
+ return ncmpix_putn_$1_float (&xp, nelems, (const float*) putbuf);
+ else if (puttype == MPI_DOUBLE)
+ return ncmpix_putn_$1_double (&xp, nelems, (const double*) putbuf);
+ else if (puttype == MPI_LONG_LONG_INT)
+ return ncmpix_putn_$1_longlong (&xp, nelems, (const longlong*) putbuf);
+ else if (puttype == MPI_UNSIGNED_LONG_LONG)
+ return ncmpix_putn_$1_ulonglong(&xp, nelems, (const ulonglong*) putbuf);
+ DEBUG_RETURN_ERROR(NC_EBADTYPE)
+}
+')dnl
+
+X_PUTN_FILETYPE(schar)
+X_PUTN_FILETYPE(uchar)
+X_PUTN_FILETYPE(short)
+X_PUTN_FILETYPE(ushort)
+X_PUTN_FILETYPE(int)
+X_PUTN_FILETYPE(uint)
+X_PUTN_FILETYPE(float)
+X_PUTN_FILETYPE(double)
+X_PUTN_FILETYPE(int64)
+X_PUTN_FILETYPE(uint64)
+
+dnl
+dnl X_GETN_FILETYPE(xtype)
+dnl
+define(`X_GETN_FILETYPE',dnl
+`dnl
+/*----< ncmpii_x_getn_$1() >-------------------------------------------------*/
+inline int
+ncmpii_x_getn_$1(const void *xp, /* file buffer of type schar */
+ void *getbuf, /* get buffer of type gettype */
+ MPI_Offset nelems,
+ MPI_Datatype gettype)
+{
+ if (gettype == MPI_CHAR || /* assume ECHAR has been checked before */
+ gettype == MPI_SIGNED_CHAR)
+ return ncmpix_getn_$1_schar (&xp, nelems, (schar*) getbuf);
+ else if (gettype == MPI_UNSIGNED_CHAR)
+ return ncmpix_getn_$1_uchar (&xp, nelems, (uchar*) getbuf);
+ else if (gettype == MPI_SHORT)
+ return ncmpix_getn_$1_short (&xp, nelems, (short*) getbuf);
+ else if (gettype == MPI_UNSIGNED_SHORT)
+ return ncmpix_getn_$1_ushort (&xp, nelems, (ushort*) getbuf);
+ else if (gettype == MPI_INT)
+ return ncmpix_getn_$1_int (&xp, nelems, (int*) getbuf);
+ else if (gettype == MPI_UNSIGNED)
+ return ncmpix_getn_$1_uint (&xp, nelems, (uint*) getbuf);
+ else if (gettype == MPI_LONG)
+ return ncmpix_getn_$1_long (&xp, nelems, (long*) getbuf);
+ else if (gettype == MPI_FLOAT)
+ return ncmpix_getn_$1_float (&xp, nelems, (float*) getbuf);
+ else if (gettype == MPI_DOUBLE)
+ return ncmpix_getn_$1_double (&xp, nelems, (double*) getbuf);
+ else if (gettype == MPI_LONG_LONG_INT)
+ return ncmpix_getn_$1_longlong (&xp, nelems, (longlong*) getbuf);
+ else if (gettype == MPI_UNSIGNED_LONG_LONG)
+ return ncmpix_getn_$1_ulonglong(&xp, nelems, (ulonglong*) getbuf);
+ DEBUG_RETURN_ERROR(NC_EBADTYPE)
+}
+')dnl
+
+X_GETN_FILETYPE(schar)
+X_GETN_FILETYPE(uchar)
+X_GETN_FILETYPE(short)
+X_GETN_FILETYPE(ushort)
+X_GETN_FILETYPE(int)
+X_GETN_FILETYPE(uint)
+X_GETN_FILETYPE(float)
+X_GETN_FILETYPE(double)
+X_GETN_FILETYPE(int64)
+X_GETN_FILETYPE(uint64)
+
diff --git a/src/lib/depend b/src/lib/depend
new file mode 100644
index 0000000..d07d4da
--- /dev/null
+++ b/src/lib/depend
@@ -0,0 +1,31 @@
+#
+# generated from command "gcc -MM file.c"
+#
+mpinetcdf.o: mpinetcdf.c ncconfig.h nc.h pnetcdf.h ncio.h fbits.h ncx.h rnd.h nctypes.h macro.h
+header.o: header.c ncconfig.h nc.h pnetcdf.h ncio.h fbits.h ncx.h rnd.h nctypes.h macro.h
+mpincio.o: mpincio.c ncconfig.h nc.h pnetcdf.h ncio.h fbits.h rnd.h macro.h
+attr.o: attr.c ncconfig.h nc.h pnetcdf.h ncio.h fbits.h ncx.h rnd.h nctypes.h macro.h
+dim.o: dim.c ncconfig.h nc.h pnetcdf.h ncio.h fbits.h ncx.h rnd.h nctypes.h macro.h
+error.o: error.c ncconfig.h nc.h pnetcdf.h ncio.h fbits.h
+nc.o: nc.c ncconfig.h nc.h pnetcdf.h ncio.h fbits.h rnd.h ncx.h nctypes.h macro.h
+ncx.o: ncx.c ncconfig.h nc.h pnetcdf.h ncio.h fbits.h ncx.h rnd.h nctypes.h macro.h
+string.o: string.c ncconfig.h nc.h pnetcdf.h ncio.h fbits.h ncx.h rnd.h nctypes.h macro.h utf8proc.h
+var.o: var.c ncconfig.h nc.h pnetcdf.h ncio.h fbits.h ncx.h rnd.h nctypes.h macro.h
+ncmpidtype.o: ncmpidtype.c ncconfig.h nc.h pnetcdf.h ncio.h fbits.h ncmpidtype.h macro.h
+convert_swap.o: convert_swap.c ncconfig.h nc.h pnetcdf.h ncio.h fbits.h ncx.h rnd.h nctypes.h macro.h
+filetype.o: filetype.c ncconfig.h nc.h pnetcdf.h ncio.h fbits.h ncx.h rnd.h nctypes.h macro.h
+m_getput_varx.o: m_getput_varx.c ncconfig.h nc.h pnetcdf.h ncio.h fbits.h ncx.h rnd.h nctypes.h ncmpidtype.h macro.h
+varn.o: varn.c ncconfig.h nc.h pnetcdf.h ncio.h fbits.h ncx.h rnd.h nctypes.h ncmpidtype.h macro.h
+i_varn.o: i_varn.c ncconfig.h nc.h pnetcdf.h ncio.h fbits.h ncx.h rnd.h nctypes.h ncmpidtype.h macro.h
+nonblocking.o: nonblocking.c ncconfig.h nc.h pnetcdf.h ncio.h fbits.h ncx.h rnd.h nctypes.h ncmpidtype.h macro.h
+malloc.o: malloc.c ncconfig.h nc.h
+utf8proc.o: utf8proc.c ncconfig.h utf8proc.h utf8proc_data.h
+ncx.o: ncx.c ncconfig.h nc.h pnetcdf.h ncx.h
+swap.o: swap.c ncconfig.h ncx.h rnd.h nctypes.h pnetcdf.h
+bput.o: bput.c ncconfig.h nc.h pnetcdf.h ncio.h fbits.h ncx.h rnd.h nctypes.h ncmpidtype.h macro.h
+getput.o: getput.c ncconfig.h nc.h pnetcdf.h ncio.h fbits.h ncx.h rnd.h nctypes.h ncmpidtype.h macro.h
+i_getput.o: i_getput.c ncconfig.h nc.h pnetcdf.h ncio.h fbits.h ncx.h rnd.h nctypes.h ncmpidtype.h macro.h
+subfile.o: subfile.c ncconfig.h subfile.h pnetcdf.h nc.h ncio.h fbits.h macro.h ncmpidtype.h
+vard.o: vard.c ncconfig.h pnetcdf.h nc.h ncio.h fbits.h rnd.h ncx.h nctypes.h macro.h ncmpidtype.h
+fill.o: fill.c nc.h ncio.h pnetcdf.h fbits.h macro.h
+util.o: util.c nc.h ncio.h pnetcdf.h fbits.h macro.h
diff --git a/src/lib/dim.c b/src/lib/dim.c
new file mode 100644
index 0000000..792f290
--- /dev/null
+++ b/src/lib/dim.c
@@ -0,0 +1,525 @@
+/*
+ * Copyright (C) 2003, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ */
+/* $Id: dim.c 2302 2016-01-10 20:33:45Z wkliao $ */
+
+#if HAVE_CONFIG_H
+# include "ncconfig.h"
+#endif
+
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+
+#include <mpi.h>
+
+#include "nc.h"
+#include "ncx.h"
+#include "fbits.h"
+#include "macro.h"
+#include "utf8proc.h"
+
+/*
+ * Free dim
+ * Formerly
+NC_free_dim(dim)
+ */
+inline void
+ncmpii_free_NC_dim(NC_dim *dimp)
+{
+ if (dimp == NULL) return;
+ ncmpii_free_NC_string(dimp->name);
+ NCI_Free(dimp);
+}
+
+
+/* allocate and return a new NC_dim object */
+inline NC_dim *
+ncmpii_new_x_NC_dim(NC_string *name)
+{
+ NC_dim *dimp;
+
+ dimp = (NC_dim *) NCI_Malloc(sizeof(NC_dim));
+ if (dimp == NULL) return NULL;
+
+ dimp->name = name;
+ dimp->size = 0;
+
+ return(dimp);
+}
+
+/*----< ncmpii_new_NC_dim() >------------------------------------------------*/
+/*
+ * Formerly, NC_new_dim(const char *name, long size)
+ */
+static NC_dim *
+ncmpii_new_NC_dim(const char *uname, /* dimension name */
+ MPI_Offset size)
+{
+ NC_string *strp;
+ NC_dim *dimp;
+
+ char *name = (char *)utf8proc_NFC((const unsigned char *)uname);
+ if (name == NULL) return NULL;
+
+ strp = ncmpii_new_NC_string(strlen(name), name);
+ free(name);
+ if (strp == NULL) return NULL;
+
+ dimp = ncmpii_new_x_NC_dim(strp);
+ if (dimp == NULL) {
+ ncmpii_free_NC_string(strp);
+ return NULL;
+ }
+
+ dimp->size = size;
+
+ return(dimp);
+}
+
+
+NC_dim *
+dup_NC_dim(const NC_dim *dimp)
+{
+ return ncmpii_new_NC_dim(dimp->name->cp, dimp->size);
+}
+
+/*----< ncmpii_find_NC_Udim() >----------------------------------------------*/
+/*
+ * Step thru NC_DIMENSION array, seeking the UNLIMITED dimension.
+ * Return dimid or -1 on not found.
+ * *dimpp is set to the appropriate NC_dim.
+ */
+int
+ncmpii_find_NC_Udim(const NC_dimarray *ncap,
+ NC_dim **dimpp)
+{
+ int dimid;
+
+ assert(ncap != NULL);
+
+ if (ncap->ndefined == 0) return -1;
+
+ /* note that the number of dimensions allowed is < 2^32 */
+ for (dimid=0; dimid<ncap->ndefined; dimid++)
+ if (ncap->value[dimid]->size == NC_UNLIMITED) {
+ /* found the matched name */
+ if (dimpp != NULL)
+ *dimpp = ncap->value[dimid];
+ return dimid;
+ }
+
+ /* not found */
+ return -1;
+}
+
+/*----< NC_finddim() >-------------------------------------------------------*/
+/*
+ * Step thru NC_DIMENSION array, seeking match on name.
+ * Return dimid or -1 on not found.
+ * *dimpp is set to the appropriate NC_dim.
+ */
+static int
+NC_finddim(const NC_dimarray *ncap,
+ const char *uname,
+ NC_dim **dimpp)
+{
+ int dimid;
+ size_t nchars;
+
+ assert(ncap != NULL);
+
+ if (ncap->ndefined == 0) return -1;
+
+ char *name = (char *)utf8proc_NFC((const unsigned char *)uname);
+ nchars = strlen(name);
+
+ /* note that the number of dimensions allowed is < 2^32 */
+ for (dimid=0; dimid<ncap->ndefined; dimid++) {
+ if (ncap->value[dimid]->name->nchars == nchars &&
+ strncmp(ncap->value[dimid]->name->cp, name, nchars) == 0) {
+ /* found the matched name */
+ if (dimpp != NULL)
+ *dimpp = ncap->value[dimid];
+ free(name);
+ return dimid;
+ }
+ }
+ free(name);
+
+ /* the name is not found */
+ return -1;
+}
+
+
+/* dimarray */
+
+
+/*----< ncmpii_free_NC_dimarray() >------------------------------------------*/
+/*
+ * Free NC_dimarray values.
+ * formerly
+NC_free_array()
+ */
+inline void
+ncmpii_free_NC_dimarray(NC_dimarray *ncap)
+{
+ int i;
+
+ assert(ncap != NULL);
+ if (ncap->nalloc == 0) return;
+
+ assert(ncap->value != NULL);
+ for (i=0; i<ncap->ndefined; i++)
+ ncmpii_free_NC_dim(ncap->value[i]);
+
+ NCI_Free(ncap->value);
+ ncap->value = NULL;
+ ncap->nalloc = 0;
+ ncap->ndefined = 0;
+}
+
+
+/*----< ncmpii_dup_NC_dimarray() >-------------------------------------------*/
+int
+ncmpii_dup_NC_dimarray(NC_dimarray *ncap, const NC_dimarray *ref)
+{
+ int i, status=NC_NOERR;
+
+ assert(ref != NULL);
+ assert(ncap != NULL);
+
+ if (ref->nalloc == 0) {
+ ncap->nalloc = 0;
+ ncap->ndefined = 0;
+ ncap->value = NULL;
+ return NC_NOERR;
+ }
+
+ if (ref->nalloc > 0) {
+ ncap->value = (NC_dim **) NCI_Calloc((size_t)ref->nalloc, sizeof(NC_dim *));
+ if (ncap->value == NULL) DEBUG_RETURN_ERROR(NC_ENOMEM)
+ ncap->nalloc = ref->nalloc;
+ }
+
+ ncap->ndefined = 0;
+ for (i=0; i<ref->ndefined; i++) {
+ ncap->value[i] = dup_NC_dim(ref->value[i]);
+ if (ncap->value[i] == NULL) {
+ DEBUG_ASSIGN_ERROR(status, NC_ENOMEM)
+ break;
+ }
+ }
+
+ if (status != NC_NOERR) {
+ ncmpii_free_NC_dimarray(ncap);
+ return status;
+ }
+
+ ncap->ndefined = ref->ndefined;
+
+ return NC_NOERR;
+}
+
+
+/*----< incr_NC_dimarray() >---------------------------------------------- --*/
+/*
+ * Add a new handle to the end of an array of handles
+ * Formerly, NC_incr_array(array, tail)
+ */
+int
+incr_NC_dimarray(NC_dimarray *ncap,
+ NC_dim *newdimp)
+{
+ NC_dim **vp;
+
+ assert(ncap != NULL);
+
+ if (ncap->nalloc == 0) {
+ assert(ncap->ndefined == 0);
+ vp = (NC_dim **) NCI_Malloc(NC_ARRAY_GROWBY * sizeof(NC_dim *));
+ if (vp == NULL) DEBUG_RETURN_ERROR(NC_ENOMEM)
+
+ ncap->value = vp;
+ ncap->nalloc = NC_ARRAY_GROWBY;
+ }
+ else if (ncap->ndefined + 1 > ncap->nalloc) {
+ vp = (NC_dim **) NCI_Realloc(ncap->value,
+ (size_t)(ncap->nalloc + NC_ARRAY_GROWBY) * sizeof(NC_dim *));
+ if (vp == NULL) DEBUG_RETURN_ERROR(NC_ENOMEM)
+
+ ncap->value = vp;
+ ncap->nalloc += NC_ARRAY_GROWBY;
+ }
+ /* else here means some space still available */
+
+ if (newdimp != NULL) {
+ ncap->value[ncap->ndefined] = newdimp;
+ ncap->ndefined++;
+ }
+
+ return NC_NOERR;
+}
+
+
+/*----< ncmpii_elem_NC_dimarray() >------------------------------------------*/
+inline NC_dim *
+ncmpii_elem_NC_dimarray(const NC_dimarray *ncap,
+ int dimid)
+{
+ /* returns the dimension ID defined earlier */
+ assert(ncap != NULL);
+
+ if (dimid < 0 || ncap->ndefined == 0 || dimid >= ncap->ndefined)
+ return NULL;
+
+ assert(ncap->value != NULL);
+
+ return ncap->value[dimid];
+}
+
+
+/* Public */
+
+/*----< ncmpi_def_dim() >----------------------------------------------------*/
+int
+ncmpi_def_dim(int ncid, /* IN: file ID */
+ const char *name, /* IN: name of dimension */
+ MPI_Offset size, /* IN: dimension size */
+ int *dimidp) /* OUT: dimension ID */
+{
+ int dimid, file_ver, status;
+ NC *ncp;
+ NC_dim *dimp;
+
+ /* check if ncid is valid */
+ status = ncmpii_NC_check_id(ncid, &ncp);
+ if (status != NC_NOERR) return status;
+
+ /* check if called in define mode */
+ if (!NC_indef(ncp)) DEBUG_RETURN_ERROR(NC_ENOTINDEFINE)
+
+ /* check if the name string is legal for netcdf format */
+ file_ver = 1;
+ if (fIsSet(ncp->flags, NC_64BIT_OFFSET))
+ file_ver = 2;
+ else if (fIsSet(ncp->flags, NC_64BIT_DATA))
+ file_ver = 5;
+
+ status = ncmpii_NC_check_name(name, file_ver);
+ if (status != NC_NOERR) return status;
+
+ /* MPI_Offset is usually a signed value, but serial netcdf uses
+ * size_t -- normally unsigned
+ * In 1999 ISO C standard, size_t is a unsigned integer type of at least
+ * 16 bit. */
+ if ((ncp->flags & NC_64BIT_OFFSET) && SIZEOF_OFF_T > 4) {
+ /* CDF2 format and LFS, max is 2^32-4 */
+ if (size > X_UINT_MAX - 3 || (size < 0))
+ /* "-3" handles rounded-up size */
+ DEBUG_RETURN_ERROR(NC_EDIMSIZE)
+ } else if ((ncp->flags & NC_64BIT_DATA)) {
+ /* CDF5 format*/
+ if (size < 0)
+ DEBUG_RETURN_ERROR(NC_EDIMSIZE)
+ } else {
+ /* CDF1 format, max is 2^31-4 */
+ if (size > X_INT_MAX - 3 || (size < 0))
+ /* "-3" handles rounded-up size */
+ DEBUG_RETURN_ERROR(NC_EDIMSIZE)
+ }
+
+ if (size == NC_UNLIMITED) {
+ /* check for any existing unlimited dimension, netcdf allows
+ * one per file
+ */
+ dimid = ncmpii_find_NC_Udim(&ncp->dims, &dimp);
+ if (dimid != -1) DEBUG_RETURN_ERROR(NC_EUNLIMIT) /* found an existing one */
+ }
+
+ /* check if exceeds the upperbound has reached */
+ if (ncp->dims.ndefined >= NC_MAX_DIMS) DEBUG_RETURN_ERROR(NC_EMAXDIMS)
+
+ /* check if the name string is previously used */
+ dimid = NC_finddim(&ncp->dims, name, &dimp);
+ if (dimid != -1) DEBUG_RETURN_ERROR(NC_ENAMEINUSE)
+
+ /* create a new dimension object */
+ dimp = ncmpii_new_NC_dim(name, size);
+ if (dimp == NULL) DEBUG_RETURN_ERROR(NC_ENOMEM)
+
+ /* Add a new handle to the end of an array of handles */
+ status = incr_NC_dimarray(&ncp->dims, dimp);
+ if (status != NC_NOERR) {
+ ncmpii_free_NC_dim(dimp);
+ return status;
+ }
+
+ if (dimidp != NULL)
+ *dimidp = (int)ncp->dims.ndefined -1;
+ /* ncp->dims.ndefined has been increased in incr_NC_dimarray() */
+
+ return NC_NOERR;
+}
+
+
+/*----< ncmpi_inq_dimid() >--------------------------------------------------*/
+int
+ncmpi_inq_dimid(int ncid,
+ const char *name,
+ int *dimid_ptr)
+{
+ int status;
+ NC *ncp;
+ int dimid;
+
+ status = ncmpii_NC_check_id(ncid, &ncp);
+ if (status != NC_NOERR) return status;
+
+ dimid = NC_finddim(&ncp->dims, name, NULL);
+ if (dimid == -1) DEBUG_RETURN_ERROR(NC_EBADDIM)
+
+ *dimid_ptr = dimid;
+ return NC_NOERR;
+}
+
+
+/*----< ncmpi_inq_dim() >----------------------------------------------------*/
+int
+ncmpi_inq_dim(int ncid,
+ int dimid,
+ char *name,
+ MPI_Offset *sizep)
+{
+ int status;
+ NC *ncp;
+ NC_dim *dimp;
+
+ status = ncmpii_NC_check_id(ncid, &ncp);
+ if (status != NC_NOERR) return status;
+
+ dimp = ncmpii_elem_NC_dimarray(&ncp->dims, dimid);
+ if (dimp == NULL) DEBUG_RETURN_ERROR(NC_EBADDIM)
+
+ if (name != NULL)
+ /* in PnetCDF, name->cp is always NULL character terminated */
+ strcpy(name, dimp->name->cp);
+
+ if (sizep != NULL) {
+ if (dimp->size == NC_UNLIMITED)
+ *sizep = NC_get_numrecs(ncp);
+ else
+ *sizep = dimp->size;
+ }
+ return NC_NOERR;
+}
+
+
+/*----< ncmpi_inq_dimname() >------------------------------------------------*/
+int
+ncmpi_inq_dimname(int ncid,
+ int dimid,
+ char *name)
+{
+ return ncmpi_inq_dim(ncid, dimid, name, NULL);
+}
+
+
+/*----< ncmpi_inq_dimlen() >-------------------------------------------------*/
+int
+ncmpi_inq_dimlen(int ncid,
+ int dimid,
+ MPI_Offset *lenp)
+{
+ return ncmpi_inq_dim(ncid, dimid, NULL, lenp);
+}
+
+
+/*----< ncmpi_rename_dim() >--------------------------------------------------*/
+/* This API is collective if called in data mode */
+int
+ncmpi_rename_dim(int ncid,
+ int dimid,
+ const char *newname)
+{
+ int file_ver, status, existid, err, mpireturn;
+ NC *ncp;
+ NC_dim *dimp;
+
+ status = ncmpii_NC_check_id(ncid, &ncp);
+ if (status != NC_NOERR) return status;
+
+ if (NC_readonly(ncp)) DEBUG_RETURN_ERROR(NC_EPERM)
+
+ file_ver = 1;
+ if (fIsSet(ncp->flags, NC_64BIT_OFFSET))
+ file_ver = 2;
+ else if (fIsSet(ncp->flags, NC_64BIT_DATA))
+ file_ver = 5;
+
+ status = ncmpii_NC_check_name(newname, file_ver);
+ if (status != NC_NOERR) return status;
+
+ existid = NC_finddim(&ncp->dims, newname, &dimp);
+ if (existid != -1) DEBUG_RETURN_ERROR(NC_ENAMEINUSE)
+
+ dimp = ncmpii_elem_NC_dimarray(&ncp->dims, dimid);
+ if (dimp == NULL) DEBUG_RETURN_ERROR(NC_EBADDIM)
+
+ if (NC_indef(ncp)) {
+ NC_string *newStr = ncmpii_new_NC_string(strlen(newname), newname);
+ if (newStr == NULL) DEBUG_RETURN_ERROR(NC_ENOMEM)
+
+ ncmpii_free_NC_string(dimp->name);
+ dimp->name = newStr;
+ return NC_NOERR;
+ }
+ /* else, not in define mode.
+ * if called in data mode (collective or independent), this function must
+ * be called collectively, i.e. all processes must participate.
+ */
+
+ if (ncp->safe_mode) {
+ int nchars = (int)strlen(newname);
+ TRACE_COMM(MPI_Bcast)(&nchars, 1, MPI_INT, 0, ncp->nciop->comm);
+ if (mpireturn != MPI_SUCCESS)
+ return ncmpii_handle_error(mpireturn, "MPI_Bcast");
+
+ if (nchars != strlen(newname)) {
+ /* newname's length is inconsistent with root's */
+ printf("Warning: dimension name(%s) used in %s() is inconsistent\n",
+ newname, __func__);
+ if (status == NC_NOERR) DEBUG_ASSIGN_ERROR(status, NC_EMULTIDEFINE_DIM_NAME)
+ }
+ }
+
+ /* ncmpii_set_NC_string() will check for strlen(newname) > nchars error */
+ err = ncmpii_set_NC_string(dimp->name, newname);
+ if (status == NC_NOERR) status = err;
+
+ /* PnetCDF expects all processes use the same name, However, when names
+ * are not the same, only root's value is significant. Broadcast the
+ * new name at root to overwrite new names at other processes.
+ * (This API is collective if called in data mode)
+ */
+ TRACE_COMM(MPI_Bcast)(dimp->name->cp, (int)dimp->name->nchars, MPI_CHAR, 0,
+ ncp->nciop->comm);
+ if (mpireturn != MPI_SUCCESS) {
+ err = ncmpii_handle_error(mpireturn, "MPI_Bcast");
+ if (status == NC_NOERR) status = err;
+ }
+
+ /* Let root write the entire header to the file. Note that we cannot just
+ * update the variable name in its space occupied in the file header,
+ * because if the file space occupied by the name shrinks, all the metadata
+ * following it must be moved ahead.
+ */
+ err = ncmpii_write_header(ncp);
+ if (status == NC_NOERR) status = err;
+
+ return status;
+}
diff --git a/src/lib/error.c b/src/lib/error.c
new file mode 100644
index 0000000..e8a8384
--- /dev/null
+++ b/src/lib/error.c
@@ -0,0 +1,761 @@
+/*
+ * Copyright (C) 2003, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ */
+/* $Id: error.c 2282 2015-12-26 17:44:27Z wkliao $ */
+
+/*LINTLIBRARY*/
+
+#if HAVE_CONFIG_H
+# include "ncconfig.h"
+#endif
+
+#include <stdio.h>
+
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
+#include <mpi.h>
+
+#include "nc.h"
+
+#ifdef HAVE_STRERROR
+#include <string.h> /* contains prototype for ansi libc function strerror() */
+#else
+/* provide a strerror function for older unix systems */
+inline static char *
+strerror(int errnum)
+{
+ extern int sys_nerr;
+ extern char *sys_errlist[];
+
+ if(errnum < 0 || errnum >= sys_nerr) return NULL;
+ /* else */
+ return sys_errlist[errnum];
+}
+#endif /* HAVE_STRERROR */
+
+
+#ifdef vms
+/* UNTESTED */
+/*
+ * On the vms system, when a system error occurs which is not
+ * mapped into the unix styled errno values, errno is set EVMSERR
+ * and a VMS error code is set in vaxc$errno.
+ * This routine prints the systems message associated with status return
+ * from a system services call.
+ */
+
+#include <errno.h>
+#include <descrip.h>
+#include <ssdef.h>
+
+static const char *
+vms_strerror( int status )
+{
+ short msglen;
+ static char msgbuf[256];
+ $DESCRIPTOR(message, msgbuf);
+ register ret;
+
+ msgbuf[0] = 0;
+ ret = SYS$GETMSG(status, &msglen, &message, 15, 0);
+
+ if(ret != SS$_BUFFEROVF && ret != SS$_NORMAL) {
+ (void) strcpy(msgbuf, "EVMSERR");
+ }
+ return(msgbuf);
+}
+#endif /* vms */
+
+
+/* must copy nc_strerror() from netCDF release */
+static const char* nc_strerror(int ncerr1);
+
+static char nc_unknown_err_msg[128];
+
+const char *
+ncmpi_strerror(int err)
+{
+ sprintf(nc_unknown_err_msg,"Unknown Error: Unrecognized error code %5d\n",err);
+
+#ifdef vms
+ if(err == EVMSERR)
+ {
+ return vms_strerror(err);
+ }
+ /* else */
+#endif /* vms */
+
+ if(NC_ISSYSERR(err))
+ {
+ const char *cp = (const char *) strerror(err);
+ if(cp == NULL)
+ return nc_unknown_err_msg;
+ /* else */
+ return cp;
+ }
+ /* else */
+
+ switch (err) {
+ /* PnetCDF errors */
+ case NC_ESMALL:
+ return "Size of MPI_Offset or MPI_Aint too small for requested format";
+ /* this usually happens on 32-bit machines where MPI_Offset and
+ * MPI_Aint may be 4-byte integers and when the I/O request amount
+ * or accessing file offset is > 2GB.
+ */
+ case NC_ENOTINDEP:
+ return "Operation not allowed in collective data mode";
+ /* this means your program is now in independent data mode, but
+ * making a call to a collective API
+ */
+ case NC_EINDEP:
+ return "Operation not allowed in independent data mode";
+ /* this means your program is now in collective data mode, but
+ * making a call to an independent API
+ */
+ case NC_EFILE:
+ return "Unknown error in file operation";
+ /* this error is caused by an unsuccessful MPI-IO call and usually
+ * accompany with additional MPI error messages
+ */
+ case NC_EREAD:
+ return "Unknow error occurs in reading file";
+ /* this error is caused by an unsuccessful call to MPI_File_read or
+ * MPI_File_read_all and usually accompany with additional MPI
+ * error messages
+ */
+ case NC_EWRITE:
+ return "Unknow error occurs in writting file";
+ /* this error is caused by an unsuccessful call to MPI_File_write or
+ * MPI_File_write_all and usually accompany with additional MPI
+ * error messages
+ */
+ case NC_EOFILE:
+ return "Can not open/create file";
+ case NC_EMULTITYPES:
+ return "Multiple types used in memory data";
+ /* when using flexible APIs, the argument MPI derived datatype is
+ * not allowed to contain more than one basic data type
+ */
+ case NC_EIOMISMATCH:
+ return "Input/Output data amount mismatch";
+ /* this error indicates the request amount is mismatched between
+ * bufcount and the value calculated from argument count[]
+ */
+ case NC_ENEGATIVECNT:
+ return "Negative count is prohibited";
+ /* In netCDF, count (or edge) argument is of type size_t, which is
+ * an unsigned integer. A negative count will make the value very
+ * large, causing NC_EEDGE error and hence netCDF need no such
+ * error code.
+ */
+ case NC_EUNSPTETYPE:
+ return "Unsupported etype is used in MPI datatype for memory data";
+ /* when using flexible APIs, the argument MPI derived datatype is
+ * only allowed to be constructed from the MPI basic data types
+ * known to PnetCDF
+ */
+ case NC_EINVAL_REQUEST:
+ return "Invalid nonblocking request ID.";
+ case NC_EAINT_TOO_SMALL:
+ return "MPI_Aint not large enough to hold requested value.";
+ /* this usually happens on 32-bit machines where MPI_Aint is a
+ * 4-byte integer and when the I/O request amount or accessing
+ * file offset is > 2GB.
+ */
+ case NC_ENOTSUPPORT:
+ return "Feature is not yet supported.";
+ case NC_ENULLBUF:
+ return "Trying to attach a NULL buffer or the buffer size is <= 0.";
+ /* an error returned from ncmpi_buffer_attach()
+ */
+ case NC_EPREVATTACHBUF:
+ return "Previous attached buffer is found.";
+ /* an error returned from ncmpi_buffer_attach() indicating a
+ * buffer has been attached previously
+ */
+ case NC_ENULLABUF:
+ return "No attached buffer is found.";
+ /* an error when calling bput APIs and no buffer has been attached
+ */
+ case NC_EPENDINGBPUT:
+ return "Cannot detach buffer as a pending bput request is found.";
+ /* an error returned from ncmpi_buffer_detach()
+ */
+ case NC_EINSUFFBUF:
+ return "Attached buffer is too small.";
+ /* an error when calling bput APIs
+ */
+ case NC_ENOENT:
+ return "The specified netCDF file does not exist.";
+ /* this error code corresponds to MPI error class
+ * MPI_ERR_NO_SUCH_FILE, an error generated from MPI_File_open(),
+ * MPI_File_delete() or others
+ */
+ case NC_EINTOVERFLOW:
+ return "Overflow when type cast to 4-byte integer.";
+ /* this usually happens on 32-bit machines where MPI_Offset is a
+ * 4-byte integer and when the I/O request amount or accessing
+ * file offset is > 2GB.
+ */
+ case NC_ENOTENABLED:
+ return "feature is not enabled at configure time.";
+ /* Some APIs require a specific feature enabled at the configure
+ * time, for example, ncmpi_inq_malloc_size() works only
+ * --enable-debug is used when configuring PnetCDF
+ */
+ case NC_EBAD_FILE:
+ return "Invalid file name (e.g., path name too long).";
+ /* this error code corresponds to MPI error class
+ * MPI_ERR_BAD_FILE, an error generated from MPI_File_open()
+ */
+ case NC_ENO_SPACE:
+ return "Not enough space.";
+ /* this error code corresponds to MPI error class
+ * MPI_ERR_NO_SPACE, an error generated from MPI_File_open()
+ */
+ case NC_EQUOTA:
+ return "Quota exceeded.";
+ /* this error code corresponds to MPI error class
+ * MPI_ERR_QUOTA, an error generated from MPI_File_open()
+ */
+ case NC_ENULLSTART:
+ return "argument start is a NULL pointer";
+ /* Some APIs require argument start not be a NULL pointer
+ */
+ case NC_ENULLCOUNT:
+ return "argument count is a NULL pointer";
+ /* Some APIs require argument count cannot be a NULL pointer
+ */
+ case NC_EINVAL_CMODE:
+ return "Invalid file create mode, cannot have both NC_64BIT_OFFSET & NC_64BIT_DATA";
+ case NC_ETYPESIZE:
+ return "MPI derived data type size error (bigger than the variable size)";
+ case NC_ETYPE_MISMATCH:
+ return "element type of the MPI derived data type mismatches the variable data type";
+ case NC_ETYPESIZE_MISMATCH:
+ return "filetype's size mismatches buftype's size * bufcount";
+ case NC_ESTRICTCDF2:
+ return "Attempting CDF-5 operation on strict CDF or CDF-2 file";
+ case NC_ENOTRECVAR:
+ return "Attempting operation only for record variables";
+ case NC_ENOTFILL:
+ return "Attempting to fill a variable when its fill mode is off";
+ case NC_EMULTIDEFINE:
+ return "File header is inconsistent among processes";
+ /* this error means the metadata (dimension names, variable names,
+ * variable's dimensions, attributes, and whatever will be stored
+ * in the file header) is inconsistent among all MPI processes.
+ */
+ case NC_EMULTIDEFINE_OMODE:
+ return "Bad file create/open mode or modes are inconsistent across processes.";
+ case NC_EMULTIDEFINE_DIM_NUM:
+ return "Number of dimensions is defined inconsistently among processes.";
+ case NC_EMULTIDEFINE_DIM_SIZE:
+ return "Dimension size is defined inconsistently among processes.";
+ case NC_EMULTIDEFINE_VAR_NUM:
+ return "Number of variables is defined inconsistently among processes.";
+ case NC_EMULTIDEFINE_VAR_NAME:
+ return "Variable names are defined inconsistently among processes.";
+ case NC_EMULTIDEFINE_VAR_NDIMS:
+ return "Dimensionality of this variable is defined inconsistently among processes.";
+ case NC_EMULTIDEFINE_VAR_DIMIDS:
+ return "Dimension IDs used to define this variable is inconsistent among processes.";
+ case NC_EMULTIDEFINE_VAR_TYPE:
+ return "Data type of this variable is defined inconsistently among processes.";
+ case NC_EMULTIDEFINE_VAR_LEN:
+ return "Number of elements of this variable is defined inconsistently among processes.";
+ case NC_EMULTIDEFINE_VAR_BEGIN:
+ return "Starting file offset of this variable is inconsistent among processes.";
+ case NC_EMULTIDEFINE_NUMRECS:
+ return "Number of records is inconsistent among processes.";
+ case NC_EMULTIDEFINE_ATTR_NUM:
+ return "Number of attributes is inconsistent among processes.";
+ case NC_EMULTIDEFINE_ATTR_SIZE:
+ return "Memory space used by attribute (internal use) is inconsistent among processes.";
+ case NC_EMULTIDEFINE_ATTR_NAME:
+ return "Attribute name is inconsistent among processes.";
+ case NC_EMULTIDEFINE_ATTR_TYPE:
+ return "Attribute type is inconsistent among processes.";
+ case NC_EMULTIDEFINE_ATTR_LEN:
+ return "Attribute length is inconsistent among processes.";
+ case NC_EMULTIDEFINE_ATTR_VAL:
+ return "Attribute value is inconsistent among processes.";
+ case NC_EMULTIDEFINE_FNC_ARGS:
+ return "inconsistent function arguments used in collective API.";
+ case NC_EMULTIDEFINE_FILL_MODE:
+ return "Dataset's file mode is inconsistent among processes.";
+ case NC_EMULTIDEFINE_VAR_FILL_MODE:
+ return "Variable's fill mode is inconsistent among processes.";
+ case NC_EMULTIDEFINE_VAR_FILL_VALUE:
+ return "Variable's fill value is inconsistent among processes.";
+
+ default:
+ /* check netCDF-3 and netCDF-4 errors */
+ return nc_strerror(err);
+ }
+}
+
+/*----< ncmpii_handle_error() ------------------------------------------------*/
+/* translate MPI error codes to PnetCDF/netCDF error codes */
+int ncmpii_handle_error(int mpi_errorcode, /* returned value from MPI call */
+ char *err_msg) /* extra error message */
+{
+ int rank, errorclass, errorStringLen;
+ char errorString[MPI_MAX_ERROR_STRING];
+
+ /* check for specific error codes understood by PnetCDF */
+
+ /* When NC_NOCLOBBER is used in ioflags(cmode) for open to create,
+ * netCDF requires NC_EEXIST returned if the file already exists.
+ * In MPI 2.1, if MPI_File_open uses MPI_MODE_EXCL and the file has
+ * already existed, the error class MPI_ERR_FILE_EXISTS should be returned.
+ * For opening an existing file but the file does not exist, MPI 2.1
+ * will return MPI_ERR_NO_SUCH_FILE
+ * Note for MPI 2.1 and prior, we return MPI_ERR_IO, as these error class
+ * have not been defined.
+ */
+ MPI_Error_class(mpi_errorcode, &errorclass);
+#ifdef HAVE_MPI_ERR_FILE_EXISTS
+ if (errorclass == MPI_ERR_FILE_EXISTS) return NC_EEXIST;
+#endif
+#ifdef HAVE_MPI_ERR_NO_SUCH_FILE
+ if (errorclass == MPI_ERR_NO_SUCH_FILE) return NC_ENOENT;
+#endif
+#ifdef HAVE_MPI_ERR_NOT_SAME
+ /* MPI-IO should return MPI_ERR_NOT_SAME when one or more arguments of a
+ * collective MPI call are different. However, MPI-IO may not report this
+ * error code correctly. For instance, some MPI-IO returns MPI_ERR_AMODE
+ * instead when amode is found inconsistent. MPI_ERR_NOT_SAME can also
+ * report inconsistent file name. */
+ if (errorclass == MPI_ERR_NOT_SAME) return NC_EMULTIDEFINE_FNC_ARGS;
+#endif
+#ifdef HAVE_MPI_ERR_AMODE
+ /* MPI-IO may or may not report MPI_ERR_AMODE if inconsistent amode is
+ * detected. MPI_ERR_AMODE can also indicate other conflict amode used
+ * on each process. But in PnetCDF, MPI_ERR_AMODE can only be caused by
+ * inconsistent file open/create mode. So, if MPI-IO returns this error
+ * we are sure it is because of the inconsistent mode */
+ if (errorclass == MPI_ERR_AMODE) return NC_EMULTIDEFINE_OMODE;
+#endif
+#ifdef HAVE_MPI_ERR_READ_ONLY
+ if (errorclass == MPI_ERR_READ_ONLY) return NC_EPERM;
+#endif
+#ifdef HAVE_MPI_ERR_ACCESS
+ if (errorclass == MPI_ERR_ACCESS) return NC_EACCESS;
+#endif
+#ifdef HAVE_MPI_ERR_BAD_FILE
+ if (errorclass == MPI_ERR_BAD_FILE) return NC_EBAD_FILE;
+#endif
+#ifdef HAVE_MPI_ERR_NO_SPACE
+ if (errorclass == MPI_ERR_NO_SPACE) return NC_ENO_SPACE;
+#endif
+#ifdef HAVE_MPI_ERR_QUOTA
+ if (errorclass == MPI_ERR_QUOTA) return NC_EQUOTA;
+#endif
+
+ /* other errors that currently have no corresponding PnetCDF error codes */
+
+ /* we report the world rank */
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ MPI_Error_string(mpi_errorcode, errorString, &errorStringLen);
+ if (err_msg == NULL) err_msg = "";
+ printf("rank %d: MPI error (%s) : %s\n", rank, err_msg, errorString);
+
+ return NC_EFILE; /* other unknown file I/O error */
+}
+
+
+/*-----------------------------------------------------------------------------
+ * Copy nc_strerror() from netCDF release to ensure the same error
+ * message is returned.
+ *----------------------------------------------------------------------------*/
+
+/*! NetCDF Error Handling
+
+\addtogroup error NetCDF Error Handling
+
+NetCDF functions return a non-zero status codes on error.
+
+Each netCDF function returns an integer status value. If the returned
+status value indicates an error, you may handle it in any way desired,
+from printing an associated error message and exiting to ignoring the
+error indication and proceeding (not recommended!). For simplicity,
+the examples in this guide check the error status and call a separate
+function, handle_err(), to handle any errors. One possible definition
+of handle_err() can be found within the documentation of
+nc_strerror().
+
+The nc_strerror() function is available to convert a returned integer
+error status into an error message string.
+
+Occasionally, low-level I/O errors may occur in a layer below the
+netCDF library. For example, if a write operation causes you to exceed
+disk quotas or to attempt to write to a device that is no longer
+available, you may get an error from a layer below the netCDF library,
+but the resulting write error will still be reflected in the returned
+status value.
+
+*/
+
+/** \{ */
+
+/*! Given an error number, return an error message.
+
+This function returns a static reference to an error message string
+corresponding to an integer netCDF error status or to a system error
+number, presumably returned by a previous call to some other netCDF
+function. The error codes are defined in netcdf.h.
+
+\param ncerr1 error number
+
+\returns short string containing error message.
+
+Here is an example of a simple error handling function that uses
+nc_strerror() to print the error message corresponding to the netCDF
+error status returned from any netCDF function call and then exit:
+
+\code
+ #include <netcdf.h>
+ ...
+ void handle_error(int status) {
+ if (status != NC_NOERR) {
+ fprintf(stderr, "%s\n", nc_strerror(status));
+ exit(-1);
+ }
+ }
+\endcode
+*/
+
+static const char *
+nc_strerror(int ncerr1)
+{
+ /* System error? */
+ if(NC_ISSYSERR(ncerr1))
+ {
+ const char *cp = (const char *) strerror(ncerr1);
+ if(cp == NULL)
+ return "Unknown Error";
+ return cp;
+ }
+
+ /* If we're here, this is a netcdf error code. */
+ switch(ncerr1)
+ {
+ case NC_NOERR:
+ return "No error";
+ case NC_EBADID:
+ return "NetCDF: Not a valid ID";
+ case NC_ENFILE:
+ return "NetCDF: Too many files open";
+ case NC_EEXIST:
+ return "NetCDF: File exists && NC_NOCLOBBER";
+ case NC_EINVAL:
+ return "NetCDF: Invalid argument";
+ case NC_EPERM:
+ return "NetCDF: Write to read only";
+ case NC_ENOTINDEFINE:
+ return "NetCDF: Operation not allowed in data mode";
+ case NC_EINDEFINE:
+ return "NetCDF: Operation not allowed in define mode";
+ case NC_EINVALCOORDS:
+ return "NetCDF: Index exceeds dimension bound";
+ case NC_EMAXDIMS:
+ return "NetCDF: NC_MAX_DIMS exceeded";
+ case NC_ENAMEINUSE:
+ return "NetCDF: String match to name in use";
+ case NC_ENOTATT:
+ return "NetCDF: Attribute not found";
+ case NC_EMAXATTS:
+ return "NetCDF: NC_MAX_ATTRS exceeded";
+ case NC_EBADTYPE:
+ return "NetCDF: Not a valid data type or _FillValue type mismatch";
+ case NC_EBADDIM:
+ return "NetCDF: Invalid dimension ID or name";
+ case NC_EUNLIMPOS:
+ return "NetCDF: NC_UNLIMITED in the wrong index";
+ case NC_EMAXVARS:
+ return "NetCDF: NC_MAX_VARS exceeded";
+ case NC_ENOTVAR:
+ return "NetCDF: Variable not found";
+ case NC_EGLOBAL:
+ return "NetCDF: Action prohibited on NC_GLOBAL varid";
+ case NC_ENOTNC:
+ return "NetCDF: Unknown file format";
+ case NC_ESTS:
+ return "NetCDF: In Fortran, string too short";
+ case NC_EMAXNAME:
+ return "NetCDF: NC_MAX_NAME exceeded";
+ case NC_EUNLIMIT:
+ return "NetCDF: NC_UNLIMITED size already in use";
+ case NC_ENORECVARS:
+ return "NetCDF: nc_rec op when there are no record vars";
+ case NC_ECHAR:
+ return "NetCDF: Attempt to convert between text & numbers";
+ case NC_EEDGE:
+ return "NetCDF: Start+count exceeds dimension bound";
+ case NC_ESTRIDE:
+ return "NetCDF: Illegal stride";
+ case NC_EBADNAME:
+ return "NetCDF: Name contains illegal characters";
+ case NC_ERANGE:
+ return "NetCDF: Numeric conversion not representable";
+ case NC_ENOMEM:
+ return "NetCDF: Memory allocation (malloc) failure";
+ case NC_EVARSIZE:
+ return "NetCDF: One or more variable sizes violate format constraints";
+ case NC_EDIMSIZE:
+ return "NetCDF: Invalid dimension size";
+ case NC_ETRUNC:
+ return "NetCDF: File likely truncated or possibly corrupted";
+ case NC_EAXISTYPE:
+ return "NetCDF: Illegal axis type";
+ case NC_EDAP:
+ return "NetCDF: DAP failure";
+ case NC_ECURL:
+ return "NetCDF: libcurl failure";
+ case NC_EIO:
+ return "NetCDF: I/O failure";
+ case NC_ENODATA:
+ return "NetCDF: Variable has no data in DAP request";
+ case NC_EDAPSVC:
+ return "NetCDF: DAP server error";
+ case NC_EDAS:
+ return "NetCDF: Malformed or inaccessible DAP DAS";
+ case NC_EDDS:
+ return "NetCDF: Malformed or inaccessible DAP DDS";
+ case NC_EDATADDS:
+ return "NetCDF: Malformed or inaccessible DAP DATADDS";
+ case NC_EDAPURL:
+ return "NetCDF: Malformed URL";
+ case NC_EDAPCONSTRAINT:
+ return "NetCDF: Malformed or unexpected Constraint";
+ case NC_ETRANSLATION:
+ return "NetCDF: Untranslatable construct";
+ case NC_EACCESS:
+ return "NetCDF: Access failure";
+ case NC_EAUTH:
+ return "NetCDF: Authorization failure";
+ case NC_ENOTFOUND:
+ return "NetCDF: file not found";
+ case NC_ECANTEXTEND:
+ return "NetCDF: Attempt to extend dataset during NC_INDEPENDENT I/O operation. Use nc_var_par_access to set mode NC_COLLECTIVE before extending variable.";
+ case NC_ECANTREMOVE:
+ return "NetCDF: cannot delete file";
+ case NC_EHDFERR:
+ return "NetCDF: HDF error";
+ case NC_ECANTREAD:
+ return "NetCDF: Can't read file";
+ case NC_ECANTWRITE:
+ return "NetCDF: Can't write file";
+ case NC_ECANTCREATE:
+ return "NetCDF: Can't create file";
+ case NC_EFILEMETA:
+ return "NetCDF: Can't add HDF5 file metadata";
+ case NC_EDIMMETA:
+ return "NetCDF: Can't define dimensional metadata";
+ case NC_EATTMETA:
+ return "NetCDF: Can't open HDF5 attribute";
+ case NC_EVARMETA:
+ return "NetCDF: Problem with variable metadata.";
+ case NC_ENOCOMPOUND:
+ return "NetCDF: Can't create HDF5 compound type";
+ case NC_EATTEXISTS:
+ return "NetCDF: Attempt to create attribute that alread exists";
+ case NC_ENOTNC4:
+ return "NetCDF: Attempting netcdf-4 operation on netcdf-3 file";
+ case NC_ESTRICTNC3:
+ return "NetCDF: Attempting netcdf-4 operation on strict nc3 netcdf-4 file";
+ case NC_ENOTNC3:
+ return "NetCDF: Attempting netcdf-3 operation on netcdf-4 file";
+ case NC_ENOPAR:
+ return "NetCDF: Parallel operation on file opened for non-parallel access";
+ case NC_EPARINIT:
+ return "NetCDF: Error initializing for parallel access";
+ case NC_EBADGRPID:
+ return "NetCDF: Bad group ID";
+ case NC_EBADTYPID:
+ return "NetCDF: Bad type ID";
+ case NC_ETYPDEFINED:
+ return "NetCDF: Type has already been defined and may not be edited";
+ case NC_EBADFIELD:
+ return "NetCDF: Bad field ID";
+ case NC_EBADCLASS:
+ return "NetCDF: Bad class";
+ case NC_EMAPTYPE:
+ return "NetCDF: Mapped access for atomic types only";
+ case NC_ELATEFILL:
+ return "NetCDF: Attempt to define fill value when data already exists.";
+ case NC_ELATEDEF:
+ return "NetCDF: Attempt to define var properties, like deflate, after enddef.";
+ case NC_EDIMSCALE:
+ return "NetCDF: Probem with HDF5 dimscales.";
+ case NC_ENOGRP:
+ return "NetCDF: No group found.";
+ case NC_ESTORAGE:
+ return "NetCDF: Cannot specify both contiguous and chunking.";
+ case NC_EBADCHUNK:
+ return "NetCDF: Bad chunk sizes.";
+ case NC_ENOTBUILT:
+ return "NetCDF: Attempt to use feature that was not turned on "
+ "when netCDF was built.";
+ case NC_EDISKLESS:
+ return "NetCDF: Error in using diskless access";
+ default:
+ return nc_unknown_err_msg;
+ }
+}
+/** \} */
+
+char* ncmpii_err_code_name(int err)
+{
+ static char unknown_str[32];
+ switch (err) {
+ case (NC_NOERR): return "NC_NOERR";
+ case (NC_EBADID): return "NC_EBADID";
+ case (NC_ENFILE): return "NC_ENFILE";
+ case (NC_EEXIST): return "NC_EEXIST";
+ case (NC_EINVAL): return "NC_EINVAL";
+ case (NC_EPERM): return "NC_EPERM";
+ case (NC_ENOTINDEFINE): return "NC_ENOTINDEFINE";
+ case (NC_EINDEFINE): return "NC_EINDEFINE";
+ case (NC_EINVALCOORDS): return "NC_EINVALCOORDS";
+ case (NC_EMAXDIMS): return "NC_EMAXDIMS";
+ case (NC_ENAMEINUSE): return "NC_ENAMEINUSE";
+ case (NC_ENOTATT): return "NC_ENOTATT";
+ case (NC_EMAXATTS): return "NC_EMAXATTS";
+ case (NC_EBADTYPE): return "NC_EBADTYPE";
+ case (NC_EBADDIM): return "NC_EBADDIM";
+ case (NC_EUNLIMPOS): return "NC_EUNLIMPOS";
+ case (NC_EMAXVARS): return "NC_EMAXVARS";
+ case (NC_ENOTVAR): return "NC_ENOTVAR";
+ case (NC_EGLOBAL): return "NC_EGLOBAL";
+ case (NC_ENOTNC): return "NC_ENOTNC";
+ case (NC_ESTS): return "NC_ESTS";
+ case (NC_EMAXNAME): return "NC_EMAXNAME";
+ case (NC_EUNLIMIT): return "NC_EUNLIMIT";
+ case (NC_ENORECVARS): return "NC_ENORECVARS";
+ case (NC_ECHAR): return "NC_ECHAR";
+ case (NC_EEDGE): return "NC_EEDGE";
+ case (NC_ESTRIDE): return "NC_ESTRIDE";
+ case (NC_EBADNAME): return "NC_EBADNAME";
+ case (NC_ERANGE): return "NC_ERANGE";
+ case (NC_ENOMEM): return "NC_ENOMEM";
+ case (NC_EVARSIZE): return "NC_EVARSIZE";
+ case (NC_EDIMSIZE): return "NC_EDIMSIZE";
+ case (NC_ETRUNC): return "NC_ETRUNC";
+ case (NC_EAXISTYPE): return "NC_EAXISTYPE";
+ case (NC_EDAP): return "NC_EDAP";
+ case (NC_ECURL): return "NC_ECURL";
+ case (NC_EIO): return "NC_EIO";
+ case (NC_ENODATA): return "NC_ENODATA";
+ case (NC_EDAPSVC): return "NC_EDAPSVC";
+ case (NC_EDAS): return "NC_EDAS";
+ case (NC_EDDS): return "NC_EDDS";
+ case (NC_EDATADDS): return "NC_EDATADDS";
+ case (NC_EDAPURL): return "NC_EDAPURL";
+ case (NC_EDAPCONSTRAINT): return "NC_EDAPCONSTRAINT";
+ case (NC_ETRANSLATION): return "NC_ETRANSLATION";
+ case (NC_EACCESS): return "NC_EACCESS";
+ case (NC_EAUTH): return "NC_EAUTH";
+ case (NC_ENOTFOUND): return "NC_ENOTFOUND";
+ case (NC_ECANTREMOVE): return "NC_ECANTREMOVE";
+ case (NC_EHDFERR): return "NC_EHDFERR";
+ case (NC_ECANTREAD): return "NC_ECANTREAD";
+ case (NC_ECANTWRITE): return "NC_ECANTWRITE";
+ case (NC_ECANTCREATE): return "NC_ECANTCREATE";
+ case (NC_EFILEMETA): return "NC_EFILEMETA";
+ case (NC_EDIMMETA): return "NC_EDIMMETA";
+ case (NC_EATTMETA): return "NC_EATTMETA";
+ case (NC_EVARMETA): return "NC_EVARMETA";
+ case (NC_ENOCOMPOUND): return "NC_ENOCOMPOUND";
+ case (NC_EATTEXISTS): return "NC_EATTEXISTS";
+ case (NC_ENOTNC4): return "NC_ENOTNC4";
+ case (NC_ESTRICTNC3): return "NC_ESTRICTNC3";
+ case (NC_ENOTNC3): return "NC_ENOTNC3";
+ case (NC_ENOPAR): return "NC_ENOPAR";
+ case (NC_EPARINIT): return "NC_EPARINIT";
+ case (NC_EBADGRPID): return "NC_EBADGRPID";
+ case (NC_EBADTYPID): return "NC_EBADTYPID";
+ case (NC_ETYPDEFINED): return "NC_ETYPDEFINED";
+ case (NC_EBADFIELD): return "NC_EBADFIELD";
+ case (NC_EBADCLASS): return "NC_EBADCLASS";
+ case (NC_EMAPTYPE): return "NC_EMAPTYPE";
+ case (NC_ELATEFILL): return "NC_ELATEFILL";
+ case (NC_ELATEDEF): return "NC_ELATEDEF";
+ case (NC_EDIMSCALE): return "NC_EDIMSCALE";
+ case (NC_ENOGRP): return "NC_ENOGRP";
+ case (NC_ESTORAGE): return "NC_ESTORAGE";
+ case (NC_EBADCHUNK): return "NC_EBADCHUNK";
+ case (NC_ENOTBUILT): return "NC_ENOTBUILT";
+ case (NC_EDISKLESS): return "NC_EDISKLESS";
+ case (NC_ECANTEXTEND): return "NC_ECANTEXTEND";
+ case (NC_EMPI): return "NC_EMPI";
+ // case (NC_EURL): return "NC_EURL";
+ // case (NC_ECONSTRAINT): return "NC_ECONSTRAINT";
+ case (NC_ESMALL): return "NC_ESMALL";
+ case (NC_ENOTINDEP): return "NC_ENOTINDEP";
+ case (NC_EINDEP): return "NC_EINDEP";
+ case (NC_EFILE): return "NC_EFILE";
+ case (NC_EREAD): return "NC_EREAD";
+ case (NC_EWRITE): return "NC_EWRITE";
+ case (NC_EOFILE): return "NC_EOFILE";
+ case (NC_EMULTITYPES): return "NC_EMULTITYPES";
+ case (NC_EIOMISMATCH): return "NC_EIOMISMATCH";
+ case (NC_ENEGATIVECNT): return "NC_ENEGATIVECNT";
+ case (NC_EUNSPTETYPE): return "NC_EUNSPTETYPE";
+ case (NC_EINVAL_REQUEST): return "NC_EINVAL_REQUEST";
+ case (NC_EAINT_TOO_SMALL): return "NC_EAINT_TOO_SMALL";
+ case (NC_ENOTSUPPORT): return "NC_ENOTSUPPORT";
+ case (NC_ENULLBUF): return "NC_ENULLBUF";
+ case (NC_EPREVATTACHBUF): return "NC_EPREVATTACHBUF";
+ case (NC_ENULLABUF): return "NC_ENULLABUF";
+ case (NC_EPENDINGBPUT): return "NC_EPENDINGBPUT";
+ case (NC_EINSUFFBUF): return "NC_EINSUFFBUF";
+ case (NC_ENOENT): return "NC_ENOENT";
+ case (NC_EINTOVERFLOW): return "NC_EINTOVERFLOW";
+ case (NC_ENOTENABLED): return "NC_ENOTENABLED";
+ case (NC_EBAD_FILE): return "NC_EBAD_FILE";
+ case (NC_ENO_SPACE): return "NC_ENO_SPACE";
+ case (NC_EQUOTA): return "NC_EQUOTA";
+ case (NC_ENULLSTART): return "NC_ENULLSTART";
+ case (NC_ENULLCOUNT): return "NC_ENULLCOUNT";
+ case (NC_EINVAL_CMODE): return "NC_EINVAL_CMODE";
+ case (NC_ETYPESIZE): return "NC_ETYPESIZE";
+ case (NC_ETYPE_MISMATCH): return "NC_ETYPE_MISMATCH";
+ case (NC_ETYPESIZE_MISMATCH): return "NC_ETYPESIZE_MISMATCH";
+ case (NC_ESTRICTCDF2): return "NC_ESTRICTCDF2";
+ case (NC_ENOTRECVAR): return "NC_ENOTRECVAR";
+ case (NC_ENOTFILL): return "NC_ENOTFILL";
+ case (NC_EMULTIDEFINE): return "NC_EMULTIDEFINE";
+ case (NC_EMULTIDEFINE_OMODE): return "NC_EMULTIDEFINE_OMODE";
+ case (NC_EMULTIDEFINE_DIM_NUM): return "NC_EMULTIDEFINE_DIM_NUM";
+ case (NC_EMULTIDEFINE_DIM_SIZE): return "NC_EMULTIDEFINE_DIM_SIZE";
+ case (NC_EMULTIDEFINE_DIM_NAME): return "NC_EMULTIDEFINE_DIM_NAME";
+ case (NC_EMULTIDEFINE_VAR_NUM): return "NC_EMULTIDEFINE_VAR_NUM";
+ case (NC_EMULTIDEFINE_VAR_NAME): return "NC_EMULTIDEFINE_VAR_NAME";
+ case (NC_EMULTIDEFINE_VAR_NDIMS): return "NC_EMULTIDEFINE_VAR_NDIMS";
+ case (NC_EMULTIDEFINE_VAR_DIMIDS): return "NC_EMULTIDEFINE_VAR_DIMIDS";
+ case (NC_EMULTIDEFINE_VAR_TYPE): return "NC_EMULTIDEFINE_VAR_TYPE";
+ case (NC_EMULTIDEFINE_VAR_LEN): return "NC_EMULTIDEFINE_VAR_LEN";
+ case (NC_EMULTIDEFINE_NUMRECS): return "NC_EMULTIDEFINE_NUMRECS";
+ case (NC_EMULTIDEFINE_VAR_BEGIN): return "NC_EMULTIDEFINE_VAR_BEGIN";
+ case (NC_EMULTIDEFINE_ATTR_NUM): return "NC_EMULTIDEFINE_ATTR_NUM";
+ case (NC_EMULTIDEFINE_ATTR_SIZE): return "NC_EMULTIDEFINE_ATTR_SIZE";
+ case (NC_EMULTIDEFINE_ATTR_NAME): return "NC_EMULTIDEFINE_ATTR_NAME";
+ case (NC_EMULTIDEFINE_ATTR_TYPE): return "NC_EMULTIDEFINE_ATTR_TYPE";
+ case (NC_EMULTIDEFINE_ATTR_LEN): return "NC_EMULTIDEFINE_ATTR_LEN";
+ case (NC_EMULTIDEFINE_ATTR_VAL): return "NC_EMULTIDEFINE_ATTR_VAL";
+ case (NC_EMULTIDEFINE_FNC_ARGS): return "NC_EMULTIDEFINE_FNC_ARGS";
+ case (NC_EMULTIDEFINE_FILL_MODE): return "NC_EMULTIDEFINE_FILL_MODE";
+ case (NC_EMULTIDEFINE_VAR_FILL_MODE): return "NC_EMULTIDEFINE_VAR_FILL_MODE";
+ case (NC_EMULTIDEFINE_VAR_FILL_VALUE): return "NC_EMULTIDEFINE_VAR_FILL_VALUE";
+ default:
+ sprintf(unknown_str,"Unknown code %d",err);
+ }
+ return unknown_str;
+}
+
diff --git a/src/lib/fbits.h b/src/lib/fbits.h
new file mode 100644
index 0000000..c52d559
--- /dev/null
+++ b/src/lib/fbits.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2003, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ */
+/* $Id: fbits.h 1468 2013-10-26 16:53:18Z wkliao $ */
+
+#ifndef _FBITS_H_
+#define _FBITS_H_
+
+/*
+ * Macros for dealing with flag bits.
+ */
+#define fSet(t, f) ((t) |= (f))
+#define fClr(t, f) ((t) &= ~(f))
+#define fIsSet(t, f) ((t) & (f))
+#define fMask(t, f) ((t) & ~(f))
+
+/*
+ * Propositions
+ */
+/* a implies b */
+#define pIf(a,b) (!(a) || (b))
+/* a if and only if b, use == when it makes sense */
+#define pIff(a,b) (((a) && (b)) || (!(a) && !(b)))
+
+#endif /*!FBITS_H_*/
diff --git a/src/lib/filetype.c b/src/lib/filetype.c
new file mode 100644
index 0000000..2e94797
--- /dev/null
+++ b/src/lib/filetype.c
@@ -0,0 +1,967 @@
+/*
+ * Copyright (C) 2003, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ */
+/* $Id: filetype.c 2196 2015-11-27 22:31:05Z wkliao $ */
+
+#if HAVE_CONFIG_H
+# include "ncconfig.h"
+#endif
+
+#include <stdio.h>
+#include <unistd.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#include <assert.h>
+
+#include <mpi.h>
+
+#include "nc.h"
+#include "ncx.h"
+#include "macro.h"
+
+
+#if SIZEOF_MPI_AINT != SIZEOF_MPI_OFFSET
+/*----< check_recsize_too_big() >--------------------------------------------*/
+inline static int
+check_recsize_too_big(NC *ncp)
+{
+ int ret = NC_NOERR;
+ /* assertion: because recsize will be used to set up the file
+ * view, we must ensure there is no overflow when specifying
+ * how big a stride there is between items (think interleaved
+ * records).
+ *
+ * note: 'recsize' is the sum of the record size of all record
+ * variables in this dataset */
+ if (ncp->recsize != (MPI_Aint)ncp->recsize) {
+ fprintf(stderr, "Type overflow: unable to read/write multiple records in this dataset\non this platform. Please either access records of this record variable\none-at-a-time or run on a 64 bit platform\n");
+ DEBUG_ASSIGN_ERROR(ret, NC_ESMALL)
+ }
+ /* the assert here might be harsh, but without it, users will get corrupt
+ * data. Now, we just skip this request to avoid this assertion. */
+ /* assert (ncp->recsize == (MPI_Aint)ncp->recsize); */
+ return ret;
+}
+#endif
+
+/*----< NC_start_count_stride_ck() >-----------------------------------------*/
+/*
+ * Check whether start, count, stride values are valid for the variable.
+ * Note that even if the request size is zero, this check is enforced in both
+ * netCDF and PnetCDF. Otherwise, many test cases under test directory can fail.
+ * Arguments count and stride can be NULL.
+ */
+int
+NC_start_count_stride_ck(const NC *ncp,
+ const NC_var *varp,
+ const MPI_Offset *start,
+ const MPI_Offset *count,
+ const MPI_Offset *stride,
+ const int rw_flag) /* for read or write */
+{
+ int i=0;
+
+ if (varp->ndims == 0) return NC_NOERR; /* 'scalar' variable */
+
+ /* negative start[] is illegal */
+ if (start[0] < 0) DEBUG_RETURN_ERROR(NC_EINVALCOORDS)
+
+ if (IS_RECVAR(varp)) {
+ if (!fIsSet(ncp->flags, NC_64BIT_DATA) && /* not CDF-5 */
+ start[0] > X_UINT_MAX) /* sanity check */
+ DEBUG_RETURN_ERROR(NC_EINVALCOORDS)
+
+ if (count != NULL && count[0] < 0) /* no negative count[] */
+ DEBUG_RETURN_ERROR(NC_ENEGATIVECNT)
+
+ /* for record variable, [0] is the NC_UNLIMITED dimension */
+ if (rw_flag == READ_REQ) { /* read cannot go beyond current numrecs */
+ if (start[0] >= ncp->numrecs)
+ DEBUG_RETURN_ERROR(NC_EINVALCOORDS)
+
+ if (count != NULL) {
+ if (stride == NULL) { /* for vara APIs */
+ if (start[0] + count[0] > ncp->numrecs)
+ DEBUG_RETURN_ERROR(NC_EEDGE)
+ }
+ else { /* for vars APIs */
+ if (count[0] > 0 &&
+ start[0] + (count[0]-1) * stride[0] >= ncp->numrecs)
+ DEBUG_RETURN_ERROR(NC_EEDGE)
+ }
+ }
+ /* else is for var1 APIs */
+ }
+
+ if (stride != NULL && stride[0] == 0) DEBUG_RETURN_ERROR(NC_ESTRIDE)
+
+ /* In collective data mode where numrecs is always kept consistent
+ * across memory, then there is no need to update numrecs.
+ * (If NC_SHARE is set, then numrecs is even sync-ed with file.)
+ *
+ * In independent data mode, numrecs in memory across processes
+ * and file can be inconsistent. Even re-reading numrecs from file
+ * cannot get the latest value, because in independent mode,
+ * numrecs in file is not updated (due to race condition).
+ * For example, a subset of processes write a new record and at
+ * the same time another set writes 2 new records. Even if NC_SHARE
+ * is set, new values of numrecs cannot be written to the file,
+ * because it can cause a race condition (atomic read-modify IO is
+ * required to solve this problem and MPI-IO cannot do it). Simply
+ * said, numrecs is not automatically kept consistent in
+ * independent mode. Users must call ncmpi_sync_numrecs()
+ * collectively to sync the value. So, here what PnetCDF can do
+ * best is just to check numrecs against the local value.
+ */
+
+ /* skip checking the record dimension */
+ i = 1;
+ }
+
+ for (; i<varp->ndims; i++) {
+ if (start[i] < 0 || start[i] >= varp->shape[i])
+ DEBUG_RETURN_ERROR(NC_EINVALCOORDS)
+
+ if (varp->shape[i] < 0) DEBUG_RETURN_ERROR(NC_EEDGE)
+
+ if (count != NULL) {
+ if (count[i] < 0) /* no negative count[] */
+ DEBUG_RETURN_ERROR(NC_ENEGATIVECNT)
+
+ if (stride == NULL) { /* for vara APIs */
+ if (count[i] > varp->shape[i] ||
+ start[i] + count[i] > varp->shape[i])
+ DEBUG_RETURN_ERROR(NC_EEDGE)
+ }
+ else { /* for vars APIs */
+ if (count[i] > 0 &&
+ start[i] + (count[i]-1) * stride[i] >= varp->shape[i])
+ DEBUG_RETURN_ERROR(NC_EEDGE)
+ if (stride[i] == 0) DEBUG_RETURN_ERROR(NC_ESTRIDE)
+ }
+ }
+ /* else is for var1 APIs */
+ }
+ return NC_NOERR;
+}
+
+/*----< ncmpii_get_offset() >------------------------------------------------*/
+/* returns the file offset of the last byte accessed of this request */
+int
+ncmpii_get_offset(NC *ncp,
+ NC_var *varp,
+ const MPI_Offset starts[], /* [varp->ndims] */
+ const MPI_Offset counts[], /* [varp->ndims] */
+ const MPI_Offset strides[], /* [varp->ndims] */
+ const int rw_flag,
+ MPI_Offset *offset_ptr) /* return file offset */
+{
+ MPI_Offset offset, *end_off=NULL;
+ int status, i, ndims;
+
+ offset = varp->begin; /* beginning file offset of this variable */
+ ndims = varp->ndims; /* number of dimensions of this variable */
+
+ if (counts != NULL)
+ end_off = (MPI_Offset*) NCI_Malloc((size_t)ndims * SIZEOF_MPI_OFFSET);
+
+ if (counts != NULL && strides != NULL) {
+ for (i=0; i<ndims; i++)
+ end_off[i] = starts[i] + (counts[i] - 1) * strides[i];
+ }
+ else if (counts != NULL) { /* strides == NULL */
+ for (i=0; i<ndims; i++)
+ end_off[i] = starts[i] + counts[i] - 1;
+ }
+ else { /* when counts == NULL strides is of no use */
+ end_off = (MPI_Offset*) starts;
+ }
+
+ /* check whether end_off is valid */
+ status = NC_start_count_stride_ck(ncp, varp, end_off, NULL, NULL, rw_flag);
+ if (status != NC_NOERR) {
+#ifdef CDEBUG
+ printf("%s(): NC_start_count_stride_ck() fails\n",__func__);
+#endif
+ return status;
+ }
+
+ if (ndims > 0) {
+ if (IS_RECVAR(varp))
+ /* no need to check recsize here: if MPI_Offset is only 32 bits we
+ will have had problems long before here */
+ offset += end_off[0] * ncp->recsize;
+ else
+ offset += end_off[ndims-1] * varp->xsz;
+
+ if (ndims > 1) {
+ if (IS_RECVAR(varp))
+ offset += end_off[ndims - 1] * varp->xsz;
+ else
+ offset += end_off[0] * varp->dsizes[1] * varp->xsz;
+
+ for (i=1; i<ndims-1; i++)
+ offset += end_off[i] * varp->dsizes[i+1] * varp->xsz;
+ }
+ }
+ if (counts != NULL && end_off != NULL)
+ NCI_Free(end_off);
+
+ *offset_ptr = offset;
+ return NC_NOERR;
+}
+
+/*----< ncmpii_is_request_contiguous() >-------------------------------------*/
+int
+ncmpii_is_request_contiguous(NC *ncp,
+ NC_var *varp,
+ const MPI_Offset starts[],
+ const MPI_Offset counts[])
+{
+ /* determine whether the get/put request to this variable using
+ starts[] and counts[] is contiguous in file */
+ int i, j, most_sig_dim, ndims=varp->ndims;
+
+ /* this variable is a scalar */
+ if (ndims == 0) return 1;
+
+ for (i=0; i<ndims; i++)
+ if (counts[i] == 0) /* zero length request */
+ return 1;
+
+ most_sig_dim = 0; /* record dimension */
+
+ if (IS_RECVAR(varp)) {
+ /* if there are more than one record variable, then the record
+ dimensions, counts[0] must == 1. For now, we assume there
+ are more than one record variable.
+ TODO: we may need an API to inquire how many record variables
+ are defined */
+ if (ncp->vars.num_rec_vars > 1) {
+ /* or if (ncp->recsize > varp->len) more than one record variable */
+ if (counts[0] > 1) return 0;
+
+ /* we need to check from dimension ndims-1 up to dimension 1 */
+ most_sig_dim = 1;
+ }
+ /* if there is only one record variable, then we need to check from
+ * dimension ndims-1 up to dimension 0 */
+ }
+
+ for (i=ndims-1; i>most_sig_dim; i--) {
+ /* find the first counts[i] that is not the entire dimension */
+ if (counts[i] < varp->shape[i]) {
+ /* check dim from i-1, i-2, ..., most_sig_dim and
+ their counts[] should all be 1 */
+ for (j=i-1; j>=most_sig_dim; j--) {
+ if (counts[j] > 1)
+ return 0;
+ }
+ break;
+ }
+ else { /* counts[i] == varp->shape[i] */
+ /* when accessing the entire dimension, starts[i] must be 0 */
+ if (starts[i] != 0) return 0; /* actually this should be error */
+ }
+ }
+ return 1;
+}
+
+#ifndef HAVE_MPI_TYPE_CREATE_SUBARRAY
+/*----< ncmpii_type_create_subarray() >--------------------------------------*/
+/* this is to be used when MPI_Type_create_subarray() is not available,
+ * typically for MPI-1 implementation only */
+static int
+ncmpii_type_create_subarray(int ndims,
+ int *array_of_sizes, /* [ndims] */
+ int *array_of_subsizes, /* [ndims] */
+ int *array_of_starts, /* [ndims] */
+ int order,
+ MPI_Datatype oldtype,
+ MPI_Datatype *newtype)
+{
+ int i, err, blklens[3] = {1, 1, 1};
+ MPI_Datatype type1, type2;
+ MPI_Aint extent, size, array_size, stride, disps[3];
+
+ if (ndims == 0) DEBUG_RETURN_ERROR(NC_EDIMMETA)
+
+#ifdef HAVE_MPI_TYPE_GET_EXTENT
+ MPI_Aint lb;
+ MPI_Type_get_extent(oldtype, &lb, &extent);
+#else
+ MPI_Type_extent(oldtype, &extent);
+#endif
+ array_size = extent;
+ for (i=0; i<ndims; i++) array_size *= array_of_sizes[i];
+
+ if (ndims == 1) {
+ /* blklens argument in MPI_Type_create_hindexed() is of type int */
+ blklens[1] = array_of_subsizes[0];
+ disps[1] = extent * array_of_starts[0];
+
+#if defined (HAVE_MPI_TYPE_CREATE_HINDEXED) && defined(HAVE_MPI_TYPE_CREATE_RESIZED)
+ /* take advantage of disps argument is of type MPI_Aint */
+ err = MPI_Type_create_hindexed(1, &blklens[1], &disps[1], oldtype, &type1);
+ if (err != MPI_SUCCESS)
+ return ncmpii_handle_error(err, "MPI_Type_create_hindexed");
+ MPI_Type_commit(&type1);
+
+ /* add holes in the beginning and tail of type1 */
+ err = MPI_Type_create_resized(type1, 0, array_size, newtype);
+ if (err != MPI_SUCCESS)
+ return ncmpii_handle_error(err, "MPI_Type_create_resized");
+ MPI_Type_free(&type1);
+#else
+ /* add holes in the beginning and tail of oldtype */
+ MPI_Datatype types[3];
+ types[0] = MPI_LB; types[1] = oldtype; types[2] = MPI_UB;
+ disps[0] = 0; disps[2] = array_size;
+ err = MPI_Type_struct(3, blklens, disps, types, newtype);
+ if (err != MPI_SUCCESS)
+ return ncmpii_handle_error(err, "MPI_Type_struct");
+#endif
+ return NC_NOERR;
+ }
+ /* now, ndims > 1 */
+
+ /* first create a datatype for the least 2 significant dimensions */
+
+ /* blklens argument in MPI_Type_create_hvector() is of type int */
+ blklens[0] = array_of_subsizes[ndims-1];
+ stride = array_of_sizes[ndims-1] * extent;
+#ifdef HAVE_MPI_TYPE_CREATE_HVECTOR
+ err = MPI_Type_create_hvector(array_of_subsizes[ndims-2], blklens[0],
+ stride, oldtype, &type1);
+ if (err != MPI_SUCCESS)
+ return ncmpii_handle_error(err, "MPI_Type_create_hvector");
+#else
+ err = MPI_Type_hvector(array_of_subsizes[ndims-2], blklens[0],
+ stride, oldtype, &type1);
+ if (err != MPI_SUCCESS)
+ return ncmpii_handle_error(err, "MPI_Type_hvector");
+#endif
+ MPI_Type_commit(&type1);
+
+ /* now iterate through the rest dimensions */
+ for (i=ndims-3; i>=0; i--) {
+ stride *= array_of_sizes[i+1];
+#ifdef HAVE_MPI_TYPE_CREATE_HVECTOR
+ err = MPI_Type_create_hvector(array_of_subsizes[i], 1, stride, type1, &type2);
+ if (err != MPI_SUCCESS)
+ return ncmpii_handle_error(err, "MPI_Type_create_hvector");
+#else
+ err = MPI_Type_hvector(array_of_subsizes[i], 1, stride, type1, &type2);
+ if (err != MPI_SUCCESS)
+ return ncmpii_handle_error(err, "MPI_Type_hvector");
+#endif
+ MPI_Type_commit(&type2);
+ MPI_Type_free(&type1);
+ type1 = type2;
+ }
+
+ /* disps[1] is the first byte displacement of the subarray */
+ disps[1] = array_of_starts[ndims-1] * extent;
+ size = 1;
+ for (i=ndims-2; i>=0; i--) {
+ size *= array_of_sizes[i+1];
+ disps[1] += size * array_of_starts[i];
+ }
+
+ /* disps[2] is the size of the global array */
+ disps[2] = array_size;
+
+ /* disps[0] is the beginning of the global array */
+ disps[0] = 0;
+
+ /* make filetype the same as calling MPI_Type_create_subarray() */
+ blklens[0] = 1;
+#if defined (HAVE_MPI_TYPE_CREATE_HINDEXED) && defined(HAVE_MPI_TYPE_CREATE_RESIZED)
+ /* adjust LB and UB without using MPI_LB or MPI_UB */
+ err = MPI_Type_create_hindexed(1, blklens, &disps[1], type1, &type2);
+ if (err != MPI_SUCCESS)
+ return ncmpii_handle_error(err, "MPI_Type_create_hindexed");
+ MPI_Type_commit(&type2);
+ err = MPI_Type_create_resized(type2, disps[0], disps[2], newtype);
+ if (err != MPI_SUCCESS)
+ return ncmpii_handle_error(err, "MPI_Type_create_resized");
+ MPI_Type_free(&type2);
+#else
+ MPI_Datatype types[3];
+ types[0] = MPI_LB;
+ types[1] = type1;
+ types[2] = MPI_UB;
+ err = MPI_Type_struct(3, blklens, disps, types, newtype);
+ if (err != MPI_SUCCESS)
+ return ncmpii_handle_error(err, "MPI_Type_struct");
+#endif
+ MPI_Type_free(&type1);
+
+ return NC_NOERR;
+}
+#endif
+
+/*----< ncmpii_type_create_subarray64() >------------------------------------*/
+/* This subroutine is to achieve the same result as MPI_Type_create_subarray()
+ * but it takes arguments in type of MPI_Offset, instead of int. It also
+ * checked for any possible 4-byte integer overflow.
+ */
+static int
+ncmpii_type_create_subarray64(int ndims,
+ MPI_Offset *array_of_sizes, /* [ndims] */
+ MPI_Offset *array_of_subsizes, /* [ndims] */
+ MPI_Offset *array_of_starts, /* [ndims] */
+ int order,
+ MPI_Datatype oldtype,
+ MPI_Datatype *newtype)
+{
+ int i, err, tag, blklens[3] = {1, 1, 1};
+ MPI_Datatype type1, type2;
+ MPI_Aint extent, size, array_size, stride, disps[3];
+#ifdef HAVE_MPI_TYPE_GET_EXTENT
+ MPI_Aint lb;
+#endif
+
+ if (ndims == 0) DEBUG_RETURN_ERROR(NC_EDIMMETA)
+
+ /* check if any of the dimensions is larger than 2^31-1 */
+ tag = 0;
+ for (i=0; i<ndims; i++) {
+ if (array_of_sizes[i] > 2147483647) {
+ tag = 1;
+ break;
+ }
+ }
+
+ if (tag == 0) {
+ /* none of dimensions > 2^31-1, we can safely use
+ * MPI_Type_create_subarray */
+ int *sizes = (int*) NCI_Malloc((size_t)ndims * 3 * SIZEOF_INT);
+ int *subsizes = sizes + ndims;
+ int *starts = subsizes + ndims;
+ for (i=0; i<ndims; i++) {
+ sizes[i] = (int)array_of_sizes[i];
+ subsizes[i] = (int)array_of_subsizes[i];
+ starts[i] = (int)array_of_starts[i];
+ if (array_of_sizes[i] != sizes[i] ||
+ array_of_subsizes[i] != subsizes[i] ||
+ array_of_starts[i] != starts[i])
+ DEBUG_RETURN_ERROR(NC_EINTOVERFLOW)
+ }
+#ifdef HAVE_MPI_TYPE_CREATE_SUBARRAY
+ err = MPI_Type_create_subarray(ndims, sizes, subsizes, starts,
+ order, oldtype, newtype);
+ NCI_Free(sizes);
+ if (err != MPI_SUCCESS)
+ return ncmpii_handle_error(err, "MPI_Type_create_subarray");
+#else
+ err = ncmpii_type_create_subarray(ndims, sizes, subsizes, starts,
+ order, oldtype, newtype);
+ NCI_Free(sizes);
+#endif
+ return err;
+ }
+
+ /* at least one dimension is of size > 2^31-1 and we cannot use
+ * MPI_Type_create_subarray() to create the newtype,
+ * as its arguments array_of_sizes[] and array_of_starts[] are of
+ * type int. One solution is to use a combination of
+ * MPI_Type_create_hvector(), MPI_Type_create_hindexed(),
+ * MPI_Type_create_resized(), and MPI_Type_struct(), as one
+ * of their arguments, stride and indices[], are of type MPI_Aint
+ * (a possible 8-byte integer) that can be used to store the value
+ * of the dimension whose size is > 2^31-1. However, on a machine
+ * where MPI_Aint is 4-byte integer, those MPI_Aint arguments will
+ * cause overflow.
+ */
+#if SIZEOF_MPI_AINT != SIZEOF_MPI_OFFSET
+ DEBUG_RETURN_ERROR(NC_EAINT_TOO_SMALL)
+#endif
+
+#ifdef HAVE_MPI_TYPE_GET_EXTENT
+ MPI_Type_get_extent(oldtype, &lb, &extent);
+#else
+ MPI_Type_extent(oldtype, &extent);
+#endif
+ array_size = extent;
+ for (i=0; i<ndims; i++) array_size *= array_of_sizes[i];
+
+ if (ndims == 1) {
+ /* blklens argument in MPI_Type_create_hindexed() is of type int */
+ blklens[1] = (int)array_of_subsizes[0];
+ if (array_of_subsizes[0] != blklens[1]) /* check int overflow */
+ DEBUG_RETURN_ERROR(NC_EINTOVERFLOW)
+ disps[1] = extent * array_of_starts[0];
+
+#if defined (HAVE_MPI_TYPE_CREATE_HINDEXED) && defined(HAVE_MPI_TYPE_CREATE_RESIZED)
+ /* take advantage of disps argument is of type MPI_Aint */
+ err = MPI_Type_create_hindexed(1, &blklens[1], &disps[1], oldtype, &type1);
+ if (err != MPI_SUCCESS)
+ return ncmpii_handle_error(err, "MPI_Type_create_hindexed");
+ MPI_Type_commit(&type1);
+
+ /* add holes in the beginning and tail of type1 */
+ err = MPI_Type_create_resized(type1, 0, array_size, newtype);
+ if (err != MPI_SUCCESS)
+ return ncmpii_handle_error(err, "MPI_Type_create_resized");
+ MPI_Type_free(&type1);
+#else
+ /* add holes in the beginning and tail of oldtype */
+ MPI_Datatype types[3];
+ types[0] = MPI_LB; types[1] = oldtype; types[2] = MPI_UB;
+ disps[0] = 0; disps[2] = array_size;
+ err = MPI_Type_struct(3, blklens, disps, types, newtype);
+ if (err != MPI_SUCCESS)
+ return ncmpii_handle_error(err, "MPI_Type_struct");
+#endif
+ return NC_NOERR;
+ }
+ /* now, ndims > 1 */
+
+ /* first create a datatype for the least 2 significant dimensions */
+
+ /* count and blocklength arguments in MPI_Type_create_hvector() are of
+ * type int. We need to check for integer overflow */
+ int count, blocklength;
+ count = (int)array_of_subsizes[ndims-2];
+ blocklength = (int)array_of_subsizes[ndims-1];
+ if (array_of_subsizes[ndims-2] != count ||
+ array_of_subsizes[ndims-1] != blocklength) /* check int overflow */
+ DEBUG_RETURN_ERROR(NC_EINTOVERFLOW)
+ stride = array_of_sizes[ndims-1] * extent;
+#ifdef HAVE_MPI_TYPE_CREATE_HVECTOR
+ err = MPI_Type_create_hvector(count, blocklength, stride, oldtype, &type1);
+ if (err != MPI_SUCCESS)
+ return ncmpii_handle_error(err, "MPI_Type_create_hvector");
+#else
+ err = MPI_Type_hvector(count, blocklength, stride, oldtype, &type1);
+ if (err != MPI_SUCCESS)
+ return ncmpii_handle_error(err, "MPI_Type_hvector");
+#endif
+ MPI_Type_commit(&type1);
+
+ /* now iterate through the rest dimensions */
+ for (i=ndims-3; i>=0; i--) {
+ count = (int)array_of_subsizes[i];
+ if (array_of_subsizes[i] != count) /* check int overflow */
+ DEBUG_RETURN_ERROR(NC_EINTOVERFLOW)
+ stride *= array_of_sizes[i+1];
+#ifdef HAVE_MPI_TYPE_CREATE_HVECTOR
+ err = MPI_Type_create_hvector(count, 1, stride, type1, &type2);
+ if (err != MPI_SUCCESS)
+ return ncmpii_handle_error(err, "MPI_Type_create_hvector");
+#else
+ err = MPI_Type_hvector(count, 1, stride, type1, &type2);
+ if (err != MPI_SUCCESS)
+ return ncmpii_handle_error(err, "MPI_Type_hvector");
+#endif
+ MPI_Type_commit(&type2);
+ MPI_Type_free(&type1);
+ type1 = type2;
+ }
+
+ /* disps[0] is the displacement to the beginning of the global array */
+ disps[0] = 0;
+
+ /* disps[1] is the first byte displacement of the subarray */
+ disps[1] = array_of_starts[ndims-1] * extent;
+ size = 1;
+ for (i=ndims-2; i>=0; i--) {
+ size *= array_of_sizes[i+1];
+ disps[1] += size * array_of_starts[i];
+ }
+
+ /* disps[2] is the size of the global array */
+ disps[2] = array_size;
+
+ /* make filetype the same as calling MPI_Type_create_subarray() */
+#if defined(HAVE_MPI_TYPE_CREATE_HINDEXED) && defined(HAVE_MPI_TYPE_CREATE_RESIZED)
+ /* adjust LB and UB without using MPI_LB or MPI_UB */
+ err = MPI_Type_create_hindexed(1, blklens, &disps[1], type1, &type2);
+ if (err != MPI_SUCCESS)
+ return ncmpii_handle_error(err, "MPI_Type_create_hindexed");
+ MPI_Type_commit(&type2);
+ err = MPI_Type_create_resized(type2, disps[0], disps[2], newtype);
+ if (err != MPI_SUCCESS)
+ return ncmpii_handle_error(err, "MPI_Type_create_resized");
+ MPI_Type_free(&type2);
+#else
+ MPI_Datatype types[3];
+ types[0] = MPI_LB;
+ types[1] = type1;
+ types[2] = MPI_UB;
+ err = MPI_Type_struct(3, blklens, disps, types, newtype);
+ if (err != MPI_SUCCESS)
+ return ncmpii_handle_error(err, "MPI_Type_struct");
+#endif
+ MPI_Type_free(&type1);
+
+ return NC_NOERR;
+}
+
+/*----< ncmpii_vara_create_filetype() >--------------------------------------*/
+static int
+ncmpii_vara_create_filetype(NC *ncp,
+ NC_var *varp,
+ const MPI_Offset *start,
+ const MPI_Offset *count,
+ int rw_flag,
+ int *blocklen,
+ MPI_Offset *offset_ptr,
+ MPI_Datatype *filetype_ptr,
+ int *is_filetype_contig)
+{
+ int dim, status, err;
+ MPI_Offset nbytes, offset;
+ MPI_Datatype filetype;
+
+ /* check whether start, count are valid */
+ status = NC_start_count_stride_ck(ncp, varp, start, count, NULL, rw_flag);
+ if (status != NC_NOERR) return status;
+
+ /* calculate the request size */
+ nbytes = varp->xsz;
+ for (dim=0; dim<varp->ndims; dim++) nbytes *= count[dim];
+ if (nbytes != (int)nbytes) DEBUG_RETURN_ERROR(NC_EINTOVERFLOW)
+ if (blocklen != NULL) *blocklen = (int)nbytes;
+
+ /* when nbytes == 0 or varp is a scalar, i.e. varp->ndims == 0, no need to
+ * create a filetype
+ */
+ if (varp->ndims == 0 || nbytes == 0) {
+ *offset_ptr = varp->begin;
+ *filetype_ptr = MPI_BYTE;
+ if (is_filetype_contig != NULL) *is_filetype_contig = 1;
+ return NC_NOERR;
+ }
+
+ /* if the request is contiguous in file, no need to create a filetype */
+ if (ncmpii_is_request_contiguous(ncp, varp, start, count)) {
+ status = ncmpii_get_offset(ncp, varp, start, NULL, NULL, rw_flag,
+ &offset);
+ *offset_ptr = offset;
+ *filetype_ptr = MPI_BYTE;
+ if (is_filetype_contig != NULL) *is_filetype_contig = 1;
+ return status;
+ }
+
+ /* hereinafter fileview is noncontiguous, i.e. filetype != MPI_BYTE.
+ * Since we will construct a filetype, blocklen is set to 1.
+ */
+ if (blocklen != NULL) *blocklen = 1;
+ if (is_filetype_contig != NULL) *is_filetype_contig = 0;
+ offset = varp->begin;
+
+ /* previously, request size has been checked and it must > 0 */
+ if (IS_RECVAR(varp)) {
+ int blocklength;
+ MPI_Datatype rectype=MPI_BYTE;
+
+#if SIZEOF_MPI_AINT != SIZEOF_MPI_OFFSET
+ /* check overflow only if MPI_Aint is smaller than MPI_Offset */
+ status = check_recsize_too_big(ncp);
+ if (status != NC_NOERR) return status;
+#endif
+ /* check overflow, because 1st argument of hvector is of type int */
+ if (count[0] != (int) count[0]) DEBUG_RETURN_ERROR(NC_EINTOVERFLOW)
+
+ offset += start[0] * ncp->recsize;
+
+ if (varp->ndims > 1) {
+ /* when ndims > 1, we need to construct a subarray type for a
+ * single record, i.e. for dimension 1 ... ndims-1 */
+ MPI_Offset *shape64, *subcount64, *substart64;
+
+ shape64 = (MPI_Offset*) NCI_Malloc((size_t)varp->ndims * 3 * SIZEOF_MPI_OFFSET);
+ subcount64 = shape64 + varp->ndims;
+ substart64 = subcount64 + varp->ndims;
+
+ shape64[0] = count[0];
+ subcount64[0] = count[0];
+ substart64[0] = 0;
+
+ for (dim=1; dim<varp->ndims; dim++) {
+ shape64[dim] = varp->shape[dim];
+ subcount64[dim] = count[dim];
+ substart64[dim] = start[dim];
+ }
+ shape64[varp->ndims-1] *= varp->xsz;
+ subcount64[varp->ndims-1] *= varp->xsz;
+ substart64[varp->ndims-1] *= varp->xsz;
+
+ status = ncmpii_type_create_subarray64(varp->ndims-1, shape64+1,
+ subcount64+1, substart64+1, MPI_ORDER_C,
+ MPI_BYTE, &rectype);
+ NCI_Free(shape64);
+ if (status != NC_NOERR) return status;
+
+ MPI_Type_commit(&rectype);
+ blocklength = 1;
+ }
+ else { /* no subarray datatype is needed */
+ blocklength = varp->xsz;
+ }
+
+#ifdef HAVE_MPI_TYPE_CREATE_HVECTOR
+ err = MPI_Type_create_hvector((int)count[0], blocklength, ncp->recsize,
+ rectype, &filetype);
+ if (err != MPI_SUCCESS)
+ return ncmpii_handle_error(err, "MPI_Type_create_hvector");
+#else
+ err = MPI_Type_hvector((int)count[0], blocklength, ncp->recsize,
+ rectype, &filetype);
+ if (err != MPI_SUCCESS)
+ return ncmpii_handle_error(err, "MPI_Type_hvector");
+#endif
+ if (rectype != MPI_BYTE) MPI_Type_free(&rectype);
+ }
+ else { /* for non-record variable, just create a subarray datatype */
+ MPI_Offset *shape64, *subcount64, *substart64;
+ shape64 = (MPI_Offset*) NCI_Malloc((size_t)varp->ndims * 3 * SIZEOF_MPI_OFFSET);
+ subcount64 = shape64 + varp->ndims;
+ substart64 = subcount64 + varp->ndims;
+
+ for (dim=0; dim<varp->ndims; dim++) {
+ shape64[dim] = varp->shape[dim];
+ subcount64[dim] = count[dim];
+ substart64[dim] = start[dim];
+ }
+ shape64[varp->ndims-1] *= varp->xsz;
+ subcount64[varp->ndims-1] *= varp->xsz;
+ substart64[varp->ndims-1] *= varp->xsz;
+
+ status = ncmpii_type_create_subarray64(varp->ndims, shape64, subcount64,
+ substart64, MPI_ORDER_C,
+ MPI_BYTE, &filetype);
+ NCI_Free(shape64);
+ if (status != NC_NOERR) return status;
+ }
+ MPI_Type_commit(&filetype);
+
+ *offset_ptr = offset;
+ *filetype_ptr = filetype;
+
+ return NC_NOERR;
+}
+
+/*----< ncmpii_vars_create_filetype() >--------------------------------------*/
+int
+ncmpii_vars_create_filetype(NC *ncp,
+ NC_var *varp,
+ const MPI_Offset start[],
+ const MPI_Offset count[],
+ const MPI_Offset stride[],
+ int rw_flag,
+ int *blocklen,
+ MPI_Offset *offset_ptr,
+ MPI_Datatype *filetype_ptr,
+ int *is_filetype_contig)
+{
+ int dim, status, err;
+ MPI_Offset offset, stride_off, nelems;
+ MPI_Datatype filetype=MPI_BYTE;
+
+ if (stride == NULL)
+ return ncmpii_vara_create_filetype(ncp, varp, start, count, rw_flag,
+ blocklen, offset_ptr, filetype_ptr,
+ is_filetype_contig);
+
+ /* check if all stride[] == 1 */
+ for (dim=0; dim<varp->ndims && stride[dim]==1; dim++) ;
+ if (dim == varp->ndims) /* all stride[] == 1, same as stride == NULL */
+ return ncmpii_vara_create_filetype(ncp, varp, start, count, rw_flag,
+ blocklen, offset_ptr, filetype_ptr,
+ is_filetype_contig);
+
+ /* now stride[] indicates a non-contiguous fileview */
+
+ /* check whether start, count, stride are valid */
+ status = NC_start_count_stride_ck(ncp, varp, start, count, stride, rw_flag);
+ if (status != NC_NOERR) return status;
+
+ /* calculate request amount */
+ nelems = 1;
+ for (dim=0; dim<varp->ndims; dim++) nelems *= count[dim];
+
+ /* when nelems == 0 or varp is a scalar, i.e. varp->ndims == 0, no need to
+ * create a filetype
+ */
+ if (varp->ndims == 0 || nelems == 0) {
+ *offset_ptr = varp->begin;
+ *filetype_ptr = MPI_BYTE;
+ if (blocklen != NULL) *blocklen = 0;
+ if (is_filetype_contig != NULL) *is_filetype_contig = 1;
+ return NC_NOERR;
+ }
+
+ /* hereinafter fileview is noncontiguous, i.e. filetype != MPI_BYTE.
+ * Since we will construct a filetype, blocklen is set to 1.
+ */
+ if (blocklen != NULL) *blocklen = 1;
+ if (is_filetype_contig != NULL) *is_filetype_contig = 0;
+ offset = varp->begin;
+
+ int ndims, *blockcounts, *blocklens;
+ MPI_Aint *blockstride;
+ MPI_Datatype tmptype;
+
+ ndims = varp->ndims;
+ blockcounts = (int*) NCI_Malloc((size_t)ndims * 2 * SIZEOF_INT);
+ blocklens = blockcounts + ndims;
+
+ blockstride = (MPI_Aint*) NCI_Malloc((size_t)ndims * SIZEOF_MPI_AINT);
+
+ tmptype = MPI_BYTE;
+
+ blockcounts[ndims-1] = (int)count[ndims-1];
+ /* check 4-byte integer overflow (blockcounts in MPI_Type_hvector
+ is of type int while count[] is of type MPI_Offset */
+ if (count[ndims-1] != blockcounts[ndims-1])
+ DEBUG_RETURN_ERROR(NC_EINTOVERFLOW)
+ /* blocklens[] is unlikely a big value */
+ blocklens[ndims-1] = varp->xsz;
+
+ if (ndims == 1 && IS_RECVAR(varp)) {
+#if SIZEOF_MPI_AINT != SIZEOF_MPI_OFFSET
+ status = check_recsize_too_big(ncp);
+ if (status != NC_NOERR) return status;
+#endif
+ stride_off = stride[ndims-1] * ncp->recsize;
+ blockstride[ndims-1] = stride_off;
+ offset += start[ndims-1] * ncp->recsize;
+ } else {
+ stride_off = stride[ndims-1] * varp->xsz;
+ blockstride[ndims-1] = stride_off;
+ offset += start[ndims-1] * varp->xsz;
+ }
+#if SIZEOF_MPI_AINT != SIZEOF_MPI_OFFSET
+ /* check 4-byte integer overflow */
+ if (stride_off != blockstride[ndims-1])
+ DEBUG_RETURN_ERROR(NC_EINTOVERFLOW)
+#endif
+
+ for (dim=ndims-1; dim>=0; dim--) {
+#ifdef HAVE_MPI_TYPE_CREATE_HVECTOR
+ err = MPI_Type_create_hvector(blockcounts[dim], blocklens[dim],
+ blockstride[dim], tmptype, &filetype);
+ if (err != MPI_SUCCESS)
+ return ncmpii_handle_error(err, "MPI_Type_create_hvector");
+#else
+ err = MPI_Type_hvector(blockcounts[dim], blocklens[dim],
+ blockstride[dim], tmptype, &filetype);
+ if (err != MPI_SUCCESS)
+ return ncmpii_handle_error(err, "MPI_Type_hvector");
+#endif
+ MPI_Type_commit(&filetype);
+ if (tmptype != MPI_BYTE)
+ MPI_Type_free(&tmptype);
+ tmptype = filetype;
+
+ if (dim - 1 >= 0) {
+ blocklens[dim-1] = 1;
+ blockcounts[dim-1] = (int)count[dim - 1];
+ /* check 4-byte integer overflow */
+ if (count[dim-1] != blockcounts[dim-1])
+ DEBUG_RETURN_ERROR(NC_EINTOVERFLOW)
+
+ if (dim-1 == 0 && IS_RECVAR(varp)) {
+ stride_off = stride[dim-1] * ncp->recsize;
+ blockstride[dim-1] = stride_off;
+ offset += start[dim-1] * ncp->recsize;
+ } else {
+ stride_off = stride[dim-1] * varp->dsizes[dim] * varp->xsz;
+ blockstride[dim-1] = stride_off;
+ offset += start[dim-1] * varp->dsizes[dim] * varp->xsz;
+ }
+#if SIZEOF_MPI_AINT != SIZEOF_MPI_OFFSET
+ /* check 4-byte integer overflow */
+ if (stride_off != blockstride[dim-1])
+ DEBUG_RETURN_ERROR(NC_EINTOVERFLOW)
+#endif
+ }
+ }
+ NCI_Free(blockstride);
+ NCI_Free(blockcounts);
+
+ *offset_ptr = offset;
+ *filetype_ptr = filetype;
+
+ return NC_NOERR;
+}
+
+/*----< ncmpii_file_set_view() >---------------------------------------------*/
+/* This function handles the special case for root process for setting its
+ * file view: to keeps the whole file header visible to the root process.
+ * This function is collective if called in collective data mode
+ */
+int
+ncmpii_file_set_view(NC *ncp,
+ MPI_File fh,
+ MPI_Offset *offset,
+ MPI_Datatype filetype)
+{
+ int rank, err, mpireturn, status=NC_NOERR;
+
+ if (filetype == MPI_BYTE) {
+ /* filetype is a contiguous space, make the whole file visible */
+ TRACE_IO(MPI_File_set_view)(fh, 0, MPI_BYTE, MPI_BYTE,
+ "native", MPI_INFO_NULL);
+ return NC_NOERR;
+ }
+
+ MPI_Comm_rank(ncp->nciop->comm, &rank);
+ if (rank == 0) {
+ /* prepend the whole file header to filetype */
+ int blocklens[2];
+ MPI_Aint disps[2];
+ MPI_Datatype root_filetype, ftypes[2];
+
+ /* first block is the header extent */
+ blocklens[0] = (int)ncp->begin_var;
+ disps[0] = 0;
+ ftypes[0] = MPI_BYTE;
+
+ /* check if header size > 2^31 */
+ if (ncp->begin_var != blocklens[0]) DEBUG_ASSIGN_ERROR(status, NC_EINTOVERFLOW)
+
+ /* second block is filetype, the subarray request(s) to the variable */
+ blocklens[1] = 1;
+ disps[1] = *offset;
+ ftypes[1] = filetype;
+
+#if SIZEOF_MPI_AINT != SIZEOF_MPI_OFFSET
+ if (*offset != disps[1]) {
+ blocklens[1] = 0;
+ DEBUG_ASSIGN_ERROR(status, NC_EAINT_TOO_SMALL)
+ }
+#endif
+
+#ifdef HAVE_MPI_TYPE_CREATE_STRUCT
+ MPI_Type_create_struct(2, blocklens, disps, ftypes, &root_filetype);
+#else
+ MPI_Type_struct(2, blocklens, disps, ftypes, &root_filetype);
+#endif
+ MPI_Type_commit(&root_filetype);
+
+ TRACE_IO(MPI_File_set_view)(fh, 0, MPI_BYTE, root_filetype,
+ "native", MPI_INFO_NULL);
+ MPI_Type_free(&root_filetype);
+
+ /* now update the explicit offset to be used in MPI-IO call later */
+ *offset = ncp->begin_var;
+ }
+ else {
+ TRACE_IO(MPI_File_set_view)(fh, *offset, MPI_BYTE, filetype,
+ "native", MPI_INFO_NULL);
+ /* the explicit offset is already set in fileview */
+ *offset = 0;
+ }
+ if (mpireturn != MPI_SUCCESS) {
+ err = ncmpii_handle_error(mpireturn, "MPI_File_set_view");
+ if (status == NC_NOERR) status = err;
+ }
+
+ return status;
+}
diff --git a/src/lib/fill.c b/src/lib/fill.c
new file mode 100644
index 0000000..3da99cb
--- /dev/null
+++ b/src/lib/fill.c
@@ -0,0 +1,523 @@
+/*
+ * Copyright (C) 2015, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ */
+/* $Id: fill.c 2198 2015-11-28 00:20:38Z wkliao $ */
+
+#if HAVE_CONFIG_H
+# include "ncconfig.h"
+#endif
+
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#include <stdio.h>
+#include <string.h>
+
+#include <mpi.h>
+
+#include "nc.h"
+#include "macro.h"
+
+#define CHECK_ERROR(status) { \
+ if (ncp->safe_mode == 1) { \
+ int g_status; \
+ TRACE_COMM(MPI_Allreduce)(&status, &g_status, 1, MPI_INT, MPI_MIN, \
+ ncp->nciop->comm); \
+ if (g_status != NC_NOERR) return status; \
+ } \
+ else if (status != NC_NOERR) \
+ return status; \
+}
+
+/* The default fill values defined in pnetcdf.h.inc must be the same as the
+ * ones defined in netCDF-4 and match the hexadecimal values set below
+ *
+#define NC_FILL_BYTE ((signed char)-127)
+#define NC_FILL_CHAR ((char)0)
+#define NC_FILL_SHORT ((short)-32767)
+#define NC_FILL_INT (-2147483647L)
+#define NC_FILL_FLOAT (9.9692099683868690e+36f)
+#define NC_FILL_DOUBLE (9.9692099683868690e+36)
+#define NC_FILL_UBYTE (255)
+#define NC_FILL_USHORT (65535)
+#define NC_FILL_UINT (4294967295U)
+#define NC_FILL_INT64 ((long long)-9223372036854775806LL)
+#define NC_FILL_UINT64 ((unsigned long long)18446744073709551614ULL)
+*/
+static unsigned char FILL_CHAR[1] = {0x00};
+static unsigned char FILL_BYTE[1] = {0x81};
+static unsigned char FILL_SHORT[2] = {0x80, 0x01};
+static unsigned char FILL_INT[4] = {0x80, 0x00, 0x00, 0x01};
+static unsigned char FILL_FLOAT[4] = {0x7C, 0xF0, 0x00, 0x00};
+static unsigned char FILL_DOUBLE[8] = {0x47, 0x9E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+static unsigned char FILL_UBYTE[1] = {0xFF};
+static unsigned char FILL_USHORT[2] = {0xFF, 0xFF};
+static unsigned char FILL_UINT[4] = {0xFF, 0xFF, 0xFF, 0xFF};
+static unsigned char FILL_INT64[8] = {0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02};
+static unsigned char FILL_UINT64[8] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE};
+
+/*----< inq_default_fill_value() >-------------------------------------------*/
+/* copy the default fill value to the memory space pointed by fill_value */
+static int
+inq_default_fill_value(int type, void *fill_value)
+{
+ if (fill_value == NULL) return NC_NOERR;
+
+ switch(type) {
+ case NC_CHAR : *(char*)fill_value = NC_FILL_CHAR; break;
+ case NC_BYTE : *(signed char*)fill_value = NC_FILL_BYTE; break;
+ case NC_SHORT : *(short*)fill_value = NC_FILL_SHORT; break;
+ case NC_INT : *(int*)fill_value = NC_FILL_INT; break;
+ case NC_FLOAT : *(float*)fill_value = NC_FILL_FLOAT; break;
+ case NC_DOUBLE : *(double*)fill_value = NC_FILL_DOUBLE; break;
+ case NC_UBYTE : *(unsigned char*)fill_value = NC_FILL_UBYTE; break;
+ case NC_USHORT : *(unsigned short*)fill_value = NC_FILL_USHORT; break;
+ case NC_UINT : *(unsigned int*)fill_value = NC_FILL_UINT; break;
+ case NC_INT64 : *(long long*)fill_value = NC_FILL_INT64; break;
+ case NC_UINT64 : *(unsigned long long*)fill_value = NC_FILL_UINT64; break;
+ default : DEBUG_RETURN_ERROR(NC_EBADTYPE)
+ }
+ return NC_NOERR;
+}
+
+/*----< ncmpii_fill_var_buf() >----------------------------------------------*/
+/* fill the buffer, buf, with either user-defined fill values or default
+ * values */
+static int
+ncmpii_fill_var_buf(const NC_var *varp,
+ MPI_Offset bnelems, /* number of elements in buf */
+ void *buf)
+{
+ int i, indx;
+
+ indx = ncmpii_NC_findattr(&varp->attrs, _FillValue);
+ if (indx >= 0) {
+ /* User defined fill value */
+ NC_attr *attrp = varp->attrs.value[indx];
+ if (attrp->type != varp->type || attrp->nelems != 1)
+ DEBUG_RETURN_ERROR(NC_EBADTYPE)
+
+ /* Use the user defined value */
+ char *bufp = buf;
+ for (i=0; i<bnelems; i++) {
+ memcpy(bufp, attrp->xvalue, (size_t)varp->xsz);
+ bufp += varp->xsz;
+ }
+ }
+ else { /* use the default */
+ void *xvalue;
+ switch(varp->type) {
+ case NC_CHAR : xvalue = &FILL_CHAR[0]; break;
+ case NC_BYTE : xvalue = &FILL_BYTE[0]; break;
+ case NC_SHORT : xvalue = &FILL_SHORT[0]; break;
+ case NC_INT : xvalue = &FILL_INT[0]; break;
+ case NC_FLOAT : xvalue = &FILL_FLOAT[0]; break;
+ case NC_DOUBLE : xvalue = &FILL_DOUBLE[0]; break;
+ case NC_UBYTE : xvalue = &FILL_UBYTE[0]; break;
+ case NC_USHORT : xvalue = &FILL_USHORT[0]; break;
+ case NC_UINT : xvalue = &FILL_UINT[0]; break;
+ case NC_INT64 : xvalue = &FILL_INT64[0]; break;
+ case NC_UINT64 : xvalue = &FILL_UINT64[0]; break;
+ default : DEBUG_RETURN_ERROR(NC_EBADTYPE)
+ }
+
+ char *bufp = buf;
+ for (i=0; i<bnelems; i++) {
+ memcpy(bufp, xvalue, (size_t)varp->xsz);
+ bufp += varp->xsz;
+ }
+ }
+ return NC_NOERR;
+}
+
+/*----< ncmpii_fill_var() >--------------------------------------------------*/
+/* If the variable is fixed-size, then write the entire variable with fill
+ * values and recno is ignored. If it is a record variable, then write one
+ * record of that variable with fill values.
+ */
+static int
+ncmpii_fill_var_rec(NC *ncp,
+ NC_var *varp,
+ MPI_Offset recno) /* record number */
+{
+ int err, mpireturn, rank, nprocs;
+ void *buf;
+ MPI_Offset var_len, start, count, offset;
+ MPI_File fh;
+ MPI_Status mpistatus;
+
+ MPI_Comm_rank(ncp->nciop->comm, &rank);
+ MPI_Comm_size(ncp->nciop->comm, &nprocs);
+
+ if (varp->ndims == 0) /* scalar variable */
+ var_len = 1;
+ else if (varp->ndims == 1 && IS_RECVAR(varp))
+ var_len = 1;
+ else if (IS_RECVAR(varp))
+ var_len = varp->dsizes[1];
+ else
+ var_len = varp->dsizes[0];
+
+ /* divide total number of elements of this variable among all processes */
+ count = var_len / nprocs;
+ start = count * rank;
+ if (rank < var_len % nprocs) {
+ start += rank;
+ count++;
+ }
+ else {
+ start += var_len % nprocs;
+ }
+
+ /* allocate buffer space */
+ buf = NCI_Malloc((size_t)(count * varp->xsz));
+
+ /* fill buffer with file values */
+ err = ncmpii_fill_var_buf(varp, count, buf);
+ if (err != NC_NOERR) return err;
+
+ offset = varp->begin;
+ if (IS_RECVAR(varp))
+ offset += ncp->recsize * recno;
+ offset += start * varp->xsz;
+
+ fh = ncp->nciop->collective_fh;
+
+ /* make the entire file visible */
+ TRACE_IO(MPI_File_set_view)(fh, 0, MPI_BYTE, MPI_BYTE, "native",
+ MPI_INFO_NULL);
+
+ count *= varp->xsz;
+ if (count != (int)count) DEBUG_ASSIGN_ERROR(err, NC_EINTOVERFLOW)
+ TRACE_IO(MPI_File_write_at_all)(fh, offset, buf, (int)count,
+ MPI_BYTE, &mpistatus);
+ NCI_Free(buf);
+
+ if (err != NC_NOERR) return err;
+
+ if (mpireturn != MPI_SUCCESS)
+ return ncmpii_handle_error(mpireturn, "MPI_File_write_at_all");
+
+ if (IS_RECVAR(varp)) { /* update header's number of records in memory */
+ err = ncmpii_sync_numrecs(ncp, recno+1);
+ if (err == NC_NOERR) return err;
+ }
+
+ return NC_NOERR;
+}
+
+/*----< ncmpi_fill_var() >---------------------------------------------------*/
+/* fill an entire record of a record variable
+ * this API is collective, must be called in data mode */
+int
+ncmpi_fill_var_rec(int ncid,
+ int varid,
+ MPI_Offset recno) /* record number, ignored if non-record var */
+{
+ int indx, err;
+ NC *ncp;
+ NC_var *varp;
+
+ /* check if ncid is valid */
+ err = ncmpii_NC_check_id(ncid, &ncp);
+ if (err != NC_NOERR) return err;
+
+ if (NC_readonly(ncp)) DEBUG_RETURN_ERROR(NC_EPERM) /* read-only */
+
+ /* This must be called in data mode */
+ if (NC_indef(ncp)) DEBUG_RETURN_ERROR(NC_EINDEFINE)
+
+ /* must be called in collective data mode */
+ if (NC_indep(ncp)) DEBUG_RETURN_ERROR(NC_EINDEP)
+
+ err = ncmpii_NC_lookupvar(ncp, varid, &varp);
+ if (err != NC_NOERR) return err;
+
+ /* error if this is not a record variable */
+ if (!IS_RECVAR(varp)) DEBUG_RETURN_ERROR(NC_ENOTRECVAR)
+
+ /* check if _FillValue attribute is defined */
+ indx = ncmpii_NC_findattr(&varp->attrs, _FillValue);
+
+ /* error if the fill mode of this variable is not on */
+ if (varp->no_fill && indx == -1) DEBUG_RETURN_ERROR(NC_ENOTFILL)
+
+ return ncmpii_fill_var_rec(ncp, varp, recno);
+}
+
+/*----< ncmpi_set_fill() >---------------------------------------------------*/
+/* this API is collective, must be called in define mode, contrary to netCDF
+ * where nc_set_fill() can also be called in data mode. The reason of PnetCDF
+ * enforcing this requirement is because PnetCDF only fills fix-sized variables
+ * at ncmpi_enddef() and record variables in ncmpi_fill_var_rec().
+ */
+int
+ncmpi_set_fill(int ncid,
+ int fill_mode,
+ int *old_fill_mode)
+{
+ int i, status=NC_NOERR, mpireturn, oldmode;
+ NC *ncp;
+
+ status = ncmpii_NC_check_id(ncid, &ncp);
+ if (status != NC_NOERR) return status;
+
+ if (NC_readonly(ncp)) DEBUG_RETURN_ERROR(NC_EPERM) /* read-only */
+
+ /* check if called in define mode */
+ if (!NC_indef(ncp)) DEBUG_RETURN_ERROR(NC_ENOTINDEFINE)
+
+ if (ncp->safe_mode) {
+ int root_fill_mode=fill_mode;
+ TRACE_COMM(MPI_Bcast)(&root_fill_mode, 1, MPI_INT, 0, ncp->nciop->comm);
+ if (mpireturn != MPI_SUCCESS)
+ return ncmpii_handle_error(mpireturn, "MPI_Bcast");
+ if (fill_mode != root_fill_mode) {
+ /* dataset's fill mode is inconsistent with root's */
+ printf("Warning: fill mode set in %s() is inconsistent\n", __func__);
+ DEBUG_ASSIGN_ERROR(status, NC_EMULTIDEFINE_FILL_MODE)
+ }
+ }
+
+ oldmode = fIsSet(ncp->flags, NC_NOFILL) ? NC_NOFILL : NC_FILL;
+
+ if (fill_mode == NC_NOFILL)
+ fSet(ncp->flags, NC_NOFILL);
+ else if (fill_mode == NC_FILL)
+ fClr(ncp->flags, NC_NOFILL);
+ else
+ DEBUG_RETURN_ERROR(NC_EINVAL) /* Invalid fill_mode */
+
+ if (old_fill_mode != NULL) *old_fill_mode = oldmode;
+
+ /* loop thru all variables defined so far to set/overwrite its fill mode */
+ for (i=0; i<ncp->vars.ndefined; i++)
+ ncp->vars.value[i]->no_fill = (fill_mode == NC_NOFILL) ? 1 : 0;
+
+ /* once the file's fill mode is set, any new variables defined after this
+ * call will check NC_dofill(ncp) and set their no_fill accordingly. See
+ * ncmpi_def_var() */
+
+ return status;
+}
+
+/*----< ncmpi_def_var_fill() >------------------------------------------------*/
+/* this API is collective, and must be called in define mode */
+int
+ncmpi_def_var_fill(int ncid,
+ int varid,
+ int no_fill, /* 1: no fill, 0: fill */
+ void *fill_value) /* when NULL, use default fill value */
+{
+ int err, status=NC_NOERR, mpireturn, free_fill_value=0;
+ NC *ncp;
+ NC_var *varp;
+
+ err = ncmpii_NC_check_id(ncid, &ncp);
+ if (err != NC_NOERR) return err;
+
+ if (NC_readonly(ncp)) DEBUG_RETURN_ERROR(NC_EPERM) /* read-only */
+
+ /* must be called in define mode */
+ if (!NC_indef(ncp)) DEBUG_RETURN_ERROR(NC_ENOTINDEFINE)
+
+ /* find the pointer to this variable's object */
+ err = ncmpii_NC_lookupvar(ncp, varid, &varp);
+ if (err != NC_NOERR) return err;
+
+ if (ncp->safe_mode) {
+ int root_no_fill=no_fill;
+ TRACE_COMM(MPI_Bcast)(&root_no_fill, 1, MPI_INT, 0, ncp->nciop->comm);
+ if (mpireturn != MPI_SUCCESS)
+ return ncmpii_handle_error(mpireturn, "MPI_Bcast");
+
+ if (no_fill != root_no_fill) {
+ /* variable's fill mode is inconsistent with root's */
+ printf("Warning: variable (%s) fill mode (%d) set in %s() is inconsistent\n",
+ varp->name->cp, no_fill, __func__);
+ if (status == NC_NOERR) DEBUG_ASSIGN_ERROR(status, NC_EMULTIDEFINE_VAR_FILL_MODE)
+ }
+
+ /* check if fill_value is consistent among processes */
+ void *root_fill_value = NCI_Malloc((size_t)varp->xsz);
+ if (fill_value == NULL) {
+ /* user intends to use default fill value */
+ fill_value = NCI_Malloc((size_t)varp->xsz);
+ err = inq_default_fill_value(varp->type, fill_value);
+ if (err != NC_NOERR) return err;
+ free_fill_value=1;
+ }
+ memcpy(root_fill_value, fill_value, (size_t)varp->xsz);
+
+ TRACE_COMM(MPI_Bcast)(root_fill_value, varp->xsz, MPI_BYTE, 0, ncp->nciop->comm);
+ if (memcmp(fill_value, root_fill_value, (size_t)varp->xsz)) {
+ /* variable's fill value is inconsistent with root's */
+ printf("Warning: variable (%s) fill value set in %s() is inconsistent\n",
+ varp->name->cp, __func__);
+ if (status == NC_NOERR) DEBUG_ASSIGN_ERROR(status, NC_EMULTIDEFINE_VAR_FILL_VALUE)
+ }
+ if (free_fill_value) {
+ NCI_Free(fill_value);
+ fill_value = NULL;
+ }
+ NCI_Free(root_fill_value);
+ }
+
+ if (no_fill)
+ varp->no_fill = 1;
+ else
+ varp->no_fill = 0;
+
+ /* Are we setting a fill value? */
+ if (fill_value != NULL && !varp->no_fill) {
+
+ /* If there's a _FillValue attribute, delete it. */
+ err = ncmpi_del_att(ncid, varid, _FillValue);
+ if (err != NC_NOERR && err != NC_ENOTATT)
+ return err;
+
+ /* Create a _FillValue attribute. */
+ err = ncmpi_put_att(ncid, varid, _FillValue, varp->type, 1, fill_value);
+ if (err != NC_NOERR) return err;
+ }
+
+ return status;
+}
+
+/*----< ncmpi_inq_var_fill() >-----------------------------------------------*/
+/* this API can be called independently and in both data and define mode */
+int
+ncmpi_inq_var_fill(int ncid,
+ int varid,
+ int *no_fill, /* OUT: 1 not fill mode, 0 fill mode */
+ void *fill_value) /* OUT: user-defined or default fill value */
+{
+ int err;
+ NC *ncp;
+ NC_var *varp;
+
+ err = ncmpii_NC_check_id(ncid, &ncp);
+ if (err != NC_NOERR) return err;
+
+ /* find the pointer to this variable's object */
+ err = ncmpii_NC_lookupvar(ncp, varid, &varp);
+ if (err != NC_NOERR) return err;
+
+ *no_fill = varp->no_fill;
+
+ if (fill_value != NULL) {
+ err = ncmpi_get_att(ncid, varid, _FillValue, fill_value);
+ if (err != NC_NOERR && err != NC_ENOTATT)
+ return err;
+ if (err == NC_ENOTATT) {
+ err = inq_default_fill_value(varp->type, fill_value);
+ if (err != NC_NOERR) return err;
+ }
+ }
+
+ return NC_NOERR;
+}
+
+/*----< fillerup() >---------------------------------------------------------*/
+/* fill the newly created variables */
+static int
+fillerup(NC *ncp)
+{
+ int i, indx, err=NC_NOERR;
+
+ /* loop thru all variables */
+ for (i=0; i<ncp->vars.ndefined; i++) {
+ if (IS_RECVAR(ncp->vars.value[i]))
+ /* skip record variables */
+ continue;
+
+ /* check if _FillValue attribute is defined */
+ indx = ncmpii_NC_findattr(&ncp->vars.value[i]->attrs, _FillValue);
+
+ /* only if filling this variable is requested */
+ if (ncp->vars.value[i]->no_fill && indx == -1) continue;
+
+ /* collectively fill the entire variable */
+ err = ncmpii_fill_var_rec(ncp, ncp->vars.value[i], 0);
+ if (err != NC_NOERR) break;
+ }
+ return err;
+}
+
+/*----< fill_added() >-------------------------------------------------------*/
+/* fill the newly added variables */
+static int
+fill_added(NC *ncp, NC *old_ncp)
+{
+ int indx, err=NC_NOERR, varid;
+
+ /* loop thru all new variables */
+ varid = old_ncp->vars.ndefined;
+ for (; varid<ncp->vars.ndefined; varid++) {
+ if (IS_RECVAR(ncp->vars.value[varid]))
+ /* skip record variables */
+ continue;
+
+ /* check if _FillValue attribute is defined */
+ indx = ncmpii_NC_findattr(&ncp->vars.value[varid]->attrs, _FillValue);
+
+ /* only if filling this variable is requested */
+ if (ncp->vars.value[varid]->no_fill && indx == -1) continue;
+
+ /* collectively fill the entire variable */
+ err = ncmpii_fill_var_rec(ncp, ncp->vars.value[varid], 0);
+ if (err != NC_NOERR) break;
+ }
+ return err;
+}
+
+/*----< fill_added_recs() >--------------------------------------------------*/
+/* for each newly added record variable, we fill the records one at a time */
+static int
+fill_added_recs(NC *ncp, NC *old_ncp)
+{
+ MPI_Offset old_nrecs = NC_get_numrecs(old_ncp);
+ int indx, err, recno, varid;
+
+ /* loop thru all old records */
+ for (recno=0; recno<old_nrecs; recno++) {
+ /* check newly added variables only */
+ for (varid=old_ncp->vars.ndefined; varid<ncp->vars.ndefined; varid++) {
+ if (!IS_RECVAR(ncp->vars.value[varid]))
+ /* skip non-record variables */
+ continue;
+
+ /* check if _FillValue attribute is defined */
+ indx = ncmpii_NC_findattr(&ncp->vars.value[varid]->attrs, _FillValue);
+
+ /* only if filling this variable is requested */
+ if (ncp->vars.value[varid]->no_fill && indx == -1) continue;
+
+ /* collectively fill the record */
+ err = ncmpii_fill_var_rec(ncp, ncp->vars.value[varid], recno);
+ if (err != NC_NOERR) return err;
+ }
+ }
+ return NC_NOERR;
+}
+
+/*----< ncmpii_fill_vars() >-------------------------------------------------*/
+int
+ncmpii_fill_vars(NC *ncp)
+{
+ int status=NC_NOERR, err;
+
+ /* fill variables according to their fill mode settings */
+ if (NC_IsNew(ncp)) {
+ status = fillerup(ncp);
+ }
+ else if (ncp->vars.ndefined > ncp->old->vars.ndefined) {
+ status = fill_added(ncp, ncp->old);
+
+ err = fill_added_recs(ncp, ncp->old);
+ if (status == NC_NOERR) status = err;
+ }
+ return status;
+}
+
diff --git a/src/lib/getput.m4 b/src/lib/getput.m4
new file mode 100644
index 0000000..4d3cbe1
--- /dev/null
+++ b/src/lib/getput.m4
@@ -0,0 +1,1246 @@
+dnl Process this m4 file to produce 'C' language file.
+dnl
+dnl If you see this line, you can ignore the next one.
+/* Do not edit this file. It is produced from the corresponding .m4 source */
+dnl
+/*
+ * Copyright (C) 2003, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ */
+/* $Id: getput.m4 2290 2016-01-02 18:37:46Z wkliao $ */
+
+#if HAVE_CONFIG_H
+# include "ncconfig.h"
+#endif
+
+#include <stdio.h>
+#include <unistd.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#include <string.h> /* memcpy() */
+#include <assert.h>
+
+#include <mpi.h>
+
+#include "nc.h"
+#include "ncx.h"
+#include "ncmpidtype.h"
+#include "macro.h"
+#ifdef ENABLE_SUBFILING
+#include "subfile.h"
+#endif
+
+
+/*----< ncmpii_calc_datatype_elems() >---------------------------------------*/
+/* check NC_ECHAR and obtain the following metadata about buftype:
+ * ptype: element data type (MPI primitive type) in buftype
+ * bufcount: If it is -1, then this is called from a high-level API and in
+ * this case buftype will be an MPI primitive data type. If not, then this
+ * is called from a flexible API. In that case, we recalculate bufcount to
+ * match with count[].
+ * bnelems: number of ptypes in user buffer
+ * nbytes: number of bytes (in external data representation) to read/write
+ * from/to the file
+ * el_size: size of ptype
+ * buftype_is_contig: whether buftype is contiguous
+ */
+int
+ncmpii_calc_datatype_elems(NC *ncp,
+ NC_var *varp,
+ const MPI_Offset *start,
+ const MPI_Offset *count,
+ const MPI_Offset *stride,
+ int rw_flag,
+ MPI_Datatype buftype,
+ MPI_Datatype *ptype, /* out */
+ MPI_Offset *bufcount, /* out */
+ MPI_Offset *bnelems, /* out */
+ MPI_Offset *nbytes, /* out */
+ int *el_size, /* out */
+ int *buftype_is_contig) /* out */
+{
+ int i, err=NC_NOERR;
+ MPI_Offset fnelems;
+
+ /* In netCDF, error code reporting priority is NC_ECHAR, NC_EINVALCOORDS,
+ * NC_EEDGE, NC_ESTRIDE
+ */
+ if (*bufcount == -1) { /* same as if (IsPrimityMPIType(buftype)) */
+ /* this subroutine is called from a high-level API */
+ err = NCMPII_ECHAR(varp->type, buftype);
+ if (err != NC_NOERR) return err;
+ }
+ else if (buftype != MPI_DATATYPE_NULL) {
+ /* This subroutine is called from a flexible API */
+ int isderived;
+ err = ncmpii_dtype_decode(buftype, ptype, el_size, bnelems,
+ &isderived, buftype_is_contig);
+ if (err != NC_NOERR) return err;
+
+ err = NCMPII_ECHAR(varp->type, *ptype);
+ if (err != NC_NOERR) return err;
+ }
+
+ /* check whether start, count, and stride are valid */
+ err = NC_start_count_stride_ck(ncp, varp, start, count, stride, rw_flag);
+ if (err != NC_NOERR) return err;
+
+ /* fnelems is the total number of nc_type elements calculated from
+ * count[]. count[] is the access count to the variable defined in
+ * the netCDF file.
+ */
+ fnelems = 1;
+ for (i=0; i<varp->ndims; i++)
+ fnelems *= count[i];
+
+ if (*bufcount == -1) { /* if (IsPrimityMPIType(buftype)) */
+ /* this subroutine is called from a high-level API */
+ *bnelems = *bufcount = fnelems;
+ *ptype = buftype;
+ MPI_Type_size(buftype, el_size); /* buffer element size */
+ *buftype_is_contig = 1;
+ /* nbytes is the amount in bytes of this request to file */
+ *nbytes = *bnelems * varp->xsz; /* varp->xsz is external element size */
+ }
+ else if (buftype == MPI_DATATYPE_NULL) {
+ /* This is called from a flexible API and buftype is set by user
+ * to MPI_DATATYPE_NULL. In this case, bufcount is set to match
+ * count[], and buf's data type to match the data type of variable
+ * defined in the file - no data conversion will be done.
+ */
+ *bnelems = *bufcount = fnelems;
+ *ptype = buftype = ncmpii_nc2mpitype(varp->type);
+ *el_size = varp->xsz;
+ *buftype_is_contig = 1;
+ /* nbytes is the amount in bytes of this request to file */
+ *nbytes = *bnelems * varp->xsz;
+ }
+ else {
+ /* This is called from a flexible API */
+
+ /* make bnelems the number of ptype in the whole user buf */
+ *bnelems *= *bufcount;
+
+ /* check mismatch between bnelems and fnelems */
+ if (fnelems != *bnelems) {
+ DEBUG_ASSIGN_ERROR(err, NC_EIOMISMATCH)
+ (fnelems>*bnelems) ? (fnelems=*bnelems) : (*bnelems=fnelems);
+ /* only handle partial of the request, smaller number of the two */
+ }
+ /* now fnelems == *bnelems */
+
+ /* nbytes is the amount in bytes of this request to file */
+ *nbytes = *bnelems * varp->xsz;
+ }
+ return err;
+}
+
+/*----< ncmpii_create_imaptype() >-------------------------------------------*/
+/* Check if a request is a true varm call. If yes, create an MPI derived
+ * data type, imaptype, using imap[]
+ */
+int
+ncmpii_create_imaptype(NC_var *varp,
+ const MPI_Offset *count,
+ const MPI_Offset *imap,
+ const MPI_Offset bnelems, /* no. elements in user buf */
+ const int el_size, /* user buf element size */
+ MPI_Datatype ptype, /* element type in buftype */
+ MPI_Datatype *imaptype)/* out */
+{
+ int dim;
+ MPI_Offset imap_contig_blocklen;
+
+ /* check if this is a vars call or a true varm call */
+ *imaptype = MPI_DATATYPE_NULL;
+
+ if (varp->ndims == 0) /* scalar var, only one value at one fixed place */
+ return NC_NOERR;
+
+ if (bnelems == 1) /* one element, same as var1 */
+ return NC_NOERR;
+
+ if (imap == NULL) /* no mapping, same as vars */
+ return NC_NOERR;
+
+ /* test each dim's contiguity in imap[] until the 1st non-contiguous
+ * dim is reached */
+ imap_contig_blocklen = 1;
+ dim = varp->ndims;
+ while (--dim >= 0 && imap_contig_blocklen == imap[dim])
+ imap_contig_blocklen *= count[dim];
+
+ if (dim == -1) /* imap is a contiguous layout */
+ return NC_NOERR;
+
+ /* We have a true varm call, as imap gives non-contiguous layout.
+ * User buffer will be packed (write case) or unpacked (read case)
+ * to/from a contiguous buffer based on imap[], before MPI-IO.
+ * First, we construct a derived data type, imaptype, based on
+ * imap[], and use it to pack lbuf to cbuf (for write), or unpack
+ * cbuf to lbuf (for read).
+ * dim is the first dimension (C order, eg. ZYX) that has
+ * non-contiguous imap.
+ */
+ if (imap_contig_blocklen != (int)imap_contig_blocklen)
+ DEBUG_RETURN_ERROR(NC_EINTOVERFLOW)
+ if (count[dim] != (int)count[dim] || imap[dim] != (int)imap[dim])
+ DEBUG_RETURN_ERROR(NC_EINTOVERFLOW)
+
+ MPI_Type_vector((int)count[dim], (int)imap_contig_blocklen, (int)imap[dim],
+ ptype, imaptype);
+ MPI_Type_commit(imaptype);
+
+ for (dim--; dim>=0; dim--) {
+ MPI_Datatype tmptype;
+ if (count[dim] != (int)count[dim])
+ DEBUG_RETURN_ERROR(NC_EINTOVERFLOW)
+#ifdef HAVE_MPI_TYPE_CREATE_HVECTOR
+ MPI_Type_create_hvector((int)count[dim], 1, imap[dim]*el_size,
+ *imaptype, &tmptype);
+#else
+ MPI_Type_hvector((int)count[dim], 1, imap[dim]*el_size, *imaptype,
+ &tmptype);
+#endif
+ MPI_Type_free(imaptype);
+ MPI_Type_commit(&tmptype);
+ *imaptype = tmptype;
+ }
+ return NC_NOERR;
+}
+
+/*----< ncmpii_getput_varm() >------------------------------------------------*/
+/* buffer layers:
+
+ User Level buf (user defined buffer of MPI_Datatype)
+ MPI Datatype Level cbuf (contiguous buffer of ptype)
+ NetCDF XDR Level xbuf (XDR I/O buffer)
+
+ varm: there maybe two layer of memory layout (remapping):
+ one is specified by MPI derived datatype,
+ the other is specified by imap[],
+ it's encouraged to use only one option of them,
+ though using both of them are supported.
+
+ user buffer: |--------------------------|
+
+ mpi derived datatype view: |------| |------| |------|
+
+ logic (contig) memory datastream: |------|------|------|
+
+ imap view: |--| |--| |--| |--|
+
+ contig I/O datastream (internal represent): |--|--|--|--|
+
+ These two layers of memory layout will both be represented in MPI
+ derived datatype, and if double layers of memory layout is used,
+ we need to eliminate the upper one passed in MPI_Datatype parameter
+ from the user, by packing it to logic contig memory datastream view.
+
+ for put_varm:
+ 1. pack buf to lbuf based on buftype
+ 2. create imap_type based on imap
+ 3. pack lbuf to cbuf based on imap_type
+ 4. type convert and byte swap cbuf to xbuf
+ 5. write from xbuf
+ 6. byte swap the buf, if it is swapped
+ 7. free up temp buffers
+
+ for get_varm:
+ 1. allocate lbuf
+ 2. create imap_type based on imap
+ 3. allocate cbuf
+ 4. allocate xbuf
+ 5. read to xbuf
+ 6. type convert and byte swap xbuf to cbuf
+ 7. unpack cbuf to lbuf based on imap_type
+ 8. unpack lbuf to buf based on buftype
+*/
+
+static int
+ncmpii_getput_varm(NC *ncp,
+ NC_var *varp,
+ const MPI_Offset start[],
+ const MPI_Offset count[],
+ const MPI_Offset stride[], /* can be NULL */
+ const MPI_Offset imap[], /* can be NULL */
+ void *buf,
+ MPI_Offset bufcount, /* -1: from high-level API */
+ MPI_Datatype buftype,
+ int rw_flag, /* WRITE_REQ or READ_REQ */
+ int io_method) /* COLL_IO or INDEP_IO */
+{
+ void *lbuf=NULL, *cbuf=NULL, *xbuf=NULL;
+ int mpireturn, err=NC_NOERR, status=NC_NOERR, warning=NC_NOERR;
+ int el_size, buftype_is_contig;
+ int need_swap=0, need_convert=0, need_swap_back_buf=0;
+ MPI_Offset bnelems=0, nbytes=0, offset=0;
+ MPI_Status mpistatus;
+ MPI_Datatype ptype, filetype=MPI_BYTE, imaptype=MPI_DATATYPE_NULL;
+ MPI_File fh;
+
+#ifdef ENABLE_SUBFILING
+ /* call a separate routine if variable is stored in subfiles */
+ if (varp->num_subfiles > 1) {
+#ifdef SUBFILE_DEBUG
+ printf("var(%s) is stored in subfiles\n", varp->name->cp);
+#endif
+ if (imap != NULL) {
+ fprintf(stderr, "varm APIs for subfiling is yet to be implemented\n");
+ DEBUG_RETURN_ERROR(NC_ENOTSUPPORT)
+ }
+
+ return ncmpii_subfile_getput_vars(ncp, varp, start, count, stride,
+ buf, bufcount, buftype,
+ rw_flag, io_method);
+ }
+#endif
+
+ /* check NC_ECHAR error and calculate the followings:
+ * ptype: element data type (MPI primitive type) in buftype
+ * bufcount: If it is -1, then this is called from a high-level API and in
+ * this case buftype will be an MPI primitive data type. If not, then this
+ * is called from a flexible API. In that case, we recalculate bufcount to
+ * match with count[].
+ * bnelems: number of ptypes in user buffer
+ * nbytes: number of bytes (in external data representation) to read/write
+ * from/to the file
+ * el_size: size of ptype
+ * buftype_is_contig: whether buftype is contiguous
+ */
+ err = ncmpii_calc_datatype_elems(ncp, varp, start, count, stride, rw_flag,
+ buftype, &ptype, &bufcount, &bnelems,
+ &nbytes, &el_size, &buftype_is_contig);
+ if (err == NC_EIOMISMATCH) DEBUG_ASSIGN_ERROR(warning, err)
+ else if (err != NC_NOERR) goto err_check;
+
+ /* because nbytes will be used as the argument "count" in MPI-IO
+ * read/write calls and the argument "count" is of type int */
+ if (nbytes != (int)nbytes) {
+ DEBUG_ASSIGN_ERROR(err, NC_EINTOVERFLOW)
+ goto err_check;
+ }
+
+ if (nbytes == 0) /* this process has nothing to read/write */
+ goto err_check;
+
+ /* TODO: if record variables are too big (so big that we cannot store the
+ * stride between records in an MPI_Aint, for example) then we will
+ * have to process this one record at a time.
+ */
+
+ /* Create the filetype for this request and calculate the beginning
+ * file offset for this request. If this request is contiguous in file,
+ * then filetype == MPI_BYTE. Otherwise filetype will be an MPI derived
+ * data type.
+ */
+ err = ncmpii_vars_create_filetype(ncp, varp, start, count, stride, rw_flag,
+ NULL, &offset, &filetype, NULL);
+ if (err != NC_NOERR) goto err_check;
+
+ if (bufcount != (int)bufcount) DEBUG_ASSIGN_ERROR(err, NC_EINTOVERFLOW)
+
+err_check:
+ /* If io_method is COLL_IO and an error occurs, we'll still conduct a
+ * zero-byte read/write (because every process must participate the
+ * collective I/O call).
+ */
+ if (err != NC_NOERR || nbytes == 0) {
+ if (io_method == INDEP_IO) return err;
+
+ /* COLL_IO: participate the collective I/O operations */
+ filetype = MPI_BYTE;
+ status = err;
+ nbytes = 0;
+ goto mpi_io;
+ }
+
+ /* check if type conversion and Endianness byte swap is needed */
+ need_convert = ncmpii_need_convert(varp->type, ptype);
+ need_swap = ncmpii_need_swap(varp->type, ptype);
+
+ /* Check if this is a vars call or a true varm call.
+ * Construct a derived datatype, imaptype, if a true varm call
+ */
+ err = ncmpii_create_imaptype(varp, count, imap, bnelems, el_size, ptype,
+ &imaptype);
+ if (status == NC_NOERR) status = err;
+
+ if (rw_flag == WRITE_REQ) { /* pack request to xbuf */
+ int position;
+ MPI_Offset outsize=bnelems*el_size;
+ /* assert(bnelems > 0); */
+ if (outsize != (int)outsize && status == NC_NOERR)
+ DEBUG_ASSIGN_ERROR(status, NC_EINTOVERFLOW)
+
+ /* Step 1: pack buf into a contiguous buffer, lbuf */
+ if (!buftype_is_contig) { /* buftype is not contiguous */
+ /* pack buf into lbuf, a contiguous buffer, using buftype */
+ lbuf = NCI_Malloc((size_t)outsize);
+ position = 0;
+ MPI_Pack(buf, (int)bufcount, buftype, lbuf, (int)outsize,
+ &position, MPI_COMM_SELF);
+ }
+ else
+ lbuf = buf;
+
+ /* Step 2: pack lbuf to cbuf if imap is non-contiguous */
+ if (imaptype != MPI_DATATYPE_NULL) { /* true varm */
+ /* pack lbuf to cbuf, a contiguous buffer, using imaptype */
+ cbuf = NCI_Malloc((size_t)outsize);
+ position = 0;
+ MPI_Pack(lbuf, 1, imaptype, cbuf, (int)outsize, &position,
+ MPI_COMM_SELF);
+ MPI_Type_free(&imaptype);
+ }
+ else /* reuse lbuf */
+ cbuf = lbuf;
+
+ /* lbuf is no longer needed */
+ if (lbuf != buf && lbuf != cbuf) NCI_Free(lbuf);
+
+ /* Step 3: pack cbuf to xbuf. The contents of xbuf will be in the
+ * external representation, ready to be written to file.
+ */
+ xbuf = cbuf;
+ if (need_convert) { /* user buf type != nc var type defined in file */
+ xbuf = NCI_Malloc((size_t)nbytes);
+
+ /* datatype conversion + byte-swap from cbuf to xbuf */
+ DATATYPE_PUT_CONVERT(varp->type, xbuf, cbuf, bnelems, ptype, status)
+ /* NC_ERANGE can be caused by a subset of buf that is out of range
+ * of the external data type, it is not considered a fatal error.
+ * The request must continue to finish.
+ */
+ if (status != NC_NOERR && status != NC_ERANGE) {
+ if (cbuf != buf) NCI_Free(cbuf);
+ NCI_Free(xbuf);
+ xbuf = NULL;
+ if (io_method == INDEP_IO) return status;
+
+ /* COLL_IO: participate the collective I/O operations */
+ filetype = MPI_BYTE;
+ nbytes = 0;
+ goto mpi_io;
+ }
+ }
+ else if (need_swap) { /* no need to convert, just byte swap */
+#ifdef DISABLE_IN_PLACE_SWAP
+ if (cbuf == buf) {
+#else
+ if (cbuf == buf && nbytes <= NC_BYTE_SWAP_BUFFER_SIZE) {
+#endif
+ /* allocate cbuf and copy buf to xbuf, before byte-swap */
+ xbuf = NCI_Malloc((size_t)nbytes);
+ memcpy(xbuf, buf, nbytes);
+ }
+
+ /* perform array in-place byte-swap on xbuf */
+ ncmpii_in_swapn(xbuf, bnelems, ncmpix_len_nctype(varp->type));
+
+ if (xbuf == buf) need_swap_back_buf = 1;
+ /* user buf needs to be swapped back to its original contents */
+ }
+ /* cbuf is no longer needed */
+ if (cbuf != buf && cbuf != xbuf) NCI_Free(cbuf);
+ }
+ else { /* rw_flag == READ_REQ */
+ /* allocate xbuf for reading */
+ if (buftype_is_contig && imaptype == MPI_DATATYPE_NULL && !need_convert)
+ xbuf = buf;
+ else
+ xbuf = NCI_Malloc((size_t)nbytes);
+ }
+ /* xbuf is the buffer whose data has been converted into the external
+ * data type, ready to be written to the netCDF file. For read,
+ * after read from file, the contents of xbuf are in external type
+ */
+
+mpi_io:
+ if (io_method == COLL_IO)
+ fh = ncp->nciop->collective_fh;
+ else
+ fh = ncp->nciop->independent_fh;
+
+ /* MPI_File_set_view is collective */
+ err = ncmpii_file_set_view(ncp, fh, &offset, filetype);
+ if (err != NC_NOERR) {
+ nbytes = 0; /* skip this request */
+ if (status == NC_NOERR) status = err;
+ }
+ if (filetype != MPI_BYTE) MPI_Type_free(&filetype);
+
+ if (rw_flag == WRITE_REQ) {
+ if (io_method == COLL_IO) {
+ TRACE_IO(MPI_File_write_at_all)(fh, offset, xbuf, (int)nbytes,
+ MPI_BYTE, &mpistatus);
+ if (mpireturn != MPI_SUCCESS) {
+ err = ncmpii_handle_error(mpireturn, "MPI_File_write_at_all");
+ /* return the first encountered error if there is any */
+ if (status == NC_NOERR) {
+ status = (err == NC_EFILE) ? NC_EWRITE : err;
+ DEBUG_ASSIGN_ERROR(status, status)
+ }
+ }
+ }
+ else { /* io_method == INDEP_IO */
+ TRACE_IO(MPI_File_write_at)(fh, offset, xbuf, (int)nbytes,
+ MPI_BYTE, &mpistatus);
+ if (mpireturn != MPI_SUCCESS) {
+ err = ncmpii_handle_error(mpireturn, "MPI_File_write_at");
+ /* return the first encountered error if there is any */
+ if (status == NC_NOERR) {
+ status = (err == NC_EFILE) ? NC_EWRITE : err;
+ DEBUG_ASSIGN_ERROR(status, status)
+ }
+ }
+ }
+ int put_size;
+ MPI_Get_count(&mpistatus, MPI_BYTE, &put_size);
+ ncp->nciop->put_size += put_size;
+ }
+ else { /* rw_flag == READ_REQ */
+ if (io_method == COLL_IO) {
+ TRACE_IO(MPI_File_read_at_all)(fh, offset, xbuf, (int)nbytes,
+ MPI_BYTE, &mpistatus);
+ if (mpireturn != MPI_SUCCESS) {
+ err = ncmpii_handle_error(mpireturn, "MPI_File_read_at_all");
+ /* return the first encountered error if there is any */
+ if (status == NC_NOERR) {
+ status = (err == NC_EFILE) ? NC_EREAD : err;
+ DEBUG_ASSIGN_ERROR(status, status)
+ }
+ }
+ }
+ else { /* io_method == INDEP_IO */
+ TRACE_IO(MPI_File_read_at)(fh, offset, xbuf, (int)nbytes,
+ MPI_BYTE, &mpistatus);
+ if (mpireturn != MPI_SUCCESS) {
+ err = ncmpii_handle_error(mpireturn, "MPI_File_read_at");
+ /* return the first encountered error if there is any */
+ if (status == NC_NOERR) {
+ status = (err == NC_EFILE) ? NC_EREAD : err;
+ DEBUG_ASSIGN_ERROR(status, status)
+ }
+ }
+ }
+ int get_size;
+ MPI_Get_count(&mpistatus, MPI_BYTE, &get_size);
+ ncp->nciop->get_size += get_size;
+ }
+
+ /* No longer need to reset the file view, as the root's fileview includes
+ * the whole file header.
+ TRACE_IO(MPI_File_set_view)(fh, 0, MPI_BYTE, MPI_BYTE, "native",
+ MPI_INFO_NULL);
+ */
+
+ if (rw_flag == READ_REQ && nbytes > 0) {
+ /* xbuf contains the data read from file.
+ * Check if it needs to be type-converted + byte-swapped
+ */
+ int position;
+ MPI_Offset insize=bnelems*el_size;
+ if (insize != (int)insize && status == NC_NOERR)
+ DEBUG_ASSIGN_ERROR(status, NC_EINTOVERFLOW)
+
+ if (need_convert) {
+ /* xbuf cannot be buf, but cbuf can */
+ if (buftype_is_contig && imaptype == MPI_DATATYPE_NULL)
+ cbuf = buf; /* vars call and buftype is contiguous */
+ else
+ cbuf = NCI_Malloc((size_t)insize);
+
+ /* type conversion + byte-swap from xbuf to cbuf */
+ DATATYPE_GET_CONVERT(varp->type, xbuf, cbuf, bnelems, ptype, err)
+ /* retain the first error status */
+ if (status == NC_NOERR) status = err;
+ NCI_Free(xbuf);
+ } else {
+ if (need_swap) /* perform array in-place byte-swap on xbuf */
+ ncmpii_in_swapn(xbuf, bnelems, ncmpix_len_nctype(varp->type));
+ cbuf = xbuf;
+ }
+ /* done with xbuf */
+
+ /* varm && noncontig: cbuf -> lbuf -> buf
+ vars && noncontig: cbuf == lbuf -> buf
+ varm && contig: cbuf -> lbuf == buf
+ vars && contig: cbuf == lbuf == buf
+ */
+ if (imaptype != MPI_DATATYPE_NULL && !buftype_is_contig)
+ /* a true varm and buftype is not contiguous: we need a separate
+ * buffer, lbuf, to unpack cbuf to lbuf using imaptype, and later
+ * unpack lbuf to buf using buftype.
+ * In this case, cbuf cannot be buf and lbuf cannot be buf.
+ */
+ lbuf = NCI_Malloc((size_t)insize);
+ else if (imaptype == MPI_DATATYPE_NULL) /* not varm */
+ lbuf = cbuf;
+ else /* varm and buftype is contiguous */
+ lbuf = buf;
+
+ if (imaptype != MPI_DATATYPE_NULL) {
+ /* unpack cbuf to lbuf based on imaptype */
+ position = 0;
+ MPI_Unpack(cbuf, (int)insize, &position, lbuf, 1, imaptype,
+ MPI_COMM_SELF);
+ MPI_Type_free(&imaptype);
+ }
+ /* done with cbuf */
+ if (cbuf != lbuf) NCI_Free(cbuf);
+
+ if (!buftype_is_contig) {
+ /* unpack lbuf to buf based on buftype */
+ position = 0;
+ MPI_Unpack(lbuf, (int)insize, &position, buf, (int)bufcount,
+ buftype, MPI_COMM_SELF);
+ }
+ /* done with lbuf */
+ if (lbuf != buf) NCI_Free(lbuf);
+ }
+ else if (rw_flag == WRITE_REQ) {
+ if (xbuf != NULL && xbuf != buf) NCI_Free(xbuf);
+
+ if (need_swap_back_buf) /* byte-swap back to buf's original contents */
+ ncmpii_in_swapn(buf, bnelems, ncmpix_len_nctype(varp->type));
+
+ if (IS_RECVAR(varp)) {
+ /* update header's number of records in memory */
+ MPI_Offset new_numrecs = ncp->numrecs;
+
+ /* calculate the max record ID written by this request */
+ if (status == NC_NOERR) { /* do this only if no error */
+ if (stride == NULL)
+ new_numrecs = start[0] + count[0];
+ else
+ new_numrecs = start[0] + (count[0] - 1) * stride[0] + 1;
+
+ /* note new_numrecs can be smaller than ncp->numrecs */
+ }
+
+ if (io_method == INDEP_IO) {
+ /* For independent put, we delay the sync for numrecs until
+ * the next collective call, such as end_indep(), sync(),
+ * enddef(), or close(). This is because if we update numrecs
+ * to file now, race condition can happen. Note numrecs in
+ * memory may be inconsistent and obsolete till then.
+ */
+ if (ncp->numrecs < new_numrecs) {
+ ncp->numrecs = new_numrecs;
+ set_NC_ndirty(ncp);
+ }
+ }
+ else { /* COLL_IO: sync numrecs in memory and file */
+ /* In ncmpii_sync_numrecs(), new_numrecs is checked against
+ * ncp->numrecs.
+ */
+ err = ncmpii_sync_numrecs(ncp, new_numrecs);
+ if (status == NC_NOERR) status = err;
+ }
+ }
+
+ if (NC_doFsync(ncp)) { /* NC_SHARE is set */
+ TRACE_IO(MPI_File_sync)(fh);
+ if (io_method == COLL_IO)
+ TRACE_COMM(MPI_Barrier)(ncp->nciop->comm);
+ }
+ }
+
+ return ((warning != NC_NOERR) ? warning : status);
+}
+
+
+define(`CollIndep', `ifelse(`$1', `_all', `COLL_IO', `INDEP_IO')')dnl
+define(`ReadWrite', `ifelse(`$1', `get', `READ_REQ', `WRITE_REQ')')dnl
+define(`BufConst', `ifelse(`$1', `put', `const')')dnl
+
+dnl
+dnl VAR_FLEXIBLE
+dnl
+define(`VAR_FLEXIBLE',dnl
+`dnl
+/*----< ncmpi_$1_var$2() >---------------------------------------------------*/
+int
+ncmpi_$1_var$2(int ncid,
+ int varid,
+ BufConst($1) void *buf,
+ MPI_Offset bufcount,
+ MPI_Datatype buftype)
+{
+ int status;
+ NC *ncp;
+ NC_var *varp=NULL;
+ MPI_Offset *start, *count;
+
+ status = ncmpii_sanity_check(ncid, varid, NULL, NULL, bufcount, API_VAR,
+ 1, 1, ReadWrite($1), CollIndep($2), &ncp, &varp);
+ if (status != NC_NOERR) return status;
+
+ GET_FULL_DIMENSIONS(start, count)
+
+ /* $1_var is a special case of $1_varm */
+ status = ncmpii_getput_varm(ncp, varp, start, count, NULL, NULL, (void*)buf,
+ bufcount, buftype, ReadWrite($1),
+ CollIndep($2));
+ if (varp->ndims > 0) NCI_Free(start);
+ return status;
+}
+')dnl
+
+dnl PnetCDF flexible APIs
+VAR_FLEXIBLE(put)
+VAR_FLEXIBLE(get)
+VAR_FLEXIBLE(put, _all)
+VAR_FLEXIBLE(get, _all)
+
+dnl
+dnl VAR(ncid, varid, op)
+dnl
+define(`VAR',dnl
+`dnl
+/*----< ncmpi_$1_var_$3$2() >------------------------------------------------*/
+int
+ncmpi_$1_var_$3$2(int ncid,
+ int varid,
+ BufConst($1) $4 *op)
+{
+ int status;
+ NC *ncp;
+ NC_var *varp=NULL;
+ MPI_Offset *start, *count;
+
+ status = ncmpii_sanity_check(ncid, varid, NULL, NULL, 0, API_VAR,
+ 1, 0, ReadWrite($1), CollIndep($2), &ncp, &varp);
+ if (status != NC_NOERR) return status;
+
+ GET_FULL_DIMENSIONS(start, count)
+
+ /* $1_var is a special case of $1_varm */
+ status = ncmpii_getput_varm(ncp, varp, start, count, NULL, NULL, (void*)op,
+ -1, $5, ReadWrite($1), CollIndep($2));
+ if (varp->ndims > 0) NCI_Free(start);
+ return status;
+}
+')dnl
+
+VAR(put, , text, char, MPI_CHAR)
+VAR(put, , schar, schar, MPI_SIGNED_CHAR)
+VAR(put, , uchar, uchar, MPI_UNSIGNED_CHAR)
+VAR(put, , short, short, MPI_SHORT)
+VAR(put, , ushort, ushort, MPI_UNSIGNED_SHORT)
+VAR(put, , int, int, MPI_INT)
+VAR(put, , uint, uint, MPI_UNSIGNED)
+VAR(put, , long, long, MPI_LONG)
+VAR(put, , float, float, MPI_FLOAT)
+VAR(put, , double, double, MPI_DOUBLE)
+VAR(put, , longlong, long long, MPI_LONG_LONG_INT)
+VAR(put, , ulonglong, unsigned long long, MPI_UNSIGNED_LONG_LONG)
+
+VAR(put, _all, text, char, MPI_CHAR)
+VAR(put, _all, schar, schar, MPI_SIGNED_CHAR)
+VAR(put, _all, uchar, uchar, MPI_UNSIGNED_CHAR)
+VAR(put, _all, short, short, MPI_SHORT)
+VAR(put, _all, ushort, ushort, MPI_UNSIGNED_SHORT)
+VAR(put, _all, int, int, MPI_INT)
+VAR(put, _all, uint, uint, MPI_UNSIGNED)
+VAR(put, _all, long, long, MPI_LONG)
+VAR(put, _all, float, float, MPI_FLOAT)
+VAR(put, _all, double, double, MPI_DOUBLE)
+VAR(put, _all, longlong, long long, MPI_LONG_LONG_INT)
+VAR(put, _all, ulonglong, unsigned long long, MPI_UNSIGNED_LONG_LONG)
+
+VAR(get, , text, char, MPI_CHAR)
+VAR(get, , schar, schar, MPI_SIGNED_CHAR)
+VAR(get, , uchar, uchar, MPI_UNSIGNED_CHAR)
+VAR(get, , short, short, MPI_SHORT)
+VAR(get, , ushort, ushort, MPI_UNSIGNED_SHORT)
+VAR(get, , int, int, MPI_INT)
+VAR(get, , uint, uint, MPI_UNSIGNED)
+VAR(get, , long, long, MPI_LONG)
+VAR(get, , float, float, MPI_FLOAT)
+VAR(get, , double, double, MPI_DOUBLE)
+VAR(get, , longlong, long long, MPI_LONG_LONG_INT)
+VAR(get, , ulonglong, unsigned long long, MPI_UNSIGNED_LONG_LONG)
+
+VAR(get, _all, text, char, MPI_CHAR)
+VAR(get, _all, schar, schar, MPI_SIGNED_CHAR)
+VAR(get, _all, uchar, uchar, MPI_UNSIGNED_CHAR)
+VAR(get, _all, short, short, MPI_SHORT)
+VAR(get, _all, ushort, ushort, MPI_UNSIGNED_SHORT)
+VAR(get, _all, int, int, MPI_INT)
+VAR(get, _all, uint, uint, MPI_UNSIGNED)
+VAR(get, _all, long, long, MPI_LONG)
+VAR(get, _all, float, float, MPI_FLOAT)
+VAR(get, _all, double, double, MPI_DOUBLE)
+VAR(get, _all, longlong, long long, MPI_LONG_LONG_INT)
+VAR(get, _all, ulonglong, unsigned long long, MPI_UNSIGNED_LONG_LONG)
+
+dnl
+dnl VAR1_FLEXIBLE
+dnl
+define(`VAR1_FLEXIBLE',dnl
+`dnl
+/*----< ncmpi_$1_var1$2() >--------------------------------------------------*/
+int
+ncmpi_$1_var1$2(int ncid,
+ int varid,
+ const MPI_Offset start[],
+ BufConst($1) void *buf,
+ MPI_Offset bufcount,
+ MPI_Datatype buftype)
+{
+ int status;
+ NC *ncp;
+ NC_var *varp=NULL;
+ MPI_Offset *count;
+
+ status = ncmpii_sanity_check(ncid, varid, start, NULL, bufcount, API_VAR1,
+ 1, 1, ReadWrite($1), CollIndep($2), &ncp, &varp);
+ if (status != NC_NOERR) return status;
+
+ GET_ONE_COUNT(count)
+
+ status = ncmpii_getput_varm(ncp, varp, start, count, NULL, NULL, (void*)buf,
+ bufcount, buftype, ReadWrite($1),
+ CollIndep($2));
+ if (varp->ndims > 0) NCI_Free(count);
+ return status;
+}
+')dnl
+
+VAR1_FLEXIBLE(put)
+VAR1_FLEXIBLE(get)
+VAR1_FLEXIBLE(put, _all)
+VAR1_FLEXIBLE(get, _all)
+
+dnl
+dnl VAR1
+dnl
+define(`VAR1',dnl
+`dnl
+/*----< ncmpi_$1_var1_$3$2() >-----------------------------------------------*/
+int
+ncmpi_$1_var1_$3$2(int ncid,
+ int varid,
+ const MPI_Offset start[],
+ BufConst($1) $4 *op)
+{
+ int status;
+ NC *ncp;
+ NC_var *varp=NULL;
+ MPI_Offset *count;
+
+ status = ncmpii_sanity_check(ncid, varid, start, NULL, 0, API_VAR1,
+ 1, 0, ReadWrite($1), CollIndep($2), &ncp, &varp);
+ if (status != NC_NOERR) return status;
+
+ GET_ONE_COUNT(count)
+
+ /* $1_var1 is a special case of $1_varm */
+ status = ncmpii_getput_varm(ncp, varp, start, count, NULL, NULL, (void*)op,
+ -1, $5, ReadWrite($1), CollIndep($2));
+ if (varp->ndims > 0) NCI_Free(count);
+ return status;
+}
+')dnl
+
+VAR1(put, , text, char, MPI_CHAR)
+VAR1(put, , schar, schar, MPI_SIGNED_CHAR)
+VAR1(put, , uchar, uchar, MPI_UNSIGNED_CHAR)
+VAR1(put, , short, short, MPI_SHORT)
+VAR1(put, , ushort, ushort, MPI_UNSIGNED_SHORT)
+VAR1(put, , int, int, MPI_INT)
+VAR1(put, , uint, uint, MPI_UNSIGNED)
+VAR1(put, , long, long, MPI_LONG)
+VAR1(put, , float, float, MPI_FLOAT)
+VAR1(put, , double, double, MPI_DOUBLE)
+VAR1(put, , longlong, long long, MPI_LONG_LONG_INT)
+VAR1(put, , ulonglong, unsigned long long, MPI_UNSIGNED_LONG_LONG)
+
+VAR1(put, _all, text, char, MPI_CHAR)
+VAR1(put, _all, schar, schar, MPI_SIGNED_CHAR)
+VAR1(put, _all, uchar, uchar, MPI_UNSIGNED_CHAR)
+VAR1(put, _all, short, short, MPI_SHORT)
+VAR1(put, _all, ushort, ushort, MPI_UNSIGNED_SHORT)
+VAR1(put, _all, int, int, MPI_INT)
+VAR1(put, _all, uint, uint, MPI_UNSIGNED)
+VAR1(put, _all, long, long, MPI_LONG)
+VAR1(put, _all, float, float, MPI_FLOAT)
+VAR1(put, _all, double, double, MPI_DOUBLE)
+VAR1(put, _all, longlong, long long, MPI_LONG_LONG_INT)
+VAR1(put, _all, ulonglong, unsigned long long, MPI_UNSIGNED_LONG_LONG)
+
+VAR1(get, , text, char, MPI_CHAR)
+VAR1(get, , schar, schar, MPI_SIGNED_CHAR)
+VAR1(get, , uchar, uchar, MPI_UNSIGNED_CHAR)
+VAR1(get, , short, short, MPI_SHORT)
+VAR1(get, , ushort, ushort, MPI_UNSIGNED_SHORT)
+VAR1(get, , int, int, MPI_INT)
+VAR1(get, , uint, uint, MPI_UNSIGNED)
+VAR1(get, , long, long, MPI_LONG)
+VAR1(get, , float, float, MPI_FLOAT)
+VAR1(get, , double, double, MPI_DOUBLE)
+VAR1(get, , longlong, long long, MPI_LONG_LONG_INT)
+VAR1(get, , ulonglong, unsigned long long, MPI_UNSIGNED_LONG_LONG)
+
+VAR1(get, _all, text, char, MPI_CHAR)
+VAR1(get, _all, schar, schar, MPI_SIGNED_CHAR)
+VAR1(get, _all, uchar, uchar, MPI_UNSIGNED_CHAR)
+VAR1(get, _all, short, short, MPI_SHORT)
+VAR1(get, _all, ushort, ushort, MPI_UNSIGNED_SHORT)
+VAR1(get, _all, int, int, MPI_INT)
+VAR1(get, _all, uint, uint, MPI_UNSIGNED)
+VAR1(get, _all, long, long, MPI_LONG)
+VAR1(get, _all, float, float, MPI_FLOAT)
+VAR1(get, _all, double, double, MPI_DOUBLE)
+VAR1(get, _all, longlong, long long, MPI_LONG_LONG_INT)
+VAR1(get, _all, ulonglong, unsigned long long, MPI_UNSIGNED_LONG_LONG)
+
+dnl
+dnl VARA_FLEXIBLE
+dnl
+define(`VARA_FLEXIBLE',dnl
+`dnl
+/*----< ncmpi_$1_vara$2() >--------------------------------------------------*/
+int
+ncmpi_$1_vara$2(int ncid,
+ int varid,
+ const MPI_Offset start[],
+ const MPI_Offset count[],
+ BufConst($1) void *buf,
+ MPI_Offset bufcount,
+ MPI_Datatype buftype)
+{
+ int status;
+ NC *ncp;
+ NC_var *varp=NULL;
+
+ status = ncmpii_sanity_check(ncid, varid, start, count, bufcount, API_VARA,
+ 1, 1, ReadWrite($1), CollIndep($2), &ncp, &varp);
+ if (status != NC_NOERR) return status;
+
+ /* $1_vara is a special case of $1_varm */
+ return ncmpii_getput_varm(ncp, varp, start, count, NULL, NULL, (void*)buf,
+ bufcount, buftype, ReadWrite($1), CollIndep($2));
+}
+')dnl
+
+dnl PnetCDF flexible APIs
+VARA_FLEXIBLE(put)
+VARA_FLEXIBLE(get)
+VARA_FLEXIBLE(put, _all)
+VARA_FLEXIBLE(get, _all)
+
+dnl
+dnl VARA
+dnl
+define(`VARA',dnl
+`dnl
+/*----< ncmpi_$1_vara_$3$2() >-----------------------------------------------*/
+int
+ncmpi_$1_vara_$3$2(int ncid,
+ int varid,
+ const MPI_Offset start[],
+ const MPI_Offset count[],
+ BufConst($1) $4 *op)
+{
+ int status;
+ NC *ncp;
+ NC_var *varp=NULL;
+
+ status = ncmpii_sanity_check(ncid, varid, start, count, 0, API_VARA,
+ 1, 0, ReadWrite($1), CollIndep($2), &ncp, &varp);
+ if (status != NC_NOERR) return status;
+
+ /* $1_vara is a special case of $1_varm */
+ return ncmpii_getput_varm(ncp, varp, start, count, NULL, NULL, (void*)op,
+ -1, $5, ReadWrite($1), CollIndep($2));
+}
+')dnl
+
+VARA(put, , text, char, MPI_CHAR)
+VARA(put, , schar, schar, MPI_SIGNED_CHAR)
+VARA(put, , uchar, uchar, MPI_UNSIGNED_CHAR)
+VARA(put, , short, short, MPI_SHORT)
+VARA(put, , ushort, ushort, MPI_UNSIGNED_SHORT)
+VARA(put, , int, int, MPI_INT)
+VARA(put, , uint, uint, MPI_UNSIGNED)
+VARA(put, , long, long, MPI_LONG)
+VARA(put, , float, float, MPI_FLOAT)
+VARA(put, , double, double, MPI_DOUBLE)
+VARA(put, , longlong, long long, MPI_LONG_LONG_INT)
+VARA(put, , ulonglong, unsigned long long, MPI_UNSIGNED_LONG_LONG)
+
+VARA(put, _all, text, char, MPI_CHAR)
+VARA(put, _all, schar, schar, MPI_SIGNED_CHAR)
+VARA(put, _all, uchar, uchar, MPI_UNSIGNED_CHAR)
+VARA(put, _all, short, short, MPI_SHORT)
+VARA(put, _all, ushort, ushort, MPI_UNSIGNED_SHORT)
+VARA(put, _all, int, int, MPI_INT)
+VARA(put, _all, uint, uint, MPI_UNSIGNED)
+VARA(put, _all, long, long, MPI_LONG)
+VARA(put, _all, float, float, MPI_FLOAT)
+VARA(put, _all, double, double, MPI_DOUBLE)
+VARA(put, _all, longlong, long long, MPI_LONG_LONG_INT)
+VARA(put, _all, ulonglong, unsigned long long, MPI_UNSIGNED_LONG_LONG)
+
+VARA(get, , text, char, MPI_CHAR)
+VARA(get, , schar, schar, MPI_SIGNED_CHAR)
+VARA(get, , uchar, uchar, MPI_UNSIGNED_CHAR)
+VARA(get, , short, short, MPI_SHORT)
+VARA(get, , ushort, ushort, MPI_UNSIGNED_SHORT)
+VARA(get, , int, int, MPI_INT)
+VARA(get, , uint, uint, MPI_UNSIGNED)
+VARA(get, , long, long, MPI_LONG)
+VARA(get, , float, float, MPI_FLOAT)
+VARA(get, , double, double, MPI_DOUBLE)
+VARA(get, , longlong, long long, MPI_LONG_LONG_INT)
+VARA(get, , ulonglong, unsigned long long, MPI_UNSIGNED_LONG_LONG)
+
+VARA(get, _all, text, char, MPI_CHAR)
+VARA(get, _all, schar, schar, MPI_SIGNED_CHAR)
+VARA(get, _all, uchar, uchar, MPI_UNSIGNED_CHAR)
+VARA(get, _all, short, short, MPI_SHORT)
+VARA(get, _all, ushort, ushort, MPI_UNSIGNED_SHORT)
+VARA(get, _all, int, int, MPI_INT)
+VARA(get, _all, uint, uint, MPI_UNSIGNED)
+VARA(get, _all, long, long, MPI_LONG)
+VARA(get, _all, float, float, MPI_FLOAT)
+VARA(get, _all, double, double, MPI_DOUBLE)
+VARA(get, _all, longlong, long long, MPI_LONG_LONG_INT)
+VARA(get, _all, ulonglong, unsigned long long, MPI_UNSIGNED_LONG_LONG)
+
+dnl
+dnl VARS_FLEXIBLE
+dnl
+define(`VARS_FLEXIBLE',dnl
+`dnl
+/*----< ncmpi_$1_vars$2() >--------------------------------------------------*/
+int
+ncmpi_$1_vars$2(int ncid,
+ int varid,
+ const MPI_Offset start[],
+ const MPI_Offset count[],
+ const MPI_Offset stride[],
+ BufConst($1) void *buf,
+ MPI_Offset bufcount,
+ MPI_Datatype buftype)
+{
+ int status;
+ NC *ncp;
+ NC_var *varp=NULL;
+
+ status = ncmpii_sanity_check(ncid, varid, start, count, bufcount, API_VARS,
+ 1, 1, ReadWrite($1), CollIndep($2), &ncp, &varp);
+ if (status != NC_NOERR) return status;
+
+ return ncmpii_getput_varm(ncp, varp, start, count, stride, NULL, (void*)buf,
+ bufcount, buftype, ReadWrite($1), CollIndep($2));
+}
+')dnl
+
+dnl PnetCDF flexible APIs
+VARS_FLEXIBLE(put)
+VARS_FLEXIBLE(get)
+VARS_FLEXIBLE(put, _all)
+VARS_FLEXIBLE(get, _all)
+
+dnl
+dnl VARS
+dnl
+define(`VARS',dnl
+`dnl
+/*----< ncmpi_$1_vars_$3$2() >-----------------------------------------------*/
+int
+ncmpi_$1_vars_$3$2(int ncid,
+ int varid,
+ const MPI_Offset start[],
+ const MPI_Offset count[],
+ const MPI_Offset stride[],
+ BufConst($1) $4 *op)
+{
+ int status;
+ NC *ncp;
+ NC_var *varp=NULL;
+
+ status = ncmpii_sanity_check(ncid, varid, start, count, 0, API_VARS,
+ 1, 0, ReadWrite($1), CollIndep($2), &ncp, &varp);
+ if (status != NC_NOERR) return status;
+
+ return ncmpii_getput_varm(ncp, varp, start, count, stride, NULL, (void*)op,
+ -1, $5, ReadWrite($1), CollIndep($2));
+}
+')dnl
+
+VARS(put, , text, char, MPI_CHAR)
+VARS(put, , schar, schar, MPI_SIGNED_CHAR)
+VARS(put, , uchar, uchar, MPI_UNSIGNED_CHAR)
+VARS(put, , short, short, MPI_SHORT)
+VARS(put, , ushort, ushort, MPI_UNSIGNED_SHORT)
+VARS(put, , int, int, MPI_INT)
+VARS(put, , uint, uint, MPI_UNSIGNED)
+VARS(put, , long, long, MPI_LONG)
+VARS(put, , float, float, MPI_FLOAT)
+VARS(put, , double, double, MPI_DOUBLE)
+VARS(put, , longlong, long long, MPI_LONG_LONG_INT)
+VARS(put, , ulonglong, unsigned long long, MPI_UNSIGNED_LONG_LONG)
+
+VARS(put, _all, text, char, MPI_CHAR)
+VARS(put, _all, schar, schar, MPI_SIGNED_CHAR)
+VARS(put, _all, uchar, uchar, MPI_UNSIGNED_CHAR)
+VARS(put, _all, short, short, MPI_SHORT)
+VARS(put, _all, ushort, ushort, MPI_UNSIGNED_SHORT)
+VARS(put, _all, int, int, MPI_INT)
+VARS(put, _all, uint, uint, MPI_UNSIGNED)
+VARS(put, _all, long, long, MPI_LONG)
+VARS(put, _all, float, float, MPI_FLOAT)
+VARS(put, _all, double, double, MPI_DOUBLE)
+VARS(put, _all, longlong, long long, MPI_LONG_LONG_INT)
+VARS(put, _all, ulonglong, unsigned long long, MPI_UNSIGNED_LONG_LONG)
+
+VARS(get, , text, char, MPI_CHAR)
+VARS(get, , schar, schar, MPI_SIGNED_CHAR)
+VARS(get, , uchar, uchar, MPI_UNSIGNED_CHAR)
+VARS(get, , short, short, MPI_SHORT)
+VARS(get, , ushort, ushort, MPI_UNSIGNED_SHORT)
+VARS(get, , int, int, MPI_INT)
+VARS(get, , uint, uint, MPI_UNSIGNED)
+VARS(get, , long, long, MPI_LONG)
+VARS(get, , float, float, MPI_FLOAT)
+VARS(get, , double, double, MPI_DOUBLE)
+VARS(get, , longlong, long long, MPI_LONG_LONG_INT)
+VARS(get, , ulonglong, unsigned long long, MPI_UNSIGNED_LONG_LONG)
+
+VARS(get, _all, text, char, MPI_CHAR)
+VARS(get, _all, schar, schar, MPI_SIGNED_CHAR)
+VARS(get, _all, uchar, uchar, MPI_UNSIGNED_CHAR)
+VARS(get, _all, short, short, MPI_SHORT)
+VARS(get, _all, ushort, ushort, MPI_UNSIGNED_SHORT)
+VARS(get, _all, int, int, MPI_INT)
+VARS(get, _all, uint, uint, MPI_UNSIGNED)
+VARS(get, _all, long, long, MPI_LONG)
+VARS(get, _all, float, float, MPI_FLOAT)
+VARS(get, _all, double, double, MPI_DOUBLE)
+VARS(get, _all, longlong, long long, MPI_LONG_LONG_INT)
+VARS(get, _all, ulonglong, unsigned long long, MPI_UNSIGNED_LONG_LONG)
+
+dnl
+dnl VARM_FLEXIBLE
+dnl
+define(`VARM_FLEXIBLE',dnl
+`dnl
+/*----< ncmpi_$1_varm$2() >--------------------------------------------------*/
+int
+ncmpi_$1_varm$2(int ncid,
+ int varid,
+ const MPI_Offset start[],
+ const MPI_Offset count[],
+ const MPI_Offset stride[],
+ const MPI_Offset imap[],
+ BufConst($1) void *buf,
+ MPI_Offset bufcount,
+ MPI_Datatype buftype)
+{
+ int status;
+ NC *ncp;
+ NC_var *varp=NULL;
+
+ status = ncmpii_sanity_check(ncid, varid, start, count, bufcount, API_VARM,
+ 1, 1, ReadWrite($1), CollIndep($2), &ncp, &varp);
+ if (status != NC_NOERR) return status;
+
+ return ncmpii_getput_varm(ncp, varp, start, count, stride, imap,
+ (void*)buf, bufcount, buftype, ReadWrite($1),
+ CollIndep($2));
+}
+')dnl
+
+dnl PnetCDF flexible APIs
+VARM_FLEXIBLE(put)
+VARM_FLEXIBLE(get)
+VARM_FLEXIBLE(put, _all)
+VARM_FLEXIBLE(get, _all)
+
+dnl
+dnl VARM
+dnl
+define(`VARM',dnl
+`dnl
+/*----< ncmpi_$1_varm_$3$2() >------------------------------------------------*/
+int
+ncmpi_$1_varm_$3$2(int ncid,
+ int varid,
+ const MPI_Offset start[],
+ const MPI_Offset count[],
+ const MPI_Offset stride[],
+ const MPI_Offset imap[],
+ BufConst($1) $4 *op)
+{
+ int status;
+ NC *ncp;
+ NC_var *varp=NULL;
+
+ status = ncmpii_sanity_check(ncid, varid, start, count, 0, API_VARM,
+ 1, 0, ReadWrite($1), CollIndep($2), &ncp, &varp);
+ if (status != NC_NOERR) return status;
+
+ return ncmpii_getput_varm(ncp, varp, start, count, stride, imap, (void*)op,
+ -1, $5, ReadWrite($1), CollIndep($2));
+}
+')dnl
+
+VARM(put, , text, char, MPI_CHAR)
+VARM(put, , schar, schar, MPI_SIGNED_CHAR)
+VARM(put, , uchar, uchar, MPI_UNSIGNED_CHAR)
+VARM(put, , short, short, MPI_SHORT)
+VARM(put, , ushort, ushort, MPI_UNSIGNED_SHORT)
+VARM(put, , int, int, MPI_INT)
+VARM(put, , uint, uint, MPI_UNSIGNED)
+VARM(put, , long, long, MPI_LONG)
+VARM(put, , float, float, MPI_FLOAT)
+VARM(put, , double, double, MPI_DOUBLE)
+VARM(put, , longlong, long long, MPI_LONG_LONG_INT)
+VARM(put, , ulonglong, unsigned long long, MPI_UNSIGNED_LONG_LONG)
+
+VARM(put, _all, text, char, MPI_CHAR)
+VARM(put, _all, schar, schar, MPI_SIGNED_CHAR)
+VARM(put, _all, uchar, uchar, MPI_UNSIGNED_CHAR)
+VARM(put, _all, short, short, MPI_SHORT)
+VARM(put, _all, ushort, ushort, MPI_UNSIGNED_SHORT)
+VARM(put, _all, int, int, MPI_INT)
+VARM(put, _all, uint, uint, MPI_UNSIGNED)
+VARM(put, _all, long, long, MPI_LONG)
+VARM(put, _all, float, float, MPI_FLOAT)
+VARM(put, _all, double, double, MPI_DOUBLE)
+VARM(put, _all, longlong, long long, MPI_LONG_LONG_INT)
+VARM(put, _all, ulonglong, unsigned long long, MPI_UNSIGNED_LONG_LONG)
+
+VARM(get, , text, char, MPI_CHAR)
+VARM(get, , schar, schar, MPI_SIGNED_CHAR)
+VARM(get, , uchar, uchar, MPI_UNSIGNED_CHAR)
+VARM(get, , short, short, MPI_SHORT)
+VARM(get, , ushort, ushort, MPI_UNSIGNED_SHORT)
+VARM(get, , int, int, MPI_INT)
+VARM(get, , uint, uint, MPI_UNSIGNED)
+VARM(get, , long, long, MPI_LONG)
+VARM(get, , float, float, MPI_FLOAT)
+VARM(get, , double, double, MPI_DOUBLE)
+VARM(get, , longlong, long long, MPI_LONG_LONG_INT)
+VARM(get, , ulonglong, unsigned long long, MPI_UNSIGNED_LONG_LONG)
+
+VARM(get, _all, text, char, MPI_CHAR)
+VARM(get, _all, schar, schar, MPI_SIGNED_CHAR)
+VARM(get, _all, uchar, uchar, MPI_UNSIGNED_CHAR)
+VARM(get, _all, short, short, MPI_SHORT)
+VARM(get, _all, ushort, ushort, MPI_UNSIGNED_SHORT)
+VARM(get, _all, int, int, MPI_INT)
+VARM(get, _all, uint, uint, MPI_UNSIGNED)
+VARM(get, _all, long, long, MPI_LONG)
+VARM(get, _all, float, float, MPI_FLOAT)
+VARM(get, _all, double, double, MPI_DOUBLE)
+VARM(get, _all, longlong, long long, MPI_LONG_LONG_INT)
+VARM(get, _all, ulonglong, unsigned long long, MPI_UNSIGNED_LONG_LONG)
+
+
diff --git a/src/lib/header.c b/src/lib/header.c
new file mode 100644
index 0000000..0f0f4c0
--- /dev/null
+++ b/src/lib/header.c
@@ -0,0 +1,2530 @@
+/*
+ * Copyright (C) 2003, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ */
+/* $Id: header.c 2299 2016-01-09 06:14:37Z wkliao $ */
+
+#if HAVE_CONFIG_H
+# include "ncconfig.h"
+#endif
+
+#include <assert.h>
+#include <string.h> /* memcpy(), memcmp() */
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#include <stdio.h>
+
+#include <mpi.h>
+
+#include "nc.h"
+#include "ncx.h"
+#include "macro.h"
+
+#ifdef SIZEOF_INT
+# if SIZEOF_INT == 4
+# define lld(x) (x)
+# elif SIZEOF_INT == 8
+# define lld(x) (long long)(x)
+# endif
+#endif
+
+/* Prototypes for functions used only in this file */
+static MPI_Offset hdr_len_NC_name(const NC_string *ncstrp, int sizeof_t);
+static MPI_Offset hdr_len_NC_dim(const NC_dim *dimp, int sizeof_t);
+static MPI_Offset hdr_len_NC_dimarray(const NC_dimarray *ncap, int sizeof_t);
+static MPI_Offset hdr_len_NC_attr(const NC_attr *attrp, int sizeof_t);
+static MPI_Offset hdr_len_NC_attrarray(const NC_attrarray *ncap, int sizeof_t);
+static MPI_Offset hdr_len_NC_var(const NC_var *varp, int sizeof_off_t, int sizeof_t);
+static MPI_Offset hdr_len_NC_vararray(const NC_vararray *ncap, int sizeof_t, int sizeof_off_t);
+static int hdr_put_NC_name(bufferinfo *pbp, const NC_string *ncstrp);
+static int hdr_put_NC_attrV(bufferinfo *pbp, const NC_attr *attrp);
+static int hdr_put_NC_dim(bufferinfo *pbp, const NC_dim *dimp);
+static int hdr_put_NC_attr(bufferinfo *pbp, const NC_attr *attrp);
+static int hdr_put_NC_var(bufferinfo *pbp, const NC_var *varp);
+static int hdr_put_NC_dimarray(bufferinfo *pbp, const NC_dimarray *ncap);
+static int hdr_put_NC_attrarray(bufferinfo *pbp, const NC_attrarray *ncap);
+static int hdr_put_NC_vararray(bufferinfo *pbp, const NC_vararray *ncap);
+static int hdr_fetch(bufferinfo *gbp);
+static int hdr_check_buffer(bufferinfo *gbp, MPI_Offset nextread);
+static int hdr_get_NCtype(bufferinfo *gbp, NCtype *typep);
+static int hdr_get_NC_name(bufferinfo *gbp, NC_string **ncstrpp);
+static int hdr_get_NC_dim(bufferinfo *gbp, NC_dim **dimpp);
+static int hdr_get_NC_dimarray(bufferinfo *gbp, NC_dimarray *ncap);
+static int hdr_get_nc_type(bufferinfo *gbp, nc_type *typep);
+static int hdr_get_NC_attrV(bufferinfo *gbp, NC_attr *attrp);
+static int hdr_get_NC_attr(bufferinfo *gbp, NC_attr **attrpp);
+static int hdr_get_NC_attrarray(bufferinfo *gbp, NC_attrarray *ncap);
+static int hdr_get_NC_var(bufferinfo *gbp, NC_var **varpp);
+static int hdr_get_NC_vararray(bufferinfo *gbp, NC_vararray *ncap);
+
+/*
+ * "magic number" at beginning of file: 0x43444601 (big endian)
+ */
+static const schar ncmagic1[] = {'C', 'D', 'F', 0x01};
+static const schar ncmagic2[] = {'C', 'D', 'F', 0x02};
+static const schar ncmagic5[] = {'C', 'D', 'F', 0x05};
+
+/*
+ * Recompute the shapes of all variables
+ * Sets ncp->begin_var to start of first variable.
+ * Sets ncp->begin_rec to start of first record variable.
+ * Returns -1 on error. The only possible error is an reference
+ * to a non existent dimension, which would occur for a corrupt
+ * netcdf file.
+ */
+int
+ncmpii_NC_computeshapes(NC *ncp)
+{
+ NC_var **vpp = (NC_var **)ncp->vars.value;
+ NC_var *const *const end = &vpp[ncp->vars.ndefined];
+ NC_var *first_var = NULL; /* first "non-record" var */
+ NC_var *first_rec = NULL; /* first "record" var */
+ int status;
+
+ ncp->begin_var = (MPI_Offset) ncp->xsz;
+ ncp->begin_rec = (MPI_Offset) ncp->xsz;
+ ncp->recsize = 0;
+
+ if (ncp->vars.ndefined == 0) return NC_NOERR;
+
+ for ( /*NADA*/; vpp < end; vpp++) {
+ /* (*vpp)->len is recomputed from dimensions in ncmpii_NC_var_shape64() */
+ status = ncmpii_NC_var_shape64(ncp, *vpp, &ncp->dims);
+
+ if (status != NC_NOERR) return status ;
+
+ if (IS_RECVAR(*vpp)) {
+ if (first_rec == NULL)
+ first_rec = *vpp;
+ ncp->recsize += (*vpp)->len;
+ }
+ else {
+ if (first_var == NULL)
+ first_var = *vpp;
+ /*
+ * Overwritten each time thru.
+ * Usually overwritten in first_rec != NULL clause.
+ */
+ ncp->begin_rec = (*vpp)->begin + (MPI_Offset)(*vpp)->len;
+ }
+ }
+
+ if (first_rec != NULL) {
+ if (ncp->begin_rec > first_rec->begin)
+ DEBUG_RETURN_ERROR(NC_ENOTNC) /* not a netCDF file or corrupted */
+
+ ncp->begin_rec = first_rec->begin;
+ /*
+ * for special case of exactly one record variable, pack value
+ */
+ if (ncp->recsize == first_rec->len)
+ ncp->recsize = *first_rec->dsizes * first_rec->xsz;
+ }
+
+ if (first_var != NULL)
+ ncp->begin_var = first_var->begin;
+ else
+ ncp->begin_var = ncp->begin_rec;
+
+ if (ncp->begin_var <= 0 ||
+ ncp->xsz > ncp->begin_var ||
+ ncp->begin_rec <= 0 ||
+ ncp->begin_var > ncp->begin_rec)
+ DEBUG_RETURN_ERROR(NC_ENOTNC) /* not a netCDF file or corrupted */
+
+ return NC_NOERR;
+}
+
+/*
+ * To compute how much space will the xdr'd header take
+ */
+
+#define X_SIZEOF_NC_TYPE X_SIZEOF_INT
+#define X_SIZEOF_NCTYPE X_SIZEOF_INT
+
+/*----< hdr_len_NC_name() >--------------------------------------------------*/
+inline static MPI_Offset
+hdr_len_NC_name(const NC_string *ncstrp,
+ int sizeof_t) /* NON_NEG */
+{
+ /* netCDF file format:
+ * name = nelems namestring
+ * nelems = NON_NEG
+ * namestring = ID1 [IDN ...] padding
+ * ID1 = alphanumeric | '_'
+ * IDN = alphanumeric | special1 | special2
+ * padding = <0, 1, 2, or 3 bytes to next 4-byte boundary>
+ * NON_NEG = <non-negative INT> | // CDF-1 and CDF-2
+ * <non-negative INT64> // CDF-5
+ */
+ MPI_Offset sz = sizeof_t; /* nelems */
+
+ assert(ncstrp != NULL);
+
+ if (ncstrp->nchars != 0) /* namestring */
+ sz += _RNDUP(ncstrp->nchars, X_ALIGN);
+
+ return sz;
+}
+
+/*----< hdr_len_NC_dim() >---------------------------------------------------*/
+inline static MPI_Offset
+hdr_len_NC_dim(const NC_dim *dimp,
+ int sizeof_t) /* NON_NEG */
+{
+ /* netCDF file format:
+ * ...
+ * dim = name dim_length
+ * dim_length = NON_NEG
+ * NON_NEG = <non-negative INT> | // CDF-1 and CDF-2
+ * <non-negative INT64> // CDF-5
+ */
+ MPI_Offset sz;
+
+ assert(dimp != NULL);
+
+ sz = hdr_len_NC_name(dimp->name, sizeof_t); /* name */
+ sz += sizeof_t; /* dim_length */
+
+ return sz;
+}
+
+/*----< hdr_len_NC_dimarray() >----------------------------------------------*/
+inline static MPI_Offset
+hdr_len_NC_dimarray(const NC_dimarray *ncap,
+ int sizeof_t) /* NON_NEG */
+{
+ /* netCDF file format:
+ * ...
+ * dim_list = ABSENT | NC_DIMENSION nelems [dim ...]
+ * ABSENT = ZERO ZERO | // list is not present for CDF-1 and 2
+ * ZERO ZERO64 // for CDF-5
+ * ZERO = \x00 \x00 \x00 \x00 // 32-bit zero
+ * ZERO64 = \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 // 64-bit zero
+ * NC_DIMENSION = \x00 \x00 \x00 \x0A // tag for list of dimensions
+ * nelems = NON_NEG // number of elements in following sequence
+ * NON_NEG = <non-negative INT> | // CDF-1 and CDF-2
+ * <non-negative INT64> // CDF-5
+ */
+ int i;
+ MPI_Offset xlen;
+
+ xlen = X_SIZEOF_NCTYPE; /* NC_DIMENSION */
+ xlen += sizeof_t; /* nelems */
+
+ if (ncap == NULL) /* ABSENT: no dimension is defined */
+ return xlen;
+
+ /* [dim ...] */
+ for (i=0; i<ncap->ndefined; i++)
+ xlen += hdr_len_NC_dim(ncap->value[i], sizeof_t);
+
+ return xlen;
+}
+
+/*----< hdr_len_NC_attr() >--------------------------------------------------*/
+inline static MPI_Offset
+hdr_len_NC_attr(const NC_attr *attrp,
+ int sizeof_t) /* NON_NEG */
+{
+ /* netCDF file format:
+ * ...
+ * attr = name nc_type nelems [values ...]
+ * nc_type = NC_BYTE | NC_CHAR | NC_SHORT | ...
+ * nelems = NON_NEG // number of elements in following sequence
+ * values = bytes | chars | shorts | ints | floats | doubles
+ * bytes = [BYTE ...] padding
+ * chars = [CHAR ...] padding
+ * shorts = [SHORT ...] padding
+ * ints = [INT ...]
+ * floats = [FLOAT ...]
+ * doubles = [DOUBLE ...]
+ * padding = <0, 1, 2, or 3 bytes to next 4-byte boundary>
+ * NON_NEG = <non-negative INT> | // CDF-1 and CDF-2
+ * <non-negative INT64> // CDF-5
+ */
+ MPI_Offset sz;
+
+ assert(attrp != NULL);
+
+ sz = hdr_len_NC_name(attrp->name, sizeof_t); /* name */
+ sz += X_SIZEOF_NC_TYPE; /* nc_type */
+ sz += sizeof_t; /* nelems */
+ sz += attrp->xsz; /* [values ...] */
+
+ return sz;
+}
+
+/*----< hdr_len_NC_attrarray() >---------------------------------------------*/
+inline static MPI_Offset
+hdr_len_NC_attrarray(const NC_attrarray *ncap,
+ int sizeof_t) /* NON_NEG */
+{
+ /* netCDF file format:
+ * ...
+ * att_list = ABSENT | NC_ATTRIBUTE nelems [attr ...]
+ * ABSENT = ZERO ZERO | // list is not present for CDF-1 and 2
+ * ZERO ZERO64 // for CDF-5
+ * ZERO = \x00 \x00 \x00 \x00 // 32-bit zero
+ * ZERO64 = \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 // 64-bit zero
+ * NC_ATTRIBUTE = \x00 \x00 \x00 \x0C // tag for list of attributes
+ * nelems = NON_NEG // number of elements in following sequence
+ * NON_NEG = <non-negative INT> | // CDF-1 and CDF-2
+ * <non-negative INT64> // CDF-5
+ */
+ int i;
+ MPI_Offset xlen;
+
+ xlen = X_SIZEOF_NCTYPE; /* NC_ATTRIBUTE */
+ xlen += sizeof_t; /* nelems */
+
+ if (ncap == NULL) /* ABSENT: no attribute is defined */
+ return xlen;
+
+ for (i=0; i<ncap->ndefined; i++) /* [attr ...] */
+ xlen += hdr_len_NC_attr(ncap->value[i], sizeof_t);
+
+ return xlen;
+}
+
+/*----< hdr_len_NC_var() >---------------------------------------------------*/
+inline static MPI_Offset
+hdr_len_NC_var(const NC_var *varp,
+ int sizeof_off_t, /* OFFSET */
+ int sizeof_t) /* NON_NEG */
+{
+ /* netCDF file format:
+ * netcdf_file = header data
+ * header = magic numrecs dim_list gatt_list var_list
+ * ...
+ * var = name nelems [dimid ...] vatt_list nc_type vsize begin
+ * nelems = NON_NEG
+ * dimid = NON_NEG
+ * vatt_list = att_list
+ * nc_type = NC_BYTE | NC_CHAR | NC_SHORT | ...
+ * vsize = NON_NEG
+ * begin = OFFSET // Variable start location.
+ * OFFSET = <non-negative INT> | // CDF-1
+ * <non-negative INT64> // CDF-2 and CDF-5
+ * NON_NEG = <non-negative INT> | // CDF-1 and CDF-2
+ * <non-negative INT64> // CDF-5
+ */
+ MPI_Offset sz;
+
+ assert(varp != NULL);
+
+ /* for CDF-1, sizeof_off_t == 4 && sizeof_t == 4
+ * for CDF-2, sizeof_off_t == 8 && sizeof_t == 4
+ * for CDF-5, sizeof_off_t == 8 && sizeof_t == 8
+ */
+ sz = hdr_len_NC_name(varp->name, sizeof_t); /* name */
+ sz += sizeof_t; /* nelems */
+ sz += sizeof_t * varp->ndims; /* [dimid ...] */
+ sz += hdr_len_NC_attrarray(&varp->attrs, sizeof_t); /* vatt_list */
+ sz += X_SIZEOF_NC_TYPE; /* nc_type */
+ sz += sizeof_t; /* vsize */
+ sz += sizeof_off_t; /* begin */
+
+ return sz;
+}
+
+/*----< hdr_len_NC_vararray() >----------------------------------------------*/
+inline static MPI_Offset
+hdr_len_NC_vararray(const NC_vararray *ncap,
+ int sizeof_t, /* NON_NEG */
+ int sizeof_off_t) /* OFFSET */
+{
+ /* netCDF file format:
+ * netcdf_file = header data
+ * header = magic numrecs dim_list gatt_list var_list
+ * ...
+ * var_list = ABSENT | NC_VARIABLE nelems [var ...]
+ * ABSENT = ZERO ZERO | // list is not present for CDF-1 and 2
+ * ZERO ZERO64 // for CDF-5
+ * ZERO = \x00 \x00 \x00 \x00 // 32-bit zero
+ * ZERO64 = \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 // 64-bit zero
+ * NC_VARIABLE = \x00 \x00 \x00 \x0B // tag for list of variables
+ * nelems = NON_NEG // number of elements in following sequence
+ * NON_NEG = <non-negative INT> | // CDF-1 and CDF-2
+ * <non-negative INT64> // CDF-5
+ */
+ int i;
+ MPI_Offset xlen;
+
+ xlen = X_SIZEOF_NCTYPE; /* NC_VARIABLE */
+ xlen += sizeof_t; /* nelems */
+
+ if (ncap == NULL) /* ABSENT: no variable is defined */
+ return xlen;
+
+ /* for CDF-1, sizeof_off_t == 4 && sizeof_t == 4
+ * for CDF-2, sizeof_off_t == 8 && sizeof_t == 4
+ * for CDF-5, sizeof_off_t == 8 && sizeof_t == 8
+ */
+ for (i=0; i<ncap->ndefined; i++) /* [var ...] */
+ xlen += hdr_len_NC_var(ncap->value[i], sizeof_off_t, sizeof_t);
+
+ return xlen;
+}
+
+/*----< ncmpii_hdr_len_NC() >------------------------------------------------*/
+MPI_Offset
+ncmpii_hdr_len_NC(const NC *ncp)
+{
+ /* netCDF file format:
+ * netcdf_file = header data
+ * header = magic numrecs dim_list gatt_list var_list
+ * ...
+ * numrecs = NON_NEG | STREAMING // length of record dimension
+ * NON_NEG = <non-negative INT> | // CDF-1 and CDF-2
+ * <non-negative INT64> // CDF-5
+ */
+
+ int sizeof_t, sizeof_off_t;
+ MPI_Offset xlen;
+
+ assert(ncp != NULL);
+
+ if (fIsSet(ncp->flags, NC_64BIT_DATA)) { /* CDF-5 */
+ sizeof_t = X_SIZEOF_INT64; /* 8-byte integer for all integers */
+ sizeof_off_t = X_SIZEOF_INT64; /* 8-byte integer for var begin */
+ }
+ else if (fIsSet(ncp->flags, NC_64BIT_OFFSET)) { /* CDF-2 */
+ sizeof_t = X_SIZEOF_INT; /* 4-byte integer in CDF-1 */
+ sizeof_off_t = X_SIZEOF_INT64; /* 8-byte integer for var begin */
+ }
+ else { /* CDF-1 */
+ sizeof_t = X_SIZEOF_INT; /* 4-byte integer in CDF-1 */
+ sizeof_off_t = X_SIZEOF_INT; /* 4-byte integer in CDF-1 */
+ }
+
+ xlen = sizeof(ncmagic1); /* magic */
+ xlen += sizeof_t; /* numrecs */
+ xlen += hdr_len_NC_dimarray(&ncp->dims, sizeof_t); /* dim_list */
+ xlen += hdr_len_NC_attrarray(&ncp->attrs, sizeof_t); /* gatt_list */
+ xlen += hdr_len_NC_vararray(&ncp->vars, sizeof_t, sizeof_off_t); /* var_list */
+
+ return xlen; /* return the header size (not yet aligned) */
+}
+
+/* Begin Of put NC */
+
+/*----< hdr_put_NC_name() >--------------------------------------------------*/
+inline static int
+hdr_put_NC_name(bufferinfo *pbp,
+ const NC_string *ncstrp)
+{
+ /* netCDF file format:
+ * ...
+ * name = nelems namestring
+ * nelems = NON_NEG
+ * namestring = ID1 [IDN ...] padding
+ * ID1 = alphanumeric | '_'
+ * IDN = alphanumeric | special1 | special2
+ * padding = <0, 1, 2, or 3 bytes to next 4-byte boundary>
+ * NON_NEG = <non-negative INT> | // CDF-1 and CDF-2
+ * <non-negative INT64> // CDF-5
+ */
+ int status;
+
+ /* copy nelems */
+ if (pbp->version == 5)
+ status = ncmpix_put_uint64((void**)(&pbp->pos), ncstrp->nchars);
+ else {
+ if (ncstrp->nchars != (uint)ncstrp->nchars) DEBUG_RETURN_ERROR(NC_EINTOVERFLOW)
+ status = ncmpix_put_uint32((void**)(&pbp->pos), (uint)ncstrp->nchars);
+ }
+ if (status != NC_NOERR) return status;
+
+ /* copy namestring */
+ status = ncmpix_pad_putn_text(&pbp->pos, ncstrp->nchars, ncstrp->cp);
+ if (status != NC_NOERR) return status;
+
+ return NC_NOERR;
+}
+
+/*----< hdr_put_NC_attrV() >-------------------------------------------------*/
+/*
+ * Put the values of an attribute
+ */
+inline static int
+hdr_put_NC_attrV(bufferinfo *pbp,
+ const NC_attr *attrp)
+{
+ /* netCDF file format:
+ * ...
+ * attr = name nc_type nelems [values ...]
+ * ...
+ * values = bytes | chars | shorts | ints | floats | doubles
+ * bytes = [BYTE ...] padding
+ * chars = [CHAR ...] padding
+ * shorts = [SHORT ...] padding
+ * ints = [INT ...]
+ * floats = [FLOAT ...]
+ * doubles = [DOUBLE ...]
+ * padding = <0, 1, 2, or 3 bytes to next 4-byte boundary>
+ */
+ MPI_Offset padding, sz;
+
+ /* ncmpix_len_nctype() returns the element size (unaligned) of attrp->type
+ attrp->xsz is the aligned total size of attribute values
+ */
+ sz = ncmpix_len_nctype(attrp->type);
+ sz *= attrp->nelems;
+ padding = attrp->xsz - sz;
+
+ if (sz != (size_t) sz) DEBUG_RETURN_ERROR(NC_EINTOVERFLOW)
+ memcpy(pbp->pos, attrp->xvalue, (size_t)sz);
+ pbp->pos = (void *)((char *)pbp->pos + sz);
+
+ /* zero-padding is per buffer, not per element */
+ memset(pbp->pos, 0, (size_t)padding);
+ pbp->pos = (void *)((char *)pbp->pos + padding);
+
+ return NC_NOERR;
+}
+
+/*----< hdr_put_NC_dim() >---------------------------------------------------*/
+inline static int
+hdr_put_NC_dim(bufferinfo *pbp,
+ const NC_dim *dimp)
+{
+ /* netCDF file format:
+ * ...
+ * dim = name dim_length
+ * dim_length = NON_NEG
+ * NON_NEG = <non-negative INT> | // CDF-1 and CDF-2
+ * <non-negative INT64> // CDF-5
+ */
+ int status;
+
+ /* copy name */
+ status = hdr_put_NC_name(pbp, dimp->name);
+ if (status != NC_NOERR) return status;
+
+ /* copy dim_length */
+ if (pbp->version == 5)
+ status = ncmpix_put_uint64((void**)(&pbp->pos), dimp->size);
+ else {
+ /* TODO: Isn't checking dimension size already done in def_dim()? */
+ if (dimp->size != (uint)dimp->size) DEBUG_RETURN_ERROR(NC_EINTOVERFLOW)
+ status = ncmpix_put_uint32((void**)(&pbp->pos), (uint)dimp->size);
+ }
+ if (status != NC_NOERR) return status;
+
+ return NC_NOERR;
+}
+
+/*----< hdr_put_NC_dimarray() >----------------------------------------------*/
+inline static int
+hdr_put_NC_dimarray(bufferinfo *pbp,
+ const NC_dimarray *ncap)
+{
+ /* netCDF file format:
+ * ...
+ * dim_list = ABSENT | NC_DIMENSION nelems [dim ...]
+ * ABSENT = ZERO ZERO | // list is not present for CDF-1 and 2
+ * ZERO ZERO64 // for CDF-5
+ * ZERO = \x00 \x00 \x00 \x00 // 32-bit zero
+ * ZERO64 = \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 // 64-bit zero
+ * NC_DIMENSION = \x00 \x00 \x00 \x0A // tag for list of dimensions
+ * nelems = NON_NEG // number of elements in following sequence
+ * NON_NEG = <non-negative INT> | // CDF-1 and CDF-2
+ * <non-negative INT64> // CDF-5
+ */
+ int i, status;
+
+ assert(pbp != NULL);
+
+ if (ncap == NULL || ncap->ndefined == 0) { /* ABSENT */
+ status = ncmpix_put_uint32((void**)(&pbp->pos), NC_UNSPECIFIED);
+ if (status != NC_NOERR) return status;
+
+ /* put a ZERO or ZERO64 depending on which CDF format */
+ if (pbp->version == 5)
+ status = ncmpix_put_uint64((void**)(&pbp->pos), 0);
+ else
+ status = ncmpix_put_uint32((void**)(&pbp->pos), 0);
+ if (status != NC_NOERR) return status;
+ }
+ else {
+ /* copy NC_DIMENSION */
+ status = ncmpix_put_uint32((void**)(&pbp->pos), NC_DIMENSION);
+ if (status != NC_NOERR) return status;
+
+ /* copy nelems */
+ if (pbp->version == 5)
+ status = ncmpix_put_uint64((void**)(&pbp->pos), ncap->ndefined);
+ else
+ status = ncmpix_put_uint32((void**)(&pbp->pos), ncap->ndefined);
+ if (status != NC_NOERR) return status;
+
+ /* copy [dim ...] */
+ for (i=0; i<ncap->ndefined; i++) {
+ status = hdr_put_NC_dim(pbp, ncap->value[i]);
+ if (status != NC_NOERR) return status;
+ }
+ }
+
+ return NC_NOERR;
+}
+
+/*----< hdr_put_NC_attr() >--------------------------------------------------*/
+inline static int
+hdr_put_NC_attr(bufferinfo *pbp,
+ const NC_attr *attrp)
+{
+ /* netCDF file format:
+ * ...
+ * attr = name nc_type nelems [values ...]
+ * nc_type = NC_BYTE | NC_CHAR | NC_SHORT | ...
+ * nelems = NON_NEG // number of elements in following sequence
+ * NON_NEG = <non-negative INT> | // CDF-1 and CDF-2
+ * <non-negative INT64> // CDF-5
+ */
+ int status;
+
+ /* copy name */
+ status = hdr_put_NC_name(pbp, attrp->name);
+ if (status != NC_NOERR) return status;
+
+ /* copy nc_type */
+ status = ncmpix_put_uint32((void**)(&pbp->pos), attrp->type);
+ if (status != NC_NOERR) return status;
+
+ /* copy nelems */
+ if (pbp->version == 5)
+ status = ncmpix_put_uint64((void**)(&pbp->pos), attrp->nelems);
+ else {
+ if (attrp->nelems != (uint)attrp->nelems) DEBUG_RETURN_ERROR(NC_EINTOVERFLOW)
+ status = ncmpix_put_uint32((void**)(&pbp->pos), (uint)attrp->nelems);
+ }
+ if (status != NC_NOERR) return status;
+
+ /* copy [values ...] */
+ status = hdr_put_NC_attrV(pbp, attrp);
+ if (status != NC_NOERR) return status;
+
+ return NC_NOERR;
+}
+
+/*----< hdr_put_NC_attrarray() >---------------------------------------------*/
+inline static int
+hdr_put_NC_attrarray(bufferinfo *pbp,
+ const NC_attrarray *ncap)
+{
+ /* netCDF file format:
+ * ...
+ * att_list = ABSENT | NC_ATTRIBUTE nelems [attr ...]
+ * ABSENT = ZERO ZERO | // list is not present for CDF-1 and 2
+ * ZERO ZERO64 // for CDF-5
+ * ZERO = \x00 \x00 \x00 \x00 // 32-bit zero
+ * ZERO64 = \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 // 64-bit zero
+ * NC_ATTRIBUTE = \x00 \x00 \x00 \x0C // tag for list of attributes
+ * nelems = NON_NEG // number of elements in following sequence
+ * NON_NEG = <non-negative INT> | // CDF-1 and CDF-2
+ * <non-negative INT64> // CDF-5
+ */
+ int i, status;
+
+ assert(pbp != NULL);
+
+ if (ncap == NULL || ncap->ndefined == 0) { /* ABSENT */
+ status = ncmpix_put_uint32((void**)(&pbp->pos), NC_UNSPECIFIED);
+ if (status != NC_NOERR) return status;
+
+ /* put a ZERO or ZERO64 depending on which CDF format */
+ if (pbp->version == 5)
+ status = ncmpix_put_uint64((void**)(&pbp->pos), 0);
+ else
+ status = ncmpix_put_uint32((void**)(&pbp->pos), 0);
+ if (status != NC_NOERR) return status;
+ }
+ else {
+ /* copy NC_ATTRIBUTE */
+ status = ncmpix_put_uint32((void**)(&pbp->pos), NC_ATTRIBUTE);
+ if (status != NC_NOERR) return status;
+
+ /* copy nelems */
+ if (pbp->version == 5)
+ status = ncmpix_put_uint64((void**)(&pbp->pos), ncap->ndefined);
+ else
+ status = ncmpix_put_uint32((void**)(&pbp->pos), ncap->ndefined);
+ if (status != NC_NOERR) return status;
+
+ /* copy [attr ...] */
+ for (i=0; i<ncap->ndefined; i++) {
+ status = hdr_put_NC_attr(pbp, ncap->value[i]);
+ if (status != NC_NOERR) return status;
+ }
+ }
+
+ return NC_NOERR;
+}
+
+/*----< hdr_put_NC_var() >---------------------------------------------------*/
+static int
+hdr_put_NC_var(bufferinfo *pbp,
+ const NC_var *varp)
+{
+ /* netCDF file format:
+ * netcdf_file = header data
+ * header = magic numrecs dim_list gatt_list var_list
+ * ...
+ * var = name nelems [dimid ...] vatt_list nc_type vsize begin
+ * nelems = NON_NEG
+ * dimid = NON_NEG
+ * vatt_list = att_list
+ * nc_type = NC_BYTE | NC_CHAR | NC_SHORT | ...
+ * vsize = NON_NEG
+ * begin = OFFSET // Variable start location.
+ * OFFSET = <non-negative INT> | // CDF-1
+ * <non-negative INT64> // CDF-2 and CDF-5
+ * NON_NEG = <non-negative INT> | // CDF-1 and CDF-2
+ * <non-negative INT64> // CDF-5
+ */
+ int i, status;
+
+ /* copy name */
+ status = hdr_put_NC_name(pbp, varp->name);
+ if (status != NC_NOERR) return status;
+
+ /* copy nelems */
+ if (pbp->version == 5)
+ status = ncmpix_put_uint64((void**)(&pbp->pos), varp->ndims);
+ else
+ status = ncmpix_put_uint32((void**)(&pbp->pos), varp->ndims);
+ if (status != NC_NOERR) return status;
+
+ /* copy [dimid ...] */
+ for (i=0; i<varp->ndims; i++) {
+ if (pbp->version == 5)
+ status = ncmpix_put_uint64((void**)(&pbp->pos), varp->dimids[i]);
+ else
+ status = ncmpix_put_uint32((void**)(&pbp->pos), varp->dimids[i]);
+ if (status != NC_NOERR) return status;
+ }
+
+ /* copy vatt_list */
+ status = hdr_put_NC_attrarray(pbp, &varp->attrs);
+ if (status != NC_NOERR) return status;
+
+ /* copy nc_type */
+ status = ncmpix_put_uint32((void**)(&pbp->pos), varp->type);
+ if (status != NC_NOERR) return status;
+
+ /* copy vsize */
+ /* in CDF-1 and CDF-2, a variable's size in the header is a 32-bit integer
+ * in CDF-5, it is a 64-bit integer
+ */
+ if (pbp->version == 5)
+ status = ncmpix_put_uint64((void**)(&pbp->pos), varp->len);
+ else {
+ /* Special case, when there is no record variable, the last fixed-size
+ * variable can be larger than 2 GiB if its file starting offset is
+ * less than 2 GiB. This checking has already been done in the call
+ * to ncmpii_NC_check_vlens() in ncmpii_NC_enddef().
+ *
+ * if (varp->len != (int)varp->len) DEBUG_RETURN_ERROR(NC_EVARSIZE)
+ */
+ status = ncmpix_put_uint32((void**)(&pbp->pos), (uint)varp->len);
+ }
+ if (status != NC_NOERR) return status;
+
+ /* copy begin */
+ /* in CDF-1 header, a variable's starting file offset is a 32-bit integer
+ * in CDF-2 and CDF-5, it is a 64-bit integer
+ */
+ if (pbp->version == 1) {
+ if (varp->begin != (uint)varp->begin) DEBUG_RETURN_ERROR(NC_EINTOVERFLOW)
+ status = ncmpix_put_uint32((void**)(&pbp->pos), (uint)varp->begin);
+ }
+ else
+ status = ncmpix_put_uint64((void**)(&pbp->pos), varp->begin);
+ if (status != NC_NOERR) return status;
+
+ return NC_NOERR;
+}
+
+/*----< hdr_put_NC_vararray() >----------------------------------------------*/
+static int
+hdr_put_NC_vararray(bufferinfo *pbp,
+ const NC_vararray *ncap)
+{
+ /* netCDF file format:
+ * netcdf_file = header data
+ * header = magic numrecs dim_list gatt_list var_list
+ * ...
+ * var_list = ABSENT | NC_VARIABLE nelems [var ...]
+ * ABSENT = ZERO ZERO | // list is not present for CDF-1 and 2
+ * ZERO ZERO64 // for CDF-5
+ * ZERO = \x00 \x00 \x00 \x00 // 32-bit zero
+ * ZERO64 = \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 // 64-bit zero
+ * NC_VARIABLE = \x00 \x00 \x00 \x0B // tag for list of variables
+ * nelems = NON_NEG // number of elements in following sequence
+ * NON_NEG = <non-negative INT> | // CDF-1 and CDF-2
+ * <non-negative INT64> // CDF-5
+ */
+ int i, status;
+
+ assert(pbp != NULL);
+
+ if (ncap == NULL || ncap->ndefined == 0) { /* ABSENT */
+ status = ncmpix_put_uint32((void**)(&pbp->pos), NC_UNSPECIFIED);
+ if (status != NC_NOERR) return status;
+
+ /* put a ZERO or ZERO64 depending on which CDF format */
+ if (pbp->version == 5)
+ status = ncmpix_put_uint64((void**)(&pbp->pos), 0);
+ else
+ status = ncmpix_put_uint32((void**)(&pbp->pos), 0);
+ if (status != NC_NOERR) return status;
+ }
+ else {
+ /* copy NC_VARIABLE */
+ status = ncmpix_put_uint32((void**)(&pbp->pos), NC_VARIABLE);
+ if (status != NC_NOERR) return status;
+
+ /* copy nelems */
+ if (pbp->version == 5)
+ status = ncmpix_put_uint64((void**)(&pbp->pos), ncap->ndefined);
+ else
+ status = ncmpix_put_uint32((void**)(&pbp->pos), ncap->ndefined);
+ if (status != NC_NOERR) return status;
+
+ /* copy [var ...] */
+ for (i=0; i<ncap->ndefined; i++) {
+ status = hdr_put_NC_var(pbp, ncap->value[i]);
+ if (status != NC_NOERR) return status;
+ }
+ }
+
+ return NC_NOERR;
+}
+
+/*----< ncmpii_hdr_put_NC() >------------------------------------------------*/
+/* fill the file header into the I/O buffer, buf
+ * this function is collective */
+int
+ncmpii_hdr_put_NC(NC *ncp,
+ void *buf) {
+ int status;
+ bufferinfo putbuf;
+ MPI_Offset nrecs=0;
+
+ putbuf.nciop = NULL;
+ putbuf.offset = 0;
+ putbuf.pos = buf;
+ putbuf.base = buf;
+ putbuf.size = ncp->xsz;
+ putbuf.put_size = 0;
+ putbuf.get_size = 0;
+ putbuf.safe_mode = ncp->safe_mode;
+
+ /* netCDF file format:
+ * netcdf_file = header data
+ * header = magic numrecs dim_list gatt_list var_list
+ */
+
+ /* copy "magic", 4 characters */
+ if (ncp->flags & NC_64BIT_DATA) {
+ putbuf.version = 5;
+ status = ncmpix_putn_schar_schar(&putbuf.pos, sizeof(ncmagic5), ncmagic5);
+ }
+ else if (ncp->flags & NC_64BIT_OFFSET) {
+ putbuf.version = 2;
+ status = ncmpix_putn_schar_schar(&putbuf.pos, sizeof(ncmagic2), ncmagic2);
+ }
+ else {
+ putbuf.version = 1;
+ status = ncmpix_putn_schar_schar(&putbuf.pos, sizeof(ncmagic1), ncmagic1);
+ }
+ if (status != NC_NOERR) return status;
+
+ /* copy numrecs, number of records */
+ nrecs = ncp->numrecs;
+ if (ncp->flags & NC_64BIT_DATA)
+ status = ncmpix_put_uint64((void**)(&putbuf.pos), nrecs);
+ else {
+ if (nrecs != (uint)nrecs) DEBUG_RETURN_ERROR(NC_EINTOVERFLOW)
+ status = ncmpix_put_uint32((void**)(&putbuf.pos), (uint)nrecs);
+ }
+ if (status != NC_NOERR) return status;
+
+ /* copy dim_list */
+ status = hdr_put_NC_dimarray(&putbuf, &ncp->dims);
+ if (status != NC_NOERR) return status;
+
+ /* copy gatt_list */
+ status = hdr_put_NC_attrarray(&putbuf, &ncp->attrs);
+ if (status != NC_NOERR) return status;
+
+ /* copy var_list */
+ status = hdr_put_NC_vararray(&putbuf, &ncp->vars);
+ if (status != NC_NOERR) return status;
+
+ ncp->nciop->put_size += putbuf.put_size;
+ ncp->nciop->get_size += putbuf.get_size;
+
+ return NC_NOERR;
+}
+
+/* End Of put NC */
+
+/* Begin Of get NC */
+
+/*
+ * Fetch the next header chunk. the chunk is 'gbp->size' bytes big
+ * Takes care to not overwrite leftover (unused) data in the buffer before
+ * fetching a new chunk: the current approach is to re-read the extra data.
+ *
+ * NOTE: An alternate approach (which we do not do) would be to save the old
+ * data, read the next chunk and then copy the old data into the new
+ * chunk. This alternate approach might help if it is important for reads
+ * to be aligned.
+ */
+static int
+hdr_fetch(bufferinfo *gbp) {
+ int rank, err=NC_NOERR, mpireturn;
+ MPI_Offset slack; /* any leftover data in the buffer */
+ MPI_Aint pos_addr, base_addr;
+
+ assert(gbp->base != NULL);
+
+#ifdef HAVE_MPI_GET_ADDRESS
+ MPI_Get_address(gbp->pos, &pos_addr);
+ MPI_Get_address(gbp->base, &base_addr);
+#else
+ MPI_Address(gbp->pos, &pos_addr);
+ MPI_Address(gbp->base, &base_addr);
+#endif
+ slack = gbp->size - (pos_addr - base_addr);
+ /* . if gbp->pos and gbp->base are the same, there is no leftover buffer
+ * data to worry about.
+ * In the other extreme, where gbp->size == (gbp->pos - gbp->base), then
+ * all data in the buffer has been consumed */
+ if (slack == gbp->size) slack = 0;
+
+ if (gbp->size != (size_t)gbp->size) DEBUG_RETURN_ERROR(NC_EINTOVERFLOW)
+ if (gbp->size != (int)gbp->size) DEBUG_RETURN_ERROR(NC_EINTOVERFLOW)
+
+ memset(gbp->base, 0, (size_t)gbp->size);
+ gbp->pos = gbp->base;
+ gbp->index = 0;
+
+ MPI_Comm_rank(gbp->nciop->comm, &rank);
+ if (rank == 0) {
+ MPI_Status mpistatus;
+ /* fileview is already entire file visible and MPI_File_read_at does
+ not change the file pointer */
+ TRACE_IO(MPI_File_read_at)(gbp->nciop->collective_fh,
+ (gbp->offset)-slack, gbp->base,
+ (int)gbp->size, MPI_BYTE, &mpistatus);
+ if (mpireturn != MPI_SUCCESS) {
+ err = ncmpii_handle_error(mpireturn, "MPI_File_read_at");
+ if (err == NC_EFILE) DEBUG_ASSIGN_ERROR(err, NC_EREAD)
+ }
+ else {
+ int get_size;
+ MPI_Get_count(&mpistatus, MPI_BYTE, &get_size);
+ gbp->get_size += get_size;
+ }
+ }
+ /* we might have had to backtrack */
+ gbp->offset += (gbp->size - slack);
+
+ if (gbp->safe_mode == 1) {
+ TRACE_COMM(MPI_Bcast)(&err, 1, MPI_INT, 0, gbp->nciop->comm);
+ if (err != NC_NOERR) return err;
+ }
+
+ /* broadcast root's read to other processes */
+ TRACE_COMM(MPI_Bcast)(gbp->base, (int)gbp->size, MPI_BYTE, 0, gbp->nciop->comm);
+
+ return err;
+}
+
+/*----< hdr_check_buffer() >--------------------------------------------------*/
+/* Ensure that 'nextread' bytes are available. */
+inline static int
+hdr_check_buffer(bufferinfo *gbp,
+ MPI_Offset nextread)
+{
+ MPI_Aint pos_addr, base_addr;
+
+#ifdef HAVE_MPI_GET_ADDRESS
+ MPI_Get_address(gbp->pos, &pos_addr);
+ MPI_Get_address(gbp->base, &base_addr);
+#else
+ MPI_Address(gbp->pos, &pos_addr);
+ MPI_Address(gbp->base, &base_addr);
+#endif
+ if (pos_addr + nextread <= base_addr + gbp->size)
+ return NC_NOERR;
+
+ return hdr_fetch(gbp);
+}
+
+/*----< hdr_get_NCtype() >----------------------------------------------------*/
+inline static int
+hdr_get_NCtype(bufferinfo *gbp,
+ NCtype *typep)
+{
+ /* NCtype is 4-byte integer */
+ uint type = 0;
+ int status = hdr_check_buffer(gbp, 4);
+ if (status != NC_NOERR) return status;
+
+ /* get an external unsigned 4-byte integer from the file */
+ status = ncmpix_get_uint32((const void**)(&gbp->pos), &type);
+ gbp->index += X_SIZEOF_INT;
+ if (status != NC_NOERR) return status;
+
+ *typep = (NCtype) type;
+ return NC_NOERR;
+}
+
+/*----< hdr_get_uint32() >---------------------------------------------------*/
+inline static int
+hdr_get_uint32(bufferinfo *gbp,
+ uint *xp)
+{
+ /* in CDF-1 format, all integers are 32-bit
+ * in CDF-2 format, only variable begin (starting file offset) is 64-bit
+ * in CDF-5 format, both variable's begin and size are 64-bit
+ */
+ int status = hdr_check_buffer(gbp, 4); /* size of int32 == 4 */
+ if (status != NC_NOERR) return status;
+ gbp->index += 4;
+
+ status = ncmpix_get_uint32((const void **)(&gbp->pos), xp);
+ return status;
+}
+
+/*----< hdr_get_uint64() >---------------------------------------------------*/
+inline static int
+hdr_get_uint64(bufferinfo *gbp,
+ uint64 *xp)
+{
+ /* in CDF-1 format, all integers are 32-bit
+ * in CDF-2 format, only variable begin (starting file offset) is 64-bit
+ * in CDF-5 format, both variable's begin and size are 64-bit
+ */
+ int status = hdr_check_buffer(gbp, 8); /* size of int64 == 8 */
+ if (status != NC_NOERR) return status;
+ gbp->index += 8;
+
+ status = ncmpix_get_uint64((const void **)(&gbp->pos), xp);
+ return status;
+}
+
+/*----< hdr_get_nc_type() >---------------------------------------------------*/
+inline static int
+hdr_get_nc_type(bufferinfo *gbp,
+ nc_type *typep)
+{
+ /* nc_type is 4-byte integer, X_SIZEOF_INT */
+ int status;
+ uint type;
+
+ status = hdr_check_buffer(gbp, X_SIZEOF_INT);
+ if (status != NC_NOERR) return status;
+
+ status = ncmpix_get_uint32((const void**)(&gbp->pos), &type);
+ gbp->index += X_SIZEOF_INT;
+ if (status != NC_NOERR) return status;
+
+ if (type != NC_BYTE &&
+ type != NC_CHAR &&
+ type != NC_UBYTE &&
+ type != NC_SHORT &&
+ type != NC_USHORT &&
+ type != NC_INT &&
+ type != NC_UINT &&
+ type != NC_FLOAT &&
+ type != NC_DOUBLE &&
+ type != NC_INT64 &&
+ type != NC_UINT64
+ )
+ DEBUG_RETURN_ERROR(NC_EINVAL)
+
+ *typep = (nc_type) type;
+ return NC_NOERR;
+}
+
+/*----< ncmpix_len_nctype() >------------------------------------------------*/
+int
+ncmpix_len_nctype(nc_type type) {
+ switch(type) {
+ case NC_BYTE:
+ case NC_CHAR:
+ case NC_UBYTE: return X_SIZEOF_CHAR;
+ case NC_SHORT:
+ case NC_USHORT: return X_SIZEOF_SHORT;
+ case NC_INT:
+ case NC_UINT: return X_SIZEOF_INT;
+ case NC_FLOAT: return X_SIZEOF_FLOAT;
+ case NC_DOUBLE: return X_SIZEOF_DOUBLE;
+ case NC_INT64:
+ case NC_UINT64: return X_SIZEOF_INT64;
+ default: assert("ncmpix_len_nctype bad type" == 0);
+ }
+ return 0;
+}
+
+/*----< hdr_get_NC_name() >---------------------------------------------------*/
+static int
+hdr_get_NC_name(bufferinfo *gbp,
+ NC_string **ncstrpp)
+{
+ /* netCDF file format:
+ * ...
+ * name = nelems namestring
+ * nelems = NON_NEG
+ * namestring = ID1 [IDN ...] padding
+ * ID1 = alphanumeric | '_'
+ * IDN = alphanumeric | special1 | special2
+ * padding = <0, 1, 2, or 3 bytes to next 4-byte boundary>
+ * NON_NEG = <non-negative INT> | // CDF-1 and CDF-2
+ * <non-negative INT64> // CDF-5
+ */
+ int status;
+ MPI_Offset nchars, nbytes, padding, bufremain, strcount;
+ NC_string *ncstrp;
+ char *cpos, pad[X_ALIGN-1];
+ MPI_Aint pos_addr, base_addr;
+
+ /* get nelems */
+ if (gbp->version == 5) {
+ uint64 tmp;
+ status = hdr_get_uint64(gbp, &tmp);
+ nchars = (MPI_Offset)tmp;
+ }
+ else {
+ uint tmp;
+ status = hdr_get_uint32(gbp, &tmp);
+ nchars = (MPI_Offset)tmp;
+ }
+ if (status != NC_NOERR) return status;
+
+ /* Allocate a NC_string structure large enough to hold nchars characters */
+ ncstrp = ncmpii_new_NC_string((size_t)nchars, NULL);
+ if (ncstrp == NULL) DEBUG_RETURN_ERROR(NC_ENOMEM)
+
+ nbytes = nchars * X_SIZEOF_CHAR;
+ padding = _RNDUP(X_SIZEOF_CHAR * ncstrp->nchars, X_ALIGN)
+ - X_SIZEOF_CHAR * ncstrp->nchars;
+#ifdef HAVE_MPI_GET_ADDRESS
+ MPI_Get_address(gbp->pos, &pos_addr);
+ MPI_Get_address(gbp->base, &base_addr);
+#else
+ MPI_Address(gbp->pos, &pos_addr);
+ MPI_Address(gbp->base, &base_addr);
+#endif
+ bufremain = gbp->size - (pos_addr - base_addr);
+ cpos = ncstrp->cp;
+
+ /* get namestring with padding */
+ while (nbytes > 0) {
+ if (bufremain > 0) {
+ strcount = MIN(bufremain, nbytes);
+ if (strcount != (size_t)strcount) DEBUG_RETURN_ERROR(NC_EINTOVERFLOW)
+ memcpy(cpos, gbp->pos, (size_t)strcount);
+ nbytes -= strcount;
+ gbp->pos = (void *)((char *)gbp->pos + strcount);
+ gbp->index += strcount;
+ cpos += strcount;
+ bufremain -= strcount;
+ } else {
+ status = hdr_fetch(gbp);
+ if (status != NC_NOERR) {
+ ncmpii_free_NC_string(ncstrp);
+ return status;
+ }
+ bufremain = gbp->size;
+ }
+ }
+
+ /* handle the padding */
+ if (padding > 0) {
+ memset(pad, 0, X_ALIGN-1);
+ if (memcmp(gbp->pos, pad, (size_t)padding) != 0) {
+ ncmpii_free_NC_string(ncstrp);
+ DEBUG_RETURN_ERROR(NC_EINVAL)
+ }
+ gbp->pos = (void *)((char *)gbp->pos + padding);
+ gbp->index += padding;
+ }
+
+ *ncstrpp = ncstrp;
+
+ return NC_NOERR;
+}
+
+/*----< hdr_get_NC_dim() >----------------------------------------------------*/
+inline static int
+hdr_get_NC_dim(bufferinfo *gbp,
+ NC_dim **dimpp)
+{
+ /* netCDF file format:
+ * ...
+ * dim = name dim_length
+ * dim_length = NON_NEG
+ * NON_NEG = <non-negative INT> | // CDF-1 and CDF-2
+ * <non-negative INT64> // CDF-5
+ */
+ int status;
+ NC_string *ncstrp;
+ NC_dim *dimp;
+
+ /* get name */
+ status = hdr_get_NC_name(gbp, &ncstrp);
+ if (status != NC_NOERR) return status;
+
+ dimp = ncmpii_new_x_NC_dim(ncstrp);
+ if (dimp == NULL) DEBUG_RETURN_ERROR(NC_ENOMEM)
+
+ /* get dim_length */
+ if (gbp->version == 5) {
+ uint64 tmp;
+ status = hdr_get_uint64(gbp, &tmp);
+ dimp->size = (MPI_Offset)tmp;
+ }
+ else {
+ uint tmp;
+ status = hdr_get_uint32(gbp, &tmp);
+ dimp->size = (MPI_Offset)tmp;
+ }
+ if (status != NC_NOERR) {
+ ncmpii_free_NC_dim(dimp); /* frees name */
+ return status;
+ }
+
+ *dimpp = dimp;
+ return NC_NOERR;
+}
+
+/*----< hdr_get_NC_dimarray() >-----------------------------------------------*/
+static int
+hdr_get_NC_dimarray(bufferinfo *gbp,
+ NC_dimarray *ncap)
+{
+ /* netCDF file format:
+ * ...
+ * dim_list = ABSENT | NC_DIMENSION nelems [dim ...]
+ * ABSENT = ZERO ZERO | // list is not present for CDF-1 and 2
+ * ZERO ZERO64 // for CDF-5
+ * ZERO = \x00 \x00 \x00 \x00 // 32-bit zero
+ * ZERO64 = \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 // 64-bit zero
+ * NC_DIMENSION = \x00 \x00 \x00 \x0A // tag for list of dimensions
+ * nelems = NON_NEG // number of elements in following sequence
+ * NON_NEG = <non-negative INT> | // CDF-1 and CDF-2
+ * <non-negative INT64> // CDF-5
+ */
+ int i, status;
+ NCtype type = NC_UNSPECIFIED;
+ MPI_Offset ndefined;
+
+ assert(gbp != NULL && gbp->pos != NULL);
+ assert(ncap != NULL);
+ assert(ncap->value == NULL);
+
+ /* get NCtype (NC_DIMENSION) */
+ status = hdr_get_NCtype(gbp, &type);
+ if (status != NC_NOERR) return status;
+
+ /* get nelems */
+ if (gbp->version == 5) {
+ uint64 tmp;
+ status = hdr_get_uint64(gbp, &tmp);
+ ndefined = (MPI_Offset)tmp;
+ }
+ else {
+ uint tmp;
+ status = hdr_get_uint32(gbp, &tmp);
+ ndefined = (MPI_Offset)tmp;
+ }
+ if (status != NC_NOERR) return status;
+ if (ndefined != (int)ndefined) DEBUG_RETURN_ERROR(NC_EINTOVERFLOW)
+ ncap->ndefined = (int)ndefined;
+ /* TODO: we should allow ndefined > 2^32, considering change the data type
+ * of ndefined from int to MPI_Offset */
+
+ if (ndefined == 0) {
+ if (type != NC_DIMENSION && type != NC_UNSPECIFIED)
+ DEBUG_RETURN_ERROR(NC_EINVAL)
+ } else {
+ if (type != NC_DIMENSION) DEBUG_RETURN_ERROR(NC_EINVAL)
+
+ ncap->value = (NC_dim **) NCI_Malloc((size_t)ndefined * sizeof(NC_dim*));
+ if (ncap->value == NULL) DEBUG_RETURN_ERROR(NC_ENOMEM)
+ ncap->nalloc = (int)ndefined;
+ /* TODO: we should allow nalloc > 2^32, considering change the data
+ * type of nalloc from int to MPI_Offset */
+
+ for (i=0; i<ndefined; i++) {
+ status = hdr_get_NC_dim(gbp, ncap->value + i);
+ if (status != NC_NOERR) { /* error: fail to get the next dim */
+ ncap->ndefined = i;
+ ncmpii_free_NC_dimarray(ncap);
+ return status;
+ }
+ }
+ }
+
+ return NC_NOERR;
+}
+
+/*----< hdr_get_NC_attrV() >--------------------------------------------------*/
+static int
+hdr_get_NC_attrV(bufferinfo *gbp,
+ NC_attr *attrp)
+{
+ /* netCDF file format:
+ * ...
+ * attr = name nc_type nelems [values ...]
+ * ...
+ * values = bytes | chars | shorts | ints | floats | doubles
+ * bytes = [BYTE ...] padding
+ * chars = [CHAR ...] padding
+ * shorts = [SHORT ...] padding
+ * ints = [INT ...]
+ * floats = [FLOAT ...]
+ * doubles = [DOUBLE ...]
+ * padding = <0, 1, 2, or 3 bytes to next 4-byte boundary>
+ */
+ int status;
+ void *value = attrp->xvalue;
+ char pad[X_ALIGN-1];
+ MPI_Offset nbytes, padding, bufremain, attcount;
+ MPI_Aint pos_addr, base_addr;
+
+ nbytes = attrp->nelems * ncmpix_len_nctype(attrp->type);
+ padding = attrp->xsz - nbytes;
+#ifdef HAVE_MPI_GET_ADDRESS
+ MPI_Get_address(gbp->pos, &pos_addr);
+ MPI_Get_address(gbp->base, &base_addr);
+#else
+ MPI_Address(gbp->pos, &pos_addr);
+ MPI_Address(gbp->base, &base_addr);
+#endif
+ bufremain = gbp->size - (pos_addr - base_addr);
+
+ /* get values */
+ while (nbytes > 0) {
+ if (bufremain > 0) {
+ attcount = MIN(bufremain, nbytes);
+ if (attcount != (size_t)attcount) DEBUG_RETURN_ERROR(NC_EINTOVERFLOW)
+ memcpy(value, gbp->pos, (size_t)attcount);
+ nbytes -= attcount;
+ gbp->pos = (void *)((char *)gbp->pos + attcount);
+ gbp->index += attcount;
+ value = (void *)((char *)value + attcount);
+ bufremain -= attcount;
+ } else {
+ status = hdr_fetch(gbp);
+ if (status != NC_NOERR) return status;
+ bufremain = gbp->size;
+ }
+ }
+
+ /* handle the padding */
+ if (padding > 0) {
+ memset(pad, 0, X_ALIGN-1);
+ if (memcmp(gbp->pos, pad, (size_t)padding) != 0) DEBUG_RETURN_ERROR(NC_EINVAL)
+ gbp->pos = (void *)((char *)gbp->pos + padding);
+ gbp->index += padding;
+ }
+
+ return NC_NOERR;
+}
+
+/*----< hdr_get_NC_attr() >---------------------------------------------------*/
+static int
+hdr_get_NC_attr(bufferinfo *gbp,
+ NC_attr **attrpp)
+{
+ /* netCDF file format:
+ * ...
+ * attr = name nc_type nelems [values ...]
+ * nc_type = NC_BYTE | NC_CHAR | NC_SHORT | ...
+ * nelems = NON_NEG // number of elements in following sequence
+ * NON_NEG = <non-negative INT> | // CDF-1 and CDF-2
+ * <non-negative INT64> // CDF-5
+ */
+ int status;
+ NC_string *strp;
+ nc_type type;
+ MPI_Offset nelems;
+ NC_attr *attrp;
+
+ /* get name */
+ status = hdr_get_NC_name(gbp, &strp);
+ if (status != NC_NOERR) return status;
+
+ /* get nc_type */
+ status = hdr_get_nc_type(gbp, &type);
+ if (status != NC_NOERR) {
+ ncmpii_free_NC_string(strp);
+ return status;
+ }
+
+ /* get nelems */
+ if (gbp->version == 5) {
+ uint64 tmp;
+ status = hdr_get_uint64(gbp, &tmp);
+ nelems = (MPI_Offset)tmp;
+ }
+ else {
+ uint tmp;
+ status = hdr_get_uint32(gbp, &tmp);
+ nelems = (MPI_Offset)tmp;
+ }
+ if (status != NC_NOERR) {
+ ncmpii_free_NC_string(strp);
+ return status;
+ }
+
+ /* allocate space for attribute object */
+ attrp = ncmpii_new_x_NC_attr(strp, type, nelems);
+ if (attrp == NULL) {
+ ncmpii_free_NC_string(strp);
+ return status;
+ }
+
+ /* get [values ...] */
+ status = hdr_get_NC_attrV(gbp, attrp);
+ if (status != NC_NOERR) {
+ ncmpii_free_NC_attr(attrp); /* frees strp */
+ return status;
+ }
+
+ *attrpp = attrp;
+ return NC_NOERR;
+}
+
+/*----< hdr_get_NC_attrarray() >----------------------------------------------*/
+static int
+hdr_get_NC_attrarray(bufferinfo *gbp,
+ NC_attrarray *ncap)
+{
+ /* netCDF file format:
+ * ...
+ * att_list = ABSENT | NC_ATTRIBUTE nelems [attr ...]
+ * ABSENT = ZERO ZERO | // list is not present for CDF-1 and 2
+ * ZERO ZERO64 // for CDF-5
+ * ZERO = \x00 \x00 \x00 \x00 // 32-bit zero
+ * ZERO64 = \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 // 64-bit zero
+ * NC_ATTRIBUTE = \x00 \x00 \x00 \x0C // tag for list of attributes
+ * nelems = NON_NEG // number of elements in following sequence
+ * NON_NEG = <non-negative INT> | // CDF-1 and CDF-2
+ * <non-negative INT64> // CDF-5
+ */
+ int i, status;
+ NCtype type = NC_UNSPECIFIED;
+ MPI_Offset ndefined;
+
+ assert(gbp != NULL && gbp->pos != NULL);
+ assert(ncap != NULL);
+ assert(ncap->value == NULL);
+
+ /* get NCtype (NC_ATTRIBUTE) */
+ status = hdr_get_NCtype(gbp, &type);
+ if (status != NC_NOERR) return status;
+
+ /* get nelems */
+ if (gbp->version == 5) {
+ uint64 tmp;
+ status = hdr_get_uint64(gbp, &tmp);
+ ndefined = (MPI_Offset)tmp;
+ }
+ else {
+ uint tmp;
+ status = hdr_get_uint32(gbp, &tmp);
+ ndefined = (MPI_Offset)tmp;
+ }
+ if (status != NC_NOERR) return status;
+ if (ndefined != (int)ndefined) DEBUG_RETURN_ERROR(NC_EINTOVERFLOW)
+ ncap->ndefined = (int)ndefined;
+
+ if (ndefined == 0) {
+ if (type != NC_ATTRIBUTE && type != NC_UNSPECIFIED)
+ DEBUG_RETURN_ERROR(NC_EINVAL)
+ } else {
+ if (type != NC_ATTRIBUTE) DEBUG_RETURN_ERROR(NC_EINVAL)
+
+ ncap->value = (NC_attr **)NCI_Malloc((size_t)ndefined * sizeof(NC_attr*));
+ if (ncap->value == NULL) DEBUG_RETURN_ERROR(NC_ENOMEM)
+ ncap->nalloc = (int)ndefined;
+
+ /* get [attr ...] */
+ for (i=0; i<ndefined; i++) {
+ status = hdr_get_NC_attr(gbp, ncap->value + i);
+ if (status != NC_NOERR) { /* Error: fail to get the next att */
+ ncap->ndefined = i;
+ ncmpii_free_NC_attrarray(ncap);
+ return status;
+ }
+ }
+ }
+
+ return NC_NOERR;
+}
+
+/*----< hdr_get_NC_var() >---------------------------------------------------*/
+static int
+hdr_get_NC_var(bufferinfo *gbp,
+ NC_var **varpp)
+{
+ /* netCDF file format:
+ * netcdf_file = header data
+ * header = magic numrecs dim_list gatt_list var_list
+ * ...
+ * var = name nelems [dimid ...] vatt_list nc_type vsize begin
+ * nelems = NON_NEG
+ * dimid = NON_NEG
+ * vatt_list = att_list
+ * nc_type = NC_BYTE | NC_CHAR | NC_SHORT | ...
+ * vsize = NON_NEG
+ * begin = OFFSET // Variable start location.
+ * OFFSET = <non-negative INT> | // CDF-1
+ * <non-negative INT64> // CDF-2 and CDF-5
+ * NON_NEG = <non-negative INT> | // CDF-1 and CDF-2
+ * <non-negative INT64> // CDF-5
+ */
+ int status;
+ NC_string *strp;
+ MPI_Offset ndims=0, dim;
+ MPI_Offset tmp_dimids=0;
+ NC_var *varp;
+
+ /* get name */
+ status = hdr_get_NC_name(gbp, &strp);
+ if (status != NC_NOERR) return status;
+
+ /* nelems */
+ if (gbp->version == 5) {
+ uint64 tmp;
+ status = hdr_get_uint64(gbp, &tmp);
+ ndims = (MPI_Offset)tmp;
+ }
+ else {
+ uint tmp;
+ status = hdr_get_uint32(gbp, &tmp);
+ ndims = (MPI_Offset)tmp;
+ }
+ if (status != NC_NOERR) {
+ ncmpii_free_NC_string(strp);
+ return status;
+ }
+ if (ndims != (int)ndims) DEBUG_RETURN_ERROR(NC_EINTOVERFLOW)
+
+ /* allocate space for var object */
+ varp = ncmpii_new_x_NC_var(strp, (int)ndims);
+ if (varp == NULL) {
+ ncmpii_free_NC_string(strp);
+ DEBUG_RETURN_ERROR(NC_ENOMEM)
+ }
+
+ /* get [dimid ...] */
+ for (dim=0; dim<ndims; dim++) {
+ status = hdr_check_buffer(gbp, (gbp->version == 5 ? 8 : 4));
+ if (status != NC_NOERR) {
+ ncmpii_free_NC_var(varp);
+ return status;
+ }
+ if (gbp->version == 5) {
+ uint64 tmp;
+ status = hdr_get_uint64(gbp, &tmp);
+ tmp_dimids = (MPI_Offset)tmp;
+ }
+ else {
+ uint tmp;
+ status = hdr_get_uint32(gbp, &tmp);
+ tmp_dimids = (MPI_Offset)tmp;
+ }
+ /* TODO: consider change the data type of dimids from int to
+ * MPI_Offset */
+ varp->dimids[dim] = (int)tmp_dimids;
+ if (status != NC_NOERR) {
+ return status;
+ }
+ }
+
+ /* get vatt_list */
+ status = hdr_get_NC_attrarray(gbp, &varp->attrs);
+ if (status != NC_NOERR) {
+ ncmpii_free_NC_var(varp);
+ return status;
+ }
+
+ /* get nc_type */
+ status = hdr_get_nc_type(gbp, &varp->type);
+ if (status != NC_NOERR) {
+ ncmpii_free_NC_var(varp);
+ return status;
+ }
+
+ /* get vsize */
+ if (gbp->version == 5) {
+ uint64 tmp;
+ status = hdr_get_uint64(gbp, &tmp);
+ varp->len = (MPI_Offset)tmp;
+ }
+ else {
+ uint tmp;
+ status = hdr_get_uint32(gbp, &tmp);
+ varp->len = (MPI_Offset)tmp;
+ }
+ if (status != NC_NOERR) {
+ ncmpii_free_NC_var(varp);
+ return status;
+ }
+ /* As described in CDF-2 format specification, vsize is redundant.
+ Its value may be computed from the product of dimension lengths.
+ In CDF-2, vsize is a 4-byte integer. So, if we define a variable of
+ less than 2^32 elements but size > 2^32-4 bytes, then vsize in CDF-2
+ will overflow. Recompute varp->len can ignore an overflowed value in
+ vsize stored in the file and hence bypass the limitation of CDF-2 on
+ variable size of 2^32-4 bytes.
+
+ Later on, back to ncmpii_hdr_get_NC(), ncmpii_NC_computeshapes() is
+ called which recomputes varp->len using the dimension values and hence
+ overwrites the value read from file above.
+
+ In summary, PnetCDF now ignores the value of vsize stored in the file
+ header.
+ */
+
+ /* next element is 'begin' */
+ status = hdr_check_buffer(gbp, (gbp->version == 1 ? 4 : 8));
+ if (status != NC_NOERR) {
+ ncmpii_free_NC_var(varp);
+ return status;
+ }
+
+ /* get begin */
+ if (gbp->version == 1) {
+ uint tmp=0;
+ status = ncmpix_get_uint32((const void **)(&gbp->pos), &tmp);
+ varp->begin = (MPI_Offset)tmp;
+ }
+ else {
+ uint64 tmp=0;
+ status = ncmpix_get_uint64((const void **)(&gbp->pos), &tmp);
+ varp->begin = (MPI_Offset)tmp;
+ }
+ if (status != NC_NOERR) {
+ ncmpii_free_NC_var(varp);
+ return status;
+ }
+
+ *varpp = varp;
+ return NC_NOERR;
+}
+
+/*----< hdr_get_NC_vararray() >----------------------------------------------*/
+static int
+hdr_get_NC_vararray(bufferinfo *gbp,
+ NC_vararray *ncap)
+{
+ /* netCDF file format:
+ * netcdf_file = header data
+ * header = magic numrecs dim_list gatt_list var_list
+ * ...
+ * var_list = ABSENT | NC_VARIABLE nelems [var ...]
+ * ABSENT = ZERO ZERO | // list is not present for CDF-1 and 2
+ * ZERO ZERO64 // for CDF-5
+ * ZERO = \x00 \x00 \x00 \x00 // 32-bit zero
+ * ZERO64 = \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 // 64-bit zero
+ * NC_VARIABLE = \x00 \x00 \x00 \x0B // tag for list of variables
+ * nelems = NON_NEG // number of elements in following sequence
+ * NON_NEG = <non-negative INT> | // CDF-1 and CDF-2
+ * <non-negative INT64> // CDF-5
+ */
+ int i, status;
+ NCtype type = NC_UNSPECIFIED;
+ MPI_Offset ndefined;
+
+ assert(gbp != NULL && gbp->pos != NULL);
+ assert(ncap != NULL);
+ assert(ncap->value == NULL);
+
+ /* get NCtype (NC_VARIABLE) from gbp buffer */
+ status = hdr_get_NCtype(gbp, &type);
+ if (status != NC_NOERR) return status;
+
+ /* get nelems (number of variables) from gbp buffer */
+ if (gbp->version == 5) {
+ uint64 tmp;
+ status = hdr_get_uint64(gbp, &tmp);
+ ndefined = (MPI_Offset)tmp;
+ }
+ else {
+ uint tmp;
+ status = hdr_get_uint32(gbp, &tmp);
+ ndefined = (MPI_Offset)tmp;
+ }
+ if (status != NC_NOERR) return status;
+ if (ndefined != (int)ndefined) DEBUG_RETURN_ERROR(NC_EINTOVERFLOW)
+ ncap->ndefined = (int)ndefined;
+ /* TODO: we should allow ndefined > 2^32, considering change the data type
+ * of ndefined from int to MPI_Offset */
+
+ if (ndefined == 0) { /* no variable defined */
+ if (type != NC_VARIABLE && type != NC_UNSPECIFIED)
+ DEBUG_RETURN_ERROR(NC_EINVAL)
+ } else {
+ if (type != NC_VARIABLE) DEBUG_RETURN_ERROR(NC_EINVAL)
+
+ ncap->value = (NC_var **) NCI_Malloc((size_t)ndefined * sizeof(NC_var*));
+ if (ncap->value == NULL) DEBUG_RETURN_ERROR(NC_ENOMEM)
+ ncap->nalloc = (int)ndefined;
+
+ /* get [var ...] */
+ for (i=0; i<ndefined; i++) {
+ status = hdr_get_NC_var(gbp, ncap->value + i);
+ if (status != NC_NOERR) { /* Error: fail to get the next var */
+ ncap->ndefined = i;
+ ncmpii_free_NC_vararray(ncap);
+ return status;
+ }
+ }
+ }
+
+ return NC_NOERR;
+}
+
+/*----< ncmpii_hdr_get_NC() >------------------------------------------------*/
+/* CDF format specification
+ * netcdf_file = header data
+ * header = magic numrecs dim_list gatt_list var_list
+ * magic = 'C' 'D' 'F' VERSION
+ * VERSION = \x01 | // classic format
+ * \x02 | // 64-bit offset format
+ * \x05 // 64-bit data format
+ * numrecs = NON_NEG | STREAMING // length of record dimension
+ * dim_list = ABSENT | NC_DIMENSION nelems [dim ...]
+ * gatt_list = att_list // global attributes
+ * att_list = ABSENT | NC_ATTRIBUTE nelems [attr ...]
+ * var_list = ABSENT | NC_VARIABLE nelems [var ...]
+ */
+int
+ncmpii_hdr_get_NC(NC *ncp)
+{
+ int status;
+ bufferinfo getbuf;
+ schar magic[sizeof(ncmagic1)];
+ MPI_Offset nrecs = 0;
+ MPI_Aint pos_addr, base_addr;
+
+ assert(ncp != NULL);
+
+ /* Initialize the get buffer that stores the header read from the file */
+ getbuf.nciop = ncp->nciop;
+ getbuf.offset = 0; /* read from start of the file */
+ getbuf.put_size = 0; /* amount of writes so far in bytes */
+ getbuf.get_size = 0; /* amount of reads so far in bytes */
+ getbuf.safe_mode = ncp->safe_mode;
+
+ /* CDF-5's minimum header size is 4 bytes more than CDF-1 and CDF-2's */
+ getbuf.size = _RNDUP( MAX(MIN_NC_XSZ+4, ncp->chunk), X_ALIGN );
+ if (getbuf.size > NC_DEFAULT_CHUNKSIZE)
+ getbuf.size = NC_DEFAULT_CHUNKSIZE;
+
+ if (getbuf.size != (size_t)getbuf.size) DEBUG_RETURN_ERROR(NC_EINTOVERFLOW)
+ getbuf.pos = getbuf.base = (void *)NCI_Malloc((size_t)getbuf.size);
+ getbuf.index = 0;
+
+ /* Fetch the next header chunk. The chunk is 'gbp->size' bytes big */
+ status = hdr_fetch(&getbuf);
+ if (status != NC_NOERR) return status;
+
+ /* processing the header from getbuf, the get buffer */
+
+ /* First get the file format information, magic */
+ memset(magic, 0, sizeof(magic));
+ status = ncmpix_getn_schar_schar((const void **)(&getbuf.pos),
+ sizeof(magic), magic);
+ if (status != NC_NOERR) return status;
+ getbuf.index += (MPI_Offset)sizeof(magic);
+
+ /* don't need to worry about CDF-1 or CDF-2
+ * if the first bits are not 'CDF'
+ */
+ if (memcmp(magic, ncmagic1, sizeof(ncmagic1)-1) != 0) {
+ NCI_Free(getbuf.base);
+ DEBUG_RETURN_ERROR(NC_ENOTNC)
+ }
+
+ /* check version number in last byte of magic */
+ if (magic[sizeof(ncmagic1)-1] == 0x1) {
+ getbuf.version = 1;
+ fSet(ncp->flags, NC_32BIT);
+ } else if (magic[sizeof(ncmagic1)-1] == 0x2) {
+ getbuf.version = 2;
+ fSet(ncp->flags, NC_64BIT_OFFSET);
+ if (SIZEOF_MPI_OFFSET != 8) {
+ /* take the easy way out: if we can't support all CDF-2
+ * files, return immediately */
+ NCI_Free(getbuf.base);
+ DEBUG_RETURN_ERROR(NC_ESMALL)
+ }
+ } else if (magic[sizeof(ncmagic1)-1] == 0x5) {
+ getbuf.version = 5;
+ fSet(ncp->flags, NC_64BIT_DATA);
+ if (SIZEOF_MPI_OFFSET != 8) {
+ NCI_Free(getbuf.base);
+ DEBUG_RETURN_ERROR(NC_ESMALL)
+ }
+ } else {
+ NCI_Free(getbuf.base);
+ DEBUG_RETURN_ERROR(NC_ENOTNC) /* not an netCDF file */
+ }
+
+ /** Ensure that 'nextread' bytes (numrecs) are available. */
+ status = hdr_check_buffer(&getbuf, (getbuf.version == 5) ? 8 : 4);
+ if(status != NC_NOERR) {
+ NCI_Free(getbuf.base);
+ return status;
+ }
+
+ /* get numrecs from getbuf into ncp */
+ if (getbuf.version == 5) {
+ uint64 tmp=0;
+ status = ncmpix_get_uint64((const void **)(&getbuf.pos), &tmp);
+ nrecs = (MPI_Offset)tmp;
+ }
+ else {
+ uint tmp=0;
+ status = ncmpix_get_uint32((const void **)(&getbuf.pos), &tmp);
+ nrecs = (MPI_Offset)tmp;
+ }
+ if (status != NC_NOERR) {
+ NCI_Free(getbuf.base);
+ return status;
+ }
+
+ if (getbuf.version == 5)
+ getbuf.index += X_SIZEOF_INT64;
+ else
+ getbuf.index += X_SIZEOF_SIZE_T;
+
+ ncp->numrecs = nrecs;
+
+#ifdef HAVE_MPI_GET_ADDRESS
+ MPI_Get_address(getbuf.pos, &pos_addr);
+ MPI_Get_address(getbuf.base, &base_addr);
+#else
+ MPI_Address(getbuf.pos, &pos_addr);
+ MPI_Address(getbuf.base, &base_addr);
+#endif
+ assert(pos_addr < base_addr + getbuf.size);
+
+ /* get dim_list from getbuf into ncp */
+ status = hdr_get_NC_dimarray(&getbuf, &ncp->dims);
+ if (status != NC_NOERR) {
+ NCI_Free(getbuf.base);
+ return status;
+ }
+
+ /* get gatt_list from getbuf into ncp */
+ status = hdr_get_NC_attrarray(&getbuf, &ncp->attrs);
+ if (status != NC_NOERR) {
+ NCI_Free(getbuf.base);
+ return status;
+ }
+
+ /* get var_list from getbuf into ncp */
+ status = hdr_get_NC_vararray(&getbuf, &ncp->vars);
+ if (status != NC_NOERR) {
+ NCI_Free(getbuf.base);
+ return status;
+ }
+
+ /* get the un-aligned size occupied by the file header */
+ ncp->xsz = ncmpii_hdr_len_NC(ncp);
+
+ /* Recompute the shapes of all variables
+ * Sets ncp->begin_var to start of first variable.
+ * Sets ncp->begin_rec to start of first record variable.
+ */
+ status = ncmpii_NC_computeshapes(ncp);
+
+ NCI_Free(getbuf.base);
+
+ ncp->nciop->put_size += getbuf.put_size;
+ ncp->nciop->get_size += getbuf.get_size;
+
+ return status;
+}
+
+/* End Of get NC */
+
+#define WARN_STR "Warning (inconsistent metadata):"
+
+/*----< ncmpii_comp_dims() >--------------------------------------------------*/
+/* compare the local copy of dim_list against root's
+ * If inconsistency is detected, overwrite local's with root's
+ * this function is collective.
+ */
+static int
+ncmpii_comp_dims(int safe_mode,
+ NC_dimarray *root_dim,
+ NC_dimarray *local_dim)
+{
+ int i, err, status=NC_NOERR;
+
+ if (root_dim->ndefined != local_dim->ndefined) {
+ if (safe_mode)
+ printf("%s number of dimensions (local=%d, root=%d)\n",
+ WARN_STR, local_dim->ndefined, root_dim->ndefined);
+ DEBUG_ASSIGN_ERROR(status, NC_EMULTIDEFINE_DIM_NUM)
+ }
+
+ for (i=0; i<root_dim->ndefined; i++) {
+
+ if (i >= local_dim->ndefined) { /* if local list is shorter */
+ /* copy root's dim to local */
+ NC_dim *new_dim = dup_NC_dim(root_dim->value[i]);
+ err = incr_NC_dimarray(local_dim, new_dim);
+ if (err != NC_NOERR) return err; /* this is a fatal error */
+ continue;
+ }
+
+ /* check dimension name */
+ NC_string *root_name, *local_name;
+ root_name = root_dim->value[i]->name;
+ local_name = local_dim->value[i]->name;
+
+ err = NC_NOERR;
+ if (root_name->nchars != local_name->nchars) {
+ if (safe_mode)
+ printf("%s dimension name length (local=%lld, root=%lld)\n",
+ WARN_STR, local_name->nchars, root_name->nchars);
+ DEBUG_ASSIGN_ERROR(err, NC_EMULTIDEFINE_DIM_NAME)
+ }
+ else if (memcmp(root_name->cp, local_name->cp, (size_t)root_name->nchars) != 0) {
+ if (safe_mode)
+ printf("%s dimension name (local=%s, root=%s)\n",
+ WARN_STR, local_name->cp, root_name->cp);
+ DEBUG_ASSIGN_ERROR(err, NC_EMULTIDEFINE_DIM_NAME)
+ }
+ else if (root_dim->value[i]->size != local_dim->value[i]->size) {
+ /* check dimension size */
+ if (safe_mode)
+ printf("%s dimension %s's size (local=%lld, root=%lld)\n",
+ WARN_STR, root_dim->value[i]->name->cp,
+ root_dim->value[i]->size, local_dim->value[i]->size);
+ DEBUG_ASSIGN_ERROR(err, NC_EMULTIDEFINE_DIM_SIZE)
+ }
+ if (status == NC_NOERR) status = err;
+
+ /* overwrite local's dim with root's */
+ if (err != NC_NOERR) {
+ ncmpii_free_NC_dim(local_dim->value[i]);
+ local_dim->value[i] = dup_NC_dim(root_dim->value[i]);
+ }
+ }
+
+ /* delete extra dimensions defined only in local copy */
+ for (; i<local_dim->ndefined; i++)
+ ncmpii_free_NC_dim(local_dim->value[i]);
+
+ local_dim->ndefined = root_dim->ndefined;
+
+ return status;
+}
+
+/*----< ncmpii_comp_attrs() >-------------------------------------------------*/
+/* compare the local copy of attr_list against root's
+ * If inconsistency is detected, overwrite local's with root's
+ */
+static int
+ncmpii_comp_attrs(int safe_mode,
+ NC_attrarray *root_attr,
+ NC_attrarray *local_attr)
+{
+ int i, j, err, status=NC_NOERR;
+ char *msg;
+
+ /* check if the numbers of attributes are the same */
+ if (root_attr->ndefined != local_attr->ndefined) {
+ if (safe_mode)
+ printf("%s number of attributes (root=%d, local=%d)\n",
+ WARN_STR, root_attr->ndefined, local_attr->ndefined);
+ DEBUG_ASSIGN_ERROR(status, NC_EMULTIDEFINE_ATTR_NUM)
+ }
+
+ for (i=0; i<root_attr->ndefined; i++) {
+
+ if (i >= local_attr->ndefined) { /* if local list is shorter */
+ /* copy root's attr to local */
+ NC_attr *new_attr = dup_NC_attr(root_attr->value[i]);
+ err = incr_NC_attrarray(local_attr, new_attr);
+ if (err != NC_NOERR) return err; /* a fatal error */
+ continue;
+ }
+
+ NC_attr *v1 = root_attr->value[i];
+ NC_attr *v2 = local_attr->value[i];
+ char *name = v1->name->cp;
+
+#define ATTR_WARN(msg, attr, root, local) \
+ if (safe_mode) printf(msg, WARN_STR, attr, root, local);
+
+#define ATTR_WARN_J(msg, attr, j, root, local) \
+ if (safe_mode) printf(msg, WARN_STR, attr, j, root, local);
+
+ err = NC_NOERR;
+ if (v1->name->nchars != v2->name->nchars ||
+ memcmp(name, v2->name->cp, (size_t)v1->name->nchars) != 0) {
+ msg ="%s attribute %s (root=%s, local=%s)\n";
+ ATTR_WARN(msg, "name", name, v2->name->cp)
+ DEBUG_ASSIGN_ERROR(err, NC_EMULTIDEFINE_ATTR_NAME)
+ }
+ else if (v1->type != v2->type) {
+ msg = "%s attribute \"%s\" type (root=%d, local=%d)\n";
+ ATTR_WARN(msg, name, v1->type, v2->type)
+ DEBUG_ASSIGN_ERROR(err, NC_EMULTIDEFINE_ATTR_TYPE)
+ }
+ else if (v1->nelems != v2->nelems) {
+ msg = "%s attribute \"%s\" length (root=%lld, local=%lld)\n";
+ ATTR_WARN(msg, name, lld(v1->nelems), lld(v2->nelems))
+ DEBUG_ASSIGN_ERROR(err, NC_EMULTIDEFINE_ATTR_LEN)
+ }
+ else if (v1->xsz != v2->xsz) { /* internal check */
+ msg = "%s attribute \"%s\" size (root=%lld, local=%lld)\n";
+ ATTR_WARN(msg, name, lld(v1->xsz), lld(v2->xsz))
+ DEBUG_ASSIGN_ERROR(err, NC_EMULTIDEFINE_ATTR_SIZE)
+ }
+ /* hereinafter, we have v1->nelems == v2->nelems */
+ else if (v1->type == NC_CHAR) {
+ if (memcmp(v1->xvalue, v2->xvalue, (size_t)v1->nelems)) {
+ msg = "%s attribute \"%s\" CHAR (root=%s, local=%s)\n";
+ ATTR_WARN(msg, name, (char*)v1->xvalue, (char*)v2->xvalue);
+ DEBUG_ASSIGN_ERROR(err, NC_EMULTIDEFINE_ATTR_VAL)
+ }
+ }
+ else if (v1->type == NC_BYTE) {
+ schar *sba = (schar*) v1->xvalue;
+ schar *sbb = (schar*) v2->xvalue;
+ for (j=0; j<v1->nelems; j++) {
+ if (sba[j] != sbb[j]) {
+ msg = "%s attribute \"%s\"[%d] BYTE (root=%hhdb, local=%hhdb)\n";
+ ATTR_WARN_J(msg, name, j, sba[j], sbb[j])
+ DEBUG_ASSIGN_ERROR(err, NC_EMULTIDEFINE_ATTR_VAL)
+ break;
+ }
+ }
+ }
+ else if (v1->type == NC_UBYTE) {
+ uchar *uba = (uchar*) v1->xvalue;
+ uchar *ubb = (uchar*) v2->xvalue;
+ for (j=0; j<v1->nelems; j++) {
+ if (uba[j] != ubb[j]) {
+ msg = "%s attribute \"%s\"[%d] UBYTE (root=%hhuub, local=%hhuub)\n";
+ ATTR_WARN_J(msg, name, j, uba[j], ubb[j])
+ DEBUG_ASSIGN_ERROR(err, NC_EMULTIDEFINE_ATTR_VAL)
+ break;
+ }
+ }
+ }
+ else if (v1->type == NC_SHORT) {
+ short *ssa = (short*) v1->xvalue;
+ short *ssb = (short*) v2->xvalue;
+ for (j=0; j<v1->nelems; j++) {
+ if (ssa[j] != ssb[j]) {
+ msg = "%s attribute \"%s\"[%d] SHORT (root=%hds, local=%hds)\n";
+ ATTR_WARN_J(msg, name, j, ssa[j], ssb[j])
+ DEBUG_ASSIGN_ERROR(err, NC_EMULTIDEFINE_ATTR_VAL)
+ break;
+ }
+ }
+ }
+ else if (v1->type == NC_USHORT) {
+ ushort *usa = (ushort*) v1->xvalue;
+ ushort *usb = (ushort*) v2->xvalue;
+ for (j=0; j<v1->nelems; j++) {
+ if (usa[j] != usb[j]) {
+ msg = "%s attribute \"%s\"[%d] USHORT (root=%huus, local=%huus)\n";
+ ATTR_WARN_J(msg, name, j, usa[j], usb[j])
+ DEBUG_ASSIGN_ERROR(err, NC_EMULTIDEFINE_ATTR_VAL)
+ break;
+ }
+ }
+ }
+ else if (v1->type == NC_INT) {
+ int *sia = (int*) v1->xvalue;
+ int *sib = (int*) v2->xvalue;
+ for (j=0; j<v1->nelems; j++) {
+ if (sia[j] != sib[j]) {
+ msg = "%s attribute \"%s\"[%d] INT (root=%d, local=%d)\n";
+ ATTR_WARN_J(msg, name, j, sia[j], sib[j])
+ DEBUG_ASSIGN_ERROR(err, NC_EMULTIDEFINE_ATTR_VAL)
+ break;
+ }
+ }
+ }
+ else if (v1->type == NC_UINT) {
+ uint *uia = (uint*) v1->xvalue;
+ uint *uib = (uint*) v2->xvalue;
+ for (j=0; j<v1->nelems; j++) {
+ if (uia[j] != uib[j]) {
+ msg = "%s attribute \"%s\"[%d] UINT (root=%uu, local=%uu)\n";
+ ATTR_WARN_J(msg, name, j, uia[j], uib[j])
+ DEBUG_ASSIGN_ERROR(err, NC_EMULTIDEFINE_ATTR_VAL)
+ break;
+ }
+ }
+ }
+ else if (v1->type == NC_FLOAT) {
+ float *fa = (float*) v1->xvalue;
+ float *fb = (float*) v2->xvalue;
+ for (j=0; j<v1->nelems; j++) {
+ /* floating-point inequality here but we genuinely do
+ * expect all processors to set bit-for-bit identical
+ * headers */
+ if (fa[j] != fb[j]) {
+ msg = "%s attribute \"%s\"[%d] FLOAT (root=%f, local=%f)\n";
+ ATTR_WARN_J(msg, name, j, fa[j], fb[j])
+ DEBUG_ASSIGN_ERROR(err, NC_EMULTIDEFINE_ATTR_VAL)
+ break;
+ }
+ }
+ }
+ else if (v1->type == NC_DOUBLE) {
+ double *da = (double*) v1->xvalue;
+ double *db = (double*) v2->xvalue;
+ for (j=0; j<v1->nelems; j++) {
+ /* floating-point inequality here but we genuinely do
+ * expect all processors to set bit-for-bit identical
+ * headers */
+ if (da[j] != db[j]) {
+ msg = "%s attribute \"%s\"[%d] DOUBLE (root=%f, local=%f)\n";
+ ATTR_WARN_J(msg, name, j, da[j], db[j])
+ DEBUG_ASSIGN_ERROR(err, NC_EMULTIDEFINE_ATTR_VAL)
+ break;
+ }
+ }
+ }
+ else if (v1->type == NC_INT64) {
+ long long *slla = (long long*) v1->xvalue;
+ long long *sllb = (long long*) v2->xvalue;
+ for (j=0; j<v1->nelems; j++) {
+ if (slla[j] != sllb[j]) {
+ msg = "%s attribute \"%s\"[%d] INT64 (root=%lldll, local=%lldll)\n";
+ ATTR_WARN_J(msg, name, j, slla[j], sllb[j])
+ DEBUG_ASSIGN_ERROR(err, NC_EMULTIDEFINE_ATTR_VAL)
+ break;
+ }
+ }
+ }
+ else if (v1->type == NC_UINT64) {
+ unsigned long long *ulla = (unsigned long long*) v1->xvalue;
+ unsigned long long *ullb = (unsigned long long*) v2->xvalue;
+ for (j=0; j<v1->nelems; j++) {
+ if (ulla[j] != ullb[j]) {
+ msg = "%s attribute \"%s\"[%d] UINT64 (root=%llull, local=%llull)\n";
+ ATTR_WARN_J(msg, name, j, ulla[j], ullb[j])
+ DEBUG_ASSIGN_ERROR(err, NC_EMULTIDEFINE_ATTR_VAL)
+ break;
+ }
+ }
+ }
+ if (status == NC_NOERR) status = err;
+
+ /* overwrite local's attr with root's */
+ if (ErrIsHeaderDiff(err)) {
+ ncmpii_free_NC_attr(local_attr->value[i]);
+ local_attr->value[i] = dup_NC_attr(root_attr->value[i]);
+ }
+ }
+
+ /* delete extra attributes defined only in local copy */
+ for (; i<local_attr->ndefined; i++)
+ ncmpii_free_NC_attr(local_attr->value[i]);
+
+ local_attr->ndefined = root_attr->ndefined;
+
+ return status;
+}
+
+/*----< ncmpii_comp_vars() >--------------------------------------------------*/
+/* compare the local copy of var_list against root's
+ * If inconsistency is detected, overwrite local's with root's
+ */
+static int
+ncmpii_comp_vars(int safe_mode,
+ NC_vararray *root_var,
+ NC_vararray *local_var)
+{
+ int i, j, err, status=NC_NOERR, no_fill;
+ char *msg;
+
+ /* check if the numbers of variables are the same */
+ if (root_var->ndefined != local_var->ndefined) {
+ if (safe_mode)
+ printf("%s number of variables (root=%d, local=%d)\n",
+ WARN_STR, root_var->ndefined, local_var->ndefined);
+ DEBUG_ASSIGN_ERROR(status, NC_EMULTIDEFINE_VAR_NUM)
+ }
+
+ for (i=0; i<root_var->ndefined; i++) {
+
+ if (i >= local_var->ndefined) { /* if local list is shorter */
+ /* copy root's variable to local */
+ NC_var *new_var = dup_NC_var(root_var->value[i]);
+ err = incr_NC_vararray(local_var, new_var);
+ if (err != NC_NOERR) return err; /* a fatal error */
+ /* local_var->ndefined is increased by 1 in incr_NC_vararray() */
+ continue;
+ }
+
+ NC_var *v1 = root_var->value[i];
+ NC_var *v2 = local_var->value[i];
+ char name[128];
+ /* in PnetCDF, name->cp is always NULL character terminated */
+ strcpy(name, v1->name->cp);
+
+ /* preserve original local variable's no_fill setting */
+ no_fill = v2->no_fill;
+
+#define VAR_WARN(msg, var, root, local) \
+ if (safe_mode) printf(msg, WARN_STR, var, root, local);
+
+#define VAR_WARN_J(msg, var, j, root, local) \
+ if (safe_mode) printf(msg, WARN_STR, var, j, root, local);
+
+ err = NC_NOERR;
+ if (v1->name->nchars != v2->name->nchars ||
+ strncmp(v1->name->cp, v2->name->cp, (size_t)v1->name->nchars) != 0) {
+ msg = "%s variable %s (root=%s, local=%s)\n";
+ VAR_WARN(msg, "name", name, v2->name->cp)
+ DEBUG_ASSIGN_ERROR(err, NC_EMULTIDEFINE_VAR_NAME)
+ }
+ else if (v1->ndims != v2->ndims) {
+ msg = "%s variable %s's ndims (root=%d, local=%d)\n";
+ VAR_WARN(msg, name, v1->ndims, v2->ndims)
+ DEBUG_ASSIGN_ERROR(err, NC_EMULTIDEFINE_VAR_NDIMS)
+ }
+ else if (v1->type != v2->type) {
+ msg = "%s variable %s's type (root=%d, local=%d)\n";
+ VAR_WARN(msg, name, v1->type, v2->type)
+ DEBUG_ASSIGN_ERROR(err, NC_EMULTIDEFINE_VAR_TYPE)
+ }
+ else if (v1->len != v2->len) {
+ msg = "%s variable %s's len (root=%lld, local=%lld)\n";
+ VAR_WARN(msg, name, v1->len, v2->len)
+ DEBUG_ASSIGN_ERROR(err, NC_EMULTIDEFINE_VAR_LEN)
+ }
+ else if (v1->begin != v2->begin) {
+ msg = "%s variable %s's begin (root=%lld, local=%lld)\n";
+ VAR_WARN(msg, name, v1->begin, v2->begin)
+ DEBUG_ASSIGN_ERROR(err, NC_EMULTIDEFINE_VAR_BEGIN)
+ }
+ else {
+ for (j=0; j<v1->ndims; j++) {
+ if (v1->dimids[j] != v2->dimids[j]) {
+ msg = "%s variable %s's %dth dim ID (root=%d, local=%ld)\n";
+ VAR_WARN_J(msg, name, j, v1->dimids[j], v2->dimids[j])
+ DEBUG_ASSIGN_ERROR(err, NC_EMULTIDEFINE_VAR_DIMIDS)
+ break;
+ }
+ }
+ }
+ /* compare variable's attributes if by far no inconsistency is found */
+ if (err == NC_NOERR) {
+ err = ncmpii_comp_attrs(safe_mode, &(v1->attrs), &(v2->attrs));
+ if (err != NC_NOERR && !ErrIsHeaderDiff(err))
+ return err; /* a fatal error */
+ }
+
+ if (status == NC_NOERR) status = err;
+
+ /* if there is any inconsistency, overwrite local's var with root's */
+ if (ErrIsHeaderDiff(err)) {
+ ncmpii_free_NC_var(local_var->value[i]);
+ local_var->value[i] = dup_NC_var(root_var->value[i]);
+ /* restore original local variable's no_fill setting */
+ local_var->value[i]->no_fill = no_fill;
+ /* note once a new var is created, one must call
+ * ncmpii_NC_computeshapes() to recalculate the shape */
+ }
+ }
+
+ /* delete extra variables defined only in local copy */
+ for (; i<local_var->ndefined; i++)
+ ncmpii_free_NC_var(local_var->value[i]);
+
+ local_var->ndefined = root_var->ndefined;
+
+ return status;
+}
+
+/*----< ncmpii_hdr_check_NC() >-----------------------------------------------*/
+/* This function is only called by NC_check_header()
+ * It checks the header of local copy against root's and overwrites local's
+ * header object, ncp, with root's header if any inconsistency is detected.
+ * This function is called independently and should not contain any MPI
+ * communication calls.
+ */
+int
+ncmpii_hdr_check_NC(bufferinfo *getbuf, /* header from root */
+ NC *ncp)
+{
+ int rank, err, status=NC_NOERR;
+ schar magic[sizeof(ncmagic1)];
+ MPI_Offset nrecs=0, chunksize=NC_DEFAULT_CHUNKSIZE;
+ MPI_Aint pos_addr, base_addr;
+ NC *root_ncp;
+
+ assert(ncp != NULL);
+ assert(getbuf != NULL);
+
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+
+ /* check header's magic */
+ memset(magic, 0, sizeof(magic));
+ err = ncmpix_getn_schar_schar((const void **)(&getbuf->pos),
+ sizeof(magic), magic);
+ if (err != NC_NOERR) {
+ /* Fatal error, as root's header is significant */
+ if (ncp->safe_mode) fprintf(stderr,"Error: CDF magic number from root's header\n");
+ return err;
+ }
+ getbuf->index += (MPI_Offset)sizeof(magic);
+
+ /* check if the first 3 letters are "CDF" */
+ if (memcmp(magic, ncmagic1, sizeof(ncmagic1)-1) != 0) {
+ /* Fatal error, as root's header is significant */
+ if (ncp->safe_mode)
+ fprintf(stderr,"Error: root's header indicates not a CDF file\n");
+ DEBUG_RETURN_ERROR(NC_ENOTNC) /* should not continue */
+ }
+
+ /* allocate a header object and fill it with root's header */
+ root_ncp = ncmpii_new_NC(&chunksize);
+
+ /* consistency of magic numbers should have already been checked during
+ * ncmpi_create()
+ */
+ if (magic[sizeof(ncmagic1)-1] == 0x5) {
+ fSet(root_ncp->flags, NC_64BIT_DATA);
+ }
+ else if (magic[sizeof(ncmagic1)-1] == 0x2) {
+ fSet(root_ncp->flags, NC_64BIT_OFFSET);
+ }
+ else if (magic[sizeof(ncmagic1)-1] != 0x1) {
+ /* Fatal error, as root's header is significant */
+ if (ncp->safe_mode)
+ fprintf(stderr,"Error: root's header indicates not CDF 1/2/5 format\n");
+ DEBUG_RETURN_ERROR(NC_ENOTNC) /* should not continue */
+ }
+
+ /* check version number in last byte of magic */
+ int local_ver, root_ver;
+ if (ncp->flags & NC_64BIT_DATA) local_ver = 0x5;
+ else if (ncp->flags & NC_64BIT_OFFSET) local_ver = 0x2;
+ else local_ver = 0x1;
+
+ root_ver = magic[sizeof(ncmagic1)-1];
+ if (local_ver != root_ver) {
+ if (ncp->safe_mode)
+ printf("%s CDF file format (local=CDF-%d, root=CDF-%d)\n",
+ WARN_STR, local_ver, root_ver);
+
+ /* overwrite the local header object with root's */
+ if (local_ver == 0x5) fClr(ncp->flags, NC_64BIT_DATA);
+ else if (local_ver == 0x2) fClr(ncp->flags, NC_64BIT_OFFSET);
+
+ if (root_ver == 0x5) fSet(ncp->flags, NC_64BIT_DATA);
+ else if (root_ver == 0x2) fSet(ncp->flags, NC_64BIT_OFFSET);
+
+ /* this inconsistency is not fatal */
+ DEBUG_ASSIGN_ERROR(status, NC_EMULTIDEFINE_OMODE)
+ }
+ getbuf->version = root_ver; /* getbuf's version has not been set before */
+
+#if SIZEOF_MPI_OFFSET < 8
+ if (root_ver > 1) {
+ /* for NC_64BIT_DATA or NC_64BIT_OFFSET, MPI_Offset must be 8 bytes */
+ if (ncp->safe_mode) fprintf(stderr,"Error: cannot support CDF-2 and CDF-5 on this machine\n");
+ DEBUG_RETURN_ERROR(NC_ESMALL) /* should not continue */
+ }
+#endif
+
+ /* since getbuf contains the entire root's header, we do not need to check
+ * for any next element in the buffer. Similarly, for all possible calls
+ * to hdr_check_buffer() from this subroutine, hdr_fetch() will never be
+ * called.
+ * (move on to the next element in header: number of records)
+ err = hdr_check_buffer(getbuf, (getbuf->version == 5) ? 8 : 4);
+ if (err != NC_NOERR) {
+ if (ncp->safe_mode)
+ fprintf(stderr,"Error: root's header is too short\n");
+ return err;
+ }
+ */
+
+ if (getbuf->version == 5) {
+ uint64 tmp=0;
+ err = ncmpix_get_uint64((const void **)(&getbuf->pos), &tmp);
+ nrecs = (MPI_Offset)tmp;
+ }
+ else {
+ uint tmp=0;
+ err = ncmpix_get_uint32((const void **)(&getbuf->pos), &tmp);
+ nrecs = (MPI_Offset)tmp;
+ }
+ if (err != NC_NOERR) {
+ if (ncp->safe_mode)
+ fprintf(stderr,"Error: failed to read numrecs from root's header\n");
+ return err; /* should not continue */
+ }
+
+ /* move the buffer point forward */
+ if (getbuf->version == 5)
+ getbuf->index += X_SIZEOF_INT64;
+ else
+ getbuf->index += X_SIZEOF_SIZE_T;
+
+ root_ncp->numrecs = nrecs;
+ if (root_ncp->numrecs != ncp->numrecs) {
+ if (ncp->safe_mode)
+ printf("%s number of records (local=%lld, root=%lld)\n",
+ WARN_STR, ncp->numrecs, root_ncp->numrecs);
+ /* overwrite the local header's numrecs */
+ ncp->numrecs = root_ncp->numrecs;
+ if (status == NC_NOERR) DEBUG_ASSIGN_ERROR(err, NC_EMULTIDEFINE_NUMRECS)
+ }
+
+#ifdef HAVE_MPI_GET_ADDRESS
+ MPI_Get_address(getbuf->pos, &pos_addr);
+ MPI_Get_address(getbuf->base, &base_addr);
+#else
+ MPI_Address(getbuf->pos, &pos_addr);
+ MPI_Address(getbuf->base, &base_addr);
+#endif
+ assert(pos_addr < base_addr + getbuf->size);
+
+ /* get the next header element dim_list from getbuf to root_ncp */
+ err = hdr_get_NC_dimarray(getbuf, &root_ncp->dims);
+ if (err != NC_NOERR) return err; /* fatal error */
+
+ /* compare local's and root's dim_list */
+ err = ncmpii_comp_dims(ncp->safe_mode, &root_ncp->dims, &ncp->dims);
+ if (err != NC_NOERR && !ErrIsHeaderDiff(err))
+ return err; /* a fatal error */
+ if (status == NC_NOERR) status = err;
+
+ /* get the next header element gatt_list from getbuf to root_ncp */
+ err = hdr_get_NC_attrarray(getbuf, &root_ncp->attrs);
+ if (err != NC_NOERR) return err; /* fatal error */
+
+ /* get the next header element att_list from getbuf to root_ncp */
+ err = ncmpii_comp_attrs(ncp->safe_mode, &root_ncp->attrs, &ncp->attrs);
+ if (err != NC_NOERR && !ErrIsHeaderDiff(err))
+ return err; /* a fatal error */
+ if (status == NC_NOERR) status = err;
+
+ /* get the next header element var_list from getbuf to root_ncp */
+ err = hdr_get_NC_vararray(getbuf, &root_ncp->vars);
+ if (err != NC_NOERR) return err; /* fatal error */
+
+ /* compare local's and root's var_list */
+ err = ncmpii_comp_vars(ncp->safe_mode, &root_ncp->vars, &ncp->vars);
+ if (err != NC_NOERR && !ErrIsHeaderDiff(err))
+ return err; /* a fatal error */
+ if (status == NC_NOERR) status = err;
+
+ if (err != NC_NOERR) { /* header has been sync-ed with root */
+ /* recompute shape is required for every new variable created */
+ err = ncmpii_NC_computeshapes(ncp);
+ if (err != NC_NOERR) return err; /* a fatal error */
+ }
+ /* now, the local header object has been sync-ed with root */
+
+ if (ncp->safe_mode && ErrIsHeaderDiff(status)) {
+ /* recompute header size */
+ MPI_Offset root_xsz, local_xsz;
+ root_xsz = ncmpii_hdr_len_NC(root_ncp);
+ local_xsz = ncmpii_hdr_len_NC(ncp);
+ /* root's header size is getbuf->size */
+ assert( ncp->xsz == getbuf->size &&
+ root_xsz == local_xsz &&
+ local_xsz == getbuf->size);
+ }
+ ncmpii_free_NC(root_ncp);
+ return status;
+}
+
+/*----< ncmpii_write_header() >-----------------------------------------------*/
+/* This function is called only in data mode (collective or independent) and by
+ * 1. ncmpi_rename_att()
+ * 2. ncmpi_copy_att()
+ * 3. ncmpii_put_att()
+ * 4. ncmpi_rename_dim()
+ * 5. ncmpi_rename_var()
+ *
+ * This function is collective (even in independent data mode) */
+int ncmpii_write_header(NC *ncp)
+{
+ int rank, status=NC_NOERR, mpireturn, err;
+ MPI_File fh;
+
+ /* Write the entire header to the file. This function may be called from
+ * a rename API. In that case, we cannot just change the variable name in
+ * the file header, because if the file space occupied by the name shrinks,
+ * all metadata following the new name must be moved ahead.
+ */
+
+ fh = ncp->nciop->collective_fh;
+ if (NC_indep(ncp))
+ fh = ncp->nciop->independent_fh;
+
+ MPI_Comm_rank(ncp->nciop->comm, &rank);
+ if (rank == 0) {
+ MPI_Status mpistatus;
+ void *buf = NCI_Malloc((size_t)ncp->xsz); /* header's write buffer */
+
+ /* copy header object to write buffer */
+ status = ncmpii_hdr_put_NC(ncp, buf);
+
+ if (ncp->xsz != (int)ncp->xsz) DEBUG_RETURN_ERROR(NC_EINTOVERFLOW)
+ TRACE_IO(MPI_File_write_at)(fh, 0, buf, (int)ncp->xsz, MPI_BYTE, &mpistatus);
+ if (mpireturn != MPI_SUCCESS) {
+ err = ncmpii_handle_error(mpireturn, "MPI_File_write_at");
+ if (status == NC_NOERR) {
+ status = (err == NC_EFILE) ? NC_EWRITE : err;
+ DEBUG_ASSIGN_ERROR(status, status)
+ }
+ }
+ else {
+ int put_size;
+ MPI_Get_count(&mpistatus, MPI_BYTE, &put_size);
+ ncp->nciop->put_size += put_size;
+ }
+ NCI_Free(buf);
+ }
+
+ if (ncp->safe_mode == 1) {
+ /* broadcast root's status, because only root writes to the file */
+ int root_status = status;
+ TRACE_COMM(MPI_Bcast)(&root_status, 1, MPI_INT, 0, ncp->nciop->comm);
+ /* root's write has failed, which is serious */
+ if (root_status == NC_EWRITE) DEBUG_ASSIGN_ERROR(status, NC_EWRITE)
+ }
+
+ /* update file header size */
+ ncp->xsz = ncmpii_hdr_len_NC(ncp);
+
+ if (NC_doFsync(ncp)) { /* NC_SHARE is set */
+ TRACE_IO(MPI_File_sync)(fh);
+ TRACE_COMM(MPI_Barrier)(ncp->nciop->comm);
+ }
+
+ return status;
+}
+
diff --git a/src/lib/i_getput.m4 b/src/lib/i_getput.m4
new file mode 100644
index 0000000..6bf1a26
--- /dev/null
+++ b/src/lib/i_getput.m4
@@ -0,0 +1,939 @@
+dnl Process this m4 file to produce 'C' language file.
+dnl
+dnl If you see this line, you can ignore the next one.
+/* Do not edit this file. It is produced from the corresponding .m4 source */
+dnl
+/*
+ * Copyright (C) 2003, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ */
+/* $Id: i_getput.m4 2290 2016-01-02 18:37:46Z wkliao $ */
+
+#if HAVE_CONFIG_H
+# include "ncconfig.h"
+#endif
+
+#include <stdio.h>
+#include <unistd.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#include <assert.h>
+
+#include <string.h> /* memcpy() */
+#include <mpi.h>
+
+#include "nc.h"
+#include "ncx.h"
+#include "ncmpidtype.h"
+#include "macro.h"
+
+
+define(`CollIndep', `ifelse(`$1',`_all', `COLL_IO', `INDEP_IO')')dnl
+define(`ReadWrite', `ifelse(`$1', `get', `READ_REQ', `WRITE_REQ')')dnl
+define(`BufConst', `ifelse(`$1', `put', `const')')dnl
+
+dnl
+dnl VAR_FLEXIBLE
+dnl
+define(`VAR_FLEXIBLE',dnl
+`dnl
+/*----< ncmpi_i$1_var() >----------------------------------------------------*/
+int
+ncmpi_i$1_var(int ncid,
+ int varid,
+ BufConst($1) void *buf,
+ MPI_Offset bufcount,
+ MPI_Datatype buftype,
+ int *reqid)
+{
+ int status;
+ NC *ncp;
+ NC_var *varp=NULL;
+ MPI_Offset *start, *count;
+
+ if (reqid != NULL) *reqid = NC_REQ_NULL;
+ status = ncmpii_sanity_check(ncid, varid, NULL, NULL, bufcount, API_VAR,
+ 0, 1, ReadWrite($1), NONBLOCKING_IO, &ncp, &varp);
+ if (status != NC_NOERR) return status;
+
+ GET_FULL_DIMENSIONS(start, count)
+
+ /* i$1_var is a special case of i$1_varm */
+ status = ncmpii_igetput_varm(ncp, varp, start, count, NULL, NULL,
+ (void*)buf, bufcount, buftype, reqid,
+ ReadWrite($1), 0, 0);
+ if (varp->ndims > 0) NCI_Free(start);
+ return status;
+}
+')dnl
+
+VAR_FLEXIBLE(put)
+VAR_FLEXIBLE(get)
+
+dnl
+dnl VAR
+dnl
+define(`VAR',dnl
+`dnl
+/*----< ncmpi_i$1_var_$2() >-------------------------------------------------*/
+int
+ncmpi_i$1_var_$2(int ncid,
+ int varid,
+ BufConst($1) $3 *buf,
+ int *reqid)
+{
+ int status;
+ NC *ncp;
+ NC_var *varp=NULL;
+ MPI_Offset *start, *count;
+
+ if (reqid != NULL) *reqid = NC_REQ_NULL;
+ status = ncmpii_sanity_check(ncid, varid, NULL, NULL, 0, API_VAR,
+ 0, 0, ReadWrite($1), NONBLOCKING_IO, &ncp, &varp);
+ if (status != NC_NOERR) return status;
+
+ GET_FULL_DIMENSIONS(start, count)
+
+ /* i$1_var is a special case of i$1_varm */
+ status = ncmpii_igetput_varm(ncp, varp, start, count, NULL, NULL,
+ (void*)buf, -1, $4, reqid,
+ ReadWrite($1), 0, 0);
+ if (varp->ndims > 0) NCI_Free(start);
+ return status;
+}
+')dnl
+
+VAR(put, text, char, MPI_CHAR)
+VAR(put, schar, schar, MPI_SIGNED_CHAR)
+VAR(put, uchar, uchar, MPI_UNSIGNED_CHAR)
+VAR(put, short, short, MPI_SHORT)
+VAR(put, ushort, ushort, MPI_UNSIGNED_SHORT)
+VAR(put, int, int, MPI_INT)
+VAR(put, uint, uint, MPI_UNSIGNED)
+VAR(put, long, long, MPI_LONG)
+VAR(put, float, float, MPI_FLOAT)
+VAR(put, double, double, MPI_DOUBLE)
+VAR(put, longlong, long long, MPI_LONG_LONG_INT)
+VAR(put, ulonglong, unsigned long long, MPI_UNSIGNED_LONG_LONG)
+
+VAR(get, text, char, MPI_CHAR)
+VAR(get, schar, schar, MPI_SIGNED_CHAR)
+VAR(get, uchar, uchar, MPI_UNSIGNED_CHAR)
+VAR(get, short, short, MPI_SHORT)
+VAR(get, ushort, ushort, MPI_UNSIGNED_SHORT)
+VAR(get, int, int, MPI_INT)
+VAR(get, uint, uint, MPI_UNSIGNED)
+VAR(get, long, long, MPI_LONG)
+VAR(get, float, float, MPI_FLOAT)
+VAR(get, double, double, MPI_DOUBLE)
+VAR(get, longlong, long long, MPI_LONG_LONG_INT)
+VAR(get, ulonglong, unsigned long long, MPI_UNSIGNED_LONG_LONG)
+
+
+dnl
+dnl VAR1_FLEXIBLE
+dnl
+define(`VAR1_FLEXIBLE',dnl
+`dnl
+/*----< ncmpi_i$1_var1() >---------------------------------------------------*/
+int
+ncmpi_i$1_var1(int ncid,
+ int varid,
+ const MPI_Offset *start,
+ BufConst($1) void *buf,
+ MPI_Offset bufcount,
+ MPI_Datatype buftype,
+ int *reqid)
+{
+ int status;
+ NC *ncp;
+ NC_var *varp=NULL;
+ MPI_Offset *count;
+
+ if (reqid != NULL) *reqid = NC_REQ_NULL;
+ status = ncmpii_sanity_check(ncid, varid, start, NULL, bufcount, API_VAR1,
+ 0, 1, ReadWrite($1), NONBLOCKING_IO, &ncp, &varp);
+ if (status != NC_NOERR) return status;
+
+ GET_ONE_COUNT(count)
+
+ status = ncmpii_igetput_varm(ncp, varp, start, count, NULL, NULL,
+ (void*)buf, bufcount, buftype, reqid,
+ ReadWrite($1), 0, 0);
+ if (varp->ndims > 0) NCI_Free(count);
+ return status;
+}
+')dnl
+
+VAR1_FLEXIBLE(put)
+VAR1_FLEXIBLE(get)
+
+dnl
+dnl VAR1
+dnl
+define(`VAR1',dnl
+`dnl
+/*----< ncmpi_i$1_var1_$2() >------------------------------------------------*/
+int
+ncmpi_i$1_var1_$2(int ncid,
+ int varid,
+ const MPI_Offset start[],
+ BufConst($1) $3 *buf,
+ int *reqid)
+{
+ int status;
+ NC *ncp;
+ NC_var *varp=NULL;
+ MPI_Offset *count;
+
+ if (reqid != NULL) *reqid = NC_REQ_NULL;
+ status = ncmpii_sanity_check(ncid, varid, start, NULL, 0, API_VAR1,
+ 0, 0, ReadWrite($1), NONBLOCKING_IO, &ncp, &varp);
+ if (status != NC_NOERR) return status;
+
+ GET_ONE_COUNT(count)
+
+ status = ncmpii_igetput_varm(ncp, varp, start, count, NULL, NULL,
+ (void*)buf, -1, $4, reqid, ReadWrite($1), 0,
+ 0);
+ if (varp->ndims > 0) NCI_Free(count);
+ return status;
+}
+')dnl
+
+VAR1(put, text, char, MPI_CHAR)
+VAR1(put, schar, schar, MPI_SIGNED_CHAR)
+VAR1(put, uchar, uchar, MPI_UNSIGNED_CHAR)
+VAR1(put, short, short, MPI_SHORT)
+VAR1(put, ushort, ushort, MPI_UNSIGNED_SHORT)
+VAR1(put, int, int, MPI_INT)
+VAR1(put, uint, uint, MPI_UNSIGNED)
+VAR1(put, long, long, MPI_LONG)
+VAR1(put, float, float, MPI_FLOAT)
+VAR1(put, double, double, MPI_DOUBLE)
+VAR1(put, longlong, long long, MPI_LONG_LONG_INT)
+VAR1(put, ulonglong, unsigned long long, MPI_UNSIGNED_LONG_LONG)
+
+VAR1(get, text, char, MPI_CHAR)
+VAR1(get, schar, schar, MPI_SIGNED_CHAR)
+VAR1(get, uchar, uchar, MPI_UNSIGNED_CHAR)
+VAR1(get, short, short, MPI_SHORT)
+VAR1(get, ushort, ushort, MPI_UNSIGNED_SHORT)
+VAR1(get, int, int, MPI_INT)
+VAR1(get, uint, uint, MPI_UNSIGNED)
+VAR1(get, long, long, MPI_LONG)
+VAR1(get, float, float, MPI_FLOAT)
+VAR1(get, double, double, MPI_DOUBLE)
+VAR1(get, longlong, long long, MPI_LONG_LONG_INT)
+VAR1(get, ulonglong, unsigned long long, MPI_UNSIGNED_LONG_LONG)
+
+
+dnl
+dnl VARA_FLEXIBLE
+dnl
+define(`VARA_FLEXIBLE',dnl
+`dnl
+/*----< ncmpi_i$1_vara() >---------------------------------------------------*/
+int
+ncmpi_i$1_vara(int ncid,
+ int varid,
+ const MPI_Offset *start,
+ const MPI_Offset *count,
+ BufConst($1) void *buf,
+ MPI_Offset bufcount,
+ MPI_Datatype buftype,
+ int *reqid)
+{
+ int status;
+ NC *ncp;
+ NC_var *varp=NULL;
+
+ if (reqid != NULL) *reqid = NC_REQ_NULL;
+ status = ncmpii_sanity_check(ncid, varid, start, count, bufcount, API_VARA,
+ 0, 1, ReadWrite($1), NONBLOCKING_IO, &ncp, &varp);
+ if (status != NC_NOERR) return status;
+
+ return ncmpii_igetput_varm(ncp, varp, start, count, NULL, NULL,
+ (void*)buf, bufcount, buftype, reqid,
+ ReadWrite($1), 0, 0);
+}
+')dnl
+
+VARA_FLEXIBLE(put)
+VARA_FLEXIBLE(get)
+
+dnl
+dnl VARA
+dnl
+define(`VARA',dnl
+`dnl
+/*----< ncmpi_i$1_vara_$1() >------------------------------------------------*/
+int
+ncmpi_i$1_vara_$2(int ncid,
+ int varid,
+ const MPI_Offset start[],
+ const MPI_Offset count[],
+ BufConst($1) $3 *buf,
+ int *reqid)
+{
+ int status;
+ NC *ncp;
+ NC_var *varp=NULL;
+
+ if (reqid != NULL) *reqid = NC_REQ_NULL;
+ status = ncmpii_sanity_check(ncid, varid, start, count, 0, API_VARA,
+ 0, 0, ReadWrite($1), NONBLOCKING_IO, &ncp, &varp);
+ if (status != NC_NOERR) return status;
+
+ return ncmpii_igetput_varm(ncp, varp, start, count, NULL, NULL,
+ (void*)buf, -1, $4, reqid, ReadWrite($1), 0, 0);
+}
+')dnl
+
+VARA(put, text, char, MPI_CHAR)
+VARA(put, schar, schar, MPI_SIGNED_CHAR)
+VARA(put, uchar, uchar, MPI_UNSIGNED_CHAR)
+VARA(put, short, short, MPI_SHORT)
+VARA(put, ushort, ushort, MPI_UNSIGNED_SHORT)
+VARA(put, int, int, MPI_INT)
+VARA(put, uint, uint, MPI_UNSIGNED)
+VARA(put, long, long, MPI_LONG)
+VARA(put, float, float, MPI_FLOAT)
+VARA(put, double, double, MPI_DOUBLE)
+VARA(put, longlong, long long, MPI_LONG_LONG_INT)
+VARA(put, ulonglong, unsigned long long, MPI_UNSIGNED_LONG_LONG)
+
+VARA(get, text, char, MPI_CHAR)
+VARA(get, schar, schar, MPI_SIGNED_CHAR)
+VARA(get, uchar, uchar, MPI_UNSIGNED_CHAR)
+VARA(get, short, short, MPI_SHORT)
+VARA(get, ushort, ushort, MPI_UNSIGNED_SHORT)
+VARA(get, int, int, MPI_INT)
+VARA(get, uint, uint, MPI_UNSIGNED)
+VARA(get, long, long, MPI_LONG)
+VARA(get, float, float, MPI_FLOAT)
+VARA(get, double, double, MPI_DOUBLE)
+VARA(get, longlong, long long, MPI_LONG_LONG_INT)
+VARA(get, ulonglong, unsigned long long, MPI_UNSIGNED_LONG_LONG)
+
+
+dnl
+dnl VARS_FLEXIBLE
+dnl
+define(`VARS_FLEXIBLE',dnl
+`dnl
+/*----< ncmpi_i$1_vars() >---------------------------------------------------*/
+int
+ncmpi_i$1_vars(int ncid,
+ int varid,
+ const MPI_Offset start[],
+ const MPI_Offset count[],
+ const MPI_Offset stride[],
+ BufConst($1) void *buf,
+ MPI_Offset bufcount,
+ MPI_Datatype buftype,
+ int *reqid)
+{
+ int status;
+ NC *ncp;
+ NC_var *varp=NULL;
+
+ if (reqid != NULL) *reqid = NC_REQ_NULL;
+ status = ncmpii_sanity_check(ncid, varid, start, count, bufcount, API_VARS,
+ 0, 1, ReadWrite($1), NONBLOCKING_IO, &ncp, &varp);
+ if (status != NC_NOERR) return status;
+
+ return ncmpii_igetput_varm(ncp, varp, start, count, stride, NULL,
+ (void*)buf, bufcount, buftype, reqid,
+ ReadWrite($1), 0, 0);
+}
+')dnl
+
+VARS_FLEXIBLE(put)
+VARS_FLEXIBLE(get)
+
+dnl
+dnl VARS
+dnl
+define(`VARS',dnl
+`dnl
+/*----< ncmpi_i$1_vars_$2() >------------------------------------------------*/
+int
+ncmpi_i$1_vars_$2(int ncid,
+ int varid,
+ const MPI_Offset start[],
+ const MPI_Offset count[],
+ const MPI_Offset stride[],
+ BufConst($1) $3 *buf,
+ int *reqid)
+{
+ int status;
+ NC *ncp;
+ NC_var *varp=NULL;
+
+ if (reqid != NULL) *reqid = NC_REQ_NULL;
+ status = ncmpii_sanity_check(ncid, varid, start, count, 0, API_VARS,
+ 0, 0, ReadWrite($1), NONBLOCKING_IO, &ncp, &varp);
+ if (status != NC_NOERR) return status;
+
+ return ncmpii_igetput_varm(ncp, varp, start, count, stride, NULL,
+ (void*)buf, -1, $4, reqid, ReadWrite($1), 0, 0);
+}
+')dnl
+
+VARS(put, text, char, MPI_CHAR)
+VARS(put, schar, schar, MPI_SIGNED_CHAR)
+VARS(put, uchar, uchar, MPI_UNSIGNED_CHAR)
+VARS(put, short, short, MPI_SHORT)
+VARS(put, ushort, ushort, MPI_UNSIGNED_SHORT)
+VARS(put, int, int, MPI_INT)
+VARS(put, uint, uint, MPI_UNSIGNED)
+VARS(put, long, long, MPI_LONG)
+VARS(put, float, float, MPI_FLOAT)
+VARS(put, double, double, MPI_DOUBLE)
+VARS(put, longlong, long long, MPI_LONG_LONG_INT)
+VARS(put, ulonglong, unsigned long long, MPI_UNSIGNED_LONG_LONG)
+
+VARS(get, text, char, MPI_CHAR)
+VARS(get, schar, schar, MPI_SIGNED_CHAR)
+VARS(get, uchar, uchar, MPI_UNSIGNED_CHAR)
+VARS(get, short, short, MPI_SHORT)
+VARS(get, ushort, ushort, MPI_UNSIGNED_SHORT)
+VARS(get, int, int, MPI_INT)
+VARS(get, uint, uint, MPI_UNSIGNED)
+VARS(get, long, long, MPI_LONG)
+VARS(get, float, float, MPI_FLOAT)
+VARS(get, double, double, MPI_DOUBLE)
+VARS(get, longlong, long long, MPI_LONG_LONG_INT)
+VARS(get, ulonglong, unsigned long long, MPI_UNSIGNED_LONG_LONG)
+
+
+/* buffer layers:
+
+ User Level buf (user defined buffer of MPI_Datatype)
+ MPI Datatype Level cbuf (contiguous buffer of ptype)
+ NetCDF XDR Level xbuf (XDR I/O buffer)
+*/
+
+static int
+pack_request(NC *ncp, NC_var *varp, NC_req *req,
+ const MPI_Offset start[], const MPI_Offset count[],
+ const MPI_Offset stride[]);
+
+dnl
+dnl VARM_FLEXIBLE
+dnl
+define(`VARM_FLEXIBLE',dnl
+`dnl
+/*----< ncmpi_i$1_varm() >---------------------------------------------------*/
+int
+ncmpi_i$1_varm(int ncid,
+ int varid,
+ const MPI_Offset start[],
+ const MPI_Offset count[],
+ const MPI_Offset stride[],
+ const MPI_Offset imap[],
+ BufConst($1) void *buf,
+ MPI_Offset bufcount,
+ MPI_Datatype buftype,
+ int *reqid)
+{
+ int status;
+ NC *ncp;
+ NC_var *varp=NULL;
+
+ if (reqid != NULL) *reqid = NC_REQ_NULL;
+ status = ncmpii_sanity_check(ncid, varid, start, count, bufcount, API_VARM,
+ 0, 1, ReadWrite($1), NONBLOCKING_IO, &ncp, &varp);
+ if (status != NC_NOERR) return status;
+
+ return ncmpii_igetput_varm(ncp, varp, start, count, stride, imap,
+ (void*)buf, bufcount, buftype, reqid,
+ ReadWrite($1), 0, 0);
+}
+')dnl
+
+VARM_FLEXIBLE(put)
+VARM_FLEXIBLE(get)
+
+dnl
+dnl VARM
+dnl
+define(`VARM',dnl
+`dnl
+/*----< ncmpi_i$1_varm_$2() >------------------------------------------------*/
+int
+ncmpi_i$1_varm_$2(int ncid,
+ int varid,
+ const MPI_Offset start[],
+ const MPI_Offset count[],
+ const MPI_Offset stride[],
+ const MPI_Offset imap[],
+ BufConst($1) $3 *buf,
+ int *reqid)
+{
+ int status;
+ NC *ncp;
+ NC_var *varp=NULL;
+
+ if (reqid != NULL) *reqid = NC_REQ_NULL;
+ status = ncmpii_sanity_check(ncid, varid, start, count, 0, API_VARM,
+ 0, 0, ReadWrite($1), NONBLOCKING_IO, &ncp, &varp);
+ if (status != NC_NOERR) return status;
+
+ return ncmpii_igetput_varm(ncp, varp, start, count, stride, imap,
+ (void*)buf, -1, $4, reqid, ReadWrite($1), 0, 0);
+}
+')dnl
+
+VARM(put, text, char, MPI_CHAR)
+VARM(put, schar, schar, MPI_SIGNED_CHAR)
+VARM(put, uchar, uchar, MPI_UNSIGNED_CHAR)
+VARM(put, short, short, MPI_SHORT)
+VARM(put, ushort, ushort, MPI_UNSIGNED_SHORT)
+VARM(put, int, int, MPI_INT)
+VARM(put, uint, uint, MPI_UNSIGNED)
+VARM(put, long, long, MPI_LONG)
+VARM(put, float, float, MPI_FLOAT)
+VARM(put, double, double, MPI_DOUBLE)
+VARM(put, longlong, long long, MPI_LONG_LONG_INT)
+VARM(put, ulonglong, unsigned long long, MPI_UNSIGNED_LONG_LONG)
+
+VARM(get, text, char, MPI_CHAR)
+VARM(get, schar, schar, MPI_SIGNED_CHAR)
+VARM(get, uchar, uchar, MPI_UNSIGNED_CHAR)
+VARM(get, short, short, MPI_SHORT)
+VARM(get, ushort, ushort, MPI_UNSIGNED_SHORT)
+VARM(get, int, int, MPI_INT)
+VARM(get, uint, uint, MPI_UNSIGNED)
+VARM(get, long, long, MPI_LONG)
+VARM(get, float, float, MPI_FLOAT)
+VARM(get, double, double, MPI_DOUBLE)
+VARM(get, longlong, long long, MPI_LONG_LONG_INT)
+VARM(get, ulonglong, unsigned long long, MPI_UNSIGNED_LONG_LONG)
+
+/*----< ncmpii_abuf_malloc() >------------------------------------------------*/
+/* allocate memory space from the attached buffer pool */
+static int
+ncmpii_abuf_malloc(NC *ncp, MPI_Offset nbytes, void **buf, int *abuf_index)
+{
+ /* extend the table size if more entries are needed */
+ if (ncp->abuf->tail + 1 == ncp->abuf->table_size) {
+ ncp->abuf->table_size += NC_ABUF_DEFAULT_TABLE_SIZE;
+ ncp->abuf->occupy_table = (NC_buf_status*)
+ NCI_Realloc(ncp->abuf->occupy_table,
+ (size_t)ncp->abuf->table_size * sizeof(NC_buf_status));
+ }
+ /* mark the new entry is used and store the requested buffer size */
+ ncp->abuf->occupy_table[ncp->abuf->tail].is_used = 1;
+ ncp->abuf->occupy_table[ncp->abuf->tail].req_size = nbytes;
+ *abuf_index = ncp->abuf->tail;
+
+ *buf = (char*)ncp->abuf->buf + ncp->abuf->size_used;
+ ncp->abuf->size_used += nbytes;
+ ncp->abuf->tail++;
+
+ return NC_NOERR;
+}
+
+/*----< ncmpii_igetput_varm() >-----------------------------------------------*/
+int
+ncmpii_igetput_varm(NC *ncp,
+ NC_var *varp,
+ const MPI_Offset start[],
+ const MPI_Offset count[],
+ const MPI_Offset stride[],
+ const MPI_Offset imap[],
+ void *buf, /* user buffer */
+ MPI_Offset bufcount,
+ MPI_Datatype buftype,
+ int *reqid, /* out, can be NULL */
+ int rw_flag,
+ int use_abuf, /* if use attached buffer */
+ int isSameGroup) /* if part of a varn group */
+{
+ void *xbuf=NULL, *cbuf=NULL, *lbuf=NULL;
+ int err=NC_NOERR, status=NC_NOERR, warning=NC_NOERR;
+ int i, abuf_index=-1, el_size, buftype_is_contig;
+ int need_convert, need_swap, need_swap_back_buf=0;
+ MPI_Offset bnelems=0, nbytes;
+ MPI_Datatype ptype, imaptype=MPI_DATATYPE_NULL;
+ NC_req *req;
+
+ /* check NC_ECHAR error and calculate the followings:
+ * ptype: element data type (MPI primitive type) in buftype
+ * bufcount: If it is -1, then this is called from a high-level API and in
+ * this case buftype will be an MPI primitive data type. If not, then this
+ * is called from a flexible API. In that case, we recalculate bufcount to
+ * match with count[].
+ * bnelems: number of ptypes in user buffer
+ * nbytes: number of bytes (in external data representation) to read/write
+ * from/to the file
+ * el_size: size of ptype
+ * buftype_is_contig: whether buftype is contiguous
+ */
+ err = ncmpii_calc_datatype_elems(ncp, varp, start, count, stride, rw_flag,
+ buftype, &ptype, &bufcount, &bnelems,
+ &nbytes, &el_size, &buftype_is_contig);
+ if (err == NC_EIOMISMATCH) DEBUG_ASSIGN_ERROR(warning, err)
+ else if (err != NC_NOERR) return err;
+
+ if (bnelems == 0) {
+ /* zero-length request, mark this as a NULL request */
+ if (!isSameGroup && reqid != NULL)
+ /* only if this is not part of a group request */
+ *reqid = NC_REQ_NULL;
+ return ((warning != NC_NOERR) ? warning : NC_NOERR);
+ }
+
+ /* for bput call, check if the remaining buffer space is sufficient
+ * to accommodate this request
+ */
+ if (rw_flag == WRITE_REQ && use_abuf &&
+ ncp->abuf->size_allocated - ncp->abuf->size_used < nbytes)
+ DEBUG_RETURN_ERROR(NC_EINSUFFBUF)
+
+ /* check if type conversion and Endianness byte swap is needed */
+ need_convert = ncmpii_need_convert(varp->type, ptype);
+ need_swap = ncmpii_need_swap(varp->type, ptype);
+
+ /* check whether this is a true varm call, if yes, imaptype will be a
+ * newly created MPI derived data type, otherwise MPI_DATATYPE_NULL
+ */
+ err = ncmpii_create_imaptype(varp, count, imap, bnelems, el_size, ptype,
+ &imaptype);
+ if (err != NC_NOERR) return err;
+
+ if (rw_flag == WRITE_REQ) { /* pack request to xbuf */
+ int position, abuf_allocated=0;
+ MPI_Offset outsize=bnelems*el_size;
+ /* assert(bnelems > 0); */
+ if (outsize != (int)outsize) DEBUG_RETURN_ERROR(NC_EINTOVERFLOW)
+
+ /* attached buffer allocation logic
+ * if (use_abuf)
+ * if contig && no imap && no convert
+ * buf == lbuf == cbuf == xbuf memcpy-> abuf
+ * abuf
+ * if contig && no imap && convert
+ * buf == lbuf == cbuf convert-> xbuf == abuf
+ * abuf
+ * if contig && imap && no convert
+ * buf == lbuf pack-> cbuf == xbuf == abuf
+ * abuf
+ * if contig && imap && convert
+ * buf == lbuf pack-> cbuf convert-> xbuf == abuf
+ * abuf
+ * if noncontig && no imap && no convert
+ * buf pack-> lbuf == cbuf == xbuf == abuf
+ * abuf
+ * if noncontig && no imap && convert
+ * buf pack-> lbuf == cbuf convert-> xbuf == abuf
+ * abuf
+ * if noncontig && imap && no convert
+ * buf pack-> lbuf pack-> cbuf == xbuf == abuf
+ * abuf
+ * if noncontig && imap && convert
+ * buf pack-> lbuf pack-> cbuf convert-> xbuf == abuf
+ * abuf
+ */
+
+ /* Step 1: pack buf into a contiguous buffer, lbuf, if buftype is
+ * not contiguous
+ */
+ if (!buftype_is_contig) { /* buftype is not contiguous */
+ /* allocate lbuf */
+ if (use_abuf && imaptype == MPI_DATATYPE_NULL && !need_convert) {
+ status = ncmpii_abuf_malloc(ncp, nbytes, &lbuf, &abuf_index);
+ if (status != NC_NOERR) return status;
+ abuf_allocated = 1;
+ }
+ else lbuf = NCI_Malloc((size_t)outsize);
+
+ if (bufcount != (int)bufcount) DEBUG_RETURN_ERROR(NC_EINTOVERFLOW)
+
+ /* pack buf into lbuf using buftype */
+ position = 0;
+ MPI_Pack(buf, (int)bufcount, buftype, lbuf, (int)outsize,
+ &position, MPI_COMM_SELF);
+ }
+ else /* for contiguous case, we reuse buf */
+ lbuf = buf;
+
+ /* Step 2: pack lbuf to cbuf if imap is non-contiguous */
+ if (imaptype != MPI_DATATYPE_NULL) { /* true varm */
+ /* allocate cbuf */
+ if (use_abuf && !need_convert) {
+ assert(abuf_allocated == 0);
+ status = ncmpii_abuf_malloc(ncp, nbytes, &cbuf, &abuf_index);
+ if (status != NC_NOERR) {
+ if (lbuf != buf) NCI_Free(lbuf);
+ return status;
+ }
+ abuf_allocated = 1;
+ }
+ else cbuf = NCI_Malloc((size_t)outsize);
+
+ /* pack lbuf to cbuf using imaptype */
+ position = 0;
+ MPI_Pack(lbuf, 1, imaptype, cbuf, (int)outsize, &position,
+ MPI_COMM_SELF);
+ MPI_Type_free(&imaptype);
+ }
+ else /* not a true varm call: reuse lbuf */
+ cbuf = lbuf;
+
+ /* lbuf is no longer needed */
+ if (lbuf != buf && lbuf != cbuf) NCI_Free(lbuf);
+
+ /* Step 3: type-convert and byte-swap cbuf to xbuf, and xbuf will be
+ * used in MPI write function to write to file
+ */
+
+ /* when user buf type != nc var type defined in file */
+ if (need_convert) {
+ if (use_abuf) { /* use attached buffer to allocate xbuf */
+ assert(abuf_allocated == 0);
+ status = ncmpii_abuf_malloc(ncp, nbytes, &xbuf, &abuf_index);
+ if (status != NC_NOERR) {
+ if (cbuf != buf) NCI_Free(cbuf);
+ return status;
+ }
+ abuf_allocated = 1;
+ }
+ else xbuf = NCI_Malloc((size_t)nbytes);
+
+ /* datatype conversion + byte-swap from cbuf to xbuf */
+ DATATYPE_PUT_CONVERT(varp->type, xbuf, cbuf, bnelems, ptype, status)
+ /* NC_ERANGE can be caused by a subset of buf that is out of range
+ * of the external data type, it is not considered a fatal error.
+ * The request must continue to finish.
+ */
+ if (status != NC_NOERR && status != NC_ERANGE) {
+ if (cbuf != buf) NCI_Free(cbuf);
+ if (xbuf != NULL) NCI_Free(xbuf);
+ return status;
+ }
+ }
+ else {
+ if (use_abuf && buftype_is_contig && imaptype == MPI_DATATYPE_NULL){
+ assert(abuf_allocated == 0);
+ status = ncmpii_abuf_malloc(ncp, nbytes, &xbuf, &abuf_index);
+ if (status != NC_NOERR) {
+ if (cbuf != buf) NCI_Free(cbuf);
+ return status;
+ }
+ memcpy(xbuf, cbuf, (size_t)nbytes);
+ }
+ else xbuf = cbuf;
+
+ if (need_swap) {
+#ifdef DISABLE_IN_PLACE_SWAP
+ if (xbuf == buf) {
+#else
+ if (xbuf == buf && nbytes <= NC_BYTE_SWAP_BUFFER_SIZE) {
+#endif
+ /* allocate xbuf and copy buf to xbuf, before byte-swap */
+ xbuf = NCI_Malloc((size_t)nbytes);
+ memcpy(xbuf, buf, (size_t)nbytes);
+ }
+ /* perform array in-place byte swap on xbuf */
+ ncmpii_in_swapn(xbuf, bnelems, ncmpix_len_nctype(varp->type));
+
+ if (xbuf == buf) need_swap_back_buf = 1;
+ /* user buf needs to be swapped back to its original contents */
+ }
+ }
+ /* cbuf is no longer needed */
+ if (cbuf != buf && cbuf != xbuf) NCI_Free(cbuf);
+ }
+ else { /* rw_flag == READ_REQ */
+ /* Type conversion and byte swap for read are done at wait call, we
+ * need bnelems to reverse the steps as done in write case
+ */
+ if (buftype_is_contig && imaptype == MPI_DATATYPE_NULL && !need_convert)
+ xbuf = buf; /* there is no buffered read (bget_var, etc.) */
+ else
+ xbuf = NCI_Malloc((size_t)nbytes);
+ }
+
+ /* allocate a new request object to store the write info */
+ req = (NC_req*) NCI_Malloc(sizeof(NC_req));
+
+ req->buf = buf;
+ req->xbuf = xbuf;
+ req->bnelems = bnelems;
+ req->bufcount = bufcount;
+ req->ptype = ptype;
+ req->buftype_is_contig = buftype_is_contig;
+ req->need_swap_back_buf = need_swap_back_buf;
+ req->imaptype = imaptype;
+ req->rw_flag = rw_flag;
+ req->abuf_index = abuf_index;
+ req->tmpBuf = NULL;
+ req->userBuf = NULL;
+
+ /* only when read and buftype is not contiguous, we duplicate buftype for
+ * later in the wait call to unpack buffer based on buftype
+ */
+ if (rw_flag == READ_REQ && !buftype_is_contig)
+ MPI_Type_dup(buftype, &req->buftype);
+ else
+ req->buftype = MPI_DATATYPE_NULL;
+
+ pack_request(ncp, varp, req, start, count, stride);
+
+ /* add the new request to the internal request array (or linked list) */
+ if (ncp->head == NULL) {
+ req->id = 0;
+ ncp->head = req;
+ ncp->tail = ncp->head;
+ }
+ else { /* add to the tail */
+ if (!isSameGroup)
+ req->id = ncp->tail->id + 1;
+ else if (reqid != NULL)
+ req->id = *reqid;
+ ncp->tail->next = req;
+ ncp->tail = req;
+ }
+ for (i=0; i<req->num_subreqs; i++)
+ req->subreqs[i].id = req->id;
+
+ /* return the request ID */
+ if (reqid != NULL) *reqid = req->id;
+
+ return ((warning != NC_NOERR) ? warning : status);
+}
+
+/*----< pack_request() >------------------------------------------------------*/
+/* if this request is for a record variable, then we break this request into
+ * sub-requests, each for a record
+ */
+static int
+pack_request(NC *ncp,
+ NC_var *varp,
+ NC_req *req,
+ const MPI_Offset start[],
+ const MPI_Offset count[],
+ const MPI_Offset stride[])
+{
+ int i, j;
+ size_t dims_chunk;
+ NC_req *subreqs;
+
+ dims_chunk = (size_t)varp->ndims * SIZEOF_MPI_OFFSET;
+
+ req->varp = varp;
+ req->next = NULL;
+ req->subreqs = NULL;
+ req->num_subreqs = 0;
+
+ if (stride != NULL)
+ req->start = (MPI_Offset*) NCI_Malloc(dims_chunk*3);
+ else
+ req->start = (MPI_Offset*) NCI_Malloc(dims_chunk*2);
+
+ req->count = req->start + varp->ndims;
+
+ if (stride != NULL)
+ req->stride = req->count + varp->ndims;
+ else
+ req->stride = NULL;
+
+ for (i=0; i<varp->ndims; i++) {
+ req->start[i] = start[i];
+ req->count[i] = count[i];
+ if (stride != NULL)
+ req->stride[i] = stride[i];
+ }
+
+#ifdef _DISALLOW_POST_NONBLOCKING_API_IN_DEFINE_MODE
+ /* move the offset calculation to wait time (ncmpii_wait_getput),
+ * such that posting a nonblocking request can be done in define
+ * mode
+ */
+
+ /* get the starting file offset for this request */
+ ncmpii_get_offset(ncp, varp, start, NULL, NULL, req->rw_flag,
+ &req->offset_start);
+
+ /* get the ending file offset for this request */
+ ncmpii_get_offset(ncp, varp, start, count, stride, req->rw_flag,
+ &req->offset_end);
+ req->offset_end += varp->xsz - 1;
+#endif
+
+ /* check if this is a record variable. if yes, split the request into
+ * subrequests, one subrequest for a record access. Hereinafter,
+ * treat each request as a non-record variable request
+ */
+
+ /* check if this access is within one record, if yes, no need to create
+ subrequests */
+ if (IS_RECVAR(varp) && req->count[0] > 1) {
+ MPI_Offset rec_bufcount = 1;
+ for (i=1; i<varp->ndims; i++)
+ rec_bufcount *= req->count[i];
+
+ subreqs = (NC_req*) NCI_Malloc((size_t)req->count[0]*sizeof(NC_req));
+ for (i=0; i<req->count[0]; i++) {
+ MPI_Offset span;
+ subreqs[i] = *req; /* inherit most attributes from req */
+
+ /* each sub-request contains <= one record size */
+ if (stride != NULL)
+ subreqs[i].start = (MPI_Offset*) NCI_Malloc(dims_chunk*3);
+ else
+ subreqs[i].start = (MPI_Offset*) NCI_Malloc(dims_chunk*2);
+
+ subreqs[i].count = subreqs[i].start + varp->ndims;
+
+ if (stride != NULL) {
+ subreqs[i].stride = subreqs[i].count + varp->ndims;
+ subreqs[i].start[0] = req->start[0] + stride[0] * i;
+ subreqs[i].stride[0] = req->stride[0];
+ } else {
+ subreqs[i].stride = NULL;
+ subreqs[i].start[0] = req->start[0] + i;
+ }
+
+ subreqs[i].count[0] = 1;
+ subreqs[i].bnelems = 1;
+ for (j=1; j<varp->ndims; j++) {
+ subreqs[i].start[j] = req->start[j];
+ subreqs[i].count[j] = req->count[j];
+ subreqs[i].bnelems *= subreqs[i].count[j];
+ if (stride != NULL)
+ subreqs[i].stride[j] = req->stride[j];
+ }
+
+#ifdef _DISALLOW_POST_NONBLOCKING_API_IN_DEFINE_MODE
+ /* move the offset calculation to wait time (ncmpii_wait_getput),
+ * such that posting a nonblocking request can be done in define
+ * mode
+ */
+ ncmpii_get_offset(ncp, varp, subreqs[i].start, NULL, NULL,
+ subreqs[i].rw_flag, &subreqs[i].offset_start);
+ ncmpii_get_offset(ncp, varp, subreqs[i].start,
+ subreqs[i].count, subreqs[i].stride,
+ subreqs[i].rw_flag, &subreqs[i].offset_end);
+ subreqs[i].offset_end += varp->xsz - 1;
+#endif
+ span = i*rec_bufcount*varp->xsz;
+ subreqs[i].buf = (char*)(req->buf) + span;
+ /* xbuf cannot be NULL assert(req->xbuf != NULL); */
+ subreqs[i].xbuf = (char*)(req->xbuf) + span;
+ subreqs[i].bufcount = rec_bufcount;
+ }
+ req->num_subreqs = (int)req->count[0];
+ req->subreqs = subreqs;
+
+ if (req->count[0] != (int)req->count[0])
+ DEBUG_RETURN_ERROR(NC_EINTOVERFLOW)
+ }
+
+ return NC_NOERR;
+}
+
diff --git a/src/lib/i_varn.m4 b/src/lib/i_varn.m4
new file mode 100644
index 0000000..f3fa832
--- /dev/null
+++ b/src/lib/i_varn.m4
@@ -0,0 +1,336 @@
+dnl Process this m4 file to produce 'C' language file.
+dnl
+dnl If you see this line, you can ignore the next one.
+/* Do not edit this file. It is produced from the corresponding .m4 source */
+dnl
+/*
+ * Copyright (C) 2014, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ */
+/* $Id: i_varn.m4 2290 2016-01-02 18:37:46Z wkliao $ */
+
+#if HAVE_CONFIG_H
+# include "ncconfig.h"
+#endif
+
+#include <stdio.h>
+#include <unistd.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#include <assert.h>
+
+#include <mpi.h>
+
+#include "nc.h"
+#include "ncx.h"
+#include "ncmpidtype.h"
+#include "macro.h"
+
+/* ncmpi_iget/iput_varn_<type>_<mode> API:
+ * type: data type of I/O buffer, buf
+ * mode: indpendent (<nond>) or collective (_all)
+ *
+ * arguments:
+ * num: number of start and count pairs
+ * starts: an 2D array of size [num][ndims]. Each starts[i][*] indicates
+ * the starting array indices for a subarray request. ndims is
+ * the number of dimensions of the defined netCDF variable.
+ * counts: an 2D array of size [num][ndims]. Each counts[i][*] indicates
+ * the number of array elements to be accessed. This argument
+ * can be NULL, equivalent to counts with all 1s.
+ * bufcount and buftype: these 2 arguments are only available for flexible
+ * APIs, indicating the I/O buffer memory layout. When buftype is
+ * MPI_DATATYPE_NULL, bufcount is ignored and the data type of buf
+ * is considered matched the variable data type defined in the file.
+ * reqid: request ID returned to user
+ */
+
+static int
+ncmpii_igetput_varn(NC *ncp,
+ NC_var *varp,
+ int num,
+ MPI_Offset* const starts[], /* [num][varp->ndims] */
+ MPI_Offset* const counts[], /* [num][varp->ndims] */
+ void *buf,
+ MPI_Offset bufcount,
+ MPI_Datatype buftype, /* data type of the bufer */
+ int *reqid,
+ int rw_flag,
+ int use_abuf);
+
+dnl
+define(`IsBput', `ifelse(`$1',`bput', `1', `0')')dnl
+define(`ReadWrite', `ifelse(`$1',`iget', `READ_REQ', `WRITE_REQ')')dnl
+define(`BufConst', `ifelse(`$1',`iget', , `const')')dnl
+dnl
+dnl VARN_FLEXIBLE()
+dnl
+define(`VARN_FLEXIBLE',dnl
+`dnl
+/*----< ncmpi_$1_varn() >-----------------------------------------------------*/
+int
+ncmpi_$1_varn(int ncid,
+ int varid,
+ int num,
+ MPI_Offset* const starts[],
+ MPI_Offset* const counts[],
+ BufConst($1) void *buf,
+ MPI_Offset bufcount,
+ MPI_Datatype buftype,
+ int *reqid)
+{
+ int status;
+ NC *ncp;
+ NC_var *varp=NULL;
+
+ if (reqid != NULL) *reqid = NC_REQ_NULL;
+
+ /* check for zero-size request */
+ if (num == 0 || bufcount == 0) return NC_NOERR;
+
+ status = ncmpii_sanity_check(ncid, varid, NULL, NULL, bufcount, API_VARN,
+ 0, 1, ReadWrite($1), NONBLOCKING_IO, &ncp, &varp);
+ if (status != NC_NOERR) return status;
+
+ return ncmpii_igetput_varn(ncp, varp, num, starts, counts, (void*)buf,
+ bufcount, buftype, reqid, ReadWrite($1),
+ IsBput($1));
+}
+')dnl
+
+dnl PnetCDF flexible APIs
+VARN_FLEXIBLE(iput)
+VARN_FLEXIBLE(iget)
+VARN_FLEXIBLE(bput)
+
+dnl
+dnl VARN()
+dnl
+define(`VARN',dnl
+`dnl
+/*----< ncmpi_$1_varn_$2() >--------------------------------------------------*/
+int
+ncmpi_$1_varn_$2(int ncid,
+ int varid,
+ int num,
+ MPI_Offset* const starts[],
+ MPI_Offset* const counts[],
+ BufConst($1) $3 *buf,
+ int *reqid)
+{
+ int status;
+ NC *ncp;
+ NC_var *varp=NULL;
+
+ if (reqid != NULL) *reqid = NC_REQ_NULL;
+
+ /* check for zero request */
+ if (num == 0) return NC_NOERR;
+
+ status = ncmpii_sanity_check(ncid, varid, NULL, NULL, 0, API_VARN,
+ 0, 0, ReadWrite($1), NONBLOCKING_IO, &ncp, &varp);
+ if (status != NC_NOERR) return status;
+
+ /* set bufcount to -1 indicating non-flexible API */
+ return ncmpii_igetput_varn(ncp, varp, num, starts, counts, (void*)buf,
+ -1, $4, reqid, ReadWrite($1), IsBput($1));
+}
+')dnl
+
+VARN(iput, text, char, MPI_CHAR)
+VARN(iput, schar, schar, MPI_SIGNED_CHAR)
+VARN(iput, uchar, uchar, MPI_UNSIGNED_CHAR)
+VARN(iput, short, short, MPI_SHORT)
+VARN(iput, ushort, ushort, MPI_UNSIGNED_SHORT)
+VARN(iput, int, int, MPI_INT)
+VARN(iput, uint, uint, MPI_UNSIGNED)
+VARN(iput, long, long, MPI_LONG)
+VARN(iput, float, float, MPI_FLOAT)
+VARN(iput, double, double, MPI_DOUBLE)
+VARN(iput, longlong, long long, MPI_LONG_LONG_INT)
+VARN(iput, ulonglong, unsigned long long, MPI_UNSIGNED_LONG_LONG)
+
+VARN(iget, text, char, MPI_CHAR)
+VARN(iget, schar, schar, MPI_SIGNED_CHAR)
+VARN(iget, uchar, uchar, MPI_UNSIGNED_CHAR)
+VARN(iget, short, short, MPI_SHORT)
+VARN(iget, ushort, ushort, MPI_UNSIGNED_SHORT)
+VARN(iget, int, int, MPI_INT)
+VARN(iget, uint, uint, MPI_UNSIGNED)
+VARN(iget, long, long, MPI_LONG)
+VARN(iget, float, float, MPI_FLOAT)
+VARN(iget, double, double, MPI_DOUBLE)
+VARN(iget, longlong, long long, MPI_LONG_LONG_INT)
+VARN(iget, ulonglong, unsigned long long, MPI_UNSIGNED_LONG_LONG)
+
+VARN(bput, text, char, MPI_CHAR)
+VARN(bput, schar, schar, MPI_SIGNED_CHAR)
+VARN(bput, uchar, uchar, MPI_UNSIGNED_CHAR)
+VARN(bput, short, short, MPI_SHORT)
+VARN(bput, ushort, ushort, MPI_UNSIGNED_SHORT)
+VARN(bput, int, int, MPI_INT)
+VARN(bput, uint, uint, MPI_UNSIGNED)
+VARN(bput, long, long, MPI_LONG)
+VARN(bput, float, float, MPI_FLOAT)
+VARN(bput, double, double, MPI_DOUBLE)
+VARN(bput, longlong, long long, MPI_LONG_LONG_INT)
+VARN(bput, ulonglong, unsigned long long, MPI_UNSIGNED_LONG_LONG)
+
+
+/*----< ncmpii_igetput_varn() >-----------------------------------------------*/
+static int
+ncmpii_igetput_varn(NC *ncp,
+ NC_var *varp,
+ int num,
+ MPI_Offset* const starts[], /* [num][varp->ndims] */
+ MPI_Offset* const counts[], /* [num][varp->ndims] */
+ void *buf,
+ MPI_Offset bufcount,
+ MPI_Datatype buftype, /* data type of the bufer */
+ int *reqidp, /* OUT: request ID */
+ int rw_flag, /* WRITE_REQ or READ_REQ */
+ int use_abuf) /* if use attached buffer */
+{
+ int i, j, el_size, status=NC_NOERR, free_cbuf=0, isSameGroup, reqid;
+ void *cbuf=NULL;
+ char *bufp;
+ MPI_Offset **_counts=NULL;
+ MPI_Datatype ptype;
+
+ if (use_abuf && ncp->abuf == NULL) DEBUG_RETURN_ERROR(NC_ENULLABUF)
+
+ /* it is illegal for starts to be NULL */
+ if (starts == NULL) DEBUG_RETURN_ERROR(NC_ENULLSTART)
+
+ if (counts != NULL) {
+ for (j=0; j<num; j++) {
+ for (i=0; i<varp->ndims; i++) {
+ if (counts[j][i] < 0) /* no negative counts[][] */
+ DEBUG_RETURN_ERROR(NC_ENEGATIVECNT)
+ }
+ }
+ }
+
+ cbuf = buf;
+ if (buftype == MPI_DATATYPE_NULL) {
+ /* In this case, we make ptype match the variable data type defined
+ * in file - no data conversion will be done. Also, it means buf is
+ * contiguous. buftype will no longer be used.
+ */
+ ptype = ncmpii_nc2mpitype(varp->type);
+ MPI_Type_size(ptype, &el_size); /* buffer element size */
+ }
+ else if (bufcount == -1) { /* if (IsPrimityMPIType(buftype)) */
+ /* this subroutine is called from a high-level API
+ * Also, it means the user buf is contiguous.
+ * Assign ptype to buftype, and buftype will no longer be used.
+ */
+ ptype = buftype;
+ MPI_Type_size(ptype, &el_size); /* buffer element size */
+ }
+ else { /* (bufcount > 0) flexible API is used */
+ /* pack buf into cbuf, a contiguous buffer */
+ int isderived, iscontig_of_ptypes;
+ MPI_Offset bnelems;
+
+ /* ptype (primitive MPI data type) from buftype
+ * el_size is the element size of ptype
+ * bnelems is the total number of ptype elements in buftype
+ */
+ status = ncmpii_dtype_decode(buftype, &ptype, &el_size, &bnelems,
+ &isderived, &iscontig_of_ptypes);
+
+ if (status != NC_NOERR) return status;
+
+ if (bufcount != (int)bufcount) DEBUG_RETURN_ERROR(NC_EINTOVERFLOW)
+
+ /* check if buftype is contiguous, if not, pack to one, cbuf */
+ if (! iscontig_of_ptypes && bnelems > 0) {
+ int position = 0;
+ MPI_Offset packsize = bnelems*el_size;
+ if (packsize != (int)packsize) DEBUG_RETURN_ERROR(NC_EINTOVERFLOW)
+
+ cbuf = NCI_Malloc((size_t)packsize);
+ free_cbuf = 1;
+ /* if not use_abuf, need a callback to free cbuf */
+
+ if (rw_flag == WRITE_REQ)
+ MPI_Pack(buf, (int)bufcount, buftype, cbuf, (int)packsize,
+ &position, MPI_COMM_SELF);
+ }
+ }
+
+ /* We allow counts == NULL and treat this the same as all 1s */
+ if (counts == NULL) {
+ _counts = (MPI_Offset**) NCI_Malloc((size_t)num * sizeof(MPI_Offset*));
+ _counts[0] = (MPI_Offset*) NCI_Malloc((size_t)(num * varp->ndims *
+ SIZEOF_MPI_OFFSET));
+ for (i=1; i<num; i++)
+ _counts[i] = _counts[i-1] + varp->ndims;
+ for (i=0; i<num; i++)
+ for (j=0; j<varp->ndims; j++)
+ _counts[i][j] = 1;
+ }
+ else
+ _counts = (MPI_Offset**) counts;
+
+ /* break buf into num pieces */
+ isSameGroup=0;
+ bufp = (char*)cbuf;
+ for (i=0; i<num; i++) {
+ MPI_Offset buflen;
+
+ /* check whether start, count, and stride are valid */
+ status = NC_start_count_stride_ck(ncp, varp, starts[i], _counts[i], NULL, rw_flag);
+ if (status != NC_NOERR) goto err_check;
+
+ for (buflen=1, j=0; j<varp->ndims; j++)
+ buflen *= _counts[i][j];
+
+ if (buflen == 0) continue;
+ status = ncmpii_igetput_varm(ncp, varp, starts[i], _counts[i], NULL,
+ NULL, bufp, buflen, ptype, &reqid,
+ rw_flag, use_abuf, isSameGroup);
+ if (status != NC_NOERR) goto err_check;
+
+ /* use isSamegroup so we end up with one nonblocking request (only the
+ * first request gets a request ID back, the rest reuse the same ID.
+ * This single ID represents num nonblocking requests */
+ isSameGroup=1;
+ bufp += buflen * el_size;
+ }
+
+ /* add callback if buftype is noncontiguous */
+ if (free_cbuf) { /* cbuf != buf, cbuf is temp allocated */
+ if (rw_flag == READ_REQ) {
+ /* tell wait() to unpack cbuf to buf and free cbuf */
+ status = ncmpii_set_iget_callback(ncp, reqid, cbuf, buf,
+ (int)bufcount, buftype);
+ }
+ else { /* WRITE_REQ */
+ if (use_abuf)
+ /* cbuf has been copied to the attached buffer, so it is safe
+ * to free cbuf now */
+ NCI_Free(cbuf);
+ else
+ /* tell wait() to free cbuf once done */
+ status = ncmpii_set_iput_callback(ncp, reqid, cbuf);
+ }
+ }
+
+err_check:
+ if (_counts != NULL && _counts != counts) {
+ NCI_Free(_counts[0]);
+ NCI_Free(_counts);
+ }
+
+ if (status != NC_NOERR) {
+ if (reqid != NC_REQ_NULL) /* cancel pending nonblocking request */
+ ncmpii_cancel(ncp, 1, &reqid, NULL);
+ if (free_cbuf) NCI_Free(cbuf);
+ }
+ if (reqidp != NULL) *reqidp = reqid;
+
+ return status;
+}
diff --git a/src/lib/m_getput_varx.m4 b/src/lib/m_getput_varx.m4
new file mode 100644
index 0000000..96575d9
--- /dev/null
+++ b/src/lib/m_getput_varx.m4
@@ -0,0 +1,1090 @@
+dnl Process this m4 file to produce 'C' language file.
+dnl
+dnl If you see this line, you can ignore the next one.
+/* Do not edit this file. It is produced from the corresponding .m4 source */
+dnl
+/*
+ * Copyright (C) 2003, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ */
+/* $Id: m_getput_varx.m4 2290 2016-01-02 18:37:46Z wkliao $ */
+
+#if HAVE_CONFIG_H
+# include "ncconfig.h"
+#endif
+
+#include <stdio.h>
+#include <unistd.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#include <assert.h>
+
+#include <mpi.h>
+
+#include "nc.h"
+#include "ncx.h"
+#include "ncmpidtype.h"
+#include "macro.h"
+
+
+/* buffer layers:
+
+ User Level buf (user defined buffer of MPI_Datatype)
+ MPI Datatype Level cbuf (contiguous buffer of ptype)
+ NetCDF XDR Level xbuf (XDR I/O buffer)
+*/
+
+static int
+ncmpii_mgetput_varm(int ncid,
+ int num,
+ int varids[], /* [num] */
+ MPI_Offset* const starts[], /* [num] */
+ MPI_Offset* const counts[], /* [num] */
+ MPI_Offset* const strides[], /* [num] */
+ MPI_Offset* const imaps[], /* [num] */
+ void *bufs[], /* [num] */
+ MPI_Offset bufcounts[], /* [num] */
+ MPI_Datatype datatypes[], /* [num] */
+ int rw_flag, /* WRITE_REQ or READ_REQ */
+ int io_method); /* COLL_IO or INDEP_IO */
+
+/*----< ncmpi_mput_var() >---------------------------------------------------*/
+int
+ncmpi_mput_var(int ncid,
+ int num,
+ int varids[], /* [num] */
+ void *bufs[], /* [num] */
+ MPI_Offset bufcounts[], /* [num] */
+ MPI_Datatype datatypes[]) /* [num] */
+{
+ return ncmpii_mgetput_varm(ncid, num, varids, NULL, NULL, NULL,
+ NULL, bufs, bufcounts, datatypes,
+ WRITE_REQ, INDEP_IO);
+}
+
+/*----< ncmpi_mput_var_all() >-----------------------------------------------*/
+int
+ncmpi_mput_var_all(int ncid,
+ int num,
+ int varids[], /* [num] */
+ void *bufs[], /* [num] */
+ MPI_Offset bufcounts[], /* [num] */
+ MPI_Datatype datatypes[]) /* [num] */
+{
+ return ncmpii_mgetput_varm(ncid, num, varids, NULL, NULL, NULL,
+ NULL, bufs, bufcounts, datatypes,
+ WRITE_REQ, COLL_IO);
+}
+
+dnl
+dnl MPUT_VAR(btype_name, btype, mpi_type, mode, mode_name)
+dnl
+define(`MPUT_VAR',dnl
+`dnl
+/*----< ncmpi_mput_var_$1$5() >-----------------------------------------------*/
+int
+ncmpi_mput_var_$1$5(int ncid,
+ int num,
+ int varids[],
+ $2 *bufs[])
+{
+ int i, err;
+ MPI_Datatype *datatypes;
+
+ datatypes = (MPI_Datatype*) NCI_Malloc((size_t)num * sizeof(MPI_Datatype));
+ for (i=0; i<num; i++)
+ datatypes[i] = $3;
+
+ err = ncmpii_mgetput_varm(ncid, num, varids, NULL, NULL, NULL,
+ NULL, (void**)bufs, NULL, datatypes,
+ WRITE_REQ, $4);
+ NCI_Free(datatypes);
+ return err;
+}
+')dnl
+
+MPUT_VAR(text, char, MPI_CHAR, INDEP_IO)
+MPUT_VAR(schar, signed char, MPI_SIGNED_CHAR, INDEP_IO)
+MPUT_VAR(uchar, unsigned char, MPI_UNSIGNED_CHAR, INDEP_IO)
+MPUT_VAR(short, short, MPI_SHORT, INDEP_IO)
+MPUT_VAR(ushort, unsigned short, MPI_UNSIGNED_SHORT, INDEP_IO)
+MPUT_VAR(int, int, MPI_INT, INDEP_IO)
+MPUT_VAR(uint, unsigned int, MPI_UNSIGNED, INDEP_IO)
+MPUT_VAR(long, long, MPI_LONG, INDEP_IO)
+MPUT_VAR(float, float, MPI_FLOAT, INDEP_IO)
+MPUT_VAR(double, double, MPI_DOUBLE, INDEP_IO)
+MPUT_VAR(longlong, long long, MPI_LONG_LONG_INT, INDEP_IO)
+MPUT_VAR(ulonglong, unsigned long long, MPI_UNSIGNED_LONG_LONG, INDEP_IO)
+
+MPUT_VAR(text, char, MPI_CHAR, COLL_IO, _all)
+MPUT_VAR(schar, signed char, MPI_SIGNED_CHAR, COLL_IO, _all)
+MPUT_VAR(uchar, unsigned char, MPI_UNSIGNED_CHAR, COLL_IO, _all)
+MPUT_VAR(short, short, MPI_SHORT, COLL_IO, _all)
+MPUT_VAR(ushort, unsigned short, MPI_UNSIGNED_SHORT, COLL_IO, _all)
+MPUT_VAR(int, int, MPI_INT, COLL_IO, _all)
+MPUT_VAR(uint, unsigned int, MPI_UNSIGNED, COLL_IO, _all)
+MPUT_VAR(long, long, MPI_LONG, COLL_IO, _all)
+MPUT_VAR(float, float, MPI_FLOAT, COLL_IO, _all)
+MPUT_VAR(double, double, MPI_DOUBLE, COLL_IO, _all)
+MPUT_VAR(longlong, long long, MPI_LONG_LONG_INT, COLL_IO, _all)
+MPUT_VAR(ulonglong, unsigned long long, MPI_UNSIGNED_LONG_LONG, COLL_IO, _all)
+
+/*----< ncmpi_mput_var1() >--------------------------------------------------*/
+int
+ncmpi_mput_var1(int ncid,
+ int num,
+ int varids[], /* [num] */
+ MPI_Offset* const starts[], /* [num] */
+ void *bufs[], /* [num] */
+ MPI_Offset bufcounts[], /* [num] */
+ MPI_Datatype datatypes[]) /* [num] */
+{
+ return ncmpii_mgetput_varm(ncid, num, varids, starts, NULL, NULL,
+ NULL, bufs, bufcounts, datatypes,
+ WRITE_REQ, INDEP_IO);
+}
+
+/*----< ncmpi_mput_var1_all() >----------------------------------------------*/
+int
+ncmpi_mput_var1_all(int ncid,
+ int num,
+ int varids[], /* [num] */
+ MPI_Offset* const starts[], /* [num] */
+ void *bufs[], /* [num] */
+ MPI_Offset bufcounts[], /* [num] */
+ MPI_Datatype datatypes[]) /* [num] */
+{
+ return ncmpii_mgetput_varm(ncid, num, varids, starts, NULL, NULL,
+ NULL, bufs, bufcounts, datatypes,
+ WRITE_REQ, COLL_IO);
+}
+
+dnl
+dnl MPUT_VAR1(btype_name, btype, mpi_type, mode, mode_name)
+dnl
+define(`MPUT_VAR1',dnl
+`dnl
+/*----< ncmpi_mput_var1_$1$5() >----------------------------------------------*/
+int
+ncmpi_mput_var1_$1$5(int ncid,
+ int num,
+ int varids[],
+ MPI_Offset* const starts[], /* [num] */
+ $2 *bufs[])
+{
+ int i, err;
+ MPI_Datatype *datatypes;
+
+ datatypes = (MPI_Datatype*) NCI_Malloc((size_t)num * sizeof(MPI_Datatype));
+ for (i=0; i<num; i++)
+ datatypes[i] = $3;
+
+ err = ncmpii_mgetput_varm(ncid, num, varids, starts, NULL, NULL,
+ NULL, (void**)bufs, NULL, datatypes,
+ WRITE_REQ, $4);
+ NCI_Free(datatypes);
+ return err;
+}
+')dnl
+
+MPUT_VAR1(text, char, MPI_CHAR, INDEP_IO)
+MPUT_VAR1(schar, signed char, MPI_SIGNED_CHAR, INDEP_IO)
+MPUT_VAR1(uchar, unsigned char, MPI_UNSIGNED_CHAR, INDEP_IO)
+MPUT_VAR1(short, short, MPI_SHORT, INDEP_IO)
+MPUT_VAR1(ushort, unsigned short, MPI_UNSIGNED_SHORT, INDEP_IO)
+MPUT_VAR1(int, int, MPI_INT, INDEP_IO)
+MPUT_VAR1(uint, unsigned int, MPI_UNSIGNED, INDEP_IO)
+MPUT_VAR1(long, long, MPI_LONG, INDEP_IO)
+MPUT_VAR1(float, float, MPI_FLOAT, INDEP_IO)
+MPUT_VAR1(double, double, MPI_DOUBLE, INDEP_IO)
+MPUT_VAR1(longlong, long long, MPI_LONG_LONG_INT, INDEP_IO)
+MPUT_VAR1(ulonglong, unsigned long long, MPI_UNSIGNED_LONG_LONG, INDEP_IO)
+
+MPUT_VAR1(text, char, MPI_CHAR, COLL_IO, _all)
+MPUT_VAR1(schar, signed char, MPI_SIGNED_CHAR, COLL_IO, _all)
+MPUT_VAR1(uchar, unsigned char, MPI_UNSIGNED_CHAR, COLL_IO, _all)
+MPUT_VAR1(short, short, MPI_SHORT, COLL_IO, _all)
+MPUT_VAR1(ushort, unsigned short, MPI_UNSIGNED_SHORT, COLL_IO, _all)
+MPUT_VAR1(int, int, MPI_INT, COLL_IO, _all)
+MPUT_VAR1(uint, unsigned int, MPI_UNSIGNED, COLL_IO, _all)
+MPUT_VAR1(long, long, MPI_LONG, COLL_IO, _all)
+MPUT_VAR1(float, float, MPI_FLOAT, COLL_IO, _all)
+MPUT_VAR1(double, double, MPI_DOUBLE, COLL_IO, _all)
+MPUT_VAR1(longlong, long long, MPI_LONG_LONG_INT, COLL_IO, _all)
+MPUT_VAR1(ulonglong, unsigned long long, MPI_UNSIGNED_LONG_LONG, COLL_IO, _all)
+
+/*----< ncmpi_mput_vara() >--------------------------------------------------*/
+int
+ncmpi_mput_vara(int ncid,
+ int num,
+ int varids[], /* [num] */
+ MPI_Offset* const starts[], /* [num] */
+ MPI_Offset* const counts[], /* [num] */
+ void *bufs[], /* [num] */
+ MPI_Offset bufcounts[], /* [num] */
+ MPI_Datatype datatypes[]) /* [num] */
+{
+ return ncmpii_mgetput_varm(ncid, num, varids, starts, counts, NULL,
+ NULL, bufs, bufcounts, datatypes,
+ WRITE_REQ, INDEP_IO);
+}
+
+/*----< ncmpi_mput_vara_all() >----------------------------------------------*/
+int
+ncmpi_mput_vara_all(int ncid,
+ int num,
+ int varids[], /* [num] */
+ MPI_Offset* const starts[], /* [num] */
+ MPI_Offset* const counts[], /* [num] */
+ void *bufs[], /* [num] */
+ MPI_Offset bufcounts[], /* [num] */
+ MPI_Datatype datatypes[]) /* [num] */
+{
+ return ncmpii_mgetput_varm(ncid, num, varids, starts, counts, NULL,
+ NULL, bufs, bufcounts, datatypes,
+ WRITE_REQ, COLL_IO);
+}
+
+dnl
+dnl MPUT_VARA(btype_name, btype, mpi_type, mode, mode_name)
+dnl
+define(`MPUT_VARA',dnl
+`dnl
+/*----< ncmpi_mput_vara_$1$5() >----------------------------------------------*/
+int
+ncmpi_mput_vara_$1$5(int ncid,
+ int num,
+ int varids[],
+ MPI_Offset* const starts[], /* [num] */
+ MPI_Offset* const counts[], /* [num] */
+ $2 *bufs[])
+{
+ int i, err;
+ MPI_Datatype *datatypes;
+
+ datatypes = (MPI_Datatype*) NCI_Malloc((size_t)num * sizeof(MPI_Datatype));
+ for (i=0; i<num; i++)
+ datatypes[i] = $3;
+
+ err = ncmpii_mgetput_varm(ncid, num, varids, starts, counts, NULL,
+ NULL, (void**)bufs, NULL, datatypes,
+ WRITE_REQ, $4);
+ NCI_Free(datatypes);
+ return err;
+}
+')dnl
+
+MPUT_VARA(text, char, MPI_CHAR, INDEP_IO)
+MPUT_VARA(schar, signed char, MPI_SIGNED_CHAR, INDEP_IO)
+MPUT_VARA(uchar, unsigned char, MPI_UNSIGNED_CHAR, INDEP_IO)
+MPUT_VARA(short, short, MPI_SHORT, INDEP_IO)
+MPUT_VARA(ushort, unsigned short, MPI_UNSIGNED_SHORT, INDEP_IO)
+MPUT_VARA(int, int, MPI_INT, INDEP_IO)
+MPUT_VARA(uint, unsigned int, MPI_UNSIGNED, INDEP_IO)
+MPUT_VARA(long, long, MPI_LONG, INDEP_IO)
+MPUT_VARA(float, float, MPI_FLOAT, INDEP_IO)
+MPUT_VARA(double, double, MPI_DOUBLE, INDEP_IO)
+MPUT_VARA(longlong, long long, MPI_LONG_LONG_INT, INDEP_IO)
+MPUT_VARA(ulonglong, unsigned long long, MPI_UNSIGNED_LONG_LONG, INDEP_IO)
+
+MPUT_VARA(text, char, MPI_CHAR, COLL_IO, _all)
+MPUT_VARA(schar, signed char, MPI_SIGNED_CHAR, COLL_IO, _all)
+MPUT_VARA(uchar, unsigned char, MPI_UNSIGNED_CHAR, COLL_IO, _all)
+MPUT_VARA(short, short, MPI_SHORT, COLL_IO, _all)
+MPUT_VARA(ushort, unsigned short, MPI_UNSIGNED_SHORT, COLL_IO, _all)
+MPUT_VARA(int, int, MPI_INT, COLL_IO, _all)
+MPUT_VARA(uint, unsigned int, MPI_UNSIGNED, COLL_IO, _all)
+MPUT_VARA(long, long, MPI_LONG, COLL_IO, _all)
+MPUT_VARA(float, float, MPI_FLOAT, COLL_IO, _all)
+MPUT_VARA(double, double, MPI_DOUBLE, COLL_IO, _all)
+MPUT_VARA(longlong, long long, MPI_LONG_LONG_INT, COLL_IO, _all)
+MPUT_VARA(ulonglong, unsigned long long, MPI_UNSIGNED_LONG_LONG, COLL_IO, _all)
+
+/*----< ncmpi_mput_vars() >--------------------------------------------------*/
+int
+ncmpi_mput_vars(int ncid,
+ int num,
+ int varids[], /* [num] */
+ MPI_Offset* const starts[], /* [num] */
+ MPI_Offset* const counts[], /* [num] */
+ MPI_Offset* const strides[], /* [num] */
+ void *bufs[], /* [num] */
+ MPI_Offset bufcounts[], /* [num] */
+ MPI_Datatype datatypes[]) /* [num] */
+{
+ return ncmpii_mgetput_varm(ncid, num, varids, starts, counts, strides,
+ NULL, bufs, bufcounts, datatypes,
+ WRITE_REQ, INDEP_IO);
+}
+
+/*----< ncmpi_mput_vars_all() >----------------------------------------------*/
+int
+ncmpi_mput_vars_all(int ncid,
+ int num,
+ int varids[], /* [num] */
+ MPI_Offset* const starts[], /* [num] */
+ MPI_Offset* const counts[], /* [num] */
+ MPI_Offset* const strides[], /* [num] */
+ void *bufs[], /* [num] */
+ MPI_Offset bufcounts[], /* [num] */
+ MPI_Datatype datatypes[]) /* [num] */
+{
+ return ncmpii_mgetput_varm(ncid, num, varids, starts, counts, strides,
+ NULL, bufs, bufcounts, datatypes,
+ WRITE_REQ, COLL_IO);
+}
+
+dnl
+dnl MPUT_VARS(btype_name, btype, mpi_type, mode, mode_name)
+dnl
+define(`MPUT_VARS',dnl
+`dnl
+/*----< ncmpi_mput_vars_$1$5() >----------------------------------------------*/
+int
+ncmpi_mput_vars_$1$5(int ncid,
+ int num,
+ int varids[],
+ MPI_Offset* const starts[], /* [num] */
+ MPI_Offset* const counts[], /* [num] */
+ MPI_Offset* const strides[], /* [num] */
+ $2 *bufs[])
+{
+ int i, err;
+ MPI_Datatype *datatypes;
+
+ datatypes = (MPI_Datatype*) NCI_Malloc((size_t)num * sizeof(MPI_Datatype));
+ for (i=0; i<num; i++)
+ datatypes[i] = $3;
+
+ err = ncmpii_mgetput_varm(ncid, num, varids, starts, counts, strides,
+ NULL, (void**)bufs, NULL, datatypes,
+ WRITE_REQ, $4);
+ NCI_Free(datatypes);
+ return err;
+}
+')dnl
+
+MPUT_VARS(text, char, MPI_CHAR, INDEP_IO)
+MPUT_VARS(schar, signed char, MPI_SIGNED_CHAR, INDEP_IO)
+MPUT_VARS(uchar, unsigned char, MPI_UNSIGNED_CHAR, INDEP_IO)
+MPUT_VARS(short, short, MPI_SHORT, INDEP_IO)
+MPUT_VARS(ushort, unsigned short, MPI_UNSIGNED_SHORT, INDEP_IO)
+MPUT_VARS(int, int, MPI_INT, INDEP_IO)
+MPUT_VARS(uint, unsigned int, MPI_UNSIGNED, INDEP_IO)
+MPUT_VARS(long, long, MPI_LONG, INDEP_IO)
+MPUT_VARS(float, float, MPI_FLOAT, INDEP_IO)
+MPUT_VARS(double, double, MPI_DOUBLE, INDEP_IO)
+MPUT_VARS(longlong, long long, MPI_LONG_LONG_INT, INDEP_IO)
+MPUT_VARS(ulonglong, unsigned long long, MPI_UNSIGNED_LONG_LONG, INDEP_IO)
+
+MPUT_VARS(text, char, MPI_CHAR, COLL_IO, _all)
+MPUT_VARS(schar, signed char, MPI_SIGNED_CHAR, COLL_IO, _all)
+MPUT_VARS(uchar, unsigned char, MPI_UNSIGNED_CHAR, COLL_IO, _all)
+MPUT_VARS(short, short, MPI_SHORT, COLL_IO, _all)
+MPUT_VARS(ushort, unsigned short, MPI_UNSIGNED_SHORT, COLL_IO, _all)
+MPUT_VARS(int, int, MPI_INT, COLL_IO, _all)
+MPUT_VARS(uint, unsigned int, MPI_UNSIGNED, COLL_IO, _all)
+MPUT_VARS(long, long, MPI_LONG, COLL_IO, _all)
+MPUT_VARS(float, float, MPI_FLOAT, COLL_IO, _all)
+MPUT_VARS(double, double, MPI_DOUBLE, COLL_IO, _all)
+MPUT_VARS(longlong, long long, MPI_LONG_LONG_INT, COLL_IO, _all)
+MPUT_VARS(ulonglong, unsigned long long, MPI_UNSIGNED_LONG_LONG, COLL_IO, _all)
+
+/*----< ncmpi_mput_varm() >--------------------------------------------------*/
+int
+ncmpi_mput_varm(int ncid,
+ int num,
+ int varids[], /* [num] */
+ MPI_Offset* const starts[], /* [num] */
+ MPI_Offset* const counts[], /* [num] */
+ MPI_Offset* const strides[], /* [num] */
+ MPI_Offset* const imaps[], /* [num] */
+ void *bufs[], /* [num] */
+ MPI_Offset bufcounts[], /* [num] */
+ MPI_Datatype datatypes[]) /* [num] */
+{
+ return ncmpii_mgetput_varm(ncid, num, varids, starts, counts, strides,
+ imaps, bufs, bufcounts, datatypes,
+ WRITE_REQ, INDEP_IO);
+}
+
+/*----< ncmpi_mput_varm_all() >----------------------------------------------*/
+int
+ncmpi_mput_varm_all(int ncid,
+ int num,
+ int varids[], /* [num] */
+ MPI_Offset* const starts[], /* [num] */
+ MPI_Offset* const counts[], /* [num] */
+ MPI_Offset* const strides[], /* [num] */
+ MPI_Offset* const imaps[], /* [num] */
+ void *bufs[], /* [num] */
+ MPI_Offset bufcounts[], /* [num] */
+ MPI_Datatype datatypes[]) /* [num] */
+{
+ return ncmpii_mgetput_varm(ncid, num, varids, starts, counts, strides,
+ imaps, bufs, bufcounts, datatypes,
+ WRITE_REQ, COLL_IO);
+}
+
+dnl
+dnl MPUT_VARM(btype_name, btype, mpi_type, mode, mode_name)
+dnl
+define(`MPUT_VARM',dnl
+`dnl
+/*----< ncmpi_mput_varm_$1$5() >----------------------------------------------*/
+int
+ncmpi_mput_varm_$1$5(int ncid,
+ int num,
+ int varids[],
+ MPI_Offset* const starts[], /* [num] */
+ MPI_Offset* const counts[], /* [num] */
+ MPI_Offset* const strides[], /* [num] */
+ MPI_Offset* const imaps[], /* [num] */
+ $2 *bufs[])
+{
+ int i, err;
+ MPI_Datatype *datatypes;
+
+ datatypes = (MPI_Datatype*) NCI_Malloc((size_t)num * sizeof(MPI_Datatype));
+ for (i=0; i<num; i++)
+ datatypes[i] = $3;
+
+ err = ncmpii_mgetput_varm(ncid, num, varids, starts, counts, strides,
+ imaps, (void**)bufs, NULL, datatypes,
+ WRITE_REQ, $4);
+ NCI_Free(datatypes);
+ return err;
+}
+')dnl
+
+MPUT_VARM(text, char, MPI_CHAR, INDEP_IO)
+MPUT_VARM(schar, signed char, MPI_SIGNED_CHAR, INDEP_IO)
+MPUT_VARM(uchar, unsigned char, MPI_UNSIGNED_CHAR, INDEP_IO)
+MPUT_VARM(short, short, MPI_SHORT, INDEP_IO)
+MPUT_VARM(ushort, unsigned short, MPI_UNSIGNED_SHORT, INDEP_IO)
+MPUT_VARM(int, int, MPI_INT, INDEP_IO)
+MPUT_VARM(uint, unsigned int, MPI_UNSIGNED, INDEP_IO)
+MPUT_VARM(long, long, MPI_LONG, INDEP_IO)
+MPUT_VARM(float, float, MPI_FLOAT, INDEP_IO)
+MPUT_VARM(double, double, MPI_DOUBLE, INDEP_IO)
+MPUT_VARM(longlong, long long, MPI_LONG_LONG_INT, INDEP_IO)
+MPUT_VARM(ulonglong, unsigned long long, MPI_UNSIGNED_LONG_LONG, INDEP_IO)
+
+MPUT_VARM(text, char, MPI_CHAR, COLL_IO, _all)
+MPUT_VARM(schar, signed char, MPI_SIGNED_CHAR, COLL_IO, _all)
+MPUT_VARM(uchar, unsigned char, MPI_UNSIGNED_CHAR, COLL_IO, _all)
+MPUT_VARM(short, short, MPI_SHORT, COLL_IO, _all)
+MPUT_VARM(ushort, unsigned short, MPI_UNSIGNED_SHORT, COLL_IO, _all)
+MPUT_VARM(int, int, MPI_INT, COLL_IO, _all)
+MPUT_VARM(uint, unsigned int, MPI_UNSIGNED, COLL_IO, _all)
+MPUT_VARM(long, long, MPI_LONG, COLL_IO, _all)
+MPUT_VARM(float, float, MPI_FLOAT, COLL_IO, _all)
+MPUT_VARM(double, double, MPI_DOUBLE, COLL_IO, _all)
+MPUT_VARM(longlong, long long, MPI_LONG_LONG_INT, COLL_IO, _all)
+MPUT_VARM(ulonglong, unsigned long long, MPI_UNSIGNED_LONG_LONG, COLL_IO, _all)
+
+/*----< ncmpi_mget_var() >---------------------------------------------------*/
+int
+ncmpi_mget_var(int ncid,
+ int num,
+ int varids[], /* [num] */
+ void *bufs[], /* [num] */
+ MPI_Offset bufcounts[], /* [num] */
+ MPI_Datatype datatypes[]) /* [num] */
+{
+ return ncmpii_mgetput_varm(ncid, num, varids, NULL, NULL, NULL,
+ NULL, bufs, bufcounts, datatypes,
+ READ_REQ, INDEP_IO);
+}
+
+/*----< ncmpi_mget_var_all() >-----------------------------------------------*/
+int
+ncmpi_mget_var_all(int ncid,
+ int num,
+ int varids[], /* [num] */
+ void *bufs[], /* [num] */
+ MPI_Offset bufcounts[], /* [num] */
+ MPI_Datatype datatypes[]) /* [num] */
+{
+ return ncmpii_mgetput_varm(ncid, num, varids, NULL, NULL, NULL,
+ NULL, bufs, bufcounts, datatypes,
+ READ_REQ, COLL_IO);
+}
+
+dnl
+dnl MGET_VAR(btype_name, btype, mpi_type, mode, mode_name)
+dnl
+define(`MGET_VAR',dnl
+`dnl
+/*----< ncmpi_mget_var_$1$5() >-----------------------------------------------*/
+int
+ncmpi_mget_var_$1$5(int ncid,
+ int num,
+ int varids[],
+ $2 *bufs[])
+{
+ int i, err;
+ MPI_Datatype *datatypes;
+
+ datatypes = (MPI_Datatype*) NCI_Malloc((size_t)num * sizeof(MPI_Datatype));
+ for (i=0; i<num; i++)
+ datatypes[i] = $3;
+
+ err = ncmpii_mgetput_varm(ncid, num, varids, NULL, NULL, NULL,
+ NULL, (void**)bufs, NULL, datatypes,
+ READ_REQ, $4);
+ NCI_Free(datatypes);
+ return err;
+}
+')dnl
+
+MGET_VAR(text, char, MPI_CHAR, INDEP_IO)
+MGET_VAR(schar, signed char, MPI_SIGNED_CHAR, INDEP_IO)
+MGET_VAR(uchar, unsigned char, MPI_UNSIGNED_CHAR, INDEP_IO)
+MGET_VAR(short, short, MPI_SHORT, INDEP_IO)
+MGET_VAR(ushort, unsigned short, MPI_UNSIGNED_SHORT, INDEP_IO)
+MGET_VAR(int, int, MPI_INT, INDEP_IO)
+MGET_VAR(uint, unsigned int, MPI_UNSIGNED, INDEP_IO)
+MGET_VAR(long, long, MPI_LONG, INDEP_IO)
+MGET_VAR(float, float, MPI_FLOAT, INDEP_IO)
+MGET_VAR(double, double, MPI_DOUBLE, INDEP_IO)
+MGET_VAR(longlong, long long, MPI_LONG_LONG_INT, INDEP_IO)
+MGET_VAR(ulonglong, unsigned long long, MPI_UNSIGNED_LONG_LONG, INDEP_IO)
+
+MGET_VAR(text, char, MPI_CHAR, COLL_IO, _all)
+MGET_VAR(schar, signed char, MPI_SIGNED_CHAR, COLL_IO, _all)
+MGET_VAR(uchar, unsigned char, MPI_UNSIGNED_CHAR, COLL_IO, _all)
+MGET_VAR(short, short, MPI_SHORT, COLL_IO, _all)
+MGET_VAR(ushort, unsigned short, MPI_UNSIGNED_SHORT, COLL_IO, _all)
+MGET_VAR(int, int, MPI_INT, COLL_IO, _all)
+MGET_VAR(uint, unsigned int, MPI_UNSIGNED, COLL_IO, _all)
+MGET_VAR(long, long, MPI_LONG, COLL_IO, _all)
+MGET_VAR(float, float, MPI_FLOAT, COLL_IO, _all)
+MGET_VAR(double, double, MPI_DOUBLE, COLL_IO, _all)
+MGET_VAR(longlong, long long, MPI_LONG_LONG_INT, COLL_IO, _all)
+MGET_VAR(ulonglong, unsigned long long, MPI_UNSIGNED_LONG_LONG, COLL_IO, _all)
+
+/*----< ncmpi_mget_var1() >--------------------------------------------------*/
+int
+ncmpi_mget_var1(int ncid,
+ int num,
+ int varids[], /* [num] */
+ MPI_Offset* const starts[], /* [num] */
+ void *bufs[], /* [num] */
+ MPI_Offset bufcounts[], /* [num] */
+ MPI_Datatype datatypes[]) /* [num] */
+{
+ return ncmpii_mgetput_varm(ncid, num, varids, starts, NULL, NULL,
+ NULL, bufs, bufcounts, datatypes,
+ READ_REQ, INDEP_IO);
+}
+
+/*----< ncmpi_mget_var1_all() >----------------------------------------------*/
+int
+ncmpi_mget_var1_all(int ncid,
+ int num,
+ int varids[], /* [num] */
+ MPI_Offset* const starts[], /* [num] */
+ void *bufs[], /* [num] */
+ MPI_Offset bufcounts[], /* [num] */
+ MPI_Datatype datatypes[]) /* [num] */
+{
+ return ncmpii_mgetput_varm(ncid, num, varids, starts, NULL, NULL,
+ NULL, bufs, bufcounts, datatypes,
+ READ_REQ, COLL_IO);
+}
+
+dnl
+dnl MGET_VAR1(btype_name, btype, mpi_type, mode, mode_name)
+dnl
+define(`MGET_VAR1',dnl
+`dnl
+/*----< ncmpi_mget_var1_$1$5() >----------------------------------------------*/
+int
+ncmpi_mget_var1_$1$5(int ncid,
+ int num,
+ int varids[],
+ MPI_Offset* const starts[], /* [num] */
+ $2 *bufs[])
+{
+ int i, err;
+ MPI_Datatype *datatypes;
+
+ datatypes = (MPI_Datatype*) NCI_Malloc((size_t)num * sizeof(MPI_Datatype));
+ for (i=0; i<num; i++)
+ datatypes[i] = $3;
+
+ err = ncmpii_mgetput_varm(ncid, num, varids, starts, NULL, NULL,
+ NULL, (void**)bufs, NULL, datatypes,
+ READ_REQ, $4);
+ NCI_Free(datatypes);
+ return err;
+}
+')dnl
+
+MGET_VAR1(text, char, MPI_CHAR, INDEP_IO)
+MGET_VAR1(schar, signed char, MPI_SIGNED_CHAR, INDEP_IO)
+MGET_VAR1(uchar, unsigned char, MPI_UNSIGNED_CHAR, INDEP_IO)
+MGET_VAR1(short, short, MPI_SHORT, INDEP_IO)
+MGET_VAR1(ushort, unsigned short, MPI_UNSIGNED_SHORT, INDEP_IO)
+MGET_VAR1(int, int, MPI_INT, INDEP_IO)
+MGET_VAR1(uint, unsigned int, MPI_UNSIGNED, INDEP_IO)
+MGET_VAR1(long, long, MPI_LONG, INDEP_IO)
+MGET_VAR1(float, float, MPI_FLOAT, INDEP_IO)
+MGET_VAR1(double, double, MPI_DOUBLE, INDEP_IO)
+MGET_VAR1(longlong, long long, MPI_LONG_LONG_INT, INDEP_IO)
+MGET_VAR1(ulonglong, unsigned long long, MPI_UNSIGNED_LONG_LONG, INDEP_IO)
+
+MGET_VAR1(text, char, MPI_CHAR, COLL_IO, _all)
+MGET_VAR1(schar, signed char, MPI_SIGNED_CHAR, COLL_IO, _all)
+MGET_VAR1(uchar, unsigned char, MPI_UNSIGNED_CHAR, COLL_IO, _all)
+MGET_VAR1(short, short, MPI_SHORT, COLL_IO, _all)
+MGET_VAR1(ushort, unsigned short, MPI_UNSIGNED_SHORT, COLL_IO, _all)
+MGET_VAR1(int, int, MPI_INT, COLL_IO, _all)
+MGET_VAR1(uint, unsigned int, MPI_UNSIGNED, COLL_IO, _all)
+MGET_VAR1(long, long, MPI_LONG, COLL_IO, _all)
+MGET_VAR1(float, float, MPI_FLOAT, COLL_IO, _all)
+MGET_VAR1(double, double, MPI_DOUBLE, COLL_IO, _all)
+MGET_VAR1(longlong, long long, MPI_LONG_LONG_INT, COLL_IO, _all)
+MGET_VAR1(ulonglong, unsigned long long, MPI_UNSIGNED_LONG_LONG, COLL_IO, _all)
+
+/*----< ncmpi_mget_vara() >--------------------------------------------------*/
+int
+ncmpi_mget_vara(int ncid,
+ int num,
+ int varids[], /* [num] */
+ MPI_Offset* const starts[], /* [num] */
+ MPI_Offset* const counts[], /* [num] */
+ void *bufs[], /* [num] */
+ MPI_Offset bufcounts[], /* [num] */
+ MPI_Datatype datatypes[]) /* [num] */
+{
+ return ncmpii_mgetput_varm(ncid, num, varids, starts, counts, NULL,
+ NULL, bufs, bufcounts, datatypes,
+ READ_REQ, INDEP_IO);
+}
+
+/*----< ncmpi_mget_vara_all() >----------------------------------------------*/
+int
+ncmpi_mget_vara_all(int ncid,
+ int num,
+ int varids[], /* [num] */
+ MPI_Offset* const starts[], /* [num] */
+ MPI_Offset* const counts[], /* [num] */
+ void *bufs[], /* [num] */
+ MPI_Offset bufcounts[], /* [num] */
+ MPI_Datatype datatypes[]) /* [num] */
+{
+ return ncmpii_mgetput_varm(ncid, num, varids, starts, counts, NULL,
+ NULL, bufs, bufcounts, datatypes,
+ READ_REQ, COLL_IO);
+}
+
+dnl
+dnl MGET_VARA(btype_name, btype, mpi_type, mode, mode_name)
+dnl
+define(`MGET_VARA',dnl
+`dnl
+/*----< ncmpi_mget_vara_$1$5() >----------------------------------------------*/
+int
+ncmpi_mget_vara_$1$5(int ncid,
+ int num,
+ int varids[],
+ MPI_Offset* const starts[], /* [num] */
+ MPI_Offset* const counts[], /* [num] */
+ $2 *bufs[])
+{
+ int i, err;
+ MPI_Datatype *datatypes;
+
+ datatypes = (MPI_Datatype*) NCI_Malloc((size_t)num * sizeof(MPI_Datatype));
+ for (i=0; i<num; i++)
+ datatypes[i] = $3;
+
+ err = ncmpii_mgetput_varm(ncid, num, varids, starts, counts, NULL,
+ NULL, (void**)bufs, NULL, datatypes,
+ READ_REQ, $4);
+ NCI_Free(datatypes);
+ return err;
+}
+')dnl
+
+MGET_VARA(text, char, MPI_CHAR, INDEP_IO)
+MGET_VARA(schar, signed char, MPI_SIGNED_CHAR, INDEP_IO)
+MGET_VARA(uchar, unsigned char, MPI_UNSIGNED_CHAR, INDEP_IO)
+MGET_VARA(short, short, MPI_SHORT, INDEP_IO)
+MGET_VARA(ushort, unsigned short, MPI_UNSIGNED_SHORT, INDEP_IO)
+MGET_VARA(int, int, MPI_INT, INDEP_IO)
+MGET_VARA(uint, unsigned int, MPI_UNSIGNED, INDEP_IO)
+MGET_VARA(long, long, MPI_LONG, INDEP_IO)
+MGET_VARA(float, float, MPI_FLOAT, INDEP_IO)
+MGET_VARA(double, double, MPI_DOUBLE, INDEP_IO)
+MGET_VARA(longlong, long long, MPI_LONG_LONG_INT, INDEP_IO)
+MGET_VARA(ulonglong, unsigned long long, MPI_UNSIGNED_LONG_LONG, INDEP_IO)
+
+MGET_VARA(text, char, MPI_CHAR, COLL_IO, _all)
+MGET_VARA(schar, signed char, MPI_SIGNED_CHAR, COLL_IO, _all)
+MGET_VARA(uchar, unsigned char, MPI_UNSIGNED_CHAR, COLL_IO, _all)
+MGET_VARA(short, short, MPI_SHORT, COLL_IO, _all)
+MGET_VARA(ushort, unsigned short, MPI_UNSIGNED_SHORT, COLL_IO, _all)
+MGET_VARA(int, int, MPI_INT, COLL_IO, _all)
+MGET_VARA(uint, unsigned int, MPI_UNSIGNED, COLL_IO, _all)
+MGET_VARA(long, long, MPI_LONG, COLL_IO, _all)
+MGET_VARA(float, float, MPI_FLOAT, COLL_IO, _all)
+MGET_VARA(double, double, MPI_DOUBLE, COLL_IO, _all)
+MGET_VARA(longlong, long long, MPI_LONG_LONG_INT, COLL_IO, _all)
+MGET_VARA(ulonglong, unsigned long long, MPI_UNSIGNED_LONG_LONG, COLL_IO, _all)
+
+/*----< ncmpi_mget_vars() >--------------------------------------------------*/
+int
+ncmpi_mget_vars(int ncid,
+ int num,
+ int varids[], /* [num] */
+ MPI_Offset* const starts[], /* [num] */
+ MPI_Offset* const counts[], /* [num] */
+ MPI_Offset* const strides[], /* [num] */
+ void *bufs[], /* [num] */
+ MPI_Offset bufcounts[], /* [num] */
+ MPI_Datatype datatypes[]) /* [num] */
+{
+ return ncmpii_mgetput_varm(ncid, num, varids, starts, counts, strides,
+ NULL, bufs, bufcounts, datatypes,
+ READ_REQ, INDEP_IO);
+}
+
+/*----< ncmpi_mget_vars_all() >----------------------------------------------*/
+int
+ncmpi_mget_vars_all(int ncid,
+ int num,
+ int varids[], /* [num] */
+ MPI_Offset* const starts[], /* [num] */
+ MPI_Offset* const counts[], /* [num] */
+ MPI_Offset* const strides[], /* [num] */
+ void *bufs[], /* [num] */
+ MPI_Offset bufcounts[], /* [num] */
+ MPI_Datatype datatypes[]) /* [num] */
+{
+ return ncmpii_mgetput_varm(ncid, num, varids, starts, counts, strides,
+ NULL, bufs, bufcounts, datatypes,
+ READ_REQ, COLL_IO);
+}
+
+dnl
+dnl MGET_VARS(btype_name, btype, mpi_type, mode, mode_name)
+dnl
+define(`MGET_VARS',dnl
+`dnl
+/*----< ncmpi_mget_vars_$1$5() >----------------------------------------------*/
+int
+ncmpi_mget_vars_$1$5(int ncid,
+ int num,
+ int varids[],
+ MPI_Offset* const starts[], /* [num] */
+ MPI_Offset* const counts[], /* [num] */
+ MPI_Offset* const strides[], /* [num] */
+ $2 *bufs[])
+{
+ int i, err;
+ MPI_Datatype *datatypes;
+
+ datatypes = (MPI_Datatype*) NCI_Malloc((size_t)num * sizeof(MPI_Datatype));
+ for (i=0; i<num; i++)
+ datatypes[i] = $3;
+
+ err = ncmpii_mgetput_varm(ncid, num, varids, starts, counts, strides,
+ NULL, (void**)bufs, NULL, datatypes,
+ READ_REQ, $4);
+ NCI_Free(datatypes);
+ return err;
+}
+')dnl
+
+MGET_VARS(text, char, MPI_CHAR, INDEP_IO)
+MGET_VARS(schar, signed char, MPI_SIGNED_CHAR, INDEP_IO)
+MGET_VARS(uchar, unsigned char, MPI_UNSIGNED_CHAR, INDEP_IO)
+MGET_VARS(short, short, MPI_SHORT, INDEP_IO)
+MGET_VARS(ushort, unsigned short, MPI_UNSIGNED_SHORT, INDEP_IO)
+MGET_VARS(int, int, MPI_INT, INDEP_IO)
+MGET_VARS(uint, unsigned int, MPI_UNSIGNED, INDEP_IO)
+MGET_VARS(long, long, MPI_LONG, INDEP_IO)
+MGET_VARS(float, float, MPI_FLOAT, INDEP_IO)
+MGET_VARS(double, double, MPI_DOUBLE, INDEP_IO)
+MGET_VARS(longlong, long long, MPI_LONG_LONG_INT, INDEP_IO)
+MGET_VARS(ulonglong, unsigned long long, MPI_UNSIGNED_LONG_LONG, INDEP_IO)
+
+MGET_VARS(text, char, MPI_CHAR, COLL_IO, _all)
+MGET_VARS(schar, signed char, MPI_SIGNED_CHAR, COLL_IO, _all)
+MGET_VARS(uchar, unsigned char, MPI_UNSIGNED_CHAR, COLL_IO, _all)
+MGET_VARS(short, short, MPI_SHORT, COLL_IO, _all)
+MGET_VARS(ushort, unsigned short, MPI_UNSIGNED_SHORT, COLL_IO, _all)
+MGET_VARS(int, int, MPI_INT, COLL_IO, _all)
+MGET_VARS(uint, unsigned int, MPI_UNSIGNED, COLL_IO, _all)
+MGET_VARS(long, long, MPI_LONG, COLL_IO, _all)
+MGET_VARS(float, float, MPI_FLOAT, COLL_IO, _all)
+MGET_VARS(double, double, MPI_DOUBLE, COLL_IO, _all)
+MGET_VARS(longlong, long long, MPI_LONG_LONG_INT, COLL_IO, _all)
+MGET_VARS(ulonglong, unsigned long long, MPI_UNSIGNED_LONG_LONG, COLL_IO, _all)
+
+/*----< ncmpi_mget_varm() >--------------------------------------------------*/
+int
+ncmpi_mget_varm(int ncid,
+ int num,
+ int varids[], /* [num] */
+ MPI_Offset* const starts[], /* [num] */
+ MPI_Offset* const counts[], /* [num] */
+ MPI_Offset* const strides[], /* [num] */
+ MPI_Offset* const imaps[], /* [num] */
+ void *bufs[], /* [num] */
+ MPI_Offset bufcounts[], /* [num] */
+ MPI_Datatype datatypes[]) /* [num] */
+{
+ return ncmpii_mgetput_varm(ncid, num, varids, starts, counts, strides,
+ imaps, bufs, bufcounts, datatypes,
+ READ_REQ, INDEP_IO);
+}
+
+/*----< ncmpi_mget_varm_all() >----------------------------------------------*/
+int
+ncmpi_mget_varm_all(int ncid,
+ int num,
+ int varids[], /* [num] */
+ MPI_Offset* const starts[], /* [num] */
+ MPI_Offset* const counts[], /* [num] */
+ MPI_Offset* const strides[], /* [num] */
+ MPI_Offset* const imaps[], /* [num] */
+ void *bufs[], /* [num] */
+ MPI_Offset bufcounts[], /* [num] */
+ MPI_Datatype datatypes[]) /* [num] */
+{
+ return ncmpii_mgetput_varm(ncid, num, varids, starts, counts, strides,
+ imaps, bufs, bufcounts, datatypes,
+ READ_REQ, COLL_IO);
+}
+
+dnl
+dnl MGET_VARM(btype_name, btype, mpi_type, mode, mode_name)
+dnl
+define(`MGET_VARM',dnl
+`dnl
+/*----< ncmpi_mget_varm_$1$5() >----------------------------------------------*/
+int
+ncmpi_mget_varm_$1$5(int ncid,
+ int num,
+ int varids[],
+ MPI_Offset* const starts[], /* [num] */
+ MPI_Offset* const counts[], /* [num] */
+ MPI_Offset* const strides[], /* [num] */
+ MPI_Offset* const imaps[], /* [num] */
+ $2 *bufs[])
+{
+ int i, err;
+ MPI_Datatype *datatypes;
+
+ datatypes = (MPI_Datatype*) NCI_Malloc((size_t)num * sizeof(MPI_Datatype));
+ for (i=0; i<num; i++)
+ datatypes[i] = $3;
+
+ err = ncmpii_mgetput_varm(ncid, num, varids, starts, counts, strides,
+ imaps, (void**)bufs, NULL, datatypes,
+ READ_REQ, $4);
+ NCI_Free(datatypes);
+ return err;
+}
+')dnl
+
+MGET_VARM(text, char, MPI_CHAR, INDEP_IO)
+MGET_VARM(schar, signed char, MPI_SIGNED_CHAR, INDEP_IO)
+MGET_VARM(uchar, unsigned char, MPI_UNSIGNED_CHAR, INDEP_IO)
+MGET_VARM(short, short, MPI_SHORT, INDEP_IO)
+MGET_VARM(ushort, unsigned short, MPI_UNSIGNED_SHORT, INDEP_IO)
+MGET_VARM(int, int, MPI_INT, INDEP_IO)
+MGET_VARM(uint, unsigned int, MPI_UNSIGNED, INDEP_IO)
+MGET_VARM(long, long, MPI_LONG, INDEP_IO)
+MGET_VARM(float, float, MPI_FLOAT, INDEP_IO)
+MGET_VARM(double, double, MPI_DOUBLE, INDEP_IO)
+MGET_VARM(longlong, long long, MPI_LONG_LONG_INT, INDEP_IO)
+MGET_VARM(ulonglong, unsigned long long, MPI_UNSIGNED_LONG_LONG, INDEP_IO)
+
+MGET_VARM(text, char, MPI_CHAR, COLL_IO, _all)
+MGET_VARM(schar, signed char, MPI_SIGNED_CHAR, COLL_IO, _all)
+MGET_VARM(uchar, unsigned char, MPI_UNSIGNED_CHAR, COLL_IO, _all)
+MGET_VARM(short, short, MPI_SHORT, COLL_IO, _all)
+MGET_VARM(ushort, unsigned short, MPI_UNSIGNED_SHORT, COLL_IO, _all)
+MGET_VARM(int, int, MPI_INT, COLL_IO, _all)
+MGET_VARM(uint, unsigned int, MPI_UNSIGNED, COLL_IO, _all)
+MGET_VARM(long, long, MPI_LONG, COLL_IO, _all)
+MGET_VARM(float, float, MPI_FLOAT, COLL_IO, _all)
+MGET_VARM(double, double, MPI_DOUBLE, COLL_IO, _all)
+MGET_VARM(longlong, long long, MPI_LONG_LONG_INT, COLL_IO, _all)
+MGET_VARM(ulonglong, unsigned long long, MPI_UNSIGNED_LONG_LONG, COLL_IO, _all)
+
+/*----< ncmpii_mgetput_varm() >-----------------------------------------------*/
+int
+ncmpii_mgetput_varm(int ncid,
+ int num,
+ int varids[], /* [num] */
+ MPI_Offset* const starts[], /* [num] */
+ MPI_Offset* const counts[], /* [num] */
+ MPI_Offset* const strides[], /* [num] */
+ MPI_Offset* const imaps[], /* [num] */
+ void *bufs[], /* [num] */
+ MPI_Offset bufcounts[], /* [num] */
+ MPI_Datatype datatypes[], /* [num] */
+ int rw_flag, /* WRITE_REQ or READ_REQ */
+ int io_method) /* COLL_IO or INDEP_IO */
+{
+ int i, j, err, status=NC_NOERR, *req_ids=NULL, *statuses=NULL;
+ NC *ncp=NULL;
+
+ /* check if ncid is valid */
+ status = ncmpii_NC_check_id(ncid, &ncp);
+ if (status != NC_NOERR) return status;
+ /* if ncid is invalid, we must return the error now. However, the program
+ * might hang when only a subset or processes have this error.
+ */
+
+ /* check if it is in define mode. This must be called in data mode */
+ if (NC_indef(ncp)) {
+ DEBUG_ASSIGN_ERROR(status, NC_EINDEFINE)
+ goto err_check;
+ }
+
+ /* check file write permission if this is write request */
+ if (rw_flag == WRITE_REQ && NC_readonly(ncp)) {
+ DEBUG_ASSIGN_ERROR(status, NC_EPERM)
+ goto err_check;
+ }
+
+err_check:
+ /* at this point, if status is not NC_NOERR, it is a fatal error */
+ if (ncp->safe_mode == 1 && io_method == COLL_IO) {
+ int mpireturn, min_st;
+ TRACE_COMM(MPI_Allreduce)(&status, &min_st, 1, MPI_INT, MPI_MIN,
+ ncp->nciop->comm);
+ if (mpireturn != MPI_SUCCESS)
+ return ncmpii_handle_error(mpireturn, "MPI_Allreduce");
+ if (min_st != NC_NOERR) return status;
+ }
+
+ if (io_method == INDEP_IO && status != NC_NOERR)
+ return status;
+
+ if (status != NC_NOERR)
+ /* this can only be reached for COLL_IO and safe_mode == 0, set num=0
+ * just so this process can participate the collective calls in
+ * wait_all */
+ num = 0;
+
+ if (num > 0) {
+ req_ids = (int*) NCI_Malloc((size_t)(2 * num * SIZEOF_INT));
+ statuses = req_ids + num;
+ }
+
+ /* for each request call ncmpi_igetput_varm() */
+ for (i=0; i<num; i++) {
+ NC_var *varp;
+ MPI_Offset *start, *count, buflen=0;
+
+ req_ids[i] = NC_REQ_NULL;
+
+ err = ncmpii_NC_lookupvar(ncp, varids[i], &varp);
+ if (err != NC_NOERR) {
+ if (status == NC_NOERR) status = err;
+ continue; /* invalid varid, skip this request */
+ }
+
+ if (bufcounts != NULL) buflen = bufcounts[i];
+
+ if (starts == NULL) { /* var */
+ GET_FULL_DIMENSIONS(start, count)
+ /* when bufcounts == NULL, it means the same as counts[] */
+ if (bufcounts == NULL) {
+ for (buflen=1, j=0; j<varp->ndims; j++)
+ buflen *= count[j];
+ }
+ err = ncmpii_igetput_varm(ncp, varp, start, count, NULL, NULL,
+ bufs[i], buflen, datatypes[i],
+ &req_ids[i], rw_flag, 0, 0);
+ if (status == NC_NOERR) status = err;
+ if (varp->ndims > 0) NCI_Free(start);
+ } else if (counts == NULL) { /* var1 */
+ /* check whether starts[i] is valid */
+ err = NC_start_count_stride_ck(ncp, varp, starts[i], NULL, NULL, rw_flag);
+ if (status == NC_NOERR) status = err;
+ if (err != NC_NOERR) continue; /* skip this request */
+ GET_ONE_COUNT(count)
+ /* when bufcounts == NULL, it means the same as counts[] */
+ if (bufcounts == NULL) buflen = 1;
+
+ err = ncmpii_igetput_varm(ncp, varp, starts[i], count, NULL, NULL,
+ bufs[i], buflen, datatypes[i],
+ &req_ids[i], rw_flag, 0, 0);
+ if (status == NC_NOERR) status = err;
+ if (varp->ndims > 0) NCI_Free(count);
+ } else if (strides == NULL) { /* vara */
+ /* check whether starts[i] and counts[i] are valid */
+ err = NC_start_count_stride_ck(ncp, varp, starts[i], counts[i], NULL, rw_flag);
+ if (status == NC_NOERR) status = err;
+ if (err != NC_NOERR) continue; /* skip this request */
+ /* when bufcounts == NULL, it means the same as counts[] */
+ if (bufcounts == NULL) {
+ for (buflen=1, j=0; j<varp->ndims; j++)
+ buflen *= counts[i][j];
+ }
+ err = ncmpii_igetput_varm(ncp, varp, starts[i], counts[i], NULL,
+ NULL, bufs[i], buflen, datatypes[i],
+ &req_ids[i], rw_flag, 0, 0);
+ if (status == NC_NOERR) status = err;
+ } else if (imaps == NULL) { /* vars */
+ /* check whether starts[i], counts[i], and strides[i] are valid */
+ err = NC_start_count_stride_ck(ncp, varp, starts[i], counts[i], strides[i], rw_flag);
+ if (status == NC_NOERR) status = err;
+ if (err != NC_NOERR) continue; /* skip this request */
+ /* when bufcounts == NULL, it means the same as counts[] */
+ if (bufcounts == NULL) {
+ for (buflen=1, j=0; j<varp->ndims; j++)
+ buflen *= counts[i][j];
+ }
+ err = ncmpii_igetput_varm(ncp, varp, starts[i], counts[i],
+ strides[i], NULL, bufs[i], buflen,
+ datatypes[i], &req_ids[i],
+ rw_flag, 0, 0);
+ if (status == NC_NOERR) status = err;
+ } else { /* varm */
+ /* check whether starts[i], counts[i], and strides[i] are valid */
+ err = NC_start_count_stride_ck(ncp, varp, starts[i], counts[i], strides[i], rw_flag);
+ if (status == NC_NOERR) status = err;
+ if (err != NC_NOERR) continue; /* skip this request */
+ /* when bufcounts == NULL, it means the same as counts[] */
+ if (bufcounts == NULL) {
+ for (buflen=1, j=0; j<varp->ndims; j++)
+ buflen *= counts[i][j];
+ }
+ err = ncmpii_igetput_varm(ncp, varp, starts[i], counts[i],
+ strides[i], imaps[i], bufs[i],
+ buflen, datatypes[i],
+ &req_ids[i], rw_flag, 0, 0);
+ if (status == NC_NOERR) status = err;
+ }
+ }
+
+ if (io_method == COLL_IO)
+ err = ncmpi_wait_all(ncid, num, req_ids, statuses);
+ else
+ err = ncmpi_wait(ncid, num, req_ids, statuses);
+
+ /* return the first error if there is one */
+ if (status == NC_NOERR) status = err;
+ if (status == NC_NOERR) {
+ for (i=0; i<num; i++)
+ if (statuses[i] != NC_NOERR) {
+ status = statuses[i];
+ break;
+ }
+ }
+
+ if (num > 0) NCI_Free(req_ids);
+
+ return status;
+}
diff --git a/src/lib/macro.h b/src/lib/macro.h
new file mode 100644
index 0000000..5dedec8
--- /dev/null
+++ b/src/lib/macro.h
@@ -0,0 +1,188 @@
+/*
+ * Copyright (C) 2003, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ */
+/* $Id: macro.h 2196 2015-11-27 22:31:05Z wkliao $ */
+
+#ifndef _H_MACRO
+#define _H_MACRO
+
+#ifndef MAX
+#define MAX(mm,nn) (((mm) > (nn)) ? (mm) : (nn))
+#endif
+#ifndef MIN
+#define MIN(mm,nn) (((mm) < (nn)) ? (mm) : (nn))
+#endif
+
+void *NCI_Malloc_fn(size_t size, int lineno, const char *func, const char *fname);
+void *NCI_Calloc_fn(size_t nelem, size_t elsize, int lineno, const char *func, const char *fname);
+void *NCI_Realloc_fn(void *ptr, size_t size, int lineno, const char *func, const char *fname);
+void NCI_Free_fn(void *ptr, int lineno, const char *func, const char *fname);
+
+#define NCI_Malloc(a) NCI_Malloc_fn(a,__LINE__,__func__,__FILE__)
+#define NCI_Calloc(a,b) NCI_Calloc_fn(a,b,__LINE__,__func__,__FILE__)
+#define NCI_Realloc(a,b) NCI_Realloc_fn(a,b,__LINE__,__func__,__FILE__)
+#define NCI_Free(a) NCI_Free_fn(a,__LINE__,__func__,__FILE__)
+
+
+#define CHECK_MPI_ERROR(mpi_errorcode, err_msg, nc_err) { \
+ if (mpi_errorcode != MPI_SUCCESS) { \
+ char errorString[MPI_MAX_ERROR_STRING]; \
+ int rank, errorStringLen; \
+ MPI_Comm_rank(ncp->nciop->comm, &rank); \
+ MPI_Error_string(mpi_errorcode, errorString, &errorStringLen); \
+ printf("%2d: MPI Failure at line %d of %s (%s : %s)\n", \
+ rank, __LINE__, __FILE__, err_msg, errorString); \
+ mpi_err = nc_err; \
+ } \
+}
+
+#ifdef PNC_DEBUG
+#define DEBUG_RETURN_ERROR(err) { \
+ int _rank; \
+ char *env_str = getenv("PNETCDF_VERBOSE_DEBUG_MODE"); \
+ MPI_Comm_rank(MPI_COMM_WORLD, &_rank); \
+ if (env_str != NULL && *env_str != '0') \
+ fprintf(stderr, "Rank %d: %s error at line %d of %s in %s\n", \
+ _rank,ncmpii_err_code_name(err),__LINE__,__func__,__FILE__); \
+ return err; \
+}
+#define DEBUG_ASSIGN_ERROR(status, err) { \
+ int _rank; \
+ char *env_str = getenv("PNETCDF_VERBOSE_DEBUG_MODE"); \
+ MPI_Comm_rank(MPI_COMM_WORLD, &_rank); \
+ if (env_str != NULL && *env_str != '0') \
+ fprintf(stderr, "Rank %d: %s error at line %d of %s in %s\n", \
+ _rank,ncmpii_err_code_name(err),__LINE__,__func__,__FILE__); \
+ status = err; \
+}
+#else
+#define DEBUG_RETURN_ERROR(err) return err;
+#define DEBUG_ASSIGN_ERROR(status, err) status = err;
+#endif
+
+#define GET_ONE_COUNT(count) { \
+ int _i; \
+ count = (MPI_Offset*) NCI_Malloc((size_t)varp->ndims * SIZEOF_MPI_OFFSET);\
+ for (_i=0; _i<varp->ndims; _i++) \
+ count[_i] = 1; \
+}
+
+#ifdef ENABLE_SUBFILING
+#define GET_FULL_DIMENSIONS(start, count) { \
+ int _i; \
+ int _ndims = (varp->num_subfiles>1?varp->ndims_org:varp->ndims); \
+ start = (MPI_Offset*) NCI_Malloc((size_t)_ndims*2*SIZEOF_MPI_OFFSET); \
+ count = start + _ndims; \
+ \
+ for (_i=0; _i<_ndims; _i++) { \
+ NC_dim *dimp; \
+ int _dimid; \
+ _dimid = (varp->num_subfiles>1)?varp->dimids_org[_i]:varp->dimids[_i];\
+ dimp = ncmpii_elem_NC_dimarray(&ncp->dims, _dimid); \
+ if (dimp->size == NC_UNLIMITED) \
+ count[_i] = NC_get_numrecs(ncp); \
+ else \
+ count[_i] = dimp->size; \
+ start[_i] = 0; \
+ } \
+}
+#else /* without subfiling */
+#define GET_FULL_DIMENSIONS(start, count) { \
+ int _i=0; \
+ start = (MPI_Offset*) NCI_Malloc((size_t)varp->ndims*2*SIZEOF_MPI_OFFSET);\
+ count = start + varp->ndims; \
+ \
+ if (IS_RECVAR(varp)) { /* find current numrec if varp is record var */ \
+ count[0] = NC_get_numrecs(ncp); \
+ start[0] = 0; \
+ _i = 1; \
+ } \
+ for (; _i<varp->ndims; _i++) { \
+ count[_i] = varp->shape[_i]; \
+ start[_i] = 0; \
+ } \
+}
+#endif
+
+#define DATATYPE_GET_CONVERT(vartype, inbuf, outbuf, cnelems, memtype, err) { \
+ /* vartype is the variable's data type defined in the nc file \
+ * memtype is the I/O buffers data type (MPI_Datatype) */ \
+ switch(vartype) { \
+ case NC_BYTE: \
+ err = ncmpii_x_getn_schar(inbuf, outbuf, cnelems, memtype); \
+ break; \
+ case NC_UBYTE: \
+ err = ncmpii_x_getn_uchar(inbuf, outbuf, cnelems, memtype); \
+ break; \
+ case NC_SHORT: \
+ err = ncmpii_x_getn_short(inbuf, outbuf, cnelems, memtype); \
+ break; \
+ case NC_USHORT: \
+ err = ncmpii_x_getn_ushort(inbuf, outbuf, cnelems, memtype); \
+ break; \
+ case NC_INT: \
+ err = ncmpii_x_getn_int(inbuf, outbuf, cnelems, memtype); \
+ break; \
+ case NC_UINT: \
+ err = ncmpii_x_getn_uint(inbuf, outbuf, cnelems, memtype); \
+ break; \
+ case NC_FLOAT: \
+ err = ncmpii_x_getn_float(inbuf, outbuf, cnelems, memtype); \
+ break; \
+ case NC_DOUBLE: \
+ err = ncmpii_x_getn_double(inbuf, outbuf, cnelems, memtype); \
+ break; \
+ case NC_INT64: \
+ err = ncmpii_x_getn_int64(inbuf, outbuf, cnelems, memtype); \
+ break; \
+ case NC_UINT64: \
+ err = ncmpii_x_getn_uint64(inbuf, outbuf, cnelems, memtype); \
+ break; \
+ default: \
+ err = NC_EBADTYPE; \
+ break; \
+ } \
+}
+
+#define DATATYPE_PUT_CONVERT(vartype, outbuf, inbuf, cnelems, memtype, err) { \
+ /* vartype is the variable's data type defined in the nc file \
+ * memtype is the I/O buffers data type (MPI_Datatype) */ \
+ switch(vartype) { \
+ case NC_BYTE: \
+ err = ncmpii_x_putn_schar(outbuf, inbuf, cnelems, memtype); \
+ break; \
+ case NC_UBYTE: \
+ err = ncmpii_x_putn_uchar(outbuf, inbuf, cnelems, memtype); \
+ break; \
+ case NC_SHORT: \
+ err = ncmpii_x_putn_short(outbuf, inbuf, cnelems, memtype); \
+ break; \
+ case NC_USHORT: \
+ err = ncmpii_x_putn_ushort(outbuf, inbuf, cnelems, memtype); \
+ break; \
+ case NC_INT: \
+ err = ncmpii_x_putn_int(outbuf, inbuf, cnelems, memtype); \
+ break; \
+ case NC_UINT: \
+ err = ncmpii_x_putn_uint(outbuf, inbuf, cnelems, memtype); \
+ break; \
+ case NC_FLOAT: \
+ err = ncmpii_x_putn_float(outbuf, inbuf, cnelems, memtype); \
+ break; \
+ case NC_DOUBLE: \
+ err = ncmpii_x_putn_double(outbuf, inbuf, cnelems, memtype); \
+ break; \
+ case NC_INT64: \
+ err = ncmpii_x_putn_int64(outbuf, inbuf, cnelems, memtype); \
+ break; \
+ case NC_UINT64: \
+ err = ncmpii_x_putn_uint64(outbuf, inbuf, cnelems, memtype); \
+ break; \
+ default: \
+ err = NC_EBADTYPE; \
+ break; \
+ } \
+}
+
+#endif
diff --git a/src/lib/malloc.c b/src/lib/malloc.c
new file mode 100644
index 0000000..0ec953f
--- /dev/null
+++ b/src/lib/malloc.c
@@ -0,0 +1,275 @@
+/*
+ * Copyright (C) 2003, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ */
+/* $Id: malloc.c 2244 2015-12-19 22:41:28Z wkliao $ */
+
+/* These are routines for allocating and deallocating memory.
+ They should be called as NCI_Malloc(size) and
+ NCI_Free(ptr). In macro.h, they are macro-replaced to
+ NCI_Malloc_fn(size,__LINE__,__FILE__) and
+ NCI_Free_fn(ptr,__LINE__,__FILE__).
+ */
+
+#if HAVE_CONFIG_H
+# include "ncconfig.h"
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h> /* strcpy(), strlen() */
+
+#include <mpi.h>
+#include "nc.h"
+
+#ifdef PNC_MALLOC_TRACE
+
+#ifdef HAVE_SEARCH_H
+#include <search.h> /* tfind(), tsearch() and tdelete() */
+#endif
+
+/* global variables for malloc tracing */
+static void *ncmpii_mem_root;
+static MPI_Offset ncmpii_mem_alloc;
+static MPI_Offset ncmpii_max_mem_alloc;
+
+/*----< ncmpii_init_malloc_tracing() >----------------------------------------*/
+void ncmpii_init_malloc_tracing(void)
+{
+ ncmpii_mem_alloc = 0;
+ ncmpii_max_mem_alloc = 0;
+ ncmpii_mem_root = NULL;
+}
+#endif
+
+/*----< ncmpii_inq_malloc_size() >--------------------------------------------*/
+/* get the current aggregate size allocated by malloc */
+int ncmpii_inq_malloc_size(MPI_Offset *size)
+{
+#ifdef PNC_MALLOC_TRACE
+ *size = ncmpii_mem_alloc;
+ return 1;
+#else
+ return 0;
+#endif
+}
+
+/*----< ncmpii_inq_malloc_max_size() >----------------------------------------*/
+/* get the max watermark ever researched by malloc */
+int ncmpii_inq_malloc_max_size(MPI_Offset *size)
+{
+#ifdef PNC_MALLOC_TRACE
+ *size = ncmpii_max_mem_alloc;
+ return 1;
+#else
+ return 0;
+#endif
+}
+
+#ifdef PNC_MALLOC_TRACE
+
+#ifndef MAX
+#define MAX(a,b) (((a) > (b)) ? (a) : (b))
+#endif
+#ifndef MIN
+#define MIN(a,b) (((a) < (b)) ? (a) : (b))
+#endif
+
+typedef struct {
+ void *self;
+ void *buf;
+ size_t size;
+ int lineno;
+ char *func;
+ char *filename;
+} ncmpii_mem_entry;
+
+inline static
+int ncmpii_cmp(const void *a, const void *b) {
+ ncmpii_mem_entry *fa = (ncmpii_mem_entry*)a;
+ ncmpii_mem_entry *fb = (ncmpii_mem_entry*)b;
+
+ if (fa->buf > fb->buf) return 1;
+ if (fa->buf < fb->buf) return -1;
+ return 0;
+}
+
+inline static
+void walker(const void *node, const VISIT which, const int depth) {
+ ncmpii_mem_entry *f;
+ f = *(ncmpii_mem_entry **)node;
+ if (which == preorder || which == leaf)
+ printf("Warning: malloc yet to be freed (buf=%p size=%zd filename=%s func=%s line=%d)\n", f->buf, f->size, f->filename, f->func, f->lineno);
+}
+#endif
+
+/* check if there is any malloc residue */
+int ncmpii_inq_malloc_list(void)
+{
+#ifdef PNC_MALLOC_TRACE
+ /* check if malloc tree is empty */
+ if (ncmpii_mem_root != NULL)
+ twalk(ncmpii_mem_root, walker);
+ return 1;
+#else
+ return 0;
+#endif
+}
+
+#ifdef PNC_MALLOC_TRACE
+/*----< ncmpii_add_mem_entry() >----------------------------------------------*/
+/* add a new malloc entry to the table */
+static
+void ncmpii_add_mem_entry(void *buf,
+ size_t size,
+ const int lineno,
+ const char *func,
+ const char *filename)
+{
+ /* use C tsearch utility */
+ ncmpii_mem_entry *node = (ncmpii_mem_entry*) malloc(sizeof(ncmpii_mem_entry));
+ node->self = node;
+ node->buf = buf;
+ node->size = size;
+ node->lineno = lineno;
+ node->func = (char*)malloc(strlen(func)+1);
+ node->filename = (char*)malloc(strlen(filename)+1);
+ strcpy(node->func, func);
+ node->func[strlen(func)] = '\0';
+ strcpy(node->filename, filename);
+ node->filename[strlen(filename)] = '\0';
+
+ /* search and add a new item */
+ void *ret = tsearch(node, &ncmpii_mem_root, ncmpii_cmp);
+ if (ret == NULL) {
+ printf("Error: tsearch()\n");
+ return;
+ }
+ ncmpii_mem_alloc += (MPI_Offset)size;
+ ncmpii_max_mem_alloc = MAX(ncmpii_max_mem_alloc, ncmpii_mem_alloc);
+}
+
+/*----< ncmpii_del_mem_entry() >----------------------------------------------*/
+/* delete a malloc entry from the table */
+static
+void ncmpii_del_mem_entry(void *buf)
+{
+ /* use C tsearch utility */
+ if (ncmpii_mem_root != NULL) {
+ ncmpii_mem_entry node;
+ node.buf = buf;
+ void *ret = tfind(&node, &ncmpii_mem_root, ncmpii_cmp);
+ ncmpii_mem_entry **found = (ncmpii_mem_entry**) ret;
+ if (ret == NULL) {
+ printf("Error: tfind() buf=%p\n", buf);
+ return;
+ }
+ /* free space for func and filename */
+ free((*found)->func);
+ free((*found)->filename);
+
+ /* subtract the space amount to be freed */
+ ncmpii_mem_alloc -= (MPI_Offset)((*found)->size);
+ void *tmp = (*found)->self;
+ ret = tdelete(&node, &ncmpii_mem_root, ncmpii_cmp);
+ if (ret == NULL) {
+ printf("Error: tdelete() buf=%p\n", buf);
+ return;
+ }
+ free(tmp);
+ }
+}
+#endif
+
+/*----< NCI_Malloc_fn() >-----------------------------------------------------*/
+void *NCI_Malloc_fn(size_t size,
+ const int lineno,
+ const char *func,
+ const char *filename)
+{
+#ifdef NC_DEBUG
+ if (size == 0)
+ fprintf(stderr, "Attempt to malloc zero-size in file %s, line %d\n", filename, lineno);
+#endif
+ if (size == 0) return NULL;
+ void *buf = malloc(size);
+ if (!buf) {
+ fprintf(stderr, "malloc(%zd) failed in file %s, line %d\n", size, filename, lineno);
+ MPI_Abort(MPI_COMM_WORLD, 1);
+ }
+#ifdef PNC_MALLOC_TRACE
+ ncmpii_add_mem_entry(buf, size, lineno, func, filename);
+#endif
+ return buf;
+}
+
+
+/*----< NCI_Calloc_fn() >-----------------------------------------------------*/
+void *NCI_Calloc_fn(size_t nelem,
+ size_t elsize,
+ const int lineno,
+ const char *func,
+ const char *filename)
+{
+#ifdef NC_DEBUG
+ if (nelem == 0 || elsize == 0)
+ fprintf(stderr, "Attempt to calloc zero-size in file %s, line %d\n", filename, lineno);
+#endif
+ if (nelem == 0 || elsize == 0) return NULL;
+ void *buf =calloc(nelem, elsize);
+ if (!buf) {
+ fprintf(stderr, "calloc(%zd, %zd) failed in file %s, line %d\n", nelem, elsize, filename, lineno);
+ MPI_Abort(MPI_COMM_WORLD, 1);
+ }
+#ifdef PNC_MALLOC_TRACE
+ ncmpii_add_mem_entry(buf, nelem * elsize, lineno, func, filename);
+#endif
+ return buf;
+}
+
+
+/*----< NCI_Realloc_fn() >----------------------------------------------------*/
+void *NCI_Realloc_fn(void *ptr,
+ size_t size,
+ const int lineno,
+ const char *func,
+ const char *filename)
+{
+#ifdef NC_DEBUG
+ if (size == 0)
+ fprintf(stderr, "Attempt to realloc zero-size in file %s, line %d\n", filename, lineno);
+#endif
+#ifdef PNC_MALLOC_TRACE
+ if (ptr != NULL) ncmpii_del_mem_entry(ptr);
+#endif
+ if (size == 0) return NULL;
+ void *buf = (void *) realloc(ptr, size);
+ if (!buf) {
+ fprintf(stderr, "realloc failed in file %s, line %d\n", filename, lineno);
+ MPI_Abort(MPI_COMM_WORLD, 1);
+ }
+#ifdef PNC_MALLOC_TRACE
+ ncmpii_add_mem_entry(buf, size, lineno, func, filename);
+#endif
+ return buf;
+}
+
+
+/*----< NCI_Free_fn() >-------------------------------------------------------*/
+void NCI_Free_fn(void *ptr,
+ const int lineno,
+ const char *func,
+ const char *filename)
+{
+#ifdef NC_DEBUG
+ if (ptr == NULL)
+ fprintf(stderr, "Attempt to free null pointer in file %s, line %d\n", filename, lineno);
+#endif
+ if (ptr == NULL) return;
+#ifdef PNC_MALLOC_TRACE
+ ncmpii_del_mem_entry(ptr);
+#endif
+ free(ptr);
+}
+
+
diff --git a/src/lib/mpincio.c b/src/lib/mpincio.c
new file mode 100644
index 0000000..9ee5fce
--- /dev/null
+++ b/src/lib/mpincio.c
@@ -0,0 +1,592 @@
+/*
+ * Copyright (C) 2003, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ */
+/* $Id: mpincio.c 2196 2015-11-27 22:31:05Z wkliao $ */
+
+#if HAVE_CONFIG_H
+# include "ncconfig.h"
+#endif
+
+#ifdef HAVE_ACCESS
+#include <unistd.h> /* access() */
+#endif
+#include <assert.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#include <stdio.h>
+#include <errno.h>
+#include <string.h> /* strchr() */
+#ifdef _MSC_VER /* Microsoft Compilers */
+#include <io.h>
+#else
+#include <unistd.h>
+#endif
+
+/* #define INSTRUMENT 1 */
+#ifdef INSTRUMENT /* debugging */
+#undef NDEBUG
+#include <stdio.h>
+#include "instr.h"
+#endif
+
+#include <mpi.h>
+
+#include "nc.h"
+#include "ncio.h"
+#include "fbits.h"
+#include "rnd.h"
+#include "macro.h"
+
+#if !defined(NDEBUG) && !defined(X_INT_MAX)
+#define X_INT_MAX INT_MAX
+#endif
+
+#if 0 /* !defined(NDEBUG) && !defined(X_ALIGN) */
+#define X_ALIGN 4
+#else
+#undef X_ALIGN
+#endif
+
+#define MAX_NC_ID 1024
+
+static unsigned char IDalloc[MAX_NC_ID];
+
+inline void
+ncmpiio_free(ncio *nciop) {
+ if (nciop != NULL) {
+#ifdef HAVE_MPI_INFO_FREE
+ if (nciop->mpiinfo != MPI_INFO_NULL)
+ MPI_Info_free(&(nciop->mpiinfo));
+#endif
+ if (nciop->comm != MPI_COMM_NULL)
+ MPI_Comm_free(&(nciop->comm));
+
+ NCI_Free(nciop);
+ }
+}
+
+inline ncio *
+ncmpiio_new(const char *path, int ioflags)
+{
+ size_t sz_ncio = M_RNDUP(sizeof(ncio));
+ size_t sz_path = M_RNDUP(strlen(path) +1);
+ ncio *nciop;
+
+ nciop = (ncio *) NCI_Malloc(sz_ncio + sz_path);
+ if (nciop == NULL) return NULL;
+
+ nciop->ioflags = ioflags;
+ nciop->comm = MPI_COMM_NULL;
+ nciop->mpiinfo = MPI_INFO_NULL;
+ nciop->put_size = 0;
+ nciop->get_size = 0;
+
+ nciop->path = (char *) ((char *)nciop + sz_ncio);
+ (void) strcpy((char *)nciop->path, path);
+
+ return nciop;
+}
+
+/*----< ncmpiio_extract_hints() >--------------------------------------------*/
+/* this is where the I/O hints designated to pnetcdf are extracted */
+static
+void ncmpiio_extract_hints(ncio *nciop,
+ MPI_Info info)
+{
+ /* value 0 indicates the hint is not set */
+ nciop->hints.h_align = 0;
+ nciop->hints.v_align = 0;
+ nciop->hints.r_align = 0;
+ nciop->hints.header_read_chunk_size = 0;
+#ifdef ENABLE_SUBFILING
+ nciop->hints.subfile_mode = 1;
+ nciop->hints.num_subfiles = 0;
+#endif
+
+ /* extract NC hints */
+ if (info != MPI_INFO_NULL) {
+ char value[MPI_MAX_INFO_VAL];
+ int flag;
+
+ MPI_Info_get(info, "nc_header_align_size", MPI_MAX_INFO_VAL-1, value,
+ &flag);
+ if (flag) nciop->hints.h_align = atoll(value);
+
+ MPI_Info_get(info, "nc_var_align_size", MPI_MAX_INFO_VAL-1, value,
+ &flag);
+ if (flag) nciop->hints.v_align = atoll(value);
+
+ MPI_Info_get(info, "nc_record_align_size", MPI_MAX_INFO_VAL-1,
+ value, &flag);
+ if (flag) nciop->hints.r_align = atoll(value);
+
+ MPI_Info_get(info, "nc_header_read_chunk_size", MPI_MAX_INFO_VAL-1,
+ value, &flag);
+ if (flag) nciop->hints.header_read_chunk_size = atoll(value);
+
+#ifdef ENABLE_SUBFILING
+ MPI_Info_get(info, "pnetcdf_subfiling", MPI_MAX_INFO_VAL-1,
+ value, &flag);
+ if (flag && strcasecmp(value, "disable") == 0)
+ nciop->hints.subfile_mode = 0;
+
+ MPI_Info_get(info, "nc_num_subfiles", MPI_MAX_INFO_VAL-1,
+ value, &flag);
+ if (flag) nciop->hints.num_subfiles = atoi(value);
+#endif
+
+ /* nc_header_align_size, nc_var_align_size, and nciop->hints.r_align
+ * take effect when a file is created or opened and later adding more
+ * header or variable data */
+
+ if (nciop->hints.h_align < 0)
+ nciop->hints.h_align = 0;
+ if (nciop->hints.v_align < 0)
+ nciop->hints.v_align = 0;
+ if (nciop->hints.r_align < 0)
+ nciop->hints.r_align = 0;
+ if (nciop->hints.header_read_chunk_size < 0)
+ nciop->hints.header_read_chunk_size = 0;
+#ifdef ENABLE_SUBFILING
+ if (nciop->hints.num_subfiles < 0)
+ nciop->hints.num_subfiles = 0;
+ /* override subfile hints if env var is set */
+ char *num_sf_env;
+ num_sf_env = getenv("NC_NUM_SUBFILES");
+ if (num_sf_env != NULL)
+ nciop->hints.num_subfiles = atoi(num_sf_env);
+ if (nciop->hints.subfile_mode == 0)
+ nciop->hints.num_subfiles = 0;
+#endif
+ }
+}
+
+/*----< ncmpiio_create() >---------------------------------------------------*/
+int
+ncmpiio_create(MPI_Comm comm,
+ const char *path,
+ int ioflags,
+ MPI_Info info,
+ NC *ncp)
+{
+ ncio *nciop;
+ int i, rank, mpireturn, err;
+ int mpiomode = MPI_MODE_RDWR | MPI_MODE_CREATE;
+
+ /* TODO: check whether path are the same across all processes */
+ if (ncp->safe_mode) {
+ int isPathValid=1;
+ if (path == NULL || *path == 0) isPathValid = 0;
+ TRACE_COMM(MPI_Allreduce)(&isPathValid, &err, 1, MPI_INT, MPI_LAND, comm);
+ if (err == 0) DEBUG_RETURN_ERROR(NC_EINVAL)
+ }
+
+ MPI_Comm_rank(comm, &rank);
+
+ /* NC_CLOBBER is the default mode, even if it is not used in cmode */
+ if (fIsSet(ioflags, NC_NOCLOBBER)) {
+ /* check if file exists: NetCDF requires NC_EEXIST returned if the file
+ * already exists and NC_NOCLOBBER mode is used in create
+ */
+#ifdef HAVE_ACCESS
+ int file_exist;
+ /* if access() is available, use it to check whether file already exists
+ * rank 0 calls access() and broadcasts file_exist */
+ if (rank == 0) {
+ /* remove the file system type prefix name if there is any.
+ * For example, path=="lustre:/home/foo/testfile.nc",
+ * use "/home/foo/testfile.nc" when calling access()
+ */
+ char *filename = strchr(path, ':');
+ if (filename == NULL) /* no prefix */
+ filename = (char*)path;
+ else
+ filename++;
+
+ if (access(filename, F_OK) == 0) file_exist = 1;
+ else file_exist = 0;
+ }
+ TRACE_COMM(MPI_Bcast)(&file_exist, 1, MPI_INT, 0, comm);
+ if (file_exist) DEBUG_RETURN_ERROR(NC_EEXIST)
+#else
+ /* use MPI_MODE_EXCL mode in MPI_File_open and check returned error */
+ fSet(mpiomode, MPI_MODE_EXCL);
+#endif
+ }
+ else { /* NC_CLOBBER is the default mode in create */
+ /* rank 0 deletes the file and ignores error code for file not exist
+ * Note calling MPI_File_set_size is expensive as it calls truncate()
+ */
+ if (rank == 0) {
+#ifdef HAVE_UNLINK
+ err = unlink(path);
+ if (err < 0 && errno != ENOENT) /* ignore ENOENT: file not exist */
+ DEBUG_ASSIGN_ERROR(err, NC_EFILE) /* other error */
+ else
+ err = NC_NOERR;
+#else
+ err = NC_NOERR;
+ TRACE_IO(MPI_File_delete)((char*)path, MPI_INFO_NULL);
+ if (mpireturn != MPI_SUCCESS) {
+ int errorclass;
+ MPI_Error_class(mpireturn, &errorclass);
+ if (errorclass != MPI_ERR_NO_SUCH_FILE) /* ignore this error */
+ err = ncmpii_handle_error(mpireturn, "MPI_File_delete");
+ }
+#endif
+ }
+ /* all processes must wait here until file deletion is completed */
+ TRACE_COMM(MPI_Bcast)(&err, 1, MPI_INT, 0, comm);
+ if (err != NC_NOERR) return err;
+ }
+
+ /* ignore if NC_NOWRITE set by user */
+ fSet(ioflags, NC_WRITE);
+
+ nciop = ncmpiio_new(path, ioflags); /* allocate buffer */
+ if (nciop == NULL)
+ DEBUG_RETURN_ERROR(NC_ENOMEM)
+
+ nciop->mpiomode = MPI_MODE_RDWR;
+ nciop->mpioflags = 0;
+
+ /* extract MPI-IO hints */
+ ncmpiio_extract_hints(nciop, info);
+
+ TRACE_IO(MPI_File_open)(comm, (char *)path, mpiomode, info,
+ &nciop->collective_fh);
+ if (mpireturn != MPI_SUCCESS) {
+ ncmpiio_free(nciop);
+#ifndef HAVE_ACCESS
+ if (fIsSet(ioflags, NC_NOCLOBBER)) {
+ /* This is the case when NC_NOCLOBBER is used in file creation and
+ * function access() is not available. MPI_MODE_EXCL is set in open
+ * mode. When MPI_MODE_EXCL is used and the file already exists,
+ * MPI-IO should return error class MPI_ERR_FILE_EXISTS. But, some
+ * MPI-IO implementations (older ROMIO) do not correctly return
+ * this error class. In this case, we can do the followings: check
+ * errno to see if it set to EEXIST. Note usually rank 0 makes the
+ * file open call and can be the only one having errno set.
+ */
+ TRACE_COMM(MPI_Bcast)(&errno, 1, MPI_INT, 0, comm);
+ if (errno == EEXIST) DEBUG_RETURN_ERROR(NC_EEXIST)
+ }
+#endif
+ return ncmpii_handle_error(mpireturn, "MPI_File_open");
+ /* for NC_NOCLOBBER, MPI_MODE_EXCL was added to mpiomode. If the file
+ * already exists, MPI-IO should return error class MPI_ERR_FILE_EXISTS
+ * which PnetCDF will return error code NC_EEXIST. This is checked
+ * inside of ncmpii_handle_error()
+ */
+ }
+
+ for (i=0; i<MAX_NC_ID; i++)
+ if (IDalloc[i] == 0)
+ break;
+
+ if (i == MAX_NC_ID) {
+ ncmpiio_free(nciop);
+ DEBUG_RETURN_ERROR(NC_ENFILE)
+ }
+
+ *((int *)&nciop->fd) = i;
+ IDalloc[i] = 1;
+
+ /* collective I/O mode is the default mode */
+ set_NC_collectiveFh(nciop);
+
+ /* duplicate communicator as user may free it later */
+ mpireturn = MPI_Comm_dup(comm, &(nciop->comm));
+ if (mpireturn != MPI_SUCCESS)
+ return ncmpii_handle_error(mpireturn, "MPI_Comm_dup");
+
+ /* get the file info actually used by MPI-IO (maybe alter user's info) */
+ MPI_File_get_info(nciop->collective_fh, &nciop->mpiinfo);
+
+ ncp->nciop = nciop;
+ return NC_NOERR;
+}
+
+/*----< ncmpiio_open() >-----------------------------------------------------*/
+int
+ncmpiio_open(MPI_Comm comm,
+ const char *path,
+ int ioflags,
+ MPI_Info info,
+ NC *ncp)
+{
+ ncio *nciop;
+ int i, mpireturn;
+ int mpiomode = fIsSet(ioflags, NC_WRITE) ? MPI_MODE_RDWR : MPI_MODE_RDONLY;
+
+ /* TODO: check whether path are the same across all processes */
+ if (ncp->safe_mode) {
+ int isPathValid=1, err;
+ if (path == NULL || *path == 0) isPathValid = 0;
+ TRACE_COMM(MPI_Allreduce)(&isPathValid, &err, 1, MPI_INT, MPI_LAND, comm);
+ if (err == 0) DEBUG_RETURN_ERROR(NC_EINVAL)
+ }
+
+ /* When open an non-existing file for read, we can either call access() to
+ * check and return error code NC_ENOENT, or call MPI_File_open and expect
+ * error class MPI_ERR_NO_SUCH_FILE. For now, we let MPI-IO to check.
+ */
+#if 0 && defined(HAVE_ACCESS)
+ if (mpiomode == MPI_MODE_RDONLY) { /* file should already exit */
+ int rank, file_exist;
+ MPI_Comm_rank(comm, &rank);
+ if (rank == 0) {
+ if (access(path, F_OK) == 0) file_exist = 1;
+ else file_exist = 0;
+ }
+ TRACE_COMM(MPI_Bcast)(&file_exist, 1, MPI_INT, 0, comm);
+ if (!file_exist) DEBUG_RETURN_ERROR(NC_ENOENT)
+ }
+#endif
+
+ nciop = ncmpiio_new(path, ioflags);
+ if (nciop == NULL)
+ DEBUG_RETURN_ERROR(NC_ENOMEM)
+
+ nciop->mpiomode = mpiomode;
+ nciop->mpioflags = 0;
+
+ /* extract MPI-IO hints */
+ ncmpiio_extract_hints(nciop, info);
+
+ TRACE_IO(MPI_File_open)(comm, (char *)path, mpiomode,
+ info, &nciop->collective_fh);
+ if (mpireturn != MPI_SUCCESS) {
+ ncmpiio_free(nciop);
+ return ncmpii_handle_error(mpireturn, "MPI_File_open");
+ }
+
+ for (i=0; i<MAX_NC_ID && IDalloc[i] != 0; i++);
+ if (i == MAX_NC_ID) {
+ ncmpiio_free(nciop);
+ DEBUG_RETURN_ERROR(NC_ENFILE)
+ }
+ *((int *)&nciop->fd) = i;
+ IDalloc[i] = 1;
+
+ set_NC_collectiveFh(nciop);
+
+ /* duplicate communicator as user may free it later */
+ mpireturn = MPI_Comm_dup(comm, &(nciop->comm));
+ if (mpireturn != MPI_SUCCESS)
+ return ncmpii_handle_error(mpireturn, "MPI_Comm_dup");
+
+ /* get the file info used by MPI-IO */
+ MPI_File_get_info(nciop->collective_fh, &nciop->mpiinfo);
+
+ ncp->nciop = nciop;
+ return NC_NOERR;
+}
+
+/*----< ncmpiio_sync() >-----------------------------------------------------*/
+/* This function must be called collectively, no matter if it is in collective
+ * or independent data mode.
+ */
+inline int
+ncmpiio_sync(ncio *nciop) {
+#ifndef DISABLE_FILE_SYNC
+ int mpireturn;
+
+ if (NC_independentFhOpened(nciop)) {
+ TRACE_IO(MPI_File_sync)(nciop->independent_fh);
+ if (mpireturn != MPI_SUCCESS)
+ return ncmpii_handle_error(mpireturn, "MPI_File_sync");
+ }
+ if (NC_collectiveFhOpened(nciop)) {
+ TRACE_IO(MPI_File_sync)(nciop->collective_fh);
+ if (mpireturn != MPI_SUCCESS)
+ return ncmpii_handle_error(mpireturn, "MPI_File_sync");
+ }
+ TRACE_COMM(MPI_Barrier)(nciop->comm);
+#endif
+ return NC_NOERR;
+}
+
+/*----< ncmpiio_close() >----------------------------------------------------*/
+int
+ncmpiio_close(ncio *nciop, int doUnlink) {
+ int mpireturn;
+
+ if (nciop == NULL) /* this should never occur */
+ DEBUG_RETURN_ERROR(NC_EINVAL)
+
+ if (NC_independentFhOpened(nciop)) {
+ TRACE_IO(MPI_File_close)(&(nciop->independent_fh));
+ if (mpireturn != MPI_SUCCESS)
+ return ncmpii_handle_error(mpireturn, "MPI_File_close");
+ }
+
+ if (NC_collectiveFhOpened(nciop)) {
+ TRACE_IO(MPI_File_close)(&(nciop->collective_fh));
+ if (mpireturn != MPI_SUCCESS)
+ return ncmpii_handle_error(mpireturn, "MPI_File_close");
+ }
+ IDalloc[*((int *)&nciop->fd)] = 0;
+
+ if (doUnlink) {
+ TRACE_IO(MPI_File_delete)((char *)nciop->path, nciop->mpiinfo);
+ if (mpireturn != MPI_SUCCESS)
+ return ncmpii_handle_error(mpireturn, "MPI_File_delete");
+ }
+ ncmpiio_free(nciop);
+
+ return NC_NOERR;
+}
+
+/*----< ncmpiio_move() >-----------------------------------------------------*/
+int
+ncmpiio_move(ncio *const nciop,
+ MPI_Offset to,
+ MPI_Offset from,
+ MPI_Offset nbytes)
+{
+ int rank, nprocs, bufcount, mpireturn, err, status=NC_NOERR, min_st;
+ void *buf;
+ int chunk_size = 1048576; /* move 1 MB per process at a time */
+ MPI_Status mpistatus;
+
+ MPI_Comm_size(nciop->comm, &nprocs);
+ MPI_Comm_rank(nciop->comm, &rank);
+
+ /* if the file striping unit size is known (obtained from MPI-IO), then
+ * we use that instead of 1 MB */
+ if (nciop->striping_unit > 0) chunk_size = nciop->striping_unit;
+
+ buf = NCI_Malloc((size_t)chunk_size);
+ if (buf == NULL) DEBUG_RETURN_ERROR(NC_ENOMEM)
+
+ /* make fileview entire file visible */
+ TRACE_IO(MPI_File_set_view)(nciop->collective_fh, 0, MPI_BYTE, MPI_BYTE,
+ "native", MPI_INFO_NULL);
+
+ /* move the variable starting from its tail toward its beginning */
+ while (nbytes > 0) {
+ /* calculate how much to move at each time */
+ bufcount = chunk_size;
+ if (nbytes < nprocs * chunk_size) {
+ /* handle the last group of chunks */
+ MPI_Offset rem_chunks = nbytes / chunk_size;
+ if (rank > rem_chunks) /* these processes do not read/write */
+ bufcount = 0;
+ else if (rank == rem_chunks) /* this process reads/writes less */
+ bufcount = (int)(nbytes % chunk_size);
+ nbytes = 0;
+ }
+ else {
+ nbytes -= chunk_size*nprocs;
+ }
+
+ /* read the original data @ from+nbytes+rank*chunk_size */
+ TRACE_IO(MPI_File_read_at_all)(nciop->collective_fh,
+ from+nbytes+rank*chunk_size,
+ buf, bufcount, MPI_BYTE, &mpistatus);
+ if (mpireturn != MPI_SUCCESS) {
+ err = ncmpii_handle_error(mpireturn, "MPI_File_read_at_all");
+ if (err == NC_EFILE) DEBUG_ASSIGN_ERROR(status, NC_EREAD)
+ }
+ else {
+ int get_size;
+ MPI_Get_count(&mpistatus, MPI_BYTE, &get_size);
+ nciop->get_size += get_size;
+ }
+
+ /* MPI_Barrier(nciop->comm); */
+ /* important, in case new region overlaps old region */
+ TRACE_COMM(MPI_Allreduce)(&status, &min_st, 1, MPI_INT, MPI_MIN, nciop->comm);
+ status = min_st;
+ if (status != NC_NOERR) break;
+
+ /* write to new location @ to+nbytes+rank*chunk_size */
+ TRACE_IO(MPI_File_write_at_all)(nciop->collective_fh,
+ to+nbytes+rank*chunk_size,
+ buf, bufcount, MPI_BYTE, &mpistatus);
+ if (mpireturn != MPI_SUCCESS) {
+ err = ncmpii_handle_error(mpireturn, "MPI_File_write_at_all");
+ if (err == NC_EFILE) DEBUG_ASSIGN_ERROR(status, NC_EWRITE)
+ }
+ else {
+ int put_size;
+ MPI_Get_count(&mpistatus, MPI_BYTE, &put_size);
+ nciop->put_size += put_size;
+ }
+ TRACE_COMM(MPI_Allreduce)(&status, &min_st, 1, MPI_INT, MPI_MIN, nciop->comm);
+ status = min_st;
+ if (status != NC_NOERR) break;
+ }
+ NCI_Free(buf);
+ return status;
+}
+
+/*----< ncmpiio_move_fixed_vars() >-------------------------------------------*/
+/* move one fixed variable at a time, only when the new begin > old begin */
+int
+ncmpiio_move_fixed_vars(NC *ncp,
+ NC *old)
+{
+ int i, err, status=NC_NOERR;
+
+ /* move starting from the last fixed variable */
+ for (i=old->vars.ndefined-1; i>=0; i--) {
+ if (IS_RECVAR(old->vars.value[i])) continue;
+
+ MPI_Offset from = old->vars.value[i]->begin;
+ MPI_Offset to = ncp->vars.value[i]->begin;
+ if (to > from) {
+ err = ncmpiio_move(ncp->nciop, to, from, ncp->vars.value[i]->len);
+ if (status == NC_NOERR) status = err;
+ }
+ }
+ return status;
+}
+
+int ncmpiio_get_hint(NC *ncp, char *key, char *value, int *flag)
+{
+ MPI_Info info;
+
+ /* info hints can come from the file system but can also come from
+ * user-specified hints. the MPI implementation probably should
+ * merge the two, but some implementations not only ignore hints
+ * they don't understand, but also fail to incorporate those hints
+ * into the info struct (this is unfortunate for us, but entirely
+ * standards compliant).
+ *
+ * Our policy will be to use the implementation's info first
+ * (perhaps the implementation knows something about the underlying
+ * file system), and then consult user-supplied hints should we not
+ * find the hint in the info associated with the MPI file descriptor
+ */
+
+ /* first check the hint from the MPI library ... */
+ MPI_File_get_info(ncp->nciop->collective_fh, &info);
+ if (info != MPI_INFO_NULL)
+ MPI_Info_get(info, key, MPI_MAX_INFO_VAL-1, value, flag);
+ if (*flag == 0) {
+ /* ... then check the hint passed in through ncmpi_create */
+ if (ncp->nciop->mpiinfo != MPI_INFO_NULL) {
+ MPI_Info_get(ncp->nciop->mpiinfo, key,
+ MPI_MAX_INFO_VAL-1, value, flag);
+ }
+ }
+#ifdef HAVE_MPI_INFO_FREE
+ if (info != MPI_INFO_NULL)
+ MPI_Info_free(&info);
+#endif
+
+ return 0;
+}
+
+/*
+ * Local variables:
+ * c-indent-level: 4
+ * c-basic-offset: 4
+ * End:
+ *
+ * vim: ts=8 sts=4 sw=4 expandtab
+ */
diff --git a/src/lib/mpinetcdf.c b/src/lib/mpinetcdf.c
new file mode 100644
index 0000000..e0ac0f5
--- /dev/null
+++ b/src/lib/mpinetcdf.c
@@ -0,0 +1,1183 @@
+/*
+ * Copyright (C) 2003, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ */
+/* $Id: mpinetcdf.c 2282 2015-12-26 17:44:27Z wkliao $ */
+
+#if HAVE_CONFIG_H
+# include "ncconfig.h"
+#endif
+
+#include <stdio.h>
+#include <unistd.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#include <assert.h>
+#include <string.h> /* strtok(), strcpy(), strchr() */
+#include <strings.h> /* strcasecmp() */
+
+#include <mpi.h>
+
+#include "nc.h"
+#include "ncx.h"
+#include "macro.h"
+#ifdef ENABLE_SUBFILING
+#include "subfile.h"
+#endif
+
+/* The const string below is for the RCS ident(1) command to find a string like
+ * "\044Id: \100(#) PnetCDF library version 1.4.0 of 16 Nov 2013 $"
+ * in the library file (libpnetcdf.a).
+ */
+static char const pnetcdf_libvers[] =
+ "\044Id: \100(#) PnetCDF library version "PNETCDF_VERSION" of "PNETCDF_RELEASE_DATE" $";
+
+/* pnetcdf_libvers is slightly different from the one returned from
+ * ncmpi_inq_libvers(). The string pnetcdf_libvers is for command "ident" to
+ * use. People can run command ident libpnetcdf.a to obtain the version of a
+ * library (or an executable built from that library). In PnetCDF case, the
+ * command will print the string of pnetcdf_libvers. Command "ident' looks for
+ * a specific keyword pattern and print it. See man page of ident.
+ *
+ * The API ncmpi_inq_libvers() below on the other hand returns a string to be
+ * used by the utility tools like ncmpidump, ncmpigen, etc. Check the last line
+ * of output from command "ncmpidump -v".
+ */
+
+/*----< ncmpi_inq_libvers() >------------------------------------------------*/
+inline const char*
+ncmpi_inq_libvers(void) {
+
+ /* match the style used by netCDF API nc_inq_libvers()
+ * for example, "4.3.0 of Jun 16 2013 12:11:30 $" */
+ /* we need some silly operation so the compiler will emit the otherwise
+ * unused pnetcdf_libvers */
+ if ((void *)pnetcdf_libvers != (void *)ncmpi_inq_libvers) {
+ ; /* do nothing */
+ }
+ return PNETCDF_VERSION " of " PNETCDF_RELEASE_DATE;
+}
+
+/* Begin Of Dataset Functions */
+
+/*----< ncmpi_create() >-----------------------------------------------------*/
+/** \ingroup datasets
+Create a new netCDF file.
+
+This function creates a new netCDF dataset, returning a netCDF ID that can
+subsequently be used to refer to the netCDF dataset in other PnetCDF function
+calls. The new netCDF dataset opened for write access and placed in define
+mode, ready for you to add dimensions, variables, and attributes.
+
+\param comm The MPI communicator. This API is a collective routine: all
+processes must provide the same value for cmode, and all processes must provide
+filenames that reference the same file. (Values for info may vary.) comm must
+be an MPI intracommunicator.
+
+\param path The file name of the new netCDF dataset.
+
+\param cmode The creation mode flag. The following flags are available:
+NC_NOCLOBBER, NC_SHARE, NC_64BIT_OFFSET, and NC_64BIT_DATA.
+
+\param info MPI info object. It is used to provide file access hints,including
+existing MPI hints as well as PnetCDF hints. For MPI hints, users are referred
+to MPI user guide for further information. For PnetCDF hints see below.
+
+\param ncidp Pointer to location where returned netCDF ID is to be stored.
+
+<h2>The cmode Flag</h2>
+
+The cmode flag is used to control the type of file created, and some aspects of
+how it may be used.
+
+Setting NC_NOCLOBBER means you do not want to clobber (overwrite) an existing
+dataset; an error (NC_EEXIST) is returned if the specified dataset already
+exists.
+
+The NC_SHARE flag in PnetCDF does not mean sharing the file with the processes
+in this MPI program. Instead, it means the file will be concurrently shared
+by a different MPI program. Hence, PnetCDF calls MPI_File_sync() right after
+every time an MPI_File_write() call is made. This includes writing to metadata
+(file header) as well as array data.
+
+Setting NC_64BIT_OFFSET causes PnetCDF to create a 64-bit offset format file
+(CDF-2), instead of a netCDF classic format file. The 64-bit offset format
+imposes far fewer restrictions on large (i.e. over 2 GB) data files. See Large
+File Support (The PnetCDF Users Guide).
+
+Setting NC_64BIT_DATA causes PnetCDF to create a 64-bit data format file
+(CDF-5). The 64-bit data format allows define variables with more than 4
+billion array elements. See Large File Support (The PnetCDF Users Guide).
+
+A zero value (defined for convenience as NC_CLOBBER) specifies the default
+behavior: overwrite any existing dataset with the same file name.
+
+<h2>The info object Flag</h2>
+
+Starting from version 1.3.1, the following PnetCDF hints are available:
+
+- nc_header_align_size: This hint allows some extra space between the end of
+the header describing the entire file and the first variable. If you have an
+application that periodically wishes to add more variables to an already
+existing file, expanding the file header size may result in an expensive move
+of the entire data file to make room for the definition of the new variables.
+Hence, setting this hint to a value that is big enough to accommodate any
+additional variables means you may leave your application code as-is and yet
+still see tremendous performance improvements.
+
+- nc_var_align_size: If you are writing to a block-based parallel file system,
+such as IBM's GPFS or Lustre, then an application write becomes a block write
+at the file system layer. If a write straddles two blocks, then locks must be
+acquired for both blocks. Aligning the start of a variable to a block boundary,
+combined with collective I/O optimization in the MPI-IO library can often
+eliminate all unaligned file system accesses.
+
+- nc_record_align_size: This hint aligns the starting file offset of the
+record variable section.
+
+- nc_header_read_chunk_size: PnetCDF reads the file headers in chunks. This
+hint indicates the chunk size (in bytes). The default is 256 KB.
+
+\returns ::NC_NOERR No error.
+\returns ::NC_ENOMEM System out of memory.
+\returns ::NC_EEXIST Specified file name exists when using NC_NOCLOBBER.
+Can be use to check if the file exists.
+\returns ::NC_EMULTIDEFINE_OMODE Bad file create/open mode or modes are
+inconsistent across processes
+\returns ::NC_EOFILE: Can not open/create file (MPI-IO errors)
+\returns ::NC_EFILE: Unknown error in file operation
+
+<h1>Examples</h1>
+
+In this example we create a netCDF dataset named foo.nc; we want the dataset to
+be created in the current directory only if a dataset with that name does not
+already exist:
+
+ at code
+ #include <mpi.h>
+ #include <pnetcdf.h>
+ ...
+ int status;
+ int ncid;
+ MPI_Info info;
+ ...
+ MPI_Info_create (&info);
+ MPI_Info_set (info, "romio_no_indep_rw", "true");
+ MPI_Info_set (info, "nc_header_align_size", "4194304");
+ MPI_Info_set (info, "nc_var_align_size", "1048576");
+ MPI_Info_set (info, "nc_record_align_size", "1048576");
+
+ status = ncmpi_create(MPI_COMM_WORLD, "foo.nc", NC_NOCLOBBER, info, &ncid);
+ if (status != NC_NOERR) handle_error(status);
+ MPI_Info_free(&info);
+ at endcode
+
+In this example we create a netCDF dataset named foo.nc. It will
+be in the CDF-5 format.
+
+ at code
+ #include <mpi.h>
+ #include <pnetcdf.h>
+ ...
+ int status;
+ int ncid;
+ int cmode = NC_NOCLOBBER | NC_64BIT_DATA;
+ MPI_Info info = MPI_INFO_NULL;
+ ...
+ status = ncmpi_create(MPI_COMM_WORLD, "foo.nc", cmode, info, &ncid);
+ if (status != NC_NOERR) handle_error(status);
+ at endcode
+*/
+int
+ncmpi_create(MPI_Comm comm,
+ const char *path,
+ int cmode,
+ MPI_Info info,
+ int *ncidp)
+{
+ int flag, err, status=NC_NOERR, safe_mode=0, mpireturn;
+ char *env_str=NULL, *hint_str, value[MPI_MAX_INFO_VAL];
+ MPI_Info env_info;
+ MPI_Offset chunksize=NC_DEFAULT_CHUNKSIZE;
+ NC *ncp;
+
+#ifdef PNC_DEBUG
+ safe_mode = 1;
+ /* this configure time setting will be overwritten by the run-time
+ * environment variable PNETCDF_SAFE_MODE */
+#endif
+ /* get environment variable PNETCDF_SAFE_MODE
+ * if it is set to 1, then we perform a strict parameter consistent test
+ */
+ env_str = getenv("PNETCDF_SAFE_MODE");
+ if (env_str != NULL) {
+ if (*env_str == '0') safe_mode = 0;
+ else safe_mode = 1;
+ /* if PNETCDF_SAFE_MODE is set but without a value, *env_str can
+ * be '\0' (null character). In this case, safe_mode is enabled */
+ }
+
+ if (safe_mode) {
+ /* check if cmode is consistent with root's */
+ int root_cmode=cmode;
+
+ TRACE_COMM(MPI_Bcast)(&root_cmode, 1, MPI_INT, 0, comm);
+ if (mpireturn != MPI_SUCCESS)
+ return ncmpii_handle_error(mpireturn, "MPI_Bcast");
+
+ if (root_cmode != cmode) {
+ int rank;
+ MPI_Comm_rank(comm, &rank);
+ /* cmodes are inconsistent, overwrite local cmode with root's */
+ printf("rank %d: Warning - inconsistent file create mode, overwrite with root's\n",rank);
+ cmode = root_cmode;
+ DEBUG_ASSIGN_ERROR(status, NC_EMULTIDEFINE_OMODE)
+ }
+ TRACE_COMM(MPI_Allreduce)(&status, &err, 1, MPI_INT, MPI_MIN, comm);
+ if (err != NC_NOERR) return status;
+
+ /* when safe_mode is disabled, NC_EMULTIDEFINE_OMODE will be reported at
+ * the time ncmpi_enddef() returns */
+ }
+
+ /* It is illegal to have both NC_64BIT_OFFSET & NC_64BIT_DATA */
+ if ((cmode & (NC_64BIT_OFFSET|NC_64BIT_DATA)) ==
+ (NC_64BIT_OFFSET|NC_64BIT_DATA))
+ DEBUG_ASSIGN_ERROR(status, NC_EINVAL_CMODE)
+ /* In safe_mode, cmodes are sync-ed, so all processes can return the same
+ * error code. But, when not in safe mode, if cmode is not consistent
+ * among processes, then some processes might not violate this above rule
+ * which can cause the program to hang (because MPI_File_open is a
+ * collective call). We use MPI_Allreduce below to check the error
+ * code, but it is costly.
+ */
+ if (safe_mode) {
+ TRACE_COMM(MPI_Allreduce)(&status, &err, 1, MPI_INT, MPI_MIN, comm);
+ status = err;
+ }
+ if (status != NC_NOERR) return status;
+
+ /* take hints from the environment variable PNETCDF_HINTS
+ * a string of hints separated by ";" and each hint is in the
+ * form of hint=value. E.g. cb_nodes=16;cb_config_list=*:6
+ * If this environment variable is set, it overrides any values that
+ * were set by using calls to MPI_Info_set in the application code.
+ */
+ env_str = getenv("PNETCDF_HINTS");
+ env_info = info;
+ if (env_str != NULL) {
+ if (info == MPI_INFO_NULL)
+ MPI_Info_create(&env_info); /* ignore error */
+
+ hint_str = strtok(env_str, ";");
+ while (hint_str != NULL && env_info != MPI_INFO_NULL) {
+ char key[128], *val;
+ strcpy(key, hint_str);
+ val = strchr(key, '=');
+ *val = '\0';
+ val++;
+ /* printf("env hint: key=%s val=%s\n",key,val); */
+ MPI_Info_set(env_info, key, val); /* override */
+ hint_str = strtok(NULL, ";");
+ }
+ }
+
+ /* get header chunk size from user info */
+ if (env_info != MPI_INFO_NULL) {
+ MPI_Info_get(env_info, "nc_header_read_chunk_size", MPI_MAX_INFO_VAL-1,
+ value, &flag);
+ if (flag) chunksize = atoll(value);
+ }
+
+ /* allocate buffer for header object NC */
+ if ((ncp = ncmpii_new_NC(&chunksize)) == NULL)
+ DEBUG_RETURN_ERROR(NC_ENOMEM)
+
+ ncp->safe_mode = safe_mode;
+ ncp->abuf = NULL;
+ ncp->old = NULL;
+#ifdef ENABLE_SUBFILING
+ ncp->subfile_mode = 1;
+ if (env_info != MPI_INFO_NULL) {
+ MPI_Info_get(env_info, "pnetcdf_subfiling", MPI_MAX_INFO_VAL-1,
+ value, &flag);
+ if (flag && strcasecmp(value, "disable") == 0)
+ ncp->subfile_mode = 0;
+ }
+ ncp->ncid_sf = -1; /* subfile ncid; init to -1 */
+ ncp->nc_num_subfiles = 0; /* num_subfiles; init to 0 */
+#endif
+ assert(ncp->flags == 0);
+
+ /* set the file format version based on the create mode, cmode */
+ if (fIsSet(cmode, NC_64BIT_DATA)) {
+ if (SIZEOF_MPI_OFFSET < 8) DEBUG_RETURN_ERROR(NC_ESMALL)
+ fSet(ncp->flags, NC_64BIT_DATA);
+ } else if (fIsSet(cmode, NC_64BIT_OFFSET)) {
+ /* unlike serial netcdf, we will not bother to support
+ * NC_64BIT_OFFSET on systems with off_t smaller than 8 bytes.
+ * serial netcdf has proven it's possible if datasets are small, but
+ * that's a hassle we don't want to worry about */
+ if (SIZEOF_OFF_T < 8) DEBUG_RETURN_ERROR(NC_ESMALL)
+ fSet(ncp->flags, NC_64BIT_OFFSET);
+ } else {
+ /* check default format */
+ int default_format;
+ ncmpi_inq_default_format(&default_format);
+ if (default_format == NC_FORMAT_CDF5) {
+ if (SIZEOF_MPI_OFFSET < 8) DEBUG_RETURN_ERROR(NC_ESMALL)
+ fSet(ncp->flags, NC_64BIT_DATA);
+ }
+ else if (default_format == NC_FORMAT_CDF2) {
+ if (SIZEOF_OFF_T < 8) DEBUG_RETURN_ERROR(NC_ESMALL)
+ fSet(ncp->flags, NC_64BIT_OFFSET);
+ }
+ else
+ fSet(ncp->flags, NC_32BIT);
+ }
+
+ /* find the true header size (not-yet aligned) */
+ ncp->xsz = ncmpii_hdr_len_NC(ncp);
+
+ fSet(ncp->flags, NC_NOFILL);
+
+ err = ncmpiio_create(comm, path, cmode, env_info, ncp);
+ if (err != NC_NOERR) { /* fatal error */
+ ncmpii_free_NC(ncp);
+ return err;
+ }
+
+ fSet(ncp->flags, NC_CREAT);
+
+ /* the linked list storing the outstanding non-blocking requests */
+ ncp->head = NULL;
+ ncp->tail = NULL;
+
+ /* add to the linked list of opened files */
+ ncmpii_add_to_NCList(ncp);
+ *ncidp = ncp->nciop->fd;
+
+ if (env_info != info) MPI_Info_free(&env_info);
+
+ return status;
+}
+
+/*----< ncmpi_open() >-------------------------------------------------------*/
+int
+ncmpi_open(MPI_Comm comm,
+ const char *path,
+ int omode,
+ MPI_Info info,
+ int *ncidp)
+{
+ int i, flag, err, status=NC_NOERR, safe_mode=0, mpireturn;
+ char *env_str=NULL, *hint_str, value[MPI_MAX_INFO_VAL];
+ MPI_Info env_info;
+ MPI_Offset chunksize=NC_DEFAULT_CHUNKSIZE;
+ NC *ncp;
+
+#ifdef PNC_DEBUG
+ safe_mode = 1;
+ /* this configure time setting will be overwritten by the run-time
+ * environment variable PNETCDF_SAFE_MODE */
+#endif
+ /* get environment variable PNETCDF_SAFE_MODE
+ * if it is set to 1, then we perform a strict parameter consistent test
+ */
+ env_str = getenv("PNETCDF_SAFE_MODE");
+ if (env_str != NULL) {
+ if (*env_str == '0') safe_mode = 0;
+ else safe_mode = 1;
+ /* if PNETCDF_SAFE_MODE is set but without a value, *env_str can
+ * be '\0' (null character). In this case, safe_mode is enabled */
+ }
+
+ if (safe_mode) {
+ /* check if omode is consistent with root's */
+ int root_omode=omode;
+
+ /* Note if omode contains NC_NOWRITE, it is equivalent to NC_CLOBBER.
+ In pnetcdf.h, they both are defined the same value, 0.
+ */
+
+ TRACE_COMM(MPI_Bcast)(&root_omode, 1, MPI_INT, 0, comm);
+ if (mpireturn != MPI_SUCCESS)
+ return ncmpii_handle_error(mpireturn, "MPI_Bcast");
+
+ if (root_omode != omode) {
+ int rank;
+ MPI_Comm_rank(comm, &rank);
+ /* omodes are inconsistent, overwrite local omode with root's */
+ printf("rank %d: Warning - inconsistent file open mode, overwrite with root's\n",rank);
+ omode = root_omode;
+ DEBUG_ASSIGN_ERROR(status, NC_EMULTIDEFINE_OMODE)
+ }
+ }
+
+ /* take hints from the environment variable PNETCDF_HINTS
+ * a string of hints separated by ";" and each hint is in the
+ * form of hint=value. E.g. cb_nodes=16;cb_config_list=*:6
+ * If this environment variable is set, it overrides any values that
+ * were set by using calls to MPI_Info_set in the application code.
+ */
+ env_str = getenv("PNETCDF_HINTS");
+ env_info = info;
+ if (env_str != NULL) {
+ if (info == MPI_INFO_NULL)
+ MPI_Info_create(&env_info); /* ignore error */
+
+ hint_str = strtok(env_str, ";");
+ while (hint_str != NULL && env_info != MPI_INFO_NULL) {
+ char key[128], *val;
+ strcpy(key, hint_str);
+ val = strchr(key, '=');
+ *val = '\0';
+ val++;
+ /* printf("env hint: key=%s val=%s\n",key,val); */
+ MPI_Info_set(env_info, key, val); /* override */
+ hint_str = strtok(NULL, ";");
+ }
+ }
+
+ /* get header chunk size from user info, if provided */
+ if (env_info != MPI_INFO_NULL) {
+ MPI_Info_get(env_info, "nc_header_read_chunk_size", MPI_MAX_INFO_VAL-1,
+ value, &flag);
+ if (flag) chunksize = atoll(value);
+ }
+
+ ncp = ncmpii_new_NC(&chunksize);
+ if (ncp == NULL)
+ DEBUG_RETURN_ERROR(NC_ENOMEM)
+
+ ncp->safe_mode = safe_mode;
+ ncp->old = NULL;
+#ifdef ENABLE_SUBFILING
+ ncp->subfile_mode = 1;
+ if (env_info != MPI_INFO_NULL) {
+ MPI_Info_get(env_info, "pnetcdf_subfiling", MPI_MAX_INFO_VAL-1,
+ value, &flag);
+ if (flag && strcasecmp(value, "disable") == 0)
+ ncp->subfile_mode = 0;
+ }
+ ncp->ncid_sf = -1;
+ ncp->nc_num_subfiles = 0;
+#endif
+
+ err = ncmpiio_open(comm, path, omode, env_info, ncp);
+ if (err != NC_NOERR) { /* fatal error */
+ ncmpii_free_NC(ncp);
+ return err;
+ }
+
+ assert(ncp->flags == 0);
+ fSet(ncp->flags, NC_NOFILL);
+
+ err = ncmpii_hdr_get_NC(ncp); /* read header from file */
+ if (err != NC_NOERR) { /* fatal error */
+ ncmpiio_close(ncp->nciop, 0);
+ ncmpii_free_NC(ncp);
+ return err;
+ }
+ ncp->head = NULL;
+ ncp->tail = NULL;
+
+ ncmpii_add_to_NCList(ncp);
+ *ncidp = ncp->nciop->fd;
+
+#ifdef ENABLE_SUBFILING
+ if (ncp->subfile_mode) {
+ /* check attr for subfiles */
+ err = ncmpi_get_att_int(ncp->nciop->fd, NC_GLOBAL, "num_subfiles",
+ &ncp->nc_num_subfiles);
+ if (err == NC_NOERR && ncp->nc_num_subfiles > 1) {
+ /* ignore error NC_ENOTATT if this attribute is not defined */
+ int nvars;
+
+ err = ncmpi_inq_nvars(ncp->nciop->fd, &nvars);
+ if (status == NC_NOERR) status = err;
+
+ for (i=0; i<nvars; i++) {
+ err = ncmpi_get_att_int(ncp->nciop->fd, i, "num_subfiles",
+ &ncp->vars.value[i]->num_subfiles);
+ if (err == NC_ENOTATT) continue;
+ if (err != NC_NOERR && status == NC_NOERR) { /* other error */
+ status = err;
+ continue;
+ }
+
+ if (ncp->vars.value[i]->num_subfiles > 1) {
+ err = ncmpi_get_att_int(ncp->nciop->fd, i, "ndims_org",
+ &ncp->vars.value[i]->ndims_org);
+ if (status == NC_NOERR) status = err;
+ }
+ }
+
+ if (ncp->nc_num_subfiles > 1) {
+ err = ncmpii_subfile_open(ncp, &ncp->ncid_sf);
+ if (status == NC_NOERR) status = err;
+ }
+ }
+ }
+ else
+ ncp->nc_num_subfiles = 0;
+#endif
+
+ if (env_info != info) MPI_Info_free(&env_info);
+
+ /* update the total number of record variables */
+ ncp->vars.num_rec_vars = 0;
+ for (i=0; i<ncp->vars.ndefined; i++)
+ ncp->vars.num_rec_vars += IS_RECVAR(ncp->vars.value[i]);
+
+ return status;
+}
+
+/*----< ncmpi_inq_format() >-------------------------------------------------*/
+int
+ncmpi_inq_format(int ncid,
+ int *formatp) /* out */
+{
+ int status;
+ NC *ncp;
+
+ status = ncmpii_NC_check_id(ncid, &ncp);
+ if (status != NC_NOERR)
+ return status;
+
+ if (fIsSet(ncp->flags, NC_64BIT_DATA)) {
+ *formatp = NC_FORMAT_CDF5;
+ } else if (fIsSet(ncp->flags, NC_64BIT_OFFSET)) {
+ *formatp = NC_FORMAT_CDF2;
+ } else if (fIsSet(ncp->flags, NC_32BIT)){
+ *formatp = NC_FORMAT_CLASSIC;
+ } else {
+ /* this should not happen, because if ncid is valid, checking for
+ * valid CDF format should have already been done already */
+ *formatp = NC_FORMAT_UNKNOWN;
+ }
+ return status;
+}
+
+/*----< ncmpi_inq_file_format() >--------------------------------------------*/
+int
+ncmpi_inq_file_format(char *filename,
+ int *formatp) /* out */
+{
+ int ncid, status;
+ NC *ncp;
+
+ /* open file for reading its header */
+ status = ncmpi_open(MPI_COMM_SELF, filename, NC_NOWRITE, MPI_INFO_NULL,
+ &ncid);
+ if (status == NC_ENOTNC)
+ DEBUG_ASSIGN_ERROR(*formatp, NC_FORMAT_UNKNOWN)
+ if (status != NC_NOERR)
+ return status;
+
+ status = ncmpii_NC_check_id(ncid, &ncp);
+ if (status != NC_NOERR)
+ return status;
+
+ if (fIsSet(ncp->flags, NC_64BIT_DATA)) {
+ *formatp = NC_FORMAT_CDF5;
+ } else if (fIsSet(ncp->flags, NC_64BIT_OFFSET)) {
+ *formatp = NC_FORMAT_CDF2;
+ } else if (fIsSet(ncp->flags, NC_32BIT)){
+ *formatp = NC_FORMAT_CLASSIC;
+ } else {
+ /* this should not happen, because if ncid is valid, checking for
+ * valid CDF format should have already been done already */
+ *formatp = NC_FORMAT_UNKNOWN;
+ }
+ status = ncmpi_close(ncid);
+
+ return status;
+}
+
+/*----< ncmpi_inq_file_info() >-----------------------------------------------*/
+int
+ncmpi_inq_file_info(int ncid,
+ MPI_Info *info_used)
+{
+ int mpireturn, status=NC_NOERR;
+ char value[MPI_MAX_INFO_VAL];
+ NC *ncp;
+
+ status = ncmpii_NC_check_id(ncid, &ncp);
+ if (status != NC_NOERR)
+ return status;
+
+#ifdef HAVE_MPI_INFO_DUP
+ mpireturn = MPI_Info_dup(ncp->nciop->mpiinfo, info_used);
+ if (mpireturn != MPI_SUCCESS)
+ return ncmpii_handle_error(mpireturn, "MPI_Info_dup");
+#else
+ mpireturn = MPI_File_get_info(ncp->nciop->collective_fh, info_used);
+ if (mpireturn != MPI_SUCCESS)
+ return ncmpii_handle_error(mpireturn, "MPI_File_get_info");
+#endif
+
+ sprintf(value, "%lld", ncp->nciop->hints.h_align);
+ MPI_Info_set(*info_used, "nc_header_align_size", value);
+
+ sprintf(value, "%lld", ncp->nciop->hints.v_align);
+ MPI_Info_set(*info_used, "nc_var_align_size", value);
+
+ sprintf(value, "%lld", ncp->nciop->hints.r_align);
+ MPI_Info_set(*info_used, "nc_record_align_size", value);
+
+ sprintf(value, "%lld", ncp->nciop->hints.header_read_chunk_size);
+ MPI_Info_set(*info_used, "nc_header_read_chunk_size", value);
+
+#ifdef ENABLE_SUBFILING
+ sprintf(value, "%d", ncp->nciop->hints.subfile_mode);
+ MPI_Info_set(*info_used, "pnetcdf_subfiling", value);
+ sprintf(value, "%d", ncp->nciop->hints.num_subfiles);
+ MPI_Info_set(*info_used, "nc_num_subfiles", value);
+#endif
+
+ return NC_NOERR;
+}
+
+/*----< ncmpi_get_file_info() >-----------------------------------------------*/
+int
+ncmpi_get_file_info(int ncid,
+ MPI_Info *info_used)
+{
+ return ncmpi_inq_file_info(ncid, info_used);
+}
+
+/*----< ncmpi_redef() >------------------------------------------------------*/
+int
+ncmpi_redef(int ncid) {
+ int status;
+ NC *ncp;
+
+ status = ncmpii_NC_check_id(ncid, &ncp);
+ if (status != NC_NOERR)
+ return status;
+
+ if (NC_readonly(ncp)) DEBUG_RETURN_ERROR(NC_EPERM) /* read-only */
+ /* if open mode is inconsistent, then this return might cause parallel
+ * program to hang */
+
+ /* cannot be in define mode */
+ if (NC_indef(ncp)) DEBUG_RETURN_ERROR(NC_EINDEFINE)
+
+ /* sync all metadata, including numrecs, if changed in independent mode.
+ * also ensure exiting define mode always entering collective data mode
+ */
+ if (NC_indep(ncp))
+ ncmpii_end_indep_data(ncp);
+
+ if (NC_doFsync(ncp)) { /* re-read the header from file */
+ status = ncmpii_read_NC(ncp);
+ if (status != NC_NOERR) return status;
+ }
+
+ /* duplicate a header to be uses in enddef() for checking if header grows */
+ ncp->old = ncmpii_dup_NC(ncp);
+ if (ncp->old == NULL) DEBUG_RETURN_ERROR(NC_ENOMEM)
+
+ /* we are now entering define mode */
+ fSet(ncp->flags, NC_INDEF);
+
+ return NC_NOERR;
+}
+
+/*----< ncmpi_begin_indep_data() >-------------------------------------------*/
+int
+ncmpi_begin_indep_data(int ncid)
+{
+ int status=NC_NOERR;
+ NC *ncp;
+
+ status = ncmpii_NC_check_id(ncid, &ncp);
+ if (status != NC_NOERR) return status;
+
+ if (NC_indef(ncp)) /* must not be in define mode */
+ DEBUG_RETURN_ERROR(NC_EINDEFINE)
+
+ if (NC_indep(ncp)) /* already in indep data mode */
+ return NC_NOERR;
+
+ /* we need no MPI_File_sync() here. If users want a stronger data
+ * consistency, they can either use NC_SHARE or call ncmpi_sync()
+ */
+#if 0 && !defined(DISABLE_FILE_SYNC)
+ if (!NC_readonly(ncp) && NC_collectiveFhOpened(ncp->nciop)) {
+ /* calling file sync for those already open the file */
+ int err, mpireturn;
+ /* MPI_File_sync() is collective */
+ TRACE_IO(MPI_File_sync)(ncp->nciop->collective_fh);
+ if (mpireturn != MPI_SUCCESS) {
+ err = ncmpii_handle_error(mpireturn, "MPI_File_sync");
+ if (status == NC_NOERR) status = err;
+ }
+ TRACE_COMM(MPI_Barrier)(ncp->nciop->comm);
+ }
+#endif
+
+ fSet(ncp->flags, NC_INDEP);
+
+ status = ncmpii_check_mpifh(ncp, 0);
+
+ return status;
+}
+
+/*----< ncmpi_end_indep_data() >---------------------------------------------*/
+int
+ncmpi_end_indep_data(int ncid) {
+ int status;
+ NC *ncp;
+
+ status = ncmpii_NC_check_id(ncid, &ncp);
+ if (status != NC_NOERR) return status;
+
+ if (!NC_indep(ncp)) /* must be in independent data mode */
+ DEBUG_RETURN_ERROR(NC_ENOTINDEP)
+
+ return ncmpii_end_indep_data(ncp);
+}
+
+/*----< ncmpii_end_indep_data() >--------------------------------------------*/
+/* this function is called when:
+ * 1. ncmpi_end_indep_data()
+ * 2. ncmpi_redef() from independent data mode entering to define more
+ * 3. ncmpii_close() when closing the file
+ * This function is collective.
+ */
+int
+ncmpii_end_indep_data(NC *ncp)
+{
+ int status=NC_NOERR;
+
+ if (!NC_readonly(ncp)) {
+ if (ncp->vars.num_rec_vars > 0) {
+ /* numrecs dirty bit may not be the same across all processes.
+ * force sync in memory no matter if dirty or not.
+ */
+ set_NC_ndirty(ncp);
+ status = ncmpii_sync_numrecs(ncp, ncp->numrecs);
+ /* the only possible dirty part of the header is numrecs */
+ }
+
+#ifndef DISABLE_FILE_SYNC
+ /* calling file sync for those already open the file */
+ if (NC_doFsync(ncp) && NC_independentFhOpened(ncp->nciop)) {
+ int mpireturn;
+ /* MPI_File_sync() is collective */
+ TRACE_IO(MPI_File_sync)(ncp->nciop->independent_fh);
+ if (mpireturn != MPI_SUCCESS) {
+ int err = ncmpii_handle_error(mpireturn, "MPI_File_sync");
+ if (status == NC_NOERR) status = err;
+ }
+ TRACE_COMM(MPI_Barrier)(ncp->nciop->comm);
+ }
+#endif
+ }
+
+ fClr(ncp->flags, NC_INDEP);
+
+ return status;
+}
+
+/*----< ncmpi_enddef() >-----------------------------------------------------*/
+int
+ncmpi_enddef(int ncid) {
+ int status;
+ NC *ncp;
+
+ /* check if file ID ncid is valid */
+ status = ncmpii_NC_check_id(ncid, &ncp);
+ if (status != NC_NOERR) return status;
+
+ if (!NC_indef(ncp)) /* must currently in define mode */
+ DEBUG_RETURN_ERROR(NC_ENOTINDEFINE)
+
+ return ncmpii_enddef(ncp);
+}
+
+/*----< ncmpi__enddef() >-----------------------------------------------------*/
+int
+ncmpi__enddef(int ncid,
+ MPI_Offset h_minfree,
+ MPI_Offset v_align,
+ MPI_Offset v_minfree,
+ MPI_Offset r_align)
+{
+ int status;
+ NC *ncp;
+
+ /* check if file ID ncid is valid */
+ status = ncmpii_NC_check_id(ncid, &ncp);
+ if (status != NC_NOERR) return status;
+
+ if (!NC_indef(ncp)) /* must currently in define mode */
+ DEBUG_RETURN_ERROR(NC_ENOTINDEFINE)
+
+ return ncmpii__enddef(ncp, h_minfree, v_align, v_minfree, r_align);
+}
+
+/*----< ncmpi_sync_numrecs() >------------------------------------------------*/
+/* this API is collective, but can be called in independent data mode.
+ * Note numrecs is always sync-ed in memory and update in file in collective
+ * data mode.
+ */
+int
+ncmpi_sync_numrecs(int ncid) {
+ int status = NC_NOERR;
+ NC *ncp;
+
+ status = ncmpii_NC_check_id(ncid, &ncp);
+ if (status != NC_NOERR) return status;
+
+ /* cannot be in define mode */
+ if (NC_indef(ncp)) DEBUG_RETURN_ERROR(NC_EINDEFINE)
+
+ /* check if we have defined record variables */
+ if (ncp->vars.num_rec_vars == 0) return NC_NOERR;
+
+ if (!NC_indep(ncp)) /* in collective data mode, numrecs is always sync-ed */
+ return NC_NOERR;
+ else /* if called in independent mode, we force sync in memory */
+ set_NC_ndirty(ncp);
+
+ /* sync numrecs in memory and file */
+ status = ncmpii_sync_numrecs(ncp, ncp->numrecs);
+
+#ifndef DISABLE_FILE_SYNC
+ if (NC_doFsync(ncp)) { /* NC_SHARE is set */
+ int err, mpireturn;
+ if (NC_indep(ncp)) {
+ TRACE_IO(MPI_File_sync)(ncp->nciop->independent_fh);
+ }
+ else {
+ TRACE_IO(MPI_File_sync)(ncp->nciop->collective_fh);
+ }
+ if (mpireturn != MPI_SUCCESS) {
+ err = ncmpii_handle_error(mpireturn, "MPI_File_sync");
+ if (status == NC_NOERR) status = err;
+ }
+ TRACE_COMM(MPI_Barrier)(ncp->nciop->comm);
+ }
+#endif
+ return status;
+}
+
+/*----< ncmpi_sync() >--------------------------------------------------------*/
+/* This API must be called collectively, no matter if it is in collective
+ * or independent data mode.
+ */
+int
+ncmpi_sync(int ncid) {
+ int status = NC_NOERR;
+ NC *ncp;
+
+ status = ncmpii_NC_check_id(ncid, &ncp);
+ if (status != NC_NOERR) return status;
+
+ if (NC_indef(ncp)) DEBUG_RETURN_ERROR(NC_EINDEFINE)
+
+ if (NC_readonly(ncp))
+ /* calling sync for file opened for read only means re-read header */
+ return ncmpii_read_NC(ncp);
+
+ /* the only part of header that can be dirty is numrecs (caused only by
+ * independent APIs) */
+ if (ncp->vars.num_rec_vars > 0 && NC_indep(ncp)) {
+ /* sync numrecs in memory among processes and in file */
+ set_NC_ndirty(ncp);
+ status = ncmpii_sync_numrecs(ncp, ncp->numrecs);
+ if (status != NC_NOERR) return status;
+ }
+
+ /* calling MPI_File_sync() on both collective and independent handlers */
+ return ncmpiio_sync(ncp->nciop);
+}
+
+/*----< ncmpi_abort() >------------------------------------------------------*/
+int
+ncmpi_abort(int ncid) {
+ /*
+ * In data mode, same as ncmpiio_close.
+ * In define mode, descard new definition.
+ * In create, remove the file.
+ */
+ int status, err, doUnlink = 0;
+ NC *ncp;
+
+ status = ncmpii_NC_check_id(ncid, &ncp);
+ if (status != NC_NOERR) return status;
+
+ /* delete the file if it is newly created by ncmpi_create() */
+ doUnlink = NC_IsNew(ncp);
+
+ if (ncp->old != NULL) {
+ /* a plain redef, not a create */
+ assert(!NC_IsNew(ncp));
+ assert(fIsSet(ncp->flags, NC_INDEF));
+ ncmpii_free_NC(ncp->old);
+ ncp->old = NULL;
+ fClr(ncp->flags, NC_INDEF);
+ }
+
+ if (!doUnlink) {
+ if (!NC_readonly(ncp) && /* file is open for write */
+ NC_indep(ncp)) { /* in independent data mode */
+ status = ncmpii_end_indep_data(ncp); /* sync header */
+ }
+
+ if (NC_doFsync(ncp)) {
+ err = ncmpiio_sync(ncp->nciop); /* calling MPI_File_sync() */
+ if (status == NC_NOERR ) status = err;
+ }
+ }
+
+ /* close the file */
+ err = ncmpiio_close(ncp->nciop, doUnlink);
+ if (status == NC_NOERR ) status = err;
+
+ ncp->nciop = NULL;
+
+ /* remove this file from the list of opened files */
+ ncmpii_del_from_NCList(ncp);
+
+ /* free up space occupied by the header metadata */
+ ncmpii_free_NC(ncp);
+
+ return status;
+}
+
+/*----< ncmpi_close() >------------------------------------------------------*/
+int
+ncmpi_close(int ncid) {
+ int status = NC_NOERR;
+ NC *ncp;
+
+ status = ncmpii_NC_check_id(ncid, &ncp);
+ if (status != NC_NOERR)
+ return status;
+
+ /* calling the implementation of ncmpi_close() */
+ return ncmpii_close(ncp);
+}
+
+/*----< ncmpi_delete() >-----------------------------------------------------*/
+/* ncmpi_delete:
+ * doesn't do anything to release resources, so call ncmpi_close before calling
+ * this function.
+ *
+ * filename: the name of the
+ * file we will remove. info: mpi info, in case underlying file system needs
+ * hints.
+ */
+int
+ncmpi_delete(char *filename,
+ MPI_Info info)
+{
+ int err=NC_NOERR, mpireturn;
+
+ TRACE_IO(MPI_File_delete)(filename, info);
+ if (mpireturn != MPI_SUCCESS)
+ err = ncmpii_handle_error(mpireturn, "MPI_File_delete");
+ return err;
+}
+
+/* End Of Dataset Functions */
+
+/*----< ncmpii_check_mpifh() >-----------------------------------------------*/
+int
+ncmpii_check_mpifh(NC *ncp,
+ int collective)
+{
+ int mpireturn;
+
+ if (collective && NC_indep(ncp)) /* collective handle but in indep mode */
+ DEBUG_RETURN_ERROR(NC_EINDEP)
+
+ if (!collective && !NC_indep(ncp)) /* indep handle but in collective mode */
+ DEBUG_RETURN_ERROR(NC_ENOTINDEP)
+
+ if (collective && !NC_collectiveFhOpened(ncp->nciop)) {
+ TRACE_IO(MPI_File_open)(ncp->nciop->comm, (char*)ncp->nciop->path,
+ ncp->nciop->mpiomode, ncp->nciop->mpiinfo,
+ &ncp->nciop->collective_fh);
+ if (mpireturn != MPI_SUCCESS)
+ return ncmpii_handle_error(mpireturn, "MPI_File_open");
+
+ set_NC_collectiveFh(ncp->nciop);
+ }
+ else if (!collective && !NC_independentFhOpened(ncp->nciop)) {
+ TRACE_IO(MPI_File_open)(MPI_COMM_SELF, (char*)ncp->nciop->path,
+ ncp->nciop->mpiomode, ncp->nciop->mpiinfo,
+ &ncp->nciop->independent_fh);
+ if (mpireturn != MPI_SUCCESS)
+ return ncmpii_handle_error(mpireturn, "MPI_File_open");
+
+ set_NC_independentFh(ncp->nciop);
+ }
+
+ return NC_NOERR;
+}
+
+/*----< ncmpi_inq_put_size() >------------------------------------------------*/
+/* returns the amount of writes, in bytes, committed to file system so far */
+int
+ncmpi_inq_put_size(int ncid,
+ MPI_Offset *size)
+{
+ int status;
+ NC *ncp;
+
+ status = ncmpii_NC_check_id(ncid, &ncp);
+ if (status != NC_NOERR)
+ return status;
+
+ *size = ncp->nciop->put_size;
+ return NC_NOERR;
+}
+
+/*----< ncmpi_inq_get_size() >------------------------------------------------*/
+/* returns the amount of reads, in bytes, obtained from file system so far */
+int
+ncmpi_inq_get_size(int ncid,
+ MPI_Offset *size)
+{
+ int status;
+ NC *ncp;
+
+ status = ncmpii_NC_check_id(ncid, &ncp);
+ if (status != NC_NOERR)
+ return status;
+
+ *size = ncp->nciop->get_size;
+ return NC_NOERR;
+}
+
+/*----< ncmpi_inq_striping() >------------------------------------------------*/
+/* return file (system) striping settings, striping size and count, if they are
+ * available from MPI-IO hint. Otherwise, 0s are returned.
+ */
+int
+ncmpi_inq_striping(int ncid,
+ int *striping_size,
+ int *striping_count)
+{
+ int flag, status=NC_NOERR;
+ char value[MPI_MAX_INFO_VAL];
+ NC *ncp;
+
+ status = ncmpii_NC_check_id(ncid, &ncp);
+ if (status != NC_NOERR)
+ return status;
+
+ if (striping_size != NULL) {
+ MPI_Info_get(ncp->nciop->mpiinfo, "striping_unit", MPI_MAX_INFO_VAL-1,
+ value, &flag);
+ *striping_size = 0;
+ if (flag) *striping_size = atoi(value);
+ }
+
+ if (striping_count != NULL) {
+ MPI_Info_get(ncp->nciop->mpiinfo, "striping_factor", MPI_MAX_INFO_VAL-1,
+ value, &flag);
+ *striping_count = 0;
+ if (flag) *striping_count = atoi(value);
+ }
+ return NC_NOERR;
+}
+
+/*----< ncmpi_inq_malloc_size() >--------------------------------------------*/
+/* report the current aggregate size allocated by malloc, yet to be freed */
+int ncmpi_inq_malloc_size(MPI_Offset *size)
+{
+#ifdef PNC_MALLOC_TRACE
+ ncmpii_inq_malloc_size(size);
+ return NC_NOERR;
+#else
+ DEBUG_RETURN_ERROR(NC_ENOTENABLED)
+#endif
+}
+
+/*----< ncmpi_inq_malloc_max_size() >----------------------------------------*/
+/* get the max watermark ever researched by malloc (aggregated amount) */
+int ncmpi_inq_malloc_max_size(MPI_Offset *size)
+{
+#ifdef PNC_MALLOC_TRACE
+ ncmpii_inq_malloc_max_size(size);
+ return NC_NOERR;
+#else
+ DEBUG_RETURN_ERROR(NC_ENOTENABLED)
+#endif
+}
+
+/*----< ncmpi_inq_malloc_list() >--------------------------------------------*/
+/* walk the malloc tree and print yet-to-be-freed malloc residues */
+int ncmpi_inq_malloc_list(void)
+{
+#ifdef PNC_MALLOC_TRACE
+ ncmpii_inq_malloc_list();
+ return NC_NOERR;
+#else
+ DEBUG_RETURN_ERROR(NC_ENOTENABLED)
+#endif
+}
+
+/*----< ncmpi_inq_files_opened() >-------------------------------------------*/
+int
+ncmpi_inq_files_opened(int *num, int *ncids)
+{
+ return ncmpii_inq_files_opened(num, ncids);
+}
+
+/*----< ncmpi_inq_recsize() >------------------------------------------------*/
+int
+ncmpi_inq_recsize(int ncid,
+ MPI_Offset *recsize)
+{
+ int status;
+ NC *ncp;
+
+ status = ncmpii_NC_check_id(ncid, &ncp);
+ if (status != NC_NOERR)
+ return status;
+
+ *recsize = ncp->recsize;
+ return NC_NOERR;
+}
+
+/*----< ncmpi_inq_header_extent() >-------------------------------------------*/
+int
+ncmpi_inq_header_extent(int ncid,
+ MPI_Offset *extent)
+{
+ int err;
+ NC *ncp;
+
+ err = ncmpii_NC_check_id(ncid, &ncp);
+ if (err != NC_NOERR) return err;
+
+ *extent = ncp->begin_var;
+
+ return NC_NOERR;
+}
+
+/*----< ncmpi_inq_header_size() >---------------------------------------------*/
+int
+ncmpi_inq_header_size(int ncid,
+ MPI_Offset *size)
+{
+ int err;
+ NC *ncp;
+
+ err = ncmpii_NC_check_id(ncid, &ncp);
+ if (err != NC_NOERR) return err;
+
+ *size = ncp->xsz;
+
+ return NC_NOERR;
+}
+
diff --git a/src/lib/nc.c b/src/lib/nc.c
new file mode 100644
index 0000000..b2f06ce
--- /dev/null
+++ b/src/lib/nc.c
@@ -0,0 +1,1635 @@
+/*
+ * Copyright (C) 2003, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ */
+/* $Id: nc.c 2299 2016-01-09 06:14:37Z wkliao $ */
+
+#if HAVE_CONFIG_H
+# include "ncconfig.h"
+#endif
+
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+
+#include <mpi.h>
+
+#include "nc.h"
+#include "rnd.h"
+#include "ncx.h"
+#include "macro.h"
+#ifdef ENABLE_SUBFILING
+#include "subfile.h"
+#endif
+
+/* list of open netcdf's */
+static NC *NClist = NULL;
+
+/* This is the default create format for ncmpi_create and nc__create. */
+static int default_create_format = NC_FORMAT_CLASSIC;
+
+/* These have to do with version numbers. */
+#define MAGIC_NUM_LEN 4
+#define VER_CLASSIC 1
+#define VER_64BIT_OFFSET 2
+#define VER_HDF5 3
+#define VER_64BIT_DATA 5
+
+/* Prototypes for functions used only in this file */
+#if 0
+static int move_data_r(NC *ncp, NC *old);
+static int move_vars_r(NC *ncp, NC *old);
+static int NC_check_def(MPI_Comm comm, void *buf, MPI_Offset nn);
+static int nc_set_fill(int ncid, int fillmode, int *old_mode_ptr);
+#endif
+
+/*----< ncmpii_add_to_NCList() >---------------------------------------------*/
+void
+ncmpii_add_to_NCList(NC *ncp)
+{
+ assert(ncp != NULL);
+
+ /* add the newly created NC object to the head of linked list */
+ ncp->prev = NULL;
+ if (NClist != NULL)
+ NClist->prev = ncp;
+ ncp->next = NClist;
+ NClist = ncp;
+}
+
+/*----< ncmpii_del_from_NCList() >-------------------------------------------*/
+void
+ncmpii_del_from_NCList(NC *ncp)
+{
+ assert(ncp != NULL);
+
+ if (NClist == ncp) {
+ assert(ncp->prev == NULL);
+ NClist = ncp->next;
+ }
+ else {
+ assert(ncp->prev != NULL);
+ ncp->prev->next = ncp->next;
+ }
+
+ if (ncp->next != NULL)
+ ncp->next->prev = ncp->prev;
+
+ ncp->next = NULL;
+ ncp->prev = NULL;
+}
+
+/*----< NC_check_header() >--------------------------------------------------*/
+/*
+ * Check the consistency of defined header metadata across all processes and
+ * overwrite the local header objects with root's if inconsistency is found.
+ * This function is collective.
+ */
+static int
+NC_check_header(NC *ncp,
+ void *buf,
+ MPI_Offset local_xsz) /* size of buf */
+{
+ void *cmpbuf;
+ int rank, g_status, status=NC_NOERR, mpireturn;
+ bufferinfo gbp;
+
+ MPI_Comm_rank(ncp->nciop->comm, &rank);
+
+ /* root's header size has been broadcasted in NC_begin() and saved in
+ * ncp->xsz.
+ */
+ if (rank == 0)
+ cmpbuf = buf;
+ else
+ cmpbuf = (void*) NCI_Malloc((size_t)ncp->xsz);
+
+ /* process 0 broadcasts its header
+ * TODO: currently the header size cannot be larger than 2^31 bytes,
+ * due to the 2nd argument, count, of MPI_Bcast being of type int.
+ * Possible solution is to broadcast in chunks of 2^31 bytes.
+ */
+ if (ncp->xsz != (int)ncp->xsz) DEBUG_RETURN_ERROR(NC_EINTOVERFLOW)
+ TRACE_COMM(MPI_Bcast)(cmpbuf, (int)ncp->xsz, MPI_BYTE, 0, ncp->nciop->comm);
+
+ if (rank > 0 && (ncp->xsz != local_xsz || memcmp(buf, cmpbuf, (size_t)ncp->xsz))) {
+ /* now part of this process's header is not consistent with root's
+ * check and report the inconsistent part
+ */
+
+ gbp.nciop = ncp->nciop; /* will not be used in ncmpii_hdr_check_NC() */
+ gbp.offset = 0; /* will not be used in ncmpii_hdr_check_NC() */
+ gbp.size = ncp->xsz; /* entire header is in the buffer, cmpbuf */
+ gbp.index = 0;
+ gbp.pos = gbp.base = cmpbuf;
+
+ /* find the inconsistent part of the header, report the difference, and
+ * overwrite the local header object with root's. ncmpii_hdr_check_NC()
+ * should not have any MPI communication calls.
+ */
+ status = ncmpii_hdr_check_NC(&gbp, ncp);
+
+ /* header consistency is only checked on non-root processes. The
+ * returned status can be a fatal error or header inconsistency error,
+ * (fatal errors are due to object allocation), but never NC_NOERR.
+ */
+ }
+
+ if (ncp->safe_mode) {
+ TRACE_COMM(MPI_Allreduce)(&status, &g_status, 1, MPI_INT, MPI_MIN,
+ ncp->nciop->comm);
+ if (mpireturn != MPI_SUCCESS)
+ return ncmpii_handle_error(mpireturn, "MPI_Allreduce");
+
+ if (g_status != NC_NOERR) { /* some headers are inconsistent */
+ if (status == NC_NOERR) DEBUG_ASSIGN_ERROR(status, NC_EMULTIDEFINE)
+ }
+ }
+
+ if (rank > 0) NCI_Free(cmpbuf);
+
+ return status;
+}
+
+
+#if 0
+/* 'defined but not used': seems like a useful function though. why did we
+ * write it? should we be using it? */
+
+static int
+NC_check_def(MPI_Comm comm, void *buf, MPI_Offset nn) {
+ int rank;
+ int errcheck;
+ MPI_Offset compare = 0;
+ void *cmpbuf;
+ MPI_Offset max_size;
+
+ MPI_Comm_rank(comm, &rank);
+
+ if (rank == 0)
+ max_size = nn;
+ MPI_Bcast(&max_size, 1, MPI_OFFSET, 0, comm);
+
+ compare = max_size - nn;
+
+ MPI_Allreduce(&compare, &errcheck, 1, MPI_OFFSET, MPI_LOR, comm);
+
+ if (errcheck)
+ DEBUG_RETURN_ERROR(NC_EMULTIDEFINE)
+
+ if (rank == 0)
+ cmpbuf = buf;
+ else
+ cmpbuf = (void *)NCI_Malloc(nn);
+
+ MPI_Bcast(cmpbuf, nn, MPI_BYTE, 0, comm);
+
+ if (rank != 0) {
+ compare = memcmp(buf, cmpbuf, nn);
+ NCI_Free(cmpbuf);
+ }
+
+ MPI_Allreduce(&compare, &errcheck, 1, MPI_OFFSET, MPI_LOR, comm);
+
+ if (errcheck){
+ DEBUG_RETURN_ERROR(NC_EMULTIDEFINE)
+ }else{
+ return NC_NOERR;
+ }
+}
+#endif
+
+/*----< ncmpii_NC_check_id() >-----------------------------------------------*/
+int
+ncmpii_NC_check_id(int ncid,
+ NC **ncpp)
+{
+ NC *ncp;
+
+ if (ncid >= 0) {
+ for (ncp = NClist; ncp != NULL; ncp = ncp->next) {
+ if (ncp->nciop->fd == ncid) {
+ *ncpp = ncp;
+ return NC_NOERR; /* normal return */
+ }
+ }
+ }
+
+ /* else, not found */
+ DEBUG_RETURN_ERROR(NC_EBADID)
+}
+
+
+/*----< ncmpii_inq_files_opened() >------------------------------------------*/
+int
+ncmpii_inq_files_opened(int *num, int *ncids)
+{
+ NC *ncp;
+
+/*
+ for (ncp=NClist; ncp!=NULL; ncp=ncp->next)
+ printf("still open %s\n",ncp->nciop->path);
+*/
+ if (num == NULL) DEBUG_RETURN_ERROR(NC_EINVAL)
+
+ *num = 0;
+ for (ncp=NClist; ncp!=NULL; ncp=ncp->next)
+ (*num)++;
+
+ if (*num > 0 && ncids != NULL) {
+ /* when ncids is NULL, we skip getting the values */
+ int i=0;
+ for (ncp=NClist; ncp!=NULL; ncp=ncp->next)
+ ncids[i] = ncp->nciop->fd;
+ }
+ return NC_NOERR;
+}
+
+
+/*----< ncmpii_free_NC() >----------------------------------------------------*/
+inline void
+ncmpii_free_NC(NC *ncp)
+{
+ if (ncp == NULL) return;
+ ncmpii_free_NC_dimarray(&ncp->dims);
+ ncmpii_free_NC_attrarray(&ncp->attrs);
+ ncmpii_free_NC_vararray(&ncp->vars);
+ NCI_Free(ncp);
+}
+
+
+/*----< ncmpii_new_NC() >----------------------------------------------------*/
+inline NC *
+ncmpii_new_NC(const MPI_Offset *chunkp)
+{
+ NC *ncp = (NC *) NCI_Calloc(1, sizeof(NC));
+
+ if (ncp == NULL) return NULL;
+
+ ncp->chunk = (chunkp != NULL) ? *chunkp : NC_SIZEHINT_DEFAULT;
+
+ return ncp;
+}
+
+/*----< ncmpi_set_default_format() >-----------------------------------------*/
+/* This function sets a default create file format.
+ * Valid formats are NC_FORMAT_CLASSIC, NC_FORMAT_CDF2, and NC_FORMAT_CDF5
+ * This API is collective.
+ */
+int
+ncmpi_set_default_format(int format, int *old_formatp)
+{
+ int safe_mode=0, mpireturn, status=NC_NOERR;
+ char *env_str;
+
+ /* Return existing format if desired. */
+ if (old_formatp)
+ *old_formatp = default_create_format;
+
+ env_str = getenv("PNETCDF_SAFE_MODE");
+ if (env_str != NULL) {
+ if (*env_str == '0') safe_mode = 0;
+ else safe_mode = 1;
+ }
+
+ if (safe_mode) {
+ /* check if format is consistent with root's */
+ int root_format=format;
+
+ TRACE_COMM(MPI_Bcast)(&root_format, 1, MPI_INT, 0, MPI_COMM_WORLD);
+ if (mpireturn != MPI_SUCCESS)
+ return ncmpii_handle_error(mpireturn, "MPI_Bcast");
+
+ if (root_format != format) {
+ int rank;
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ /* formats are inconsistent, overwrite local format with root's */
+ printf("rank %d: Warning - inconsistent file format, overwrite with root's\n",rank);
+ format = root_format;
+ DEBUG_ASSIGN_ERROR(status, NC_EMULTIDEFINE_OMODE)
+ }
+ }
+
+
+ /* Make sure only valid format is set. */
+ if (format != NC_FORMAT_CLASSIC &&
+ format != NC_FORMAT_CDF2 &&
+ format != NC_FORMAT_CDF5) {
+ DEBUG_RETURN_ERROR(NC_EINVAL)
+ }
+ default_create_format = format;
+
+ return status;
+}
+
+/* returns a value suitable for a create flag. Will return one or more of the
+ * following values OR-ed together:
+ * NC_64BIT_OFFSET, NC_CLOBBER, NC_LOCK, NC_SHARE */
+int
+ncmpi_inq_default_format(int *formatp)
+{
+ if (formatp == NULL) DEBUG_RETURN_ERROR(NC_EINVAL)
+
+ *formatp = default_create_format;
+ return NC_NOERR;
+}
+
+/*----< ncmpii_dup_NC() >----------------------------------------------------*/
+NC *
+ncmpii_dup_NC(const NC *ref)
+{
+ NC *ncp;
+
+ ncp = (NC *) NCI_Malloc(sizeof(NC));
+ if (ncp == NULL) return NULL;
+
+ memset(ncp, 0, sizeof(NC));
+
+ if (ncmpii_dup_NC_dimarray(&ncp->dims, &ref->dims) != NC_NOERR ||
+ ncmpii_dup_NC_attrarray(&ncp->attrs, &ref->attrs) != NC_NOERR ||
+ ncmpii_dup_NC_vararray(&ncp->vars, &ref->vars) != NC_NOERR) {
+ ncmpii_free_NC(ncp);
+ return NULL;
+ }
+
+ ncp->xsz = ref->xsz;
+ ncp->begin_var = ref->begin_var;
+ ncp->begin_rec = ref->begin_rec;
+ ncp->recsize = ref->recsize;
+
+ NC_set_numrecs(ncp, NC_get_numrecs(ref));
+ return ncp;
+}
+
+
+/*
+ * Verify that this is a user nc_type
+ * Formerly
+NCcktype()
+ * Sense of the return is changed.
+ */
+inline int
+ncmpii_cktype(int cdf_ver,
+ nc_type type)
+{
+ /* the max data type supported by CDF-5 is NC_UINT64 */
+ if (type <= 0 || type > NC_UINT64)
+ DEBUG_RETURN_ERROR(NC_EBADTYPE)
+
+ /* For CDF-1 and CDF-2 files, only classic types are allowed. */
+ if (cdf_ver < 5 && type > NC_DOUBLE)
+ DEBUG_RETURN_ERROR(NC_ESTRICTCDF2)
+
+ return NC_NOERR;
+}
+
+
+/*
+ * How many objects of 'type'
+ * will fit into xbufsize?
+ */
+inline MPI_Offset
+ncmpix_howmany(nc_type type, MPI_Offset xbufsize)
+{
+ switch(type){
+ case NC_BYTE:
+ case NC_UBYTE:
+ case NC_CHAR: return xbufsize;
+ case NC_SHORT: return xbufsize/X_SIZEOF_SHORT;
+ case NC_USHORT: return xbufsize/X_SIZEOF_USHORT;
+ case NC_INT: return xbufsize/X_SIZEOF_INT;
+ case NC_UINT: return xbufsize/X_SIZEOF_UINT;
+ case NC_FLOAT: return xbufsize/X_SIZEOF_FLOAT;
+ case NC_DOUBLE: return xbufsize/X_SIZEOF_DOUBLE;
+ case NC_INT64: return xbufsize/X_SIZEOF_INT64;
+ case NC_UINT64: return xbufsize/X_SIZEOF_UINT64;
+ default:
+ assert("ncmpix_howmany: Bad type" == 0);
+ return(0);
+ }
+}
+
+#define D_RNDUP(x, align) _RNDUP(x, (off_t)(align))
+
+/*----< NC_begins() >--------------------------------------------------------*/
+/*
+ * This function is only called at enddef().
+ * It computes each variable's 'begin' offset, and sets/updates the followings:
+ * ncp->xsz ---- header size
+ * ncp->vars.value[*]->begin ---- each variable's 'begin' offset
+ * ncp->begin_var ---- offset of first non-record variable
+ * ncp->begin_rec ---- offset of first record variable
+ * ncp->recsize ---- sum of single records
+ * ncp->numrecs ---- number of records (set only if new file)
+ */
+static int
+NC_begins(NC *ncp,
+ MPI_Offset h_align, /* header alignment */
+ MPI_Offset h_minfree,/* free space for header */
+ MPI_Offset v_align, /* alignment for each fixed variable */
+ MPI_Offset v_minfree,/* free space for fixed variable section */
+ MPI_Offset r_align) /* alignment for record variable section */
+{
+ int i, j, rank, cdf_format, mpireturn;
+ MPI_Offset end_var=0;
+ NC_var *last = NULL;
+ NC_var *first_var = NULL; /* first "non-record" var */
+
+ /* cdf_format determines the size of variable's "begin" in the header */
+ if (fIsSet(ncp->flags, NC_64BIT_DATA))
+ cdf_format = 5; /* CDF-5 */
+ else if (fIsSet(ncp->flags, NC_64BIT_OFFSET))
+ cdf_format = 2; /* CDF-2 */
+ else
+ cdf_format = 1; /* CDF-1 */
+
+ /* get the true header size (un-aligned one) */
+ MPI_Comm_rank(ncp->nciop->comm, &rank);
+ if (rank ==0) ncp->xsz = ncmpii_hdr_len_NC(ncp);
+
+ /* only root's header size matters */
+ TRACE_COMM(MPI_Bcast)(&ncp->xsz, 1, MPI_OFFSET, 0, ncp->nciop->comm);
+ if (mpireturn != MPI_SUCCESS)
+ return ncmpii_handle_error(mpireturn, "MPI_Bcast");
+
+ /* This function is called in ncmpi_enddef(), which can happen either when
+ * creating a new file or opening an existing file with metadata modified.
+ * For the former case, ncp->begin_var == 0 here.
+ * For the latter case, we set begin_var a new value only if the new header
+ * grows out of its extent or the start of non-record variables is not
+ * aligned as requested by h_align.
+ * Note ncp->xsz is header size and ncp->begin_var is header extent.
+ * Add the minimum header free space requested by user.
+ */
+ if (h_minfree < 0) h_minfree = 0;
+ ncp->begin_var = D_RNDUP(ncp->xsz + h_minfree, h_align);
+
+ if (ncp->old != NULL) {
+ /* If this define mode was entered from a redef(), we check whether
+ * the new begin_var against the old begin_var. We do not shrink
+ * the header extent.
+ */
+ if (ncp->begin_var < ncp->old->begin_var)
+ ncp->begin_var = ncp->old->begin_var;
+ }
+
+ /* ncp->begin_var is the aligned starting file offset of the first
+ variable, also the extent of file header */
+
+ /* Now calculate the starting file offsets for all variables.
+ loop thru vars, first pass is for the 'non-record' vars */
+ end_var = ncp->begin_var;
+ for (j=0, i=0; i<ncp->vars.ndefined; i++) {
+ if (IS_RECVAR(ncp->vars.value[i]))
+ /* skip record variables on this pass */
+ continue;
+ if (first_var == NULL) first_var = ncp->vars.value[i];
+
+ /* for CDF-1 check if over the file size limit 32-bit integer */
+ if (cdf_format == 1 && end_var > X_OFF_MAX)
+ DEBUG_RETURN_ERROR(NC_EVARSIZE)
+
+ /* this will pad out non-record variables with zero to the
+ * requested alignment. record variables are a bit trickier.
+ * we don't do anything special with them */
+ ncp->vars.value[i]->begin = D_RNDUP(end_var, v_align);
+
+ if (ncp->old != NULL) {
+ /* move to the next fixed variable */
+ for (; j<ncp->old->vars.ndefined; j++)
+ if (!IS_RECVAR(ncp->old->vars.value[j]))
+ break;
+ if (j < ncp->old->vars.ndefined) {
+ if (ncp->vars.value[i]->begin < ncp->old->vars.value[j]->begin)
+ /* the first ncp->vars.ndefined non-record variables should
+ be the same. If the new begin is smaller, reuse the old
+ begin */
+ ncp->vars.value[i]->begin = ncp->old->vars.value[j]->begin;
+ j++;
+ }
+ }
+ /* end_var is the end offset of variable i */
+ end_var = ncp->vars.value[i]->begin + ncp->vars.value[i]->len;
+ }
+
+ /* end_var now is pointing to the end of last non-record variable */
+
+ /* only (re)calculate begin_rec if there is not sufficient
+ * space at end of non-record variables or if start of record
+ * variables is not aligned as requested by r_align.
+ * If the existing begin_rec is already >= index, then leave the
+ * begin_rec as is (in case some non-record variables are deleted)
+ */
+ if (ncp->begin_rec < end_var ||
+ ncp->begin_rec != D_RNDUP(ncp->begin_rec, v_align))
+ ncp->begin_rec = D_RNDUP(end_var, v_align);
+
+ /* expand free space for fixed variable section */
+ if (ncp->begin_rec < end_var + v_minfree)
+ ncp->begin_rec = D_RNDUP(end_var + v_minfree, v_align);
+
+ /* align the starting offset for record variable section */
+ if (r_align > 1)
+ ncp->begin_rec = D_RNDUP(ncp->begin_rec, r_align);
+
+ if (ncp->old != NULL) {
+ /* check whether the new begin_rec is smaller */
+ if (ncp->begin_rec < ncp->old->begin_rec)
+ ncp->begin_rec = ncp->old->begin_rec;
+ }
+
+ if (first_var != NULL)
+ ncp->begin_var = first_var->begin;
+ else
+ ncp->begin_var = ncp->begin_rec;
+
+ end_var = ncp->begin_rec;
+ /* end_var now is pointing to the beginning of record variables
+ * note that this can be larger than the end of last non-record variable
+ */
+
+ ncp->recsize = 0;
+
+ /* TODO: alignment for record variables (maybe using a new hint) */
+
+ /* loop thru vars, second pass is for the 'record' vars,
+ * re-calculate the starting offset for each record variable */
+ for (j=0, i=0; i<ncp->vars.ndefined; i++) {
+ if (!IS_RECVAR(ncp->vars.value[i]))
+ /* skip non-record variables on this pass */
+ continue;
+
+ /* X_OFF_MAX is the max of 32-bit integer */
+ if (cdf_format == 1 && end_var > X_OFF_MAX)
+ DEBUG_RETURN_ERROR(NC_EVARSIZE)
+
+ /* A few attempts at aligning record variables have failed
+ * (either with range error or 'value read not that expected',
+ * or with an error in ncmpi_redef )). Not sufficient to align
+ * 'begin', but haven't figured out what else to adjust */
+ ncp->vars.value[i]->begin = end_var;
+
+ if (ncp->old != NULL) {
+ /* move to the next record variable */
+ for (; j<ncp->old->vars.ndefined; j++)
+ if (IS_RECVAR(ncp->old->vars.value[j]))
+ break;
+ if (j < ncp->old->vars.ndefined) {
+ if (ncp->vars.value[i]->begin < ncp->old->vars.value[j]->begin)
+ /* if the new begin is smaller, use the old begin */
+ ncp->vars.value[i]->begin = ncp->old->vars.value[j]->begin;
+ j++;
+ }
+ }
+ end_var += ncp->vars.value[i]->len;
+ /* end_var is the end offset of record variable i */
+
+ /* check if record size must fit in 32-bits */
+#if SIZEOF_OFF_T == SIZEOF_SIZE_T && SIZEOF_SIZE_T == 4
+ if (ncp->recsize > X_UINT_MAX - ncp->vars.value[i]->len)
+ DEBUG_RETURN_ERROR(NC_EVARSIZE)
+#endif
+ ncp->recsize += ncp->vars.value[i]->len;
+ last = ncp->vars.value[i];
+ }
+
+ /*
+ * for special case (Check CDF-1 and CDF-2 file format specifications.)
+ * "A special case: Where there is exactly one record variable, we drop the
+ * requirement that each record be four-byte aligned, so in this case there
+ * is no record padding."
+ */
+ if (last != NULL) {
+ if (ncp->recsize == last->len) {
+ /* exactly one record variable, pack value */
+ ncp->recsize = *last->dsizes * last->xsz;
+ }
+#if 0
+ else if (last->len == UINT32_MAX) { /* huge last record variable */
+ ncp->recsize += *last->dsizes * last->xsz;
+ }
+#endif
+ }
+
+/* below is only needed if alignment is performed on record variables */
+#if 0
+ /*
+ * for special case of exactly one record variable, pack value
+ */
+ /* if there is exactly one record variable, then there is no need to
+ * pad for alignment -- there's nothing after it */
+ if (last != NULL && ncp->recsize == last->len)
+ ncp->recsize = *last->dsizes * last->xsz;
+#endif
+
+ if (NC_IsNew(ncp))
+ NC_set_numrecs(ncp, 0);
+
+ return NC_NOERR;
+}
+
+#define NC_NUMRECS_OFFSET 4
+
+/*----< ncmpii_sync_numrecs() >-----------------------------------------------*/
+/* Synchronize the number of records in memory and write numrecs to file.
+ * This function is called by:
+ * 1. ncmpi_sync_numrecs(): by the user
+ * 2. ncmpi_sync(): by the user
+ * 3. ncmpii_end_indep_data(): exit from independent data mode
+ * 4. all blocking collective put APIs (getput.m4) when writing record variable
+ * 5. collective nonblocking wait API (ncmpii_wait_getput)
+ * 6. ncmpii_close(): file close and currently in independent data mode
+ *
+ * This function is collective.
+ */
+int
+ncmpii_sync_numrecs(NC *ncp,
+ MPI_Offset new_numrecs)
+{
+ int rank, status=NC_NOERR, mpireturn, err;
+ MPI_File fh;
+ MPI_Offset max_numrecs;
+
+ assert(!NC_readonly(ncp));
+ assert(!NC_indef(ncp)); /* can only be called by APIs in data mode */
+
+ /* find the max new_numrecs among all processes
+ * Note new_numrecs may be smaller than ncp->numrecs
+ */
+ TRACE_COMM(MPI_Allreduce)(&new_numrecs, &max_numrecs, 1, MPI_OFFSET,
+ MPI_MAX, ncp->nciop->comm);
+ if (mpireturn != MPI_SUCCESS)
+ return ncmpii_handle_error(mpireturn, "MPI_Allreduce");
+
+ fh = ncp->nciop->collective_fh;
+ if (NC_indep(ncp))
+ fh = ncp->nciop->independent_fh;
+
+ /* root process writes numrecs in file */
+ MPI_Comm_rank(ncp->nciop->comm, &rank);
+ if (rank == 0 && /* Only root process writes to file header */
+ (max_numrecs > ncp->numrecs || NC_ndirty(ncp))) {
+ /* For collective data mode, we check max_numrecs against root's
+ * ncp->numrecs because root's numrecs has not been updated.
+ * For independent data mode, we check NC_ndirty bit, because root's
+ * numrecs may have been updated and in this case NC_ndirty bit has
+ * been set to dirty. */
+ int len;
+ char pos[8], *buf=pos;
+ MPI_Status mpistatus;
+
+ if (ncp->flags & NC_64BIT_DATA) {
+ len = X_SIZEOF_INT64;
+ status = ncmpix_put_uint64((void**)&buf, max_numrecs);
+ }
+ else {
+ if (max_numrecs != (int)max_numrecs) DEBUG_ASSIGN_ERROR(status, NC_EINTOVERFLOW)
+ len = X_SIZEOF_SIZE_T;
+ status = ncmpix_put_uint32((void**)&buf, (uint)max_numrecs);
+ }
+ /* ncmpix_put_xxx advances the 1st argument with size len */
+
+ /* root's file view always includes the entire file header */
+
+ TRACE_IO(MPI_File_write_at)(fh, NC_NUMRECS_OFFSET, (void*)pos, len,
+ MPI_BYTE, &mpistatus);
+ if (mpireturn != MPI_SUCCESS) {
+ err = ncmpii_handle_error(mpireturn, "MPI_File_write_at");
+ if (status == NC_NOERR && err == NC_EFILE) DEBUG_ASSIGN_ERROR(status, NC_EWRITE)
+ }
+ else {
+ int put_size;
+ MPI_Get_count(&mpistatus, MPI_BYTE, &put_size);
+ ncp->nciop->put_size += put_size;
+ }
+ }
+ /* update numrecs in all processes's memory only if the new one is larger.
+ * Note new_numrecs may be smaller than ncp->numrecs
+ */
+ if (max_numrecs > ncp->numrecs) ncp->numrecs = max_numrecs;
+
+ if (ncp->safe_mode == 1) {
+ /* broadcast root's status, because only root writes to the file */
+ int root_status = status;
+ TRACE_COMM(MPI_Bcast)(&root_status, 1, MPI_INT, 0, ncp->nciop->comm);
+ /* root's write has failed, which is serious */
+ if (root_status == NC_EWRITE) DEBUG_ASSIGN_ERROR(status, NC_EWRITE)
+ }
+
+ /* clear numrecs dirty bit */
+ fClr(ncp->flags, NC_NDIRTY);
+
+ return status;
+}
+
+/*
+ * Read in the header
+ * It is expensive.
+ */
+
+inline int
+ncmpii_read_NC(NC *ncp) {
+ int status = NC_NOERR;
+
+ ncmpii_free_NC_dimarray(&ncp->dims);
+ ncmpii_free_NC_attrarray(&ncp->attrs);
+ ncmpii_free_NC_vararray(&ncp->vars);
+
+ status = ncmpii_hdr_get_NC(ncp);
+
+ if (status == NC_NOERR)
+ fClr(ncp->flags, NC_NDIRTY);
+
+ return status;
+}
+
+/*----< write_NC() >---------------------------------------------------------*/
+/*
+ * This function is collective and only called by enddef().
+ * Write out the header
+ * 1. Call ncmpii_hdr_put_NC() to copy the header object, ncp, to a buffer.
+ * 2. Call NC_check_header() to check if header is consistent across all
+ * processes.
+ * 3. Process rank 0 writes the header to file.
+ * This is a collective call.
+ */
+static int
+write_NC(NC *ncp)
+{
+ void *buf;
+ int status, mpireturn, err, max_err, rank;
+ MPI_Offset local_xsz;
+
+ assert(!NC_readonly(ncp));
+
+ /* ncp->xsz is root's header size, we need to calculate local's */
+ local_xsz = ncmpii_hdr_len_NC(ncp);
+
+ buf = NCI_Malloc((size_t)local_xsz); /* buffer for local header object */
+
+ /* copy the entire local header object to buffer */
+ status = ncmpii_hdr_put_NC(ncp, buf);
+ if (status != NC_NOERR) { /* a fatal error */
+ NCI_Free(buf);
+ return status;
+ }
+
+ /* check the header consistency across all processes and sync header.
+ * When safe_mode is on:
+ * The returned status on root can be either NC_NOERR (all headers are
+ * consistent) or NC_EMULTIDEFINE (some headers are inconsistent).
+ * The returned status on non-root processes can be NC_NOERR, fatal
+ * error (>-250), or inconsistency error (-250 to -269).
+ * When safe_mode is off:
+ * The returned status on root is always NC_NOERR
+ * The returned status on non-root processes can be NC_NOERR, fatal
+ * error (>-250), or inconsistency error (-250 to -269).
+ * For fatal error, we should stop. For others, we can continue.
+ */
+ status = NC_check_header(ncp, buf, local_xsz);
+
+ /* check for fatal error */
+ err = (status != NC_NOERR && !ErrIsHeaderDiff(status)) ? 1 : 0;
+ max_err = err;
+
+ if (ncp->safe_mode == 1)
+ TRACE_COMM(MPI_Allreduce)(&err, &max_err, 1, MPI_INT, MPI_MAX,
+ ncp->nciop->comm);
+
+ if (max_err == 1) { /* some processes encounter a fatal error */
+ NCI_Free(buf);
+ return status;
+ }
+ /* For non-fatal error, we continue to write header to the file, as now the
+ * header object in memory has been sync-ed across all processes. */
+
+ /* only rank 0's header gets written to the file */
+ MPI_Comm_rank(ncp->nciop->comm, &rank);
+ if (rank == 0) {
+ /* rank 0's fileview already includes the file header */
+ MPI_Status mpistatus;
+ if (ncp->xsz != (int)ncp->xsz) DEBUG_ASSIGN_ERROR(status, NC_EINTOVERFLOW)
+ TRACE_IO(MPI_File_write_at)(ncp->nciop->collective_fh, 0, buf,
+ (int)ncp->xsz, MPI_BYTE, &mpistatus);
+ if (mpireturn != MPI_SUCCESS) {
+ err = ncmpii_handle_error(mpireturn, "MPI_File_write_at");
+ /* write has failed, which is more serious than inconsistency */
+ if (err == NC_EFILE) DEBUG_ASSIGN_ERROR(status, NC_EWRITE)
+ }
+ else {
+ int put_size;
+ MPI_Get_count(&mpistatus, MPI_BYTE, &put_size);
+ ncp->nciop->put_size += put_size;
+ }
+ }
+
+ if (ncp->safe_mode == 1) {
+ /* broadcast root's status, because only root writes to the file */
+ int root_status = status;
+ TRACE_COMM(MPI_Bcast)(&root_status, 1, MPI_INT, 0, ncp->nciop->comm);
+ /* root's write has failed, which is more serious than inconsistency */
+ if (root_status == NC_EWRITE) DEBUG_ASSIGN_ERROR(status, NC_EWRITE)
+ }
+
+ fClr(ncp->flags, NC_NDIRTY);
+ NCI_Free(buf);
+
+ return status;
+}
+
+inline int
+ncmpii_dset_has_recvars(NC *ncp)
+{
+ /* possible further optimization: set a flag on the header data
+ * structure when record variable created so we can skip this loop*/
+ int i;
+ NC_var **vpp;
+
+ vpp = ncp->vars.value;
+ for (i=0; i< ncp->vars.ndefined; i++, vpp++) {
+ if (IS_RECVAR(*vpp)) return 1;
+ }
+ return 0;
+}
+
+
+#if 0
+/*
+ * header size increases, shift all record and non-record variables down
+ */
+static int
+move_data_r(NC *ncp, NC *old) {
+ /* no new record or non-record variable inserted, header size increases,
+ * must shift (move) the whole contiguous data part down
+ * Note ncp->numrecs may be > old->numrecs
+ */
+ return ncmpiio_move(ncp->nciop, ncp->begin_var, old->begin_var,
+ old->begin_rec - old->begin_var +
+ ncp->recsize * ncp->numrecs);
+}
+#endif
+
+/*
+ * Move the record variables down,
+ * re-arrange records as needed
+ * Fill as needed.
+ */
+static int
+move_recs_r(NC *ncp, NC *old) {
+ int status;
+ MPI_Offset recno;
+ const MPI_Offset nrecs = ncp->numrecs;
+ const MPI_Offset ncp_recsize = ncp->recsize;
+ const MPI_Offset old_recsize = old->recsize;
+ const off_t ncp_off = ncp->begin_rec;
+ const off_t old_off = old->begin_rec;
+
+ assert(ncp_recsize >= old_recsize);
+
+ if (ncp_recsize == old_recsize) {
+ if (ncp_recsize == 0) /* no record variable defined yet */
+ return NC_NOERR;
+
+ /* No new record variable inserted, move all record variables as a whole */
+ status = ncmpiio_move(ncp->nciop, ncp_off, old_off, ncp_recsize * nrecs);
+ if (status != NC_NOERR)
+ return status;
+ } else {
+ /* new record variables inserted, move one whole record at a time */
+ for (recno = nrecs-1; recno >= 0; recno--) {
+ status = ncmpiio_move(ncp->nciop,
+ ncp_off+recno*ncp_recsize,
+ old_off+recno*old_recsize,
+ old_recsize);
+ if (status != NC_NOERR)
+ return status;
+ }
+ }
+
+ return NC_NOERR;
+}
+
+
+#if 0
+/*
+ * Move the "non record" variables "out".
+ * Fill as needed.
+ */
+
+static int
+move_vars_r(NC *ncp, NC *old) {
+ return ncmpiio_move(ncp->nciop, ncp->begin_var, old->begin_var,
+ old->begin_rec - old->begin_var);
+}
+#endif
+
+/*
+ * Given a valid ncp, return NC_EVARSIZE if any variable has a bad len
+ * (product of non-rec dim sizes too large), else return NC_NOERR.
+ */
+static int
+ncmpii_NC_check_vlens(NC *ncp)
+{
+ NC_var **vpp;
+ /* maximum permitted variable size (or size of one record's worth
+ of a record variable) in bytes. This is different for format 1
+ and format 2. */
+ MPI_Offset vlen_max;
+ MPI_Offset ii;
+ MPI_Offset large_vars_count;
+ MPI_Offset rec_vars_count;
+ int last = 0;
+
+ if(ncp->vars.ndefined == 0)
+ return NC_NOERR;
+
+ if ((ncp->flags & NC_64BIT_DATA) && SIZEOF_OFF_T > 4)
+ return NC_NOERR;
+
+ if ((ncp->flags & NC_64BIT_OFFSET) && SIZEOF_OFF_T > 4) {
+ /* CDF2 format and LFS */
+ vlen_max = X_UINT_MAX - 3; /* "- 3" handles rounded-up size */
+ } else {
+ /* CDF1 format */
+ vlen_max = X_INT_MAX - 3;
+ }
+ /* Loop through vars, first pass is for non-record variables. */
+ large_vars_count = 0;
+ rec_vars_count = 0;
+ vpp = ncp->vars.value;
+ for (ii = 0; ii < ncp->vars.ndefined; ii++, vpp++) {
+ if( !IS_RECVAR(*vpp) ) {
+ last = 0;
+ if( ncmpii_NC_check_vlen(*vpp, vlen_max) == 0 ) {
+ large_vars_count++;
+ last = 1;
+ }
+ } else {
+ rec_vars_count++;
+ }
+ }
+ /* OK if last non-record variable size too large, since not used to
+ compute an offset */
+ if( large_vars_count > 1) { /* only one "too-large" variable allowed */
+ DEBUG_RETURN_ERROR(NC_EVARSIZE)
+ }
+ /* and it has to be the last one */
+ if( large_vars_count == 1 && last == 0) {
+ DEBUG_RETURN_ERROR(NC_EVARSIZE)
+ }
+ if( rec_vars_count > 0 ) {
+ /* and if it's the last one, there can't be any record variables */
+ if( large_vars_count == 1 && last == 1) {
+ DEBUG_RETURN_ERROR(NC_EVARSIZE)
+ }
+ /* Loop through vars, second pass is for record variables. */
+ large_vars_count = 0;
+ vpp = ncp->vars.value;
+ for (ii = 0; ii < ncp->vars.ndefined; ii++, vpp++) {
+ if( IS_RECVAR(*vpp) ) {
+ last = 0;
+ if( ncmpii_NC_check_vlen(*vpp, vlen_max) == 0 ) {
+ large_vars_count++;
+ last = 1;
+ }
+ }
+ }
+ /* OK if last record variable size too large, since not used to
+ compute an offset */
+ if( large_vars_count > 1) { /* only one "too-large" variable allowed */
+ DEBUG_RETURN_ERROR(NC_EVARSIZE)
+ }
+ /* and it has to be the last one */
+ if( large_vars_count == 1 && last == 0) {
+ DEBUG_RETURN_ERROR(NC_EVARSIZE)
+ }
+ }
+ return NC_NOERR;
+}
+
+#define DEFAULT_ALIGNMENT 512
+#define HEADER_ALIGNMENT_LB 4
+
+/* Many subroutines called in ncmpii_NC_enddef() are collective. We check the
+ * error codes of all processes only in safe mode, so the program can stop
+ * collectively, if any one process got an error. However, when safe mode is
+ * off, we simply return the error and program may hang if some processes
+ * do not get error and proceed to the next subroutine call.
+ */
+#define CHECK_ERROR(status) { \
+ if (ncp->safe_mode == 1) { \
+ int g_status; \
+ TRACE_COMM(MPI_Allreduce)(&status, &g_status, 1, MPI_INT, MPI_MIN, \
+ ncp->nciop->comm); \
+ if (mpireturn != MPI_SUCCESS) \
+ return ncmpii_handle_error(mpireturn, "MPI_Allreduce"); \
+ if (g_status != NC_NOERR) return status; \
+ } \
+ else if (status != NC_NOERR) \
+ return status; \
+}
+
+/*----< ncmpii_NC_enddef() >-------------------------------------------------*/
+static int
+ncmpii_NC_enddef(NC *ncp,
+ MPI_Offset h_align,
+ MPI_Offset h_minfree,
+ MPI_Offset v_align,
+ MPI_Offset v_minfree,
+ MPI_Offset r_align)
+{
+ int i, err, status=NC_NOERR, mpireturn;
+ char value[MPI_MAX_INFO_VAL];
+#ifdef ENABLE_SUBFILING
+ NC *ncp_sf=NULL;
+#endif
+
+ assert(h_align > 0); /* alignment size cannot be zero */
+ assert(v_align > 0);
+ assert(r_align > 0);
+
+ /* all CDF formats require 4-bytes alignment */
+ h_align = D_RNDUP(h_align, 4);
+ v_align = D_RNDUP(v_align, 4);
+ r_align = D_RNDUP(r_align, 4);
+
+ /* reflect the hint changes to the MPI info object, so the user can
+ * query exactly what hint values are being used
+ */
+ ncp->nciop->hints.h_align = h_align;
+ ncp->nciop->hints.v_align = v_align;
+ ncp->nciop->hints.r_align = r_align;
+
+ sprintf(value, "%lld", h_align);
+ MPI_Info_set(ncp->nciop->mpiinfo, "nc_header_align_size", value);
+ sprintf(value, "%lld", v_align);
+ MPI_Info_set(ncp->nciop->mpiinfo, "nc_var_align_size", value);
+ sprintf(value, "%lld", r_align);
+ MPI_Info_set(ncp->nciop->mpiinfo, "nc_record_align_size", value);
+
+#ifdef ENABLE_SUBFILING
+ /* num of subfiles has been determined already */
+ ncp->subfile_mode = ncp->nciop->hints.subfile_mode;
+ ncp->nc_num_subfiles = ncp->nciop->hints.num_subfiles;
+
+ if (ncp->nc_num_subfiles > 1) {
+ /* TODO: should return subfile-related msg when there's an error */
+ status = ncmpii_subfile_partition(ncp, &ncp->ncid_sf);
+ if (status != NC_NOERR)
+ printf("Error in file %s line %d (%s)\n",__FILE__,__LINE__,
+ ncmpi_strerror(status));
+
+ CHECK_ERROR(status)
+ }
+#endif
+
+ /* check on dimension lengths */
+ status = ncmpii_NC_check_vlens(ncp);
+ CHECK_ERROR(status)
+
+ /* When ncp->old == NULL, this enddef is called the first time after file
+ * create call. In this case, we compute each variable's 'begin', starting
+ * file offset as well as the offsets of record variables.
+ * When ncp->old != NULL, this enddef is called after a redef. In this
+ * case, we re-used all variable offsets as many as possible.
+ */
+ status = NC_begins(ncp, h_align, h_minfree, v_align, v_minfree, r_align);
+ CHECK_ERROR(status)
+
+#ifdef ENABLE_SUBFILING
+ if (ncp->nc_num_subfiles > 1) {
+ /* get ncp info for the subfile */
+ status = ncmpii_NC_check_id(ncp->ncid_sf, &ncp_sf);
+ CHECK_ERROR(status)
+
+ status = NC_begins(ncp_sf, h_align, h_minfree, v_align, v_minfree,
+ r_align);
+ CHECK_ERROR(status)
+ }
+#endif
+
+ if (ncp->old != NULL) {
+ /* The current define mode was entered from ncmpi_redef, not from
+ * ncmpi_create. We must check if header has been expanded.
+ */
+
+ assert(!NC_IsNew(ncp));
+ assert(fIsSet(ncp->flags, NC_INDEF));
+ assert(ncp->begin_rec >= ncp->old->begin_rec);
+ assert(ncp->begin_var >= ncp->old->begin_var);
+ assert(ncp->vars.ndefined >= ncp->old->vars.ndefined);
+ /* ncp->numrecs has already sync-ed in ncmpi_redef */
+
+ if (ncp->vars.ndefined > 0) { /* no. record and non-record variables */
+ if (ncp->begin_var > ncp->old->begin_var) {
+ /* header size increases, shift the entire data part down */
+ /* shift record variables first */
+ status = move_recs_r(ncp, ncp->old);
+ CHECK_ERROR(status)
+
+ /* shift non-record variables */
+ /* status = move_vars_r(ncp, ncp->old); */
+ status = ncmpiio_move_fixed_vars(ncp, ncp->old);
+ CHECK_ERROR(status)
+ }
+ else if (ncp->begin_rec > ncp->old->begin_rec ||
+ ncp->recsize > ncp->old->recsize) {
+ /* number of non-record variables increases, or
+ number of records of record variables increases,
+ shift and move all record variables down */
+ status = move_recs_r(ncp, ncp->old);
+ CHECK_ERROR(status)
+ }
+ }
+ } /* ... ncp->old != NULL */
+
+ /* first sync header objects in memory across all processes, and then root
+ * writes the header to file. Note safe_mode error check is already done
+ * in write_NC() */
+ status = write_NC(ncp);
+
+ /* we should continue to exit define mode, even if header is inconsistent
+ * among processes, so the program can proceed, say to close file properly.
+ * However, if ErrIsHeaderDiff(status) is true, this error should
+ * be considered fatal, as inconsistency is about the data structure,
+ * rather then contents (such as attribute values) */
+
+#ifdef ENABLE_SUBFILING
+ /* write header to subfile */
+ if (ncp->nc_num_subfiles > 1) {
+ err = write_NC(ncp_sf);
+ if (status == NC_NOERR) status = err;
+ }
+#endif
+
+ /* update the total number of record variables */
+ ncp->vars.num_rec_vars = 0;
+ for (i=0; i<ncp->vars.ndefined; i++)
+ ncp->vars.num_rec_vars += IS_RECVAR(ncp->vars.value[i]);
+
+ /* fill variables according to their fill mode settings */
+ err = ncmpii_fill_vars(ncp);
+ if (status == NC_NOERR) status = err;
+
+ if (ncp->old != NULL) {
+ ncmpii_free_NC(ncp->old);
+ ncp->old = NULL;
+ }
+ fClr(ncp->flags, NC_CREAT | NC_INDEF);
+
+#ifdef ENABLE_SUBFILING
+ if (ncp->nc_num_subfiles > 1)
+ fClr(ncp_sf->flags, NC_CREAT | NC_INDEF);
+#endif
+
+ /* If the user sets NC_SHARE, we enforce a stronger data consistency */
+ if (NC_doFsync(ncp))
+ ncmpiio_sync(ncp->nciop); /* calling MPI_File_sync() */
+
+ return status;
+}
+
+/*----< ncmpii_inq_env_align_hints() >---------------------------------------*/
+/* check if environment variable PNETCDF_HINTS sets any of the following hints.
+ * nc_header_align_size if yes, set its value to h_align
+ * nc_var_align_size if yes, set its value to v_align
+ * nc_header_read_chunk_size if yes, set its value to h_chunk
+ * nc_record_align_size if yes, set its value to r_align
+ */
+static int
+ncmpii_inq_env_align_hints(MPI_Offset *h_align,
+ MPI_Offset *v_align,
+ MPI_Offset *h_chunk,
+ MPI_Offset *r_align)
+{
+ char *env_str=NULL, *hint_str;
+
+ *h_align = 0;
+ *v_align = 0;
+ *h_chunk = 0;
+ *r_align = 0;
+
+ env_str = getenv("PNETCDF_HINTS");
+ if (env_str != NULL) {
+ hint_str = strtok(env_str, ";");
+ while (hint_str != NULL) {
+ char key[128], *val;
+ strcpy(key, hint_str);
+ val = strchr(key, '=');
+ *val = '\0';
+ val++;
+ if (strcasecmp(key, "nc_header_align_size") == 0)
+ *h_align = atoll(val);
+ else if (strcasecmp(key, "nc_var_align_size") == 0)
+ *v_align = atoll(val);
+ else if (strcasecmp(key, "nc_header_read_chunk_size") == 0)
+ *h_chunk = atoll(val);
+ else if (strcasecmp(key, "nc_record_align_size") == 0)
+ *r_align = atoll(val);
+ hint_str = strtok(NULL, ";");
+ }
+ }
+ return 1;
+}
+
+/*----< ncmpii_enddef() >----------------------------------------------------*/
+int
+ncmpii_enddef(NC *ncp)
+{
+ int i, flag, striping_unit;
+ char value[MPI_MAX_INFO_VAL];
+ MPI_Offset h_align, v_align, r_align, all_var_size;
+ MPI_Offset env_h_align, env_v_align, env_h_chunk, env_r_align;
+
+ assert(!NC_readonly(ncp));
+ assert(NC_indef(ncp));
+
+ /* calculate a good align size for PnetCDF level hints:
+ * header_align_size and var_align_size based on the MPI-IO hint
+ * striping_unit. This hint can be either supplied by the user or obtained
+ * from MPI-IO (for example, ROMIO's Lustre driver makes a system call to
+ * get the striping parameters of a file).
+ */
+ MPI_Info_get(ncp->nciop->mpiinfo, "striping_unit", MPI_MAX_INFO_VAL-1,
+ value, &flag);
+ striping_unit = 0;
+ if (flag) striping_unit = atoi(value);
+ ncp->nciop->striping_unit = striping_unit;
+
+ all_var_size = 0; /* sum of all defined variables */
+ for (i=0; i<ncp->vars.ndefined; i++)
+ all_var_size += ncp->vars.value[i]->len;
+
+ /* check if any hints have been set in the environment variable
+ * PNETCDF_HINTS, as they will overwrite the ones set in the MPI_info
+ * provided in ncmpi_creat() or ncmpi_open() */
+ ncmpii_inq_env_align_hints(&env_h_align, &env_v_align, &env_h_chunk,
+ &env_r_align);
+
+ /* align file offsets for file header space and fixed variables.
+ These alignment hints have been extracted from the MPI_Info object when
+ ncmpi_create() is called.
+ */
+ h_align = (env_h_align == 0) ? ncp->nciop->hints.h_align : env_h_align;
+ v_align = (env_v_align == 0) ? ncp->nciop->hints.v_align : env_v_align;
+ r_align = (env_r_align == 0) ? ncp->nciop->hints.r_align : env_r_align;
+
+ if (h_align == 0) { /* user info does not set hint nc_header_align_size */
+ if (striping_unit &&
+ all_var_size > HEADER_ALIGNMENT_LB * striping_unit)
+ /* if striping_unit is available and file size sufficiently large */
+ h_align = striping_unit;
+ else
+ h_align = DEFAULT_ALIGNMENT;
+ }
+ /* else respect user hint */
+
+ if (v_align == 0) { /* user info does not set hint nc_var_align_size */
+ if (striping_unit &&
+ all_var_size > HEADER_ALIGNMENT_LB * striping_unit)
+ /* if striping_unit is available and file size sufficiently large */
+ v_align = striping_unit;
+ else
+ v_align = DEFAULT_ALIGNMENT;
+ }
+ /* else respect user hint */
+
+ if (r_align == 0) { /* user info does not set hint nc_record_align_size */
+ if (striping_unit)
+ r_align = striping_unit;
+ else
+ r_align = DEFAULT_ALIGNMENT;
+ }
+ /* else respect user hint */
+
+ return ncmpii_NC_enddef(ncp, h_align, 0, v_align, 0, r_align);
+}
+
+/*----< ncmpii__enddef() >---------------------------------------------------*/
+int
+ncmpii__enddef(NC *ncp,
+ MPI_Offset h_minfree,
+ MPI_Offset v_align,
+ MPI_Offset v_minfree,
+ MPI_Offset r_align)
+{
+ int i, flag, striping_unit;
+ char value[MPI_MAX_INFO_VAL];
+ MPI_Offset h_align, all_var_size;
+ MPI_Offset env_h_align, env_v_align, env_h_chunk, env_r_align;
+
+ assert(!NC_readonly(ncp));
+ assert(NC_indef(ncp));
+
+ /* calculate a good align size for PnetCDF level hints:
+ * header_align_size and var_align_size based on the MPI-IO hint
+ * striping_unit. This hint can be either supplied by the user or obtained
+ * from MPI-IO (for example, ROMIO's Lustre driver makes a system call to
+ * get the striping parameters of a file).
+ */
+ MPI_Info_get(ncp->nciop->mpiinfo, "striping_unit", MPI_MAX_INFO_VAL-1,
+ value, &flag);
+ striping_unit = 0;
+ if (flag) striping_unit = atoi(value);
+ ncp->nciop->striping_unit = striping_unit;
+
+ all_var_size = 0; /* sum of all defined variables */
+ for (i=0; i<ncp->vars.ndefined; i++)
+ all_var_size += ncp->vars.value[i]->len;
+
+ /* check if any hints have been set in the environment variable
+ * PNETCDF_HINTS, as they will overwrite the ones passed in this function
+ * and those passed-in alignment values will overwrite the ones set in the
+ * MPI_info provided in ncmpi_creat() or ncmpi_open() */
+ ncmpii_inq_env_align_hints(&env_h_align, &env_v_align, &env_h_chunk,
+ &env_r_align);
+
+ /* align file offsets for file header space and fixed variables */
+ h_align = (env_h_align == 0) ? ncp->nciop->hints.h_align : env_h_align;
+ v_align = (env_v_align == 0) ? v_align : env_v_align;
+ r_align = (env_r_align == 0) ? r_align : env_r_align;
+
+ if (v_align == 0) /* 0 means let PnetCDF decide, 1 means no align */
+ v_align = ncp->nciop->hints.v_align;
+
+ if (r_align == 0) /* 0 means let PnetCDF decide, 1 means no align */
+ r_align = ncp->nciop->hints.r_align;
+
+ if (h_align == 0) { /* user does not set hint nc_header_align_size */
+ if (striping_unit &&
+ all_var_size > HEADER_ALIGNMENT_LB * striping_unit)
+ /* if striping_unit is available and file size sufficiently large */
+ h_align = striping_unit;
+ else
+ h_align = DEFAULT_ALIGNMENT;
+ }
+ /* else respect user hint */
+
+ if (v_align == 0) { /* user does not set hint nc_var_align_size */
+ if (striping_unit &&
+ all_var_size > HEADER_ALIGNMENT_LB * striping_unit)
+ /* if striping_unit is available and file size sufficiently large */
+ v_align = striping_unit;
+ else
+ v_align = DEFAULT_ALIGNMENT;
+ }
+ /* else respect user hint */
+
+ if (r_align == 0) { /* user does not set hint nc_record_align_size */
+ if (striping_unit)
+ r_align = striping_unit;
+ else
+ r_align = DEFAULT_ALIGNMENT;
+ }
+ /* else respect user hint */
+
+ return ncmpii_NC_enddef(ncp, h_align, h_minfree, v_align, v_minfree,
+ r_align);
+}
+
+/*----< ncmpii_close() >------------------------------------------------------*/
+/* This function is collective */
+int
+ncmpii_close(NC *ncp)
+{
+ int num_reqs, err, status=NC_NOERR, *req_ids=NULL, *statuses=NULL;
+ NC_req *cur_req;
+
+ if (NC_indef(ncp)) { /* currently in define mode */
+ status = ncmpii_enddef(ncp); /* TODO: defaults */
+ if (status != NC_NOERR ) {
+ /* To do: Abort new definition, if any */
+ if (ncp->old != NULL) {
+ ncmpii_free_NC(ncp->old);
+ ncp->old = NULL;
+ fClr(ncp->flags, NC_INDEF);
+ }
+ }
+ }
+
+ if (!NC_readonly(ncp) && /* file is open for write */
+ NC_indep(ncp)) { /* exit independent data mode will sync header */
+ err = ncmpii_end_indep_data(ncp);
+ if (status == NC_NOERR ) status = err;
+ }
+
+ /* if entering this function in collective data mode, we do not have to
+ * update header in file, as file header is always up-to-date */
+
+#ifdef ENABLE_SUBFILING
+ /* ncmpii_enddef() will update nc_num_subfiles */
+ /* TODO: should check ncid_sf? */
+ /* if the file has subfiles, close them first */
+ if (ncp->nc_num_subfiles > 1)
+ ncmpii_subfile_close(ncp);
+#endif
+
+ /* cancel or complete all outstanding nonblocking I/O */
+ num_reqs = 0;
+ cur_req = ncp->head;
+ while (cur_req != NULL) {
+ num_reqs++;
+ cur_req = cur_req->next;
+ }
+ if (num_reqs > 0) { /* fill in req_ids[] */
+ req_ids = (int*) NCI_Malloc((size_t)num_reqs * 2 * SIZEOF_INT);
+ statuses = req_ids + num_reqs;
+ num_reqs = 0;
+ cur_req = ncp->head;
+ while (cur_req != NULL) {
+ req_ids[num_reqs++] = cur_req->id;
+ cur_req = cur_req->next;
+ }
+#ifdef COMPLETE_NONBLOCKING_IO
+ ncmpii_wait(ncp, COLL_IO, num_reqs, req_ids, statuses);
+#else
+ ncmpii_cancel(ncp, num_reqs, req_ids, statuses);
+#endif
+ NCI_Free(req_ids);
+ }
+
+ /* If the user wants a stronger data consistency by setting NC_SHARE */
+ if (fIsSet(ncp->nciop->ioflags, NC_SHARE))
+ ncmpiio_sync(ncp->nciop); /* calling MPI_File_sync() */
+
+ /* calling MPI_File_close() */
+ ncmpiio_close(ncp->nciop, 0);
+ ncp->nciop = NULL;
+
+ /* remove this file from the list of opened files */
+ ncmpii_del_from_NCList(ncp);
+
+ /* free up space occupied by the header metadata */
+ ncmpii_free_NC(ncp);
+
+ return status;
+}
+
+/* Public */
+
+int
+ncmpi_inq(int ncid,
+ int *ndimsp,
+ int *nvarsp,
+ int *nattsp,
+ int *xtendimp)
+{
+ int status;
+ NC *ncp;
+
+ status = ncmpii_NC_check_id(ncid, &ncp);
+ if (status != NC_NOERR)
+ return status;
+
+ if (ndimsp != NULL)
+ *ndimsp = (int) ncp->dims.ndefined;
+ if (nvarsp != NULL)
+ *nvarsp = (int) ncp->vars.ndefined;
+ if (nattsp != NULL)
+ *nattsp = (int) ncp->attrs.ndefined;
+ if (xtendimp != NULL)
+ *xtendimp = ncmpii_find_NC_Udim(&ncp->dims, NULL);
+
+ return NC_NOERR;
+}
+
+/*----< ncmpi_inq_version() >-----------------------------------------------*/
+int
+ncmpi_inq_version(int ncid, int *nc_mode)
+{
+ int status;
+ NC *ncp;
+
+ status = ncmpii_NC_check_id(ncid, &ncp);
+ if (status != NC_NOERR)
+ return status;
+
+ if (fIsSet(ncp->flags, NC_64BIT_DATA))
+ *nc_mode = NC_64BIT_DATA;
+ else if (fIsSet(ncp->flags, NC_64BIT_OFFSET))
+ *nc_mode = NC_64BIT_OFFSET;
+ else
+ *nc_mode = NC_CLASSIC_MODEL;
+
+ return NC_NOERR;
+}
+
+
+int
+ncmpi_inq_ndims(int ncid, int *ndimsp)
+{
+ int status;
+ NC *ncp;
+
+ status = ncmpii_NC_check_id(ncid, &ncp);
+ if (status != NC_NOERR) return status;
+
+ if (ndimsp != NULL)
+ *ndimsp = (int) ncp->dims.ndefined;
+
+ return NC_NOERR;
+}
+
+int
+ncmpi_inq_nvars(int ncid, int *nvarsp)
+{
+ int status;
+ NC *ncp;
+
+ status = ncmpii_NC_check_id(ncid, &ncp);
+ if (status != NC_NOERR) return status;
+
+ if (nvarsp != NULL)
+ *nvarsp = (int) ncp->vars.ndefined;
+
+ return NC_NOERR;
+}
+
+int
+ncmpi_inq_natts(int ncid, int *nattsp)
+{
+ int status;
+ NC *ncp;
+
+ status = ncmpii_NC_check_id(ncid, &ncp);
+ if (status != NC_NOERR) return status;
+
+ if (nattsp != NULL)
+ *nattsp = (int) ncp->attrs.ndefined;
+
+ return NC_NOERR;
+}
+
+int
+ncmpi_inq_unlimdim(int ncid, int *xtendimp)
+{
+ int status;
+ NC *ncp;
+
+ status = ncmpii_NC_check_id(ncid, &ncp);
+ if (status != NC_NOERR) return status;
+
+ if (xtendimp != NULL)
+ *xtendimp = ncmpii_find_NC_Udim(&ncp->dims, NULL);
+
+ return NC_NOERR;
+}
+
+/*----< ncmpi_inq_num_rec_vars() >-------------------------------------------*/
+int
+ncmpi_inq_num_rec_vars(int ncid, int *nvarsp)
+{
+ int i, status;
+ NC *ncp;
+
+ /* get ncp object */
+ status = ncmpii_NC_check_id(ncid, &ncp);
+ if (status != NC_NOERR)
+ return status;
+
+ if (nvarsp != NULL) {
+ if (NC_indef(ncp)) {
+ /* if in define mode, recalculate the number of record variables */
+ *nvarsp = 0;
+ for (i=0; i<ncp->vars.ndefined; i++)
+ *nvarsp += IS_RECVAR(ncp->vars.value[i]);
+ }
+ else
+ *nvarsp = ncp->vars.num_rec_vars;
+ }
+
+ return NC_NOERR;
+}
+
+/*----< ncmpi_inq_num_fix_vars() >-------------------------------------------*/
+int
+ncmpi_inq_num_fix_vars(int ncid, int *nvarsp)
+{
+ int i, status;
+ NC *ncp;
+
+ /* get ncp object */
+ status = ncmpii_NC_check_id(ncid, &ncp);
+ if (status != NC_NOERR)
+ return status;
+
+ if (nvarsp != NULL) {
+ if (NC_indef(ncp)) {
+ /* if in define mode, recalculate the number of record variables */
+ *nvarsp = 0;
+ for (i=0; i<ncp->vars.ndefined; i++)
+ *nvarsp += IS_RECVAR(ncp->vars.value[i]);
+ }
+ else
+ *nvarsp = ncp->vars.num_rec_vars;
+
+ /* no. fixed-size == ndefined - no. record variables */
+ *nvarsp = ncp->vars.ndefined- *nvarsp;
+ }
+
+ return NC_NOERR;
+}
+
diff --git a/src/lib/nc.h b/src/lib/nc.h
new file mode 100644
index 0000000..2c322d9
--- /dev/null
+++ b/src/lib/nc.h
@@ -0,0 +1,939 @@
+/*
+ * Copyright (C) 2003, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ */
+/* $Id: nc.h 2299 2016-01-09 06:14:37Z wkliao $ */
+#ifndef _NC_H_
+#define _NC_H_
+
+/*
+ * netcdf library 'private' data structures, objects and interfaces
+ */
+
+#include <stddef.h> /* size_t */
+#include <sys/types.h> /* off_t */
+
+#include "ncio.h" /* ncio */
+#include "fbits.h"
+
+/* for put request less than 4KB, copy it to a buffer and do byte swap there,
+ * so if the user buffer is immutable (assuming smaller than 4KB), it will not
+ * cause seg fault. Not a perfect solution, but should be sufficient for most
+ * of the cases.
+ */
+#define NC_BYTE_SWAP_BUFFER_SIZE 4096
+
+/* define MPI_OFFSET if not defined */
+#ifndef HAVE_MPI_OFFSET_DATATYPE
+ #ifdef HAVE_MPI_LONG_LONG_INT
+ #define MPI_OFFSET MPI_LONG_LONG_INT
+ #else
+ #define MPI_OFFSET MPI_INT
+ #endif
+#endif
+
+enum API_KIND {
+ API_VARD, /* do not check start and count, no flexible APIs */
+ API_VARN, /* do not check start and count */
+ API_VAR, /* do not check start and count */
+ API_VAR1, /* check start */
+ API_VARA, /* check start and count */
+ API_VARS, /* check start and count */
+ API_VARM /* check start and count */
+};
+
+#define WRITE_REQ 0
+#define READ_REQ 1
+
+#define INDEP_IO 0
+#define COLL_IO 1
+#define NONBLOCKING_IO -1
+
+/* C macros for TRACE MPI calls */
+#ifdef PNETCDF_TRACE_MPI_COMM
+#define TRACE_COMM(x) printf("TRACE-MPI-COMM: FILE %s FUNC %s() LINE %d calling %s()\n",__FILE__,__func__,__LINE__,#x),mpireturn=x
+#else
+#define TRACE_COMM(x) mpireturn=x
+#endif
+
+#ifdef PNETCDF_TRACE_MPI_IO
+#define TRACE_IO(x) printf("TRACE-MPI-IO: FILE %s FUNC %s() LINE %d calling %s()\n",__FILE__,__func__,__LINE__,#x),mpireturn=x
+#else
+#define TRACE_IO(x) mpireturn=x
+#endif
+
+
+/* XXX: this seems really low. do we end up spending a ton of time mallocing?
+ * could we reduce that by increasing this to something 21st century? */
+#ifndef NC_ARRAY_GROWBY
+#define NC_ARRAY_GROWBY 4
+#endif
+
+/* ncmpi_create/ncmpi_open set up header to be 'chunksize' big and to grow
+ * by 'chunksize' as new items adde. This used to be 4k. 256k lets us read
+ * in an entire climate header in one go */
+#define NC_DEFAULT_CHUNKSIZE 262144
+
+/* when variable's nctype is NC_CHAR, I/O buffer's MPI type must be MPI_CHAR
+ * and vice versa */
+#define NCMPII_ECHAR(nctype, mpitype) ((((nctype) == NC_CHAR) == ((mpitype) != MPI_CHAR)) ? NC_ECHAR : NC_NOERR)
+
+/*
+ * The extern size of an empty
+ * netcdf version 1 file.
+ * The initial value of ncp->xsz.
+ */
+#define MIN_NC_XSZ 32
+
+/* netcdf file format:
+ netcdf_file = header data
+ header = magic numrecs dim_list gatt_list var_list
+ magic = 'C' 'D' 'F' VERSION
+ VERSION = \x01 | \x02 | \x05
+ numrecs = NON_NEG | STREAMING
+ dim_list = ABSENT | NC_DIMENSION nelems [dim ...]
+ gatt_list = att_list
+ att_list = ABSENT | NC_ATTRIBUTE nelems [attr ...]
+ var_list = ABSENT | NC_VARIABLE nelems [var ...]
+ ABSENT = ZERO ZERO // Means list is not present
+ ZERO = \x00 \x00 \x00 \x00 // 32-bit zero
+
+ Minimum happens when nothing is defined, i.e.
+ magic -- 4 bytes
+ numrecs -- 4 bytes for CDF-1 and CDF-2, 8 bytes for CDF-5
+ dim_list = ABSENT -- 8 bytes
+ gatt_list = ABSENT -- 8 bytes
+ var_list = ABSENT -- 8 bytes
+*/
+
+typedef struct NC NC; /* forward reference */
+
+/*
+ * The internal data types
+ */
+typedef enum {
+ NC_UNSPECIFIED = 0,
+/* NC_BITFIELD = 7, */
+/* NC_STRING = 8, */
+ NC_DIMENSION = 10,
+ NC_VARIABLE = 11,
+ NC_ATTRIBUTE = 12
+} NCtype;
+
+
+/*
+ * Counted string for names and such
+ */
+typedef struct {
+ /* all xdr'd */
+ MPI_Offset nchars;
+ char *cp; /* [nchars+1] one additional char for '\0' */
+} NC_string;
+
+extern NC *
+ncmpii_new_NC(const MPI_Offset *chunkp);
+
+extern NC *
+ncmpii_dup_NC(const NC *ref);
+
+/* Begin defined in string.c */
+extern void
+ncmpii_free_NC_string(NC_string *ncstrp);
+
+extern int
+ncmpii_NC_check_name(const char *name, int file_ver);
+
+extern NC_string *
+ncmpii_new_NC_string(size_t slen, const char *str);
+
+extern int
+ncmpii_set_NC_string(NC_string *ncstrp, const char *str);
+
+/* End defined in string.c */
+
+/*
+ * NC dimension structure
+ */
+typedef struct {
+ /* all xdr'd */
+ NC_string *name;
+ MPI_Offset size;
+#ifdef ENABLE_SUBFILING
+ int range[2]; /* subfile range {start, end} */
+ MPI_Offset rcount; /* subfile range count */
+ int num_subfiles;
+#endif
+} NC_dim;
+
+/* the dimension ID returned from ncmpi_def_dim() is an integer pointer
+ * which means the total number of defined dimension allowed in a file
+ * is up to 2^31-1. Thus, the member ndefined below should be of type int.
+ */
+typedef struct NC_dimarray {
+ int nalloc; /* number allocated >= ndefined */
+ int ndefined; /* number of defined dimensions */
+ NC_dim **value;
+} NC_dimarray;
+
+/* Begin defined in dim.c */
+
+extern void
+ncmpii_free_NC_dim(NC_dim *dimp);
+
+extern NC_dim *
+ncmpii_new_x_NC_dim(NC_string *name);
+
+extern int
+ncmpii_find_NC_Udim(const NC_dimarray *ncap, NC_dim **dimpp);
+
+extern int
+incr_NC_dimarray(NC_dimarray *ncap, NC_dim *newdimp);
+
+extern NC_dim*
+dup_NC_dim(const NC_dim *dimp);
+
+/* dimarray */
+
+extern void
+ncmpii_free_NC_dimarray(NC_dimarray *ncap);
+
+extern int
+ncmpii_dup_NC_dimarray(NC_dimarray *ncap, const NC_dimarray *ref);
+
+extern NC_dim *
+ncmpii_elem_NC_dimarray(const NC_dimarray *ncap, int elem);
+
+extern int
+ncmpi_def_dim(int ncid, const char *name, MPI_Offset size, int *dimidp);
+
+extern int
+ncmpi_rename_dim( int ncid, int dimid, const char *newname);
+
+extern int
+ncmpi_inq_dimid(int ncid, const char *name, int *dimid_ptr);
+
+extern int
+ncmpi_inq_dim(int ncid, int dimid, char *name, MPI_Offset *sizep);
+
+extern int
+ncmpi_inq_dimname(int ncid, int dimid, char *name);
+
+extern int
+ncmpi_inq_dimlen(int ncid, int dimid, MPI_Offset *lenp);
+/* End defined in dim.c */
+
+/*
+ * NC attribute
+ *
+ * Number of attributes is limited by 2^31-1 because the argument attnump in
+ * int nc_inq_attid(int ncid, int varid, const char *name, int *attnump);
+ * is a signed 4-byte integer.
+ */
+typedef struct {
+ MPI_Offset xsz; /* amount of space at xvalue (4-byte aligned) */
+ NC_string *name; /* name of the attributes */
+ nc_type type; /* the discriminant */
+ MPI_Offset nelems; /* number of attribute elements */
+ void *xvalue; /* the actual data, in external representation */
+} NC_attr;
+
+typedef struct NC_attrarray {
+ int nalloc; /* number allocated >= ndefined */
+ int ndefined; /* number of defined attributes */
+ NC_attr **value;
+} NC_attrarray;
+
+/* Begin defined in attr.c */
+
+extern void
+ncmpii_free_NC_attr(NC_attr *attrp);
+
+extern NC_attr *
+ncmpii_new_x_NC_attr(NC_string *strp, nc_type type, MPI_Offset nelems);
+
+extern int
+incr_NC_attrarray(NC_attrarray *ncap, NC_attr *newelemp);
+
+extern NC_attr*
+dup_NC_attr(const NC_attr *rattrp);
+
+extern int
+ncmpii_NC_findattr(const NC_attrarray *ncap, const char *uname);
+
+/* attrarray */
+
+extern void
+ncmpii_free_NC_attrarray(NC_attrarray *ncap);
+
+extern int
+ncmpii_dup_NC_attrarray(NC_attrarray *ncap, const NC_attrarray *ref);
+
+extern NC_attr *
+ncmpii_elem_NC_attrarray(const NC_attrarray *ncap, MPI_Offset elem);
+
+extern int
+ncmpi_put_att_text(int ncid, int varid, const char *name,
+ MPI_Offset nelems, const char *value);
+
+extern int
+ncmpi_get_att_text(int ncid, int varid, const char *name, char *str);
+
+extern int
+ncmpi_put_att_schar(int ncid, int varid, const char *name,
+ nc_type type, MPI_Offset nelems, const signed char *value);
+
+extern int
+ncmpi_get_att_schar(int ncid, int varid, const char *name, signed char *tp);
+
+extern int
+ncmpi_put_att_uchar(int ncid, int varid, const char *name,
+ nc_type type, MPI_Offset nelems, const unsigned char *value);
+
+extern int
+ncmpi_get_att_uchar(int ncid, int varid, const char *name, unsigned char *tp);
+
+extern int
+ncmpi_put_att_short(int ncid, int varid, const char *name,
+ nc_type type, MPI_Offset nelems, const short *value);
+
+extern int
+ncmpi_get_att_short(int ncid, int varid, const char *name, short *tp);
+
+extern int
+ncmpi_put_att_int(int ncid, int varid, const char *name,
+ nc_type type, MPI_Offset nelems, const int *value);
+
+extern int
+ncmpi_get_att_int(int ncid, int varid, const char *name, int *tp);
+
+extern int
+ncmpi_put_att_long(int ncid, int varid, const char *name,
+ nc_type type, MPI_Offset nelems, const long *value);
+
+extern int
+ncmpi_get_att_long(int ncid, int varid, const char *name, long *tp);
+
+extern int
+ncmpi_put_att_float(int ncid, int varid, const char *name,
+ nc_type type, MPI_Offset nelems, const float *value);
+extern int
+ncmpi_get_att_float(int ncid, int varid, const char *name, float *tp);
+extern int
+ncmpi_put_att_double(int ncid, int varid, const char *name,
+ nc_type type, MPI_Offset nelems, const double *value);
+extern int
+ncmpi_get_att_double(int ncid, int varid, const char *name, double *tp);
+
+extern int
+ncmpi_inq_attid(int ncid, int varid, const char *name, int *attnump);
+
+extern int
+ncmpi_inq_atttype(int ncid, int varid, const char *name, nc_type *datatypep);
+
+extern int
+ncmpi_inq_attlen(int ncid, int varid, const char *name, MPI_Offset *lenp);
+
+extern int
+ncmpi_inq_att(int ncid, int varid, const char *name,
+ nc_type *datatypep, MPI_Offset *lenp);
+
+extern int
+ncmpi_copy_att(int ncid_in, int varid_in, const char *name,
+ int ncid_out, int ovarid);
+
+extern int
+ncmpi_rename_att( int ncid, int varid, const char *name, const char *newname);
+
+extern int
+ncmpi_del_att(int ncid, int varid, const char *name);
+
+extern int
+ncmpi_inq_attname(int ncid, int varid, int attnum, char *name);
+/* End defined in attr.c */
+
+/*
+ * NC variable: description and data
+ */
+typedef struct {
+ int xsz; /* byte size of 1 array element */
+ MPI_Offset *shape; /* dim->size of each dim */
+ MPI_Offset *dsizes; /* the right to left product of shape */
+ NC_string *name; /* name of the variable */
+ int ndims; /* number of dimensions */
+ int *dimids; /* array of dimension IDs */
+ NC_attrarray attrs; /* attribute array */
+ nc_type type; /* variable's data type */
+ MPI_Offset len; /* this is the "vsize" defined in header format, the
+ total size in bytes of the array variable.
+ For record variable, this is the record size */
+ MPI_Offset begin; /* starting file offset of this variable */
+ int no_fill;
+#ifdef ENABLE_SUBFILING
+ int ndims_org; /* ndims before subfiling */
+ int *dimids_org; /* dimids before subfiling */
+ int num_subfiles;
+#endif
+} NC_var;
+
+/* note: we only allow less than 2^31-1 variables defined in a file */
+typedef struct NC_vararray {
+ int nalloc; /* number allocated >= ndefined */
+ int ndefined; /* number of defined variables */
+ int num_rec_vars;/* number of defined record variables */
+ NC_var **value;
+} NC_vararray;
+
+/* Begin defined in var.c */
+
+extern void
+ncmpii_free_NC_var(NC_var *varp);
+
+extern NC_var *
+ncmpii_new_x_NC_var(NC_string *strp, int ndims);
+
+extern NC_var*
+dup_NC_var(const NC_var *rvarp);
+
+extern int
+incr_NC_vararray(NC_vararray *ncap, NC_var *newvarp);
+
+/* vararray */
+
+extern void
+ncmpii_free_NC_vararray(NC_vararray *ncap);
+
+extern int
+ncmpii_dup_NC_vararray(NC_vararray *ncap, const NC_vararray *ref);
+
+extern int
+ncmpii_NC_var_shape64(NC *ncp, NC_var *varp, const NC_dimarray *dims);
+
+extern int
+ncmpii_NC_check_vlen(NC_var *varp, MPI_Offset vlen_max);
+
+extern int
+ncmpii_NC_lookupvar(NC *ncp, int varid, NC_var **varp);
+
+extern int
+ncmpi_def_var(int ncid, const char *name, nc_type type,
+ int ndims, const int *dimidsp, int *varidp);
+
+extern int
+ncmpi_rename_var(int ncid, int varid, const char *newname);
+
+extern int
+ncmpi_inq_var(int ncid, int varid, char *name, nc_type *typep,
+ int *ndimsp, int *dimids, int *nattsp);
+
+extern int
+ncmpi_inq_varid(int ncid, const char *name, int *varid_ptr);
+
+extern int
+ncmpi_inq_varname(int ncid, int varid, char *name);
+
+extern int
+ncmpi_inq_vartype(int ncid, int varid, nc_type *typep);
+
+extern int
+ncmpi_inq_varndims(int ncid, int varid, int *ndimsp);
+
+extern int
+ncmpi_inq_vardimid(int ncid, int varid, int *dimids);
+
+extern int
+ncmpi_inq_varnatts(int ncid, int varid, int *nattsp);
+
+extern int
+ncmpi_rename_var(int ncid, int varid, const char *newname);
+/* End defined in var.c */
+
+#define IS_RECVAR(vp) \
+ ((vp)->shape != NULL ? (*(vp)->shape == NC_UNLIMITED) : 0 )
+
+/*
+ * The PnetCDF non-blocking I/O request type
+ */
+typedef struct NC_req {
+ int id;
+ int rw_flag;
+ void *buf; /* the original user buffer */
+ void *xbuf; /* the buffer used to read/write, may point to
+ the same address as buf */
+ int buftype_is_contig;
+ int need_swap_back_buf;
+ int abuf_index; /* index in the abuf occupy_table
+ -1 means not using attached buffer */
+
+ void *tmpBuf; /* tmp buffer to be freed, used only by
+ nonblocking varn when buftype is noncontig */
+ void *userBuf; /* user buffer to be unpacked from tmpBuf. used
+ only by by nonblocking varn when buftype is
+ noncontig */
+ NC_var *varp;
+ MPI_Offset *start; /* [varp->ndims] */
+ MPI_Offset *count; /* [varp->ndims] */
+ MPI_Offset *stride; /* [varp->ndims] */
+ MPI_Offset bnelems; /* number of elements in user buffer */
+ MPI_Offset offset_start; /* starting of aggregate access region */
+ MPI_Offset offset_end; /* ending of aggregate access region */
+ MPI_Offset bufcount; /* the number of buftype in this request */
+ MPI_Datatype buftype; /* user defined derived data type */
+ MPI_Datatype ptype; /* element data type in buftype */
+ MPI_Datatype imaptype; /* derived data type constructed from imap */
+ int *status; /* pointer to user's status */
+ int num_subreqs; /* each record is a subrequest */
+ struct NC_req *subreqs; /* [num_subreq] */
+ struct NC_req *next;
+} NC_req;
+
+#define NC_ABUF_DEFAULT_TABLE_SIZE 128
+
+typedef struct NC_buf_status {
+ int is_used;
+ MPI_Aint buf_addr;
+ MPI_Offset req_size;
+} NC_buf_status;
+
+typedef struct NC_buf {
+ MPI_Offset size_allocated;
+ MPI_Offset size_used;
+ int table_size;
+ NC_buf_status *occupy_table; /* [table_size] */
+ int tail; /* index of last free entry */
+ void *buf;
+} NC_buf;
+
+struct NC {
+ /* linked list of currently opened netcdf files */
+ struct NC *next;
+ struct NC *prev;
+#ifdef ENABLE_SUBFILING
+ int nc_num_subfiles; /* # of subfiles */
+ int ncid_sf; /* ncid of subfile */
+#endif
+ /* contains the previous NC during redef. */
+ struct NC *old;
+ /* flags */
+#define NC_INDEP 0x10000 /* in independent data mode, cleared by endindep */
+#define NC_CREAT 0x20000 /* in create phase, cleared by ncenddef */
+#define NC_INDEF 0x80000 /* in define mode, cleared by ncenddef */
+#define NC_NSYNC 0x100000 /* synchronise numrecs on change */
+#define NC_HSYNC 0x200000 /* synchronise whole header on change */
+#define NC_NDIRTY 0x400000 /* numrecs has changed */
+#define NC_HDIRTY 0x800000 /* header info has changed */
+/* NC_NOFILL is defined in netcdf.h, historical interface */
+ int flags;
+ int safe_mode; /* 0 or 1, for parameter consistency check */
+ int subfile_mode; /* 0 or 1, for disable/enable subfiling */
+ ncio *nciop;
+ MPI_Offset chunk; /* largest extent this layer will request from
+ ncio->get() */
+ MPI_Offset xsz; /* external size of this header, <= var[0].begin */
+ MPI_Offset begin_var;/* file offset of the first (non-record) var */
+ MPI_Offset begin_rec;/* file offset of the first 'record' */
+
+ MPI_Offset recsize; /* length of 'record': sum of single record sizes
+ of all the record variables */
+ MPI_Offset numrecs; /* number of 'records' allocated */
+ NC_dimarray dims; /* dimensions defined */
+ NC_attrarray attrs; /* global attributes defined */
+ NC_vararray vars; /* variables defined */
+ NC_req *head; /* linked list head of nonblocking requests */
+ NC_req *tail; /* tail of the linked list */
+ NC_buf *abuf; /* attached buffer, used by bput APIs */
+};
+
+#define NC_readonly(ncp) \
+ (!fIsSet((ncp)->nciop->ioflags, NC_WRITE))
+
+#define NC_IsNew(ncp) \
+ fIsSet((ncp)->flags, NC_CREAT)
+
+#define NC_indep(ncp) \
+ fIsSet((ncp)->flags, NC_INDEP)
+
+#define NC_indef(ncp) \
+ (NC_IsNew(ncp) || fIsSet((ncp)->flags, NC_INDEF))
+
+#define set_NC_ndirty(ncp) \
+ fSet((ncp)->flags, NC_NDIRTY)
+
+#define NC_ndirty(ncp) \
+ fIsSet((ncp)->flags, NC_NDIRTY)
+
+#define set_NC_hdirty(ncp) \
+ fSet((ncp)->flags, NC_HDIRTY)
+
+#define NC_hdirty(ncp) \
+ fIsSet((ncp)->flags, NC_HDIRTY)
+
+#define NC_dofill(ncp) \
+ (!fIsSet((ncp)->flags, NC_NOFILL))
+
+#define NC_doFsync(ncp) \
+ fIsSet((ncp)->nciop->ioflags, NC_SHARE)
+
+#define NC_doHsync(ncp) \
+ fIsSet((ncp)->flags, NC_HSYNC)
+
+#define NC_doNsync(ncp) \
+ fIsSet((ncp)->flags, NC_NSYNC)
+
+#define NC_get_numrecs(ncp) \
+ ((ncp)->numrecs)
+
+#define NC_set_numrecs(ncp, nrecs) \
+ {((ncp)->numrecs = (nrecs));}
+
+#define NC_increase_numrecs(ncp, nrecs) \
+ {if((nrecs) > (ncp)->numrecs) ((ncp)->numrecs = (nrecs));}
+
+#define ErrIsHeaderDiff(err) \
+ (NC_EMULTIDEFINE_FIRST >= (err) && (err) >= NC_EMULTIDEFINE_LAST)
+
+#define IsPrimityMPIType(buftype) (buftype == MPI_FLOAT || \
+ buftype == MPI_DOUBLE || \
+ buftype == MPI_INT || \
+ buftype == MPI_CHAR || \
+ buftype == MPI_SIGNED_CHAR || \
+ buftype == MPI_UNSIGNED_CHAR || \
+ buftype == MPI_SHORT || \
+ buftype == MPI_UNSIGNED_SHORT || \
+ buftype == MPI_UNSIGNED || \
+ buftype == MPI_LONG || \
+ buftype == MPI_LONG_LONG_INT || \
+ buftype == MPI_UNSIGNED_LONG_LONG)
+
+/* Begin defined in nc.c */
+
+extern int
+ncmpii_NC_check_id(int ncid, NC **ncpp);
+
+extern int
+ncmpii_cktype(int cdf_ver, nc_type datatype);
+
+extern MPI_Offset
+ncmpix_howmany(nc_type type, MPI_Offset xbufsize);
+
+extern int
+ncmpii_dset_has_recvars(NC *ncp);
+
+extern int
+ncmpii_write_header(NC *ncp);
+
+extern void
+ncmpii_free_NC(NC *ncp);
+
+extern void
+ncmpii_add_to_NCList(NC *ncp);
+
+extern void
+ncmpii_del_from_NCList(NC *ncp);
+
+extern int
+ncmpii_read_NC(NC *ncp);
+
+extern int
+ncmpii_enddef(NC *ncp);
+
+extern int
+ncmpii__enddef(NC *ncp, MPI_Offset h_minfree, MPI_Offset v_align,
+ MPI_Offset v_minfree, MPI_Offset r_align);
+
+extern int
+ncmpii_close(NC *ncp);
+
+extern int
+ncmpi_inq(int ncid, int *ndimsp, int *nvarsp, int *nattsp, int *xtendimp);
+
+extern int
+ncmpi_inq_ndims(int ncid, int *ndimsp);
+
+extern int
+ncmpi_inq_nvars(int ncid, int *nvarsp);
+
+extern int
+ncmpi_inq_natts(int ncid, int *nattsp);
+
+extern int
+ncmpi_inq_unlimdim(int ncid, int *xtendimp);
+
+extern int
+ncmpi_get_default_format(void);
+
+extern int
+ncmpi_inq_num_rec_vars(int ncid, int *nump);
+
+extern int
+ncmpi_inq_num_fix_vars(int ncid, int *nump);
+
+/* End defined in nc.c */
+
+#if 0
+/* Begin defined in v1hpg.c */
+
+extern size_t
+ncx_len_NC(const NC *ncp, MPI_Offset sizeof_off_t);
+
+extern int
+ncx_put_NC(const NC *ncp, void **xpp, MPI_Offset offset, MPI_Offset extent);
+
+extern int
+nc_get_NC( NC *ncp);
+
+/* End defined in v1hpg.c */
+
+/* Begin defined in putget.c */
+
+extern int
+ncmpii_fill_NC_var(NC *ncp, const NC_var *varp, MPI_Offset recno);
+
+extern int
+ncmpii_inq_rec(int ncid, MPI_Offset *nrecvars, MPI_Offset *recvarids, MPI_Offset *recsizes);
+
+extern int
+ncmpii_get_rec(int ncid, MPI_Offset recnum, void **datap);
+
+extern int
+ncmpii_put_rec(int ncid, MPI_Offset recnum, void *const *datap);
+#endif
+
+/* End defined in putget.c */
+
+/* Begin defined in header.c */
+typedef struct bufferinfo {
+ ncio *nciop;
+ MPI_Offset offset; /* current read/write offset in the file */
+ int version; /* 1, 2, and 5 for CDF-1, 2, and 5 respectively */
+ int safe_mode;/* 0: disabled, 1: enabled */
+ void *base; /* beginning of read/write buffer */
+ void *pos; /* current position in buffer */
+ MPI_Offset size; /* size of the buffer */
+ MPI_Offset index; /* index of current position in buffer */
+ MPI_Offset put_size; /* amount of writes so far in bytes */
+ MPI_Offset get_size; /* amount of reads so far in bytes */
+} bufferinfo;
+
+extern int
+ncmpix_len_nctype(nc_type type);
+
+#if 0
+extern int
+hdr_put_NC_attrarray(bufferinfo *pbp, const NC_attrarray *ncap);
+#endif
+
+extern MPI_Offset
+ncmpii_hdr_len_NC(const NC *ncp);
+
+extern int
+ncmpii_hdr_get_NC(NC *ncp);
+
+extern int
+ncmpii_hdr_put_NC(NC *ncp, void *buf);
+
+extern int
+ncmpii_NC_computeshapes(NC *ncp);
+
+extern int
+ncmpii_hdr_check_NC(bufferinfo *getbuf, NC *ncp);
+/* end defined in header.c */
+
+/* begin defined in mpincio.c */
+extern int
+ncmpiio_create(MPI_Comm comm, const char *path, int ioflags, MPI_Info info,
+ NC *ncp);
+
+extern int
+ncmpiio_open(MPI_Comm comm, const char *path, int ioflags, MPI_Info info,
+ NC *ncp);
+extern int
+ncmpiio_sync(ncio *nciop);
+
+extern int
+ncmpiio_move(ncio *const nciop, MPI_Offset to, MPI_Offset from,
+ MPI_Offset nbytes);
+
+extern int
+ncmpiio_move_fixed_vars(NC *ncp, NC *old);
+
+extern int
+ncmpiio_get_hint(NC *ncp, char *key, char *value, int *flag);
+
+extern int
+NC_computeshapes(NC *ncp);
+
+/* end defined in mpincio.h */
+
+/* begin defined in error.c */
+const char* ncmpi_strerror(int err);
+
+int ncmpii_handle_error(int mpi_errorcode, char *msg);
+
+/* end defined in error.c */
+/*
+ * These functions are used to support
+ * interface version 2 backward compatibility.
+ * N.B. these are tested in ../nc_test even though they are
+ * not public. So, be careful to change the declarations in
+ * ../nc_test/tests.h if you change these.
+ */
+
+int ncmpii_x_putn_schar (void *xbuf, const void *buf, MPI_Offset nelems,
+ MPI_Datatype datatype);
+int ncmpii_x_putn_uchar (void *xbuf, const void *buf, MPI_Offset nelems,
+ MPI_Datatype datatype);
+int ncmpii_x_putn_short (void *xbuf, const void *buf, MPI_Offset nelems,
+ MPI_Datatype datatype);
+int ncmpii_x_putn_ushort(void *xbuf, const void *buf, MPI_Offset nelems,
+ MPI_Datatype datatype);
+int ncmpii_x_putn_int (void *xbuf, const void *buf, MPI_Offset nelems,
+ MPI_Datatype datatype);
+int ncmpii_x_putn_uint (void *xbuf, const void *buf, MPI_Offset nelems,
+ MPI_Datatype datatype);
+int ncmpii_x_putn_float (void *xbuf, const void *buf, MPI_Offset nelems,
+ MPI_Datatype datatype);
+int ncmpii_x_putn_double(void *xbuf, const void *buf, MPI_Offset nelems,
+ MPI_Datatype datatype);
+int ncmpii_x_putn_int64 (void *xbuf, const void *buf, MPI_Offset nelems,
+ MPI_Datatype datatype);
+int ncmpii_x_putn_uint64(void *xbuf, const void *buf, MPI_Offset nelems,
+ MPI_Datatype datatype);
+int ncmpii_x_getn_schar (const void *xbuf, void *buf, MPI_Offset nelems,
+ MPI_Datatype datatype);
+int ncmpii_x_getn_uchar (const void *xbuf, void *buf, MPI_Offset nelems,
+ MPI_Datatype datatype);
+int ncmpii_x_getn_short (const void *xbuf, void *buf, MPI_Offset nelems,
+ MPI_Datatype datatype);
+int ncmpii_x_getn_ushort(const void *xbuf, void *buf, MPI_Offset nelems,
+ MPI_Datatype datatype);
+int ncmpii_x_getn_int (const void *xbuf, void *buf, MPI_Offset nelems,
+ MPI_Datatype datatype);
+int ncmpii_x_getn_uint (const void *xbuf, void *buf, MPI_Offset nelems,
+ MPI_Datatype datatype);
+int ncmpii_x_getn_float (const void *xbuf, void *buf, MPI_Offset nelems,
+ MPI_Datatype datatype);
+int ncmpii_x_getn_double(const void *xbuf, void *buf, MPI_Offset nelems,
+ MPI_Datatype datatype);
+int ncmpii_x_getn_int64 (const void *xbuf, void *buf, MPI_Offset nelems,
+ MPI_Datatype datatype);
+int ncmpii_x_getn_uint64(const void *xbuf, void *buf, MPI_Offset nelems,
+ MPI_Datatype datatype);
+
+int NC_start_count_stride_ck(const NC *ncp, const NC_var *varp,
+ const MPI_Offset *start, const MPI_Offset *count,
+ const MPI_Offset *stride, const int rw_flag);
+
+int ncmpii_need_convert(nc_type nctype,MPI_Datatype mpitype);
+
+int ncmpii_need_swap(nc_type nctype,MPI_Datatype mpitype);
+
+void ncmpii_swapn(void *dest_p, const void* src_p, MPI_Offset nelems, int esize);
+
+void ncmpii_in_swapn(void *buf, MPI_Offset nelems, int esize);
+
+int ncmpii_is_request_contiguous(NC *ncp, NC_var *varp,
+ const MPI_Offset starts[], const MPI_Offset counts[]);
+
+int ncmpii_get_offset(NC *ncp, NC_var *varp, const MPI_Offset starts[],
+ const MPI_Offset counts[], const MPI_Offset strides[],
+ const int rw_flag, MPI_Offset *offset_ptr);
+
+int ncmpii_check_mpifh(NC* ncp, int collective);
+
+int ncmpii_sync_numrecs(NC *ncp, MPI_Offset newnumrecs);
+
+int ncmpii_vars_create_filetype(NC* ncp, NC_var* varp,
+ const MPI_Offset start[], const MPI_Offset count[],
+ const MPI_Offset stride[], int rw_flag, int *blocklen,
+ MPI_Offset *offset, MPI_Datatype *filetype,
+ int *is_filetype_contig);
+
+extern int
+ncmpii_igetput_varm(NC *ncp, NC_var *varp, const MPI_Offset *start,
+ const MPI_Offset *stride, const MPI_Offset *imap,
+ const MPI_Offset *count, void *buf, MPI_Offset bufcount,
+ MPI_Datatype datatype, int *reqid, int rw_flag, int use_abuf,
+ int isSameGroup);
+
+extern int
+ncmpii_wait(NC *ncp, int io_method, int num_reqs, int *req_ids,
+ int *statuses);
+
+extern int
+ncmpii_cancel(NC *ncp, int num_req, int *req_ids, int *statuses);
+
+extern int
+ncmpii_inq_malloc_size(MPI_Offset *size);
+
+extern int
+ncmpii_inq_malloc_max_size(MPI_Offset *size);
+
+extern int
+ncmpii_inq_malloc_list(void);
+
+#ifdef PNC_MALLOC_TRACE
+void ncmpii_init_malloc_tracing(void);
+#endif
+
+extern void *
+NCI_Malloc_fn(size_t size, const int lineno, const char *func,
+ const char *filename);
+
+extern void *
+NCI_Calloc_fn(size_t nelem, size_t elsize, const int lineno, const char *func,
+ const char *filename);
+
+extern void *
+NCI_Realloc_fn(void *ptr, size_t size, const int lineno, const char *func,
+ const char *filename);
+
+extern void
+NCI_Free_fn(void *ptr, const int lineno, const char *func,
+ const char *filename);
+
+extern int
+ncmpii_inq_files_opened(int *num, int *ncids);
+
+extern MPI_Datatype
+ncmpii_nc2mpitype(nc_type type);
+
+extern int
+ncmpii_set_iget_callback(NC *ncp, int reqid, void *tmpBuf, void *userBuf,
+ int userBufCount, MPI_Datatype userBufType);
+
+extern int
+ncmpii_set_iput_callback(NC *ncp, int reqid, void *tmpPutBuf);
+
+extern int
+ncmpii_end_indep_data(NC *ncp);
+
+extern int
+ncmpii_file_set_view(NC *ncp, MPI_File fh, MPI_Offset *offset, MPI_Datatype filetype);
+
+extern int
+ncmpii_create_imaptype(NC_var *varp, const MPI_Offset *count,
+ const MPI_Offset *imap, const MPI_Offset bnelems,
+ const int el_size, MPI_Datatype ptype,
+ MPI_Datatype *imaptype);
+
+extern int
+ncmpii_calc_datatype_elems(NC *ncp, NC_var *varp, const MPI_Offset *start,
+ const MPI_Offset *count, const MPI_Offset *stride,
+ int rw_flag, MPI_Datatype buftype,
+ MPI_Datatype *ptype, MPI_Offset *bufcount,
+ MPI_Offset *bnelems, MPI_Offset *nbytes,
+ int *el_size, int *buftype_is_contig);
+
+extern int
+ncmpii_fill_vars(NC *ncp);
+
+extern int
+ncmpii_sanity_check(int ncid, int varid, const MPI_Offset *start,
+ const MPI_Offset *count, MPI_Offset bufcount,
+ enum API_KIND api, int mustInDataMode, int isFlexAPI,
+ int rw_flag, int io_method, NC **ncp, NC_var **varp);
+
+extern char*
+ncmpii_err_code_name(int err);
+
+#endif /* _NC_H_ */
diff --git a/src/lib/ncconfig.h.in b/src/lib/ncconfig.h.in
new file mode 100644
index 0000000..5337808
--- /dev/null
+++ b/src/lib/ncconfig.h.in
@@ -0,0 +1,483 @@
+/* src/lib/ncconfig.h.in. Generated from configure.in by autoheader. */
+
+/* Define if building universal (internal helper macro) */
+#undef AC_APPLE_UNIVERSAL_BUILD
+
+/* configure command-line arguments used */
+#undef CONFIGURE_ARGS_CLEAN
+
+/* Define if to disable MPI_File_sync */
+#undef DISABLE_FILE_SYNC
+
+/* Define if to disable in-place byte swap */
+#undef DISABLE_IN_PLACE_SWAP
+
+/* Define if able to support CDF-5 file format */
+#undef ENABLE_CDF5
+
+/* Define if able to support nonblocking routines */
+#undef ENABLE_NONBLOCKING
+
+/* Define if to enable subfiling feature */
+#undef ENABLE_SUBFILING
+
+/* Define if Fortran names are lower case */
+#undef F77_NAME_LOWER
+
+/* Define if Fortran names are lower case with two trailing underscore2 */
+#undef F77_NAME_LOWER_2USCORE
+
+/* Define if Fortran names are lower case with one trailing underscore */
+#undef F77_NAME_LOWER_USCORE
+
+/* Define if Fortran names are uppercase */
+#undef F77_NAME_UPPER
+
+/* Define to dummy `main' function (if any) required to link to the Fortran
+ libraries. */
+#undef FC_DUMMY_MAIN
+
+/* Define if F77 and FC dummy `main' functions are identical. */
+#undef FC_DUMMY_MAIN_EQ_F77
+
+/* Define to 1 if you have the `access' function. */
+#undef HAVE_ACCESS
+
+/* Define if C++ macro __FUNCTION__ is defined */
+#undef HAVE_FUNCTION_MACRO
+
+/* Define if C++ macro __func__ is defined */
+#undef HAVE_FUNC_MACRO
+
+/* Define to 1 if the system has the type `int64'. */
+#undef HAVE_INT64
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define to 1 if the system has the type `longlong'. */
+#undef HAVE_LONGLONG
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* available */
+#undef HAVE_MPI_BYTE
+
+/* available */
+#undef HAVE_MPI_CHAR
+
+/* available */
+#undef HAVE_MPI_CHARACTER
+
+/* available */
+#undef HAVE_MPI_COMBINER_DARRAY
+
+/* available */
+#undef HAVE_MPI_COMBINER_DUP
+
+/* available */
+#undef HAVE_MPI_COMBINER_F90_COMPLEX
+
+/* available */
+#undef HAVE_MPI_COMBINER_F90_INTEGER
+
+/* available */
+#undef HAVE_MPI_COMBINER_F90_REAL
+
+/* available */
+#undef HAVE_MPI_COMBINER_HINDEXED_INTEGER
+
+/* available */
+#undef HAVE_MPI_COMBINER_HVECTOR_INTEGER
+
+/* available */
+#undef HAVE_MPI_COMBINER_INDEXED_BLOCK
+
+/* available */
+#undef HAVE_MPI_COMBINER_RESIZED
+
+/* available */
+#undef HAVE_MPI_COMBINER_STRUCT_INTEGER
+
+/* available */
+#undef HAVE_MPI_COMBINER_SUBARRAY
+
+/* available */
+#undef HAVE_MPI_COMPLEX16
+
+/* available */
+#undef HAVE_MPI_COMPLEX32
+
+/* available */
+#undef HAVE_MPI_COMPLEX8
+
+/* available */
+#undef HAVE_MPI_DOUBLE
+
+/* available */
+#undef HAVE_MPI_DOUBLE_PRECISION
+
+/* available */
+#undef HAVE_MPI_ERR_ACCESS
+
+/* available */
+#undef HAVE_MPI_ERR_AMODE
+
+/* available */
+#undef HAVE_MPI_ERR_BAD_FILE
+
+/* available */
+#undef HAVE_MPI_ERR_FILE_EXISTS
+
+/* available */
+#undef HAVE_MPI_ERR_NOT_SAME
+
+/* available */
+#undef HAVE_MPI_ERR_NO_SPACE
+
+/* available */
+#undef HAVE_MPI_ERR_NO_SUCH_FILE
+
+/* available */
+#undef HAVE_MPI_ERR_QUOTA
+
+/* available */
+#undef HAVE_MPI_ERR_READ_ONLY
+
+/* available */
+#undef HAVE_MPI_FLOAT
+
+/* Define to 1 if you have the `MPI_Get_address' function. */
+#undef HAVE_MPI_GET_ADDRESS
+
+/* Define to 1 if you have the `MPI_Info_dup' function. */
+#undef HAVE_MPI_INFO_DUP
+
+/* Define to 1 if you have the `MPI_Info_free' function. */
+#undef HAVE_MPI_INFO_FREE
+
+/* available */
+#undef HAVE_MPI_INT
+
+/* available */
+#undef HAVE_MPI_INTEGER
+
+/* available */
+#undef HAVE_MPI_INTEGER1
+
+/* available */
+#undef HAVE_MPI_INTEGER16
+
+/* available */
+#undef HAVE_MPI_INTEGER2
+
+/* available */
+#undef HAVE_MPI_INTEGER4
+
+/* available */
+#undef HAVE_MPI_INTEGER8
+
+/* available */
+#undef HAVE_MPI_LB
+
+/* available */
+#undef HAVE_MPI_LONG
+
+/* available */
+#undef HAVE_MPI_LONG_LONG_INT
+
+/* available */
+#undef HAVE_MPI_OFFSET_DATATYPE
+
+/* available */
+#undef HAVE_MPI_REAL
+
+/* available */
+#undef HAVE_MPI_REAL16
+
+/* available */
+#undef HAVE_MPI_REAL4
+
+/* available */
+#undef HAVE_MPI_REAL8
+
+/* available */
+#undef HAVE_MPI_SHORT
+
+/* available */
+#undef HAVE_MPI_SIGNED_CHAR
+
+/* Define to 1 if you have the `MPI_Type_create_hindexed' function. */
+#undef HAVE_MPI_TYPE_CREATE_HINDEXED
+
+/* Define to 1 if you have the `MPI_Type_create_hvector' function. */
+#undef HAVE_MPI_TYPE_CREATE_HVECTOR
+
+/* Define to 1 if you have the `MPI_Type_create_resized' function. */
+#undef HAVE_MPI_TYPE_CREATE_RESIZED
+
+/* Define to 1 if you have the `MPI_Type_create_struct' function. */
+#undef HAVE_MPI_TYPE_CREATE_STRUCT
+
+/* Define to 1 if you have the `MPI_Type_create_subarray' function. */
+#undef HAVE_MPI_TYPE_CREATE_SUBARRAY
+
+/* Define to 1 if you have the `MPI_Type_get_extent' function. */
+#undef HAVE_MPI_TYPE_GET_EXTENT
+
+/* available */
+#undef HAVE_MPI_UB
+
+/* available */
+#undef HAVE_MPI_UNSIGNED
+
+/* available */
+#undef HAVE_MPI_UNSIGNED_CHAR
+
+/* available */
+#undef HAVE_MPI_UNSIGNED_LONG_LONG
+
+/* available */
+#undef HAVE_MPI_UNSIGNED_SHORT
+
+/* Define to 1 if the system has the type `ptrdiff_t'. */
+#undef HAVE_PTRDIFF_T
+
+/* Define to 1 if you have the <search.h> header file. */
+#undef HAVE_SEARCH_H
+
+/* Define to 1 if the system has the type `ssize_t'. */
+#undef HAVE_SSIZE_T
+
+/* Define to 1 if stdbool.h conforms to C99. */
+#undef HAVE_STDBOOL_H
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define to 1 if you have the `strerror' function. */
+#undef HAVE_STRERROR
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have the `tdelete' function. */
+#undef HAVE_TDELETE
+
+/* Define to 1 if you have the `tsearch' function. */
+#undef HAVE_TSEARCH
+
+/* Define to 1 if the system has the type `uchar'. */
+#undef HAVE_UCHAR
+
+/* Define to 1 if the system has the type `uint'. */
+#undef HAVE_UINT
+
+/* Define to 1 if the system has the type `uint64'. */
+#undef HAVE_UINT64
+
+/* Define to 1 if the system has the type `ulonglong'. */
+#undef HAVE_ULONGLONG
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Define to 1 if you have the `unlink' function. */
+#undef HAVE_UNLINK
+
+/* Define to 1 if the system has the type `ushort'. */
+#undef HAVE_USHORT
+
+/* Define to 1 if the system has the type `_Bool'. */
+#undef HAVE__BOOL
+
+/* Type of NC_BYTE */
+#undef NCBYTE_T
+
+/* Type of NC_SHORT */
+#undef NCSHORT_T
+
+/* C type for Fortran double */
+#undef NF_DOUBLEPRECISION_IS_C_
+
+/* C type for Fortran INT1 */
+#undef NF_INT1_IS_C_
+
+/* Type for Fortran INT1 */
+#undef NF_INT1_T
+
+/* C type for Fortran INT2 */
+#undef NF_INT2_IS_C_
+
+/* Type for Fortran INT2 */
+#undef NF_INT2_T
+
+/* C type for Fortran INT8 */
+#undef NF_INT8_IS_C_
+
+/* Type for Fortran INT8 */
+#undef NF_INT8_T
+
+/* C type for Fortran INT */
+#undef NF_INT_IS_C_
+
+/* C type for Fortran REAL */
+#undef NF_REAL_IS_C_
+
+/* Does system have IEEE FLOAT */
+#undef NO_IEEE_FLOAT
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the home page for this package. */
+#undef PACKAGE_URL
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* Define if to enable debugging */
+#undef PNC_DEBUG
+
+/* Define if to enable malloc tracing */
+#undef PNC_MALLOC_TRACE
+
+/* PnetCDF release date string */
+#undef PNETCDF_RELEASE_DATE
+
+/* full PnetCDF version string */
+#undef PNETCDF_VERSION
+
+/* major version number */
+#undef PNETCDF_VERSION_MAJOR
+
+/* minor version number */
+#undef PNETCDF_VERSION_MINOR
+
+/* pre-release string */
+#undef PNETCDF_VERSION_PRE
+
+/* sub version number */
+#undef PNETCDF_VERSION_SUB
+
+/* The size of `double', as computed by sizeof. */
+#undef SIZEOF_DOUBLE
+
+/* The size of `float', as computed by sizeof. */
+#undef SIZEOF_FLOAT
+
+/* The size of `int', as computed by sizeof. */
+#undef SIZEOF_INT
+
+/* The size of `long', as computed by sizeof. */
+#undef SIZEOF_LONG
+
+/* The size of `longlong', as computed by sizeof. */
+#undef SIZEOF_LONGLONG
+
+/* The size of `long long', as computed by sizeof. */
+#undef SIZEOF_LONG_LONG
+
+/* The size of `MPI_Aint', as computed by sizeof. */
+#undef SIZEOF_MPI_AINT
+
+/* The size of `MPI_Offset', as computed by sizeof. */
+#undef SIZEOF_MPI_OFFSET
+
+/* The size of `off_t', as computed by sizeof. */
+#undef SIZEOF_OFF_T
+
+/* The size of `short', as computed by sizeof. */
+#undef SIZEOF_SHORT
+
+/* The size of `signed char', as computed by sizeof. */
+#undef SIZEOF_SIGNED_CHAR
+
+/* The size of `size_t', as computed by sizeof. */
+#undef SIZEOF_SIZE_T
+
+/* The size of `uint', as computed by sizeof. */
+#undef SIZEOF_UINT
+
+/* The size of `ulonglong', as computed by sizeof. */
+#undef SIZEOF_ULONGLONG
+
+/* The size of `unsigned char', as computed by sizeof. */
+#undef SIZEOF_UNSIGNED_CHAR
+
+/* The size of `unsigned int', as computed by sizeof. */
+#undef SIZEOF_UNSIGNED_INT
+
+/* The size of `unsigned long long', as computed by sizeof. */
+#undef SIZEOF_UNSIGNED_LONG_LONG
+
+/* The size of `unsigned short', as computed by sizeof. */
+#undef SIZEOF_UNSIGNED_SHORT
+
+/* The size of `ushort', as computed by sizeof. */
+#undef SIZEOF_USHORT
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
+ significant byte first (like Motorola and SPARC, unlike Intel). */
+#if defined AC_APPLE_UNIVERSAL_BUILD
+# if defined __BIG_ENDIAN__
+# define WORDS_BIGENDIAN 1
+# endif
+#else
+# ifndef WORDS_BIGENDIAN
+# undef WORDS_BIGENDIAN
+# endif
+#endif
+
+/* Enable large inode numbers on Mac OS X 10.5. */
+#ifndef _DARWIN_USE_64_BIT_INODE
+# define _DARWIN_USE_64_BIT_INODE 1
+#endif
+
+/* Number of bits in a file offset, on hosts where this is settable. */
+#undef _FILE_OFFSET_BITS
+
+/* Define for large files, on AIX-style hosts. */
+#undef _LARGE_FILES
+
+/* Define to 1 if type `char' is unsigned and you are not using gcc. */
+#ifndef __CHAR_UNSIGNED__
+# undef __CHAR_UNSIGNED__
+#endif
+
+/* Define to `__inline__' or `__inline' if that's what the C compiler
+ calls it, or to nothing if 'inline' is not supported under any name. */
+#ifndef __cplusplus
+#undef inline
+#endif
+
+/* Define to `long int' if <sys/types.h> does not define. */
+#undef off_t
+
+/* Define to `unsigned int' if <sys/types.h> does not define. */
+#undef size_t
diff --git a/src/lib/ncio.h b/src/lib/ncio.h
new file mode 100644
index 0000000..a145b6f
--- /dev/null
+++ b/src/lib/ncio.h
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2003, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ */
+/* $Id: ncio.h 2017 2015-04-01 21:27:21Z wkliao $ */
+
+#ifndef _NCIO_H_
+#define _NCIO_H_
+
+#include <stddef.h> /* size_t */
+#include <sys/types.h> /* off_t */
+#include <mpi.h>
+#include "pnetcdf.h"
+
+#define MPI_COLLECTIVE_FH 2
+#define MPI_INDEPENDENT_FH 8
+
+#define NC_collectiveFhOpened(nciop) \
+ (fIsSet(nciop->mpioflags, MPI_COLLECTIVE_FH))
+
+#define NC_independentFhOpened(nciop) \
+ (fIsSet(nciop->mpioflags, MPI_INDEPENDENT_FH))
+
+#define set_NC_collectiveFh(nciop) \
+ fSet((nciop)->mpioflags, MPI_COLLECTIVE_FH)
+
+#define set_NC_independentFh(nciop) \
+ fSet((nciop)->mpioflags, MPI_INDEPENDENT_FH)
+
+
+/*
+ * I/O hints used by PnetCDF, but MPI-IO
+ */
+typedef struct {
+ MPI_Offset h_align; /* file alignment size for header */
+ MPI_Offset v_align; /* file alignment size for each fixed variable */
+ MPI_Offset r_align; /* file alignment size for record variable section */
+ MPI_Offset header_read_chunk_size;
+#ifdef ENABLE_SUBFILING
+ int subfile_mode;
+ int num_subfiles;
+#endif
+} nc_hints;
+
+/*
+ * netcdf i/o abstraction
+ */
+typedef struct {
+ /*
+ * A copy of the ioflags argument passed in to ncmpiio_open()
+ * or ncmpiio_create().
+ */
+ int ioflags;
+
+ /*
+ * The file descriptor of the netcdf file.
+ * This gets handed to the user as the netcdf id.
+ */
+ int fd;
+
+ /*
+ * The MPI File handle and the communicator
+ */
+ MPI_File collective_fh;
+ MPI_File independent_fh;
+ MPI_Comm comm;
+ MPI_Info mpiinfo;
+
+ int mpiomode; /* mode used in MPI_File_open */
+ int mpioflags; /* MPI_COLLECTIVE_FH or MPI_INDEPENDENT_FH */
+ int striping_unit; /* file stripe size of the file */
+
+ nc_hints hints; /* I/O hints used by PnetCDF only */
+
+ /*
+ * A copy of the 'path' argument passed in to ncmpiio_open()
+ * or ncmpiio_create(). Used by ncabort() to remove (unlink)
+ * the file and by error messages.
+ */
+ const char *path;
+
+ MPI_Offset put_size; /* amount of writes committed so far in bytes */
+ MPI_Offset get_size; /* amount of reads committed so far in bytes */
+} ncio;
+
+extern ncio *
+ncmpiio_new(const char *path, int ioflags);
+
+extern void
+ncmpiio_free(ncio *nciop);
+
+extern int
+ncmpiio_close(ncio *nciop, int doUnlink);
+
+#endif /* _NCIO_H_ */
diff --git a/src/lib/ncmpidtype.c b/src/lib/ncmpidtype.c
new file mode 100644
index 0000000..bcd5745
--- /dev/null
+++ b/src/lib/ncmpidtype.c
@@ -0,0 +1,575 @@
+/*
+ * Copyright (C) 2003, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ */
+/* $Id: ncmpidtype.c 2290 2016-01-02 18:37:46Z wkliao $ */
+
+#if HAVE_CONFIG_H
+# include "ncconfig.h"
+#endif
+
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#include <stdio.h>
+
+#include <mpi.h>
+
+#include "nc.h"
+#include "ncmpidtype.h"
+#include "macro.h"
+
+/*@
+ ncmpii_type_filter - Map a basic MPI datatype into one of the eight
+ that we process natively.
+
+ We unfortunately need to wrap all these types in case they aren't defined.
+
+ Return:
+ On success, one of MPI_CHAR, MPI_SIGNED_CHAR, MPI_UNSIGNED_CHAR, MPI_BYTE,
+ MPI_SHORT, MPI_INT, MPI_LONG, MPI_FLOAT, and MPI_DOUBLE.
+ On failure, MPI_DATATYPE_NULL.
+@*/
+static MPI_Datatype ncmpii_type_filter(MPI_Datatype type)
+{
+ /* char types */
+#ifdef HAVE_MPI_CHARACTER
+ if (type == MPI_CHARACTER)
+ return MPI_CHAR;
+#endif
+ if (type == MPI_CHAR)
+ return MPI_CHAR;
+
+ /* unsigned char types */
+ if (type == MPI_UNSIGNED_CHAR)
+ return MPI_UNSIGNED_CHAR;
+
+ /* signed char types */
+ if (type == MPI_SIGNED_CHAR)
+ return MPI_SIGNED_CHAR;
+
+#ifdef HAVE_MPI_INTEGER1
+ if (type == MPI_INTEGER1)
+ return MPI_SIGNED_CHAR;
+#endif
+ if (type == MPI_BYTE)
+ return MPI_BYTE;
+
+ /* 2-byte integer types (only supported if MPI_SHORT is 2-bytes). */
+#if (SIZEOF_SHORT == 2)
+ #ifdef HAVE_MPI_INTEGER2
+ if (type == MPI_INTEGER2)
+ return MPI_SHORT;
+ #endif
+ if (type == MPI_SHORT)
+ return MPI_SHORT;
+
+ if (type == MPI_UNSIGNED_SHORT)
+ return MPI_UNSIGNED_SHORT;
+#endif
+
+ /* 4-byte integer types */
+ {
+ MPI_Datatype int_4byte, uint_4byte;
+#if (SIZEOF_INT == 4)
+ int_4byte = MPI_INT;
+ uint_4byte = MPI_UNSIGNED;
+#elif (SIZEOF_SHORT == 4)
+ int_4byte = MPI_SHORT;
+ uint_4byte = MPI_UNSIGNED_SHORT;
+#else
+ int_4byte = MPI_DATATYPE_NULL; /* no 4-byte type? */
+ uint_4byte = MPI_DATATYPE_NULL;
+#endif
+
+#ifdef HAVE_MPI_INTEGER
+ if (type == MPI_INTEGER)
+ return int_4byte;
+ if (type == MPI_UNSIGNED)
+ return uint_4byte;
+#endif
+#ifdef HAVE_MPI_INTEGER4
+ if (type == MPI_INTEGER4)
+ return int_4byte;
+#endif
+#if (SIZEOF_LONG == 4)
+ if (type == MPI_LONG)
+ return int_4byte;
+ if (type == MPI_UNSIGNED_LONG)
+ return uint_4byte;
+#endif
+#if (SIZEOF_INT == 4)
+ if (type == MPI_INT)
+ return MPI_INT;
+ if (type == MPI_UNSIGNED)
+ return MPI_UNSIGNED;
+#elif (SIZEOF_SHORT == 4)
+ if (type == MPI_SHORT)
+ return MPI_SHORT;
+ if (type == MPI_UNSIGNED_SHORT)
+ return MPI_UNSIGNED_SHORT;
+#endif
+ }
+
+ /* 8-byte integer types (only supported if MPI_INT or MPI_LONG
+ * is 8-bytes).
+ */
+#if (SIZEOF_INT == 8) || (SIZEOF_LONG == 8)
+ #ifdef HAVE_MPI_INTEGER8
+ if (type == MPI_INTEGER8)
+ #if (SIZEOF_INT == 8)
+ return MPI_INT;
+ #else
+ return MPI_LONG;
+ #endif
+ #endif
+ #ifdef HAVE_MPI_UNSIGNED_INTEGER8
+ if (type == MPI_UNSIGNED_INTEGER8)
+ #if (SIZEOF_UINT == 8)
+ return MPI_UNSIGNED;
+ #else
+ return MPI_UNSIGNED_LONG;
+ #endif
+ #endif
+
+ #if (SIZEOF_INT == 8)
+ if (type == MPI_INT)
+ return MPI_INT;
+ if (type == MPI_UNSIGNED)
+ return MPI_UNSIGNED;
+ #endif
+ #if (SIZEOF_LONG == 8)
+ if (type == MPI_LONG)
+ #if (SIZEOF_INT == 8)
+ return MPI_INT;
+ #else
+ return MPI_LONG;
+ #endif
+ if (type == MPI_UNSIGNED_LONG)
+ #if (SIZEOF_UINT == 8)
+ return MPI_UNSIGNED;
+ #else
+ return MPI_UNSIGNED_LONG;
+ #endif
+ #endif
+#endif
+
+ /* 4-byte float types (we assume float is 4-bytes). */
+#ifdef HAVE_MPI_REAL
+ if (type == MPI_REAL)
+ return MPI_FLOAT;
+#endif
+#ifdef HAVE_MPI_REAL4
+ if (type == MPI_REAL4)
+ return MPI_FLOAT;
+#endif
+ if (type == MPI_FLOAT)
+ return MPI_FLOAT;
+
+ /* 8-byte float types (we assume double is 8-bytes). */
+#ifdef HAVE_MPI_REAL8
+ if (type == MPI_REAL8)
+ return MPI_DOUBLE;
+#endif
+#ifdef HAVE_MPI_DOUBLE_PRECISION
+ if (type == MPI_DOUBLE_PRECISION)
+ return MPI_DOUBLE;
+#endif
+ if (type == MPI_DOUBLE)
+ return MPI_DOUBLE;
+
+ if (type == MPI_LONG_LONG_INT)
+ return MPI_LONG_LONG_INT;
+
+ if (type == MPI_UNSIGNED_LONG_LONG)
+ return MPI_UNSIGNED_LONG_LONG;
+
+/* HP-MPI for example needs to handle MPI_LB and MPI_UB */
+#ifdef HAVE_MPI_LB
+ if (type == MPI_LB) {
+#if SIZEOF_SIZE_T == 8
+ return MPI_DOUBLE;
+#elif SIZEOF_SIZE_T == 4
+ return MPI_DOUBLE;
+#endif
+ }
+#endif
+#ifdef HAVE_MPI_UB
+ if (type == MPI_UB) {
+#if SIZEOF_SIZE_T == 8
+ return MPI_DOUBLE;
+#elif SIZEOF_SIZE_T == 4
+ return MPI_DOUBLE;
+#endif
+ }
+#endif
+
+/* default */
+ return MPI_DATATYPE_NULL;
+}
+
+/*@
+ ncmpi_darray_get_totalblock - Count the total number of blocks assigned
+ to the calling process by the darray datatype.
+
+ Input:
+. rank - rank of calling process
+. ndims - number of dimensions for the array and process grid
+. array_of_gsizes - Number of elements of type oldtype in each dimension
+ of global array (array of positive integers)
+. array_of_distribs - Distribution of array in each dimension (array of state)
+. array_of_dargs - Distribution argument in each dimension
+ (array of positive integers)
+. array_of_psizes - Size of process grid in each dimension
+ (array of positive integers)
+
+ Return:
+. total number of blocks assigned from the distributed array
+@*/
+#ifdef HAVE_MPI_COMBINER_DARRAY
+static int
+ncmpii_darray_get_totalblks(int rank,
+ MPI_Offset ndims,
+ int array_of_gsizes[],
+ int array_of_distribs[],
+ int array_of_dargs[],
+ int array_of_psizes[])
+{
+ int total_blocks = 1;
+ int subblocks, cycle, remain_cycle;
+ int i;
+ int pcoord;
+
+ /* Process Grid ranking is always in C ORDER,
+ so compute proc coordinates from last dim */
+
+ for (i=(int)ndims-1; i>=0; i--) {
+ if ( array_of_distribs[i] == MPI_DISTRIBUTE_NONE ) {
+ total_blocks *= array_of_gsizes[i];
+ } else {
+
+ pcoord = rank % array_of_psizes[i];
+ rank /= array_of_psizes[i];
+ if ( array_of_dargs[i] == MPI_DISTRIBUTE_DFLT_DARG ) {
+ subblocks = array_of_gsizes[i]/array_of_psizes[i];
+ if ( subblocks*array_of_psizes[i]+pcoord < array_of_gsizes[i] )
+ subblocks++;
+ } else {
+ cycle = array_of_dargs[i]*array_of_psizes[i];
+ remain_cycle = array_of_gsizes[i] % cycle;
+
+ subblocks = remain_cycle - pcoord*array_of_dargs[i];
+ if (subblocks > array_of_dargs[i])
+ subblocks = array_of_dargs[i];
+ else if (subblocks < 0)
+ subblocks = 0;
+
+ subblocks += array_of_gsizes[i]/cycle * array_of_dargs[i];
+ }
+
+ if (subblocks == 0)
+ return 0;
+ total_blocks *= subblocks;
+
+ }
+ }
+
+ return total_blocks;
+}
+#endif
+
+
+/*@
+ ncmpii_dtype_decode - Decode the MPI derived datatype to get the bottom
+ level primitive datatype information.
+
+ Input:
+. dtype - The MPI derived datatype to be decoded (can be predefined type).
+
+ Output:
+. ptype - The bottom level primitive datatype (only one allowed) in buftype
+. el_size - The size of the ptype
+. nelems - Number of elements/entries of such ptype in one buftype object
+. iscontig_of_ptypes - Whether dtype is a contiguous number of ptype
+@*/
+int ncmpii_dtype_decode(MPI_Datatype dtype,
+ MPI_Datatype *ptype,
+ int *el_size,
+ MPI_Offset *nelems,
+ int *isderived,
+ int *iscontig_of_ptypes)
+{
+ int i;
+ MPI_Offset tmpnelems, total_blocks;
+ int tmpel_size;
+ MPI_Datatype tmpptype;
+ int num_ints, num_adds, num_dtypes, combiner;
+ int *array_of_ints;
+ MPI_Aint *array_of_adds;
+ MPI_Datatype *array_of_dtypes;
+ MPI_Offset count;
+ int ndims;
+ int status = NC_NOERR;
+
+ *isderived = 0;
+
+ if (dtype == MPI_DATATYPE_NULL) {
+ *nelems = 0;
+ *ptype = dtype;
+ *el_size = 0;
+ *iscontig_of_ptypes = 1;
+ return NC_NOERR;
+ }
+
+ MPI_Type_get_envelope(dtype, &num_ints, &num_adds, &num_dtypes, &combiner);
+
+ if (
+#ifdef HAVE_MPI_COMBINER_F90_INTEGER
+ combiner == MPI_COMBINER_F90_INTEGER ||
+#endif
+#ifdef HAVE_MPI_COMBINER_F90_REAL
+ combiner == MPI_COMBINER_F90_REAL ||
+#endif
+#ifdef HAVE_MPI_COMBINER_F90_COMPLEX
+ combiner == MPI_COMBINER_F90_COMPLEX ||
+#endif
+ 0 )
+ {
+ fprintf(stderr,
+ "FIXME: F90_INTEGER, F90_REAL or F90_COMPLEX are not supported.\n");
+ }
+
+ if ( combiner == MPI_COMBINER_NAMED ) {
+ /* Predefined datatype */
+ *nelems = 1;
+ if ( (*ptype = ncmpii_type_filter(dtype)) == MPI_DATATYPE_NULL )
+ DEBUG_RETURN_ERROR(NC_EUNSPTETYPE)
+ MPI_Type_size(dtype, el_size);
+ *iscontig_of_ptypes = 1;
+ return NC_NOERR;
+ }
+
+ array_of_ints = (int *) NCI_Malloc(num_ints * SIZEOF_INT);
+ array_of_adds = (MPI_Aint *) NCI_Malloc(num_adds * SIZEOF_MPI_AINT);
+ array_of_dtypes = (MPI_Datatype *) NCI_Malloc(num_dtypes * sizeof(MPI_Datatype));
+
+ MPI_Type_get_contents(dtype, num_ints, num_adds, num_dtypes,
+ array_of_ints, array_of_adds, array_of_dtypes);
+
+ switch (combiner) {
+
+ /* single etype */
+
+ case MPI_COMBINER_CONTIGUOUS:
+ case MPI_COMBINER_HVECTOR:
+ case MPI_COMBINER_VECTOR:
+ case MPI_COMBINER_HINDEXED:
+ case MPI_COMBINER_INDEXED:
+#ifdef HAVE_MPI_COMBINER_DUP
+ case MPI_COMBINER_DUP:
+#endif
+#ifdef HAVE_MPI_COMBINER_HVECTOR_INTEGER
+ case MPI_COMBINER_HVECTOR_INTEGER:
+#endif
+#ifdef HAVE_MPI_COMBINER_INDEXED_BLOCK
+ case MPI_COMBINER_INDEXED_BLOCK:
+#endif
+#ifdef HAVE_MPI_COMBINER_HINDEXED_INTEGER
+ case MPI_COMBINER_HINDEXED_INTEGER:
+#endif
+#ifdef HAVE_MPI_COMBINER_SUBARRAY
+ case MPI_COMBINER_SUBARRAY:
+#endif
+#ifdef HAVE_MPI_COMBINER_DARRAY
+ case MPI_COMBINER_DARRAY:
+#endif
+#ifdef HAVE_MPI_COMBINER_RESIZED
+ case MPI_COMBINER_RESIZED:
+#endif
+
+ status = ncmpii_dtype_decode(array_of_dtypes[0], ptype, el_size,
+ nelems, isderived, iscontig_of_ptypes);
+ if (*isderived)
+ MPI_Type_free(array_of_dtypes);
+
+ break;
+
+ /* multiple etypes */
+
+ case MPI_COMBINER_STRUCT:
+#ifdef HAVE_MPI_COMBINER_STRUCT_INTEGER
+ case MPI_COMBINER_STRUCT_INTEGER:
+#endif
+ count = array_of_ints[0];
+ *el_size = 0;
+ for (i=0; i<count && *el_size==0; i++) {
+ /* need to skip null/marker types */
+ status = ncmpii_dtype_decode(array_of_dtypes[i],
+ ptype,
+ el_size,
+ nelems,
+ isderived,
+ iscontig_of_ptypes);
+ if (status != NC_NOERR)
+ return status;
+ if (*isderived)
+ MPI_Type_free(array_of_dtypes+i);
+ if (*el_size > 0)
+ *nelems *= array_of_ints[1+i];
+ }
+ for ( ; i<count; i++) {
+ status = ncmpii_dtype_decode(array_of_dtypes[i],
+ &tmpptype,
+ &tmpel_size,
+ &tmpnelems,
+ isderived,
+ iscontig_of_ptypes);
+ if (status != NC_NOERR)
+ return status;
+ if (*isderived)
+ MPI_Type_free(array_of_dtypes+i);
+ if (tmpel_size > 0) {
+ if (tmpptype != *ptype)
+ DEBUG_RETURN_ERROR(NC_EMULTITYPES)
+ *nelems += tmpnelems*array_of_ints[1+i];
+ }
+ }
+
+ *iscontig_of_ptypes = 0;
+
+ break;
+
+ default:
+ break;
+ }
+
+ *isderived = 1;
+
+ switch (combiner) {
+
+ /* single etype */
+
+ case MPI_COMBINER_CONTIGUOUS:
+ total_blocks = array_of_ints[0];
+ break;
+
+ case MPI_COMBINER_HVECTOR:
+ case MPI_COMBINER_VECTOR:
+#ifdef HAVE_MPI_COMBINER_HVECTOR_INTEGER
+ case MPI_COMBINER_HVECTOR_INTEGER:
+#endif
+#ifdef HAVE_MPI_COMBINER_INDEXED_BLOCK
+ case MPI_COMBINER_INDEXED_BLOCK:
+#endif
+ *iscontig_of_ptypes = 0;
+ total_blocks = array_of_ints[0]*array_of_ints[1];
+ break;
+
+ case MPI_COMBINER_HINDEXED:
+ case MPI_COMBINER_INDEXED:
+#ifdef HAVE_MPI_COMBINER_HINDEXED_INTEGER
+ case MPI_COMBINER_HINDEXED_INTEGER:
+#endif
+ *iscontig_of_ptypes = 0;
+ for (i=0, total_blocks=0; i<array_of_ints[0]; i++)
+ total_blocks += array_of_ints[1+i];
+ break;
+
+#ifdef HAVE_MPI_COMBINER_SUBARRAY
+ case MPI_COMBINER_SUBARRAY:
+ *iscontig_of_ptypes = 0;
+ ndims = array_of_ints[0];
+ for (i=0, total_blocks=1; i<ndims; i++)
+ total_blocks *= array_of_ints[1+ndims+i];
+ break;
+#endif
+
+#ifdef HAVE_MPI_COMBINER_DARRAY
+ case MPI_COMBINER_DARRAY:
+ *iscontig_of_ptypes = 0;
+ ndims = array_of_ints[2];
+
+ /* seldom reached, so put it in a separate function */
+ total_blocks = ncmpii_darray_get_totalblks(array_of_ints[1],
+ ndims,
+ array_of_ints+3,
+ array_of_ints+3+ndims,
+ array_of_ints+3+2*ndims,
+ array_of_ints+3+3*ndims);
+ break;
+#endif
+
+#ifdef HAVE_MPI_COMBINER_RESIZED
+ case MPI_COMBINER_RESIZED:
+ *iscontig_of_ptypes = 0;
+ total_blocks = 1;
+ break;
+#endif
+
+ default: /* DUP etc. */
+ total_blocks = 1;
+ break;
+ }
+
+ *nelems *= total_blocks;
+
+ NCI_Free(array_of_ints);
+ NCI_Free(array_of_adds);
+ NCI_Free(array_of_dtypes);
+
+ return status;
+}
+
+/*@
+ ncmpii_data_repack - copy data between two buffers with different datatypes.
+
+ Input:
+. inbuf - input buffer where data is copied from
+. incount - number of input elements
+. intype - datatype of each element in input buffer
+. outbuf - output buffer where data is copied to
+. outcount - number of output elements
+. outtype - datatype of each element in output buffer
+@*/
+
+int ncmpii_data_repack(void *inbuf,
+ MPI_Offset incount,
+ MPI_Datatype intype,
+ void *outbuf,
+ MPI_Offset outcount,
+ MPI_Datatype outtype)
+{
+ int intypesz, outtypesz;
+ int packsz;
+ void *packbuf;
+ int packpos;
+
+ MPI_Type_size(intype, &intypesz);
+ MPI_Type_size(outtype, &outtypesz);
+
+ if (incount*intypesz != outcount*outtypesz) {
+ /* input data amount does not match output data amount */
+ /* NOTE: we ignore it for user responsibility or add error handling ? */
+
+ /* for rescue, guarantee output data amount <= input data amount */
+ if (incount*intypesz < outcount*outtypesz)
+ outcount = incount*intypesz/outtypesz;
+ }
+
+ if (incount == 0)
+ return NC_NOERR;
+
+ /* local pack-n-unpack, using MPI_COMM_SELF */
+ if (incount != (int)incount) DEBUG_RETURN_ERROR(NC_EINTOVERFLOW)
+ if (outcount != (int)outcount) DEBUG_RETURN_ERROR(NC_EINTOVERFLOW)
+
+ MPI_Pack_size((int)incount, intype, MPI_COMM_SELF, &packsz);
+ packbuf = (void *)NCI_Malloc((size_t)packsz);
+ packpos = 0;
+ MPI_Pack(inbuf, (int)incount, intype, packbuf, packsz, &packpos, MPI_COMM_SELF);
+ packpos = 0;
+ MPI_Unpack(packbuf, packsz, &packpos, outbuf, (int)outcount, outtype, MPI_COMM_SELF);
+ NCI_Free(packbuf);
+
+ return NC_NOERR;
+}
diff --git a/src/lib/ncmpidtype.h b/src/lib/ncmpidtype.h
new file mode 100644
index 0000000..5ed6a8f
--- /dev/null
+++ b/src/lib/ncmpidtype.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2003, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ */
+/* $Id: ncmpidtype.h 1468 2013-10-26 16:53:18Z wkliao $ */
+
+#ifndef NCMPI_DTYPE_H
+#define NCMPI_DTYPE_H
+
+int ncmpii_dtype_decode(MPI_Datatype dtype,
+ MPI_Datatype *ptype,
+ int *el_size,
+ MPI_Offset *nelems,
+ int *isderived,
+ int *iscontig_of_ptypes);
+
+int ncmpii_data_repack(void *inbuf,
+ MPI_Offset incount,
+ MPI_Datatype intype,
+ void *outbuf,
+ MPI_Offset outcount,
+ MPI_Datatype outtype);
+
+#endif
diff --git a/src/lib/nctypes.h b/src/lib/nctypes.h
new file mode 100644
index 0000000..938a675
--- /dev/null
+++ b/src/lib/nctypes.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2003, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ */
+/* $Id: nctypes.h 2301 2016-01-10 19:21:33Z wkliao $ */
+
+#ifndef NCTYPES_H
+#define NCTYPES_H
+
+#ifndef HAVE_PTRDIFF_T
+typedef int ptrdiff_t;
+#endif
+
+#ifndef HAVE_SSIZE_T
+typedef int ssize_t;
+#endif
+
+#ifndef HAVE_UCHAR
+typedef unsigned char uchar;
+#endif
+
+#ifndef HAVE_USHORT
+typedef unsigned short int ushort;
+#endif
+
+#ifndef HAVE_UINT
+typedef unsigned int uint;
+#endif
+
+#ifndef HAVE_LONGLONG
+typedef long long longlong;
+#endif
+
+#ifndef HAVE_ULONGLONG
+typedef unsigned long long ulonglong;
+#endif
+
+#ifndef HAVE_INT64
+typedef long long int64;
+#endif
+
+#ifndef HAVE_UINT64
+typedef unsigned long long uint64;
+#endif
+
+#endif
diff --git a/src/lib/ncx.h b/src/lib/ncx.h
new file mode 100644
index 0000000..053507e
--- /dev/null
+++ b/src/lib/ncx.h
@@ -0,0 +1,979 @@
+/*
+ * Copyright (C) 2003, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ */
+/* "$Id: ncx.h 2301 2016-01-10 19:21:33Z wkliao $" */
+
+#ifndef _NCX_H_
+#define _NCX_H_
+
+#include <mpi.h>
+
+#include "nc.h"
+#include "ncio.h"
+#include "fbits.h"
+#include "nctypes.h"
+
+/*
+ * An external data representation interface.
+
+ *
+ * This started out as a general replacement for ONC XDR,
+ * specifically, the xdrmem family of functions.
+ *
+ * We eventually realized that we could write more portable
+ * code if we decoupled any association between the 'C' types
+ * and the external types. (XDR has this association between the 'C'
+ * types and the external representations, like xdr_int() takes
+ * an int argument and goes to an external int representation.)
+ * So, now there is a matrix of functions.
+ *
+ */
+
+#include "rnd.h"
+#include <stddef.h> /* size_t */
+#include <errno.h>
+#include <sys/types.h> /* off_t */
+
+
+#if defined(_CRAY) && !defined(_CRAYIEEE) && !defined(__crayx1)
+#define CRAYFLOAT 1 /* CRAY Floating point */
+#elif defined(_SX) && defined(_FLOAT2) /* NEC SUPER-UX in CRAY mode */
+#define CRAYFLOAT 1 /* CRAY Floating point */
+#endif
+
+/*
+ * External sizes of the primitive elements.
+ */
+#define X_SIZEOF_CHAR 1
+#define X_SIZEOF_SHORT 2
+#define X_SIZEOF_INT 4 /* xdr_int */
+#if 0
+#define X_SIZEOF_LONG 8 */ /* xdr_long_long */
+#endif
+#define X_SIZEOF_FLOAT 4
+#define X_SIZEOF_DOUBLE 8
+
+/* additional data types in CDF-5 */
+#define X_SIZEOF_UBYTE 1
+#define X_SIZEOF_USHORT 2
+#define X_SIZEOF_UINT 4
+#define X_SIZEOF_LONGLONG 8
+#define X_SIZEOF_ULONGLONG 8
+#define X_SIZEOF_INT64 8
+#define X_SIZEOF_UINT64 8
+
+/*
+ * For now, netcdf is limited to 32 bit sizes,
+ * If compiled with support for "large files", then
+ * netcdf will use a 64 bit off_t and it can then write a file
+ * using 64 bit offsets.
+ * see also X_SIZE_MAX, X_OFF_MAX below
+ */
+/* #define X_SIZEOF_OFF_T (sizeof(off_t)) */
+#define X_SIZEOF_OFF_T SIZEOF_OFF_T
+#define X_SIZEOF_SIZE_T X_SIZEOF_INT
+
+/*
+ * limits of the external representation
+ */
+#define X_SCHAR_MIN (-128)
+#define X_SCHAR_MAX 127
+#define X_UCHAR_MAX 255U
+#define X_SHORT_MIN (-32768)
+#define X_SHRT_MIN X_SHORT_MIN /* alias compatible with limits.h */
+#define X_SHORT_MAX 32767
+#define X_SHRT_MAX X_SHORT_MAX /* alias compatible with limits.h */
+#define X_USHORT_MAX 65535U
+#define X_USHRT_MAX X_USHORT_MAX /* alias compatible with limits.h */
+#define X_INT_MIN (-2147483647-1)
+#define X_INT_MAX 2147483647
+#define X_UINT_MAX 4294967295U
+#define X_LONGLONG_MIN (-9223372036854775807LL-1LL)
+#define X_LONGLONG_MAX 9223372036854775807LL
+#define X_ULONGLONG_MAX 18446744073709551615ULL
+#define X_FLOAT_MAX 3.402823466e+38f
+#define X_FLOAT_MIN (-X_FLOAT_MAX)
+#define X_FLT_MAX X_FLOAT_MAX /* alias compatible with limits.h */
+#if defined(CRAYFLOAT) && CRAYFLOAT != 0
+/* ldexp(1. - ldexp(.5 , -46), 1024) */
+#define X_DOUBLE_MAX 1.79769313486230e+308
+#else
+/* scalb(1. - scalb(.5 , -52), 1024) */
+#define X_DOUBLE_MAX 1.7976931348623157e+308
+#endif
+#define X_DOUBLE_MIN (-X_DOUBLE_MAX)
+#define X_DBL_MAX X_DOUBLE_MAX /* alias compatible with limits.h */
+
+#define X_SIZE_MAX X_UINT_MAX
+#define X_OFF_MAX X_INT_MAX
+
+
+/* Begin ncmpix_len */
+
+/*
+ * ncmpix_len_xxx() interfaces are defined as macros below,
+ * These give the length of an array of nelems of the type.
+ * N.B. The 'char' and 'short' interfaces give the X_ALIGNED length.
+ */
+#define X_ALIGN 4 /* a.k.a. BYTES_PER_XDR_UNIT */
+
+#define ncmpix_len_char(nelems) \
+ _RNDUP((nelems), X_ALIGN)
+
+#define ncmpix_len_short(nelems) \
+ (((nelems) + (nelems)%2) * X_SIZEOF_SHORT)
+
+#define ncmpix_len_int(nelems) \
+ ((nelems) * X_SIZEOF_INT)
+
+#define ncmpix_len_long(nelems) \
+ ((nelems) * X_SIZEOF_LONG)
+
+#define ncmpix_len_float(nelems) \
+ ((nelems) * X_SIZEOF_FLOAT)
+
+#define ncmpix_len_double(nelems) \
+ ((nelems) * X_SIZEOF_DOUBLE)
+
+#define ncmpix_len_ubyte(nelems) \
+ _RNDUP((nelems), X_ALIGN)
+
+#define ncmpix_len_ushort(nelems) \
+ (((nelems) + (nelems)%2) * X_SIZEOF_USHORT)
+
+#define ncmpix_len_uint(nelems) \
+ ((nelems) * X_SIZEOF_UINT)
+
+#define ncmpix_len_int64(nelems) \
+ ((nelems) * X_SIZEOF_INT64)
+
+#define ncmpix_len_uint64(nelems) \
+ ((nelems) * X_SIZEOF_UINT64)
+
+/* End ncmpix_len */
+
+#if defined(__CHAR_UNSIGNED__) && __CHAR_UNSIGNED__ != 0
+ /* 'char' is unsigned, declare ncbyte as 'signed char' */
+typedef signed char schar;
+
+#else
+ /* 'char' is signed */
+typedef signed char schar;
+
+#endif /* __CHAR_UNSIGNED__ */
+
+/*
+ * Primitive numeric conversion functions.
+ * The `put' functions convert from native internal
+ * type to the external type, while the `get' functions
+ * convert from the external to the internal.
+ *
+ * These take the form
+ * int ncmpix_get_{external_type}_{internal_type}(
+ * const void *xp,
+ * internal_type *ip
+ * );
+ * int ncmpix_put_{external_type}_{internal_type}(
+ * void *xp,
+ * const internal_type *ip
+ * );
+ * where
+ * `external_type' and `internal_type' chosen from
+ schar
+ uchar
+ short
+ ushort
+ int
+ uint
+ long
+ ulong
+ float
+ double
+ *
+ * Not all combinations make sense.
+ * We may not implement all combinations that make sense.
+ * The netcdf functions that use this ncmpix interface don't
+ * use these primitive conversion functions. They use the
+ * aggregate conversion functions declared below.
+ *
+ * Storage for a single element of external type is at the `void * xp'
+ * argument.
+ *
+ * Storage for a single element of internal type is at `ip' argument.
+ *
+ * These functions return NC_NOERR when no error occured,
+ * or NC_ERANGE when the value being converted is too large.
+ * When NC_ERANGE occurs, an undefined (implementation dependent)
+ * conversion may have occured.
+ *
+ * Note that loss of precision may occur silently.
+ *
+ */
+
+/*
+ * Other primitive conversion functions
+ * N.B. slightly different interface
+ * Used by netcdf.
+ */
+
+/* ncmpix_get_int_size_t */
+extern int
+ncmpix_get_size_t(const void **xpp, size_t *ulp);
+/* ncmpix_get_int_off_t */
+extern int
+ncmpix_get_off_t(const void **xpp, off_t *lp, size_t sizeof_off_t);
+
+/* ncmpix_put_int_size_t */
+extern int
+ncmpix_put_size_t(void **xpp, const size_t *ulp);
+/* ncmpix_put_int_off_t */
+extern int
+ncmpix_put_off_t(void **xpp, const off_t *lp, size_t sizeof_off_t);
+
+extern int
+ncmpix_get_uint32(const void **xpp, unsigned int *ip);
+extern int
+ncmpix_get_uint64(const void **xpp, unsigned long long *ip);
+extern int
+ncmpix_put_uint32(void **xpp, const unsigned int ip);
+extern int
+ncmpix_put_uint64(void **xpp, const unsigned long long ip);
+
+
+/*
+ * Aggregate numeric conversion functions.
+ * Convert an array. Replaces xdr_array(...).
+ * These functions are used by netcdf. Unlike the xdr
+ * interface, we optimize for aggregate conversions.
+ * This functions should be implemented to take advantage
+ * of multiple processor / parallel hardware where available.
+ *
+ * These take the form
+ * int ncmpix_getn_{external_type}_{internal_type}(
+ * const void *xpp,
+ * size_t nelems,
+ * internal_type *ip
+ * );
+ * int ncmpix_putn_{external_type}_{internal_type}(
+ * void **xpp,
+ * size_t nelems,
+ * const internal_type *ip
+ * );
+ * Where the types are as in the primitive numeric conversion functions.
+ *
+ * The value of the pointer to pointer argument, *xpp, is
+ * expected to reference storage for `nelems' of the external
+ * type. On return, it modified to reference just past the last
+ * converted external element.
+ *
+ * The types whose external size is less than X_ALIGN also have `pad'
+ * interfaces. These round (and zero fill on put) *xpp up to X_ALIGN
+ * boundaries. (This is the usual xdr behavior.)
+ *
+ * The `ip' argument should point to an array of `nelems' of
+ * internal_type.
+ *
+ * Range errors (NC_ERANGE) for a individual values in the array
+ * DO NOT terminate the array conversion. All elements are converted,
+ * with some having undefined values.
+ * If any range error occurs, the function returns NC_ERANGE.
+ *
+ */
+
+/*---- schar ----------------------------------------------------------------*/
+extern int
+ncmpix_getn_schar_schar (const void **xpp, MPI_Offset nelems, schar *ip);
+extern int
+ncmpix_getn_schar_uchar (const void **xpp, MPI_Offset nelems, uchar *ip);
+extern int
+ncmpix_getn_schar_short (const void **xpp, MPI_Offset nelems, short *ip);
+extern int
+ncmpix_getn_schar_ushort(const void **xpp, MPI_Offset nelems, ushort *ip);
+extern int
+ncmpix_getn_schar_int (const void **xpp, MPI_Offset nelems, int *ip);
+extern int
+ncmpix_getn_schar_uint (const void **xpp, MPI_Offset nelems, uint *ip);
+extern int
+ncmpix_getn_schar_long (const void **xpp, MPI_Offset nelems, long *ip);
+extern int
+ncmpix_getn_schar_float (const void **xpp, MPI_Offset nelems, float *ip);
+extern int
+ncmpix_getn_schar_double(const void **xpp, MPI_Offset nelems, double *ip);
+extern int
+ncmpix_getn_schar_longlong (const void **xpp, MPI_Offset nelems, longlong *ip);
+extern int
+ncmpix_getn_schar_ulonglong(const void **xpp, MPI_Offset nelems, ulonglong *ip);
+
+extern int
+ncmpix_pad_getn_schar_schar (const void **xpp, MPI_Offset nelems, schar *ip);
+extern int
+ncmpix_pad_getn_schar_uchar (const void **xpp, MPI_Offset nelems, uchar *ip);
+extern int
+ncmpix_pad_getn_schar_short (const void **xpp, MPI_Offset nelems, short *ip);
+extern int
+ncmpix_pad_getn_schar_ushort(const void **xpp, MPI_Offset nelems, ushort *ip);
+extern int
+ncmpix_pad_getn_schar_int (const void **xpp, MPI_Offset nelems, int *ip);
+extern int
+ncmpix_pad_getn_schar_uint (const void **xpp, MPI_Offset nelems, uint *ip);
+extern int
+ncmpix_pad_getn_schar_long (const void **xpp, MPI_Offset nelems, long *ip);
+extern int
+ncmpix_pad_getn_schar_float (const void **xpp, MPI_Offset nelems, float *ip);
+extern int
+ncmpix_pad_getn_schar_double(const void **xpp, MPI_Offset nelems, double *ip);
+extern int
+ncmpix_pad_getn_schar_longlong (const void **xpp, MPI_Offset nelems, longlong *ip);
+extern int
+ncmpix_pad_getn_schar_ulonglong(const void **xpp, MPI_Offset nelems, ulonglong *ip);
+
+extern int
+ncmpix_putn_schar_schar (void **xpp, MPI_Offset nelems, const schar *ip);
+extern int
+ncmpix_putn_schar_uchar (void **xpp, MPI_Offset nelems, const uchar *ip);
+extern int
+ncmpix_putn_schar_short (void **xpp, MPI_Offset nelems, const short *ip);
+extern int
+ncmpix_putn_schar_ushort(void **xpp, MPI_Offset nelems, const ushort *ip);
+extern int
+ncmpix_putn_schar_int (void **xpp, MPI_Offset nelems, const int *ip);
+extern int
+ncmpix_putn_schar_uint (void **xpp, MPI_Offset nelems, const uint *ip);
+extern int
+ncmpix_putn_schar_long (void **xpp, MPI_Offset nelems, const long *ip);
+extern int
+ncmpix_putn_schar_float (void **xpp, MPI_Offset nelems, const float *ip);
+extern int
+ncmpix_putn_schar_double(void **xpp, MPI_Offset nelems, const double *ip);
+extern int
+ncmpix_putn_schar_longlong (void **xpp, MPI_Offset nelems, const longlong *ip);
+extern int
+ncmpix_putn_schar_ulonglong(void **xpp, MPI_Offset nelems, const ulonglong *ip);
+
+extern int
+ncmpix_pad_putn_schar_schar (void **xpp, MPI_Offset nelems, const schar *ip);
+extern int
+ncmpix_pad_putn_schar_uchar (void **xpp, MPI_Offset nelems, const uchar *ip);
+extern int
+ncmpix_pad_putn_schar_short (void **xpp, MPI_Offset nelems, const short *ip);
+extern int
+ncmpix_pad_putn_schar_ushort(void **xpp, MPI_Offset nelems, const ushort *ip);
+extern int
+ncmpix_pad_putn_schar_int (void **xpp, MPI_Offset nelems, const int *ip);
+extern int
+ncmpix_pad_putn_schar_uint (void **xpp, MPI_Offset nelems, const uint *ip);
+extern int
+ncmpix_pad_putn_schar_long (void **xpp, MPI_Offset nelems, const long *ip);
+extern int
+ncmpix_pad_putn_schar_float (void **xpp, MPI_Offset nelems, const float *ip);
+extern int
+ncmpix_pad_putn_schar_double(void **xpp, MPI_Offset nelems, const double *ip);
+extern int
+ncmpix_pad_putn_schar_longlong (void **xpp, MPI_Offset nelems, const longlong *ip);
+extern int
+ncmpix_pad_putn_schar_ulonglong(void **xpp, MPI_Offset nelems, const ulonglong *ip);
+
+/*---- uchar ----------------------------------------------------------------*/
+extern int
+ncmpix_getn_uchar_schar (const void **xpp, MPI_Offset nelems, schar *ip);
+extern int
+ncmpix_getn_uchar_uchar (const void **xpp, MPI_Offset nelems, uchar *ip);
+extern int
+ncmpix_getn_uchar_short (const void **xpp, MPI_Offset nelems, short *ip);
+extern int
+ncmpix_getn_uchar_ushort(const void **xpp, MPI_Offset nelems, ushort *ip);
+extern int
+ncmpix_getn_uchar_int (const void **xpp, MPI_Offset nelems, int *ip);
+extern int
+ncmpix_getn_uchar_uint (const void **xpp, MPI_Offset nelems, uint *ip);
+extern int
+ncmpix_getn_uchar_long (const void **xpp, MPI_Offset nelems, long *ip);
+extern int
+ncmpix_getn_uchar_float (const void **xpp, MPI_Offset nelems, float *ip);
+extern int
+ncmpix_getn_uchar_double(const void **xpp, MPI_Offset nelems, double *ip);
+extern int
+ncmpix_getn_uchar_longlong (const void **xpp, MPI_Offset nelems, longlong *ip);
+extern int
+ncmpix_getn_uchar_ulonglong(const void **xpp, MPI_Offset nelems, ulonglong *ip);
+
+extern int
+ncmpix_pad_getn_uchar_schar (const void **xpp, MPI_Offset nelems, schar *ip);
+extern int
+ncmpix_pad_getn_uchar_uchar (const void **xpp, MPI_Offset nelems, uchar *ip);
+extern int
+ncmpix_pad_getn_uchar_short (const void **xpp, MPI_Offset nelems, short *ip);
+extern int
+ncmpix_pad_getn_uchar_ushort(const void **xpp, MPI_Offset nelems, ushort *ip);
+extern int
+ncmpix_pad_getn_uchar_int (const void **xpp, MPI_Offset nelems, int *ip);
+extern int
+ncmpix_pad_getn_uchar_uint (const void **xpp, MPI_Offset nelems, uint *ip);
+extern int
+ncmpix_pad_getn_uchar_long (const void **xpp, MPI_Offset nelems, long *ip);
+extern int
+ncmpix_pad_getn_uchar_float (const void **xpp, MPI_Offset nelems, float *ip);
+extern int
+ncmpix_pad_getn_uchar_double(const void **xpp, MPI_Offset nelems, double *ip);
+extern int
+ncmpix_pad_getn_uchar_longlong (const void **xpp, MPI_Offset nelems, longlong *ip);
+extern int
+ncmpix_pad_getn_uchar_ulonglong(const void **xpp, MPI_Offset nelems, ulonglong *ip);
+
+extern int
+ncmpix_putn_uchar_schar (void **xpp, MPI_Offset nelems, const schar *ip);
+extern int
+ncmpix_putn_uchar_uchar (void **xpp, MPI_Offset nelems, const uchar *ip);
+extern int
+ncmpix_putn_uchar_short (void **xpp, MPI_Offset nelems, const short *ip);
+extern int
+ncmpix_putn_uchar_ushort(void **xpp, MPI_Offset nelems, const ushort *ip);
+extern int
+ncmpix_putn_uchar_int (void **xpp, MPI_Offset nelems, const int *ip);
+extern int
+ncmpix_putn_uchar_uint (void **xpp, MPI_Offset nelems, const uint *ip);
+extern int
+ncmpix_putn_uchar_long (void **xpp, MPI_Offset nelems, const long *ip);
+extern int
+ncmpix_putn_uchar_float (void **xpp, MPI_Offset nelems, const float *ip);
+extern int
+ncmpix_putn_uchar_double(void **xpp, MPI_Offset nelems, const double *ip);
+extern int
+ncmpix_putn_uchar_longlong (void **xpp, MPI_Offset nelems, const longlong *ip);
+extern int
+ncmpix_putn_uchar_ulonglong(void **xpp, MPI_Offset nelems, const ulonglong *ip);
+
+extern int
+ncmpix_pad_putn_uchar_schar (void **xpp, MPI_Offset nelems, const schar *ip);
+extern int
+ncmpix_pad_putn_uchar_uchar (void **xpp, MPI_Offset nelems, const uchar *ip);
+extern int
+ncmpix_pad_putn_uchar_short (void **xpp, MPI_Offset nelems, const short *ip);
+extern int
+ncmpix_pad_putn_uchar_ushort(void **xpp, MPI_Offset nelems, const ushort *ip);
+extern int
+ncmpix_pad_putn_uchar_int (void **xpp, MPI_Offset nelems, const int *ip);
+extern int
+ncmpix_pad_putn_uchar_uint (void **xpp, MPI_Offset nelems, const uint *ip);
+extern int
+ncmpix_pad_putn_uchar_long (void **xpp, MPI_Offset nelems, const long *ip);
+extern int
+ncmpix_pad_putn_uchar_float (void **xpp, MPI_Offset nelems, const float *ip);
+extern int
+ncmpix_pad_putn_uchar_double(void **xpp, MPI_Offset nelems, const double *ip);
+extern int
+ncmpix_pad_putn_uchar_longlong (void **xpp, MPI_Offset nelems, const longlong *ip);
+extern int
+ncmpix_pad_putn_uchar_ulonglong(void **xpp, MPI_Offset nelems, const ulonglong *ip);
+
+/*---- short ----------------------------------------------------------------*/
+extern int
+ncmpix_getn_short_schar (const void **xpp, MPI_Offset nelems, schar *ip);
+extern int
+ncmpix_getn_short_uchar (const void **xpp, MPI_Offset nelems, uchar *ip);
+extern int
+ncmpix_getn_short_short (const void **xpp, MPI_Offset nelems, short *ip);
+extern int
+ncmpix_getn_short_ushort(const void **xpp, MPI_Offset nelems, ushort *ip);
+extern int
+ncmpix_getn_short_int (const void **xpp, MPI_Offset nelems, int *ip);
+extern int
+ncmpix_getn_short_uint (const void **xpp, MPI_Offset nelems, uint *ip);
+extern int
+ncmpix_getn_short_long (const void **xpp, MPI_Offset nelems, long *ip);
+extern int
+ncmpix_getn_short_float (const void **xpp, MPI_Offset nelems, float *ip);
+extern int
+ncmpix_getn_short_double(const void **xpp, MPI_Offset nelems, double *ip);
+extern int
+ncmpix_getn_short_longlong (const void **xpp, MPI_Offset nelems, longlong *ip);
+extern int
+ncmpix_getn_short_ulonglong(const void **xpp, MPI_Offset nelems, ulonglong *ip);
+
+extern int
+ncmpix_pad_getn_short_schar (const void **xpp, MPI_Offset nelems, schar *ip);
+extern int
+ncmpix_pad_getn_short_uchar (const void **xpp, MPI_Offset nelems, uchar *ip);
+extern int
+ncmpix_pad_getn_short_short (const void **xpp, MPI_Offset nelems, short *ip);
+extern int
+ncmpix_pad_getn_short_ushort(const void **xpp, MPI_Offset nelems, ushort *ip);
+extern int
+ncmpix_pad_getn_short_int (const void **xpp, MPI_Offset nelems, int *ip);
+extern int
+ncmpix_pad_getn_short_uint (const void **xpp, MPI_Offset nelems, uint *ip);
+extern int
+ncmpix_pad_getn_short_long (const void **xpp, MPI_Offset nelems, long *ip);
+extern int
+ncmpix_pad_getn_short_float (const void **xpp, MPI_Offset nelems, float *ip);
+extern int
+ncmpix_pad_getn_short_double(const void **xpp, MPI_Offset nelems, double *ip);
+extern int
+ncmpix_pad_getn_short_longlong (const void **xpp, MPI_Offset nelems, longlong *ip);
+extern int
+ncmpix_pad_getn_short_ulonglong(const void **xpp, MPI_Offset nelems, ulonglong *ip);
+
+extern int
+ncmpix_putn_short_schar (void **xpp, MPI_Offset nelems, const schar *ip);
+extern int
+ncmpix_putn_short_uchar (void **xpp, MPI_Offset nelems, const uchar *ip);
+extern int
+ncmpix_putn_short_short (void **xpp, MPI_Offset nelems, const short *ip);
+extern int
+ncmpix_putn_short_ushort(void **xpp, MPI_Offset nelems, const ushort *ip);
+extern int
+ncmpix_putn_short_int (void **xpp, MPI_Offset nelems, const int *ip);
+extern int
+ncmpix_putn_short_uint (void **xpp, MPI_Offset nelems, const uint *ip);
+extern int
+ncmpix_putn_short_long (void **xpp, MPI_Offset nelems, const long *ip);
+extern int
+ncmpix_putn_short_float (void **xpp, MPI_Offset nelems, const float *ip);
+extern int
+ncmpix_putn_short_double(void **xpp, MPI_Offset nelems, const double *ip);
+extern int
+ncmpix_putn_short_longlong (void **xpp, MPI_Offset nelems, const longlong *ip);
+extern int
+ncmpix_putn_short_ulonglong(void **xpp, MPI_Offset nelems, const ulonglong *ip);
+
+extern int
+ncmpix_pad_putn_short_schar (void **xpp, MPI_Offset nelems, const schar *ip);
+extern int
+ncmpix_pad_putn_short_uchar (void **xpp, MPI_Offset nelems, const uchar *ip);
+extern int
+ncmpix_pad_putn_short_short (void **xpp, MPI_Offset nelems, const short *ip);
+extern int
+ncmpix_pad_putn_short_ushort(void **xpp, MPI_Offset nelems, const ushort *ip);
+extern int
+ncmpix_pad_putn_short_int (void **xpp, MPI_Offset nelems, const int *ip);
+extern int
+ncmpix_pad_putn_short_uint (void **xpp, MPI_Offset nelems, const uint *ip);
+extern int
+ncmpix_pad_putn_short_long (void **xpp, MPI_Offset nelems, const long *ip);
+extern int
+ncmpix_pad_putn_short_float (void **xpp, MPI_Offset nelems, const float *ip);
+extern int
+ncmpix_pad_putn_short_double(void **xpp, MPI_Offset nelems, const double *ip);
+extern int
+ncmpix_pad_putn_short_longlong (void **xpp, MPI_Offset nelems, const longlong *ip);
+extern int
+ncmpix_pad_putn_short_ulonglong(void **xpp, MPI_Offset nelems, const ulonglong *ip);
+
+/*---- ushort ---------------------------------------------------------------*/
+extern int
+ncmpix_getn_ushort_schar (const void **xpp, MPI_Offset nelems, schar *ip);
+extern int
+ncmpix_getn_ushort_uchar (const void **xpp, MPI_Offset nelems, uchar *ip);
+extern int
+ncmpix_getn_ushort_short (const void **xpp, MPI_Offset nelems, short *ip);
+extern int
+ncmpix_getn_ushort_ushort(const void **xpp, MPI_Offset nelems, ushort *ip);
+extern int
+ncmpix_getn_ushort_int (const void **xpp, MPI_Offset nelems, int *ip);
+extern int
+ncmpix_getn_ushort_uint (const void **xpp, MPI_Offset nelems, uint *ip);
+extern int
+ncmpix_getn_ushort_long (const void **xpp, MPI_Offset nelems, long *ip);
+extern int
+ncmpix_getn_ushort_float (const void **xpp, MPI_Offset nelems, float *ip);
+extern int
+ncmpix_getn_ushort_double(const void **xpp, MPI_Offset nelems, double *ip);
+extern int
+ncmpix_getn_ushort_longlong (const void **xpp, MPI_Offset nelems, longlong *ip);
+extern int
+ncmpix_getn_ushort_ulonglong(const void **xpp, MPI_Offset nelems, ulonglong *ip);
+
+extern int
+ncmpix_pad_getn_ushort_schar (const void **xpp, MPI_Offset nelems, schar *ip);
+extern int
+ncmpix_pad_getn_ushort_uchar (const void **xpp, MPI_Offset nelems, uchar *ip);
+extern int
+ncmpix_pad_getn_ushort_short (const void **xpp, MPI_Offset nelems, short *ip);
+extern int
+ncmpix_pad_getn_ushort_ushort(const void **xpp, MPI_Offset nelems, ushort *ip);
+extern int
+ncmpix_pad_getn_ushort_int (const void **xpp, MPI_Offset nelems, int *ip);
+extern int
+ncmpix_pad_getn_ushort_uint (const void **xpp, MPI_Offset nelems, uint *ip);
+extern int
+ncmpix_pad_getn_ushort_long (const void **xpp, MPI_Offset nelems, long *ip);
+extern int
+ncmpix_pad_getn_ushort_float (const void **xpp, MPI_Offset nelems, float *ip);
+extern int
+ncmpix_pad_getn_ushort_double(const void **xpp, MPI_Offset nelems, double *ip);
+extern int
+ncmpix_pad_getn_ushort_longlong (const void **xpp, MPI_Offset nelems, longlong *ip);
+extern int
+ncmpix_pad_getn_ushort_ulonglong(const void **xpp, MPI_Offset nelems, ulonglong *ip);
+
+extern int
+ncmpix_putn_ushort_schar (void **xpp, MPI_Offset nelems, const schar *ip);
+extern int
+ncmpix_putn_ushort_uchar (void **xpp, MPI_Offset nelems, const uchar *ip);
+extern int
+ncmpix_putn_ushort_short (void **xpp, MPI_Offset nelems, const short *ip);
+extern int
+ncmpix_putn_ushort_ushort(void **xpp, MPI_Offset nelems, const ushort *ip);
+extern int
+ncmpix_putn_ushort_int (void **xpp, MPI_Offset nelems, const int *ip);
+extern int
+ncmpix_putn_ushort_uint (void **xpp, MPI_Offset nelems, const uint *ip);
+extern int
+ncmpix_putn_ushort_long (void **xpp, MPI_Offset nelems, const long *ip);
+extern int
+ncmpix_putn_ushort_float (void **xpp, MPI_Offset nelems, const float *ip);
+extern int
+ncmpix_putn_ushort_double(void **xpp, MPI_Offset nelems, const double *ip);
+extern int
+ncmpix_putn_ushort_longlong (void **xpp, MPI_Offset nelems, const longlong *ip);
+extern int
+ncmpix_putn_ushort_ulonglong(void **xpp, MPI_Offset nelems, const ulonglong *ip);
+
+extern int
+ncmpix_pad_putn_ushort_schar (void **xpp, MPI_Offset nelems, const schar *ip);
+extern int
+ncmpix_pad_putn_ushort_uchar (void **xpp, MPI_Offset nelems, const uchar *ip);
+extern int
+ncmpix_pad_putn_ushort_short (void **xpp, MPI_Offset nelems, const short *ip);
+extern int
+ncmpix_pad_putn_ushort_ushort(void **xpp, MPI_Offset nelems, const ushort *ip);
+extern int
+ncmpix_pad_putn_ushort_int (void **xpp, MPI_Offset nelems, const int *ip);
+extern int
+ncmpix_pad_putn_ushort_uint (void **xpp, MPI_Offset nelems, const uint *ip);
+extern int
+ncmpix_pad_putn_ushort_long (void **xpp, MPI_Offset nelems, const long *ip);
+extern int
+ncmpix_pad_putn_ushort_float (void **xpp, MPI_Offset nelems, const float *ip);
+extern int
+ncmpix_pad_putn_ushort_double(void **xpp, MPI_Offset nelems, const double *ip);
+extern int
+ncmpix_pad_putn_ushort_longlong (void **xpp, MPI_Offset nelems, const longlong *ip);
+extern int
+ncmpix_pad_putn_ushort_ulonglong(void **xpp, MPI_Offset nelems, const ulonglong *ip);
+
+/*---- int ------------------------------------------------------------------*/
+extern int
+ncmpix_getn_int_schar (const void **xpp, MPI_Offset nelems, schar *ip);
+extern int
+ncmpix_getn_int_uchar (const void **xpp, MPI_Offset nelems, uchar *ip);
+extern int
+ncmpix_getn_int_short (const void **xpp, MPI_Offset nelems, short *ip);
+extern int
+ncmpix_getn_int_ushort(const void **xpp, MPI_Offset nelems, ushort *ip);
+extern int
+ncmpix_getn_int_int (const void **xpp, MPI_Offset nelems, int *ip);
+extern int
+ncmpix_getn_int_uint (const void **xpp, MPI_Offset nelems, uint *ip);
+extern int
+ncmpix_getn_int_long (const void **xpp, MPI_Offset nelems, long *ip);
+extern int
+ncmpix_getn_long_long (const void **xpp, MPI_Offset nelems, long *ip);
+extern int
+ncmpix_getn_int_float (const void **xpp, MPI_Offset nelems, float *ip);
+extern int
+ncmpix_getn_int_double(const void **xpp, MPI_Offset nelems, double *ip);
+extern int
+ncmpix_getn_int_longlong (const void **xpp, MPI_Offset nelems, longlong *ip);
+extern int
+ncmpix_getn_int_ulonglong(const void **xpp, MPI_Offset nelems, ulonglong *ip);
+
+extern int
+ncmpix_putn_int_schar (void **xpp, MPI_Offset nelems, const schar *ip);
+extern int
+ncmpix_putn_int_uchar (void **xpp, MPI_Offset nelems, const uchar *ip);
+extern int
+ncmpix_putn_int_short (void **xpp, MPI_Offset nelems, const short *ip);
+extern int
+ncmpix_putn_int_ushort(void **xpp, MPI_Offset nelems, const ushort *ip);
+extern int
+ncmpix_putn_int_int (void **xpp, MPI_Offset nelems, const int *ip);
+extern int
+ncmpix_putn_int_uint (void **xpp, MPI_Offset nelems, const uint *ip);
+extern int
+ncmpix_putn_int_long (void **xpp, MPI_Offset nelems, const long *ip);
+extern int
+ncmpix_putn_long_long (void **xpp, MPI_Offset nelems, const long *ip);
+extern int
+ncmpix_putn_int_float (void **xpp, MPI_Offset nelems, const float *ip);
+extern int
+ncmpix_putn_int_double(void **xpp, MPI_Offset nelems, const double *ip);
+extern int
+ncmpix_putn_int_longlong (void **xpp, MPI_Offset nelems, const longlong *ip);
+extern int
+ncmpix_putn_int_ulonglong(void **xpp, MPI_Offset nelems, const ulonglong *ip);
+
+/*---- uint -----------------------------------------------------------------*/
+extern int
+ncmpix_getn_uint_schar (const void **xpp, MPI_Offset nelems, schar *ip);
+extern int
+ncmpix_getn_uint_uchar (const void **xpp, MPI_Offset nelems, uchar *ip);
+extern int
+ncmpix_getn_uint_short (const void **xpp, MPI_Offset nelems, short *ip);
+extern int
+ncmpix_getn_uint_ushort(const void **xpp, MPI_Offset nelems, ushort *ip);
+extern int
+ncmpix_getn_uint_int (const void **xpp, MPI_Offset nelems, int *ip);
+extern int
+ncmpix_getn_uint_uint (const void **xpp, MPI_Offset nelems, uint *ip);
+extern int
+ncmpix_getn_uint_long (const void **xpp, MPI_Offset nelems, long *ip);
+extern int
+ncmpix_getn_long_long (const void **xpp, MPI_Offset nelems, long *ip);
+extern int
+ncmpix_getn_uint_float (const void **xpp, MPI_Offset nelems, float *ip);
+extern int
+ncmpix_getn_uint_double(const void **xpp, MPI_Offset nelems, double *ip);
+extern int
+ncmpix_getn_uint_longlong (const void **xpp, MPI_Offset nelems, longlong *ip);
+extern int
+ncmpix_getn_uint_ulonglong(const void **xpp, MPI_Offset nelems, ulonglong *ip);
+
+extern int
+ncmpix_putn_uint_schar (void **xpp, MPI_Offset nelems, const schar *ip);
+extern int
+ncmpix_putn_uint_uchar (void **xpp, MPI_Offset nelems, const uchar *ip);
+extern int
+ncmpix_putn_uint_short (void **xpp, MPI_Offset nelems, const short *ip);
+extern int
+ncmpix_putn_uint_ushort(void **xpp, MPI_Offset nelems, const ushort *ip);
+extern int
+ncmpix_putn_uint_int (void **xpp, MPI_Offset nelems, const int *ip);
+extern int
+ncmpix_putn_uint_uint (void **xpp, MPI_Offset nelems, const uint *ip);
+extern int
+ncmpix_putn_uint_long (void **xpp, MPI_Offset nelems, const long *ip);
+extern int
+ncmpix_putn_long_long (void **xpp, MPI_Offset nelems, const long *ip);
+extern int
+ncmpix_putn_uint_float (void **xpp, MPI_Offset nelems, const float *ip);
+extern int
+ncmpix_putn_uint_double(void **xpp, MPI_Offset nelems, const double *ip);
+extern int
+ncmpix_putn_uint_longlong (void **xpp, MPI_Offset nelems, const longlong *ip);
+extern int
+ncmpix_putn_uint_ulonglong(void **xpp, MPI_Offset nelems, const ulonglong *ip);
+
+/*---- float ----------------------------------------------------------------*/
+extern int
+ncmpix_getn_float_schar (const void **xpp, MPI_Offset nelems, schar *ip);
+extern int
+ncmpix_getn_float_uchar (const void **xpp, MPI_Offset nelems, uchar *ip);
+extern int
+ncmpix_getn_float_short (const void **xpp, MPI_Offset nelems, short *ip);
+extern int
+ncmpix_getn_float_ushort(const void **xpp, MPI_Offset nelems, ushort *ip);
+extern int
+ncmpix_getn_float_int (const void **xpp, MPI_Offset nelems, int *ip);
+extern int
+ncmpix_getn_float_uint (const void **xpp, MPI_Offset nelems, uint *ip);
+extern int
+ncmpix_getn_float_long (const void **xpp, MPI_Offset nelems, long *ip);
+extern int
+ncmpix_getn_float_float (const void **xpp, MPI_Offset nelems, float *ip);
+extern int
+ncmpix_getn_float_double(const void **xpp, MPI_Offset nelems, double *ip);
+extern int
+ncmpix_getn_float_longlong (const void **xpp, MPI_Offset nelems, longlong *ip);
+extern int
+ncmpix_getn_float_ulonglong(const void **xpp, MPI_Offset nelems, ulonglong *ip);
+
+extern int
+ncmpix_putn_float_schar (void **xpp, MPI_Offset nelems, const schar *ip);
+extern int
+ncmpix_putn_float_uchar (void **xpp, MPI_Offset nelems, const uchar *ip);
+extern int
+ncmpix_putn_float_short (void **xpp, MPI_Offset nelems, const short *ip);
+extern int
+ncmpix_putn_float_ushort(void **xpp, MPI_Offset nelems, const ushort *ip);
+extern int
+ncmpix_putn_float_int (void **xpp, MPI_Offset nelems, const int *ip);
+extern int
+ncmpix_putn_float_uint (void **xpp, MPI_Offset nelems, const uint *ip);
+extern int
+ncmpix_putn_float_long (void **xpp, MPI_Offset nelems, const long *ip);
+extern int
+ncmpix_putn_float_float (void **xpp, MPI_Offset nelems, const float *ip);
+extern int
+ncmpix_putn_float_double(void **xpp, MPI_Offset nelems, const double *ip);
+extern int
+ncmpix_putn_float_longlong (void **xpp, MPI_Offset nelems, const longlong *ip);
+extern int
+ncmpix_putn_float_ulonglong(void **xpp, MPI_Offset nelems, const ulonglong *ip);
+
+/*---- double ---------------------------------------------------------------*/
+extern int
+ncmpix_getn_double_schar (const void **xpp, MPI_Offset nelems, schar *ip);
+extern int
+ncmpix_getn_double_uchar (const void **xpp, MPI_Offset nelems, uchar *ip);
+extern int
+ncmpix_getn_double_short (const void **xpp, MPI_Offset nelems, short *ip);
+extern int
+ncmpix_getn_double_ushort(const void **xpp, MPI_Offset nelems, ushort *ip);
+extern int
+ncmpix_getn_double_int (const void **xpp, MPI_Offset nelems, int *ip);
+extern int
+ncmpix_getn_double_uint (const void **xpp, MPI_Offset nelems, uint *ip);
+extern int
+ncmpix_getn_double_long (const void **xpp, MPI_Offset nelems, long *ip);
+extern int
+ncmpix_getn_double_float (const void **xpp, MPI_Offset nelems, float *ip);
+extern int
+ncmpix_getn_double_double(const void **xpp, MPI_Offset nelems, double *ip);
+extern int
+ncmpix_getn_double_longlong (const void **xpp, MPI_Offset nelems, longlong *ip);
+extern int
+ncmpix_getn_double_ulonglong(const void **xpp, MPI_Offset nelems, ulonglong *ip);
+
+extern int
+ncmpix_putn_double_schar (void **xpp, MPI_Offset nelems, const schar *ip);
+extern int
+ncmpix_putn_double_uchar (void **xpp, MPI_Offset nelems, const uchar *ip);
+extern int
+ncmpix_putn_double_short (void **xpp, MPI_Offset nelems, const short *ip);
+extern int
+ncmpix_putn_double_ushort(void **xpp, MPI_Offset nelems, const ushort *ip);
+extern int
+ncmpix_putn_double_int (void **xpp, MPI_Offset nelems, const int *ip);
+extern int
+ncmpix_putn_double_uint (void **xpp, MPI_Offset nelems, const uint *ip);
+extern int
+ncmpix_putn_double_long (void **xpp, MPI_Offset nelems, const long *ip);
+extern int
+ncmpix_putn_double_float (void **xpp, MPI_Offset nelems, const float *ip);
+extern int
+ncmpix_putn_double_double(void **xpp, MPI_Offset nelems, const double *ip);
+extern int
+ncmpix_putn_double_longlong (void **xpp, MPI_Offset nelems, const longlong *ip);
+extern int
+ncmpix_putn_double_ulonglong(void **xpp, MPI_Offset nelems, const ulonglong *ip);
+
+/*---- int64 ----------------------------------------------------------------*/
+extern int
+ncmpix_getn_int64_schar (const void **xpp, MPI_Offset nelems, schar *ip);
+extern int
+ncmpix_getn_int64_uchar (const void **xpp, MPI_Offset nelems, uchar *ip);
+extern int
+ncmpix_getn_int64_short (const void **xpp, MPI_Offset nelems, short *ip);
+extern int
+ncmpix_getn_int64_ushort(const void **xpp, MPI_Offset nelems, ushort *ip);
+extern int
+ncmpix_getn_int64_int (const void **xpp, MPI_Offset nelems, int *ip);
+extern int
+ncmpix_getn_int64_uint (const void **xpp, MPI_Offset nelems, uint *ip);
+extern int
+ncmpix_getn_int64_long (const void **xpp, MPI_Offset nelems, long *ip);
+extern int
+ncmpix_getn_int64_float (const void **xpp, MPI_Offset nelems, float *ip);
+extern int
+ncmpix_getn_int64_double(const void **xpp, MPI_Offset nelems, double *ip);
+extern int
+ncmpix_getn_int64_longlong (const void **xpp, MPI_Offset nelems, longlong *ip);
+extern int
+ncmpix_getn_int64_ulonglong(const void **xpp, MPI_Offset nelems, ulonglong *ip);
+
+extern int
+ncmpix_putn_int64_schar (void **xpp, MPI_Offset nelems, const schar *ip);
+extern int
+ncmpix_putn_int64_uchar (void **xpp, MPI_Offset nelems, const uchar *ip);
+extern int
+ncmpix_putn_int64_short (void **xpp, MPI_Offset nelems, const short *ip);
+extern int
+ncmpix_putn_int64_ushort(void **xpp, MPI_Offset nelems, const ushort *ip);
+extern int
+ncmpix_putn_int64_int (void **xpp, MPI_Offset nelems, const int *ip);
+extern int
+ncmpix_putn_int64_uint (void **xpp, MPI_Offset nelems, const uint *ip);
+extern int
+ncmpix_putn_int64_long (void **xpp, MPI_Offset nelems, const long *ip);
+extern int
+ncmpix_putn_int64_float (void **xpp, MPI_Offset nelems, const float *ip);
+extern int
+ncmpix_putn_int64_double(void **xpp, MPI_Offset nelems, const double *ip);
+extern int
+ncmpix_putn_int64_longlong (void **xpp, MPI_Offset nelems, const longlong *ip);
+extern int
+ncmpix_putn_int64_ulonglong(void **xpp, MPI_Offset nelems, const ulonglong *ip);
+
+/*---- uint64 ---------------------------------------------------------------*/
+extern int
+ncmpix_getn_uint64_schar (const void **xpp, MPI_Offset nelems, schar *ip);
+extern int
+ncmpix_getn_uint64_uchar (const void **xpp, MPI_Offset nelems, uchar *ip);
+extern int
+ncmpix_getn_uint64_short (const void **xpp, MPI_Offset nelems, short *ip);
+extern int
+ncmpix_getn_uint64_ushort(const void **xpp, MPI_Offset nelems, ushort *ip);
+extern int
+ncmpix_getn_uint64_int (const void **xpp, MPI_Offset nelems, int *ip);
+extern int
+ncmpix_getn_uint64_uint (const void **xpp, MPI_Offset nelems, uint *ip);
+extern int
+ncmpix_getn_uint64_long (const void **xpp, MPI_Offset nelems, long *ip);
+extern int
+ncmpix_getn_uint64_float (const void **xpp, MPI_Offset nelems, float *ip);
+extern int
+ncmpix_getn_uint64_double(const void **xpp, MPI_Offset nelems, double *ip);
+extern int
+ncmpix_getn_uint64_longlong (const void **xpp, MPI_Offset nelems, longlong *ip);
+extern int
+ncmpix_getn_uint64_ulonglong(const void **xpp, MPI_Offset nelems, ulonglong *ip);
+
+extern int
+ncmpix_putn_uint64_schar (void **xpp, MPI_Offset nelems, const schar *ip);
+extern int
+ncmpix_putn_uint64_uchar (void **xpp, MPI_Offset nelems, const uchar *ip);
+extern int
+ncmpix_putn_uint64_short (void **xpp, MPI_Offset nelems, const short *ip);
+extern int
+ncmpix_putn_uint64_ushort(void **xpp, MPI_Offset nelems, const ushort *ip);
+extern int
+ncmpix_putn_uint64_int (void **xpp, MPI_Offset nelems, const int *ip);
+extern int
+ncmpix_putn_uint64_uint (void **xpp, MPI_Offset nelems, const uint *ip);
+extern int
+ncmpix_putn_uint64_long (void **xpp, MPI_Offset nelems, const long *ip);
+extern int
+ncmpix_putn_uint64_float (void **xpp, MPI_Offset nelems, const float *ip);
+extern int
+ncmpix_putn_uint64_double(void **xpp, MPI_Offset nelems, const double *ip);
+extern int
+ncmpix_putn_uint64_longlong (void **xpp, MPI_Offset nelems, const longlong *ip);
+extern int
+ncmpix_putn_uint64_ulonglong(void **xpp, MPI_Offset nelems, const ulonglong *ip);
+
+
+/*
+ * Other aggregate conversion functions.
+ */
+
+/* read ASCII characters */
+extern int
+ncmpix_getn_text(const void **xpp, MPI_Offset nchars, char *cp);
+extern int
+ncmpix_pad_getn_text(const void **xpp, MPI_Offset nchars, char *cp);
+
+/* write ASCII characters */
+extern int
+ncmpix_putn_text(void **xpp, MPI_Offset nchars, const char *cp);
+extern int
+ncmpix_pad_putn_text(void **xpp, MPI_Offset nchars, const char *cp);
+
+/* for symmetry */
+#define ncmpix_getn_char_char(xpp, nelems, fillp) ncmpix_getn_text(xpp, nelems, fillp)
+#define ncmpix_putn_char_char(xpp, nelems, fillp) ncmpix_putn_text(xpp, nelems, fillp)
+
+/* read opaque data */
+extern int
+ncmpix_getn_void(const void **xpp, MPI_Offset nchars, void *vp);
+extern int
+ncmpix_pad_getn_void(const void **xpp, MPI_Offset nchars, void *vp);
+
+/* write opaque data */
+extern int
+ncmpix_putn_void(void **xpp, MPI_Offset nchars, const void *vp);
+extern int
+ncmpix_pad_putn_void(void **xpp, MPI_Offset nchars, const void *vp);
+
+#endif /* _NCX_H_ */
diff --git a/src/lib/ncx.m4 b/src/lib/ncx.m4
new file mode 100644
index 0000000..b7b7554
--- /dev/null
+++ b/src/lib/ncx.m4
@@ -0,0 +1,3551 @@
+dnl Process this m4 file to produce 'C' language file.
+dnl
+dnl If you see this line, you can ignore the next one.
+/* Do not edit this file. It is produced from the corresponding .m4 source */
+dnl
+/*
+ * Copyright (C) 2014, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ */
+/* $Id: ncx.m4 2299 2016-01-09 06:14:37Z wkliao $ */
+
+#if HAVE_CONFIG_H
+# include "ncconfig.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <mpi.h>
+
+/*
+ * The only error code returned from subroutines in this file is NC_ERANGE,
+ * if errors are detected.
+ */
+
+/*
+ * An external data representation interface.
+ */
+
+#include <string.h>
+#include <limits.h>
+#include "ncx.h"
+#include "nc.h"
+#include "macro.h"
+
+/* alias poorly named limits.h macros */
+#define SHORT_MAX SHRT_MAX
+#define SHORT_MIN SHRT_MIN
+#define USHORT_MAX USHRT_MAX
+#ifndef LLONG_MAX
+# define LLONG_MAX 9223372036854775807LL
+# define LLONG_MIN (-LLONG_MAX - 1LL)
+# define ULLONG_MAX 18446744073709551615ULL
+#endif
+#ifndef LONG_LONG_MAX
+#define LONG_LONG_MAX LLONG_MAX
+#endif
+#ifndef LONGLONG_MAX
+#define LONGLONG_MAX LONG_LONG_MAX
+#endif
+#ifndef LONG_LONG_MIN
+#define LONG_LONG_MIN LLONG_MIN
+#endif
+#ifndef LONGLONG_MIN
+#define LONGLONG_MIN LONG_LONG_MIN
+#endif
+#ifndef ULONG_LONG_MAX
+#define ULONG_LONG_MAX ULLONG_MAX
+#endif
+#ifndef ULONGLONG_MAX
+#define ULONGLONG_MAX ULONG_LONG_MAX
+#endif
+#include <float.h>
+#ifndef FLT_MAX /* This POSIX macro missing on some systems */
+# ifndef NO_IEEE_FLOAT
+# define FLT_MAX 3.40282347e+38f
+# else
+# error "You will need to define FLT_MAX"
+# endif
+#endif
+/* alias poorly named float.h macros */
+#define FLOAT_MAX FLT_MAX
+#define FLOAT_MIN (-FLT_MAX)
+#define DOUBLE_MAX DBL_MAX
+#define DOUBLE_MIN (-DBL_MAX)
+#define FLOAT_MAX_EXP FLT_MAX_EXP
+#define DOUBLE_MAX_EXP DBL_MAX_EXP
+#include <assert.h>
+#define UCHAR_MIN 0
+#define Min(a,b) ((a) < (b) ? (a) : (b))
+#define Max(a,b) ((a) > (b) ? (a) : (b))
+
+#ifndef SIZEOF_UCHAR
+#define SIZEOF_UCHAR SIZEOF_UNSIGNED_CHAR
+#endif
+#ifndef SIZEOF_USHORT
+#define SIZEOF_USHORT SIZEOF_UNSIGNED_SHORT_INT
+#endif
+#ifndef SIZEOF_UINT
+#define SIZEOF_UINT SIZEOF_UNSIGNED_INT
+#endif
+#ifndef SIZEOF_LONGLONG
+#define SIZEOF_LONGLONG SIZEOF_LONG_LONG
+#endif
+#ifndef SIZEOF_ULONGLONG
+#define SIZEOF_ULONGLONG SIZEOF_UNSIGNED_LONG_LONG
+#endif
+
+/*
+ * If the machine's float domain is "smaller" than the external one
+ * use the machine domain
+ */
+#if defined(FLT_MAX_EXP) && FLT_MAX_EXP < 128 /* 128 is X_FLT_MAX_EXP */
+#undef X_FLOAT_MAX
+# define X_FLOAT_MAX FLT_MAX
+#undef X_FLOAT_MIN
+# define X_FLOAT_MIN (-X_FLOAT_MAX)
+#endif
+
+#if defined(_SX) && _SX != 0 /* NEC SUPER UX */
+#define LOOPCNT 256 /* must be no longer than hardware vector length */
+#if _INT64
+#undef INT_MAX /* workaround cpp bug */
+#define INT_MAX X_INT_MAX
+#undef INT_MIN /* workaround cpp bug */
+#define INT_MIN X_INT_MIN
+#undef LONG_MAX /* workaround cpp bug */
+#define LONG_MAX X_INT_MAX
+#undef LONG_MIN /* workaround cpp bug */
+#define LONG_MIN X_INT_MIN
+#elif _LONG64
+#undef LONG_MAX /* workaround cpp bug */
+#define LONG_MAX 4294967295L
+#undef LONG_MIN /* workaround cpp bug */
+#define LONG_MIN -4294967295L
+#endif
+#if !_FLOAT0
+#error "FLOAT1 and FLOAT2 not supported"
+#endif
+#endif /* _SX */
+
+static const char nada[X_ALIGN] = {0, 0, 0, 0};
+
+#ifndef WORDS_BIGENDIAN
+/* LITTLE_ENDIAN: DEC and intel */
+/*
+ * Routines to convert to BIG ENDIAN.
+ * Optimize the swapn?b() and swap?b() routines aggressively.
+ */
+
+#define SWAP2(a) ( (((a) & 0xff) << 8) | \
+ (((a) >> 8) & 0xff) )
+
+#define SWAP4(a) ( ((a) << 24) | \
+ (((a) << 8) & 0x00ff0000) | \
+ (((a) >> 8) & 0x0000ff00) | \
+ (((a) >> 24) & 0x000000ff) )
+
+
+static void
+swapn2b(void *dst, const void *src, MPI_Offset nn)
+{
+ char *op = dst;
+ const char *ip = src;
+
+/* unroll the following to reduce loop overhead
+ *
+ * while (nn-- > 0)
+ * {
+ * *op++ = *(++ip);
+ * *op++ = *(ip++ -1);
+ * }
+ */
+ while (nn > 3)
+ {
+ *op++ = *(++ip);
+ *op++ = *(ip++ -1);
+ *op++ = *(++ip);
+ *op++ = *(ip++ -1);
+ *op++ = *(++ip);
+ *op++ = *(ip++ -1);
+ *op++ = *(++ip);
+ *op++ = *(ip++ -1);
+ nn -= 4;
+ }
+ while (nn-- > 0)
+ {
+ *op++ = *(++ip);
+ *op++ = *(ip++ -1);
+ }
+}
+
+# ifndef vax
+static void
+swap4b(void *dst, const void *src)
+{
+ char *op = dst;
+ const char *ip = src;
+ op[0] = ip[3];
+ op[1] = ip[2];
+ op[2] = ip[1];
+ op[3] = ip[0];
+
+/* We can use bitwise operations as below.
+ Here, unsigned int must be of size 4 bytes.
+
+ unsigned int *cp = (unsigned int *) dst;
+ unsigned int *ip = (unsigned int *) src;
+
+ *cp = ((*ip) << 24)
+ | (((*ip) & 0x0000ff00) << 8)
+ | (((*ip) & 0x00ff0000) >> 8)
+ | (((*ip) >> 24));
+*/
+}
+# endif /* !vax */
+
+static void
+swapn4b(void *dst, const void *src, MPI_Offset nn)
+{
+ char *op = dst;
+ const char *ip = src;
+
+/* unroll the following to reduce loop overhead
+ * while (nn-- > 0)
+ * {
+ * op[0] = ip[3];
+ * op[1] = ip[2];
+ * op[2] = ip[1];
+ * op[3] = ip[0];
+ * op += 4;
+ * ip += 4;
+ * }
+ */
+ while (nn > 3)
+ {
+ op[0] = ip[3];
+ op[1] = ip[2];
+ op[2] = ip[1];
+ op[3] = ip[0];
+ op[4] = ip[7];
+ op[5] = ip[6];
+ op[6] = ip[5];
+ op[7] = ip[4];
+ op[8] = ip[11];
+ op[9] = ip[10];
+ op[10] = ip[9];
+ op[11] = ip[8];
+ op[12] = ip[15];
+ op[13] = ip[14];
+ op[14] = ip[13];
+ op[15] = ip[12];
+ op += 16;
+ ip += 16;
+ nn -= 4;
+ }
+ while (nn-- > 0)
+ {
+ op[0] = ip[3];
+ op[1] = ip[2];
+ op[2] = ip[1];
+ op[3] = ip[0];
+ op += 4;
+ ip += 4;
+ }
+}
+
+# ifndef vax
+static void
+swap8b(void *dst, const void *src)
+{
+ char *op = dst;
+ const char *ip = src;
+# ifndef FLOAT_WORDS_BIGENDIAN
+ op[0] = ip[7];
+ op[1] = ip[6];
+ op[2] = ip[5];
+ op[3] = ip[4];
+ op[4] = ip[3];
+ op[5] = ip[2];
+ op[6] = ip[1];
+ op[7] = ip[0];
+# else
+ op[0] = ip[3];
+ op[1] = ip[2];
+ op[2] = ip[1];
+ op[3] = ip[0];
+ op[4] = ip[7];
+ op[5] = ip[6];
+ op[6] = ip[5];
+ op[7] = ip[4];
+#endif
+}
+# endif /* !vax */
+
+# ifndef vax
+static void
+swapn8b(void *dst, const void *src, MPI_Offset nn)
+{
+ char *op = dst;
+ const char *ip = src;
+
+/* unroll the following to reduce loop overhead
+ * while (nn-- > 0)
+ * {
+ * op[0] = ip[7];
+ * op[1] = ip[6];
+ * op[2] = ip[5];
+ * op[3] = ip[4];
+ * op[4] = ip[3];
+ * op[5] = ip[2];
+ * op[6] = ip[1];
+ * op[7] = ip[0];
+ * op += 8;
+ * ip += 8;
+ * }
+ */
+# ifndef FLOAT_WORDS_BIGENDIAN
+ while (nn > 1)
+ {
+ op[0] = ip[7];
+ op[1] = ip[6];
+ op[2] = ip[5];
+ op[3] = ip[4];
+ op[4] = ip[3];
+ op[5] = ip[2];
+ op[6] = ip[1];
+ op[7] = ip[0];
+ op[8] = ip[15];
+ op[9] = ip[14];
+ op[10] = ip[13];
+ op[11] = ip[12];
+ op[12] = ip[11];
+ op[13] = ip[10];
+ op[14] = ip[9];
+ op[15] = ip[8];
+ op += 16;
+ ip += 16;
+ nn -= 2;
+ }
+ while (nn-- > 0)
+ {
+ op[0] = ip[7];
+ op[1] = ip[6];
+ op[2] = ip[5];
+ op[3] = ip[4];
+ op[4] = ip[3];
+ op[5] = ip[2];
+ op[6] = ip[1];
+ op[7] = ip[0];
+ op += 8;
+ ip += 8;
+ }
+# else
+ while (nn-- > 0)
+ {
+ op[0] = ip[3];
+ op[1] = ip[2];
+ op[2] = ip[1];
+ op[3] = ip[0];
+ op[4] = ip[7];
+ op[5] = ip[6];
+ op[6] = ip[5];
+ op[7] = ip[4];
+ op += 8;
+ ip += 8;
+ }
+#endif
+}
+# endif /* !vax */
+
+#endif /* LITTLE_ENDIAN */
+
+dnl dnl dnl
+dnl
+dnl Upcase(str)
+dnl
+define(`Upcase',dnl
+`dnl
+translit($1, abcdefghijklmnopqrstuvwxyz, ABCDEFGHIJKLMNOPQRSTUVWXYZ)')dnl
+dnl
+dnl dnl dnl
+dnl
+define(`Isizeof', ``SIZEOF_'Upcase($1)')dnl
+define(`Xsizeof', ``X_SIZEOF_'Upcase($1)')dnl
+define(`IXsizeof', ``SIZEOF_IX_'Upcase($1)')dnl
+define(`Imax', `Upcase($1)`_MAX'')dnl
+define(`Imin', `Upcase($1)`_MIN'')dnl
+define(`Xmax', ``X_'Upcase($1)`_MAX'')dnl
+define(`Xmin', ``X_'Upcase($1)`_MIN'')dnl
+define(`IXmax', ``IX_'Upcase($1)`_MAX'')dnl
+dnl
+define(`Fmin', `ifelse(index(`$1',`u'), 0, `0', `(double)Imin($1)')')dnl
+define(`Dmin', `ifelse(index(`$1',`u'), 0, `0', `(double)Imin($1)')')dnl
+define(`FXmin', `ifelse(index(`$1',`u'), 0, `0', `(double)Xmin($1)')')dnl
+define(`DXmin', `ifelse(index(`$1',`u'), 0, `0', `Xmin($1)')')dnl
+
+dnl
+dnl For GET APIs:
+dnl check for negative $3 if $1 is signed && $2 is unsigned
+dnl Don't check for negative $3 if $1 is signed && $2 is signed
+dnl Don't check for negative $3 if $1 is unsigned
+dnl $5 is either "return" or "status ="
+dnl
+define(`GETI_CheckNegReturn',
+ `ifelse(index(`$1',`u'), 0, ,
+ index(`$2',`u'), 0,
+ `if ($3 < 0) DEBUG_RETURN_ERROR(NC_ERANGE) /* because $4 is unsigned */')')dnl
+
+define(`GETI_CheckNegAssign',
+ `ifelse(index(`$1',`u'), 0, ,
+ index(`$2',`u'), 0,
+ `if ($3 < 0) DEBUG_ASSIGN_ERROR(status, NC_ERANGE) /* because $4 is unsigned */')')dnl
+
+define(`Cast_Signed2Unsigned',
+ `ifelse(index(`$1',`u'), 0,
+ `ifelse(index(`$2',`u'), 0, , `(signed)')')')dnl
+
+dnl
+dnl For PUT APIs:
+dnl check for negative $3 if $1 is unsigned && $2 is signed
+dnl Don't check for negative $3 if $1 is unsigned && $2 is unsigned
+dnl Don't check for negative $3 if $1 is signed
+dnl
+define(`PUTI_CheckNeg',
+ `ifelse(index(`$1',`u'), 0,
+ `ifelse(index(`$2',`u'), 0, ,
+ ` if ($3 < 0) DEBUG_RETURN_ERROR(NC_ERANGE) /* because $4 is unsigned */')')')dnl
+
+dnl
+dnl For GET APIs boundary check
+dnl
+define(`GETF_CheckBND',
+`if (xx > (double)Upcase($1)_MAX || xx < Dmin($1)) DEBUG_RETURN_ERROR(NC_ERANGE)
+ *ip = ($1)xx;')
+
+dnl
+dnl For GET APIs boudnary check for when $1 is either 'longlong' or 'ulonglong'
+dnl
+define(`GETF_CheckBND2',
+ `ifelse(index(`$1',`u'), 0,
+`if (xx == Upcase($1)_MAX) *ip = Upcase($1)_MAX;',dnl for unsigned type
+`if (xx == Upcase($1)_MAX) *ip = Upcase($1)_MAX;
+ else if (xx == Upcase($1)_MIN) *ip = Upcase($1)_MIN;')
+ else if (xx > (double)Upcase($1)_MAX || xx < Dmin($1)) DEBUG_RETURN_ERROR(NC_ERANGE)
+ else *ip = ($1)xx;')
+
+dnl
+dnl For PUT APIs and either $1 and $2 is float or double:
+dnl
+define(`PUTF_CheckBND',
+`ifelse(`$2', `double', `if (*ip > Xmax($1) || *ip < DXmin($1)) DEBUG_RETURN_ERROR(NC_ERANGE)',
+ `$2', `float', `if (*ip > (double)Xmax($1) || *ip < FXmin($1)) DEBUG_RETURN_ERROR(NC_ERANGE)')')
+
+dnl
+dnl For GET APIs and $1 and $2 are not float or double
+dnl
+define(`GETI_CheckBND',
+``#'if IXmax($1) > Imax($2)
+ if (xx > Imax($2)'`ifelse(index(`$1',`u'), 0, ,
+ index(`$2',`u'), 0, ,
+ ` || xx < Imin($2)')'`) DEBUG_RETURN_ERROR(NC_ERANGE)'
+`#'endif)
+
+dnl
+dnl For PUT APIs and $1 and $2 are not float or double
+dnl
+define(`PUTI_CheckBND',
+``#'if IXmax($1) < Imax($2)
+ if (*ip > IXmax($1)'`ifelse(index(`$1',`u'), 0, ,
+ index(`$2',`u'), 0, ,
+ ` || *ip < Xmin($1)')'`) DEBUG_RETURN_ERROR(NC_ERANGE)'
+`#'endif)
+
+/*
+ * Primitive numeric conversion functions.
+ */
+
+dnl dnl dnl
+dnl
+dnl NCX_GET1F(xtype, itype) for floating-point types
+dnl
+define(`NCX_GET1F',dnl
+`dnl
+static int
+ncmpix_get_$1_$2(const void *xp, $2 *ip)
+{
+ ix_$1 xx;
+ get_ix_$1(xp, &xx);
+ ifelse(`$1', `float', `ifelse(`$2', `longlong', GETF_CheckBND2($2),
+ `$2', `ulonglong', GETF_CheckBND2($2),
+ `$2', `double', `*ip = ($2)xx;',
+ GETF_CheckBND($2))',
+ `$1', `double', `ifelse(`$2', `longlong', GETF_CheckBND2($2),
+ `$2', `ulonglong', GETF_CheckBND2($2),
+ GETF_CheckBND($2))',
+ `*ip = ($2)xx;')
+ return NC_NOERR;
+}
+')dnl
+
+dnl dnl dnl
+dnl
+dnl NCX_GET1I(xtype, itype, isComptable) for integral types
+dnl
+define(`NCX_GET1I',dnl
+`dnl
+static int
+ncmpix_get_$1_$2(const void *xp, $2 *ip)
+{
+ifelse(`$3', `1',
+``#'if IXsizeof($1) == Isizeof($2) && IXmax($1) == Upcase($2)_MAX
+ get_ix_$1(xp, (ix_$1 *)ip);
+`#'else
+')dnl
+ ix_$1 xx;
+ get_ix_$1(xp, &xx);
+GETI_CheckBND($1, $2)
+ GETI_CheckNegReturn($1, $2, xx, ip)
+ *ip = ($2) xx;
+ifelse(`$3', `1', ``#'endif
+')dnl
+ return NC_NOERR;
+}
+')dnl
+
+dnl dnl dnl
+dnl
+dnl NCX_PUT1F(xtype, itype) for floating-point types
+dnl
+define(`NCX_PUT1F',dnl
+`dnl
+static int
+ncmpix_put_$1_$2(void *xp, const $2 *ip)
+{
+ ix_$1 xx;
+ PUTF_CheckBND($1, $2)
+ xx = (ix_$1)*ip;
+ put_ix_$1(xp, &xx);
+ return NC_NOERR;
+}
+')dnl
+
+dnl dnl dnl
+dnl
+dnl NCX_PUT1I(xtype, itype, isComptable) for integral types
+dnl
+define(`NCX_PUT1I',dnl
+`dnl
+static int
+ncmpix_put_$1_$2(void *xp, const $2 *ip)
+{
+ifelse(`$3', `1',
+``#'if IXsizeof($1) == Isizeof($2) && IXmax($1) == Upcase($2)_MAX
+ put_ix_$1(xp, (const ix_$1 *)ip);
+`#'else
+')dnl
+ ix_$1 xx;
+PUTI_CheckBND($1, $2)
+PUTI_CheckNeg($1, $2, *ip, xp)
+ xx = (ix_$1)*ip;
+ put_ix_$1(xp, &xx);
+ifelse(`$3', `1', ``#'endif
+')dnl
+ return NC_NOERR;
+}
+')dnl
+
+/* x_schar */
+/* x_uchar */
+
+/* We don't implement any x_schar and x_uchar primitives. */
+
+
+/* x_short -------------------------------------------------------------------*/
+
+#if SHORT_MAX == X_SHORT_MAX
+typedef short ix_short;
+#define SIZEOF_IX_SHORT SIZEOF_SHORT
+#define IX_SHORT_MAX SHORT_MAX
+#elif INT_MAX >= X_SHORT_MAX
+typedef int ix_short;
+#define SIZEOF_IX_SHORT SIZEOF_INT
+#define IX_SHORT_MAX INT_MAX
+#elif LONG_MAX >= X_SHORT_MAX
+typedef long ix_short;
+#define SIZEOF_IX_SHORT SIZEOF_LONG
+#define IX_SHORT_MAX LONG_MAX
+#elif LLONG_MAX >= X_SHORT_MAX
+typedef long long ix_short;
+#define SIZEOF_IX_SHORT SIZEOF_LONGLONG
+#define IX_SHORT_MAX LLONG_MAX
+#else
+#error "ix_short implementation"
+#endif
+
+static void
+get_ix_short(const void *xp, ix_short *ip)
+{
+ const uchar *cp = (const uchar *) xp;
+ *ip = *cp++ << 8;
+#if SIZEOF_IX_SHORT > X_SIZEOF_SHORT
+ if (*ip & 0x8000)
+ {
+ /* extern is negative */
+ *ip |= (~(0xffff)); /* N.B. Assumes "twos complement" */
+ }
+#endif
+ *ip |= *cp;
+}
+
+static void
+put_ix_short(void *xp, const ix_short *ip)
+{
+ uchar *cp = (uchar *) xp;
+ *cp++ = (*ip) >> 8;
+ *cp = (*ip) & 0xff;
+}
+
+NCX_GET1I(short, schar, 0)
+NCX_GET1I(short, short, 1)
+NCX_GET1I(short, int, 1)
+NCX_GET1I(short, long, 1)
+NCX_GET1I(short, longlong, 1)
+NCX_GET1I(short, ushort, 0)
+NCX_GET1I(short, uchar, 0)
+NCX_GET1I(short, uint, 0)
+NCX_GET1I(short, ulonglong, 0)
+NCX_GET1F(short, float)
+NCX_GET1F(short, double)
+
+static int
+ncmpix_put_short_schar(void *xp, const schar *ip)
+{
+ uchar *cp = (uchar *) xp;
+ if (*ip & 0x80)
+ *cp++ = 0xff;
+ else
+ *cp++ = 0;
+ *cp = (uchar)*ip;
+ return NC_NOERR;
+}
+
+static int
+ncmpix_put_short_uchar(void *xp, const uchar *ip)
+{
+ uchar *cp = (uchar *) xp;
+ *cp++ = 0;
+ *cp = *ip;
+ return NC_NOERR;
+}
+
+NCX_PUT1I(short, short, 1)
+NCX_PUT1I(short, int, 1)
+NCX_PUT1I(short, long, 1)
+NCX_PUT1I(short, longlong, 1)
+NCX_PUT1I(short, ushort, 0)
+NCX_PUT1I(short, uint, 0)
+NCX_PUT1I(short, ulonglong, 0)
+NCX_PUT1F(short, float)
+NCX_PUT1F(short, double)
+
+/* x_ushort ------------------------------------------------------------------*/
+
+#if USHORT_MAX == X_USHORT_MAX
+typedef unsigned short ix_ushort;
+#define SIZEOF_IX_USHORT SIZEOF_USHORT
+#define IX_USHORT_MAX USHORT_MAX
+#elif UINT_MAX >= X_USHORT_MAX
+typedef unsigned int ix_ushort;
+#define SIZEOF_IX_USHORT SIZEOF_UINT
+#define IX_USHORT_MAX UINT_MAX
+#elif ULONG_MAX >= X_USHORT_MAX
+typedef unsigned long ix_ushort;
+#define SIZEOF_IX_USHORT SIZEOF_ULONG
+#define IX_USHORT_MAX ULONG_MAX
+#elif ULLONG_MAX >= X_USHORT_MAX
+typedef unsigned long long ix_ushort;
+#define SIZEOF_IX_USHORT SIZEOF_ULONGLONG
+#define IX_USHORT_MAX ULLONG_MAX
+#else
+#error "ix_ushort implementation"
+#endif
+
+static void
+get_ix_ushort(const void *xp, ix_ushort *ip)
+{
+ const uchar *cp = (const uchar *) xp;
+ *ip = *cp++ << 8;
+#if SIZEOF_IX_SHORT > X_SIZEOF_SHORT
+ if (*ip & 0x8000)
+ {
+ /* extern is negative */
+ *ip |= (~(0xffff)); /* N.B. Assumes "twos complement" */
+ }
+#endif
+ *ip |= *cp;
+}
+
+static void
+put_ix_ushort(void *xp, const ix_ushort *ip)
+{
+ uchar *cp = (uchar *) xp;
+ *cp++ = (*ip) >> 8;
+ *cp = (*ip) & 0xff;
+}
+
+NCX_GET1I(ushort, schar, 0)
+NCX_GET1I(ushort, short, 0)
+NCX_GET1I(ushort, int, 0)
+NCX_GET1I(ushort, long, 0)
+NCX_GET1I(ushort, longlong, 0)
+NCX_GET1I(ushort, ushort, 1)
+NCX_GET1I(ushort, uchar, 1)
+NCX_GET1I(ushort, uint, 1)
+NCX_GET1I(ushort, ulonglong, 1)
+NCX_GET1F(ushort, float)
+NCX_GET1F(ushort, double)
+
+static int
+ncmpix_put_ushort_schar(void *xp, const schar *ip)
+{
+ uchar *cp;
+ if (*ip < 0) DEBUG_RETURN_ERROR(NC_ERANGE)
+ cp = (uchar *) xp;
+ if (*ip & 0x80)
+ *cp++ = 0xff;
+ else
+ *cp++ = 0;
+ *cp = (uchar)*ip;
+
+ return NC_NOERR;
+}
+
+static int
+ncmpix_put_ushort_uchar(void *xp, const uchar *ip)
+{
+ uchar *cp = (uchar *) xp;
+ *cp++ = 0;
+ *cp = *ip;
+ return NC_NOERR;
+}
+
+NCX_PUT1I(ushort, short, 0)
+NCX_PUT1I(ushort, int, 0)
+NCX_PUT1I(ushort, long, 0)
+NCX_PUT1I(ushort, longlong, 0)
+NCX_PUT1I(ushort, ushort, 1)
+NCX_PUT1I(ushort, uint, 1)
+NCX_PUT1I(ushort, ulonglong, 1)
+NCX_PUT1F(ushort, float)
+NCX_PUT1F(ushort, double)
+
+/* x_int ---------------------------------------------------------------------*/
+
+#if SHORT_MAX == X_INT_MAX
+typedef short ix_int;
+#define SIZEOF_IX_INT SIZEOF_SHORT
+#define IX_INT_MAX SHORT_MAX
+#elif INT_MAX >= X_INT_MAX
+typedef int ix_int;
+#define SIZEOF_IX_INT SIZEOF_INT
+#define IX_INT_MAX INT_MAX
+#elif LONG_MAX >= X_INT_MAX
+typedef long ix_int;
+#define SIZEOF_IX_INT SIZEOF_LONG
+#define IX_INT_MAX LONG_MAX
+#else
+#error "ix_int implementation"
+#endif
+
+
+static void
+get_ix_int(const void *xp, ix_int *ip)
+{
+ const uchar *cp = (const uchar *) xp;
+
+ *ip = *cp++ << 24;
+#if SIZEOF_IX_INT > X_SIZEOF_INT
+ if (*ip & 0x80000000)
+ {
+ /* extern is negative */
+ *ip |= (~(0xffffffff)); /* N.B. Assumes "twos complement" */
+ }
+#endif
+ *ip |= (*cp++ << 16);
+ *ip |= (*cp++ << 8);
+ *ip |= *cp;
+}
+
+static void
+put_ix_int(void *xp, const ix_int *ip)
+{
+ uchar *cp = (uchar *) xp;
+
+ *cp++ = (*ip) >> 24;
+ *cp++ = ((*ip) & 0x00ff0000) >> 16;
+ *cp++ = ((*ip) & 0x0000ff00) >> 8;
+ *cp = ((*ip) & 0x000000ff);
+}
+
+#if X_SIZEOF_INT != SIZEOF_INT
+NCX_GET1I(int, int, 1)
+#endif
+NCX_GET1I(int, schar, 0)
+NCX_GET1I(int, short, 1)
+NCX_GET1I(int, long, 1)
+NCX_GET1I(int, longlong, 1)
+NCX_GET1I(int, ushort, 0)
+NCX_GET1I(int, uchar, 0)
+NCX_GET1I(int, uint, 0)
+NCX_GET1I(int, ulonglong, 0)
+NCX_GET1F(int, float)
+NCX_GET1F(int, double)
+
+static int
+ncmpix_put_int_schar(void *xp, const schar *ip)
+{
+ uchar *cp = (uchar *) xp;
+ if (*ip & 0x80)
+ {
+ *cp++ = 0xff;
+ *cp++ = 0xff;
+ *cp++ = 0xff;
+ }
+ else
+ {
+ *cp++ = 0x00;
+ *cp++ = 0x00;
+ *cp++ = 0x00;
+ }
+ *cp = (uchar)*ip;
+ return NC_NOERR;
+}
+
+static int
+ncmpix_put_int_uchar(void *xp, const uchar *ip)
+{
+ uchar *cp = (uchar *) xp;
+ *cp++ = 0x00;
+ *cp++ = 0x00;
+ *cp++ = 0x00;
+ *cp = *ip;
+ return NC_NOERR;
+}
+
+#if X_SIZEOF_INT != SIZEOF_INT
+NCX_PUT1I(int, int, 1)
+#endif
+NCX_PUT1I(int, short, 1)
+NCX_PUT1I(int, long, 1)
+NCX_PUT1I(int, longlong, 1)
+NCX_PUT1I(int, ushort, 0)
+NCX_PUT1I(int, uint, 0)
+NCX_PUT1I(int, ulonglong, 0)
+NCX_PUT1F(int, float)
+NCX_PUT1F(int, double)
+
+
+/* x_uint --------------------------------------------------------------------*/
+
+#if USHORT_MAX == X_UINT_MAX
+typedef ushort ix_uint;
+#define SIZEOF_IX_UINT SIZEOF_USHORT
+#define IX_UINT_MAX USHORT_MAX
+#elif UINT_MAX >= X_UINT_MAX
+typedef uint ix_uint;
+#define SIZEOF_IX_UINT SIZEOF_UINT
+#define IX_UINT_MAX UINT_MAX
+#elif ULONG_MAX >= X_UINT_MAX
+typedef ulong ix_uint;
+#define SIZEOF_IX_UINT SIZEOF_ULONG
+#define IX_UINT_MAX ULONG_MAX
+#else
+#error "ix_uint implementation"
+#endif
+
+
+static void
+get_ix_uint(const void *xp, ix_uint *ip)
+{
+ const uchar *cp = (const uchar *) xp;
+
+ *ip = (ix_uint)(*cp++ << 24);
+ *ip |= (ix_uint)(*cp++ << 16);
+ *ip |= (ix_uint)(*cp++ << 8);
+ *ip |= *cp;
+}
+
+static void
+put_ix_uint(void *xp, const ix_uint *ip)
+{
+ uchar *cp = (uchar *) xp;
+
+ *cp++ = (*ip) >> 24;
+ *cp++ = ((*ip) & 0x00ff0000) >> 16;
+ *cp++ = ((*ip) & 0x0000ff00) >> 8;
+ *cp = ((*ip) & 0x000000ff);
+}
+
+#if X_SIZEOF_UINT != SIZEOF_UINT
+NCX_GET1I(uint, uint, 1)
+#endif
+
+NCX_GET1I(uint, schar, 0)
+NCX_GET1I(uint, short, 0)
+NCX_GET1I(uint, int, 0)
+NCX_GET1I(uint, long, 0)
+NCX_GET1I(uint, longlong, 0)
+NCX_GET1I(uint, ushort, 1)
+NCX_GET1I(uint, uchar, 1)
+NCX_GET1I(uint, ulonglong, 1)
+NCX_GET1F(uint, float)
+NCX_GET1F(uint, double)
+
+static int
+ncmpix_put_uint_schar(void *xp, const schar *ip)
+{
+ uchar *cp;
+ if (*ip < 0) DEBUG_RETURN_ERROR(NC_ERANGE)
+
+ cp = (uchar *) xp;
+ *cp++ = 0x00;
+ *cp++ = 0x00;
+ *cp++ = 0x00;
+ *cp = (uchar)*ip;
+
+ return NC_NOERR;
+}
+
+static int
+ncmpix_put_uint_uchar(void *xp, const uchar *ip)
+{
+ uchar *cp = (uchar *) xp;
+ *cp++ = 0x00;
+ *cp++ = 0x00;
+ *cp++ = 0x00;
+ *cp = *ip;
+ return NC_NOERR;
+}
+
+#if X_SIZEOF_UINT != SIZEOF_UINT
+NCX_PUT1I(uint, uint, 1)
+#endif
+
+NCX_PUT1I(uint, short, 0)
+NCX_PUT1I(uint, int, 0)
+NCX_PUT1I(uint, long, 0)
+NCX_PUT1I(uint, longlong, 0)
+NCX_PUT1I(uint, ushort, 1)
+NCX_PUT1I(uint, ulonglong, 1)
+NCX_PUT1F(uint, float)
+NCX_PUT1F(uint, double)
+
+
+/* x_float -------------------------------------------------------------------*/
+
+#if X_SIZEOF_FLOAT == SIZEOF_FLOAT && !defined(NO_IEEE_FLOAT)
+
+static void
+get_ix_float(const void *xp, float *ip)
+{
+#ifdef WORDS_BIGENDIAN
+ (void) memcpy(ip, xp, SIZEOF_FLOAT);
+#else
+ swap4b(ip, xp);
+#endif
+}
+
+static void
+put_ix_float(void *xp, const float *ip)
+{
+#ifdef WORDS_BIGENDIAN
+ (void) memcpy(xp, ip, X_SIZEOF_FLOAT);
+#else
+ swap4b(xp, ip);
+#endif
+}
+
+#elif defined(vax) && vax != 0
+
+/* What IEEE single precision floating point looks like on a Vax */
+struct ieee_single {
+ unsigned int exp_hi : 7;
+ unsigned int sign : 1;
+ unsigned int mant_hi : 7;
+ unsigned int exp_lo : 1;
+ unsigned int mant_lo_hi : 8;
+ unsigned int mant_lo_lo : 8;
+};
+
+/* Vax single precision floating point */
+struct vax_single {
+ unsigned int mantissa1 : 7;
+ unsigned int exp : 8;
+ unsigned int sign : 1;
+ unsigned int mantissa2 : 16;
+};
+
+#define VAX_SNG_BIAS 0x81
+#define IEEE_SNG_BIAS 0x7f
+
+static struct sgl_limits {
+ struct vax_single s;
+ struct ieee_single ieee;
+} max = {
+ { 0x7f, 0xff, 0x0, 0xffff }, /* Max Vax */
+ { 0x7f, 0x0, 0x0, 0x1, 0x0, 0x0 } /* Max IEEE */
+};
+static struct sgl_limits min = {
+ { 0x0, 0x0, 0x0, 0x0 }, /* Min Vax */
+ { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } /* Min IEEE */
+};
+
+dnl dnl dnl
+dnl
+dnl GET_VAX_DFLOAT_Body(xp) (body for get_ix_float)
+dnl
+define(`GET_VAX_DFLOAT_Body',dnl
+`dnl
+ struct vax_single *const vsp = (struct vax_single *) ip;
+ const struct ieee_single *const isp =
+ (const struct ieee_single *) $1;
+ unsigned exp = isp->exp_hi << 1 | isp->exp_lo;
+
+ switch(exp) {
+ case 0 :
+ /* ieee subnormal */
+ if (isp->mant_hi == min.ieee.mant_hi
+ && isp->mant_lo_hi == min.ieee.mant_lo_hi
+ && isp->mant_lo_lo == min.ieee.mant_lo_lo)
+ {
+ *vsp = min.s;
+ }
+ else
+ {
+ unsigned mantissa = (isp->mant_hi << 16)
+ | isp->mant_lo_hi << 8
+ | isp->mant_lo_lo;
+ unsigned tmp = mantissa >> 20;
+ if (tmp >= 4) {
+ vsp->exp = 2;
+ } else if (tmp >= 2) {
+ vsp->exp = 1;
+ } else {
+ *vsp = min.s;
+ break;
+ } /* else */
+ tmp = mantissa - (1 << (20 + vsp->exp ));
+ tmp <<= 3 - vsp->exp;
+ vsp->mantissa2 = tmp;
+ vsp->mantissa1 = (tmp >> 16);
+ }
+ break;
+ case 0xfe :
+ case 0xff :
+ *vsp = max.s;
+ break;
+ default :
+ vsp->exp = exp - IEEE_SNG_BIAS + VAX_SNG_BIAS;
+ vsp->mantissa2 = isp->mant_lo_hi << 8 | isp->mant_lo_lo;
+ vsp->mantissa1 = isp->mant_hi;
+ }
+
+ vsp->sign = isp->sign;
+')dnl
+static void
+get_ix_float(const void *xp, float *ip)
+{
+GET_VAX_DFLOAT_Body(xp)
+}
+
+dnl dnl dnl
+dnl
+dnl PUT_VAX_DFLOAT_Body(xp) (body for get_ix_float)
+dnl
+define(`PUT_VAX_DFLOAT_Body',dnl
+`dnl
+ const struct vax_single *const vsp =
+ (const struct vax_single *)ip;
+ struct ieee_single *const isp = (struct ieee_single *) $1;
+
+ switch(vsp->exp){
+ case 0 :
+ /* all vax float with zero exponent map to zero */
+ *isp = min.ieee;
+ break;
+ case 2 :
+ case 1 :
+ {
+ /* These will map to subnormals */
+ unsigned mantissa = (vsp->mantissa1 << 16)
+ | vsp->mantissa2;
+ mantissa >>= 3 - vsp->exp;
+ mantissa += (1 << (20 + vsp->exp));
+ isp->mant_lo_lo = mantissa;
+ isp->mant_lo_hi = mantissa >> 8;
+ isp->mant_hi = mantissa >> 16;
+ isp->exp_lo = 0;
+ isp->exp_hi = 0;
+ }
+ break;
+ case 0xff : /* max.s.exp */
+ if (vsp->mantissa2 == max.s.mantissa2 &&
+ vsp->mantissa1 == max.s.mantissa1)
+ {
+ /* map largest vax float to ieee infinity */
+ *isp = max.ieee;
+ break;
+ } /* else, fall thru */
+ default :
+ {
+ unsigned exp = vsp->exp - VAX_SNG_BIAS + IEEE_SNG_BIAS;
+ isp->exp_hi = exp >> 1;
+ isp->exp_lo = exp;
+ isp->mant_lo_lo = vsp->mantissa2;
+ isp->mant_lo_hi = vsp->mantissa2 >> 8;
+ isp->mant_hi = vsp->mantissa1;
+ }
+ }
+
+ isp->sign = vsp->sign;
+')dnl
+
+static void
+put_ix_float(void *xp, const float *ip)
+{
+PUT_VAX_DFLOAT_Body(xp)
+}
+
+ /* vax */
+#elif defined(_CRAY) && !defined(__crayx1)
+
+/*
+ * Return the number of bytes until the next "word" boundary
+ * N.B. This is based on the very weird YMP address structure,
+ * which puts the address within a word in the leftmost 3 bits
+ * of the address.
+ */
+static size_t
+word_align(const void *vp)
+{
+ const size_t rem = ((size_t)vp >> (64 - 3)) & 0x7;
+ return (rem != 0);
+}
+
+struct ieee_single_hi {
+ unsigned int sign : 1;
+ unsigned int exp : 8;
+ unsigned int mant :23;
+ unsigned int pad :32;
+};
+typedef struct ieee_single_hi ieee_single_hi;
+
+struct ieee_single_lo {
+ unsigned int pad :32;
+ unsigned int sign : 1;
+ unsigned int exp : 8;
+ unsigned int mant :23;
+};
+typedef struct ieee_single_lo ieee_single_lo;
+
+static const int ieee_single_bias = 0x7f;
+
+struct ieee_double {
+ unsigned int sign : 1;
+ unsigned int exp :11;
+ unsigned int mant :52;
+};
+typedef struct ieee_double ieee_double;
+
+static const int ieee_double_bias = 0x3ff;
+
+#if defined(NO_IEEE_FLOAT)
+
+struct cray_single {
+ unsigned int sign : 1;
+ unsigned int exp :15;
+ unsigned int mant :48;
+};
+typedef struct cray_single cray_single;
+
+static const int cs_ieis_bias = 0x4000 - 0x7f;
+
+static const int cs_id_bias = 0x4000 - 0x3ff;
+
+dnl dnl dnl
+dnl
+dnl GET_IX_FLOAT_Body (body for get_ix_float)
+dnl
+define(`GET_IX_FLOAT_Body',dnl
+`dnl
+ cray_single *csp = (cray_single *) ip;
+
+ if (isp->exp == 0)
+ {
+ /* ieee subnormal */
+ *ip = (double)isp->mant;
+ if (isp->mant != 0)
+ {
+ csp->exp -= (ieee_single_bias + 22);
+ }
+ }
+ else
+ {
+ csp->exp = isp->exp + cs_ieis_bias + 1;
+ csp->mant = isp->mant << (48 - 1 - 23);
+ csp->mant |= (1 << (48 - 1));
+ }
+ csp->sign = isp->sign;
+
+')dnl
+dnl dnl dnl
+dnl
+dnl PUT_IX_FLOAT_Body (body for put_ix_float)
+dnl
+define(`PUT_IX_FLOAT_Body',dnl
+`dnl
+ const cray_single *csp = (const cray_single *) ip;
+ int ieee_exp = csp->exp - cs_ieis_bias -1;
+
+ isp->sign = csp->sign;
+
+ if (ieee_exp >= 0xff)
+ {
+ /* NC_ERANGE => ieee Inf */
+ isp->exp = 0xff;
+ isp->mant = 0x0;
+ }
+ else if (ieee_exp > 0)
+ {
+ /* normal ieee representation */
+ isp->exp = ieee_exp;
+ /* assumes cray rep is in normal form */
+ assert(csp->mant & 0x800000000000);
+ isp->mant = (((csp->mant << 1) &
+ 0xffffffffffff) >> (48 - 23));
+ }
+ else if (ieee_exp > -23)
+ {
+ /* ieee subnormal, right shift */
+ const int rshift = (48 - 23 - ieee_exp);
+
+ isp->mant = csp->mant >> rshift;
+
+#if 0
+ if (csp->mant & (1 << (rshift -1)))
+ {
+ /* round up */
+ isp->mant++;
+ }
+#endif
+
+ isp->exp = 0;
+ }
+ else
+ {
+ /* smaller than ieee can represent */
+ isp->exp = 0;
+ isp->mant = 0;
+ }
+')dnl
+
+static void
+get_ix_float(const void *xp, float *ip)
+{
+
+ if (word_align(xp) == 0)
+ {
+ const ieee_single_hi *isp = (const ieee_single_hi *) xp;
+GET_IX_FLOAT_Body
+ }
+ else
+ {
+ const ieee_single_lo *isp = (const ieee_single_lo *) xp;
+GET_IX_FLOAT_Body
+ }
+}
+
+static void
+put_ix_float(void *xp, const float *ip)
+{
+ if (word_align(xp) == 0)
+ {
+ ieee_single_hi *isp = (ieee_single_hi*)xp;
+PUT_IX_FLOAT_Body
+ }
+ else
+ {
+ ieee_single_lo *isp = (ieee_single_lo*)xp;
+PUT_IX_FLOAT_Body
+ }
+}
+
+#else
+ /* IEEE Cray with only doubles */
+static void
+get_ix_float(const void *xp, float *ip)
+{
+
+ ieee_double *idp = (ieee_double *) ip;
+
+ if (word_align(xp) == 0)
+ {
+ const ieee_single_hi *isp = (const ieee_single_hi *) xp;
+ if (isp->exp == 0 && isp->mant == 0)
+ {
+ idp->exp = 0;
+ idp->mant = 0;
+ }
+ else
+ {
+ idp->exp = isp->exp + (ieee_double_bias - ieee_single_bias);
+ idp->mant = isp->mant << (52 - 23);
+ }
+ idp->sign = isp->sign;
+ }
+ else
+ {
+ const ieee_single_lo *isp = (const ieee_single_lo *) xp;
+ if (isp->exp == 0 && isp->mant == 0)
+ {
+ idp->exp = 0;
+ idp->mant = 0;
+ }
+ else
+ {
+ idp->exp = isp->exp + (ieee_double_bias - ieee_single_bias);
+ idp->mant = isp->mant << (52 - 23);
+ }
+ idp->sign = isp->sign;
+ }
+}
+
+static void
+put_ix_float(void *xp, const float *ip)
+{
+ const ieee_double *idp = (const ieee_double *) ip;
+ if (word_align(xp) == 0)
+ {
+ ieee_single_hi *isp = (ieee_single_hi*)xp;
+ if (idp->exp > (ieee_double_bias - ieee_single_bias))
+ isp->exp = idp->exp - (ieee_double_bias - ieee_single_bias);
+ else
+ isp->exp = 0;
+ isp->mant = idp->mant >> (52 - 23);
+ isp->sign = idp->sign;
+ }
+ else
+ {
+ ieee_single_lo *isp = (ieee_single_lo*)xp;
+ if (idp->exp > (ieee_double_bias - ieee_single_bias))
+ isp->exp = idp->exp - (ieee_double_bias - ieee_single_bias);
+ else
+ isp->exp = 0;
+ isp->mant = idp->mant >> (52 - 23);
+ isp->sign = idp->sign;
+ }
+}
+#endif
+
+#else
+#error "ix_float implementation"
+#endif
+
+#if X_SIZEOF_FLOAT != SIZEOF_FLOAT || defined(NO_IEEE_FLOAT)
+static int
+ncmpix_get_float_float(const void *xp, float *ip)
+{
+ /* TODO */
+ get_ix_float(xp, ip);
+ return NC_NOERR;
+}
+#endif
+
+#define ix_float float
+
+NCX_GET1F(float, schar)
+NCX_GET1F(float, short)
+NCX_GET1F(float, int)
+NCX_GET1F(float, long)
+NCX_GET1F(float, double)
+NCX_GET1F(float, longlong)
+NCX_GET1F(float, uchar)
+NCX_GET1F(float, ushort)
+NCX_GET1F(float, uint)
+NCX_GET1F(float, ulonglong)
+
+#if X_SIZEOF_FLOAT != SIZEOF_FLOAT || defined(NO_IEEE_FLOAT)
+static int
+ncmpix_put_float_float(void *xp, const float *ip)
+{
+#ifdef NO_IEEE_FLOAT
+ if (*ip > X_FLOAT_MAX || *ip < X_FLOAT_MIN)
+ DEBUG_RETURN_ERROR(NC_ERANGE)
+#endif
+ put_ix_float(xp, ip);
+ return NC_NOERR;
+}
+#endif
+
+NCX_PUT1F(float, schar)
+NCX_PUT1F(float, short)
+NCX_PUT1F(float, int)
+NCX_PUT1F(float, long)
+NCX_PUT1F(float, double)
+NCX_PUT1F(float, longlong)
+NCX_PUT1F(float, uchar)
+NCX_PUT1F(float, ushort)
+NCX_PUT1F(float, uint)
+NCX_PUT1F(float, ulonglong)
+
+
+/* x_double ------------------------------------------------------------------*/
+
+#if X_SIZEOF_DOUBLE == SIZEOF_DOUBLE && !defined(NO_IEEE_FLOAT)
+
+static void
+get_ix_double(const void *xp, double *ip)
+{
+#ifdef WORDS_BIGENDIAN
+ (void) memcpy(ip, xp, SIZEOF_DOUBLE);
+#else
+ swap8b(ip, xp);
+#endif
+}
+
+static void
+put_ix_double(void *xp, const double *ip)
+{
+#ifdef WORDS_BIGENDIAN
+ (void) memcpy(xp, ip, X_SIZEOF_DOUBLE);
+#else
+ swap8b(xp, ip);
+#endif
+}
+
+#elif defined(vax) && vax != 0
+
+/* What IEEE double precision floating point looks like on a Vax */
+struct ieee_double {
+ unsigned int exp_hi : 7;
+ unsigned int sign : 1;
+ unsigned int mant_6 : 4;
+ unsigned int exp_lo : 4;
+ unsigned int mant_5 : 8;
+ unsigned int mant_4 : 8;
+
+ unsigned int mant_lo : 32;
+};
+
+/* Vax double precision floating point */
+struct vax_double {
+ unsigned int mantissa1 : 7;
+ unsigned int exp : 8;
+ unsigned int sign : 1;
+ unsigned int mantissa2 : 16;
+ unsigned int mantissa3 : 16;
+ unsigned int mantissa4 : 16;
+};
+
+#define VAX_DBL_BIAS 0x81
+#define IEEE_DBL_BIAS 0x3ff
+#define MASK(nbits) ((1 << nbits) - 1)
+
+static const struct dbl_limits {
+ struct vax_double d;
+ struct ieee_double ieee;
+} dbl_limits[2] = {
+ {{ 0x7f, 0xff, 0x0, 0xffff, 0xffff, 0xffff }, /* Max Vax */
+ { 0x7f, 0x0, 0x0, 0xf, 0x0, 0x0, 0x0}}, /* Max IEEE */
+ {{ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, /* Min Vax */
+ { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}}, /* Min IEEE */
+};
+
+
+dnl dnl dnl
+dnl
+dnl GET_VAX_DDOUBLE_Body(xp) (body for get_ix_double)
+dnl
+define(`GET_VAX_DDOUBLE_Body',dnl
+`dnl
+ struct vax_double *const vdp =
+ (struct vax_double *)ip;
+ const struct ieee_double *const idp =
+ (const struct ieee_double *) $1;
+ {
+ const struct dbl_limits *lim;
+ int ii;
+ for (ii = 0, lim = dbl_limits;
+ ii < sizeof(dbl_limits)/sizeof(struct dbl_limits);
+ ii++, lim++)
+ {
+ if ((idp->mant_lo == lim->ieee.mant_lo)
+ && (idp->mant_4 == lim->ieee.mant_4)
+ && (idp->mant_5 == lim->ieee.mant_5)
+ && (idp->mant_6 == lim->ieee.mant_6)
+ && (idp->exp_lo == lim->ieee.exp_lo)
+ && (idp->exp_hi == lim->ieee.exp_hi)
+ )
+ {
+ *vdp = lim->d;
+ goto doneit;
+ }
+ }
+ }
+ {
+ unsigned exp = idp->exp_hi << 4 | idp->exp_lo;
+ vdp->exp = exp - IEEE_DBL_BIAS + VAX_DBL_BIAS;
+ }
+ {
+ unsigned mant_hi = ((idp->mant_6 << 16)
+ | (idp->mant_5 << 8)
+ | idp->mant_4);
+ unsigned mant_lo = SWAP4(idp->mant_lo);
+ vdp->mantissa1 = (mant_hi >> 13);
+ vdp->mantissa2 = ((mant_hi & MASK(13)) << 3)
+ | (mant_lo >> 29);
+ vdp->mantissa3 = (mant_lo >> 13);
+ vdp->mantissa4 = (mant_lo << 3);
+ }
+ doneit:
+ vdp->sign = idp->sign;
+')dnl
+static void
+get_ix_double(const void *xp, double *ip)
+{
+GET_VAX_DDOUBLE_Body(xp)
+}
+
+
+dnl dnl dnl
+dnl
+dnl PUT_VAX_DDOUBLE_Body(xp) (body for put_ix_double)
+dnl
+define(`PUT_VAX_DDOUBLE_Body',dnl
+`dnl
+ const struct vax_double *const vdp =
+ (const struct vax_double *)ip;
+ struct ieee_double *const idp =
+ (struct ieee_double *) $1;
+
+ if ((vdp->mantissa4 > (dbl_limits[0].d.mantissa4 - 3)) &&
+ (vdp->mantissa3 == dbl_limits[0].d.mantissa3) &&
+ (vdp->mantissa2 == dbl_limits[0].d.mantissa2) &&
+ (vdp->mantissa1 == dbl_limits[0].d.mantissa1) &&
+ (vdp->exp == dbl_limits[0].d.exp))
+ {
+ *idp = dbl_limits[0].ieee;
+ goto shipit;
+ }
+ if ((vdp->mantissa4 == dbl_limits[1].d.mantissa4) &&
+ (vdp->mantissa3 == dbl_limits[1].d.mantissa3) &&
+ (vdp->mantissa2 == dbl_limits[1].d.mantissa2) &&
+ (vdp->mantissa1 == dbl_limits[1].d.mantissa1) &&
+ (vdp->exp == dbl_limits[1].d.exp))
+ {
+ *idp = dbl_limits[1].ieee;
+ goto shipit;
+ }
+
+ {
+ unsigned exp = vdp->exp - VAX_DBL_BIAS + IEEE_DBL_BIAS;
+
+ unsigned mant_lo = ((vdp->mantissa2 & MASK(3)) << 29) |
+ (vdp->mantissa3 << 13) |
+ ((vdp->mantissa4 >> 3) & MASK(13));
+
+ unsigned mant_hi = (vdp->mantissa1 << 13)
+ | (vdp->mantissa2 >> 3);
+
+ if ((vdp->mantissa4 & 7) > 4)
+ {
+ /* round up */
+ mant_lo++;
+ if (mant_lo == 0)
+ {
+ mant_hi++;
+ if (mant_hi > 0xffffff)
+ {
+ mant_hi = 0;
+ exp++;
+ }
+ }
+ }
+
+ idp->mant_lo = SWAP4(mant_lo);
+ idp->mant_6 = mant_hi >> 16;
+ idp->mant_5 = (mant_hi & 0xff00) >> 8;
+ idp->mant_4 = mant_hi;
+ idp->exp_hi = exp >> 4;
+ idp->exp_lo = exp;
+ }
+
+ shipit:
+ idp->sign = vdp->sign;
+')dnl
+static void
+put_ix_double(void *xp, const double *ip)
+{
+PUT_VAX_DDOUBLE_Body(xp)
+}
+
+ /* vax */
+#elif defined(_CRAY) && !defined(__crayx1)
+
+static void
+get_ix_double(const void *xp, double *ip)
+{
+ const ieee_double *idp = (const ieee_double *) xp;
+ cray_single *csp = (cray_single *) ip;
+
+ if (idp->exp == 0)
+ {
+ /* ieee subnormal */
+ *ip = (double)idp->mant;
+ if (idp->mant != 0)
+ {
+ csp->exp -= (ieee_double_bias + 51);
+ }
+ }
+ else
+ {
+ csp->exp = idp->exp + cs_id_bias + 1;
+ csp->mant = idp->mant >> (52 - 48 + 1);
+ csp->mant |= (1 << (48 - 1));
+ }
+ csp->sign = idp->sign;
+}
+
+static void
+put_ix_double(void *xp, const double *ip)
+{
+ ieee_double *idp = (ieee_double *) xp;
+ const cray_single *csp = (const cray_single *) ip;
+
+ int ieee_exp = csp->exp - cs_id_bias -1;
+
+ idp->sign = csp->sign;
+
+ if (ieee_exp >= 0x7ff)
+ {
+ /* NC_ERANGE => ieee Inf */
+ idp->exp = 0x7ff;
+ idp->mant = 0x0;
+ }
+ else if (ieee_exp > 0)
+ {
+ /* normal ieee representation */
+ idp->exp = ieee_exp;
+ /* assumes cray rep is in normal form */
+ assert(csp->mant & 0x800000000000);
+ idp->mant = (((csp->mant << 1) &
+ 0xffffffffffff) << (52 - 48));
+ }
+ else if (ieee_exp >= (-(52 -48)))
+ {
+ /* ieee subnormal, left shift */
+ const int lshift = (52 - 48) + ieee_exp;
+ idp->mant = csp->mant << lshift;
+ idp->exp = 0;
+ }
+ else if (ieee_exp >= -52)
+ {
+ /* ieee subnormal, right shift */
+ const int rshift = (- (52 - 48) - ieee_exp);
+
+ idp->mant = csp->mant >> rshift;
+
+#if 0
+ if (csp->mant & (1 << (rshift -1)))
+ {
+ /* round up */
+ idp->mant++;
+ }
+#endif
+
+ idp->exp = 0;
+ }
+ else
+ {
+ /* smaller than ieee can represent */
+ idp->exp = 0;
+ idp->mant = 0;
+ }
+}
+#else
+#error "ix_double implementation"
+#endif
+
+#define ix_double double
+
+NCX_GET1F(double, schar)
+NCX_GET1F(double, short)
+NCX_GET1F(double, int)
+NCX_GET1F(double, long)
+NCX_GET1F(double, longlong)
+NCX_GET1F(double, uchar)
+NCX_GET1F(double, ushort)
+NCX_GET1F(double, uint)
+NCX_GET1F(double, ulonglong)
+
+static int
+ncmpix_get_double_float(const void *xp, float *ip)
+{
+ double xx;
+ get_ix_double(xp, &xx);
+ if (xx > FLT_MAX)
+ {
+ *ip = FLT_MAX;
+ DEBUG_RETURN_ERROR(NC_ERANGE)
+ }
+ if (xx < (-FLT_MAX))
+ {
+ *ip = (-FLT_MAX);
+ DEBUG_RETURN_ERROR(NC_ERANGE)
+ }
+ *ip = (float) xx;
+ return NC_NOERR;
+}
+
+#if X_SIZEOF_DOUBLE != SIZEOF_DOUBLE || defined(NO_IEEE_FLOAT)
+static int
+ncmpix_get_double_double(const void *xp, double *ip)
+{
+ /* TODO */
+ get_ix_double(xp, ip);
+ return NC_NOERR;
+}
+#endif
+
+NCX_PUT1F(double, schar)
+NCX_PUT1F(double, uchar)
+NCX_PUT1F(double, short)
+NCX_PUT1F(double, ushort)
+NCX_PUT1F(double, int)
+NCX_PUT1F(double, long)
+NCX_PUT1F(double, uint)
+NCX_PUT1F(double, longlong)
+NCX_PUT1F(double, ulonglong)
+
+static int
+ncmpix_put_double_float(void *xp, const float *ip)
+{
+#if 0 /* TODO: figure this out (if condition below will never be true)*/
+ if ((double)(*ip) > X_DOUBLE_MAX || (double)(*ip) < X_DOUBLE_MIN)
+ DEBUG_RETURN_ERROR(NC_ERANGE)
+#endif
+ double xx = (double) *ip;
+ put_ix_double(xp, &xx);
+ return NC_NOERR;
+}
+
+#if X_SIZEOF_DOUBLE != SIZEOF_DOUBLE || defined(NO_IEEE_FLOAT)
+static int
+ncmpix_put_double_double(void *xp, const double *ip)
+{
+#ifdef NO_IEEE_FLOAT
+ if (*ip > X_DOUBLE_MAX || *ip < X_DOUBLE_MIN)
+ DEBUG_RETURN_ERROR(NC_ERANGE)
+#endif
+ put_ix_double(xp, ip);
+ return NC_NOERR;
+}
+#endif
+
+
+/* x_int64 -------------------------------------------------------------------*/
+
+#if SHORT_MAX == X_INT64_MAX
+typedef short ix_int64;
+#define SIZEOF_IX_INT64 SIZEOF_SHORT
+#define IX_INT64_MAX SHORT_MAX
+#elif LONG_LONG_MAX >= X_INT64_MAX
+typedef longlong ix_int64;
+#define SIZEOF_IX_INT64 SIZEOF_LONGLONG
+#define IX_INT64_MAX LONG_LONG_MAX
+#elif LONG_MAX >= X_INT64_MAX
+typedef long ix_int64;
+#define SIZEOF_IX_INT64 SIZEOF_LONG
+#define IX_INT64_MAX LONG_MAX
+#else
+#error "ix_int64 implementation"
+#endif
+
+
+static void
+get_ix_int64(const void *xp, ix_int64 *ip)
+{
+ const uchar *cp = (const uchar *) xp;
+
+ *ip = ((ix_int64)(*cp++) << 56);
+ *ip |= ((ix_int64)(*cp++) << 48);
+ *ip |= ((ix_int64)(*cp++) << 40);
+ *ip |= ((ix_int64)(*cp++) << 32);
+ *ip |= ((ix_int64)(*cp++) << 24);
+ *ip |= ((ix_int64)(*cp++) << 16);
+ *ip |= ((ix_int64)(*cp++) << 8);
+ *ip |= (ix_int64)*cp;
+}
+
+static void
+put_ix_int64(void *xp, const ix_int64 *ip)
+{
+ uchar *cp = (uchar *) xp;
+
+ *cp++ = (*ip) >> 56;
+ *cp++ = ((*ip) & 0x00ff000000000000LL) >> 48;
+ *cp++ = ((*ip) & 0x0000ff0000000000LL) >> 40;
+ *cp++ = ((*ip) & 0x000000ff00000000LL) >> 32;
+ *cp++ = ((*ip) & 0x00000000ff000000LL) >> 24;
+ *cp++ = ((*ip) & 0x0000000000ff0000LL) >> 16;
+ *cp++ = ((*ip) & 0x000000000000ff00LL) >> 8;
+ *cp = ((*ip) & 0x00000000000000ffLL);
+}
+
+#if X_SIZEOF_INT64 != SIZEOF_LONGLONG
+NCX_GET1I(int64, longlong, 1)
+#endif
+NCX_GET1I(int64, schar, 0)
+NCX_GET1I(int64, short, 1)
+NCX_GET1I(int64, int, 1)
+NCX_GET1I(int64, long, 1)
+NCX_GET1I(int64, ushort, 0)
+NCX_GET1I(int64, uchar, 0)
+NCX_GET1I(int64, uint, 0)
+NCX_GET1I(int64, ulonglong, 0)
+NCX_GET1F(int64, float)
+NCX_GET1F(int64, double)
+
+#if X_SIZEOF_INT64 != SIZEOF_LONGLONG
+NCX_PUT1I(int64, longlong, 1)
+#endif
+NCX_PUT1I(int64, schar, 0)
+NCX_PUT1I(int64, short, 1)
+NCX_PUT1I(int64, int, 1)
+NCX_PUT1I(int64, long, 1)
+NCX_PUT1I(int64, ushort, 0)
+NCX_PUT1I(int64, uchar, 0)
+NCX_PUT1I(int64, uint, 0)
+NCX_PUT1I(int64, ulonglong, 0)
+NCX_PUT1F(int64, float)
+NCX_PUT1F(int64, double)
+
+
+/* x_uint64 -----------------------------------------------------------------*/
+
+#if USHORT_MAX == X_UINT64_MAX
+typedef ushort ix_uint64;
+#define SIZEOF_IX_UINT64 SIZEOF_USHORT
+#define IX_UINT64_MAX USHORT_MAX
+#elif ULONG_LONG_MAX >= X_UINT64_MAX
+typedef ulonglong ix_uint64;
+#define SIZEOF_IX_UINT64 SIZEOF_ULONGLONG
+#define IX_UINT64_MAX ULONG_LONG_MAX
+#elif ULONG_MAX >= X_UINT64_MAX
+typedef ulong ix_uint64;
+#define SIZEOF_IX_UINT64 SIZEOF_ULONG
+#define IX_UINT64_MAX ULONG_MAX
+#else
+#error "ix_uint64 implementation"
+#endif
+
+
+static void
+get_ix_uint64(const void *xp, ix_uint64 *ip)
+{
+ const uchar *cp = (const uchar *) xp;
+
+ *ip = ((ix_uint64)(*cp++) << 56);
+ *ip |= ((ix_uint64)(*cp++) << 48);
+ *ip |= ((ix_uint64)(*cp++) << 40);
+ *ip |= ((ix_uint64)(*cp++) << 32);
+ *ip |= ((ix_uint64)(*cp++) << 24);
+ *ip |= ((ix_uint64)(*cp++) << 16);
+ *ip |= ((ix_uint64)(*cp++) << 8);
+ *ip |= (ix_uint64)*cp;
+}
+
+static void
+put_ix_uint64(void *xp, const ix_uint64 *ip)
+{
+ uchar *cp = (uchar *) xp;
+
+ *cp++ = (*ip) >> 56;
+ *cp++ = ((*ip) & 0x00ff000000000000ULL) >> 48;
+ *cp++ = ((*ip) & 0x0000ff0000000000ULL) >> 40;
+ *cp++ = ((*ip) & 0x000000ff00000000ULL) >> 32;
+ *cp++ = ((*ip) & 0x00000000ff000000ULL) >> 24;
+ *cp++ = ((*ip) & 0x0000000000ff0000ULL) >> 16;
+ *cp++ = ((*ip) & 0x000000000000ff00ULL) >> 8;
+ *cp = ((*ip) & 0x00000000000000ffULL);
+}
+
+#if X_SIZEOF_UINT64 != SIZEOF_ULONGLONG
+NCX_GET1I(uint64, ulonglong, 1)
+#endif
+NCX_GET1I(uint64, schar, 0)
+NCX_GET1I(uint64, short, 0)
+NCX_GET1I(uint64, int, 0)
+NCX_GET1I(uint64, long, 0)
+NCX_GET1I(uint64, longlong, 0)
+NCX_GET1I(uint64, ushort, 1)
+NCX_GET1I(uint64, uchar, 1)
+NCX_GET1I(uint64, uint, 1)
+NCX_GET1F(uint64, float)
+NCX_GET1F(uint64, double)
+
+#if X_SIZEOF_UINT64 != SIZEOF_ULONGLONG
+NCX_PUT1I(uint64, ulonglong, 1)
+#endif
+NCX_PUT1I(uint64, schar, 0)
+NCX_PUT1I(uint64, short, 0)
+NCX_PUT1I(uint64, int, 0)
+NCX_PUT1I(uint64, long, 0)
+NCX_PUT1I(uint64, longlong, 0)
+NCX_PUT1I(uint64, uchar, 1)
+NCX_PUT1I(uint64, ushort, 1)
+NCX_PUT1I(uint64, uint, 1)
+NCX_PUT1F(uint64, float)
+NCX_PUT1F(uint64, double)
+
+
+/* x_size_t */
+
+#if SIZEOF_SIZE_T < X_SIZEOF_SIZE_T
+#error "x_size_t implementation"
+/* netcdf requires size_t which can hold a values from 0 to 2^32 -1 */
+#endif
+
+int
+ncmpix_put_size_t(void **xpp, const size_t *ulp)
+{
+ /* similar to put_ix_int() */
+ uchar *cp = (uchar *) *xpp;
+ assert(*ulp <= X_SIZE_MAX);
+
+ *cp++ = (uchar)((*ulp) >> 24);
+ *cp++ = (uchar)(((*ulp) & 0x00ff0000) >> 16);
+ *cp++ = (uchar)(((*ulp) & 0x0000ff00) >> 8);
+ *cp = (uchar)((*ulp) & 0x000000ff);
+
+ *xpp = (void *)((char *)(*xpp) + X_SIZEOF_SIZE_T);
+ return NC_NOERR;
+}
+
+int
+ncmpix_get_size_t(const void **xpp, size_t *ulp)
+{
+ /* similar to get_ix_int */
+ const uchar *cp = (const uchar *) *xpp;
+
+ *ulp = (size_t)(*cp++ << 24);
+ *ulp |= (size_t)(*cp++ << 16);
+ *ulp |= (size_t)(*cp++ << 8);
+ *ulp |= *cp;
+
+ *xpp = (const void *)((const char *)(*xpp) + X_SIZEOF_SIZE_T);
+ return NC_NOERR;
+}
+
+/* x_off_t */
+
+int
+ncmpix_put_off_t(void **xpp, const off_t *lp, size_t sizeof_off_t)
+{
+ /* No negative offsets stored in netcdf */
+ if (*lp < 0) {
+ /* Assume this is an overflow of a 32-bit int... */
+ DEBUG_RETURN_ERROR(NC_ERANGE)
+ }
+
+ assert(sizeof_off_t == 4 || sizeof_off_t == 8);
+
+ /* similar to put_ix_int() */
+ uchar *cp = (uchar *) *xpp;
+
+ if (sizeof_off_t == 4) {
+ *cp++ = (uchar) ((*lp) >> 24);
+ *cp++ = (uchar)(((*lp) & 0x00ff0000) >> 16);
+ *cp++ = (uchar)(((*lp) & 0x0000ff00) >> 8);
+ *cp = (uchar)( (*lp) & 0x000000ff);
+ } else {
+#if SIZEOF_OFF_T == 4
+/* Write a 64-bit offset on a system with only a 32-bit offset */
+ *cp++ = (uchar)0;
+ *cp++ = (uchar)0;
+ *cp++ = (uchar)0;
+ *cp++ = (uchar)0;
+
+ *cp++ = (uchar)(((*lp) & 0xff000000) >> 24);
+ *cp++ = (uchar)(((*lp) & 0x00ff0000) >> 16);
+ *cp++ = (uchar)(((*lp) & 0x0000ff00) >> 8);
+ *cp = (uchar)( (*lp) & 0x000000ff);
+#else
+ *cp++ = (uchar) ((*lp) >> 56);
+ *cp++ = (uchar)(((*lp) & 0x00ff000000000000LL) >> 48);
+ *cp++ = (uchar)(((*lp) & 0x0000ff0000000000LL) >> 40);
+ *cp++ = (uchar)(((*lp) & 0x000000ff00000000LL) >> 32);
+ *cp++ = (uchar)(((*lp) & 0x00000000ff000000LL) >> 24);
+ *cp++ = (uchar)(((*lp) & 0x0000000000ff0000LL) >> 16);
+ *cp++ = (uchar)(((*lp) & 0x000000000000ff00LL) >> 8);
+ *cp = (uchar)( (*lp) & 0x00000000000000ffLL);
+#endif
+ }
+ *xpp = (void *)((char *)(*xpp) + sizeof_off_t);
+ return NC_NOERR;
+}
+
+int
+ncmpix_get_off_t(const void **xpp, off_t *lp, size_t sizeof_off_t)
+{
+ /* similar to get_ix_int() */
+ const uchar *cp = (const uchar *) *xpp;
+ assert(sizeof_off_t == 4 || sizeof_off_t == 8);
+
+ if (sizeof_off_t == 4) {
+ *lp = (off_t)(*cp++ << 24);
+ *lp |= (off_t)(*cp++ << 16);
+ *lp |= (off_t)(*cp++ << 8);
+ *lp |= (off_t)*cp;
+ } else {
+#if SIZEOF_OFF_T == 4
+/* Read a 64-bit offset on a system with only a 32-bit offset */
+/* If the offset overflows, set an error code and return */
+ *lp = ((off_t)(*cp++) << 24);
+ *lp |= ((off_t)(*cp++) << 16);
+ *lp |= ((off_t)(*cp++) << 8);
+ *lp |= ((off_t)(*cp++));
+/*
+ * lp now contains the upper 32-bits of the 64-bit offset. if lp is
+ * not zero, then the dataset is larger than can be represented
+ * on this system. Set an error code and return.
+ */
+ if (*lp != 0) {
+ DEBUG_RETURN_ERROR(NC_ERANGE)
+ }
+
+ *lp = ((off_t)(*cp++) << 24);
+ *lp |= ((off_t)(*cp++) << 16);
+ *lp |= ((off_t)(*cp++) << 8);
+ *lp |= (off_t)*cp;
+
+ if (*lp < 0) {
+ /*
+ * If this fails, then the offset is >2^31, but less
+ * than 2^32 which is not allowed, but is not caught
+ * by the previous check
+ */
+ DEBUG_RETURN_ERROR(NC_ERANGE)
+ }
+#else
+ *lp = ((off_t)(*cp++) << 56);
+ *lp |= ((off_t)(*cp++) << 48);
+ *lp |= ((off_t)(*cp++) << 40);
+ *lp |= ((off_t)(*cp++) << 32);
+ *lp |= ((off_t)(*cp++) << 24);
+ *lp |= ((off_t)(*cp++) << 16);
+ *lp |= ((off_t)(*cp++) << 8);
+ *lp |= (off_t)*cp;
+#endif
+ }
+ *xpp = (const void *)((const char *)(*xpp) + sizeof_off_t);
+ return NC_NOERR;
+}
+
+/*----< ncmpix_get_uint32() >-------------------------------------------------*/
+int
+ncmpix_get_uint32(const void **xpp, uint *ip)
+{
+#ifdef WORDS_BIGENDIAN
+ /* use memcpy instead of assignment to avoid BUS_ADRALN alignment error on
+ * some system, such as HPUX */
+ (void) memcpy(ip, *xpp, X_SIZEOF_INT);
+#else
+ const uchar *cp = (const uchar *) *xpp;
+
+ *ip = (*cp++ << 24);
+ *ip |= (*cp++ << 16);
+ *ip |= (*cp++ << 8);
+ *ip |= *cp;
+#endif
+ /* advance *xpp 4 bytes */
+ *xpp = (void *)((const char *)(*xpp) + 4);
+
+ return NC_NOERR;
+}
+
+/*----< ncmpix_get_uint64() >-------------------------------------------------*/
+int
+ncmpix_get_uint64(const void **xpp, unsigned long long *llp)
+{
+#ifdef WORDS_BIGENDIAN
+ /* use memcpy instead of assignment to avoid BUS_ADRALN alignment error on
+ * some system, such as HPUX */
+ (void) memcpy(llp, *xpp, X_SIZEOF_INT64);
+#else
+ const uchar *cp = (const uchar *) *xpp;
+
+ /* below is the same as calling swap8b(llp, *xpp) */
+ *llp = ((long long)(*cp++) << 56);
+ *llp |= ((long long)(*cp++) << 48);
+ *llp |= ((long long)(*cp++) << 40);
+ *llp |= ((long long)(*cp++) << 32);
+ *llp |= ((long long)(*cp++) << 24);
+ *llp |= ((long long)(*cp++) << 16);
+ *llp |= ((long long)(*cp++) << 8);
+ *llp |= (long long)*cp;
+#endif
+ /* advance *xpp 8 bytes */
+ *xpp = (void *)((const char *)(*xpp) + 8);
+
+ return NC_NOERR;
+}
+
+/*---< ncmpix_put_uint32() >--------------------------------------------------*/
+/* copy the contents of ip (an unsigned 32-bit integer) to xpp in Big Endian
+ * form and advance *xpp 4 bytes
+ */
+int
+ncmpix_put_uint32(void **xpp, const unsigned int ip)
+{
+#ifdef WORDS_BIGENDIAN
+ /* use memcpy instead of assignment to avoid BUS_ADRALN alignment error on
+ * some system, such as HPUX */
+ (void) memcpy(*xpp, &ip, X_SIZEOF_INT);
+#else
+ /* bitwise shifts below are to produce an integer in Big Endian */
+ uchar *cp = (uchar *) *xpp;
+ *cp++ = (uchar)((ip & 0xff000000) >> 24);
+ *cp++ = (uchar)((ip & 0x00ff0000) >> 16);
+ *cp++ = (uchar)((ip & 0x0000ff00) >> 8);
+ *cp = (uchar)( ip & 0x000000ff);
+#endif
+ /* advance *xpp 4 bytes */
+ *xpp = (void *)((char *)(*xpp) + 4);
+
+ return NC_NOERR;
+}
+
+/*---< ncmpix_put_uint64() >--------------------------------------------------*/
+/* copy the contents of ip (an unsigned 64-bit integer) to xpp in Big Endian
+ * form and advance *xpp 8 bytes
+ */
+int
+ncmpix_put_uint64(void **xpp, const unsigned long long ip)
+{
+#ifdef WORDS_BIGENDIAN
+ /* use memcpy instead of assignment to avoid BUS_ADRALN alignment error on
+ * some system, such as HPUX */
+ (void) memcpy(*xpp, &ip, X_SIZEOF_INT64);
+#else
+ uchar *cp = (uchar *) *xpp;
+ /* below is the same as calling swap8b(*xpp, &ip) */
+ *cp++ = (uchar) (ip >> 56);
+ *cp++ = (uchar)((ip & 0x00ff000000000000LL) >> 48);
+ *cp++ = (uchar)((ip & 0x0000ff0000000000LL) >> 40);
+ *cp++ = (uchar)((ip & 0x000000ff00000000LL) >> 32);
+ *cp++ = (uchar)((ip & 0x00000000ff000000LL) >> 24);
+ *cp++ = (uchar)((ip & 0x0000000000ff0000LL) >> 16);
+ *cp++ = (uchar)((ip & 0x000000000000ff00LL) >> 8);
+ *cp = (uchar) (ip & 0x00000000000000ffLL);
+#endif
+ /* advance *xpp 8 bytes */
+ *xpp = (void *)((char *)(*xpp) + 8);
+
+ return NC_NOERR;
+}
+
+
+/*
+ * Aggregate numeric conversion functions.
+ */
+dnl
+define(`GETN_CheckBND', `ifelse(index(`$1',`u'), 0, , index(`$2',`u'), 0, `|| xp[i] < 0', `|| xp[i] < Imin($2)')')dnl
+define(`PUTN_CheckBND', `ifelse(index(`$2',`u'), 0, , index(`$1',`u'), 0, `|| tp[i] < 0', `|| tp[i] < Xmin($1)')')dnl
+
+dnl
+dnl dnl dnl
+dnl
+dnl NCX_GETN_Byte_Body (body for one byte types on diagonal)
+dnl
+define(`NCX_GETN_Byte_Body',dnl
+`dnl
+ (void) memcpy(tp, *xpp, (size_t)nelems);
+ *xpp = (void *)((char *)(*xpp) + nelems);
+ return NC_NOERR;
+')dnl
+dnl dnl dnl
+dnl
+dnl NCX_PAD_GETN_Byte_body (body for one byte types on diagonal)
+dnl
+define(`NCX_PAD_GETN_Byte_Body',dnl
+`dnl
+ MPI_Offset rndup = nelems % X_ALIGN;
+
+ if (rndup)
+ rndup = X_ALIGN - rndup;
+
+ (void) memcpy(tp, *xpp, (size_t)nelems);
+ *xpp = (void *)((char *)(*xpp) + nelems + rndup);
+
+ return NC_NOERR;
+')dnl
+dnl dnl dnl
+dnl
+dnl NCX_GETN_CHAR(Type)
+dnl
+define(`NCX_GETN_CHAR',dnl
+`dnl
+int
+ncmpix_getn_$1_$2(const void **xpp, MPI_Offset nelems, $2 *tp)
+{
+ int status = NC_NOERR;
+ $1 *xp = ($1 *)(*xpp);
+
+ while (nelems-- != 0)
+ {
+ GETI_CheckNegAssign($1, $2, *xp, tp)
+ *tp++ = ($2) Cast_Signed2Unsigned($2,$1) (*xp++); /* type cast from $1 to $2 */
+ /* TODO: skip the assignment if NC_ERANGE occurs?
+ * However, if doing so, many nc_test/nf_test will fail
+ */
+ }
+
+ *xpp = (const void *)xp;
+ return status;
+}
+')dnl
+dnl dnl dnl
+dnl
+dnl NCX_PAD_GETN_CHAR(Type)
+dnl
+define(`NCX_PAD_GETN_CHAR',dnl
+`dnl
+int
+ncmpix_pad_getn_$1_$2(const void **xpp, MPI_Offset nelems, $2 *tp)
+{
+ int status = NC_NOERR;
+ MPI_Offset rndup = nelems % X_ALIGN;
+ $1 *xp = ($1 *) *xpp;
+
+ if (rndup)
+ rndup = X_ALIGN - rndup;
+
+ while (nelems-- != 0)
+ {
+ GETI_CheckNegAssign($1, $2, *xp, tp)
+ *tp++ = ($2) Cast_Signed2Unsigned($2,$1) (*xp++); /* type cast from $1 to $2 */
+ /* TODO: skip the assignment if NC_ERANGE occurs?
+ * However, if doing so, many nc_test/nf_test will fail
+ */
+ }
+
+ *xpp = (void *)(xp + rndup);
+ return status;
+}
+')dnl
+dnl dnl dnl
+dnl
+dnl NCX_GETNo(XType, Type) deprecated
+dnl
+define(`NCX_GETNo',dnl
+`dnl
+int
+ncmpix_getn_$1_$2(const void **xpp, MPI_Offset nelems, $2 *tp)
+{
+ const char *xp = (const char *) *xpp;
+ int status = NC_NOERR;
+ $1 xx;
+
+ for( ; nelems != 0; nelems--, xp += Xsizeof($1), tp++)
+ {
+ const int lstatus = ncmpix_get_$1_$1(xp, &xx);
+ *tp = ($2)xx;
+ if (status == NC_NOERR) /* report the first encountered error */
+ status = lstatus;
+ }
+
+ *xpp = (const void *)xp;
+ return status;
+}
+')dnl
+dnl dnl dnl
+dnl
+dnl NCX_GETN(XType, Type, condition)
+dnl
+define(`NCX_GETN',dnl
+`dnl
+int
+ncmpix_getn_$1_$2(const void **xpp, MPI_Offset nelems, $2 *tp)
+{
+`#'if defined(_SX) && _SX != 0 && Xsizeof($1) == Isizeof($1)
+
+ /* basic algorithm is:
+ * - ensure sane alignment of input data
+ * - copy (conversion happens automatically) input data
+ * to output
+ * - update xpp to point at next unconverted input, and tp to point
+ * at next location for converted output
+ */
+ long i, j, ni;
+ $1 tmp[LOOPCNT]; /* in case input is misaligned */
+ $1 *xp;
+ int nrange = 0; /* number of range errors */
+ int realign = 0; /* "do we need to fix input data alignment?" */
+ long cxp = (long) *((char**)xpp);
+
+ realign = (cxp & 7) % Isizeof($1);
+ /* sjl: manually stripmine so we can limit amount of
+ * vector work space reserved to LOOPCNT elements. Also
+ * makes vectorisation easy */
+ for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
+ ni=Min(nelems-j,LOOPCNT);
+ if (realign) {
+ memcpy(tmp, *xpp, (size_t)(ni*Isizeof($1)));
+ xp = tmp;
+ } else {
+ xp = ($1 *) *xpp;
+ }
+ /* copy the next block */
+#pragma cdir loopcnt=LOOPCNT
+#pragma cdir shortloop
+ for (i=0; i<ni; i++) {
+ tp[i] = ($2) Max( Imin($2), Min(Imax($2), ($2) xp[i]));
+ /* test for range errors (not always needed but do it anyway) */
+ /* if xpp is unsigned, we need not check if xp[i] < Imin */
+ /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
+ nrange += xp[i] > Imax($2) GETN_CheckBND($1, $2);
+ }
+ /* update xpp and tp */
+ if (realign) xp = ($1 *) *xpp;
+ xp += ni;
+ tp += ni;
+ *xpp = (void*)xp;
+ }
+ return nrange == 0 ? NC_NOERR : NC_ERANGE;
+
+#else /* not SX */
+ const char *xp = (const char *) *xpp;
+ int status = NC_NOERR;
+
+ for( ; nelems != 0; nelems--, xp += Xsizeof($1), tp++)
+ {
+ const int lstatus = ncmpix_get_$1_$2(xp, tp);
+ if (status == NC_NOERR) /* report the first encountered error */
+ status = lstatus;
+ }
+
+ *xpp = (const void *)xp;
+ return status;
+#endif
+}
+')dnl
+dnl dnl dnl
+dnl
+dnl NCX_PAD_GETN_SHORT(xtype ttype)
+dnl
+define(`NCX_PAD_GETN_SHORT',dnl
+`dnl
+int
+ncmpix_pad_getn_$1_$2(const void **xpp, MPI_Offset nelems, $2 *tp)
+{
+ const MPI_Offset rndup = nelems % 2;
+
+ const char *xp = (const char *) *xpp;
+ int status = NC_NOERR;
+
+ for( ; nelems != 0; nelems--, xp += Xsizeof($1), tp++)
+ {
+ const int lstatus = ncmpix_get_$1_$2(xp, tp);
+ if (status == NC_NOERR) /* report the first encountered error */
+ status = lstatus;
+ }
+
+ if (rndup != 0)
+ xp += Xsizeof($1);
+
+ *xpp = (void *)xp;
+ return status;
+}
+')dnl
+dnl dnl dnl
+dnl
+dnl NCX_PUTN_Byte_Body(Type) (body for one byte types)
+dnl
+define(`NCX_PUTN_Byte_Body',dnl
+`dnl
+ (void) memcpy(*xpp, tp, (size_t)nelems);
+ *xpp = (void *)((char *)(*xpp) + nelems);
+
+ return NC_NOERR;
+')dnl
+dnl dnl dnl
+dnl
+dnl NCX_PAD_PUTN_Byte_Body(Type) (body for one byte types)
+dnl
+define(`NCX_PAD_PUTN_Byte_Body',dnl
+ MPI_Offset rndup = nelems % X_ALIGN;
+
+ if (rndup)
+ rndup = X_ALIGN - rndup;
+
+ (void) memcpy(*xpp, tp, (size_t)nelems);
+ *xpp = (void *)((char *)(*xpp) + nelems);
+
+ if (rndup)
+ {
+ (void) memcpy(*xpp, nada, (size_t)rndup);
+ *xpp = (void *)((char *)(*xpp) + rndup);
+ }
+
+ return NC_NOERR;
+`dnl
+')dnl
+dnl dnl dnl
+dnl
+dnl NCX_PUTN_CHAR(Type)
+dnl
+define(`NCX_PUTN_CHAR',dnl
+`dnl
+int
+ncmpix_putn_$1_$2(void **xpp, MPI_Offset nelems, const $2 *tp)
+{
+ int status = NC_NOERR;
+ $1 *xp = ($1 *) *xpp;
+
+ while (nelems-- != 0)
+ {
+ if (*tp > ($2)Xmax($1) ifelse(index(`$2',`u'), 0, , index(`$1',`u'), 0, `|| *tp < 0',`|| *tp < Xmin(schar)'))
+ DEBUG_ASSIGN_ERROR(status, NC_ERANGE)
+ *xp++ = ($1) Cast_Signed2Unsigned($1,$2) *tp++; /* type cast from $2 to $1 */
+ /* TODO: skip the assignment if NC_ERANGE occurs?
+ * However, if doing so, many nc_test/nf_test will fail
+ */
+ }
+
+ *xpp = (void *)xp;
+ return status;
+}
+')dnl
+dnl dnl dnl
+dnl
+dnl NCX_PAD_PUTN_CHAR(xtype, ttype)
+dnl
+define(`NCX_PAD_PUTN_CHAR',dnl
+`dnl
+int
+ncmpix_pad_putn_$1_$2(void **xpp, MPI_Offset nelems, const $2 *tp)
+{
+ int status = NC_NOERR;
+ MPI_Offset rndup = nelems % X_ALIGN;
+ $1 *xp = ($1 *) *xpp;
+
+ if (rndup)
+ rndup = X_ALIGN - rndup;
+
+ while (nelems-- != 0)
+ {
+ if (*tp > ($2)Xmax($1) ifelse(index(`$2',`u'), 0, , index(`$1',`u'), 0, `|| *tp < 0',`|| *tp < Xmin(schar)'))
+ DEBUG_ASSIGN_ERROR(status, NC_ERANGE)
+ *xp++ = ($1) Cast_Signed2Unsigned($1,$2) *tp++; /* type cast from $2 to $1 */
+ /* TODO: skip the assignment if NC_ERANGE occurs?
+ * However, if doing so, many nc_test/nf_test will fail
+ */
+ }
+
+
+ if (rndup)
+ {
+ (void) memcpy(xp, nada, (size_t)rndup);
+ xp += rndup;
+ }
+
+ *xpp = (void *)xp;
+ return status;
+}
+')dnl
+dnl dnl dnl
+dnl
+dnl NCX_PUTNo(XType, Type) deprecated
+dnl
+define(`NCX_PUTNo',dnl
+`dnl
+int
+ncmpix_putn_$1_$2(void **xpp, MPI_Offset nelems, const $2 *tp)
+{
+ char *xp = (char *) *xpp;
+ int status = NC_NOERR;
+ $1 xx;
+
+ for( ; nelems != 0; nelems--, xp += Xsizeof($1), tp++)
+ {
+ xx = ($1) *tp;
+ {
+ int lstatus = ncmpix_put_$1_$1(xp, &xx);
+ if (status == NC_NOERR) /* report the first encountered error */
+ status = lstatus;
+ }
+ }
+
+ *xpp = (void *)xp;
+ return status;
+}
+')dnl
+dnl dnl dnl
+dnl
+dnl NCX_PUTN(XType, Type, condition)
+dnl
+define(`NCX_PUTN',dnl
+`dnl
+int
+ncmpix_putn_$1_$2(void **xpp, MPI_Offset nelems, const $2 *tp)
+{
+`#'if defined(_SX) && _SX != 0 && Xsizeof($1) == Isizeof($1)
+
+ /* basic algorithm is:
+ * - ensure sane alignment of output data
+ * - copy (conversion happens automatically) input data
+ * to output
+ * - update tp to point at next unconverted input, and xpp to point
+ * at next location for converted output
+ */
+ long i, j, ni;
+ $1 tmp[LOOPCNT]; /* in case input is misaligned */
+ $1 *xp;
+ifelse( $1$2, intfloat,dnl
+`dnl
+ double d; /* special case for ncmpix_putn_int_float */
+')dnl
+ int nrange = 0; /* number of range errors */
+ int realign = 0; /* "do we need to fix input data alignment?" */
+ long cxp = (long) *((char**)xpp);
+
+ realign = (cxp & 7) % Isizeof($1);
+ /* sjl: manually stripmine so we can limit amount of
+ * vector work space reserved to LOOPCNT elements. Also
+ * makes vectorisation easy */
+ for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
+ ni=Min(nelems-j,LOOPCNT);
+ if (realign) {
+ xp = tmp;
+ } else {
+ xp = ($1 *) *xpp;
+ }
+ /* copy the next block */
+#pragma cdir loopcnt=LOOPCNT
+#pragma cdir shortloop
+ for (i=0; i<ni; i++) {
+ifelse( $1$2, intfloat,dnl
+`dnl
+ /* for some reason int to float, for putn, requires a special case */
+ d = tp[i];
+ xp[i] = ($1) Max( Xmin($1), Min(Xmax($1), ($1) d));
+ nrange += tp[i] > Xmax($1) PUTN_CheckBND($1, $2);
+',dnl
+`dnl
+ /* the normal case: */
+ xp[i] = ($1) Max( Xmin($1), Min(Xmax($1), ($1) tp[i]));
+ /* test for range errors (not always needed but do it anyway) */
+ /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
+ /* if tp is unsigned, we need not check if tp[i] < Xmin */
+ nrange += tp[i] > Xmax($1) PUTN_CheckBND($1, $2);
+')dnl
+ }
+ /* copy workspace back if necessary */
+ if (realign) {
+ memcpy(*xpp, tmp, (size_t)*ni*Xsizeof($1)));
+ xp = ($1 *) *xpp;
+ }
+ /* update xpp and tp */
+ xp += ni;
+ tp += ni;
+ *xpp = (void*)xp;
+ }
+ return nrange == 0 ? NC_NOERR : NC_ERANGE;
+
+#else /* not SX */
+
+ char *xp = (char *) *xpp;
+ int status = NC_NOERR;
+
+ for( ; nelems != 0; nelems--, xp += Xsizeof($1), tp++)
+ {
+ int lstatus = ncmpix_put_$1_$2(xp, tp);
+ if (status == NC_NOERR) /* report the first encountered error */
+ status = lstatus;
+ }
+
+ *xpp = (void *)xp;
+ return status;
+#endif
+}
+')dnl
+dnl dnl dnl
+dnl
+dnl NCX_PAD_PUTN_SHORT(xtype, ttype)
+dnl
+define(`NCX_PAD_PUTN_SHORT',dnl
+`dnl
+int
+ncmpix_pad_putn_$1_$2(void **xpp, MPI_Offset nelems, const $2 *tp)
+{
+ const MPI_Offset rndup = nelems % 2;
+
+ char *xp = (char *) *xpp;
+ int status = NC_NOERR;
+
+ for( ; nelems != 0; nelems--, xp += Xsizeof($1), tp++)
+ {
+ int lstatus = ncmpix_put_$1_$2(xp, tp);
+ if (status == NC_NOERR) /* report the first encountered error */
+ status = lstatus;
+ }
+
+ if (rndup != 0)
+ {
+ (void) memcpy(xp, nada, (size_t)(Xsizeof($1)));
+ xp += Xsizeof($1);
+ }
+
+ *xpp = (void *)xp;
+ return status;
+}
+')dnl
+
+dnl dnl dnl
+dnl
+dnl Declare & define routines
+dnl
+dnl dnl dnl
+
+/* schar ---------------------------------------------------------------------*/
+
+dnl NCX_GETN_CHAR(schar, schar)
+int
+ncmpix_getn_schar_schar(const void **xpp, MPI_Offset nelems, schar *tp)
+{
+ NCX_GETN_Byte_Body
+}
+dnl NCX_GETN_CHAR(schar, uchar)
+int
+ncmpix_getn_schar_uchar(const void **xpp, MPI_Offset nelems, uchar *tp)
+{
+ NCX_GETN_Byte_Body
+}
+NCX_GETN_CHAR(schar, short)
+NCX_GETN_CHAR(schar, int)
+NCX_GETN_CHAR(schar, long)
+NCX_GETN_CHAR(schar, float)
+NCX_GETN_CHAR(schar, double)
+NCX_GETN_CHAR(schar, longlong)
+NCX_GETN_CHAR(schar, ushort)
+NCX_GETN_CHAR(schar, uint)
+NCX_GETN_CHAR(schar, ulonglong)
+
+dnl NCX_PAD_GETN_CHAR(schar, schar)
+int
+ncmpix_pad_getn_schar_schar(const void **xpp, MPI_Offset nelems, schar *tp)
+{
+ NCX_PAD_GETN_Byte_Body
+}
+dnl NCX_PAD_GETN_CHAR(schar, uchar)
+int
+ncmpix_pad_getn_schar_uchar(const void **xpp, MPI_Offset nelems, uchar *tp)
+{
+ NCX_PAD_GETN_Byte_Body
+}
+NCX_PAD_GETN_CHAR(schar, short)
+NCX_PAD_GETN_CHAR(schar, int)
+NCX_PAD_GETN_CHAR(schar, long)
+NCX_PAD_GETN_CHAR(schar, float)
+NCX_PAD_GETN_CHAR(schar, double)
+NCX_PAD_GETN_CHAR(schar, longlong)
+NCX_PAD_GETN_CHAR(schar, ushort)
+NCX_PAD_GETN_CHAR(schar, uint)
+NCX_PAD_GETN_CHAR(schar, ulonglong)
+
+dnl NCX_PUTN_CHAR(schar, schar)
+int
+ncmpix_putn_schar_schar(void **xpp, MPI_Offset nelems, const schar *tp)
+{
+ NCX_PUTN_Byte_Body
+}
+dnl NCX_PUTN_CHAR(schar, uchar)
+int
+ncmpix_putn_schar_uchar(void **xpp, MPI_Offset nelems, const uchar *tp)
+{
+ NCX_PUTN_Byte_Body
+}
+NCX_PUTN_CHAR(schar, short)
+NCX_PUTN_CHAR(schar, int)
+NCX_PUTN_CHAR(schar, long)
+NCX_PUTN_CHAR(schar, float)
+NCX_PUTN_CHAR(schar, double)
+NCX_PUTN_CHAR(schar, longlong)
+NCX_PUTN_CHAR(schar, ushort)
+NCX_PUTN_CHAR(schar, uint)
+NCX_PUTN_CHAR(schar, ulonglong)
+
+dnl NCX_PAD_PUTN_CHAR(schar, schar)
+int
+ncmpix_pad_putn_schar_schar(void **xpp, MPI_Offset nelems, const schar *tp)
+{
+ NCX_PAD_PUTN_Byte_Body
+}
+dnl NCX_PAD_PUTN_CHAR(schar, uchar)
+int
+ncmpix_pad_putn_schar_uchar(void **xpp, MPI_Offset nelems, const uchar *tp)
+{
+ NCX_PAD_PUTN_Byte_Body
+}
+NCX_PAD_PUTN_CHAR(schar, short)
+NCX_PAD_PUTN_CHAR(schar, int)
+NCX_PAD_PUTN_CHAR(schar, long)
+NCX_PAD_PUTN_CHAR(schar, float)
+NCX_PAD_PUTN_CHAR(schar, double)
+NCX_PAD_PUTN_CHAR(schar, longlong)
+NCX_PAD_PUTN_CHAR(schar, ushort)
+NCX_PAD_PUTN_CHAR(schar, uint)
+NCX_PAD_PUTN_CHAR(schar, ulonglong)
+
+
+/* uchar ---------------------------------------------------------------------*/
+dnl
+dnl NCX_GETN_CHAR(uchar, schar)
+int
+ncmpix_getn_uchar_schar(const void **xpp, MPI_Offset nelems, schar *tp)
+{
+ int status = NC_NOERR;
+ uchar *xp = (uchar *)(*xpp);
+
+ while (nelems-- != 0)
+ {
+ if (*xp > SCHAR_MAX)
+ DEBUG_ASSIGN_ERROR(status, NC_ERANGE)
+ *tp++ = (schar) *xp++; /* type cast from uchar to schar */
+ /* TODO: skip the assignment if NC_ERANGE occurs?
+ * However, if doing so, many nc_test/nf_test will fail
+ */
+ }
+
+ *xpp = (const void *)xp;
+ return status;
+}
+dnl NCX_GETN_CHAR(uchar, uchar)
+int
+ncmpix_getn_uchar_uchar(const void **xpp, MPI_Offset nelems, uchar *tp)
+{
+ NCX_GETN_Byte_Body
+}
+NCX_GETN_CHAR(uchar, short)
+NCX_GETN_CHAR(uchar, int)
+NCX_GETN_CHAR(uchar, long)
+NCX_GETN_CHAR(uchar, float)
+NCX_GETN_CHAR(uchar, double)
+NCX_GETN_CHAR(uchar, longlong)
+NCX_GETN_CHAR(uchar, ushort)
+NCX_GETN_CHAR(uchar, uint)
+NCX_GETN_CHAR(uchar, ulonglong)
+
+dnl NCX_PAD_GETN_CHAR(uchar, schar)
+int
+ncmpix_pad_getn_uchar_schar(const void **xpp, MPI_Offset nelems, schar *tp)
+{
+ int status = NC_NOERR;
+ MPI_Offset rndup = nelems % X_ALIGN;
+ uchar *xp = (uchar *) *xpp;
+
+ if (rndup)
+ rndup = X_ALIGN - rndup;
+
+ while (nelems-- != 0)
+ {
+ if (*xp > SCHAR_MAX)
+ DEBUG_ASSIGN_ERROR(status, NC_ERANGE)
+ *tp++ = (schar) *xp++; /* type cast from uchar to schar */
+ /* TODO: skip the assignment if NC_ERANGE occurs?
+ * However, if doing so, many nc_test/nf_test will fail
+ */
+ }
+
+ *xpp = (void *)(xp + rndup);
+ return status;
+}
+dnl NCX_PAD_GETN_CHAR(uchar, uchar)
+int
+ncmpix_pad_getn_uchar_uchar(const void **xpp, MPI_Offset nelems, uchar *tp)
+{
+ NCX_PAD_GETN_Byte_Body
+}
+NCX_PAD_GETN_CHAR(uchar, short)
+NCX_PAD_GETN_CHAR(uchar, int)
+NCX_PAD_GETN_CHAR(uchar, long)
+NCX_PAD_GETN_CHAR(uchar, float)
+NCX_PAD_GETN_CHAR(uchar, double)
+NCX_PAD_GETN_CHAR(uchar, longlong)
+NCX_PAD_GETN_CHAR(uchar, ushort)
+NCX_PAD_GETN_CHAR(uchar, uint)
+NCX_PAD_GETN_CHAR(uchar, ulonglong)
+
+dnl NCX_PUTN_CHAR(uchar, schar)
+int
+ncmpix_putn_uchar_schar(void **xpp, MPI_Offset nelems, const schar *tp)
+{
+ int status = NC_NOERR;
+ uchar *xp = (uchar *) *xpp;
+
+ while (nelems-- != 0)
+ {
+ if (*tp < 0)
+ DEBUG_ASSIGN_ERROR(status, NC_ERANGE)
+ *xp++ = (uchar) (signed) *tp++; /* type cast from schar to uchar */
+ /* TODO: skip the assignment if NC_ERANGE occurs?
+ * However, if doing so, many nc_test/nf_test will fail
+ */
+ }
+
+ *xpp = (void *)xp;
+ return status;
+}
+dnl NCX_PUTN_CHAR(uchar, uchar)
+int
+ncmpix_putn_uchar_uchar(void **xpp, MPI_Offset nelems, const uchar *tp)
+{
+ NCX_PUTN_Byte_Body
+}
+NCX_PUTN_CHAR(uchar, short)
+NCX_PUTN_CHAR(uchar, int)
+NCX_PUTN_CHAR(uchar, long)
+NCX_PUTN_CHAR(uchar, float)
+NCX_PUTN_CHAR(uchar, double)
+NCX_PUTN_CHAR(uchar, longlong)
+NCX_PUTN_CHAR(uchar, ushort)
+NCX_PUTN_CHAR(uchar, uint)
+NCX_PUTN_CHAR(uchar, ulonglong)
+
+dnl NCX_PAD_PUTN_UCHAR(uchar, schar)
+int
+ncmpix_pad_putn_uchar_schar(void **xpp, MPI_Offset nelems, const schar *tp)
+{
+ int status = NC_NOERR;
+ MPI_Offset rndup = nelems % X_ALIGN;
+ uchar *xp = (uchar *) *xpp;
+
+ if (rndup)
+ rndup = X_ALIGN - rndup;
+
+ while (nelems-- != 0)
+ {
+ if (*tp < 0)
+ DEBUG_ASSIGN_ERROR(status, NC_ERANGE)
+ *xp++ = (uchar) (signed) *tp++; /* type cast from schar to uchar */
+ /* TODO: skip the assignment if NC_ERANGE occurs?
+ * However, if doing so, many nc_test/nf_test will fail
+ */
+ }
+
+
+ if (rndup)
+ {
+ (void) memcpy(xp, nada, (size_t)rndup);
+ xp += rndup;
+ }
+
+ *xpp = (void *)xp;
+ return status;
+}
+dnl NCX_PAD_PUTN_UCHAR(uchar, uchar)
+int
+ncmpix_pad_putn_uchar_uchar(void **xpp, MPI_Offset nelems, const uchar *tp)
+{
+ NCX_PAD_PUTN_Byte_Body
+}
+NCX_PAD_PUTN_CHAR(uchar, short)
+NCX_PAD_PUTN_CHAR(uchar, int)
+NCX_PAD_PUTN_CHAR(uchar, long)
+NCX_PAD_PUTN_CHAR(uchar, float)
+NCX_PAD_PUTN_CHAR(uchar, double)
+NCX_PAD_PUTN_CHAR(uchar, longlong)
+NCX_PAD_PUTN_CHAR(uchar, ushort)
+NCX_PAD_PUTN_CHAR(uchar, uint)
+NCX_PAD_PUTN_CHAR(uchar, ulonglong)
+
+/* short ---------------------------------------------------------------------*/
+
+#if X_SIZEOF_SHORT == SIZEOF_SHORT
+/* optimized version */
+int
+ncmpix_getn_short_short(const void **xpp, MPI_Offset nelems, short *tp)
+{
+#ifdef WORDS_BIGENDIAN
+ (void) memcpy(tp, *xpp, (size_t)nelems * SIZEOF_SHORT);
+# else
+ swapn2b(tp, *xpp, nelems);
+# endif
+ *xpp = (const void *)((const char *)(*xpp) + nelems * X_SIZEOF_SHORT);
+ return NC_NOERR;
+}
+#else
+NCX_GETN(short, short)
+#endif
+NCX_GETN(short, schar)
+NCX_GETN(short, int)
+NCX_GETN(short, long)
+NCX_GETN(short, float)
+NCX_GETN(short, double)
+NCX_GETN(short, longlong)
+NCX_GETN(short, uchar)
+NCX_GETN(short, ushort)
+NCX_GETN(short, uint)
+NCX_GETN(short, ulonglong)
+
+NCX_PAD_GETN_SHORT(short, schar)
+NCX_PAD_GETN_SHORT(short, uchar)
+NCX_PAD_GETN_SHORT(short, short)
+NCX_PAD_GETN_SHORT(short, int)
+NCX_PAD_GETN_SHORT(short, long)
+NCX_PAD_GETN_SHORT(short, float)
+NCX_PAD_GETN_SHORT(short, double)
+NCX_PAD_GETN_SHORT(short, uint)
+NCX_PAD_GETN_SHORT(short, longlong)
+NCX_PAD_GETN_SHORT(short, ulonglong)
+NCX_PAD_GETN_SHORT(short, ushort)
+
+#if X_SIZEOF_SHORT == SIZEOF_SHORT
+/* optimized version */
+int
+ncmpix_putn_short_short(void **xpp, MPI_Offset nelems, const short *tp)
+{
+#ifdef WORDS_BIGENDIAN
+ (void) memcpy(*xpp, tp, (size_t)nelems * X_SIZEOF_SHORT);
+# else
+ swapn2b(*xpp, tp, nelems);
+# endif
+ *xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_SHORT);
+ return NC_NOERR;
+}
+#else
+NCX_PUTN(short, short)
+#endif
+NCX_PUTN(short, schar)
+NCX_PUTN(short, int)
+NCX_PUTN(short, long)
+NCX_PUTN(short, float)
+NCX_PUTN(short, double)
+NCX_PUTN(short, longlong)
+NCX_PUTN(short, uchar)
+NCX_PUTN(short, uint)
+NCX_PUTN(short, ulonglong)
+NCX_PUTN(short, ushort)
+
+NCX_PAD_PUTN_SHORT(short, schar)
+NCX_PAD_PUTN_SHORT(short, uchar)
+NCX_PAD_PUTN_SHORT(short, short)
+NCX_PAD_PUTN_SHORT(short, int)
+NCX_PAD_PUTN_SHORT(short, long)
+NCX_PAD_PUTN_SHORT(short, float)
+NCX_PAD_PUTN_SHORT(short, double)
+NCX_PAD_PUTN_SHORT(short, uint)
+NCX_PAD_PUTN_SHORT(short, longlong)
+NCX_PAD_PUTN_SHORT(short, ulonglong)
+NCX_PAD_PUTN_SHORT(short, ushort)
+
+
+/* ushort --------------------------------------------------------------------*/
+
+#if X_SIZEOF_USHORT == SIZEOF_USHORT
+/* optimized version */
+int
+ncmpix_getn_ushort_ushort(const void **xpp, MPI_Offset nelems, unsigned short *tp)
+{
+#ifdef WORDS_BIGENDIAN
+ (void) memcpy(tp, *xpp, (size_t)nelems * SIZEOF_UNSIGNED_SHORT);
+# else
+ swapn2b(tp, *xpp, nelems);
+# endif
+ *xpp = (const void *)((const char *)(*xpp) + nelems * X_SIZEOF_USHORT);
+ return NC_NOERR;
+}
+#else
+NCX_GETN(ushort, ushort)
+#endif
+NCX_GETN(ushort, schar)
+NCX_GETN(ushort, short)
+NCX_GETN(ushort, int)
+NCX_GETN(ushort, long)
+NCX_GETN(ushort, float)
+NCX_GETN(ushort, double)
+NCX_GETN(ushort, longlong)
+NCX_GETN(ushort, uchar)
+NCX_GETN(ushort, uint)
+NCX_GETN(ushort, ulonglong)
+
+NCX_PAD_GETN_SHORT(ushort, schar)
+NCX_PAD_GETN_SHORT(ushort, short)
+NCX_PAD_GETN_SHORT(ushort, int)
+NCX_PAD_GETN_SHORT(ushort, long)
+NCX_PAD_GETN_SHORT(ushort, float)
+NCX_PAD_GETN_SHORT(ushort, double)
+NCX_PAD_GETN_SHORT(ushort, uchar)
+NCX_PAD_GETN_SHORT(ushort, ushort)
+NCX_PAD_GETN_SHORT(ushort, uint)
+NCX_PAD_GETN_SHORT(ushort, longlong)
+NCX_PAD_GETN_SHORT(ushort, ulonglong)
+
+#if X_SIZEOF_USHORT == SIZEOF_USHORT
+/* optimized version */
+int
+ncmpix_putn_ushort_ushort(void **xpp, MPI_Offset nelems, const unsigned short *tp)
+{
+#ifdef WORDS_BIGENDIAN
+ (void) memcpy(*xpp, tp, (size_t)nelems * X_SIZEOF_USHORT);
+# else
+ swapn2b(*xpp, tp, nelems);
+# endif
+ *xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_USHORT);
+ return NC_NOERR;
+}
+#else
+NCX_PUTN(ushort, ushort)
+#endif
+NCX_PUTN(ushort, schar)
+NCX_PUTN(ushort, short)
+NCX_PUTN(ushort, int)
+NCX_PUTN(ushort, long)
+NCX_PUTN(ushort, float)
+NCX_PUTN(ushort, double)
+NCX_PUTN(ushort, longlong)
+NCX_PUTN(ushort, uchar)
+NCX_PUTN(ushort, uint)
+NCX_PUTN(ushort, ulonglong)
+
+NCX_PAD_PUTN_SHORT(ushort, schar)
+NCX_PAD_PUTN_SHORT(ushort, uchar)
+NCX_PAD_PUTN_SHORT(ushort, short)
+NCX_PAD_PUTN_SHORT(ushort, int)
+NCX_PAD_PUTN_SHORT(ushort, long)
+NCX_PAD_PUTN_SHORT(ushort, float)
+NCX_PAD_PUTN_SHORT(ushort, double)
+NCX_PAD_PUTN_SHORT(ushort, uint)
+NCX_PAD_PUTN_SHORT(ushort, longlong)
+NCX_PAD_PUTN_SHORT(ushort, ulonglong)
+NCX_PAD_PUTN_SHORT(ushort, ushort)
+
+
+/* int -----------------------------------------------------------------------*/
+
+#if X_SIZEOF_INT == SIZEOF_INT
+/* optimized version */
+int
+ncmpix_getn_int_int(const void **xpp, MPI_Offset nelems, int *tp)
+{
+#ifdef WORDS_BIGENDIAN
+ (void) memcpy(tp, *xpp, (size_t)nelems * SIZEOF_INT);
+# else
+ swapn4b(tp, *xpp, nelems);
+# endif
+ *xpp = (const void *)((const char *)(*xpp) + nelems * X_SIZEOF_INT);
+ return NC_NOERR;
+}
+#else
+NCX_GETN(int, int)
+#endif
+NCX_GETN(int, schar)
+NCX_GETN(int, short)
+NCX_GETN(int, long)
+NCX_GETN(int, float)
+NCX_GETN(int, double)
+NCX_GETN(int, longlong)
+NCX_GETN(int, uchar)
+NCX_GETN(int, ushort)
+NCX_GETN(int, uint)
+NCX_GETN(int, ulonglong)
+
+#if X_SIZEOF_INT == SIZEOF_INT
+/* optimized version */
+int
+ncmpix_putn_int_int(void **xpp, MPI_Offset nelems, const int *tp)
+{
+#ifdef WORDS_BIGENDIAN
+ (void) memcpy(*xpp, tp, (size_t)nelems * X_SIZEOF_INT);
+# else
+ swapn4b(*xpp, tp, nelems);
+# endif
+ *xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_INT);
+ return NC_NOERR;
+}
+#else
+NCX_PUTN(int, int)
+#endif
+NCX_PUTN(int, schar)
+NCX_PUTN(int, short)
+NCX_PUTN(int, long)
+NCX_PUTN(int, float)
+NCX_PUTN(int, double)
+NCX_PUTN(int, longlong)
+NCX_PUTN(int, uchar)
+NCX_PUTN(int, ushort)
+NCX_PUTN(int, uint)
+NCX_PUTN(int, ulonglong)
+
+/* uint ----------------------------------------------------------------------*/
+
+#if X_SIZEOF_UINT == SIZEOF_UINT
+/* optimized version */
+int
+ncmpix_getn_uint_uint(const void **xpp, MPI_Offset nelems, unsigned int *tp)
+{
+#ifdef WORDS_BIGENDIAN
+ (void) memcpy(tp, *xpp, (size_t)nelems * SIZEOF_UINT);
+# else
+ swapn4b(tp, *xpp, nelems);
+# endif
+ *xpp = (const void *)((const char *)(*xpp) + nelems * X_SIZEOF_UINT);
+ return NC_NOERR;
+}
+#else
+NCX_GETN(uint, uint)
+#endif
+NCX_GETN(uint, schar)
+NCX_GETN(uint, short)
+NCX_GETN(uint, int)
+NCX_GETN(uint, long)
+NCX_GETN(uint, float)
+NCX_GETN(uint, double)
+NCX_GETN(uint, longlong)
+NCX_GETN(uint, uchar)
+NCX_GETN(uint, ushort)
+NCX_GETN(uint, ulonglong)
+
+#if X_SIZEOF_UINT == SIZEOF_UINT
+/* optimized version */
+int
+ncmpix_putn_uint_uint(void **xpp, MPI_Offset nelems, const unsigned int *tp)
+{
+#ifdef WORDS_BIGENDIAN
+ (void) memcpy(*xpp, tp, (size_t)nelems * X_SIZEOF_UINT);
+# else
+ swapn4b(*xpp, tp, nelems);
+# endif
+ *xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_UINT);
+ return NC_NOERR;
+}
+#else
+NCX_PUTN(uint, uint)
+#endif
+NCX_PUTN(uint, schar)
+NCX_PUTN(uint, short)
+NCX_PUTN(uint, int)
+NCX_PUTN(uint, long)
+NCX_PUTN(uint, float)
+NCX_PUTN(uint, double)
+NCX_PUTN(uint, longlong)
+NCX_PUTN(uint, uchar)
+NCX_PUTN(uint, ushort)
+NCX_PUTN(uint, ulonglong)
+
+
+/* float ---------------------------------------------------------------------*/
+
+#if X_SIZEOF_FLOAT == SIZEOF_FLOAT && !defined(NO_IEEE_FLOAT)
+/* optimized version */
+int
+ncmpix_getn_float_float(const void **xpp, MPI_Offset nelems, float *tp)
+{
+#ifdef WORDS_BIGENDIAN
+ (void) memcpy(tp, *xpp, (size_t)nelems * SIZEOF_FLOAT);
+# else
+ swapn4b(tp, *xpp, nelems);
+# endif
+ *xpp = (const void *)((const char *)(*xpp) + nelems * X_SIZEOF_FLOAT);
+ return NC_NOERR;
+}
+#elif defined(vax) && vax != 0
+int
+ncmpix_getn_float_float(const void **xpp, MPI_Offset nfloats, float *ip)
+{
+ float *const end = ip + nfloats;
+
+ while (ip < end)
+ {
+GET_VAX_DFLOAT_Body(`(*xpp)')
+
+ ip++;
+ *xpp = (char *)(*xpp) + X_SIZEOF_FLOAT;
+ }
+ return NC_NOERR;
+}
+#else
+int
+ncmpix_getn_float_float(const void **xpp, MPI_Offset nelems, float *tp)
+{
+ const char *xp = *xpp;
+ int status = NC_NOERR;
+
+ for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
+ {
+ const int lstatus = ncmpix_get_float_float(xp, tp);
+ if (status == NC_NOERR) /* report the first encountered error */
+ status = lstatus;
+ }
+
+ *xpp = (const void *)xp;
+ return status;
+}
+
+#endif
+NCX_GETN(float, schar)
+NCX_GETN(float, short)
+NCX_GETN(float, int)
+NCX_GETN(float, long)
+NCX_GETN(float, double)
+NCX_GETN(float, longlong)
+NCX_GETN(float, ushort)
+NCX_GETN(float, uchar)
+NCX_GETN(float, uint)
+NCX_GETN(float, ulonglong)
+
+#if X_SIZEOF_FLOAT == SIZEOF_FLOAT && !defined(NO_IEEE_FLOAT)
+/* optimized version */
+int
+ncmpix_putn_float_float(void **xpp, MPI_Offset nelems, const float *tp)
+{
+#ifdef WORDS_BIGENDIAN
+ (void) memcpy(*xpp, tp, (size_t)nelems * X_SIZEOF_FLOAT);
+# else
+ swapn4b(*xpp, tp, nelems);
+# endif
+ *xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_FLOAT);
+ return NC_NOERR;
+}
+#elif defined(vax) && vax != 0
+int
+ncmpix_putn_float_float(void **xpp, MPI_Offset nfloats, const float *ip)
+{
+ const float *const end = ip + nfloats;
+
+ while (ip < end)
+ {
+PUT_VAX_DFLOAT_Body(`(*xpp)')
+
+ ip++;
+ *xpp = (char *)(*xpp) + X_SIZEOF_FLOAT;
+ }
+ return NC_NOERR;
+}
+#else
+int
+ncmpix_putn_float_float(void **xpp, MPI_Offset nelems, const float *tp)
+{
+ char *xp = *xpp;
+ int status = NC_NOERR;
+
+ for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
+ {
+ int lstatus = ncmpix_put_float_float(xp, tp);
+ if (status == NC_NOERR) /* report the first encountered error */
+ status = lstatus;
+ }
+
+ *xpp = (void *)xp;
+ return status;
+}
+#endif
+NCX_PUTN(float, schar)
+NCX_PUTN(float, short)
+NCX_PUTN(float, int)
+NCX_PUTN(float, long)
+NCX_PUTN(float, double)
+NCX_PUTN(float, longlong)
+NCX_PUTN(float, uchar)
+NCX_PUTN(float, ushort)
+NCX_PUTN(float, uint)
+NCX_PUTN(float, ulonglong)
+
+/* double --------------------------------------------------------------------*/
+
+#if X_SIZEOF_DOUBLE == SIZEOF_DOUBLE && !defined(NO_IEEE_FLOAT)
+/* optimized version */
+int
+ncmpix_getn_double_double(const void **xpp, MPI_Offset nelems, double *tp)
+{
+#ifdef WORDS_BIGENDIAN
+ (void) memcpy(tp, *xpp, (size_t)nelems * SIZEOF_DOUBLE);
+# else
+ swapn8b(tp, *xpp, nelems);
+# endif
+ *xpp = (const void *)((const char *)(*xpp) + nelems * X_SIZEOF_DOUBLE);
+ return NC_NOERR;
+}
+#elif defined(vax) && vax != 0
+int
+ncmpix_getn_double_double(const void **xpp, MPI_Offset ndoubles, double *ip)
+{
+ double *const end = ip + ndoubles;
+
+ while (ip < end)
+ {
+GET_VAX_DDOUBLE_Body(`(*xpp)')
+ ip++;
+ *xpp = (char *)(*xpp) + X_SIZEOF_DOUBLE;
+ }
+ return NC_NOERR;
+}
+ /* vax */
+#else
+int
+ncmpix_getn_double_double(const void **xpp, MPI_Offset nelems, double *tp)
+{
+ const char *xp = *xpp;
+ int status = NC_NOERR;
+
+ for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
+ {
+ const int lstatus = ncmpix_get_double_double(xp, tp);
+ if (status == NC_NOERR) /* report the first encountered error */
+ status = lstatus;
+ }
+
+ *xpp = (const void *)xp;
+ return status;
+}
+#endif
+NCX_GETN(double, schar)
+NCX_GETN(double, short)
+NCX_GETN(double, int)
+NCX_GETN(double, long)
+NCX_GETN(double, float)
+NCX_GETN(double, longlong)
+NCX_GETN(double, uchar)
+NCX_GETN(double, ushort)
+NCX_GETN(double, uint)
+NCX_GETN(double, ulonglong)
+
+#if X_SIZEOF_DOUBLE == SIZEOF_DOUBLE && !defined(NO_IEEE_FLOAT)
+/* optimized version */
+int
+ncmpix_putn_double_double(void **xpp, MPI_Offset nelems, const double *tp)
+{
+#ifdef WORDS_BIGENDIAN
+ (void) memcpy(*xpp, tp, (size_t)nelems * X_SIZEOF_DOUBLE);
+# else
+ swapn8b(*xpp, tp, nelems);
+# endif
+ *xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_DOUBLE);
+ return NC_NOERR;
+}
+#elif defined(vax) && vax != 0
+int
+ncmpix_putn_double_double(void **xpp, MPI_Offset ndoubles, const double *ip)
+{
+ const double *const end = ip + ndoubles;
+
+ while (ip < end)
+ {
+PUT_VAX_DDOUBLE_Body(`(*xpp)')
+ ip++;
+ *xpp = (char *)(*xpp) + X_SIZEOF_DOUBLE;
+ }
+ return NC_NOERR;
+}
+ /* vax */
+#else
+int
+ncmpix_putn_double_double(void **xpp, MPI_Offset nelems, const double *tp)
+{
+ char *xp = *xpp;
+ int status = NC_NOERR;
+
+ for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
+ {
+ int lstatus = ncmpix_put_double_double(xp, tp);
+ if (status == NC_NOERR) /* report the first encountered error */
+ status = lstatus;
+ }
+
+ *xpp = (void *)xp;
+ return status;
+}
+#endif
+NCX_PUTN(double, schar)
+NCX_PUTN(double, short)
+NCX_PUTN(double, int)
+NCX_PUTN(double, long)
+NCX_PUTN(double, float)
+NCX_PUTN(double, longlong)
+NCX_PUTN(double, uchar)
+NCX_PUTN(double, ushort)
+NCX_PUTN(double, uint)
+NCX_PUTN(double, ulonglong)
+
+
+/* longlong ------------------------------------------------------------------*/
+
+#if X_SIZEOF_INT64 == SIZEOF_LONGLONG
+/* optimized version */
+int
+ncmpix_getn_int64_longlong(const void **xpp, MPI_Offset nelems, long long *tp)
+{
+#ifdef WORDS_BIGENDIAN
+ (void) memcpy(tp, *xpp, (size_t)nelems * SIZEOF_LONG_LONG);
+# else
+ swapn8b(tp, *xpp, nelems);
+# endif
+ *xpp = (const void *)((const char *)(*xpp) + nelems * X_SIZEOF_INT64);
+ return NC_NOERR;
+}
+#else
+NCX_GETN(int64, longlong)
+#endif
+NCX_GETN(int64, schar)
+NCX_GETN(int64, short)
+NCX_GETN(int64, int)
+NCX_GETN(int64, long)
+NCX_GETN(int64, float)
+NCX_GETN(int64, double)
+NCX_GETN(int64, uchar)
+NCX_GETN(int64, ushort)
+NCX_GETN(int64, uint)
+NCX_GETN(int64, ulonglong)
+
+#if X_SIZEOF_INT64 == SIZEOF_LONGLONG
+/* optimized version */
+int
+ncmpix_putn_int64_longlong(void **xpp, MPI_Offset nelems, const long long *tp)
+{
+#ifdef WORDS_BIGENDIAN
+ (void) memcpy(*xpp, tp, (size_t)nelems * X_SIZEOF_INT64);
+# else
+ swapn8b(*xpp, tp, nelems);
+# endif
+ *xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_INT64);
+ return NC_NOERR;
+}
+#else
+NCX_PUTN(int64, longlong)
+#endif
+NCX_PUTN(int64, schar)
+NCX_PUTN(int64, short)
+NCX_PUTN(int64, int)
+NCX_PUTN(int64, long)
+NCX_PUTN(int64, float)
+NCX_PUTN(int64, double)
+NCX_PUTN(int64, uchar)
+NCX_PUTN(int64, ushort)
+NCX_PUTN(int64, uint)
+NCX_PUTN(int64, ulonglong)
+
+/* uint64 --------------------------------------------------------------------*/
+
+#if X_SIZEOF_UINT64 == SIZEOF_ULONGLONG
+/* optimized version */
+int
+ncmpix_getn_uint64_ulonglong(const void **xpp, MPI_Offset nelems, unsigned long long *tp)
+{
+#ifdef WORDS_BIGENDIAN
+ (void) memcpy(tp, *xpp, (size_t)nelems * SIZEOF_UNSIGNED_LONG_LONG);
+# else
+ swapn8b(tp, *xpp, nelems);
+# endif
+ *xpp = (const void *)((const char *)(*xpp) + nelems * X_SIZEOF_UINT64);
+ return NC_NOERR;
+}
+#else
+NCX_GETN(uint64, ulonglong)
+#endif
+NCX_GETN(uint64, schar)
+NCX_GETN(uint64, short)
+NCX_GETN(uint64, int)
+NCX_GETN(uint64, long)
+NCX_GETN(uint64, float)
+NCX_GETN(uint64, double)
+NCX_GETN(uint64, longlong)
+NCX_GETN(uint64, uchar)
+NCX_GETN(uint64, ushort)
+NCX_GETN(uint64, uint)
+
+#if X_SIZEOF_UINT64 == SIZEOF_ULONGLONG
+/* optimized version */
+int
+ncmpix_putn_uint64_ulonglong(void **xpp, MPI_Offset nelems, const unsigned long long *tp)
+{
+#ifdef WORDS_BIGENDIAN
+ (void) memcpy(*xpp, tp, (size_t)nelems * X_SIZEOF_UINT64);
+# else
+ swapn8b(*xpp, tp, nelems);
+# endif
+ *xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_UINT64);
+ return NC_NOERR;
+}
+#else
+NCX_PUTN(uint64, ulonglong)
+#endif
+NCX_PUTN(uint64, schar)
+NCX_PUTN(uint64, short)
+NCX_PUTN(uint64, int)
+NCX_PUTN(uint64, long)
+NCX_PUTN(uint64, float)
+NCX_PUTN(uint64, double)
+NCX_PUTN(uint64, longlong)
+NCX_PUTN(uint64, uchar)
+NCX_PUTN(uint64, ushort)
+NCX_PUTN(uint64, uint)
+
+
+/*
+ * Other aggregate conversion functions.
+ */
+
+/* text */
+
+int
+ncmpix_getn_text(const void **xpp, MPI_Offset nelems, char *tp)
+{
+NCX_GETN_Byte_Body
+}
+
+int
+ncmpix_pad_getn_text(const void **xpp, MPI_Offset nelems, char *tp)
+{
+NCX_PAD_GETN_Byte_Body
+}
+
+int
+ncmpix_putn_text(void **xpp, MPI_Offset nelems, const char *tp)
+{
+NCX_PUTN_Byte_Body
+}
+
+int
+ncmpix_pad_putn_text(void **xpp, MPI_Offset nelems, const char *tp)
+{
+NCX_PAD_PUTN_Byte_Body
+}
+
+
+/* opaque */
+
+int
+ncmpix_getn_void(const void **xpp, MPI_Offset nelems, void *tp)
+{
+NCX_GETN_Byte_Body
+}
+
+int
+ncmpix_pad_getn_void(const void **xpp, MPI_Offset nelems, void *tp)
+{
+NCX_PAD_GETN_Byte_Body
+}
+
+int
+ncmpix_putn_void(void **xpp, MPI_Offset nelems, const void *tp)
+{
+NCX_PUTN_Byte_Body
+}
+
+int
+ncmpix_pad_putn_void(void **xpp, MPI_Offset nelems, const void *tp)
+{
+NCX_PAD_PUTN_Byte_Body
+}
diff --git a/src/lib/nonblocking.c b/src/lib/nonblocking.c
new file mode 100644
index 0000000..21086dd
--- /dev/null
+++ b/src/lib/nonblocking.c
@@ -0,0 +1,2201 @@
+/*
+ * Copyright (C) 2003, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ */
+/* $Id: nonblocking.c 2214 2015-12-08 00:33:40Z wkliao $ */
+
+#if HAVE_CONFIG_H
+# include "ncconfig.h"
+#endif
+
+#include <stdio.h>
+#include <unistd.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#include <assert.h>
+
+#include <mpi.h>
+
+#include "nc.h"
+#include "ncx.h"
+#include "ncmpidtype.h"
+#include "macro.h"
+
+
+/* buffer layers:
+
+ User Level buf (user defined buffer of MPI_Datatype)
+ MPI Datatype Level cbuf (contiguous buffer of ptype)
+ NetCDF XDR Level xbuf (XDR I/O buffer)
+*/
+
+/* Prototypes for functions used only in this file */
+static int ncmpii_wait_getput(NC *ncp, int num_reqs, NC_req *req_head,
+ int rw_flag, int io_method);
+
+static int ncmpii_mgetput(NC *ncp, int num_reqs, NC_req *reqs, int rw_flag,
+ int io_method);
+
+/*----< ncmpii_getput_zero_req() >--------------------------------------------*/
+/* This function is called when this process has zero-length I/O request and
+ * must participate all the MPI collective calls involved in the collective
+ * APIs and wait_all(), which include setting fileview, collective read/write,
+ * another setting fileview.
+ *
+ * This function is collective.
+ */
+static int
+ncmpii_getput_zero_req(NC *ncp,
+ int rw_flag) /* WRITE_REQ or READ_REQ */
+{
+ int err, mpireturn, status=NC_NOERR;
+ MPI_Status mpistatus;
+ MPI_File fh;
+
+ fh = ncp->nciop->collective_fh;
+
+ TRACE_IO(MPI_File_set_view)(fh, 0, MPI_BYTE, MPI_BYTE, "native",
+ MPI_INFO_NULL);
+
+ if (rw_flag == READ_REQ) {
+ TRACE_IO(MPI_File_read_all)(fh, NULL, 0, MPI_BYTE, &mpistatus);
+ if (mpireturn != MPI_SUCCESS) {
+ err = ncmpii_handle_error(mpireturn, "MPI_File_read_all");
+ status = (err == NC_EFILE) ? NC_EREAD : err;
+ DEBUG_ASSIGN_ERROR(status, status)
+ }
+ } else { /* WRITE_REQ */
+ TRACE_IO(MPI_File_write_all)(fh, NULL, 0, MPI_BYTE, &mpistatus);
+ if (mpireturn != MPI_SUCCESS) {
+ err = ncmpii_handle_error(mpireturn, "MPI_File_write_all");
+ status = (err == NC_EFILE) ? NC_EWRITE : err;
+ DEBUG_ASSIGN_ERROR(status, status)
+ }
+ }
+
+ /* No longer need to reset the file view, as the root's fileview includes
+ * the whole file header.
+ TRACE_IO(MPI_File_set_view)(fh, 0, MPI_BYTE, MPI_BYTE, "native",
+ MPI_INFO_NULL);
+ */
+
+ return status;
+}
+
+/*----< ncmpii_abuf_coalesce() >---------------------------------------------*/
+/* this function should be called after all bput requests have been served */
+static int
+ncmpii_abuf_coalesce(NC *ncp)
+{
+ int i;
+
+ i = ncp->abuf->tail - 1;
+ /* tail is always pointing to the last (empty) entry of occupy_table[] */
+
+ /* coalesce the freed entries backwardly from the tail */
+ while (i >= 0) {
+ if (ncp->abuf->occupy_table[i].is_used == 0) {
+ ncp->abuf->size_used -= ncp->abuf->occupy_table[i].req_size;
+ i--;
+ }
+ else break;
+ }
+ ncp->abuf->tail = i + 1;
+ /* This may not be ideal, as we stop at the last one that is yet to be
+ * freed. There may be some freed entries before this yet-to-be-freed
+ * one, but we would like to keep the available space as contiguous as
+ * possible. Maybe some smart approach can be considered here.
+ */
+
+ return NC_NOERR;
+}
+
+#define FREE_REQUEST(req) { \
+ if (req->abuf_index >= 0) \
+ ncp->abuf->occupy_table[req->abuf_index].is_used = 0; /* mark free */ \
+ else if (req->xbuf != NULL && req->xbuf != req->buf) \
+ NCI_Free(req->xbuf); \
+ req->xbuf = NULL; \
+ \
+ for (j=0; j<req->num_subreqs; j++) \
+ NCI_Free(req->subreqs[j].start); \
+ \
+ if (req->num_subreqs > 0) \
+ NCI_Free(req->subreqs); \
+ NCI_Free(req->start); \
+}
+
+/*----< ncmpi_cancel() >------------------------------------------------------*/
+int
+ncmpi_cancel(int ncid,
+ int num_req, /* NC_REQ_ALL or non-negative value */
+ int *req_ids, /* [num_req] */
+ int *statuses) /* [num_req] */
+{
+ int status;
+ NC *ncp;
+
+ status = ncmpii_NC_check_id(ncid, &ncp);
+ if (status != NC_NOERR) return status;
+
+ if (NC_indef(ncp)) DEBUG_RETURN_ERROR(NC_EINDEFINE)
+
+ return ncmpii_cancel(ncp, num_req, req_ids, statuses);
+}
+
+/*----< ncmpii_cancel() >-----------------------------------------------------*/
+int
+ncmpii_cancel(NC *ncp,
+ int num_req, /* NC_REQ_all means all pending requests */
+ int *req_ids, /* [num_req]: IN/OUT */
+ int *statuses) /* [num_req] can be NULL (ignore status) */
+{
+ int i, j, status=NC_NOERR;
+ NC_req *pre_req, *cur_req;
+
+ if (num_req == 0)
+ return NC_NOERR;
+
+ /* cancel all pending requests, ignore req_ids and statuses */
+ if (num_req == NC_REQ_ALL) {
+ cur_req = ncp->head;
+ while (cur_req != NULL) {
+ FREE_REQUEST(cur_req)
+ NCI_Free(cur_req);
+ cur_req = cur_req->next;
+ }
+ ncp->head = NULL;
+ ncp->tail = NULL;
+ return NC_NOERR;
+ }
+
+ /* collect the requests from the linked list */
+ for (i=0; i<num_req; i++) {
+ int found_id=-1;
+ if (statuses != NULL) statuses[i] = NC_NOERR;
+
+ if (req_ids[i] == NC_REQ_NULL)
+ continue;
+
+ if (ncp->head == NULL) {
+ if (statuses != NULL) DEBUG_ASSIGN_ERROR(statuses[i], NC_EINVAL_REQUEST)
+ if (status == NC_NOERR) DEBUG_ASSIGN_ERROR(status, NC_EINVAL_REQUEST)
+ continue;
+ }
+
+ pre_req = cur_req = ncp->head;
+ while (cur_req != NULL) {
+ /* there may be more than one node with the same ID */
+ if (cur_req->id == req_ids[i]) {
+ if (cur_req == ncp->head) { /* move ncp->head ahead */
+ ncp->head = cur_req->next;
+ pre_req = ncp->head;
+ }
+ else /* move pre_req ahead */
+ pre_req->next = cur_req->next;
+
+ FREE_REQUEST(cur_req)
+ NCI_Free(cur_req);
+ found_id = req_ids[i];
+ /* move cur_req ahead */
+ cur_req = (pre_req == ncp->head) ? pre_req : pre_req->next;
+ }
+ else if (found_id >= 0) break;
+ else {
+ if (cur_req == pre_req) cur_req = pre_req->next;
+ else {
+ pre_req = cur_req;
+ cur_req = pre_req->next;
+ }
+ }
+ }
+
+ if (found_id == -1) { /* no such request ID */
+ if (statuses != NULL) DEBUG_ASSIGN_ERROR(statuses[i], NC_EINVAL_REQUEST)
+ /* retain the first error status */
+ if (status == NC_NOERR) DEBUG_ASSIGN_ERROR(status, NC_EINVAL_REQUEST)
+ }
+ else req_ids[i] = NC_REQ_NULL;
+ }
+
+ /* make sure ncp->tail pointing to the tail */
+ ncp->tail = ncp->head;
+ while (ncp->tail != NULL && ncp->tail->next != NULL)
+ ncp->tail = ncp->tail->next;
+
+ return status;
+}
+
+/*----< ncmpi_inq_nreqs() >---------------------------------------------------*/
+/* TODO: add member num_reqs into NC_req to track this info */
+int
+ncmpi_inq_nreqs(int ncid,
+ int *nreqs) /* OUT: number of pending requests */
+{
+ int status, prev_id;
+ NC *ncp;
+ NC_req *req_ptr;
+
+ status = ncmpii_NC_check_id(ncid, &ncp);
+ if (status != NC_NOERR) return status;
+
+ req_ptr = ncp->head;
+ *nreqs = 0;
+ prev_id = NC_REQ_NULL;
+ while (req_ptr != NULL) {
+ /* some requests in the linked list may share the same ID, they were
+ * corresponding to the subrequests made from iput/iget/bput varn APIs.
+ */
+ if (req_ptr->id != prev_id) {
+ prev_id = req_ptr->id;
+ (*nreqs)++;
+ }
+ req_ptr = req_ptr->next;
+ }
+
+ return NC_NOERR;
+}
+
+/*----< ncmpi_wait() >--------------------------------------------------------*/
+/* ncmpi_wait() is an independent call
+ * Argument num_reqs can be NC_REQ_ALL which means to flush all pending
+ * nonblocking requests. In this case, arguments req_ids and statuses will be
+ * ignored.
+ * Argument num_reqs must either be NC_REQ_ALL or a non-negative value.
+ * Argument statuses can be NULL, meaning the caller only cares about the
+ * error code returned by this call, but not the statuses of individual
+ * nonblocking requests.
+ */
+int
+ncmpi_wait(int ncid,
+ int num_reqs,
+ int *req_ids, /* [num_reqs]: IN/OUT */
+ int *statuses) /* [num_reqs] */
+{
+ int status=NC_NOERR;
+ NC *ncp;
+
+ if (num_reqs == 0) return NC_NOERR;
+
+ status = ncmpii_NC_check_id(ncid, &ncp);
+ if (status != NC_NOERR) return status;
+
+#ifdef ENABLE_NONBLOCKING
+ return ncmpii_wait(ncp, INDEP_IO, num_reqs, req_ids, statuses);
+#else
+ int i, err, *reqids=NULL;
+ if (num_reqs == NC_REQ_ALL) { /* flush all pending requests */
+ /* in this case, arguments req_ids and statuses are ignored */
+ int prev_id = NC_REQ_NULL;
+ NC_req *req_ptr = ncp->head;
+ num_reqs = 0;
+ while (req_ptr != NULL) {
+ /* some requests in the linked list may share the same ID, they were
+ * corresponding to the subrequests made from iput/iget/bput varn APIs.
+ */
+ if (req_ptr->id != prev_id) {
+ prev_id = req_ptr->id;
+ num_reqs++;
+ }
+ req_ptr = req_ptr->next;
+ }
+ /* allocate ID array */
+ reqids = (int*) NCI_Malloc(num_reqs * sizeof(int));
+ req_ptr = ncp->head;
+ num_reqs = 0;
+ prev_id = NC_REQ_NULL;
+ while (req_ptr != NULL) {
+ if (req_ptr->id != prev_id) {
+ prev_id = req_ptr->id;
+ reqids[num_reqs++] = prev_id;
+ }
+ req_ptr = req_ptr->next;
+ }
+ req_ids = reqids;
+ }
+ for (i=0; i<num_reqs; i++) { /* serve one request at a time */
+ if (statuses == NULL)
+ err = ncmpii_wait(ncp, INDEP_IO, 1, &req_ids[i], NULL);
+ else
+ err = ncmpii_wait(ncp, INDEP_IO, 1, &req_ids[i], &statuses[i]);
+ if (status == NC_NOERR) status = err;
+ }
+ if (reqids != NULL) NCI_Free(reqids);
+
+ return status; /* return the first error encountered */
+#endif
+}
+
+/*----< ncmpi_wait_all() >----------------------------------------------------*/
+/* ncmpi_wait_all() is a collective call
+ * Argument num_reqs can be NC_REQ_ALL which means to flush all pending
+ * nonblocking requests. In this case, arguments req_ids and statuses will be
+ * ignored.
+ * Argument num_reqs must either be NC_REQ_ALL or a non-negative value.
+ * Argument statuses can be NULL, meaning the caller only cares about the
+ * error code returned by this call, but not the statuses of individual
+ * nonblocking requests.
+ */
+int
+ncmpi_wait_all(int ncid,
+ int num_reqs, /* number of requests */
+ int *req_ids, /* [num_reqs]: IN/OUT */
+ int *statuses) /* [num_reqs], can be NULL */
+{
+ int status=NC_NOERR;
+ NC *ncp;
+ /* the following line CANNOT be added, because ncmpi_wait_all() is a
+ * collective call, all processes must participate some MPI collective
+ * operations used later on.
+ */
+ /* if (num_reqs == 0) return NC_NOERR; */
+
+ status = ncmpii_NC_check_id(ncid, &ncp);
+ if (status != NC_NOERR)
+ /* must return the error now, parallel program might hang */
+ return status;
+
+#ifdef ENABLE_NONBLOCKING
+ return ncmpii_wait(ncp, COLL_IO, num_reqs, req_ids, statuses);
+#else
+ int i, err, *reqids=NULL;
+
+ /* This API is collective, so make it illegal in indep mode. This also
+ ensures the program will returns back to collective mode. */
+ if (NC_indep(ncp)) DEBUG_RETURN_ERROR(NC_EINDEP);
+
+ /* must enter independent mode, as num_reqs may be different among
+ processes */
+ err = ncmpi_begin_indep_data(ncid);
+ if (status == NC_NOERR) status = err;
+
+ if (num_reqs == NC_REQ_ALL) { /* flush all pending requests */
+ int prev_id = NC_REQ_NULL;
+ NC_req *req_ptr = ncp->head;
+ num_reqs = 0;
+ while (req_ptr != NULL) {
+ /* some requests in the linked list may share the same ID, they were
+ * corresponding to the subrequests made from iput/iget/bput varn APIs.
+ */
+ if (req_ptr->id != prev_id) {
+ prev_id = req_ptr->id;
+ num_reqs++;
+ }
+ req_ptr = req_ptr->next;
+ }
+ /* allocate ID array */
+ reqids = (int*) NCI_Malloc(num_reqs * sizeof(int));
+ req_ptr = ncp->head;
+ num_reqs = 0;
+ prev_id = NC_REQ_NULL;
+ while (req_ptr != NULL) {
+ if (req_ptr->id != prev_id) {
+ prev_id = req_ptr->id;
+ reqids[num_reqs++] = prev_id;
+ }
+ req_ptr = req_ptr->next;
+ }
+ req_ids = reqids;
+ }
+ for (i=0; i<num_reqs; i++) { /* serve one request at a time */
+ if (statuses == NULL)
+ err = ncmpii_wait(ncp, INDEP_IO, 1, &req_ids[i], NULL);
+ else
+ err = ncmpii_wait(ncp, INDEP_IO, 1, &req_ids[i], &statuses[i]);
+ if (status == NC_NOERR) status = err;
+ }
+ if (reqids != NULL) NCI_Free(reqids);
+
+ /* return to collective data mode */
+ err = ncmpi_end_indep_data(ncid);
+ if (status == NC_NOERR) status = err;
+
+ return status; /* return the first error encountered, if there is any */
+#endif
+}
+
+/*----< ncmpii_concatenate_datatypes() >--------------------------------------*/
+static int
+ncmpii_concatenate_datatypes(int num,
+ int *blocklens, /* IN: [num] */
+ MPI_Offset *displacements, /* IN: [num] */
+ MPI_Datatype *dtypes, /* IN: [num] */
+ MPI_Datatype *datatype) /* OUT: */
+{
+#if SIZEOF_MPI_AINT != SIZEOF_MPI_OFFSET
+ int i;
+#endif
+ int mpireturn, status=NC_NOERR;
+ MPI_Aint *addrs;
+
+ *datatype = MPI_BYTE;
+
+ if (num <= 0) return NC_NOERR;
+
+ /* on most 32 bit systems, MPI_Aint and MPI_Offset are different sizes.
+ * Possible that on those platforms some of the beginning offsets of
+ * these variables in the dataset won't fit into the aint used by
+ * MPI_Type_create_struct. Minor optimization: we don't need to do any
+ * of this if MPI_Aint and MPI_Offset are the same size */
+
+ /* at the configure time, size of MPI_Offset and MPI_Aint are checked */
+#if SIZEOF_MPI_AINT == SIZEOF_MPI_OFFSET
+ addrs = (MPI_Aint*) displacements; /* cast ok: types same size */
+#else
+ /* if (sizeof(MPI_Offset) != sizeof(MPI_Aint)) */
+ addrs = (MPI_Aint *) NCI_Malloc((size_t)num * SIZEOF_MPI_AINT);
+ for (i=0; i<num; i++) {
+ addrs[i] = displacements[i];
+ if (displacements[i] != addrs[i]) {
+ NCI_Free(addrs);
+ DEBUG_RETURN_ERROR(NC_EAINT_TOO_SMALL)
+ }
+ }
+#endif
+
+#ifdef HAVE_MPI_TYPE_CREATE_STRUCT
+ mpireturn = MPI_Type_create_struct(num, blocklens, addrs, dtypes, datatype);
+#else
+ mpireturn = MPI_Type_struct(num, blocklens, addrs, dtypes, datatype);
+#endif
+ if (mpireturn != MPI_SUCCESS)
+ status = ncmpii_handle_error(mpireturn, "MPI_Type_create_struct");
+ else
+ MPI_Type_commit(datatype);
+
+#if SIZEOF_MPI_AINT != SIZEOF_MPI_OFFSET
+ NCI_Free(addrs);
+#endif
+
+ return status;
+}
+
+/*----< ncmpii_construct_filetypes() >----------------------------------------*/
+/* concatenate the requests into a single MPI derived filetype */
+static int
+ncmpii_construct_filetypes(NC *ncp,
+ int num_reqs,
+ NC_req *reqs, /* [num_reqs] */
+ int rw_flag,
+ MPI_Datatype *filetype) /* OUT */
+{
+ int i, j, err, status=NC_NOERR, *blocklens;
+ MPI_Datatype *ftypes;
+ MPI_Offset *displacements;
+
+ if (num_reqs <= 0) { /* for participating collective call */
+ *filetype = MPI_BYTE;
+ return NC_NOERR;;
+ }
+
+ /* hereinafter, num_reqs > 0 */
+ blocklens = (int*) NCI_Malloc((size_t)num_reqs * SIZEOF_INT);
+ displacements = (MPI_Offset*) NCI_Malloc((size_t)num_reqs * SIZEOF_MPI_OFFSET);
+ ftypes = (MPI_Datatype*) NCI_Malloc((size_t)num_reqs * sizeof(MPI_Datatype));
+
+ /* create a filetype for each request */
+ int last_contig_req = -1; /* index of the last contiguous request */
+ j = 0; /* index of last valid ftypes */
+ for (i=0; i<num_reqs; i++, j++) {
+ int is_filetype_contig;
+ ftypes[j] = MPI_BYTE; /* in case the call below failed */
+ err = ncmpii_vars_create_filetype(ncp,
+ reqs[i].varp,
+ reqs[i].start,
+ reqs[i].count,
+ reqs[i].stride,
+ rw_flag,
+ &blocklens[j],
+ &displacements[j], /* to offset 0 */
+ &ftypes[j],
+ &is_filetype_contig);
+ if (err != NC_NOERR) {
+ reqs[i].bnelems = 0; /* make this request no effect */
+ if (reqs[i].status != NULL && *reqs[i].status == NC_NOERR)
+ *reqs[i].status = err;
+ if (status == NC_NOERR) status = err; /* report the first error */
+ continue;
+ }
+
+ if (is_filetype_contig) {
+ if (last_contig_req >= 0 &&
+ displacements[j] - displacements[last_contig_req] ==
+ blocklens[last_contig_req]) {
+ blocklens[last_contig_req] += blocklens[j];
+ j--;
+ }
+ else last_contig_req = j;
+ }
+ else last_contig_req = -1;
+ }
+ /* j is the new num_reqs */
+ num_reqs = j;
+
+ if (status != NC_NOERR) {
+ /* even if error occurs, we still must participate the collective
+ call to MPI_File_set_view() */
+ *filetype = MPI_BYTE;
+ }
+ else if (num_reqs == 1 && displacements[0] == 0) {
+ MPI_Type_dup(ftypes[0], filetype);
+ }
+ else { /* if (num_reqs > 1 || (num_reqs == 1 && displacements[0] > 0)) */
+ /* all ftypes[] created fine, now concatenate all ftypes[] */
+ err = ncmpii_concatenate_datatypes(num_reqs,
+ blocklens,
+ displacements,
+ ftypes,
+ filetype);
+ if (err != NC_NOERR) *filetype = MPI_BYTE;
+ if (status == NC_NOERR) status = err; /* report the first error */
+ }
+
+ for (i=0; i<num_reqs; i++) {
+ if (ftypes[i] != MPI_BYTE)
+ MPI_Type_free(&ftypes[i]);
+ }
+ NCI_Free(ftypes);
+ NCI_Free(displacements);
+ NCI_Free(blocklens);
+
+ return status;
+}
+
+/*----< ncmpii_construct_buffertypes() >--------------------------------------*/
+/* the input requests, reqs[], are non-interleaving requests */
+static int
+ncmpii_construct_buffertypes(int num_reqs,
+ NC_req *reqs, /* [num_reqs] */
+ MPI_Datatype *buffer_type) /* OUT */
+{
+ int i, j, status=NC_NOERR, mpireturn;
+
+ *buffer_type = MPI_BYTE;
+ if (num_reqs == 0) return NC_NOERR;
+
+ /* create the I/O buffer derived data type */
+ int *blocklengths = (int*) NCI_Malloc((size_t)num_reqs * SIZEOF_INT);
+ MPI_Aint *disps = (MPI_Aint*) NCI_Malloc((size_t)num_reqs*SIZEOF_MPI_AINT);
+ MPI_Aint a0, ai;
+
+ /* process only valid requests */
+ for (i=0, j=0; i<num_reqs; i++) {
+ /* check int overflow */
+ MPI_Offset int8 = reqs[i].bnelems * reqs[i].varp->xsz;
+ blocklengths[j] = (int)int8;
+ if (int8 != blocklengths[j]) { /* skip this request */
+ DEBUG_ASSIGN_ERROR(status, NC_EINTOVERFLOW)
+ continue;
+ }
+#ifdef HAVE_MPI_GET_ADDRESS
+ MPI_Get_address(reqs[i].xbuf, &ai);
+#else
+ MPI_Address(reqs[i].xbuf, &ai);
+#endif
+ if (j == 0) a0 = ai;
+ disps[j] = ai - a0;
+ j++;
+ }
+ /* update num_reqs to number of valid requests */
+ num_reqs = j;
+
+ if (num_reqs > 0) {
+ /* concatenate buffer addresses into a single buffer type */
+#ifdef HAVE_MPI_TYPE_CREATE_HINDEXED
+ mpireturn = MPI_Type_create_hindexed(num_reqs, blocklengths, disps,
+ MPI_BYTE, buffer_type);
+#else
+ mpireturn = MPI_Type_hindexed(num_reqs, blocklengths, disps, MPI_BYTE,
+ buffer_type);
+#endif
+ if (mpireturn != MPI_SUCCESS) {
+ int err = ncmpii_handle_error(mpireturn, "MPI_Type_hindexed");
+ /* return the first encountered error if there is any */
+ if (status == NC_NOERR) status = err;
+ }
+ else
+ MPI_Type_commit(buffer_type);
+ }
+ NCI_Free(disps);
+ NCI_Free(blocklengths);
+
+ return status;
+}
+
+/*----< ncmpii_wait() >-------------------------------------------------------*/
+/* The buffer management flow is described below. The wait side starts from
+ the I/O step, i.e. step 5
+
+ for put_varm:
+ 1. pack buf to lbuf based on buftype
+ 2. create imap_type based on imap
+ 3. pack lbuf to cbuf based on imap_type
+ 4. type convert and byte swap cbuf to xbuf
+ 5. write from xbuf
+ 6. byte swap the buf to its original, if it is swapped
+ 7. free up temp buffers, cbuf and xbuf if they were allocated separately
+
+ for get_varm:
+ 1. allocate lbuf
+ 2. create imap_type based on imap
+ 3. allocate cbuf
+ 4. allocate xbuf
+ 5. read to xbuf
+ 6. type convert and byte swap xbuf to cbuf
+ 7. unpack cbuf to lbuf based on imap_type
+ 8. unpack lbuf to buf based on buftype
+ 9. free up temp buffers, cbuf and xbuf if they were allocated separately
+ */
+int
+ncmpii_wait(NC *ncp,
+ int io_method, /* COLL_IO or INDEP_IO */
+ int num_reqs, /* number of requests */
+ int *req_ids, /* [num_reqs] */
+ int *statuses) /* [num_reqs] */
+{
+ int i, j, err=NC_NOERR, status=NC_NOERR;
+ int do_read, do_write, num_w_reqs=0, num_r_reqs=0;
+ NC_req *pre_req, *cur_req, *next_req;
+ NC_req *w_req_head=NULL, *w_req_tail=NULL;
+ NC_req *r_req_head=NULL, *r_req_tail=NULL;
+
+ if (NC_indef(ncp)) { /* This API can only be called in data mode */
+ DEBUG_ASSIGN_ERROR(err, NC_EINDEFINE)
+ goto err_check;
+ }
+
+ /* check the MPI file handles for collective or independent mode */
+ if (io_method == INDEP_IO)
+ err = ncmpii_check_mpifh(ncp, 0);
+ else if (io_method == COLL_IO)
+ err = ncmpii_check_mpifh(ncp, 1);
+ if (err != NC_NOERR) goto err_check;
+
+ if (num_reqs == NC_REQ_ALL) { /* flush all pending requests */
+ /* in this case, arguments req_ids[] and statuses[] are ignored */
+ cur_req = ncp->head;
+ while (cur_req != NULL) {
+ cur_req->status = NULL;
+ next_req = cur_req->next;
+ if (cur_req->rw_flag == READ_REQ) {
+ /* add cur_req to r_req_tail */
+ if (r_req_head == NULL) {
+ r_req_head = cur_req;
+ r_req_tail = cur_req;
+ }
+ else {
+ r_req_tail->next = cur_req;
+ r_req_tail = r_req_tail->next;
+ }
+ r_req_tail->next = NULL;
+ num_r_reqs += (cur_req->num_subreqs == 0) ?
+ 1 : cur_req->num_subreqs;
+ /* if this request is to a record variable, then count all
+ * its subrequests (one for each individual record) */
+ }
+ else { /* add cur_req to w_req_tail */
+ if (w_req_head == NULL) {
+ w_req_head = cur_req;
+ w_req_tail = cur_req;
+ }
+ else {
+ w_req_tail->next = cur_req;
+ w_req_tail = w_req_tail->next;
+ }
+ w_req_tail->next = NULL;
+ num_w_reqs += (cur_req->num_subreqs == 0) ?
+ 1 : cur_req->num_subreqs;
+ /* if this request is to a record variable, then count all
+ * its subrequests (one for each individual record) */
+ }
+ cur_req = next_req;
+ }
+ ncp->head = NULL;
+ ncp->tail = NULL;
+ num_reqs = 0; /* to skip the loop below */
+ }
+ /* extract the matched requests from the pending queue (a linked list
+ * containing all nonblocking requests posted by far) into two separate
+ * linked lists for read and write. In the meantime coalesce the pending
+ * request queue.
+ */
+ for (i=0; i<num_reqs; i++) {
+ int found_id=-1;
+
+ if (statuses != NULL)
+ statuses[i] = NC_NOERR; /* initialize the request's status */
+
+ if (req_ids[i] == NC_REQ_NULL) continue; /* skip NULL request */
+
+ if (ncp->head == NULL) {
+ /* no more pending requests in the queue, this request is invalid */
+ if (statuses != NULL) DEBUG_ASSIGN_ERROR(statuses[i], NC_EINVAL_REQUEST)
+ /* retain the first error status */
+ if (status == NC_NOERR) DEBUG_ASSIGN_ERROR(status, NC_EINVAL_REQUEST)
+ continue;
+ /* don't break loop i, continue to set the error status */
+ }
+
+ /* find req_ids[i] from the pending queue */
+ pre_req = cur_req = ncp->head;
+ while (cur_req != NULL) {
+ /* there may be more than one pending request with the same ID.
+ * In this case, these requests are from a single nonblocking
+ * varn API.
+ */
+ if (cur_req->id == req_ids[i]) { /* found it */
+ /* point status of this request to user's statuses[i] */
+ if (statuses != NULL)
+ cur_req->status = statuses + i;
+ else
+ cur_req->status = NULL;
+ /* point all subrequests' statuses to status */
+ for (j=0; j<cur_req->num_subreqs; j++)
+ cur_req->subreqs[j].status = cur_req->status;
+
+ /* remove cur_req from the ncp->head linked list */
+ if (cur_req == ncp->head) { /* move cur_req to next */
+ ncp->head = cur_req->next;
+ pre_req = ncp->head;
+ }
+ else /* move pre_req and cur_req to next */
+ pre_req->next = cur_req->next;
+
+ next_req = cur_req->next;
+
+ if (cur_req->rw_flag == READ_REQ) {
+ /* add cur_req to r_req_tail */
+ if (r_req_head == NULL) {
+ r_req_head = cur_req;
+ r_req_tail = cur_req;
+ }
+ else {
+ r_req_tail->next = cur_req;
+ r_req_tail = r_req_tail->next;
+ }
+ r_req_tail->next = NULL;
+ num_r_reqs += (cur_req->num_subreqs == 0) ?
+ 1 : cur_req->num_subreqs;
+ /* if this request is to a record variable, then count all
+ * its subrequests (one for each individual record) */
+ }
+ else { /* add cur_req to w_req_tail */
+ if (w_req_head == NULL) {
+ w_req_head = cur_req;
+ w_req_tail = cur_req;
+ }
+ else {
+ w_req_tail->next = cur_req;
+ w_req_tail = w_req_tail->next;
+ }
+ w_req_tail->next = NULL;
+ num_w_reqs += (cur_req->num_subreqs == 0) ?
+ 1 : cur_req->num_subreqs;
+ /* if this request is to a record variable, then count all
+ * its subrequests (one for each individual record) */
+ }
+ found_id = req_ids[i]; /* indicating previous found ID */
+ cur_req = next_req;
+ }
+ else if (found_id >= 0) {
+ /* same request IDs (for varn APIs) are stored contiguously in
+ * the linked list so if it is already found and this next
+ * request has a different ID, no need to continue checking
+ * the rest list */
+ break; /* while loop */
+ }
+ else { /* not found: move on to next pending request in the queue */
+ if (cur_req == pre_req) cur_req = pre_req->next;
+ else {
+ pre_req = cur_req;
+ cur_req = pre_req->next;
+ }
+ }
+ } /* done with searching the entire linked list for this request ID */
+
+ if (found_id == -1) { /* no such request ID */
+ if (statuses != NULL) DEBUG_ASSIGN_ERROR(statuses[i], NC_EINVAL_REQUEST)
+ if (status == NC_NOERR) /* retain the first error status */
+ DEBUG_ASSIGN_ERROR(status, NC_EINVAL_REQUEST)
+ }
+ else req_ids[i] = NC_REQ_NULL;
+ }
+ /* make sure ncp->tail pointing to the tail of the pending request queue */
+ ncp->tail = ncp->head;
+ while (ncp->tail != NULL && ncp->tail->next != NULL)
+ ncp->tail = ncp->tail->next;
+
+err_check:
+ if (io_method == COLL_IO) {
+ int mpireturn;
+ int io_req[3], do_io[3]; /* [0]: read [1]: write [2]: error */
+ io_req[0] = num_r_reqs;
+ io_req[1] = num_w_reqs;
+ io_req[2] = -err; /* all NC errors are negative */
+ TRACE_COMM(MPI_Allreduce)(io_req, do_io, 3, MPI_INT, MPI_MAX,
+ ncp->nciop->comm);
+ if (mpireturn != MPI_SUCCESS)
+ return ncmpii_handle_error(mpireturn, "MPI_Allreduce");
+
+ /* if error occurs, return the API collectively */
+ if (do_io[2] != -NC_NOERR) return err;
+
+ /* if at least one process has a non-zero request, all processes must
+ * participate the collective read/write */
+ do_read = do_io[0];
+ do_write = do_io[1];
+ }
+ else {
+ if (err != NC_NOERR) return err;
+ do_read = num_r_reqs;
+ do_write = num_w_reqs;
+ }
+ /* carry out writes and reads separately (writes first) */
+ if (do_write > 0)
+ err = ncmpii_wait_getput(ncp, num_w_reqs, w_req_head, WRITE_REQ,
+ io_method);
+
+ if (do_read > 0)
+ err = ncmpii_wait_getput(ncp, num_r_reqs, r_req_head, READ_REQ,
+ io_method);
+
+ /* retain the first error status */
+ if (status == NC_NOERR) status = err;
+
+ /* post-IO data processing: In write case, we may need to byte-swap user
+ * write buf if it is used as the write buffer in MPI write call and the
+ * target machine is little Endian. For read case, we may need to
+ * unpack/byte-swap/type-convert a temp buffer to the user read buf
+ */
+
+ if (w_req_head != NULL) {
+ cur_req = w_req_head;
+ while (cur_req != NULL) {
+ /* must byte-swap the user buffer back to its original Endianness
+ only when the buffer itself has been byte-swapped before,
+ i.e. NOT buftype_is_contig && NOT ncmpii_need_convert() &&
+ ncmpii_need_swap()
+ */
+ if (cur_req->need_swap_back_buf)
+ ncmpii_in_swapn(cur_req->buf, cur_req->bnelems,
+ ncmpix_len_nctype(cur_req->varp->type));
+ cur_req = cur_req->next;
+ }
+ cur_req = w_req_head;
+ while (cur_req != NULL) {
+ /* free temp space allocated for iput/bput varn requests. Note that
+ * tmpBuf is used only by nonblocking varn APIs. This while loop
+ * is not combined with the one above because the nonblocking varn
+ * APIs may be used. During the posting of a nonblocking varn
+ * request, the temporary buffer, if allocated, can be divided into
+ * several sub-buffers, each used in a separate requests. Only the
+ * first subrequest's tmpBuf will be set to non-NULL, indicating
+ * it should be freed.
+ */
+ if (cur_req->tmpBuf != NULL && cur_req->abuf_index == -1)
+ NCI_Free(cur_req->tmpBuf);
+
+ FREE_REQUEST(cur_req)
+ pre_req = cur_req;
+ cur_req = cur_req->next;
+ NCI_Free(pre_req);
+ }
+ /* once the bput requests are served, we reclaim the space and try
+ * coalesce the freed space for the attached buffer */
+ if (ncp->abuf != NULL) ncmpii_abuf_coalesce(ncp);
+ }
+
+ if (r_req_head != NULL) {
+ cur_req = r_req_head;
+ while (cur_req != NULL) {
+ NC_var *varp = cur_req->varp;
+
+ /* now, xbuf contains the data read from the file.
+ * It needs to be type-converted + byte-swapped to cbuf
+ */
+ void *cbuf, *lbuf;
+ int el_size, position;
+ MPI_Offset insize;
+
+ MPI_Type_size(cur_req->ptype, &el_size);
+ insize = cur_req->bnelems * el_size;
+ if (insize != (int)insize && status == NC_NOERR)
+ DEBUG_ASSIGN_ERROR(status, NC_EINTOVERFLOW)
+
+ if (ncmpii_need_convert(varp->type, cur_req->ptype)) {
+ /* need type conversion from the external type to user buffer
+ type */
+ if (cur_req->imaptype != MPI_DATATYPE_NULL ||
+ !cur_req->buftype_is_contig)
+ cbuf = NCI_Malloc((size_t)insize);
+ else
+ cbuf = cur_req->buf;
+
+ /* type convert + byte swap from xbuf to cbuf */
+ DATATYPE_GET_CONVERT(varp->type, cur_req->xbuf, cbuf,
+ cur_req->bnelems, cur_req->ptype, err)
+ /* keep the first error */
+ if (cur_req->status != NULL && *cur_req->status == NC_NOERR)
+ *cur_req->status = err;
+ if (status == NC_NOERR) status = err;
+ } else {
+ if (ncmpii_need_swap(varp->type, cur_req->ptype))
+ ncmpii_in_swapn(cur_req->xbuf, cur_req->bnelems,
+ ncmpix_len_nctype(varp->type));
+ cbuf = cur_req->xbuf;
+ }
+
+ if (cur_req->imaptype != MPI_DATATYPE_NULL) {
+ /* handle the case for a true get_varm */
+ if (cur_req->buftype_is_contig)
+ lbuf = cur_req->buf;
+ else
+ lbuf = NCI_Malloc((size_t)insize);
+
+ /* unpack cbuf to lbuf based on imaptype */
+ position = 0;
+ MPI_Unpack(cbuf, (int)insize, &position, lbuf, 1,
+ cur_req->imaptype, MPI_COMM_SELF);
+ MPI_Type_free(&cur_req->imaptype);
+
+ /* cbuf is no longer needed
+ * for a true varm call, cbuf cannot be == cur_req->buf */
+ if (cbuf != cur_req->xbuf) NCI_Free(cbuf);
+ cbuf = NULL;
+ } else { /* get_vars */
+ lbuf = cbuf;
+ }
+
+ if (!cur_req->buftype_is_contig) {
+ /* unpack lbuf to buf based on buftype */
+ position = 0;
+ if (cur_req->bufcount != (int)cur_req->bufcount &&
+ status == NC_NOERR)
+ DEBUG_ASSIGN_ERROR(status, NC_EINTOVERFLOW)
+ MPI_Unpack(lbuf, (int)insize, &position, cur_req->buf,
+ (int)cur_req->bufcount, cur_req->buftype,
+ MPI_COMM_SELF);
+ MPI_Type_free(&cur_req->buftype);
+ }
+ /* lbuf is no longer needed */
+ if (lbuf != cur_req->buf && lbuf != cur_req->xbuf)
+ NCI_Free(lbuf);
+
+ cur_req = cur_req->next;
+ }
+
+ cur_req = r_req_head;
+ while (cur_req != NULL) {
+ /* free space allocated for the request objects
+ * tmpBuf is used only by nonblocking varn APIs. This while loop
+ * is not combined with the one above because the nonblocking varn
+ * APIs may be used. During the posting of a nonblocking varn
+ * request, the temporary buffer, if allocated, can be divided into
+ * several sub-buffers, each used in a separate requests. Only the
+ * first subrequest's tmpBuf will be set to non-NULL, indicating
+ * it should be freed.
+ */
+ if (cur_req->tmpBuf != NULL) {
+ int position=0, bufsize;
+ MPI_Offset insize;
+
+ /* unpack tmpBuf to userBuf and free tmpBuf
+ * Note this unpack must wait for all above unpacks are done
+ * because cur_req->buf may be part of cur_req->userBuf
+ */
+ MPI_Type_size(cur_req->buftype, &bufsize);
+ insize = cur_req->bufcount * bufsize;
+ if (insize != (int)insize && status == NC_NOERR)
+ DEBUG_ASSIGN_ERROR(status, NC_EINTOVERFLOW)
+
+ MPI_Unpack(cur_req->tmpBuf, (int)insize, &position,
+ cur_req->userBuf, (int)cur_req->bufcount,
+ cur_req->buftype, MPI_COMM_SELF);
+ NCI_Free(cur_req->tmpBuf);
+ MPI_Type_free(&cur_req->buftype);
+ }
+ FREE_REQUEST(cur_req)
+ pre_req = cur_req;
+ cur_req = cur_req->next;
+ NCI_Free(pre_req);
+ }
+ }
+ return status;
+}
+
+/* C struct for breaking down a request to a list of offset-length segments */
+typedef struct {
+ MPI_Offset off; /* starting file offset of the request */
+ MPI_Offset len; /* requested length in bytes starting from off */
+ MPI_Aint buf_addr; /* distance of this request's I/O buffer to the first
+ request to be merged */
+} off_len;
+
+/*----< off_compare() >-------------------------------------------------------*/
+/* used for sorting the offsets of the off_len array */
+static int
+off_compare(const void *a, const void *b)
+{
+ if (((off_len*)a)->off > ((off_len*)b)->off) return 1;
+ if (((off_len*)a)->off < ((off_len*)b)->off) return -1;
+ return 0;
+}
+
+/*----< ncmpii_flatten() >----------------------------------------------------*/
+/* flatten a subarray request into a list of offset-length pairs */
+static MPI_Offset
+ncmpii_flatten(int ndim, /* number of dimensions */
+ int el_size, /* array element size */
+ MPI_Offset *dimlen, /* [ndim] dimension lengths */
+ MPI_Offset offset, /* starting file offset of variable */
+ MPI_Aint buf_addr,/* starting buffer address */
+ MPI_Offset *start, /* [ndim] starts of subarray */
+ MPI_Offset *count, /* [ndim] counts of subarray */
+ MPI_Offset *stride, /* [ndim] strides of subarray */
+ MPI_Offset *nseg, /* OUT: number of segments */
+ off_len *seg) /* OUT: array of segments */
+{
+ int i, j, to_free_stride=0;
+ MPI_Offset seg_len, nstride, array_len, off, subarray_len;
+ off_len *ptr=seg, *seg0;
+
+ *nseg = 0;
+ if (ndim < 0) return *nseg;
+
+ if (ndim == 0) { /* 1D record variable */
+ *nseg = 1;
+ seg->off = offset;
+ seg->len = el_size;
+ seg->buf_addr = buf_addr;
+ return *nseg;
+ }
+
+ if (stride == NULL) { /* equivalent to {1, 1, ..., 1} */
+ stride = (MPI_Offset*) NCI_Malloc((size_t)ndim * SIZEOF_MPI_OFFSET);
+ for (i=0; i<ndim; i++) stride[i] = 1;
+ to_free_stride = 1;
+ }
+
+ /* TODO: check if all stride[] >= 1
+ Q: Is it legal if any stride[] <= 0 ? */
+
+ /* calculate the number of offset-length pairs */
+ *nseg = (stride[ndim-1] == 1) ? 1 : count[ndim-1];
+ for (i=0; i<ndim-1; i++)
+ *nseg *= count[i];
+ if (*nseg == 0) { /* not reachable, an error if count[] == 0 */
+ if (to_free_stride) NCI_Free(stride);
+ return *nseg;
+ }
+
+ /* the length of all segments are of the same size */
+ seg_len = (stride[ndim-1] == 1) ? count[ndim-1] : 1;
+ seg_len *= el_size;
+ nstride = (stride[ndim-1] == 1) ? 1 : count[ndim-1];
+
+ /* set the offset-length pairs for the lowest dimension */
+ off = offset + start[ndim-1] * el_size;
+ for (i=0; i<nstride; i++) {
+ ptr->off = off;
+ ptr->len = seg_len;
+ ptr->buf_addr = buf_addr;
+ buf_addr += seg_len;
+ off += stride[ndim-1] * el_size;
+ ptr++;
+ }
+ ndim--;
+
+ subarray_len = nstride;
+ array_len = 1;
+ /* for higher dimensions */
+ while (ndim > 0) {
+ /* array_len is global array size from lowest up to ndim */
+ array_len *= dimlen[ndim];
+
+ /* off is the global array offset for this dimension, ndim-1 */
+ off = start[ndim-1] * array_len * el_size;
+
+ /* update all offsets from lowest up to dimension ndim-1 */
+ seg0 = seg;
+ for (j=0; j<subarray_len; j++) {
+ seg0->off += off;
+ seg0++;
+ }
+
+ /* update each plan subarray of dimension ndim-1 */
+ off = array_len * stride[ndim-1] * el_size;
+ for (i=1; i<count[ndim-1]; i++) {
+ seg0 = seg;
+ for (j=0; j<subarray_len; j++) {
+ ptr->off = seg0->off + off;
+ ptr->len = seg_len;
+ ptr->buf_addr = buf_addr;
+ buf_addr += seg_len;
+ ptr++;
+ seg0++;
+ }
+ off += array_len * stride[ndim-1] * el_size;
+ }
+ ndim--; /* move to next higher dimension */
+ subarray_len *= count[ndim];
+ }
+ if (to_free_stride) NCI_Free(stride);
+
+ return *nseg;
+}
+
+/*----< ncmpii_merge_requests() >---------------------------------------------*/
+static int
+ncmpii_merge_requests(NC *ncp,
+ int num_reqs,
+ NC_req *reqs, /* [num_reqs] */
+ void **buf, /* OUT: 1st I/O buf addr */
+ MPI_Offset *nsegs, /* OUT: no. off-len pairs */
+ off_len **segs) /* OUT: [*nsegs] */
+{
+ int i, j, status=NC_NOERR, ndims, is_recvar;
+ MPI_Offset nseg, *start, *count, *shape, *stride;
+ MPI_Aint addr, buf_addr;
+
+ *nsegs = 0; /* total number of offset-length pairs */
+ *segs = NULL; /* array of offset-length pairs */
+
+ /* note invalid requests have been removed in ncmpii_wait_getput() */
+ *buf = reqs[0].xbuf; /* I/O buffer of first request */
+
+ /* buf_addr is the buffer address of the first request */
+#ifdef HAVE_MPI_GET_ADDRESS
+ MPI_Get_address(reqs[0].xbuf, &buf_addr);
+#else
+ MPI_Address(reqs[0].xbuf, &buf_addr);
+#endif
+
+ /* Count the number off-len pairs from reqs[], so we can malloc a
+ * contiguous memory space for storing off-len pairs
+ */
+ for (i=0; i<num_reqs; i++) {
+ is_recvar = IS_RECVAR(reqs[i].varp);
+
+ /* for record variable, each reqs[] is within a record */
+ ndims = (is_recvar) ? reqs[i].varp->ndims - 1 : reqs[i].varp->ndims;
+ count = (is_recvar) ? reqs[i].count + 1 : reqs[i].count;
+ stride = NULL;
+ if (reqs[i].stride != NULL)
+ stride = (is_recvar) ? reqs[i].stride + 1 : reqs[i].stride;
+
+ if (ndims < 0) continue;
+ if (ndims == 0) { /* 1D record variable */
+ (*nsegs)++;
+ continue;
+ }
+ nseg = 1;
+ if (stride != NULL && stride[ndims-1] > 1)
+ nseg = count[ndims-1]; /* count of last dimension */
+ for (j=0; j<ndims-1; j++)
+ nseg *= count[j]; /* all count[] except the last dimension */
+
+ *nsegs += nseg;
+ }
+
+ /* now we can allocate a contiguous memory space for the off-len pairs */
+ off_len *seg_ptr = (off_len*) NCI_Malloc((size_t)(*nsegs) * sizeof(off_len));
+ *segs = seg_ptr;
+
+ /* now re-run the loop to fill in the off-len pairs */
+ for (i=0; i<num_reqs; i++) {
+ /* buf_addr is the buffer address of the first valid request */
+#ifdef HAVE_MPI_GET_ADDRESS
+ MPI_Get_address(reqs[i].xbuf, &addr);
+#else
+ MPI_Address(reqs[i].xbuf, &addr);
+#endif
+ addr -= buf_addr, /* distance to the buf of first req */
+
+ is_recvar = IS_RECVAR(reqs[i].varp);
+
+ /* for record variable, each reqs[] is within a record */
+ ndims = (is_recvar) ? reqs[i].varp->ndims - 1 : reqs[i].varp->ndims;
+ start = (is_recvar) ? reqs[i].start + 1 : reqs[i].start;
+ count = (is_recvar) ? reqs[i].count + 1 : reqs[i].count;
+ shape = (is_recvar) ? reqs[i].varp->shape + 1 : reqs[i].varp->shape;
+ stride = NULL;
+ if (reqs[i].stride != NULL)
+ stride = (is_recvar) ? reqs[i].stride + 1 : reqs[i].stride;
+
+ /* find the starting file offset for this record */
+ MPI_Offset var_begin = reqs[i].varp->begin;
+ if (is_recvar) var_begin += reqs[i].start[0] * ncp->recsize;
+
+ /* flatten each request to a list of offset-length pairs */
+ ncmpii_flatten(ndims, reqs[i].varp->xsz, shape, var_begin,
+ addr, start, count, stride,
+ &nseg, /* OUT: number of offset-length pairs */
+ seg_ptr); /* OUT: array of offset-length pairs */
+ seg_ptr += nseg; /* append the list to the end of segs array */
+ }
+
+ /* check if (*segs)[].off are in an increasing order */
+ for (i=1; i<*nsegs; i++) {
+ if ((*segs)[i-1].off > (*segs)[i].off)
+ break;
+ }
+ if (i < *nsegs) /* not in an increasing order */
+ /* sort the off-len array, segs[], in an increasing order */
+ qsort(*segs, (size_t)(*nsegs), sizeof(off_len), off_compare);
+
+ /* merge the overlapped requests, skip the overlapped regions for those
+ * requests with higher j indices (i.e. requests with lower j indices
+ * win the writes to the overlapped regions)
+ */
+ for (i=0, j=1; j<*nsegs; j++) {
+ if ((*segs)[i].off + (*segs)[i].len >= (*segs)[j].off + (*segs)[j].len)
+ /* segment i completely covers segment j, skip j */
+ continue;
+
+ MPI_Offset gap = (*segs)[i].off + (*segs)[i].len - (*segs)[j].off;
+ if (gap >= 0) { /* segments i and j overlaps */
+ if ((*segs)[i].buf_addr + (*segs)[i].len ==
+ (*segs)[j].buf_addr + gap) {
+ /* buffers i and j are contiguous, merge j to i */
+ (*segs)[i].len += (*segs)[j].len - gap;
+ }
+ else { /* buffers are not contiguous, reduce j's len */
+ (*segs)[i+1].off = (*segs)[j].off + gap;
+ (*segs)[i+1].len = (*segs)[j].len - gap;
+ (*segs)[i+1].buf_addr = (*segs)[j].buf_addr + gap;
+ i++;
+ }
+ }
+ else { /* i and j do not overlap */
+ i++;
+ if (i < j) (*segs)[i] = (*segs)[j];
+ }
+ }
+
+ /* update number of segments, now all off-len pairs are not overlapped */
+ *nsegs = i+1;
+
+ return status;
+}
+
+/*----< ncmpii_construct_off_len_type() >-------------------------------------*/
+static int
+ncmpii_construct_off_len_type(MPI_Offset nsegs, /* no. off-len pairs */
+ off_len *segs, /* [nsegs] off-en pairs */
+ MPI_Datatype *filetype,
+ MPI_Datatype *buf_type)
+{
+ int i, j, mpireturn, *blocklengths;
+ MPI_Aint *displacements;
+ MPI_Offset next_off, next_len;
+
+ assert(nsegs > 0);
+
+ /* create the file view MPI derived data type by concatenating the sorted
+ offset-length pairs */
+
+ /* For filetype, the segs[].off can be further coalesced. For example,
+ * when writing a consecutive columns of a 2D array, even though the I/O
+ * buffer addresses may not be able to coalesced, the file offsets on
+ * the same row can be coalesced. Thus, first calculate the length of
+ * coalesced off-len pairs (the memory space needed for malloc)
+ */
+ next_off = segs[0].off;
+ next_len = segs[0].len;
+ for (j=0,i=1; i<nsegs; i++) {
+ if (next_off + next_len == segs[i].off) /* j and i are contiguous */
+ next_len += segs[i].len;
+ else {
+ j++;
+ next_off = segs[i].off;
+ next_len = segs[i].len;
+ }
+ }
+ /* j+1 is the coalesced length */
+ blocklengths = (int*) NCI_Malloc((size_t)(j+1) * SIZEOF_INT);
+ displacements = (MPI_Aint*) NCI_Malloc((size_t)(j+1) * SIZEOF_MPI_AINT);
+
+ /* coalesce segs[].off and len to dispalcements[] and blocklengths[] */
+ if (segs[0].len != (int)segs[0].len) DEBUG_RETURN_ERROR(NC_EINTOVERFLOW)
+ displacements[0] = segs[0].off;
+ blocklengths[0] = (int)segs[0].len;
+ for (j=0,i=1; i<nsegs; i++) {
+ if (segs[i].len != (int)segs[i].len) DEBUG_RETURN_ERROR(NC_EINTOVERFLOW)
+ if (displacements[j] + blocklengths[j] == segs[i].off)
+ /* j and i are contiguous */
+ blocklengths[j] += (int)segs[i].len;
+ /* TODO: take care of 4-byte int overflow problem */
+ else {
+ j++;
+ displacements[j] = segs[i].off;
+ blocklengths[j] = (int)segs[i].len;
+ }
+ }
+ /* j+1 is the coalesced length */
+
+#ifdef HAVE_MPI_TYPE_CREATE_HINDEXED
+ mpireturn = MPI_Type_create_hindexed(j+1, blocklengths, displacements,
+ MPI_BYTE, filetype);
+#else
+ mpireturn = MPI_Type_hindexed(j+1, blocklengths, displacements, MPI_BYTE,
+ filetype);
+#endif
+ if (mpireturn != MPI_SUCCESS) {
+ *filetype = MPI_BYTE;
+ *buf_type = MPI_BYTE;
+ NCI_Free(displacements);
+ NCI_Free(blocklengths);
+ return ncmpii_handle_error(mpireturn, "MPI_Type_create_hindexed");
+ }
+ MPI_Type_commit(filetype);
+ NCI_Free(displacements);
+ NCI_Free(blocklengths);
+
+ /* create the I/O buffer derived data type from the I/O buffer's
+ offset-length pairs */
+
+ /* Although it is unlikely buffers can be coalesced, it will not harm to
+ check it out */
+ next_off = segs[0].buf_addr;
+ next_len = segs[0].len;
+ for (j=0,i=1; i<nsegs; i++) {
+ if (next_off + next_len == segs[i].buf_addr)
+ /* j and i are contiguous */
+ next_len += segs[i].len;
+ else {
+ j++;
+ next_off = segs[i].buf_addr;
+ next_len = segs[i].len;
+ }
+ }
+ /* j+1 is the coalesced length */
+ blocklengths = (int*) NCI_Malloc((size_t)(j+1) * SIZEOF_INT);
+ displacements = (MPI_Aint*) NCI_Malloc((size_t)(j+1) * SIZEOF_MPI_AINT);
+
+ /* coalesce segs[].off and len to dispalcements[] and blocklengths[] */
+ if (segs[0].len != (int)segs[0].len) DEBUG_RETURN_ERROR(NC_EINTOVERFLOW)
+ displacements[0] = segs[0].buf_addr;
+ blocklengths[0] = (int)segs[0].len;
+ for (j=0,i=1; i<nsegs; i++) {
+ if (segs[i].len != (int)segs[i].len) DEBUG_RETURN_ERROR(NC_EINTOVERFLOW)
+ if (displacements[j] + blocklengths[j] == segs[i].buf_addr)
+ /* j and i are contiguous */
+ blocklengths[j] += (int)segs[i].len;
+ else {
+ j++;
+ displacements[j] = segs[i].buf_addr;
+ blocklengths[j] = (int)segs[i].len;
+ }
+ }
+ /* j+1 is the coalesced length */
+#ifdef HAVE_MPI_TYPE_CREATE_HINDEXED
+ mpireturn = MPI_Type_create_hindexed(j+1, blocklengths, displacements,
+ MPI_BYTE, buf_type);
+#else
+ mpireturn = MPI_Type_hindexed(j+1, blocklengths, displacements, MPI_BYTE,
+ buf_type);
+#endif
+ if (mpireturn != MPI_SUCCESS) {
+ if (*filetype != MPI_BYTE) MPI_Type_free(filetype);
+ *filetype = MPI_BYTE;
+ *buf_type = MPI_BYTE;
+ NCI_Free(displacements);
+ NCI_Free(blocklengths);
+ return ncmpii_handle_error(mpireturn, "MPI_Type_create_hindexed");
+ }
+ MPI_Type_commit(buf_type);
+ NCI_Free(displacements);
+ NCI_Free(blocklengths);
+
+ return NC_NOERR;
+}
+
+/*----< req_compare() >-------------------------------------------------------*/
+/* used to sort the the string file offsets of reqs[] */
+static int
+req_compare(const void *a, const void *b)
+{
+ if (((NC_req*)a)->offset_start > ((NC_req*)b)->offset_start) return (1);
+ if (((NC_req*)a)->offset_start < ((NC_req*)b)->offset_start) return (-1);
+ return (0);
+}
+
+/*----< ncmpii_req_aggregation() >--------------------------------------------*/
+/* aggregate multiple read/write (non-contiguous) requests and call MPI-IO
+ */
+static int
+ncmpii_req_aggregation(NC *ncp,
+ int num_reqs, /* # requests */
+ NC_req *reqs, /* sorted requests */
+ int rw_flag, /* WRITE_REQ or READ_REQ */
+ int io_method, /* COLL_IO or INDEP_IO */
+ int interleaved) /* interleaved in reqs[] */
+{
+ int i, type, err, status=NC_NOERR, ngroups;
+ int *group_index, *group_type;
+
+ if (num_reqs == 0) { /* only COLL_IO can reach here for 0 request */
+ assert(io_method == COLL_IO);
+ /* simply participate the collective call */
+ return ncmpii_getput_zero_req(ncp, rw_flag);
+ }
+ if (! interleaved) {
+ /* concatenate all filetypes into a single one and do I/O */
+ return ncmpii_mgetput(ncp, num_reqs, reqs, rw_flag, io_method);
+ }
+ /* now some request's aggregate access region is interleaved with other's */
+
+ /* divide the requests into groups.
+ * Two types of groups: one contains requests that all are not interleaved
+ * and the other contains requests that any 2 consecutive requests are
+ * interleaved. All requests will be aggregated into one and carried out
+ * by a single MPI-IO call.
+ * This approach is because MPI collective I/O requires each process's
+ * fileview must contain only monotonic non-decreasing file offsets. Thus
+ * if the nonblocking requests interleave with each other (although not
+ * overlapp), then we cannot simply concatenate the filetypes of individual
+ * requests. This approach flattens the requests of "interleaved" groups
+ * into offset-length pairs, sorts, and merges them into an aggregated
+ * filetype. Similar for building an aggregated I/O buffer type.
+ */
+
+ /* first calculate the number of groups, so group_index and group_type can
+ be malloc-ed. Group type: 0 for non-interleaved group and 1 for
+ interleaved group.
+ */
+ ngroups = 1;
+ type = (reqs[0].offset_end > reqs[1].offset_start) ? 1 : 0;
+ for (i=1; i<num_reqs-1; i++) {
+ if (type == 0 && reqs[i].offset_end > reqs[i+1].offset_start) {
+ ngroups++;
+ type = 1;
+ }
+ else if (type == 1 && reqs[i].offset_end <= reqs[i+1].offset_start) {
+ type = 0;
+ if (i+2 < num_reqs && reqs[i+1].offset_end > reqs[i+2].offset_start)
+ type = 1; /* next group is also interleaved */
+ ngroups++;
+ }
+ }
+
+ group_index = (int*) NCI_Malloc((size_t)(ngroups+1) * SIZEOF_INT);
+ group_type = (int*) NCI_Malloc((size_t)(ngroups+1) * SIZEOF_INT);
+
+ /* calculate the starting index of each group and determine group type */
+ ngroups = 1;
+ type = (reqs[0].offset_end > reqs[1].offset_start) ? 1 : 0;
+ group_index[0] = 0;
+ group_type[0] = type;
+ for (i=1; i<num_reqs-1; i++) {
+ if (type == 0 &&
+ reqs[i].offset_end > reqs[i+1].offset_start) {
+ /* reqs[i] starts an interleaved group */
+ group_index[ngroups] = i;
+ type = 1;
+ group_type[ngroups] = type;
+ ngroups++;
+ }
+ else if (type == 1 &&
+ reqs[i].offset_end <= reqs[i+1].offset_start) {
+ /* the interleaved group ends with reqs[i] */
+ group_index[ngroups] = i+1;
+ type = 0;
+ if (i+2 < num_reqs && reqs[i+1].offset_end > reqs[i+2].offset_start)
+ type = 1; /* next group is also interleaved */
+ group_type[ngroups] = type;
+ ngroups++;
+ }
+ }
+ group_index[ngroups] = num_reqs; /* to indicate end of groups */
+
+ /* for each group, construct one filetype by concatenating if the group
+ * is non-interleaved and by flatten/sort/merge if the group is
+ * interleaved. At the end, all ngroups filetypes are concatenated into
+ * a single filetype. Similar for constructing buffer types.
+ * Then use one collective I/O to commit.
+ */
+
+ void *buf; /* point to starting buffer, used by MPI-IO call */
+ int *f_blocklengths, *b_blocklengths;
+ MPI_Aint b_begin, b_addr, *f_disps, *b_disps;
+ MPI_Datatype filetype, buf_type, *ftypes, *btypes;
+
+ ftypes = (MPI_Datatype*) NCI_Malloc((size_t)ngroups*2*sizeof(MPI_Datatype));
+ btypes = ftypes + ngroups;
+ f_blocklengths = (int*) NCI_Malloc((size_t)ngroups*2*SIZEOF_INT);
+ b_blocklengths = f_blocklengths + ngroups;
+ f_disps = (MPI_Aint*) NCI_Malloc((size_t)ngroups*2*SIZEOF_MPI_AINT);
+ b_disps = f_disps + ngroups;
+
+ buf = reqs[0].xbuf; /* the buffer of 1st request */
+ b_disps[0] = 0; /* relative to address of 1st buf */
+#ifdef HAVE_MPI_GET_ADDRESS
+ MPI_Get_address(buf, &b_begin);
+#else
+ MPI_Address(buf, &b_begin);
+#endif
+
+ /* for each group, build a filetype and a buffer type in ftypes[i] and
+ btypes[i] */
+ for (i=0; i<ngroups; i++) {
+ NC_req *g_reqs = reqs + group_index[i];
+ int g_num_reqs = group_index[i+1] - group_index[i];
+ f_disps[i] = 0; /* file displacements always to the file offset 0 */
+
+ if (group_type[i] == 0) {
+ /* This group contains no interleaved filetypes, so we can
+ * simply concatenate filetypes of this group into a single one
+ */
+ err = ncmpii_construct_filetypes(ncp, g_num_reqs, g_reqs, rw_flag,
+ &ftypes[i]);
+ if (status == NC_NOERR) status = err;
+ if (err != NC_NOERR) { /* skip this group */
+ ftypes[i] = btypes[i] = MPI_BYTE;
+ f_blocklengths[i] = 0;
+ continue;
+ }
+ f_blocklengths[i] = 1;
+
+ /* concatenate buffer types of this group into a single one */
+ err = ncmpii_construct_buffertypes(g_num_reqs, g_reqs, &btypes[i]);
+ if (status == NC_NOERR) status = err;
+ if (err != NC_NOERR) { /* skip this group */
+ ftypes[i] = btypes[i] = MPI_BYTE;
+ b_blocklengths[i] = 0;
+ f_blocklengths[i] = 0;
+ continue;
+ }
+ }
+ else { /* this group is interleaved */
+ /* flatten the interleaved requests in this group, so interleaved
+ * requests can be sorted and merged into a monotonically
+ * non-decreasing filetype. For example, multiple nonblocking
+ * requests each accessing a single column of a 2D array, that each
+ * produces a filetype interleaving with others'.
+ *
+ * The pitfall of this flattening is the additional memory
+ * requirement, as it will have to break down each request into a
+ * list of offset-length pairs, and merge all lists into a sorted
+ * list based on their offsets into an increasing order.
+ *
+ * Be warned! The additional memory requirement for this merging can
+ * be more than the I/O data itself. For example, each nonblocking
+ * request access a single column of a 2D array of 4-byte integer
+ * type. Each off-len pair represents only a 4-byte integer, but the
+ * off-len pair itself takes 24 bytes. Additional memory is also
+ * required for MPI arguments of displacements and blocklengths.
+ */
+ MPI_Offset nsegs=0; /* number of merged offset-length pairs */
+ off_len *segs=NULL; /* array of the offset-length pairs */
+ void *merged_buf;
+
+ /* merge all requests into sorted offset-length pairs */
+ err = ncmpii_merge_requests(ncp, g_num_reqs, g_reqs, &merged_buf,
+ &nsegs, &segs);
+ if (status == NC_NOERR) status = err;
+ if (err != NC_NOERR) { /* skip this group */
+ ftypes[i] = btypes[i] = MPI_BYTE;
+ b_blocklengths[i] = 0;
+ f_blocklengths[i] = 0;
+ if (segs != NULL) NCI_Free(segs);
+ continue;
+ }
+ assert(nsegs > 0);
+
+ /* sges[] will be used to construct fileview and buffer type */
+ err = ncmpii_construct_off_len_type(nsegs, segs, &ftypes[i],
+ &btypes[i]);
+ /* preserve the previous error if there is any */
+ if (status == NC_NOERR) status = err;
+ NCI_Free(segs);
+ if (err != NC_NOERR) { /* skip this group */
+ ftypes[i] = btypes[i] = MPI_BYTE;
+ b_blocklengths[i] = 0;
+ f_blocklengths[i] = 0;
+ continue;
+ }
+ f_blocklengths[i] = 1;
+ }
+
+ if (i > 0) {
+ /* get the buffer address of the first request in this group */
+#ifdef HAVE_MPI_GET_ADDRESS
+ MPI_Get_address(g_reqs[0].xbuf, &b_addr);
+#else
+ MPI_Address(g_reqs[0].xbuf, &b_addr);
+#endif
+ b_disps[i] = b_addr - b_begin; /* to 1st buffer of 1st group*/
+ }
+ b_blocklengths[i] = 1;
+ }
+ NCI_Free(group_index);
+ NCI_Free(group_type);
+
+ int mpireturn, buf_len=1;
+
+ if (ngroups == 1) {
+ /* use ftypes[0] and btypes[0] directly */
+ filetype = ftypes[0];
+ buf_type = btypes[0];
+ }
+ else {
+ /* concatenate all ftypes[] to filetype */
+#ifdef HAVE_MPI_TYPE_CREATE_STRUCT
+ mpireturn = MPI_Type_create_struct(ngroups, f_blocklengths, f_disps,
+ ftypes, &filetype);
+#else
+ mpireturn = MPI_Type_struct(ngroups, f_blocklengths, f_disps, ftypes,
+ &filetype);
+#endif
+ if (mpireturn != MPI_SUCCESS) {
+ err = ncmpii_handle_error(mpireturn, "MPI_Type_create_struct");
+ /* return the first encountered error if there is any */
+ if (status == NC_NOERR) status = err;
+
+ buf_len = 0; /* skip this request */
+ filetype = MPI_BYTE;
+ }
+ else
+ MPI_Type_commit(&filetype);
+
+ for (i=0; i<ngroups; i++) {
+ if (ftypes[i] != MPI_BYTE) MPI_Type_free(&ftypes[i]);
+ }
+
+ /* concatenate all btypes[] to buf_type */
+#ifdef HAVE_MPI_TYPE_CREATE_STRUCT
+ mpireturn = MPI_Type_create_struct(ngroups, b_blocklengths, b_disps,
+ btypes, &buf_type);
+#else
+ mpireturn = MPI_Type_struct(ngroups, b_blocklengths, b_disps, btypes,
+ &buf_type);
+#endif
+ if (mpireturn != MPI_SUCCESS) {
+ err = ncmpii_handle_error(mpireturn, "MPI_Type_create_struct");
+ /* return the first encountered error if there is any */
+ if (status == NC_NOERR) status = err;
+
+ buf_len = 0; /* skip this request */
+ buf_type = MPI_BYTE;
+ }
+ else
+ MPI_Type_commit(&buf_type);
+
+ for (i=0; i<ngroups; i++) {
+ if (btypes[i] != MPI_BYTE) MPI_Type_free(&btypes[i]);
+ }
+ }
+
+ MPI_File fh;
+ MPI_Status mpistatus;
+
+ if (io_method == COLL_IO)
+ fh = ncp->nciop->collective_fh;
+ else
+ fh = ncp->nciop->independent_fh;
+
+ /* set the file view */
+ MPI_Offset offset=0;
+ err = ncmpii_file_set_view(ncp, fh, &offset, filetype);
+ if (err != NC_NOERR) {
+ buf_len = 0; /* skip this request */
+ if (status == NC_NOERR) status = err;
+ }
+
+ if (rw_flag == READ_REQ) {
+ if (io_method == COLL_IO) {
+ TRACE_IO(MPI_File_read_at_all)(fh, offset, buf, buf_len, buf_type,
+ &mpistatus);
+ if (mpireturn != MPI_SUCCESS) {
+ err = ncmpii_handle_error(mpireturn, "MPI_File_read_at_all");
+ /* return the first encountered error if there is any */
+ if (status == NC_NOERR) {
+ status = (err == NC_EFILE) ? NC_EREAD : err;
+ DEBUG_ASSIGN_ERROR(status, status)
+ }
+ }
+ } else {
+ TRACE_IO(MPI_File_read_at)(fh, offset, buf, buf_len, buf_type,
+ &mpistatus);
+ if (mpireturn != MPI_SUCCESS) {
+ err = ncmpii_handle_error(mpireturn, "MPI_File_read_at");
+ /* return the first encountered error if there is any */
+ if (status == NC_NOERR) {
+ status = (err == NC_EFILE) ? NC_EREAD : err;
+ DEBUG_ASSIGN_ERROR(status, status)
+ }
+ }
+ }
+ if (mpireturn == MPI_SUCCESS) {
+ int get_size;
+ MPI_Get_count(&mpistatus, MPI_BYTE, &get_size);
+ ncp->nciop->get_size += get_size;
+ }
+ } else { /* WRITE_REQ */
+ if (io_method == COLL_IO) {
+ TRACE_IO(MPI_File_write_at_all)(fh, offset, buf, buf_len, buf_type,
+ &mpistatus);
+ if (mpireturn != MPI_SUCCESS) {
+ err = ncmpii_handle_error(mpireturn, "MPI_File_write_at_all");
+ /* return the first encountered error if there is any */
+ if (status == NC_NOERR) {
+ status = (err == NC_EFILE) ? NC_EWRITE : err;
+ DEBUG_ASSIGN_ERROR(status, status)
+ }
+ }
+ } else {
+ TRACE_IO(MPI_File_write_at)(fh, offset, buf, buf_len, buf_type,
+ &mpistatus);
+ if (mpireturn != MPI_SUCCESS) {
+ err = ncmpii_handle_error(mpireturn, "MPI_File_write_at");
+ /* return the first encountered error if there is any */
+ if (status == NC_NOERR) {
+ status = (err == NC_EFILE) ? NC_EWRITE : err;
+ DEBUG_ASSIGN_ERROR(status, status)
+ }
+ }
+ }
+ if (mpireturn == MPI_SUCCESS) {
+ int put_size;
+ MPI_Get_count(&mpistatus, MPI_BYTE, &put_size);
+ ncp->nciop->put_size += put_size;
+ }
+ }
+
+ if (filetype != MPI_BYTE) MPI_Type_free(&filetype);
+ if (buf_type != MPI_BYTE) MPI_Type_free(&buf_type);
+
+ /* No longer need to reset the file view, as the root's fileview includes
+ * the whole file header.
+ TRACE_IO(MPI_File_set_view)(fh, 0, MPI_BYTE, MPI_BYTE, "native",
+ MPI_INFO_NULL);
+ */
+
+ NCI_Free(ftypes);
+ NCI_Free(f_blocklengths);
+ NCI_Free(f_disps);
+
+ return status;
+}
+
+/*----< ncmpii_wait_getput() >------------------------------------------------*/
+static int
+ncmpii_wait_getput(NC *ncp,
+ int num_reqs, /* # requests including subrequests */
+ NC_req *req_head, /* linked list not include subrequests */
+ int rw_flag, /* WRITE_REQ or READ_REQ */
+ int io_method) /* COLL_IO or INDEP_IO */
+{
+ int i, j, err, status=NC_NOERR, access_interleaved=0;
+ NC_req *reqs, *cur_req;
+
+ /* pack the requests and sub-requests from the linked list into an array,
+ * so they can be sorted */
+ reqs = (NC_req*) NCI_Malloc((size_t)num_reqs * sizeof(NC_req));
+ i = 0;
+ cur_req = req_head;
+ while (cur_req != NULL) {
+ if (cur_req->num_subreqs == 0)
+ reqs[i++] = *cur_req;
+ else {
+ for (j=0; j<cur_req->num_subreqs; j++)
+ reqs[i++] = cur_req->subreqs[j];
+ }
+ cur_req = cur_req->next;
+ }
+
+#ifndef _DISALLOW_POST_NONBLOCKING_API_IN_DEFINE_MODE
+ /* move the offset calculation from posting API calls (pack_request) to
+ * wait call, such that posting a nonblocking request can be done in
+ * define mode
+ */
+ for (i=0; i<num_reqs; i++) {
+ /* get the starting file offset for this request */
+ ncmpii_get_offset(ncp, reqs[i].varp, reqs[i].start, NULL, NULL,
+ reqs[i].rw_flag, &reqs[i].offset_start);
+
+ /* get the ending file offset for this request */
+ ncmpii_get_offset(ncp, reqs[i].varp, reqs[i].start, reqs[i].count,
+ reqs[i].stride, reqs[i].rw_flag, &reqs[i].offset_end);
+ reqs[i].offset_end += reqs[i].varp->xsz - 1;
+ }
+#endif
+
+ /* check if reqs[].offset_start are in an increasing order */
+ for (i=1; i<num_reqs; i++) {
+ if (reqs[i-1].offset_start > reqs[i].offset_start) {
+ break;
+ }
+ }
+ if (i < num_reqs) /* a non-increasing order is found */
+ /* sort reqs[] based on reqs[].offset_start */
+ qsort(reqs, (size_t)num_reqs, sizeof(NC_req), req_compare);
+
+ /* check for any interleaved requests */
+ for (i=1; i<num_reqs; i++) {
+ if (reqs[i-1].offset_end > reqs[i].offset_start) {
+ access_interleaved = 1;
+ break;
+ }
+ }
+
+ /* aggregate requests and carry out the I/O */
+ err = ncmpii_req_aggregation(ncp, num_reqs, reqs, rw_flag, io_method,
+ access_interleaved);
+ if (status == NC_NOERR) status = err;
+
+ /* Update the number of records if new records have been created.
+ * For nonblocking APIs, there is no way for a process to know whether
+ * others write to a record variable or not. Hence, we must sync the
+ * number of records for write request
+ */
+ if (rw_flag == WRITE_REQ) {
+ /* Because netCDF allows only one unlimited dimension, find the
+ * maximum number of records from all nonblocking requests and
+ * update newnumrecs once
+ */
+ MPI_Offset newnumrecs = ncp->numrecs;
+ for (i=0; i<num_reqs; i++) {
+ if (!IS_RECVAR(reqs[i].varp)) continue; /* not a record var */
+ if (reqs[i].bnelems == 0) continue; /* 0-len or invalid request */
+
+ newnumrecs = MAX(newnumrecs, reqs[i].start[0] + reqs[i].count[0]);
+ }
+
+ if (io_method == COLL_IO) {
+ /* sync numrecs in memory and file. Note that even this process
+ * does not write to record variable, others might. Note in
+ * ncmpii_sync_numrecs(), new_numrecs is checked against
+ * ncp->numrecs and if NC_SHARE is set, MPI_File_sync() will
+ * be called.
+ */
+ err = ncmpii_sync_numrecs(ncp, newnumrecs);
+ if (status == NC_NOERR) status = err;
+ /* retain the first error if there is any */
+ }
+ else { /* INDEP_IO */
+ if (ncp->numrecs < newnumrecs) {
+ ncp->numrecs = newnumrecs;
+ set_NC_ndirty(ncp);
+ /* delay numrecs sync until end_indep, redef or close */
+ }
+ }
+
+ if (NC_doFsync(ncp)) { /* NC_SHARE is set */
+ int mpireturn;
+ if (io_method == INDEP_IO) {
+ TRACE_IO(MPI_File_sync)(ncp->nciop->independent_fh);
+ if (mpireturn != MPI_SUCCESS) {
+ err = ncmpii_handle_error(mpireturn, "MPI_File_sync");
+ if (status == NC_NOERR) status = err;
+ }
+ }
+ else {
+ TRACE_IO(MPI_File_sync)(ncp->nciop->collective_fh);
+ if (mpireturn != MPI_SUCCESS) {
+ err = ncmpii_handle_error(mpireturn, "MPI_File_sync");
+ if (status == NC_NOERR) status = err;
+ }
+ TRACE_COMM(MPI_Barrier)(ncp->nciop->comm);
+ }
+ }
+ }
+
+ if (reqs != NULL) NCI_Free(reqs);
+
+ return status;
+}
+
+/*----< ncmpii_mgetput() >----------------------------------------------------*/
+/* Before reaching to this subroutine, all the filetypes in the request array
+ * are sorted in a non-decreasing order and not interleaved. This subroutine
+ * concatenates the filetypes into a single fileview and calls MPI-IO function.
+ * This subroutine also concatenates user buffertypes into a single derived
+ * data type to be used in the MPI read/write function call.
+ */
+static int
+ncmpii_mgetput(NC *ncp,
+ int num_reqs,
+ NC_req *reqs, /* [num_reqs] */
+ int rw_flag, /* WRITE_REQ or READ_REQ */
+ int io_method) /* COLL_IO or INDEP_IO */
+{
+ int i, j, len=0, status=NC_NOERR, mpireturn, err;
+ void *buf=NULL;
+ MPI_Status mpistatus;
+ MPI_Datatype filetype, buf_type=MPI_BYTE;
+ MPI_File fh;
+
+ if (io_method == COLL_IO)
+ fh = ncp->nciop->collective_fh;
+ else
+ fh = ncp->nciop->independent_fh;
+
+ /* construct a MPI file type by concatenating fileviews of all requests */
+ status = ncmpii_construct_filetypes(ncp,num_reqs, reqs, rw_flag, &filetype);
+ if (status != NC_NOERR) { /* if failed, skip this request */
+ if (io_method == INDEP_IO) return status;
+
+ /* For collective I/O, we still need to participate the successive
+ collective calls: setview/read/write */
+ num_reqs = 0;
+ filetype = MPI_BYTE;
+ }
+
+ /* set the MPI-IO fileview */
+ MPI_Offset offset=0;
+ err = ncmpii_file_set_view(ncp, fh, &offset, filetype);
+ if (err != NC_NOERR) {
+ num_reqs = 0; /* skip this request */
+ if (status == NC_NOERR) status = err;
+ }
+
+ if (filetype != MPI_BYTE) MPI_Type_free(&filetype);
+
+ /* now construct buffer datatype */
+ if (num_reqs == 0) {
+ /* num_reqs == 0, simply participate the collective call */
+ buf = NULL;
+ len = 0;
+ }
+ else if (num_reqs == 1) {
+ MPI_Offset int8 = reqs[0].bnelems * reqs[0].varp->xsz;
+ len = (int)int8;
+ if (int8 != len) {
+ if (status == NC_NOERR) DEBUG_ASSIGN_ERROR(status, NC_EINTOVERFLOW)
+ len = 0; /* skip this request */
+ }
+ buf = reqs[0].xbuf;
+ }
+ else if (num_reqs > 1) { /* create the I/O buffer derived data type */
+ int *blocklengths = (int*) NCI_Malloc((size_t)num_reqs * SIZEOF_INT);
+ MPI_Aint *disps = (MPI_Aint*) NCI_Malloc((size_t)num_reqs*SIZEOF_MPI_AINT);
+ MPI_Aint a0=0, ai, a_last_contig;
+
+ int last_contig_req = 0; /* index of the last contiguous request */
+ buf = NULL;
+ /* process only valid requests */
+ for (i=0, j=0; i<num_reqs; i++) {
+ /* check int overflow */
+ MPI_Offset int8 = reqs[i].bnelems * reqs[i].varp->xsz;
+ blocklengths[j] = (int)int8;
+ if (int8 != blocklengths[j]) { /* int overflow */
+ if (status == NC_NOERR) DEBUG_ASSIGN_ERROR(status, NC_EINTOVERFLOW)
+ blocklengths[j] = 0;
+ continue; /* skip this request */
+ }
+#ifdef HAVE_MPI_GET_ADDRESS
+ MPI_Get_address(reqs[i].xbuf, &ai);
+#else
+ MPI_Address(reqs[i].xbuf, &ai);
+#endif
+ if (j == 0) { /* first valid request */
+ a_last_contig = a0 = ai;
+ buf = reqs[i].xbuf;
+ }
+ disps[j] = ai - a0;
+
+ if (ai - a_last_contig == blocklengths[last_contig_req])
+ /* user buffer of request j is contiguous from j-1
+ * we coalesce j to j-1 */
+ blocklengths[last_contig_req] += blocklengths[j];
+ else if (j > 0) {
+ /* not contiguous from request last_contig_req */
+ last_contig_req++;
+ a_last_contig = ai;
+ disps[last_contig_req] = ai - a0;
+ blocklengths[last_contig_req] = blocklengths[i];
+ }
+ j++;
+ }
+
+ /* last_contig_req is the index of last contiguous request */
+ if (last_contig_req == 0) {
+ /* user buffers can be concatenated into a contiguous buffer */
+ buf_type = MPI_BYTE;
+ len = blocklengths[0];
+ }
+ else {
+ /* after possible concatenating the user buffers, the true number
+ * of non-contiguous buffers is last_contig_req+1 */
+ num_reqs = last_contig_req+1;
+
+ /* concatenate buffer addresses into a single buffer type */
+#ifdef HAVE_MPI_TYPE_CREATE_HINDEXED
+ mpireturn = MPI_Type_create_hindexed(num_reqs, blocklengths, disps,
+ MPI_BYTE, &buf_type);
+#else
+ mpireturn = MPI_Type_hindexed(num_reqs, blocklengths, disps,
+ MPI_BYTE, &buf_type);
+#endif
+ if (mpireturn != MPI_SUCCESS) {
+ err = ncmpii_handle_error(mpireturn,"MPI_Type_create_hindexed");
+ /* return the first encountered error if there is any */
+ if (status == NC_NOERR) status = err;
+ }
+ else
+ mpireturn = MPI_Type_commit(&buf_type);
+
+ len = 1;
+ }
+ NCI_Free(disps);
+ NCI_Free(blocklengths);
+ }
+ /* if (buf_type == MPI_BYTE) then the whole buf is contiguous */
+
+ if (rw_flag == READ_REQ) {
+ if (io_method == COLL_IO) {
+ TRACE_IO(MPI_File_read_at_all)(fh, offset, buf, len, buf_type,
+ &mpistatus);
+ if (mpireturn != MPI_SUCCESS) {
+ err = ncmpii_handle_error(mpireturn, "MPI_File_read_at_all");
+ /* return the first encountered error if there is any */
+ if (status == NC_NOERR) {
+ status = (err == NC_EFILE) ? NC_EREAD : err;
+ DEBUG_ASSIGN_ERROR(status, status)
+ }
+ }
+ } else {
+ TRACE_IO(MPI_File_read_at)(fh, offset, buf, len, buf_type,
+ &mpistatus);
+ if (mpireturn != MPI_SUCCESS) {
+ err = ncmpii_handle_error(mpireturn, "MPI_File_read_at");
+ /* return the first encountered error if there is any */
+ if (status == NC_NOERR) {
+ status = (err == NC_EFILE) ? NC_EREAD : err;
+ DEBUG_ASSIGN_ERROR(status, status)
+ }
+ }
+ }
+ /* update the number of bytes read since file open */
+ int get_size;
+ MPI_Get_count(&mpistatus, MPI_BYTE, &get_size);
+ ncp->nciop->get_size += get_size;
+
+ } else { /* WRITE_REQ */
+ if (io_method == COLL_IO) {
+ TRACE_IO(MPI_File_write_at_all)(fh, offset, buf, len, buf_type,
+ &mpistatus);
+ if (mpireturn != MPI_SUCCESS) {
+ err = ncmpii_handle_error(mpireturn, "MPI_File_write_at_all");
+ /* return the first encountered error if there is any */
+ if (status == NC_NOERR) {
+ status = (err == NC_EFILE) ? NC_EWRITE : err;
+ DEBUG_ASSIGN_ERROR(status, status)
+ }
+ }
+ } else {
+ TRACE_IO(MPI_File_write_at)(fh, offset, buf, len, buf_type,
+ &mpistatus);
+ if (mpireturn != MPI_SUCCESS) {
+ err = ncmpii_handle_error(mpireturn, "MPI_File_write_at");
+ /* return the first encountered error if there is any */
+ if (status == NC_NOERR) {
+ status = (err == NC_EFILE) ? NC_EWRITE : err;
+ DEBUG_ASSIGN_ERROR(status, status)
+ }
+ }
+ }
+ /* update the number of bytes written since file open */
+ int put_size;
+ MPI_Get_count(&mpistatus, MPI_BYTE, &put_size);
+ ncp->nciop->put_size += put_size;
+ }
+
+ if (buf_type != MPI_BYTE) /* free user buffer type */
+ mpireturn = MPI_Type_free(&buf_type);
+
+ /* No longer need to reset the file view, as the root's fileview includes
+ * the whole file header.
+ TRACE_IO(MPI_File_set_view)(fh, 0, MPI_BYTE, MPI_BYTE, "native",
+ MPI_INFO_NULL);
+ */
+
+ return status;
+}
+
+/*----< ncmpii_set_iget_callback() >-----------------------------------------*/
+/* this subroutine is only used by iget_varn API family and when its buftype
+ * argument indicated a noncontiguous data type. In this case, tmpBuf is never
+ * == userBuf
+ *
+ * iget_varn() divides userBuf into pieces, each is used in an iget_varm() and
+ * stored in a cur_req->buf. We cannot unpack each req->buf individually, as
+ * req->buf may need to type converted. So at the end of wait(), we unpack the
+ * entire tmpBuf into userBuf.
+ */
+int ncmpii_set_iget_callback(NC *ncp,
+ int reqid,
+ void *tmpBuf,
+ void *userBuf,
+ int userBufCount,
+ MPI_Datatype userBufType)
+{
+ NC_req *cur_req;
+
+ if (reqid == NC_REQ_NULL) return NC_NOERR;
+
+ if (ncp->head == NULL) DEBUG_RETURN_ERROR(NC_EINVAL_REQUEST)
+
+ cur_req = ncp->head;
+ while (cur_req != NULL) {
+ /* find the first linked-list node with reqid, there may be more than
+ * one node with the same request ID
+ */
+ if (cur_req->id == reqid) {
+ MPI_Datatype dup_buftype;
+ MPI_Type_dup(userBufType, &dup_buftype);
+
+ cur_req->tmpBuf = tmpBuf;
+ /* When not NULL, tmpBuf is an internal buffer allocated
+ * in iget_varn(). At the end of nonblocking wait call,
+ * tmpBuf will be unpacked to userBuf and freed.
+ */
+ cur_req->userBuf = userBuf;
+ /* User's buffer. iget_varn() divides userBuf into pieces,
+ * each is used in an iget_varm() and stored in a
+ * cur_req->buf.
+ */
+ cur_req->bufcount = userBufCount;
+ cur_req->buftype = dup_buftype;
+ break;
+ }
+ cur_req = cur_req->next;
+ }
+ if (cur_req == NULL) DEBUG_RETURN_ERROR(NC_EINVAL_REQUEST)
+
+ return NC_NOERR;
+}
+
+/*----< ncmpii_set_iput_callback() >-----------------------------------------*/
+/* this subroutine is only used by iput_varn API family, to tell wait() to
+ * free the temporary buffer at the end.
+ */
+int ncmpii_set_iput_callback(NC *ncp,
+ int reqid,
+ void *tmpPutBuf)
+{
+ int found_req_id=NC_REQ_NULL;
+ NC_req *cur_req;
+
+ if (reqid == NC_REQ_NULL) return NC_NOERR;
+
+ if (ncp->head == NULL) DEBUG_RETURN_ERROR(NC_EINVAL_REQUEST)
+
+ cur_req = ncp->head;
+ while (cur_req != NULL) {
+ /* there may be more than one linked-list node with the same ID */
+ if (cur_req->id == reqid) {
+ /* set tmpBuf only on the first node, so it is freed just once */
+ if (found_req_id == NC_REQ_NULL) cur_req->tmpBuf = tmpPutBuf;
+ found_req_id = reqid;
+ }
+ if (found_req_id != NC_REQ_NULL && cur_req->id != found_req_id)
+ break; /* requests with same ID are in consecutive linked nodes */
+ cur_req = cur_req->next;
+ }
+ if (found_req_id == NC_REQ_NULL) DEBUG_RETURN_ERROR(NC_EINVAL_REQUEST)
+
+ return NC_NOERR;
+}
diff --git a/src/lib/pnetcdf.h.in b/src/lib/pnetcdf.h.in
new file mode 100644
index 0000000..eaaa3c6
--- /dev/null
+++ b/src/lib/pnetcdf.h.in
@@ -0,0 +1,3906 @@
+/*
+ * Copyright (C) 2003, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ */
+/* $Id: pnetcdf.h.in 2290 2016-01-02 18:37:46Z wkliao $ */
+
+#ifndef _PNETCDF_
+#define _PNETCDF_
+
+#include <mpi.h>
+
+#ifndef PNETCDF_VERSION_MAJOR
+#define PNETCDF_VERSION_MAJOR @PNETCDF_VERSION_MAJOR@
+#define PNETCDF_VERSION_MINOR @PNETCDF_VERSION_MINOR@
+#define PNETCDF_VERSION_SUB @PNETCDF_VERSION_SUB@
+#endif
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/* NetCDF data types and their corresponding external types in C convention
+ * and type names used in PnetCDF APIs:
+ NC_BYTE : signed char (for _schar APIs)
+ NC_CHAR : unsigned char (for _text APIs)
+ NC_SHORT : signed short int (for _short APIs)
+ NC_INT : signed int (for _int APIs)
+ NC_FLOAT : float (for _float APIs)
+ NC_DOUBLE : double (for _double APIs)
+ NC_UBYTE : unsigned char (for _ubyte and
+ _uchar APIs)
+ NC_USHORT : unsigned short int (for _ushort APIs)
+ NC_UINT : unsigned int (for _uint APIs)
+ NC_INT64 : signed long long (for _longlong APIs)
+ NC_UINT64 : unsigned long long (for _ulonglong APIs)
+ */
+
+/* to make PnetCDF error codes compatible to netCDF, below we keep an exact
+ * same copy of netcdf.h and re-use their defined values
+ * Sync-ed with netcdf.h of version 4.4.0-rc5
+ */
+#ifndef _NETCDF_
+
+/*! The nc_type type is just an int. */
+typedef int nc_type;
+
+/*
+ * The netcdf external data types
+ */
+#define NC_NAT 0 /**< Not A Type */
+#define NC_BYTE 1 /**< signed 1 byte integer */
+#define NC_CHAR 2 /**< ISO/ASCII character */
+#define NC_SHORT 3 /**< signed 2 byte integer */
+#define NC_INT 4 /**< signed 4 byte integer */
+#define NC_LONG NC_INT /**< deprecated, but required for backward compatibility. */
+#define NC_FLOAT 5 /**< single precision floating point number */
+#define NC_DOUBLE 6 /**< double precision floating point number */
+#define NC_UBYTE 7 /**< unsigned 1 byte int */
+#define NC_USHORT 8 /**< unsigned 2-byte int */
+#define NC_UINT 9 /**< unsigned 4-byte int */
+#define NC_INT64 10 /**< signed 8-byte int */
+#define NC_UINT64 11 /**< unsigned 8-byte int */
+#define NC_STRING 12 /**< string */
+
+#define NC_MAX_ATOMIC_TYPE NC_STRING
+
+/* The following are use internally in support of user-defines
+ * types. They are also the class returned by nc_inq_user_type. */
+#define NC_VLEN 13 /**< vlen (variable-length) types */
+#define NC_OPAQUE 14 /**< opaque types */
+#define NC_ENUM 15 /**< enum types */
+#define NC_COMPOUND 16 /**< compound types */
+
+/* Define the first user defined type id (leave some room) */
+#define NC_FIRSTUSERTYPEID 32
+
+/** Default fill value. This is used unless _FillValue attribute
+ * is set. These values are stuffed into newly allocated space as
+ * appropriate. The hope is that one might use these to notice that a
+ * particular datum has not been set. */
+/**@{*/
+#define NC_FILL_BYTE ((signed char)-127)
+#define NC_FILL_CHAR ((char)0)
+#define NC_FILL_SHORT ((short)-32767)
+#define NC_FILL_INT (-2147483647L)
+#define NC_FILL_FLOAT (9.9692099683868690e+36f) /* near 15 * 2^119 */
+#define NC_FILL_DOUBLE (9.9692099683868690e+36)
+#define NC_FILL_UBYTE (255)
+#define NC_FILL_USHORT (65535)
+#define NC_FILL_UINT (4294967295U)
+#define NC_FILL_INT64 ((long long)-9223372036854775806LL)
+#define NC_FILL_UINT64 ((unsigned long long)18446744073709551614ULL)
+#define NC_FILL_STRING ((char *)"")
+/**@}*/
+
+/*! Max or min values for a type. Nothing greater/smaller can be
+ * stored in a netCDF file for their associated types. Recall that a C
+ * compiler may define int to be any length it wants, but a NC_INT is
+ * *always* a 4 byte signed int. On a platform with 64 bit ints,
+ * there will be many ints which are outside the range supported by
+ * NC_INT. But since NC_INT is an external format, it has to mean the
+ * same thing everywhere. */
+/**@{*/
+#define NC_MAX_BYTE 127
+#define NC_MIN_BYTE (-NC_MAX_BYTE-1)
+#define NC_MAX_CHAR 255
+#define NC_MAX_SHORT 32767
+#define NC_MIN_SHORT (-NC_MAX_SHORT - 1)
+#define NC_MAX_INT 2147483647
+#define NC_MIN_INT (-NC_MAX_INT - 1)
+#define NC_MAX_FLOAT 3.402823466e+38f
+#define NC_MIN_FLOAT (-NC_MAX_FLOAT)
+#define NC_MAX_DOUBLE 1.7976931348623157e+308
+#define NC_MIN_DOUBLE (-NC_MAX_DOUBLE)
+#define NC_MAX_UBYTE NC_MAX_CHAR
+#define NC_MAX_USHORT 65535U
+#define NC_MAX_UINT 4294967295U
+#define NC_MAX_INT64 (9223372036854775807LL)
+#define NC_MIN_INT64 (-9223372036854775807LL-1)
+#define NC_MAX_UINT64 (18446744073709551615ULL)
+#define X_INT64_MAX (9223372036854775807LL)
+#define X_INT64_MIN (-X_INT64_MAX - 1)
+#define X_UINT64_MAX (18446744073709551615ULL)
+/**@}*/
+
+/** Name of fill value attribute. If you wish a variable to use a
+ * different value than the above defaults, create an attribute with
+ * the same type as the variable and this reserved name. The value you
+ * give the attribute will be used as the fill value for that
+ * variable. */
+#define _FillValue "_FillValue"
+#define NC_FILL 0 /**< Argument to nc_set_fill() to clear NC_NOFILL */
+#define NC_NOFILL 0x100 /**< Argument to nc_set_fill() to turn off filling of data. */
+
+/* Define the ioflags bits for nc_create and nc_open.
+ currently unused:
+ 0x0002
+ 0x0040
+ 0x0080
+ and the whole upper 16 bits
+*/
+
+#define NC_NOWRITE 0x0000 /**< Set read-only access for nc_open(). */
+#define NC_WRITE 0x0001 /**< Set read-write access for nc_open(). */
+#define NC_CLOBBER 0x0000 /**< Destroy existing file. Mode flag for nc_create(). */
+#define NC_NOCLOBBER 0x0004 /**< Don't destroy existing file. Mode flag for nc_create(). */
+
+#define NC_DISKLESS 0x0008 /**< Use diskless file. Mode flag for nc_open() or nc_create(). */
+#define NC_MMAP 0x0010 /**< Use diskless file with mmap. Mode flag for nc_open() or nc_create(). */
+
+#define NC_64BIT_DATA 0x0020 /**< CDF-5 format: classic model but 64 bit dimensions and sizes */
+#define NC_CDF5 NC_64BIT_DATA /**< Alias NC_CDF5 to NC_64BIT_DATA */
+
+#define NC_CLASSIC_MODEL 0x0100 /**< Enforce classic model on netCDF-4. Mode flag for nc_create(). */
+#define NC_64BIT_OFFSET 0x0200 /**< Use large (64-bit) file offsets. Mode flag for nc_create(). */
+
+/** \deprecated The following flag currently is ignored, but use in
+ * nc_open() or nc_create() may someday support use of advisory
+ * locking to prevent multiple writers from clobbering a file
+ */
+#define NC_LOCK 0x0400
+
+/** Share updates, limit caching.
+Use this in mode flags for both nc_create() and nc_open(). */
+#define NC_SHARE 0x0800
+
+#define NC_NETCDF4 0x1000 /**< Use netCDF-4/HDF5 format. Mode flag for nc_create(). */
+
+/** Turn on MPI I/O.
+Use this in mode flags for both nc_create() and nc_open(). */
+#define NC_MPIIO 0x2000
+/** Turn on MPI POSIX I/O.
+Use this in mode flags for both nc_create() and nc_open(). */
+#define NC_MPIPOSIX 0x4000 /**< \deprecated As of libhdf5 1.8.13. */
+
+#define NC_INMEMORY 0x8000 /**< Read from memory. Mode flag for nc_open() or nc_create(). */
+
+#define NC_PNETCDF (NC_MPIIO) /**< Use parallel-netcdf library; alias for NC_MPIIO. */
+
+/** Format specifier for nc_set_default_format() and returned
+ * by nc_inq_format. This returns the format as provided by
+ * the API. See nc_inq_format_extended to see the true file format.
+ * Starting with version 3.6, there are different format netCDF files.
+ * 4.0 introduces the third one. \see netcdf_format
+ */
+/**@{*/
+#define NC_FORMAT_CLASSIC (1)
+/* After adding CDF5 support, this flag
+ is somewhat confusing. So, it is renamed.
+ Note that the name in the contributed code
+ NC_FORMAT_64BIT was renamed to NC_FORMAT_CDF2
+*/
+#define NC_FORMAT_64BIT_OFFSET (2)
+#define NC_FORMAT_64BIT (NC_FORMAT_64BIT_OFFSET) /**< \deprecated Saved for compatibility. Use NC_FORMAT_64BIT_OFFSET or NC_FORMAT_64BIT_DATA, from netCDF 4.4.0 onwards. */
+#define NC_FORMAT_NETCDF4 (3)
+#define NC_FORMAT_NETCDF4_CLASSIC (4)
+#define NC_FORMAT_64BIT_DATA (5)
+
+/* Alias */
+#define NC_FORMAT_CDF5 NC_FORMAT_64BIT_DATA
+
+/**@}*/
+
+/** Extended format specifier returned by nc_inq_format_extended()
+ * Added in version 4.3.1. This returns the true format of the
+ * underlying data.
+ * The function returns two values
+ * 1. a small integer indicating the underlying source type
+ * of the data. Note that this may differ from what the user
+ * sees from nc_inq_format() because this latter function
+ * returns what the user can expect to see thru the API.
+ * 2. A mode value indicating what mode flags are effectively
+ * set for this dataset. This usually will be a superset
+ * of the mode flags used as the argument to nc_open
+ * or nc_create.
+ * More or less, the #1 values track the set of dispatch tables.
+ * The #1 values are as follows.
+ * Note that CDF-5 returns NC_FORMAT_NC3, but sets the mode flag properly.
+ */
+/**@{*/
+
+#define NC_FORMATX_NC3 (1)
+#define NC_FORMATX_NC_HDF5 (2) /**< netCDF-4 subset of HDF5 */
+#define NC_FORMATX_NC4 NC_FORMATX_NC_HDF5 /**< alias */
+#define NC_FORMATX_NC_HDF4 (3) /**< netCDF-4 subset of HDF4 */
+#define NC_FORMATX_PNETCDF (4)
+#define NC_FORMATX_DAP2 (5)
+#define NC_FORMATX_DAP4 (6)
+#define NC_FORMATX_UNDEFINED (0)
+
+ /* To avoid breaking compatibility (such as in the python library),
+ we need to retain the NC_FORMAT_xxx format as well. This may come
+ out eventually, as the NC_FORMATX is more clear that it's an extended
+ format specifier.*/
+
+#define NC_FORMAT_NC3 NC_FORMATX_NC3 /**< \deprecated As of 4.4.0, use NC_FORMATX_NC3 */
+#define NC_FORMAT_NC_HDF5 NC_FORMATX_NC_HDF5 /**< \deprecated As of 4.4.0, use NC_FORMATX_NC_HDF5 */
+#define NC_FORMAT_NC4 NC_FORMATX_NC4 /**< \deprecated As of 4.4.0, use NC_FORMATX_NC4 */
+#define NC_FORMAT_NC_HDF4 NC_FORMATX_NC_HDF4 /**< \deprecated As of 4.4.0, use NC_FORMATX_HDF4 */
+#define NC_FORMAT_PNETCDF NC_FORMATX_PNETCDF /**< \deprecated As of 4.4.0, use NC_FORMATX_PNETCDF */
+#define NC_FORMAT_DAP2 NC_FORMATX_DAP2 /**< \deprecated As of 4.4.0, use NC_FORMATX_DAP2 */
+#define NC_FORMAT_DAP4 NC_FORMATX_DAP4 /**< \deprecated As of 4.4.0, use NC_FORMATX_DAP4 */
+#define NC_FORMAT_UNDEFINED NC_FORMATX_UNDEFINED /**< \deprecated As of 4.4.0, use NC_FORMATX_UNDEFINED */
+
+/**@}*/
+
+/** Let nc__create() or nc__open() figure out a suitable buffer size. */
+#define NC_SIZEHINT_DEFAULT 0
+
+/** In nc__enddef(), align to the buffer size. */
+#define NC_ALIGN_CHUNK ((size_t)(-1))
+
+/** Size argument to nc_def_dim() for an unlimited dimension. */
+#define NC_UNLIMITED 0L
+
+/** Attribute id to put/get a global attribute. */
+#define NC_GLOBAL -1
+
+/**
+Maximum for classic library.
+
+In the classic netCDF model there are maximum values for the number of
+dimensions in the file (\ref NC_MAX_DIMS), the number of global or per
+variable attributes (\ref NC_MAX_ATTRS), the number of variables in
+the file (\ref NC_MAX_VARS), and the length of a name (\ref
+NC_MAX_NAME).
+
+These maximums are enforced by the interface, to facilitate writing
+applications and utilities. However, nothing is statically allocated
+to these sizes internally.
+
+These maximums are not used for netCDF-4/HDF5 files unless they were
+created with the ::NC_CLASSIC_MODEL flag.
+
+As a rule, NC_MAX_VAR_DIMS <= NC_MAX_DIMS.
+*/
+/**@{*/
+#define NC_MAX_DIMS 1024
+#define NC_MAX_ATTRS 8192
+#define NC_MAX_VARS 8192
+#define NC_MAX_NAME 256
+#define NC_MAX_VAR_DIMS 1024 /**< max per variable dimensions */
+/**@}*/
+
+/** This is the max size of an SD dataset name in HDF4 (from HDF4 documentation).*/
+#define NC_MAX_HDF4_NAME 64
+
+/** In HDF5 files you can set the endianness of variables with
+ nc_def_var_endian(). This define is used there. */
+/**@{*/
+#define NC_ENDIAN_NATIVE 0
+#define NC_ENDIAN_LITTLE 1
+#define NC_ENDIAN_BIG 2
+/**@}*/
+
+/** In HDF5 files you can set storage for each variable to be either
+ * contiguous or chunked, with nc_def_var_chunking(). This define is
+ * used there. */
+/**@{*/
+#define NC_CHUNKED 0
+#define NC_CONTIGUOUS 1
+/**@}*/
+
+/** In HDF5 files you can set check-summing for each variable.
+Currently the only checksum available is Fletcher-32, which can be set
+with the function nc_def_var_fletcher32. These defines are used
+there. */
+/**@{*/
+#define NC_NOCHECKSUM 0
+#define NC_FLETCHER32 1
+/**@}*/
+
+/**@{*/
+/** Control the HDF5 shuffle filter. In HDF5 files you can specify
+ * that a shuffle filter should be used on each chunk of a variable to
+ * improve compression for that variable. This per-variable shuffle
+ * property can be set with the function nc_def_var_deflate(). */
+#define NC_NOSHUFFLE 0
+#define NC_SHUFFLE 1
+/**@}*/
+
+/** The netcdf version 3 functions all return integer error status.
+ * These are the possible values, in addition to certain values from
+ * the system errno.h.
+ */
+#define NC_ISSYSERR(err) ((err) > 0)
+
+#define NC_NOERR 0 /**< No Error */
+#define NC2_ERR (-1) /**< Returned for all errors in the v2 API. */
+
+/** Not a netcdf id.
+
+The specified netCDF ID does not refer to an
+open netCDF dataset. */
+#define NC_EBADID (-33)
+#define NC_ENFILE (-34) /**< Too many netcdfs open */
+#define NC_EEXIST (-35) /**< netcdf file exists && NC_NOCLOBBER */
+#define NC_EINVAL (-36) /**< Invalid Argument */
+#define NC_EPERM (-37) /**< Write to read only */
+
+/** Operation not allowed in data mode. This is returned for netCDF
+classic or 64-bit offset files, or for netCDF-4 files, when they were
+been created with ::NC_CLASSIC_MODEL flag in nc_create(). */
+#define NC_ENOTINDEFINE (-38)
+
+/** Operation not allowed in define mode.
+
+The specified netCDF is in define mode rather than data mode.
+
+With netCDF-4/HDF5 files, this error will not occur, unless
+::NC_CLASSIC_MODEL was used in nc_create().
+ */
+#define NC_EINDEFINE (-39)
+
+/** Index exceeds dimension bound.
+
+The specified corner indices were out of range for the rank of the
+specified variable. For example, a negative index or an index that is
+larger than the corresponding dimension length will cause an error. */
+#define NC_EINVALCOORDS (-40)
+
+/** NC_MAX_DIMS exceeded. Max number of dimensions exceeded in a
+classic or 64-bit offset file, or an netCDF-4 file with
+::NC_CLASSIC_MODEL on. */
+#define NC_EMAXDIMS (-41)
+
+#define NC_ENAMEINUSE (-42) /**< String match to name in use */
+#define NC_ENOTATT (-43) /**< Attribute not found */
+#define NC_EMAXATTS (-44) /**< NC_MAX_ATTRS exceeded */
+#define NC_EBADTYPE (-45) /**< Not a netcdf data type */
+#define NC_EBADDIM (-46) /**< Invalid dimension id or name */
+#define NC_EUNLIMPOS (-47) /**< NC_UNLIMITED in the wrong index */
+
+/** NC_MAX_VARS exceeded. Max number of variables exceeded in a
+classic or 64-bit offset file, or an netCDF-4 file with
+::NC_CLASSIC_MODEL on. */
+#define NC_EMAXVARS (-48)
+
+/** Variable not found.
+
+The variable ID is invalid for the specified netCDF dataset. */
+#define NC_ENOTVAR (-49)
+#define NC_EGLOBAL (-50) /**< Action prohibited on NC_GLOBAL varid */
+#define NC_ENOTNC (-51) /**< Not a netcdf file */
+#define NC_ESTS (-52) /**< In Fortran, string too short */
+#define NC_EMAXNAME (-53) /**< NC_MAX_NAME exceeded */
+#define NC_EUNLIMIT (-54) /**< NC_UNLIMITED size already in use */
+#define NC_ENORECVARS (-55) /**< nc_rec op when there are no record vars */
+#define NC_ECHAR (-56) /**< Attempt to convert between text & numbers */
+
+/** Start+count exceeds dimension bound.
+
+The specified edge lengths added to the specified corner would have
+referenced data out of range for the rank of the specified
+variable. For example, an edge length that is larger than the
+corresponding dimension length minus the corner index will cause an
+error. */
+#define NC_EEDGE (-57)
+#define NC_ESTRIDE (-58) /**< Illegal stride */
+#define NC_EBADNAME (-59) /**< Attribute or variable name contains illegal characters */
+/* N.B. following must match value in ncx.h */
+
+/** Math result not representable.
+
+One or more of the values are out of the range of values representable
+by the desired type. */
+#define NC_ERANGE (-60)
+#define NC_ENOMEM (-61) /**< Memory allocation (malloc) failure */
+#define NC_EVARSIZE (-62) /**< One or more variable sizes violate format constraints */
+#define NC_EDIMSIZE (-63) /**< Invalid dimension size */
+#define NC_ETRUNC (-64) /**< File likely truncated or possibly corrupted */
+#define NC_EAXISTYPE (-65) /**< Unknown axis type. */
+
+/* Following errors are added for DAP */
+#define NC_EDAP (-66) /**< Generic DAP error */
+#define NC_ECURL (-67) /**< Generic libcurl error */
+#define NC_EIO (-68) /**< Generic IO error */
+#define NC_ENODATA (-69) /**< Attempt to access variable with no data */
+#define NC_EDAPSVC (-70) /**< DAP server error */
+#define NC_EDAS (-71) /**< Malformed or inaccessible DAS */
+#define NC_EDDS (-72) /**< Malformed or inaccessible DDS */
+#define NC_EDATADDS (-73) /**< Malformed or inaccessible DATADDS */
+#define NC_EDAPURL (-74) /**< Malformed DAP URL */
+#define NC_EDAPCONSTRAINT (-75) /**< Malformed DAP Constraint*/
+#define NC_ETRANSLATION (-76) /**< Untranslatable construct */
+#define NC_EACCESS (-77) /**< Access Failure */
+#define NC_EAUTH (-78) /**< Authorization Failure */
+
+/* Misc. additional errors */
+#define NC_ENOTFOUND (-90) /**< No such file */
+#define NC_ECANTREMOVE (-91) /**< Can't remove file */
+
+/* The following was added in support of netcdf-4. Make all netcdf-4
+ error codes < -100 so that errors can be added to netcdf-3 if
+ needed. */
+#define NC4_FIRST_ERROR (-100)
+
+/** Error at HDF5 layer. */
+#define NC_EHDFERR (-101)
+#define NC_ECANTREAD (-102) /**< Can't read. */
+#define NC_ECANTWRITE (-103) /**< Can't write. */
+#define NC_ECANTCREATE (-104) /**< Can't create. */
+#define NC_EFILEMETA (-105) /**< Problem with file metadata. */
+#define NC_EDIMMETA (-106) /**< Problem with dimension metadata. */
+#define NC_EATTMETA (-107) /**< Problem with attribute metadata. */
+#define NC_EVARMETA (-108) /**< Problem with variable metadata. */
+#define NC_ENOCOMPOUND (-109) /**< Not a compound type. */
+#define NC_EATTEXISTS (-110) /**< Attribute already exists. */
+#define NC_ENOTNC4 (-111) /**< Attempting netcdf-4 operation on netcdf-3 file. */
+
+/** Attempting netcdf-4 operation on strict nc3 netcdf-4 file. */
+#define NC_ESTRICTNC3 (-112)
+#define NC_ENOTNC3 (-113) /**< Attempting netcdf-3 operation on netcdf-4 file. */
+#define NC_ENOPAR (-114) /**< Parallel operation on file opened for non-parallel access. */
+#define NC_EPARINIT (-115) /**< Error initializing for parallel access. */
+#define NC_EBADGRPID (-116) /**< Bad group ID. */
+#define NC_EBADTYPID (-117) /**< Bad type ID. */
+#define NC_ETYPDEFINED (-118) /**< Type has already been defined and may not be edited. */
+#define NC_EBADFIELD (-119) /**< Bad field ID. */
+#define NC_EBADCLASS (-120) /**< Bad class. */
+#define NC_EMAPTYPE (-121) /**< Mapped access for atomic types only. */
+#define NC_ELATEFILL (-122) /**< Attempt to define fill value when data already exists. */
+#define NC_ELATEDEF (-123) /**< Attempt to define var properties, like deflate, after enddef. */
+#define NC_EDIMSCALE (-124) /**< Problem with HDF5 dimscales. */
+#define NC_ENOGRP (-125) /**< No group found. */
+#define NC_ESTORAGE (-126) /**< Can't specify both contiguous and chunking. */
+#define NC_EBADCHUNK (-127) /**< Bad chunksize. */
+#define NC_ENOTBUILT (-128) /**< Attempt to use feature that was not turned on when netCDF was built. */
+#define NC_EDISKLESS (-129) /**< Error in using diskless access. */
+#define NC_ECANTEXTEND (-130) /**< Attempt to extend dataset during ind. I/O operation. */
+#define NC_EMPI (-131) /**< MPI operation failed. */
+
+#define NC4_LAST_ERROR (-131)
+
+/* This is used in netCDF-4 files for dimensions without coordinate
+ * vars. */
+#define DIM_WITHOUT_VARIABLE "This is a netCDF dimension but not a netCDF variable."
+
+/* This is here at the request of the NCO team to support our
+ * mistake of having chunksizes be first ints, then size_t. Doh! */
+#define NC_HAVE_NEW_CHUNKING_API 1
+
+
+/*Errors for all remote access methods(e.g. DAP and CDMREMOTE)*/
+#define NC_EURL (NC_EDAPURL) /* Malformed URL */
+#define NC_ECONSTRAINT (NC_EDAPCONSTRAINT) /* Malformed Constraint*/
+
+#endif
+/* end of #ifndef _NETCDF_ */
+
+/* now some definitions used in PnetCDF only */
+
+#define NC_FORMAT_UNKNOWN -1
+
+/* CDF version 1, NC_32BIT is used internally and never
+ actually passed in to ncmpi_create */
+#define NC_32BIT 0x1000000
+
+/* CDF-5 format, (64-bit) supported */
+#ifndef NC_64BIT_DATA
+#define NC_64BIT_DATA 0x0020
+#endif
+
+/* CDF-2 format, with NC_64BIT_OFFSET. */
+#ifndef NC_FORMAT_CDF2
+#define NC_FORMAT_CDF2 2
+#endif
+
+/* CDF-5 format, with NC_64BIT_DATA. */
+#ifndef NC_FORMAT_CDF5
+#define NC_FORMAT_CDF5 5
+#endif
+
+/* PnetCDF Error Codes: */
+#define NC_ESMALL (-201) /**< size of MPI_Offset too small for format */
+#define NC_ENOTINDEP (-202) /**< Operation not allowed in collective data mode */
+#define NC_EINDEP (-203) /**< Operation not allowed in independent data mode */
+#define NC_EFILE (-204) /**< Unknown error in file operation */
+#define NC_EREAD (-205) /**< Unknown error in reading file */
+#define NC_EWRITE (-206) /**< Unknown error in writing to file */
+#define NC_EOFILE (-207) /**< file open/creation failed */
+#define NC_EMULTITYPES (-208) /**< Multiple types used in memory data */
+#define NC_EIOMISMATCH (-209) /**< Input/Output data amount mismatch */
+#define NC_ENEGATIVECNT (-210) /**< Negative count is specified */
+#define NC_EUNSPTETYPE (-211) /**< Unsupported etype in memory MPI datatype */
+#define NC_EINVAL_REQUEST (-212) /**< invalid nonblocking request ID */
+#define NC_EAINT_TOO_SMALL (-213) /**< MPI_Aint not large enough to hold requested value */
+#define NC_ENOTSUPPORT (-214) /**< feature is not yet supported */
+#define NC_ENULLBUF (-215) /**< trying to attach a NULL buffer */
+#define NC_EPREVATTACHBUF (-216) /**< previous attached buffer is found */
+#define NC_ENULLABUF (-217) /**< no attached buffer is found */
+#define NC_EPENDINGBPUT (-218) /**< pending bput is found, cannot detach buffer */
+#define NC_EINSUFFBUF (-219) /**< attached buffer is too small */
+#define NC_ENOENT (-220) /**< File does not exist */
+#define NC_EINTOVERFLOW (-221) /**< Overflow when type cast to 4-byte integer */
+#define NC_ENOTENABLED (-222) /**< feature is not enabled */
+#define NC_EBAD_FILE (-223) /**< Invalid file name (e.g., path name too long) */
+#define NC_ENO_SPACE (-224) /**< Not enough space */
+#define NC_EQUOTA (-225) /**< Quota exceeded */
+#define NC_ENULLSTART (-226) /**< argument start is a NULL pointer */
+#define NC_ENULLCOUNT (-227) /**< argument count is a NULL pointer */
+#define NC_EINVAL_CMODE (-228) /**< Invalid file create mode, cannot have both NC_64BIT_OFFSET & NC_64BIT_DATA */
+#define NC_ETYPESIZE (-229) /**< MPI derived data type size error (bigger than the variable size) */
+#define NC_ETYPE_MISMATCH (-230) /**< element type of the MPI derived data type mismatches the variable type */
+#define NC_ETYPESIZE_MISMATCH (-231) /**< file type size mismatches buffer type size */
+#define NC_ESTRICTCDF2 (-232) /**< Attempting CDF-5 operation on CDF-2 file */
+#define NC_ENOTRECVAR (-233) /**< Attempting operation only for record variables */
+#define NC_ENOTFILL (-234) /**< Attempting to fill a variable when its fill mode is off */
+/* add new error here */
+
+/* header inconsistency errors start from -250 */
+#define NC_EMULTIDEFINE (-250) /**< NC definitions on multiprocesses conflict */
+#define NC_EMULTIDEFINE_OMODE (-251) /**< create/open mode are inconsistent across processes */
+#define NC_EMULTIDEFINE_DIM_NUM (-252) /**< inconsistent number of dimensions */
+#define NC_EMULTIDEFINE_DIM_SIZE (-253) /**< inconsistent size of dimension */
+#define NC_EMULTIDEFINE_DIM_NAME (-254) /**< inconsistent dimension names */
+#define NC_EMULTIDEFINE_VAR_NUM (-255) /**< inconsistent number of variables */
+#define NC_EMULTIDEFINE_VAR_NAME (-256) /**< inconsistent variable name */
+#define NC_EMULTIDEFINE_VAR_NDIMS (-257) /**< inconsistent variable's number of dimensions */
+#define NC_EMULTIDEFINE_VAR_DIMIDS (-258) /**< inconsistent variable's dimid */
+#define NC_EMULTIDEFINE_VAR_TYPE (-259) /**< inconsistent variable's data type */
+#define NC_EMULTIDEFINE_VAR_LEN (-260) /**< inconsistent variable's size */
+#define NC_EMULTIDEFINE_NUMRECS (-261) /**< inconsistent number of records */
+#define NC_EMULTIDEFINE_VAR_BEGIN (-262) /**< inconsistent variable file begin offset (internal use) */
+#define NC_EMULTIDEFINE_ATTR_NUM (-263) /**< inconsistent number of attributes */
+#define NC_EMULTIDEFINE_ATTR_SIZE (-264) /**< inconsistent memory space used by attribute (internal use) */
+#define NC_EMULTIDEFINE_ATTR_NAME (-265) /**< inconsistent attribute name */
+#define NC_EMULTIDEFINE_ATTR_TYPE (-266) /**< inconsistent attribute type */
+#define NC_EMULTIDEFINE_ATTR_LEN (-267) /**< inconsistent attribute length */
+#define NC_EMULTIDEFINE_ATTR_VAL (-268) /**< inconsistent attribute value */
+#define NC_EMULTIDEFINE_FNC_ARGS (-269) /**< inconsistent function arguments used in collective API */
+#define NC_EMULTIDEFINE_FILL_MODE (-270) /**< inconsistent dataset fill mode */
+#define NC_EMULTIDEFINE_VAR_FILL_MODE (-271) /**< inconsistent variable fill mode */
+#define NC_EMULTIDEFINE_VAR_FILL_VALUE (-272) /**< inconsistent variable fill value */
+
+#define NC_EMULTIDEFINE_FIRST NC_EMULTIDEFINE
+#define NC_EMULTIDEFINE_LAST NC_EMULTIDEFINE_FNC_ARGS
+
+/* backward compatible with PnetCDF 1.3.1 and earlier */
+#define NC_ECMODE NC_EMULTIDEFINE_OMODE
+#define NC_EDIMS_NELEMS_MULTIDEFINE NC_EMULTIDEFINE_DIM_NUM
+#define NC_EDIMS_SIZE_MULTIDEFINE NC_EMULTIDEFINE_DIM_SIZE
+#define NC_EDIMS_NAME_MULTIDEFINE NC_EMULTIDEFINE_DIM_NAME
+#define NC_EVARS_NELEMS_MULTIDEFINE NC_EMULTIDEFINE_VAR_NUM
+#define NC_EVARS_NAME_MULTIDEFINE NC_EMULTIDEFINE_VAR_NAME
+#define NC_EVARS_NDIMS_MULTIDEFINE NC_EMULTIDEFINE_VAR_NDIMS
+#define NC_EVARS_DIMIDS_MULTIDEFINE NC_EMULTIDEFINE_VAR_DIMIDS
+#define NC_EVARS_TYPE_MULTIDEFINE NC_EMULTIDEFINE_VAR_TYPE
+#define NC_EVARS_LEN_MULTIDEFINE NC_EMULTIDEFINE_VAR_LEN
+#define NC_ENUMRECS_MULTIDEFINE NC_EMULTIDEFINE_NUMRECS
+#define NC_EVARS_BEGIN_MULTIDEFINE NC_EMULTIDEFINE_VAR_BEGIN
+
+/* invalid nonblocking request ID and zero-length request */
+#define NC_REQ_NULL -1
+
+/* indicate to flush all pending non-blocking requests */
+#define NC_REQ_ALL -1
+
+
+/*
+ * The Interface
+ */
+
+/* Begin Prototypes */
+
+const char* ncmpi_strerror(int err);
+
+/* Begin Dataset Functions */
+
+int ncmpi_create(MPI_Comm comm, const char *path, int cmode, MPI_Info info, int *ncidp);
+
+int ncmpi_open(MPI_Comm comm, const char *path, int omode, MPI_Info info, int *ncidp);
+
+int ncmpi_inq_file_info(int ncid, MPI_Info *info_used);
+int ncmpi_get_file_info(int ncid, MPI_Info *info_used);
+
+int ncmpi_delete(char *filename, MPI_Info info);
+
+int ncmpi_enddef(int ncid);
+
+int ncmpi__enddef(int ncid, MPI_Offset h_minfree, MPI_Offset v_align,
+ MPI_Offset v_minfree, MPI_Offset r_align);
+
+int ncmpi_redef(int ncid);
+
+int ncmpi_set_default_format(int format, int *old_formatp);
+
+int ncmpi_inq_default_format(int *formatp);
+
+int ncmpi_sync(int ncid);
+
+int ncmpi_sync_numrecs(int ncid);
+
+int ncmpi_abort(int ncid);
+
+int ncmpi_begin_indep_data(int ncid);
+
+int ncmpi_end_indep_data(int ncid);
+
+int ncmpi_close(int ncid);
+
+int ncmpi_set_fill(int ncid, int fillmode, int *old_modep);
+
+int ncmpi_def_var_fill(int ncid, int varid, int no_fill, void *fill_value);
+
+int ncmpi_inq_var_fill(int ncid, int varid, int *no_fill, void *fill_value);
+
+int ncmpi_fill_var_rec(int ncid, int varid, MPI_Offset recno);
+
+/* End Dataset Functions */
+
+/* Begin Define Mode Functions */
+
+int ncmpi_def_dim(int ncid, const char *name, MPI_Offset len, int *idp);
+
+int ncmpi_def_var(int ncid, const char *name, nc_type xtype,
+ int ndims, const int *dimidsp, int *varidp);
+
+int ncmpi_rename_dim(int ncid, int dimid, const char *name);
+
+int ncmpi_rename_var(int ncid, int varid, const char *name);
+
+/* End Define Mode Functions */
+
+/* Begin Inquiry Functions */
+
+const char* ncmpi_inq_libvers(void);
+
+int ncmpi_inq(int ncid, int *ndimsp, int *nvarsp,
+ int *ngattsp, int *unlimdimidp);
+
+int ncmpi_inq_format(int ncid, int *formatp);
+
+int ncmpi_inq_file_format(char *filename, int *formatp);
+
+int ncmpi_inq_version(int ncid, int *NC_mode);
+
+int ncmpi_inq_striping(int ncid, int *striping_size, int *striping_count);
+
+int ncmpi_inq_ndims(int ncid, int *ndimsp);
+
+int ncmpi_inq_nvars(int ncid, int *nvarsp);
+
+int ncmpi_inq_num_rec_vars(int ncid, int *nvarsp);
+
+int ncmpi_inq_num_fix_vars(int ncid, int *nvarsp);
+
+int ncmpi_inq_natts(int ncid, int *ngattsp);
+
+int ncmpi_inq_unlimdim(int ncid, int *unlimdimidp);
+
+int ncmpi_inq_dimid(int ncid, const char *name, int *idp);
+
+int ncmpi_inq_dim(int ncid, int dimid, char *name, MPI_Offset *lenp);
+
+int ncmpi_inq_dimname(int ncid, int dimid, char *name);
+
+int ncmpi_inq_dimlen(int ncid, int dimid, MPI_Offset *lenp);
+
+int ncmpi_inq_var(int ncid, int varid, char *name, nc_type *xtypep,
+ int *ndimsp, int *dimidsp, int *nattsp);
+
+int ncmpi_inq_varid(int ncid, const char *name, int *varidp);
+
+int ncmpi_inq_varname(int ncid, int varid, char *name);
+
+int ncmpi_inq_vartype(int ncid, int varid, nc_type *xtypep);
+
+int ncmpi_inq_varndims(int ncid, int varid, int *ndimsp);
+
+int ncmpi_inq_vardimid(int ncid, int varid, int *dimidsp);
+
+int ncmpi_inq_varnatts(int ncid, int varid, int *nattsp);
+
+int ncmpi_inq_varoffset(int ncid, int varid, MPI_Offset *offset);
+
+int ncmpi_inq_put_size(int ncid, MPI_Offset *size);
+
+int ncmpi_inq_get_size(int ncid, MPI_Offset *size);
+
+int ncmpi_inq_header_size(int ncid, MPI_Offset *size);
+
+int ncmpi_inq_header_extent(int ncid, MPI_Offset *extent);
+
+int ncmpi_inq_malloc_size(MPI_Offset *size);
+int ncmpi_inq_malloc_max_size(MPI_Offset *size);
+int ncmpi_inq_malloc_list(void);
+
+int ncmpi_inq_files_opened(int *num, int *ncids);
+
+int ncmpi_inq_recsize(int ncid, MPI_Offset *recsize);
+
+/* End Inquiry Functions */
+
+/* Begin _att */
+
+int ncmpi_inq_att(int ncid, int varid, const char *name,
+ nc_type *xtypep, MPI_Offset *lenp);
+
+int ncmpi_inq_attid(int ncid, int varid, const char *name, int *idp);
+
+int ncmpi_inq_atttype(int ncid, int varid, const char *name,
+ nc_type *xtypep);
+
+int ncmpi_inq_attlen(int ncid, int varid, const char *name,
+ MPI_Offset *lenp);
+
+int ncmpi_inq_attname(int ncid, int varid, int attnum, char *name);
+
+int ncmpi_copy_att(int ncid_in, int varid_in, const char *name,
+ int ncid_out, int varid_out);
+
+int ncmpi_rename_att(int ncid, int varid, const char *name,
+ const char *newname);
+
+int ncmpi_del_att(int ncid, int varid, const char *name);
+
+int ncmpi_put_att(int ncid, int varid, const char *name, nc_type xtype,
+ MPI_Offset nelems, const void *value);
+
+int ncmpi_put_att_text(int ncid, int varid, const char *name, MPI_Offset len,
+ const char *op);
+
+int ncmpi_put_att_schar(int ncid, int varid, const char *name,
+ nc_type xtype, MPI_Offset len, const signed char *op);
+
+int ncmpi_put_att_short(int ncid, int varid, const char *name,
+ nc_type xtype, MPI_Offset len, const short *op);
+
+int ncmpi_put_att_int(int ncid, int varid, const char *name,
+ nc_type xtype, MPI_Offset len, const int *op);
+
+int ncmpi_put_att_float(int ncid, int varid, const char *name,
+ nc_type xtype, MPI_Offset len, const float *op);
+
+int ncmpi_put_att_double(int ncid, int varid, const char *name,
+ nc_type xtype, MPI_Offset len, const double *op);
+
+int ncmpi_put_att_longlong(int ncid, int varid, const char *name,
+ nc_type xtype, MPI_Offset len, const long long *op);
+
+int ncmpi_get_att(int ncid, int varid, const char *name, void *value);
+
+int ncmpi_get_att_text(int ncid, int varid, const char *name, char *ip);
+
+int ncmpi_get_att_schar(int ncid, int varid, const char *name,
+ signed char *ip);
+
+int ncmpi_get_att_short(int ncid, int varid, const char *name, short *ip);
+
+int ncmpi_get_att_int(int ncid, int varid, const char *name, int *ip);
+
+int ncmpi_get_att_float(int ncid, int varid, const char *name, float *ip);
+
+int ncmpi_get_att_double(int ncid, int varid, const char *name, double *ip);
+
+int ncmpi_get_att_longlong(int ncid, int varid, const char *name, long long *ip);
+
+/* Begin Skip Prototypes for Fortran binding */
+/* skip types: uchar, ubyte, ushort, uint, long, ulonglong string */
+
+int ncmpi_put_att_uchar(int ncid, int varid, const char *name,
+ nc_type xtype, MPI_Offset len, const unsigned char *op);
+
+int ncmpi_put_att_ubyte(int ncid, int varid, const char *name,
+ nc_type xtype, MPI_Offset len, const unsigned char *op);
+
+int ncmpi_put_att_ushort(int ncid, int varid, const char *name,
+ nc_type xtype, MPI_Offset len, const unsigned short *op);
+
+int ncmpi_put_att_uint(int ncid, int varid, const char *name,
+ nc_type xtype, MPI_Offset len, const unsigned int *op);
+
+int ncmpi_put_att_long(int ncid, int varid, const char *name,
+ nc_type xtype, MPI_Offset len, const long *op);
+
+int ncmpi_put_att_ulonglong(int ncid, int varid, const char *name,
+ nc_type xtype, MPI_Offset len, const unsigned long long *op);
+
+int ncmpi_get_att_uchar(int ncid, int varid, const char *name,
+ unsigned char *ip);
+
+int ncmpi_get_att_ubyte(int ncid, int varid, const char *name,
+ unsigned char *ip);
+
+int ncmpi_get_att_ushort(int ncid, int varid, const char *name,
+ unsigned short *ip);
+
+int ncmpi_get_att_uint(int ncid, int varid, const char *name,
+ unsigned int *ip);
+
+int ncmpi_get_att_long(int ncid, int varid, const char *name,
+ long *ip);
+
+int ncmpi_get_att_ulonglong(int ncid, int varid, const char *name,
+ unsigned long long *ip);
+
+/* End Skip Prototypes for Fortran binding */
+
+/* End _att */
+
+/* Begin {put,get}_var1 */
+
+int ncmpi_put_var1(int ncid, int varid, const MPI_Offset index[],
+ const void *buf, MPI_Offset bufcount, MPI_Datatype buftype);
+int ncmpi_put_var1_all(int ncid, int varid, const MPI_Offset index[],
+ const void *buf, MPI_Offset bufcount, MPI_Datatype buftype);
+
+int ncmpi_put_var1_text(int ncid, int varid, const MPI_Offset index[],
+ const char *op);
+int ncmpi_put_var1_text_all(int ncid, int varid, const MPI_Offset index[],
+ const char *op);
+
+int ncmpi_put_var1_schar(int ncid, int varid, const MPI_Offset index[],
+ const signed char *op);
+int ncmpi_put_var1_schar_all(int ncid, int varid, const MPI_Offset index[],
+ const signed char *op);
+
+int ncmpi_put_var1_short(int ncid, int varid, const MPI_Offset index[],
+ const short *op);
+int ncmpi_put_var1_short_all(int ncid, int varid, const MPI_Offset index[],
+ const short *op);
+
+int ncmpi_put_var1_int(int ncid, int varid, const MPI_Offset index[],
+ const int *op);
+int ncmpi_put_var1_int_all(int ncid, int varid, const MPI_Offset index[],
+ const int *op);
+
+int ncmpi_put_var1_float(int ncid, int varid, const MPI_Offset index[],
+ const float *op);
+int ncmpi_put_var1_float_all(int ncid, int varid, const MPI_Offset index[],
+ const float *op);
+
+int ncmpi_put_var1_double(int ncid, int varid, const MPI_Offset index[],
+ const double *op);
+int ncmpi_put_var1_double_all(int ncid, int varid, const MPI_Offset index[],
+ const double *op);
+
+int ncmpi_put_var1_longlong(int ncid, int varid, const MPI_Offset index[],
+ const long long *op);
+int ncmpi_put_var1_longlong_all(int ncid, int varid, const MPI_Offset index[],
+ const long long *op);
+
+int ncmpi_get_var1(int ncid, int varid, const MPI_Offset index[],
+ void *buf, MPI_Offset bufcount, MPI_Datatype buftype);
+int ncmpi_get_var1_all(int ncid, int varid, const MPI_Offset index[],
+ void *buf, MPI_Offset bufcount, MPI_Datatype buftype);
+
+int ncmpi_get_var1_text(int ncid, int varid, const MPI_Offset index[],
+ char *ip);
+int ncmpi_get_var1_text_all(int ncid, int varid, const MPI_Offset index[],
+ char *ip);
+
+int ncmpi_get_var1_schar(int ncid, int varid, const MPI_Offset index[],
+ signed char *ip);
+int ncmpi_get_var1_schar_all(int ncid, int varid, const MPI_Offset index[],
+ signed char *ip);
+
+int ncmpi_get_var1_short(int ncid, int varid, const MPI_Offset index[],
+ short *ip);
+int ncmpi_get_var1_short_all(int ncid, int varid, const MPI_Offset index[],
+ short *ip);
+
+int ncmpi_get_var1_int(int ncid, int varid, const MPI_Offset index[],
+ int *ip);
+int ncmpi_get_var1_int_all(int ncid, int varid, const MPI_Offset index[],
+ int *ip);
+
+int ncmpi_get_var1_float(int ncid, int varid, const MPI_Offset index[],
+ float *ip);
+int ncmpi_get_var1_float_all(int ncid, int varid, const MPI_Offset index[],
+ float *ip);
+
+int ncmpi_get_var1_double(int ncid, int varid, const MPI_Offset index[],
+ double *ip);
+int ncmpi_get_var1_double_all(int ncid, int varid, const MPI_Offset index[],
+ double *ip);
+
+int ncmpi_get_var1_longlong(int ncid, int varid, const MPI_Offset index[],
+ long long *ip);
+int ncmpi_get_var1_longlong_all(int ncid, int varid, const MPI_Offset index[],
+ long long *ip);
+
+/* Begin Skip Prototypes for Fortran binding */
+/* skip types: uchar, ubyte, ushort, uint, long, ulonglong string */
+
+int ncmpi_put_var1_uchar(int ncid, int varid, const MPI_Offset index[],
+ const unsigned char *op);
+int ncmpi_put_var1_uchar_all(int ncid, int varid, const MPI_Offset index[],
+ const unsigned char *op);
+
+int ncmpi_put_var1_ushort(int ncid, int varid, const MPI_Offset index[],
+ const unsigned short *op);
+int ncmpi_put_var1_ushort_all(int ncid, int varid, const MPI_Offset index[],
+ const unsigned short *op);
+
+int ncmpi_put_var1_uint(int ncid, int varid, const MPI_Offset index[],
+ const unsigned int *op);
+int ncmpi_put_var1_uint_all(int ncid, int varid, const MPI_Offset index[],
+ const unsigned int *op);
+
+int ncmpi_put_var1_long(int ncid, int varid, const MPI_Offset index[],
+ const long *ip);
+int ncmpi_put_var1_long_all(int ncid, int varid, const MPI_Offset index[],
+ const long *ip);
+
+int ncmpi_put_var1_ulonglong(int ncid, int varid, const MPI_Offset index[],
+ const unsigned long long *ip);
+int ncmpi_put_var1_ulonglong_all(int ncid, int varid, const MPI_Offset index[],
+ const unsigned long long *ip);
+
+int ncmpi_get_var1_uchar(int ncid, int varid, const MPI_Offset index[],
+ unsigned char *ip);
+int ncmpi_get_var1_uchar_all(int ncid, int varid, const MPI_Offset index[],
+ unsigned char *ip);
+
+int ncmpi_get_var1_ushort(int ncid, int varid, const MPI_Offset index[],
+ unsigned short *ip);
+int ncmpi_get_var1_ushort_all(int ncid, int varid, const MPI_Offset index[],
+ unsigned short *ip);
+
+int ncmpi_get_var1_uint(int ncid, int varid, const MPI_Offset index[],
+ unsigned int *ip);
+int ncmpi_get_var1_uint_all(int ncid, int varid, const MPI_Offset index[],
+ unsigned int *ip);
+
+int ncmpi_get_var1_long(int ncid, int varid, const MPI_Offset index[],
+ long *ip);
+int ncmpi_get_var1_long_all(int ncid, int varid, const MPI_Offset index[],
+ long *ip);
+
+int ncmpi_get_var1_ulonglong(int ncid, int varid, const MPI_Offset index[],
+ unsigned long long *ip);
+int ncmpi_get_var1_ulonglong_all(int ncid, int varid, const MPI_Offset index[],
+ unsigned long long *ip);
+/* End Skip Prototypes for Fortran binding */
+
+/* End {put,get}_var1 */
+
+/* Begin {put,get}_var */
+
+int ncmpi_put_var(int ncid, int varid, const void *buf, MPI_Offset bufcount,
+ MPI_Datatype buftype);
+
+int ncmpi_put_var_all(int ncid, int varid, const void *buf, MPI_Offset bufcount,
+ MPI_Datatype buftype);
+
+int ncmpi_put_var_text(int ncid, int varid, const char *op);
+int ncmpi_put_var_text_all(int ncid, int varid, const char *op);
+
+int ncmpi_put_var_schar(int ncid, int varid, const signed char *op);
+int ncmpi_put_var_schar_all(int ncid, int varid, const signed char *op);
+
+int ncmpi_put_var_short(int ncid, int varid, const short *op);
+int ncmpi_put_var_short_all(int ncid, int varid, const short *op);
+
+int ncmpi_put_var_int(int ncid, int varid, const int *op);
+int ncmpi_put_var_int_all(int ncid, int varid, const int *op);
+
+int ncmpi_put_var_float(int ncid, int varid, const float *op);
+int ncmpi_put_var_float_all(int ncid, int varid, const float *op);
+
+int ncmpi_put_var_double(int ncid, int varid, const double *op);
+int ncmpi_put_var_double_all(int ncid, int varid, const double *op);
+
+int ncmpi_put_var_longlong(int ncid, int varid, const long long *op);
+int ncmpi_put_var_longlong_all(int ncid, int varid, const long long *op);
+
+int ncmpi_get_var(int ncid, int varid, void *buf, MPI_Offset bufcount,
+ MPI_Datatype buftype);
+
+int ncmpi_get_var_all(int ncid, int varid, void *buf, MPI_Offset bufcount,
+ MPI_Datatype buftype);
+
+int ncmpi_get_var_text(int ncid, int varid, char *ip);
+int ncmpi_get_var_text_all(int ncid, int varid, char *ip);
+
+int ncmpi_get_var_schar(int ncid, int varid, signed char *ip);
+int ncmpi_get_var_schar_all(int ncid, int varid, signed char *ip);
+
+int ncmpi_get_var_short(int ncid, int varid, short *ip);
+int ncmpi_get_var_short_all(int ncid, int varid, short *ip);
+
+int ncmpi_get_var_int(int ncid, int varid, int *ip);
+int ncmpi_get_var_int_all(int ncid, int varid, int *ip);
+
+int ncmpi_get_var_float(int ncid, int varid, float *ip);
+int ncmpi_get_var_float_all(int ncid, int varid, float *ip);
+
+int ncmpi_get_var_double(int ncid, int varid, double *ip);
+int ncmpi_get_var_double_all(int ncid, int varid, double *ip);
+
+int ncmpi_get_var_longlong(int ncid, int varid, long long *ip);
+int ncmpi_get_var_longlong_all(int ncid, int varid, long long *ip);
+
+/* Begin Skip Prototypes for Fortran binding */
+/* skip types: uchar, ubyte, ushort, uint, long, ulonglong string */
+
+int ncmpi_put_var_uchar(int ncid, int varid, const unsigned char *op);
+int ncmpi_put_var_uchar_all(int ncid, int varid, const unsigned char *op);
+
+int ncmpi_put_var_ushort(int ncid, int varid, const unsigned short *op);
+int ncmpi_put_var_ushort_all(int ncid, int varid, const unsigned short *op);
+
+int ncmpi_put_var_uint(int ncid, int varid, const unsigned int *op);
+int ncmpi_put_var_uint_all(int ncid, int varid, const unsigned int *op);
+
+int ncmpi_put_var_long(int ncid, int varid, const long *op);
+int ncmpi_put_var_long_all(int ncid, int varid, const long *op);
+
+int ncmpi_put_var_ulonglong(int ncid, int varid, const unsigned long long *op);
+int ncmpi_put_var_ulonglong_all(int ncid, int varid, const unsigned long long *op);
+
+int ncmpi_get_var_uchar(int ncid, int varid, unsigned char *ip);
+int ncmpi_get_var_uchar_all(int ncid, int varid, unsigned char *ip);
+
+int ncmpi_get_var_ushort(int ncid, int varid, unsigned short *ip);
+int ncmpi_get_var_ushort_all(int ncid, int varid, unsigned short *ip);
+
+int ncmpi_get_var_uint(int ncid, int varid, unsigned int *ip);
+int ncmpi_get_var_uint_all(int ncid, int varid, unsigned int *ip);
+
+int ncmpi_get_var_long(int ncid, int varid, long *ip);
+int ncmpi_get_var_long_all(int ncid, int varid, long *ip);
+
+int ncmpi_get_var_ulonglong(int ncid, int varid, unsigned long long *ip);
+int ncmpi_get_var_ulonglong_all(int ncid, int varid, unsigned long long *ip);
+/* End Skip Prototypes for Fortran binding */
+
+/* End {put,get}_var */
+
+/* Begin {put,get}_vara */
+
+int ncmpi_put_vara(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const void *buf,
+ MPI_Offset bufcount, MPI_Datatype buftype);
+
+int ncmpi_put_vara_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const void *buf,
+ MPI_Offset bufcount, MPI_Datatype buftype);
+
+int ncmpi_put_vara_text(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const char *op);
+
+int ncmpi_put_vara_text_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const char *op);
+
+int ncmpi_put_vara_schar(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const signed char *op);
+
+int ncmpi_put_vara_schar_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const signed char *op);
+
+int ncmpi_put_vara_short(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const short *op);
+
+int ncmpi_put_vara_short_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const short *op);
+
+int ncmpi_put_vara_int(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const int *op);
+
+int ncmpi_put_vara_int_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const int *op);
+
+int ncmpi_put_vara_float(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const float *op);
+
+int ncmpi_put_vara_float_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const float *op);
+
+int ncmpi_put_vara_double(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const double *op);
+
+int ncmpi_put_vara_double_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const double *op);
+
+int ncmpi_put_vara_longlong(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const long long *op);
+
+int ncmpi_put_vara_longlong_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const long long *op);
+
+int ncmpi_get_vara(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], void *buf, MPI_Offset bufcount,
+ MPI_Datatype buftype);
+
+int ncmpi_get_vara_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], void *buf, MPI_Offset bufcount,
+ MPI_Datatype buftype);
+
+int ncmpi_get_vara_text(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], char *ip);
+
+int ncmpi_get_vara_text_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], char *ip);
+
+int ncmpi_get_vara_schar(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], signed char *ip);
+
+int ncmpi_get_vara_schar_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], signed char *ip);
+
+int ncmpi_get_vara_short(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], short *ip);
+
+int ncmpi_get_vara_short_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], short *ip);
+
+int ncmpi_get_vara_int(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], int *ip);
+
+int ncmpi_get_vara_int_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], int *ip);
+
+int ncmpi_get_vara_float(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], float *ip);
+
+int ncmpi_get_vara_float_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], float *ip);
+
+int ncmpi_get_vara_double(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], double *ip);
+
+int ncmpi_get_vara_double_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], double *ip);
+
+int ncmpi_get_vara_longlong(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], long long *ip);
+
+int ncmpi_get_vara_longlong_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], long long *ip);
+
+/* Begin Skip Prototypes for Fortran binding */
+/* skip types: uchar, ubyte, ushort, uint, long, ulonglong string */
+
+int ncmpi_put_vara_uchar(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const unsigned char *op);
+
+int ncmpi_put_vara_uchar_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const unsigned char *op);
+
+int ncmpi_put_vara_ushort(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const unsigned short *op);
+
+int ncmpi_put_vara_ushort_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const unsigned short *op);
+
+int ncmpi_put_vara_uint(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const unsigned int *op);
+
+int ncmpi_put_vara_uint_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const unsigned int *op);
+
+int ncmpi_put_vara_long(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const long *op);
+
+int ncmpi_put_vara_long_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const long *op);
+
+int ncmpi_put_vara_ulonglong(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const unsigned long long *op);
+
+int ncmpi_put_vara_ulonglong_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const unsigned long long *op);
+
+int ncmpi_get_vara_uchar(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], unsigned char *ip);
+
+int ncmpi_get_vara_uchar_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], unsigned char *ip);
+
+int ncmpi_get_vara_ushort(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], unsigned short *ip);
+
+int ncmpi_get_vara_ushort_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], unsigned short *ip);
+
+int ncmpi_get_vara_uint(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], unsigned int *ip);
+
+int ncmpi_get_vara_uint_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], unsigned int *ip);
+
+int ncmpi_get_vara_long(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], long *ip);
+
+int ncmpi_get_vara_long_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], long *ip);
+
+int ncmpi_get_vara_ulonglong(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], unsigned long long *ip);
+
+int ncmpi_get_vara_ulonglong_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], unsigned long long *ip);
+
+/* End Skip Prototypes for Fortran binding */
+
+/* End {put,get}_vara */
+
+/* Begin {put,get}_vars */
+
+int ncmpi_put_vars(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const void *buf, MPI_Offset bufcount,
+ MPI_Datatype buftype);
+
+int ncmpi_put_vars_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const void *buf, MPI_Offset bufcount,
+ MPI_Datatype buftype);
+
+int ncmpi_put_vars_text(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const char *op);
+
+int ncmpi_put_vars_text_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const char *op);
+
+int ncmpi_put_vars_schar(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const signed char *op);
+
+int ncmpi_put_vars_schar_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const signed char *op);
+
+int ncmpi_put_vars_short(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const short *op);
+
+int ncmpi_put_vars_short_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const short *op);
+
+int ncmpi_put_vars_int(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const int *op);
+
+int ncmpi_put_vars_int_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const int *op);
+
+int ncmpi_put_vars_float(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const float *op);
+
+int ncmpi_put_vars_float_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const float *op);
+
+int ncmpi_put_vars_double(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const double *op);
+
+int ncmpi_put_vars_double_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const double *op);
+
+int ncmpi_put_vars_longlong(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const long long *op);
+
+int ncmpi_put_vars_longlong_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const long long *op);
+
+int ncmpi_get_vars(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ void *buf, MPI_Offset bufcount, MPI_Datatype buftype);
+
+int ncmpi_get_vars_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ void *buf, MPI_Offset bufcount, MPI_Datatype buftype);
+
+int ncmpi_get_vars_schar(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ signed char *ip);
+
+int ncmpi_get_vars_schar_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ signed char *ip);
+
+int ncmpi_get_vars_text(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ char *ip);
+
+int ncmpi_get_vars_text_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ char *ip);
+
+int ncmpi_get_vars_short(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ short *ip);
+
+int ncmpi_get_vars_short_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ short *ip);
+
+int ncmpi_get_vars_int(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ int *ip);
+
+int ncmpi_get_vars_int_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ int *ip);
+
+int ncmpi_get_vars_float(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ float *ip);
+
+int ncmpi_get_vars_float_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ float *ip);
+
+int ncmpi_get_vars_double(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ double *ip);
+
+int ncmpi_get_vars_double_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ double *ip);
+
+int ncmpi_get_vars_longlong(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ long long *ip);
+
+int ncmpi_get_vars_longlong_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ long long *ip);
+
+/* Begin Skip Prototypes for Fortran binding */
+/* skip types: uchar, ubyte, ushort, uint, long, ulonglong string */
+
+int ncmpi_put_vars_uchar(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const unsigned char *op);
+
+int ncmpi_put_vars_uchar_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const unsigned char *op);
+
+int ncmpi_put_vars_ushort(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const unsigned short *op);
+
+int ncmpi_put_vars_ushort_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const unsigned short *op);
+
+int ncmpi_put_vars_uint(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const unsigned int *op);
+
+int ncmpi_put_vars_uint_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const unsigned int *op);
+
+int ncmpi_put_vars_long(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const long *op);
+
+int ncmpi_put_vars_long_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const long *op);
+
+int ncmpi_put_vars_ulonglong(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const unsigned long long *op);
+
+int ncmpi_put_vars_ulonglong_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const unsigned long long *op);
+
+int ncmpi_get_vars_uchar(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ unsigned char *ip);
+
+int ncmpi_get_vars_uchar_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ unsigned char *ip);
+
+int ncmpi_get_vars_ushort(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ unsigned short *ip);
+
+int ncmpi_get_vars_ushort_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ unsigned short *ip);
+
+int ncmpi_get_vars_uint(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ unsigned int *ip);
+
+int ncmpi_get_vars_uint_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ unsigned int *ip);
+
+int ncmpi_get_vars_long(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ long *ip);
+
+int ncmpi_get_vars_long_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ long *ip);
+
+int ncmpi_get_vars_ulonglong(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ unsigned long long *ip);
+
+int ncmpi_get_vars_ulonglong_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ unsigned long long *ip);
+
+/* End Skip Prototypes for Fortran binding */
+
+/* End {put,get}_vars */
+
+/* Begin {put,get}_varm */
+
+int ncmpi_put_varm(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], const void *buf,
+ MPI_Offset bufcount, MPI_Datatype buftype);
+
+int ncmpi_put_varm_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], const void *buf,
+ MPI_Offset bufcount, MPI_Datatype buftype);
+
+int ncmpi_put_varm_text(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], const char *op);
+
+int ncmpi_put_varm_text_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], const char *op);
+
+int ncmpi_put_varm_schar(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], const signed char *op);
+
+int ncmpi_put_varm_schar_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], const signed char *op);
+
+int ncmpi_put_varm_short(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], const short *op);
+
+int ncmpi_put_varm_short_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], const short *op);
+
+int ncmpi_put_varm_int(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], const int *op);
+
+int ncmpi_put_varm_int_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], const int *op);
+
+int ncmpi_put_varm_float(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], const float *op);
+
+int ncmpi_put_varm_float_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], const float *op);
+
+int ncmpi_put_varm_double(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], const double *op);
+
+int ncmpi_put_varm_double_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], const double *op);
+
+int ncmpi_put_varm_longlong(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], const long long *op);
+
+int ncmpi_put_varm_longlong_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], const long long *op);
+
+int ncmpi_get_varm(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], void *buf, MPI_Offset bufcount,
+ MPI_Datatype buftype);
+
+int ncmpi_get_varm_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], void *buf, MPI_Offset bufcount,
+ MPI_Datatype buftype);
+
+int ncmpi_get_varm_schar(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], signed char *ip);
+
+int ncmpi_get_varm_schar_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], signed char *ip);
+
+int ncmpi_get_varm_text(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], char *ip);
+
+int ncmpi_get_varm_text_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], char *ip);
+
+int ncmpi_get_varm_short(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], short *ip);
+
+int ncmpi_get_varm_short_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], short *ip);
+
+int ncmpi_get_varm_int(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], int *ip);
+
+int ncmpi_get_varm_int_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], int *ip);
+
+int ncmpi_get_varm_float(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], float *ip);
+
+int ncmpi_get_varm_float_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], float *ip);
+
+int ncmpi_get_varm_double(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], double *ip);
+
+int ncmpi_get_varm_double_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], double *ip);
+
+int ncmpi_get_varm_longlong(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], long long *ip);
+
+int ncmpi_get_varm_longlong_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], long long *ip);
+
+/* Begin Skip Prototypes for Fortran binding */
+/* skip types: uchar, ubyte, ushort, uint, long, ulonglong string */
+
+int ncmpi_put_varm_uchar(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], const unsigned char *op);
+
+int ncmpi_put_varm_uchar_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], const unsigned char *op);
+
+int ncmpi_put_varm_ushort(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], const unsigned short *op);
+
+int ncmpi_put_varm_ushort_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], const unsigned short *op);
+
+int ncmpi_put_varm_uint(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], const unsigned int *op);
+
+int ncmpi_put_varm_uint_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], const unsigned int *op);
+
+int ncmpi_put_varm_long(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], const long *op);
+
+int ncmpi_put_varm_long_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], const long *op);
+
+int ncmpi_put_varm_ulonglong(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], const unsigned long long *op);
+
+int ncmpi_put_varm_ulonglong_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], const unsigned long long *op);
+
+int ncmpi_get_varm_uchar(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], unsigned char *ip);
+
+int ncmpi_get_varm_uchar_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], unsigned char *ip);
+
+int ncmpi_get_varm_ushort(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], unsigned short *ip);
+
+int ncmpi_get_varm_ushort_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], unsigned short *ip);
+
+int ncmpi_get_varm_uint(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], unsigned int *ip);
+
+int ncmpi_get_varm_uint_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], unsigned int *ip);
+
+int ncmpi_get_varm_long(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], long *ip);
+
+int ncmpi_get_varm_long_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], long *ip);
+
+int ncmpi_get_varm_ulonglong(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], unsigned long long *ip);
+
+int ncmpi_get_varm_ulonglong_all(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], unsigned long long *ip);
+
+/* End Skip Prototypes for Fortran binding */
+
+/* End {put,get}_varm */
+
+/* Begin of {put,get}_varn{kind} */
+
+int ncmpi_put_varn(int ncid, int varid, int num, MPI_Offset* const starts[],
+ MPI_Offset* const counts[], const void *buf, MPI_Offset bufcount,
+ MPI_Datatype buftype);
+
+int ncmpi_put_varn_all(int ncid, int varid, int num, MPI_Offset* const starts[],
+ MPI_Offset* const counts[], const void *buf, MPI_Offset bufcount,
+ MPI_Datatype buftype);
+
+int ncmpi_get_varn(int ncid, int varid, int num, MPI_Offset* const starts[],
+ MPI_Offset* const counts[], void *buf, MPI_Offset bufcount,
+ MPI_Datatype buftype);
+
+int ncmpi_get_varn_all(int ncid, int varid, int num, MPI_Offset* const starts[],
+ MPI_Offset* const counts[], void *buf, MPI_Offset bufcount,
+ MPI_Datatype buftype);
+
+int ncmpi_put_varn_text(int ncid, int varid, int num,
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ const char *buf);
+
+int ncmpi_put_varn_schar(int ncid, int varid, int num,
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ const signed char *buf);
+
+int ncmpi_put_varn_short(int ncid, int varid, int num,
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ const short *buf);
+
+int ncmpi_put_varn_int(int ncid, int varid, int num,
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ const int *buf);
+
+int ncmpi_put_varn_float(int ncid, int varid, int num,
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ const float *buf);
+
+int ncmpi_put_varn_double(int ncid, int varid, int num,
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ const double *buf);
+
+int ncmpi_put_varn_longlong(int ncid, int varid, int num,
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ const long long *buf);
+
+
+/* Begin Skip Prototypes for Fortran binding */
+/* skip types: uchar, ubyte, ushort, uint, long, ulonglong string */
+
+int ncmpi_put_varn_uchar(int ncid, int varid, int num,
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ const unsigned char *buf);
+
+int ncmpi_put_varn_ushort(int ncid, int varid, int num,
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ const unsigned short *buf);
+
+int ncmpi_put_varn_uint(int ncid, int varid, int num,
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ const unsigned int *buf);
+
+int ncmpi_put_varn_long(int ncid, int varid, int num,
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ const long *buf);
+
+int ncmpi_put_varn_ulonglong(int ncid, int varid, int num,
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ const unsigned long long *buf);
+
+/* End Skip Prototypes for Fortran binding */
+
+int ncmpi_put_varn_text_all(int ncid, int varid, int num,
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ const char *buf);
+
+int ncmpi_put_varn_schar_all(int ncid, int varid, int num,
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ const signed char *buf);
+
+int ncmpi_put_varn_short_all(int ncid, int varid, int num,
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ const short *buf);
+
+int ncmpi_put_varn_int_all(int ncid, int varid, int num,
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ const int *buf);
+
+int ncmpi_put_varn_float_all(int ncid, int varid, int num,
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ const float *buf);
+
+int ncmpi_put_varn_double_all(int ncid, int varid, int num,
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ const double *buf);
+
+int ncmpi_put_varn_longlong_all(int ncid, int varid, int num,
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ const long long *buf);
+
+
+/* Begin Skip Prototypes for Fortran binding */
+/* skip types: uchar, ubyte, ushort, uint, long, ulonglong string */
+
+int ncmpi_put_varn_uchar_all(int ncid, int varid, int num,
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ const unsigned char *buf);
+
+int ncmpi_put_varn_ushort_all(int ncid, int varid, int num,
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ const unsigned short *buf);
+
+int ncmpi_put_varn_uint_all(int ncid, int varid, int num,
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ const unsigned int *buf);
+
+int ncmpi_put_varn_long_all(int ncid, int varid, int num,
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ const long *buf);
+
+int ncmpi_put_varn_ulonglong_all(int ncid, int varid, int num,
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ const unsigned long long *buf);
+
+/* End Skip Prototypes for Fortran binding */
+
+int ncmpi_get_varn_text(int ncid, int varid, int num,
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ char *buf);
+
+int ncmpi_get_varn_schar(int ncid, int varid, int num,
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ signed char *buf);
+
+int ncmpi_get_varn_short(int ncid, int varid, int num,
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ short *buf);
+
+int ncmpi_get_varn_int(int ncid, int varid, int num,
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ int *buf);
+
+int ncmpi_get_varn_float(int ncid, int varid, int num,
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ float *buf);
+
+int ncmpi_get_varn_double(int ncid, int varid, int num,
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ double *buf);
+
+int ncmpi_get_varn_longlong(int ncid, int varid, int num,
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ long long *buf);
+
+
+/* Begin Skip Prototypes for Fortran binding */
+/* skip types: uchar, ubyte, ushort, uint, long, ulonglong string */
+
+int ncmpi_get_varn_uchar(int ncid, int varid, int num,
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ unsigned char *buf);
+
+int ncmpi_get_varn_ushort(int ncid, int varid, int num,
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ unsigned short *buf);
+
+int ncmpi_get_varn_uint(int ncid, int varid, int num,
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ unsigned int *buf);
+
+int ncmpi_get_varn_long(int ncid, int varid, int num,
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ long *buf);
+
+int ncmpi_get_varn_ulonglong(int ncid, int varid, int num,
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ unsigned long long *buf);
+
+/* End Skip Prototypes for Fortran binding */
+
+int ncmpi_get_varn_text_all(int ncid, int varid, int num,
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ char *buf);
+
+int ncmpi_get_varn_schar_all(int ncid, int varid, int num,
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ signed char *buf);
+
+int ncmpi_get_varn_short_all(int ncid, int varid, int num,
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ short *buf);
+
+int ncmpi_get_varn_int_all(int ncid, int varid, int num,
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ int *buf);
+
+int ncmpi_get_varn_float_all(int ncid, int varid, int num,
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ float *buf);
+
+int ncmpi_get_varn_double_all(int ncid, int varid, int num,
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ double *buf);
+
+int ncmpi_get_varn_longlong_all(int ncid, int varid, int num,
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ long long *buf);
+
+
+/* Begin Skip Prototypes for Fortran binding */
+/* skip types: uchar, ubyte, ushort, uint, long, ulonglong string */
+
+int ncmpi_get_varn_uchar_all(int ncid, int varid, int num,
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ unsigned char *buf);
+
+int ncmpi_get_varn_ushort_all(int ncid, int varid, int num,
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ unsigned short *buf);
+
+int ncmpi_get_varn_uint_all(int ncid, int varid, int num,
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ unsigned int *buf);
+
+int ncmpi_get_varn_long_all(int ncid, int varid, int num,
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ long *buf);
+
+int ncmpi_get_varn_ulonglong_all(int ncid, int varid, int num,
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ unsigned long long *buf);
+
+/* End Skip Prototypes for Fortran binding */
+
+/* End of {put,get}_varn{kind} */
+
+/* Begin {put,get}_vard */
+int ncmpi_get_vard(int ncid, int varid, MPI_Datatype filetype, void *buf,
+ MPI_Offset bufcount, MPI_Datatype buftype);
+int ncmpi_get_vard_all(int ncid, int varid, MPI_Datatype filetype, void *buf,
+ MPI_Offset bufcount, MPI_Datatype buftype);
+int ncmpi_put_vard(int ncid, int varid, MPI_Datatype filetype, const void *buf,
+ MPI_Offset bufcount, MPI_Datatype buftype);
+int ncmpi_put_vard_all(int ncid, int varid, MPI_Datatype filetype, const void *buf,
+ MPI_Offset bufcount, MPI_Datatype buftype);
+/* End of {put,get}_vard */
+
+/* Begin {mput,mget}_var */
+
+/* #################################################################### */
+/* Begin: more prototypes to be included for Fortran binding conversion */
+
+/* Begin non-blocking data access functions */
+
+int ncmpi_wait(int ncid, int count, int array_of_requests[],
+ int array_of_statuses[]);
+
+int ncmpi_wait_all(int ncid, int count, int array_of_requests[],
+ int array_of_statuses[]);
+
+int ncmpi_cancel(int ncid, int num, int *requests, int *statuses);
+
+int ncmpi_buffer_attach(int ncid, MPI_Offset bufsize);
+int ncmpi_buffer_detach(int ncid);
+int ncmpi_inq_buffer_usage(int ncid, MPI_Offset *usage);
+int ncmpi_inq_buffer_size(int ncid, MPI_Offset *buf_size);
+int ncmpi_inq_nreqs(int ncid, int *nreqs);
+
+/* Begin {iput,iget,bput}_var1 */
+
+int ncmpi_iput_var1(int ncid, int varid, const MPI_Offset index[],
+ const void *buf, MPI_Offset bufcount,
+ MPI_Datatype buftype, int *request);
+
+int ncmpi_iput_var1_text(int ncid, int varid, const MPI_Offset index[],
+ const char *op, int *request);
+
+int ncmpi_iput_var1_schar(int ncid, int varid, const MPI_Offset index[],
+ const signed char *op, int *request);
+
+int ncmpi_iput_var1_short(int ncid, int varid, const MPI_Offset index[],
+ const short *op, int *request);
+
+int ncmpi_iput_var1_int(int ncid, int varid, const MPI_Offset index[],
+ const int *op, int *request);
+
+int ncmpi_iput_var1_float(int ncid, int varid, const MPI_Offset index[],
+ const float *op, int *request);
+
+int ncmpi_iput_var1_double(int ncid, int varid, const MPI_Offset index[],
+ const double *op, int *request);
+
+int ncmpi_iput_var1_longlong(int ncid, int varid, const MPI_Offset index[],
+ const long long *op, int *request);
+
+int ncmpi_iget_var1(int ncid, int varid, const MPI_Offset index[], void *buf,
+ MPI_Offset bufcount, MPI_Datatype buftype, int *request);
+
+int ncmpi_iget_var1_schar(int ncid, int varid, const MPI_Offset index[],
+ signed char *ip, int *request);
+
+int ncmpi_iget_var1_text(int ncid, int varid, const MPI_Offset index[],
+ char *ip, int *request);
+
+int ncmpi_iget_var1_short(int ncid, int varid, const MPI_Offset index[],
+ short *ip, int *request);
+
+int ncmpi_iget_var1_int(int ncid, int varid, const MPI_Offset index[],
+ int *ip, int *request);
+
+int ncmpi_iget_var1_float(int ncid, int varid, const MPI_Offset index[],
+ float *ip, int *request);
+
+int ncmpi_iget_var1_double(int ncid, int varid, const MPI_Offset index[],
+ double *ip, int *request);
+
+int ncmpi_iget_var1_longlong(int ncid, int varid, const MPI_Offset index[],
+ long long *ip, int *request);
+
+int ncmpi_bput_var1(int ncid, int varid, const MPI_Offset index[],
+ const void *buf, MPI_Offset bufcount,
+ MPI_Datatype buftype, int *request);
+
+int ncmpi_bput_var1_text(int ncid, int varid, const MPI_Offset index[],
+ const char *op, int *request);
+
+int ncmpi_bput_var1_schar(int ncid, int varid, const MPI_Offset index[],
+ const signed char *op, int *request);
+
+int ncmpi_bput_var1_short(int ncid, int varid, const MPI_Offset index[],
+ const short *op, int *request);
+
+int ncmpi_bput_var1_int(int ncid, int varid, const MPI_Offset index[],
+ const int *op, int *request);
+
+int ncmpi_bput_var1_float(int ncid, int varid, const MPI_Offset index[],
+ const float *op, int *request);
+
+int ncmpi_bput_var1_double(int ncid, int varid, const MPI_Offset index[],
+ const double *op, int *request);
+
+int ncmpi_bput_var1_longlong(int ncid, int varid, const MPI_Offset index[],
+ const long long *op, int *request);
+
+/* Begin Skip Prototypes for Fortran binding */
+/* skip types: uchar, ubyte, ushort, uint, long, ulonglong string */
+
+int ncmpi_iput_var1_uchar(int ncid, int varid, const MPI_Offset index[],
+ const unsigned char *op, int *request);
+
+int ncmpi_iput_var1_ushort(int ncid, int varid, const MPI_Offset index[],
+ const unsigned short *op, int *request);
+
+int ncmpi_iput_var1_uint(int ncid, int varid, const MPI_Offset index[],
+ const unsigned int *op, int *request);
+
+int ncmpi_iput_var1_long(int ncid, int varid, const MPI_Offset index[],
+ const long *ip, int *request);
+
+int ncmpi_iput_var1_ulonglong(int ncid, int varid, const MPI_Offset index[],
+ const unsigned long long *op, int *request);
+
+int ncmpi_iget_var1_uchar(int ncid, int varid, const MPI_Offset index[],
+ unsigned char *ip, int *request);
+
+int ncmpi_iget_var1_ushort(int ncid, int varid, const MPI_Offset index[],
+ unsigned short *ip, int *request);
+
+int ncmpi_iget_var1_uint(int ncid, int varid, const MPI_Offset index[],
+ unsigned int *ip, int *request);
+
+int ncmpi_iget_var1_long(int ncid, int varid, const MPI_Offset index[],
+ long *ip, int *request);
+
+int ncmpi_iget_var1_ulonglong(int ncid, int varid, const MPI_Offset index[],
+ unsigned long long *ip, int *request);
+
+int ncmpi_bput_var1_uchar(int ncid, int varid, const MPI_Offset index[],
+ const unsigned char *op, int *request);
+
+int ncmpi_bput_var1_ushort(int ncid, int varid, const MPI_Offset index[],
+ const unsigned short *op, int *request);
+
+int ncmpi_bput_var1_uint(int ncid, int varid, const MPI_Offset index[],
+ const unsigned int *op, int *request);
+
+int ncmpi_bput_var1_long(int ncid, int varid, const MPI_Offset index[],
+ const long *ip, int *request);
+
+int ncmpi_bput_var1_ulonglong(int ncid, int varid, const MPI_Offset index[],
+ const unsigned long long *op, int *request);
+
+/* End Skip Prototypes for Fortran binding */
+
+/* End {iput,iget,bput}_var1 */
+
+/* Begin {iput,iget,bput}_var */
+
+int ncmpi_iput_var(int ncid, int varid, const void *buf, MPI_Offset bufcount,
+ MPI_Datatype buftype, int *request);
+
+int ncmpi_iput_var_schar(int ncid, int varid, const signed char *op,
+ int *request);
+
+int ncmpi_iput_var_text(int ncid, int varid, const char *op, int *request);
+
+int ncmpi_iput_var_short(int ncid, int varid, const short *op, int *request);
+
+int ncmpi_iput_var_int(int ncid, int varid, const int *op, int *request);
+
+int ncmpi_iput_var_float(int ncid, int varid, const float *op, int *request);
+
+int ncmpi_iput_var_double(int ncid, int varid, const double *op, int *request);
+
+int ncmpi_iput_var_longlong(int ncid, int varid, const long long *op, int *request);
+
+int ncmpi_iget_var(int ncid, int varid, void *buf, MPI_Offset bufcount,
+ MPI_Datatype buftype, int *request);
+
+int ncmpi_iget_var_schar(int ncid, int varid, signed char *ip, int *request);
+
+int ncmpi_iget_var_text(int ncid, int varid, char *ip, int *request);
+
+int ncmpi_iget_var_short(int ncid, int varid, short *ip, int *request);
+
+int ncmpi_iget_var_int(int ncid, int varid, int *ip, int *request);
+
+int ncmpi_iget_var_float(int ncid, int varid, float *ip, int *request);
+
+int ncmpi_iget_var_double(int ncid, int varid, double *ip, int *request);
+
+int ncmpi_iget_var_longlong(int ncid, int varid, long long *ip, int *request);
+
+int ncmpi_bput_var(int ncid, int varid, const void *buf, MPI_Offset bufcount,
+ MPI_Datatype buftype, int *request);
+
+int ncmpi_bput_var_schar(int ncid, int varid, const signed char *op,
+ int *request);
+
+int ncmpi_bput_var_text(int ncid, int varid, const char *op, int *request);
+
+int ncmpi_bput_var_short(int ncid, int varid, const short *op, int *request);
+
+int ncmpi_bput_var_int(int ncid, int varid, const int *op, int *request);
+
+int ncmpi_bput_var_float(int ncid, int varid, const float *op, int *request);
+
+int ncmpi_bput_var_double(int ncid, int varid, const double *op, int *request);
+
+int ncmpi_bput_var_longlong(int ncid, int varid, const long long *op, int *request);
+
+/* Begin Skip Prototypes for Fortran binding */
+/* skip types: uchar, ubyte, ushort, uint, long, ulonglong string */
+
+int ncmpi_iput_var_uchar(int ncid, int varid, const unsigned char *op,
+ int *request);
+
+int ncmpi_iput_var_ushort(int ncid, int varid, const unsigned short *op,
+ int *request);
+
+int ncmpi_iput_var_uint(int ncid, int varid, const unsigned int *op,
+ int *request);
+
+int ncmpi_iput_var_long(int ncid, int varid, const long *op, int *request);
+
+int ncmpi_iput_var_ulonglong(int ncid, int varid, const unsigned long long *op,
+ int *request);
+
+int ncmpi_iget_var_uchar(int ncid, int varid, unsigned char *ip, int *request);
+
+int ncmpi_iget_var_ushort(int ncid, int varid, unsigned short *ip, int *request);
+
+int ncmpi_iget_var_uint(int ncid, int varid, unsigned int *ip, int *request);
+
+int ncmpi_iget_var_long(int ncid, int varid, long *ip, int *request);
+
+int ncmpi_iget_var_ulonglong(int ncid, int varid, unsigned long long *ip, int *request);
+
+int ncmpi_bput_var_uchar(int ncid, int varid, const unsigned char *op,
+ int *request);
+
+int ncmpi_bput_var_ushort(int ncid, int varid, const unsigned short *op,
+ int *request);
+
+int ncmpi_bput_var_uint(int ncid, int varid, const unsigned int *op,
+ int *request);
+
+int ncmpi_bput_var_long(int ncid, int varid, const long *op, int *request);
+
+int ncmpi_bput_var_ulonglong(int ncid, int varid, const unsigned long long *op,
+ int *request);
+
+/* End Skip Prototypes for Fortran binding */
+
+/* End {iput,iget,bput}_var */
+
+/* Begin {iput,iget,bput}_vara */
+
+int ncmpi_iput_vara(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const void *buf,
+ MPI_Offset bufcount, MPI_Datatype buftype, int *request);
+
+int ncmpi_iput_vara_schar(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const signed char *op,
+ int *request);
+
+int ncmpi_iput_vara_text(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const char *op, int *request);
+
+int ncmpi_iput_vara_short(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const short *op, int *request);
+
+int ncmpi_iput_vara_int(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const int *op, int *request);
+
+int ncmpi_iput_vara_float(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const float *op, int *request);
+
+int ncmpi_iput_vara_double(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const double *op, int *request);
+
+int ncmpi_iput_vara_longlong(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const long long *op, int *request);
+
+int ncmpi_iget_vara(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], void *buf, MPI_Offset bufcount,
+ MPI_Datatype buftype, int *request);
+
+int ncmpi_iget_vara_schar(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], signed char *ip, int *request);
+
+int ncmpi_iget_vara_text(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], char *ip, int *request);
+
+int ncmpi_iget_vara_short(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], short *ip, int *request);
+
+int ncmpi_iget_vara_int(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], int *ip, int *request);
+
+int ncmpi_iget_vara_float(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], float *ip, int *request);
+
+int ncmpi_iget_vara_double(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], double *ip, int *request);
+
+int ncmpi_iget_vara_longlong(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], long long *ip, int *request);
+
+int ncmpi_bput_vara(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const void *buf,
+ MPI_Offset bufcount, MPI_Datatype buftype, int *request);
+
+int ncmpi_bput_vara_schar(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const signed char *op,
+ int *request);
+
+int ncmpi_bput_vara_text(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const char *op, int *request);
+
+int ncmpi_bput_vara_short(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const short *op, int *request);
+
+int ncmpi_bput_vara_int(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const int *op, int *request);
+
+int ncmpi_bput_vara_float(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const float *op, int *request);
+
+int ncmpi_bput_vara_double(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const double *op, int *request);
+
+int ncmpi_bput_vara_longlong(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const long long *op, int *request);
+
+/* Begin Skip Prototypes for Fortran binding */
+/* skip types: uchar, ubyte, ushort, uint, long, ulonglong string */
+
+int ncmpi_iput_vara_uchar(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const unsigned char *op,
+ int *request);
+
+int ncmpi_iput_vara_ushort(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const unsigned short *op,
+ int *request);
+
+int ncmpi_iput_vara_uint(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const unsigned int *op,
+ int *request);
+
+int ncmpi_iput_vara_long(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const long *op, int *request);
+
+int ncmpi_iput_vara_ulonglong(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const unsigned long long *op,
+ int *request);
+
+int ncmpi_iget_vara_uchar(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], unsigned char *ip, int *request);
+
+int ncmpi_iget_vara_ushort(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], unsigned short *ip, int *request);
+
+int ncmpi_iget_vara_uint(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], unsigned int *ip, int *request);
+
+int ncmpi_iget_vara_long(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], long *ip, int *request);
+
+int ncmpi_iget_vara_ulonglong(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], unsigned long long *ip, int *request);
+
+int ncmpi_bput_vara_uchar(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const unsigned char *op,
+ int *request);
+
+int ncmpi_bput_vara_ushort(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const unsigned short *op,
+ int *request);
+
+int ncmpi_bput_vara_uint(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const unsigned int *op,
+ int *request);
+
+int ncmpi_bput_vara_long(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const long *op, int *request);
+
+int ncmpi_bput_vara_ulonglong(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const unsigned long long *op,
+ int *request);
+
+/* End Skip Prototypes for Fortran binding */
+
+/* End {iput,iget,bput}_vara */
+
+/* Begin {iput,iget,bput}_vars */
+
+int ncmpi_iput_vars(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const void *buf, MPI_Offset bufcount,
+ MPI_Datatype buftype, int *request);
+
+int ncmpi_iput_vars_schar(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const signed char *op, int *request);
+
+int ncmpi_iput_vars_text(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const char *op, int *request);
+
+int ncmpi_iput_vars_short(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const short *op, int *request);
+
+int ncmpi_iput_vars_int(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const int *op, int *request);
+
+int ncmpi_iput_vars_float(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const float *op, int *request);
+
+int ncmpi_iput_vars_double(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const double *op, int *request);
+
+int ncmpi_iput_vars_longlong(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const long long *op, int *request);
+
+int ncmpi_iget_vars(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ void *buf, MPI_Offset bufcount, MPI_Datatype buftype,
+ int *request);
+
+int ncmpi_iget_vars_schar(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ signed char *ip, int *request);
+
+int ncmpi_iget_vars_text(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ char *ip, int *request);
+
+int ncmpi_iget_vars_short(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ short *ip, int *request);
+
+int ncmpi_iget_vars_int(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ int *ip, int *request);
+
+int ncmpi_iget_vars_float(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ float *ip, int *request);
+
+int ncmpi_iget_vars_double(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ double *ip, int *request);
+
+int ncmpi_iget_vars_longlong(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ long long *ip, int *request);
+
+int ncmpi_bput_vars(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const void *buf, MPI_Offset bufcount,
+ MPI_Datatype buftype, int *request);
+
+int ncmpi_bput_vars_schar(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const signed char *op, int *request);
+
+int ncmpi_bput_vars_text(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const char *op, int *request);
+
+int ncmpi_bput_vars_short(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const short *op, int *request);
+
+int ncmpi_bput_vars_int(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const int *op, int *request);
+
+int ncmpi_bput_vars_float(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const float *op, int *request);
+
+int ncmpi_bput_vars_double(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const double *op, int *request);
+
+int ncmpi_bput_vars_longlong(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const long long *op, int *request);
+
+/* Begin Skip Prototypes for Fortran binding */
+/* skip types: uchar, ubyte, ushort, uint, long, ulonglong string */
+
+int ncmpi_iput_vars_uchar(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const unsigned char *op, int *request);
+
+int ncmpi_iput_vars_ushort(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const unsigned short *op, int *request);
+
+int ncmpi_iput_vars_uint(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const unsigned int *op, int *request);
+
+int ncmpi_iput_vars_long(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const long *op, int *request);
+
+int ncmpi_iput_vars_ulonglong(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const unsigned long long *op, int *request);
+
+int ncmpi_iget_vars_uchar(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ unsigned char *ip, int *request);
+
+int ncmpi_iget_vars_ushort(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ unsigned short *ip, int *request);
+
+int ncmpi_iget_vars_uint(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ unsigned int *ip, int *request);
+
+int ncmpi_iget_vars_long(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ long *ip, int *request);
+
+int ncmpi_iget_vars_ulonglong(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ unsigned long long *ip, int *request);
+
+int ncmpi_bput_vars_uchar(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const unsigned char *op, int *request);
+
+int ncmpi_bput_vars_ushort(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const unsigned short *op, int *request);
+
+int ncmpi_bput_vars_uint(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const unsigned int *op, int *request);
+
+int ncmpi_bput_vars_long(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const long *op, int *request);
+
+int ncmpi_bput_vars_ulonglong(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const unsigned long long *op, int *request);
+
+/* End Skip Prototypes for Fortran binding */
+
+/* End {iput,iget,bput}_vars */
+
+/* Begin {iput,iget,bput}_varm */
+
+int ncmpi_iput_varm(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], const void *buf,
+ MPI_Offset bufcount, MPI_Datatype buftype, int *request);
+
+int ncmpi_iput_varm_schar(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], const signed char *op,
+ int *request);
+
+int ncmpi_iput_varm_text(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], const char *op, int *request);
+
+int ncmpi_iput_varm_short(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], const short *op, int *request);
+
+int ncmpi_iput_varm_int(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], const int *op, int *request);
+
+int ncmpi_iput_varm_float(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], const float *op, int *request);
+
+int ncmpi_iput_varm_double(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], const double *op, int *request);
+
+int ncmpi_iput_varm_longlong(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], const long long *op, int *request);
+
+int ncmpi_iget_varm(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], void *buf, MPI_Offset bufcount,
+ MPI_Datatype buftype, int *request);
+
+int ncmpi_iget_varm_schar(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], signed char *ip, int *request);
+
+int ncmpi_iget_varm_text(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], char *ip, int *request);
+
+int ncmpi_iget_varm_short(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], short *ip, int *request);
+
+int ncmpi_iget_varm_int(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], int *ip, int *request);
+
+int ncmpi_iget_varm_float(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], float *ip, int *request);
+
+int ncmpi_iget_varm_double(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], double *ip, int *request);
+
+int ncmpi_iget_varm_longlong(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], long long *ip, int *request);
+
+int ncmpi_bput_varm(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], const void *buf,
+ MPI_Offset bufcount, MPI_Datatype buftype, int *request);
+
+int ncmpi_bput_varm_schar(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], const signed char *op,
+ int *request);
+
+int ncmpi_bput_varm_text(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], const char *op, int *request);
+
+int ncmpi_bput_varm_short(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], const short *op, int *request);
+
+int ncmpi_bput_varm_int(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], const int *op, int *request);
+
+int ncmpi_bput_varm_float(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], const float *op, int *request);
+
+int ncmpi_bput_varm_double(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], const double *op, int *request);
+
+int ncmpi_bput_varm_longlong(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], const long long *op, int *request);
+
+/* Begin Skip Prototypes for Fortran binding */
+/* skip types: uchar, ubyte, ushort, uint, long, ulonglong string */
+
+int ncmpi_iput_varm_uchar(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], const unsigned char *op,
+ int *request);
+
+int ncmpi_iput_varm_ushort(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], const unsigned short *op,
+ int *request);
+
+int ncmpi_iput_varm_uint(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], const unsigned int *op,
+ int *request);
+
+int ncmpi_iput_varm_long(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], const long *op, int *request);
+
+int ncmpi_iput_varm_ulonglong(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], const unsigned long long *op,
+ int *request);
+
+int ncmpi_iget_varm_uchar(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], unsigned char *ip, int *request);
+
+int ncmpi_iget_varm_ushort(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], unsigned short *ip, int *request);
+
+int ncmpi_iget_varm_uint(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], unsigned int *ip, int *request);
+
+int ncmpi_iget_varm_long(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], long *ip, int *request);
+
+int ncmpi_iget_varm_ulonglong(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], unsigned long long *ip, int *request);
+
+int ncmpi_bput_varm_uchar(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], const unsigned char *op,
+ int *request);
+
+int ncmpi_bput_varm_ushort(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], const unsigned short *op,
+ int *request);
+
+int ncmpi_bput_varm_uint(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], const unsigned int *op,
+ int *request);
+
+int ncmpi_bput_varm_long(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], const long *op, int *request);
+
+int ncmpi_bput_varm_ulonglong(int ncid, int varid, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ const MPI_Offset imap[], const unsigned long long *op,
+ int *request);
+
+/* End Skip Prototypes for Fortran binding */
+
+/* End {iput,iget,bput}_varm */
+
+/* Begin of nonblocking {iput,iget}_varn{kind} */
+
+int ncmpi_iput_varn(int ncid, int varid, int num, MPI_Offset* const starts[],
+ MPI_Offset* const counts[], const void *buf, MPI_Offset bufcount,
+ MPI_Datatype buftype, int *request);
+
+int ncmpi_iget_varn(int ncid, int varid, int num, MPI_Offset* const starts[],
+ MPI_Offset* const counts[], void *buf, MPI_Offset bufcount,
+ MPI_Datatype buftype, int *request);
+
+int ncmpi_iput_varn_text(int ncid, int varid, int num,
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ const char *buf, int *request);
+
+int ncmpi_iput_varn_schar(int ncid, int varid, int num,
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ const signed char *buf, int *request);
+
+int ncmpi_iput_varn_short(int ncid, int varid, int num,
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ const short *buf, int *request);
+
+int ncmpi_iput_varn_int(int ncid, int varid, int num,
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ const int *buf, int *request);
+
+int ncmpi_iput_varn_float(int ncid, int varid, int num,
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ const float *buf, int *request);
+
+int ncmpi_iput_varn_double(int ncid, int varid, int num,
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ const double *buf, int *request);
+
+int ncmpi_iput_varn_longlong(int ncid, int varid, int num,
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ const long long *buf, int *request);
+
+
+/* Begin Skip Prototypes for Fortran binding */
+/* skip types: uchar, ubyte, ushort, uint, long, ulonglong string */
+
+int ncmpi_iput_varn_uchar(int ncid, int varid, int num,
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ const unsigned char *buf, int *request);
+
+int ncmpi_iput_varn_ushort(int ncid, int varid, int num,
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ const unsigned short *buf, int *request);
+
+int ncmpi_iput_varn_uint(int ncid, int varid, int num,
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ const unsigned int *buf, int *request);
+
+int ncmpi_iput_varn_long(int ncid, int varid, int num,
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ const long *buf, int *request);
+
+int ncmpi_iput_varn_ulonglong(int ncid, int varid, int num,
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ const unsigned long long *buf, int *request);
+
+/* End Skip Prototypes for Fortran binding */
+
+int ncmpi_iget_varn_text(int ncid, int varid, int num,
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ char *buf, int *request);
+
+int ncmpi_iget_varn_schar(int ncid, int varid, int num,
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ signed char *buf, int *request);
+
+int ncmpi_iget_varn_short(int ncid, int varid, int num,
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ short *buf, int *request);
+
+int ncmpi_iget_varn_int(int ncid, int varid, int num,
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ int *buf, int *request);
+
+int ncmpi_iget_varn_float(int ncid, int varid, int num,
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ float *buf, int *request);
+
+int ncmpi_iget_varn_double(int ncid, int varid, int num,
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ double *buf, int *request);
+
+int ncmpi_iget_varn_longlong(int ncid, int varid, int num,
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ long long *buf, int *request);
+
+
+/* Begin Skip Prototypes for Fortran binding */
+/* skip types: uchar, ubyte, ushort, uint, long, ulonglong string */
+
+int ncmpi_iget_varn_uchar(int ncid, int varid, int num,
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ unsigned char *buf, int *request);
+
+int ncmpi_iget_varn_ushort(int ncid, int varid, int num,
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ unsigned short *buf, int *request);
+
+int ncmpi_iget_varn_uint(int ncid, int varid, int num,
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ unsigned int *buf, int *request);
+
+int ncmpi_iget_varn_long(int ncid, int varid, int num,
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ long *buf, int *request);
+
+int ncmpi_iget_varn_ulonglong(int ncid, int varid, int num,
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ unsigned long long *buf, int *request);
+
+/* End Skip Prototypes for Fortran binding */
+
+/* End of {iput,iget}_varn{kind} */
+
+/* Begin of nonblocking bput_varn{kind} */
+
+int ncmpi_bput_varn(int ncid, int varid, int num, MPI_Offset* const starts[],
+ MPI_Offset* const counts[], const void *buf, MPI_Offset bufcount,
+ MPI_Datatype buftype, int *request);
+
+int ncmpi_bput_varn_text(int ncid, int varid, int num,
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ const char *buf, int *request);
+
+int ncmpi_bput_varn_schar(int ncid, int varid, int num,
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ const signed char *buf, int *request);
+
+int ncmpi_bput_varn_short(int ncid, int varid, int num,
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ const short *buf, int *request);
+
+int ncmpi_bput_varn_int(int ncid, int varid, int num,
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ const int *buf, int *request);
+
+int ncmpi_bput_varn_float(int ncid, int varid, int num,
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ const float *buf, int *request);
+
+int ncmpi_bput_varn_double(int ncid, int varid, int num,
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ const double *buf, int *request);
+
+int ncmpi_bput_varn_longlong(int ncid, int varid, int num,
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ const long long *buf, int *request);
+
+
+/* Begin Skip Prototypes for Fortran binding */
+/* skip types: uchar, ubyte, ushort, uint, long, ulonglong string */
+
+int ncmpi_bput_varn_uchar(int ncid, int varid, int num,
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ const unsigned char *buf, int *request);
+
+int ncmpi_bput_varn_ushort(int ncid, int varid, int num,
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ const unsigned short *buf, int *request);
+
+int ncmpi_bput_varn_uint(int ncid, int varid, int num,
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ const unsigned int *buf, int *request);
+
+int ncmpi_bput_varn_long(int ncid, int varid, int num,
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ const long *buf, int *request);
+
+int ncmpi_bput_varn_ulonglong(int ncid, int varid, int num,
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ const unsigned long long *buf, int *request);
+
+/* End Skip Prototypes for Fortran binding */
+
+/* End of bput_varn{kind} */
+
+/* End non-blocking data access functions */
+
+/* Begin Skip Prototypes for Fortran binding */
+/* skip all mput/mget APIs as Fortran cannot handle array of buffers */
+
+int ncmpi_mput_var(int ncid, int num, int varids[], void *bufs[],
+ MPI_Offset bufcounts[], MPI_Datatype datatypes[]);
+
+int ncmpi_mput_var_all(int ncid, int num, int varids[], void *bufs[],
+ MPI_Offset bufcounts[], MPI_Datatype datatypes[]);
+
+int ncmpi_mput_var_text(int ncid, int num, int varids[],
+ char *bufs[]);
+
+int ncmpi_mput_var_schar(int ncid, int num, int varids[],
+ signed char *bufs[]);
+
+int ncmpi_mput_var_uchar(int ncid, int num, int varids[],
+ unsigned char *bufs[]);
+
+int ncmpi_mput_var_short(int ncid, int num, int varids[],
+ short *bufs[]);
+
+int ncmpi_mput_var_ushort(int ncid, int num, int varids[],
+ unsigned short *bufs[]);
+
+int ncmpi_mput_var_int(int ncid, int num, int varids[],
+ int *bufs[]);
+
+int ncmpi_mput_var_uint(int ncid, int num, int varids[],
+ unsigned int *bufs[]);
+
+int ncmpi_mput_var_long(int ncid, int num, int varids[],
+ long *bufs[]);
+
+int ncmpi_mput_var_float(int ncid, int num, int varids[],
+ float *bufs[]);
+
+int ncmpi_mput_var_double(int ncid, int num, int varids[],
+ double *bufs[]);
+
+int ncmpi_mput_var_longlong(int ncid, int num, int varids[],
+ long long *bufs[]);
+
+int ncmpi_mput_var_ulonglong(int ncid, int num, int varids[],
+ unsigned long long *bufs[]);
+
+
+int ncmpi_mput_var_text_all(int ncid, int num, int varids[],
+ char *bufs[]);
+
+int ncmpi_mput_var_schar_all(int ncid, int num, int varids[],
+ signed char *bufs[]);
+
+int ncmpi_mput_var_uchar_all(int ncid, int num, int varids[],
+ unsigned char *bufs[]);
+
+int ncmpi_mput_var_short_all(int ncid, int num, int varids[],
+ short *bufs[]);
+
+int ncmpi_mput_var_ushort_all(int ncid, int num, int varids[],
+ unsigned short *bufs[]);
+
+int ncmpi_mput_var_int_all(int ncid, int num, int varids[],
+ int *bufs[]);
+
+int ncmpi_mput_var_uint_all(int ncid, int num, int varids[],
+ unsigned int *bufs[]);
+
+int ncmpi_mput_var_long_all(int ncid, int num, int varids[],
+ long *bufs[]);
+
+int ncmpi_mput_var_float_all(int ncid, int num, int varids[],
+ float *bufs[]);
+
+int ncmpi_mput_var_double_all(int ncid, int num, int varids[],
+ double *bufs[]);
+
+int ncmpi_mput_var_longlong_all(int ncid, int num, int varids[],
+ long long *bufs[]);
+
+int ncmpi_mput_var_ulonglong_all(int ncid, int num, int varids[],
+ unsigned long long *bufs[]);
+
+
+int ncmpi_mput_var1(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], void *bufs[],
+ MPI_Offset bufcounts[], MPI_Datatype datatypes[]);
+
+int ncmpi_mput_var1_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], void *bufs[],
+ MPI_Offset bufcounts[], MPI_Datatype datatypes[]);
+
+int ncmpi_mput_var1_text(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], char *bufs[]);
+
+int ncmpi_mput_var1_schar(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], signed char *bufs[]);
+
+int ncmpi_mput_var1_uchar(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], unsigned char *bufs[]);
+
+int ncmpi_mput_var1_short(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], short *bufs[]);
+
+int ncmpi_mput_var1_ushort(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], unsigned short *bufs[]);
+
+int ncmpi_mput_var1_int(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], int *bufs[]);
+
+int ncmpi_mput_var1_uint(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], unsigned int *bufs[]);
+
+int ncmpi_mput_var1_long(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], long *bufs[]);
+
+int ncmpi_mput_var1_float(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], float *bufs[]);
+
+int ncmpi_mput_var1_double(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], double *bufs[]);
+
+int ncmpi_mput_var1_longlong(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], long long *bufs[]);
+
+int ncmpi_mput_var1_ulonglong(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], unsigned long long *bufs[]);
+
+
+int ncmpi_mput_var1_text_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], char *bufs[]);
+
+int ncmpi_mput_var1_schar_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], signed char *bufs[]);
+
+int ncmpi_mput_var1_uchar_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], unsigned char *bufs[]);
+
+int ncmpi_mput_var1_short_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], short *bufs[]);
+
+int ncmpi_mput_var1_ushort_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], unsigned short *bufs[]);
+
+int ncmpi_mput_var1_int_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], int *bufs[]);
+
+int ncmpi_mput_var1_uint_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], unsigned int *bufs[]);
+
+int ncmpi_mput_var1_long_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], long *bufs[]);
+
+int ncmpi_mput_var1_float_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], float *bufs[]);
+
+int ncmpi_mput_var1_double_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], double *bufs[]);
+
+int ncmpi_mput_var1_longlong_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], long long *bufs[]);
+
+int ncmpi_mput_var1_ulonglong_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], unsigned long long *bufs[]);
+
+
+int ncmpi_mput_vara(int ncid, int num, int varids[], MPI_Offset* const starts[],
+ MPI_Offset* const counts[], void *bufs[],
+ MPI_Offset bufcounts[], MPI_Datatype datatypes[]);
+
+int ncmpi_mput_vara_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ void *bufs[], MPI_Offset bufcounts[],
+ MPI_Datatype datatypes[]);
+
+int ncmpi_mput_vara_text(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ char *bufs[]);
+
+int ncmpi_mput_vara_schar(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ signed char *bufs[]);
+
+int ncmpi_mput_vara_uchar(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ unsigned char *bufs[]);
+
+int ncmpi_mput_vara_short(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ short *bufs[]);
+
+int ncmpi_mput_vara_ushort(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ unsigned short *bufs[]);
+
+int ncmpi_mput_vara_int(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ int *bufs[]);
+
+int ncmpi_mput_vara_uint(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ unsigned int *bufs[]);
+
+int ncmpi_mput_vara_long(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ long *bufs[]);
+
+int ncmpi_mput_vara_float(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ float *bufs[]);
+
+int ncmpi_mput_vara_double(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ double *bufs[]);
+
+int ncmpi_mput_vara_longlong(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ long long *bufs[]);
+
+int ncmpi_mput_vara_ulonglong(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ unsigned long long *bufs[]);
+
+
+int ncmpi_mput_vara_text_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ char *bufs[]);
+
+int ncmpi_mput_vara_schar_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ signed char *bufs[]);
+
+int ncmpi_mput_vara_uchar_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ unsigned char *bufs[]);
+
+int ncmpi_mput_vara_short_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ short *bufs[]);
+
+int ncmpi_mput_vara_ushort_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ unsigned short *bufs[]);
+
+int ncmpi_mput_vara_int_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ int *bufs[]);
+
+int ncmpi_mput_vara_uint_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ unsigned int *bufs[]);
+
+int ncmpi_mput_vara_long_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ long *bufs[]);
+
+int ncmpi_mput_vara_float_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ float *bufs[]);
+
+int ncmpi_mput_vara_double_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ double *bufs[]);
+
+int ncmpi_mput_vara_longlong_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ long long *bufs[]);
+
+int ncmpi_mput_vara_ulonglong_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ unsigned long long *bufs[]);
+
+
+int ncmpi_mput_vars(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], void *bufs[],
+ MPI_Offset bufcounts[], MPI_Datatype datatypes[]);
+
+int ncmpi_mput_vars_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], void *bufs[],
+ MPI_Offset bufcounts[], MPI_Datatype datatypes[]);
+
+int ncmpi_mput_vars_text(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], char *bufs[]);
+
+int ncmpi_mput_vars_schar(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], signed char *bufs[]);
+
+int ncmpi_mput_vars_uchar(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], unsigned char *bufs[]);
+
+int ncmpi_mput_vars_short(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], short *bufs[]);
+
+int ncmpi_mput_vars_ushort(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], unsigned short *bufs[]);
+
+int ncmpi_mput_vars_int(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], int *bufs[]);
+
+int ncmpi_mput_vars_uint(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], unsigned int *bufs[]);
+
+int ncmpi_mput_vars_long(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], long *bufs[]);
+
+int ncmpi_mput_vars_float(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], float *bufs[]);
+
+int ncmpi_mput_vars_double(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], double *bufs[]);
+
+int ncmpi_mput_vars_longlong(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], long long *bufs[]);
+
+int ncmpi_mput_vars_ulonglong(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], unsigned long long *bufs[]);
+
+
+int ncmpi_mput_vars_text_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], char *bufs[]);
+
+int ncmpi_mput_vars_schar_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], signed char *bufs[]);
+
+int ncmpi_mput_vars_uchar_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], unsigned char *bufs[]);
+
+int ncmpi_mput_vars_short_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], short *bufs[]);
+
+int ncmpi_mput_vars_ushort_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], unsigned short *bufs[]);
+
+int ncmpi_mput_vars_int_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], int *bufs[]);
+
+int ncmpi_mput_vars_uint_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], unsigned int *bufs[]);
+
+int ncmpi_mput_vars_long_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], long *bufs[]);
+
+int ncmpi_mput_vars_float_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], float *bufs[]);
+
+int ncmpi_mput_vars_double_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], double *bufs[]);
+
+int ncmpi_mput_vars_longlong_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], long long *bufs[]);
+
+int ncmpi_mput_vars_ulonglong_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], unsigned long long *bufs[]);
+
+
+int ncmpi_mput_varm(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], MPI_Offset* const imaps[],
+ void *bufs[], MPI_Offset bufcounts[],
+ MPI_Datatype datatypes[]);
+
+int ncmpi_mput_varm_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], MPI_Offset* const imaps[],
+ void *bufs[], MPI_Offset bufcounts[],
+ MPI_Datatype datatypes[]);
+
+int ncmpi_mput_varm_text(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], MPI_Offset* const imaps[],
+ char *bufs[]);
+
+int ncmpi_mput_varm_schar(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], MPI_Offset* const imaps[],
+ signed char *bufs[]);
+
+int ncmpi_mput_varm_uchar(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], MPI_Offset* const imaps[],
+ unsigned char *bufs[]);
+
+int ncmpi_mput_varm_short(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], MPI_Offset* const imaps[],
+ short *bufs[]);
+
+int ncmpi_mput_varm_ushort(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], MPI_Offset* const imaps[],
+ unsigned short *bufs[]);
+
+int ncmpi_mput_varm_int(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], MPI_Offset* const imaps[],
+ int *bufs[]);
+
+int ncmpi_mput_varm_uint(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], MPI_Offset* const imaps[],
+ unsigned int *bufs[]);
+
+int ncmpi_mput_varm_long(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], MPI_Offset* const imaps[],
+ long *bufs[]);
+
+int ncmpi_mput_varm_float(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], MPI_Offset* const imaps[],
+ float *bufs[]);
+
+int ncmpi_mput_varm_double(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], MPI_Offset* const imaps[],
+ double *bufs[]);
+
+int ncmpi_mput_varm_longlong(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], MPI_Offset* const imaps[],
+ long long *bufs[]);
+
+int ncmpi_mput_varm_ulonglong(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], MPI_Offset* const imaps[],
+ unsigned long long *bufs[]);
+
+
+int ncmpi_mput_varm_text_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], MPI_Offset* const imaps[],
+ char *bufs[]);
+
+int ncmpi_mput_varm_schar_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], MPI_Offset* const imaps[],
+ signed char *bufs[]);
+
+int ncmpi_mput_varm_uchar_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], MPI_Offset* const imaps[],
+ unsigned char *bufs[]);
+
+int ncmpi_mput_varm_short_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], MPI_Offset* const imaps[],
+ short *bufs[]);
+
+int ncmpi_mput_varm_ushort_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], MPI_Offset* const imaps[],
+ unsigned short *bufs[]);
+
+int ncmpi_mput_varm_int_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], MPI_Offset* const imaps[],
+ int *bufs[]);
+
+int ncmpi_mput_varm_uint_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], MPI_Offset* const imaps[],
+ unsigned int *bufs[]);
+
+int ncmpi_mput_varm_long_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], MPI_Offset* const imaps[],
+ long *bufs[]);
+
+int ncmpi_mput_varm_float_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], MPI_Offset* const imaps[],
+ float *bufs[]);
+
+int ncmpi_mput_varm_double_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], MPI_Offset* const imaps[],
+ double *bufs[]);
+
+int ncmpi_mput_varm_longlong_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], MPI_Offset* const imaps[],
+ long long *bufs[]);
+
+int ncmpi_mput_varm_ulonglong_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], MPI_Offset* const imaps[],
+ unsigned long long *bufs[]);
+
+
+int ncmpi_mget_var(int ncid, int num, int varids[], void *bufs[],
+ MPI_Offset bufcounts[], MPI_Datatype datatypes[]);
+
+int ncmpi_mget_var_all(int ncid, int num, int varids[], void *bufs[],
+ MPI_Offset bufcounts[], MPI_Datatype datatypes[]);
+
+int ncmpi_mget_var_text(int ncid, int num, int varids[],
+ char *bufs[]);
+
+int ncmpi_mget_var_schar(int ncid, int num, int varids[],
+ signed char *bufs[]);
+
+int ncmpi_mget_var_uchar(int ncid, int num, int varids[],
+ unsigned char *bufs[]);
+
+int ncmpi_mget_var_short(int ncid, int num, int varids[],
+ short *bufs[]);
+
+int ncmpi_mget_var_ushort(int ncid, int num, int varids[],
+ unsigned short *bufs[]);
+
+int ncmpi_mget_var_int(int ncid, int num, int varids[],
+ int *bufs[]);
+
+int ncmpi_mget_var_uint(int ncid, int num, int varids[],
+ unsigned int *bufs[]);
+
+int ncmpi_mget_var_long(int ncid, int num, int varids[],
+ long *bufs[]);
+
+int ncmpi_mget_var_float(int ncid, int num, int varids[],
+ float *bufs[]);
+
+int ncmpi_mget_var_double(int ncid, int num, int varids[],
+ double *bufs[]);
+
+int ncmpi_mget_var_longlong(int ncid, int num, int varids[],
+ long long *bufs[]);
+
+int ncmpi_mget_var_ulonglong(int ncid, int num, int varids[],
+ unsigned long long *bufs[]);
+
+
+int ncmpi_mget_var_text_all(int ncid, int num, int varids[],
+ char *bufs[]);
+
+int ncmpi_mget_var_schar_all(int ncid, int num, int varids[],
+ signed char *bufs[]);
+
+int ncmpi_mget_var_uchar_all(int ncid, int num, int varids[],
+ unsigned char *bufs[]);
+
+int ncmpi_mget_var_short_all(int ncid, int num, int varids[],
+ short *bufs[]);
+
+int ncmpi_mget_var_ushort_all(int ncid, int num, int varids[],
+ unsigned short *bufs[]);
+
+int ncmpi_mget_var_int_all(int ncid, int num, int varids[],
+ int *bufs[]);
+
+int ncmpi_mget_var_uint_all(int ncid, int num, int varids[],
+ unsigned int *bufs[]);
+
+int ncmpi_mget_var_long_all(int ncid, int num, int varids[],
+ long *bufs[]);
+
+int ncmpi_mget_var_float_all(int ncid, int num, int varids[],
+ float *bufs[]);
+
+int ncmpi_mget_var_double_all(int ncid, int num, int varids[],
+ double *bufs[]);
+
+int ncmpi_mget_var_longlong_all(int ncid, int num, int varids[],
+ long long *bufs[]);
+
+int ncmpi_mget_var_ulonglong_all(int ncid, int num, int varids[],
+ unsigned long long *bufs[]);
+
+
+int ncmpi_mget_var1(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], void *bufs[],
+ MPI_Offset bufcounts[], MPI_Datatype datatypes[]);
+
+int ncmpi_mget_var1_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], void *bufs[],
+ MPI_Offset bufcounts[], MPI_Datatype datatypes[]);
+
+int ncmpi_mget_var1_text(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], char *bufs[]);
+
+int ncmpi_mget_var1_schar(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], signed char *bufs[]);
+
+int ncmpi_mget_var1_uchar(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], unsigned char *bufs[]);
+
+int ncmpi_mget_var1_short(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], short *bufs[]);
+
+int ncmpi_mget_var1_ushort(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], unsigned short *bufs[]);
+
+int ncmpi_mget_var1_int(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], int *bufs[]);
+
+int ncmpi_mget_var1_uint(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], unsigned int *bufs[]);
+
+int ncmpi_mget_var1_long(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], long *bufs[]);
+
+int ncmpi_mget_var1_float(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], float *bufs[]);
+
+int ncmpi_mget_var1_double(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], double *bufs[]);
+
+int ncmpi_mget_var1_longlong(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], long long *bufs[]);
+
+int ncmpi_mget_var1_ulonglong(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], unsigned long long *bufs[]);
+
+
+int ncmpi_mget_var1_text_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], char *bufs[]);
+
+int ncmpi_mget_var1_schar_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], signed char *bufs[]);
+
+int ncmpi_mget_var1_uchar_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], unsigned char *bufs[]);
+
+int ncmpi_mget_var1_short_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], short *bufs[]);
+
+int ncmpi_mget_var1_ushort_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], unsigned short *bufs[]);
+
+int ncmpi_mget_var1_int_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], int *bufs[]);
+
+int ncmpi_mget_var1_uint_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], unsigned int *bufs[]);
+
+int ncmpi_mget_var1_long_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], long *bufs[]);
+
+int ncmpi_mget_var1_float_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], float *bufs[]);
+
+int ncmpi_mget_var1_double_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], double *bufs[]);
+
+int ncmpi_mget_var1_longlong_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], long long *bufs[]);
+
+int ncmpi_mget_var1_ulonglong_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], unsigned long long *bufs[]);
+
+
+int ncmpi_mget_vara(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ void *bufs[], MPI_Offset bufcounts[],
+ MPI_Datatype datatypes[]);
+
+int ncmpi_mget_vara_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ void *bufs[], MPI_Offset bufcounts[],
+ MPI_Datatype datatypes[]);
+
+int ncmpi_mget_vara_text(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ char *bufs[]);
+
+int ncmpi_mget_vara_schar(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ signed char *bufs[]);
+
+int ncmpi_mget_vara_uchar(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ unsigned char *bufs[]);
+
+int ncmpi_mget_vara_short(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ short *bufs[]);
+
+int ncmpi_mget_vara_ushort(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ unsigned short *bufs[]);
+
+int ncmpi_mget_vara_int(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ int *bufs[]);
+
+int ncmpi_mget_vara_uint(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ unsigned int *bufs[]);
+
+int ncmpi_mget_vara_long(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ long *bufs[]);
+
+int ncmpi_mget_vara_float(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ float *bufs[]);
+
+int ncmpi_mget_vara_double(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ double *bufs[]);
+
+int ncmpi_mget_vara_longlong(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ long long *bufs[]);
+
+int ncmpi_mget_vara_ulonglong(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ unsigned long long *bufs[]);
+
+
+int ncmpi_mget_vara_text_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ char *bufs[]);
+
+int ncmpi_mget_vara_schar_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ signed char *bufs[]);
+
+int ncmpi_mget_vara_uchar_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ unsigned char *bufs[]);
+
+int ncmpi_mget_vara_short_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ short *bufs[]);
+
+int ncmpi_mget_vara_ushort_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ unsigned short *bufs[]);
+
+int ncmpi_mget_vara_int_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ int *bufs[]);
+
+int ncmpi_mget_vara_uint_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ unsigned int *bufs[]);
+
+int ncmpi_mget_vara_long_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ long *bufs[]);
+
+int ncmpi_mget_vara_float_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ float *bufs[]);
+
+int ncmpi_mget_vara_double_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ double *bufs[]);
+
+int ncmpi_mget_vara_longlong_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ long long *bufs[]);
+
+int ncmpi_mget_vara_ulonglong_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ unsigned long long *bufs[]);
+
+
+int ncmpi_mget_vars(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], void *bufs[],
+ MPI_Offset bufcounts[], MPI_Datatype datatypes[]);
+
+int ncmpi_mget_vars_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], void *bufs[],
+ MPI_Offset bufcounts[], MPI_Datatype datatypes[]);
+
+int ncmpi_mget_vars_text(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], char *bufs[]);
+
+int ncmpi_mget_vars_schar(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], signed char *bufs[]);
+
+int ncmpi_mget_vars_uchar(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], unsigned char *bufs[]);
+
+int ncmpi_mget_vars_short(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], short *bufs[]);
+
+int ncmpi_mget_vars_ushort(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], unsigned short *bufs[]);
+
+int ncmpi_mget_vars_int(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], int *bufs[]);
+
+int ncmpi_mget_vars_uint(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], unsigned int *bufs[]);
+
+int ncmpi_mget_vars_long(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], long *bufs[]);
+
+int ncmpi_mget_vars_float(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], float *bufs[]);
+
+int ncmpi_mget_vars_double(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], double *bufs[]);
+
+int ncmpi_mget_vars_longlong(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], long long *bufs[]);
+
+int ncmpi_mget_vars_ulonglong(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], unsigned long long *bufs[]);
+
+
+int ncmpi_mget_vars_text_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], char *bufs[]);
+
+int ncmpi_mget_vars_schar_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], signed char *bufs[]);
+
+int ncmpi_mget_vars_uchar_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], unsigned char *bufs[]);
+
+int ncmpi_mget_vars_short_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], short *bufs[]);
+
+int ncmpi_mget_vars_ushort_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], unsigned short *bufs[]);
+
+int ncmpi_mget_vars_int_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], int *bufs[]);
+
+int ncmpi_mget_vars_uint_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], unsigned int *bufs[]);
+
+int ncmpi_mget_vars_long_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], long *bufs[]);
+
+int ncmpi_mget_vars_float_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], float *bufs[]);
+
+int ncmpi_mget_vars_double_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], double *bufs[]);
+
+int ncmpi_mget_vars_longlong_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], long long *bufs[]);
+
+int ncmpi_mget_vars_ulonglong_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], unsigned long long *bufs[]);
+
+
+int ncmpi_mget_varm(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], MPI_Offset* const imaps[],
+ void *bufs[], MPI_Offset bufcounts[],
+ MPI_Datatype datatypes[]);
+
+int ncmpi_mget_varm_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], MPI_Offset* const imaps[],
+ void *bufs[], MPI_Offset bufcounts[],
+ MPI_Datatype datatypes[]);
+
+int ncmpi_mget_varm_text(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], MPI_Offset* const imaps[],
+ char *bufs[]);
+
+int ncmpi_mget_varm_schar(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], MPI_Offset* const imaps[],
+ signed char *bufs[]);
+
+int ncmpi_mget_varm_uchar(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], MPI_Offset* const imaps[],
+ unsigned char *bufs[]);
+
+int ncmpi_mget_varm_short(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], MPI_Offset* const imaps[],
+ short *bufs[]);
+
+int ncmpi_mget_varm_ushort(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], MPI_Offset* const imaps[],
+ unsigned short *bufs[]);
+
+int ncmpi_mget_varm_int(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], MPI_Offset* const imaps[],
+ int *bufs[]);
+
+int ncmpi_mget_varm_uint(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], MPI_Offset* const imaps[],
+ unsigned int *bufs[]);
+
+int ncmpi_mget_varm_long(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], MPI_Offset* const imaps[],
+ long *bufs[]);
+
+int ncmpi_mget_varm_float(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], MPI_Offset* const imaps[],
+ float *bufs[]);
+
+int ncmpi_mget_varm_double(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], MPI_Offset* const imaps[],
+ double *bufs[]);
+
+int ncmpi_mget_varm_longlong(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], MPI_Offset* const imaps[],
+ long long *bufs[]);
+
+int ncmpi_mget_varm_ulonglong(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], MPI_Offset* const imaps[],
+ unsigned long long *bufs[]);
+
+
+int ncmpi_mget_varm_text_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], MPI_Offset* const imaps[],
+ char *bufs[]);
+
+int ncmpi_mget_varm_schar_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], MPI_Offset* const imaps[],
+ signed char *bufs[]);
+
+int ncmpi_mget_varm_uchar_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], MPI_Offset* const imaps[],
+ unsigned char *bufs[]);
+
+int ncmpi_mget_varm_short_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], MPI_Offset* const imaps[],
+ short *bufs[]);
+
+int ncmpi_mget_varm_ushort_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], MPI_Offset* const imaps[],
+ unsigned short *bufs[]);
+
+int ncmpi_mget_varm_int_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], MPI_Offset* const imaps[],
+ int *bufs[]);
+
+int ncmpi_mget_varm_uint_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], MPI_Offset* const imaps[],
+ unsigned int *bufs[]);
+
+int ncmpi_mget_varm_long_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], MPI_Offset* const imaps[],
+ long *bufs[]);
+
+int ncmpi_mget_varm_float_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], MPI_Offset* const imaps[],
+ float *bufs[]);
+
+int ncmpi_mget_varm_double_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], MPI_Offset* const imaps[],
+ double *bufs[]);
+
+int ncmpi_mget_varm_longlong_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], MPI_Offset* const imaps[],
+ long long *bufs[]);
+
+int ncmpi_mget_varm_ulonglong_all(int ncid, int num, int varids[],
+ MPI_Offset* const starts[], MPI_Offset* const counts[],
+ MPI_Offset* const strides[], MPI_Offset* const imaps[],
+ unsigned long long *bufs[]);
+
+/* End Skip Prototypes for Fortran binding */
+
+/* End {mput,mget}_var */
+
+/* End: more prototypes to be included for Fortran binding conversion */
+/* ################################################################## */
+
+/* End Prototypes */
+
+
+/* These macros are defined in serial netcdf (3.5.0) for backwards
+ * compatibility with older netcdf code. We aren't concerned with backwards
+ * compatibility, so if your code doesn't compile with parallel-netcdf, maybe
+ * this is why:
+ *
+ *
+ * OLD NAME NEW NAME
+ * ----------------------------------
+ * FILL_BYTE NC_FILL_BYTE
+ * FILL_CHAR NC_FILL_CHAR
+ * FILL_SHORT NC_FILL_SHORT
+ * FILL_LONG NC_FILL_INT
+ * FILL_FLOAT NC_FILL_FLOAT
+ * FILL_DOUBLE NC_FILL_DOUBLE
+ *
+ * MAX_NC_DIMS NC_MAX_DIMS
+ * MAX_NC_ATTRS NC_MAX_ATTRS
+ * MAX_NC_VARS NC_MAX_VARS
+ * MAX_NC_NAME NC_MAX_NAME
+ * MAX_VAR_DIMS NC_MAX_VAR_DIMS
+ */
+
+#if defined(__cplusplus)
+}
+#endif
+#endif
diff --git a/src/lib/rnd.h b/src/lib/rnd.h
new file mode 100644
index 0000000..3a9c810
--- /dev/null
+++ b/src/lib/rnd.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2003, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ */
+/* $Id: rnd.h 2021 2015-04-09 20:29:40Z wkliao $ */
+#ifndef _RNDUP
+
+/* useful for aligning memory */
+#define _RNDUP(x, unit) ((((x) + (unit) - 1) / (unit)) * (unit))
+#define _RNDDOWN(x, unit) ((x) - ((x)%(unit)))
+
+/* #define M_RND_UNIT (sizeof(double))
+ * SIZEOF_DOUBLE is defined in ncconfig.h
+ */
+#define M_RND_UNIT SIZEOF_DOUBLE
+#define M_RNDUP(x) _RNDUP(x, M_RND_UNIT)
+#define M_RNDDOWN(x) __RNDDOWN(x, M_RND_UNIT)
+
+#endif
diff --git a/src/lib/string.c b/src/lib/string.c
new file mode 100644
index 0000000..3665008
--- /dev/null
+++ b/src/lib/string.c
@@ -0,0 +1,351 @@
+/*
+ * Copyright (C) 2003, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ */
+/* $Id: string.c 2196 2015-11-27 22:31:05Z wkliao $ */
+
+#if HAVE_CONFIG_H
+# include "ncconfig.h"
+#endif
+
+#include <stdio.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#include <string.h>
+#include <ctype.h>
+#include <assert.h>
+
+#include <mpi.h>
+
+#include "nc.h"
+#include "ncx.h"
+#include "rnd.h"
+#include "macro.h"
+
+
+/*
+ * Free string, and, if needed, its values.
+ * Formerly
+NC_free_string()
+ */
+inline void
+ncmpii_free_NC_string(NC_string *ncstrp)
+{
+ if (ncstrp==NULL) return;
+ /* ncstrp->cp is allocated as part of ncstrp object */
+ NCI_Free(ncstrp);
+}
+
+#ifdef _CONFORM_NETCDF_3_5_1
+/*
+ * For CDF-1, Verify that a name string is valid
+ * CDL syntax, eg, all the characters are
+ * alphanumeric, '-', '_', or '.'.
+ * Also permit ':', '@', '(', or ')' in names for chemists currently making
+ * use of these characters, but don't document until ncgen and ncdump can
+ * also handle these characters in names.
+ */
+static int
+ncmpii_NC_check_name_CDF1(const char *name)
+{
+ const char *cp = name;
+ assert(name != NULL);
+
+ if (*name == 0)
+ DEBUG_RETURN_ERROR(NC_EBADNAME) /* empty names disallowed */
+
+ for (; *cp != 0; cp++) {
+ int ch = *cp;
+ if (!isalnum(ch)) {
+ if (ch != '_' && ch != '-' && ch != '+' && ch != '.' &&
+ ch != ':' && ch != '@' && ch != '(' && ch != ')')
+ DEBUG_RETURN_ERROR(NC_EBADNAME)
+ }
+ }
+ if (cp - name > NC_MAX_NAME)
+ DEBUG_RETURN_ERROR(NC_EMAXNAME)
+
+ return NC_NOERR;
+}
+#endif
+
+static int ncmpii_NC_check_name_CDF2(const char *name);
+
+/*----< ncmpii_NC_check_name() >---------------------------------------------*/
+int
+ncmpii_NC_check_name(const char *name,
+ int file_ver) /* CDF version: 1, 2, or 5 */
+{
+ /* NetCDF4 has made CDF-1 no different from CDF-2 except the size of
+ * OFFSET (i.e. 32-bit vs. 64-bit integer. Both formats support extended
+ * names now.
+ */
+#ifdef _CONFORM_NETCDF_3_5_1
+ if (file_ver == 1)
+ return ncmpii_NC_check_name_CDF1(name);
+#endif
+
+ return ncmpii_NC_check_name_CDF2(name);
+}
+
+#include "utf8proc.h"
+
+/* There are 3 levels of UTF8 checking: 1=> (exact)validating 2=>relaxed
+ and 3=>very relaxed
+*/
+/* Use semi-relaxed check */
+#define UTF8_CHECK 2
+
+static int
+nextUTF8(const char* cp)
+{
+ /* The goal here is to recognize the length of each
+ multibyte utf8 character sequence and skip it.
+ Again, we assume that every non-ascii character is legal.
+ We can define three possible tests of decreasing correctness
+ (in the sense that the least correct will allow some sequences that
+ are technically illegal UTF8).
+ As Regular expressions they are as follows:
+ 1. most correct:
+ UTF8 ([\xC2-\xDF][\x80-\xBF]) \
+ | (\xE0[\xA0-\xBF][\x80-\xBF]) \
+ | ([\xE1-\xEC][\x80-\xBF][\x80-\xBF]) \
+ | (\xED[\x80-\x9F][\x80-\xBF]) \
+ | ([\xEE-\xEF][\x80-\xBF][\x80-\xBF]) \
+ | (\xF0[\x90-\xBF][\x80-\xBF][\x80-\xBF]) \
+ | ([\xF1-\xF3][\x80-\xBF][\x80-\xBF][\x80-\xBF]) \
+ | (\xF4[\x80-\x8F][\x80-\xBF][\x80-\xBF]) \
+
+ 2. partially relaxed:
+ UTF8 ([\xC0-\xDF][\x80-\xBF])
+ |([\xE0-\xEF][\x80-\xBF][\x80-\xBF])
+ |([\xF0-\xF7][\x80-\xBF][\x80-\xBF][\x80-\xBF])
+
+ 3. The most relaxed version of UTF8:
+ UTF8 ([\xC0-\xD6].)|([\xE0-\xEF]..)|([\xF0-\xF7]...)
+
+ We use #2 here.
+
+ The tests are derived from the table at
+ http://www.w3.org/2005/03/23-lex-U
+ */
+
+/* Define a test macro to test against a range */
+#define RANGE(c,lo,hi) (((uchar)c) >= lo && ((uchar)c) <= hi)
+/* Define a common RANGE */
+#define RANGE0(c) RANGE(c,0x80,0xBF)
+
+ int ch0;
+
+ int skip = -1; /* assume failed */
+
+ ch0 = (uchar)*cp;
+ if(ch0 <= 0x7f) skip = 1; /* remove ascii case */
+ else
+
+#if UTF8_CHECK == 2
+ /* Do relaxed validation check */
+ if(RANGE(ch0,0xC0,0XDF)) {/* 2-bytes, but check */
+ if(cp[1] != 0 && RANGE0(cp[1]))
+ skip = 2; /* two bytes */
+ } else if(RANGE(ch0,0xE0,0XEF)) {/* 3-bytes, but check */
+ if(cp[1] != 0 && RANGE0(cp[1]) && cp[2] != 0 && RANGE0(cp[1]))
+ skip = 3; /* three bytes */
+ } else if(RANGE(ch0,0xF0,0XF7)) {/* 3-bytes, but check */
+ if(cp[1] != 0 && RANGE0(cp[1]) && cp[2] != 0
+ && RANGE0(cp[1]) && cp[3] != 0 && RANGE0(cp[1]))
+ skip = 4; /* four bytes*/
+ }
+#elif UTF8_CHECK == 1
+ /* Do exact validation check */
+ if(RANGE(ch0,0xC2,0xDF)) {/* non-overlong 2-bytes */
+ int ch1 = (uchar)cp[1];
+ if(ch1 != 0 && RANGE0(ch1)) skip = 2;
+ } else if((ch0 == 0xE0)) {/* 3-bytes, not overlong */
+ int ch1 = (uchar)cp[1];
+ if(ch1 != 0 && RANGE(ch1,0xA0,0xBF)) {
+ int ch2 = (uchar)cp[2];
+ if(ch2 != 0 && RANGE0(ch2)) skip = 3;
+ }
+ } else if((ch0 == 0xED)) {/* 3-bytes minus surrogates */
+ int ch1 = (uchar)cp[1];
+ if(ch1 != 0 && RANGE(ch1,0x80,0x9f)) {
+ int ch2 = (uchar)cp[2];
+ if(ch2 != 0 && RANGE0(ch2)) skip = 3;
+ }
+ } else if(RANGE(ch0,0xE1,0xEC) || ch0 == 0xEE || ch0 == 0xEF) {
+ int ch1 = (uchar)cp[1];
+ if(ch1 != 0 && RANGE0(ch1)) {
+ int ch2 = (uchar)cp[2];
+ if(ch2 != 0 && RANGE0(ch2)) skip = 3;
+ }
+ } else if((ch0 == 0xF0)) {/* planes 1-3 */
+ int ch1 = (uchar)cp[1];
+ if(ch1 != 0 && RANGE(ch1,0x90,0xBF)) {
+ int ch2 = (uchar)cp[2];
+ if(ch2 != 0 && RANGE0(ch2)) {
+ int ch3 = (uchar)cp[3];
+ if(ch3 != 0 && RANGE0(ch3)) skip = 4;
+ }
+ }
+ } else if((ch0 == 0xF4)) {/* plane 16 */
+ int ch1 = (uchar)cp[1];
+ if(ch1 != 0 && RANGE0(ch1)) {
+ int ch2 = (uchar)cp[2];
+ if(ch2 != 0 && RANGE0(ch2)) {
+ int ch3 = (uchar)cp[3];
+ if(ch3 != 0 && RANGE0(ch3)) skip = 4;
+ }
+ }
+ } else if(RANGE(ch0,0xF1,0xF3)) { /* planes 4-15 */
+ int ch1 = (uchar)cp[1];
+ if(ch1 != 0 && RANGE0(ch1)) {
+ int ch2 = (uchar)cp[2];
+ if(ch2 != 0 && RANGE0(ch2)) {
+ int ch3 = (uchar)cp[3];
+ if(ch3 != 0 && RANGE0(ch3)) skip = 4;
+ }
+ }
+ }
+#else
+#error "Must Define UTF8_CHECK as 1 or 2"
+#endif
+ return skip;
+}
+
+
+/*
+ * Verify that a name string is valid syntax. The allowed name
+ * syntax (in RE form) is:
+ *
+ * ([a-zA-Z_]|{UTF8})([^\x00-\x1F\x7F/]|{UTF8})*
+ *
+ * where UTF8 represents a multibyte UTF-8 encoding. Also, no
+ * trailing spaces are permitted in names. This definition
+ * must be consistent with the one in ncgen.l. We do not allow '/'
+ * because HDF5 does not permit slashes in names as slash is used as a
+ * group separator. If UTF-8 is supported, then a multi-byte UTF-8
+ * character can occur anywhere within an identifier. We later
+ * normalize UTF-8 strings to NFC to facilitate matching and queries.
+ */
+static int
+ncmpii_NC_check_name_CDF2(const char *name)
+{
+ int skip;
+ int ch;
+ const char *cp = name;
+ ssize_t utf8_stat;
+
+ assert(name != NULL);
+
+ if(*name == 0 /* empty names disallowed */
+ || strchr(cp, '/')) /* '/' can't be in a name */
+ DEBUG_RETURN_ERROR(NC_EBADNAME)
+
+ /* check validity of any UTF-8 */
+ utf8_stat = utf8proc_check((const unsigned char *)name);
+ if (utf8_stat < 0)
+ DEBUG_RETURN_ERROR(NC_EBADNAME)
+
+ /* First char must be [a-z][A-Z][0-9]_ | UTF8 */
+ ch = (uchar)*cp;
+ if(ch <= 0x7f) {
+ if(!('A' <= ch && ch <= 'Z')
+ && !('a' <= ch && ch <= 'z')
+ && !('0' <= ch && ch <= '9')
+ && ch != '_' )
+ DEBUG_RETURN_ERROR(NC_EBADNAME)
+ cp++;
+ } else {
+ if((skip = nextUTF8(cp)) < 0)
+ DEBUG_RETURN_ERROR(NC_EBADNAME)
+ cp += skip;
+ }
+
+ while(*cp != 0) {
+ ch = (uchar)*cp;
+ /* handle simple 0x00-0x7f characters here */
+ if(ch <= 0x7f) {
+ if( ch < ' ' || ch > 0x7E) /* control char or DEL */
+ DEBUG_RETURN_ERROR(NC_EBADNAME)
+ cp++;
+ } else {
+ if((skip = nextUTF8(cp)) < 0) DEBUG_RETURN_ERROR(NC_EBADNAME)
+ cp += skip;
+ }
+ if(cp - name > NC_MAX_NAME)
+ DEBUG_RETURN_ERROR(NC_EMAXNAME)
+ }
+ if(ch <= 0x7f && isspace(ch)) /* trailing spaces disallowed */
+ DEBUG_RETURN_ERROR(NC_EBADNAME)
+ return NC_NOERR;
+}
+
+/*----< ncmpii_new_NC_string() >---------------------------------------------*/
+/*
+ * Allocate a NC_string structure large enough
+ * to hold slen characters.
+ * Formerly
+NC_new_string(count, str)
+ */
+NC_string *
+ncmpii_new_NC_string(size_t slen,
+ const char *str)
+{
+ /* str may not be NULL terminated */
+ NC_string *ncstrp;
+ size_t sizeof_NC_string = M_RNDUP(sizeof(NC_string));
+ size_t sz = slen + sizeof_NC_string + 1;
+ /* one char more space for NULL terminate char */
+
+#if 0
+ sz = _RNDUP(sz, X_ALIGN);
+#endif
+
+ ncstrp = (NC_string *) NCI_Calloc(sz, sizeof(char));
+ if (ncstrp == NULL) return NULL;
+
+ /* make space occupied by ncstrp->cp part of ncstrp */
+ ncstrp->nchars = (MPI_Offset)slen;
+ ncstrp->cp = (char *)ncstrp + sizeof_NC_string;
+
+ /* in PnetCDF, we want to make name->cp always NULL character terminated */
+ if (str != NULL && *str != '\0') {
+ strncpy(ncstrp->cp, str, slen);
+ ncstrp->cp[slen] = '\0'; /* NULL terminated */
+ }
+
+ return(ncstrp);
+}
+
+
+/*----< ncmpii_set_NC_string() >---------------------------------------------*/
+/*
+ * If possible, change the value of an NC_string to 'str'.
+ *
+ * Formerly
+NC_re_string()
+ */
+int
+ncmpii_set_NC_string(NC_string *ncstrp,
+ const char *str)
+{
+ size_t slen;
+
+ assert(str != NULL && *str != '\0');
+
+ slen = strlen(str);
+
+ if (ncstrp->nchars < (MPI_Offset)slen) DEBUG_RETURN_ERROR(NC_ENOTINDEFINE)
+
+ memcpy(ncstrp->cp, str, slen);
+
+ /* in PnetCDF, we want to make name->cp always NULL character terminated */
+ if (ncstrp->nchars > (MPI_Offset)slen)
+ memset(ncstrp->cp + slen, 0, (size_t)ncstrp->nchars - slen);
+
+ ncstrp->nchars = (MPI_Offset)slen;
+
+ return NC_NOERR;
+}
diff --git a/src/lib/subfile.c b/src/lib/subfile.c
new file mode 100644
index 0000000..ca909e8
--- /dev/null
+++ b/src/lib/subfile.c
@@ -0,0 +1,1109 @@
+/*
+ * Copyright (C) 2013, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ */
+/* $Id: subfile.c 2196 2015-11-27 22:31:05Z wkliao $ */
+
+#if HAVE_CONFIG_H
+# include "ncconfig.h"
+#endif
+#include "subfile.h"
+#ifdef TAU_SSON
+#include <TAU.h>
+#endif
+#include <stdlib.h>
+#include "ncmpidtype.h"
+
+static int DEBUG = 1;
+enum {ONE, BALANCED};
+int min_ndims = 1;
+
+/* set default values for the following values */
+int delegate_scheme = BALANCED; /* default: any proc can be delegate proc */
+static int is_partitioned = 0;
+
+#define check_err(fn_name_) \
+ if (mpireturn != MPI_SUCCESS) { \
+ errs++; \
+ if (DEBUG) { \
+ int _len; \
+ char err_str_[MPI_MAX_ERROR_STRING]; \
+ MPI_Error_string(mpireturn, err_str_, &_len); \
+ fprintf(stderr, #fn_name_ " failed at line %d, mpireturn=%d: %s\n", \
+ __LINE__, mpireturn, err_str_); \
+ } \
+ } \
+
+#if 0
+static int ncmpii_itoa(int val, char* buf)
+{
+ const unsigned int radix = 10;
+
+ char* p;
+ unsigned int a; /* every digit */
+ int len;
+ char* b; /* start of the digit char */
+ char temp;
+ unsigned int u;
+
+ p = buf;
+
+ if (val < 0) {
+ *p++ = '-';
+ val = 0 - val;
+ }
+ u = (unsigned int)val;
+
+ b = p;
+
+ do {
+ a = u % radix;
+ u /= radix;
+
+ *p++ = a + '0';
+
+ } while (u > 0);
+
+ len = (int)(p - buf);
+
+ *p-- = 0;
+
+ /* swap */
+ do {
+ temp = *p;
+ *p = *b;
+ *b = temp;
+ --p;
+ ++b;
+ } while (b < p);
+
+ return len;
+}
+#endif
+
+int ncmpii_subfile_create(NC *ncp, int *ncidp)
+{
+ int myrank, nprocs, color, status=NC_NOERR, mpireturn;
+ char path_sf[1024];
+ double ratio;
+ MPI_Comm comm_sf;
+ MPI_Info info;
+
+ MPI_Info_create(&info);
+
+ MPI_Comm_rank(ncp->nciop->comm, &myrank);
+ MPI_Comm_size(ncp->nciop->comm, &nprocs);
+#ifdef SUBFILE_DEBUG
+ if (myrank == 0)
+ printf("%s: rank(%d): nprocs=%d, ncp->nc_num_subfiles=%d\n",
+ __func__, myrank, nprocs, ncp->nc_num_subfiles);
+#endif
+
+ /* split the orignial comm to subcomm */
+ if (nprocs > ncp->nc_num_subfiles) {
+ ratio = (double)nprocs/(double)(ncp->nc_num_subfiles);
+ color = (int)((double)myrank/ratio);
+ }
+ else
+ color = myrank%ncp->nc_num_subfiles;
+
+#ifdef SUBFILE_DEBUG
+ printf("rank(%d): color=%d\n", myrank, color);
+#endif
+ /* key = myrank/comm_size; */
+
+ /* TODO: fix error when using generated key value.
+ * for now, just passing 0 value. */
+ TRACE_COMM(MPI_Comm_split)(ncp->nciop->comm, color, myrank, &comm_sf);
+ if (mpireturn != MPI_SUCCESS)
+ return ncmpii_handle_error(mpireturn, "MPI_Comm_split");
+
+ sprintf(path_sf, "%s.subfile_%i.%s", ncp->nciop->path, color, "nc");
+
+ /* MPI_Info_set(info, "romio_lustre_start_iodevice", offset);
+ MPI_Info_set(info, "striping_factor", "1");
+ */
+
+ status = ncmpi_create(comm_sf, path_sf, ncp->nciop->ioflags, info, ncidp);
+ if (status != NC_NOERR && myrank == 0)
+ fprintf(stderr, "%s: error in creating file(%s): %s\n",
+ __func__, path_sf, ncmpi_strerror(status));
+
+ MPI_Comm_free(&comm_sf);
+ MPI_Info_free(&info);
+
+ return status;
+}
+
+int
+ncmpii_subfile_open(NC *ncp, int *ncidp)
+{
+ int myrank, nprocs, color, status=NC_NOERR, mpireturn;
+ char path_sf[1024];
+ MPI_Comm comm_sf;
+ double ratio;
+
+ MPI_Comm_rank(ncp->nciop->comm, &myrank);
+ MPI_Comm_size(ncp->nciop->comm, &nprocs);
+#ifdef SUBFILE_DEBUG
+ if (myrank == 0)
+ printf("%s: rank(%d): nprocs=%d, ncp->nc_num_subfiles=%d\n", __func__,
+ myrank, nprocs, ncp->nc_num_subfiles);
+#endif
+
+ /* split the original comm to subcomm */
+ if (nprocs > ncp->nc_num_subfiles) {
+ ratio = (double)nprocs/(double)ncp->nc_num_subfiles;
+ color = (int)((double)myrank/ratio);
+ }
+ else
+ color = myrank%ncp->nc_num_subfiles;
+
+#ifdef SUBFILE_DEBUG
+ if (myrank == 0)
+ printf("%s: rank(%d): color=%d\n", __func__, myrank, color);
+#endif
+ /* key = myrank/comm_size; */
+
+ /* TODO: fix error when using generated key value.
+ * for now, just passing 0 value. */
+ TRACE_COMM(MPI_Comm_split)(ncp->nciop->comm, color, myrank, &comm_sf);
+ if (mpireturn != MPI_SUCCESS)
+ return ncmpii_handle_error(mpireturn, "MPI_Comm_split");
+
+ /* char path[1024], file[1024]; */
+ /* find_path_and_fname(ncp->nciop->path, path, file); */
+ sprintf(path_sf, "%s.subfile_%i.%s", ncp->nciop->path, color, "nc");
+ /* sprintf(path_sf, "%s%d/%s", path, color, file); */
+
+ status = ncmpi_open(comm_sf, path_sf, ncp->nciop->ioflags, MPI_INFO_NULL, ncidp);
+ if (status != NC_NOERR)
+ fprintf(stderr, "Error in file %s line %d: %s\n", __FILE__,__LINE__, ncmpi_strerror(status));
+
+ MPI_Comm_free(&comm_sf);
+ return status;
+}
+
+int ncmpii_subfile_close(NC *ncp)
+{
+ int status = NC_NOERR;
+ NC *ncp_sf;
+
+ status = ncmpii_NC_check_id(ncp->ncid_sf, &ncp_sf);
+ if (status != NC_NOERR)
+ return status;
+
+ status = ncmpii_close(ncp_sf);
+ if (status != NC_NOERR)
+ return status;
+
+ /* reset values to 0 */
+ is_partitioned = 0;
+
+ return status;
+}
+
+/*----< ncmpii_subfile_partition() >---------------------------------------*/
+int ncmpii_subfile_partition(NC *ncp, int *ncidp)
+{
+ int i, j, color, myrank, nprocs, status=NC_NOERR, num_subfiles;
+ NC *ncp_sf;
+ double ratio;
+
+ MPI_Comm_rank(ncp->nciop->comm, &myrank);
+ MPI_Comm_size(ncp->nciop->comm, &nprocs);
+#ifdef SUBFILE_DEBUG
+ if (myrank==0) /* debug */
+ {
+ printf("rank(%d): is_partitioned=%d\n", myrank, is_partitioned);
+ }
+#endif
+ if (is_partitioned == 1) return NC_NOERR;
+
+ if (nprocs > ncp->nc_num_subfiles) {
+ ratio = (double)nprocs/(double)ncp->nc_num_subfiles;
+ color = (int)((double)myrank/ratio);
+ }
+ else
+ color = myrank%ncp->nc_num_subfiles;
+
+#ifdef SUBFILE_DEBUG
+ printf("%s: rank(%d): color=%d\n", __func__, myrank, color);
+#endif
+
+ /* check whether file is already partitioned */
+ /* this is to handle when app has multiple ncmpi_enddef() */
+ status = ncmpi_get_att_int(ncp->nciop->fd, NC_GLOBAL, "_PnetCDF_SubFiling.num_subfiles",
+ &num_subfiles);
+
+ if (status == NC_ENOTATT) { /* if such attr doesn't exist */
+ status = ncmpii_subfile_create(ncp, ncidp);
+ TEST_HANDLE_ERR(status)
+
+ status = ncmpi_put_att_int(ncp->nciop->fd, NC_GLOBAL, "_PnetCDF_SubFiling.num_subfiles",
+ NC_INT, 1, &ncp->nc_num_subfiles);
+ TEST_HANDLE_ERR(status)
+ }
+ else if (status == NC_NOERR) { /* attr is already set */
+ assert(num_subfiles == ncp->nc_num_subfiles);
+ }
+ else /* other error */
+ return status;
+
+ /* TODO: ignore UNLIMITED dims */
+ /* NOTE: the following "for loop" should be before NC_begins() */
+ /* NOTE: ncp->vars.nalloc shouldn't be used for loop bound
+ because it will incremented by 4, not by 1 */
+ status = ncmpii_NC_check_id(ncp->ncid_sf, &ncp_sf);
+ TEST_HANDLE_ERR(status)
+
+ /* adjust the hints to be used by PnetCDF; use the same value in master */
+ ncp_sf->nciop->hints.h_align = ncp->nciop->hints.h_align;
+ ncp_sf->nciop->hints.v_align = ncp->nciop->hints.v_align;
+ ncp_sf->nciop->hints.r_align = ncp->nciop->hints.r_align;
+
+ for(i=0; i<ncp->vars.ndefined; i++) { /* traverse all variables */
+ NC_var **vpp = ncp->vars.value;
+ NC_dim **dpp = ncp->dims.value;
+
+ /* check attr for subfiles */
+ int par_dim_id = (IS_RECVAR(vpp[i])?1:0); /* default is the most significant dim excluding NC_UNLIMITED */
+
+ /* skip if the var is partitioned already */
+ if (vpp[i]->dimids == NULL) continue;
+
+ int par_dim_id_temp;
+ status = ncmpi_get_att_int(ncp->nciop->fd, i, "_PnetCDF_SubFiling.par_dim_id",
+ &par_dim_id_temp);
+ if (status == NC_NOERR) { /* if this attr exists */
+#ifdef SUBFILE_DEBUG
+ printf("par_dim_id_temp=%d\n", par_dim_id_temp);
+ printf("par_dim_id=%d\n", par_dim_id);
+#endif
+ /* convert par_dim_id to dim index defined in a var */
+ for (j=0; j<vpp[i]->ndims; j++)
+ if (vpp[i]->dimids[j] == par_dim_id_temp) {
+#ifdef SUBFILE_DEBUG
+ if (myrank == 0)
+ printf("dimids[%d]=%d\n", j, vpp[i]->dimids[j]);
+#endif
+ par_dim_id = j;
+ break;
+ }
+ }
+ else if (status != NC_ENOTATT) /* ignore if this attr does not exist */
+ return status; /* other kind of error */
+
+ if (par_dim_id < vpp[i]->ndims) {
+ status = ncmpi_put_att_int(ncp->nciop->fd, i, "_PnetCDF_SubFiling.par_dim_index",
+ NC_INT, 1, &par_dim_id);
+ TEST_HANDLE_ERR(status)
+ }
+
+#ifdef SUBFILE_DEBUG
+ if (myrank == 0)
+ printf ("%s: var(%s): size of partitioning dim (id=%d)=%d\n",
+ __func__, (*vpp[i]).name->cp, par_dim_id,
+ dpp[par_dim_id]->size);
+#endif
+ /* divide only when dim is partitionable */
+ /* 1. skip sizeof(par_dim_id) is smaller than num_subfiles */
+ /* 2. skip if ndims < min_ndims */
+ if ( (dpp[(*vpp[i]).dimids[par_dim_id]]->size)/(ncp->nc_num_subfiles) != 0 && (vpp[i]->ndims >= par_dim_id+1) && (vpp[i]->ndims >= min_ndims)) {
+ int varid, j, jj, k;
+ int var_ndims = vpp[i]->ndims; /* keep org ndims */
+ int dimids[var_ndims];
+ char *key[ncp->nc_num_subfiles][var_ndims];
+
+ for (jj=0; jj < ncp->nc_num_subfiles; jj++)
+ for (k=0; k<var_ndims; k++)
+ key[jj][k] = (char*) NCI_Calloc((size_t)256, sizeof(char));
+
+ /* save original value ndims to attribute before making to 0 */
+ status = ncmpi_put_att_int(ncp->nciop->fd, i, "_PnetCDF_SubFiling.ndims_org", NC_INT, 1, &vpp[i]->ndims);
+ TEST_HANDLE_ERR(status)
+
+ int sf_range[ncp->nc_num_subfiles][var_ndims][3];
+
+ /* j: each dimension */
+ /* subfile: create a var with partitioned dim sizes */
+ for(j=0; j<var_ndims; j++) {
+ MPI_Offset dim_sz;
+ char str[80];
+ double x; /* = org dim size / num_subfiles */
+ int min, max;
+
+ dim_sz = dpp[vpp[i]->dimids[j]]->size; /* init both to org dim sz */
+ /* determine partition ratio */
+ x = (double)(dpp[vpp[i]->dimids[j]]->size)/(double)(ncp->nc_num_subfiles);
+
+ /* don't partition dim if dim size is less than ratio x */
+ if ((int)x < 1 && j == par_dim_id)
+ continue;
+
+ /* don't need to check? */
+ if (j == par_dim_id)
+ {
+ double xx = x*(double)color;
+ double yy = x*(double)(color+1);
+ min = (int)xx+(color==0||(xx-(int)xx==0.0)?0:1);
+ max = (int)yy-(yy-(int)yy==0.0?1:0);
+ if (max >= dpp[vpp[i]->dimids[j]]->size) max = dpp[vpp[i]->dimids[j]]->size-1;
+ dim_sz = max-min+1;
+ }
+
+ /* name->cp is always NULL terminated, see ncmpii_new_NC_string() */
+ sprintf(str, "%s.%s", dpp[vpp[i]->dimids[j]]->name->cp,
+ vpp[i]->name->cp);
+#ifdef SUBFILE_DEBUG
+ printf("rank(%d): new dim name = %s, dim_sz=%d\n", myrank, str, dim_sz);
+#endif
+ status = ncmpi_def_dim(ncp->ncid_sf, str, dim_sz, &dimids[j]);
+ TEST_HANDLE_ERR(status)
+
+ /* dpp_sf[color][j] = ncp_sf->dims.value[j]; */
+
+ for (jj=0; jj < ncp->nc_num_subfiles; jj++) {
+ double xx, yy;
+ sprintf(key[jj][j], "_PnetCDF_SubFiling.range(%s).subfile.%d", dpp[vpp[i]->dimids[j]]->name->cp, jj); /* dim name*/
+ xx = x*(double)jj;
+ min = (int)xx+(jj==0||(xx-(int)xx==0.0)?0:1);
+ yy = x*(double)(jj+1);
+ max = (int)yy-(yy-(int)yy==0.0?1:0);
+ if (max >= dpp[vpp[i]->dimids[j]]->size) max = dpp[vpp[i]->dimids[j]]->size-1;
+#ifdef SUBFILE_DEBUG
+ if (myrank == 0) printf("subfile(%d): min=%d, max=%d\n", jj, min, max);
+#endif
+ if (j == par_dim_id) { /* partitioning dims? */
+ sf_range[jj][j][0] = min;
+ sf_range[jj][j][1] = max;
+ sf_range[jj][j][2] = (max-min+1);;
+ }
+ else {
+ sf_range[jj][j][0] = 0;
+ sf_range[jj][j][2] = dpp[vpp[i]->dimids[j]]->size;
+ sf_range[jj][j][1] = (dpp[vpp[i]->dimids[j]]->size!=0?(dpp[vpp[i]->dimids[j]]->size)-1:0);
+ }
+ }
+ } /* for each dim */
+
+ /* master file: replace the original var with scalar var */
+ vpp[i]->dimids_org = (int*) NCI_Malloc((size_t)vpp[i]->ndims * SIZEOF_INT);
+ memcpy(vpp[i]->dimids_org, vpp[i]->dimids, (size_t)vpp[i]->ndims*SIZEOF_INT);
+ vpp[i]->ndims_org = vpp[i]->ndims;
+ vpp[i]->ndims = 0;
+ vpp[i]->dimids = (IS_RECVAR(vpp[i])?&vpp[i]->dimids[0]:NULL);
+ vpp[i]->len = vpp[i]->xsz; /* size of type */
+ vpp[i]->shape = NULL;
+ vpp[i]->num_subfiles = ncp->nc_num_subfiles;
+
+ status = ncmpi_put_att_int(ncp->nciop->fd, i, "_PnetCDF_SubFiling.dimids_org",
+ NC_INT, vpp[i]->ndims_org, vpp[i]->dimids_org);
+ TEST_HANDLE_ERR(status)
+
+ status = ncmpi_put_att_int(ncp->nciop->fd, i, "_PnetCDF_SubFiling.num_subfiles",
+ NC_INT, 1, &ncp->nc_num_subfiles);
+ TEST_HANDLE_ERR(status)
+
+ for (jj=0; jj < ncp->nc_num_subfiles; jj++)
+ for (k=0; k < var_ndims; k++) {
+ status = ncmpi_put_att_int(ncp->nciop->fd, i,
+ key[jj][k], NC_INT,
+ 2, sf_range[jj][k]);
+ TEST_HANDLE_ERR(status)
+ }
+
+ /* define a var with new dim */
+ status = ncmpi_def_var(ncp->ncid_sf, (*vpp[i]).name->cp,
+ vpp[i]->type, var_ndims, dimids, &varid);
+ TEST_HANDLE_ERR(status)
+
+ /* add an attribute about each dim's range in subfile */
+ /* varid: var id in subfile */
+ for (k=0; k<var_ndims; k++) {
+ status = ncmpi_put_att_int(ncp->ncid_sf, varid, key[color][k],
+ NC_INT, 2, sf_range[color][k]);
+ TEST_HANDLE_ERR(status)
+ }
+
+ /* deallocate buffers */
+ for (jj=0; jj < ncp->nc_num_subfiles; jj++)
+ for (k=0; k<var_ndims; k++)
+ NCI_Free(key[jj][k]);
+
+ status = ncmpi_put_att_int(ncp->ncid_sf, varid, "_PnetCDF_SubFiling.subfile_index",
+ NC_INT, 1, &color);
+ TEST_HANDLE_ERR(status)
+ } /* end if() */
+ } /* for each variable */
+
+ is_partitioned = 1;
+
+ return NC_NOERR;
+}
+
+/*----< ncmpii_subfile_getput_vars() >---------------------------------------*/
+int
+ncmpii_subfile_getput_vars(NC *ncp,
+ NC_var *varp,
+ const MPI_Offset start[],
+ const MPI_Offset count[],
+ const MPI_Offset stride[],
+ void *buf,
+ MPI_Offset bufcount,
+ MPI_Datatype buftype, /* data type of the buffer */
+ int rw_flag,
+ int io_method)
+{
+ int mpireturn, errs=0, status;
+ NC_subfile_access *my_req, *others_req;
+ int i, j, k, myrank, nprocs;
+ NC *ncp_sf;
+ int *count_my_req_per_proc, *count_others_req_per_proc;
+ int varid, varid_sf;
+ MPI_Offset *buf_count_my, *buf_count_others;
+ void **xbuf=NULL, *cbuf=NULL;
+ MPI_Request *requests=NULL;
+ MPI_Status *statuses=NULL;
+ int ndims_org = varp->ndims_org;
+ int color;
+ int nasyncios=0;
+
+ /* check whether start, count, and stride are valid */
+ status = NC_start_count_stride_ck(ncp, varp, start, count, stride, rw_flag);
+ if (status != NC_NOERR) return status;
+
+ MPI_Comm_rank(ncp->nciop->comm, &myrank);
+ MPI_Comm_size(ncp->nciop->comm, &nprocs);
+
+#ifdef SUBFILE_DEBUG
+ for (i=0; i<ndims_org; i++)
+ printf("rank(%d): %s: var(%s): start[%d]=%ld, count[%d]=%ld, stride[%d]=%ld, bufcount=%ld\n",
+ myrank, __func__, varp->name->cp, i, start[i], i, count[i], i,
+ ((stride != NULL)?stride[i]:1), bufcount);
+#endif
+
+ /* get ncp info for the subfile */
+ status = ncmpii_NC_check_id(ncp->ncid_sf, &ncp_sf);
+ TEST_HANDLE_ERR(status)
+
+ /* check attr for subfiles */
+ int par_dim_id = 0; /* default is the most significant dim */
+
+ status = ncmpi_inq_varid(ncp->nciop->fd, varp->name->cp, &varid);
+ TEST_HANDLE_ERR(status)
+
+ status = ncmpi_get_att_int(ncp->nciop->fd, varid, "_PnetCDF_SubFiling.par_dim_index",
+ &par_dim_id);
+ TEST_HANDLE_ERR(status)
+#ifdef SUBFILE_DEBUG
+ if (myrank == 0)
+ printf("_PnetCDF_SubFiling.par_dim_index of %s = %d\n", varp->name->cp, par_dim_id);
+#endif
+ status = ncmpi_inq_varid(ncp_sf->nciop->fd, varp->name->cp, &varid_sf);
+ TEST_HANDLE_ERR(status)
+
+ status = ncmpi_get_att_int(ncp_sf->nciop->fd, varid_sf, "_PnetCDF_SubFiling.subfile_index",
+ &color);
+ TEST_HANDLE_ERR(status)
+
+ count_my_req_per_proc = (int *)NCI_Calloc((size_t)nprocs, SIZEOF_INT);
+ count_others_req_per_proc = (int *)NCI_Calloc((size_t)nprocs, SIZEOF_INT);
+ buf_count_my = (MPI_Offset *)NCI_Calloc((size_t)nprocs, SIZEOF_MPI_OFFSET);
+ buf_count_others = (MPI_Offset *)NCI_Calloc((size_t)nprocs, SIZEOF_MPI_OFFSET);
+
+ /* TODO: shouldn't it be initialized to 0? */
+ for (i=0; i<nprocs; i++) {
+ buf_count_my[i] = 1;
+ buf_count_others[i] = 1;
+ }
+
+ /* allocate space for my_req */
+ my_req = (NC_subfile_access*) NCI_Calloc((size_t)nprocs, sizeof(NC_subfile_access));
+
+ /* init allocated my_req */
+ for (i=0; i<nprocs; i++) {
+ my_req[i].start = (MPI_Offset*)NCI_Malloc((size_t)(3 * ndims_org * SIZEOF_MPI_OFFSET));
+ my_req[i].count = my_req[i].start + ndims_org;
+ my_req[i].start_org = my_req[i].count + ndims_org;
+ /* init start/count to -1 */
+ for (j=0; j<ndims_org; j++) {
+ my_req[i].start[j] = -1;
+ my_req[i].count[j] = -1;
+ my_req[i].start_org[j] = -1;
+ }
+ }
+
+ /* i: for each subfile */
+ for (i=0; i<ncp->nc_num_subfiles; i++) {
+ int flag = 0; /* set to 1 if par_dim_id is partitioned, initially 0 */
+ double ratio = (double)nprocs/(double)ncp->nc_num_subfiles;
+ int aproc=-1; /* I/O delegate proc in subfile group */
+
+ if (delegate_scheme == BALANCED) {
+ double scaled, xx, yy;
+ int min, max;
+
+ xx = (ratio)*(double)i; /* i: each subfile */
+ min = (int)xx+(i==0||(xx-(int)xx==0.0)?0:1);
+ yy = (ratio)*(double)(i+1);
+ max = (int)yy-(yy-(int)yy==0.0?1:0);
+ if (max >= nprocs) max = nprocs-1;
+ /* scaled = (double)rand()/RAND_MAX; */
+ scaled = (double)myrank/ratio-(double)color;
+ aproc = (i==color)?myrank:(min+(max-min+1)*scaled);
+ }
+ else if (delegate_scheme == ONE)
+ {
+ double xx;
+ int min;
+ xx = (ratio)*(double)i;
+ min = (int)xx+(i==0||(xx-(int)xx==0.0)?0:1);
+ aproc = (i==color)?myrank:min;
+ }
+
+ /* check out of range? */
+ if (aproc >= nprocs)
+ aproc = nprocs-1;
+
+#ifdef SUBFILE_DEBUG
+ printf("rank(%d): color=%d, subfile=%d, aproc=%d\n", myrank, color, i, aproc);
+#endif
+
+ /* j: for each dim starting from par_dim_id in round-robin manner */
+ for (j=par_dim_id; j<par_dim_id+ndims_org; j++) {
+ int jx = j%ndims_org;
+ NC_dim *dimp = ncp_sf->dims.value[ncp_sf->vars.value[varid_sf]->dimids[jx]];
+ int sf_range[2];
+ int ii, jj, kk, stride_count;
+ char key[256], *org_dim_name;
+
+ org_dim_name = strtok(dimp->name->cp, ".");
+ sprintf(key, "_PnetCDF_SubFiling.range(%s).subfile.%d", org_dim_name, i); /* dim name*/
+#ifdef SUBFILE_DEBUG
+ if (myrank == 0) {
+ printf("rank(%d): org_dim_name=%s\n", myrank, org_dim_name);
+ printf("rank(%d): key=%s\n", myrank, key);
+ }
+#endif
+ /* should get range info from the master file */
+ status = ncmpi_get_att_int(ncp->nciop->fd, varid, key, sf_range);
+ TEST_HANDLE_ERR(status)
+
+#ifdef SUBFILE_DEBUG
+ /* if (myrank == 0) */
+ printf("rank(%d): ndims_org=%d, rstart=%d, rend=%d, start[%d]=%d, count[%d]=%d\n",
+ myrank, ndims_org, sf_range[0], sf_range[1], jx, start[jx], jx, count[jx]);
+#endif
+ /* ii: traverse user's request range, incremented by stride count
+ jj: traverse subfile range, incrementing sequentially
+ kk: count belong to my subfile range */
+ ii=start[jx], jj=sf_range[0], kk=0;
+ stride_count = (stride == NULL?1:stride[jx]);
+ /* printf("stride_count[%d]=%d\n", jx, stride_count); */
+
+ /* TODO: if sf_range is 1, count[] value is incorrect
+ e.g., size of par_dim is 4 and the nproc is also 4 */
+ int is_unlimited_dim = sf_range[1]-sf_range[0];
+
+ /* skip the remaining dim if par_dim is not
+ intersected with user's request */
+ if (jx != par_dim_id && !flag) continue;
+
+ while (ii < (start[jx]+(count[jx]*stride_count)) &&
+ jj <= (is_unlimited_dim==0?(count[jx]*stride_count-1):sf_range[1]))
+ {
+ if (ii < jj)
+ ii+=stride_count;
+ else if (jj < ii)
+ jj++;
+ else {
+#ifdef SUBFILE_DEBUG
+ printf("rank(%d): var(%s): i=%d, j=%d, ii=%d, jj=%d, kk=%d, jx=%d\n", myrank, varp->name->cp, i, j, ii, jj, kk, jx);
+#endif
+ if (kk == 0) {
+ my_req[aproc].start[jx] = ii;
+#ifdef SUBFILE_DEBUG
+ printf("rank(%d): var(%s): my_req[%d].start[%d]=%d\n",
+ myrank, varp->name->cp, aproc, jx, ii);
+#endif
+ }
+ if (jx == par_dim_id) flag = 1;
+ ii+=stride_count; jj++; kk++;
+ }
+
+ }
+ if (kk > 0 && flag == 1) my_req[aproc].count[jx] = kk;
+ /* adjust start offset based on subfile's range start.
+ otherwise, there will be an out of bound error during I/O */
+ if (my_req[aproc].start[jx] != -1) {
+ my_req[aproc].start_org[jx] = my_req[aproc].start[jx];
+ my_req[aproc].start[jx] -= sf_range[0];
+ }
+#ifdef SUBFILE_DEBUG
+ /* if (myrank == 0) */
+ {
+ printf("rank(%d): my_req[%d].start[%d]=%d\n", myrank, aproc,
+ jx, my_req[aproc].start[jx]);
+ printf("rank(%d): my_req[%d].count[%d]=%d\n", myrank, aproc,
+ jx, my_req[aproc].count[jx]);
+ }
+#endif
+ } /* for each dim, j */
+ if (my_req[aproc].start[0] == -1)
+ count_my_req_per_proc[aproc] = 0;
+ else
+ count_my_req_per_proc[aproc] = 1;
+ } /* for each subfile, i */
+
+#ifdef SUBFILE_DEBUG
+ for (i=0; i<ncp->nc_num_subfiles; i++) {
+ char str_st[100], str_st_org[100], str_ct[100], str_t1[10];
+ sprintf(str_st, ">> rank(%d): subfile(%d): var(%s): start(", myrank, i, varp->name->cp);
+ sprintf(str_ct, ">> rank(%d): subfile(%d): count(", myrank, i);
+ sprintf(str_st_org, "%d: start_org(", i);
+ for (j=0; j<ndims_org; j++) {
+ sprintf(str_t1, "%d", my_req[i].start[j]);
+ strcat(str_st, str_t1);
+ sprintf(str_t1, "%d", my_req[i].count[j]);
+ strcat(str_ct, str_t1);
+ sprintf(str_t1, "%d", my_req[i].start_org[j]);
+ strcat(str_st_org, str_t1);
+ if (j != (ndims_org-1)) {
+ strcat(str_st, ",");
+ strcat(str_ct, ",");
+ strcat(str_st_org, ",");
+ }
+
+ }
+ strcat(str_st, ")");
+ strcat(str_ct, ")");
+ strcat(str_st_org, ")");
+ printf("%s\n", str_st);
+ printf("%s\n", str_ct);
+ printf("%s\n", str_st_org);
+ }
+#endif
+
+ /* calculate buf_count based on subfile */
+ /* TODO: should do only when count_my_req_per_proc[myrank] != 0??? */
+ for (i=0; i<ndims_org; i++)
+ buf_count_my[myrank] *= my_req[myrank].count[i];
+
+ /* build other proc's request */
+ others_req = (NC_subfile_access *) NCI_Calloc((size_t)nprocs, sizeof(NC_subfile_access));
+ /* init allocated others_req */
+ for (i=0; i<nprocs; i++) {
+ others_req[i].start = (MPI_Offset *)NCI_Malloc((size_t)(3 * ndims_org * SIZEOF_MPI_OFFSET));
+ others_req[i].count = others_req[i].start + ndims_org;
+ others_req[i].start_org = others_req[i].count + ndims_org;
+ /* init start/count to -1 */
+ for (j=0; j<ndims_org; j++) {
+ others_req[i].start[j] = -1;
+ others_req[i].count[j] = -1;
+ others_req[i].start_org[j] = -1;
+ }
+ }
+
+#ifdef SUBFILE_DEBUG
+ for (i=0; i<nprocs && myrank==0; i++) {
+ printf("%d: count_my_req_per_proc[%d]=%d\n", myrank, i, count_my_req_per_proc[i]);
+ printf("%d: count_others_req_per_proc[%d]=%d\n", myrank, i, count_others_req_per_proc[i]);
+ }
+#endif
+
+#ifdef TAU_SSON
+ TAU_PHASE_CREATE_STATIC(t51, "SSON --- getput_vars MPI_Alltoall", "", TAU_USER);
+ TAU_PHASE_START(t51);
+#endif
+
+ TRACE_COMM(MPI_Alltoall)(count_my_req_per_proc, 1, MPI_INT, count_others_req_per_proc, 1, MPI_INT, ncp->nciop->comm);
+
+#ifdef TAU_SSON
+ TAU_PHASE_STOP(t51);
+#endif
+
+#ifdef SUBFILE_DEBUG
+ for (i=0; i<nprocs && myrank==0; i++) {
+ printf("=> %d: count_others_req_per_proc[%d]=%d\n", myrank, i, count_others_req_per_proc[i]);
+ }
+#endif
+
+ MPI_Offset buf_offset[nprocs];
+ for (i=0; i<nprocs; i++)
+ buf_offset[i] = 0;
+
+#ifdef SUBFILE_DEBUG
+ if (myrank == 0) printf("varname=%s: etype=0x%x, etype_size=%d\n", varp->name->cp, varp->type, varp->xsz);
+#endif
+
+ /* find the ptype (primitive MPI data type) from buftype
+ * el_size is the element size of ptype
+ * bnelems is the total number of ptype elements in the I/O buffer, buf
+ * fnelems is the number of nc variable elements in nc_type
+ * nbytes is the amount of read/write in bytes
+ */
+ MPI_Datatype ptype;
+ int el_size;
+ int isderived, buftype_is_contig;
+ MPI_Offset bnelems;
+
+ if (buftype == MPI_DATATYPE_NULL) {
+ /* In this case, bufcount is ignored and will be recalculated to match
+ * count[]. Note buf's data type must match the data type of
+ * variable defined in the file - no data conversion will be done.
+ */
+ bufcount = 1;
+ for (i=0; i<varp->ndims; i++) {
+ if (count[i] < 0) /* no negative count[] */
+ DEBUG_RETURN_ERROR(NC_ENEGATIVECNT)
+ bufcount *= count[i];
+ }
+ /* assign buftype match with the variable's data type */
+ buftype = ncmpii_nc2mpitype(varp->type);
+ }
+
+ status = ncmpii_dtype_decode(buftype, &ptype, &el_size, &bnelems,
+ &isderived, &buftype_is_contig);
+ /* bnelems now is the number of ptype in a buftype */
+ TEST_HANDLE_ERR(status)
+
+#ifdef SUBFILE_DEBUG
+ MPI_Aint lb, extent;
+ MPI_Type_get_extent(buftype, &lb, &extent);
+ printf("rank(%d): var(%s): ptype=0x%x, el_size=%d, bnelems=%d, isderived=%d, buftype_is_contig=%d, lb=%d, extent=%d\n",
+ myrank, varp->name->cp, ptype, el_size, bnelems, isderived, buftype_is_contig, lb, extent);
+#endif
+
+ /* if buftype is non-contiguous, pack to contiguous buffer*/
+ /* NOTE: no conversion and byte swap are performed here
+ as they are done underneath layer */
+ if (!buftype_is_contig && bufcount > 0 && bnelems > 0) {
+ int position=0;
+ MPI_Offset outsize = bnelems * bufcount * el_size;
+ if (outsize != (int)outsize) DEBUG_RETURN_ERROR(NC_EINTOVERFLOW)
+ if (bufcount != (int)bufcount) DEBUG_RETURN_ERROR(NC_EINTOVERFLOW)
+ cbuf = NCI_Malloc((size_t)outsize);
+ if (rw_flag == WRITE_REQ)
+ MPI_Pack(buf, (int)bufcount, buftype, cbuf, (int)outsize,
+ &position, MPI_COMM_SELF);
+ }
+ else
+ cbuf = (void *)buf;
+
+ MPI_Offset diff[ndims_org];
+ for (i=0; i < ndims_org; i++) {
+ MPI_Offset stride_count;
+ stride_count = (stride == NULL?1:stride[i]);
+ /* making diff is necessary?? */
+ diff[i] = ABS(my_req[myrank].start_org[i]-start[i])/stride_count;
+#ifdef SUBFILE_DEBUG
+ if (myrank == 0) printf("rank(%d): my_req[%d].start_org[%d]=%d, start[%d]=%d, diff[%d]=%lld\n", myrank,
+ myrank, i, my_req[myrank].start_org[i], i, start[i], i, diff[i]);
+#endif
+ }
+
+ for (i=0; i<ndims_org; i++) {
+ int l;
+ MPI_Offset tmp=1;
+ for (l=i+1; l < ndims_org ; l++) {
+ tmp *= my_req[myrank].count[l];
+ }
+ buf_offset[myrank] += tmp*diff[i];
+#ifdef SUBFILE_DEBUG
+ if (myrank == 0) printf("local: rank(%d): buf_offset[%d]=%d\n", myrank, myrank, buf_offset[myrank]);
+#endif
+ }
+
+ buf_offset[myrank] *= el_size;
+
+#ifdef SUBFILE_DEBUG
+ printf("rank(%d): buf_offset[%d]=%d, buf_count_my[%d]=%d\n", myrank,
+ myrank, buf_offset[myrank], myrank, buf_count_my[myrank]);
+
+ printf ("rank(%d): %s: var(%s)\n", myrank, __func__, varp->name->cp);
+ for (i=0; i<ndims_org; i++)
+ printf("my_req[%d].start[%d]=%ld, my_req[%d].count[%d]=%ld, my_req[%d].stride[%d]=%ld, bufcount=%ld\n",
+ myrank, i, my_req[myrank].start[i], myrank, i,
+ my_req[myrank].count[i], myrank, i,
+ ((stride != NULL)?stride[i]:1), bufcount);
+#endif
+
+ int *array_of_requests;
+ int *array_of_statuses;
+ /* TODO: each proc can't get more than nprocs-1?? */
+ array_of_requests = (int *)NCI_Malloc((size_t)nprocs * SIZEOF_INT);
+ for (i=0; i<nprocs; i++)
+ array_of_requests[i] = NC_REQ_NULL;
+
+#ifdef SUBFILE_DEBUG
+ printf("buf_count_my[%d]=%d\n", myrank, buf_count_my[myrank]);
+#endif
+ /* doing my portion of I/O */
+ if (count_my_req_per_proc[myrank] != 0) {
+ status = ncmpii_igetput_varm(ncp_sf,
+ ncp_sf->vars.value[varid_sf],
+ my_req[myrank].start,
+ my_req[myrank].count,
+ stride,
+ NULL,
+ (char*)cbuf+buf_offset[myrank],
+ buf_count_my[myrank],
+ (!buftype_is_contig?ptype:buftype),
+ &array_of_requests[nasyncios++],
+ rw_flag,
+ 0, 0);
+ TEST_HANDLE_ERR(status)
+ }
+#ifdef SUBFILE_DEBUG
+ printf("rank(%d): var(%s): pushed local I/O to async calls...\n", myrank, varp->name->cp);
+#endif
+
+ /* doing other proc's request to my subfile
+ TODO: each proc can't get more than nprocs?? */
+ requests = (MPI_Request *)NCI_Malloc((size_t)nprocs*2*sizeof(MPI_Request));
+
+ j = 0;
+#ifdef TAU_SSON
+ TAU_PHASE_CREATE_STATIC(t52, "SSON --- getput_vars: exch count_my_req", "", TAU_USER);
+ TAU_PHASE_START(t52);
+#endif
+ /* TODO: need to exchange count_my_req_per_proc? */
+ count_others_req_per_proc[myrank] = count_my_req_per_proc[myrank];
+
+ for (i=0; i<nprocs; i++)
+ if (count_my_req_per_proc[i] != 0 && i != myrank)
+ TRACE_COMM(MPI_Irecv)(&count_others_req_per_proc[i], 1, MPI_INT, i, i+myrank, ncp->nciop->comm, &requests[j++]);
+
+ for (i=0; i<nprocs; i++)
+ if (count_others_req_per_proc[i] != 0 && i != myrank)
+ TRACE_COMM(MPI_Isend)(&count_my_req_per_proc[i], 1, MPI_INT, i, i+myrank, ncp->nciop->comm, &requests[j++]);
+
+ statuses = (MPI_Status *)NCI_Malloc((size_t)j*sizeof(MPI_Status));
+ TRACE_COMM(MPI_Waitall)(j, requests, statuses);
+#ifdef TAU_SSON
+ TAU_PHASE_STOP(t52);
+#endif
+ check_err(MPI_Waitall);
+ NCI_Free(statuses);
+ NCI_Free(requests);
+
+ j = 0;
+ requests = (MPI_Request *)NCI_Malloc((size_t)nprocs*2*sizeof(MPI_Request));
+
+#ifdef TAU_SSON
+ TAU_PHASE_CREATE_STATIC(t53, "SSON --- getput_vars: exch start,count,", "", TAU_USER);
+ TAU_PHASE_START(t53);
+#endif
+ /* when dest rank == myrank */
+ if (count_others_req_per_proc[myrank] > 0)
+ memcpy(others_req[myrank].start, my_req[myrank].start,
+ (size_t)ndims_org * 3 * SIZEOF_MPI_OFFSET);
+
+ /* exchange my_req's and others_req's start[], count[], and start_org[] */
+ for (i=0; i<nprocs; i++) {
+ if (count_others_req_per_proc[i] != 0 && i != myrank)
+ /* MPI_Offset == MPI_LONG_LONG_INT */
+ TRACE_COMM(MPI_Irecv)(others_req[i].start, 3*ndims_org, MPI_LONG_LONG_INT, i,
+ i+myrank, ncp->nciop->comm, &requests[j++]);
+ }
+ for (i=0; i<nprocs; i++) {
+ if (count_my_req_per_proc[i] != 0 && i != myrank)
+ TRACE_COMM(MPI_Isend)(my_req[i].start, 3 * ndims_org, MPI_LONG_LONG_INT, i,
+ i+myrank, ncp->nciop->comm, &requests[j++]);
+ }
+
+ statuses = (MPI_Status *)NCI_Malloc((size_t)j*sizeof(MPI_Status));
+ TRACE_COMM(MPI_Waitall)(j, requests, statuses);
+ NCI_Free(statuses);
+ NCI_Free(requests);
+
+#ifdef TAU_SSON
+ TAU_PHASE_STOP(t53);
+#endif
+ check_err(MPI_Waitall);
+
+#ifdef SUBFILE_DEBUG
+ /* DEBUG: print out others_req.{start,count} */
+ for (i=0; i<nprocs && myrank == 0; i++) {
+ char str_st[100], str_st_org[100], str_ct[100], str_t1[10];
+ sprintf(str_st, "%d: others.start(", i);
+ sprintf(str_ct, "%d: others.count(", i);
+ sprintf(str_st_org, "%d: others.start_org(", i);
+
+ for (j=0; j<ndims_org; j++) {
+ sprintf(str_t1, "%d", others_req[i].start[j]);
+ strcat(str_st, str_t1);
+ sprintf(str_t1, "%d", others_req[i].count[j]);
+ strcat(str_ct, str_t1);
+ sprintf(str_t1, "%d", others_req[i].start_org[j]);
+ strcat(str_st_org, str_t1);
+ if (j != (ndims_org-1)) {
+ strcat(str_st, ",");
+ strcat(str_ct, ",");
+ strcat(str_st_org, ",");
+ }
+
+ }
+ strcat(str_st, ")");
+ strcat(str_ct, ")");
+ strcat(str_st_org, ")");
+ printf("%s\n", str_st);
+ printf("%s\n", str_ct);
+ printf("%s\n", str_st_org);
+ }
+#endif
+
+ j = 0;
+ requests = (MPI_Request *)NCI_Malloc((size_t)nprocs*2*sizeof(MPI_Request));
+
+ xbuf = (void**)NCI_Calloc((size_t)nprocs, sizeof(void *));
+
+#ifdef TAU_SSON
+ TAU_PHASE_CREATE_STATIC(t54, "SSON --- getput_vars: exch buf", "", TAU_USER);
+ TAU_PHASE_START(t54);
+#endif
+
+ for (i=0; i<nprocs; i++) {
+ /* xbuf[i] = NULL; */
+ buf_count_others[i] = 1;
+ if (count_others_req_per_proc[i] != 0 && i != myrank) {
+ for (k=0; k<ndims_org; k++) {
+ buf_count_others[i] *= others_req[i].count[k];
+ }
+#ifdef SUBFILE_DEBUG
+ printf("rank(%d): recv from rank %d: buf_count_others[%d]=%d\n", myrank, i, i, buf_count_others[i]);
+#endif
+ xbuf[i] = (void*)NCI_Calloc((size_t)buf_count_others[i], (size_t)el_size);
+ TRACE_COMM(MPI_Irecv)(xbuf[i], buf_count_others[i], (!buftype_is_contig?ptype:buftype), i, i+myrank, ncp->nciop->comm, &requests[j++]);
+ }
+ }
+
+ for (i=0; i<nprocs; i++) {
+ buf_count_my[i] = 1;
+ if (count_my_req_per_proc[i] != 0 && i != myrank) {
+ MPI_Offset diff[ndims_org];
+ for (k=0; k < ndims_org; k++) {
+ int l;
+ MPI_Offset stride_count, tmp=1;
+
+ stride_count = (stride == NULL?1:stride[k]);
+ diff[k] = ABS(my_req[i].start_org[k]-start[k])/stride_count;
+
+ for (l=k+1; l < ndims_org; l++)
+ tmp *= my_req[i].count[l];
+
+ buf_offset[i] += tmp*diff[k];
+#ifdef SUBFILE_DEBUG
+ if (myrank == 0) printf("rank(%d): subfile(%d): diff[%d]=%d\n", myrank, i, k, diff[k]);
+#endif
+ }
+
+ buf_offset[i] *= el_size;
+
+ for (k=0; k<ndims_org; k++) {
+ buf_count_my[i] *= my_req[i].count[k];
+ }
+#ifdef SUBFILE_DEBUG
+ printf("rank(%d): send to rank %d: buf_offset[%d]=%d, buf_count_my[%d]=%d\n", myrank, i, i, buf_offset[i], i, buf_count_my[i]);
+#endif
+
+ TRACE_COMM(MPI_Isend)((char*)cbuf+buf_offset[i], buf_count_my[i], (!buftype_is_contig?ptype:buftype), i, i+myrank, ncp->nciop->comm, &requests[j++]);
+ } /* end if() */
+ } /* end for() */
+
+ statuses = (MPI_Status *)NCI_Malloc((size_t)j * sizeof(MPI_Status));
+ TRACE_COMM(MPI_Waitall)(j, requests, statuses);
+ NCI_Free(statuses);
+ NCI_Free(requests);
+
+#ifdef TAU_SSON
+ TAU_PHASE_STOP(t54);
+#endif
+ check_err(MPI_Waitall);
+
+#ifdef TAU_SSON
+ TAU_PHASE_CREATE_STATIC(t55, "SSON --- getput_vars igetput", "", TAU_USER);
+ TAU_PHASE_START(t55);
+#endif
+
+ for (i=0; i<nprocs; i++) {
+ if (count_others_req_per_proc[i] != 0 && i != myrank) {
+ status = ncmpii_igetput_varm(ncp_sf,
+ ncp_sf->vars.value[varid_sf],
+ others_req[i].start,
+ others_req[i].count,
+ stride,
+ NULL,
+ xbuf[i],
+ buf_count_others[i],
+ (!buftype_is_contig?ptype:buftype),
+ &array_of_requests[nasyncios++],
+ rw_flag,
+ 0, 0);
+ TEST_HANDLE_ERR(status)
+ }
+ }
+#ifdef TAU_SSON
+ TAU_PHASE_STOP(t55);
+#endif
+
+#ifdef SUBFILE_DEBUG
+ printf("rank(%d): nasyncios=%d\n", myrank, nasyncios);
+#endif
+
+#ifdef TAU_SSON
+ TAU_PHASE_CREATE_STATIC(t56, "SSON --- getput_vars ncmpi_wait_all", "", TAU_USER);
+ TAU_PHASE_START(t56);
+#endif
+ /*
+ double stime, wait_time;
+ stime = MPI_Wtime();
+ */
+ array_of_statuses = (int *)NCI_Malloc((size_t)nasyncios * SIZEOF_INT);
+ status = ncmpii_wait(ncp_sf, COLL_IO, nasyncios, array_of_requests, array_of_statuses);
+ TEST_HANDLE_ERR(status)
+ NCI_Free(array_of_statuses);
+ NCI_Free(array_of_requests);
+
+ /*
+ int pending_nreqs;
+ status = ncmpi_inq_nreqs(ncp->nciop->fd, &pending_nreqs);
+ printf("myrank(%d): pending_nreqs=%d\n", myrank, pending_nreqs);
+ wait_time = MPI_Wtime() - stime;
+ printf("myrank(%d): ncmpii_wait time = %f\n", myrank, wait_time);
+ */
+#ifdef TAU_SSON
+ TAU_PHASE_STOP(t56);
+#endif
+
+#ifdef SUBFILE_DEBUG
+ printf("rank(%d): var(%s): after ncmpi_wait_all()\n", myrank, varp->name->cp);
+#endif
+
+ /* MPI_Barrier(ncp->nciop->comm); */
+
+ /* free all allocated memories */
+
+ for(i=0; i<nprocs; i++)
+ if (xbuf[i] != NULL) NCI_Free(xbuf[i]);
+ NCI_Free(xbuf);
+
+ if (cbuf != NULL && cbuf != buf) {
+ NCI_Free(cbuf);
+ }
+
+ NCI_Free(count_my_req_per_proc);
+ NCI_Free(count_others_req_per_proc);
+ NCI_Free(buf_count_my);
+ NCI_Free(buf_count_others);
+
+ for (i=0; i<nprocs; i++) {
+ NCI_Free(my_req[i].start);
+ NCI_Free(others_req[i].start);
+ }
+ NCI_Free(my_req);
+ NCI_Free(others_req);
+
+ return status;
+}
diff --git a/src/lib/subfile.h b/src/lib/subfile.h
new file mode 100644
index 0000000..7e209ef
--- /dev/null
+++ b/src/lib/subfile.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2013, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ */
+/* $Id: subfile.h 2021 2015-04-09 20:29:40Z wkliao $ */
+#ifndef SUBFILE_H
+#define SUBFILE_H
+
+#include "pnetcdf.h"
+#include "nc.h"
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+#include "macro.h"
+
+/* structure for storing access info of this process's request
+ to the subfiles on all other processes, and vice-versa. used
+ as array of structures indexed by subfile index. */
+typedef struct {
+ MPI_Offset *start;
+ MPI_Offset *count;
+ MPI_Offset *start_org;
+} NC_subfile_access;
+
+#define CEIL(x) ( (x - (int)x)==0 ? (int)x : (int)x+1 )
+#define FLOOR(x) ( (x - (int)x)==0 ? (int)x : (int)x-1 )
+#define ROUND(x) ( x >= 0 ? (int)(x+0.5) : (int)(x-0.5) )
+#define ABS(a) (((a) < 0) ? -(a) : (a))
+
+#define TEST_HANDLE_ERR(status) \
+ if ((status) != NC_NOERR) { \
+ printf("Error at file %s line %d (%s)\n", __FILE__, __LINE__, \
+ ncmpi_strerror((status)) ); \
+ return status; \
+ }
+
+extern int ncmpii_subfile_create(NC *ncp, int *ncidp);
+
+extern int ncmpii_subfile_open(NC *ncp, int *ncidp);
+
+extern int ncmpii_subfile_close(NC *ncp);
+
+extern int ncmpii_subfile_partition(NC *ncp, int *ncidp);
+
+extern int ncmpii_subfile_getput_vars(NC *ncp, NC_var *varp, const MPI_Offset start[],
+ const MPI_Offset count[], const MPI_Offset stride[],
+ void *buf, MPI_Offset bufcount,
+ MPI_Datatype buftype, int rw_flag, int io_method);
+
+#endif /* end of SUBFILE_H */
diff --git a/src/lib/utf8proc.c b/src/lib/utf8proc.c
new file mode 100644
index 0000000..756a10b
--- /dev/null
+++ b/src/lib/utf8proc.c
@@ -0,0 +1,600 @@
+/*
+ * Copyright (C) 2012, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ */
+/* $Id: utf8proc.c 2220 2015-12-11 23:07:44Z wkliao $ */
+
+/*
+ * Copyright (c) 2006-2007 Jan Behrens, FlexiGuided GmbH, Berlin
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * This library contains derived data from a modified version of the
+ * Unicode data files.
+ *
+ * The original data files are available at
+ * http://www.unicode.org/Public/UNIDATA/
+ *
+ * Please notice the copyright statement in the file "utf8proc_data.c".
+ */
+
+
+/*
+ * File name: utf8proc.c
+ * Version: 1.1.1
+ * Last changed: 2007-07-22
+ *
+ * Description:
+ * Implementation of libutf8proc.
+ */
+
+
+#if HAVE_CONFIG_H
+# include "ncconfig.h"
+#endif
+
+#include "utf8proc.h"
+#include "utf8proc_data.h"
+
+const int8_t utf8proc_utf8class[256] = {
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0 };
+
+#define UTF8PROC_HANGUL_SBASE 0xAC00
+#define UTF8PROC_HANGUL_LBASE 0x1100
+#define UTF8PROC_HANGUL_VBASE 0x1161
+#define UTF8PROC_HANGUL_TBASE 0x11A7
+#define UTF8PROC_HANGUL_LCOUNT 19
+#define UTF8PROC_HANGUL_VCOUNT 21
+#define UTF8PROC_HANGUL_TCOUNT 28
+#define UTF8PROC_HANGUL_NCOUNT 588
+#define UTF8PROC_HANGUL_SCOUNT 11172
+/*// END is exclusive*/
+#define UTF8PROC_HANGUL_L_START 0x1100
+#define UTF8PROC_HANGUL_L_END 0x115A
+#define UTF8PROC_HANGUL_L_FILLER 0x115F
+#define UTF8PROC_HANGUL_V_START 0x1160
+#define UTF8PROC_HANGUL_V_END 0x11A3
+#define UTF8PROC_HANGUL_T_START 0x11A8
+#define UTF8PROC_HANGUL_T_END 0x11FA
+#define UTF8PROC_HANGUL_S_START 0xAC00
+#define UTF8PROC_HANGUL_S_END 0xD7A4
+
+
+#define UTF8PROC_BOUNDCLASS_START 0
+#define UTF8PROC_BOUNDCLASS_OTHER 1
+#define UTF8PROC_BOUNDCLASS_CR 2
+#define UTF8PROC_BOUNDCLASS_LF 3
+#define UTF8PROC_BOUNDCLASS_CONTROL 4
+#define UTF8PROC_BOUNDCLASS_EXTEND 5
+#define UTF8PROC_BOUNDCLASS_L 6
+#define UTF8PROC_BOUNDCLASS_V 7
+#define UTF8PROC_BOUNDCLASS_T 8
+#define UTF8PROC_BOUNDCLASS_LV 9
+#define UTF8PROC_BOUNDCLASS_LVT 10
+
+
+const char *utf8proc_errmsg(ssize_t errcode) {
+ switch (errcode) {
+ case UTF8PROC_ERROR_NOMEM:
+ return "Memory for processing UTF-8 data could not be allocated.";
+ case UTF8PROC_ERROR_OVERFLOW:
+ return "UTF-8 string is too long to be processed.";
+ case UTF8PROC_ERROR_INVALIDUTF8:
+ return "Invalid UTF-8 string";
+ case UTF8PROC_ERROR_NOTASSIGNED:
+ return "Unassigned Unicode code point found in UTF-8 string.";
+ case UTF8PROC_ERROR_INVALIDOPTS:
+ return "Invalid options for UTF-8 processing chosen.";
+ default:
+ return "An unknown error occurred while processing UTF-8 data.";
+ }
+}
+
+ssize_t utf8proc_iterate(
+ const uint8_t *str, ssize_t slen, int32_t *dst
+) {
+ int length;
+ int i;
+ int32_t uc = -1;
+ *dst = -1;
+ if (!slen) return 0;
+ length = utf8proc_utf8class[str[0]];
+ if (!length) return UTF8PROC_ERROR_INVALIDUTF8;
+ if (slen >= 0 && length > slen) return UTF8PROC_ERROR_INVALIDUTF8;
+ for (i=1; i<length; i++) {
+ if ((str[i] & 0xC0) != 0x80) return UTF8PROC_ERROR_INVALIDUTF8;
+ }
+ switch (length) {
+ case 1:
+ uc = str[0];
+ break;
+ case 2:
+ uc = ((str[0] & 0x1F) << 6) + (str[1] & 0x3F);
+ if (uc < 0x80) uc = -1;
+ break;
+ case 3:
+ uc = ((str[0] & 0x0F) << 12) + ((str[1] & 0x3F) << 6)
+ + (str[2] & 0x3F);
+ if (uc < 0x800 || (uc >= 0xD800 && uc < 0xE000) ||
+ (uc >= 0xFDD0 && uc < 0xFDF0)) uc = -1;
+ break;
+ case 4:
+ uc = ((str[0] & 0x07) << 18) + ((str[1] & 0x3F) << 12)
+ + ((str[2] & 0x3F) << 6) + (str[3] & 0x3F);
+ if (uc < 0x10000 || uc >= 0x110000) uc = -1;
+ break;
+ }
+ if (uc < 0 || ((uc & 0xFFFF) >= 0xFFFE))
+ return UTF8PROC_ERROR_INVALIDUTF8;
+ *dst = uc;
+ return length;
+}
+
+bool utf8proc_codepoint_valid(int32_t uc) {
+ if (uc < 0 || uc >= 0x110000 ||
+ ((uc & 0xFFFF) >= 0xFFFE) || (uc >= 0xD800 && uc < 0xE000) ||
+ (uc >= 0xFDD0 && uc < 0xFDF0)) return false;
+ else return true;
+}
+
+ssize_t utf8proc_encode_char(int32_t uc, uint8_t *dst) {
+ if (uc < 0x00) {
+ return 0;
+ } else if (uc < 0x80) {
+ dst[0] = (uint8_t)uc;
+ return 1;
+ } else if (uc < 0x800) {
+ dst[0] = (uint8_t)(0xC0 + (uc >> 6));
+ dst[1] = (uint8_t)(0x80 + (uc & 0x3F));
+ return 2;
+ } else if (uc == 0xFFFF) {
+ dst[0] = 0xFF;
+ return 1;
+ } else if (uc == 0xFFFE) {
+ dst[0] = 0xFE;
+ return 1;
+ } else if (uc < 0x10000) {
+ dst[0] = (uint8_t)(0xE0 + (uc >> 12));
+ dst[1] = (uint8_t)(0x80 + ((uc >> 6) & 0x3F));
+ dst[2] = (uint8_t)(0x80 + (uc & 0x3F));
+ return 3;
+ } else if (uc < 0x110000) {
+ dst[0] = (uint8_t)(0xF0 + (uc >> 18));
+ dst[1] = (uint8_t)(0x80 + ((uc >> 12) & 0x3F));
+ dst[2] = (uint8_t)(0x80 + ((uc >> 6) & 0x3F));
+ dst[3] = (uint8_t)(0x80 + (uc & 0x3F));
+ return 4;
+ } else return 0;
+}
+
+const utf8proc_property_t *utf8proc_get_property(int32_t uc) {
+ /* // ASSERT: uc >= 0 && uc < 0x110000*/
+ return utf8proc_properties + (
+ utf8proc_stage2table[
+ utf8proc_stage1table[uc >> 8] + (uc & 0xFF)
+ ]
+ );
+}
+
+#define utf8proc_decompose_lump(replacement_uc) \
+ return utf8proc_decompose_char((replacement_uc), dst, bufsize, \
+ options & ~UTF8PROC_LUMP, last_boundclass)
+
+ssize_t utf8proc_decompose_char(int32_t uc, int32_t *dst, ssize_t bufsize,
+ int options, int *last_boundclass) {
+ /*// ASSERT: uc >= 0 && uc < 0x110000*/
+ const utf8proc_property_t *property;
+ utf8proc_propval_t category;
+ int32_t hangul_sindex;
+ property = utf8proc_get_property(uc);
+ category = property->category;
+ hangul_sindex = uc - UTF8PROC_HANGUL_SBASE;
+ if (options & (UTF8PROC_COMPOSE|UTF8PROC_DECOMPOSE)) {
+ if (hangul_sindex >= 0 && hangul_sindex < UTF8PROC_HANGUL_SCOUNT) {
+ int32_t hangul_tindex;
+ if (bufsize >= 1) {
+ dst[0] = UTF8PROC_HANGUL_LBASE +
+ hangul_sindex / UTF8PROC_HANGUL_NCOUNT;
+ if (bufsize >= 2) dst[1] = UTF8PROC_HANGUL_VBASE +
+ (hangul_sindex % UTF8PROC_HANGUL_NCOUNT) / UTF8PROC_HANGUL_TCOUNT;
+ }
+ hangul_tindex = hangul_sindex % UTF8PROC_HANGUL_TCOUNT;
+ if (!hangul_tindex) return 2;
+ if (bufsize >= 3) dst[2] = UTF8PROC_HANGUL_TBASE + hangul_tindex;
+ return 3;
+ }
+ }
+ if (options & UTF8PROC_REJECTNA) {
+ if (!category) return UTF8PROC_ERROR_NOTASSIGNED;
+ }
+ if (options & UTF8PROC_IGNORE) {
+ if (property->ignorable) return 0;
+ }
+ if (options & UTF8PROC_LUMP) {
+ if (category == UTF8PROC_CATEGORY_ZS) utf8proc_decompose_lump(0x0020);
+ if (uc == 0x2018 || uc == 0x2019 || uc == 0x02BC || uc == 0x02C8)
+ utf8proc_decompose_lump(0x0027);
+ if (category == UTF8PROC_CATEGORY_PD || uc == 0x2212)
+ utf8proc_decompose_lump(0x002D);
+ if (uc == 0x2044 || uc == 0x2215) utf8proc_decompose_lump(0x002F);
+ if (uc == 0x2236) utf8proc_decompose_lump(0x003A);
+ if (uc == 0x2039 || uc == 0x2329 || uc == 0x3008)
+ utf8proc_decompose_lump(0x003C);
+ if (uc == 0x203A || uc == 0x232A || uc == 0x3009)
+ utf8proc_decompose_lump(0x003E);
+ if (uc == 0x2216) utf8proc_decompose_lump(0x005C);
+ if (uc == 0x02C4 || uc == 0x02C6 || uc == 0x2038 || uc == 0x2303)
+ utf8proc_decompose_lump(0x005E);
+ if (category == UTF8PROC_CATEGORY_PC || uc == 0x02CD)
+ utf8proc_decompose_lump(0x005F);
+ if (uc == 0x02CB) utf8proc_decompose_lump(0x0060);
+ if (uc == 0x2223) utf8proc_decompose_lump(0x007C);
+ if (uc == 0x223C) utf8proc_decompose_lump(0x007E);
+ if ((options & UTF8PROC_NLF2LS) && (options & UTF8PROC_NLF2PS)) {
+ if (category == UTF8PROC_CATEGORY_ZL ||
+ category == UTF8PROC_CATEGORY_ZP)
+ utf8proc_decompose_lump(0x000A);
+ }
+ }
+ if (options & UTF8PROC_STRIPMARK) {
+ if (category == UTF8PROC_CATEGORY_MN ||
+ category == UTF8PROC_CATEGORY_MC ||
+ category == UTF8PROC_CATEGORY_ME) return 0;
+ }
+ if (options & UTF8PROC_CASEFOLD) {
+ if (property->casefold_mapping) {
+ const int32_t *casefold_entry;
+ ssize_t written = 0;
+ for (casefold_entry = property->casefold_mapping;
+ *casefold_entry >= 0; casefold_entry++) {
+ written += utf8proc_decompose_char(*casefold_entry, dst+written,
+ (bufsize > written) ? (bufsize - written) : 0, options,
+ last_boundclass);
+ if (written < 0) return UTF8PROC_ERROR_OVERFLOW;
+ }
+ return written;
+ }
+ }
+ if (options & (UTF8PROC_COMPOSE|UTF8PROC_DECOMPOSE)) {
+ if (property->decomp_mapping &&
+ (!property->decomp_type || (options & UTF8PROC_COMPAT))) {
+ const int32_t *decomp_entry;
+ ssize_t written = 0;
+ for (decomp_entry = property->decomp_mapping;
+ *decomp_entry >= 0; decomp_entry++) {
+ written += utf8proc_decompose_char(*decomp_entry, dst+written,
+ (bufsize > written) ? (bufsize - written) : 0, options,
+ last_boundclass);
+ if (written < 0) return UTF8PROC_ERROR_OVERFLOW;
+ }
+ return written;
+ }
+ }
+ if (options & UTF8PROC_CHARBOUND) {
+ bool boundary;
+ int tbc, lbc;
+ tbc =
+ (uc == 0x000D) ? UTF8PROC_BOUNDCLASS_CR :
+ (uc == 0x000A) ? UTF8PROC_BOUNDCLASS_LF :
+ ((category == UTF8PROC_CATEGORY_ZL ||
+ category == UTF8PROC_CATEGORY_ZP ||
+ category == UTF8PROC_CATEGORY_CC ||
+ category == UTF8PROC_CATEGORY_CF) &&
+ !(uc == 0x200C || uc == 0x200D)) ? UTF8PROC_BOUNDCLASS_CONTROL :
+ property->extend ? UTF8PROC_BOUNDCLASS_EXTEND :
+ ((uc >= UTF8PROC_HANGUL_L_START && uc < UTF8PROC_HANGUL_L_END) ||
+ uc == UTF8PROC_HANGUL_L_FILLER) ? UTF8PROC_BOUNDCLASS_L :
+ (uc >= UTF8PROC_HANGUL_V_START && uc < UTF8PROC_HANGUL_V_END) ?
+ UTF8PROC_BOUNDCLASS_V :
+ (uc >= UTF8PROC_HANGUL_T_START && uc < UTF8PROC_HANGUL_T_END) ?
+ UTF8PROC_BOUNDCLASS_T :
+ (uc >= UTF8PROC_HANGUL_S_START && uc < UTF8PROC_HANGUL_S_END) ? (
+ ((uc-UTF8PROC_HANGUL_SBASE) % UTF8PROC_HANGUL_TCOUNT == 0) ?
+ UTF8PROC_BOUNDCLASS_LV : UTF8PROC_BOUNDCLASS_LVT
+ ) :
+ UTF8PROC_BOUNDCLASS_OTHER;
+ lbc = *last_boundclass;
+ boundary =
+ (tbc == UTF8PROC_BOUNDCLASS_EXTEND) ? false :
+ (lbc == UTF8PROC_BOUNDCLASS_START) ? true :
+ (lbc == UTF8PROC_BOUNDCLASS_CR &&
+ tbc == UTF8PROC_BOUNDCLASS_LF) ? false :
+ (lbc == UTF8PROC_BOUNDCLASS_CONTROL) ? true :
+ (tbc == UTF8PROC_BOUNDCLASS_CONTROL) ? true :
+ (lbc == UTF8PROC_BOUNDCLASS_L &&
+ (tbc == UTF8PROC_BOUNDCLASS_L ||
+ tbc == UTF8PROC_BOUNDCLASS_V ||
+ tbc == UTF8PROC_BOUNDCLASS_LV ||
+ tbc == UTF8PROC_BOUNDCLASS_LVT)) ? false :
+ ((lbc == UTF8PROC_BOUNDCLASS_LV ||
+ lbc == UTF8PROC_BOUNDCLASS_V) &&
+ (tbc == UTF8PROC_BOUNDCLASS_V ||
+ tbc == UTF8PROC_BOUNDCLASS_T)) ? false :
+ ((lbc == UTF8PROC_BOUNDCLASS_LVT ||
+ lbc == UTF8PROC_BOUNDCLASS_T) &&
+ tbc == UTF8PROC_BOUNDCLASS_T) ? false :
+ true;
+ *last_boundclass = tbc;
+ if (boundary) {
+ if (bufsize >= 1) dst[0] = 0xFFFF;
+ if (bufsize >= 2) dst[1] = uc;
+ return 2;
+ }
+ }
+ if (bufsize >= 1) *dst = uc;
+ return 1;
+}
+
+ssize_t utf8proc_decompose(
+ const uint8_t *str, ssize_t slen,
+ int32_t *buffer, ssize_t bufsize, int options
+) {
+ /*// slen will be ignored, if UTF8PROC_NULLTERM is set in options*/
+ ssize_t wpos = 0;
+ if ((options & UTF8PROC_COMPOSE) && (options & UTF8PROC_DECOMPOSE))
+ return UTF8PROC_ERROR_INVALIDOPTS;
+ if ((options & UTF8PROC_STRIPMARK) &&
+ !(options & UTF8PROC_COMPOSE) && !(options & UTF8PROC_DECOMPOSE))
+ return UTF8PROC_ERROR_INVALIDOPTS;
+ {
+ int32_t uc;
+ ssize_t rpos = 0;
+ ssize_t decomp_result;
+ int boundclass = UTF8PROC_BOUNDCLASS_START;
+ while (1) {
+ if (options & UTF8PROC_NULLTERM) {
+ rpos += utf8proc_iterate(str + rpos, -1, &uc);
+ /* checking of return value is not necessary,
+ as 'uc' is < 0 in case of error. */
+ if (uc < 0) return UTF8PROC_ERROR_INVALIDUTF8;
+ if (rpos < 0) return UTF8PROC_ERROR_OVERFLOW;
+ if (uc == 0) break;
+ } else {
+ if (rpos >= slen) break;
+ rpos += utf8proc_iterate(str + rpos, slen - rpos, &uc);
+ if (uc < 0) return UTF8PROC_ERROR_INVALIDUTF8;
+ }
+ decomp_result = utf8proc_decompose_char(
+ uc, buffer + wpos, (bufsize > wpos) ? (bufsize - wpos) : 0, options,
+ &boundclass
+ );
+ if (decomp_result < 0) return decomp_result;
+ wpos += decomp_result;
+ /* // prohibiting integer overflows due to too long strings:*/
+ if (wpos < 0 || wpos > SSIZE_MAX/sizeof(int32_t)/2)
+ return UTF8PROC_ERROR_OVERFLOW;
+ }
+ }
+ if ((options & (UTF8PROC_COMPOSE|UTF8PROC_DECOMPOSE)) && bufsize >= wpos) {
+ ssize_t pos = 0;
+ while (pos < wpos-1) {
+ int32_t uc1, uc2;
+ const utf8proc_property_t *property1, *property2;
+ uc1 = buffer[pos];
+ uc2 = buffer[pos+1];
+ property1 = utf8proc_get_property(uc1);
+ property2 = utf8proc_get_property(uc2);
+ if (property1->combining_class > property2->combining_class &&
+ property2->combining_class > 0) {
+ buffer[pos] = uc2;
+ buffer[pos+1] = uc1;
+ if (pos > 0) pos--; else pos++;
+ } else {
+ pos++;
+ }
+ }
+ }
+ return wpos;
+}
+
+ssize_t utf8proc_reencode(int32_t *buffer, ssize_t length, int options) {
+ /* UTF8PROC_NULLTERM option will be ignored, 'length' is never ignored
+ ASSERT: 'buffer' has one spare byte of free space at the end! */
+ if (options & (UTF8PROC_NLF2LS | UTF8PROC_NLF2PS | UTF8PROC_STRIPCC)) {
+ ssize_t rpos;
+ ssize_t wpos = 0;
+ int32_t uc;
+ for (rpos = 0; rpos < length; rpos++) {
+ uc = buffer[rpos];
+ if (uc == 0x000D && rpos < length-1 && buffer[rpos+1] == 0x000A) rpos++;
+ if (uc == 0x000A || uc == 0x000D || uc == 0x0085 ||
+ ((options & UTF8PROC_STRIPCC) && (uc == 0x000B || uc == 0x000C))) {
+ if (options & UTF8PROC_NLF2LS) {
+ if (options & UTF8PROC_NLF2PS) {
+ buffer[wpos++] = 0x000A;
+ } else {
+ buffer[wpos++] = 0x2028;
+ }
+ } else {
+ if (options & UTF8PROC_NLF2PS) {
+ buffer[wpos++] = 0x2029;
+ } else {
+ buffer[wpos++] = 0x0020;
+ }
+ }
+ } else if ((options & UTF8PROC_STRIPCC) &&
+ (uc < 0x0020 || (uc >= 0x007F && uc < 0x00A0))) {
+ if (uc == 0x0009) buffer[wpos++] = 0x0020;
+ } else {
+ buffer[wpos++] = uc;
+ }
+ }
+ length = wpos;
+ }
+ if (options & UTF8PROC_COMPOSE) {
+ int32_t *starter = NULL;
+ int32_t current_char;
+ const utf8proc_property_t *starter_property = NULL, *current_property;
+ utf8proc_propval_t max_combining_class = -1;
+ ssize_t rpos;
+ ssize_t wpos = 0;
+ int32_t composition;
+ for (rpos = 0; rpos < length; rpos++) {
+ current_char = buffer[rpos];
+ current_property = utf8proc_get_property(current_char);
+ if (starter && current_property->combining_class > max_combining_class) {
+ /* // combination perhaps possible*/
+ int32_t hangul_lindex;
+ int32_t hangul_sindex;
+ hangul_lindex = *starter - UTF8PROC_HANGUL_LBASE;
+ if (hangul_lindex >= 0 && hangul_lindex < UTF8PROC_HANGUL_LCOUNT) {
+ int32_t hangul_vindex;
+ hangul_vindex = current_char - UTF8PROC_HANGUL_VBASE;
+ if (hangul_vindex >= 0 && hangul_vindex < UTF8PROC_HANGUL_VCOUNT) {
+ *starter = UTF8PROC_HANGUL_SBASE +
+ (hangul_lindex * UTF8PROC_HANGUL_VCOUNT + hangul_vindex) *
+ UTF8PROC_HANGUL_TCOUNT;
+ starter_property = NULL;
+ continue;
+ }
+ }
+ hangul_sindex = *starter - UTF8PROC_HANGUL_SBASE;
+ if (hangul_sindex >= 0 && hangul_sindex < UTF8PROC_HANGUL_SCOUNT &&
+ (hangul_sindex % UTF8PROC_HANGUL_TCOUNT) == 0) {
+ int32_t hangul_tindex;
+ hangul_tindex = current_char - UTF8PROC_HANGUL_TBASE;
+ if (hangul_tindex >= 0 && hangul_tindex < UTF8PROC_HANGUL_TCOUNT) {
+ *starter += hangul_tindex;
+ starter_property = NULL;
+ continue;
+ }
+ }
+ if (!starter_property) {
+ starter_property = utf8proc_get_property(*starter);
+ }
+ if (starter_property->comb1st_index >= 0 &&
+ current_property->comb2nd_index >= 0) {
+ composition = utf8proc_combinations[
+ starter_property->comb1st_index +
+ current_property->comb2nd_index
+ ];
+ if (composition >= 0 && (!(options & UTF8PROC_STABLE) ||
+ !(utf8proc_get_property(composition)->comp_exclusion))) {
+ *starter = composition;
+ starter_property = NULL;
+ continue;
+ }
+ }
+ }
+ buffer[wpos] = current_char;
+ if (current_property->combining_class) {
+ if (current_property->combining_class > max_combining_class) {
+ max_combining_class = current_property->combining_class;
+ }
+ } else {
+ starter = buffer + wpos;
+ starter_property = NULL;
+ max_combining_class = -1;
+ }
+ wpos++;
+ }
+ length = wpos;
+ }
+ {
+ ssize_t rpos, wpos = 0;
+ int32_t uc;
+ for (rpos = 0; rpos < length; rpos++) {
+ uc = buffer[rpos];
+ wpos += utf8proc_encode_char(uc, ((uint8_t *)buffer) + wpos);
+ }
+ ((uint8_t *)buffer)[wpos] = 0;
+ return wpos;
+ }
+}
+
+ssize_t utf8proc_map(
+ const uint8_t *str, ssize_t slen, uint8_t **dstptr, int options
+) {
+ int32_t *buffer;
+ ssize_t result;
+ *dstptr = NULL;
+ result = utf8proc_decompose(str, slen, NULL, 0, options);
+ if (result < 0) return result;
+ buffer = (int32_t*)malloc(((size_t)result) * sizeof(int32_t) + 1);
+ if (!buffer) return UTF8PROC_ERROR_NOMEM;
+ result = utf8proc_decompose(str, slen, buffer, result, options);
+ if (result < 0) {
+ free(buffer);
+ return result;
+ }
+ result = utf8proc_reencode(buffer, result, options);
+ if (result < 0) {
+ free(buffer);
+ return result;
+ }
+ {
+ int32_t *newptr;
+ newptr = (int32_t*) realloc(buffer, (size_t)result+1);
+ if (newptr) buffer = newptr;
+ }
+ *dstptr = (uint8_t *)buffer;
+ return result;
+}
+
+uint8_t *utf8proc_NFD(const uint8_t *str) {
+ uint8_t *retval;
+ utf8proc_map(str, 0, &retval, UTF8PROC_NULLTERM | UTF8PROC_STABLE |
+ UTF8PROC_DECOMPOSE);
+ return retval;
+}
+
+uint8_t *utf8proc_NFC(const uint8_t *str) {
+ uint8_t *retval;
+ utf8proc_map(str, 0, &retval, UTF8PROC_NULLTERM | UTF8PROC_STABLE |
+ UTF8PROC_COMPOSE);
+ return retval;
+}
+
+uint8_t *utf8proc_NFKD(const uint8_t *str) {
+ uint8_t *retval;
+ utf8proc_map(str, 0, &retval, UTF8PROC_NULLTERM | UTF8PROC_STABLE |
+ UTF8PROC_DECOMPOSE | UTF8PROC_COMPAT);
+ return retval;
+}
+
+uint8_t *utf8proc_NFKC(const uint8_t *str) {
+ uint8_t *retval;
+ utf8proc_map(str, 0, &retval, UTF8PROC_NULLTERM | UTF8PROC_STABLE |
+ UTF8PROC_COMPOSE | UTF8PROC_COMPAT);
+ return retval;
+}
+
+ssize_t utf8proc_check(const uint8_t *str) {
+ ssize_t result;
+ result = utf8proc_decompose(str, 0, NULL, 0,
+ UTF8PROC_NULLTERM | UTF8PROC_STABLE);
+ return result;
+}
diff --git a/src/lib/utf8proc.h b/src/lib/utf8proc.h
new file mode 100644
index 0000000..41ae4ec
--- /dev/null
+++ b/src/lib/utf8proc.h
@@ -0,0 +1,407 @@
+/*
+ * Copyright (C) 2012, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ */
+/* $Id: utf8proc.h 2220 2015-12-11 23:07:44Z wkliao $ */
+
+/*
+ * Copyright (c) 2006-2007 Jan Behrens, FlexiGuided GmbH, Berlin
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * File name: utf8proc.h
+ * Version: 1.1.1
+ * Last changed: 2007-07-22
+ * Changed 2008-05-16 by rkr to add config.h and replacement for stdbool.h
+ * for pre-C99 compilers that don't support bool.
+ * Changed 2008-06-05 by rkr to add utf8proc_check(str, options) function for
+ * for just checking UTF-8 validity
+ * Description:
+ * Header files for libutf8proc, which is a mapping tool for UTF-8 strings
+ * with following features:
+ * - decomposing and composing of strings
+ * - replacing compatibility characters with their equivalents
+ * - stripping of "default ignorable characters"
+ * like SOFT-HYPHEN or ZERO-WIDTH-SPACE
+ * - folding of certain characters for string comparison
+ * (e.g. HYPHEN U+2010 and MINUS U+2212 to ASCII "-")
+ * (see "LUMP" option)
+ * - optional rejection of strings containing non-assigned code points
+ * - stripping of control characters
+ * - stripping of character marks (accents, etc.)
+ * - transformation of LF, CRLF, CR and NEL to line-feed (LF)
+ * or to the unicode chararacters for paragraph separation (PS)
+ * or line separation (LS).
+ * - unicode case folding (for case insensitive string comparisons)
+ * - rejection of illegal UTF-8 data
+ * (i.e. UTF-8 encoded UTF-16 surrogates)
+ * - support for korean hangul characters
+ * Unicode Version 5.0.0 is supported.
+ */
+
+
+#ifndef UTF8PROC_H
+#define UTF8PROC_H
+
+#if HAVE_CONFIG_H
+# include "ncconfig.h"
+#endif
+
+#include <stdlib.h>
+#ifdef HAVE_STDBOOL_H
+#include <stdbool.h>
+#else
+# if ! HAVE__BOOL
+# ifdef __cplusplus
+typedef bool _Bool;
+# else
+typedef unsigned char _Bool;
+# endif
+# endif
+#ifndef _Bool
+# define bool _Bool
+#endif
+# define false 0
+# define true 1
+# define __bool_true_false_are_defined 1
+#endif
+#include <sys/types.h>
+#ifdef HAVE_INTTYPES_H
+#include <inttypes.h>
+#elif defined(_MSC_VER) && defined(HAVE_STDINT_H)
+#include <stdint.h>
+#else /* HAVE_INTTYPES_H */
+#include <pstdint.h>
+#endif /* HAVE_INTTYPES_H */
+#include <limits.h>
+
+#ifndef HAVE_SSIZE_T
+#define ssize_t int
+#endif
+
+#ifndef SSIZE_MAX
+#define SSIZE_MAX (SIZE_MAX/2)
+#endif
+
+#define UTF8PROC_NULLTERM (1<<0)
+#define UTF8PROC_STABLE (1<<1)
+#define UTF8PROC_COMPAT (1<<2)
+#define UTF8PROC_COMPOSE (1<<3)
+#define UTF8PROC_DECOMPOSE (1<<4)
+#define UTF8PROC_IGNORE (1<<5)
+#define UTF8PROC_REJECTNA (1<<6)
+#define UTF8PROC_NLF2LS (1<<7)
+#define UTF8PROC_NLF2PS (1<<8)
+#define UTF8PROC_NLF2LF (UTF8PROC_NLF2LS | UTF8PROC_NLF2PS)
+#define UTF8PROC_STRIPCC (1<<9)
+#define UTF8PROC_CASEFOLD (1<<10)
+#define UTF8PROC_CHARBOUND (1<<11)
+#define UTF8PROC_LUMP (1<<12)
+#define UTF8PROC_STRIPMARK (1<<13)
+/*
+ * Flags being regarded by several functions in the library:
+ * NULLTERM: The given UTF-8 input is NULL terminated.
+ * STABLE: Unicode Versioning Stability has to be respected.
+ * COMPAT: Compatibility decomposition
+ * (i.e. formatting information is lost)
+ * COMPOSE: Return a result with composed characters.
+ * DECOMPOSE: Return a result with decomposed characters.
+ * IGNORE: Strip "default ignorable characters"
+ * REJECTNA: Return an error, if the input contains unassigned
+ * code points.
+ * NLF2LS: Indicating that NLF-sequences (LF, CRLF, CR, NEL) are
+ * representing a line break, and should be converted to the
+ * unicode character for line separation (LS).
+ * NLF2PS: Indicating that NLF-sequences are representing a paragraph
+ * break, and should be converted to the unicode character for
+ * paragraph separation (PS).
+ * NLF2LF: Indicating that the meaning of NLF-sequences is unknown.
+ * STRIPCC: Strips and/or convers control characters.
+ * NLF-sequences are transformed into space, except if one of
+ * the NLF2LS/PS/LF options is given.
+ * HorizontalTab (HT) and FormFeed (FF) are treated as a
+ * NLF-sequence in this case.
+ * All other control characters are simply removed.
+ * CASEFOLD: Performs unicode case folding, to be able to do a
+ * case-insensitive string comparison.
+ * CHARBOUND: Inserts 0xFF bytes at the beginning of each sequence which
+ * is representing a single grapheme cluster (see UAX#29).
+ * LUMP: Lumps certain characters together
+ * (e.g. HYPHEN U+2010 and MINUS U+2212 to ASCII "-").
+ * (See lump.txt for details.)
+ * If NLF2LF is set, this includes a transformation of
+ * paragraph and line separators to ASCII line-feed (LF).
+ * STRIPMARK: Strips all character markings
+ * (non-spacing, spacing and enclosing) (i.e. accents)
+ * NOTE: this option works only with COMPOSE or DECOMPOSE
+ */
+
+#define UTF8PROC_ERROR_NOMEM -1
+#define UTF8PROC_ERROR_OVERFLOW -2
+#define UTF8PROC_ERROR_INVALIDUTF8 -3
+#define UTF8PROC_ERROR_NOTASSIGNED -4
+#define UTF8PROC_ERROR_INVALIDOPTS -5
+/*
+ * Error codes being returned by almost all functions:
+ * ERROR_NOMEM: Memory could not be allocated.
+ * ERROR_OVERFLOW: The given string is too long to be processed.
+ * ERROR_INVALIDUTF8: The given string is not a legal UTF-8 string.
+ * ERROR_NOTASSIGNED: The REJECTNA flag was set,
+ * and an unassigned code point was found.
+ * ERROR_INVALIDOPTS: Invalid options have been used.
+ */
+
+typedef int16_t utf8proc_propval_t;
+typedef struct utf8proc_property_struct {
+ utf8proc_propval_t category;
+ utf8proc_propval_t combining_class;
+ utf8proc_propval_t bidi_class;
+ utf8proc_propval_t decomp_type;
+ const int32_t *decomp_mapping;
+ unsigned bidi_mirrored:1;
+ int32_t uppercase_mapping;
+ int32_t lowercase_mapping;
+ int32_t titlecase_mapping;
+ int32_t comb1st_index;
+ int32_t comb2nd_index;
+ unsigned comp_exclusion:1;
+ unsigned ignorable:1;
+ unsigned control_boundary:1;
+ unsigned extend:1;
+ const int32_t *casefold_mapping;
+} utf8proc_property_t;
+
+#define UTF8PROC_CATEGORY_LU 1
+#define UTF8PROC_CATEGORY_LL 2
+#define UTF8PROC_CATEGORY_LT 3
+#define UTF8PROC_CATEGORY_LM 4
+#define UTF8PROC_CATEGORY_LO 5
+#define UTF8PROC_CATEGORY_MN 6
+#define UTF8PROC_CATEGORY_MC 7
+#define UTF8PROC_CATEGORY_ME 8
+#define UTF8PROC_CATEGORY_ND 9
+#define UTF8PROC_CATEGORY_NL 10
+#define UTF8PROC_CATEGORY_NO 11
+#define UTF8PROC_CATEGORY_PC 12
+#define UTF8PROC_CATEGORY_PD 13
+#define UTF8PROC_CATEGORY_PS 14
+#define UTF8PROC_CATEGORY_PE 15
+#define UTF8PROC_CATEGORY_PI 16
+#define UTF8PROC_CATEGORY_PF 17
+#define UTF8PROC_CATEGORY_PO 18
+#define UTF8PROC_CATEGORY_SM 19
+#define UTF8PROC_CATEGORY_SC 20
+#define UTF8PROC_CATEGORY_SK 21
+#define UTF8PROC_CATEGORY_SO 22
+#define UTF8PROC_CATEGORY_ZS 23
+#define UTF8PROC_CATEGORY_ZL 24
+#define UTF8PROC_CATEGORY_ZP 25
+#define UTF8PROC_CATEGORY_CC 26
+#define UTF8PROC_CATEGORY_CF 27
+#define UTF8PROC_CATEGORY_CS 28
+#define UTF8PROC_CATEGORY_CO 29
+#define UTF8PROC_CATEGORY_CN 30
+#define UTF8PROC_BIDI_CLASS_L 1
+#define UTF8PROC_BIDI_CLASS_LRE 2
+#define UTF8PROC_BIDI_CLASS_LRO 3
+#define UTF8PROC_BIDI_CLASS_R 4
+#define UTF8PROC_BIDI_CLASS_AL 5
+#define UTF8PROC_BIDI_CLASS_RLE 6
+#define UTF8PROC_BIDI_CLASS_RLO 7
+#define UTF8PROC_BIDI_CLASS_PDF 8
+#define UTF8PROC_BIDI_CLASS_EN 9
+#define UTF8PROC_BIDI_CLASS_ES 10
+#define UTF8PROC_BIDI_CLASS_ET 11
+#define UTF8PROC_BIDI_CLASS_AN 12
+#define UTF8PROC_BIDI_CLASS_CS 13
+#define UTF8PROC_BIDI_CLASS_NSM 14
+#define UTF8PROC_BIDI_CLASS_BN 15
+#define UTF8PROC_BIDI_CLASS_B 16
+#define UTF8PROC_BIDI_CLASS_S 17
+#define UTF8PROC_BIDI_CLASS_WS 18
+#define UTF8PROC_BIDI_CLASS_ON 19
+#define UTF8PROC_DECOMP_TYPE_FONT 1
+#define UTF8PROC_DECOMP_TYPE_NOBREAK 2
+#define UTF8PROC_DECOMP_TYPE_INITIAL 3
+#define UTF8PROC_DECOMP_TYPE_MEDIAL 4
+#define UTF8PROC_DECOMP_TYPE_FINAL 5
+#define UTF8PROC_DECOMP_TYPE_ISOLATED 6
+#define UTF8PROC_DECOMP_TYPE_CIRCLE 7
+#define UTF8PROC_DECOMP_TYPE_SUPER 8
+#define UTF8PROC_DECOMP_TYPE_SUB 9
+#define UTF8PROC_DECOMP_TYPE_VERTICAL 10
+#define UTF8PROC_DECOMP_TYPE_WIDE 11
+#define UTF8PROC_DECOMP_TYPE_NARROW 12
+#define UTF8PROC_DECOMP_TYPE_SMALL 13
+#define UTF8PROC_DECOMP_TYPE_SQUARE 14
+#define UTF8PROC_DECOMP_TYPE_FRACTION 15
+#define UTF8PROC_DECOMP_TYPE_COMPAT 16
+
+extern const int8_t utf8proc_utf8class[256];
+
+const char *utf8proc_errmsg(ssize_t errcode);
+/*
+ * Returns a static error string for the given error code.
+ */
+
+ssize_t utf8proc_iterate(const uint8_t *str, ssize_t strlen, int32_t *dst);
+/*
+ * Reads a single char from the UTF-8 sequence being pointed to by 'str'.
+ * The maximum number of bytes read is 'strlen', unless 'strlen' is
+ * negative.
+ * If a valid unicode char could be read, it is stored in the variable
+ * being pointed to by 'dst', otherwise that variable will be set to -1.
+ * In case of success the number of bytes read is returned, otherwise a
+ * negative error code is returned.
+ */
+
+bool utf8proc_codepoint_valid(int32_t uc);
+/*
+ * Returns 1, if the given unicode code-point is valid, otherwise 0.
+ */
+
+ssize_t utf8proc_encode_char(int32_t uc, uint8_t *dst);
+/*
+ * Encodes the unicode char with the code point 'uc' as an UTF-8 string in
+ * the byte array being pointed to by 'dst'. This array has to be at least
+ * 4 bytes long.
+ * In case of success the number of bytes written is returned,
+ * otherwise 0.
+ * This function does not check if 'uc' is a valid unicode code point.
+ */
+
+const utf8proc_property_t *utf8proc_get_property(int32_t uc);
+/*
+ * Returns a pointer to a (constant) struct containing information about
+ * the unicode char with the given code point 'uc'.
+ * If the character is not existent a pointer to a special struct is
+ * returned, where 'category' is a NULL pointer.
+ * WARNING: The parameter 'uc' has to be in the range of 0x0000 to
+ * 0x10FFFF, otherwise the program might crash!
+ */
+
+ssize_t utf8proc_decompose_char(
+ int32_t uc, int32_t *dst, ssize_t bufsize,
+ int options, int *last_boundclass
+);
+/*
+ * Writes a decomposition of the unicode char 'uc' into the array being
+ * pointed to by 'dst'.
+ * Following flags in the 'options' field are regarded:
+ * REJECTNA: an unassigned unicode code point leads to an error
+ * IGNORE: "default ignorable" chars are stripped
+ * CASEFOLD: unicode casefolding is applied
+ * COMPAT: replace certain characters with their
+ * compatibility decomposition
+ * CHARBOUND: Inserts 0xFF bytes before each grapheme cluster
+ * LUMP: lumps certain different characters together
+ * STRIPMARK: removes all character marks
+ * The pointer 'last_boundclass' has to point to an integer variable which
+ * is storing the last character boundary class, if the CHARBOUND option
+ * is used.
+ * In case of success the number of chars written is returned,
+ * in case of an error, a negative error code is returned.
+ * If the number of written chars would be bigger than 'bufsize',
+ * the buffer (up to 'bufsize') has inpredictable data, and the needed
+ * buffer size is returned.
+ * WARNING: The parameter 'uc' has to be in the range of 0x0000 to
+ * 0x10FFFF, otherwise the program might crash!
+ */
+
+ssize_t utf8proc_decompose(
+ const uint8_t *str, ssize_t strlen,
+ int32_t *buffer, ssize_t bufsize, int options
+);
+/*
+ * Does the same as 'utf8proc_decompose_char', but acts on a whole UTF-8
+ * string, and orders the decomposed sequences correctly.
+ * If the NULLTERM flag in 'options' is set, processing will be stopped,
+ * when a NULL byte is encounted, otherwise 'strlen' bytes are processed.
+ * The result in form of unicode code points is written into the buffer
+ * being pointed to by 'buffer', having the length of 'bufsize' entries.
+ * In case of success the number of chars written is returned,
+ * in case of an error, a negative error code is returned.
+ * If the number of written chars would be bigger than 'bufsize',
+ * the buffer (up to 'bufsize') has inpredictable data, and the needed
+ * buffer size is returned.
+ */
+
+ssize_t utf8proc_reencode(int32_t *buffer, ssize_t length, int options);
+/*
+ * Reencodes the sequence of unicode characters given by the pointer
+ * 'buffer' and 'length' as UTF-8.
+ * The result is stored in the same memory area where the data is read.
+ * Following flags in the 'options' field are regarded:
+ * NLF2LS: converts LF, CRLF, CR and NEL into LS
+ * NLF2PS: converts LF, CRLF, CR and NEL into PS
+ * NLF2LF: converts LF, CRLF, CR and NEL into LF
+ * STRIPCC: strips or converts all non-affected control characters
+ * COMPOSE: tries to combine decomposed characters into composite
+ * characters
+ * STABLE: prohibits combining characters which would violate
+ * the unicode versioning stability
+ * In case of success the length of the resulting UTF-8 string is
+ * returned, otherwise a negative error code is returned.
+ * WARNING: The amount of free space being pointed to by 'buffer', has to
+ * exceed the amount of the input data by one byte, and the
+ * entries of the array pointed to by 'str' have to be in the
+ * range of 0x0000 to 0x10FFFF, otherwise the program might
+ * crash!
+ */
+
+ssize_t utf8proc_map(
+ const uint8_t *str, ssize_t strlen, uint8_t **dstptr, int options
+);
+/*
+ * Maps the given UTF-8 string being pointed to by 'str' to a new UTF-8
+ * string, which is allocated dynamically, and afterwards pointed to by
+ * the pointer being pointed to by 'dstptr'.
+ * If the NULLTERM flag in the 'options' field is set, the length is
+ * determined by a NULL terminator, otherwise the parameter 'strlen' is
+ * evaluated to determine the string length, but in any case the result
+ * will be NULL terminated (though it might contain NULL characters
+ * before). Other flags in the 'options' field are passed to the functions
+ * defined above, and regarded as described.
+ * In case of success the length of the new string is returned,
+ * otherwise a negative error code is returned.
+ * NOTICE: The memory of the new UTF-8 string will have been allocated with
+ * 'malloc', and has theirfore to be freed with 'free'.
+ */
+
+uint8_t *utf8proc_NFD(const uint8_t *str);
+uint8_t *utf8proc_NFC(const uint8_t *str);
+uint8_t *utf8proc_NFKD(const uint8_t *str);
+uint8_t *utf8proc_NFKC(const uint8_t *str);
+/*
+ * Returns a pointer to newly allocated memory of a NFD, NFC, NFKD or NFKC
+ * normalized version of the null-terminated string 'str'.
+ */
+
+ssize_t utf8proc_check(const uint8_t *str);
+/*
+ * Just checks UTF-8 string for validity, returns 0 if valid or one of
+ * the negative UTF8PROC_ERROR_* codes if invalid or memory exhausted
+ * checking. Assumes null-terminated string str and UTF8PROC_STABLE
+ * option.
+ */
+
+#endif
+
diff --git a/src/lib/utf8proc_data.h b/src/lib/utf8proc_data.h
new file mode 100644
index 0000000..475be23
--- /dev/null
+++ b/src/lib/utf8proc_data.h
@@ -0,0 +1,13389 @@
+/*
+ * Copyright (C) 2012, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ */
+/* $Id: utf8proc_data.h 1468 2013-10-26 16:53:18Z wkliao $ */
+
+/*
+ * This file contains derived data from a modified version of the
+ * Unicode data files.
+ *
+ * The original data files are available at
+ * http://www.unicode.org/Public/UNIDATA/
+ *
+ *
+ * COPYRIGHT AND PERMISSION NOTICE
+ *
+ * Copyright (c) 1991-2007 Unicode, Inc. All rights reserved. Distributed
+ * under the Terms of Use in http://www.unicode.org/copyright.html.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of the Unicode data files and any associated documentation (the "Data
+ * Files") or Unicode software and any associated documentation (the
+ * "Software") to deal in the Data Files or Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, and/or sell copies of the Data Files or Software, and
+ * to permit persons to whom the Data Files or Software are furnished to do
+ * so, provided that (a) the above copyright notice(s) and this permission
+ * notice appear with all copies of the Data Files or Software, (b) both the
+ * above copyright notice(s) and this permission notice appear in associated
+ * documentation, and (c) there is clear notice in each modified Data File or
+ * in the Software as well as in the documentation associated with the Data
+ * File(s) or Software that the data or software has been modified.
+ *
+ * THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+ * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
+ * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
+ * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR
+ * CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+ * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THE DATA FILES OR SOFTWARE.
+ *
+ * Except as contained in this notice, the name of a copyright holder shall
+ * not be used in advertising or otherwise to promote the sale, use or other
+ * dealings in these Data Files or Software without prior written
+ * authorization of the copyright holder.
+ */
+
+
+const int32_t utf8proc_sequences[] = {
+ 97, -1, 98, -1, 99, -1, 100,
+ -1, 101, -1, 102, -1, 103, -1, 104,
+ -1, 105, -1, 106, -1, 107, -1, 108,
+ -1, 109, -1, 110, -1, 111, -1, 112,
+ -1, 113, -1, 114, -1, 115, -1, 116,
+ -1, 117, -1, 118, -1, 119, -1, 120,
+ -1, 121, -1, 122, -1, 32, -1, 32,
+ 776, -1, 32, 772, -1, 50, -1, 51,
+ -1, 32, 769, -1, 956, -1, 32, 807,
+ -1, 49, -1, 49, 8260, 52, -1, 49,
+ 8260, 50, -1, 51, 8260, 52, -1, 65,
+ 768, -1, 224, -1, 65, 769, -1, 225,
+ -1, 65, 770, -1, 226, -1, 65, 771,
+ -1, 227, -1, 65, 776, -1, 228, -1,
+ 65, 778, -1, 229, -1, 230, -1, 67,
+ 807, -1, 231, -1, 69, 768, -1, 232,
+ -1, 69, 769, -1, 233, -1, 69, 770,
+ -1, 234, -1, 69, 776, -1, 235, -1,
+ 73, 768, -1, 236, -1, 73, 769, -1,
+ 237, -1, 73, 770, -1, 238, -1, 73,
+ 776, -1, 239, -1, 240, -1, 78, 771,
+ -1, 241, -1, 79, 768, -1, 242, -1,
+ 79, 769, -1, 243, -1, 79, 770, -1,
+ 244, -1, 79, 771, -1, 245, -1, 79,
+ 776, -1, 246, -1, 248, -1, 85, 768,
+ -1, 249, -1, 85, 769, -1, 250, -1,
+ 85, 770, -1, 251, -1, 85, 776, -1,
+ 252, -1, 89, 769, -1, 253, -1, 254,
+ -1, 115, 115, -1, 97, 768, -1, 97,
+ 769, -1, 97, 770, -1, 97, 771, -1,
+ 97, 776, -1, 97, 778, -1, 99, 807,
+ -1, 101, 768, -1, 101, 769, -1, 101,
+ 770, -1, 101, 776, -1, 105, 768, -1,
+ 105, 769, -1, 105, 770, -1, 105, 776,
+ -1, 110, 771, -1, 111, 768, -1, 111,
+ 769, -1, 111, 770, -1, 111, 771, -1,
+ 111, 776, -1, 117, 768, -1, 117, 769,
+ -1, 117, 770, -1, 117, 776, -1, 121,
+ 769, -1, 121, 776, -1, 65, 772, -1,
+ 257, -1, 97, 772, -1, 65, 774, -1,
+ 259, -1, 97, 774, -1, 65, 808, -1,
+ 261, -1, 97, 808, -1, 67, 769, -1,
+ 263, -1, 99, 769, -1, 67, 770, -1,
+ 265, -1, 99, 770, -1, 67, 775, -1,
+ 267, -1, 99, 775, -1, 67, 780, -1,
+ 269, -1, 99, 780, -1, 68, 780, -1,
+ 271, -1, 100, 780, -1, 273, -1, 69,
+ 772, -1, 275, -1, 101, 772, -1, 69,
+ 774, -1, 277, -1, 101, 774, -1, 69,
+ 775, -1, 279, -1, 101, 775, -1, 69,
+ 808, -1, 281, -1, 101, 808, -1, 69,
+ 780, -1, 283, -1, 101, 780, -1, 71,
+ 770, -1, 285, -1, 103, 770, -1, 71,
+ 774, -1, 287, -1, 103, 774, -1, 71,
+ 775, -1, 289, -1, 103, 775, -1, 71,
+ 807, -1, 291, -1, 103, 807, -1, 72,
+ 770, -1, 293, -1, 104, 770, -1, 295,
+ -1, 73, 771, -1, 297, -1, 105, 771,
+ -1, 73, 772, -1, 299, -1, 105, 772,
+ -1, 73, 774, -1, 301, -1, 105, 774,
+ -1, 73, 808, -1, 303, -1, 105, 808,
+ -1, 73, 775, -1, 105, 775, -1, 73,
+ 74, -1, 307, -1, 105, 106, -1, 74,
+ 770, -1, 309, -1, 106, 770, -1, 75,
+ 807, -1, 311, -1, 107, 807, -1, 76,
+ 769, -1, 314, -1, 108, 769, -1, 76,
+ 807, -1, 316, -1, 108, 807, -1, 76,
+ 780, -1, 318, -1, 108, 780, -1, 76,
+ 183, -1, 320, -1, 108, 183, -1, 322,
+ -1, 78, 769, -1, 324, -1, 110, 769,
+ -1, 78, 807, -1, 326, -1, 110, 807,
+ -1, 78, 780, -1, 328, -1, 110, 780,
+ -1, 700, 110, -1, 331, -1, 79, 772,
+ -1, 333, -1, 111, 772, -1, 79, 774,
+ -1, 335, -1, 111, 774, -1, 79, 779,
+ -1, 337, -1, 111, 779, -1, 339, -1,
+ 82, 769, -1, 341, -1, 114, 769, -1,
+ 82, 807, -1, 343, -1, 114, 807, -1,
+ 82, 780, -1, 345, -1, 114, 780, -1,
+ 83, 769, -1, 347, -1, 115, 769, -1,
+ 83, 770, -1, 349, -1, 115, 770, -1,
+ 83, 807, -1, 351, -1, 115, 807, -1,
+ 83, 780, -1, 353, -1, 115, 780, -1,
+ 84, 807, -1, 355, -1, 116, 807, -1,
+ 84, 780, -1, 357, -1, 116, 780, -1,
+ 359, -1, 85, 771, -1, 361, -1, 117,
+ 771, -1, 85, 772, -1, 363, -1, 117,
+ 772, -1, 85, 774, -1, 365, -1, 117,
+ 774, -1, 85, 778, -1, 367, -1, 117,
+ 778, -1, 85, 779, -1, 369, -1, 117,
+ 779, -1, 85, 808, -1, 371, -1, 117,
+ 808, -1, 87, 770, -1, 373, -1, 119,
+ 770, -1, 89, 770, -1, 375, -1, 121,
+ 770, -1, 89, 776, -1, 255, -1, 90,
+ 769, -1, 378, -1, 122, 769, -1, 90,
+ 775, -1, 380, -1, 122, 775, -1, 90,
+ 780, -1, 382, -1, 122, 780, -1, 595,
+ -1, 387, -1, 389, -1, 596, -1, 392,
+ -1, 598, -1, 599, -1, 396, -1, 477,
+ -1, 601, -1, 603, -1, 402, -1, 608,
+ -1, 611, -1, 617, -1, 616, -1, 409,
+ -1, 623, -1, 626, -1, 629, -1, 79,
+ 795, -1, 417, -1, 111, 795, -1, 419,
+ -1, 421, -1, 640, -1, 424, -1, 643,
+ -1, 429, -1, 648, -1, 85, 795, -1,
+ 432, -1, 117, 795, -1, 650, -1, 651,
+ -1, 436, -1, 438, -1, 658, -1, 441,
+ -1, 445, -1, 68, 381, -1, 454, -1,
+ 68, 382, -1, 100, 382, -1, 76, 74,
+ -1, 457, -1, 76, 106, -1, 108, 106,
+ -1, 78, 74, -1, 460, -1, 78, 106,
+ -1, 110, 106, -1, 65, 780, -1, 462,
+ -1, 97, 780, -1, 73, 780, -1, 464,
+ -1, 105, 780, -1, 79, 780, -1, 466,
+ -1, 111, 780, -1, 85, 780, -1, 468,
+ -1, 117, 780, -1, 220, 772, -1, 470,
+ -1, 252, 772, -1, 220, 769, -1, 472,
+ -1, 252, 769, -1, 220, 780, -1, 474,
+ -1, 252, 780, -1, 220, 768, -1, 476,
+ -1, 252, 768, -1, 196, 772, -1, 479,
+ -1, 228, 772, -1, 550, 772, -1, 481,
+ -1, 551, 772, -1, 198, 772, -1, 483,
+ -1, 230, 772, -1, 485, -1, 71, 780,
+ -1, 487, -1, 103, 780, -1, 75, 780,
+ -1, 489, -1, 107, 780, -1, 79, 808,
+ -1, 491, -1, 111, 808, -1, 490, 772,
+ -1, 493, -1, 491, 772, -1, 439, 780,
+ -1, 495, -1, 658, 780, -1, 106, 780,
+ -1, 68, 90, -1, 499, -1, 68, 122,
+ -1, 100, 122, -1, 71, 769, -1, 501,
+ -1, 103, 769, -1, 405, -1, 447, -1,
+ 78, 768, -1, 505, -1, 110, 768, -1,
+ 197, 769, -1, 507, -1, 229, 769, -1,
+ 198, 769, -1, 509, -1, 230, 769, -1,
+ 216, 769, -1, 511, -1, 248, 769, -1,
+ 65, 783, -1, 513, -1, 97, 783, -1,
+ 65, 785, -1, 515, -1, 97, 785, -1,
+ 69, 783, -1, 517, -1, 101, 783, -1,
+ 69, 785, -1, 519, -1, 101, 785, -1,
+ 73, 783, -1, 521, -1, 105, 783, -1,
+ 73, 785, -1, 523, -1, 105, 785, -1,
+ 79, 783, -1, 525, -1, 111, 783, -1,
+ 79, 785, -1, 527, -1, 111, 785, -1,
+ 82, 783, -1, 529, -1, 114, 783, -1,
+ 82, 785, -1, 531, -1, 114, 785, -1,
+ 85, 783, -1, 533, -1, 117, 783, -1,
+ 85, 785, -1, 535, -1, 117, 785, -1,
+ 83, 806, -1, 537, -1, 115, 806, -1,
+ 84, 806, -1, 539, -1, 116, 806, -1,
+ 541, -1, 72, 780, -1, 543, -1, 104,
+ 780, -1, 414, -1, 547, -1, 549, -1,
+ 65, 775, -1, 551, -1, 97, 775, -1,
+ 69, 807, -1, 553, -1, 101, 807, -1,
+ 214, 772, -1, 555, -1, 246, 772, -1,
+ 213, 772, -1, 557, -1, 245, 772, -1,
+ 79, 775, -1, 559, -1, 111, 775, -1,
+ 558, 772, -1, 561, -1, 559, 772, -1,
+ 89, 772, -1, 563, -1, 121, 772, -1,
+ 11365, -1, 572, -1, 410, -1, 11366, -1,
+ 578, -1, 384, -1, 649, -1, 652, -1,
+ 583, -1, 585, -1, 587, -1, 589, -1,
+ 591, -1, 614, -1, 633, -1, 635, -1,
+ 641, -1, 32, 774, -1, 32, 775, -1,
+ 32, 778, -1, 32, 808, -1, 32, 771,
+ -1, 32, 779, -1, 661, -1, 768, -1,
+ 769, -1, 787, -1, 776, 769, -1, 953,
+ -1, 697, -1, 32, 837, -1, 59, -1,
+ 168, 769, -1, 913, 769, -1, 940, -1,
+ 183, -1, 917, 769, -1, 941, -1, 919,
+ 769, -1, 942, -1, 921, 769, -1, 943,
+ -1, 927, 769, -1, 972, -1, 933, 769,
+ -1, 973, -1, 937, 769, -1, 974, -1,
+ 970, 769, -1, 953, 776, 769, -1, 945,
+ -1, 946, -1, 947, -1, 948, -1, 949,
+ -1, 950, -1, 951, -1, 952, -1, 954,
+ -1, 955, -1, 957, -1, 958, -1, 959,
+ -1, 960, -1, 961, -1, 963, -1, 964,
+ -1, 965, -1, 966, -1, 967, -1, 968,
+ -1, 969, -1, 921, 776, -1, 970, -1,
+ 933, 776, -1, 971, -1, 945, 769, -1,
+ 949, 769, -1, 951, 769, -1, 953, 769,
+ -1, 971, 769, -1, 965, 776, 769, -1,
+ 953, 776, -1, 965, 776, -1, 959, 769,
+ -1, 965, 769, -1, 969, 769, -1, 933,
+ -1, 978, 769, -1, 978, 776, -1, 985,
+ -1, 987, -1, 989, -1, 991, -1, 993,
+ -1, 995, -1, 997, -1, 999, -1, 1001,
+ -1, 1003, -1, 1005, -1, 1007, -1, 962,
+ -1, 920, -1, 1016, -1, 931, -1, 1010,
+ -1, 1019, -1, 891, -1, 892, -1, 893,
+ -1, 1045, 768, -1, 1104, -1, 1045, 776,
+ -1, 1105, -1, 1106, -1, 1043, 769, -1,
+ 1107, -1, 1108, -1, 1109, -1, 1110, -1,
+ 1030, 776, -1, 1111, -1, 1112, -1, 1113,
+ -1, 1114, -1, 1115, -1, 1050, 769, -1,
+ 1116, -1, 1048, 768, -1, 1117, -1, 1059,
+ 774, -1, 1118, -1, 1119, -1, 1072, -1,
+ 1073, -1, 1074, -1, 1075, -1, 1076, -1,
+ 1077, -1, 1078, -1, 1079, -1, 1080, -1,
+ 1048, 774, -1, 1081, -1, 1082, -1, 1083,
+ -1, 1084, -1, 1085, -1, 1086, -1, 1087,
+ -1, 1088, -1, 1089, -1, 1090, -1, 1091,
+ -1, 1092, -1, 1093, -1, 1094, -1, 1095,
+ -1, 1096, -1, 1097, -1, 1098, -1, 1099,
+ -1, 1100, -1, 1101, -1, 1102, -1, 1103,
+ -1, 1080, 774, -1, 1077, 768, -1, 1077,
+ 776, -1, 1075, 769, -1, 1110, 776, -1,
+ 1082, 769, -1, 1080, 768, -1, 1091, 774,
+ -1, 1121, -1, 1123, -1, 1125, -1, 1127,
+ -1, 1129, -1, 1131, -1, 1133, -1, 1135,
+ -1, 1137, -1, 1139, -1, 1141, -1, 1140,
+ 783, -1, 1143, -1, 1141, 783, -1, 1145,
+ -1, 1147, -1, 1149, -1, 1151, -1, 1153,
+ -1, 1163, -1, 1165, -1, 1167, -1, 1169,
+ -1, 1171, -1, 1173, -1, 1175, -1, 1177,
+ -1, 1179, -1, 1181, -1, 1183, -1, 1185,
+ -1, 1187, -1, 1189, -1, 1191, -1, 1193,
+ -1, 1195, -1, 1197, -1, 1199, -1, 1201,
+ -1, 1203, -1, 1205, -1, 1207, -1, 1209,
+ -1, 1211, -1, 1213, -1, 1215, -1, 1231,
+ -1, 1046, 774, -1, 1218, -1, 1078, 774,
+ -1, 1220, -1, 1222, -1, 1224, -1, 1226,
+ -1, 1228, -1, 1230, -1, 1040, 774, -1,
+ 1233, -1, 1072, 774, -1, 1040, 776, -1,
+ 1235, -1, 1072, 776, -1, 1237, -1, 1045,
+ 774, -1, 1239, -1, 1077, 774, -1, 1241,
+ -1, 1240, 776, -1, 1243, -1, 1241, 776,
+ -1, 1046, 776, -1, 1245, -1, 1078, 776,
+ -1, 1047, 776, -1, 1247, -1, 1079, 776,
+ -1, 1249, -1, 1048, 772, -1, 1251, -1,
+ 1080, 772, -1, 1048, 776, -1, 1253, -1,
+ 1080, 776, -1, 1054, 776, -1, 1255, -1,
+ 1086, 776, -1, 1257, -1, 1256, 776, -1,
+ 1259, -1, 1257, 776, -1, 1069, 776, -1,
+ 1261, -1, 1101, 776, -1, 1059, 772, -1,
+ 1263, -1, 1091, 772, -1, 1059, 776, -1,
+ 1265, -1, 1091, 776, -1, 1059, 779, -1,
+ 1267, -1, 1091, 779, -1, 1063, 776, -1,
+ 1269, -1, 1095, 776, -1, 1271, -1, 1067,
+ 776, -1, 1273, -1, 1099, 776, -1, 1275,
+ -1, 1277, -1, 1279, -1, 1281, -1, 1283,
+ -1, 1285, -1, 1287, -1, 1289, -1, 1291,
+ -1, 1293, -1, 1295, -1, 1297, -1, 1299,
+ -1, 1377, -1, 1378, -1, 1379, -1, 1380,
+ -1, 1381, -1, 1382, -1, 1383, -1, 1384,
+ -1, 1385, -1, 1386, -1, 1387, -1, 1388,
+ -1, 1389, -1, 1390, -1, 1391, -1, 1392,
+ -1, 1393, -1, 1394, -1, 1395, -1, 1396,
+ -1, 1397, -1, 1398, -1, 1399, -1, 1400,
+ -1, 1401, -1, 1402, -1, 1403, -1, 1404,
+ -1, 1405, -1, 1406, -1, 1407, -1, 1408,
+ -1, 1409, -1, 1410, -1, 1411, -1, 1412,
+ -1, 1413, -1, 1414, -1, 1381, 1410, -1,
+ 1575, 1619, -1, 1575, 1620, -1, 1608, 1620,
+ -1, 1575, 1621, -1, 1610, 1620, -1, 1575,
+ 1652, -1, 1608, 1652, -1, 1735, 1652, -1,
+ 1610, 1652, -1, 1749, 1620, -1, 1729, 1620,
+ -1, 1746, 1620, -1, 2344, 2364, -1, 2352,
+ 2364, -1, 2355, 2364, -1, 2325, 2364, -1,
+ 2326, 2364, -1, 2327, 2364, -1, 2332, 2364,
+ -1, 2337, 2364, -1, 2338, 2364, -1, 2347,
+ 2364, -1, 2351, 2364, -1, 2503, 2494, -1,
+ 2503, 2519, -1, 2465, 2492, -1, 2466, 2492,
+ -1, 2479, 2492, -1, 2610, 2620, -1, 2616,
+ 2620, -1, 2582, 2620, -1, 2583, 2620, -1,
+ 2588, 2620, -1, 2603, 2620, -1, 2887, 2902,
+ -1, 2887, 2878, -1, 2887, 2903, -1, 2849,
+ 2876, -1, 2850, 2876, -1, 2962, 3031, -1,
+ 3014, 3006, -1, 3015, 3006, -1, 3014, 3031,
+ -1, 3142, 3158, -1, 3263, 3285, -1, 3270,
+ 3285, -1, 3270, 3286, -1, 3270, 3266, -1,
+ 3274, 3285, -1, 3398, 3390, -1, 3399, 3390,
+ -1, 3398, 3415, -1, 3545, 3530, -1, 3545,
+ 3535, -1, 3548, 3530, -1, 3545, 3551, -1,
+ 3661, 3634, -1, 3789, 3762, -1, 3755, 3737,
+ -1, 3755, 3745, -1, 3851, -1, 3906, 4023,
+ -1, 3916, 4023, -1, 3921, 4023, -1, 3926,
+ 4023, -1, 3931, 4023, -1, 3904, 4021, -1,
+ 3953, 3954, -1, 3953, 3956, -1, 4018, 3968,
+ -1, 4018, 3969, -1, 4019, 3968, -1, 4019,
+ 3969, -1, 3953, 3968, -1, 3986, 4023, -1,
+ 3996, 4023, -1, 4001, 4023, -1, 4006, 4023,
+ -1, 4011, 4023, -1, 3984, 4021, -1, 4133,
+ 4142, -1, 11520, -1, 11521, -1, 11522, -1,
+ 11523, -1, 11524, -1, 11525, -1, 11526, -1,
+ 11527, -1, 11528, -1, 11529, -1, 11530, -1,
+ 11531, -1, 11532, -1, 11533, -1, 11534, -1,
+ 11535, -1, 11536, -1, 11537, -1, 11538, -1,
+ 11539, -1, 11540, -1, 11541, -1, 11542, -1,
+ 11543, -1, 11544, -1, 11545, -1, 11546, -1,
+ 11547, -1, 11548, -1, 11549, -1, 11550, -1,
+ 11551, -1, 11552, -1, 11553, -1, 11554, -1,
+ 11555, -1, 11556, -1, 11557, -1, 4316, -1,
+ 6917, 6965, -1, 6919, 6965, -1, 6921, 6965,
+ -1, 6923, 6965, -1, 6925, 6965, -1, 6929,
+ 6965, -1, 6970, 6965, -1, 6972, 6965, -1,
+ 6974, 6965, -1, 6975, 6965, -1, 6978, 6965,
+ -1, 65, -1, 198, -1, 66, -1, 68,
+ -1, 69, -1, 398, -1, 71, -1, 72,
+ -1, 73, -1, 74, -1, 75, -1, 76,
+ -1, 77, -1, 78, -1, 79, -1, 546,
+ -1, 80, -1, 82, -1, 84, -1, 85,
+ -1, 87, -1, 592, -1, 593, -1, 7426,
+ -1, 604, -1, 7446, -1, 7447, -1, 7453,
+ -1, 7461, -1, 594, -1, 597, -1, 607,
+ -1, 609, -1, 613, -1, 618, -1, 7547,
+ -1, 669, -1, 621, -1, 7557, -1, 671,
+ -1, 625, -1, 624, -1, 627, -1, 628,
+ -1, 632, -1, 642, -1, 427, -1, 7452,
+ -1, 656, -1, 657, -1, 65, 805, -1,
+ 7681, -1, 97, 805, -1, 66, 775, -1,
+ 7683, -1, 98, 775, -1, 66, 803, -1,
+ 7685, -1, 98, 803, -1, 66, 817, -1,
+ 7687, -1, 98, 817, -1, 199, 769, -1,
+ 7689, -1, 231, 769, -1, 68, 775, -1,
+ 7691, -1, 100, 775, -1, 68, 803, -1,
+ 7693, -1, 100, 803, -1, 68, 817, -1,
+ 7695, -1, 100, 817, -1, 68, 807, -1,
+ 7697, -1, 100, 807, -1, 68, 813, -1,
+ 7699, -1, 100, 813, -1, 274, 768, -1,
+ 7701, -1, 275, 768, -1, 274, 769, -1,
+ 7703, -1, 275, 769, -1, 69, 813, -1,
+ 7705, -1, 101, 813, -1, 69, 816, -1,
+ 7707, -1, 101, 816, -1, 552, 774, -1,
+ 7709, -1, 553, 774, -1, 70, 775, -1,
+ 7711, -1, 102, 775, -1, 71, 772, -1,
+ 7713, -1, 103, 772, -1, 72, 775, -1,
+ 7715, -1, 104, 775, -1, 72, 803, -1,
+ 7717, -1, 104, 803, -1, 72, 776, -1,
+ 7719, -1, 104, 776, -1, 72, 807, -1,
+ 7721, -1, 104, 807, -1, 72, 814, -1,
+ 7723, -1, 104, 814, -1, 73, 816, -1,
+ 7725, -1, 105, 816, -1, 207, 769, -1,
+ 7727, -1, 239, 769, -1, 75, 769, -1,
+ 7729, -1, 107, 769, -1, 75, 803, -1,
+ 7731, -1, 107, 803, -1, 75, 817, -1,
+ 7733, -1, 107, 817, -1, 76, 803, -1,
+ 7735, -1, 108, 803, -1, 7734, 772, -1,
+ 7737, -1, 7735, 772, -1, 76, 817, -1,
+ 7739, -1, 108, 817, -1, 76, 813, -1,
+ 7741, -1, 108, 813, -1, 77, 769, -1,
+ 7743, -1, 109, 769, -1, 77, 775, -1,
+ 7745, -1, 109, 775, -1, 77, 803, -1,
+ 7747, -1, 109, 803, -1, 78, 775, -1,
+ 7749, -1, 110, 775, -1, 78, 803, -1,
+ 7751, -1, 110, 803, -1, 78, 817, -1,
+ 7753, -1, 110, 817, -1, 78, 813, -1,
+ 7755, -1, 110, 813, -1, 213, 769, -1,
+ 7757, -1, 245, 769, -1, 213, 776, -1,
+ 7759, -1, 245, 776, -1, 332, 768, -1,
+ 7761, -1, 333, 768, -1, 332, 769, -1,
+ 7763, -1, 333, 769, -1, 80, 769, -1,
+ 7765, -1, 112, 769, -1, 80, 775, -1,
+ 7767, -1, 112, 775, -1, 82, 775, -1,
+ 7769, -1, 114, 775, -1, 82, 803, -1,
+ 7771, -1, 114, 803, -1, 7770, 772, -1,
+ 7773, -1, 7771, 772, -1, 82, 817, -1,
+ 7775, -1, 114, 817, -1, 83, 775, -1,
+ 7777, -1, 115, 775, -1, 83, 803, -1,
+ 7779, -1, 115, 803, -1, 346, 775, -1,
+ 7781, -1, 347, 775, -1, 352, 775, -1,
+ 7783, -1, 353, 775, -1, 7778, 775, -1,
+ 7785, -1, 7779, 775, -1, 84, 775, -1,
+ 7787, -1, 116, 775, -1, 84, 803, -1,
+ 7789, -1, 116, 803, -1, 84, 817, -1,
+ 7791, -1, 116, 817, -1, 84, 813, -1,
+ 7793, -1, 116, 813, -1, 85, 804, -1,
+ 7795, -1, 117, 804, -1, 85, 816, -1,
+ 7797, -1, 117, 816, -1, 85, 813, -1,
+ 7799, -1, 117, 813, -1, 360, 769, -1,
+ 7801, -1, 361, 769, -1, 362, 776, -1,
+ 7803, -1, 363, 776, -1, 86, 771, -1,
+ 7805, -1, 118, 771, -1, 86, 803, -1,
+ 7807, -1, 118, 803, -1, 87, 768, -1,
+ 7809, -1, 119, 768, -1, 87, 769, -1,
+ 7811, -1, 119, 769, -1, 87, 776, -1,
+ 7813, -1, 119, 776, -1, 87, 775, -1,
+ 7815, -1, 119, 775, -1, 87, 803, -1,
+ 7817, -1, 119, 803, -1, 88, 775, -1,
+ 7819, -1, 120, 775, -1, 88, 776, -1,
+ 7821, -1, 120, 776, -1, 89, 775, -1,
+ 7823, -1, 121, 775, -1, 90, 770, -1,
+ 7825, -1, 122, 770, -1, 90, 803, -1,
+ 7827, -1, 122, 803, -1, 90, 817, -1,
+ 7829, -1, 122, 817, -1, 104, 817, -1,
+ 116, 776, -1, 119, 778, -1, 121, 778,
+ -1, 97, 702, -1, 383, 775, -1, 65,
+ 803, -1, 7841, -1, 97, 803, -1, 65,
+ 777, -1, 7843, -1, 97, 777, -1, 194,
+ 769, -1, 7845, -1, 226, 769, -1, 194,
+ 768, -1, 7847, -1, 226, 768, -1, 194,
+ 777, -1, 7849, -1, 226, 777, -1, 194,
+ 771, -1, 7851, -1, 226, 771, -1, 7840,
+ 770, -1, 7853, -1, 7841, 770, -1, 258,
+ 769, -1, 7855, -1, 259, 769, -1, 258,
+ 768, -1, 7857, -1, 259, 768, -1, 258,
+ 777, -1, 7859, -1, 259, 777, -1, 258,
+ 771, -1, 7861, -1, 259, 771, -1, 7840,
+ 774, -1, 7863, -1, 7841, 774, -1, 69,
+ 803, -1, 7865, -1, 101, 803, -1, 69,
+ 777, -1, 7867, -1, 101, 777, -1, 69,
+ 771, -1, 7869, -1, 101, 771, -1, 202,
+ 769, -1, 7871, -1, 234, 769, -1, 202,
+ 768, -1, 7873, -1, 234, 768, -1, 202,
+ 777, -1, 7875, -1, 234, 777, -1, 202,
+ 771, -1, 7877, -1, 234, 771, -1, 7864,
+ 770, -1, 7879, -1, 7865, 770, -1, 73,
+ 777, -1, 7881, -1, 105, 777, -1, 73,
+ 803, -1, 7883, -1, 105, 803, -1, 79,
+ 803, -1, 7885, -1, 111, 803, -1, 79,
+ 777, -1, 7887, -1, 111, 777, -1, 212,
+ 769, -1, 7889, -1, 244, 769, -1, 212,
+ 768, -1, 7891, -1, 244, 768, -1, 212,
+ 777, -1, 7893, -1, 244, 777, -1, 212,
+ 771, -1, 7895, -1, 244, 771, -1, 7884,
+ 770, -1, 7897, -1, 7885, 770, -1, 416,
+ 769, -1, 7899, -1, 417, 769, -1, 416,
+ 768, -1, 7901, -1, 417, 768, -1, 416,
+ 777, -1, 7903, -1, 417, 777, -1, 416,
+ 771, -1, 7905, -1, 417, 771, -1, 416,
+ 803, -1, 7907, -1, 417, 803, -1, 85,
+ 803, -1, 7909, -1, 117, 803, -1, 85,
+ 777, -1, 7911, -1, 117, 777, -1, 431,
+ 769, -1, 7913, -1, 432, 769, -1, 431,
+ 768, -1, 7915, -1, 432, 768, -1, 431,
+ 777, -1, 7917, -1, 432, 777, -1, 431,
+ 771, -1, 7919, -1, 432, 771, -1, 431,
+ 803, -1, 7921, -1, 432, 803, -1, 89,
+ 768, -1, 7923, -1, 121, 768, -1, 89,
+ 803, -1, 7925, -1, 121, 803, -1, 89,
+ 777, -1, 7927, -1, 121, 777, -1, 89,
+ 771, -1, 7929, -1, 121, 771, -1, 945,
+ 787, -1, 945, 788, -1, 7936, 768, -1,
+ 7937, 768, -1, 7936, 769, -1, 7937, 769,
+ -1, 7936, 834, -1, 7937, 834, -1, 913,
+ 787, -1, 7936, -1, 913, 788, -1, 7937,
+ -1, 7944, 768, -1, 7938, -1, 7945, 768,
+ -1, 7939, -1, 7944, 769, -1, 7940, -1,
+ 7945, 769, -1, 7941, -1, 7944, 834, -1,
+ 7942, -1, 7945, 834, -1, 7943, -1, 949,
+ 787, -1, 949, 788, -1, 7952, 768, -1,
+ 7953, 768, -1, 7952, 769, -1, 7953, 769,
+ -1, 917, 787, -1, 7952, -1, 917, 788,
+ -1, 7953, -1, 7960, 768, -1, 7954, -1,
+ 7961, 768, -1, 7955, -1, 7960, 769, -1,
+ 7956, -1, 7961, 769, -1, 7957, -1, 951,
+ 787, -1, 951, 788, -1, 7968, 768, -1,
+ 7969, 768, -1, 7968, 769, -1, 7969, 769,
+ -1, 7968, 834, -1, 7969, 834, -1, 919,
+ 787, -1, 7968, -1, 919, 788, -1, 7969,
+ -1, 7976, 768, -1, 7970, -1, 7977, 768,
+ -1, 7971, -1, 7976, 769, -1, 7972, -1,
+ 7977, 769, -1, 7973, -1, 7976, 834, -1,
+ 7974, -1, 7977, 834, -1, 7975, -1, 953,
+ 787, -1, 953, 788, -1, 7984, 768, -1,
+ 7985, 768, -1, 7984, 769, -1, 7985, 769,
+ -1, 7984, 834, -1, 7985, 834, -1, 921,
+ 787, -1, 7984, -1, 921, 788, -1, 7985,
+ -1, 7992, 768, -1, 7986, -1, 7993, 768,
+ -1, 7987, -1, 7992, 769, -1, 7988, -1,
+ 7993, 769, -1, 7989, -1, 7992, 834, -1,
+ 7990, -1, 7993, 834, -1, 7991, -1, 959,
+ 787, -1, 959, 788, -1, 8000, 768, -1,
+ 8001, 768, -1, 8000, 769, -1, 8001, 769,
+ -1, 927, 787, -1, 8000, -1, 927, 788,
+ -1, 8001, -1, 8008, 768, -1, 8002, -1,
+ 8009, 768, -1, 8003, -1, 8008, 769, -1,
+ 8004, -1, 8009, 769, -1, 8005, -1, 965,
+ 787, -1, 965, 788, -1, 8016, 768, -1,
+ 965, 787, 768, -1, 8017, 768, -1, 8016,
+ 769, -1, 965, 787, 769, -1, 8017, 769,
+ -1, 8016, 834, -1, 965, 787, 834, -1,
+ 8017, 834, -1, 933, 788, -1, 8017, -1,
+ 8025, 768, -1, 8019, -1, 8025, 769, -1,
+ 8021, -1, 8025, 834, -1, 8023, -1, 969,
+ 787, -1, 969, 788, -1, 8032, 768, -1,
+ 8033, 768, -1, 8032, 769, -1, 8033, 769,
+ -1, 8032, 834, -1, 8033, 834, -1, 937,
+ 787, -1, 8032, -1, 937, 788, -1, 8033,
+ -1, 8040, 768, -1, 8034, -1, 8041, 768,
+ -1, 8035, -1, 8040, 769, -1, 8036, -1,
+ 8041, 769, -1, 8037, -1, 8040, 834, -1,
+ 8038, -1, 8041, 834, -1, 8039, -1, 945,
+ 768, -1, 949, 768, -1, 951, 768, -1,
+ 953, 768, -1, 959, 768, -1, 965, 768,
+ -1, 969, 768, -1, 7936, 837, -1, 7936,
+ 953, -1, 7937, 837, -1, 7937, 953, -1,
+ 7938, 837, -1, 7938, 953, -1, 7939, 837,
+ -1, 7939, 953, -1, 7940, 837, -1, 7940,
+ 953, -1, 7941, 837, -1, 7941, 953, -1,
+ 7942, 837, -1, 7942, 953, -1, 7943, 837,
+ -1, 7943, 953, -1, 7944, 837, -1, 8064,
+ -1, 7945, 837, -1, 8065, -1, 7946, 837,
+ -1, 8066, -1, 7947, 837, -1, 8067, -1,
+ 7948, 837, -1, 8068, -1, 7949, 837, -1,
+ 8069, -1, 7950, 837, -1, 8070, -1, 7951,
+ 837, -1, 8071, -1, 7968, 837, -1, 7968,
+ 953, -1, 7969, 837, -1, 7969, 953, -1,
+ 7970, 837, -1, 7970, 953, -1, 7971, 837,
+ -1, 7971, 953, -1, 7972, 837, -1, 7972,
+ 953, -1, 7973, 837, -1, 7973, 953, -1,
+ 7974, 837, -1, 7974, 953, -1, 7975, 837,
+ -1, 7975, 953, -1, 7976, 837, -1, 8080,
+ -1, 7977, 837, -1, 8081, -1, 7978, 837,
+ -1, 8082, -1, 7979, 837, -1, 8083, -1,
+ 7980, 837, -1, 8084, -1, 7981, 837, -1,
+ 8085, -1, 7982, 837, -1, 8086, -1, 7983,
+ 837, -1, 8087, -1, 8032, 837, -1, 8032,
+ 953, -1, 8033, 837, -1, 8033, 953, -1,
+ 8034, 837, -1, 8034, 953, -1, 8035, 837,
+ -1, 8035, 953, -1, 8036, 837, -1, 8036,
+ 953, -1, 8037, 837, -1, 8037, 953, -1,
+ 8038, 837, -1, 8038, 953, -1, 8039, 837,
+ -1, 8039, 953, -1, 8040, 837, -1, 8096,
+ -1, 8041, 837, -1, 8097, -1, 8042, 837,
+ -1, 8098, -1, 8043, 837, -1, 8099, -1,
+ 8044, 837, -1, 8100, -1, 8045, 837, -1,
+ 8101, -1, 8046, 837, -1, 8102, -1, 8047,
+ 837, -1, 8103, -1, 945, 774, -1, 945,
+ 772, -1, 8048, 837, -1, 8048, 953, -1,
+ 945, 837, -1, 945, 953, -1, 940, 837,
+ -1, 940, 953, -1, 945, 834, -1, 8118,
+ 837, -1, 945, 834, 953, -1, 913, 774,
+ -1, 8112, -1, 913, 772, -1, 8113, -1,
+ 913, 768, -1, 8048, -1, 902, -1, 8049,
+ -1, 913, 837, -1, 8115, -1, 32, 787,
+ -1, 32, 834, -1, 168, 834, -1, 8052,
+ 837, -1, 8052, 953, -1, 951, 837, -1,
+ 951, 953, -1, 942, 837, -1, 942, 953,
+ -1, 951, 834, -1, 8134, 837, -1, 951,
+ 834, 953, -1, 917, 768, -1, 8050, -1,
+ 904, -1, 8051, -1, 919, 768, -1, 8052,
+ -1, 905, -1, 8053, -1, 919, 837, -1,
+ 8131, -1, 8127, 768, -1, 8127, 769, -1,
+ 8127, 834, -1, 953, 774, -1, 953, 772,
+ -1, 970, 768, -1, 953, 776, 768, -1,
+ 912, -1, 953, 834, -1, 970, 834, -1,
+ 953, 776, 834, -1, 921, 774, -1, 8144,
+ -1, 921, 772, -1, 8145, -1, 921, 768,
+ -1, 8054, -1, 906, -1, 8055, -1, 8190,
+ 768, -1, 8190, 769, -1, 8190, 834, -1,
+ 965, 774, -1, 965, 772, -1, 971, 768,
+ -1, 965, 776, 768, -1, 944, -1, 961,
+ 787, -1, 961, 788, -1, 965, 834, -1,
+ 971, 834, -1, 965, 776, 834, -1, 933,
+ 774, -1, 8160, -1, 933, 772, -1, 8161,
+ -1, 933, 768, -1, 8058, -1, 910, -1,
+ 8059, -1, 929, 788, -1, 8165, -1, 168,
+ 768, -1, 901, -1, 96, -1, 8060, 837,
+ -1, 8060, 953, -1, 969, 837, -1, 969,
+ 953, -1, 974, 837, -1, 974, 953, -1,
+ 969, 834, -1, 8182, 837, -1, 969, 834,
+ 953, -1, 927, 768, -1, 8056, -1, 908,
+ -1, 8057, -1, 937, 768, -1, 8060, -1,
+ 911, -1, 8061, -1, 937, 837, -1, 8179,
+ -1, 180, -1, 32, 788, -1, 8194, -1,
+ 8195, -1, 8208, -1, 32, 819, -1, 46,
+ -1, 46, 46, -1, 46, 46, 46, -1,
+ 8242, 8242, -1, 8242, 8242, 8242, -1, 8245,
+ 8245, -1, 8245, 8245, 8245, -1, 33, 33,
+ -1, 32, 773, -1, 63, 63, -1, 63,
+ 33, -1, 33, 63, -1, 8242, 8242, 8242,
+ 8242, -1, 48, -1, 52, -1, 53, -1,
+ 54, -1, 55, -1, 56, -1, 57, -1,
+ 43, -1, 8722, -1, 61, -1, 40, -1,
+ 41, -1, 82, 115, -1, 97, 47, 99,
+ -1, 97, 47, 115, -1, 67, -1, 176,
+ 67, -1, 99, 47, 111, -1, 99, 47,
+ 117, -1, 400, -1, 176, 70, -1, 78,
+ 111, -1, 81, -1, 83, 77, -1, 84,
+ 69, 76, -1, 84, 77, -1, 90, -1,
+ 937, -1, 197, -1, 70, -1, 8526, -1,
+ 1488, -1, 1489, -1, 1490, -1, 1491, -1,
+ 70, 65, 88, -1, 915, -1, 928, -1,
+ 8721, -1, 49, 8260, 51, -1, 50, 8260,
+ 51, -1, 49, 8260, 53, -1, 50, 8260,
+ 53, -1, 51, 8260, 53, -1, 52, 8260,
+ 53, -1, 49, 8260, 54, -1, 53, 8260,
+ 54, -1, 49, 8260, 56, -1, 51, 8260,
+ 56, -1, 53, 8260, 56, -1, 55, 8260,
+ 56, -1, 49, 8260, -1, 8560, -1, 73,
+ 73, -1, 8561, -1, 73, 73, 73, -1,
+ 8562, -1, 73, 86, -1, 8563, -1, 86,
+ -1, 8564, -1, 86, 73, -1, 8565, -1,
+ 86, 73, 73, -1, 8566, -1, 86, 73,
+ 73, 73, -1, 8567, -1, 73, 88, -1,
+ 8568, -1, 88, -1, 8569, -1, 88, 73,
+ -1, 8570, -1, 88, 73, 73, -1, 8571,
+ -1, 8572, -1, 8573, -1, 8574, -1, 8575,
+ -1, 105, 105, -1, 105, 105, 105, -1,
+ 105, 118, -1, 118, 105, -1, 118, 105,
+ 105, -1, 118, 105, 105, 105, -1, 105,
+ 120, -1, 120, 105, -1, 120, 105, 105,
+ -1, 8580, -1, 8592, 824, -1, 8594, 824,
+ -1, 8596, 824, -1, 8656, 824, -1, 8660,
+ 824, -1, 8658, 824, -1, 8707, 824, -1,
+ 8712, 824, -1, 8715, 824, -1, 8739, 824,
+ -1, 8741, 824, -1, 8747, 8747, -1, 8747,
+ 8747, 8747, -1, 8750, 8750, -1, 8750, 8750,
+ 8750, -1, 8764, 824, -1, 8771, 824, -1,
+ 8773, 824, -1, 8776, 824, -1, 61, 824,
+ -1, 8801, 824, -1, 8781, 824, -1, 60,
+ 824, -1, 62, 824, -1, 8804, 824, -1,
+ 8805, 824, -1, 8818, 824, -1, 8819, 824,
+ -1, 8822, 824, -1, 8823, 824, -1, 8826,
+ 824, -1, 8827, 824, -1, 8834, 824, -1,
+ 8835, 824, -1, 8838, 824, -1, 8839, 824,
+ -1, 8866, 824, -1, 8872, 824, -1, 8873,
+ 824, -1, 8875, 824, -1, 8828, 824, -1,
+ 8829, 824, -1, 8849, 824, -1, 8850, 824,
+ -1, 8882, 824, -1, 8883, 824, -1, 8884,
+ 824, -1, 8885, 824, -1, 12296, -1, 12297,
+ -1, 49, 48, -1, 49, 49, -1, 49,
+ 50, -1, 49, 51, -1, 49, 52, -1,
+ 49, 53, -1, 49, 54, -1, 49, 55,
+ -1, 49, 56, -1, 49, 57, -1, 50,
+ 48, -1, 40, 49, 41, -1, 40, 50,
+ 41, -1, 40, 51, 41, -1, 40, 52,
+ 41, -1, 40, 53, 41, -1, 40, 54,
+ 41, -1, 40, 55, 41, -1, 40, 56,
+ 41, -1, 40, 57, 41, -1, 40, 49,
+ 48, 41, -1, 40, 49, 49, 41, -1,
+ 40, 49, 50, 41, -1, 40, 49, 51,
+ 41, -1, 40, 49, 52, 41, -1, 40,
+ 49, 53, 41, -1, 40, 49, 54, 41,
+ -1, 40, 49, 55, 41, -1, 40, 49,
+ 56, 41, -1, 40, 49, 57, 41, -1,
+ 40, 50, 48, 41, -1, 49, 46, -1,
+ 50, 46, -1, 51, 46, -1, 52, 46,
+ -1, 53, 46, -1, 54, 46, -1, 55,
+ 46, -1, 56, 46, -1, 57, 46, -1,
+ 49, 48, 46, -1, 49, 49, 46, -1,
+ 49, 50, 46, -1, 49, 51, 46, -1,
+ 49, 52, 46, -1, 49, 53, 46, -1,
+ 49, 54, 46, -1, 49, 55, 46, -1,
+ 49, 56, 46, -1, 49, 57, 46, -1,
+ 50, 48, 46, -1, 40, 97, 41, -1,
+ 40, 98, 41, -1, 40, 99, 41, -1,
+ 40, 100, 41, -1, 40, 101, 41, -1,
+ 40, 102, 41, -1, 40, 103, 41, -1,
+ 40, 104, 41, -1, 40, 105, 41, -1,
+ 40, 106, 41, -1, 40, 107, 41, -1,
+ 40, 108, 41, -1, 40, 109, 41, -1,
+ 40, 110, 41, -1, 40, 111, 41, -1,
+ 40, 112, 41, -1, 40, 113, 41, -1,
+ 40, 114, 41, -1, 40, 115, 41, -1,
+ 40, 116, 41, -1, 40, 117, 41, -1,
+ 40, 118, 41, -1, 40, 119, 41, -1,
+ 40, 120, 41, -1, 40, 121, 41, -1,
+ 40, 122, 41, -1, 9424, -1, 9425, -1,
+ 9426, -1, 9427, -1, 9428, -1, 9429, -1,
+ 9430, -1, 9431, -1, 9432, -1, 9433, -1,
+ 9434, -1, 9435, -1, 9436, -1, 9437, -1,
+ 9438, -1, 9439, -1, 9440, -1, 9441, -1,
+ 83, -1, 9442, -1, 9443, -1, 9444, -1,
+ 9445, -1, 9446, -1, 9447, -1, 89, -1,
+ 9448, -1, 9449, -1, 8747, 8747, 8747, 8747,
+ -1, 58, 58, 61, -1, 61, 61, -1,
+ 61, 61, 61, -1, 10973, 824, -1, 11312,
+ -1, 11313, -1, 11314, -1, 11315, -1, 11316,
+ -1, 11317, -1, 11318, -1, 11319, -1, 11320,
+ -1, 11321, -1, 11322, -1, 11323, -1, 11324,
+ -1, 11325, -1, 11326, -1, 11327, -1, 11328,
+ -1, 11329, -1, 11330, -1, 11331, -1, 11332,
+ -1, 11333, -1, 11334, -1, 11335, -1, 11336,
+ -1, 11337, -1, 11338, -1, 11339, -1, 11340,
+ -1, 11341, -1, 11342, -1, 11343, -1, 11344,
+ -1, 11345, -1, 11346, -1, 11347, -1, 11348,
+ -1, 11349, -1, 11350, -1, 11351, -1, 11352,
+ -1, 11353, -1, 11354, -1, 11355, -1, 11356,
+ -1, 11357, -1, 11358, -1, 11361, -1, 619,
+ -1, 7549, -1, 637, -1, 11368, -1, 11370,
+ -1, 11372, -1, 11382, -1, 11393, -1, 11395,
+ -1, 11397, -1, 11399, -1, 11401, -1, 11403,
+ -1, 11405, -1, 11407, -1, 11409, -1, 11411,
+ -1, 11413, -1, 11415, -1, 11417, -1, 11419,
+ -1, 11421, -1, 11423, -1, 11425, -1, 11427,
+ -1, 11429, -1, 11431, -1, 11433, -1, 11435,
+ -1, 11437, -1, 11439, -1, 11441, -1, 11443,
+ -1, 11445, -1, 11447, -1, 11449, -1, 11451,
+ -1, 11453, -1, 11455, -1, 11457, -1, 11459,
+ -1, 11461, -1, 11463, -1, 11465, -1, 11467,
+ -1, 11469, -1, 11471, -1, 11473, -1, 11475,
+ -1, 11477, -1, 11479, -1, 11481, -1, 11483,
+ -1, 11485, -1, 11487, -1, 11489, -1, 11491,
+ -1, 11617, -1, 27597, -1, 40863, -1, 19968,
+ -1, 20008, -1, 20022, -1, 20031, -1, 20057,
+ -1, 20101, -1, 20108, -1, 20128, -1, 20154,
+ -1, 20799, -1, 20837, -1, 20843, -1, 20866,
+ -1, 20886, -1, 20907, -1, 20960, -1, 20981,
+ -1, 20992, -1, 21147, -1, 21241, -1, 21269,
+ -1, 21274, -1, 21304, -1, 21313, -1, 21340,
+ -1, 21353, -1, 21378, -1, 21430, -1, 21448,
+ -1, 21475, -1, 22231, -1, 22303, -1, 22763,
+ -1, 22786, -1, 22794, -1, 22805, -1, 22823,
+ -1, 22899, -1, 23376, -1, 23424, -1, 23544,
+ -1, 23567, -1, 23586, -1, 23608, -1, 23662,
+ -1, 23665, -1, 24027, -1, 24037, -1, 24049,
+ -1, 24062, -1, 24178, -1, 24186, -1, 24191,
+ -1, 24308, -1, 24318, -1, 24331, -1, 24339,
+ -1, 24400, -1, 24417, -1, 24435, -1, 24515,
+ -1, 25096, -1, 25142, -1, 25163, -1, 25903,
+ -1, 25908, -1, 25991, -1, 26007, -1, 26020,
+ -1, 26041, -1, 26080, -1, 26085, -1, 26352,
+ -1, 26376, -1, 26408, -1, 27424, -1, 27490,
+ -1, 27513, -1, 27571, -1, 27595, -1, 27604,
+ -1, 27611, -1, 27663, -1, 27668, -1, 27700,
+ -1, 28779, -1, 29226, -1, 29238, -1, 29243,
+ -1, 29247, -1, 29255, -1, 29273, -1, 29275,
+ -1, 29356, -1, 29572, -1, 29577, -1, 29916,
+ -1, 29926, -1, 29976, -1, 29983, -1, 29992,
+ -1, 30000, -1, 30091, -1, 30098, -1, 30326,
+ -1, 30333, -1, 30382, -1, 30399, -1, 30446,
+ -1, 30683, -1, 30690, -1, 30707, -1, 31034,
+ -1, 31160, -1, 31166, -1, 31348, -1, 31435,
+ -1, 31481, -1, 31859, -1, 31992, -1, 32566,
+ -1, 32593, -1, 32650, -1, 32701, -1, 32769,
+ -1, 32780, -1, 32786, -1, 32819, -1, 32895,
+ -1, 32905, -1, 33251, -1, 33258, -1, 33267,
+ -1, 33276, -1, 33292, -1, 33307, -1, 33311,
+ -1, 33390, -1, 33394, -1, 33400, -1, 34381,
+ -1, 34411, -1, 34880, -1, 34892, -1, 34915,
+ -1, 35198, -1, 35211, -1, 35282, -1, 35328,
+ -1, 35895, -1, 35910, -1, 35925, -1, 35960,
+ -1, 35997, -1, 36196, -1, 36208, -1, 36275,
+ -1, 36523, -1, 36554, -1, 36763, -1, 36784,
+ -1, 36789, -1, 37009, -1, 37193, -1, 37318,
+ -1, 37324, -1, 37329, -1, 38263, -1, 38272,
+ -1, 38428, -1, 38582, -1, 38585, -1, 38632,
+ -1, 38737, -1, 38750, -1, 38754, -1, 38761,
+ -1, 38859, -1, 38893, -1, 38899, -1, 38913,
+ -1, 39080, -1, 39131, -1, 39135, -1, 39318,
+ -1, 39321, -1, 39340, -1, 39592, -1, 39640,
+ -1, 39647, -1, 39717, -1, 39727, -1, 39730,
+ -1, 39740, -1, 39770, -1, 40165, -1, 40565,
+ -1, 40575, -1, 40613, -1, 40635, -1, 40643,
+ -1, 40653, -1, 40657, -1, 40697, -1, 40701,
+ -1, 40718, -1, 40723, -1, 40736, -1, 40763,
+ -1, 40778, -1, 40786, -1, 40845, -1, 40860,
+ -1, 40864, -1, 12306, -1, 21316, -1, 21317,
+ -1, 12363, 12441, -1, 12365, 12441, -1, 12367,
+ 12441, -1, 12369, 12441, -1, 12371, 12441, -1,
+ 12373, 12441, -1, 12375, 12441, -1, 12377, 12441,
+ -1, 12379, 12441, -1, 12381, 12441, -1, 12383,
+ 12441, -1, 12385, 12441, -1, 12388, 12441, -1,
+ 12390, 12441, -1, 12392, 12441, -1, 12399, 12441,
+ -1, 12399, 12442, -1, 12402, 12441, -1, 12402,
+ 12442, -1, 12405, 12441, -1, 12405, 12442, -1,
+ 12408, 12441, -1, 12408, 12442, -1, 12411, 12441,
+ -1, 12411, 12442, -1, 12358, 12441, -1, 32,
+ 12441, -1, 32, 12442, -1, 12445, 12441, -1,
+ 12424, 12426, -1, 12459, 12441, -1, 12461, 12441,
+ -1, 12463, 12441, -1, 12465, 12441, -1, 12467,
+ 12441, -1, 12469, 12441, -1, 12471, 12441, -1,
+ 12473, 12441, -1, 12475, 12441, -1, 12477, 12441,
+ -1, 12479, 12441, -1, 12481, 12441, -1, 12484,
+ 12441, -1, 12486, 12441, -1, 12488, 12441, -1,
+ 12495, 12441, -1, 12495, 12442, -1, 12498, 12441,
+ -1, 12498, 12442, -1, 12501, 12441, -1, 12501,
+ 12442, -1, 12504, 12441, -1, 12504, 12442, -1,
+ 12507, 12441, -1, 12507, 12442, -1, 12454, 12441,
+ -1, 12527, 12441, -1, 12528, 12441, -1, 12529,
+ 12441, -1, 12530, 12441, -1, 12541, 12441, -1,
+ 12467, 12488, -1, 4352, -1, 4353, -1, 4522,
+ -1, 4354, -1, 4524, -1, 4525, -1, 4355,
+ -1, 4356, -1, 4357, -1, 4528, -1, 4529,
+ -1, 4530, -1, 4531, -1, 4532, -1, 4533,
+ -1, 4378, -1, 4358, -1, 4359, -1, 4360,
+ -1, 4385, -1, 4361, -1, 4362, -1, 4363,
+ -1, 4364, -1, 4365, -1, 4366, -1, 4367,
+ -1, 4368, -1, 4369, -1, 4370, -1, 4449,
+ -1, 4450, -1, 4451, -1, 4452, -1, 4453,
+ -1, 4454, -1, 4455, -1, 4456, -1, 4457,
+ -1, 4458, -1, 4459, -1, 4460, -1, 4461,
+ -1, 4462, -1, 4463, -1, 4464, -1, 4465,
+ -1, 4466, -1, 4467, -1, 4468, -1, 4469,
+ -1, 4448, -1, 4372, -1, 4373, -1, 4551,
+ -1, 4552, -1, 4556, -1, 4558, -1, 4563,
+ -1, 4567, -1, 4569, -1, 4380, -1, 4573,
+ -1, 4575, -1, 4381, -1, 4382, -1, 4384,
+ -1, 4386, -1, 4387, -1, 4391, -1, 4393,
+ -1, 4395, -1, 4396, -1, 4397, -1, 4398,
+ -1, 4399, -1, 4402, -1, 4406, -1, 4416,
+ -1, 4423, -1, 4428, -1, 4593, -1, 4594,
+ -1, 4439, -1, 4440, -1, 4441, -1, 4484,
+ -1, 4485, -1, 4488, -1, 4497, -1, 4498,
+ -1, 4500, -1, 4510, -1, 4513, -1, 19977,
+ -1, 22235, -1, 19978, -1, 20013, -1, 19979,
+ -1, 30002, -1, 19993, -1, 19969, -1, 22825,
+ -1, 22320, -1, 40, 4352, 41, -1, 40,
+ 4354, 41, -1, 40, 4355, 41, -1, 40,
+ 4357, 41, -1, 40, 4358, 41, -1, 40,
+ 4359, 41, -1, 40, 4361, 41, -1, 40,
+ 4363, 41, -1, 40, 4364, 41, -1, 40,
+ 4366, 41, -1, 40, 4367, 41, -1, 40,
+ 4368, 41, -1, 40, 4369, 41, -1, 40,
+ 4370, 41, -1, 40, 4352, 4449, 41, -1,
+ 40, 4354, 4449, 41, -1, 40, 4355, 4449,
+ 41, -1, 40, 4357, 4449, 41, -1, 40,
+ 4358, 4449, 41, -1, 40, 4359, 4449, 41,
+ -1, 40, 4361, 4449, 41, -1, 40, 4363,
+ 4449, 41, -1, 40, 4364, 4449, 41, -1,
+ 40, 4366, 4449, 41, -1, 40, 4367, 4449,
+ 41, -1, 40, 4368, 4449, 41, -1, 40,
+ 4369, 4449, 41, -1, 40, 4370, 4449, 41,
+ -1, 40, 4364, 4462, 41, -1, 40, 4363,
+ 4457, 4364, 4453, 4523, 41, -1, 40, 4363,
+ 4457, 4370, 4462, 41, -1, 40, 19968, 41,
+ -1, 40, 20108, 41, -1, 40, 19977, 41,
+ -1, 40, 22235, 41, -1, 40, 20116, 41,
+ -1, 40, 20845, 41, -1, 40, 19971, 41,
+ -1, 40, 20843, 41, -1, 40, 20061, 41,
+ -1, 40, 21313, 41, -1, 40, 26376, 41,
+ -1, 40, 28779, 41, -1, 40, 27700, 41,
+ -1, 40, 26408, 41, -1, 40, 37329, 41,
+ -1, 40, 22303, 41, -1, 40, 26085, 41,
+ -1, 40, 26666, 41, -1, 40, 26377, 41,
+ -1, 40, 31038, 41, -1, 40, 21517, 41,
+ -1, 40, 29305, 41, -1, 40, 36001, 41,
+ -1, 40, 31069, 41, -1, 40, 21172, 41,
+ -1, 40, 20195, 41, -1, 40, 21628, 41,
+ -1, 40, 23398, 41, -1, 40, 30435, 41,
+ -1, 40, 20225, 41, -1, 40, 36039, 41,
+ -1, 40, 21332, 41, -1, 40, 31085, 41,
+ -1, 40, 20241, 41, -1, 40, 33258, 41,
+ -1, 40, 33267, 41, -1, 80, 84, 69,
+ -1, 50, 49, -1, 50, 50, -1, 50,
+ 51, -1, 50, 52, -1, 50, 53, -1,
+ 50, 54, -1, 50, 55, -1, 50, 56,
+ -1, 50, 57, -1, 51, 48, -1, 51,
+ 49, -1, 51, 50, -1, 51, 51, -1,
+ 51, 52, -1, 51, 53, -1, 4352, 4449,
+ -1, 4354, 4449, -1, 4355, 4449, -1, 4357,
+ 4449, -1, 4358, 4449, -1, 4359, 4449, -1,
+ 4361, 4449, -1, 4363, 4449, -1, 4364, 4449,
+ -1, 4366, 4449, -1, 4367, 4449, -1, 4368,
+ 4449, -1, 4369, 4449, -1, 4370, 4449, -1,
+ 4366, 4449, 4535, 4352, 4457, -1, 4364, 4462,
+ 4363, 4468, -1, 4363, 4462, -1, 20116, -1,
+ 20845, -1, 19971, -1, 20061, -1, 26666, -1,
+ 26377, -1, 31038, -1, 21517, -1, 29305, -1,
+ 36001, -1, 31069, -1, 21172, -1, 31192, -1,
+ 30007, -1, 36969, -1, 20778, -1, 21360, -1,
+ 27880, -1, 38917, -1, 20241, -1, 20889, -1,
+ 27491, -1, 24038, -1, 21491, -1, 21307, -1,
+ 23447, -1, 23398, -1, 30435, -1, 20225, -1,
+ 36039, -1, 21332, -1, 22812, -1, 51, 54,
+ -1, 51, 55, -1, 51, 56, -1, 51,
+ 57, -1, 52, 48, -1, 52, 49, -1,
+ 52, 50, -1, 52, 51, -1, 52, 52,
+ -1, 52, 53, -1, 52, 54, -1, 52,
+ 55, -1, 52, 56, -1, 52, 57, -1,
+ 53, 48, -1, 49, 26376, -1, 50, 26376,
+ -1, 51, 26376, -1, 52, 26376, -1, 53,
+ 26376, -1, 54, 26376, -1, 55, 26376, -1,
+ 56, 26376, -1, 57, 26376, -1, 49, 48,
+ 26376, -1, 49, 49, 26376, -1, 49, 50,
+ 26376, -1, 72, 103, -1, 101, 114, 103,
+ -1, 101, 86, -1, 76, 84, 68, -1,
+ 12450, -1, 12452, -1, 12454, -1, 12456, -1,
+ 12458, -1, 12459, -1, 12461, -1, 12463, -1,
+ 12465, -1, 12467, -1, 12469, -1, 12471, -1,
+ 12473, -1, 12475, -1, 12477, -1, 12479, -1,
+ 12481, -1, 12484, -1, 12486, -1, 12488, -1,
+ 12490, -1, 12491, -1, 12492, -1, 12493, -1,
+ 12494, -1, 12495, -1, 12498, -1, 12501, -1,
+ 12504, -1, 12507, -1, 12510, -1, 12511, -1,
+ 12512, -1, 12513, -1, 12514, -1, 12516, -1,
+ 12518, -1, 12520, -1, 12521, -1, 12522, -1,
+ 12523, -1, 12524, -1, 12525, -1, 12527, -1,
+ 12528, -1, 12529, -1, 12530, -1, 12450, 12497,
+ 12540, 12488, -1, 12450, 12523, 12501, 12449, -1,
+ 12450, 12531, 12506, 12450, -1, 12450, 12540, 12523,
+ -1, 12452, 12491, 12531, 12464, -1, 12452, 12531,
+ 12481, -1, 12454, 12457, 12531, -1, 12456, 12473,
+ 12463, 12540, 12489, -1, 12456, 12540, 12459, 12540,
+ -1, 12458, 12531, 12473, -1, 12458, 12540, 12512,
+ -1, 12459, 12452, 12522, -1, 12459, 12521, 12483,
+ 12488, -1, 12459, 12525, 12522, 12540, -1, 12460,
+ 12525, 12531, -1, 12460, 12531, 12510, -1, 12462,
+ 12460, -1, 12462, 12491, 12540, -1, 12461, 12517,
+ 12522, 12540, -1, 12462, 12523, 12480, 12540, -1,
+ 12461, 12525, -1, 12461, 12525, 12464, 12521, 12512,
+ -1, 12461, 12525, 12513, 12540, 12488, 12523, -1,
+ 12461, 12525, 12527, 12483, 12488, -1, 12464, 12521,
+ 12512, -1, 12464, 12521, 12512, 12488, 12531, -1,
+ 12463, 12523, 12476, 12452, 12525, -1, 12463, 12525,
+ 12540, 12493, -1, 12465, 12540, 12473, -1, 12467,
+ 12523, 12490, -1, 12467, 12540, 12509, -1, 12469,
+ 12452, 12463, 12523, -1, 12469, 12531, 12481, 12540,
+ 12512, -1, 12471, 12522, 12531, 12464, -1, 12475,
+ 12531, 12481, -1, 12475, 12531, 12488, -1, 12480,
+ 12540, 12473, -1, 12487, 12471, -1, 12489, 12523,
+ -1, 12488, 12531, -1, 12490, 12494, -1, 12494,
+ 12483, 12488, -1, 12495, 12452, 12484, -1, 12497,
+ 12540, 12475, 12531, 12488, -1, 12497, 12540, 12484,
+ -1, 12496, 12540, 12524, 12523, -1, 12500, 12450,
+ 12473, 12488, 12523, -1, 12500, 12463, 12523, -1,
+ 12500, 12467, -1, 12499, 12523, -1, 12501, 12449,
+ 12521, 12483, 12489, -1, 12501, 12451, 12540, 12488,
+ -1, 12502, 12483, 12471, 12455, 12523, -1, 12501,
+ 12521, 12531, -1, 12504, 12463, 12479, 12540, 12523,
+ -1, 12506, 12477, -1, 12506, 12491, 12498, -1,
+ 12504, 12523, 12484, -1, 12506, 12531, 12473, -1,
+ 12506, 12540, 12472, -1, 12505, 12540, 12479, -1,
+ 12509, 12452, 12531, 12488, -1, 12508, 12523, 12488,
+ -1, 12507, 12531, -1, 12509, 12531, 12489, -1,
+ 12507, 12540, 12523, -1, 12507, 12540, 12531, -1,
+ 12510, 12452, 12463, 12525, -1, 12510, 12452, 12523,
+ -1, 12510, 12483, 12495, -1, 12510, 12523, 12463,
+ -1, 12510, 12531, 12471, 12519, 12531, -1, 12511,
+ 12463, 12525, 12531, -1, 12511, 12522, -1, 12511,
+ 12522, 12496, 12540, 12523, -1, 12513, 12460, -1,
+ 12513, 12460, 12488, 12531, -1, 12513, 12540, 12488,
+ 12523, -1, 12516, 12540, 12489, -1, 12516, 12540,
+ 12523, -1, 12518, 12450, 12531, -1, 12522, 12483,
+ 12488, 12523, -1, 12522, 12521, -1, 12523, 12500,
+ 12540, -1, 12523, 12540, 12502, 12523, -1, 12524,
+ 12512, -1, 12524, 12531, 12488, 12466, 12531, -1,
+ 12527, 12483, 12488, -1, 48, 28857, -1, 49,
+ 28857, -1, 50, 28857, -1, 51, 28857, -1,
+ 52, 28857, -1, 53, 28857, -1, 54, 28857,
+ -1, 55, 28857, -1, 56, 28857, -1, 57,
+ 28857, -1, 49, 48, 28857, -1, 49, 49,
+ 28857, -1, 49, 50, 28857, -1, 49, 51,
+ 28857, -1, 49, 52, 28857, -1, 49, 53,
+ 28857, -1, 49, 54, 28857, -1, 49, 55,
+ 28857, -1, 49, 56, 28857, -1, 49, 57,
+ 28857, -1, 50, 48, 28857, -1, 50, 49,
+ 28857, -1, 50, 50, 28857, -1, 50, 51,
+ 28857, -1, 50, 52, 28857, -1, 104, 80,
+ 97, -1, 100, 97, -1, 65, 85, -1,
+ 98, 97, 114, -1, 111, 86, -1, 112,
+ 99, -1, 100, 109, -1, 100, 109, 178,
+ -1, 100, 109, 179, -1, 73, 85, -1,
+ 24179, 25104, -1, 26157, 21644, -1, 22823, 27491,
+ -1, 26126, 27835, -1, 26666, 24335, 20250, 31038,
+ -1, 112, 65, -1, 110, 65, -1, 956,
+ 65, -1, 109, 65, -1, 107, 65, -1,
+ 75, 66, -1, 77, 66, -1, 71, 66,
+ -1, 99, 97, 108, -1, 107, 99, 97,
+ 108, -1, 112, 70, -1, 110, 70, -1,
+ 956, 70, -1, 956, 103, -1, 109, 103,
+ -1, 107, 103, -1, 72, 122, -1, 107,
+ 72, 122, -1, 77, 72, 122, -1, 71,
+ 72, 122, -1, 84, 72, 122, -1, 956,
+ 8467, -1, 109, 8467, -1, 100, 8467, -1,
+ 107, 8467, -1, 102, 109, -1, 110, 109,
+ -1, 956, 109, -1, 109, 109, -1, 99,
+ 109, -1, 107, 109, -1, 109, 109, 178,
+ -1, 99, 109, 178, -1, 109, 178, -1,
+ 107, 109, 178, -1, 109, 109, 179, -1,
+ 99, 109, 179, -1, 109, 179, -1, 107,
+ 109, 179, -1, 109, 8725, 115, -1, 109,
+ 8725, 115, 178, -1, 80, 97, -1, 107,
+ 80, 97, -1, 77, 80, 97, -1, 71,
+ 80, 97, -1, 114, 97, 100, -1, 114,
+ 97, 100, 8725, 115, -1, 114, 97, 100,
+ 8725, 115, 178, -1, 112, 115, -1, 110,
+ 115, -1, 956, 115, -1, 109, 115, -1,
+ 112, 86, -1, 110, 86, -1, 956, 86,
+ -1, 109, 86, -1, 107, 86, -1, 77,
+ 86, -1, 112, 87, -1, 110, 87, -1,
+ 956, 87, -1, 109, 87, -1, 107, 87,
+ -1, 77, 87, -1, 107, 937, -1, 77,
+ 937, -1, 97, 46, 109, 46, -1, 66,
+ 113, -1, 99, 99, -1, 99, 100, -1,
+ 67, 8725, 107, 103, -1, 67, 111, 46,
+ -1, 100, 66, -1, 71, 121, -1, 104,
+ 97, -1, 72, 80, -1, 105, 110, -1,
+ 75, 75, -1, 75, 77, -1, 107, 116,
+ -1, 108, 109, -1, 108, 110, -1, 108,
+ 111, 103, -1, 108, 120, -1, 109, 98,
+ -1, 109, 105, 108, -1, 109, 111, 108,
+ -1, 80, 72, -1, 112, 46, 109, 46,
+ -1, 80, 80, 77, -1, 80, 82, -1,
+ 115, 114, -1, 83, 118, -1, 87, 98,
+ -1, 86, 8725, 109, -1, 65, 8725, 109,
+ -1, 49, 26085, -1, 50, 26085, -1, 51,
+ 26085, -1, 52, 26085, -1, 53, 26085, -1,
+ 54, 26085, -1, 55, 26085, -1, 56, 26085,
+ -1, 57, 26085, -1, 49, 48, 26085, -1,
+ 49, 49, 26085, -1, 49, 50, 26085, -1,
+ 49, 51, 26085, -1, 49, 52, 26085, -1,
+ 49, 53, 26085, -1, 49, 54, 26085, -1,
+ 49, 55, 26085, -1, 49, 56, 26085, -1,
+ 49, 57, 26085, -1, 50, 48, 26085, -1,
+ 50, 49, 26085, -1, 50, 50, 26085, -1,
+ 50, 51, 26085, -1, 50, 52, 26085, -1,
+ 50, 53, 26085, -1, 50, 54, 26085, -1,
+ 50, 55, 26085, -1, 50, 56, 26085, -1,
+ 50, 57, 26085, -1, 51, 48, 26085, -1,
+ 51, 49, 26085, -1, 103, 97, 108, -1,
+ 35912, -1, 26356, -1, 36040, -1, 28369, -1,
+ 20018, -1, 21477, -1, 22865, -1, 21895, -1,
+ 22856, -1, 25078, -1, 30313, -1, 32645, -1,
+ 34367, -1, 34746, -1, 35064, -1, 37007, -1,
+ 27138, -1, 27931, -1, 28889, -1, 29662, -1,
+ 33853, -1, 37226, -1, 39409, -1, 20098, -1,
+ 21365, -1, 27396, -1, 29211, -1, 34349, -1,
+ 40478, -1, 23888, -1, 28651, -1, 34253, -1,
+ 35172, -1, 25289, -1, 33240, -1, 34847, -1,
+ 24266, -1, 26391, -1, 28010, -1, 29436, -1,
+ 37070, -1, 20358, -1, 20919, -1, 21214, -1,
+ 25796, -1, 27347, -1, 29200, -1, 30439, -1,
+ 34310, -1, 34396, -1, 36335, -1, 38706, -1,
+ 39791, -1, 40442, -1, 30860, -1, 31103, -1,
+ 32160, -1, 33737, -1, 37636, -1, 35542, -1,
+ 22751, -1, 24324, -1, 31840, -1, 32894, -1,
+ 29282, -1, 30922, -1, 36034, -1, 38647, -1,
+ 22744, -1, 23650, -1, 27155, -1, 28122, -1,
+ 28431, -1, 32047, -1, 32311, -1, 38475, -1,
+ 21202, -1, 32907, -1, 20956, -1, 20940, -1,
+ 31260, -1, 32190, -1, 33777, -1, 38517, -1,
+ 35712, -1, 25295, -1, 35582, -1, 20025, -1,
+ 23527, -1, 24594, -1, 29575, -1, 30064, -1,
+ 21271, -1, 30971, -1, 20415, -1, 24489, -1,
+ 19981, -1, 27852, -1, 25976, -1, 32034, -1,
+ 21443, -1, 22622, -1, 30465, -1, 33865, -1,
+ 35498, -1, 27578, -1, 27784, -1, 25342, -1,
+ 33509, -1, 25504, -1, 30053, -1, 20142, -1,
+ 20841, -1, 20937, -1, 26753, -1, 31975, -1,
+ 33391, -1, 35538, -1, 37327, -1, 21237, -1,
+ 21570, -1, 24300, -1, 26053, -1, 28670, -1,
+ 31018, -1, 38317, -1, 39530, -1, 40599, -1,
+ 40654, -1, 26310, -1, 27511, -1, 36706, -1,
+ 24180, -1, 24976, -1, 25088, -1, 25754, -1,
+ 28451, -1, 29001, -1, 29833, -1, 31178, -1,
+ 32244, -1, 32879, -1, 36646, -1, 34030, -1,
+ 36899, -1, 37706, -1, 21015, -1, 21155, -1,
+ 21693, -1, 28872, -1, 35010, -1, 24265, -1,
+ 24565, -1, 25467, -1, 27566, -1, 31806, -1,
+ 29557, -1, 20196, -1, 22265, -1, 23994, -1,
+ 24604, -1, 29618, -1, 29801, -1, 32666, -1,
+ 32838, -1, 37428, -1, 38646, -1, 38728, -1,
+ 38936, -1, 20363, -1, 31150, -1, 37300, -1,
+ 38584, -1, 24801, -1, 20102, -1, 20698, -1,
+ 23534, -1, 23615, -1, 26009, -1, 29134, -1,
+ 30274, -1, 34044, -1, 36988, -1, 26248, -1,
+ 38446, -1, 21129, -1, 26491, -1, 26611, -1,
+ 27969, -1, 28316, -1, 29705, -1, 30041, -1,
+ 30827, -1, 32016, -1, 39006, -1, 25134, -1,
+ 38520, -1, 20523, -1, 23833, -1, 28138, -1,
+ 36650, -1, 24459, -1, 24900, -1, 26647, -1,
+ 38534, -1, 21033, -1, 21519, -1, 23653, -1,
+ 26131, -1, 26446, -1, 26792, -1, 27877, -1,
+ 29702, -1, 30178, -1, 32633, -1, 35023, -1,
+ 35041, -1, 38626, -1, 21311, -1, 28346, -1,
+ 21533, -1, 29136, -1, 29848, -1, 34298, -1,
+ 38563, -1, 40023, -1, 40607, -1, 26519, -1,
+ 28107, -1, 33256, -1, 31520, -1, 31890, -1,
+ 29376, -1, 28825, -1, 35672, -1, 20160, -1,
+ 33590, -1, 21050, -1, 20999, -1, 24230, -1,
+ 25299, -1, 31958, -1, 23429, -1, 27934, -1,
+ 26292, -1, 36667, -1, 38477, -1, 24275, -1,
+ 20800, -1, 21952, -1, 22618, -1, 26228, -1,
+ 20958, -1, 29482, -1, 30410, -1, 31036, -1,
+ 31070, -1, 31077, -1, 31119, -1, 38742, -1,
+ 31934, -1, 34322, -1, 35576, -1, 36920, -1,
+ 37117, -1, 39151, -1, 39164, -1, 39208, -1,
+ 40372, -1, 20398, -1, 20711, -1, 20813, -1,
+ 21193, -1, 21220, -1, 21329, -1, 21917, -1,
+ 22022, -1, 22120, -1, 22592, -1, 22696, -1,
+ 23652, -1, 24724, -1, 24936, -1, 24974, -1,
+ 25074, -1, 25935, -1, 26082, -1, 26257, -1,
+ 26757, -1, 28023, -1, 28186, -1, 28450, -1,
+ 29038, -1, 29227, -1, 29730, -1, 30865, -1,
+ 31049, -1, 31048, -1, 31056, -1, 31062, -1,
+ 31117, -1, 31118, -1, 31296, -1, 31361, -1,
+ 31680, -1, 32265, -1, 32321, -1, 32626, -1,
+ 32773, -1, 33261, -1, 33401, -1, 33879, -1,
+ 35088, -1, 35222, -1, 35585, -1, 35641, -1,
+ 36051, -1, 36104, -1, 36790, -1, 38627, -1,
+ 38911, -1, 38971, -1, 20006, -1, 20917, -1,
+ 20840, -1, 20352, -1, 20805, -1, 20864, -1,
+ 21191, -1, 21242, -1, 21845, -1, 21913, -1,
+ 21986, -1, 22707, -1, 22852, -1, 22868, -1,
+ 23138, -1, 23336, -1, 24274, -1, 24281, -1,
+ 24425, -1, 24493, -1, 24792, -1, 24910, -1,
+ 24840, -1, 24928, -1, 25140, -1, 25540, -1,
+ 25628, -1, 25682, -1, 25942, -1, 26395, -1,
+ 26454, -1, 28379, -1, 28363, -1, 28702, -1,
+ 30631, -1, 29237, -1, 29359, -1, 29809, -1,
+ 29958, -1, 30011, -1, 30237, -1, 30239, -1,
+ 30427, -1, 30452, -1, 30538, -1, 30528, -1,
+ 30924, -1, 31409, -1, 31867, -1, 32091, -1,
+ 32574, -1, 33618, -1, 33775, -1, 34681, -1,
+ 35137, -1, 35206, -1, 35519, -1, 35531, -1,
+ 35565, -1, 35722, -1, 36664, -1, 36978, -1,
+ 37273, -1, 37494, -1, 38524, -1, 38875, -1,
+ 38923, -1, 39698, -1, 141386, -1, 141380, -1,
+ 144341, -1, 15261, -1, 16408, -1, 16441, -1,
+ 152137, -1, 154832, -1, 163539, -1, 40771, -1,
+ 40846, -1, 102, 102, -1, 102, 105, -1,
+ 102, 108, -1, 102, 102, 105, -1, 102,
+ 102, 108, -1, 383, 116, -1, 115, 116,
+ -1, 1396, 1398, -1, 1396, 1381, -1, 1396,
+ 1387, -1, 1406, 1398, -1, 1396, 1389, -1,
+ 1497, 1460, -1, 1522, 1463, -1, 1506, -1,
+ 1492, -1, 1499, -1, 1500, -1, 1501, -1,
+ 1512, -1, 1514, -1, 1513, 1473, -1, 1513,
+ 1474, -1, 64329, 1473, -1, 64329, 1474, -1,
+ 1488, 1463, -1, 1488, 1464, -1, 1488, 1468,
+ -1, 1489, 1468, -1, 1490, 1468, -1, 1491,
+ 1468, -1, 1492, 1468, -1, 1493, 1468, -1,
+ 1494, 1468, -1, 1496, 1468, -1, 1497, 1468,
+ -1, 1498, 1468, -1, 1499, 1468, -1, 1500,
+ 1468, -1, 1502, 1468, -1, 1504, 1468, -1,
+ 1505, 1468, -1, 1507, 1468, -1, 1508, 1468,
+ -1, 1510, 1468, -1, 1511, 1468, -1, 1512,
+ 1468, -1, 1513, 1468, -1, 1514, 1468, -1,
+ 1493, 1465, -1, 1489, 1471, -1, 1499, 1471,
+ -1, 1508, 1471, -1, 1488, 1500, -1, 1649,
+ -1, 1659, -1, 1662, -1, 1664, -1, 1658,
+ -1, 1663, -1, 1657, -1, 1700, -1, 1702,
+ -1, 1668, -1, 1667, -1, 1670, -1, 1671,
+ -1, 1677, -1, 1676, -1, 1678, -1, 1672,
+ -1, 1688, -1, 1681, -1, 1705, -1, 1711,
+ -1, 1715, -1, 1713, -1, 1722, -1, 1723,
+ -1, 1728, -1, 1729, -1, 1726, -1, 1746,
+ -1, 1747, -1, 1709, -1, 1735, -1, 1734,
+ -1, 1736, -1, 1655, -1, 1739, -1, 1733,
+ -1, 1737, -1, 1744, -1, 1609, -1, 1574,
+ 1575, -1, 1574, 1749, -1, 1574, 1608, -1,
+ 1574, 1735, -1, 1574, 1734, -1, 1574, 1736,
+ -1, 1574, 1744, -1, 1574, 1609, -1, 1740,
+ -1, 1574, 1580, -1, 1574, 1581, -1, 1574,
+ 1605, -1, 1574, 1610, -1, 1576, 1580, -1,
+ 1576, 1581, -1, 1576, 1582, -1, 1576, 1605,
+ -1, 1576, 1609, -1, 1576, 1610, -1, 1578,
+ 1580, -1, 1578, 1581, -1, 1578, 1582, -1,
+ 1578, 1605, -1, 1578, 1609, -1, 1578, 1610,
+ -1, 1579, 1580, -1, 1579, 1605, -1, 1579,
+ 1609, -1, 1579, 1610, -1, 1580, 1581, -1,
+ 1580, 1605, -1, 1581, 1580, -1, 1581, 1605,
+ -1, 1582, 1580, -1, 1582, 1581, -1, 1582,
+ 1605, -1, 1587, 1580, -1, 1587, 1581, -1,
+ 1587, 1582, -1, 1587, 1605, -1, 1589, 1581,
+ -1, 1589, 1605, -1, 1590, 1580, -1, 1590,
+ 1581, -1, 1590, 1582, -1, 1590, 1605, -1,
+ 1591, 1581, -1, 1591, 1605, -1, 1592, 1605,
+ -1, 1593, 1580, -1, 1593, 1605, -1, 1594,
+ 1580, -1, 1594, 1605, -1, 1601, 1580, -1,
+ 1601, 1581, -1, 1601, 1582, -1, 1601, 1605,
+ -1, 1601, 1609, -1, 1601, 1610, -1, 1602,
+ 1581, -1, 1602, 1605, -1, 1602, 1609, -1,
+ 1602, 1610, -1, 1603, 1575, -1, 1603, 1580,
+ -1, 1603, 1581, -1, 1603, 1582, -1, 1603,
+ 1604, -1, 1603, 1605, -1, 1603, 1609, -1,
+ 1603, 1610, -1, 1604, 1580, -1, 1604, 1581,
+ -1, 1604, 1582, -1, 1604, 1605, -1, 1604,
+ 1609, -1, 1604, 1610, -1, 1605, 1580, -1,
+ 1605, 1581, -1, 1605, 1582, -1, 1605, 1605,
+ -1, 1605, 1609, -1, 1605, 1610, -1, 1606,
+ 1580, -1, 1606, 1581, -1, 1606, 1582, -1,
+ 1606, 1605, -1, 1606, 1609, -1, 1606, 1610,
+ -1, 1607, 1580, -1, 1607, 1605, -1, 1607,
+ 1609, -1, 1607, 1610, -1, 1610, 1580, -1,
+ 1610, 1581, -1, 1610, 1582, -1, 1610, 1605,
+ -1, 1610, 1609, -1, 1610, 1610, -1, 1584,
+ 1648, -1, 1585, 1648, -1, 1609, 1648, -1,
+ 32, 1612, 1617, -1, 32, 1613, 1617, -1,
+ 32, 1614, 1617, -1, 32, 1615, 1617, -1,
+ 32, 1616, 1617, -1, 32, 1617, 1648, -1,
+ 1574, 1585, -1, 1574, 1586, -1, 1574, 1606,
+ -1, 1576, 1585, -1, 1576, 1586, -1, 1576,
+ 1606, -1, 1578, 1585, -1, 1578, 1586, -1,
+ 1578, 1606, -1, 1579, 1585, -1, 1579, 1586,
+ -1, 1579, 1606, -1, 1605, 1575, -1, 1606,
+ 1585, -1, 1606, 1586, -1, 1606, 1606, -1,
+ 1610, 1585, -1, 1610, 1586, -1, 1610, 1606,
+ -1, 1574, 1582, -1, 1574, 1607, -1, 1576,
+ 1607, -1, 1578, 1607, -1, 1589, 1582, -1,
+ 1604, 1607, -1, 1606, 1607, -1, 1607, 1648,
+ -1, 1610, 1607, -1, 1579, 1607, -1, 1587,
+ 1607, -1, 1588, 1605, -1, 1588, 1607, -1,
+ 1600, 1614, 1617, -1, 1600, 1615, 1617, -1,
+ 1600, 1616, 1617, -1, 1591, 1609, -1, 1591,
+ 1610, -1, 1593, 1609, -1, 1593, 1610, -1,
+ 1594, 1609, -1, 1594, 1610, -1, 1587, 1609,
+ -1, 1587, 1610, -1, 1588, 1609, -1, 1588,
+ 1610, -1, 1581, 1609, -1, 1581, 1610, -1,
+ 1580, 1609, -1, 1580, 1610, -1, 1582, 1609,
+ -1, 1582, 1610, -1, 1589, 1609, -1, 1589,
+ 1610, -1, 1590, 1609, -1, 1590, 1610, -1,
+ 1588, 1580, -1, 1588, 1581, -1, 1588, 1582,
+ -1, 1588, 1585, -1, 1587, 1585, -1, 1589,
+ 1585, -1, 1590, 1585, -1, 1575, 1611, -1,
+ 1578, 1580, 1605, -1, 1578, 1581, 1580, -1,
+ 1578, 1581, 1605, -1, 1578, 1582, 1605, -1,
+ 1578, 1605, 1580, -1, 1578, 1605, 1581, -1,
+ 1578, 1605, 1582, -1, 1580, 1605, 1581, -1,
+ 1581, 1605, 1610, -1, 1581, 1605, 1609, -1,
+ 1587, 1581, 1580, -1, 1587, 1580, 1581, -1,
+ 1587, 1580, 1609, -1, 1587, 1605, 1581, -1,
+ 1587, 1605, 1580, -1, 1587, 1605, 1605, -1,
+ 1589, 1581, 1581, -1, 1589, 1605, 1605, -1,
+ 1588, 1581, 1605, -1, 1588, 1580, 1610, -1,
+ 1588, 1605, 1582, -1, 1588, 1605, 1605, -1,
+ 1590, 1581, 1609, -1, 1590, 1582, 1605, -1,
+ 1591, 1605, 1581, -1, 1591, 1605, 1605, -1,
+ 1591, 1605, 1610, -1, 1593, 1580, 1605, -1,
+ 1593, 1605, 1605, -1, 1593, 1605, 1609, -1,
+ 1594, 1605, 1605, -1, 1594, 1605, 1610, -1,
+ 1594, 1605, 1609, -1, 1601, 1582, 1605, -1,
+ 1602, 1605, 1581, -1, 1602, 1605, 1605, -1,
+ 1604, 1581, 1605, -1, 1604, 1581, 1610, -1,
+ 1604, 1581, 1609, -1, 1604, 1580, 1580, -1,
+ 1604, 1582, 1605, -1, 1604, 1605, 1581, -1,
+ 1605, 1581, 1580, -1, 1605, 1581, 1605, -1,
+ 1605, 1581, 1610, -1, 1605, 1580, 1581, -1,
+ 1605, 1580, 1605, -1, 1605, 1582, 1580, -1,
+ 1605, 1582, 1605, -1, 1605, 1580, 1582, -1,
+ 1607, 1605, 1580, -1, 1607, 1605, 1605, -1,
+ 1606, 1581, 1605, -1, 1606, 1581, 1609, -1,
+ 1606, 1580, 1605, -1, 1606, 1580, 1609, -1,
+ 1606, 1605, 1610, -1, 1606, 1605, 1609, -1,
+ 1610, 1605, 1605, -1, 1576, 1582, 1610, -1,
+ 1578, 1580, 1610, -1, 1578, 1580, 1609, -1,
+ 1578, 1582, 1610, -1, 1578, 1582, 1609, -1,
+ 1578, 1605, 1610, -1, 1578, 1605, 1609, -1,
+ 1580, 1605, 1610, -1, 1580, 1581, 1609, -1,
+ 1580, 1605, 1609, -1, 1587, 1582, 1609, -1,
+ 1589, 1581, 1610, -1, 1588, 1581, 1610, -1,
+ 1590, 1581, 1610, -1, 1604, 1580, 1610, -1,
+ 1604, 1605, 1610, -1, 1610, 1581, 1610, -1,
+ 1610, 1580, 1610, -1, 1610, 1605, 1610, -1,
+ 1605, 1605, 1610, -1, 1602, 1605, 1610, -1,
+ 1606, 1581, 1610, -1, 1593, 1605, 1610, -1,
+ 1603, 1605, 1610, -1, 1606, 1580, 1581, -1,
+ 1605, 1582, 1610, -1, 1604, 1580, 1605, -1,
+ 1603, 1605, 1605, -1, 1580, 1581, 1610, -1,
+ 1581, 1580, 1610, -1, 1605, 1580, 1610, -1,
+ 1601, 1605, 1610, -1, 1576, 1581, 1610, -1,
+ 1587, 1582, 1610, -1, 1606, 1580, 1610, -1,
+ 1589, 1604, 1746, -1, 1602, 1604, 1746, -1,
+ 1575, 1604, 1604, 1607, -1, 1575, 1603, 1576,
+ 1585, -1, 1605, 1581, 1605, 1583, -1, 1589,
+ 1604, 1593, 1605, -1, 1585, 1587, 1608, 1604,
+ -1, 1593, 1604, 1610, 1607, -1, 1608, 1587,
+ 1604, 1605, -1, 1589, 1604, 1609, -1, 1589,
+ 1604, 1609, 32, 1575, 1604, 1604, 1607, 32,
+ 1593, 1604, 1610, 1607, 32, 1608, 1587, 1604,
+ 1605, -1, 1580, 1604, 32, 1580, 1604, 1575,
+ 1604, 1607, -1, 1585, 1740, 1575, 1604, -1,
+ 44, -1, 12289, -1, 12290, -1, 58, -1,
+ 33, -1, 63, -1, 12310, -1, 12311, -1,
+ 8230, -1, 8229, -1, 8212, -1, 8211, -1,
+ 95, -1, 123, -1, 125, -1, 12308, -1,
+ 12309, -1, 12304, -1, 12305, -1, 12298, -1,
+ 12299, -1, 12300, -1, 12301, -1, 12302, -1,
+ 12303, -1, 91, -1, 93, -1, 8254, -1,
+ 35, -1, 38, -1, 42, -1, 45, -1,
+ 60, -1, 62, -1, 92, -1, 36, -1,
+ 37, -1, 64, -1, 32, 1611, -1, 1600,
+ 1611, -1, 32, 1612, -1, 32, 1613, -1,
+ 32, 1614, -1, 1600, 1614, -1, 32, 1615,
+ -1, 1600, 1615, -1, 32, 1616, -1, 1600,
+ 1616, -1, 32, 1617, -1, 1600, 1617, -1,
+ 32, 1618, -1, 1600, 1618, -1, 1569, -1,
+ 1570, -1, 1571, -1, 1572, -1, 1573, -1,
+ 1574, -1, 1575, -1, 1576, -1, 1577, -1,
+ 1578, -1, 1579, -1, 1580, -1, 1581, -1,
+ 1582, -1, 1583, -1, 1584, -1, 1585, -1,
+ 1586, -1, 1587, -1, 1588, -1, 1589, -1,
+ 1590, -1, 1591, -1, 1592, -1, 1593, -1,
+ 1594, -1, 1601, -1, 1602, -1, 1603, -1,
+ 1604, -1, 1605, -1, 1606, -1, 1607, -1,
+ 1608, -1, 1610, -1, 1604, 1570, -1, 1604,
+ 1571, -1, 1604, 1573, -1, 1604, 1575, -1,
+ 34, -1, 39, -1, 47, -1, 65345, -1,
+ 65346, -1, 65347, -1, 65348, -1, 65349, -1,
+ 65350, -1, 65351, -1, 65352, -1, 65353, -1,
+ 65354, -1, 65355, -1, 65356, -1, 65357, -1,
+ 65358, -1, 65359, -1, 65360, -1, 65361, -1,
+ 65362, -1, 65363, -1, 65364, -1, 65365, -1,
+ 65366, -1, 65367, -1, 65368, -1, 65369, -1,
+ 65370, -1, 94, -1, 124, -1, 126, -1,
+ 10629, -1, 10630, -1, 12539, -1, 12449, -1,
+ 12451, -1, 12453, -1, 12455, -1, 12457, -1,
+ 12515, -1, 12517, -1, 12519, -1, 12483, -1,
+ 12540, -1, 12531, -1, 12441, -1, 12442, -1,
+ 12644, -1, 12593, -1, 12594, -1, 12595, -1,
+ 12596, -1, 12597, -1, 12598, -1, 12599, -1,
+ 12600, -1, 12601, -1, 12602, -1, 12603, -1,
+ 12604, -1, 12605, -1, 12606, -1, 12607, -1,
+ 12608, -1, 12609, -1, 12610, -1, 12611, -1,
+ 12612, -1, 12613, -1, 12614, -1, 12615, -1,
+ 12616, -1, 12617, -1, 12618, -1, 12619, -1,
+ 12620, -1, 12621, -1, 12622, -1, 12623, -1,
+ 12624, -1, 12625, -1, 12626, -1, 12627, -1,
+ 12628, -1, 12629, -1, 12630, -1, 12631, -1,
+ 12632, -1, 12633, -1, 12634, -1, 12635, -1,
+ 12636, -1, 12637, -1, 12638, -1, 12639, -1,
+ 12640, -1, 12641, -1, 12642, -1, 12643, -1,
+ 162, -1, 163, -1, 172, -1, 175, -1,
+ 166, -1, 165, -1, 8361, -1, 9474, -1,
+ 8592, -1, 8593, -1, 8594, -1, 8595, -1,
+ 9632, -1, 9675, -1, 66600, -1, 66601, -1,
+ 66602, -1, 66603, -1, 66604, -1, 66605, -1,
+ 66606, -1, 66607, -1, 66608, -1, 66609, -1,
+ 66610, -1, 66611, -1, 66612, -1, 66613, -1,
+ 66614, -1, 66615, -1, 66616, -1, 66617, -1,
+ 66618, -1, 66619, -1, 66620, -1, 66621, -1,
+ 66622, -1, 66623, -1, 66624, -1, 66625, -1,
+ 66626, -1, 66627, -1, 66628, -1, 66629, -1,
+ 66630, -1, 66631, -1, 66632, -1, 66633, -1,
+ 66634, -1, 66635, -1, 66636, -1, 66637, -1,
+ 66638, -1, 66639, -1, 119127, 119141, -1, 119128,
+ 119141, -1, 119135, 119150, -1, 119135, 119151, -1,
+ 119135, 119152, -1, 119135, 119153, -1, 119135, 119154,
+ -1, 119225, 119141, -1, 119226, 119141, -1, 119227,
+ 119150, -1, 119228, 119150, -1, 119227, 119151, -1,
+ 119228, 119151, -1, 305, -1, 567, -1, 913,
+ -1, 914, -1, 916, -1, 917, -1, 918,
+ -1, 919, -1, 921, -1, 922, -1, 923,
+ -1, 924, -1, 925, -1, 926, -1, 927,
+ -1, 929, -1, 1012, -1, 932, -1, 934,
+ -1, 935, -1, 936, -1, 8711, -1, 8706,
+ -1, 1013, -1, 977, -1, 1008, -1, 981,
+ -1, 1009, -1, 982, -1, 988, -1, 20029,
+ -1, 20024, -1, 20033, -1, 131362, -1, 20320,
+ -1, 20411, -1, 20482, -1, 20602, -1, 20633,
+ -1, 20687, -1, 13470, -1, 132666, -1, 20820,
+ -1, 20836, -1, 20855, -1, 132380, -1, 13497,
+ -1, 20839, -1, 20877, -1, 132427, -1, 20887,
+ -1, 20900, -1, 20172, -1, 20908, -1, 168415,
+ -1, 20995, -1, 13535, -1, 21051, -1, 21062,
+ -1, 21106, -1, 21111, -1, 13589, -1, 21253,
+ -1, 21254, -1, 21321, -1, 21338, -1, 21363,
+ -1, 21373, -1, 21375, -1, 133676, -1, 28784,
+ -1, 21450, -1, 21471, -1, 133987, -1, 21483,
+ -1, 21489, -1, 21510, -1, 21662, -1, 21560,
+ -1, 21576, -1, 21608, -1, 21666, -1, 21750,
+ -1, 21776, -1, 21843, -1, 21859, -1, 21892,
+ -1, 21931, -1, 21939, -1, 21954, -1, 22294,
+ -1, 22295, -1, 22097, -1, 22132, -1, 22766,
+ -1, 22478, -1, 22516, -1, 22541, -1, 22411,
+ -1, 22578, -1, 22577, -1, 22700, -1, 136420,
+ -1, 22770, -1, 22775, -1, 22790, -1, 22810,
+ -1, 22818, -1, 22882, -1, 136872, -1, 136938,
+ -1, 23020, -1, 23067, -1, 23079, -1, 23000,
+ -1, 23142, -1, 14062, -1, 14076, -1, 23304,
+ -1, 23358, -1, 137672, -1, 23491, -1, 23512,
+ -1, 23539, -1, 138008, -1, 23551, -1, 23558,
+ -1, 24403, -1, 14209, -1, 23648, -1, 23744,
+ -1, 23693, -1, 138724, -1, 23875, -1, 138726,
+ -1, 23918, -1, 23915, -1, 23932, -1, 24033,
+ -1, 24034, -1, 14383, -1, 24061, -1, 24104,
+ -1, 24125, -1, 24169, -1, 14434, -1, 139651,
+ -1, 14460, -1, 24240, -1, 24243, -1, 24246,
+ -1, 172946, -1, 140081, -1, 33281, -1, 24354,
+ -1, 14535, -1, 144056, -1, 156122, -1, 24418,
+ -1, 24427, -1, 14563, -1, 24474, -1, 24525,
+ -1, 24535, -1, 24569, -1, 24705, -1, 14650,
+ -1, 14620, -1, 141012, -1, 24775, -1, 24904,
+ -1, 24908, -1, 24954, -1, 25010, -1, 24996,
+ -1, 25007, -1, 25054, -1, 25104, -1, 25115,
+ -1, 25181, -1, 25265, -1, 25300, -1, 25424,
+ -1, 142092, -1, 25405, -1, 25340, -1, 25448,
+ -1, 25475, -1, 25572, -1, 142321, -1, 25634,
+ -1, 25541, -1, 25513, -1, 14894, -1, 25705,
+ -1, 25726, -1, 25757, -1, 25719, -1, 14956,
+ -1, 25964, -1, 143370, -1, 26083, -1, 26360,
+ -1, 26185, -1, 15129, -1, 15112, -1, 15076,
+ -1, 20882, -1, 20885, -1, 26368, -1, 26268,
+ -1, 32941, -1, 17369, -1, 26401, -1, 26462,
+ -1, 26451, -1, 144323, -1, 15177, -1, 26618,
+ -1, 26501, -1, 26706, -1, 144493, -1, 26766,
+ -1, 26655, -1, 26900, -1, 26946, -1, 27043,
+ -1, 27114, -1, 27304, -1, 145059, -1, 27355,
+ -1, 15384, -1, 27425, -1, 145575, -1, 27476,
+ -1, 15438, -1, 27506, -1, 27551, -1, 27579,
+ -1, 146061, -1, 138507, -1, 146170, -1, 27726,
+ -1, 146620, -1, 27839, -1, 27853, -1, 27751,
+ -1, 27926, -1, 27966, -1, 28009, -1, 28024,
+ -1, 28037, -1, 146718, -1, 27956, -1, 28207,
+ -1, 28270, -1, 15667, -1, 28359, -1, 147153,
+ -1, 28153, -1, 28526, -1, 147294, -1, 147342,
+ -1, 28614, -1, 28729, -1, 28699, -1, 15766,
+ -1, 28746, -1, 28797, -1, 28791, -1, 28845,
+ -1, 132389, -1, 28997, -1, 148067, -1, 29084,
+ -1, 148395, -1, 29224, -1, 29264, -1, 149000,
+ -1, 29312, -1, 29333, -1, 149301, -1, 149524,
+ -1, 29562, -1, 29579, -1, 16044, -1, 29605,
+ -1, 16056, -1, 29767, -1, 29788, -1, 29829,
+ -1, 29898, -1, 16155, -1, 29988, -1, 150582,
+ -1, 30014, -1, 150674, -1, 139679, -1, 30224,
+ -1, 151457, -1, 151480, -1, 151620, -1, 16380,
+ -1, 16392, -1, 151795, -1, 151794, -1, 151833,
+ -1, 151859, -1, 30494, -1, 30495, -1, 30603,
+ -1, 16454, -1, 16534, -1, 152605, -1, 30798,
+ -1, 16611, -1, 153126, -1, 153242, -1, 153285,
+ -1, 31211, -1, 16687, -1, 31306, -1, 31311,
+ -1, 153980, -1, 154279, -1, 31470, -1, 16898,
+ -1, 154539, -1, 31686, -1, 31689, -1, 16935,
+ -1, 154752, -1, 31954, -1, 17056, -1, 31976,
+ -1, 31971, -1, 32000, -1, 155526, -1, 32099,
+ -1, 17153, -1, 32199, -1, 32258, -1, 32325,
+ -1, 17204, -1, 156200, -1, 156231, -1, 17241,
+ -1, 156377, -1, 32634, -1, 156478, -1, 32661,
+ -1, 32762, -1, 156890, -1, 156963, -1, 32864,
+ -1, 157096, -1, 32880, -1, 144223, -1, 17365,
+ -1, 32946, -1, 33027, -1, 17419, -1, 33086,
+ -1, 23221, -1, 157607, -1, 157621, -1, 144275,
+ -1, 144284, -1, 33284, -1, 36766, -1, 17515,
+ -1, 33425, -1, 33419, -1, 33437, -1, 21171,
+ -1, 33457, -1, 33459, -1, 33469, -1, 33510,
+ -1, 158524, -1, 33565, -1, 33635, -1, 33709,
+ -1, 33571, -1, 33725, -1, 33767, -1, 33619,
+ -1, 33738, -1, 33740, -1, 33756, -1, 158774,
+ -1, 159083, -1, 158933, -1, 17707, -1, 34033,
+ -1, 34035, -1, 34070, -1, 160714, -1, 34148,
+ -1, 159532, -1, 17757, -1, 17761, -1, 159665,
+ -1, 159954, -1, 17771, -1, 34384, -1, 34407,
+ -1, 34409, -1, 34473, -1, 34440, -1, 34574,
+ -1, 34530, -1, 34600, -1, 34667, -1, 34694,
+ -1, 17879, -1, 34785, -1, 34817, -1, 17913,
+ -1, 34912, -1, 161383, -1, 35031, -1, 35038,
+ -1, 17973, -1, 35066, -1, 13499, -1, 161966,
+ -1, 162150, -1, 18110, -1, 18119, -1, 35488,
+ -1, 162984, -1, 36011, -1, 36033, -1, 36123,
+ -1, 36215, -1, 163631, -1, 133124, -1, 36299,
+ -1, 36284, -1, 36336, -1, 133342, -1, 36564,
+ -1, 165330, -1, 165357, -1, 37012, -1, 37105,
+ -1, 37137, -1, 165678, -1, 37147, -1, 37432,
+ -1, 37591, -1, 37592, -1, 37500, -1, 37881,
+ -1, 37909, -1, 166906, -1, 38283, -1, 18837,
+ -1, 38327, -1, 167287, -1, 18918, -1, 38595,
+ -1, 23986, -1, 38691, -1, 168261, -1, 168474,
+ -1, 19054, -1, 19062, -1, 38880, -1, 168970,
+ -1, 19122, -1, 169110, -1, 38953, -1, 169398,
+ -1, 39138, -1, 19251, -1, 39209, -1, 39335,
+ -1, 39362, -1, 39422, -1, 19406, -1, 170800,
+ -1, 40000, -1, 40189, -1, 19662, -1, 19693,
+ -1, 40295, -1, 172238, -1, 19704, -1, 172293,
+ -1, 172558, -1, 172689, -1, 19798, -1, 40702,
+ -1, 40709, -1, 40719, -1, 40726, -1, 173568,
+ -1, };
+
+const uint16_t utf8proc_stage1table[] = {
+ 0, 256, 512, 768, 1024, 1280, 1536,
+ 1792, 2048, 2304, 2560, 2816, 3072, 3328, 3584,
+ 3840, 4096, 4352, 4608, 4864, 5120, 5376, 5632,
+ 5888, 6144, 6400, 6656, 6912, 2048, 7168, 7424,
+ 7680, 7936, 8192, 8448, 8704, 8960, 9216, 9472,
+ 9728, 9984, 10240, 10496, 10752, 11008, 11264, 11520,
+ 11776, 12032, 12288, 12544, 12800, 5376, 5376, 5376,
+ 5376, 5376, 5376, 5376, 5376, 5376, 5376, 5376,
+ 5376, 5376, 5376, 5376, 5376, 5376, 5376, 5376,
+ 5376, 5376, 5376, 5376, 5376, 5376, 13056, 5376,
+ 5376, 5376, 5376, 5376, 5376, 5376, 5376, 5376,
+ 5376, 5376, 5376, 5376, 5376, 5376, 5376, 5376,
+ 5376, 5376, 5376, 5376, 5376, 5376, 5376, 5376,
+ 5376, 5376, 5376, 5376, 5376, 5376, 5376, 5376,
+ 5376, 5376, 5376, 5376, 5376, 5376, 5376, 5376,
+ 5376, 5376, 5376, 5376, 5376, 5376, 5376, 5376,
+ 5376, 5376, 5376, 5376, 5376, 5376, 5376, 5376,
+ 5376, 5376, 5376, 5376, 5376, 5376, 5376, 5376,
+ 5376, 5376, 5376, 5376, 5376, 5376, 5376, 5376,
+ 5376, 5376, 5376, 5376, 5376, 5376, 5376, 5376,
+ 13312, 13568, 5376, 5376, 5376, 13824, 2048, 2048,
+ 14080, 14336, 2048, 2048, 2048, 5376, 5376, 5376,
+ 5376, 5376, 5376, 5376, 5376, 5376, 5376, 5376,
+ 5376, 5376, 5376, 5376, 5376, 5376, 5376, 5376,
+ 5376, 5376, 5376, 5376, 5376, 5376, 5376, 5376,
+ 5376, 5376, 5376, 5376, 5376, 5376, 5376, 5376,
+ 5376, 5376, 5376, 5376, 5376, 5376, 5376, 5376,
+ 14592, 14848, 14848, 14848, 14848, 14848, 14848, 14848,
+ 14848, 15104, 15104, 15104, 15104, 15104, 15104, 15104,
+ 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104,
+ 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104,
+ 15104, 15104, 15360, 15616, 15872, 16128, 16384, 16640,
+ 16896, 17152, 17408, 2048, 17664, 17920, 2048, 2048,
+ 2048, 18176, 18432, 18688, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 5376, 5376, 5376, 18944, 19200, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 19456, 19712, 19968, 20224, 20480, 20736, 20992,
+ 21248, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 5376, 5376, 5376, 5376, 5376, 5376, 5376,
+ 5376, 5376, 5376, 5376, 5376, 5376, 5376, 5376,
+ 5376, 5376, 5376, 5376, 5376, 5376, 5376, 5376,
+ 5376, 5376, 5376, 5376, 5376, 5376, 5376, 5376,
+ 5376, 5376, 5376, 5376, 5376, 5376, 5376, 5376,
+ 5376, 5376, 5376, 5376, 5376, 5376, 5376, 5376,
+ 5376, 5376, 5376, 5376, 5376, 5376, 5376, 5376,
+ 5376, 5376, 5376, 5376, 5376, 5376, 5376, 5376,
+ 5376, 5376, 5376, 5376, 5376, 5376, 5376, 5376,
+ 5376, 5376, 5376, 5376, 5376, 5376, 5376, 5376,
+ 5376, 5376, 5376, 5376, 5376, 5376, 5376, 5376,
+ 5376, 5376, 5376, 5376, 5376, 5376, 5376, 5376,
+ 5376, 5376, 5376, 5376, 5376, 5376, 5376, 5376,
+ 5376, 5376, 5376, 5376, 5376, 5376, 5376, 5376,
+ 5376, 5376, 5376, 5376, 5376, 5376, 5376, 5376,
+ 5376, 5376, 5376, 5376, 5376, 5376, 5376, 5376,
+ 5376, 5376, 5376, 5376, 5376, 5376, 5376, 5376,
+ 5376, 5376, 5376, 5376, 5376, 5376, 5376, 5376,
+ 5376, 5376, 5376, 5376, 5376, 5376, 5376, 5376,
+ 5376, 5376, 5376, 5376, 5376, 5376, 5376, 5376,
+ 5376, 5376, 5376, 5376, 5376, 5376, 5376, 21504,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 21760, 22016, 22272, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 22528, 22784, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048,
+ 2048, 15104, 15104, 15104, 15104, 15104, 15104, 15104,
+ 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104,
+ 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104,
+ 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104,
+ 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104,
+ 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104,
+ 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104,
+ 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104,
+ 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104,
+ 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104,
+ 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104,
+ 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104,
+ 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104,
+ 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104,
+ 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104,
+ 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104,
+ 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104,
+ 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104,
+ 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104,
+ 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104,
+ 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104,
+ 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104,
+ 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104,
+ 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104,
+ 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104,
+ 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104,
+ 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104,
+ 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104,
+ 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104,
+ 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104,
+ 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104,
+ 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104,
+ 23040, 15104, 15104, 15104, 15104, 15104, 15104, 15104,
+ 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104,
+ 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104,
+ 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104,
+ 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104,
+ 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104,
+ 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104,
+ 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104,
+ 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104,
+ 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104,
+ 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104,
+ 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104,
+ 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104,
+ 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104,
+ 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104,
+ 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104,
+ 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104,
+ 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104,
+ 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104,
+ 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104,
+ 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104,
+ 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104,
+ 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104,
+ 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104,
+ 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104,
+ 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104,
+ 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104,
+ 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104,
+ 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104,
+ 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104,
+ 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104,
+ 15104, 15104, 15104, 15104, 15104, 15104, 15104, 15104,
+ 23040, };
+
+const uint16_t utf8proc_stage2table[] = {
+ 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 2, 3, 2, 4, 3, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 5, 5, 5,
+ 6, 7, 8, 8, 9, 10, 9, 8,
+ 8, 11, 12, 8, 13, 14, 15, 14,
+ 14, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 14, 8, 17, 18, 19,
+ 8, 8, 20, 21, 22, 23, 24, 25,
+ 26, 27, 28, 29, 30, 31, 32, 33,
+ 34, 35, 36, 37, 38, 39, 40, 41,
+ 42, 43, 44, 45, 11, 8, 12, 46,
+ 47, 46, 48, 49, 50, 51, 52, 53,
+ 54, 55, 56, 57, 58, 59, 60, 61,
+ 62, 63, 64, 65, 66, 67, 68, 69,
+ 70, 71, 72, 73, 11, 74, 12, 74,
+ 1, 1, 1, 1, 1, 1, 3, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 75, 8, 10, 10, 10, 10, 76,
+ 76, 77, 76, 78, 79, 74, 80, 76,
+ 81, 82, 83, 84, 85, 86, 87, 76,
+ 8, 88, 89, 90, 91, 92, 93, 94,
+ 8, 95, 96, 97, 98, 99, 100, 101,
+ 102, 103, 104, 105, 106, 107, 108, 109,
+ 110, 111, 112, 113, 114, 115, 116, 117,
+ 74, 118, 119, 120, 121, 122, 123, 124,
+ 125, 126, 127, 128, 129, 130, 131, 132,
+ 133, 134, 135, 136, 137, 138, 139, 140,
+ 141, 142, 143, 144, 145, 146, 147, 148,
+ 74, 149, 150, 151, 152, 153, 154, 155,
+ 156, 157, 158, 159, 160, 161, 162, 163,
+ 164, 165, 166, 167, 168, 169, 170, 171,
+ 172, 173, 174, 175, 176, 177, 178, 179,
+ 180, 181, 182, 183, 184, 185, 186, 187,
+ 188, 189, 190, 191, 192, 193, 194, 195,
+ 196, 197, 198, 199, 200, 201, 202, 203,
+ 204, 205, 206, 207, 208, 209, 210, 211,
+ 212, 213, 214, 215, 216, 217, 218, 219,
+ 220, 221, 222, 223, 224, 225, 226, 227,
+ 228, 229, 230, 231, 232, 233, 234, 235,
+ 236, 237, 238, 239, 240, 241, 242, 243,
+ 244, 245, 246, 247, 248, 249, 250, 251,
+ 252, 253, 254, 255, 256, 257, 258, 259,
+ 260, 261, 262, 263, 264, 265, 266, 267,
+ 268, 269, 270, 271, 272, 273, 274, 275,
+ 276, 277, 278, 279, 280, 281, 282, 283,
+ 284, 285, 286, 287, 288, 289, 290, 291,
+ 292, 293, 294, 295, 296, 297, 213, 298,
+ 299, 300, 301, 302, 303, 304, 305, 306,
+ 307, 308, 309, 310, 213, 311, 312, 313,
+ 314, 315, 316, 317, 318, 319, 320, 321,
+ 322, 323, 324, 213, 213, 325, 326, 327,
+ 328, 329, 330, 331, 332, 333, 334, 335,
+ 336, 337, 338, 213, 339, 340, 341, 213,
+ 342, 339, 339, 339, 339, 343, 344, 345,
+ 346, 347, 348, 349, 350, 351, 352, 353,
+ 354, 355, 356, 357, 358, 359, 360, 361,
+ 362, 363, 364, 365, 366, 367, 368, 369,
+ 370, 371, 372, 373, 374, 375, 376, 377,
+ 378, 379, 380, 381, 382, 383, 384, 385,
+ 386, 387, 388, 389, 390, 391, 392, 393,
+ 394, 395, 396, 397, 398, 399, 400, 401,
+ 402, 403, 404, 405, 406, 407, 408, 409,
+ 410, 411, 412, 413, 414, 415, 416, 417,
+ 418, 419, 420, 421, 422, 423, 424, 425,
+ 426, 427, 428, 429, 430, 431, 432, 433,
+ 434, 435, 213, 436, 437, 438, 439, 440,
+ 441, 442, 443, 444, 445, 446, 447, 448,
+ 449, 450, 451, 452, 453, 213, 213, 213,
+ 213, 213, 213, 454, 455, 456, 457, 458,
+ 213, 213, 459, 460, 461, 462, 463, 464,
+ 465, 466, 467, 468, 469, 470, 471, 472,
+ 473, 213, 213, 213, 474, 475, 213, 476,
+ 477, 213, 478, 213, 479, 213, 213, 213,
+ 213, 480, 213, 213, 481, 213, 213, 213,
+ 213, 482, 483, 213, 484, 213, 213, 213,
+ 485, 213, 213, 486, 213, 213, 487, 213,
+ 213, 213, 213, 213, 213, 213, 488, 213,
+ 213, 489, 213, 213, 490, 213, 213, 213,
+ 213, 491, 492, 493, 494, 495, 213, 213,
+ 213, 213, 213, 496, 213, 339, 213, 213,
+ 213, 213, 213, 213, 213, 213, 213, 213,
+ 213, 213, 213, 213, 213, 213, 213, 213,
+ 213, 213, 213, 213, 213, 213, 213, 213,
+ 213, 497, 498, 499, 500, 501, 502, 503,
+ 504, 505, 506, 506, 507, 507, 507, 507,
+ 507, 507, 507, 46, 46, 46, 46, 506,
+ 506, 506, 506, 506, 506, 506, 506, 506,
+ 506, 507, 507, 46, 46, 46, 46, 46,
+ 46, 508, 509, 510, 511, 512, 513, 46,
+ 46, 514, 515, 516, 517, 518, 46, 46,
+ 46, 46, 46, 46, 46, 46, 46, 507,
+ 46, 46, 46, 46, 46, 46, 46, 46,
+ 46, 46, 46, 46, 46, 46, 46, 46,
+ 46, 519, 520, 521, 522, 523, 524, 525,
+ 526, 527, 528, 529, 530, 531, 524, 524,
+ 532, 524, 533, 524, 534, 535, 536, 537,
+ 537, 537, 537, 536, 538, 537, 537, 537,
+ 537, 537, 539, 539, 540, 541, 542, 543,
+ 544, 545, 537, 537, 537, 537, 546, 547,
+ 537, 548, 549, 537, 537, 550, 550, 550,
+ 550, 551, 537, 537, 537, 537, 524, 524,
+ 524, 552, 553, 554, 555, 556, 557, 524,
+ 537, 537, 537, 524, 524, 524, 537, 537,
+ 558, 524, 524, 524, 537, 537, 537, 537,
+ 524, 536, 537, 537, 524, 559, 560, 560,
+ 559, 560, 560, 559, 524, 524, 524, 524,
+ 524, 524, 524, 524, 524, 524, 524, 524,
+ 524, 0, 0, 0, 0, 561, 46, 0,
+ 0, 0, 0, 562, 563, 564, 565, 566,
+ 0, 0, 0, 0, 0, 86, 567, 568,
+ 569, 570, 571, 572, 0, 573, 0, 574,
+ 575, 576, 577, 578, 579, 580, 581, 582,
+ 583, 584, 585, 586, 587, 588, 589, 590,
+ 591, 592, 593, 0, 594, 595, 596, 597,
+ 598, 599, 600, 601, 602, 603, 604, 605,
+ 606, 607, 608, 609, 610, 611, 612, 613,
+ 614, 615, 616, 617, 618, 619, 620, 621,
+ 622, 623, 624, 625, 626, 627, 628, 629,
+ 630, 631, 632, 633, 634, 635, 636, 637,
+ 0, 638, 639, 640, 641, 642, 643, 644,
+ 213, 645, 646, 647, 648, 649, 650, 651,
+ 652, 653, 654, 655, 656, 657, 658, 659,
+ 660, 661, 662, 663, 664, 665, 666, 667,
+ 668, 669, 670, 671, 213, 672, 673, 74,
+ 674, 675, 676, 677, 678, 213, 679, 680,
+ 681, 682, 683, 684, 685, 686, 687, 688,
+ 689, 690, 691, 692, 693, 694, 695, 696,
+ 697, 698, 699, 700, 701, 702, 703, 704,
+ 705, 706, 707, 708, 709, 710, 711, 712,
+ 713, 714, 715, 716, 717, 718, 719, 720,
+ 721, 722, 723, 724, 725, 726, 727, 728,
+ 729, 730, 731, 732, 733, 734, 735, 736,
+ 737, 738, 739, 740, 741, 742, 743, 744,
+ 745, 746, 747, 748, 749, 750, 751, 752,
+ 753, 754, 755, 756, 757, 758, 759, 760,
+ 761, 762, 763, 764, 765, 766, 767, 768,
+ 769, 770, 771, 772, 773, 774, 775, 776,
+ 777, 778, 779, 780, 781, 782, 783, 784,
+ 785, 786, 787, 788, 789, 790, 791, 792,
+ 793, 794, 795, 796, 797, 798, 799, 800,
+ 801, 802, 803, 804, 805, 806, 807, 808,
+ 809, 810, 811, 812, 524, 524, 524, 524,
+ 0, 813, 813, 814, 815, 816, 817, 818,
+ 819, 820, 821, 822, 823, 824, 825, 826,
+ 827, 828, 829, 830, 831, 832, 833, 834,
+ 835, 836, 837, 838, 839, 840, 841, 842,
+ 843, 844, 845, 846, 847, 848, 849, 850,
+ 851, 852, 853, 854, 855, 856, 857, 858,
+ 859, 860, 861, 862, 863, 864, 865, 866,
+ 867, 868, 869, 870, 871, 872, 873, 874,
+ 875, 876, 877, 878, 879, 880, 881, 882,
+ 883, 884, 885, 886, 887, 888, 889, 890,
+ 891, 892, 893, 894, 895, 896, 897, 898,
+ 899, 900, 901, 902, 903, 904, 905, 906,
+ 907, 908, 909, 910, 911, 912, 913, 914,
+ 915, 916, 917, 918, 919, 920, 921, 922,
+ 923, 924, 925, 926, 927, 928, 929, 930,
+ 931, 932, 933, 934, 935, 936, 937, 938,
+ 939, 940, 941, 942, 943, 944, 945, 946,
+ 947, 948, 949, 950, 951, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 952, 953, 954, 955, 956, 957,
+ 958, 959, 960, 961, 962, 963, 964, 965,
+ 966, 967, 968, 969, 970, 971, 972, 973,
+ 974, 975, 976, 977, 978, 979, 980, 981,
+ 982, 983, 984, 985, 986, 987, 988, 989,
+ 0, 0, 507, 990, 990, 990, 990, 990,
+ 990, 0, 991, 992, 993, 994, 995, 996,
+ 997, 998, 999, 1000, 1001, 1002, 1003, 1004,
+ 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012,
+ 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020,
+ 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028,
+ 1029, 0, 990, 1030, 0, 0, 0, 0,
+ 0, 0, 537, 524, 524, 524, 524, 537,
+ 524, 524, 524, 1031, 537, 524, 524, 524,
+ 524, 524, 524, 537, 537, 537, 537, 537,
+ 537, 524, 524, 537, 524, 524, 1031, 1032,
+ 524, 1033, 1034, 1035, 1036, 1037, 1038, 1039,
+ 1040, 1041, 1042, 1042, 1043, 1044, 1045, 1046,
+ 1047, 1046, 1048, 1049, 1046, 524, 537, 1046,
+ 1041, 0, 0, 0, 0, 0, 0, 0,
+ 0, 1050, 1050, 1050, 1050, 1050, 1050, 1050,
+ 1050, 1050, 1050, 1050, 1050, 1050, 1050, 1050,
+ 1050, 1050, 1050, 1050, 1050, 1050, 1050, 1050,
+ 1050, 1050, 1050, 1050, 0, 0, 0, 0,
+ 0, 1050, 1050, 1050, 1046, 1046, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 1051, 1051, 1051, 1051, 0, 0, 0,
+ 0, 0, 0, 0, 1052, 14, 1053, 76,
+ 76, 524, 524, 524, 524, 524, 524, 0,
+ 0, 0, 0, 0, 1053, 0, 0, 1053,
+ 1053, 0, 1054, 1055, 1056, 1057, 1058, 1059,
+ 1060, 1054, 1054, 1054, 1054, 1054, 1054, 1054,
+ 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054,
+ 1054, 1054, 1054, 1054, 0, 0, 0, 0,
+ 0, 1061, 1054, 1054, 1054, 1054, 1054, 1054,
+ 1054, 1062, 1054, 1063, 1064, 1065, 1066, 1067,
+ 1068, 1069, 1070, 1071, 1072, 1073, 1074, 537,
+ 524, 524, 524, 524, 524, 537, 524, 524,
+ 0, 1075, 1075, 1075, 1075, 1075, 1075, 1075,
+ 1075, 1075, 1075, 9, 1076, 1076, 1053, 1054,
+ 1054, 1077, 1054, 1054, 1054, 1054, 1078, 1079,
+ 1080, 1081, 1054, 1054, 1054, 1054, 1054, 1054,
+ 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054,
+ 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054,
+ 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054,
+ 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054,
+ 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054,
+ 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054,
+ 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054,
+ 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054,
+ 1054, 1082, 1083, 1084, 1054, 1054, 1054, 1054,
+ 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054,
+ 1054, 1054, 1054, 1085, 1086, 1053, 1087, 524,
+ 524, 524, 524, 524, 524, 524, 1051, 813,
+ 524, 524, 524, 524, 537, 524, 1061, 1061,
+ 524, 524, 76, 537, 524, 524, 537, 1054,
+ 1054, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 1054, 1054, 1054, 1088, 1088,
+ 1054, 1053, 1053, 1053, 1053, 1053, 1053, 1053,
+ 1053, 1053, 1053, 1053, 1053, 1053, 1053, 0,
+ 80, 1054, 1089, 1054, 1054, 1054, 1054, 1054,
+ 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054,
+ 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054,
+ 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054,
+ 1054, 524, 537, 524, 524, 537, 524, 524,
+ 537, 537, 537, 524, 537, 537, 524, 537,
+ 524, 524, 524, 537, 524, 537, 524, 537,
+ 524, 537, 524, 524, 0, 0, 1054, 1054,
+ 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054,
+ 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054,
+ 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054,
+ 1054, 1054, 1054, 1054, 1054, 1054, 1054, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 1054, 1054, 1054, 1054, 1054, 1054, 1054,
+ 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054,
+ 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054,
+ 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054,
+ 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1090,
+ 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090,
+ 1090, 1090, 1054, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 1091, 1091, 1091, 1091, 1091, 1091, 1091,
+ 1091, 1091, 1091, 1050, 1050, 1050, 1050, 1050,
+ 1050, 1050, 1050, 1050, 1050, 1050, 1050, 1050,
+ 1050, 1050, 1050, 1050, 1050, 1050, 1050, 1050,
+ 1050, 1050, 1050, 1050, 1050, 1050, 1050, 1050,
+ 1050, 1050, 1050, 1050, 524, 524, 524, 524,
+ 524, 524, 524, 537, 524, 1092, 1092, 76,
+ 8, 8, 8, 1092, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 1090, 1090, 1093, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 1094, 1095, 339, 339, 339, 339, 339,
+ 339, 1096, 1097, 339, 1098, 1099, 339, 339,
+ 339, 339, 339, 0, 0, 1100, 339, 1093,
+ 1093, 1093, 1090, 1090, 1090, 1090, 1090, 1090,
+ 1090, 1090, 1093, 1093, 1093, 1093, 1101, 0,
+ 0, 339, 524, 537, 524, 524, 0, 0,
+ 0, 1102, 1103, 1104, 1105, 1106, 1107, 1108,
+ 1109, 339, 339, 1090, 1090, 990, 990, 1110,
+ 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110,
+ 1110, 990, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 339, 339, 339, 339,
+ 339, 0, 1090, 1093, 1093, 0, 339, 339,
+ 339, 339, 339, 339, 339, 339, 0, 0,
+ 339, 339, 0, 0, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 0, 339, 339, 339, 339, 339,
+ 339, 339, 0, 339, 0, 0, 0, 339,
+ 339, 339, 339, 0, 0, 1111, 339, 1112,
+ 1093, 1093, 1090, 1090, 1090, 1090, 0, 0,
+ 1113, 1093, 0, 0, 1114, 1115, 1101, 339,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 1116, 0, 0, 0, 0, 1117, 1118, 0,
+ 1119, 339, 339, 1090, 1090, 0, 0, 1110,
+ 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110,
+ 1110, 339, 339, 10, 10, 1120, 1120, 1120,
+ 1120, 1120, 1120, 812, 0, 0, 0, 0,
+ 0, 0, 1090, 1090, 1093, 0, 339, 339,
+ 339, 339, 339, 339, 0, 0, 0, 0,
+ 339, 339, 0, 0, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 0, 339, 339, 339, 339, 339,
+ 339, 339, 0, 339, 1121, 0, 339, 1122,
+ 0, 339, 339, 0, 0, 1111, 0, 1093,
+ 1093, 1093, 1090, 1090, 0, 0, 0, 0,
+ 1090, 1090, 0, 0, 1090, 1090, 1101, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 1123, 1124, 1125, 339, 0, 1126,
+ 0, 0, 0, 0, 0, 0, 0, 1110,
+ 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110,
+ 1110, 1090, 1090, 339, 339, 339, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 1090, 1090, 1093, 0, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 0,
+ 339, 339, 339, 0, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 0, 339, 339, 339, 339, 339,
+ 339, 339, 0, 339, 339, 0, 339, 339,
+ 339, 339, 339, 0, 0, 1111, 339, 1093,
+ 1093, 1093, 1090, 1090, 1090, 1090, 1090, 0,
+ 1090, 1090, 1093, 0, 1093, 1093, 1101, 0,
+ 0, 339, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 339, 339, 1090, 1090, 0, 0, 1110,
+ 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110,
+ 1110, 0, 10, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 1090, 1093, 1093, 0, 339, 339,
+ 339, 339, 339, 339, 339, 339, 0, 0,
+ 339, 339, 0, 0, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 0, 339, 339, 339, 339, 339,
+ 339, 339, 0, 339, 339, 0, 339, 339,
+ 339, 339, 339, 0, 0, 1111, 339, 1127,
+ 1090, 1093, 1090, 1090, 1090, 0, 0, 0,
+ 1128, 1129, 0, 0, 1130, 1131, 1101, 0,
+ 0, 0, 0, 0, 0, 0, 0, 1132,
+ 1133, 0, 0, 0, 0, 1134, 1135, 0,
+ 339, 339, 339, 0, 0, 0, 0, 1110,
+ 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110,
+ 1110, 812, 339, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 1090, 339, 0, 339, 339,
+ 339, 339, 339, 339, 0, 0, 0, 339,
+ 339, 339, 0, 1136, 339, 1137, 339, 0,
+ 0, 0, 339, 339, 0, 339, 0, 339,
+ 339, 0, 0, 0, 339, 339, 0, 0,
+ 0, 339, 339, 339, 0, 0, 0, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 0, 0, 0, 0, 1138,
+ 1093, 1090, 1093, 1093, 0, 0, 0, 1139,
+ 1140, 1093, 0, 1141, 1142, 1143, 1101, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 1144, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 1110,
+ 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110,
+ 1110, 1120, 1120, 1120, 76, 76, 76, 76,
+ 76, 76, 10, 76, 0, 0, 0, 0,
+ 0, 0, 1093, 1093, 1093, 0, 339, 339,
+ 339, 339, 339, 339, 339, 339, 0, 339,
+ 339, 339, 0, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 0, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 0, 339, 339,
+ 339, 339, 339, 0, 0, 0, 0, 1090,
+ 1090, 1090, 1093, 1093, 1093, 1093, 0, 1145,
+ 1090, 1146, 0, 1090, 1090, 1090, 1101, 0,
+ 0, 0, 0, 0, 0, 0, 1147, 1148,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 339, 339, 0, 0, 0, 0, 1110,
+ 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110,
+ 1110, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 1093, 1093, 0, 339, 339,
+ 339, 339, 339, 339, 339, 339, 0, 339,
+ 339, 339, 0, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 0, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 0, 339, 339,
+ 339, 339, 339, 0, 0, 1111, 339, 1093,
+ 1149, 1150, 1093, 1151, 1093, 1093, 0, 1152,
+ 1153, 1154, 0, 1155, 1156, 1090, 1101, 0,
+ 0, 0, 0, 0, 0, 0, 1157, 1158,
+ 0, 0, 0, 0, 0, 0, 0, 339,
+ 0, 339, 339, 1090, 1090, 0, 0, 1110,
+ 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110,
+ 1110, 0, 76, 76, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 1093, 1093, 0, 339, 339,
+ 339, 339, 339, 339, 339, 339, 0, 339,
+ 339, 339, 0, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 0, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 0, 0, 0, 0, 1159,
+ 1093, 1093, 1090, 1090, 1090, 0, 0, 1160,
+ 1161, 1093, 0, 1162, 1163, 1164, 1101, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 1165, 0, 0, 0, 0, 0, 0, 0,
+ 0, 339, 339, 0, 0, 0, 0, 1110,
+ 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110,
+ 1110, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 1093, 1093, 0, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 0, 0, 0, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 0, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 0, 339, 0,
+ 0, 339, 339, 339, 339, 339, 339, 339,
+ 0, 0, 0, 1166, 0, 0, 0, 0,
+ 1167, 1093, 1093, 1090, 1090, 1090, 0, 1090,
+ 0, 1093, 1168, 1169, 1093, 1170, 1171, 1172,
+ 1173, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 1093, 1093, 990, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 1090, 339, 1174, 1090, 1090, 1090,
+ 1090, 1175, 1175, 1101, 0, 0, 0, 0,
+ 10, 339, 339, 339, 339, 339, 339, 507,
+ 1090, 1176, 1176, 1176, 1176, 1090, 1090, 1090,
+ 990, 1110, 1110, 1110, 1110, 1110, 1110, 1110,
+ 1110, 1110, 1110, 990, 990, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 339, 339, 0, 339, 0, 0,
+ 339, 339, 0, 339, 0, 0, 339, 0,
+ 0, 0, 0, 0, 0, 339, 339, 339,
+ 339, 0, 339, 339, 339, 339, 339, 339,
+ 339, 0, 339, 339, 339, 0, 339, 0,
+ 339, 0, 0, 339, 339, 0, 339, 339,
+ 339, 339, 1090, 339, 1177, 1090, 1090, 1090,
+ 1090, 1178, 1178, 0, 1090, 1090, 339, 0,
+ 0, 339, 339, 339, 339, 339, 0, 507,
+ 0, 1179, 1179, 1179, 1179, 1090, 1090, 0,
+ 0, 1110, 1110, 1110, 1110, 1110, 1110, 1110,
+ 1110, 1110, 1110, 0, 0, 1180, 1181, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 339, 812, 812, 812, 990, 990, 990,
+ 990, 990, 990, 990, 990, 1182, 990, 990,
+ 990, 990, 990, 990, 812, 812, 812, 812,
+ 812, 537, 537, 812, 812, 812, 812, 812,
+ 812, 1110, 1110, 1110, 1110, 1110, 1110, 1110,
+ 1110, 1110, 1110, 1120, 1120, 1120, 1120, 1120,
+ 1120, 1120, 1120, 1120, 1120, 812, 537, 812,
+ 537, 812, 1183, 11, 12, 11, 12, 1093,
+ 1093, 339, 339, 339, 1184, 339, 339, 339,
+ 339, 0, 339, 339, 339, 339, 1185, 339,
+ 339, 339, 339, 1186, 339, 339, 339, 339,
+ 1187, 339, 339, 339, 339, 1188, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 1189, 339, 0, 0, 0, 0,
+ 0, 0, 1190, 1191, 1192, 1193, 1194, 1195,
+ 1196, 1197, 1198, 1191, 1191, 1191, 1191, 1090,
+ 1093, 1191, 1199, 524, 524, 1101, 990, 524,
+ 524, 339, 339, 339, 339, 0, 0, 0,
+ 0, 1090, 1090, 1090, 1200, 1090, 1090, 1090,
+ 1090, 0, 1090, 1090, 1090, 1090, 1201, 1090,
+ 1090, 1090, 1090, 1202, 1090, 1090, 1090, 1090,
+ 1203, 1090, 1090, 1090, 1090, 1204, 1090, 1090,
+ 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1090,
+ 1090, 1090, 1205, 1090, 1090, 1090, 0, 812,
+ 812, 812, 812, 812, 812, 812, 812, 537,
+ 812, 812, 812, 812, 812, 812, 0, 0,
+ 812, 990, 990, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 0, 339, 339, 1206, 1207,
+ 339, 0, 339, 339, 0, 1093, 1090, 1208,
+ 1090, 1090, 1093, 1090, 0, 0, 0, 1090,
+ 1111, 1093, 1101, 0, 0, 0, 0, 0,
+ 0, 1110, 1110, 1110, 1110, 1110, 1110, 1110,
+ 1110, 1110, 1110, 990, 990, 990, 990, 990,
+ 990, 339, 339, 339, 339, 339, 339, 1093,
+ 1093, 1090, 1090, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 1209, 1210, 1211, 1212, 1213, 1214, 1215,
+ 1216, 1217, 1218, 1219, 1220, 1221, 1222, 1223,
+ 1224, 1225, 1226, 1227, 1228, 1229, 1230, 1231,
+ 1232, 1233, 1234, 1235, 1236, 1237, 1238, 1239,
+ 1240, 1241, 1242, 1243, 1244, 1245, 1246, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 990, 1247, 0, 0,
+ 0, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 0, 0, 0, 0, 0,
+ 1248, 1248, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 0, 0, 0, 0,
+ 0, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 0, 0, 0, 0, 0,
+ 0, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 0, 339, 339, 339, 339, 0,
+ 0, 339, 339, 339, 339, 339, 339, 339,
+ 0, 339, 0, 339, 339, 339, 339, 0,
+ 0, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 0, 339, 339, 339, 339, 0,
+ 0, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 0, 339, 339, 339, 339, 0,
+ 0, 339, 339, 339, 339, 339, 339, 339,
+ 0, 339, 0, 339, 339, 339, 339, 0,
+ 0, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 0, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 0, 339, 339, 339, 339, 0,
+ 0, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 0, 0, 0, 0,
+ 524, 812, 990, 990, 990, 990, 990, 990,
+ 990, 990, 1120, 1120, 1120, 1120, 1120, 1120,
+ 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120,
+ 1120, 1120, 1120, 1120, 1120, 1120, 0, 0,
+ 0, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 0, 0, 0, 0, 0,
+ 0, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 990, 990,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 7, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 11, 12, 0, 0,
+ 0, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 990, 990, 990, 1249,
+ 1249, 1249, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 0, 339,
+ 339, 339, 339, 1090, 1090, 1101, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 1090, 1090, 1101, 990, 990,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 1090, 1090, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 0, 339,
+ 339, 339, 0, 1090, 1090, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 1250, 1250, 1093,
+ 1090, 1090, 1090, 1090, 1090, 1090, 1090, 1093,
+ 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1090,
+ 1093, 1093, 1090, 1090, 1090, 1090, 1090, 1090,
+ 1090, 1090, 1090, 1101, 1090, 990, 990, 990,
+ 507, 990, 990, 990, 10, 339, 524, 0,
+ 0, 1110, 1110, 1110, 1110, 1110, 1110, 1110,
+ 1110, 1110, 1110, 0, 0, 0, 0, 0,
+ 0, 1251, 1251, 1251, 1251, 1251, 1251, 1251,
+ 1251, 1251, 1251, 0, 0, 0, 0, 0,
+ 0, 8, 8, 8, 8, 8, 8, 1030,
+ 8, 8, 8, 8, 558, 558, 558, 7,
+ 0, 1110, 1110, 1110, 1110, 1110, 1110, 1110,
+ 1110, 1110, 1110, 0, 0, 0, 0, 0,
+ 0, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 507, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 0, 0, 0, 0, 0, 0, 0,
+ 0, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 1032, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 0, 0,
+ 0, 1090, 1090, 1090, 1093, 1093, 1093, 1093,
+ 1090, 1090, 1252, 1252, 1252, 0, 0, 0,
+ 0, 1093, 1093, 1090, 1093, 1093, 1093, 1093,
+ 1093, 1093, 1031, 524, 537, 0, 0, 0,
+ 0, 76, 0, 0, 0, 8, 8, 1110,
+ 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110,
+ 1110, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 0,
+ 0, 339, 339, 339, 339, 339, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 0, 0, 0, 0, 0,
+ 0, 1093, 1093, 1093, 1093, 1093, 1093, 1093,
+ 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093,
+ 1093, 1093, 339, 339, 339, 339, 339, 339,
+ 339, 1093, 1093, 0, 0, 0, 0, 0,
+ 0, 1110, 1110, 1110, 1110, 1110, 1110, 1110,
+ 1110, 1110, 1110, 0, 0, 0, 0, 8,
+ 8, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 524, 537, 1093, 1093, 1093, 0, 0, 990,
+ 990, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 1090, 1090, 1090, 1090, 1093, 1253, 1254,
+ 1255, 1256, 1257, 1258, 1259, 1260, 1261, 1262,
+ 339, 339, 1263, 1264, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 1111, 1265, 1090,
+ 1090, 1090, 1090, 1266, 1267, 1268, 1269, 1270,
+ 1271, 1272, 1273, 1274, 1275, 1276, 339, 339,
+ 339, 339, 339, 339, 339, 0, 0, 0,
+ 0, 1110, 1110, 1110, 1110, 1110, 1110, 1110,
+ 1110, 1110, 1110, 990, 990, 990, 990, 990,
+ 990, 990, 812, 812, 812, 812, 812, 812,
+ 812, 812, 812, 812, 524, 537, 524, 524,
+ 524, 524, 524, 524, 524, 812, 812, 812,
+ 812, 812, 812, 812, 812, 812, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 213, 213, 213, 213, 213, 213, 213,
+ 213, 213, 213, 213, 213, 213, 213, 213,
+ 213, 213, 213, 213, 213, 213, 213, 213,
+ 213, 213, 213, 213, 213, 213, 213, 213,
+ 213, 213, 213, 213, 213, 213, 213, 213,
+ 213, 213, 213, 213, 213, 1277, 1278, 1279,
+ 507, 1280, 1281, 1282, 1283, 1284, 1285, 1286,
+ 1287, 1288, 1289, 1290, 507, 1291, 1292, 1293,
+ 1294, 1295, 1296, 1297, 1298, 1299, 1300, 1301,
+ 1302, 1303, 1304, 1305, 1306, 1307, 1308, 507,
+ 1309, 1310, 1311, 1312, 1313, 1314, 1315, 1316,
+ 1317, 1318, 1319, 1320, 1321, 1322, 1323, 1324,
+ 1325, 1326, 1327, 1328, 1329, 1330, 1331, 1332,
+ 1333, 1334, 1335, 1336, 213, 213, 213, 213,
+ 213, 213, 213, 213, 213, 213, 213, 213,
+ 213, 1337, 213, 213, 213, 213, 1338, 213,
+ 213, 213, 213, 213, 213, 213, 213, 213,
+ 213, 213, 213, 213, 213, 213, 213, 213,
+ 213, 213, 213, 213, 213, 213, 213, 213,
+ 213, 213, 213, 213, 1339, 1340, 1341, 1342,
+ 1307, 1343, 1344, 1345, 1346, 1347, 1348, 1349,
+ 1350, 1351, 1352, 1353, 1354, 1355, 1356, 1357,
+ 1358, 1359, 1360, 1361, 1362, 1363, 1364, 1365,
+ 1366, 1367, 1368, 1369, 1370, 1371, 1372, 1373,
+ 1374, 524, 524, 537, 524, 524, 524, 524,
+ 524, 524, 524, 537, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 524,
+ 537, 1375, 1376, 1377, 1378, 1379, 1380, 1381,
+ 1382, 1383, 1384, 1385, 1386, 1387, 1388, 1389,
+ 1390, 1391, 1392, 1393, 1394, 1395, 1396, 1397,
+ 1398, 1399, 1400, 1401, 1402, 1403, 1404, 1405,
+ 1406, 1407, 1408, 1409, 1410, 1411, 1412, 1413,
+ 1414, 1415, 1416, 1417, 1418, 1419, 1420, 1421,
+ 1422, 1423, 1424, 1425, 1426, 1427, 1428, 1429,
+ 1430, 1431, 1432, 1433, 1434, 1435, 1436, 1437,
+ 1438, 1439, 1440, 1441, 1442, 1443, 1444, 1445,
+ 1446, 1447, 1448, 1449, 1450, 1451, 1452, 1453,
+ 1454, 1455, 1456, 1457, 1458, 1459, 1460, 1461,
+ 1462, 1463, 1464, 1465, 1466, 1467, 1468, 1469,
+ 1470, 1471, 1472, 1473, 1474, 1475, 1476, 1477,
+ 1478, 1479, 1480, 1481, 1482, 1483, 1484, 1485,
+ 1486, 1487, 1488, 1489, 1490, 1491, 1492, 1493,
+ 1494, 1495, 1496, 1497, 1498, 1499, 1500, 1501,
+ 1502, 1503, 1504, 1505, 1506, 1507, 1508, 1509,
+ 1510, 1511, 1512, 1513, 1514, 1515, 1516, 1517,
+ 1518, 1519, 1520, 1521, 1522, 1523, 1524, 1525,
+ 1526, 1527, 1528, 1529, 1530, 0, 0, 0,
+ 0, 1531, 1532, 1533, 1534, 1535, 1536, 1537,
+ 1538, 1539, 1540, 1541, 1542, 1543, 1544, 1545,
+ 1546, 1547, 1548, 1549, 1550, 1551, 1552, 1553,
+ 1554, 1555, 1556, 1557, 1558, 1559, 1560, 1561,
+ 1562, 1563, 1564, 1565, 1566, 1567, 1568, 1569,
+ 1570, 1571, 1572, 1573, 1574, 1575, 1576, 1577,
+ 1578, 1579, 1580, 1581, 1582, 1583, 1584, 1585,
+ 1586, 1587, 1588, 1589, 1590, 1591, 1592, 1593,
+ 1594, 1595, 1596, 1597, 1598, 1599, 1600, 1601,
+ 1602, 1603, 1604, 1605, 1606, 1607, 1608, 1609,
+ 1610, 1611, 1612, 1613, 1614, 1615, 1616, 1617,
+ 1618, 1619, 1620, 0, 0, 0, 0, 0,
+ 0, 1621, 1622, 1623, 1624, 1625, 1626, 1627,
+ 1628, 1629, 1630, 1631, 1632, 1633, 1634, 1635,
+ 1636, 1637, 1638, 1639, 1640, 1641, 1642, 0,
+ 0, 1643, 1644, 1645, 1646, 1647, 1648, 0,
+ 0, 1649, 1650, 1651, 1652, 1653, 1654, 1655,
+ 1656, 1657, 1658, 1659, 1660, 1661, 1662, 1663,
+ 1664, 1665, 1666, 1667, 1668, 1669, 1670, 1671,
+ 1672, 1673, 1674, 1675, 1676, 1677, 1678, 1679,
+ 1680, 1681, 1682, 1683, 1684, 1685, 1686, 0,
+ 0, 1687, 1688, 1689, 1690, 1691, 1692, 0,
+ 0, 1693, 1694, 1695, 1696, 1697, 1698, 1699,
+ 1700, 0, 1701, 0, 1702, 0, 1703, 0,
+ 1704, 1705, 1706, 1707, 1708, 1709, 1710, 1711,
+ 1712, 1713, 1714, 1715, 1716, 1717, 1718, 1719,
+ 1720, 1721, 1722, 1723, 1724, 1725, 1726, 1727,
+ 1728, 1729, 1730, 1731, 1732, 1733, 1734, 0,
+ 0, 1735, 1736, 1737, 1738, 1739, 1740, 1741,
+ 1742, 1743, 1744, 1745, 1746, 1747, 1748, 1749,
+ 1750, 1751, 1752, 1753, 1754, 1755, 1756, 1757,
+ 1758, 1759, 1760, 1761, 1762, 1763, 1764, 1765,
+ 1766, 1767, 1768, 1769, 1770, 1771, 1772, 1773,
+ 1774, 1775, 1776, 1777, 1778, 1779, 1780, 1781,
+ 1782, 1783, 1784, 1785, 1786, 1787, 0, 1788,
+ 1789, 1790, 1791, 1792, 1793, 1794, 1795, 1796,
+ 1797, 1798, 1799, 1800, 1801, 1802, 0, 1803,
+ 1804, 1805, 1806, 1807, 1808, 1809, 1810, 1811,
+ 1812, 1813, 1814, 1815, 1816, 0, 0, 1817,
+ 1818, 1819, 1820, 1821, 1822, 0, 1823, 1824,
+ 1825, 1826, 1827, 1828, 1829, 1830, 1831, 1832,
+ 1833, 1834, 1835, 1836, 1837, 1838, 1839, 1840,
+ 1841, 0, 0, 1842, 1843, 1844, 0, 1845,
+ 1846, 1847, 1848, 1849, 1850, 1851, 1852, 1853,
+ 0, 1854, 1855, 1856, 1856, 1856, 1856, 1856,
+ 1857, 1856, 1856, 1856, 80, 1858, 1858, 1250,
+ 1859, 1030, 1860, 1030, 1030, 1030, 1030, 8,
+ 1861, 79, 91, 11, 79, 79, 91, 11,
+ 79, 8, 8, 8, 8, 1862, 1863, 1864,
+ 8, 1865, 1866, 1867, 1868, 1869, 1870, 1871,
+ 75, 9, 9, 9, 1872, 1873, 8, 1874,
+ 1875, 8, 79, 91, 8, 1876, 8, 1877,
+ 47, 47, 8, 8, 8, 1878, 11, 12,
+ 1879, 1880, 1881, 8, 8, 8, 8, 8,
+ 8, 8, 8, 74, 8, 47, 8, 8,
+ 1882, 8, 8, 8, 8, 8, 8, 8,
+ 1856, 80, 80, 80, 80, 0, 0, 0,
+ 0, 0, 0, 80, 80, 80, 80, 80,
+ 80, 1883, 1884, 0, 0, 1885, 1886, 1887,
+ 1888, 1889, 1890, 1891, 1892, 1893, 1894, 1895,
+ 1896, 1897, 1898, 1899, 1900, 1901, 1902, 1903,
+ 1904, 1905, 1906, 1907, 1908, 1909, 1910, 1911,
+ 0, 1912, 1913, 1914, 1915, 1916, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 10, 10, 10, 10, 10, 10, 10,
+ 10, 1917, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 524, 524, 550, 550, 524, 524, 524,
+ 524, 550, 550, 550, 524, 524, 813, 813,
+ 813, 813, 524, 813, 813, 813, 550, 550,
+ 524, 537, 524, 550, 550, 537, 537, 537,
+ 537, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 1918, 1919, 1920, 1921, 76, 1922, 1923,
+ 1924, 76, 1925, 1926, 1927, 1927, 1927, 1928,
+ 1929, 1930, 1930, 1931, 1932, 76, 1933, 1934,
+ 76, 76, 1935, 1936, 1937, 1937, 1937, 76,
+ 76, 1938, 1939, 1940, 76, 1941, 76, 1942,
+ 76, 1941, 76, 1943, 1944, 1945, 1920, 82,
+ 1946, 1947, 1948, 1949, 1950, 1951, 1952, 1953,
+ 1954, 1955, 1956, 76, 1957, 1958, 1959, 1960,
+ 1961, 1962, 74, 74, 74, 74, 1963, 1964,
+ 1946, 1956, 1965, 76, 74, 76, 76, 1966,
+ 0, 0, 0, 0, 1967, 1968, 1969, 1970,
+ 1971, 1972, 1973, 1974, 1975, 1976, 1977, 1978,
+ 1979, 1980, 1981, 1982, 1983, 1984, 1985, 1986,
+ 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
+ 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+ 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
+ 2011, 1249, 1249, 1249, 2012, 2013, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 2014, 74, 2015, 74, 2016, 76, 76,
+ 76, 76, 76, 2017, 2018, 76, 76, 76,
+ 76, 74, 76, 76, 74, 76, 76, 74,
+ 76, 76, 76, 76, 76, 76, 76, 2019,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 2020, 2021,
+ 2022, 2023, 76, 2024, 76, 2025, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 74, 74, 74,
+ 74, 74, 74, 74, 74, 74, 74, 74,
+ 74, 74, 2026, 2026, 2027, 2028, 74, 74,
+ 74, 2029, 2030, 2026, 2031, 2032, 2026, 74,
+ 74, 74, 2026, 13, 83, 74, 2026, 2026,
+ 74, 74, 74, 2026, 2026, 2026, 2026, 74,
+ 2026, 2026, 2026, 2026, 2033, 2034, 2035, 2036,
+ 74, 74, 74, 74, 2026, 2037, 2038, 2026,
+ 2039, 2040, 2026, 2026, 2026, 74, 74, 74,
+ 74, 74, 2026, 74, 2026, 2041, 2026, 2026,
+ 2026, 2026, 2042, 2026, 2043, 2044, 2045, 2026,
+ 2046, 2047, 2048, 2026, 2026, 2026, 2049, 74,
+ 74, 74, 74, 2026, 2026, 2026, 2026, 74,
+ 74, 74, 74, 74, 74, 74, 74, 74,
+ 2026, 2050, 2051, 2052, 74, 2053, 2054, 2026,
+ 2026, 2026, 2026, 2026, 2026, 74, 2055, 2056,
+ 2057, 2058, 2059, 2060, 2061, 2062, 2063, 2064,
+ 2065, 2066, 2067, 2068, 2069, 2070, 2071, 2026,
+ 2026, 2072, 2073, 2074, 2075, 2076, 2077, 2078,
+ 2079, 2080, 2081, 2026, 2026, 2026, 74, 74,
+ 2026, 2026, 2082, 2083, 74, 74, 74, 74,
+ 74, 2026, 74, 74, 74, 74, 74, 74,
+ 74, 74, 74, 2084, 2026, 74, 74, 2026,
+ 2026, 2085, 2086, 2026, 2087, 2088, 2089, 2090,
+ 2091, 2026, 2026, 2092, 2093, 2094, 2095, 2026,
+ 2026, 2026, 74, 74, 74, 74, 74, 2026,
+ 2026, 74, 74, 74, 74, 74, 74, 74,
+ 74, 74, 2026, 2026, 2026, 2026, 2026, 74,
+ 74, 2026, 2026, 74, 74, 74, 74, 2026,
+ 2026, 2026, 2026, 2026, 2026, 2026, 2026, 2026,
+ 2026, 2096, 2097, 2098, 2099, 2026, 2026, 2026,
+ 2026, 2026, 2026, 2100, 2101, 2102, 2103, 74,
+ 74, 2026, 2026, 2026, 2026, 2026, 2026, 2026,
+ 2026, 2026, 2026, 2026, 2026, 2026, 2026, 2026,
+ 2026, 76, 76, 76, 76, 76, 76, 76,
+ 76, 2026, 2026, 2026, 2026, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 2026, 2026, 76, 76, 76, 76, 76,
+ 76, 76, 2104, 2105, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 812,
+ 812, 812, 812, 812, 812, 812, 812, 812,
+ 812, 812, 812, 812, 812, 812, 812, 812,
+ 812, 812, 812, 812, 812, 812, 812, 812,
+ 812, 812, 812, 812, 812, 812, 812, 812,
+ 812, 812, 812, 812, 812, 812, 812, 812,
+ 812, 812, 812, 812, 812, 812, 812, 812,
+ 812, 812, 812, 812, 812, 812, 812, 812,
+ 812, 812, 812, 812, 812, 812, 812, 812,
+ 812, 812, 812, 812, 76, 74, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 812, 76,
+ 76, 76, 76, 76, 74, 74, 74, 74,
+ 74, 74, 74, 74, 74, 74, 74, 74,
+ 74, 74, 74, 74, 74, 74, 74, 74,
+ 74, 74, 74, 74, 74, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 74, 74, 74,
+ 74, 74, 74, 76, 76, 76, 76, 76,
+ 76, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 2106, 2107, 2108, 2109, 2110, 2111, 2112,
+ 2113, 2114, 2115, 2116, 2117, 2118, 2119, 2120,
+ 2121, 2122, 2123, 2124, 2125, 2126, 2127, 2128,
+ 2129, 2130, 2131, 2132, 2133, 2134, 2135, 2136,
+ 2137, 2138, 2139, 2140, 2141, 2142, 2143, 2144,
+ 2145, 2146, 2147, 2148, 2149, 2150, 2151, 2152,
+ 2153, 2154, 2155, 2156, 2157, 2158, 2159, 2160,
+ 2161, 2162, 2163, 2164, 2165, 2166, 2167, 2168,
+ 2169, 2170, 2171, 2172, 2173, 2174, 2175, 2176,
+ 2177, 2178, 2179, 2180, 2181, 2182, 2183, 2184,
+ 2185, 2186, 2187, 2188, 2189, 2190, 2191, 2192,
+ 2193, 2194, 2195, 2196, 2197, 2198, 2199, 2200,
+ 2201, 2202, 2203, 2204, 2205, 2206, 2207, 2208,
+ 2209, 2210, 2211, 2212, 2213, 2214, 2215, 2216,
+ 2217, 2218, 2219, 2220, 2221, 2222, 2223, 2224,
+ 2225, 2226, 2227, 2228, 2229, 2230, 2231, 2232,
+ 2233, 2234, 2235, 2236, 2237, 2238, 2239, 2240,
+ 2241, 2242, 2243, 2244, 1251, 1251, 1251, 1251,
+ 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251,
+ 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251,
+ 1251, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 74, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 74, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 74, 74, 74, 74, 74, 74, 74,
+ 74, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 74, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 0, 0,
+ 0, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 812, 76, 76,
+ 76, 76, 76, 76, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 76, 76, 76, 76, 0, 76,
+ 76, 76, 76, 0, 0, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 0, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 0, 76, 0,
+ 76, 76, 76, 76, 0, 0, 0, 76,
+ 0, 76, 76, 76, 76, 76, 76, 76,
+ 0, 0, 76, 76, 76, 76, 76, 76,
+ 76, 11, 12, 11, 12, 11, 12, 11,
+ 12, 11, 12, 11, 12, 11, 12, 1251,
+ 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251,
+ 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251,
+ 1251, 1251, 1251, 1251, 1251, 1251, 1251, 1251,
+ 1251, 1251, 1251, 1251, 1251, 76, 0, 0,
+ 0, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 0, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 0, 2026, 74, 74, 2026, 2026, 11, 12,
+ 74, 74, 74, 74, 0, 0, 0, 0,
+ 0, 74, 74, 74, 2026, 2026, 2026, 2026,
+ 74, 74, 74, 74, 74, 2026, 2026, 2026,
+ 74, 74, 74, 2026, 2026, 2026, 2026, 11,
+ 12, 11, 12, 11, 12, 0, 0, 0,
+ 0, 74, 74, 74, 74, 74, 74, 74,
+ 74, 74, 74, 74, 74, 74, 74, 74,
+ 74, 812, 812, 812, 812, 812, 812, 812,
+ 812, 812, 812, 812, 812, 812, 812, 812,
+ 812, 812, 812, 812, 812, 812, 812, 812,
+ 812, 812, 812, 812, 812, 812, 812, 812,
+ 812, 812, 812, 812, 812, 812, 812, 812,
+ 812, 812, 812, 812, 812, 812, 812, 812,
+ 812, 812, 812, 812, 812, 812, 812, 812,
+ 812, 812, 812, 812, 812, 812, 812, 812,
+ 812, 812, 812, 812, 812, 812, 812, 812,
+ 812, 812, 812, 812, 812, 812, 812, 812,
+ 812, 812, 812, 812, 812, 812, 812, 812,
+ 812, 812, 812, 812, 812, 812, 812, 812,
+ 812, 812, 812, 812, 812, 812, 812, 812,
+ 812, 812, 812, 812, 812, 812, 812, 812,
+ 812, 812, 812, 812, 812, 812, 812, 812,
+ 812, 812, 812, 812, 812, 812, 812, 812,
+ 812, 812, 812, 812, 812, 812, 812, 812,
+ 812, 812, 812, 812, 812, 812, 812, 812,
+ 812, 812, 812, 812, 812, 812, 812, 812,
+ 812, 812, 812, 812, 812, 812, 812, 812,
+ 812, 812, 812, 812, 812, 812, 812, 812,
+ 812, 812, 812, 812, 812, 812, 812, 812,
+ 812, 812, 812, 812, 812, 812, 812, 812,
+ 812, 812, 812, 812, 812, 812, 812, 812,
+ 812, 812, 812, 812, 812, 812, 812, 812,
+ 812, 812, 812, 812, 812, 812, 812, 812,
+ 812, 812, 812, 812, 812, 812, 812, 812,
+ 812, 812, 812, 812, 812, 812, 812, 812,
+ 812, 812, 812, 812, 812, 812, 812, 812,
+ 812, 812, 812, 812, 812, 812, 812, 812,
+ 812, 812, 812, 812, 812, 812, 812, 812,
+ 812, 812, 812, 812, 812, 812, 812, 812,
+ 812, 74, 74, 74, 74, 74, 74, 74,
+ 74, 74, 74, 74, 74, 74, 74, 74,
+ 74, 74, 74, 74, 74, 74, 74, 74,
+ 74, 74, 74, 74, 74, 74, 74, 74,
+ 74, 74, 74, 74, 74, 74, 74, 74,
+ 74, 74, 74, 74, 74, 74, 74, 74,
+ 74, 74, 74, 74, 74, 74, 74, 74,
+ 74, 74, 74, 74, 74, 74, 74, 74,
+ 74, 74, 74, 74, 74, 74, 74, 74,
+ 74, 74, 74, 74, 74, 74, 74, 74,
+ 74, 74, 74, 74, 74, 74, 74, 74,
+ 74, 74, 74, 74, 74, 74, 74, 74,
+ 74, 74, 74, 74, 74, 74, 74, 74,
+ 74, 74, 74, 74, 74, 74, 74, 74,
+ 74, 74, 74, 74, 74, 74, 74, 74,
+ 74, 74, 74, 74, 74, 74, 74, 74,
+ 74, 74, 74, 74, 11, 12, 11, 12,
+ 11, 12, 11, 12, 11, 12, 11, 12,
+ 11, 12, 11, 12, 11, 12, 11, 12,
+ 11, 12, 74, 74, 2026, 2026, 2026, 2026,
+ 2026, 2026, 2026, 2026, 2026, 2026, 2026, 2026,
+ 2026, 2026, 2026, 2026, 2026, 2026, 2026, 2026,
+ 2026, 74, 74, 74, 74, 74, 74, 74,
+ 74, 2026, 74, 74, 74, 74, 74, 74,
+ 74, 2026, 2026, 2026, 2026, 2026, 2026, 74,
+ 74, 74, 2026, 74, 74, 74, 74, 2026,
+ 2026, 2026, 2026, 2026, 74, 2026, 2026, 74,
+ 74, 11, 12, 11, 12, 2026, 74, 74,
+ 74, 74, 2026, 74, 2026, 2026, 2026, 74,
+ 74, 2026, 2026, 74, 74, 74, 74, 74,
+ 74, 74, 74, 74, 74, 2026, 2026, 2026,
+ 2026, 2026, 2026, 74, 74, 11, 12, 74,
+ 74, 74, 74, 74, 74, 74, 74, 74,
+ 74, 74, 74, 2026, 2026, 2245, 2026, 2026,
+ 2026, 2026, 2026, 2026, 2026, 2026, 2026, 2026,
+ 2026, 2026, 2026, 2026, 2026, 2026, 74, 2026,
+ 2026, 2026, 2026, 74, 74, 2026, 74, 2026,
+ 74, 74, 2026, 74, 2026, 2026, 2026, 2026,
+ 74, 74, 74, 74, 74, 2026, 2026, 74,
+ 74, 74, 74, 74, 74, 2026, 2026, 2026,
+ 74, 74, 74, 74, 74, 74, 74, 74,
+ 74, 74, 74, 74, 74, 74, 74, 74,
+ 74, 74, 74, 74, 74, 74, 74, 74,
+ 2026, 2026, 74, 74, 74, 74, 74, 74,
+ 74, 74, 74, 74, 74, 2026, 2026, 74,
+ 74, 74, 74, 2026, 2026, 2026, 2026, 74,
+ 2026, 2026, 74, 74, 2026, 2246, 2247, 2248,
+ 74, 74, 2026, 2026, 2026, 2026, 2026, 2026,
+ 2026, 2026, 2026, 2026, 2026, 2026, 2026, 2026,
+ 2026, 2026, 2026, 2026, 2026, 2026, 2026, 2026,
+ 2026, 2026, 2026, 2026, 2026, 2026, 2026, 2026,
+ 2026, 2026, 2026, 2026, 2026, 2026, 2026, 2026,
+ 2026, 2026, 2026, 2026, 2026, 74, 74, 2026,
+ 2026, 2026, 2026, 2026, 2026, 2026, 2026, 74,
+ 2026, 2026, 2026, 2026, 2026, 2026, 2026, 2026,
+ 2026, 2026, 2026, 2026, 2026, 2026, 2026, 2026,
+ 2026, 2026, 2026, 2026, 2026, 2026, 2026, 2026,
+ 2026, 2026, 2026, 2026, 2026, 2026, 2026, 2026,
+ 2026, 2026, 2026, 2026, 2026, 2026, 2026, 2026,
+ 74, 74, 74, 74, 74, 2249, 2250, 2026,
+ 74, 74, 74, 2026, 2026, 2026, 2026, 2026,
+ 74, 74, 74, 74, 74, 2026, 2026, 2026,
+ 74, 74, 74, 74, 2026, 74, 74, 74,
+ 2026, 2026, 2026, 2026, 2026, 74, 2026, 74,
+ 74, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 0, 0, 0, 0,
+ 0, 76, 76, 76, 76, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 2251, 2252, 2253, 2254, 2255, 2256, 2257,
+ 2258, 2259, 2260, 2261, 2262, 2263, 2264, 2265,
+ 2266, 2267, 2268, 2269, 2270, 2271, 2272, 2273,
+ 2274, 2275, 2276, 2277, 2278, 2279, 2280, 2281,
+ 2282, 2283, 2284, 2285, 2286, 2287, 2288, 2289,
+ 2290, 2291, 2292, 2293, 2294, 2295, 2296, 2297,
+ 0, 2298, 2299, 2300, 2301, 2302, 2303, 2304,
+ 2305, 2306, 2307, 2308, 2309, 2310, 2311, 2312,
+ 2313, 2314, 2315, 2316, 2317, 2318, 2319, 2320,
+ 2321, 2322, 2323, 2324, 2325, 2326, 2327, 2328,
+ 2329, 2330, 2331, 2332, 2333, 2334, 2335, 2336,
+ 2337, 2338, 2339, 2340, 2341, 2342, 2343, 2344,
+ 0, 2345, 2346, 2347, 2348, 2349, 2350, 2351,
+ 2352, 2353, 2354, 2355, 2356, 2357, 0, 0,
+ 0, 0, 0, 0, 0, 213, 2358, 2359,
+ 213, 0, 0, 0, 0, 0, 0, 0,
+ 0, 2360, 2361, 2362, 2363, 2364, 2365, 2366,
+ 2367, 2368, 2369, 2370, 2371, 2372, 2373, 2374,
+ 2375, 2376, 2377, 2378, 2379, 2380, 2381, 2382,
+ 2383, 2384, 2385, 2386, 2387, 2388, 2389, 2390,
+ 2391, 2392, 2393, 2394, 2395, 2396, 2397, 2398,
+ 2399, 2400, 2401, 2402, 2403, 2404, 2405, 2406,
+ 2407, 2408, 2409, 2410, 2411, 2412, 2413, 2414,
+ 2415, 2416, 2417, 2418, 2419, 2420, 2421, 2422,
+ 2423, 2424, 2425, 2426, 2427, 2428, 2429, 2430,
+ 2431, 2432, 2433, 2434, 2435, 2436, 2437, 2438,
+ 2439, 2440, 2441, 2442, 2443, 2444, 2445, 2446,
+ 2447, 2448, 2449, 2450, 2451, 2452, 2453, 2454,
+ 2455, 2456, 2457, 2458, 2459, 213, 76, 76,
+ 76, 76, 76, 76, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 8, 8, 8, 8, 1251, 8,
+ 8, 2460, 2461, 2462, 2463, 2464, 2465, 2466,
+ 2467, 2468, 2469, 2470, 2471, 2472, 2473, 2474,
+ 2475, 2476, 2477, 2478, 2479, 2480, 2481, 2482,
+ 2483, 2484, 2485, 2486, 2487, 2488, 2489, 2490,
+ 2491, 2492, 2493, 2494, 2495, 2496, 2497, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 2498, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 339, 339, 339, 339, 339, 339, 339,
+ 0, 339, 339, 339, 339, 339, 339, 339,
+ 0, 339, 339, 339, 339, 339, 339, 339,
+ 0, 339, 339, 339, 339, 339, 339, 339,
+ 0, 339, 339, 339, 339, 339, 339, 339,
+ 0, 339, 339, 339, 339, 339, 339, 339,
+ 0, 339, 339, 339, 339, 339, 339, 339,
+ 0, 339, 339, 339, 339, 339, 339, 339,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 8, 8, 79, 91, 79, 91, 8,
+ 8, 8, 79, 91, 8, 79, 91, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8,
+ 1030, 0, 0, 0, 0, 79, 91, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 0, 76, 76, 76, 76,
+ 2499, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 2500, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 2501, 2502, 2503, 2504, 2505, 2506, 2507,
+ 2508, 2509, 2510, 2511, 2512, 2513, 2514, 2515,
+ 2516, 2517, 2518, 2519, 2520, 2521, 2522, 2523,
+ 2524, 2525, 2526, 2527, 2528, 2529, 2530, 2531,
+ 2532, 2533, 2534, 2535, 2536, 2537, 2538, 2539,
+ 2540, 2541, 2542, 2543, 2544, 2545, 2546, 2547,
+ 2548, 2549, 2550, 2551, 2552, 2553, 2554, 2555,
+ 2556, 2557, 2558, 2559, 2560, 2561, 2562, 2563,
+ 2564, 2565, 2566, 2567, 2568, 2569, 2570, 2571,
+ 2572, 2573, 2574, 2575, 2576, 2577, 2578, 2579,
+ 2580, 2581, 2582, 2583, 2584, 2585, 2586, 2587,
+ 2588, 2589, 2590, 2591, 2592, 2593, 2594, 2595,
+ 2596, 2597, 2598, 2599, 2600, 2601, 2602, 2603,
+ 2604, 2605, 2606, 2607, 2608, 2609, 2610, 2611,
+ 2612, 2613, 2614, 2615, 2616, 2617, 2618, 2619,
+ 2620, 2621, 2622, 2623, 2624, 2625, 2626, 2627,
+ 2628, 2629, 2630, 2631, 2632, 2633, 2634, 2635,
+ 2636, 2637, 2638, 2639, 2640, 2641, 2642, 2643,
+ 2644, 2645, 2646, 2647, 2648, 2649, 2650, 2651,
+ 2652, 2653, 2654, 2655, 2656, 2657, 2658, 2659,
+ 2660, 2661, 2662, 2663, 2664, 2665, 2666, 2667,
+ 2668, 2669, 2670, 2671, 2672, 2673, 2674, 2675,
+ 2676, 2677, 2678, 2679, 2680, 2681, 2682, 2683,
+ 2684, 2685, 2686, 2687, 2688, 2689, 2690, 2691,
+ 2692, 2693, 2694, 2695, 2696, 2697, 2698, 2699,
+ 2700, 2701, 2702, 2703, 2704, 2705, 2706, 2707,
+ 2708, 2709, 2710, 2711, 2712, 2713, 2714, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 0, 0, 0,
+ 0, 2715, 8, 8, 8, 76, 507, 339,
+ 1249, 11, 12, 11, 12, 11, 12, 11,
+ 12, 11, 12, 76, 76, 11, 12, 11,
+ 12, 11, 12, 11, 12, 1030, 11, 12,
+ 12, 76, 1249, 1249, 1249, 1249, 1249, 1249,
+ 1249, 1249, 1249, 2716, 1032, 536, 1031, 2717,
+ 2717, 1030, 507, 507, 507, 507, 507, 2718,
+ 76, 2719, 2720, 2721, 507, 339, 8, 76,
+ 76, 0, 339, 339, 339, 339, 339, 2722,
+ 339, 339, 339, 339, 2723, 2724, 2725, 2726,
+ 2727, 2728, 2729, 2730, 2731, 2732, 2733, 2734,
+ 2735, 2736, 2737, 2738, 2739, 2740, 2741, 2742,
+ 2743, 2744, 2745, 2746, 339, 2747, 2748, 2749,
+ 2750, 2751, 2752, 339, 339, 339, 339, 339,
+ 2753, 2754, 2755, 2756, 2757, 2758, 2759, 2760,
+ 2761, 2762, 2763, 2764, 2765, 2766, 2767, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 2768, 339, 339,
+ 0, 0, 2769, 2770, 2771, 2772, 2773, 2774,
+ 2775, 1030, 339, 339, 339, 339, 339, 2776,
+ 339, 339, 339, 339, 2777, 2778, 2779, 2780,
+ 2781, 2782, 2783, 2784, 2785, 2786, 2787, 2788,
+ 2789, 2790, 2791, 2792, 2793, 2794, 2795, 2796,
+ 2797, 2798, 2799, 2800, 339, 2801, 2802, 2803,
+ 2804, 2805, 2806, 339, 339, 339, 339, 339,
+ 2807, 2808, 2809, 2810, 2811, 2812, 2813, 2814,
+ 2815, 2816, 2817, 2818, 2819, 2820, 2821, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 2822, 2823, 2824, 2825, 339, 2826, 339, 339,
+ 2827, 2828, 2829, 2830, 8, 507, 2831, 2832,
+ 2833, 0, 0, 0, 0, 0, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 0, 0,
+ 0, 0, 2834, 2835, 2836, 2837, 2838, 2839,
+ 2840, 2841, 2842, 2843, 2844, 2845, 2846, 2847,
+ 2848, 2849, 2850, 2851, 2852, 2853, 2854, 2855,
+ 2856, 2857, 2858, 2859, 2860, 2861, 2862, 2863,
+ 2864, 2865, 2866, 2867, 2868, 2869, 2870, 2871,
+ 2872, 2873, 2874, 2875, 2876, 2877, 2878, 2879,
+ 2880, 2881, 2882, 2883, 2884, 2885, 2886, 2887,
+ 2888, 2889, 2890, 2891, 2892, 2893, 2894, 2895,
+ 2896, 2897, 2898, 2899, 2900, 2901, 2902, 2903,
+ 2904, 2905, 2906, 2907, 2908, 2909, 2910, 2911,
+ 2912, 2913, 2914, 2915, 2916, 2917, 2918, 2919,
+ 2920, 2921, 2922, 2923, 2924, 2925, 2926, 2927,
+ 0, 812, 812, 2928, 2929, 2930, 2931, 2932,
+ 2933, 2934, 2935, 2936, 2937, 2938, 2939, 2940,
+ 2941, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 0, 0, 0, 0, 0, 0, 0,
+ 0, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 2942, 2943, 2944, 2945, 2946, 2947, 2948,
+ 2949, 2950, 2951, 2952, 2953, 2954, 2955, 2956,
+ 2957, 2958, 2959, 2960, 2961, 2962, 2963, 2964,
+ 2965, 2966, 2967, 2968, 2969, 2970, 2971, 2972,
+ 0, 2973, 2974, 2975, 2976, 2977, 2978, 2979,
+ 2980, 2981, 2982, 2983, 2984, 2985, 2986, 2987,
+ 2988, 2989, 2990, 2991, 2992, 2993, 2994, 2995,
+ 2996, 2997, 2998, 2999, 3000, 3001, 3002, 3003,
+ 3004, 3005, 3006, 3007, 3008, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 3009, 3010, 3011, 3012, 3013, 3014, 3015,
+ 3016, 3017, 3018, 3019, 3020, 3021, 3022, 3023,
+ 3024, 3025, 3026, 3027, 3028, 3029, 3030, 3031,
+ 3032, 3033, 3034, 3035, 3036, 3037, 3038, 3039,
+ 3040, 3041, 3042, 3043, 3044, 3045, 3046, 3047,
+ 3048, 3049, 3050, 3051, 3052, 3053, 3054, 3055,
+ 812, 3056, 3057, 3058, 3059, 3060, 3061, 3062,
+ 3063, 3064, 3065, 3066, 3067, 3068, 3069, 3070,
+ 3071, 3072, 3073, 3074, 3075, 3076, 3077, 3078,
+ 3079, 3080, 3081, 3082, 3083, 3084, 3085, 3086,
+ 3087, 3088, 3089, 3090, 3091, 3092, 3093, 3094,
+ 3095, 3096, 3097, 3098, 3099, 3100, 3101, 3102,
+ 3103, 3104, 3105, 3106, 3107, 3108, 3109, 3110,
+ 3111, 3112, 3113, 3114, 3115, 3116, 3117, 3118,
+ 3119, 3120, 3121, 3122, 3123, 3124, 3125, 3126,
+ 3127, 3128, 3129, 3130, 3131, 3132, 3133, 3134,
+ 3135, 3136, 3137, 3138, 3139, 3140, 3141, 3142,
+ 3143, 3144, 3145, 3146, 3147, 3148, 3149, 3150,
+ 3151, 3152, 3153, 3154, 3155, 3156, 3157, 3158,
+ 3159, 3160, 3161, 3162, 3163, 3164, 3165, 3166,
+ 3167, 3168, 3169, 3170, 3171, 3172, 3173, 3174,
+ 3175, 3176, 3177, 3178, 3179, 3180, 3181, 3182,
+ 0, 3183, 3184, 3185, 3186, 3187, 3188, 3189,
+ 3190, 3191, 3192, 3193, 3194, 3195, 3196, 3197,
+ 3198, 3199, 3200, 3201, 3202, 3203, 3204, 3205,
+ 3206, 3207, 3208, 3209, 3210, 3211, 3212, 3213,
+ 3214, 3215, 3216, 3217, 3218, 3219, 3220, 3221,
+ 3222, 3223, 3224, 3225, 3226, 3227, 3228, 3229,
+ 3230, 3231, 3232, 3233, 3234, 3235, 3236, 3237,
+ 3238, 3239, 3240, 3241, 3242, 3243, 3244, 3245,
+ 3246, 3247, 3248, 3249, 3250, 3251, 3252, 3253,
+ 3254, 3255, 3256, 3257, 3258, 3259, 3260, 3261,
+ 3262, 3263, 3264, 3265, 3266, 3267, 3268, 3269,
+ 3270, 3271, 3272, 3273, 3274, 3275, 3276, 3277,
+ 3278, 3279, 3280, 3281, 3282, 3283, 3284, 3285,
+ 3286, 3287, 3288, 3289, 3290, 3291, 3292, 3293,
+ 3294, 3295, 3296, 3297, 3298, 3299, 3300, 3301,
+ 3302, 3303, 3304, 3305, 3306, 3307, 3308, 3309,
+ 3310, 3311, 3312, 3313, 3314, 3315, 3316, 3317,
+ 3318, 3319, 3320, 3321, 3322, 3323, 3324, 3325,
+ 3326, 3327, 3328, 3329, 3330, 3331, 3332, 3333,
+ 3334, 3335, 3336, 3337, 3338, 3339, 3340, 3341,
+ 3342, 3343, 3344, 3345, 3346, 3347, 3348, 3349,
+ 3350, 3351, 3352, 3353, 3354, 3355, 3356, 3357,
+ 3358, 3359, 3360, 3361, 3362, 3363, 3364, 3365,
+ 3366, 3367, 3368, 3369, 3370, 3371, 3372, 3373,
+ 3374, 3375, 3376, 3377, 3378, 3379, 3380, 3381,
+ 3382, 3383, 3384, 3385, 3386, 3387, 3388, 3389,
+ 3390, 3391, 3392, 3393, 3394, 3395, 3396, 3397,
+ 3398, 3399, 3400, 3401, 3402, 3403, 3404, 3405,
+ 3406, 3407, 3408, 3409, 3410, 3411, 3412, 3413,
+ 3414, 3415, 3416, 3417, 3418, 3419, 3420, 3421,
+ 3422, 3423, 3424, 3425, 3426, 3427, 3428, 3429,
+ 3430, 3431, 3432, 3433, 3434, 3435, 3436, 3437,
+ 3438, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 507, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 0, 0,
+ 0, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 46, 46, 46, 46, 46, 46, 46,
+ 46, 46, 46, 46, 46, 46, 46, 46,
+ 46, 46, 46, 46, 46, 46, 46, 46,
+ 506, 506, 506, 506, 0, 0, 0, 0,
+ 0, 46, 46, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 339, 339, 1252, 339, 339, 339, 1101,
+ 339, 339, 339, 339, 1090, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 1093, 1093, 1090, 1090,
+ 1093, 76, 76, 76, 76, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 8, 8, 8,
+ 8, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 3439, 3439, 3439, 3439, 3439, 3439, 3439,
+ 3439, 3439, 3439, 3439, 3439, 3439, 3439, 3439,
+ 3439, 3439, 3439, 3439, 3439, 3439, 3439, 3439,
+ 3439, 3439, 3439, 3439, 3439, 3439, 3439, 3439,
+ 3439, 3439, 3439, 3439, 3439, 3439, 3439, 3439,
+ 3439, 3439, 3439, 3439, 3439, 3439, 3439, 3439,
+ 3439, 3439, 3439, 3439, 3439, 3439, 3439, 3439,
+ 3439, 3439, 3439, 3439, 3439, 3439, 3439, 3439,
+ 3439, 3439, 3439, 3439, 3439, 3439, 3439, 3439,
+ 3439, 3439, 3439, 3439, 3439, 3439, 3439, 3439,
+ 3439, 3439, 3439, 3439, 3439, 3439, 3439, 3439,
+ 3439, 3439, 3439, 3439, 3439, 3439, 3439, 3439,
+ 3439, 3439, 3439, 3439, 3439, 3439, 3439, 3439,
+ 3439, 3439, 3439, 3439, 3439, 3439, 3439, 3439,
+ 3439, 3439, 3439, 3439, 3439, 3439, 3439, 3439,
+ 3439, 3439, 3439, 3439, 3439, 3439, 3439, 3439,
+ 3439, 3439, 3439, 3439, 3439, 3439, 3439, 3439,
+ 3439, 3439, 3439, 3439, 3439, 3439, 3439, 3439,
+ 3439, 3439, 3439, 3439, 3439, 3439, 3439, 3439,
+ 3439, 3439, 3439, 3439, 3439, 3439, 3439, 3439,
+ 3439, 3439, 3439, 3439, 3439, 3439, 3439, 3439,
+ 3439, 3439, 3439, 3439, 3439, 3439, 3439, 3439,
+ 3439, 3439, 3439, 3439, 3439, 3439, 3439, 3439,
+ 3439, 3439, 3439, 3439, 3439, 3439, 3439, 3439,
+ 3439, 3439, 3439, 3439, 3439, 3439, 3439, 3439,
+ 3439, 3439, 3439, 3439, 3439, 3439, 3439, 3439,
+ 3439, 3439, 3439, 3439, 3439, 3439, 3439, 3439,
+ 3439, 3439, 3439, 3439, 3439, 3439, 3439, 3439,
+ 3439, 3439, 3439, 3439, 3439, 3439, 3439, 3439,
+ 3439, 3439, 3439, 3439, 3439, 3439, 3439, 3439,
+ 3439, 3439, 3439, 3439, 3439, 3439, 3439, 3439,
+ 3439, 3439, 3439, 3439, 3439, 3439, 3439, 3439,
+ 3439, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
+ 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
+ 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
+ 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
+ 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
+ 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
+ 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
+ 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
+ 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
+ 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
+ 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
+ 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
+ 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
+ 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
+ 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
+ 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
+ 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
+ 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
+ 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
+ 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
+ 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
+ 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
+ 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
+ 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
+ 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
+ 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
+ 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
+ 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
+ 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
+ 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
+ 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
+ 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
+ 3440, 3441, 3442, 3443, 3444, 3445, 3446, 3447,
+ 3448, 3448, 3449, 3450, 3451, 3452, 3453, 3454,
+ 3455, 3456, 3457, 3458, 3459, 3460, 3461, 3462,
+ 3463, 3464, 3465, 3466, 3467, 3468, 3469, 3470,
+ 3471, 3472, 3473, 3474, 3475, 3476, 3477, 3478,
+ 3479, 3480, 3481, 3482, 3483, 3484, 3485, 3486,
+ 3487, 3488, 3489, 3490, 3491, 3492, 3493, 3494,
+ 3495, 3496, 3497, 3498, 3499, 3500, 3501, 3502,
+ 3503, 3504, 3505, 3506, 3507, 3508, 3509, 3510,
+ 3511, 3512, 3513, 3514, 3515, 3516, 3517, 3518,
+ 3519, 3520, 3521, 3522, 3523, 3524, 3525, 3526,
+ 3527, 3528, 3529, 3530, 3531, 3460, 3532, 3533,
+ 3534, 3535, 3536, 3537, 3538, 3539, 3540, 3541,
+ 3542, 3543, 3544, 3545, 3546, 3547, 3548, 3549,
+ 3550, 3551, 3552, 3553, 3554, 3555, 3556, 3557,
+ 3558, 3559, 3560, 3561, 3562, 3563, 3564, 3565,
+ 3566, 3567, 3568, 3569, 3570, 3571, 3572, 3573,
+ 3574, 3575, 3576, 3577, 3578, 3579, 3580, 3581,
+ 3582, 3583, 3584, 3585, 3586, 3587, 3588, 3589,
+ 3590, 3591, 3592, 3593, 3594, 3595, 3596, 3597,
+ 3598, 3599, 3550, 3600, 3601, 3602, 3603, 3604,
+ 3605, 3606, 3607, 3534, 3608, 3609, 3610, 3611,
+ 3612, 3613, 3614, 3615, 3616, 3617, 3618, 3619,
+ 3620, 3621, 3622, 3623, 3624, 3625, 3626, 3627,
+ 3460, 3628, 3629, 3630, 3631, 3632, 3633, 3634,
+ 3635, 3636, 3637, 3638, 3639, 3640, 3641, 3642,
+ 3643, 3644, 3645, 3646, 3647, 3648, 3649, 3650,
+ 3651, 3652, 3653, 3654, 3536, 3655, 3656, 3657,
+ 3658, 3659, 3660, 3661, 3662, 3663, 3664, 3665,
+ 3666, 3667, 3668, 3669, 3670, 3671, 3672, 3673,
+ 3674, 3675, 3676, 3677, 3678, 3679, 3680, 3681,
+ 3682, 3683, 3684, 3685, 3686, 3687, 3688, 3689,
+ 3690, 3691, 3692, 3693, 3694, 3695, 3696, 3697,
+ 3698, 3699, 3700, 3701, 3702, 3703, 3704, 339,
+ 339, 3705, 339, 3706, 339, 339, 3707, 3708,
+ 3709, 3710, 3711, 3712, 3713, 3714, 3715, 3716,
+ 339, 3717, 339, 3718, 339, 339, 3719, 3720,
+ 339, 339, 339, 3721, 3722, 3723, 3724, 0,
+ 0, 3725, 3726, 3727, 3728, 3729, 3730, 3731,
+ 3732, 3733, 3734, 3735, 3736, 3737, 3738, 3739,
+ 3740, 3741, 3742, 3743, 3744, 3745, 3746, 3747,
+ 3748, 3749, 3750, 3751, 3752, 3753, 3754, 3755,
+ 3756, 3757, 3758, 3759, 3760, 3761, 3762, 3763,
+ 3589, 3764, 3765, 3766, 3767, 3768, 3769, 3769,
+ 3770, 3771, 3772, 3773, 3774, 3775, 3776, 3777,
+ 3719, 3778, 3779, 3780, 0, 0, 0, 0,
+ 0, 3781, 3782, 3783, 3784, 3785, 3786, 3787,
+ 3788, 3731, 3789, 3790, 3791, 3705, 3792, 3793,
+ 3794, 3795, 3796, 3797, 3798, 3799, 3800, 3801,
+ 3802, 3803, 3740, 3804, 3741, 3805, 3806, 3807,
+ 3808, 3809, 3706, 3481, 3810, 3811, 3812, 3551,
+ 3638, 3813, 3814, 3748, 3815, 3749, 3816, 3817,
+ 3818, 3708, 3819, 3820, 3821, 3822, 3823, 3709,
+ 3824, 3825, 3826, 3827, 3828, 3829, 3763, 3830,
+ 3831, 3589, 3832, 3767, 3833, 3834, 3835, 3836,
+ 3837, 3772, 3838, 3718, 3839, 3773, 3532, 3840,
+ 3774, 3841, 3776, 3842, 3843, 3844, 3845, 3846,
+ 3778, 3714, 3847, 3779, 3848, 3780, 3849, 3448,
+ 3850, 3851, 3852, 3853, 3854, 3855, 3856, 3857,
+ 3858, 3859, 3860, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 3861, 3862, 3863, 3864, 3865, 3866, 3867,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 3868, 3869, 3870, 3871,
+ 3872, 0, 0, 0, 0, 0, 3873, 3874,
+ 3875, 3876, 3877, 3878, 3879, 3880, 3881, 3882,
+ 3883, 3884, 3885, 3886, 3887, 3888, 3889, 3890,
+ 3891, 3892, 3893, 3894, 3895, 3896, 3897, 3898,
+ 0, 3899, 3900, 3901, 3902, 3903, 0, 3904,
+ 0, 3905, 3906, 0, 3907, 3908, 0, 3909,
+ 3910, 3911, 3912, 3913, 3914, 3915, 3916, 3917,
+ 3918, 3919, 3920, 3921, 3922, 3923, 3924, 3925,
+ 3926, 3927, 3928, 3929, 3930, 3931, 3932, 3933,
+ 3934, 3935, 3936, 3937, 3938, 3939, 3940, 3941,
+ 3942, 3943, 3944, 3945, 3946, 3947, 3948, 3949,
+ 3950, 3951, 3952, 3953, 3954, 3955, 3956, 3957,
+ 3958, 3959, 3960, 3961, 3962, 3963, 3964, 3965,
+ 3966, 3967, 3968, 3969, 3970, 3971, 3972, 3973,
+ 3974, 3975, 3976, 3977, 3978, 3979, 3980, 3981,
+ 3982, 3983, 3984, 3985, 3986, 3987, 3988, 3989,
+ 3990, 3991, 3992, 3993, 3994, 3995, 3996, 3997,
+ 3998, 3999, 4000, 4001, 4002, 4003, 4004, 4005,
+ 4006, 4007, 4008, 4009, 4010, 4011, 4012, 4013,
+ 4014, 4015, 4016, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 4017, 4018, 4019, 4020,
+ 4021, 4022, 4023, 4024, 4025, 4026, 4027, 4028,
+ 4029, 4030, 4031, 4032, 4033, 4034, 4035, 4036,
+ 4037, 4038, 4039, 4040, 4041, 4042, 4043, 4044,
+ 4045, 4046, 4047, 4048, 4049, 4050, 4051, 4052,
+ 4053, 4054, 4055, 4056, 4057, 4058, 4059, 4060,
+ 4061, 4062, 4063, 4064, 4055, 4065, 4066, 4067,
+ 4068, 4069, 4070, 4071, 4072, 4073, 4074, 4075,
+ 4076, 4077, 4078, 4079, 4080, 4081, 4082, 4083,
+ 4084, 4085, 4086, 4087, 4088, 4089, 4090, 4091,
+ 4092, 4093, 4094, 4095, 4096, 4097, 4098, 4099,
+ 4100, 4101, 4102, 4103, 4104, 4105, 4106, 4107,
+ 4108, 4109, 4110, 4111, 4112, 4113, 4114, 4115,
+ 4116, 4117, 4118, 4119, 4120, 4121, 4122, 4123,
+ 4124, 4125, 4126, 4127, 4128, 4129, 4130, 4131,
+ 4132, 4133, 4134, 4135, 4136, 4137, 4138, 4139,
+ 4140, 4141, 4142, 4143, 4144, 4145, 4146, 4147,
+ 4148, 4149, 4150, 4151, 4152, 4153, 4154, 4155,
+ 4156, 4157, 4158, 4159, 4160, 4161, 4162, 4163,
+ 4164, 4056, 4165, 4166, 4167, 4168, 4169, 4170,
+ 4171, 4172, 4173, 4174, 4175, 4176, 4177, 4178,
+ 4179, 4180, 4181, 4182, 4183, 4184, 4185, 4186,
+ 4187, 4188, 4189, 4190, 4191, 4192, 4193, 4194,
+ 4195, 4196, 4197, 4198, 4199, 4200, 4201, 4202,
+ 4203, 4204, 4205, 4206, 4207, 4208, 4209, 4210,
+ 4211, 4212, 4213, 4214, 4215, 4216, 4217, 4218,
+ 4219, 4220, 4221, 4222, 4223, 4224, 4225, 4226,
+ 4227, 4228, 4229, 4230, 4231, 4232, 4233, 4234,
+ 4235, 4236, 4237, 4238, 4239, 4240, 4241, 4242,
+ 4243, 4244, 4245, 4246, 4247, 4248, 4249, 4250,
+ 4251, 4252, 4253, 4254, 4255, 4256, 4257, 4258,
+ 4259, 4260, 4261, 4262, 4263, 4264, 4265, 4266,
+ 4267, 4268, 4269, 4270, 4271, 4272, 4273, 4274,
+ 4275, 4276, 4277, 4278, 4279, 4280, 4281, 4282,
+ 4283, 4284, 4285, 4286, 4287, 4288, 4289, 4290,
+ 4291, 4292, 4293, 4294, 4295, 4296, 4297, 4298,
+ 4299, 4300, 4301, 4302, 4303, 4304, 4305, 4306,
+ 4307, 4308, 4309, 4310, 4311, 4312, 4313, 4314,
+ 4315, 4316, 4317, 4318, 4319, 4320, 4321, 4322,
+ 4323, 4324, 4325, 4326, 4327, 4328, 4329, 4330,
+ 4331, 4332, 4333, 4334, 4335, 4336, 4337, 4338,
+ 4339, 4340, 4341, 4342, 4343, 4344, 4345, 4346,
+ 4347, 4348, 4349, 4350, 4351, 4352, 4353, 4354,
+ 4355, 4356, 4357, 4358, 4359, 4360, 4361, 4362,
+ 4363, 4364, 4365, 4366, 4367, 4368, 4369, 4370,
+ 4371, 4372, 4373, 4374, 4375, 4376, 4377, 4378,
+ 4379, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 4380, 4381, 4382, 4383, 4384, 4385, 4386,
+ 4387, 4388, 4389, 4390, 4391, 4392, 4393, 4394,
+ 4395, 4396, 4397, 4398, 4399, 4400, 4401, 4402,
+ 4403, 4404, 4405, 4406, 4407, 4408, 4409, 4410,
+ 4411, 4412, 4413, 4414, 4415, 4416, 4417, 4418,
+ 4419, 4420, 4421, 4422, 4423, 4424, 4425, 4426,
+ 4427, 4428, 4429, 4430, 4431, 4432, 4433, 4434,
+ 4435, 4436, 4437, 4438, 4439, 4440, 4441, 4442,
+ 4443, 0, 0, 4444, 4445, 4446, 4447, 4448,
+ 4449, 4450, 4451, 4452, 4453, 4454, 4455, 4456,
+ 4457, 4458, 4459, 4460, 4461, 4462, 4463, 4464,
+ 4465, 4466, 4467, 4468, 4469, 4470, 4471, 4472,
+ 4473, 4474, 4475, 4476, 4477, 4478, 4479, 4480,
+ 4481, 4482, 4483, 4484, 4485, 4486, 4487, 4488,
+ 4489, 4490, 4491, 4492, 4493, 4494, 4495, 4496,
+ 4497, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 4498, 4499, 4500, 4501, 4502, 4503, 4504,
+ 4505, 4506, 4507, 4508, 4509, 4510, 76, 0,
+ 0, 558, 558, 558, 558, 558, 558, 558,
+ 558, 558, 558, 558, 558, 558, 558, 558,
+ 558, 4511, 4512, 4513, 4514, 4515, 4516, 4517,
+ 4518, 4519, 4520, 0, 0, 0, 0, 0,
+ 0, 524, 524, 524, 524, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 4521, 4522, 4523, 4524, 4524, 4525, 4526,
+ 4527, 4528, 4529, 4530, 4531, 4532, 4533, 4534,
+ 4535, 4536, 4537, 4538, 4539, 4540, 8, 8,
+ 4541, 4542, 4543, 4543, 4543, 4543, 4544, 4544,
+ 4544, 4545, 4546, 4547, 0, 4548, 4549, 4550,
+ 4551, 4552, 4553, 4554, 4555, 4556, 4557, 4558,
+ 4559, 4560, 4561, 4562, 4563, 4564, 4565, 4566,
+ 0, 4567, 4568, 4569, 4570, 0, 0, 0,
+ 0, 4571, 4572, 4573, 1054, 4574, 0, 4575,
+ 4576, 4577, 4578, 4579, 4580, 4581, 4582, 4583,
+ 4584, 4585, 4586, 4587, 4588, 4589, 4590, 4591,
+ 4592, 4593, 4594, 4595, 4596, 4597, 4598, 4599,
+ 4600, 4601, 4602, 4603, 4604, 4605, 4606, 4607,
+ 4608, 4609, 4610, 4611, 4612, 4613, 4614, 4615,
+ 4616, 4617, 4618, 4619, 4620, 4621, 4622, 4623,
+ 4624, 4625, 4626, 4627, 4628, 4629, 4630, 4631,
+ 4632, 4633, 4634, 4635, 4636, 4637, 4638, 4639,
+ 4640, 4641, 4642, 4643, 4644, 4645, 4646, 4647,
+ 4648, 4649, 4650, 4651, 4652, 4653, 4654, 4655,
+ 4656, 4657, 4658, 4659, 4660, 4661, 4662, 4663,
+ 4664, 4665, 4666, 4667, 4668, 4669, 4670, 4671,
+ 4672, 4673, 4674, 4675, 4676, 4677, 4678, 4679,
+ 4680, 4681, 4682, 4683, 4684, 4685, 4686, 4687,
+ 4688, 4689, 4690, 4691, 4692, 4693, 4694, 4695,
+ 4696, 4697, 4698, 4699, 4700, 4701, 4702, 4703,
+ 4704, 4705, 4706, 4707, 4708, 4709, 0, 0,
+ 80, 0, 4710, 4711, 4712, 4713, 4714, 4715,
+ 4716, 4717, 4718, 4719, 4720, 4721, 4722, 4723,
+ 4724, 4725, 4726, 4727, 4728, 4729, 4730, 4731,
+ 4732, 4733, 4734, 4735, 4736, 4737, 4738, 4739,
+ 4740, 4741, 4742, 4743, 4744, 4745, 4746, 4747,
+ 4748, 4749, 4750, 4751, 4752, 4753, 4754, 4755,
+ 4756, 4757, 4758, 4759, 4760, 4761, 4762, 4763,
+ 4764, 4765, 4766, 4767, 4768, 4769, 4770, 4771,
+ 4772, 4773, 4774, 4775, 4776, 4777, 4778, 4779,
+ 4780, 4781, 4782, 4783, 4784, 4785, 4786, 4787,
+ 4788, 4789, 4790, 4791, 4792, 4793, 4794, 4795,
+ 4796, 4797, 4798, 4799, 4800, 4801, 4802, 4803,
+ 4804, 4805, 4806, 4807, 4808, 4809, 4810, 4811,
+ 4812, 4813, 4814, 4815, 4816, 4817, 4818, 4819,
+ 4820, 4821, 4822, 4823, 4824, 4825, 4826, 4827,
+ 4828, 4829, 4830, 4831, 4832, 4833, 4834, 4835,
+ 4836, 4837, 4838, 4839, 4840, 4841, 4842, 4843,
+ 4844, 4845, 4846, 4847, 4848, 4849, 4850, 4851,
+ 4852, 4853, 4854, 4855, 4856, 4857, 4858, 4859,
+ 4860, 4861, 4862, 4863, 4864, 4865, 4866, 4867,
+ 4868, 4869, 4870, 4871, 4872, 4873, 4874, 4875,
+ 4876, 4877, 4878, 4879, 4880, 4881, 4882, 4883,
+ 4884, 4885, 4886, 4887, 4888, 4889, 4890, 4891,
+ 4892, 4893, 4894, 4895, 4896, 4897, 4898, 4899,
+ 0, 0, 0, 4900, 4901, 4902, 4903, 4904,
+ 4905, 0, 0, 4906, 4907, 4908, 4909, 4910,
+ 4911, 0, 0, 4912, 4913, 4914, 4915, 4916,
+ 4917, 0, 0, 4918, 4919, 4920, 0, 0,
+ 0, 4921, 4922, 4923, 4924, 4925, 4926, 4927,
+ 0, 4928, 4929, 4930, 4931, 4932, 4933, 4934,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 4935, 4935, 4935, 76, 76, 0,
+ 0, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 0, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 0, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 0, 339, 339, 0,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 0,
+ 0, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 0, 0, 0, 0,
+ 0, 990, 8, 812, 0, 0, 0, 0,
+ 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120,
+ 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120,
+ 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120,
+ 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120,
+ 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120,
+ 1120, 1120, 1120, 1120, 1120, 0, 0, 0,
+ 812, 812, 812, 812, 812, 812, 812, 812,
+ 812, 4936, 4936, 4936, 4936, 4936, 4936, 4936,
+ 4936, 4936, 4936, 4936, 4936, 4936, 4936, 4936,
+ 4936, 4936, 4936, 4936, 4936, 4936, 4936, 4936,
+ 4936, 4936, 4936, 4936, 4936, 4936, 4936, 4936,
+ 4936, 4936, 4936, 4936, 4936, 4936, 4936, 4936,
+ 4936, 4936, 4936, 4936, 4936, 4936, 4936, 4936,
+ 4936, 4936, 4936, 4936, 4936, 4936, 1251, 1251,
+ 1251, 1251, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 1251, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 0, 1120, 1120, 1120, 1120, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 1249, 339, 339, 339, 339, 339,
+ 339, 339, 339, 1249, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 0,
+ 990, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 0, 0, 0,
+ 0, 339, 339, 339, 339, 339, 339, 339,
+ 339, 990, 1249, 1249, 1249, 1249, 1249, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 4937, 4938, 4939, 4940, 4941, 4942, 4943,
+ 4944, 4945, 4946, 4947, 4948, 4949, 4950, 4951,
+ 4952, 4953, 4954, 4955, 4956, 4957, 4958, 4959,
+ 4960, 4961, 4962, 4963, 4964, 4965, 4966, 4967,
+ 4968, 4969, 4970, 4971, 4972, 4973, 4974, 4975,
+ 4976, 4977, 4978, 4979, 4980, 4981, 4982, 4983,
+ 4984, 4985, 4986, 4987, 4988, 4989, 4990, 4991,
+ 4992, 4993, 4994, 4995, 4996, 4997, 4998, 4999,
+ 5000, 5001, 5002, 5003, 5004, 5005, 5006, 5007,
+ 5008, 5009, 5010, 5011, 5012, 5013, 5014, 5015,
+ 5016, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 0,
+ 0, 1110, 1110, 1110, 1110, 1110, 1110, 1110,
+ 1110, 1110, 1110, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 1050, 1050, 1050, 1050, 1050, 1050, 0,
+ 0, 1050, 0, 1050, 1050, 1050, 1050, 1050,
+ 1050, 1050, 1050, 1050, 1050, 1050, 1050, 1050,
+ 1050, 1050, 1050, 1050, 1050, 1050, 1050, 1050,
+ 1050, 1050, 1050, 1050, 1050, 1050, 1050, 1050,
+ 1050, 1050, 1050, 1050, 1050, 1050, 1050, 1050,
+ 1050, 1050, 1050, 1050, 1050, 1050, 1050, 0,
+ 1050, 1050, 0, 0, 0, 1050, 0, 0,
+ 1050, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 1050, 1050, 1050, 1050, 1050, 1050, 1050,
+ 1050, 1050, 1050, 1050, 1050, 1050, 1050, 1050,
+ 1050, 1050, 1050, 1050, 1050, 1050, 1050, 5017,
+ 5017, 5017, 5017, 0, 0, 0, 0, 0,
+ 8, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 1050, 1090, 1090, 1090, 0, 1090, 1090,
+ 0, 0, 0, 0, 0, 1090, 537, 1090,
+ 524, 1050, 1050, 1050, 1050, 0, 1050, 1050,
+ 1050, 0, 1050, 1050, 1050, 1050, 1050, 1050,
+ 1050, 1050, 1050, 1050, 1050, 1050, 1050, 1050,
+ 1050, 1050, 1050, 1050, 1050, 1050, 1050, 1050,
+ 1050, 1050, 1050, 1050, 1050, 0, 0, 0,
+ 0, 524, 550, 537, 0, 0, 0, 0,
+ 1101, 5017, 5017, 5017, 5017, 5017, 5017, 5017,
+ 5017, 0, 0, 0, 0, 0, 0, 0,
+ 0, 1046, 1046, 1046, 1046, 1046, 1046, 1046,
+ 1046, 1046, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 1249, 1249, 1249, 1249, 1249, 1249, 1249,
+ 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249,
+ 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249,
+ 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249,
+ 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249,
+ 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249,
+ 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249,
+ 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249,
+ 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249,
+ 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249,
+ 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249,
+ 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249,
+ 1249, 1249, 1249, 1249, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 990, 990, 990, 990, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 812, 812, 812, 812, 812, 812, 812,
+ 812, 812, 812, 812, 812, 812, 812, 812,
+ 812, 812, 812, 812, 812, 812, 812, 812,
+ 812, 812, 812, 812, 812, 812, 812, 812,
+ 812, 812, 812, 812, 812, 812, 812, 812,
+ 812, 812, 812, 812, 812, 812, 812, 812,
+ 812, 812, 812, 812, 812, 812, 812, 812,
+ 812, 812, 812, 812, 812, 812, 812, 812,
+ 812, 812, 812, 812, 812, 812, 812, 812,
+ 812, 812, 812, 812, 812, 812, 812, 812,
+ 812, 812, 812, 812, 812, 812, 812, 812,
+ 812, 812, 812, 812, 812, 812, 812, 812,
+ 812, 812, 812, 812, 812, 812, 812, 812,
+ 812, 812, 812, 812, 812, 812, 812, 812,
+ 812, 812, 812, 812, 812, 812, 812, 812,
+ 812, 812, 812, 812, 812, 812, 812, 812,
+ 812, 812, 812, 812, 812, 812, 812, 812,
+ 812, 812, 812, 812, 812, 812, 812, 812,
+ 812, 812, 812, 812, 812, 812, 812, 812,
+ 812, 812, 812, 812, 812, 812, 812, 812,
+ 812, 812, 812, 812, 812, 812, 812, 812,
+ 812, 812, 812, 812, 812, 812, 812, 812,
+ 812, 812, 812, 812, 812, 812, 812, 812,
+ 812, 812, 812, 812, 812, 812, 812, 812,
+ 812, 812, 812, 812, 812, 812, 812, 812,
+ 812, 812, 812, 812, 812, 812, 812, 812,
+ 812, 812, 812, 812, 812, 812, 812, 812,
+ 812, 812, 812, 812, 812, 812, 812, 812,
+ 812, 812, 812, 812, 812, 812, 812, 812,
+ 812, 812, 812, 812, 812, 812, 812, 812,
+ 812, 812, 812, 812, 812, 812, 812, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 812, 812, 812, 812, 812, 812, 812,
+ 812, 812, 812, 812, 812, 812, 812, 812,
+ 812, 812, 812, 812, 812, 812, 812, 812,
+ 812, 812, 812, 812, 812, 812, 812, 812,
+ 812, 812, 812, 812, 812, 812, 812, 812,
+ 0, 0, 0, 812, 812, 812, 812, 812,
+ 812, 812, 812, 812, 812, 812, 812, 812,
+ 812, 812, 812, 812, 812, 812, 812, 812,
+ 812, 812, 812, 812, 812, 812, 812, 812,
+ 812, 812, 812, 812, 812, 812, 812, 812,
+ 812, 812, 812, 812, 812, 812, 812, 812,
+ 5018, 5019, 812, 812, 812, 812, 812, 5020,
+ 5021, 5022, 5023, 5024, 5025, 5026, 5027, 5028,
+ 550, 550, 550, 812, 812, 812, 5029, 5030,
+ 5031, 5032, 5033, 5034, 80, 80, 80, 80,
+ 80, 80, 80, 80, 537, 537, 537, 537,
+ 537, 537, 537, 537, 812, 812, 524, 524,
+ 524, 524, 524, 537, 537, 812, 812, 812,
+ 812, 812, 812, 812, 812, 812, 812, 812,
+ 812, 812, 812, 812, 812, 812, 812, 812,
+ 812, 812, 812, 812, 812, 812, 812, 812,
+ 812, 812, 812, 524, 524, 524, 524, 812,
+ 812, 812, 812, 812, 812, 812, 812, 812,
+ 812, 812, 5035, 5036, 5037, 5038, 5039, 5040,
+ 5041, 5042, 812, 812, 812, 812, 812, 812,
+ 812, 812, 812, 812, 812, 812, 812, 812,
+ 812, 812, 812, 812, 812, 812, 812, 812,
+ 812, 812, 812, 812, 812, 812, 812, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 524, 524, 524, 76, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 76, 76, 76, 76, 76, 76, 76, 76,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 1120, 1120, 1120, 1120, 1120, 1120, 1120,
+ 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120,
+ 1120, 1120, 1120, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 5043, 1945, 1920, 1963, 1947, 1948, 5044,
+ 1927, 1930, 5045, 5046, 1931, 1950, 1933, 5047,
+ 1935, 1936, 1937, 5048, 5049, 5050, 5051, 5052,
+ 5053, 5054, 1941, 5055, 5056, 5057, 1964, 1946,
+ 5058, 1926, 1928, 1956, 1965, 5059, 1932, 5060,
+ 5061, 1951, 5062, 5063, 5064, 5065, 5066, 5067,
+ 5068, 5069, 5070, 5071, 5072, 5043, 1945, 1920,
+ 1963, 1947, 1948, 5044, 1927, 1930, 5045, 5046,
+ 1931, 1950, 1933, 5047, 1935, 1936, 1937, 5048,
+ 5049, 5050, 5051, 5052, 5053, 5054, 1941, 5055,
+ 5056, 5057, 1964, 1946, 5058, 1926, 0, 1956,
+ 1965, 5059, 1932, 5060, 5061, 1951, 5062, 5063,
+ 5064, 5065, 5066, 5067, 5068, 5069, 5070, 5071,
+ 5072, 5043, 1945, 1920, 1963, 1947, 1948, 5044,
+ 1927, 1930, 5045, 5046, 1931, 1950, 1933, 5047,
+ 1935, 1936, 1937, 5048, 5049, 5050, 5051, 5052,
+ 5053, 5054, 1941, 5055, 5056, 5057, 1964, 1946,
+ 5058, 1926, 1928, 1956, 1965, 5059, 1932, 5060,
+ 5061, 1951, 5062, 5063, 5064, 5065, 5066, 5067,
+ 5068, 5069, 5070, 5071, 5072, 5043, 0, 1920,
+ 1963, 0, 0, 5044, 0, 0, 5045, 5046,
+ 0, 0, 1933, 5047, 1935, 1936, 0, 5048,
+ 5049, 5050, 5051, 5052, 5053, 5054, 1941, 5055,
+ 5056, 5057, 1964, 0, 5058, 0, 1928, 1956,
+ 1965, 5059, 1932, 5060, 5061, 0, 5062, 5063,
+ 5064, 5065, 5066, 5067, 5068, 5069, 5070, 5071,
+ 5072, 5043, 1945, 1920, 1963, 1947, 1948, 5044,
+ 1927, 1930, 5045, 5046, 1931, 1950, 1933, 5047,
+ 1935, 1936, 1937, 5048, 5049, 5050, 5051, 5052,
+ 5053, 5054, 1941, 5055, 5056, 5057, 1964, 1946,
+ 5058, 1926, 1928, 1956, 1965, 5059, 1932, 5060,
+ 5061, 1951, 5062, 5063, 5064, 5065, 5066, 5067,
+ 5068, 5069, 5070, 5071, 5072, 5043, 1945, 0,
+ 1963, 1947, 1948, 5044, 0, 0, 5045, 5046,
+ 1931, 1950, 1933, 5047, 1935, 1936, 0, 5048,
+ 5049, 5050, 5051, 5052, 5053, 5054, 0, 5055,
+ 5056, 5057, 1964, 1946, 5058, 1926, 1928, 1956,
+ 1965, 5059, 1932, 5060, 5061, 1951, 5062, 5063,
+ 5064, 5065, 5066, 5067, 5068, 5069, 5070, 5071,
+ 5072, 5043, 1945, 0, 1963, 1947, 1948, 5044,
+ 0, 1930, 5045, 5046, 1931, 1950, 0, 5047,
+ 0, 0, 0, 5048, 5049, 5050, 5051, 5052,
+ 5053, 5054, 0, 5055, 5056, 5057, 1964, 1946,
+ 5058, 1926, 1928, 1956, 1965, 5059, 1932, 5060,
+ 5061, 1951, 5062, 5063, 5064, 5065, 5066, 5067,
+ 5068, 5069, 5070, 5071, 5072, 5043, 1945, 1920,
+ 1963, 1947, 1948, 5044, 1927, 1930, 5045, 5046,
+ 1931, 1950, 1933, 5047, 1935, 1936, 1937, 5048,
+ 5049, 5050, 5051, 5052, 5053, 5054, 1941, 5055,
+ 5056, 5057, 1964, 1946, 5058, 1926, 1928, 1956,
+ 1965, 5059, 1932, 5060, 5061, 1951, 5062, 5063,
+ 5064, 5065, 5066, 5067, 5068, 5069, 5070, 5071,
+ 5072, 5043, 1945, 1920, 1963, 1947, 1948, 5044,
+ 1927, 1930, 5045, 5046, 1931, 1950, 1933, 5047,
+ 1935, 1936, 1937, 5048, 5049, 5050, 5051, 5052,
+ 5053, 5054, 1941, 5055, 5056, 5057, 1964, 1946,
+ 5058, 1926, 1928, 1956, 1965, 5059, 1932, 5060,
+ 5061, 1951, 5062, 5063, 5064, 5065, 5066, 5067,
+ 5068, 5069, 5070, 5071, 5072, 5043, 1945, 1920,
+ 1963, 1947, 1948, 5044, 1927, 1930, 5045, 5046,
+ 1931, 1950, 1933, 5047, 1935, 1936, 1937, 5048,
+ 5049, 5050, 5051, 5052, 5053, 5054, 1941, 5055,
+ 5056, 5057, 1964, 1946, 5058, 1926, 1928, 1956,
+ 1965, 5059, 1932, 5060, 5061, 1951, 5062, 5063,
+ 5064, 5065, 5066, 5067, 5068, 5069, 5070, 5071,
+ 5072, 5043, 1945, 1920, 1963, 1947, 1948, 5044,
+ 1927, 1930, 5045, 5046, 1931, 1950, 1933, 5047,
+ 1935, 1936, 1937, 5048, 5049, 5050, 5051, 5052,
+ 5053, 5054, 1941, 5055, 5056, 5057, 1964, 1946,
+ 5058, 1926, 1928, 1956, 1965, 5059, 1932, 5060,
+ 5061, 1951, 5062, 5063, 5064, 5065, 5066, 5067,
+ 5068, 5069, 5070, 5071, 5072, 5043, 1945, 1920,
+ 1963, 1947, 1948, 5044, 1927, 1930, 5045, 5046,
+ 1931, 1950, 1933, 5047, 1935, 1936, 1937, 5048,
+ 5049, 5050, 5051, 5052, 5053, 5054, 1941, 5055,
+ 5056, 5057, 1964, 1946, 5058, 1926, 1928, 1956,
+ 1965, 5059, 1932, 5060, 5061, 1951, 5062, 5063,
+ 5064, 5065, 5066, 5067, 5068, 5069, 5070, 5071,
+ 5072, 5043, 1945, 1920, 1963, 1947, 1948, 5044,
+ 1927, 1930, 5045, 5046, 1931, 1950, 1933, 5047,
+ 1935, 1936, 1937, 5048, 5049, 5050, 5051, 5052,
+ 5053, 5054, 1941, 5055, 5056, 5057, 1964, 1946,
+ 5058, 1926, 1928, 1956, 1965, 5059, 1932, 5060,
+ 5061, 1951, 5062, 5063, 5064, 5065, 5066, 5067,
+ 5068, 5069, 5070, 5071, 5072, 5073, 5074, 0,
+ 0, 5075, 5076, 1960, 5077, 5078, 5079, 5080,
+ 5081, 5082, 5083, 5084, 5085, 5086, 5087, 5088,
+ 1961, 5089, 5090, 5091, 5092, 5093, 5094, 5095,
+ 5096, 5097, 5098, 5099, 5100, 1959, 5101, 5102,
+ 5103, 5104, 5105, 5106, 5107, 5108, 5109, 5110,
+ 5111, 5112, 1958, 5113, 5114, 5115, 5116, 5117,
+ 5118, 5119, 5120, 5121, 5122, 5123, 5124, 5125,
+ 5126, 5127, 5128, 5075, 5076, 1960, 5077, 5078,
+ 5079, 5080, 5081, 5082, 5083, 5084, 5085, 5086,
+ 5087, 5088, 1961, 5089, 5090, 5091, 5092, 5093,
+ 5094, 5095, 5096, 5097, 5098, 5099, 5100, 1959,
+ 5101, 5102, 5103, 5104, 5105, 5106, 5107, 5108,
+ 5109, 5110, 5111, 5112, 1958, 5113, 5114, 5115,
+ 5116, 5117, 5118, 5119, 5120, 5121, 5122, 5123,
+ 5124, 5125, 5126, 5127, 5128, 5075, 5076, 1960,
+ 5077, 5078, 5079, 5080, 5081, 5082, 5083, 5084,
+ 5085, 5086, 5087, 5088, 1961, 5089, 5090, 5091,
+ 5092, 5093, 5094, 5095, 5096, 5097, 5098, 5099,
+ 5100, 1959, 5101, 5102, 5103, 5104, 5105, 5106,
+ 5107, 5108, 5109, 5110, 5111, 5112, 1958, 5113,
+ 5114, 5115, 5116, 5117, 5118, 5119, 5120, 5121,
+ 5122, 5123, 5124, 5125, 5126, 5127, 5128, 5075,
+ 5076, 1960, 5077, 5078, 5079, 5080, 5081, 5082,
+ 5083, 5084, 5085, 5086, 5087, 5088, 1961, 5089,
+ 5090, 5091, 5092, 5093, 5094, 5095, 5096, 5097,
+ 5098, 5099, 5100, 1959, 5101, 5102, 5103, 5104,
+ 5105, 5106, 5107, 5108, 5109, 5110, 5111, 5112,
+ 1958, 5113, 5114, 5115, 5116, 5117, 5118, 5119,
+ 5120, 5121, 5122, 5123, 5124, 5125, 5126, 5127,
+ 5128, 5075, 5076, 1960, 5077, 5078, 5079, 5080,
+ 5081, 5082, 5083, 5084, 5085, 5086, 5087, 5088,
+ 1961, 5089, 5090, 5091, 5092, 5093, 5094, 5095,
+ 5096, 5097, 5098, 5099, 5100, 1959, 5101, 5102,
+ 5103, 5104, 5105, 5106, 5107, 5108, 5109, 5110,
+ 5111, 5112, 1958, 5113, 5114, 5115, 5116, 5117,
+ 5118, 5119, 5120, 5121, 5122, 5123, 5124, 5125,
+ 5126, 5127, 5128, 5129, 5130, 0, 0, 5131,
+ 5132, 5133, 5134, 5135, 5136, 5137, 5138, 5139,
+ 5140, 5131, 5132, 5133, 5134, 5135, 5136, 5137,
+ 5138, 5139, 5140, 5131, 5132, 5133, 5134, 5135,
+ 5136, 5137, 5138, 5139, 5140, 5131, 5132, 5133,
+ 5134, 5135, 5136, 5137, 5138, 5139, 5140, 5131,
+ 5132, 5133, 5134, 5135, 5136, 5137, 5138, 5139,
+ 5140, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 5141, 5142, 5143, 5144, 5145, 3725, 5146,
+ 5147, 5148, 5149, 3726, 5150, 5151, 5152, 3727,
+ 5153, 5154, 5155, 5156, 5157, 5158, 5159, 5160,
+ 5161, 5162, 5163, 5164, 3782, 5165, 5166, 5167,
+ 5168, 5169, 5170, 5171, 5172, 5173, 3787, 3728,
+ 3729, 3788, 5174, 5175, 3538, 5176, 3730, 5177,
+ 5178, 5179, 5180, 5180, 5180, 5181, 5182, 5183,
+ 5184, 5185, 5186, 5187, 5188, 5189, 5190, 5191,
+ 5192, 5193, 5194, 5195, 5196, 5197, 5198, 5198,
+ 3790, 5199, 5200, 5201, 5202, 3732, 5203, 5204,
+ 5205, 3691, 5206, 5207, 5208, 5209, 5210, 5211,
+ 5212, 5213, 5214, 5215, 5216, 5217, 5218, 5219,
+ 5220, 5221, 5222, 5223, 5224, 5225, 5226, 5227,
+ 5228, 5229, 5230, 5231, 5231, 5232, 5233, 5234,
+ 3534, 5235, 5236, 5237, 5238, 5239, 5240, 5241,
+ 5242, 3737, 5243, 5244, 5245, 5246, 5247, 5248,
+ 5249, 5250, 5251, 5252, 5253, 5254, 5255, 5256,
+ 5257, 5258, 5259, 5260, 5261, 5262, 5263, 3480,
+ 5264, 5265, 5266, 5266, 5267, 5268, 5268, 5269,
+ 5270, 5271, 5272, 5273, 5274, 5275, 5276, 5277,
+ 5278, 5279, 5280, 5281, 3738, 5282, 5283, 5284,
+ 5285, 3802, 5285, 5286, 3740, 5287, 5288, 5289,
+ 5290, 3741, 3453, 5291, 5292, 5293, 5294, 5295,
+ 5296, 5297, 5298, 5299, 5300, 5301, 5302, 5303,
+ 5304, 5305, 5306, 5307, 5308, 5309, 5310, 5311,
+ 5312, 3742, 5313, 5314, 5315, 5316, 5317, 5318,
+ 3744, 5319, 5320, 5321, 5322, 5323, 5324, 5325,
+ 5326, 3481, 3810, 5327, 5328, 5329, 5330, 5331,
+ 5332, 5333, 5334, 3745, 5335, 5336, 5337, 5338,
+ 3853, 5339, 5340, 5341, 5342, 5343, 5344, 5345,
+ 5346, 5347, 5348, 5349, 5350, 5351, 3551, 5352,
+ 5353, 5354, 5355, 5356, 5357, 5358, 5359, 5360,
+ 5361, 5362, 3746, 3638, 5363, 5364, 5365, 5366,
+ 5367, 5368, 5369, 5370, 3814, 5371, 5372, 5373,
+ 5374, 5375, 5376, 5377, 5378, 3815, 5379, 5380,
+ 5381, 5382, 5383, 5384, 5385, 5386, 5387, 5388,
+ 5389, 5390, 3817, 5391, 5392, 5393, 5394, 5395,
+ 5396, 5397, 5398, 5399, 5400, 5401, 5401, 5402,
+ 5403, 3819, 5404, 5405, 5406, 5407, 5408, 5409,
+ 5410, 3537, 5411, 5412, 5413, 5414, 5415, 5416,
+ 5417, 3825, 5418, 5419, 5420, 5421, 5422, 5423,
+ 5423, 3826, 3855, 5424, 5425, 5426, 5427, 5428,
+ 3499, 3828, 5429, 5430, 3757, 5431, 5432, 3713,
+ 5433, 5434, 3761, 5435, 5436, 5437, 5438, 5438,
+ 5439, 5440, 5441, 5442, 5443, 5444, 5445, 5446,
+ 5447, 5448, 5449, 5450, 5451, 5452, 5453, 5454,
+ 5455, 5456, 5457, 5458, 5459, 5460, 5461, 5462,
+ 5463, 5464, 5465, 3767, 5466, 5467, 5468, 5469,
+ 5470, 5471, 5472, 5473, 5474, 5475, 5476, 5477,
+ 5478, 5479, 5480, 5481, 5267, 5482, 5483, 5484,
+ 5485, 5486, 5487, 5488, 5489, 5490, 5491, 5492,
+ 5493, 3555, 5494, 5495, 5496, 5497, 5498, 5499,
+ 3770, 5500, 5501, 5502, 5503, 5504, 5505, 5506,
+ 5507, 5508, 5509, 5510, 5511, 5512, 5513, 5514,
+ 5515, 5516, 5517, 5518, 5519, 3494, 5520, 5521,
+ 5522, 5523, 5524, 5525, 3835, 5526, 5527, 5528,
+ 5529, 5530, 5531, 5532, 5533, 5534, 5535, 5536,
+ 5537, 5538, 5539, 5540, 5541, 5542, 5543, 5544,
+ 5545, 3840, 3841, 5546, 5547, 5548, 5549, 5550,
+ 5551, 5552, 5553, 5554, 5555, 5556, 5557, 5558,
+ 3842, 5559, 5560, 5561, 5562, 5563, 5564, 5565,
+ 5566, 5567, 5568, 5569, 5570, 5571, 5572, 5573,
+ 5574, 5575, 5576, 5577, 5578, 5579, 5580, 5581,
+ 5582, 5583, 5584, 5585, 5586, 5587, 5588, 3848,
+ 3848, 5589, 5590, 5591, 5592, 5593, 5594, 5595,
+ 5596, 5597, 5598, 3849, 5599, 5600, 5601, 5602,
+ 5603, 5604, 5605, 5606, 5607, 5608, 5609, 5610,
+ 5611, 5612, 5613, 5614, 5615, 5616, 5617, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 80, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 80, 80, 80, 80, 80, 80, 80,
+ 80, 80, 80, 80, 80, 80, 80, 80,
+ 80, 80, 80, 80, 80, 80, 80, 80,
+ 80, 80, 80, 80, 80, 80, 80, 80,
+ 80, 80, 80, 80, 80, 80, 80, 80,
+ 80, 80, 80, 80, 80, 80, 80, 80,
+ 80, 80, 80, 80, 80, 80, 80, 80,
+ 80, 80, 80, 80, 80, 80, 80, 80,
+ 80, 80, 80, 80, 80, 80, 80, 80,
+ 80, 80, 80, 80, 80, 80, 80, 80,
+ 80, 80, 80, 80, 80, 80, 80, 80,
+ 80, 80, 80, 80, 80, 80, 80, 80,
+ 80, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 558, 558, 558, 558, 558, 558, 558,
+ 558, 558, 558, 558, 558, 558, 558, 558,
+ 558, 558, 558, 558, 558, 558, 558, 558,
+ 558, 558, 558, 558, 558, 558, 558, 558,
+ 558, 558, 558, 558, 558, 558, 558, 558,
+ 558, 558, 558, 558, 558, 558, 558, 558,
+ 558, 558, 558, 558, 558, 558, 558, 558,
+ 558, 558, 558, 558, 558, 558, 558, 558,
+ 558, 558, 558, 558, 558, 558, 558, 558,
+ 558, 558, 558, 558, 558, 558, 558, 558,
+ 558, 558, 558, 558, 558, 558, 558, 558,
+ 558, 558, 558, 558, 558, 558, 558, 558,
+ 558, 558, 558, 558, 558, 558, 558, 558,
+ 558, 558, 558, 558, 558, 558, 558, 558,
+ 558, 558, 558, 558, 558, 558, 558, 558,
+ 558, 558, 558, 558, 558, 558, 558, 558,
+ 558, 558, 558, 558, 558, 558, 558, 558,
+ 558, 558, 558, 558, 558, 558, 558, 558,
+ 558, 558, 558, 558, 558, 558, 558, 558,
+ 558, 558, 558, 558, 558, 558, 558, 558,
+ 558, 558, 558, 558, 558, 558, 558, 558,
+ 558, 558, 558, 558, 558, 558, 558, 558,
+ 558, 558, 558, 558, 558, 558, 558, 558,
+ 558, 558, 558, 558, 558, 558, 558, 558,
+ 558, 558, 558, 558, 558, 558, 558, 558,
+ 558, 558, 558, 558, 558, 558, 558, 558,
+ 558, 558, 558, 558, 558, 558, 558, 558,
+ 558, 558, 558, 558, 558, 558, 558, 558,
+ 558, 558, 558, 558, 558, 558, 558, 558,
+ 558, 558, 558, 558, 558, 558, 558, 558,
+ 558, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
+ 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
+ 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
+ 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
+ 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
+ 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
+ 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
+ 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
+ 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
+ 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
+ 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
+ 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
+ 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
+ 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
+ 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
+ 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
+ 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
+ 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
+ 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
+ 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
+ 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
+ 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
+ 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
+ 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
+ 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
+ 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
+ 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
+ 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
+ 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
+ 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
+ 3440, 3440, 3440, 3440, 3440, 3440, 3440, 3440,
+ 3440, 3440, 3440, 3440, 3440, 3440, 3440, 0,
+ 0, };
+
+const utf8proc_property_t utf8proc_properties[] = {
+ {0, 0, 0, 0, NULL, false, -1, -1, -1, -1, -1, false},
+ {UTF8PROC_CATEGORY_CC, 0, UTF8PROC_BIDI_CLASS_BN, 0, NULL, false, -1, -1, -1, -1, -1, false, true, true, false, NULL},
+ {UTF8PROC_CATEGORY_CC, 0, UTF8PROC_BIDI_CLASS_S, 0, NULL, false, -1, -1, -1, -1, -1, false, false, true, false, NULL},
+ {UTF8PROC_CATEGORY_CC, 0, UTF8PROC_BIDI_CLASS_B, 0, NULL, false, -1, -1, -1, -1, -1, false, false, true, false, NULL},
+ {UTF8PROC_CATEGORY_CC, 0, UTF8PROC_BIDI_CLASS_WS, 0, NULL, false, -1, -1, -1, -1, -1, false, false, true, false, NULL},
+ {UTF8PROC_CATEGORY_CC, 0, UTF8PROC_BIDI_CLASS_B, 0, NULL, false, -1, -1, -1, -1, -1, false, true, true, false, NULL},
+ {UTF8PROC_CATEGORY_CC, 0, UTF8PROC_BIDI_CLASS_S, 0, NULL, false, -1, -1, -1, -1, -1, false, true, true, false, NULL},
+ {UTF8PROC_CATEGORY_ZS, 0, UTF8PROC_BIDI_CLASS_WS, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ET, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SC, 0, UTF8PROC_BIDI_CLASS_ET, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PS, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, true, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PE, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, true, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ES, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_CS, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PD, 0, UTF8PROC_BIDI_CLASS_ES, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_ND, 0, UTF8PROC_BIDI_CLASS_EN, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, true, -1, -1, -1, 17580, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, false, -1, -1, -1, 17400, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, true, -1, -1, -1, 17640, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 97, -1, 0, -1, false, false, false, false, utf8proc_sequences + 0},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 98, -1, 8640, -1, false, false, false, false, utf8proc_sequences + 2},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 99, -1, 60, -1, false, false, false, false, utf8proc_sequences + 4},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 100, -1, 960, -1, false, false, false, false, utf8proc_sequences + 6},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 101, -1, 120, -1, false, false, false, false, utf8proc_sequences + 8},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 102, -1, 9120, -1, false, false, false, false, utf8proc_sequences + 10},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 103, -1, 1080, -1, false, false, false, false, utf8proc_sequences + 12},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 104, -1, 1200, -1, false, false, false, false, utf8proc_sequences + 14},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 105, -1, 180, -1, false, false, false, false, utf8proc_sequences + 16},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 106, -1, 1320, -1, false, false, false, false, utf8proc_sequences + 18},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 107, -1, 1440, -1, false, false, false, false, utf8proc_sequences + 20},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 108, -1, 1560, -1, false, false, false, false, utf8proc_sequences + 22},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 109, -1, 9480, -1, false, false, false, false, utf8proc_sequences + 24},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 110, -1, 240, -1, false, false, false, false, utf8proc_sequences + 26},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 111, -1, 300, -1, false, false, false, false, utf8proc_sequences + 28},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 112, -1, 9720, -1, false, false, false, false, utf8proc_sequences + 30},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 113, -1, -1, -1, false, false, false, false, utf8proc_sequences + 32},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 114, -1, 1680, -1, false, false, false, false, utf8proc_sequences + 34},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 115, -1, 1800, -1, false, false, false, false, utf8proc_sequences + 36},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 116, -1, 1920, -1, false, false, false, false, utf8proc_sequences + 38},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 117, -1, 360, -1, false, false, false, false, utf8proc_sequences + 40},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 118, -1, 10560, -1, false, false, false, false, utf8proc_sequences + 42},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 119, -1, 2040, -1, false, false, false, false, utf8proc_sequences + 44},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 120, -1, 10680, -1, false, false, false, false, utf8proc_sequences + 46},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 121, -1, 420, -1, false, false, false, false, utf8proc_sequences + 48},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 122, -1, 2160, -1, false, false, false, false, utf8proc_sequences + 50},
+ {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PC, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 65, -1, 65, 480, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 66, -1, 66, 8700, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 67, -1, 67, 540, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 68, -1, 68, 1020, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 69, -1, 69, 600, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 70, -1, 70, 9180, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 71, -1, 71, 1140, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 72, -1, 72, 1260, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 73, -1, 73, 660, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 74, -1, 74, 1380, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 75, -1, 75, 1500, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 76, -1, 76, 1620, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 77, -1, 77, 9540, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 78, -1, 78, 720, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 79, -1, 79, 780, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 80, -1, 80, 9780, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 81, -1, 81, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 82, -1, 82, 1740, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 83, -1, 83, 1860, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 84, -1, 84, 1980, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 85, -1, 85, 840, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 86, -1, 86, 10620, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 87, -1, 87, 2100, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 88, -1, 88, 10740, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 89, -1, 89, 900, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 90, -1, 90, 2220, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_ZS, 0, UTF8PROC_BIDI_CLASS_CS, UTF8PROC_DECOMP_TYPE_NOBREAK, utf8proc_sequences + 52, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 54, false, -1, -1, -1, 3600, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 0, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PI, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, true, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_CF, 0, UTF8PROC_BIDI_CLASS_BN, 0, NULL, false, -1, -1, -1, -1, -1, false, true, true, false, NULL},
+ {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 57, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ET, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ET, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 60, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 62, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 64, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 67, false, 924, -1, 924, -1, -1, false, false, false, false, utf8proc_sequences + 67},
+ {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 69, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 72, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 28, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PF, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, true, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_FRACTION, utf8proc_sequences + 74, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_FRACTION, utf8proc_sequences + 78, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_FRACTION, utf8proc_sequences + 82, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 86, false, -1, 224, -1, -1, -1, false, false, false, false, utf8proc_sequences + 89},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 91, false, -1, 225, -1, -1, -1, false, false, false, false, utf8proc_sequences + 94},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 96, false, -1, 226, -1, 10860, -1, false, false, false, false, utf8proc_sequences + 99},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 101, false, -1, 227, -1, -1, -1, false, false, false, false, utf8proc_sequences + 104},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 106, false, -1, 228, -1, 2400, -1, false, false, false, false, utf8proc_sequences + 109},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 111, false, -1, 229, -1, 3000, -1, false, false, false, false, utf8proc_sequences + 114},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 230, -1, 2640, -1, false, false, false, false, utf8proc_sequences + 116},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 118, false, -1, 231, -1, 8760, -1, false, false, false, false, utf8proc_sequences + 121},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 123, false, -1, 232, -1, -1, -1, false, false, false, false, utf8proc_sequences + 126},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 128, false, -1, 233, -1, -1, -1, false, false, false, false, utf8proc_sequences + 131},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 133, false, -1, 234, -1, 11220, -1, false, false, false, false, utf8proc_sequences + 136},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 138, false, -1, 235, -1, -1, -1, false, false, false, false, utf8proc_sequences + 141},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 143, false, -1, 236, -1, -1, -1, false, false, false, false, utf8proc_sequences + 146},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 148, false, -1, 237, -1, -1, -1, false, false, false, false, utf8proc_sequences + 151},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 153, false, -1, 238, -1, -1, -1, false, false, false, false, utf8proc_sequences + 156},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 158, false, -1, 239, -1, 9240, -1, false, false, false, false, utf8proc_sequences + 161},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 240, -1, -1, -1, false, false, false, false, utf8proc_sequences + 163},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 165, false, -1, 241, -1, -1, -1, false, false, false, false, utf8proc_sequences + 168},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 170, false, -1, 242, -1, -1, -1, false, false, false, false, utf8proc_sequences + 173},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 175, false, -1, 243, -1, -1, -1, false, false, false, false, utf8proc_sequences + 178},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 180, false, -1, 244, -1, 11460, -1, false, false, false, false, utf8proc_sequences + 183},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 185, false, -1, 245, -1, 3360, -1, false, false, false, false, utf8proc_sequences + 188},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 190, false, -1, 246, -1, 3240, -1, false, false, false, false, utf8proc_sequences + 193},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 248, -1, 3120, -1, false, false, false, false, utf8proc_sequences + 195},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 197, false, -1, 249, -1, -1, -1, false, false, false, false, utf8proc_sequences + 200},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 202, false, -1, 250, -1, -1, -1, false, false, false, false, utf8proc_sequences + 205},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 207, false, -1, 251, -1, -1, -1, false, false, false, false, utf8proc_sequences + 210},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 212, false, -1, 252, -1, 2280, -1, false, false, false, false, utf8proc_sequences + 215},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 217, false, -1, 253, -1, -1, -1, false, false, false, false, utf8proc_sequences + 220},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 254, -1, -1, -1, false, false, false, false, utf8proc_sequences + 222},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, false, utf8proc_sequences + 224},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 227, false, 192, -1, 192, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 230, false, 193, -1, 193, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 233, false, 194, -1, 194, 10920, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 236, false, 195, -1, 195, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 239, false, 196, -1, 196, 2460, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 242, false, 197, -1, 197, 3060, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 198, -1, 198, 2700, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 245, false, 199, -1, 199, 8820, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 248, false, 200, -1, 200, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 251, false, 201, -1, 201, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 254, false, 202, -1, 202, 11280, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 257, false, 203, -1, 203, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 260, false, 204, -1, 204, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 263, false, 205, -1, 205, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 266, false, 206, -1, 206, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 269, false, 207, -1, 207, 9300, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 208, -1, 208, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 272, false, 209, -1, 209, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 275, false, 210, -1, 210, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 278, false, 211, -1, 211, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 281, false, 212, -1, 212, 11520, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 284, false, 213, -1, 213, 3420, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 287, false, 214, -1, 214, 3300, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 216, -1, 216, 3180, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 290, false, 217, -1, 217, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 293, false, 218, -1, 218, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 296, false, 219, -1, 219, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 299, false, 220, -1, 220, 2340, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 302, false, 221, -1, 221, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 222, -1, 222, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 305, false, 376, -1, 376, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 308, false, -1, 257, -1, -1, -1, false, false, false, false, utf8proc_sequences + 311},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 313, false, 256, -1, 256, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 316, false, -1, 259, -1, 11100, -1, false, false, false, false, utf8proc_sequences + 319},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 321, false, 258, -1, 258, 11160, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 324, false, -1, 261, -1, -1, -1, false, false, false, false, utf8proc_sequences + 327},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 329, false, 260, -1, 260, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 332, false, -1, 263, -1, -1, -1, false, false, false, false, utf8proc_sequences + 335},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 337, false, 262, -1, 262, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 340, false, -1, 265, -1, -1, -1, false, false, false, false, utf8proc_sequences + 343},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 345, false, 264, -1, 264, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 348, false, -1, 267, -1, -1, -1, false, false, false, false, utf8proc_sequences + 351},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 353, false, 266, -1, 266, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 356, false, -1, 269, -1, -1, -1, false, false, false, false, utf8proc_sequences + 359},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 361, false, 268, -1, 268, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 364, false, -1, 271, -1, -1, -1, false, false, false, false, utf8proc_sequences + 367},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 369, false, 270, -1, 270, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 273, -1, -1, -1, false, false, false, false, utf8proc_sequences + 372},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 272, -1, 272, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 374, false, -1, 275, -1, 8880, -1, false, false, false, false, utf8proc_sequences + 377},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 379, false, 274, -1, 274, 8940, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 382, false, -1, 277, -1, -1, -1, false, false, false, false, utf8proc_sequences + 385},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 387, false, 276, -1, 276, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 390, false, -1, 279, -1, -1, -1, false, false, false, false, utf8proc_sequences + 393},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 395, false, 278, -1, 278, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 398, false, -1, 281, -1, -1, -1, false, false, false, false, utf8proc_sequences + 401},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 403, false, 280, -1, 280, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 406, false, -1, 283, -1, -1, -1, false, false, false, false, utf8proc_sequences + 409},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 411, false, 282, -1, 282, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 414, false, -1, 285, -1, -1, -1, false, false, false, false, utf8proc_sequences + 417},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 419, false, 284, -1, 284, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 422, false, -1, 287, -1, -1, -1, false, false, false, false, utf8proc_sequences + 425},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 427, false, 286, -1, 286, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 430, false, -1, 289, -1, -1, -1, false, false, false, false, utf8proc_sequences + 433},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 435, false, 288, -1, 288, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 438, false, -1, 291, -1, -1, -1, false, false, false, false, utf8proc_sequences + 441},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 443, false, 290, -1, 290, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 446, false, -1, 293, -1, -1, -1, false, false, false, false, utf8proc_sequences + 449},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 451, false, 292, -1, 292, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 295, -1, -1, -1, false, false, false, false, utf8proc_sequences + 454},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 294, -1, 294, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 456, false, -1, 297, -1, -1, -1, false, false, false, false, utf8proc_sequences + 459},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 461, false, 296, -1, 296, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 464, false, -1, 299, -1, -1, -1, false, false, false, false, utf8proc_sequences + 467},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 469, false, 298, -1, 298, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 472, false, -1, 301, -1, -1, -1, false, false, false, false, utf8proc_sequences + 475},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 477, false, 300, -1, 300, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 480, false, -1, 303, -1, -1, -1, false, false, false, false, utf8proc_sequences + 483},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 485, false, 302, -1, 302, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 488, false, -1, 105, -1, -1, -1, false, false, false, false, utf8proc_sequences + 491},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 73, -1, 73, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 494, false, -1, 307, -1, -1, -1, false, false, false, false, utf8proc_sequences + 497},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 499, false, 306, -1, 306, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 502, false, -1, 309, -1, -1, -1, false, false, false, false, utf8proc_sequences + 505},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 507, false, 308, -1, 308, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 510, false, -1, 311, -1, -1, -1, false, false, false, false, utf8proc_sequences + 513},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 515, false, 310, -1, 310, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 518, false, -1, 314, -1, -1, -1, false, false, false, false, utf8proc_sequences + 521},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 523, false, 313, -1, 313, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 526, false, -1, 316, -1, -1, -1, false, false, false, false, utf8proc_sequences + 529},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 531, false, 315, -1, 315, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 534, false, -1, 318, -1, -1, -1, false, false, false, false, utf8proc_sequences + 537},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 539, false, 317, -1, 317, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 542, false, -1, 320, -1, -1, -1, false, false, false, false, utf8proc_sequences + 545},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 547, false, 319, -1, 319, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 322, -1, -1, -1, false, false, false, false, utf8proc_sequences + 550},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 321, -1, 321, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 552, false, -1, 324, -1, -1, -1, false, false, false, false, utf8proc_sequences + 555},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 557, false, 323, -1, 323, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 560, false, -1, 326, -1, -1, -1, false, false, false, false, utf8proc_sequences + 563},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 565, false, 325, -1, 325, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 568, false, -1, 328, -1, -1, -1, false, false, false, false, utf8proc_sequences + 571},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 573, false, 327, -1, 327, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 576, false, -1, -1, -1, -1, -1, false, false, false, false, utf8proc_sequences + 576},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 331, -1, -1, -1, false, false, false, false, utf8proc_sequences + 579},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 330, -1, 330, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 581, false, -1, 333, -1, 9600, -1, false, false, false, false, utf8proc_sequences + 584},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 586, false, 332, -1, 332, 9660, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 589, false, -1, 335, -1, -1, -1, false, false, false, false, utf8proc_sequences + 592},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 594, false, 334, -1, 334, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 597, false, -1, 337, -1, -1, -1, false, false, false, false, utf8proc_sequences + 600},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 602, false, 336, -1, 336, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 339, -1, -1, -1, false, false, false, false, utf8proc_sequences + 605},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 338, -1, 338, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 607, false, -1, 341, -1, -1, -1, false, false, false, false, utf8proc_sequences + 610},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 612, false, 340, -1, 340, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 615, false, -1, 343, -1, -1, -1, false, false, false, false, utf8proc_sequences + 618},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 620, false, 342, -1, 342, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 623, false, -1, 345, -1, -1, -1, false, false, false, false, utf8proc_sequences + 626},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 628, false, 344, -1, 344, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 631, false, -1, 347, -1, 9960, -1, false, false, false, false, utf8proc_sequences + 634},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 636, false, 346, -1, 346, 10020, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 639, false, -1, 349, -1, -1, -1, false, false, false, false, utf8proc_sequences + 642},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 644, false, 348, -1, 348, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 647, false, -1, 351, -1, -1, -1, false, false, false, false, utf8proc_sequences + 650},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 652, false, 350, -1, 350, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 655, false, -1, 353, -1, 10080, -1, false, false, false, false, utf8proc_sequences + 658},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 660, false, 352, -1, 352, 10140, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 663, false, -1, 355, -1, -1, -1, false, false, false, false, utf8proc_sequences + 666},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 668, false, 354, -1, 354, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 671, false, -1, 357, -1, -1, -1, false, false, false, false, utf8proc_sequences + 674},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 676, false, 356, -1, 356, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 359, -1, -1, -1, false, false, false, false, utf8proc_sequences + 679},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 358, -1, 358, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 681, false, -1, 361, -1, 10320, -1, false, false, false, false, utf8proc_sequences + 684},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 686, false, 360, -1, 360, 10380, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 689, false, -1, 363, -1, 10440, -1, false, false, false, false, utf8proc_sequences + 692},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 694, false, 362, -1, 362, 10500, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 697, false, -1, 365, -1, -1, -1, false, false, false, false, utf8proc_sequences + 700},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 702, false, 364, -1, 364, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 705, false, -1, 367, -1, -1, -1, false, false, false, false, utf8proc_sequences + 708},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 710, false, 366, -1, 366, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 713, false, -1, 369, -1, -1, -1, false, false, false, false, utf8proc_sequences + 716},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 718, false, 368, -1, 368, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 721, false, -1, 371, -1, -1, -1, false, false, false, false, utf8proc_sequences + 724},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 726, false, 370, -1, 370, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 729, false, -1, 373, -1, -1, -1, false, false, false, false, utf8proc_sequences + 732},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 734, false, 372, -1, 372, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 737, false, -1, 375, -1, -1, -1, false, false, false, false, utf8proc_sequences + 740},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 742, false, 374, -1, 374, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 745, false, -1, 255, -1, -1, -1, false, false, false, false, utf8proc_sequences + 748},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 750, false, -1, 378, -1, -1, -1, false, false, false, false, utf8proc_sequences + 753},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 755, false, 377, -1, 377, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 758, false, -1, 380, -1, -1, -1, false, false, false, false, utf8proc_sequences + 761},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 763, false, 379, -1, 379, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 766, false, -1, 382, -1, -1, -1, false, false, false, false, utf8proc_sequences + 769},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 771, false, 381, -1, 381, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 36, false, 83, -1, 83, 10800, -1, false, false, false, false, utf8proc_sequences + 36},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 579, -1, 579, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 595, -1, -1, -1, false, false, false, false, utf8proc_sequences + 774},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 387, -1, -1, -1, false, false, false, false, utf8proc_sequences + 776},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 386, -1, 386, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 389, -1, -1, -1, false, false, false, false, utf8proc_sequences + 778},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 388, -1, 388, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 596, -1, -1, -1, false, false, false, false, utf8proc_sequences + 780},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 392, -1, -1, -1, false, false, false, false, utf8proc_sequences + 782},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 391, -1, 391, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 598, -1, -1, -1, false, false, false, false, utf8proc_sequences + 784},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 599, -1, -1, -1, false, false, false, false, utf8proc_sequences + 786},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 396, -1, -1, -1, false, false, false, false, utf8proc_sequences + 788},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 395, -1, 395, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 477, -1, -1, -1, false, false, false, false, utf8proc_sequences + 790},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 601, -1, -1, -1, false, false, false, false, utf8proc_sequences + 792},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 603, -1, -1, -1, false, false, false, false, utf8proc_sequences + 794},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 402, -1, -1, -1, false, false, false, false, utf8proc_sequences + 796},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 401, -1, 401, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 608, -1, -1, -1, false, false, false, false, utf8proc_sequences + 798},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 611, -1, -1, -1, false, false, false, false, utf8proc_sequences + 800},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 502, -1, 502, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 617, -1, -1, -1, false, false, false, false, utf8proc_sequences + 802},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 616, -1, -1, -1, false, false, false, false, utf8proc_sequences + 804},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 409, -1, -1, -1, false, false, false, false, utf8proc_sequences + 806},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 408, -1, 408, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 573, -1, 573, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 623, -1, -1, -1, false, false, false, false, utf8proc_sequences + 808},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 626, -1, -1, -1, false, false, false, false, utf8proc_sequences + 810},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 544, -1, 544, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 629, -1, -1, -1, false, false, false, false, utf8proc_sequences + 812},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 814, false, -1, 417, -1, 11700, -1, false, false, false, false, utf8proc_sequences + 817},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 819, false, 416, -1, 416, 11760, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 419, -1, -1, -1, false, false, false, false, utf8proc_sequences + 822},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 418, -1, 418, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 421, -1, -1, -1, false, false, false, false, utf8proc_sequences + 824},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 420, -1, 420, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 640, -1, -1, -1, false, false, false, false, utf8proc_sequences + 826},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 424, -1, -1, -1, false, false, false, false, utf8proc_sequences + 828},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 423, -1, 423, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 643, -1, -1, -1, false, false, false, false, utf8proc_sequences + 830},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 429, -1, -1, -1, false, false, false, false, utf8proc_sequences + 832},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 428, -1, 428, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 648, -1, -1, -1, false, false, false, false, utf8proc_sequences + 834},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 836, false, -1, 432, -1, 11820, -1, false, false, false, false, utf8proc_sequences + 839},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 841, false, 431, -1, 431, 11880, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 650, -1, -1, -1, false, false, false, false, utf8proc_sequences + 844},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 651, -1, -1, -1, false, false, false, false, utf8proc_sequences + 846},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 436, -1, -1, -1, false, false, false, false, utf8proc_sequences + 848},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 435, -1, 435, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 438, -1, -1, -1, false, false, false, false, utf8proc_sequences + 850},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 437, -1, 437, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 658, -1, 2880, -1, false, false, false, false, utf8proc_sequences + 852},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 441, -1, -1, -1, false, false, false, false, utf8proc_sequences + 854},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 440, -1, 440, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 445, -1, -1, -1, false, false, false, false, utf8proc_sequences + 856},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 444, -1, 444, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 503, -1, 503, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 858, false, -1, 454, 453, -1, -1, false, false, false, false, utf8proc_sequences + 861},
+ {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 863, false, 452, 454, 453, -1, -1, false, false, false, false, utf8proc_sequences + 861},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 866, false, 452, -1, 453, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 869, false, -1, 457, 456, -1, -1, false, false, false, false, utf8proc_sequences + 872},
+ {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 874, false, 455, 457, 456, -1, -1, false, false, false, false, utf8proc_sequences + 872},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 877, false, 455, -1, 456, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 880, false, -1, 460, 459, -1, -1, false, false, false, false, utf8proc_sequences + 883},
+ {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 885, false, 458, 460, 459, -1, -1, false, false, false, false, utf8proc_sequences + 883},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 888, false, 458, -1, 459, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 891, false, -1, 462, -1, -1, -1, false, false, false, false, utf8proc_sequences + 894},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 896, false, 461, -1, 461, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 899, false, -1, 464, -1, -1, -1, false, false, false, false, utf8proc_sequences + 902},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 904, false, 463, -1, 463, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 907, false, -1, 466, -1, -1, -1, false, false, false, false, utf8proc_sequences + 910},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 912, false, 465, -1, 465, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 915, false, -1, 468, -1, -1, -1, false, false, false, false, utf8proc_sequences + 918},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 920, false, 467, -1, 467, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 923, false, -1, 470, -1, -1, -1, false, false, false, false, utf8proc_sequences + 926},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 928, false, 469, -1, 469, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 931, false, -1, 472, -1, -1, -1, false, false, false, false, utf8proc_sequences + 934},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 936, false, 471, -1, 471, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 939, false, -1, 474, -1, -1, -1, false, false, false, false, utf8proc_sequences + 942},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 944, false, 473, -1, 473, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 947, false, -1, 476, -1, -1, -1, false, false, false, false, utf8proc_sequences + 950},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 952, false, 475, -1, 475, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 398, -1, 398, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 955, false, -1, 479, -1, -1, -1, false, false, false, false, utf8proc_sequences + 958},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 960, false, 478, -1, 478, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 963, false, -1, 481, -1, -1, -1, false, false, false, false, utf8proc_sequences + 966},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 968, false, 480, -1, 480, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 971, false, -1, 483, -1, -1, -1, false, false, false, false, utf8proc_sequences + 974},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 976, false, 482, -1, 482, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 485, -1, -1, -1, false, false, false, false, utf8proc_sequences + 979},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 484, -1, 484, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 981, false, -1, 487, -1, -1, -1, false, false, false, false, utf8proc_sequences + 984},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 986, false, 486, -1, 486, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 989, false, -1, 489, -1, -1, -1, false, false, false, false, utf8proc_sequences + 992},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 994, false, 488, -1, 488, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 997, false, -1, 491, -1, 2760, -1, false, false, false, false, utf8proc_sequences + 1000},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1002, false, 490, -1, 490, 2820, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1005, false, -1, 493, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1008},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1010, false, 492, -1, 492, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1013, false, -1, 495, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1016},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1018, false, 494, -1, 494, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1021, false, -1, -1, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1021},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 1024, false, -1, 499, 498, -1, -1, false, false, false, false, utf8proc_sequences + 1027},
+ {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 1029, false, 497, 499, 498, -1, -1, false, false, false, false, utf8proc_sequences + 1027},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 1032, false, 497, -1, 498, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1035, false, -1, 501, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1038},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1040, false, 500, -1, 500, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 405, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1043},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 447, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1045},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1047, false, -1, 505, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1050},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1052, false, 504, -1, 504, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1055, false, -1, 507, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1058},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1060, false, 506, -1, 506, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1063, false, -1, 509, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1066},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1068, false, 508, -1, 508, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1071, false, -1, 511, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1074},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1076, false, 510, -1, 510, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1079, false, -1, 513, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1082},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1084, false, 512, -1, 512, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1087, false, -1, 515, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1090},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1092, false, 514, -1, 514, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1095, false, -1, 517, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1098},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1100, false, 516, -1, 516, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1103, false, -1, 519, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1106},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1108, false, 518, -1, 518, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1111, false, -1, 521, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1114},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1116, false, 520, -1, 520, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1119, false, -1, 523, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1122},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1124, false, 522, -1, 522, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1127, false, -1, 525, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1130},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1132, false, 524, -1, 524, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1135, false, -1, 527, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1138},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1140, false, 526, -1, 526, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1143, false, -1, 529, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1146},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1148, false, 528, -1, 528, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1151, false, -1, 531, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1154},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1156, false, 530, -1, 530, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1159, false, -1, 533, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1162},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1164, false, 532, -1, 532, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1167, false, -1, 535, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1170},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1172, false, 534, -1, 534, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1175, false, -1, 537, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1178},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1180, false, 536, -1, 536, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1183, false, -1, 539, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1186},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1188, false, 538, -1, 538, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 541, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1191},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 540, -1, 540, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1193, false, -1, 543, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1196},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1198, false, 542, -1, 542, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 414, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1201},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 547, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1203},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 546, -1, 546, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 549, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1205},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 548, -1, 548, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1207, false, -1, 551, -1, 2520, -1, false, false, false, false, utf8proc_sequences + 1210},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1212, false, 550, -1, 550, 2580, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1215, false, -1, 553, -1, 9000, -1, false, false, false, false, utf8proc_sequences + 1218},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1220, false, 552, -1, 552, 9060, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1223, false, -1, 555, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1226},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1228, false, 554, -1, 554, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1231, false, -1, 557, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1234},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1236, false, 556, -1, 556, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1239, false, -1, 559, -1, 3480, -1, false, false, false, false, utf8proc_sequences + 1242},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1244, false, 558, -1, 558, 3540, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1247, false, -1, 561, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1250},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1252, false, 560, -1, 560, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1255, false, -1, 563, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1258},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1260, false, 562, -1, 562, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11365, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1263},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 572, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1265},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 571, -1, 571, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 410, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1267},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11366, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1269},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 578, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1271},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 577, -1, 577, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 384, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1273},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 649, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1275},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 652, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1277},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 583, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1279},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 582, -1, 582, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 585, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1281},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 584, -1, 584, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 587, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1283},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 586, -1, 586, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 589, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1285},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 588, -1, 588, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 591, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1287},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 590, -1, 590, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 385, -1, 385, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 390, -1, 390, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 393, -1, 393, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 394, -1, 394, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 399, -1, 399, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 400, -1, 400, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 403, -1, 403, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 404, -1, 404, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 407, -1, 407, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 406, -1, 406, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11362, -1, 11362, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 412, -1, 412, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 413, -1, 413, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 415, -1, 415, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11364, -1, 11364, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 422, -1, 422, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 425, -1, 425, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 430, -1, 430, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 580, -1, 580, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 433, -1, 433, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 434, -1, 434, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 581, -1, 581, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 439, -1, 439, 2940, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 14, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 1289, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 18, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 34, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 1291, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 1293, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 1295, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 44, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 48, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 1297, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 1300, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 1303, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 1306, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 1309, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 1312, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 800, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 22, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 36, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 46, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 1315, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_MN, 230, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, 0, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MN, 230, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, 1, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MN, 230, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, 2, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MN, 230, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, 3, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MN, 230, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, 7, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MN, 230, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MN, 230, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, 8, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MN, 230, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, 10, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MN, 230, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, 4, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MN, 230, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, 46, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MN, 230, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, 5, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MN, 230, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, 12, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MN, 230, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, 11, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MN, 230, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, 14, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MN, 230, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, 15, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MN, 230, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, 47, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MN, 230, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, 48, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MN, 232, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MN, 220, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MN, 216, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, 13, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MN, 202, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MN, 220, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, 40, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MN, 220, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, 45, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MN, 220, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, 39, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MN, 220, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, 16, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MN, 202, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, 6, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MN, 202, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, 9, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MN, 220, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, 42, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MN, 220, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, 44, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MN, 220, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, 43, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MN, 220, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, 41, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MN, 1, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MN, 1, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, 51, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MN, 230, UTF8PROC_BIDI_CLASS_NSM, 0, utf8proc_sequences + 1317, false, -1, -1, -1, -1, -1, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MN, 230, UTF8PROC_BIDI_CLASS_NSM, 0, utf8proc_sequences + 1319, false, -1, -1, -1, -1, -1, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MN, 230, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, 49, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MN, 230, UTF8PROC_BIDI_CLASS_NSM, 0, utf8proc_sequences + 1321, false, -1, -1, -1, -1, -1, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MN, 230, UTF8PROC_BIDI_CLASS_NSM, 0, utf8proc_sequences + 1323, false, -1, -1, -1, -1, -1, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MN, 240, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, 921, -1, 921, -1, 50, false, false, false, true, utf8proc_sequences + 1326},
+ {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, true, false, true, NULL},
+ {UTF8PROC_CATEGORY_MN, 233, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MN, 234, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 1328, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 1330, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1021, -1, 1021, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1022, -1, 1022, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1023, -1, 1023, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 1333, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 1335, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1338, false, -1, 940, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1341},
+ {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 1343, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1345, false, -1, 941, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1348},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1350, false, -1, 942, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1353},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1355, false, -1, 943, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1358},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1360, false, -1, 972, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1363},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1365, false, -1, 973, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1368},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1370, false, -1, 974, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1373},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1375, false, -1, -1, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1378},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 945, -1, 3660, -1, false, false, false, false, utf8proc_sequences + 1382},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 946, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1384},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 947, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1386},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 948, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1388},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 949, -1, 3720, -1, false, false, false, false, utf8proc_sequences + 1390},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 950, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1392},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 951, -1, 3780, -1, false, false, false, false, utf8proc_sequences + 1394},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 952, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1396},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 953, -1, 3840, -1, false, false, false, false, utf8proc_sequences + 1326},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 954, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1398},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 955, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1400},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 956, -1, -1, -1, false, false, false, false, utf8proc_sequences + 67},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 957, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1402},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 958, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1404},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 959, -1, 3900, -1, false, false, false, false, utf8proc_sequences + 1406},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 960, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1408},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 961, -1, 16260, -1, false, false, false, false, utf8proc_sequences + 1410},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 963, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1412},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 964, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1414},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 965, -1, 3960, -1, false, false, false, false, utf8proc_sequences + 1416},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 966, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1418},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 967, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1420},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 968, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1422},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 969, -1, 4020, -1, false, false, false, false, utf8proc_sequences + 1424},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1426, false, -1, 970, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1429},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1431, false, -1, 971, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1434},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1436, false, 902, -1, 902, 15780, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1439, false, 904, -1, 904, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1442, false, 905, -1, 905, 15960, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1445, false, 906, -1, 906, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1448, false, -1, -1, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1451},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 913, -1, 913, 4140, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 914, -1, 914, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 915, -1, 915, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 916, -1, 916, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 917, -1, 917, 4200, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 918, -1, 918, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 919, -1, 919, 4260, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 920, -1, 920, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 921, -1, 921, 4320, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 922, -1, 922, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 923, -1, 923, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 924, -1, 924, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 925, -1, 925, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 926, -1, 926, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 927, -1, 927, 4500, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 928, -1, 928, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 929, -1, 929, 16200, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 931, -1, 931, -1, -1, false, false, false, false, utf8proc_sequences + 1412},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 931, -1, 931, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 932, -1, 932, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 933, -1, 933, 4440, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 934, -1, 934, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 935, -1, 935, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 936, -1, 936, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 937, -1, 937, 4560, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1455, false, 938, -1, 938, 4080, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1458, false, 939, -1, 939, 4380, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1461, false, 908, -1, 908, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1464, false, 910, -1, 910, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1467, false, 911, -1, 911, 16380, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 1384, false, 914, -1, 914, -1, -1, false, false, false, false, utf8proc_sequences + 1384},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 1396, false, 920, -1, 920, -1, -1, false, false, false, false, utf8proc_sequences + 1396},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 1470, false, -1, -1, -1, 4620, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1472, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1475, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 1418, false, 934, -1, 934, -1, -1, false, false, false, false, utf8proc_sequences + 1418},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 1408, false, 928, -1, 928, -1, -1, false, false, false, false, utf8proc_sequences + 1408},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 985, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1478},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 984, -1, 984, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 987, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1480},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 986, -1, 986, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 989, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1482},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 988, -1, 988, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 991, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1484},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 990, -1, 990, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 993, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1486},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 992, -1, 992, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 995, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1488},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 994, -1, 994, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 997, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1490},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 996, -1, 996, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 999, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1492},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 998, -1, 998, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1001, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1494},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1000, -1, 1000, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1003, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1496},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1002, -1, 1002, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1005, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1498},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1004, -1, 1004, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1007, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1500},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1006, -1, 1006, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 1398, false, 922, -1, 922, -1, -1, false, false, false, false, utf8proc_sequences + 1398},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 1410, false, 929, -1, 929, -1, -1, false, false, false, false, utf8proc_sequences + 1410},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 1502, false, 1017, -1, 1017, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 1504, false, -1, 952, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1396},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 1390, false, 917, -1, 917, -1, -1, false, false, false, false, utf8proc_sequences + 1390},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1016, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1506},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1015, -1, 1015, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 1508, false, -1, 1010, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1510},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1019, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1512},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1018, -1, 1018, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 891, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1514},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 892, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1516},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 893, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1518},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1520, false, -1, 1104, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1523},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1525, false, -1, 1105, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1528},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1106, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1530},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1532, false, -1, 1107, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1535},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1108, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1537},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1109, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1539},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1110, -1, 4800, -1, false, false, false, false, utf8proc_sequences + 1541},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1543, false, -1, 1111, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1546},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1112, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1548},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1113, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1550},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1114, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1552},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1115, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1554},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1556, false, -1, 1116, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1559},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1561, false, -1, 1117, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1564},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1566, false, -1, 1118, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1569},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1119, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1571},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1072, -1, 5640, -1, false, false, false, false, utf8proc_sequences + 1573},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1073, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1575},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1074, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1577},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1075, -1, 4740, -1, false, false, false, false, utf8proc_sequences + 1579},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1076, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1581},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1077, -1, 4680, -1, false, false, false, false, utf8proc_sequences + 1583},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1078, -1, 5520, -1, false, false, false, false, utf8proc_sequences + 1585},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1079, -1, 5880, -1, false, false, false, false, utf8proc_sequences + 1587},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1080, -1, 4920, -1, false, false, false, false, utf8proc_sequences + 1589},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1591, false, -1, 1081, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1594},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1082, -1, 4860, -1, false, false, false, false, utf8proc_sequences + 1596},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1083, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1598},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1084, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1600},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1085, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1602},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1086, -1, 6000, -1, false, false, false, false, utf8proc_sequences + 1604},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1087, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1606},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1088, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1608},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1089, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1610},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1090, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1612},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1091, -1, 4980, -1, false, false, false, false, utf8proc_sequences + 1614},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1092, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1616},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1093, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1618},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1094, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1620},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1095, -1, 6360, -1, false, false, false, false, utf8proc_sequences + 1622},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1096, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1624},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1097, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1626},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1098, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1628},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1099, -1, 6480, -1, false, false, false, false, utf8proc_sequences + 1630},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1100, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1632},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1101, -1, 6240, -1, false, false, false, false, utf8proc_sequences + 1634},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1102, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1636},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1103, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1638},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1040, -1, 1040, 5700, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1041, -1, 1041, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1042, -1, 1042, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1043, -1, 1043, 5160, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1044, -1, 1044, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1045, -1, 1045, 5100, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1046, -1, 1046, 5580, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1047, -1, 1047, 5940, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1048, -1, 1048, 5040, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1640, false, 1049, -1, 1049, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1050, -1, 1050, 5280, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1051, -1, 1051, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1052, -1, 1052, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1053, -1, 1053, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1054, -1, 1054, 6060, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1055, -1, 1055, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1056, -1, 1056, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1057, -1, 1057, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1058, -1, 1058, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1059, -1, 1059, 5340, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1060, -1, 1060, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1061, -1, 1061, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1062, -1, 1062, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1063, -1, 1063, 6420, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1064, -1, 1064, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1065, -1, 1065, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1066, -1, 1066, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1067, -1, 1067, 6540, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1068, -1, 1068, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1069, -1, 1069, 6300, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1070, -1, 1070, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1071, -1, 1071, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1643, false, 1024, -1, 1024, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1646, false, 1025, -1, 1025, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1026, -1, 1026, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1649, false, 1027, -1, 1027, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1028, -1, 1028, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1029, -1, 1029, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1030, -1, 1030, 5220, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1652, false, 1031, -1, 1031, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1032, -1, 1032, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1033, -1, 1033, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1034, -1, 1034, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1035, -1, 1035, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1655, false, 1036, -1, 1036, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1658, false, 1037, -1, 1037, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1661, false, 1038, -1, 1038, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1039, -1, 1039, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1121, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1664},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1120, -1, 1120, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1123, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1666},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1122, -1, 1122, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1125, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1668},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1124, -1, 1124, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1127, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1670},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1126, -1, 1126, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1129, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1672},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1128, -1, 1128, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1131, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1674},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1130, -1, 1130, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1133, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1676},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1132, -1, 1132, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1135, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1678},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1134, -1, 1134, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1137, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1680},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1136, -1, 1136, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1139, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1682},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1138, -1, 1138, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1141, -1, 5400, -1, false, false, false, false, utf8proc_sequences + 1684},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1140, -1, 1140, 5460, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1686, false, -1, 1143, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1689},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1691, false, 1142, -1, 1142, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1145, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1694},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1144, -1, 1144, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1147, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1696},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1146, -1, 1146, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1149, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1698},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1148, -1, 1148, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1151, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1700},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1150, -1, 1150, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1153, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1702},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1152, -1, 1152, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_ME, 0, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1163, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1704},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1162, -1, 1162, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1165, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1706},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1164, -1, 1164, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1167, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1708},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1166, -1, 1166, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1169, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1710},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1168, -1, 1168, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1171, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1712},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1170, -1, 1170, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1173, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1714},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1172, -1, 1172, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1175, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1716},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1174, -1, 1174, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1177, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1718},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1176, -1, 1176, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1179, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1720},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1178, -1, 1178, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1181, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1722},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1180, -1, 1180, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1183, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1724},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1182, -1, 1182, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1185, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1726},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1184, -1, 1184, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1187, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1728},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1186, -1, 1186, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1189, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1730},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1188, -1, 1188, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1191, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1732},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1190, -1, 1190, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1193, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1734},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1192, -1, 1192, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1195, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1736},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1194, -1, 1194, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1197, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1738},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1196, -1, 1196, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1199, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1740},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1198, -1, 1198, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1201, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1742},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1200, -1, 1200, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1203, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1744},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1202, -1, 1202, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1205, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1746},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1204, -1, 1204, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1207, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1748},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1206, -1, 1206, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1209, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1750},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1208, -1, 1208, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1211, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1752},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1210, -1, 1210, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1213, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1754},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1212, -1, 1212, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1215, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1756},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1214, -1, 1214, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1231, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1758},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1760, false, -1, 1218, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1763},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1765, false, 1217, -1, 1217, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1220, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1768},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1219, -1, 1219, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1222, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1770},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1221, -1, 1221, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1224, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1772},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1223, -1, 1223, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1226, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1774},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1225, -1, 1225, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1228, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1776},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1227, -1, 1227, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1230, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1778},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1229, -1, 1229, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1216, -1, 1216, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1780, false, -1, 1233, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1783},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1785, false, 1232, -1, 1232, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1788, false, -1, 1235, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1791},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1793, false, 1234, -1, 1234, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1237, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1796},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1236, -1, 1236, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1798, false, -1, 1239, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1801},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1803, false, 1238, -1, 1238, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1241, -1, 5760, -1, false, false, false, false, utf8proc_sequences + 1806},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1240, -1, 1240, 5820, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1808, false, -1, 1243, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1811},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1813, false, 1242, -1, 1242, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1816, false, -1, 1245, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1819},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1821, false, 1244, -1, 1244, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1824, false, -1, 1247, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1827},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1829, false, 1246, -1, 1246, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1249, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1832},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1248, -1, 1248, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1834, false, -1, 1251, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1837},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1839, false, 1250, -1, 1250, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1842, false, -1, 1253, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1845},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1847, false, 1252, -1, 1252, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1850, false, -1, 1255, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1853},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1855, false, 1254, -1, 1254, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1257, -1, 6120, -1, false, false, false, false, utf8proc_sequences + 1858},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1256, -1, 1256, 6180, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1860, false, -1, 1259, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1863},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1865, false, 1258, -1, 1258, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1868, false, -1, 1261, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1871},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1873, false, 1260, -1, 1260, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1876, false, -1, 1263, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1879},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1881, false, 1262, -1, 1262, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1884, false, -1, 1265, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1887},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1889, false, 1264, -1, 1264, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1892, false, -1, 1267, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1895},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1897, false, 1266, -1, 1266, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1900, false, -1, 1269, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1903},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1905, false, 1268, -1, 1268, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1271, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1908},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1270, -1, 1270, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1910, false, -1, 1273, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1913},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1915, false, 1272, -1, 1272, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1275, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1918},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1274, -1, 1274, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1277, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1920},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1276, -1, 1276, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1279, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1922},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1278, -1, 1278, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1281, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1924},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1280, -1, 1280, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1283, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1926},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1282, -1, 1282, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1285, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1928},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1284, -1, 1284, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1287, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1930},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1286, -1, 1286, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1289, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1932},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1288, -1, 1288, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1291, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1934},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1290, -1, 1290, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1293, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1936},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1292, -1, 1292, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1295, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1938},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1294, -1, 1294, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1297, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1940},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1296, -1, 1296, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1299, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1942},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1298, -1, 1298, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1377, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1944},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1378, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1946},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1379, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1948},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1380, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1950},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1381, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1952},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1382, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1954},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1383, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1956},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1384, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1958},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1385, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1960},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1386, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1962},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1387, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1964},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1388, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1966},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1389, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1968},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1390, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1970},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1391, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1972},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1392, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1974},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1393, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1976},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1394, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1978},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1395, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1980},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1396, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1982},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1397, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1984},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1398, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1986},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1399, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1988},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1400, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1990},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1401, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1992},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1402, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1994},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1403, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1996},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1404, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1998},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1405, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2000},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1406, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2002},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1407, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2004},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1408, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2006},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1409, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2008},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1410, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2010},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1411, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2012},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1412, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2014},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1413, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2016},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 1414, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2018},
+ {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1329, -1, 1329, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1330, -1, 1330, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1331, -1, 1331, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1332, -1, 1332, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1333, -1, 1333, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1334, -1, 1334, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1335, -1, 1335, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1336, -1, 1336, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1337, -1, 1337, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1338, -1, 1338, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1339, -1, 1339, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1340, -1, 1340, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1341, -1, 1341, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1342, -1, 1342, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1343, -1, 1343, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1344, -1, 1344, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1345, -1, 1345, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1346, -1, 1346, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1347, -1, 1347, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1348, -1, 1348, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1349, -1, 1349, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1350, -1, 1350, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1351, -1, 1351, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1352, -1, 1352, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1353, -1, 1353, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1354, -1, 1354, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1355, -1, 1355, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1356, -1, 1356, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1357, -1, 1357, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1358, -1, 1358, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1359, -1, 1359, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1360, -1, 1360, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1361, -1, 1361, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1362, -1, 1362, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1363, -1, 1363, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1364, -1, 1364, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1365, -1, 1365, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 1366, -1, 1366, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 2020, false, -1, -1, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2020},
+ {UTF8PROC_CATEGORY_PD, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_MN, 222, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MN, 228, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MN, 10, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MN, 11, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MN, 12, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MN, 13, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MN, 14, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MN, 15, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MN, 16, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MN, 17, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MN, 18, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MN, 19, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MN, 20, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MN, 21, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MN, 22, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_R, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_MN, 23, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MN, 24, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MN, 25, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_CF, 0, UTF8PROC_BIDI_CLASS_AL, 0, NULL, false, -1, -1, -1, -1, -1, false, true, true, false, NULL},
+ {UTF8PROC_CATEGORY_SC, 0, UTF8PROC_BIDI_CLASS_AL, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_AL, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, 0, utf8proc_sequences + 2023, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, 0, utf8proc_sequences + 2026, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, 0, utf8proc_sequences + 2029, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, 0, utf8proc_sequences + 2032, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, 0, utf8proc_sequences + 2035, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, 0, NULL, false, -1, -1, -1, 6600, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_AL, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, 0, NULL, false, -1, -1, -1, 6660, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, 0, NULL, false, -1, -1, -1, 6720, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_MN, 27, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MN, 28, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MN, 29, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MN, 30, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MN, 31, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MN, 32, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MN, 33, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MN, 34, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MN, 230, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, 17, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MN, 230, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, 18, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MN, 220, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, 19, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_ND, 0, UTF8PROC_BIDI_CLASS_AN, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_AN, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_MN, 35, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 2038, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 2041, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 2044, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 2047, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, 0, utf8proc_sequences + 2050, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, 0, NULL, false, -1, -1, -1, 6840, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, 0, utf8proc_sequences + 2053, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, 0, NULL, false, -1, -1, -1, 6900, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, 0, utf8proc_sequences + 2056, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, 0, NULL, false, -1, -1, -1, 6780, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_AL, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_MN, 36, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_ND, 0, UTF8PROC_BIDI_CLASS_R, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_R, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 6960, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2059, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 7020, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2062, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 7080, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2065, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_MN, 7, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, 20, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MN, 9, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2068, false, -1, -1, -1, -1, -1, true, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2071, false, -1, -1, -1, -1, -1, true, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2074, false, -1, -1, -1, -1, -1, true, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2077, false, -1, -1, -1, -1, -1, true, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2080, false, -1, -1, -1, -1, -1, true, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2083, false, -1, -1, -1, -1, -1, true, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2086, false, -1, -1, -1, -1, -1, true, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2089, false, -1, -1, -1, -1, -1, true, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_ND, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_MN, 7, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, -1, 21, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 7140, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2092, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2095, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, -1, 22, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2098, false, -1, -1, -1, -1, -1, true, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2101, false, -1, -1, -1, -1, -1, true, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2104, false, -1, -1, -1, -1, -1, true, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2107, false, -1, -1, -1, -1, -1, true, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2110, false, -1, -1, -1, -1, -1, true, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2113, false, -1, -1, -1, -1, -1, true, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2116, false, -1, -1, -1, -1, -1, true, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2119, false, -1, -1, -1, -1, -1, true, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2122, false, -1, -1, -1, -1, -1, true, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, -1, 24, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 7200, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2125, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2128, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2131, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, 23, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, -1, 25, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2134, false, -1, -1, -1, -1, -1, true, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2137, false, -1, -1, -1, -1, -1, true, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 7260, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2140, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, -1, 27, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 7320, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 7380, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2143, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2146, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2149, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, -1, 26, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, 7440, -1, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_NSM, 0, utf8proc_sequences + 2152, false, -1, -1, -1, -1, -1, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MN, 84, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MN, 91, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, 28, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 7500, -1, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2155, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, -1, 31, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 7560, -1, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2158, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2161, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2164, false, -1, -1, -1, 7620, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2167, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, -1, 29, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, -1, 30, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, -1, 32, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 7680, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 7740, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2170, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2173, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2176, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, -1, 33, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MN, 9, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, 34, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, -1, 35, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 7800, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2179, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2182, false, -1, -1, -1, 7860, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2185, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2188, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, -1, 36, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 2191, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_MN, 103, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MN, 107, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 2194, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_MN, 118, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MN, 122, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 2197, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 2200, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NOBREAK, utf8proc_sequences + 2203, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_MN, 216, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2205, false, -1, -1, -1, -1, -1, true, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2208, false, -1, -1, -1, -1, -1, true, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2211, false, -1, -1, -1, -1, -1, true, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2214, false, -1, -1, -1, -1, -1, true, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2217, false, -1, -1, -1, -1, -1, true, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2220, false, -1, -1, -1, -1, -1, true, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_MN, 129, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MN, 130, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_NSM, 0, utf8proc_sequences + 2223, false, -1, -1, -1, -1, -1, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MN, 132, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_NSM, 0, utf8proc_sequences + 2226, false, -1, -1, -1, -1, -1, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_NSM, 0, utf8proc_sequences + 2229, false, -1, -1, -1, -1, -1, true, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_NSM, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 2232, false, -1, -1, -1, -1, -1, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_NSM, 0, utf8proc_sequences + 2235, false, -1, -1, -1, -1, -1, true, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_NSM, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 2238, false, -1, -1, -1, -1, -1, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_NSM, 0, utf8proc_sequences + 2241, false, -1, -1, -1, -1, -1, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_NSM, 0, utf8proc_sequences + 2244, false, -1, -1, -1, -1, -1, true, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_NSM, 0, utf8proc_sequences + 2247, false, -1, -1, -1, -1, -1, true, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_NSM, 0, utf8proc_sequences + 2250, false, -1, -1, -1, -1, -1, true, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_NSM, 0, utf8proc_sequences + 2253, false, -1, -1, -1, -1, -1, true, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_NSM, 0, utf8proc_sequences + 2256, false, -1, -1, -1, -1, -1, true, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_NSM, 0, utf8proc_sequences + 2259, false, -1, -1, -1, -1, -1, true, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 7920, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2262, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, 37, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11520, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2265},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11521, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2267},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11522, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2269},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11523, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2271},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11524, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2273},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11525, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2275},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11526, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2277},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11527, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2279},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11528, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2281},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11529, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2283},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11530, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2285},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11531, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2287},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11532, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2289},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11533, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2291},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11534, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2293},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11535, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2295},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11536, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2297},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11537, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2299},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11538, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2301},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11539, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2303},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11540, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2305},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11541, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2307},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11542, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2309},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11543, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2311},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11544, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2313},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11545, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2315},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11546, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2317},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11547, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2319},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11548, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2321},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11549, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2323},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11550, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2325},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11551, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2327},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11552, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2329},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11553, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2331},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11554, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2333},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11555, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2335},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11556, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2337},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11557, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2339},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2341, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, -1, -1, false, true, false, false, NULL},
+ {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_CF, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, -1, -1, false, true, true, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 7980, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2343, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 8040, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2346, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 8100, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2349, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 8160, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2352, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 8220, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2355, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 8280, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2358, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, -1, 38, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, 8340, -1, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2361, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, 8400, -1, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2364, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 8460, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 8520, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2367, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2370, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_MN, 0, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, 8580, -1, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MC, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2373, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_MC, 9, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2376, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2378, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2380, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2382, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2384, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2386, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2388, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2390, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2392, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2394, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2396, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2398, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2400, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2402, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2404, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2406, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2408, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2410, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2412, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2414, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2416, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 0, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2418, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2420, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2422, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 6, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 8, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 792, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 794, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2424, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 12, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 20, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 24, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 579, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 28, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 780, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2426, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2428, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 30, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 38, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 40, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2430, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 808, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 42, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2432, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 1384, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 1386, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 1388, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 1418, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 1420, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUB, utf8proc_sequences + 16, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUB, utf8proc_sequences + 34, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUB, utf8proc_sequences + 40, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUB, utf8proc_sequences + 42, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUB, utf8proc_sequences + 1384, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUB, utf8proc_sequences + 1386, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUB, utf8proc_sequences + 1410, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUB, utf8proc_sequences + 1418, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUB, utf8proc_sequences + 1420, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 1602, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11363, -1, 11363, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2434, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 4, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2436, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 163, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 10, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2438, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2440, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2442, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 804, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 802, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2444, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2446, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2448, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2450, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2452, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2454, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2456, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2458, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 810, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2460, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2462, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 812, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2464, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2466, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 830, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2468, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 1275, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 844, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2470, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 846, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 1277, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 50, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2472, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 2474, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 852, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 1396, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2476, false, -1, 7681, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2479},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2481, false, 7680, -1, 7680, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2484, false, -1, 7683, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2487},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2489, false, 7682, -1, 7682, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2492, false, -1, 7685, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2495},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2497, false, 7684, -1, 7684, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2500, false, -1, 7687, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2503},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2505, false, 7686, -1, 7686, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2508, false, -1, 7689, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2511},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2513, false, 7688, -1, 7688, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2516, false, -1, 7691, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2519},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2521, false, 7690, -1, 7690, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2524, false, -1, 7693, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2527},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2529, false, 7692, -1, 7692, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2532, false, -1, 7695, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2535},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2537, false, 7694, -1, 7694, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2540, false, -1, 7697, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2543},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2545, false, 7696, -1, 7696, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2548, false, -1, 7699, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2551},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2553, false, 7698, -1, 7698, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2556, false, -1, 7701, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2559},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2561, false, 7700, -1, 7700, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2564, false, -1, 7703, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2567},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2569, false, 7702, -1, 7702, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2572, false, -1, 7705, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2575},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2577, false, 7704, -1, 7704, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2580, false, -1, 7707, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2583},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2585, false, 7706, -1, 7706, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2588, false, -1, 7709, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2591},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2593, false, 7708, -1, 7708, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2596, false, -1, 7711, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2599},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2601, false, 7710, -1, 7710, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2604, false, -1, 7713, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2607},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2609, false, 7712, -1, 7712, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2612, false, -1, 7715, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2615},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2617, false, 7714, -1, 7714, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2620, false, -1, 7717, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2623},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2625, false, 7716, -1, 7716, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2628, false, -1, 7719, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2631},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2633, false, 7718, -1, 7718, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2636, false, -1, 7721, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2639},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2641, false, 7720, -1, 7720, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2644, false, -1, 7723, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2647},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2649, false, 7722, -1, 7722, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2652, false, -1, 7725, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2655},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2657, false, 7724, -1, 7724, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2660, false, -1, 7727, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2663},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2665, false, 7726, -1, 7726, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2668, false, -1, 7729, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2671},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2673, false, 7728, -1, 7728, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2676, false, -1, 7731, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2679},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2681, false, 7730, -1, 7730, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2684, false, -1, 7733, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2687},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2689, false, 7732, -1, 7732, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2692, false, -1, 7735, -1, 9360, -1, false, false, false, false, utf8proc_sequences + 2695},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2697, false, 7734, -1, 7734, 9420, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2700, false, -1, 7737, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2703},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2705, false, 7736, -1, 7736, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2708, false, -1, 7739, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2711},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2713, false, 7738, -1, 7738, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2716, false, -1, 7741, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2719},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2721, false, 7740, -1, 7740, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2724, false, -1, 7743, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2727},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2729, false, 7742, -1, 7742, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2732, false, -1, 7745, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2735},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2737, false, 7744, -1, 7744, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2740, false, -1, 7747, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2743},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2745, false, 7746, -1, 7746, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2748, false, -1, 7749, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2751},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2753, false, 7748, -1, 7748, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2756, false, -1, 7751, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2759},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2761, false, 7750, -1, 7750, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2764, false, -1, 7753, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2767},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2769, false, 7752, -1, 7752, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2772, false, -1, 7755, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2775},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2777, false, 7754, -1, 7754, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2780, false, -1, 7757, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2783},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2785, false, 7756, -1, 7756, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2788, false, -1, 7759, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2791},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2793, false, 7758, -1, 7758, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2796, false, -1, 7761, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2799},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2801, false, 7760, -1, 7760, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2804, false, -1, 7763, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2807},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2809, false, 7762, -1, 7762, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2812, false, -1, 7765, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2815},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2817, false, 7764, -1, 7764, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2820, false, -1, 7767, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2823},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2825, false, 7766, -1, 7766, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2828, false, -1, 7769, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2831},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2833, false, 7768, -1, 7768, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2836, false, -1, 7771, -1, 9840, -1, false, false, false, false, utf8proc_sequences + 2839},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2841, false, 7770, -1, 7770, 9900, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2844, false, -1, 7773, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2847},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2849, false, 7772, -1, 7772, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2852, false, -1, 7775, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2855},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2857, false, 7774, -1, 7774, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2860, false, -1, 7777, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2863},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2865, false, 7776, -1, 7776, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2868, false, -1, 7779, -1, 10200, -1, false, false, false, false, utf8proc_sequences + 2871},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2873, false, 7778, -1, 7778, 10260, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2876, false, -1, 7781, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2879},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2881, false, 7780, -1, 7780, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2884, false, -1, 7783, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2887},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2889, false, 7782, -1, 7782, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2892, false, -1, 7785, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2895},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2897, false, 7784, -1, 7784, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2900, false, -1, 7787, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2903},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2905, false, 7786, -1, 7786, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2908, false, -1, 7789, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2911},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2913, false, 7788, -1, 7788, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2916, false, -1, 7791, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2919},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2921, false, 7790, -1, 7790, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2924, false, -1, 7793, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2927},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2929, false, 7792, -1, 7792, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2932, false, -1, 7795, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2935},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2937, false, 7794, -1, 7794, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2940, false, -1, 7797, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2943},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2945, false, 7796, -1, 7796, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2948, false, -1, 7799, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2951},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2953, false, 7798, -1, 7798, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2956, false, -1, 7801, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2959},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2961, false, 7800, -1, 7800, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2964, false, -1, 7803, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2967},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2969, false, 7802, -1, 7802, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2972, false, -1, 7805, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2975},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2977, false, 7804, -1, 7804, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2980, false, -1, 7807, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2983},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2985, false, 7806, -1, 7806, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2988, false, -1, 7809, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2991},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2993, false, 7808, -1, 7808, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2996, false, -1, 7811, -1, -1, -1, false, false, false, false, utf8proc_sequences + 2999},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3001, false, 7810, -1, 7810, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3004, false, -1, 7813, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3007},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3009, false, 7812, -1, 7812, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3012, false, -1, 7815, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3015},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3017, false, 7814, -1, 7814, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3020, false, -1, 7817, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3023},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3025, false, 7816, -1, 7816, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3028, false, -1, 7819, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3031},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3033, false, 7818, -1, 7818, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3036, false, -1, 7821, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3039},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3041, false, 7820, -1, 7820, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3044, false, -1, 7823, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3047},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3049, false, 7822, -1, 7822, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3052, false, -1, 7825, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3055},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3057, false, 7824, -1, 7824, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3060, false, -1, 7827, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3063},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3065, false, 7826, -1, 7826, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3068, false, -1, 7829, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3071},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3073, false, 7828, -1, 7828, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3076, false, -1, -1, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3076},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3079, false, -1, -1, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3079},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3082, false, -1, -1, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3082},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3085, false, -1, -1, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3085},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 3088, false, -1, -1, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3088},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3091, false, 7776, -1, 7776, -1, -1, false, false, false, false, utf8proc_sequences + 2863},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3094, false, -1, 7841, -1, 10980, -1, false, false, false, false, utf8proc_sequences + 3097},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3099, false, 7840, -1, 7840, 11040, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3102, false, -1, 7843, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3105},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3107, false, 7842, -1, 7842, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3110, false, -1, 7845, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3113},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3115, false, 7844, -1, 7844, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3118, false, -1, 7847, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3121},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3123, false, 7846, -1, 7846, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3126, false, -1, 7849, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3129},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3131, false, 7848, -1, 7848, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3134, false, -1, 7851, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3137},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3139, false, 7850, -1, 7850, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3142, false, -1, 7853, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3145},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3147, false, 7852, -1, 7852, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3150, false, -1, 7855, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3153},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3155, false, 7854, -1, 7854, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3158, false, -1, 7857, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3161},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3163, false, 7856, -1, 7856, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3166, false, -1, 7859, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3169},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3171, false, 7858, -1, 7858, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3174, false, -1, 7861, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3177},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3179, false, 7860, -1, 7860, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3182, false, -1, 7863, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3185},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3187, false, 7862, -1, 7862, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3190, false, -1, 7865, -1, 11340, -1, false, false, false, false, utf8proc_sequences + 3193},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3195, false, 7864, -1, 7864, 11400, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3198, false, -1, 7867, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3201},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3203, false, 7866, -1, 7866, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3206, false, -1, 7869, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3209},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3211, false, 7868, -1, 7868, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3214, false, -1, 7871, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3217},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3219, false, 7870, -1, 7870, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3222, false, -1, 7873, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3225},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3227, false, 7872, -1, 7872, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3230, false, -1, 7875, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3233},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3235, false, 7874, -1, 7874, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3238, false, -1, 7877, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3241},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3243, false, 7876, -1, 7876, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3246, false, -1, 7879, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3249},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3251, false, 7878, -1, 7878, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3254, false, -1, 7881, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3257},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3259, false, 7880, -1, 7880, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3262, false, -1, 7883, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3265},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3267, false, 7882, -1, 7882, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3270, false, -1, 7885, -1, 11580, -1, false, false, false, false, utf8proc_sequences + 3273},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3275, false, 7884, -1, 7884, 11640, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3278, false, -1, 7887, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3281},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3283, false, 7886, -1, 7886, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3286, false, -1, 7889, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3289},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3291, false, 7888, -1, 7888, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3294, false, -1, 7891, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3297},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3299, false, 7890, -1, 7890, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3302, false, -1, 7893, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3305},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3307, false, 7892, -1, 7892, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3310, false, -1, 7895, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3313},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3315, false, 7894, -1, 7894, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3318, false, -1, 7897, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3321},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3323, false, 7896, -1, 7896, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3326, false, -1, 7899, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3329},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3331, false, 7898, -1, 7898, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3334, false, -1, 7901, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3337},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3339, false, 7900, -1, 7900, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3342, false, -1, 7903, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3345},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3347, false, 7902, -1, 7902, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3350, false, -1, 7905, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3353},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3355, false, 7904, -1, 7904, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3358, false, -1, 7907, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3361},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3363, false, 7906, -1, 7906, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3366, false, -1, 7909, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3369},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3371, false, 7908, -1, 7908, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3374, false, -1, 7911, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3377},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3379, false, 7910, -1, 7910, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3382, false, -1, 7913, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3385},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3387, false, 7912, -1, 7912, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3390, false, -1, 7915, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3393},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3395, false, 7914, -1, 7914, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3398, false, -1, 7917, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3401},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3403, false, 7916, -1, 7916, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3406, false, -1, 7919, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3409},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3411, false, 7918, -1, 7918, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3414, false, -1, 7921, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3417},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3419, false, 7920, -1, 7920, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3422, false, -1, 7923, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3425},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3427, false, 7922, -1, 7922, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3430, false, -1, 7925, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3433},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3435, false, 7924, -1, 7924, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3438, false, -1, 7927, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3441},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3443, false, 7926, -1, 7926, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3446, false, -1, 7929, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3449},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3451, false, 7928, -1, 7928, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3454, false, 7944, -1, 7944, 11940, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3457, false, 7945, -1, 7945, 12000, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3460, false, 7946, -1, 7946, 13560, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3463, false, 7947, -1, 7947, 13620, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3466, false, 7948, -1, 7948, 13680, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3469, false, 7949, -1, 7949, 13740, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3472, false, 7950, -1, 7950, 13800, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3475, false, 7951, -1, 7951, 13860, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3478, false, -1, 7936, -1, 12060, -1, false, false, false, false, utf8proc_sequences + 3481},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3483, false, -1, 7937, -1, 12120, -1, false, false, false, false, utf8proc_sequences + 3486},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3488, false, -1, 7938, -1, 13920, -1, false, false, false, false, utf8proc_sequences + 3491},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3493, false, -1, 7939, -1, 13980, -1, false, false, false, false, utf8proc_sequences + 3496},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3498, false, -1, 7940, -1, 14040, -1, false, false, false, false, utf8proc_sequences + 3501},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3503, false, -1, 7941, -1, 14100, -1, false, false, false, false, utf8proc_sequences + 3506},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3508, false, -1, 7942, -1, 14160, -1, false, false, false, false, utf8proc_sequences + 3511},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3513, false, -1, 7943, -1, 14220, -1, false, false, false, false, utf8proc_sequences + 3516},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3518, false, 7960, -1, 7960, 12180, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3521, false, 7961, -1, 7961, 12240, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3524, false, 7962, -1, 7962, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3527, false, 7963, -1, 7963, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3530, false, 7964, -1, 7964, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3533, false, 7965, -1, 7965, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3536, false, -1, 7952, -1, 12300, -1, false, false, false, false, utf8proc_sequences + 3539},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3541, false, -1, 7953, -1, 12360, -1, false, false, false, false, utf8proc_sequences + 3544},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3546, false, -1, 7954, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3549},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3551, false, -1, 7955, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3554},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3556, false, -1, 7956, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3559},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3561, false, -1, 7957, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3564},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3566, false, 7976, -1, 7976, 12420, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3569, false, 7977, -1, 7977, 12480, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3572, false, 7978, -1, 7978, 14280, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3575, false, 7979, -1, 7979, 14340, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3578, false, 7980, -1, 7980, 14400, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3581, false, 7981, -1, 7981, 14460, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3584, false, 7982, -1, 7982, 14520, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3587, false, 7983, -1, 7983, 14580, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3590, false, -1, 7968, -1, 12540, -1, false, false, false, false, utf8proc_sequences + 3593},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3595, false, -1, 7969, -1, 12600, -1, false, false, false, false, utf8proc_sequences + 3598},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3600, false, -1, 7970, -1, 14640, -1, false, false, false, false, utf8proc_sequences + 3603},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3605, false, -1, 7971, -1, 14700, -1, false, false, false, false, utf8proc_sequences + 3608},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3610, false, -1, 7972, -1, 14760, -1, false, false, false, false, utf8proc_sequences + 3613},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3615, false, -1, 7973, -1, 14820, -1, false, false, false, false, utf8proc_sequences + 3618},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3620, false, -1, 7974, -1, 14880, -1, false, false, false, false, utf8proc_sequences + 3623},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3625, false, -1, 7975, -1, 14940, -1, false, false, false, false, utf8proc_sequences + 3628},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3630, false, 7992, -1, 7992, 12660, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3633, false, 7993, -1, 7993, 12720, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3636, false, 7994, -1, 7994, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3639, false, 7995, -1, 7995, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3642, false, 7996, -1, 7996, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3645, false, 7997, -1, 7997, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3648, false, 7998, -1, 7998, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3651, false, 7999, -1, 7999, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3654, false, -1, 7984, -1, 12780, -1, false, false, false, false, utf8proc_sequences + 3657},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3659, false, -1, 7985, -1, 12840, -1, false, false, false, false, utf8proc_sequences + 3662},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3664, false, -1, 7986, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3667},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3669, false, -1, 7987, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3672},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3674, false, -1, 7988, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3677},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3679, false, -1, 7989, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3682},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3684, false, -1, 7990, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3687},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3689, false, -1, 7991, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3692},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3694, false, 8008, -1, 8008, 12900, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3697, false, 8009, -1, 8009, 12960, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3700, false, 8010, -1, 8010, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3703, false, 8011, -1, 8011, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3706, false, 8012, -1, 8012, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3709, false, 8013, -1, 8013, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3712, false, -1, 8000, -1, 13020, -1, false, false, false, false, utf8proc_sequences + 3715},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3717, false, -1, 8001, -1, 13080, -1, false, false, false, false, utf8proc_sequences + 3720},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3722, false, -1, 8002, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3725},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3727, false, -1, 8003, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3730},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3732, false, -1, 8004, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3735},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3737, false, -1, 8005, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3740},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3742, false, -1, -1, -1, 13140, -1, false, false, false, false, utf8proc_sequences + 3742},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3745, false, 8025, -1, 8025, 13200, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3748, false, -1, -1, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3751},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3755, false, 8027, -1, 8027, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3758, false, -1, -1, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3761},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3765, false, 8029, -1, 8029, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3768, false, -1, -1, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3771},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3775, false, 8031, -1, 8031, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3778, false, -1, 8017, -1, 13260, -1, false, false, false, false, utf8proc_sequences + 3781},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3783, false, -1, 8019, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3786},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3788, false, -1, 8021, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3791},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3793, false, -1, 8023, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3796},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3798, false, 8040, -1, 8040, 13320, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3801, false, 8041, -1, 8041, 13380, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3804, false, 8042, -1, 8042, 15000, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3807, false, 8043, -1, 8043, 15060, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3810, false, 8044, -1, 8044, 15120, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3813, false, 8045, -1, 8045, 15180, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3816, false, 8046, -1, 8046, 15240, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3819, false, 8047, -1, 8047, 15300, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3822, false, -1, 8032, -1, 13440, -1, false, false, false, false, utf8proc_sequences + 3825},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3827, false, -1, 8033, -1, 13500, -1, false, false, false, false, utf8proc_sequences + 3830},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3832, false, -1, 8034, -1, 15360, -1, false, false, false, false, utf8proc_sequences + 3835},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3837, false, -1, 8035, -1, 15420, -1, false, false, false, false, utf8proc_sequences + 3840},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3842, false, -1, 8036, -1, 15480, -1, false, false, false, false, utf8proc_sequences + 3845},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3847, false, -1, 8037, -1, 15540, -1, false, false, false, false, utf8proc_sequences + 3850},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3852, false, -1, 8038, -1, 15600, -1, false, false, false, false, utf8proc_sequences + 3855},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3857, false, -1, 8039, -1, 15660, -1, false, false, false, false, utf8proc_sequences + 3860},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3862, false, 8122, -1, 8122, 15720, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1341, false, 8123, -1, 8123, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3865, false, 8136, -1, 8136, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1348, false, 8137, -1, 8137, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3868, false, 8138, -1, 8138, 15900, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1353, false, 8139, -1, 8139, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3871, false, 8154, -1, 8154, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1358, false, 8155, -1, 8155, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3874, false, 8184, -1, 8184, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1363, false, 8185, -1, 8185, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3877, false, 8170, -1, 8170, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1368, false, 8171, -1, 8171, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3880, false, 8186, -1, 8186, 16320, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1373, false, 8187, -1, 8187, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3883, false, 8072, -1, 8072, -1, -1, false, false, false, false, utf8proc_sequences + 3886},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3889, false, 8073, -1, 8073, -1, -1, false, false, false, false, utf8proc_sequences + 3892},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3895, false, 8074, -1, 8074, -1, -1, false, false, false, false, utf8proc_sequences + 3898},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3901, false, 8075, -1, 8075, -1, -1, false, false, false, false, utf8proc_sequences + 3904},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3907, false, 8076, -1, 8076, -1, -1, false, false, false, false, utf8proc_sequences + 3910},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3913, false, 8077, -1, 8077, -1, -1, false, false, false, false, utf8proc_sequences + 3916},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3919, false, 8078, -1, 8078, -1, -1, false, false, false, false, utf8proc_sequences + 3922},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3925, false, 8079, -1, 8079, -1, -1, false, false, false, false, utf8proc_sequences + 3928},
+ {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3931, false, -1, 8064, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3934},
+ {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3936, false, -1, 8065, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3939},
+ {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3941, false, -1, 8066, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3944},
+ {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3946, false, -1, 8067, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3949},
+ {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3951, false, -1, 8068, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3954},
+ {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3956, false, -1, 8069, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3959},
+ {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3961, false, -1, 8070, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3964},
+ {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3966, false, -1, 8071, -1, -1, -1, false, false, false, false, utf8proc_sequences + 3969},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3971, false, 8088, -1, 8088, -1, -1, false, false, false, false, utf8proc_sequences + 3974},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3977, false, 8089, -1, 8089, -1, -1, false, false, false, false, utf8proc_sequences + 3980},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3983, false, 8090, -1, 8090, -1, -1, false, false, false, false, utf8proc_sequences + 3986},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3989, false, 8091, -1, 8091, -1, -1, false, false, false, false, utf8proc_sequences + 3992},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 3995, false, 8092, -1, 8092, -1, -1, false, false, false, false, utf8proc_sequences + 3998},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4001, false, 8093, -1, 8093, -1, -1, false, false, false, false, utf8proc_sequences + 4004},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4007, false, 8094, -1, 8094, -1, -1, false, false, false, false, utf8proc_sequences + 4010},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4013, false, 8095, -1, 8095, -1, -1, false, false, false, false, utf8proc_sequences + 4016},
+ {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4019, false, -1, 8080, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4022},
+ {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4024, false, -1, 8081, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4027},
+ {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4029, false, -1, 8082, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4032},
+ {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4034, false, -1, 8083, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4037},
+ {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4039, false, -1, 8084, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4042},
+ {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4044, false, -1, 8085, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4047},
+ {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4049, false, -1, 8086, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4052},
+ {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4054, false, -1, 8087, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4057},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4059, false, 8104, -1, 8104, -1, -1, false, false, false, false, utf8proc_sequences + 4062},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4065, false, 8105, -1, 8105, -1, -1, false, false, false, false, utf8proc_sequences + 4068},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4071, false, 8106, -1, 8106, -1, -1, false, false, false, false, utf8proc_sequences + 4074},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4077, false, 8107, -1, 8107, -1, -1, false, false, false, false, utf8proc_sequences + 4080},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4083, false, 8108, -1, 8108, -1, -1, false, false, false, false, utf8proc_sequences + 4086},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4089, false, 8109, -1, 8109, -1, -1, false, false, false, false, utf8proc_sequences + 4092},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4095, false, 8110, -1, 8110, -1, -1, false, false, false, false, utf8proc_sequences + 4098},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4101, false, 8111, -1, 8111, -1, -1, false, false, false, false, utf8proc_sequences + 4104},
+ {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4107, false, -1, 8096, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4110},
+ {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4112, false, -1, 8097, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4115},
+ {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4117, false, -1, 8098, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4120},
+ {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4122, false, -1, 8099, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4125},
+ {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4127, false, -1, 8100, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4130},
+ {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4132, false, -1, 8101, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4135},
+ {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4137, false, -1, 8102, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4140},
+ {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4142, false, -1, 8103, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4145},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4147, false, 8120, -1, 8120, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4150, false, 8121, -1, 8121, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4153, false, -1, -1, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4156},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4159, false, 8124, -1, 8124, -1, -1, false, false, false, false, utf8proc_sequences + 4162},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4165, false, -1, -1, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4168},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4171, false, -1, -1, -1, 15840, -1, false, false, false, false, utf8proc_sequences + 4171},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4174, false, -1, -1, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4177},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4181, false, -1, 8112, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4184},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4186, false, -1, 8113, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4189},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4191, false, -1, 8048, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4194},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4196, false, -1, 8049, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4198},
+ {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4200, false, -1, 8115, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4203},
+ {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4205, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 1326, false, 921, -1, 921, -1, -1, false, false, false, false, utf8proc_sequences + 1326},
+ {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4205, false, -1, -1, -1, 16080, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4208, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4211, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4214, false, -1, -1, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4217},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4220, false, 8140, -1, 8140, -1, -1, false, false, false, false, utf8proc_sequences + 4223},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4226, false, -1, -1, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4229},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4232, false, -1, -1, -1, 16020, -1, false, false, false, false, utf8proc_sequences + 4232},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4235, false, -1, -1, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4238},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4242, false, -1, 8050, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4245},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4247, false, -1, 8051, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4249},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4251, false, -1, 8052, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4254},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4256, false, -1, 8053, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4258},
+ {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4260, false, -1, 8131, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4263},
+ {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4265, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4268, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4271, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4274, false, 8152, -1, 8152, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4277, false, 8153, -1, 8153, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4280, false, -1, -1, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4283},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4287, false, -1, -1, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1378},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4289, false, -1, -1, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4289},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4292, false, -1, -1, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4295},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4299, false, -1, 8144, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4302},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4304, false, -1, 8145, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4307},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4309, false, -1, 8054, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4312},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4314, false, -1, 8055, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4316},
+ {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4318, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4321, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4324, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4327, false, 8168, -1, 8168, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4330, false, 8169, -1, 8169, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4333, false, -1, -1, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4336},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4340, false, -1, -1, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1451},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4342, false, -1, -1, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4342},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4345, false, 8172, -1, 8172, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4348, false, -1, -1, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4348},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4351, false, -1, -1, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4354},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4358, false, -1, 8160, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4361},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4363, false, -1, 8161, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4366},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4368, false, -1, 8058, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4371},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4373, false, -1, 8059, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4375},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4377, false, -1, 8165, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4380},
+ {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4382, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4385, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4387, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4389, false, -1, -1, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4392},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4395, false, 8188, -1, 8188, -1, -1, false, false, false, false, utf8proc_sequences + 4398},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4401, false, -1, -1, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4404},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4407, false, -1, -1, -1, 16440, -1, false, false, false, false, utf8proc_sequences + 4407},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4410, false, -1, -1, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4413},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4417, false, -1, 8056, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4420},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4422, false, -1, 8057, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4424},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4426, false, -1, 8060, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4429},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4431, false, -1, 8061, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4433},
+ {UTF8PROC_CATEGORY_LT, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4435, false, -1, 8179, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4438},
+ {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4440, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4442, false, -1, -1, -1, 16140, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_ZS, 0, UTF8PROC_BIDI_CLASS_WS, 0, utf8proc_sequences + 4445, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_ZS, 0, UTF8PROC_BIDI_CLASS_WS, 0, utf8proc_sequences + 4447, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_ZS, 0, UTF8PROC_BIDI_CLASS_WS, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 52, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_ZS, 0, UTF8PROC_BIDI_CLASS_WS, UTF8PROC_DECOMP_TYPE_NOBREAK, utf8proc_sequences + 52, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_CF, 0, UTF8PROC_BIDI_CLASS_BN, 0, NULL, false, -1, -1, -1, -1, -1, false, true, true, true, NULL},
+ {UTF8PROC_CATEGORY_CF, 0, UTF8PROC_BIDI_CLASS_R, 0, NULL, false, -1, -1, -1, -1, -1, false, true, true, false, NULL},
+ {UTF8PROC_CATEGORY_PD, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_NOBREAK, utf8proc_sequences + 4449, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4451, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4454, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4456, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4459, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_ZL, 0, UTF8PROC_BIDI_CLASS_WS, 0, NULL, false, -1, -1, -1, -1, -1, false, false, true, false, NULL},
+ {UTF8PROC_CATEGORY_ZP, 0, UTF8PROC_BIDI_CLASS_B, 0, NULL, false, -1, -1, -1, -1, -1, false, false, true, false, NULL},
+ {UTF8PROC_CATEGORY_CF, 0, UTF8PROC_BIDI_CLASS_LRE, 0, NULL, false, -1, -1, -1, -1, -1, false, true, true, false, NULL},
+ {UTF8PROC_CATEGORY_CF, 0, UTF8PROC_BIDI_CLASS_RLE, 0, NULL, false, -1, -1, -1, -1, -1, false, true, true, false, NULL},
+ {UTF8PROC_CATEGORY_CF, 0, UTF8PROC_BIDI_CLASS_PDF, 0, NULL, false, -1, -1, -1, -1, -1, false, true, true, false, NULL},
+ {UTF8PROC_CATEGORY_CF, 0, UTF8PROC_BIDI_CLASS_LRO, 0, NULL, false, -1, -1, -1, -1, -1, false, true, true, false, NULL},
+ {UTF8PROC_CATEGORY_CF, 0, UTF8PROC_BIDI_CLASS_RLO, 0, NULL, false, -1, -1, -1, -1, -1, false, true, true, false, NULL},
+ {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ET, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4463, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ET, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4466, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4470, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4473, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4477, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4480, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_CS, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4483, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4486, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4489, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4492, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 4497, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 16, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 4499, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 4501, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 4503, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 4505, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 4507, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 4509, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ES, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 4511, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ES, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 4513, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 4515, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PS, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 4517, true, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PE, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 4519, true, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 26, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_SUB, utf8proc_sequences + 4497, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_SUB, utf8proc_sequences + 72, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_SUB, utf8proc_sequences + 60, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_SUB, utf8proc_sequences + 62, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_SUB, utf8proc_sequences + 4499, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_SUB, utf8proc_sequences + 4501, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_SUB, utf8proc_sequences + 4503, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_SUB, utf8proc_sequences + 4505, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_SUB, utf8proc_sequences + 4507, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_SUB, utf8proc_sequences + 4509, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ES, UTF8PROC_DECOMP_TYPE_SUB, utf8proc_sequences + 4511, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ES, UTF8PROC_DECOMP_TYPE_SUB, utf8proc_sequences + 4513, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SUB, utf8proc_sequences + 4515, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PS, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SUB, utf8proc_sequences + 4517, true, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PE, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SUB, utf8proc_sequences + 4519, true, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUB, utf8proc_sequences + 0, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUB, utf8proc_sequences + 8, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUB, utf8proc_sequences + 28, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUB, utf8proc_sequences + 46, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUB, utf8proc_sequences + 792, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SC, 0, UTF8PROC_BIDI_CLASS_ET, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4521, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4524, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4528, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 4532, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4534, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4537, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4541, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4545, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4547, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 12, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 2390, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 14, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 454, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 2392, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 2398, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 22, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 2402, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4550, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 2408, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 4553, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 2410, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 4555, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4558, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 4562, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 4565, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4567, false, -1, 969, -1, -1, -1, false, false, false, false, utf8proc_sequences + 1424},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 2396, false, -1, 107, -1, -1, -1, false, false, false, false, utf8proc_sequences + 20},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 4569, false, -1, 229, -1, -1, -1, false, false, false, false, utf8proc_sequences + 114},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 2380, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 8, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 2384, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 4571, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 8526, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4573},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 2400, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 28, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4575, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4577, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4579, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4581, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 16, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4583, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 1408, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 1386, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 4587, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 4589, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 4591, true, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 2382, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 6, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 18, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 8498, -1, 8498, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_FRACTION, utf8proc_sequences + 4593, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_FRACTION, utf8proc_sequences + 4597, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_FRACTION, utf8proc_sequences + 4601, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_FRACTION, utf8proc_sequences + 4605, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_FRACTION, utf8proc_sequences + 4609, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_FRACTION, utf8proc_sequences + 4613, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_FRACTION, utf8proc_sequences + 4617, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_FRACTION, utf8proc_sequences + 4621, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_FRACTION, utf8proc_sequences + 4625, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_FRACTION, utf8proc_sequences + 4629, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_FRACTION, utf8proc_sequences + 4633, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_FRACTION, utf8proc_sequences + 4637, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_FRACTION, utf8proc_sequences + 4641, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 2392, false, -1, 8560, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4644},
+ {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4646, false, -1, 8561, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4649},
+ {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4651, false, -1, 8562, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4655},
+ {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4657, false, -1, 8563, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4660},
+ {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4662, false, -1, 8564, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4664},
+ {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4666, false, -1, 8565, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4669},
+ {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4671, false, -1, 8566, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4675},
+ {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4677, false, -1, 8567, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4682},
+ {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4684, false, -1, 8568, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4687},
+ {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4689, false, -1, 8569, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4691},
+ {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4693, false, -1, 8570, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4696},
+ {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4698, false, -1, 8571, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4702},
+ {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 2398, false, -1, 8572, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4704},
+ {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4532, false, -1, 8573, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4706},
+ {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 2382, false, -1, 8574, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4708},
+ {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 2400, false, -1, 8575, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4710},
+ {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 16, false, 8544, -1, 8544, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4712, false, 8545, -1, 8545, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4715, false, 8546, -1, 8546, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4719, false, 8547, -1, 8547, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 42, false, 8548, -1, 8548, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4722, false, 8549, -1, 8549, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4725, false, 8550, -1, 8550, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4729, false, 8551, -1, 8551, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4734, false, 8552, -1, 8552, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 46, false, 8553, -1, 8553, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4737, false, 8554, -1, 8554, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4740, false, 8555, -1, 8555, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 22, false, 8556, -1, 8556, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4, false, 8557, -1, 8557, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6, false, 8558, -1, 8558, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 24, false, 8559, -1, 8559, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 8580, -1, -1, -1, false, false, false, false, utf8proc_sequences + 4744},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 8579, -1, 8579, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, false, -1, -1, -1, 16500, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, false, -1, -1, -1, 16560, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, false, -1, -1, -1, 16620, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4746, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4749, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4752, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4755, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4758, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4761, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, false, -1, -1, -1, 16680, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, false, -1, -1, -1, 16800, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, false, -1, -1, -1, 16740, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, true, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, true, -1, -1, -1, 16860, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4764, true, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, true, -1, -1, -1, 16920, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4767, true, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, true, -1, -1, -1, 16980, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4770, true, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, false, -1, -1, -1, 17040, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4773, true, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, false, -1, -1, -1, 17100, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4776, true, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4779, true, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4782, true, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4786, true, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4789, true, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, true, -1, -1, -1, 17160, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4793, true, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, true, -1, -1, -1, 17220, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4796, true, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, true, -1, -1, -1, 17280, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4799, true, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, true, -1, -1, -1, 17340, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4802, true, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, false, -1, -1, -1, 17520, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4805, true, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, false, -1, -1, -1, 17460, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4808, true, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, true, -1, -1, -1, 17700, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, true, -1, -1, -1, 17760, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4811, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4814, true, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4817, true, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4820, true, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4823, true, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, true, -1, -1, -1, 17820, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, true, -1, -1, -1, 17880, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4826, true, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4829, true, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, true, -1, -1, -1, 17940, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, true, -1, -1, -1, 18000, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4832, true, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4835, true, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, true, -1, -1, -1, 18060, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, true, -1, -1, -1, 18120, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, true, -1, -1, -1, 18660, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, true, -1, -1, -1, 18720, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4838, true, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4841, true, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, true, -1, -1, -1, 18180, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, true, -1, -1, -1, 18240, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4844, true, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4847, true, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, true, -1, -1, -1, 18300, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, true, -1, -1, -1, 18360, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4850, true, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4853, true, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, true, -1, -1, -1, 18780, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, true, -1, -1, -1, 18840, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, true, -1, -1, -1, 18420, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, true, -1, -1, -1, 18480, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, true, -1, -1, -1, 18540, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, true, -1, -1, -1, 18600, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4856, true, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4859, true, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4862, true, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4865, true, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, true, -1, -1, -1, 18900, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, true, -1, -1, -1, 18960, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, true, -1, -1, -1, 19020, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, true, -1, -1, -1, 19080, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4868, true, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4871, true, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4874, true, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4877, true, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4880, true, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4883, true, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4886, true, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4889, true, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PS, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4892, true, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PE, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 4894, true, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 72, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 60, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 62, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 4499, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 4501, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 4503, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 4505, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 4507, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 4509, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 4896, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 4899, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 4902, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 4905, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 4908, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 4911, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 4914, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 4917, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 4920, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 4923, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 4926, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4929, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4933, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4937, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4941, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4945, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4949, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4953, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4957, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4961, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4965, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4970, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4975, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4980, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4985, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4990, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 4995, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5000, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5005, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5010, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5015, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5020, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5023, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5026, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5029, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5032, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5035, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5038, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5041, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5044, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5047, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5051, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5055, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5059, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5063, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5067, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5071, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5075, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5079, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5083, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5087, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5091, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5095, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5099, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5103, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5107, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5111, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5115, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5119, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5123, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5127, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5131, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5135, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5139, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5143, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5147, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5151, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5155, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5159, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5163, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5167, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5171, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5175, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5179, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5183, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5187, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5191, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 2376, false, -1, 9424, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5195},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 2380, false, -1, 9425, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5197},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 4532, false, -1, 9426, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5199},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 2382, false, -1, 9427, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5201},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 2384, false, -1, 9428, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5203},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 4571, false, -1, 9429, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5205},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 2388, false, -1, 9430, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5207},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 2390, false, -1, 9431, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5209},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 2392, false, -1, 9432, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5211},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 2394, false, -1, 9433, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5213},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 2396, false, -1, 9434, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5215},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 2398, false, -1, 9435, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5217},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 2400, false, -1, 9436, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5219},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 2402, false, -1, 9437, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5221},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 2404, false, -1, 9438, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5223},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 2408, false, -1, 9439, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5225},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 4553, false, -1, 9440, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5227},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 2410, false, -1, 9441, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5229},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 5231, false, -1, 9442, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5233},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 2412, false, -1, 9443, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5235},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 2414, false, -1, 9444, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5237},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 4662, false, -1, 9445, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5239},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 2416, false, -1, 9446, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5241},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 4689, false, -1, 9447, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5243},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 5245, false, -1, 9448, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5247},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 4565, false, -1, 9449, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5249},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 0, false, 9398, -1, 9398, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 2, false, 9399, -1, 9399, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 4, false, 9400, -1, 9400, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6, false, 9401, -1, 9401, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 8, false, 9402, -1, 9402, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 10, false, 9403, -1, 9403, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 12, false, 9404, -1, 9404, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 14, false, 9405, -1, 9405, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 16, false, 9406, -1, 9406, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 18, false, 9407, -1, 9407, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 20, false, 9408, -1, 9408, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 22, false, 9409, -1, 9409, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 24, false, 9410, -1, 9410, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 26, false, 9411, -1, 9411, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 28, false, 9412, -1, 9412, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 30, false, 9413, -1, 9413, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 32, false, 9414, -1, 9414, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 34, false, 9415, -1, 9415, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 36, false, 9416, -1, 9416, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 38, false, 9417, -1, 9417, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 40, false, 9418, -1, 9418, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 42, false, 9419, -1, 9419, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 44, false, 9420, -1, 9420, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 46, false, 9421, -1, 9421, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 48, false, 9422, -1, 9422, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 50, false, 9423, -1, 9423, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 4497, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5251, true, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5256, true, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5260, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5263, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, utf8proc_sequences + 5267, true, -1, -1, -1, -1, -1, true, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, false, -1, -1, -1, 19140, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11312, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5270},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11313, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5272},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11314, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5274},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11315, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5276},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11316, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5278},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11317, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5280},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11318, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5282},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11319, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5284},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11320, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5286},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11321, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5288},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11322, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5290},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11323, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5292},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11324, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5294},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11325, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5296},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11326, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5298},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11327, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5300},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11328, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5302},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11329, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5304},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11330, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5306},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11331, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5308},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11332, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5310},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11333, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5312},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11334, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5314},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11335, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5316},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11336, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5318},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11337, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5320},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11338, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5322},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11339, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5324},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11340, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5326},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11341, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5328},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11342, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5330},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11343, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5332},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11344, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5334},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11345, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5336},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11346, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5338},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11347, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5340},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11348, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5342},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11349, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5344},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11350, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5346},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11351, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5348},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11352, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5350},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11353, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5352},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11354, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5354},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11355, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5356},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11356, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5358},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11357, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5360},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11358, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5362},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11264, -1, 11264, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11265, -1, 11265, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11266, -1, 11266, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11267, -1, 11267, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11268, -1, 11268, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11269, -1, 11269, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11270, -1, 11270, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11271, -1, 11271, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11272, -1, 11272, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11273, -1, 11273, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11274, -1, 11274, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11275, -1, 11275, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11276, -1, 11276, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11277, -1, 11277, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11278, -1, 11278, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11279, -1, 11279, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11280, -1, 11280, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11281, -1, 11281, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11282, -1, 11282, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11283, -1, 11283, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11284, -1, 11284, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11285, -1, 11285, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11286, -1, 11286, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11287, -1, 11287, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11288, -1, 11288, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11289, -1, 11289, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11290, -1, 11290, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11291, -1, 11291, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11292, -1, 11292, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11293, -1, 11293, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11294, -1, 11294, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11295, -1, 11295, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11296, -1, 11296, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11297, -1, 11297, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11298, -1, 11298, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11299, -1, 11299, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11300, -1, 11300, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11301, -1, 11301, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11302, -1, 11302, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11303, -1, 11303, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11304, -1, 11304, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11305, -1, 11305, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11306, -1, 11306, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11307, -1, 11307, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11308, -1, 11308, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11309, -1, 11309, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11310, -1, 11310, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11361, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5364},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11360, -1, 11360, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 619, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5366},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 7549, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5368},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 637, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5370},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 570, -1, 570, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 574, -1, 574, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11368, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5372},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11367, -1, 11367, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11370, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5374},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11369, -1, 11369, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11372, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5376},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11371, -1, 11371, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11382, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5378},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11381, -1, 11381, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11393, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5380},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11392, -1, 11392, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11395, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5382},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11394, -1, 11394, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11397, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5384},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11396, -1, 11396, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11399, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5386},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11398, -1, 11398, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11401, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5388},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11400, -1, 11400, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11403, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5390},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11402, -1, 11402, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11405, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5392},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11404, -1, 11404, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11407, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5394},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11406, -1, 11406, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11409, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5396},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11408, -1, 11408, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11411, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5398},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11410, -1, 11410, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11413, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5400},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11412, -1, 11412, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11415, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5402},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11414, -1, 11414, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11417, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5404},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11416, -1, 11416, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11419, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5406},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11418, -1, 11418, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11421, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5408},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11420, -1, 11420, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11423, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5410},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11422, -1, 11422, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11425, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5412},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11424, -1, 11424, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11427, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5414},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11426, -1, 11426, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11429, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5416},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11428, -1, 11428, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11431, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5418},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11430, -1, 11430, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11433, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5420},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11432, -1, 11432, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11435, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5422},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11434, -1, 11434, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11437, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5424},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11436, -1, 11436, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11439, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5426},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11438, -1, 11438, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11441, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5428},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11440, -1, 11440, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11443, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5430},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11442, -1, 11442, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11445, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5432},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11444, -1, 11444, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11447, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5434},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11446, -1, 11446, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11449, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5436},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11448, -1, 11448, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11451, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5438},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11450, -1, 11450, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11453, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5440},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11452, -1, 11452, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11455, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5442},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11454, -1, 11454, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11457, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5444},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11456, -1, 11456, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11459, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5446},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11458, -1, 11458, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11461, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5448},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11460, -1, 11460, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11463, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5450},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11462, -1, 11462, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11465, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5452},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11464, -1, 11464, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11467, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5454},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11466, -1, 11466, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11469, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5456},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11468, -1, 11468, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11471, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5458},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11470, -1, 11470, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11473, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5460},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11472, -1, 11472, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11475, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5462},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11474, -1, 11474, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11477, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5464},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11476, -1, 11476, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11479, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5466},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11478, -1, 11478, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11481, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5468},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11480, -1, 11480, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11483, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5470},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11482, -1, 11482, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11485, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5472},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11484, -1, 11484, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11487, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5474},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11486, -1, 11486, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11489, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5476},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11488, -1, 11488, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 11491, -1, -1, -1, false, false, false, false, utf8proc_sequences + 5478},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 11490, -1, 11490, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 4256, -1, 4256, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 4257, -1, 4257, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 4258, -1, 4258, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 4259, -1, 4259, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 4260, -1, 4260, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 4261, -1, 4261, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 4262, -1, 4262, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 4263, -1, 4263, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 4264, -1, 4264, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 4265, -1, 4265, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 4266, -1, 4266, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 4267, -1, 4267, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 4268, -1, 4268, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 4269, -1, 4269, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 4270, -1, 4270, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 4271, -1, 4271, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 4272, -1, 4272, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 4273, -1, 4273, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 4274, -1, 4274, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 4275, -1, 4275, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 4276, -1, 4276, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 4277, -1, 4277, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 4278, -1, 4278, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 4279, -1, 4279, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 4280, -1, 4280, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 4281, -1, 4281, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 4282, -1, 4282, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 4283, -1, 4283, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 4284, -1, 4284, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 4285, -1, 4285, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 4286, -1, 4286, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 4287, -1, 4287, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 4288, -1, 4288, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 4289, -1, 4289, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 4290, -1, 4290, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 4291, -1, 4291, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 4292, -1, 4292, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 4293, -1, 4293, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 5480, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5482, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5484, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5486, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5488, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5490, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5492, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5494, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5496, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5498, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5500, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5502, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5504, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5506, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5508, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5510, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5512, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5514, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5516, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5518, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5520, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5522, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5524, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5526, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5528, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5530, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5532, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5534, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5536, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5538, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5540, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5542, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5544, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5546, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5548, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5550, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5552, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5554, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5556, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5558, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5560, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5562, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5564, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5566, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5568, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5570, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5572, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5574, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5576, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5578, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5580, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5582, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5584, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5586, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5588, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5590, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5592, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5594, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5596, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5598, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5600, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5602, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5604, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5606, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5608, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5610, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5612, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5614, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5616, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5618, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5620, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5622, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5624, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5626, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5628, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5630, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5632, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5634, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5636, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5638, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5640, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5642, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5644, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5646, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5648, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5650, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5652, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5654, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5656, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5658, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5660, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5662, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5664, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5666, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5668, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5670, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5672, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5674, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5676, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5678, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5680, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5682, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5684, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5686, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5688, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5690, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5692, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5694, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5696, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5698, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5700, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5702, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5704, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5706, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5708, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5710, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5712, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5714, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5716, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5718, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5720, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5722, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5724, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5726, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5728, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5730, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5732, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5734, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5736, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5738, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5740, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5742, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5744, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5746, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5748, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5750, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5752, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5754, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5756, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5758, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5760, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5762, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5764, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5766, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5768, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5770, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5772, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5774, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5776, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5778, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5780, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5782, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5784, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5786, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5788, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5790, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5792, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5794, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5796, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5798, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5800, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5802, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5804, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5806, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5808, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5810, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5812, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5814, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5816, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5818, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5820, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5822, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5824, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5826, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5828, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5830, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5832, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5834, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5836, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5838, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5840, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5842, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5844, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5846, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5848, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5850, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5852, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5854, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5856, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5858, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5860, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5862, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5864, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5866, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5868, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5870, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5872, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5874, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5876, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5878, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5880, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5882, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5884, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5886, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5888, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5890, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5892, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5894, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5896, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5898, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5900, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5902, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5904, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5906, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5908, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5910, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5912, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_ZS, 0, UTF8PROC_BIDI_CLASS_WS, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 52, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_MN, 218, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MN, 224, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5914, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5532, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5916, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5918, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 20400, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 19200, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 5920, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 19260, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 5923, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 19320, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 5926, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 19380, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 5929, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 19440, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 5932, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 19500, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 5935, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 19560, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 5938, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 19620, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 5941, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 19680, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 5944, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 19740, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 5947, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 19800, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 5950, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 19860, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 5953, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 19920, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 5956, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 19980, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 5959, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 20040, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 5962, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 20100, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 5965, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 5968, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 20160, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 5971, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 5974, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 20220, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 5977, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 5980, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 20280, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 5983, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 5986, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 20340, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 5989, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 5992, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 5995, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_MN, 8, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, 52, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MN, 8, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, 53, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 5998, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6001, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 20460, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 6004, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_VERTICAL, utf8proc_sequences + 6007, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 21720, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 20520, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 6010, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 20580, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 6013, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 20640, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 6016, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 20700, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 6019, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 20760, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 6022, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 20820, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 6025, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 20880, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 6028, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 20940, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 6031, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 21000, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 6034, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 21060, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 6037, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 21120, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 6040, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 21180, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 6043, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 21240, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 6046, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 21300, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 6049, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 21360, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 6052, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 21420, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 6055, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 6058, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 21480, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 6061, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 6064, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 21540, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 6067, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 6070, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 21600, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 6073, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 6076, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 21660, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 6079, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 6082, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 21780, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 21840, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 21900, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 21960, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 6085, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 6088, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 6091, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 6094, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 6097, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 22020, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 6100, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_VERTICAL, utf8proc_sequences + 6103, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6106, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6108, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6110, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6112, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6114, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6116, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6118, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6120, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6122, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6124, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6126, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6128, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6130, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6132, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6134, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6136, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6138, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6140, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6142, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6144, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6146, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6148, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6150, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6152, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6154, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6156, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6158, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6160, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6162, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6164, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6166, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6168, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6170, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6172, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6174, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6176, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6178, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6180, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6182, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6184, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6186, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6188, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6190, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6192, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6194, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6196, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6198, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6200, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6202, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6204, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6206, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6208, false, -1, -1, -1, -1, -1, false, true, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6210, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6212, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6214, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6216, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6218, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6220, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6222, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6224, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6226, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6228, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6230, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6232, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6234, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6236, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6238, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6240, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6242, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6244, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6246, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6248, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6250, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6252, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6254, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6256, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6258, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6260, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6262, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6264, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6266, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6268, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6270, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6272, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6274, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6276, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6278, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6280, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6282, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6284, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6286, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6288, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6290, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6292, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 5486, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 5498, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 6294, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 6296, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 6298, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 6300, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 6302, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 6304, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 5494, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 6306, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 6308, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 6310, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 6312, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SUPER, utf8proc_sequences + 5502, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6314, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6318, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6322, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6326, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6330, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6334, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6338, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6342, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6346, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6350, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6354, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6358, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6362, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6366, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6370, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6375, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6380, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6385, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6390, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6395, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6400, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6405, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6410, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6415, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6420, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6425, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6430, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6435, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6440, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6445, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6453, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6460, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6464, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6468, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6472, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6476, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6480, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6484, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6488, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6492, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6496, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6500, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6504, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6508, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6512, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6516, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6520, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6524, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6528, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6532, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6536, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6540, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6544, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6548, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6552, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6556, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6560, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6564, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6568, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6572, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6576, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6580, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6584, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6588, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6592, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6596, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6600, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 6604, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6608, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6611, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6614, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6617, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6620, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6623, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6626, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6629, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6632, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6635, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6638, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6641, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6644, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6647, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6650, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6106, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6112, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6118, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6122, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6138, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6140, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6146, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6150, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6152, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6156, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6158, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6160, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6162, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6164, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6653, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6656, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6659, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6662, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6665, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6668, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6671, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6674, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6677, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6680, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6683, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6686, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6689, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6692, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6695, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6701, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6706, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 5486, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 5498, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6294, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6296, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6709, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6711, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6713, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 5508, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6715, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 5532, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 5632, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 5656, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 5654, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 5634, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 5818, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 5548, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 5628, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6717, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6719, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6721, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6723, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6725, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6727, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6729, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6731, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6733, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6735, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 5560, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6737, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6739, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6741, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6743, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6745, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6747, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6749, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6751, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6298, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6300, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6302, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6753, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6755, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6757, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6759, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6761, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6763, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6765, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6767, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6769, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6771, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6773, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6776, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6779, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6782, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6785, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6788, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6791, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6794, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6797, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6800, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6803, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6806, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6809, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6812, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6815, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6818, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6821, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6824, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6827, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6830, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6833, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6836, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6839, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6842, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6845, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6849, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 6853, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 6857, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 6860, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 6864, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 6867, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6871, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6873, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6875, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6877, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6879, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6881, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6883, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6885, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6887, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6889, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6891, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6893, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6895, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6897, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6899, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6901, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6903, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6905, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6907, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6909, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6911, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6913, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6915, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6917, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6919, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6921, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6923, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6925, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6927, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6929, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6931, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6933, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6935, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6937, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6939, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6941, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6943, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6945, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6947, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6949, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6951, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6953, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6955, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6957, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6959, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6961, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_CIRCLE, utf8proc_sequences + 6963, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 6965, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 6970, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 6975, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 6980, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 6984, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 6989, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 6993, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 6997, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7003, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7008, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7012, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7016, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7020, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7025, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7030, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7034, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7038, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7041, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7045, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7050, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7055, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7058, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7064, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7071, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7077, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7081, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7087, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7093, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7098, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7102, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7106, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7110, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7115, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7121, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7126, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7130, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7134, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7138, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7141, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7144, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7147, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7150, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7154, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7158, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7164, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7168, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7173, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7179, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7183, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7186, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7189, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7195, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7200, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7206, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7210, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7216, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7219, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7223, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7227, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7231, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7235, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7239, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7244, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7248, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7251, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7255, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7259, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7263, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7268, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7272, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7276, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7280, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7286, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7291, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7294, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7300, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7303, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7308, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7313, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7317, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7321, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7325, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7330, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7333, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7337, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7342, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7345, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7351, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7355, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7358, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7361, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7364, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7367, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7370, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7373, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7376, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7379, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7382, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7385, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7389, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7393, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7397, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7401, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7405, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7409, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7413, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7417, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7421, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7425, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7429, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7433, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7437, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7441, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7445, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7449, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7452, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7455, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7459, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7462, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7465, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7468, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7472, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7476, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7479, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7482, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7485, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7488, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7491, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7496, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7499, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7502, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7505, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7508, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7511, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7514, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7517, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7520, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7524, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7529, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7532, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7535, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7538, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7541, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7544, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7547, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7550, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7554, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7558, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7562, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7566, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7569, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7572, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7575, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7578, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7581, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7584, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7587, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7590, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7593, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7596, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7600, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7604, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7607, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7611, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7615, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7619, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7622, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7626, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7630, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7635, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7638, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7642, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7646, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7650, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7654, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7660, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7667, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7670, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7673, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7676, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7679, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7682, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7685, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7688, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7691, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7694, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7697, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7700, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7703, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7706, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7709, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7712, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7715, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7718, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7721, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7726, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7729, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7732, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7735, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7740, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7744, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7747, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7750, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7753, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7756, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7759, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7762, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7765, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7768, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7771, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7774, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7778, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7781, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7784, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7788, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7792, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7795, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7800, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7804, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7807, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7810, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7813, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7816, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7820, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7824, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7827, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7830, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7833, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7836, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7839, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7842, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7845, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7848, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7851, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7855, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7859, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7863, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7867, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7871, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7875, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7879, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7883, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7887, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7891, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7895, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7899, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7903, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7907, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7911, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7915, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7919, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7923, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7927, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7931, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 7935, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SQUARE, utf8proc_sequences + 7939, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_CS, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, -1, -1, false, true, false, false, NULL},
+ {UTF8PROC_CATEGORY_CO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 7943, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 7945, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 5802, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 7947, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 7949, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 7951, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 7953, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 5910, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 7955, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 5818, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 7957, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 7959, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 7961, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 7963, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 7965, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 7967, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 7969, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 7971, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 7973, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 7975, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 7977, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 7979, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 7981, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 7983, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 7985, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 7987, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 7989, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 7991, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 7993, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 7995, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 7997, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 7999, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8001, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8003, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8005, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8007, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8009, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8011, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8013, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8015, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8017, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8019, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8021, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8023, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8025, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8027, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8029, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8031, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8033, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8035, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8037, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 5734, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8039, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8041, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8043, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8045, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8047, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8049, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8051, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8053, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8055, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8057, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8059, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 5880, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8061, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8063, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8065, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8067, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8069, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8071, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8073, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8075, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8077, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8079, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8081, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8083, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8085, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8087, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8089, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8091, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8093, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8095, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8097, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8099, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8101, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8103, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8105, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8107, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8109, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8111, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8113, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8115, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8117, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8119, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8121, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8123, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8125, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8127, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8129, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8131, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8133, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8135, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8137, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8139, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8141, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8143, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8145, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8147, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8149, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8151, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8153, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 5806, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8155, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8157, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8159, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8161, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8163, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8165, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8167, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8169, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8171, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8173, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8175, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8177, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8179, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8181, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8183, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 5560, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8185, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8187, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8189, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8191, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8193, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8195, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8197, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8199, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 5522, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8201, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8203, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8205, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8207, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8209, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8211, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8213, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8215, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8217, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8219, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8221, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8223, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8225, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8227, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8229, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8231, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8233, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8235, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8237, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8239, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8241, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8243, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8245, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8247, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8249, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8251, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8253, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8255, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8257, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8259, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8261, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8263, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8265, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8267, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8269, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8271, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8273, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8275, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8277, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8279, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8281, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8283, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8285, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8287, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8289, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8291, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8293, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8295, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8297, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8299, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8301, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8303, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8305, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8307, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 5908, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8309, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8311, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8313, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8315, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8317, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8319, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8321, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8323, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8325, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8327, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8329, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8331, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 6711, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8333, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8335, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8337, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8339, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8341, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8343, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8345, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8347, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8349, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8351, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8353, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8355, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8357, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8359, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8361, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8363, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8365, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8367, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8369, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8371, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8373, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8375, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 5816, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8377, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8379, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8381, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8383, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8385, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8387, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8389, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8391, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8393, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8395, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8397, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8399, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8401, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 5718, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8403, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8405, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8407, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8409, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8411, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8413, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8415, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8417, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8419, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8421, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8423, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8425, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8427, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8429, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8431, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8433, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 5772, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8435, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 5778, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8437, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8439, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8441, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8443, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8445, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8447, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8449, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8451, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8453, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8455, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8457, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8459, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8461, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8463, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 5732, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8465, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8467, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8469, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8471, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8473, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8475, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8477, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8479, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8481, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8483, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8485, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8487, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8489, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8491, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8493, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8495, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8497, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8499, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8501, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8503, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 5574, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8505, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8507, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8509, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8511, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8513, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8515, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8517, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8519, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8521, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8523, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8525, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8527, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8529, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8531, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8533, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 6721, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8535, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8537, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8539, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8541, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 6729, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8543, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8545, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8547, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8549, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8551, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8553, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8555, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8557, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8559, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8561, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8563, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8565, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8567, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8569, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8571, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8573, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8575, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8577, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8579, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8581, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8583, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8585, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8587, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8589, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8591, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8593, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8595, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8597, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8599, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8601, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8603, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8605, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8607, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8609, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8611, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8613, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8615, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8617, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8619, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8621, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8623, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8625, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8627, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8629, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8631, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8633, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8635, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8637, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8639, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8641, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8643, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8645, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8647, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 5640, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8649, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8651, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8653, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8655, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8657, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8659, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8661, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8663, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8665, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8667, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8669, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8671, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8673, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8675, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8677, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8679, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8681, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8683, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8685, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8687, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8689, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8691, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8693, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8695, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8697, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8699, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8701, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8703, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8705, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8707, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8709, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8711, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8713, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8715, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8717, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8719, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8721, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8723, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8725, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8727, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8729, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8731, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8733, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8735, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8737, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8739, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8741, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 8743, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 8745, false, -1, -1, -1, -1, -1, false, false, false, false, utf8proc_sequences + 8745},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 8748, false, -1, -1, -1, -1, -1, false, false, false, false, utf8proc_sequences + 8748},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 8751, false, -1, -1, -1, -1, -1, false, false, false, false, utf8proc_sequences + 8751},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 8754, false, -1, -1, -1, -1, -1, false, false, false, false, utf8proc_sequences + 8754},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 8758, false, -1, -1, -1, -1, -1, false, false, false, false, utf8proc_sequences + 8758},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 8762, false, -1, -1, -1, -1, -1, false, false, false, false, utf8proc_sequences + 8765},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 8765, false, -1, -1, -1, -1, -1, false, false, false, false, utf8proc_sequences + 8765},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 8768, false, -1, -1, -1, -1, -1, false, false, false, false, utf8proc_sequences + 8768},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 8771, false, -1, -1, -1, -1, -1, false, false, false, false, utf8proc_sequences + 8771},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 8774, false, -1, -1, -1, -1, -1, false, false, false, false, utf8proc_sequences + 8774},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 8777, false, -1, -1, -1, -1, -1, false, false, false, false, utf8proc_sequences + 8777},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 8780, false, -1, -1, -1, -1, -1, false, false, false, false, utf8proc_sequences + 8780},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, utf8proc_sequences + 8783, false, -1, -1, -1, -1, -1, true, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_MN, 26, UTF8PROC_BIDI_CLASS_NSM, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, utf8proc_sequences + 8786, false, -1, -1, -1, -1, -1, true, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 8789, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 4575, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 4581, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 8791, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 8793, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 8795, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 8797, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 8799, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 8801, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ES, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 4511, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, utf8proc_sequences + 8803, false, -1, -1, -1, -1, -1, true, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, utf8proc_sequences + 8806, false, -1, -1, -1, -1, -1, true, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, utf8proc_sequences + 8809, false, -1, -1, -1, -1, -1, true, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, utf8proc_sequences + 8812, false, -1, -1, -1, -1, -1, true, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, utf8proc_sequences + 8815, false, -1, -1, -1, -1, -1, true, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, utf8proc_sequences + 8818, false, -1, -1, -1, -1, -1, true, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, utf8proc_sequences + 8821, false, -1, -1, -1, -1, -1, true, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, utf8proc_sequences + 8824, false, -1, -1, -1, -1, -1, true, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, utf8proc_sequences + 8827, false, -1, -1, -1, -1, -1, true, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, utf8proc_sequences + 8830, false, -1, -1, -1, -1, -1, true, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, utf8proc_sequences + 8833, false, -1, -1, -1, -1, -1, true, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, utf8proc_sequences + 8836, false, -1, -1, -1, -1, -1, true, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, utf8proc_sequences + 8839, false, -1, -1, -1, -1, -1, true, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, utf8proc_sequences + 8842, false, -1, -1, -1, -1, -1, true, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, utf8proc_sequences + 8845, false, -1, -1, -1, -1, -1, true, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, utf8proc_sequences + 8848, false, -1, -1, -1, -1, -1, true, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, utf8proc_sequences + 8851, false, -1, -1, -1, -1, -1, true, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, utf8proc_sequences + 8854, false, -1, -1, -1, -1, -1, true, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, utf8proc_sequences + 8857, false, -1, -1, -1, -1, -1, true, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, utf8proc_sequences + 8860, false, -1, -1, -1, -1, -1, true, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, utf8proc_sequences + 8863, false, -1, -1, -1, -1, -1, true, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, utf8proc_sequences + 8866, false, -1, -1, -1, -1, -1, true, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, utf8proc_sequences + 8869, false, -1, -1, -1, -1, -1, true, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, utf8proc_sequences + 8872, false, -1, -1, -1, -1, -1, true, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, utf8proc_sequences + 8875, false, -1, -1, -1, -1, -1, true, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, utf8proc_sequences + 8878, false, -1, -1, -1, -1, -1, true, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, utf8proc_sequences + 8881, false, -1, -1, -1, -1, -1, true, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, utf8proc_sequences + 8884, false, -1, -1, -1, -1, -1, true, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, utf8proc_sequences + 8887, false, -1, -1, -1, -1, -1, true, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, utf8proc_sequences + 8890, false, -1, -1, -1, -1, -1, true, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, utf8proc_sequences + 8893, false, -1, -1, -1, -1, -1, true, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, 0, utf8proc_sequences + 8896, false, -1, -1, -1, -1, -1, true, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_R, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 8899, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 8902, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 8902, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 8904, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 8904, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 8904, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 8904, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 8906, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 8906, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 8906, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 8906, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 8908, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 8908, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 8908, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 8908, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 8910, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 8910, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 8910, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 8910, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 8912, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 8912, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 8912, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 8912, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 8914, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 8914, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 8914, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 8914, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 8916, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 8916, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 8916, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 8916, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 8918, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 8918, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 8918, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 8918, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 8920, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 8920, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 8920, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 8920, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 8922, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 8922, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 8922, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 8922, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 8924, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 8924, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 8924, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 8924, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 8926, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 8926, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 8926, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 8926, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 8928, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 8928, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 8930, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 8930, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 8932, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 8932, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 8934, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 8934, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 8936, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 8936, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 8938, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 8938, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 8940, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 8940, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 8940, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 8940, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 8942, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 8942, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 8942, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 8942, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 8944, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 8944, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 8944, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 8944, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 8946, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 8946, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 8946, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 8946, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 8948, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 8948, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 8950, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 8950, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 8950, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 8950, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 8952, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 8952, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 8954, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 8954, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 8954, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 8954, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 8956, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 8956, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 8956, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 8956, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 8958, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 8958, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 8960, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 8960, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 8962, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 8962, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 8962, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 8962, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 8964, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 8964, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 8966, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 8966, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 8968, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 8968, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 8970, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 8972, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 8972, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 8974, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 8974, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 8976, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 8976, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 8978, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 8978, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 8978, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 8978, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 8980, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 8980, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 8982, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 8982, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 8985, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 8985, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 8988, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 8988, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 8991, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 8991, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 8994, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 8994, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 8997, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 8997, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9000, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9000, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9000, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9003, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9003, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9003, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9006, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9006, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9006, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 9006, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9008, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9011, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9014, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9017, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9020, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9023, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9026, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9029, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9032, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9035, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9038, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9041, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9044, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9047, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9050, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9053, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9056, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9059, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9062, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9065, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9068, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9071, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9074, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9077, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9080, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9083, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9086, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9089, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9092, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9095, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9098, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9101, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9104, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9107, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9110, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9113, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9116, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9119, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9122, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9125, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9128, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9131, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9134, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9137, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9140, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9143, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9146, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9149, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9152, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9155, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9158, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9161, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9164, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9167, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9170, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9173, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9176, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9179, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9182, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9185, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9188, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9191, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9194, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9197, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9200, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9203, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9206, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9209, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9212, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9215, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9218, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9221, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9224, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9227, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9230, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9233, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9236, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9239, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9242, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9245, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9248, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9251, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9254, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9257, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9260, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9263, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9266, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9269, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9272, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9275, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9278, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9281, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9284, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9287, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9291, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9295, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9299, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9303, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9307, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9311, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9314, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9014, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9317, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9017, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9320, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9323, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9029, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9326, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9032, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9035, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9329, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9332, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9047, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9335, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9050, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9053, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9338, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9341, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9059, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9344, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9062, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9065, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9152, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9155, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9164, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9167, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9170, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9182, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9185, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9188, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9191, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9203, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9206, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9209, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9347, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9221, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9350, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9353, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9239, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9356, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9242, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9245, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9284, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9359, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9362, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9269, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9365, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9272, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9275, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9008, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9011, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9368, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9014, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9371, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9020, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9023, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9026, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9029, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9374, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9038, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9041, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9044, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9047, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9377, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9059, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9068, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9071, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9074, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9077, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9080, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9086, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9089, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9092, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9095, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9098, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9101, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9380, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9104, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9107, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9110, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9113, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9116, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9119, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9125, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9128, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9131, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9134, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9137, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9140, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9143, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9146, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9149, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9158, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9161, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9173, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9176, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9179, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9182, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9185, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9194, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9197, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9200, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9203, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9383, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9212, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9215, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9218, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9221, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9230, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9233, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9236, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9239, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9386, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9248, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9251, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9389, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9260, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9263, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9266, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9269, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9392, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 9014, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 9371, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 9029, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 9374, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 9047, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 9377, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 9059, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 9395, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 9098, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 9398, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 9401, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 9404, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 9182, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 9185, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 9203, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 9239, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 9386, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 9269, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 9392, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 9407, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 9411, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 9415, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9419, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9422, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9425, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9428, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9431, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9434, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9437, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9440, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9443, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9446, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9449, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9452, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9455, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9458, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9461, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9464, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9467, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9470, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9473, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9476, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9479, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9482, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9485, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9401, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9488, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9491, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9494, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9497, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9419, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9422, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9425, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9428, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9431, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9434, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9437, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9440, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9443, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9446, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9449, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9452, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9455, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9458, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9461, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9464, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9467, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9470, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9473, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9476, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9479, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9482, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9485, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9401, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9488, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9491, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9494, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9497, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9479, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9482, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9485, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9401, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9398, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9404, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9122, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 9089, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 9092, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 9095, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 9479, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 9482, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 9485, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 9122, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 9125, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9500, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9500, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PS, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PE, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9503, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9507, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9507, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9511, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9515, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9519, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9523, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9527, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9531, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9531, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9535, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9539, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9543, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9547, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9551, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9555, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9555, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9559, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9563, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9563, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9567, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9567, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9571, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9575, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9575, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9579, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9583, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9583, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9587, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9587, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9591, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9595, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9595, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9599, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9599, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9603, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9607, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9611, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9615, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9615, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9619, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9623, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9627, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9631, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9635, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9635, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9639, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9643, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9647, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9651, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9655, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9659, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9659, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9663, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9663, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9667, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9667, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9671, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9675, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9679, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9683, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9687, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9691, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9695, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9699, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9703, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9707, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9711, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9715, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9719, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9719, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9723, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9727, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9731, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9735, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9735, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9739, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9743, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9747, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9751, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9755, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9759, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9763, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9767, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9771, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9775, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9779, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9783, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9787, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9791, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9795, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9799, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9803, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9807, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9811, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9815, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9819, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9823, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9639, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9647, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9827, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9831, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9835, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9839, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9843, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9847, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9843, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9835, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9851, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9855, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9859, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9863, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9867, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9847, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9611, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 9571, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9871, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 9875, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9879, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9883, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9887, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9892, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9897, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9902, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9907, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9912, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9917, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9922, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9926, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9945, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SC, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 9954, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, utf8proc_sequences + 9959, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, utf8proc_sequences + 9961, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, utf8proc_sequences + 9963, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, utf8proc_sequences + 9965, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, utf8proc_sequences + 1333, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, utf8proc_sequences + 9967, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, utf8proc_sequences + 9969, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PS, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, utf8proc_sequences + 9971, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PE, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, utf8proc_sequences + 9973, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, utf8proc_sequences + 9975, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, utf8proc_sequences + 9977, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PD, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, utf8proc_sequences + 9979, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PD, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, utf8proc_sequences + 9981, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PC, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, utf8proc_sequences + 9983, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PS, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, utf8proc_sequences + 4517, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PE, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, utf8proc_sequences + 4519, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PS, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, utf8proc_sequences + 9985, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PE, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, utf8proc_sequences + 9987, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PS, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, utf8proc_sequences + 9989, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PE, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, utf8proc_sequences + 9991, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PS, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, utf8proc_sequences + 9993, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PE, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, utf8proc_sequences + 9995, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PS, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, utf8proc_sequences + 9997, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PE, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, utf8proc_sequences + 9999, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PS, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, utf8proc_sequences + 4892, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PE, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, utf8proc_sequences + 4894, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PS, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, utf8proc_sequences + 10001, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PE, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, utf8proc_sequences + 10003, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PS, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, utf8proc_sequences + 10005, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PE, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, utf8proc_sequences + 10007, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PS, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, utf8proc_sequences + 10009, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PE, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_VERTICAL, utf8proc_sequences + 10011, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 10013, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PC, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_COMPAT, utf8proc_sequences + 9983, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_CS, UTF8PROC_DECOMP_TYPE_SMALL, utf8proc_sequences + 9959, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SMALL, utf8proc_sequences + 9961, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_CS, UTF8PROC_DECOMP_TYPE_SMALL, utf8proc_sequences + 4454, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SMALL, utf8proc_sequences + 1333, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_CS, UTF8PROC_DECOMP_TYPE_SMALL, utf8proc_sequences + 9965, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SMALL, utf8proc_sequences + 9969, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SMALL, utf8proc_sequences + 9967, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PD, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SMALL, utf8proc_sequences + 9979, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PS, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SMALL, utf8proc_sequences + 4517, true, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PE, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SMALL, utf8proc_sequences + 4519, true, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PS, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SMALL, utf8proc_sequences + 9985, true, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PE, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SMALL, utf8proc_sequences + 9987, true, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PS, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SMALL, utf8proc_sequences + 9989, true, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PE, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SMALL, utf8proc_sequences + 9991, true, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ET, UTF8PROC_DECOMP_TYPE_SMALL, utf8proc_sequences + 10015, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SMALL, utf8proc_sequences + 10017, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SMALL, utf8proc_sequences + 10019, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ES, UTF8PROC_DECOMP_TYPE_SMALL, utf8proc_sequences + 4511, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PD, 0, UTF8PROC_BIDI_CLASS_ES, UTF8PROC_DECOMP_TYPE_SMALL, utf8proc_sequences + 10021, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SMALL, utf8proc_sequences + 10023, true, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SMALL, utf8proc_sequences + 10025, true, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SMALL, utf8proc_sequences + 4515, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SMALL, utf8proc_sequences + 10027, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SC, 0, UTF8PROC_BIDI_CLASS_ET, UTF8PROC_DECOMP_TYPE_SMALL, utf8proc_sequences + 10029, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ET, UTF8PROC_DECOMP_TYPE_SMALL, utf8proc_sequences + 10031, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_SMALL, utf8proc_sequences + 10033, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 10035, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 10038, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 10041, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 10044, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 10047, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 10050, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 10053, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 10056, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 10059, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 10062, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 10065, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 10068, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 10071, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 10074, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 10077, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 10079, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 10079, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 10081, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 10081, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 10083, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 10083, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 10085, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 10085, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 10087, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 10087, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 10087, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 10087, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 10089, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 10089, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 10091, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 10091, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 10091, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 10091, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 10093, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 10093, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 10095, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 10095, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 10095, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 10095, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 10097, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 10097, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 10097, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 10097, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 10099, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 10099, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 10099, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 10099, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 10101, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 10101, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 10101, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 10101, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 10103, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 10103, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 10103, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 10103, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 10105, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 10105, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 10107, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 10107, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 10109, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 10109, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 10111, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 10111, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 10113, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 10113, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 10113, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 10113, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 10115, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 10115, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 10115, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 10115, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 10117, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 10117, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 10117, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 10117, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 10119, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 10119, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 10119, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 10119, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 10121, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 10121, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 10121, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 10121, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 10123, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 10123, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 10123, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 10123, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 10125, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 10125, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 10125, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 10125, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 10127, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 10127, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 10127, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 10127, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 10129, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 10129, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 10129, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 10129, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 10131, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 10131, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 10131, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 10131, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 10133, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 10133, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 10133, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 10133, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 10135, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 10135, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 10135, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 10135, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 10137, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 10137, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 10137, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 10137, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 10139, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 10139, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 10139, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 10139, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 10141, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 10141, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 10141, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 10141, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 10143, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 10143, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 8980, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 8980, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 10145, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 10145, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_INITIAL, utf8proc_sequences + 10145, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_MEDIAL, utf8proc_sequences + 10145, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 10147, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 10147, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 10150, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 10150, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 10153, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 10153, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_ISOLATED, utf8proc_sequences + 10156, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_AL, UTF8PROC_DECOMP_TYPE_FINAL, utf8proc_sequences + 10156, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 9967, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 10159, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ET, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 10015, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SC, 0, UTF8PROC_BIDI_CLASS_ET, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 10029, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ET, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 10031, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 10017, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 10161, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PS, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 4517, true, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PE, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 4519, true, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 10019, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ES, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 4511, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_CS, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 9959, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PD, 0, UTF8PROC_BIDI_CLASS_ES, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 10021, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_CS, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 4454, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_CS, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 10163, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_ND, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 4497, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_ND, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 72, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_ND, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 60, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_ND, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 62, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_ND, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 4499, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_ND, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 4501, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_ND, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 4503, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_ND, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 4505, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_ND, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 4507, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_ND, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 4509, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_CS, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 9965, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 1333, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 10023, true, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 4515, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 10025, true, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 9969, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 10033, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 2376, false, -1, 65345, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10165},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 2380, false, -1, 65346, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10167},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 4532, false, -1, 65347, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10169},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 2382, false, -1, 65348, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10171},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 2384, false, -1, 65349, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10173},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 4571, false, -1, 65350, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10175},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 2388, false, -1, 65351, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10177},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 2390, false, -1, 65352, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10179},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 2392, false, -1, 65353, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10181},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 2394, false, -1, 65354, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10183},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 2396, false, -1, 65355, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10185},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 2398, false, -1, 65356, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10187},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 2400, false, -1, 65357, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10189},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 2402, false, -1, 65358, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10191},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 2404, false, -1, 65359, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10193},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 2408, false, -1, 65360, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10195},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 4553, false, -1, 65361, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10197},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 2410, false, -1, 65362, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10199},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 5231, false, -1, 65363, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10201},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 2412, false, -1, 65364, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10203},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 2414, false, -1, 65365, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10205},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 4662, false, -1, 65366, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10207},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 2416, false, -1, 65367, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10209},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 4689, false, -1, 65368, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10211},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 5245, false, -1, 65369, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10213},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 4565, false, -1, 65370, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10215},
+ {UTF8PROC_CATEGORY_PS, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 10009, true, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 10027, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PE, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 10011, true, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 10217, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PC, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 9983, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 4387, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 0, false, 65313, -1, 65313, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 2, false, 65314, -1, 65314, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 4, false, 65315, -1, 65315, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 6, false, 65316, -1, 65316, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 8, false, 65317, -1, 65317, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 10, false, 65318, -1, 65318, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 12, false, 65319, -1, 65319, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 14, false, 65320, -1, 65320, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 16, false, 65321, -1, 65321, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 18, false, 65322, -1, 65322, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 20, false, 65323, -1, 65323, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 22, false, 65324, -1, 65324, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 24, false, 65325, -1, 65325, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 26, false, 65326, -1, 65326, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 28, false, 65327, -1, 65327, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 30, false, 65328, -1, 65328, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 32, false, 65329, -1, 65329, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 34, false, 65330, -1, 65330, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 36, false, 65331, -1, 65331, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 38, false, 65332, -1, 65332, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 40, false, 65333, -1, 65333, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 42, false, 65334, -1, 65334, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 44, false, 65335, -1, 65335, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 46, false, 65336, -1, 65336, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 48, false, 65337, -1, 65337, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 50, false, 65338, -1, 65338, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PS, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 9985, true, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 10219, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PE, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 9987, true, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 10221, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PS, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 10223, true, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PE, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 10225, true, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 9963, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PS, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10001, true, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PE, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10003, true, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 9961, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_PO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10227, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 6963, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10229, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10231, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10233, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10235, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10237, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10239, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10241, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10243, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10245, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10247, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 6871, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 6873, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 6875, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 6877, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 6879, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 6881, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 6883, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 6885, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 6887, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 6889, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 6891, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 6893, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 6895, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 6897, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 6899, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 6901, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 6903, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 6905, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 6907, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 6909, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 6911, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 6913, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 6915, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 6917, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 6919, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 6921, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 6923, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 6925, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 6927, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 6929, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 6931, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 6933, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 6935, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 6937, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 6939, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 6941, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 6943, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 6945, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 6947, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 6949, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 6951, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 6953, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 6955, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 6957, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10249, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10251, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10253, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10255, false, -1, -1, -1, -1, -1, false, true, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10257, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10259, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10261, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10263, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10265, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10267, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10269, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10271, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10273, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10275, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10277, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10279, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10281, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10283, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10285, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10287, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10289, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10291, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10293, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10295, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10297, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10299, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10301, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10303, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10305, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10307, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10309, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10311, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10313, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10315, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10317, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10319, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10321, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10323, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10325, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10327, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10329, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10331, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10333, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10335, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10337, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10339, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10341, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10343, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10345, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10347, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10349, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10351, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10353, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10355, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10357, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SC, 0, UTF8PROC_BIDI_CLASS_ET, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 10359, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SC, 0, UTF8PROC_BIDI_CLASS_ET, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 10361, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 10363, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SK, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 10365, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 10367, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SC, 0, UTF8PROC_BIDI_CLASS_ET, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 10369, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SC, 0, UTF8PROC_BIDI_CLASS_ET, UTF8PROC_DECOMP_TYPE_WIDE, utf8proc_sequences + 10371, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10373, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10375, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10377, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10379, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10381, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10383, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_ON, UTF8PROC_DECOMP_TYPE_NARROW, utf8proc_sequences + 10385, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_CF, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, false, -1, -1, -1, -1, -1, false, false, true, false, NULL},
+ {UTF8PROC_CATEGORY_NL, 0, UTF8PROC_BIDI_CLASS_ON, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 66600, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10387},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 66601, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10389},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 66602, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10391},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 66603, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10393},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 66604, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10395},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 66605, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10397},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 66606, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10399},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 66607, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10401},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 66608, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10403},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 66609, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10405},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 66610, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10407},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 66611, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10409},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 66612, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10411},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 66613, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10413},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 66614, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10415},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 66615, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10417},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 66616, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10419},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 66617, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10421},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 66618, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10423},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 66619, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10425},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 66620, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10427},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 66621, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10429},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 66622, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10431},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 66623, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10433},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 66624, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10435},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 66625, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10437},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 66626, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10439},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 66627, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10441},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 66628, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10443},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 66629, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10445},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 66630, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10447},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 66631, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10449},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 66632, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10451},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 66633, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10453},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 66634, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10455},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 66635, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10457},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 66636, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10459},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 66637, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10461},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 66638, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10463},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, 66639, -1, -1, -1, false, false, false, false, utf8proc_sequences + 10465},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 66560, -1, 66560, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 66561, -1, 66561, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 66562, -1, 66562, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 66563, -1, 66563, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 66564, -1, 66564, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 66565, -1, 66565, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 66566, -1, 66566, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 66567, -1, 66567, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 66568, -1, 66568, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 66569, -1, 66569, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 66570, -1, 66570, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 66571, -1, 66571, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 66572, -1, 66572, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 66573, -1, 66573, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 66574, -1, 66574, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 66575, -1, 66575, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 66576, -1, 66576, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 66577, -1, 66577, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 66578, -1, 66578, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 66579, -1, 66579, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 66580, -1, 66580, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 66581, -1, 66581, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 66582, -1, 66582, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 66583, -1, 66583, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 66584, -1, 66584, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 66585, -1, 66585, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 66586, -1, 66586, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 66587, -1, 66587, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 66588, -1, 66588, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 66589, -1, 66589, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 66590, -1, 66590, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 66591, -1, 66591, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 66592, -1, 66592, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 66593, -1, 66593, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 66594, -1, 66594, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 66595, -1, 66595, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 66596, -1, 66596, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 66597, -1, 66597, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 66598, -1, 66598, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, 66599, -1, 66599, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_NO, 0, UTF8PROC_BIDI_CLASS_R, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 22080, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 22140, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10467, false, -1, -1, -1, -1, -1, true, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10470, false, -1, -1, -1, 22200, -1, true, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10473, false, -1, -1, -1, -1, -1, true, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10476, false, -1, -1, -1, -1, -1, true, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10479, false, -1, -1, -1, -1, -1, true, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10482, false, -1, -1, -1, -1, -1, true, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10485, false, -1, -1, -1, -1, -1, true, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_MC, 216, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, -1, 54, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MC, 216, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_MC, 226, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_MC, 216, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, -1, 55, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MC, 216, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, -1, 56, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MC, 216, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, -1, 57, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MC, 216, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, -1, 58, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_MC, 216, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, -1, 59, false, false, false, true, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 22260, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, NULL, false, -1, -1, -1, 22320, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10488, false, -1, -1, -1, 22380, -1, true, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10491, false, -1, -1, -1, 22440, -1, true, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10494, false, -1, -1, -1, -1, -1, true, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10497, false, -1, -1, -1, -1, -1, true, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10500, false, -1, -1, -1, -1, -1, true, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10503, false, -1, -1, -1, -1, -1, true, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 2376, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 2388, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 2394, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 2396, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 2404, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 5231, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 2412, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 2414, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 4662, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 2416, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 4689, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 5245, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 0, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 2, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 4, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 10, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 20, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 24, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 26, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 30, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 32, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 34, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 36, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 38, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 40, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 42, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 44, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 46, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 48, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 50, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 10506, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 10508, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 10510, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 10512, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 10514, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 10516, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 10518, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 10520, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 1504, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 10522, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 10524, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 10526, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 10528, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 10530, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 10532, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 10534, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 10536, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 10538, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 1508, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 10540, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 1470, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 10542, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 10544, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 10546, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 4567, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 10548, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 1382, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 1384, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 1388, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 1390, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 1392, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 1394, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 1396, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 1326, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 1398, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 1400, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 67, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 1402, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 1404, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 1406, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 1410, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 1502, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 1412, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 1414, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 1416, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 1418, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 1420, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 1422, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 1424, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_SM, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 10550, true, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 10552, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 10554, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 10556, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 10558, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 10560, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 10562, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LU, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 10564, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LL, 0, UTF8PROC_BIDI_CLASS_L, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 1482, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_ND, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 4497, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_ND, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 72, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_ND, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 60, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_ND, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 62, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_ND, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 4499, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_ND, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 4501, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_ND, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 4503, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_ND, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 4505, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_ND, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 4507, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_ND, 0, UTF8PROC_BIDI_CLASS_EN, UTF8PROC_DECOMP_TYPE_FONT, utf8proc_sequences + 4509, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10566, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10568, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10570, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10572, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10574, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10576, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10578, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10580, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10582, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10584, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10586, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10588, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10590, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10592, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10594, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10596, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10598, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10600, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10602, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10604, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10606, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10608, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10610, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10612, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10614, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 5518, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10616, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10618, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10620, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10622, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10624, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10626, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10628, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10630, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10632, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10634, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10636, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10638, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10640, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10642, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10644, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10646, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10648, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10650, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10652, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10654, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10656, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10658, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10660, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10662, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10664, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10666, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10668, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10670, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10672, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10674, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10676, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10678, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10680, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10682, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10684, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10686, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10688, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10690, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10692, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10694, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10696, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10698, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10700, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10702, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10704, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10706, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10708, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10710, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10712, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10714, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10716, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10718, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10720, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10722, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10724, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10726, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10728, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10730, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10732, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10734, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10736, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10738, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10740, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10742, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10744, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10746, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10748, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10750, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10752, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10754, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10756, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10758, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10760, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 5570, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10762, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10764, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10766, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10768, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10770, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10772, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10774, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10776, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10778, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10780, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10782, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10784, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10786, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10788, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10790, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10792, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10794, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10796, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10798, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10800, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10802, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10804, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10806, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10808, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 5594, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10810, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10812, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10814, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10816, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10818, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10820, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10822, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10824, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10826, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10828, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10830, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10832, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10834, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10836, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10838, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10840, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10842, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10844, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10846, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10848, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10850, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10852, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10854, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10856, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10858, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10860, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10862, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10864, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10866, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10868, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10870, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10872, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10874, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10876, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10878, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10880, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10882, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10884, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10886, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10888, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10890, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10892, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10894, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10896, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10898, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10900, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10902, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10904, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10906, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10908, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10910, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10912, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10914, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10916, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10918, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10920, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10922, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10924, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10926, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10928, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10930, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10932, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10934, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10936, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10938, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10940, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10942, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10944, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10946, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10948, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10950, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10952, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10954, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10956, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10958, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10960, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10962, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10964, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10966, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10968, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10970, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10972, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10974, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10976, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10978, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10980, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10982, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10984, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10986, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10988, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10990, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10992, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10994, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10996, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 10998, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11000, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11002, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11004, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11006, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11008, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11010, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11012, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11014, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11016, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11018, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11020, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11022, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11024, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11026, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11028, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11030, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11032, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11034, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11036, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11038, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11040, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11042, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11044, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11046, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11048, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11050, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11052, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11054, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11056, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11058, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11060, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11062, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11064, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11066, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11068, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11070, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11072, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11074, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11076, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11078, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11080, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11082, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11084, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11086, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11088, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11090, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11092, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11094, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11096, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11098, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11100, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11102, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11104, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11106, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11108, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11110, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11112, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11114, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11116, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11118, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11120, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11122, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11124, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11126, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11128, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11130, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11132, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11134, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11136, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11138, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11140, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11142, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11144, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11146, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11148, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11150, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11152, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11154, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11156, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11158, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11160, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11162, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11164, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11166, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11168, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11170, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11172, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11174, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11176, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11178, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11180, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11182, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11184, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11186, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11188, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11190, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11192, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11194, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11196, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11198, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11200, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11202, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11204, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11206, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11208, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11210, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11212, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11214, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11216, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11218, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11220, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11222, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11224, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11226, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11228, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11230, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11232, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11234, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11236, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11238, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11240, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11242, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11244, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11246, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11248, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11250, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11252, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11254, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11256, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11258, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11260, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11262, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11264, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11266, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11268, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11270, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11272, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11274, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11276, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11278, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11280, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11282, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11284, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11286, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11288, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11290, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11292, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11294, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11296, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11298, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11300, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11302, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11304, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11306, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11308, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11310, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11312, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11314, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11316, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11318, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11320, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11322, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11324, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11326, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11328, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11330, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11332, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11334, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11336, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11338, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11340, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11342, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11344, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 5774, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11346, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11348, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11350, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11352, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11354, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11356, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11358, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11360, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11362, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11364, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11366, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 5788, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11368, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11370, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11372, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11374, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11376, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11378, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11380, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11382, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11384, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11386, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11388, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11390, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11392, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11394, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11396, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11398, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11400, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11402, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11404, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11406, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11408, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11410, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11412, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11414, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11416, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11418, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11420, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11422, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11424, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11426, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11428, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11430, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11432, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11434, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11436, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11438, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11440, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11442, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11444, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11446, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11448, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11450, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11452, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11454, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11456, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11458, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11460, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11462, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11464, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11466, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11468, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11470, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11472, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11474, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11476, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11478, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11480, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11482, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11484, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11486, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11488, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11490, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 5884, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11492, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 5892, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11494, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11496, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11498, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11500, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 5902, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+ {UTF8PROC_CATEGORY_LO, 0, UTF8PROC_BIDI_CLASS_L, 0, utf8proc_sequences + 11502, false, -1, -1, -1, -1, -1, false, false, false, false, NULL},
+};
+
+const int32_t utf8proc_combinations[] = {
+ 192, 193, 194, 195, 196, 197, -1,
+ 256, 258, 260, 550, 461, -1, -1, 512,
+ 514, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ 7680, 7840, -1, -1, -1, -1, -1, 7842,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 262, 264,
+ -1, -1, -1, 199, -1, -1, -1, 266,
+ 268, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 200, 201, 202, 7868, 203, -1, 552,
+ 274, 276, 280, 278, 282, -1, -1, 516,
+ 518, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 7864, -1, 7704, 7706, -1, -1, 7866,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 204, 205, 206,
+ 296, 207, -1, -1, 298, 300, 302, 304,
+ 463, -1, -1, 520, 522, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 7882, -1, -1,
+ 7724, -1, -1, 7880, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 504, 323, -1, 209, -1, -1, 325,
+ -1, -1, -1, 7748, 327, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 7750, 7752, 7754, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 210, 211, 212,
+ 213, 214, -1, -1, 332, 334, 490, 558,
+ 465, 336, 416, 524, 526, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 7884, -1, -1,
+ -1, -1, -1, 7886, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 217, 218, 219, 360, 220, 366, -1,
+ 362, 364, 370, -1, 467, 368, 431, 532,
+ 534, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 7908, -1, 7798, 7796, -1, 7794, 7910,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 7922, 221, 374,
+ 7928, 376, -1, -1, 562, -1, -1, 7822,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 7924, -1, -1,
+ -1, -1, -1, 7926, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 224, 225, 226, 227, 228, 229, -1,
+ 257, 259, 261, 551, 462, -1, -1, 513,
+ 515, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ 7681, 7841, -1, -1, -1, -1, -1, 7843,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 263, 265,
+ -1, -1, -1, 231, -1, -1, -1, 267,
+ 269, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 232, 233, 234, 7869, 235, -1, 553,
+ 275, 277, 281, 279, 283, -1, -1, 517,
+ 519, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 7865, -1, 7705, 7707, -1, -1, 7867,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 236, 237, 238,
+ 297, 239, -1, -1, 299, 301, 303, -1,
+ 464, -1, -1, 521, 523, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 7883, -1, -1,
+ 7725, -1, -1, 7881, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 505, 324, -1, 241, -1, -1, 326,
+ -1, -1, -1, 7749, 328, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 7751, 7753, 7755, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 242, 243, 244,
+ 245, 246, -1, -1, 333, 335, 491, 559,
+ 466, 337, 417, 525, 527, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 7885, -1, -1,
+ -1, -1, -1, 7887, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 249, 250, 251, 361, 252, 367, -1,
+ 363, 365, 371, -1, 468, 369, 432, 533,
+ 535, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 7909, -1, 7799, 7797, -1, 7795, 7911,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 7923, 253, 375,
+ 7929, 255, 7833, -1, 563, -1, -1, 7823,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 7925, -1, -1,
+ -1, -1, -1, 7927, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 7696,
+ -1, -1, -1, 7690, 270, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 7692, 7694, 7698, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 7697, -1, -1, -1, 7691,
+ 271, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 7693, 7695, 7699,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 500, 284, -1, -1, -1, 290,
+ 7712, 286, -1, 288, 486, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 501, 285,
+ -1, -1, -1, 291, 7713, 287, -1, 289,
+ 487, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 292, -1, 7718, -1, 7720,
+ -1, -1, -1, 7714, 542, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 7716, -1, -1, -1, 7722, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 293,
+ -1, 7719, -1, 7721, -1, -1, -1, 7715,
+ 543, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 7717, 7830, -1,
+ -1, 7723, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 308, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 309,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ 496, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 7728, -1, -1, -1, -1, 310,
+ -1, -1, -1, -1, 488, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 7730, 7732, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 7729, -1,
+ -1, -1, -1, 311, -1, -1, -1, -1,
+ 489, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 7731, 7733, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 313, -1, -1, -1, -1, 315,
+ -1, -1, -1, -1, 317, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 7734, 7738, 7740, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 314, -1,
+ -1, -1, -1, 316, -1, -1, -1, -1,
+ 318, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 7735, 7739, 7741,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 340, -1, -1, -1, -1, 342,
+ -1, -1, -1, 7768, 344, -1, -1, 528,
+ 530, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 7770, 7774, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 341, -1,
+ -1, -1, -1, 343, -1, -1, -1, 7769,
+ 345, -1, -1, 529, 531, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 7771, 7775, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 346, 348, -1, -1, -1, 350,
+ -1, -1, -1, 7776, 352, -1, -1, -1,
+ -1, 536, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 7778, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 347, 349,
+ -1, -1, -1, 351, -1, -1, -1, 7777,
+ 353, -1, -1, -1, -1, 537, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 7779, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 354,
+ -1, -1, -1, 7786, 356, -1, -1, -1,
+ -1, 538, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 7788, 7790, 7792, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 7831, -1, 355, -1, -1, -1, 7787,
+ 357, -1, -1, -1, -1, 539, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 7789, 7791, 7793,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 7808, 7810, 372, -1, 7812, -1, -1,
+ -1, -1, -1, 7814, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 7816, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 7809, 7811, 373,
+ -1, 7813, 7832, -1, -1, -1, -1, 7815,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 7817, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 377, 7824, -1, -1, -1, -1,
+ -1, -1, -1, 379, 381, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 7826, 7828, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 378, 7825,
+ -1, -1, -1, -1, -1, -1, -1, 380,
+ 382, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 7827, 7829, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 475, 471, -1, -1, -1, -1, -1,
+ 469, -1, -1, -1, 473, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 476, 472, -1,
+ -1, -1, -1, -1, 470, -1, -1, -1,
+ 474, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ 478, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 479, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ 480, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 481, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 508, -1, -1, -1, -1, -1,
+ 482, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 509, -1,
+ -1, -1, -1, -1, 483, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ 492, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 493, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 494, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ 495, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 506, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 507, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 510, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 511, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ 554, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 555, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 7756, -1, -1, 7758, -1, -1,
+ 556, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 7757, -1,
+ -1, 7759, -1, -1, 557, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ 560, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 561, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 8173, 901, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 8129, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 8122, 902, -1,
+ -1, -1, -1, -1, 8121, 8120, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 7944, 7945, -1, 8124,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 8136, 904, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ 7960, 7961, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 8138, 905, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 7976, 7977, -1, 8140,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 8154, 906, -1, -1, 938, -1, -1,
+ 8153, 8152, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ 7992, 7993, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 8184, 908, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 8008, 8009, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 8170, 910, -1, -1, 939, -1, -1,
+ 8169, 8168, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 8025, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 8186, 911, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 8040, 8041, -1, 8188,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 8146, 912, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 8151, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 8048, 940, -1,
+ -1, -1, -1, -1, 8113, 8112, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 7936, 7937, 8118, 8115,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 8050, 941, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ 7952, 7953, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 8052, 942, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 7968, 7969, 8134, 8131,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 8054, 943, -1, -1, 970, -1, -1,
+ 8145, 8144, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ 7984, 7985, 8150, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 8162, 944, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 8167, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 8058, 973, -1, -1, 971, -1, -1,
+ 8161, 8160, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ 8016, 8017, 8166, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 8056, 972, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 8000, 8001, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 8060, 974, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ 8032, 8033, 8182, 8179, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 979, -1,
+ -1, 980, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 1024, -1, -1, -1, 1025, -1, -1,
+ -1, 1238, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 1027, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 1031, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 1036, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 1037, -1, -1, -1, 1252, -1, -1,
+ 1250, 1049, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 1264, -1, -1, 1262, 1038, -1, -1,
+ -1, 1266, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 1117, -1, -1, -1, 1253, -1, -1,
+ 1251, 1081, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 1104, -1, -1,
+ -1, 1105, -1, -1, -1, 1239, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 1107, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 1111, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 1116, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 1265, -1, -1, 1263, 1118, -1, -1,
+ -1, 1267, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 1142,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 1143, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 1244, -1, -1,
+ -1, 1217, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 1245, -1, -1, -1, 1218, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 1234, -1, -1,
+ -1, 1232, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 1235, -1, -1, -1, 1233, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 1242, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 1243, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 1246, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 1247, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 1254, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 1255, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 1258, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 1259, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 1260, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 1261, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 1268, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 1269, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 1272, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 1273, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 1570, 1571, 1573, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 1572,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 1574, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 1728,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 1730, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 1747,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 2345, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 2353, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 2356, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 2507, 2508, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ 2888, 2891, 2892, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 2964,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 3020, 3018, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ 3019, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 3144, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 3264, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 3271, 3272,
+ 3274, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 3275, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 3402, 3404, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 3403, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 3546, 3548, 3550, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 3549,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 4134, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 6918, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 6920,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 6922, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 6924,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 6926, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 6930,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 6971, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 6973,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 6976, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 6977,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 6979, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 7682, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 7684, 7686, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 7683,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 7685, 7687, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 7688, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 7689, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 7700, 7702, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 7701, 7703, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 7708, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 7709, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 7710, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 7711,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 7726, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 7727, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ 7736, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 7737, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 7742, -1, -1, -1, -1, -1,
+ -1, -1, -1, 7744, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 7746, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 7743, -1,
+ -1, -1, -1, -1, -1, -1, -1, 7745,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 7747, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 7760, 7762, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 7761, 7763, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 7764, -1, -1, -1, -1, -1,
+ -1, -1, -1, 7766, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 7765, -1,
+ -1, -1, -1, -1, -1, -1, -1, 7767,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ 7772, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 7773, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 7780, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 7781,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 7782, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 7783,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 7784, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 7785,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 7800, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 7801, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 7802, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 7803, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 7804, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 7806, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ 7805, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 7807, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 7820, -1, -1,
+ -1, -1, -1, 7818, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 7821, -1, -1, -1, -1, -1, 7819,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 7835, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 7846, 7844, -1,
+ 7850, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 7848, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 7847, 7845, -1, 7851, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 7849,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 7852,
+ -1, -1, -1, -1, -1, 7862, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 7853, -1, -1, -1, -1,
+ -1, 7863, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 7856, 7854, -1,
+ 7860, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 7858, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 7857, 7855, -1, 7861, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 7859,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 7872, 7870, -1,
+ 7876, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 7874, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 7873, 7871, -1, 7877, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 7875,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 7878,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 7879, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 7890, 7888, -1,
+ 7894, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 7892, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 7891, 7889, -1, 7895, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 7893,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 7896,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 7897, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 7900, 7898, -1,
+ 7904, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 7906, -1, -1,
+ -1, -1, -1, 7902, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 7901, 7899, -1, 7905, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 7907, -1, -1, -1, -1, -1, 7903,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 7914, 7912, -1,
+ 7918, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 7920, -1, -1,
+ -1, -1, -1, 7916, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 7915, 7913, -1, 7919, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 7921, -1, -1, -1, -1, -1, 7917,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 7938, 7940, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 7942, 8064,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 7939, 7941, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 7943, 8065, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 7946, 7948, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 7950, 8072,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 7947, 7949, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 7951, 8073, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 7954, 7956, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 7955, 7957, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 7962, 7964, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 7963, 7965, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 7970, 7972, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 7974, 8080,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 7971, 7973, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 7975, 8081, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 7978, 7980, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 7982, 8088,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 7979, 7981, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 7983, 8089, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 7986, 7988, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 7990, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 7987, 7989, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 7991, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 7994, 7996, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 7998, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 7995, 7997, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 7999, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 8002, 8004, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 8003, 8005, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 8010, 8012, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 8011, 8013, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 8018, 8020, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 8022, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 8019, 8021, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 8023, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 8027, 8029, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 8031, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 8034, 8036, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 8038, 8096, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 8035, 8037, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 8039, 8097,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 8042, 8044, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 8046, 8104, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 8043, 8045, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 8047, 8105,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 8066, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 8067,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 8068, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 8069,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 8070, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 8071,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 8074, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 8075,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 8076, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 8077,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 8078, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 8079,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 8082, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 8083,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 8084, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 8085,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 8086, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 8087,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 8090, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 8091,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 8092, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 8093,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 8094, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 8095,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 8098, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 8099,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 8100, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 8101,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 8102, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 8103,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 8106, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 8107,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 8108, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 8109,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 8110, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 8111,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 8114, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 8116,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 8119, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 8130,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 8132, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 8135,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 8141, 8142, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 8143, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 8157, 8158, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 8159, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ 8164, 8165, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 8172, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 8178, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 8180,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 8183, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ 8602, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 8603, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ 8622, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 8653, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ 8654, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 8655, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ 8708, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 8713, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ 8716, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 8740, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ 8742, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 8769, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ 8772, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 8775, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ 8777, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 8800, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ 8802, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 8813, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ 8814, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 8815, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ 8816, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 8817, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ 8820, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 8821, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ 8824, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 8825, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ 8832, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 8833, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ 8836, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 8837, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ 8840, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 8841, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ 8876, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 8877, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ 8878, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 8879, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ 8928, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 8929, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ 8930, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 8931, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ 8938, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 8939, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ 8940, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 8941, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ 10972, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 12364, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 12366, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 12368, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 12370, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 12372, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 12374, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 12376, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 12378, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 12380, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 12382, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 12384, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 12386, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 12389, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 12391, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 12393, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 12400, 12401, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 12403, 12404, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 12406, 12407, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 12409, 12410, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 12412, 12413, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 12436, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 12446, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 12460, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 12462, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 12464, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 12466, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 12468, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 12470, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 12472, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 12474, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 12476, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 12478, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 12480, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 12482, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 12485, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 12487, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 12489, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 12496, 12497, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 12499, 12500, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 12502, 12503, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 12505, 12506, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 12508, 12509, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 12532, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 12535, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 12536, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 12537, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 12538, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 12542, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 119134,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 119135, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ 119136, 119137, 119138, 119139, 119140, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 119227, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 119228,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 119229, 119231, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ 119230, 119232, -1, -1, -1, };
+
diff --git a/src/lib/util.c b/src/lib/util.c
new file mode 100644
index 0000000..50c14fa
--- /dev/null
+++ b/src/lib/util.c
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2015, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ */
+/* $Id: util.c 2214 2015-12-08 00:33:40Z wkliao $ */
+
+#if HAVE_CONFIG_H
+# include "ncconfig.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <mpi.h>
+#include "nc.h"
+#include "macro.h"
+
+/*----< ncmpii_sanity_check() >----------------------------------------------*/
+int ncmpii_sanity_check(int ncid,
+ int varid,
+ const MPI_Offset *start,
+ const MPI_Offset *count,
+ MPI_Offset bufcount,
+ enum API_KIND api,
+ int mustInDataMode,
+ int isFlexAPI,
+ int rw_flag,
+ int io_method,
+ NC **ncp,
+ NC_var **varp)
+{
+ /* all errors detected here are fatal, must return immediately */
+ int status;
+
+ /* check if ncid is valid */
+ status = ncmpii_NC_check_id(ncid, ncp);
+ if (status != NC_NOERR) return status;
+ /* For invalid ncid, we must return error now, as there is no way to
+ * continue with invalid ncp. However, collective APIs might hang if this
+ * error occurs only on a subset of processes
+ */
+
+ /* if this call must be made in data mode, check if currently is in define
+ * mode */
+ if (mustInDataMode && NC_indef(*ncp)) {
+ DEBUG_ASSIGN_ERROR(status, NC_EINDEFINE)
+ goto fn_exit;
+ }
+
+ /* check file write permission if this is write request */
+ if (rw_flag == WRITE_REQ && NC_readonly(*ncp)) {
+ DEBUG_ASSIGN_ERROR(status, NC_EPERM)
+ goto fn_exit;
+ }
+
+ if (io_method != NONBLOCKING_IO) { /* for blocking APIs */
+ /* check if in the right collective or independent mode and initialize
+ * MPI file handlers */
+ status = ncmpii_check_mpifh(*ncp, io_method);
+ if (status != NC_NOERR) goto fn_exit;
+ }
+
+ /* check if varid is valid */
+ status = ncmpii_NC_lookupvar(*ncp, varid, varp);
+ if (status != NC_NOERR) goto fn_exit;
+
+ /* for API var1, vara, vars, varm, and varn, start cannot be NULL */
+ if (start == NULL && api >= API_VAR1 && (*varp)->ndims > 0) {
+ DEBUG_ASSIGN_ERROR(status, NC_ENULLSTART)
+ goto fn_exit;
+ }
+
+ /* for API vara, vars, and varm, count cannot be NULL */
+ if (count == NULL && api >= API_VARA && (*varp)->ndims > 0) {
+ DEBUG_ASSIGN_ERROR(status, NC_ENULLCOUNT)
+ goto fn_exit;
+ }
+
+ /* for flexible APIs, bufcount cannot be negative */
+ if (isFlexAPI && bufcount < 0) {
+ DEBUG_ASSIGN_ERROR(status, NC_EINVAL)
+ goto fn_exit;
+ }
+
+fn_exit:
+ if ((*ncp)->safe_mode == 1 && io_method == COLL_IO) {
+ int min_st;
+ MPI_Allreduce(&status, &min_st, 1, MPI_INT, MPI_MIN, (*ncp)->nciop->comm);
+ if (status == NC_NOERR) status = min_st;
+ }
+ return status;
+}
+
diff --git a/src/lib/var.c b/src/lib/var.c
new file mode 100644
index 0000000..dfd0915
--- /dev/null
+++ b/src/lib/var.c
@@ -0,0 +1,939 @@
+/*
+ * Copyright (C) 2003, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ */
+/* $Id: var.c 2196 2015-11-27 22:31:05Z wkliao $ */
+
+#if HAVE_CONFIG_H
+# include "ncconfig.h"
+#endif
+
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#include <stdio.h>
+#include <string.h> /* memset() */
+#include <assert.h>
+
+#include <mpi.h>
+
+#include "nc.h"
+#include "ncx.h"
+#include "rnd.h"
+#include "macro.h"
+#include "utf8proc.h"
+
+/*----< ncmpii_free_NC_var() >------------------------------------------------*/
+/*
+ * Free var
+ * Formerly
+NC_free_var(var)
+ */
+inline void
+ncmpii_free_NC_var(NC_var *varp)
+{
+ if (varp == NULL) return;
+ ncmpii_free_NC_attrarray(&varp->attrs);
+ ncmpii_free_NC_string(varp->name);
+#ifdef ENABLE_SUBFILING
+ if (varp->num_subfiles > 1) /* deallocate it */
+ NCI_Free(varp->dimids_org);
+#endif
+ NCI_Free(varp);
+}
+
+
+/*----< ncmpii_new_x_NC_var() >-----------------------------------------------*/
+/*
+ * Common code for ncmpii_new_NC_var()
+ * and ncx_get_NC_var()
+ */
+NC_var *
+ncmpii_new_x_NC_var(NC_string *strp,
+ int ndims)
+{
+ NC_var *varp;
+ int shape_space = M_RNDUP(ndims * SIZEOF_MPI_OFFSET);
+ int dsizes_space = M_RNDUP(ndims * SIZEOF_MPI_OFFSET);
+ int dimids_space = M_RNDUP(ndims * SIZEOF_INT);
+ size_t sizeof_NC_var = M_RNDUP(sizeof(NC_var));
+ size_t sz = sizeof_NC_var + (size_t)(shape_space + dsizes_space + dimids_space);
+
+ /* this function allocates a contiguous memory space to put all
+ * members of NC_var structure together:
+ * dimid_space is for dimids[],
+ * shape_space is for shape[],
+ * dsizes_space is for dsizes[]
+ * (I don't know why M_RNDUP is needed here and why they should be kept
+ * in a contiguous memory space.)
+ */
+ varp = (NC_var *) NCI_Malloc(sz);
+ if (varp == NULL ) return NULL;
+
+ memset(varp, 0, sz);
+
+ varp->name = strp;
+ varp->ndims = ndims;
+
+ if (ndims != 0) {
+ /*
+ * NOTE: lint may complain about the next 3 lines:
+ * "pointer cast may result in improper alignment".
+ * We use the M_RNDUP() macro to get the proper alignment.
+ * roundup to a double
+ */
+ varp->shape = (MPI_Offset *)((char *)varp + sizeof_NC_var);
+ varp->dsizes = (MPI_Offset *)((char *)varp->shape + shape_space);
+ varp->dimids = (int *) ((char *)varp->dsizes + dsizes_space);
+ }
+
+ varp->xsz = 0;
+ varp->len = 0;
+ varp->begin = 0;
+
+ return varp;
+}
+
+
+/*----< ncmpii_new_NC_var() >------------------------------------------------*/
+/*
+ * Formerly, NC_new_var()
+ */
+static NC_var *
+ncmpii_new_NC_var(const char *uname, /* variable name (NULL terminated) */
+ nc_type type,
+ int ndims,
+ const int *dimids)
+{
+ NC_string *strp;
+ NC_var *varp;
+
+ char *name = (char *)utf8proc_NFC((const unsigned char *)uname);
+ if (name == NULL) return NULL;
+
+ strp = ncmpii_new_NC_string(strlen(name), name);
+ free(name);
+ if (strp == NULL) return NULL;
+
+ varp = ncmpii_new_x_NC_var(strp, ndims);
+ if (varp == NULL ) {
+ ncmpii_free_NC_string(strp);
+ return NULL;
+ }
+
+ varp->type = type;
+
+ if (ndims != 0 && dimids != NULL)
+ memcpy(varp->dimids, dimids, (size_t)ndims * SIZEOF_INT);
+
+ return(varp);
+}
+
+/*----< dup_NC_var() >--------------------------------------------------------*/
+NC_var *
+dup_NC_var(const NC_var *rvarp)
+{
+ NC_var *varp;
+
+ varp = ncmpii_new_NC_var(rvarp->name->cp, rvarp->type, rvarp->ndims,
+ rvarp->dimids);
+ if (varp == NULL) return NULL;
+
+ if (ncmpii_dup_NC_attrarray(&varp->attrs, &rvarp->attrs) != NC_NOERR) {
+ ncmpii_free_NC_var(varp);
+ return NULL;
+ }
+
+ /* copy the contents of shape may not be necessary, as one must call
+ * ncmpii_NC_computeshapes() to recompute it after a new variable is
+ * created */
+ memcpy(varp->shape, rvarp->shape, (size_t)rvarp->ndims * SIZEOF_MPI_OFFSET);
+ memcpy(varp->dsizes, rvarp->dsizes, (size_t)rvarp->ndims * SIZEOF_MPI_OFFSET);
+ varp->xsz = rvarp->xsz;
+ varp->len = rvarp->len;
+ varp->begin = rvarp->begin;
+
+ return varp;
+}
+
+/* vararray */
+
+/*----< ncmpii_free_NC_vararray() >-------------------------------------------*/
+/*
+ * Free NC_vararray values.
+ * formerly
+NC_free_array()
+ */
+inline void
+ncmpii_free_NC_vararray(NC_vararray *ncap)
+{
+ int i;
+
+ assert(ncap != NULL);
+ if (ncap->nalloc == 0) return;
+
+ assert(ncap->value != NULL);
+ for (i=0; i<ncap->ndefined; i++) {
+ if (ncap->value[i] != NULL)
+ ncmpii_free_NC_var(ncap->value[i]);
+ }
+
+ NCI_Free(ncap->value);
+ ncap->value = NULL;
+ ncap->nalloc = 0;
+ ncap->ndefined = 0;
+}
+
+
+/*----< ncmpii_dup_NC_vararray() >--------------------------------------------*/
+int
+ncmpii_dup_NC_vararray(NC_vararray *ncap,
+ const NC_vararray *ref)
+{
+ int i, status=NC_NOERR;
+
+ assert(ref != NULL);
+ assert(ncap != NULL);
+
+ if (ref->nalloc == 0) {
+ ncap->nalloc = 0;
+ ncap->ndefined = 0;
+ ncap->value = NULL;
+ return NC_NOERR;
+ }
+
+ if (ref->nalloc > 0) {
+ ncap->value = (NC_var **) NCI_Calloc((size_t)ref->nalloc, sizeof(NC_var*));
+ if (ncap->value == NULL) DEBUG_RETURN_ERROR(NC_ENOMEM)
+ ncap->nalloc = ref->nalloc;
+ }
+
+ ncap->ndefined = 0;
+ for (i=0; i<ref->ndefined; i++) {
+ ncap->value[i] = dup_NC_var(ref->value[i]);
+ if (ncap->value[i] == NULL) {
+ DEBUG_ASSIGN_ERROR(status, NC_ENOMEM)
+ break;
+ }
+ }
+
+ if (status != NC_NOERR) {
+ ncmpii_free_NC_vararray(ncap);
+ return status;
+ }
+
+ ncap->ndefined = ref->ndefined;
+
+ return NC_NOERR;
+}
+
+
+/*
+ * Add a new handle on the end of an array of handles
+ * Formerly
+NC_incr_array(array, tail)
+ */
+int
+incr_NC_vararray(NC_vararray *ncap,
+ NC_var *newvarp)
+{
+ NC_var **vp;
+
+ assert(ncap != NULL);
+ assert(newvarp != NULL);
+
+ if (ncap->nalloc == 0) { /* no variable has been allocated yet */
+ assert(ncap->ndefined == 0);
+ vp = (NC_var **) NCI_Malloc(NC_ARRAY_GROWBY * sizeof(NC_var *));
+ if (vp == NULL) DEBUG_RETURN_ERROR(NC_ENOMEM)
+
+ ncap->value = vp;
+ ncap->nalloc = NC_ARRAY_GROWBY;
+ }
+ else if (ncap->ndefined + 1 > ncap->nalloc) {
+ vp = (NC_var **) NCI_Realloc(ncap->value,
+ (size_t)(ncap->nalloc + NC_ARRAY_GROWBY) * sizeof(NC_var *));
+ if (vp == NULL) DEBUG_RETURN_ERROR(NC_ENOMEM)
+
+ ncap->value = vp;
+ ncap->nalloc += NC_ARRAY_GROWBY;
+ }
+
+ if (newvarp != NULL) {
+ ncap->value[ncap->ndefined] = newvarp;
+ ncap->ndefined++;
+ }
+
+ return NC_NOERR;
+}
+
+
+inline static NC_var *
+elem_NC_vararray(const NC_vararray *ncap,
+ int varid)
+{
+ assert(ncap != NULL);
+ /* cast needed for braindead systems with signed MPI_Offset */
+ if ((varid < 0) || ncap->ndefined == 0 || varid >= ncap->ndefined)
+ return NULL;
+
+ assert(ncap->value != NULL);
+
+ return ncap->value[varid];
+}
+
+
+/* End vararray per se */
+
+
+/*
+ * Step thru NC_VARIABLE array, seeking match on name.
+ * Return varid or -1 on not found.
+ * *varpp is set to the appropriate NC_var.
+ * Formerly (sort of)
+NC_hvarid
+ */
+static int
+ncmpii_NC_findvar(const NC_vararray *ncap,
+ const char *uname,
+ NC_var **varpp)
+{
+ int varid;
+ size_t nchars;
+ char *name;
+ NC_var **loc;
+
+ assert (ncap != NULL);
+
+ if (ncap->ndefined == 0) return -1;
+
+ loc = (NC_var **) ncap->value;
+
+ /* normalized version of uname */
+ name = (char *)utf8proc_NFC((const unsigned char *)uname);
+ if (name == NULL) DEBUG_RETURN_ERROR(NC_ENOMEM)
+ nchars = strlen(name);
+
+ for (varid=0; varid<ncap->ndefined; varid++, loc++) {
+ if ((*loc)->name->nchars == nchars &&
+ strncmp((*loc)->name->cp, name, nchars) == 0) {
+ if (varpp != NULL)
+ *varpp = *loc;
+ free(name);
+ return (varid); /* Normal return */
+ }
+ }
+ free(name);
+ return (-1); /* not found */
+}
+
+/*
+ * For a netcdf type
+ * return the size of one element in the external representation.
+ * Note that arrays get rounded up to X_ALIGN boundaries.
+ * Formerly
+NC_xtypelen
+ * See also ncx_len()
+ */
+static int
+ncx_szof(nc_type type)
+{
+ switch(type){
+ case NC_BYTE:
+ case NC_CHAR: return (1);
+ case NC_SHORT: return (2);
+ case NC_INT: return X_SIZEOF_INT;
+ case NC_FLOAT: return X_SIZEOF_FLOAT;
+ case NC_DOUBLE: return X_SIZEOF_DOUBLE;
+ case NC_UBYTE: return (1);
+ case NC_USHORT: return (2);
+ case NC_UINT: return X_SIZEOF_UINT;
+ case NC_INT64: return X_SIZEOF_INT64;
+ case NC_UINT64: return X_SIZEOF_UINT64;
+ default:
+ assert("ncx_szof invalid type" == 0);
+ }
+ /* default */
+ return 0;
+}
+
+/*----< ncmpii_NC_var_shape64() >--------------------------------------------*/
+/*
+ * set varp->xsz, varp->shape and varp->len of a variable
+ */
+int
+ncmpii_NC_var_shape64(NC *ncp,
+ NC_var *varp,
+ const NC_dimarray *dims)
+{
+ int i;
+ MPI_Offset product = 1;
+
+ /* set the size of 1 element */
+ varp->xsz = ncx_szof(varp->type);
+
+ if (varp->ndims == 0) goto out;
+
+ /*
+ * use the user supplied dimension indices to determine the shape
+ */
+ for (i=0; i<varp->ndims; i++) {
+ const NC_dim *dimp;
+
+ if (varp->dimids[i] < 0)
+ DEBUG_RETURN_ERROR(NC_EBADDIM)
+
+ if (varp->dimids[i] >= ((dims != NULL) ? dims->ndefined : 1))
+ DEBUG_RETURN_ERROR(NC_EBADDIM)
+
+ /* get the pointer to the dim object */
+ dimp = ncmpii_elem_NC_dimarray(dims, varp->dimids[i]);
+ varp->shape[i] = dimp->size;
+
+ /* check for record variable, only the highest dimension can
+ * be unlimited */
+ if (varp->shape[i] == NC_UNLIMITED && i != 0)
+ DEBUG_RETURN_ERROR(NC_EUNLIMPOS)
+ }
+
+ /*
+ * compute the dsizes, the right to left product of shape
+ */
+ product = 1;
+ if (varp->ndims == 1) {
+ if (varp->shape[0] == NC_UNLIMITED)
+ varp->dsizes[0] = 1;
+ else {
+ varp->dsizes[0] = varp->shape[0];
+ product = varp->shape[0];
+ }
+ }
+ else { /* varp->ndims > 1 */
+ varp->dsizes[varp->ndims-1] = varp->shape[varp->ndims-1];
+ product = varp->shape[varp->ndims-1];
+ for (i=varp->ndims-2; i>=0; i--) {
+ if (varp->shape[i] != NC_UNLIMITED)
+ product *= varp->shape[i];
+ varp->dsizes[i] = product;
+ }
+ }
+
+out :
+ /*
+ * For CDF-1 and CDF-2 formats, the total number of array elements
+ * cannot exceed 2^32, unless this variable is the last fixed-size
+ * variable, there is no record variable, and the file starting
+ * offset of this variable is less than 2GiB.
+ * We will check this in ncmpi_enddef() which calls ncmpii_NC_enddef()
+ * which calls ncmpii_NC_check_vlens()
+ *
+ if (! fIsSet(ncp->flags, NC_64BIT_DATA) && product >= X_UINT_MAX)
+ DEBUG_RETURN_ERROR(NC_EVARSIZE)
+ */
+
+ /*
+ * align variable size to 4 byte boundary, required by all netcdf
+ * file formats
+ */
+ varp->len = product * varp->xsz;
+ if (varp->len % 4 > 0)
+ varp->len += 4 - varp->len % 4; /* round up */
+
+ return NC_NOERR;
+}
+
+/*
+ * Check whether variable size is less than or equal to vlen_max,
+ * without overflowing in arithmetic calculations. If OK, return 1,
+ * else, return 0. For CDF1 format or for CDF2 format on non-LFS
+ * platforms, vlen_max should be 2^31 - 4, but for CDF2 format on
+ * systems with LFS it should be 2^32 - 4.
+ */
+inline int
+ncmpii_NC_check_vlen(NC_var *varp,
+ MPI_Offset vlen_max)
+{
+ int ii;
+ MPI_Offset prod=varp->xsz; /* product of xsz and dimensions so far */
+
+ for (ii = IS_RECVAR(varp) ? 1 : 0; ii < varp->ndims; ii++) {
+ if (varp->shape[ii] > vlen_max / prod) {
+ return 0; /* size in bytes won't fit in a 32-bit int */
+ }
+ prod *= varp->shape[ii];
+ }
+ return 1; /* OK */
+}
+
+/*----< ncmpii_NC_lookupvar() >----------------------------------------------*/
+/*
+ * Given valid ncp and varid, return var
+ * else NULL on error
+ * Formerly
+NC_hlookupvar()
+ */
+int
+ncmpii_NC_lookupvar(NC *ncp,
+ int varid,
+ NC_var **varp)
+{
+ if (varid == NC_GLOBAL) /* Global is error in this context */
+ DEBUG_RETURN_ERROR(NC_EGLOBAL)
+
+ *varp = elem_NC_vararray(&ncp->vars, varid);
+ if (*varp == NULL) /* could not find variable with varid */
+ DEBUG_RETURN_ERROR(NC_ENOTVAR)
+
+ return NC_NOERR;
+}
+
+
+/* Public */
+
+/*----< ncmpi_def_var() >----------------------------------------------------*/
+int
+ncmpi_def_var(int ncid,
+ const char *name,
+ nc_type type,
+ int ndims,
+ const int *dimids,
+ int *varidp)
+{
+ int varid, file_ver, status;
+ NC *ncp;
+ NC_var *varp;
+
+ /* check if ncid is valid */
+ status = ncmpii_NC_check_id(ncid, &ncp);
+ if (status != NC_NOERR) return status;
+
+ /* check if called in define mode */
+ if (!NC_indef(ncp)) DEBUG_RETURN_ERROR(NC_ENOTINDEFINE)
+
+ /* check if the name string is legal for netcdf format */
+ file_ver = 1;
+ if (fIsSet(ncp->flags, NC_64BIT_OFFSET))
+ file_ver = 2;
+ else if (fIsSet(ncp->flags, NC_64BIT_DATA))
+ file_ver = 5;
+ status = ncmpii_NC_check_name(name, file_ver);
+ if (status != NC_NOERR) return status;
+
+ /* check if type is a valid netcdf type */
+ status = ncmpii_cktype(file_ver, type);
+ if (status != NC_NOERR) return status;
+
+ /* TODO: can ndims > 2^31-1 in CDF-5 ? */
+ if ((ndims < 0) || ndims > X_INT_MAX) DEBUG_RETURN_ERROR(NC_EINVAL)
+
+ /* there is an upperbound for the number of variables defined in a file */
+ if (ncp->vars.ndefined >= NC_MAX_VARS) DEBUG_RETURN_ERROR(NC_EMAXVARS)
+
+ /* check whether the variable name has been used */
+ varid = ncmpii_NC_findvar(&ncp->vars, name, &varp);
+ if (varid != -1) DEBUG_RETURN_ERROR(NC_ENAMEINUSE)
+
+ /* create a new variable */
+ varp = ncmpii_new_NC_var(name, type, ndims, dimids);
+ if (varp == NULL) DEBUG_RETURN_ERROR(NC_ENOMEM)
+
+ /* set up array dimensional structures */
+ status = ncmpii_NC_var_shape64(ncp, varp, &ncp->dims);
+ if (status != NC_NOERR) {
+ ncmpii_free_NC_var(varp);
+ return status;
+ }
+
+ /* Add a new handle to the end of an array of handles */
+ status = incr_NC_vararray(&ncp->vars, varp);
+ if (status != NC_NOERR) {
+ ncmpii_free_NC_var(varp);
+ return status;
+ }
+
+ if (varidp != NULL)
+ *varidp = (int)ncp->vars.ndefined - 1; /* varid */
+ /* ncp->vars.ndefined has been increased in incr_NC_vararray() */
+
+ /* default is NOFILL */
+ varp->no_fill = 1;
+
+ /* change to FILL only if the entire dataset fill mode is FILL */
+ if (NC_dofill(ncp)) varp->no_fill = 0;
+
+ return NC_NOERR;
+}
+
+
+/*----< ncmpi_inq_varid() >--------------------------------------------------*/
+int
+ncmpi_inq_varid(int ncid,
+ const char *name,
+ int *varid_ptr)
+{
+ int status;
+ NC *ncp;
+ NC_var *varp;
+ int varid;
+
+ status = ncmpii_NC_check_id(ncid, &ncp);
+ if (status != NC_NOERR) return status;
+
+ varid = ncmpii_NC_findvar(&ncp->vars, name, &varp);
+ if (varid == -1) DEBUG_RETURN_ERROR(NC_ENOTVAR)
+
+ *varid_ptr = varid;
+ return NC_NOERR;
+}
+
+/*----< ncmpi_inq_var() >----------------------------------------------------*/
+int
+ncmpi_inq_var(int ncid,
+ int varid,
+ char *name,
+ nc_type *typep,
+ int *ndimsp,
+ int *dimids,
+ int *nattsp)
+{
+ int status;
+ NC *ncp;
+ NC_var *varp;
+
+ status = ncmpii_NC_check_id(ncid, &ncp);
+ if (status != NC_NOERR) return status;
+
+ /* using NC_GLOBAL in varid is illegal for this API. See
+ * http://www.unidata.ucar.edu/mailing_lists/archives/netcdfgroup/2015/msg00196.html
+ */
+ if (varid == NC_GLOBAL) DEBUG_RETURN_ERROR(NC_EGLOBAL)
+
+ varp = elem_NC_vararray(&ncp->vars, varid);
+ if (varp == NULL) DEBUG_RETURN_ERROR(NC_ENOTVAR)
+
+ if (name != NULL)
+ /* in PnetCDF, name->cp is always NULL character terminated */
+ strcpy(name, varp->name->cp);
+
+ if (typep != 0)
+ *typep = varp->type;
+
+ if (ndimsp != 0) {
+#ifdef ENABLE_SUBFILING
+ /* varp->num_subfiles is already set during open or enddef */
+ if (varp->num_subfiles > 1)
+ *ndimsp = varp->ndims_org;
+ else
+#endif
+ *ndimsp = varp->ndims;
+ }
+ if (dimids != 0) {
+#ifdef ENABLE_SUBFILING
+ /* varp->dimids_org is already set during open or enddef */
+ if (varp->num_subfiles > 1)
+ memcpy(dimids, varp->dimids_org, (size_t)varp->ndims_org * SIZEOF_INT);
+ else
+#endif
+ memcpy(dimids, varp->dimids, (size_t)varp->ndims * SIZEOF_INT);
+ }
+ if (nattsp != 0)
+ *nattsp = (int) varp->attrs.ndefined;
+
+ return NC_NOERR;
+}
+
+
+/*----< ncmpi_inq_varname() >------------------------------------------------*/
+int
+ncmpi_inq_varname(int ncid,
+ int varid,
+ char *name)
+{
+ int status;
+ NC *ncp;
+ NC_var *varp;
+
+ status = ncmpii_NC_check_id(ncid, &ncp);
+ if (status != NC_NOERR) return status;
+
+ /* using NC_GLOBAL in varid is illegal for this API. See
+ * http://www.unidata.ucar.edu/mailing_lists/archives/netcdfgroup/2015/msg00196.html
+ */
+ if (varid == NC_GLOBAL) DEBUG_RETURN_ERROR(NC_EGLOBAL)
+
+ varp = elem_NC_vararray(&ncp->vars, varid);
+ if (varp == NULL) DEBUG_RETURN_ERROR(NC_ENOTVAR)
+
+ if (name != NULL)
+ /* in PnetCDF, name->cp is always NULL character terminated */
+ strcpy(name, varp->name->cp);
+
+ return NC_NOERR;
+}
+
+/*----< ncmpi_inq_vartype() >------------------------------------------------*/
+int
+ncmpi_inq_vartype(int ncid,
+ int varid,
+ nc_type *typep)
+{
+ int status;
+ NC *ncp;
+ NC_var *varp;
+
+ status = ncmpii_NC_check_id(ncid, &ncp);
+ if (status != NC_NOERR) return status;
+
+ /* using NC_GLOBAL in varid is illegal for this API. See
+ * http://www.unidata.ucar.edu/mailing_lists/archives/netcdfgroup/2015/msg00196.html
+ */
+ if (varid == NC_GLOBAL) DEBUG_RETURN_ERROR(NC_EGLOBAL)
+
+ varp = elem_NC_vararray(&ncp->vars, varid);
+ if (varp == NULL) DEBUG_RETURN_ERROR(NC_ENOTVAR)
+
+ if (typep != NULL) *typep = varp->type;
+
+ return NC_NOERR;
+}
+
+/*----< ncmpi_inq_varndims() >-----------------------------------------------*/
+int
+ncmpi_inq_varndims(int ncid, int varid, int *ndimsp)
+{
+ int status;
+ NC *ncp;
+ NC_var *varp;
+
+ status = ncmpii_NC_check_id(ncid, &ncp);
+ if (status != NC_NOERR) return status;
+
+ /* using NC_GLOBAL in varid is illegal for this API. See
+ * http://www.unidata.ucar.edu/mailing_lists/archives/netcdfgroup/2015/msg00196.html
+ */
+ if (varid == NC_GLOBAL) DEBUG_RETURN_ERROR(NC_EGLOBAL)
+
+ varp = elem_NC_vararray(&ncp->vars, varid);
+ if (varp == NULL) DEBUG_RETURN_ERROR(NC_ENOTVAR)
+
+ if (ndimsp != 0) {
+#ifdef ENABLE_SUBFILNIG
+ if (varp->num_subfiles > 1)
+ *ndimsp = varp->ndims_org;
+ else
+#endif
+ *ndimsp = varp->ndims;
+ }
+
+ return NC_NOERR;
+}
+
+/*----< ncmpi_inq_vardimid() >-----------------------------------------------*/
+int
+ncmpi_inq_vardimid(int ncid, int varid, int *dimids)
+{
+ int status;
+ NC *ncp;
+ NC_var *varp;
+
+ status = ncmpii_NC_check_id(ncid, &ncp);
+ if (status != NC_NOERR) return status;
+
+ /* using NC_GLOBAL in varid is illegal for this API. See
+ * http://www.unidata.ucar.edu/mailing_lists/archives/netcdfgroup/2015/msg00196.html
+ */
+ if (varid == NC_GLOBAL) DEBUG_RETURN_ERROR(NC_EGLOBAL)
+
+ varp = elem_NC_vararray(&ncp->vars, varid);
+ if (varp == NULL) DEBUG_RETURN_ERROR(NC_ENOTVAR)
+
+ if (dimids != 0) {
+#ifdef ENABLE_SUBFILING
+ if (varp->num_subfiles > 1)
+ memcpy(dimids, varp->dimids_org, (size_t)varp->ndims_org * SIZEOF_INT);
+ else
+#endif
+ memcpy(dimids, varp->dimids, (size_t)varp->ndims * SIZEOF_INT);
+ }
+
+ return NC_NOERR;
+}
+
+
+/*----< ncmpi_inq_varnatts() >------------------------------------------------*/
+int
+ncmpi_inq_varnatts(int ncid,
+ int varid,
+ int *nattsp)
+{
+ int status;
+ NC *ncp;
+ NC_var *varp;
+
+ if (varid == NC_GLOBAL)
+ return ncmpi_inq_natts(ncid, nattsp);
+
+ status = ncmpii_NC_check_id(ncid, &ncp);
+ if (status != NC_NOERR) return status;
+
+ varp = elem_NC_vararray(&ncp->vars, varid);
+ if (varp == NULL) DEBUG_RETURN_ERROR(NC_ENOTVAR)
+
+ if (nattsp != NULL)
+ *nattsp = (int) varp->attrs.ndefined;
+
+ return NC_NOERR;
+}
+
+/*----< ncmpi_rename_var() >--------------------------------------------------*/
+/* This API is collective if called in data mode */
+int
+ncmpi_rename_var(int ncid,
+ int varid,
+ const char *newname)
+{
+ int file_ver, status=NC_NOERR, other, err, mpireturn;
+ NC *ncp;
+ NC_var *varp;
+
+ status = ncmpii_NC_check_id(ncid, &ncp);
+ if (status != NC_NOERR) return status;
+
+ if (NC_readonly(ncp)) DEBUG_RETURN_ERROR(NC_EPERM)
+
+ /* check if variable ID is valid*/
+ status = ncmpii_NC_lookupvar(ncp, varid, &varp);
+ if (status != NC_NOERR) return status;
+
+ file_ver = 1;
+ if (fIsSet(ncp->flags, NC_64BIT_OFFSET))
+ file_ver = 2;
+ else if (fIsSet(ncp->flags, NC_64BIT_DATA))
+ file_ver = 5;
+
+ status = ncmpii_NC_check_name(newname, file_ver);
+ if (status != NC_NOERR) return status;
+
+ /* check for name in use */
+ other = ncmpii_NC_findvar(&ncp->vars, newname, &varp);
+ if (other != -1)
+ DEBUG_RETURN_ERROR(NC_ENAMEINUSE)
+
+ /* if called in define mode, just update to the NC object */
+ if (NC_indef(ncp)) {
+ NC_string *newStr = ncmpii_new_NC_string(strlen(newname), newname);
+ if (newStr == NULL) DEBUG_RETURN_ERROR(NC_ENOMEM)
+
+ ncmpii_free_NC_string(varp->name);
+ varp->name = newStr;
+ return NC_NOERR;
+ }
+ /* else, not in define mode.
+ * if called in data mode (collective or independent), this function must
+ * be called collectively, i.e. all processes must participate.
+ */
+
+ if (ncp->safe_mode) {
+ int nchars = (int)strlen(newname);
+ TRACE_COMM(MPI_Bcast)(&nchars, 1, MPI_INT, 0, ncp->nciop->comm);
+ if (mpireturn != MPI_SUCCESS)
+ return ncmpii_handle_error(mpireturn, "MPI_Bcast");
+
+ if (nchars != (int) strlen(newname)) {
+ /* newname's length is inconsistent with root's */
+ printf("Warning: variable name(%s) used in %s() is inconsistent\n",
+ newname, __func__);
+ if (status == NC_NOERR) DEBUG_ASSIGN_ERROR(status, NC_EMULTIDEFINE_VAR_NAME)
+ }
+ }
+
+ /* ncmpii_set_NC_string() will check for strlen(newname) > nchars error */
+ err = ncmpii_set_NC_string(varp->name, newname);
+ if (status == NC_NOERR) status = err;
+
+ /* PnetCDF expects all processes use the same name, However, when names
+ * are not the same, only root's value is significant. Broadcast the
+ * new name at root to overwrite new names at other processes.
+ * (This API is collective if called in data mode)
+ */
+ TRACE_COMM(MPI_Bcast)(varp->name->cp, (int)varp->name->nchars, MPI_CHAR, 0,
+ ncp->nciop->comm);
+
+ /* Let root write the entire header to the file. Note that we cannot just
+ * update the variable name in its space occupied in the file header,
+ * because if the file space occupied by the name shrinks, all the metadata
+ * following it must be moved ahead.
+ */
+ err = ncmpii_write_header(ncp);
+ if (status == NC_NOERR) status = err;
+
+ return status;
+}
+
+/* some utility functions for debugging purpose */
+
+/*----< ncmpi_inq_varoffset() >-----------------------------------------------*/
+int
+ncmpi_inq_varoffset(int ncid,
+ int varid,
+ MPI_Offset *offset)
+{
+ int status;
+ NC *ncp;
+ NC_var *varp;
+
+ status = ncmpii_NC_check_id(ncid, &ncp);
+ if (status != NC_NOERR) return status;
+
+ /* using NC_GLOBAL in varid is illegal for this API. See
+ * http://www.unidata.ucar.edu/mailing_lists/archives/netcdfgroup/2015/msg00196.html
+ */
+ if (varid == NC_GLOBAL) DEBUG_RETURN_ERROR(NC_EGLOBAL)
+
+ varp = elem_NC_vararray(&ncp->vars, varid);
+ if (varp == NULL) DEBUG_RETURN_ERROR(NC_ENOTVAR)
+
+ if (offset != NULL)
+ *offset = varp->begin;
+
+ return NC_NOERR;
+}
+
+#ifdef __DEBUG
+
+/*----< ncmpi_print_all_var_offsets() >---------------------------------------*/
+int
+ncmpi_print_all_var_offsets(int ncid) {
+ int i;
+ NC_var **vpp;
+ NC *ncp;
+
+ ncmpii_NC_check_id(ncid, &ncp);
+
+ if (ncp->begin_var%1048576)
+ printf("%s header size (ncp->begin_var)=%lld MB + %lld\n",
+ ncp->nciop->path, ncp->begin_var/1048575, ncp->begin_var%1048576);
+ else
+ printf("%s header size (ncp->begin_var)=%lld MB\n",
+ ncp->nciop->path, ncp->begin_var/1048575);
+
+ vpp = ncp->vars.value;
+ for (i=0; i<ncp->vars.ndefined; i++, vpp++) {
+ char str[1024];
+ MPI_Offset off = (*vpp)->begin;
+ MPI_Offset rem = off % 1048576;;
+
+ if (IS_RECVAR(*vpp))
+ sprintf(str," Record variable \"%20s\": ",(*vpp)->name->cp);
+ else
+ sprintf(str,"non-record variable \"%20s\": ",(*vpp)->name->cp);
+
+ if (rem)
+ printf("%s offset=%12lld MB + %7lld len=%lld\n", str, off/1048576, rem,(*vpp)->len);
+ else
+ printf("%s offset=%12lld MB len=%lld\n", str, off/1048576,(*vpp)->len);
+ }
+ return NC_NOERR;
+}
+
+#endif
diff --git a/src/lib/vard.c b/src/lib/vard.c
new file mode 100644
index 0000000..16b4076
--- /dev/null
+++ b/src/lib/vard.c
@@ -0,0 +1,407 @@
+/*
+ * Copyright (C) 2014, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ */
+/* $Id: vard.c 2216 2015-12-08 05:47:19Z wkliao $ */
+
+#if HAVE_CONFIG_H
+# include "ncconfig.h"
+#endif
+
+#include <stdio.h>
+#include <unistd.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#include <string.h> /* memcpy() */
+#include <assert.h>
+
+#include <mpi.h>
+
+#include "nc.h"
+#include "ncx.h"
+#include "ncmpidtype.h"
+#include "macro.h"
+#ifdef ENABLE_SUBFILING
+#include "subfile.h"
+#endif
+
+/* for write case, buf needs to swapped back if swapped previously */
+#define FINAL_CLEAN_UP { \
+ if (is_buf_swapped) /* byte-swap back to buf's original contents */ \
+ ncmpii_in_swapn(buf, bnelems, ncmpix_len_nctype(varp->type)); \
+ \
+ if (cbuf != NULL && cbuf != buf) NCI_Free(cbuf); \
+}
+
+/*----< ncmpii_getput_vard() >------------------------------------------------*/
+static int
+ncmpii_getput_vard(NC *ncp,
+ NC_var *varp,
+ MPI_Datatype filetype, /* data type of the variable */
+ void *buf,
+ MPI_Offset bufcount,
+ MPI_Datatype buftype, /* data type of the bufer */
+ int rw_flag,
+ int io_method)
+{
+ void *cbuf=NULL;
+ int i, isderived, el_size, mpireturn, status=NC_NOERR, err=NC_NOERR;
+ int buftype_is_contig, filetype_is_contig=1, need_swap=0, is_buf_swapped=0;
+ int filetype_size=0, buftype_size;
+ MPI_Offset btnelems, bnelems=0, offset=0, orig_bufcount=bufcount;
+ MPI_Status mpistatus;
+ MPI_Datatype ptype, orig_buftype=buftype;
+ MPI_File fh=MPI_FILE_NULL;
+
+ if (filetype == MPI_DATATYPE_NULL) { /* this process does zero-length I/O */
+ if (io_method == INDEP_IO) return NC_NOERR;
+ bufcount = 0;
+ goto err_check;
+ }
+
+ if (bufcount == 0 && buftype != MPI_DATATYPE_NULL) {
+ /* if this process has nothing to read/write */
+ if (io_method == INDEP_IO) return NC_NOERR;
+ goto err_check;
+ }
+
+#ifdef ENABLE_SUBFILING
+ /* call a separate routine if variable is stored in subfiles */
+ if (varp->num_subfiles > 1) {
+ printf("This feature for subfiling is yet to implement\n");
+ DEBUG_RETURN_ERROR(NC_ENOTSUPPORT)
+ }
+#endif
+
+ /* PROBLEM: argument filetype_size is a 4-byte integer, cannot be used
+ * for largefiletypes */
+ mpireturn = MPI_Type_size(filetype, &filetype_size);
+ if (mpireturn != MPI_SUCCESS) {
+ err = ncmpii_handle_error(mpireturn, "MPI_Type_size");
+ goto err_check;
+ }
+
+ if (filetype_size == 0) { /* zero-length request */
+ if (io_method == INDEP_IO) return NC_NOERR;
+ bufcount = 0;
+ goto err_check;
+ }
+
+ MPI_Aint true_lb, true_extent;
+ MPI_Type_get_true_extent(filetype, &true_lb, &true_extent);
+ MPI_Aint lb, extent;
+ MPI_Type_get_extent(filetype, &lb, &extent);
+
+ if (!IS_RECVAR(varp)) {
+ /* for fixed-size variable, extent should not be larger than the
+ * variabe size */
+ MPI_Offset var_size = varp->xsz;
+ for (i=0; i<varp->ndims; i++)
+ var_size *= varp->shape[i];
+
+ if (extent > var_size) {
+ DEBUG_ASSIGN_ERROR(err, NC_ETYPESIZE)
+ goto err_check;
+ }
+ }
+
+ cbuf = (void*) buf;
+
+ /* find the element type of filetype */
+ err = ncmpii_dtype_decode(filetype, &ptype, &el_size, &btnelems,
+ &isderived, &filetype_is_contig);
+ if (err != NC_NOERR) goto err_check;
+
+ /* element type of filetype must be the same as variable's type */
+ if (ptype != ncmpii_nc2mpitype(varp->type)) {
+ DEBUG_ASSIGN_ERROR(err, NC_ETYPE_MISMATCH)
+ goto err_check;
+ }
+
+ if (bufcount != (int)bufcount) {
+ DEBUG_ASSIGN_ERROR(err, NC_EINTOVERFLOW)
+ goto err_check;
+ }
+
+ if (buftype == MPI_DATATYPE_NULL) {
+ /* In this case, bufcount is ignored and will be set to the size of
+ * filetype. Note buf's data type must match the data type of variable
+ * defined in the file - no data conversion will be done.
+ */
+ /* set buftype to the variable's data type */
+ buftype = ncmpii_nc2mpitype(varp->type);
+ MPI_Type_size(buftype, &buftype_size);
+ bufcount = filetype_size / buftype_size;
+ buftype_is_contig = 1;
+ bnelems = bufcount;
+ }
+ else {
+ MPI_Offset outsize;
+
+ /* find whether buftype is contiguous */
+ err = ncmpii_dtype_decode(buftype, &ptype, &el_size, &btnelems,
+ &isderived, &buftype_is_contig);
+ if (err != NC_NOERR) goto err_check;
+
+ err = NCMPII_ECHAR(varp->type, ptype);
+ if (err != NC_NOERR) goto err_check;
+
+ if (btnelems != (int)btnelems) {
+ DEBUG_ASSIGN_ERROR(err, NC_EINTOVERFLOW)
+ goto err_check;
+ }
+
+ bnelems = bufcount * btnelems;
+ buftype_size = el_size * (int)btnelems;
+ outsize = bufcount * buftype_size;
+
+ if (outsize != filetype_size) {
+ DEBUG_ASSIGN_ERROR(err, NC_ETYPESIZE_MISMATCH)
+ goto err_check;
+ }
+
+ /* if buf is not contiguous, we need to pack it to one, cbuf */
+ if (!buftype_is_contig && bnelems > 0) {
+ cbuf = NCI_Malloc((size_t)outsize);
+
+ if (rw_flag == WRITE_REQ) {
+ /* pack buf into cbuf, a contiguous buffer */
+ int position = 0;
+ MPI_Pack(buf, (int)bufcount, buftype, cbuf, (int)outsize, &position,
+ MPI_COMM_SELF);
+ }
+ buftype = ptype;
+ bufcount *= bnelems;
+ }
+ }
+
+ /* Check if we need byte swap cbuf in-place or (into cbuf) */
+ need_swap = ncmpii_need_swap(varp->type, ptype);
+ if (need_swap) {
+ if (rw_flag == WRITE_REQ) {
+#ifdef DISABLE_IN_PLACE_SWAP
+ if (cbuf == buf) {
+#else
+ if (cbuf == buf && filetype_size <= NC_BYTE_SWAP_BUFFER_SIZE) {
+#endif
+ /* allocate cbuf and copy buf to cbuf, cbuf is to be freed */
+ cbuf = NCI_Malloc((size_t)filetype_size);
+ memcpy(cbuf, buf, filetype_size);
+ }
+ /* perform array in-place byte swap on cbuf */
+ ncmpii_in_swapn(cbuf, bnelems, ncmpix_len_nctype(varp->type));
+ is_buf_swapped = (cbuf == buf) ? 1 : 0;
+ /* is_buf_swapped indicates if the contents of the original user
+ * buffer, buf, have been changed, i.e. byte swapped. */
+ }
+ }
+ /* no type conversion */
+
+ /* set fileview's displacement to the variable's starting file offset */
+ offset = varp->begin;
+
+err_check:
+ /* check API error from any proc before going into a collective call.
+ * optimization: to avoid MPI_Allreduce to check parameters at
+ * every call, we assume caller does the right thing most of the
+ * time. If caller passed in bad parameters, we'll still conduct a
+ * zero-byte operation (everyone has to participate in the
+ * collective I/O call) but return error */
+ if (err != NC_NOERR || bufcount == 0 || filetype_size == 0) {
+ if (io_method == INDEP_IO) {
+ FINAL_CLEAN_UP /* swap back put buffer and free temp buffers */
+ return err;
+ }
+ /* else for COLL_IO, must participate successive collective calls */
+ }
+ status = err;
+
+ if (io_method == COLL_IO)
+ fh = ncp->nciop->collective_fh;
+ else
+ fh = ncp->nciop->independent_fh;
+
+ /* set the file view */
+ err = ncmpii_file_set_view(ncp, fh, &offset, filetype);
+ if (err != NC_NOERR) {
+ bufcount = 0; /* skip this request */
+ if (status == NC_NOERR) status = err;
+ }
+
+ if (rw_flag == WRITE_REQ) {
+ if (io_method == COLL_IO) {
+ TRACE_IO(MPI_File_write_at_all)(fh, offset, cbuf, (int)bufcount, buftype, &mpistatus);
+ if (mpireturn != MPI_SUCCESS)
+ return ncmpii_handle_error(mpireturn, "MPI_File_write_at_all");
+ }
+ else { /* io_method == INDEP_IO */
+ TRACE_IO(MPI_File_write_at)(fh, offset, cbuf, (int)bufcount, buftype, &mpistatus);
+ if (mpireturn != MPI_SUCCESS)
+ return ncmpii_handle_error(mpireturn, "MPI_File_write_at");
+ }
+ int put_size;
+ MPI_Get_count(&mpistatus, MPI_BYTE, &put_size);
+ ncp->nciop->put_size += put_size;
+ }
+ else { /* rw_flag == READ_REQ */
+ if (io_method == COLL_IO) {
+ TRACE_IO(MPI_File_read_at_all)(fh, offset, cbuf, (int)bufcount, buftype, &mpistatus);
+ if (mpireturn != MPI_SUCCESS)
+ return ncmpii_handle_error(mpireturn, "MPI_File_read_at_all");
+ }
+ else { /* io_method == INDEP_IO */
+ TRACE_IO(MPI_File_read_at)(fh, offset, cbuf, (int)bufcount, buftype, &mpistatus);
+ if (mpireturn != MPI_SUCCESS)
+ return ncmpii_handle_error(mpireturn, "MPI_File_read_at");
+ }
+ int get_size;
+ MPI_Get_count(&mpistatus, MPI_BYTE, &get_size);
+ ncp->nciop->get_size += get_size;
+ }
+
+ /* No longer need to reset the file view, as the root's fileview includes
+ * the whole file header.
+ TRACE_IO(MPI_File_set_view)(fh, 0, MPI_BYTE, MPI_BYTE, "native", MPI_INFO_NULL);
+ */
+
+ if (rw_flag == READ_REQ) {
+ if (need_swap)
+ /* perform array in-place byte swap on cbuf */
+ ncmpii_in_swapn(cbuf, bnelems, ncmpix_len_nctype(varp->type));
+
+ if (!buftype_is_contig && bnelems > 0) {
+ /* unpack cbuf, a contiguous buffer, to buf using buftype */
+ int position = 0;
+ MPI_Offset insize = bnelems * el_size;
+ if (insize != (int)insize) {
+ if (status == NC_NOERR) DEBUG_ASSIGN_ERROR(status, NC_EINTOVERFLOW)
+ }
+ else
+ MPI_Unpack(cbuf, (int)insize, &position, buf, (int)orig_bufcount,
+ orig_buftype, MPI_COMM_SELF);
+ }
+ }
+ else { /* WRITE_REQ */
+ if (IS_RECVAR(varp)) {
+ /* update header's number of records in memory */
+ MPI_Offset new_numrecs;
+
+ /* since filetype's LB is required to be == varp->begin for vard
+ * API, we can simply use extent to calculate new_numrecs */
+ new_numrecs = extent / ncp->recsize;
+ if (extent % ncp->recsize) new_numrecs++;
+
+ if (io_method == INDEP_IO) {
+ /* For independent put, we delay the sync for numrecs until
+ * the next collective call, such as end_indep(), sync(),
+ * enddef(), or close(). This is because if we update numrecs
+ * to file now, race condition can happen. Note numrecs in
+ * memory may be inconsistent and obsolete till then.
+ */
+ if (ncp->numrecs < new_numrecs) {
+ ncp->numrecs = new_numrecs;
+ set_NC_ndirty(ncp);
+ }
+ }
+ else { /* COLL_IO: sync numrecs in memory and file */
+ err = ncmpii_sync_numrecs(ncp, new_numrecs);
+ if (err != NC_NOERR && status == NC_NOERR) status = err;
+ }
+ }
+
+ if (NC_doFsync(ncp)) { /* NC_SHARE is set */
+ TRACE_IO(MPI_File_sync)(fh);
+ if (io_method == COLL_IO)
+ TRACE_COMM(MPI_Barrier)(ncp->nciop->comm);
+ }
+ }
+
+ FINAL_CLEAN_UP /* swap back the put buffer and free temp buffers */
+
+ return status;
+}
+
+/*----< ncmpi_get_vard() >---------------------------------------------------*/
+int
+ncmpi_get_vard(int ncid,
+ int varid,
+ MPI_Datatype filetype, /* access layout to the variable in file */
+ void *buf,
+ MPI_Offset bufcount,
+ MPI_Datatype buftype) /* data type of the buffer */
+{
+ int status;
+ NC *ncp;
+ NC_var *varp=NULL;
+
+ status = ncmpii_sanity_check(ncid, varid, NULL, NULL, bufcount, API_VARD,
+ 1, 1, READ_REQ, INDEP_IO, &ncp, &varp);
+ if (status != NC_NOERR) return status;
+
+ return ncmpii_getput_vard(ncp, varp, filetype, buf, bufcount, buftype,
+ READ_REQ, INDEP_IO);
+}
+
+/*----< ncmpi_get_vard_all() >-----------------------------------------------*/
+int
+ncmpi_get_vard_all(int ncid,
+ int varid,
+ MPI_Datatype filetype, /* access layout to the variable in file */
+ void *buf,
+ MPI_Offset bufcount,
+ MPI_Datatype buftype) /* data type of the buffer */
+{
+ int status;
+ NC *ncp;
+ NC_var *varp=NULL;
+
+ status = ncmpii_sanity_check(ncid, varid, NULL, NULL, bufcount, API_VARD,
+ 1, 1, READ_REQ, COLL_IO, &ncp, &varp);
+ if (status != NC_NOERR) return status;
+
+ return ncmpii_getput_vard(ncp, varp, filetype, buf, bufcount, buftype,
+ READ_REQ, COLL_IO);
+}
+
+/*----< ncmpi_put_vard() >---------------------------------------------------*/
+int
+ncmpi_put_vard(int ncid,
+ int varid,
+ MPI_Datatype filetype, /* access layout to the variable in file */
+ const void *buf,
+ MPI_Offset bufcount,
+ MPI_Datatype buftype) /* data type of the buffer */
+{
+ int status;
+ NC *ncp;
+ NC_var *varp=NULL;
+
+ status = ncmpii_sanity_check(ncid, varid, NULL, NULL, bufcount, API_VARD,
+ 1, 1, WRITE_REQ, INDEP_IO, &ncp, &varp);
+ if (status != NC_NOERR) return status;
+
+ return ncmpii_getput_vard(ncp, varp, filetype, (void*)buf, bufcount,
+ buftype, WRITE_REQ, INDEP_IO);
+}
+
+/*----< ncmpi_put_vard_all() >-----------------------------------------------*/
+int
+ncmpi_put_vard_all(int ncid,
+ int varid,
+ MPI_Datatype filetype, /* access layout to the variable in file */
+ const void *buf,
+ MPI_Offset bufcount,
+ MPI_Datatype buftype) /* data type of the buffer */
+{
+ int status;
+ NC *ncp;
+ NC_var *varp=NULL;
+
+ status = ncmpii_sanity_check(ncid, varid, NULL, NULL, bufcount, API_VARD,
+ 1, 1, WRITE_REQ, COLL_IO, &ncp, &varp);
+ if (status != NC_NOERR) return status;
+
+ return ncmpii_getput_vard(ncp, varp, filetype, (void*)buf, bufcount,
+ buftype, WRITE_REQ, COLL_IO);
+}
diff --git a/src/lib/varn.m4 b/src/lib/varn.m4
new file mode 100644
index 0000000..1fd0993
--- /dev/null
+++ b/src/lib/varn.m4
@@ -0,0 +1,368 @@
+dnl Process this m4 file to produce 'C' language file.
+dnl
+dnl If you see this line, you can ignore the next one.
+/* Do not edit this file. It is produced from the corresponding .m4 source */
+dnl
+/*
+ * Copyright (C) 2014, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ */
+/* $Id: varn.m4 2290 2016-01-02 18:37:46Z wkliao $ */
+
+#if HAVE_CONFIG_H
+# include "ncconfig.h"
+#endif
+
+#include <stdio.h>
+#include <unistd.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#include <assert.h>
+
+#include <mpi.h>
+
+#include "nc.h"
+#include "ncx.h"
+#include "ncmpidtype.h"
+#include "macro.h"
+
+/* ncmpi_get/put_varn_<type>_<mode> API:
+ * type: data type of I/O buffer, buf
+ * mode: independent (<nond>) or collective (_all)
+ *
+ * arguments:
+ * num: number of start and count pairs
+ * starts: an 2D array of size [num][ndims]. Each starts[i][*] indicates
+ * the starting array indices for a subarray request. ndims is
+ * the number of dimensions of the defined netCDF variable.
+ * counts: an 2D array of size [num][ndims]. Each counts[i][*] indicates
+ * the number of array elements to be accessed. This argument
+ * can be NULL, equivalent to counts with all 1s.
+ * bufcount and buftype: these 2 arguments are only available for flexible
+ * APIs, indicating the I/O buffer memory layout. When buftype is
+ * MPI_DATATYPE_NULL, bufcount is ignored and the data type of buf
+ * is considered matched the variable data type defined in the file.
+ */
+
+static int
+ncmpii_getput_varn(NC *ncp,
+ NC_var *varp,
+ int num,
+ MPI_Offset* const starts[], /* [num][varp->ndims] */
+ MPI_Offset* const counts[], /* [num][varp->ndims] */
+ void *buf,
+ MPI_Offset bufcount,
+ MPI_Datatype buftype, /* data type of the buffer */
+ int rw_flag,
+ int io_method);
+
+define(`CollIndep', `ifelse(`$1',`_all', `COLL_IO', `INDEP_IO')')dnl
+define(`BufConst', `ifelse(`$1', `put', `const')')dnl
+define(`ReadWrite', `ifelse(`$1', `get', `READ_REQ', `WRITE_REQ')')dnl
+
+dnl
+dnl VARN_FLEXIBLE(ncid, varid, num starts, counts, buf, bufcount, buftype)
+dnl
+define(`VARN_FLEXIBLE',dnl
+`dnl
+/*----< ncmpi_$1_varn$2() >---------------------------------------------------*/
+int
+ncmpi_$1_varn$2(int ncid,
+ int varid,
+ int num,
+ MPI_Offset* const starts[],
+ MPI_Offset* const counts[],
+ BufConst($1) void *buf,
+ MPI_Offset bufcount,
+ MPI_Datatype buftype)
+{
+ int status;
+ NC *ncp;
+ NC_var *varp=NULL;
+
+ status = ncmpii_sanity_check(ncid, varid, NULL, NULL, bufcount, API_VARN,
+ 1, 1, ReadWrite($1), CollIndep($2), &ncp, &varp);
+ if (status != NC_NOERR) return status;
+
+ return ncmpii_getput_varn(ncp, varp, num, starts, counts, (void*)buf,
+ bufcount, buftype, ReadWrite($1), CollIndep($2));
+}
+')dnl
+
+dnl PnetCDF flexible APIs
+VARN_FLEXIBLE(put)
+VARN_FLEXIBLE(put, _all)
+VARN_FLEXIBLE(get)
+VARN_FLEXIBLE(get, _all)
+
+dnl
+dnl VARN(ncid, varid, starts, counts, buf)
+dnl
+define(`VARN',dnl
+`dnl
+/*----< ncmpi_$1_varn_$3$2() >------------------------------------------------*/
+int
+ncmpi_$1_varn_$3$2(int ncid,
+ int varid,
+ int num,
+ MPI_Offset* const starts[],
+ MPI_Offset* const counts[],
+ BufConst($1) $4 *buf)
+{
+ int status;
+ NC *ncp;
+ NC_var *varp=NULL;
+
+ status = ncmpii_sanity_check(ncid, varid, NULL, NULL, 0, API_VARN,
+ 1, 0, ReadWrite($1), CollIndep($2), &ncp, &varp);
+ if (status != NC_NOERR) return status;
+
+ /* set bufcount to -1 indicating non-flexible API */
+ return ncmpii_getput_varn(ncp, varp, num, starts, counts, (void*)buf,
+ -1, $5, ReadWrite($1), CollIndep($2));
+}
+')dnl
+
+VARN(put, , text, char, MPI_CHAR)
+VARN(put, , schar, schar, MPI_SIGNED_CHAR)
+VARN(put, , uchar, uchar, MPI_UNSIGNED_CHAR)
+VARN(put, , short, short, MPI_SHORT)
+VARN(put, , ushort, ushort, MPI_UNSIGNED_SHORT)
+VARN(put, , int, int, MPI_INT)
+VARN(put, , uint, uint, MPI_UNSIGNED)
+VARN(put, , long, long, MPI_LONG)
+VARN(put, , float, float, MPI_FLOAT)
+VARN(put, , double, double, MPI_DOUBLE)
+VARN(put, , longlong, long long, MPI_LONG_LONG_INT)
+VARN(put, , ulonglong, unsigned long long, MPI_UNSIGNED_LONG_LONG)
+
+VARN(put, _all, text, char, MPI_CHAR)
+VARN(put, _all, schar, schar, MPI_SIGNED_CHAR)
+VARN(put, _all, uchar, uchar, MPI_UNSIGNED_CHAR)
+VARN(put, _all, short, short, MPI_SHORT)
+VARN(put, _all, ushort, ushort, MPI_UNSIGNED_SHORT)
+VARN(put, _all, int, int, MPI_INT)
+VARN(put, _all, uint, uint, MPI_UNSIGNED)
+VARN(put, _all, long, long, MPI_LONG)
+VARN(put, _all, float, float, MPI_FLOAT)
+VARN(put, _all, double, double, MPI_DOUBLE)
+VARN(put, _all, longlong, long long, MPI_LONG_LONG_INT)
+VARN(put, _all, ulonglong, unsigned long long, MPI_UNSIGNED_LONG_LONG)
+
+VARN(get, , text, char, MPI_CHAR)
+VARN(get, , schar, schar, MPI_SIGNED_CHAR)
+VARN(get, , uchar, uchar, MPI_UNSIGNED_CHAR)
+VARN(get, , short, short, MPI_SHORT)
+VARN(get, , ushort, ushort, MPI_UNSIGNED_SHORT)
+VARN(get, , int, int, MPI_INT)
+VARN(get, , uint, uint, MPI_UNSIGNED)
+VARN(get, , long, long, MPI_LONG)
+VARN(get, , float, float, MPI_FLOAT)
+VARN(get, , double, double, MPI_DOUBLE)
+VARN(get, , longlong, long long, MPI_LONG_LONG_INT)
+VARN(get, , ulonglong, unsigned long long, MPI_UNSIGNED_LONG_LONG)
+
+VARN(get, _all, text, char, MPI_CHAR)
+VARN(get, _all, schar, schar, MPI_SIGNED_CHAR)
+VARN(get, _all, uchar, uchar, MPI_UNSIGNED_CHAR)
+VARN(get, _all, short, short, MPI_SHORT)
+VARN(get, _all, ushort, ushort, MPI_UNSIGNED_SHORT)
+VARN(get, _all, int, int, MPI_INT)
+VARN(get, _all, uint, uint, MPI_UNSIGNED)
+VARN(get, _all, long, long, MPI_LONG)
+VARN(get, _all, float, float, MPI_FLOAT)
+VARN(get, _all, double, double, MPI_DOUBLE)
+VARN(get, _all, longlong, long long, MPI_LONG_LONG_INT)
+VARN(get, _all, ulonglong, unsigned long long, MPI_UNSIGNED_LONG_LONG)
+
+
+/*----< ncmpii_getput_varn() >------------------------------------------------*/
+static int
+ncmpii_getput_varn(NC *ncp,
+ NC_var *varp,
+ int num,
+ MPI_Offset* const starts[], /* [num][varp->ndims] */
+ MPI_Offset* const counts[], /* [num][varp->ndims] */
+ void *buf,
+ MPI_Offset bufcount,
+ MPI_Datatype buftype, /* data type of the buffer */
+ int rw_flag, /* WRITE_REQ or READ_REQ */
+ int io_method) /* COLL_IO or INDEP_IO */
+{
+ int i, j, el_size, status=NC_NOERR, min_st, err, free_cbuf=0;
+ int req_id=NC_REQ_NULL, st, isSameGroup, position;
+ void *cbuf=NULL;
+ char *bufp;
+ MPI_Offset packsize=0, **_counts=NULL;
+ MPI_Datatype ptype;
+
+ /* check for zero-size request */
+ if (num == 0 || bufcount == 0) goto err_check;
+
+ /* it is illegal for starts to be NULL */
+ if (starts == NULL) {
+ DEBUG_ASSIGN_ERROR(status, NC_ENULLSTART)
+ goto err_check;
+ }
+
+ if (buftype == MPI_DATATYPE_NULL) {
+ /* In this case, bufcount is ignored and will be recalculated to match
+ * counts[]. Note buf's data type must match the data type of
+ * variable defined in the file - no data conversion will be done.
+ */
+ if (counts == NULL)
+ bufcount = 1;
+ else {
+ bufcount = 0;
+ for (j=0; j<num; j++) {
+ MPI_Offset bufcount_j = 1;
+ for (i=0; i<varp->ndims; i++) {
+ if (counts[j][i] < 0) { /* no negative counts[][] */
+ DEBUG_ASSIGN_ERROR(err, NC_ENEGATIVECNT)
+ goto err_check;
+ }
+ bufcount_j *= counts[j][i];
+ }
+ bufcount += bufcount_j;
+ }
+ }
+ /* assign buftype match with the variable's data type */
+ buftype = ncmpii_nc2mpitype(varp->type);
+ }
+
+ cbuf = buf;
+ if (bufcount > 0) { /* flexible API is used */
+ /* pack buf into cbuf, a contiguous buffer */
+ int isderived, iscontig_of_ptypes;
+ MPI_Offset bnelems;
+
+ /* ptype (primitive MPI data type) from buftype
+ * el_size is the element size of ptype
+ * bnelems is the total number of ptype elements in buftype
+ */
+ status = ncmpii_dtype_decode(buftype, &ptype, &el_size, &bnelems,
+ &isderived, &iscontig_of_ptypes);
+
+ if (status != NC_NOERR) goto err_check;
+
+ if (bufcount != (int)bufcount) {
+ DEBUG_ASSIGN_ERROR(status, NC_EINTOVERFLOW)
+ goto err_check;
+ }
+
+ /* check if buftype is contiguous, if not, pack to one, cbuf */
+ if (! iscontig_of_ptypes && bnelems > 0) {
+ position = 0;
+ packsize = bnelems*el_size;
+ if (packsize != (int)packsize) {
+ DEBUG_ASSIGN_ERROR(status, NC_EINTOVERFLOW)
+ goto err_check;
+ }
+ cbuf = NCI_Malloc((size_t)packsize);
+ free_cbuf = 1;
+ if (rw_flag == WRITE_REQ)
+ MPI_Pack(buf, (int)bufcount, buftype, cbuf, (int)packsize,
+ &position, MPI_COMM_SELF);
+ }
+ }
+ else {
+ /* this subroutine is called from a high-level API */
+ status = NCMPII_ECHAR(varp->type, buftype);
+ if (status != NC_NOERR) goto err_check;
+
+ ptype = buftype;
+ el_size = ncmpix_len_nctype(varp->type);
+ }
+
+ /* We allow counts == NULL and treat this the same as all 1s */
+ if (counts == NULL) {
+ _counts = (MPI_Offset**) NCI_Malloc((size_t)num * sizeof(MPI_Offset*));
+ _counts[0] = (MPI_Offset*) NCI_Malloc((size_t)(num * varp->ndims *
+ SIZEOF_MPI_OFFSET));
+ for (i=1; i<num; i++)
+ _counts[i] = _counts[i-1] + varp->ndims;
+ for (i=0; i<num; i++)
+ for (j=0; j<varp->ndims; j++)
+ _counts[i][j] = 1;
+ }
+ else
+ _counts = (MPI_Offset**) counts;
+
+ /* break buf into num pieces */
+ isSameGroup=0;
+ bufp = (char*)cbuf;
+ for (i=0; i<num; i++) {
+ MPI_Offset buflen;
+ for (buflen=1, j=0; j<varp->ndims; j++) {
+ if (_counts[i][j] < 0) { /* any negative counts[][] is illegal */
+ DEBUG_ASSIGN_ERROR(status, NC_ENEGATIVECNT)
+ goto err_check;
+ }
+ buflen *= _counts[i][j];
+ }
+ if (buflen == 0) continue;
+ status = ncmpii_igetput_varm(ncp, varp, starts[i], _counts[i], NULL,
+ NULL, bufp, buflen, ptype, &req_id,
+ rw_flag, 0, isSameGroup);
+ if (status != NC_NOERR) goto err_check;
+
+ /* use isSamegroup so we end up with one nonblocking request (only the
+ * first request gets a request ID back, the rest reuse the same ID.
+ * This single ID represents num nonblocking requests */
+ isSameGroup=1;
+ bufp += buflen * el_size;
+ }
+
+err_check:
+ if (_counts != NULL && _counts != counts) {
+ NCI_Free(_counts[0]);
+ NCI_Free(_counts);
+ }
+
+ if (ncp->safe_mode == 1 && io_method == COLL_IO) {
+ int mpireturn;
+ TRACE_COMM(MPI_Allreduce)(&status, &min_st, 1, MPI_INT, MPI_MIN,
+ ncp->nciop->comm);
+ if (mpireturn != MPI_SUCCESS)
+ return ncmpii_handle_error(mpireturn, "MPI_Allreduce");
+
+ if (min_st != NC_NOERR) {
+ if (req_id != NC_REQ_NULL) /* cancel pending nonblocking request */
+ ncmpii_cancel(ncp, 1, &req_id, &st);
+ if (free_cbuf) NCI_Free(cbuf);
+ return status;
+ }
+ }
+
+ if (io_method == INDEP_IO && status != NC_NOERR) {
+ if (req_id != NC_REQ_NULL) /* cancel pending nonblocking request */
+ ncmpii_cancel(ncp, 1, &req_id, &st);
+ if (free_cbuf) NCI_Free(cbuf);
+ return status;
+ }
+
+ num = 1;
+ if (status != NC_NOERR)
+ /* This can only be reached for COLL_IO and safe_mode == 0.
+ Set num=0 just so this process can participate the collective
+ calls in wait_all */
+ num = 0;
+
+ err = ncmpii_wait(ncp, io_method, num, &req_id, &st);
+
+ /* unpack to user buf, if buftype is noncontiguous */
+ if (status == NC_NOERR && rw_flag == READ_REQ && free_cbuf) {
+ position = 0;
+ MPI_Unpack(cbuf, (int)packsize, &position, buf, (int)bufcount, buftype,
+ MPI_COMM_SELF);
+ }
+
+ /* return the first error, if there is one */
+ if (status == NC_NOERR) status = err;
+ if (status == NC_NOERR) status = st;
+
+ if (free_cbuf) NCI_Free(cbuf);
+
+ return status;
+}
diff --git a/src/libcxx/Makefile.in b/src/libcxx/Makefile.in
new file mode 100755
index 0000000..3744491
--- /dev/null
+++ b/src/libcxx/Makefile.in
@@ -0,0 +1,83 @@
+#
+# Copyright (C) 2014, Northwestern University and Argonne National Laboratory
+# See COPYRIGHT notice in top-level directory.
+#
+# $Id: Makefile.in 2285 2015-12-30 20:48:25Z wkliao $
+#
+# @configure_input@
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+# generated by configure, so it's in the build dir, not srcdirr
+include ../../macros.make
+
+# For VPATH build:
+# Add ../lib into search path because ../lib/pnetcdf.h is created at the
+# configure time and included by all C++ source files.
+INCLUDES = -I../lib
+
+CXX_HEADER = pnetcdf
+
+LIBRARY = ../lib/libpnetcdf.a
+
+# Note the file order is important
+LIBS_HEADERS = ncmpi_notyet.h \
+ ncmpiCheck.h \
+ ncmpiType.h \
+ ncmpiAtt.h \
+ ncmpiEnumType.h \
+ ncmpiGroupAtt.h \
+ ncmpiGroup.h \
+ ncmpiByte.h \
+ ncmpiChar.h \
+ ncmpiCompoundType.h \
+ ncmpiDouble.h \
+ ncmpiFloat.h \
+ ncmpiInt.h \
+ ncmpiInt64.h \
+ ncmpiOpaqueType.h \
+ ncmpiShort.h \
+ ncmpiUbyte.h \
+ ncmpiUint.h \
+ ncmpiUint64.h \
+ ncmpiUshort.h \
+ ncmpiException.h \
+ ncmpiDim.h \
+ ncmpiFile.h \
+ ncmpiVarAtt.h \
+ ncmpiVar.h \
+ ncmpiVlenType.h
+
+LIB_SRCS = $(LIBS_HEADERS:.h=.cpp)
+
+LIB_OBJS = $(LIBS_HEADERS:.h=.o)
+
+PACKING_LIST = $(LIBS_HEADERS) $(LIB_SRCS) pnetcdf.in \
+ Makefile.in depend
+
+GARBAGE = $(LIB_OBJS) $(CXX_HEADER)
+DIST_GARBAGE =
+
+all: $(CXX_HEADER) $(LIBRARY)
+
+library $(LIBRARY): $(LIB_OBJS)
+ $(AR) $(ARFLAGS) $(LIBRARY) $(LIB_OBJS)
+ $(RANLIB) $(LIBRARY)
+
+$(CXX_HEADER): $(LIBS_HEADERS)
+ cp -f $(srcdir)/pnetcdf.in $(CXX_HEADER)
+ set -e; for i in $(LIBS_HEADERS); do ( \
+ sed -e '/#ifndef/d' -e '/#define/d' -e '/#endif/d' -e '/#include/d' $(srcdir)/$$i >> $(CXX_HEADER); \
+ ) ; done
+
+install:
+ $(INSTALL) -d -m 755 $(INCDIR)
+ $(INSTALL_DATA) $(CXX_HEADER) $(INCDIR)
+
+uninstall:
+ $(RM) -f $(INCDIR)/$(CXX_HEADER)
+
+include $(srcdir)/depend
+include $(srcdir)/../../rules.make
+
diff --git a/src/libcxx/depend b/src/libcxx/depend
new file mode 100644
index 0000000..d2e244f
--- /dev/null
+++ b/src/libcxx/depend
@@ -0,0 +1,67 @@
+ncmpi_notyet.o: ncmpi_notyet.cpp ../lib/pnetcdf.h ncmpi_notyet.h
+ncmpiCheck.o: ncmpiCheck.cpp ../lib/pnetcdf.h ncmpiException.h
+ncmpiType.o: ncmpiType.cpp ncmpiType.h ../lib/pnetcdf.h \
+ ncmpiGroup.h ncmpiEnumType.h ncmpiCheck.h ncmpi_notyet.h \
+ ncmpiGroupAtt.h ncmpiAtt.h ncmpiException.h
+ncmpiAtt.o: ncmpiAtt.cpp ncmpiAtt.h ncmpiType.h ../lib/pnetcdf.h \
+ ncmpiException.h ncmpiGroup.h ncmpiEnumType.h ncmpiCheck.h \
+ ncmpi_notyet.h ncmpiGroupAtt.h
+ncmpiEnumType.o: ncmpiEnumType.cpp ncmpiEnumType.h ncmpiType.h \
+ ../lib/pnetcdf.h ncmpiCheck.h ncmpi_notyet.h \
+ ncmpiGroup.h ncmpiGroupAtt.h ncmpiAtt.h ncmpiException.h ncmpiByte.h \
+ ncmpiUbyte.h ncmpiChar.h ncmpiShort.h ncmpiUshort.h ncmpiInt.h \
+ ncmpiUint.h ncmpiInt64.h ncmpiUint64.h ncmpiFloat.h ncmpiDouble.h
+ncmpiGroupAtt.o: ncmpiGroupAtt.cpp ncmpiGroupAtt.h ncmpiAtt.h ncmpiType.h \
+ ../lib/pnetcdf.h ncmpiException.h ncmpiGroup.h \
+ ncmpiEnumType.h ncmpiCheck.h ncmpi_notyet.h
+ncmpiGroup.o: ncmpiGroup.cpp ncmpiGroup.h ncmpiType.h ../lib/pnetcdf.h \
+ ncmpiEnumType.h ncmpiCheck.h ncmpi_notyet.h ncmpiGroupAtt.h ncmpiAtt.h \
+ ncmpiException.h ncmpiVar.h ncmpiVarAtt.h ncmpiByte.h ncmpiUbyte.h \
+ ncmpiChar.h ncmpiShort.h ncmpiUshort.h ncmpiInt.h ncmpiUint.h \
+ ncmpiInt64.h ncmpiUint64.h ncmpiFloat.h ncmpiDouble.h \
+ ncmpiDim.h ncmpiVlenType.h ncmpiCompoundType.h ncmpiOpaqueType.h \
+ ncmpiException.h
+ncmpiByte.o: ncmpiByte.cpp ncmpiByte.h ncmpiType.h ../lib/pnetcdf.h
+ncmpiChar.o: ncmpiChar.cpp ncmpiChar.h ncmpiType.h ../lib/pnetcdf.h
+ncmpiCompoundType.o: ncmpiCompoundType.cpp ncmpiGroup.h ncmpiType.h \
+ ../lib/pnetcdf.h ncmpiEnumType.h ncmpiCheck.h \
+ ncmpi_notyet.h ncmpiGroupAtt.h ncmpiAtt.h ncmpiException.h \
+ ncmpiCompoundType.h ncmpiByte.h ncmpiUbyte.h ncmpiChar.h ncmpiShort.h \
+ ncmpiUshort.h ncmpiInt.h ncmpiUint.h ncmpiInt64.h ncmpiUint64.h \
+ ncmpiFloat.h ncmpiDouble.h
+ncmpiDouble.o: ncmpiDouble.cpp ncmpiDouble.h ncmpiType.h ../lib/pnetcdf.h
+ncmpiFloat.o: ncmpiFloat.cpp ncmpiFloat.h ncmpiType.h ../lib/pnetcdf.h
+ncmpiInt.o: ncmpiInt.cpp ncmpiInt.h ncmpiType.h ../lib/pnetcdf.h
+ncmpiInt64.o: ncmpiInt64.cpp ncmpiInt64.h ncmpiType.h ../lib/pnetcdf.h
+ncmpiOpaqueType.o: ncmpiOpaqueType.cpp ncmpiOpaqueType.h ncmpiType.h \
+ ../lib/pnetcdf.h ncmpiGroup.h ncmpiEnumType.h \
+ ncmpiCheck.h ncmpi_notyet.h ncmpiGroupAtt.h ncmpiAtt.h ncmpiException.h
+ncmpiShort.o: ncmpiShort.cpp ncmpiShort.h ncmpiType.h ../lib/pnetcdf.h
+ncmpiUbyte.o: ncmpiUbyte.cpp ncmpiUbyte.h ncmpiType.h ../lib/pnetcdf.h
+ncmpiUint.o: ncmpiUint.cpp ncmpiUint.h ncmpiType.h ../lib/pnetcdf.h
+ncmpiUint64.o: ncmpiUint64.cpp ncmpiUint64.h ncmpiType.h ../lib/pnetcdf.h
+ncmpiUshort.o: ncmpiUshort.cpp ncmpiUshort.h ncmpiType.h ../lib/pnetcdf.h
+ncmpiException.o: ncmpiException.cpp ncmpiException.h ../lib/pnetcdf.h
+ncmpiDim.o: ncmpiDim.cpp ncmpiDim.h ncmpiGroup.h ncmpiType.h \
+ ../lib/pnetcdf.h ncmpiEnumType.h ncmpiCheck.h ncmpi_notyet.h \
+ ncmpiGroupAtt.h ncmpiAtt.h ncmpiException.h
+ncmpiFile.o: ncmpiFile.cpp ncmpiFile.h ncmpiGroup.h ncmpiType.h \
+ ../lib/pnetcdf.h ncmpiEnumType.h ncmpiCheck.h \
+ ncmpi_notyet.h ncmpiGroupAtt.h ncmpiAtt.h ncmpiException.h ncmpiByte.h
+ncmpiVarAtt.o: ncmpiVarAtt.cpp ncmpiVar.h ../lib/pnetcdf.h \
+ ncmpiVarAtt.h ncmpiAtt.h ncmpiType.h ncmpiException.h ncmpiGroup.h \
+ ncmpiEnumType.h ncmpiCheck.h ncmpi_notyet.h ncmpiGroupAtt.h ncmpiByte.h \
+ ncmpiUbyte.h ncmpiChar.h ncmpiShort.h ncmpiUshort.h ncmpiInt.h \
+ ncmpiUint.h ncmpiInt64.h ncmpiUint64.h ncmpiFloat.h ncmpiDouble.h
+ncmpiVar.o: ncmpiVar.cpp ncmpiVarAtt.h ncmpiAtt.h ncmpiType.h \
+ ../lib/pnetcdf.h ncmpiException.h ncmpiDim.h \
+ ncmpiVar.h ncmpiGroup.h ncmpiEnumType.h ncmpiCheck.h ncmpi_notyet.h \
+ ncmpiGroupAtt.h ncmpiByte.h ncmpiUbyte.h ncmpiChar.h ncmpiShort.h \
+ ncmpiUshort.h ncmpiInt.h ncmpiUint.h ncmpiInt64.h ncmpiUint64.h \
+ ncmpiFloat.h ncmpiDouble.h
+ncmpiVlenType.o: ncmpiVlenType.cpp ncmpiVlenType.h ncmpiType.h \
+ ../lib/pnetcdf.h ncmpiGroup.h ncmpiEnumType.h \
+ ncmpiCheck.h ncmpi_notyet.h ncmpiGroupAtt.h ncmpiAtt.h ncmpiException.h \
+ ncmpiByte.h ncmpiUbyte.h ncmpiChar.h ncmpiShort.h ncmpiUshort.h \
+ ncmpiInt.h ncmpiUint.h ncmpiInt64.h ncmpiUint64.h ncmpiFloat.h \
+ ncmpiDouble.h
diff --git a/src/libcxx/ncmpiAtt.cpp b/src/libcxx/ncmpiAtt.cpp
new file mode 100644
index 0000000..ec207f3
--- /dev/null
+++ b/src/libcxx/ncmpiAtt.cpp
@@ -0,0 +1,224 @@
+#include "ncmpiAtt.h"
+#include "ncmpiGroup.h"
+#include "ncmpiCheck.h"
+#include <vector>
+#include <assert.h>
+
+using namespace std;
+using namespace PnetCDF;
+
+
+// destructor (defined even though it is virtual)
+NcmpiAtt::~NcmpiAtt() {}
+
+// assignment operator
+NcmpiAtt& NcmpiAtt::operator=(const NcmpiAtt& rhs)
+{
+ nullObject = rhs.nullObject;
+ myName = rhs.myName;
+ groupId = rhs.groupId;
+ varId =rhs.varId;
+ return *this;
+}
+
+// Constructor generates a null object.
+NcmpiAtt::NcmpiAtt() :
+ nullObject(true)
+{}
+
+// Constructor for non-null instances.
+NcmpiAtt::NcmpiAtt(bool nullObject):
+ nullObject(nullObject)
+{}
+
+// The copy constructor.
+NcmpiAtt::NcmpiAtt(const NcmpiAtt& rhs) :
+ nullObject(rhs.nullObject),
+ myName(rhs.myName),
+ groupId(rhs.groupId),
+ varId(rhs.varId)
+{}
+
+
+// equivalence operator
+bool NcmpiAtt::operator==(const NcmpiAtt & rhs) const
+{
+ if(nullObject)
+ return nullObject == rhs.nullObject;
+ else
+ return myName == rhs.myName && groupId == rhs.groupId && varId == rhs.varId;
+}
+
+// != operator
+bool NcmpiAtt::operator!=(const NcmpiAtt & rhs) const
+{
+ return !(*this == rhs);
+}
+
+// Gets parent group.
+PnetCDF::NcmpiGroup NcmpiAtt::getParentGroup() const {
+ return PnetCDF::NcmpiGroup(groupId);
+}
+
+
+// Returns the attribute type.
+NcmpiType NcmpiAtt::getType() const{
+ // get the identifier for the netCDF type of this attribute.
+ nc_type xtypep;
+ ncmpiCheck(ncmpi_inq_atttype(groupId,varId,myName.c_str(),&xtypep),__FILE__,__LINE__);
+ if(xtypep <= 12)
+ // This is an atomic type
+ return NcmpiType(xtypep);
+ else
+ // this is a user-defined type
+ {
+ // now get the set of NcmpiType objects in this file.
+ multimap<string,NcmpiType> typeMap(getParentGroup().getTypes(NcmpiGroup::ParentsAndCurrent));
+ multimap<string,NcmpiType>::iterator iter;
+ // identify the Nctype object with the same id as this attribute.
+ for (iter=typeMap.begin(); iter!= typeMap.end();iter++) {
+ if(iter->second.getId() == xtypep) return iter->second;
+ }
+ // return a null object, as no type was identified.
+ return NcmpiType();
+ }
+}
+
+// Gets attribute length.
+MPI_Offset NcmpiAtt::getAttLength() const{
+ MPI_Offset lenp;
+ ncmpiCheck(ncmpi_inq_attlen(groupId, varId, myName.c_str(), &lenp),__FILE__,__LINE__);
+ return lenp;
+}
+
+// Gets a netCDF variable attribute.
+void NcmpiAtt::getValues(string& dataValues) const {
+ NcmpiType::ncmpiType typeClass(getType().getTypeClass());
+
+ MPI_Offset att_len=getAttLength();
+ char* tmpValues;
+ assert(att_len == (MPI_Offset)(size_t)att_len);
+ tmpValues = (char *) malloc((size_t)att_len + 1); /* + 1 for trailing null */
+
+ if(typeClass == NcmpiType::ncmpi_VLEN || typeClass == NcmpiType::ncmpi_OPAQUE || typeClass == NcmpiType::ncmpi_ENUM || typeClass == NcmpiType::ncmpi_COMPOUND)
+ ncmpiCheck(ncmpi_get_att(groupId,varId,myName.c_str(),tmpValues),__FILE__,__LINE__);
+ else
+ ncmpiCheck(ncmpi_get_att_text(groupId,varId,myName.c_str(),tmpValues),__FILE__,__LINE__);
+ dataValues=string(tmpValues, (size_t)att_len);
+ free(tmpValues);
+}
+
+// Gets a netCDF variable attribute.
+void NcmpiAtt::getValues(char* dataValues) const {
+ NcmpiType::ncmpiType typeClass(getType().getTypeClass());
+ if(typeClass == NcmpiType::ncmpi_VLEN || typeClass == NcmpiType::ncmpi_OPAQUE || typeClass == NcmpiType::ncmpi_ENUM || typeClass == NcmpiType::ncmpi_COMPOUND)
+ ncmpiCheck(ncmpi_get_att(groupId,varId,myName.c_str(),dataValues),__FILE__,__LINE__);
+ else
+ ncmpiCheck(ncmpi_get_att_text(groupId,varId,myName.c_str(),dataValues),__FILE__,__LINE__);
+}
+
+
+// Gets a netCDF variable attribute.
+void NcmpiAtt::getValues(unsigned char* dataValues) const {
+ NcmpiType::ncmpiType typeClass(getType().getTypeClass());
+ if(typeClass == NcmpiType::ncmpi_VLEN || typeClass == NcmpiType::ncmpi_OPAQUE || typeClass == NcmpiType::ncmpi_ENUM || typeClass == NcmpiType::ncmpi_COMPOUND)
+ ncmpiCheck(ncmpi_get_att(groupId,varId,myName.c_str(),dataValues),__FILE__,__LINE__);
+ else
+ ncmpiCheck(ncmpi_get_att_uchar(groupId,varId,myName.c_str(),dataValues),__FILE__,__LINE__);
+}
+
+// Gets a netCDF variable attribute.
+void NcmpiAtt::getValues(signed char* dataValues) const {
+ NcmpiType::ncmpiType typeClass(getType().getTypeClass());
+ if(typeClass == NcmpiType::ncmpi_VLEN || typeClass == NcmpiType::ncmpi_OPAQUE || typeClass == NcmpiType::ncmpi_ENUM || typeClass == NcmpiType::ncmpi_COMPOUND)
+ ncmpiCheck(ncmpi_get_att(groupId,varId,myName.c_str(),dataValues),__FILE__,__LINE__);
+ else
+ ncmpiCheck(ncmpi_get_att_schar(groupId,varId,myName.c_str(),dataValues),__FILE__,__LINE__);
+}
+
+// Gets a netCDF variable attribute.
+void NcmpiAtt::getValues(short* dataValues) const {
+ NcmpiType::ncmpiType typeClass(getType().getTypeClass());
+ if(typeClass == NcmpiType::ncmpi_VLEN || typeClass == NcmpiType::ncmpi_OPAQUE || typeClass == NcmpiType::ncmpi_ENUM || typeClass == NcmpiType::ncmpi_COMPOUND)
+ ncmpiCheck(ncmpi_get_att(groupId,varId,myName.c_str(),dataValues),__FILE__,__LINE__);
+ else
+ ncmpiCheck(ncmpi_get_att_short(groupId,varId,myName.c_str(),dataValues),__FILE__,__LINE__);
+}
+
+// Gets a netCDF variable attribute.
+void NcmpiAtt::getValues(int* dataValues) const {
+ NcmpiType::ncmpiType typeClass(getType().getTypeClass());
+ if(typeClass == NcmpiType::ncmpi_VLEN || typeClass == NcmpiType::ncmpi_OPAQUE || typeClass == NcmpiType::ncmpi_ENUM || typeClass == NcmpiType::ncmpi_COMPOUND)
+ ncmpiCheck(ncmpi_get_att(groupId,varId,myName.c_str(),dataValues),__FILE__,__LINE__);
+ else
+ ncmpiCheck(ncmpi_get_att_int(groupId,varId,myName.c_str(),dataValues),__FILE__,__LINE__);
+}
+
+// Gets a netCDF variable attribute.
+void NcmpiAtt::getValues(long* dataValues) const {
+ NcmpiType::ncmpiType typeClass(getType().getTypeClass());
+ if(typeClass == NcmpiType::ncmpi_VLEN || typeClass == NcmpiType::ncmpi_OPAQUE || typeClass == NcmpiType::ncmpi_ENUM || typeClass == NcmpiType::ncmpi_COMPOUND)
+ ncmpiCheck(ncmpi_get_att(groupId,varId,myName.c_str(),dataValues),__FILE__,__LINE__);
+ else
+ ncmpiCheck(ncmpi_get_att_long(groupId,varId,myName.c_str(),dataValues),__FILE__,__LINE__);
+}
+
+// Gets a netCDF variable attribute.
+void NcmpiAtt::getValues(float* dataValues) const {
+ NcmpiType::ncmpiType typeClass(getType().getTypeClass());
+ if(typeClass == NcmpiType::ncmpi_VLEN || typeClass == NcmpiType::ncmpi_OPAQUE || typeClass == NcmpiType::ncmpi_ENUM || typeClass == NcmpiType::ncmpi_COMPOUND)
+ ncmpiCheck(ncmpi_get_att(groupId,varId,myName.c_str(),dataValues),__FILE__,__LINE__);
+ else
+ ncmpiCheck(ncmpi_get_att_float(groupId,varId,myName.c_str(),dataValues),__FILE__,__LINE__);
+}
+
+// Gets a netCDF variable attribute.
+void NcmpiAtt::getValues(double* dataValues) const {
+ NcmpiType::ncmpiType typeClass(getType().getTypeClass());
+ if(typeClass == NcmpiType::ncmpi_VLEN || typeClass == NcmpiType::ncmpi_OPAQUE || typeClass == NcmpiType::ncmpi_ENUM || typeClass == NcmpiType::ncmpi_COMPOUND)
+ ncmpiCheck(ncmpi_get_att(groupId,varId,myName.c_str(),dataValues),__FILE__,__LINE__);
+ else
+ ncmpiCheck(ncmpi_get_att_double(groupId,varId,myName.c_str(),dataValues),__FILE__,__LINE__);
+}
+
+// Gets a netCDF variable attribute.
+void NcmpiAtt::getValues(unsigned short* dataValues) const {
+ NcmpiType::ncmpiType typeClass(getType().getTypeClass());
+ if(typeClass == NcmpiType::ncmpi_VLEN || typeClass == NcmpiType::ncmpi_OPAQUE || typeClass == NcmpiType::ncmpi_ENUM || typeClass == NcmpiType::ncmpi_COMPOUND)
+ ncmpiCheck(ncmpi_get_att(groupId,varId,myName.c_str(),dataValues),__FILE__,__LINE__);
+ else
+ ncmpiCheck(ncmpi_get_att_ushort(groupId,varId,myName.c_str(),dataValues),__FILE__,__LINE__);
+}
+
+// Gets a netCDF variable attribute.
+void NcmpiAtt::getValues(unsigned int* dataValues) const {
+ NcmpiType::ncmpiType typeClass(getType().getTypeClass());
+ if(typeClass == NcmpiType::ncmpi_VLEN || typeClass == NcmpiType::ncmpi_OPAQUE || typeClass == NcmpiType::ncmpi_ENUM || typeClass == NcmpiType::ncmpi_COMPOUND)
+ ncmpiCheck(ncmpi_get_att(groupId,varId,myName.c_str(),dataValues),__FILE__,__LINE__);
+ else
+ ncmpiCheck(ncmpi_get_att_uint(groupId,varId,myName.c_str(),dataValues),__FILE__,__LINE__);
+}
+
+// Gets a netCDF variable attribute.
+void NcmpiAtt::getValues(long long* dataValues) const {
+ NcmpiType::ncmpiType typeClass(getType().getTypeClass());
+ if(typeClass == NcmpiType::ncmpi_VLEN || typeClass == NcmpiType::ncmpi_OPAQUE || typeClass == NcmpiType::ncmpi_ENUM || typeClass == NcmpiType::ncmpi_COMPOUND)
+ ncmpiCheck(ncmpi_get_att(groupId,varId,myName.c_str(),dataValues),__FILE__,__LINE__);
+ else
+ ncmpiCheck(ncmpi_get_att_longlong(groupId,varId,myName.c_str(),dataValues),__FILE__,__LINE__);
+}
+
+// Gets a netCDF variable attribute.
+void NcmpiAtt::getValues(unsigned long long* dataValues) const {
+ NcmpiType::ncmpiType typeClass(getType().getTypeClass());
+ if(typeClass == NcmpiType::ncmpi_VLEN || typeClass == NcmpiType::ncmpi_OPAQUE || typeClass == NcmpiType::ncmpi_ENUM || typeClass == NcmpiType::ncmpi_COMPOUND)
+ ncmpiCheck(ncmpi_get_att(groupId,varId,myName.c_str(),dataValues),__FILE__,__LINE__);
+ else
+ ncmpiCheck(ncmpi_get_att_ulonglong(groupId,varId,myName.c_str(),dataValues),__FILE__,__LINE__);
+}
+
+// Gets a netCDF variable attribute.
+void NcmpiAtt::getValues(void* dataValues) const {
+ ncmpiCheck(ncmpi_get_att(groupId,varId,myName.c_str(),dataValues),__FILE__,__LINE__);
+}
+
diff --git a/src/libcxx/ncmpiAtt.h b/src/libcxx/ncmpiAtt.h
new file mode 100644
index 0000000..423e1dd
--- /dev/null
+++ b/src/libcxx/ncmpiAtt.h
@@ -0,0 +1,121 @@
+#include "ncmpiType.h"
+#include "ncmpiException.h"
+#include <string>
+#include <typeinfo>
+
+#ifndef NcmpiAttClass
+#define NcmpiAttClass
+
+namespace PnetCDF
+{
+
+ /*! Abstract base class represents inherited by ncmpiVarAtt and ncmpiGroupAtt. */
+ class NcmpiAtt
+ {
+ public:
+
+ /*! destructor */
+ virtual ~NcmpiAtt()=0;
+
+ /*! Constructor generates a \ref isNull "null object". */
+ NcmpiAtt ();
+
+ /*! Constructor for non-null instances. */
+ NcmpiAtt(bool nullObject);
+
+ /*! The copy constructor. */
+ NcmpiAtt(const NcmpiAtt& rhs);
+
+ /*! Get the attribute name. */
+ std::string getName() const {return myName;}
+
+ /*! Gets attribute length. */
+ MPI_Offset getAttLength() const;
+
+ /*! Returns the attribute type. */
+ NcmpiType getType() const;
+
+ /*! Gets parent group. */
+ NcmpiGroup getParentGroup() const;
+
+ /*! equivalence operator */
+ bool operator== (const NcmpiAtt& rhs) const;
+
+ /*! != operator */
+ bool operator!=(const NcmpiAtt& rhs) const;
+
+ /*! \overload
+ */
+ void getValues(char* dataValues) const;
+ /*! \overload
+ */
+ void getValues(unsigned char* dataValues) const;
+ /*! \overload
+ */
+ void getValues(signed char* dataValues) const;
+ /*! \overload
+ */
+ void getValues(short* dataValues) const;
+ /*! \overload
+ */
+ void getValues(int* dataValues) const;
+ /*! \overload
+ */
+ void getValues(long* dataValues) const;
+ /*! \overload
+ */
+ void getValues(float* dataValues) const;
+ /*! \overload
+ */
+ void getValues(double* dataValues) const;
+ /*! \overload
+ */
+ void getValues(unsigned short* dataValues) const;
+ /*! \overload
+ */
+ void getValues(unsigned int* dataValues) const;
+ /*! \overload
+ */
+ void getValues(long long* dataValues) const;
+ /*! \overload
+ */
+ void getValues(unsigned long long* dataValues) const;
+ /*! \overload
+ */
+ void getValues(char** dataValues) const;
+
+ /*! \overload
+ (The string variable does not need preallocating.)
+ */
+ void getValues(std::string& dataValues) const;
+
+ /*!
+ Gets a netCDF attribute.
+ The user must ensure that the variable "dataValues" has sufficient space to hold the attribute.
+ \param dataValues On return contains the value of the attribute.
+ If the type of data values differs from the netCDF variable type, type conversion will occur.
+ (However, no type conversion is carried out for variables using the user-defined data types:
+ ncmpi_Vlen, ncmpi_Opaque, ncmpi_Compound and ncmpi_Enum.)
+ */
+ void getValues(void* dataValues) const;
+
+ /*! Returns true if this object is null (i.e. it has no contents); otherwise returns false. */
+ bool isNull() const {return nullObject;}
+
+ protected:
+ /*! assignment operator */
+ NcmpiAtt& operator= (const NcmpiAtt& rhs);
+
+ bool nullObject;
+
+ std::string myName;
+
+ int groupId;
+
+ int varId;
+
+ };
+
+}
+
+#endif
diff --git a/src/libcxx/ncmpiByte.cpp b/src/libcxx/ncmpiByte.cpp
new file mode 100644
index 0000000..8d057f8
--- /dev/null
+++ b/src/libcxx/ncmpiByte.cpp
@@ -0,0 +1,24 @@
+#include "ncmpiByte.h"
+#include <pnetcdf.h>
+using namespace PnetCDF;
+
+// create an instance of NcmpiByte called PnetCDF::ncmpiByte
+namespace PnetCDF {
+ NcmpiByte ncmpiByte;
+}
+
+// constructor
+NcmpiByte::NcmpiByte() : NcmpiType(NC_BYTE){
+}
+
+NcmpiByte::~NcmpiByte() {
+}
+
+int NcmpiByte::sizeoff(){char a;return sizeof(a);};
+
+
+// equivalence operator
+bool NcmpiByte::operator==(const NcmpiByte & rhs) {
+ // simply check the netCDF id.
+ return myId == rhs.myId;
+}
diff --git a/src/libcxx/ncmpiByte.h b/src/libcxx/ncmpiByte.h
new file mode 100644
index 0000000..8c973ac
--- /dev/null
+++ b/src/libcxx/ncmpiByte.h
@@ -0,0 +1,30 @@
+#include "ncmpiType.h"
+
+#ifndef NcmpiByteClass
+#define NcmpiByteClass
+
+namespace PnetCDF
+{
+
+ /*! Class represents a netCDF atomic Byte type. */
+ class NcmpiByte : public NcmpiType
+ {
+ public:
+
+ /*! equivalence operator */
+ bool operator==(const NcmpiByte & rhs);
+
+ /*! storage size */
+ int sizeoff();
+
+ ~NcmpiByte();
+
+ /*! Constructor */
+ NcmpiByte();
+ };
+
+ /*! A global instance of the NcmpiByte class within the netCDF namespace. */
+ extern NcmpiByte ncmpiByte;
+
+}
+#endif
diff --git a/src/libcxx/ncmpiChar.cpp b/src/libcxx/ncmpiChar.cpp
new file mode 100644
index 0000000..a4f7cc0
--- /dev/null
+++ b/src/libcxx/ncmpiChar.cpp
@@ -0,0 +1,22 @@
+#include "ncmpiChar.h"
+#include <pnetcdf.h>
+using namespace PnetCDF;
+
+// create an instance of NcmpiChar called PnetCDF::ncmpiChar
+namespace PnetCDF {
+ NcmpiChar ncmpiChar;
+}
+
+// constructor
+NcmpiChar::NcmpiChar() : NcmpiType(NC_CHAR){
+}
+
+NcmpiChar::~NcmpiChar() {
+}
+
+
+// equivalence operator
+bool NcmpiChar::operator==(const NcmpiChar & rhs) {
+ // simply check the netCDF id.
+ return myId == rhs.myId;
+}
diff --git a/src/libcxx/ncmpiChar.h b/src/libcxx/ncmpiChar.h
new file mode 100644
index 0000000..9b8ed0f
--- /dev/null
+++ b/src/libcxx/ncmpiChar.h
@@ -0,0 +1,27 @@
+#include "ncmpiType.h"
+
+#ifndef NcmpiCharClass
+#define NcmpiCharClass
+
+namespace PnetCDF
+{
+
+ /*! Class represents a netCDF atomic Char type. */
+ class NcmpiChar : public NcmpiType
+ {
+ public:
+
+ /*! equivalence operator */
+ bool operator==(const NcmpiChar & rhs);
+
+ ~NcmpiChar();
+
+ /*! Constructor */
+ NcmpiChar();
+ };
+
+ /*! A global instance of the NcmpiChar class within the netCDF namespace. */
+ extern NcmpiChar ncmpiChar;
+
+}
+#endif
diff --git a/src/libcxx/ncmpiCheck.cpp b/src/libcxx/ncmpiCheck.cpp
new file mode 100644
index 0000000..c9d3793
--- /dev/null
+++ b/src/libcxx/ncmpiCheck.cpp
@@ -0,0 +1,94 @@
+#include <cstring>
+#include <pnetcdf.h>
+#include "ncmpiException.h"
+using namespace std;
+using namespace PnetCDF::exceptions;
+
+// C++ API for netCDF4.
+namespace PnetCDF
+{
+ // function checks error code and if necessary throws appropriate exception.
+ void ncmpiCheck(int retCode, const char* file, int line){
+ if (retCode==NC_NOERR)
+ return;
+
+ const char* msg = 0;
+ if (NC_ISSYSERR(retCode)){
+ msg = std::strerror(retCode);
+ msg = msg ? msg : "Unknown system error";
+ }else{
+ msg = ncmpi_strerror(retCode);
+ }
+
+ switch(retCode) {
+ case NC_EBADID : throw NcBadId(msg,file,line);
+ case NC_ENFILE : throw NcNFile(msg,file,line);
+ case NC_EEXIST : throw NcExist(msg,file,line);
+ case NC_EINVAL : throw NcInvalidArg(msg,file,line);
+ case NC_EPERM : throw NcInvalidWrite(msg,file,line);
+ case NC_ENOTINDEFINE : throw NcNotInDefineMode(msg,file,line);
+ case NC_EINDEFINE : throw NcInDefineMode(msg,file,line);
+ case NC_EINVALCOORDS : throw NcInvalidCoords(msg,file,line);
+ case NC_EMAXDIMS : throw NcMaxDims(msg,file,line);
+ case NC_ENAMEINUSE : throw NcNameInUse(msg,file,line);
+ case NC_ENOTATT : throw NcNotAtt(msg,file,line);
+ case NC_EMAXATTS : throw NcMaxAtts(msg,file,line);
+ case NC_EBADTYPE : throw NcBadType(msg,file,line);
+ case NC_EBADDIM : throw NcBadDim(msg,file,line);
+ case NC_EUNLIMPOS : throw NcUnlimPos(msg,file,line);
+ case NC_EMAXVARS : throw NcMaxVars(msg,file,line);
+ case NC_ENOTVAR : throw NcNotVar(msg,file,line);
+ case NC_EGLOBAL : throw NcGlobal(msg,file,line);
+ case NC_ENOTNC : throw NcNotNCF(msg,file,line);
+ case NC_ESTS : throw NcSts(msg,file,line);
+ case NC_EMAXNAME : throw NcMaxName(msg,file,line);
+ case NC_EUNLIMIT : throw NcUnlimit(msg,file,line);
+ case NC_ENORECVARS : throw NcNoRecVars(msg,file,line);
+ case NC_ECHAR : throw NcmpiChar(msg,file,line);
+ case NC_EEDGE : throw NcEdge(msg,file,line);
+ case NC_ESTRIDE : throw NcStride(msg,file,line);
+ case NC_EBADNAME : throw NcBadName(msg,file,line);
+ case NC_ERANGE : throw NcRange(msg,file,line);
+ case NC_ENOMEM : throw NcNoMem(msg,file,line);
+ case NC_EVARSIZE : throw NcmpiVarSize(msg,file,line);
+ case NC_EDIMSIZE : throw NcmpiDimSize(msg,file,line);
+ case NC_ETRUNC : throw NcTrunc(msg,file,line);
+
+ // The following are specific netCDF4 errors.
+ case NC_EHDFERR : throw NcHdfErr(msg,file,line);
+ case NC_ECANTREAD : throw NcCantRead(msg,file,line);
+ case NC_ECANTWRITE : throw NcCantWrite(msg,file,line);
+ case NC_ECANTCREATE : throw NcCantCreate(msg,file,line);
+ case NC_EFILEMETA : throw NcmpiFileMeta(msg,file,line);
+ case NC_EDIMMETA : throw NcmpiDimMeta(msg,file,line);
+ case NC_EATTMETA : throw NcmpiAttMeta(msg,file,line);
+ case NC_EVARMETA : throw NcmpiVarMeta(msg,file,line);
+ case NC_ENOCOMPOUND : throw NcNoCompound(msg,file,line);
+ case NC_EATTEXISTS : throw NcmpiAttExists(msg,file,line);
+ case NC_ENOTNC4 : throw NcNotNc4(msg,file,line);
+ case NC_ESTRICTNC3 : throw NcStrictNc3(msg,file,line);
+ case NC_EBADGRPID : throw NcBadGroupId(msg,file,line);
+ case NC_EBADTYPID : throw NcBadTypeId(msg,file,line); // netcdf.h file inconsistent with documentation!!
+ case NC_EBADFIELD : throw NcBadFieldId(msg,file,line); // netcdf.h file inconsistent with documentation!!
+ // case NC_EUNKNAME : throw NcUnkownName("Cannot find the field id.",file,line); // netcdf.h file inconsistent with documentation!!
+
+ case NC_ENOGRP : throw NcEnoGrp(msg,file,line);
+ case NC_ELATEDEF : throw NcElateDef(msg,file,line);
+
+ default:
+ throw NcmpiException(retCode, msg, file, line);
+ }
+ }
+
+ void ncmpiCheckDefineMode(int ncid)
+ {
+ int status = ncmpi_redef(ncid);
+ if (status != NC_EINDEFINE) ncmpiCheck(status, __FILE__, __LINE__);
+ }
+
+ void ncmpiCheckDataMode(int ncid)
+ {
+ int status = ncmpi_enddef(ncid);
+ if (status != NC_ENOTINDEFINE) ncmpiCheck(status, __FILE__, __LINE__);
+ }
+}
diff --git a/src/libcxx/ncmpiCheck.h b/src/libcxx/ncmpiCheck.h
new file mode 100644
index 0000000..3cd09c9
--- /dev/null
+++ b/src/libcxx/ncmpiCheck.h
@@ -0,0 +1,35 @@
+#include <string.h>
+#include <stdlib.h>
+
+#ifndef NcmpiCheckFunction
+#define NcmpiCheckFunction
+
+namespace PnetCDF
+{
+ /*!
+ Function checks error code and if necessary throws an exception.
+ \param retCode Integer value returned by %netCDF C-routines.
+ \param file The name of the file from which this call originates.
+ \param line The line number in the file from which this call originates.
+ */
+ void ncmpiCheck(int retCode, const char* file, int line);
+
+ /*!
+ Function checks if the file (group) is in define mode.
+ If not, it places it in the define mode.
+ While this is automatically done by the underlying C API
+ for netCDF-4 files, the netCDF-3 files still need this call.
+ */
+ void ncmpiCheckDefineMode(int ncid);
+
+ /*!
+ Function checks if the file (group) is in data mode.
+ If not, it places it in the data mode.
+ While this is automatically done by the underlying C API
+ for netCDF-4 files, the netCDF-3 files still need this call.
+ */
+ void ncmpiCheckDataMode(int ncid);
+
+};
+
+#endif
diff --git a/src/libcxx/ncmpiCompoundType.cpp b/src/libcxx/ncmpiCompoundType.cpp
new file mode 100644
index 0000000..99cd96b
--- /dev/null
+++ b/src/libcxx/ncmpiCompoundType.cpp
@@ -0,0 +1,156 @@
+#include "ncmpiGroup.h"
+#include "ncmpiCheck.h"
+#include "ncmpiCompoundType.h"
+#include "ncmpiByte.h"
+#include "ncmpiUbyte.h"
+#include "ncmpiChar.h"
+#include "ncmpiShort.h"
+#include "ncmpiUshort.h"
+#include "ncmpiInt.h"
+#include "ncmpiUint.h"
+#include "ncmpiInt64.h"
+#include "ncmpiUint64.h"
+#include "ncmpiFloat.h"
+#include "ncmpiDouble.h"
+#include "ncmpiException.h"
+
+using namespace std;
+using namespace PnetCDF;
+using namespace PnetCDF::exceptions;
+
+// Class represents a netCDF variable.
+
+// assignment operator
+NcmpiCompoundType& NcmpiCompoundType::operator=(const NcmpiCompoundType& rhs)
+{
+ NcmpiType::operator=(rhs); // assign base class parts
+ return *this;
+}
+
+// assignment operator
+NcmpiCompoundType& NcmpiCompoundType::operator=(const NcmpiType& rhs)
+{
+ if (&rhs != this) {
+ // check the rhs is the base of a Compound type
+ if(getTypeClass() != ncmpi_COMPOUND) throw NcmpiException("The NcmpiType object must be the base of a Compound type.",__FILE__,__LINE__);
+ // assign base class parts
+ NcmpiType::operator=(rhs);
+ }
+ return *this;
+}
+
+// The copy constructor.
+NcmpiCompoundType::NcmpiCompoundType(const NcmpiCompoundType& rhs):
+ NcmpiType(rhs)
+{
+}
+
+
+// equivalence operator
+bool NcmpiCompoundType::operator==(const NcmpiCompoundType& rhs)
+{
+ if(nullObject)
+ return nullObject == rhs.nullObject;
+ else
+ return myId ==rhs.myId && groupId == rhs.groupId;
+}
+
+// Constructor generates a null object.
+NcmpiCompoundType::NcmpiCompoundType() :
+ NcmpiType() // invoke base class constructor
+{}
+
+// constructor
+NcmpiCompoundType::NcmpiCompoundType(const NcmpiGroup& grp, const string& name):
+ NcmpiType(grp,name)
+{
+}
+
+// constructor
+// The copy constructor.
+NcmpiCompoundType::NcmpiCompoundType(const NcmpiType& rhs):
+ NcmpiType()
+{
+ // assign base class parts
+ NcmpiType::operator=(rhs);
+}
+
+// Inserts a named field.
+void NcmpiCompoundType::addMember(const string& memberName, const NcmpiType& newMemberType,MPI_Offset offset)
+{
+ ncmpiCheck(ncmpi_insert_compound(groupId,myId,const_cast<char*>(memberName.c_str()),offset,newMemberType.getId()),__FILE__,__LINE__);
+}
+
+
+
+// Inserts a named array field.
+void NcmpiCompoundType::addMember(const string& memberName, const NcmpiType& newMemberType, MPI_Offset offset, const vector<int>& shape)
+{
+ if (!shape.empty())
+ ncmpiCheck(ncmpi_insert_array_compound(groupId, myId,const_cast<char*>(memberName.c_str()), offset, newMemberType.getId(), shape.size(), const_cast<int*>(&shape[0])),__FILE__,__LINE__);
+ else
+ addMember(memberName, newMemberType, offset);
+}
+
+
+
+// Returns number of members in this NcmpiCompoundType object.
+MPI_Offset NcmpiCompoundType::getMemberCount() const
+{
+ MPI_Offset nfieldsp;
+ ncmpiCheck(ncmpi_inq_compound_nfields(groupId,myId,&nfieldsp),__FILE__,__LINE__);
+ return nfieldsp;
+}
+
+
+// Returns a NcmpiType object for a single member. */
+NcmpiType NcmpiCompoundType::getMember(int memberIndex) const
+{
+ nc_type fieldtypeidp;
+ ncmpiCheck(ncmpi_inq_compound_fieldtype(groupId,myId,memberIndex,&fieldtypeidp),__FILE__,__LINE__);
+ switch (fieldtypeidp) {
+ case NC_BYTE : return ncmpiByte;
+ case NC_UBYTE : return ncmpiUbyte;
+ case NC_CHAR : return ncmpiChar;
+ case NC_SHORT : return ncmpiShort;
+ case NC_USHORT : return ncmpiUshort;
+ case NC_INT : return ncmpiInt;
+ case NC_UINT : return ncmpiUint;
+ case NC_INT64 : return ncmpiInt64;
+ case NC_UINT64 : return ncmpiUint64;
+ case NC_FLOAT : return ncmpiFloat;
+ case NC_DOUBLE : return ncmpiDouble;
+ default:
+ // this is a user defined type
+ return NcmpiType(getParentGroup(),fieldtypeidp);
+ }
+}
+
+
+// Returns the number of dimensions of a member with the given index.
+int NcmpiCompoundType::getMemberDimCount(int memberIndex) const
+{
+ int ndimsp;
+ ncmpiCheck(ncmpi_inq_compound_fieldndims(groupId,myId,memberIndex, &ndimsp),__FILE__,__LINE__);
+ return ndimsp;
+}
+
+
+// Returns the shape of the given member.
+vector<int> NcmpiCompoundType::getMemberShape(int memberIndex) const
+{
+ vector<int> dim_size;
+ dim_size.resize(getMemberDimCount(memberIndex));
+ if(!dim_size.empty())
+ ncmpiCheck(ncmpi_inq_compound_fielddim_sizes(groupId,myId,memberIndex,&dim_size[0]),__FILE__,__LINE__);
+ return dim_size;
+}
+
+
+// Returns the offset of the member with given index.
+MPI_Offset NcmpiCompoundType::getMemberOffset(const int index) const
+{
+ MPI_Offset offsetp;
+ ncmpiCheck(ncmpi_inq_compound_fieldoffset(groupId,myId, index,&offsetp),__FILE__,__LINE__);
+ return offsetp;
+}
diff --git a/src/libcxx/ncmpiCompoundType.h b/src/libcxx/ncmpiCompoundType.h
new file mode 100644
index 0000000..9ff9cd4
--- /dev/null
+++ b/src/libcxx/ncmpiCompoundType.h
@@ -0,0 +1,107 @@
+#include <string>
+#include <vector>
+#include "ncmpiType.h"
+
+#ifndef NcmpiCompoundTypeClass
+#define NcmpiCompoundTypeClass
+
+
+namespace PnetCDF
+{
+ class NcmpiGroup; // forward declaration.
+
+ /*!
+ Class represents a netCDF compound type
+ */
+ class NcmpiCompoundType : public NcmpiType
+ {
+ public:
+
+ /*! Constructor generates a \ref isNull "null object". */
+ NcmpiCompoundType();
+
+ /*!
+ Constructor.
+ The compound Type must already exist in the netCDF file. New netCDF compound types can be
+ added using NcmpiGroup::addNcmpiCompoundType();
+ \param grp The parent group where this type is defined.
+ \param name Name of new type.
+ */
+ NcmpiCompoundType(const NcmpiGroup& grp, const std::string& name);
+
+ /*!
+ Constructor.
+ Constructs from the base type NcmpiType object. Will throw an exception if the NcmpiType is not the base of a Compound type.
+ \param ncmpiType A Nctype object.
+ */
+ NcmpiCompoundType(const NcmpiType& ncmpiType);
+
+ /*! assignment operator */
+ NcmpiCompoundType& operator=(const NcmpiCompoundType& rhs);
+
+ /*!
+ Assignment operator.
+ This assigns from the base type NcmpiType object. Will throw an exception if the NcmpiType is not the base of a Compound type.
+ */
+ NcmpiCompoundType& operator=(const NcmpiType& rhs);
+
+ /*! The copy constructor. */
+ NcmpiCompoundType(const NcmpiCompoundType& rhs);
+
+ /*! equivalence operator */
+ bool operator==(const NcmpiCompoundType & rhs);
+
+ /*! destructor */
+ ~NcmpiCompoundType(){;}
+
+
+ /*!
+ Adds a named field.
+ \param memName Name of new field.
+ \param newMemberType The type of the new member.
+ \param offset Offset of this member in bytes, obtained by a call to offsetof. For example
+the offset of a member "mem4" in structure struct1 is: offsetof(struct1,mem4).
+ */
+ void addMember(const std::string& memName, const NcmpiType& newMemberType,MPI_Offset offset);
+
+ /*!
+ Adds a named array field.
+ \param memName Name of new field.
+ \param newMemberType The type of the new member.
+ \param offset Offset of this member in bytes, obtained by a call to offsetof. For example
+ the offset of a member "mem4" in structure struct1 is: offsetof(struct1,mem4).
+ \param shape The shape of the array field.
+ */
+ void addMember(const std::string& memName, const NcmpiType& newMemberType, MPI_Offset offset, const std::vector<int>& shape);
+
+
+ /*! Returns number of members in this NcmpiCompoundType object. */
+ MPI_Offset getMemberCount() const;
+
+ /*! Returns a NcmpiType object for a single member. */
+ NcmpiType getMember(int memberIndex) const;
+
+ /*! Returns the offset of the member with given index. */
+ MPI_Offset getMemberOffset(const int index) const;
+
+ /*!
+ Returns the number of dimensions of a member with the given index.
+ \param Index of member (numbering starts at zero).
+ \return The number of dimensions of the field. Non-array fields have 0 dimensions.
+ */
+ int getMemberDimCount(int memberIndex) const;
+
+
+ /*!
+ Returns the shape of a given member.
+ \param Index of member (numbering starts at zero).
+ \return The size of the dimensions of the field. Non-array fields have 0 dimensions.
+ */
+ std::vector<int> getMemberShape(int memberIndex) const;
+
+ };
+
+}
+
+
+#endif
diff --git a/src/libcxx/ncmpiDim.cpp b/src/libcxx/ncmpiDim.cpp
new file mode 100644
index 0000000..cd29382
--- /dev/null
+++ b/src/libcxx/ncmpiDim.cpp
@@ -0,0 +1,125 @@
+#include "ncmpiDim.h"
+#include "ncmpiGroup.h"
+#include "ncmpiCheck.h"
+#include <algorithm>
+using namespace std;
+
+
+namespace PnetCDF {
+ // Global comparator operator ==============
+ // comparator operator
+ bool operator<(const NcmpiDim& lhs,const NcmpiDim& rhs)
+ {
+ return false;
+ }
+
+ // comparator operator
+ bool operator>(const NcmpiDim& lhs,const NcmpiDim& rhs)
+ {
+ return true;
+ }
+}
+
+using namespace PnetCDF;
+
+// assignment operator
+NcmpiDim& NcmpiDim::operator=(const NcmpiDim & rhs)
+{
+ nullObject = rhs.nullObject;
+ myId = rhs.myId;
+ groupId = rhs.groupId;
+ return *this;
+}
+
+// The copy constructor.
+NcmpiDim::NcmpiDim(const NcmpiDim& rhs):
+ nullObject(rhs.nullObject),
+ myId(rhs.myId),
+ groupId(rhs.groupId)
+{}
+
+
+// equivalence operator
+bool NcmpiDim::operator==(const NcmpiDim& rhs) const
+{
+ if(nullObject)
+ return nullObject == rhs.nullObject;
+ else
+ return myId == rhs.myId && groupId == rhs.groupId;
+}
+
+// != operator
+bool NcmpiDim::operator!=(const NcmpiDim & rhs) const
+{
+ return !(*this == rhs);
+}
+
+
+// Gets parent group.
+NcmpiGroup NcmpiDim::getParentGroup() const {
+ return NcmpiGroup(groupId);
+}
+
+// Constructor generates a null object.
+NcmpiDim::NcmpiDim() :
+ nullObject(true)
+{}
+
+// Constructor for a dimension (must already exist in the netCDF file.)
+NcmpiDim::NcmpiDim(const NcmpiGroup& grp, int dimId) :
+ nullObject(false)
+{
+ groupId = grp.getId();
+ myId = dimId;
+}
+
+// gets the size of the dimension, for unlimited, this is the current number of records.
+MPI_Offset NcmpiDim::getSize() const
+{
+ MPI_Offset dimSize;
+ ncmpiCheck(ncmpi_inq_dimlen(groupId, myId, &dimSize),__FILE__,__LINE__);
+ return dimSize;
+}
+
+
+// returns true if this dimension is unlimited.
+bool NcmpiDim::isUnlimited() const
+{
+ int dimid;
+ ncmpiCheck(ncmpi_inq_unlimdim(groupId,&dimid),__FILE__,__LINE__);
+ return (myId == dimid);
+
+#if 0
+ int numlimdims;
+ int* unlimdimidsp=NULL;
+ // get the number of unlimited dimensions
+ ncmpiCheck(ncmpi_inq_unlimdims(groupId,&numlimdims,unlimdimidsp),__FILE__,__LINE__);
+ if (numlimdims){
+ // get all the unlimited dimension ids in this group
+ vector<int> unlimdimid(numlimdims);
+ ncmpiCheck(ncmpi_inq_unlimdims(groupId,&numlimdims,&unlimdimid[0]),__FILE__,__LINE__);
+ vector<int>::iterator it;
+ // now look to see if this dimension is unlimited
+ it = find(unlimdimid.begin(),unlimdimid.end(),myId);
+ return it != unlimdimid.end();
+ }
+ return false;
+#endif
+}
+
+
+// gets the name of the dimension.
+const string NcmpiDim::getName() const
+{
+ char dimName[NC_MAX_NAME+1];
+ ncmpiCheck(ncmpi_inq_dimname(groupId, myId, dimName),__FILE__,__LINE__);
+ return string(dimName);
+}
+
+// renames this dimension.
+void NcmpiDim::rename(const string& name)
+{
+ ncmpiCheck(ncmpi_rename_dim(groupId, myId, name.c_str()),__FILE__,__LINE__);
+}
+
+
diff --git a/src/libcxx/ncmpiDim.h b/src/libcxx/ncmpiDim.h
new file mode 100644
index 0000000..a381849
--- /dev/null
+++ b/src/libcxx/ncmpiDim.h
@@ -0,0 +1,84 @@
+#include <string>
+#include <mpi.h>
+
+#ifndef NcmpiDimClass
+#define NcmpiDimClass
+
+
+namespace PnetCDF
+{
+ class NcmpiGroup; // forward declaration.
+
+ /*! Class represents a netCDF dimension */
+ class NcmpiDim {
+
+ public:
+
+ /*! destructor*/
+ ~NcmpiDim(){};
+
+ /*! Constructor generates a \ref isNull "null object". */
+ NcmpiDim ();
+
+ /*!
+ Constructor for a dimension .
+ The dimension must already exist in the netCDF file. New netCDF variables can be added using NcmpiGroup::addNcmpiDim();
+ \param grp Parent NcmpiGroup object.
+ \param dimId Id of the NcmpiDim object.
+ */
+ NcmpiDim(const NcmpiGroup& grp, int dimId);
+
+ /*! assignment operator */
+ NcmpiDim& operator =(const NcmpiDim &);
+
+ /*! equivalence operator */
+ bool operator==(const NcmpiDim& rhs) const;
+
+ /*! != operator */
+ bool operator!=(const NcmpiDim& rhs) const;
+
+ /*! The copy constructor. */
+ NcmpiDim(const NcmpiDim& ncmpiDim);
+
+ /*! The name of this dimension.*/
+ const std::string getName() const;
+
+ /*! The netCDF Id of this dimension. */
+ int getId() const {return myId;};
+
+ /*! Gets a NcmpiGroup object of the parent group. */
+ NcmpiGroup getParentGroup() const;
+
+ /*! Returns true if this is an unlimited dimension */
+ bool isUnlimited() const;
+
+ /*! The size of the dimension; for unlimited, this is the number of records written so far. */
+ MPI_Offset getSize() const;
+
+ /*!renames the dimension */
+ void rename( const std::string& newName);
+
+ /*! Returns true if this object is null (i.e. it has no contents); otherwise returns false. */
+ bool isNull() const {return nullObject;}
+
+ /*! comparator operator */
+ friend bool operator<(const NcmpiDim& lhs,const NcmpiDim& rhs);
+
+ /*! comparator operator */
+ friend bool operator>(const NcmpiDim& lhs,const NcmpiDim& rhs);
+
+ private:
+
+ bool nullObject;
+
+ int myId;
+
+ int groupId;
+
+ };
+
+}
+
+
+#endif
+
diff --git a/src/libcxx/ncmpiDouble.cpp b/src/libcxx/ncmpiDouble.cpp
new file mode 100644
index 0000000..94cd401
--- /dev/null
+++ b/src/libcxx/ncmpiDouble.cpp
@@ -0,0 +1,22 @@
+#include "ncmpiDouble.h"
+#include <pnetcdf.h>
+using namespace PnetCDF;
+
+// create an instance of NcmpiDouble called PnetCDF::ncmpiDouble
+namespace PnetCDF {
+ NcmpiDouble ncmpiDouble;
+}
+
+// constructor
+NcmpiDouble::NcmpiDouble() : NcmpiType(NC_DOUBLE){
+}
+
+NcmpiDouble::~NcmpiDouble() {
+}
+
+
+// equivalence operator
+bool NcmpiDouble::operator==(const NcmpiDouble & rhs) {
+ // simply check the netCDF id.
+ return myId == rhs.myId;
+}
diff --git a/src/libcxx/ncmpiDouble.h b/src/libcxx/ncmpiDouble.h
new file mode 100644
index 0000000..73dcc32
--- /dev/null
+++ b/src/libcxx/ncmpiDouble.h
@@ -0,0 +1,28 @@
+#include "ncmpiType.h"
+
+#ifndef NcmpiDoubleClass
+#define NcmpiDoubleClass
+
+namespace PnetCDF
+{
+
+ /*! Class represents a netCDF atomic Double type. */
+ class NcmpiDouble : public NcmpiType
+ {
+ public:
+
+ /*! equivalence operator */
+ bool operator==(const NcmpiDouble & rhs);
+
+ /*! destructor */
+ ~NcmpiDouble();
+
+ /*! Constructor */
+ NcmpiDouble();
+ };
+
+ /*! A global instance of the NcmpiDouble class within the netCDF namespace. */
+ extern NcmpiDouble ncmpiDouble;
+
+}
+#endif
diff --git a/src/libcxx/ncmpiEnumType.cpp b/src/libcxx/ncmpiEnumType.cpp
new file mode 100644
index 0000000..e0223ba
--- /dev/null
+++ b/src/libcxx/ncmpiEnumType.cpp
@@ -0,0 +1,111 @@
+#include "ncmpiEnumType.h"
+#include "ncmpiGroup.h"
+#include "ncmpiCheck.h"
+#include "ncmpiByte.h"
+#include "ncmpiUbyte.h"
+#include "ncmpiChar.h"
+#include "ncmpiShort.h"
+#include "ncmpiUshort.h"
+#include "ncmpiInt.h"
+#include "ncmpiUint.h"
+#include "ncmpiInt64.h"
+#include "ncmpiUint64.h"
+#include "ncmpiFloat.h"
+#include "ncmpiDouble.h"
+#include "ncmpiException.h"
+
+using namespace std;
+using namespace PnetCDF;
+using namespace PnetCDF::exceptions;
+
+// Class represents a netCDF variable.
+
+// assignment operator
+NcmpiEnumType& NcmpiEnumType::operator=(const NcmpiEnumType& rhs)
+{
+ NcmpiType::operator=(rhs); // assign base class parts
+ return *this;
+}
+
+// assignment operator
+NcmpiEnumType& NcmpiEnumType::operator=(const NcmpiType& rhs)
+{
+ if (&rhs != this) {
+ // check the rhs is the base of an Enum type
+ if(getTypeClass() != NC_ENUM) throw NcmpiException("The NcmpiType object must be the base of an Enum type.",__FILE__,__LINE__);
+ // assign base class parts
+ NcmpiType::operator=(rhs);
+ }
+ return *this;
+}
+
+// The copy constructor.
+NcmpiEnumType::NcmpiEnumType(const NcmpiEnumType& rhs):
+ NcmpiType(rhs)
+{
+}
+
+
+// Constructor generates a null object.
+NcmpiEnumType::NcmpiEnumType() :
+ NcmpiType() // invoke base class constructor
+{}
+
+// constructor
+NcmpiEnumType::NcmpiEnumType(const NcmpiGroup& grp, const string& name):
+ NcmpiType(grp,name)
+{}
+
+
+// constructor
+NcmpiEnumType::NcmpiEnumType(const NcmpiType& ncmpiType):
+ NcmpiType(ncmpiType)
+{
+ // check the nctype object is the base of an Enum type
+ if(getTypeClass() != NC_ENUM) throw NcmpiException("The NcmpiType object must be the base of an Enum type.",__FILE__,__LINE__);
+}
+
+// Returns the base type.
+NcmpiType NcmpiEnumType::getBaseType() const
+{
+ char charName[NC_MAX_NAME+1];
+ nc_type base_nc_typep;
+ MPI_Offset *base_sizep=NULL;
+ MPI_Offset *num_membersp=NULL;
+ ncmpiCheck(ncmpi_inq_enum(groupId,myId,charName,&base_nc_typep,base_sizep,num_membersp),__FILE__,__LINE__);
+ switch (base_nc_typep) {
+ case NC_BYTE : return ncmpiByte;
+ case NC_UBYTE : return ncmpiUbyte;
+ case NC_CHAR : return ncmpiChar;
+ case NC_SHORT : return ncmpiShort;
+ case NC_USHORT : return ncmpiUshort;
+ case NC_INT : return ncmpiInt;
+ case NC_UINT : return ncmpiUint;
+ case NC_INT64 : return ncmpiInt64;
+ case NC_UINT64 : return ncmpiUint64;
+ case NC_FLOAT : return ncmpiFloat;
+ case NC_DOUBLE : return ncmpiDouble;
+ default:
+ // this is a user defined type
+ return NcmpiType(getParentGroup(),base_nc_typep);
+ }
+}
+
+
+// Returns number of members in this NcmpiEnumType object.
+MPI_Offset NcmpiEnumType::getMemberCount() const{
+ char charName[NC_MAX_NAME+1];
+ nc_type* base_nc_typep=NULL;
+ MPI_Offset* base_sizep=NULL;
+ MPI_Offset num_membersp;
+ ncmpiCheck(ncmpi_inq_enum(groupId,myId,charName,base_nc_typep,base_sizep,&num_membersp),__FILE__,__LINE__);
+ return num_membersp;
+};
+
+// Returns the member name for the given zero-based index.
+string NcmpiEnumType::getMemberNameFromIndex(int index) const{
+ void* value=NULL;
+ char charName[NC_MAX_NAME+1];
+ ncmpiCheck(ncmpi_inq_enum_member(groupId,myId,index,charName,value),__FILE__,__LINE__);
+ return static_cast<string> (charName);
+};
diff --git a/src/libcxx/ncmpiEnumType.h b/src/libcxx/ncmpiEnumType.h
new file mode 100644
index 0000000..d2d6bd6
--- /dev/null
+++ b/src/libcxx/ncmpiEnumType.h
@@ -0,0 +1,109 @@
+#include <string>
+#include "ncmpiType.h"
+#include "ncmpiCheck.h"
+
+#include <pnetcdf.h>
+#include "ncmpi_notyet.h"
+
+#ifndef NcmpiEnumTypeClass
+#define NcmpiEnumTypeClass
+
+
+namespace PnetCDF
+{
+ class NcmpiGroup; // forward declaration.
+
+ /*! Class represents a netCDF enum type */
+ class NcmpiEnumType : public NcmpiType
+ {
+ public:
+
+ /*! List of NetCDF-4 Enumeration types.*/
+ enum ncmpiEnumType {
+ ncmpi_BYTE = NC_BYTE, //!< signed 1 byte integer
+ ncmpi_SHORT = NC_SHORT, //!< signed 2 byte integer
+ ncmpi_INT = NC_INT, //!< signed 4 byte integer
+ ncmpi_UBYTE = NC_UBYTE, //!< unsigned 1 byte int
+ ncmpi_USHORT = NC_USHORT, //!< unsigned 2-byte int
+ ncmpi_UINT = NC_UINT, //!< unsigned 4-byte int
+ ncmpi_INT64 = NC_INT64, //!< signed 8-byte int
+ ncmpi_UINT64 = NC_UINT64 //!< unsigned 8-byte int
+ };
+
+ /*! Constructor generates a \ref isNull "null object". */
+ NcmpiEnumType();
+
+ /*!
+ Constructor.
+ The enum Type must already exist in the netCDF file. New netCDF enum types can
+ be added using NcmpiGroup::addNcmpiEnumType();
+ \param grp The parent group where this type is defined.
+ \param name Name of new type.
+ */
+ NcmpiEnumType(const NcmpiGroup& grp, const std::string& name);
+
+ /*!
+ Constructor.
+ Constructs from the base type NcmpiType object. Will throw an exception if the NcmpiType is not the base of an Enum type.
+ \param ncmpiType A Nctype object.
+ */
+ NcmpiEnumType(const NcmpiType& ncmpiType);
+
+ /*! assignment operator */
+ NcmpiEnumType& operator=(const NcmpiEnumType& rhs);
+
+ /*!
+ Assignment operator.
+ This assigns from the base type NcmpiType object. Will throw an exception if the NcmpiType is not the base of an Enum type.
+ */
+ NcmpiEnumType& operator=(const NcmpiType& rhs);
+
+ /*! The copy constructor. */
+ NcmpiEnumType(const NcmpiEnumType& rhs);
+
+ /*! Destructor */
+ ~NcmpiEnumType(){}
+
+
+ /*!
+ Adds a new member to this NcmpiEnumType type.
+ \param name Name for this new Enum memebr.
+ \param memberValue Member value, must be of the correct NcmpiType.
+ */
+ template <class T> void addMember(const std::string& name, T memberValue)
+ {
+ ncmpiCheck(ncmpi_insert_enum(groupId, myId, name.c_str(), (void*) &memberValue),__FILE__,__LINE__);
+ }
+
+ /*! Returns number of members in this NcmpiEnumType object. */
+ MPI_Offset getMemberCount() const;
+
+ /*! Returns the member name for the given zero-based index. */
+ std::string getMemberNameFromIndex(int index) const;
+
+ /*! Returns the member name for the given NcmpiEnumType value. */
+ template <class T> std::string getMemberNameFromValue(const T memberValue) const {
+ char charName[NC_MAX_NAME+1];
+ ncmpiCheck(ncmpi_inq_enum_ident(groupId,myId,static_cast<long long>(memberValue),charName),__FILE__,__LINE__);
+ return std::string(charName);
+ }
+
+ /*!
+ Returns the value of a member with the given zero-based index.
+ \param name Name for this new Enum member.
+ \param memberValue Member value, returned by this routine.
+ */
+ template <class T> void getMemberValue(int index, T& memberValue) const
+ {
+ char* charName=NULL;
+ ncmpiCheck(ncmpi_inq_enum_member(groupId,myId,index,charName,&memberValue),__FILE__,__LINE__);
+ }
+
+ /*! Returns the base type. */
+ NcmpiType getBaseType() const;
+
+ };
+
+}
+
+#endif
diff --git a/src/libcxx/ncmpiException.cpp b/src/libcxx/ncmpiException.cpp
new file mode 100644
index 0000000..ac8785a
--- /dev/null
+++ b/src/libcxx/ncmpiException.cpp
@@ -0,0 +1,308 @@
+#include "ncmpiException.h"
+#include <sstream>
+#include <pnetcdf.h>
+using namespace std;
+using namespace PnetCDF;
+using namespace PnetCDF::exceptions;
+
+
+// Default object thrown if a netCDF exception is encountered.
+/*NcmpiException::NcmpiException(const string& complaint,const char* fileName,int lineNumber)
+ : what_msg(NULL)
+ , ec(0)
+{
+ try{
+ std::ostringstream oss;
+ oss << lineNumber;
+ what_msg = new std::string(complaint+"\nfile: "+fileName+" line:"+oss.str());
+ }catch(...){
+ what_msg = NULL;
+ }
+}*/
+
+NcmpiException::NcmpiException(const char* complaint,const char* fileName,int lineNumber)
+ : what_msg(NULL)
+ , ec(0)
+{
+ try{
+ std::ostringstream oss;
+ oss << lineNumber;
+ what_msg = new std::string(complaint?complaint:"");
+ what_msg->append("\nfile: ");
+ what_msg->append(fileName);
+ what_msg->append(" line:");
+ what_msg->append(oss.str());
+ }catch(...){
+ what_msg = NULL;
+ }
+}
+
+NcmpiException::NcmpiException(int errorCode, const char* complaint,const char* fileName,int lineNumber)
+ : what_msg(NULL)
+ , ec(errorCode)
+{
+ try{
+ std::ostringstream oss;
+ oss << lineNumber;
+ what_msg = new std::string(complaint?complaint:"");
+ what_msg->append("\nfile: ");
+ what_msg->append(fileName);
+ what_msg->append(" line:");
+ what_msg->append(oss.str());
+ }catch(...){
+ what_msg = NULL;
+ }
+}
+
+NcmpiException::NcmpiException(const NcmpiException& e) throw()
+ : what_msg(NULL)
+ , ec(e.ec)
+{
+ try{
+ what_msg = new std::string(*(e.what_msg));
+ }catch(...){
+ what_msg = NULL;
+ }
+}
+
+NcmpiException& NcmpiException::operator=(const NcmpiException& e) throw(){
+ if (this != &e){
+ ec = e.ec;
+ delete what_msg;
+ try{
+ what_msg = new std::string(*(e.what_msg));
+ }catch(...){
+ what_msg = NULL;
+ }
+ }
+ return *this;
+}
+
+NcmpiException::~NcmpiException()throw() {
+ delete what_msg;
+}
+
+
+const char* NcmpiException::what() const throw()
+{
+ return what_msg==NULL ? "" : what_msg->c_str();
+}
+
+int NcmpiException::errorCode() const throw() {
+ return ec;
+}
+
+
+// Thrown if the specified netCDF ID does not refer to an open netCDF dataset.
+NcBadId::NcBadId(const char* complaint,const char* file,int line) :
+ NcmpiException(NC_EBADID,complaint,file,line) { }
+
+
+// Thrown if too many netcdf files are open.
+NcNFile::NcNFile(const char* complaint,const char* file,int line) :
+ NcmpiException(NC_ENFILE,complaint,file,line) { }
+
+// Thrown if, having set NC_NOCLOBBER, the specified dataset already exists.
+NcExist::NcExist(const char* complaint,const char* file,int line) :
+ NcmpiException(NC_EEXIST,complaint,file,line) { }
+
+// Thrown if not a netCDF id.
+NcInvalidArg::NcInvalidArg(const char* complaint,const char* file,int line) :
+ NcmpiException(NC_EINVAL,complaint,file,line) { }
+
+// Thrown if invalid argument.
+NcInvalidWrite::NcInvalidWrite(const char* complaint,const char* file,int line) :
+ NcmpiException(NC_EPERM,complaint,file,line) { }
+
+// Thrown if operation not allowed in data mode.
+NcNotInDefineMode::NcNotInDefineMode(const char* complaint,const char* file,int line) :
+ NcmpiException(NC_ENOTINDEFINE,complaint,file,line) { }
+
+// Thrown if operation not allowed in defined mode.
+NcInDefineMode::NcInDefineMode(const char* complaint,const char* file,int line) :
+ NcmpiException(NC_EINDEFINE,complaint,file,line) { }
+
+// Index exceeds dimension bound
+NcInvalidCoords::NcInvalidCoords(const char* complaint,const char* file,int line) :
+ NcmpiException(NC_EINVALCOORDS,complaint,file,line) { }
+
+// Thrown if NC_MAX_DIMS is exceeded.
+NcMaxDims::NcMaxDims(const char* complaint,const char* file,int line) :
+ NcmpiException(NC_EMAXDIMS,complaint,file,line) { }
+
+// Thrown if string match to name is in use.
+NcNameInUse::NcNameInUse(const char* complaint,const char* file,int line) :
+ NcmpiException(NC_ENAMEINUSE,complaint,file,line) { }
+
+// Thrown if attribute is not found.
+NcNotAtt::NcNotAtt(const char* complaint,const char* file,int line) :
+ NcmpiException(NC_ENOTATT,complaint,file,line) { }
+
+// Thrown if Nc_MAX_ATTRS is exceeded.
+NcMaxAtts::NcMaxAtts(const char* complaint,const char* file,int line) :
+ NcmpiException(NC_EMAXATTS,complaint,file,line) { }
+
+// Thrown if not a valid netCDF data type.
+NcBadType::NcBadType(const char* complaint,const char* file,int line) :
+ NcmpiException(NC_EBADTYPE,complaint,file,line) { }
+
+// Thrown if an invalid dimension id or name.
+NcBadDim::NcBadDim(const char* complaint,const char* file,int line) :
+ NcmpiException(NC_EBADDIM,complaint,file,line) { }
+
+// Thrown if Nc_UNLIMITED is in the wrong index.
+NcUnlimPos::NcUnlimPos(const char* complaint,const char* file,int line) :
+ NcmpiException(NC_EUNLIMPOS,complaint,file,line) { }
+
+// Thrown if NC_MAX_VARS is exceeded.
+NcMaxVars::NcMaxVars(const char* complaint,const char* file,int line) :
+ NcmpiException(NC_EMAXVARS,complaint,file,line) { }
+
+// Thrown if variable is not found.
+NcNotVar::NcNotVar(const char* complaint,const char* file,int line) :
+ NcmpiException(NC_ENOTVAR,complaint,file,line) { }
+
+// Thrown if the action is prohibited on the NC_GLOBAL varid.
+NcGlobal::NcGlobal(const char* complaint,const char* file,int line) :
+ NcmpiException(NC_EGLOBAL,complaint,file,line) { }
+
+// Thrown if not a netCDF file.
+NcNotNCF::NcNotNCF(const char* complaint,const char* file,int line) :
+ NcmpiException(NC_ENOTNC,complaint,file,line) { }
+
+// Thrown if in FORTRAN, string is too short.
+NcSts::NcSts(const char* complaint,const char* file,int line) :
+ NcmpiException(NC_ESTS,complaint,file,line) { }
+
+// Thrown if NC_MAX_NAME is exceeded.
+NcMaxName::NcMaxName(const char* complaint,const char* file,int line) :
+ NcmpiException(NC_EMAXNAME,complaint,file,line) { }
+
+// Thrown if NC_UNLIMITED size is already in use.
+NcUnlimit::NcUnlimit(const char* complaint,const char* file,int line) :
+ NcmpiException(NC_EUNLIMIT,complaint,file,line) { }
+
+// Thrown if ncmpi_rec op when there are no record vars.
+NcNoRecVars::NcNoRecVars(const char* complaint,const char* file,int line) :
+ NcmpiException(NC_ENORECVARS,complaint,file,line) { }
+
+// Thrown if attempt to convert between text and numbers.
+NcmpiChar::NcmpiChar(const char* complaint,const char* file,int line) :
+ NcmpiException(NC_ECHAR,complaint,file,line) { }
+
+// Thrown if edge+start exceeds dimension bound.
+NcEdge::NcEdge(const char* complaint,const char* file,int line) :
+ NcmpiException(NC_EEDGE,complaint,file,line) { }
+
+// Thrown if illegal stride.
+NcStride::NcStride(const char* complaint,const char* file,int line) :
+ NcmpiException(NC_ESTRIDE,complaint,file,line) { }
+
+// Thrown if attribute or variable name contains illegal characters.
+NcBadName::NcBadName(const char* complaint,const char* file,int line) :
+ NcmpiException(NC_EBADNAME,complaint,file,line) { }
+
+// Thrown if math result not representable.
+NcRange::NcRange(const char* complaint,const char* file,int line) :
+ NcmpiException(NC_ERANGE,complaint,file,line) { }
+
+// Thrown if memory allocation (malloc) failure.
+NcNoMem::NcNoMem(const char* complaint,const char* file,int line) :
+ NcmpiException(NC_ENOMEM,complaint,file,line) { }
+
+// Thrown if one or more variable sizes violate format constraints
+NcmpiVarSize::NcmpiVarSize(const char* complaint,const char* file,int line) :
+ NcmpiException(NC_EVARSIZE,complaint,file,line) { }
+
+// Thrown if invalid dimension size.
+NcmpiDimSize::NcmpiDimSize(const char* complaint,const char* file,int line) :
+ NcmpiException(NC_EDIMSIZE,complaint,file,line) { }
+
+// Thrown if file likely truncated or possibly corrupted.
+NcTrunc::NcTrunc(const char* complaint,const char* file,int line) :
+ NcmpiException(NC_ETRUNC,complaint,file,line) { }
+
+// Thrown if an error was reported by the HDF5 layer.
+NcHdfErr::NcHdfErr(const char* complaint,const char* file,int line) :
+ NcmpiException(NC_EHDFERR,complaint,file,line) { }
+
+// Thrown if cannot read.
+NcCantRead::NcCantRead(const char* complaint,const char* file,int line) :
+ NcmpiException(NC_ECANTREAD,complaint,file,line) { }
+
+// Thrown if cannot write.
+NcCantWrite::NcCantWrite(const char* complaint,const char* file,int line) :
+ NcmpiException(NC_ECANTWRITE,complaint,file,line) { }
+
+// Thrown if cannot create.
+NcCantCreate::NcCantCreate(const char* complaint,const char* file,int line) :
+ NcmpiException(NC_ECANTCREATE,complaint,file,line) { }
+
+// Thrown if file meta.
+NcmpiFileMeta::NcmpiFileMeta(const char* complaint,const char* file,int line) :
+ NcmpiException(NC_EFILEMETA,complaint,file,line) { }
+
+// Thrown if dim meta.
+NcmpiDimMeta::NcmpiDimMeta(const char* complaint,const char* file,int line) :
+ NcmpiException(NC_EDIMMETA,complaint,file,line) { }
+
+// Thrown if attribute meta.
+NcmpiAttMeta::NcmpiAttMeta(const char* complaint,const char* file,int line) :
+ NcmpiException(NC_EATTMETA,complaint,file,line) { }
+
+// Thrown if variable meta.
+NcmpiVarMeta::NcmpiVarMeta(const char* complaint,const char* file,int line) :
+ NcmpiException(NC_EVARMETA,complaint,file,line) { }
+
+// Thrown if no compound.
+NcNoCompound::NcNoCompound(const char* complaint,const char* file,int line) :
+ NcmpiException(NC_ENOCOMPOUND,complaint,file,line) { }
+
+// Thrown if attribute exists.
+NcmpiAttExists::NcmpiAttExists(const char* complaint,const char* file,int line) :
+ NcmpiException(NC_EATTEXISTS,complaint,file,line) { }
+
+// Thrown if attempting netcdf-4 operation on netcdf-3 file.
+NcNotNc4::NcNotNc4(const char* complaint,const char* file,int line) :
+ NcmpiException(NC_ENOTNC4,complaint,file,line) { }
+
+// Thrown if attempting netcdf-4 operation on strict nc3 netcdf-4 file.
+NcStrictNc3::NcStrictNc3(const char* complaint,const char* file,int line) :
+ NcmpiException(NC_ESTRICTNC3,complaint,file,line) { }
+
+// Thrown if bad group id.
+NcBadGroupId::NcBadGroupId(const char* complaint,const char* file,int line) :
+ NcmpiException(NC_EBADGRPID,complaint,file,line) { }
+
+// Thrown if bad type id.
+NcBadTypeId::NcBadTypeId(const char* complaint,const char* file,int line) :
+ NcmpiException(NC_EBADTYPID,complaint,file,line) { }
+
+// Thrown if bad field id.
+NcBadFieldId::NcBadFieldId(const char* complaint,const char* file,int line) :
+ NcmpiException(NC_EBADFIELD,complaint,file,line) { }
+
+// Thrown if cannot find the field id.
+NcUnknownName::NcUnknownName(const char* complaint,const char* file,int line) :
+ NcmpiException(complaint,file,line) { }
+
+// Thrown if cannot find the field id.
+NcEnoGrp::NcEnoGrp(const char* complaint,const char* file,int line) :
+ NcmpiException(NC_ENOGRP,complaint,file,line) { }
+
+// Thrown if cannot find the field id.
+NcNullGrp::NcNullGrp(const char* complaint,const char* file,int line) :
+ NcmpiException(complaint,file,line) { }
+
+// Thrown if cannot find the field id.
+NcNullDim::NcNullDim(const char* complaint,const char* file,int line) :
+ NcmpiException(complaint,file,line) { }
+
+// Thrown if cannot find the field id.
+NcNullType::NcNullType(const char* complaint,const char* file,int line) :
+ NcmpiException(complaint,file,line) { }
+
+// Thrown if an operation to set the deflation, chunking, endianness, fill, compression, or checksum of a NcmpiVar object is issued after a call to NcmpiVar::getVar or NcmpiVar::putVar.
+NcElateDef::NcElateDef(const char* complaint,const char* file,int line) :
+ NcmpiException(NC_ELATEDEF,complaint,file,line) { }
+
diff --git a/src/libcxx/ncmpiException.h b/src/libcxx/ncmpiException.h
new file mode 100644
index 0000000..4bad82d
--- /dev/null
+++ b/src/libcxx/ncmpiException.h
@@ -0,0 +1,437 @@
+#include <exception>
+#include <string>
+#include <iostream>
+
+#ifndef NcmpiExceptionClasses
+#define NcmpiExceptionClasses
+
+namespace PnetCDF
+{
+
+ //! Exception classes.
+ /*!
+ These exceptions are thrown if the netCDF-4 API encounters an error.
+ */
+ namespace exceptions
+ {
+
+ /*!
+ Base object is thrown if a netCDF exception is encountered.
+ An unsatisfactory return from a call to one of the netCDF C-routines
+ generates an exception using an object inheriting this class. All other netCDF-related
+ errors including those originating in the C++ binding, generates an NcmpiException.
+ */
+ class NcmpiException : public std::exception {
+ public:
+ //NcmpiException(const string& complaint,const char* fileName,int lineNumber);
+ NcmpiException(const char* complaint,const char* fileName,int lineNumber);
+ NcmpiException(int errorCode, const char* complaint,const char* fileName,int lineNumber);
+ NcmpiException(const NcmpiException& e) throw();
+ NcmpiException& operator=(const NcmpiException& e) throw();
+ virtual ~NcmpiException() throw();
+ const char* what() const throw();
+ int errorCode() const throw();
+ private:
+ std::string* what_msg;
+ int ec;
+ };
+
+
+ /*! Thrown if the specified netCDF ID does not refer to an open netCDF dataset. */
+ class NcBadId : public NcmpiException
+ {
+ public:
+ NcBadId(const char* complaint,const char* file,int line);
+ };
+
+ /*! Thrown if too many netcdf files are open. */
+ class NcNFile : public NcmpiException
+ {
+ public:
+ NcNFile(const char* complaint,const char* file,int line);
+ };
+
+ /*! Thrown if, having set NC_NOCLOBBER, the specified dataset already exists. */
+ class NcExist : public NcmpiException
+ {
+ public:
+ NcExist(const char* complaint,const char* file,int line);
+ };
+
+ /*! Thrown if not a netCDF id. */
+ class NcInvalidArg : public NcmpiException
+ {
+ public:
+ NcInvalidArg(const char* complaint,const char* file,int line);
+ };
+
+ /*! Thrown if invalid argument. */
+ class NcInvalidWrite : public NcmpiException
+ {
+ public:
+ NcInvalidWrite(const char* complaint,const char* file,int line);
+ };
+
+ /*! Thrown if operation not allowed in data mode. */
+ class NcNotInDefineMode : public NcmpiException
+ {
+ public:
+ NcNotInDefineMode(const char* complaint,const char* file,int line);
+ };
+
+ /*! Thrown if operation not allowed in defined mode. */
+ class NcInDefineMode : public NcmpiException
+ {
+ public:
+ NcInDefineMode(const char* complaint,const char* file,int line);
+ };
+
+ /*!
+ Index exceeds dimension bound.
+ Exception may be generated during operations to get or put netCDF variable data.
+ The exception is thrown if the specified indices were out of range for the rank of the
+ specified variable. For example, a negative index or an index that is larger than
+ the corresponding dimension length will cause an error.
+ */
+ class NcInvalidCoords : public NcmpiException
+ {
+ public:
+ NcInvalidCoords(const char* complaint,const char* file,int line);
+ };
+
+ /*! Thrown if NC_MAX_DIMS is exceeded. */
+ class NcMaxDims : public NcmpiException
+ {
+ public:
+ NcMaxDims(const char* complaint,const char* file,int line);
+ };
+
+ /*! Thrown if string match to name is in use. */
+ class NcNameInUse : public NcmpiException
+ {
+ public:
+ NcNameInUse(const char* complaint,const char* file,int line);
+ };
+
+ /*! Thrown if attribute is not found. */
+ class NcNotAtt : public NcmpiException
+ {
+ public:
+ NcNotAtt(const char* complaint,const char* file,int line);
+ };
+
+ /*! Thrown if Nc_MAX_ATTRS is exceeded. */
+ class NcMaxAtts : public NcmpiException
+ {
+ public:
+ NcMaxAtts(const char* complaint,const char* file,int line);
+ };
+
+ /*! Thrown if not a valid netCDF data type. */
+ class NcBadType : public NcmpiException
+ {
+ public:
+ NcBadType(const char* complaint,const char* file,int line);
+ };
+
+ /*! Thrown if an invalid dimension id or name. */
+ class NcBadDim : public NcmpiException
+ {
+ public:
+ NcBadDim(const char* complaint,const char* file,int line);
+ };
+
+ /*! Thrown if Nc_UNLIMITED is in the wrong index. */
+ class NcUnlimPos : public NcmpiException
+ {
+ public:
+ NcUnlimPos(const char* complaint,const char* file,int line);
+ };
+
+ /*! Thrown if NC_MAX_VARS is exceeded. */
+ class NcMaxVars : public NcmpiException
+ {
+ public:
+ NcMaxVars(const char* complaint,const char* file,int line);
+ };
+
+ /*! Thrown if variable is not found. */
+ class NcNotVar : public NcmpiException
+ {
+ public:
+ NcNotVar(const char* complaint,const char* file,int line);
+ };
+
+ /*! Thrown if the action is prohibited on the NC_GLOBAL varid. */
+ class NcGlobal : public NcmpiException
+ {
+ public:
+ NcGlobal(const char* complaint,const char* file,int line);
+ };
+
+ /*! Thrown if not a netCDF file. */
+ class NcNotNCF : public NcmpiException
+ {
+ public:
+ NcNotNCF(const char* complaint,const char* file,int line);
+ };
+
+ /*! Thrown if in FORTRAN, string is too short. */
+ class NcSts : public NcmpiException
+ {
+ public:
+ NcSts(const char* complaint,const char* file,int line);
+ };
+
+ /*! Thrown if NC_MAX_NAME is exceeded. */
+ class NcMaxName : public NcmpiException
+ {
+ public:
+ NcMaxName(const char* complaint,const char* file,int line);
+ };
+
+ /*! Thrown if NC_UNLIMITED size is already in use. */
+ class NcUnlimit : public NcmpiException
+ {
+ public:
+ NcUnlimit(const char* complaint,const char* file,int line);
+ };
+
+ /*! Thrown if ncmpi_rec op when there are no record vars. */
+ class NcNoRecVars : public NcmpiException
+ {
+ public:
+ NcNoRecVars(const char* complaint,const char* file,int line);
+ };
+
+ /*! Thrown if attempt to convert between text and numbers. */
+ class NcmpiChar : public NcmpiException
+ {
+ public:
+ NcmpiChar(const char* complaint,const char* file,int line);
+ };
+
+ /*! Thrown if edge+start exceeds dimension bound. */
+ class NcEdge : public NcmpiException
+ {
+ public:
+ NcEdge(const char* complaint,const char* file,int line);
+ };
+
+ /*! Thrown if illegal stride. */
+ class NcStride : public NcmpiException
+ {
+ public:
+ NcStride(const char* complaint,const char* file,int line);
+ };
+
+ /*! Thrown if attribute or variable name contains illegal characters. */
+ class NcBadName : public NcmpiException
+ {
+ public:
+ NcBadName(const char* complaint,const char* file,int line);
+ };
+
+ /*! Thrown if math result not representable. */
+ class NcRange : public NcmpiException
+ {
+ public:
+ NcRange(const char* complaint,const char* file,int line);
+ };
+
+ /*! Thrown if memory allocation (malloc) failure. */
+ class NcNoMem : public NcmpiException
+ {
+ public:
+ NcNoMem(const char* complaint,const char* file,int line);
+ };
+
+ /*! Thrown if one or more variable sizes violate format constraints */
+ class NcmpiVarSize : public NcmpiException
+ {
+ public:
+ NcmpiVarSize(const char* complaint,const char* file,int line);
+ };
+
+ /*! Thrown if invalid dimension size. */
+ class NcmpiDimSize : public NcmpiException
+ {
+ public:
+ NcmpiDimSize(const char* complaint,const char* file,int line);
+ };
+
+ /*! Thrown if file likely truncated or possibly corrupted. */
+ class NcTrunc : public NcmpiException
+ {
+ public:
+ NcTrunc(const char* complaint,const char* file,int line);
+ };
+
+ /*! Thrown if an error was reported by the HDF5 layer. */
+ class NcHdfErr : public NcmpiException
+ {
+ public:
+ NcHdfErr(const char* complaint,const char* file,int line);
+ };
+
+ /*! Thrown if cannot read. */
+ class NcCantRead : public NcmpiException
+ {
+ public:
+ NcCantRead(const char* complaint,const char* file,int line);
+ };
+
+ /*! Thrown if cannot write. */
+ class NcCantWrite : public NcmpiException
+ {
+ public:
+ NcCantWrite(const char* complaint,const char* file,int line);
+ };
+
+ /*! Thrown if cannot create. */
+ class NcCantCreate : public NcmpiException
+ {
+ public:
+ NcCantCreate(const char* complaint,const char* file,int line);
+ };
+
+ /*! Thrown if file meta. */
+ class NcmpiFileMeta : public NcmpiException
+ {
+ public:
+ NcmpiFileMeta(const char* complaint,const char* file,int line);
+ };
+
+ /*! Thrown if dim meta. */
+ class NcmpiDimMeta : public NcmpiException
+ {
+ public:
+ NcmpiDimMeta(const char* complaint,const char* file,int line);
+ };
+
+ /*! Thrown if attribute meta. */
+ class NcmpiAttMeta : public NcmpiException
+ {
+ public:
+ NcmpiAttMeta(const char* complaint,const char* file,int line);
+ };
+
+ /*! Thrown if variable meta. */
+ class NcmpiVarMeta : public NcmpiException
+ {
+ public:
+ NcmpiVarMeta(const char* complaint,const char* file,int line);
+ };
+
+ /*! Thrown if no compound. */
+ class NcNoCompound : public NcmpiException
+ {
+ public:
+ NcNoCompound(const char* complaint,const char* file,int line);
+ };
+
+ /*! Thrown if attribute exists. */
+ class NcmpiAttExists : public NcmpiException
+ {
+ public:
+ NcmpiAttExists(const char* complaint,const char* file,int line);
+ };
+
+ /*! Thrown if attempting netcdf-4 operation on netcdf-3 file. */
+ class NcNotNc4 : public NcmpiException
+ {
+ public:
+ NcNotNc4(const char* complaint,const char* file,int line);
+ };
+
+ /*! Thrown if attempting netcdf-4 operation on strict nc3 netcdf-4 file. */
+ class NcStrictNc3 : public NcmpiException
+ {
+ public:
+ NcStrictNc3(const char* complaint,const char* file,int line);
+ };
+
+ /*! Thrown if bad group id. */
+ class NcBadGroupId : public NcmpiException
+ {
+ public:
+ NcBadGroupId(const char* complaint,const char* file,int line);
+ };
+
+ /*! Thrown if bad type id. */
+ class NcBadTypeId : public NcmpiException
+ {
+ public:
+ NcBadTypeId(const char* complaint,const char* file,int line);
+ };
+
+ /*! Thrown if bad field id. */
+ class NcBadFieldId : public NcmpiException
+ {
+ public:
+ NcBadFieldId(const char* complaint,const char* file,int line);
+ };
+
+ /*! Thrown if cannot find the field id. */
+ class NcUnknownName : public NcmpiException
+ {
+ public:
+ NcUnknownName(const char* complaint,const char* file,int line);
+ };
+
+ /*! Thrown if cannot return a netCDF group. */
+ class NcEnoGrp : public NcmpiException
+ {
+ public:
+ NcEnoGrp(const char* complaint,const char* file,int line);
+ };
+
+ /*!
+ Thrown if the requested operation is on a NULL group.
+
+ This exception is thrown if an operation on a NcmpiGroup object is requested which is empty. To test if the object is empty used NcmpiGroup::isNull()
+ */
+ class NcNullGrp : public NcmpiException
+ {
+ public:
+ NcNullGrp(const char* complaint,const char* file,int line);
+ };
+
+ /*!
+ Thrown if the requested operation is on a NULL type.
+
+ This exception is thrown if an operation on a NcmpiType object is requested which is empty. To test if the object is empty used NcmpiType::isNull()
+ */
+ class NcNullType : public NcmpiException
+ {
+ public:
+ NcNullType(const char* complaint,const char* file,int line);
+ };
+
+ /*!
+ Thrown if the requested operation is on a NULL dimension.
+
+ This exception is thrown if an operation on a NcmpiDim object is requested which is empty. To test if the object is empty used NcmpiDim::isNull()
+ */
+ class NcNullDim : public NcmpiException
+ {
+ public:
+ NcNullDim(const char* complaint,const char* file,int line);
+ };
+
+ /*!
+ Thrown if an operation to set the chunking, endianness, fill of a NcmpiVar object is issued after a
+ call to NcmpiVar::getVar or NcmpiVar::putVar has been made.
+ */
+ class NcElateDef : public NcmpiException
+ {
+ public:
+ NcElateDef(const char* complaint,const char* file,int line);
+ };
+
+ }
+
+}
+
+#endif
+
diff --git a/src/libcxx/ncmpiFile.cpp b/src/libcxx/ncmpiFile.cpp
new file mode 100644
index 0000000..fb018a7
--- /dev/null
+++ b/src/libcxx/ncmpiFile.cpp
@@ -0,0 +1,205 @@
+#include "ncmpiFile.h"
+#include "ncmpiCheck.h"
+#include "ncmpiException.h"
+#include "ncmpiByte.h"
+#include<iostream>
+#include<string>
+#include<sstream>
+using namespace std;
+using namespace PnetCDF;
+using namespace PnetCDF::exceptions;
+
+// destructor
+NcmpiFile::~NcmpiFile()
+{
+ // destructor may be called due to an exception being thrown
+ // hence throwing an exception from within a destructor
+ // causes undefined behaviour! so just printing a warning message
+ try
+ {
+ if (!nullObject)
+ ncmpiCheck(ncmpi_close(myId),__FILE__,__LINE__);
+ }
+ catch (NcmpiException &e)
+ {
+ cerr << e.what() << endl;
+ }
+}
+
+// Constructor generates a null object.
+NcmpiFile::NcmpiFile() :
+ NcmpiGroup() // invoke base class constructor
+{}
+
+// constructor
+NcmpiFile::NcmpiFile(const MPI_Comm &comm,
+ const string &filePath,
+ const FileMode fMode,
+ const MPI_Info &info /* = MPI_INFO_NULL */ )
+{
+ switch (fMode)
+ {
+ case NcmpiFile::write:
+ ncmpiCheck(ncmpi_open(comm, filePath.c_str(), NC_WRITE, info, &myId),__FILE__,__LINE__);
+ break;
+ case NcmpiFile::read:
+ ncmpiCheck(ncmpi_open(comm, filePath.c_str(), NC_NOWRITE, info, &myId),__FILE__,__LINE__);
+ break;
+ case NcmpiFile::newFile:
+ ncmpiCheck(ncmpi_create(comm, filePath.c_str(), NC_NOCLOBBER, info, &myId),__FILE__,__LINE__);
+ break;
+ case NcmpiFile::replace:
+ ncmpiCheck(ncmpi_create(comm, filePath.c_str(), NC_CLOBBER, info, &myId),__FILE__,__LINE__);
+ break;
+ }
+ nullObject=false;
+}
+
+// constructor with file type specified
+NcmpiFile::NcmpiFile(const MPI_Comm &comm,
+ const string &filePath,
+ const FileMode fMode,
+ const FileFormat fFormat,
+ const MPI_Info &info /* = MPI_INFO_NULL */)
+{
+ int format=0;
+ switch (fFormat)
+ {
+ case NcmpiFile::classic:
+ format = 0;
+ break;
+ case NcmpiFile::classic2:
+ format = NC_64BIT_OFFSET;
+ break;
+ case NcmpiFile::nc4:
+ format = NC_NETCDF4;
+ break;
+ case NcmpiFile::nc4classic:
+ format = NC_NETCDF4 | NC_CLASSIC_MODEL;
+ break;
+ case NcmpiFile::classic5:
+ format = NC_64BIT_DATA;
+ break;
+ case NcmpiFile::BadFormat:
+ throw NcNotNCF("NetCDF: Unknown file format",__FILE__,__LINE__);
+ }
+ switch (fMode)
+ {
+ case NcmpiFile::write:
+ ncmpiCheck(ncmpi_open(comm, filePath.c_str(), format | NC_WRITE, info, &myId),__FILE__,__LINE__);
+ break;
+ case NcmpiFile::read:
+ ncmpiCheck(ncmpi_open(comm, filePath.c_str(), format | NC_NOWRITE, info, &myId),__FILE__,__LINE__);
+ break;
+ case NcmpiFile::newFile:
+ ncmpiCheck(ncmpi_create(comm, filePath.c_str(), format | NC_NOCLOBBER, info, &myId),__FILE__,__LINE__);
+ break;
+ case NcmpiFile::replace:
+ ncmpiCheck(ncmpi_create(comm, filePath.c_str(), format | NC_CLOBBER, info, &myId),__FILE__,__LINE__);
+ break;
+ }
+ nullObject=false;
+}
+
+// Synchronize an open netcdf dataset to disk
+void NcmpiFile::sync(){
+ ncmpiCheck(ncmpi_sync(myId),__FILE__,__LINE__);
+}
+
+// Leave define mode, used for classic model
+void NcmpiFile::enddef() {
+ ncmpiCheck(ncmpi_enddef(myId),__FILE__,__LINE__);
+}
+
+NcmpiFile::FileFormat NcmpiFile::getFormat( void ) const
+{
+ int the_format;
+ ncmpiCheck(ncmpi_inq_format(myId, &the_format),__FILE__,__LINE__);
+
+ switch (the_format) {
+ case NC_FORMAT_CLASSIC:
+ return classic;
+ case NC_FORMAT_CDF2:
+ return classic2;
+ case NC_FORMAT_NETCDF4:
+ return nc4;
+ case NC_FORMAT_NETCDF4_CLASSIC:
+ return nc4classic;
+ case NC_FORMAT_CDF5:
+ return classic5;
+ default:
+ return BadFormat;
+ }
+}
+
+void NcmpiFile::Wait_all(int num,
+ int *array_of_requests,
+ int *array_of_statuses)
+{
+ ncmpiCheck(ncmpi_wait_all(myId, num, array_of_requests, array_of_statuses),__FILE__,__LINE__);
+}
+
+void NcmpiFile::Wait(int num,
+ int *array_of_requests,
+ int *array_of_statuses)
+{
+ ncmpiCheck(ncmpi_wait(myId, num, array_of_requests, array_of_statuses),__FILE__,__LINE__);
+}
+
+void NcmpiFile::Cancel(int num,
+ int *array_of_requests,
+ int *array_of_statuses)
+{
+ ncmpiCheck(ncmpi_cancel(myId, num, array_of_requests, array_of_statuses),__FILE__,__LINE__);
+}
+
+void NcmpiFile::Buffer_attach(MPI_Offset bufsize)
+{
+ ncmpiCheck(ncmpi_buffer_attach(myId, bufsize),__FILE__,__LINE__);
+}
+
+void NcmpiFile::Buffer_detach(void)
+{
+ ncmpiCheck(ncmpi_buffer_detach(myId),__FILE__,__LINE__);
+}
+
+void NcmpiFile::Inq_buffer_usage(MPI_Offset *usage)
+{
+ ncmpiCheck(ncmpi_inq_buffer_usage(myId, usage),__FILE__,__LINE__);
+}
+
+void NcmpiFile::Inq_buffer_size(MPI_Offset *buf_size)
+{
+ ncmpiCheck(ncmpi_inq_buffer_size(myId, buf_size),__FILE__,__LINE__);
+}
+
+void NcmpiFile::Inq_nreqs(int *nreqs)
+{
+ ncmpiCheck(ncmpi_inq_nreqs(myId, nreqs),__FILE__,__LINE__);
+}
+
+void NcmpiFile::Inq_file_info(MPI_Info *info)
+{
+ ncmpiCheck(ncmpi_inq_file_info(myId, info),__FILE__,__LINE__);
+}
+
+void NcmpiFile::Inq_put_size(MPI_Offset *put_size)
+{
+ ncmpiCheck(ncmpi_inq_put_size(myId, put_size),__FILE__,__LINE__);
+}
+
+void NcmpiFile::Inq_get_size(MPI_Offset *get_size)
+{
+ ncmpiCheck(ncmpi_inq_get_size(myId, get_size),__FILE__,__LINE__);
+}
+
+void NcmpiFile::Inq_header_size(MPI_Offset *header_size)
+{
+ ncmpiCheck(ncmpi_inq_header_size(myId, header_size),__FILE__,__LINE__);
+}
+
+void NcmpiFile::Inq_header_extent(MPI_Offset *header_extent)
+{
+ ncmpiCheck(ncmpi_inq_header_extent(myId, header_extent),__FILE__,__LINE__);
+}
+
diff --git a/src/libcxx/ncmpiFile.h b/src/libcxx/ncmpiFile.h
new file mode 100644
index 0000000..515286f
--- /dev/null
+++ b/src/libcxx/ncmpiFile.h
@@ -0,0 +1,125 @@
+#include <string>
+#include "ncmpiGroup.h"
+
+#ifndef NcmpiFileClass
+#define NcmpiFileClass
+
+//! C++ API for PnetCDF.
+namespace PnetCDF
+{
+
+ /*!
+ Class represents a netCDF root group.
+ The Ncfile class is the same as the NcmpiGroup class with the additional
+ functionality for opening and closing files.
+ */
+ class NcmpiFile : public NcmpiGroup
+ {
+ public:
+
+ enum FileMode
+ {
+ read, //!< File exists, open read-only.
+ write, //!< File exists, open for writing.
+ replace, //!< Create new file, even if already exists.
+ newFile //!< Create new file, fail if already exists.
+ };
+
+ enum FileFormat
+ {
+ classic, //!< Classic format, classic data model
+ classic2, //!< 64-bit offset format, classic data model
+ nc4, //!< (default) netCDF-4/HDF5 format, enhanced data model
+ nc4classic, //!< netCDF-4/HDF5 format, classic data model
+ classic5, //!< CDF-5 format, classic data model
+ BadFormat
+ };
+
+
+ /*! Constructor generates a \ref isNull "null object". */
+ NcmpiFile();
+
+ /*!
+ Creates/opens a netCDF file.
+ \param comm MPI intra-communicator
+ \param filePath Name of netCDF optional path.
+ \param fMode The file mode:
+ - 'read' File exists, open for read-only.
+ - 'write' File exists, open for writing.
+ - 'replace' Create new file, even it already exists.
+ - 'newFile' Create new file, fail it exists already.
+ \param info MPI info object containing MPI and PnetCDF IO hints
+ */
+ NcmpiFile(const MPI_Comm &comm,
+ const std::string &filePath,
+ FileMode fMode,
+ const MPI_Info &info = MPI_INFO_NULL);
+
+ /*!
+ Creates a netCDF file of a specified format.
+ \param comm MPI intra-communicator
+ \param filePath Name of netCDF optional path.
+ \param fMode The file mode:
+ - 'replace' Create new file, even it already exists.
+ - 'newFile' Create new file, fail it exists already.
+ \param info MPI info object containing MPI and PnetCDF IO hints
+ */
+ NcmpiFile(const MPI_Comm &comm,
+ const std::string &filePath,
+ FileMode fMode,
+ FileFormat fFormat,
+ const MPI_Info &info = MPI_INFO_NULL);
+
+ /*! destructor */
+ virtual ~NcmpiFile(); //closes file and releases all resources
+
+ //! Synchronize an open netcdf dataset to disk
+ void sync();
+
+ //! Leave define mode, used for classic model
+ void enddef();
+
+ FileFormat getFormat( void ) const;
+
+ void Wait_all(int num, int *array_of_requests, int *array_of_statuses);
+
+ void Wait(int num, int *array_of_requests, int *array_of_statuses);
+
+ void Cancel(int num, int *array_of_requests, int *array_of_statuses);
+
+ void Buffer_attach(MPI_Offset bufsize);
+
+ void Buffer_detach(void);
+
+ void Inq_nreqs(int *nreqs);
+
+ void Inq_buffer_usage(MPI_Offset *usage);
+
+ void Inq_buffer_size(MPI_Offset *buf_size);
+
+ void Inq_file_info(MPI_Info *info);
+
+ void Inq_put_size(MPI_Offset *put_size);
+
+ void Inq_get_size(MPI_Offset *get_size);
+
+ void Inq_header_size(MPI_Offset *header_size);
+
+ void Inq_header_extent(MPI_Offset *header_extent);
+
+ private:
+ /* Do not allow definition of NcmpiFile involving copying any NcmpiFile
+ or NcmpiGroup. Because the destructor closes the file and releases
+ al resources such an action could leave NcmpiFile objects in an
+ invalid state
+ */
+ NcmpiFile& operator =(const NcmpiGroup & rhs);
+ NcmpiFile& operator =(const NcmpiFile & rhs);
+ NcmpiFile(const NcmpiGroup& rhs);
+ NcmpiFile(const NcmpiFile& rhs);
+ };
+
+}
+
+#endif
+
diff --git a/src/libcxx/ncmpiFloat.cpp b/src/libcxx/ncmpiFloat.cpp
new file mode 100644
index 0000000..2fc1c95
--- /dev/null
+++ b/src/libcxx/ncmpiFloat.cpp
@@ -0,0 +1,22 @@
+#include "ncmpiFloat.h"
+#include <pnetcdf.h>
+using namespace PnetCDF;
+
+// create an instance of NcmpiFloat called PnetCDF::ncmpiFloat
+namespace PnetCDF {
+ NcmpiFloat ncmpiFloat;
+}
+
+// constructor
+NcmpiFloat::NcmpiFloat() : NcmpiType(NC_FLOAT){
+}
+
+NcmpiFloat::~NcmpiFloat() {
+}
+
+
+// equivalence operator
+bool NcmpiFloat::operator==(const NcmpiFloat & rhs) {
+ // simply check the netCDF id.
+ return myId == rhs.myId;
+}
diff --git a/src/libcxx/ncmpiFloat.h b/src/libcxx/ncmpiFloat.h
new file mode 100644
index 0000000..4ed7176
--- /dev/null
+++ b/src/libcxx/ncmpiFloat.h
@@ -0,0 +1,28 @@
+#include "ncmpiType.h"
+
+#ifndef NcmpiFloatClass
+#define NcmpiFloatClass
+
+namespace PnetCDF
+{
+
+ /*! Class represents a netCDF atomic Float type. */
+ class NcmpiFloat : public NcmpiType
+ {
+ public:
+
+ /*! equivalence operator */
+ bool operator==(const NcmpiFloat & rhs);
+
+ /*! destructor */
+ ~NcmpiFloat();
+
+ /*! Constructor */
+ NcmpiFloat();
+ };
+
+ /*! A global instance of the NcmpiFloat class within the netCDF namespace. */
+ extern NcmpiFloat ncmpiFloat;
+
+}
+#endif
diff --git a/src/libcxx/ncmpiGroup.cpp b/src/libcxx/ncmpiGroup.cpp
new file mode 100644
index 0000000..8759e25
--- /dev/null
+++ b/src/libcxx/ncmpiGroup.cpp
@@ -0,0 +1,1456 @@
+#include "ncmpiGroup.h"
+#include "ncmpiVar.h"
+#include "ncmpiDim.h"
+#include "ncmpiVlenType.h"
+#include "ncmpiCompoundType.h"
+#include "ncmpiOpaqueType.h"
+#include "ncmpiGroupAtt.h"
+#include "ncmpiByte.h"
+#include "ncmpiUbyte.h"
+#include "ncmpiChar.h"
+#include "ncmpiShort.h"
+#include "ncmpiUshort.h"
+#include "ncmpiInt.h"
+#include "ncmpiUint.h"
+#include "ncmpiInt64.h"
+#include "ncmpiUint64.h"
+#include "ncmpiFloat.h"
+#include "ncmpiDouble.h"
+#include "ncmpiException.h"
+#include "ncmpiCheck.h"
+using namespace std;
+using namespace PnetCDF::exceptions;
+
+namespace PnetCDF {
+ // Global comparator operator ==============
+ // comparator operator
+ bool operator<(const NcmpiGroup& lhs,const NcmpiGroup& rhs)
+ {
+ return false;
+ }
+
+ // comparator operator
+ bool operator>(const NcmpiGroup& lhs,const NcmpiGroup& rhs)
+ {
+ return true;
+ }
+}
+
+using namespace PnetCDF;
+
+/////////////////////////////////////////////
+
+NcmpiGroup::~NcmpiGroup()
+{
+}
+
+// Constructor generates a null object.
+NcmpiGroup::NcmpiGroup() :
+ nullObject(true)
+{}
+
+
+// constructor
+NcmpiGroup::NcmpiGroup(const int groupId) :
+ nullObject(false),
+ myId(groupId)
+{ }
+
+// assignment operator
+NcmpiGroup& NcmpiGroup::operator=(const NcmpiGroup & rhs)
+{
+ nullObject = rhs.nullObject;
+ myId = rhs.myId;
+ return *this;
+}
+
+// The copy constructor.
+NcmpiGroup::NcmpiGroup(const NcmpiGroup& rhs):
+ nullObject(rhs.nullObject),
+ myId(rhs.myId)
+{}
+
+
+// equivalence operator
+bool NcmpiGroup::operator==(const NcmpiGroup & rhs) const
+{
+ if(nullObject)
+ return nullObject == rhs.nullObject;
+ else
+ return myId == rhs.myId;
+}
+
+// != operator
+bool NcmpiGroup::operator!=(const NcmpiGroup & rhs) const
+{
+ return !(*this == rhs);
+}
+
+
+// /////////////
+// NcmpiGroup-related methods
+// /////////////
+
+// Get the group name.
+string NcmpiGroup::getName(bool fullName) const {
+ if(isNull()) throw NcNullGrp("Attempt to invoke NcmpiGroup::getName on a Null group",__FILE__,__LINE__);
+ string groupName;
+ if(fullName){
+ // return full name of group with foward "/" separarating sub-groups.
+ MPI_Offset lenp;
+ ncmpiCheck(ncmpi_inq_grpname_len(myId,&lenp),__FILE__,__LINE__);
+ char* charName= new char[lenp+1];
+ ncmpiCheck(ncmpi_inq_grpname_full(myId,&lenp,charName),__FILE__,__LINE__);
+ groupName = charName;
+ delete charName;
+ }
+ else {
+ // return the (local) name of this group.
+ char charName[NC_MAX_NAME+1];
+ // ncmpiCheck(ncmpi_inq_grpname(myId,charName),__FILE__,__LINE__);
+ charName[0] = '/'; charName[1] = '\0';
+ groupName = charName;
+ }
+ return groupName;
+}
+
+// returns true if this is the root group.
+bool NcmpiGroup::isRootGroup() const{
+ bool result = getName() == "/";
+ return result;
+}
+
+// Get the parent group.
+NcmpiGroup NcmpiGroup::getParentGroup() const {
+ if(isNull()) throw NcNullGrp("Attempt to invoke NcmpiGroup::getParentGroup on a Null group",__FILE__,__LINE__);
+ try {
+ int parentId;
+ ncmpiCheck(ncmpi_inq_grp_parent(myId,&parentId),__FILE__,__LINE__);
+ NcmpiGroup ncmpiGroupParent(parentId);
+ return ncmpiGroupParent;
+ }
+ catch (NcEnoGrp& e) {
+ // no group found, so return null group
+ return NcmpiGroup();
+ }
+}
+
+
+// Get the group id.
+int NcmpiGroup::getId() const {
+ if(isNull()) throw NcNullGrp("Attempt to invoke NcmpiGroup::getId on a Null group",__FILE__,__LINE__);
+ return myId;
+}
+
+// Get the number of NcmpiGroup objects.
+int NcmpiGroup::getGroupCount(NcmpiGroup::GroupLocation location) const {
+ if(isNull()) throw NcNullGrp("Attempt to invoke NcmpiGroup::getGroupCount on a Null group",__FILE__,__LINE__);
+ // initialize group counter
+ int ngroups=0;
+
+ // record this group
+ if(location == ParentsAndCurrentGrps || location == AllGrps) {
+ ngroups ++;
+ }
+
+ // number of children in current group
+ if(location == ChildrenGrps || location == AllChildrenGrps || location == AllGrps ) {
+ int numgrps;
+ int* ncids=NULL;
+ ncmpiCheck(ncmpi_inq_grps(getId(), &numgrps,ncids),__FILE__,__LINE__);
+ ngroups += numgrps;
+ }
+
+ // search in parent groups
+ if(location == ParentsGrps || location == ParentsAndCurrentGrps || location == AllGrps ) {
+ multimap<string,NcmpiGroup> groups(getGroups(ParentsGrps));
+ ngroups += groups.size();
+ }
+
+
+ // get the number of all children that are childreof children
+ if(location == ChildrenOfChildrenGrps || location == AllChildrenGrps || location == AllGrps ) {
+ multimap<string,NcmpiGroup> groups(getGroups(ChildrenOfChildrenGrps));
+ ngroups += groups.size();
+ }
+
+ return ngroups;
+}
+
+
+// Get the set of child NcmpiGroup objects.
+multimap<std::string,NcmpiGroup> NcmpiGroup::getGroups(NcmpiGroup::GroupLocation location) const {
+ if(isNull()) throw NcNullGrp("Attempt to invoke NcmpiGroup::getGroups on a Null group",__FILE__,__LINE__);
+ // create a container to hold the NcmpiGroup's.
+ multimap<string,NcmpiGroup> ncmpiGroups;
+
+ // record this group
+ if(location == ParentsAndCurrentGrps || location == AllGrps) {
+ ncmpiGroups.insert(pair<const string,NcmpiGroup>(getName(),*this));
+ }
+
+ // the child groups of the current group
+ if(location == ChildrenGrps || location == AllChildrenGrps || location == AllGrps ) {
+ // get the number of groups
+ int groupCount = getGroupCount();
+ if (groupCount){
+ vector<int> ncids(groupCount);
+ int* numgrps=NULL;
+ // now get the id of each NcmpiGroup and populate the ncmpiGroups container.
+ ncmpiCheck(ncmpi_inq_grps(myId, numgrps,&ncids[0]),__FILE__,__LINE__);
+ for(int i=0; i<groupCount;i++){
+ NcmpiGroup tmpGroup(ncids[i]);
+ ncmpiGroups.insert(pair<const string,NcmpiGroup>(tmpGroup.getName(),tmpGroup));
+ }
+ }
+ }
+
+ // search in parent groups.
+ if(location == ParentsGrps || location == ParentsAndCurrentGrps || location == AllGrps ) {
+ NcmpiGroup tmpGroup(*this);
+ if(!tmpGroup.isRootGroup()) {
+ while(1) {
+ const NcmpiGroup parentGroup(tmpGroup.getParentGroup());
+ if(parentGroup.isNull()) break;
+ ncmpiGroups.insert(pair<const string,NcmpiGroup>(parentGroup.getName(),parentGroup));
+ tmpGroup=parentGroup;
+ }
+ }
+ }
+
+ // search in child groups of the children
+ if(location == ChildrenOfChildrenGrps || location == AllChildrenGrps || location == AllGrps ) {
+ multimap<string,NcmpiGroup>::iterator it;
+ multimap<string,NcmpiGroup> groups(getGroups(ChildrenGrps));
+ for (it=groups.begin();it!=groups.end();it++) {
+ multimap<string,NcmpiGroup> childGroups(it->second.getGroups(AllChildrenGrps));
+ ncmpiGroups.insert(childGroups.begin(),childGroups.end());
+ }
+ }
+
+ return ncmpiGroups;
+}
+
+// Get the named child NcmpiGroup object.
+NcmpiGroup NcmpiGroup::getGroup(const string& name,NcmpiGroup::GroupLocation location) const{
+ if(isNull()) throw NcNullGrp("Attempt to invoke NcmpiGroup::getGroup on a Null group",__FILE__,__LINE__);
+ multimap<string,NcmpiGroup> ncmpiGroups(getGroups(location));
+ pair<multimap<string,NcmpiGroup>::iterator,multimap<string,NcmpiGroup>::iterator> ret;
+ ret = ncmpiGroups.equal_range(name);
+ if(ret.first == ret.second)
+ return NcmpiGroup(); // null group is returned
+ else
+ return ret.first->second;
+}
+
+
+
+// Get all NcmpiGroup objects with a given name.
+set<NcmpiGroup> NcmpiGroup::getGroups(const std::string& name,NcmpiGroup::GroupLocation location) const {
+ if(isNull()) throw NcNullGrp("Attempt to invoke NcmpiGroup::getGroups on a Null group",__FILE__,__LINE__);
+ // get the set of ncmpiGroups in this group and above.
+ multimap<std::string,NcmpiGroup> ncmpiGroups(getGroups(location));
+ pair<multimap<string,NcmpiGroup>::iterator,multimap<string,NcmpiGroup>::iterator> ret;
+ multimap<string,NcmpiGroup>::iterator it;
+ ret = ncmpiGroups.equal_range(name);
+ set<NcmpiGroup> tmpGroup;
+ for (it=ret.first; it!=ret.second; ++it) {
+ tmpGroup.insert(it->second);
+ }
+ return tmpGroup;
+}
+
+// Add a new child NcmpiGroup object.
+NcmpiGroup NcmpiGroup::addGroup(const string& name) const {
+ if(isNull()) throw NcNullGrp("Attempt to invoke NcmpiGroup::addGroup on a Null group",__FILE__,__LINE__);
+ int new_ncid;
+ ncmpiCheck(ncmpi_def_grp(myId,const_cast<char*> (name.c_str()),&new_ncid),__FILE__,__LINE__);
+ return NcmpiGroup(new_ncid);
+}
+
+
+
+// /////////////
+// NcmpiVar-related accessors
+// /////////////
+
+// Get the number of NcmpiVar objects in this group.
+int NcmpiGroup::getVarCount(NcmpiGroup::Location location) const {
+
+ // search in current group.
+ NcmpiGroup tmpGroup(*this);
+ int nvars=0;
+ // search in current group
+ if((location == ParentsAndCurrent || location == ChildrenAndCurrent || location == Current || location ==All) && !tmpGroup.isNull()) {
+ ncmpiCheck(ncmpi_inq_nvars(tmpGroup.getId(), &nvars),__FILE__,__LINE__);
+ }
+
+ // search recursively in all parent groups.
+ if(location == Parents || location == ParentsAndCurrent || location ==All) {
+ tmpGroup=getParentGroup();
+ while(!tmpGroup.isNull()) {
+ int nvarsp;
+ ncmpiCheck(ncmpi_inq_nvars(tmpGroup.getId(), &nvarsp),__FILE__,__LINE__);
+ nvars += nvarsp;
+ // continue loop with the parent.
+ tmpGroup=tmpGroup.getParentGroup();
+ }
+ }
+
+ // search recursively in all child groups
+ if(location == ChildrenAndCurrent || location == Children || location == All) {
+ multimap<string,NcmpiGroup>::iterator it;
+ multimap<string,NcmpiGroup> groups(getGroups());
+ for (it=groups.begin();it!=groups.end();it++) {
+ nvars += it->second.getVarCount(ChildrenAndCurrent);
+ }
+ }
+ return nvars;
+}
+
+// Get the number of record variable NcmpiVar objects in this group.
+int NcmpiGroup::getRecVarCount(NcmpiGroup::Location location) const {
+
+ // search in current group.
+ NcmpiGroup tmpGroup(*this);
+ int nvars=0;
+ // search in current group
+ if((location == ParentsAndCurrent || location == ChildrenAndCurrent || location == Current || location ==All) && !tmpGroup.isNull()) {
+ ncmpiCheck(ncmpi_inq_num_rec_vars(tmpGroup.getId(), &nvars),__FILE__,__LINE__);
+ }
+
+ // search recursively in all parent groups.
+ if(location == Parents || location == ParentsAndCurrent || location ==All) {
+ tmpGroup=getParentGroup();
+ while(!tmpGroup.isNull()) {
+ int nvarsp;
+ ncmpiCheck(ncmpi_inq_num_rec_vars(tmpGroup.getId(), &nvarsp),__FILE__,__LINE__);
+ nvars += nvarsp;
+ // continue loop with the parent.
+ tmpGroup=tmpGroup.getParentGroup();
+ }
+ }
+
+ // search recursively in all child groups
+ if(location == ChildrenAndCurrent || location == Children || location == All) {
+ multimap<string,NcmpiGroup>::iterator it;
+ multimap<string,NcmpiGroup> groups(getGroups());
+ for (it=groups.begin();it!=groups.end();it++) {
+ nvars += it->second.getRecVarCount(ChildrenAndCurrent);
+ }
+ }
+ return nvars;
+}
+
+// Get the number of fixed-size variable NcmpiVar objects in this group.
+int NcmpiGroup::getFixVarCount(NcmpiGroup::Location location) const {
+
+ // search in current group.
+ NcmpiGroup tmpGroup(*this);
+ int nvars=0;
+ // search in current group
+ if((location == ParentsAndCurrent || location == ChildrenAndCurrent || location == Current || location ==All) && !tmpGroup.isNull()) {
+ ncmpiCheck(ncmpi_inq_num_fix_vars(tmpGroup.getId(), &nvars),__FILE__,__LINE__);
+ }
+
+ // search recursively in all parent groups.
+ if(location == Parents || location == ParentsAndCurrent || location ==All) {
+ tmpGroup=getParentGroup();
+ while(!tmpGroup.isNull()) {
+ int nvarsp;
+ ncmpiCheck(ncmpi_inq_num_fix_vars(tmpGroup.getId(), &nvarsp),__FILE__,__LINE__);
+ nvars += nvarsp;
+ // continue loop with the parent.
+ tmpGroup=tmpGroup.getParentGroup();
+ }
+ }
+
+ // search recursively in all child groups
+ if(location == ChildrenAndCurrent || location == Children || location == All) {
+ multimap<string,NcmpiGroup>::iterator it;
+ multimap<string,NcmpiGroup> groups(getGroups());
+ for (it=groups.begin();it!=groups.end();it++) {
+ nvars += it->second.getFixVarCount(ChildrenAndCurrent);
+ }
+ }
+ return nvars;
+}
+
+// Get the size of record block, sum of single record of all record variables
+MPI_Offset NcmpiGroup::getRecSize(NcmpiGroup::Location location) const {
+
+ // search in current group.
+ NcmpiGroup tmpGroup(*this);
+ MPI_Offset recsize=0;
+ // search in current group
+ if((location == ParentsAndCurrent || location == ChildrenAndCurrent || location == Current || location ==All) && !tmpGroup.isNull()) {
+ ncmpiCheck(ncmpi_inq_recsize(tmpGroup.getId(), &recsize),__FILE__,__LINE__);
+ }
+ return recsize;
+}
+
+// Get the collection of NcmpiVar objects.
+multimap<std::string,NcmpiVar> NcmpiGroup::getVars(NcmpiGroup::Location location) const {
+
+ // create a container to hold the NcmpiVar's.
+ multimap<string,NcmpiVar> ncmpiVars;
+
+ // search in current group.
+ NcmpiGroup tmpGroup(*this);
+ if((location == ParentsAndCurrent || location == ChildrenAndCurrent || location == Current || location ==All) && !tmpGroup.isNull()) {
+ // get the number of variables.
+ int varCount = getVarCount();
+ if (varCount){
+ // now get the name of each NcmpiVar object and populate the ncmpiVars container.
+ // int* nvars=NULL;
+ // vector<int> varids(varCount);
+ // ncmpiCheck(ncmpi_inq_varids(myId, nvars,&varids[0]),__FILE__,__LINE__);
+ for(int i=0; i<varCount;i++){
+ // NcmpiVar tmpVar(*this,varids[i]);
+ NcmpiVar tmpVar(*this,i);
+ ncmpiVars.insert(pair<const string,NcmpiVar>(tmpVar.getName(),tmpVar));
+ }
+ }
+ }
+
+
+ // search recursively in all parent groups.
+ if(location == Parents || location == ParentsAndCurrent || location ==All) {
+ tmpGroup=getParentGroup();
+ while(!tmpGroup.isNull()) {
+ // get the number of variables
+ int varCount = tmpGroup.getVarCount();
+ if (varCount){
+ // now get the name of each NcmpiVar object and populate the ncmpiVars container.
+ int* nvars=NULL;
+ vector<int> varids(varCount);
+ ncmpiCheck(ncmpi_inq_varids(tmpGroup.getId(), nvars,&varids[0]),__FILE__,__LINE__);
+ for(int i=0; i<varCount;i++){
+ NcmpiVar tmpVar(tmpGroup,varids[i]);
+ ncmpiVars.insert(pair<const string,NcmpiVar>(tmpVar.getName(),tmpVar));
+ }
+ }
+ // continue loop with the parent.
+ tmpGroup=tmpGroup.getParentGroup();
+ }
+ }
+
+ // search recusively in all child groups.
+ if(location == ChildrenAndCurrent || location == Children || location == All ) {
+ multimap<string,NcmpiGroup>::iterator it;
+ multimap<string,NcmpiGroup> groups(getGroups());
+ for (it=groups.begin();it!=groups.end();it++) {
+ multimap<string,NcmpiVar> vars=it->second.getVars(ChildrenAndCurrent);
+ ncmpiVars.insert(vars.begin(),vars.end());
+ }
+ }
+
+ return ncmpiVars;
+}
+
+
+// Get all NcmpiVar objects with a given name.
+set<NcmpiVar> NcmpiGroup::getVars(const string& name,NcmpiGroup::Location location) const {
+ // get the set of ncmpiVars in this group and above.
+ multimap<std::string,NcmpiVar> ncmpiVars(getVars(location));
+ pair<multimap<string,NcmpiVar>::iterator,multimap<string,NcmpiVar>::iterator> ret;
+ multimap<string,NcmpiVar>::iterator it;
+ ret = ncmpiVars.equal_range(name);
+ set<NcmpiVar> tmpVar;
+ for (it=ret.first; it!=ret.second; ++it) {
+ tmpVar.insert(it->second);
+ }
+ return tmpVar;
+}
+
+
+
+// Get the named NcmpiVar object.
+NcmpiVar NcmpiGroup::getVar(const string& name,NcmpiGroup::Location location) const {
+ multimap<std::string,NcmpiVar> ncmpiVars(getVars(location));
+ pair<multimap<string,NcmpiVar>::iterator,multimap<string,NcmpiVar>::iterator> ret;
+ ret = ncmpiVars.equal_range(name);
+ if(ret.first == ret.second)
+ // no matching netCDF variable found so return null object.
+ return NcmpiVar();
+ else
+ return ret.first->second;
+}
+
+// Adds a new netCDF scalar variable.
+NcmpiVar NcmpiGroup::addVar(const std::string& name, const NcmpiType& ncmpiType) const {
+ return NcmpiGroup::addVar(name, ncmpiType, std::vector<NcmpiDim>());
+}
+
+// Add a new netCDF variable.
+NcmpiVar NcmpiGroup::addVar(const string& name, const string& typeName, const string& dimName) const {
+ ncmpiCheckDefineMode(myId);
+
+ // get an NcmpiType object with the given type name.
+ NcmpiType tmpType(getType(typeName,NcmpiGroup::ParentsAndCurrent));
+ if(tmpType.isNull()) throw NcNullType("Attempt to invoke NcmpiGroup::addVar failed: typeName must be defined in either the current group or a parent group",__FILE__,__LINE__);
+
+ // get a NcmpiDim object with the given dimension name
+ NcmpiDim tmpDim(getDim(dimName,NcmpiGroup::ParentsAndCurrent));
+ if(tmpDim.isNull()) throw NcNullDim("Attempt to invoke NcmpiGroup::addVar failed: dimName must be defined in either the current group or a parent group",__FILE__,__LINE__);
+
+ // finally define a new netCDF variable
+ int varId;
+ int dimId(tmpDim.getId());
+ ncmpiCheck(ncmpi_def_var(myId,name.c_str(),tmpType.getId(),1,&dimId,&varId),__FILE__,__LINE__);
+ // return an NcmpiVar object for this new variable
+ return NcmpiVar(*this,varId);
+}
+
+
+// Add a new netCDF variable.
+NcmpiVar NcmpiGroup::addVar(const string& name, const NcmpiType& ncmpiType, const NcmpiDim& ncmpiDim) const {
+ ncmpiCheckDefineMode(myId);
+
+ // check NcmpiType object is valid
+ if(ncmpiType.isNull()) throw NcNullType("Attempt to invoke NcmpiGroup::addVar with a Null NcmpiType object",__FILE__,__LINE__);
+ NcmpiType tmpType(getType(ncmpiType.getName(),NcmpiGroup::ParentsAndCurrent));
+ if(tmpType.isNull()) throw NcNullType("Attempt to invoke NcmpiGroup::addVar failed: NcmpiType must be defined in either the current group or a parent group",__FILE__,__LINE__);
+
+ // check NcmpiDim object is valid
+ if(ncmpiDim.isNull()) throw NcNullDim("Attempt to invoke NcmpiGroup::addVar with a Null NcmpiDim object",__FILE__,__LINE__);
+ NcmpiDim tmpDim(getDim(ncmpiDim.getName(),NcmpiGroup::ParentsAndCurrent));
+ if(tmpDim.isNull()) throw NcNullDim("Attempt to invoke NcmpiGroup::addVar failed: NcmpiDim must be defined in either the current group or a parent group",__FILE__,__LINE__);
+
+ // finally define a new netCDF variable
+ int varId;
+ int dimId(tmpDim.getId());
+ ncmpiCheck(ncmpi_def_var(myId,name.c_str(),tmpType.getId(),1,&dimId,&varId),__FILE__,__LINE__);
+ // return an NcmpiVar object for this new variable
+ return NcmpiVar(*this,varId);
+}
+
+
+// Add a new netCDF multi-dimensional variable.
+NcmpiVar NcmpiGroup::addVar(const string& name, const string& typeName, const vector<string>& dimNames) const {
+ ncmpiCheckDefineMode(myId);
+
+ // get an NcmpiType object with the given name.
+ NcmpiType tmpType(getType(typeName,NcmpiGroup::ParentsAndCurrent));
+ if(tmpType.isNull()) throw NcNullType("Attempt to invoke NcmpiGroup::addVar failed: typeName must be defined in either the current group or a parent group",__FILE__,__LINE__);
+
+ // get a set of NcmpiDim objects corresponding to the given dimension names.
+ vector<int> dimIds;
+ dimIds.reserve(dimNames.size());
+ for (size_t i=0; i<dimNames.size();i++){
+ NcmpiDim tmpDim(getDim(dimNames[i],NcmpiGroup::ParentsAndCurrent));
+ if(tmpDim.isNull()) throw NcNullDim("Attempt to invoke NcmpiGroup::addVar failed: dimNames must be defined in either the current group or a parent group",__FILE__,__LINE__);
+ dimIds.push_back(tmpDim.getId());
+ }
+
+ // finally define a new netCDF variable
+ int varId;
+ int *dimIdsPtr = dimIds.empty() ? 0 : &dimIds[0];
+ ncmpiCheck(ncmpi_def_var(myId,name.c_str(),tmpType.getId(),dimIds.size(), dimIdsPtr,&varId),__FILE__,__LINE__);
+ // return an NcmpiVar object for this new variable
+ return NcmpiVar(*this,varId);
+}
+
+// Add a new netCDF multi-dimensional variable.
+NcmpiVar NcmpiGroup::addVar(const string& name, const NcmpiType& ncmpiType, const vector<NcmpiDim>& ncmpiDimVector) const {
+ ncmpiCheckDefineMode(myId);
+
+ // check NcmpiType object is valid
+ if(ncmpiType.isNull()) throw NcNullType("Attempt to invoke NcmpiGroup::addVar with a Null NcmpiType object",__FILE__,__LINE__);
+ NcmpiType tmpType(getType(ncmpiType.getName(),NcmpiGroup::ParentsAndCurrent));
+ if(tmpType.isNull()) throw NcNullType("Attempt to invoke NcmpiGroup::addVar failed: NcmpiType must be defined in either the current group or a parent group",__FILE__,__LINE__);
+
+ // check NcmpiDim objects are valid
+ vector<NcmpiDim>::const_iterator iter;
+ vector<int> dimIds;
+ dimIds.reserve(ncmpiDimVector.size());
+ for (iter=ncmpiDimVector.begin();iter < ncmpiDimVector.end(); iter++) {
+ if(iter->isNull()) throw NcNullDim("Attempt to invoke NcmpiGroup::addVar with a Null NcmpiDim object",__FILE__,__LINE__);
+ NcmpiDim tmpDim(getDim(iter->getName(),NcmpiGroup::ParentsAndCurrent));
+ if(tmpDim.isNull()) throw NcNullDim("Attempt to invoke NcmpiGroup::addVar failed: NcmpiDim must be defined in either the current group or a parent group",__FILE__,__LINE__);
+ dimIds.push_back(tmpDim.getId());
+ }
+
+ // finally define a new netCDF variable
+ int varId;
+ int *dimIdsPtr = dimIds.empty() ? 0 : &dimIds[0];
+ ncmpiCheck(ncmpi_def_var(myId,name.c_str(),tmpType.getId(),dimIds.size(), dimIdsPtr,&varId),__FILE__,__LINE__);
+ // return an NcmpiVar object for this new variable
+ return NcmpiVar(*this,varId);
+}
+
+
+// /////////////
+// NcmpiAtt-related methods
+// /////////////
+
+// Get the number of group attributes.
+int NcmpiGroup::getAttCount(NcmpiGroup::Location location) const {
+
+ // search in current group.
+ NcmpiGroup tmpGroup(*this);
+ int ngatts=0;
+ // search in current group
+ if((location == ParentsAndCurrent || location == ChildrenAndCurrent || location == Current || location ==All) && !tmpGroup.isNull()) {
+ ncmpiCheck(ncmpi_inq_natts(tmpGroup.getId(), &ngatts),__FILE__,__LINE__);
+ }
+
+ // search recursively in all parent groups.
+ if(location == Parents || location == ParentsAndCurrent || location ==All) {
+ tmpGroup=getParentGroup();
+ while(!tmpGroup.isNull()) {
+ int ngattsp;
+ ncmpiCheck(ncmpi_inq_natts(tmpGroup.getId(), &ngattsp),__FILE__,__LINE__);
+ ngatts += ngattsp;
+ // continue loop with the parent.
+ tmpGroup=tmpGroup.getParentGroup();
+ }
+ }
+
+ // search recursively in all child groups
+ if(location == ChildrenAndCurrent || location == Children || location == All) {
+ multimap<string,NcmpiGroup>::iterator it;
+ multimap<string,NcmpiGroup> groups(getGroups());
+ for (it=groups.begin();it!=groups.end();it++) {
+ ngatts += it->second.getAttCount(ChildrenAndCurrent);
+ }
+ }
+
+ return ngatts;
+}
+
+// Get the collection of NcmpiGroupAtt objects.
+multimap<std::string,NcmpiGroupAtt> NcmpiGroup::getAtts(NcmpiGroup::Location location) const {
+
+ // create a container to hold the NcmpiAtt's.
+ multimap<string,NcmpiGroupAtt> ncmpiAtts;
+
+ // search in current group.
+ NcmpiGroup tmpGroup(*this);
+ if((location == ParentsAndCurrent || location == ChildrenAndCurrent || location == Current || location ==All) && !tmpGroup.isNull()) {
+ // get the number of attributes
+ int attCount = tmpGroup.getAttCount();
+ // now get the name of each NcmpiAtt and populate the ncmpiAtts container.
+ for(int i=0; i<attCount;i++){
+ char charName[NC_MAX_NAME+1];
+ ncmpiCheck(ncmpi_inq_attname(tmpGroup.getId(),NC_GLOBAL,i,charName),__FILE__,__LINE__);
+ NcmpiGroupAtt tmpAtt(tmpGroup.getId(),i);
+ ncmpiAtts.insert(pair<const string,NcmpiGroupAtt>(string(charName),tmpAtt));
+ }
+ }
+
+ // search recursively in all parent groups.
+ if(location == Parents || location == ParentsAndCurrent || location ==All) {
+ tmpGroup=getParentGroup();
+ while(!tmpGroup.isNull()) {
+ // get the number of attributes
+ int attCount = tmpGroup.getAttCount();
+ // now get the name of each NcmpiAtt and populate the ncmpiAtts container.
+ for(int i=0; i<attCount;i++){
+ char charName[NC_MAX_NAME+1];
+ ncmpiCheck(ncmpi_inq_attname(tmpGroup.getId(),NC_GLOBAL,i,charName),__FILE__,__LINE__);
+ NcmpiGroupAtt tmpAtt(tmpGroup.getId(),i);
+ ncmpiAtts.insert(pair<const string,NcmpiGroupAtt>(string(charName),tmpAtt));
+ }
+ // continue loop with the parent.
+ tmpGroup=tmpGroup.getParentGroup();
+ }
+ }
+
+ // search recusively in all child groups.
+ if(location == ChildrenAndCurrent || location == Children || location == All ) {
+ multimap<string,NcmpiGroup>::iterator it;
+ multimap<string,NcmpiGroup> groups(getGroups());
+ for (it=groups.begin();it!=groups.end();it++) {
+ multimap<string,NcmpiGroupAtt> atts=it->second.getAtts(ChildrenAndCurrent);
+ ncmpiAtts.insert(atts.begin(),atts.end());
+ }
+ }
+
+ return ncmpiAtts;
+}
+
+// Get the named NcmpiGroupAtt object.
+NcmpiGroupAtt NcmpiGroup::getAtt(const std::string& name,NcmpiGroup::Location location) const {
+ multimap<std::string,NcmpiGroupAtt> ncmpiAtts(getAtts(location));
+ pair<multimap<string,NcmpiGroupAtt>::iterator,multimap<string,NcmpiGroupAtt>::iterator> ret;
+ ret = ncmpiAtts.equal_range(name);
+ if(ret.first == ret.second)
+ // no matching groupAttribute so return null object.
+ return NcmpiGroupAtt();
+ else
+ return ret.first->second;
+}
+
+// Get all NcmpiGroupAtt objects with a given name.
+set<NcmpiGroupAtt> NcmpiGroup::getAtts(const string& name,NcmpiGroup::Location location) const {
+ // get the set of ncmpiGroupAtts in this group and above.
+ multimap<std::string,NcmpiGroupAtt> ncmpiAtts(getAtts(location));
+ pair<multimap<string,NcmpiGroupAtt>::iterator,multimap<string,NcmpiGroupAtt>::iterator> ret;
+ multimap<string,NcmpiGroupAtt>::iterator it;
+ ret = ncmpiAtts.equal_range(name);
+ set<NcmpiGroupAtt> tmpAtt;
+ for (it=ret.first; it!=ret.second; ++it) {
+ tmpAtt.insert(it->second);
+ }
+ return tmpAtt;
+}
+
+
+
+
+// Creates a new NetCDF group attribute or if already exisiting replaces it.
+NcmpiGroupAtt NcmpiGroup::putAtt(const string& name, const string& dataValues) const {
+ ncmpiCheckDefineMode(myId);
+ ncmpiCheck(ncmpi_put_att_text(myId,NC_GLOBAL,name.c_str(),dataValues.size(),dataValues.c_str()),__FILE__,__LINE__);
+ // finally instantiate this attribute and return
+ return getAtt(name);
+}
+
+// Creates a new NetCDF group attribute or if already exisiting replaces it.
+NcmpiGroupAtt NcmpiGroup::putAtt(const string& name, const NcmpiType& type, MPI_Offset len, const unsigned char* dataValues) const {
+ ncmpiCheckDefineMode(myId);
+ NcmpiType::ncmpiType typeClass(type.getTypeClass());
+ if(typeClass == NcmpiType::ncmpi_VLEN || typeClass == NcmpiType::ncmpi_OPAQUE || typeClass == NcmpiType::ncmpi_ENUM || typeClass == NcmpiType::ncmpi_COMPOUND)
+ ncmpiCheck(ncmpi_put_att(myId,NC_GLOBAL,name.c_str(),type.getId(),len,dataValues),__FILE__,__LINE__);
+ else
+ ncmpiCheck(ncmpi_put_att_uchar(myId,NC_GLOBAL,name.c_str(),type.getId(),len,dataValues),__FILE__,__LINE__);
+ // finally instantiate this attribute and return
+ return getAtt(name);
+}
+
+
+// Creates a new NetCDF group attribute or if already exisiting replaces it.
+NcmpiGroupAtt NcmpiGroup::putAtt(const string& name, const NcmpiType& type, MPI_Offset len, const signed char* dataValues) const {
+ ncmpiCheckDefineMode(myId);
+ NcmpiType::ncmpiType typeClass(type.getTypeClass());
+ if(typeClass == NcmpiType::ncmpi_VLEN || typeClass == NcmpiType::ncmpi_OPAQUE || typeClass == NcmpiType::ncmpi_ENUM || typeClass == NcmpiType::ncmpi_COMPOUND)
+ ncmpiCheck(ncmpi_put_att(myId,NC_GLOBAL,name.c_str(),type.getId(),len,dataValues),__FILE__,__LINE__);
+ else
+ ncmpiCheck(ncmpi_put_att_schar(myId,NC_GLOBAL,name.c_str(),type.getId(),len,dataValues),__FILE__,__LINE__);
+ // finally instantiate this attribute and return
+ return getAtt(name);
+}
+
+
+// Creates a new NetCDF group attribute or if already exisiting replaces it.
+NcmpiGroupAtt NcmpiGroup::putAtt(const string& name, const NcmpiType& type, short datumValue) const {
+ ncmpiCheckDefineMode(myId);
+ NcmpiType::ncmpiType typeClass(type.getTypeClass());
+ if(typeClass == NcmpiType::ncmpi_VLEN || typeClass == NcmpiType::ncmpi_OPAQUE || typeClass == NcmpiType::ncmpi_ENUM || typeClass == NcmpiType::ncmpi_COMPOUND)
+ ncmpiCheck(ncmpi_put_att(myId,NC_GLOBAL,name.c_str(),type.getId(),1,&datumValue),__FILE__,__LINE__);
+ else
+ ncmpiCheck(ncmpi_put_att_short(myId,NC_GLOBAL,name.c_str(),type.getId(),1,&datumValue),__FILE__,__LINE__);
+ // finally instantiate this attribute and return
+ return getAtt(name);
+}
+
+
+// Creates a new NetCDF group attribute or if already exisiting replaces it.
+NcmpiGroupAtt NcmpiGroup::putAtt(const string& name, const NcmpiType& type, int datumValue) const {
+ ncmpiCheckDefineMode(myId);
+ NcmpiType::ncmpiType typeClass(type.getTypeClass());
+ if(typeClass == NcmpiType::ncmpi_VLEN || typeClass == NcmpiType::ncmpi_OPAQUE || typeClass == NcmpiType::ncmpi_ENUM || typeClass == NcmpiType::ncmpi_COMPOUND)
+ ncmpiCheck(ncmpi_put_att(myId,NC_GLOBAL,name.c_str(),type.getId(),1,&datumValue),__FILE__,__LINE__);
+ else
+ ncmpiCheck(ncmpi_put_att_int(myId,NC_GLOBAL,name.c_str(),type.getId(),1,&datumValue),__FILE__,__LINE__);
+ // finally instantiate this attribute and return
+ return getAtt(name);
+}
+
+// Creates a new NetCDF group attribute or if already exisiting replaces it.
+NcmpiGroupAtt NcmpiGroup::putAtt(const string& name, const NcmpiType& type, long datumValue) const {
+ ncmpiCheckDefineMode(myId);
+ NcmpiType::ncmpiType typeClass(type.getTypeClass());
+ if(typeClass == NcmpiType::ncmpi_VLEN || typeClass == NcmpiType::ncmpi_OPAQUE || typeClass == NcmpiType::ncmpi_ENUM || typeClass == NcmpiType::ncmpi_COMPOUND)
+ ncmpiCheck(ncmpi_put_att(myId,NC_GLOBAL,name.c_str(),type.getId(),1,&datumValue),__FILE__,__LINE__);
+ else
+ ncmpiCheck(ncmpi_put_att_long(myId,NC_GLOBAL,name.c_str(),type.getId(),1,&datumValue),__FILE__,__LINE__);
+ // finally instantiate this attribute and return
+ return getAtt(name);
+}
+
+// Creates a new NetCDF group attribute or if already exisiting replaces it.
+NcmpiGroupAtt NcmpiGroup::putAtt(const string& name, const NcmpiType& type, float datumValue) const {
+ ncmpiCheckDefineMode(myId);
+ NcmpiType::ncmpiType typeClass(type.getTypeClass());
+ if(typeClass == NcmpiType::ncmpi_VLEN || typeClass == NcmpiType::ncmpi_OPAQUE || typeClass == NcmpiType::ncmpi_ENUM || typeClass == NcmpiType::ncmpi_COMPOUND)
+ ncmpiCheck(ncmpi_put_att(myId,NC_GLOBAL,name.c_str(),type.getId(),1,&datumValue),__FILE__,__LINE__);
+ else
+ ncmpiCheck(ncmpi_put_att_float(myId,NC_GLOBAL,name.c_str(),type.getId(),1,&datumValue),__FILE__,__LINE__);
+ // finally instantiate this attribute and return
+ return getAtt(name);
+}
+
+
+// Creates a new NetCDF group attribute or if already exisiting replaces it.
+NcmpiGroupAtt NcmpiGroup::putAtt(const string& name, const NcmpiType& type, double datumValue) const {
+ ncmpiCheckDefineMode(myId);
+ NcmpiType::ncmpiType typeClass(type.getTypeClass());
+ if(typeClass == NcmpiType::ncmpi_VLEN || typeClass == NcmpiType::ncmpi_OPAQUE || typeClass == NcmpiType::ncmpi_ENUM || typeClass == NcmpiType::ncmpi_COMPOUND)
+ ncmpiCheck(ncmpi_put_att(myId,NC_GLOBAL,name.c_str(),type.getId(),1,&datumValue),__FILE__,__LINE__);
+ else
+ ncmpiCheck(ncmpi_put_att_double(myId,NC_GLOBAL,name.c_str(),type.getId(),1,&datumValue),__FILE__,__LINE__);
+ // finally instantiate this attribute and return
+ return getAtt(name);
+}
+
+
+// Creates a new NetCDF group attribute or if already exisiting replaces it.
+NcmpiGroupAtt NcmpiGroup::putAtt(const string& name, const NcmpiType& type, unsigned short datumValue) const {
+ ncmpiCheckDefineMode(myId);
+ NcmpiType::ncmpiType typeClass(type.getTypeClass());
+ if(typeClass == NcmpiType::ncmpi_VLEN || typeClass == NcmpiType::ncmpi_OPAQUE || typeClass == NcmpiType::ncmpi_ENUM || typeClass == NcmpiType::ncmpi_COMPOUND)
+ ncmpiCheck(ncmpi_put_att(myId,NC_GLOBAL,name.c_str(),type.getId(),1,&datumValue),__FILE__,__LINE__);
+ else
+ ncmpiCheck(ncmpi_put_att_ushort(myId,NC_GLOBAL,name.c_str(),type.getId(),1,&datumValue),__FILE__,__LINE__);
+ // finally instantiate this attribute and return
+ return getAtt(name);
+}
+
+// Creates a new NetCDF group attribute or if already exisiting replaces it.
+NcmpiGroupAtt NcmpiGroup::putAtt(const string& name, const NcmpiType& type, unsigned int datumValue) const {
+ ncmpiCheckDefineMode(myId);
+ NcmpiType::ncmpiType typeClass(type.getTypeClass());
+ if(typeClass == NcmpiType::ncmpi_VLEN || typeClass == NcmpiType::ncmpi_OPAQUE || typeClass == NcmpiType::ncmpi_ENUM || typeClass == NcmpiType::ncmpi_COMPOUND)
+ ncmpiCheck(ncmpi_put_att(myId,NC_GLOBAL,name.c_str(),type.getId(),1,&datumValue),__FILE__,__LINE__);
+ else
+ ncmpiCheck(ncmpi_put_att_uint(myId,NC_GLOBAL,name.c_str(),type.getId(),1,&datumValue),__FILE__,__LINE__);
+ // finally instantiate this attribute and return
+ return getAtt(name);
+}
+
+// Creates a new NetCDF group attribute or if already exisiting replaces it.
+NcmpiGroupAtt NcmpiGroup::putAtt(const string& name, const NcmpiType& type, long long datumValue) const {
+ ncmpiCheckDefineMode(myId);
+ NcmpiType::ncmpiType typeClass(type.getTypeClass());
+ if(typeClass == NcmpiType::ncmpi_VLEN || typeClass == NcmpiType::ncmpi_OPAQUE || typeClass == NcmpiType::ncmpi_ENUM || typeClass == NcmpiType::ncmpi_COMPOUND)
+ ncmpiCheck(ncmpi_put_att(myId,NC_GLOBAL,name.c_str(),type.getId(),1,&datumValue),__FILE__,__LINE__);
+ else
+ ncmpiCheck(ncmpi_put_att_longlong(myId,NC_GLOBAL,name.c_str(),type.getId(),1,&datumValue),__FILE__,__LINE__);
+ // finally instantiate this attribute and return
+ return getAtt(name);
+}
+
+
+// Creates a new NetCDF group attribute or if already exisiting replaces it.
+NcmpiGroupAtt NcmpiGroup::putAtt(const string& name, const NcmpiType& type, unsigned long long datumValue) const {
+ ncmpiCheckDefineMode(myId);
+ NcmpiType::ncmpiType typeClass(type.getTypeClass());
+ if(typeClass == NcmpiType::ncmpi_VLEN || typeClass == NcmpiType::ncmpi_OPAQUE || typeClass == NcmpiType::ncmpi_ENUM || typeClass == NcmpiType::ncmpi_COMPOUND)
+ ncmpiCheck(ncmpi_put_att(myId,NC_GLOBAL,name.c_str(),type.getId(),1,&datumValue),__FILE__,__LINE__);
+ else
+ ncmpiCheck(ncmpi_put_att_ulonglong(myId,NC_GLOBAL,name.c_str(),type.getId(),1,&datumValue),__FILE__,__LINE__);
+ // finally instantiate this attribute and return
+ return getAtt(name);
+}
+
+
+// Creates a new NetCDF group attribute or if already exisiting replaces it.
+NcmpiGroupAtt NcmpiGroup::putAtt(const string& name, const NcmpiType& type, MPI_Offset len, const short* dataValues) const {
+ ncmpiCheckDefineMode(myId);
+ NcmpiType::ncmpiType typeClass(type.getTypeClass());
+ if(typeClass == NcmpiType::ncmpi_VLEN || typeClass == NcmpiType::ncmpi_OPAQUE || typeClass == NcmpiType::ncmpi_ENUM || typeClass == NcmpiType::ncmpi_COMPOUND)
+ ncmpiCheck(ncmpi_put_att(myId,NC_GLOBAL,name.c_str(),type.getId(),len,dataValues),__FILE__,__LINE__);
+ else
+ ncmpiCheck(ncmpi_put_att_short(myId,NC_GLOBAL,name.c_str(),type.getId(),len,dataValues),__FILE__,__LINE__);
+ // finally instantiate this attribute and return
+ return getAtt(name);
+}
+
+
+// Creates a new NetCDF group attribute or if already exisiting replaces it.
+NcmpiGroupAtt NcmpiGroup::putAtt(const string& name, const NcmpiType& type, MPI_Offset len, const int* dataValues) const {
+ ncmpiCheckDefineMode(myId);
+ NcmpiType::ncmpiType typeClass(type.getTypeClass());
+ if(typeClass == NcmpiType::ncmpi_VLEN || typeClass == NcmpiType::ncmpi_OPAQUE || typeClass == NcmpiType::ncmpi_ENUM || typeClass == NcmpiType::ncmpi_COMPOUND)
+ ncmpiCheck(ncmpi_put_att(myId,NC_GLOBAL,name.c_str(),type.getId(),len,dataValues),__FILE__,__LINE__);
+ else
+ ncmpiCheck(ncmpi_put_att_int(myId,NC_GLOBAL,name.c_str(),type.getId(),len,dataValues),__FILE__,__LINE__);
+ // finally instantiate this attribute and return
+ return getAtt(name);
+}
+
+// Creates a new NetCDF group attribute or if already exisiting replaces it.
+NcmpiGroupAtt NcmpiGroup::putAtt(const string& name, const NcmpiType& type, MPI_Offset len, const long* dataValues) const {
+ ncmpiCheckDefineMode(myId);
+ NcmpiType::ncmpiType typeClass(type.getTypeClass());
+ if(typeClass == NcmpiType::ncmpi_VLEN || typeClass == NcmpiType::ncmpi_OPAQUE || typeClass == NcmpiType::ncmpi_ENUM || typeClass == NcmpiType::ncmpi_COMPOUND)
+ ncmpiCheck(ncmpi_put_att(myId,NC_GLOBAL,name.c_str(),type.getId(),len,dataValues),__FILE__,__LINE__);
+ else
+ ncmpiCheck(ncmpi_put_att_long(myId,NC_GLOBAL,name.c_str(),type.getId(),len,dataValues),__FILE__,__LINE__);
+ // finally instantiate this attribute and return
+ return getAtt(name);
+}
+
+// Creates a new NetCDF group attribute or if already exisiting replaces it.
+NcmpiGroupAtt NcmpiGroup::putAtt(const string& name, const NcmpiType& type, MPI_Offset len, const float* dataValues) const {
+ ncmpiCheckDefineMode(myId);
+ NcmpiType::ncmpiType typeClass(type.getTypeClass());
+ if(typeClass == NcmpiType::ncmpi_VLEN || typeClass == NcmpiType::ncmpi_OPAQUE || typeClass == NcmpiType::ncmpi_ENUM || typeClass == NcmpiType::ncmpi_COMPOUND)
+ ncmpiCheck(ncmpi_put_att(myId,NC_GLOBAL,name.c_str(),type.getId(),len,dataValues),__FILE__,__LINE__);
+ else
+ ncmpiCheck(ncmpi_put_att_float(myId,NC_GLOBAL,name.c_str(),type.getId(),len,dataValues),__FILE__,__LINE__);
+ // finally instantiate this attribute and return
+ return getAtt(name);
+}
+
+
+// Creates a new NetCDF group attribute or if already exisiting replaces it.
+NcmpiGroupAtt NcmpiGroup::putAtt(const string& name, const NcmpiType& type, MPI_Offset len, const double* dataValues) const {
+ ncmpiCheckDefineMode(myId);
+ NcmpiType::ncmpiType typeClass(type.getTypeClass());
+ if(typeClass == NcmpiType::ncmpi_VLEN || typeClass == NcmpiType::ncmpi_OPAQUE || typeClass == NcmpiType::ncmpi_ENUM || typeClass == NcmpiType::ncmpi_COMPOUND)
+ ncmpiCheck(ncmpi_put_att(myId,NC_GLOBAL,name.c_str(),type.getId(),len,dataValues),__FILE__,__LINE__);
+ else
+ ncmpiCheck(ncmpi_put_att_double(myId,NC_GLOBAL,name.c_str(),type.getId(),len,dataValues),__FILE__,__LINE__);
+ // finally instantiate this attribute and return
+ return getAtt(name);
+}
+
+
+// Creates a new NetCDF group attribute or if already exisiting replaces it.
+NcmpiGroupAtt NcmpiGroup::putAtt(const string& name, const NcmpiType& type, MPI_Offset len, const unsigned short* dataValues) const {
+ ncmpiCheckDefineMode(myId);
+ NcmpiType::ncmpiType typeClass(type.getTypeClass());
+ if(typeClass == NcmpiType::ncmpi_VLEN || typeClass == NcmpiType::ncmpi_OPAQUE || typeClass == NcmpiType::ncmpi_ENUM || typeClass == NcmpiType::ncmpi_COMPOUND)
+ ncmpiCheck(ncmpi_put_att(myId,NC_GLOBAL,name.c_str(),type.getId(),len,dataValues),__FILE__,__LINE__);
+ else
+ ncmpiCheck(ncmpi_put_att_ushort(myId,NC_GLOBAL,name.c_str(),type.getId(),len,dataValues),__FILE__,__LINE__);
+ // finally instantiate this attribute and return
+ return getAtt(name);
+}
+
+// Creates a new NetCDF group attribute or if already exisiting replaces it.
+NcmpiGroupAtt NcmpiGroup::putAtt(const string& name, const NcmpiType& type, MPI_Offset len, const unsigned int* dataValues) const {
+ ncmpiCheckDefineMode(myId);
+ NcmpiType::ncmpiType typeClass(type.getTypeClass());
+ if(typeClass == NcmpiType::ncmpi_VLEN || typeClass == NcmpiType::ncmpi_OPAQUE || typeClass == NcmpiType::ncmpi_ENUM || typeClass == NcmpiType::ncmpi_COMPOUND)
+ ncmpiCheck(ncmpi_put_att(myId,NC_GLOBAL,name.c_str(),type.getId(),len,dataValues),__FILE__,__LINE__);
+ else
+ ncmpiCheck(ncmpi_put_att_uint(myId,NC_GLOBAL,name.c_str(),type.getId(),len,dataValues),__FILE__,__LINE__);
+ // finally instantiate this attribute and return
+ return getAtt(name);
+}
+
+// Creates a new NetCDF group attribute or if already exisiting replaces it.
+NcmpiGroupAtt NcmpiGroup::putAtt(const string& name, const NcmpiType& type, MPI_Offset len, const long long* dataValues) const {
+ ncmpiCheckDefineMode(myId);
+ NcmpiType::ncmpiType typeClass(type.getTypeClass());
+ if(typeClass == NcmpiType::ncmpi_VLEN || typeClass == NcmpiType::ncmpi_OPAQUE || typeClass == NcmpiType::ncmpi_ENUM || typeClass == NcmpiType::ncmpi_COMPOUND)
+ ncmpiCheck(ncmpi_put_att(myId,NC_GLOBAL,name.c_str(),type.getId(),len,dataValues),__FILE__,__LINE__);
+ else
+ ncmpiCheck(ncmpi_put_att_longlong(myId,NC_GLOBAL,name.c_str(),type.getId(),len,dataValues),__FILE__,__LINE__);
+ // finally instantiate this attribute and return
+ return getAtt(name);
+}
+
+
+// Creates a new NetCDF group attribute or if already exisiting replaces it.
+NcmpiGroupAtt NcmpiGroup::putAtt(const string& name, const NcmpiType& type, MPI_Offset len, const unsigned long long* dataValues) const {
+ ncmpiCheckDefineMode(myId);
+ NcmpiType::ncmpiType typeClass(type.getTypeClass());
+ if(typeClass == NcmpiType::ncmpi_VLEN || typeClass == NcmpiType::ncmpi_OPAQUE || typeClass == NcmpiType::ncmpi_ENUM || typeClass == NcmpiType::ncmpi_COMPOUND)
+ ncmpiCheck(ncmpi_put_att(myId,NC_GLOBAL,name.c_str(),type.getId(),len,dataValues),__FILE__,__LINE__);
+ else
+ ncmpiCheck(ncmpi_put_att_ulonglong(myId,NC_GLOBAL,name.c_str(),type.getId(),len,dataValues),__FILE__,__LINE__);
+ // finally instantiate this attribute and return
+ return getAtt(name);
+}
+
+
+// Creates a new NetCDF group attribute or if already exisiting replaces it.
+ NcmpiGroupAtt NcmpiGroup::putAtt(const string& name, const NcmpiType& type, MPI_Offset len, const void* dataValues) const {
+ ncmpiCheckDefineMode(myId);
+ ncmpiCheck(ncmpi_put_att(myId,NC_GLOBAL,name.c_str(),type.getId(),len,dataValues),__FILE__,__LINE__);
+ // finally instantiate this attribute and return
+ return getAtt(name);
+}
+
+
+
+// /////////////
+// NcmpiDim-related methods
+// /////////////
+
+// Get the number of NcmpiDim objects.
+int NcmpiGroup::getDimCount(NcmpiGroup::Location location) const {
+ if(isNull()) throw NcNullGrp("Attempt to invoke NcmpiGroup::getDimCount on a Null group",__FILE__,__LINE__);
+
+ // intialize counter
+ int ndims=0;
+
+ // search in current group
+ if(location == Current || location == ParentsAndCurrent || location == ChildrenAndCurrent || location == All ) {
+ int ndimsp;
+ ncmpiCheck(ncmpi_inq_ndims(getId(), &ndimsp),__FILE__,__LINE__);
+ ndims += ndimsp;
+ }
+
+ // search in parent groups.
+ if(location == Parents || location == ParentsAndCurrent || location == All ) {
+ multimap<string,NcmpiGroup>::iterator it;
+ multimap<string,NcmpiGroup> groups(getGroups(ParentsGrps));
+ for (it=groups.begin();it!=groups.end();it++) {
+ ndims += it->second.getDimCount();
+ }
+ }
+
+ // search in child groups.
+ if(location == Children || location == ChildrenAndCurrent || location == All ) {
+ multimap<string,NcmpiGroup>::iterator it;
+ multimap<string,NcmpiGroup> groups(getGroups(AllChildrenGrps));
+ for (it=groups.begin();it!=groups.end();it++) {
+ ndims += it->second.getDimCount();
+ }
+ }
+ return ndims;
+}
+
+
+// Get the set of NcmpiDim objects.
+multimap<string,NcmpiDim> NcmpiGroup::getDims(NcmpiGroup::Location location) const {
+ if(isNull()) throw NcNullGrp("Attempt to invoke NcmpiGroup::getDims on a Null group",__FILE__,__LINE__);
+ // create a container to hold the NcmpiDim's.
+ multimap<string,NcmpiDim> ncmpiDims;
+
+ // search in current group
+ if(location == Current || location == ParentsAndCurrent || location == ChildrenAndCurrent || location == All ) {
+ int dimCount = getDimCount();
+ if (dimCount){
+ vector<int> dimids(dimCount);
+ // ncmpiCheck(ncmpi_inq_dimids(getId(), &dimCount, &dimids[0], 0),__FILE__,__LINE__);
+ ncmpiCheck(ncmpi_inq_ndims(getId(), &dimCount),__FILE__,__LINE__);
+ // now get the name of each NcmpiDim and populate the nDims container.
+ for(int i=0; i<dimCount;i++){
+ dimids[i] = i;
+ NcmpiDim tmpDim(*this,dimids[i]);
+ ncmpiDims.insert(pair<const string,NcmpiDim>(tmpDim.getName(),tmpDim));
+ }
+ }
+ }
+
+ // search in parent groups.
+ if(location == Parents || location == ParentsAndCurrent || location == All ) {
+ multimap<string,NcmpiGroup>::iterator it;
+ multimap<string,NcmpiGroup> groups(getGroups(ParentsGrps));
+ for (it=groups.begin();it!=groups.end();it++) {
+ multimap<string,NcmpiDim> dimTmp(it->second.getDims());
+ ncmpiDims.insert(dimTmp.begin(),dimTmp.end());
+ }
+ }
+
+ // search in child groups (makes recursive calls).
+ if(location == Children || location == ChildrenAndCurrent || location == All ) {
+ multimap<string,NcmpiGroup>::iterator it;
+ multimap<string,NcmpiGroup> groups(getGroups(AllChildrenGrps));
+ for (it=groups.begin();it!=groups.end();it++) {
+ multimap<string,NcmpiDim> dimTmp(it->second.getDims());
+ ncmpiDims.insert(dimTmp.begin(),dimTmp.end());
+ }
+ }
+
+ return ncmpiDims;
+}
+
+
+
+// Get the named NcmpiDim object.
+NcmpiDim NcmpiGroup::getDim(const string& name,NcmpiGroup::Location location) const {
+ if(isNull()) throw NcNullGrp("Attempt to invoke NcmpiGroup::getDim on a Null group",__FILE__,__LINE__);
+ multimap<string,NcmpiDim> ncmpiDims(getDims(location));
+ pair<multimap<string,NcmpiDim>::iterator,multimap<string,NcmpiDim>::iterator> ret;
+ ret = ncmpiDims.equal_range(name);
+ if(ret.first == ret.second)
+ return NcmpiDim(); // null group is returned
+ else
+ return ret.first->second;
+}
+
+
+// Get all NcmpiDim objects with a given name.
+set<NcmpiDim> NcmpiGroup::getDims(const string& name,NcmpiGroup::Location location) const {
+ if(isNull()) throw NcNullGrp("Attempt to invoke NcmpiGroup::getDims on a Null group",__FILE__,__LINE__);
+ // get the set of ncmpiDims in this group and above.
+ multimap<string,NcmpiDim> ncmpiDims(getDims(location));
+ pair<multimap<string,NcmpiDim>::iterator,multimap<string,NcmpiDim>::iterator> ret;
+ multimap<string,NcmpiDim>::iterator it;
+ ret = ncmpiDims.equal_range(name);
+ set<NcmpiDim> tmpDim;
+ for (it=ret.first; it!=ret.second; ++it) {
+ tmpDim.insert(it->second);
+ }
+ return tmpDim;
+}
+
+// Add a new NcmpiDim object.
+NcmpiDim NcmpiGroup::addDim(const string& name, MPI_Offset dimSize) const {
+ ncmpiCheckDefineMode(myId);
+ if(isNull()) throw NcNullGrp("Attempt to invoke NcmpiGroup::addDim on a Null group",__FILE__,__LINE__);
+ int dimId;
+ ncmpiCheck(ncmpi_def_dim(myId,name.c_str(),dimSize,&dimId),__FILE__,__LINE__);
+ // finally return NcmpiDim object for this new variable
+ return NcmpiDim(*this,dimId);
+}
+
+// Add a new NcmpiDim object with unlimited size..
+NcmpiDim NcmpiGroup::addDim(const string& name) const {
+ ncmpiCheckDefineMode(myId);
+ if(isNull()) throw NcNullGrp("Attempt to invoke NcmpiGroup::addDim on a Null group",__FILE__,__LINE__);
+ int dimId;
+ ncmpiCheck(ncmpi_def_dim(myId,name.c_str(),NC_UNLIMITED,&dimId),__FILE__,__LINE__);
+ // finally return NcmpiDim object for this new variable
+ return NcmpiDim(*this,dimId);
+}
+
+
+
+
+
+// /////////////
+// type-object related methods
+// /////////////
+
+// Gets the number of type objects.
+int NcmpiGroup::getTypeCount(NcmpiGroup::Location location) const {
+
+ if(isNull()) throw NcNullGrp("Attempt to invoke NcmpiGroup::getTypeCount on a Null group",__FILE__,__LINE__);
+
+ // intialize counter
+ int ntypes=0;
+
+ // search in current group
+ if(location == Current || location == ParentsAndCurrent || location == ChildrenAndCurrent || location == All ) {
+ int ntypesp=0;
+ int* typeidsp=NULL;
+ ncmpiCheck(ncmpi_inq_typeids(getId(), &ntypesp,typeidsp),__FILE__,__LINE__);
+ ntypes+= ntypesp;
+ }
+
+ // search in parent groups.
+ if(location == Parents || location == ParentsAndCurrent || location == All ) {
+ multimap<string,NcmpiGroup>::iterator it;
+ multimap<string,NcmpiGroup> groups(getGroups(ParentsGrps));
+ for (it=groups.begin();it!=groups.end();it++) {
+ ntypes += it->second.getTypeCount();
+ }
+ }
+
+ // search in child groups.
+ if(location == Children || location == ChildrenAndCurrent || location == All ) {
+ multimap<string,NcmpiGroup>::iterator it;
+ multimap<string,NcmpiGroup> groups(getGroups(AllChildrenGrps));
+ for (it=groups.begin();it!=groups.end();it++) {
+ ntypes += it->second.getTypeCount();
+ }
+ }
+ return ntypes;
+}
+
+
+
+// Gets the number of type objects with a given enumeration type.
+int NcmpiGroup::getTypeCount(NcmpiType::ncmpiType enumType, NcmpiGroup::Location location) const {
+
+ if(isNull()) throw NcNullGrp("Attempt to invoke NcmpiGroup::getTypeCount on a Null group",__FILE__,__LINE__);
+
+ // intialize counter
+ int ntypes=0;
+
+ // search in current group
+ if(location == Current || location == ParentsAndCurrent || location == ChildrenAndCurrent || location == All ) {
+ int ntypesp=0;
+ int* typeidsp=NULL;
+ ncmpiCheck(ncmpi_inq_typeids(getId(), &ntypesp,typeidsp),__FILE__,__LINE__);
+ if (ntypesp){
+ vector<int> typeids(ntypesp);
+ ncmpiCheck(ncmpi_inq_typeids(getId(), &ntypesp,&typeids[0]),__FILE__,__LINE__);
+ for (int i=0; i<ntypesp;i++){
+ NcmpiType tmpType(*this,typeids[i]);
+ if(tmpType.getTypeClass() == enumType) ntypes++;
+ }
+ }
+ }
+
+ // search in parent groups.
+ if(location == Parents || location == ParentsAndCurrent || location == All ) {
+ multimap<string,NcmpiGroup>::iterator it;
+ multimap<string,NcmpiGroup> groups(getGroups(ParentsGrps));
+ for (it=groups.begin();it!=groups.end();it++) {
+ ntypes += it->second.getTypeCount(enumType);
+ }
+ }
+
+ // search in child groups.
+ if(location == Children || location == ChildrenAndCurrent || location == All ) {
+ multimap<string,NcmpiGroup>::iterator it;
+ multimap<string,NcmpiGroup> groups(getGroups(AllChildrenGrps));
+ for (it=groups.begin();it!=groups.end();it++) {
+ ntypes += it->second.getTypeCount(enumType);
+ }
+ }
+ return ntypes;
+}
+
+
+// Gets the collection of NcmpiType objects.
+multimap<string,NcmpiType> NcmpiGroup::getTypes(NcmpiGroup::Location location) const {
+ if(isNull()) throw NcNullGrp("Attempt to invoke NcmpiGroup::getTypes on a Null group",__FILE__,__LINE__);
+ // create a container to hold the NcmpiType's.
+ multimap<string,NcmpiType> ncmpiTypes;
+
+ // search in current group
+ if(location == Current || location == ParentsAndCurrent || location == ChildrenAndCurrent || location == All ) {
+ int typeCount = getTypeCount();
+ if (typeCount){
+ vector<int> typeids(typeCount);
+ ncmpiCheck(ncmpi_inq_typeids(getId(), &typeCount,&typeids[0]),__FILE__,__LINE__);
+ // now get the name of each NcmpiType and populate the nTypes container.
+ for(int i=0; i<typeCount;i++){
+ NcmpiType tmpType(*this,typeids[i]);
+ ncmpiTypes.insert(pair<const string,NcmpiType>(tmpType.getName(),tmpType));
+ }
+ }
+ }
+
+ // search in parent groups.
+ if(location == Parents || location == ParentsAndCurrent || location == All ) {
+ multimap<string,NcmpiGroup>::iterator it;
+ multimap<string,NcmpiGroup> groups(getGroups(ParentsGrps));
+ for (it=groups.begin();it!=groups.end();it++) {
+ multimap<string,NcmpiType> typeTmp(it->second.getTypes());
+ ncmpiTypes.insert(typeTmp.begin(),typeTmp.end());
+ }
+ }
+
+ // search in child groups (makes recursive calls).
+ if(location == Children || location == ChildrenAndCurrent || location == All ) {
+ multimap<string,NcmpiGroup>::iterator it;
+ multimap<string,NcmpiGroup> groups(getGroups(AllChildrenGrps));
+ for (it=groups.begin();it!=groups.end();it++) {
+ multimap<string,NcmpiType> typeTmp(it->second.getTypes());
+ ncmpiTypes.insert(typeTmp.begin(),typeTmp.end());
+ }
+ }
+
+ return ncmpiTypes;
+}
+
+
+// Gets the collection of NcmpiType objects with a given name.
+set<NcmpiType> NcmpiGroup::getTypes(const string& name, NcmpiGroup::Location location) const {
+ if(isNull()) throw NcNullGrp("Attempt to invoke NcmpiGroup::getTypes on a Null group",__FILE__,__LINE__);
+ // iterator for the multimap container.
+ multimap<string,NcmpiType>::iterator it;
+ // return argument of equal_range: iterators to lower and upper bounds of the range.
+ pair<multimap<string,NcmpiType>::iterator,multimap<string,NcmpiType>::iterator> ret;
+ // get the entire collection of types.
+ multimap<string,NcmpiType> types(getTypes(location));
+ // define STL set object to hold the result
+ set<NcmpiType> tmpType;
+ // get the set of NcmpiType objects with a given name
+ ret=types.equal_range(name);
+ for (it=ret.first;it!=ret.second;it++) {
+ tmpType.insert(it->second);
+ }
+ return tmpType;
+}
+
+
+// Gets the collection of NcmpiType objects with a given data type.
+set<NcmpiType> NcmpiGroup::getTypes(NcmpiType::ncmpiType enumType, NcmpiGroup::Location location) const {
+ if(isNull()) throw NcNullGrp("Attempt to invoke NcmpiGroup::getTypes on a Null group",__FILE__,__LINE__);
+ // iterator for the multimap container.
+ multimap<string,NcmpiType>::iterator it;
+ // get the entire collection of types.
+ multimap<string,NcmpiType> types(getTypes(location));
+ // define STL set object to hold the result
+ set<NcmpiType> tmpType;
+ // get the set of NcmpiType objects with a given data type
+ for (it=types.begin();it!=types.end();it++) {
+ if(it->second.getTypeClass() == enumType) {
+ tmpType.insert(it->second);
+ }
+ }
+ return(tmpType);
+}
+
+
+// Gets the collection of NcmpiType objects with a given name and data type.
+set<NcmpiType> NcmpiGroup::getTypes(const string& name, NcmpiType::ncmpiType enumType, NcmpiGroup::Location location) const {
+ if(isNull()) throw NcNullGrp("Attempt to invoke NcmpiGroup::getTypes on a Null group",__FILE__,__LINE__);
+ // iterator for the multimap container.
+ multimap<string,NcmpiType>::iterator it;
+ // return argument of equal_range: iterators to lower and upper bounds of the range.
+ pair<multimap<string,NcmpiType>::iterator,multimap<string,NcmpiType>::iterator> ret;
+ // get the entire collection of types.
+ multimap<string,NcmpiType> types(getTypes(location));
+ // define STL set object to hold the result
+ set<NcmpiType> tmpType;
+ // get the set of NcmpiType objects with a given name
+ ret=types.equal_range(name);
+ for (it=ret.first;it!=ret.second;it++) {
+ if((*it).second.getTypeClass() == enumType) {
+ tmpType.insert(it->second);
+ }
+ }
+ return(tmpType);
+}
+
+
+// Gets the NcmpiType object with a given name.
+NcmpiType NcmpiGroup::getType(const string& name, NcmpiGroup::Location location) const {
+ if(isNull()) throw NcNullGrp("Attempt to invoke NcmpiGroup::getType on a Null group",__FILE__,__LINE__);
+ if(name == "byte" ) return ncmpiByte;
+ if(name == "ubyte" ) return ncmpiUbyte;
+ if(name == "char" ) return ncmpiChar;
+ if(name == "short" ) return ncmpiShort;
+ if(name == "ushort" ) return ncmpiUshort;
+ if(name == "int" ) return ncmpiInt;
+ if(name == "uint" ) return ncmpiUint;
+ if(name == "int64" ) return ncmpiInt64;
+ if(name == "uint64" ) return ncmpiUint64;
+ if(name == "float" ) return ncmpiFloat;
+ if(name == "double" ) return ncmpiDouble;
+
+ // this is a user defined type
+ // iterator for the multimap container.
+ multimap<string,NcmpiType>::iterator it;
+ // return argument of equal_range: iterators to lower and upper bounds of the range.
+ pair<multimap<string,NcmpiType>::iterator,multimap<string,NcmpiType>::iterator> ret;
+ // get the entire collection of types.
+ multimap<string,NcmpiType> types(getTypes(location));
+ // define STL set object to hold the result
+ set<NcmpiType> tmpType;
+ // get the set of NcmpiType objects with a given name
+ ret=types.equal_range(name);
+ if(ret.first == ret.second)
+ return NcmpiType();
+ else
+ return ret.first->second;
+}
+
+
+// Adds a new netCDF Enum type.
+NcmpiEnumType NcmpiGroup::addEnumType(const string& name,NcmpiEnumType::ncmpiEnumType baseType) const {
+ ncmpiCheckDefineMode(myId);
+ nc_type typeId;
+ ncmpiCheck(ncmpi_def_enum(myId, baseType, name.c_str(), &typeId),__FILE__,__LINE__);
+ NcmpiEnumType ncmpiTypeTmp(*this,name);
+ return ncmpiTypeTmp;
+}
+
+
+// Adds a new netCDF Vlen type.
+NcmpiVlenType NcmpiGroup::addVlenType(const string& name,NcmpiType& baseType) const {
+ ncmpiCheckDefineMode(myId);
+ nc_type typeId;
+ ncmpiCheck(ncmpi_def_vlen(myId, const_cast<char*>(name.c_str()),baseType.getId(),&typeId),__FILE__,__LINE__);
+ NcmpiVlenType ncmpiTypeTmp(*this,name);
+ return ncmpiTypeTmp;
+}
+
+
+// Adds a new netCDF Opaque type.
+NcmpiOpaqueType NcmpiGroup::addOpaqueType(const string& name, MPI_Offset size) const {
+ ncmpiCheckDefineMode(myId);
+ nc_type typeId;
+ ncmpiCheck(ncmpi_def_opaque(myId, size,const_cast<char*>(name.c_str()), &typeId),__FILE__,__LINE__);
+ NcmpiOpaqueType ncmpiTypeTmp(*this,name);
+ return ncmpiTypeTmp;
+}
+
+// Adds a new netCDF UserDefined type.
+NcmpiCompoundType NcmpiGroup::addCompoundType(const string& name, MPI_Offset size) const {
+ ncmpiCheckDefineMode(myId);
+ nc_type typeId;
+ ncmpiCheck(ncmpi_def_compound(myId, size,const_cast<char*>(name.c_str()),&typeId),__FILE__,__LINE__);
+ NcmpiCompoundType ncmpiTypeTmp(*this,name);
+ return ncmpiTypeTmp;
+}
+
+
+// Get the collection of coordinate variables.
+map<string,NcmpiGroup> NcmpiGroup::getCoordVars(NcmpiGroup::Location location) const {
+ map<string,NcmpiGroup> coordVars;
+
+ // search in current group and parent groups.
+ NcmpiGroup tmpGroup(*this);
+ multimap<string,NcmpiDim>::iterator itD;
+ multimap<string,NcmpiVar>::iterator itV;
+ while(1) {
+ // get the collection of NcmpiDim objects defined in this group.
+ multimap<string,NcmpiDim> dimTmp(tmpGroup.getDims());
+ multimap<string,NcmpiVar> varTmp(tmpGroup.getVars());
+ for (itD=dimTmp.begin();itD!=dimTmp.end();itD++) {
+ string coordName(itD->first);
+ itV = varTmp.find(coordName);
+ if(itV != varTmp.end()) {
+ coordVars.insert(pair<const string,NcmpiGroup>(string(coordName),tmpGroup));
+ }
+ }
+ if(location != ParentsAndCurrent || location != All || tmpGroup.isRootGroup()) {
+ break;
+ }
+ // continue loop with the parent.
+ tmpGroup=tmpGroup.getParentGroup();
+ }
+
+ // search in child groups (makes recursive calls).
+ if(location == ChildrenAndCurrent || location == All ) {
+ multimap<string,NcmpiGroup>::iterator it;
+ multimap<string,NcmpiGroup> groups(getGroups());
+ for (it=groups.begin();it!=groups.end();it++) {
+ map<string,NcmpiGroup> coordVarsTmp=getCoordVars(ChildrenAndCurrent);
+ coordVars.insert(coordVarsTmp.begin(),coordVarsTmp.end());
+ }
+ }
+
+ return coordVars;
+}
+
+// Get the NcmpiDim and NcmpiVar object pair for a named coordinate variables.
+void NcmpiGroup::getCoordVar(string& coordVarName, NcmpiDim& ncmpiDim, NcmpiVar& ncmpiVar, NcmpiGroup::Location location) const {
+
+ // search in current group and parent groups.
+ multimap<string,NcmpiDim>::iterator itD;
+ NcmpiGroup tmpGroup(*this);
+ multimap<string,NcmpiVar>::iterator itV;
+ while(1) {
+ // get the collection of NcmpiDim objects defined in this group.
+ multimap<string,NcmpiDim> dimTmp(tmpGroup.getDims());
+ multimap<string,NcmpiVar> varTmp(tmpGroup.getVars());
+ itD=dimTmp.find(coordVarName);
+ itV=varTmp.find(coordVarName);
+ if(itD != dimTmp.end() && itV != varTmp.end()) {
+ ncmpiDim=itD->second;
+ ncmpiVar=itV->second;
+ return;
+ }
+ if(location != ParentsAndCurrent || location != All || tmpGroup.isRootGroup()) {
+ break;
+ }
+ // continue loop with the parent.
+ tmpGroup=tmpGroup.getParentGroup();
+ }
+
+ // search in child groups (makes recursive calls).
+ if(location == ChildrenAndCurrent || location == All ) {
+ multimap<string,NcmpiGroup>::iterator it;
+ multimap<string,NcmpiGroup> groups(getGroups());
+ for (it=groups.begin();it!=groups.end();it++) {
+ getCoordVar(coordVarName,ncmpiDim,ncmpiVar,ChildrenAndCurrent);
+ if(!ncmpiDim.isNull()) break;
+ }
+ }
+
+ if(ncmpiDim.isNull()) {
+ // return null objects as no coordinates variables were obtained.
+ NcmpiDim dimTmp;
+ NcmpiVar varTmp;
+ ncmpiDim=dimTmp;
+ ncmpiVar=varTmp;
+ return;
+ }
+
+}
diff --git a/src/libcxx/ncmpiGroup.h b/src/libcxx/ncmpiGroup.h
new file mode 100644
index 0000000..311b101
--- /dev/null
+++ b/src/libcxx/ncmpiGroup.h
@@ -0,0 +1,596 @@
+#include <string>
+#include <vector>
+#include <set>
+#include <map>
+#include "ncmpiType.h"
+#include "ncmpiEnumType.h"
+#include "ncmpiGroupAtt.h"
+
+
+
+#ifndef NcmpiGroupClass
+#define NcmpiGroupClass
+
+
+namespace PnetCDF
+{
+ class NcmpiVar; // forward declaration.
+ class NcmpiDim; // forward declaration.
+ class NcmpiVlenType; // forward declaration.
+ class NcmpiCompoundType; // forward declaration.
+ class NcmpiOpaqueType; // forward declaration.
+
+ /*! Class represents a netCDF group. */
+ class NcmpiGroup
+ {
+
+ public:
+
+ /*!
+ The enumeration list contains the options for selecting groups (used for returned set of NcmpiGroup objects).
+ */
+ enum GroupLocation
+ {
+ ChildrenGrps, //!< Select from the set of children in the current group.
+ ParentsGrps, //!< Select from set of parent groups (excludes the current group).
+ ChildrenOfChildrenGrps, //!< Select from set of all children of children in the current group.
+ AllChildrenGrps, //!< Select from set of all children of the current group and beneath.
+ ParentsAndCurrentGrps, //!< Select from set of parent groups(includes the current group).
+ AllGrps //!< Select from set of parent groups, current groups and all the children beneath.
+ };
+
+ /*!
+ The enumeration list contains the options for selecting groups.
+ */
+ enum Location
+ {
+ Current, //!< Select from contents of current group.
+ Parents, //!< Select from contents of parents groups.
+ Children, //!< Select from contents of children groups.
+ ParentsAndCurrent, //!< Select from contents of current and parents groups.
+ ChildrenAndCurrent, //!< Select from contents of current and child groups.
+ All //!< Select from contents of current, parents and child groups.
+ };
+
+
+ /*! assignment operator */
+ NcmpiGroup& operator=(const NcmpiGroup& rhs);
+
+ /*! Constructor generates a \ref isNull "null object". */
+ NcmpiGroup();
+
+ //* constructor */
+ NcmpiGroup(int groupId);
+
+ /*! The copy constructor. */
+ NcmpiGroup(const NcmpiGroup& rhs);
+
+ /*! destructor */
+ virtual ~NcmpiGroup();
+
+ /*! equivalence operator */
+ bool operator==(const NcmpiGroup& rhs) const;
+
+ /*! != operator */
+ bool operator!=(const NcmpiGroup& rhs) const;
+
+ /*! comparator operator */
+ friend bool operator<(const NcmpiGroup& lhs,const NcmpiGroup& rhs);
+
+ /*! comparator operator */
+ friend bool operator>(const NcmpiGroup& lhs,const NcmpiGroup& rhs);
+
+ // /////////////
+ // NcmpiGroup-related methods
+ // /////////////
+
+ /*! Gets the group name. */
+ /*!
+ Method will throw an PnetCDF::exceptions::NcNullgrp exception if the group is null (ie NcmpiGroup::isNull()=true).
+ \param fullName If true then the full name is returned with subgroups separated by a forward slash "/" (default is false)
+ \return The group name.
+ */
+ std::string getName(bool fullName=false) const;
+
+ /*!
+ Gets the parent group.
+ Method will throw an PnetCDF::exceptions::NcNullgrp exception if the group is null (ie NcmpiGroup::isNull()=true).
+ If the current root is the parent group, then return a null group.
+ */
+ NcmpiGroup getParentGroup() const ;
+
+ /*!
+ Gets the group id.
+ Method will throw an PnetCDF::exceptions::NcNullgrp exception if the group is null (ie NcmpiGroup::isNull()=true).
+ */
+ int getId() const;
+
+ /*!
+ Gets the number of NcmpiGroup objects.
+ Method will throw an PnetCDF::exceptions::NcNullgrp exception if the group is null (ie NcmpiGroup::isNull()=true).
+ \param location Enumeration type controlling the groups to search.
+ \return Number of groups.
+ */
+ int getGroupCount(NcmpiGroup::GroupLocation location=ChildrenGrps) const;
+
+ /*!
+ Gets the collection of NcmpiGroup objects.
+ Method will throw an PnetCDF::exceptions::NcNullgrp exception if the group is null (ie NcmpiGroup::isNull()=true).
+ \param location Enumeration type controlling the groups to search.
+ \return A STL multimap object, containing pairs of <attribute name, NcmpiGroup object> entities.
+ */
+ std::multimap<std::string,NcmpiGroup> getGroups(NcmpiGroup::GroupLocation location=ChildrenGrps) const;
+
+
+ /*!
+ Gets NcmpiGroup objects with a given name.
+ Method will throw an PnetCDF::exceptions::NcNullgrp exception if the group is null (ie NcmpiGroup::isNull()=true).
+ \param name Name of group.
+ \param location Enumeration type controlling the groups to search.
+ \return Set of NcmpiGroup objects with given name.
+ */
+ std::set<NcmpiGroup> getGroups(const std::string& name,NcmpiGroup::GroupLocation location=ChildrenGrps) const;
+
+ /*!
+ Gets the named child NcmpiGroup object.
+ Method will throw an PnetCDF::exceptions::NcNullgrp exception if the group is null (ie NcmpiGroup::isNull()=true).
+ \param name Group name.
+ \param location Enumeration type controlling the groups to search.
+ \return An NcmpiGroup object. If there are multiple objects indentied with the same name,
+ the object closest to the current group is returned. If no valid object is found ,
+ a \ref NcmpiGroup::isNull "null node" is returned.
+ */
+ NcmpiGroup getGroup(const std::string& name,NcmpiGroup::GroupLocation location=ChildrenGrps) const;
+
+ /*!
+ Adds a new child netCDF group object.
+ Method will throw an PnetCDF::exceptions::NcNullgrp exception if the group is null (ie NcmpiGroup::isNull()=true).
+ \param name Variable name.
+ \return NcmpiGroup The NcmpiGroup object for this new netCDF group.
+ */
+ NcmpiGroup addGroup(const std::string& name) const;
+
+
+ /*! Returns true if this object is null (i.e. it has no contents); otherwise returns false. */
+ bool isNull() const {return nullObject;}
+
+ /*! Returns true if this is the root group, otherwise returns false. */
+ bool isRootGroup() const;
+
+ // /////////////
+ // NcmpiVar-related accessors
+ // /////////////
+
+ /*!
+ Gets the number of NcmpiVar objects in this group.
+ \param location Enumeration type controlling the groups to search.
+ \return Number of variables.
+ */
+ int getVarCount(NcmpiGroup::Location location=Current) const;
+
+ /*!
+ Gets the number of record variable NcmpiVar objects in this group.
+ \param location Enumeration type controlling the groups to search.
+ \return Number of record variables.
+ */
+ int getRecVarCount(NcmpiGroup::Location location=Current) const;
+
+ /*!
+ Gets the size of record block, i.e. the sume of single records of all
+ the record variables.
+ \param location Enumeration type controlling the groups to search.
+ \return size of record bock.
+ */
+ MPI_Offset getRecSize(NcmpiGroup::Location location=Current) const;
+
+ /*!
+ Gets the number of fixed-size variable NcmpiVar objects in this group.
+ \param location Enumeration type controlling the groups to search.
+ \return Number of fixed-size variables.
+ */
+ int getFixVarCount(NcmpiGroup::Location location=Current) const;
+
+ /*!
+ Get the collection of NcmpiVar objects.
+ \param location Enumeration type controlling the groups to search.
+ \return A STL multimap object, containing pairs of <attribute name, NcmpiVar object> entities.
+ */
+ std::multimap<std::string,NcmpiVar> getVars(NcmpiGroup::Location location=Current) const;
+
+ /*!
+ Gets all NcmpiVar objects with a given name.
+ \param name Name of attribute
+ \param location Enumeration type controlling the groups to search.
+ \return Set of NcmpiVar objects.
+ */
+ std::set<NcmpiVar> getVars(const std::string& name,NcmpiGroup::Location location=Current) const;
+
+ /*!
+ Gets the named NcmpiVar object..
+ \param name Variable name.
+ \param location Enumeration type controlling the groups to search.
+ \return A NcmpiVar object. If there are multiple objects indentied with the
+ same name, the object closest to the current group is returned.
+ If no valid object is found , a \ref NcmpiVar::isNull "null node" is returned.
+ */
+ NcmpiVar getVar(const std::string& name,NcmpiGroup::Location location=Current) const;
+
+ /*!
+ Adds a new netCDF scalar variable.
+ The NcmpiType must be non-null, and be defined in either the current group or a parent group.
+ An NcNullType exception is thrown if the NcmpiType object is invalid.
+ \param name Variable name.
+ \param typeName Type name.
+ \return The NcmpiVar object for this new netCDF variable.
+ */
+ NcmpiVar addVar(const std::string& name, const NcmpiType& ncmpiType) const;
+
+ /*!
+ Adds a new netCDF variable.
+ The NcmpiType and NcmpiDim objects must be non-null, and be defined in either the current group or a parent group.
+ An NcNullType exception is thrown if the NcmpiType object is invalid.
+ An NcNullDim exception is thrown if the NcmpiDim object is invalid.
+ \param name Variable name.
+ \param typeName Type name.
+ \param dimName Dimension name.
+ \return The NcmpiVar object for this new netCDF variable.
+ */
+ NcmpiVar addVar(const std::string& name, const std::string& typeName, const std::string& dimName) const;
+
+ /*!
+ Adds a new netCDF variable.
+ The NcmpiType and NcmpiDim objects must be non-null, and be defined in either the current group or a parent group.
+ An NcNullType exception is thrown if the NcmpiType object is invalid.
+ An NcNullDim exception is thrown if the NcmpiDim object is invalid.
+ \param name Variable name.
+ \param ncmpiType NcmpiType object.
+ \param ncmpiDim NcmpiDim object.
+ \return The NcmpiVar object for this new netCDF variable.
+ */
+ NcmpiVar addVar(const std::string& name, const NcmpiType& ncmpiType, const NcmpiDim& ncmpiDim) const;
+
+ /*!
+ Adds a new netCDF multi-dimensional variable.
+ The NcmpiType and NcmpiDim objects must be non-null, and be defined in either the current group or a parent group.
+ An NcNullType exception is thrown if the NcmpiType object is invalid.
+ An NcNullDim exception is thrown if the NcmpiDim object is invalid.
+ \param name Variable name.
+ \param typeName Type name.
+ \param dimNames Vector of dimension names.
+ \return The NcmpiVar object for this new netCDF variable.
+ */
+ NcmpiVar addVar(const std::string& name, const std::string& typeName, const std::vector<std::string>& dimNames) const;
+
+
+ /*!
+ Adds a new multi-dimensional netCDF variable.
+ The NcmpiType and NcmpiDim objects must be non-null, and be defined in either the current group or a parent group.
+ An NcNullType exception is thrown if the NcmpiType object is invalid.
+ An NcNullDim exception is thrown if any of the the NcmpiDim objects are invalid.
+ \param name Variable name.
+ \param ncmpiType NcmpiType object.
+ \param ncmpiDimvector Vector of NcmpiDim objects.
+ \return The NcmpiVar object for this new netCDF variable.
+ */
+ NcmpiVar addVar(const std::string& name, const NcmpiType& ncmpiType, const std::vector<NcmpiDim>& ncmpiDimVector) const;
+
+ // /////////////
+ // NcmpiGroupAtt-related methods
+ // /////////////
+
+ /*!
+ Gets the number of group attributes.
+ \param location Enumeration type controlling the groups to search.
+ \return Number of attributes.
+ */
+ int getAttCount(NcmpiGroup::Location location=Current) const;
+
+ /*!
+ Gets the collection of NcmpiGroupAtt objects.
+ \param location Enumeration type controlling the groups to search.
+ \return A STL multimap object, containing pairs of <attribute name, NcmpiGroupAtt object> entities.
+ */
+ std::multimap<std::string,NcmpiGroupAtt> getAtts(NcmpiGroup::Location location=Current) const;
+
+ /*!
+ Gets all NcmpiGroupAtt objects with a given name.
+ \param name Name of attribute
+ \param location Enumeration type controlling the groups to search.
+ \return Set of NcmpiGroupAtt objects.
+ */
+ std::set<NcmpiGroupAtt> getAtts(const std::string& name,NcmpiGroup::Location location=Current) const;
+
+ /*!
+ Gets the named NcmpiGroupAtt object.
+ \param name Name of attribute
+ \param location Enumeration type controlling the groups to search.
+ \return A NcmpiGroupAtt object. If there are multiple objects indentied with the
+ same name, the object closest to the current group is returned. If no valid object is found ,
+ a \ref NcmpiGroupAtt::isNull "null node" is returned.
+ */
+ NcmpiGroupAtt getAtt(const std::string& name,NcmpiGroup::Location location=Current) const;
+
+
+ /*! \overload
+ */
+ NcmpiGroupAtt putAtt(const std::string& name, MPI_Offset len, const char** dataValues) const ;
+
+ /*! \overload
+ */
+ NcmpiGroupAtt putAtt(const std::string& name, const std::string& dataValues) const ;
+ /*! \overload
+ */
+ NcmpiGroupAtt putAtt(const std::string& name, const NcmpiType& type, short datumValue) const ;
+ /*! \overload
+ */
+ NcmpiGroupAtt putAtt(const std::string& name, const NcmpiType& type, int datumValue) const ;
+ /*! \overload
+ */
+ NcmpiGroupAtt putAtt(const std::string& name, const NcmpiType& type, long datumValue) const ;
+ /*! \overload
+ */
+ NcmpiGroupAtt putAtt(const std::string& name, const NcmpiType& type, float datumValue) const ;
+ /*! \overload
+ */
+ NcmpiGroupAtt putAtt(const std::string& name, const NcmpiType& type, double datumValue) const ;
+ /*! \overload
+ */
+ NcmpiGroupAtt putAtt(const std::string& name, const NcmpiType& type, unsigned short datumValue) const ;
+ /*! \overload
+ */
+ NcmpiGroupAtt putAtt(const std::string& name, const NcmpiType& type, unsigned int datumValue) const ;
+ /*! \overload
+ */
+ NcmpiGroupAtt putAtt(const std::string& name, const NcmpiType& type, unsigned long long datumValue) const ;
+ /*! \overload
+ */
+ NcmpiGroupAtt putAtt(const std::string& name, const NcmpiType& type, long long datumValue) const ;
+ /*! \overload
+ */
+ NcmpiGroupAtt putAtt(const std::string& name, const NcmpiType& type, MPI_Offset len, const unsigned char* dataValues) const ;
+ /*! \overload
+ */
+ NcmpiGroupAtt putAtt(const std::string& name, const NcmpiType& type, MPI_Offset len, const signed char* dataValues) const ;
+ /*! \overload
+ */
+ NcmpiGroupAtt putAtt(const std::string& name, const NcmpiType& type, MPI_Offset len, const short* dataValues) const ;
+ /*! \overload
+ */
+ NcmpiGroupAtt putAtt(const std::string& name, const NcmpiType& type, MPI_Offset len, const int* dataValues) const ;
+ /*! \overload
+ */
+ NcmpiGroupAtt putAtt(const std::string& name, const NcmpiType& type, MPI_Offset len, const long* dataValues) const ;
+ /*! \overload
+ */
+ NcmpiGroupAtt putAtt(const std::string& name, const NcmpiType& type, MPI_Offset len, const float* dataValues) const ;
+ /*! \overload
+ */
+ NcmpiGroupAtt putAtt(const std::string& name, const NcmpiType& type, MPI_Offset len, const double* dataValues) const ;
+ /*! \overload
+ */
+ NcmpiGroupAtt putAtt(const std::string& name, const NcmpiType& type, MPI_Offset len, const unsigned short* dataValues) const ;
+ /*! \overload
+ */
+ NcmpiGroupAtt putAtt(const std::string& name, const NcmpiType& type, MPI_Offset len, const unsigned int* dataValues) const ;
+ /*! \overload
+ */
+ NcmpiGroupAtt putAtt(const std::string& name, const NcmpiType& type, MPI_Offset len, const unsigned long long* dataValues) const ;
+ /*! \overload
+ */
+ NcmpiGroupAtt putAtt(const std::string& name, const NcmpiType& type, MPI_Offset len, const long long* dataValues) const ;
+ /*!
+ Creates a new NetCDF group attribute or if already exisiting replaces it.
+ If you are writing a _Fill_Value_ attribute, and will tell the HDF5 layer to use
+ the specified fill value for that variable.
+ \par
+ Although it's possible to create attributes of all types, text and double attributes are adequate for most purposes.
+ \param name Name of attribute.
+ \param type The attribute type.
+ \param len The length of the attribute (number of Nctype repeats).
+ \param dataValues Data Values to put into the new attribute.
+ If the type of data values differs from the netCDF variable type, type conversion will occur.
+ (However, no type conversion is carried out for variables using the user-defined data types:
+ ncmpi_Vlen, ncmpi_Opaque, ncmpi_Compound and ncmpi_Enum.)
+ \return The NcmpiGroupAtt object for this new netCDF attribute.
+ */
+ NcmpiGroupAtt putAtt(const std::string& name, const NcmpiType& type, MPI_Offset len, const void* dataValues) const ;
+
+
+
+ // /////////////
+ // NcmpiDim-related methods
+ // /////////////
+
+ /*!
+ Gets the number of NcmpiDim objects.
+ \param location Enumeration type controlling the groups to search.
+ \return Number of dimensions.
+ */
+ int getDimCount(NcmpiGroup::Location location=Current) const;
+
+ /*!
+ Gets the collection of NcmpiDim objects.
+ \param location Enumeration type controlling the groups to search.
+ \return A STL multimap object, containing pairs of <attribute name, NcmpiDim object> entities.
+ */
+ std::multimap<std::string,NcmpiDim> getDims(NcmpiGroup::Location location=Current) const;
+
+ /*!
+ Gets NcmpiDim objects with a given name.
+ \param name Name of dimension.
+ \param location Enumeration type controlling the groups to search.
+ \return Set of NcmpiDim objects with given name.
+ */
+ std::set<NcmpiDim> getDims(const std::string& name,NcmpiGroup::Location location=Current) const;
+
+ /*!
+ Gets the named NcmpiDim object.
+ \param name Name of dimension.
+ \param location Enumeration type controlling the groups to search.
+ \return An NcmpiDim object. If there are multiple objects indentied with the same name,
+ the object closest to the current group is returned. If no valid object is found , a \ref NcmpiDim::isNull "null node" is returned.
+ */
+ NcmpiDim getDim(const std::string& name,NcmpiGroup::Location location=Current) const;
+
+ /*!
+ Adds a new netCDF dimension.
+ \param The name of new dimension.
+ \param Length of dimension; that is, number of values for this dimension as an index to variables
+ that use it.
+ \return The NcmpiDim object for this new netCDF dimension.
+ */
+ NcmpiDim addDim(const std::string& name, MPI_Offset dimSize) const;
+
+ /*!
+ Adds a new unlimited netCDF dimension.
+ \param The name of new dimension.
+ \return The NcmpiDim object for this new netCDF dimension.
+ */
+ NcmpiDim addDim(const std::string& name) const;
+
+ // /////////////
+ // NcmpiType-related methods
+ // /////////////
+
+ /*!
+ Gets the number of type objects.
+ \param location Enumeration type controlling the groups to search.
+ \return Number of types.
+ */
+ int getTypeCount(NcmpiGroup::Location location=Current) const;
+
+
+ /*!
+ Gets the number of type objects with a given enumeration type.
+ \param enumType The enumeration value of the object type.
+ \param location Enumeration type controlling the groups to search.
+ \return Number of types of the given enumeration type.
+ */
+ int getTypeCount(NcmpiType::ncmpiType enumType, NcmpiGroup::Location location=Current) const;
+
+
+ /*!
+ Gets the collection of NcmpiType objects.
+ \param location Enumeration type controlling the groups to search.
+ \return A STL multimap object, on return contains pairs of <Type name, NcmpiType object> entities.
+ For atomic types, the type returned is the CDL name.
+ */
+ std::multimap<std::string,NcmpiType> getTypes(NcmpiGroup::Location location=Current) const;
+
+
+ /*!
+ Gets the collection of NcmpiType objects with a given name.
+ \param name Name of type. For atomic types, the CDL name is expected. This is consistent with the
+ string returned from NcmpiType::getName().
+ \param location Enumeration type controlling the groups to search.
+ \return Set of NcmpiType objects.
+ */
+ std::set<NcmpiType> getTypes(const std::string& name, NcmpiGroup::Location location=Current) const;
+
+ /*!
+ Gets the collection of NcmpiType objects with a given data type.
+ \param enumType Enumeration type specifying the data type.
+ \param location Enumeration type controlling the groups to search.
+ \return Set of Nctype objects.
+ */
+ std::set<NcmpiType> getTypes(NcmpiType::ncmpiType enumType, NcmpiGroup::Location location=Current) const;
+
+
+ /*!
+ Gets the collection of NcmpiType objects with a given name and data type.
+ \param name Name of type. For atomic types, the CDL name is expected. This is consistent with the
+ string returned from NcmpiType::getName().
+ \param enumType Enumeration type specifying the data type.
+ \param location Enumeration type controlling the groups to search.
+ \return Set of Nctype objects.
+ */
+ std::set<NcmpiType> getTypes(const std::string& name, NcmpiType::ncmpiType enumType, NcmpiGroup::Location location=Current) const;
+
+
+ /*!
+ Gets the NcmpiType object with a given name.
+ \param name Name of type. For atomic types, the CDL name is expected. This is consistent with the
+ string returned from NcmpiType::getName().
+ \param location Enumeration type controlling the groups to search.
+ \return NcmpiType object. If there are multiple objects indentied with the same name,
+ the object closest to the current group is returned. If no valid object is found , a \ref NcmpiType::isNull "null node" is returned.
+
+ */
+ NcmpiType getType(const std::string& name, NcmpiGroup::Location location=Current) const;
+
+
+ /*!
+ Adds a new netCDF enum type.
+ \param name Name of type. For atomic types, the CDL name is expected. This is consistent with the
+ string returned from NcmpiType::getName().
+ \param enumType The enumeration value of the object type.
+ \return The NcmpiEnumType object for this new netCDF enum type.
+ */
+ NcmpiEnumType addEnumType(const std::string& name,NcmpiEnumType::ncmpiEnumType basetype) const;
+
+
+ /*!
+ Adds a new netCDF Vlen type.
+ \param name Name of type.
+ \param basetype A NcmpiType object to be used for the basetype.
+ \return The NcmpiVlenType object for this new netCDF vlen type.
+ */
+ NcmpiVlenType addVlenType(const std::string& name,NcmpiType& basetype) const;
+
+
+ /*!
+ Adds a new netCDF Opaque type.
+ \param name Name of type.
+ \param size The size of the new type in bytes.
+ \return The NcmpiOpaqueType object for this new netCDF opaque type..
+ */
+ NcmpiOpaqueType addOpaqueType(const std::string& name, MPI_Offset size) const;
+
+
+ /*!
+ Adds a new netCDF UserDefined type.
+ \param name Name of type.
+ \param size The size of the new type in bytes.
+ \return The new NcmpiCompoundType object for this new netCDF userDefined type.
+ */
+ NcmpiCompoundType addCompoundType(const std::string& name, MPI_Offset size) const;
+
+
+ /*!
+ Gets a collection of coordinate variables.
+ Coordinate variable have an NcmpiDim and NcmpiVar object with the same name defined in the same group.
+ \par
+ The method returns STL map object containing a coordinate variables in the current group and optionally
+ in the parent and child groups. It is expected that within each group, the names of dimensions are unique and
+ the the names of variables are unique. However, if this is not the case, this method will still work correctly.
+
+ \param location Enumeration type controlling the groups to search.
+ \return The NcmpiVar dimension variable. If no valid object is found , a \ref NcmpiVar::isNull "null node" is returned.
+ */
+ std::map<std::string,NcmpiGroup> getCoordVars(NcmpiGroup::Location location=Current) const;
+
+ /*!
+ Gets the NcmpiDim and NcmpiVar object pair for a named coordinate variable.
+ Coordinate variable have an NcmpiDim and NcmpiVar object with the same name defined in the same group.
+ \par
+ The method returns two objects for the named coordinate variable. The method searches first in the current
+ group and optionally in the parent and child group and returns the first instance found.
+ \param location Enumeration type controlling the groups to search.
+ \return The set of names of dimension variables.
+ */
+ void getCoordVar(std::string& coordVarName, NcmpiDim& ncmpiDim, NcmpiVar& ncmpiVar, NcmpiGroup::Location location=Current) const;
+
+
+ protected:
+
+ /*! assignment operator */
+ /* NcmpiGroup& operator=(const NcmpiGroup& rhs); */
+
+ bool nullObject;
+
+ int myId;
+
+ };
+
+}
+#endif
diff --git a/src/libcxx/ncmpiGroupAtt.cpp b/src/libcxx/ncmpiGroupAtt.cpp
new file mode 100644
index 0000000..722090c
--- /dev/null
+++ b/src/libcxx/ncmpiGroupAtt.cpp
@@ -0,0 +1,65 @@
+#include "ncmpiGroupAtt.h"
+#include "ncmpiGroup.h"
+#include "ncmpiCheck.h"
+#include <pnetcdf.h>
+using namespace std;
+
+
+namespace PnetCDF {
+ // Global comparator operator ==============
+ // comparator operator
+ bool operator<(const NcmpiGroupAtt& lhs,const NcmpiGroupAtt& rhs)
+ {
+ return false;
+ }
+
+ // comparator operator
+ bool operator>(const NcmpiGroupAtt& lhs,const NcmpiGroupAtt& rhs)
+ {
+ return true;
+ }
+}
+
+
+using namespace PnetCDF;
+
+// assignment operator
+NcmpiGroupAtt& NcmpiGroupAtt::operator=(const NcmpiGroupAtt & rhs)
+{
+ NcmpiAtt::operator=(rhs); // assign base class parts
+ return *this;
+}
+
+//! The copy constructor.
+NcmpiGroupAtt::NcmpiGroupAtt(const NcmpiGroupAtt& rhs):
+ NcmpiAtt(rhs) // invoke base class copy constructor
+{}
+
+
+// Constructor generates a null object.
+NcmpiGroupAtt::NcmpiGroupAtt() :
+ NcmpiAtt() // invoke base class constructor
+{}
+
+// equivalence operator (doesn't bother compaing varid's of each object).
+bool NcmpiGroupAtt::operator==(const NcmpiGroupAtt & rhs)
+{
+ if(nullObject)
+ return nullObject == rhs.isNull();
+ else
+ return myName == rhs.myName && groupId == rhs.groupId;
+}
+
+// Constructor for an existing global attribute.
+NcmpiGroupAtt::NcmpiGroupAtt(const NcmpiGroup& grp, const int index):
+ NcmpiAtt(false)
+{
+ groupId = grp.getId();
+ varId = NC_GLOBAL;
+ // get the name of this attribute
+ char attName[NC_MAX_NAME+1];
+ ncmpiCheck(ncmpi_inq_attname(groupId,varId, index, attName),__FILE__,__LINE__);
+ ncmpiCheck(ncmpi_inq_attname(groupId,varId,index,attName),__FILE__,__LINE__);
+ myName = attName;
+}
+
diff --git a/src/libcxx/ncmpiGroupAtt.h b/src/libcxx/ncmpiGroupAtt.h
new file mode 100644
index 0000000..809dc52
--- /dev/null
+++ b/src/libcxx/ncmpiGroupAtt.h
@@ -0,0 +1,44 @@
+#include "ncmpiAtt.h"
+
+#ifndef NcmpiGroupAttClass
+#define NcmpiGroupAttClass
+
+namespace PnetCDF
+{
+ class NcmpiGroup; // forward declaration.
+
+ /*! Class represents a netCDF group attribute */
+ class NcmpiGroupAtt : public NcmpiAtt
+ {
+ public:
+
+ /*! assignment operator */
+ NcmpiGroupAtt& operator= (const NcmpiGroupAtt& rhs);
+
+ /*! Constructor generates a \ref isNull "null object". */
+ NcmpiGroupAtt ();
+
+ /*! The copy constructor. */
+ NcmpiGroupAtt(const NcmpiGroupAtt& rhs) ;
+
+ /*!
+ Constructor for an existing global attribute.
+ \param grp Parent Group object.
+ \param index The index (id) of the attribute.
+ */
+ NcmpiGroupAtt(const NcmpiGroup& grp, const int index);
+
+ /*! equivalence operator */
+ bool operator== (const NcmpiGroupAtt& rhs);
+
+ /*! comparator operator */
+ friend bool operator<(const NcmpiGroupAtt& lhs,const NcmpiGroupAtt& rhs);
+
+ /*! comparator operator */
+ friend bool operator>(const NcmpiGroupAtt& lhs,const NcmpiGroupAtt& rhs);
+
+ };
+
+}
+
+#endif
diff --git a/src/libcxx/ncmpiInt.cpp b/src/libcxx/ncmpiInt.cpp
new file mode 100644
index 0000000..d23c7e5
--- /dev/null
+++ b/src/libcxx/ncmpiInt.cpp
@@ -0,0 +1,22 @@
+#include "ncmpiInt.h"
+#include <pnetcdf.h>
+using namespace PnetCDF;
+
+// create an instance of NcmpiInt called PnetCDF::ncmpiInt
+namespace PnetCDF {
+ NcmpiInt ncmpiInt;
+}
+
+// constructor
+NcmpiInt::NcmpiInt() : NcmpiType(NC_INT){
+}
+
+NcmpiInt::~NcmpiInt() {
+}
+
+
+// equivalence operator
+bool NcmpiInt::operator==(const NcmpiInt & rhs) {
+ // simply check the netCDF id.
+ return myId == rhs.myId;
+}
diff --git a/src/libcxx/ncmpiInt.h b/src/libcxx/ncmpiInt.h
new file mode 100644
index 0000000..fcbb88d
--- /dev/null
+++ b/src/libcxx/ncmpiInt.h
@@ -0,0 +1,28 @@
+#include "ncmpiType.h"
+
+#ifndef NcmpiIntClass
+#define NcmpiIntClass
+
+namespace PnetCDF
+{
+
+ /*! Class represents a netCDF atomic Int type. */
+ class NcmpiInt : public NcmpiType
+ {
+ public:
+
+ /*! equivalence operator */
+ bool operator==(const NcmpiInt & rhs);
+
+ /*! destructor */
+ ~NcmpiInt();
+
+ /*! Constructor */
+ NcmpiInt();
+ };
+
+ /*! A global instance of the NcmpiInt class within the netCDF namespace. */
+ extern NcmpiInt ncmpiInt;
+
+}
+#endif
diff --git a/src/libcxx/ncmpiInt64.cpp b/src/libcxx/ncmpiInt64.cpp
new file mode 100644
index 0000000..99024d3
--- /dev/null
+++ b/src/libcxx/ncmpiInt64.cpp
@@ -0,0 +1,22 @@
+#include "ncmpiInt64.h"
+#include <pnetcdf.h>
+using namespace PnetCDF;
+
+// create an instance of NcmpiInt64 called PnetCDF::ncmpiInt64
+namespace PnetCDF {
+ NcmpiInt64 ncmpiInt64;
+}
+
+// constructor
+NcmpiInt64::NcmpiInt64() : NcmpiType(NC_INT64){
+}
+
+NcmpiInt64::~NcmpiInt64() {
+}
+
+
+// equivalence operator
+bool NcmpiInt64::operator==(const NcmpiInt64 & rhs) {
+ // simply check the netCDF id.
+ return myId == rhs.myId;
+}
diff --git a/src/libcxx/ncmpiInt64.h b/src/libcxx/ncmpiInt64.h
new file mode 100644
index 0000000..c1c1b23
--- /dev/null
+++ b/src/libcxx/ncmpiInt64.h
@@ -0,0 +1,28 @@
+#include "ncmpiType.h"
+
+#ifndef NcmpiInt64Class
+#define NcmpiInt64Class
+
+namespace PnetCDF
+{
+
+ /*! Class represents a netCDF atomic Int64 type. */
+ class NcmpiInt64 : public NcmpiType
+ {
+ public:
+
+ /*! equivalence operator */
+ bool operator==(const NcmpiInt64 & rhs);
+
+ /*! destructor */
+ ~NcmpiInt64();
+
+ /*! Constructor */
+ NcmpiInt64();
+ };
+
+ /*! A global instance of the NcmpiInt64 class within the netCDF namespace. */
+ extern NcmpiInt64 ncmpiInt64;
+
+}
+#endif
diff --git a/src/libcxx/ncmpiOpaqueType.cpp b/src/libcxx/ncmpiOpaqueType.cpp
new file mode 100644
index 0000000..1d33ec1
--- /dev/null
+++ b/src/libcxx/ncmpiOpaqueType.cpp
@@ -0,0 +1,68 @@
+#include "ncmpiOpaqueType.h"
+#include "ncmpiGroup.h"
+#include "ncmpiCheck.h"
+#include "ncmpiException.h"
+#include <pnetcdf.h>
+using namespace std;
+using namespace PnetCDF;
+using namespace PnetCDF::exceptions;
+
+// Class represents a netCDF variable.
+using namespace PnetCDF;
+
+// assignment operator
+NcmpiOpaqueType& NcmpiOpaqueType::operator=(const NcmpiOpaqueType& rhs)
+{
+ // assign base class parts
+ NcmpiType::operator=(rhs);
+ return *this;
+}
+
+// assignment operator
+NcmpiOpaqueType& NcmpiOpaqueType::operator=(const NcmpiType& rhs)
+{
+ if (&rhs != this) {
+ // check the rhs is the base of an Opaque type
+ if(getTypeClass() != NC_OPAQUE) throw NcmpiException("The NcmpiType object must be the base of an Opaque type.",__FILE__,__LINE__);
+ // assign base class parts
+ NcmpiType::operator=(rhs);
+ }
+ return *this;
+}
+
+// The copy constructor.
+NcmpiOpaqueType::NcmpiOpaqueType(const NcmpiOpaqueType& rhs):
+ NcmpiType(rhs)
+{
+}
+
+
+// Constructor generates a null object.
+NcmpiOpaqueType::NcmpiOpaqueType() :
+ NcmpiType() // invoke base class constructor
+{}
+
+
+// constructor
+NcmpiOpaqueType::NcmpiOpaqueType(const NcmpiGroup& grp, const string& name) :
+ NcmpiType(grp,name)
+{}
+
+
+// constructor
+NcmpiOpaqueType::NcmpiOpaqueType(const NcmpiType& ncmpiType) :
+ NcmpiType(ncmpiType)
+{
+ // check the nctype object is the base of a Opaque type
+ if(getTypeClass() != NC_OPAQUE) throw NcmpiException("The NcmpiType object must be the base of an Opaque type.",__FILE__,__LINE__);
+}
+
+// Returns the size of the opaque type in bytes.
+MPI_Offset NcmpiOpaqueType::getTypeSize() const
+{
+ char* charName;
+ charName=NULL;
+ MPI_Offset sizep;
+ ncmpiCheck(ncmpi_inq_opaque(groupId,myId,charName,&sizep),__FILE__,__LINE__);
+ return sizep;
+}
diff --git a/src/libcxx/ncmpiOpaqueType.h b/src/libcxx/ncmpiOpaqueType.h
new file mode 100644
index 0000000..e7a8527
--- /dev/null
+++ b/src/libcxx/ncmpiOpaqueType.h
@@ -0,0 +1,58 @@
+#include <string>
+#include "ncmpiType.h"
+
+#ifndef NcmpiOpaqueTypeClass
+#define NcmpiOpaqueTypeClass
+
+
+namespace PnetCDF
+{
+ class NcmpiGroup; // forward declaration.
+
+ /*! Class represents a netCDF opaque type */
+ class NcmpiOpaqueType : public NcmpiType
+ {
+ public:
+
+ /*! Constructor generates a \ref isNull "null object". */
+ NcmpiOpaqueType();
+
+ /*!
+ Constructor.
+ The opaque Type must already exist in the netCDF file. New netCDF opaque types #
+ can be added using NcmpiGroup::addNcmpiOpaqueType();
+ \param grp The parent group where this type is defined.
+ \param name Name of new type.
+ */
+ NcmpiOpaqueType(const NcmpiGroup& grp, const std::string& name);
+
+ /*!
+ Constructor.
+ Constructs from the base type NcmpiType object. Will throw an exception if the NcmpiType is not the base of a Opaque type.
+ \param ncmpiType A Nctype object.
+ */
+ NcmpiOpaqueType(const NcmpiType& ncmpiType);
+
+ /*! assignment operator */
+ NcmpiOpaqueType& operator=(const NcmpiOpaqueType& rhs);
+
+ /*!
+ Assignment operator.
+ This assigns from the base type NcmpiType object. Will throw an exception if the NcmpiType is not the base of an Opaque type.
+ */
+ NcmpiOpaqueType& operator=(const NcmpiType& rhs);
+
+ /*! The copy constructor.*/
+ NcmpiOpaqueType(const NcmpiOpaqueType& rhs);
+
+ /*! destructor */
+ ~NcmpiOpaqueType(){;}
+
+ /*! Returns the size of the opaque type in bytes. */
+ MPI_Offset getTypeSize() const;
+
+ };
+
+}
+
+#endif
diff --git a/src/libcxx/ncmpiShort.cpp b/src/libcxx/ncmpiShort.cpp
new file mode 100644
index 0000000..aeae3b9
--- /dev/null
+++ b/src/libcxx/ncmpiShort.cpp
@@ -0,0 +1,22 @@
+#include "ncmpiShort.h"
+#include <pnetcdf.h>
+using namespace PnetCDF;
+
+// create an instance of NcmpiShort called PnetCDF::ncmpiShort
+namespace PnetCDF {
+ NcmpiShort ncmpiShort;
+}
+
+// constructor
+NcmpiShort::NcmpiShort() : NcmpiType(NC_SHORT){
+}
+
+NcmpiShort::~NcmpiShort() {
+}
+
+
+// equivalence operator
+bool NcmpiShort::operator==(const NcmpiShort & rhs) {
+ // simply check the netCDF id.
+ return myId == rhs.myId;
+}
diff --git a/src/libcxx/ncmpiShort.h b/src/libcxx/ncmpiShort.h
new file mode 100644
index 0000000..f5145af
--- /dev/null
+++ b/src/libcxx/ncmpiShort.h
@@ -0,0 +1,28 @@
+#include "ncmpiType.h"
+
+#ifndef NcmpiShortClass
+#define NcmpiShortClass
+
+namespace PnetCDF
+{
+
+ /*! Class represents a netCDF atomic Short type. */
+ class NcmpiShort : public NcmpiType
+ {
+ public:
+
+ /*! equivalence operator */
+ bool operator==(const NcmpiShort & rhs);
+
+ /*! destructor */
+ ~NcmpiShort();
+
+ /*! Constructor */
+ NcmpiShort();
+ };
+
+ /*! A global instance of the NcmpiShort class within the netCDF namespace. */
+ extern NcmpiShort ncmpiShort;
+
+}
+#endif
diff --git a/src/libcxx/ncmpiType.cpp b/src/libcxx/ncmpiType.cpp
new file mode 100644
index 0000000..74e93fd
--- /dev/null
+++ b/src/libcxx/ncmpiType.cpp
@@ -0,0 +1,179 @@
+#include <string>
+#include "ncmpiType.h"
+#include "ncmpiGroup.h"
+#include "ncmpiCheck.h"
+using namespace std;
+
+
+namespace PnetCDF {
+ // Global comparator operator ==============
+ // comparator operator
+ bool operator<(const NcmpiType& lhs,const NcmpiType& rhs)
+ {
+ return false;
+ }
+
+ // comparator operator
+ bool operator>(const NcmpiType& lhs,const NcmpiType& rhs)
+ {
+ return true;
+ }
+}
+
+using namespace PnetCDF;
+
+// assignment operator
+NcmpiType& NcmpiType::operator=(const NcmpiType & rhs)
+{
+ nullObject = rhs.nullObject;
+ myId= rhs.myId;
+ groupId = rhs.groupId;
+ return *this;
+}
+
+// The copy constructor.
+NcmpiType::NcmpiType(const NcmpiType& rhs):
+ nullObject(rhs.nullObject),
+ myId(rhs.myId),
+ groupId(rhs.groupId)
+{}
+
+
+// Constructor generates a null object.
+NcmpiType::NcmpiType() :
+ nullObject(true)
+{}
+
+// constructor
+NcmpiType::NcmpiType(const NcmpiGroup& grp, const string& name) :
+ nullObject (false)
+{
+ groupId= grp.getId();
+ NcmpiType typTmp(grp.getType(name,NcmpiGroup::ParentsAndCurrent));
+ myId = typTmp.getId();
+}
+
+// constructor for a global type
+NcmpiType::NcmpiType(nc_type id) :
+ nullObject(false),
+ myId(id),
+ groupId(0)
+{
+}
+
+
+// Constructor for a non-global type
+NcmpiType::NcmpiType(const PnetCDF::NcmpiGroup& grp, nc_type id):
+ nullObject(false),
+ myId(id),
+ groupId(grp.getId())
+{}
+
+
+// equivalence operator
+bool NcmpiType::operator==(const NcmpiType & rhs) const
+{
+ if(nullObject)
+ return nullObject == rhs.nullObject;
+ else
+ return groupId == rhs.groupId && myId == rhs.myId;
+}
+
+// != operator
+bool NcmpiType::operator!=(const NcmpiType & rhs) const
+{
+ return !(*this == rhs);
+}
+
+// Gets parent group.
+NcmpiGroup NcmpiType::getParentGroup() const {
+ if(groupId == 0) return NcmpiGroup(); else return NcmpiGroup(groupId);
+}
+
+static
+string inq_type(int myId) {
+ switch (myId) {
+ case NC_BYTE : return string("byte");
+ case NC_UBYTE : return string("ubyte");
+ case NC_CHAR : return string("char");
+ case NC_SHORT : return string("short");
+ case NC_USHORT : return string("ushort");
+ case NC_INT : return string("int");
+ case NC_UINT : return string("uint");
+ case NC_INT64 : return string("int64");
+ case NC_UINT64 : return string("uint64");
+ case NC_FLOAT : return string("float");
+ case NC_DOUBLE : return string("double");
+ default: break;
+ }
+ return string("");
+}
+
+// Returns the type name.
+string NcmpiType::getName() const{
+ // char charName[NC_MAX_NAME+1];
+ // MPI_Offset *sizep=NULL;
+ // ncmpiCheck(ncmpi_inq_type(groupId,myId,charName,sizep),__FILE__,__LINE__);
+ // return string(charName);
+ return inq_type(myId);
+};
+
+// Returns the size in bytes
+MPI_Offset NcmpiType::getSize() const{
+ char* charName=NULL;
+ MPI_Offset sizep;
+ ncmpiCheck(ncmpi_inq_type(groupId,myId,charName,&sizep),__FILE__,__LINE__);
+ return sizep;
+};
+
+// The type class returned as an enumeration type.
+NcmpiType::ncmpiType NcmpiType::getTypeClass() const{
+ switch (myId) {
+ case NC_BYTE : return ncmpi_BYTE;
+ case NC_UBYTE : return ncmpi_UBYTE;
+ case NC_CHAR : return ncmpi_CHAR;
+ case NC_SHORT : return ncmpi_SHORT;
+ case NC_USHORT : return ncmpi_USHORT;
+ case NC_INT : return ncmpi_INT;
+ case NC_UINT : return ncmpi_UINT;
+ case NC_INT64 : return ncmpi_INT64;
+ case NC_UINT64 : return ncmpi_UINT64;
+ case NC_FLOAT : return ncmpi_FLOAT;
+ case NC_DOUBLE : return ncmpi_DOUBLE;
+ default:
+ // this is a user defined type
+ // establish its type class, ie whether it is: NC_VLEN, NC_OPAQUE, NC_ENUM, or NC_COMPOUND.
+ char* name=NULL;
+ MPI_Offset* sizep=NULL;
+ nc_type* base_nc_typep=NULL;
+ MPI_Offset* nfieldsp=NULL;
+ int classp;
+ ncmpiCheck(ncmpi_inq_user_type(groupId,myId,name,sizep,base_nc_typep,nfieldsp,&classp),__FILE__,__LINE__);
+ return static_cast<ncmpiType>(classp);
+ }
+}
+
+// The type class returned as a string.
+string NcmpiType::getTypeClassName() const{
+ ncmpiType typeClass=getTypeClass();
+ switch (typeClass) {
+ case ncmpi_BYTE : return string("ncmpi_BYTE");
+ case ncmpi_UBYTE : return string("ncmpi_UBYTE");
+ case ncmpi_CHAR : return string("ncmpi_CHAR");
+ case ncmpi_SHORT : return string("ncmpi_SHORT");
+ case ncmpi_USHORT : return string("ncmpi_USHORT");
+ case ncmpi_INT : return string("ncmpi_INT");
+ case ncmpi_UINT : return string("ncmpi_UINT");
+ case ncmpi_INT64 : return string("ncmpi_INT64");
+ case ncmpi_UINT64 : return string("ncmpi_UINT64");
+ case ncmpi_FLOAT : return string("ncmpi_FLOAT");
+ case ncmpi_DOUBLE : return string("ncmpi_DOUBLE");
+ case ncmpi_STRING : return string("ncmpi_STRING");
+ case ncmpi_VLEN : return string("ncmpi_VLEN");
+ case ncmpi_OPAQUE : return string("ncmpi_OPAQUE");
+ case ncmpi_ENUM : return string("ncmpi_ENUM");
+ case ncmpi_COMPOUND: return string("ncmpi_COMPOUND");
+ }
+ // we never get here!
+ return "Dummy";
+}
diff --git a/src/libcxx/ncmpiType.h b/src/libcxx/ncmpiType.h
new file mode 100644
index 0000000..932d9fe
--- /dev/null
+++ b/src/libcxx/ncmpiType.h
@@ -0,0 +1,157 @@
+#include <string>
+#include <pnetcdf.h>
+
+#ifndef NcmpiTypeClass
+#define NcmpiTypeClass
+
+
+namespace PnetCDF
+{
+ class NcmpiGroup; // forward declaration to avoid cyclic reference.
+
+ /*! Base class inherited by NcOpaque, NcVlen, NcCompound and NcEnum classes. */
+ class NcmpiType
+ {
+
+ public:
+
+ /*!
+ List of netCDF types that can be represented.
+ The enumeration list contains the complete set of netCDF variable types. In addition, the type NC_TYPE
+ is included. This enables the user to instantiate a netCDF type object without explcitly needing to know
+ it precise type.
+ */
+ enum ncmpiType
+ {
+ ncmpi_BYTE = NC_BYTE, //!< signed 1 byte integer
+ ncmpi_CHAR = NC_CHAR, //!< ISO/ASCII character
+ ncmpi_SHORT = NC_SHORT, //!< signed 2 byte integer
+ ncmpi_INT = NC_INT, //!< signed 4 byte integer
+ ncmpi_FLOAT = NC_FLOAT, //!< single precision floating point number
+ ncmpi_DOUBLE = NC_DOUBLE, //!< double precision floating point number
+ ncmpi_UBYTE = NC_UBYTE, //!< unsigned 1 byte int
+ ncmpi_USHORT = NC_USHORT, //!< unsigned 2-byte int
+ ncmpi_UINT = NC_UINT, //!< unsigned 4-byte int
+ ncmpi_INT64 = NC_INT64, //!< signed 8-byte int
+ ncmpi_UINT64 = NC_UINT64, //!< unsigned 8-byte int
+
+ // PnetCDF does not support types below
+ ncmpi_STRING = NC_STRING, //!< string
+ ncmpi_VLEN = NC_VLEN, //!< "NcVlen type"
+ ncmpi_OPAQUE = NC_OPAQUE, //!< "NcOpaque type"
+ ncmpi_ENUM = NC_ENUM, //!< "NcEnum type"
+ ncmpi_COMPOUND = NC_COMPOUND //!< "NcCompound type"
+ };
+
+ /*! Constructor generates a \ref isNull "null object". */
+ NcmpiType();
+
+ /*!
+ Constructor for a non-global type.
+ This object describes the "essential" information for all netCDF types required by NcmpiVar, NcmpiAtt objects.
+ New netCDF types can be added using the appropriate "add" method in the NcmpiGroup object.
+ \param grp Parent NcmpiGroup object.
+ \param name Name of this type.
+ */
+ NcmpiType(const PnetCDF::NcmpiGroup& grp, const std::string& name);
+
+
+ /*!
+ Constructor for a non-global type.
+ This object describes the "essential" information for all netCDF types required by NcmpiVar, NcmpiAtt objects.
+ New netCDF types can be added using the appropriate "add" method in the NcmpiGroup object.
+ \param grp Parent NcmpiGroup object.
+ \param id type id
+ */
+ NcmpiType(const PnetCDF::NcmpiGroup& grp, nc_type id);
+
+ /*!
+ Constructor for a global type
+ This object describes the "essential" information for a netCDF global type.
+ \param id type id
+ */
+ NcmpiType(nc_type id);
+
+ /*! The copy constructor. */
+ NcmpiType(const NcmpiType& rhs);
+
+ /*! destructor */
+ virtual ~NcmpiType() {}
+
+ /*! equivalence operator */
+ bool operator==(const NcmpiType&) const;
+
+ /*! != operator */
+ bool operator!=(const NcmpiType &) const;
+
+ // accessors to private data.
+ /*! The netCDF Id of this type. */
+ nc_type getId() const {return myId;}
+
+ /*! Gets parent group. For an atomic type, returns a Null object.*/
+ PnetCDF::NcmpiGroup getParentGroup() const;
+
+ /*!
+ The name of this type. For atomic types, the CDL type names are returned. These are as follows:
+ - NcmpiByte String returned is "byte".
+ - NcmpiUbyte String returned is "ubyte".
+ - NcmpiChar String returned is "char".
+ - NcmpiShort String returned is "short".
+ - NcmpiUshort String returned is "ushort".
+ - NcmpiInt String returned is "int".
+ - NcmpiUint String returned is "uint".
+ - NcmpiInt64 String returned is "int64".
+ - NcmpiUint64 String returned is "uint64".
+ - NcmpiFloat String returned is "float".
+ - NcmpiDouble String returned is "double".
+ */
+ std::string getName() const;
+
+ /*!
+ The size in bytes.
+ This function will work on any type, including atomic and any user defined type, whether
+ compound, opaque, enumeration, or variable length array.
+ */
+ MPI_Offset getSize() const;
+
+ /*!
+ The type class returned as enumeration type.
+ Valid for all types, whether atomic or user-defined. User-defined types are returned as one of the following
+ enumeration types: ncmpi_VLEN, ncmpi_OPAQUE, ncmpi_ENUM, or ncmpi_COMPOUND.
+ */
+ ncmpiType getTypeClass() const;
+
+ /*!
+ Return a string containing the name of the enumerated type. (ie one of the following strings:
+ "ncmpi_BYTE", "ncmpi_CHAR", "ncmpi_SHORT", "ncmpi_INT", "ncmpi_FLOAT", "ncmpi_DOUBLE", "ncmpi_UBYTE", "ncmpi_USHORT",
+ "ncmpi_UINT", "ncmpi_INT64", "ncmpi_UINT64", "ncmpi_STRING", "ncmpi_VLEN", "ncmpi_OPAQUE", "ncmpi_ENUM", "ncmpi_COMPOUND"
+ */
+ std::string getTypeClassName() const;
+
+ /*! Returns true if this object is null (i.e. it has no contents); otherwise returns false. */
+ bool isNull() const {return nullObject;}
+
+ /*! comparator operator */
+ friend bool operator<(const NcmpiType& lhs,const NcmpiType& rhs);
+
+ /*! comparator operator */
+ friend bool operator>(const NcmpiType& lhs,const NcmpiType& rhs);
+
+ protected:
+
+ /*! assignment operator */
+ NcmpiType& operator=(const NcmpiType& rhs);
+
+ bool nullObject;
+
+ /*! the type Id */
+ nc_type myId;
+
+ /*! the group Id */
+ int groupId;
+
+ };
+
+}
+#endif
+
diff --git a/src/libcxx/ncmpiUbyte.cpp b/src/libcxx/ncmpiUbyte.cpp
new file mode 100644
index 0000000..debe553
--- /dev/null
+++ b/src/libcxx/ncmpiUbyte.cpp
@@ -0,0 +1,22 @@
+#include "ncmpiUbyte.h"
+#include <pnetcdf.h>
+using namespace PnetCDF;
+
+// create an instance of NcmpiUbyte called PnetCDF::ncmpiUbyte
+namespace PnetCDF {
+ NcmpiUbyte ncmpiUbyte;
+}
+
+// constructor
+NcmpiUbyte::NcmpiUbyte() : NcmpiType(NC_UBYTE){
+}
+
+NcmpiUbyte::~NcmpiUbyte() {
+}
+
+
+// equivalence operator
+bool NcmpiUbyte::operator==(const NcmpiUbyte & rhs) {
+ // simply check the netCDF id.
+ return myId == rhs.myId;
+}
diff --git a/src/libcxx/ncmpiUbyte.h b/src/libcxx/ncmpiUbyte.h
new file mode 100644
index 0000000..3361351
--- /dev/null
+++ b/src/libcxx/ncmpiUbyte.h
@@ -0,0 +1,28 @@
+#include "ncmpiType.h"
+
+#ifndef NcmpiUbyteClass
+#define NcmpiUbyteClass
+
+namespace PnetCDF
+{
+
+ /*! Class represents a netCDF atomic Ubyte type. */
+ class NcmpiUbyte : public NcmpiType
+ {
+ public:
+
+ /*! equivalence operator */
+ bool operator==(const NcmpiUbyte & rhs);
+
+ /*! destructor */
+ ~NcmpiUbyte();
+
+ /*! Constructor */
+ NcmpiUbyte();
+ };
+
+ /*! A global instance of the NcmpiUbyte class within the netCDF namespace. */
+ extern NcmpiUbyte ncmpiUbyte;
+
+}
+#endif
diff --git a/src/libcxx/ncmpiUint.cpp b/src/libcxx/ncmpiUint.cpp
new file mode 100644
index 0000000..14bf349
--- /dev/null
+++ b/src/libcxx/ncmpiUint.cpp
@@ -0,0 +1,22 @@
+#include "ncmpiUint.h"
+#include <pnetcdf.h>
+using namespace PnetCDF;
+
+// create an instance of NcmpiUint called PnetCDF::ncmpiUint
+namespace PnetCDF {
+ NcmpiUint ncmpiUint;
+}
+
+// constructor
+NcmpiUint::NcmpiUint() : NcmpiType(NC_UINT){
+}
+
+NcmpiUint::~NcmpiUint() {
+}
+
+
+// equivalence operator
+bool NcmpiUint::operator==(const NcmpiUint & rhs) {
+ // simply check the netCDF id.
+ return myId == rhs.myId;
+}
diff --git a/src/libcxx/ncmpiUint.h b/src/libcxx/ncmpiUint.h
new file mode 100644
index 0000000..2098ebf
--- /dev/null
+++ b/src/libcxx/ncmpiUint.h
@@ -0,0 +1,28 @@
+#include "ncmpiType.h"
+
+#ifndef NcmpiUintClass
+#define NcmpiUintClass
+
+namespace PnetCDF
+{
+
+ /*! Class represents a netCDF atomic Uint type. */
+ class NcmpiUint : public NcmpiType
+ {
+ public:
+
+ /*! equivalence operator */
+ bool operator==(const NcmpiUint & rhs);
+
+ /*! destructor */
+ ~NcmpiUint();
+
+ /*! Constructor */
+ NcmpiUint();
+ };
+
+ /*! A global instance of the NcmpiUint class within the netCDF namespace. */
+ extern NcmpiUint ncmpiUint;
+
+}
+#endif
diff --git a/src/libcxx/ncmpiUint64.cpp b/src/libcxx/ncmpiUint64.cpp
new file mode 100644
index 0000000..11074c8
--- /dev/null
+++ b/src/libcxx/ncmpiUint64.cpp
@@ -0,0 +1,22 @@
+#include "ncmpiUint64.h"
+#include <pnetcdf.h>
+using namespace PnetCDF;
+
+// create an instance of NcmpiUint64 called PnetCDF::ncmpiUint64
+namespace PnetCDF {
+ NcmpiUint64 ncmpiUint64;
+}
+
+// constructor
+NcmpiUint64::NcmpiUint64() : NcmpiType(NC_UINT64){
+}
+
+NcmpiUint64::~NcmpiUint64() {
+}
+
+
+// equivalence operator
+bool NcmpiUint64::operator==(const NcmpiUint64 & rhs) {
+ // simply check the netCDF id.
+ return myId == rhs.myId;
+}
diff --git a/src/libcxx/ncmpiUint64.h b/src/libcxx/ncmpiUint64.h
new file mode 100644
index 0000000..5581815
--- /dev/null
+++ b/src/libcxx/ncmpiUint64.h
@@ -0,0 +1,28 @@
+#include "ncmpiType.h"
+
+#ifndef NcmpiUint64Class
+#define NcmpiUint64Class
+
+namespace PnetCDF
+{
+
+ /*! Class represents a netCDF atomic Uint64 type.*/
+ class NcmpiUint64 : public NcmpiType
+ {
+ public:
+
+ /*! equivalence operator */
+ bool operator==(const NcmpiUint64 & rhs);
+
+ /*! destructor */
+ ~NcmpiUint64();
+
+ /*! Constructor */
+ NcmpiUint64();
+ };
+
+ /*! A global instance of the NcmpiUint64 class within the netCDF namespace. */
+ extern NcmpiUint64 ncmpiUint64;
+
+}
+#endif
diff --git a/src/libcxx/ncmpiUshort.cpp b/src/libcxx/ncmpiUshort.cpp
new file mode 100644
index 0000000..80de2ab
--- /dev/null
+++ b/src/libcxx/ncmpiUshort.cpp
@@ -0,0 +1,22 @@
+#include "ncmpiUshort.h"
+#include <pnetcdf.h>
+using namespace PnetCDF;
+
+// create an instance of NcmpiUshort called PnetCDF::ncmpiUshort
+namespace PnetCDF {
+ NcmpiUshort ncmpiUshort;
+}
+
+// constructor
+NcmpiUshort::NcmpiUshort() : NcmpiType(NC_USHORT){
+}
+
+NcmpiUshort::~NcmpiUshort() {
+}
+
+
+// equivalence operator
+bool NcmpiUshort::operator==(const NcmpiUshort & rhs) {
+ // simply check the netCDF id.
+ return myId == rhs.myId;
+}
diff --git a/src/libcxx/ncmpiUshort.h b/src/libcxx/ncmpiUshort.h
new file mode 100644
index 0000000..dfffb21
--- /dev/null
+++ b/src/libcxx/ncmpiUshort.h
@@ -0,0 +1,28 @@
+#include "ncmpiType.h"
+
+#ifndef NcmpiUshortClass
+#define NcmpiUshortClass
+
+namespace PnetCDF
+{
+
+ /*! Class represents a netCDF atomic Ushort type. */
+ class NcmpiUshort : public NcmpiType
+ {
+ public:
+
+ /*! equivalence operator */
+ bool operator==(const NcmpiUshort & rhs);
+
+ /*! destructor */
+ ~NcmpiUshort();
+
+ /*! Constructor */
+ NcmpiUshort();
+ };
+
+ // declare that the class instance ncmpiUshort is known by all....
+ extern NcmpiUshort ncmpiUshort;
+
+}
+#endif
diff --git a/src/libcxx/ncmpiVar.cpp b/src/libcxx/ncmpiVar.cpp
new file mode 100644
index 0000000..5e82abf
--- /dev/null
+++ b/src/libcxx/ncmpiVar.cpp
@@ -0,0 +1,3289 @@
+#include "ncmpiVarAtt.h"
+#include "ncmpiDim.h"
+#include "ncmpiVar.h"
+#include "ncmpiGroup.h"
+#include "ncmpiCheck.h"
+#include "ncmpiException.h"
+#include<pnetcdf.h>
+using namespace std;
+using namespace PnetCDF::exceptions;
+
+namespace PnetCDF {
+ // Global comparator operator ==============
+ // comparator operator
+ bool operator<(const NcmpiVar& lhs,const NcmpiVar& rhs)
+ {
+ return false;
+ }
+
+ // comparator operator
+ bool operator>(const NcmpiVar& lhs,const NcmpiVar& rhs)
+ {
+ return true;
+ }
+}
+
+using namespace PnetCDF;
+
+// assignment operator
+NcmpiVar& NcmpiVar::operator=(const NcmpiVar & rhs)
+{
+ nullObject = rhs.nullObject;
+ myId = rhs.myId;
+ groupId = rhs.groupId;
+ return *this;
+}
+
+// The copy constructor.
+NcmpiVar::NcmpiVar(const NcmpiVar& rhs) :
+ nullObject(rhs.nullObject),
+ myId(rhs.myId),
+ groupId(rhs.groupId)
+{}
+
+
+// equivalence operator
+bool NcmpiVar::operator==(const NcmpiVar & rhs) const
+{
+ // simply check the netCDF id.
+ return (myId == rhs.myId);
+}
+
+// != operator
+bool NcmpiVar::operator!=(const NcmpiVar & rhs) const
+{
+ return !(*this == rhs);
+}
+
+/////////////////
+
+// Constructors and intialization
+
+/////////////////
+
+// Constructor generates a null object.
+NcmpiVar::NcmpiVar() : nullObject(true) {}
+
+// Constructor for a variable (must already exist in the netCDF file.)
+NcmpiVar::NcmpiVar (const NcmpiGroup& grp, const int& varId) :
+ nullObject (false),
+ myId (varId),
+ groupId(grp.getId())
+{}
+
+
+
+// Gets parent group.
+NcmpiGroup NcmpiVar::getParentGroup() const {
+ return NcmpiGroup(groupId);
+}
+
+
+// Get the variable id.
+int NcmpiVar::getId() const {return myId;}
+
+//////////////////////
+
+// Information about the variable type
+
+/////////////////////
+
+
+// Gets the NcmpiType object with a given name.
+NcmpiType NcmpiVar::getType() const {
+
+ // if this variable has not been defined, return a NULL type
+ if(isNull()) return NcmpiType();
+
+ // first get the typeid
+ nc_type xtypep;
+ ncmpiCheck(ncmpi_inq_vartype(groupId,myId,&xtypep),__FILE__,__LINE__);
+
+ if(xtypep == ncmpiByte.getId() ) return ncmpiByte;
+ if(xtypep == ncmpiUbyte.getId() ) return ncmpiUbyte;
+ if(xtypep == ncmpiChar.getId() ) return ncmpiChar;
+ if(xtypep == ncmpiShort.getId() ) return ncmpiShort;
+ if(xtypep == ncmpiUshort.getId() ) return ncmpiUshort;
+ if(xtypep == ncmpiInt.getId() ) return ncmpiInt;
+ if(xtypep == ncmpiUint.getId() ) return ncmpiUint;
+ if(xtypep == ncmpiInt64.getId() ) return ncmpiInt64;
+ if(xtypep == ncmpiUint64.getId() ) return ncmpiUint64;
+ if(xtypep == ncmpiFloat.getId() ) return ncmpiFloat;
+ if(xtypep == ncmpiDouble.getId() ) return ncmpiDouble;
+
+ multimap<string,NcmpiType>::const_iterator it;
+ multimap<string,NcmpiType> types(NcmpiGroup(groupId).getTypes(NcmpiGroup::ParentsAndCurrent));
+ for(it=types.begin(); it!=types.end(); it++) {
+ if(it->second.getId() == xtypep) return it->second;
+ }
+ // we will never reach here
+ return true;
+}
+
+
+
+
+
+
+
+
+/////////////////
+
+// Information about Dimensions
+
+/////////////////
+
+
+// Gets the number of dimensions.
+int NcmpiVar::getDimCount() const
+{
+ // get the number of dimensions
+ int dimCount;
+ ncmpiCheck(ncmpi_inq_varndims(groupId,myId, &dimCount),__FILE__,__LINE__);
+ return dimCount;
+}
+
+// Gets the set of Ncdim objects.
+vector<NcmpiDim> NcmpiVar::getDims() const
+{
+ // get the number of dimensions
+ int dimCount = getDimCount();
+ // create a vector of dimensions.
+ vector<NcmpiDim> ncmpiDims;
+ if (dimCount){
+ vector<int> dimids(dimCount);
+ ncmpiCheck(ncmpi_inq_vardimid(groupId,myId, &dimids[0]),__FILE__,__LINE__);
+ ncmpiDims.reserve(dimCount);
+ for (int i=0; i<dimCount; i++){
+ NcmpiDim tmpDim(getParentGroup(),dimids[i]);
+ ncmpiDims.push_back(tmpDim);
+ }
+ }
+ return ncmpiDims;
+}
+
+
+// Gets the i'th NcmpiDim object.
+NcmpiDim NcmpiVar::getDim(int i) const
+{
+ vector<NcmpiDim> ncmpiDims = getDims();
+ if((size_t)i >= ncmpiDims.size() || i < 0) throw NcmpiException("Index out of range",__FILE__,__LINE__);
+ return ncmpiDims[i];
+}
+
+
+/////////////////
+
+// Information about Attributes
+
+/////////////////
+
+
+// Gets the number of attributes.
+int NcmpiVar::getAttCount() const
+{
+ // get the number of attributes
+ int attCount;
+ ncmpiCheck(ncmpi_inq_varnatts(groupId,myId, &attCount),__FILE__,__LINE__);
+ return attCount;
+}
+
+// Gets the set of attributes.
+map<string,NcmpiVarAtt> NcmpiVar::getAtts() const
+{
+ // get the number of attributes
+ int attCount = getAttCount();
+ // create a container of attributes.
+ map<string,NcmpiVarAtt> ncmpiAtts;
+ for (int i=0; i<attCount; i++){
+ NcmpiVarAtt tmpAtt(getParentGroup(),*this,i);
+ ncmpiAtts.insert(pair<const string,NcmpiVarAtt>(tmpAtt.getName(),tmpAtt));
+ }
+ return ncmpiAtts;
+}
+
+
+// Gets attribute by name.
+NcmpiVarAtt NcmpiVar::getAtt(const string& name) const
+{
+ map<string,NcmpiVarAtt> attributeList = getAtts();
+ map<string,NcmpiVarAtt>::iterator myIter;
+ myIter = attributeList.find(name);
+ if(myIter == attributeList.end()){
+ string msg("Attribute '"+name+"' not found");
+ throw NcmpiException(msg.c_str(),__FILE__,__LINE__);
+ }
+ return NcmpiVarAtt(myIter->second);
+}
+
+
+
+/////////////////////////
+
+
+// Creates a new NetCDF variable attribute or if already exisiting replaces it.
+NcmpiVarAtt NcmpiVar::putAtt(const string& name, const string& dataValues) const {
+ ncmpiCheckDefineMode(groupId);
+ ncmpiCheck(ncmpi_put_att_text(groupId,myId,name.c_str(),dataValues.size(),dataValues.c_str()),__FILE__,__LINE__);
+ // finally instantiate this attribute and return
+ return getAtt(name);
+}
+
+// Creates a new NetCDF variable attribute or if already exisiting replaces it.
+NcmpiVarAtt NcmpiVar::putAtt(const string& name, const NcmpiType& type, MPI_Offset len, const unsigned char* dataValues) const {
+ ncmpiCheckDefineMode(groupId);
+ NcmpiType::ncmpiType typeClass(type.getTypeClass());
+ if(typeClass == NcmpiType::ncmpi_VLEN || typeClass == NcmpiType::ncmpi_OPAQUE || typeClass == NcmpiType::ncmpi_ENUM || typeClass == NcmpiType::ncmpi_COMPOUND)
+ ncmpiCheck(ncmpi_put_att(groupId,myId,name.c_str(),type.getId(),len,dataValues),__FILE__,__LINE__);
+ else
+ ncmpiCheck(ncmpi_put_att_uchar(groupId,myId,name.c_str(),type.getId(),len,dataValues),__FILE__,__LINE__);
+ // finally instantiate this attribute and return
+ return getAtt(name);
+}
+
+
+// Creates a new NetCDF variable attribute or if already exisiting replaces it.
+NcmpiVarAtt NcmpiVar::putAtt(const string& name, const NcmpiType& type, MPI_Offset len, const signed char* dataValues) const {
+ ncmpiCheckDefineMode(groupId);
+ NcmpiType::ncmpiType typeClass(type.getTypeClass());
+ if(typeClass == NcmpiType::ncmpi_VLEN || typeClass == NcmpiType::ncmpi_OPAQUE || typeClass == NcmpiType::ncmpi_ENUM || typeClass == NcmpiType::ncmpi_COMPOUND)
+ ncmpiCheck(ncmpi_put_att(groupId,myId,name.c_str(),type.getId(),len,dataValues),__FILE__,__LINE__);
+ else
+ ncmpiCheck(ncmpi_put_att_schar(groupId,myId,name.c_str(),type.getId(),len,dataValues),__FILE__,__LINE__);
+ // finally instantiate this attribute and return
+ return getAtt(name);
+}
+
+
+
+/////////////////////////////////
+// Creates a new NetCDF variable attribute or if already exisiting replaces it.
+NcmpiVarAtt NcmpiVar::putAtt(const string& name, const NcmpiType& type, short datumValue) const {
+ ncmpiCheckDefineMode(groupId);
+ NcmpiType::ncmpiType typeClass(type.getTypeClass());
+ if(typeClass == NcmpiType::ncmpi_VLEN || typeClass == NcmpiType::ncmpi_OPAQUE || typeClass == NcmpiType::ncmpi_ENUM || typeClass == NcmpiType::ncmpi_COMPOUND)
+ ncmpiCheck(ncmpi_put_att(groupId,myId,name.c_str(),type.getId(),1,&datumValue),__FILE__,__LINE__);
+ else
+ ncmpiCheck(ncmpi_put_att_short(groupId,myId,name.c_str(),type.getId(),1,&datumValue),__FILE__,__LINE__);
+ // finally instantiate this attribute and return
+ return getAtt(name);
+}
+
+
+// Creates a new NetCDF variable attribute or if already exisiting replaces it.
+NcmpiVarAtt NcmpiVar::putAtt(const string& name, const NcmpiType& type, int datumValue) const {
+ ncmpiCheckDefineMode(groupId);
+ NcmpiType::ncmpiType typeClass(type.getTypeClass());
+ if(typeClass == NcmpiType::ncmpi_VLEN || typeClass == NcmpiType::ncmpi_OPAQUE || typeClass == NcmpiType::ncmpi_ENUM || typeClass == NcmpiType::ncmpi_COMPOUND)
+ ncmpiCheck(ncmpi_put_att(groupId,myId,name.c_str(),type.getId(),1,&datumValue),__FILE__,__LINE__);
+ else
+ ncmpiCheck(ncmpi_put_att_int(groupId,myId,name.c_str(),type.getId(),1,&datumValue),__FILE__,__LINE__);
+ // finally instantiate this attribute and return
+ return getAtt(name);
+}
+
+// Creates a new NetCDF variable attribute or if already exisiting replaces it.
+NcmpiVarAtt NcmpiVar::putAtt(const string& name, const NcmpiType& type, long datumValue) const {
+ ncmpiCheckDefineMode(groupId);
+ NcmpiType::ncmpiType typeClass(type.getTypeClass());
+ if(typeClass == NcmpiType::ncmpi_VLEN || typeClass == NcmpiType::ncmpi_OPAQUE || typeClass == NcmpiType::ncmpi_ENUM || typeClass == NcmpiType::ncmpi_COMPOUND)
+ ncmpiCheck(ncmpi_put_att(groupId,myId,name.c_str(),type.getId(),1,&datumValue),__FILE__,__LINE__);
+ else
+ ncmpiCheck(ncmpi_put_att_long(groupId,myId,name.c_str(),type.getId(),1,&datumValue),__FILE__,__LINE__);
+ // finally instantiate this attribute and return
+ return getAtt(name);
+}
+
+// Creates a new NetCDF variable attribute or if already exisiting replaces it.
+NcmpiVarAtt NcmpiVar::putAtt(const string& name, const NcmpiType& type, float datumValue) const {
+ ncmpiCheckDefineMode(groupId);
+ NcmpiType::ncmpiType typeClass(type.getTypeClass());
+ if(typeClass == NcmpiType::ncmpi_VLEN || typeClass == NcmpiType::ncmpi_OPAQUE || typeClass == NcmpiType::ncmpi_ENUM || typeClass == NcmpiType::ncmpi_COMPOUND)
+ ncmpiCheck(ncmpi_put_att(groupId,myId,name.c_str(),type.getId(),1,&datumValue),__FILE__,__LINE__);
+ else
+ ncmpiCheck(ncmpi_put_att_float(groupId,myId,name.c_str(),type.getId(),1,&datumValue),__FILE__,__LINE__);
+ // finally instantiate this attribute and return
+ return getAtt(name);
+}
+
+
+// Creates a new NetCDF variable attribute or if already exisiting replaces it.
+NcmpiVarAtt NcmpiVar::putAtt(const string& name, const NcmpiType& type, double datumValue) const {
+ ncmpiCheckDefineMode(groupId);
+ NcmpiType::ncmpiType typeClass(type.getTypeClass());
+ if(typeClass == NcmpiType::ncmpi_VLEN || typeClass == NcmpiType::ncmpi_OPAQUE || typeClass == NcmpiType::ncmpi_ENUM || typeClass == NcmpiType::ncmpi_COMPOUND)
+ ncmpiCheck(ncmpi_put_att(groupId,myId,name.c_str(),type.getId(),1,&datumValue),__FILE__,__LINE__);
+ else
+ ncmpiCheck(ncmpi_put_att_double(groupId,myId,name.c_str(),type.getId(),1,&datumValue),__FILE__,__LINE__);
+ // finally instantiate this attribute and return
+ return getAtt(name);
+}
+
+
+// Creates a new NetCDF variable attribute or if already exisiting replaces it.
+NcmpiVarAtt NcmpiVar::putAtt(const string& name, const NcmpiType& type, unsigned short datumValue) const {
+ ncmpiCheckDefineMode(groupId);
+ NcmpiType::ncmpiType typeClass(type.getTypeClass());
+ if(typeClass == NcmpiType::ncmpi_VLEN || typeClass == NcmpiType::ncmpi_OPAQUE || typeClass == NcmpiType::ncmpi_ENUM || typeClass == NcmpiType::ncmpi_COMPOUND)
+ ncmpiCheck(ncmpi_put_att(groupId,myId,name.c_str(),type.getId(),1,&datumValue),__FILE__,__LINE__);
+ else
+ ncmpiCheck(ncmpi_put_att_ushort(groupId,myId,name.c_str(),type.getId(),1,&datumValue),__FILE__,__LINE__);
+ // finally instantiate this attribute and return
+ return getAtt(name);
+}
+
+// Creates a new NetCDF variable attribute or if already exisiting replaces it.
+NcmpiVarAtt NcmpiVar::putAtt(const string& name, const NcmpiType& type, unsigned int datumValue) const {
+ ncmpiCheckDefineMode(groupId);
+ NcmpiType::ncmpiType typeClass(type.getTypeClass());
+ if(typeClass == NcmpiType::ncmpi_VLEN || typeClass == NcmpiType::ncmpi_OPAQUE || typeClass == NcmpiType::ncmpi_ENUM || typeClass == NcmpiType::ncmpi_COMPOUND)
+ ncmpiCheck(ncmpi_put_att(groupId,myId,name.c_str(),type.getId(),1,&datumValue),__FILE__,__LINE__);
+ else
+ ncmpiCheck(ncmpi_put_att_uint(groupId,myId,name.c_str(),type.getId(),1,&datumValue),__FILE__,__LINE__);
+ // finally instantiate this attribute and return
+ return getAtt(name);
+}
+
+// Creates a new NetCDF variable attribute or if already exisiting replaces it.
+NcmpiVarAtt NcmpiVar::putAtt(const string& name, const NcmpiType& type, long long datumValue) const {
+ ncmpiCheckDefineMode(groupId);
+ NcmpiType::ncmpiType typeClass(type.getTypeClass());
+ if(typeClass == NcmpiType::ncmpi_VLEN || typeClass == NcmpiType::ncmpi_OPAQUE || typeClass == NcmpiType::ncmpi_ENUM || typeClass == NcmpiType::ncmpi_COMPOUND)
+ ncmpiCheck(ncmpi_put_att(groupId,myId,name.c_str(),type.getId(),1,&datumValue),__FILE__,__LINE__);
+ else
+ ncmpiCheck(ncmpi_put_att_longlong(groupId,myId,name.c_str(),type.getId(),1,&datumValue),__FILE__,__LINE__);
+ // finally instantiate this attribute and return
+ return getAtt(name);
+}
+
+
+// Creates a new NetCDF variable attribute or if already exisiting replaces it.
+NcmpiVarAtt NcmpiVar::putAtt(const string& name, const NcmpiType& type, unsigned long long datumValue) const {
+ ncmpiCheckDefineMode(groupId);
+ NcmpiType::ncmpiType typeClass(type.getTypeClass());
+ if(typeClass == NcmpiType::ncmpi_VLEN || typeClass == NcmpiType::ncmpi_OPAQUE || typeClass == NcmpiType::ncmpi_ENUM || typeClass == NcmpiType::ncmpi_COMPOUND)
+ ncmpiCheck(ncmpi_put_att(groupId,myId,name.c_str(),type.getId(),1,&datumValue),__FILE__,__LINE__);
+ else
+ ncmpiCheck(ncmpi_put_att_ulonglong(groupId,myId,name.c_str(),type.getId(),1,&datumValue),__FILE__,__LINE__);
+ // finally instantiate this attribute and return
+ return getAtt(name);
+}
+
+
+/////////////////////////////////
+
+
+
+
+
+
+
+
+
+
+
+// Creates a new NetCDF variable attribute or if already exisiting replaces it.
+NcmpiVarAtt NcmpiVar::putAtt(const string& name, const NcmpiType& type, MPI_Offset len, const short* dataValues) const {
+ ncmpiCheckDefineMode(groupId);
+ NcmpiType::ncmpiType typeClass(type.getTypeClass());
+ if(typeClass == NcmpiType::ncmpi_VLEN || typeClass == NcmpiType::ncmpi_OPAQUE || typeClass == NcmpiType::ncmpi_ENUM || typeClass == NcmpiType::ncmpi_COMPOUND)
+ ncmpiCheck(ncmpi_put_att(groupId,myId,name.c_str(),type.getId(),len,dataValues),__FILE__,__LINE__);
+ else
+ ncmpiCheck(ncmpi_put_att_short(groupId,myId,name.c_str(),type.getId(),len,dataValues),__FILE__,__LINE__);
+ // finally instantiate this attribute and return
+ return getAtt(name);
+}
+
+
+// Creates a new NetCDF variable attribute or if already exisiting replaces it.
+NcmpiVarAtt NcmpiVar::putAtt(const string& name, const NcmpiType& type, MPI_Offset len, const int* dataValues) const {
+ ncmpiCheckDefineMode(groupId);
+ NcmpiType::ncmpiType typeClass(type.getTypeClass());
+ if(typeClass == NcmpiType::ncmpi_VLEN || typeClass == NcmpiType::ncmpi_OPAQUE || typeClass == NcmpiType::ncmpi_ENUM || typeClass == NcmpiType::ncmpi_COMPOUND)
+ ncmpiCheck(ncmpi_put_att(groupId,myId,name.c_str(),type.getId(),len,dataValues),__FILE__,__LINE__);
+ else
+ ncmpiCheck(ncmpi_put_att_int(groupId,myId,name.c_str(),type.getId(),len,dataValues),__FILE__,__LINE__);
+ // finally instantiate this attribute and return
+ return getAtt(name);
+}
+
+// Creates a new NetCDF variable attribute or if already exisiting replaces it.
+NcmpiVarAtt NcmpiVar::putAtt(const string& name, const NcmpiType& type, MPI_Offset len, const long* dataValues) const {
+ ncmpiCheckDefineMode(groupId);
+ NcmpiType::ncmpiType typeClass(type.getTypeClass());
+ if(typeClass == NcmpiType::ncmpi_VLEN || typeClass == NcmpiType::ncmpi_OPAQUE || typeClass == NcmpiType::ncmpi_ENUM || typeClass == NcmpiType::ncmpi_COMPOUND)
+ ncmpiCheck(ncmpi_put_att(groupId,myId,name.c_str(),type.getId(),len,dataValues),__FILE__,__LINE__);
+ else
+ ncmpiCheck(ncmpi_put_att_long(groupId,myId,name.c_str(),type.getId(),len,dataValues),__FILE__,__LINE__);
+ // finally instantiate this attribute and return
+ return getAtt(name);
+}
+
+// Creates a new NetCDF variable attribute or if already exisiting replaces it.
+NcmpiVarAtt NcmpiVar::putAtt(const string& name, const NcmpiType& type, MPI_Offset len, const float* dataValues) const {
+ ncmpiCheckDefineMode(groupId);
+ NcmpiType::ncmpiType typeClass(type.getTypeClass());
+ if(typeClass == NcmpiType::ncmpi_VLEN || typeClass == NcmpiType::ncmpi_OPAQUE || typeClass == NcmpiType::ncmpi_ENUM || typeClass == NcmpiType::ncmpi_COMPOUND)
+ ncmpiCheck(ncmpi_put_att(groupId,myId,name.c_str(),type.getId(),len,dataValues),__FILE__,__LINE__);
+ else
+ ncmpiCheck(ncmpi_put_att_float(groupId,myId,name.c_str(),type.getId(),len,dataValues),__FILE__,__LINE__);
+ // finally instantiate this attribute and return
+ return getAtt(name);
+}
+
+
+// Creates a new NetCDF variable attribute or if already exisiting replaces it.
+NcmpiVarAtt NcmpiVar::putAtt(const string& name, const NcmpiType& type, MPI_Offset len, const double* dataValues) const {
+ ncmpiCheckDefineMode(groupId);
+ NcmpiType::ncmpiType typeClass(type.getTypeClass());
+ if(typeClass == NcmpiType::ncmpi_VLEN || typeClass == NcmpiType::ncmpi_OPAQUE || typeClass == NcmpiType::ncmpi_ENUM || typeClass == NcmpiType::ncmpi_COMPOUND)
+ ncmpiCheck(ncmpi_put_att(groupId,myId,name.c_str(),type.getId(),len,dataValues),__FILE__,__LINE__);
+ else
+ ncmpiCheck(ncmpi_put_att_double(groupId,myId,name.c_str(),type.getId(),len,dataValues),__FILE__,__LINE__);
+ // finally instantiate this attribute and return
+ return getAtt(name);
+}
+
+
+// Creates a new NetCDF variable attribute or if already exisiting replaces it.
+NcmpiVarAtt NcmpiVar::putAtt(const string& name, const NcmpiType& type, MPI_Offset len, const unsigned short* dataValues) const {
+ ncmpiCheckDefineMode(groupId);
+ NcmpiType::ncmpiType typeClass(type.getTypeClass());
+ if(typeClass == NcmpiType::ncmpi_VLEN || typeClass == NcmpiType::ncmpi_OPAQUE || typeClass == NcmpiType::ncmpi_ENUM || typeClass == NcmpiType::ncmpi_COMPOUND)
+ ncmpiCheck(ncmpi_put_att(groupId,myId,name.c_str(),type.getId(),len,dataValues),__FILE__,__LINE__);
+ else
+ ncmpiCheck(ncmpi_put_att_ushort(groupId,myId,name.c_str(),type.getId(),len,dataValues),__FILE__,__LINE__);
+ // finally instantiate this attribute and return
+ return getAtt(name);
+}
+
+// Creates a new NetCDF variable attribute or if already exisiting replaces it.
+NcmpiVarAtt NcmpiVar::putAtt(const string& name, const NcmpiType& type, MPI_Offset len, const unsigned int* dataValues) const {
+ ncmpiCheckDefineMode(groupId);
+ NcmpiType::ncmpiType typeClass(type.getTypeClass());
+ if(typeClass == NcmpiType::ncmpi_VLEN || typeClass == NcmpiType::ncmpi_OPAQUE || typeClass == NcmpiType::ncmpi_ENUM || typeClass == NcmpiType::ncmpi_COMPOUND)
+ ncmpiCheck(ncmpi_put_att(groupId,myId,name.c_str(),type.getId(),len,dataValues),__FILE__,__LINE__);
+ else
+ ncmpiCheck(ncmpi_put_att_uint(groupId,myId,name.c_str(),type.getId(),len,dataValues),__FILE__,__LINE__);
+ // finally instantiate this attribute and return
+ return getAtt(name);
+}
+
+// Creates a new NetCDF variable attribute or if already exisiting replaces it.
+NcmpiVarAtt NcmpiVar::putAtt(const string& name, const NcmpiType& type, MPI_Offset len, const long long* dataValues) const {
+ ncmpiCheckDefineMode(groupId);
+ NcmpiType::ncmpiType typeClass(type.getTypeClass());
+ if(typeClass == NcmpiType::ncmpi_VLEN || typeClass == NcmpiType::ncmpi_OPAQUE || typeClass == NcmpiType::ncmpi_ENUM || typeClass == NcmpiType::ncmpi_COMPOUND)
+ ncmpiCheck(ncmpi_put_att(groupId,myId,name.c_str(),type.getId(),len,dataValues),__FILE__,__LINE__);
+ else
+ ncmpiCheck(ncmpi_put_att_longlong(groupId,myId,name.c_str(),type.getId(),len,dataValues),__FILE__,__LINE__);
+ // finally instantiate this attribute and return
+ return getAtt(name);
+}
+
+
+// Creates a new NetCDF variable attribute or if already exisiting replaces it.
+NcmpiVarAtt NcmpiVar::putAtt(const string& name, const NcmpiType& type, MPI_Offset len, const unsigned long long* dataValues) const {
+ ncmpiCheckDefineMode(groupId);
+ NcmpiType::ncmpiType typeClass(type.getTypeClass());
+ if(typeClass == NcmpiType::ncmpi_VLEN || typeClass == NcmpiType::ncmpi_OPAQUE || typeClass == NcmpiType::ncmpi_ENUM || typeClass == NcmpiType::ncmpi_COMPOUND)
+ ncmpiCheck(ncmpi_put_att(groupId,myId,name.c_str(),type.getId(),len,dataValues),__FILE__,__LINE__);
+ else
+ ncmpiCheck(ncmpi_put_att_ulonglong(groupId,myId,name.c_str(),type.getId(),len,dataValues),__FILE__,__LINE__);
+ // finally instantiate this attribute and return
+ return getAtt(name);
+}
+
+
+// Creates a new NetCDF variable attribute or if already exisiting replaces it.
+NcmpiVarAtt NcmpiVar::putAtt(const string& name, const NcmpiType& type, MPI_Offset len, const void* dataValues) const {
+ ncmpiCheckDefineMode(groupId);
+ ncmpiCheck(ncmpi_put_att(groupId,myId ,name.c_str(),type.getId(),len,dataValues),__FILE__,__LINE__);
+ // finally instantiate this attribute and return
+ return getAtt(name);
+}
+
+
+
+
+////////////////////
+
+// Other Basic variable info
+
+////////////////////
+
+// The name of this variable.
+string NcmpiVar::getName() const{
+ char charName[NC_MAX_NAME+1];
+ ncmpiCheck(ncmpi_inq_varname(groupId, myId, charName),__FILE__,__LINE__);
+ return string(charName);
+}
+
+
+////////////////////
+
+// Chunking details
+
+////////////////////
+
+
+// Sets chunking parameters.
+void NcmpiVar::setChunking(ChunkMode chunkMode, vector<MPI_Offset>& chunkSizes) const {
+ MPI_Offset *chunkSizesPtr = chunkSizes.empty() ? 0 : &chunkSizes[0];
+ ncmpiCheck(ncmpi_def_var_chunking(groupId,myId,static_cast<int> (chunkMode), chunkSizesPtr),__FILE__,__LINE__);
+}
+
+
+// Gets the chunking parameters
+void NcmpiVar::getChunkingParameters(ChunkMode& chunkMode, vector<MPI_Offset>& chunkSizes) const {
+ int chunkModeInt;
+ chunkSizes.resize(getDimCount());
+ MPI_Offset *chunkSizesPtr = chunkSizes.empty() ? 0 : &chunkSizes[0];
+ ncmpiCheck(ncmpi_inq_var_chunking(groupId,myId, &chunkModeInt, chunkSizesPtr),__FILE__,__LINE__);
+ chunkMode = static_cast<ChunkMode> (chunkModeInt);
+}
+
+
+
+
+////////////////////
+
+// Fill details
+
+////////////////////
+
+
+// Sets the fill parameters
+void NcmpiVar::setFill(bool fillMode, void* fillValue) const {
+ // If fillMode is enabled, check that fillValue has a legal pointer.
+ // if(fillMode && fillValue == NULL)
+ // throw NcmpiException("FillMode was set to zero but fillValue has invalid pointer",__FILE__,__LINE__);
+
+ ncmpiCheck(ncmpi_def_var_fill(groupId,myId,static_cast<int> (!fillMode),fillValue),__FILE__,__LINE__);
+}
+
+// Sets the fill parameters
+/*
+void NcmpiVar::setFill(bool fillMode, const void* fillValue) const {
+ setFill(fillMode,const_cast<void*>(fillValue));
+}
+*/
+
+
+// Gets the fill parameters
+void NcmpiVar::getFillModeParameters(bool& fillMode, void* fillValue)const{
+
+ int fillModeInt;
+ ncmpiCheck(ncmpi_inq_var_fill(groupId,myId,&fillModeInt,fillValue),__FILE__,__LINE__);
+ fillMode= static_cast<bool> (fillModeInt == 0);
+}
+
+/* fill variable */
+void NcmpiVar::fillRec(MPI_Offset recno) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_fill_var_rec(groupId, myId, recno),__FILE__,__LINE__);
+}
+
+
+////////////////////
+
+// Compression details
+
+////////////////////
+
+
+// Sets the compression parameters
+void NcmpiVar::setCompression(bool enableShuffleFilter, bool enableDeflateFilter, int deflateLevel) const {
+
+ // Check that the deflate level is legal
+ if(enableDeflateFilter & (deflateLevel < 0 || deflateLevel >9))
+ throw NcmpiException("The deflateLevel must be set between 0 and 9.",__FILE__,__LINE__);
+
+ ncmpiCheck(ncmpi_def_var_deflate(groupId,myId,
+ static_cast<int> (enableShuffleFilter),
+ static_cast<int> (enableDeflateFilter),
+ deflateLevel),__FILE__,__LINE__);
+}
+
+
+// Gets the compression parameters
+void NcmpiVar::getCompressionParameters(bool& shuffleFilterEnabled, bool& deflateFilterEnabled, int& deflateLevel) const {
+
+ int enableShuffleFilterInt;
+ int enableDeflateFilterInt;
+ ncmpiCheck(ncmpi_inq_var_deflate(groupId,myId,
+ &enableShuffleFilterInt,
+ &enableDeflateFilterInt,
+ &deflateLevel),__FILE__,__LINE__);
+ shuffleFilterEnabled = static_cast<bool> (enableShuffleFilterInt);
+ deflateFilterEnabled = static_cast<bool> (enableDeflateFilterInt);
+}
+
+
+
+////////////////////
+
+// Endianness details
+
+////////////////////
+
+
+// Sets the endianness of the variable.
+void NcmpiVar::setEndianness(EndianMode endianMode) const {
+
+ ncmpiCheck(ncmpi_def_var_endian(groupId,myId,static_cast<int> (endianMode)),__FILE__,__LINE__);
+}
+
+
+// Gets the endianness of the variable.
+NcmpiVar::EndianMode NcmpiVar::getEndianness() const {
+
+ int endianInt;
+ ncmpiCheck(ncmpi_inq_var_endian(groupId,myId,&endianInt),__FILE__,__LINE__);
+ return static_cast<EndianMode> (endianInt);
+}
+
+
+
+////////////////////
+
+// Checksum details
+
+////////////////////
+
+
+// Sets the checksum parameters of a variable.
+void NcmpiVar::setChecksum(ChecksumMode checksumMode) const {
+ ncmpiCheck(ncmpi_def_var_fletcher32(groupId,myId,static_cast<int> (checksumMode)),__FILE__,__LINE__);
+}
+
+
+// Gets the checksum parameters of the variable.
+NcmpiVar::ChecksumMode NcmpiVar::getChecksum() const {
+ int checksumInt;
+ ncmpiCheck(ncmpi_inq_var_fletcher32(groupId,myId,&checksumInt),__FILE__,__LINE__);
+ return static_cast<ChecksumMode> (checksumInt);
+}
+
+
+
+
+////////////////////
+
+// renaming the variable
+
+////////////////////
+
+void NcmpiVar::rename( const string& newname ) const
+{
+ ncmpiCheck(ncmpi_rename_var(groupId,myId,newname.c_str()),__FILE__,__LINE__);
+}
+
+
+
+
+
+////////////////////
+
+// data writing (independent I/O APIs)
+
+////////////////////
+
+// Writes the entire data into the netCDF variable.
+void NcmpiVar::putVar(const char* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_var_text(groupId, myId,dataValues),__FILE__,__LINE__);
+}
+// Writes the entire data into the netCDF variable.
+void NcmpiVar::putVar(const unsigned char* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_var_uchar(groupId, myId,dataValues),__FILE__,__LINE__);
+}
+// Writes the entire data into the netCDF variable.
+void NcmpiVar::putVar(const signed char* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_var_schar(groupId, myId,dataValues),__FILE__,__LINE__);
+}
+// Writes the entire data into the netCDF variable.
+void NcmpiVar::putVar(const short* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_var_short(groupId, myId,dataValues),__FILE__,__LINE__);
+}
+// Writes the entire data into the netCDF variable.
+void NcmpiVar::putVar(const int* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_var_int(groupId, myId,dataValues),__FILE__,__LINE__);
+}
+// Writes the entire data into the netCDF variable.
+void NcmpiVar::putVar(const long* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_var_long(groupId, myId,dataValues),__FILE__,__LINE__);
+}
+// Writes the entire data into the netCDF variable.
+void NcmpiVar::putVar(const float* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_var_float(groupId, myId,dataValues),__FILE__,__LINE__);
+}
+// Writes the entire data into the netCDF variable.
+void NcmpiVar::putVar(const double* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_var_double(groupId, myId,dataValues),__FILE__,__LINE__);
+}
+// Writes the entire data into the netCDF variable.
+void NcmpiVar::putVar(const unsigned short* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_var_ushort(groupId, myId,dataValues),__FILE__,__LINE__);
+}
+// Writes the entire data into the netCDF variable.
+void NcmpiVar::putVar(const unsigned int* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_var_uint(groupId, myId,dataValues),__FILE__,__LINE__);
+}
+// Writes the entire data into the netCDF variable.
+void NcmpiVar::putVar(const long long* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_var_longlong(groupId, myId,dataValues),__FILE__,__LINE__);
+}
+// Writes the entire data into the netCDF variable.
+void NcmpiVar::putVar(const unsigned long long* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_var_ulonglong(groupId, myId,dataValues),__FILE__,__LINE__);
+}
+// Writes the entire data into the netCDF variable with no data conversion.
+void NcmpiVar::putVar(const void* dataValues, MPI_Offset bufcount, MPI_Datatype buftype) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_var(groupId, myId,dataValues, bufcount, buftype),__FILE__,__LINE__);
+}
+
+
+///////////////////
+
+// Writes a single datum value into the netCDF variable.
+void NcmpiVar::putVar(const vector<MPI_Offset>& index, const unsigned char* datumValue) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_var1_uchar(groupId, myId,&index[0],datumValue),__FILE__,__LINE__);
+}
+// Writes a single datum value into the netCDF variable.
+void NcmpiVar::putVar(const vector<MPI_Offset>& index, const signed char* datumValue) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_var1_schar(groupId, myId,&index[0],datumValue),__FILE__,__LINE__);
+}
+// Writes a single datum value into the netCDF variable.
+void NcmpiVar::putVar(const vector<MPI_Offset>& index, const short datumValue) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_var1_short(groupId, myId,&index[0],&datumValue),__FILE__,__LINE__);
+}
+// Writes a single datum value into the netCDF variable.
+void NcmpiVar::putVar(const vector<MPI_Offset>& index, const int datumValue) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_var1_int(groupId, myId,&index[0],&datumValue),__FILE__,__LINE__);
+}
+// Writes a single datum value into the netCDF variable.
+void NcmpiVar::putVar(const vector<MPI_Offset>& index, const long datumValue) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_var1_long(groupId, myId,&index[0],&datumValue),__FILE__,__LINE__);
+}
+// Writes a single datum value into the netCDF variable.
+void NcmpiVar::putVar(const vector<MPI_Offset>& index, const float datumValue) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_var1_float(groupId, myId,&index[0],&datumValue),__FILE__,__LINE__);
+}
+// Writes a single datum value into the netCDF variable.
+void NcmpiVar::putVar(const vector<MPI_Offset>& index, const double datumValue) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_var1_double(groupId, myId,&index[0],&datumValue),__FILE__,__LINE__);
+}
+// Writes a single datum value into the netCDF variable.
+void NcmpiVar::putVar(const vector<MPI_Offset>& index, const unsigned short datumValue) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_var1_ushort(groupId, myId,&index[0],&datumValue),__FILE__,__LINE__);
+}
+// Writes a single datum value into the netCDF variable.
+void NcmpiVar::putVar(const vector<MPI_Offset>& index, const unsigned int datumValue) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_var1_uint(groupId, myId,&index[0],&datumValue),__FILE__,__LINE__);
+}
+// Writes a single datum value into the netCDF variable.
+void NcmpiVar::putVar(const vector<MPI_Offset>& index, const long long datumValue) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_var1_longlong(groupId, myId,&index[0],&datumValue),__FILE__,__LINE__);
+}
+// Writes a single datum value into the netCDF variable.
+void NcmpiVar::putVar(const vector<MPI_Offset>& index, const unsigned long long datumValue) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_var1_ulonglong(groupId, myId,&index[0],&datumValue),__FILE__,__LINE__);
+}
+// Writes a single datum value into the netCDF variable with no data conversion.
+void NcmpiVar::putVar(const vector<MPI_Offset>& index, const void* datumValue, MPI_Offset bufcount, MPI_Datatype buftype) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_var1(groupId, myId,&index[0],datumValue, bufcount, buftype),__FILE__,__LINE__);
+}
+
+
+////////////////////
+
+// Writes an array of values into the netCDF variable.
+void NcmpiVar::putVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const char* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_vara_text(groupId, myId,&startp[0],&countp[0],dataValues),__FILE__,__LINE__);
+}
+// Writes an array of values into the netCDF variable.
+void NcmpiVar::putVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const unsigned char* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_vara_uchar(groupId, myId,&startp[0],&countp[0],dataValues),__FILE__,__LINE__);
+}
+// Writes an array of values into the netCDF variable.
+void NcmpiVar::putVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const signed char* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_vara_schar(groupId, myId,&startp[0],&countp[0],dataValues),__FILE__,__LINE__);
+}
+// Writes an array of values into the netCDF variable.
+void NcmpiVar::putVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const short* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_vara_short(groupId, myId,&startp[0],&countp[0],dataValues),__FILE__,__LINE__);
+}
+// Writes an array of values into the netCDF variable.
+void NcmpiVar::putVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const int* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_vara_int(groupId, myId,&startp[0],&countp[0],dataValues),__FILE__,__LINE__);
+}
+// Writes an array of values into the netCDF variable.
+void NcmpiVar::putVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const long* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_vara_long(groupId, myId,&startp[0],&countp[0],dataValues),__FILE__,__LINE__);
+}
+// Writes an array of values into the netCDF variable.
+void NcmpiVar::putVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const float* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_vara_float(groupId, myId,&startp[0],&countp[0],dataValues),__FILE__,__LINE__);
+}
+// Writes an array of values into the netCDF variable.
+void NcmpiVar::putVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const double* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_vara_double(groupId, myId,&startp[0],&countp[0],dataValues),__FILE__,__LINE__);
+}
+// Writes an array of values into the netCDF variable.
+void NcmpiVar::putVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const unsigned short* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_vara_ushort(groupId, myId,&startp[0],&countp[0],dataValues),__FILE__,__LINE__);
+}
+// Writes an array of values into the netCDF variable.
+void NcmpiVar::putVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const unsigned int* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_vara_uint(groupId, myId,&startp[0],&countp[0],dataValues),__FILE__,__LINE__);
+}
+// Writes an array of values into the netCDF variable.
+void NcmpiVar::putVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const long long* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_vara_longlong(groupId, myId,&startp[0],&countp[0],dataValues),__FILE__,__LINE__);
+}
+// Writes an array of values into the netCDF variable.
+void NcmpiVar::putVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const unsigned long long* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_vara_ulonglong(groupId, myId,&startp[0],&countp[0],dataValues),__FILE__,__LINE__);
+}
+// Writes an array of values into the netCDF variable with no data conversion.
+void NcmpiVar::putVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const void* dataValues, MPI_Offset bufcount, MPI_Datatype buftype) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_vara(groupId, myId,&startp[0],&countp[0],dataValues, bufcount, buftype),__FILE__,__LINE__);
+}
+
+////////////////////
+
+// Writes a set of subsampled array values into the netCDF variable.
+void NcmpiVar::putVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const char* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_vars_text(groupId, myId,&startp[0],&countp[0],&stridep[0],dataValues),__FILE__,__LINE__);
+}
+// Writes a set of subsampled array values into the netCDF variable.
+void NcmpiVar::putVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const unsigned char* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_vars_uchar(groupId, myId,&startp[0],&countp[0],&stridep[0],dataValues),__FILE__,__LINE__);
+}
+// Writes a set of subsampled array values into the netCDF variable.
+void NcmpiVar::putVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const signed char* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_vars_schar(groupId, myId,&startp[0],&countp[0],&stridep[0],dataValues),__FILE__,__LINE__);
+}
+// Writes a set of subsampled array values into the netCDF variable.
+void NcmpiVar::putVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const short* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_vars_short(groupId, myId,&startp[0],&countp[0],&stridep[0],dataValues),__FILE__,__LINE__);
+}
+// Writes a set of subsampled array values into the netCDF variable.
+void NcmpiVar::putVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const int* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_vars_int(groupId, myId,&startp[0],&countp[0],&stridep[0],dataValues),__FILE__,__LINE__);
+}
+// Writes a set of subsampled array values into the netCDF variable.
+void NcmpiVar::putVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const long* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_vars_long(groupId, myId,&startp[0],&countp[0],&stridep[0],dataValues),__FILE__,__LINE__);
+}
+// Writes a set of subsampled array values into the netCDF variable.
+void NcmpiVar::putVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const float* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_vars_float(groupId, myId,&startp[0],&countp[0],&stridep[0],dataValues),__FILE__,__LINE__);
+}
+// Writes a set of subsampled array values into the netCDF variable.
+void NcmpiVar::putVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const double* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_vars_double(groupId, myId,&startp[0],&countp[0],&stridep[0],dataValues),__FILE__,__LINE__);
+}
+// Writes a set of subsampled array values into the netCDF variable.
+void NcmpiVar::putVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const unsigned short* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_vars_ushort(groupId, myId,&startp[0],&countp[0],&stridep[0],dataValues),__FILE__,__LINE__);
+}
+// Writes a set of subsampled array values into the netCDF variable.
+void NcmpiVar::putVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const unsigned int* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_vars_uint(groupId, myId,&startp[0],&countp[0],&stridep[0],dataValues),__FILE__,__LINE__);
+}
+// Writes a set of subsampled array values into the netCDF variable.
+void NcmpiVar::putVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const long long* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_vars_longlong(groupId, myId,&startp[0],&countp[0],&stridep[0],dataValues),__FILE__,__LINE__);
+}
+// Writes a set of subsampled array values into the netCDF variable.
+void NcmpiVar::putVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const unsigned long long* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_vars_ulonglong(groupId, myId,&startp[0],&countp[0],&stridep[0],dataValues),__FILE__,__LINE__);
+}
+// Writes a set of subsampled array values into the netCDF variable with no data conversion.
+void NcmpiVar::putVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const void* dataValues, MPI_Offset bufcount, MPI_Datatype buftype) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_vars(groupId, myId,&startp[0],&countp[0],&stridep[0],dataValues, bufcount, buftype),__FILE__,__LINE__);
+}
+
+////////////////////
+
+// Writes a mapped array section of values into the netCDF variable.
+void NcmpiVar::putVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const vector<MPI_Offset>& imapp, const char* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_varm_text(groupId, myId,&startp[0],&countp[0],&stridep[0],&imapp[0],dataValues),__FILE__,__LINE__);
+}
+// Writes a mapped array section of values into the netCDF variable.
+void NcmpiVar::putVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const vector<MPI_Offset>& imapp, const unsigned char* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_varm_uchar(groupId, myId,&startp[0],&countp[0],&stridep[0],&imapp[0],dataValues),__FILE__,__LINE__);
+}
+// Writes a mapped array section of values into the netCDF variable.
+void NcmpiVar::putVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const vector<MPI_Offset>& imapp, const signed char* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_varm_schar(groupId, myId,&startp[0],&countp[0],&stridep[0],&imapp[0],dataValues),__FILE__,__LINE__);
+}
+// Writes a mapped array section of values into the netCDF variable.
+void NcmpiVar::putVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const vector<MPI_Offset>& imapp, const short* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_varm_short(groupId, myId,&startp[0],&countp[0],&stridep[0],&imapp[0],dataValues),__FILE__,__LINE__);
+}
+// Writes a mapped array section of values into the netCDF variable.
+void NcmpiVar::putVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const vector<MPI_Offset>& imapp, const int* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_varm_int(groupId, myId,&startp[0],&countp[0],&stridep[0],&imapp[0],dataValues),__FILE__,__LINE__);
+}
+// Writes a mapped array section of values into the netCDF variable.
+void NcmpiVar::putVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const vector<MPI_Offset>& imapp, const long* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_varm_long(groupId, myId,&startp[0],&countp[0],&stridep[0],&imapp[0],dataValues),__FILE__,__LINE__);
+}
+// Writes a mapped array section of values into the netCDF variable.
+void NcmpiVar::putVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const vector<MPI_Offset>& imapp, const float* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_varm_float(groupId, myId,&startp[0],&countp[0],&stridep[0],&imapp[0],dataValues),__FILE__,__LINE__);
+}
+// Writes a mapped array section of values into the netCDF variable.
+void NcmpiVar::putVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const vector<MPI_Offset>& imapp, const double* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_varm_double(groupId, myId,&startp[0],&countp[0],&stridep[0],&imapp[0],dataValues),__FILE__,__LINE__);
+}
+// Writes a mapped array section of values into the netCDF variable.
+void NcmpiVar::putVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const vector<MPI_Offset>& imapp, const unsigned short* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_varm_ushort(groupId, myId,&startp[0],&countp[0],&stridep[0],&imapp[0],dataValues),__FILE__,__LINE__);
+}
+// Writes a mapped array section of values into the netCDF variable.
+void NcmpiVar::putVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const vector<MPI_Offset>& imapp, const unsigned int* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_varm_uint(groupId, myId,&startp[0],&countp[0],&stridep[0],&imapp[0],dataValues),__FILE__,__LINE__);
+}
+// Writes a mapped array section of values into the netCDF variable.
+void NcmpiVar::putVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const vector<MPI_Offset>& imapp, const long long* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_varm_longlong(groupId, myId,&startp[0],&countp[0],&stridep[0],&imapp[0],dataValues),__FILE__,__LINE__);
+}
+// Writes a mapped array section of values into the netCDF variable.
+void NcmpiVar::putVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const vector<MPI_Offset>& imapp, const unsigned long long* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_varm_ulonglong(groupId, myId,&startp[0],&countp[0],&stridep[0],&imapp[0],dataValues),__FILE__,__LINE__);
+}
+// Writes a mapped array section of values into the netCDF variable with no data conversion.
+void NcmpiVar::putVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const vector<MPI_Offset>& imapp, const void* dataValues, MPI_Offset bufcount, MPI_Datatype buftype) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_varm(groupId, myId,&startp[0],&countp[0],&stridep[0],&imapp[0],dataValues, bufcount, buftype),__FILE__,__LINE__);
+}
+
+////////////////////
+
+// data writing (collective data mode)
+
+////////////////////
+
+// Writes the entire data into the netCDF variable.
+void NcmpiVar::putVar_all(const char* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_var_text_all(groupId, myId,dataValues),__FILE__,__LINE__);
+}
+// Writes the entire data into the netCDF variable.
+void NcmpiVar::putVar_all(const unsigned char* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_var_uchar_all(groupId, myId,dataValues),__FILE__,__LINE__);
+}
+// Writes the entire data into the netCDF variable.
+void NcmpiVar::putVar_all(const signed char* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_var_schar_all(groupId, myId,dataValues),__FILE__,__LINE__);
+}
+// Writes the entire data into the netCDF variable.
+void NcmpiVar::putVar_all(const short* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_var_short_all(groupId, myId,dataValues),__FILE__,__LINE__);
+}
+// Writes the entire data into the netCDF variable.
+void NcmpiVar::putVar_all(const int* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_var_int_all(groupId, myId,dataValues),__FILE__,__LINE__);
+}
+// Writes the entire data into the netCDF variable.
+void NcmpiVar::putVar_all(const long* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_var_long_all(groupId, myId,dataValues),__FILE__,__LINE__);
+}
+// Writes the entire data into the netCDF variable.
+void NcmpiVar::putVar_all(const float* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_var_float_all(groupId, myId,dataValues),__FILE__,__LINE__);
+}
+// Writes the entire data into the netCDF variable.
+void NcmpiVar::putVar_all(const double* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_var_double_all(groupId, myId,dataValues),__FILE__,__LINE__);
+}
+// Writes the entire data into the netCDF variable.
+void NcmpiVar::putVar_all(const unsigned short* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_var_ushort_all(groupId, myId,dataValues),__FILE__,__LINE__);
+}
+// Writes the entire data into the netCDF variable.
+void NcmpiVar::putVar_all(const unsigned int* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_var_uint_all(groupId, myId,dataValues),__FILE__,__LINE__);
+}
+// Writes the entire data into the netCDF variable.
+void NcmpiVar::putVar_all(const long long* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_var_longlong_all(groupId, myId,dataValues),__FILE__,__LINE__);
+}
+// Writes the entire data into the netCDF variable.
+void NcmpiVar::putVar_all(const unsigned long long* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_var_ulonglong_all(groupId, myId,dataValues),__FILE__,__LINE__);
+}
+// Writes the entire data into the netCDF variable with no data conversion.
+void NcmpiVar::putVar_all(const void* dataValues, MPI_Offset bufcount, MPI_Datatype buftype) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_var_all(groupId, myId,dataValues, bufcount, buftype),__FILE__,__LINE__);
+}
+
+///////////////////
+
+// Writes a single datum value into the netCDF variable.
+void NcmpiVar::putVar_all(const vector<MPI_Offset>& index, const unsigned char* datumValue) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_var1_uchar_all(groupId, myId,&index[0],datumValue),__FILE__,__LINE__);
+}
+// Writes a single datum value into the netCDF variable.
+void NcmpiVar::putVar_all(const vector<MPI_Offset>& index, const signed char* datumValue) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_var1_schar_all(groupId, myId,&index[0],datumValue),__FILE__,__LINE__);
+}
+// Writes a single datum value into the netCDF variable.
+void NcmpiVar::putVar_all(const vector<MPI_Offset>& index, const short datumValue) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_var1_short_all(groupId, myId,&index[0],&datumValue),__FILE__,__LINE__);
+}
+// Writes a single datum value into the netCDF variable.
+void NcmpiVar::putVar_all(const vector<MPI_Offset>& index, const int datumValue) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_var1_int_all(groupId, myId,&index[0],&datumValue),__FILE__,__LINE__);
+}
+// Writes a single datum value into the netCDF variable.
+void NcmpiVar::putVar_all(const vector<MPI_Offset>& index, const long datumValue) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_var1_long_all(groupId, myId,&index[0],&datumValue),__FILE__,__LINE__);
+}
+// Writes a single datum value into the netCDF variable.
+void NcmpiVar::putVar_all(const vector<MPI_Offset>& index, const float datumValue) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_var1_float_all(groupId, myId,&index[0],&datumValue),__FILE__,__LINE__);
+}
+// Writes a single datum value into the netCDF variable.
+void NcmpiVar::putVar_all(const vector<MPI_Offset>& index, const double datumValue) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_var1_double_all(groupId, myId,&index[0],&datumValue),__FILE__,__LINE__);
+}
+// Writes a single datum value into the netCDF variable.
+void NcmpiVar::putVar_all(const vector<MPI_Offset>& index, const unsigned short datumValue) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_var1_ushort_all(groupId, myId,&index[0],&datumValue),__FILE__,__LINE__);
+}
+// Writes a single datum value into the netCDF variable.
+void NcmpiVar::putVar_all(const vector<MPI_Offset>& index, const unsigned int datumValue) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_var1_uint_all(groupId, myId,&index[0],&datumValue),__FILE__,__LINE__);
+}
+// Writes a single datum value into the netCDF variable.
+void NcmpiVar::putVar_all(const vector<MPI_Offset>& index, const long long datumValue) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_var1_longlong_all(groupId, myId,&index[0],&datumValue),__FILE__,__LINE__);
+}
+// Writes a single datum value into the netCDF variable.
+void NcmpiVar::putVar_all(const vector<MPI_Offset>& index, const unsigned long long datumValue) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_var1_ulonglong_all(groupId, myId,&index[0],&datumValue),__FILE__,__LINE__);
+}
+// Writes a single datum value into the netCDF variable with no data conversion.
+void NcmpiVar::putVar_all(const vector<MPI_Offset>& index, const void* datumValue, MPI_Offset bufcount, MPI_Datatype buftype) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_var1_all(groupId, myId,&index[0],datumValue, bufcount, buftype),__FILE__,__LINE__);
+}
+
+
+////////////////////
+
+// Writes an array of values into the netCDF variable.
+void NcmpiVar::putVar_all(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const char* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_vara_text_all(groupId, myId,&startp[0],&countp[0],dataValues),__FILE__,__LINE__);
+}
+// Writes an array of values into the netCDF variable.
+void NcmpiVar::putVar_all(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const unsigned char* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_vara_uchar_all(groupId, myId,&startp[0],&countp[0],dataValues),__FILE__,__LINE__);
+}
+// Writes an array of values into the netCDF variable.
+void NcmpiVar::putVar_all(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const signed char* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_vara_schar_all(groupId, myId,&startp[0],&countp[0],dataValues),__FILE__,__LINE__);
+}
+// Writes an array of values into the netCDF variable.
+void NcmpiVar::putVar_all(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const short* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_vara_short_all(groupId, myId,&startp[0],&countp[0],dataValues),__FILE__,__LINE__);
+}
+// Writes an array of values into the netCDF variable.
+void NcmpiVar::putVar_all(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const int* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_vara_int_all(groupId, myId,&startp[0],&countp[0],dataValues),__FILE__,__LINE__);
+}
+// Writes an array of values into the netCDF variable.
+void NcmpiVar::putVar_all(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const long* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_vara_long_all(groupId, myId,&startp[0],&countp[0],dataValues),__FILE__,__LINE__);
+}
+// Writes an array of values into the netCDF variable.
+void NcmpiVar::putVar_all(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const float* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_vara_float_all(groupId, myId,&startp[0],&countp[0],dataValues),__FILE__,__LINE__);
+}
+// Writes an array of values into the netCDF variable.
+void NcmpiVar::putVar_all(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const double* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_vara_double_all(groupId, myId,&startp[0],&countp[0],dataValues),__FILE__,__LINE__);
+}
+// Writes an array of values into the netCDF variable.
+void NcmpiVar::putVar_all(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const unsigned short* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_vara_ushort_all(groupId, myId,&startp[0],&countp[0],dataValues),__FILE__,__LINE__);
+}
+// Writes an array of values into the netCDF variable.
+void NcmpiVar::putVar_all(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const unsigned int* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_vara_uint_all(groupId, myId,&startp[0],&countp[0],dataValues),__FILE__,__LINE__);
+}
+// Writes an array of values into the netCDF variable.
+void NcmpiVar::putVar_all(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const long long* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_vara_longlong_all(groupId, myId,&startp[0],&countp[0],dataValues),__FILE__,__LINE__);
+}
+// Writes an array of values into the netCDF variable.
+void NcmpiVar::putVar_all(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const unsigned long long* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_vara_ulonglong_all(groupId, myId,&startp[0],&countp[0],dataValues),__FILE__,__LINE__);
+}
+// Writes an array of values into the netCDF variable with no data conversion.
+void NcmpiVar::putVar_all(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const void* dataValues, MPI_Offset bufcount, MPI_Datatype buftype) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_vara_all(groupId, myId,&startp[0],&countp[0],dataValues, bufcount, buftype),__FILE__,__LINE__);
+}
+
+////////////////////
+
+// Writes a set of subsampled array values into the netCDF variable.
+void NcmpiVar::putVar_all(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const char* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_vars_text_all(groupId, myId,&startp[0],&countp[0],&stridep[0],dataValues),__FILE__,__LINE__);
+}
+// Writes a set of subsampled array values into the netCDF variable.
+void NcmpiVar::putVar_all(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const unsigned char* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_vars_uchar_all(groupId, myId,&startp[0],&countp[0],&stridep[0],dataValues),__FILE__,__LINE__);
+}
+// Writes a set of subsampled array values into the netCDF variable.
+void NcmpiVar::putVar_all(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const signed char* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_vars_schar_all(groupId, myId,&startp[0],&countp[0],&stridep[0],dataValues),__FILE__,__LINE__);
+}
+// Writes a set of subsampled array values into the netCDF variable.
+void NcmpiVar::putVar_all(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const short* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_vars_short_all(groupId, myId,&startp[0],&countp[0],&stridep[0],dataValues),__FILE__,__LINE__);
+}
+// Writes a set of subsampled array values into the netCDF variable.
+void NcmpiVar::putVar_all(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const int* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_vars_int_all(groupId, myId,&startp[0],&countp[0],&stridep[0],dataValues),__FILE__,__LINE__);
+}
+// Writes a set of subsampled array values into the netCDF variable.
+void NcmpiVar::putVar_all(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const long* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_vars_long_all(groupId, myId,&startp[0],&countp[0],&stridep[0],dataValues),__FILE__,__LINE__);
+}
+// Writes a set of subsampled array values into the netCDF variable.
+void NcmpiVar::putVar_all(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const float* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_vars_float_all(groupId, myId,&startp[0],&countp[0],&stridep[0],dataValues),__FILE__,__LINE__);
+}
+// Writes a set of subsampled array values into the netCDF variable.
+void NcmpiVar::putVar_all(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const double* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_vars_double_all(groupId, myId,&startp[0],&countp[0],&stridep[0],dataValues),__FILE__,__LINE__);
+}
+// Writes a set of subsampled array values into the netCDF variable.
+void NcmpiVar::putVar_all(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const unsigned short* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_vars_ushort_all(groupId, myId,&startp[0],&countp[0],&stridep[0],dataValues),__FILE__,__LINE__);
+}
+// Writes a set of subsampled array values into the netCDF variable.
+void NcmpiVar::putVar_all(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const unsigned int* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_vars_uint_all(groupId, myId,&startp[0],&countp[0],&stridep[0],dataValues),__FILE__,__LINE__);
+}
+// Writes a set of subsampled array values into the netCDF variable.
+void NcmpiVar::putVar_all(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const long long* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_vars_longlong_all(groupId, myId,&startp[0],&countp[0],&stridep[0],dataValues),__FILE__,__LINE__);
+}
+// Writes a set of subsampled array values into the netCDF variable.
+void NcmpiVar::putVar_all(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const unsigned long long* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_vars_ulonglong_all(groupId, myId,&startp[0],&countp[0],&stridep[0],dataValues),__FILE__,__LINE__);
+}
+// Writes a set of subsampled array values into the netCDF variable with no data conversion.
+void NcmpiVar::putVar_all(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const void* dataValues, MPI_Offset bufcount, MPI_Datatype buftype) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_vars_all(groupId, myId,&startp[0],&countp[0],&stridep[0],dataValues, bufcount, buftype),__FILE__,__LINE__);
+}
+
+////////////////////
+
+// Writes a mapped array section of values into the netCDF variable.
+void NcmpiVar::putVar_all(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const vector<MPI_Offset>& imapp, const char* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_varm_text_all(groupId, myId,&startp[0],&countp[0],&stridep[0],&imapp[0],dataValues),__FILE__,__LINE__);
+}
+// Writes a mapped array section of values into the netCDF variable.
+void NcmpiVar::putVar_all(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const vector<MPI_Offset>& imapp, const unsigned char* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_varm_uchar_all(groupId, myId,&startp[0],&countp[0],&stridep[0],&imapp[0],dataValues),__FILE__,__LINE__);
+}
+// Writes a mapped array section of values into the netCDF variable.
+void NcmpiVar::putVar_all(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const vector<MPI_Offset>& imapp, const signed char* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_varm_schar_all(groupId, myId,&startp[0],&countp[0],&stridep[0],&imapp[0],dataValues),__FILE__,__LINE__);
+}
+// Writes a mapped array section of values into the netCDF variable.
+void NcmpiVar::putVar_all(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const vector<MPI_Offset>& imapp, const short* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_varm_short_all(groupId, myId,&startp[0],&countp[0],&stridep[0],&imapp[0],dataValues),__FILE__,__LINE__);
+}
+// Writes a mapped array section of values into the netCDF variable.
+void NcmpiVar::putVar_all(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const vector<MPI_Offset>& imapp, const int* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_varm_int_all(groupId, myId,&startp[0],&countp[0],&stridep[0],&imapp[0],dataValues),__FILE__,__LINE__);
+}
+// Writes a mapped array section of values into the netCDF variable.
+void NcmpiVar::putVar_all(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const vector<MPI_Offset>& imapp, const long* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_varm_long_all(groupId, myId,&startp[0],&countp[0],&stridep[0],&imapp[0],dataValues),__FILE__,__LINE__);
+}
+// Writes a mapped array section of values into the netCDF variable.
+void NcmpiVar::putVar_all(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const vector<MPI_Offset>& imapp, const float* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_varm_float_all(groupId, myId,&startp[0],&countp[0],&stridep[0],&imapp[0],dataValues),__FILE__,__LINE__);
+}
+// Writes a mapped array section of values into the netCDF variable.
+void NcmpiVar::putVar_all(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const vector<MPI_Offset>& imapp, const double* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_varm_double_all(groupId, myId,&startp[0],&countp[0],&stridep[0],&imapp[0],dataValues),__FILE__,__LINE__);
+}
+// Writes a mapped array section of values into the netCDF variable.
+void NcmpiVar::putVar_all(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const vector<MPI_Offset>& imapp, const unsigned short* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_varm_ushort_all(groupId, myId,&startp[0],&countp[0],&stridep[0],&imapp[0],dataValues),__FILE__,__LINE__);
+}
+// Writes a mapped array section of values into the netCDF variable.
+void NcmpiVar::putVar_all(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const vector<MPI_Offset>& imapp, const unsigned int* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_varm_uint_all(groupId, myId,&startp[0],&countp[0],&stridep[0],&imapp[0],dataValues),__FILE__,__LINE__);
+}
+// Writes a mapped array section of values into the netCDF variable.
+void NcmpiVar::putVar_all(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const vector<MPI_Offset>& imapp, const long long* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_varm_longlong_all(groupId, myId,&startp[0],&countp[0],&stridep[0],&imapp[0],dataValues),__FILE__,__LINE__);
+}
+// Writes a mapped array section of values into the netCDF variable.
+void NcmpiVar::putVar_all(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const vector<MPI_Offset>& imapp, const unsigned long long* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_varm_ulonglong_all(groupId, myId,&startp[0],&countp[0],&stridep[0],&imapp[0],dataValues),__FILE__,__LINE__);
+}
+// Writes a mapped array section of values into the netCDF variable with no data conversion.
+void NcmpiVar::putVar_all(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const vector<MPI_Offset>& imapp, const void* dataValues, MPI_Offset bufcount, MPI_Datatype buftype) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_varm_all(groupId, myId,&startp[0],&countp[0],&stridep[0],&imapp[0],dataValues, bufcount, buftype),__FILE__,__LINE__);
+}
+
+////////////////////
+
+// Writes a list of subarrays into the netCDF variable. (independent I/O APIs)
+void NcmpiVar::putVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], const char* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_varn_text(groupId, myId, num, starts, counts, dataValues),__FILE__,__LINE__);
+}
+// Writes an array of values into the netCDF variable.
+void NcmpiVar::putVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], const unsigned char* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_varn_uchar(groupId, myId, num, starts, counts, dataValues),__FILE__,__LINE__);
+}
+// Writes an array of values into the netCDF variable.
+void NcmpiVar::putVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], const signed char* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_varn_schar(groupId, myId, num, starts, counts, dataValues),__FILE__,__LINE__);
+}
+// Writes an array of values into the netCDF variable.
+void NcmpiVar::putVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], const short* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_varn_short(groupId, myId, num, starts, counts, dataValues),__FILE__,__LINE__);
+}
+// Writes an array of values into the netCDF variable.
+void NcmpiVar::putVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], const int* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_varn_int(groupId, myId, num, starts, counts, dataValues),__FILE__,__LINE__);
+}
+// Writes an array of values into the netCDF variable.
+void NcmpiVar::putVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], const long* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_varn_long(groupId, myId, num, starts, counts, dataValues),__FILE__,__LINE__);
+}
+// Writes an array of values into the netCDF variable.
+void NcmpiVar::putVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], const float* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_varn_float(groupId, myId, num, starts, counts, dataValues),__FILE__,__LINE__);
+}
+// Writes an array of values into the netCDF variable.
+void NcmpiVar::putVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], const double* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_varn_double(groupId, myId, num, starts, counts, dataValues),__FILE__,__LINE__);
+}
+// Writes an array of values into the netCDF variable.
+void NcmpiVar::putVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], const unsigned short* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_varn_ushort(groupId, myId, num, starts, counts, dataValues),__FILE__,__LINE__);
+}
+// Writes an array of values into the netCDF variable.
+void NcmpiVar::putVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], const unsigned int* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_varn_uint(groupId, myId, num, starts, counts, dataValues),__FILE__,__LINE__);
+}
+// Writes an array of values into the netCDF variable.
+void NcmpiVar::putVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], const long long* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_varn_longlong(groupId, myId, num, starts, counts, dataValues),__FILE__,__LINE__);
+}
+// Writes an array of values into the netCDF variable.
+void NcmpiVar::putVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], const unsigned long long* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_varn_ulonglong(groupId, myId, num, starts, counts, dataValues),__FILE__,__LINE__);
+}
+// Writes an array of values into the netCDF variable with no data conversion.
+void NcmpiVar::putVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], const void* dataValues, MPI_Offset bufcount, MPI_Datatype buftype) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_varn(groupId, myId, num, starts, counts, dataValues, bufcount, buftype),__FILE__,__LINE__);
+}
+
+////////////////////
+
+// Writes a list of subarrays into the netCDF variable. (collective I/O APIs)
+void NcmpiVar::putVarn_all(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], const char* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_varn_text_all(groupId, myId, num, starts, counts, dataValues),__FILE__,__LINE__);
+}
+// Writes an array of values into the netCDF variable.
+void NcmpiVar::putVarn_all(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], const unsigned char* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_varn_uchar_all(groupId, myId, num, starts, counts, dataValues),__FILE__,__LINE__);
+}
+// Writes an array of values into the netCDF variable.
+void NcmpiVar::putVarn_all(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], const signed char* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_varn_schar_all(groupId, myId, num, starts, counts, dataValues),__FILE__,__LINE__);
+}
+// Writes an array of values into the netCDF variable.
+void NcmpiVar::putVarn_all(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], const short* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_varn_short_all(groupId, myId, num, starts, counts, dataValues),__FILE__,__LINE__);
+}
+// Writes an array of values into the netCDF variable.
+void NcmpiVar::putVarn_all(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], const int* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_varn_int_all(groupId, myId, num, starts, counts, dataValues),__FILE__,__LINE__);
+}
+// Writes an array of values into the netCDF variable.
+void NcmpiVar::putVarn_all(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], const long* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_varn_long_all(groupId, myId, num, starts, counts, dataValues),__FILE__,__LINE__);
+}
+// Writes an array of values into the netCDF variable.
+void NcmpiVar::putVarn_all(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], const float* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_varn_float_all(groupId, myId, num, starts, counts, dataValues),__FILE__,__LINE__);
+}
+// Writes an array of values into the netCDF variable.
+void NcmpiVar::putVarn_all(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], const double* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_varn_double_all(groupId, myId, num, starts, counts, dataValues),__FILE__,__LINE__);
+}
+// Writes an array of values into the netCDF variable.
+void NcmpiVar::putVarn_all(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], const unsigned short* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_varn_ushort_all(groupId, myId, num, starts, counts, dataValues),__FILE__,__LINE__);
+}
+// Writes an array of values into the netCDF variable.
+void NcmpiVar::putVarn_all(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], const unsigned int* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_varn_uint_all(groupId, myId, num, starts, counts, dataValues),__FILE__,__LINE__);
+}
+// Writes an array of values into the netCDF variable.
+void NcmpiVar::putVarn_all(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], const long long* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_varn_longlong_all(groupId, myId, num, starts, counts, dataValues),__FILE__,__LINE__);
+}
+// Writes an array of values into the netCDF variable.
+void NcmpiVar::putVarn_all(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], const unsigned long long* dataValues) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_varn_ulonglong_all(groupId, myId, num, starts, counts, dataValues),__FILE__,__LINE__);
+}
+// Writes an array of values into the netCDF variable with no data conversion.
+void NcmpiVar::putVarn_all(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], const void* dataValues, MPI_Offset bufcount, MPI_Datatype buftype) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_varn_all(groupId, myId, num, starts, counts, dataValues, bufcount, buftype),__FILE__,__LINE__);
+}
+
+////////////////////
+
+// Writes an array of values into the netCDF variable with filetype and buftype.
+void NcmpiVar::putVard(MPI_Datatype filetype, const void* dataValues, MPI_Offset bufcount, MPI_Datatype buftype) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_vard(groupId, myId, filetype, dataValues, bufcount, buftype),__FILE__,__LINE__);
+}
+
+void NcmpiVar::putVard_all(MPI_Datatype filetype, const void* dataValues, MPI_Offset bufcount, MPI_Datatype buftype) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_put_vard_all(groupId, myId, filetype, dataValues, bufcount, buftype),__FILE__,__LINE__);
+}
+
+////////////////////
+
+// Nonblocking data writing
+
+////////////////////
+
+// Writes the entire data into the netCDF variable.
+void NcmpiVar::iputVar(const char* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_iput_var_text(groupId, myId,dataValues, req),__FILE__,__LINE__);
+}
+// Writes the entire data into the netCDF variable.
+void NcmpiVar::iputVar(const unsigned char* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_iput_var_uchar(groupId, myId,dataValues, req),__FILE__,__LINE__);
+}
+// Writes the entire data into the netCDF variable.
+void NcmpiVar::iputVar(const signed char* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_iput_var_schar(groupId, myId,dataValues, req),__FILE__,__LINE__);
+}
+// Writes the entire data into the netCDF variable.
+void NcmpiVar::iputVar(const short* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_iput_var_short(groupId, myId,dataValues, req),__FILE__,__LINE__);
+}
+// Writes the entire data into the netCDF variable.
+void NcmpiVar::iputVar(const int* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_iput_var_int(groupId, myId,dataValues, req),__FILE__,__LINE__);
+}
+// Writes the entire data into the netCDF variable.
+void NcmpiVar::iputVar(const long* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_iput_var_long(groupId, myId,dataValues, req),__FILE__,__LINE__);
+}
+// Writes the entire data into the netCDF variable.
+void NcmpiVar::iputVar(const float* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_iput_var_float(groupId, myId,dataValues, req),__FILE__,__LINE__);
+}
+// Writes the entire data into the netCDF variable.
+void NcmpiVar::iputVar(const double* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_iput_var_double(groupId, myId,dataValues, req),__FILE__,__LINE__);
+}
+// Writes the entire data into the netCDF variable.
+void NcmpiVar::iputVar(const unsigned short* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_iput_var_ushort(groupId, myId,dataValues, req),__FILE__,__LINE__);
+}
+// Writes the entire data into the netCDF variable.
+void NcmpiVar::iputVar(const unsigned int* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_iput_var_uint(groupId, myId,dataValues, req),__FILE__,__LINE__);
+}
+// Writes the entire data into the netCDF variable.
+void NcmpiVar::iputVar(const long long* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_iput_var_longlong(groupId, myId,dataValues, req),__FILE__,__LINE__);
+}
+// Writes the entire data into the netCDF variable.
+void NcmpiVar::iputVar(const unsigned long long* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_iput_var_ulonglong(groupId, myId,dataValues, req),__FILE__,__LINE__);
+}
+// Writes the entire data into the netCDF variable with no data conversion.
+void NcmpiVar::iputVar(const void* dataValues, MPI_Offset bufcount, MPI_Datatype buftype, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_iput_var(groupId, myId,dataValues, bufcount, buftype, req),__FILE__,__LINE__);
+}
+
+
+///////////////////
+// Writes a single datum value into the netCDF variable.
+void NcmpiVar::iputVar(const vector<MPI_Offset>& index, const unsigned char* datumValue, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_iput_var1_uchar(groupId, myId,&index[0],datumValue, req),__FILE__,__LINE__);
+}
+// Writes a single datum value into the netCDF variable.
+void NcmpiVar::iputVar(const vector<MPI_Offset>& index, const signed char* datumValue, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_iput_var1_schar(groupId, myId,&index[0],datumValue, req),__FILE__,__LINE__);
+}
+// Writes a single datum value into the netCDF variable.
+void NcmpiVar::iputVar(const vector<MPI_Offset>& index, const short datumValue, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_iput_var1_short(groupId, myId,&index[0],&datumValue, req),__FILE__,__LINE__);
+}
+// Writes a single datum value into the netCDF variable.
+void NcmpiVar::iputVar(const vector<MPI_Offset>& index, const int datumValue, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_iput_var1_int(groupId, myId,&index[0],&datumValue, req),__FILE__,__LINE__);
+}
+// Writes a single datum value into the netCDF variable.
+void NcmpiVar::iputVar(const vector<MPI_Offset>& index, const long datumValue, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_iput_var1_long(groupId, myId,&index[0],&datumValue, req),__FILE__,__LINE__);
+}
+// Writes a single datum value into the netCDF variable.
+void NcmpiVar::iputVar(const vector<MPI_Offset>& index, const float datumValue, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_iput_var1_float(groupId, myId,&index[0],&datumValue, req),__FILE__,__LINE__);
+}
+// Writes a single datum value into the netCDF variable.
+void NcmpiVar::iputVar(const vector<MPI_Offset>& index, const double datumValue, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_iput_var1_double(groupId, myId,&index[0],&datumValue, req),__FILE__,__LINE__);
+}
+// Writes a single datum value into the netCDF variable.
+void NcmpiVar::iputVar(const vector<MPI_Offset>& index, const unsigned short datumValue, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_iput_var1_ushort(groupId, myId,&index[0],&datumValue, req),__FILE__,__LINE__);
+}
+// Writes a single datum value into the netCDF variable.
+void NcmpiVar::iputVar(const vector<MPI_Offset>& index, const unsigned int datumValue, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_iput_var1_uint(groupId, myId,&index[0],&datumValue, req),__FILE__,__LINE__);
+}
+// Writes a single datum value into the netCDF variable.
+void NcmpiVar::iputVar(const vector<MPI_Offset>& index, const long long datumValue, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_iput_var1_longlong(groupId, myId,&index[0],&datumValue, req),__FILE__,__LINE__);
+}
+// Writes a single datum value into the netCDF variable.
+void NcmpiVar::iputVar(const vector<MPI_Offset>& index, const unsigned long long datumValue, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_iput_var1_ulonglong(groupId, myId,&index[0],&datumValue, req),__FILE__,__LINE__);
+}
+// Writes a single datum value into the netCDF variable with no data conversion.
+void NcmpiVar::iputVar(const vector<MPI_Offset>& index, const void* datumValue, MPI_Offset bufcount, MPI_Datatype buftype, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_iput_var1(groupId, myId,&index[0],datumValue, bufcount, buftype, req),__FILE__,__LINE__);
+}
+
+
+////////////////////
+
+// Writes an array of values into the netCDF variable.
+void NcmpiVar::iputVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const char* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_iput_vara_text(groupId, myId,&startp[0],&countp[0],dataValues, req),__FILE__,__LINE__);
+}
+// Writes an array of values into the netCDF variable.
+void NcmpiVar::iputVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const unsigned char* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_iput_vara_uchar(groupId, myId,&startp[0],&countp[0],dataValues, req),__FILE__,__LINE__);
+}
+// Writes an array of values into the netCDF variable.
+void NcmpiVar::iputVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const signed char* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_iput_vara_schar(groupId, myId,&startp[0],&countp[0],dataValues, req),__FILE__,__LINE__);
+}
+// Writes an array of values into the netCDF variable.
+void NcmpiVar::iputVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const short* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_iput_vara_short(groupId, myId,&startp[0],&countp[0],dataValues, req),__FILE__,__LINE__);
+}
+// Writes an array of values into the netCDF variable.
+void NcmpiVar::iputVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const int* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_iput_vara_int(groupId, myId,&startp[0],&countp[0],dataValues, req),__FILE__,__LINE__);
+}
+// Writes an array of values into the netCDF variable.
+void NcmpiVar::iputVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const long* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_iput_vara_long(groupId, myId,&startp[0],&countp[0],dataValues, req),__FILE__,__LINE__);
+}
+// Writes an array of values into the netCDF variable.
+void NcmpiVar::iputVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const float* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_iput_vara_float(groupId, myId,&startp[0],&countp[0],dataValues, req),__FILE__,__LINE__);
+}
+// Writes an array of values into the netCDF variable.
+void NcmpiVar::iputVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const double* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_iput_vara_double(groupId, myId,&startp[0],&countp[0],dataValues, req),__FILE__,__LINE__);
+}
+// Writes an array of values into the netCDF variable.
+void NcmpiVar::iputVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const unsigned short* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_iput_vara_ushort(groupId, myId,&startp[0],&countp[0],dataValues, req),__FILE__,__LINE__);
+}
+// Writes an array of values into the netCDF variable.
+void NcmpiVar::iputVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const unsigned int* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_iput_vara_uint(groupId, myId,&startp[0],&countp[0],dataValues, req),__FILE__,__LINE__);
+}
+// Writes an array of values into the netCDF variable.
+void NcmpiVar::iputVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const long long* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_iput_vara_longlong(groupId, myId,&startp[0],&countp[0],dataValues, req),__FILE__,__LINE__);
+}
+// Writes an array of values into the netCDF variable.
+void NcmpiVar::iputVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const unsigned long long* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_iput_vara_ulonglong(groupId, myId,&startp[0],&countp[0],dataValues, req),__FILE__,__LINE__);
+}
+// Writes an array of values into the netCDF variable with no data conversion.
+void NcmpiVar::iputVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const void* dataValues, MPI_Offset bufcount, MPI_Datatype buftype, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_iput_vara(groupId, myId,&startp[0],&countp[0],dataValues, bufcount, buftype, req),__FILE__,__LINE__);
+}
+
+
+
+////////////////////
+
+// Writes a set of subsampled array values into the netCDF variable.
+void NcmpiVar::iputVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const char* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_iput_vars_text(groupId, myId,&startp[0],&countp[0],&stridep[0],dataValues, req),__FILE__,__LINE__);
+}
+// Writes a set of subsampled array values into the netCDF variable.
+void NcmpiVar::iputVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const unsigned char* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_iput_vars_uchar(groupId, myId,&startp[0],&countp[0],&stridep[0],dataValues, req),__FILE__,__LINE__);
+}
+// Writes a set of subsampled array values into the netCDF variable.
+void NcmpiVar::iputVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const signed char* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_iput_vars_schar(groupId, myId,&startp[0],&countp[0],&stridep[0],dataValues, req),__FILE__,__LINE__);
+}
+// Writes a set of subsampled array values into the netCDF variable.
+void NcmpiVar::iputVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const short* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_iput_vars_short(groupId, myId,&startp[0],&countp[0],&stridep[0],dataValues, req),__FILE__,__LINE__);
+}
+// Writes a set of subsampled array values into the netCDF variable.
+void NcmpiVar::iputVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const int* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_iput_vars_int(groupId, myId,&startp[0],&countp[0],&stridep[0],dataValues, req),__FILE__,__LINE__);
+}
+// Writes a set of subsampled array values into the netCDF variable.
+void NcmpiVar::iputVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const long* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_iput_vars_long(groupId, myId,&startp[0],&countp[0],&stridep[0],dataValues, req),__FILE__,__LINE__);
+}
+// Writes a set of subsampled array values into the netCDF variable.
+void NcmpiVar::iputVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const float* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_iput_vars_float(groupId, myId,&startp[0],&countp[0],&stridep[0],dataValues, req),__FILE__,__LINE__);
+}
+// Writes a set of subsampled array values into the netCDF variable.
+void NcmpiVar::iputVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const double* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_iput_vars_double(groupId, myId,&startp[0],&countp[0],&stridep[0],dataValues, req),__FILE__,__LINE__);
+}
+// Writes a set of subsampled array values into the netCDF variable.
+void NcmpiVar::iputVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const unsigned short* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_iput_vars_ushort(groupId, myId,&startp[0],&countp[0],&stridep[0],dataValues, req),__FILE__,__LINE__);
+}
+// Writes a set of subsampled array values into the netCDF variable.
+void NcmpiVar::iputVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const unsigned int* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_iput_vars_uint(groupId, myId,&startp[0],&countp[0],&stridep[0],dataValues, req),__FILE__,__LINE__);
+}
+// Writes a set of subsampled array values into the netCDF variable.
+void NcmpiVar::iputVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const long long* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_iput_vars_longlong(groupId, myId,&startp[0],&countp[0],&stridep[0],dataValues, req),__FILE__,__LINE__);
+}
+// Writes a set of subsampled array values into the netCDF variable.
+void NcmpiVar::iputVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const unsigned long long* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_iput_vars_ulonglong(groupId, myId,&startp[0],&countp[0],&stridep[0],dataValues, req),__FILE__,__LINE__);
+}
+// Writes a set of subsampled array values into the netCDF variable with no data conversion.
+void NcmpiVar::iputVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const void* dataValues, MPI_Offset bufcount, MPI_Datatype buftype, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_iput_vars(groupId, myId,&startp[0],&countp[0],&stridep[0],dataValues, bufcount, buftype, req),__FILE__,__LINE__);
+}
+
+
+////////////////////
+// Writes a mapped array section of values into the netCDF variable.
+void NcmpiVar::iputVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const vector<MPI_Offset>& imapp, const char* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_iput_varm_text(groupId, myId,&startp[0],&countp[0],&stridep[0],&imapp[0],dataValues, req),__FILE__,__LINE__);
+}
+// Writes a mapped array section of values into the netCDF variable.
+void NcmpiVar::iputVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const vector<MPI_Offset>& imapp, const unsigned char* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_iput_varm_uchar(groupId, myId,&startp[0],&countp[0],&stridep[0],&imapp[0],dataValues, req),__FILE__,__LINE__);
+}
+// Writes a mapped array section of values into the netCDF variable.
+void NcmpiVar::iputVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const vector<MPI_Offset>& imapp, const signed char* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_iput_varm_schar(groupId, myId,&startp[0],&countp[0],&stridep[0],&imapp[0],dataValues, req),__FILE__,__LINE__);
+}
+// Writes a mapped array section of values into the netCDF variable.
+void NcmpiVar::iputVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const vector<MPI_Offset>& imapp, const short* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_iput_varm_short(groupId, myId,&startp[0],&countp[0],&stridep[0],&imapp[0],dataValues, req),__FILE__,__LINE__);
+}
+// Writes a mapped array section of values into the netCDF variable.
+void NcmpiVar::iputVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const vector<MPI_Offset>& imapp, const int* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_iput_varm_int(groupId, myId,&startp[0],&countp[0],&stridep[0],&imapp[0],dataValues, req),__FILE__,__LINE__);
+}
+// Writes a mapped array section of values into the netCDF variable.
+void NcmpiVar::iputVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const vector<MPI_Offset>& imapp, const long* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_iput_varm_long(groupId, myId,&startp[0],&countp[0],&stridep[0],&imapp[0],dataValues, req),__FILE__,__LINE__);
+}
+// Writes a mapped array section of values into the netCDF variable.
+void NcmpiVar::iputVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const vector<MPI_Offset>& imapp, const float* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_iput_varm_float(groupId, myId,&startp[0],&countp[0],&stridep[0],&imapp[0],dataValues, req),__FILE__,__LINE__);
+}
+// Writes a mapped array section of values into the netCDF variable.
+void NcmpiVar::iputVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const vector<MPI_Offset>& imapp, const double* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_iput_varm_double(groupId, myId,&startp[0],&countp[0],&stridep[0],&imapp[0],dataValues, req),__FILE__,__LINE__);
+}
+// Writes a mapped array section of values into the netCDF variable.
+void NcmpiVar::iputVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const vector<MPI_Offset>& imapp, const unsigned short* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_iput_varm_ushort(groupId, myId,&startp[0],&countp[0],&stridep[0],&imapp[0],dataValues, req),__FILE__,__LINE__);
+}
+// Writes a mapped array section of values into the netCDF variable.
+void NcmpiVar::iputVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const vector<MPI_Offset>& imapp, const unsigned int* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_iput_varm_uint(groupId, myId,&startp[0],&countp[0],&stridep[0],&imapp[0],dataValues, req),__FILE__,__LINE__);
+}
+// Writes a mapped array section of values into the netCDF variable.
+void NcmpiVar::iputVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const vector<MPI_Offset>& imapp, const long long* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_iput_varm_longlong(groupId, myId,&startp[0],&countp[0],&stridep[0],&imapp[0],dataValues, req),__FILE__,__LINE__);
+}
+// Writes a mapped array section of values into the netCDF variable.
+void NcmpiVar::iputVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const vector<MPI_Offset>& imapp, const unsigned long long* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_iput_varm_ulonglong(groupId, myId,&startp[0],&countp[0],&stridep[0],&imapp[0],dataValues, req),__FILE__,__LINE__);
+}
+// Writes a mapped array section of values into the netCDF variable with no data conversion.
+void NcmpiVar::iputVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const vector<MPI_Offset>& imapp, const void* dataValues, MPI_Offset bufcount, MPI_Datatype buftype, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_iput_varm(groupId, myId,&startp[0],&countp[0],&stridep[0],&imapp[0],dataValues, bufcount, buftype, req),__FILE__,__LINE__);
+}
+
+////////////////////
+
+// Nonblocking writes a list of subarrays into the netCDF variable.
+void NcmpiVar::iputVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], const char* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_iput_varn_text(groupId, myId, num, starts, counts, dataValues, req),__FILE__,__LINE__);
+}
+// Writes an array of values into the netCDF variable.
+void NcmpiVar::iputVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], const unsigned char* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_iput_varn_uchar(groupId, myId, num, starts, counts, dataValues, req),__FILE__,__LINE__);
+}
+// Writes an array of values into the netCDF variable.
+void NcmpiVar::iputVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], const signed char* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_iput_varn_schar(groupId, myId, num, starts, counts, dataValues, req),__FILE__,__LINE__);
+}
+// Writes an array of values into the netCDF variable.
+void NcmpiVar::iputVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], const short* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_iput_varn_short(groupId, myId, num, starts, counts, dataValues, req),__FILE__,__LINE__);
+}
+// Writes an array of values into the netCDF variable.
+void NcmpiVar::iputVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], const int* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_iput_varn_int(groupId, myId, num, starts, counts, dataValues, req),__FILE__,__LINE__);
+}
+// Writes an array of values into the netCDF variable.
+void NcmpiVar::iputVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], const long* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_iput_varn_long(groupId, myId, num, starts, counts, dataValues, req),__FILE__,__LINE__);
+}
+// Writes an array of values into the netCDF variable.
+void NcmpiVar::iputVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], const float* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_iput_varn_float(groupId, myId, num, starts, counts, dataValues, req),__FILE__,__LINE__);
+}
+// Writes an array of values into the netCDF variable.
+void NcmpiVar::iputVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], const double* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_iput_varn_double(groupId, myId, num, starts, counts, dataValues, req),__FILE__,__LINE__);
+}
+// Writes an array of values into the netCDF variable.
+void NcmpiVar::iputVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], const unsigned short* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_iput_varn_ushort(groupId, myId, num, starts, counts, dataValues, req),__FILE__,__LINE__);
+}
+// Writes an array of values into the netCDF variable.
+void NcmpiVar::iputVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], const unsigned int* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_iput_varn_uint(groupId, myId, num, starts, counts, dataValues, req),__FILE__,__LINE__);
+}
+// Writes an array of values into the netCDF variable.
+void NcmpiVar::iputVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], const long long* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_iput_varn_longlong(groupId, myId, num, starts, counts, dataValues, req),__FILE__,__LINE__);
+}
+// Writes an array of values into the netCDF variable.
+void NcmpiVar::iputVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], const unsigned long long* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_iput_varn_ulonglong(groupId, myId, num, starts, counts, dataValues, req),__FILE__,__LINE__);
+}
+// Writes an array of values into the netCDF variable with no data conversion.
+void NcmpiVar::iputVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], const void* dataValues, MPI_Offset bufcount, MPI_Datatype buftype, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_iput_varn(groupId, myId, num, starts, counts, dataValues, bufcount, buftype, req),__FILE__,__LINE__);
+}
+
+////////////////////
+
+// Buffered nonblocking data writing
+
+////////////////////
+
+// Writes the entire data into the netCDF variable.
+void NcmpiVar::bputVar(const char* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_bput_var_text(groupId, myId,dataValues, req),__FILE__,__LINE__);
+}
+// Writes the entire data into the netCDF variable.
+void NcmpiVar::bputVar(const unsigned char* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_bput_var_uchar(groupId, myId,dataValues, req),__FILE__,__LINE__);
+}
+// Writes the entire data into the netCDF variable.
+void NcmpiVar::bputVar(const signed char* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_bput_var_schar(groupId, myId,dataValues, req),__FILE__,__LINE__);
+}
+// Writes the entire data into the netCDF variable.
+void NcmpiVar::bputVar(const short* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_bput_var_short(groupId, myId,dataValues, req),__FILE__,__LINE__);
+}
+// Writes the entire data into the netCDF variable.
+void NcmpiVar::bputVar(const int* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_bput_var_int(groupId, myId,dataValues, req),__FILE__,__LINE__);
+}
+// Writes the entire data into the netCDF variable.
+void NcmpiVar::bputVar(const long* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_bput_var_long(groupId, myId,dataValues, req),__FILE__,__LINE__);
+}
+// Writes the entire data into the netCDF variable.
+void NcmpiVar::bputVar(const float* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_bput_var_float(groupId, myId,dataValues, req),__FILE__,__LINE__);
+}
+// Writes the entire data into the netCDF variable.
+void NcmpiVar::bputVar(const double* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_bput_var_double(groupId, myId,dataValues, req),__FILE__,__LINE__);
+}
+// Writes the entire data into the netCDF variable.
+void NcmpiVar::bputVar(const unsigned short* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_bput_var_ushort(groupId, myId,dataValues, req),__FILE__,__LINE__);
+}
+// Writes the entire data into the netCDF variable.
+void NcmpiVar::bputVar(const unsigned int* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_bput_var_uint(groupId, myId,dataValues, req),__FILE__,__LINE__);
+}
+// Writes the entire data into the netCDF variable.
+void NcmpiVar::bputVar(const long long* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_bput_var_longlong(groupId, myId,dataValues, req),__FILE__,__LINE__);
+}
+// Writes the entire data into the netCDF variable.
+void NcmpiVar::bputVar(const unsigned long long* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_bput_var_ulonglong(groupId, myId,dataValues, req),__FILE__,__LINE__);
+}
+// Writes the entire data into the netCDF variable with no data conversion.
+void NcmpiVar::bputVar(const void* dataValues, MPI_Offset bufcount, MPI_Datatype buftype, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_bput_var(groupId, myId,dataValues, bufcount, buftype, req),__FILE__,__LINE__);
+}
+
+
+///////////////////
+// Writes a single datum value into the netCDF variable.
+void NcmpiVar::bputVar(const vector<MPI_Offset>& index, const unsigned char* datumValue, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_bput_var1_uchar(groupId, myId,&index[0],datumValue, req),__FILE__,__LINE__);
+}
+// Writes a single datum value into the netCDF variable.
+void NcmpiVar::bputVar(const vector<MPI_Offset>& index, const signed char* datumValue, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_bput_var1_schar(groupId, myId,&index[0],datumValue, req),__FILE__,__LINE__);
+}
+// Writes a single datum value into the netCDF variable.
+void NcmpiVar::bputVar(const vector<MPI_Offset>& index, const short datumValue, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_bput_var1_short(groupId, myId,&index[0],&datumValue, req),__FILE__,__LINE__);
+}
+// Writes a single datum value into the netCDF variable.
+void NcmpiVar::bputVar(const vector<MPI_Offset>& index, const int datumValue, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_bput_var1_int(groupId, myId,&index[0],&datumValue, req),__FILE__,__LINE__);
+}
+// Writes a single datum value into the netCDF variable.
+void NcmpiVar::bputVar(const vector<MPI_Offset>& index, const long datumValue, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_bput_var1_long(groupId, myId,&index[0],&datumValue, req),__FILE__,__LINE__);
+}
+// Writes a single datum value into the netCDF variable.
+void NcmpiVar::bputVar(const vector<MPI_Offset>& index, const float datumValue, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_bput_var1_float(groupId, myId,&index[0],&datumValue, req),__FILE__,__LINE__);
+}
+// Writes a single datum value into the netCDF variable.
+void NcmpiVar::bputVar(const vector<MPI_Offset>& index, const double datumValue, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_bput_var1_double(groupId, myId,&index[0],&datumValue, req),__FILE__,__LINE__);
+}
+// Writes a single datum value into the netCDF variable.
+void NcmpiVar::bputVar(const vector<MPI_Offset>& index, const unsigned short datumValue, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_bput_var1_ushort(groupId, myId,&index[0],&datumValue, req),__FILE__,__LINE__);
+}
+// Writes a single datum value into the netCDF variable.
+void NcmpiVar::bputVar(const vector<MPI_Offset>& index, const unsigned int datumValue, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_bput_var1_uint(groupId, myId,&index[0],&datumValue, req),__FILE__,__LINE__);
+}
+// Writes a single datum value into the netCDF variable.
+void NcmpiVar::bputVar(const vector<MPI_Offset>& index, const long long datumValue, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_bput_var1_longlong(groupId, myId,&index[0],&datumValue, req),__FILE__,__LINE__);
+}
+// Writes a single datum value into the netCDF variable.
+void NcmpiVar::bputVar(const vector<MPI_Offset>& index, const unsigned long long datumValue, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_bput_var1_ulonglong(groupId, myId,&index[0],&datumValue, req),__FILE__,__LINE__);
+}
+// Writes a single datum value into the netCDF variable with no data conversion.
+void NcmpiVar::bputVar(const vector<MPI_Offset>& index, const void* datumValue, MPI_Offset bufcount, MPI_Datatype buftype, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_bput_var1(groupId, myId,&index[0],datumValue, bufcount, buftype, req),__FILE__,__LINE__);
+}
+
+
+////////////////////
+
+// Writes an array of values into the netCDF variable.
+void NcmpiVar::bputVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const char* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_bput_vara_text(groupId, myId,&startp[0],&countp[0],dataValues, req),__FILE__,__LINE__);
+}
+// Writes an array of values into the netCDF variable.
+void NcmpiVar::bputVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const unsigned char* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_bput_vara_uchar(groupId, myId,&startp[0],&countp[0],dataValues, req),__FILE__,__LINE__);
+}
+// Writes an array of values into the netCDF variable.
+void NcmpiVar::bputVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const signed char* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_bput_vara_schar(groupId, myId,&startp[0],&countp[0],dataValues, req),__FILE__,__LINE__);
+}
+// Writes an array of values into the netCDF variable.
+void NcmpiVar::bputVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const short* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_bput_vara_short(groupId, myId,&startp[0],&countp[0],dataValues, req),__FILE__,__LINE__);
+}
+// Writes an array of values into the netCDF variable.
+void NcmpiVar::bputVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const int* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_bput_vara_int(groupId, myId,&startp[0],&countp[0],dataValues, req),__FILE__,__LINE__);
+}
+// Writes an array of values into the netCDF variable.
+void NcmpiVar::bputVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const long* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_bput_vara_long(groupId, myId,&startp[0],&countp[0],dataValues, req),__FILE__,__LINE__);
+}
+// Writes an array of values into the netCDF variable.
+void NcmpiVar::bputVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const float* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_bput_vara_float(groupId, myId,&startp[0],&countp[0],dataValues, req),__FILE__,__LINE__);
+}
+// Writes an array of values into the netCDF variable.
+void NcmpiVar::bputVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const double* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_bput_vara_double(groupId, myId,&startp[0],&countp[0],dataValues, req),__FILE__,__LINE__);
+}
+// Writes an array of values into the netCDF variable.
+void NcmpiVar::bputVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const unsigned short* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_bput_vara_ushort(groupId, myId,&startp[0],&countp[0],dataValues, req),__FILE__,__LINE__);
+}
+// Writes an array of values into the netCDF variable.
+void NcmpiVar::bputVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const unsigned int* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_bput_vara_uint(groupId, myId,&startp[0],&countp[0],dataValues, req),__FILE__,__LINE__);
+}
+// Writes an array of values into the netCDF variable.
+void NcmpiVar::bputVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const long long* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_bput_vara_longlong(groupId, myId,&startp[0],&countp[0],dataValues, req),__FILE__,__LINE__);
+}
+// Writes an array of values into the netCDF variable.
+void NcmpiVar::bputVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const unsigned long long* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_bput_vara_ulonglong(groupId, myId,&startp[0],&countp[0],dataValues, req),__FILE__,__LINE__);
+}
+// Writes an array of values into the netCDF variable with no data conversion.
+void NcmpiVar::bputVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const void* dataValues, MPI_Offset bufcount, MPI_Datatype buftype, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_bput_vara(groupId, myId,&startp[0],&countp[0],dataValues, bufcount, buftype, req),__FILE__,__LINE__);
+}
+
+
+
+////////////////////
+
+// Writes a set of subsampled array values into the netCDF variable.
+void NcmpiVar::bputVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const char* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_bput_vars_text(groupId, myId,&startp[0],&countp[0],&stridep[0],dataValues, req),__FILE__,__LINE__);
+}
+// Writes a set of subsampled array values into the netCDF variable.
+void NcmpiVar::bputVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const unsigned char* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_bput_vars_uchar(groupId, myId,&startp[0],&countp[0],&stridep[0],dataValues, req),__FILE__,__LINE__);
+}
+// Writes a set of subsampled array values into the netCDF variable.
+void NcmpiVar::bputVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const signed char* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_bput_vars_schar(groupId, myId,&startp[0],&countp[0],&stridep[0],dataValues, req),__FILE__,__LINE__);
+}
+// Writes a set of subsampled array values into the netCDF variable.
+void NcmpiVar::bputVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const short* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_bput_vars_short(groupId, myId,&startp[0],&countp[0],&stridep[0],dataValues, req),__FILE__,__LINE__);
+}
+// Writes a set of subsampled array values into the netCDF variable.
+void NcmpiVar::bputVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const int* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_bput_vars_int(groupId, myId,&startp[0],&countp[0],&stridep[0],dataValues, req),__FILE__,__LINE__);
+}
+// Writes a set of subsampled array values into the netCDF variable.
+void NcmpiVar::bputVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const long* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_bput_vars_long(groupId, myId,&startp[0],&countp[0],&stridep[0],dataValues, req),__FILE__,__LINE__);
+}
+// Writes a set of subsampled array values into the netCDF variable.
+void NcmpiVar::bputVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const float* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_bput_vars_float(groupId, myId,&startp[0],&countp[0],&stridep[0],dataValues, req),__FILE__,__LINE__);
+}
+// Writes a set of subsampled array values into the netCDF variable.
+void NcmpiVar::bputVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const double* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_bput_vars_double(groupId, myId,&startp[0],&countp[0],&stridep[0],dataValues, req),__FILE__,__LINE__);
+}
+// Writes a set of subsampled array values into the netCDF variable.
+void NcmpiVar::bputVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const unsigned short* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_bput_vars_ushort(groupId, myId,&startp[0],&countp[0],&stridep[0],dataValues, req),__FILE__,__LINE__);
+}
+// Writes a set of subsampled array values into the netCDF variable.
+void NcmpiVar::bputVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const unsigned int* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_bput_vars_uint(groupId, myId,&startp[0],&countp[0],&stridep[0],dataValues, req),__FILE__,__LINE__);
+}
+// Writes a set of subsampled array values into the netCDF variable.
+void NcmpiVar::bputVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const long long* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_bput_vars_longlong(groupId, myId,&startp[0],&countp[0],&stridep[0],dataValues, req),__FILE__,__LINE__);
+}
+// Writes a set of subsampled array values into the netCDF variable.
+void NcmpiVar::bputVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const unsigned long long* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_bput_vars_ulonglong(groupId, myId,&startp[0],&countp[0],&stridep[0],dataValues, req),__FILE__,__LINE__);
+}
+// Writes a set of subsampled array values into the netCDF variable with no data conversion.
+void NcmpiVar::bputVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const void* dataValues, MPI_Offset bufcount, MPI_Datatype buftype, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_bput_vars(groupId, myId,&startp[0],&countp[0],&stridep[0],dataValues, bufcount, buftype, req),__FILE__,__LINE__);
+}
+
+
+////////////////////
+// Writes a mapped array section of values into the netCDF variable.
+void NcmpiVar::bputVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const vector<MPI_Offset>& imapp, const char* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_bput_varm_text(groupId, myId,&startp[0],&countp[0],&stridep[0],&imapp[0],dataValues, req),__FILE__,__LINE__);
+}
+// Writes a mapped array section of values into the netCDF variable.
+void NcmpiVar::bputVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const vector<MPI_Offset>& imapp, const unsigned char* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_bput_varm_uchar(groupId, myId,&startp[0],&countp[0],&stridep[0],&imapp[0],dataValues, req),__FILE__,__LINE__);
+}
+// Writes a mapped array section of values into the netCDF variable.
+void NcmpiVar::bputVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const vector<MPI_Offset>& imapp, const signed char* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_bput_varm_schar(groupId, myId,&startp[0],&countp[0],&stridep[0],&imapp[0],dataValues, req),__FILE__,__LINE__);
+}
+// Writes a mapped array section of values into the netCDF variable.
+void NcmpiVar::bputVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const vector<MPI_Offset>& imapp, const short* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_bput_varm_short(groupId, myId,&startp[0],&countp[0],&stridep[0],&imapp[0],dataValues, req),__FILE__,__LINE__);
+}
+// Writes a mapped array section of values into the netCDF variable.
+void NcmpiVar::bputVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const vector<MPI_Offset>& imapp, const int* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_bput_varm_int(groupId, myId,&startp[0],&countp[0],&stridep[0],&imapp[0],dataValues, req),__FILE__,__LINE__);
+}
+// Writes a mapped array section of values into the netCDF variable.
+void NcmpiVar::bputVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const vector<MPI_Offset>& imapp, const long* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_bput_varm_long(groupId, myId,&startp[0],&countp[0],&stridep[0],&imapp[0],dataValues, req),__FILE__,__LINE__);
+}
+// Writes a mapped array section of values into the netCDF variable.
+void NcmpiVar::bputVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const vector<MPI_Offset>& imapp, const float* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_bput_varm_float(groupId, myId,&startp[0],&countp[0],&stridep[0],&imapp[0],dataValues, req),__FILE__,__LINE__);
+}
+// Writes a mapped array section of values into the netCDF variable.
+void NcmpiVar::bputVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const vector<MPI_Offset>& imapp, const double* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_bput_varm_double(groupId, myId,&startp[0],&countp[0],&stridep[0],&imapp[0],dataValues, req),__FILE__,__LINE__);
+}
+// Writes a mapped array section of values into the netCDF variable.
+void NcmpiVar::bputVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const vector<MPI_Offset>& imapp, const unsigned short* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_bput_varm_ushort(groupId, myId,&startp[0],&countp[0],&stridep[0],&imapp[0],dataValues, req),__FILE__,__LINE__);
+}
+// Writes a mapped array section of values into the netCDF variable.
+void NcmpiVar::bputVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const vector<MPI_Offset>& imapp, const unsigned int* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_bput_varm_uint(groupId, myId,&startp[0],&countp[0],&stridep[0],&imapp[0],dataValues, req),__FILE__,__LINE__);
+}
+// Writes a mapped array section of values into the netCDF variable.
+void NcmpiVar::bputVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const vector<MPI_Offset>& imapp, const long long* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_bput_varm_longlong(groupId, myId,&startp[0],&countp[0],&stridep[0],&imapp[0],dataValues, req),__FILE__,__LINE__);
+}
+// Writes a mapped array section of values into the netCDF variable.
+void NcmpiVar::bputVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const vector<MPI_Offset>& imapp, const unsigned long long* dataValues, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_bput_varm_ulonglong(groupId, myId,&startp[0],&countp[0],&stridep[0],&imapp[0],dataValues, req),__FILE__,__LINE__);
+}
+// Writes a mapped array section of values into the netCDF variable with no data conversion.
+void NcmpiVar::bputVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>&countp, const vector<MPI_Offset>& stridep, const vector<MPI_Offset>& imapp, const void* dataValues, MPI_Offset bufcount, MPI_Datatype buftype, int *req) const {
+ ncmpiCheckDataMode(groupId);
+ ncmpiCheck(ncmpi_bput_varm(groupId, myId,&startp[0],&countp[0],&stridep[0],&imapp[0],dataValues, bufcount, buftype, req),__FILE__,__LINE__);
+}
+
+
+// Data reading (independent I/O APIs)
+
+// Reads the entire data of the netCDF variable.
+void NcmpiVar::getVar(char* dataValues) const {
+ ncmpiCheck(ncmpi_get_var_text(groupId, myId,dataValues),__FILE__,__LINE__);
+}
+// Reads the entire data of the netCDF variable.
+void NcmpiVar::getVar(unsigned char* dataValues) const {
+ ncmpiCheck(ncmpi_get_var_uchar(groupId, myId,dataValues),__FILE__,__LINE__);
+}
+// Reads the entire data of the netCDF variable.
+void NcmpiVar::getVar(signed char* dataValues) const {
+ ncmpiCheck(ncmpi_get_var_schar(groupId, myId,dataValues),__FILE__,__LINE__);
+}
+// Reads the entire data of the netCDF variable.
+void NcmpiVar::getVar(short* dataValues) const {
+ ncmpiCheck(ncmpi_get_var_short(groupId, myId,dataValues),__FILE__,__LINE__);
+}
+// Reads the entire data of the netCDF variable.
+void NcmpiVar::getVar(int* dataValues) const {
+ ncmpiCheck(ncmpi_get_var_int(groupId, myId,dataValues),__FILE__,__LINE__);
+}
+// Reads the entire data of the netCDF variable.
+void NcmpiVar::getVar(long* dataValues) const {
+ ncmpiCheck(ncmpi_get_var_long(groupId, myId,dataValues),__FILE__,__LINE__);
+}
+// Reads the entire data of the netCDF variable.
+void NcmpiVar::getVar(float* dataValues) const {
+ ncmpiCheck(ncmpi_get_var_float(groupId, myId,dataValues),__FILE__,__LINE__);
+}
+// Reads the entire data of the netCDF variable.
+void NcmpiVar::getVar(double* dataValues) const {
+ ncmpiCheck(ncmpi_get_var_double(groupId, myId,dataValues),__FILE__,__LINE__);
+}
+// Reads the entire data of the netCDF variable.
+void NcmpiVar::getVar(unsigned short* dataValues) const {
+ ncmpiCheck(ncmpi_get_var_ushort(groupId, myId,dataValues),__FILE__,__LINE__);
+}
+// Reads the entire data of the netCDF variable.
+void NcmpiVar::getVar(unsigned int* dataValues) const {
+ ncmpiCheck(ncmpi_get_var_uint(groupId, myId,dataValues),__FILE__,__LINE__);
+}
+// Reads the entire data of the netCDF variable.
+void NcmpiVar::getVar(long long* dataValues) const {
+ ncmpiCheck(ncmpi_get_var_longlong(groupId, myId,dataValues),__FILE__,__LINE__);
+}
+// Reads the entire data of the netCDF variable.
+void NcmpiVar::getVar(unsigned long long* dataValues) const {
+ ncmpiCheck(ncmpi_get_var_ulonglong(groupId, myId,dataValues),__FILE__,__LINE__);
+}
+// Reads the entire data of the netCDF variable with no data conversion.
+void NcmpiVar::getVar(void* dataValues, MPI_Offset bufcount, MPI_Datatype buftype) const {
+ ncmpiCheck(ncmpi_get_var(groupId, myId,dataValues, bufcount, buftype),__FILE__,__LINE__);
+}
+
+///////////
+
+// Reads a single datum value of a netCDF variable.
+void NcmpiVar::getVar(const vector<MPI_Offset>& index, char* datumValue) const {
+ ncmpiCheck(ncmpi_get_var1_text(groupId, myId,&index[0],datumValue),__FILE__,__LINE__);
+}
+// Reads a single datum value of a netCDF variable.
+void NcmpiVar::getVar(const vector<MPI_Offset>& index, unsigned char* datumValue) const {
+ ncmpiCheck(ncmpi_get_var1_uchar(groupId, myId,&index[0],datumValue),__FILE__,__LINE__);
+}
+// Reads a single datum value of a netCDF variable.
+void NcmpiVar::getVar(const vector<MPI_Offset>& index, signed char* datumValue) const {
+ ncmpiCheck(ncmpi_get_var1_schar(groupId, myId,&index[0],datumValue),__FILE__,__LINE__);
+}
+// Reads a single datum value of a netCDF variable.
+void NcmpiVar::getVar(const vector<MPI_Offset>& index, short* datumValue) const {
+ ncmpiCheck(ncmpi_get_var1_short(groupId, myId,&index[0],datumValue),__FILE__,__LINE__);
+}
+// Reads a single datum value of a netCDF variable.
+void NcmpiVar::getVar(const vector<MPI_Offset>& index, int* datumValue) const {
+ ncmpiCheck(ncmpi_get_var1_int(groupId, myId,&index[0],datumValue),__FILE__,__LINE__);
+}
+// Reads a single datum value of a netCDF variable.
+void NcmpiVar::getVar(const vector<MPI_Offset>& index, long* datumValue) const {
+ ncmpiCheck(ncmpi_get_var1_long(groupId, myId,&index[0],datumValue),__FILE__,__LINE__);
+}
+// Reads a single datum value of a netCDF variable.
+void NcmpiVar::getVar(const vector<MPI_Offset>& index, float* datumValue) const {
+ ncmpiCheck(ncmpi_get_var1_float(groupId, myId,&index[0],datumValue),__FILE__,__LINE__);
+}
+// Reads a single datum value of a netCDF variable.
+void NcmpiVar::getVar(const vector<MPI_Offset>& index, double* datumValue) const {
+ ncmpiCheck(ncmpi_get_var1_double(groupId, myId,&index[0],datumValue),__FILE__,__LINE__);
+}
+// Reads a single datum value of a netCDF variable.
+void NcmpiVar::getVar(const vector<MPI_Offset>& index, unsigned short* datumValue) const {
+ ncmpiCheck(ncmpi_get_var1_ushort(groupId, myId,&index[0],datumValue),__FILE__,__LINE__);
+}
+// Reads a single datum value of a netCDF variable.
+void NcmpiVar::getVar(const vector<MPI_Offset>& index, unsigned int* datumValue) const {
+ ncmpiCheck(ncmpi_get_var1_uint(groupId, myId,&index[0],datumValue),__FILE__,__LINE__);
+}
+// Reads a single datum value of a netCDF variable.
+void NcmpiVar::getVar(const vector<MPI_Offset>& index, long long* datumValue) const {
+ ncmpiCheck(ncmpi_get_var1_longlong(groupId, myId,&index[0],datumValue),__FILE__,__LINE__);
+}
+// Reads a single datum value of a netCDF variable
+void NcmpiVar::getVar(const vector<MPI_Offset>& index, unsigned long long* datumValue) const {
+ ncmpiCheck(ncmpi_get_var1_ulonglong(groupId, myId,&index[0],datumValue),__FILE__,__LINE__);
+}
+// Reads a single datum value of a netCDF variable with no data conversion.
+void NcmpiVar::getVar(const vector<MPI_Offset>& index, void* datumValue, MPI_Offset bufcount, MPI_Datatype buftype) const {
+ ncmpiCheck(ncmpi_get_var1(groupId, myId,&index[0],datumValue, bufcount, buftype),__FILE__,__LINE__);
+}
+
+///////////
+
+// Reads an array of values from a netCDF variable.
+void NcmpiVar::getVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, char* dataValues) const {
+ ncmpiCheck(ncmpi_get_vara_text(groupId, myId,&startp[0],&countp[0],dataValues),__FILE__,__LINE__);
+}
+// Reads an array of values from a netCDF variable.
+void NcmpiVar::getVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, unsigned char* dataValues) const {
+ ncmpiCheck(ncmpi_get_vara_uchar(groupId, myId,&startp[0],&countp[0],dataValues),__FILE__,__LINE__);
+}
+// Reads an array of values from a netCDF variable.
+void NcmpiVar::getVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, signed char* dataValues) const {
+ ncmpiCheck(ncmpi_get_vara_schar(groupId, myId,&startp[0],&countp[0],dataValues),__FILE__,__LINE__);
+}
+// Reads an array of values from a netCDF variable.
+void NcmpiVar::getVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, short* dataValues) const {
+ ncmpiCheck(ncmpi_get_vara_short(groupId, myId,&startp[0],&countp[0],dataValues),__FILE__,__LINE__);
+}
+// Reads an array of values from a netCDF variable.
+void NcmpiVar::getVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, int* dataValues) const {
+ ncmpiCheck(ncmpi_get_vara_int(groupId, myId,&startp[0],&countp[0],dataValues),__FILE__,__LINE__);
+}
+// Reads an array of values from a netCDF variable.
+void NcmpiVar::getVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, long* dataValues) const {
+ ncmpiCheck(ncmpi_get_vara_long(groupId, myId,&startp[0],&countp[0],dataValues),__FILE__,__LINE__);
+}
+// Reads an array of values from a netCDF variable.
+void NcmpiVar::getVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, float* dataValues) const {
+ ncmpiCheck(ncmpi_get_vara_float(groupId, myId,&startp[0],&countp[0],dataValues),__FILE__,__LINE__);
+}
+// Reads an array of values from a netCDF variable.
+void NcmpiVar::getVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, double* dataValues) const {
+ ncmpiCheck(ncmpi_get_vara_double(groupId, myId,&startp[0],&countp[0],dataValues),__FILE__,__LINE__);
+}
+// Reads an array of values from a netCDF variable.
+void NcmpiVar::getVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, unsigned short* dataValues) const {
+ ncmpiCheck(ncmpi_get_vara_ushort(groupId, myId,&startp[0],&countp[0],dataValues),__FILE__,__LINE__);
+}
+// Reads an array of values from a netCDF variable.
+void NcmpiVar::getVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, unsigned int* dataValues) const {
+ ncmpiCheck(ncmpi_get_vara_uint(groupId, myId,&startp[0],&countp[0],dataValues),__FILE__,__LINE__);
+}
+// Reads an array of values from a netCDF variable.
+void NcmpiVar::getVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, long long* dataValues) const {
+ ncmpiCheck(ncmpi_get_vara_longlong(groupId, myId,&startp[0],&countp[0],dataValues),__FILE__,__LINE__);
+}
+// Reads an array of values from a netCDF variable
+void NcmpiVar::getVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, unsigned long long* dataValues) const {
+ ncmpiCheck(ncmpi_get_vara_ulonglong(groupId, myId,&startp[0],&countp[0],dataValues),__FILE__,__LINE__);
+}
+// Reads an array of values from a netCDF variable with no data conversion.
+void NcmpiVar::getVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, void* dataValues, MPI_Offset bufcount, MPI_Datatype buftype) const {
+ ncmpiCheck(ncmpi_get_vara(groupId, myId,&startp[0],&countp[0],dataValues, bufcount, buftype),__FILE__,__LINE__);
+}
+
+
+///////////
+
+// Reads a subsampled (strided) array section of values from a netCDF variable.
+void NcmpiVar::getVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const vector<MPI_Offset>& stridep, char* dataValues) const {
+ ncmpiCheck(ncmpi_get_vars_text(groupId, myId,&startp[0],&countp[0],&stridep[0],dataValues),__FILE__,__LINE__);
+}
+// Reads a subsampled (strided) array section of values from a netCDF variable.
+void NcmpiVar::getVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const vector<MPI_Offset>& stridep, unsigned char* dataValues) const {
+ ncmpiCheck(ncmpi_get_vars_uchar(groupId, myId,&startp[0],&countp[0],&stridep[0],dataValues),__FILE__,__LINE__);
+}
+// Reads a subsampled (strided) array section of values from a netCDF variable.
+void NcmpiVar::getVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const vector<MPI_Offset>& stridep, signed char* dataValues) const {
+ ncmpiCheck(ncmpi_get_vars_schar(groupId, myId,&startp[0],&countp[0],&stridep[0],dataValues),__FILE__,__LINE__);
+}
+// Reads a subsampled (strided) array section of values from a netCDF variable.
+void NcmpiVar::getVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const vector<MPI_Offset>& stridep, short* dataValues) const {
+ ncmpiCheck(ncmpi_get_vars_short(groupId, myId,&startp[0],&countp[0],&stridep[0],dataValues),__FILE__,__LINE__);
+}
+// Reads a subsampled (strided) array section of values from a netCDF variable.
+void NcmpiVar::getVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const vector<MPI_Offset>& stridep, int* dataValues) const {
+ ncmpiCheck(ncmpi_get_vars_int(groupId, myId,&startp[0],&countp[0],&stridep[0],dataValues),__FILE__,__LINE__);
+}
+// Reads a subsampled (strided) array section of values from a netCDF variable.
+void NcmpiVar::getVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const vector<MPI_Offset>& stridep, long* dataValues) const {
+ ncmpiCheck(ncmpi_get_vars_long(groupId, myId,&startp[0],&countp[0],&stridep[0],dataValues),__FILE__,__LINE__);
+}
+// Reads a subsampled (strided) array section of values from a netCDF variable.
+void NcmpiVar::getVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const vector<MPI_Offset>& stridep, float* dataValues) const {
+ ncmpiCheck(ncmpi_get_vars_float(groupId, myId,&startp[0],&countp[0],&stridep[0],dataValues),__FILE__,__LINE__);
+}
+// Reads a subsampled (strided) array section of values from a netCDF variable.
+void NcmpiVar::getVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const vector<MPI_Offset>& stridep, double* dataValues) const {
+ ncmpiCheck(ncmpi_get_vars_double(groupId, myId,&startp[0],&countp[0],&stridep[0],dataValues),__FILE__,__LINE__);
+}
+// Reads a subsampled (strided) array section of values from a netCDF variable.
+void NcmpiVar::getVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const vector<MPI_Offset>& stridep, unsigned short* dataValues) const {
+ ncmpiCheck(ncmpi_get_vars_ushort(groupId, myId,&startp[0],&countp[0],&stridep[0],dataValues),__FILE__,__LINE__);
+}
+// Reads a subsampled (strided) array section of values from a netCDF variable.
+void NcmpiVar::getVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const vector<MPI_Offset>& stridep, unsigned int* dataValues) const {
+ ncmpiCheck(ncmpi_get_vars_uint(groupId, myId,&startp[0],&countp[0],&stridep[0],dataValues),__FILE__,__LINE__);
+}
+// Reads a subsampled (strided) array section of values from a netCDF variable.
+void NcmpiVar::getVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const vector<MPI_Offset>& stridep, long long* dataValues) const {
+ ncmpiCheck(ncmpi_get_vars_longlong(groupId, myId,&startp[0],&countp[0],&stridep[0],dataValues),__FILE__,__LINE__);
+}
+// Reads a subsampled (strided) array section of values from a netCDF variable
+void NcmpiVar::getVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const vector<MPI_Offset>& stridep, unsigned long long* dataValues) const {
+ ncmpiCheck(ncmpi_get_vars_ulonglong(groupId, myId,&startp[0],&countp[0],&stridep[0],dataValues),__FILE__,__LINE__);
+}
+// Reads a subsampled (strided) array section of values from a netCDF variable with no data conversion.
+void NcmpiVar::getVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const vector<MPI_Offset>& stridep, void* dataValues, MPI_Offset bufcount, MPI_Datatype buftype) const {
+ ncmpiCheck(ncmpi_get_vars(groupId, myId,&startp[0],&countp[0],&stridep[0],dataValues, bufcount, buftype),__FILE__,__LINE__);
+}
+
+
+///////////
+
+// Reads a mapped array section of values from a netCDF variable.
+void NcmpiVar::getVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const vector<MPI_Offset>& stridep, const vector<MPI_Offset>& imapp, char* dataValues) const {
+ ncmpiCheck(ncmpi_get_varm_text(groupId, myId,&startp[0],&countp[0],&stridep[0],&imapp[0],dataValues),__FILE__,__LINE__);
+}
+// Reads a mapped array section of values from a netCDF variable.
+void NcmpiVar::getVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const vector<MPI_Offset>& stridep, const vector<MPI_Offset>& imapp, unsigned char* dataValues) const {
+ ncmpiCheck(ncmpi_get_varm_uchar(groupId, myId,&startp[0],&countp[0],&stridep[0],&imapp[0],dataValues),__FILE__,__LINE__);
+}
+// Reads a mapped array section of values from a netCDF variable.
+void NcmpiVar::getVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const vector<MPI_Offset>& stridep, const vector<MPI_Offset>& imapp, signed char* dataValues) const {
+ ncmpiCheck(ncmpi_get_varm_schar(groupId, myId,&startp[0],&countp[0],&stridep[0],&imapp[0],dataValues),__FILE__,__LINE__);
+}
+// Reads a mapped array section of values from a netCDF variable.
+void NcmpiVar::getVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const vector<MPI_Offset>& stridep, const vector<MPI_Offset>& imapp, short* dataValues) const {
+ ncmpiCheck(ncmpi_get_varm_short(groupId, myId,&startp[0],&countp[0],&stridep[0],&imapp[0],dataValues),__FILE__,__LINE__);
+}
+// Reads a mapped array section of values from a netCDF variable.
+void NcmpiVar::getVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const vector<MPI_Offset>& stridep, const vector<MPI_Offset>& imapp, int* dataValues) const {
+ ncmpiCheck(ncmpi_get_varm_int(groupId, myId,&startp[0],&countp[0],&stridep[0],&imapp[0],dataValues),__FILE__,__LINE__);
+}
+// Reads a mapped array section of values from a netCDF variable.
+void NcmpiVar::getVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const vector<MPI_Offset>& stridep, const vector<MPI_Offset>& imapp, long* dataValues) const {
+ ncmpiCheck(ncmpi_get_varm_long(groupId, myId,&startp[0],&countp[0],&stridep[0],&imapp[0],dataValues),__FILE__,__LINE__);
+}
+// Reads a mapped array section of values from a netCDF variable.
+void NcmpiVar::getVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const vector<MPI_Offset>& stridep, const vector<MPI_Offset>& imapp, float* dataValues) const {
+ ncmpiCheck(ncmpi_get_varm_float(groupId, myId,&startp[0],&countp[0],&stridep[0],&imapp[0],dataValues),__FILE__,__LINE__);
+}
+// Reads a mapped array section of values from a netCDF variable.
+void NcmpiVar::getVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const vector<MPI_Offset>& stridep, const vector<MPI_Offset>& imapp, double* dataValues) const {
+ ncmpiCheck(ncmpi_get_varm_double(groupId, myId,&startp[0],&countp[0],&stridep[0],&imapp[0],dataValues),__FILE__,__LINE__);
+}
+// Reads a mapped array section of values from a netCDF variable.
+void NcmpiVar::getVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const vector<MPI_Offset>& stridep, const vector<MPI_Offset>& imapp, unsigned short* dataValues) const {
+ ncmpiCheck(ncmpi_get_varm_ushort(groupId, myId,&startp[0],&countp[0],&stridep[0],&imapp[0],dataValues),__FILE__,__LINE__);
+}
+// Reads a mapped array section of values from a netCDF variable.
+void NcmpiVar::getVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const vector<MPI_Offset>& stridep, const vector<MPI_Offset>& imapp, unsigned int* dataValues) const {
+ ncmpiCheck(ncmpi_get_varm_uint(groupId, myId,&startp[0],&countp[0],&stridep[0],&imapp[0],dataValues),__FILE__,__LINE__);
+}
+// Reads a mapped array section of values from a netCDF variable.
+void NcmpiVar::getVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const vector<MPI_Offset>& stridep, const vector<MPI_Offset>& imapp, long long* dataValues) const {
+ ncmpiCheck(ncmpi_get_varm_longlong(groupId, myId,&startp[0],&countp[0],&stridep[0],&imapp[0],dataValues),__FILE__,__LINE__);
+}
+// Reads a mapped array section of values from a netCDF variable
+void NcmpiVar::getVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const vector<MPI_Offset>& stridep, const vector<MPI_Offset>& imapp, unsigned long long* dataValues) const {
+ ncmpiCheck(ncmpi_get_varm_ulonglong(groupId, myId,&startp[0],&countp[0],&stridep[0],&imapp[0],dataValues),__FILE__,__LINE__);
+}
+// Reads a mapped array section of values from a netCDF variable with no data conversion.
+void NcmpiVar::getVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const vector<MPI_Offset>& stridep, const vector<MPI_Offset>& imapp, void* dataValues, MPI_Offset bufcount, MPI_Datatype buftype) const {
+ ncmpiCheck(ncmpi_get_varm(groupId, myId,&startp[0],&countp[0],&stridep[0],&imapp[0],dataValues, bufcount, buftype),__FILE__,__LINE__);
+}
+
+//
+// Data reading (collective data mode)
+//
+
+// Reads the entire data of the netCDF variable.
+void NcmpiVar::getVar_all(char* dataValues) const {
+ ncmpiCheck(ncmpi_get_var_text_all(groupId, myId,dataValues),__FILE__,__LINE__);
+}
+// Reads the entire data of the netCDF variable.
+void NcmpiVar::getVar_all(unsigned char* dataValues) const {
+ ncmpiCheck(ncmpi_get_var_uchar_all(groupId, myId,dataValues),__FILE__,__LINE__);
+}
+// Reads the entire data of the netCDF variable.
+void NcmpiVar::getVar_all(signed char* dataValues) const {
+ ncmpiCheck(ncmpi_get_var_schar_all(groupId, myId,dataValues),__FILE__,__LINE__);
+}
+// Reads the entire data of the netCDF variable.
+void NcmpiVar::getVar_all(short* dataValues) const {
+ ncmpiCheck(ncmpi_get_var_short_all(groupId, myId,dataValues),__FILE__,__LINE__);
+}
+// Reads the entire data of the netCDF variable.
+void NcmpiVar::getVar_all(int* dataValues) const {
+ ncmpiCheck(ncmpi_get_var_int_all(groupId, myId,dataValues),__FILE__,__LINE__);
+}
+// Reads the entire data of the netCDF variable.
+void NcmpiVar::getVar_all(long* dataValues) const {
+ ncmpiCheck(ncmpi_get_var_long_all(groupId, myId,dataValues),__FILE__,__LINE__);
+}
+// Reads the entire data of the netCDF variable.
+void NcmpiVar::getVar_all(float* dataValues) const {
+ ncmpiCheck(ncmpi_get_var_float_all(groupId, myId,dataValues),__FILE__,__LINE__);
+}
+// Reads the entire data of the netCDF variable.
+void NcmpiVar::getVar_all(double* dataValues) const {
+ ncmpiCheck(ncmpi_get_var_double_all(groupId, myId,dataValues),__FILE__,__LINE__);
+}
+// Reads the entire data of the netCDF variable.
+void NcmpiVar::getVar_all(unsigned short* dataValues) const {
+ ncmpiCheck(ncmpi_get_var_ushort_all(groupId, myId,dataValues),__FILE__,__LINE__);
+}
+// Reads the entire data of the netCDF variable.
+void NcmpiVar::getVar_all(unsigned int* dataValues) const {
+ ncmpiCheck(ncmpi_get_var_uint_all(groupId, myId,dataValues),__FILE__,__LINE__);
+}
+// Reads the entire data of the netCDF variable.
+void NcmpiVar::getVar_all(long long* dataValues) const {
+ ncmpiCheck(ncmpi_get_var_longlong_all(groupId, myId,dataValues),__FILE__,__LINE__);
+}
+// Reads the entire data of the netCDF variable.
+void NcmpiVar::getVar_all(unsigned long long* dataValues) const {
+ ncmpiCheck(ncmpi_get_var_ulonglong_all(groupId, myId,dataValues),__FILE__,__LINE__);
+}
+// Reads the entire data of the netCDF variable with no data conversion.
+void NcmpiVar::getVar_all(void* dataValues, MPI_Offset bufcount, MPI_Datatype buftype) const {
+ ncmpiCheck(ncmpi_get_var_all(groupId, myId,dataValues, bufcount, buftype),__FILE__,__LINE__);
+}
+
+
+///////////
+
+// Reads a single datum value of a netCDF variable.
+void NcmpiVar::getVar_all(const vector<MPI_Offset>& index, char* datumValue) const {
+ ncmpiCheck(ncmpi_get_var1_text_all(groupId, myId,&index[0],datumValue),__FILE__,__LINE__);
+}
+// Reads a single datum value of a netCDF variable.
+void NcmpiVar::getVar_all(const vector<MPI_Offset>& index, unsigned char* datumValue) const {
+ ncmpiCheck(ncmpi_get_var1_uchar_all(groupId, myId,&index[0],datumValue),__FILE__,__LINE__);
+}
+// Reads a single datum value of a netCDF variable.
+void NcmpiVar::getVar_all(const vector<MPI_Offset>& index, signed char* datumValue) const {
+ ncmpiCheck(ncmpi_get_var1_schar_all(groupId, myId,&index[0],datumValue),__FILE__,__LINE__);
+}
+// Reads a single datum value of a netCDF variable.
+void NcmpiVar::getVar_all(const vector<MPI_Offset>& index, short* datumValue) const {
+ ncmpiCheck(ncmpi_get_var1_short_all(groupId, myId,&index[0],datumValue),__FILE__,__LINE__);
+}
+// Reads a single datum value of a netCDF variable.
+void NcmpiVar::getVar_all(const vector<MPI_Offset>& index, int* datumValue) const {
+ ncmpiCheck(ncmpi_get_var1_int_all(groupId, myId,&index[0],datumValue),__FILE__,__LINE__);
+}
+// Reads a single datum value of a netCDF variable.
+void NcmpiVar::getVar_all(const vector<MPI_Offset>& index, long* datumValue) const {
+ ncmpiCheck(ncmpi_get_var1_long_all(groupId, myId,&index[0],datumValue),__FILE__,__LINE__);
+}
+// Reads a single datum value of a netCDF variable.
+void NcmpiVar::getVar_all(const vector<MPI_Offset>& index, float* datumValue) const {
+ ncmpiCheck(ncmpi_get_var1_float_all(groupId, myId,&index[0],datumValue),__FILE__,__LINE__);
+}
+// Reads a single datum value of a netCDF variable.
+void NcmpiVar::getVar_all(const vector<MPI_Offset>& index, double* datumValue) const {
+ ncmpiCheck(ncmpi_get_var1_double_all(groupId, myId,&index[0],datumValue),__FILE__,__LINE__);
+}
+// Reads a single datum value of a netCDF variable.
+void NcmpiVar::getVar_all(const vector<MPI_Offset>& index, unsigned short* datumValue) const {
+ ncmpiCheck(ncmpi_get_var1_ushort_all(groupId, myId,&index[0],datumValue),__FILE__,__LINE__);
+}
+// Reads a single datum value of a netCDF variable.
+void NcmpiVar::getVar_all(const vector<MPI_Offset>& index, unsigned int* datumValue) const {
+ ncmpiCheck(ncmpi_get_var1_uint_all(groupId, myId,&index[0],datumValue),__FILE__,__LINE__);
+}
+// Reads a single datum value of a netCDF variable.
+void NcmpiVar::getVar_all(const vector<MPI_Offset>& index, long long* datumValue) const {
+ ncmpiCheck(ncmpi_get_var1_longlong_all(groupId, myId,&index[0],datumValue),__FILE__,__LINE__);
+}
+// Reads a single datum value of a netCDF variable
+void NcmpiVar::getVar_all(const vector<MPI_Offset>& index, unsigned long long* datumValue) const {
+ ncmpiCheck(ncmpi_get_var1_ulonglong_all(groupId, myId,&index[0],datumValue),__FILE__,__LINE__);
+}
+// Reads a single datum value of a netCDF variable with no data conversion.
+void NcmpiVar::getVar_all(const vector<MPI_Offset>& index, void* datumValue, MPI_Offset bufcount, MPI_Datatype buftype) const {
+ ncmpiCheck(ncmpi_get_var1_all(groupId, myId,&index[0],datumValue, bufcount, buftype),__FILE__,__LINE__);
+}
+
+///////////
+
+// Reads an array of values from a netCDF variable.
+void NcmpiVar::getVar_all(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, char* dataValues) const {
+ ncmpiCheck(ncmpi_get_vara_text_all(groupId, myId,&startp[0],&countp[0],dataValues),__FILE__,__LINE__);
+}
+// Reads an array of values from a netCDF variable.
+void NcmpiVar::getVar_all(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, unsigned char* dataValues) const {
+ ncmpiCheck(ncmpi_get_vara_uchar_all(groupId, myId,&startp[0],&countp[0],dataValues),__FILE__,__LINE__);
+}
+// Reads an array of values from a netCDF variable.
+void NcmpiVar::getVar_all(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, signed char* dataValues) const {
+ ncmpiCheck(ncmpi_get_vara_schar_all(groupId, myId,&startp[0],&countp[0],dataValues),__FILE__,__LINE__);
+}
+// Reads an array of values from a netCDF variable.
+void NcmpiVar::getVar_all(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, short* dataValues) const {
+ ncmpiCheck(ncmpi_get_vara_short_all(groupId, myId,&startp[0],&countp[0],dataValues),__FILE__,__LINE__);
+}
+// Reads an array of values from a netCDF variable.
+void NcmpiVar::getVar_all(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, int* dataValues) const {
+ ncmpiCheck(ncmpi_get_vara_int_all(groupId, myId,&startp[0],&countp[0],dataValues),__FILE__,__LINE__);
+}
+// Reads an array of values from a netCDF variable.
+void NcmpiVar::getVar_all(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, long* dataValues) const {
+ ncmpiCheck(ncmpi_get_vara_long_all(groupId, myId,&startp[0],&countp[0],dataValues),__FILE__,__LINE__);
+}
+// Reads an array of values from a netCDF variable.
+void NcmpiVar::getVar_all(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, float* dataValues) const {
+ ncmpiCheck(ncmpi_get_vara_float_all(groupId, myId,&startp[0],&countp[0],dataValues),__FILE__,__LINE__);
+}
+// Reads an array of values from a netCDF variable.
+void NcmpiVar::getVar_all(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, double* dataValues) const {
+ ncmpiCheck(ncmpi_get_vara_double_all(groupId, myId,&startp[0],&countp[0],dataValues),__FILE__,__LINE__);
+}
+// Reads an array of values from a netCDF variable.
+void NcmpiVar::getVar_all(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, unsigned short* dataValues) const {
+ ncmpiCheck(ncmpi_get_vara_ushort_all(groupId, myId,&startp[0],&countp[0],dataValues),__FILE__,__LINE__);
+}
+// Reads an array of values from a netCDF variable.
+void NcmpiVar::getVar_all(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, unsigned int* dataValues) const {
+ ncmpiCheck(ncmpi_get_vara_uint_all(groupId, myId,&startp[0],&countp[0],dataValues),__FILE__,__LINE__);
+}
+// Reads an array of values from a netCDF variable.
+void NcmpiVar::getVar_all(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, long long* dataValues) const {
+ ncmpiCheck(ncmpi_get_vara_longlong_all(groupId, myId,&startp[0],&countp[0],dataValues),__FILE__,__LINE__);
+}
+// Reads an array of values from a netCDF variable
+void NcmpiVar::getVar_all(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, unsigned long long* dataValues) const {
+ ncmpiCheck(ncmpi_get_vara_ulonglong_all(groupId, myId,&startp[0],&countp[0],dataValues),__FILE__,__LINE__);
+}
+// Reads an array of values from a netCDF variable with no data conversion.
+void NcmpiVar::getVar_all(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, void* dataValues, MPI_Offset bufcount, MPI_Datatype buftype) const {
+ ncmpiCheck(ncmpi_get_vara_all(groupId, myId,&startp[0],&countp[0],dataValues, bufcount, buftype),__FILE__,__LINE__);
+}
+
+
+///////////
+
+// Reads a subsampled (strided) array section of values from a netCDF variable.
+void NcmpiVar::getVar_all(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const vector<MPI_Offset>& stridep, char* dataValues) const {
+ ncmpiCheck(ncmpi_get_vars_text_all(groupId, myId,&startp[0],&countp[0],&stridep[0],dataValues),__FILE__,__LINE__);
+}
+// Reads a subsampled (strided) array section of values from a netCDF variable.
+void NcmpiVar::getVar_all(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const vector<MPI_Offset>& stridep, unsigned char* dataValues) const {
+ ncmpiCheck(ncmpi_get_vars_uchar_all(groupId, myId,&startp[0],&countp[0],&stridep[0],dataValues),__FILE__,__LINE__);
+}
+// Reads a subsampled (strided) array section of values from a netCDF variable.
+void NcmpiVar::getVar_all(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const vector<MPI_Offset>& stridep, signed char* dataValues) const {
+ ncmpiCheck(ncmpi_get_vars_schar_all(groupId, myId,&startp[0],&countp[0],&stridep[0],dataValues),__FILE__,__LINE__);
+}
+// Reads a subsampled (strided) array section of values from a netCDF variable.
+void NcmpiVar::getVar_all(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const vector<MPI_Offset>& stridep, short* dataValues) const {
+ ncmpiCheck(ncmpi_get_vars_short_all(groupId, myId,&startp[0],&countp[0],&stridep[0],dataValues),__FILE__,__LINE__);
+}
+// Reads a subsampled (strided) array section of values from a netCDF variable.
+void NcmpiVar::getVar_all(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const vector<MPI_Offset>& stridep, int* dataValues) const {
+ ncmpiCheck(ncmpi_get_vars_int_all(groupId, myId,&startp[0],&countp[0],&stridep[0],dataValues),__FILE__,__LINE__);
+}
+// Reads a subsampled (strided) array section of values from a netCDF variable.
+void NcmpiVar::getVar_all(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const vector<MPI_Offset>& stridep, long* dataValues) const {
+ ncmpiCheck(ncmpi_get_vars_long_all(groupId, myId,&startp[0],&countp[0],&stridep[0],dataValues),__FILE__,__LINE__);
+}
+// Reads a subsampled (strided) array section of values from a netCDF variable.
+void NcmpiVar::getVar_all(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const vector<MPI_Offset>& stridep, float* dataValues) const {
+ ncmpiCheck(ncmpi_get_vars_float_all(groupId, myId,&startp[0],&countp[0],&stridep[0],dataValues),__FILE__,__LINE__);
+}
+// Reads a subsampled (strided) array section of values from a netCDF variable.
+void NcmpiVar::getVar_all(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const vector<MPI_Offset>& stridep, double* dataValues) const {
+ ncmpiCheck(ncmpi_get_vars_double_all(groupId, myId,&startp[0],&countp[0],&stridep[0],dataValues),__FILE__,__LINE__);
+}
+// Reads a subsampled (strided) array section of values from a netCDF variable.
+void NcmpiVar::getVar_all(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const vector<MPI_Offset>& stridep, unsigned short* dataValues) const {
+ ncmpiCheck(ncmpi_get_vars_ushort_all(groupId, myId,&startp[0],&countp[0],&stridep[0],dataValues),__FILE__,__LINE__);
+}
+// Reads a subsampled (strided) array section of values from a netCDF variable.
+void NcmpiVar::getVar_all(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const vector<MPI_Offset>& stridep, unsigned int* dataValues) const {
+ ncmpiCheck(ncmpi_get_vars_uint_all(groupId, myId,&startp[0],&countp[0],&stridep[0],dataValues),__FILE__,__LINE__);
+}
+// Reads a subsampled (strided) array section of values from a netCDF variable.
+void NcmpiVar::getVar_all(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const vector<MPI_Offset>& stridep, long long* dataValues) const {
+ ncmpiCheck(ncmpi_get_vars_longlong_all(groupId, myId,&startp[0],&countp[0],&stridep[0],dataValues),__FILE__,__LINE__);
+}
+// Reads a subsampled (strided) array section of values from a netCDF variable
+void NcmpiVar::getVar_all(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const vector<MPI_Offset>& stridep, unsigned long long* dataValues) const {
+ ncmpiCheck(ncmpi_get_vars_ulonglong_all(groupId, myId,&startp[0],&countp[0],&stridep[0],dataValues),__FILE__,__LINE__);
+}
+// Reads a subsampled (strided) array section of values from a netCDF variable with no data conversion.
+void NcmpiVar::getVar_all(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const vector<MPI_Offset>& stridep, void* dataValues, MPI_Offset bufcount, MPI_Datatype buftype) const {
+ ncmpiCheck(ncmpi_get_vars_all(groupId, myId,&startp[0],&countp[0],&stridep[0],dataValues, bufcount, buftype),__FILE__,__LINE__);
+}
+
+
+///////////
+
+// Reads a mapped array section of values from a netCDF variable.
+void NcmpiVar::getVar_all(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const vector<MPI_Offset>& stridep, const vector<MPI_Offset>& imapp, char* dataValues) const {
+ ncmpiCheck(ncmpi_get_varm_text_all(groupId, myId,&startp[0],&countp[0],&stridep[0],&imapp[0],dataValues),__FILE__,__LINE__);
+}
+// Reads a mapped array section of values from a netCDF variable.
+void NcmpiVar::getVar_all(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const vector<MPI_Offset>& stridep, const vector<MPI_Offset>& imapp, unsigned char* dataValues) const {
+ ncmpiCheck(ncmpi_get_varm_uchar_all(groupId, myId,&startp[0],&countp[0],&stridep[0],&imapp[0],dataValues),__FILE__,__LINE__);
+}
+// Reads a mapped array section of values from a netCDF variable.
+void NcmpiVar::getVar_all(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const vector<MPI_Offset>& stridep, const vector<MPI_Offset>& imapp, signed char* dataValues) const {
+ ncmpiCheck(ncmpi_get_varm_schar_all(groupId, myId,&startp[0],&countp[0],&stridep[0],&imapp[0],dataValues),__FILE__,__LINE__);
+}
+// Reads a mapped array section of values from a netCDF variable.
+void NcmpiVar::getVar_all(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const vector<MPI_Offset>& stridep, const vector<MPI_Offset>& imapp, short* dataValues) const {
+ ncmpiCheck(ncmpi_get_varm_short_all(groupId, myId,&startp[0],&countp[0],&stridep[0],&imapp[0],dataValues),__FILE__,__LINE__);
+}
+// Reads a mapped array section of values from a netCDF variable.
+void NcmpiVar::getVar_all(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const vector<MPI_Offset>& stridep, const vector<MPI_Offset>& imapp, int* dataValues) const {
+ ncmpiCheck(ncmpi_get_varm_int_all(groupId, myId,&startp[0],&countp[0],&stridep[0],&imapp[0],dataValues),__FILE__,__LINE__);
+}
+// Reads a mapped array section of values from a netCDF variable.
+void NcmpiVar::getVar_all(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const vector<MPI_Offset>& stridep, const vector<MPI_Offset>& imapp, long* dataValues) const {
+ ncmpiCheck(ncmpi_get_varm_long_all(groupId, myId,&startp[0],&countp[0],&stridep[0],&imapp[0],dataValues),__FILE__,__LINE__);
+}
+// Reads a mapped array section of values from a netCDF variable.
+void NcmpiVar::getVar_all(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const vector<MPI_Offset>& stridep, const vector<MPI_Offset>& imapp, float* dataValues) const {
+ ncmpiCheck(ncmpi_get_varm_float_all(groupId, myId,&startp[0],&countp[0],&stridep[0],&imapp[0],dataValues),__FILE__,__LINE__);
+}
+// Reads a mapped array section of values from a netCDF variable.
+void NcmpiVar::getVar_all(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const vector<MPI_Offset>& stridep, const vector<MPI_Offset>& imapp, double* dataValues) const {
+ ncmpiCheck(ncmpi_get_varm_double_all(groupId, myId,&startp[0],&countp[0],&stridep[0],&imapp[0],dataValues),__FILE__,__LINE__);
+}
+// Reads a mapped array section of values from a netCDF variable.
+void NcmpiVar::getVar_all(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const vector<MPI_Offset>& stridep, const vector<MPI_Offset>& imapp, unsigned short* dataValues) const {
+ ncmpiCheck(ncmpi_get_varm_ushort_all(groupId, myId,&startp[0],&countp[0],&stridep[0],&imapp[0],dataValues),__FILE__,__LINE__);
+}
+// Reads a mapped array section of values from a netCDF variable.
+void NcmpiVar::getVar_all(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const vector<MPI_Offset>& stridep, const vector<MPI_Offset>& imapp, unsigned int* dataValues) const {
+ ncmpiCheck(ncmpi_get_varm_uint_all(groupId, myId,&startp[0],&countp[0],&stridep[0],&imapp[0],dataValues),__FILE__,__LINE__);
+}
+// Reads a mapped array section of values from a netCDF variable.
+void NcmpiVar::getVar_all(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const vector<MPI_Offset>& stridep, const vector<MPI_Offset>& imapp, long long* dataValues) const {
+ ncmpiCheck(ncmpi_get_varm_longlong_all(groupId, myId,&startp[0],&countp[0],&stridep[0],&imapp[0],dataValues),__FILE__,__LINE__);
+}
+// Reads a mapped array section of values from a netCDF variable
+void NcmpiVar::getVar_all(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const vector<MPI_Offset>& stridep, const vector<MPI_Offset>& imapp, unsigned long long* dataValues) const {
+ ncmpiCheck(ncmpi_get_varm_ulonglong_all(groupId, myId,&startp[0],&countp[0],&stridep[0],&imapp[0],dataValues),__FILE__,__LINE__);
+}
+// Reads a mapped array section of values from a netCDF variable with no data conversion.
+void NcmpiVar::getVar_all(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const vector<MPI_Offset>& stridep, const vector<MPI_Offset>& imapp, void* dataValues, MPI_Offset bufcount, MPI_Datatype buftype) const {
+ ncmpiCheck(ncmpi_get_varm_all(groupId, myId,&startp[0],&countp[0],&stridep[0],&imapp[0],dataValues, bufcount, buftype),__FILE__,__LINE__);
+}
+
+//////////////////////
+
+// Reads a list of subarrays from a netCDF variable. (independent I/O APIs)
+void NcmpiVar::getVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], char* dataValues) const {
+ ncmpiCheck(ncmpi_get_varn_text(groupId, myId, num, starts, counts, dataValues),__FILE__,__LINE__);
+}
+// Reads an array of values from a netCDF variable.
+void NcmpiVar::getVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], unsigned char* dataValues) const {
+ ncmpiCheck(ncmpi_get_varn_uchar(groupId, myId, num, starts, counts, dataValues),__FILE__,__LINE__);
+}
+// Reads an array of values from a netCDF variable.
+void NcmpiVar::getVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], signed char* dataValues) const {
+ ncmpiCheck(ncmpi_get_varn_schar(groupId, myId, num, starts, counts, dataValues),__FILE__,__LINE__);
+}
+// Reads an array of values from a netCDF variable.
+void NcmpiVar::getVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], short* dataValues) const {
+ ncmpiCheck(ncmpi_get_varn_short(groupId, myId, num, starts, counts, dataValues),__FILE__,__LINE__);
+}
+// Reads an array of values from a netCDF variable.
+void NcmpiVar::getVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], int* dataValues) const {
+ ncmpiCheck(ncmpi_get_varn_int(groupId, myId, num, starts, counts, dataValues),__FILE__,__LINE__);
+}
+// Reads an array of values from a netCDF variable.
+void NcmpiVar::getVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], long* dataValues) const {
+ ncmpiCheck(ncmpi_get_varn_long(groupId, myId, num, starts, counts, dataValues),__FILE__,__LINE__);
+}
+// Reads an array of values from a netCDF variable.
+void NcmpiVar::getVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], float* dataValues) const {
+ ncmpiCheck(ncmpi_get_varn_float(groupId, myId, num, starts, counts, dataValues),__FILE__,__LINE__);
+}
+// Reads an array of values from a netCDF variable.
+void NcmpiVar::getVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], double* dataValues) const {
+ ncmpiCheck(ncmpi_get_varn_double(groupId, myId, num, starts, counts, dataValues),__FILE__,__LINE__);
+}
+// Reads an array of values from a netCDF variable.
+void NcmpiVar::getVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], unsigned short* dataValues) const {
+ ncmpiCheck(ncmpi_get_varn_ushort(groupId, myId, num, starts, counts, dataValues),__FILE__,__LINE__);
+}
+// Reads an array of values from a netCDF variable.
+void NcmpiVar::getVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], unsigned int* dataValues) const {
+ ncmpiCheck(ncmpi_get_varn_uint(groupId, myId, num, starts, counts, dataValues),__FILE__,__LINE__);
+}
+// Reads an array of values from a netCDF variable.
+void NcmpiVar::getVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], long long* dataValues) const {
+ ncmpiCheck(ncmpi_get_varn_longlong(groupId, myId, num, starts, counts, dataValues),__FILE__,__LINE__);
+}
+// Reads an array of values from a netCDF variable
+void NcmpiVar::getVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], unsigned long long* dataValues) const {
+ ncmpiCheck(ncmpi_get_varn_ulonglong(groupId, myId, num, starts, counts, dataValues),__FILE__,__LINE__);
+}
+// Reads an array of values from a netCDF variable with no data conversion.
+void NcmpiVar::getVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], void* dataValues, MPI_Offset bufcount, MPI_Datatype buftype) const {
+ ncmpiCheck(ncmpi_get_varn(groupId, myId, num, starts, counts, dataValues, bufcount, buftype),__FILE__,__LINE__);
+}
+
+//////////////////////
+
+// Reads a list of subarrays from a netCDF variable. (collective I/O APIs)
+void NcmpiVar::getVarn_all(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], char* dataValues) const {
+ ncmpiCheck(ncmpi_get_varn_text_all(groupId, myId, num, starts, counts, dataValues),__FILE__,__LINE__);
+}
+// Reads an array of values from a netCDF variable.
+void NcmpiVar::getVarn_all(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], unsigned char* dataValues) const {
+ ncmpiCheck(ncmpi_get_varn_uchar_all(groupId, myId, num, starts, counts, dataValues),__FILE__,__LINE__);
+}
+// Reads an array of values from a netCDF variable.
+void NcmpiVar::getVarn_all(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], signed char* dataValues) const {
+ ncmpiCheck(ncmpi_get_varn_schar_all(groupId, myId, num, starts, counts, dataValues),__FILE__,__LINE__);
+}
+// Reads an array of values from a netCDF variable.
+void NcmpiVar::getVarn_all(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], short* dataValues) const {
+ ncmpiCheck(ncmpi_get_varn_short_all(groupId, myId, num, starts, counts, dataValues),__FILE__,__LINE__);
+}
+// Reads an array of values from a netCDF variable.
+void NcmpiVar::getVarn_all(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], int* dataValues) const {
+ ncmpiCheck(ncmpi_get_varn_int_all(groupId, myId, num, starts, counts, dataValues),__FILE__,__LINE__);
+}
+// Reads an array of values from a netCDF variable.
+void NcmpiVar::getVarn_all(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], long* dataValues) const {
+ ncmpiCheck(ncmpi_get_varn_long_all(groupId, myId, num, starts, counts, dataValues),__FILE__,__LINE__);
+}
+// Reads an array of values from a netCDF variable.
+void NcmpiVar::getVarn_all(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], float* dataValues) const {
+ ncmpiCheck(ncmpi_get_varn_float_all(groupId, myId, num, starts, counts, dataValues),__FILE__,__LINE__);
+}
+// Reads an array of values from a netCDF variable.
+void NcmpiVar::getVarn_all(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], double* dataValues) const {
+ ncmpiCheck(ncmpi_get_varn_double_all(groupId, myId, num, starts, counts, dataValues),__FILE__,__LINE__);
+}
+// Reads an array of values from a netCDF variable.
+void NcmpiVar::getVarn_all(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], unsigned short* dataValues) const {
+ ncmpiCheck(ncmpi_get_varn_ushort_all(groupId, myId, num, starts, counts, dataValues),__FILE__,__LINE__);
+}
+// Reads an array of values from a netCDF variable.
+void NcmpiVar::getVarn_all(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], unsigned int* dataValues) const {
+ ncmpiCheck(ncmpi_get_varn_uint_all(groupId, myId, num, starts, counts, dataValues),__FILE__,__LINE__);
+}
+// Reads an array of values from a netCDF variable.
+void NcmpiVar::getVarn_all(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], long long* dataValues) const {
+ ncmpiCheck(ncmpi_get_varn_longlong_all(groupId, myId, num, starts, counts, dataValues),__FILE__,__LINE__);
+}
+// Reads an array of values from a netCDF variable
+void NcmpiVar::getVarn_all(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], unsigned long long* dataValues) const {
+ ncmpiCheck(ncmpi_get_varn_ulonglong_all(groupId, myId, num, starts, counts, dataValues),__FILE__,__LINE__);
+}
+// Reads an array of values from a netCDF variable with no data conversion.
+void NcmpiVar::getVarn_all(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], void* dataValues, MPI_Offset bufcount, MPI_Datatype buftype) const {
+ ncmpiCheck(ncmpi_get_varn_all(groupId, myId, num, starts, counts, dataValues, bufcount, buftype),__FILE__,__LINE__);
+}
+
+
+// Reads an array of values from a netCDF variable with filetype and buftype.
+void NcmpiVar::getVard(MPI_Datatype filetype, void* dataValues, MPI_Offset bufcount, MPI_Datatype buftype) const {
+ ncmpiCheck(ncmpi_get_vard(groupId, myId, filetype, dataValues, bufcount, buftype),__FILE__,__LINE__);
+}
+
+// Reads an array of values from a netCDF variable with filetype and buftype.
+void NcmpiVar::getVard_all(MPI_Datatype filetype, void* dataValues, MPI_Offset bufcount, MPI_Datatype buftype) const {
+ ncmpiCheck(ncmpi_get_vard_all(groupId, myId, filetype, dataValues, bufcount, buftype),__FILE__,__LINE__);
+}
+
+// Nonblocking data reading
+
+// Reads the entire data of the netCDF variable.
+void NcmpiVar::igetVar(char* dataValues, int *req) const {
+ ncmpiCheck(ncmpi_iget_var_text(groupId, myId,dataValues, req),__FILE__,__LINE__);
+}
+// Reads the entire data of the netCDF variable.
+void NcmpiVar::igetVar(unsigned char* dataValues, int *req) const {
+ ncmpiCheck(ncmpi_iget_var_uchar(groupId, myId,dataValues, req),__FILE__,__LINE__);
+}
+// Reads the entire data of the netCDF variable.
+void NcmpiVar::igetVar(signed char* dataValues, int *req) const {
+ ncmpiCheck(ncmpi_iget_var_schar(groupId, myId,dataValues, req),__FILE__,__LINE__);
+}
+// Reads the entire data of the netCDF variable.
+void NcmpiVar::igetVar(short* dataValues, int *req) const {
+ ncmpiCheck(ncmpi_iget_var_short(groupId, myId,dataValues, req),__FILE__,__LINE__);
+}
+// Reads the entire data of the netCDF variable.
+void NcmpiVar::igetVar(int* dataValues, int *req) const {
+ ncmpiCheck(ncmpi_iget_var_int(groupId, myId,dataValues, req),__FILE__,__LINE__);
+}
+// Reads the entire data of the netCDF variable.
+void NcmpiVar::igetVar(long* dataValues, int *req) const {
+ ncmpiCheck(ncmpi_iget_var_long(groupId, myId,dataValues, req),__FILE__,__LINE__);
+}
+// Reads the entire data of the netCDF variable.
+void NcmpiVar::igetVar(float* dataValues, int *req) const {
+ ncmpiCheck(ncmpi_iget_var_float(groupId, myId,dataValues, req),__FILE__,__LINE__);
+}
+// Reads the entire data of the netCDF variable.
+void NcmpiVar::igetVar(double* dataValues, int *req) const {
+ ncmpiCheck(ncmpi_iget_var_double(groupId, myId,dataValues, req),__FILE__,__LINE__);
+}
+// Reads the entire data of the netCDF variable.
+void NcmpiVar::igetVar(unsigned short* dataValues, int *req) const {
+ ncmpiCheck(ncmpi_iget_var_ushort(groupId, myId,dataValues, req),__FILE__,__LINE__);
+}
+// Reads the entire data of the netCDF variable.
+void NcmpiVar::igetVar(unsigned int* dataValues, int *req) const {
+ ncmpiCheck(ncmpi_iget_var_uint(groupId, myId,dataValues, req),__FILE__,__LINE__);
+}
+// Reads the entire data of the netCDF variable.
+void NcmpiVar::igetVar(long long* dataValues, int *req) const {
+ ncmpiCheck(ncmpi_iget_var_longlong(groupId, myId,dataValues, req),__FILE__,__LINE__);
+}
+// Reads the entire data of the netCDF variable.
+void NcmpiVar::igetVar(unsigned long long* dataValues, int *req) const {
+ ncmpiCheck(ncmpi_iget_var_ulonglong(groupId, myId,dataValues, req),__FILE__,__LINE__);
+}
+// Reads the entire data of the netCDF variable with no data conversion.
+void NcmpiVar::igetVar(void* dataValues, MPI_Offset bufcount, MPI_Datatype buftype, int *req) const {
+ ncmpiCheck(ncmpi_iget_var(groupId, myId,dataValues, bufcount, buftype, req),__FILE__,__LINE__);
+}
+
+
+
+///////////
+
+// Reads a single datum value of a netCDF variable.
+void NcmpiVar::igetVar(const vector<MPI_Offset>& index, char* datumValue, int *req) const {
+ ncmpiCheck(ncmpi_iget_var1_text(groupId, myId,&index[0],datumValue, req),__FILE__,__LINE__);
+}
+// Reads a single datum value of a netCDF variable.
+void NcmpiVar::igetVar(const vector<MPI_Offset>& index, unsigned char* datumValue, int *req) const {
+ ncmpiCheck(ncmpi_iget_var1_uchar(groupId, myId,&index[0],datumValue, req),__FILE__,__LINE__);
+}
+// Reads a single datum value of a netCDF variable.
+void NcmpiVar::igetVar(const vector<MPI_Offset>& index, signed char* datumValue, int *req) const {
+ ncmpiCheck(ncmpi_iget_var1_schar(groupId, myId,&index[0],datumValue, req),__FILE__,__LINE__);
+}
+// Reads a single datum value of a netCDF variable.
+void NcmpiVar::igetVar(const vector<MPI_Offset>& index, short* datumValue, int *req) const {
+ ncmpiCheck(ncmpi_iget_var1_short(groupId, myId,&index[0],datumValue, req),__FILE__,__LINE__);
+}
+// Reads a single datum value of a netCDF variable.
+void NcmpiVar::igetVar(const vector<MPI_Offset>& index, int* datumValue, int *req) const {
+ ncmpiCheck(ncmpi_iget_var1_int(groupId, myId,&index[0],datumValue, req),__FILE__,__LINE__);
+}
+// Reads a single datum value of a netCDF variable.
+void NcmpiVar::igetVar(const vector<MPI_Offset>& index, long* datumValue, int *req) const {
+ ncmpiCheck(ncmpi_iget_var1_long(groupId, myId,&index[0],datumValue, req),__FILE__,__LINE__);
+}
+// Reads a single datum value of a netCDF variable.
+void NcmpiVar::igetVar(const vector<MPI_Offset>& index, float* datumValue, int *req) const {
+ ncmpiCheck(ncmpi_iget_var1_float(groupId, myId,&index[0],datumValue, req),__FILE__,__LINE__);
+}
+// Reads a single datum value of a netCDF variable.
+void NcmpiVar::igetVar(const vector<MPI_Offset>& index, double* datumValue, int *req) const {
+ ncmpiCheck(ncmpi_iget_var1_double(groupId, myId,&index[0],datumValue, req),__FILE__,__LINE__);
+}
+// Reads a single datum value of a netCDF variable.
+void NcmpiVar::igetVar(const vector<MPI_Offset>& index, unsigned short* datumValue, int *req) const {
+ ncmpiCheck(ncmpi_iget_var1_ushort(groupId, myId,&index[0],datumValue, req),__FILE__,__LINE__);
+}
+// Reads a single datum value of a netCDF variable.
+void NcmpiVar::igetVar(const vector<MPI_Offset>& index, unsigned int* datumValue, int *req) const {
+ ncmpiCheck(ncmpi_iget_var1_uint(groupId, myId,&index[0],datumValue, req),__FILE__,__LINE__);
+}
+// Reads a single datum value of a netCDF variable.
+void NcmpiVar::igetVar(const vector<MPI_Offset>& index, long long* datumValue, int *req) const {
+ ncmpiCheck(ncmpi_iget_var1_longlong(groupId, myId,&index[0],datumValue, req),__FILE__,__LINE__);
+}
+// Reads a single datum value of a netCDF variable
+void NcmpiVar::igetVar(const vector<MPI_Offset>& index, unsigned long long* datumValue, int *req) const {
+ ncmpiCheck(ncmpi_iget_var1_ulonglong(groupId, myId,&index[0],datumValue, req),__FILE__,__LINE__);
+}
+// Reads a single datum value of a netCDF variable with no data conversion.
+void NcmpiVar::igetVar(const vector<MPI_Offset>& index, void* datumValue, MPI_Offset bufcount, MPI_Datatype buftype, int *req) const {
+ ncmpiCheck(ncmpi_iget_var1(groupId, myId,&index[0],datumValue, bufcount, buftype, req),__FILE__,__LINE__);
+}
+
+
+
+///////////
+
+// Reads an array of values from a netCDF variable.
+void NcmpiVar::igetVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, char* dataValues, int *req) const {
+ ncmpiCheck(ncmpi_iget_vara_text(groupId, myId,&startp[0],&countp[0],dataValues, req),__FILE__,__LINE__);
+}
+// Reads an array of values from a netCDF variable.
+void NcmpiVar::igetVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, unsigned char* dataValues, int *req) const {
+ ncmpiCheck(ncmpi_iget_vara_uchar(groupId, myId,&startp[0],&countp[0],dataValues, req),__FILE__,__LINE__);
+}
+// Reads an array of values from a netCDF variable.
+void NcmpiVar::igetVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, signed char* dataValues, int *req) const {
+ ncmpiCheck(ncmpi_iget_vara_schar(groupId, myId,&startp[0],&countp[0],dataValues, req),__FILE__,__LINE__);
+}
+// Reads an array of values from a netCDF variable.
+void NcmpiVar::igetVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, short* dataValues, int *req) const {
+ ncmpiCheck(ncmpi_iget_vara_short(groupId, myId,&startp[0],&countp[0],dataValues, req),__FILE__,__LINE__);
+}
+// Reads an array of values from a netCDF variable.
+void NcmpiVar::igetVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, int* dataValues, int *req) const {
+ ncmpiCheck(ncmpi_iget_vara_int(groupId, myId,&startp[0],&countp[0],dataValues, req),__FILE__,__LINE__);
+}
+// Reads an array of values from a netCDF variable.
+void NcmpiVar::igetVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, long* dataValues, int *req) const {
+ ncmpiCheck(ncmpi_iget_vara_long(groupId, myId,&startp[0],&countp[0],dataValues, req),__FILE__,__LINE__);
+}
+// Reads an array of values from a netCDF variable.
+void NcmpiVar::igetVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, float* dataValues, int *req) const {
+ ncmpiCheck(ncmpi_iget_vara_float(groupId, myId,&startp[0],&countp[0],dataValues, req),__FILE__,__LINE__);
+}
+// Reads an array of values from a netCDF variable.
+void NcmpiVar::igetVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, double* dataValues, int *req) const {
+ ncmpiCheck(ncmpi_iget_vara_double(groupId, myId,&startp[0],&countp[0],dataValues, req),__FILE__,__LINE__);
+}
+// Reads an array of values from a netCDF variable.
+void NcmpiVar::igetVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, unsigned short* dataValues, int *req) const {
+ ncmpiCheck(ncmpi_iget_vara_ushort(groupId, myId,&startp[0],&countp[0],dataValues, req),__FILE__,__LINE__);
+}
+// Reads an array of values from a netCDF variable.
+void NcmpiVar::igetVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, unsigned int* dataValues, int *req) const {
+ ncmpiCheck(ncmpi_iget_vara_uint(groupId, myId,&startp[0],&countp[0],dataValues, req),__FILE__,__LINE__);
+}
+// Reads an array of values from a netCDF variable.
+void NcmpiVar::igetVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, long long* dataValues, int *req) const {
+ ncmpiCheck(ncmpi_iget_vara_longlong(groupId, myId,&startp[0],&countp[0],dataValues, req),__FILE__,__LINE__);
+}
+// Reads an array of values from a netCDF variable
+void NcmpiVar::igetVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, unsigned long long* dataValues, int *req) const {
+ ncmpiCheck(ncmpi_iget_vara_ulonglong(groupId, myId,&startp[0],&countp[0],dataValues, req),__FILE__,__LINE__);
+}
+// Reads an array of values from a netCDF variable with no data conversion.
+void NcmpiVar::igetVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, void* dataValues, MPI_Offset bufcount, MPI_Datatype buftype, int *req) const {
+ ncmpiCheck(ncmpi_iget_vara(groupId, myId,&startp[0],&countp[0],dataValues, bufcount, buftype, req),__FILE__,__LINE__);
+}
+
+
+///////////
+
+// Reads a subsampled (strided) array section of values from a netCDF variable.
+void NcmpiVar::igetVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const vector<MPI_Offset>& stridep, char* dataValues, int *req) const {
+ ncmpiCheck(ncmpi_iget_vars_text(groupId, myId,&startp[0],&countp[0],&stridep[0],dataValues, req),__FILE__,__LINE__);
+}
+// Reads a subsampled (strided) array section of values from a netCDF variable.
+void NcmpiVar::igetVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const vector<MPI_Offset>& stridep, unsigned char* dataValues, int *req) const {
+ ncmpiCheck(ncmpi_iget_vars_uchar(groupId, myId,&startp[0],&countp[0],&stridep[0],dataValues, req),__FILE__,__LINE__);
+}
+// Reads a subsampled (strided) array section of values from a netCDF variable.
+void NcmpiVar::igetVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const vector<MPI_Offset>& stridep, signed char* dataValues, int *req) const {
+ ncmpiCheck(ncmpi_iget_vars_schar(groupId, myId,&startp[0],&countp[0],&stridep[0],dataValues, req),__FILE__,__LINE__);
+}
+// Reads a subsampled (strided) array section of values from a netCDF variable.
+void NcmpiVar::igetVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const vector<MPI_Offset>& stridep, short* dataValues, int *req) const {
+ ncmpiCheck(ncmpi_iget_vars_short(groupId, myId,&startp[0],&countp[0],&stridep[0],dataValues, req),__FILE__,__LINE__);
+}
+// Reads a subsampled (strided) array section of values from a netCDF variable.
+void NcmpiVar::igetVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const vector<MPI_Offset>& stridep, int* dataValues, int *req) const {
+ ncmpiCheck(ncmpi_iget_vars_int(groupId, myId,&startp[0],&countp[0],&stridep[0],dataValues, req),__FILE__,__LINE__);
+}
+// Reads a subsampled (strided) array section of values from a netCDF variable.
+void NcmpiVar::igetVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const vector<MPI_Offset>& stridep, long* dataValues, int *req) const {
+ ncmpiCheck(ncmpi_iget_vars_long(groupId, myId,&startp[0],&countp[0],&stridep[0],dataValues, req),__FILE__,__LINE__);
+}
+// Reads a subsampled (strided) array section of values from a netCDF variable.
+void NcmpiVar::igetVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const vector<MPI_Offset>& stridep, float* dataValues, int *req) const {
+ ncmpiCheck(ncmpi_iget_vars_float(groupId, myId,&startp[0],&countp[0],&stridep[0],dataValues, req),__FILE__,__LINE__);
+}
+// Reads a subsampled (strided) array section of values from a netCDF variable.
+void NcmpiVar::igetVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const vector<MPI_Offset>& stridep, double* dataValues, int *req) const {
+ ncmpiCheck(ncmpi_iget_vars_double(groupId, myId,&startp[0],&countp[0],&stridep[0],dataValues, req),__FILE__,__LINE__);
+}
+// Reads a subsampled (strided) array section of values from a netCDF variable.
+void NcmpiVar::igetVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const vector<MPI_Offset>& stridep, unsigned short* dataValues, int *req) const {
+ ncmpiCheck(ncmpi_iget_vars_ushort(groupId, myId,&startp[0],&countp[0],&stridep[0],dataValues, req),__FILE__,__LINE__);
+}
+// Reads a subsampled (strided) array section of values from a netCDF variable.
+void NcmpiVar::igetVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const vector<MPI_Offset>& stridep, unsigned int* dataValues, int *req) const {
+ ncmpiCheck(ncmpi_iget_vars_uint(groupId, myId,&startp[0],&countp[0],&stridep[0],dataValues, req),__FILE__,__LINE__);
+}
+// Reads a subsampled (strided) array section of values from a netCDF variable.
+void NcmpiVar::igetVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const vector<MPI_Offset>& stridep, long long* dataValues, int *req) const {
+ ncmpiCheck(ncmpi_iget_vars_longlong(groupId, myId,&startp[0],&countp[0],&stridep[0],dataValues, req),__FILE__,__LINE__);
+}
+// Reads a subsampled (strided) array section of values from a netCDF variable
+void NcmpiVar::igetVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const vector<MPI_Offset>& stridep, unsigned long long* dataValues, int *req) const {
+ ncmpiCheck(ncmpi_iget_vars_ulonglong(groupId, myId,&startp[0],&countp[0],&stridep[0],dataValues, req),__FILE__,__LINE__);
+}
+// Reads a subsampled (strided) array section of values from a netCDF variable with no data conversion.
+void NcmpiVar::igetVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const vector<MPI_Offset>& stridep, void* dataValues, MPI_Offset bufcount, MPI_Datatype buftype, int *req) const {
+ ncmpiCheck(ncmpi_iget_vars(groupId, myId,&startp[0],&countp[0],&stridep[0],dataValues, bufcount, buftype, req),__FILE__,__LINE__);
+}
+
+
+///////////
+
+// Reads a mapped array section of values from a netCDF variable.
+void NcmpiVar::igetVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const vector<MPI_Offset>& stridep, const vector<MPI_Offset>& imapp, char* dataValues, int *req) const {
+ ncmpiCheck(ncmpi_iget_varm_text(groupId, myId,&startp[0],&countp[0],&stridep[0],&imapp[0],dataValues, req),__FILE__,__LINE__);
+}
+// Reads a mapped array section of values from a netCDF variable.
+void NcmpiVar::igetVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const vector<MPI_Offset>& stridep, const vector<MPI_Offset>& imapp, unsigned char* dataValues, int *req) const {
+ ncmpiCheck(ncmpi_iget_varm_uchar(groupId, myId,&startp[0],&countp[0],&stridep[0],&imapp[0],dataValues, req),__FILE__,__LINE__);
+}
+// Reads a mapped array section of values from a netCDF variable.
+void NcmpiVar::igetVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const vector<MPI_Offset>& stridep, const vector<MPI_Offset>& imapp, signed char* dataValues, int *req) const {
+ ncmpiCheck(ncmpi_iget_varm_schar(groupId, myId,&startp[0],&countp[0],&stridep[0],&imapp[0],dataValues, req),__FILE__,__LINE__);
+}
+// Reads a mapped array section of values from a netCDF variable.
+void NcmpiVar::igetVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const vector<MPI_Offset>& stridep, const vector<MPI_Offset>& imapp, short* dataValues, int *req) const {
+ ncmpiCheck(ncmpi_iget_varm_short(groupId, myId,&startp[0],&countp[0],&stridep[0],&imapp[0],dataValues, req),__FILE__,__LINE__);
+}
+// Reads a mapped array section of values from a netCDF variable.
+void NcmpiVar::igetVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const vector<MPI_Offset>& stridep, const vector<MPI_Offset>& imapp, int* dataValues, int *req) const {
+ ncmpiCheck(ncmpi_iget_varm_int(groupId, myId,&startp[0],&countp[0],&stridep[0],&imapp[0],dataValues, req),__FILE__,__LINE__);
+}
+// Reads a mapped array section of values from a netCDF variable.
+void NcmpiVar::igetVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const vector<MPI_Offset>& stridep, const vector<MPI_Offset>& imapp, long* dataValues, int *req) const {
+ ncmpiCheck(ncmpi_iget_varm_long(groupId, myId,&startp[0],&countp[0],&stridep[0],&imapp[0],dataValues, req),__FILE__,__LINE__);
+}
+// Reads a mapped array section of values from a netCDF variable.
+void NcmpiVar::igetVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const vector<MPI_Offset>& stridep, const vector<MPI_Offset>& imapp, float* dataValues, int *req) const {
+ ncmpiCheck(ncmpi_iget_varm_float(groupId, myId,&startp[0],&countp[0],&stridep[0],&imapp[0],dataValues, req),__FILE__,__LINE__);
+}
+// Reads a mapped array section of values from a netCDF variable.
+void NcmpiVar::igetVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const vector<MPI_Offset>& stridep, const vector<MPI_Offset>& imapp, double* dataValues, int *req) const {
+ ncmpiCheck(ncmpi_iget_varm_double(groupId, myId,&startp[0],&countp[0],&stridep[0],&imapp[0],dataValues, req),__FILE__,__LINE__);
+}
+// Reads a mapped array section of values from a netCDF variable.
+void NcmpiVar::igetVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const vector<MPI_Offset>& stridep, const vector<MPI_Offset>& imapp, unsigned short* dataValues, int *req) const {
+ ncmpiCheck(ncmpi_iget_varm_ushort(groupId, myId,&startp[0],&countp[0],&stridep[0],&imapp[0],dataValues, req),__FILE__,__LINE__);
+}
+// Reads a mapped array section of values from a netCDF variable.
+void NcmpiVar::igetVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const vector<MPI_Offset>& stridep, const vector<MPI_Offset>& imapp, unsigned int* dataValues, int *req) const {
+ ncmpiCheck(ncmpi_iget_varm_uint(groupId, myId,&startp[0],&countp[0],&stridep[0],&imapp[0],dataValues, req),__FILE__,__LINE__);
+}
+// Reads a mapped array section of values from a netCDF variable.
+void NcmpiVar::igetVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const vector<MPI_Offset>& stridep, const vector<MPI_Offset>& imapp, long long* dataValues, int *req) const {
+ ncmpiCheck(ncmpi_iget_varm_longlong(groupId, myId,&startp[0],&countp[0],&stridep[0],&imapp[0],dataValues, req),__FILE__,__LINE__);
+}
+// Reads a mapped array section of values from a netCDF variable
+void NcmpiVar::igetVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const vector<MPI_Offset>& stridep, const vector<MPI_Offset>& imapp, unsigned long long* dataValues, int *req) const {
+ ncmpiCheck(ncmpi_iget_varm_ulonglong(groupId, myId,&startp[0],&countp[0],&stridep[0],&imapp[0],dataValues, req),__FILE__,__LINE__);
+}
+// Reads a mapped array section of values from a netCDF variable with no data conversion.
+void NcmpiVar::igetVar(const vector<MPI_Offset>& startp, const vector<MPI_Offset>& countp, const vector<MPI_Offset>& stridep, const vector<MPI_Offset>& imapp, void* dataValues, MPI_Offset bufcount, MPI_Datatype buftype, int *req) const {
+ ncmpiCheck(ncmpi_iget_varm(groupId, myId,&startp[0],&countp[0],&stridep[0],&imapp[0],dataValues, bufcount, buftype, req),__FILE__,__LINE__);
+}
+
+//////////////////////
+
+// Reads a list of subarrays from a netCDF variable. (independent I/O APIs)
+void NcmpiVar::igetVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], char* dataValues, int*req) const {
+ ncmpiCheck(ncmpi_iget_varn_text(groupId, myId, num, starts, counts, dataValues, req),__FILE__,__LINE__);
+}
+// Reads an array of values from a netCDF variable.
+void NcmpiVar::igetVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], unsigned char* dataValues, int*req) const {
+ ncmpiCheck(ncmpi_iget_varn_uchar(groupId, myId, num, starts, counts, dataValues, req),__FILE__,__LINE__);
+}
+// Reads an array of values from a netCDF variable.
+void NcmpiVar::igetVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], signed char* dataValues, int*req) const {
+ ncmpiCheck(ncmpi_iget_varn_schar(groupId, myId, num, starts, counts, dataValues, req),__FILE__,__LINE__);
+}
+// Reads an array of values from a netCDF variable.
+void NcmpiVar::igetVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], short* dataValues, int*req) const {
+ ncmpiCheck(ncmpi_iget_varn_short(groupId, myId, num, starts, counts, dataValues, req),__FILE__,__LINE__);
+}
+// Reads an array of values from a netCDF variable.
+void NcmpiVar::igetVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], int* dataValues, int*req) const {
+ ncmpiCheck(ncmpi_iget_varn_int(groupId, myId, num, starts, counts, dataValues, req),__FILE__,__LINE__);
+}
+// Reads an array of values from a netCDF variable.
+void NcmpiVar::igetVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], long* dataValues, int*req) const {
+ ncmpiCheck(ncmpi_iget_varn_long(groupId, myId, num, starts, counts, dataValues, req),__FILE__,__LINE__);
+}
+// Reads an array of values from a netCDF variable.
+void NcmpiVar::igetVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], float* dataValues, int*req) const {
+ ncmpiCheck(ncmpi_iget_varn_float(groupId, myId, num, starts, counts, dataValues, req),__FILE__,__LINE__);
+}
+// Reads an array of values from a netCDF variable.
+void NcmpiVar::igetVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], double* dataValues, int*req) const {
+ ncmpiCheck(ncmpi_iget_varn_double(groupId, myId, num, starts, counts, dataValues, req),__FILE__,__LINE__);
+}
+// Reads an array of values from a netCDF variable.
+void NcmpiVar::igetVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], unsigned short* dataValues, int*req) const {
+ ncmpiCheck(ncmpi_iget_varn_ushort(groupId, myId, num, starts, counts, dataValues, req),__FILE__,__LINE__);
+}
+// Reads an array of values from a netCDF variable.
+void NcmpiVar::igetVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], unsigned int* dataValues, int*req) const {
+ ncmpiCheck(ncmpi_iget_varn_uint(groupId, myId, num, starts, counts, dataValues, req),__FILE__,__LINE__);
+}
+// Reads an array of values from a netCDF variable.
+void NcmpiVar::igetVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], long long* dataValues, int*req) const {
+ ncmpiCheck(ncmpi_iget_varn_longlong(groupId, myId, num, starts, counts, dataValues, req),__FILE__,__LINE__);
+}
+// Reads an array of values from a netCDF variable
+void NcmpiVar::igetVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], unsigned long long* dataValues, int*req) const {
+ ncmpiCheck(ncmpi_iget_varn_ulonglong(groupId, myId, num, starts, counts, dataValues, req),__FILE__,__LINE__);
+}
+// Reads an array of values from a netCDF variable with no data conversion.
+void NcmpiVar::igetVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], void* dataValues, MPI_Offset bufcount, MPI_Datatype buftype, int*req) const {
+ ncmpiCheck(ncmpi_iget_varn(groupId, myId, num, starts, counts, dataValues, bufcount, buftype, req),__FILE__,__LINE__);
+}
+
+//////////////////////
+
+void NcmpiVar::Inq_file_offset(MPI_Offset *offset)
+{
+ ncmpiCheck(ncmpi_inq_varoffset(groupId, myId, offset),__FILE__,__LINE__);
+}
+
diff --git a/src/libcxx/ncmpiVar.h b/src/libcxx/ncmpiVar.h
new file mode 100644
index 0000000..ec20240
--- /dev/null
+++ b/src/libcxx/ncmpiVar.h
@@ -0,0 +1,3322 @@
+#include <exception>
+#include <string>
+#include <typeinfo>
+#include <map>
+#include <vector>
+#include <pnetcdf.h>
+#include "ncmpiVarAtt.h"
+#include "ncmpiGroup.h"
+#include "ncmpiByte.h"
+#include "ncmpiUbyte.h"
+#include "ncmpiChar.h"
+#include "ncmpiShort.h"
+#include "ncmpiUshort.h"
+#include "ncmpiInt.h"
+#include "ncmpiUint.h"
+#include "ncmpiInt64.h"
+#include "ncmpiUint64.h"
+#include "ncmpiFloat.h"
+#include "ncmpiDouble.h"
+
+#ifndef NcmpiVarClass
+#define NcmpiVarClass
+
+namespace PnetCDF
+{
+ // class NcmpiGroup; // forward declaration.
+ class NcmpiDim; // forward declaration.
+ // class NcmpiVarAtt; // forward declaration.
+ class NcmpiType; // forward declaration.
+
+ /*! Class represents a netCDF variable. */
+ class NcmpiVar
+ {
+ public:
+
+ /*! Used for chunking specifications (see NcmpiVar::setChunking, NcmpiVar::getChunkingParameters). */
+ enum ChunkMode
+ {
+ /*!
+ Chunked storage is used for this variable.
+ */
+ ncmpi_CHUNKED = NC_CHUNKED,
+ /*! Contiguous storage is used for this variable. Variables with one or more unlimited
+ dimensions cannot use contiguous storage. If contiguous storage is turned on, the
+ chunkSizes parameter is ignored.
+ */
+ ncmpi_CONTIGUOUS = NC_CONTIGUOUS
+ };
+
+ /*!
+ Used to specifying the endianess of the data, (see NcmpiVar::setEndianness, NcmpiVar::getEndianness). By default this is NC_ENDIAN_NATIVE.
+ */
+ enum EndianMode
+ {
+ ncmpi_ENDIAN_NATIVE = NC_ENDIAN_NATIVE, //!< Native endian.
+ ncmpi_ENDIAN_LITTLE = NC_ENDIAN_LITTLE, //!< Little endian.
+ ncmpi_ENDIAN_BIG = NC_ENDIAN_BIG //!< Big endian.
+ };
+
+ /*! Used for checksum specification (see NcmpiVar::setChecksum, NcmpiVar::getChecksum). */
+ enum ChecksumMode
+ {
+ ncmpi_NOCHECKSUM = NC_NOCHECKSUM, //!< No checksum (the default).
+ ncmpi_FLETCHER32 = NC_FLETCHER32 //!< Selects the Fletcher32 checksum filter.
+ };
+
+ /*! destructor */
+ ~NcmpiVar(){};
+
+ /*! Constructor generates a \ref isNull "null object". */
+ NcmpiVar ();
+
+ /*! Constructor for a variable .
+
+ The variable must already exist in the netCDF file. New netCDF variables can be added using NcmpiGroup::addNcmpiVar();
+ \param grp Parent NcmpiGroup object.
+ \param varId Id of the is NcmpiVar object.
+ */
+ NcmpiVar (const NcmpiGroup& grp, const int& varId);
+
+ /*! assignment operator */
+ NcmpiVar& operator =(const NcmpiVar& rhs);
+
+ /*! equivalence operator */
+ bool operator==(const NcmpiVar& rhs) const;
+
+ /*! != operator */
+ bool operator!=(const NcmpiVar& rhs) const;
+
+ /*! The copy constructor. */
+ NcmpiVar(const NcmpiVar& ncmpiVar);
+
+ /*! Name of this NcmpiVar object.*/
+ std::string getName() const;
+
+ /*! Gets parent group. */
+ NcmpiGroup getParentGroup() const;
+
+ /*! Returns the variable type. */
+ NcmpiType getType() const;
+
+
+ /*! Rename the variable. */
+ void rename( const std::string& newname ) const;
+
+
+ /*! Get the variable id. */
+ int getId() const;
+
+ /*! Returns true if this object variable is not defined. */
+ bool isNull() const {return nullObject;}
+
+ /*! comparator operator */
+ friend bool operator<(const NcmpiVar& lhs,const NcmpiVar& rhs);
+
+ /*! comparator operator */
+ friend bool operator>(const NcmpiVar& lhs,const NcmpiVar& rhs);
+
+ /////////////////
+
+ // Information about Dimensions
+
+ /////////////////
+
+ /*! The the number of dimensions. */
+ int getDimCount() const ;
+
+ /*! Gets the i'th NcmpiDim object. */
+ NcmpiDim getDim(int i) const;
+
+ /*! Gets the set of NcmpiDim objects. */
+ std::vector<NcmpiDim> getDims() const;
+
+ /////////////////
+
+ // Information about Attributes
+
+ /////////////////
+
+ /*! Gets the number of attributes. */
+ int getAttCount() const;
+
+ /*! Gets attribute by name */
+ NcmpiVarAtt getAtt(const std::string& name) const;
+
+ /*! Gets the set of attributes. */
+ std::map<std::string,NcmpiVarAtt> getAtts() const;
+
+
+
+
+ /////////////////////////
+
+
+ /*! \overload
+ */
+ NcmpiVarAtt putAtt(const std::string& name, const std::string& dataValues) const ;
+
+ /*! \overload
+ */
+ NcmpiVarAtt putAtt(const std::string& name, const NcmpiType& type, MPI_Offset len, const unsigned char* dataValues) const ;
+ /*! \overload
+ */
+ NcmpiVarAtt putAtt(const std::string& name, const NcmpiType& type, MPI_Offset len, const signed char* dataValues) const ;
+ /*! \overload
+ */
+ NcmpiVarAtt putAtt(const std::string& name, const NcmpiType& type, short datumValue) const ;
+ /*! \overload
+ */
+ NcmpiVarAtt putAtt(const std::string& name, const NcmpiType& type, int datumValue) const ;
+ /*! \overload
+ */
+ NcmpiVarAtt putAtt(const std::string& name, const NcmpiType& type, long datumValue) const ;
+ /*! \overload
+ */
+ NcmpiVarAtt putAtt(const std::string& name, const NcmpiType& type, float datumValue) const ;
+ /*! \overload
+ */
+ NcmpiVarAtt putAtt(const std::string& name, const NcmpiType& type, double datumValue) const ;
+ /*! \overload
+ */
+ NcmpiVarAtt putAtt(const std::string& name, const NcmpiType& type, unsigned short datumValue) const ;
+ /*! \overload
+ */
+ NcmpiVarAtt putAtt(const std::string& name, const NcmpiType& type, unsigned int datumValue) const ;
+ /*! \overload
+ */
+ NcmpiVarAtt putAtt(const std::string& name, const NcmpiType& type, unsigned long long datumValue) const ;
+ /*! \overload
+ */
+ NcmpiVarAtt putAtt(const std::string& name, const NcmpiType& type, long long datumValue) const ;
+ /*! \overload
+ */
+ NcmpiVarAtt putAtt(const std::string& name, const NcmpiType& type, MPI_Offset len, const short* dataValues) const ;
+ /*! \overload
+ */
+ NcmpiVarAtt putAtt(const std::string& name, const NcmpiType& type, MPI_Offset len, const int* dataValues) const ;
+ /*! \overload
+ */
+ NcmpiVarAtt putAtt(const std::string& name, const NcmpiType& type, MPI_Offset len, const long* dataValues) const ;
+ /*! \overload
+ */
+ NcmpiVarAtt putAtt(const std::string& name, const NcmpiType& type, MPI_Offset len, const float* dataValues) const ;
+ /*! \overload
+ */
+ NcmpiVarAtt putAtt(const std::string& name, const NcmpiType& type, MPI_Offset len, const double* dataValues) const ;
+ /*! \overload
+ */
+ NcmpiVarAtt putAtt(const std::string& name, const NcmpiType& type, MPI_Offset len, const unsigned short* dataValues) const ;
+ /*! \overload
+ */
+ NcmpiVarAtt putAtt(const std::string& name, const NcmpiType& type, MPI_Offset len, const unsigned int* dataValues) const ;
+ /*! \overload
+ */
+ NcmpiVarAtt putAtt(const std::string& name, const NcmpiType& type, MPI_Offset len, const unsigned long long* dataValues) const ;
+ /*! \overload
+ */
+ NcmpiVarAtt putAtt(const std::string& name, const NcmpiType& type, MPI_Offset len, const long long* dataValues) const ;
+ /*!
+ Creates a new variable attribute or if already exisiting replaces it.
+ If you are writing a _Fill_Value_ attribute, and will tell the HDF5 layer to use
+ the specified fill value for that variable.
+ \par
+ Although it's possible to create attributes of all types, text and double attributes are adequate for most purposes.
+ \param name Name of attribute.
+ \param type The attribute type.
+ \param len The length of the attribute (number of Nctype repeats).
+ \param dataValues Data Values to put into the new attribute.
+ If the type of data values differs from the netCDF variable type, type conversion will occur.
+ (However, no type conversion is carried out for variables using the user-defined data types:
+ ncmpi_Vlen, ncmpi_Opaque, ncmpi_Compound and ncmpi_Enum.)
+ \return The NcmpiVarAtt object for this new netCDF attribute.
+ */
+ NcmpiVarAtt putAtt(const std::string& name, const NcmpiType& type, MPI_Offset len, const void* dataValues) const ;
+
+
+
+ ////////////////////
+
+ // Chunking details
+
+ ////////////////////
+
+ /*! Sets chunking parameters.
+ \param chunkMode Enumeration type. Allowable parameters are: "ncmpi_CONTIGUOUS", "ncmpi_CHUNKED"
+ \param chunksizes Shape of chunking, used if ChunkMode=ncmpi_CHUNKED.
+ */
+ void setChunking(ChunkMode chunkMode, std::vector<MPI_Offset>& chunksizes) const;
+
+ /*! Gets the chunking parameters
+ \param chunkMode On return contains either: "ncmpi_CONTIGUOUS" or "ncmpi_CHUNKED"
+ \param chunksizes On return contains shape of chunking, used if ChunkMode=ncmpi_CHUNKED.
+ */
+ void getChunkingParameters(ChunkMode& chunkMode, std::vector<MPI_Offset>& chunkSizes) const;
+
+
+
+ ////////////////////
+
+ // Fill details
+
+ ////////////////////
+
+ // Sets the fill parameters
+ /*!
+ \overload
+ */
+ void setFill(bool fillMode, void *fillValue=NULL) const;
+
+ /*!
+ This is an overloaded member function, provided for convenience.
+ It differs from the above function in what argument(s) it accepts.
+ The function can be used for any type, including user-defined types.
+ \param fillMode Setting to true, turns on fill mode.
+ \param fillValue Pointer to fill value.
+ Must be the same type as the variable. Ignored if fillMode=.false.
+ */
+ // void setFill(bool fillMode,const void* fillValue=NULL) const;
+
+ /*! Sets the fill parameters
+ \param fillMode Setting to true, turns on fill mode.
+ \param fillValue Fill value for the variable.
+ Must be the same type as the variable. Ignored if fillMode=.false.
+ */
+/*
+ template<class T>
+ void setFill(bool fillMode, T fillValue) const
+ {
+ ncmpiCheck(ncmpi_def_var_fill(groupId,myId,static_cast<int> (!fillMode),&fillValue),__FILE__,__LINE__);
+ }
+*/
+
+
+
+ /*!
+ This is an overloaded member function, provided for convenience.
+ It differs from the above function in what argument(s) it accepts.
+ The function can be used for any type, including user-defined types.
+ \param fillMode On return set to true if fill mode is enabled.
+ \param fillValue On return containts a pointer to fill value.
+ Must be the same type as the variable. Ignored if fillMode=.false.
+ */
+ void getFillModeParameters(bool& fillMode, void* fillValue=NULL) const;
+
+
+ /*! Gets the fill parameters
+ \param On return set to true if fill mode is enabled.
+ \param On return is set to the fill value.
+ */
+ template <class T> void getFillModeParameters(bool& fillMode,T& fillValue) const{
+ int fillModeInt;
+ ncmpiCheck(ncmpi_inq_var_fill(groupId,myId,&fillModeInt,&fillValue),__FILE__,__LINE__);
+ fillMode= static_cast<bool> (fillModeInt == 0);
+ }
+
+
+ /* fill variable */
+ void fillRec(MPI_Offset recno) const;
+
+ ////////////////////
+
+ // Compression details
+
+ ////////////////////
+
+
+ /*! Sets the compression parameters
+ \param enableShuffleFilter Set to true to turn on shuffle filter.
+ \param enableDeflateFilter Set to true to turn on deflate filter.
+ \param deflateLevel The deflate level, must be 0 and 9.
+ */
+ void setCompression(bool enableShuffleFilter, bool enableDeflateFilter, int deflateLevel) const;
+
+ /*! Gets the compression parameters
+ \param enableShuffleFilter On return set to true if the shuffle filter is enabled.
+ \param enableDeflateFilter On return set to true if the deflate filter is enabled.
+ \param deflateLevel On return set to the deflate level.
+ */
+ void getCompressionParameters(bool& shuffleFilterEnabled, bool& deflateFilterEnabled, int& deflateLevel) const;
+
+
+
+ ////////////////////
+
+ // Endianness details
+
+ ////////////////////
+
+
+ /*! Sets the endianness of the variable.
+ \param Endianness enumeration type. Allowable parameters are: "ncmpi_ENDIAN_NATIVE" (the default), "ncmpi_ENDIAN_LITTLE", "ncmpi_ENDIAN_BIG"
+ */
+ void setEndianness(EndianMode endianMode) const;
+
+ /*! Gets the endianness of the variable.
+ \return Endianness enumeration type. Allowable parameters are: "ncmpi_ENDIAN_NATIVE" (the default), "ncmpi_ENDIAN_LITTLE", "ncmpi_ENDIAN_BIG"
+ */
+ EndianMode getEndianness() const;
+
+
+
+ ////////////////////
+
+ // Checksum details
+
+ ////////////////////
+
+
+ /*! Sets the checksum parameters of a variable.
+ \param ChecksumMode Enumeration type. Allowable parameters are: "ncmpi_NOCHECKSUM", "ncmpi_FLETCHER32".
+ */
+ void setChecksum(ChecksumMode checksumMode) const;
+
+ /*! Gets the checksum parameters of the variable.
+ \return ChecksumMode Enumeration type. Allowable parameters are: "ncmpi_NOCHECKSUM", "ncmpi_FLETCHER32".
+ */
+ ChecksumMode getChecksum() const;
+
+
+
+ ////////////////////
+
+ // data reading
+
+ ////////////////////
+
+
+
+ // Reads the entire data into the netCDF variable. (independent data mode)
+ /*!
+ This is an overloaded member function, provided for convenience.
+ It differs from the above function in what argument(s) it accepts.
+ In addition, no data conversion is carried out. This means that
+ the type of the data in memory must match the type of the variable.
+ */
+ // void getVar(void* dataValues) const;
+ /*! \overload
+ */
+ void getVar(char* dataValues) const;
+ /*! \overload
+ */
+ void getVar(unsigned char* dataValues) const;
+ /*! \overload
+ */
+ void getVar(signed char* dataValues) const;
+ /*! \overload
+ */
+ void getVar(short* dataValues) const;
+ /*! \overload
+ */
+ void getVar(int* dataValues) const;
+ /*! \overload
+ */
+ void getVar(long* dataValues) const;
+ /*! \overload
+ */
+ void getVar(float* dataValues) const;
+ /*! \overload
+ */
+ void getVar(double* dataValues) const;
+ /*! \overload
+ */
+ void getVar(unsigned short* dataValues) const;
+ /*! \overload
+ */
+ void getVar(unsigned int* dataValues) const;
+ /*! \overload
+ */
+ void getVar(unsigned long long* dataValues) const;
+ /*!
+ Reads the entire data from an netCDF variable.
+ This is the simplest interface to use for reading the value of a scalar variable
+ or when all the values of a multidimensional variable can be read at once. The values
+ are read into consecutive locations with the last dimension varying fastest.
+
+ Take care when using the simplest forms of this interface with record variables when you
+ don't specify how many records are to be read. If you try to read all the values of a
+ record variable into an array but there are more records in the file than you assume,
+ more data will be read than you expect, which may cause a segmentation violation.
+
+ \param dataValues Pointer to the location into which the data value is read. If the type of
+ data value differs from the netCDF variable type, type conversion will occur.
+ (However, no type conversion is carried out for variables using the user-defined data types:
+ ncmpi_Vlen, ncmpi_Opaque, ncmpi_Compound and ncmpi_Enum.)
+ */
+ void getVar(long long* dataValues) const;
+
+ void getVar(void* dataValues, MPI_Offset bufcount, MPI_Datatype buftype) const;
+
+
+ //////////////////////
+
+ // Reads a single datum value from a variable of an open netCDF dataset.
+ /*!
+ This is an overloaded member function, provided for convenience.
+ It differs from the above function in what argument(s) it accepts.
+ In addition, no data conversion is carried out. This means that
+ the type of the data in memory must match the type of the variable.
+ */
+ // void getVar(const std::vector<MPI_Offset>& index, void* dataumValue) const;
+ /*! \overload
+ */
+ void getVar(const std::vector<MPI_Offset>& index, char* dataumValue) const;
+ /*! \overload
+ */
+ void getVar(const std::vector<MPI_Offset>& index, unsigned char* dataumValue) const;
+ /*! \overload
+ */
+ void getVar(const std::vector<MPI_Offset>& index, signed char* dataumValue) const;
+ /*! \overload
+ */
+ void getVar(const std::vector<MPI_Offset>& index, short* dataumValue) const;
+ /*! \overload
+ */
+ void getVar(const std::vector<MPI_Offset>& index, int* dataumValue) const;
+ /*! \overload
+ */
+ void getVar(const std::vector<MPI_Offset>& index, long* dataumValue) const;
+ /*! \overload
+ */
+ void getVar(const std::vector<MPI_Offset>& index, float* dataumValue) const;
+ /*! \overload
+ */
+ void getVar(const std::vector<MPI_Offset>& index, double* dataumValue) const;
+ /*! \overload
+ */
+ void getVar(const std::vector<MPI_Offset>& index, unsigned short* dataumValue) const;
+ /*! \overload
+ */
+ void getVar(const std::vector<MPI_Offset>& index, unsigned int* dataumValue) const;
+ /*! \overload
+ */
+ void getVar(const std::vector<MPI_Offset>& index, unsigned long long* dataumValue) const;
+ /*! Reads a single datum value from a variable of an open netCDF dataset.
+ The value is converted from the external data type of the variable, if necessary.
+
+ \param index Vector specifying the index of the data value to be read.
+ The indices are relative to 0, so for example, the first data value of a two-dimensional
+ variable would have index (0,0). The elements of index must correspond to the variable's dimensions.
+ Hence, if the variable is a record variable, the first index is the record number.
+
+ \param datumValue Pointer to the location into which the data value is read. If the type of
+ data value differs from the netCDF variable type, type conversion will occur.
+ (However, no type conversion is carried out for variables using the user-defined data types:
+ ncmpi_Vlen, ncmpi_Opaque, ncmpi_Compound and ncmpi_Enum.)
+ */
+ void getVar(const std::vector<MPI_Offset>& index, long long* dataumValue) const;
+
+ void getVar(const std::vector<MPI_Offset>& index, void* dataumValue, MPI_Offset bufcount, MPI_Datatype buftype) const;
+
+ //////////////////////
+
+ // Reads an array of values from a netCDF variable of an open netCDF dataset.
+ /*!
+ This is an overloaded member function, provided for convenience.
+ It differs from the above function in what argument(s) it accepts.
+ In addition, no data conversion is carried out. This means that
+ the type of the data in memory must match the type of the variable.
+ */
+ // void getVar(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, void* dataValues) const;
+ /*! \overload
+ */
+ void getVar(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, char* dataValues) const;
+ /*! \overload
+ */
+ void getVar(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, unsigned char* dataValues) const;
+ /*! \overload
+ */
+ void getVar(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, signed char* dataValues) const;
+ /*! \overload
+ */
+ void getVar(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, short* dataValues) const;
+ /*! \overload
+ */
+ void getVar(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, int* dataValues) const;
+ /*! \overload
+ */
+ void getVar(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, long* dataValues) const;
+ /*! \overload
+ */
+ void getVar(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, float* dataValues) const;
+ /*! \overload
+ */
+ void getVar(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, double* dataValues) const;
+ /*! \overload
+ */
+ void getVar(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, unsigned short* dataValues) const;
+ /*! \overload
+ */
+ void getVar(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, unsigned int* dataValues) const;
+ /*! \overload
+ */
+ void getVar(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, unsigned long long* dataValues) const;
+ /*!
+ Reads an array of values from a netCDF variable of an open netCDF dataset.
+ The array is specified by giving a corner and a vector of edge lengths.
+ The values are read into consecutive locations with the last dimension varying fastest.
+
+ \param start
+ Vector specifying the index in the variable where the first of the data values will be read.
+ The indices are relative to 0, so for example, the first data value of a variable would have index (0, 0, ... , 0).
+ The length of start must be the same as the number of dimensions of the specified variable.
+ The elements of start correspond, in order, to the variable's dimensions. Hence, if the variable is a record variable,
+ the first index would correspond to the starting record number for reading the data values.
+
+ \param count
+ Vector specifying the edge lengths along each dimension of the block of data values to be read.
+ To read a single value, for example, specify count as (1, 1, ... , 1). The length of count is the number of
+ dimensions of the specified variable. The elements of count correspond, in order, to the variable's dimensions.
+ Hence, if the variable is a record variable, the first element of count corresponds to a count of the number of records to read.
+ Note: setting any element of the count array to zero causes the function to exit without error, and without doing anything.
+
+ \param dataValues Pointer to the location into which the data value is read. If the type of
+ data value differs from the netCDF variable type, type conversion will occur.
+ (However, no type conversion is carried out for variables using the user-defined data types:
+ ncmpi_Vlen, ncmpi_Opaque, ncmpi_Compound and ncmpi_Enum.)
+ */
+ void getVar(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, long long* dataValues) const;
+
+ void getVar(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, void* dataValues, MPI_Offset bufcount, MPI_Datatype buftype) const;
+
+ //////////////////////
+
+ // Reads a subsampled (strided) array section of values from a netCDF variable.
+ /*!
+ This is an overloaded member function, provided for convenience.
+ It differs from the above function in what argument(s) it accepts.
+ In addition, no data conversion is carried out. This means that
+ the type of the data in memory must match the type of the variable.
+ */
+ // void getVar(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, const std::vector<MPI_Offset>& stride, void* dataValues) const;
+ /*! \overload
+ */
+ void getVar(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, const std::vector<MPI_Offset>& stride, char* dataValues) const;
+ /*! \overload
+ */
+ void getVar(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, const std::vector<MPI_Offset>& stride, unsigned char* dataValues) const;
+ /*! \overload
+ */
+ void getVar(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, const std::vector<MPI_Offset>& stride, signed char* dataValues) const;
+ /*! \overload
+ */
+ void getVar(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, const std::vector<MPI_Offset>& stride, short* dataValues) const;
+ /*! \overload
+ */
+ void getVar(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, const std::vector<MPI_Offset>& stride, int* dataValues) const;
+ /*! \overload
+ */
+ void getVar(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, const std::vector<MPI_Offset>& stride, long* dataValues) const;
+ /*! \overload
+ */
+ void getVar(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, const std::vector<MPI_Offset>& stride, float* dataValues) const;
+ /*! \overload
+ */
+ void getVar(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, const std::vector<MPI_Offset>& stride, double* dataValues) const;
+ /*! \overload
+ */
+ void getVar(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, const std::vector<MPI_Offset>& stride, unsigned short* dataValues) const;
+ /*! \overload
+ */
+ void getVar(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, const std::vector<MPI_Offset>& stride, unsigned int* dataValues) const;
+ /*! \overload
+ */
+ void getVar(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, const std::vector<MPI_Offset>& stride, unsigned long long* dataValues) const;
+ /*!
+ Reads a subsampled (strided) array section of values from a netCDF variable.
+ The subsampled array section is specified by giving a corner, a vector of edge lengths, and a stride vector.
+ The values are read with the last dimension of the netCDF variable varying fastest.
+
+ \param start
+ Vector specifying the index in the variable where the first of the data values will be read.
+ The indices are relative to 0, so for example, the first data value of a variable would have index (0, 0, ... , 0).
+ The length of start must be the same as the number of dimensions of the specified variable.
+ The elements of start correspond, in order, to the variable's dimensions. Hence, if the variable is a record variable,
+ the first index would correspond to the starting record number for reading the data values.
+
+ \param count
+ Vector specifying the edge lengths along each dimension of the block of data values to be read.
+ To read a single value, for example, specify count as (1, 1, ... , 1). The length of count is the number of
+ dimensions of the specified variable. The elements of count correspond, in order, to the variable's dimensions.
+ Hence, if the variable is a record variable, the first element of count corresponds to a count of the number of records to read.
+ Note: setting any element of the count array to zero causes the function to exit without error, and without doing anything.
+
+ \param stride
+ Vector specifying the interval between selected indices. The elements of the stride vector correspond, in order,
+ to the variable's dimensions. A value of 1 accesses adjacent values of the netCDF variable in the corresponding
+ dimension; a value of 2 accesses every other value of the netCDF variable in the corresponding dimension; and so
+ on. A NULL stride argument is treated as (1, 1, ... , 1).
+
+ \param dataValues Pointer to the location into which the data value is read. If the type of
+ data value differs from the netCDF variable type, type conversion will occur.
+ (However, no type conversion is carried out for variables using the user-defined data types:
+ ncmpi_Vlen, ncmpi_Opaque, ncmpi_Compound and ncmpi_Enum.)
+ */
+ void getVar(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, const std::vector<MPI_Offset>& stride, long long* dataValues) const;
+
+ void getVar(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, const std::vector<MPI_Offset>& stride, void* dataValues, MPI_Offset bufcount, MPI_Datatype buftype) const;
+
+
+ //////////////////////
+
+ // Reads a mapped array section of values from a netCDF variable.
+ /*!
+ This is an overloaded member function, provided for convenience.
+ It differs from the above function in what argument(s) it accepts.
+ In addition, no data conversion is carried out. This means that
+ the type of the data in memory must match the type of the variable.
+ */
+ // void getVar(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, const std::vector<MPI_Offset>& stride, const std::vector<MPI_Offset>& imap, void* dataValues) const;
+ /*! \overload
+ */
+ void getVar(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, const std::vector<MPI_Offset>& stride, const std::vector<MPI_Offset>& imap, char* dataValues) const;
+ /*! \overload
+ */
+ void getVar(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, const std::vector<MPI_Offset>& stride, const std::vector<MPI_Offset>& imap, unsigned char* dataValues) const;
+ /*! \overload
+ */
+ void getVar(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, const std::vector<MPI_Offset>& stride, const std::vector<MPI_Offset>& imap, signed char* dataValues) const;
+ /*! \overload
+ */
+ void getVar(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, const std::vector<MPI_Offset>& stride, const std::vector<MPI_Offset>& imap, short* dataValues) const;
+ /*! \overload
+ */
+ void getVar(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, const std::vector<MPI_Offset>& stride, const std::vector<MPI_Offset>& imap, int* dataValues) const;
+ /*! \overload
+ */
+ void getVar(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, const std::vector<MPI_Offset>& stride, const std::vector<MPI_Offset>& imap, long* dataValues) const;
+ /*! \overload
+ */
+ void getVar(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, const std::vector<MPI_Offset>& stride, const std::vector<MPI_Offset>& imap, float* dataValues) const;
+ /*! \overload
+ */
+ void getVar(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, const std::vector<MPI_Offset>& stride, const std::vector<MPI_Offset>& imap, double* dataValues) const;
+ /*! \overload
+ */
+ void getVar(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, const std::vector<MPI_Offset>& stride, const std::vector<MPI_Offset>& imap, unsigned short* dataValues) const;
+ /*! \overload
+ */
+ void getVar(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, const std::vector<MPI_Offset>& stride, const std::vector<MPI_Offset>& imap, unsigned int* dataValues) const;
+ /*! \overload
+ */
+ void getVar(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, const std::vector<MPI_Offset>& stride, const std::vector<MPI_Offset>& imap, unsigned long long* dataValues) const;
+ /*!
+ Reads a mapped array section of values from a netCDF variable.
+ The mapped array section is specified by giving a corner, a vector of edge lengths, a stride vector, and an
+ index mapping vector. The index mapping vector is a vector of integers that specifies the mapping between the
+ dimensions of a netCDF variable and the in-memory structure of the internal data array. No assumptions are
+ made about the ordering or length of the dimensions of the data array.
+
+ \param start
+ Vector specifying the index in the variable where the first of the data values will be read.
+ The indices are relative to 0, so for example, the first data value of a variable would have index (0, 0, ... , 0).
+ The length of start must be the same as the number of dimensions of the specified variable.
+ The elements of start correspond, in order, to the variable's dimensions. Hence, if the variable is a record variable,
+ the first index would correspond to the starting record number for reading the data values.
+
+ \param count
+ Vector specifying the edge lengths along each dimension of the block of data values to be read.
+ To read a single value, for example, specify count as (1, 1, ... , 1). The length of count is the number of
+ dimensions of the specified variable. The elements of count correspond, in order, to the variable's dimensions.
+ Hence, if the variable is a record variable, the first element of count corresponds to a count of the number of records to read.
+ Note: setting any element of the count array to zero causes the function to exit without error, and without doing anything.
+
+ \param stride
+ Vector specifying the interval between selected indices. The elements of the stride vector correspond, in order,
+ to the variable's dimensions. A value of 1 accesses adjacent values of the netCDF variable in the corresponding
+ dimension; a value of 2 accesses every other value of the netCDF variable in the corresponding dimension; and so
+ on. A NULL stride argument is treated as (1, 1, ... , 1).
+
+ \param imap
+ Vector of integers that specifies the mapping between the dimensions of a netCDF variable and the in-memory
+ structure of the internal data array. imap[0] gives the distance between elements of the internal array corresponding
+ to the most slowly varying dimension of the netCDF variable. imap[n-1] (where n is the rank of the netCDF variable)
+ gives the distance between elements of the internal array corresponding to the most rapidly varying dimension of the
+ netCDF variable. Intervening imap elements correspond to other dimensions of the netCDF variable in the obvious way.
+ Distances between elements are specified in type-independent units of elements (the distance between internal elements
+ that occupy adjacent memory locations is 1 and not the element's byte-length as in netCDF 2).
+
+ \param dataValues Pointer to the location into which the data value is read. If the type of
+ data value differs from the netCDF variable type, type conversion will occur.
+ (However, no type conversion is carried out for variables using the user-defined data types:
+ ncmpi_Vlen, ncmpi_Opaque, ncmpi_Compound and ncmpi_Enum.)
+ */
+ void getVar(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, const std::vector<MPI_Offset>& stride, const std::vector<MPI_Offset>& imap, long long* dataValues) const;
+
+ void getVar(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, const std::vector<MPI_Offset>& stride, const std::vector<MPI_Offset>& imap, void* dataValues, MPI_Offset bufcount, MPI_Datatype buftype) const;
+
+ //////////////////////
+
+ // Reads the entire data into the netCDF variable. (collective data mode)
+ /*!
+ This is an overloaded member function, provided for convenience.
+ It differs from the above function in what argument(s) it accepts.
+ In addition, no data conversion is carried out. This means that
+ the type of the data in memory must match the type of the variable.
+ */
+ // void getVar_all(void* dataValues) const;
+ /*! \overload
+ */
+ void getVar_all(char* dataValues) const;
+ /*! \overload
+ */
+ void getVar_all(unsigned char* dataValues) const;
+ /*! \overload
+ */
+ void getVar_all(signed char* dataValues) const;
+ /*! \overload
+ */
+ void getVar_all(short* dataValues) const;
+ /*! \overload
+ */
+ void getVar_all(int* dataValues) const;
+ /*! \overload
+ */
+ void getVar_all(long* dataValues) const;
+ /*! \overload
+ */
+ void getVar_all(float* dataValues) const;
+ /*! \overload
+ */
+ void getVar_all(double* dataValues) const;
+ /*! \overload
+ */
+ void getVar_all(unsigned short* dataValues) const;
+ /*! \overload
+ */
+ void getVar_all(unsigned int* dataValues) const;
+ /*! \overload
+ */
+ void getVar_all(unsigned long long* dataValues) const;
+ /*!
+ Reads the entire data from an netCDF variable.
+ This is the simplest interface to use for reading the value of a scalar variable
+ or when all the values of a multidimensional variable can be read at once. The values
+ are read into consecutive locations with the last dimension varying fastest.
+
+ Take care when using the simplest forms of this interface with record variables when you
+ don't specify how many records are to be read. If you try to read all the values of a
+ record variable into an array but there are more records in the file than you assume,
+ more data will be read than you expect, which may cause a segmentation violation.
+
+ \param dataValues Pointer to the location into which the data value is read. If the type of
+ data value differs from the netCDF variable type, type conversion will occur.
+ (However, no type conversion is carried out for variables using the user-defined data types:
+ ncmpi_Vlen, ncmpi_Opaque, ncmpi_Compound and ncmpi_Enum.)
+ */
+ void getVar_all(long long* dataValues) const;
+
+ void getVar_all(void* dataValues, MPI_Offset bufcount, MPI_Datatype buftype) const;
+
+ ////////////////////
+
+ // Reads a single datum value from a variable of an open netCDF dataset.
+ /*!
+ This is an overloaded member function, provided for convenience.
+ It differs from the above function in what argument(s) it accepts.
+ In addition, no data conversion is carried out. This means that
+ the type of the data in memory must match the type of the variable.
+ */
+ // void getVar_all(const std::vector<MPI_Offset>& index, void* dataumValue) const;
+ /*! \overload
+ */
+ void getVar_all(const std::vector<MPI_Offset>& index, char* dataumValue) const;
+ /*! \overload
+ */
+ void getVar_all(const std::vector<MPI_Offset>& index, unsigned char* dataumValue) const;
+ /*! \overload
+ */
+ void getVar_all(const std::vector<MPI_Offset>& index, signed char* dataumValue) const;
+ /*! \overload
+ */
+ void getVar_all(const std::vector<MPI_Offset>& index, short* dataumValue) const;
+ /*! \overload
+ */
+ void getVar_all(const std::vector<MPI_Offset>& index, int* dataumValue) const;
+ /*! \overload
+ */
+ void getVar_all(const std::vector<MPI_Offset>& index, long* dataumValue) const;
+ /*! \overload
+ */
+ void getVar_all(const std::vector<MPI_Offset>& index, float* dataumValue) const;
+ /*! \overload
+ */
+ void getVar_all(const std::vector<MPI_Offset>& index, double* dataumValue) const;
+ /*! \overload
+ */
+ void getVar_all(const std::vector<MPI_Offset>& index, unsigned short* dataumValue) const;
+ /*! \overload
+ */
+ void getVar_all(const std::vector<MPI_Offset>& index, unsigned int* dataumValue) const;
+ /*! \overload
+ */
+ void getVar_all(const std::vector<MPI_Offset>& index, unsigned long long* dataumValue) const;
+ /*! Reads a single datum value from a variable of an open netCDF dataset.
+ The value is converted from the external data type of the variable, if necessary.
+
+ \param index Vector specifying the index of the data value to be read.
+ The indices are relative to 0, so for example, the first data value of a two-dimensional
+ variable would have index (0,0). The elements of index must correspond to the variable's dimensions.
+ Hence, if the variable is a record variable, the first index is the record number.
+
+ \param datumValue Pointer to the location into which the data value is read. If the type of
+ data value differs from the netCDF variable type, type conversion will occur.
+ (However, no type conversion is carried out for variables using the user-defined data types:
+ ncmpi_Vlen, ncmpi_Opaque, ncmpi_Compound and ncmpi_Enum.)
+ */
+ void getVar_all(const std::vector<MPI_Offset>& index, long long* dataumValue) const;
+
+ void getVar_all(const std::vector<MPI_Offset>& index, void* dataumValue, MPI_Offset bufcount, MPI_Datatype buftype) const;
+
+ //////////////////////
+
+ // Reads an array of values from a netCDF variable of an open netCDF dataset.
+ /*!
+ This is an overloaded member function, provided for convenience.
+ It differs from the above function in what argument(s) it accepts.
+ In addition, no data conversion is carried out. This means that
+ the type of the data in memory must match the type of the variable.
+ */
+ // void getVar_all(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, void* dataValues) const;
+ /*! \overload
+ */
+ void getVar_all(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, char* dataValues) const;
+ /*! \overload
+ */
+ void getVar_all(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, unsigned char* dataValues) const;
+ /*! \overload
+ */
+ void getVar_all(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, signed char* dataValues) const;
+ /*! \overload
+ */
+ void getVar_all(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, short* dataValues) const;
+ /*! \overload
+ */
+ void getVar_all(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, int* dataValues) const;
+ /*! \overload
+ */
+ void getVar_all(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, long* dataValues) const;
+ /*! \overload
+ */
+ void getVar_all(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, float* dataValues) const;
+ /*! \overload
+ */
+ void getVar_all(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, double* dataValues) const;
+ /*! \overload
+ */
+ void getVar_all(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, unsigned short* dataValues) const;
+ /*! \overload
+ */
+ void getVar_all(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, unsigned int* dataValues) const;
+ /*! \overload
+ */
+ void getVar_all(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, unsigned long long* dataValues) const;
+ /*!
+ Reads an array of values from a netCDF variable of an open netCDF dataset.
+ The array is specified by giving a corner and a vector of edge lengths.
+ The values are read into consecutive locations with the last dimension varying fastest.
+
+ \param start
+ Vector specifying the index in the variable where the first of the data values will be read.
+ The indices are relative to 0, so for example, the first data value of a variable would have index (0, 0, ... , 0).
+ The length of start must be the same as the number of dimensions of the specified variable.
+ The elements of start correspond, in order, to the variable's dimensions. Hence, if the variable is a record variable,
+ the first index would correspond to the starting record number for reading the data values.
+
+ \param count
+ Vector specifying the edge lengths along each dimension of the block of data values to be read.
+ To read a single value, for example, specify count as (1, 1, ... , 1). The length of count is the number of
+ dimensions of the specified variable. The elements of count correspond, in order, to the variable's dimensions.
+ Hence, if the variable is a record variable, the first element of count corresponds to a count of the number of records to read.
+ Note: setting any element of the count array to zero causes the function to exit without error, and without doing anything.
+
+ \param dataValues Pointer to the location into which the data value is read. If the type of
+ data value differs from the netCDF variable type, type conversion will occur.
+ (However, no type conversion is carried out for variables using the user-defined data types:
+ ncmpi_Vlen, ncmpi_Opaque, ncmpi_Compound and ncmpi_Enum.)
+ */
+ void getVar_all(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, long long* dataValues) const;
+
+ void getVar_all(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, void* dataValues, MPI_Offset bufcount, MPI_Datatype buftype) const;
+
+ //////////////////////
+
+ // Reads a subsampled (strided) array section of values from a netCDF variable.
+ /*!
+ This is an overloaded member function, provided for convenience.
+ It differs from the above function in what argument(s) it accepts.
+ In addition, no data conversion is carried out. This means that
+ the type of the data in memory must match the type of the variable.
+ */
+ // void getVar_all(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, const std::vector<MPI_Offset>& stride, void* dataValues) const;
+ /*! \overload
+ */
+ void getVar_all(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, const std::vector<MPI_Offset>& stride, char* dataValues) const;
+ /*! \overload
+ */
+ void getVar_all(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, const std::vector<MPI_Offset>& stride, unsigned char* dataValues) const;
+ /*! \overload
+ */
+ void getVar_all(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, const std::vector<MPI_Offset>& stride, signed char* dataValues) const;
+ /*! \overload
+ */
+ void getVar_all(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, const std::vector<MPI_Offset>& stride, short* dataValues) const;
+ /*! \overload
+ */
+ void getVar_all(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, const std::vector<MPI_Offset>& stride, int* dataValues) const;
+ /*! \overload
+ */
+ void getVar_all(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, const std::vector<MPI_Offset>& stride, long* dataValues) const;
+ /*! \overload
+ */
+ void getVar_all(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, const std::vector<MPI_Offset>& stride, float* dataValues) const;
+ /*! \overload
+ */
+ void getVar_all(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, const std::vector<MPI_Offset>& stride, double* dataValues) const;
+ /*! \overload
+ */
+ void getVar_all(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, const std::vector<MPI_Offset>& stride, unsigned short* dataValues) const;
+ /*! \overload
+ */
+ void getVar_all(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, const std::vector<MPI_Offset>& stride, unsigned int* dataValues) const;
+ /*! \overload
+ */
+ void getVar_all(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, const std::vector<MPI_Offset>& stride, unsigned long long* dataValues) const;
+ /*!
+ Reads a subsampled (strided) array section of values from a netCDF variable.
+ The subsampled array section is specified by giving a corner, a vector of edge lengths, and a stride vector.
+ The values are read with the last dimension of the netCDF variable varying fastest.
+
+ \param start
+ Vector specifying the index in the variable where the first of the data values will be read.
+ The indices are relative to 0, so for example, the first data value of a variable would have index (0, 0, ... , 0).
+ The length of start must be the same as the number of dimensions of the specified variable.
+ The elements of start correspond, in order, to the variable's dimensions. Hence, if the variable is a record variable,
+ the first index would correspond to the starting record number for reading the data values.
+
+ \param count
+ Vector specifying the edge lengths along each dimension of the block of data values to be read.
+ To read a single value, for example, specify count as (1, 1, ... , 1). The length of count is the number of
+ dimensions of the specified variable. The elements of count correspond, in order, to the variable's dimensions.
+ Hence, if the variable is a record variable, the first element of count corresponds to a count of the number of records to read.
+ Note: setting any element of the count array to zero causes the function to exit without error, and without doing anything.
+
+ \param stride
+ Vector specifying the interval between selected indices. The elements of the stride vector correspond, in order,
+ to the variable's dimensions. A value of 1 accesses adjacent values of the netCDF variable in the corresponding
+ dimension; a value of 2 accesses every other value of the netCDF variable in the corresponding dimension; and so
+ on. A NULL stride argument is treated as (1, 1, ... , 1).
+
+ \param dataValues Pointer to the location into which the data value is read. If the type of
+ data value differs from the netCDF variable type, type conversion will occur.
+ (However, no type conversion is carried out for variables using the user-defined data types:
+ ncmpi_Vlen, ncmpi_Opaque, ncmpi_Compound and ncmpi_Enum.)
+ */
+ void getVar_all(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, const std::vector<MPI_Offset>& stride, long long* dataValues) const;
+
+ void getVar_all(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, const std::vector<MPI_Offset>& stride, void* dataValues, MPI_Offset bufcount, MPI_Datatype buftype) const;
+
+
+ //////////////////////
+
+ // Reads a mapped array section of values from a netCDF variable.
+ /*!
+ This is an overloaded member function, provided for convenience.
+ It differs from the above function in what argument(s) it accepts.
+ In addition, no data conversion is carried out. This means that
+ the type of the data in memory must match the type of the variable.
+ */
+ // void getVar_all(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, const std::vector<MPI_Offset>& stride, const std::vector<MPI_Offset>& imap, void* dataValues) const;
+ /*! \overload
+ */
+ void getVar_all(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, const std::vector<MPI_Offset>& stride, const std::vector<MPI_Offset>& imap, char* dataValues) const;
+ /*! \overload
+ */
+ void getVar_all(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, const std::vector<MPI_Offset>& stride, const std::vector<MPI_Offset>& imap, unsigned char* dataValues) const;
+ /*! \overload
+ */
+ void getVar_all(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, const std::vector<MPI_Offset>& stride, const std::vector<MPI_Offset>& imap, signed char* dataValues) const;
+ /*! \overload
+ */
+ void getVar_all(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, const std::vector<MPI_Offset>& stride, const std::vector<MPI_Offset>& imap, short* dataValues) const;
+ /*! \overload
+ */
+ void getVar_all(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, const std::vector<MPI_Offset>& stride, const std::vector<MPI_Offset>& imap, int* dataValues) const;
+ /*! \overload
+ */
+ void getVar_all(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, const std::vector<MPI_Offset>& stride, const std::vector<MPI_Offset>& imap, long* dataValues) const;
+ /*! \overload
+ */
+ void getVar_all(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, const std::vector<MPI_Offset>& stride, const std::vector<MPI_Offset>& imap, float* dataValues) const;
+ /*! \overload
+ */
+ void getVar_all(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, const std::vector<MPI_Offset>& stride, const std::vector<MPI_Offset>& imap, double* dataValues) const;
+ /*! \overload
+ */
+ void getVar_all(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, const std::vector<MPI_Offset>& stride, const std::vector<MPI_Offset>& imap, unsigned short* dataValues) const;
+ /*! \overload
+ */
+ void getVar_all(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, const std::vector<MPI_Offset>& stride, const std::vector<MPI_Offset>& imap, unsigned int* dataValues) const;
+ /*! \overload
+ */
+ void getVar_all(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, const std::vector<MPI_Offset>& stride, const std::vector<MPI_Offset>& imap, unsigned long long* dataValues) const;
+ /*!
+ Reads a mapped array section of values from a netCDF variable.
+ The mapped array section is specified by giving a corner, a vector of edge lengths, a stride vector, and an
+ index mapping vector. The index mapping vector is a vector of integers that specifies the mapping between the
+ dimensions of a netCDF variable and the in-memory structure of the internal data array. No assumptions are
+ made about the ordering or length of the dimensions of the data array.
+
+ \param start
+ Vector specifying the index in the variable where the first of the data values will be read.
+ The indices are relative to 0, so for example, the first data value of a variable would have index (0, 0, ... , 0).
+ The length of start must be the same as the number of dimensions of the specified variable.
+ The elements of start correspond, in order, to the variable's dimensions. Hence, if the variable is a record variable,
+ the first index would correspond to the starting record number for reading the data values.
+
+ \param count
+ Vector specifying the edge lengths along each dimension of the block of data values to be read.
+ To read a single value, for example, specify count as (1, 1, ... , 1). The length of count is the number of
+ dimensions of the specified variable. The elements of count correspond, in order, to the variable's dimensions.
+ Hence, if the variable is a record variable, the first element of count corresponds to a count of the number of records to read.
+ Note: setting any element of the count array to zero causes the function to exit without error, and without doing anything.
+
+ \param stride
+ Vector specifying the interval between selected indices. The elements of the stride vector correspond, in order,
+ to the variable's dimensions. A value of 1 accesses adjacent values of the netCDF variable in the corresponding
+ dimension; a value of 2 accesses every other value of the netCDF variable in the corresponding dimension; and so
+ on. A NULL stride argument is treated as (1, 1, ... , 1).
+
+ \param imap
+ Vector of integers that specifies the mapping between the dimensions of a netCDF variable and the in-memory
+ structure of the internal data array. imap[0] gives the distance between elements of the internal array corresponding
+ to the most slowly varying dimension of the netCDF variable. imap[n-1] (where n is the rank of the netCDF variable)
+ gives the distance between elements of the internal array corresponding to the most rapidly varying dimension of the
+ netCDF variable. Intervening imap elements correspond to other dimensions of the netCDF variable in the obvious way.
+ Distances between elements are specified in type-independent units of elements (the distance between internal elements
+ that occupy adjacent memory locations is 1 and not the element's byte-length as in netCDF 2).
+
+ \param dataValues Pointer to the location into which the data value is read. If the type of
+ data value differs from the netCDF variable type, type conversion will occur.
+ (However, no type conversion is carried out for variables using the user-defined data types:
+ ncmpi_Vlen, ncmpi_Opaque, ncmpi_Compound and ncmpi_Enum.)
+ */
+ void getVar_all(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, const std::vector<MPI_Offset>& stride, const std::vector<MPI_Offset>& imap, long long* dataValues) const;
+
+ void getVar_all(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, const std::vector<MPI_Offset>& stride, const std::vector<MPI_Offset>& imap, void* dataValues, MPI_Offset bufcount, MPI_Datatype buftype) const;
+
+
+
+ ////////////////////
+
+ // Nonblocking data reading
+
+ ////////////////////
+
+ // Reads the entire data into the netCDF variable.
+ /*!
+ This is an overloaded member function, provided for convenience.
+ It differs from the above function in what argument(s) it accepts.
+ In addition, no data conversion is carried out. This means that
+ the type of the data in memory must match the type of the variable.
+ */
+ // void igetVar(void* dataValues, int *req) const;
+ /*! \overload
+ */
+ void igetVar(char* dataValues, int *req) const;
+ /*! \overload
+ */
+ void igetVar(unsigned char* dataValues, int *req) const;
+ /*! \overload
+ */
+ void igetVar(signed char* dataValues, int *req) const;
+ /*! \overload
+ */
+ void igetVar(short* dataValues, int *req) const;
+ /*! \overload
+ */
+ void igetVar(int* dataValues, int *req) const;
+ /*! \overload
+ */
+ void igetVar(long* dataValues, int *req) const;
+ /*! \overload
+ */
+ void igetVar(float* dataValues, int *req) const;
+ /*! \overload
+ */
+ void igetVar(double* dataValues, int *req) const;
+ /*! \overload
+ */
+ void igetVar(unsigned short* dataValues, int *req) const;
+ /*! \overload
+ */
+ void igetVar(unsigned int* dataValues, int *req) const;
+ /*! \overload
+ */
+ void igetVar(unsigned long long* dataValues, int *req) const;
+ /*!
+ Reads the entire data from an netCDF variable.
+ This is the simplest interface to use for reading the value of a scalar variable
+ or when all the values of a multidimensional variable can be read at once. The values
+ are read into consecutive locations with the last dimension varying fastest.
+
+ Take care when using the simplest forms of this interface with record variables when you
+ don't specify how many records are to be read. If you try to read all the values of a
+ record variable into an array but there are more records in the file than you assume,
+ more data will be read than you expect, which may cause a segmentation violation.
+
+ \param dataValues Pointer to the location into which the data value is read. If the type of
+ data value differs from the netCDF variable type, type conversion will occur.
+ (However, no type conversion is carried out for variables using the user-defined data types:
+ ncmpi_Vlen, ncmpi_Opaque, ncmpi_Compound and ncmpi_Enum.)
+ */
+ void igetVar(long long* dataValues, int *req) const;
+
+ void igetVar(void* dataValues, MPI_Offset bufcount, MPI_Datatype buftype, int *req) const;
+
+
+ //////////////////////
+
+ // Reads a single datum value from a variable of an open netCDF dataset.
+ /*!
+ This is an overloaded member function, provided for convenience.
+ It differs from the above function in what argument(s) it accepts.
+ In addition, no data conversion is carried out. This means that
+ the type of the data in memory must match the type of the variable.
+ */
+ // void igetVar(const std::vector<MPI_Offset>& index, void* dataumValue, int *req) const;
+ /*! \overload
+ */
+ void igetVar(const std::vector<MPI_Offset>& index, char* dataumValue, int *req) const;
+ /*! \overload
+ */
+ void igetVar(const std::vector<MPI_Offset>& index, unsigned char* dataumValue, int *req) const;
+ /*! \overload
+ */
+ void igetVar(const std::vector<MPI_Offset>& index, signed char* dataumValue, int *req) const;
+ /*! \overload
+ */
+ void igetVar(const std::vector<MPI_Offset>& index, short* dataumValue, int *req) const;
+ /*! \overload
+ */
+ void igetVar(const std::vector<MPI_Offset>& index, int* dataumValue, int *req) const;
+ /*! \overload
+ */
+ void igetVar(const std::vector<MPI_Offset>& index, long* dataumValue, int *req) const;
+ /*! \overload
+ */
+ void igetVar(const std::vector<MPI_Offset>& index, float* dataumValue, int *req) const;
+ /*! \overload
+ */
+ void igetVar(const std::vector<MPI_Offset>& index, double* dataumValue, int *req) const;
+ /*! \overload
+ */
+ void igetVar(const std::vector<MPI_Offset>& index, unsigned short* dataumValue, int *req) const;
+ /*! \overload
+ */
+ void igetVar(const std::vector<MPI_Offset>& index, unsigned int* dataumValue, int *req) const;
+ /*! \overload
+ */
+ void igetVar(const std::vector<MPI_Offset>& index, unsigned long long* dataumValue, int *req) const;
+ /*! Reads a single datum value from a variable of an open netCDF dataset.
+ The value is converted from the external data type of the variable, if necessary.
+
+ \param index Vector specifying the index of the data value to be read.
+ The indices are relative to 0, so for example, the first data value of a two-dimensional
+ variable would have index (0,0). The elements of index must correspond to the variable's dimensions.
+ Hence, if the variable is a record variable, the first index is the record number.
+
+ \param datumValue Pointer to the location into which the data value is read. If the type of
+ data value differs from the netCDF variable type, type conversion will occur.
+ (However, no type conversion is carried out for variables using the user-defined data types:
+ ncmpi_Vlen, ncmpi_Opaque, ncmpi_Compound and ncmpi_Enum.)
+ */
+ void igetVar(const std::vector<MPI_Offset>& index, long long* dataumValue, int *req) const;
+
+ void igetVar(const std::vector<MPI_Offset>& index, void* dataumValue, MPI_Offset bufcount, MPI_Datatype buftype, int *req) const;
+
+ //////////////////////
+
+ // Reads an array of values from a netCDF variable of an open netCDF dataset.
+ /*!
+ This is an overloaded member function, provided for convenience.
+ It differs from the above function in what argument(s) it accepts.
+ In addition, no data conversion is carried out. This means that
+ the type of the data in memory must match the type of the variable.
+ */
+ // void igetVar(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, void* dataValues, int *req) const;
+ /*! \overload
+ */
+ void igetVar(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, char* dataValues, int *req) const;
+ /*! \overload
+ */
+ void igetVar(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, unsigned char* dataValues, int *req) const;
+ /*! \overload
+ */
+ void igetVar(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, signed char* dataValues, int *req) const;
+ /*! \overload
+ */
+ void igetVar(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, short* dataValues, int *req) const;
+ /*! \overload
+ */
+ void igetVar(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, int* dataValues, int *req) const;
+ /*! \overload
+ */
+ void igetVar(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, long* dataValues, int *req) const;
+ /*! \overload
+ */
+ void igetVar(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, float* dataValues, int *req) const;
+ /*! \overload
+ */
+ void igetVar(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, double* dataValues, int *req) const;
+ /*! \overload
+ */
+ void igetVar(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, unsigned short* dataValues, int *req) const;
+ /*! \overload
+ */
+ void igetVar(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, unsigned int* dataValues, int *req) const;
+ /*! \overload
+ */
+ void igetVar(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, unsigned long long* dataValues, int *req) const;
+ /*!
+ Reads an array of values from a netCDF variable of an open netCDF dataset.
+ The array is specified by giving a corner and a vector of edge lengths.
+ The values are read into consecutive locations with the last dimension varying fastest.
+
+ \param start
+ Vector specifying the index in the variable where the first of the data values will be read.
+ The indices are relative to 0, so for example, the first data value of a variable would have index (0, 0, ... , 0).
+ The length of start must be the same as the number of dimensions of the specified variable.
+ The elements of start correspond, in order, to the variable's dimensions. Hence, if the variable is a record variable,
+ the first index would correspond to the starting record number for reading the data values.
+
+ \param count
+ Vector specifying the edge lengths along each dimension of the block of data values to be read.
+ To read a single value, for example, specify count as (1, 1, ... , 1). The length of count is the number of
+ dimensions of the specified variable. The elements of count correspond, in order, to the variable's dimensions.
+ Hence, if the variable is a record variable, the first element of count corresponds to a count of the number of records to read.
+ Note: setting any element of the count array to zero causes the function to exit without error, and without doing anything.
+
+ \param dataValues Pointer to the location into which the data value is read. If the type of
+ data value differs from the netCDF variable type, type conversion will occur.
+ (However, no type conversion is carried out for variables using the user-defined data types:
+ ncmpi_Vlen, ncmpi_Opaque, ncmpi_Compound and ncmpi_Enum.)
+ */
+ void igetVar(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, long long* dataValues, int *req) const;
+
+ void igetVar(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, void* dataValues, MPI_Offset bufcount, MPI_Datatype buftype, int *req) const;
+
+ //////////////////////
+
+ // Reads a subsampled (strided) array section of values from a netCDF variable.
+ /*!
+ This is an overloaded member function, provided for convenience.
+ It differs from the above function in what argument(s) it accepts.
+ In addition, no data conversion is carried out. This means that
+ the type of the data in memory must match the type of the variable.
+ */
+ // void igetVar(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, const std::vector<MPI_Offset>& stride, void* dataValues, int *req) const;
+ /*! \overload
+ */
+ void igetVar(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, const std::vector<MPI_Offset>& stride, char* dataValues, int *req) const;
+ /*! \overload
+ */
+ void igetVar(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, const std::vector<MPI_Offset>& stride, unsigned char* dataValues, int *req) const;
+ /*! \overload
+ */
+ void igetVar(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, const std::vector<MPI_Offset>& stride, signed char* dataValues, int *req) const;
+ /*! \overload
+ */
+ void igetVar(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, const std::vector<MPI_Offset>& stride, short* dataValues, int *req) const;
+ /*! \overload
+ */
+ void igetVar(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, const std::vector<MPI_Offset>& stride, int* dataValues, int *req) const;
+ /*! \overload
+ */
+ void igetVar(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, const std::vector<MPI_Offset>& stride, long* dataValues, int *req) const;
+ /*! \overload
+ */
+ void igetVar(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, const std::vector<MPI_Offset>& stride, float* dataValues, int *req) const;
+ /*! \overload
+ */
+ void igetVar(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, const std::vector<MPI_Offset>& stride, double* dataValues, int *req) const;
+ /*! \overload
+ */
+ void igetVar(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, const std::vector<MPI_Offset>& stride, unsigned short* dataValues, int *req) const;
+ /*! \overload
+ */
+ void igetVar(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, const std::vector<MPI_Offset>& stride, unsigned int* dataValues, int *req) const;
+ /*! \overload
+ */
+ void igetVar(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, const std::vector<MPI_Offset>& stride, unsigned long long* dataValues, int *req) const;
+ /*!
+ Reads a subsampled (strided) array section of values from a netCDF variable.
+ The subsampled array section is specified by giving a corner, a vector of edge lengths, and a stride vector.
+ The values are read with the last dimension of the netCDF variable varying fastest.
+
+ \param start
+ Vector specifying the index in the variable where the first of the data values will be read.
+ The indices are relative to 0, so for example, the first data value of a variable would have index (0, 0, ... , 0).
+ The length of start must be the same as the number of dimensions of the specified variable.
+ The elements of start correspond, in order, to the variable's dimensions. Hence, if the variable is a record variable,
+ the first index would correspond to the starting record number for reading the data values.
+
+ \param count
+ Vector specifying the edge lengths along each dimension of the block of data values to be read.
+ To read a single value, for example, specify count as (1, 1, ... , 1). The length of count is the number of
+ dimensions of the specified variable. The elements of count correspond, in order, to the variable's dimensions.
+ Hence, if the variable is a record variable, the first element of count corresponds to a count of the number of records to read.
+ Note: setting any element of the count array to zero causes the function to exit without error, and without doing anything.
+
+ \param stride
+ Vector specifying the interval between selected indices. The elements of the stride vector correspond, in order,
+ to the variable's dimensions. A value of 1 accesses adjacent values of the netCDF variable in the corresponding
+ dimension; a value of 2 accesses every other value of the netCDF variable in the corresponding dimension; and so
+ on. A NULL stride argument is treated as (1, 1, ... , 1).
+
+ \param dataValues Pointer to the location into which the data value is read. If the type of
+ data value differs from the netCDF variable type, type conversion will occur.
+ (However, no type conversion is carried out for variables using the user-defined data types:
+ ncmpi_Vlen, ncmpi_Opaque, ncmpi_Compound and ncmpi_Enum.)
+ */
+ void igetVar(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, const std::vector<MPI_Offset>& stride, long long* dataValues, int *req) const;
+
+ void igetVar(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, const std::vector<MPI_Offset>& stride, void* dataValues, MPI_Offset bufcount, MPI_Datatype buftype, int *req) const;
+
+
+ //////////////////////
+
+ // Reads a mapped array section of values from a netCDF variable.
+ /*!
+ This is an overloaded member function, provided for convenience.
+ It differs from the above function in what argument(s) it accepts.
+ In addition, no data conversion is carried out. This means that
+ the type of the data in memory must match the type of the variable.
+ */
+ // void igetVar(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, const std::vector<MPI_Offset>& stride, const std::vector<MPI_Offset>& imap, void* dataValues, int *req) const;
+ /*! \overload
+ */
+ void igetVar(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, const std::vector<MPI_Offset>& stride, const std::vector<MPI_Offset>& imap, char* dataValues, int *req) const;
+ /*! \overload
+ */
+ void igetVar(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, const std::vector<MPI_Offset>& stride, const std::vector<MPI_Offset>& imap, unsigned char* dataValues, int *req) const;
+ /*! \overload
+ */
+ void igetVar(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, const std::vector<MPI_Offset>& stride, const std::vector<MPI_Offset>& imap, signed char* dataValues, int *req) const;
+ /*! \overload
+ */
+ void igetVar(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, const std::vector<MPI_Offset>& stride, const std::vector<MPI_Offset>& imap, short* dataValues, int *req) const;
+ /*! \overload
+ */
+ void igetVar(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, const std::vector<MPI_Offset>& stride, const std::vector<MPI_Offset>& imap, int* dataValues, int *req) const;
+ /*! \overload
+ */
+ void igetVar(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, const std::vector<MPI_Offset>& stride, const std::vector<MPI_Offset>& imap, long* dataValues, int *req) const;
+ /*! \overload
+ */
+ void igetVar(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, const std::vector<MPI_Offset>& stride, const std::vector<MPI_Offset>& imap, float* dataValues, int *req) const;
+ /*! \overload
+ */
+ void igetVar(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, const std::vector<MPI_Offset>& stride, const std::vector<MPI_Offset>& imap, double* dataValues, int *req) const;
+ /*! \overload
+ */
+ void igetVar(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, const std::vector<MPI_Offset>& stride, const std::vector<MPI_Offset>& imap, unsigned short* dataValues, int *req) const;
+ /*! \overload
+ */
+ void igetVar(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, const std::vector<MPI_Offset>& stride, const std::vector<MPI_Offset>& imap, unsigned int* dataValues, int *req) const;
+ /*! \overload
+ */
+ void igetVar(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, const std::vector<MPI_Offset>& stride, const std::vector<MPI_Offset>& imap, unsigned long long* dataValues, int *req) const;
+ /*!
+ Reads a mapped array section of values from a netCDF variable.
+ The mapped array section is specified by giving a corner, a vector of edge lengths, a stride vector, and an
+ index mapping vector. The index mapping vector is a vector of integers that specifies the mapping between the
+ dimensions of a netCDF variable and the in-memory structure of the internal data array. No assumptions are
+ made about the ordering or length of the dimensions of the data array.
+
+ \param start
+ Vector specifying the index in the variable where the first of the data values will be read.
+ The indices are relative to 0, so for example, the first data value of a variable would have index (0, 0, ... , 0).
+ The length of start must be the same as the number of dimensions of the specified variable.
+ The elements of start correspond, in order, to the variable's dimensions. Hence, if the variable is a record variable,
+ the first index would correspond to the starting record number for reading the data values.
+
+ \param count
+ Vector specifying the edge lengths along each dimension of the block of data values to be read.
+ To read a single value, for example, specify count as (1, 1, ... , 1). The length of count is the number of
+ dimensions of the specified variable. The elements of count correspond, in order, to the variable's dimensions.
+ Hence, if the variable is a record variable, the first element of count corresponds to a count of the number of records to read.
+ Note: setting any element of the count array to zero causes the function to exit without error, and without doing anything.
+
+ \param stride
+ Vector specifying the interval between selected indices. The elements of the stride vector correspond, in order,
+ to the variable's dimensions. A value of 1 accesses adjacent values of the netCDF variable in the corresponding
+ dimension; a value of 2 accesses every other value of the netCDF variable in the corresponding dimension; and so
+ on. A NULL stride argument is treated as (1, 1, ... , 1).
+
+ \param imap
+ Vector of integers that specifies the mapping between the dimensions of a netCDF variable and the in-memory
+ structure of the internal data array. imap[0] gives the distance between elements of the internal array corresponding
+ to the most slowly varying dimension of the netCDF variable. imap[n-1] (where n is the rank of the netCDF variable)
+ gives the distance between elements of the internal array corresponding to the most rapidly varying dimension of the
+ netCDF variable. Intervening imap elements correspond to other dimensions of the netCDF variable in the obvious way.
+ Distances between elements are specified in type-independent units of elements (the distance between internal elements
+ that occupy adjacent memory locations is 1 and not the element's byte-length as in netCDF 2).
+
+ \param dataValues Pointer to the location into which the data value is read. If the type of
+ data value differs from the netCDF variable type, type conversion will occur.
+ (However, no type conversion is carried out for variables using the user-defined data types:
+ ncmpi_Vlen, ncmpi_Opaque, ncmpi_Compound and ncmpi_Enum.)
+ */
+ void igetVar(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, const std::vector<MPI_Offset>& stride, const std::vector<MPI_Offset>& imap, long long* dataValues, int *req) const;
+
+ void igetVar(const std::vector<MPI_Offset>& start, const std::vector<MPI_Offset>& count, const std::vector<MPI_Offset>& stride, const std::vector<MPI_Offset>& imap, void* dataValues, MPI_Offset bufcount, MPI_Datatype buftype, int *req) const;
+
+ //////////////////////
+
+ // Reads a list of subarrays of values from a netCDF variable of an open netCDF dataset. (independent I/O APIs)
+ /*!
+ This is an overloaded member function, provided for convenience.
+ It differs from the above function in what argument(s) it accepts.
+ In addition, no data conversion is carried out. This means that
+ the type of the data in memory must match the type of the variable.
+ */
+ // void getVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], void* dataValues) const;
+ /*! \overload
+ */
+ void getVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], char* dataValues) const;
+ /*! \overload
+ */
+ void getVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], unsigned char* dataValues) const;
+ /*! \overload
+ */
+ void getVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], signed char* dataValues) const;
+ /*! \overload
+ */
+ void getVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], short* dataValues) const;
+ /*! \overload
+ */
+ void getVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], int* dataValues) const;
+ /*! \overload
+ */
+ void getVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], long* dataValues) const;
+ /*! \overload
+ */
+ void getVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], float* dataValues) const;
+ /*! \overload
+ */
+ void getVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], double* dataValues) const;
+ /*! \overload
+ */
+ void getVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], unsigned short* dataValues) const;
+ /*! \overload
+ */
+ void getVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], unsigned int* dataValues) const;
+ /*! \overload
+ */
+ void getVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], unsigned long long* dataValues) const;
+ /*!
+ Reads a list of subarrays from a netCDF variable of an open netCDF dataset.
+ Each subarray i is specified by giving a corner (starts[i][*]) and a vector of edge lengths (counts[i][*]).
+ The values are read into consecutive locations with the last dimension varying fastest.
+
+ \param num
+ Number of subarrays.
+
+ \param starts
+ 2D array of size [num][ndims] where num is the number of subarrays to get and ndims if the number of dimensions of the specified variable.
+ Each subarray i is specified by starts[i][*], the first of the data values will be read, and counts[i][*], edge lengths of the subarray.
+ The indices are relative to 0, so for example, the first data value of a variable would have index (0, 0, ... , 0).
+ The length of the second dimension of starts and counts must be the same as the number of dimensions of the specified variable.
+ The elements of starts's second dimension correspond, in order, to the variable's dimensions. Hence, if the variable is a record variable,
+ the first element starts[*][0] would correspond to the starting record number for reading the data values.
+
+ \param counts
+ 2D array of size [num][ndims] where num is the number of subarrays to get and ndims if the number of dimensions of the specified variable.
+ To read a single value, for example, specify count as (1, 1, ... , 1). The length of each count[i] is the number of
+ dimensions of the specified variable. The elements of each count[i] correspond, in order, to the variable's dimensions.
+ Hence, if the variable is a record variable, the first element of count[i] corresponds to a count of the number of records to read.
+ Note: setting any element of the count array to zero causes the function to exit without error, and without doing anything.
+
+ \param dataValues Pointer to the location into which the data value is read. If the type of
+ data value differs from the netCDF variable type, type conversion will occur.
+ (However, no type conversion is carried out for variables using the user-defined data types:
+ ncmpi_Vlen, ncmpi_Opaque, ncmpi_Compound and ncmpi_Enum.)
+ */
+ void getVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], long long* dataValues) const;
+
+ void getVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], void* dataValues, MPI_Offset bufcount, MPI_Datatype buftype) const;
+
+ // Reads a list of subarrays of values from a netCDF variable of an open netCDF dataset. (collective I/O APIs)
+ /*!
+ This is an overloaded member function, provided for convenience.
+ It differs from the above function in what argument(s) it accepts.
+ In addition, no data conversion is carried out. This means that
+ the type of the data in memory must match the type of the variable.
+ */
+ // void getVarn_all(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], void* dataValues) const;
+ /*! \overload
+ */
+ void getVarn_all(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], char* dataValues) const;
+ /*! \overload
+ */
+ void getVarn_all(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], unsigned char* dataValues) const;
+ /*! \overload
+ */
+ void getVarn_all(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], signed char* dataValues) const;
+ /*! \overload
+ */
+ void getVarn_all(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], short* dataValues) const;
+ /*! \overload
+ */
+ void getVarn_all(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], int* dataValues) const;
+ /*! \overload
+ */
+ void getVarn_all(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], long* dataValues) const;
+ /*! \overload
+ */
+ void getVarn_all(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], float* dataValues) const;
+ /*! \overload
+ */
+ void getVarn_all(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], double* dataValues) const;
+ /*! \overload
+ */
+ void getVarn_all(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], unsigned short* dataValues) const;
+ /*! \overload
+ */
+ void getVarn_all(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], unsigned int* dataValues) const;
+ /*! \overload
+ */
+ void getVarn_all(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], unsigned long long* dataValues) const;
+ /*!
+ Reads a list of subarrays from a netCDF variable of an open netCDF dataset.
+ Each subarray i is specified by giving a corner (starts[i][*]) and a vector of edge lengths (counts[i][*]).
+ The values are read into consecutive locations with the last dimension varying fastest.
+
+ \param num
+ Number of subarrays.
+
+ \param starts
+ 2D array of size [num][ndims] where num is the number of subarrays to get and ndims if the number of dimensions of the specified variable.
+ Each subarray i is specified by starts[i][*], the first of the data values will be read, and counts[i][*], edge lengths of the subarray.
+ The indices are relative to 0, so for example, the first data value of a variable would have index (0, 0, ... , 0).
+ The length of the second dimension of starts and counts must be the same as the number of dimensions of the specified variable.
+ The elements of starts's second dimension correspond, in order, to the variable's dimensions. Hence, if the variable is a record variable,
+ the first element starts[*][0] would correspond to the starting record number for reading the data values.
+
+ \param counts
+ 2D array of size [num][ndims] where num is the number of subarrays to get and ndims if the number of dimensions of the specified variable.
+ To read a single value, for example, specify count as (1, 1, ... , 1). The length of each count[i] is the number of
+ dimensions of the specified variable. The elements of each count[i] correspond, in order, to the variable's dimensions.
+ Hence, if the variable is a record variable, the first element of count[i] corresponds to a count of the number of records to read.
+ Note: setting any element of the count array to zero causes the function to exit without error, and without doing anything.
+
+ \param dataValues Pointer to the location into which the data value is read. If the type of
+ data value differs from the netCDF variable type, type conversion will occur.
+ (However, no type conversion is carried out for variables using the user-defined data types:
+ ncmpi_Vlen, ncmpi_Opaque, ncmpi_Compound and ncmpi_Enum.)
+ */
+ void getVarn_all(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], long long* dataValues) const;
+
+ void getVarn_all(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], void* dataValues, MPI_Offset bufcount, MPI_Datatype buftype) const;
+
+ /* vard APIs take filetype and buftype */
+ void getVard (MPI_Datatype filetype, void* dataValues, MPI_Offset bufcount, MPI_Datatype buftype) const;
+ void getVard_all(MPI_Datatype filetype, void* dataValues, MPI_Offset bufcount, MPI_Datatype buftype) const;
+
+ //////////////////////
+
+ // Nonblocking reads a list of subarrays of values from a netCDF variable of an open netCDF dataset.
+ /*!
+ This is an overloaded member function, provided for convenience.
+ It differs from the above function in what argument(s) it accepts.
+ In addition, no data conversion is carried out. This means that
+ the type of the data in memory must match the type of the variable.
+ */
+ // void igetVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], void* dataValues, int *req) const;
+ /*! \overload
+ */
+ void igetVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], char* dataValues, int *req) const;
+ /*! \overload
+ */
+ void igetVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], unsigned char* dataValues, int *req) const;
+ /*! \overload
+ */
+ void igetVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], signed char* dataValues, int *req) const;
+ /*! \overload
+ */
+ void igetVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], short* dataValues, int *req) const;
+ /*! \overload
+ */
+ void igetVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], int* dataValues, int *req) const;
+ /*! \overload
+ */
+ void igetVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], long* dataValues, int *req) const;
+ /*! \overload
+ */
+ void igetVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], float* dataValues, int *req) const;
+ /*! \overload
+ */
+ void igetVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], double* dataValues, int *req) const;
+ /*! \overload
+ */
+ void igetVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], unsigned short* dataValues, int *req) const;
+ /*! \overload
+ */
+ void igetVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], unsigned int* dataValues, int *req) const;
+ /*! \overload
+ */
+ void igetVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], unsigned long long* dataValues, int *req) const;
+ /*!
+ Reads a list of subarrays from a netCDF variable of an open netCDF dataset.
+ Each subarray i is specified by giving a corner (starts[i][*]) and a vector of edge lengths (counts[i][*]).
+ The values are read into consecutive locations with the last dimension varying fastest.
+
+ \param num
+ Number of subarrays.
+
+ \param starts
+ 2D array of size [num][ndims] where num is the number of subarrays to get and ndims if the number of dimensions of the specified variable.
+ Each subarray i is specified by starts[i][*], the first of the data values will be read, and counts[i][*], edge lengths of the subarray.
+ The indices are relative to 0, so for example, the first data value of a variable would have index (0, 0, ... , 0).
+ The length of the second dimension of starts and counts must be the same as the number of dimensions of the specified variable.
+ The elements of starts's second dimension correspond, in order, to the variable's dimensions. Hence, if the variable is a record variable,
+ the first element starts[*][0] would correspond to the starting record number for reading the data values.
+
+ \param counts
+ 2D array of size [num][ndims] where num is the number of subarrays to get and ndims if the number of dimensions of the specified variable.
+ To read a single value, for example, specify count as (1, 1, ... , 1). The length of each count[i] is the number of
+ dimensions of the specified variable. The elements of each count[i] correspond, in order, to the variable's dimensions.
+ Hence, if the variable is a record variable, the first element of count[i] corresponds to a count of the number of records to read.
+ Note: setting any element of the count array to zero causes the function to exit without error, and without doing anything.
+
+ \param dataValues Pointer to the location into which the data value is read. If the type of
+ data value differs from the netCDF variable type, type conversion will occur.
+ (However, no type conversion is carried out for variables using the user-defined data types:
+ ncmpi_Vlen, ncmpi_Opaque, ncmpi_Compound and ncmpi_Enum.)
+ */
+ void igetVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], long long* dataValues, int *req) const;
+
+ void igetVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], void* dataValues, MPI_Offset bufcount, MPI_Datatype buftype, int *req) const;
+
+ //////////////////////
+
+
+ // data writing (independent data mode)
+
+ ////////////////////
+
+ // Writes the entire data into the netCDF variable.
+ /*!
+ This is an overloaded member function, provided for convenience.
+ It differs from the above function in what argument(s) it accepts.
+ In addition, no data conversion is carried out. This means that
+ the type of the data in memory must match the type of the variable.
+ */
+ // void putVar(const void* dataValues) const;
+ /*! \overload
+ */
+ void putVar(const char* dataValues) const;
+ /*! \overload
+ */
+ void putVar(const unsigned char* dataValues) const;
+ /*! \overload
+ */
+ void putVar(const signed char* dataValues) const;
+ /*! \overload
+ */
+ void putVar(const short* dataValues) const;
+ /*! \overload
+ */
+ void putVar(const int* dataValues) const;
+ /*! \overload
+ */
+ void putVar(const long* dataValues) const;
+ /*! \overload
+ */
+ void putVar(const float* dataValues) const;
+ /*! \overload
+ */
+ void putVar(const double* dataValues) const;
+ /*! \overload
+ */
+ void putVar(const unsigned short* dataValues) const;
+ /*! \overload
+ */
+ void putVar(const unsigned int* dataValues) const;
+ /*! \overload
+ */
+ void putVar(const unsigned long long* dataValues) const;
+ /*!
+ Writes the entire data into the netCDF variable.
+ This is the simplest interface to use for writing a value in a scalar variable
+ or whenever all the values of a multidimensional variable can all be
+ written at once. The values to be written are associated with the
+ netCDF variable by assuming that the last dimension of the netCDF
+ variable varies fastest in the C interface.
+
+ Take care when using the simplest forms of this interface with
+ record variables when you don't specify how many records are to be
+ written. If you try to write all the values of a record variable
+ into a netCDF file that has no record data yet (hence has 0 records),
+ nothing will be written. Similarly, if you try to write all of a record
+ variable but there are more records in the file than you assume, more data
+ may be written to the file than you supply, which may result in a
+ segmentation violation.
+
+ \param dataValues The data values. The order in which the data will be written to the netCDF variable is with the last
+ dimension of the specified variable varying fastest. If the type of data values differs from the netCDF variable type, type conversion will occur.
+ (However, no type conversion is carried out for variables using the user-defined data types:
+ ncmpi_Vlen, ncmpi_Opaque, ncmpi_Compound and ncmpi_Enum.)
+ */
+ void putVar(const long long* dataValues) const;
+
+ void putVar(const void* dataValues, MPI_Offset bufcount, MPI_Datatype buftype) const;
+
+ /////////////////////////
+
+ // Writes a single datum into the netCDF variable.
+ /*!
+ This is an overloaded member function, provided for convenience.
+ It differs from the above function in what argument(s) it accepts.
+ In addition, no data conversion is carried out. This means that
+ the type of the data in memory must match the type of the variable.
+ */
+ // void putVar(const std::vector<MPI_Offset>& index, const void* dataumValue) const;
+ /*! \overload
+ */
+ void putVar(const std::vector<MPI_Offset>& index, const std::string& dataumValue) const;
+ /*! \overload
+ */
+ void putVar(const std::vector<MPI_Offset>& index, const unsigned char* dataumValue) const;
+ /*! \overload
+ */
+ void putVar(const std::vector<MPI_Offset>& index, const signed char* dataumValue) const;
+ /*! \overload
+ */
+ void putVar(const std::vector<MPI_Offset>& index, const short dataumValue) const;
+ /*! \overload
+ */
+ void putVar(const std::vector<MPI_Offset>& index, const int dataumValue) const;
+ /*! \overload
+ */
+ void putVar(const std::vector<MPI_Offset>& index, const long dataumValue) const;
+ /*! \overload
+ */
+ void putVar(const std::vector<MPI_Offset>& index, const float dataumValue) const;
+ /*! \overload
+ */
+ void putVar(const std::vector<MPI_Offset>& index, const double dataumValue) const;
+ /*! \overload
+ */
+ void putVar(const std::vector<MPI_Offset>& index, const unsigned short dataumValue) const;
+ /*! \overload
+ */
+ void putVar(const std::vector<MPI_Offset>& index, const unsigned int dataumValue) const;
+ /*! \overload
+ */
+ void putVar(const std::vector<MPI_Offset>& index, const unsigned long long dataumValue) const;
+ /*!
+ Writes a single datum into the netCDF variable.
+
+ \param index Vector specifying the index where the data values will be written. The indices are relative to 0, so for example,
+ the first data value of a two-dimensional variable would have index (0,0). The elements of index must correspond to the variable's dimensions.
+ Hence, if the variable uses the unlimited dimension, the first index would correspond to the unlimited dimension.
+
+ \param datumValue The data value. If the type of data values differs from the netCDF variable type, type conversion will occur.
+ (However, no type conversion is carried out for variables using the user-defined data types:
+ ncmpi_Vlen, ncmpi_Opaque, ncmpi_Compound and ncmpi_Enum.)
+ */
+ void putVar(const std::vector<MPI_Offset>& index, const long long dataumValue) const;
+
+ void putVar(const std::vector<MPI_Offset>& index, const void* dataumValue, MPI_Offset bufcount, MPI_Datatype buftype) const;
+
+ /////////////////////////
+
+ // Writes an array of values into the netCDF variable.
+ /*!
+ This is an overloaded member function, provided for convenience.
+ It differs from the above function in what argument(s) it accepts.
+ In addition, no data conversion is carried out. This means that
+ the type of the data in memory must match the type of the variable.
+ */
+ // void putVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const void* dataValues) const;
+ /*! \overload
+ */
+ void putVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const char* dataValues) const;
+ /*! \overload
+ */
+ void putVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const unsigned char* dataValues) const;
+ /*! \overload
+ */
+ void putVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const signed char* dataValues) const;
+ /*! \overload
+ */
+ void putVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const short* dataValues) const;
+ /*! \overload
+ */
+ void putVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const int* dataValues) const;
+ /*! \overload
+ */
+ void putVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const long* dataValues) const;
+ /*! \overload
+ */
+ void putVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const float* dataValues) const;
+ /*! \overload
+ */
+ void putVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const double* dataValues) const;
+ /*! \overload
+ */
+ void putVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const unsigned short* dataValues) const;
+ /*! \overload
+ */
+ void putVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const unsigned int* dataValues) const;
+ /*! \overload
+ */
+ void putVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const unsigned long long* dataValues) const;
+ /*!
+ Writes an array of values into the netCDF variable.
+ The portion of the netCDF variable to write is specified by giving a corner and a vector of edge lengths
+ that refer to an array section of the netCDF variable. The values to be written are associated with
+ the netCDF variable by assuming that the last dimension of the netCDF variable varies fastest.
+
+ \param startp Vector specifying the index where the first data values will be written. The indices are relative to 0, so for
+ example, the first data value of a variable would have index (0, 0, ... , 0). The elements of start correspond, in order, to the
+ variable's dimensions. Hence, if the variable is a record variable, the first index corresponds to the starting record number for writing the data values.
+
+ \param countp Vector specifying the number of indices selected along each dimension.
+ To write a single value, for example, specify count as (1, 1, ... , 1). The elements of
+ count correspond, in order, to the variable's dimensions. Hence, if the variable is a record
+ variable, the first element of count corresponds to a count of the number of records to write. Note: setting any element
+ of the count array to zero causes the function to exit without error, and without doing anything.
+
+ \param dataValues The data values. The order in which the data will be written to the netCDF variable is with the last
+ dimension of the specified variable varying fastest. If the type of data values differs from the netCDF variable
+ type, type conversion will occur. (However, no type conversion is
+ carried out for variables using the user-defined data types:
+ ncmpi_Vlen, ncmpi_Opaque, ncmpi_Compound and ncmpi_Enum.)
+ */
+ void putVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const long long* dataValues) const;
+ void putVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const void* dataValues, MPI_Offset bufcount, MPI_Datatype buftype) const;
+
+ ////////////////
+
+ // Writes a set of subsampled array values into the netCDF variable.
+ /*!
+ This is an overloaded member function, provided for convenience.
+ It differs from the above function in what argument(s) it accepts.
+ In addition, no data conversion is carried out. This means that
+ the type of the data in memory must match the type of the variable.
+ */
+ // void putVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const void* dataValues) const;
+ /*! \overload
+ */
+ void putVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const char* dataValues) const;
+ /*! \overload
+ */
+ void putVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const unsigned char* dataValues) const;
+ /*! \overload
+ */
+ void putVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const signed char* dataValues) const;
+ /*! \overload
+ */
+ void putVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const short* dataValues) const;
+ /*! \overload
+ */
+ void putVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const int* dataValues) const;
+ /*! \overload
+ */
+ void putVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const long* dataValues) const;
+ /*! \overload
+ */
+ void putVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const float* dataValues) const;
+ /*! \overload
+ */
+ void putVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const double* dataValues) const;
+ /*! \overload
+ */
+ void putVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const unsigned short* dataValues) const;
+ /*! \overload
+ */
+ void putVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const unsigned int* dataValues) const;
+ /*! \overload
+ */
+ void putVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const unsigned long long* dataValues) const;
+ /*!
+ Writes an array of values into the netCDF variable.
+ The subsampled array section is specified by giving a corner, a vector of counts, and a stride vector.
+
+ \param startp Vector specifying the index where the first data values will be written. The indices are relative to 0, so for
+ example, the first data value of a variable would have index (0, 0, ... , 0). The elements of start correspond, in order, to the
+ variable's dimensions. Hence, if the variable is a record variable, the first index corresponds to the starting record number for writing the data values.
+
+ \param countp Vector specifying the number of indices selected along each dimension.
+ To write a single value, for example, specify count as (1, 1, ... , 1). The elements of
+ count correspond, in order, to the variable's dimensions. Hence, if the variable is a record
+ variable, the first element of count corresponds to a count of the number of records to write. Note: setting any element
+ of the count array to zero causes the function to exit without error, and without doing anything.
+
+ \param stridep A vector of MPI_Offset integers that specifies the sampling interval along each dimension of the netCDF variable.
+ The elements of the stride vector correspond, in order, to the netCDF variable's dimensions (stride[0] gives the sampling interval
+ along the most slowly varying dimension of the netCDF variable). Sampling intervals are specified in type-independent units of
+ elements (a value of 1 selects consecutive elements of the netCDF variable along the corresponding dimension, a value of 2 selects
+ every other element, etc.). A NULL stride argument is treated as (1, 1, ... , 1).
+
+ \param dataValues The data values. The order in which the data will be written to the netCDF variable is with the last
+ dimension of the specified variable varying fastest. If the type of data values differs from the netCDF variable type, type conversion will occur.
+ (However, no type conversion is carried out for variables using the user-defined data types: ncmpi_Vlen, ncmpi_Opaque, ncmpi_Compound and ncmpi_Enum.
+ */
+ void putVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const long long* dataValues) const;
+
+ void putVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const void* dataValues, MPI_Offset bufcount, MPI_Datatype buftype) const;
+
+ ////////////////
+
+ // Writes a mapped array section of values into the netCDF variable.
+ /*!
+ This is an overloaded member function, provided for convenience.
+ It differs from the above function in what argument(s) it accepts.
+ In addition, no data conversion is carried out. This means that
+ the type of the data in memory must match the type of the variable.
+ */
+ // void putVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const std::vector<MPI_Offset>& imapp, const void* dataValues) const;
+ /*! \overload
+ */
+ void putVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const std::vector<MPI_Offset>& imapp, const char* dataValues) const;
+ /*! \overload
+ */
+ void putVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const std::vector<MPI_Offset>& imapp, const unsigned char* dataValues) const;
+ /*! \overload
+ */
+ void putVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const std::vector<MPI_Offset>& imapp, const signed char* dataValues) const;
+ /*! \overload
+ */
+ void putVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const std::vector<MPI_Offset>& imapp, const short* dataValues) const;
+ /*! \overload
+ */
+ void putVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const std::vector<MPI_Offset>& imapp, const int* dataValues) const;
+ /*! \overload
+ */
+ void putVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const std::vector<MPI_Offset>& imapp, const long* dataValues) const;
+ /*! \overload
+ */
+ void putVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const std::vector<MPI_Offset>& imapp, const float* dataValues) const;
+ /*! \overload
+ */
+ void putVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const std::vector<MPI_Offset>& imapp, const double* dataValues) const;
+ /*! \overload
+ */
+ void putVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const std::vector<MPI_Offset>& imapp, const unsigned short* dataValues) const;
+ /*! \overload
+ */
+ void putVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const std::vector<MPI_Offset>& imapp, const unsigned int* dataValues) const;
+ /*! \overload
+ */
+ void putVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const std::vector<MPI_Offset>& imapp, const unsigned long long* dataValues) const;
+ /*!
+ Writes a mapped array section of values into the netCDF variable.
+ The mapped array section is specified by giving a corner, a vector of counts, a stride vector, and an index mapping vector.
+ The index mapping vector is a vector of integers that specifies the mapping between the dimensions of a netCDF variable and the in-memory structure of the internal data array.
+ No assumptions are made about the ordering or length of the dimensions of the data array.
+
+ \param countp Vector specifying the number of indices selected along each dimension.
+ To write a single value, for example, specify count as (1, 1, ... , 1). The elements of
+ count correspond, in order, to the variable's dimensions. Hence, if the variable is a record
+ variable, the first element of count corresponds to a count of the number of records to write. Note: setting any element
+ of the count array to zero causes the function to exit without error, and without doing anything.
+
+ \param stridep A vector of MPI_Offset integers that specifies the sampling interval along each dimension of the netCDF variable.
+ The elements of the stride vector correspond, in order, to the netCDF variable's dimensions (stride[0] gives the sampling interval
+ along the most slowly varying dimension of the netCDF variable). Sampling intervals are specified in type-independent units of
+ elements (a value of 1 selects consecutive elements of the netCDF variable along the corresponding dimension, a value of 2 selects
+ every other element, etc.). A NULL stride argument is treated as (1, 1, ... , 1).
+
+ \param imap Vector specifies the mapping between the dimensions of a netCDF variable and the in-memory structure of the internal data array.
+ The elements of the index mapping vector correspond, in order, to the netCDF variable's dimensions (imap[0] gives the distance between elements
+ of the internal array corresponding to the most slowly varying dimension of the netCDF variable). Distances between elements are
+ specified in type-independent units of elements (the distance between internal elements that occupy adjacent memory locations is
+ 1 and not the element's byte-length as in netCDF 2). A NULL argument means the memory-resident values have the same structure as
+ the associated netCDF variable.
+
+ \param dataValues The data values. The order in which the data will be written to the netCDF variable is with the last
+ dimension of the specified variable varying fastest. If the type of data values differs from the netCDF variable type, type conversion will occur.
+ (However, no type conversion is carried out for variables using the user-defined data types: ncmpi_Vlen, ncmpi_Opaque, ncmpi_Compound and ncmpi_Enum.)
+*/
+ void putVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const std::vector<MPI_Offset>& imapp, const long long* dataValues) const;
+
+ void putVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const std::vector<MPI_Offset>& imapp, const void* dataValues, MPI_Offset bufcount, MPI_Datatype buftype) const;
+
+ ////////////////////
+
+ // data writing (collective data mode)
+
+ ////////////////////
+
+ // Writes the entire data into the netCDF variable.
+ /*!
+ This is an overloaded member function, provided for convenience.
+ It differs from the above function in what argument(s) it accepts.
+ In addition, no data conversion is carried out. This means that
+ the type of the data in memory must match the type of the variable.
+ */
+ // void putVar_all(const void* dataValues) const;
+ /*! \overload
+ */
+ void putVar_all(const char* dataValues) const;
+ /*! \overload
+ */
+ void putVar_all(const unsigned char* dataValues) const;
+ /*! \overload
+ */
+ void putVar_all(const signed char* dataValues) const;
+ /*! \overload
+ */
+ void putVar_all(const short* dataValues) const;
+ /*! \overload
+ */
+ void putVar_all(const int* dataValues) const;
+ /*! \overload
+ */
+ void putVar_all(const long* dataValues) const;
+ /*! \overload
+ */
+ void putVar_all(const float* dataValues) const;
+ /*! \overload
+ */
+ void putVar_all(const double* dataValues) const;
+ /*! \overload
+ */
+ void putVar_all(const unsigned short* dataValues) const;
+ /*! \overload
+ */
+ void putVar_all(const unsigned int* dataValues) const;
+ /*! \overload
+ */
+ void putVar_all(const unsigned long long* dataValues) const;
+ /*!
+ Writes the entire data into the netCDF variable.
+ This is the simplest interface to use for writing a value in a scalar variable
+ or whenever all the values of a multidimensional variable can all be
+ written at once. The values to be written are associated with the
+ netCDF variable by assuming that the last dimension of the netCDF
+ variable varies fastest in the C interface.
+
+ Take care when using the simplest forms of this interface with
+ record variables when you don't specify how many records are to be
+ written. If you try to write all the values of a record variable
+ into a netCDF file that has no record data yet (hence has 0 records),
+ nothing will be written. Similarly, if you try to write all of a record
+ variable but there are more records in the file than you assume, more data
+ may be written to the file than you supply, which may result in a
+ segmentation violation.
+
+ \param dataValues The data values. The order in which the data will be written to the netCDF variable is with the last
+ dimension of the specified variable varying fastest. If the type of data values differs from the netCDF variable type, type conversion will occur.
+ (However, no type conversion is carried out for variables using the user-defined data types:
+ ncmpi_Vlen, ncmpi_Opaque, ncmpi_Compound and ncmpi_Enum.)
+ */
+ void putVar_all(const long long* dataValues) const;
+
+ void putVar_all(const void* dataValues, MPI_Offset bufcount, MPI_Datatype buftype) const;
+
+ /////////////////////////
+
+ // Writes a single datum into the netCDF variable.
+ /*!
+ This is an overloaded member function, provided for convenience.
+ It differs from the above function in what argument(s) it accepts.
+ In addition, no data conversion is carried out. This means that
+ the type of the data in memory must match the type of the variable.
+ */
+ // void putVar_all(const std::vector<MPI_Offset>& index, const void* dataumValue) const;
+ /*! \overload
+ */
+ void putVar_all(const std::vector<MPI_Offset>& index, const std::string& dataumValue) const;
+ /*! \overload
+ */
+ void putVar_all(const std::vector<MPI_Offset>& index, const unsigned char* dataumValue) const;
+ /*! \overload
+ */
+ void putVar_all(const std::vector<MPI_Offset>& index, const signed char* dataumValue) const;
+ /*! \overload
+ */
+ void putVar_all(const std::vector<MPI_Offset>& index, const short dataumValue) const;
+ /*! \overload
+ */
+ void putVar_all(const std::vector<MPI_Offset>& index, const int dataumValue) const;
+ /*! \overload
+ */
+ void putVar_all(const std::vector<MPI_Offset>& index, const long dataumValue) const;
+ /*! \overload
+ */
+ void putVar_all(const std::vector<MPI_Offset>& index, const float dataumValue) const;
+ /*! \overload
+ */
+ void putVar_all(const std::vector<MPI_Offset>& index, const double dataumValue) const;
+ /*! \overload
+ */
+ void putVar_all(const std::vector<MPI_Offset>& index, const unsigned short dataumValue) const;
+ /*! \overload
+ */
+ void putVar_all(const std::vector<MPI_Offset>& index, const unsigned int dataumValue) const;
+ /*! \overload
+ */
+ void putVar_all(const std::vector<MPI_Offset>& index, const unsigned long long dataumValue) const;
+ /*!
+ Writes a single datum into the netCDF variable.
+
+ \param index Vector specifying the index where the data values will be written. The indices are relative to 0, so for example,
+ the first data value of a two-dimensional variable would have index (0,0). The elements of index must correspond to the variable's dimensions.
+ Hence, if the variable uses the unlimited dimension, the first index would correspond to the unlimited dimension.
+
+ \param datumValue The data value. If the type of data values differs from the netCDF variable type, type conversion will occur.
+ (However, no type conversion is carried out for variables using the user-defined data types:
+ ncmpi_Vlen, ncmpi_Opaque, ncmpi_Compound and ncmpi_Enum.)
+ */
+ void putVar_all(const std::vector<MPI_Offset>& index, const long long dataumValue) const;
+
+ void putVar_all(const std::vector<MPI_Offset>& index, const void* dataumValue, MPI_Offset bufcount, MPI_Datatype buftype) const;
+
+ /////////////////////////
+
+ // Writes an array of values into the netCDF variable.
+ /*!
+ This is an overloaded member function, provided for convenience.
+ It differs from the above function in what argument(s) it accepts.
+ In addition, no data conversion is carried out. This means that
+ the type of the data in memory must match the type of the variable.
+ */
+ // void putVar_all(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const void* dataValues) const;
+ /*! \overload
+ */
+ void putVar_all(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const char* dataValues) const;
+ /*! \overload
+ */
+ void putVar_all(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const unsigned char* dataValues) const;
+ /*! \overload
+ */
+ void putVar_all(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const signed char* dataValues) const;
+ /*! \overload
+ */
+ void putVar_all(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const short* dataValues) const;
+ /*! \overload
+ */
+ void putVar_all(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const int* dataValues) const;
+ /*! \overload
+ */
+ void putVar_all(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const long* dataValues) const;
+ /*! \overload
+ */
+ void putVar_all(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const float* dataValues) const;
+ /*! \overload
+ */
+ void putVar_all(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const double* dataValues) const;
+ /*! \overload
+ */
+ void putVar_all(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const unsigned short* dataValues) const;
+ /*! \overload
+ */
+ void putVar_all(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const unsigned int* dataValues) const;
+ /*! \overload
+ */
+ void putVar_all(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const unsigned long long* dataValues) const;
+ /*!
+ Writes an array of values into the netCDF variable.
+ The portion of the netCDF variable to write is specified by giving a corner and a vector of edge lengths
+ that refer to an array section of the netCDF variable. The values to be written are associated with
+ the netCDF variable by assuming that the last dimension of the netCDF variable varies fastest.
+
+ \param startp Vector specifying the index where the first data values will be written. The indices are relative to 0, so for
+ example, the first data value of a variable would have index (0, 0, ... , 0). The elements of start correspond, in order, to the
+ variable's dimensions. Hence, if the variable is a record variable, the first index corresponds to the starting record number for writing the data values.
+
+ \param countp Vector specifying the number of indices selected along each dimension.
+ To write a single value, for example, specify count as (1, 1, ... , 1). The elements of
+ count correspond, in order, to the variable's dimensions. Hence, if the variable is a record
+ variable, the first element of count corresponds to a count of the number of records to write. Note: setting any element
+ of the count array to zero causes the function to exit without error, and without doing anything.
+
+ \param dataValues The data values. The order in which the data will be written to the netCDF variable is with the last
+ dimension of the specified variable varying fastest. If the type of data values differs from the netCDF variable
+ type, type conversion will occur. (However, no type conversion is
+ carried out for variables using the user-defined data types:
+ ncmpi_Vlen, ncmpi_Opaque, ncmpi_Compound and ncmpi_Enum.)
+ */
+ void putVar_all(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const long long* dataValues) const;
+ void putVar_all(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const void* dataValues, MPI_Offset bufcount, MPI_Datatype buftype) const;
+
+ ////////////////
+
+ // Writes a set of subsampled array values into the netCDF variable.
+ /*!
+ This is an overloaded member function, provided for convenience.
+ It differs from the above function in what argument(s) it accepts.
+ In addition, no data conversion is carried out. This means that
+ the type of the data in memory must match the type of the variable.
+ */
+ // void putVar_all(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const void* dataValues) const;
+ /*! \overload
+ */
+ void putVar_all(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const char* dataValues) const;
+ /*! \overload
+ */
+ void putVar_all(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const unsigned char* dataValues) const;
+ /*! \overload
+ */
+ void putVar_all(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const signed char* dataValues) const;
+ /*! \overload
+ */
+ void putVar_all(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const short* dataValues) const;
+ /*! \overload
+ */
+ void putVar_all(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const int* dataValues) const;
+ /*! \overload
+ */
+ void putVar_all(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const long* dataValues) const;
+ /*! \overload
+ */
+ void putVar_all(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const float* dataValues) const;
+ /*! \overload
+ */
+ void putVar_all(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const double* dataValues) const;
+ /*! \overload
+ */
+ void putVar_all(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const unsigned short* dataValues) const;
+ /*! \overload
+ */
+ void putVar_all(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const unsigned int* dataValues) const;
+ /*! \overload
+ */
+ void putVar_all(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const unsigned long long* dataValues) const;
+ /*!
+ Writes an array of values into the netCDF variable.
+ The subsampled array section is specified by giving a corner, a vector of counts, and a stride vector.
+
+ \param startp Vector specifying the index where the first data values will be written. The indices are relative to 0, so for
+ example, the first data value of a variable would have index (0, 0, ... , 0). The elements of start correspond, in order, to the
+ variable's dimensions. Hence, if the variable is a record variable, the first index corresponds to the starting record number for writing the data values.
+
+ \param countp Vector specifying the number of indices selected along each dimension.
+ To write a single value, for example, specify count as (1, 1, ... , 1). The elements of
+ count correspond, in order, to the variable's dimensions. Hence, if the variable is a record
+ variable, the first element of count corresponds to a count of the number of records to write. Note: setting any element
+ of the count array to zero causes the function to exit without error, and without doing anything.
+
+ \param stridep A vector of MPI_Offset integers that specifies the sampling interval along each dimension of the netCDF variable.
+ The elements of the stride vector correspond, in order, to the netCDF variable's dimensions (stride[0] gives the sampling interval
+ along the most slowly varying dimension of the netCDF variable). Sampling intervals are specified in type-independent units of
+ elements (a value of 1 selects consecutive elements of the netCDF variable along the corresponding dimension, a value of 2 selects
+ every other element, etc.). A NULL stride argument is treated as (1, 1, ... , 1).
+
+ \param dataValues The data values. The order in which the data will be written to the netCDF variable is with the last
+ dimension of the specified variable varying fastest. If the type of data values differs from the netCDF variable type, type conversion will occur.
+ (However, no type conversion is carried out for variables using the user-defined data types: ncmpi_Vlen, ncmpi_Opaque, ncmpi_Compound and ncmpi_Enum.
+ */
+ void putVar_all(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const long long* dataValues) const;
+
+ void putVar_all(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const void* dataValues, MPI_Offset bufcount, MPI_Datatype buftype) const;
+
+ ////////////////
+
+ // Writes a mapped array section of values into the netCDF variable.
+ /*!
+ This is an overloaded member function, provided for convenience.
+ It differs from the above function in what argument(s) it accepts.
+ In addition, no data conversion is carried out. This means that
+ the type of the data in memory must match the type of the variable.
+ */
+ // void putVar_all(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const std::vector<MPI_Offset>& imapp, const void* dataValues) const;
+ /*! \overload
+ */
+ void putVar_all(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const std::vector<MPI_Offset>& imapp, const char* dataValues) const;
+ /*! \overload
+ */
+ void putVar_all(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const std::vector<MPI_Offset>& imapp, const unsigned char* dataValues) const;
+ /*! \overload
+ */
+ void putVar_all(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const std::vector<MPI_Offset>& imapp, const signed char* dataValues) const;
+ /*! \overload
+ */
+ void putVar_all(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const std::vector<MPI_Offset>& imapp, const short* dataValues) const;
+ /*! \overload
+ */
+ void putVar_all(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const std::vector<MPI_Offset>& imapp, const int* dataValues) const;
+ /*! \overload
+ */
+ void putVar_all(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const std::vector<MPI_Offset>& imapp, const long* dataValues) const;
+ /*! \overload
+ */
+ void putVar_all(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const std::vector<MPI_Offset>& imapp, const float* dataValues) const;
+ /*! \overload
+ */
+ void putVar_all(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const std::vector<MPI_Offset>& imapp, const double* dataValues) const;
+ /*! \overload
+ */
+ void putVar_all(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const std::vector<MPI_Offset>& imapp, const unsigned short* dataValues) const;
+ /*! \overload
+ */
+ void putVar_all(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const std::vector<MPI_Offset>& imapp, const unsigned int* dataValues) const;
+ /*! \overload
+ */
+ void putVar_all(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const std::vector<MPI_Offset>& imapp, const unsigned long long* dataValues) const;
+ /*!
+ Writes a mapped array section of values into the netCDF variable.
+ The mapped array section is specified by giving a corner, a vector of counts, a stride vector, and an index mapping vector.
+ The index mapping vector is a vector of integers that specifies the mapping between the dimensions of a netCDF variable and the in-memory structure of the internal data array.
+ No assumptions are made about the ordering or length of the dimensions of the data array.
+
+ \param countp Vector specifying the number of indices selected along each dimension.
+ To write a single value, for example, specify count as (1, 1, ... , 1). The elements of
+ count correspond, in order, to the variable's dimensions. Hence, if the variable is a record
+ variable, the first element of count corresponds to a count of the number of records to write. Note: setting any element
+ of the count array to zero causes the function to exit without error, and without doing anything.
+
+ \param stridep A vector of MPI_Offset integers that specifies the sampling interval along each dimension of the netCDF variable.
+ The elements of the stride vector correspond, in order, to the netCDF variable's dimensions (stride[0] gives the sampling interval
+ along the most slowly varying dimension of the netCDF variable). Sampling intervals are specified in type-independent units of
+ elements (a value of 1 selects consecutive elements of the netCDF variable along the corresponding dimension, a value of 2 selects
+ every other element, etc.). A NULL stride argument is treated as (1, 1, ... , 1).
+
+ \param imap Vector specifies the mapping between the dimensions of a netCDF variable and the in-memory structure of the internal data array.
+ The elements of the index mapping vector correspond, in order, to the netCDF variable's dimensions (imap[0] gives the distance between elements
+ of the internal array corresponding to the most slowly varying dimension of the netCDF variable). Distances between elements are
+ specified in type-independent units of elements (the distance between internal elements that occupy adjacent memory locations is
+ 1 and not the element's byte-length as in netCDF 2). A NULL argument means the memory-resident values have the same structure as
+ the associated netCDF variable.
+
+ \param dataValues The data values. The order in which the data will be written to the netCDF variable is with the last
+ dimension of the specified variable varying fastest. If the type of data values differs from the netCDF variable type, type conversion will occur.
+ (However, no type conversion is carried out for variables using the user-defined data types: ncmpi_Vlen, ncmpi_Opaque, ncmpi_Compound and ncmpi_Enum.)
+*/
+ void putVar_all(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const std::vector<MPI_Offset>& imapp, const long long* dataValues) const;
+
+ void putVar_all(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const std::vector<MPI_Offset>& imapp, const void* dataValues, MPI_Offset bufcount, MPI_Datatype buftype) const;
+
+ ////////////////////
+
+ // Writes a list of subarrays into the netCDF variable. (independent I/O APIs)
+ /*!
+ This is an overloaded member function, provided for convenience.
+ It differs from the above function in what argument(s) it accepts.
+ In addition, no data conversion is carried out. This means that
+ the type of the data in memory must match the type of the variable.
+ */
+ // void putVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], const void* dataValues) const;
+ /*! \overload
+ */
+ void putVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], const char* dataValues) const;
+ /*! \overload
+ */
+ void putVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], const unsigned char* dataValues) const;
+ /*! \overload
+ */
+ void putVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], const signed char* dataValues) const;
+ /*! \overload
+ */
+ void putVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], const short* dataValues) const;
+ /*! \overload
+ */
+ void putVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], const int* dataValues) const;
+ /*! \overload
+ */
+ void putVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], const long* dataValues) const;
+ /*! \overload
+ */
+ void putVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], const float* dataValues) const;
+ /*! \overload
+ */
+ void putVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], const double* dataValues) const;
+ /*! \overload
+ */
+ void putVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], const unsigned short* dataValues) const;
+ /*! \overload
+ */
+ void putVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], const unsigned int* dataValues) const;
+ /*! \overload
+ */
+ void putVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], const unsigned long long* dataValues) const;
+ /*!
+ Writes a list of subarrays into the netCDF variable.
+ Each subarray i is specified by giving a corner (starts[i][*]) and a vector of edge lengths (counts[i][*]).
+ The values to be written are associated with the netCDF variable by assuming that the last dimension of the netCDF variable varies fastest.
+
+ \param num
+ Number of subarrays.
+
+ \param starts
+ 2D array of size [num][ndims] where num is the number of subarrays to get and ndims if the number of dimensions of the specified variable.
+ Each subarray i is specified by starts[i][*], the first of the data values will be written, and counts[i][*], edge lengths of the subarray.
+ The indices are relative to 0, so for example, the first data value of a variable would have index (0, 0, ... , 0).
+ The length of the second dimension of starts and counts must be the same as the number of dimensions of the specified variable.
+ The elements of starts's second dimension correspond, in order, to the variable's dimensions. Hence, if the variable is a record variable,
+ the first element starts[*][0] would correspond to the starting record number for writing the data values.
+
+ \param counts
+ 2D array of size [num][ndims] where num is the number of subarrays to get and ndims if the number of dimensions of the specified variable.
+ To write a single value, for example, specify count as (1, 1, ... , 1). The length of each count[i] is the number of
+ dimensions of the specified variable. The elements of each count[i] correspond, in order, to the variable's dimensions.
+ Hence, if the variable is a record variable, the first element of count[i] corresponds to a count of the number of records to write.
+ Note: setting any element of the count array to zero causes the function to exit without error, and without doing anything.
+
+ \param dataValues Pointer to the location into which the data value is written. If the type of
+ data value differs from the netCDF variable type, type conversion will occur.
+ */
+ void putVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], const long long* dataValues) const;
+ void putVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], const void* dataValues, MPI_Offset bufcount, MPI_Datatype buftype) const;
+
+ ////////////////
+
+ // Writes an array of values into the netCDF variable. (collective I/O APIs)
+ /*!
+ This is an overloaded member function, provided for convenience.
+ It differs from the above function in what argument(s) it accepts.
+ In addition, no data conversion is carried out. This means that
+ the type of the data in memory must match the type of the variable.
+ */
+ // void putVarn_all(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], const void* dataValues) const;
+ /*! \overload
+ */
+ void putVarn_all(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], const char* dataValues) const;
+ /*! \overload
+ */
+ void putVarn_all(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], const unsigned char* dataValues) const;
+ /*! \overload
+ */
+ void putVarn_all(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], const signed char* dataValues) const;
+ /*! \overload
+ */
+ void putVarn_all(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], const short* dataValues) const;
+ /*! \overload
+ */
+ void putVarn_all(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], const int* dataValues) const;
+ /*! \overload
+ */
+ void putVarn_all(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], const long* dataValues) const;
+ /*! \overload
+ */
+ void putVarn_all(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], const float* dataValues) const;
+ /*! \overload
+ */
+ void putVarn_all(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], const double* dataValues) const;
+ /*! \overload
+ */
+ void putVarn_all(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], const unsigned short* dataValues) const;
+ /*! \overload
+ */
+ void putVarn_all(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], const unsigned int* dataValues) const;
+ /*! \overload
+ */
+ void putVarn_all(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], const unsigned long long* dataValues) const;
+ /*!
+ Writes an array of values into the netCDF variable.
+ The portion of the netCDF variable to write is specified by giving a corner and a vector of edge lengths
+ that refer to an array section of the netCDF variable. The values to be written are associated with
+ the netCDF variable by assuming that the last dimension of the netCDF variable varies fastest.
+
+ \param startp Vector specifying the index where the first data values will be written. The indices are relative to 0, so for
+ example, the first data value of a variable would have index (0, 0, ... , 0). The elements of start correspond, in order, to the
+ variable's dimensions. Hence, if the variable is a record variable, the first index corresponds to the starting record number for writing the data values.
+
+ \param countp Vector specifying the number of indices selected along each dimension.
+ To write a single value, for example, specify count as (1, 1, ... , 1). The elements of
+ count correspond, in order, to the variable's dimensions. Hence, if the variable is a record
+ variable, the first element of count corresponds to a count of the number of records to write. Note: setting any element
+ of the count array to zero causes the function to exit without error, and without doing anything.
+
+ \param dataValues The data values. The order in which the data will be written to the netCDF variable is with the last
+ dimension of the specified variable varying fastest. If the type of data values differs from the netCDF variable
+ type, type conversion will occur. (However, no type conversion is
+ carried out for variables using the user-defined data types:
+ ncmpi_Vlen, ncmpi_Opaque, ncmpi_Compound and ncmpi_Enum.)
+ */
+ void putVarn_all(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], const long long* dataValues) const;
+ void putVarn_all(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], const void* dataValues, MPI_Offset bufcount, MPI_Datatype buftype) const;
+
+ /* vard APIs take filetype and buftype */
+ void putVard (MPI_Datatype filetype, const void* dataValues, MPI_Offset bufcount, MPI_Datatype buftype) const;
+ void putVard_all(MPI_Datatype filetype, const void* dataValues, MPI_Offset bufcount, MPI_Datatype buftype) const;
+
+ ////////////////
+
+ // Nonblocking data writing
+
+ ////////////////////
+
+
+ // Writes the entire data into the netCDF variable.
+ /*!
+ This is an overloaded member function, provided for convenience.
+ It differs from the above function in what argument(s) it accepts.
+ In addition, no data conversion is carried out. This means that
+ the type of the data in memory must match the type of the variable.
+ */
+ // void iputVar(const void* dataValues, int *req) const;
+ /*! \overload
+ */
+ void iputVar(const char* dataValues, int *req) const;
+ /*! \overload
+ */
+ void iputVar(const unsigned char* dataValues, int *req) const;
+ /*! \overload
+ */
+ void iputVar(const signed char* dataValues, int *req) const;
+ /*! \overload
+ */
+ void iputVar(const short* dataValues, int *req) const;
+ /*! \overload
+ */
+ void iputVar(const int* dataValues, int *req) const;
+ /*! \overload
+ */
+ void iputVar(const long* dataValues, int *req) const;
+ /*! \overload
+ */
+ void iputVar(const float* dataValues, int *req) const;
+ /*! \overload
+ */
+ void iputVar(const double* dataValues, int *req) const;
+ /*! \overload
+ */
+ void iputVar(const unsigned short* dataValues, int *req) const;
+ /*! \overload
+ */
+ void iputVar(const unsigned int* dataValues, int *req) const;
+ /*! \overload
+ */
+ void iputVar(const unsigned long long* dataValues, int *req) const;
+ /*!
+ Writes the entire data into the netCDF variable.
+ This is the simplest interface to use for writing a value in a scalar variable
+ or whenever all the values of a multidimensional variable can all be
+ written at once. The values to be written are associated with the
+ netCDF variable by assuming that the last dimension of the netCDF
+ variable varies fastest in the C interface.
+
+ Take care when using the simplest forms of this interface with
+ record variables when you don't specify how many records are to be
+ written. If you try to write all the values of a record variable
+ into a netCDF file that has no record data yet (hence has 0 records),
+ nothing will be written. Similarly, if you try to write all of a record
+ variable but there are more records in the file than you assume, more data
+ may be written to the file than you supply, which may result in a
+ segmentation violation.
+
+ \param dataValues The data values. The order in which the data will be written to the netCDF variable is with the last
+ dimension of the specified variable varying fastest. If the type of data values differs from the netCDF variable type, type conversion will occur.
+ (However, no type conversion is carried out for variables using the user-defined data types:
+ ncmpi_Vlen, ncmpi_Opaque, ncmpi_Compound and ncmpi_Enum.)
+ */
+ void iputVar(const long long* dataValues, int *req) const;
+
+ void iputVar(const void* dataValues, MPI_Offset bufcount, MPI_Datatype buftype, int *req) const;
+
+ /////////////////////////
+
+ // Writes a single datum into the netCDF variable.
+ /*!
+ This is an overloaded member function, provided for convenience.
+ It differs from the above function in what argument(s) it accepts.
+ In addition, no data conversion is carried out. This means that
+ the type of the data in memory must match the type of the variable.
+ */
+ // void iputVar(const std::vector<MPI_Offset>& index, const void* dataumValue, int *req) const;
+ /*! \overload
+ */
+ void iputVar(const std::vector<MPI_Offset>& index, const std::string& dataumValue, int *req) const;
+ /*! \overload
+ */
+ void iputVar(const std::vector<MPI_Offset>& index, const unsigned char* dataumValue, int *req) const;
+ /*! \overload
+ */
+ void iputVar(const std::vector<MPI_Offset>& index, const signed char* dataumValue, int *req) const;
+ /*! \overload
+ */
+ void iputVar(const std::vector<MPI_Offset>& index, const short dataumValue, int *req) const;
+ /*! \overload
+ */
+ void iputVar(const std::vector<MPI_Offset>& index, const int dataumValue, int *req) const;
+ /*! \overload
+ */
+ void iputVar(const std::vector<MPI_Offset>& index, const long dataumValue, int *req) const;
+ /*! \overload
+ */
+ void iputVar(const std::vector<MPI_Offset>& index, const float dataumValue, int *req) const;
+ /*! \overload
+ */
+ void iputVar(const std::vector<MPI_Offset>& index, const double dataumValue, int *req) const;
+ /*! \overload
+ */
+ void iputVar(const std::vector<MPI_Offset>& index, const unsigned short dataumValue, int *req) const;
+ /*! \overload
+ */
+ void iputVar(const std::vector<MPI_Offset>& index, const unsigned int dataumValue, int *req) const;
+ /*! \overload
+ */
+ void iputVar(const std::vector<MPI_Offset>& index, const unsigned long long dataumValue, int *req) const;
+ /*!
+ Writes a single datum into the netCDF variable.
+
+ \param index Vector specifying the index where the data values will be written. The indices are relative to 0, so for example,
+ the first data value of a two-dimensional variable would have index (0,0). The elements of index must correspond to the variable's dimensions.
+ Hence, if the variable uses the unlimited dimension, the first index would correspond to the unlimited dimension.
+
+ \param datumValue The data value. If the type of data values differs from the netCDF variable type, type conversion will occur.
+ (However, no type conversion is carried out for variables using the user-defined data types:
+ ncmpi_Vlen, ncmpi_Opaque, ncmpi_Compound and ncmpi_Enum.)
+ */
+ void iputVar(const std::vector<MPI_Offset>& index, const long long dataumValue, int *req) const;
+
+ void iputVar(const std::vector<MPI_Offset>& index, const void* dataumValue, MPI_Offset bufcount, MPI_Datatype buftype, int *req) const;
+
+ /////////////////////////
+
+ // Writes an array of values into the netCDF variable.
+ /*!
+ This is an overloaded member function, provided for convenience.
+ It differs from the above function in what argument(s) it accepts.
+ In addition, no data conversion is carried out. This means that
+ the type of the data in memory must match the type of the variable.
+ */
+ // void iputVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const void* dataValues, int *req) const;
+ /*! \overload
+ */
+ void iputVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const char* dataValues, int *req) const;
+ /*! \overload
+ */
+ void iputVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const unsigned char* dataValues, int *req) const;
+ /*! \overload
+ */
+ void iputVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const signed char* dataValues, int *req) const;
+ /*! \overload
+ */
+ void iputVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const short* dataValues, int *req) const;
+ /*! \overload
+ */
+ void iputVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const int* dataValues, int *req) const;
+ /*! \overload
+ */
+ void iputVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const long* dataValues, int *req) const;
+ /*! \overload
+ */
+ void iputVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const float* dataValues, int *req) const;
+ /*! \overload
+ */
+ void iputVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const double* dataValues, int *req) const;
+ /*! \overload
+ */
+ void iputVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const unsigned short* dataValues, int *req) const;
+ /*! \overload
+ */
+ void iputVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const unsigned int* dataValues, int *req) const;
+ /*! \overload
+ */
+ void iputVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const unsigned long long* dataValues, int *req) const;
+ /*!
+ Writes an array of values into the netCDF variable.
+ The portion of the netCDF variable to write is specified by giving a corner and a vector of edge lengths
+ that refer to an array section of the netCDF variable. The values to be written are associated with
+ the netCDF variable by assuming that the last dimension of the netCDF variable varies fastest.
+
+ \param startp Vector specifying the index where the first data values will be written. The indices are relative to 0, so for
+ example, the first data value of a variable would have index (0, 0, ... , 0). The elements of start correspond, in order, to the
+ variable's dimensions. Hence, if the variable is a record variable, the first index corresponds to the starting record number for writing the data values.
+
+ \param countp Vector specifying the number of indices selected along each dimension.
+ To write a single value, for example, specify count as (1, 1, ... , 1). The elements of
+ count correspond, in order, to the variable's dimensions. Hence, if the variable is a record
+ variable, the first element of count corresponds to a count of the number of records to write. Note: setting any element
+ of the count array to zero causes the function to exit without error, and without doing anything.
+
+ \param dataValues The data values. The order in which the data will be written to the netCDF variable is with the last
+ dimension of the specified variable varying fastest. If the type of data values differs from the netCDF variable
+ type, type conversion will occur. (However, no type conversion is
+ carried out for variables using the user-defined data types:
+ ncmpi_Vlen, ncmpi_Opaque, ncmpi_Compound and ncmpi_Enum.)
+ */
+ void iputVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const long long* dataValues, int *req) const;
+ void iputVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const void* dataValues, MPI_Offset bufcount, MPI_Datatype buftype, int *req) const;
+
+ ////////////////
+
+ // Writes a set of subsampled array values into the netCDF variable.
+ /*!
+ This is an overloaded member function, provided for convenience.
+ It differs from the above function in what argument(s) it accepts.
+ In addition, no data conversion is carried out. This means that
+ the type of the data in memory must match the type of the variable.
+ */
+ // void iputVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const void* dataValues, int *req) const;
+ /*! \overload
+ */
+ void iputVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const char* dataValues, int *req) const;
+ /*! \overload
+ */
+ void iputVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const unsigned char* dataValues, int *req) const;
+ /*! \overload
+ */
+ void iputVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const signed char* dataValues, int *req) const;
+ /*! \overload
+ */
+ void iputVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const short* dataValues, int *req) const;
+ /*! \overload
+ */
+ void iputVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const int* dataValues, int *req) const;
+ /*! \overload
+ */
+ void iputVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const long* dataValues, int *req) const;
+ /*! \overload
+ */
+ void iputVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const float* dataValues, int *req) const;
+ /*! \overload
+ */
+ void iputVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const double* dataValues, int *req) const;
+ /*! \overload
+ */
+ void iputVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const unsigned short* dataValues, int *req) const;
+ /*! \overload
+ */
+ void iputVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const unsigned int* dataValues, int *req) const;
+ /*! \overload
+ */
+ void iputVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const unsigned long long* dataValues, int *req) const;
+ /*!
+ Writes an array of values into the netCDF variable.
+ The subsampled array section is specified by giving a corner, a vector of counts, and a stride vector.
+
+ \param startp Vector specifying the index where the first data values will be written. The indices are relative to 0, so for
+ example, the first data value of a variable would have index (0, 0, ... , 0). The elements of start correspond, in order, to the
+ variable's dimensions. Hence, if the variable is a record variable, the first index corresponds to the starting record number for writing the data values.
+
+ \param countp Vector specifying the number of indices selected along each dimension.
+ To write a single value, for example, specify count as (1, 1, ... , 1). The elements of
+ count correspond, in order, to the variable's dimensions. Hence, if the variable is a record
+ variable, the first element of count corresponds to a count of the number of records to write. Note: setting any element
+ of the count array to zero causes the function to exit without error, and without doing anything.
+
+ \param stridep A vector of MPI_Offset integers that specifies the sampling interval along each dimension of the netCDF variable.
+ The elements of the stride vector correspond, in order, to the netCDF variable's dimensions (stride[0] gives the sampling interval
+ along the most slowly varying dimension of the netCDF variable). Sampling intervals are specified in type-independent units of
+ elements (a value of 1 selects consecutive elements of the netCDF variable along the corresponding dimension, a value of 2 selects
+ every other element, etc.). A NULL stride argument is treated as (1, 1, ... , 1).
+
+ \param dataValues The data values. The order in which the data will be written to the netCDF variable is with the last
+ dimension of the specified variable varying fastest. If the type of data values differs from the netCDF variable type, type conversion will occur.
+ (However, no type conversion is carried out for variables using the user-defined data types: ncmpi_Vlen, ncmpi_Opaque, ncmpi_Compound and ncmpi_Enum.
+ */
+ void iputVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const long long* dataValues, int *req) const;
+
+ void iputVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const void* dataValues, MPI_Offset bufcount, MPI_Datatype buftype, int *req) const;
+
+ ////////////////
+
+ // Writes a mapped array section of values into the netCDF variable.
+ /*!
+ This is an overloaded member function, provided for convenience.
+ It differs from the above function in what argument(s) it accepts.
+ In addition, no data conversion is carried out. This means that
+ the type of the data in memory must match the type of the variable.
+ */
+ // void iputVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const std::vector<MPI_Offset>& imapp, const void* dataValues, int *req) const;
+ /*! \overload
+ */
+ void iputVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const std::vector<MPI_Offset>& imapp, const char* dataValues, int *req) const;
+ /*! \overload
+ */
+ void iputVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const std::vector<MPI_Offset>& imapp, const unsigned char* dataValues, int *req) const;
+ /*! \overload
+ */
+ void iputVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const std::vector<MPI_Offset>& imapp, const signed char* dataValues, int *req) const;
+ /*! \overload
+ */
+ void iputVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const std::vector<MPI_Offset>& imapp, const short* dataValues, int *req) const;
+ /*! \overload
+ */
+ void iputVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const std::vector<MPI_Offset>& imapp, const int* dataValues, int *req) const;
+ /*! \overload
+ */
+ void iputVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const std::vector<MPI_Offset>& imapp, const long* dataValues, int *req) const;
+ /*! \overload
+ */
+ void iputVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const std::vector<MPI_Offset>& imapp, const float* dataValues, int *req) const;
+ /*! \overload
+ */
+ void iputVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const std::vector<MPI_Offset>& imapp, const double* dataValues, int *req) const;
+ /*! \overload
+ */
+ void iputVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const std::vector<MPI_Offset>& imapp, const unsigned short* dataValues, int *req) const;
+ /*! \overload
+ */
+ void iputVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const std::vector<MPI_Offset>& imapp, const unsigned int* dataValues, int *req) const;
+ /*! \overload
+ */
+ void iputVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const std::vector<MPI_Offset>& imapp, const unsigned long long* dataValues, int *req) const;
+ /*!
+ Writes a mapped array section of values into the netCDF variable.
+ The mapped array section is specified by giving a corner, a vector of counts, a stride vector, and an index mapping vector.
+ The index mapping vector is a vector of integers that specifies the mapping between the dimensions of a netCDF variable and the in-memory structure of the internal data array.
+ No assumptions are made about the ordering or length of the dimensions of the data array.
+
+ \param countp Vector specifying the number of indices selected along each dimension.
+ To write a single value, for example, specify count as (1, 1, ... , 1). The elements of
+ count correspond, in order, to the variable's dimensions. Hence, if the variable is a record
+ variable, the first element of count corresponds to a count of the number of records to write. Note: setting any element
+ of the count array to zero causes the function to exit without error, and without doing anything.
+
+ \param stridep A vector of MPI_Offset integers that specifies the sampling interval along each dimension of the netCDF variable.
+ The elements of the stride vector correspond, in order, to the netCDF variable's dimensions (stride[0] gives the sampling interval
+ along the most slowly varying dimension of the netCDF variable). Sampling intervals are specified in type-independent units of
+ elements (a value of 1 selects consecutive elements of the netCDF variable along the corresponding dimension, a value of 2 selects
+ every other element, etc.). A NULL stride argument is treated as (1, 1, ... , 1).
+
+ \param imap Vector specifies the mapping between the dimensions of a netCDF variable and the in-memory structure of the internal data array.
+ The elements of the index mapping vector correspond, in order, to the netCDF variable's dimensions (imap[0] gives the distance between elements
+ of the internal array corresponding to the most slowly varying dimension of the netCDF variable). Distances between elements are
+ specified in type-independent units of elements (the distance between internal elements that occupy adjacent memory locations is
+ 1 and not the element's byte-length as in netCDF 2). A NULL argument means the memory-resident values have the same structure as
+ the associated netCDF variable.
+
+ \param dataValues The data values. The order in which the data will be written to the netCDF variable is with the last
+ dimension of the specified variable varying fastest. If the type of data values differs from the netCDF variable type, type conversion will occur.
+ (However, no type conversion is carried out for variables using the user-defined data types: ncmpi_Vlen, ncmpi_Opaque, ncmpi_Compound and ncmpi_Enum.)
+*/
+ void iputVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const std::vector<MPI_Offset>& imapp, const long long* dataValues, int *req) const;
+
+ void iputVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const std::vector<MPI_Offset>& imapp, const void* dataValues, MPI_Offset bufcount, MPI_Datatype buftype, int *req) const;
+
+ ////////////////////
+
+ // Writes a list of subarrays into the netCDF variable. (independent I/O APIs)
+ /*!
+ This is an overloaded member function, provided for convenience.
+ It differs from the above function in what argument(s) it accepts.
+ In addition, no data conversion is carried out. This means that
+ the type of the data in memory must match the type of the variable.
+ */
+ // void putVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], const void* dataValues) const;
+ /*! \overload
+ */
+ void iputVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], const char* dataValues, int *req) const;
+ /*! \overload
+ */
+ void iputVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], const unsigned char* dataValues, int *req) const;
+ /*! \overload
+ */
+ void iputVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], const signed char* dataValues, int *req) const;
+ /*! \overload
+ */
+ void iputVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], const short* dataValues, int *req) const;
+ /*! \overload
+ */
+ void iputVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], const int* dataValues, int *req) const;
+ /*! \overload
+ */
+ void iputVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], const long* dataValues, int *req) const;
+ /*! \overload
+ */
+ void iputVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], const float* dataValues, int *req) const;
+ /*! \overload
+ */
+ void iputVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], const double* dataValues, int *req) const;
+ /*! \overload
+ */
+ void iputVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], const unsigned short* dataValues, int *req) const;
+ /*! \overload
+ */
+ void iputVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], const unsigned int* dataValues, int *req) const;
+ /*! \overload
+ */
+ void iputVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], const unsigned long long* dataValues, int *req) const;
+ /*!
+ Writes a list of subarrays into the netCDF variable.
+ Each subarray i is specified by giving a corner (starts[i][*]) and a vector of edge lengths (counts[i][*]).
+ The values to be written are associated with the netCDF variable by assuming that the last dimension of the netCDF variable varies fastest.
+
+ \param num
+ Number of subarrays.
+
+ \param starts
+ 2D array of size [num][ndims] where num is the number of subarrays to get and ndims if the number of dimensions of the specified variable.
+ Each subarray i is specified by starts[i][*], the first of the data values will be written, and counts[i][*], edge lengths of the subarray.
+ The indices are relative to 0, so for example, the first data value of a variable would have index (0, 0, ... , 0).
+ The length of the second dimension of starts and counts must be the same as the number of dimensions of the specified variable.
+ The elements of starts's second dimension correspond, in order, to the variable's dimensions. Hence, if the variable is a record variable,
+ the first element starts[*][0] would correspond to the starting record number for writing the data values.
+
+ \param counts
+ 2D array of size [num][ndims] where num is the number of subarrays to get and ndims if the number of dimensions of the specified variable.
+ To write a single value, for example, specify count as (1, 1, ... , 1). The length of each count[i] is the number of
+ dimensions of the specified variable. The elements of each count[i] correspond, in order, to the variable's dimensions.
+ Hence, if the variable is a record variable, the first element of count[i] corresponds to a count of the number of records to write.
+ Note: setting any element of the count array to zero causes the function to exit without error, and without doing anything.
+
+ \param dataValues Pointer to the location into which the data value is written. If the type of
+ data value differs from the netCDF variable type, type conversion will occur.
+ */
+ void iputVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], const long long* dataValues, int *req) const;
+ void iputVarn(const int num, MPI_Offset* const starts[], MPI_Offset* const counts[], const void* dataValues, MPI_Offset bufcount, MPI_Datatype buftype, int *req) const;
+
+ ////////////////////
+
+ // Buffered nonblocking data writing
+
+ ////////////////////
+
+ // Writes the entire data into the netCDF variable.
+ /*!
+ This is an overloaded member function, provided for convenience.
+ It differs from the above function in what argument(s) it accepts.
+ In addition, no data conversion is carried out. This means that
+ the type of the data in memory must match the type of the variable.
+ */
+ // void bputVar(const void* dataValues, int *req) const;
+ /*! \overload
+ */
+ void bputVar(const char* dataValues, int *req) const;
+ /*! \overload
+ */
+ void bputVar(const unsigned char* dataValues, int *req) const;
+ /*! \overload
+ */
+ void bputVar(const signed char* dataValues, int *req) const;
+ /*! \overload
+ */
+ void bputVar(const short* dataValues, int *req) const;
+ /*! \overload
+ */
+ void bputVar(const int* dataValues, int *req) const;
+ /*! \overload
+ */
+ void bputVar(const long* dataValues, int *req) const;
+ /*! \overload
+ */
+ void bputVar(const float* dataValues, int *req) const;
+ /*! \overload
+ */
+ void bputVar(const double* dataValues, int *req) const;
+ /*! \overload
+ */
+ void bputVar(const unsigned short* dataValues, int *req) const;
+ /*! \overload
+ */
+ void bputVar(const unsigned int* dataValues, int *req) const;
+ /*! \overload
+ */
+ void bputVar(const unsigned long long* dataValues, int *req) const;
+ /*!
+ Writes the entire data into the netCDF variable.
+ This is the simplest interface to use for writing a value in a scalar variable
+ or whenever all the values of a multidimensional variable can all be
+ written at once. The values to be written are associated with the
+ netCDF variable by assuming that the last dimension of the netCDF
+ variable varies fastest in the C interface.
+
+ Take care when using the simplest forms of this interface with
+ record variables when you don't specify how many records are to be
+ written. If you try to write all the values of a record variable
+ into a netCDF file that has no record data yet (hence has 0 records),
+ nothing will be written. Similarly, if you try to write all of a record
+ variable but there are more records in the file than you assume, more data
+ may be written to the file than you supply, which may result in a
+ segmentation violation.
+
+ \param dataValues The data values. The order in which the data will be written to the netCDF variable is with the last
+ dimension of the specified variable varying fastest. If the type of data values differs from the netCDF variable type, type conversion will occur.
+ (However, no type conversion is carried out for variables using the user-defined data types:
+ ncmpi_Vlen, ncmpi_Opaque, ncmpi_Compound and ncmpi_Enum.)
+ */
+ void bputVar(const long long* dataValues, int *req) const;
+
+ void bputVar(const void* dataValues, MPI_Offset bufcount, MPI_Datatype buftype, int *req) const;
+
+ /////////////////////////
+
+ // Writes a single datum into the netCDF variable.
+ /*!
+ This is an overloaded member function, provided for convenience.
+ It differs from the above function in what argument(s) it accepts.
+ In addition, no data conversion is carried out. This means that
+ the type of the data in memory must match the type of the variable.
+ */
+ // void bputVar(const std::vector<MPI_Offset>& index, const void* dataumValue, int *req) const;
+ /*! \overload
+ */
+ void bputVar(const std::vector<MPI_Offset>& index, const std::string& dataumValue, int *req) const;
+ /*! \overload
+ */
+ void bputVar(const std::vector<MPI_Offset>& index, const unsigned char* dataumValue, int *req) const;
+ /*! \overload
+ */
+ void bputVar(const std::vector<MPI_Offset>& index, const signed char* dataumValue, int *req) const;
+ /*! \overload
+ */
+ void bputVar(const std::vector<MPI_Offset>& index, const short dataumValue, int *req) const;
+ /*! \overload
+ */
+ void bputVar(const std::vector<MPI_Offset>& index, const int dataumValue, int *req) const;
+ /*! \overload
+ */
+ void bputVar(const std::vector<MPI_Offset>& index, const long dataumValue, int *req) const;
+ /*! \overload
+ */
+ void bputVar(const std::vector<MPI_Offset>& index, const float dataumValue, int *req) const;
+ /*! \overload
+ */
+ void bputVar(const std::vector<MPI_Offset>& index, const double dataumValue, int *req) const;
+ /*! \overload
+ */
+ void bputVar(const std::vector<MPI_Offset>& index, const unsigned short dataumValue, int *req) const;
+ /*! \overload
+ */
+ void bputVar(const std::vector<MPI_Offset>& index, const unsigned int dataumValue, int *req) const;
+ /*! \overload
+ */
+ void bputVar(const std::vector<MPI_Offset>& index, const unsigned long long dataumValue, int *req) const;
+ /*!
+ Writes a single datum into the netCDF variable.
+
+ \param index Vector specifying the index where the data values will be written. The indices are relative to 0, so for example,
+ the first data value of a two-dimensional variable would have index (0,0). The elements of index must correspond to the variable's dimensions.
+ Hence, if the variable uses the unlimited dimension, the first index would correspond to the unlimited dimension.
+
+ \param datumValue The data value. If the type of data values differs from the netCDF variable type, type conversion will occur.
+ (However, no type conversion is carried out for variables using the user-defined data types:
+ ncmpi_Vlen, ncmpi_Opaque, ncmpi_Compound and ncmpi_Enum.)
+ */
+ void bputVar(const std::vector<MPI_Offset>& index, const long long dataumValue, int *req) const;
+
+ void bputVar(const std::vector<MPI_Offset>& index, const void* dataumValue, MPI_Offset bufcount, MPI_Datatype buftype, int *req) const;
+
+ /////////////////////////
+
+ // Writes an array of values into the netCDF variable.
+ /*!
+ This is an overloaded member function, provided for convenience.
+ It differs from the above function in what argument(s) it accepts.
+ In addition, no data conversion is carried out. This means that
+ the type of the data in memory must match the type of the variable.
+ */
+ // void bputVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const void* dataValues, int *req) const;
+ /*! \overload
+ */
+ void bputVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const char* dataValues, int *req) const;
+ /*! \overload
+ */
+ void bputVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const unsigned char* dataValues, int *req) const;
+ /*! \overload
+ */
+ void bputVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const signed char* dataValues, int *req) const;
+ /*! \overload
+ */
+ void bputVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const short* dataValues, int *req) const;
+ /*! \overload
+ */
+ void bputVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const int* dataValues, int *req) const;
+ /*! \overload
+ */
+ void bputVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const long* dataValues, int *req) const;
+ /*! \overload
+ */
+ void bputVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const float* dataValues, int *req) const;
+ /*! \overload
+ */
+ void bputVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const double* dataValues, int *req) const;
+ /*! \overload
+ */
+ void bputVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const unsigned short* dataValues, int *req) const;
+ /*! \overload
+ */
+ void bputVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const unsigned int* dataValues, int *req) const;
+ /*! \overload
+ */
+ void bputVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const unsigned long long* dataValues, int *req) const;
+ /*!
+ Writes an array of values into the netCDF variable.
+ The portion of the netCDF variable to write is specified by giving a corner and a vector of edge lengths
+ that refer to an array section of the netCDF variable. The values to be written are associated with
+ the netCDF variable by assuming that the last dimension of the netCDF variable varies fastest.
+
+ \param startp Vector specifying the index where the first data values will be written. The indices are relative to 0, so for
+ example, the first data value of a variable would have index (0, 0, ... , 0). The elements of start correspond, in order, to the
+ variable's dimensions. Hence, if the variable is a record variable, the first index corresponds to the starting record number for writing the data values.
+
+ \param countp Vector specifying the number of indices selected along each dimension.
+ To write a single value, for example, specify count as (1, 1, ... , 1). The elements of
+ count correspond, in order, to the variable's dimensions. Hence, if the variable is a record
+ variable, the first element of count corresponds to a count of the number of records to write. Note: setting any element
+ of the count array to zero causes the function to exit without error, and without doing anything.
+
+ \param dataValues The data values. The order in which the data will be written to the netCDF variable is with the last
+ dimension of the specified variable varying fastest. If the type of data values differs from the netCDF variable
+ type, type conversion will occur. (However, no type conversion is
+ carried out for variables using the user-defined data types:
+ ncmpi_Vlen, ncmpi_Opaque, ncmpi_Compound and ncmpi_Enum.)
+ */
+ void bputVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const long long* dataValues, int *req) const;
+ void bputVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const void* dataValues, MPI_Offset bufcount, MPI_Datatype buftype, int *req) const;
+
+ ////////////////
+
+ // Writes a set of subsampled array values into the netCDF variable.
+ /*!
+ This is an overloaded member function, provided for convenience.
+ It differs from the above function in what argument(s) it accepts.
+ In addition, no data conversion is carried out. This means that
+ the type of the data in memory must match the type of the variable.
+ */
+ // void bputVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const void* dataValues, int *req) const;
+ /*! \overload
+ */
+ void bputVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const char* dataValues, int *req) const;
+ /*! \overload
+ */
+ void bputVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const unsigned char* dataValues, int *req) const;
+ /*! \overload
+ */
+ void bputVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const signed char* dataValues, int *req) const;
+ /*! \overload
+ */
+ void bputVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const short* dataValues, int *req) const;
+ /*! \overload
+ */
+ void bputVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const int* dataValues, int *req) const;
+ /*! \overload
+ */
+ void bputVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const long* dataValues, int *req) const;
+ /*! \overload
+ */
+ void bputVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const float* dataValues, int *req) const;
+ /*! \overload
+ */
+ void bputVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const double* dataValues, int *req) const;
+ /*! \overload
+ */
+ void bputVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const unsigned short* dataValues, int *req) const;
+ /*! \overload
+ */
+ void bputVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const unsigned int* dataValues, int *req) const;
+ /*! \overload
+ */
+ void bputVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const unsigned long long* dataValues, int *req) const;
+ /*!
+ Writes an array of values into the netCDF variable.
+ The subsampled array section is specified by giving a corner, a vector of counts, and a stride vector.
+
+ \param startp Vector specifying the index where the first data values will be written. The indices are relative to 0, so for
+ example, the first data value of a variable would have index (0, 0, ... , 0). The elements of start correspond, in order, to the
+ variable's dimensions. Hence, if the variable is a record variable, the first index corresponds to the starting record number for writing the data values.
+
+ \param countp Vector specifying the number of indices selected along each dimension.
+ To write a single value, for example, specify count as (1, 1, ... , 1). The elements of
+ count correspond, in order, to the variable's dimensions. Hence, if the variable is a record
+ variable, the first element of count corresponds to a count of the number of records to write. Note: setting any element
+ of the count array to zero causes the function to exit without error, and without doing anything.
+
+ \param stridep A vector of MPI_Offset integers that specifies the sampling interval along each dimension of the netCDF variable.
+ The elements of the stride vector correspond, in order, to the netCDF variable's dimensions (stride[0] gives the sampling interval
+ along the most slowly varying dimension of the netCDF variable). Sampling intervals are specified in type-independent units of
+ elements (a value of 1 selects consecutive elements of the netCDF variable along the corresponding dimension, a value of 2 selects
+ every other element, etc.). A NULL stride argument is treated as (1, 1, ... , 1).
+
+ \param dataValues The data values. The order in which the data will be written to the netCDF variable is with the last
+ dimension of the specified variable varying fastest. If the type of data values differs from the netCDF variable type, type conversion will occur.
+ (However, no type conversion is carried out for variables using the user-defined data types: ncmpi_Vlen, ncmpi_Opaque, ncmpi_Compound and ncmpi_Enum.
+ */
+ void bputVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const long long* dataValues, int *req) const;
+
+ void bputVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const void* dataValues, MPI_Offset bufcount, MPI_Datatype buftype, int *req) const;
+
+ ////////////////
+
+ // Writes a mapped array section of values into the netCDF variable.
+ /*!
+ This is an overloaded member function, provided for convenience.
+ It differs from the above function in what argument(s) it accepts.
+ In addition, no data conversion is carried out. This means that
+ the type of the data in memory must match the type of the variable.
+ */
+ // void bputVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const std::vector<MPI_Offset>& imapp, const void* dataValues, int *req) const;
+ /*! \overload
+ */
+ void bputVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const std::vector<MPI_Offset>& imapp, const char* dataValues, int *req) const;
+ /*! \overload
+ */
+ void bputVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const std::vector<MPI_Offset>& imapp, const unsigned char* dataValues, int *req) const;
+ /*! \overload
+ */
+ void bputVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const std::vector<MPI_Offset>& imapp, const signed char* dataValues, int *req) const;
+ /*! \overload
+ */
+ void bputVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const std::vector<MPI_Offset>& imapp, const short* dataValues, int *req) const;
+ /*! \overload
+ */
+ void bputVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const std::vector<MPI_Offset>& imapp, const int* dataValues, int *req) const;
+ /*! \overload
+ */
+ void bputVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const std::vector<MPI_Offset>& imapp, const long* dataValues, int *req) const;
+ /*! \overload
+ */
+ void bputVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const std::vector<MPI_Offset>& imapp, const float* dataValues, int *req) const;
+ /*! \overload
+ */
+ void bputVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const std::vector<MPI_Offset>& imapp, const double* dataValues, int *req) const;
+ /*! \overload
+ */
+ void bputVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const std::vector<MPI_Offset>& imapp, const unsigned short* dataValues, int *req) const;
+ /*! \overload
+ */
+ void bputVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const std::vector<MPI_Offset>& imapp, const unsigned int* dataValues, int *req) const;
+ /*! \overload
+ */
+ void bputVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const std::vector<MPI_Offset>& imapp, const unsigned long long* dataValues, int *req) const;
+ /*!
+ Writes a mapped array section of values into the netCDF variable.
+ The mapped array section is specified by giving a corner, a vector of counts, a stride vector, and an index mapping vector.
+ The index mapping vector is a vector of integers that specifies the mapping between the dimensions of a netCDF variable and the in-memory structure of the internal data array.
+ No assumptions are made about the ordering or length of the dimensions of the data array.
+
+ \param countp Vector specifying the number of indices selected along each dimension.
+ To write a single value, for example, specify count as (1, 1, ... , 1). The elements of
+ count correspond, in order, to the variable's dimensions. Hence, if the variable is a record
+ variable, the first element of count corresponds to a count of the number of records to write. Note: setting any element
+ of the count array to zero causes the function to exit without error, and without doing anything.
+
+ \param stridep A vector of MPI_Offset integers that specifies the sampling interval along each dimension of the netCDF variable.
+ The elements of the stride vector correspond, in order, to the netCDF variable's dimensions (stride[0] gives the sampling interval
+ along the most slowly varying dimension of the netCDF variable). Sampling intervals are specified in type-independent units of
+ elements (a value of 1 selects consecutive elements of the netCDF variable along the corresponding dimension, a value of 2 selects
+ every other element, etc.). A NULL stride argument is treated as (1, 1, ... , 1).
+
+ \param imap Vector specifies the mapping between the dimensions of a netCDF variable and the in-memory structure of the internal data array.
+ The elements of the index mapping vector correspond, in order, to the netCDF variable's dimensions (imap[0] gives the distance between elements
+ of the internal array corresponding to the most slowly varying dimension of the netCDF variable). Distances between elements are
+ specified in type-independent units of elements (the distance between internal elements that occupy adjacent memory locations is
+ 1 and not the element's byte-length as in netCDF 2). A NULL argument means the memory-resident values have the same structure as
+ the associated netCDF variable.
+
+ \param dataValues The data values. The order in which the data will be written to the netCDF variable is with the last
+ dimension of the specified variable varying fastest. If the type of data values differs from the netCDF variable type, type conversion will occur.
+ (However, no type conversion is carried out for variables using the user-defined data types: ncmpi_Vlen, ncmpi_Opaque, ncmpi_Compound and ncmpi_Enum.)
+*/
+ void bputVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const std::vector<MPI_Offset>& imapp, const long long* dataValues, int *req) const;
+
+ void bputVar(const std::vector<MPI_Offset>& startp, const std::vector<MPI_Offset>& countp, const std::vector<MPI_Offset>& stridep, const std::vector<MPI_Offset>& imapp, const void* dataValues, MPI_Offset bufcount, MPI_Datatype buftype, int *req) const;
+
+ void Inq_file_offset(MPI_Offset *offset);
+
+ private:
+
+ bool nullObject;
+
+ int myId;
+
+ int groupId;
+
+ };
+
+
+}
+
+
+
+#endif
+
diff --git a/src/libcxx/ncmpiVarAtt.cpp b/src/libcxx/ncmpiVarAtt.cpp
new file mode 100644
index 0000000..902a782
--- /dev/null
+++ b/src/libcxx/ncmpiVarAtt.cpp
@@ -0,0 +1,63 @@
+#include "ncmpiVar.h"
+#include "ncmpiVarAtt.h"
+#include "ncmpiGroup.h"
+#include "ncmpiCheck.h"
+#include <pnetcdf.h>
+using namespace std;
+
+
+namespace PnetCDF {
+ // Global comparator operator ==============
+ // comparator operator
+ bool operator<(const NcmpiVarAtt& lhs,const NcmpiVarAtt& rhs)
+ {
+ return false;
+ }
+
+ // comparator operator
+ bool operator>(const NcmpiVarAtt& lhs,const NcmpiVarAtt& rhs)
+ {
+ return true;
+ }
+}
+
+
+using namespace PnetCDF;
+
+
+// assignment operator
+NcmpiVarAtt& NcmpiVarAtt::operator=(const NcmpiVarAtt & rhs)
+{
+ NcmpiAtt::operator=(rhs); // assign base class parts
+ return *this;
+}
+
+//! The copy constructor.
+NcmpiVarAtt::NcmpiVarAtt(const NcmpiVarAtt& rhs):
+ NcmpiAtt(rhs) // invoke base class copy constructor
+{}
+
+
+// Constructor generates a null object.
+NcmpiVarAtt::NcmpiVarAtt() :
+ NcmpiAtt() // invoke base class constructor
+{}
+
+
+// Constructor for an existing local attribute.
+NcmpiVarAtt::NcmpiVarAtt(const NcmpiGroup& grp, const NcmpiVar& ncmpiVar, const int index):
+ NcmpiAtt(false)
+{
+ groupId = grp.getId();
+ varId = ncmpiVar.getId();
+ // get the name of this attribute
+ char attName[NC_MAX_NAME+1];
+ ncmpiCheck(ncmpi_inq_attname(groupId,varId, index, attName),__FILE__,__LINE__);
+ ncmpiCheck(ncmpi_inq_attname(groupId,varId,index,attName),__FILE__,__LINE__);
+ myName = attName;
+}
+
+// Returns the NcmpiVar parent object.
+NcmpiVar NcmpiVarAtt::getParentVar() const {
+ return NcmpiVar(groupId,varId);
+}
diff --git a/src/libcxx/ncmpiVarAtt.h b/src/libcxx/ncmpiVarAtt.h
new file mode 100644
index 0000000..0059e69
--- /dev/null
+++ b/src/libcxx/ncmpiVarAtt.h
@@ -0,0 +1,46 @@
+#include "ncmpiAtt.h"
+
+#ifndef NcmpiVarAttClass
+#define NcmpiVarAttClass
+
+namespace PnetCDF
+{
+ class NcmpiGroup; // forward declaration.
+ class NcmpiVar; // forward declaration.
+
+ /*! Class represents a netCDF attribute local to a netCDF variable. */
+ class NcmpiVarAtt : public NcmpiAtt
+ {
+ public:
+
+ /*! assignment operator */
+ NcmpiVarAtt& operator= (const NcmpiVarAtt& rhs);
+
+ /*! Constructor generates a \ref isNull "null object". */
+ NcmpiVarAtt ();
+
+ /*! The copy constructor. */
+ NcmpiVarAtt(const NcmpiVarAtt& rhs) ;
+
+ /*!
+ Constructor for an existing local attribute.
+ \param grp Parent Group object.
+ \param NcmpiVar Parent NcmpiVar object.
+ \param index The index (id) of the attribute.
+ */
+ NcmpiVarAtt(const NcmpiGroup& grp, const NcmpiVar& ncmpiVar, const int index);
+
+ /*! Returns the NcmpiVar parent object. */
+ NcmpiVar getParentVar() const;
+
+ /*! comparator operator */
+ friend bool operator<(const NcmpiVarAtt& lhs,const NcmpiVarAtt& rhs);
+
+ /*! comparator operator */
+ friend bool operator>(const NcmpiVarAtt& lhs,const NcmpiVarAtt& rhs);
+
+ };
+
+}
+
+#endif
diff --git a/src/libcxx/ncmpiVlenType.cpp b/src/libcxx/ncmpiVlenType.cpp
new file mode 100644
index 0000000..8027313
--- /dev/null
+++ b/src/libcxx/ncmpiVlenType.cpp
@@ -0,0 +1,91 @@
+#include "ncmpiVlenType.h"
+#include "ncmpiGroup.h"
+#include "ncmpiCheck.h"
+#include "ncmpiException.h"
+#include "ncmpiByte.h"
+#include "ncmpiUbyte.h"
+#include "ncmpiChar.h"
+#include "ncmpiShort.h"
+#include "ncmpiUshort.h"
+#include "ncmpiInt.h"
+#include "ncmpiUint.h"
+#include "ncmpiInt64.h"
+#include "ncmpiUint64.h"
+#include "ncmpiFloat.h"
+#include "ncmpiDouble.h"
+#include <pnetcdf.h>
+using namespace std;
+using namespace PnetCDF;
+using namespace PnetCDF::exceptions;
+
+// Class represents a netCDF variable.
+using namespace PnetCDF;
+
+// assignment operator
+NcmpiVlenType& NcmpiVlenType::operator=(const NcmpiVlenType& rhs)
+{
+ NcmpiType::operator=(rhs); // assign base class parts
+ return *this;
+}
+
+// assignment operator
+NcmpiVlenType& NcmpiVlenType::operator=(const NcmpiType& rhs)
+{
+ if (&rhs != this) {
+ // check the rhs is the base of an Opaque type
+ if(getTypeClass() != NC_VLEN) throw NcmpiException("The NcmpiType object must be the base of an Vlen type.",__FILE__,__LINE__);
+ // assign base class parts
+ NcmpiType::operator=(rhs);
+ }
+ return *this;
+}
+
+// The copy constructor.
+NcmpiVlenType::NcmpiVlenType(const NcmpiVlenType& rhs):
+ NcmpiType(rhs)
+{
+}
+
+
+// Constructor generates a null object.
+NcmpiVlenType::NcmpiVlenType() :
+ NcmpiType() // invoke base class constructor
+{}
+
+// constructor
+NcmpiVlenType::NcmpiVlenType(const NcmpiGroup& grp, const string& name) :
+ NcmpiType(grp,name)
+{}
+
+// constructor
+NcmpiVlenType::NcmpiVlenType(const NcmpiType& ncmpiType):
+ NcmpiType(ncmpiType)
+{
+ // check the nctype object is the base of a Vlen type
+ if(getTypeClass() != NC_VLEN) throw NcmpiException("The NcmpiType object must be the base of a Vlen type.",__FILE__,__LINE__);
+}
+
+// Returns the base type.
+NcmpiType NcmpiVlenType::getBaseType() const
+{
+ char charName[NC_MAX_NAME+1];
+ nc_type base_nc_typep;
+ MPI_Offset datum_sizep;
+ ncmpiCheck(ncmpi_inq_vlen(groupId,myId,charName,&datum_sizep,&base_nc_typep),__FILE__,__LINE__);
+ switch (base_nc_typep) {
+ case NC_BYTE : return ncmpiByte;
+ case NC_UBYTE : return ncmpiUbyte;
+ case NC_CHAR : return ncmpiChar;
+ case NC_SHORT : return ncmpiShort;
+ case NC_USHORT : return ncmpiUshort;
+ case NC_INT : return ncmpiInt;
+ case NC_UINT : return ncmpiUint;
+ case NC_INT64 : return ncmpiInt64;
+ case NC_UINT64 : return ncmpiUint64;
+ case NC_FLOAT : return ncmpiFloat;
+ case NC_DOUBLE : return ncmpiDouble;
+ default:
+ // this is a user defined type
+ return NcmpiType(getParentGroup(),base_nc_typep);
+ }
+}
diff --git a/src/libcxx/ncmpiVlenType.h b/src/libcxx/ncmpiVlenType.h
new file mode 100644
index 0000000..1491d9f
--- /dev/null
+++ b/src/libcxx/ncmpiVlenType.h
@@ -0,0 +1,57 @@
+#include <string>
+#include "ncmpiType.h"
+
+#ifndef NcmpiVlenTypeClass
+#define NcmpiVlenTypeClass
+
+
+namespace PnetCDF
+{
+ class NcmpiGroup; // forward declaration.
+
+ /*! Class represents a netCDF VLEN type */
+ class NcmpiVlenType : public NcmpiType
+ {
+ public:
+
+ /*! Constructor generates a \ref isNull "null object". */
+ NcmpiVlenType();
+
+ /*!
+ Constructor.
+ The vlen Type must already exist in the netCDF file. New netCDF vlen types can be added
+ using NcmpiGroup::addNcmpiVlenType();
+ \param grp The parent group where this type is defined.
+ \param name Name of new type.
+ */
+ NcmpiVlenType(const NcmpiGroup& grp, const std::string& name);
+
+ /*!
+ Constructor.
+ Constructs from the base type NcmpiType object. Will throw an exception if the NcmpiType is not the base of a Vlen type.
+ \param ncmpiType A Nctype object.
+ */
+ NcmpiVlenType(const NcmpiType& ncmpiType);
+
+ /*! assignment operator */
+ NcmpiVlenType& operator=(const NcmpiVlenType& rhs);
+
+ /*!
+ Assignment operator.
+ This assigns from the base type NcmpiType object. Will throw an exception if the NcmpiType is not the base of a Vlen type.
+ */
+ NcmpiVlenType& operator=(const NcmpiType& rhs);
+
+ /*! The copy constructor. */
+ NcmpiVlenType(const NcmpiVlenType& rhs);
+
+ ~NcmpiVlenType(){;}
+
+ /*! Returns the base type. */
+ NcmpiType getBaseType() const;
+
+ };
+
+}
+
+#endif
diff --git a/src/libcxx/ncmpi_notyet.cpp b/src/libcxx/ncmpi_notyet.cpp
new file mode 100644
index 0000000..be1af0f
--- /dev/null
+++ b/src/libcxx/ncmpi_notyet.cpp
@@ -0,0 +1,318 @@
+#include <pnetcdf.h>
+#include <iostream>
+#include "ncmpi_notyet.h"
+
+#ifndef __func__
+#define __func__ __FUNCTION__
+#endif
+
+ int
+ncmpi_insert_compound(int ncid, nc_type xtype, const char *name,
+ MPI_Offset offset, nc_type field_typeid){std::cout << __func__ << " not implemented" << std::endl; return NC_EINVAL;}
+
+/* Insert a named array into a compound type. */
+ int
+ncmpi_insert_array_compound(int ncid, nc_type xtype, const char *name,
+ MPI_Offset offset, nc_type field_typeid,
+ int ndims, const int *dim_sizes){std::cout << __func__ << " not implemented" << std::endl; return NC_EINVAL;}
+ int
+ncmpi_insert_enum(int ncid, nc_type xtype, const char *name,
+ const void *value){std::cout << __func__ << " not implemented" << std::endl; return NC_EINVAL;}
+ int
+ncmpi_def_compound(int ncid, MPI_Offset size, const char *name, nc_type *typeidp){std::cout << __func__ << " not implemented" << std::endl; return NC_EINVAL;}
+
+ int
+ncmpi_inq_enum(int ncid, nc_type xtype, char *name, nc_type *base_nc_typep,
+ MPI_Offset *base_sizep, MPI_Offset *num_membersp){std::cout << __func__ << " not implemented" << std::endl; return NC_EINVAL;}
+
+/* Get information about an enum member: a name and value. Name size
+ * * will be <= NC_MAX_NAME. */
+ int
+ncmpi_inq_enum_member(int ncid, nc_type xtype, int idx, char *name,
+ void *value){std::cout << __func__ << " not implemented" << std::endl; return NC_EINVAL;}
+
+ int
+ncmpi_inq_enum_ident(int ncid, nc_type xtype, long long value, char *identifier){std::cout << __func__ << " not implemented" << std::endl; return NC_EINVAL;}
+
+ int
+ncmpi_inq_compound_nfields(int ncid, nc_type xtype, MPI_Offset *nfieldsp){std::cout << __func__ << " not implemented" << std::endl; return NC_EINVAL;}
+
+ int
+ncmpi_inq_compound_name(int ncid, nc_type xtype, char *name){std::cout << __func__ << " not implemented" << std::endl; return NC_EINVAL;}
+
+/* Get the size of a compound type. */
+ int
+ncmpi_inq_compound_size(int ncid, nc_type xtype, MPI_Offset *sizep){std::cout << __func__ << " not implemented" << std::endl; return NC_EINVAL;}
+
+/* Given the xtype and the fieldid, get all info about it. */
+ int
+ncmpi_inq_compound_field(int ncid, nc_type xtype, int fieldid, char *name,
+ MPI_Offset *offsetp, nc_type *field_typeidp, int *ndimsp,
+ int *dim_sizesp){std::cout << __func__ << " not implemented" << std::endl; return NC_EINVAL;}
+
+/* Given the typeid and the fieldid, get the name. */
+ int
+ncmpi_inq_compound_fieldname(int ncid, nc_type xtype, int fieldid,
+ char *name){std::cout << __func__ << " not implemented" << std::endl; return NC_EINVAL;}
+ int
+ncmpi_inq_compound(int ncid, nc_type xtype, char *name, MPI_Offset *sizep,
+ MPI_Offset *nfieldsp){std::cout << __func__ << " not implemented" << std::endl; return NC_EINVAL;}
+/* Given the xtype and the name, get the fieldid. */
+ int
+ncmpi_inq_compound_fieldindex(int ncid, nc_type xtype, const char *name,
+ int *fieldidp){std::cout << __func__ << " not implemented" << std::endl; return NC_EINVAL;}
+
+/* Given the xtype and fieldid, get the offset. */
+ int
+ncmpi_inq_compound_fieldoffset(int ncid, nc_type xtype, int fieldid,
+ MPI_Offset *offsetp){std::cout << __func__ << " not implemented" << std::endl; return NC_EINVAL;}
+
+/* Given the xtype and the fieldid, get the type of that field. */
+ int
+ncmpi_inq_compound_fieldtype(int ncid, nc_type xtype, int fieldid,
+ nc_type *field_typeidp){std::cout << __func__ << " not implemented" << std::endl; return NC_EINVAL;}
+
+/* Given the xtype and the fieldid, get the number of dimensions for
+ * * that field (scalars are 0). */
+ int
+ncmpi_inq_compound_fieldndims(int ncid, nc_type xtype, int fieldid,
+ int *ndimsp){std::cout << __func__ << " not implemented" << std::endl; return NC_EINVAL;}
+ int
+ncmpi_inq_compound_fielddim_sizes(int ncid, nc_type xtype, int fieldid,
+ int *dim_sizes){std::cout << __func__ << " not implemented" << std::endl; return NC_EINVAL;}
+
+ int
+ncmpi_inq_unlimdims(int ncid, int *nunlimdimsp, int *unlimdimidsp){std::cout << __func__ << " not implemented" << std::endl; return NC_EINVAL;}
+
+ int
+ncmpi_inq_grpname_len(int ncid, MPI_Offset *lenp){std::cout << __func__ << " not implemented" << std::endl; return NC_EINVAL;}
+
+/* Given an ncid, find the ncid of its parent group. */
+ int
+ncmpi_inq_grp_parent(int ncid, int *parent_ncid){std::cout << __func__ << " not implemented" << std::endl; return NC_EINVAL;}
+
+/* Given a name and parent ncid, find group ncid. */
+ int
+ncmpi_inq_grp_ncid(int ncid, const char *grp_name, int *grp_ncid){std::cout << __func__ << " not implemented" << std::endl; return NC_EINVAL;}
+/* Given a full name and ncid, find group ncid. */
+ int
+ncmpi_inq_grp_full_ncid(int ncid, const char *full_name, int *grp_ncid){std::cout << __func__ << " not implemented" << std::endl; return NC_EINVAL;}
+
+/* Get a list of ids for all the variables in a group. */
+ int
+ncmpi_inq_varids(int ncid, int *nvars, int *varids){std::cout << __func__ << " not implemented" << std::endl; return NC_EINVAL;}
+
+/* Find all dimids for a location. This finds all dimensions in a
+ * * group, or any of its parents. */
+ int
+ncmpi_inq_dimids(int ncid, int *ndims, int *dimids, int include_parents){std::cout << __func__ << " not implemented" << std::endl; return NC_EINVAL;}
+
+ int
+ncmpi_inq_type(int ncid, nc_type xtype, char *name, MPI_Offset *size){std::cout << __func__ << " not implemented" << std::endl; return NC_EINVAL;}
+
+/* Find all user-defined types for a location. This finds all
+ * * user-defined types in a group. */
+ int
+ncmpi_inq_typeids(int ncid, int *ntypes, int *typeids){*ntypes=0; std::cout << __func__ << " not implemented" << std::endl; return NC_EINVAL;}
+
+/* Are two types equal? */
+ int
+ncmpi_inq_type_equal(int ncid1, nc_type typeid1, int ncid2,
+ nc_type typeid2, int *equal){std::cout << __func__ << " not implemented" << std::endl; return NC_EINVAL;}
+/* Create a group. its ncid is returned in the new_ncid pointer. */
+ int
+ncmpi_def_grp(int parent_ncid, const char *name, int *new_ncid){std::cout << __func__ << " not implemented" << std::endl; return NC_EINVAL;}
+
+/* Rename a group */
+ int
+ncmpi_rename_grp(int grpid, const char *name){std::cout << __func__ << " not implemented" << std::endl; return NC_EINVAL;}
+
+ int
+ncmpi_inq_grps(int ncid, int *numgrps, int *ncids){std::cout << __func__ << " not implemented" << std::endl; return NC_EINVAL;}
+
+/* Given locid, find name of group. (Root group is named "/".) */
+ int
+ncmpi_inq_grpname(int ncid, char *name){std::cout << __func__ << " not implemented" << std::endl; return NC_EINVAL;}
+
+/* Given ncid, find full name and len of full name. (Root group is
+ * * named "/", with length 1.) */
+ int
+ncmpi_inq_grpname_full(int ncid, MPI_Offset *lenp, char *full_name){std::cout << __func__ << " not implemented" << std::endl; return NC_EINVAL;}
+
+ int
+ncmpi_def_enum(int ncid, nc_type base_typeid, const char *name,
+ nc_type *typeidp){std::cout << __func__ << " not implemented" << std::endl; return NC_EINVAL;}
+
+ int
+ncmpi_def_vlen(int ncid, const char *name, nc_type base_typeid, nc_type *xtypep){std::cout << __func__ << " not implemented" << std::endl; return NC_EINVAL;}
+
+/* Find out about a vlen. */
+ int
+ncmpi_inq_vlen(int ncid, nc_type xtype, char *name, MPI_Offset *datum_sizep,
+ nc_type *base_nc_typep){std::cout << __func__ << " not implemented" << std::endl; return NC_EINVAL;}
+
+ int
+ncmpi_free_vlen(nc_vlen_t *vl){std::cout << __func__ << " not implemented" << std::endl; return NC_EINVAL;}
+
+ int
+ncmpi_free_vlens(MPI_Offset len, nc_vlen_t vlens[]){std::cout << __func__ << " not implemented" << std::endl; return NC_EINVAL;}
+
+/* Put or get one element in a vlen array. */
+ int
+ncmpi_put_vlen_element(int ncid, int typeid1, void *vlen_element,
+ MPI_Offset len, const void *data){std::cout << __func__ << " not implemented" << std::endl; return NC_EINVAL;}
+
+ int
+ncmpi_get_vlen_element(int ncid, int typeid1, const void *vlen_element,
+ MPI_Offset *len, void *data){std::cout << __func__ << " not implemented" << std::endl; return NC_EINVAL;}
+ int
+ncmpi_def_opaque(int ncid, MPI_Offset size, const char *name, nc_type *xtypep){std::cout << __func__ << " not implemented" << std::endl; return NC_EINVAL;}
+
+/* Get information about an opaque type. */
+ int
+ncmpi_inq_opaque(int ncid, nc_type xtype, char *name, MPI_Offset *sizep){std::cout << __func__ << " not implemented" << std::endl; return NC_EINVAL;}
+
+ int
+ncmpi_inq_user_type(int ncid, nc_type xtype, char *name, MPI_Offset *size,
+ nc_type *base_nc_typep, MPI_Offset *nfieldsp, int *classp){std::cout << __func__ << " not implemented" << std::endl; return NC_EINVAL;}
+
+ int
+ncmpi_def_var_chunking(int ncid, int varid, int storage, const MPI_Offset *chunksizesp){std::cout << __func__ << " not implemented" << std::endl; return NC_EINVAL;}
+ int
+ncmpi_inq_var_chunking(int ncid, int varid, int *storagep, MPI_Offset *chunksizesp){std::cout << __func__ << " not implemented" << std::endl; return NC_EINVAL;}
+
+ int
+ncmpi_def_var_endian(int ncid, int varid, int endian){std::cout << __func__ << " not implemented" << std::endl; return NC_EINVAL;}
+
+/* Learn about the endianness of a variable. */
+ int
+ncmpi_inq_var_endian(int ncid, int varid, int *endianp){std::cout << __func__ << " not implemented" << std::endl; return NC_EINVAL;}
+ int
+ncmpi_set_chunk_cache(MPI_Offset size, MPI_Offset nelems, float preemption){std::cout << __func__ << " not implemented" << std::endl; return NC_EINVAL;}
+
+ int
+ncmpi_def_var_deflate(int ncid, int varid, int shuffle, int deflate,
+ int deflate_level){std::cout << __func__ << " not implemented" << std::endl; return NC_EINVAL;}
+ int
+ncmpi_inq_var_deflate(int ncid, int varid, int *shufflep,
+ int *deflatep, int *deflate_levelp){std::cout << __func__ << " not implemented" << std::endl; return NC_EINVAL;}
+ int
+ncmpi_inq_var_szip(int ncid, int varid, int *options_maskp, int *pixels_per_blockp){std::cout << __func__ << " not implemented" << std::endl; return NC_EINVAL;}
+
+/* Set fletcher32 checksum for a var. This must be done after nc_def_var
+ * and before nc_enddef. */
+ int
+ncmpi_def_var_fletcher32(int ncid, int varid, int fletcher32){std::cout << __func__ << " not implemented" << std::endl; return NC_EINVAL;}
+
+/* Inquire about fletcher32 checksum for a var. */
+ int
+ncmpi_inq_var_fletcher32(int ncid, int varid, int *fletcher32p){std::cout << __func__ << " not implemented" << std::endl; return NC_EINVAL;}
+
+ int
+ncmpi_put_var1_string(int ncid, int varid, const MPI_Offset *indexp,
+ const char **op){std::cout << __func__ << " not implemented" << std::endl; return NC_EINVAL;}
+
+ int
+ncmpi_get_var1_string(int ncid, int varid, const MPI_Offset *indexp,
+ char **ip){std::cout << __func__ << " not implemented" << std::endl; return NC_EINVAL;}
+
+ int
+ncmpi_put_var_string(int ncid, int varid,
+ const char **op){std::cout << __func__ << " not implemented" << std::endl; return NC_EINVAL;}
+
+ int
+ncmpi_get_var_string(int ncid, int varid,
+ char **ip){std::cout << __func__ << " not implemented" << std::endl; return NC_EINVAL;}
+
+ int
+ncmpi_put_vara_string(int ncid, int varid, const MPI_Offset *startp,
+ const MPI_Offset *countp,
+ const char **op){std::cout << __func__ << " not implemented" << std::endl; return NC_EINVAL;}
+
+ int
+ncmpi_get_vara_string(int ncid, int varid, const MPI_Offset *startp,
+ const MPI_Offset *countp,
+ char **ip){std::cout << __func__ << " not implemented" << std::endl; return NC_EINVAL;}
+
+ int
+ncmpi_put_vars_string(int ncid, int varid, const MPI_Offset *startp,
+ const MPI_Offset *countp, const MPI_Offset *stridep,
+ const char **op){std::cout << __func__ << " not implemented" << std::endl; return NC_EINVAL;}
+
+ int
+ncmpi_get_vars_string(int ncid, int varid, const MPI_Offset *startp,
+ const MPI_Offset *countp, const MPI_Offset *stridep,
+ char **ip){std::cout << __func__ << " not implemented" << std::endl; return NC_EINVAL;}
+
+ int
+ncmpi_put_varm_string(int ncid, int varid, const MPI_Offset *startp,
+ const MPI_Offset *countp, const MPI_Offset *stridep,
+ const MPI_Offset * imapp, const char **op){std::cout << __func__ << " not implemented" << std::endl; return NC_EINVAL;}
+
+ int
+ncmpi_get_varm_string(int ncid, int varid, const MPI_Offset *startp,
+ const MPI_Offset *countp, const MPI_Offset *stridep,
+ const MPI_Offset * imapp, char **ip){std::cout << __func__ << " not implemented" << std::endl; return NC_EINVAL;}
+
+ int
+ncmpi_put_varn_string(int ncid, int varid, int num, MPI_Offset* const starts[],
+ MPI_Offset* const count[], const char **op){std::cout << __func__ << " not implemented" << std::endl; return NC_EINVAL;}
+
+ int
+ncmpi_get_varn_string(int ncid, int varid, int num, MPI_Offset* const starts[],
+ MPI_Offset* const count[], char **ip){std::cout << __func__ << " not implemented" << std::endl; return NC_EINVAL;}
+
+ int
+ncmpi_put_varn_string_all(int ncid, int varid, int num, MPI_Offset* const starts[],
+ MPI_Offset* const count[], const char **op){std::cout << __func__ << " not implemented" << std::endl; return NC_EINVAL;}
+
+ int
+ncmpi_get_varn_string_all(int ncid, int varid, int num, MPI_Offset* const starts[],
+ MPI_Offset* const count[], char **ip){std::cout << __func__ << " not implemented" << std::endl; return NC_EINVAL;}
+
+ int
+ncmpi_iput_var1_string(int ncid, int varid, const MPI_Offset *indexp, const char **op, int *req){std::cout << __func__ << " not implemented" << std::endl; return NC_EINVAL;}
+
+ int
+ncmpi_bput_var1_string(int ncid, int varid, const MPI_Offset *indexp, const char **op, int *req){std::cout << __func__ << " not implemented" << std::endl; return NC_EINVAL;}
+
+ int
+ncmpi_iget_var1_string(int ncid, int varid, const MPI_Offset *indexp, char **ip, int *req){std::cout << __func__ << " not implemented" << std::endl; return NC_EINVAL;}
+
+ int
+ncmpi_iput_var_string(int ncid, int varid, const char **op, int *req){std::cout << __func__ << " not implemented" << std::endl; return NC_EINVAL;}
+
+ int
+ncmpi_bput_var_string(int ncid, int varid, const char **op, int *req){std::cout << __func__ << " not implemented" << std::endl; return NC_EINVAL;}
+
+ int
+ncmpi_iget_var_string(int ncid, int varid, char **ip, int *req){std::cout << __func__ << " not implemented" << std::endl; return NC_EINVAL;}
+
+ int
+ncmpi_iput_vara_string(int ncid, int varid, const MPI_Offset *startp, const MPI_Offset *countp, const char **op, int *req){std::cout << __func__ << " not implemented" << std::endl; return NC_EINVAL;}
+
+ int
+ncmpi_bput_vara_string(int ncid, int varid, const MPI_Offset *startp, const MPI_Offset *countp, const char **op, int *req){std::cout << __func__ << " not implemented" << std::endl; return NC_EINVAL;}
+
+ int
+ncmpi_iget_vara_string(int ncid, int varid, const MPI_Offset *startp, const MPI_Offset *countp, char **ip, int *req){std::cout << __func__ << " not implemented" << std::endl; return NC_EINVAL;}
+
+ int
+ncmpi_iput_vars_string(int ncid, int varid, const MPI_Offset *startp, const MPI_Offset *countp, const MPI_Offset *stridep, const char **op, int *req){std::cout << __func__ << " not implemented" << std::endl; return NC_EINVAL;}
+
+ int
+ncmpi_bput_vars_string(int ncid, int varid, const MPI_Offset *startp, const MPI_Offset *countp, const MPI_Offset *stridep, const char **op, int *req){std::cout << __func__ << " not implemented" << std::endl; return NC_EINVAL;}
+
+ int
+ncmpi_iget_vars_string(int ncid, int varid, const MPI_Offset *startp, const MPI_Offset *countp, const MPI_Offset *stridep, char **ip, int *req){std::cout << __func__ << " not implemented" << std::endl; return NC_EINVAL;}
+
+ int
+ncmpi_iput_varm_string(int ncid, int varid, const MPI_Offset *startp, const MPI_Offset *countp, const MPI_Offset *stridep, const MPI_Offset * imapp, const char **op, int *req){std::cout << __func__ << " not implemented" << std::endl; return NC_EINVAL;}
+
+ int
+ncmpi_bput_varm_string(int ncid, int varid, const MPI_Offset *startp, const MPI_Offset *countp, const MPI_Offset *stridep, const MPI_Offset * imapp, const char **op, int *req){std::cout << __func__ << " not implemented" << std::endl; return NC_EINVAL;}
+
+ int
+ncmpi_iget_varm_string(int ncid, int varid, const MPI_Offset *startp, const MPI_Offset *countp, const MPI_Offset *stridep, const MPI_Offset * imapp, char **ip, int *req){std::cout << __func__ << " not implemented" << std::endl; return NC_EINVAL;}
+
+
diff --git a/src/libcxx/ncmpi_notyet.h b/src/libcxx/ncmpi_notyet.h
new file mode 100644
index 0000000..0970746
--- /dev/null
+++ b/src/libcxx/ncmpi_notyet.h
@@ -0,0 +1,214 @@
+#ifndef H_NC
+#define H_NC
+extern int
+ncmpi_insert_compound(int ncid, nc_type xtype, const char *name,
+ MPI_Offset offset, nc_type field_typeid);
+
+/* Insert a named array into a compound type. */
+extern int
+ncmpi_insert_array_compound(int ncid, nc_type xtype, const char *name,
+ MPI_Offset offset, nc_type field_typeid,
+ int ndims, const int *dim_sizes);
+extern int
+ncmpi_insert_enum(int ncid, nc_type xtype, const char *name,
+ const void *value);
+extern int
+ncmpi_def_compound(int ncid, MPI_Offset size, const char *name, nc_type *typeidp);
+
+extern int
+ncmpi_inq_enum(int ncid, nc_type xtype, char *name, nc_type *base_nc_typep,
+ MPI_Offset *base_sizep, MPI_Offset *num_membersp);
+
+/* Get information about an enum member: a name and value. Name size
+ * * will be <= NC_MAX_NAME. */
+extern int
+ncmpi_inq_enum_member(int ncid, nc_type xtype, int idx, char *name,
+ void *value);
+
+extern int
+ncmpi_inq_enum_ident(int ncid, nc_type xtype, long long value, char *identifier);
+
+extern int
+ncmpi_inq_compound_nfields(int ncid, nc_type xtype, MPI_Offset *nfieldsp);
+
+extern int
+ncmpi_inq_compound_name(int ncid, nc_type xtype, char *name);
+
+/* Get the size of a compound type. */
+extern int
+ncmpi_inq_compound_size(int ncid, nc_type xtype, MPI_Offset *sizep);
+
+/* Get the number of fields in this compound type. */
+extern int
+ncmpi_inq_compound_nfields(int ncid, nc_type xtype, MPI_Offset *nfieldsp);
+
+/* Given the xtype and the fieldid, get all info about it. */
+extern int
+ncmpi_inq_compound_field(int ncid, nc_type xtype, int fieldid, char *name,
+ MPI_Offset *offsetp, nc_type *field_typeidp, int *ndimsp,
+ int *dim_sizesp);
+
+/* Given the typeid and the fieldid, get the name. */
+extern int
+ncmpi_inq_compound_fieldname(int ncid, nc_type xtype, int fieldid,
+ char *name);
+extern int
+ncmpi_inq_compound(int ncid, nc_type xtype, char *name, MPI_Offset *sizep,
+ MPI_Offset *nfieldsp);
+/* Given the xtype and the name, get the fieldid. */
+extern int
+ncmpi_inq_compound_fieldindex(int ncid, nc_type xtype, const char *name,
+ int *fieldidp);
+
+/* Given the xtype and fieldid, get the offset. */
+extern int
+ncmpi_inq_compound_fieldoffset(int ncid, nc_type xtype, int fieldid,
+ MPI_Offset *offsetp);
+
+/* Given the xtype and the fieldid, get the type of that field. */
+extern int
+ncmpi_inq_compound_fieldtype(int ncid, nc_type xtype, int fieldid,
+ nc_type *field_typeidp);
+
+/* Given the xtype and the fieldid, get the number of dimensions for
+ * * that field (scalars are 0). */
+extern int
+ncmpi_inq_compound_fieldndims(int ncid, nc_type xtype, int fieldid,
+ int *ndimsp);
+extern int
+ncmpi_inq_compound_fielddim_sizes(int ncid, nc_type xtype, int fieldid,
+ int *dim_sizes);
+
+extern int
+ncmpi_inq_unlimdims(int ncid, int *nunlimdimsp, int *unlimdimidsp);
+
+extern int
+ncmpi_inq_grpname_len(int ncid, MPI_Offset *lenp);
+
+/* Given an ncid, find the ncid of its parent group. */
+extern int
+ncmpi_inq_grp_parent(int ncid, int *parent_ncid);
+
+/* Given a name and parent ncid, find group ncid. */
+extern int
+ncmpi_inq_grp_ncid(int ncid, const char *grp_name, int *grp_ncid);
+/* Given a full name and ncid, find group ncid. */
+extern int
+ncmpi_inq_grp_full_ncid(int ncid, const char *full_name, int *grp_ncid);
+
+/* Get a list of ids for all the variables in a group. */
+extern int
+ncmpi_inq_varids(int ncid, int *nvars, int *varids);
+
+/* Find all dimids for a location. This finds all dimensions in a
+ * * group, or any of its parents. */
+extern int
+ncmpi_inq_dimids(int ncid, int *ndims, int *dimids, int include_parents);
+
+extern int
+ncmpi_inq_type(int ncid, nc_type xtype, char *name, MPI_Offset *size);
+
+/* Find all user-defined types for a location. This finds all
+ * * user-defined types in a group. */
+extern int
+ncmpi_inq_typeids(int ncid, int *ntypes, int *typeids);
+
+/* Are two types equal? */
+extern int
+ncmpi_inq_type_equal(int ncid1, nc_type typeid1, int ncid2,
+ nc_type typeid2, int *equal);
+/* Create a group. its ncid is returned in the new_ncid pointer. */
+extern int
+ncmpi_def_grp(int parent_ncid, const char *name, int *new_ncid);
+
+/* Rename a group */
+extern int
+ncmpi_rename_grp(int grpid, const char *name);
+
+extern int
+ncmpi_inq_grps(int ncid, int *numgrps, int *ncids);
+
+/* Given locid, find name of group. (Root group is named "/".) */
+extern int
+ncmpi_inq_grpname(int ncid, char *name);
+
+/* Given ncid, find full name and len of full name. (Root group is
+ * * named "/", with length 1.) */
+extern int
+ncmpi_inq_grpname_full(int ncid, MPI_Offset *lenp, char *full_name);
+
+extern int
+ncmpi_def_enum(int ncid, nc_type base_typeid, const char *name,
+ nc_type *typeidp);
+
+extern int
+ncmpi_def_vlen(int ncid, const char *name, nc_type base_typeid, nc_type *xtypep);
+
+/* Find out about a vlen. */
+extern int
+ncmpi_inq_vlen(int ncid, nc_type xtype, char *name, MPI_Offset *datum_sizep,
+ nc_type *base_nc_typep);
+
+typedef struct {
+ MPI_Offset len; /**< Length of VL data (in base type units) */
+ void *p; /**< Pointer to VL data */
+} nc_vlen_t;
+
+extern int
+ncmpi_free_vlen(nc_vlen_t *vl);
+
+extern int
+ncmpi_free_vlens(MPI_Offset len, nc_vlen_t vlens[]);
+
+/* Put or get one element in a vlen array. */
+extern int
+ncmpi_put_vlen_element(int ncid, int typeid1, void *vlen_element,
+ MPI_Offset len, const void *data);
+
+extern int
+ncmpi_get_vlen_element(int ncid, int typeid1, const void *vlen_element,
+ MPI_Offset *len, void *data);
+extern int
+ncmpi_def_opaque(int ncid, MPI_Offset size, const char *name, nc_type *xtypep);
+
+/* Get information about an opaque type. */
+extern int
+ncmpi_inq_opaque(int ncid, nc_type xtype, char *name, MPI_Offset *sizep);
+
+extern int
+ncmpi_inq_user_type(int ncid, nc_type xtype, char *name, MPI_Offset *size,
+ nc_type *base_nc_typep, MPI_Offset *nfieldsp, int *classp);
+
+extern int
+ncmpi_def_var_chunking(int ncid, int varid, int storage, const MPI_Offset *chunksizesp);
+extern int
+ncmpi_inq_var_chunking(int ncid, int varid, int *storagep, MPI_Offset *chunksizesp);
+
+extern int
+ncmpi_def_var_endian(int ncid, int varid, int endian);
+
+/* Learn about the endianness of a variable. */
+extern int
+ncmpi_inq_var_endian(int ncid, int varid, int *endianp);
+extern int
+ncmpi_set_chunk_cache(MPI_Offset size, MPI_Offset nelems, float preemption);
+
+extern int
+ncmpi_def_var_deflate(int ncid, int varid, int shuffle, int deflate,
+ int deflate_level);
+extern int
+ncmpi_inq_var_deflate(int ncid, int varid, int *shufflep,
+ int *deflatep, int *deflate_levelp);
+extern int
+ncmpi_inq_var_szip(int ncid, int varid, int *options_maskp, int *pixels_per_blockp);
+
+/* Set fletcher32 checksum for a var. This must be done after nc_def_var
+ * and before nc_enddef. */
+extern int
+ncmpi_def_var_fletcher32(int ncid, int varid, int fletcher32);
+
+/* Inquire about fletcher32 checksum for a var. */
+extern int
+ncmpi_inq_var_fletcher32(int ncid, int varid, int *fletcher32p);
+
+#endif
diff --git a/src/libcxx/pnetcdf.in b/src/libcxx/pnetcdf.in
new file mode 100644
index 0000000..310e30e
--- /dev/null
+++ b/src/libcxx/pnetcdf.in
@@ -0,0 +1,14 @@
+//
+// generic include file for the PnetCDF C++ API
+//
+using namespace std;
+
+#include <exception>
+#include <string>
+#include <typeinfo>
+#include <vector>
+#include <set>
+#include <map>
+
+#include <pnetcdf.h>
+
diff --git a/src/libf/Makefile.in b/src/libf/Makefile.in
new file mode 100644
index 0000000..e2dfeee
--- /dev/null
+++ b/src/libf/Makefile.in
@@ -0,0 +1,403 @@
+#
+# Copyright (C) 2003, Northwestern University and Argonne National Laboratory
+# See COPYRIGHT notice in top-level directory.
+#
+# $Id: Makefile.in 2285 2015-12-30 20:48:25Z wkliao $
+#
+# @configure_input@
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+# generated by configure, so it's in the build dir, not srcdirr
+include ../../macros.make
+
+# For VPATH build:
+# Add ../lib into search path because ../lib/pnetcdf.h is created at the
+# configure time and included by all C2F_SRCS files in this folder.
+# Add $(srcdir) into search path because the C2F_SRCS files created at the
+# configure time in this folder all include $(srcdir)/mpinetcdf_impl.h.
+INCLUDES = -I../lib -I$(srcdir)
+
+HEADER = ../lib/pnetcdf.h
+LIBRARY = ../lib/libpnetcdf.a
+ld_netcdf = -L../lib -lpnetcdf
+
+UTIL_SRCS = issyserrf.c \
+ nfxutil.c \
+ xstrerrorf.c \
+ xinq_libversf.c
+
+C2F_SRCS = createf.c \
+ openf.c \
+ inq_file_infof.c \
+ get_file_infof.c \
+ deletef.c \
+ enddeff.c \
+ _enddeff.c \
+ redeff.c \
+ set_default_formatf.c inq_default_formatf.c \
+ syncf.c \
+ sync_numrecsf.c \
+ abortf.c \
+ begin_indep_dataf.c \
+ end_indep_dataf.c \
+ closef.c \
+ set_fillf.c def_var_fillf.c inq_var_fillf.c fill_var_recf.c \
+ def_dimf.c \
+ def_varf.c \
+ rename_dimf.c \
+ rename_varf.c \
+ inqf.c \
+ inq_formatf.c \
+ inq_file_formatf.c \
+ inq_versionf.c \
+ inq_stripingf.c \
+ inq_ndimsf.c \
+ inq_nvarsf.c \
+ inq_num_rec_varsf.c \
+ inq_num_fix_varsf.c \
+ inq_nattsf.c \
+ inq_unlimdimf.c \
+ inq_dimidf.c \
+ inq_dimf.c \
+ inq_dimnamef.c \
+ inq_dimlenf.c \
+ inq_varf.c \
+ inq_varidf.c \
+ inq_varnamef.c \
+ inq_vartypef.c \
+ inq_varndimsf.c \
+ inq_vardimidf.c \
+ inq_varnattsf.c \
+ inq_varoffsetf.c \
+ inq_attf.c \
+ inq_attidf.c \
+ inq_atttypef.c \
+ inq_attlenf.c \
+ inq_attnamef.c \
+ copy_attf.c \
+ rename_attf.c \
+ del_attf.c \
+ put_attf.c \
+ put_att_textf.c \
+ put_att_int1f.c \
+ put_att_int2f.c \
+ put_att_intf.c \
+ put_att_realf.c \
+ put_att_doublef.c \
+ put_att_int8f.c \
+ get_attf.c \
+ get_att_textf.c \
+ get_att_int1f.c \
+ get_att_int2f.c \
+ get_att_intf.c \
+ get_att_realf.c \
+ get_att_doublef.c \
+ get_att_int8f.c \
+ put_var1f.c put_var1_allf.c \
+ put_var1_textf.c put_var1_text_allf.c \
+ put_var1_int1f.c put_var1_int1_allf.c \
+ put_var1_int2f.c put_var1_int2_allf.c \
+ put_var1_intf.c put_var1_int_allf.c \
+ put_var1_realf.c put_var1_real_allf.c \
+ put_var1_doublef.c put_var1_double_allf.c \
+ put_var1_int8f.c put_var1_int8_allf.c \
+ get_var1f.c get_var1_allf.c \
+ get_var1_textf.c get_var1_text_allf.c \
+ get_var1_int1f.c get_var1_int1_allf.c \
+ get_var1_int2f.c get_var1_int2_allf.c \
+ get_var1_intf.c get_var1_int_allf.c \
+ get_var1_realf.c get_var1_real_allf.c \
+ get_var1_doublef.c get_var1_double_allf.c \
+ get_var1_int8f.c get_var1_int8_allf.c \
+ put_varf.c put_var_allf.c \
+ put_var_textf.c put_var_text_allf.c \
+ put_var_int1f.c put_var_int1_allf.c \
+ put_var_int2f.c put_var_int2_allf.c \
+ put_var_intf.c put_var_int_allf.c \
+ put_var_realf.c put_var_real_allf.c \
+ put_var_doublef.c put_var_double_allf.c \
+ put_var_int8f.c put_var_int8_allf.c \
+ get_varf.c get_var_allf.c \
+ get_var_textf.c get_var_text_allf.c \
+ get_var_int1f.c get_var_int1_allf.c \
+ get_var_int2f.c get_var_int2_allf.c \
+ get_var_intf.c get_var_int_allf.c \
+ get_var_realf.c get_var_real_allf.c \
+ get_var_doublef.c get_var_double_allf.c \
+ get_var_int8f.c get_var_int8_allf.c \
+ put_varaf.c put_vara_allf.c \
+ put_vara_textf.c put_vara_text_allf.c \
+ put_vara_int1f.c put_vara_int1_allf.c \
+ put_vara_int2f.c put_vara_int2_allf.c \
+ put_vara_intf.c put_vara_int_allf.c \
+ put_vara_realf.c put_vara_real_allf.c \
+ put_vara_doublef.c put_vara_double_allf.c \
+ put_vara_int8f.c put_vara_int8_allf.c \
+ get_varaf.c get_vara_allf.c \
+ get_vara_textf.c get_vara_text_allf.c \
+ get_vara_int1f.c get_vara_int1_allf.c \
+ get_vara_int2f.c get_vara_int2_allf.c \
+ get_vara_intf.c get_vara_int_allf.c \
+ get_vara_realf.c get_vara_real_allf.c \
+ get_vara_doublef.c get_vara_double_allf.c \
+ get_vara_int8f.c get_vara_int8_allf.c \
+ put_varsf.c put_vars_allf.c \
+ put_vars_textf.c put_vars_text_allf.c \
+ put_vars_int1f.c put_vars_int1_allf.c \
+ put_vars_int2f.c put_vars_int2_allf.c \
+ put_vars_intf.c put_vars_int_allf.c \
+ put_vars_realf.c put_vars_real_allf.c \
+ put_vars_doublef.c put_vars_double_allf.c \
+ put_vars_int8f.c put_vars_int8_allf.c \
+ get_varsf.c get_vars_allf.c \
+ get_vars_int1f.c get_vars_int1_allf.c \
+ get_vars_textf.c get_vars_text_allf.c \
+ get_vars_int2f.c get_vars_int2_allf.c \
+ get_vars_intf.c get_vars_int_allf.c \
+ get_vars_realf.c get_vars_real_allf.c \
+ get_vars_doublef.c get_vars_double_allf.c \
+ get_vars_int8f.c get_vars_int8_allf.c \
+ put_varmf.c put_varm_allf.c \
+ put_varm_textf.c put_varm_text_allf.c \
+ put_varm_int1f.c put_varm_int1_allf.c \
+ put_varm_int2f.c put_varm_int2_allf.c \
+ put_varm_intf.c put_varm_int_allf.c \
+ put_varm_realf.c put_varm_real_allf.c \
+ put_varm_doublef.c put_varm_double_allf.c \
+ put_varm_int8f.c put_varm_int8_allf.c \
+ get_varmf.c get_varm_allf.c \
+ get_varm_int1f.c get_varm_int1_allf.c \
+ get_varm_textf.c get_varm_text_allf.c \
+ get_varm_int2f.c get_varm_int2_allf.c \
+ get_varm_intf.c get_varm_int_allf.c \
+ get_varm_realf.c get_varm_real_allf.c \
+ get_varm_doublef.c get_varm_double_allf.c \
+ get_varm_int8f.c get_varm_int8_allf.c \
+ waitf.c \
+ wait_allf.c \
+ cancelf.c \
+ iput_var1f.c \
+ iput_var1_textf.c \
+ iput_var1_int1f.c \
+ iput_var1_int2f.c \
+ iput_var1_intf.c \
+ iput_var1_realf.c \
+ iput_var1_doublef.c \
+ iput_var1_int8f.c \
+ iget_var1f.c \
+ iget_var1_textf.c \
+ iget_var1_int1f.c \
+ iget_var1_int2f.c \
+ iget_var1_intf.c \
+ iget_var1_realf.c \
+ iget_var1_doublef.c \
+ iget_var1_int8f.c \
+ bput_var1f.c \
+ bput_var1_textf.c \
+ bput_var1_int1f.c \
+ bput_var1_int2f.c \
+ bput_var1_intf.c \
+ bput_var1_realf.c \
+ bput_var1_doublef.c \
+ bput_var1_int8f.c \
+ iput_varf.c \
+ iput_var_textf.c \
+ iput_var_int1f.c \
+ iput_var_int2f.c \
+ iput_var_intf.c \
+ iput_var_realf.c \
+ iput_var_doublef.c \
+ iput_var_int8f.c \
+ iget_varf.c \
+ iget_var_textf.c \
+ iget_var_int1f.c \
+ iget_var_int2f.c \
+ iget_var_intf.c \
+ iget_var_realf.c \
+ iget_var_doublef.c \
+ iget_var_int8f.c \
+ bput_varf.c \
+ bput_var_textf.c \
+ bput_var_int1f.c \
+ bput_var_int2f.c \
+ bput_var_intf.c \
+ bput_var_realf.c \
+ bput_var_doublef.c \
+ bput_var_int8f.c \
+ iput_varaf.c \
+ iput_vara_textf.c \
+ iput_vara_int1f.c \
+ iput_vara_int2f.c \
+ iput_vara_intf.c \
+ iput_vara_realf.c \
+ iput_vara_doublef.c \
+ iput_vara_int8f.c \
+ iget_varaf.c \
+ iget_vara_textf.c \
+ iget_vara_int1f.c \
+ iget_vara_int2f.c \
+ iget_vara_intf.c \
+ iget_vara_realf.c \
+ iget_vara_doublef.c \
+ iget_vara_int8f.c \
+ bput_varaf.c \
+ bput_vara_textf.c \
+ bput_vara_int1f.c \
+ bput_vara_int2f.c \
+ bput_vara_intf.c \
+ bput_vara_realf.c \
+ bput_vara_doublef.c \
+ bput_vara_int8f.c \
+ iput_varsf.c \
+ iput_vars_textf.c \
+ iput_vars_int1f.c \
+ iput_vars_int2f.c \
+ iput_vars_intf.c \
+ iput_vars_realf.c \
+ iput_vars_doublef.c \
+ iput_vars_int8f.c \
+ iget_varsf.c \
+ iget_vars_textf.c \
+ iget_vars_int1f.c \
+ iget_vars_int2f.c \
+ iget_vars_intf.c \
+ iget_vars_realf.c \
+ iget_vars_doublef.c \
+ iget_vars_int8f.c \
+ bput_varsf.c \
+ bput_vars_textf.c \
+ bput_vars_int1f.c \
+ bput_vars_int2f.c \
+ bput_vars_intf.c \
+ bput_vars_realf.c \
+ bput_vars_doublef.c \
+ bput_vars_int8f.c \
+ iput_varmf.c \
+ iput_varm_textf.c \
+ iput_varm_int1f.c \
+ iput_varm_int2f.c \
+ iput_varm_intf.c \
+ iput_varm_realf.c \
+ iput_varm_doublef.c \
+ iput_varm_int8f.c \
+ iget_varmf.c \
+ iget_varm_textf.c \
+ iget_varm_int1f.c \
+ iget_varm_int2f.c \
+ iget_varm_intf.c \
+ iget_varm_realf.c \
+ iget_varm_doublef.c \
+ iget_varm_int8f.c \
+ bput_varmf.c \
+ bput_varm_textf.c \
+ bput_varm_int1f.c \
+ bput_varm_int2f.c \
+ bput_varm_intf.c \
+ bput_varm_realf.c \
+ bput_varm_doublef.c \
+ bput_varm_int8f.c \
+ bufattachf.c \
+ bufdetachf.c \
+ inq_buffer_usagef.c \
+ inq_buffer_sizef.c \
+ inq_put_sizef.c \
+ inq_get_sizef.c \
+ inq_header_sizef.c \
+ inq_header_extentf.c \
+ inq_malloc_sizef.c inq_malloc_max_sizef.c inq_malloc_listf.c \
+ inq_files_openedf.c \
+ inq_nreqsf.c \
+ inq_recsizef.c \
+ get_varnf.c get_varn_allf.c \
+ get_varn_textf.c get_varn_text_allf.c \
+ get_varn_int1f.c get_varn_int1_allf.c \
+ get_varn_int2f.c get_varn_int2_allf.c \
+ get_varn_intf.c get_varn_int_allf.c \
+ get_varn_realf.c get_varn_real_allf.c \
+ get_varn_doublef.c get_varn_double_allf.c \
+ get_varn_int8f.c get_varn_int8_allf.c \
+ put_varnf.c put_varn_allf.c \
+ put_varn_textf.c put_varn_text_allf.c \
+ put_varn_int1f.c put_varn_int1_allf.c \
+ put_varn_int2f.c put_varn_int2_allf.c \
+ put_varn_intf.c put_varn_int_allf.c \
+ put_varn_realf.c put_varn_real_allf.c \
+ put_varn_doublef.c put_varn_double_allf.c \
+ put_varn_int8f.c put_varn_int8_allf.c \
+ iget_varnf.c \
+ iget_varn_textf.c \
+ iget_varn_int1f.c \
+ iget_varn_int2f.c \
+ iget_varn_intf.c \
+ iget_varn_realf.c \
+ iget_varn_doublef.c \
+ iget_varn_int8f.c \
+ iput_varnf.c \
+ iput_varn_textf.c \
+ iput_varn_int1f.c \
+ iput_varn_int2f.c \
+ iput_varn_intf.c \
+ iput_varn_realf.c \
+ iput_varn_doublef.c \
+ iput_varn_int8f.c \
+ bput_varnf.c \
+ bput_varn_textf.c \
+ bput_varn_int1f.c \
+ bput_varn_int2f.c \
+ bput_varn_intf.c \
+ bput_varn_realf.c \
+ bput_varn_doublef.c \
+ bput_varn_int8f.c \
+ get_vardf.c get_vard_allf.c \
+ put_vardf.c put_vard_allf.c
+
+LIB_CSRCS = $(C2F_SRCS) $(UTIL_SRCS)
+
+LIB_FSRCS = strerrorf.f inq_libversf.f
+
+PACKING_LIST = $(LIB_FSRCS) \
+ nfconfig_inc.in \
+ pnetcdf.inc.in \
+ mpinetcdf_impl.h \
+ buildiface \
+ defs \
+ createffiles \
+ Makefile.in
+
+LIB_OBJS = $(LIB_CSRCS:.c=.o) $(LIB_FSRCS:.f=.o)
+
+GARBAGE = nfconfig.inc $(LIB_CSRCS) mpifnetcdf.h
+DIST_GARBAGE = nfconfig_inc pnetcdf.inc
+
+all: $(LIB_CSRCS) nfconfig.inc $(LIBRARY)
+
+library $(LIBRARY): $(LIB_OBJS)
+ $(AR) $(ARFLAGS) $(LIBRARY) $(LIB_OBJS)
+ $(RANLIB) $(LIBRARY)
+
+$(LIB_CSRCS): mpifnetcdf.h
+$(LIB_OBJS): mpifnetcdf.h
+
+mpifnetcdf.h: defs buildiface $(HEADER)
+ $(srcdir)/buildiface -infile=$(HEADER) -deffile=$(srcdir)/defs
+
+# Starting from 1.4.0, nfconfig.inc is only used in test/nf_test/tests.inc and
+# test/nf90_test/tests.inc
+#
+# the sed command below is for generating a fortran-friendly header files by
+# replacing C comment starter '/*' with '!' in Fortran and remove '*/'
+#
+nfconfig.inc: nfconfig_inc
+ $(RM) -f $@
+ $(SED) -e "s%/\*%!%g" -e "s%\*/%%g" $< > $@
+
+install:
+ $(INSTALL) -d -m 755 $(INCDIR)
+ $(INSTALL_DATA) pnetcdf.inc $(INCDIR)
+
+uninstall:
+ $(RM) -f $(INCDIR)/pnetcdf.inc
+
+include $(srcdir)/../../rules.make
diff --git a/src/libf/buildiface b/src/libf/buildiface
new file mode 100755
index 0000000..22eade4
--- /dev/null
+++ b/src/libf/buildiface
@@ -0,0 +1,4068 @@
+#! /usr/bin/env perl
+#
+# This file builds candidate interface files from the descriptions in
+# mpi.h
+#
+# Here are the steps:
+# 1) Find the prototypes in mpi.h.in (Look for *Begin Prototypes*)
+# 2) For each function, match the name and args:
+# int MPI_xxxx( ... )
+# 3) Create a new file with the name lc(xxxx)f.c (lowercase of name),
+# containing
+# Copyright
+# Profiling block indicator
+# Fortran name version of function, with MPI objects replaced by
+# MPI_Fint etc. as appropriate
+#
+#
+
+use warnings;
+
+# Setup global variables
+%CtoFName = ();
+ at ExtraRoutines = ();
+
+$buildfiles = 1;
+$build_prototypes = 1;
+$buildMakefile = 1;
+$prototype_header_file = "fproto.h";
+$build_io = 1;
+$print_line_len = 0;
+$write_mpif = 1;
+$is_MPI = 1;
+$do_profiling = 1;
+$routine_prefix = "MPI_";
+$routine_pattern = "[A-Z][a-z0-9_]*";
+$out_prefix="mpi_";
+$malloc = "MPIU_Malloc";
+$free = "MPIU_Free";
+$header_file = "mpi_fortimpl.h";
+$debug = 0;
+$writeRoutineList = 0; # Set to 1 to get a list of MPI routines
+
+ at arg_addresses = ();
+#
+# Error return handling
+$errparmtype = "MPI_Fint *";
+$errparm = "MPI_Fint *ierr";
+$errparmlval = "*ierr";
+$errparmrval = "*ierr";
+$returnErrval = 0;
+$returnType = "void";
+
+%altweak = (); # Alternate weak declarations
+%altweakrtype = ();
+
+#feature variables
+$do_logical = 1;
+$do_weak = 1;
+$do_subdecls = 1;
+$do_bufptr = 1;
+$prototype_file = "../../include/mpi.h.in";
+
+# Global hashes used for definitions and to record the locations of the
+# defintions.
+%mpidef = ();
+%mpidefFile = ();
+%mpiRoutinesFile = ();
+
+# Handle special initializations
+#
+# Notes on this string. Some symbols need to be initialized at runtime.
+# These are typically the addresses of the "special" Fortran symbols,
+# such as MPIR_F_MPI_BOTTOM. Because MPI-2 requires that MPI_Init and
+# MPI_Init_thread, called in *any* language, initalize MPI for *all*
+# languages, we can't depend on having the Fortran versions of MPI_Init or
+# MPI_Init_thread called before these values might be used in a Fortran
+# wrapper function.
+# We also cannot have the C version of MPI_Init and MPI_Init_thread call
+# the initialization routine, because some Fortran compilers will require
+# special routines from that particular vendors Fortran runtime library for
+# any executable that uses routines that are compiled with the Fortran
+# compiler, forcing user programs that are entirely C to link with the
+# Fortran runtime. Thus, we must check whether the values are initialized
+# before any use in any routine.
+#
+# Having said the above, however, if the environment (specifically, the
+# C and Fortran compilers) makes it easy for the C init routines to initialize
+# the Fortran environment, then we should make that easy. This is indicated
+# by the CPP name HAVE_MPI_F_INIT_WORKS_WITH_C. If that is defined, then
+# there is no lazy initialization of these values.
+$specialInitAdded = 0;
+$specialInitString = "\
+#ifndef HAVE_MPI_F_INIT_WORKS_WITH_C
+ if (MPIR_F_NeedInit){ mpirinitf_(); MPIR_F_NeedInit = 0; }
+#endif";
+
+# Process arguments
+#
+# Args
+# -feature={logical,fint,subdecls,weak,bufptr}, separated by :, value given
+# by =on or =off, eg
+# -feature=logical=on:fint=off
+# The feature names mean:
+# logical - Fortran logicals are converted to/from C
+# fint - Fortran integers and C ints are different size (not implemented)
+# subdecls - Declarations for PC-Fortran compilers added
+# weak - Use weak symbols
+# bufptr - Check for MPI_BOTTOM as a special address. This is
+# not needed if a POINTER declaration is available.
+foreach $_ (@ARGV) {
+ if (/-noprototypes/) { $build_prototypes = 0; }
+ elsif (/-infile=(.*)/) {
+ # Special arg to help with debugging
+ $prototype_file = $1;
+ $write_mpif = 0;
+ $build_prototypes = 0;
+ $do_weak = 0;
+ }
+ elsif (/-noromio/) { $build_io = 0; }
+ elsif (/-debug/) {
+ $debug = 1;
+ }
+ elsif (/-prefix=(.*)/) {
+ $routine_prefix = $1;
+ $is_MPI = 0;
+ }
+ elsif (/-pattern=(.*)/) {
+ $routine_pattern = $1;
+ }
+ elsif (/-feature=(.*)/) {
+ foreach $feature (split(/:/,$1)) {
+ print STDERR "Processing feature $feature\n" if $debug;
+ # Feature values are foo=on,off
+ ($name,$value) = split(/=/,$feature);
+ if ($value eq "on") { $value = 1; }
+ elsif ($value eq "off") { $value = 0; }
+ # Set the variable based on the string
+ $varname = "do_$name";
+ $$varname = $value;
+ }
+ }
+ elsif (/deffile=(.*)/) {
+ $definition_file = $1;
+ $is_MPI = 0;
+ }
+ else {
+ print STDERR "Unrecognized argument $_\n";
+ }
+}
+
+# Note that the code that looks up values strips blanks out of the type name
+# No blanks should be used in the key.
+%tof77 = ( 'MPI_Datatype' => 'MPI_Fint *',
+ 'MPI_Comm' => 'MPI_Fint *',
+#MPI_File must be handled specially, since ROMIO still uses pointers
+ 'MPI_File' => 'MPI_Fint *',
+ 'MPI_Win' => 'MPI_Fint *',
+ 'MPI_Request' => 'MPI_Fint *',
+ 'MPI_Group' => 'MPI_Fint *',
+ 'MPI_Op' => 'MPI_Fint *',
+ 'MPI_Info' => 'MPI_Fint *',
+ 'MPI_Errhandler' => 'MPI_Fint *',
+ 'MPI_Aint' => 'MPI_Fint *', # Should be MPIR_FAint
+ 'MPI_FAintp' => 'MPI_Aint *', # Used to force an MPI_Aint*
+ 'MPI_Offset' => 'MPI_Offset *', # Should be MPIR_FOint
+ 'int' => 'MPI_Fint *',
+ 'int[]' => 'MPI_Fint', # no * because we'll use array form
+ 'int[][3]' => 'MPI_Fint', # no * because we'll use array form
+ 'MPI_Datatype*' => 'MPI_Fint *',
+ 'MPI_Datatype[]' => 'MPI_Fint', # no * because we'll use array form
+ 'MPI_Comm*' => 'MPI_Fint *',
+ 'MPI_File*' => 'MPI_Fint *',
+ 'MPI_Win*' => 'MPI_Fint *',
+ 'MPI_Group*' => 'MPI_Fint *',
+ 'MPI_Request*' => 'MPI_Fint *',
+ 'MPI_Aint*' => 'MPI_Fint *', # Should be MPIR_FAint
+ 'int *' => 'MPI_Fint *',
+ 'int*' => 'MPI_Fint *', # Catch missing space
+ 'MPI_Op*' => 'MPI_Fint *',
+ 'MPI_Status*' => 'MPI_Fint *',
+ 'MPI_Info*' => 'MPI_Fint *',
+ 'MPI_Errhandler*' => 'MPI_Fint *',
+ );
+
+# declarg is special parameters for certain routines
+%declarg = ( 'type_extent-2' => 'MPI_Fint *',
+ 'type_lb-2' => 'MPI_Fint *',
+ 'type_ub-2' => 'MPI_Fint *',
+ 'type_struct-3' => 'MPI_Fint *', # Really [], but * is easier
+ 'type_hindexed-3' => 'MPI_Fint *', # As above
+ 'type_hvector-3' => 'MPI_Fint *',
+ # The following are MPI-2 routines with address args.
+ # For these, the user must pass in the correct arguments
+ 'file_get_type_extent-3' => 'MPI_FAint *',
+ 'pack_external-6' => 'MPI_Aint *', # Value in C call
+ 'pack_external-7' => 'MPI_Aint *',
+ 'pack_external_size-4' => 'MPI_Aint *',
+ 'type_create_hvector-3' => 'MPI_Aint *', # Value in C call
+ 'type_create_hindexed-3' => 'MPI_Aint *',
+ 'type_create_struct-3' => 'MPI_Aint *',
+ 'type_get_contents-6' => 'MPI_Aint *',
+ 'type_get_extent-2' => 'MPI_Aint *',
+ 'type_get_extent-3' => 'MPI_Aint *',
+ 'type_get_true_extent-2' => 'MPI_Aint *',
+ 'type_get_true_extent-3' => 'MPI_Aint *',
+ 'type_create_resized-2' => 'MPI_Aint *', # Value in C call
+ 'type_create_resized-3' => 'MPI_Aint *', # Value in C call
+ 'unpack_external-3' => 'MPI_Aint *', # Value in C call
+ 'unpack_external-4' => 'MPI_Aint *',
+ 'win_create-2' => 'MPI_Aint *',
+ 'accumulate-5' => 'MPI_Aint *',
+ 'put-5' => 'MPI_Aint *',
+ 'get-5' => 'MPI_Aint *',
+ 'alloc_mem-1' => 'MPI_Aint *',
+ );
+
+%argsneedcast = ( 'MPI_Request *' => '(MPI_Request *)(ARG)',
+ 'MPI_Status *' => '(MPI_Status *)(ARG)',
+ 'MPI_File' => 'MPI_File_f2c(ARG)',
+ 'MPI_Comm' => '(MPI_Comm)(ARG)',
+ 'MPI_Comm *' => '(MPI_Comm *)(ARG)',
+ 'MPI_Datatype' => '(MPI_Datatype)(ARG)',
+ 'MPI_Datatype *' => '(MPI_Datatype *)(ARG)',
+ 'MPI_Info *' => '(MPI_Info *)(ARG)',
+ 'MPI_Info' => '(MPI_Info)(ARG)',
+ 'int [][3]' => '(int (*)[3])(ARG)'
+);
+
+##
+## For implementations other than MPICH2, we'll need to consider using
+## MPI_C2f_<name> and MPI_F2c_<name>, as in
+## 'MPI_Info' => 'MPI_F2c_info(ARG)'
+##
+# name_map maps the filenames. Most filenames are created automatically
+# from the routine name, but some names have too many characters (15,
+# including the extension(.o) is a limit for ar in some systems).
+%name_map = ( 'add_error_class' => 'adderrclass',
+ 'add_error_code' => 'adderrcode',
+ 'add_error_string' => 'adderrstring',
+ 'buffer_attach' => 'bufattach',
+ 'buffer_detach' => 'bufdetach',
+ 'comm_call_errhandler' => 'commcallerr',
+ 'comm_create_errhandler' => 'commcreerr',
+ 'comm_create_keyval' => 'commnewkey',
+ 'comm_delete_attr' => 'commdelattr',
+ 'comm_disconnect' => 'commdisc',
+ 'comm_free_keyval' => 'commfreekey',
+ 'comm_get_errhandler' => 'commgeterr',
+ 'comm_get_name' => 'commgetnam',
+ 'comm_get_parent' => 'commparent',
+ 'comm_remote_group' => 'commrgroup',
+ 'comm_remote_size' => 'commrsize',
+ 'comm_set_errhandler' => 'commseterr',
+ 'comm_spawn_multiple' => 'spawnmult',
+ 'comm_test_inter' => 'commtestic',
+ 'errhandler_create' => 'errhcreate',
+ 'errhandler_free' => 'errhfree',
+ 'errhandler_get' => 'errhget',
+ 'errhandler_set' => 'errhset',
+ 'file_call_errhandler' => 'filecallerr',
+ 'file_create_errhandler' => 'filecreerr',
+ 'file_get_errhandler' => 'filegeterr',
+ 'file_set_errhandler' => 'fileseterr',
+ 'get_processor_name' => 'getpname',
+ 'graph_neighbors_count' => 'grfnbcount',
+ 'graph_neighbors' => 'grfnbrs',
+ 'grequest_complete' => 'greqcomplete',
+ 'grequest_start' => 'greqstart',
+ 'group_difference' => 'groupdiff',
+ 'group_intersection' => 'groupinter',
+ 'group_range_excl' => 'grouprexcl',
+ 'group_range_incl' => 'grouprincl',
+ 'group_translate_ranks' => 'grouptranks',
+ 'info_get_nkeys' => 'infognk',
+ 'info_get_nthkey' => 'infognthk',
+ 'info_get_valuelen' => 'infovallen',
+ 'intercomm_create' => 'iccreate',
+ 'intercomm_merge' => 'icmerge',
+ 'is_thread_main' => 'isthrmain',
+ 'pack_external_size' => 'packesize',
+ 'reduce_scatter' => 'redscat',
+ 'request_get_status' => 'reqgetstat',
+ 'sendrecv_replace' => 'sndrcvrpl',
+ 'status_set_cancelled' => 'statgetcl',
+ 'status_set_elements' => 'statsetel',
+ 'test_cancelled' => 'testcancel',
+ 'type_contiguous' => 'typecontig',
+ 'type_create_darray' => 'typedarray',
+ 'type_create_f90_integer' => 'typef90int',
+ 'type_create_f90_real' => 'typef90real',
+ 'type_create_f90_complex' => 'typef90cmplx',
+ 'type_create_hindexed' => 'typechind',
+ 'type_create_hvector' => 'typechvec',
+ 'type_create_indexed_block' => 'typecindb',
+ 'type_create_keyval' => 'typenewkey',
+ 'type_create_resized' => 'typecresize',
+ 'type_create_struct' => 'typecstruct',
+ 'type_create_subarray' => 'typecsubarr',
+ 'type_delete_attr' => 'typedelattr',
+ 'type_free_keyval' => 'typefreekey',
+ 'type_get_contents' => 'typegetcnts',
+ 'type_get_envelope' => 'typegetenv',
+ 'type_get_extent' => 'typegetextent', # there is already a type_extent
+ 'type_get_name' => 'typegname',
+ 'type_get_true_extent' => 'typegtext',
+ 'type_set_attr' => 'typesetattr',
+ 'type_set_name' => 'typesetname',
+ 'unpack_external' => 'unpackext',
+ 'unpublish_name' => 'unpubname',
+ 'win_call_errhandler' => 'wincallerr',
+ 'win_create_errhandler' => 'wincreerr',
+ 'win_create_keyval' => 'winnewkey',
+ 'win_delete_attr' => 'windelattr',
+ 'win_free_keyval' => 'winfreekey',
+ 'win_get_errhandler' => 'wingeterr',
+ 'win_set_errhandler' => 'winseterr',
+);
+
+#
+# Special routines have very different calling seqences in C and Fortran
+# or different behavior.
+# Init and Init thread have different arg lists (no argc, argv)
+# Pcontrol has no varargs
+# Address and Get_address require special integer types and
+# possibly handling for MPI_BOTTOM
+# Keyval routines require setting the language to Fortran (Attribute
+# routines are handled with the special argument processing)
+#
+# The Type_create_f90_xxx routines are only available as part of the
+# extended Fortran support, and are excluded from the f77 routines.
+%special_routines = ( 'Init' => 1, 'Init_thread' => 1, 'Pcontrol' => '1',
+ 'Address' => 1, 'Get_address' => 1,
+ 'Keyval_create' => 1, 'Status_f2c' => 1,
+ 'Status_c2f' => 1,
+ 'Type_create_f90_integer' => 1,
+ 'Type_create_f90_real' => 1,
+ 'Type_create_f90_complex' => 1,
+ );
+
+# Some routines have special needs and must call a different routine. For
+# similicity, we make the requirement that the replacement routine take
+# all of the arguments of the original routine, but all additional arguments
+# at the end. This is used with the attribute routines which must
+# pass an additional argument to a special attribute routine that handles
+# the differences between C and Fortran attributes.
+%ChangeCall = ( 'Comm_get_attr' => 'MPIR_CommGetAttr:!MPIR_ATTR_AINT' ,
+ 'Type_get_attr' => 'MPIR_TypeGetAttr:!MPIR_ATTR_AINT',
+ 'Win_get_attr' => 'MPIR_WinGetAttr:!MPIR_ATTR_AINT',
+ 'Attr_get' => 'MPIR_CommGetAttr:!MPIR_ATTR_INT',
+ 'Comm_set_attr' => 'MPIR_CommSetAttr:!MPIR_ATTR_AINT',
+ 'Type_set_attr' => 'MPIR_TypeSetAttr:!MPIR_ATTR_AINT',
+ 'Win_set_attr' => 'MPIR_WinSetAttr:!MPIR_ATTR_AINT',
+ 'Attr_put' => 'MPIR_CommSetAttr:!MPIR_ATTR_INT',
+ );
+#
+# Note that wtime and wtick aren't found because they don't match the
+# int MPI_xxx format. They're handled directly by the special routine
+# code below
+
+#
+# Most routines can be processed automatically. However, some
+# require some special processing. For example, those routines with
+# LOGICAL arguments need some special handling. To detect this, there
+# are two entries in a %special_args hash: the routine name, and the routine
+# name -arg#. E.g., for MPI_Test, the hash has keys
+# "Test" and "Test-2". The value for "Test-2" is "out:logical"; this
+# indicates that the variable is an out variable with logical type.
+# Processing types (the second field after the :) are
+# logical: convert to/from Fortran and C representations of logical
+# index: convert to/from Fortran (1-based) and C (0-based) origins
+# array: handle arrays of items that may have different lengths
+# in C and Fortran because the integer types have
+# different sizes. The term has an additional :expression,
+# the third term give the array size.
+# addnull: Add a null character to a *copy* of the input string,
+# after trimming any blanks.
+# blankpad: Add blanks and remove nulls. Only used for out args;
+# must use an allocated space to provide room for the null
+# that the C routines may require
+# bufptr: Detect MPI_BOTTOM. Note that a better alternative is to
+# use MPI_Address and MPI_Get_address to make addresses
+# relative to the Fortran MPI_BOTTOM. The lines that
+# define this are commented out below.
+# addrint: Given the address of an int, provide the int. Used
+# for attr_put/set routines
+# attrint: Convert an attribute value to an int.
+# addraint: Given the address of an address-sized int, provide the
+# value of that item. Used for the MPI-2 versions of the
+# attribute caching routines
+# bufaddr: Argument is *output* as a buffer address. Discarded before
+# passing to Fortran.
+# For MPI-2 routines that take MPI_Aints even in Fortran, we need a
+# special mapping when the value is passed to c
+# aintToVal: Given the address of an Aint, pass the value to the C routine
+# (This should really be done by not applying the Aint->int mapping
+# for MPI-2 routines. But for now, this hack will work)
+%special_args = (
+# 'Allreduce' => '1:2', 'Allreduce-1' => 'in:bufptr',
+# 'Allreduce-2' => 'in:bufptr',
+# 'Bcast' => '1', 'Bcast-1' => 'in:bufptr',
+# 'Gather' => '1:4', 'Gather-1' => 'in:bufptr', 'Gather-4' => 'in:bufptr',
+# 'Gatherv' => '1:4', 'Gatherv-1' => 'in:bufptr', 'Gatherv-4' => 'in:bufptr',
+# 'Scatter' => '1:4', 'Scatter-1' => 'in:bufptr', 'Scatter-4' => 'in:bufptr',
+# 'Scatterv' => '1:5', 'Scatterv-1' => 'in:bufptr', 'Scatterv-5' => 'in:bufptr',
+# 'Allgather' => '1:4', 'Allgather-1' => 'in:bufptr', 'Allgather-4' => 'in:bufptr',
+# 'Allgatherv' => '1:4', 'Allgatherv-1' => 'in:bufptr', 'Allgatherv-4' => 'in:bufptr',
+# 'Alltoall' => '1:4', 'Alltoall-1' => 'in:bufptr', 'Alltoall-4' => 'in:bufptr',
+# 'Alltoallv' => '1:5', 'Alltoallv-1' => 'in:bufptr', 'Alltoallv-5' => 'in:bufptr',
+# 'Reduce' => '1:2', 'Reduce-1' => 'in:bufptr', 'Reduce-2' => 'in:bufptr',
+# 'Reduce_scatter' => '1:2', 'Reduce_scatter-1' => 'in:bufptr',
+# 'Reduce_scatter-2' => 'in:bufptr',
+# 'Scan' => '1:2', 'Scan-1' => 'in:bufptr', 'Scan-2' => 'in:bufptr',
+#
+ 'Gather' => '1', 'Gather-1' => 'in:inplace',
+ 'Gatherv' => '1', 'Gatherv-1' => 'in:inplace',
+ 'Scatter' => '4', 'Scatter-4' => 'in:inplace',
+ 'Scatterv' => '5', 'Scatterv-5' => 'in:inplace',
+ 'Allgather' => '1', 'Allgather-1' => 'in:inplace',
+ 'Allgatherv' => '1', 'Allgatherv-1' => 'in:inplace',
+ 'Reduce' => '1', 'Reduce-1' => 'in:inplace',
+ 'Allreduce' => '1', 'Allreduce-1' => 'in:inplace',
+ 'Reduce_scatter' => '1', 'Reduce_scatter-1' => 'in:inplace',
+ 'Scan' => '1', 'Scan-1' => 'in:inplace',
+
+
+ 'Add_error_string' => '2', 'Add_error_string-2' => 'in:addnull',
+ 'Attr_put' => '3', 'Attr_put-3' => 'in:addrint',
+ 'Attr_get' => '3:4', 'Attr_get-4' => 'out:logical',
+ 'Attr_get-3' => 'out:attrint:4',
+ 'Comm_set_attr' => '3', 'Comm_set_attr-3' => 'in:addraint',
+ 'Type_set_attr' => '3', 'Type_set_attr-3' => 'in:addraint',
+ 'Win_set_attr' => '3', 'Win_set_attr-3' => 'in:addraint',
+ 'Comm_get_attr' => '3:4', 'Comm_get_attr-4' => 'out:logical',
+ 'Comm_get_attr-3' => 'out:attraint:4',
+ 'Type_get_attr' => '3:4', 'Type_get_attr-4' => 'out:logical',
+ 'Type_get_attr-3' => 'out:attraint:4',
+ 'Win_get_attr' => '3:4', 'Win_get_attr-4' => 'out:logical',
+ 'Win_get_attr-3' => 'out:attraint:4',
+ 'Buffer_detach' => '1', 'Buffer_detach-1' => 'out:bufaddr',
+ 'Cart_create' => '4:5', 'Cart_create-4' => 'in:logical_array:*v2',
+ 'Cart_create-5' => 'in:logical',
+ 'Cart_get' => '4', 'Cart_get-4' => 'out:logical_array:*v2',
+ 'Comm_accept' => '1', 'Comm_accept-1' => 'in:addnull',
+ 'Comm_connect' => '1', 'Comm_connect-1' => 'in:addnull',
+ 'Comm_get_name' => '2', 'Comm_get_name-2' => 'out:blankpad',
+ 'Comm_set_name' => '2', 'Comm_set_name-2' => 'in:addnull',
+ 'Comm_spawn' => '1:2:8', 'Comm_spawn-1' => 'in:addnull',
+ 'Comm_spawn-2' => 'in:chararray',
+ 'Comm_spawn-8' => 'in:errcodesignore',
+ 'Comm_test_inter' => '2', 'Comm_test_inter-2' => 'out:logical',
+ 'Get_processor_name' => '1', 'Get_processor_name-1' => 'out:blankpad',
+ 'Error_string' => '2', 'Error_string-2' => 'out:blankpad',
+ 'Intercomm_merge' => '2', 'Intercomm_merge-2' => 'in:logical',
+ 'Info_get' => '2:4:5', 'Info_get-2' => 'in:addnull',
+ 'Info_get-4' => 'out:blankpadonflag:l5',
+ 'Info_get-5' => 'out:logical',
+ 'Info_set' => '2:3', 'Info_set-2' => 'in:addnullandtrim',
+ 'Info_set-3' => 'in:addnullandtrim',
+ 'Info_get_nthkey' => '3', 'Info_get_nthkey-3' => 'out:blankpad',
+ 'Info_get_valuelen' => '2:4', 'Info_get_valuelen-2' => 'in:addnull',
+ 'Info_get_valuelen-4' => 'out:logical',
+ 'Info_delete' => '2', 'Info_delete-2' => 'in:addnull',
+ 'Lookup_name' => '1:3', 'Lookup_name-1' => 'in:addnull',
+ 'Lookup_name-3' => 'out:blankpad',
+ 'Open_port' => '2', 'Open_port-2' => 'out:blankpad',
+ 'Close_port' => '1', 'Close_port-1' => 'in:addnull',
+ 'Pack_external' => '1:6', 'Pack_external-1' => 'in:addnull',
+ 'Pack_external-6' => 'in:aintToVal',
+ 'Pack_external_size' => '1', 'Pack_external_size-1' => 'in:addnull',
+ 'Publish_name' => '1:3', 'Publish_name-1' => 'in:addnull',
+ 'Publish_name-3' => 'in:addnull',
+# comm spawn multiple needs slightly different routines
+ 'Comm_spawn_multiple' => '2:3:9',
+ 'Comm_spawn_multiple-2' => 'in:chararray:*v1',
+ 'Comm_spawn_multiple-3' => 'in:chararray2:*v1',
+ 'Comm_spawn_multiple-9' => 'in:errcodesignore',
+ 'Initialized' => '1', 'Initialized-1' => 'out:logical',
+ 'Iprobe' => '4:5', 'Iprobe-4' => 'out:logical',
+ 'Iprobe-5' => 'in:status',
+ 'Probe' => '4', 'Probe-4' => 'in:status',
+ 'Recv' => '7', 'Recv-7' => 'in:status',
+ 'Sendrecv' => '12', 'Sendrecv-12' => 'in:status',
+ 'Sendrecv_replace' => '9', 'Sendrecv_replace-9' => 'in:status',
+# 'Send' => '1', 'Send-1' => 'in:bufptr',
+# 'Ssend' => '1', 'Ssend-1' => 'in:bufptr',
+# 'Rsend' => '1', 'Rsend-1' => 'in:bufptr',
+# 'Bsend' => '1', 'Bsend-1' => 'in:bufptr',
+# 'Isend' => '1', 'Isend-1' => 'in:bufptr',
+# 'Issend' => '1', 'Issend-1' => 'in:bufptr',
+# 'Irsend' => '1', 'Irsend-1' => 'in:bufptr',
+# 'Ibsend' => '1', 'Ibsend-1' => 'in:bufptr',
+# 'Irecv' => '1', 'Irecv-1' => 'in:bufptr',
+# 'Recv' => '1', 'Recv-1' => 'in:bufptr',
+# 'Send_init' => '1', 'Send_init-1' => 'in:bufptr',
+# 'Bsend_init' => '1', 'Bsend_init-1' => 'in:bufptr',
+# 'Ssend_init' => '1', 'Ssend_init-1' => 'in:bufptr',
+# 'Rsend_init' => '1', 'Rsend_init-1' => 'in:bufptr',
+# 'Recv_init' => '1', 'Recv_init-1' => 'in:bufptr',
+# 'Sendrecv' => '1:6', 'Sendrecv-1' => 'in:bufptr', 'Sendrecv-6' => 'in:bufptr',
+# 'Sendrecv_replace' => '1', 'Sendrecv_replace-1' => 'in:bufptr',
+ 'Test_cancelled' => '2', 'Test_cancelled-2' => 'out:logical',
+ 'Test' => '2:3', 'Test-2' => 'out:logical',
+ 'Test-3' => 'in:status',
+ 'Testall' => '3:4', 'Testall-3' => 'out:logical',
+ 'Testall-4' => 'in:status_array',
+ 'Testany' => '3:4:5', 'Testany-4' => 'out:logical',
+ 'Testany-3' => 'out:index',
+ 'Testany-5' => 'in:status',
+ 'Testsome' => '4:5', 'Testsome-4' => 'out:index_array:*v3',
+ 'Testsome-5' => 'in:status_array',
+ 'Type_create_hvector' => 3, 'Type_create_hvector-3' => 'in:aintToVal',
+ 'Type_create_resized' => '2:3',
+ 'Type_create_resized-2' => 'in:aintToVal',
+ 'Type_create_resized-3' => 'in:aintToVal',
+ 'Type_get_name' => '2', 'Type_get_name-2' => 'out:blankpad',
+ 'Type_set_name' => '2', 'Type_set_name-2' => 'in:addnull',
+ 'Type_extent' => '2', 'Type_extent-2' => 'out:aintToInt',
+ 'Type_lb' => '2', 'Type_lb-2' => 'out:aintToInt',
+ 'Type_ub' => '2', 'Type_ub-2' => 'out:aintToInt',
+ 'Type_struct' => '3', 'Type_struct-3' => 'in:intToAintArr:*v1',
+ 'Type_hindexed' => '3', 'Type_hindexed-3' => 'in:intToAintArr:*v1',
+# also need
+ 'Type_hvector' => '3', 'Type_hvector-3' => 'in:intToAint',
+ 'Unpack_external' => '1:3', 'Unpack_external-1' => 'in:addnull',
+ 'Unpack_external-3' => 'in:aintToVal',
+ 'Unpublish_name' => '1:3', 'Unpublish_name-1' => 'in:addnull',
+ 'Unpublish_name-3' => 'in:addnull',
+ 'Win_create' => '2', 'Win_create-2' => 'in:aintToVal',
+ 'Accumulate' => '5', 'Accumulate-5' => 'in:aintToVal',
+ 'Put' => '5', 'Put-5' => 'in:aintToVal',
+ 'Get' => '5', 'Get-5' => 'in:aintToVal',
+ 'Alloc_mem' => '1', 'Alloc_mem-1' => 'in:aintToVal',
+ 'Win_get_name' => '2', 'Win_get_name-2' => 'out:blankpad',
+ 'Win_set_name' => '2', 'Win_set_name-2' => 'in:addnull',
+ 'Wait' => '2', 'Wait-2' => 'in:status',
+ 'Waitall' => '3', 'Waitall-3' => 'in:status_array',
+ 'Waitany' => '3:4', 'Waitany-3' => 'out:index',
+ 'Waitany-4' => 'in:status',
+ 'Waitsome' => '4:5', 'Waitsome-4' => 'out:index_array:*v3',
+ 'Waitsome-5' => 'in:status_array',
+# File routines are separate
+ 'File_open' => '2:5', 'File_open-2' => 'in:addnull',
+ 'File_open-5' => 'out:FileToFint',
+ 'File_close' => '1', 'File_close-1', 'inout:FileToFint',
+ 'File_delete' => '1', 'File_delete-1' => 'in:addnull',
+ 'File_set_view' => '5', 'File_set_view-5' => 'in:addnull',
+ 'File_get_view' => '5', 'File_get_view-5' => 'out:blankpad',
+ 'File_set_atomicity' => '2', 'File_set_atomicity-2' => 'in:logical',
+ 'File_get_atomicity' => '2', 'File_get_atomicity-2' => 'out:logical',
+ 'Register_datarep' => '1:2:3', 'Register_datarep-1' => 'in:addnull',
+ 'Register_datarep-2' => 'in:checkdatarep',
+ 'Register_datarep-3' => 'in:checkdatarep',
+ 'Op_commutative' => '2', 'Op_commutative-2' => 'out:logical',
+ );
+
+#
+# These give special post processing after the MPI routine is called.
+# The named routine is invoked with the argument number, e.g.,
+# &"setF90keyval"( FD, 1 );
+#
+%specialPost = (
+ 'Type_create_keyval' => 3,
+ 'Type_create_keyval-3' => 'setF90Type_keyval',
+ 'Comm_create_keyval' => 3,
+ 'Comm_create_keyval-3' => 'setF90Comm_keyval',
+ 'Win_create_keyval' => 3,
+ 'Win_create_keyval-3' => 'setF90Win_keyval',
+ 'Grequest_start' => 5,
+ 'Grequest_start-5' => 'setF77greq',
+ );
+
+#
+# Load any definition file
+if ($definition_file) {
+ require $definition_file;
+}
+
+$arg_string = join( ' ', @ARGV );
+if ($build_prototypes) {
+ open( PROTOFD, ">$prototype_header_file.new" ) || die "Cannot open $prototype_header_file.new\n";
+ print PROTOFD "/* -*- Mode: C; c-basic-offset:4 ; -*- */\
+/* \
+ * (C) 2003 by Argonne National Laboratory and Northwestern University.\
+ * See COPYRIGHT in top-level directory.\
+ *\
+ * This file is automatically generated by ./buildiface $arg_string\
+ * DO NOT EDIT\
+ */\
+/* Prototypes for Fortran Interface Functions */
+\n";
+}
+
+%skipBlocks = ();
+&ReadAndProcessInterface( $prototype_file, 0 );
+
+# if doing MPI2, we also need to read the MPI-2 protottypes
+if ( -s "../../mpi/romio/include/mpio.h.in" && $build_io) {
+ %skipBlocks = ( 'HAVE_MPI_DARRAY_SUBARRAY' => 1,
+ 'HAVE_MPI_INFO' => 1,
+ 'MPICH2' => 1 );
+ &ReadAndProcessInterface( "../../mpi/romio/include/mpio.h.in", 1 );
+ %skipBlocks = ();
+}
+
+# Write a list of the routines that we've found.
+if ($writeRoutineList) {
+ open LFD, ">mpi.dat" || die "Cannot open mpi.dat\n";
+ foreach my $name (sort(keys(%mpi_routines))) {
+ print LFD "$name\n";
+ }
+ close LFD;
+}
+
+if ($is_MPI) {
+ # Build the special routines
+ &build_specials;
+}
+else {
+ for ($i=0; $i<=$#ExtraRoutines; $i++) {
+ $r = $ExtraRoutines[$i];
+ &$r;
+ }
+}
+
+if ($build_prototypes) {
+ close PROTOFD;
+ &ReplaceIfDifferent( $prototype_header_file,
+ $prototype_header_file . ".new" );
+}
+
+#
+# This block can be used to create the Makefile
+if ("$buildMakefile") {
+ open ( MAKEFD, ">Makefile.sm.new" ) || die "Cannot create Makefile.sm.new";
+ print MAKEFD "# DO NOT EDIT\n# This file created by ./buildiface $arg_string\n";
+
+ # FIXME: Find out what happened to the code here and either restore/fix
+ # it or remove this block
+ # Check to see if autoconf works. Autoconf 2.13 has a bug in the Fortran
+ # language support that will break this module. Since some sites have
+ # corrected the bug in autoconf 2.13, CheckAutoconfs test for this bug.
+ if (&CheckAutoconf) {
+ # Autoconf does not work
+ # This isn't quite right, because any updates will be broken
+ # FIXME : but not sure how to do this.
+ ;
+ }
+ else {
+ # just use the regular autoconf
+ ;
+}
+
+ #print MAKEFD "smvar_debug = 1\n";
+ print MAKEFD "smvar_do_dependencies = ignore\n";
+ &print_line( MAKEFD, "mpi_sources = ", 80, "\\\n\t", 8 );
+ for ($i=0; $i<=$#files; $i++) {
+ $name = $files[$i];
+ &print_line( MAKEFD, "$name ", 80, "\\\n\t", 8 );
+ }
+ &print_endline( MAKEFD );
+ print MAKEFD "MPIFLIBNAME = \@MPIFLIBNAME\@\n";
+ print MAKEFD "PMPIFLIBNAME = \@PMPIFLIBNAME\@\n";
+
+ # The definitions for the Fortran wrappers are special
+ &AddFwrapDefs;
+ print MAKEFD "\
+lib\${MPIFLIBNAME}_a_DIR = ROOTDIR/lib\
+lib\${MPIFLIBNAME}_a_SOURCES = \${mpi_sources} setbot.c setbotf.f\
+\
+HEADERS = fproto.h mpi_fortimpl.h\
+profilelib_\${MPIFLIBNAME} = \${PMPIFLIBNAME}\
+profilelib_\${MPIFLIBNAME}_SOURCES = \${mpi_sources}\
+INCLUDES = -I../../include -I\${master_top_srcdir}/src/include -I\${master_top_srcdir}/src/binding/f77 \
+maint-clean:\
+\trm -f \${mpi_sources} $prototype_header_file\n";
+
+ print MAKEFD "install_INCLUDE = mpif.h\n";
+
+ # Add the documentation
+ print MAKEFD "# Documentation sources
+doc_sources = mpif77.txt
+DOCDESTDIRS = html:www/www1,man:man/man1,latex:doc/refman
+doc_HTML_SOURCES = \${doc_sources}
+doc_MAN_SOURCES = \${doc_sources}
+doc_LATEX_SOURCES = \${doc_sources}
+";
+
+ # Since configure copies mpif.h to the include dir, we need to remove it
+ # in a distclean step. Ditto for mpif77; add the generated files.
+ print MAKEFD "distclean-local:\n";
+ print MAKEFD "\trm -f mpif_bottom.h\n";
+ print MAKEFD "\trm -f ../../../src/include/mpif.h\n";
+ print MAKEFD "\trm -f ../../../bin/mpif77\n";
+
+ # Add the generated files to the maintainer clean target
+ print MAKEFD "maintainerclean-local:\n";
+ &print_line( MAKEFD, "\trm -f ", 80, "\\\n\t", 8 );
+ for ($i=0; $i<=$#files; $i++) {
+ if ( (($i+1) % 20) == 0) {
+ # Avoid having a line that is too long
+ &print_endline( MAKEFD );
+ &print_line( MAKEFD, "\trm -f ", 80, "\\n\t", 8 );
+ }
+ $name = $files[$i];
+ &print_line( MAKEFD, "$name ", 80, "\\\n\t", 8 );
+ }
+ &print_endline( MAKEFD );
+ print MAKEFD "\trm -f Makefile.sm\n";
+
+ # Add the definitions for compiling the members of the wrap file
+ &AddFwrapBuild;
+
+ close( MAKEFD );
+ &ReplaceIfDifferent( "Makefile.sm", "Makefile.sm.new" );
+}
+
+#
+# ------------------------------------------------------------------------
+# Procedures
+# print_line( FD, line, count, continue, continuelen )
+# Print line to FD; if line size > count, output continue string and
+# continue. Use print_endline to finish a line
+sub print_line {
+ my $FD = $_[0];
+ my $line = $_[1];
+ my $count = $_[2];
+ my $continue = $_[3];
+ my $continue_len = $_[4];
+
+ $linelen = length( $line );
+ #print "linelen = $linelen, print_line_len = $print_line_len\n";
+ if ($print_line_len + $linelen > $count) {
+ print $FD $continue;
+ $print_line_len = $continue_len;
+ }
+ print $FD $line;
+ $print_line_len += $linelen;
+}
+sub print_endline {
+ my $FD = $_[0];
+ print $FD "\n";
+ $print_line_len = 0;
+}
+
+# Print the header of the file, containing the definitions etc.
+sub print_header {
+ my $routine_name = $_[0];
+ my $lcname = $_[1];
+ my $args = $_[2];
+ my $extra = $_[3];
+
+ &print_copyright( );
+ if ($extra) {
+ print $OUTFD $extra;
+ }
+ &print_profiling_block( $routine_name, $lcname, $args );
+ &print_name_map_block( $routine_name, $lcname );
+
+ my $fn = "HelperFor" . $routine_name ;
+ if (defined(&$fn)) {
+ &$fn( $OUTFD );
+ }
+}
+
+sub print_copyright {
+ print $OUTFD "/* -*- Mode: C; c-basic-offset:4 ; -*- */\
+/* \
+ * (C) 2003 by Argonne National Laboratory and Northwestern University.\
+ * See COPYRIGHT in top-level directory.\
+ *\
+ * This file is automatically generated by ./buildiface $arg_string\
+ * DO NOT EDIT\
+ */\
+#include \"${header_file}\"\n\n";
+}
+
+#
+# Print the (ugly) profiling name definition block.
+# This is made more complex by the need, new with gcc 3.2, to
+# generate an extern declaration of the routine *before* the pragma
+#
+sub print_profiling_block {
+ my $routine_name = $_[0];
+ my $lcname = $_[1];
+ my $args = $_[2];
+ my $ucname = uc($lcname);
+
+ if ($do_weak) {
+ print $OUTFD "\
+/* Begin MPI profiling block */\
+#if defined(USE_WEAK_SYMBOLS) && !defined(USE_ONLY_MPI_NAMES) \
+#if defined(HAVE_MULTIPLE_PRAGMA_WEAK)\n";
+ &print_weak_decl( $OUTFD, "MPI_$ucname", $args, $lcname );
+ &print_weak_decl( $OUTFD, "mpi_${lcname}__", $args, $lcname );
+ &print_weak_decl( $OUTFD, "mpi_${lcname}", $args, $lcname );
+ &print_weak_decl( $OUTFD, "mpi_${lcname}_", $args, $lcname );
+ print $OUTFD "\
+#if defined(F77_NAME_UPPER)
+#pragma weak MPI_$ucname = PMPI_${ucname}
+#pragma weak mpi_${lcname}__ = PMPI_${ucname}
+#pragma weak mpi_${lcname}_ = PMPI_${ucname}
+#pragma weak mpi_${lcname} = PMPI_${ucname}
+#elif defined(F77_NAME_LOWER_2USCORE)
+#pragma weak MPI_$ucname = pmpi_${lcname}__
+#pragma weak mpi_${lcname}__ = pmpi_${lcname}__
+#pragma weak mpi_${lcname}_ = pmpi_${lcname}__
+#pragma weak mpi_${lcname} = pmpi_${lcname}__
+#elif defined(F77_NAME_LOWER_USCORE)
+#pragma weak MPI_$ucname = pmpi_${lcname}_
+#pragma weak mpi_${lcname}__ = pmpi_${lcname}_
+#pragma weak mpi_${lcname}_ = pmpi_${lcname}_
+#pragma weak mpi_${lcname} = pmpi_${lcname}_
+#else
+#pragma weak MPI_$ucname = pmpi_${lcname}
+#pragma weak mpi_${lcname}__ = pmpi_${lcname}
+#pragma weak mpi_${lcname}_ = pmpi_${lcname}
+#pragma weak mpi_${lcname} = pmpi_${lcname}
+#endif
+\n\n";
+
+ print $OUTFD "\
+#elif defined(HAVE_PRAGMA_WEAK)\
+
+#if defined(F77_NAME_UPPER)\n";
+ &print_weak_decl( $OUTFD, "MPI_$ucname", $args, $lcname );
+ print $OUTFD "\
+#pragma weak MPI_$ucname = PMPI_$ucname\
+#elif defined(F77_NAME_LOWER_2USCORE)\n";
+ &print_weak_decl( $OUTFD, "mpi_${lcname}__", $args, $lcname );
+ print $OUTFD "\
+#pragma weak mpi_${lcname}__ = pmpi_${lcname}__\
+#elif !defined(F77_NAME_LOWER_USCORE)\n";
+ &print_weak_decl( $OUTFD, "mpi_$lcname", $args, $lcname );
+ print $OUTFD "\
+#pragma weak mpi_$lcname = pmpi_$lcname\
+#else\n";
+ &print_weak_decl( $OUTFD, "mpi_${lcname}_", $args, $lcname );
+ print $OUTFD "\
+#pragma weak mpi_${lcname}_ = pmpi_${lcname}_\
+#endif\
+\
+#elif defined(HAVE_PRAGMA_HP_SEC_DEF)\
+#if defined(F77_NAME_UPPER)\
+#pragma _HP_SECONDARY_DEF PMPI_$ucname MPI_$ucname\
+#elif defined(F77_NAME_LOWER_2USCORE)\
+#pragma _HP_SECONDARY_DEF pmpi_${lcname}__ mpi_${lcname}__\
+#elif !defined(F77_NAME_LOWER_USCORE)\
+#pragma _HP_SECONDARY_DEF pmpi_$lcname mpi_$lcname\
+#else\
+#pragma _HP_SECONDARY_DEF pmpi_${lcname}_ mpi_${lcname}_\
+#endif\
+\
+#elif defined(HAVE_PRAGMA_CRI_DUP)\
+#if defined(F77_NAME_UPPER)\
+#pragma _CRI duplicate MPI_$ucname as PMPI_$ucname\
+#elif defined(F77_NAME_LOWER_2USCORE)\
+#pragma _CRI duplicate mpi_${lcname}__ as pmpi_${lcname}__\
+#elif !defined(F77_NAME_LOWER_USCORE)\
+#pragma _CRI duplicate mpi_${lcname} as pmpi_${lcname}\
+#else\
+#pragma _CRI duplicate mpi_${lcname}_ as pmpi_${lcname}_\
+#endif\
+#endif /* HAVE_PRAGMA_WEAK */\
+#endif /* USE_WEAK_SYMBOLS */\
+/* End MPI profiling block */\n\n";
+
+ &AddFwrapWeakName( $lcname, $ucname, $args );
+ }
+}
+
+#
+# Print the code that modifies the name
+# The function prototypes must be loaded *after* the name block so that the
+# name used in the function prototypes will match the one that is declared
+# in this file.
+sub print_name_map_block {
+ my $routine_name = $_[0];
+ my $lcname = $_[1];
+ my $ucname = uc($lcname);
+
+ # This include the code to map names for the profiling interface,
+ # using the same macro as for the rest of the MPI code
+ $uc_out_prefix = uc($out_prefix);
+ if ($do_profiling) {
+ # Remove the leading MPI_ if the name has it.
+ if ($routine_name =~ /^MPI_/) {
+ $routine_name =~ s/^MPI_//;
+ }
+ print $OUTFD "
+/* Map the name to the correct form */
+#ifndef MPICH_MPI_FROM_PMPI
+#if defined(USE_WEAK_SYMBOLS) && defined(HAVE_MULTIPLE_PRAGMA_WEAK)
+/* Define the weak versions of the PMPI routine*/
+#ifndef F77_NAME_UPPER\n";
+ &print_weak_decl( $OUTFD, "PMPI_$ucname", $args, $lcname );
+ print $OUTFD "#endif\n#ifndef F77_NAME_LOWER_2USCORE\n";
+ &print_weak_decl( $OUTFD, "pmpi_${lcname}__", $args, $lcname );
+ print $OUTFD "#endif\n#ifndef F77_NAME_LOWER_USCORE\n";
+ &print_weak_decl( $OUTFD, "pmpi_${lcname}_", $args, $lcname );
+ print $OUTFD "#endif\n#ifndef F77_NAME_LOWER\n";
+ &print_weak_decl( $OUTFD, "pmpi_${lcname}", $args, $lcname );
+ print $OUTFD "
+#endif
+
+#if defined(F77_NAME_UPPER)
+#pragma weak pmpi_${lcname}__ = PMPI_${ucname}
+#pragma weak pmpi_${lcname}_ = PMPI_${ucname}
+#pragma weak pmpi_${lcname} = PMPI_${ucname}
+#elif defined(F77_NAME_LOWER_2USCORE)
+#pragma weak PMPI_$ucname = pmpi_${lcname}__
+#pragma weak pmpi_${lcname}_ = pmpi_${lcname}__
+#pragma weak pmpi_${lcname} = pmpi_${lcname}__
+#elif defined(F77_NAME_LOWER_USCORE)
+#pragma weak PMPI_$ucname = pmpi_${lcname}_
+#pragma weak pmpi_${lcname}__ = pmpi_${lcname}_
+#pragma weak pmpi_${lcname} = pmpi_${lcname}_
+#else
+#pragma weak PMPI_$ucname = pmpi_${lcname}
+#pragma weak pmpi_${lcname}__ = pmpi_${lcname}
+#pragma weak pmpi_${lcname}_ = pmpi_${lcname}
+#endif /* Test on name mapping */
+#endif /* Use multiple pragma weak */
+
+#ifdef F77_NAME_UPPER
+#define ${out_prefix}${lcname}_ PMPI_${ucname}
+#elif defined(F77_NAME_LOWER_2USCORE)
+#define ${out_prefix}${lcname}_ pmpi_${lcname}__
+#elif !defined(F77_NAME_LOWER_USCORE)
+#define ${out_prefix}${lcname}_ pmpi_${lcname}
+#else
+#define ${out_prefix}${lcname}_ pmpi_${lcname}_
+#endif /* Test on name mapping */
+
+/* This defines the routine that we call, which must be the PMPI version
+ since we're renaming the Fortran entry as the pmpi version. The MPI name
+ must be undefined first to prevent any conflicts with previous renamings,
+ such as those put in place by the globus device when it is building on
+ top of a vendor MPI. */
+#undef MPI_${routine_name}
+#define MPI_${routine_name} PMPI_${routine_name}
+
+#else
+";
+ }
+ print $OUTFD "
+#ifdef F77_NAME_UPPER
+#define ${out_prefix}${lcname}_ ${uc_out_prefix}${ucname}
+#elif defined(F77_NAME_LOWER_2USCORE)
+#define ${out_prefix}${lcname}_ ${out_prefix}${lcname}__
+#elif !defined(F77_NAME_LOWER_USCORE)
+#define ${out_prefix}${lcname}_ ${out_prefix}${lcname}
+/* Else leave name alone */
+#endif
+
+";
+ if ($do_profiling) {
+ print $OUTFD "
+#endif /* MPICH_MPI_FROM_PMPI */
+";
+ }
+ if ($build_prototypes) {
+ print $OUTFD "
+/* Prototypes for the Fortran interfaces */
+#include \"$prototype_header_file\"
+";
+ }
+}
+
+# Print the arguments for the routine DEFINITION.
+sub print_args {
+ my @parms = split(/\s*,\s*/, $_[1] );
+ my $OUTFD = $_[0];
+ my $count = 1;
+ my $last_args = "";
+ my $prototype_only = $_[2];
+ my $routine = $_[3];
+
+ # Clear the @arg_addresses and $arg_qualifiers array.
+ $#arg_addresses = -1;
+ $#arg_qualifiers = -1;
+
+ # Special case: if the only parm is "void", remove it from the list
+ print STDERR "Nparms = $#parms, parms = " . join(',', at parms) . "\n" if $debug;
+ if ($#parms == 0 && $parms[0] eq "void") {
+ print $OUTFD "( void )";
+ return
+ }
+ # argsep is used to add a comma before every argument, except for the
+ # first
+ $argsep = "";
+ print $OUTFD "( ";
+ foreach $parm (@parms) {
+ # Match type to replacement
+ print "parm = :$parm:\n" if $debug;
+ # Remove qualifiers from the parm
+ $arg_qualifiers[$count] = "";
+ if ($parm =~ /^const\s+/) {
+ $parm =~ s/^const\s+//;
+ $arg_qualifiers[$count] .= "const ";
+ }
+ # remove all "const"
+ $parm =~ s/const//;
+
+ if ($parm =~ /^restrict\s+/) {
+ $parm =~ s/restrict\s+//;
+ $arg_qualifiers[$count] .= "restrict ";
+ }
+ # remove leading whitespace
+ $parm =~ s/^\s+//;
+
+ # Remove arg names from array types
+ if ($parm =~ /(\w+)\s+(\w+)\s*\[\]/) {
+ # Assume that this is <type> <name>[]; convert to <type>[]
+ print " Removing argname $2 from parm array $parm\n" if $debug;
+ $parm = "$1" . "[]";
+ }
+ elsif ($parm =~ /(\w+)\s*\*\s*(\w+)\s*\[\]/) {
+ # Assume that this is <type>* <name>[]; convert to <type>*
+ print " Removing argname $2 from parm array $parm\n" if $debug;
+ $parm = "$1" . "*";
+ }
+ elsif ($parm =~ /(\w+)\s*\*\s*\*\s*(\w+)/) {
+ # Remove arg names from pointer types
+ # Assume that this is <type>** ; convert to <type>*
+ print " Removing argname $2 from parm pointer\n" if $debug;
+ $parm = "$1" . "*";
+ }
+ elsif ($parm =~ /(\w+)\s*\*\s*(\w+)/) {
+ # Remove arg names from pointer types
+ # Assume that this is <type>* ; convert to <type>*
+ print " Removing argname $2 from parm pointer\n" if $debug;
+ $parm = "$1" . "*";
+ }
+ # Remove blanks from the parm
+ $parm =~ s/\s+//;
+ $arg_addresses[$count] = 0;
+
+ # This handles routines that have special declaration requirements
+ # for particular arguments
+ if (defined($declarg{"$routine-$count"})) {
+ print " Using declarg{$routine} for this parm\n" if $debug;
+ $parm = $declarg{"$routine-$count"};
+ if ($prototype_only) {
+ print $OUTFD "$argsep$parm";
+ }
+ else {
+ print $OUTFD "$argsep$parm v$count";
+ }
+ }
+ elsif ($parm =~ /char\s*\*/) {
+ # char's go out at char *v FORT_MIXED_LEN(d)
+ # and FORT_END_LEN(d) at the end
+ # (even if an array, because at the Fortran level, it
+ # is still a pointer to a character variable; the length
+ # of each entry in the array is the "d" value).
+ # FORT_END_LEN and FORT_MIXED_LEN contain the necessary comman
+ # if they are prsent at all.
+ print " parm is a character string\n" if $debug;
+ if ($prototype_only) {
+ print $OUTFD "${argsep}char * FORT_MIXED_LEN_DECL";
+ $last_args .= "FORT_END_LEN_DECL ";
+ }
+ else {
+ print $OUTFD "${argsep}char *v$count FORT_MIXED_LEN(d$count)";
+ $last_args .= "FORT_END_LEN(d$count) ";
+ }
+ }
+ elsif ($parm =~/\[/) {
+ # Argument type is array, so we need to
+ # a) mark as containing a star
+ # b) place parameter correctly
+ $star_count = 1;
+ $arg_addresses[$count] = $star_count;
+ # Split into raw type and []
+ # Use \S* instead of the equivalent [^\s]*.
+ # (\S is not-a-space)
+ # perl 5.8 is known to mishandle the latter, leading to
+ # an empty basetype
+ if ($parm =~ /\s*(\S*)\s*(\[\s*\])/) {
+ $basetype = $1;
+ }
+ else {
+ print STDERR "Internal error. Could not find basetype\n";
+ print STDERR "This may be a bug in perl in the handling of certain expressions\n";
+ }
+ print "\tparm $parm is array of >$basetype<\n" if $debug;
+ #$foundbrack = $2;
+ if (defined($tof77{$parm})) {
+ # This is a special case; the full type is defined.
+ # This is used, for example, for int [][3] in the
+ # routines that specify a range.
+ print "Matched to full type $parm with replacement $tof77{$parm}\n" if $debug;
+ # We use the replacement type
+ $basetype = $tof77{$parm};
+ $star_count = 0;
+ $arg_addresses[$count] = $star_count;
+ }
+ elsif ($basetype eq "int") {
+ # Do nothing because the [] added to the arg below
+ # is all that is necessary.
+ $star_count = 0;
+ $arg_addresses[$count] = $star_count;
+ }
+ elsif (defined($tof77{"$basetype\[\]"})) {
+ # Use the code for handling array parameters if
+ # mapping code is provided.
+ print "Match to array type $basetype\[\]\n" if $debug;
+ $star_count = 0;
+ $arg_addresses[$count] = $star_count;
+ $basetype = $tof77{"$basetype\[\]"};
+ }
+ elsif (defined($tof77{$basetype})) {
+ # FIXME: This code (now commented out) is not correct
+ print STDERR "Using fall through for $basetype in $routine\n" if $debug;
+# if ($useOldCode eq "yes") {
+# $nstar_before = ($basetype =~ /\*/);
+# $basetype = $tof77{$basetype};
+# # The following fixes the case where the underlying type
+# # is a simple int.
+# if ($basetype eq "int") {
+# $arg_addresses[$count] = 0;
+# }
+# print "\tparm has defined type of $basetype\n" if $debug;
+# $nstar_after = ($basetype =~ /\*/);
+# if ($nstar_before != $nstar_after) {
+# $star_count++;
+# }
+ # If we have an array, and a type mapping to fortran
+ # We want to simply pretend that all is well (like int
+ # above)
+ $star_count = 0;
+ $arg_addresses[$count] = $star_count;
+ }
+ if ($prototype_only) {
+ print $OUTFD "$argsep$basetype \[\]";
+ }
+ else {
+ print $OUTFD "$argsep$basetype v$count\[\]";
+ }
+ }
+ else {
+ $nstar_before = ($parm =~ /\*/);
+ $nstar_after = $nstar_before;
+ print "Nstar = $nstar_after\n" if $debug;
+ if (defined($tof77{$parm})) {
+ $parm = $tof77{$parm};
+ $nstar_after = ($parm =~ /\*/);
+ }
+ $leadspace = "";
+ if ($parm =~ /\w$/) {
+ $leadspace = " ";
+ }
+ if ($prototype_only) {
+ print $OUTFD "${argsep}${parm}";
+ }
+ else {
+ if ($parm =~ /^(\w+)\*$/) {
+ # make "type*" to "type *"
+ $parm = "$1" . " *";
+ }
+ print $OUTFD "${argsep}${parm}${leadspace}v$count";
+ }
+ $star_count = 0;
+ if ($nstar_before != $nstar_after) {
+ $star_count = 1;
+ }
+ $arg_addresses[$count] = $star_count;
+ }
+ $count++;
+ $argsep = ", ";
+ }
+ # Add the new error return code if necessary
+ $tmpargs= $errparm;
+ $tmpargs =~ s/\s*//g;
+ if ($tmpargs ne "") {
+ if ($prototype_only) {
+ print $OUTFD "$argsep$errparmtype";
+ }
+ else {
+ print $OUTFD "$argsep$errparm";
+ }
+ }
+ print $OUTFD " $last_args";
+ print $OUTFD ")";
+}
+
+# Print the arguments for the routine CALL.
+# Handle the special arguments
+sub print_call_args {
+ my @parms = split(/\s*,\s*/, $_[0] );
+ my $count = 1;
+ my $first = 1;
+ print $OUTFD "( ";
+ # Special case: if the only parm is "void", remove it from the list
+ if ($#parms == 0 && $parms[0] eq "void") {
+ $#parms = -1;
+ }
+
+ foreach $parm (@parms) {
+ $parm =~ s/^const\s//; # Remove const if present
+ # Remove variable name if present in an array arg
+ if ($parm =~ /(.*)\s+(\w+)\[\]/) {
+ $parm = "$1 \[\]";
+ }
+ # Compress multiple spaces
+ $parm =~ s/\s\s/ /g;
+ if (!$first) { print $OUTFD ", "; } else { $first = 0; }
+
+ if (defined($special_args{"${routine_name}-$count"})) {
+ # We must handle this argument specially
+ &print_special_call_arg( $routine_name, $count );
+ }
+ elsif ($parm =~ /!/) {
+ # This parameter is a special case; the exclamation point
+ # is used to say "call with this argument as is"
+ $parm =~ s/!//;
+ print $OUTFD $parm;
+ }
+ else {
+ # Convert to/from object type as required.
+ #print "TMP: parm = $arg_qualifiers[$count]$parm\n";
+ $fullparm="$arg_qualifiers[$count]$parm";
+ if (defined($argsneedcast{$fullparm})) {
+ $argval = "v$count";
+ if ($arg_addresses[$count] > 0) {
+ $argval = "*$argval";
+ }
+ $callparm = $argsneedcast{$fullparm};
+ $callparm =~ s/ARG/$argval/;
+ print $OUTFD "$callparm";
+ }
+ else {
+ # Since MPICH objects are ints, we don't need to do
+ # anything unless MPI_Fint and int are different.
+ # print STDERR "XXX $count $#arg_addresses XXX\n";
+ if ($arg_addresses[$count] > 0) {
+ print $OUTFD "*";
+ }
+ print $OUTFD "v$count";
+ }
+ }
+ $count++;
+ }
+ print $OUTFD " );\n";
+}
+
+# Print the option function attribute; this supports GCC, particularly
+# the __atribute__ ((weak)) option. Unfortunately, the name must be
+# made into a string and inserted into the attribute list.
+sub print_attr {
+ my $OUTFD = $_[0];
+ my $name = $_[1];
+ if ($do_weak) {
+ print $OUTFD " FUNC_ATTRIBUTES($name)";
+ }
+}
+
+#
+# We allow a routine to specify an alternate weak decl by name
+sub set_weak_decl {
+ my $name = $_[0];
+ my $decl = $_[1];
+ my $rtype = $_[2];
+ $name = lc($name);
+ $altweak{$name} = $decl;
+ $altweakrtype{$name} = $rtype;
+}
+sub print_weak_decl {
+ my $OUTFD = $_[0];
+ my $name = $_[1];
+ my $args = $_[2];
+ my $lcname = $_[3];
+
+ my $basename = lc($name);
+ $basename =~ s/_*$//;
+ if (defined($altweak{$basename})) {
+ print $OUTFD "extern FORTRAN_API $altweakrtype{$basename} FORT_CALL $name($altweak{$basename});\n";
+ }
+ else {
+ print $OUTFD "extern FORTRAN_API $returnType FORT_CALL $name";
+ &print_args( $OUTFD, $args, 1, $lcname );
+ print $OUTFD ";\n";
+ }
+}
+#
+# --------------------------------------------------------------------------
+# Special processing
+#
+# Each parameter can be processed by a routine, with the suffix controlling
+# the routine invoked for each step. Roughly, these are:
+#
+# void foo( MPI_Fint *v1, etc )
+# {
+# /* Special declarations needed for the variables */
+# <name>_<direction>_decl( <argnum> )
+# /* Special processing need for in variables */
+# <name>_ftoc( <argnum> )
+# /* Call the function. Replace special arguments with the output from */
+# <name>_<direction>_arg( <argnum> )
+# /* Special post call processing (for out variables) */
+# <name>_ctof( l$count, v$count ) /* local (C) variable name, fortran var name */
+#
+# Special case: For parameters that are arrays, the size of the
+# array is in $Array_size.
+#
+#
+# --------------------------------------------------------------------------
+# Buffer pointers
+sub bufptr_ftoc {
+ my $count = $_[0];
+}
+sub bufptr_in_decl {
+ my $count = $_[0];
+}
+sub bufptr_in_arg {
+ my $count = $_[0];
+ if ($do_bufptr) {
+ print $OUTFD "MPIR_F_PTR(v$count)";
+ }
+ else {
+ print $OUTFD "v$count";
+ }
+}
+# bufptr_ctof( cvar, fvar )
+sub bufptr_ctof {
+ my $coutvar = $_[0];
+ my $outvar = $_[1];
+}
+# --------------------------------------------------------------------------
+# MPI_IN_PLACE buffer pointers
+sub inplace_ftoc {
+ my $count = $_[0];
+ &specialInitStatement( $OUTFD );
+ print $OUTFD " if (v$count == MPIR_F_MPI_IN_PLACE) v$count = MPI_IN_PLACE;\n";
+}
+sub inplace_in_decl {
+ my $count = $_[0];
+}
+sub inplace_in_arg {
+ my $count = $_[0];
+ print $OUTFD "v$count";
+}
+# inplace_ctof( cvar, fvar )
+sub inplace_ctof {
+ my $coutvar = $_[0];
+ my $outvar = $_[1];
+}
+# --------------------------------------------------------------------------
+# Logical variables
+sub logical_ftoc {
+ my $count = $_[0];
+ print $OUTFD " l$count = MPIR_FROM_FLOG(*v$count);\n";
+}
+sub logical_in_decl {
+ my $count = $_[0];
+ if ($do_logical) {
+ print $OUTFD " int l$count;\n";
+ }
+}
+sub logical_in_arg {
+ my $count = $_[0];
+ if ($do_logical) {
+ print $OUTFD "l$count";
+ }
+ else {
+ print $OUTFD "v$count";
+ }
+}
+# logical_ctof( cvar, fvar )
+sub logical_ctof {
+ my $coutvar = $_[0];
+ my $outvar = $_[1];
+ if ($do_logical) {
+ print $OUTFD " *$outvar = MPIR_TO_FLOG($coutvar);\n";
+ }
+}
+sub logical_out_decl {
+ my $count = $_[0];
+ if ($do_logical) {
+ print $OUTFD " int l$count;\n";
+ }
+}
+sub logical_out_arg {
+ my $count = $_[0];
+ if ($do_logical) {
+ print $OUTFD "\&l$count";
+ }
+ else {
+ print $OUTFD "v$count";
+ }
+}
+# --------------------------------------------------------------------------
+#
+# Logical variables, but for an array.
+# Array args can use the global $Array_size and $Array_typedef if necessary
+sub logical_array_ftoc {
+ print $OUTFD "\
+ {int li;
+ for (li=0; li<$Array_size; li++) {
+ l$count\[li\] = MPIR_FROM_FLOG(v$count\[li\]);
+ }
+ }
+";
+}
+sub logical_array_in_decl {
+ my $count = $_[0];
+ print $OUTFD " int *l$count = (int *)$malloc((size_t)($Array_size) * sizeof(int));\n";
+ $clean_up .= " $free(l$count);\n";
+}
+sub logical_array_in_arg {
+ my $count = $_[0];
+ print $OUTFD "l$count";
+}
+
+sub logical_array_ctof {
+ my $coutvar = $_[0];
+ my $outvar = $_[1];
+ print $OUTFD "\
+ {int li;
+ for (li=0; li<$Array_size; li++) {
+ $outvar\[li\] = MPIR_TO_FLOG($outvar\[li\]);
+ }
+ }
+";
+}
+sub logical_array_out_decl {
+}
+sub logical_array_out_arg {
+ my $count = $_[0];
+ print $OUTFD "v$count";
+}
+# --------------------------------------------------------------------------
+#
+# Index variables.
+# Index variables are not optional, since the values of the variable
+# are changed.
+sub index_ftoc {
+ my $count = $_[0];
+}
+sub index_ctof {
+ my $coutvar = $_[0];
+ my $outvar = $_[1];
+ print $OUTFD " *$outvar = (MPI_Fint)$coutvar;\n";
+ print $OUTFD " if ($coutvar >= 0) *$outvar = *$outvar + 1;\n";
+}
+sub index_out_decl {
+ my $count = $_[0];
+ print $OUTFD " int l$count;\n";
+}
+sub index_out_arg {
+ my $count = $_[0];
+ print $OUTFD " \&l$count";
+}
+#
+# Index variables, but for an array.
+# Array args can use the global $Array_size and $Array_typedef if necessary
+sub index_array_ftoc {
+ my $count = $_[0];
+}
+sub index_array_ctof {
+ my $coutvar = $_[0];
+ my $outvar = $_[1];
+ print $OUTFD "\
+ {int li;
+ for (li=0; li<$Array_size; li++) {
+ if ($outvar\[li\] >= 0) $outvar\[li\] += 1;
+ }
+ }
+"
+}
+sub index_array_out_decl {
+}
+sub index_array_out_arg {
+ my $count = $_[0];
+ print $OUTFD "v$count";
+}
+# --------------------------------------------------------------------------
+#
+# Address and attribute handling
+# Note that this construction can lead to compiler warnings on systems
+# where an address is larger than an MPI_Fint. This is correct; these
+# routines are for the MPI-1 routines that use an MPI_Fint where the
+# C code uses a void * (MPI_Aint in MPI-2).
+# Instead of using MPI_Aint, we use MPIR_Pint. This allows the MPI
+# implementation to set MPI_Aint to be *larger* than a pointer-sized-int,
+# which is needed (as a temporary workaround) on systems like Blue Gene, which
+# have 4 byte pointers but file systems that need 8 byte datatypes (not just
+# offsets).
+# A possible extension is to provide an error warning (much as
+# MPI_Address does) when the attribute value loses bits when assigned into
+# the MPI_Fint.
+#in:addrint
+#out:attrint:4
+sub addrint_ftoc {
+ my $count = $_[0];
+}
+sub addrint_in_decl {
+}
+sub addrint_in_arg {
+ my $count = $_[0];
+ print $OUTFD "(void *)(MPIR_Pint)((int)*(int *)v$count)";
+}
+
+sub attrint_ctof {
+ my $fvar = $_[0];
+ my $cvar = $_[1];
+ my $flagarg = 4; # get from option
+ # The double cast of attr$cvar first to MPIR_Pint and then to MPI_Fint
+ # keeps some compilers happy on 64-bit platforms
+ print $OUTFD "
+ if ((int)*ierr || !l$flagarg) {
+ *(MPI_Fint*)$cvar = 0;
+ }
+ else {
+ *(MPI_Fint*)$cvar = (MPI_Fint)(MPIR_Pint)attr$cvar;
+ }\n";
+}
+
+sub attrint_out_decl {
+ my $count = $_[0];
+ print $OUTFD " void *attrv$count;\n";
+}
+
+sub attrint_out_arg {
+ my $count = $_[0];
+ print $OUTFD "&attrv$count";
+}
+# --------------------------------------------------------------------------
+# Address and attribute handling
+# This version of attrint uses Aints instead of ints, and is appropriate
+# for the MPI-2 attribute caching functions
+#in:addraint
+#out:attraint:4
+sub addraint_ftoc {
+ my $count = $_[0];
+}
+sub addraint_in_decl {
+}
+sub addraint_in_arg {
+ my $count = $_[0];
+ print $OUTFD "(void *)(*(MPI_Aint *)v$count)";
+}
+
+sub attraint_ctof {
+ my $fvar = $_[0];
+ my $cvar = $_[1];
+ my $flagarg = 4; # get from option
+ print $OUTFD "
+ if ((int)*ierr || !l$flagarg) {
+ *(MPI_Aint*)$cvar = 0;
+ }
+ else {
+ *(MPI_Aint*)$cvar = (MPI_Aint)attr$cvar;
+ }\n";
+}
+
+sub attraint_out_decl {
+ my $count = $_[0];
+ print $OUTFD " void *attrv$count;\n";
+}
+
+sub attraint_out_arg {
+ my $count = $_[0];
+ print $OUTFD "&attrv$count";
+}
+# --------------------------------------------------------------------------
+#
+# Buffer Address output handling (Buffer_detach)
+#out:bufaddr
+sub bufaddr_ftoc {
+}
+sub bufaddr_out_decl {
+ my $count =$_[0];
+ print $OUTFD " void *t$count = v$count;\n";
+}
+sub bufaddr_out_arg {
+ my $count = $_[0];
+ print $OUTFD "&t$count";
+}
+
+sub bufaddr_ctof {
+ my $fvar = $_[0];
+ my $cvar = $_[1];
+}
+# --------------------------------------------------------------------------
+#
+# Handle MPI_STATUS_IGNORE and MPI_STATUSES_IGNORE
+sub status_ftoc {
+ my $count = $_[0];
+ # Cast MPI_STATUS_IGNORE back to an MPI_Fint (we'll re-cast it back
+ # to (MPI_Status *) in the call to the C version of the routine)
+ &specialInitStatement( $OUTFD );
+ print $OUTFD "\
+ if (v$count == MPI_F_STATUS_IGNORE) { v$count = (MPI_Fint*)MPI_STATUS_IGNORE; }\n";
+}
+sub status_ctof {
+ my $coutvar = $_[0];
+ my $outvar = $_[1];
+}
+sub status_in_decl {
+ my $count = $_[0];
+}
+sub status_in_arg {
+ my $count = $_[0];
+ print $OUTFD "(MPI_Status *)v$count";
+}
+# --------------------------------------------------------------------------
+#
+# Handle MPI_ERRCODES_IGNORE
+sub errcodesignore_ftoc {
+ my $count = $_[0];
+ &specialInitStatement( $OUTFD );
+ print $OUTFD "\
+ if (v$count == MPI_F_ERRCODES_IGNORE) { v$count = MPI_ERRCODES_IGNORE; }\n";
+}
+sub errcodesignore_ctof {
+ my $coutvar = $_[0];
+ my $outvar = $_[1];
+}
+sub errcodesignore_in_decl {
+ my $count = $_[0];
+}
+sub errcodesignore_in_arg {
+ my $count = $_[0];
+ print $OUTFD "(int *)v$count";
+}
+# --------------------------------------------------------------------------
+#
+# Index variables, but for an array.
+# Array args can use the global $Array_size and $Array_typedef if necessary
+sub status_array_ftoc {
+ my $count = $_[0];
+ &specialInitStatement( $OUTFD );
+ print $OUTFD "\
+ if (v$count == MPI_F_STATUSES_IGNORE) { v$count = (MPI_Fint *)MPI_STATUSES_IGNORE; }\n";
+}
+sub status_array_ctof {
+ my $coutvar = $_[0];
+ my $outvar = $_[1];
+}
+sub status_array_in_decl {
+}
+sub status_array_in_arg {
+ my $count = $_[0];
+ print $OUTFD "(MPI_Status *)v$count";
+}
+# --------------------------------------------------------------------------
+# aintToint
+sub aintToInt_ctof {
+ my $coutvar = $_[0];
+ my $outvar = $_[1];
+ print $OUTFD " *$outvar = (MPI_Fint)($coutvar);\n";
+}
+sub aintToInt_out_decl {
+ my $count = $_[0];
+ print $OUTFD " MPI_Aint l$count;\n";
+}
+sub aintToInt_out_arg {
+ my $count = $_[0];
+ print $OUTFD "\&l$count";
+}
+# --------------------------------------------------------------------------
+# aintToVal - Convert address of Aint to value
+sub aintToVal_ftoc {
+ my $coutvar = $_[0];
+ my $outvar = $_[1];
+}
+sub aintToVal_in_decl {
+ my $count = $_[0];
+}
+sub aintToVal_in_arg {
+ my $count = $_[0];
+ print $OUTFD "*v$count";
+}
+# ---------------------------------------------------------------------------
+# This is the routine that handles the post-call processing
+sub print_post_call {
+ my $routine_name = $_[0];
+ my $args = $_[1];
+ if (defined($special_args{$routine_name})) {
+ # Erg. Special processing
+ foreach $count (split(/:/,$special_args{$routine_name})) {
+ $rule = $special_args{"${routine_name}-$count"};
+ ($direction,$method,$Array_size) = split(/:/,$rule);
+ print STDERR "$routine_name: dir = $direction, method = $method\n" if $debug;
+ $processing_in_routine = "${method}_in_ctof";
+ if ($direction eq "out" || $direction eq "inout") {
+ $processing_routine = "${method}_ctof";
+ &$processing_routine( "l$count", "v$count" );
+ }
+ elsif (defined(&$processing_in_routine)) {
+ # Invoke even for "in" args incase we need to free a temp
+ &$processing_in_routine( "l$count", "v$count" );
+ }
+ if ($clean_up ne "") {
+ print $OUTFD $clean_up;
+ $clean_up = "";
+ }
+ }
+ }
+
+ # Handle here any special post-only calls
+ if (defined($specialPost{$routine_name})) {
+ my $argnum = $specialPost{$routine_name};
+ my $postRoutine = $specialPost{"$routine_name-$argnum"};
+ &$postRoutine( $OUTFD, $argnum );
+ }
+}
+#
+# ---------------------------------------------------------------------------
+#
+# Blankpad strings
+# This is complicated by the fact that the Fortran strings do not contain
+# null terminators and the MPI definitions of string lengths, such as
+# MPI_MAX_PORT_NAME, are one smaller in Fortran than in C (see 4.12.9
+# in the MPI-2 specification). Because of this, we need to allocate a
+# temporary that is one longer on
+sub blankpad_out_decl {
+ my $count = $_[0];
+ print $OUTFD " char *p$count;\n";
+}
+sub blankpad_out_arg {
+ my $count = $_[0];
+ print $OUTFD "p$count";
+}
+sub blankpad_out_ftoc {
+ my $count = $_[0];
+
+ # Allocate space to hold the C version of the output
+ $strlen = "d$count";
+ print $OUTFD " p$count = (char *)$malloc( (size_t)$strlen + 1 );\n";
+}
+sub blankpad_ctof {
+ my $coutvar = $_[0];
+ my $outvar = $_[1];
+
+ # find the null character. Replace with blanks from there to the
+ # end of the string. The declared lenght is given by a variable
+ # whose name is derived from outvar
+ $strlen = $outvar;
+ $strlen =~ s/^v/d/;
+ my $cvar = $outvar;
+ $cvar =~ s/^v/p/;
+ print $OUTFD "
+ {
+ char *p = $outvar, *pc=$cvar;
+ while (*pc) {*p++ = *pc++;}
+ while ((p-$outvar) < $strlen) { *p++ = ' '; }
+ }\n";
+ $clean_up .= " $free($cvar);\n";
+}
+#
+# Blankpad strings if a flag is true (for info_get, perhaps others?)
+# This is complicated by the fact that the Fortran strings do not contain
+# null terminators and the MPI definitions of string lengths, such as
+# MPI_MAX_PORT_NAME, are one smaller in Fortran than in C (see 4.12.9
+# in the MPI-2 specification). Because of this, we need to allocate a
+# temporary that is one longer on
+sub blankpadonflag_out_decl {
+ my $count = $_[0];
+ print $OUTFD " char *p$count;\n";
+}
+sub blankpadonflag_out_arg {
+ my $count = $_[0];
+ print $OUTFD "p$count";
+}
+sub blankpadonflag_out_ftoc {
+ my $count = $_[0];
+
+ # Allocate space to hold the C version of the output
+ $strlen = "d$count";
+ print $OUTFD " p$count = (char *)$malloc( (size_t)$strlen + 1 );\n";
+}
+sub blankpadonflag_ctof {
+ my $coutvar = $_[0];
+ my $outvar = $_[1];
+
+ # find the null character. Replace with blanks from there to the
+ # end of the string. The declared lenght is given by a variable
+ # whose name is derived from outvar
+ $strlen = $outvar;
+ $strlen =~ s/^v/d/;
+ my $cvar = $outvar;
+ $cvar =~ s/^v/p/;
+ print $OUTFD "\
+ if ($Array_size) {char *p = $outvar, *pc=$cvar;
+ while (*pc) {*p++ = *pc++;}
+ while ((p-$outvar) < $strlen) { *p++ = ' '; }
+ }
+";
+ $clean_up .= " $free( $cvar );\n";
+}
+
+# ---------------------------------------------------------------------------
+# Add null to input strings
+# We must make a copy
+sub addnull_in_decl {
+ my $count = $_[0];
+ print $OUTFD " char *p$count;\n";
+}
+sub addnull_in_arg {
+ my $count = $_[0];
+ print $OUTFD "p$count";
+}
+sub addnull_ftoc {
+ my $count = $_[0];
+
+ # Working backwards from the length argument, find the first
+ # nonblank character
+ # end of the string. The declared length is given by a variable
+ # whose name is derived from outvar
+ $strlen = "v$count";
+ $strlen =~ s/^v/d/;
+ print $OUTFD "\
+ {char *p = v$count + $strlen - 1;
+ int li;
+ while (*p == ' ' && p > v$count) p--;
+ p++;
+ p$count = (char *)$malloc( (size_t)(p-v$count) + 1 );
+ for (li=0; li<(p-v$count); li++) { p$count\[li\] = v$count\[li\]; }
+ p$count\[li\] = 0;
+ }
+";
+ $clean_up .= " $free( p$count );\n";
+}
+# ----------------------------------------------------------------------------
+# Add null to input strings, also trim all LEADING and trailing blanks.
+# This is required by Info_set (but not explicitly for the other
+# routines).
+# We must make a copy
+sub addnullandtrim_in_decl {
+ my $count = $_[0];
+ print $OUTFD " char *p$count;\n";
+}
+sub addnullandtrim_in_arg {
+ my $count = $_[0];
+ print $OUTFD "p$count";
+}
+sub addnullandtrim_ftoc {
+ my $count = $_[0];
+
+ # Working backwards from the length argument, find the first
+ # nonblank character
+ # end of the string. The declared length is given by a variable
+ # whose name is derived from outvar
+ $strlen = "v$count";
+ $strlen =~ s/^v/d/;
+ print $OUTFD "\
+ {char *p = v$count + $strlen - 1;
+ char *pin = v$count;
+ int li;
+ while (*p == ' ' && p > v$count) p--;
+ p++;
+ while (*pin == ' ' && pin < p) pin++;
+ p$count = (char *)$malloc( (size_t)(p-pin) + 1 );
+ for (li=0; li<(p-pin); li++) { p$count\[li\] = pin\[li\]; }
+ p$count\[li\] = 0;
+ }
+";
+ $clean_up .= " $free( p$count );\n";
+}
+
+# ----------------------------------------------------------------------------
+# Add null to arrays of input strings
+# We must make a copy
+# chararray is used ONLY in comm_spawn
+sub chararray_in_decl {
+ my $count = $_[0];
+ print $OUTFD " char **p$count;\n";
+ if (!$Array_size) { print $OUTFD " char *pcpy$count;\n"; }
+ # pcpy<digit> is used for the case where the array length is not known
+ print $OUTFD " int asize$count=0;\n";
+}
+sub chararray_in_arg {
+ my $count = $_[0];
+ print $OUTFD "p$count";
+}
+sub chararray_ftoc {
+ my $count = $_[0];
+
+ # There is a special case - the input is MPI_ARGV_NULL. We
+ # detect this by checking for a null string (all blanks).
+ # The initialization of MPI_ARGV_NULL is done in the special
+ #init setup
+ &specialInitStatement( $OUTFD );
+ # First, compute the number of elements. In Fortran, a null
+ # string terminates the array. The array is stored as
+ # a two-dimensional field of fixed-length characters.
+ # Then copy the strings into the new storage, appending the
+ # null at the end
+ print $OUTFD "\
+ { int i;
+ char *ptmp;\n";
+ if ($Array_size) {
+ print $OUTFD "\
+ asize$count = $Array_size + 1;\n";
+ }
+ else {
+ print $OUTFD "\
+ /* Compute the size of the array by looking for an all-blank line */
+ pcpy$count = v$count;
+ for (asize$count=1; 1; asize$count++) {
+ char *pt = pcpy$count + d$count - 1;
+ while (*pt == ' ' && pt > pcpy$count) pt--;
+ if (*pt == ' ') break;
+ pcpy$count += d$count;
+ }\n";
+ }
+ print $OUTFD "\
+ p$count = (char **)$malloc( (size_t)asize$count * sizeof(char *) );
+ ptmp = (char *)$malloc( (size_t)asize$count * (d$count + 1) );
+ for (i=0; i<asize$count-1; i++) {
+ char *p = v$count + i * d$count, *pin, *pdest;
+ int j;
+
+ pdest = ptmp + i * (d$count + 1);
+ p$count\[i\] = pdest;
+ /* Move to the end and work back */
+ pin = p + d$count - 1;
+ while (*pin == ' ' && pin > p) pin--;
+ /* Copy and then null terminate */
+ for (j=0; j<(pin-p)+1; j++) { pdest\[j\] = p\[j\]; }
+ pdest\[j\] = 0;
+ }
+ /* Null terminate the array */
+ p$count\[asize$count-1\] = 0;
+ }\n";
+ $clean_up .= " $free( p$count\[0\] ); $free( p$count );\n";
+}
+
+# Add null to 2-dimensional arrays of input strings. Used only
+# by comm_spawn_multiple
+# FIXME : THIS CODE IS NOT CORRECT YET
+# Note the special handling of MPI_ARGVS_NULL
+sub chararray2_in_decl {
+ my $count = $_[0];
+ print $OUTFD " char ***p$count=0;\n";
+}
+sub chararray2_in_arg {
+ my $count = $_[0];
+ print $OUTFD "p$count";
+}
+sub chararray2_ftoc {
+ my $count = $_[0];
+
+ if ($Array_size eq "") {
+ print STDERR "A leading array size is required for 2-d Character arrays\n";
+ return 1;
+ }
+
+ # First, compute the number of elements. In Fortran, a null
+ # string terminates the array. The array is stored as
+ # a two-dimensional field of fixed-length characters.
+ # Then copy the strings into the new storage, appending the
+ # null at the end
+ # Since this is a 2-d array, we always know the first dimension,
+ # the second dimension must be computed, this is asize$count.
+ # The first dimension is Array_size.
+ &specialInitStatement( $OUTFD );
+ print $OUTFD "\
+ /* Check for the special case of a the null args case. */
+ if (v$count == MPI_F_ARGVS_NULL) { v$count = (char *)MPI_ARGVS_NULL; }
+ else {
+ /* We must convert from the 2-dimensional Fortran array of
+ fixed length strings to a C variable-sized array (really an
+ array of pointers for each command of pointers to each
+ argument, which is null terminated.*/\n";
+
+ # We must be careful. A blank line is ALL blank, not just leading blank
+ # We must also be careful allocating the array, as C and Fortran
+ # arrays are not the same. In C, for a two dimensional array
+ # sized at run time, we must
+ # allocate an array of pointers to arrays.
+ # p = (char ***) malloc( nrows * sizeof(char **) )
+ # where we are letting using p[nrows][colindex].
+ # For MPI_Comm_spawn_multiple, each of these rows is for one command.
+ # Each p[k] is a pointer to an array of character strings.
+ # For MPI_Comm_spawn_multiple, all we know is that in the
+ # corresponding Fortran code, the two-dimensional character array
+ # contains an all-blank entry as the terminating element; the
+ # corresponding C array must have a null entry (pointer) in
+ # the corresponding position.
+ # Thus, the C code must make several allocations:
+ # p = nrows * sizeof(char **)
+ # for p[k], (ncols + 1) * sizeof(char *)
+ # for p[k][i], space for the ith input argument.
+ # To reduce the number of allocations, we allocate space for all
+ # elements on a row at one time.
+
+ # Purely local variables don't need $count
+ print $OUTFD "\
+ int k;
+
+ /* Allocate the array of pointers for the commands */
+ p$count = (char ***)$malloc( (size_t)($Array_size) * sizeof(char **) );
+
+ for (k=0; k<$Array_size; k++) {
+ /* For each command, find the number of command-line arguments.
+ They are terminated by an empty entry. */
+ /* Find the first entry in the Fortran array for this row */
+ char *p = v$count + k * d$count;
+ int arglen = 0, argcnt=0, i;
+ char **pargs, *pdata;
+ for (argcnt=0; 1; argcnt ++) {
+ char *pin = p + d$count - 1; /* Move to the end of the
+ current Fortran string */
+ while (*pin == ' ' && pin > p) pin--; /* Move backwards until
+ we find a non-blank
+ (Fortran is blank padded)*/
+ if (pin == p && *pin == ' ') {
+ /* found the terminating empty arg */
+ break;
+ }
+ /* Keep track of the amount of space needed */
+ arglen += (pin - p) + 2; /* add 1 for the null */
+ /* Advance to the next entry in the array */
+ p += ($Array_size) * d$count;
+ }
+
+ /* argcnt is the number of provided arguments.
+ Allocate the necessary elements and copy, null terminating copies */
+ pargs = (char **)$malloc( (size_t)(argcnt+1)*sizeof(char *) );
+ pdata = (char *)$malloc( (size_t)arglen );
+ p$count\[k\] = pargs;
+ pargs\[argcnt\] = 0; /* Null terminate end */
+ /* Copy each argument to consequtive locations in pdata,
+ and set the corresponding pointer entry */
+ p = v$count + k * d$count;
+ for (i=0; i<argcnt; i++) {
+ int j;
+ char *pin;
+ p$count\[k\]\[i\] = pdata;
+ /* Move to the end and work back */
+ pin = p + d$count - 1;
+ while (*pin == ' ' && pin > p) pin--;
+ /* Copy and then null terminate */
+ for (j=0; j<(pin-p)+1; j++) { *pdata++ = p\[j\]; }
+ *pdata++ = 0;
+ /* Advance to the next entry in the array */
+ p += ($Array_size) * d$count;
+ }
+ /* Set the terminator */
+ p3[k][i] = 0;
+ }
+ }\n";
+
+ $clean_up .= " if (v$count != (char *)MPI_ARGVS_NULL) {
+ int i;
+ for (i=0; i <$Array_size; i++) {
+ $free( p$count\[i\]\[0\] ); /* Free space allocated to args */
+ $free( p$count\[i\] ); /* Free space allocated to arg array */
+ }
+ /* Free the array of arrays */
+ $free( p$count );
+ }\n";
+}
+
+# ---------------------------------------------------------------------------
+# Convert from an int array to an Aint array for routines taking an Aint as
+# input
+sub intToAintArr_in_decl {
+ my $count = $_[0];
+ print $OUTFD " MPI_Aint *l$count;\n";
+}
+sub intToAintArr_ftoc {
+ my $count = $_[0];
+ print $OUTFD "
+#ifdef HAVE_AINT_LARGER_THAN_FINT
+ if ($Array_size > 0) {
+ int li;
+ l$count = (MPI_Aint *)$malloc( (size_t)($Array_size) * sizeof(MPI_Aint) );
+ for (li=0; li<$Array_size; li++)
+ l$count\[li\] = v$count\[li\];
+ }
+ else l$count = 0;
+#else
+ l$count = v$count;
+#endif\n";
+}
+sub intToAintArr_in_arg {
+ my $count = $_[0];
+ print $OUTFD "l$count";
+}
+# This routine is invoked even for the in case (to free the result)
+sub intToAintArr_in_ctof {
+ my $lname = $_[0];
+ my $vname = $_[1];
+ print $OUTFD "
+#ifdef HAVE_AINT_LARGER_THAN_FINT
+ if ($lname) { $free($lname); }
+#endif\n";
+}
+# ---------------------------------------------------------------------------
+# Convert from an int to an Aint for routines taking an Aint as
+# input
+sub intToAint_in_decl {
+ my $count = $_[0];
+ print $OUTFD " MPI_Aint l$count;\n";
+}
+sub intToAint_ftoc {
+ my $count = $_[0];
+ print $OUTFD " l$count = (MPI_Aint)*v$count;\n";
+}
+sub intToAint_in_arg {
+ my $count = $_[0];
+ print $OUTFD "l$count";
+}
+
+# ---------------------------------------------------------------------------
+# Convert from an FILE to a fortran int
+# (output).
+# -- temp
+sub FileToFint_inout_decl {
+ my $count = $_[0];
+ print $OUTFD " MPI_File l$count = MPI_File_f2c(*v$count);\n";
+}
+sub FileToFint_inout_arg {
+ my $count = $_[0];
+ print $OUTFD "&l$count";
+}
+# -- end temp
+
+sub FileToFint_out_decl {
+ my $count = $_[0];
+ print $OUTFD " MPI_File l$count;\n";
+}
+sub FileToFint_ctof {
+ my $lvar = $_[0];
+ my $gvar = $_[1];
+ print $OUTFD " *$gvar = MPI_File_c2f($lvar);\n";
+}
+sub FileToFint_out_arg {
+ my $count = $_[0];
+ print $OUTFD "&l$count";
+}
+# ---------------------------------------------------------------------------
+# Check for the null datarep functions
+sub checkdatarep_in_decl {
+ my $count = $_[0];
+# if ($count == 2) {
+# print $OUTFD "
+# #ifndef HAVE_MPI_CONVERSION_DEFN
+# #define HAVE_MPI_CONVERSION_DEFN
+# #ifdef F77_NAME_UPPER
+# #define mpi_conversion_fn_null_ MPI_CONVERSION_FN_NULL
+# #elif defined(F77_NAME_LOWER_2USCORE)
+# #define mpi_conversion_fn_null_ mpi_conversion_fn_null__
+# #elif !defined(F77_NAME_LOWER_USCORE)
+# #define mpi_conversion_fn_null_ mpi_conversion_fn_null
+# /* Else leave name alone */
+# #endif
+# /* Add the prototype so the routine knows what this is */
+# extern FORTRAN_API int FORT_CALL mpi_conversion_fn_null_ ( void*v1, MPI_Fint*v2, MPI_Fint*v3, void*v4, MPI_Offset*v5, MPI_Fint *v6, MPI_Fint*v7, MPI_Fint *ierr );
+# #endif
+# ";
+# }
+}
+sub checkdatarep_in_arg {
+ my $count = $_[0];
+ print $OUTFD "v$count";
+}
+sub checkdatarep_ftoc {
+ my $count = $_[0];
+
+ # Check to see if the pointer is the same as the null function
+ # We do something ugly here: we exploit the fact that we know which is
+ # the first argument that needs this definition
+ print $OUTFD "\
+ if (v$count == (MPI_Datarep_conversion_function *)mpi_conversion_fn_null_){
+ v$count = 0;
+ }\n";
+}
+# ---------------------------------------------------------------------------
+# Special post processing for some routines
+sub setF90Type_keyval {
+ my $FD = $_[0];
+ my $argnum = $_[1];
+
+ print $FD "\
+ if (*ierr == MPI_SUCCESS) {
+ MPIR_Keyval_set_proxy( *v$argnum, MPIR_Type_copy_attr_f90_proxy, MPIR_Type_delete_attr_f90_proxy );
+ }\n";
+}
+sub setF90Comm_keyval {
+ my $FD = $_[0];
+ my $argnum = $_[1];
+
+ print $FD "\
+ if (*ierr == MPI_SUCCESS) {
+ MPIR_Keyval_set_proxy( *v$argnum, MPIR_Comm_copy_attr_f90_proxy, MPIR_Comm_delete_attr_f90_proxy );
+ }\n";
+}
+sub setF90Win_keyval {
+ my $FD = $_[0];
+ my $argnum = $_[1];
+
+ print $FD "\
+ if (*ierr == MPI_SUCCESS) {
+ MPIR_Keyval_set_proxy( *v$argnum, MPIR_Win_copy_attr_f90_proxy, MPIR_Win_delete_attr_f90_proxy );
+ }\n";
+}
+sub setF77greq {
+ my $FD = $_[0];
+ my $argnum = $_[1];
+
+ print $FD "\
+ if (*ierr == MPI_SUCCESS) {
+ MPIR_Grequest_set_lang_f77( *v$argnum );
+ }\n";
+}
+
+
+# ---------------------------------------------------------------------------
+# This routine handles the special arguments in the *call*
+sub print_special_call_arg {
+ my $routine_name = $_[0];
+ my $count = $_[1];
+
+ $rule = $special_args{"${routine_name}-$count"};
+ ($direction,$method,$Array_size) = split(/:/,$rule);
+
+ $processing_routine = "${method}_${direction}_arg";
+ &$processing_routine( $count );
+}
+
+# This routine prints any declarations that are needed
+sub print_special_decls {
+ my $routine_name = $_[0];
+
+ if ($returnErrval) {
+ print $OUTFD " int $errparmrval;\n";
+ }
+ if (defined($special_args{$routine_name})) {
+ # First do the declarations
+ foreach $count (split(/:/,$special_args{$routine_name})) {
+ $rule = $special_args{"${routine_name}-$count"};
+ ($direction,$method,$Array_size) = split(/:/,$rule);
+ # Sanity check: method and direction must be nonnull
+ if ($method eq "" || $direction eq "") {
+ print STDERR "Error in special args for argument number $count of $routine_name\n";
+ last;
+ }
+ $processing_routine = "${method}_${direction}_decl";
+ &$processing_routine( $count );
+ }
+ }
+ if (defined($special_args{$routine_name})) {
+ # Then do the precall steps
+ foreach $count (split(/:/,$special_args{$routine_name})) {
+ $rule = $special_args{"${routine_name}-$count"};
+ ($direction,$method,$Array_size) = split(/:/,$rule);
+ if ($direction eq "in") {
+ $processing_routine = "${method}_ftoc";
+ &$processing_routine( $count );
+ }
+ else {
+ $processing_routine = "${method}_out_ftoc";
+ if (defined(&$processing_routine)) {
+ &$processing_routine( $count );
+ }
+ }
+ }
+ }
+}
+
+#
+# --------------------------------------------------------------------------
+# Create mpif.h.in from mpi.h
+#
+# Need to put this into a routine similar to the ReadInterface routine
+# in the c++ version. This will allow us to read both mpi.h.in
+# and mpio.h.in (or other files)
+
+&ReadInterfaceForDefinitions( $prototype_file );
+if ( -s "../../mpi/romio/include/mpio.h.in" && $build_io) {
+ %skipBlocks = ( 'HAVE_MPI_DARRAY_SUBARRAY' => 1,
+ 'HAVE_MPI_INFO' => 1,
+ 'MPICH2' => 1 );
+ &ReadInterfaceForDefinitions( "../../mpi/romio/include/mpio.h.in" );
+ %skipBlocks = ();
+}
+#
+if ($write_mpif) {
+
+ # The ONLY valid comment character for Fortran 77 is a C in column 1
+ # For those Fortran compilers that support it (which is most at this point)
+ # the top-level configure will replace the "C" in column 1 with "!"
+ # (also in column 1)
+ $cchar = "C";
+ open ( MPIFFD, ">mpif.h.in.new" ) || die "Could not open mpif.h.in.new\n";
+
+
+ # Now, write out the file
+ # This first line makes sure that other tools know that this is a
+ # Fortran file
+ print MPIFFD "$cchar /* -*- Mode: Fortran; -*- */\n";
+ print MPIFFD "$cchar \n";
+ print MPIFFD "$cchar (C) 2003 by Argonne National Laboratory and Northwestern University.\n";
+ print MPIFFD "$cchar See COPYRIGHT in top-level directory.\n";
+ print MPIFFD "$cchar \n";
+ print MPIFFD "$cchar DO NOT EDIT\n";
+ print MPIFFD "$cchar This file created by ./buildiface $arg_string\n";
+ print MPIFFD "$cchar \n";
+ #
+ # Status elements
+ # FIXME: The offsets for the status elements are hardwired. If they
+ # change in mpi.h.in, they need to change here as well.
+ print MPIFFD " INTEGER MPI_SOURCE, MPI_TAG, MPI_ERROR\n";
+ print MPIFFD " PARAMETER (MPI_SOURCE=3,MPI_TAG=4,MPI_ERROR=5)\n";
+ print MPIFFD " INTEGER MPI_STATUS_SIZE\n";
+ print MPIFFD " PARAMETER (MPI_STATUS_SIZE=\@MPI_STATUS_SIZE\@)\n";
+ # Temporary until configure handles these. Define as arrays to keep
+ # Fortran compilers from complaining excessively.
+ print MPIFFD " INTEGER MPI_STATUS_IGNORE(MPI_STATUS_SIZE)\n";
+ print MPIFFD " INTEGER MPI_STATUSES_IGNORE(MPI_STATUS_SIZE,1)\n";
+ #
+ # Other special constants. ERRCODES_IGNORE and ARGVS_NULL
+ # are both like STATUS(ES)_IGNORE
+ print MPIFFD " INTEGER MPI_ERRCODES_IGNORE(1)\n";
+ print MPIFFD " CHARACTER*1 MPI_ARGVS_NULL(1,1)\n";
+ # Unfortunately, we cannot parameter initialize this. Further,
+ # there is no default initialization. We could use a block data item...
+ # ARGV_NULL can actually be a single blank string, but it needs
+ # to be typed as a character array
+ print MPIFFD " CHARACTER*1 MPI_ARGV_NULL(1)\n";
+
+ #
+ # Error Classes
+ print MPIFFD " INTEGER MPI_SUCCESS\n";
+ print MPIFFD " PARAMETER (MPI_SUCCESS=0)\n";
+ foreach $key (keys(%mpidef)) {
+ if ($key =~ /MPI_ERR_/) {
+ &print_mpif_int( $key );
+ }
+ }
+ # Predefined error handlers
+ foreach $key (ERRORS_ARE_FATAL, ERRORS_RETURN) {
+ &print_mpif_int( "MPI_$key" );
+ }
+ # Compare operations
+ foreach $key (IDENT,CONGRUENT,SIMILAR,UNEQUAL) {
+ &print_mpif_int( "MPI_$key" );
+ }
+ # Collective operations
+ foreach $key (MAX, MIN, SUM, PROD, LAND, BAND, LOR, BOR, LXOR, BXOR, MINLOC, MAXLOC, REPLACE ) {
+ &print_mpif_int( "MPI_$key" );
+ }
+ # Objects
+ foreach $key ('COMM_WORLD', 'COMM_SELF', 'GROUP_EMPTY', 'COMM_NULL', 'WIN_NULL', 'FILE_NULL', 'GROUP_NULL', 'OP_NULL', 'DATATYPE_NULL', 'REQUEST_NULL', 'ERRHANDLER_NULL', 'INFO_NULL', ) {
+ &print_mpif_int( "MPI_$key" );
+ }
+ # Attributes
+ foreach $key (TAG_UB, HOST, IO, WTIME_IS_GLOBAL, UNIVERSE_SIZE, LASTUSEDCODE, APPNUM, WIN_BASE, WIN_SIZE, WIN_DISP_UNIT ) {
+ # Special cast: The Fortran versions of these attributes have
+ # value 1 greater than the C versions
+ $attrval = $mpidef{"MPI_$key"};
+ print "$key is $attrval\n" if $debug;
+ if ($attrval =~ /^0x/) { $attrval = hex $attrval; }
+ $attrval++;
+ $attrval = "0x" . sprintf "%x", $attrval;
+ print "$key is now $attrval\n" if $debug;
+ $mpidef{"MPI_$key"} = $attrval;
+ &print_mpif_int( "MPI_$key" );
+ }
+ # String sizes
+ # See MPI-2 2.6.2 and 4.12.9; the constants for string lenghts are
+ # defined as one less than the C/C++ version
+
+ # Missing - max processor name!
+ # Handle max processor name here.
+ $mpidef{"MPI_MAX_PROCESSOR_NAME"} = "\@MPI_MAX_PROCESSOR_NAME\@";
+ # Other maximum values
+ foreach $key (MAX_ERROR_STRING, MAX_PORT_NAME,
+ MAX_OBJECT_NAME, MAX_INFO_KEY, MAX_INFO_VAL,
+ MAX_PROCESSOR_NAME, MAX_DATAREP_STRING ) {
+ &print_mpif_int( "MPI_$key", -1 );
+ }
+
+ # predefined constants
+ print MPIFFD " INTEGER MPI_UNDEFINED\n";
+ print MPIFFD " PARAMETER (MPI_UNDEFINED=$mpidef{'MPI_UNDEFINED'})\n";
+ &print_mpif_int( "MPI_KEYVAL_INVALID" );
+ foreach $key ('BSEND_OVERHEAD', 'PROC_NULL', 'ANY_SOURCE', 'ANY_TAG', 'ROOT') {
+ &print_mpif_int( "MPI_$key" );
+ }
+ #
+ # Topology types
+ foreach $key (GRAPH, CART) {
+ &print_mpif_int( "MPI_$key" );
+ }
+ #
+ # version
+ &print_mpif_int( "MPI_VERSION" );
+ &print_mpif_int( "MPI_SUBVERSION" );
+
+ # Special RMA values
+ &print_mpif_int( "MPI_LOCK_EXCLUSIVE" );
+ &print_mpif_int( "MPI_LOCK_SHARED" );
+ #
+ # Datatypes
+ # These are determined and set at configure time
+ foreach $key (COMPLEX, DOUBLE_COMPLEX, LOGICAL, REAL, DOUBLE_PRECISION, INTEGER, '2INTEGER', '2COMPLEX', '2DOUBLE_PRECISION', '2REAL', '2DOUBLE_COMPLEX', CHARACTER) {
+ print MPIFFD " INTEGER MPI_$key\n";
+ print MPIFFD " PARAMETER (MPI_$key=\@MPI_$key\@)\n";
+ }
+ # Value of MPI_BYTE from top level configure!
+ $mpidef{"MPI_BYTE"} = hex "0x4c00010d";
+ foreach $key (BYTE, UB, LB, PACKED) {
+ print MPIFFD " INTEGER MPI_$key\n";
+ print MPIFFD " PARAMETER (MPI_$key=\@MPI_F77_$key\@)\n";
+ }
+ #&print_mpif_int( "MPI_BYTE" );
+ #&print_mpif_int( "MPI_UB" );
+ #&print_mpif_int( "MPI_LB" );
+ #&print_mpif_int( "MPI_PACKED" );
+
+ # Optional types
+ # Warning: Should these use \@MPI_$key\@, since the
+ # C-version must also compute these?
+ foreach $key (INTEGER1, INTEGER2, INTEGER4, INTEGER8, INTEGER16,
+ REAL4, REAL8, REAL16, COMPLEX8, COMPLEX16, COMPLEX32) {
+ print MPIFFD " INTEGER MPI_$key\n";
+ print MPIFFD " PARAMETER (MPI_$key=\@F77_$key\@)\n";
+ }
+ #
+ # Fortran 90 types
+ print MPIFFD " INTEGER MPI_ADDRESS_KIND, MPI_OFFSET_KIND\n";
+ print MPIFFD " PARAMETER (MPI_ADDRESS_KIND=\@ADDRESS_KIND\@)\n";
+ print MPIFFD " PARAMETER (MPI_OFFSET_KIND=\@OFFSET_KIND\@)\n";
+ #
+ # C Types. Note that we need to convert the C hex constant
+ # into a decimal constant for Fortran (there is no standard
+ # for for hex constants in Fortran, and different compilers make
+ # use of different extensions)
+ foreach $key (CHAR, SIGNED_CHAR, UNSIGNED_CHAR, WCHAR, SHORT,
+ UNSIGNED_SHORT, INT, UNSIGNED, LONG, UNSIGNED_LONG,
+ FLOAT, DOUBLE, LONG_DOUBLE, LONG_LONG_INT,
+ UNSIGNED_LONG_LONG, LONG_LONG, FLOAT_INT, DOUBLE_INT,
+ LONG_INT, SHORT_INT, "2INT", LONG_DOUBLE_INT) {
+ print MPIFFD " INTEGER MPI_$key\n";
+ print MPIFFD " PARAMETER (MPI_$key=\@MPI_F77_$key\@)\n";
+ }
+ # C types added in MPI 2.2
+ foreach $key (INT8_T, INT16_T, INT32_T, INT64_T, UINT8_T, UINT16_T,
+ UINT32_T, UINT64_T, C_BOOL, C_FLOAT_COMPLEX, C_COMPLEX,
+ C_DOUBLE_COMPLEX, C_LONG_DOUBLE_COMPLEX, AINT, OFFSET) {
+ print MPIFFD " INTEGER MPI_$key\n";
+ print MPIFFD " PARAMETER (MPI_$key=\@MPI_F77_$key\@)\n";
+ }
+ # Datatype combiners
+ foreach $key (NAMED, DUP, CONTIGUOUS, VECTOR, HVECTOR_INTEGER, HVECTOR,
+ INDEXED, HINDEXED_INTEGER, HINDEXED, INDEXED_BLOCK,
+ STRUCT_INTEGER, STRUCT, SUBARRAY, DARRAY, F90_REAL,
+ F90_COMPLEX, F90_INTEGER, RESIZED) {
+ &print_mpif_int( "MPI_COMBINER_$key" );
+ }
+ # Typeclasses
+ foreach $key (REAL, INTEGER, COMPLEX) {
+ &print_mpif_int( "MPI_TYPECLASS_$key" );
+ }
+
+ # RMA Asserts
+ foreach $mode (NOCHECK, NOSTORE, NOPUT, NOPRECEDE, NOSUCCEED) {
+ &print_mpif_int( "MPI_MODE_$mode" );
+ }
+
+ # Thread values
+ foreach my $threadlevel (SINGLE, FUNNELED, SERIALIZED, MULTIPLE) {
+ &print_mpif_int( "MPI_THREAD_$threadlevel" );
+ }
+
+ # MPI-2 types: Files
+ if ($build_io) {
+ # Modes
+ foreach $mode (RDONLY, RDWR, WRONLY, DELETE_ON_CLOSE, UNIQUE_OPEN,
+ CREATE, EXCL, APPEND, SEQUENTIAL) {
+ &print_mpif_int( "MPI_MODE_$mode" );
+ }
+ # Seek
+ foreach $dir (SET, CUR, END) {
+ &print_mpif_int( "MPI_SEEK_$dir" );
+ }
+ # Order
+ foreach $order (C, FORTRAN) {
+ &print_mpif_int("MPI_ORDER_$order");
+ }
+ # direction
+ foreach $distrib (BLOCK, CYCLIC, NONE, DFLT_DARG) {
+ &print_mpif_int("MPI_DISTRIBUTE_$distrib");
+ }
+ &print_mpif_int( "MPI_DISPLACEMENT_CURRENT", 0,
+ "\@FORTRAN_MPI_OFFSET\@" );
+ }
+ #
+ # Finally, the special symbols
+ print MPIFFD " INTEGER MPI_BOTTOM, MPI_IN_PLACE\n";
+
+ # And the external names. This are necessary to
+ # ensure that these are passed as routines, not implicitly-defined
+ # variables
+ print MPIFFD " EXTERNAL MPI_DUP_FN, MPI_NULL_DELETE_FN, MPI_NULL_COPY_FN\n";
+ # Note that pmpi_wtime can cause problems with some Fortran compilers
+ # if the corresponding routines aren't available (even if not used)
+ print MPIFFD " EXTERNAL MPI_WTIME, MPI_WTICK\n";
+ print MPIFFD " EXTERNAL PMPI_WTIME, PMPI_WTICK\n";
+ # Add the external names for the MPI-2 attribute functions
+ print MPIFFD " EXTERNAL MPI_COMM_DUP_FN, MPI_COMM_NULL_DELETE_FN\n";
+ print MPIFFD " EXTERNAL MPI_COMM_NULL_COPY_FN\n";
+ print MPIFFD " EXTERNAL MPI_WIN_DUP_FN, MPI_WIN_NULL_DELETE_FN\n";
+ print MPIFFD " EXTERNAL MPI_WIN_NULL_COPY_FN\n";
+ print MPIFFD " EXTERNAL MPI_TYPE_DUP_FN, MPI_TYPE_NULL_DELETE_FN\n";
+ print MPIFFD " EXTERNAL MPI_TYPE_NULL_COPY_FN\n";
+ print MPIFFD " EXTERNAL MPI_CONVERSION_FN_NULL\n";
+ # the time/tick functions
+ # Special option. Some compilers (particularly IBM's xl compilers)
+ # allow the user to change the definition of the datatypes, such as
+ # making real 8 bytes and double precision 16. To allow mpif.h
+ # to be used with such compilers, those compilers allow the
+ # use of the non-standard real*8 to force exactly 8 bytes.
+ # WARNING: REAL*8 is not standard and must not be used here.
+ # Instead, the top level configure (in mpich2/configure) will
+ # replace DOUBLE PRECISION with REAL*8 where the Fortran compiler
+ # supports it.
+ print MPIFFD " DOUBLE PRECISION MPI_WTIME, MPI_WTICK\n";
+ print MPIFFD " DOUBLE PRECISION PMPI_WTIME, PMPI_WTICK\n";
+ # We avoid adding the external declarations because some Fortran
+ # compilers then insist on linking with the routines, even if
+ # they are not used. Combined with systems that do not have weak
+ # symbols, and you can get some strange link failures.
+
+ # When building the Fortran interface for Microsoft Windows, there
+ # are some additional compiler directives needed
+ # This provides a hook for any DLL import directives. We need to
+ # make this a configure-time variable because some compilers (in
+ # particular, a version of the Intel Fortran compiler for Linux)
+ # will read directives for other compilers and then flag as fatal
+ # errors directives that it does not support but does recognize.
+ print MPIFFD "\@DLLIMPORT\@\n";
+
+ # Add the common blocks for the special constants
+ # (Use two to avoid problems with continuations)
+ print MPIFFD "\
+ COMMON /MPIPRIV1/ MPI_BOTTOM, MPI_IN_PLACE, MPI_STATUS_IGNORE\n";
+ print MPIFFD "\
+ COMMON /MPIPRIV2/ MPI_STATUSES_IGNORE, MPI_ERRCODES_IGNORE\n";
+ print MPIFFD " SAVE /MPIPRIV1/,/MPIPRIV2/\n";
+ # Add the common block for the character parameter ARGVS_NULL (Fortran
+ # requires character data in a different common block than
+ # non-character data)
+ print MPIFFD "\
+ COMMON /MPIPRIVC/ MPI_ARGVS_NULL, MPI_ARGV_NULL
+ SAVE /MPIPRIVC/\n";
+
+ close( MPIFFD );
+ &ReplaceIfDifferent( "mpif.h.in", "mpif.h.in.new" );
+} # if write_mpif
+
+#
+# Look through $args for parameter names (foo\s+name)
+# and remove them
+sub clean_args {
+ my $newargs = "";
+ my $comma = "";
+ for $parm (split(',',$args)) {
+ # Remove any leading or trailing spaces
+ $parm =~ s/^\s*//;
+ $parm =~ s/\s*$//;
+ # Handle parameters with parameter names
+ # First if handles "int foo", second handles "int *foo"
+ if ( ($parm =~ /^([A-Za-z0-9_]+)\s+[A-Za-z0-9_]+$/) ) {
+ $parm = $1;
+ }
+ elsif ( ($parm =~ /([A-Za-z0-9_]+\s*\*)\s*[A-Za-z0-9_]+$/) ) {
+ $parm = $1;
+ }
+ $newargs .= "$comma$parm";
+ $comma = ",";
+ }
+ print STDERR "$newargs\n" if $debug;
+ $args = $newargs;
+}
+
+# print_type_decl( $FD, $lcname )
+
+sub print_routine_type_decl {
+ my $OUTFD = $_[0];
+ my $lcname = $_[1];
+ # The name "FORTRAN_API" may be use to tell the compiler that
+ #
+ if ($do_subdecls) {
+ print $OUTFD "FORTRAN_API $returnType FORT_CALL ";
+ }
+ else {
+ print $OUTFD "$returnType ";
+ }
+ print $OUTFD "${out_prefix}${lcname}_ ";
+}
+
+#
+# Build the special routines
+sub build_specials {
+ my $filename = "";
+ # The init routine contains some configure-time values.
+ # We may not want to do this if we are supporting multiple
+ # Fortran compilers with different values for Fortran .TRUE. and
+ # .FALSE., but to get started, this is easiest.
+ $OUTFD = "INITFFD";
+ $filename = "initf.c";
+ open( $OUTFD, ">$filename.new" ) || die "Cannot open $filename.new\n";
+ $files[$#files+1] = $filename;
+ &print_header( "MPI_Init", "init", "" );
+
+ &print_routine_type_decl( $OUTFD, "init" );
+ $args = "";
+ &print_args( $OUTFD, $args, 0, "init" );
+ # If an attribute can be added before the code, then do that here.
+ # Gcc only allows attributes on the prototypes, not the function
+ # definitions
+ print $OUTFD "{\n";
+ print $OUTFD "#ifndef F77_RUNTIME_VALUES
+ /* any compile/link time values go here */
+#else
+# error \"Fortran values must be determined at configure time\"
+#endif
+";
+ # See the discussion on MPIR_F_NeedInit at the head of this file
+ print $OUTFD " mpirinitf_(); MPIR_F_NeedInit = 0;\n";
+ print $OUTFD " *ierr = MPI_Init( 0, 0 );\n";
+ # Still to do:
+ # Initialize the Fortran versions of the predefined keyvals.
+ # Find the value of MPI_BOTTOM.
+ # Call a Fortran routine that calls a C routine that is passed
+ # MPI_BOTTOM from the common block.
+ #
+ print $OUTFD "}\n";
+ close ($OUTFD);
+ &ReplaceIfDifferent( $filename, $filename . ".new" );
+ &AddPrototype( "init", $args );
+
+ $OUTFD = "INITFFD";
+ $filename = "initthreadf.c";
+ open( $OUTFD, ">$filename.new" ) || die "Cannot open $filename.new\n";
+ $files[$#files+1] = $filename;
+ $args = "int, int *";
+ &print_header( "MPI_Init_thread", "init_thread", $args );
+
+ &print_routine_type_decl( $OUTFD, "init_thread" );
+ &print_args( $OUTFD, $args, 0, "init_thread" );
+ print $OUTFD "{\n";
+ # See the discussion on MPIR_F_NeedInit at the head of this file
+ print $OUTFD " mpirinitf_(); MPIR_F_NeedInit = 0;\n";
+ print $OUTFD " *ierr = MPI_Init_thread( 0, 0, *v1, v2 );\n";
+ print $OUTFD "}\n";
+ close ($OUTFD);
+ &ReplaceIfDifferent( $filename, $filename . ".new" );
+ &AddPrototype( "init_thread", $args );
+
+ # Functions used by the C init process, but that must be called
+ # from C
+ $OUTFD = "FORTTOC";
+ $filename = "setbot.c";
+ open( $OUTFD, ">$filename.new" ) || die "Cannot open $filename.new\n";
+ #setbot.c is not one of the mpi_sources files
+ #$files[$#files+1] = $filename;
+ &print_copyright;
+
+ print $OUTFD "
+#ifdef F77_NAME_UPPER
+#define mpirinitc_ MPIRINITC
+#define mpirinitc2_ MPIRINITC2
+#elif defined(F77_NAME_LOWER_2USCORE) || defined(F77_NAME_LOWER_USCORE)
+/* leave name alone */
+#else
+#define mpirinitc_ mpirinitc
+#define mpirinitc2_ mpirinitc2
+#endif
+/* These functions are called from Fortran so only need prototypes in
+ this file. Note that the last argument is a character array, so
+ we need to include the elements of the Fortran character \"dope vector\".
+*/
+FORTRAN_API void FORT_CALL mpirinitc_( void *, void *, void *, void *,
+ void *, void * FORT_MIXED_LEN_DECL
+ FORT_END_LEN_DECL );
+FORTRAN_API void FORT_CALL mpirinitc2_( char * FORT_MIXED_LEN_DECL
+ FORT_END_LEN_DECL );
+";
+ # These are here rather than in initf.c to solve some link order
+ # problems for Windows when separate libraries are used for the C and
+ # Fortran routines.
+ # Note that the global variables have values. This is to work around
+ # a bug in some C environments (e.g., Mac OS/X) that don't load
+ # external symbols that don't have a value assigned at compile time
+ # (so called common symbols)
+ print $OUTFD "
+#ifndef F77_USE_BOOLEAN_LITERALS
+#if defined(F77_RUNTIME_VALUES) || !defined(F77_TRUE_VALUE_SET)
+MPI_Fint MPIR_F_TRUE = 1, MPIR_F_FALSE = 0;
+#else
+const MPI_Fint MPIR_F_TRUE=F77_TRUE_VALUE;
+const MPI_Fint MPIR_F_FALSE=F77_FALSE_VALUE;
+#endif
+#endif
+";
+ # MPI-2, section 4.12.5, on the declaration of MPI_F_STATUS_IGNORE
+ # MPI_F_STATUSES_IGNORE as global variables in mpi.h (!)
+ print $OUTFD "
+#ifndef USE_POINTER_FOR_BOTTOM
+int MPIR_F_NeedInit = 1;
+void *MPIR_F_MPI_BOTTOM = 0;
+void *MPIR_F_MPI_IN_PLACE = 0;
+/* MPI_F_STATUS_IGNORE etc must be declared within mpi.h (MPI-2 standard
+ requires this) */
+/*
+void *MPI_F_STATUS_IGNORE = 0;
+void *MPI_F_STATUSES_IGNORE = 0;
+*/
+int *MPI_F_ERRCODES_IGNORE = 0;
+void *MPI_F_ARGVS_NULL = 0;
+#endif
+\n";
+
+
+ print $OUTFD "
+FORTRAN_API void FORT_CALL mpirinitc_( void *a, void *b, void *c, void *d,
+ void *e, void *f FORT_MIXED_LEN(d1)
+ FORT_END_LEN(d1) )
+{
+ MPIR_F_MPI_BOTTOM = a;
+ MPIR_F_MPI_IN_PLACE = b;
+ MPI_F_STATUS_IGNORE = (MPI_Fint *)c;
+ MPI_F_STATUSES_IGNORE = (MPI_Fint *)d;
+ MPI_F_ERRCODES_IGNORE = (int *)e;
+ MPI_F_ARGVS_NULL = f;
+}
+/* Initialize the Fortran ARGV_NULL to a blank. Using this routine
+ avoids potential problems with string manipulation routines that
+ exist in the Fortran runtime but not in the C runtime libraries */
+FORTRAN_API void FORT_CALL mpirinitc2_( char *a FORT_MIXED_LEN(d1)
+ FORT_END_LEN(d1) )
+{
+ *a = ' ';
+}
+";
+ close ($OUTFD);
+ &ReplaceIfDifferent( $filename, $filename . ".new" );
+
+ $OUTFD = "PCONTROLFFD";
+ $filename = "pcontrolf.c";
+ open( $OUTFD, ">$filename.new" ) || die "Cannot open $filename.new\n";
+ $files[$#files+1] = $filename;
+ $args = "int";
+ &print_header( "MPI_Pcontrol", "pcontrol", $args );
+ &print_routine_type_decl( $OUTFD, "pcontrol" );
+ &print_args( $OUTFD, $args, 0, "pcontrol" );
+ #&print_attr;
+ print $OUTFD "{\n";
+ print $OUTFD " *ierr = MPI_Pcontrol( (int)*v1 );\n";
+ print $OUTFD "}\n";
+ close ($OUTFD);
+ &ReplaceIfDifferent( $filename, $filename . ".new" );
+ &AddPrototype( "pcontrol", $args );
+
+ $OUTFD = "ADDRESSFFD";
+ $filename = "addressf.c";
+ open ($OUTFD, ">$filename.new" ) || die "Cannot open $filename.new\n";
+ $files[$#files+1] = $filename;
+ $args = "void *, int *";
+ &print_header( "MPI_Address", "address", $args );
+ # Add the definitions needed for error reporting
+ # (We could use mpiimpl.h, but mpierrs.h should be sufficient)
+ # mpierror.h references FILE *, so needs stdio.h
+ print $OUTFD "#include \"mpierrs.h\"\n";
+ print $OUTFD "#include <stdio.h>\n";
+ print $OUTFD "#include \"mpierror.h\"\n";
+ &print_routine_type_decl( $OUTFD, "address" );
+ &print_args( $OUTFD, $args, 0, "address" );
+ #&print_attr;
+ print $OUTFD "{
+ MPI_Aint a, b;
+ *ierr = MPI_Address( v1, &a );\n";
+ &specialInitStatement( $OUTFD );
+ print $OUTFD "\
+#ifdef USE_POINTER_FOR_BOTTOM
+ b = a;
+#else
+ b = a - (MPIR_Pint) MPIR_F_MPI_BOTTOM;
+#endif
+ *v2 = (MPI_Fint)( b );
+#ifdef HAVE_AINT_LARGER_THAN_FINT
+ /* Check for truncation */
+ if ((MPI_Aint)*v2 - b != 0) {
+ *ierr = MPIR_Err_create_code( MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
+ \"MPI_Address\", __LINE__, MPI_ERR_ARG, \"**inttoosmall\", 0 );
+ (void)MPIR_Err_return_comm( 0, \"MPI_Address\", *ierr );
+ }
+#endif
+}\n";
+ close ($OUTFD);
+ &ReplaceIfDifferent( $filename, $filename . ".new" );
+ &AddPrototype( "address", $args );
+
+ $OUTFD = "GETADDRESSFFD";
+ $filename = "getaddressf.c";
+ open ($OUTFD, ">$filename.new" ) || die "Cannot open $filename.new\n";
+ $files[$#files+1] = $filename;
+ $args = "void *, MPI_FAintp";
+ &print_header( "MPI_Get_address", "get_address", $args );
+ # Add the definitions needed for error reporting
+ # (We could use mpiimpl.h, but mpierrs.h should be sufficient)
+ # mpierror.h references FILE *, so needs stdio.h
+ print $OUTFD "#include \"mpierrs.h\"\n";
+ print $OUTFD "#include <stdio.h>\n";
+ print $OUTFD "#include \"mpierror.h\"\n";
+ &print_routine_type_decl( $OUTFD, "get_address" );
+ &print_args( $OUTFD, $args, 0, "get_address" );
+ #&print_attr;
+ print $OUTFD "{
+ MPI_Aint a;
+ *ierr = MPI_Get_address( v1, &a );\n";
+ &specialInitStatement( $OUTFD );
+ print $OUTFD "\
+#ifndef USE_POINTER_FOR_BOTTOM
+ a = a - (MPIR_Pint) MPIR_F_MPI_BOTTOM;
+#endif
+ *v2 = a;
+}\n";
+ close ($OUTFD);
+ &ReplaceIfDifferent( $filename, $filename . ".new" );
+ &AddPrototype( "get_address", $args );
+
+ $OUTFD = "WTIMEFD";
+ $filename = "wtimef.c";
+ open( $OUTFD, ">$filename.new" ) || die "Cannot open $filename.new\n";
+ $files[$#files+1] = $filename;
+ $returnType = "double";
+ &set_weak_decl( "MPI_Wtime", "void", "double" );
+ &set_weak_decl( "PMPI_Wtime", "void", "double" );
+ &print_header( "MPI_Wtime", "wtime", "" );
+ # mpichtimer.h is needed for the timer definitions
+ print $OUTFD "#include \"mpichconf.h\"\n";
+ print $OUTFD "#include \"mpichtimer.h\"\n";
+ &print_routine_type_decl( $OUTFD, "wtime" );
+ print $OUTFD "( void ) ";
+ #&print_attr;
+ print $OUTFD "{\n";
+ print $OUTFD " double d; MPID_Time_t t;\n
+ MPID_Wtime( &t );
+ MPID_Wtime_todouble( &t, &d );
+ return d;\n";
+ print $OUTFD "}\n";
+ close ($OUTFD);
+ &ReplaceIfDifferent( $filename, $filename . ".new" );
+
+ if ($build_prototypes) {
+ print PROTOFD "extern ";
+ &print_routine_type_decl( PROTOFD, "wtime" );
+ print PROTOFD "( void )";
+ &print_attr( PROTOFD, "${out_prefix}wtime_" );
+ print PROTOFD ";\n";
+ }
+ $returnType = "void";
+
+ $OUTFD = "WTICKFD";
+ $filename = "wtickf.c";
+ open( $OUTFD, ">$filename.new" ) || die "Cannot open $filename.new\n";
+ $files[$#files+1] = $filename;
+ $returnType = "double";
+ &set_weak_decl( "MPI_Wtick", "void", "double" );
+ &set_weak_decl( "PMPI_Wtick", "void", "double" );
+ &print_header( "MPI_Wtick", "wtick", "" );
+ # mpichtimer.h is needed for the timer definitions
+ print $OUTFD "#include \"mpichconf.h\"\n";
+ print $OUTFD "#include \"mpichtimer.h\"\n";
+ &print_routine_type_decl( $OUTFD, "wtick" );
+ print $OUTFD "( void ) ";
+ #&print_attr;
+ print $OUTFD "{\n";
+ print $OUTFD " double d;
+ d = MPID_Wtick( );
+ return d;\n";
+ print $OUTFD "}\n";
+ close ($OUTFD);
+ &ReplaceIfDifferent( $filename, $filename . ".new" );
+
+ if ($build_prototypes) {
+ print PROTOFD "extern ";
+ &print_routine_type_decl( PROTOFD, "wtick" );
+ print PROTOFD "( void )";
+ &print_attr( PROTOFD, "${out_prefix}wtick_" );
+ print PROTOFD ";\n";
+ }
+ $returnType = "void";
+
+ $OUTFD = "KEYVALCREATEF";
+ $filename = "keyval_createf.c";
+ open ($OUTFD, ">$filename.new" ) || die "Cannot open $filename.new\n";
+ $files[$#files+1] = $filename;
+ $args = "MPI_Copy_function , MPI_Delete_function , int *, void *";
+ &print_header( "MPI_Keyval_create", "keyval_create", $args );
+ print $OUTFD "
+#ifndef MPICH_MPI_FROM_PMPI
+#undef MPI_Comm_create_keyval
+#define MPI_Comm_create_keyval PMPI_Comm_create_keyval
+#endif
+";
+
+ print $OUTFD "
+/* The F77 attr copy function prototype and calling convention */
+typedef void (FORT_CALL F77_CopyFunction) (MPI_Fint *, MPI_Fint *, MPI_Fint *, MPI_Fint *,MPI_Fint *, MPI_Fint *, MPI_Fint *);
+
+/* Helper proxy function to thunk the attr copy function call into F77 calling convention */
+static
+int
+MPIR_Comm_copy_attr_f77_proxy(
+ MPI_Comm_copy_attr_function* user_function,
+ MPI_Comm comm,
+ int keyval,
+ void* extra_state,
+ MPIR_AttrType value_type,
+ void* value,
+ void** new_value,
+ int* flag
+ )
+{
+ MPI_Fint ierr = 0;
+ MPI_Fint fhandle = (MPI_Fint)comm;
+ MPI_Fint fkeyval = (MPI_Fint)keyval;
+ MPI_Fint fvalue = (MPI_Fint) MPI_VOID_PTR_CAST_TO_MPI_AINT (value);
+ MPI_Fint* fextra = (MPI_Fint*)extra_state;
+ MPI_Fint fnew = 0;
+ MPI_Fint fflag = 0;
+
+ ((F77_CopyFunction*)user_function)( &fhandle, &fkeyval, fextra, &fvalue, &fnew, &fflag, &ierr );
+
+ *flag = fflag;
+ *new_value = MPI_AINT_CAST_TO_VOID_PTR ((MPI_Aint) fnew);
+ return ierr;
+}
+
+
+/* The F77 attr delete function prototype and calling convention */
+typedef void (FORT_CALL F77_DeleteFunction) (MPI_Fint *, MPI_Fint *, MPI_Fint *, MPI_Fint *, MPI_Fint *);
+
+/* Helper proxy function to thunk the attr delete function call into F77 calling convention */
+static
+int
+MPIR_Comm_delete_attr_f77_proxy(
+ MPI_Comm_delete_attr_function* user_function,
+ MPI_Comm comm,
+ int keyval,
+ MPIR_AttrType value_type,
+ void* value,
+ void* extra_state
+ )
+{
+ MPI_Fint ierr = 0;
+ MPI_Fint fhandle = (MPI_Fint)comm;
+ MPI_Fint fkeyval = (MPI_Fint)keyval;
+ MPI_Fint fvalue = (MPI_Fint) MPI_VOID_PTR_CAST_TO_MPI_AINT (value);
+ MPI_Fint* fextra = (MPI_Fint*)extra_state;
+
+ ((F77_DeleteFunction*)user_function)( &fhandle, &fkeyval, &fvalue, fextra, &ierr );
+ return ierr;
+}
+
+
+";
+ &print_routine_type_decl( $OUTFD, "keyval_create" );
+ &print_args( $OUTFD, $args, 0, "keyval_create" );
+ #&print_attr;
+ print $OUTFD "{
+ *ierr = MPI_Comm_create_keyval( v1, v2, v3, v4 );
+ if (!*ierr) {
+ MPIR_Keyval_set_proxy(*v3, MPIR_Comm_copy_attr_f77_proxy, MPIR_Comm_delete_attr_f77_proxy);
+ }
+}\n";
+ close ($OUTFD);
+ &ReplaceIfDifferent( $filename, $filename . ".new" );
+ &AddPrototype( "keyval_create", $args );
+
+ # Default attribute functions.
+ # We must create separate functions since we cannot rely on
+ # using a preprocessor to alias the names.
+ # OPTION: we could use weak symbols where available to
+ # reduce the number of files.
+ $OUTFD = "DUPFN";
+ $filename = "dup_fnf.c";
+ open ($OUTFD, ">$filename.new" ) || die "Cannot open $filename.new\n";
+ $files[$#files+1] = $filename;
+ $args = "MPI_Fint, MPI_Fint *, void *, void **, void **, MPI_Fint *";
+ &print_header( "mpi_dup_fn", "dup_fn", $args );
+ &print_routine_type_decl( $OUTFD, "dup_fn" );
+ &print_args( $OUTFD, $args, 0, "dup_fn" );
+ #&print_attr;
+ print $OUTFD "{
+ *v5 = *v4;
+ *v6 = MPIR_TO_FLOG(1);
+ *ierr = MPI_SUCCESS;
+}\n";
+ close ($OUTFD);
+ &ReplaceIfDifferent( $filename, $filename . ".new" );
+ &AddPrototype( "dup_fn", $args );
+
+ $OUTFD = "NULLDELFN";
+ $filename = "null_del_fnf.c";
+ open ($OUTFD, ">$filename.new" ) || die "Cannot open $filename.new\n";
+ $files[$#files+1] = $filename;
+ $args = "MPI_Fint *, MPI_Fint *, void *, void *";
+ &print_header( "mpi_null_delete_fn", "null_delete_fn", $args );
+ &print_routine_type_decl( $OUTFD, "null_delete_fn" );
+ &print_args( $OUTFD, $args, 0, "null_delete_fn" );
+ #&print_attr;
+ print $OUTFD "{
+ *ierr = MPI_SUCCESS;
+}\n";
+ close ($OUTFD);
+ &ReplaceIfDifferent( $filename, $filename . ".new" );
+ &AddPrototype( "null_delete_fn", $args );
+
+ $OUTFD = "NULLCOPYFN";
+ $filename = "null_copy_fnf.c";
+ open ($OUTFD, ">$filename.new" ) || die "Cannot open $filename.new\n";
+ $files[$#files+1] = $filename;
+ $args = "MPI_Fint *, MPI_Fint *, void *, void *, void *, int *";
+ &print_header( "mpi_null_copy_fn", "null_copy_fn", $args );
+ &print_routine_type_decl( $OUTFD, "null_copy_fn" );
+ &print_args( $OUTFD, $args, 0, "null_copy_fn" );
+ print $OUTFD "{
+ *ierr = MPI_SUCCESS;
+ *v6 = MPIR_TO_FLOG(0);
+}\n";
+ close ($OUTFD);
+ &ReplaceIfDifferent( $filename, $filename . ".new" );
+ &AddPrototype( "null_copy_fn", $args );
+
+ &WriteAttrDefaults( "comm_" );
+ &WriteAttrDefaults( "win_" );
+ &WriteAttrDefaults( "type_" );
+
+ # Datarep conversion function
+ # This is a special case. We need to define this function
+ # but it should never be called (we convert a reference to it
+ # to a reference to null, which is how the C version of this
+ # routine is defined.
+#
+# This is now part of the register_datarep function
+# $OUTFD = "NULLCONVERSIONFN";
+# $filename = "null_conv_fnf.c";
+# $returnType = "int";
+# open ($OUTFD, ">$filename.new" ) || die "Cannot open $filename.new\n";
+# $files[$#files+1] = $filename;
+# $args = "void *, MPI_Fint *, MPI_Fint *, void *, MPI_Offset *, MPI_Aint *, MPI_Fint *";
+# &print_header( "mpi_conversion_fn_null", "conversion_fn_null", $args,
+# "#ifdef MPI_CONVERSION_FN_NULL\n#undef MPI_CONVERSION_FN_NULL\n#endif\n" );
+# &print_routine_type_decl( $OUTFD, "conversion_fn_null" );
+# &print_args( $OUTFD, $args, 0, "conversion_fn_null" );
+# # This is tricky; we don't want to call this function at all
+# # FIXME
+# print $OUTFD "\n{\n return MPI_SUCCESS;\n}\n";
+# close ($OUTFD);
+# &ReplaceIfDifferent( $filename, $filename . ".new" );
+# &AddPrototype( "conversion_fn_null", $args );
+
+
+ # The status conversion functions.
+ # These are a little different because they are routines that
+ # are called from C.
+ # Also note that we must exclude them from the routines that
+ # are generated for Fortran. These are here because they need to
+ # know how Fortran stores a status (e.g., if C and Fortran integers
+ # are the same size).
+ $OUTFD = "STATUSF2C";
+ $filename = "statusf2c.c";
+ open ($OUTFD, ">$filename.new" ) || die "Cannot open $filename.new\n";
+ $files[$#files+1] = $filename;
+ # Status_f2c and c2f will need to have const added before the input
+ # argument for MPI 2.2
+ print $OUTFD "
+/* -*- Mode: C; c-basic-offset:4 ; -*- */
+/*
+ * (C) 2003 by Argonne National Laboratory and Northwestern University.
+ * See COPYRIGHT in top-level directory.
+ *
+ * This file is automatically generated by ./buildiface
+ * DO NOT EDIT
+ */
+#include \"mpi_fortimpl.h\"
+/* mpierrs.h and mpierror.h for the error code creation */
+#include \"mpierrs.h\"
+#include <stdio.h>
+#include \"mpierror.h\"
+
+/* -- Begin Profiling Symbol Block for routine MPI_Status_f2c */
+#if defined(USE_WEAK_SYMBOLS) && !defined(USE_ONLY_MPI_NAMES)
+#if defined(HAVE_PRAGMA_WEAK)
+#pragma weak MPI_Status_f2c = PMPI_Status_f2c
+#elif defined(HAVE_PRAGMA_HP_SEC_DEF)
+#pragma _HP_SECONDARY_DEF PMPI_Status_f2c MPI_Status_f2c
+#elif defined(HAVE_PRAGMA_CRI_DUP)
+#pragma _CRI duplicate MPI_Status_f2c as PMPI_Status_f2c
+#endif
+#endif
+/* -- End Profiling Symbol Block */
+
+/* Define MPICH_MPI_FROM_PMPI if weak symbols are not supported to build
+ the MPI routines */
+#ifndef MPICH_MPI_FROM_PMPI
+#undef MPI_Status_f2c
+#define MPI_Status_f2c PMPI_Status_f2c
+#endif
+
+#undef FUNCNAME
+#define FUNCNAME MPI_Status_f2c
+
+int MPI_Status_f2c( MPI_Fint *f_status, MPI_Status *c_status )
+{
+ int mpi_errno = MPI_SUCCESS;
+ /* This code assumes that the ints are the same size */\n";
+ &specialInitStatement( $OUTFD );
+print $OUTFD "\
+ if (f_status == MPI_F_STATUS_IGNORE) {
+ /* The call is erroneous (see 4.12.5 in MPI-2) */
+ mpi_errno = MPIR_Err_create_code( MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
+ \"MPI_Status_f2c\", __LINE__, MPI_ERR_OTHER, \"**notfstatignore\", 0 );
+ return MPIR_Err_return_comm( 0, \"MPI_Status_f2c\", mpi_errno );
+ }
+ *c_status = *(MPI_Status *) f_status;
+ return MPI_SUCCESS;
+}\n";
+ close ($OUTFD);
+ &ReplaceIfDifferent( $filename, $filename . ".new" );
+
+ $OUTFD = "STATUSC2F";
+ $filename = "statusc2f.c";
+ open ($OUTFD, ">$filename.new" ) || die "Cannot open $filename.new\n";
+ $files[$#files+1] = $filename;
+ print $OUTFD "
+/* -*- Mode: C; c-basic-offset:4 ; -*- */
+/*
+ * (C) 2003 by Argonne National Laboratory and Northwestern University.
+ * See COPYRIGHT in top-level directory.
+ *
+ * This file is automatically generated by ./buildiface
+ * DO NOT EDIT
+ */
+#include \"mpi_fortimpl.h\"
+/* mpierrs.h and mpierror.h for the error code creation */
+#include \"mpierrs.h\"
+#include <stdio.h>
+#include \"mpierror.h\"
+
+/* -- Begin Profiling Symbol Block for routine MPI_Status_c2f */
+#if defined(USE_WEAK_SYMBOLS) && !defined(USE_ONLY_MPI_NAMES)
+#if defined(HAVE_PRAGMA_WEAK)
+#pragma weak MPI_Status_c2f = PMPI_Status_c2f
+#elif defined(HAVE_PRAGMA_HP_SEC_DEF)
+#pragma _HP_SECONDARY_DEF PMPI_Status_c2f MPI_Status_c2f
+#elif defined(HAVE_PRAGMA_CRI_DUP)
+#pragma _CRI duplicate MPI_Status_c2f as PMPI_Status_c2f
+#endif
+#endif
+/* -- End Profiling Symbol Block */
+
+/* Define MPICH_MPI_FROM_PMPI if weak symbols are not supported to build
+ the MPI routines */
+#ifndef MPICH_MPI_FROM_PMPI
+#undef MPI_Status_c2f
+#define MPI_Status_c2f PMPI_Status_c2f
+#endif
+
+#undef FUNCNAME
+#define FUNCNAME MPI_Status_c2f
+
+int MPI_Status_c2f( MPI_Status *c_status, MPI_Fint *f_status )
+{
+ int mpi_errno = MPI_SUCCESS;
+ /* This code assumes that the ints are the same size */
+ if (c_status == MPI_STATUS_IGNORE ||
+ c_status == MPI_STATUSES_IGNORE) {
+ /* The call is erroneous (see 4.12.5 in MPI-2) */
+ mpi_errno = MPIR_Err_create_code( MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
+ \"MPI_Status_c2f\", __LINE__, MPI_ERR_OTHER, \"**notcstatignore\", 0 );
+ return MPIR_Err_return_comm( 0, \"MPI_Status_c2f\", mpi_errno );
+ }
+ *(MPI_Status *)f_status = *c_status;
+ return MPI_SUCCESS;
+}\n";
+ close ($OUTFD);
+ &ReplaceIfDifferent( $filename, $filename . ".new" );
+
+}
+
+sub print_mpif_int {
+ my $key = $_[0];
+ my $value = $mpidef{$key};
+ my $valueOffset = $_[1];
+ my $inttype = $_[2];
+
+ # integertype lets use change the integer type of the
+ # variable; e.g., to make it integer*8 or integer (kind=MPI_OFFSET_KIND).
+ # This is needed for MPI_DISPLACEMENT_CURRENT.
+ # Because this will need to be set by configure, if set, this
+ # needs to be a configure variable.
+ my $integertype = "INTEGER";
+
+ if (defined($inttype)) {
+ $integertype = $inttype;
+ }
+
+ if (!defined($value) || $value eq "") {
+ print STDERR "No value found for \"$key\"\n";
+ return 0;
+ }
+ # Remove any casts
+ print "Input value for $key = $value\n" if $debug;
+ if ($value =~ /\(MPI/) {
+ $value =~ s/\(MPI_[A-Za-z0-9]*\s*\)//;
+ print "cast removal: $value\n" if $debug;
+ }
+ # Remove any surrounding ()
+ if ($value =~ /\(\s*[-a-fx0-9]*\)/) {
+ $value =~ s/\(\s*([-a-fx0-9]*)\s*\)/$1/;
+ print "paren removal: $value\n" if $debug;
+ }
+ # Convert hex to decimal
+ if ($value =~ /^0x[a-f\d]*/) {
+ $value = hex $value;
+ print "hex conversion: $value\n" if $debug;
+ }
+ if (defined($valueOffset) && $valueOffset ne "0") {
+ if ($value =~ /^-?\d+/) {
+ $value += $valueOffset;
+ }
+ else {
+ $value .= "$valueOffset";
+ }
+ }
+ print MPIFFD " $integertype $key\n";
+ print MPIFFD " PARAMETER ($key=$value)\n";
+}
+
+
+sub ReadAndProcessInterface {
+ my $prototype_file = $_[0];
+ my $protectMPIO = $_[1]; # Wrap MPI-IO routines in ifdefs MPI_MODE_RDONLY
+ my $linecount = 0;
+ my $newfilename = "";
+ my $filename = "";
+ open( FD, "<$prototype_file" ) || die "Cannot open $prototype_file\n";
+
+ # Skip to prototypes
+ while (<FD>) {
+ $linecount ++;
+ if ( /\/\*\s*Begin Prototypes/ ) { last; }
+ }
+
+ # Read each one
+ while (<FD>) {
+ $linecount ++;
+ print $_ if $debug;
+ # In some packages (not MPI but in Parallel netCDF) not all prototypes
+ # have Fortran equivalents. The following lets us skip over them
+ if (/\/\*\s*Begin Skip Prototypes/) {
+ while (<FD>) {
+ if (/\/\*\s*End Skip Prototypes/) { last; }
+ }
+ }
+ if (/\/\*\s*End Prototypes/) { last; }
+
+ # We should also skip #ifndef xxx, for some xxx.
+ if (/^#\s*ifndef\s+(\w*)/) {
+ $ndefname = $1;
+ if (defined($skipBlocks{$ndefname})) {
+ &SkipCPPIfdef( FD );
+ }
+ }
+ # Remove any comments; check for problems
+ $origline = $_;
+ while (/(.*)\/\*(.*?)\*\/(.*)/) {
+ my $removed = $2;
+ $_ = $1.$3;
+ if ($2 =~ /\/\*/) {
+ print STDERR "Error in processing comment within interface file $prototype_file in line $origline";
+ }
+ }
+
+ if (/^int\s+$routine_prefix($routine_pattern)\s*\((.*)/) {
+ $routine_name = $1;
+ $args = $2;
+ while (! ($args =~ /;/)) {
+ $args .= <FD>;
+ $linecount++;
+ }
+ $args =~ s/\)\s*;//g;
+ $args =~ s/[\r\n]*//g;
+ # remove qualifiers from args
+### TEMP - REMEMBER const because we may need it later
+ #$args =~ s/\s*const\s+//g;
+ # Convert MPIO_Request to MPI_Request (temporary)
+# $args =~ s/MPIO_Request/MPI_Request/g;
+
+ # Get the name of the Fortran routine (without the prefix).
+ # Normally, the name is just the lower-case version, but
+ # some libraries (such as NetCDF) use "real" in Fortran
+ # where C uses "float".
+ $lcname = lc($routine_name);
+ if (defined($CtoFName{$lcname})) {
+ $lcname = $CtoFName{$lcname};
+ }
+ # Eventually, we'll create a new file here.
+ # For C++, we may create similar files by looking up
+ # the corresponding routines.
+ if (defined($special_routines{$routine_name})) {
+ print "Skipping $routine_name\n" if $debug;
+ }
+ else {
+ # Check for duplicates in the list of routines
+ if (defined($mpi_routines{$routine_name})) {
+ my $found = "";
+ if (defined($mpiRoutinesFile{$routine_name})) {
+ my $location = $mpiRoutinesFile{$routine_name};
+ $found = "previous prototoype found in $location\n";
+ }
+ print STDERR "Duplicate prototypes for $routine_name in $prototype_file:$linecount\n$found";
+ next;
+ }
+ # Clear variables
+ &clean_args;
+ $mpi_routines{$routine_name} = $args;
+ $mpiRoutinesFile{$routine_name} = "$prototype_file:$linecount";
+
+ $clean_up = "";
+ if ($buildfiles) {
+ if (defined($name_map{$lcname})) {
+ $filename = $name_map{$lcname} . "f.c";
+ }
+ else {
+ $filename = $lcname . "f.c";
+ }
+ $OUTFD = OUTPUTFILED; # Needed for pre 5.6 versions of perl
+ $newfilename = $filename . ".new";
+ open ($OUTFD, ">$newfilename" ) || die "Cannot open $newfilename\n";
+ # Add the name to the list of files"
+ $files[$#files+1] = $filename;
+ }
+ else {
+ $OUTFD = STDOUT;
+ }
+ &print_header( $routine_name, $lcname, $args );
+ if ($do_subdecls) {
+ print $OUTFD "FORTRAN_API $returnType FORT_CALL ";
+ }
+ else {
+ print $OUTFD "$returnType ";
+ }
+ print $OUTFD "${out_prefix}${lcname}_ ";
+ # Print args not only prints the arguments but fills the
+ # array @arg_addresses to indicate the number of dereference
+ # operations are needed to recover the original value (since
+ # all Fortran parameters are passed either by value-result or
+ # by reference, many value parameters in the C calls are
+ # replaced by reference parameters in the Fortran interface.
+ print "Printing arguments for $routine_prefix${lcname}_\n" if $debug;
+ &print_args( $OUTFD, $args, 0, $lcname );
+
+ #&print_attr;
+ print $OUTFD "{\n";
+ &specialInitClear;
+ if ($protectMPIO) {
+ print $OUTFD "#ifdef MPI_MODE_RDONLY\n";
+ }
+ &print_special_decls( $routine_name );
+ if (defined($ChangeCall{$routine_name})) {
+ my ($newName,$extraArgs) =
+ split(/:/,$ChangeCall{$routine_name} );
+ print $OUTFD " $errparmlval = $newName";
+ my $largs = $args . "," . $extraArgs;
+ &print_call_args( $largs );
+ }
+ else {
+ print $OUTFD " $errparmlval = $routine_prefix$routine_name";
+ print "Printing call arguments for mpi_${lcname}_\n" if $debug;
+ &print_call_args( $args );
+ }
+ # Print any post call processing
+ &print_post_call( $routine_name, $args );
+ if ($protectMPIO) {
+ print $OUTFD "#else\n$errparmlval = MPI_ERR_INTERN;\n#endif\n";
+ }
+ if ($returnErrval) {
+ print $OUTFD " return $errparmrval;\n";
+ }
+ print $OUTFD "}\n";
+ if ($buildfiles) {
+ close ($OUTFD);
+ &ReplaceIfDifferent( $filename, $newfilename );
+ }
+ if ($build_prototypes) {
+ if ($do_subdecls) {
+ print PROTOFD "extern FORTRAN_API $returnType FORT_CALL ${out_prefix}${lcname}_ ";
+ }
+ else {
+ print PROTOFD "extern $returnType ${out_prefix}${lcname}_ ";
+ }
+ &print_args( PROTOFD, $args, 0, $lcname );
+ &print_attr( PROTOFD, "${out_prefix}${lcname}_" );
+ print PROTOFD ";\n";
+ }
+ }
+ }
+ }
+}
+
+sub ReadInterfaceForDefinitions {
+ my $prototype_file = $_[0];
+ my $linecount = 0;
+
+ open ( MPIFD, "<$prototype_file" ) || die "Could not open $prototype_file\n";
+ #
+ # First, find the values that we need
+ while (<MPIFD>) {
+ $linecount++;
+ # Remove any comments; check for problems
+ $origline = $_;
+ while (/(.*)\/\*(.*?)\*\/(.*)/) {
+ my $removed = $2;
+ $_ = $1.$3;
+ if ($2 =~ /\/\*/) {
+ print STDERR "Error in processing comment within interface file $prototype_file in line $origline";
+ }
+ }
+
+ # We should also skip #ifndef xxx, for some xxx.
+ if (/^#\s*ifndef\s+(\w*)/) {
+ $ndefname = $1;
+ if (defined($skipBlocks{$ndefname})) {
+ &SkipCPPIfdef( MPIFD );
+ }
+ }
+
+ # Use \S instead of [^\s]. See the comment above
+ if (/^\s*#\s*define\s+(MPI_[A-Za-z_0-9]*)\s+(\S+)(.*)/) {
+ my $name = $1;
+ my $val = $2;
+ my $remainder = $3;
+ print "Found definition of $name as $val\n" if $debug;
+ # If the name has some lower case letters in it, we
+ # need to skip it (e.g., for a define MPI_Comm_c2f...)
+ if ($name =~ /[a-z]/) { next; }
+ if (defined($mpidef{$name})) {
+ # We want to catch the case ((cast) value). In
+ # The above definition, the space will break the
+ # value into the cast (actually, "((cast)").
+ $fullval = "$val $remainder";
+ if ($fullval =~ /\(\(([^\(\)]*)\)\s*([^\(\)]*)\s*\)/) {
+ $val = "(($1)$2)";
+ }
+ if ($mpidef{$name} ne $val) {
+ my $found = "";
+ if (defined($mpidefFile{$name})) {
+ my $location = $mpidefFile{$name};
+ $found = " found in $location";
+ }
+ print STDERR "Attempting to redefine $name with a new value $val found in $prototype_file:$linecount,\nusing original value of $mpidef{$name}$found\n";
+ }
+ }
+ else {
+ $mpidef{$name} = $val;
+ $mpidefFile{$name} = "$prototype_file:$linecount";
+ }
+ }
+ elsif (/typedef\s+enum\s+[A-Za-z0-9_]*\s*{\s*(.*)/) {
+ # Allow a named type
+ # Eat until we find the closing right brace
+ $enum_line = $1;
+ while (! ($enum_line =~ /}/)) {
+ $enum_line .= <MPIFD>;
+ $linecount++;
+ }
+ # Now process for names and values
+ while ( ($enum_line =~ /\s*(MPI_[A-Z_0-9]*)\s*=\s*([a-fx0-9]*)(.*)/ ) ){
+ $mpidef{$1} = $2;
+ $mpidefFile{$1} = "$prototype_file:$linecount";
+ $enum_line = $3;
+ print "Defining $1 as $2\n" if $debug;
+ }
+
+ }
+ elsif (/enum\s+([A-Za-z0-9_]*)\s*{\s*(.*)/) {
+ # Allow a named type
+ # Eat until we find the closing right brace
+ my $enum_name = $1;
+ my $enum_line = $2;
+ while (! ($enum_line =~ /}/)) {
+ print "reading for $enum_name...\n" if $debug;
+ my $newline = <MPIFD>;
+ $newline =~ s/\r*\n//;
+ $enum_line .= $newline;
+ $linecount++;
+ }
+ # Now process for names and values
+ while ( ($enum_line =~ /\s*(MPI_[A-Z_0-9]*)\s*=\s*([a-fx0-9]*)(.*)/ ) ){
+ my $name = $1;
+ my $val = $2;
+ my $remainder = $3;
+ $mpidef{$name} = $val;
+ $mpidefFile{$name} = "$prototype_file:$linecount";
+ $enum_line = $remainder;
+ print "Defining $name as $val\n" if $debug;
+ }
+
+ }
+ }
+ close (MPIFD);
+}
+
+# ----------------------------------------------------------------------------
+# Check for a working autoconf
+#
+# Try the following first
+# in a new directory, create configure.in containing:
+# AC_INIT(configure.in)
+# AC_LANG_FORTRAN77
+# AC_TRY_COMPILE(,[integer a],a=1,a=0)
+# Then run autoconf
+# Then grep endEOF configure. If found (status 0), then autoconf is
+# broken.
+#
+# CheckAutoconf - returns 0 if autoconf works, 1 if broken.
+sub CheckAutoconf {
+ if (! -d "tmp") {
+ mkdir "tmp", 0777 || die "Cannot create temporary directory\n";
+ }
+ open (ACFD, ">tmp/configure.in" ) || die "Cannot create test configure.in\n";
+ print ACFD "AC_INIT(configure.in)\nAC_LANG_FORTRAN77\n";
+ print ACFD "AC_TRY_COMPILE(,[integer a],a=1,a=0)\n";
+ close ACFD;
+
+ chdir 'tmp';
+ $rc = system "autoconf >/dev/null 2>&1 ";
+ $rc = system "grep endEOF configure >/dev/null 2>&1";
+ $rc = !$rc;
+ chdir "..";
+
+ system "rm -rf tmp";
+ return $rc;
+}
+#
+# ISSUES NOT YET HANDLED
+# ----------------------------------------------------------------------------
+# Fortran Integer conversion.
+# If C ints and Fortran integers are not the same size, we have to do
+# more. In the case of arrays, we must make temporary copies.
+# In MPICH1, there is also code for the case where the sizes of
+# the C and Fortran integers are not known. Roughly, the code could look
+# like
+# #ifdef SIZEOF_F77_INTEGER = SIZEOF_INT
+# straight-forward code
+# #else
+# {
+# code that converts arrays, calls routine, frees arrays
+# }
+# #endif
+#
+# There are several options for allocating the temporary arrays
+# For some, like cartesian dimension arrays, it is reasonable to
+# use a predeclared array (and signal an error if too large)
+# For the others, use a predeclared array with a special case
+# for extra-large
+#
+# Scalars:
+# FintToint_in_decl: int *vi$count;
+# FintToint_in_arg: vi$count
+# FintToint_ftoc: vi$count = (int)v$count
+# similar for intToFint_out
+# For arrays,
+# FintTointArray_in_decl ...
+#
+# ----------------------------------------------------------------------------
+# Character buffer handling for choice arguments
+# If Fortran passes character arrays as a pair of arguments (rather than
+# putting the second argument at the end of the arg list), then all of the
+# choice arg routines must check the *count* of the number of arguments,
+# and then, if there are too many args, assume that the choice buffer
+# is a character. Note that for Sendrecv, there is no unique
+# solution unless you know more about the MPI datatypes.
+#
+# ----------------------------------------------------------------------------
+sub SkipCPPIfdef {
+ my $FD = $_[0];
+ my $depth = 1;
+
+ while (<$FD>) {
+ if (/^#\s*endif/) {
+ $depth--;
+ #print "Depth is now $depth\n";
+ }
+ elsif (/^#\s*if/) {
+ $depth++;
+ #print "Depth is now $depth\n";
+ }
+ #print "Skipping $_";
+ if ($depth <= 0) { last; }
+ }
+ return 0;
+}
+# ---------------------------------------------------------------------------
+# Add a prototype for (functionname, arguments)
+sub AddPrototype {
+ my ($funcname,$args) = @_;
+ if ($build_prototypes) {
+ print PROTOFD "extern ";
+ &print_routine_type_decl( PROTOFD, "$funcname" );
+ &print_args( PROTOFD, $args, 1, "$funcname" );
+ &print_attr( PROTOFD, "${out_prefix}${funcname}_" );
+ print PROTOFD ";\n";
+ }
+}
+# ---------------------------------------------------------------------------
+# This function writes the attribute copy/delete/dup functions
+# with a particular prefix (and a null prefix is allowed)
+# WriteAttrDefaults( prefix )
+sub WriteAttrDefaults {
+ my $prefix =$_[0];
+ my $ucprefix = uc($prefix);
+
+ my $filename = "dup_${prefix}fnf.c";
+ open ($OUTFD, ">$filename.new" ) || die "Cannot open $filename.new\n";
+ $files[$#files+1] = $filename;
+ # The dup functions with a prefix in Fortran take an MPI_Aint * as
+ # the argument, not a void *. When sizeof(MPI_Aint) > sizeof(void *),
+ # its important to use an MPI_Aint * instead of a void **
+# $args = "MPI_Fint, MPI_Fint *, void *, void **, void **, MPI_Fint *";
+ $args = "MPI_Fint, MPI_Fint *, void *, MPI_FAintp, MPI_FAintp, MPI_Fint *";
+ &print_header( "mpi_${prefix}dup_fn", "${prefix}dup_fn", $args,
+ "#ifdef MPI_${ucprefix}DUP_FN\n#undef MPI_${ucprefix}DUP_FN\n#endif\n" );
+ &print_routine_type_decl( $OUTFD, "${prefix}dup_fn" );
+ &print_args( $OUTFD, $args, 0, "${prefix}dup_fn" );
+ #&print_attr;
+ print $OUTFD "{
+ *v5 = *v4;
+ *v6 = MPIR_TO_FLOG(1);
+ *ierr = MPI_SUCCESS;
+}\n";
+ close ($OUTFD);
+ &ReplaceIfDifferent( $filename, $filename . ".new" );
+ &AddPrototype( "${prefix}dup_fn", $args );
+
+ $OUTFD = "NULLDELFN";
+ $filename = "null_${prefix}del_fnf.c";
+ open ($OUTFD, ">$filename.new" ) || die "Cannot open $filename.new\n";
+ $files[$#files+1] = $filename;
+ $args = "MPI_Fint *, MPI_Fint *, MPI_FAintp, MPI_FAintp";
+ &print_header( "mpi_${prefix}null_delete_fn", "${prefix}null_delete_fn", $args,
+ "#ifdef MPI_${ucprefix}NULL_DELETE_FN\n#undef MPI_${ucprefix}NULL_DELETE_FN\n#endif\n" );
+ &print_routine_type_decl( $OUTFD, "${prefix}null_delete_fn" );
+ &print_args( $OUTFD, $args, 0, "${prefix}null_delete_fn" );
+ #&print_attr;
+ print $OUTFD "{
+ *ierr = MPI_SUCCESS;
+}\n";
+ close ($OUTFD);
+ &ReplaceIfDifferent( $filename, $filename . ".new" );
+ &AddPrototype( "${prefix}null_delete_fn", $args );
+
+ $OUTFD = "NULLCOPYFN";
+ $filename = "null_${prefix}copy_fnf.c";
+ open ($OUTFD, ">$filename.new" ) || die "Cannot open $filename.new\n";
+ $files[$#files+1] = $filename;
+ $args = "MPI_Fint *, MPI_Fint *, MPI_FAintp, MPI_FAintp, MPI_FAintp, int *";
+ &print_header( "mpi_${prefix}null_copy_fn", "${prefix}null_copy_fn", $args,
+ "#ifdef MPI_${ucprefix}NULL_COPY_FN\n#undef MPI_${ucprefix}NULL_COPY_FN\n#endif\n" );
+ &print_routine_type_decl( $OUTFD, "${prefix}null_copy_fn" );
+ &print_args( $OUTFD, $args, 0, "${prefix}null_copy_fn" );
+ print $OUTFD "{
+ *ierr = MPI_SUCCESS;
+ *v6 = MPIR_TO_FLOG(0);
+}\n";
+ close ($OUTFD);
+ &ReplaceIfDifferent( $filename, $filename . ".new" );
+
+ &AddPrototype( "${prefix}null_copy_fn", $args );
+}
+
+#
+# Replace old file with new file only if new file is different
+# Otherwise, remove new filename
+sub ReplaceIfDifferent {
+ my ($oldfilename,$newfilename) = @_;
+ my $rc = 1;
+ if (-s $oldfilename) {
+ $rc = system "cmp -s $newfilename $oldfilename";
+ $rc >>= 8; # Shift right to get exit status
+ }
+ if ($rc != 0) {
+ # The files differ. Replace the old file
+ # with the new one
+ if (-s $oldfilename) {
+ print STDERR "Replacing $oldfilename\n";
+ unlink $oldfilename;
+ }
+ # else {
+ # print STDERR "Creating $oldfilename\n";
+ # }
+ rename $newfilename, $oldfilename ||
+ die "Could not replace $oldfilename";
+ }
+ else {
+ unlink $newfilename;
+ }
+}
+# ------------------------------------------------------------------------
+# We wish to have the option of adding a special init call for some
+# variables. This lets us ensure that MPI routines that need special
+# symbols (such as MPI_BOTTOM or MPI_IN_PLACE) can initialize them without
+# requiring any Fortran routines be called from the C verison of MPI_Init
+# (this can cause problems if the Fortran object file includes references
+# to compiler-specific symbols, making it difficult and inconvenient at
+# best to link C programs)
+# ------------------------------------------------------------------------
+sub specialInitClear {
+ $specialInitAdded = 0;
+}
+sub specialInitStatement {
+ my $FD = $_[0];
+
+ if ($specialInitAdded) { return; }
+ if (length($specialInitString) > 0) {
+ print $FD $specialInitString . "\n";
+ }
+ $specialInitAdded = 1;
+}
+# ------------------------------------------------------------------------
+# Helper function entries. Only one so far
+sub HelperForRegister_datarep {
+ my $OUTFD = $_[0];
+
+ print $OUTFD "\
+ /* There is a dummy routine, mpi_conversion_fn_null, that is available
+ for use as the conversion function for MPI_Register_datarep.
+ Like the attribute null functions, we provide multiple weak versions
+ of this if possible */
+#if defined(USE_WEAK_SYMBOLS) && defined(HAVE_MULTIPLE_PRAGMA_WEAK)
+extern FORTRAN_API int FORT_CALL mpi_conversion_fn_null_ ( void*v1, MPI_Fint*v2, MPI_Fint*v3, void*v4, MPI_Offset*v5, MPI_Fint *v6, MPI_Fint*v7, MPI_Fint *ierr );
+extern FORTRAN_API int FORT_CALL mpi_conversion_fn_null__ ( void*v1, MPI_Fint*v2, MPI_Fint*v3, void*v4, MPI_Offset*v5, MPI_Fint *v6, MPI_Fint*v7, MPI_Fint *ierr );
+extern FORTRAN_API int FORT_CALL mpi_conversion_fn_null ( void*v1, MPI_Fint*v2, MPI_Fint*v3, void*v4, MPI_Offset*v5, MPI_Fint *v6, MPI_Fint*v7, MPI_Fint *ierr );
+extern FORTRAN_API int FORT_CALL MPI_CONVERSION_FN_NULL ( void*v1, MPI_Fint*v2, MPI_Fint*v3, void*v4, MPI_Offset*v5, MPI_Fint *v6, MPI_Fint*v7, MPI_Fint *ierr );
+/* */
+#ifndef MPICH_MPI_FROM_PMPI
+#pragma weak mpi_conversion_fn_null__ = mpi_conversion_fn_null_
+#pragma weak mpi_conversion_fn_null = mpi_conversion_fn_null_
+#pragma weak MPI_CONVERSION_FN_NULL = mpi_conversion_fn_null_
+#endif /* MPICH_MPI_FROM_PMPI */
+
+#else
+ /* No weak symbols, so simply rename the one version to match the
+ Fortran naming convention */
+#ifdef F77_NAME_UPPER
+#define mpi_conversion_fn_null_ MPI_CONVERSION_FN_NULL
+#elif defined(F77_NAME_LOWER_2USCORE)
+#define mpi_conversion_fn_null_ mpi_conversion_fn_null__
+#elif !defined(F77_NAME_LOWER_USCORE)
+#define mpi_conversion_fn_null_ mpi_conversion_fn_null
+/* Else leave name alone */
+#endif /* Test on name mapping */
+
+/* Add the prototype so the routine knows what this is */
+extern FORTRAN_API int FORT_CALL mpi_conversion_fn_null_ ( void*v1, MPI_Fint*v2, MPI_Fint*v3, void*v4, MPI_Offset*v5, MPI_Fint *v6, MPI_Fint*v7, MPI_Fint *ierr );
+
+
+#endif /* Test on use multiple weak symbols */
+#ifndef MPICH_MPI_FROM_PMPI
+
+/* This isn't a callable function */
+FORTRAN_API int FORT_CALL mpi_conversion_fn_null_ ( void*v1, MPI_Fint*v2, MPI_Fint*v3, void*v4, MPI_Offset*v5, MPI_Fint *v6, MPI_Fint*v7, MPI_Fint *ierr ) {
+ return 0;
+}
+#endif
+
+";
+
+}
+
+sub HelperForType_create_keyval {
+ my $OUTFD = $_[0];
+
+ print $OUTFD "\
+
+/* The F90 attr copy function prototype and calling convention */
+typedef void (FORT_CALL F90_CopyFunction) (MPI_Fint *, MPI_Fint *, MPI_Aint *, MPI_Aint *,MPI_Aint *, MPI_Fint *, MPI_Fint *);
+
+/* Helper proxy function to thunk the attr copy function call into F90 calling convention */
+static
+int
+MPIR_Type_copy_attr_f90_proxy(
+ MPI_Type_copy_attr_function* user_function,
+ MPI_Datatype datatype,
+ int keyval,
+ void* extra_state,
+ MPIR_AttrType value_type,
+ void* value,
+ void** new_value,
+ int* flag
+ )
+{
+ MPI_Fint ierr = 0;
+ MPI_Fint fhandle = (MPI_Fint)datatype;
+ MPI_Fint fkeyval = (MPI_Fint)keyval;
+ MPI_Aint fvalue = MPI_VOID_PTR_CAST_TO_MPI_AINT (value);
+ MPI_Aint* fextra = (MPI_Aint*)extra_state;
+ MPI_Aint fnew = 0;
+ MPI_Fint fflag = 0;
+
+ ((F90_CopyFunction*)user_function)( &fhandle, &fkeyval, fextra, &fvalue, &fnew, &fflag, &ierr );
+
+ *flag = fflag;
+ *new_value = MPI_AINT_CAST_TO_VOID_PTR (fnew);
+ return ierr;
+}
+
+
+/* The F90 attr delete function prototype and calling convention */
+typedef void (FORT_CALL F90_DeleteFunction) (MPI_Fint *, MPI_Fint *, MPI_Aint *, MPI_Aint *, MPI_Fint *);
+
+/* Helper proxy function to thunk the attr delete function call into F77 calling convention */
+static
+int
+MPIR_Type_delete_attr_f90_proxy(
+ MPI_Type_delete_attr_function* user_function,
+ MPI_Datatype datatype,
+ int keyval,
+ MPIR_AttrType value_type,
+ void* value,
+ void* extra_state
+ )
+{
+ MPI_Fint ierr = 0;
+ MPI_Fint fhandle = (MPI_Fint)datatype;
+ MPI_Fint fkeyval = (MPI_Fint)keyval;
+ MPI_Aint fvalue = MPI_VOID_PTR_CAST_TO_MPI_AINT (value);
+ MPI_Aint* fextra = (MPI_Aint*)extra_state;
+
+ ((F90_DeleteFunction*)user_function)( &fhandle, &fkeyval, &fvalue, fextra, &ierr );
+ return ierr;
+}\n";
+}
+
+sub HelperForComm_create_keyval {
+ my $OUTFD = $_[0];
+
+ print $OUTFD "\
+
+/* The F90 attr copy function prototype and calling convention */
+typedef void (FORT_CALL F90_CopyFunction) (MPI_Fint *, MPI_Fint *, MPI_Aint *, MPI_Aint *,MPI_Aint *, MPI_Fint *, MPI_Fint *);
+
+/* Helper proxy function to thunk the attr copy function call into F90 calling convention */
+static
+int
+MPIR_Comm_copy_attr_f90_proxy(
+ MPI_Comm_copy_attr_function* user_function,
+ MPI_Comm comm,
+ int keyval,
+ void* extra_state,
+ MPIR_AttrType value_type,
+ void* value,
+ void** new_value,
+ int* flag
+ )
+{
+ MPI_Fint ierr = 0;
+ MPI_Fint fhandle = (MPI_Fint)comm;
+ MPI_Fint fkeyval = (MPI_Fint)keyval;
+ MPI_Aint fvalue = MPI_VOID_PTR_CAST_TO_MPI_AINT (value);
+ MPI_Aint* fextra = (MPI_Aint*)extra_state;
+ MPI_Aint fnew = 0;
+ MPI_Fint fflag = 0;
+
+ ((F90_CopyFunction*)user_function)( &fhandle, &fkeyval, fextra, &fvalue, &fnew, &fflag, &ierr );
+
+ *flag = fflag;
+ *new_value = MPI_AINT_CAST_TO_VOID_PTR (fnew);
+ return ierr;
+}
+
+
+/* The F90 attr delete function prototype and calling convention */
+typedef void (FORT_CALL F90_DeleteFunction) (MPI_Fint *, MPI_Fint *, MPI_Aint *, MPI_Aint *, MPI_Fint *);
+
+/* Helper proxy function to thunk the attr delete function call into F77 calling convention */
+static
+int
+MPIR_Comm_delete_attr_f90_proxy(
+ MPI_Comm_delete_attr_function* user_function,
+ MPI_Comm comm,
+ int keyval,
+ MPIR_AttrType value_type,
+ void* value,
+ void* extra_state
+ )
+{
+ MPI_Fint ierr = 0;
+ MPI_Fint fhandle = (MPI_Fint)comm;
+ MPI_Fint fkeyval = (MPI_Fint)keyval;
+ MPI_Aint fvalue = MPI_VOID_PTR_CAST_TO_MPI_AINT (value);
+ MPI_Aint* fextra = (MPI_Aint*)extra_state;
+
+ ((F90_DeleteFunction*)user_function)( &fhandle, &fkeyval, &fvalue, fextra, &ierr );
+ return ierr;
+}\n";
+}
+
+sub HelperForWin_create_keyval {
+ my $OUTFD = $_[0];
+
+ print $OUTFD "\
+
+/* The F90 attr copy function prototype and calling convention */
+typedef void (FORT_CALL F90_CopyFunction) (MPI_Fint *, MPI_Fint *, MPI_Aint *, MPI_Aint *,MPI_Aint *, MPI_Fint *, MPI_Fint *);
+
+/* Helper proxy function to thunk the attr copy function call into F90 calling convention */
+static
+int
+MPIR_Win_copy_attr_f90_proxy(
+ MPI_Win_copy_attr_function* user_function,
+ MPI_Win win,
+ int keyval,
+ void* extra_state,
+ MPIR_AttrType value_type,
+ void* value,
+ void** new_value,
+ int* flag
+ )
+{
+ MPI_Fint ierr = 0;
+ MPI_Fint fhandle = (MPI_Fint)win;
+ MPI_Fint fkeyval = (MPI_Fint)keyval;
+ MPI_Aint fvalue = MPI_VOID_PTR_CAST_TO_MPI_AINT (value);
+ MPI_Aint* fextra = (MPI_Aint*)extra_state;
+ MPI_Aint fnew = 0;
+ MPI_Fint fflag = 0;
+
+ ((F90_CopyFunction*)user_function)( &fhandle, &fkeyval, fextra, &fvalue, &fnew, &fflag, &ierr );
+
+ *flag = fflag;
+ *new_value = MPI_AINT_CAST_TO_VOID_PTR (fnew);
+ return ierr;
+}
+
+
+/* The F90 attr delete function prototype and calling convention */
+typedef void (FORT_CALL F90_DeleteFunction) (MPI_Fint *, MPI_Fint *, MPI_Aint *, MPI_Aint *, MPI_Fint *);
+
+/* Helper proxy function to thunk the attr delete function call into F77 calling convention */
+static
+int
+MPIR_Win_delete_attr_f90_proxy(
+ MPI_Win_delete_attr_function* user_function,
+ MPI_Win win,
+ int keyval,
+ MPIR_AttrType value_type,
+ void* value,
+ void* extra_state
+ )
+{
+ MPI_Fint ierr = 0;
+ MPI_Fint fhandle = (MPI_Fint)win;
+ MPI_Fint fkeyval = (MPI_Fint)keyval;
+ MPI_Aint fvalue = MPI_VOID_PTR_CAST_TO_MPI_AINT (value);
+ MPI_Aint* fextra = (MPI_Aint*)extra_state;
+
+ ((F90_DeleteFunction*)user_function)( &fhandle, &fkeyval, &fvalue, fextra, &ierr );
+ return ierr;
+}\n";
+}
+#
+# FWRAPLIB is a special case. We want to compile all of the same files,
+# but with MPICH_MPI_FROM_PMPI defined, even (or especially) if weak symbols
+# are defined.
+#
+sub AddFwrapDefs {
+ &print_line( MAKEFD, "wrap_objs = ", 80, "\\\n\t", 8 );
+ for ($i=0; $i<=$#files; $i++) {
+ $name = $files[$i];
+ # files contains only the "mpi" files, which is what
+ # we want
+ my $basename = $name;
+ $basename =~ s/\.c//;
+ &print_line( MAKEFD, "_w$basename.o ", 80, "\\\n\t", 8 );
+ }
+ &print_endline( MAKEFD );
+ # FWRAPNAME is the name of a library that contains ONLY the
+ # Fortran wrappers
+ print MAKEFD "FWRAPNAME = \@FWRAPNAME\@\n";
+print MAKEFD "\
+lib\${FWRAPNAME}_a_DIR = ROOTDIR/lib\
+lib\${FWRAPNAME}_a_SOURCES = \${wrap_objs}\n";
+}
+
+sub AddFwrapBuild {
+ for ($i=0; $i<=$#files; $i++) {
+ $name = $files[$i];
+ # files contains only the "mpi" files, which is what
+ # we want
+ my $basename = $name;
+ $basename =~ s/\.c//;
+ # Some versions of make won't figure out the $< in this case,
+ # so we use the explicit version
+ # To conform to the newer format of output produced by simplemake,
+ # we output the same set of commands to shorten the output lines
+ # (it seems wierd to optimize make output which is too long to
+ # watch manually anyway, but this seems to be the current expected
+ # practice). (Note that CC is the C++ compiler on some systems;
+ # this use of CC is apparently supposed to be a shorthand for \$(CC),
+ # which may not be correct either.
+ print MAKEFD "_w$basename.o: $name\n";
+ print MAKEFD " \@if [ \"x\$(VERBOSE)\" != \"x1\" ] ; then \\
+ echo \" CC -o _w$basename.o -c -D... \$(srcdir)/$basename.c\" ; \\
+ else \\
+ echo \"\$(C_COMPILE) -o _w$basename.o -c -DMPICH_MPI_FROM_PMPI -DUSE_ONLY_MPI_NAMES \$(srcdir)/$basename.c\" ; \\
+ fi\n";
+ print MAKEFD "\t\@\$(C_COMPILE) -o _w$basename.o -c -DMPICH_MPI_FROM_PMPI -DUSE_ONLY_MPI_NAMES \$(srcdir)/$basename.c\n";
+
+ print MAKEFD "_w$basename.lo: $name\n";
+ print MAKEFD " \@if [ \"x\$(VERBOSE)\" != \"x1\" ] ; then \\
+ echo \" CC -o _sw$basename.o -c -D... \$(srcdir)/$basename.c\" ; \\
+ else \\
+ echo \"\$(C_COMPILE_SHL) -o _sw$basename.o -c -DMPICH_MPI_FROM_PMPI -DUSE_ONLY_MPI_NAMES \$(srcdir)/$basename.c\" ; \\
+ fi\n";
+ print MAKEFD "\t\@\$(C_COMPILE_SHL) -o _sw$basename.o -c -DMPICH_MPI_FROM_PMPI -DUSE_ONLY_MPI_NAMES \$(srcdir)/$basename.c\n";
+ print MAKEFD "\t\@mv -f _sw$basename.o _w$basename.lo\n";
+ }
+}
+
+# Allow multiple underscore versions of names
+# but without the PMPI versions (needed for the wrapper library)
+sub AddFwrapWeakName {
+ my ($lcname, $ucname, $args) = @_;
+
+ print $OUTFD "
+/* These definitions are used only for generating the Fortran wrappers */
+#if defined(USE_WEAK_SYMBOLS) && defined(HAVE_MULTIPLE_PRAGMA_WEAK) && \\
+ defined(USE_ONLY_MPI_NAMES)\n";
+ &print_weak_decl( $OUTFD, "MPI_$ucname", $args, $lcname );
+ &print_weak_decl( $OUTFD, "mpi_${lcname}__", $args, $lcname );
+ &print_weak_decl( $OUTFD, "mpi_${lcname}", $args, $lcname );
+ &print_weak_decl( $OUTFD, "mpi_${lcname}_", $args, $lcname );
+ print $OUTFD "\
+#if defined(F77_NAME_UPPER)
+#pragma weak mpi_${lcname}__ = MPI_${ucname}
+#pragma weak mpi_${lcname}_ = MPI_${ucname}
+#pragma weak mpi_${lcname} = MPI_${ucname}
+#elif defined(F77_NAME_LOWER_2USCORE)
+#pragma weak MPI_$ucname = mpi_${lcname}__
+#pragma weak mpi_${lcname}_ = mpi_${lcname}__
+#pragma weak mpi_${lcname} = mpi_${lcname}__
+#elif defined(F77_NAME_LOWER_USCORE)
+#pragma weak MPI_$ucname = mpi_${lcname}_
+#pragma weak mpi_${lcname}__ = mpi_${lcname}_
+#pragma weak mpi_${lcname} = mpi_${lcname}_
+#else
+#pragma weak MPI_$ucname = mpi_${lcname}
+#pragma weak mpi_${lcname}__ = mpi_${lcname}
+#pragma weak mpi_${lcname}_ = mpi_${lcname}
+#endif
+
+#endif
+";
+}
diff --git a/src/libf/createffiles b/src/libf/createffiles
new file mode 100755
index 0000000..321055b
--- /dev/null
+++ b/src/libf/createffiles
@@ -0,0 +1,24 @@
+#! /bin/sh
+# -*- Mode: shell-script-mode; -*-
+#
+# $Id: createffiles 1162 2013-02-12 20:04:25Z wkliao $
+
+# This is a simple script that creates the Fortran interface files.
+# Usually, it is MPICH_DISTRIBUTION/src/binding/f77/buildiface
+# It makes use of an interface builder developed for MPICH2 and a set of
+# NetCDF-specific descriptions in the file "defs".
+
+if [ -z "$BUILDIFACE" ] ; then
+ BUILDIFACE=./buildiface
+fi
+
+# Build the files
+$BUILDIFACE -infile=../lib/pnetcdf.h -deffile=defs $@
+# Update to the old name
+for file in *f.c mpifnetcdf.h ; do
+ if grep FORT_DLL_SPEC $file >/dev/null 2>&1 ; then
+ rm -f .tmp
+ sed -e 's/FORT_DLL_SPEC/FORTRAN_API/g' $file > .tmp
+ mv .tmp $file
+ fi
+done
diff --git a/src/libf/defs b/src/libf/defs
new file mode 100644
index 0000000..9a5f8d4
--- /dev/null
+++ b/src/libf/defs
@@ -0,0 +1,2547 @@
+#
+# Copyright (C) 2003, Northwestern University and Argonne National Laboratory
+# See COPYRIGHT notice in top-level directory.
+#
+# $Id: defs 2071 2015-08-11 04:39:53Z wkliao $
+
+$routine_prefix = "ncmpi_";
+$routine_pattern = "[a-z0-9_]*";
+$out_prefix = "nfmpi_";
+$do_weak = 0;
+$do_profiling = 0;
+
+## Need MPI_Offset / INTEGER(KIND=MPI_OFFSET_KIND) Fortran interface
+# $tof77{"MPI_Offset"} = "int *";
+# $tof77{"MPI_Offset *"} = "int *";
+# $tof77{"MPI_Offset*"} = "int *";
+# $tof77{"MPI_Offset\[\]"} = "int";
+
+$tof77{"int"} = "int *";
+$tof77{"int64_t"} = "int64_t *";
+$tof77{"int64_t *"} = "int64_t *";
+$tof77{"nc_type"} = "int *";
+$tof77{"nc_type *"} = "int *";
+$tof77{"nc_type*"} = "int *";
+$malloc = "malloc";
+$calloc = "calloc";
+$free = "free";
+$header_file = "mpinetcdf_impl.h";
+
+# $tof77{"NCMPI_Request*"} = "MPI_Fint *";
+# $tof77{"NCMPI_Request*"} = "MPI_Fint *";
+# $tof77{"NCMPI_Request\[\]"} = "int *";
+# $tof77{"MPI_Offset**"} = "MPI_Offset *";
+
+# Error return handling
+$errparmtype = "";
+$errparm = "";
+$errparmlval = "ierr";
+$errparmrval = "ierr";
+$returnErrval = 1;
+$returnType = "int";
+
+#%
+#% Change the handling of input MPI handles
+%argsneedcast = ( 'MPI_Request *' => '(fixme][)(ARG)',
+ 'MPI_Status *' => '(MPI_Status *)(ARG)',
+ 'MPI_File' => 'MPI_File_f2c(ARG)',
+ 'MPI_Comm' => 'MPI_Comm_f2c(ARG)',
+ 'MPI_Comm *' => '(fixme][)(ARG)',
+ 'MPI_Datatype' => 'MPI_Type_f2c(ARG)',
+ 'MPI_Datatype *' => '(fixme][ *)(ARG)',
+ 'MPI_Info *' => '(fixme][)(ARG)',
+ 'MPI_Info' => 'MPI_Info_f2c(ARG)'
+);
+
+# Map some of the names from C to Fortran to replace float with real,
+# schar with int1, short with int2, longlong with int8
+%CtoFName = (
+ 'put_att_schar' => 'put_att_int1',
+ 'get_att_schar' => 'get_att_int1',
+ 'put_var1_schar' => 'put_var1_int1',
+ 'get_var1_schar' => 'get_var1_int1',
+ 'put_var1_schar_all' => 'put_var1_int1_all',
+ 'get_var1_schar_all' => 'get_var1_int1_all',
+ 'put_var_schar' => 'put_var_int1',
+ 'get_var_schar' => 'get_var_int1',
+ 'put_var_schar_all' => 'put_var_int1_all',
+ 'get_var_schar_all' => 'get_var_int1_all',
+ 'put_vara_schar' => 'put_vara_int1',
+ 'get_vara_schar' => 'get_vara_int1',
+ 'put_vara_schar_all' => 'put_vara_int1_all',
+ 'get_vara_schar_all' => 'get_vara_int1_all',
+ 'put_vars_schar' => 'put_vars_int1',
+ 'get_vars_schar' => 'get_vars_int1',
+ 'put_vars_schar_all' => 'put_vars_int1_all',
+ 'get_vars_schar_all' => 'get_vars_int1_all',
+ 'put_varm_schar' => 'put_varm_int1',
+ 'get_varm_schar' => 'get_varm_int1',
+ 'put_varm_schar_all' => 'put_varm_int1_all',
+ 'get_varm_schar_all' => 'get_varm_int1_all',
+
+ 'put_att_short' => 'put_att_int2',
+ 'get_att_short' => 'get_att_int2',
+ 'put_var1_short' => 'put_var1_int2',
+ 'get_var1_short' => 'get_var1_int2',
+ 'put_var1_short_all' => 'put_var1_int2_all',
+ 'get_var1_short_all' => 'get_var1_int2_all',
+ 'put_var_short' => 'put_var_int2',
+ 'get_var_short' => 'get_var_int2',
+ 'put_var_short_all' => 'put_var_int2_all',
+ 'get_var_short_all' => 'get_var_int2_all',
+ 'put_vara_short' => 'put_vara_int2',
+ 'get_vara_short' => 'get_vara_int2',
+ 'put_vara_short_all' => 'put_vara_int2_all',
+ 'get_vara_short_all' => 'get_vara_int2_all',
+ 'put_vars_short' => 'put_vars_int2',
+ 'get_vars_short' => 'get_vars_int2',
+ 'put_vars_short_all' => 'put_vars_int2_all',
+ 'get_vars_short_all' => 'get_vars_int2_all',
+ 'put_varm_short' => 'put_varm_int2',
+ 'get_varm_short' => 'get_varm_int2',
+ 'put_varm_short_all' => 'put_varm_int2_all',
+ 'get_varm_short_all' => 'get_varm_int2_all',
+
+ 'put_att_float' => 'put_att_real',
+ 'get_att_float' => 'get_att_real',
+ 'put_var1_float' => 'put_var1_real',
+ 'get_var1_float' => 'get_var1_real',
+ 'put_var1_float_all' => 'put_var1_real_all',
+ 'get_var1_float_all' => 'get_var1_real_all',
+ 'put_var_float' => 'put_var_real',
+ 'get_var_float' => 'get_var_real',
+ 'put_var_float_all' => 'put_var_real_all',
+ 'get_var_float_all' => 'get_var_real_all',
+ 'put_vara_float' => 'put_vara_real',
+ 'get_vara_float' => 'get_vara_real',
+ 'put_vara_float_all' => 'put_vara_real_all',
+ 'get_vara_float_all' => 'get_vara_real_all',
+ 'put_vars_float' => 'put_vars_real',
+ 'get_vars_float' => 'get_vars_real',
+ 'put_vars_float_all' => 'put_vars_real_all',
+ 'get_vars_float_all' => 'get_vars_real_all',
+ 'put_varm_float' => 'put_varm_real',
+ 'get_varm_float' => 'get_varm_real',
+ 'put_varm_float_all' => 'put_varm_real_all',
+ 'get_varm_float_all' => 'get_varm_real_all',
+
+ 'put_att_longlong' => 'put_att_int8',
+ 'get_att_longlong' => 'get_att_int8',
+ 'put_var1_longlong' => 'put_var1_int8',
+ 'get_var1_longlong' => 'get_var1_int8',
+ 'put_var1_longlong_all' => 'put_var1_int8_all',
+ 'get_var1_longlong_all' => 'get_var1_int8_all',
+ 'put_var_longlong' => 'put_var_int8',
+ 'get_var_longlong' => 'get_var_int8',
+ 'put_var_longlong_all' => 'put_var_int8_all',
+ 'get_var_longlong_all' => 'get_var_int8_all',
+ 'put_vara_longlong' => 'put_vara_int8',
+ 'get_vara_longlong' => 'get_vara_int8',
+ 'put_vara_longlong_all' => 'put_vara_int8_all',
+ 'get_vara_longlong_all' => 'get_vara_int8_all',
+ 'put_vars_longlong' => 'put_vars_int8',
+ 'get_vars_longlong' => 'get_vars_int8',
+ 'put_vars_longlong_all' => 'put_vars_int8_all',
+ 'get_vars_longlong_all' => 'get_vars_int8_all',
+ 'put_varm_longlong' => 'put_varm_int8',
+ 'get_varm_longlong' => 'get_varm_int8',
+ 'put_varm_longlong_all' => 'put_varm_int8_all',
+ 'get_varm_longlong_all' => 'get_varm_int8_all',
+
+ 'put_varn_schar' => 'put_varn_int1',
+ 'get_varn_schar' => 'get_varn_int1',
+ 'put_varn_schar_all' => 'put_varn_int1_all',
+ 'get_varn_schar_all' => 'get_varn_int1_all',
+ 'put_varn_short' => 'put_varn_int2',
+ 'get_varn_short' => 'get_varn_int2',
+ 'put_varn_short_all' => 'put_varn_int2_all',
+ 'get_varn_short_all' => 'get_varn_int2_all',
+ 'put_varn_float' => 'put_varn_real',
+ 'get_varn_float' => 'get_varn_real',
+ 'put_varn_float_all' => 'put_varn_real_all',
+ 'get_varn_float_all' => 'get_varn_real_all',
+ 'put_varn_longlong' => 'put_varn_int8',
+ 'get_varn_longlong' => 'get_varn_int8',
+ 'put_varn_longlong_all' => 'put_varn_int8_all',
+ 'get_varn_longlong_all' => 'get_varn_int8_all',
+
+ 'iput_var1_schar' => 'iput_var1_int1',
+ 'iget_var1_schar' => 'iget_var1_int1',
+ 'iput_var_schar' => 'iput_var_int1',
+ 'iget_var_schar' => 'iget_var_int1',
+ 'iput_vara_schar' => 'iput_vara_int1',
+ 'iget_vara_schar' => 'iget_vara_int1',
+ 'iput_vars_schar' => 'iput_vars_int1',
+ 'iget_vars_schar' => 'iget_vars_int1',
+ 'iput_varm_schar' => 'iput_varm_int1',
+ 'iget_varm_schar' => 'iget_varm_int1',
+
+ 'iput_var1_short' => 'iput_var1_int2',
+ 'iget_var1_short' => 'iget_var1_int2',
+ 'iput_var_short' => 'iput_var_int2',
+ 'iget_var_short' => 'iget_var_int2',
+ 'iput_vara_short' => 'iput_vara_int2',
+ 'iget_vara_short' => 'iget_vara_int2',
+ 'iput_vars_short' => 'iput_vars_int2',
+ 'iget_vars_short' => 'iget_vars_int2',
+ 'iput_varm_short' => 'iput_varm_int2',
+ 'iget_varm_short' => 'iget_varm_int2',
+
+ 'iput_var1_float' => 'iput_var1_real',
+ 'iget_var1_float' => 'iget_var1_real',
+ 'iput_var_float' => 'iput_var_real',
+ 'iget_var_float' => 'iget_var_real',
+ 'iput_vara_float' => 'iput_vara_real',
+ 'iget_vara_float' => 'iget_vara_real',
+ 'iput_vars_float' => 'iput_vars_real',
+ 'iget_vars_float' => 'iget_vars_real',
+ 'iput_varm_float' => 'iput_varm_real',
+ 'iget_varm_float' => 'iget_varm_real',
+
+ 'iput_var1_longlong' => 'iput_var1_int8',
+ 'iget_var1_longlong' => 'iget_var1_int8',
+ 'iput_var_longlong' => 'iput_var_int8',
+ 'iget_var_longlong' => 'iget_var_int8',
+ 'iput_vara_longlong' => 'iput_vara_int8',
+ 'iget_vara_longlong' => 'iget_vara_int8',
+ 'iput_vars_longlong' => 'iput_vars_int8',
+ 'iget_vars_longlong' => 'iget_vars_int8',
+ 'iput_varm_longlong' => 'iput_varm_int8',
+ 'iget_varm_longlong' => 'iget_varm_int8',
+
+ 'iput_varn_schar' => 'iput_varn_int1',
+ 'iget_varn_schar' => 'iget_varn_int1',
+ 'iput_varn_short' => 'iput_varn_int2',
+ 'iget_varn_short' => 'iget_varn_int2',
+ 'iput_varn_float' => 'iput_varn_real',
+ 'iget_varn_float' => 'iget_varn_real',
+ 'iput_varn_longlong' => 'iput_varn_int8',
+ 'iget_varn_longlong' => 'iget_varn_int8',
+
+ 'bput_varn_schar' => 'bput_varn_int1',
+ 'bput_varn_short' => 'bput_varn_int2',
+ 'bput_varn_float' => 'bput_varn_real',
+ 'bput_varn_longlong' => 'bput_varn_int8',
+
+ 'bput_var1_schar' => 'bput_var1_int1',
+ 'bput_var_schar' => 'bput_var_int1',
+ 'bput_vara_schar' => 'bput_vara_int1',
+ 'bput_vars_schar' => 'bput_vars_int1',
+ 'bput_varm_schar' => 'bput_varm_int1',
+
+ 'bput_var1_short' => 'bput_var1_int2',
+ 'bput_var_short' => 'bput_var_int2',
+ 'bput_vara_short' => 'bput_vara_int2',
+ 'bput_vars_short' => 'bput_vars_int2',
+ 'bput_varm_short' => 'bput_varm_int2',
+
+ 'bput_var1_float' => 'bput_var1_real',
+ 'bput_var_float' => 'bput_var_real',
+ 'bput_vara_float' => 'bput_vara_real',
+ 'bput_vars_float' => 'bput_vars_real',
+ 'bput_varm_float' => 'bput_varm_real',
+
+ 'bput_var1_longlong' => 'bput_var1_int8',
+ 'bput_var_longlong' => 'bput_var_int8',
+ 'bput_vara_longlong' => 'bput_vara_int8',
+ 'bput_vars_longlong' => 'bput_vars_int8',
+ 'bput_varm_longlong' => 'bput_varm_int8'
+);
+
+#
+# We really need a easier way to force a default for a particular data type
+# (e.g., so that we can say "use 'in:intToOffset' for MPI_Offset. For arrays,
+# we still need an argument for the array size
+#
+# Other transformations:
+# variable ids and dimension ids must be shifted by 1 (0... in C, 1... in
+# Fortran. This is done with out:OffsetIndex and in:IntIndexIn or
+# out:IntIndex and in:IntIndexIn).
+# Arrays of ids are handled with in:IntIndexInArr:dimension
+
+%special_args = (
+ 'copy_att' => '2:3:5',
+ 'copy_att-2' => 'in:IntIndexIn',
+ 'copy_att-3' => 'in:addnull',
+ 'copy_att-5' => 'in:IntIndexIn',
+ 'create' => 2,
+ 'create-2' => 'in:addnull',
+ 'def_dim' => '2:4',
+ 'def_dim-2' => 'in:addnull',
+ 'def_dim-4' => 'out:IntIndex',
+ 'def_var' => '2:5:6',
+ 'def_var-2' => 'in:addnull',
+ 'def_var-5' => 'in:IntIndexInArr:*v4',
+ 'def_var-6' => 'out:IntIndex',
+ 'del_att' => '2:3',
+ 'del_att-2' => 'in:IntIndexIn',
+ 'del_att-3' => 'in:addnull',
+
+ 'get_att_text' => '2:3:4',
+ 'get_att_text-2' => 'in:IntIndexIn',
+ 'get_att_text-3' => 'in:addnull',
+ 'get_att_text-4' => 'out:charBufferOut',
+ 'get_att_schar' => '2:3:4',
+ 'get_att_schar-2' => 'in:IntIndexIn',
+ 'get_att_schar-3' => 'in:addnull',
+ 'get_att_schar-4' => 'out:int1toschar',
+ 'get_att_short' => '2:3',
+ 'get_att_short-2' => 'in:IntIndexIn',
+ 'get_att_short-3' => 'in:addnull',
+ 'get_att_int' => '2:3',
+ 'get_att_int-2' => 'in:IntIndexIn',
+ 'get_att_int-3' => 'in:addnull',
+## Skip long for fortran binding iface
+# 'get_att_long' => '2:3',
+# 'get_att_long-2' => 'in:IntIndexIn',
+# 'get_att_long-3' => 'in:addnull',
+ 'get_att_float' => '2:3',
+ 'get_att_float-2' => 'in:IntIndexIn',
+ 'get_att_float-3' => 'in:addnull',
+ 'get_att_double' => '2:3',
+ 'get_att_double-2' => 'in:IntIndexIn',
+ 'get_att_double-3' => 'in:addnull',
+ 'get_att_longlong' => '2:3',
+ 'get_att_longlong-2' => 'in:IntIndexIn',
+ 'get_att_longlong-3' => 'in:addnull',
+
+## Skip uchar for fortran binding iface
+# 'get_att_uchar' => '2:3:4',
+# 'get_att_uchar-2' => 'in:IntIndexIn',
+# 'get_att_uchar-3' => 'in:addnull',
+# 'get_att_uchar-4' => 'out:charBufferOut',
+
+ 'get_var1' => '2:3',
+ 'get_var1-2' => 'in:IntIndexIn',
+ 'get_var1-3' => 'in:reorderOffsetArr:true',
+ 'get_var1_all' => '2:3',
+ 'get_var1_all-2' => 'in:IntIndexIn',
+ 'get_var1_all-3' => 'in:reorderOffsetArr:true',
+ 'get_var1_text' => '2:3:4',
+ 'get_var1_text-2' => 'in:IntIndexIn',
+ 'get_var1_text-4' => 'out:charBufferOut',
+ 'get_var1_text-3' => 'in:reorderOffsetArr:true',
+ 'get_var1_text_all' => '2:3:4',
+ 'get_var1_text_all-2' => 'in:IntIndexIn',
+ 'get_var1_text_all-4' => 'out:charBufferOut',
+ 'get_var1_text_all-3' => 'in:reorderOffsetArr:true',
+ 'get_var1_schar' => '2:3',
+ 'get_var1_schar-2' => 'in:IntIndexIn',
+ 'get_var1_schar-3' => 'in:reorderOffsetArr:true',
+ 'get_var1_schar_all' => '2:3',
+ 'get_var1_schar_all-2' => 'in:IntIndexIn',
+ 'get_var1_schar_all-3' => 'in:reorderOffsetArr:true',
+ 'get_var1_short' => '2:3',
+ 'get_var1_short-2' => 'in:IntIndexIn',
+ 'get_var1_short-3' => 'in:reorderOffsetArr:true',
+ 'get_var1_short_all' => '2:3',
+ 'get_var1_short_all-2' => 'in:IntIndexIn',
+ 'get_var1_short_all-3' => 'in:reorderOffsetArr:true',
+ 'get_var1_int' => '2:3',
+ 'get_var1_int-2' => 'in:IntIndexIn',
+ 'get_var1_int-3' => 'in:reorderOffsetArr:true',
+ 'get_var1_int_all' => '2:3',
+ 'get_var1_int_all-2' => 'in:IntIndexIn',
+ 'get_var1_int_all-3' => 'in:reorderOffsetArr:true',
+ 'get_var1_float' => '2:3',
+ 'get_var1_float-2' => 'in:IntIndexIn',
+ 'get_var1_float-3' => 'in:reorderOffsetArr:true',
+ 'get_var1_float_all' => '2:3',
+ 'get_var1_float_all-2' => 'in:IntIndexIn',
+ 'get_var1_float_all-3' => 'in:reorderOffsetArr:true',
+ 'get_var1_double' => '2:3',
+ 'get_var1_double-2' => 'in:IntIndexIn',
+ 'get_var1_double-3' => 'in:reorderOffsetArr:true',
+ 'get_var1_double_all' => '2:3',
+ 'get_var1_double_all-2' => 'in:IntIndexIn',
+ 'get_var1_double_all-3' => 'in:reorderOffsetArr:true',
+ 'get_var1_longlong' => '2:3',
+ 'get_var1_longlong-2' => 'in:IntIndexIn',
+ 'get_var1_longlong-3' => 'in:reorderOffsetArr:true',
+ 'get_var1_longlong_all' => '2:3',
+ 'get_var1_longlong_all-2' => 'in:IntIndexIn',
+ 'get_var1_longlong_all-3' => 'in:reorderOffsetArr:true',
+
+ 'get_var' => '2',
+ 'get_var-2' => 'in:IntIndexIn',
+ 'get_var_all' => '2',
+ 'get_var_all-2' => 'in:IntIndexIn',
+ 'get_var_text' => '2:3',
+ 'get_var_text-2' => 'in:IntIndexIn',
+ 'get_var_text-3' => 'out:charBufferOut',
+ 'get_var_text_all' => '2:3',
+ 'get_var_text_all-2' => 'in:IntIndexIn',
+ 'get_var_text_all-3' => 'out:charBufferOut',
+ 'get_var_schar' => '2',
+ 'get_var_schar-2' => 'in:IntIndexIn',
+ 'get_var_schar_all' => '2',
+ 'get_var_schar_all-2' => 'in:IntIndexIn',
+ 'get_var_short' => '2',
+ 'get_var_short-2' => 'in:IntIndexIn',
+ 'get_var_short_all' => '2',
+ 'get_var_short_all-2' => 'in:IntIndexIn',
+ 'get_var_int' => '2',
+ 'get_var_int-2' => 'in:IntIndexIn',
+ 'get_var_int_all' => '2',
+ 'get_var_int_all-2' => 'in:IntIndexIn',
+ 'get_var_float' => '2',
+ 'get_var_float-2' => 'in:IntIndexIn',
+ 'get_var_float_all' => '2',
+ 'get_var_float_all-2' => 'in:IntIndexIn',
+ 'get_var_double' => '2',
+ 'get_var_double-2' => 'in:IntIndexIn',
+ 'get_var_double_all' => '2',
+ 'get_var_double_all-2' => 'in:IntIndexIn',
+ 'get_var_longlong' => '2',
+ 'get_var_longlong-2' => 'in:IntIndexIn',
+ 'get_var_longlong_all' => '2',
+ 'get_var_longlong_all-2' => 'in:IntIndexIn',
+
+ 'get_vara' => '2:3:4',
+ 'get_vara-2' => 'in:IntIndexIn',
+ 'get_vara-3' => 'in:reorderOffsetArr:true',
+ 'get_vara-4' => 'in:reorderOffsetArr',
+ 'get_vara_all' => '2:3:4',
+ 'get_vara_all-2' => 'in:IntIndexIn',
+ 'get_vara_all-3' => 'in:reorderOffsetArr:true',
+ 'get_vara_all-4' => 'in:reorderOffsetArr',
+ 'get_vara_text' => '2:3:4:5',
+ 'get_vara_text-2' => 'in:IntIndexIn',
+ 'get_vara_text-3' => 'in:reorderOffsetArr:true',
+ 'get_vara_text-4' => 'in:reorderOffsetArr',
+ 'get_vara_text-5' => 'out:charBufferOut',
+ 'get_vara_text_all' => '2:3:4:5',
+ 'get_vara_text_all-2' => 'in:IntIndexIn',
+ 'get_vara_text_all-3' => 'in:reorderOffsetArr:true',
+ 'get_vara_text_all-4' => 'in:reorderOffsetArr',
+ 'get_vara_text_all-5' => 'out:charBufferOut',
+ 'get_vara_schar' => '2:3:4',
+ 'get_vara_schar-2' => 'in:IntIndexIn',
+ 'get_vara_schar-3' => 'in:reorderOffsetArr:true',
+ 'get_vara_schar-4' => 'in:reorderOffsetArr',
+ 'get_vara_schar_all' => '2:3:4',
+ 'get_vara_schar_all-2' => 'in:IntIndexIn',
+ 'get_vara_schar_all-3' => 'in:reorderOffsetArr:true',
+ 'get_vara_schar_all-4' => 'in:reorderOffsetArr',
+ 'get_vara_short' => '2:3:4',
+ 'get_vara_short-2' => 'in:IntIndexIn',
+ 'get_vara_short-3' => 'in:reorderOffsetArr:true',
+ 'get_vara_short-4' => 'in:reorderOffsetArr',
+ 'get_vara_short_all' => '2:3:4',
+ 'get_vara_short_all-2' => 'in:IntIndexIn',
+ 'get_vara_short_all-3' => 'in:reorderOffsetArr:true',
+ 'get_vara_short_all-4' => 'in:reorderOffsetArr',
+ 'get_vara_int' => '2:3:4',
+ 'get_vara_int-2' => 'in:IntIndexIn',
+ 'get_vara_int-3' => 'in:reorderOffsetArr:true',
+ 'get_vara_int-4' => 'in:reorderOffsetArr',
+ 'get_vara_int_all' => '2:3:4',
+ 'get_vara_int_all-2' => 'in:IntIndexIn',
+ 'get_vara_int_all-3' => 'in:reorderOffsetArr:true',
+ 'get_vara_int_all-4' => 'in:reorderOffsetArr',
+ 'get_vara_float' => '2:3:4',
+ 'get_vara_float-2' => 'in:IntIndexIn',
+ 'get_vara_float-3' => 'in:reorderOffsetArr:true',
+ 'get_vara_float-4' => 'in:reorderOffsetArr',
+ 'get_vara_float_all' => '2:3:4',
+ 'get_vara_float_all-2' => 'in:IntIndexIn',
+ 'get_vara_float_all-3' => 'in:reorderOffsetArr:true',
+ 'get_vara_float_all-4' => 'in:reorderOffsetArr',
+ 'get_vara_double' => '2:3:4',
+ 'get_vara_double-2' => 'in:IntIndexIn',
+ 'get_vara_double-3' => 'in:reorderOffsetArr:true',
+ 'get_vara_double-4' => 'in:reorderOffsetArr',
+ 'get_vara_double_all' => '2:3:4',
+ 'get_vara_double_all-2' => 'in:IntIndexIn',
+ 'get_vara_double_all-3' => 'in:reorderOffsetArr:true',
+ 'get_vara_double_all-4' => 'in:reorderOffsetArr',
+ 'get_vara_longlong' => '2:3:4',
+ 'get_vara_longlong-2' => 'in:IntIndexIn',
+ 'get_vara_longlong-3' => 'in:reorderOffsetArr:true',
+ 'get_vara_longlong-4' => 'in:reorderOffsetArr',
+ 'get_vara_longlong_all' => '2:3:4',
+ 'get_vara_longlong_all-2' => 'in:IntIndexIn',
+ 'get_vara_longlong_all-3' => 'in:reorderOffsetArr:true',
+ 'get_vara_longlong_all-4' => 'in:reorderOffsetArr',
+
+ 'get_vars' => '2:3:4:5',
+ 'get_vars-2' => 'in:IntIndexIn',
+ 'get_vars-3' => 'in:reorderOffsetArr:true',
+ 'get_vars-4' => 'in:reorderOffsetArr',
+ 'get_vars-5' => 'in:reorderOffsetArr',
+ 'get_vars_all' => '2:3:4:5',
+ 'get_vars_all-2' => 'in:IntIndexIn',
+ 'get_vars_all-3' => 'in:reorderOffsetArr:true',
+ 'get_vars_all-4' => 'in:reorderOffsetArr',
+ 'get_vars_all-5' => 'in:reorderOffsetArr',
+ 'get_vars_text' => '2:3:4:5:6',
+ 'get_vars_text-2' => 'in:IntIndexIn',
+ 'get_vars_text-3' => 'in:reorderOffsetArr:true',
+ 'get_vars_text-4' => 'in:reorderOffsetArr',
+ 'get_vars_text-5' => 'in:reorderOffsetArr',
+ 'get_vars_text-6' => 'out:charBufferOut',
+ 'get_vars_text_all' => '2:3:4:5:6',
+ 'get_vars_text_all-2' => 'in:IntIndexIn',
+ 'get_vars_text_all-3' => 'in:reorderOffsetArr:true',
+ 'get_vars_text_all-4' => 'in:reorderOffsetArr',
+ 'get_vars_text_all-5' => 'in:reorderOffsetArr',
+ 'get_vars_text_all-6' => 'out:charBufferOut',
+ 'get_vars_schar' => '2:3:4:5',
+ 'get_vars_schar-2' => 'in:IntIndexIn',
+ 'get_vars_schar-3' => 'in:reorderOffsetArr:true',
+ 'get_vars_schar-4' => 'in:reorderOffsetArr',
+ 'get_vars_schar-5' => 'in:reorderOffsetArr',
+ 'get_vars_schar_all' => '2:3:4:5',
+ 'get_vars_schar_all-2' => 'in:IntIndexIn',
+ 'get_vars_schar_all-3' => 'in:reorderOffsetArr:true',
+ 'get_vars_schar_all-4' => 'in:reorderOffsetArr',
+ 'get_vars_schar_all-5' => 'in:reorderOffsetArr',
+ 'get_vars_short' => '2:3:4:5',
+ 'get_vars_short-2' => 'in:IntIndexIn',
+ 'get_vars_short-3' => 'in:reorderOffsetArr:true',
+ 'get_vars_short-4' => 'in:reorderOffsetArr',
+ 'get_vars_short-5' => 'in:reorderOffsetArr',
+ 'get_vars_short_all' => '2:3:4:5',
+ 'get_vars_short_all-2' => 'in:IntIndexIn',
+ 'get_vars_short_all-3' => 'in:reorderOffsetArr:true',
+ 'get_vars_short_all-4' => 'in:reorderOffsetArr',
+ 'get_vars_short_all-5' => 'in:reorderOffsetArr',
+ 'get_vars_int' => '2:3:4:5',
+ 'get_vars_int-2' => 'in:IntIndexIn',
+ 'get_vars_int-3' => 'in:reorderOffsetArr:true',
+ 'get_vars_int-4' => 'in:reorderOffsetArr',
+ 'get_vars_int-5' => 'in:reorderOffsetArr',
+ 'get_vars_int_all' => '2:3:4:5',
+ 'get_vars_int_all-2' => 'in:IntIndexIn',
+ 'get_vars_int_all-3' => 'in:reorderOffsetArr:true',
+ 'get_vars_int_all-4' => 'in:reorderOffsetArr',
+ 'get_vars_int_all-5' => 'in:reorderOffsetArr',
+ 'get_vars_float' => '2:3:4:5',
+ 'get_vars_float-2' => 'in:IntIndexIn',
+ 'get_vars_float-3' => 'in:reorderOffsetArr:true',
+ 'get_vars_float-4' => 'in:reorderOffsetArr',
+ 'get_vars_float-5' => 'in:reorderOffsetArr',
+ 'get_vars_float_all' => '2:3:4:5',
+ 'get_vars_float_all-2' => 'in:IntIndexIn',
+ 'get_vars_float_all-3' => 'in:reorderOffsetArr:true',
+ 'get_vars_float_all-4' => 'in:reorderOffsetArr',
+ 'get_vars_float_all-5' => 'in:reorderOffsetArr',
+ 'get_vars_double' => '2:3:4:5',
+ 'get_vars_double-2' => 'in:IntIndexIn',
+ 'get_vars_double-3' => 'in:reorderOffsetArr:true',
+ 'get_vars_double-4' => 'in:reorderOffsetArr',
+ 'get_vars_double-5' => 'in:reorderOffsetArr',
+ 'get_vars_double_all' => '2:3:4:5',
+ 'get_vars_double_all-2' => 'in:IntIndexIn',
+ 'get_vars_double_all-3' => 'in:reorderOffsetArr:true',
+ 'get_vars_double_all-4' => 'in:reorderOffsetArr',
+ 'get_vars_double_all-5' => 'in:reorderOffsetArr',
+ 'get_vars_longlong' => '2:3:4:5',
+ 'get_vars_longlong-2' => 'in:IntIndexIn',
+ 'get_vars_longlong-3' => 'in:reorderOffsetArr:true',
+ 'get_vars_longlong-4' => 'in:reorderOffsetArr',
+ 'get_vars_longlong-5' => 'in:reorderOffsetArr',
+ 'get_vars_longlong_all' => '2:3:4:5',
+ 'get_vars_longlong_all-2' => 'in:IntIndexIn',
+ 'get_vars_longlong_all-3' => 'in:reorderOffsetArr:true',
+ 'get_vars_longlong_all-4' => 'in:reorderOffsetArr',
+ 'get_vars_longlong_all-5' => 'in:reorderOffsetArr',
+
+ 'get_varm' => '2:3:4:5:6',
+ 'get_varm-2' => 'in:IntIndexIn',
+ 'get_varm-3' => 'in:reorderOffsetArr:true',
+ 'get_varm-4' => 'in:reorderOffsetArr',
+ 'get_varm-5' => 'in:reorderOffsetArr',
+ 'get_varm-6' => 'in:reorderOffsetArr',
+ 'get_varm_all' => '2:3:4:5:6',
+ 'get_varm_all-2' => 'in:IntIndexIn',
+ 'get_varm_all-3' => 'in:reorderOffsetArr:true',
+ 'get_varm_all-4' => 'in:reorderOffsetArr',
+ 'get_varm_all-5' => 'in:reorderOffsetArr',
+ 'get_varm_all-6' => 'in:reorderOffsetArr',
+ 'get_varm_text' => '2:3:4:5:6:7',
+ 'get_varm_text-2' => 'in:IntIndexIn',
+ 'get_varm_text-3' => 'in:reorderOffsetArr:true',
+ 'get_varm_text-4' => 'in:reorderOffsetArr',
+ 'get_varm_text-5' => 'in:reorderOffsetArr',
+ 'get_varm_text-6' => 'in:reorderOffsetArr',
+ 'get_varm_text-7' => 'out:charBufferOut',
+ 'get_varm_text_all' => '2:3:4:5:6:7',
+ 'get_varm_text_all-2' => 'in:IntIndexIn',
+ 'get_varm_text_all-3' => 'in:reorderOffsetArr:true',
+ 'get_varm_text_all-4' => 'in:reorderOffsetArr',
+ 'get_varm_text_all-5' => 'in:reorderOffsetArr',
+ 'get_varm_text_all-6' => 'in:reorderOffsetArr',
+ 'get_varm_text_all-7' => 'out:charBufferOut',
+ 'get_varm_schar' => '2:3:4:5:6',
+ 'get_varm_schar-2' => 'in:IntIndexIn',
+ 'get_varm_schar-3' => 'in:reorderOffsetArr:true',
+ 'get_varm_schar-4' => 'in:reorderOffsetArr',
+ 'get_varm_schar-5' => 'in:reorderOffsetArr',
+ 'get_varm_schar-6' => 'in:reorderOffsetArr',
+ 'get_varm_schar_all' => '2:3:4:5:6',
+ 'get_varm_schar_all-2' => 'in:IntIndexIn',
+ 'get_varm_schar_all-3' => 'in:reorderOffsetArr:true',
+ 'get_varm_schar_all-4' => 'in:reorderOffsetArr',
+ 'get_varm_schar_all-5' => 'in:reorderOffsetArr',
+ 'get_varm_schar_all-6' => 'in:reorderOffsetArr',
+ 'get_varm_short' => '2:3:4:5:6',
+ 'get_varm_short-2' => 'in:IntIndexIn',
+ 'get_varm_short-3' => 'in:reorderOffsetArr:true',
+ 'get_varm_short-4' => 'in:reorderOffsetArr',
+ 'get_varm_short-5' => 'in:reorderOffsetArr',
+ 'get_varm_short-6' => 'in:reorderOffsetArr',
+ 'get_varm_short_all' => '2:3:4:5:6',
+ 'get_varm_short_all-2' => 'in:IntIndexIn',
+ 'get_varm_short_all-3' => 'in:reorderOffsetArr:true',
+ 'get_varm_short_all-4' => 'in:reorderOffsetArr',
+ 'get_varm_short_all-5' => 'in:reorderOffsetArr',
+ 'get_varm_short_all-6' => 'in:reorderOffsetArr',
+ 'get_varm_int' => '2:3:4:5:6',
+ 'get_varm_int-2' => 'in:IntIndexIn',
+ 'get_varm_int-3' => 'in:reorderOffsetArr:true',
+ 'get_varm_int-4' => 'in:reorderOffsetArr',
+ 'get_varm_int-5' => 'in:reorderOffsetArr',
+ 'get_varm_int-6' => 'in:reorderOffsetArr',
+ 'get_varm_int_all' => '2:3:4:5:6',
+ 'get_varm_int_all-2' => 'in:IntIndexIn',
+ 'get_varm_int_all-3' => 'in:reorderOffsetArr:true',
+ 'get_varm_int_all-4' => 'in:reorderOffsetArr',
+ 'get_varm_int_all-5' => 'in:reorderOffsetArr',
+ 'get_varm_int_all-6' => 'in:reorderOffsetArr',
+ 'get_varm_float' => '2:3:4:5:6',
+ 'get_varm_float-2' => 'in:IntIndexIn',
+ 'get_varm_float-3' => 'in:reorderOffsetArr:true',
+ 'get_varm_float-4' => 'in:reorderOffsetArr',
+ 'get_varm_float-5' => 'in:reorderOffsetArr',
+ 'get_varm_float-6' => 'in:reorderOffsetArr',
+ 'get_varm_float_all' => '2:3:4:5:6',
+ 'get_varm_float_all-2' => 'in:IntIndexIn',
+ 'get_varm_float_all-3' => 'in:reorderOffsetArr:true',
+ 'get_varm_float_all-4' => 'in:reorderOffsetArr',
+ 'get_varm_float_all-5' => 'in:reorderOffsetArr',
+ 'get_varm_float_all-6' => 'in:reorderOffsetArr',
+ 'get_varm_double' => '2:3:4:5:6',
+ 'get_varm_double-2' => 'in:IntIndexIn',
+ 'get_varm_double-3' => 'in:reorderOffsetArr:true',
+ 'get_varm_double-4' => 'in:reorderOffsetArr',
+ 'get_varm_double-5' => 'in:reorderOffsetArr',
+ 'get_varm_double-6' => 'in:reorderOffsetArr',
+ 'get_varm_double_all' => '2:3:4:5:6',
+ 'get_varm_double_all-2' => 'in:IntIndexIn',
+ 'get_varm_double_all-3' => 'in:reorderOffsetArr:true',
+ 'get_varm_double_all-4' => 'in:reorderOffsetArr',
+ 'get_varm_double_all-5' => 'in:reorderOffsetArr',
+ 'get_varm_double_all-6' => 'in:reorderOffsetArr',
+ 'get_varm_longlong' => '2:3:4:5:6',
+ 'get_varm_longlong-2' => 'in:IntIndexIn',
+ 'get_varm_longlong-3' => 'in:reorderOffsetArr:true',
+ 'get_varm_longlong-4' => 'in:reorderOffsetArr',
+ 'get_varm_longlong-5' => 'in:reorderOffsetArr',
+ 'get_varm_longlong-6' => 'in:reorderOffsetArr',
+ 'get_varm_longlong_all' => '2:3:4:5:6',
+ 'get_varm_longlong_all-2' => 'in:IntIndexIn',
+ 'get_varm_longlong_all-3' => 'in:reorderOffsetArr:true',
+ 'get_varm_longlong_all-4' => 'in:reorderOffsetArr',
+ 'get_varm_longlong_all-5' => 'in:reorderOffsetArr',
+ 'get_varm_longlong_all-6' => 'in:reorderOffsetArr',
+
+ 'inq' => '5',
+ 'inq-5' => 'out:IntDimIndex',
+ 'inq_att' => '2:3',
+ 'inq_att-2' => 'in:IntIndexIn',
+ 'inq_att-3' => 'in:addnull',
+ 'inq_attid' => '2:3:4',
+ 'inq_attid-2' => 'in:IntIndexIn',
+ 'inq_attid-3' => 'in:addnull',
+ 'inq_attid-4' => 'out:IntIndex',
+ 'inq_attlen' => '2:3',
+ 'inq_attlen-2' => 'in:IntIndexIn',
+ 'inq_attlen-3' => 'in:addnull',
+ 'inq_attname' => '2:3:4',
+ 'inq_attname-2' => 'in:IntIndexIn',
+ 'inq_attname-3' => 'in:IntIndexIn',
+ 'inq_attname-4' => 'out:blankpad',
+ 'inq_atttype' => '2:3',
+ 'inq_atttype-2' => 'in:IntIndexIn',
+ 'inq_atttype-3' => 'in:addnull',
+ 'inq_attdim' => 3,
+ 'inq_attdim-3' => 'in:addnull',
+ 'inq_dim' => '2:3',
+ 'inq_dim-2' => 'in:IntIndexIn',
+ 'inq_dim-3' => 'out:blankpad',
+ 'inq_dimid' => '2:3',
+ 'inq_dimid-2' => 'in:addnull',
+ 'inq_dimid-3' => 'out:IntIndex',
+ 'inq_dimlen' => '2',
+ 'inq_dimlen-2' => 'in:IntIndexIn',
+ 'inq_dimname' => '2:3',
+ 'inq_dimname-2' => 'in:IntIndexIn',
+ 'inq_dimname-3' => 'out:blankpad',
+ 'inq_unlimdim' => 2,
+ 'inq_unlimdim-2' => 'out:IntIndex',
+ 'inq_var' => '2:3:6',
+ 'inq_var-2' => 'in:IntIndexIn',
+ 'inq_var-3' => 'out:blankpad',
+ 'inq_var-6' => 'out:reorderIntArrOut',
+ 'inq_vardimid' => '2:3',
+ 'inq_vardimid-2' => 'in:IntIndexIn',
+ 'inq_vardimid-3' => 'out:reorderIntArrOut',
+ 'inq_varid' => '2:3',
+ 'inq_varid-2' => 'in:addnull',
+ 'inq_varid-3' => 'out:IntIndex',
+ 'inq_varname' => '2:3',
+ 'inq_varname-2' => 'in:IntIndexIn',
+ 'inq_varname-3' => 'out:blankpad',
+ 'inq_varnatts' => '2',
+ 'inq_varnatts-2' => 'in:IntIndexIn',
+ 'inq_varndims' => '2',
+ 'inq_varndims-2' => 'in:IntIndexIn',
+ 'inq_vartype' => '2',
+ 'inq_vartype-2' => 'in:IntIndexIn',
+ 'inq_varoffset' => '2',
+ 'inq_varoffset-2' => 'in:IntIndexIn',
+ 'open' => 2,
+ 'open-2' => 'in:addnull',
+ 'delete' => 1,
+ 'delete-1' => 'in:addnull',
+ 'def_var_fill' => '2',
+ 'def_var_fill-2' => 'in:IntIndexIn',
+ 'inq_var_fill' => '2',
+ 'inq_var_fill-2' => 'in:IntIndexIn',
+ 'fill_var_rec' => '2:3',
+ 'fill_var_rec-2' => 'in:IntIndexIn',
+ 'fill_var_rec-3' => 'in:OffsetIndexIn',
+
+ 'put_att_text' => '2:3:5',
+ 'put_att_text-2' => 'in:IntIndexIn',
+ 'put_att_text-3' => 'in:addnull',
+ 'put_att_text-5' => 'in:charBufferIn',
+ 'put_att_schar' => '2:3:6',
+ 'put_att_schar-2' => 'in:IntIndexIn',
+ 'put_att_schar-3' => 'in:addnull',
+ 'put_att_schar-6' => 'in:int1toschar',
+ 'put_att_short' => '2:3',
+ 'put_att_short-2' => 'in:IntIndexIn',
+ 'put_att_short-3' => 'in:addnull',
+ 'put_att_int' => '2:3',
+ 'put_att_int-2' => 'in:IntIndexIn',
+ 'put_att_int-3' => 'in:addnull',
+ 'put_att_float' => '2:3',
+ 'put_att_float-2' => 'in:IntIndexIn',
+ 'put_att_float-3' => 'in:addnull',
+ 'put_att_double' => '2:3',
+ 'put_att_double-2' => 'in:IntIndexIn',
+ 'put_att_double-3' => 'in:addnull',
+ 'put_att_longlong' => '2:3',
+ 'put_att_longlong-2' => 'in:IntIndexIn',
+ 'put_att_longlong-3' => 'in:addnull',
+## Skip long for fortran binding iface
+# 'put_att_long' => '2:3',
+# 'put_att_long-2' => 'in:IntIndexIn',
+# 'put_att_long-3' => 'in:addnull',
+# 'put_att_long-5' => 'in:intToOffset',
+
+## Skip uchar for fortran binding iface
+# 'put_att_uchar' => '2:3',
+# 'put_att_uchar-2' => 'in:IntIndexIn',
+# 'put_att_uchar-3' => 'in:charBufferIn',
+# 'put_att_uchar-5' => 'in:intToOffset',
+
+ 'put_var1' => '2:3',
+ 'put_var1-2' => 'in:IntIndexIn',
+ 'put_var1-3' => 'in:reorderOffsetArr:true',
+ 'put_var1_all' => '2:3',
+ 'put_var1_all-2' => 'in:IntIndexIn',
+ 'put_var1_all-3' => 'in:reorderOffsetArr:true',
+ 'put_var1_text' => '2:3:4',
+ 'put_var1_text-2' => 'in:IntIndexIn',
+ 'put_var1_text-3' => 'in:reorderOffsetArr:true',
+ 'put_var1_text-4' => 'in:charBufferIn',
+ 'put_var1_text_all' => '2:3:4',
+ 'put_var1_text_all-2' => 'in:IntIndexIn',
+ 'put_var1_text_all-3' => 'in:reorderOffsetArr:true',
+ 'put_var1_text_all-4' => 'in:charBufferIn',
+ 'put_var1_schar' => '2:3',
+ 'put_var1_schar-2' => 'in:IntIndexIn',
+ 'put_var1_schar-3' => 'in:reorderOffsetArr:true',
+ 'put_var1_schar_all' => '2:3',
+ 'put_var1_schar_all-2' => 'in:IntIndexIn',
+ 'put_var1_schar_all-3' => 'in:reorderOffsetArr:true',
+ 'put_var1_short' => '2:3',
+ 'put_var1_short-2' => 'in:IntIndexIn',
+ 'put_var1_short-3' => 'in:reorderOffsetArr:true',
+ 'put_var1_short_all' => '2:3',
+ 'put_var1_short_all-2' => 'in:IntIndexIn',
+ 'put_var1_short_all-3' => 'in:reorderOffsetArr:true',
+ 'put_var1_int' => '2:3',
+ 'put_var1_int-2' => 'in:IntIndexIn',
+ 'put_var1_int-3' => 'in:reorderOffsetArr:true',
+ 'put_var1_int_all' => '2:3',
+ 'put_var1_int_all-2' => 'in:IntIndexIn',
+ 'put_var1_int_all-3' => 'in:reorderOffsetArr:true',
+ 'put_var1_float' => '2:3',
+ 'put_var1_float-2' => 'in:IntIndexIn',
+ 'put_var1_float-3' => 'in:reorderOffsetArr:true',
+ 'put_var1_float_all' => '2:3',
+ 'put_var1_float_all-2' => 'in:IntIndexIn',
+ 'put_var1_float_all-3' => 'in:reorderOffsetArr:true',
+ 'put_var1_double' => '2:3',
+ 'put_var1_double-2' => 'in:IntIndexIn',
+ 'put_var1_double-3' => 'in:reorderOffsetArr:true',
+ 'put_var1_double_all' => '2:3',
+ 'put_var1_double_all-2' => 'in:IntIndexIn',
+ 'put_var1_double_all-3' => 'in:reorderOffsetArr:true',
+ 'put_var1_longlong' => '2:3',
+ 'put_var1_longlong-2' => 'in:IntIndexIn',
+ 'put_var1_longlong-3' => 'in:reorderOffsetArr:true',
+ 'put_var1_longlong_all' => '2:3',
+ 'put_var1_longlong_all-2' => 'in:IntIndexIn',
+ 'put_var1_longlong_all-3' => 'in:reorderOffsetArr:true',
+
+ 'put_var_text' => '2:3',
+ 'put_var_text-2' => 'in:IntIndexIn',
+ 'put_var_text-3' => 'in:charBufferIn',
+ 'put_var_text_all' => '2:3',
+ 'put_var_text_all-2' => 'in:IntIndexIn',
+ 'put_var_text_all-3' => 'in:charBufferIn',
+ 'put_var_schar' => '2',
+ 'put_var_schar-2' => 'in:IntIndexIn',
+ 'put_var_schar_all' => '2',
+ 'put_var_schar_all-2' => 'in:IntIndexIn',
+ 'put_var_int' => '2',
+ 'put_var_int-2' => 'in:IntIndexIn',
+ 'put_var_int_all' => '2',
+ 'put_var_int_all-2' => 'in:IntIndexIn',
+ 'put_var_short' => '2',
+ 'put_var_short-2' => 'in:IntIndexIn',
+ 'put_var_short_all' => '2',
+ 'put_var_short_all-2' => 'in:IntIndexIn',
+ 'put_var_float' => '2',
+ 'put_var_float-2' => 'in:IntIndexIn',
+ 'put_var_float_all' => '2',
+ 'put_var_float_all-2' => 'in:IntIndexIn',
+ 'put_var_double' => '2',
+ 'put_var_double-2' => 'in:IntIndexIn',
+ 'put_var_double_all' => '2',
+ 'put_var_double_all-2' => 'in:IntIndexIn',
+ 'put_var_longlong' => '2',
+ 'put_var_longlong-2' => 'in:IntIndexIn',
+ 'put_var_longlong_all' => '2',
+ 'put_var_longlong_all-2' => 'in:IntIndexIn',
+
+ 'put_var' => '2',
+ 'put_var-2' => 'in:IntIndexIn',
+ 'put_vara' => '2:3:4',
+ 'put_vara-2' => 'in:IntIndexIn',
+ 'put_vara-3' => 'in:reorderOffsetArr:true',
+ 'put_vara-4' => 'in:reorderOffsetArr',
+ 'put_vara_all' => '2:3:4',
+ 'put_vara_all-2' => 'in:IntIndexIn',
+ 'put_vara_all-3' => 'in:reorderOffsetArr:true',
+ 'put_vara_all-4' => 'in:reorderOffsetArr',
+ 'put_vara_text' => '2:3:4:5',
+ 'put_vara_text-2' => 'in:IntIndexIn',
+ 'put_vara_text-3' => 'in:reorderOffsetArr:true',
+ 'put_vara_text-4' => 'in:reorderOffsetArr',
+ 'put_vara_text-5' => 'in:charBufferIn',
+ 'put_vara_text_all' => '2:3:4:5',
+ 'put_vara_text_all-2' => 'in:IntIndexIn',
+ 'put_vara_text_all-3' => 'in:reorderOffsetArr:true',
+ 'put_vara_text_all-4' => 'in:reorderOffsetArr',
+ 'put_vara_text_all-5' => 'in:charBufferIn',
+ 'put_vara_schar' => '2:3:4',
+ 'put_vara_schar-2' => 'in:IntIndexIn',
+ 'put_vara_schar-3' => 'in:reorderOffsetArr:true',
+ 'put_vara_schar-4' => 'in:reorderOffsetArr',
+ 'put_vara_schar_all' => '2:3:4',
+ 'put_vara_schar_all-2' => 'in:IntIndexIn',
+ 'put_vara_schar_all-3' => 'in:reorderOffsetArr:true',
+ 'put_vara_schar_all-4' => 'in:reorderOffsetArr',
+ 'put_vara_short' => '2:3:4',
+ 'put_vara_short-2' => 'in:IntIndexIn',
+ 'put_vara_short-3' => 'in:reorderOffsetArr:true',
+ 'put_vara_short-4' => 'in:reorderOffsetArr',
+ 'put_vara_short_all' => '2:3:4',
+ 'put_vara_short_all-2' => 'in:IntIndexIn',
+ 'put_vara_short_all-3' => 'in:reorderOffsetArr:true',
+ 'put_vara_short_all-4' => 'in:reorderOffsetArr',
+ 'put_vara_int' => '2:3:4',
+ 'put_vara_int-2' => 'in:IntIndexIn',
+ 'put_vara_int-3' => 'in:reorderOffsetArr:true',
+ 'put_vara_int-4' => 'in:reorderOffsetArr',
+ 'put_vara_int_all' => '2:3:4',
+ 'put_vara_int_all-2' => 'in:IntIndexIn',
+ 'put_vara_int_all-3' => 'in:reorderOffsetArr:true',
+ 'put_vara_int_all-4' => 'in:reorderOffsetArr',
+ 'put_vara_float' => '2:3:4',
+ 'put_vara_float-2' => 'in:IntIndexIn',
+ 'put_vara_float-3' => 'in:reorderOffsetArr:true',
+ 'put_vara_float-4' => 'in:reorderOffsetArr',
+ 'put_vara_float_all' => '2:3:4',
+ 'put_vara_float_all-2' => 'in:IntIndexIn',
+ 'put_vara_float_all-3' => 'in:reorderOffsetArr:true',
+ 'put_vara_float_all-4' => 'in:reorderOffsetArr',
+ 'put_vara_double' => '2:3:4',
+ 'put_vara_double-2' => 'in:IntIndexIn',
+ 'put_vara_double-3' => 'in:reorderOffsetArr:true',
+ 'put_vara_double-4' => 'in:reorderOffsetArr',
+ 'put_vara_double_all' => '2:3:4',
+ 'put_vara_double_all-2' => 'in:IntIndexIn',
+ 'put_vara_double_all-3' => 'in:reorderOffsetArr:true',
+ 'put_vara_double_all-4' => 'in:reorderOffsetArr',
+ 'put_vara_longlong' => '2:3:4',
+ 'put_vara_longlong-2' => 'in:IntIndexIn',
+ 'put_vara_longlong-3' => 'in:reorderOffsetArr:true',
+ 'put_vara_longlong-4' => 'in:reorderOffsetArr',
+ 'put_vara_longlong_all' => '2:3:4',
+ 'put_vara_longlong_all-2' => 'in:IntIndexIn',
+ 'put_vara_longlong_all-3' => 'in:reorderOffsetArr:true',
+ 'put_vara_longlong_all-4' => 'in:reorderOffsetArr',
+
+ 'put_vars' => '2:3:4:5',
+ 'put_vars-2' => 'in:IntIndexIn',
+ 'put_vars-3' => 'in:reorderOffsetArr:true',
+ 'put_vars-4' => 'in:reorderOffsetArr',
+ 'put_vars-5' => 'in:reorderOffsetArr',
+ 'put_vars_all' => '2:3:4:5',
+ 'put_vars_all-2' => 'in:IntIndexIn',
+ 'put_vars_all-3' => 'in:reorderOffsetArr:true',
+ 'put_vars_all-4' => 'in:reorderOffsetArr',
+ 'put_vars_all-5' => 'in:reorderOffsetArr',
+ 'put_vars_text' => '2:3:4:5:6',
+ 'put_vars_text-2' => 'in:IntIndexIn',
+ 'put_vars_text-3' => 'in:reorderOffsetArr:true',
+ 'put_vars_text-4' => 'in:reorderOffsetArr',
+ 'put_vars_text-5' => 'in:reorderOffsetArr',
+ 'put_vars_text-6' => 'in:charBufferIn',
+ 'put_vars_text_all' => '2:3:4:5:6',
+ 'put_vars_text_all-2' => 'in:IntIndexIn',
+ 'put_vars_text_all-3' => 'in:reorderOffsetArr:true',
+ 'put_vars_text_all-4' => 'in:reorderOffsetArr',
+ 'put_vars_text_all-5' => 'in:reorderOffsetArr',
+ 'put_vars_text_all-6' => 'in:charBufferIn',
+ 'put_vars_schar' => '2:3:4:5',
+ 'put_vars_schar-2' => 'in:IntIndexIn',
+ 'put_vars_schar-3' => 'in:reorderOffsetArr:true',
+ 'put_vars_schar-4' => 'in:reorderOffsetArr',
+ 'put_vars_schar-5' => 'in:reorderOffsetArr',
+ 'put_vars_schar_all' => '2:3:4:5',
+ 'put_vars_schar_all-2' => 'in:IntIndexIn',
+ 'put_vars_schar_all-3' => 'in:reorderOffsetArr:true',
+ 'put_vars_schar_all-4' => 'in:reorderOffsetArr',
+ 'put_vars_schar_all-5' => 'in:reorderOffsetArr',
+ 'put_vars_short' => '2:3:4:5',
+ 'put_vars_short-2' => 'in:IntIndexIn',
+ 'put_vars_short-3' => 'in:reorderOffsetArr:true',
+ 'put_vars_short-4' => 'in:reorderOffsetArr',
+ 'put_vars_short-5' => 'in:reorderOffsetArr',
+ 'put_vars_short_all' => '2:3:4:5',
+ 'put_vars_short_all-2' => 'in:IntIndexIn',
+ 'put_vars_short_all-3' => 'in:reorderOffsetArr:true',
+ 'put_vars_short_all-4' => 'in:reorderOffsetArr',
+ 'put_vars_short_all-5' => 'in:reorderOffsetArr',
+ 'put_vars_int' => '2:3:4:5',
+ 'put_vars_int-2' => 'in:IntIndexIn',
+ 'put_vars_int-3' => 'in:reorderOffsetArr:true',
+ 'put_vars_int-4' => 'in:reorderOffsetArr',
+ 'put_vars_int-5' => 'in:reorderOffsetArr',
+ 'put_vars_int_all' => '2:3:4:5',
+ 'put_vars_int_all-2' => 'in:IntIndexIn',
+ 'put_vars_int_all-3' => 'in:reorderOffsetArr:true',
+ 'put_vars_int_all-4' => 'in:reorderOffsetArr',
+ 'put_vars_int_all-5' => 'in:reorderOffsetArr',
+ 'put_vars_float' => '2:3:4:5',
+ 'put_vars_float-2' => 'in:IntIndexIn',
+ 'put_vars_float-3' => 'in:reorderOffsetArr:true',
+ 'put_vars_float-4' => 'in:reorderOffsetArr',
+ 'put_vars_float-5' => 'in:reorderOffsetArr',
+ 'put_vars_float_all' => '2:3:4:5',
+ 'put_vars_float_all-2' => 'in:IntIndexIn',
+ 'put_vars_float_all-3' => 'in:reorderOffsetArr:true',
+ 'put_vars_float_all-4' => 'in:reorderOffsetArr',
+ 'put_vars_float_all-5' => 'in:reorderOffsetArr',
+ 'put_vars_double' => '2:3:4:5',
+ 'put_vars_double-2' => 'in:IntIndexIn',
+ 'put_vars_double-3' => 'in:reorderOffsetArr:true',
+ 'put_vars_double-4' => 'in:reorderOffsetArr',
+ 'put_vars_double-5' => 'in:reorderOffsetArr',
+ 'put_vars_double_all' => '2:3:4:5',
+ 'put_vars_double_all-2' => 'in:IntIndexIn',
+ 'put_vars_double_all-3' => 'in:reorderOffsetArr:true',
+ 'put_vars_double_all-4' => 'in:reorderOffsetArr',
+ 'put_vars_double_all-5' => 'in:reorderOffsetArr',
+ 'put_vars_longlong' => '2:3:4:5',
+ 'put_vars_longlong-2' => 'in:IntIndexIn',
+ 'put_vars_longlong-3' => 'in:reorderOffsetArr:true',
+ 'put_vars_longlong-4' => 'in:reorderOffsetArr',
+ 'put_vars_longlong-5' => 'in:reorderOffsetArr',
+ 'put_vars_longlong_all' => '2:3:4:5',
+ 'put_vars_longlong_all-2' => 'in:IntIndexIn',
+ 'put_vars_longlong_all-3' => 'in:reorderOffsetArr:true',
+ 'put_vars_longlong_all-4' => 'in:reorderOffsetArr',
+ 'put_vars_longlong_all-5' => 'in:reorderOffsetArr',
+
+ 'put_varm' => '2:3:4:5:6',
+ 'put_varm-2' => 'in:IntIndexIn',
+ 'put_varm-3' => 'in:reorderOffsetArr:true',
+ 'put_varm-4' => 'in:reorderOffsetArr',
+ 'put_varm-5' => 'in:reorderOffsetArr',
+ 'put_varm-6' => 'in:reorderOffsetArr',
+ 'put_varm_all' => '2:3:4:5:6',
+ 'put_varm_all-2' => 'in:IntIndexIn',
+ 'put_varm_all-3' => 'in:reorderOffsetArr:true',
+ 'put_varm_all-4' => 'in:reorderOffsetArr',
+ 'put_varm_all-5' => 'in:reorderOffsetArr',
+ 'put_varm_all-6' => 'in:reorderOffsetArr',
+ 'put_varm_text' => '2:3:4:5:6:7',
+ 'put_varm_text-2' => 'in:IntIndexIn',
+ 'put_varm_text-3' => 'in:reorderOffsetArr:true',
+ 'put_varm_text-4' => 'in:reorderOffsetArr',
+ 'put_varm_text-5' => 'in:reorderOffsetArr',
+ 'put_varm_text-6' => 'in:reorderOffsetArr',
+ 'put_varm_text-7' => 'in:charBufferIn',
+ 'put_varm_text_all' => '2:3:4:5:6:7',
+ 'put_varm_text_all-2' => 'in:IntIndexIn',
+ 'put_varm_text_all-3' => 'in:reorderOffsetArr:true',
+ 'put_varm_text_all-4' => 'in:reorderOffsetArr',
+ 'put_varm_text_all-5' => 'in:reorderOffsetArr',
+ 'put_varm_text_all-6' => 'in:reorderOffsetArr',
+ 'put_varm_text_all-7' => 'in:charBufferIn',
+ 'put_varm_schar' => '2:3:4:5:6',
+ 'put_varm_schar-2' => 'in:IntIndexIn',
+ 'put_varm_schar-3' => 'in:reorderOffsetArr:true',
+ 'put_varm_schar-4' => 'in:reorderOffsetArr',
+ 'put_varm_schar-5' => 'in:reorderOffsetArr',
+ 'put_varm_schar-6' => 'in:reorderOffsetArr',
+ 'put_varm_schar_all' => '2:3:4:5:6',
+ 'put_varm_schar_all-2' => 'in:IntIndexIn',
+ 'put_varm_schar_all-3' => 'in:reorderOffsetArr:true',
+ 'put_varm_schar_all-4' => 'in:reorderOffsetArr',
+ 'put_varm_schar_all-5' => 'in:reorderOffsetArr',
+ 'put_varm_schar_all-6' => 'in:reorderOffsetArr',
+ 'put_varm_short' => '2:3:4:5:6',
+ 'put_varm_short-2' => 'in:IntIndexIn',
+ 'put_varm_short-3' => 'in:reorderOffsetArr:true',
+ 'put_varm_short-4' => 'in:reorderOffsetArr',
+ 'put_varm_short-5' => 'in:reorderOffsetArr',
+ 'put_varm_short-6' => 'in:reorderOffsetArr',
+ 'put_varm_short_all' => '2:3:4:5:6',
+ 'put_varm_short_all-2' => 'in:IntIndexIn',
+ 'put_varm_short_all-3' => 'in:reorderOffsetArr:true',
+ 'put_varm_short_all-4' => 'in:reorderOffsetArr',
+ 'put_varm_short_all-5' => 'in:reorderOffsetArr',
+ 'put_varm_short_all-6' => 'in:reorderOffsetArr',
+ 'put_varm_int' => '2:3:4:5:6',
+ 'put_varm_int-2' => 'in:IntIndexIn',
+ 'put_varm_int-3' => 'in:reorderOffsetArr:true',
+ 'put_varm_int-4' => 'in:reorderOffsetArr',
+ 'put_varm_int-5' => 'in:reorderOffsetArr',
+ 'put_varm_int-6' => 'in:reorderOffsetArr',
+ 'put_varm_int_all' => '2:3:4:5:6',
+ 'put_varm_int_all-2' => 'in:IntIndexIn',
+ 'put_varm_int_all-3' => 'in:reorderOffsetArr:true',
+ 'put_varm_int_all-4' => 'in:reorderOffsetArr',
+ 'put_varm_int_all-5' => 'in:reorderOffsetArr',
+ 'put_varm_int_all-6' => 'in:reorderOffsetArr',
+ 'put_varm_float' => '2:3:4:5:6',
+ 'put_varm_float-2' => 'in:IntIndexIn',
+ 'put_varm_float-3' => 'in:reorderOffsetArr:true',
+ 'put_varm_float-4' => 'in:reorderOffsetArr',
+ 'put_varm_float-5' => 'in:reorderOffsetArr',
+ 'put_varm_float-6' => 'in:reorderOffsetArr',
+ 'put_varm_float_all' => '2:3:4:5:6',
+ 'put_varm_float_all-2' => 'in:IntIndexIn',
+ 'put_varm_float_all-3' => 'in:reorderOffsetArr:true',
+ 'put_varm_float_all-4' => 'in:reorderOffsetArr',
+ 'put_varm_float_all-5' => 'in:reorderOffsetArr',
+ 'put_varm_float_all-6' => 'in:reorderOffsetArr',
+ 'put_varm_double' => '2:3:4:5:6',
+ 'put_varm_double-2' => 'in:IntIndexIn',
+ 'put_varm_double-3' => 'in:reorderOffsetArr:true',
+ 'put_varm_double-4' => 'in:reorderOffsetArr',
+ 'put_varm_double-5' => 'in:reorderOffsetArr',
+ 'put_varm_double-6' => 'in:reorderOffsetArr',
+ 'put_varm_double_all' => '2:3:4:5:6',
+ 'put_varm_double_all-2' => 'in:IntIndexIn',
+ 'put_varm_double_all-3' => 'in:reorderOffsetArr:true',
+ 'put_varm_double_all-4' => 'in:reorderOffsetArr',
+ 'put_varm_double_all-5' => 'in:reorderOffsetArr',
+ 'put_varm_double_all-6' => 'in:reorderOffsetArr',
+ 'put_varm_longlong' => '2:3:4:5:6',
+ 'put_varm_longlong-2' => 'in:IntIndexIn',
+ 'put_varm_longlong-3' => 'in:reorderOffsetArr:true',
+ 'put_varm_longlong-4' => 'in:reorderOffsetArr',
+ 'put_varm_longlong-5' => 'in:reorderOffsetArr',
+ 'put_varm_longlong-6' => 'in:reorderOffsetArr',
+ 'put_varm_longlong_all' => '2:3:4:5:6',
+ 'put_varm_longlong_all-2' => 'in:IntIndexIn',
+ 'put_varm_longlong_all-3' => 'in:reorderOffsetArr:true',
+ 'put_varm_longlong_all-4' => 'in:reorderOffsetArr',
+ 'put_varm_longlong_all-5' => 'in:reorderOffsetArr',
+ 'put_varm_longlong_all-6' => 'in:reorderOffsetArr',
+
+ 'get_varn' => '2:4:5',
+ 'get_varn-2' => 'in:IntIndexIn',
+ 'get_varn-4' => 'in:reorderOffsetArr1DTo2D:true',
+ 'get_varn-4' => 'in:reorderOffsetArr1DTo2D:true',
+ 'get_varn-5' => 'in:reorderOffsetArr1DTo2D',
+ 'get_varn_text' => '2:4:5:6',
+ 'get_varn_text-2' => 'in:IntIndexIn',
+ 'get_varn_text-4' => 'in:reorderOffsetArr1DTo2D:true',
+ 'get_varn_text-5' => 'in:reorderOffsetArr1DTo2D',
+ 'get_varn_text-6' => 'out:charBufferOut',
+ 'get_varn_schar' => '2:4:5',
+ 'get_varn_schar-2' => 'in:IntIndexIn',
+ 'get_varn_schar-4' => 'in:reorderOffsetArr1DTo2D:true',
+ 'get_varn_schar-5' => 'in:reorderOffsetArr1DTo2D',
+ 'get_varn_short' => '2:4:5',
+ 'get_varn_short-2' => 'in:IntIndexIn',
+ 'get_varn_short-4' => 'in:reorderOffsetArr1DTo2D:true',
+ 'get_varn_short-5' => 'in:reorderOffsetArr1DTo2D',
+ 'get_varn_int' => '2:4:5',
+ 'get_varn_int-2' => 'in:IntIndexIn',
+ 'get_varn_int-4' => 'in:reorderOffsetArr1DTo2D:true',
+ 'get_varn_int-5' => 'in:reorderOffsetArr1DTo2D',
+ 'get_varn_float' => '2:4:5',
+ 'get_varn_float-2' => 'in:IntIndexIn',
+ 'get_varn_float-4' => 'in:reorderOffsetArr1DTo2D:true',
+ 'get_varn_float-5' => 'in:reorderOffsetArr1DTo2D',
+ 'get_varn_double' => '2:4:5',
+ 'get_varn_double-2' => 'in:IntIndexIn',
+ 'get_varn_double-4' => 'in:reorderOffsetArr1DTo2D:true',
+ 'get_varn_double-5' => 'in:reorderOffsetArr1DTo2D',
+ 'get_varn_longlong' => '2:4:5',
+ 'get_varn_longlong-2' => 'in:IntIndexIn',
+ 'get_varn_longlong-4' => 'in:reorderOffsetArr1DTo2D:true',
+ 'get_varn_longlong-5' => 'in:reorderOffsetArr1DTo2D',
+
+ 'get_varn_all' => '2:4:5',
+ 'get_varn_all-2' => 'in:IntIndexIn',
+ 'get_varn_all-4' => 'in:reorderOffsetArr1DTo2D:true',
+ 'get_varn_all-5' => 'in:reorderOffsetArr1DTo2D',
+ 'get_varn_text_all' => '2:4:5:6',
+ 'get_varn_text_all-2' => 'in:IntIndexIn',
+ 'get_varn_text_all-4' => 'in:reorderOffsetArr1DTo2D:true',
+ 'get_varn_text_all-5' => 'in:reorderOffsetArr1DTo2D',
+ 'get_varn_text_all-6' => 'out:charBufferOut',
+ 'get_varn_schar_all' => '2:4:5',
+ 'get_varn_schar_all-2' => 'in:IntIndexIn',
+ 'get_varn_schar_all-4' => 'in:reorderOffsetArr1DTo2D:true',
+ 'get_varn_schar_all-5' => 'in:reorderOffsetArr1DTo2D',
+ 'get_varn_short_all' => '2:4:5',
+ 'get_varn_short_all-2' => 'in:IntIndexIn',
+ 'get_varn_short_all-4' => 'in:reorderOffsetArr1DTo2D:true',
+ 'get_varn_short_all-5' => 'in:reorderOffsetArr1DTo2D',
+ 'get_varn_int_all' => '2:4:5',
+ 'get_varn_int_all-2' => 'in:IntIndexIn',
+ 'get_varn_int_all-4' => 'in:reorderOffsetArr1DTo2D:true',
+ 'get_varn_int_all-5' => 'in:reorderOffsetArr1DTo2D',
+ 'get_varn_float_all' => '2:4:5',
+ 'get_varn_float_all-2' => 'in:IntIndexIn',
+ 'get_varn_float_all-4' => 'in:reorderOffsetArr1DTo2D:true',
+ 'get_varn_float_all-5' => 'in:reorderOffsetArr1DTo2D',
+ 'get_varn_double_all' => '2:4:5',
+ 'get_varn_double_all-2' => 'in:IntIndexIn',
+ 'get_varn_double_all-4' => 'in:reorderOffsetArr1DTo2D:true',
+ 'get_varn_double_all-5' => 'in:reorderOffsetArr1DTo2D',
+ 'get_varn_longlong_all' => '2:4:5',
+ 'get_varn_longlong_all-2' => 'in:IntIndexIn',
+ 'get_varn_longlong_all-4' => 'in:reorderOffsetArr1DTo2D:true',
+ 'get_varn_longlong_all-5' => 'in:reorderOffsetArr1DTo2D',
+
+ 'put_varn' => '2:4:5',
+ 'put_varn-2' => 'in:IntIndexIn',
+ 'put_varn-4' => 'in:reorderOffsetArr1DTo2D:true',
+ 'put_varn-5' => 'in:reorderOffsetArr1DTo2D',
+ 'put_varn_text' => '2:4:5:6',
+ 'put_varn_text-2' => 'in:IntIndexIn',
+ 'put_varn_text-4' => 'in:reorderOffsetArr1DTo2D:true',
+ 'put_varn_text-5' => 'in:reorderOffsetArr1DTo2D',
+ 'put_varn_text-6' => 'in:charBufferIn',
+ 'put_varn_schar' => '2:4:5',
+ 'put_varn_schar-2' => 'in:IntIndexIn',
+ 'put_varn_schar-4' => 'in:reorderOffsetArr1DTo2D:true',
+ 'put_varn_schar-5' => 'in:reorderOffsetArr1DTo2D',
+ 'put_varn_short' => '2:4:5',
+ 'put_varn_short-2' => 'in:IntIndexIn',
+ 'put_varn_short-4' => 'in:reorderOffsetArr1DTo2D:true',
+ 'put_varn_short-5' => 'in:reorderOffsetArr1DTo2D',
+ 'put_varn_int' => '2:4:5',
+ 'put_varn_int-2' => 'in:IntIndexIn',
+ 'put_varn_int-4' => 'in:reorderOffsetArr1DTo2D:true',
+ 'put_varn_int-5' => 'in:reorderOffsetArr1DTo2D',
+ 'put_varn_float' => '2:4:5',
+ 'put_varn_float-2' => 'in:IntIndexIn',
+ 'put_varn_float-4' => 'in:reorderOffsetArr1DTo2D:true',
+ 'put_varn_float-5' => 'in:reorderOffsetArr1DTo2D',
+ 'put_varn_double' => '2:4:5',
+ 'put_varn_double-2' => 'in:IntIndexIn',
+ 'put_varn_double-4' => 'in:reorderOffsetArr1DTo2D:true',
+ 'put_varn_double-5' => 'in:reorderOffsetArr1DTo2D',
+ 'put_varn_longlong' => '2:4:5',
+ 'put_varn_longlong-2' => 'in:IntIndexIn',
+ 'put_varn_longlong-4' => 'in:reorderOffsetArr1DTo2D:true',
+ 'put_varn_longlong-5' => 'in:reorderOffsetArr1DTo2D',
+
+ 'put_varn_all' => '2:4:5',
+ 'put_varn_all-2' => 'in:IntIndexIn',
+ 'put_varn_all-4' => 'in:reorderOffsetArr1DTo2D:true',
+ 'put_varn_all-5' => 'in:reorderOffsetArr1DTo2D',
+ 'put_varn_text_all' => '2:4:5:6',
+ 'put_varn_text_all-2' => 'in:IntIndexIn',
+ 'put_varn_text_all-4' => 'in:reorderOffsetArr1DTo2D:true',
+ 'put_varn_text_all-5' => 'in:reorderOffsetArr1DTo2D',
+ 'put_varn_text_all-6' => 'in:charBufferIn',
+ 'put_varn_schar_all' => '2:4:5',
+ 'put_varn_schar_all-2' => 'in:IntIndexIn',
+ 'put_varn_schar_all-4' => 'in:reorderOffsetArr1DTo2D:true',
+ 'put_varn_schar_all-5' => 'in:reorderOffsetArr1DTo2D',
+ 'put_varn_short_all' => '2:4:5',
+ 'put_varn_short_all-2' => 'in:IntIndexIn',
+ 'put_varn_short_all-4' => 'in:reorderOffsetArr1DTo2D:true',
+ 'put_varn_short_all-5' => 'in:reorderOffsetArr1DTo2D',
+ 'put_varn_int_all' => '2:4:5',
+ 'put_varn_int_all-2' => 'in:IntIndexIn',
+ 'put_varn_int_all-4' => 'in:reorderOffsetArr1DTo2D:true',
+ 'put_varn_int_all-5' => 'in:reorderOffsetArr1DTo2D',
+ 'put_varn_float_all' => '2:4:5',
+ 'put_varn_float_all-2' => 'in:IntIndexIn',
+ 'put_varn_float_all-4' => 'in:reorderOffsetArr1DTo2D:true',
+ 'put_varn_float_all-5' => 'in:reorderOffsetArr1DTo2D',
+ 'put_varn_double_all' => '2:4:5',
+ 'put_varn_double_all-2' => 'in:IntIndexIn',
+ 'put_varn_double_all-4' => 'in:reorderOffsetArr1DTo2D:true',
+ 'put_varn_double_all-5' => 'in:reorderOffsetArr1DTo2D',
+ 'put_varn_longlong_all' => '2:4:5',
+ 'put_varn_longlong_all-2' => 'in:IntIndexIn',
+ 'put_varn_longlong_all-4' => 'in:reorderOffsetArr1DTo2D:true',
+ 'put_varn_longlong_all-5' => 'in:reorderOffsetArr1DTo2D',
+
+ 'get_vard' => '2',
+ 'get_vard-2' => 'in:IntIndexIn',
+ 'put_vard' => '2',
+ 'put_vard-2' => 'in:IntIndexIn',
+ 'get_vard_all' => '2',
+ 'get_vard_all-2' => 'in:IntIndexIn',
+ 'put_vard_all' => '2',
+ 'put_vard_all-2' => 'in:IntIndexIn',
+
+ 'iget_var1' => '2:3',
+ 'iget_var1-2' => 'in:IntIndexIn',
+ 'iget_var1-3' => 'in:reorderOffsetArr:true',
+ 'iget_var1_text' => '2:3:4',
+ 'iget_var1_text-2' => 'in:IntIndexIn',
+ 'iget_var1_text-3' => 'in:reorderOffsetArr:true',
+ 'iget_var1_text-4' => 'out:charBufferOut',
+ 'iget_var1_schar' => '2:3',
+ 'iget_var1_schar-2' => 'in:IntIndexIn',
+ 'iget_var1_schar-3' => 'in:reorderOffsetArr:true',
+ 'iget_var1_short' => '2:3',
+ 'iget_var1_short-2' => 'in:IntIndexIn',
+ 'iget_var1_short-3' => 'in:reorderOffsetArr:true',
+ 'iget_var1_int' => '2:3',
+ 'iget_var1_int-2' => 'in:IntIndexIn',
+ 'iget_var1_int-3' => 'in:reorderOffsetArr:true',
+ 'iget_var1_float' => '2:3',
+ 'iget_var1_float-2' => 'in:IntIndexIn',
+ 'iget_var1_float-3' => 'in:reorderOffsetArr:true',
+ 'iget_var1_double' => '2:3',
+ 'iget_var1_double-2' => 'in:IntIndexIn',
+ 'iget_var1_double-3' => 'in:reorderOffsetArr:true',
+ 'iget_var1_longlong' => '2:3',
+ 'iget_var1_longlong-2' => 'in:IntIndexIn',
+ 'iget_var1_longlong-3' => 'in:reorderOffsetArr:true',
+
+ 'iget_var' => '2',
+ 'iget_var-2' => 'in:IntIndexIn',
+ 'iget_var_text' => '2:3',
+ 'iget_var_text-2' => 'in:IntIndexIn',
+ 'iget_var_text-3' => 'out:charBufferOut',
+ 'iget_var_schar' => '2',
+ 'iget_var_schar-2' => 'in:IntIndexIn',
+ 'iget_var_short' => '2',
+ 'iget_var_short-2' => 'in:IntIndexIn',
+ 'iget_var_float' => '2',
+ 'iget_var_float-2' => 'in:IntIndexIn',
+ 'iget_var_double' => '2',
+ 'iget_var_double-2' => 'in:IntIndexIn',
+ 'iget_var_longlong' => '2',
+ 'iget_var_longlong-2' => 'in:IntIndexIn',
+ 'iget_var_int' => '2',
+ 'iget_var_int-2' => 'in:IntIndexIn',
+
+ 'iget_vara' => '2:3:4',
+ 'iget_vara-2' => 'in:IntIndexIn',
+ 'iget_vara-3' => 'in:reorderOffsetArr:true',
+ 'iget_vara-4' => 'in:reorderOffsetArr',
+ 'iget_vara_text' => '2:3:4:5',
+ 'iget_vara_text-2' => 'in:IntIndexIn',
+ 'iget_vara_text-3' => 'in:reorderOffsetArr:true',
+ 'iget_vara_text-4' => 'in:reorderOffsetArr',
+ 'iget_vara_text-5' => 'out:charBufferOut',
+ 'iget_vara_schar' => '2:3:4',
+ 'iget_vara_schar-2' => 'in:IntIndexIn',
+ 'iget_vara_schar-3' => 'in:reorderOffsetArr:true',
+ 'iget_vara_schar-4' => 'in:reorderOffsetArr',
+ 'iget_vara_short' => '2:3:4',
+ 'iget_vara_short-2' => 'in:IntIndexIn',
+ 'iget_vara_short-3' => 'in:reorderOffsetArr:true',
+ 'iget_vara_short-4' => 'in:reorderOffsetArr',
+ 'iget_vara_int' => '2:3:4',
+ 'iget_vara_int-2' => 'in:IntIndexIn',
+ 'iget_vara_int-3' => 'in:reorderOffsetArr:true',
+ 'iget_vara_int-4' => 'in:reorderOffsetArr',
+ 'iget_vara_float' => '2:3:4',
+ 'iget_vara_float-2' => 'in:IntIndexIn',
+ 'iget_vara_float-3' => 'in:reorderOffsetArr:true',
+ 'iget_vara_float-4' => 'in:reorderOffsetArr',
+ 'iget_vara_double' => '2:3:4',
+ 'iget_vara_double-2' => 'in:IntIndexIn',
+ 'iget_vara_double-3' => 'in:reorderOffsetArr:true',
+ 'iget_vara_double-4' => 'in:reorderOffsetArr',
+ 'iget_vara_longlong' => '2:3:4',
+ 'iget_vara_longlong-2' => 'in:IntIndexIn',
+ 'iget_vara_longlong-3' => 'in:reorderOffsetArr:true',
+ 'iget_vara_longlong-4' => 'in:reorderOffsetArr',
+
+ 'iget_vars' => '2:3:4:5',
+ 'iget_vars-2' => 'in:IntIndexIn',
+ 'iget_vars-3' => 'in:reorderOffsetArr:true',
+ 'iget_vars-4' => 'in:reorderOffsetArr',
+ 'iget_vars-5' => 'in:reorderOffsetArr',
+ 'iget_vars_text' => '2:3:4:5:6',
+ 'iget_vars_text-2' => 'in:IntIndexIn',
+ 'iget_vars_text-3' => 'in:reorderOffsetArr:true',
+ 'iget_vars_text-4' => 'in:reorderOffsetArr',
+ 'iget_vars_text-5' => 'in:reorderOffsetArr',
+ 'iget_vars_text-6' => 'out:charBufferOut',
+ 'iget_vars_schar' => '2:3:4:5',
+ 'iget_vars_schar-2' => 'in:IntIndexIn',
+ 'iget_vars_schar-3' => 'in:reorderOffsetArr:true',
+ 'iget_vars_schar-4' => 'in:reorderOffsetArr',
+ 'iget_vars_schar-5' => 'in:reorderOffsetArr',
+ 'iget_vars_short' => '2:3:4:5',
+ 'iget_vars_short-2' => 'in:IntIndexIn',
+ 'iget_vars_short-3' => 'in:reorderOffsetArr:true',
+ 'iget_vars_short-4' => 'in:reorderOffsetArr',
+ 'iget_vars_short-5' => 'in:reorderOffsetArr',
+ 'iget_vars_int' => '2:3:4:5',
+ 'iget_vars_int-2' => 'in:IntIndexIn',
+ 'iget_vars_int-3' => 'in:reorderOffsetArr:true',
+ 'iget_vars_int-4' => 'in:reorderOffsetArr',
+ 'iget_vars_int-5' => 'in:reorderOffsetArr',
+ 'iget_vars_float' => '2:3:4:5',
+ 'iget_vars_float-2' => 'in:IntIndexIn',
+ 'iget_vars_float-3' => 'in:reorderOffsetArr:true',
+ 'iget_vars_float-4' => 'in:reorderOffsetArr',
+ 'iget_vars_float-5' => 'in:reorderOffsetArr',
+ 'iget_vars_double' => '2:3:4:5',
+ 'iget_vars_double-2' => 'in:IntIndexIn',
+ 'iget_vars_double-3' => 'in:reorderOffsetArr:true',
+ 'iget_vars_double-4' => 'in:reorderOffsetArr',
+ 'iget_vars_double-5' => 'in:reorderOffsetArr',
+ 'iget_vars_longlong' => '2:3:4:5',
+ 'iget_vars_longlong-2' => 'in:IntIndexIn',
+ 'iget_vars_longlong-3' => 'in:reorderOffsetArr:true',
+ 'iget_vars_longlong-4' => 'in:reorderOffsetArr',
+ 'iget_vars_longlong-5' => 'in:reorderOffsetArr',
+
+ 'iget_varm' => '2:3:4:5:6',
+ 'iget_varm-2' => 'in:IntIndexIn',
+ 'iget_varm-3' => 'in:reorderOffsetArr:true',
+ 'iget_varm-4' => 'in:reorderOffsetArr',
+ 'iget_varm-5' => 'in:reorderOffsetArr',
+ 'iget_varm-6' => 'in:reorderOffsetArr',
+ 'iget_varm_text' => '2:3:4:5:6:7',
+ 'iget_varm_text-2' => 'in:IntIndexIn',
+ 'iget_varm_text-3' => 'in:reorderOffsetArr:true',
+ 'iget_varm_text-4' => 'in:reorderOffsetArr',
+ 'iget_varm_text-5' => 'in:reorderOffsetArr',
+ 'iget_varm_text-6' => 'in:reorderOffsetArr',
+ 'iget_varm_text-7' => 'out:charBufferOut',
+ 'iget_varm_schar' => '2:3:4:5:6',
+ 'iget_varm_schar-2' => 'in:IntIndexIn',
+ 'iget_varm_schar-3' => 'in:reorderOffsetArr:true',
+ 'iget_varm_schar-4' => 'in:reorderOffsetArr',
+ 'iget_varm_schar-5' => 'in:reorderOffsetArr',
+ 'iget_varm_schar-6' => 'in:reorderOffsetArr',
+ 'iget_varm_short' => '2:3:4:5:6',
+ 'iget_varm_short-2' => 'in:IntIndexIn',
+ 'iget_varm_short-3' => 'in:reorderOffsetArr:true',
+ 'iget_varm_short-4' => 'in:reorderOffsetArr',
+ 'iget_varm_short-5' => 'in:reorderOffsetArr',
+ 'iget_varm_short-6' => 'in:reorderOffsetArr',
+ 'iget_varm_int' => '2:3:4:5:6',
+ 'iget_varm_int-2' => 'in:IntIndexIn',
+ 'iget_varm_int-3' => 'in:reorderOffsetArr:true',
+ 'iget_varm_int-4' => 'in:reorderOffsetArr',
+ 'iget_varm_int-5' => 'in:reorderOffsetArr',
+ 'iget_varm_int-6' => 'in:reorderOffsetArr',
+ 'iget_varm_float' => '2:3:4:5:6',
+ 'iget_varm_float-2' => 'in:IntIndexIn',
+ 'iget_varm_float-3' => 'in:reorderOffsetArr:true',
+ 'iget_varm_float-4' => 'in:reorderOffsetArr',
+ 'iget_varm_float-5' => 'in:reorderOffsetArr',
+ 'iget_varm_float-6' => 'in:reorderOffsetArr',
+ 'iget_varm_double' => '2:3:4:5:6',
+ 'iget_varm_double-2' => 'in:IntIndexIn',
+ 'iget_varm_double-3' => 'in:reorderOffsetArr:true',
+ 'iget_varm_double-4' => 'in:reorderOffsetArr',
+ 'iget_varm_double-5' => 'in:reorderOffsetArr',
+ 'iget_varm_double-6' => 'in:reorderOffsetArr',
+ 'iget_varm_longlong' => '2:3:4:5:6',
+ 'iget_varm_longlong-2' => 'in:IntIndexIn',
+ 'iget_varm_longlong-3' => 'in:reorderOffsetArr:true',
+ 'iget_varm_longlong-4' => 'in:reorderOffsetArr',
+ 'iget_varm_longlong-5' => 'in:reorderOffsetArr',
+ 'iget_varm_longlong-6' => 'in:reorderOffsetArr',
+
+ 'iput_var1' => '2:3',
+ 'iput_var1-2' => 'in:IntIndexIn',
+ 'iput_var1-3' => 'in:reorderOffsetArr:true',
+ 'iput_var1_text' => '2:3:4',
+ 'iput_var1_text-2' => 'in:IntIndexIn',
+ 'iput_var1_text-3' => 'in:reorderOffsetArr:true',
+ 'iput_var1_text-4' => 'in:charBufferIn',
+ 'iput_var1_schar' => '2:3',
+ 'iput_var1_schar-2' => 'in:IntIndexIn',
+ 'iput_var1_schar-3' => 'in:reorderOffsetArr:true',
+ 'iput_var1_short' => '2:3',
+ 'iput_var1_short-2' => 'in:IntIndexIn',
+ 'iput_var1_short-3' => 'in:reorderOffsetArr:true',
+ 'iput_var1_int' => '2:3',
+ 'iput_var1_int-2' => 'in:IntIndexIn',
+ 'iput_var1_int-3' => 'in:reorderOffsetArr:true',
+ 'iput_var1_float' => '2:3',
+ 'iput_var1_float-2' => 'in:IntIndexIn',
+ 'iput_var1_float-3' => 'in:reorderOffsetArr:true',
+ 'iput_var1_double' => '2:3',
+ 'iput_var1_double-2' => 'in:IntIndexIn',
+ 'iput_var1_double-3' => 'in:reorderOffsetArr:true',
+ 'iput_var1_longlong' => '2:3',
+ 'iput_var1_longlong-2' => 'in:IntIndexIn',
+ 'iput_var1_longlong-3' => 'in:reorderOffsetArr:true',
+
+ 'iput_var' => '2',
+ 'iput_var-2' => 'in:IntIndexIn',
+ 'iput_var_text' => '2:3',
+ 'iput_var_text-2' => 'in:IntIndexIn',
+ 'iput_var_text-3' => 'in:charBufferIn',
+ 'iput_var_schar' => '2',
+ 'iput_var_schar-2' => 'in:IntIndexIn',
+ 'iput_var_short' => '2',
+ 'iput_var_short-2' => 'in:IntIndexIn',
+ 'iput_var_int' => '2',
+ 'iput_var_int-2' => 'in:IntIndexIn',
+ 'iput_var_float' => '2',
+ 'iput_var_float-2' => 'in:IntIndexIn',
+ 'iput_var_double' => '2',
+ 'iput_var_double-2' => 'in:IntIndexIn',
+ 'iput_var_longlong' => '2',
+ 'iput_var_longlong-2' => 'in:IntIndexIn',
+
+ 'iput_vara' => '2:3:4',
+ 'iput_vara-2' => 'in:IntIndexIn',
+ 'iput_vara-3' => 'in:reorderOffsetArr:true',
+ 'iput_vara-4' => 'in:reorderOffsetArr',
+ 'iput_vara_text' => '2:3:4:5',
+ 'iput_vara_text-2' => 'in:IntIndexIn',
+ 'iput_vara_text-3' => 'in:reorderOffsetArr:true',
+ 'iput_vara_text-4' => 'in:reorderOffsetArr',
+ 'iput_vara_text-5' => 'in:charBufferIn',
+ 'iput_vara_schar' => '2:3:4',
+ 'iput_vara_schar-2' => 'in:IntIndexIn',
+ 'iput_vara_schar-3' => 'in:reorderOffsetArr:true',
+ 'iput_vara_schar-4' => 'in:reorderOffsetArr',
+ 'iput_vara_short' => '2:3:4',
+ 'iput_vara_short-2' => 'in:IntIndexIn',
+ 'iput_vara_short-3' => 'in:reorderOffsetArr:true',
+ 'iput_vara_short-4' => 'in:reorderOffsetArr',
+ 'iput_vara_int' => '2:3:4',
+ 'iput_vara_int-2' => 'in:IntIndexIn',
+ 'iput_vara_int-3' => 'in:reorderOffsetArr:true',
+ 'iput_vara_int-4' => 'in:reorderOffsetArr',
+ 'iput_vara_float' => '2:3:4',
+ 'iput_vara_float-2' => 'in:IntIndexIn',
+ 'iput_vara_float-3' => 'in:reorderOffsetArr:true',
+ 'iput_vara_float-4' => 'in:reorderOffsetArr',
+ 'iput_vara_double' => '2:3:4',
+ 'iput_vara_double-2' => 'in:IntIndexIn',
+ 'iput_vara_double-3' => 'in:reorderOffsetArr:true',
+ 'iput_vara_double-4' => 'in:reorderOffsetArr',
+ 'iput_vara_longlong' => '2:3:4',
+ 'iput_vara_longlong-2' => 'in:IntIndexIn',
+ 'iput_vara_longlong-3' => 'in:reorderOffsetArr:true',
+ 'iput_vara_longlong-4' => 'in:reorderOffsetArr',
+
+ 'iput_vars' => '2:3:4:5',
+ 'iput_vars-2' => 'in:IntIndexIn',
+ 'iput_vars-3' => 'in:reorderOffsetArr:true',
+ 'iput_vars-4' => 'in:reorderOffsetArr',
+ 'iput_vars-5' => 'in:reorderOffsetArr',
+ 'iput_vars_text' => '2:3:4:5:6',
+ 'iput_vars_text-2' => 'in:IntIndexIn',
+ 'iput_vars_text-3' => 'in:reorderOffsetArr:true',
+ 'iput_vars_text-4' => 'in:reorderOffsetArr',
+ 'iput_vars_text-5' => 'in:reorderOffsetArr',
+ 'iput_vars_text-6' => 'in:charBufferIn',
+ 'iput_vars_schar' => '2:3:4:5',
+ 'iput_vars_schar-2' => 'in:IntIndexIn',
+ 'iput_vars_schar-3' => 'in:reorderOffsetArr:true',
+ 'iput_vars_schar-4' => 'in:reorderOffsetArr',
+ 'iput_vars_schar-5' => 'in:reorderOffsetArr',
+ 'iput_vars_short' => '2:3:4:5',
+ 'iput_vars_short-2' => 'in:IntIndexIn',
+ 'iput_vars_short-3' => 'in:reorderOffsetArr:true',
+ 'iput_vars_short-4' => 'in:reorderOffsetArr',
+ 'iput_vars_short-5' => 'in:reorderOffsetArr',
+ 'iput_vars_int' => '2:3:4:5',
+ 'iput_vars_int-2' => 'in:IntIndexIn',
+ 'iput_vars_int-3' => 'in:reorderOffsetArr:true',
+ 'iput_vars_int-4' => 'in:reorderOffsetArr',
+ 'iput_vars_int-5' => 'in:reorderOffsetArr',
+ 'iput_vars_float' => '2:3:4:5',
+ 'iput_vars_float-2' => 'in:IntIndexIn',
+ 'iput_vars_float-3' => 'in:reorderOffsetArr:true',
+ 'iput_vars_float-4' => 'in:reorderOffsetArr',
+ 'iput_vars_float-5' => 'in:reorderOffsetArr',
+ 'iput_vars_double' => '2:3:4:5',
+ 'iput_vars_double-2' => 'in:IntIndexIn',
+ 'iput_vars_double-3' => 'in:reorderOffsetArr:true',
+ 'iput_vars_double-4' => 'in:reorderOffsetArr',
+ 'iput_vars_double-5' => 'in:reorderOffsetArr',
+ 'iput_vars_longlong' => '2:3:4:5',
+ 'iput_vars_longlong-2' => 'in:IntIndexIn',
+ 'iput_vars_longlong-3' => 'in:reorderOffsetArr:true',
+ 'iput_vars_longlong-4' => 'in:reorderOffsetArr',
+ 'iput_vars_longlong-5' => 'in:reorderOffsetArr',
+
+ 'iput_varm' => '2:3:4:5:6',
+ 'iput_varm-2' => 'in:IntIndexIn',
+ 'iput_varm-3' => 'in:reorderOffsetArr:true',
+ 'iput_varm-4' => 'in:reorderOffsetArr',
+ 'iput_varm-5' => 'in:reorderOffsetArr',
+ 'iput_varm-6' => 'in:reorderOffsetArr',
+ 'iput_varm_text' => '2:3:4:5:6:7',
+ 'iput_varm_text-2' => 'in:IntIndexIn',
+ 'iput_varm_text-3' => 'in:reorderOffsetArr:true',
+ 'iput_varm_text-4' => 'in:reorderOffsetArr',
+ 'iput_varm_text-5' => 'in:reorderOffsetArr',
+ 'iput_varm_text-6' => 'in:reorderOffsetArr',
+ 'iput_varm_text-7' => 'in:charBufferIn',
+ 'iput_varm_schar' => '2:3:4:5:6',
+ 'iput_varm_schar-2' => 'in:IntIndexIn',
+ 'iput_varm_schar-3' => 'in:reorderOffsetArr:true',
+ 'iput_varm_schar-4' => 'in:reorderOffsetArr',
+ 'iput_varm_schar-5' => 'in:reorderOffsetArr',
+ 'iput_varm_schar-6' => 'in:reorderOffsetArr',
+ 'iput_varm_short' => '2:3:4:5:6',
+ 'iput_varm_short-2' => 'in:IntIndexIn',
+ 'iput_varm_short-3' => 'in:reorderOffsetArr:true',
+ 'iput_varm_short-4' => 'in:reorderOffsetArr',
+ 'iput_varm_short-5' => 'in:reorderOffsetArr',
+ 'iput_varm_short-6' => 'in:reorderOffsetArr',
+ 'iput_varm_int' => '2:3:4:5:6',
+ 'iput_varm_int-2' => 'in:IntIndexIn',
+ 'iput_varm_int-3' => 'in:reorderOffsetArr:true',
+ 'iput_varm_int-4' => 'in:reorderOffsetArr',
+ 'iput_varm_int-5' => 'in:reorderOffsetArr',
+ 'iput_varm_int-6' => 'in:reorderOffsetArr',
+ 'iput_varm_float' => '2:3:4:5:6',
+ 'iput_varm_float-2' => 'in:IntIndexIn',
+ 'iput_varm_float-3' => 'in:reorderOffsetArr:true',
+ 'iput_varm_float-4' => 'in:reorderOffsetArr',
+ 'iput_varm_float-5' => 'in:reorderOffsetArr',
+ 'iput_varm_float-6' => 'in:reorderOffsetArr',
+ 'iput_varm_double' => '2:3:4:5:6',
+ 'iput_varm_double-2' => 'in:IntIndexIn',
+ 'iput_varm_double-3' => 'in:reorderOffsetArr:true',
+ 'iput_varm_double-4' => 'in:reorderOffsetArr',
+ 'iput_varm_double-5' => 'in:reorderOffsetArr',
+ 'iput_varm_double-6' => 'in:reorderOffsetArr',
+ 'iput_varm_longlong' => '2:3:4:5:6',
+ 'iput_varm_longlong-2' => 'in:IntIndexIn',
+ 'iput_varm_longlong-3' => 'in:reorderOffsetArr:true',
+ 'iput_varm_longlong-4' => 'in:reorderOffsetArr',
+ 'iput_varm_longlong-5' => 'in:reorderOffsetArr',
+ 'iput_varm_longlong-6' => 'in:reorderOffsetArr',
+
+ 'iget_varn' => '2:4:5',
+ 'iget_varn-2' => 'in:IntIndexIn',
+ 'iget_varn-4' => 'in:reorderOffsetArr1DTo2D:true',
+ 'iget_varn-5' => 'in:reorderOffsetArr1DTo2D',
+ 'iget_varn_text' => '2:4:5:6',
+ 'iget_varn_text-2' => 'in:IntIndexIn',
+ 'iget_varn_text-4' => 'in:reorderOffsetArr1DTo2D:true',
+ 'iget_varn_text-5' => 'in:reorderOffsetArr1DTo2D',
+ 'iget_varn_text-6' => 'out:charBufferOut',
+ 'iget_varn_schar' => '2:4:5',
+ 'iget_varn_schar-2' => 'in:IntIndexIn',
+ 'iget_varn_schar-4' => 'in:reorderOffsetArr1DTo2D:true',
+ 'iget_varn_schar-5' => 'in:reorderOffsetArr1DTo2D',
+ 'iget_varn_short' => '2:4:5',
+ 'iget_varn_short-2' => 'in:IntIndexIn',
+ 'iget_varn_short-4' => 'in:reorderOffsetArr1DTo2D:true',
+ 'iget_varn_short-5' => 'in:reorderOffsetArr1DTo2D',
+ 'iget_varn_int' => '2:4:5',
+ 'iget_varn_int-2' => 'in:IntIndexIn',
+ 'iget_varn_int-4' => 'in:reorderOffsetArr1DTo2D:true',
+ 'iget_varn_int-5' => 'in:reorderOffsetArr1DTo2D',
+ 'iget_varn_float' => '2:4:5',
+ 'iget_varn_float-2' => 'in:IntIndexIn',
+ 'iget_varn_float-4' => 'in:reorderOffsetArr1DTo2D:true',
+ 'iget_varn_float-5' => 'in:reorderOffsetArr1DTo2D',
+ 'iget_varn_double' => '2:4:5',
+ 'iget_varn_double-2' => 'in:IntIndexIn',
+ 'iget_varn_double-4' => 'in:reorderOffsetArr1DTo2D:true',
+ 'iget_varn_double-5' => 'in:reorderOffsetArr1DTo2D',
+ 'iget_varn_longlong' => '2:4:5',
+ 'iget_varn_longlong-2' => 'in:IntIndexIn',
+ 'iget_varn_longlong-4' => 'in:reorderOffsetArr1DTo2D:true',
+ 'iget_varn_longlong-5' => 'in:reorderOffsetArr1DTo2D',
+
+ 'iput_varn' => '2:4:5',
+ 'iput_varn-2' => 'in:IntIndexIn',
+ 'iput_varn-4' => 'in:reorderOffsetArr1DTo2D:true',
+ 'iput_varn-5' => 'in:reorderOffsetArr1DTo2D',
+ 'iput_varn_text' => '2:4:5:6',
+ 'iput_varn_text-2' => 'in:IntIndexIn',
+ 'iput_varn_text-4' => 'in:reorderOffsetArr1DTo2D:true',
+ 'iput_varn_text-5' => 'in:reorderOffsetArr1DTo2D',
+ 'iput_varn_text-6' => 'in:charBufferIn',
+ 'iput_varn_schar' => '2:4:5',
+ 'iput_varn_schar-2' => 'in:IntIndexIn',
+ 'iput_varn_schar-4' => 'in:reorderOffsetArr1DTo2D:true',
+ 'iput_varn_schar-5' => 'in:reorderOffsetArr1DTo2D',
+ 'iput_varn_short' => '2:4:5',
+ 'iput_varn_short-2' => 'in:IntIndexIn',
+ 'iput_varn_short-4' => 'in:reorderOffsetArr1DTo2D:true',
+ 'iput_varn_short-5' => 'in:reorderOffsetArr1DTo2D',
+ 'iput_varn_int' => '2:4:5',
+ 'iput_varn_int-2' => 'in:IntIndexIn',
+ 'iput_varn_int-4' => 'in:reorderOffsetArr1DTo2D:true',
+ 'iput_varn_int-5' => 'in:reorderOffsetArr1DTo2D',
+ 'iput_varn_float' => '2:4:5',
+ 'iput_varn_float-2' => 'in:IntIndexIn',
+ 'iput_varn_float-4' => 'in:reorderOffsetArr1DTo2D:true',
+ 'iput_varn_float-5' => 'in:reorderOffsetArr1DTo2D',
+ 'iput_varn_double' => '2:4:5',
+ 'iput_varn_double-2' => 'in:IntIndexIn',
+ 'iput_varn_double-4' => 'in:reorderOffsetArr1DTo2D:true',
+ 'iput_varn_double-5' => 'in:reorderOffsetArr1DTo2D',
+ 'iput_varn_longlong' => '2:4:5',
+ 'iput_varn_longlong-2' => 'in:IntIndexIn',
+ 'iput_varn_longlong-4' => 'in:reorderOffsetArr1DTo2D:true',
+ 'iput_varn_longlong-5' => 'in:reorderOffsetArr1DTo2D',
+
+ 'bput_varn' => '2:4:5',
+ 'bput_varn-2' => 'in:IntIndexIn',
+ 'bput_varn-4' => 'in:reorderOffsetArr1DTo2D:true',
+ 'bput_varn-5' => 'in:reorderOffsetArr1DTo2D',
+ 'bput_varn_text' => '2:4:5:6',
+ 'bput_varn_text-2' => 'in:IntIndexIn',
+ 'bput_varn_text-4' => 'in:reorderOffsetArr1DTo2D:true',
+ 'bput_varn_text-5' => 'in:reorderOffsetArr1DTo2D',
+ 'bput_varn_text-6' => 'in:charBufferIn',
+ 'bput_varn_schar' => '2:4:5',
+ 'bput_varn_schar-2' => 'in:IntIndexIn',
+ 'bput_varn_schar-4' => 'in:reorderOffsetArr1DTo2D:true',
+ 'bput_varn_schar-5' => 'in:reorderOffsetArr1DTo2D',
+ 'bput_varn_short' => '2:4:5',
+ 'bput_varn_short-2' => 'in:IntIndexIn',
+ 'bput_varn_short-4' => 'in:reorderOffsetArr1DTo2D:true',
+ 'bput_varn_short-5' => 'in:reorderOffsetArr1DTo2D',
+ 'bput_varn_int' => '2:4:5',
+ 'bput_varn_int-2' => 'in:IntIndexIn',
+ 'bput_varn_int-4' => 'in:reorderOffsetArr1DTo2D:true',
+ 'bput_varn_int-5' => 'in:reorderOffsetArr1DTo2D',
+ 'bput_varn_float' => '2:4:5',
+ 'bput_varn_float-2' => 'in:IntIndexIn',
+ 'bput_varn_float-4' => 'in:reorderOffsetArr1DTo2D:true',
+ 'bput_varn_float-5' => 'in:reorderOffsetArr1DTo2D',
+ 'bput_varn_double' => '2:4:5',
+ 'bput_varn_double-2' => 'in:IntIndexIn',
+ 'bput_varn_double-4' => 'in:reorderOffsetArr1DTo2D:true',
+ 'bput_varn_double-5' => 'in:reorderOffsetArr1DTo2D',
+ 'bput_varn_longlong' => '2:4:5',
+ 'bput_varn_longlong-2' => 'in:IntIndexIn',
+ 'bput_varn_longlong-4' => 'in:reorderOffsetArr1DTo2D:true',
+ 'bput_varn_longlong-5' => 'in:reorderOffsetArr1DTo2D',
+
+ 'bput_var1' => '2:3',
+ 'bput_var1-2' => 'in:IntIndexIn',
+ 'bput_var1-3' => 'in:reorderOffsetArr:true',
+ 'bput_var1_text' => '2:3:4',
+ 'bput_var1_text-2' => 'in:IntIndexIn',
+ 'bput_var1_text-3' => 'in:reorderOffsetArr:true',
+ 'bput_var1_text-4' => 'in:charBufferIn',
+ 'bput_var1_schar' => '2:3',
+ 'bput_var1_schar-2' => 'in:IntIndexIn',
+ 'bput_var1_schar-3' => 'in:reorderOffsetArr:true',
+ 'bput_var1_short' => '2:3',
+ 'bput_var1_short-2' => 'in:IntIndexIn',
+ 'bput_var1_short-3' => 'in:reorderOffsetArr:true',
+ 'bput_var1_int' => '2:3',
+ 'bput_var1_int-2' => 'in:IntIndexIn',
+ 'bput_var1_int-3' => 'in:reorderOffsetArr:true',
+ 'bput_var1_float' => '2:3',
+ 'bput_var1_float-2' => 'in:IntIndexIn',
+ 'bput_var1_float-3' => 'in:reorderOffsetArr:true',
+ 'bput_var1_double' => '2:3',
+ 'bput_var1_double-2' => 'in:IntIndexIn',
+ 'bput_var1_double-3' => 'in:reorderOffsetArr:true',
+ 'bput_var1_longlong' => '2:3',
+ 'bput_var1_longlong-2' => 'in:IntIndexIn',
+ 'bput_var1_longlong-3' => 'in:reorderOffsetArr:true',
+
+ 'bput_var' => '2',
+ 'bput_var-2' => 'in:IntIndexIn',
+ 'bput_var_text' => '2:3',
+ 'bput_var_text-2' => 'in:IntIndexIn',
+ 'bput_var_text-3' => 'in:charBufferIn',
+ 'bput_var_schar' => '2',
+ 'bput_var_schar-2' => 'in:IntIndexIn',
+ 'bput_var_short' => '2',
+ 'bput_var_short-2' => 'in:IntIndexIn',
+ 'bput_var_int' => '2',
+ 'bput_var_int-2' => 'in:IntIndexIn',
+ 'bput_var_float' => '2',
+ 'bput_var_float-2' => 'in:IntIndexIn',
+ 'bput_var_double' => '2',
+ 'bput_var_double-2' => 'in:IntIndexIn',
+ 'bput_var_longlong' => '2',
+ 'bput_var_longlong-2' => 'in:IntIndexIn',
+
+ 'bput_vara' => '2:3:4',
+ 'bput_vara-2' => 'in:IntIndexIn',
+ 'bput_vara-3' => 'in:reorderOffsetArr:true',
+ 'bput_vara-4' => 'in:reorderOffsetArr',
+ 'bput_vara_text' => '2:3:4:5',
+ 'bput_vara_text-2' => 'in:IntIndexIn',
+ 'bput_vara_text-3' => 'in:reorderOffsetArr:true',
+ 'bput_vara_text-4' => 'in:reorderOffsetArr',
+ 'bput_vara_text-5' => 'in:charBufferIn',
+ 'bput_vara_schar' => '2:3:4',
+ 'bput_vara_schar-2' => 'in:IntIndexIn',
+ 'bput_vara_schar-3' => 'in:reorderOffsetArr:true',
+ 'bput_vara_schar-4' => 'in:reorderOffsetArr',
+ 'bput_vara_short' => '2:3:4',
+ 'bput_vara_short-2' => 'in:IntIndexIn',
+ 'bput_vara_short-3' => 'in:reorderOffsetArr:true',
+ 'bput_vara_short-4' => 'in:reorderOffsetArr',
+ 'bput_vara_int' => '2:3:4',
+ 'bput_vara_int-2' => 'in:IntIndexIn',
+ 'bput_vara_int-3' => 'in:reorderOffsetArr:true',
+ 'bput_vara_int-4' => 'in:reorderOffsetArr',
+ 'bput_vara_float' => '2:3:4',
+ 'bput_vara_float-2' => 'in:IntIndexIn',
+ 'bput_vara_float-3' => 'in:reorderOffsetArr:true',
+ 'bput_vara_float-4' => 'in:reorderOffsetArr',
+ 'bput_vara_double' => '2:3:4',
+ 'bput_vara_double-2' => 'in:IntIndexIn',
+ 'bput_vara_double-3' => 'in:reorderOffsetArr:true',
+ 'bput_vara_double-4' => 'in:reorderOffsetArr',
+ 'bput_vara_longlong' => '2:3:4',
+ 'bput_vara_longlong-2' => 'in:IntIndexIn',
+ 'bput_vara_longlong-3' => 'in:reorderOffsetArr:true',
+ 'bput_vara_longlong-4' => 'in:reorderOffsetArr',
+
+ 'bput_vars' => '2:3:4:5',
+ 'bput_vars-2' => 'in:IntIndexIn',
+ 'bput_vars-3' => 'in:reorderOffsetArr:true',
+ 'bput_vars-4' => 'in:reorderOffsetArr',
+ 'bput_vars-5' => 'in:reorderOffsetArr',
+ 'bput_vars_text' => '2:3:4:5:6',
+ 'bput_vars_text-2' => 'in:IntIndexIn',
+ 'bput_vars_text-3' => 'in:reorderOffsetArr:true',
+ 'bput_vars_text-4' => 'in:reorderOffsetArr',
+ 'bput_vars_text-5' => 'in:reorderOffsetArr',
+ 'bput_vars_text-6' => 'in:charBufferIn',
+ 'bput_vars_schar' => '2:3:4:5',
+ 'bput_vars_schar-2' => 'in:IntIndexIn',
+ 'bput_vars_schar-3' => 'in:reorderOffsetArr:true',
+ 'bput_vars_schar-4' => 'in:reorderOffsetArr',
+ 'bput_vars_schar-5' => 'in:reorderOffsetArr',
+ 'bput_vars_short' => '2:3:4:5',
+ 'bput_vars_short-2' => 'in:IntIndexIn',
+ 'bput_vars_short-3' => 'in:reorderOffsetArr:true',
+ 'bput_vars_short-4' => 'in:reorderOffsetArr',
+ 'bput_vars_short-5' => 'in:reorderOffsetArr',
+ 'bput_vars_int' => '2:3:4:5',
+ 'bput_vars_int-2' => 'in:IntIndexIn',
+ 'bput_vars_int-3' => 'in:reorderOffsetArr:true',
+ 'bput_vars_int-4' => 'in:reorderOffsetArr',
+ 'bput_vars_int-5' => 'in:reorderOffsetArr',
+ 'bput_vars_float' => '2:3:4:5',
+ 'bput_vars_float-2' => 'in:IntIndexIn',
+ 'bput_vars_float-3' => 'in:reorderOffsetArr:true',
+ 'bput_vars_float-4' => 'in:reorderOffsetArr',
+ 'bput_vars_float-5' => 'in:reorderOffsetArr',
+ 'bput_vars_double' => '2:3:4:5',
+ 'bput_vars_double-2' => 'in:IntIndexIn',
+ 'bput_vars_double-3' => 'in:reorderOffsetArr:true',
+ 'bput_vars_double-4' => 'in:reorderOffsetArr',
+ 'bput_vars_double-5' => 'in:reorderOffsetArr',
+ 'bput_vars_longlong' => '2:3:4:5',
+ 'bput_vars_longlong-2' => 'in:IntIndexIn',
+ 'bput_vars_longlong-3' => 'in:reorderOffsetArr:true',
+ 'bput_vars_longlong-4' => 'in:reorderOffsetArr',
+ 'bput_vars_longlong-5' => 'in:reorderOffsetArr',
+
+ 'bput_varm' => '2:3:4:5:6',
+ 'bput_varm-2' => 'in:IntIndexIn',
+ 'bput_varm-3' => 'in:reorderOffsetArr:true',
+ 'bput_varm-4' => 'in:reorderOffsetArr',
+ 'bput_varm-5' => 'in:reorderOffsetArr',
+ 'bput_varm-6' => 'in:reorderOffsetArr',
+ 'bput_varm_text' => '2:3:4:5:6:7',
+ 'bput_varm_text-2' => 'in:IntIndexIn',
+ 'bput_varm_text-3' => 'in:reorderOffsetArr:true',
+ 'bput_varm_text-4' => 'in:reorderOffsetArr',
+ 'bput_varm_text-5' => 'in:reorderOffsetArr',
+ 'bput_varm_text-6' => 'in:reorderOffsetArr',
+ 'bput_varm_text-7' => 'in:charBufferIn',
+ 'bput_varm_schar' => '2:3:4:5:6',
+ 'bput_varm_schar-2' => 'in:IntIndexIn',
+ 'bput_varm_schar-3' => 'in:reorderOffsetArr:true',
+ 'bput_varm_schar-4' => 'in:reorderOffsetArr',
+ 'bput_varm_schar-5' => 'in:reorderOffsetArr',
+ 'bput_varm_schar-6' => 'in:reorderOffsetArr',
+ 'bput_varm_short' => '2:3:4:5:6',
+ 'bput_varm_short-2' => 'in:IntIndexIn',
+ 'bput_varm_short-3' => 'in:reorderOffsetArr:true',
+ 'bput_varm_short-4' => 'in:reorderOffsetArr',
+ 'bput_varm_short-5' => 'in:reorderOffsetArr',
+ 'bput_varm_short-6' => 'in:reorderOffsetArr',
+ 'bput_varm_int' => '2:3:4:5:6',
+ 'bput_varm_int-2' => 'in:IntIndexIn',
+ 'bput_varm_int-3' => 'in:reorderOffsetArr:true',
+ 'bput_varm_int-4' => 'in:reorderOffsetArr',
+ 'bput_varm_int-5' => 'in:reorderOffsetArr',
+ 'bput_varm_int-6' => 'in:reorderOffsetArr',
+ 'bput_varm_float' => '2:3:4:5:6',
+ 'bput_varm_float-2' => 'in:IntIndexIn',
+ 'bput_varm_float-3' => 'in:reorderOffsetArr:true',
+ 'bput_varm_float-4' => 'in:reorderOffsetArr',
+ 'bput_varm_float-5' => 'in:reorderOffsetArr',
+ 'bput_varm_float-6' => 'in:reorderOffsetArr',
+ 'bput_varm_double' => '2:3:4:5:6',
+ 'bput_varm_double-2' => 'in:IntIndexIn',
+ 'bput_varm_double-3' => 'in:reorderOffsetArr:true',
+ 'bput_varm_double-4' => 'in:reorderOffsetArr',
+ 'bput_varm_double-5' => 'in:reorderOffsetArr',
+ 'bput_varm_double-6' => 'in:reorderOffsetArr',
+ 'bput_varm_longlong' => '2:3:4:5:6',
+ 'bput_varm_longlong-2' => 'in:IntIndexIn',
+ 'bput_varm_longlong-3' => 'in:reorderOffsetArr:true',
+ 'bput_varm_longlong-4' => 'in:reorderOffsetArr',
+ 'bput_varm_longlong-5' => 'in:reorderOffsetArr',
+ 'bput_varm_longlong-6' => 'in:reorderOffsetArr',
+
+
+ 'rename_att' => '2:3:4',
+ 'rename_att-2' => 'in:IntIndexIn',
+ 'rename_att-3' => 'in:addnull',
+ 'rename_att-4' => 'in:addnull',
+ 'rename_dim' => '2:3',
+ 'rename_dim-2' => 'in:IntIndexIn',
+ 'rename_dim-3' => 'in:addnull',
+ 'rename_var' => '2:3',
+ 'rename_var-2' => 'in:IntIndexIn',
+ 'rename_var-3' => 'in:addnull'
+);
+
+$build_prototypes = 1;
+$buildMakefile = 0;
+$prototype_header_file = "mpifnetcdf.h";
+$argsneedcast{'const MPI_Offset []'} = '(const MPI_Offset *)(ARG)';
+$argsneedcast{'nc_type *'} = '(nc_type *)(ARG)';
+$argsneedcast{'nc_type'} = '(nc_type)(ARG)';
+
+# Special handling for integer*1 routines
+$declarg{'get_att_int1-4'} = 'signed char *';
+$declarg{'put_att_int1-6'} = 'const signed char *';
+$declarg{'get_var1_int1-4'} = 'signed char *';
+$declarg{'put_var1_int1-4'} = 'const signed char *';
+$declarg{'get_var1_int1_all-4'} = 'signed char *';
+$declarg{'put_var1_int1_all-4'} = 'const signed char *';
+$declarg{'get_var_int1-3'} = 'signed char *';
+$declarg{'put_var_int1-3'} = 'const signed char *';
+$declarg{'get_var_int1_all-3'} = 'signed char *';
+$declarg{'put_var_int1_all-3'} = 'const signed char *';
+$declarg{'get_vara_int1-5'} = 'signed char *';
+$declarg{'put_vara_int1-5'} = 'const signed char *';
+$declarg{'get_vara_int1_all-5'} = 'signed char *';
+$declarg{'put_vara_int1_all-5'} = 'const signed char *';
+$declarg{'get_vars_int1-6'} = 'signed char *';
+$declarg{'put_vars_int1-6'} = 'const signed char *';
+$declarg{'get_vars_int1_all-6'} = 'signed char *';
+$declarg{'put_vars_int1_all-6'} = 'const signed char *';
+$declarg{'get_varm_int1-7'} = 'signed char *';
+$declarg{'put_varm_int1-7'} = 'const signed char *';
+$declarg{'get_varm_int1_all-7'} = 'signed char *';
+$declarg{'put_varm_int1_all-7'} = 'const signed char *';
+
+$declarg{'get_varn_int1-6'} = 'signed char *';
+$declarg{'put_varn_int1-6'} = 'const signed char *';
+$declarg{'get_varn_int1_all-6'} = 'signed char *';
+$declarg{'put_varn_int1_all-6'} = 'const signed char *';
+
+$declarg{'iget_varn_int1-6'} = 'signed char *';
+$declarg{'iput_varn_int1-6'} = 'const signed char *';
+$declarg{'iget_varn_int1_all-6'} = 'signed char *';
+$declarg{'iput_varn_int1_all-6'} = 'const signed char *';
+
+$declarg{'bput_varn_int1-6'} = 'const signed char *';
+$declarg{'bput_varn_int1_all-6'} = 'const signed char *';
+
+$declarg{'iget_var1_int1-4'} = 'signed char *';
+$declarg{'iput_var1_int1-4'} = 'const signed char *';
+$declarg{'iget_var1_int1-4'} = 'signed char *';
+$declarg{'iput_var1_int1-4'} = 'const signed char *';
+$declarg{'iget_var_int1-3'} = 'signed char *';
+$declarg{'iput_var_int1-3'} = 'const signed char *';
+$declarg{'iget_vara_int1-5'} = 'signed char *';
+$declarg{'iput_vara_int1-5'} = 'const signed char *';
+$declarg{'iget_vars_int1-6'} = 'signed char *';
+$declarg{'iput_vars_int1-6'} = 'const signed char *';
+$declarg{'iget_varm_int1-7'} = 'signed char *';
+$declarg{'iput_varm_int1-7'} = 'const signed char *';
+
+$declarg{'bput_var1_int1-4'} = 'const signed char *';
+$declarg{'bput_var_int1-3'} = 'const signed char *';
+$declarg{'bput_vara_int1-5'} = 'const signed char *';
+$declarg{'bput_vars_int1-6'} = 'const signed char *';
+$declarg{'bput_varm_int1-7'} = 'const signed char *';
+
+# Special handling for int8 routines
+$declarg{'put_att_int8-6'} = 'const long long *';
+$declarg{'get_att_int8-4'} = 'long long *';
+
+$declarg{'get_var1_int8-4'} = 'long long *';
+$declarg{'put_var1_int8-4'} = 'const long long *';
+$declarg{'get_var1_int8_all-4'} = 'long long *';
+$declarg{'put_var1_int8_all-4'} = 'const long long *';
+$declarg{'get_var_int8-3'} = 'long long *';
+$declarg{'put_var_int8-3'} = 'const long long *';
+$declarg{'get_var_int8_all-3'} = 'long long *';
+$declarg{'put_var_int8_all-3'} = 'const long long *';
+$declarg{'get_vara_int8-5'} = 'long long *';
+$declarg{'put_vara_int8-5'} = 'const long long *';
+$declarg{'get_vara_int8_all-5'} = 'long long *';
+$declarg{'put_vara_int8_all-5'} = 'const long long *';
+$declarg{'get_vars_int8-6'} = 'long long *';
+$declarg{'put_vars_int8-6'} = 'const long long *';
+$declarg{'get_vars_int8_all-6'} = 'long long *';
+$declarg{'put_vars_int8_all-6'} = 'const long long *';
+$declarg{'get_varm_int8-7'} = 'long long *';
+$declarg{'put_varm_int8-7'} = 'const long long *';
+$declarg{'get_varm_int8_all-7'} = 'long long *';
+$declarg{'put_varm_int8_all-7'} = 'const long long *';
+
+$declarg{'get_varn_int8-6'} = 'long long *';
+$declarg{'put_varn_int8-6'} = 'const long long *';
+$declarg{'get_varn_int8_all-6'} = 'long long *';
+$declarg{'put_varn_int8_all-6'} = 'const long long *';
+
+$declarg{'iget_varn_int8-6'} = 'long long *';
+$declarg{'iput_varn_int8-6'} = 'const long long *';
+$declarg{'iget_varn_int8_all-6'} = 'long long *';
+$declarg{'iput_varn_int8_all-6'} = 'const long long *';
+
+$declarg{'bput_varn_int8-6'} = 'const long long *';
+$declarg{'bput_varn_int8_all-6'} = 'const long long *';
+
+$declarg{'iget_var1_int8-4'} = 'long long *';
+$declarg{'iput_var1_int8-4'} = 'const long long *';
+$declarg{'iget_var_int8-3'} = 'long long *';
+$declarg{'iput_var_int8-3'} = 'const long long *';
+$declarg{'iget_vara_int8-5'} = 'long long *';
+$declarg{'iput_vara_int8-5'} = 'const long long *';
+$declarg{'iget_vars_int8-6'} = 'long long *';
+$declarg{'iput_vars_int8-6'} = 'const long long *';
+$declarg{'iget_varm_int8-7'} = 'long long *';
+$declarg{'iput_varm_int8-7'} = 'const long long *';
+
+$declarg{'bput_var1_int8-4'} = 'const long long *';
+$declarg{'bput_var_int8-3'} = 'const long long *';
+$declarg{'bput_vara_int8-5'} = 'const long long *';
+$declarg{'bput_vars_int8-6'} = 'const long long *';
+$declarg{'bput_varm_int8-7'} = 'const long long *';
+
+# Special argument handling
+# Special routines are used whose names are created from the name
+# used in the hashes above (routinename-position) and these special routine
+# names.
+# void foo( MPI_Fint *v1, etc )
+# {
+# /* Special declarations needed for the variables */
+# <name>_<direction>_decl( <argnum> )
+# /* Special processing need for in variables */
+# <name>_ftoc( <argnum> )
+# /* Call the function. Replace special arguments with the output from */
+# <name>_<direction>_arg( <argnum> )
+# /* Special post call processing (for out variables) */
+# <name>_ctof( l$count, v$count ) /* local (C) variable name, fortran var name */
+# Not all routines must be provided
+# use $declarg{routine-position} to replace the handling of input
+# arguments (in the definition)
+# E.g., $declarg{'put_att_schar-6'} = 'const signed char *';
+#
+# Routines needed for special argument handling for MPI_Offset
+
+# ---------------------------------------------------------------------------
+# F2C dimension reorder from a Fortran 1D array of type MPI_Offset to a C
+# 1D array of type MPI_Offset.
+# usage is
+# 'Type_struct' => '3', 'Type_struct-3' => 'in:reorderOffsetArr:true',
+# or
+# 'Type_struct' => '3', 'Type_struct-3' => 'in:reorderOffsetArr',
+# where true indicates the array values of the array will be converted
+# from 1-based to 0-based. Without it, no conversion is done.
+#
+sub reorderOffsetArr_in_decl {
+ my $count = $_[0];
+ print $OUTFD " MPI_Offset *l$count = NULL;\n";
+}
+sub reorderOffsetArr_ftoc {
+ my $count = $_[0];
+ # We use a local variable for the array size because we may need to
+ # call a function of some of the other arguments to get the array size
+ if ($Array_size) {
+ print $OUTFD "
+ int ndims;
+ ierr = ncmpi_inq_varndims(*v1, l2, &ndims); /* get number of dimensions */
+ if (ierr != NC_NOERR) return ierr;
+
+ if (ndims > 0) {
+ int li;
+ l$count = (MPI_Offset*) $malloc((size_t)ndims * sizeof(MPI_Offset));
+ for (li=0; li<ndims; li++) /* convert Fortran order to C order */
+ l$count\[li\] = v$count\[ndims-1-li\] - 1; /* convert 1-based to 0-based */
+ }\n";
+ } else {
+ print $OUTFD "
+ if (ndims > 0) {
+ int li;
+ l$count = (MPI_Offset*) $malloc((size_t)ndims * sizeof(MPI_Offset));
+ for (li=0; li<ndims; li++) /* convert Fortran order to C order */
+ l$count\[li\] = v$count\[ndims-1-li\];
+ }\n";
+ }
+}
+sub reorderOffsetArr_in_arg {
+ my $count = $_[0];
+ print $OUTFD "l$count";
+}
+# This routine is invoked even for the in case (to free the result)
+sub reorderOffsetArr_in_ctof {
+ my $lname = $_[0];
+ my $vname = $_[1];
+ print $OUTFD "
+ if ($lname) { $free($lname); }
+";
+}
+
+# ---------------------------------------------------------------------------
+# F2C dimension reorder from a Fortran MPI_Offset 1D array to a C MPI_Offset
+# 2D array.
+# 'Type_struct' => '3', 'Type_struct-3' => 'in:reorderOffsetArr1DTo2D:true',
+# or
+# 'Type_struct' => '3', 'Type_struct-3' => 'in:reorderOffsetArr1DTo2D',
+# where true indicates the array values of the array will be converted
+# from 1-based to 0-based. Without it, no conversion is done.
+#
+sub reorderOffsetArr1DTo2D_in_decl {
+ my $count = $_[0];
+ print $OUTFD " MPI_Offset **l$count = NULL;\n";
+}
+sub reorderOffsetArr1DTo2D_ftoc {
+ my $count = $_[0];
+ if ($Array_size) {
+ print $OUTFD "
+ int ndims;
+ ierr = ncmpi_inq_varndims(*v1, l2, &ndims); /* get number of dimensions */
+ if (ierr != NC_NOERR) return ierr;\n"
+ }
+ print $OUTFD "
+ if (ndims > 0) {
+ int li, lj;
+ size_t len = (size_t)*v3;
+ l$count = (MPI_Offset**) $malloc(len * sizeof(MPI_Offset*));
+ l$count\[0\] = (MPI_Offset*) $malloc(len * (size_t)ndims * sizeof(MPI_Offset));
+ for (lj=1; lj<*v3; lj++)
+ l$count\[lj\] = l$count\[lj-1\] + ndims;
+ for (lj=0; lj<*v3; lj++)
+ for (li=0; li<ndims; li++) /* convert Fortran order to C order */";
+ if ($Array_size) {
+ print $OUTFD "
+ l$count\[lj\]\[li\] = v$count\[lj*ndims + ndims-1-li\] - 1; /* convert 1-based to 0-based */
+ }\n";
+ } else {
+ print $OUTFD "
+ l$count\[lj\]\[li\] = v$count\[lj*ndims + ndims-1-li\];
+ }\n";
+ }
+}
+sub reorderOffsetArr1DTo2D_in_arg {
+ my $count = $_[0];
+ print $OUTFD "l$count";
+}
+# This routine is invoked even for the in case (to free the result)
+sub reorderOffsetArr1DTo2D_in_ctof {
+ my $lname = $_[0];
+ my $vname = $_[1];
+ print $OUTFD "
+ if ($lname) { $free($lname\[0\]); $free($lname); }
+";
+}
+
+# -------------------------------------------------------------------------
+# F2C dimension reorder from a Fortran int array to a C int array.
+# usage is
+# 'Type_struct' => '3', 'Type_struct-3' => 'in:reorderIntArr:true',
+# or
+# 'Type_struct' => '3', 'Type_struct-3' => 'in:reorderIntArr",
+# where true indicates the array values of the array will be converted
+# from 1-based to 0-based. Without it, no conversion is done.
+#
+sub reorderIntArr_in_decl {
+ my $count = $_[0];
+ print $OUTFD " int *l$count=NULL;\n";
+}
+sub reorderIntArr_ftoc {
+ my $count = $_[0];
+ # We use a local variable for the array size because we may need to
+ # call a function of some of the other arguments to get the array size
+ # Always copy and invert order
+ if ($Array_size) {
+ print $OUTFD "
+ int ndims;
+ ierr = ncmpi_inq_varndims(*v1, l2, &ndims); /* get number of dimensions */
+ if (ierr != NC_NOERR) return ierr;\n"
+ }
+ print $OUTFD "
+ if (ndims > 0) {
+ int li;
+ l$count = (int*) $malloc((size_t)ndims * sizeof(int));
+ for (li=0; li<ndims; li++) /* convert Fortran order to C order */
+ l$count\[li\] = v$count\[ndims-1-li\];
+ }\n";
+ $clean_up .= " $free(l$count);\n";
+}
+sub reorderIntArr_in_arg {
+ my $count = $_[0];
+ print $OUTFD "l$count";
+}
+# This routine is invoked even for the in case (to free the result)
+sub reorderIntArr_in_ctof {
+ my $lname = $_[0];
+ my $vname = $_[1];
+ print $OUTFD "
+ if ($lname) { $free($lname); }
+";
+}
+
+# -------------------------------------------------------------------------
+# Convert from a C int array to a Fortran int array with the values reordered
+# for an OUTPUT array
+# usage is
+# 'Type_struct' => '3', 'Type_struct-3' => 'out:reorderIntArrOut',
+# the array values will be converted from C 0-based to Fortran 1-based.
+#
+sub reorderIntArrOut_out_decl {
+ my $count = $_[0];
+ print $OUTFD " int *l$count=NULL;\n";
+}
+sub reorderIntArrOut_out_ftoc {
+ my $count = $_[0];
+ # We use a local variable for the array size because we may need to
+ # call a function of some of the other arguments to get the array size
+ # Always copy and invert order
+ print $OUTFD "
+ int ndims;
+ ierr = ncmpi_inq_varndims(*v1, l2, &ndims); /* get number of dimensions */
+ if (ierr != NC_NOERR) return ierr;
+
+ if (ndims > 0) {
+ l$count = (int*) $malloc((size_t)ndims * sizeof(int));
+ }\n";
+}
+sub reorderIntArrOut_out_arg {
+ my $count = $_[0];
+ print $OUTFD "l$count";
+}
+# This routine is invoked even for the in case (to free the result)
+sub reorderIntArrOut_ctof {
+ my $lname = $_[0];
+ my $vname = $_[1];
+ print $OUTFD "
+ if (ndims > 0) {
+ int li;
+ for (li=0; li<ndims; li++) /* convert C order to Fortran order */
+ v$count\[li\] = l$count\[ndims-1-li\] + 1; /* convert from 0-based to 1-based */
+ $free($lname);
+ }\n";
+}
+
+# -------------------------------------------------------------------------
+sub intToOffset_in_decl {
+ my $count = $_[0];
+ print $OUTFD " MPI_Offset l$count = (MPI_Offset)*v$count;\n";
+}
+sub intToOffset_ftoc {
+ my $count = $_[0];
+}
+sub intToOffset_in_arg {
+ my $count = $_[0];
+ print $OUTFD "l$count";
+}
+# This routine is invoked even for the in case (to free the result)
+sub intToOffset_in_ctof {
+ my $lname = $_[0];
+ my $vname = $_[1];
+}
+
+# -------------------------------------------------------------------------
+# For output of int indices, add one to the result
+# usage is
+# 'inq_varid' => '3', 'inq_varid-3' => 'out:IntIndex',
+#
+sub IntIndex_out_decl {
+ my $count = $_[0];
+}
+sub IntIndex_out_ftoc {
+ my $count = $_[0];
+}
+sub IntIndex_out_arg {
+ my $count = $_[0];
+ print $OUTFD "v$count";
+}
+sub IntIndex_ctof {
+ my $lname = $_[0];
+ my $vname = $_[1];
+ print $OUTFD "
+ if (!$errparmrval) *v$count = *v$count + 1;\n";
+}
+
+# -------------------------------------------------------------------------
+# For output of MPI_Offset indices, add one to the result
+# usage is
+# 'inq_varid' => '3', 'inq_varid-3' => 'out:OffsetIndex',
+#
+sub OffsetIndex_out_decl {
+ my $count = $_[0];
+}
+sub OffsetIndex_out_ftoc {
+ my $count = $_[0];
+}
+sub OffsetIndex_out_arg {
+ my $count = $_[0];
+ print $OUTFD "v$count";
+}
+sub OffsetIndex_ctof {
+ my $lname = $_[0];
+ my $vname = $_[1];
+ print $OUTFD "
+ if (!$errparmrval) *v$count = *v$count + 1;\n";
+}
+
+# -------------------------------------------------------------------------
+# For output of dimension indices, add one to the result
+# If no unlimited length dimension has been defined, -1 is returned.
+# usage is
+# 'inq_varid' => '3', 'inq_varid-3' => 'out:IntDimIndex',
+#
+sub IntDimIndex_out_decl {
+ my $count = $_[0];
+}
+sub IntDimIndex_out_ftoc {
+ my $count = $_[0];
+}
+sub IntDimIndex_out_arg {
+ my $count = $_[0];
+ print $OUTFD "v$count";
+}
+sub IntDimIndex_ctof {
+ my $lname = $_[0];
+ my $vname = $_[1];
+ print $OUTFD "
+ if (!$errparmrval && *v$count != -1) *v$count = *v$count + 1;\n";
+}
+
+# -------------------------------------------------------------------------
+# For input of int indices, subtract one to the result
+# usage is
+# 'inq_dim' => '3', 'inq_dim-3' => 'in:IntIndexIn',
+#
+sub IntIndexIn_in_decl {
+ my $count = $_[0];
+ print $OUTFD " int l$count = *v$count - 1;\n";
+}
+sub IntIndexIn_ftoc {
+ my $count = $_[0];
+}
+sub IntIndexIn_in_arg {
+ my $count = $_[0];
+ print $OUTFD "l$count";
+}
+sub IntIndexIn_ctof {
+ my $lname = $_[0];
+ my $vname = $_[1];
+}
+
+# -------------------------------------------------------------------------
+# For input of MPI_Offset indices, subtract one to the result
+# usage is
+# 'inq_dim' => '3', 'inq_dim-3' => 'in:OffsetIndexIn',
+#
+sub OffsetIndexIn_in_decl {
+ my $count = $_[0];
+ print $OUTFD " MPI_Offset l$count = *v$count - 1;\n";
+}
+sub OffsetIndexIn_ftoc {
+ my $count = $_[0];
+}
+sub OffsetIndexIn_in_arg {
+ my $count = $_[0];
+ print $OUTFD "l$count";
+}
+sub OffsetIndexIn_ctof {
+ my $lname = $_[0];
+ my $vname = $_[1];
+}
+
+# -------------------------------------------------------------------------
+# For input of an array of int indices, subtract one from the result.
+# Also, reverse the order of the array indices
+# usage is
+# 'def_var' => '3', 'def_var-3' => 'in:IntIndexInArr',
+# Note:
+# This did not match the one use of this routine, in defA-var
+#
+sub IntIndexInArr_in_decl {
+ my $count = $_[0];
+ print $OUTFD " int *l$count=NULL;\n int ln$count;\n";
+}
+sub IntIndexInArr_ftoc {
+ my $count = $_[0];
+ print $OUTFD "
+ { ln$count = $Array_size;
+ if (ln$count > 0) {
+ int li;
+ l$count = (int*) $malloc( (size_t)ln$count * sizeof(int));
+ for (li=0; li<ln$count; li++) /* convert Fortran order to C order */
+ l$count\[li\] = v$count\[ln$count-li-1\]-1; /* convert 1-based to 0-based */
+ }}\n";
+ $clean_up .= " $free(l$count);\n";
+}
+sub IntIndexInArr_in_arg {
+ my $count = $_[0];
+ print $OUTFD "l$count";
+}
+sub IntIndexInArr_ctof {
+ my $lname = $_[0];
+ my $vname = $_[1];
+ print $OUTFD "
+ if ($lname) { $free($lname); }
+";
+}
+
+# ---------------------------------------------------------------------------
+# charBufferIn and charBufferOut are basically no-ops. They are provided
+# in case special processing is required for the character buffers.
+#
+sub charBufferIn_in_decl {
+}
+sub charBufferIn_in_arg {
+ my $count = $_[0];
+ print $OUTFD "v$count";
+}
+sub charBufferIn_ftoc {
+}
+# Output text buffers
+sub charBufferOut_out_decl {
+}
+sub charBufferOut_out_arg {
+ my $count = $_[0];
+ print $OUTFD "v$count";
+}
+sub charBufferOut_ctof {
+}
+
+# -----------------------------------------------------------------------------
+# integer*1 in Fortran to signed char in C
+# FIXME: Not done yet
+#
+sub int1toschar_out_arg {
+ my $count = $_[0];
+ print $OUTFD "v$count";
+}
+sub int1toschar_in_decl {
+ my $count = $_[0];
+}
+sub int1toschar_out_decl {
+ my $count = $_[0];
+}
+sub int1toschar_ftoc {
+ my $count = $_[0];
+}
+sub int1toschar_in_arg {
+ my $count = $_[0];
+ print $OUTFD "v$count";
+}
+sub int1toschar_ctof {
+ my $lname = $_[0];
+ my $vname = $_[1];
+}
+
+# will this overrride buildiface?
+sub blankpad_out_ftoc {
+ my $count = $_[0];
+
+ # Allocate space to hold the C version of the output
+ $strlen = "d$count";
+ print $OUTFD " p$count = (char*) $calloc((size_t)$strlen + 1, 1);\n";
+}
+
+# ---------------------------------------------------------------------------
+# Functions to add routines that need special handling
+$ExtraRoutines[$#ExtraRoutines+1] = "ncfxstrerror";
+$ExtraRoutines[$#ExtraRoutines+1] = "ncfxutil";
+$ExtraRoutines[$#ExtraRoutines+1] = "ncfxinqlibvers";
+$ExtraRoutines[$#ExtraRoutines+1] = "ncfissyserr";
+$ExtraRoutines[$#ExtraRoutines+1] = "get_file_info";
+$ExtraRoutines[$#ExtraRoutines+1] = "inq_file_info";
+
+sub ncfxstrerror {
+ $OUTFD = "NCFXSTRERRORFD";
+ open( $OUTFD, ">xstrerrorf.c" ) || die "Cannot open xstrerrorf.c\n";
+ $out_prefix = "nfmpi_";
+ $files[$#files+1] = "xstrerrorf.c";
+ $args = "int *, char *";
+ &print_header( "ncfmpi_xstrerror", "xstrerror", $args );
+ &print_routine_type_decl( $OUTFD, "xstrerror" );
+ &print_args( $OUTFD, $args, 0, "xstrerror" );
+ print $OUTFD "{
+ const char *p = ncmpi_strerror( *v1 );
+ int i;
+ /* d2 is the length of the string passed into the routine */
+ for (i=0; i<d2 && *p; i++) {
+ v2[i] = *p++;
+ }
+ /* Blank pad */
+ for (; i<d2; i++) v2[i] = ' ';
+ return 0;
+}\n";
+ close ($OUTFD);
+}
+
+# Note that this works for errors because the Netcdf errors are negative
+sub ncfxutil {
+ $OUTFD = "NCFXUTIL";
+ open( $OUTFD, ">nfxutil.c" ) || die "Cannot open nfxutil.c\n";
+ $files[$#files+1] = "nfxutil.c";
+ &print_copyright( );
+ print $OUTFD "
+int ncmpixVardim( int ncid, int varid )
+{
+ int ndims, status;
+ status = ncmpi_inq_varndims(ncid, varid, &ndims); /* get number of dimensions */
+ if (status != NC_NOERR) return status;
+ return ndims;
+}\n";
+ close ($OUTFD);
+}
+
+sub ncfxinqlibvers {
+ $OUTFD = "NCFXINQLIBVERSFD";
+ open( $OUTFD, ">xinq_libversf.c" ) || die "Cannot open xinq_libversf.c\n";
+ $out_prefix = "nfmpi_";
+ $args = "char *";
+ $files[$#files+1] = "xinq_libversf.c";
+ &print_header( "ncfmpi_xinq_libvers", "xinq_libvers", $args );
+ &print_routine_type_decl( $OUTFD, "xinq_libvers" );
+ &print_args( $OUTFD, $args, 0, "xinq_libvers" );
+ print $OUTFD "{
+ const char *p = ncmpi_inq_libvers();
+ int i;
+ /* d1 is the length of the string passed into the routine */
+ for (i=0; i<d1 && *p; i++) {
+ v1[i] = *p++;
+ }
+ /* Blank pad */
+ for (; i<d1; i++) v1[i] = ' ';
+ return 0;
+}\n";
+ close ($OUTFD);
+}
+
+sub ncfissyserr {
+ $OUTFD = "NCFISSYSERRFD";
+ open( $OUTFD, ">issyserrf.c" ) || die "Cannot open issyserrf.c\n";
+ $out_prefix = "nfmpi_";
+ $args = "int *";
+ $files[$#files+1] = "issyserrf.c";
+ &print_header( "ncfmpi_issyserr", "issyserr", $args );
+ &print_routine_type_decl( $OUTFD, "issyserr" );
+ &print_args( $OUTFD, $args, 0, "issyserr" );
+ print $OUTFD "{
+ if (*v1 > 0)
+ return 1;
+ else
+ return 0;
+}\n";
+ close ($OUTFD);
+
+}
+
+sub inq_file_info {
+ $OUTFD = "GETFILEINFOFD";
+ open( $OUTFD, ">inq_file_infof.c" ) || die "Cannot open inq_file_infof.c\n";
+ $out_prefix = "nfmpi_";
+ $files[$#files+1] = "inq_file_infof.c";
+ $args = "int *, int *";
+ &print_header( "ncfmpi_inq_file_info", "inq_file_info", $args );
+ &print_routine_type_decl( $OUTFD, "inq_file_info" );
+ &print_args( $OUTFD, $args, 0, "inq_file_info" );
+ print $OUTFD "{
+ int ierr;
+ MPI_Info info;
+
+ ierr = ncmpi_inq_file_info( *v1, &info );
+ *v2 = MPI_Info_c2f(info);
+ return ierr;
+}\n";
+ close ($OUTFD);
+}
+
+sub get_file_info {
+ $OUTFD = "GETFILEINFOFD";
+ open( $OUTFD, ">get_file_infof.c" ) || die "Cannot open get_file_infof.c\n";
+ $out_prefix = "nfmpi_";
+ $files[$#files+1] = "get_file_infof.c";
+ $args = "int *, int *";
+ &print_header( "ncfmpi_get_file_info", "get_file_info", $args );
+ &print_routine_type_decl( $OUTFD, "get_file_info" );
+ &print_args( $OUTFD, $args, 0, "get_file_info" );
+ print $OUTFD "{
+ int ierr;
+ MPI_Info info;
+
+ ierr = ncmpi_get_file_info( *v1, &info );
+ *v2 = MPI_Info_c2f(info);
+ return ierr;
+}\n";
+ close ($OUTFD);
+}
+
+
+return 1;
+
+# Local variables:
+# mode: perl
+# End:
+#
+# vim:ft=perl
diff --git a/src/libf/inq_libversf.f b/src/libf/inq_libversf.f
new file mode 100644
index 0000000..ce91f54
--- /dev/null
+++ b/src/libf/inq_libversf.f
@@ -0,0 +1,10 @@
+ character *80 function nfmpi_inq_libvers()
+ integer ierr
+ character *(80) tmpstr
+
+ integer nfmpi_xinq_libvers
+ external nfmpi_xinq_libvers
+
+ ierr = nfmpi_xinq_libvers(tmpstr)
+ nfmpi_inq_libvers = tmpstr
+ end
diff --git a/src/libf/mpinetcdf_impl.h b/src/libf/mpinetcdf_impl.h
new file mode 100644
index 0000000..d9ffa98
--- /dev/null
+++ b/src/libf/mpinetcdf_impl.h
@@ -0,0 +1,77 @@
+/* -*- Mode: C; c-basic-offset:4 ; -*- */
+/*
+ * Copyright (C) 2003, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT in top-level directory.
+ */
+/* $Id: mpinetcdf_impl.h 2104 2015-09-18 23:36:19Z wkliao $ */
+
+#ifndef MPINETCDF_IMPL_H
+#define MPINETCDF_IMPL_H
+
+#if HAVE_CONFIG_H
+# include <ncconfig.h>
+#endif
+
+#include <stdlib.h>
+#include <pnetcdf.h>
+
+/* Support Windows extension to specify calling convention */
+#ifdef USE_FORT_STDCALL
+#define FORT_CALL __stdcall
+#elif defined (USE_FORT_CDECL)
+#define FORT_CALL __cdecl
+#else
+#define FORT_CALL
+#endif
+
+/* Handle different mechanisms for passing Fortran CHARACTER to routines */
+#ifdef USE_FORT_MIXED_STR_LEN
+#define FORT_MIXED_LEN_DECL , MPI_Fint
+#define FORT_END_LEN_DECL
+#define FORT_MIXED_LEN(a) , MPI_Fint a
+#define FORT_END_LEN(a)
+#else
+#define FORT_MIXED_LEN_DECL
+#define FORT_END_LEN_DECL , MPI_Fint
+#define FORT_MIXED_LEN(a)
+#define FORT_END_LEN(a) , MPI_Fint a
+#endif
+
+/* Support Windows extension to specify which functions are exported from
+ shared (DLL) libraries */
+#ifdef HAVE_FORTRAN_API
+# ifdef FORTRAN_EXPORTS
+# define FORTRAN_API __declspec(dllexport)
+# else
+# define FORTRAN_API __declspec(dllimport)
+# endif
+#else
+# define FORTRAN_API
+#endif
+
+/* Support an alternate approach for declaring a weak symbol supported by
+ some versions of gcc */
+#ifdef USE_WEAK_ATTRIBUTE
+#define FUNC_ATTRIBUTES(name) __attribute__ ((weak,alias(#name)))
+#else
+#define FUNC_ATTRIBUTES(name)
+#endif
+
+/* Utility functions */
+int ncmpixVardim( int, int );
+
+extern FORTRAN_API int FORT_CALL nfmpi_xstrerror_ ( MPI_Fint *v1, char *v2 FORT_MIXED_LEN(d2) FORT_END_LEN(d2) );
+extern FORTRAN_API int FORT_CALL nfmpi_xinq_libvers_ ( char *v1 FORT_MIXED_LEN(d1) FORT_END_LEN(d1) );
+extern FORTRAN_API int FORT_CALL nfmpi_issyserr_ ( MPI_Fint *v1 );
+/* Define the internal values needed for Fortran support */
+
+/* Fortran logicals */
+
+/* Fortran logical values */
+
+
+#endif
+
+
+
+
diff --git a/src/libf/nfconfig_inc.in b/src/libf/nfconfig_inc.in
new file mode 100644
index 0000000..6a2bb2e
--- /dev/null
+++ b/src/libf/nfconfig_inc.in
@@ -0,0 +1,91 @@
+#if 0
+ Copyright (C) 2003, Northwestern University and Argonne National Laboratory
+ See COPYRIGHT notice in top-level directory.
+
+ $Id: nfconfig_inc.in 1468 2013-10-26 16:53:18Z wkliao $
+#endif
+
+
+#ifndef UD_NETCDF_CPP_INC
+#define UD_NETCDF_CPP_INC
+
+
+#if 0
+ Do not have C-style comments in here because this file is processed
+ by both the FORTRAN compiler (for the nf_test/ stuff) and the C
+ compiler (for the FORTRAN-callable interface routines) and some
+ FORTRAN preprocessors do not understand the /*...*/ syntax.
+#endif
+
+
+#if 0
+ The following macros define the supplementary FORTRAN arithmetic
+ datatypes beyond the standard INTEGER, REAL, and DOUBLEPRECISION --
+ ostensibly corresponding to 8-bit and 16-bit integers, respectively.
+ For example:
+
+ #define NF_INT1_T integer*1
+ #define NF_INT2_T integer*2
+ #define NF_INT8_T integer*8
+
+ These are the types of the relevant arguments in the NF_*_INT1() and
+ NF_*_INT2() netCDF FORTRAN function calls. The word "ostensibly"
+ is used advisedly: on some systems an "integer*2" datatype,
+ nevertheless, occupies 64 bits (we are not making this up).
+
+ If your FORTRAN system does not have the respective supplementary
+ datatype, then do not define the corresponding macro.
+#endif
+#undef NF_INT1_T
+#undef NF_INT2_T
+#undef NF_INT8_T
+
+
+#if 0
+ Define the following NF_*_IS_C_* macros appropriatly for your system.
+ The "INT1", "INT2", "INT", and "INT8" after the "NF_" refer to the
+ NF_INT1_T FORTRAN datatype, the NF_INT2_T FORTRAN datatype, the INTEGER
+ FORTRAN datatype, and the NF_INT8_T FORTRAN datatype, respectively.
+ If the respective FORTRAN datatype
+ does not exist, then do not define the corresponding macro.
+#endif
+#undef NF_INT1_IS_C_SIGNED_CHAR
+#undef NF_INT1_IS_C_SHORT
+#undef NF_INT1_IS_C_INT
+#undef NF_INT1_IS_C_LONG
+#undef NF_INT2_IS_C_SHORT
+#undef NF_INT2_IS_C_INT
+#undef NF_INT2_IS_C_LONG
+#undef NF_INT_IS_C_INT
+#undef NF_INT_IS_C_LONG
+#undef NF_INT8_IS_C_LONG
+#undef NF_INT8_IS_C_LONG_LONG
+#undef NF_REAL_IS_C_FLOAT
+#undef NF_REAL_IS_C_DOUBLE
+#undef NF_DOUBLEPRECISION_IS_C_DOUBLE
+#undef NF_DOUBLEPRECISION_IS_C_FLOAT
+
+
+#if 0
+ Whether the system uses something besides the IEEE floating-point
+ format to represent floating-point values.
+#endif
+#undef NO_IEEE_FLOAT
+
+
+#if 0
+ END OF CUSTOMIZATION
+#endif
+
+
+#if 0
+ FORTRAN data types corresponding to netCDF version 2 "byte" and "short"
+ data types (e.g. INTEGER*1, INTEGER*2). See file "ftest.F" for usage.
+#endif
+#if !defined(NO_NETCDF_2)
+# undef NCBYTE_T
+# undef NCSHORT_T
+#endif
+
+
+#endif
diff --git a/src/libf/pnetcdf.inc.in b/src/libf/pnetcdf.inc.in
new file mode 100644
index 0000000..09820d0
--- /dev/null
+++ b/src/libf/pnetcdf.inc.in
@@ -0,0 +1,1512 @@
+!
+! pnetcdf fortran defines
+!
+
+!
+! PnetCDF library version numbers
+!
+ integer PNETCDF_VERSION_MAJOR
+ integer PNETCDF_VERSION_MINOR
+ integer PNETCDF_VERSION_SUB
+
+ parameter (PNETCDF_VERSION_MAJOR = @PNETCDF_VERSION_MAJOR@)
+ parameter (PNETCDF_VERSION_MINOR = @PNETCDF_VERSION_MINOR@)
+ parameter (PNETCDF_VERSION_SUB = @PNETCDF_VERSION_SUB@)
+
+!
+! external netcdf data types: (must conform with netCDF release)
+!
+ integer nf_byte
+ integer nf_int1
+ integer nf_char
+ integer nf_short
+ integer nf_int2
+ integer nf_int
+ integer nf_float
+ integer nf_real
+ integer nf_double
+ integer nf_ubyte
+ integer nf_ushort
+ integer nf_uint
+ integer nf_int64
+ integer nf_uint64
+
+ parameter (nf_byte = 1)
+ parameter (nf_int1 = nf_byte)
+ parameter (nf_char = 2)
+ parameter (nf_short = 3)
+ parameter (nf_int2 = nf_short)
+ parameter (nf_int = 4)
+ parameter (nf_float = 5)
+ parameter (nf_real = nf_float)
+ parameter (nf_double = 6)
+ parameter (nf_ubyte = 7)
+ parameter (nf_ushort = 8)
+ parameter (nf_uint = 9)
+ parameter (nf_int64 = 10)
+ parameter (nf_uint64 = 11)
+
+!
+! default fill values:
+!
+ integer nf_fill_byte
+ integer nf_fill_int1
+ integer nf_fill_char
+ integer nf_fill_short
+ integer nf_fill_int2
+ integer nf_fill_int
+ real nf_fill_float
+ real nf_fill_real
+ doubleprecision nf_fill_double
+ integer nf_fill_ubyte
+ integer nf_fill_ushort
+ integer*8 nf_fill_uint
+ integer*8 nf_fill_int64
+ ! integer*8 nf_fill_uint64 ! no unsigned int*8 in Fortran
+ doubleprecision nf_fill_uint64
+
+ parameter (nf_fill_byte = -127)
+ parameter (nf_fill_int1 = nf_fill_byte)
+ parameter (nf_fill_char = 0)
+ parameter (nf_fill_short = -32767)
+ parameter (nf_fill_int2 = nf_fill_short)
+ parameter (nf_fill_int = -2147483647)
+ parameter (nf_fill_float = 9.9692099683868690e+36)
+ parameter (nf_fill_real = nf_fill_float)
+ parameter (nf_fill_double = 9.9692099683868690e+36)
+ parameter (nf_fill_ubyte = 255)
+ parameter (nf_fill_ushort = 65535)
+
+ at PNF_INT8_MODIFIER@
+ parameter (nf_fill_uint = @PNF_FILL_UINT@)
+ parameter (nf_fill_int64 = @PNF_FILL_INT64@)
+ ! parameter (nf_fill_uint64 = @PNF_FILL_UINT64@) ! currently not supported
+ parameter (nf_fill_uint64 = 1.8446744073709551614e+19)
+
+!
+! mode flags for opening and creating a netcdf dataset:
+!
+ integer nf_nowrite
+ integer nf_write
+ integer nf_clobber
+ integer nf_noclobber
+ integer nf_fill
+ integer nf_nofill
+ integer nf_lock
+ integer nf_share
+ integer nf_64bit_offset
+ integer nf_32bit
+ integer nf_64bit_data
+ integer nf_sizehint_default
+ integer nf_align_chunk
+ integer nf_format_classic
+ integer nf_format_64bit
+ integer nf_format_64bit_data
+ integer nf_format_64bit_offset
+ integer nf_format_cdf2
+ integer nf_format_cdf5
+
+ parameter (nf_nowrite = 0)
+ parameter (nf_write = 1)
+ parameter (nf_clobber = 0)
+ parameter (nf_noclobber = 4)
+ parameter (nf_fill = 0)
+ parameter (nf_nofill = 256)
+ parameter (nf_lock = 1024)
+ parameter (nf_share = 2048)
+ parameter (nf_64bit_offset = 512)
+ parameter (nf_64bit_data = 32)
+ parameter (nf_32bit = 16777216)
+ parameter (nf_sizehint_default = 0)
+ parameter (nf_align_chunk = -1)
+ parameter (nf_format_classic = 1)
+ parameter (nf_format_cdf2 = 2)
+ parameter (nf_format_cdf5 = 5)
+ parameter (nf_format_64bit = nf_format_cdf2)
+ parameter (nf_format_64bit_offset = nf_format_cdf2)
+ parameter (nf_format_64bit_data = nf_format_cdf5)
+
+!
+! size argument for defining an unlimited dimension:
+!
+ integer nf_unlimited
+ parameter (nf_unlimited = 0)
+
+ integer*@SIZEOF_MPI_OFFSET@ nfmpi_unlimited
+ parameter (nfmpi_unlimited = 0)
+
+!
+! global attribute id:
+!
+ integer nf_global
+ parameter (nf_global = 0)
+
+!
+! implementation limits:
+!
+ integer nf_max_dims
+ integer nf_max_attrs
+ integer nf_max_vars
+ integer nf_max_name
+ integer nf_max_var_dims
+
+ parameter (nf_max_dims = 512)
+ parameter (nf_max_attrs = 4092)
+ parameter (nf_max_vars = 4096)
+ parameter (nf_max_name = 128)
+ parameter (nf_max_var_dims = nf_max_dims)
+
+!
+! error codes: (conform with netCDF release)
+!
+ integer NF_NOERR
+ integer NF2_ERR
+ integer NF_EBADID
+ integer NF_ENFILE
+ integer NF_EEXIST
+ integer NF_EINVAL
+ integer NF_EPERM
+ integer NF_ENOTINDEFINE
+ integer NF_EINDEFINE
+ integer NF_EINVALCOORDS
+ integer NF_EMAXDIMS
+ integer NF_ENAMEINUSE
+ integer NF_ENOTATT
+ integer NF_EMAXATTS
+ integer NF_EBADTYPE
+ integer NF_EBADDIM
+ integer NF_EUNLIMPOS
+ integer NF_EMAXVARS
+ integer NF_ENOTVAR
+ integer NF_EGLOBAL
+ integer NF_ENOTNC
+ integer NF_ESTS
+ integer NF_EMAXNAME
+ integer NF_EUNLIMIT
+ integer NF_ENORECVARS
+ integer NF_ECHAR
+ integer NF_EEDGE
+ integer NF_ESTRIDE
+ integer NF_EBADNAME
+ integer NF_ERANGE
+ integer NF_ENOMEM
+ integer NF_EVARSIZE
+ integer NF_EDIMSIZE
+ integer NF_ETRUNC
+ integer NF_EAXISTYPE
+ integer NF_EDAP
+ integer NF_ECURL
+ integer NF_EIO
+ integer NF_ENODATA
+ integer NF_EDAPSVC
+ integer NF_EDAS
+ integer NF_EDDS
+ integer NF_EDATADDS
+ integer NF_EDAPURL
+ integer NF_EDAPCONSTRAINT
+ integer NF_ETRANSLATION
+ integer NF_EACCESS
+ integer NF_EAUTH
+ integer NF_ENOTFOUND
+ integer NF_ECANTREMOVE
+
+ PARAMETER (NF_NOERR = 0) ! No Error
+ PARAMETER (NF2_ERR = -1) ! Returned for all errors in the v2 API
+ PARAMETER (NF_EBADID = -33) ! Not a netcdf id
+ PARAMETER (NF_ENFILE = -34) ! Too many netcdfs open
+ PARAMETER (NF_EEXIST = -35) ! netcdf file exists and NF_NOCLOBBER
+ PARAMETER (NF_EINVAL = -36) ! Invalid Argument
+ PARAMETER (NF_EPERM = -37) ! Write to read only
+ PARAMETER (NF_ENOTINDEFINE = -38) ! Operation not allowed in data mode
+ PARAMETER (NF_EINDEFINE = -39) ! Operation not allowed in define mode
+ PARAMETER (NF_EINVALCOORDS = -40) ! Index exceeds dimension bound
+ PARAMETER (NF_EMAXDIMS = -41) ! NF_MAX_DIMS exceeded
+ PARAMETER (NF_ENAMEINUSE = -42) ! String match to name in use
+ PARAMETER (NF_ENOTATT = -43) ! Attribute not found
+ PARAMETER (NF_EMAXATTS = -44) ! NF_MAX_ATTRS exceeded
+ PARAMETER (NF_EBADTYPE = -45) ! Not a netcdf data type
+ PARAMETER (NF_EBADDIM = -46) ! Invalid dimension id or name
+ PARAMETER (NF_EUNLIMPOS = -47) ! NFMPI_UNLIMITED in the wrong index
+ PARAMETER (NF_EMAXVARS = -48) ! NF_MAX_VARS exceeded
+ PARAMETER (NF_ENOTVAR = -49) ! Variable not found
+ PARAMETER (NF_EGLOBAL = -50) ! Action prohibited on NF_GLOBAL varid
+ PARAMETER (NF_ENOTNC = -51) ! Not a netcdf file
+ PARAMETER (NF_ESTS = -52) ! In Fortran, string too short
+ PARAMETER (NF_EMAXNAME = -53) ! NF_MAX_NAME exceeded
+ PARAMETER (NF_EUNLIMIT = -54) ! NFMPI_UNLIMITED size already in use
+ PARAMETER (NF_ENORECVARS = -55) ! nc_rec op when there are no record vars
+ PARAMETER (NF_ECHAR = -56) ! Attempt to convert between text & numbers
+ PARAMETER (NF_EEDGE = -57) ! Edge+start exceeds dimension bound
+ PARAMETER (NF_ESTRIDE = -58) ! Illegal stride
+ PARAMETER (NF_EBADNAME = -59) ! Attribute or variable name contains illegal characters
+ PARAMETER (NF_ERANGE = -60) ! Math result not representable
+ PARAMETER (NF_ENOMEM = -61) ! Memory allocation (malloc) failure
+ PARAMETER (NF_EVARSIZE = -62) ! One or more variable sizes violate format constraints
+ PARAMETER (NF_EDIMSIZE = -63) ! Invalid dimension size
+ PARAMETER (NF_ETRUNC = -64) ! File likely truncated or possibly corrupted
+ PARAMETER (NF_EAXISTYPE = -65) ! Unknown axis type
+
+! Following errors are added for DAP
+ PARAMETER (NF_EDAP = -66) ! Generic DAP error
+ PARAMETER (NF_ECURL = -67) ! Generic libcurl error
+ PARAMETER (NF_EIO = -68) ! Generic IO error
+ PARAMETER (NF_ENODATA = -69) ! Attempt to access variable with no data
+ PARAMETER (NF_EDAPSVC = -70) ! DAP server error
+ PARAMETER (NF_EDAS = -71) ! Malformed or inaccessible DAS
+ PARAMETER (NF_EDDS = -72) ! Malformed or inaccessible DDS
+ PARAMETER (NF_EDATADDS = -73) ! Malformed or inaccessible DATADDS
+ PARAMETER (NF_EDAPURL = -74) ! Malformed DAP URL
+ PARAMETER (NF_EDAPCONSTRAINT = -75) ! Malformed DAP Constraint
+ PARAMETER (NF_ETRANSLATION = -76) ! Untranslatable construct
+ PARAMETER (NF_EACCESS = -77) ! Access Failure
+ PARAMETER (NF_EAUTH = -78) ! Authorization Failure
+
+! Misc. additional errors
+ PARAMETER (NF_ENOTFOUND = -90) ! No such file
+ PARAMETER (NF_ECANTREMOVE = -91) ! Can't remove file
+
+!
+! netCDF-4 error codes (copied from netCDF release)
+!
+ integer NF_EHDFERR
+ integer NF_ECANTREAD
+ integer NF_ECANTWRITE
+ integer NF_ECANTCREATE
+ integer NF_EFILEMETA
+ integer NF_EDIMMETA
+ integer NF_EATTMETA
+ integer NF_EVARMETA
+ integer NF_ENOCOMPOUND
+ integer NF_EATTEXISTS
+ integer NF_ENOTNC4
+ integer NF_ESTRICTNC3
+ integer NF_ENOTNC3
+ integer NF_ENOPAR
+ integer NF_EPARINIT
+ integer NF_EBADGRPID
+ integer NF_EBADTYPID
+ integer NF_ETYPDEFINED
+ integer NF_EBADFIELD
+ integer NF_EBADCLASS
+ integer NF_EMAPTYPE
+ integer NF_ELATEFILL
+ integer NF_ELATEDEF
+ integer NF_EDIMSCALE
+ integer NF_ENOGRP
+ integer NF_ESTORAGE
+ integer NF_EBADCHUNK
+ integer NF_ENOTBUILT
+ integer NF_EDISKLESS
+ integer NF_ECANTEXTEND
+ integer NF_EMPI
+
+ PARAMETER (NF_EHDFERR = -101) ! Error at HDF5 layer.
+ PARAMETER (NF_ECANTREAD = -102) ! Can't read.
+ PARAMETER (NF_ECANTWRITE = -103) ! Can't write.
+ PARAMETER (NF_ECANTCREATE = -104) ! Can't create.
+ PARAMETER (NF_EFILEMETA = -105) ! Problem with file metadata.
+ PARAMETER (NF_EDIMMETA = -106) ! Problem with dimension metadata.
+ PARAMETER (NF_EATTMETA = -107) ! Problem with attribute metadata.
+ PARAMETER (NF_EVARMETA = -108) ! Problem with variable metadata.
+ PARAMETER (NF_ENOCOMPOUND = -109) ! Not a compound type.
+ PARAMETER (NF_EATTEXISTS = -110) ! Attribute already exists.
+ PARAMETER (NF_ENOTNC4 = -111) ! Attempting netcdf-4 operation on netcdf-3 file.
+ PARAMETER (NF_ESTRICTNC3 = -112) ! Attempting netcdf-4 operation on strict nc3 netcdf-4 file.
+ PARAMETER (NF_ENOTNC3 = -113) ! Attempting netcdf-3 operation on netcdf-4 file.
+ PARAMETER (NF_ENOPAR = -114) ! Parallel operation on file opened for non-parallel access.
+ PARAMETER (NF_EPARINIT = -115) ! Error initializing for parallel access.
+ PARAMETER (NF_EBADGRPID = -116) ! Bad group ID.
+ PARAMETER (NF_EBADTYPID = -117) ! Bad type ID.
+ PARAMETER (NF_ETYPDEFINED = -118) ! Type has already been defined and may not be edited.
+ PARAMETER (NF_EBADFIELD = -119) ! Bad field ID.
+ PARAMETER (NF_EBADCLASS = -120) ! Bad class.
+ PARAMETER (NF_EMAPTYPE = -121) ! Mapped access for atomic types only.
+ PARAMETER (NF_ELATEFILL = -122) ! Attempt to define fill value when data already exists.
+ PARAMETER (NF_ELATEDEF = -123) ! Attempt to define var properties, like deflate, after enddef.
+ PARAMETER (NF_EDIMSCALE = -124) ! Problem with HDF5 dimscales.
+ PARAMETER (NF_ENOGRP = -125) ! No group found.
+ PARAMETER (NF_ESTORAGE = -126) ! Can't specify both contiguous and chunking.
+ PARAMETER (NF_EBADCHUNK = -127) ! Bad chunksize.
+ PARAMETER (NF_ENOTBUILT = -128) ! Attempt to use feature that was not turned on when netCDF was built.
+ PARAMETER (NF_EDISKLESS = -129) ! Error in using diskless access.
+ PARAMETER (NF_ECANTEXTEND = -130) ! Attempt to extend dataset during ind. I/O operation.
+ PARAMETER (NF_EMPI = -131) ! MPI operation failed.
+
+!
+! PnetCDF error codes start here
+!
+ integer NF_ESMALL
+ integer NF_ENOTINDEP
+ integer NF_EINDEP
+ integer NF_EFILE
+ integer NF_EREAD
+ integer NF_EWRITE
+ integer NF_EOFILE
+ integer NF_EMULTITYPES
+ integer NF_EIOMISMATCH
+ integer NF_ENEGATIVECNT
+ integer NF_EUNSPTETYPE
+ integer NF_EINVAL_REQUEST
+ integer NF_EAINT_TOO_SMALL
+ integer NF_ENOTSUPPORT
+ integer NF_ENULLBUF
+ integer NF_EPREVATTACHBUF
+ integer NF_ENULLABUF
+ integer NF_EPENDINGBPUT
+ integer NF_EINSUFFBUF
+ integer NF_ENOENT
+ integer NF_EINTOVERFLOW
+ integer NF_ENOTENABLED
+ integer NF_EBAD_FILE
+ integer NF_ENO_SPACE
+ integer NF_EQUOTA
+ integer NF_ENULLSTART
+ integer NF_ENULLCOUNT
+ integer NF_EINVAL_CMODE
+ integer NF_ETYPESIZE
+ integer NF_ETYPE_MISMATCH
+ integer NF_ETYPESIZE_MISMATCH
+ integer NF_ESTRICTCDF2
+ integer NF_ENOTRECVAR
+ integer NF_ENOTFILL
+
+ integer NF_EMULTIDEFINE
+ integer NF_EMULTIDEFINE_OMODE, NF_ECMODE
+ integer NF_EMULTIDEFINE_DIM_NUM, NF_EDIMS_NELEMS_MULTIDEFINE
+ integer NF_EMULTIDEFINE_DIM_SIZE, NF_EDIMS_SIZE_MULTIDEFINE
+ integer NF_EMULTIDEFINE_DIM_NAME, NF_EDIMS_NAME_MULTIDEFINE
+ integer NF_EMULTIDEFINE_VAR_NUM, NF_EVARS_NELEMS_MULTIDEFINE
+ integer NF_EMULTIDEFINE_VAR_NAME, NF_EVARS_NAME_MULTIDEFINE
+ integer NF_EMULTIDEFINE_VAR_NDIMS, NF_EVARS_NDIMS_MULTIDEFINE
+ integer NF_EMULTIDEFINE_VAR_DIMIDS, NF_EVARS_DIMIDS_MULTIDEFINE
+ integer NF_EMULTIDEFINE_VAR_TYPE, NF_EVARS_TYPE_MULTIDEFINE
+ integer NF_EMULTIDEFINE_VAR_LEN, NF_EVARS_LEN_MULTIDEFINE
+ integer NF_EMULTIDEFINE_VAR_BEGIN, NF_EVARS_BEGIN_MULTIDEFINE
+ integer NF_EMULTIDEFINE_NUMRECS, NF_ENUMRECS_MULTIDEFINE
+ integer NF_EMULTIDEFINE_ATTR_NUM
+ integer NF_EMULTIDEFINE_ATTR_SIZE
+ integer NF_EMULTIDEFINE_ATTR_NAME
+ integer NF_EMULTIDEFINE_ATTR_TYPE
+ integer NF_EMULTIDEFINE_ATTR_LEN
+ integer NF_EMULTIDEFINE_ATTR_VAL
+ integer NF_EMULTIDEFINE_FNC_ARGS
+ integer NF_EMULTIDEFINE_FILL_MODE
+ integer NF_EMULTIDEFINE_VAR_FILL_MODE
+ integer NF_EMULTIDEFINE_VAR_FILL_VALUE
+
+!
+! PnetCDF error codes start from -201
+!
+ PARAMETER (NF_ESMALL = -201) ! size of off_t too small for format
+ PARAMETER (NF_ENOTINDEP = -202) ! Operation not allowed in collective data mode
+ PARAMETER (NF_EINDEP = -203) ! Operation not allowed in independent data mode
+ PARAMETER (NF_EFILE = -204) ! Unknown error in file operation
+ PARAMETER (NF_EREAD = -205) ! Unknown error in reading file
+ PARAMETER (NF_EWRITE = -206) ! Unknown error in writing to file
+ PARAMETER (NF_EOFILE = -207) ! file open/creation failed
+ PARAMETER (NF_EMULTITYPES = -208) ! Multiple types used in memory data
+ PARAMETER (NF_EIOMISMATCH = -209) ! Input/Output data amount mismatch
+ PARAMETER (NF_ENEGATIVECNT = -210) ! Negative count is specified
+ PARAMETER (NF_EUNSPTETYPE = -211) ! Unsupported etype in memory MPI datatype
+ PARAMETER (NF_EINVAL_REQUEST = -212) ! invalid nonblocking request ID
+ PARAMETER (NF_EAINT_TOO_SMALL = -213) ! MPI_Aint not large enough to hold requested value
+ PARAMETER (NF_ENOTSUPPORT = -214) ! feature is not yet supported
+ PARAMETER (NF_ENULLBUF = -215) ! trying to attach a NULL buffer
+ PARAMETER (NF_EPREVATTACHBUF = -216) ! previous attached buffer is found
+ PARAMETER (NF_ENULLABUF = -217) ! no attached buffer is found
+ PARAMETER (NF_EPENDINGBPUT = -218) ! pending bput is found, cannot detach buffer
+ PARAMETER (NF_EINSUFFBUF = -219) ! attached buffer is too small
+ PARAMETER (NF_ENOENT = -220) ! File does not exist when calling nfmpi_open()
+ PARAMETER (NF_EINTOVERFLOW = -221) ! Overflow when type cast to 4-byte integer
+ PARAMETER (NF_ENOTENABLED = -222) ! feature is not enabled
+ PARAMETER (NF_EBAD_FILE = -223) ! Invalid file name (e.g., path name too long)
+ PARAMETER (NF_ENO_SPACE = -224) ! Not enough space
+ PARAMETER (NF_EQUOTA = -225) ! Quota exceeded
+ PARAMETER (NF_ENULLSTART = -226) ! argument start is a NULL pointer
+ PARAMETER (NF_ENULLCOUNT = -227) ! argument count is a NULL pointer
+ PARAMETER (NF_EINVAL_CMODE = -228) ! Invalid file create mode, cannot have both NC_64BIT_OFFSET & NC_64BIT_DATA
+ PARAMETER (NF_ETYPESIZE = -229) ! MPI derived data type size error (bigger than the variable size)
+ PARAMETER (NF_ETYPE_MISMATCH = -230) ! element type of the MPI derived data type mismatches the variable type
+ PARAMETER (NF_ETYPESIZE_MISMATCH = -231) ! file type size mismatches buffer type size
+ PARAMETER (NF_ESTRICTCDF2 = -232) ! Attempting CDF-5 operation on CDF-2 file
+ PARAMETER (NF_ENOTRECVAR = -233) ! Attempting operation only for record variables
+ PARAMETER (NF_ENOTFILL = -234) ! Attempting to fill a variable when its fill mode is off
+
+!
+! PnetCDF header inconsistency errors start from -250
+!
+ PARAMETER (NF_EMULTIDEFINE = -250) ! NC definitions on multiprocesses conflict
+ PARAMETER (NF_EMULTIDEFINE_OMODE = -251) ! file create/open modes are inconsistent
+ PARAMETER (NF_EMULTIDEFINE_DIM_NUM = -252) ! inconsistent number of dimensions
+ PARAMETER (NF_EMULTIDEFINE_DIM_SIZE = -253) ! inconsistent size of dimension
+ PARAMETER (NF_EMULTIDEFINE_DIM_NAME = -254) ! inconsistent dimension names
+ PARAMETER (NF_EMULTIDEFINE_VAR_NUM = -255) ! inconsistent number of variables
+ PARAMETER (NF_EMULTIDEFINE_VAR_NAME = -256) ! inconsistent variable name
+ PARAMETER (NF_EMULTIDEFINE_VAR_NDIMS = -257) ! inconsistent variable's number of dimensions
+ PARAMETER (NF_EMULTIDEFINE_VAR_DIMIDS = -258) ! inconsistent variable's dimid
+ PARAMETER (NF_EMULTIDEFINE_VAR_TYPE = -259) ! inconsistent variable's data type
+ PARAMETER (NF_EMULTIDEFINE_VAR_LEN = -260) ! inconsistent variable's size
+ PARAMETER (NF_EMULTIDEFINE_NUMRECS = -261) ! inconsistent number of records
+ PARAMETER (NF_EMULTIDEFINE_VAR_BEGIN = -262) ! inconsistent variable file begin offset (internal use)
+ PARAMETER (NF_EMULTIDEFINE_ATTR_NUM = -263) ! inconsistent number of attributes
+ PARAMETER (NF_EMULTIDEFINE_ATTR_SIZE = -264) ! inconsistent memory space used by attribute (internal use)
+ PARAMETER (NF_EMULTIDEFINE_ATTR_NAME = -265) ! inconsistent attribute name
+ PARAMETER (NF_EMULTIDEFINE_ATTR_TYPE = -266) ! inconsistent attribute type
+ PARAMETER (NF_EMULTIDEFINE_ATTR_LEN = -267) ! inconsistent attribute length
+ PARAMETER (NF_EMULTIDEFINE_ATTR_VAL = -268) ! inconsistent attribute value
+ PARAMETER (NF_EMULTIDEFINE_FNC_ARGS = -269) ! inconsistent function arguments used in collective API
+ PARAMETER (NF_EMULTIDEFINE_FILL_MODE = -270) ! inconsistent dataset fill mode
+ PARAMETER (NF_EMULTIDEFINE_VAR_FILL_MODE = -271) ! inconsistent variable fill mode
+ PARAMETER (NF_EMULTIDEFINE_VAR_FILL_VALUE = -272) ! inconsistent variable fill value
+
+ PARAMETER(NF_ECMODE =NF_EMULTIDEFINE_OMODE)
+ PARAMETER(NF_EDIMS_NELEMS_MULTIDEFINE=NF_EMULTIDEFINE_DIM_NUM)
+ PARAMETER(NF_EDIMS_SIZE_MULTIDEFINE =NF_EMULTIDEFINE_DIM_SIZE)
+ PARAMETER(NF_EDIMS_NAME_MULTIDEFINE =NF_EMULTIDEFINE_DIM_NAME)
+ PARAMETER(NF_EVARS_NELEMS_MULTIDEFINE=NF_EMULTIDEFINE_VAR_NUM)
+ PARAMETER(NF_EVARS_NAME_MULTIDEFINE =NF_EMULTIDEFINE_VAR_NAME)
+ PARAMETER(NF_EVARS_NDIMS_MULTIDEFINE =NF_EMULTIDEFINE_VAR_NDIMS)
+ PARAMETER(NF_EVARS_DIMIDS_MULTIDEFINE=NF_EMULTIDEFINE_VAR_DIMIDS)
+ PARAMETER(NF_EVARS_TYPE_MULTIDEFINE =NF_EMULTIDEFINE_VAR_TYPE)
+ PARAMETER(NF_EVARS_LEN_MULTIDEFINE =NF_EMULTIDEFINE_VAR_LEN)
+ PARAMETER(NF_ENUMRECS_MULTIDEFINE =NF_EMULTIDEFINE_NUMRECS)
+ PARAMETER(NF_EVARS_BEGIN_MULTIDEFINE =NF_EMULTIDEFINE_VAR_BEGIN)
+
+! error handling modes:
+!
+ integer nf_fatal
+ integer nf_verbose
+
+ parameter (nf_fatal = 1)
+ parameter (nf_verbose = 2)
+
+
+!ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
+! begin netcdf 2.4 backward compatibility:
+!
+
+!
+! functions in the fortran interface
+!
+
+ integer ncrdwr
+ integer nccreat
+ integer ncexcl
+ integer ncindef
+ integer ncnsync
+ integer nchsync
+ integer ncndirty
+ integer nchdirty
+ integer nclink
+ integer ncnowrit
+ integer ncwrite
+ integer ncclob
+ integer ncnoclob
+ integer ncglobal
+ integer ncfill
+ integer ncnofill
+ integer maxncop
+ integer maxncdim
+ integer maxncatt
+ integer maxncvar
+ integer maxncnam
+ integer maxvdims
+ integer ncnoerr
+ integer ncebadid
+ integer ncenfile
+ integer nceexist
+ integer nceinval
+ integer nceperm
+ integer ncenotin
+ integer nceindef
+ integer ncecoord
+ integer ncemaxds
+ integer ncename
+ integer ncenoatt
+ integer ncemaxat
+ integer ncebadty
+ integer ncebadd
+ integer ncests
+ integer nceunlim
+ integer ncemaxvs
+ integer ncenotvr
+ integer nceglob
+ integer ncenotnc
+ integer ncfoobar
+ integer ncsyserr
+ integer ncfatal
+ integer ncverbos
+ integer ncentool
+
+
+!
+! netcdf data types:
+!
+ integer ncbyte
+ integer ncchar
+ integer ncshort
+ integer nclong
+ integer ncfloat
+ integer ncdouble
+
+ parameter(ncbyte = 1)
+ parameter(ncchar = 2)
+ parameter(ncshort = 3)
+ parameter(nclong = 4)
+ parameter(ncfloat = 5)
+ parameter(ncdouble = 6)
+
+!
+! masks for the struct nc flag field; passed in as 'mode' arg to
+! nccreate and ncopen.
+!
+
+! read/write, 0 => readonly
+ parameter(ncrdwr = 1)
+! in create phase, cleared by ncendef
+ parameter(nccreat = 2)
+! on create destroy existing file
+ parameter(ncexcl = 4)
+! in define mode, cleared by ncendef
+ parameter(ncindef = 8)
+! synchronise numrecs on change (x'10')
+ parameter(ncnsync = 16)
+! synchronise whole header on change (x'20')
+ parameter(nchsync = 32)
+! numrecs has changed (x'40')
+ parameter(ncndirty = 64)
+! header info has changed (x'80')
+ parameter(nchdirty = 128)
+! prefill vars on endef and increase of record, the default behavior
+ parameter(ncfill = 0)
+! do not fill vars on endef and increase of record (x'100')
+ parameter(ncnofill = 256)
+! isa link (x'8000')
+ parameter(nclink = 32768)
+
+!
+! 'mode' arguments for nccreate and ncopen
+!
+ parameter(ncnowrit = 0)
+ parameter(ncwrite = ncrdwr)
+ parameter(ncclob = nf_clobber)
+ parameter(ncnoclob = nf_noclobber)
+
+!
+! 'size' argument to ncdimdef for an unlimited dimension
+!
+ integer ncunlim
+ parameter(ncunlim = 0)
+
+!
+! attribute id to put/get a global attribute
+!
+ parameter(ncglobal = 0)
+
+!
+! advisory maximums:
+!
+ parameter(maxncop = 32)
+ parameter(maxncdim = 100)
+ parameter(maxncatt = 2000)
+ parameter(maxncvar = 2000)
+! not enforced
+ parameter(maxncnam = 128)
+ parameter(maxvdims = maxncdim)
+
+!
+! global netcdf error status variable
+! initialized in error.c
+!
+
+! no error
+ parameter(ncnoerr = nf_noerr)
+! not a netcdf id
+ parameter(ncebadid = nf_ebadid)
+! too many netcdfs open
+ parameter(ncenfile = -31) ! nc_syserr
+! netcdf file exists && ncnoclob
+ parameter(nceexist = nf_eexist)
+! invalid argument
+ parameter(nceinval = nf_einval)
+! write to read only
+ parameter(nceperm = nf_eperm)
+! operation not allowed in data mode
+ parameter(ncenotin = nf_enotindefine)
+! operation not allowed in define mode
+ parameter(nceindef = nf_eindefine)
+! coordinates out of domain
+ parameter(ncecoord = nf_einvalcoords)
+! maxncdims exceeded
+ parameter(ncemaxds = nf_emaxdims)
+! string match to name in use
+ parameter(ncename = nf_enameinuse)
+! attribute not found
+ parameter(ncenoatt = nf_enotatt)
+! maxncattrs exceeded
+ parameter(ncemaxat = nf_emaxatts)
+! not a netcdf data type
+ parameter(ncebadty = nf_ebadtype)
+! invalid dimension id
+ parameter(ncebadd = nf_ebaddim)
+! ncunlimited in the wrong index
+ parameter(nceunlim = nf_eunlimpos)
+! maxncvars exceeded
+ parameter(ncemaxvs = nf_emaxvars)
+! variable not found
+ parameter(ncenotvr = nf_enotvar)
+! action prohibited on ncglobal varid
+ parameter(nceglob = nf_eglobal)
+! not a netcdf file
+ parameter(ncenotnc = nf_enotnc)
+ parameter(ncests = nf_ests)
+ parameter (ncentool = nf_emaxname)
+ parameter(ncfoobar = 32)
+ parameter(ncsyserr = -31)
+
+!
+! global options variable. used to determine behavior of error handler.
+! initialized in lerror.c
+!
+ parameter(ncfatal = 1)
+ parameter(ncverbos = 2)
+
+!
+! default fill values. these must be the same as in the c interface.
+!
+ integer filbyte
+ integer filchar
+ integer filshort
+ integer fillong
+ real filfloat
+ doubleprecision fildoub
+
+ parameter (filbyte = -127)
+ parameter (filchar = 0)
+ parameter (filshort = -32767)
+ parameter (fillong = -2147483647)
+ parameter (filfloat = 9.9692099683868690e+36)
+ parameter (fildoub = 9.9692099683868690e+36)
+
+! NULL request for non-blocking I/O APIs
+ integer NF_REQ_NULL
+ PARAMETER (NF_REQ_NULL = -1)
+
+! indicate to flush all pending non-blocking requests
+ integer NF_REQ_ALL
+ PARAMETER (NF_REQ_ALL = -1)
+
+!
+! PnetCDF APIs
+!
+
+!
+! miscellaneous routines:
+!
+ character*80 nfmpi_inq_libvers
+ character*80 nfmpi_strerror
+
+ external nfmpi_inq_libvers
+ external nfmpi_strerror
+
+ logical nfmpi_issyserr
+ external nfmpi_issyserr
+
+!
+! control routines:
+!
+ integer nfmpi_create
+ integer nfmpi_open
+ integer nfmpi_inq_format
+ integer nfmpi_inq_file_format
+ integer nfmpi_inq_file_info
+ integer nfmpi_get_file_info
+ integer nfmpi_delete
+ integer nfmpi_enddef
+ integer nfmpi__enddef
+ integer nfmpi_redef
+ integer nfmpi_set_default_format
+ integer nfmpi_inq_default_format
+ integer nfmpi_sync
+ integer nfmpi_abort
+ integer nfmpi_close
+ integer nfmpi_set_fill
+ integer nfmpi_def_var_fill
+ integer nfmpi_inq_var_fill
+ integer nfmpi_fill_var_rec
+
+ external nfmpi_create
+ external nfmpi_open
+ external nfmpi_inq_format
+ external nfmpi_inq_file_format
+ external nfmpi_inq_file_info
+ external nfmpi_get_file_info
+ external nfmpi_delete
+ external nfmpi_enddef
+ external nfmpi__enddef
+ external nfmpi_redef
+ external nfmpi_set_default_format
+ external nfmpi_inq_default_format
+ external nfmpi_sync
+ external nfmpi_abort
+ external nfmpi_close
+ external nfmpi_set_fill
+ external nfmpi_def_var_fill
+ external nfmpi_inq_var_fill
+ external nfmpi_fill_var_rec
+
+!
+! general inquiry routines:
+!
+ integer nfmpi_inq
+ integer nfmpi_inq_ndims
+ integer nfmpi_inq_nvars
+ integer nfmpi_inq_num_rec_vars
+ integer nfmpi_inq_num_fix_vars
+ integer nfmpi_inq_natts
+ integer nfmpi_inq_unlimdim
+ integer nfmpi_inq_striping
+ integer nfmpi_inq_malloc_size
+ integer nfmpi_inq_malloc_max_size
+ integer nfmpi_inq_malloc_list
+ integer nfmpi_inq_files_opened
+ integer nfmpi_inq_recsize
+
+ external nfmpi_inq
+ external nfmpi_inq_ndims
+ external nfmpi_inq_nvars
+ external nfmpi_inq_num_rec_vars
+ external nfmpi_inq_num_fix_vars
+ external nfmpi_inq_natts
+ external nfmpi_inq_unlimdim
+ external nfmpi_inq_striping
+ external nfmpi_inq_malloc_size
+ external nfmpi_inq_malloc_max_size
+ external nfmpi_inq_malloc_list
+ external nfmpi_inq_files_opened
+ external nfmpi_inq_recsize
+!
+! dimension routines:
+!
+ integer nfmpi_def_dim
+ integer nfmpi_inq_dimid
+ integer nfmpi_inq_dim
+ integer nfmpi_inq_dimname
+ integer nfmpi_inq_dimlen
+ integer nfmpi_rename_dim
+
+ external nfmpi_def_dim
+ external nfmpi_inq_dimid
+ external nfmpi_inq_dim
+ external nfmpi_inq_dimname
+ external nfmpi_inq_dimlen
+ external nfmpi_rename_dim
+!
+! general attribute routines:
+!
+ integer nfmpi_inq_att
+ integer nfmpi_inq_attid
+ integer nfmpi_inq_atttype
+ integer nfmpi_inq_attlen
+ integer nfmpi_inq_attname
+ integer nfmpi_copy_att
+ integer nfmpi_rename_att
+ integer nfmpi_del_att
+
+ external nfmpi_inq_att
+ external nfmpi_inq_attid
+ external nfmpi_inq_atttype
+ external nfmpi_inq_attlen
+ external nfmpi_inq_attname
+ external nfmpi_copy_att
+ external nfmpi_rename_att
+ external nfmpi_del_att
+
+!
+! attribute put/get routines:
+!
+ integer nfmpi_put_att, nfmpi_get_att
+ integer nfmpi_put_att_text, nfmpi_get_att_text
+ integer nfmpi_put_att_int1, nfmpi_get_att_int1
+ integer nfmpi_put_att_int2, nfmpi_get_att_int2
+ integer nfmpi_put_att_int, nfmpi_get_att_int
+ integer nfmpi_put_att_real, nfmpi_get_att_real
+ integer nfmpi_put_att_double, nfmpi_get_att_double
+ integer nfmpi_put_att_int8, nfmpi_get_att_int8
+
+ external nfmpi_put_att, nfmpi_get_att
+ external nfmpi_put_att_text, nfmpi_get_att_text
+ external nfmpi_put_att_int1, nfmpi_get_att_int1
+ external nfmpi_put_att_int2, nfmpi_get_att_int2
+ external nfmpi_put_att_int, nfmpi_get_att_int
+ external nfmpi_put_att_real, nfmpi_get_att_real
+ external nfmpi_put_att_double, nfmpi_get_att_double
+ external nfmpi_put_att_int8, nfmpi_get_att_int8
+
+!
+! independent data mode routines:
+!
+ integer nfmpi_begin_indep_data
+ integer nfmpi_end_indep_data
+
+ external nfmpi_begin_indep_data
+ external nfmpi_end_indep_data
+
+!
+! general variable routines:
+!
+ integer nfmpi_def_var
+ integer nfmpi_inq_var
+ integer nfmpi_inq_varid
+ integer nfmpi_inq_varname
+ integer nfmpi_inq_vartype
+ integer nfmpi_inq_varndims
+ integer nfmpi_inq_vardimid
+ integer nfmpi_inq_varnatts
+ integer nfmpi_rename_var
+
+ external nfmpi_def_var
+ external nfmpi_inq_var
+ external nfmpi_inq_varid
+ external nfmpi_inq_varname
+ external nfmpi_inq_vartype
+ external nfmpi_inq_varndims
+ external nfmpi_inq_vardimid
+ external nfmpi_inq_varnatts
+ external nfmpi_rename_var
+
+!
+! entire variable put/get routines:
+!
+ integer nfmpi_put_var
+ integer nfmpi_put_var_text
+ integer nfmpi_put_var_int1
+ integer nfmpi_put_var_int2
+ integer nfmpi_put_var_int
+ integer nfmpi_put_var_real
+ integer nfmpi_put_var_double
+ integer nfmpi_put_var_int8
+
+ external nfmpi_put_var
+ external nfmpi_put_var_text
+ external nfmpi_put_var_int1
+ external nfmpi_put_var_int2
+ external nfmpi_put_var_int
+ external nfmpi_put_var_real
+ external nfmpi_put_var_double
+ external nfmpi_put_var_int8
+
+ integer nfmpi_get_var, nfmpi_get_var_all
+ integer nfmpi_get_var_text, nfmpi_get_var_text_all
+ integer nfmpi_get_var_int1, nfmpi_get_var_int1_all
+ integer nfmpi_get_var_int2, nfmpi_get_var_int2_all
+ integer nfmpi_get_var_int, nfmpi_get_var_int_all
+ integer nfmpi_get_var_real, nfmpi_get_var_real_all
+ integer nfmpi_get_var_double, nfmpi_get_var_double_all
+ integer nfmpi_get_var_int8, nfmpi_get_var_int8_all
+
+ external nfmpi_get_var, nfmpi_get_var_all
+ external nfmpi_get_var_text, nfmpi_get_var_text_all
+ external nfmpi_get_var_int1, nfmpi_get_var_int1_all
+ external nfmpi_get_var_int2, nfmpi_get_var_int2_all
+ external nfmpi_get_var_int, nfmpi_get_var_int_all
+ external nfmpi_get_var_real, nfmpi_get_var_real_all
+ external nfmpi_get_var_double, nfmpi_get_var_double_all
+ external nfmpi_get_var_int8, nfmpi_get_var_int8_all
+
+!
+! single element variable put/get routines:
+!
+ integer nfmpi_put_var1, nfmpi_put_var1_all
+ integer nfmpi_put_var1_text, nfmpi_put_var1_text_all
+ integer nfmpi_put_var1_int1, nfmpi_put_var1_int1_all
+ integer nfmpi_put_var1_int2, nfmpi_put_var1_int2_all
+ integer nfmpi_put_var1_int, nfmpi_put_var1_int_all
+ integer nfmpi_put_var1_real, nfmpi_put_var1_real_all
+ integer nfmpi_put_var1_double, nfmpi_put_var1_double_all
+ integer nfmpi_put_var1_int8, nfmpi_put_var1_int8_all
+
+ external nfmpi_put_var1, nfmpi_put_var1_all
+ external nfmpi_put_var1_text, nfmpi_put_var1_text_all
+ external nfmpi_put_var1_int1, nfmpi_put_var1_int1_all
+ external nfmpi_put_var1_int2, nfmpi_put_var1_int2_all
+ external nfmpi_put_var1_int, nfmpi_put_var1_int_all
+ external nfmpi_put_var1_real, nfmpi_put_var1_real_all
+ external nfmpi_put_var1_double, nfmpi_put_var1_double_all
+ external nfmpi_put_var1_int8, nfmpi_put_var1_int8_all
+
+ integer nfmpi_get_var1, nfmpi_get_var1_all
+ integer nfmpi_get_var1_text, nfmpi_get_var1_text_all
+ integer nfmpi_get_var1_int1, nfmpi_get_var1_int1_all
+ integer nfmpi_get_var1_int2, nfmpi_get_var1_int2_all
+ integer nfmpi_get_var1_int, nfmpi_get_var1_int_all
+ integer nfmpi_get_var1_real, nfmpi_get_var1_real_all
+ integer nfmpi_get_var1_double, nfmpi_get_var1_double_all
+ integer nfmpi_get_var1_int8, nfmpi_get_var1_int8_all
+
+ external nfmpi_get_var1, nfmpi_get_var1_all
+ external nfmpi_get_var1_text, nfmpi_get_var1_text_all
+ external nfmpi_get_var1_int1, nfmpi_get_var1_int1_all
+ external nfmpi_get_var1_int2, nfmpi_get_var1_int2_all
+ external nfmpi_get_var1_int, nfmpi_get_var1_int_all
+ external nfmpi_get_var1_real, nfmpi_get_var1_real_all
+ external nfmpi_get_var1_double, nfmpi_get_var1_double_all
+ external nfmpi_get_var1_int8, nfmpi_get_var1_int8_all
+
+!
+! variable sub-array put/get routines:
+!
+ integer nfmpi_put_vara, nfmpi_put_vara_all
+ integer nfmpi_put_vara_text, nfmpi_put_vara_text_all
+ integer nfmpi_put_vara_int1, nfmpi_put_vara_int1_all
+ integer nfmpi_put_vara_int2, nfmpi_put_vara_int2_all
+ integer nfmpi_put_vara_int, nfmpi_put_vara_int_all
+ integer nfmpi_put_vara_real, nfmpi_put_vara_real_all
+ integer nfmpi_put_vara_double, nfmpi_put_vara_double_all
+ integer nfmpi_put_vara_int8, nfmpi_put_vara_int8_all
+
+ external nfmpi_put_vara, nfmpi_put_vara_all
+ external nfmpi_put_vara_text, nfmpi_put_vara_text_all
+ external nfmpi_put_vara_int1, nfmpi_put_vara_int1_all
+ external nfmpi_put_vara_int2, nfmpi_put_vara_int2_all
+ external nfmpi_put_vara_int, nfmpi_put_vara_int_all
+ external nfmpi_put_vara_real, nfmpi_put_vara_real_all
+ external nfmpi_put_vara_double, nfmpi_put_vara_double_all
+ external nfmpi_put_vara_int8, nfmpi_put_vara_int8_all
+
+ integer nfmpi_get_vara, nfmpi_get_vara_all
+ integer nfmpi_get_vara_text, nfmpi_get_vara_text_all
+ integer nfmpi_get_vara_int1, nfmpi_get_vara_int1_all
+ integer nfmpi_get_vara_int2, nfmpi_get_vara_int2_all
+ integer nfmpi_get_vara_int, nfmpi_get_vara_int_all
+ integer nfmpi_get_vara_real, nfmpi_get_vara_real_all
+ integer nfmpi_get_vara_double, nfmpi_get_vara_double_all
+ integer nfmpi_get_vara_int8, nfmpi_get_vara_int8_all
+
+ external nfmpi_get_vara, nfmpi_get_vara_all
+ external nfmpi_get_vara_text, nfmpi_get_vara_text_all
+ external nfmpi_get_vara_int1, nfmpi_get_vara_int1_all
+ external nfmpi_get_vara_int2, nfmpi_get_vara_int2_all
+ external nfmpi_get_vara_int, nfmpi_get_vara_int_all
+ external nfmpi_get_vara_real, nfmpi_get_vara_real_all
+ external nfmpi_get_vara_double, nfmpi_get_vara_double_all
+ external nfmpi_get_vara_int8, nfmpi_get_vara_int8_all
+
+!
+! strided variable put/get routines:
+!
+ integer nfmpi_put_vars, nfmpi_put_vars_all
+ integer nfmpi_put_vars_text, nfmpi_put_vars_text_all
+ integer nfmpi_put_vars_int1, nfmpi_put_vars_int1_all
+ integer nfmpi_put_vars_int2, nfmpi_put_vars_int2_all
+ integer nfmpi_put_vars_int, nfmpi_put_vars_int_all
+ integer nfmpi_put_vars_real, nfmpi_put_vars_real_all
+ integer nfmpi_put_vars_double, nfmpi_put_vars_double_all
+ integer nfmpi_put_vars_int8, nfmpi_put_vars_int8_all
+
+ external nfmpi_put_vars, nfmpi_put_vars_all
+ external nfmpi_put_vars_text, nfmpi_put_vars_text_all
+ external nfmpi_put_vars_int1, nfmpi_put_vars_int1_all
+ external nfmpi_put_vars_int2, nfmpi_put_vars_int2_all
+ external nfmpi_put_vars_int, nfmpi_put_vars_int_all
+ external nfmpi_put_vars_real, nfmpi_put_vars_real_all
+ external nfmpi_put_vars_double, nfmpi_put_vars_double_all
+ external nfmpi_put_vars_int8, nfmpi_put_vars_int8_all
+
+ integer nfmpi_get_vars, nfmpi_get_vars_all
+ integer nfmpi_get_vars_text, nfmpi_get_vars_text_all
+ integer nfmpi_get_vars_int1, nfmpi_get_vars_int1_all
+ integer nfmpi_get_vars_int2, nfmpi_get_vars_int2_all
+ integer nfmpi_get_vars_int, nfmpi_get_vars_int_all
+ integer nfmpi_get_vars_real, nfmpi_get_vars_real_all
+ integer nfmpi_get_vars_double, nfmpi_get_vars_double_all
+ integer nfmpi_get_vars_int8, nfmpi_get_vars_int8_all
+
+ external nfmpi_get_vars, nfmpi_get_vars_all
+ external nfmpi_get_vars_text, nfmpi_get_vars_text_all
+ external nfmpi_get_vars_int1, nfmpi_get_vars_int1_all
+ external nfmpi_get_vars_int2, nfmpi_get_vars_int2_all
+ external nfmpi_get_vars_int, nfmpi_get_vars_int_all
+ external nfmpi_get_vars_real, nfmpi_get_vars_real_all
+ external nfmpi_get_vars_double, nfmpi_get_vars_double_all
+ external nfmpi_get_vars_int8, nfmpi_get_vars_int8_all
+
+!
+! mapped variable put/get routines:
+!
+ integer nfmpi_put_varm, nfmpi_put_varm_all
+ integer nfmpi_put_varm_text, nfmpi_put_varm_text_all
+ integer nfmpi_put_varm_int1, nfmpi_put_varm_int1_all
+ integer nfmpi_put_varm_int2, nfmpi_put_varm_int2_all
+ integer nfmpi_put_varm_int, nfmpi_put_varm_int_all
+ integer nfmpi_put_varm_real, nfmpi_put_varm_real_all
+ integer nfmpi_put_varm_double, nfmpi_put_varm_double_all
+ integer nfmpi_put_varm_int8, nfmpi_put_varm_int8_all
+
+ external nfmpi_put_varm, nfmpi_put_varm_all
+ external nfmpi_put_varm_text, nfmpi_put_varm_text_all
+ external nfmpi_put_varm_int1, nfmpi_put_varm_int1_all
+ external nfmpi_put_varm_int2, nfmpi_put_varm_int2_all
+ external nfmpi_put_varm_int, nfmpi_put_varm_int_all
+ external nfmpi_put_varm_real, nfmpi_put_varm_real_all
+ external nfmpi_put_varm_double, nfmpi_put_varm_double_all
+ external nfmpi_put_varm_int8, nfmpi_put_varm_int8_all
+
+ integer nfmpi_get_varm, nfmpi_get_varm_all
+ integer nfmpi_get_varm_text, nfmpi_get_varm_text_all
+ integer nfmpi_get_varm_int1, nfmpi_get_varm_int1_all
+ integer nfmpi_get_varm_int2, nfmpi_get_varm_int2_all
+ integer nfmpi_get_varm_int, nfmpi_get_varm_int_all
+ integer nfmpi_get_varm_real, nfmpi_get_varm_real_all
+ integer nfmpi_get_varm_double, nfmpi_get_varm_double_all
+ integer nfmpi_get_varm_int8, nfmpi_get_varm_int8_all
+
+ external nfmpi_get_varm, nfmpi_get_varm_all
+ external nfmpi_get_varm_text, nfmpi_get_varm_text_all
+ external nfmpi_get_varm_int1, nfmpi_get_varm_int1_all
+ external nfmpi_get_varm_int2, nfmpi_get_varm_int2_all
+ external nfmpi_get_varm_int, nfmpi_get_varm_int_all
+ external nfmpi_get_varm_real, nfmpi_get_varm_real_all
+ external nfmpi_get_varm_double, nfmpi_get_varm_double_all
+ external nfmpi_get_varm_int8, nfmpi_get_varm_int8_all
+
+!
+! Non-blocking APIs
+!
+! entire variable iput/iget routines:
+!
+ integer nfmpi_iput_var
+ integer nfmpi_iput_var_text
+ integer nfmpi_iput_var_int1
+ integer nfmpi_iput_var_int2
+ integer nfmpi_iput_var_int
+ integer nfmpi_iput_var_real
+ integer nfmpi_iput_var_double
+ integer nfmpi_iput_var_int8
+
+ external nfmpi_iput_var
+ external nfmpi_iput_var_text
+ external nfmpi_iput_var_int1
+ external nfmpi_iput_var_int2
+ external nfmpi_iput_var_int
+ external nfmpi_iput_var_real
+ external nfmpi_iput_var_double
+ external nfmpi_iput_var_int8
+
+ integer nfmpi_iget_var
+ integer nfmpi_iget_var_text
+ integer nfmpi_iget_var_int1
+ integer nfmpi_iget_var_int2
+ integer nfmpi_iget_var_int
+ integer nfmpi_iget_var_real
+ integer nfmpi_iget_var_double
+ integer nfmpi_iget_var_int8
+
+ external nfmpi_iget_var
+ external nfmpi_iget_var_text
+ external nfmpi_iget_var_int1
+ external nfmpi_iget_var_int2
+ external nfmpi_iget_var_int
+ external nfmpi_iget_var_real
+ external nfmpi_iget_var_double
+ external nfmpi_iget_var_int8
+
+!
+! Nonblocking single-element variable iput/iget routines:
+!
+ integer nfmpi_iput_var1
+ integer nfmpi_iput_var1_text
+ integer nfmpi_iput_var1_int1
+ integer nfmpi_iput_var1_int2
+ integer nfmpi_iput_var1_int
+ integer nfmpi_iput_var1_real
+ integer nfmpi_iput_var1_double
+ integer nfmpi_iput_var1_int8
+
+ external nfmpi_iput_var1
+ external nfmpi_iput_var1_text
+ external nfmpi_iput_var1_int1
+ external nfmpi_iput_var1_int2
+ external nfmpi_iput_var1_int
+ external nfmpi_iput_var1_real
+ external nfmpi_iput_var1_double
+ external nfmpi_iput_var1_int8
+
+ integer nfmpi_iget_var1
+ integer nfmpi_iget_var1_text
+ integer nfmpi_iget_var1_int1
+ integer nfmpi_iget_var1_int2
+ integer nfmpi_iget_var1_int
+ integer nfmpi_iget_var1_real
+ integer nfmpi_iget_var1_double
+ integer nfmpi_iget_var1_int8
+
+ external nfmpi_iget_var1
+ external nfmpi_iget_var1_text
+ external nfmpi_iget_var1_int1
+ external nfmpi_iget_var1_int2
+ external nfmpi_iget_var1_int
+ external nfmpi_iget_var1_real
+ external nfmpi_iget_var1_double
+ external nfmpi_iget_var1_int8
+
+!
+! Nonblocking subarray variable iput/iget routines:
+!
+ integer nfmpi_iput_vara
+ integer nfmpi_iput_vara_text
+ integer nfmpi_iput_vara_int1
+ integer nfmpi_iput_vara_int2
+ integer nfmpi_iput_vara_int
+ integer nfmpi_iput_vara_real
+ integer nfmpi_iput_vara_double
+ integer nfmpi_iput_vara_int8
+
+ external nfmpi_iput_vara
+ external nfmpi_iput_vara_text
+ external nfmpi_iput_vara_int1
+ external nfmpi_iput_vara_int2
+ external nfmpi_iput_vara_int
+ external nfmpi_iput_vara_real
+ external nfmpi_iput_vara_double
+ external nfmpi_iput_vara_int8
+
+ integer nfmpi_iget_vara
+ integer nfmpi_iget_vara_text
+ integer nfmpi_iget_vara_int1
+ integer nfmpi_iget_vara_int2
+ integer nfmpi_iget_vara_int
+ integer nfmpi_iget_vara_real
+ integer nfmpi_iget_vara_double
+ integer nfmpi_iget_vara_int8
+
+ external nfmpi_iget_vara
+ external nfmpi_iget_vara_text
+ external nfmpi_iget_vara_int1
+ external nfmpi_iget_vara_int2
+ external nfmpi_iget_vara_int
+ external nfmpi_iget_vara_real
+ external nfmpi_iget_vara_double
+ external nfmpi_iget_vara_int8
+
+!
+! Nonblocking strided variable iput/iget routines:
+!
+ integer nfmpi_iput_vars
+ integer nfmpi_iput_vars_text
+ integer nfmpi_iput_vars_int1
+ integer nfmpi_iput_vars_int2
+ integer nfmpi_iput_vars_int
+ integer nfmpi_iput_vars_real
+ integer nfmpi_iput_vars_double
+ integer nfmpi_iput_vars_int8
+
+ external nfmpi_iput_vars
+ external nfmpi_iput_vars_text
+ external nfmpi_iput_vars_int1
+ external nfmpi_iput_vars_int2
+ external nfmpi_iput_vars_int
+ external nfmpi_iput_vars_real
+ external nfmpi_iput_vars_double
+ external nfmpi_iput_vars_int8
+
+ integer nfmpi_iget_vars
+ integer nfmpi_iget_vars_text
+ integer nfmpi_iget_vars_int1
+ integer nfmpi_iget_vars_int2
+ integer nfmpi_iget_vars_int
+ integer nfmpi_iget_vars_real
+ integer nfmpi_iget_vars_double
+ integer nfmpi_iget_vars_int8
+
+ external nfmpi_iget_vars
+ external nfmpi_iget_vars_text
+ external nfmpi_iget_vars_int1
+ external nfmpi_iget_vars_int2
+ external nfmpi_iget_vars_int
+ external nfmpi_iget_vars_real
+ external nfmpi_iget_vars_double
+ external nfmpi_iget_vars_int8
+
+!
+! Nonblocking mapped variable iput/iget routines:
+!
+ integer nfmpi_iput_varm
+ integer nfmpi_iput_varm_text
+ integer nfmpi_iput_varm_int1
+ integer nfmpi_iput_varm_int2
+ integer nfmpi_iput_varm_int
+ integer nfmpi_iput_varm_real
+ integer nfmpi_iput_varm_double
+ integer nfmpi_iput_varm_int8
+
+ external nfmpi_iput_varm
+ external nfmpi_iput_varm_text
+ external nfmpi_iput_varm_int1
+ external nfmpi_iput_varm_int2
+ external nfmpi_iput_varm_int
+ external nfmpi_iput_varm_real
+ external nfmpi_iput_varm_double
+ external nfmpi_iput_varm_int8
+
+ integer nfmpi_iget_varm
+ integer nfmpi_iget_varm_text
+ integer nfmpi_iget_varm_int1
+ integer nfmpi_iget_varm_int2
+ integer nfmpi_iget_varm_int
+ integer nfmpi_iget_varm_real
+ integer nfmpi_iget_varm_double
+ integer nfmpi_iget_varm_int8
+
+ external nfmpi_iget_varm
+ external nfmpi_iget_varm_text
+ external nfmpi_iget_varm_int1
+ external nfmpi_iget_varm_int2
+ external nfmpi_iget_varm_int
+ external nfmpi_iget_varm_real
+ external nfmpi_iget_varm_double
+ external nfmpi_iget_varm_int8
+
+!
+! Nonblocking entire variable bput routines:
+!
+ integer nfmpi_bput_var
+ integer nfmpi_bput_var_text
+ integer nfmpi_bput_var_int1
+ integer nfmpi_bput_var_int2
+ integer nfmpi_bput_var_int
+ integer nfmpi_bput_var_real
+ integer nfmpi_bput_var_double
+ integer nfmpi_bput_var_int8
+
+ external nfmpi_bput_var
+ external nfmpi_bput_var_text
+ external nfmpi_bput_var_int1
+ external nfmpi_bput_var_int2
+ external nfmpi_bput_var_int
+ external nfmpi_bput_var_real
+ external nfmpi_bput_var_double
+ external nfmpi_bput_var_int8
+
+!
+! Nonblocking single element variable bput routines:
+!
+ integer nfmpi_bput_var1
+ integer nfmpi_bput_var1_text
+ integer nfmpi_bput_var1_int1
+ integer nfmpi_bput_var1_int2
+ integer nfmpi_bput_var1_int
+ integer nfmpi_bput_var1_real
+ integer nfmpi_bput_var1_double
+ integer nfmpi_bput_var1_int8
+
+ external nfmpi_bput_var1
+ external nfmpi_bput_var1_text
+ external nfmpi_bput_var1_int1
+ external nfmpi_bput_var1_int2
+ external nfmpi_bput_var1_int
+ external nfmpi_bput_var1_real
+ external nfmpi_bput_var1_double
+ external nfmpi_bput_var1_int8
+
+!
+! Nonblocking subarray variable bput routines:
+!
+ integer nfmpi_bput_vara
+ integer nfmpi_bput_vara_text
+ integer nfmpi_bput_vara_int1
+ integer nfmpi_bput_vara_int2
+ integer nfmpi_bput_vara_int
+ integer nfmpi_bput_vara_real
+ integer nfmpi_bput_vara_double
+ integer nfmpi_bput_vara_int8
+
+ external nfmpi_bput_vara
+ external nfmpi_bput_vara_text
+ external nfmpi_bput_vara_int1
+ external nfmpi_bput_vara_int2
+ external nfmpi_bput_vara_int
+ external nfmpi_bput_vara_real
+ external nfmpi_bput_vara_double
+ external nfmpi_bput_vara_int8
+
+!
+! Nonblocking strided variable bput routines:
+!
+ integer nfmpi_bput_vars
+ integer nfmpi_bput_vars_text
+ integer nfmpi_bput_vars_int1
+ integer nfmpi_bput_vars_int2
+ integer nfmpi_bput_vars_int
+ integer nfmpi_bput_vars_real
+ integer nfmpi_bput_vars_double
+ integer nfmpi_bput_vars_int8
+
+ external nfmpi_bput_vars
+ external nfmpi_bput_vars_text
+ external nfmpi_bput_vars_int1
+ external nfmpi_bput_vars_int2
+ external nfmpi_bput_vars_int
+ external nfmpi_bput_vars_real
+ external nfmpi_bput_vars_double
+ external nfmpi_bput_vars_int8
+
+!
+! Nonblocking mapped variable bput routines:
+!
+ integer nfmpi_bput_varm
+ integer nfmpi_bput_varm_text
+ integer nfmpi_bput_varm_int1
+ integer nfmpi_bput_varm_int2
+ integer nfmpi_bput_varm_int
+ integer nfmpi_bput_varm_real
+ integer nfmpi_bput_varm_double
+ integer nfmpi_bput_varm_int8
+
+ external nfmpi_bput_varm
+ external nfmpi_bput_varm_text
+ external nfmpi_bput_varm_int1
+ external nfmpi_bput_varm_int2
+ external nfmpi_bput_varm_int
+ external nfmpi_bput_varm_real
+ external nfmpi_bput_varm_double
+ external nfmpi_bput_varm_int8
+
+!
+! Nonblocking control APIs
+!
+ integer nfmpi_wait
+ integer nfmpi_wait_all
+ integer nfmpi_cancel
+
+ external nfmpi_wait
+ external nfmpi_wait_all
+ external nfmpi_cancel
+
+ integer nfmpi_buffer_attach
+ integer nfmpi_buffer_detach
+ integer nfmpi_inq_buffer_usage
+ integer nfmpi_inq_buffer_size
+ integer nfmpi_inq_put_size
+ integer nfmpi_inq_get_size
+ integer nfmpi_inq_header_size
+ integer nfmpi_inq_header_extent
+ integer nfmpi_inq_varoffset
+ integer nfmpi_inq_nreqs
+
+ external nfmpi_buffer_attach
+ external nfmpi_buffer_detach
+ external nfmpi_inq_buffer_usage
+ external nfmpi_inq_buffer_size
+ external nfmpi_inq_put_size
+ external nfmpi_inq_get_size
+ external nfmpi_inq_header_size
+ external nfmpi_inq_header_extent
+ external nfmpi_inq_varoffset
+ external nfmpi_inq_nreqs
+
+!
+! varn routines:
+!
+ integer nfmpi_put_varn, nfmpi_put_varn_all
+ integer nfmpi_put_varn_text, nfmpi_put_varn_text_all
+ integer nfmpi_put_varn_int1, nfmpi_put_varn_int1_all
+ integer nfmpi_put_varn_int2, nfmpi_put_varn_int2_all
+ integer nfmpi_put_varn_int, nfmpi_put_varn_int_all
+ integer nfmpi_put_varn_real, nfmpi_put_varn_real_all
+ integer nfmpi_put_varn_double, nfmpi_put_varn_double_all
+ integer nfmpi_put_varn_int8, nfmpi_put_varn_int8_all
+
+ external nfmpi_put_varn, nfmpi_put_varn_all
+ external nfmpi_put_varn_text, nfmpi_put_varn_text_all
+ external nfmpi_put_varn_int1, nfmpi_put_varn_int1_all
+ external nfmpi_put_varn_int2, nfmpi_put_varn_int2_all
+ external nfmpi_put_varn_int, nfmpi_put_varn_int_all
+ external nfmpi_put_varn_real, nfmpi_put_varn_real_all
+ external nfmpi_put_varn_double, nfmpi_put_varn_double_all
+ external nfmpi_put_varn_int8, nfmpi_put_varn_int8_all
+
+ integer nfmpi_get_varn, nfmpi_get_varn_all
+ integer nfmpi_get_varn_text, nfmpi_get_varn_text_all
+ integer nfmpi_get_varn_int1, nfmpi_get_varn_int1_all
+ integer nfmpi_get_varn_int2, nfmpi_get_varn_int2_all
+ integer nfmpi_get_varn_int, nfmpi_get_varn_int_all
+ integer nfmpi_get_varn_real, nfmpi_get_varn_real_all
+ integer nfmpi_get_varn_double, nfmpi_get_varn_double_all
+ integer nfmpi_get_varn_int8, nfmpi_get_varn_int8_all
+
+ external nfmpi_get_varn, nfmpi_get_varn_all
+ external nfmpi_get_varn_text, nfmpi_get_varn_text_all
+ external nfmpi_get_varn_int1, nfmpi_get_varn_int1_all
+ external nfmpi_get_varn_int2, nfmpi_get_varn_int2_all
+ external nfmpi_get_varn_int, nfmpi_get_varn_int_all
+ external nfmpi_get_varn_real, nfmpi_get_varn_real_all
+ external nfmpi_get_varn_double, nfmpi_get_varn_double_all
+ external nfmpi_get_varn_int8, nfmpi_get_varn_int8_all
+
+!
+! Nonblocking varn routines:
+!
+ integer nfmpi_iput_varn
+ integer nfmpi_iput_varn_text
+ integer nfmpi_iput_varn_int1
+ integer nfmpi_iput_varn_int2
+ integer nfmpi_iput_varn_int
+ integer nfmpi_iput_varn_real
+ integer nfmpi_iput_varn_double
+ integer nfmpi_iput_varn_int8
+
+ external nfmpi_iput_varn
+ external nfmpi_iput_varn_text
+ external nfmpi_iput_varn_int1
+ external nfmpi_iput_varn_int2
+ external nfmpi_iput_varn_int
+ external nfmpi_iput_varn_real
+ external nfmpi_iput_varn_double
+ external nfmpi_iput_varn_int8
+
+ integer nfmpi_iget_varn
+ integer nfmpi_iget_varn_text
+ integer nfmpi_iget_varn_int1
+ integer nfmpi_iget_varn_int2
+ integer nfmpi_iget_varn_int
+ integer nfmpi_iget_varn_real
+ integer nfmpi_iget_varn_double
+ integer nfmpi_iget_varn_int8
+
+ external nfmpi_iget_varn
+ external nfmpi_iget_varn_text
+ external nfmpi_iget_varn_int1
+ external nfmpi_iget_varn_int2
+ external nfmpi_iget_varn_int
+ external nfmpi_iget_varn_real
+ external nfmpi_iget_varn_double
+ external nfmpi_iget_varn_int8
+
+ integer nfmpi_bput_varn
+ integer nfmpi_bput_varn_text
+ integer nfmpi_bput_varn_int1
+ integer nfmpi_bput_varn_int2
+ integer nfmpi_bput_varn_int
+ integer nfmpi_bput_varn_real
+ integer nfmpi_bput_varn_double
+ integer nfmpi_bput_varn_int8
+
+ external nfmpi_bput_varn
+ external nfmpi_bput_varn_text
+ external nfmpi_bput_varn_int1
+ external nfmpi_bput_varn_int2
+ external nfmpi_bput_varn_int
+ external nfmpi_bput_varn_real
+ external nfmpi_bput_varn_double
+ external nfmpi_bput_varn_int8
+
+!
+! vard routines:
+!
+ integer nfmpi_put_vard, nfmpi_put_vard_all
+ integer nfmpi_get_vard, nfmpi_get_vard_all
+
+ external nfmpi_put_vard, nfmpi_put_vard_all
+ external nfmpi_get_vard, nfmpi_get_vard_all
+
diff --git a/src/libf/strerrorf.f b/src/libf/strerrorf.f
new file mode 100644
index 0000000..fc0444c
--- /dev/null
+++ b/src/libf/strerrorf.f
@@ -0,0 +1,10 @@
+ character *80 function nfmpi_strerror( err )
+ integer err, ierr
+ character *(80) tmpstr
+
+ integer nfmpi_xstrerror
+ external nfmpi_xstrerror
+
+ ierr = nfmpi_xstrerror( err, tmpstr )
+ nfmpi_strerror = tmpstr
+ end
diff --git a/src/libf90/Makefile.in b/src/libf90/Makefile.in
new file mode 100644
index 0000000..fe9a55e
--- /dev/null
+++ b/src/libf90/Makefile.in
@@ -0,0 +1,84 @@
+#
+# Copyright (C) 2013, Northwestern University and Argonne National Laboratory
+# See COPYRIGHT notice in top-level directory.
+#
+# $Id: Makefile.in 2285 2015-12-30 20:48:25Z wkliao $
+#
+# @configure_input@
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+# generated by configure, so it's in the build dir, not srcdirr
+include ../../macros.make
+
+# F90FLAGS = @FC_DEFINE at MPI_OFFSET_KIND=@SIZEOF_MPI_OFFSET@
+
+# For VPATH build:
+# Add . into search path because api.f90 and nfmpi_constants.f90 are created in
+# the build directory at configure time and they are included in pnetcdf.f90.
+# If NAG compiler is used, $(srcdir) must also be added into search path
+# because NAG does not seem to look for include file in the same directory as
+# the source file.
+INCLUDES = -I. -I$(srcdir)
+
+LIBRARY = ../lib/libpnetcdf.a
+
+PNETCDF_MOD = pnetcdf. at FC_MODEXT@
+ifeq (@UPPER_CASE_MOD@, yes)
+ PNETCDF_MOD = PNETCDF. at FC_MODEXT@
+endif
+
+F90FLAGS += @FC_MODOUT at .
+M4FLAGS += -DINTENTV=@INTENTV@
+
+M4_SRCS = getput_text.m4 \
+ getput_var.m4 \
+ getput_varn.m4 \
+ getput_vard.m4
+
+F90_SRCS = nf90_constants.f90 \
+ overloads.f90 \
+ visibility.f90 \
+ file.f90 \
+ dims.f90 \
+ attributes.f90 \
+ variables.f90 \
+ pnetcdf.f90
+
+SRCS = $(F90_SRCS) $(M4_SRCS:.m4=.f90) \
+ api.f90 nfmpi_constants.f90
+
+LIB_OBJS = pnetcdf.o
+
+PACKING_LIST = $(F90_SRCS) \
+ $(M4_SRCS) \
+ Makefile.in \
+ api.f90.in \
+ nfmpi_constants.f90.in
+
+GARBAGE = $(PNETCDF_MOD) $(M4_SRCS:.m4=.f90)
+DIST_GARBAGE = api.f90 nfmpi_constants.f90
+
+%.mod: %.f90 $(SRCS)
+ $(COMPILE.f90) $<
+
+all: $(LIBRARY)
+
+library $(LIBRARY): $(LIB_OBJS)
+ $(AR) $(ARFLAGS) $(LIBRARY) $(LIB_OBJS)
+ $(RANLIB) $(LIBRARY)
+
+$(LIB_OBJS): $(SRCS)
+
+$(PNETCDF_MOD): $(SRCS)
+
+install: $(PNETCDF_MOD)
+ $(INSTALL) -d -m 755 $(INCDIR)
+ $(INSTALL_DATA) $(PNETCDF_MOD) $(INCDIR)
+
+uninstall:
+ $(RM) -f $(INCDIR)/$(PNETCDF_MOD)
+
+include $(srcdir)/../../rules.make
+
diff --git a/src/libf90/api.f90.in b/src/libf90/api.f90.in
new file mode 100644
index 0000000..a277c0a
--- /dev/null
+++ b/src/libf90/api.f90.in
@@ -0,0 +1,4110 @@
+!
+! Copyright (C) 2013, Northwestern University and Argonne National Laboratory
+! See COPYRIGHT notice in top-level directory.
+!
+! $Id: api.f90.in 2221 2015-12-12 00:39:15Z wkliao $
+!
+
+!
+! miscellaneous subroutines:
+!
+INTERFACE
+ character(LEN=80) FUNCTION nfmpi_inq_libvers()
+ END FUNCTION nfmpi_inq_libvers
+
+ character(LEN=80) FUNCTION nfmpi_strerror(ncerr)
+ INTEGER, INTENT(IN) :: ncerr
+ END FUNCTION nfmpi_strerror
+
+ logical FUNCTION nfmpi_issyserr(ncerr)
+ INTEGER, INTENT(IN) :: ncerr
+ END FUNCTION nfmpi_issyserr
+
+!
+! control subroutines:
+!
+ INTEGER FUNCTION nfmpi_create(mpi_comm, path, cmode, mpi_info, ncid)
+ INTEGER, INTENT(IN) :: mpi_comm
+ CHARACTER(len=*), INTENT(IN) :: path
+ INTEGER, INTENT(IN) :: cmode
+ INTEGER, INTENT(IN) :: mpi_info
+ INTEGER, INTENT(OUT) :: ncid
+ END FUNCTION nfmpi_create
+
+ INTEGER FUNCTION nfmpi_open(mpi_comm, path, mode, mpi_info, ncid)
+ INTEGER, INTENT(IN) :: mpi_comm
+ CHARACTER(len=*), INTENT(IN) :: path
+ INTEGER, INTENT(IN) :: mode
+ INTEGER, INTENT(IN) :: mpi_info
+ INTEGER, INTENT(OUT) :: ncid
+ END FUNCTION nfmpi_open
+
+ INTEGER FUNCTION nfmpi_inq_format(ncid, format)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(OUT) :: format
+ END FUNCTION nfmpi_inq_format
+
+ INTEGER FUNCTION nfmpi_inq_file_format(path, format)
+ CHARACTER(len=*), INTENT(IN) :: path
+ INTEGER, INTENT(OUT) :: format
+ END FUNCTION nfmpi_inq_file_format
+
+ INTEGER FUNCTION nfmpi_inq_file_info(ncid, mpi_info)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(OUT) :: mpi_info
+ END FUNCTION nfmpi_inq_file_info
+
+ INTEGER FUNCTION nfmpi_get_file_info(ncid, mpi_info)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(OUT) :: mpi_info
+ END FUNCTION nfmpi_get_file_info
+
+ INTEGER FUNCTION nfmpi_delete(path, mpi_info)
+ CHARACTER(len=*), INTENT(IN) :: path
+ INTEGER, INTENT(IN) :: mpi_info
+ END FUNCTION nfmpi_delete
+
+ INTEGER FUNCTION nfmpi_enddef(ncid)
+ INTEGER, INTENT(IN) :: ncid
+ END FUNCTION nfmpi_enddef
+
+ INTEGER FUNCTION nfmpi__enddef(ncid, h_minfree, v_align, v_minfree, r_align)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: h_minfree
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: v_align
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: v_minfree
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: r_align
+ END FUNCTION nfmpi__enddef
+
+ INTEGER FUNCTION nfmpi_redef(ncid)
+ INTEGER, INTENT(IN) :: ncid
+ END FUNCTION nfmpi_redef
+
+ INTEGER FUNCTION nfmpi_set_default_format(new_format, old_format)
+ INTEGER, INTENT(IN) :: new_format
+ INTEGER, INTENT(OUT) :: old_format
+ END FUNCTION nfmpi_set_default_format
+
+ INTEGER FUNCTION nfmpi_inq_default_format(default_format)
+ INTEGER, INTENT(OUT) :: default_format
+ END FUNCTION nfmpi_inq_default_format
+
+ INTEGER FUNCTION nfmpi_sync(ncid)
+ INTEGER, INTENT(IN) :: ncid
+ END FUNCTION nfmpi_sync
+
+ INTEGER FUNCTION nfmpi_abort(ncid)
+ INTEGER, INTENT(IN) :: ncid
+ END FUNCTION nfmpi_abort
+
+ INTEGER FUNCTION nfmpi_close(ncid)
+ INTEGER, INTENT(IN) :: ncid
+ END FUNCTION nfmpi_close
+
+ INTEGER FUNCTION nfmpi_set_fill(ncid, fillmode, old_mode)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: fillmode
+ INTEGER, INTENT(OUT) :: old_mode
+ END FUNCTION nfmpi_set_fill
+
+!
+! general inquiry subroutines:
+!
+
+ INTEGER FUNCTION nfmpi_inq(ncid, ndims, nvars, ngatts, unlimdimid)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(OUT) :: ndims
+ INTEGER, INTENT(OUT) :: nvars
+ INTEGER, INTENT(OUT) :: ngatts
+ INTEGER, INTENT(OUT) :: unlimdimid
+ END FUNCTION nfmpi_inq
+
+ INTEGER FUNCTION nfmpi_inq_striping(ncid, striping_size, striping_count)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(OUT) :: striping_size
+ INTEGER, INTENT(OUT) :: striping_count
+ END FUNCTION nfmpi_inq_striping
+
+ INTEGER FUNCTION nfmpi_inq_ndims(ncid, ndims)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(OUT) :: ndims
+ END FUNCTION nfmpi_inq_ndims
+
+ INTEGER FUNCTION nfmpi_inq_nvars(ncid, nvars)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(OUT) :: nvars
+ END FUNCTION nfmpi_inq_nvars
+
+ INTEGER FUNCTION nfmpi_inq_num_rec_vars(ncid, nvars)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(OUT) :: nvars
+ END FUNCTION nfmpi_inq_num_rec_vars
+
+ INTEGER FUNCTION nfmpi_inq_num_fix_vars(ncid, nvars)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(OUT) :: nvars
+ END FUNCTION nfmpi_inq_num_fix_vars
+
+ INTEGER FUNCTION nfmpi_inq_natts(ncid, ngatts)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(OUT) :: ngatts
+ END FUNCTION nfmpi_inq_natts
+
+ INTEGER FUNCTION nfmpi_inq_unlimdim(ncid, unlimdimid)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(OUT) :: unlimdimid
+ END FUNCTION nfmpi_inq_unlimdim
+
+!
+! dimension subroutines:
+!
+
+ INTEGER FUNCTION nfmpi_def_dim(ncid, name, len, dimid)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ CHARACTER(len=*), INTENT(IN) :: name
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: len
+ INTEGER, INTENT(OUT) :: dimid
+ END FUNCTION nfmpi_def_dim
+
+ INTEGER FUNCTION nfmpi_inq_dimid(ncid, name, dimid)
+ INTEGER, INTENT(IN) :: ncid
+ CHARACTER(len=*), INTENT(IN) :: name
+ INTEGER, INTENT(OUT) :: dimid
+ END FUNCTION nfmpi_inq_dimid
+
+ INTEGER FUNCTION nfmpi_inq_dim(ncid, dimid, name, len)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: dimid
+ CHARACTER(len=*), INTENT(OUT) :: name
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(OUT) :: len
+ END FUNCTION nfmpi_inq_dim
+
+ INTEGER FUNCTION nfmpi_inq_dimname(ncid, dimid, name)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: dimid
+ CHARACTER(len=*), INTENT(OUT) :: name
+ END FUNCTION nfmpi_inq_dimname
+
+ INTEGER FUNCTION nfmpi_inq_dimlen(ncid, dimid, len)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: dimid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(OUT) :: len
+ END FUNCTION nfmpi_inq_dimlen
+
+ INTEGER FUNCTION nfmpi_rename_dim(ncid, dimid, name)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: dimid
+ CHARACTER(len=*), INTENT(IN) :: name
+ END FUNCTION nfmpi_rename_dim
+
+!
+! general attribute subroutines:
+!
+
+ INTEGER FUNCTION nfmpi_inq_att(ncid, varid, name, xtype, len)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ CHARACTER(len=*), INTENT(IN) :: name
+ INTEGER, INTENT(OUT) :: xtype
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(OUT) :: len
+ END FUNCTION nfmpi_inq_att
+
+ INTEGER FUNCTION nfmpi_inq_attid(ncid, varid, name, attid)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ CHARACTER(len=*), INTENT(IN) :: name
+ INTEGER, INTENT(OUT) :: attid
+ END FUNCTION nfmpi_inq_attid
+
+ INTEGER FUNCTION nfmpi_inq_atttype(ncid, varid, name, xtype)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ CHARACTER(len=*), INTENT(IN) :: name
+ INTEGER, INTENT(OUT) :: xtype
+ END FUNCTION nfmpi_inq_atttype
+
+ INTEGER FUNCTION nfmpi_inq_attlen(ncid, varid, name, len)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ CHARACTER(len=*), INTENT(IN) :: name
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(OUT) :: len
+ END FUNCTION nfmpi_inq_attlen
+
+ INTEGER FUNCTION nfmpi_inq_attname(ncid, varid, attid, name)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER, INTENT(IN) :: attid
+ CHARACTER(len=*), INTENT(OUT) :: name
+ END FUNCTION nfmpi_inq_attname
+
+ INTEGER FUNCTION nfmpi_copy_att(ncid_in, varid_in, name, ncid_out, varid_out)
+ INTEGER, INTENT(IN) :: ncid_in
+ INTEGER, INTENT(IN) :: varid_in
+ CHARACTER(len=*), INTENT(IN) :: name
+ INTEGER, INTENT(IN) :: ncid_out
+ INTEGER, INTENT(IN) :: varid_out
+ END FUNCTION nfmpi_copy_att
+
+ INTEGER FUNCTION nfmpi_rename_att(ncid, varid, curname, newname)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ CHARACTER(len=*), INTENT(IN) :: curname
+ CHARACTER(len=*), INTENT(IN) :: newname
+ END FUNCTION nfmpi_rename_att
+
+ INTEGER FUNCTION nfmpi_del_att(ncid, varid, name)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ CHARACTER(len=*), INTENT(IN) :: name
+ END FUNCTION nfmpi_del_att
+
+!
+! attribute put/get subroutines:
+!
+
+ INTEGER FUNCTION nfmpi_put_att_text(ncid, varid, name, len, text)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ CHARACTER(len=*), INTENT(IN) :: name
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: len
+ CHARACTER(len=*), INTENT(IN) :: text
+ END FUNCTION nfmpi_put_att_text
+
+ INTEGER FUNCTION nfmpi_get_att_text(ncid, varid, name, text)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ CHARACTER(len=*), INTENT(IN) :: name
+ CHARACTER(len=*), INTENT(OUT) :: text
+ END FUNCTION nfmpi_get_att_text
+
+ INTEGER FUNCTION nfmpi_put_att_int1(ncid, varid, name, xtype, len, i1vals)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: OneByteInt = selected_int_kind(2)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ CHARACTER(len=*), INTENT(IN) :: name
+ INTEGER, INTENT(IN) :: xtype
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: len
+ INTEGER(KIND=OneByteInt), INTENT(IN) :: i1vals(*)
+ END FUNCTION nfmpi_put_att_int1
+
+ INTEGER FUNCTION nfmpi_get_att_int1(ncid, varid, name, i1vals)
+ integer, parameter :: OneByteInt = selected_int_kind(2)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ CHARACTER(len=*), INTENT(IN) :: name
+ INTEGER(KIND=OneByteInt), INTENT(OUT) :: i1vals(*)
+ END FUNCTION nfmpi_get_att_int1
+
+ INTEGER FUNCTION nfmpi_put_att_int2(ncid, varid, name, xtype, len, i2vals)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: TwoByteInt = selected_int_kind(4)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ CHARACTER(len=*), INTENT(IN) :: name
+ INTEGER, INTENT(IN) :: xtype
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: len
+ INTEGER(KIND=TwoByteInt), INTENT(IN) :: i2vals(*)
+ END FUNCTION nfmpi_put_att_int2
+
+ INTEGER FUNCTION nfmpi_get_att_int2(ncid, varid, name, i2vals)
+ integer, parameter :: TwoByteInt = selected_int_kind(4)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ CHARACTER(len=*), INTENT(IN) :: name
+ INTEGER(KIND=TwoByteInt), INTENT(OUT) :: i2vals(*)
+ END FUNCTION nfmpi_get_att_int2
+
+ INTEGER FUNCTION nfmpi_put_att_int(ncid, varid, name, xtype, len, IVALS)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ CHARACTER(len=*), INTENT(IN) :: name
+ INTEGER, INTENT(IN) :: xtype
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: len
+ INTEGER, INTENT(IN) :: ivals(*)
+ END FUNCTION nfmpi_put_att_int
+
+ INTEGER FUNCTION nfmpi_get_att_int(ncid, varid, name, IVALS)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ CHARACTER(len=*), INTENT(IN) :: name
+ INTEGER, INTENT(OUT) :: ivals(*)
+ END FUNCTION nfmpi_get_att_int
+
+ INTEGER FUNCTION nfmpi_put_att_real(ncid, varid, name, xtype, len, RVALS)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ CHARACTER(len=*), INTENT(IN) :: name
+ INTEGER, INTENT(IN) :: xtype
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: len
+ REAL, INTENT(IN) :: rvals(*)
+ END FUNCTION nfmpi_put_att_real
+
+ INTEGER FUNCTION nfmpi_get_att_real(ncid, varid, name, rvals)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ CHARACTER(len=*), INTENT(IN) :: name
+ REAL, INTENT(OUT) :: rvals(*)
+ END FUNCTION nfmpi_get_att_real
+
+ INTEGER FUNCTION nfmpi_put_att_double(ncid, varid, name, xtype, len, dvals)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ CHARACTER(len=*), INTENT(IN) :: name
+ INTEGER, INTENT(IN) :: xtype
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: len
+ DOUBLE PRECISION, INTENT(IN) :: dvals(*)
+ END FUNCTION nfmpi_put_att_double
+
+ INTEGER FUNCTION nfmpi_get_att_double(ncid, varid, name, dvals)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ CHARACTER(len=*), INTENT(IN) :: name
+ DOUBLE PRECISION, INTENT(OUT) :: dvals(*)
+ END FUNCTION nfmpi_get_att_double
+
+ INTEGER FUNCTION nfmpi_put_att_int8(ncid, varid, name, xtype, len, i8vals)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: EightByteInt = selected_int_kind(18)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ CHARACTER(len=*), INTENT(IN) :: name
+ INTEGER, INTENT(IN) :: xtype
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: len
+ INTEGER(KIND=EightByteInt), INTENT(IN) :: i8vals(*)
+ END FUNCTION nfmpi_put_att_int8
+
+ INTEGER FUNCTION nfmpi_get_att_int8(ncid, varid, name, i8vals)
+ integer, parameter :: EightByteInt = selected_int_kind(18)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ CHARACTER(len=*), INTENT(IN) :: name
+ INTEGER(KIND=EightByteInt), INTENT(OUT) :: i8vals(*)
+ END FUNCTION nfmpi_get_att_int8
+
+!
+! independent data mode subroutines:
+!
+ INTEGER FUNCTION nfmpi_begin_indep_data(ncid)
+ INTEGER, INTENT(IN) :: ncid
+ END FUNCTION nfmpi_begin_indep_data
+
+ INTEGER FUNCTION nfmpi_end_indep_data(ncid)
+ INTEGER, INTENT(IN) :: ncid
+ END FUNCTION nfmpi_end_indep_data
+!
+! general variable subroutines:
+!
+
+ INTEGER FUNCTION nfmpi_def_var(ncid, name, datatype, ndims, dimids, varid)
+ INTEGER, INTENT(IN) :: ncid
+ CHARACTER(len=*), INTENT(IN) :: name
+ INTEGER, INTENT(IN) :: datatype
+ INTEGER, INTENT(IN) :: ndims
+ INTEGER, INTENT(IN) :: dimids(ndims)
+ INTEGER, INTENT(OUT) :: varid
+ END FUNCTION nfmpi_def_var
+
+ INTEGER FUNCTION nfmpi_inq_var(ncid, varid, name, datatype, ndims, dimids, natts)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ CHARACTER(len=*), INTENT(OUT) :: name
+ INTEGER, INTENT(OUT) :: datatype
+ INTEGER, INTENT(OUT) :: ndims
+ INTEGER, INTENT(OUT) :: dimids(*)
+ INTEGER, INTENT(OUT) :: natts
+ END FUNCTION nfmpi_inq_var
+
+ INTEGER FUNCTION nfmpi_inq_varid(ncid, name, varid)
+ INTEGER, INTENT(IN) :: ncid
+ CHARACTER(len=*), INTENT(IN) :: name
+ INTEGER, INTENT(OUT) :: varid
+ END FUNCTION nfmpi_inq_varid
+
+ INTEGER FUNCTION nfmpi_inq_varname(ncid, varid, name)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ CHARACTER(len=*), INTENT(OUT) :: name
+ END FUNCTION nfmpi_inq_varname
+
+ INTEGER FUNCTION nfmpi_inq_vartype(ncid, varid, xtype)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER, INTENT(OUT) :: xtype
+ END FUNCTION nfmpi_inq_vartype
+
+ INTEGER FUNCTION nfmpi_inq_varndims(ncid, varid, ndims)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER, INTENT(OUT) :: ndims
+ END FUNCTION nfmpi_inq_varndims
+
+ INTEGER FUNCTION nfmpi_inq_vardimid(ncid, varid, dimids)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER, INTENT(OUT) :: dimids(*)
+ END FUNCTION nfmpi_inq_vardimid
+
+ INTEGER FUNCTION nfmpi_inq_varnatts(ncid, varid, natts)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER, INTENT(OUT) :: natts
+ END FUNCTION nfmpi_inq_varnatts
+
+ INTEGER FUNCTION nfmpi_rename_var(ncid, varid, name)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ CHARACTER(len=*), INTENT(IN) :: name
+ END FUNCTION nfmpi_rename_var
+
+! INTEGER FUNCTION nfmpi_def_var_fill(ncid, varid, no_fill, fill_value)
+! INTEGER, INTENT(IN) :: ncid
+! INTEGER, INTENT(IN) :: varid
+! INTEGER, INTENT(IN) :: no_fill
+! <type>, INTENT(IN) :: fill_value
+! END FUNCTION nfmpi_def_var_fill
+
+! INTEGER FUNCTION nfmpi_inq_var_fill(ncid, varid, no_fill, fill_value)
+! INTEGER, INTENT(IN) :: ncid
+! INTEGER, INTENT(IN) :: varid
+! INTEGER, INTENT(OUT) :: no_fill
+! <type>, INTENT(OUT) :: fill_value
+! END FUNCTION nfmpi_inq_var_fill
+
+ INTEGER FUNCTION nfmpi_fill_var_rec(ncid, varid, recno)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: recno
+ END FUNCTION nfmpi_fill_var_rec
+
+!
+! entire variable put/get subroutines:
+!
+
+!
+! flexible APIs, not ready yet for Fortran 77
+!
+! INTEGER FUNCTION nfmpi_put_var(ncid, varid, buf, bufcount, datatype)
+! INTEGER, INTENT(IN) :: ncid
+! INTEGER, INTENT(IN) :: varid
+! <type>, INTENT(IN) :: buf(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: bufcount
+! INTEGER, INTENT(IN) :: datatype
+! END FUNCTION nfmpi_put_var
+
+! INTEGER FUNCTION nfmpi_get_var(ncid, varid, buf, bufcount, datatype)
+! INTEGER, INTENT(IN) :: ncid
+! INTEGER, INTENT(IN) :: varid
+! <type>, INTENT(OUT) :: buf(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: bufcount
+! INTEGER, INTENT(IN) :: datatype
+! END FUNCTION nfmpi_get_var
+
+! INTEGER FUNCTION nfmpi_get_var_all (ncid, varid, buf, bufcount, datatype)
+! INTEGER, INTENT(IN) :: ncid
+! INTEGER, INTENT(IN) :: varid
+! <type>, INTENT(OUT) :: buf(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: bufcount
+! INTEGER, INTENT(IN) :: datatype
+! END FUNCTION nfmpi_get_var_all
+
+ INTEGER FUNCTION nfmpi_put_var_text(ncid, varid, text)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ CHARACTER(len=*), INTENT(IN) :: text
+ END FUNCTION nfmpi_put_var_text
+
+ INTEGER FUNCTION nfmpi_get_var_text(ncid, varid, text)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ CHARACTER(len=*), INTENT(OUT) :: text
+ END FUNCTION nfmpi_get_var_text
+
+ INTEGER FUNCTION nfmpi_get_var_text_all(ncid, varid, text)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ CHARACTER(len=*), INTENT(OUT) :: text
+ END FUNCTION nfmpi_get_var_text_all
+
+ INTEGER FUNCTION nfmpi_put_var_int1(ncid, varid, i1vals)
+ integer, parameter :: OneByteInt = selected_int_kind(2)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=OneByteInt), INTENT(IN) :: i1vals(*)
+ END FUNCTION nfmpi_put_var_int1
+
+ INTEGER FUNCTION nfmpi_get_var_int1(ncid, varid, i1vals)
+ integer, parameter :: OneByteInt = selected_int_kind(2)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=OneByteInt), INTENT(OUT) :: i1vals(*)
+ END FUNCTION nfmpi_get_var_int1
+
+ INTEGER FUNCTION nfmpi_get_var_int1_all(ncid, varid, i1vals)
+ integer, parameter :: OneByteInt = selected_int_kind(2)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=OneByteInt), INTENT(OUT) :: i1vals(*)
+ END FUNCTION nfmpi_get_var_int1_all
+
+ INTEGER FUNCTION nfmpi_put_var_int2(ncid, varid, i2vals)
+ integer, parameter :: TwoByteInt = selected_int_kind(4)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=TwoByteInt), INTENT(@INTENTV@) :: i2vals(*)
+ END FUNCTION nfmpi_put_var_int2
+
+ INTEGER FUNCTION nfmpi_get_var_int2(ncid, varid, i2vals)
+ integer, parameter :: TwoByteInt = selected_int_kind(4)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=TwoByteInt), INTENT(OUT) :: i2vals(*)
+ END FUNCTION nfmpi_get_var_int2
+
+ INTEGER FUNCTION nfmpi_get_var_int2_all(ncid, varid, i2vals)
+ integer, parameter :: TwoByteInt = selected_int_kind(4)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=TwoByteInt), INTENT(OUT) :: i2vals(*)
+ END FUNCTION nfmpi_get_var_int2_all
+
+ INTEGER FUNCTION nfmpi_put_var_int(ncid, varid, ivals)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER, INTENT(@INTENTV@) :: ivals(*)
+ END FUNCTION nfmpi_put_var_int
+
+ INTEGER FUNCTION nfmpi_get_var_int(ncid, varid, ivals)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER, INTENT(OUT) :: ivals(*)
+ END FUNCTION nfmpi_get_var_int
+
+ INTEGER FUNCTION nfmpi_get_var_int_all(ncid, varid, ivals)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER, INTENT(OUT) :: ivals(*)
+ END FUNCTION nfmpi_get_var_int_all
+
+ INTEGER FUNCTION nfmpi_put_var_real(ncid, varid, rvals)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ REAL, INTENT(@INTENTV@) :: rvals(*)
+ END FUNCTION nfmpi_put_var_real
+
+ INTEGER FUNCTION nfmpi_get_var_real(ncid, varid, rvals)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ REAL, INTENT(OUT) :: rvals(*)
+ END FUNCTION nfmpi_get_var_real
+
+ INTEGER FUNCTION nfmpi_get_var_real_all(ncid, varid, rvals)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ REAL, INTENT(OUT) :: rvals(*)
+ END FUNCTION nfmpi_get_var_real_all
+
+ INTEGER FUNCTION nfmpi_put_var_double(ncid, varid, dvals)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ DOUBLE PRECISION, INTENT(@INTENTV@) :: dvals(*)
+ END FUNCTION nfmpi_put_var_double
+
+ INTEGER FUNCTION nfmpi_get_var_double(ncid, varid, dvals)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ DOUBLE PRECISION, INTENT(OUT) :: dvals(*)
+ END FUNCTION nfmpi_get_var_double
+
+ INTEGER FUNCTION nfmpi_get_var_double_all(ncid, varid, dvals)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ DOUBLE PRECISION, INTENT(OUT) :: dvals(*)
+ END FUNCTION nfmpi_get_var_double_all
+
+ INTEGER FUNCTION nfmpi_put_var_int8(ncid, varid, i8vals)
+ integer, parameter :: EightByteInt = selected_int_kind(18)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=EightByteInt), INTENT(@INTENTV@) :: i8vals(*)
+ END FUNCTION nfmpi_put_var_int8
+
+ INTEGER FUNCTION nfmpi_get_var_int8(ncid, varid, i8vals)
+ integer, parameter :: EightByteInt = selected_int_kind(18)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=EightByteInt), INTENT(OUT) :: i8vals(*)
+ END FUNCTION nfmpi_get_var_int8
+
+ INTEGER FUNCTION nfmpi_get_var_int8_all(ncid, varid, i8vals)
+ integer, parameter :: EightByteInt = selected_int_kind(18)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=EightByteInt), INTENT(OUT) :: i8vals(*)
+ END FUNCTION nfmpi_get_var_int8_all
+
+!
+! single variable put/get subroutines:
+!
+
+!
+! flexible APIs, not ready yet for Fortran 77
+!
+! INTEGER FUNCTION nfmpi_put_var1(ncid, varid, index, buf, bufcount, datatype)
+! INTEGER, INTENT(IN) :: ncid
+! INTEGER, INTENT(IN) :: varid
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: index(*)
+! <type>, INTENT(IN) :: buf(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: bufcount
+! INTEGER, INTENT(IN) :: datatype
+! END FUNCTION nfmpi_put_var1
+
+! INTEGER FUNCTION nfmpi_put_var1_all(ncid, varid, index, buf, bufcount, datatype)
+! INTEGER, INTENT(IN) :: ncid
+! INTEGER, INTENT(IN) :: varid
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: index(*)
+! <type>, INTENT(IN) :: buf(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: bufcount
+! INTEGER, INTENT(IN) :: datatype
+! END FUNCTION nfmpi_put_var1_all
+
+! INTEGER FUNCTION nfmpi_get_var1(ncid, varid, index, buf, bufcount, datatype)
+! INTEGER, INTENT(IN) :: ncid
+! INTEGER, INTENT(IN) :: varid
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: index(*)
+! <type>, INTENT(OUT) :: buf(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: bufcount
+! INTEGER, INTENT(IN) :: datatype
+! END FUNCTION nfmpi_get_var1
+
+! INTEGER FUNCTION nfmpi_get_var1_all(ncid, varid, index, buf, bufcount, datatype)
+! INTEGER, INTENT(IN) :: ncid
+! INTEGER, INTENT(IN) :: varid
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: index(*)
+! <type>, INTENT(OUT) :: buf(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: bufcount
+! INTEGER, INTENT(IN) :: datatype
+! END FUNCTION nfmpi_get_var1_all
+
+ INTEGER FUNCTION nfmpi_put_var1_text(ncid, varid, index, text)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: index(*)
+ CHARACTER, INTENT(IN) :: text
+ END FUNCTION nfmpi_put_var1_text
+
+ INTEGER FUNCTION nfmpi_put_var1_text_all(ncid, varid, index, text)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: index(*)
+ CHARACTER, INTENT(IN) :: text
+ END FUNCTION nfmpi_put_var1_text_all
+
+ INTEGER FUNCTION nfmpi_get_var1_text(ncid, varid, index, text)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: index(*)
+ CHARACTER, INTENT(OUT) :: text
+ END FUNCTION nfmpi_get_var1_text
+
+ INTEGER FUNCTION nfmpi_get_var1_text_all(ncid, varid, index, text)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: index(*)
+ CHARACTER, INTENT(OUT) :: text
+ END FUNCTION nfmpi_get_var1_text_all
+
+ INTEGER FUNCTION nfmpi_put_var1_int1(ncid, varid, index, i1val)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: OneByteInt = selected_int_kind(2)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: index(*)
+ INTEGER(KIND=OneByteInt), INTENT(IN) :: i1val
+ END FUNCTION nfmpi_put_var1_int1
+
+ INTEGER FUNCTION nfmpi_put_var1_int1_all(ncid, varid, index, i1val)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: OneByteInt = selected_int_kind(2)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: index(*)
+ INTEGER(KIND=OneByteInt), INTENT(IN) :: i1val
+ END FUNCTION nfmpi_put_var1_int1_all
+
+ INTEGER FUNCTION nfmpi_get_var1_int1(ncid, varid, index, i1val)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: OneByteInt = selected_int_kind(2)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: index(*)
+ INTEGER(KIND=OneByteInt), INTENT(OUT) :: i1val
+ END FUNCTION nfmpi_get_var1_int1
+
+ INTEGER FUNCTION nfmpi_get_var1_int1_all(ncid, varid, index, i1val)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: OneByteInt = selected_int_kind(2)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: index(*)
+ INTEGER(KIND=OneByteInt), INTENT(OUT) :: i1val
+ END FUNCTION nfmpi_get_var1_int1_all
+
+ INTEGER FUNCTION nfmpi_put_var1_int2(ncid, varid, index, i2val)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: TwoByteInt = selected_int_kind(4)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: index(*)
+ INTEGER(KIND=TwoByteInt), INTENT(@INTENTV@) :: i2val
+ END FUNCTION nfmpi_put_var1_int2
+
+ INTEGER FUNCTION nfmpi_put_var1_int2_all(ncid, varid, index, i2val)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: TwoByteInt = selected_int_kind(4)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: index(*)
+ INTEGER(KIND=TwoByteInt), INTENT(@INTENTV@) :: i2val
+ END FUNCTION nfmpi_put_var1_int2_all
+
+ INTEGER FUNCTION nfmpi_get_var1_int2(ncid, varid, index, i2val)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: TwoByteInt = selected_int_kind(4)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: index(*)
+ INTEGER(KIND=TwoByteInt), INTENT(OUT) :: i2val
+ END FUNCTION nfmpi_get_var1_int2
+
+ INTEGER FUNCTION nfmpi_get_var1_int2_all(ncid, varid, index, i2val)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: TwoByteInt = selected_int_kind(4)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: index(*)
+ INTEGER(KIND=TwoByteInt), INTENT(OUT) :: i2val
+ END FUNCTION nfmpi_get_var1_int2_all
+
+ INTEGER FUNCTION nfmpi_put_var1_int(ncid, varid, index, ival)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: index(*)
+ INTEGER, INTENT(@INTENTV@) :: ival
+ END FUNCTION nfmpi_put_var1_int
+
+ INTEGER FUNCTION nfmpi_put_var1_int_all(ncid, varid, index, ival)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: index(*)
+ INTEGER, INTENT(@INTENTV@) :: ival
+ END FUNCTION nfmpi_put_var1_int_all
+
+ INTEGER FUNCTION nfmpi_get_var1_int(ncid, varid, index, ival)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: index(*)
+ INTEGER, INTENT(OUT) :: ival
+ END FUNCTION nfmpi_get_var1_int
+
+ INTEGER FUNCTION nfmpi_get_var1_int_all(ncid, varid, index, ival)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: index(*)
+ INTEGER, INTENT(OUT) :: ival
+ END FUNCTION nfmpi_get_var1_int_all
+
+ INTEGER FUNCTION nfmpi_put_var1_real(ncid, varid, index, rval)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: index(*)
+ REAL, INTENT(@INTENTV@) :: rval
+ END FUNCTION nfmpi_put_var1_real
+
+ INTEGER FUNCTION nfmpi_put_var1_real_all(ncid, varid, index, rval)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: index(*)
+ REAL, INTENT(@INTENTV@) :: rval
+ END FUNCTION nfmpi_put_var1_real_all
+
+ INTEGER FUNCTION nfmpi_get_var1_real(ncid, varid, index, rval)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: index(*)
+ REAL, INTENT(OUT) :: rval
+ END FUNCTION nfmpi_get_var1_real
+
+ INTEGER FUNCTION nfmpi_get_var1_real_all(ncid, varid, index, rval)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: index(*)
+ REAL, INTENT(OUT) :: rval
+ END FUNCTION nfmpi_get_var1_real_all
+
+ INTEGER FUNCTION nfmpi_put_var1_double(ncid, varid, index, dval)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: index(*)
+ DOUBLE PRECISION, INTENT(@INTENTV@) :: dval
+ END FUNCTION nfmpi_put_var1_double
+
+ INTEGER FUNCTION nfmpi_put_var1_double_all(ncid, varid, index, dval)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: index(*)
+ DOUBLE PRECISION, INTENT(@INTENTV@) :: dval
+ END FUNCTION nfmpi_put_var1_double_all
+
+ INTEGER FUNCTION nfmpi_get_var1_double(ncid, varid, index, dval)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: index(*)
+ DOUBLE PRECISION, INTENT(OUT) :: dval
+ END FUNCTION nfmpi_get_var1_double
+
+ INTEGER FUNCTION nfmpi_get_var1_double_all(ncid, varid, index, dval)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: index(*)
+ DOUBLE PRECISION, INTENT(OUT) :: dval
+ END FUNCTION nfmpi_get_var1_double_all
+
+ INTEGER FUNCTION nfmpi_put_var1_int8(ncid, varid, index, i8val)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: EightByteInt = selected_int_kind(18)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: index(*)
+ INTEGER(KIND=EightByteInt), INTENT(@INTENTV@) :: i8val
+ END FUNCTION nfmpi_put_var1_int8
+
+ INTEGER FUNCTION nfmpi_put_var1_int8_all(ncid, varid, index, i8val)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: EightByteInt = selected_int_kind(18)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: index(*)
+ INTEGER(KIND=EightByteInt), INTENT(@INTENTV@) :: i8val
+ END FUNCTION nfmpi_put_var1_int8_all
+
+ INTEGER FUNCTION nfmpi_get_var1_int8(ncid, varid, index, i8val)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: EightByteInt = selected_int_kind(18)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: index(*)
+ INTEGER(KIND=EightByteInt), INTENT(OUT) :: i8val
+ END FUNCTION nfmpi_get_var1_int8
+
+ INTEGER FUNCTION nfmpi_get_var1_int8_all(ncid, varid, index, i8val)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: EightByteInt = selected_int_kind(18)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: index(*)
+ INTEGER(KIND=EightByteInt), INTENT(OUT) :: i8val
+ END FUNCTION nfmpi_get_var1_int8_all
+
+!
+! variable array put/get subroutines:
+!
+
+!
+! flexible APIs, not ready yet for Fortran 77
+!
+! INTEGER FUNCTION nfmpi_put_vara(ncid, varid, start, count, buf, bufcount, datatype)
+! INTEGER, INTENT(IN) :: ncid
+! INTEGER, INTENT(IN) :: varid
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+! <type>, INTENT(IN) :: buf(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: bufcount
+! INTEGER, INTENT(IN) :: datatype
+! END FUNCTION nfmpi_put_vara
+
+! INTEGER FUNCTION nfmpi_put_vara_all(ncid, varid, start, count, buf, bufcount, datatype)
+! INTEGER, INTENT(IN) :: ncid
+! INTEGER, INTENT(IN) :: varid
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+! <type>, INTENT(IN) :: buf(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: bufcount
+! INTEGER, INTENT(IN) :: datatype
+! END FUNCTION nfmpi_put_vara_all
+
+! INTEGER FUNCTION nfmpi_get_vara(ncid, varid, start, count, buf, bufcount, datatype)
+! INTEGER, INTENT(IN) :: ncid
+! INTEGER, INTENT(IN) :: varid
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+! <type>, INTENT(OUT) :: buf(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: bufcount
+! INTEGER, INTENT(IN) :: datatype
+! END FUNCTION nfmpi_get_vara
+
+! INTEGER FUNCTION nfmpi_get_vara_all (ncid, varid, start, count, buf, bufcount, datatype)
+! INTEGER, INTENT(IN) :: ncid
+! INTEGER, INTENT(IN) :: varid
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+! <type>, INTENT(OUT) :: buf(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: bufcount
+! INTEGER, INTENT(IN) :: datatype
+! END FUNCTION nfmpi_get_vara_all
+
+ INTEGER FUNCTION nfmpi_put_vara_text(ncid, varid, start, count, text)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ CHARACTER(len=*), INTENT(IN) :: text
+ END FUNCTION nfmpi_put_vara_text
+
+ INTEGER FUNCTION nfmpi_put_vara_text_all(ncid, varid, start, count, text)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ CHARACTER(len=*), INTENT(IN) :: text
+ END FUNCTION nfmpi_put_vara_text_all
+
+ INTEGER FUNCTION nfmpi_get_vara_text(ncid, varid, start, count, text)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ CHARACTER(len=*), INTENT(OUT) :: text
+ END FUNCTION nfmpi_get_vara_text
+
+ INTEGER FUNCTION nfmpi_get_vara_text_all(ncid, varid, start, count, text)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ CHARACTER(len=*), INTENT(OUT) :: text
+ END FUNCTION nfmpi_get_vara_text_all
+
+ INTEGER FUNCTION nfmpi_put_vara_int1(ncid, varid, start, count, i1vals)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: OneByteInt = selected_int_kind(2)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=OneByteInt), INTENT(IN) :: i1vals(*)
+ END FUNCTION nfmpi_put_vara_int1
+
+ INTEGER FUNCTION nfmpi_put_vara_int1_all(ncid, varid, start, count, i1vals)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: OneByteInt = selected_int_kind(2)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=OneByteInt), INTENT(IN) :: i1vals(*)
+ END FUNCTION nfmpi_put_vara_int1_all
+
+ INTEGER FUNCTION nfmpi_get_vara_int1(ncid, varid, start, count, i1vals)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: OneByteInt = selected_int_kind(2)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=OneByteInt), INTENT(OUT) :: i1vals(*)
+ END FUNCTION nfmpi_get_vara_int1
+
+ INTEGER FUNCTION nfmpi_get_vara_int1_all(ncid, varid, start, count, i1vals)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: OneByteInt = selected_int_kind(2)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=OneByteInt), INTENT(OUT) :: i1vals(*)
+ END FUNCTION nfmpi_get_vara_int1_all
+
+ INTEGER FUNCTION nfmpi_put_vara_int2(ncid, varid, start, count, i2vals)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: TwoByteInt = selected_int_kind(4)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=TwoByteInt), INTENT(@INTENTV@) :: i2vals(*)
+ END FUNCTION nfmpi_put_vara_int2
+
+ INTEGER FUNCTION nfmpi_put_vara_int2_all(ncid, varid, start, count, i2vals)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: TwoByteInt = selected_int_kind(4)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=TwoByteInt), INTENT(@INTENTV@) :: i2vals(*)
+ END FUNCTION nfmpi_put_vara_int2_all
+
+ INTEGER FUNCTION nfmpi_get_vara_int2(ncid, varid, start, count, i2vals)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: TwoByteInt = selected_int_kind(4)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=TwoByteInt), INTENT(OUT) :: i2vals(*)
+ END FUNCTION nfmpi_get_vara_int2
+
+ INTEGER FUNCTION nfmpi_get_vara_int2_all(ncid, varid, start, count, i2vals)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: TwoByteInt = selected_int_kind(4)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=TwoByteInt), INTENT(OUT) :: i2vals(*)
+ END FUNCTION nfmpi_get_vara_int2_all
+
+ INTEGER FUNCTION nfmpi_put_vara_int(ncid, varid, start, count, ivals)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER, INTENT(@INTENTV@) :: ivals(*)
+ END FUNCTION nfmpi_put_vara_int
+
+ INTEGER FUNCTION nfmpi_put_vara_int_all(ncid, varid, start, count, ivals)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER, INTENT(@INTENTV@) :: ivals(*)
+ END FUNCTION nfmpi_put_vara_int_all
+
+ INTEGER FUNCTION nfmpi_get_vara_int(ncid, varid, start, count, ivals)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER, INTENT(OUT) :: ivals(*)
+ END FUNCTION nfmpi_get_vara_int
+
+ INTEGER FUNCTION nfmpi_get_vara_int_all(ncid, varid, start, count, ivals)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER, INTENT(OUT) :: ivals(*)
+ END FUNCTION nfmpi_get_vara_int_all
+
+ INTEGER FUNCTION nfmpi_put_vara_real(ncid, varid, start, count, rvals)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ REAL, INTENT(@INTENTV@) :: rvals(*)
+ END FUNCTION nfmpi_put_vara_real
+
+ INTEGER FUNCTION nfmpi_put_vara_real_all(ncid, varid, start, count, rvals)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ REAL, INTENT(@INTENTV@) :: rvals(*)
+ END FUNCTION nfmpi_put_vara_real_all
+
+ INTEGER FUNCTION nfmpi_get_vara_real(ncid, varid, start, count, rvals)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ REAL, INTENT(OUT) :: rvals(*)
+ END FUNCTION nfmpi_get_vara_real
+
+ INTEGER FUNCTION nfmpi_get_vara_real_all(ncid, varid, start, count, rvals)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ REAL, INTENT(OUT) :: rvals(*)
+ END FUNCTION nfmpi_get_vara_real_all
+
+ INTEGER FUNCTION nfmpi_put_vara_double(ncid, varid, start, count, dvals)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ DOUBLE PRECISION, INTENT(@INTENTV@) :: dvals(*)
+ END FUNCTION nfmpi_put_vara_double
+
+ INTEGER FUNCTION nfmpi_put_vara_double_all(ncid, varid, start, count, dvals)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ DOUBLE PRECISION, INTENT(@INTENTV@) :: dvals(*)
+ END FUNCTION nfmpi_put_vara_double_all
+
+ INTEGER FUNCTION nfmpi_get_vara_double(ncid, varid, start, count, dvals)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ DOUBLE PRECISION, INTENT(OUT) :: dvals(*)
+ END FUNCTION nfmpi_get_vara_double
+
+ INTEGER FUNCTION nfmpi_get_vara_double_all(ncid, varid, start, count, dvals)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ DOUBLE PRECISION, INTENT(OUT) :: dvals(*)
+ END FUNCTION nfmpi_get_vara_double_all
+
+ INTEGER FUNCTION nfmpi_put_vara_int8(ncid, varid, start, count, i8vals)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: EightByteInt = selected_int_kind(18)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=EightByteInt), INTENT(@INTENTV@) :: i8vals(*)
+ END FUNCTION nfmpi_put_vara_int8
+
+ INTEGER FUNCTION nfmpi_put_vara_int8_all(ncid, varid, start, count, i8vals)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: EightByteInt = selected_int_kind(18)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=EightByteInt), INTENT(@INTENTV@) :: i8vals(*)
+ END FUNCTION nfmpi_put_vara_int8_all
+
+ INTEGER FUNCTION nfmpi_get_vara_int8(ncid, varid, start, count, i8vals)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: EightByteInt = selected_int_kind(18)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=EightByteInt), INTENT(OUT) :: i8vals(*)
+ END FUNCTION nfmpi_get_vara_int8
+
+ INTEGER FUNCTION nfmpi_get_vara_int8_all(ncid, varid, start, count, i8vals)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: EightByteInt = selected_int_kind(18)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=EightByteInt), INTENT(OUT) :: i8vals(*)
+ END FUNCTION nfmpi_get_vara_int8_all
+
+!
+! strided variable put/get subroutines:
+!
+
+!
+! flexible APIs, not ready yet for Fortran 77
+!
+! INTEGER FUNCTION nfmpi_put_vars(ncid, varid, start, count, stride, buf, bufcount, datatype)
+! INTEGER, INTENT(IN) :: ncid
+! INTEGER, INTENT(IN) :: varid
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+! <type>, INTENT(IN) :: buf(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: bufcount
+! INTEGER, INTENT(IN) :: datatype
+! END FUNCTION nfmpi_put_vars
+
+! INTEGER FUNCTION nfmpi_put_vars_all(ncid, varid, start, count, stride, buf, bufcount, datatype)
+! INTEGER, INTENT(IN) :: ncid
+! INTEGER, INTENT(IN) :: varid
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+! <type>, INTENT(IN) :: buf(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: bufcount
+! INTEGER, INTENT(IN) :: datatype
+! END FUNCTION nfmpi_put_vars_all
+
+! INTEGER FUNCTION nfmpi_get_vars(ncid, varid, start, count, stride, buf, bufcount, datatype)
+! INTEGER, INTENT(IN) :: ncid
+! INTEGER, INTENT(IN) :: varid
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+! <type>, INTENT(OUT) :: buf(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: bufcount
+! INTEGER, INTENT(IN) :: datatype
+! END FUNCTION nfmpi_get_vars
+
+! INTEGER FUNCTION nfmpi_get_vars_all(ncid, varid, start, count, stride, buf, bufcount, datatype)
+! INTEGER, INTENT(IN) :: ncid
+! INTEGER, INTENT(IN) :: varid
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+! <type>, INTENT(OUT) :: buf(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: bufcount
+! INTEGER, INTENT(IN) :: datatype
+! END FUNCTION nfmpi_get_vars_all
+
+ INTEGER FUNCTION nfmpi_put_vars_text(ncid, varid, start, count, stride, text)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+ CHARACTER(len=*), INTENT(IN) :: text
+ END FUNCTION nfmpi_put_vars_text
+
+ INTEGER FUNCTION nfmpi_put_vars_text_all(ncid, varid, start, count, stride, text)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+ CHARACTER(len=*), INTENT(IN) :: text
+ END FUNCTION nfmpi_put_vars_text_all
+
+ INTEGER FUNCTION nfmpi_get_vars_text(ncid, varid, start, count, stride, text)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+ CHARACTER(len=*), INTENT(OUT) :: text
+ END FUNCTION nfmpi_get_vars_text
+
+ INTEGER FUNCTION nfmpi_get_vars_text_all(ncid, varid, start, count, stride, text)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+ CHARACTER(len=*), INTENT(OUT) :: text
+ END FUNCTION nfmpi_get_vars_text_all
+
+ INTEGER FUNCTION nfmpi_put_vars_int1(ncid, varid, start, count, stride, i1vals)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: OneByteInt = selected_int_kind(2)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+ INTEGER(KIND=OneByteInt), INTENT(IN) :: i1vals(*)
+ END FUNCTION nfmpi_put_vars_int1
+
+ INTEGER FUNCTION nfmpi_put_vars_int1_all(ncid, varid, start, count, stride, i1vals)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: OneByteInt = selected_int_kind(2)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+ INTEGER(KIND=OneByteInt), INTENT(IN) :: i1vals(*)
+ END FUNCTION nfmpi_put_vars_int1_all
+
+ INTEGER FUNCTION nfmpi_get_vars_int1(ncid, varid, start, count, stride, i1vals)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: OneByteInt = selected_int_kind(2)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+ INTEGER(KIND=OneByteInt), INTENT(OUT) :: i1vals(*)
+ END FUNCTION nfmpi_get_vars_int1
+
+ INTEGER FUNCTION nfmpi_get_vars_int1_all(ncid, varid, start, count, stride, i1vals)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: OneByteInt = selected_int_kind(2)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+ INTEGER(KIND=OneByteInt), INTENT(OUT) :: i1vals(*)
+ END FUNCTION nfmpi_get_vars_int1_all
+
+ INTEGER FUNCTION nfmpi_put_vars_int2(ncid, varid, start, count, stride, i2vals)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: TwoByteInt = selected_int_kind(4)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+ INTEGER(KIND=TwoByteInt), INTENT(@INTENTV@) :: i2vals(*)
+ END FUNCTION nfmpi_put_vars_int2
+
+ INTEGER FUNCTION nfmpi_put_vars_int2_all(ncid, varid, start, count, stride, i2vals)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: TwoByteInt = selected_int_kind(4)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+ INTEGER(KIND=TwoByteInt), INTENT(@INTENTV@) :: i2vals(*)
+ END FUNCTION nfmpi_put_vars_int2_all
+
+ INTEGER FUNCTION nfmpi_get_vars_int2(ncid, varid, start, count, stride, i2vals)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: TwoByteInt = selected_int_kind(4)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+ INTEGER(KIND=TwoByteInt), INTENT(OUT) :: i2vals(*)
+ END FUNCTION nfmpi_get_vars_int2
+
+ INTEGER FUNCTION nfmpi_get_vars_int2_all(ncid, varid, start, count, stride, i2vals)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: TwoByteInt = selected_int_kind(4)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+ INTEGER(KIND=TwoByteInt), INTENT(OUT) :: i2vals(*)
+ END FUNCTION nfmpi_get_vars_int2_all
+
+ INTEGER FUNCTION nfmpi_put_vars_int(ncid, varid, start, count, stride, ivals)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+ INTEGER, INTENT(@INTENTV@) :: ivals(*)
+ END FUNCTION nfmpi_put_vars_int
+
+ INTEGER FUNCTION nfmpi_put_vars_int_all(ncid, varid, start, count, stride, ivals)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+ INTEGER, INTENT(@INTENTV@) :: ivals(*)
+ END FUNCTION nfmpi_put_vars_int_all
+
+ INTEGER FUNCTION nfmpi_get_vars_int(ncid, varid, start, count, stride, ivals)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+ INTEGER, INTENT(OUT) :: ivals(*)
+ END FUNCTION nfmpi_get_vars_int
+
+ INTEGER FUNCTION nfmpi_get_vars_int_all(ncid, varid, start, count, stride, ivals)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+ INTEGER, INTENT(OUT) :: ivals(*)
+ END FUNCTION nfmpi_get_vars_int_all
+
+ INTEGER FUNCTION nfmpi_put_vars_real(ncid, varid, start, count, stride, rvals)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+ REAL, INTENT(@INTENTV@) :: rvals(*)
+ END FUNCTION nfmpi_put_vars_real
+
+ INTEGER FUNCTION nfmpi_put_vars_real_all(ncid, varid, start, count, stride, rvals)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+ REAL, INTENT(@INTENTV@) :: rvals(*)
+ END FUNCTION nfmpi_put_vars_real_all
+
+ INTEGER FUNCTION nfmpi_get_vars_real(ncid, varid, start, count, stride, rvals)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+ REAL, INTENT(OUT) :: rvals(*)
+ END FUNCTION nfmpi_get_vars_real
+
+ INTEGER FUNCTION nfmpi_get_vars_real_all(ncid, varid, start, count, stride, rvals)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+ REAL, INTENT(OUT) :: rvals(*)
+ END FUNCTION nfmpi_get_vars_real_all
+
+ INTEGER FUNCTION nfmpi_put_vars_double(ncid, varid, start, count, stride, dvals)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+ DOUBLE PRECISION, INTENT(@INTENTV@) :: dvals(*)
+ END FUNCTION nfmpi_put_vars_double
+
+ INTEGER FUNCTION nfmpi_put_vars_double_all(ncid, varid, start, count, stride, dvals)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+ DOUBLE PRECISION, INTENT(@INTENTV@) :: dvals(*)
+ END FUNCTION nfmpi_put_vars_double_all
+
+ INTEGER FUNCTION nfmpi_get_vars_double(ncid, varid, start, count, stride, dvals)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+ DOUBLE PRECISION, INTENT(OUT) :: dvals(*)
+ END FUNCTION nfmpi_get_vars_double
+
+ INTEGER FUNCTION nfmpi_get_vars_double_all(ncid, varid, start, count, stride, dvals)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+ DOUBLE PRECISION, INTENT(OUT) :: dvals(*)
+ END FUNCTION nfmpi_get_vars_double_all
+
+ INTEGER FUNCTION nfmpi_put_vars_int8(ncid, varid, start, count, stride, i8vals)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: EightByteInt = selected_int_kind(18)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+ INTEGER(KIND=EightByteInt), INTENT(@INTENTV@) :: i8vals(*)
+ END FUNCTION nfmpi_put_vars_int8
+
+ INTEGER FUNCTION nfmpi_put_vars_int8_all(ncid, varid, start, count, stride, i8vals)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: EightByteInt = selected_int_kind(18)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+ INTEGER(KIND=EightByteInt), INTENT(@INTENTV@) :: i8vals(*)
+ END FUNCTION nfmpi_put_vars_int8_all
+
+ INTEGER FUNCTION nfmpi_get_vars_int8(ncid, varid, start, count, stride, i8vals)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: EightByteInt = selected_int_kind(18)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+ INTEGER(KIND=EightByteInt), INTENT(OUT) :: i8vals(*)
+ END FUNCTION nfmpi_get_vars_int8
+
+ INTEGER FUNCTION nfmpi_get_vars_int8_all(ncid, varid, start, count, stride, i8vals)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: EightByteInt = selected_int_kind(18)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+ INTEGER(KIND=EightByteInt), INTENT(OUT) :: i8vals(*)
+ END FUNCTION nfmpi_get_vars_int8_all
+
+!
+! mapped variable put/get subroutines:
+!
+
+!
+! flexible APIs, not ready yet for Fortran 77
+!
+! INTEGER FUNCTION nfmpi_put_varm(ncid, varid, start, count, stride, imap, buf, bufcount, datatype)
+! INTEGER, INTENT(IN) :: ncid
+! INTEGER, INTENT(IN) :: varid
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: imap(*)
+! <type>, INTENT(IN) :: buf(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: bufcount
+! INTEGER, INTENT(IN) :: datatype
+! END FUNCTION nfmpi_put_varm
+
+! INTEGER FUNCTION nfmpi_put_varm_all(ncid, varid, start, count, stride, imap, buf, bufcount, datatype)
+! INTEGER, INTENT(IN) :: ncid
+! INTEGER, INTENT(IN) :: varid
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: imap(*)
+! <type>, INTENT(IN) :: buf(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: bufcount
+! INTEGER, INTENT(IN) :: datatype
+! END FUNCTION nfmpi_put_varm_all
+
+! INTEGER FUNCTION nfmpi_get_varm(ncid, varid, start, count, stride, imap, buf, bufcount, datatype)
+! INTEGER, INTENT(IN) :: ncid
+! INTEGER, INTENT(IN) :: varid
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: imap(*)
+! <type>, INTENT(OUT) :: buf(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: bufcount
+! INTEGER, INTENT(IN) :: datatype
+! END FUNCTION nfmpi_get_varm
+
+! INTEGER FUNCTION nfmpi_get_varm_all(ncid, varid, start, count, stride, imap, buf, bufcount, datatype)
+! INTEGER, INTENT(IN) :: ncid
+! INTEGER, INTENT(IN) :: varid
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: imap(*)
+! <type>, INTENT(OUT) :: buf(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: bufcount
+! INTEGER, INTENT(IN) :: datatype
+! END FUNCTION nfmpi_get_varm_all
+
+ INTEGER FUNCTION nfmpi_put_varm_text(ncid, varid, start, count, stride, imap, text)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: imap(*)
+ CHARACTER(len=*), INTENT(IN) :: text
+ END FUNCTION nfmpi_put_varm_text
+
+ INTEGER FUNCTION nfmpi_put_varm_text_all(ncid, varid, start, count, stride, imap, text)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: imap(*)
+ CHARACTER(len=*), INTENT(IN) :: text
+ END FUNCTION nfmpi_put_varm_text_all
+
+ INTEGER FUNCTION nfmpi_get_varm_text(ncid, varid, start, count, stride, imap, text)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: imap(*)
+ CHARACTER(len=*), INTENT(OUT) :: text
+ END FUNCTION nfmpi_get_varm_text
+
+ INTEGER FUNCTION nfmpi_get_varm_text_all(ncid, varid, start, count, stride, imap, text)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: imap(*)
+ CHARACTER(len=*), INTENT(OUT) :: text
+ END FUNCTION nfmpi_get_varm_text_all
+
+ INTEGER FUNCTION nfmpi_put_varm_int1(ncid, varid, start, count, stride, imap, i1vals)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: OneByteInt = selected_int_kind(2)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: imap(*)
+ INTEGER(KIND=OneByteInt), INTENT(IN) :: i1vals(*)
+ END FUNCTION nfmpi_put_varm_int1
+
+ INTEGER FUNCTION nfmpi_put_varm_int1_all(ncid, varid, start, count, stride, imap, i1vals)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: OneByteInt = selected_int_kind(2)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: imap(*)
+ INTEGER(KIND=OneByteInt), INTENT(IN) :: i1vals(*)
+ END FUNCTION nfmpi_put_varm_int1_all
+
+ INTEGER FUNCTION nfmpi_get_varm_int1(ncid, varid, start, count, stride, imap, i1vals)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: OneByteInt = selected_int_kind(2)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: imap(*)
+ INTEGER(KIND=OneByteInt), INTENT(OUT) :: i1vals(*)
+ END FUNCTION nfmpi_get_varm_int1
+
+ INTEGER FUNCTION nfmpi_get_varm_int1_all(ncid, varid, start, count, stride, imap, i1vals)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: OneByteInt = selected_int_kind(2)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: imap(*)
+ INTEGER(KIND=OneByteInt), INTENT(OUT) :: i1vals(*)
+ END FUNCTION nfmpi_get_varm_int1_all
+
+ INTEGER FUNCTION nfmpi_put_varm_int2(ncid, varid, start, count, stride, imap, i2vals)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: TwoByteInt = selected_int_kind(4)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: imap(*)
+ INTEGER(KIND=TwoByteInt), INTENT(@INTENTV@) :: i2vals(*)
+ END FUNCTION nfmpi_put_varm_int2
+
+ INTEGER FUNCTION nfmpi_put_varm_int2_all(ncid, varid, start, count, stride, imap, i2vals)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: TwoByteInt = selected_int_kind(4)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: imap(*)
+ INTEGER(KIND=TwoByteInt), INTENT(@INTENTV@) :: i2vals(*)
+ END FUNCTION nfmpi_put_varm_int2_all
+
+ INTEGER FUNCTION nfmpi_get_varm_int2(ncid, varid, start, count, stride, imap, i2vals)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: TwoByteInt = selected_int_kind(4)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: imap(*)
+ INTEGER(KIND=TwoByteInt), INTENT(OUT) :: i2vals(*)
+ END FUNCTION nfmpi_get_varm_int2
+
+ INTEGER FUNCTION nfmpi_get_varm_int2_all(ncid, varid, start, count, stride, imap, i2vals)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: TwoByteInt = selected_int_kind(4)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: imap(*)
+ INTEGER(KIND=TwoByteInt), INTENT(OUT) :: i2vals(*)
+ END FUNCTION nfmpi_get_varm_int2_all
+
+ INTEGER FUNCTION nfmpi_put_varm_int (ncid, varid, start, count, stride, imap, ivals)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: imap(*)
+ INTEGER, INTENT(@INTENTV@) :: ivals(*)
+ END FUNCTION nfmpi_put_varm_int
+
+ INTEGER FUNCTION nfmpi_put_varm_int_all(ncid, varid, start, count, stride, imap, ivals)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: imap(*)
+ INTEGER, INTENT(@INTENTV@) :: ivals(*)
+ END FUNCTION nfmpi_put_varm_int_all
+
+ INTEGER FUNCTION nfmpi_get_varm_int (ncid, varid, start, count, stride, imap, ivals)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: imap(*)
+ INTEGER, INTENT(OUT) :: ivals(*)
+ END FUNCTION nfmpi_get_varm_int
+
+ INTEGER FUNCTION nfmpi_get_varm_int_all(ncid, varid, start, count, stride, imap, ivals)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: imap(*)
+ INTEGER, INTENT(OUT) :: ivals(*)
+ END FUNCTION nfmpi_get_varm_int_all
+
+ INTEGER FUNCTION nfmpi_put_varm_real(ncid, varid, start, count, stride, imap, rvals)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: imap(*)
+ REAL, INTENT(@INTENTV@) :: rvals(*)
+ END FUNCTION nfmpi_put_varm_real
+
+ INTEGER FUNCTION nfmpi_put_varm_real_all(ncid, varid, start, count, stride, imap, rvals)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: imap(*)
+ REAL, INTENT(@INTENTV@) :: rvals(*)
+ END FUNCTION nfmpi_put_varm_real_all
+
+ INTEGER FUNCTION nfmpi_get_varm_real(ncid, varid, start, count, stride, imap, rvals)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: imap(*)
+ REAL, INTENT(OUT) :: rvals(*)
+ END FUNCTION nfmpi_get_varm_real
+
+ INTEGER FUNCTION nfmpi_get_varm_real_all(ncid, varid, start, count, stride, imap, rvals)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: imap(*)
+ REAL, INTENT(OUT) :: rvals(*)
+ END FUNCTION nfmpi_get_varm_real_all
+
+ INTEGER FUNCTION nfmpi_put_varm_double(ncid, varid, start, count, stride, imap, dvals)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: imap(*)
+ DOUBLE PRECISION, INTENT(@INTENTV@) :: dvals(*)
+ END FUNCTION nfmpi_put_varm_double
+
+ INTEGER FUNCTION nfmpi_put_varm_double_all(ncid, varid, start, count, stride, imap, dvals)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: imap(*)
+ DOUBLE PRECISION, INTENT(@INTENTV@) :: dvals(*)
+ END FUNCTION nfmpi_put_varm_double_all
+
+ INTEGER FUNCTION nfmpi_get_varm_double(ncid, varid, start, count, stride, imap, dvals)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: imap(*)
+ DOUBLE PRECISION, INTENT(OUT) :: dvals(*)
+ END FUNCTION nfmpi_get_varm_double
+
+ INTEGER FUNCTION nfmpi_get_varm_double_all(ncid, varid, start, count, stride, imap, dvals)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: imap(*)
+ DOUBLE PRECISION, INTENT(OUT) :: dvals(*)
+ END FUNCTION nfmpi_get_varm_double_all
+
+ INTEGER FUNCTION nfmpi_put_varm_int8(ncid, varid, start, count, stride, imap, i8vals)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: EightByteInt = selected_int_kind(18)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: imap(*)
+ INTEGER(KIND=EightByteInt), INTENT(@INTENTV@) :: i8vals(*)
+ END FUNCTION nfmpi_put_varm_int8
+
+ INTEGER FUNCTION nfmpi_put_varm_int8_all(ncid, varid, start, count, stride, imap, i8vals)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: EightByteInt = selected_int_kind(18)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: imap(*)
+ INTEGER(KIND=EightByteInt), INTENT(@INTENTV@) :: i8vals(*)
+ END FUNCTION nfmpi_put_varm_int8_all
+
+ INTEGER FUNCTION nfmpi_get_varm_int8(ncid, varid, start, count, stride, imap, i8vals)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: EightByteInt = selected_int_kind(18)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: imap(*)
+ INTEGER(KIND=EightByteInt), INTENT(OUT) :: i8vals(*)
+ END FUNCTION nfmpi_get_varm_int8
+
+ INTEGER FUNCTION nfmpi_get_varm_int8_all(ncid, varid, start, count, stride, imap, i8vals)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: EightByteInt = selected_int_kind(18)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: imap(*)
+ INTEGER(KIND=EightByteInt), INTENT(OUT) :: i8vals(*)
+ END FUNCTION nfmpi_get_varm_int8_all
+
+!
+! non-blocking variable array iput/iget subroutines:
+!
+
+!
+! entire variable iput/iget subroutines:
+!
+
+!
+! flexible APIs, not ready yet for Fortran 77
+!
+! INTEGER FUNCTION nfmpi_iput_var(ncid, varid, buf, bufcount, datatype, req)
+! INTEGER, INTENT(IN) :: ncid
+! INTEGER, INTENT(IN) :: varid
+! <type>, INTENT(IN) :: buf(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: bufcount
+! INTEGER, INTENT(IN) :: datatype
+! INTEGER, INTENT(OUT) :: req
+! END FUNCTION nfmpi_iput_var
+
+! INTEGER FUNCTION nfmpi_iget_var(ncid, varid, buf, bufcount, datatype, req)
+! INTEGER, INTENT(IN) :: ncid
+! INTEGER, INTENT(IN) :: varid
+! <type>, INTENT(OUT) :: buf(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: bufcount
+! INTEGER, INTENT(IN) :: datatype
+! INTEGER, INTENT(OUT) :: req
+! END FUNCTION nfmpi_iget_var
+
+
+ INTEGER FUNCTION nfmpi_iput_var_text(ncid, varid, text, req)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ CHARACTER(len=*), INTENT(IN) :: text
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_iput_var_text
+
+ INTEGER FUNCTION nfmpi_iget_var_text(ncid, varid, text, req)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ CHARACTER(len=*), INTENT(OUT) :: text
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_iget_var_text
+
+ INTEGER FUNCTION nfmpi_iput_var_int1(ncid, varid, i1vals, req)
+ integer, parameter :: OneByteInt = selected_int_kind(2)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=OneByteInt), INTENT(IN) :: i1vals(*)
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_iput_var_int1
+
+ INTEGER FUNCTION nfmpi_iget_var_int1(ncid, varid, i1vals, req)
+ integer, parameter :: OneByteInt = selected_int_kind(2)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=OneByteInt), INTENT(OUT) :: i1vals(*)
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_iget_var_int1
+
+ INTEGER FUNCTION nfmpi_iput_var_int2(ncid, varid, i2vals, req)
+ integer, parameter :: TwoByteInt = selected_int_kind(4)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=TwoByteInt), INTENT(@INTENTV@) :: i2vals(*)
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_iput_var_int2
+
+ INTEGER FUNCTION nfmpi_iget_var_int2(ncid, varid, i2vals, req)
+ integer, parameter :: TwoByteInt = selected_int_kind(4)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=TwoByteInt), INTENT(OUT) :: i2vals(*)
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_iget_var_int2
+
+ INTEGER FUNCTION nfmpi_iput_var_int(ncid, varid, ivals, req)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER, INTENT(@INTENTV@) :: ivals(*)
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_iput_var_int
+
+ INTEGER FUNCTION nfmpi_iget_var_int(ncid, varid, ivals, req)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER, INTENT(OUT) :: ivals(*)
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_iget_var_int
+
+ INTEGER FUNCTION nfmpi_iput_var_real(ncid, varid, rvals, req)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ REAL, INTENT(@INTENTV@) :: rvals(*)
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_iput_var_real
+
+ INTEGER FUNCTION nfmpi_iget_var_real(ncid, varid, rvals, req)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ REAL, INTENT(OUT) :: rvals(*)
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_iget_var_real
+
+ INTEGER FUNCTION nfmpi_iput_var_double(ncid, varid, dvals, req)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ DOUBLE PRECISION, INTENT(@INTENTV@) :: dvals(*)
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_iput_var_double
+
+ INTEGER FUNCTION nfmpi_iget_var_double(ncid, varid, dvals, req)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ DOUBLE PRECISION, INTENT(OUT) :: dvals(*)
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_iget_var_double
+
+ INTEGER FUNCTION nfmpi_iput_var_int8(ncid, varid, i8vals, req)
+ integer, parameter :: EightByteInt = selected_int_kind(18)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=EightByteInt), INTENT(@INTENTV@) :: i8vals(*)
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_iput_var_int8
+
+ INTEGER FUNCTION nfmpi_iget_var_int8(ncid, varid, i8vals, req)
+ integer, parameter :: EightByteInt = selected_int_kind(18)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=EightByteInt), INTENT(OUT) :: i8vals(*)
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_iget_var_int8
+
+!
+! single variable iput/iget subroutines:
+!
+
+!
+! flexible APIs, not ready yet for Fortran 77
+!
+! INTEGER FUNCTION nfmpi_iput_var1(ncid, varid, index, buf, bufcount, datatype, req)
+! INTEGER, INTENT(IN) :: ncid
+! INTEGER, INTENT(IN) :: varid
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: index(*)
+! <type>, INTENT(IN) :: buf(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: bufcount
+! INTEGER, INTENT(IN) :: datatype
+! INTEGER, INTENT(OUT) :: req
+! END FUNCTION nfmpi_iput_var1
+
+! INTEGER FUNCTION nfmpi_iget_var1(ncid, varid, index, buf, bufcount, datatype, req)
+! INTEGER, INTENT(IN) :: ncid
+! INTEGER, INTENT(IN) :: varid
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: index(*)
+! <type>, INTENT(OUT) :: buf(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: bufcount
+! INTEGER, INTENT(IN) :: datatype
+! INTEGER, INTENT(OUT) :: req
+! END FUNCTION nfmpi_iget_var1
+
+ INTEGER FUNCTION nfmpi_iput_var1_text(ncid, varid, index, text, req)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: index(*)
+ CHARACTER, INTENT(IN) :: text
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_iput_var1_text
+
+ INTEGER FUNCTION nfmpi_iget_var1_text(ncid, varid, index, text, req)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: index(*)
+ CHARACTER, INTENT(OUT) :: text
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_iget_var1_text
+
+ INTEGER FUNCTION nfmpi_iput_var1_int1(ncid, varid, index, i1val, req)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: OneByteInt = selected_int_kind(2)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: index(*)
+ INTEGER(KIND=OneByteInt), INTENT(IN) :: i1val
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_iput_var1_int1
+
+ INTEGER FUNCTION nfmpi_iget_var1_int1(ncid, varid, index, i1val, req)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: OneByteInt = selected_int_kind(2)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: index(*)
+ INTEGER(KIND=OneByteInt), INTENT(OUT) :: i1val
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_iget_var1_int1
+
+ INTEGER FUNCTION nfmpi_iput_var1_int2(ncid, varid, index, i2val, req)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: TwoByteInt = selected_int_kind(4)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: index(*)
+ INTEGER(KIND=TwoByteInt), INTENT(@INTENTV@) :: i2val
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_iput_var1_int2
+
+ INTEGER FUNCTION nfmpi_iget_var1_int2(ncid, varid, index, i2val, req)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: TwoByteInt = selected_int_kind(4)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: index(*)
+ INTEGER(KIND=TwoByteInt), INTENT(OUT) :: i2val
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_iget_var1_int2
+
+ INTEGER FUNCTION nfmpi_iput_var1_int(ncid, varid, index, ival, req)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: index(*)
+ INTEGER, INTENT(@INTENTV@) :: ival
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_iput_var1_int
+
+ INTEGER FUNCTION nfmpi_iget_var1_int(ncid, varid, index, ival, req)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: index(*)
+ INTEGER, INTENT(OUT) :: ival
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_iget_var1_int
+
+ INTEGER FUNCTION nfmpi_iput_var1_real(ncid, varid, index, rval, req)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: index(*)
+ REAL, INTENT(@INTENTV@) :: rval
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_iput_var1_real
+
+ INTEGER FUNCTION nfmpi_iget_var1_real(ncid, varid, index, rval, req)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: index(*)
+ REAL, INTENT(OUT) :: rval
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_iget_var1_real
+
+ INTEGER FUNCTION nfmpi_iput_var1_double(ncid, varid, index, dval, req)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: index(*)
+ DOUBLE PRECISION, INTENT(@INTENTV@) :: dval
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_iput_var1_double
+
+ INTEGER FUNCTION nfmpi_iget_var1_double(ncid, varid, index, dval, req)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: index(*)
+ DOUBLE PRECISION, INTENT(OUT) :: dval
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_iget_var1_double
+
+ INTEGER FUNCTION nfmpi_iput_var1_int8(ncid, varid, index, i8val, req)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: EightByteInt = selected_int_kind(18)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: index(*)
+ INTEGER(KIND=EightByteInt), INTENT(@INTENTV@) :: i8val
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_iput_var1_int8
+
+ INTEGER FUNCTION nfmpi_iget_var1_int8(ncid, varid, index, i8val, req)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: EightByteInt = selected_int_kind(18)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: index(*)
+ INTEGER(KIND=EightByteInt), INTENT(OUT) :: i8val
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_iget_var1_int8
+
+!
+! variable array iput/iget subroutines:
+!
+
+!
+! flexible APIs, not ready yet for Fortran 77
+!
+! INTEGER FUNCTION nfmpi_iput_vara(ncid, varid, start, count, buf, bufcount, datatype, req)
+! INTEGER, INTENT(IN) :: ncid
+! INTEGER, INTENT(IN) :: varid
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+! <type>, INTENT(IN) :: buf(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: bufcount
+! INTEGER, INTENT(IN) :: datatype
+! INTEGER, INTENT(OUT) :: req
+! END FUNCTION nfmpi_iput_vara
+
+! INTEGER FUNCTION nfmpi_iget_vara(ncid, varid, start, count, buf, bufcount, datatype, req)
+! INTEGER, INTENT(IN) :: ncid
+! INTEGER, INTENT(IN) :: varid
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+! <type>, INTENT(OUT) :: buf(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: bufcount
+! INTEGER, INTENT(IN) :: datatype
+! INTEGER, INTENT(OUT) :: req
+! END FUNCTION nfmpi_iget_vara
+
+ INTEGER FUNCTION nfmpi_iput_vara_text(ncid, varid, start, count, text, req)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ CHARACTER(len=*), INTENT(IN) :: text
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_iput_vara_text
+
+ INTEGER FUNCTION nfmpi_iget_vara_text(ncid, varid, start, count, text, req)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ CHARACTER(len=*), INTENT(OUT) :: text
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_iget_vara_text
+
+ INTEGER FUNCTION nfmpi_iput_vara_int1(ncid, varid, start, count, i1vals, req)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: OneByteInt = selected_int_kind(2)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=OneByteInt), INTENT(IN) :: i1vals(*)
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_iput_vara_int1
+
+ INTEGER FUNCTION nfmpi_iget_vara_int1(ncid, varid, start, count, i1vals, req)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: OneByteInt = selected_int_kind(2)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=OneByteInt), INTENT(OUT) :: i1vals(*)
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_iget_vara_int1
+
+ INTEGER FUNCTION nfmpi_iput_vara_int2(ncid, varid, start, count, i2vals, req)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: TwoByteInt = selected_int_kind(4)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=TwoByteInt), INTENT(@INTENTV@) :: i2vals(*)
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_iput_vara_int2
+
+ INTEGER FUNCTION nfmpi_iget_vara_int2(ncid, varid, start, count, i2vals, req)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: TwoByteInt = selected_int_kind(4)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=TwoByteInt), INTENT(OUT) :: i2vals(*)
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_iget_vara_int2
+
+ INTEGER FUNCTION nfmpi_iput_vara_int(ncid, varid, start, count, ivals, req)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER, INTENT(@INTENTV@) :: ivals(*)
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_iput_vara_int
+
+ INTEGER FUNCTION nfmpi_iget_vara_int(ncid, varid, start, count, ivals, req)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER, INTENT(OUT) :: ivals(*)
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_iget_vara_int
+
+ INTEGER FUNCTION nfmpi_iput_vara_real(ncid, varid, start, count, rvals, req)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ REAL, INTENT(@INTENTV@) :: rvals(*)
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_iput_vara_real
+
+ INTEGER FUNCTION nfmpi_iget_vara_real(ncid, varid, start, count, rvals, req)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ REAL, INTENT(OUT) :: rvals(*)
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_iget_vara_real
+
+ INTEGER FUNCTION nfmpi_iput_vara_double(ncid, varid, start, count, dvals, req)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ DOUBLE PRECISION, INTENT(@INTENTV@) :: dvals(*)
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_iput_vara_double
+
+ INTEGER FUNCTION nfmpi_iget_vara_double(ncid, varid, start, count, dvals, req)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ DOUBLE PRECISION, INTENT(OUT) :: dvals(*)
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_iget_vara_double
+
+ INTEGER FUNCTION nfmpi_iput_vara_int8(ncid, varid, start, count, i8vals, req)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: EightByteInt = selected_int_kind(18)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=EightByteInt), INTENT(@INTENTV@) :: i8vals(*)
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_iput_vara_int8
+
+ INTEGER FUNCTION nfmpi_iget_vara_int8(ncid, varid, start, count, i8vals, req)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: EightByteInt = selected_int_kind(18)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=EightByteInt), INTENT(OUT) :: i8vals(*)
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_iget_vara_int8
+
+!
+! strided variable iput/iget subroutines:
+!
+
+!
+! flexible APIs, not ready yet for Fortran 77
+!
+! INTEGER FUNCTION nfmpi_iput_vars(ncid, varid, start, count, stride, buf, bufcount, datatype, req)
+! INTEGER, INTENT(IN) :: ncid
+! INTEGER, INTENT(IN) :: varid
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+! <type>, INTENT(IN) :: buf(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: bufcount
+! INTEGER, INTENT(IN) :: datatype
+! INTEGER, INTENT(OUT) :: req
+! END FUNCTION nfmpi_iput_vars
+
+! INTEGER FUNCTION nfmpi_iget_vars(ncid, varid, start, count, stride, buf, bufcount, datatype, req)
+! INTEGER, INTENT(IN) :: ncid
+! INTEGER, INTENT(IN) :: varid
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+! <type>, INTENT(OUT) :: buf(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: bufcount
+! INTEGER, INTENT(IN) :: datatype
+! INTEGER, INTENT(OUT) :: req
+! END FUNCTION nfmpi_iget_vars
+
+ INTEGER FUNCTION nfmpi_iput_vars_text(ncid, varid, start, count, stride, text, req)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+ CHARACTER(len=*), INTENT(IN) :: text
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_iput_vars_text
+
+ INTEGER FUNCTION nfmpi_iget_vars_text(ncid, varid, start, count, stride, text, req)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+ CHARACTER(len=*), INTENT(OUT) :: text
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_iget_vars_text
+
+ INTEGER FUNCTION nfmpi_iput_vars_int1(ncid, varid, start, count, stride, i1vals, req)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: OneByteInt = selected_int_kind(2)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+ INTEGER(KIND=OneByteInt), INTENT(IN) :: i1vals(*)
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_iput_vars_int1
+
+ INTEGER FUNCTION nfmpi_iget_vars_int1(ncid, varid, start, count, stride, i1vals, req)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: OneByteInt = selected_int_kind(2)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+ INTEGER(KIND=OneByteInt), INTENT(OUT) :: i1vals(*)
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_iget_vars_int1
+
+ INTEGER FUNCTION nfmpi_iput_vars_int2(ncid, varid, start, count, stride, i2vals, req)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: TwoByteInt = selected_int_kind(4)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+ INTEGER(KIND=TwoByteInt), INTENT(@INTENTV@) :: i2vals(*)
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_iput_vars_int2
+
+ INTEGER FUNCTION nfmpi_iget_vars_int2(ncid, varid, start, count, stride, i2vals, req)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: TwoByteInt = selected_int_kind(4)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+ INTEGER(KIND=TwoByteInt), INTENT(OUT) :: i2vals(*)
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_iget_vars_int2
+
+ INTEGER FUNCTION nfmpi_iput_vars_int(ncid, varid, start, count, stride, ivals, req)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+ INTEGER, INTENT(@INTENTV@) :: ivals(*)
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_iput_vars_int
+
+ INTEGER FUNCTION nfmpi_iget_vars_int(ncid, varid, start, count, stride, ivals, req)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+ INTEGER, INTENT(OUT) :: ivals(*)
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_iget_vars_int
+
+ INTEGER FUNCTION nfmpi_iput_vars_real(ncid, varid, start, count, stride, rvals, req)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+ REAL, INTENT(@INTENTV@) :: rvals(*)
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_iput_vars_real
+
+ INTEGER FUNCTION nfmpi_iget_vars_real(ncid, varid, start, count, stride, rvals, req)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+ REAL, INTENT(OUT) :: rvals(*)
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_iget_vars_real
+
+ INTEGER FUNCTION nfmpi_iput_vars_double(ncid, varid, start, count, stride, dvals, req)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+ DOUBLE PRECISION, INTENT(@INTENTV@) :: dvals(*)
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_iput_vars_double
+
+ INTEGER FUNCTION nfmpi_iget_vars_double(ncid, varid, start, count, stride, dvals, req)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+ DOUBLE PRECISION, INTENT(OUT) :: dvals(*)
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_iget_vars_double
+
+ INTEGER FUNCTION nfmpi_iput_vars_int8(ncid, varid, start, count, stride, i8vals, req)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: EightByteInt = selected_int_kind(18)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+ INTEGER(KIND=EightByteInt), INTENT(@INTENTV@) :: i8vals(*)
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_iput_vars_int8
+
+ INTEGER FUNCTION nfmpi_iget_vars_int8(ncid, varid, start, count, stride, i8vals, req)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: EightByteInt = selected_int_kind(18)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+ INTEGER(KIND=EightByteInt), INTENT(OUT) :: i8vals(*)
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_iget_vars_int8
+
+!
+! mapped variable iput/iget subroutines:
+!
+
+!
+! flexible APIs, not ready yet for Fortran 77
+!
+! INTEGER FUNCTION nfmpi_iput_varm(ncid, varid, start, count, stride, imap, buf, bufcount, datatype, req)
+! INTEGER, INTENT(IN) :: ncid
+! INTEGER, INTENT(IN) :: varid
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: imap(*)
+! <type>, INTENT(IN) :: buf(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: bufcount
+! INTEGER, INTENT(IN) :: datatype
+! INTEGER, INTENT(OUT) :: req
+! END FUNCTION nfmpi_iput_varm
+
+! INTEGER FUNCTION nfmpi_iget_varm(ncid, varid, start, count, stride, imap, buf, bufcount, datatype, req)
+! INTEGER, INTENT(IN) :: ncid
+! INTEGER, INTENT(IN) :: varid
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: imap(*)
+! <type>, INTENT(OUT) :: buf(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: bufcount
+! INTEGER, INTENT(IN) :: datatype
+! INTEGER, INTENT(OUT) :: req
+! END FUNCTION nfmpi_iget_varm
+
+ INTEGER FUNCTION nfmpi_iput_varm_text(ncid, varid, start, count, stride, imap, text, req)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: imap(*)
+ CHARACTER(len=*), INTENT(IN) :: text
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_iput_varm_text
+
+ INTEGER FUNCTION nfmpi_iget_varm_text(ncid, varid, start, count, stride, imap, text, req)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: imap(*)
+ CHARACTER(len=*), INTENT(OUT) :: text
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_iget_varm_text
+
+ INTEGER FUNCTION nfmpi_iput_varm_int1(ncid, varid, start, count, stride, imap, i1vals, req)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: OneByteInt = selected_int_kind(2)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: imap(*)
+ INTEGER(KIND=OneByteInt), INTENT(IN) :: i1vals(*)
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_iput_varm_int1
+
+ INTEGER FUNCTION nfmpi_iget_varm_int1(ncid, varid, start, count, stride, imap, i1vals, req)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: OneByteInt = selected_int_kind(2)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: imap(*)
+ INTEGER(KIND=OneByteInt), INTENT(OUT) :: i1vals(*)
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_iget_varm_int1
+
+ INTEGER FUNCTION nfmpi_iput_varm_int2(ncid, varid, start, count, stride, imap, i2vals, req)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: TwoByteInt = selected_int_kind(4)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: imap(*)
+ INTEGER(KIND=TwoByteInt), INTENT(@INTENTV@) :: i2vals(*)
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_iput_varm_int2
+
+ INTEGER FUNCTION nfmpi_iget_varm_int2(ncid, varid, start, count, stride, imap, i2vals, req)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: TwoByteInt = selected_int_kind(4)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: imap(*)
+ INTEGER(KIND=TwoByteInt), INTENT(OUT) :: i2vals(*)
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_iget_varm_int2
+
+ INTEGER FUNCTION nfmpi_iput_varm_int (ncid, varid, start, count, stride, imap, ivals, req)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: imap(*)
+ INTEGER, INTENT(@INTENTV@) :: ivals(*)
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_iput_varm_int
+
+ INTEGER FUNCTION nfmpi_iget_varm_int (ncid, varid, start, count, stride, imap, ivals, req)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: imap(*)
+ INTEGER, INTENT(OUT) :: ivals(*)
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_iget_varm_int
+
+ INTEGER FUNCTION nfmpi_iput_varm_real(ncid, varid, start, count, stride, imap, rvals, req)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: imap(*)
+ REAL, INTENT(@INTENTV@) :: rvals(*)
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_iput_varm_real
+
+ INTEGER FUNCTION nfmpi_iget_varm_real(ncid, varid, start, count, stride, imap, rvals, req)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: imap(*)
+ REAL, INTENT(OUT) :: rvals(*)
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_iget_varm_real
+
+ INTEGER FUNCTION nfmpi_iput_varm_double(ncid, varid, start, count, stride, imap, dvals, req)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: imap(*)
+ DOUBLE PRECISION, INTENT(@INTENTV@) :: dvals(*)
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_iput_varm_double
+
+ INTEGER FUNCTION nfmpi_iget_varm_double(ncid, varid, start, count, stride, imap, dvals, req)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: imap(*)
+ DOUBLE PRECISION, INTENT(OUT) :: dvals(*)
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_iget_varm_double
+
+ INTEGER FUNCTION nfmpi_iput_varm_int8(ncid, varid, start, count, stride, imap, i8vals, req)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: EightByteInt = selected_int_kind(18)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: imap(*)
+ INTEGER(KIND=EightByteInt), INTENT(@INTENTV@) :: i8vals(*)
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_iput_varm_int8
+
+ INTEGER FUNCTION nfmpi_iget_varm_int8(ncid, varid, start, count, stride, imap, i8vals, req)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: EightByteInt = selected_int_kind(18)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: imap(*)
+ INTEGER(KIND=EightByteInt), INTENT(OUT) :: i8vals(*)
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_iget_varm_int8
+
+!
+! Begin buffered put non-blocking subroutines:
+!
+
+!
+! flexible APIs, not ready yet for Fortran 77
+!
+! INTEGER FUNCTION nfmpi_bput_var(ncid, varid, buf, bufcount, datatype, req)
+! INTEGER, INTENT(IN) :: ncid
+! INTEGER, INTENT(IN) :: varid
+! <type>, INTENT(IN) :: buf(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: bufcount
+! INTEGER, INTENT(IN) :: datatype
+! INTEGER, INTENT(OUT) :: req
+! END FUNCTION nfmpi_bput_var
+
+! INTEGER FUNCTION nfmpi_bget_var(ncid, varid, buf, bufcount, datatype, req)
+! INTEGER, INTENT(IN) :: ncid
+! INTEGER, INTENT(IN) :: varid
+! <type>, INTENT(OUT) :: buf(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: bufcount
+! INTEGER, INTENT(IN) :: datatype
+! INTEGER, INTENT(OUT) :: req
+! END FUNCTION nfmpi_bget_var
+
+ INTEGER FUNCTION nfmpi_bput_var_text(ncid, varid, text, req)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ CHARACTER(len=*), INTENT(IN) :: text(*)
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_bput_var_text
+
+ INTEGER FUNCTION nfmpi_bput_var_int1(ncid, varid, i1vals, req)
+ integer, parameter :: OneByteInt = selected_int_kind(2)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=OneByteInt), INTENT(IN) :: i1vals(*)
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_bput_var_int1
+
+ INTEGER FUNCTION nfmpi_bput_var_int2(ncid, varid, i2vals, req)
+ integer, parameter :: TwoByteInt = selected_int_kind(4)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=TwoByteInt), INTENT(IN) :: i2vals(*)
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_bput_var_int2
+
+ INTEGER FUNCTION nfmpi_bput_var_int(ncid, varid, ivals, req)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER, INTENT(IN) :: ivals(*)
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_bput_var_int
+
+ INTEGER FUNCTION nfmpi_bput_var_real(ncid, varid, rvals, req)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ REAL, INTENT(IN) :: rvals(*)
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_bput_var_real
+
+ INTEGER FUNCTION nfmpi_bput_var_double(ncid, varid, dvals, req)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ DOUBLE PRECISION, INTENT(IN) :: dvals(*)
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_bput_var_double
+
+ INTEGER FUNCTION nfmpi_bput_var_int8(ncid, varid, i8vals, req)
+ integer, parameter :: EightByteInt = selected_int_kind(18)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=EightByteInt), INTENT(IN) :: i8vals(*)
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_bput_var_int8
+
+!
+! flexible APIs, not ready yet for Fortran 77
+!
+! INTEGER FUNCTION nfmpi_bput_var1(ncid, varid, start, buf, bufcount, datatype, req)
+! INTEGER, INTENT(IN) :: ncid
+! INTEGER, INTENT(IN) :: varid
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+! <type>, INTENT(IN) :: buf(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: bufcount
+! INTEGER, INTENT(IN) :: datatype
+! INTEGER, INTENT(OUT) :: req
+! END FUNCTION nfmpi_bput_var1
+
+! INTEGER FUNCTION nfmpi_bget_var1(ncid, varid, start, buf, bufcount, datatype, req)
+! INTEGER, INTENT(IN) :: ncid
+! INTEGER, INTENT(IN) :: varid
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+! <type>, INTENT(OUT) :: buf(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: bufcount
+! INTEGER, INTENT(IN) :: datatype
+! INTEGER, INTENT(OUT) :: req
+! END FUNCTION nfmpi_bget_var1
+
+ INTEGER FUNCTION nfmpi_bput_var1_text(ncid, varid, index, text, req)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: index(*)
+ CHARACTER, INTENT(IN) :: text
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_bput_var1_text
+
+ INTEGER FUNCTION nfmpi_bput_var1_int1(ncid, varid, index, i1val, req)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: OneByteInt = selected_int_kind(2)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: index(*)
+ INTEGER(KIND=OneByteInt), INTENT(IN) :: i1val
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_bput_var1_int1
+
+ INTEGER FUNCTION nfmpi_bput_var1_int2(ncid, varid, index, i2val, req)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: TwoByteInt = selected_int_kind(4)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: index(*)
+ INTEGER(KIND=TwoByteInt), INTENT(IN) :: i2val
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_bput_var1_int2
+
+ INTEGER FUNCTION nfmpi_bput_var1_int(ncid, varid, index, ival, req)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: index(*)
+ INTEGER, INTENT(IN) :: ival
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_bput_var1_int
+
+ INTEGER FUNCTION nfmpi_bput_var1_real(ncid, varid, index, rval, req)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: index(*)
+ REAL, INTENT(IN) :: rval
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_bput_var1_real
+
+ INTEGER FUNCTION nfmpi_bput_var1_double(ncid, varid, index, dval, req)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: index(*)
+ DOUBLE PRECISION, INTENT(IN) :: dval
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_bput_var1_double
+
+ INTEGER FUNCTION nfmpi_bput_var1_int8(ncid, varid, index, i8val, req)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: EightByteInt = selected_int_kind(18)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: index(*)
+ INTEGER(KIND=EightByteInt), INTENT(IN) :: i8val
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_bput_var1_int8
+
+!
+! flexible APIs, not ready yet for Fortran 77
+!
+! INTEGER FUNCTION nfmpi_bput_vara(ncid, varid, start, count, buf, bufcount, datatype, req)
+! INTEGER, INTENT(IN) :: ncid
+! INTEGER, INTENT(IN) :: varid
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+! <type>, INTENT(IN) :: buf(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: bufcount
+! INTEGER, INTENT(IN) :: datatype
+! INTEGER, INTENT(OUT) :: req
+! END FUNCTION nfmpi_bput_vara
+
+! INTEGER FUNCTION nfmpi_bget_vara(ncid, varid, start, count, buf, bufcount, datatype, req)
+! INTEGER, INTENT(IN) :: ncid
+! INTEGER, INTENT(IN) :: varid
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+! <type>, INTENT(OUT) :: buf(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: bufcount
+! INTEGER, INTENT(IN) :: datatype
+! INTEGER, INTENT(OUT) :: req
+! END FUNCTION nfmpi_bget_vara
+
+ INTEGER FUNCTION nfmpi_bput_vara_text(ncid, varid, start, count, text, req)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ CHARACTER(len=*), INTENT(IN) :: text(*)
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_bput_vara_text
+
+ INTEGER FUNCTION nfmpi_bput_vara_int1(ncid, varid, start, count, i1vals, req)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: OneByteInt = selected_int_kind(2)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=OneByteInt), INTENT(IN) :: i1vals(*)
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_bput_vara_int1
+
+ INTEGER FUNCTION nfmpi_bput_vara_int2(ncid, varid, start, count, i2vals, req)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: TwoByteInt = selected_int_kind(4)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=TwoByteInt), INTENT(IN) :: i2vals(*)
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_bput_vara_int2
+
+ INTEGER FUNCTION nfmpi_bput_vara_int(ncid, varid, start, count, ivals, req)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER, INTENT(IN) :: ivals(*)
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_bput_vara_int
+
+ INTEGER FUNCTION nfmpi_bput_vara_real(ncid, varid, start, count, rvals, req)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ REAL, INTENT(IN) :: rvals(*)
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_bput_vara_real
+
+ INTEGER FUNCTION nfmpi_bput_vara_double(ncid, varid, start, count, dvals, req)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ DOUBLE PRECISION, INTENT(IN) :: dvals(*)
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_bput_vara_double
+
+ INTEGER FUNCTION nfmpi_bput_vara_int8(ncid, varid, start, count, i8vals, req)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: EightByteInt = selected_int_kind(18)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=EightByteInt), INTENT(IN) :: i8vals(*)
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_bput_vara_int8
+
+!
+! flexible APIs, not ready yet for Fortran 77
+!
+! INTEGER FUNCTION nfmpi_bput_vars(ncid, varid, start, count, stride, imap, buf, bufcount, datatype, req)
+! INTEGER, INTENT(IN) :: ncid
+! INTEGER, INTENT(IN) :: varid
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+! <type>, INTENT(IN) :: buf(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: bufcount
+! INTEGER, INTENT(IN) :: datatype
+! INTEGER, INTENT(OUT) :: req
+! END FUNCTION nfmpi_bput_vars
+
+! INTEGER FUNCTION nfmpi_bget_vars(ncid, varid, start, count, stride, imap, buf, bufcount, datatype, req)
+! INTEGER, INTENT(IN) :: ncid
+! INTEGER, INTENT(IN) :: varid
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+! <type>, INTENT(OUT) :: buf(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: bufcount
+! INTEGER, INTENT(IN) :: datatype
+! INTEGER, INTENT(OUT) :: req
+! END FUNCTION nfmpi_bget_vars
+
+ INTEGER FUNCTION nfmpi_bput_vars_text(ncid, varid, start, count, stride, text, req)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+ CHARACTER(len=*), INTENT(IN) :: text
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_bput_vars_text
+
+ INTEGER FUNCTION nfmpi_bput_vars_int1(ncid, varid, start, count, stride, i1vals, req)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: OneByteInt = selected_int_kind(2)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+ INTEGER(KIND=OneByteInt), INTENT(IN) :: i1vals(*)
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_bput_vars_int1
+
+ INTEGER FUNCTION nfmpi_bput_vars_int2(ncid, varid, start, count, stride, i2vals, req)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: TwoByteInt = selected_int_kind(4)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+ INTEGER(KIND=TwoByteInt), INTENT(IN) :: i2vals(*)
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_bput_vars_int2
+
+ INTEGER FUNCTION nfmpi_bput_vars_int(ncid, varid, start, count, stride, ivals, req)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+ INTEGER, INTENT(IN) :: ivals(*)
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_bput_vars_int
+
+ INTEGER FUNCTION nfmpi_bput_vars_real(ncid, varid, start, count, stride, rvals, req)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+ REAL, INTENT(IN) :: rvals(*)
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_bput_vars_real
+
+ INTEGER FUNCTION nfmpi_bput_vars_double(ncid, varid, start, count, stride, dvals, req)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+ DOUBLE PRECISION, INTENT(IN) :: dvals(*)
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_bput_vars_double
+
+ INTEGER FUNCTION nfmpi_bput_vars_int8(ncid, varid, start, count, stride, i8vals, req)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: EightByteInt = selected_int_kind(18)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+ INTEGER(KIND=EightByteInt), INTENT(IN) :: i8vals(*)
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_bput_vars_int8
+
+!
+! flexible APIs, not ready yet for Fortran 77
+!
+! INTEGER FUNCTION nfmpi_bput_varm(ncid, varid, start, count, stride, imap, buf, bufcount, datatype, req)
+! INTEGER, INTENT(IN) :: ncid
+! INTEGER, INTENT(IN) :: varid
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: imap(*)
+! <type>, INTENT(IN) :: buf(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: bufcount
+! INTEGER, INTENT(IN) :: datatype
+! INTEGER, INTENT(OUT) :: req
+! END FUNCTION nfmpi_bput_varm
+
+! INTEGER FUNCTION nfmpi_bget_varm(ncid, varid, start, count, stride, imap, buf, bufcount, datatype, req)
+! INTEGER, INTENT(IN) :: ncid
+! INTEGER, INTENT(IN) :: varid
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: imap(*)
+! <type>, INTENT(OUT) :: buf(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: bufcount
+! INTEGER, INTENT(IN) :: datatype
+! INTEGER, INTENT(OUT) :: req
+! END FUNCTION nfmpi_bget_varm
+
+ INTEGER FUNCTION nfmpi_bput_varm_text(ncid, varid, start, count, stride, imap, text, req)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: imap(*)
+ CHARACTER(len=*), INTENT(IN) :: text
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_bput_varm_text
+
+ INTEGER FUNCTION nfmpi_bput_varm_int1(ncid, varid, start, count, stride, imap, i1vals, req)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: OneByteInt = selected_int_kind(2)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: imap(*)
+ INTEGER(KIND=OneByteInt), INTENT(IN) :: i1vals(*)
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_bput_varm_int1
+
+ INTEGER FUNCTION nfmpi_bput_varm_int2(ncid, varid, start, count, stride, imap, i2vals, req)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: TwoByteInt = selected_int_kind(4)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: imap(*)
+ INTEGER(KIND=TwoByteInt), INTENT(IN) :: i2vals(*)
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_bput_varm_int2
+
+ INTEGER FUNCTION nfmpi_bput_varm_int (ncid, varid, start, count, stride, imap, ivals, req)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: imap(*)
+ INTEGER, INTENT(IN) :: ivals(*)
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_bput_varm_int
+
+ INTEGER FUNCTION nfmpi_bput_varm_real(ncid, varid, start, count, stride, imap, rvals, req)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: imap(*)
+ REAL, INTENT(IN) :: rvals(*)
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_bput_varm_real
+
+ INTEGER FUNCTION nfmpi_bput_varm_double(ncid, varid, start, count, stride, imap, dvals, req)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: imap(*)
+ DOUBLE PRECISION, INTENT(IN) :: dvals(*)
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_bput_varm_double
+
+ INTEGER FUNCTION nfmpi_bput_varm_int8(ncid, varid, start, count, stride, imap, i8vals, req)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: EightByteInt = selected_int_kind(18)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: start(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: count(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: stride(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: imap(*)
+ INTEGER(KIND=EightByteInt), INTENT(IN) :: i8vals(*)
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_bput_varm_int8
+
+ INTEGER FUNCTION nfmpi_buffer_attach(ncid, bufsize)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: bufsize
+ END FUNCTION nfmpi_buffer_attach
+
+ INTEGER FUNCTION nfmpi_buffer_detach(ncid)
+ INTEGER, INTENT(IN) :: ncid
+ END FUNCTION nfmpi_buffer_detach
+
+ INTEGER FUNCTION nfmpi_inq_buffer_usage(ncid, usage)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(OUT) :: usage
+ END FUNCTION nfmpi_inq_buffer_usage
+
+ INTEGER FUNCTION nfmpi_inq_buffer_size(ncid, buf_size)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(OUT) :: buf_size
+ END FUNCTION nfmpi_inq_buffer_size
+
+!
+! End buffered put non-blocking subroutines:
+!
+
+ INTEGER FUNCTION nfmpi_wait(ncid, count, req, status)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: count
+ INTEGER, INTENT(INOUT):: req(count)
+ INTEGER, INTENT(OUT) :: status(count)
+ END FUNCTION nfmpi_wait
+
+ INTEGER FUNCTION nfmpi_wait_all(ncid, count, req, status)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: count
+ INTEGER, INTENT(INOUT):: req(count)
+ INTEGER, INTENT(OUT) :: status(count)
+ END FUNCTION nfmpi_wait_all
+
+ INTEGER FUNCTION nfmpi_cancel(ncid, count, req, status)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: count
+ INTEGER, INTENT(INOUT):: req(count)
+ INTEGER, INTENT(OUT) :: status(count)
+ END FUNCTION nfmpi_cancel
+
+ INTEGER FUNCTION nfmpi_inq_put_size(ncid, size)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(OUT) :: size
+ END FUNCTION nfmpi_inq_put_size
+
+ INTEGER FUNCTION nfmpi_inq_get_size(ncid, size)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(OUT) :: size
+ END FUNCTION nfmpi_inq_get_size
+
+ INTEGER FUNCTION nfmpi_inq_header_size(ncid, size)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(OUT) :: size
+ END FUNCTION nfmpi_inq_header_size
+
+ INTEGER FUNCTION nfmpi_inq_header_extent(ncid, extent)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(OUT) :: extent
+ END FUNCTION nfmpi_inq_header_extent
+
+ INTEGER FUNCTION nfmpi_inq_varoffset(ncid, varid, offset)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(OUT) :: offset
+ END FUNCTION nfmpi_inq_varoffset
+
+ INTEGER FUNCTION nfmpi_inq_nreqs(ncid, nreqs)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(OUT) :: nreqs
+ END FUNCTION nfmpi_inq_nreqs
+
+ INTEGER FUNCTION nfmpi_inq_malloc_size(size)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(OUT) :: size
+ END FUNCTION nfmpi_inq_malloc_size
+
+ INTEGER FUNCTION nfmpi_inq_malloc_max_size(size)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(OUT) :: size
+ END FUNCTION nfmpi_inq_malloc_max_size
+
+ INTEGER FUNCTION nfmpi_inq_malloc_list()
+ END FUNCTION nfmpi_inq_malloc_list
+
+ INTEGER FUNCTION nfmpi_inq_files_opened(nfiles, ncids)
+ INTEGER, INTENT(OUT) :: nfiles
+ INTEGER, INTENT(OUT) :: ncids(*)
+ END FUNCTION nfmpi_inq_files_opened
+
+ INTEGER FUNCTION nfmpi_inq_recsize(ncid, recsize)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(OUT) :: recsize
+ END FUNCTION nfmpi_inq_recsize
+
+!
+! Begin of varn subroutines:
+!
+
+!
+! flexible APIs, not ready yet for Fortran 77
+!
+! INTEGER FUNCTION nfmpi_get_varn(ncid, varid, num, starts, counts, buf, bufcount, buftype)
+! INTEGER, INTENT(IN) :: ncid
+! INTEGER, INTENT(IN) :: varid
+! INTEGER, INTENT(IN) :: num
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: starts(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: counts(*)
+! <type>, INTENT(OUT) :: buf(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: bufcount
+! INTEGER, INTENT(IN) :: buftype
+! END FUNCTION nfmpi_get_varn
+
+! INTEGER FUNCTION nfmpi_get_varn_all(ncid, varid, num, starts, counts, buf, bufcount, buftype)
+! INTEGER, INTENT(IN) :: ncid
+! INTEGER, INTENT(IN) :: varid
+! INTEGER, INTENT(IN) :: num
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: starts(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: counts(*)
+! <type>, INTENT(OUT) :: buf(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: bufcount
+! INTEGER, INTENT(IN) :: buftype
+! END FUNCTION nfmpi_get_varn_all
+
+! INTEGER FUNCTION nfmpi_put_varn(ncid, varid, num, starts, counts, buf, bufcount, buftype)
+! INTEGER, INTENT(IN) :: ncid
+! INTEGER, INTENT(IN) :: varid
+! INTEGER, INTENT(IN) :: num
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: starts(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: counts(*)
+! <type>, INTENT(IN) :: buf(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: bufcount
+! INTEGER, INTENT(IN) :: buftype
+! END FUNCTION nfmpi_put_varn
+
+! INTEGER FUNCTION nfmpi_put_varn_all(ncid, varid, num, starts, counts, buf, bufcount, buftype)
+! INTEGER, INTENT(IN) :: ncid
+! INTEGER, INTENT(IN) :: varid
+! INTEGER, INTENT(IN) :: num
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: starts(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: counts(*)
+! <type>, INTENT(IN) :: buf(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: bufcount
+! INTEGER, INTENT(IN) :: buftype
+! END FUNCTION nfmpi_put_varn_all
+
+
+ INTEGER FUNCTION nfmpi_get_varn_text(ncid, varid, num, starts, counts, text)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER, INTENT(IN) :: num
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: starts(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: counts(*)
+ CHARACTER(len=*), INTENT(OUT) :: text
+ END FUNCTION nfmpi_get_varn_text
+
+ INTEGER FUNCTION nfmpi_get_varn_int1(ncid, varid, num, starts, counts, i1vals)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: OneByteInt = selected_int_kind(2)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER, INTENT(IN) :: num
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: starts(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: counts(*)
+ INTEGER(KIND=OneByteInt), INTENT(OUT) :: i1vals(*)
+ END FUNCTION nfmpi_get_varn_int1
+
+ INTEGER FUNCTION nfmpi_get_varn_int2(ncid, varid, num, starts, counts, i2vals)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: TwoByteInt = selected_int_kind(4)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER, INTENT(IN) :: num
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: starts(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: counts(*)
+ INTEGER(KIND=TwoByteInt), INTENT(OUT) :: i2vals(*)
+ END FUNCTION nfmpi_get_varn_int2
+
+ INTEGER FUNCTION nfmpi_get_varn_int(ncid, varid, num, starts, counts, ivals)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER, INTENT(IN) :: num
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: starts(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: counts(*)
+ INTEGER, INTENT(OUT) :: ivals(*)
+ END FUNCTION nfmpi_get_varn_int
+
+ INTEGER FUNCTION nfmpi_get_varn_real(ncid, varid, num, starts, counts, rvals)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER, INTENT(IN) :: num
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: starts(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: counts(*)
+ REAL, INTENT(OUT) :: rvals(*)
+ END FUNCTION nfmpi_get_varn_real
+
+ INTEGER FUNCTION nfmpi_get_varn_double(ncid, varid, num, starts, counts, dvals)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER, INTENT(IN) :: num
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: starts(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: counts(*)
+ DOUBLE PRECISION, INTENT(OUT) :: dvals(*)
+ END FUNCTION nfmpi_get_varn_double
+
+ INTEGER FUNCTION nfmpi_get_varn_int8(ncid, varid, num, starts, counts, i8vals)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: EightByteInt = selected_int_kind(18)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER, INTENT(IN) :: num
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: starts(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: counts(*)
+ INTEGER(KIND=EightByteInt), INTENT(OUT) :: i8vals(*)
+ END FUNCTION nfmpi_get_varn_int8
+
+ INTEGER FUNCTION nfmpi_get_varn_text_all(ncid, varid, num, starts, counts, text)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER, INTENT(IN) :: num
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: starts(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: counts(*)
+ CHARACTER(len=*), INTENT(OUT) :: text
+ END FUNCTION nfmpi_get_varn_text_all
+
+ INTEGER FUNCTION nfmpi_get_varn_int1_all(ncid, varid, num, starts, counts, i1vals)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: OneByteInt = selected_int_kind(2)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER, INTENT(IN) :: num
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: starts(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: counts(*)
+ INTEGER(KIND=OneByteInt), INTENT(OUT) :: i1vals(*)
+ END FUNCTION nfmpi_get_varn_int1_all
+
+ INTEGER FUNCTION nfmpi_get_varn_int2_all(ncid, varid, num, starts, counts, i2vals)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: TwoByteInt = selected_int_kind(4)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER, INTENT(IN) :: num
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: starts(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: counts(*)
+ INTEGER(KIND=TwoByteInt), INTENT(OUT) :: i2vals(*)
+ END FUNCTION nfmpi_get_varn_int2_all
+
+ INTEGER FUNCTION nfmpi_get_varn_int_all(ncid, varid, num, starts, counts, ivals)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER, INTENT(IN) :: num
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: starts(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: counts(*)
+ INTEGER, INTENT(OUT) :: ivals(*)
+ END FUNCTION nfmpi_get_varn_int_all
+
+ INTEGER FUNCTION nfmpi_get_varn_real_all(ncid, varid, num, starts, counts, rvals)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER, INTENT(IN) :: num
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: starts(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: counts(*)
+ REAL, INTENT(OUT) :: rvals(*)
+ END FUNCTION nfmpi_get_varn_real_all
+
+ INTEGER FUNCTION nfmpi_get_varn_double_all(ncid, varid, num, starts, counts, dvals)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER, INTENT(IN) :: num
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: starts(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: counts(*)
+ DOUBLE PRECISION, INTENT(OUT) :: dvals(*)
+ END FUNCTION nfmpi_get_varn_double_all
+
+ INTEGER FUNCTION nfmpi_get_varn_int8_all(ncid, varid, num, starts, counts, i8vals)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: EightByteInt = selected_int_kind(18)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER, INTENT(IN) :: num
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: starts(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: counts(*)
+ INTEGER(KIND=EightByteInt), INTENT(OUT) :: i8vals(*)
+ END FUNCTION nfmpi_get_varn_int8_all
+
+
+ INTEGER FUNCTION nfmpi_put_varn_text(ncid, varid, num, starts, counts, text)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER, INTENT(IN) :: num
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: starts(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: counts(*)
+ CHARACTER(len=*), INTENT(IN) :: text
+ END FUNCTION nfmpi_put_varn_text
+
+ INTEGER FUNCTION nfmpi_put_varn_int1(ncid, varid, num, starts, counts, i1vals)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: OneByteInt = selected_int_kind(2)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER, INTENT(IN) :: num
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: starts(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: counts(*)
+ INTEGER(KIND=OneByteInt), INTENT(IN) :: i1vals(*)
+ END FUNCTION nfmpi_put_varn_int1
+
+ INTEGER FUNCTION nfmpi_put_varn_int2(ncid, varid, num, starts, counts, i2vals)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: TwoByteInt = selected_int_kind(4)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER, INTENT(IN) :: num
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: starts(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: counts(*)
+ INTEGER(KIND=TwoByteInt), INTENT(@INTENTV@) :: i2vals(*)
+ END FUNCTION nfmpi_put_varn_int2
+
+ INTEGER FUNCTION nfmpi_put_varn_int(ncid, varid, num, starts, counts, ivals)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER, INTENT(IN) :: num
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: starts(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: counts(*)
+ INTEGER, INTENT(@INTENTV@) :: ivals(*)
+ END FUNCTION nfmpi_put_varn_int
+
+ INTEGER FUNCTION nfmpi_put_varn_real(ncid, varid, num, starts, counts, rvals)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER, INTENT(IN) :: num
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: starts(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: counts(*)
+ REAL, INTENT(@INTENTV@) :: rvals(*)
+ END FUNCTION nfmpi_put_varn_real
+
+ INTEGER FUNCTION nfmpi_put_varn_double(ncid, varid, num, starts, counts, dvals)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER, INTENT(IN) :: num
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: starts(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: counts(*)
+ DOUBLE PRECISION, INTENT(@INTENTV@) :: dvals(*)
+ END FUNCTION nfmpi_put_varn_double
+
+ INTEGER FUNCTION nfmpi_put_varn_int8(ncid, varid, num, starts, counts, i8vals)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: EightByteInt = selected_int_kind(18)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER, INTENT(IN) :: num
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: starts(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: counts(*)
+ INTEGER(KIND=EightByteInt), INTENT(@INTENTV@) :: i8vals(*)
+ END FUNCTION nfmpi_put_varn_int8
+
+ INTEGER FUNCTION nfmpi_put_varn_text_all(ncid, varid, num, starts, counts, text)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER, INTENT(IN) :: num
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: starts(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: counts(*)
+ CHARACTER(len=*), INTENT(IN) :: text
+ END FUNCTION nfmpi_put_varn_text_all
+
+ INTEGER FUNCTION nfmpi_put_varn_int1_all(ncid, varid, num, starts, counts, i1vals)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: OneByteInt = selected_int_kind(2)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER, INTENT(IN) :: num
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: starts(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: counts(*)
+ INTEGER(KIND=OneByteInt), INTENT(IN) :: i1vals(*)
+ END FUNCTION nfmpi_put_varn_int1_all
+
+ INTEGER FUNCTION nfmpi_put_varn_int2_all(ncid, varid, num, starts, counts, i2vals)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: TwoByteInt = selected_int_kind(4)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER, INTENT(IN) :: num
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: starts(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: counts(*)
+ INTEGER(KIND=TwoByteInt), INTENT(@INTENTV@) :: i2vals(*)
+ END FUNCTION nfmpi_put_varn_int2_all
+
+ INTEGER FUNCTION nfmpi_put_varn_int_all(ncid, varid, num, starts, counts, ivals)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER, INTENT(IN) :: num
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: starts(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: counts(*)
+ INTEGER, INTENT(@INTENTV@) :: ivals(*)
+ END FUNCTION nfmpi_put_varn_int_all
+
+ INTEGER FUNCTION nfmpi_put_varn_real_all(ncid, varid, num, starts, counts, rvals)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER, INTENT(IN) :: num
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: starts(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: counts(*)
+ REAL, INTENT(@INTENTV@) :: rvals(*)
+ END FUNCTION nfmpi_put_varn_real_all
+
+ INTEGER FUNCTION nfmpi_put_varn_double_all(ncid, varid, num, starts, counts, dvals)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER, INTENT(IN) :: num
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: starts(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: counts(*)
+ DOUBLE PRECISION, INTENT(@INTENTV@) :: dvals(*)
+ END FUNCTION nfmpi_put_varn_double_all
+
+ INTEGER FUNCTION nfmpi_put_varn_int8_all(ncid, varid, num, starts, counts, i8vals)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: EightByteInt = selected_int_kind(18)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER, INTENT(IN) :: num
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: starts(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: counts(*)
+ INTEGER(KIND=EightByteInt), INTENT(@INTENTV@) :: i8vals(*)
+ END FUNCTION nfmpi_put_varn_int8_all
+
+!
+! flexible APIs, not ready yet for Fortran 77
+!
+! INTEGER FUNCTION nfmpi_iget_varn(ncid, varid, num, starts, counts, buf, bufcount, buftype, req)
+! INTEGER, INTENT(IN) :: ncid
+! INTEGER, INTENT(IN) :: varid
+! INTEGER, INTENT(IN) :: num
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: starts(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: counts(*)
+! <type>, INTENT(OUT) :: buf(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: bufcount
+! INTEGER, INTENT(IN) :: buftype
+! INTEGER, INTENT(OUT) :: req
+! END FUNCTION nfmpi_iget_varn
+
+! INTEGER FUNCTION nfmpi_iput_varn(ncid, varid, num, starts, counts, buf, bufcount, buftype, req)
+! INTEGER, INTENT(IN) :: ncid
+! INTEGER, INTENT(IN) :: varid
+! INTEGER, INTENT(IN) :: num
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: starts(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: counts(*)
+! <type>, INTENT(IN) :: buf(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: bufcount
+! INTEGER, INTENT(IN) :: buftype
+! INTEGER, INTENT(OUT) :: req
+! END FUNCTION nfmpi_iput_varn
+
+ INTEGER FUNCTION nfmpi_iget_varn_text(ncid, varid, num, starts, counts, text, req)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER, INTENT(IN) :: num
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: starts(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: counts(*)
+ CHARACTER(len=*), INTENT(OUT) :: text
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_iget_varn_text
+
+ INTEGER FUNCTION nfmpi_iget_varn_int1(ncid, varid, num, starts, counts, i1vals, req)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: OneByteInt = selected_int_kind(2)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER, INTENT(IN) :: num
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: starts(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: counts(*)
+ INTEGER(KIND=OneByteInt), INTENT(OUT) :: i1vals(*)
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_iget_varn_int1
+
+ INTEGER FUNCTION nfmpi_iget_varn_int2(ncid, varid, num, starts, counts, i2vals, req)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: TwoByteInt = selected_int_kind(4)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER, INTENT(IN) :: num
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: starts(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: counts(*)
+ INTEGER(KIND=TwoByteInt), INTENT(OUT) :: i2vals(*)
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_iget_varn_int2
+
+ INTEGER FUNCTION nfmpi_iget_varn_int(ncid, varid, num, starts, counts, ivals, req)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER, INTENT(IN) :: num
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: starts(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: counts(*)
+ INTEGER, INTENT(OUT) :: ivals(*)
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_iget_varn_int
+
+ INTEGER FUNCTION nfmpi_iget_varn_real(ncid, varid, num, starts, counts, rvals, req)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER, INTENT(IN) :: num
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: starts(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: counts(*)
+ REAL, INTENT(OUT) :: rvals(*)
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_iget_varn_real
+
+ INTEGER FUNCTION nfmpi_iget_varn_double(ncid, varid, num, starts, counts, dvals, req)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER, INTENT(IN) :: num
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: starts(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: counts(*)
+ DOUBLE PRECISION, INTENT(OUT) :: dvals(*)
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_iget_varn_double
+
+ INTEGER FUNCTION nfmpi_iget_varn_int8(ncid, varid, num, starts, counts, i8vals, req)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: EightByteInt = selected_int_kind(18)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER, INTENT(IN) :: num
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: starts(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: counts(*)
+ INTEGER(KIND=EightByteInt), INTENT(OUT) :: i8vals(*)
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_iget_varn_int8
+
+ INTEGER FUNCTION nfmpi_iput_varn_text(ncid, varid, num, starts, counts, text, req)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER, INTENT(IN) :: num
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: starts(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: counts(*)
+ CHARACTER(len=*), INTENT(IN) :: text
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_iput_varn_text
+
+ INTEGER FUNCTION nfmpi_iput_varn_int1(ncid, varid, num, starts, counts, i1vals, req)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: OneByteInt = selected_int_kind(2)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER, INTENT(IN) :: num
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: starts(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: counts(*)
+ INTEGER(KIND=OneByteInt), INTENT(IN) :: i1vals(*)
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_iput_varn_int1
+
+ INTEGER FUNCTION nfmpi_iput_varn_int2(ncid, varid, num, starts, counts, i2vals, req)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: TwoByteInt = selected_int_kind(4)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER, INTENT(IN) :: num
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: starts(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: counts(*)
+ INTEGER(KIND=TwoByteInt), INTENT(@INTENTV@) :: i2vals(*)
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_iput_varn_int2
+
+ INTEGER FUNCTION nfmpi_iput_varn_int(ncid, varid, num, starts, counts, ivals, req)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER, INTENT(IN) :: num
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: starts(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: counts(*)
+ INTEGER, INTENT(@INTENTV@) :: ivals(*)
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_iput_varn_int
+
+ INTEGER FUNCTION nfmpi_iput_varn_real(ncid, varid, num, starts, counts, rvals, req)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER, INTENT(IN) :: num
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: starts(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: counts(*)
+ REAL, INTENT(@INTENTV@) :: rvals(*)
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_iput_varn_real
+
+ INTEGER FUNCTION nfmpi_iput_varn_double(ncid, varid, num, starts, counts, dvals, req)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER, INTENT(IN) :: num
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: starts(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: counts(*)
+ DOUBLE PRECISION, INTENT(@INTENTV@) :: dvals(*)
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_iput_varn_double
+
+ INTEGER FUNCTION nfmpi_iput_varn_int8(ncid, varid, num, starts, counts, i8vals, req)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: EightByteInt = selected_int_kind(18)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER, INTENT(IN) :: num
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: starts(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: counts(*)
+ INTEGER(KIND=EightByteInt), INTENT(@INTENTV@) :: i8vals(*)
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_iput_varn_int8
+
+! INTEGER FUNCTION nfmpi_bput_varn(ncid, varid, num, starts, counts, buf, bufcount, buftype, req)
+! INTEGER, INTENT(IN) :: ncid
+! INTEGER, INTENT(IN) :: varid
+! INTEGER, INTENT(IN) :: num
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: starts(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: counts(*)
+! <type>, INTENT(IN) :: buf(*)
+! INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: bufcount
+! INTEGER, INTENT(IN) :: buftype
+! INTEGER, INTENT(OUT) :: req
+! END FUNCTION nfmpi_bput_varn
+
+ INTEGER FUNCTION nfmpi_bput_varn_text(ncid, varid, num, starts, counts, text, req)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER, INTENT(IN) :: num
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: starts(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: counts(*)
+ CHARACTER(len=*), INTENT(IN) :: text
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_bput_varn_text
+
+ INTEGER FUNCTION nfmpi_bput_varn_int1(ncid, varid, num, starts, counts, i1vals, req)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: OneByteInt = selected_int_kind(2)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER, INTENT(IN) :: num
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: starts(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: counts(*)
+ INTEGER(KIND=OneByteInt), INTENT(IN) :: i1vals(*)
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_bput_varn_int1
+
+ INTEGER FUNCTION nfmpi_bput_varn_int2(ncid, varid, num, starts, counts, i2vals, req)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: TwoByteInt = selected_int_kind(4)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER, INTENT(IN) :: num
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: starts(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: counts(*)
+ INTEGER(KIND=TwoByteInt), INTENT(@INTENTV@) :: i2vals(*)
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_bput_varn_int2
+
+ INTEGER FUNCTION nfmpi_bput_varn_int(ncid, varid, num, starts, counts, ivals, req)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER, INTENT(IN) :: num
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: starts(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: counts(*)
+ INTEGER, INTENT(@INTENTV@) :: ivals(*)
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_bput_varn_int
+
+ INTEGER FUNCTION nfmpi_bput_varn_real(ncid, varid, num, starts, counts, rvals, req)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER, INTENT(IN) :: num
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: starts(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: counts(*)
+ REAL, INTENT(@INTENTV@) :: rvals(*)
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_bput_varn_real
+
+ INTEGER FUNCTION nfmpi_bput_varn_double(ncid, varid, num, starts, counts, dvals, req)
+ use mpi, only: MPI_OFFSET_KIND
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER, INTENT(IN) :: num
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: starts(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: counts(*)
+ DOUBLE PRECISION, INTENT(@INTENTV@) :: dvals(*)
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_bput_varn_double
+
+ INTEGER FUNCTION nfmpi_bput_varn_int8(ncid, varid, num, starts, counts, i8vals, req)
+ use mpi, only: MPI_OFFSET_KIND
+ integer, parameter :: EightByteInt = selected_int_kind(18)
+ INTEGER, INTENT(IN) :: ncid
+ INTEGER, INTENT(IN) :: varid
+ INTEGER, INTENT(IN) :: num
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: starts(*)
+ INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: counts(*)
+ INTEGER(KIND=EightByteInt), INTENT(@INTENTV@) :: i8vals(*)
+ INTEGER, INTENT(OUT) :: req
+ END FUNCTION nfmpi_bput_varn_int8
+
+!
+! End of varn subroutines:
+!
+
+END INTERFACE
+
+! PnetCDF flexible APIs
+ integer, external :: &
+ nfmpi_put_var, &
+ nfmpi_put_var1, &
+ nfmpi_put_vara, &
+ nfmpi_put_vars, &
+ nfmpi_put_varm, &
+ nfmpi_get_var, &
+ nfmpi_get_var1, &
+ nfmpi_get_vara, &
+ nfmpi_get_vars, &
+ nfmpi_get_varm, &
+ nfmpi_put_vard, &
+ nfmpi_get_vard, &
+ nfmpi_def_var_fill, &
+ nfmpi_inq_var_fill
+
+! nfmpi_put_var_all
+! collective put an entire variable does not make sense
+!
+
+ integer, external :: &
+ nfmpi_put_var1_all, &
+ nfmpi_put_vara_all, &
+ nfmpi_put_vars_all, &
+ nfmpi_put_varm_all, &
+ nfmpi_get_var_all, &
+ nfmpi_get_var1_all, &
+ nfmpi_get_vara_all, &
+ nfmpi_get_vars_all, &
+ nfmpi_get_varm_all, &
+ nfmpi_iput_var, &
+ nfmpi_iput_var1, &
+ nfmpi_iput_vara, &
+ nfmpi_iput_vars, &
+ nfmpi_iput_varm, &
+ nfmpi_iget_var, &
+ nfmpi_iget_var1, &
+ nfmpi_iget_vara, &
+ nfmpi_iget_vars, &
+ nfmpi_iget_varm, &
+ nfmpi_bput_var, &
+ nfmpi_bput_var1, &
+ nfmpi_bput_vara, &
+ nfmpi_bput_vars, &
+ nfmpi_bput_varm, &
+ nfmpi_get_varn, &
+ nfmpi_put_varn, &
+ nfmpi_get_varn_all, &
+ nfmpi_put_varn_all, &
+ nfmpi_iget_varn, &
+ nfmpi_iput_varn, &
+ nfmpi_bput_varn, &
+ nfmpi_put_vard_all, &
+ nfmpi_get_vard_all
+
diff --git a/src/libf90/attributes.f90 b/src/libf90/attributes.f90
new file mode 100644
index 0000000..68a67f9
--- /dev/null
+++ b/src/libf90/attributes.f90
@@ -0,0 +1,352 @@
+!
+! Copyright (C) 2013, Northwestern University and Argonne National Laboratory
+! See COPYRIGHT notice in top-level directory.
+!
+! $Id: attributes.f90 1525 2013-12-14 17:17:42Z wkliao $
+!
+! This file is taken from netcdf_attributes.f90 with changes for PnetCDF use
+!
+!
+
+ !
+ ! Attribute routines:
+ !
+ ! -------
+ function nf90mpi_copy_att(ncid_in, varid_in, name, ncid_out, varid_out)
+ integer, intent(in) :: ncid_in, varid_in
+ character (len = *), intent(in) :: name
+ integer, intent(in) :: ncid_out, varid_out
+ integer :: nf90mpi_copy_att
+
+ nf90mpi_copy_att = nfmpi_copy_att(ncid_in, varid_in, name, ncid_out, varid_out)
+ end function nf90mpi_copy_att
+ ! -------
+ function nf90mpi_rename_att(ncid, varid, curname, newname)
+ integer, intent(in) :: ncid, varid
+ character (len = *), intent(in) :: curname, newname
+ integer :: nf90mpi_rename_att
+
+ nf90mpi_rename_att = nfmpi_rename_att(ncid, varid, curname, newname)
+ end function nf90mpi_rename_att
+ ! -------
+ function nf90mpi_del_att(ncid, varid, name)
+ integer, intent(in) :: ncid, varid
+ character (len = *), intent(in) :: name
+ integer :: nf90mpi_del_att
+
+ nf90mpi_del_att = nfmpi_del_att(ncid, varid, name)
+ end function nf90mpi_del_att
+ ! -------
+ ! Attribute inquiry functions
+ ! -------
+ function nf90mpi_inq_attname(ncid, varid, attnum, name)
+ integer, intent( in) :: ncid, varid, attnum
+ character (len = *), intent(out) :: name
+ integer :: nf90mpi_inq_attname
+
+ nf90mpi_inq_attname = nfmpi_inq_attname(ncid, varid, attnum, name)
+ end function nf90mpi_inq_attname
+ ! -------
+ function nf90mpi_inquire_attribute(ncid, varid, name, xtype, len, attnum)
+ integer, intent( in) :: ncid, varid
+ character (len = *), intent( in) :: name
+ integer, intent(out), optional :: xtype, attnum
+ integer (kind=MPI_OFFSET_KIND), intent(out), optional :: len
+ integer :: nf90mpi_inquire_attribute
+ integer :: local_xtype
+ integer (kind=MPI_OFFSET_KIND) :: local_len
+
+ ! Do we need to worry about not saving the state from this call?
+ if(present(attnum)) &
+ nf90mpi_inquire_attribute = nfmpi_inq_attid(ncid, varid, name, attnum)
+
+ nf90mpi_inquire_attribute = nfmpi_inq_att (ncid, varid, name, local_xtype, local_len)
+
+ if(present(xtype)) xtype = local_xtype
+ if(present(len )) len = local_len
+ end function nf90mpi_inquire_attribute
+ ! -------
+ ! Put and get functions; these will get overloaded
+ ! -------
+ ! Text
+ ! -------
+ function nf90mpi_put_att_text(ncid, varid, name, values)
+ integer, intent(in) :: ncid, varid
+ character(len = *), intent(in) :: name
+ character(len = *), intent(in) :: values
+ integer :: nf90mpi_put_att_text
+ integer (kind=MPI_OFFSET_KIND) :: ilen
+
+ ilen = len_trim(values)
+ nf90mpi_put_att_text = nfmpi_put_att_text(ncid, varid, name, ilen, trim(values))
+ end function nf90mpi_put_att_text
+ ! -------
+ function nf90mpi_get_att_text(ncid, varid, name, values)
+ integer, intent( in) :: ncid, varid
+ character(len = *), intent( in) :: name
+ character(len = *), intent(out) :: values
+ integer :: nf90mpi_get_att_text
+
+ values = ' ' !! make sure result will be blank padded
+ nf90mpi_get_att_text = nfmpi_get_att_text(ncid, varid, name, values)
+ end function nf90mpi_get_att_text
+ ! -------
+ ! Integer attributes
+ ! -------
+ function nf90mpi_put_att_OneByteInt(ncid, varid, name, values)
+ integer, intent( in) :: ncid, varid
+ character(len = *), intent( in) :: name
+ integer (kind = OneByteInt), dimension(:), intent( in) :: values
+ integer :: nf90mpi_put_att_OneByteInt
+ integer (kind=MPI_OFFSET_KIND) :: ilen
+
+ ilen = size(values)
+ nf90mpi_put_att_OneByteInt = nfmpi_put_att_int1(ncid, varid, name, nf90_int1, ilen, values)
+ end function nf90mpi_put_att_OneByteInt
+ ! -------
+ function nf90mpi_put_att_one_OneByteInt(ncid, varid, name, values)
+ integer, intent( in) :: ncid, varid
+ character(len = *), intent( in) :: name
+ integer (kind = OneByteInt), intent( in) :: values
+ integer :: nf90mpi_put_att_one_OneByteInt
+ integer (kind = OneByteInt), dimension(1) :: valuesA
+
+ valuesA(1) = values
+ nf90mpi_put_att_one_OneByteInt = nfmpi_put_att_int1(ncid, varid, name, nf90_int1, 1_MPI_OFFSET_KIND, valuesA)
+ end function nf90mpi_put_att_one_OneByteInt
+ ! -------
+ function nf90mpi_get_att_OneByteInt(ncid, varid, name, values)
+ integer, intent( in) :: ncid, varid
+ character(len = *), intent( in) :: name
+ integer (kind = OneByteInt), dimension(:), intent(out) :: values
+ integer :: nf90mpi_get_att_OneByteInt
+
+ nf90mpi_get_att_OneByteInt = nfmpi_get_att_int1(ncid, varid, name, values)
+ end function nf90mpi_get_att_OneByteInt
+ ! -------
+ function nf90mpi_get_att_one_OneByteInt(ncid, varid, name, values)
+ integer, intent( in) :: ncid, varid
+ character(len = *), intent( in) :: name
+ integer (kind = OneByteInt), intent(out) :: values
+ integer :: nf90mpi_get_att_one_OneByteInt
+ integer (kind = OneByteInt), dimension(1) :: valuesA
+
+ nf90mpi_get_att_one_OneByteInt = nfmpi_get_att_int1(ncid, varid, name, valuesA)
+ values = valuesA(1)
+ end function nf90mpi_get_att_one_OneByteInt
+ ! -------
+ function nf90mpi_put_att_TwoByteInt(ncid, varid, name, values)
+ integer, intent(in) :: ncid, varid
+ character(len = *), intent(in) :: name
+ integer (kind = TwoByteInt), dimension(:), intent(in) :: values
+ integer :: nf90mpi_put_att_TwoByteInt
+ integer (kind=MPI_OFFSET_KIND) :: ilen
+
+ ilen = size(values)
+ nf90mpi_put_att_TwoByteInt = nfmpi_put_att_int2(ncid, varid, name, nf90_int2, ilen, values)
+ end function nf90mpi_put_att_TwoByteInt
+ ! -------
+ function nf90mpi_put_att_one_TwoByteInt(ncid, varid, name, values)
+ integer, intent(in) :: ncid, varid
+ character(len = *), intent(in) :: name
+ integer (kind = TwoByteInt), intent(in) :: values
+ integer :: nf90mpi_put_att_one_TwoByteInt
+ integer (kind = TwoByteInt), dimension(1) :: valuesA
+
+ valuesA(1) = values
+ nf90mpi_put_att_one_TwoByteInt = nfmpi_put_att_int2(ncid, varid, name, nf90_int2, 1_MPI_OFFSET_KIND, valuesA)
+ end function nf90mpi_put_att_one_TwoByteInt
+ ! -------
+ function nf90mpi_get_att_TwoByteInt(ncid, varid, name, values)
+ integer, intent( in) :: ncid, varid
+ character(len = *), intent( in) :: name
+ integer (kind = TwoByteInt), dimension(:), intent(out) :: values
+ integer :: nf90mpi_get_att_TwoByteInt
+
+ nf90mpi_get_att_TwoByteInt = nfmpi_get_att_int2(ncid, varid, name, values)
+ end function nf90mpi_get_att_TwoByteInt
+ ! -------
+ function nf90mpi_get_att_one_TwoByteInt(ncid, varid, name, values)
+ integer, intent( in) :: ncid, varid
+ character(len = *), intent( in) :: name
+ integer (kind = TwoByteInt), intent(out) :: values
+ integer :: nf90mpi_get_att_one_TwoByteInt
+ integer (kind = TwoByteInt), dimension(1) :: valuesA
+
+ nf90mpi_get_att_one_TwoByteInt = nfmpi_get_att_int2(ncid, varid, name, valuesA)
+ values = valuesA(1)
+ end function nf90mpi_get_att_one_TwoByteInt
+ ! -------
+ function nf90mpi_put_att_FourByteInt(ncid, varid, name, values)
+ integer, intent(in) :: ncid, varid
+ character(len = *), intent(in) :: name
+ integer (kind = FourByteInt), dimension(:), intent(in) :: values
+ integer :: nf90mpi_put_att_FourByteInt
+ integer (kind=MPI_OFFSET_KIND) :: ilen
+
+ ilen = size(values)
+ nf90mpi_put_att_FourByteInt = nfmpi_put_att_int(ncid, varid, name, nf90_int, ilen, values)
+ end function nf90mpi_put_att_FourByteInt
+ ! -------
+ function nf90mpi_put_att_one_FourByteInt(ncid, varid, name, values)
+ integer, intent(in) :: ncid, varid
+ character(len = *), intent(in) :: name
+ integer (kind = FourByteInt), intent(in) :: values
+ integer :: nf90mpi_put_att_one_FourByteInt
+ integer (kind = FourByteInt), dimension(1) :: valuesA
+
+ valuesA(1) = int(values)
+ nf90mpi_put_att_one_FourByteInt = nfmpi_put_att_int(ncid, varid, name, nf90_int, 1_MPI_OFFSET_KIND, valuesA)
+ end function nf90mpi_put_att_one_FourByteInt
+ ! -------
+ function nf90mpi_get_att_FourByteInt(ncid, varid, name, values)
+ integer, intent(in) :: ncid, varid
+ character(len = *), intent(in) :: name
+ integer (kind = FourByteInt), dimension(:), intent(out) :: values
+ integer :: nf90mpi_get_att_FourByteInt
+ integer, dimension(size(values)) :: defaultInteger
+
+ nf90mpi_get_att_FourByteInt = nfmpi_get_att_int(ncid, varid, name, defaultInteger)
+ values(:) = defaultInteger(:)
+ end function nf90mpi_get_att_FourByteInt
+ ! -------
+ function nf90mpi_get_att_one_FourByteInt(ncid, varid, name, values)
+ integer, intent(in) :: ncid, varid
+ character(len = *), intent(in) :: name
+ integer (kind = FourByteInt), intent(out) :: values
+ integer :: nf90mpi_get_att_one_FourByteInt
+ integer, dimension(1) :: defaultInteger
+
+ nf90mpi_get_att_one_FourByteInt = nfmpi_get_att_int(ncid, varid, name, defaultInteger)
+ values = defaultInteger(1)
+ end function nf90mpi_get_att_one_FourByteInt
+ ! -------
+ function nf90mpi_put_att_EightByteInt(ncid, varid, name, values)
+ integer, intent(in) :: ncid, varid
+ character(len = *), intent(in) :: name
+ integer (kind = EightByteInt), dimension(:), intent(in) :: values
+ integer :: nf90mpi_put_att_EightByteInt
+ integer (kind=MPI_OFFSET_KIND) :: ilen
+
+ ilen = size(values)
+ nf90mpi_put_att_EightByteInt = nfmpi_put_att_int8(ncid, varid, name, nf90_int, ilen, values)
+ end function nf90mpi_put_att_EightByteInt
+ ! -------
+ function nf90mpi_put_att_one_EightByteInt(ncid, varid, name, values)
+ integer, intent(in) :: ncid, varid
+ character(len = *), intent(in) :: name
+ integer (kind = EightByteInt), intent(in) :: values
+ integer :: nf90mpi_put_att_one_EightByteInt
+
+ integer (kind = EightByteInt), dimension(1) :: valuesA
+ valuesA(1) = values
+ nf90mpi_put_att_one_EightByteInt = nfmpi_put_att_int8(ncid, varid, name, nf90_int, 1_MPI_OFFSET_KIND, valuesA)
+ end function nf90mpi_put_att_one_EightByteInt
+ ! -------
+ function nf90mpi_get_att_EightByteInt(ncid, varid, name, values)
+ integer, intent(in) :: ncid, varid
+ character(len = *), intent(in) :: name
+ integer (kind = EightByteInt), dimension(:), intent(out) :: values
+ integer :: nf90mpi_get_att_EightByteInt
+
+ nf90mpi_get_att_EightByteInt = nfmpi_get_att_int8(ncid, varid, name, values)
+ end function nf90mpi_get_att_EightByteInt
+ ! -------
+ function nf90mpi_get_att_one_EightByteInt(ncid, varid, name, values)
+ integer, intent(in) :: ncid, varid
+ character(len = *), intent(in) :: name
+ integer (kind = EightByteInt), intent(out) :: values
+ integer :: nf90mpi_get_att_one_EightByteInt
+
+ integer (kind = EightByteInt), dimension(1) :: valuesA
+
+ nf90mpi_get_att_one_EightByteInt = nfmpi_get_att_int8(ncid, varid, name, valuesA)
+ values = valuesA(1)
+ end function nf90mpi_get_att_one_EightByteInt
+ ! -------
+ ! Real attributes
+ ! -------
+ function nf90mpi_put_att_FourByteReal(ncid, varid, name, values)
+ integer, intent(in) :: ncid, varid
+ character(len = *), intent(in) :: name
+ real (kind = FourByteReal), dimension(:), intent(in) :: values
+ integer :: nf90mpi_put_att_FourByteReal
+ integer (kind=MPI_OFFSET_KIND) :: ilen
+
+ ilen = size(values)
+ nf90mpi_put_att_FourByteReal = nfmpi_put_att_real(ncid, varid, name, nf90_real4, ilen, values)
+ end function nf90mpi_put_att_FourByteReal
+ ! -------
+ function nf90mpi_put_att_one_FourByteReal(ncid, varid, name, values)
+ integer, intent(in) :: ncid, varid
+ character(len = *), intent(in) :: name
+ real (kind = FourByteReal), intent(in) :: values
+ integer :: nf90mpi_put_att_one_FourByteReal
+
+ real (kind = FourByteReal), dimension(1) :: valuesA
+ valuesA(1) = values
+ nf90mpi_put_att_one_FourByteReal = nfmpi_put_att_real(ncid, varid, name, nf90_real4, 1_MPI_OFFSET_KIND, valuesA)
+ end function nf90mpi_put_att_one_FourByteReal
+ ! -------
+ function nf90mpi_get_att_FourByteReal(ncid, varid, name, values)
+ integer, intent(in) :: ncid, varid
+ character(len = *), intent(in) :: name
+ real (kind = FourByteReal), dimension(:), intent(out) :: values
+ integer :: nf90mpi_get_att_FourByteReal
+
+ nf90mpi_get_att_FourByteReal = nfmpi_get_att_real(ncid, varid, name, values)
+ end function nf90mpi_get_att_FourByteReal
+ ! -------
+ function nf90mpi_get_att_one_FourByteReal(ncid, varid, name, values)
+ integer, intent(in) :: ncid, varid
+ character(len = *), intent(in) :: name
+ real (kind = FourByteReal), intent(out) :: values
+ integer :: nf90mpi_get_att_one_FourByteReal
+
+ real (kind = FourByteReal), dimension(1) :: valuesA
+ nf90mpi_get_att_one_FourByteReal = nfmpi_get_att_real(ncid, varid, name, valuesA)
+ values = valuesA(1)
+ end function nf90mpi_get_att_one_FourByteReal
+ ! -------
+ function nf90mpi_put_att_EightByteReal(ncid, varid, name, values)
+ integer, intent(in) :: ncid, varid
+ character(len = *), intent(in) :: name
+ real (kind = EightByteReal), dimension(:), intent(in) :: values
+ integer :: nf90mpi_put_att_EightByteReal
+ integer (kind=MPI_OFFSET_KIND) :: ilen
+
+ ilen = size(values)
+ nf90mpi_put_att_EightByteReal = nfmpi_put_att_double(ncid, varid, name, nf90_real8, ilen, values)
+ end function nf90mpi_put_att_EightByteReal
+ ! -------
+ function nf90mpi_put_att_one_EightByteReal(ncid, varid, name, values)
+ integer, intent(in) :: ncid, varid
+ character(len = *), intent(in) :: name
+ real (kind = EightByteReal), intent(in) :: values
+ integer :: nf90mpi_put_att_one_EightByteReal
+
+ real (kind = EightByteReal), dimension(1) :: valuesA
+ valuesA(1) = values
+ nf90mpi_put_att_one_EightByteReal = nfmpi_put_att_double(ncid, varid, name, nf90_real8, 1_MPI_OFFSET_KIND, valuesA)
+ end function nf90mpi_put_att_one_EightByteReal
+ ! -------
+ function nf90mpi_get_att_EightByteReal(ncid, varid, name, values)
+ integer, intent(in) :: ncid, varid
+ character(len = *), intent(in) :: name
+ real (kind = EightByteReal), dimension(:), intent(out) :: values
+ integer :: nf90mpi_get_att_EightByteReal
+
+ nf90mpi_get_att_EightByteReal = nfmpi_get_att_double(ncid, varid, name, values)
+ end function nf90mpi_get_att_EightByteReal
+ ! -------
+ function nf90mpi_get_att_one_EightByteReal(ncid, varid, name, values)
+ integer, intent(in) :: ncid, varid
+ character(len = *), intent(in) :: name
+ real (kind = EightByteReal), intent(out) :: values
+ integer :: nf90mpi_get_att_one_EightByteReal
+
+ real (kind = EightByteReal), dimension(1) :: valuesA
+ nf90mpi_get_att_one_EightByteReal = nfmpi_get_att_double(ncid, varid, name, valuesA)
+ values = valuesA(1)
+ end function nf90mpi_get_att_one_EightByteReal
+ ! -------
diff --git a/src/libf90/dims.f90 b/src/libf90/dims.f90
new file mode 100644
index 0000000..92f4f4d
--- /dev/null
+++ b/src/libf90/dims.f90
@@ -0,0 +1,56 @@
+!
+! Copyright (C) 2013, Northwestern University and Argonne National Laboratory
+! See COPYRIGHT notice in top-level directory.
+!
+! $Id: dims.f90 1468 2013-10-26 16:53:18Z wkliao $
+!
+! This file is taken from netcdf_dims.f90 with changes for PnetCDF use
+!
+!
+
+ !
+ ! Dimension routines:
+ !
+ ! -----------
+ function nf90mpi_def_dim(ncid, name, len, dimid)
+ integer, intent( in) :: ncid
+ character (len=*), intent( in) :: name
+ integer (kind=MPI_OFFSET_KIND), intent( in) :: len
+ integer, intent(out) :: dimid
+ integer :: nf90mpi_def_dim
+
+ nf90mpi_def_dim = nfmpi_def_dim(ncid, name, len, dimid)
+ end function nf90mpi_def_dim
+ ! -----------
+ function nf90mpi_inq_dimid(ncid, name, dimid)
+ integer, intent( in) :: ncid
+ character (len=*), intent( in) :: name
+ integer, intent(out) :: dimid
+ integer :: nf90mpi_inq_dimid
+
+ nf90mpi_inq_dimid = nfmpi_inq_dimid(ncid, name, dimid)
+ end function nf90mpi_inq_dimid
+ ! -----------
+ function nf90mpi_rename_dim(ncid, dimid, name)
+ integer, intent( in) :: ncid
+ character (len=*), intent( in) :: name
+ integer, intent( in) :: dimid
+ integer :: nf90mpi_rename_dim
+
+ nf90mpi_rename_dim = nfmpi_rename_dim(ncid, dimid, name)
+ end function nf90mpi_rename_dim
+ ! -----------
+ function nf90mpi_inquire_dimension(ncid, dimid, name, len)
+ integer, intent( in) :: ncid, dimid
+ character (len=*), optional, intent(out) :: name
+ integer (kind=MPI_OFFSET_KIND), optional, intent(out) :: len
+ integer :: nf90mpi_inquire_dimension
+
+ character (len=nf90_max_name) :: dimName
+ integer (kind=MPI_OFFSET_KIND) :: length
+
+ nf90mpi_inquire_dimension = nfmpi_inq_dim(ncid, dimid, dimName, length)
+ if(present(name)) name = trim(dimName)
+ if(present(len )) len = length
+ end function nf90mpi_inquire_dimension
+ ! -----------
diff --git a/src/libf90/file.f90 b/src/libf90/file.f90
new file mode 100644
index 0000000..53f7267
--- /dev/null
+++ b/src/libf90/file.f90
@@ -0,0 +1,331 @@
+!
+! Copyright (C) 2013, Northwestern University and Argonne National Laboratory
+! See COPYRIGHT notice in top-level directory.
+!
+! $Id: file.f90 2013 2015-02-18 17:14:26Z wkliao $
+!
+! This file is taken from netcdf_file.f90 with changes for PnetCDF use
+!
+!
+
+! This is part of the netCDF F90 API, or. Copyright 2006 UCAR. See COPYRIGHT file
+! for details.
+
+! This file contains the netcdf file functions that are shared by
+! netcdf-3 and netcdf-4.
+
+! $Id: file.f90 2013 2015-02-18 17:14:26Z wkliao $
+! -------
+function nf90mpi_inq_libvers()
+ character(len = 80) :: nf90mpi_inq_libvers
+
+ nf90mpi_inq_libvers = nfmpi_inq_libvers()
+end function nf90mpi_inq_libvers
+! -------
+function nf90mpi_strerror(ncerr)
+ integer, intent( in) :: ncerr
+ character(len = 80) :: nf90mpi_strerror
+
+ nf90mpi_strerror = nfmpi_strerror(ncerr)
+end function nf90mpi_strerror
+! -------
+!
+! File level control routines:
+!
+! function nf90mpi_inq_base_pe(ncid, pe)
+! integer, intent( in) :: ncid
+! integer, intent(out) :: pe
+! integer :: nf90mpi_inq_base_pe
+!
+! nf90mpi_inq_base_pe = nfmpi_inq_base_pe(ncid, pe)
+! end function nf90mpi_inq_base_pe
+! -------
+! function nf90mpi_set_base_pe(ncid, pe)
+! integer, intent( in) :: ncid, pe
+! integer :: nf90mpi_set_base_pe
+!
+! nf90mpi_set_base_pe = nfmpi_set_base_pe(ncid, pe)
+! end function nf90mpi_set_base_pe
+! -------
+function nf90mpi_create(mpi_comm, path, cmode, mpi_info, ncid)
+ character (len = *), intent( in) :: path
+ integer, intent( in) :: mpi_comm, cmode, mpi_info
+ integer, intent(out) :: ncid
+ integer :: nf90mpi_create
+
+ nf90mpi_create = nfmpi_create(mpi_comm, path, cmode, mpi_info, ncid)
+end function nf90mpi_create
+! -------
+function nf90mpi_open(mpi_comm, path, omode, mpi_info, ncid)
+ character (len = *), intent( in) :: path
+ integer, intent( in) :: mpi_comm, omode, mpi_info
+ integer, intent(out) :: ncid
+ integer :: nf90mpi_open
+
+ nf90mpi_open = nfmpi_open(mpi_comm, path, omode, mpi_info, ncid)
+end function nf90mpi_open
+! -------
+function nf90mpi_set_fill(ncid, fillmode, old_mode)
+ integer, intent( in) :: ncid, fillmode
+ integer, intent(out) :: old_mode
+ integer :: nf90mpi_set_fill
+
+ nf90mpi_set_fill = nfmpi_set_fill(ncid, fillmode, old_mode)
+end function nf90mpi_set_fill
+! -------
+function nf90mpi_redef(ncid)
+ integer, intent( in) :: ncid
+ integer :: nf90mpi_redef
+
+ nf90mpi_redef = nfmpi_redef(ncid)
+end function nf90mpi_redef
+! -------
+function nf90mpi_enddef(ncid, h_minfree, v_align, v_minfree, r_align)
+ integer, intent(in) :: ncid
+ integer (kind = MPI_OFFSET_KIND), optional, intent(in) :: h_minfree
+ integer (kind = MPI_OFFSET_KIND), optional, intent(in) :: v_align
+ integer (kind = MPI_OFFSET_KIND), optional, intent(in) :: v_minfree
+ integer (kind = MPI_OFFSET_KIND), optional, intent(in) :: r_align
+ integer :: nf90mpi_enddef
+
+ integer (kind = MPI_OFFSET_KIND) :: hMinFree, VAlign, VMinFree, RAlign
+
+ if (.not. any( (/ present(h_minfree), present(v_align), &
+ present(v_minfree), present(r_align) /) ) )then
+ nf90mpi_enddef = nfmpi_enddef(ncid)
+ else
+ ! Default values per the man page
+ hMinFree = 0; VMinFree = 0
+ VAlign = 4; RAlign = 4
+ if(present(h_minfree)) HMinFree = h_minfree
+ if(present(v_align )) VAlign = v_align
+ if(present(v_minfree)) VMinFree = v_minfree
+ if(present(r_align )) RAlign = r_align
+ nf90mpi_enddef = nfmpi__enddef(ncid, hMinFree, VAlign, VMinFree, RAlign)
+ end if
+end function nf90mpi_enddef
+! -------
+function nf90mpi_sync(ncid)
+ integer, intent( in) :: ncid
+ integer :: nf90mpi_sync
+
+ nf90mpi_sync = nfmpi_sync(ncid)
+end function nf90mpi_sync
+! -------
+function nf90mpi_abort(ncid)
+ integer, intent( in) :: ncid
+ integer :: nf90mpi_abort
+
+ nf90mpi_abort = nfmpi_abort(ncid)
+end function nf90mpi_abort
+! -------
+function nf90mpi_close(ncid)
+ integer, intent( in) :: ncid
+ integer :: nf90mpi_close
+
+ nf90mpi_close = nfmpi_close(ncid)
+end function nf90mpi_close
+! -------
+function nf90mpi_delete(name, mpi_info)
+ character(len = *), intent( in) :: name
+ integer :: nf90mpi_delete
+ integer, intent( in) :: mpi_info
+
+ nf90mpi_delete = nfmpi_delete(name, mpi_info)
+end function nf90mpi_delete
+
+!
+! A single file level inquiry routine
+!
+function nf90mpi_inquire(ncid, nDimensions, nVariables, nAttributes, unlimitedDimId, formatNum)
+ integer, intent( in) :: ncid
+ integer, optional, intent(out) :: nDimensions, nVariables, nAttributes, unlimitedDimId, formatNum
+ integer :: nf90mpi_inquire
+
+ integer :: nDims, nVars, nGAtts, unlimDimId, frmt
+
+ nf90mpi_inquire = nfmpi_inq(ncid, nDims, nVars, nGAtts, unlimDimId)
+ if(present(nDimensions)) nDimensions = nDims
+ if(present(nVariables)) nVariables = nVars
+ if(present(nAttributes)) nAttributes = nGAtts
+ if(present(unlimitedDimId)) unlimitedDimId = unlimDimId
+ if(present(formatNum)) then
+ nf90mpi_inquire = nfmpi_inq_format(ncid, frmt)
+ formatNum = frmt
+ endif
+end function nf90mpi_inquire
+
+! -------
+function nf90mpi_inq_striping(ncid, striping_size, striping_count)
+ integer, intent( in) :: ncid
+ integer, intent(out) :: striping_size
+ integer, intent(out) :: striping_count
+ integer :: nf90mpi_inq_striping
+
+ nf90mpi_inq_striping = nfmpi_inq_striping(ncid, striping_size, striping_count)
+end function nf90mpi_inq_striping
+
+! -------
+function nf90mpi_begin_indep_data(ncid)
+ integer, intent( in) :: ncid
+ integer :: nf90mpi_begin_indep_data
+
+ nf90mpi_begin_indep_data = nfmpi_begin_indep_data(ncid)
+end function nf90mpi_begin_indep_data
+
+! -------
+function nf90mpi_end_indep_data(ncid)
+ integer, intent( in) :: ncid
+ integer :: nf90mpi_end_indep_data
+
+ nf90mpi_end_indep_data = nfmpi_end_indep_data(ncid)
+end function nf90mpi_end_indep_data
+
+! -------
+function nf90mpi_inq_put_size(ncid, put_size)
+ integer, intent( in) :: ncid
+ integer (kind = MPI_OFFSET_KIND), intent(out) :: put_size
+ integer :: nf90mpi_inq_put_size
+
+ nf90mpi_inq_put_size = nfmpi_inq_put_size(ncid, put_size)
+end function nf90mpi_inq_put_size
+
+! -------
+function nf90mpi_inq_get_size(ncid, get_size)
+ integer, intent( in) :: ncid
+ integer (kind = MPI_OFFSET_KIND), intent(out) :: get_size
+ integer :: nf90mpi_inq_get_size
+
+ nf90mpi_inq_get_size = nfmpi_inq_get_size(ncid, get_size)
+end function nf90mpi_inq_get_size
+
+! -------
+function nf90mpi_inq_header_size(ncid, h_size)
+ integer, intent( in) :: ncid
+ integer (kind = MPI_OFFSET_KIND), intent(out) :: h_size
+ integer :: nf90mpi_inq_header_size
+
+ nf90mpi_inq_header_size = nfmpi_inq_header_size(ncid, h_size)
+end function nf90mpi_inq_header_size
+
+! -------
+function nf90mpi_inq_header_extent(ncid, h_extent)
+ integer, intent( in) :: ncid
+ integer (kind = MPI_OFFSET_KIND), intent(out) :: h_extent
+ integer :: nf90mpi_inq_header_extent
+
+ nf90mpi_inq_header_extent = nfmpi_inq_header_extent(ncid, h_extent)
+end function nf90mpi_inq_header_extent
+
+! -------
+function nf90mpi_inq_varoffset(ncid, varid, offset)
+ integer, intent( in) :: ncid, varid
+ integer (kind = MPI_OFFSET_KIND), intent(out) :: offset
+ integer :: nf90mpi_inq_varoffset
+
+ nf90mpi_inq_varoffset = nfmpi_inq_varoffset(ncid, varid, offset)
+end function nf90mpi_inq_varoffset
+
+! -------
+function nf90mpi_inq_nreqs(ncid, nreqs)
+ integer, intent( in) :: ncid
+ integer, intent(out) :: nreqs
+ integer :: nf90mpi_inq_nreqs
+
+ nf90mpi_inq_nreqs = nfmpi_inq_nreqs(ncid, nreqs)
+end function nf90mpi_inq_nreqs
+
+! -------
+function nf90mpi_inq_file_info(ncid, mpi_info)
+ integer, intent( in) :: ncid
+ integer, intent(out) :: mpi_info
+ integer :: nf90mpi_inq_file_info
+
+ nf90mpi_inq_file_info = nfmpi_inq_file_info(ncid, mpi_info)
+end function nf90mpi_inq_file_info
+
+! -------
+function nf90mpi_get_file_info(ncid, mpi_info)
+ integer, intent( in) :: ncid
+ integer, intent(out) :: mpi_info
+ integer :: nf90mpi_get_file_info
+
+ nf90mpi_get_file_info = nfmpi_get_file_info(ncid, mpi_info)
+end function nf90mpi_get_file_info
+
+! -------
+function nf90mpi_inq_malloc_size(size)
+ integer (kind = MPI_OFFSET_KIND), intent(out) :: size
+ integer :: nf90mpi_inq_malloc_size
+
+ nf90mpi_inq_malloc_size = nfmpi_inq_malloc_size(size)
+end function nf90mpi_inq_malloc_size
+
+! -------
+function nf90mpi_inq_malloc_max_size(size)
+ integer (kind = MPI_OFFSET_KIND), intent(out) :: size
+ integer :: nf90mpi_inq_malloc_max_size
+
+ nf90mpi_inq_malloc_max_size = nfmpi_inq_malloc_max_size(size)
+end function nf90mpi_inq_malloc_max_size
+
+! -------
+function nf90mpi_inq_malloc_list()
+ integer :: nf90mpi_inq_malloc_list
+
+ nf90mpi_inq_malloc_list = nfmpi_inq_malloc_list()
+end function nf90mpi_inq_malloc_list
+
+! -------
+function nf90mpi_inq_files_opened(nfiles, ncids)
+ integer, intent(out) :: nfiles
+ integer, dimension(:), intent(out) :: ncids
+ integer :: nf90mpi_inq_files_opened
+
+ nf90mpi_inq_files_opened = nfmpi_inq_files_opened(nfiles, ncids)
+end function nf90mpi_inq_files_opened
+
+! -------
+function nf90mpi_inq_num_rec_vars(ncid, nvars)
+ integer, intent( in) :: ncid
+ integer, intent(out) :: nvars
+ integer :: nf90mpi_inq_num_rec_vars
+
+ nf90mpi_inq_num_rec_vars = nfmpi_inq_num_rec_vars(ncid, nvars)
+end function nf90mpi_inq_num_rec_vars
+
+! -------
+function nf90mpi_inq_num_fix_vars(ncid, nvars)
+ integer, intent( in) :: ncid
+ integer, intent(out) :: nvars
+ integer :: nf90mpi_inq_num_fix_vars
+
+ nf90mpi_inq_num_fix_vars = nfmpi_inq_num_fix_vars(ncid, nvars)
+end function nf90mpi_inq_num_fix_vars
+
+! -------
+function nf90mpi_inq_recsize(ncid, recsize)
+ integer, intent( in) :: ncid
+ integer (kind = MPI_OFFSET_KIND), intent(out) :: recsize
+ integer :: nf90mpi_inq_recsize
+
+ nf90mpi_inq_recsize = nfmpi_inq_recsize(ncid, recsize)
+end function nf90mpi_inq_recsize
+
+! -------
+function nf90mpi_set_default_format(new_format, old_format)
+ integer, intent( in) :: new_format
+ integer, intent(out) :: old_format
+ integer :: nf90mpi_set_default_format
+
+ nf90mpi_set_default_format = nfmpi_set_default_format(new_format, old_format)
+end function nf90mpi_set_default_format
+
+! -------
+function nf90mpi_inq_default_format(default_format)
+ integer, intent(out) :: default_format
+ integer :: nf90mpi_inq_default_format
+
+ nf90mpi_inq_default_format = nfmpi_inq_default_format(default_format)
+end function nf90mpi_inq_default_format
+
diff --git a/src/libf90/getput_text.m4 b/src/libf90/getput_text.m4
new file mode 100644
index 0000000..0ffd27c
--- /dev/null
+++ b/src/libf90/getput_text.m4
@@ -0,0 +1,251 @@
+dnl Process this m4 file to produce 'C' language file.
+dnl
+dnl If you see this line, you can ignore the next one.
+! Do not edit this file. It is produced from the corresponding .m4 source
+dnl
+!
+! Copyright (C) 2013, Northwestern University and Argonne National Laboratory
+! See COPYRIGHT notice in top-level directory.
+!
+! $Id: getput_text.m4 1882 2014-11-21 17:44:34Z wkliao $
+!
+
+dnl
+dnl TEXTVAR1(ncid, varid, values, start, count, stride, map)
+dnl
+define(`TEXTVAR1',dnl
+`dnl
+ function nf90mpi_$1_var_text$3(ncid, varid, values, start, count, stride, map)
+ integer, intent(in) :: ncid, varid
+ character (len=*), intent($2) :: values
+ integer (kind=MPI_OFFSET_KIND), dimension(:), optional, intent(in) :: start, count, stride, map
+
+ integer :: nf90mpi_$1_var_text$3
+ integer (kind=MPI_OFFSET_KIND), dimension(nf90_max_var_dims) :: localStart, localCount, localStride
+
+ ! Set local arguments to default values
+ localStart (:) = 1
+ localCount (1) = LEN(values); localCount (2:) = 1
+ localStride(:) = 1
+
+ if(present(start)) localStart (:size(start) ) = start(:)
+ if(present(count)) localCount (:size(count) ) = count(:)
+ if(present(stride)) localStride(:size(stride)) = stride(:)
+ if(present(map)) then
+ nf90mpi_$1_var_text$3 = nfmpi_$1_varm_text$3(ncid, varid, localStart, localCount, localStride, map, values)
+ else
+ nf90mpi_$1_var_text$3 = nfmpi_$1_vars_text$3(ncid, varid, localStart, localCount, localStride, values)
+ end if
+ end function nf90mpi_$1_var_text$3
+')dnl
+
+!
+! Independent put APIs
+!
+
+TEXTVAR1(put, in)
+TEXTVAR1(get, out)
+
+!
+! Collective put APIs
+!
+
+TEXTVAR1(put, in, _all)
+TEXTVAR1(get, out, _all)
+
+
+dnl
+dnl TEXTVAR(ncid, varid, values, start, count, stride, map)
+dnl
+define(`TEXTVAR',dnl
+`dnl
+ function nf90mpi_$1_var_$2_text$6(ncid, varid, values, start, count, stride, map)
+ integer, intent(in) :: ncid, varid
+ character (len=*), dimension($3), intent($5) :: values
+ integer (kind=MPI_OFFSET_KIND), dimension(:), optional, intent(in) :: start, count, stride, map
+
+ integer :: nf90mpi_$1_var_$2_text$6
+ integer (kind=MPI_OFFSET_KIND), dimension(nf90_max_var_dims) :: localStart, localCount, localStride, localMap
+ integer :: numDims, counter
+
+ ! Set local arguments to default values
+ numDims = substr(`$2', `0', `1')
+
+ localStart (: ) = 1
+ localCount (:numDims+1) = (/ LEN(values($4)), shape(values) /)
+ localCount (numDims+2:) = 0
+ localStride(: ) = 1
+ ! localMap (:numDims ) = (/ 1, (product(localCount(:counter)), counter = 1, numDims - 1) /)
+ localMap(1) = 1
+ do counter = 1, numDims - 1
+ localMap(counter+1) = localMap(counter) * localCount(counter)
+ enddo
+
+ if(present(start)) localStart (:size(start)) = start(:)
+ if(present(count)) localCount (:size(count)) = count(:)
+ if(present(stride)) localStride(:size(stride)) = stride(:)
+ if(present(map)) then
+ localMap (:size(map)) = map(:)
+ nf90mpi_$1_var_$2_text$6 = &
+ nfmpi_$1_varm_text$6(ncid, varid, localStart, localCount, localStride, localMap, values($4))
+ else
+ nf90mpi_$1_var_$2_text$6 = &
+ nfmpi_$1_vars_text$6(ncid, varid, localStart, localCount, localStride, values($4))
+ end if
+ end function nf90mpi_$1_var_$2_text$6
+')dnl
+
+TEXTVAR(put, 1D, :, 1, in)
+TEXTVAR(put, 2D, `:,:', `1,1', in)
+TEXTVAR(put, 3D, `:,:,:', `1,1,1', in)
+TEXTVAR(put, 4D, `:,:,:,:', `1,1,1,1', in)
+TEXTVAR(put, 5D, `:,:,:,:,:', `1,1,1,1,1', in)
+TEXTVAR(put, 6D, `:,:,:,:,:,:', `1,1,1,1,1,1', in)
+TEXTVAR(put, 7D, `:,:,:,:,:,:,:', `1,1,1,1,1,1,1', in)
+
+TEXTVAR(get, 1D, :, 1, out)
+TEXTVAR(get, 2D, `:,:', `1,1', out)
+TEXTVAR(get, 3D, `:,:,:', `1,1,1', out)
+TEXTVAR(get, 4D, `:,:,:,:', `1,1,1,1', out)
+TEXTVAR(get, 5D, `:,:,:,:,:', `1,1,1,1,1', out)
+TEXTVAR(get, 6D, `:,:,:,:,:,:', `1,1,1,1,1,1', out)
+TEXTVAR(get, 7D, `:,:,:,:,:,:,:', `1,1,1,1,1,1,1', out)
+
+!
+! Collective APIs
+!
+
+TEXTVAR(put, 1D, :, 1, in, _all)
+TEXTVAR(put, 2D, `:,:', `1,1', in, _all)
+TEXTVAR(put, 3D, `:,:,:', `1,1,1', in, _all)
+TEXTVAR(put, 4D, `:,:,:,:', `1,1,1,1', in, _all)
+TEXTVAR(put, 5D, `:,:,:,:,:', `1,1,1,1,1', in, _all)
+TEXTVAR(put, 6D, `:,:,:,:,:,:', `1,1,1,1,1,1', in, _all)
+TEXTVAR(put, 7D, `:,:,:,:,:,:,:', `1,1,1,1,1,1,1', in, _all)
+
+TEXTVAR(get, 1D, :, 1, out, _all)
+TEXTVAR(get, 2D, `:,:', `1,1', out, _all)
+TEXTVAR(get, 3D, `:,:,:', `1,1,1', out, _all)
+TEXTVAR(get, 4D, `:,:,:,:', `1,1,1,1', out, _all)
+TEXTVAR(get, 5D, `:,:,:,:,:', `1,1,1,1,1', out, _all)
+TEXTVAR(get, 6D, `:,:,:,:,:,:', `1,1,1,1,1,1', out, _all)
+TEXTVAR(get, 7D, `:,:,:,:,:,:,:', `1,1,1,1,1,1,1', out, _all)
+
+!
+! Nonblocking APIs
+!
+
+dnl
+dnl NBTEXTVAR1(ncid, varid, values, req, start, count, stride, map)
+dnl
+define(`NBTEXTVAR1',dnl
+`dnl
+ function nf90mpi_$1_var_text(ncid, varid, values, req, start, count, stride, map)
+ integer, intent( in) :: ncid, varid
+ integer, intent(out) :: req
+ character (len=*), intent( $2) :: values
+ integer (kind=MPI_OFFSET_KIND), dimension(:), optional, intent( in) :: start, count, stride, map
+
+ integer :: nf90mpi_$1_var_text
+ integer (kind=MPI_OFFSET_KIND), dimension(nf90_max_var_dims) :: localStart, localCount, localStride
+
+ ! Set local arguments to default values
+ localStart (:) = 1
+ localCount (1) = LEN(values); localCount (2:) = 1
+ localStride(:) = 1
+
+ if(present(start)) localStart (:size(start) ) = start(:)
+ if(present(count)) localCount (:size(count) ) = count(:)
+ if(present(stride)) localStride(:size(stride)) = stride(:)
+ if(present(map)) then
+ nf90mpi_$1_var_text = nfmpi_$1_varm_text(ncid, varid, localStart, localCount, localStride, map, values, req)
+ else
+ nf90mpi_$1_var_text = nfmpi_$1_vars_text(ncid, varid, localStart, localCount, localStride, values, req)
+ end if
+ end function nf90mpi_$1_var_text
+')dnl
+
+!
+! iput APIs
+!
+
+NBTEXTVAR1(iput, in)
+NBTEXTVAR1(iget, out)
+
+!
+! bput APIs
+!
+
+NBTEXTVAR1(bput, in)
+
+
+dnl
+dnl NBTEXTVAR(ncid, varid, values, req, start, count, stride, map)
+dnl
+define(`NBTEXTVAR',dnl
+`dnl
+ function nf90mpi_$1_var_$2_text(ncid, varid, values, req, start, count, stride, map)
+ integer, intent( in) :: ncid, varid
+ integer, intent(out) :: req
+ character (len=*), dimension($3), intent( $5) :: values
+ integer (kind=MPI_OFFSET_KIND), dimension(:), optional, intent( in) :: start, count, stride, map
+
+ integer :: nf90mpi_$1_var_$2_text
+ integer (kind=MPI_OFFSET_KIND), dimension(nf90_max_var_dims) :: localStart, localCount, localStride, localMap
+ integer :: numDims, counter
+
+ ! Set local arguments to default values
+ numDims = substr(`$2', `0', `1')
+
+ localStart (: ) = 1
+ localCount ( :numDims+1) = (/ LEN(values($4)), shape(values) /)
+ localCount (numDims+2:) = 0
+ localStride(: ) = 1
+ ! localMap (:numDims ) = (/ 1, (product(localCount(:counter)), counter = 1, numDims - 1) /)
+ localMap(1) = 1
+ do counter = 1, numDims - 1
+ localMap(counter+1) = localMap(counter) * localCount(counter)
+ enddo
+
+ if(present(start)) localStart (:size(start)) = start(:)
+ if(present(count)) localCount (:size(count)) = count(:)
+ if(present(stride)) localStride(:size(stride)) = stride(:)
+ if(present(map)) then
+ localMap (:size(map)) = map(:)
+ nf90mpi_$1_var_$2_text = &
+ nfmpi_$1_varm_text(ncid, varid, localStart, localCount, localStride, localMap, values($4), req)
+ else
+ nf90mpi_$1_var_$2_text = &
+ nfmpi_$1_vars_text(ncid, varid, localStart, localCount, localStride, values($4), req)
+ end if
+ end function nf90mpi_$1_var_$2_text
+')dnl
+
+NBTEXTVAR(iput, 1D, :, 1, in)
+NBTEXTVAR(iput, 2D, `:,:', `1,1', in)
+NBTEXTVAR(iput, 3D, `:,:,:', `1,1,1', in)
+NBTEXTVAR(iput, 4D, `:,:,:,:', `1,1,1,1', in)
+NBTEXTVAR(iput, 5D, `:,:,:,:,:', `1,1,1,1,1', in)
+NBTEXTVAR(iput, 6D, `:,:,:,:,:,:', `1,1,1,1,1,1', in)
+NBTEXTVAR(iput, 7D, `:,:,:,:,:,:,:', `1,1,1,1,1,1,1', in)
+
+NBTEXTVAR(iget, 1D, :, 1, out)
+NBTEXTVAR(iget, 2D, `:,:', `1,1', out)
+NBTEXTVAR(iget, 3D, `:,:,:', `1,1,1', out)
+NBTEXTVAR(iget, 4D, `:,:,:,:', `1,1,1,1', out)
+NBTEXTVAR(iget, 5D, `:,:,:,:,:', `1,1,1,1,1', out)
+NBTEXTVAR(iget, 6D, `:,:,:,:,:,:', `1,1,1,1,1,1', out)
+NBTEXTVAR(iget, 7D, `:,:,:,:,:,:,:', `1,1,1,1,1,1,1', out)
+
+!
+! bput APIs
+!
+
+NBTEXTVAR(bput, 1D, :, 1, in)
+NBTEXTVAR(bput, 2D, `:,:', `1,1', in)
+NBTEXTVAR(bput, 3D, `:,:,:', `1,1,1', in)
+NBTEXTVAR(bput, 4D, `:,:,:,:', `1,1,1,1', in)
+NBTEXTVAR(bput, 5D, `:,:,:,:,:', `1,1,1,1,1', in)
+NBTEXTVAR(bput, 6D, `:,:,:,:,:,:', `1,1,1,1,1,1', in)
+NBTEXTVAR(bput, 7D, `:,:,:,:,:,:,:', `1,1,1,1,1,1,1', in)
+
diff --git a/src/libf90/getput_var.m4 b/src/libf90/getput_var.m4
new file mode 100644
index 0000000..9849fe9
--- /dev/null
+++ b/src/libf90/getput_var.m4
@@ -0,0 +1,678 @@
+dnl Process this m4 file to produce 'C' language file.
+dnl
+dnl If you see this line, you can ignore the next one.
+! Do not edit this file. It is produced from the corresponding .m4 source
+dnl
+!
+! Copyright (C) 2013, Northwestern University and Argonne National Laboratory
+! See COPYRIGHT notice in top-level directory.
+!
+! $Id: getput_var.m4 2221 2015-12-12 00:39:15Z wkliao $
+!
+
+dnl
+dnl VAR_SCALAR
+dnl
+define(`VAR_SCALAR',dnl
+`dnl
+ function nf90mpi_$1_var_$3$2(ncid, varid, values, start, bufcount, buftype)
+ integer, intent( in) :: ncid, varid
+ $4 (kind=$3), intent($6) :: values
+ integer (kind=MPI_OFFSET_KIND), dimension(:), optional, intent( in) :: start
+ integer (kind=MPI_OFFSET_KIND), optional, intent( in) :: bufcount
+ integer, optional, intent( in) :: buftype
+
+ integer :: nf90mpi_$1_var_$3$2
+ integer (kind=MPI_OFFSET_KIND), dimension(nf90_max_var_dims) :: localIndex
+
+ ! Set local arguments to default values
+ localIndex(:) = 1
+ if (present(start)) localIndex(:size(start)) = start(:)
+
+ if (present(buftype)) then
+ nf90mpi_$1_var_$3$2 = nfmpi_$1_var1$2(ncid, varid, localIndex, values, bufcount, buftype)
+ else
+ nf90mpi_$1_var_$3$2 = nfmpi_$1_var1_$5$2(ncid, varid, localIndex, values)
+ endif
+ end function nf90mpi_$1_var_$3$2
+')dnl
+
+VAR_SCALAR(put, , OneByteInt, integer, int1, in)
+VAR_SCALAR(put, , TwoByteInt, integer, int2, INTENTV)
+VAR_SCALAR(put, , FourByteInt, integer, int, INTENTV)
+VAR_SCALAR(put, , FourByteReal, real, real, INTENTV)
+VAR_SCALAR(put, , EightByteReal, real, double, INTENTV)
+VAR_SCALAR(put, , EightByteInt, integer, int8, INTENTV)
+
+VAR_SCALAR(put, _all, OneByteInt, integer, int1, in)
+VAR_SCALAR(put, _all, TwoByteInt, integer, int2, INTENTV)
+VAR_SCALAR(put, _all, FourByteInt, integer, int, INTENTV)
+VAR_SCALAR(put, _all, FourByteReal, real, real, INTENTV)
+VAR_SCALAR(put, _all, EightByteReal, real, double, INTENTV)
+VAR_SCALAR(put, _all, EightByteInt, integer, int8, INTENTV)
+
+VAR_SCALAR(get, , OneByteInt, integer, int1, out)
+VAR_SCALAR(get, , TwoByteInt, integer, int2, out)
+VAR_SCALAR(get, , FourByteInt, integer, int, out)
+VAR_SCALAR(get, , FourByteReal, real, real, out)
+VAR_SCALAR(get, , EightByteReal, real, double, out)
+VAR_SCALAR(get, , EightByteInt, integer, int8, out)
+
+VAR_SCALAR(get, _all, OneByteInt, integer, int1, out)
+VAR_SCALAR(get, _all, TwoByteInt, integer, int2, out)
+VAR_SCALAR(get, _all, FourByteInt, integer, int, out)
+VAR_SCALAR(get, _all, FourByteReal, real, real, out)
+VAR_SCALAR(get, _all, EightByteReal, real, double, out)
+VAR_SCALAR(get, _all, EightByteInt, integer, int8, out)
+
+dnl
+dnl NBVAR1(ncid, varid, values, start, count, req)
+dnl
+define(`NBVAR1',dnl
+`dnl
+ function nf90mpi_$1_var_$2(ncid, varid, values, req, start, bufcount, buftype)
+ integer, intent( in) :: ncid, varid
+ $3 (kind=$2), intent($5) :: values
+ integer, intent(out) :: req
+ integer (kind=MPI_OFFSET_KIND), dimension(:), optional, intent( in) :: start
+ integer (kind=MPI_OFFSET_KIND), optional, intent( in) :: bufcount
+ integer, optional, intent( in) :: buftype
+
+ integer :: nf90mpi_$1_var_$2
+ integer (kind=MPI_OFFSET_KIND), dimension(nf90_max_var_dims) :: localIndex
+
+ ! Set local arguments to default values
+ localIndex(:) = 1
+ if (present(start)) localIndex(:size(start)) = start(:)
+
+ if (present(buftype)) then
+ nf90mpi_$1_var_$2 = nfmpi_$1_var1(ncid, varid, localIndex, values, bufcount, buftype, req)
+ else
+ nf90mpi_$1_var_$2 = nfmpi_$1_var1_$4(ncid, varid, localIndex, values, req)
+ endif
+ end function nf90mpi_$1_var_$2
+')dnl
+
+!
+! Nonblocking iput APIs
+!
+
+NBVAR1(iput, OneByteInt, integer, int1, in)
+NBVAR1(iput, TwoByteInt, integer, int2, INTENTV)
+NBVAR1(iput, FourByteInt, integer, int, INTENTV)
+NBVAR1(iput, FourByteReal, real, real, INTENTV)
+NBVAR1(iput, EightByteReal, real, double, INTENTV)
+NBVAR1(iput, EightByteInt, integer, int8, INTENTV)
+
+!
+! Nonblocking iget APIs
+!
+
+NBVAR1(iget, OneByteInt, integer, int1, out)
+NBVAR1(iget, TwoByteInt, integer, int2, out)
+NBVAR1(iget, FourByteInt, integer, int, out)
+NBVAR1(iget, FourByteReal, real, real, out)
+NBVAR1(iget, EightByteReal, real, double, out)
+NBVAR1(iget, EightByteInt, integer, int8, out)
+
+!
+! Nonblocking bput APIs
+!
+
+NBVAR1(bput, OneByteInt, integer, int1, in)
+NBVAR1(bput, TwoByteInt, integer, int2, INTENTV)
+NBVAR1(bput, FourByteInt, integer, int, INTENTV)
+NBVAR1(bput, FourByteReal, real, real, INTENTV)
+NBVAR1(bput, EightByteReal, real, double, INTENTV)
+NBVAR1(bput, EightByteInt, integer, int8, INTENTV)
+
+dnl
+dnl VAR(ncid, varid, values, start, count, stride, map)
+dnl
+define(`VAR',dnl
+`dnl
+ function nf90mpi_$1_var_$2_$3$8(ncid, varid, values, start, count, stride, map, bufcount, buftype)
+ integer, intent( in) :: ncid, varid
+ $4 (kind=$3), dimension($6), intent( $7) :: values
+ integer (kind=MPI_OFFSET_KIND), dimension(:), optional, intent( in) :: start, count, stride, map
+ integer (kind=MPI_OFFSET_KIND), optional, intent( in) :: bufcount
+ integer, optional, intent( in) :: buftype
+
+ integer :: nf90mpi_$1_var_$2_$3$8
+ integer (kind=MPI_OFFSET_KIND), dimension(nf90_max_var_dims) :: localStart, localCount, localStride, localMap
+ integer :: numDims, counter
+
+ ! Set local arguments to default values
+ numDims = substr(`$2', `0', `1')
+ localStart (: ) = 1
+ localCount (:numDims ) = shape(values)
+ localCount (numDims+1:) = 1
+ localStride(: ) = 1
+ ! localMap (:numDims ) = (/ 1, (product(localCount(:counter)), counter = 1, numDims - 1) /)
+ localMap(1) = 1
+ do counter = 1, numDims - 1
+ localMap(counter+1) = localMap(counter) * localCount(counter)
+ enddo
+
+ if (present(start)) localStart (:size(start) ) = start(:)
+ if (present(count)) localCount (:size(count) ) = count(:)
+ if (present(stride)) localStride(:size(stride)) = stride(:)
+ if (present(map)) then
+ localMap (:size(map)) = map(:)
+ if (present(buftype)) then
+ nf90mpi_$1_var_$2_$3$8 = &
+ nfmpi_$1_varm$8(ncid, varid, localStart, localCount, localStride, localMap, values, bufcount, buftype)
+ else
+ nf90mpi_$1_var_$2_$3$8 = &
+ nfmpi_$1_varm_$5$8(ncid, varid, localStart, localCount, localStride, localMap, values)
+ endif
+ else if (present(stride)) then
+ if (present(buftype)) then
+ nf90mpi_$1_var_$2_$3$8 = &
+ nfmpi_$1_vars$8(ncid, varid, localStart, localCount, localStride, values, bufcount, buftype)
+ else
+ nf90mpi_$1_var_$2_$3$8 = &
+ nfmpi_$1_vars_$5$8(ncid, varid, localStart, localCount, localStride, values)
+ endif
+ else
+ if (present(buftype)) then
+ nf90mpi_$1_var_$2_$3$8 = &
+ nfmpi_$1_vara$8(ncid, varid, localStart, localCount, values, bufcount, buftype)
+ else
+ nf90mpi_$1_var_$2_$3$8 = &
+ nfmpi_$1_vara_$5$8(ncid, varid, localStart, localCount, values)
+ endif
+ end if
+ end function nf90mpi_$1_var_$2_$3$8
+')dnl
+
+!
+! Independent put APIs
+!
+
+VAR(put, 1D, OneByteInt, integer, int1, :, in)
+VAR(put, 2D, OneByteInt, integer, int1, `:,:', in)
+VAR(put, 3D, OneByteInt, integer, int1, `:,:,:', in)
+VAR(put, 4D, OneByteInt, integer, int1, `:,:,:,:', in)
+VAR(put, 5D, OneByteInt, integer, int1, `:,:,:,:,:', in)
+VAR(put, 6D, OneByteInt, integer, int1, `:,:,:,:,:,:', in)
+VAR(put, 7D, OneByteInt, integer, int1, `:,:,:,:,:,:,:', in)
+
+VAR(put, 1D, TwoByteInt, integer, int2, :, INTENTV)
+VAR(put, 2D, TwoByteInt, integer, int2, `:,:', INTENTV)
+VAR(put, 3D, TwoByteInt, integer, int2, `:,:,:', INTENTV)
+VAR(put, 4D, TwoByteInt, integer, int2, `:,:,:,:', INTENTV)
+VAR(put, 5D, TwoByteInt, integer, int2, `:,:,:,:,:', INTENTV)
+VAR(put, 6D, TwoByteInt, integer, int2, `:,:,:,:,:,:', INTENTV)
+VAR(put, 7D, TwoByteInt, integer, int2, `:,:,:,:,:,:,:', INTENTV)
+
+VAR(put, 1D, FourByteInt, integer, int, :, INTENTV)
+VAR(put, 2D, FourByteInt, integer, int, `:,:', INTENTV)
+VAR(put, 3D, FourByteInt, integer, int, `:,:,:', INTENTV)
+VAR(put, 4D, FourByteInt, integer, int, `:,:,:,:', INTENTV)
+VAR(put, 5D, FourByteInt, integer, int, `:,:,:,:,:', INTENTV)
+VAR(put, 6D, FourByteInt, integer, int, `:,:,:,:,:,:', INTENTV)
+VAR(put, 7D, FourByteInt, integer, int, `:,:,:,:,:,:,:', INTENTV)
+
+VAR(put, 1D, FourByteReal, real, real, :, INTENTV)
+VAR(put, 2D, FourByteReal, real, real, `:,:', INTENTV)
+VAR(put, 3D, FourByteReal, real, real, `:,:,:', INTENTV)
+VAR(put, 4D, FourByteReal, real, real, `:,:,:,:', INTENTV)
+VAR(put, 5D, FourByteReal, real, real, `:,:,:,:,:', INTENTV)
+VAR(put, 6D, FourByteReal, real, real, `:,:,:,:,:,:', INTENTV)
+VAR(put, 7D, FourByteReal, real, real, `:,:,:,:,:,:,:', INTENTV)
+
+VAR(put, 1D, EightByteReal, real, double, :, INTENTV)
+VAR(put, 2D, EightByteReal, real, double, `:,:', INTENTV)
+VAR(put, 3D, EightByteReal, real, double, `:,:,:', INTENTV)
+VAR(put, 4D, EightByteReal, real, double, `:,:,:,:', INTENTV)
+VAR(put, 5D, EightByteReal, real, double, `:,:,:,:,:', INTENTV)
+VAR(put, 6D, EightByteReal, real, double, `:,:,:,:,:,:', INTENTV)
+VAR(put, 7D, EightByteReal, real, double, `:,:,:,:,:,:,:', INTENTV)
+
+VAR(put, 1D, EightByteInt, integer, int8, :, INTENTV)
+VAR(put, 2D, EightByteInt, integer, int8, `:,:', INTENTV)
+VAR(put, 3D, EightByteInt, integer, int8, `:,:,:', INTENTV)
+VAR(put, 4D, EightByteInt, integer, int8, `:,:,:,:', INTENTV)
+VAR(put, 5D, EightByteInt, integer, int8, `:,:,:,:,:', INTENTV)
+VAR(put, 6D, EightByteInt, integer, int8, `:,:,:,:,:,:', INTENTV)
+VAR(put, 7D, EightByteInt, integer, int8, `:,:,:,:,:,:,:', INTENTV)
+
+!
+! Independent get APIs
+!
+
+VAR(get, 1D, OneByteInt, integer, int1, :, out)
+VAR(get, 2D, OneByteInt, integer, int1, `:,:', out)
+VAR(get, 3D, OneByteInt, integer, int1, `:,:,:', out)
+VAR(get, 4D, OneByteInt, integer, int1, `:,:,:,:', out)
+VAR(get, 5D, OneByteInt, integer, int1, `:,:,:,:,:', out)
+VAR(get, 6D, OneByteInt, integer, int1, `:,:,:,:,:,:', out)
+VAR(get, 7D, OneByteInt, integer, int1, `:,:,:,:,:,:,:', out)
+
+VAR(get, 1D, TwoByteInt, integer, int2, :, out)
+VAR(get, 2D, TwoByteInt, integer, int2, `:,:', out)
+VAR(get, 3D, TwoByteInt, integer, int2, `:,:,:', out)
+VAR(get, 4D, TwoByteInt, integer, int2, `:,:,:,:', out)
+VAR(get, 5D, TwoByteInt, integer, int2, `:,:,:,:,:', out)
+VAR(get, 6D, TwoByteInt, integer, int2, `:,:,:,:,:,:', out)
+VAR(get, 7D, TwoByteInt, integer, int2, `:,:,:,:,:,:,:', out)
+
+VAR(get, 1D, FourByteInt, integer, int, :, out)
+VAR(get, 2D, FourByteInt, integer, int, `:,:', out)
+VAR(get, 3D, FourByteInt, integer, int, `:,:,:', out)
+VAR(get, 4D, FourByteInt, integer, int, `:,:,:,:', out)
+VAR(get, 5D, FourByteInt, integer, int, `:,:,:,:,:', out)
+VAR(get, 6D, FourByteInt, integer, int, `:,:,:,:,:,:', out)
+VAR(get, 7D, FourByteInt, integer, int, `:,:,:,:,:,:,:', out)
+
+VAR(get, 1D, FourByteReal, real, real, :, out)
+VAR(get, 2D, FourByteReal, real, real, `:,:', out)
+VAR(get, 3D, FourByteReal, real, real, `:,:,:', out)
+VAR(get, 4D, FourByteReal, real, real, `:,:,:,:', out)
+VAR(get, 5D, FourByteReal, real, real, `:,:,:,:,:', out)
+VAR(get, 6D, FourByteReal, real, real, `:,:,:,:,:,:', out)
+VAR(get, 7D, FourByteReal, real, real, `:,:,:,:,:,:,:', out)
+
+VAR(get, 1D, EightByteReal, real, double, :, out)
+VAR(get, 2D, EightByteReal, real, double, `:,:', out)
+VAR(get, 3D, EightByteReal, real, double, `:,:,:', out)
+VAR(get, 4D, EightByteReal, real, double, `:,:,:,:', out)
+VAR(get, 5D, EightByteReal, real, double, `:,:,:,:,:', out)
+VAR(get, 6D, EightByteReal, real, double, `:,:,:,:,:,:', out)
+VAR(get, 7D, EightByteReal, real, double, `:,:,:,:,:,:,:', out)
+
+VAR(get, 1D, EightByteInt, integer, int8, :, out)
+VAR(get, 2D, EightByteInt, integer, int8, `:,:', out)
+VAR(get, 3D, EightByteInt, integer, int8, `:,:,:', out)
+VAR(get, 4D, EightByteInt, integer, int8, `:,:,:,:', out)
+VAR(get, 5D, EightByteInt, integer, int8, `:,:,:,:,:', out)
+VAR(get, 6D, EightByteInt, integer, int8, `:,:,:,:,:,:', out)
+VAR(get, 7D, EightByteInt, integer, int8, `:,:,:,:,:,:,:', out)
+
+!
+! collective put APIs
+!
+
+VAR(put, 1D, OneByteInt, integer, int1, :, in, _all)
+VAR(put, 2D, OneByteInt, integer, int1, `:,:', in, _all)
+VAR(put, 3D, OneByteInt, integer, int1, `:,:,:', in, _all)
+VAR(put, 4D, OneByteInt, integer, int1, `:,:,:,:', in, _all)
+VAR(put, 5D, OneByteInt, integer, int1, `:,:,:,:,:', in, _all)
+VAR(put, 6D, OneByteInt, integer, int1, `:,:,:,:,:,:', in, _all)
+VAR(put, 7D, OneByteInt, integer, int1, `:,:,:,:,:,:,:', in, _all)
+
+VAR(put, 1D, TwoByteInt, integer, int2, :, INTENTV, _all)
+VAR(put, 2D, TwoByteInt, integer, int2, `:,:', INTENTV, _all)
+VAR(put, 3D, TwoByteInt, integer, int2, `:,:,:', INTENTV, _all)
+VAR(put, 4D, TwoByteInt, integer, int2, `:,:,:,:', INTENTV, _all)
+VAR(put, 5D, TwoByteInt, integer, int2, `:,:,:,:,:', INTENTV, _all)
+VAR(put, 6D, TwoByteInt, integer, int2, `:,:,:,:,:,:', INTENTV, _all)
+VAR(put, 7D, TwoByteInt, integer, int2, `:,:,:,:,:,:,:', INTENTV, _all)
+
+VAR(put, 1D, FourByteInt, integer, int, :, INTENTV, _all)
+VAR(put, 2D, FourByteInt, integer, int, `:,:', INTENTV, _all)
+VAR(put, 3D, FourByteInt, integer, int, `:,:,:', INTENTV, _all)
+VAR(put, 4D, FourByteInt, integer, int, `:,:,:,:', INTENTV, _all)
+VAR(put, 5D, FourByteInt, integer, int, `:,:,:,:,:', INTENTV, _all)
+VAR(put, 6D, FourByteInt, integer, int, `:,:,:,:,:,:', INTENTV, _all)
+VAR(put, 7D, FourByteInt, integer, int, `:,:,:,:,:,:,:', INTENTV, _all)
+
+VAR(put, 1D, FourByteReal, real, real, :, INTENTV, _all)
+VAR(put, 2D, FourByteReal, real, real, `:,:', INTENTV, _all)
+VAR(put, 3D, FourByteReal, real, real, `:,:,:', INTENTV, _all)
+VAR(put, 4D, FourByteReal, real, real, `:,:,:,:', INTENTV, _all)
+VAR(put, 5D, FourByteReal, real, real, `:,:,:,:,:', INTENTV, _all)
+VAR(put, 6D, FourByteReal, real, real, `:,:,:,:,:,:', INTENTV, _all)
+VAR(put, 7D, FourByteReal, real, real, `:,:,:,:,:,:,:', INTENTV, _all)
+
+VAR(put, 1D, EightByteReal, real, double, :, INTENTV, _all)
+VAR(put, 2D, EightByteReal, real, double, `:,:', INTENTV, _all)
+VAR(put, 3D, EightByteReal, real, double, `:,:,:', INTENTV, _all)
+VAR(put, 4D, EightByteReal, real, double, `:,:,:,:', INTENTV, _all)
+VAR(put, 5D, EightByteReal, real, double, `:,:,:,:,:', INTENTV, _all)
+VAR(put, 6D, EightByteReal, real, double, `:,:,:,:,:,:', INTENTV, _all)
+VAR(put, 7D, EightByteReal, real, double, `:,:,:,:,:,:,:', INTENTV, _all)
+
+VAR(put, 1D, EightByteInt, integer, int8, :, INTENTV, _all)
+VAR(put, 2D, EightByteInt, integer, int8, `:,:', INTENTV, _all)
+VAR(put, 3D, EightByteInt, integer, int8, `:,:,:', INTENTV, _all)
+VAR(put, 4D, EightByteInt, integer, int8, `:,:,:,:', INTENTV, _all)
+VAR(put, 5D, EightByteInt, integer, int8, `:,:,:,:,:', INTENTV, _all)
+VAR(put, 6D, EightByteInt, integer, int8, `:,:,:,:,:,:', INTENTV, _all)
+VAR(put, 7D, EightByteInt, integer, int8, `:,:,:,:,:,:,:', INTENTV, _all)
+!
+! collective get APIs
+!
+
+VAR(get, 1D, OneByteInt, integer, int1, :, out, _all)
+VAR(get, 2D, OneByteInt, integer, int1, `:,:', out, _all)
+VAR(get, 3D, OneByteInt, integer, int1, `:,:,:', out, _all)
+VAR(get, 4D, OneByteInt, integer, int1, `:,:,:,:', out, _all)
+VAR(get, 5D, OneByteInt, integer, int1, `:,:,:,:,:', out, _all)
+VAR(get, 6D, OneByteInt, integer, int1, `:,:,:,:,:,:', out, _all)
+VAR(get, 7D, OneByteInt, integer, int1, `:,:,:,:,:,:,:', out, _all)
+
+VAR(get, 1D, TwoByteInt, integer, int2, :, out, _all)
+VAR(get, 2D, TwoByteInt, integer, int2, `:,:', out, _all)
+VAR(get, 3D, TwoByteInt, integer, int2, `:,:,:', out, _all)
+VAR(get, 4D, TwoByteInt, integer, int2, `:,:,:,:', out, _all)
+VAR(get, 5D, TwoByteInt, integer, int2, `:,:,:,:,:', out, _all)
+VAR(get, 6D, TwoByteInt, integer, int2, `:,:,:,:,:,:', out, _all)
+VAR(get, 7D, TwoByteInt, integer, int2, `:,:,:,:,:,:,:', out, _all)
+
+VAR(get, 1D, FourByteInt, integer, int, :, out, _all)
+VAR(get, 2D, FourByteInt, integer, int, `:,:', out, _all)
+VAR(get, 3D, FourByteInt, integer, int, `:,:,:', out, _all)
+VAR(get, 4D, FourByteInt, integer, int, `:,:,:,:', out, _all)
+VAR(get, 5D, FourByteInt, integer, int, `:,:,:,:,:', out, _all)
+VAR(get, 6D, FourByteInt, integer, int, `:,:,:,:,:,:', out, _all)
+VAR(get, 7D, FourByteInt, integer, int, `:,:,:,:,:,:,:', out, _all)
+
+VAR(get, 1D, FourByteReal, real, real, :, out, _all)
+VAR(get, 2D, FourByteReal, real, real, `:,:', out, _all)
+VAR(get, 3D, FourByteReal, real, real, `:,:,:', out, _all)
+VAR(get, 4D, FourByteReal, real, real, `:,:,:,:', out, _all)
+VAR(get, 5D, FourByteReal, real, real, `:,:,:,:,:', out, _all)
+VAR(get, 6D, FourByteReal, real, real, `:,:,:,:,:,:', out, _all)
+VAR(get, 7D, FourByteReal, real, real, `:,:,:,:,:,:,:', out, _all)
+
+VAR(get, 1D, EightByteReal, real, double, :, out, _all)
+VAR(get, 2D, EightByteReal, real, double, `:,:', out, _all)
+VAR(get, 3D, EightByteReal, real, double, `:,:,:', out, _all)
+VAR(get, 4D, EightByteReal, real, double, `:,:,:,:', out, _all)
+VAR(get, 5D, EightByteReal, real, double, `:,:,:,:,:', out, _all)
+VAR(get, 6D, EightByteReal, real, double, `:,:,:,:,:,:', out, _all)
+VAR(get, 7D, EightByteReal, real, double, `:,:,:,:,:,:,:', out, _all)
+
+VAR(get, 1D, EightByteInt, integer, int8, :, out, _all)
+VAR(get, 2D, EightByteInt, integer, int8, `:,:', out, _all)
+VAR(get, 3D, EightByteInt, integer, int8, `:,:,:', out, _all)
+VAR(get, 4D, EightByteInt, integer, int8, `:,:,:,:', out, _all)
+VAR(get, 5D, EightByteInt, integer, int8, `:,:,:,:,:', out, _all)
+VAR(get, 6D, EightByteInt, integer, int8, `:,:,:,:,:,:', out, _all)
+VAR(get, 7D, EightByteInt, integer, int8, `:,:,:,:,:,:,:', out, _all)
+
+!
+! Nonblocking APIs
+!
+
+dnl
+dnl NBVAR(ncid, varid, values, start, count, stride, map, req)
+dnl
+define(`NBVAR',dnl
+`dnl
+ function nf90mpi_$1_var_$2_$3(ncid, varid, values, req, start, count, stride, map, bufcount, buftype)
+ integer, intent( in) :: ncid, varid
+ $4 (kind=$3), dimension($6), intent( $7) :: values
+ integer, intent(out) :: req
+ integer (kind=MPI_OFFSET_KIND), dimension(:), optional, intent( in) :: start, count, stride, map
+ integer (kind=MPI_OFFSET_KIND), optional, intent( in) :: bufcount
+ integer, optional, intent( in) :: buftype
+
+ integer :: nf90mpi_$1_var_$2_$3
+ integer (kind=MPI_OFFSET_KIND), dimension(nf90_max_var_dims) :: localStart, localCount, localStride, localMap
+ integer :: numDims, counter
+
+ ! Set local arguments to default values
+ numDims = substr(`$2', `0', `1')
+ localStart (: ) = 1
+ localCount (:numDims ) = shape(values)
+ localCount (numDims+1:) = 1
+ localStride(: ) = 1
+ ! localMap (:numDims ) = (/ 1, (product(localCount(:counter)), counter = 1, numDims - 1) /)
+ localMap(1) = 1
+ do counter = 1, numDims - 1
+ localMap(counter+1) = localMap(counter) * localCount(counter)
+ enddo
+
+ if (present(start)) localStart (:size(start) ) = start(:)
+ if (present(count)) localCount (:size(count) ) = count(:)
+ if (present(stride)) localStride(:size(stride)) = stride(:)
+ if (present(map)) then
+ localMap (:size(map)) = map(:)
+ if (present(buftype)) then
+ nf90mpi_$1_var_$2_$3 = &
+ nfmpi_$1_varm(ncid, varid, localStart, localCount, localStride, localMap, values, bufcount, buftype, req)
+ else
+ nf90mpi_$1_var_$2_$3 = &
+ nfmpi_$1_varm_$5(ncid, varid, localStart, localCount, localStride, localMap, values, req)
+ endif
+ else if (present(stride)) then
+ if (present(buftype)) then
+ nf90mpi_$1_var_$2_$3 = &
+ nfmpi_$1_vars(ncid, varid, localStart, localCount, localStride, values, bufcount, buftype, req)
+ else
+ nf90mpi_$1_var_$2_$3 = &
+ nfmpi_$1_vars_$5(ncid, varid, localStart, localCount, localStride, values, req)
+ endif
+ else
+ if (present(buftype)) then
+ nf90mpi_$1_var_$2_$3 = &
+ nfmpi_$1_vara(ncid, varid, localStart, localCount, values, bufcount, buftype, req)
+ else
+ nf90mpi_$1_var_$2_$3 = &
+ nfmpi_$1_vara_$5(ncid, varid, localStart, localCount, values, req)
+ endif
+ end if
+ end function nf90mpi_$1_var_$2_$3
+')dnl
+
+!
+! iput APIs
+!
+
+NBVAR(iput, 1D, OneByteInt, integer, int1, :, in)
+NBVAR(iput, 2D, OneByteInt, integer, int1, `:,:', in)
+NBVAR(iput, 3D, OneByteInt, integer, int1, `:,:,:', in)
+NBVAR(iput, 4D, OneByteInt, integer, int1, `:,:,:,:', in)
+NBVAR(iput, 5D, OneByteInt, integer, int1, `:,:,:,:,:', in)
+NBVAR(iput, 6D, OneByteInt, integer, int1, `:,:,:,:,:,:', in)
+NBVAR(iput, 7D, OneByteInt, integer, int1, `:,:,:,:,:,:,:', in)
+
+NBVAR(iput, 1D, TwoByteInt, integer, int2, :, INTENTV)
+NBVAR(iput, 2D, TwoByteInt, integer, int2, `:,:', INTENTV)
+NBVAR(iput, 3D, TwoByteInt, integer, int2, `:,:,:', INTENTV)
+NBVAR(iput, 4D, TwoByteInt, integer, int2, `:,:,:,:', INTENTV)
+NBVAR(iput, 5D, TwoByteInt, integer, int2, `:,:,:,:,:', INTENTV)
+NBVAR(iput, 6D, TwoByteInt, integer, int2, `:,:,:,:,:,:', INTENTV)
+NBVAR(iput, 7D, TwoByteInt, integer, int2, `:,:,:,:,:,:,:', INTENTV)
+
+NBVAR(iput, 1D, FourByteInt, integer, int, :, INTENTV)
+NBVAR(iput, 2D, FourByteInt, integer, int, `:,:', INTENTV)
+NBVAR(iput, 3D, FourByteInt, integer, int, `:,:,:', INTENTV)
+NBVAR(iput, 4D, FourByteInt, integer, int, `:,:,:,:', INTENTV)
+NBVAR(iput, 5D, FourByteInt, integer, int, `:,:,:,:,:', INTENTV)
+NBVAR(iput, 6D, FourByteInt, integer, int, `:,:,:,:,:,:', INTENTV)
+NBVAR(iput, 7D, FourByteInt, integer, int, `:,:,:,:,:,:,:', INTENTV)
+
+NBVAR(iput, 1D, FourByteReal, real, real, :, INTENTV)
+NBVAR(iput, 2D, FourByteReal, real, real, `:,:', INTENTV)
+NBVAR(iput, 3D, FourByteReal, real, real, `:,:,:', INTENTV)
+NBVAR(iput, 4D, FourByteReal, real, real, `:,:,:,:', INTENTV)
+NBVAR(iput, 5D, FourByteReal, real, real, `:,:,:,:,:', INTENTV)
+NBVAR(iput, 6D, FourByteReal, real, real, `:,:,:,:,:,:', INTENTV)
+NBVAR(iput, 7D, FourByteReal, real, real, `:,:,:,:,:,:,:', INTENTV)
+
+NBVAR(iput, 1D, EightByteReal, real, double, :, INTENTV)
+NBVAR(iput, 2D, EightByteReal, real, double, `:,:', INTENTV)
+NBVAR(iput, 3D, EightByteReal, real, double, `:,:,:', INTENTV)
+NBVAR(iput, 4D, EightByteReal, real, double, `:,:,:,:', INTENTV)
+NBVAR(iput, 5D, EightByteReal, real, double, `:,:,:,:,:', INTENTV)
+NBVAR(iput, 6D, EightByteReal, real, double, `:,:,:,:,:,:', INTENTV)
+NBVAR(iput, 7D, EightByteReal, real, double, `:,:,:,:,:,:,:', INTENTV)
+
+NBVAR(iput, 1D, EightByteInt, integer, int8, :, INTENTV)
+NBVAR(iput, 2D, EightByteInt, integer, int8, `:,:', INTENTV)
+NBVAR(iput, 3D, EightByteInt, integer, int8, `:,:,:', INTENTV)
+NBVAR(iput, 4D, EightByteInt, integer, int8, `:,:,:,:', INTENTV)
+NBVAR(iput, 5D, EightByteInt, integer, int8, `:,:,:,:,:', INTENTV)
+NBVAR(iput, 6D, EightByteInt, integer, int8, `:,:,:,:,:,:', INTENTV)
+NBVAR(iput, 7D, EightByteInt, integer, int8, `:,:,:,:,:,:,:', INTENTV)
+
+!
+! iget APIs
+!
+
+NBVAR(iget, 1D, OneByteInt, integer, int1, :, out)
+NBVAR(iget, 2D, OneByteInt, integer, int1, `:,:', out)
+NBVAR(iget, 3D, OneByteInt, integer, int1, `:,:,:', out)
+NBVAR(iget, 4D, OneByteInt, integer, int1, `:,:,:,:', out)
+NBVAR(iget, 5D, OneByteInt, integer, int1, `:,:,:,:,:', out)
+NBVAR(iget, 6D, OneByteInt, integer, int1, `:,:,:,:,:,:', out)
+NBVAR(iget, 7D, OneByteInt, integer, int1, `:,:,:,:,:,:,:', out)
+
+NBVAR(iget, 1D, TwoByteInt, integer, int2, :, out)
+NBVAR(iget, 2D, TwoByteInt, integer, int2, `:,:', out)
+NBVAR(iget, 3D, TwoByteInt, integer, int2, `:,:,:', out)
+NBVAR(iget, 4D, TwoByteInt, integer, int2, `:,:,:,:', out)
+NBVAR(iget, 5D, TwoByteInt, integer, int2, `:,:,:,:,:', out)
+NBVAR(iget, 6D, TwoByteInt, integer, int2, `:,:,:,:,:,:', out)
+NBVAR(iget, 7D, TwoByteInt, integer, int2, `:,:,:,:,:,:,:', out)
+
+NBVAR(iget, 1D, FourByteInt, integer, int, :, out)
+NBVAR(iget, 2D, FourByteInt, integer, int, `:,:', out)
+NBVAR(iget, 3D, FourByteInt, integer, int, `:,:,:', out)
+NBVAR(iget, 4D, FourByteInt, integer, int, `:,:,:,:', out)
+NBVAR(iget, 5D, FourByteInt, integer, int, `:,:,:,:,:', out)
+NBVAR(iget, 6D, FourByteInt, integer, int, `:,:,:,:,:,:', out)
+NBVAR(iget, 7D, FourByteInt, integer, int, `:,:,:,:,:,:,:', out)
+
+NBVAR(iget, 1D, FourByteReal, real, real, :, out)
+NBVAR(iget, 2D, FourByteReal, real, real, `:,:', out)
+NBVAR(iget, 3D, FourByteReal, real, real, `:,:,:', out)
+NBVAR(iget, 4D, FourByteReal, real, real, `:,:,:,:', out)
+NBVAR(iget, 5D, FourByteReal, real, real, `:,:,:,:,:', out)
+NBVAR(iget, 6D, FourByteReal, real, real, `:,:,:,:,:,:', out)
+NBVAR(iget, 7D, FourByteReal, real, real, `:,:,:,:,:,:,:', out)
+
+NBVAR(iget, 1D, EightByteReal, real, double, :, out)
+NBVAR(iget, 2D, EightByteReal, real, double, `:,:', out)
+NBVAR(iget, 3D, EightByteReal, real, double, `:,:,:', out)
+NBVAR(iget, 4D, EightByteReal, real, double, `:,:,:,:', out)
+NBVAR(iget, 5D, EightByteReal, real, double, `:,:,:,:,:', out)
+NBVAR(iget, 6D, EightByteReal, real, double, `:,:,:,:,:,:', out)
+NBVAR(iget, 7D, EightByteReal, real, double, `:,:,:,:,:,:,:', out)
+
+NBVAR(iget, 1D, EightByteInt, integer, int8, :, out)
+NBVAR(iget, 2D, EightByteInt, integer, int8, `:,:', out)
+NBVAR(iget, 3D, EightByteInt, integer, int8, `:,:,:', out)
+NBVAR(iget, 4D, EightByteInt, integer, int8, `:,:,:,:', out)
+NBVAR(iget, 5D, EightByteInt, integer, int8, `:,:,:,:,:', out)
+NBVAR(iget, 6D, EightByteInt, integer, int8, `:,:,:,:,:,:', out)
+NBVAR(iget, 7D, EightByteInt, integer, int8, `:,:,:,:,:,:,:', out)
+
+!
+! bput APIs
+!
+
+NBVAR(bput, 1D, OneByteInt, integer, int1, :, in)
+NBVAR(bput, 2D, OneByteInt, integer, int1, `:,:', in)
+NBVAR(bput, 3D, OneByteInt, integer, int1, `:,:,:', in)
+NBVAR(bput, 4D, OneByteInt, integer, int1, `:,:,:,:', in)
+NBVAR(bput, 5D, OneByteInt, integer, int1, `:,:,:,:,:', in)
+NBVAR(bput, 6D, OneByteInt, integer, int1, `:,:,:,:,:,:', in)
+NBVAR(bput, 7D, OneByteInt, integer, int1, `:,:,:,:,:,:,:', in)
+
+NBVAR(bput, 1D, TwoByteInt, integer, int2, :, INTENTV)
+NBVAR(bput, 2D, TwoByteInt, integer, int2, `:,:', INTENTV)
+NBVAR(bput, 3D, TwoByteInt, integer, int2, `:,:,:', INTENTV)
+NBVAR(bput, 4D, TwoByteInt, integer, int2, `:,:,:,:', INTENTV)
+NBVAR(bput, 5D, TwoByteInt, integer, int2, `:,:,:,:,:', INTENTV)
+NBVAR(bput, 6D, TwoByteInt, integer, int2, `:,:,:,:,:,:', INTENTV)
+NBVAR(bput, 7D, TwoByteInt, integer, int2, `:,:,:,:,:,:,:', INTENTV)
+
+NBVAR(bput, 1D, FourByteInt, integer, int, :, INTENTV)
+NBVAR(bput, 2D, FourByteInt, integer, int, `:,:', INTENTV)
+NBVAR(bput, 3D, FourByteInt, integer, int, `:,:,:', INTENTV)
+NBVAR(bput, 4D, FourByteInt, integer, int, `:,:,:,:', INTENTV)
+NBVAR(bput, 5D, FourByteInt, integer, int, `:,:,:,:,:', INTENTV)
+NBVAR(bput, 6D, FourByteInt, integer, int, `:,:,:,:,:,:', INTENTV)
+NBVAR(bput, 7D, FourByteInt, integer, int, `:,:,:,:,:,:,:', INTENTV)
+
+NBVAR(bput, 1D, FourByteReal, real, real, :, INTENTV)
+NBVAR(bput, 2D, FourByteReal, real, real, `:,:', INTENTV)
+NBVAR(bput, 3D, FourByteReal, real, real, `:,:,:', INTENTV)
+NBVAR(bput, 4D, FourByteReal, real, real, `:,:,:,:', INTENTV)
+NBVAR(bput, 5D, FourByteReal, real, real, `:,:,:,:,:', INTENTV)
+NBVAR(bput, 6D, FourByteReal, real, real, `:,:,:,:,:,:', INTENTV)
+NBVAR(bput, 7D, FourByteReal, real, real, `:,:,:,:,:,:,:', INTENTV)
+
+NBVAR(bput, 1D, EightByteReal, real, double, :, INTENTV)
+NBVAR(bput, 2D, EightByteReal, real, double, `:,:', INTENTV)
+NBVAR(bput, 3D, EightByteReal, real, double, `:,:,:', INTENTV)
+NBVAR(bput, 4D, EightByteReal, real, double, `:,:,:,:', INTENTV)
+NBVAR(bput, 5D, EightByteReal, real, double, `:,:,:,:,:', INTENTV)
+NBVAR(bput, 6D, EightByteReal, real, double, `:,:,:,:,:,:', INTENTV)
+NBVAR(bput, 7D, EightByteReal, real, double, `:,:,:,:,:,:,:', INTENTV)
+
+NBVAR(bput, 1D, EightByteInt, integer, int8, :, INTENTV)
+NBVAR(bput, 2D, EightByteInt, integer, int8, `:,:', INTENTV)
+NBVAR(bput, 3D, EightByteInt, integer, int8, `:,:,:', INTENTV)
+NBVAR(bput, 4D, EightByteInt, integer, int8, `:,:,:,:', INTENTV)
+NBVAR(bput, 5D, EightByteInt, integer, int8, `:,:,:,:,:', INTENTV)
+NBVAR(bput, 6D, EightByteInt, integer, int8, `:,:,:,:,:,:', INTENTV)
+NBVAR(bput, 7D, EightByteInt, integer, int8, `:,:,:,:,:,:,:', INTENTV)
+
+!
+! Other nonblocking control APIs
+!
+
+ function nf90mpi_wait(ncid, num, req, st)
+ integer, intent(in) :: ncid, num
+ integer, dimension(:), intent(inout) :: req
+ integer, dimension(:), intent(out) :: st
+ integer :: nf90mpi_wait
+
+ nf90mpi_wait = nfmpi_wait(ncid, num, req, st)
+ end function nf90mpi_wait
+
+ function nf90mpi_wait_all(ncid, num, req, st)
+ integer, intent(in) :: ncid, num
+ integer, dimension(:), intent(inout) :: req
+ integer, dimension(:), intent(out) :: st
+ integer :: nf90mpi_wait_all
+
+ nf90mpi_wait_all = nfmpi_wait_all(ncid, num, req, st)
+ end function nf90mpi_wait_all
+
+ function nf90mpi_cancel(ncid, num, req, st)
+ integer, intent(in) :: ncid, num
+ integer, dimension(:), intent(inout) :: req
+ integer, dimension(:), intent(out) :: st
+ integer :: nf90mpi_cancel
+
+ nf90mpi_cancel = nfmpi_cancel(ncid, num, req, st)
+ end function nf90mpi_cancel
+
+ function nf90mpi_buffer_attach(ncid, bufsize)
+ integer, intent( in) :: ncid
+ integer (kind=MPI_OFFSET_KIND), intent( in) :: bufsize
+ integer :: nf90mpi_buffer_attach
+
+ nf90mpi_buffer_attach = nfmpi_buffer_attach(ncid, bufsize)
+ end function nf90mpi_buffer_attach
+
+ function nf90mpi_inq_buffer_usage(ncid, usage)
+ integer, intent( in) :: ncid
+ integer (kind=MPI_OFFSET_KIND), intent(out) :: usage
+ integer :: nf90mpi_inq_buffer_usage
+
+ nf90mpi_inq_buffer_usage = nfmpi_inq_buffer_usage(ncid, usage)
+ end function nf90mpi_inq_buffer_usage
+
+ function nf90mpi_inq_buffer_size(ncid, buf_size)
+ integer, intent( in) :: ncid
+ integer (kind=MPI_OFFSET_KIND), intent(out) :: buf_size
+ integer :: nf90mpi_inq_buffer_size
+
+ nf90mpi_inq_buffer_size = nfmpi_inq_buffer_usage(ncid, buf_size)
+ end function nf90mpi_inq_buffer_size
+
+ function nf90mpi_buffer_detach(ncid)
+ integer, intent( in) :: ncid
+ integer :: nf90mpi_buffer_detach
+
+ nf90mpi_buffer_detach = nfmpi_buffer_detach(ncid)
+ end function nf90mpi_buffer_detach
+
diff --git a/src/libf90/getput_vard.m4 b/src/libf90/getput_vard.m4
new file mode 100644
index 0000000..c1810b3
--- /dev/null
+++ b/src/libf90/getput_vard.m4
@@ -0,0 +1,375 @@
+dnl Process this m4 file to produce 'C' language file.
+dnl
+dnl If you see this line, you can ignore the next one.
+! Do not edit this file. It is produced from the corresponding .m4 source
+dnl
+!
+! Copyright (C) 2014, Northwestern University and Argonne National Laboratory
+! See COPYRIGHT notice in top-level directory.
+!
+! $Id: getput_vard.m4 2221 2015-12-12 00:39:15Z wkliao $
+!
+
+dnl
+dnl VARD1(ncid, varid, filetype, buf, bufcount, buftype)
+dnl
+define(`VARD1',dnl
+`dnl
+ function nf90mpi_$1_vard_$3$6(ncid, varid, filetype, buf, bufcount, buftype)
+ integer, intent(in) :: ncid, varid
+ integer, intent(in) :: filetype
+ $4 (kind=$3), intent($2) :: buf
+ integer (kind=MPI_OFFSET_KIND), intent(in) :: bufcount
+ integer, intent(in) :: buftype
+ integer :: nf90mpi_$1_vard_$3$6
+ nf90mpi_$1_vard_$3$6 = nfmpi_$1_vard$6(ncid, varid, filetype, buf, bufcount, buftype)
+ end function nf90mpi_$1_vard_$3$6
+')dnl
+
+!
+! Independent put APIs
+!
+
+VARD1(put, INTENTV, OneByteInt, integer, int1)
+VARD1(put, INTENTV, TwoByteInt, integer, int2)
+VARD1(put, INTENTV, FourByteInt, integer, int)
+VARD1(put, INTENTV, FourByteReal, real, real)
+VARD1(put, INTENTV, EightByteReal, real, double)
+VARD1(put, INTENTV, EightByteInt, integer, int8)
+
+!
+! Independent get APIs
+!
+
+VARD1(get, out, OneByteInt, integer, int1)
+VARD1(get, out, TwoByteInt, integer, int2)
+VARD1(get, out, FourByteInt, integer, int)
+VARD1(get, out, FourByteReal, real, real)
+VARD1(get, out, EightByteReal, real, double)
+VARD1(get, out, EightByteInt, integer, int8)
+
+!
+! Collective put APIs
+!
+
+VARD1(put, INTENTV, OneByteInt, integer, int1, _all)
+VARD1(put, INTENTV, TwoByteInt, integer, int2, _all)
+VARD1(put, INTENTV, FourByteInt, integer, int, _all)
+VARD1(put, INTENTV, FourByteReal, real, real, _all)
+VARD1(put, INTENTV, EightByteReal, real, double, _all)
+VARD1(put, INTENTV, EightByteInt, integer, int8, _all)
+
+!
+! Collective get APIs
+!
+
+VARD1(get, out, OneByteInt, integer, int1, _all)
+VARD1(get, out, TwoByteInt, integer, int2, _all)
+VARD1(get, out, FourByteInt, integer, int, _all)
+VARD1(get, out, FourByteReal, real, real, _all)
+VARD1(get, out, EightByteReal, real, double, _all)
+VARD1(get, out, EightByteInt, integer, int8, _all)
+
+
+dnl
+dnl VARD(ncid, varid, values, num, start, count)
+dnl
+define(`VARD',dnl
+`dnl
+ function nf90mpi_$1_vard_$2_$3$8(ncid, varid, filetype, buf, bufcount, buftype)
+ integer, intent(in) :: ncid, varid
+ integer, intent(in) :: filetype
+ $4 (kind=$3), dimension($6), intent($7) :: buf
+ integer (kind=MPI_OFFSET_KIND), intent(in) :: bufcount
+ integer, intent(in) :: buftype
+ integer :: nf90mpi_$1_vard_$2_$3$8
+ nf90mpi_$1_vard_$2_$3$8 = nfmpi_$1_vard$8(ncid, varid, filetype, buf, bufcount, buftype)
+ end function nf90mpi_$1_vard_$2_$3$8
+')dnl
+
+!
+! put APIs
+!
+
+VARD(put, 1D, OneByteInt, integer, int1, :, in)
+VARD(put, 2D, OneByteInt, integer, int1, `:,:', in)
+VARD(put, 3D, OneByteInt, integer, int1, `:,:,:', in)
+VARD(put, 4D, OneByteInt, integer, int1, `:,:,:,:', in)
+VARD(put, 5D, OneByteInt, integer, int1, `:,:,:,:,:', in)
+VARD(put, 6D, OneByteInt, integer, int1, `:,:,:,:,:,:', in)
+VARD(put, 7D, OneByteInt, integer, int1, `:,:,:,:,:,:,:', in)
+
+VARD(put, 1D, TwoByteInt, integer, int2, :, INTENTV)
+VARD(put, 2D, TwoByteInt, integer, int2, `:,:', INTENTV)
+VARD(put, 3D, TwoByteInt, integer, int2, `:,:,:', INTENTV)
+VARD(put, 4D, TwoByteInt, integer, int2, `:,:,:,:', INTENTV)
+VARD(put, 5D, TwoByteInt, integer, int2, `:,:,:,:,:', INTENTV)
+VARD(put, 6D, TwoByteInt, integer, int2, `:,:,:,:,:,:', INTENTV)
+VARD(put, 7D, TwoByteInt, integer, int2, `:,:,:,:,:,:,:', INTENTV)
+
+VARD(put, 1D, FourByteInt, integer, int, :, INTENTV)
+VARD(put, 2D, FourByteInt, integer, int, `:,:', INTENTV)
+VARD(put, 3D, FourByteInt, integer, int, `:,:,:', INTENTV)
+VARD(put, 4D, FourByteInt, integer, int, `:,:,:,:', INTENTV)
+VARD(put, 5D, FourByteInt, integer, int, `:,:,:,:,:', INTENTV)
+VARD(put, 6D, FourByteInt, integer, int, `:,:,:,:,:,:', INTENTV)
+VARD(put, 7D, FourByteInt, integer, int, `:,:,:,:,:,:,:', INTENTV)
+
+VARD(put, 1D, FourByteReal, real, real, :, INTENTV)
+VARD(put, 2D, FourByteReal, real, real, `:,:', INTENTV)
+VARD(put, 3D, FourByteReal, real, real, `:,:,:', INTENTV)
+VARD(put, 4D, FourByteReal, real, real, `:,:,:,:', INTENTV)
+VARD(put, 5D, FourByteReal, real, real, `:,:,:,:,:', INTENTV)
+VARD(put, 6D, FourByteReal, real, real, `:,:,:,:,:,:', INTENTV)
+VARD(put, 7D, FourByteReal, real, real, `:,:,:,:,:,:,:', INTENTV)
+
+VARD(put, 1D, EightByteReal, real, double, :, INTENTV)
+VARD(put, 2D, EightByteReal, real, double, `:,:', INTENTV)
+VARD(put, 3D, EightByteReal, real, double, `:,:,:', INTENTV)
+VARD(put, 4D, EightByteReal, real, double, `:,:,:,:', INTENTV)
+VARD(put, 5D, EightByteReal, real, double, `:,:,:,:,:', INTENTV)
+VARD(put, 6D, EightByteReal, real, double, `:,:,:,:,:,:', INTENTV)
+VARD(put, 7D, EightByteReal, real, double, `:,:,:,:,:,:,:', INTENTV)
+
+VARD(put, 1D, EightByteInt, integer, int8, :, INTENTV)
+VARD(put, 2D, EightByteInt, integer, int8, `:,:', INTENTV)
+VARD(put, 3D, EightByteInt, integer, int8, `:,:,:', INTENTV)
+VARD(put, 4D, EightByteInt, integer, int8, `:,:,:,:', INTENTV)
+VARD(put, 5D, EightByteInt, integer, int8, `:,:,:,:,:', INTENTV)
+VARD(put, 6D, EightByteInt, integer, int8, `:,:,:,:,:,:', INTENTV)
+VARD(put, 7D, EightByteInt, integer, int8, `:,:,:,:,:,:,:', INTENTV)
+
+!
+! get APIs
+!
+
+VARD(get, 1D, OneByteInt, integer, int1, :, out)
+VARD(get, 2D, OneByteInt, integer, int1, `:,:', out)
+VARD(get, 3D, OneByteInt, integer, int1, `:,:,:', out)
+VARD(get, 4D, OneByteInt, integer, int1, `:,:,:,:', out)
+VARD(get, 5D, OneByteInt, integer, int1, `:,:,:,:,:', out)
+VARD(get, 6D, OneByteInt, integer, int1, `:,:,:,:,:,:', out)
+VARD(get, 7D, OneByteInt, integer, int1, `:,:,:,:,:,:,:', out)
+
+VARD(get, 1D, TwoByteInt, integer, int2, :, out)
+VARD(get, 2D, TwoByteInt, integer, int2, `:,:', out)
+VARD(get, 3D, TwoByteInt, integer, int2, `:,:,:', out)
+VARD(get, 4D, TwoByteInt, integer, int2, `:,:,:,:', out)
+VARD(get, 5D, TwoByteInt, integer, int2, `:,:,:,:,:', out)
+VARD(get, 6D, TwoByteInt, integer, int2, `:,:,:,:,:,:', out)
+VARD(get, 7D, TwoByteInt, integer, int2, `:,:,:,:,:,:,:', out)
+
+VARD(get, 1D, FourByteInt, integer, int, :, out)
+VARD(get, 2D, FourByteInt, integer, int, `:,:', out)
+VARD(get, 3D, FourByteInt, integer, int, `:,:,:', out)
+VARD(get, 4D, FourByteInt, integer, int, `:,:,:,:', out)
+VARD(get, 5D, FourByteInt, integer, int, `:,:,:,:,:', out)
+VARD(get, 6D, FourByteInt, integer, int, `:,:,:,:,:,:', out)
+VARD(get, 7D, FourByteInt, integer, int, `:,:,:,:,:,:,:', out)
+
+VARD(get, 1D, FourByteReal, real, real, :, out)
+VARD(get, 2D, FourByteReal, real, real, `:,:', out)
+VARD(get, 3D, FourByteReal, real, real, `:,:,:', out)
+VARD(get, 4D, FourByteReal, real, real, `:,:,:,:', out)
+VARD(get, 5D, FourByteReal, real, real, `:,:,:,:,:', out)
+VARD(get, 6D, FourByteReal, real, real, `:,:,:,:,:,:', out)
+VARD(get, 7D, FourByteReal, real, real, `:,:,:,:,:,:,:', out)
+
+VARD(get, 1D, EightByteReal, real, double, :, out)
+VARD(get, 2D, EightByteReal, real, double, `:,:', out)
+VARD(get, 3D, EightByteReal, real, double, `:,:,:', out)
+VARD(get, 4D, EightByteReal, real, double, `:,:,:,:', out)
+VARD(get, 5D, EightByteReal, real, double, `:,:,:,:,:', out)
+VARD(get, 6D, EightByteReal, real, double, `:,:,:,:,:,:', out)
+VARD(get, 7D, EightByteReal, real, double, `:,:,:,:,:,:,:', out)
+
+VARD(get, 1D, EightByteInt, integer, int8, :, out)
+VARD(get, 2D, EightByteInt, integer, int8, `:,:', out)
+VARD(get, 3D, EightByteInt, integer, int8, `:,:,:', out)
+VARD(get, 4D, EightByteInt, integer, int8, `:,:,:,:', out)
+VARD(get, 5D, EightByteInt, integer, int8, `:,:,:,:,:', out)
+VARD(get, 6D, EightByteInt, integer, int8, `:,:,:,:,:,:', out)
+VARD(get, 7D, EightByteInt, integer, int8, `:,:,:,:,:,:,:', out)
+
+!
+! collective put APIs
+!
+
+VARD(put, 1D, OneByteInt, integer, int1, :, in, _all)
+VARD(put, 2D, OneByteInt, integer, int1, `:,:', in, _all)
+VARD(put, 3D, OneByteInt, integer, int1, `:,:,:', in, _all)
+VARD(put, 4D, OneByteInt, integer, int1, `:,:,:,:', in, _all)
+VARD(put, 5D, OneByteInt, integer, int1, `:,:,:,:,:', in, _all)
+VARD(put, 6D, OneByteInt, integer, int1, `:,:,:,:,:,:', in, _all)
+VARD(put, 7D, OneByteInt, integer, int1, `:,:,:,:,:,:,:', in, _all)
+
+VARD(put, 1D, TwoByteInt, integer, int2, :, INTENTV, _all)
+VARD(put, 2D, TwoByteInt, integer, int2, `:,:', INTENTV, _all)
+VARD(put, 3D, TwoByteInt, integer, int2, `:,:,:', INTENTV, _all)
+VARD(put, 4D, TwoByteInt, integer, int2, `:,:,:,:', INTENTV, _all)
+VARD(put, 5D, TwoByteInt, integer, int2, `:,:,:,:,:', INTENTV, _all)
+VARD(put, 6D, TwoByteInt, integer, int2, `:,:,:,:,:,:', INTENTV, _all)
+VARD(put, 7D, TwoByteInt, integer, int2, `:,:,:,:,:,:,:', INTENTV, _all)
+
+VARD(put, 1D, FourByteInt, integer, int, :, INTENTV, _all)
+VARD(put, 2D, FourByteInt, integer, int, `:,:', INTENTV, _all)
+VARD(put, 3D, FourByteInt, integer, int, `:,:,:', INTENTV, _all)
+VARD(put, 4D, FourByteInt, integer, int, `:,:,:,:', INTENTV, _all)
+VARD(put, 5D, FourByteInt, integer, int, `:,:,:,:,:', INTENTV, _all)
+VARD(put, 6D, FourByteInt, integer, int, `:,:,:,:,:,:', INTENTV, _all)
+VARD(put, 7D, FourByteInt, integer, int, `:,:,:,:,:,:,:', INTENTV, _all)
+
+VARD(put, 1D, FourByteReal, real, real, :, INTENTV, _all)
+VARD(put, 2D, FourByteReal, real, real, `:,:', INTENTV, _all)
+VARD(put, 3D, FourByteReal, real, real, `:,:,:', INTENTV, _all)
+VARD(put, 4D, FourByteReal, real, real, `:,:,:,:', INTENTV, _all)
+VARD(put, 5D, FourByteReal, real, real, `:,:,:,:,:', INTENTV, _all)
+VARD(put, 6D, FourByteReal, real, real, `:,:,:,:,:,:', INTENTV, _all)
+VARD(put, 7D, FourByteReal, real, real, `:,:,:,:,:,:,:', INTENTV, _all)
+
+VARD(put, 1D, EightByteReal, real, double, :, INTENTV, _all)
+VARD(put, 2D, EightByteReal, real, double, `:,:', INTENTV, _all)
+VARD(put, 3D, EightByteReal, real, double, `:,:,:', INTENTV, _all)
+VARD(put, 4D, EightByteReal, real, double, `:,:,:,:', INTENTV, _all)
+VARD(put, 5D, EightByteReal, real, double, `:,:,:,:,:', INTENTV, _all)
+VARD(put, 6D, EightByteReal, real, double, `:,:,:,:,:,:', INTENTV, _all)
+VARD(put, 7D, EightByteReal, real, double, `:,:,:,:,:,:,:', INTENTV, _all)
+
+VARD(put, 1D, EightByteInt, integer, int8, :, INTENTV, _all)
+VARD(put, 2D, EightByteInt, integer, int8, `:,:', INTENTV, _all)
+VARD(put, 3D, EightByteInt, integer, int8, `:,:,:', INTENTV, _all)
+VARD(put, 4D, EightByteInt, integer, int8, `:,:,:,:', INTENTV, _all)
+VARD(put, 5D, EightByteInt, integer, int8, `:,:,:,:,:', INTENTV, _all)
+VARD(put, 6D, EightByteInt, integer, int8, `:,:,:,:,:,:', INTENTV, _all)
+VARD(put, 7D, EightByteInt, integer, int8, `:,:,:,:,:,:,:', INTENTV, _all)
+
+!
+! collective get APIs
+!
+
+VARD(get, 1D, OneByteInt, integer, int1, :, out, _all)
+VARD(get, 2D, OneByteInt, integer, int1, `:,:', out, _all)
+VARD(get, 3D, OneByteInt, integer, int1, `:,:,:', out, _all)
+VARD(get, 4D, OneByteInt, integer, int1, `:,:,:,:', out, _all)
+VARD(get, 5D, OneByteInt, integer, int1, `:,:,:,:,:', out, _all)
+VARD(get, 6D, OneByteInt, integer, int1, `:,:,:,:,:,:', out, _all)
+VARD(get, 7D, OneByteInt, integer, int1, `:,:,:,:,:,:,:', out, _all)
+
+VARD(get, 1D, TwoByteInt, integer, int2, :, out, _all)
+VARD(get, 2D, TwoByteInt, integer, int2, `:,:', out, _all)
+VARD(get, 3D, TwoByteInt, integer, int2, `:,:,:', out, _all)
+VARD(get, 4D, TwoByteInt, integer, int2, `:,:,:,:', out, _all)
+VARD(get, 5D, TwoByteInt, integer, int2, `:,:,:,:,:', out, _all)
+VARD(get, 6D, TwoByteInt, integer, int2, `:,:,:,:,:,:', out, _all)
+VARD(get, 7D, TwoByteInt, integer, int2, `:,:,:,:,:,:,:', out, _all)
+
+VARD(get, 1D, FourByteInt, integer, int, :, out, _all)
+VARD(get, 2D, FourByteInt, integer, int, `:,:', out, _all)
+VARD(get, 3D, FourByteInt, integer, int, `:,:,:', out, _all)
+VARD(get, 4D, FourByteInt, integer, int, `:,:,:,:', out, _all)
+VARD(get, 5D, FourByteInt, integer, int, `:,:,:,:,:', out, _all)
+VARD(get, 6D, FourByteInt, integer, int, `:,:,:,:,:,:', out, _all)
+VARD(get, 7D, FourByteInt, integer, int, `:,:,:,:,:,:,:', out, _all)
+
+VARD(get, 1D, FourByteReal, real, real, :, out, _all)
+VARD(get, 2D, FourByteReal, real, real, `:,:', out, _all)
+VARD(get, 3D, FourByteReal, real, real, `:,:,:', out, _all)
+VARD(get, 4D, FourByteReal, real, real, `:,:,:,:', out, _all)
+VARD(get, 5D, FourByteReal, real, real, `:,:,:,:,:', out, _all)
+VARD(get, 6D, FourByteReal, real, real, `:,:,:,:,:,:', out, _all)
+VARD(get, 7D, FourByteReal, real, real, `:,:,:,:,:,:,:', out, _all)
+
+VARD(get, 1D, EightByteReal, real, double, :, out, _all)
+VARD(get, 2D, EightByteReal, real, double, `:,:', out, _all)
+VARD(get, 3D, EightByteReal, real, double, `:,:,:', out, _all)
+VARD(get, 4D, EightByteReal, real, double, `:,:,:,:', out, _all)
+VARD(get, 5D, EightByteReal, real, double, `:,:,:,:,:', out, _all)
+VARD(get, 6D, EightByteReal, real, double, `:,:,:,:,:,:', out, _all)
+VARD(get, 7D, EightByteReal, real, double, `:,:,:,:,:,:,:', out, _all)
+
+VARD(get, 1D, EightByteInt, integer, int8, :, out, _all)
+VARD(get, 2D, EightByteInt, integer, int8, `:,:', out, _all)
+VARD(get, 3D, EightByteInt, integer, int8, `:,:,:', out, _all)
+VARD(get, 4D, EightByteInt, integer, int8, `:,:,:,:', out, _all)
+VARD(get, 5D, EightByteInt, integer, int8, `:,:,:,:,:', out, _all)
+VARD(get, 6D, EightByteInt, integer, int8, `:,:,:,:,:,:', out, _all)
+VARD(get, 7D, EightByteInt, integer, int8, `:,:,:,:,:,:,:', out, _all)
+
+!
+! text variable
+!
+
+dnl
+dnl TEXTVARD1(ncid, varid, values, num, start, count)
+dnl
+define(`TEXTVARD1',dnl
+`dnl
+ function nf90mpi_$1_vard_text$3(ncid, varid, filetype, buf, bufcount, buftype)
+ integer, intent(in) :: ncid, varid
+ integer, intent(in) :: filetype
+ character (len = *), intent($2) :: buf
+ integer (kind=MPI_OFFSET_KIND), intent(in) :: bufcount
+ integer, intent(in) :: buftype
+ integer :: nf90mpi_$1_vard_text$3
+ nf90mpi_$1_vard_text$3 = nfmpi_$1_vard$3(ncid, varid, filetype, buf, bufcount, buftype)
+ end function nf90mpi_$1_vard_text$3
+')dnl
+
+TEXTVARD1(put, in)
+TEXTVARD1(get, out)
+
+TEXTVARD1(put, in, _all)
+TEXTVARD1(get, out, _all)
+
+dnl
+dnl TEXTVARD(ncid, varid, values, num, start, count)
+dnl
+define(`TEXTVARD',dnl
+`dnl
+ function nf90mpi_$1_vard_$2_text$6(ncid, varid, filetype, buf, bufcount, buftype)
+ integer, intent(in) :: ncid, varid
+ integer, intent(in) :: filetype
+ character (len = *), dimension($3), intent($5) :: buf
+ integer (kind=MPI_OFFSET_KIND), intent(in) :: bufcount
+ integer, intent(in) :: buftype
+ integer :: nf90mpi_$1_vard_$2_text$6
+ nf90mpi_$1_vard_$2_text$6 = nfmpi_$1_vard$6(ncid, varid, filetype, buf($4), bufcount, buftype)
+ end function nf90mpi_$1_vard_$2_text$6
+')dnl
+
+TEXTVARD(put, 1D, :, 1, in)
+TEXTVARD(put, 2D, `:,:', `1,1', in)
+TEXTVARD(put, 3D, `:,:,:', `1,1,1', in)
+TEXTVARD(put, 4D, `:,:,:,:', `1,1,1,1', in)
+TEXTVARD(put, 5D, `:,:,:,:,:', `1,1,1,1,1', in)
+TEXTVARD(put, 6D, `:,:,:,:,:,:', `1,1,1,1,1,1', in)
+TEXTVARD(put, 7D, `:,:,:,:,:,:,:', `1,1,1,1,1,1,1', in)
+
+TEXTVARD(get, 1D, :, 1, out)
+TEXTVARD(get, 2D, `:,:', `1,1', out)
+TEXTVARD(get, 3D, `:,:,:', `1,1,1', out)
+TEXTVARD(get, 4D, `:,:,:,:', `1,1,1,1', out)
+TEXTVARD(get, 5D, `:,:,:,:,:', `1,1,1,1,1', out)
+TEXTVARD(get, 6D, `:,:,:,:,:,:', `1,1,1,1,1,1', out)
+TEXTVARD(get, 7D, `:,:,:,:,:,:,:', `1,1,1,1,1,1,1', out)
+
+!
+! Collective APIs
+!
+
+TEXTVARD(put, 1D, :, 1, in, _all)
+TEXTVARD(put, 2D, `:,:', `1,1', in, _all)
+TEXTVARD(put, 3D, `:,:,:', `1,1,1', in, _all)
+TEXTVARD(put, 4D, `:,:,:,:', `1,1,1,1', in, _all)
+TEXTVARD(put, 5D, `:,:,:,:,:', `1,1,1,1,1', in, _all)
+TEXTVARD(put, 6D, `:,:,:,:,:,:', `1,1,1,1,1,1', in, _all)
+TEXTVARD(put, 7D, `:,:,:,:,:,:,:', `1,1,1,1,1,1,1', in, _all)
+
+TEXTVARD(get, 1D, :, 1, out, _all)
+TEXTVARD(get, 2D, `:,:', `1,1', out, _all)
+TEXTVARD(get, 3D, `:,:,:', `1,1,1', out, _all)
+TEXTVARD(get, 4D, `:,:,:,:', `1,1,1,1', out, _all)
+TEXTVARD(get, 5D, `:,:,:,:,:', `1,1,1,1,1', out, _all)
+TEXTVARD(get, 6D, `:,:,:,:,:,:', `1,1,1,1,1,1', out, _all)
+TEXTVARD(get, 7D, `:,:,:,:,:,:,:', `1,1,1,1,1,1,1', out, _all)
+
diff --git a/src/libf90/getput_varn.m4 b/src/libf90/getput_varn.m4
new file mode 100644
index 0000000..e15d299
--- /dev/null
+++ b/src/libf90/getput_varn.m4
@@ -0,0 +1,666 @@
+dnl Process this m4 file to produce 'C' language file.
+dnl
+dnl If you see this line, you can ignore the next one.
+! Do not edit this file. It is produced from the corresponding .m4 source
+dnl
+!
+! Copyright (C) 2014, Northwestern University and Argonne National Laboratory
+! See COPYRIGHT notice in top-level directory.
+!
+! $Id: getput_varn.m4 2221 2015-12-12 00:39:15Z wkliao $
+!
+
+dnl
+dnl VARN1
+dnl
+define(`VARN1',dnl
+`dnl
+ ! $1 a scalar of type $5 (kind=$4)
+ function nf90mpi_$1_varn_$4$2(ncid, varid, value, start)
+ integer, intent(in) :: ncid, varid
+ $5 (kind=$4), intent($3) :: value
+ integer (kind=MPI_OFFSET_KIND), dimension(:,:), intent(in) :: start
+ integer :: nf90mpi_$1_varn_$4$2
+
+ nf90mpi_$1_varn_$4$2 = nfmpi_$1_var1_$6$2(ncid, varid, start(:,1), value)
+ end function nf90mpi_$1_varn_$4$2
+')dnl
+
+VARN1(put, , in, OneByteInt, integer, int1)
+VARN1(put, , INTENTV, TwoByteInt, integer, int2)
+VARN1(put, , INTENTV, FourByteInt, integer, int)
+VARN1(put, , INTENTV, FourByteReal, real, real)
+VARN1(put, , INTENTV, EightByteReal, real, double)
+VARN1(put, , INTENTV, EightByteInt, integer, int8)
+
+VARN1(put, _all, in, OneByteInt, integer, int1)
+VARN1(put, _all, INTENTV, TwoByteInt, integer, int2)
+VARN1(put, _all, INTENTV, FourByteInt, integer, int)
+VARN1(put, _all, INTENTV, FourByteReal, real, real)
+VARN1(put, _all, INTENTV, EightByteReal, real, double)
+VARN1(put, _all, INTENTV, EightByteInt, integer, int8)
+
+VARN1(get, , out, OneByteInt, integer, int1)
+VARN1(get, , out, TwoByteInt, integer, int2)
+VARN1(get, , out, FourByteInt, integer, int)
+VARN1(get, , out, FourByteReal, real, real)
+VARN1(get, , out, EightByteReal, real, double)
+VARN1(get, , out, EightByteInt, integer, int8)
+
+VARN1(get, _all, out, OneByteInt, integer, int1)
+VARN1(get, _all, out, TwoByteInt, integer, int2)
+VARN1(get, _all, out, FourByteInt, integer, int)
+VARN1(get, _all, out, FourByteReal, real, real)
+VARN1(get, _all, out, EightByteReal, real, double)
+VARN1(get, _all, out, EightByteInt, integer, int8)
+
+dnl
+dnl VARN(ncid, varid, values, num, start, count)
+dnl
+define(`VARN',dnl
+`dnl
+ function nf90mpi_$1_varn_$2_$3$8(ncid, varid, values, num, start, count)
+ integer, intent(in) :: ncid, varid, num
+ $4 (kind=$3), dimension($6), intent($7) :: values
+ integer (kind=MPI_OFFSET_KIND), dimension(:,:), intent(in) :: start
+ integer (kind=MPI_OFFSET_KIND), dimension(:,:), optional, intent(in) :: count
+ integer :: nf90mpi_$1_varn_$2_$3$8
+ integer (kind=MPI_OFFSET_KIND), dimension(nf90_max_var_dims,num) :: localCount
+ integer :: numDims
+
+ ! Set local arguments to default values
+ numDims = size(start(:,1))
+ localCount(1:numDims,1:num) = 1
+ if (present(count)) localCount(1:numDims,1:num) = count(1:numDims,1:num)
+ nf90mpi_$1_varn_$2_$3$8 = nfmpi_$1_varn_$5$8(ncid, varid, num, start, &
+ localCount(1:numDims,1:num), values)
+ end function nf90mpi_$1_varn_$2_$3$8
+')dnl
+
+!
+! put APIs
+!
+
+VARN(put, 1D, OneByteInt, integer, int1, :, in)
+VARN(put, 2D, OneByteInt, integer, int1, `:,:', in)
+VARN(put, 3D, OneByteInt, integer, int1, `:,:,:', in)
+VARN(put, 4D, OneByteInt, integer, int1, `:,:,:,:', in)
+VARN(put, 5D, OneByteInt, integer, int1, `:,:,:,:,:', in)
+VARN(put, 6D, OneByteInt, integer, int1, `:,:,:,:,:,:', in)
+VARN(put, 7D, OneByteInt, integer, int1, `:,:,:,:,:,:,:', in)
+
+VARN(put, 1D, TwoByteInt, integer, int2, :, INTENTV)
+VARN(put, 2D, TwoByteInt, integer, int2, `:,:', INTENTV)
+VARN(put, 3D, TwoByteInt, integer, int2, `:,:,:', INTENTV)
+VARN(put, 4D, TwoByteInt, integer, int2, `:,:,:,:', INTENTV)
+VARN(put, 5D, TwoByteInt, integer, int2, `:,:,:,:,:', INTENTV)
+VARN(put, 6D, TwoByteInt, integer, int2, `:,:,:,:,:,:', INTENTV)
+VARN(put, 7D, TwoByteInt, integer, int2, `:,:,:,:,:,:,:', INTENTV)
+
+VARN(put, 1D, FourByteInt, integer, int, :, INTENTV)
+VARN(put, 2D, FourByteInt, integer, int, `:,:', INTENTV)
+VARN(put, 3D, FourByteInt, integer, int, `:,:,:', INTENTV)
+VARN(put, 4D, FourByteInt, integer, int, `:,:,:,:', INTENTV)
+VARN(put, 5D, FourByteInt, integer, int, `:,:,:,:,:', INTENTV)
+VARN(put, 6D, FourByteInt, integer, int, `:,:,:,:,:,:', INTENTV)
+VARN(put, 7D, FourByteInt, integer, int, `:,:,:,:,:,:,:', INTENTV)
+
+VARN(put, 1D, FourByteReal, real, real, :, INTENTV)
+VARN(put, 2D, FourByteReal, real, real, `:,:', INTENTV)
+VARN(put, 3D, FourByteReal, real, real, `:,:,:', INTENTV)
+VARN(put, 4D, FourByteReal, real, real, `:,:,:,:', INTENTV)
+VARN(put, 5D, FourByteReal, real, real, `:,:,:,:,:', INTENTV)
+VARN(put, 6D, FourByteReal, real, real, `:,:,:,:,:,:', INTENTV)
+VARN(put, 7D, FourByteReal, real, real, `:,:,:,:,:,:,:', INTENTV)
+
+VARN(put, 1D, EightByteReal, real, double, :, INTENTV)
+VARN(put, 2D, EightByteReal, real, double, `:,:', INTENTV)
+VARN(put, 3D, EightByteReal, real, double, `:,:,:', INTENTV)
+VARN(put, 4D, EightByteReal, real, double, `:,:,:,:', INTENTV)
+VARN(put, 5D, EightByteReal, real, double, `:,:,:,:,:', INTENTV)
+VARN(put, 6D, EightByteReal, real, double, `:,:,:,:,:,:', INTENTV)
+VARN(put, 7D, EightByteReal, real, double, `:,:,:,:,:,:,:', INTENTV)
+
+VARN(put, 1D, EightByteInt, integer, int8, :, INTENTV)
+VARN(put, 2D, EightByteInt, integer, int8, `:,:', INTENTV)
+VARN(put, 3D, EightByteInt, integer, int8, `:,:,:', INTENTV)
+VARN(put, 4D, EightByteInt, integer, int8, `:,:,:,:', INTENTV)
+VARN(put, 5D, EightByteInt, integer, int8, `:,:,:,:,:', INTENTV)
+VARN(put, 6D, EightByteInt, integer, int8, `:,:,:,:,:,:', INTENTV)
+VARN(put, 7D, EightByteInt, integer, int8, `:,:,:,:,:,:,:', INTENTV)
+
+!
+! get APIs
+!
+
+VARN(get, 1D, OneByteInt, integer, int1, :, out)
+VARN(get, 2D, OneByteInt, integer, int1, `:,:', out)
+VARN(get, 3D, OneByteInt, integer, int1, `:,:,:', out)
+VARN(get, 4D, OneByteInt, integer, int1, `:,:,:,:', out)
+VARN(get, 5D, OneByteInt, integer, int1, `:,:,:,:,:', out)
+VARN(get, 6D, OneByteInt, integer, int1, `:,:,:,:,:,:', out)
+VARN(get, 7D, OneByteInt, integer, int1, `:,:,:,:,:,:,:', out)
+
+VARN(get, 1D, TwoByteInt, integer, int2, :, out)
+VARN(get, 2D, TwoByteInt, integer, int2, `:,:', out)
+VARN(get, 3D, TwoByteInt, integer, int2, `:,:,:', out)
+VARN(get, 4D, TwoByteInt, integer, int2, `:,:,:,:', out)
+VARN(get, 5D, TwoByteInt, integer, int2, `:,:,:,:,:', out)
+VARN(get, 6D, TwoByteInt, integer, int2, `:,:,:,:,:,:', out)
+VARN(get, 7D, TwoByteInt, integer, int2, `:,:,:,:,:,:,:', out)
+
+VARN(get, 1D, FourByteInt, integer, int, :, out)
+VARN(get, 2D, FourByteInt, integer, int, `:,:', out)
+VARN(get, 3D, FourByteInt, integer, int, `:,:,:', out)
+VARN(get, 4D, FourByteInt, integer, int, `:,:,:,:', out)
+VARN(get, 5D, FourByteInt, integer, int, `:,:,:,:,:', out)
+VARN(get, 6D, FourByteInt, integer, int, `:,:,:,:,:,:', out)
+VARN(get, 7D, FourByteInt, integer, int, `:,:,:,:,:,:,:', out)
+
+VARN(get, 1D, FourByteReal, real, real, :, out)
+VARN(get, 2D, FourByteReal, real, real, `:,:', out)
+VARN(get, 3D, FourByteReal, real, real, `:,:,:', out)
+VARN(get, 4D, FourByteReal, real, real, `:,:,:,:', out)
+VARN(get, 5D, FourByteReal, real, real, `:,:,:,:,:', out)
+VARN(get, 6D, FourByteReal, real, real, `:,:,:,:,:,:', out)
+VARN(get, 7D, FourByteReal, real, real, `:,:,:,:,:,:,:', out)
+
+VARN(get, 1D, EightByteReal, real, double, :, out)
+VARN(get, 2D, EightByteReal, real, double, `:,:', out)
+VARN(get, 3D, EightByteReal, real, double, `:,:,:', out)
+VARN(get, 4D, EightByteReal, real, double, `:,:,:,:', out)
+VARN(get, 5D, EightByteReal, real, double, `:,:,:,:,:', out)
+VARN(get, 6D, EightByteReal, real, double, `:,:,:,:,:,:', out)
+VARN(get, 7D, EightByteReal, real, double, `:,:,:,:,:,:,:', out)
+
+VARN(get, 1D, EightByteInt, integer, int8, :, out)
+VARN(get, 2D, EightByteInt, integer, int8, `:,:', out)
+VARN(get, 3D, EightByteInt, integer, int8, `:,:,:', out)
+VARN(get, 4D, EightByteInt, integer, int8, `:,:,:,:', out)
+VARN(get, 5D, EightByteInt, integer, int8, `:,:,:,:,:', out)
+VARN(get, 6D, EightByteInt, integer, int8, `:,:,:,:,:,:', out)
+VARN(get, 7D, EightByteInt, integer, int8, `:,:,:,:,:,:,:', out)
+
+!
+! collective put APIs
+!
+
+VARN(put, 1D, OneByteInt, integer, int1, :, in, _all)
+VARN(put, 2D, OneByteInt, integer, int1, `:,:', in, _all)
+VARN(put, 3D, OneByteInt, integer, int1, `:,:,:', in, _all)
+VARN(put, 4D, OneByteInt, integer, int1, `:,:,:,:', in, _all)
+VARN(put, 5D, OneByteInt, integer, int1, `:,:,:,:,:', in, _all)
+VARN(put, 6D, OneByteInt, integer, int1, `:,:,:,:,:,:', in, _all)
+VARN(put, 7D, OneByteInt, integer, int1, `:,:,:,:,:,:,:', in, _all)
+
+VARN(put, 1D, TwoByteInt, integer, int2, :, INTENTV, _all)
+VARN(put, 2D, TwoByteInt, integer, int2, `:,:', INTENTV, _all)
+VARN(put, 3D, TwoByteInt, integer, int2, `:,:,:', INTENTV, _all)
+VARN(put, 4D, TwoByteInt, integer, int2, `:,:,:,:', INTENTV, _all)
+VARN(put, 5D, TwoByteInt, integer, int2, `:,:,:,:,:', INTENTV, _all)
+VARN(put, 6D, TwoByteInt, integer, int2, `:,:,:,:,:,:', INTENTV, _all)
+VARN(put, 7D, TwoByteInt, integer, int2, `:,:,:,:,:,:,:', INTENTV, _all)
+
+VARN(put, 1D, FourByteInt, integer, int, :, INTENTV, _all)
+VARN(put, 2D, FourByteInt, integer, int, `:,:', INTENTV, _all)
+VARN(put, 3D, FourByteInt, integer, int, `:,:,:', INTENTV, _all)
+VARN(put, 4D, FourByteInt, integer, int, `:,:,:,:', INTENTV, _all)
+VARN(put, 5D, FourByteInt, integer, int, `:,:,:,:,:', INTENTV, _all)
+VARN(put, 6D, FourByteInt, integer, int, `:,:,:,:,:,:', INTENTV, _all)
+VARN(put, 7D, FourByteInt, integer, int, `:,:,:,:,:,:,:', INTENTV, _all)
+
+VARN(put, 1D, FourByteReal, real, real, :, INTENTV, _all)
+VARN(put, 2D, FourByteReal, real, real, `:,:', INTENTV, _all)
+VARN(put, 3D, FourByteReal, real, real, `:,:,:', INTENTV, _all)
+VARN(put, 4D, FourByteReal, real, real, `:,:,:,:', INTENTV, _all)
+VARN(put, 5D, FourByteReal, real, real, `:,:,:,:,:', INTENTV, _all)
+VARN(put, 6D, FourByteReal, real, real, `:,:,:,:,:,:', INTENTV, _all)
+VARN(put, 7D, FourByteReal, real, real, `:,:,:,:,:,:,:', INTENTV, _all)
+
+VARN(put, 1D, EightByteReal, real, double, :, INTENTV, _all)
+VARN(put, 2D, EightByteReal, real, double, `:,:', INTENTV, _all)
+VARN(put, 3D, EightByteReal, real, double, `:,:,:', INTENTV, _all)
+VARN(put, 4D, EightByteReal, real, double, `:,:,:,:', INTENTV, _all)
+VARN(put, 5D, EightByteReal, real, double, `:,:,:,:,:', INTENTV, _all)
+VARN(put, 6D, EightByteReal, real, double, `:,:,:,:,:,:', INTENTV, _all)
+VARN(put, 7D, EightByteReal, real, double, `:,:,:,:,:,:,:', INTENTV, _all)
+
+VARN(put, 1D, EightByteInt, integer, int8, :, INTENTV, _all)
+VARN(put, 2D, EightByteInt, integer, int8, `:,:', INTENTV, _all)
+VARN(put, 3D, EightByteInt, integer, int8, `:,:,:', INTENTV, _all)
+VARN(put, 4D, EightByteInt, integer, int8, `:,:,:,:', INTENTV, _all)
+VARN(put, 5D, EightByteInt, integer, int8, `:,:,:,:,:', INTENTV, _all)
+VARN(put, 6D, EightByteInt, integer, int8, `:,:,:,:,:,:', INTENTV, _all)
+VARN(put, 7D, EightByteInt, integer, int8, `:,:,:,:,:,:,:', INTENTV, _all)
+
+!
+! collective get APIs
+!
+
+VARN(get, 1D, OneByteInt, integer, int1, :, out, _all)
+VARN(get, 2D, OneByteInt, integer, int1, `:,:', out, _all)
+VARN(get, 3D, OneByteInt, integer, int1, `:,:,:', out, _all)
+VARN(get, 4D, OneByteInt, integer, int1, `:,:,:,:', out, _all)
+VARN(get, 5D, OneByteInt, integer, int1, `:,:,:,:,:', out, _all)
+VARN(get, 6D, OneByteInt, integer, int1, `:,:,:,:,:,:', out, _all)
+VARN(get, 7D, OneByteInt, integer, int1, `:,:,:,:,:,:,:', out, _all)
+
+VARN(get, 1D, TwoByteInt, integer, int2, :, out, _all)
+VARN(get, 2D, TwoByteInt, integer, int2, `:,:', out, _all)
+VARN(get, 3D, TwoByteInt, integer, int2, `:,:,:', out, _all)
+VARN(get, 4D, TwoByteInt, integer, int2, `:,:,:,:', out, _all)
+VARN(get, 5D, TwoByteInt, integer, int2, `:,:,:,:,:', out, _all)
+VARN(get, 6D, TwoByteInt, integer, int2, `:,:,:,:,:,:', out, _all)
+VARN(get, 7D, TwoByteInt, integer, int2, `:,:,:,:,:,:,:', out, _all)
+
+VARN(get, 1D, FourByteInt, integer, int, :, out, _all)
+VARN(get, 2D, FourByteInt, integer, int, `:,:', out, _all)
+VARN(get, 3D, FourByteInt, integer, int, `:,:,:', out, _all)
+VARN(get, 4D, FourByteInt, integer, int, `:,:,:,:', out, _all)
+VARN(get, 5D, FourByteInt, integer, int, `:,:,:,:,:', out, _all)
+VARN(get, 6D, FourByteInt, integer, int, `:,:,:,:,:,:', out, _all)
+VARN(get, 7D, FourByteInt, integer, int, `:,:,:,:,:,:,:', out, _all)
+
+VARN(get, 1D, FourByteReal, real, real, :, out, _all)
+VARN(get, 2D, FourByteReal, real, real, `:,:', out, _all)
+VARN(get, 3D, FourByteReal, real, real, `:,:,:', out, _all)
+VARN(get, 4D, FourByteReal, real, real, `:,:,:,:', out, _all)
+VARN(get, 5D, FourByteReal, real, real, `:,:,:,:,:', out, _all)
+VARN(get, 6D, FourByteReal, real, real, `:,:,:,:,:,:', out, _all)
+VARN(get, 7D, FourByteReal, real, real, `:,:,:,:,:,:,:', out, _all)
+
+VARN(get, 1D, EightByteReal, real, double, :, out, _all)
+VARN(get, 2D, EightByteReal, real, double, `:,:', out, _all)
+VARN(get, 3D, EightByteReal, real, double, `:,:,:', out, _all)
+VARN(get, 4D, EightByteReal, real, double, `:,:,:,:', out, _all)
+VARN(get, 5D, EightByteReal, real, double, `:,:,:,:,:', out, _all)
+VARN(get, 6D, EightByteReal, real, double, `:,:,:,:,:,:', out, _all)
+VARN(get, 7D, EightByteReal, real, double, `:,:,:,:,:,:,:', out, _all)
+
+VARN(get, 1D, EightByteInt, integer, int8, :, out, _all)
+VARN(get, 2D, EightByteInt, integer, int8, `:,:', out, _all)
+VARN(get, 3D, EightByteInt, integer, int8, `:,:,:', out, _all)
+VARN(get, 4D, EightByteInt, integer, int8, `:,:,:,:', out, _all)
+VARN(get, 5D, EightByteInt, integer, int8, `:,:,:,:,:', out, _all)
+VARN(get, 6D, EightByteInt, integer, int8, `:,:,:,:,:,:', out, _all)
+VARN(get, 7D, EightByteInt, integer, int8, `:,:,:,:,:,:,:', out, _all)
+
+!
+! text variable
+!
+
+dnl
+dnl TEXTVARN1(ncid, varid, values, num, start, count)
+dnl
+define(`TEXTVARN1',dnl
+`dnl
+ ! $1 a scalar of type character (len = *)
+ function nf90mpi_$1_varn_text$3(ncid, varid, value, start)
+ integer, intent(in) :: ncid, varid
+ character (len=*), intent($2) :: value
+ integer (kind=MPI_OFFSET_KIND), dimension(:,:), intent(in) :: start
+ integer :: nf90mpi_$1_varn_text$3
+
+ nf90mpi_$1_varn_text$3 = nfmpi_$1_var1_text$3(ncid, varid, start(:,1), value)
+ end function nf90mpi_$1_varn_text$3
+')dnl
+
+TEXTVARN1(put, in)
+TEXTVARN1(get, out)
+TEXTVARN1(put, in, _all)
+TEXTVARN1(get, out, _all)
+
+dnl
+dnl TEXTVARN(ncid, varid, values, num, start, count)
+dnl
+define(`TEXTVARN',dnl
+`dnl
+ function nf90mpi_$1_varn_$2_text$6(ncid, varid, values, num, start, count)
+ integer, intent(in) :: ncid, varid, num
+ character (len=*), dimension($3), intent($5) :: values
+ integer (kind=MPI_OFFSET_KIND), dimension(:,:), intent(in) :: start
+ integer (kind=MPI_OFFSET_KIND), dimension(:,:), optional, intent(in) :: count
+ integer :: nf90mpi_$1_varn_$2_text$6
+ integer (kind=MPI_OFFSET_KIND), dimension(nf90_max_var_dims,num) :: localCount
+ integer :: numDims
+
+ ! Set local arguments to default values
+ numDims = size(start(:,1))
+ localCount(1:numDims,1:num) = 1
+ if (present(count)) localCount(1:numDims,1:num) = count(1:numDims,1:num)
+ nf90mpi_$1_varn_$2_text$6 = nfmpi_$1_varn_text$6(ncid, varid, num, start, &
+ localCount(1:numDims,1:num), values($4))
+ end function nf90mpi_$1_varn_$2_text$6
+')dnl
+
+TEXTVARN(put, 1D, :, 1, in)
+TEXTVARN(put, 2D, `:,:', `1,1', in)
+TEXTVARN(put, 3D, `:,:,:', `1,1,1', in)
+TEXTVARN(put, 4D, `:,:,:,:', `1,1,1,1', in)
+TEXTVARN(put, 5D, `:,:,:,:,:', `1,1,1,1,1', in)
+TEXTVARN(put, 6D, `:,:,:,:,:,:', `1,1,1,1,1,1', in)
+TEXTVARN(put, 7D, `:,:,:,:,:,:,:', `1,1,1,1,1,1,1', in)
+
+TEXTVARN(get, 1D, :, 1, out)
+TEXTVARN(get, 2D, `:,:', `1,1', out)
+TEXTVARN(get, 3D, `:,:,:', `1,1,1', out)
+TEXTVARN(get, 4D, `:,:,:,:', `1,1,1,1', out)
+TEXTVARN(get, 5D, `:,:,:,:,:', `1,1,1,1,1', out)
+TEXTVARN(get, 6D, `:,:,:,:,:,:', `1,1,1,1,1,1', out)
+TEXTVARN(get, 7D, `:,:,:,:,:,:,:', `1,1,1,1,1,1,1', out)
+
+!
+! Collective APIs
+!
+
+TEXTVARN(put, 1D, :, 1, in, _all)
+TEXTVARN(put, 2D, `:,:', `1,1', in, _all)
+TEXTVARN(put, 3D, `:,:,:', `1,1,1', in, _all)
+TEXTVARN(put, 4D, `:,:,:,:', `1,1,1,1', in, _all)
+TEXTVARN(put, 5D, `:,:,:,:,:', `1,1,1,1,1', in, _all)
+TEXTVARN(put, 6D, `:,:,:,:,:,:', `1,1,1,1,1,1', in, _all)
+TEXTVARN(put, 7D, `:,:,:,:,:,:,:', `1,1,1,1,1,1,1', in, _all)
+
+TEXTVARN(get, 1D, :, 1, out, _all)
+TEXTVARN(get, 2D, `:,:', `1,1', out, _all)
+TEXTVARN(get, 3D, `:,:,:', `1,1,1', out, _all)
+TEXTVARN(get, 4D, `:,:,:,:', `1,1,1,1', out, _all)
+TEXTVARN(get, 5D, `:,:,:,:,:', `1,1,1,1,1', out, _all)
+TEXTVARN(get, 6D, `:,:,:,:,:,:', `1,1,1,1,1,1', out, _all)
+TEXTVARN(get, 7D, `:,:,:,:,:,:,:', `1,1,1,1,1,1,1', out, _all)
+
+!
+! Nonblocking APIs
+!
+
+dnl
+dnl IVARN1
+dnl
+define(`IVARN1',dnl
+`dnl
+ ! $1 a scalar of type $4 (kind=$3)
+ function nf90mpi_$1_varn_$3(ncid, varid, value, req, start)
+ integer, intent(in) :: ncid, varid
+ $4 (kind=$3), intent($2) :: value
+ integer, intent(out):: req
+ integer (kind=MPI_OFFSET_KIND), dimension(:,:), intent(in) :: start
+ integer :: nf90mpi_$1_varn_$3
+
+ nf90mpi_$1_varn_$3 = nfmpi_$1_var1_$5(ncid, varid, start(:,1), value, req)
+ end function nf90mpi_$1_varn_$3
+')dnl
+
+IVARN1(iput, in, OneByteInt, integer, int1)
+IVARN1(iput, INTENTV, TwoByteInt, integer, int2)
+IVARN1(iput, INTENTV, FourByteInt, integer, int)
+IVARN1(iput, INTENTV, FourByteReal, real, real)
+IVARN1(iput, INTENTV, EightByteReal, real, double)
+IVARN1(iput, INTENTV, EightByteInt, integer, int8)
+
+IVARN1(iget, out, OneByteInt, integer, int1)
+IVARN1(iget, out, TwoByteInt, integer, int2)
+IVARN1(iget, out, FourByteInt, integer, int)
+IVARN1(iget, out, FourByteReal, real, real)
+IVARN1(iget, out, EightByteReal, real, double)
+IVARN1(iget, out, EightByteInt, integer, int8)
+
+IVARN1(bput, in, OneByteInt, integer, int1)
+IVARN1(bput, INTENTV, TwoByteInt, integer, int2)
+IVARN1(bput, INTENTV, FourByteInt, integer, int)
+IVARN1(bput, INTENTV, FourByteReal, real, real)
+IVARN1(bput, INTENTV, EightByteReal, real, double)
+IVARN1(bput, INTENTV, EightByteInt, integer, int8)
+
+dnl
+dnl IVARN(ncid, varid, values, num, start, count)
+dnl
+define(`IVARN',dnl
+`dnl
+ function nf90mpi_$1_varn_$2_$3(ncid, varid, values, req, num, start, count)
+ integer, intent(in) :: ncid, varid, num
+ $4 (kind=$3), dimension($6), intent($7) :: values
+ integer, intent(out):: req
+ integer (kind=MPI_OFFSET_KIND), dimension(:,:), intent(in) :: start
+ integer (kind=MPI_OFFSET_KIND), dimension(:,:), optional, intent(in) :: count
+ integer :: nf90mpi_$1_varn_$2_$3
+ integer (kind=MPI_OFFSET_KIND), dimension(nf90_max_var_dims,num) :: localCount
+ integer :: numDims
+
+ ! Set local arguments to default values
+ numDims = size(start(:,1))
+ localCount(1:numDims,1:num) = 1
+ if (present(count)) localCount(1:numDims,1:num) = count(1:numDims,1:num)
+ nf90mpi_$1_varn_$2_$3 = nfmpi_$1_varn_$5(ncid, varid, num, start, &
+ localCount(1:numDims,1:num), values, req)
+ end function nf90mpi_$1_varn_$2_$3
+')dnl
+
+!
+! put APIs
+!
+
+IVARN(iput, 1D, OneByteInt, integer, int1, :, in)
+IVARN(iput, 2D, OneByteInt, integer, int1, `:,:', in)
+IVARN(iput, 3D, OneByteInt, integer, int1, `:,:,:', in)
+IVARN(iput, 4D, OneByteInt, integer, int1, `:,:,:,:', in)
+IVARN(iput, 5D, OneByteInt, integer, int1, `:,:,:,:,:', in)
+IVARN(iput, 6D, OneByteInt, integer, int1, `:,:,:,:,:,:', in)
+IVARN(iput, 7D, OneByteInt, integer, int1, `:,:,:,:,:,:,:', in)
+
+IVARN(iput, 1D, TwoByteInt, integer, int2, :, INTENTV)
+IVARN(iput, 2D, TwoByteInt, integer, int2, `:,:', INTENTV)
+IVARN(iput, 3D, TwoByteInt, integer, int2, `:,:,:', INTENTV)
+IVARN(iput, 4D, TwoByteInt, integer, int2, `:,:,:,:', INTENTV)
+IVARN(iput, 5D, TwoByteInt, integer, int2, `:,:,:,:,:', INTENTV)
+IVARN(iput, 6D, TwoByteInt, integer, int2, `:,:,:,:,:,:', INTENTV)
+IVARN(iput, 7D, TwoByteInt, integer, int2, `:,:,:,:,:,:,:', INTENTV)
+
+IVARN(iput, 1D, FourByteInt, integer, int, :, INTENTV)
+IVARN(iput, 2D, FourByteInt, integer, int, `:,:', INTENTV)
+IVARN(iput, 3D, FourByteInt, integer, int, `:,:,:', INTENTV)
+IVARN(iput, 4D, FourByteInt, integer, int, `:,:,:,:', INTENTV)
+IVARN(iput, 5D, FourByteInt, integer, int, `:,:,:,:,:', INTENTV)
+IVARN(iput, 6D, FourByteInt, integer, int, `:,:,:,:,:,:', INTENTV)
+IVARN(iput, 7D, FourByteInt, integer, int, `:,:,:,:,:,:,:', INTENTV)
+
+IVARN(iput, 1D, FourByteReal, real, real, :, INTENTV)
+IVARN(iput, 2D, FourByteReal, real, real, `:,:', INTENTV)
+IVARN(iput, 3D, FourByteReal, real, real, `:,:,:', INTENTV)
+IVARN(iput, 4D, FourByteReal, real, real, `:,:,:,:', INTENTV)
+IVARN(iput, 5D, FourByteReal, real, real, `:,:,:,:,:', INTENTV)
+IVARN(iput, 6D, FourByteReal, real, real, `:,:,:,:,:,:', INTENTV)
+IVARN(iput, 7D, FourByteReal, real, real, `:,:,:,:,:,:,:', INTENTV)
+
+IVARN(iput, 1D, EightByteReal, real, double, :, INTENTV)
+IVARN(iput, 2D, EightByteReal, real, double, `:,:', INTENTV)
+IVARN(iput, 3D, EightByteReal, real, double, `:,:,:', INTENTV)
+IVARN(iput, 4D, EightByteReal, real, double, `:,:,:,:', INTENTV)
+IVARN(iput, 5D, EightByteReal, real, double, `:,:,:,:,:', INTENTV)
+IVARN(iput, 6D, EightByteReal, real, double, `:,:,:,:,:,:', INTENTV)
+IVARN(iput, 7D, EightByteReal, real, double, `:,:,:,:,:,:,:', INTENTV)
+
+IVARN(iput, 1D, EightByteInt, integer, int8, :, INTENTV)
+IVARN(iput, 2D, EightByteInt, integer, int8, `:,:', INTENTV)
+IVARN(iput, 3D, EightByteInt, integer, int8, `:,:,:', INTENTV)
+IVARN(iput, 4D, EightByteInt, integer, int8, `:,:,:,:', INTENTV)
+IVARN(iput, 5D, EightByteInt, integer, int8, `:,:,:,:,:', INTENTV)
+IVARN(iput, 6D, EightByteInt, integer, int8, `:,:,:,:,:,:', INTENTV)
+IVARN(iput, 7D, EightByteInt, integer, int8, `:,:,:,:,:,:,:', INTENTV)
+
+!
+! get APIs
+!
+
+IVARN(iget, 1D, OneByteInt, integer, int1, :, out)
+IVARN(iget, 2D, OneByteInt, integer, int1, `:,:', out)
+IVARN(iget, 3D, OneByteInt, integer, int1, `:,:,:', out)
+IVARN(iget, 4D, OneByteInt, integer, int1, `:,:,:,:', out)
+IVARN(iget, 5D, OneByteInt, integer, int1, `:,:,:,:,:', out)
+IVARN(iget, 6D, OneByteInt, integer, int1, `:,:,:,:,:,:', out)
+IVARN(iget, 7D, OneByteInt, integer, int1, `:,:,:,:,:,:,:', out)
+
+IVARN(iget, 1D, TwoByteInt, integer, int2, :, out)
+IVARN(iget, 2D, TwoByteInt, integer, int2, `:,:', out)
+IVARN(iget, 3D, TwoByteInt, integer, int2, `:,:,:', out)
+IVARN(iget, 4D, TwoByteInt, integer, int2, `:,:,:,:', out)
+IVARN(iget, 5D, TwoByteInt, integer, int2, `:,:,:,:,:', out)
+IVARN(iget, 6D, TwoByteInt, integer, int2, `:,:,:,:,:,:', out)
+IVARN(iget, 7D, TwoByteInt, integer, int2, `:,:,:,:,:,:,:', out)
+
+IVARN(iget, 1D, FourByteInt, integer, int, :, out)
+IVARN(iget, 2D, FourByteInt, integer, int, `:,:', out)
+IVARN(iget, 3D, FourByteInt, integer, int, `:,:,:', out)
+IVARN(iget, 4D, FourByteInt, integer, int, `:,:,:,:', out)
+IVARN(iget, 5D, FourByteInt, integer, int, `:,:,:,:,:', out)
+IVARN(iget, 6D, FourByteInt, integer, int, `:,:,:,:,:,:', out)
+IVARN(iget, 7D, FourByteInt, integer, int, `:,:,:,:,:,:,:', out)
+
+IVARN(iget, 1D, FourByteReal, real, real, :, out)
+IVARN(iget, 2D, FourByteReal, real, real, `:,:', out)
+IVARN(iget, 3D, FourByteReal, real, real, `:,:,:', out)
+IVARN(iget, 4D, FourByteReal, real, real, `:,:,:,:', out)
+IVARN(iget, 5D, FourByteReal, real, real, `:,:,:,:,:', out)
+IVARN(iget, 6D, FourByteReal, real, real, `:,:,:,:,:,:', out)
+IVARN(iget, 7D, FourByteReal, real, real, `:,:,:,:,:,:,:', out)
+
+IVARN(iget, 1D, EightByteReal, real, double, :, out)
+IVARN(iget, 2D, EightByteReal, real, double, `:,:', out)
+IVARN(iget, 3D, EightByteReal, real, double, `:,:,:', out)
+IVARN(iget, 4D, EightByteReal, real, double, `:,:,:,:', out)
+IVARN(iget, 5D, EightByteReal, real, double, `:,:,:,:,:', out)
+IVARN(iget, 6D, EightByteReal, real, double, `:,:,:,:,:,:', out)
+IVARN(iget, 7D, EightByteReal, real, double, `:,:,:,:,:,:,:', out)
+
+IVARN(iget, 1D, EightByteInt, integer, int8, :, out)
+IVARN(iget, 2D, EightByteInt, integer, int8, `:,:', out)
+IVARN(iget, 3D, EightByteInt, integer, int8, `:,:,:', out)
+IVARN(iget, 4D, EightByteInt, integer, int8, `:,:,:,:', out)
+IVARN(iget, 5D, EightByteInt, integer, int8, `:,:,:,:,:', out)
+IVARN(iget, 6D, EightByteInt, integer, int8, `:,:,:,:,:,:', out)
+IVARN(iget, 7D, EightByteInt, integer, int8, `:,:,:,:,:,:,:', out)
+
+!
+! bput APIs
+!
+
+IVARN(bput, 1D, OneByteInt, integer, int1, :, in)
+IVARN(bput, 2D, OneByteInt, integer, int1, `:,:', in)
+IVARN(bput, 3D, OneByteInt, integer, int1, `:,:,:', in)
+IVARN(bput, 4D, OneByteInt, integer, int1, `:,:,:,:', in)
+IVARN(bput, 5D, OneByteInt, integer, int1, `:,:,:,:,:', in)
+IVARN(bput, 6D, OneByteInt, integer, int1, `:,:,:,:,:,:', in)
+IVARN(bput, 7D, OneByteInt, integer, int1, `:,:,:,:,:,:,:', in)
+
+IVARN(bput, 1D, TwoByteInt, integer, int2, :, INTENTV)
+IVARN(bput, 2D, TwoByteInt, integer, int2, `:,:', INTENTV)
+IVARN(bput, 3D, TwoByteInt, integer, int2, `:,:,:', INTENTV)
+IVARN(bput, 4D, TwoByteInt, integer, int2, `:,:,:,:', INTENTV)
+IVARN(bput, 5D, TwoByteInt, integer, int2, `:,:,:,:,:', INTENTV)
+IVARN(bput, 6D, TwoByteInt, integer, int2, `:,:,:,:,:,:', INTENTV)
+IVARN(bput, 7D, TwoByteInt, integer, int2, `:,:,:,:,:,:,:', INTENTV)
+
+IVARN(bput, 1D, FourByteInt, integer, int, :, INTENTV)
+IVARN(bput, 2D, FourByteInt, integer, int, `:,:', INTENTV)
+IVARN(bput, 3D, FourByteInt, integer, int, `:,:,:', INTENTV)
+IVARN(bput, 4D, FourByteInt, integer, int, `:,:,:,:', INTENTV)
+IVARN(bput, 5D, FourByteInt, integer, int, `:,:,:,:,:', INTENTV)
+IVARN(bput, 6D, FourByteInt, integer, int, `:,:,:,:,:,:', INTENTV)
+IVARN(bput, 7D, FourByteInt, integer, int, `:,:,:,:,:,:,:', INTENTV)
+
+IVARN(bput, 1D, FourByteReal, real, real, :, INTENTV)
+IVARN(bput, 2D, FourByteReal, real, real, `:,:', INTENTV)
+IVARN(bput, 3D, FourByteReal, real, real, `:,:,:', INTENTV)
+IVARN(bput, 4D, FourByteReal, real, real, `:,:,:,:', INTENTV)
+IVARN(bput, 5D, FourByteReal, real, real, `:,:,:,:,:', INTENTV)
+IVARN(bput, 6D, FourByteReal, real, real, `:,:,:,:,:,:', INTENTV)
+IVARN(bput, 7D, FourByteReal, real, real, `:,:,:,:,:,:,:', INTENTV)
+
+IVARN(bput, 1D, EightByteReal, real, double, :, INTENTV)
+IVARN(bput, 2D, EightByteReal, real, double, `:,:', INTENTV)
+IVARN(bput, 3D, EightByteReal, real, double, `:,:,:', INTENTV)
+IVARN(bput, 4D, EightByteReal, real, double, `:,:,:,:', INTENTV)
+IVARN(bput, 5D, EightByteReal, real, double, `:,:,:,:,:', INTENTV)
+IVARN(bput, 6D, EightByteReal, real, double, `:,:,:,:,:,:', INTENTV)
+IVARN(bput, 7D, EightByteReal, real, double, `:,:,:,:,:,:,:', INTENTV)
+
+IVARN(bput, 1D, EightByteInt, integer, int8, :, INTENTV)
+IVARN(bput, 2D, EightByteInt, integer, int8, `:,:', INTENTV)
+IVARN(bput, 3D, EightByteInt, integer, int8, `:,:,:', INTENTV)
+IVARN(bput, 4D, EightByteInt, integer, int8, `:,:,:,:', INTENTV)
+IVARN(bput, 5D, EightByteInt, integer, int8, `:,:,:,:,:', INTENTV)
+IVARN(bput, 6D, EightByteInt, integer, int8, `:,:,:,:,:,:', INTENTV)
+IVARN(bput, 7D, EightByteInt, integer, int8, `:,:,:,:,:,:,:', INTENTV)
+
+!
+! text variable
+!
+
+dnl
+dnl ITEXTVARN1
+dnl
+define(`ITEXTVARN1',dnl
+`dnl
+ ! $1 a scalar of type character (len = *)
+ function nf90mpi_$1_varn_text(ncid, varid, value, req, start)
+ integer, intent(in) :: ncid, varid
+ character (len = *), intent($2) :: value
+ integer, intent(out):: req
+ integer (kind=MPI_OFFSET_KIND), dimension(:,:), intent(in) :: start
+ integer :: nf90mpi_$1_varn_text
+
+ nf90mpi_$1_varn_text = nfmpi_$1_var1_text(ncid, varid, start(:,1), value, req)
+ end function nf90mpi_$1_varn_text
+')dnl
+
+ITEXTVARN1(iput, in)
+ITEXTVARN1(iget, out)
+ITEXTVARN1(bput, in)
+
+dnl
+dnl ITEXTVARN(ncid, varid, values, num, start, count)
+dnl
+define(`ITEXTVARN',dnl
+`dnl
+ function nf90mpi_$1_varn_$2_text(ncid, varid, values, req, num, start, count)
+ integer, intent(in) :: ncid, varid, num
+ character (len=*), dimension($3), intent($5) :: values
+ integer, intent(out):: req
+ integer (kind=MPI_OFFSET_KIND), dimension(:,:), intent(in) :: start
+ integer (kind=MPI_OFFSET_KIND), dimension(:,:), optional, intent(in) :: count
+ integer :: nf90mpi_$1_varn_$2_text
+ integer (kind=MPI_OFFSET_KIND), dimension(nf90_max_var_dims,num) :: localCount
+ integer :: numDims
+
+ ! Set local arguments to default values
+ numDims = size(start(:,1))
+ localCount(1:numDims,1:num) = 1
+ if (present(count)) localCount(1:numDims,1:num) = count(1:numDims,1:num)
+ nf90mpi_$1_varn_$2_text = nfmpi_$1_varn_text(ncid, varid, num, start, &
+ localCount(1:numDims,1:num), values($4), req)
+ end function nf90mpi_$1_varn_$2_text
+')dnl
+
+ITEXTVARN(iput, 1D, :, 1, in)
+ITEXTVARN(iput, 2D, `:,:', `1,1', in)
+ITEXTVARN(iput, 3D, `:,:,:', `1,1,1', in)
+ITEXTVARN(iput, 4D, `:,:,:,:', `1,1,1,1', in)
+ITEXTVARN(iput, 5D, `:,:,:,:,:', `1,1,1,1,1', in)
+ITEXTVARN(iput, 6D, `:,:,:,:,:,:', `1,1,1,1,1,1', in)
+ITEXTVARN(iput, 7D, `:,:,:,:,:,:,:', `1,1,1,1,1,1,1', in)
+
+ITEXTVARN(iget, 1D, :, 1, out)
+ITEXTVARN(iget, 2D, `:,:', `1,1', out)
+ITEXTVARN(iget, 3D, `:,:,:', `1,1,1', out)
+ITEXTVARN(iget, 4D, `:,:,:,:', `1,1,1,1', out)
+ITEXTVARN(iget, 5D, `:,:,:,:,:', `1,1,1,1,1', out)
+ITEXTVARN(iget, 6D, `:,:,:,:,:,:', `1,1,1,1,1,1', out)
+ITEXTVARN(iget, 7D, `:,:,:,:,:,:,:', `1,1,1,1,1,1,1', out)
+
+ITEXTVARN(bput, 1D, :, 1, in)
+ITEXTVARN(bput, 2D, `:,:', `1,1', in)
+ITEXTVARN(bput, 3D, `:,:,:', `1,1,1', in)
+ITEXTVARN(bput, 4D, `:,:,:,:', `1,1,1,1', in)
+ITEXTVARN(bput, 5D, `:,:,:,:,:', `1,1,1,1,1', in)
+ITEXTVARN(bput, 6D, `:,:,:,:,:,:', `1,1,1,1,1,1', in)
+ITEXTVARN(bput, 7D, `:,:,:,:,:,:,:', `1,1,1,1,1,1,1', in)
+
diff --git a/src/libf90/nf90_constants.f90 b/src/libf90/nf90_constants.f90
new file mode 100644
index 0000000..cc8caf2
--- /dev/null
+++ b/src/libf90/nf90_constants.f90
@@ -0,0 +1,302 @@
+!
+! Copyright (C) 2013, Northwestern University and Argonne National Laboratory
+! See COPYRIGHT notice in top-level directory.
+!
+! $Id: nf90_constants.f90 2195 2015-11-27 18:42:11Z wkliao $
+!
+! This file is taken from netcdf_constants.f90 with changes for PnetCDF use
+!
+!
+ !
+ ! external netcdf data types:
+ !
+ integer, parameter, public :: &
+ nf90_byte = 1, &
+ nf90_int1 = nf90_byte, &
+ nf90_char = 2, &
+ nf90_short = 3, &
+ nf90_int2 = nf90_short, &
+ nf90_int = 4, &
+ nf90_int4 = nf90_int, &
+ nf90_float = 5, &
+ nf90_real = nf90_float, &
+ nf90_real4 = nf90_float, &
+ nf90_double = 6, &
+ nf90_real8 = nf90_double, &
+ nf90_ubyte = 7, &
+ nf90_ushort = 8, &
+ nf90_uint = 9, &
+ nf90_int64 = 10, &
+ nf90_uint64 = 11
+
+ !
+ ! default fill values:
+ !
+ ! character (len = 1), parameter, public :: &
+ ! nf90_fill_char = achar(0)
+ integer (kind = OneByteInt), parameter, public :: &
+ nf90_fill_char = 0, &
+ nf90_fill_byte = -127, &
+ nf90_fill_int1 = nf90_fill_byte
+ integer (kind = TwoByteInt), parameter, public :: &
+ nf90_fill_short = -32767, &
+ nf90_fill_int2 = nf90_fill_short, &
+ nf90_fill_ubyte = 255
+ integer (kind = FourByteInt), parameter, public :: &
+ nf90_fill_int = -2147483647, &
+ nf90_fill_ushort = 65535
+ real (kind = FourByteReal), parameter, public :: &
+ nf90_fill_float = 9.9692099683868690e+36, &
+ nf90_fill_real = nf90_fill_float, &
+ nf90_fill_real4 = nf90_fill_float
+ real (kind = EightByteReal), parameter, public :: &
+ nf90_fill_double = 9.9692099683868690e+36, &
+ nf90_fill_real8 = nf90_fill_double, &
+ nf90_fill_uint64 = 1.8446744073709551614e+19
+ integer (kind = EightByteInt), parameter, public :: &
+ nf90_fill_uint = 4294967295_EightByteInt, &
+ nf90_fill_int64 = -9223372036854775806_EightByteInt
+
+ !
+ ! mode flags for opening and creating a netcdf dataset:
+ !
+ integer, parameter, public :: &
+ nf90_nowrite = 0, &
+ nf90_write = 1, &
+ nf90_clobber = 0, &
+ nf90_noclobber = 4, &
+ nf90_fill = 0, &
+ nf90_nofill = 256, &
+ nf90_64bit_offset = 512, &
+ nf90_64bit_data = 32, &
+ nf90_lock = 1024, &
+ nf90_share = 2048
+
+ integer, parameter, public :: &
+ nf90_sizehint_default = 0, &
+ nf90_align_chunk = -1
+
+ !
+ ! size argument for defining an unlimited dimension:
+ !
+ integer, parameter, public :: &
+ nf90_unlimited = 0
+
+ integer(KIND=MPI_OFFSET_KIND), parameter, public :: &
+ nf90mpi_unlimited = 0
+
+ ! NULL request for non-blocking I/O APIs
+ integer, parameter, public :: nf90_req_null = -1
+
+ ! indicate to flush all pending non-blocking requests
+ integer, parameter, public :: nf90_req_all = -1
+
+ !
+ ! global attribute id:
+ !
+ integer, parameter, public :: nf90_global = 0
+
+ !
+ ! implementation limits:
+ !
+ integer, parameter, public :: &
+ nf90_max_dims = 1024, &
+ nf90_max_attrs = 8192, &
+ nf90_max_vars = 8192, &
+ nf90_max_name = 256, &
+ nf90_max_var_dims = 1024
+
+ !
+ ! error handling modes:
+ !
+ integer, parameter, public :: &
+ nf90_fatal = 1, &
+ nf90_verbose = 2
+
+ !
+ ! format version numbers:
+ !
+ integer, parameter, public :: &
+ nf90_format_classic = 1, &
+ nf90_format_cdf2 = 2, &
+ nf90_format_netcdf4 = 3, &
+ nf90_format_netcdf4_classic = 4, &
+ nf90_format_cdf5 = 5, &
+ nf90_format_64bit = nf90_format_cdf2, &
+ nf90_format_64bit_offset = nf90_format_cdf2, &
+ nf90_format_64bit_data = nf90_format_cdf5
+
+ !
+ ! error codes:
+ !
+ integer, parameter, public :: &
+ NF90_NOERR = NF_NOERR , & ! No Error
+ NF90_EBADID = NF_EBADID , & ! Not a netcdf id
+ NF90_ENFILE = NF_ENFILE , & ! Too many netcdfs open
+ NF90_EEXIST = NF_EEXIST , & ! netcdf file exists and NF_NOCLOBBER
+ NF90_EINVAL = NF_EINVAL , & ! Invalid Argument
+ NF90_EPERM = NF_EPERM , & ! Write to read only
+ NF90_ENOTINDEFINE = NF_ENOTINDEFINE , & ! Operation not allowed in data mode
+ NF90_EINDEFINE = NF_EINDEFINE , & ! Operation not allowed in define mode
+ NF90_EINVALCOORDS = NF_EINVALCOORDS , & ! Index exceeds dimension bound
+ NF90_EMAXDIMS = NF_EMAXDIMS , & ! NF_MAX_DIMS exceeded
+ NF90_ENAMEINUSE = NF_ENAMEINUSE , & ! String match to name in use
+ NF90_ENOTATT = NF_ENOTATT , & ! Attribute not found
+ NF90_EMAXATTS = NF_EMAXATTS , & ! NF_MAX_ATTRS exceeded
+ NF90_EBADTYPE = NF_EBADTYPE , & ! Not a netcdf data type
+ NF90_EBADDIM = NF_EBADDIM , & ! Invalid dimension id or name
+ NF90_EUNLIMPOS = NF_EUNLIMPOS , & ! NFMPI_UNLIMITED in the wrong index
+ NF90_EMAXVARS = NF_EMAXVARS , & ! NF_MAX_VARS exceeded
+ NF90_ENOTVAR = NF_ENOTVAR , & ! Variable not found
+ NF90_EGLOBAL = NF_EGLOBAL , & ! Action prohibited on NF_GLOBAL varid
+ NF90_ENOTNC = NF_ENOTNC , & ! Not a netcdf file
+ NF90_ESTS = NF_ESTS , & ! In Fortran, string too short
+ NF90_EMAXNAME = NF_EMAXNAME , & ! NF_MAX_NAME exceeded
+ NF90_EUNLIMIT = NF_EUNLIMIT , & ! NFMPI_UNLIMITED size already in use
+ NF90_ENORECVARS = NF_ENORECVARS , & ! nc_rec op when there are no record vars
+ NF90_ECHAR = NF_ECHAR , & ! Attempt to convert between text & numbers
+ NF90_EEDGE = NF_EEDGE , & ! Edge+start exceeds dimension bound
+ NF90_ESTRIDE = NF_ESTRIDE , & ! Illegal stride
+ NF90_EBADNAME = NF_EBADNAME , & ! Attribute or variable name contains illegal characters
+ NF90_ERANGE = NF_ERANGE , & ! Math result not representable
+ NF90_ENOMEM = NF_ENOMEM , & ! Memory allocation (malloc) failure
+ NF90_EVARSIZE = NF_EVARSIZE , & ! One or more variable sizes violate format constraints
+ NF90_EDIMSIZE = NF_EDIMSIZE , & ! Invalid dimension size
+ NF90_ETRUNC = NF_ETRUNC , & ! File likely truncated or possibly corrupted
+ NF90_EAXISTYPE = NF_EAXISTYPE ! Unknown axis type
+
+ ! Following errors are added for DAP
+ integer, parameter, public :: &
+ NF90_EDAP = NF_EDAP , & ! Generic DAP error
+ NF90_ECURL = NF_ECURL , & ! Generic libcurl error
+ NF90_EIO = NF_EIO , & ! Generic IO error
+ NF90_ENODATA = NF_ENODATA , & ! Attempt to access variable with no data
+ NF90_EDAPSVC = NF_EDAPSVC , & ! DAP server error
+ NF90_EDAS = NF_EDAS , & ! Malformed or inaccessible DAS
+ NF90_EDDS = NF_EDDS , & ! Malformed or inaccessible DDS
+ NF90_EDATADDS = NF_EDATADDS , & ! Malformed or inaccessible DATADDS
+ NF90_EDAPURL = NF_EDAPURL , & ! Malformed DAP URL
+ NF90_EDAPCONSTRAINT = NF_EDAPCONSTRAINT, & ! Malformed DAP Constraint
+ NF90_ETRANSLATION = NF_ETRANSLATION , & ! Untranslatable construct
+ NF90_EACCESS = NF_EACCESS , & ! Access Failure
+ NF90_EAUTH = NF_EAUTH ! Authorization Failure
+
+ ! Misc. additional errors
+ integer, parameter, public :: &
+ NF90_ENOTFOUND = NF_ENOTFOUND , & ! No such file
+ NF90_ECANTREMOVE = NF_ECANTREMOVE ! Can't remove file
+
+ ! netCDF-4 error codes (copied from netCDF release)
+ integer, parameter, public :: &
+ NF90_EHDFERR = NF_EHDFERR , & ! Error at HDF5 layer.
+ NF90_ECANTREAD = NF_ECANTREAD , & ! Can't read.
+ NF90_ECANTWRITE = NF_ECANTWRITE , & ! Can't write.
+ NF90_ECANTCREATE = NF_ECANTCREATE , & ! Can't create.
+ NF90_EFILEMETA = NF_EFILEMETA , & ! Problem with file metadata.
+ NF90_EDIMMETA = NF_EDIMMETA , & ! Problem with dimension metadata.
+ NF90_EATTMETA = NF_EATTMETA , & ! Problem with attribute metadata.
+ NF90_EVARMETA = NF_EVARMETA , & ! Problem with variable metadata.
+ NF90_ENOCOMPOUND = NF_ENOCOMPOUND , & ! Not a compound type.
+ NF90_EATTEXISTS = NF_EATTEXISTS , & ! Attribute already exists.
+ NF90_ENOTNC4 = NF_ENOTNC4 , & ! Attempting netcdf-4 operation on netcdf-3 file.
+ NF90_ESTRICTNC3 = NF_ESTRICTNC3 , & ! Attempting netcdf-4 operation on strict nc3 netcdf-4 file.
+ NF90_ENOTNC3 = NF_ENOTNC3 , & ! Attempting netcdf-3 operation on netcdf-4 file.
+ NF90_ENOPAR = NF_ENOPAR , & ! Parallel operation on file opened for non-parallel access.
+ NF90_EPARINIT = NF_EPARINIT , & ! Error initializing for parallel access.
+ NF90_EBADGRPID = NF_EBADGRPID , & ! Bad group ID.
+ NF90_EBADTYPID = NF_EBADTYPID , & ! Bad type ID.
+ NF90_ETYPDEFINED = NF_ETYPDEFINED , & ! Type has already been defined and may not be edited.
+ NF90_EBADFIELD = NF_EBADFIELD , & ! Bad field ID.
+ NF90_EBADCLASS = NF_EBADCLASS , & ! Bad class.
+ NF90_EMAPTYPE = NF_EMAPTYPE , & ! Mapped access for atomic types only.
+ NF90_ELATEFILL = NF_ELATEFILL , & ! Attempt to define fill value when data already exists.
+ NF90_ELATEDEF = NF_ELATEDEF , & ! Attempt to define var properties, like deflate, after enddef.
+ NF90_EDIMSCALE = NF_EDIMSCALE , & ! Probem with HDF5 dimscales.
+ NF90_ENOGRP = NF_ENOGRP , & ! No group found.
+ NF90_ESTORAGE = NF_ESTORAGE , & ! Can't specify both contiguous and chunking.
+ NF90_EBADCHUNK = NF_EBADCHUNK , & ! Bad chunksize.
+ NF90_ENOTBUILT = NF_ENOTBUILT , & ! Attempt to use feature that was not turned on when netCDF was built
+ NF90_EDISKLESS = NF_EDISKLESS , & ! Error in using diskless access.
+ NF90_ECANTEXTEND = NF_ECANTEXTEND , & ! Attempt to extend dataset during ind. I/O operation.
+ NF90_EMPI = NF_EMPI ! MPI operation failed.
+
+ ! This is the position of NC_NETCDF4 in cmode, counting from the
+ ! right, starting (uncharacteristically for fortran) at 0. It's needed
+ ! for the BTEST function calls.
+ integer, parameter, private :: NETCDF4_BIT = 12
+
+
+ ! PnetCDF error codes start here
+ integer, parameter, public :: &
+ NF90_ESMALL = NF_ESMALL , & ! size of off_t too small for format
+ NF90_ENOTINDEP = NF_ENOTINDEP , & ! Operation not allowed in collective data mode
+ NF90_EINDEP = NF_EINDEP , & ! Operation not allowed in independent data mode
+ NF90_EFILE = NF_EFILE , & ! Unknown error in file operation
+ NF90_EREAD = NF_EREAD , & ! Unknown error in reading file
+ NF90_EWRITE = NF_EWRITE , & ! Unknown error in writting to file
+ NF90_EOFILE = NF_EOFILE , & ! file open/creation failed
+ NF90_EMULTITYPES = NF_EMULTITYPES , & ! Multiple types used in memory data
+ NF90_EIOMISMATCH = NF_EIOMISMATCH , & ! Input/Output data amount mismatch
+ NF90_ENEGATIVECNT = NF_ENEGATIVECNT , & ! Negative count is specified
+ NF90_EUNSPTETYPE = NF_EUNSPTETYPE , & ! Unsupported etype in memory MPI datatype
+ NF90_EINVAL_REQUEST = NF_EINVAL_REQUEST , & ! invalid nonblocking request ID
+ NF90_EAINT_TOO_SMALL = NF_EAINT_TOO_SMALL , & ! MPI_Aint not large enough to hold requested value
+ NF90_ENOTSUPPORT = NF_ENOTSUPPORT , & ! feature is not yet supported
+ NF90_ENULLBUF = NF_ENULLBUF , & ! trying to attach a NULL buffer
+ NF90_EPREVATTACHBUF = NF_EPREVATTACHBUF , & ! previous attached buffer is found
+ NF90_ENULLABUF = NF_ENULLABUF , & ! no attached buffer is found
+ NF90_EPENDINGBPUT = NF_EPENDINGBPUT , & ! pending bput is found, cannot detach buffer
+ NF90_EINSUFFBUF = NF_EINSUFFBUF , & ! attached buffer is too small
+ NF90_ENOENT = NF_ENOENT , & ! File does not exist when calling nfmpi_open()
+ NF90_EINTOVERFLOW = NF_EINTOVERFLOW , & ! Overflow when type cast to 4-byte integer
+ NF90_ENOTENABLED = NF_ENOTENABLED , & ! Overflow when type cast to 4-byte integer
+ NF90_EBAD_FILE = NF_EBAD_FILE , & ! Invalid file name (e.g., path name too long)
+ NF90_ENO_SPACE = NF_ENO_SPACE , & ! Not enough space
+ NF90_EQUOTA = NF_EQUOTA , & ! Quota exceeded
+ NF90_ENULLSTART = NF_ENULLSTART , & ! argument start is a NULL pointer
+ NF90_ENULLCOUNT = NF_ENULLCOUNT , & ! argument count is a NULL pointer
+ NF90_EINVAL_CMODE = NF_EINVAL_CMODE , & ! Invalid file create mode, cannot have both
+ ! NC_64BIT_OFFSET & NC_64BIT_DATA
+ NF90_ETYPESIZE = NF_ETYPESIZE , & ! MPI derived data type size error (bigger than the
+ ! variable size)
+ NF90_ETYPE_MISMATCH = NF_ETYPE_MISMATCH , & ! element type of the MPI derived data type mismatches
+ ! the variable type
+ NF90_ETYPESIZE_MISMATCH = NF_ETYPESIZE_MISMATCH , & ! file type size mismatches buffer type size
+ NF90_ESTRICTCDF2 = NF_ESTRICTCDF2 , & ! Attempting CDF-5 operation on CDF-2 file
+ NF90_ENOTRECVAR = NF_ENOTRECVAR , & ! Attempting operation only for record variables
+ NF90_ENOTFILL = NF_ENOTFILL , & ! Attempting to fill a variable when its fill mode is off
+ NF90_EMULTIDEFINE = NF_EMULTIDEFINE , & ! NC definitions on multiprocesses conflict
+ NF90_EMULTIDEFINE_OMODE = NF_EMULTIDEFINE_OMODE , & ! file create/open modes are inconsistent among processes
+ NF90_EMULTIDEFINE_DIM_NUM = NF_EMULTIDEFINE_DIM_NUM , & ! inconsistent number of dimensions
+ NF90_EMULTIDEFINE_DIM_SIZE = NF_EMULTIDEFINE_DIM_SIZE , & ! inconsistent size of dimension
+ NF90_EMULTIDEFINE_DIM_NAME = NF_EMULTIDEFINE_DIM_NAME , & ! inconsistent dimension names
+ NF90_EMULTIDEFINE_VAR_NUM = NF_EMULTIDEFINE_VAR_NUM , & ! inconsistent number of variables
+ NF90_EMULTIDEFINE_VAR_NAME = NF_EMULTIDEFINE_VAR_NAME , & ! inconsistent variable name
+ NF90_EMULTIDEFINE_VAR_NDIMS = NF_EMULTIDEFINE_VAR_NDIMS , & ! inconsistent variable's number of dimensions
+ NF90_EMULTIDEFINE_VAR_DIMIDS = NF_EMULTIDEFINE_VAR_DIMIDS , & ! inconsistent variable's dimid
+ NF90_EMULTIDEFINE_VAR_TYPE = NF_EMULTIDEFINE_VAR_TYPE , & ! inconsistent variable's data type
+ NF90_EMULTIDEFINE_VAR_LEN = NF_EMULTIDEFINE_VAR_LEN , & ! inconsistent variable's size
+ NF90_EMULTIDEFINE_NUMRECS = NF_EMULTIDEFINE_NUMRECS , & ! inconsistent number of records
+ NF90_EMULTIDEFINE_VAR_BEGIN = NF_EMULTIDEFINE_VAR_BEGIN , & ! inconsistent variable file begin offset (internal use)
+ NF90_EMULTIDEFINE_ATTR_NUM = NF_EMULTIDEFINE_ATTR_NUM , & ! inconsistent number of attributes
+ NF90_EMULTIDEFINE_ATTR_SIZE = NF_EMULTIDEFINE_ATTR_SIZE , & ! inconsistent memory space used by attribute (internal use)
+ NF90_EMULTIDEFINE_ATTR_NAME = NF_EMULTIDEFINE_ATTR_NAME , & ! inconsistent attribute name
+ NF90_EMULTIDEFINE_ATTR_TYPE = NF_EMULTIDEFINE_ATTR_TYPE , & ! inconsistent attribute type
+ NF90_EMULTIDEFINE_ATTR_LEN = NF_EMULTIDEFINE_ATTR_LEN , & ! inconsistent attribute length
+ NF90_EMULTIDEFINE_ATTR_VAL = NF_EMULTIDEFINE_ATTR_VAL , & ! inconsistent attribute value
+ NF90_EMULTIDEFINE_FNC_ARGS = NF_EMULTIDEFINE_FNC_ARGS , & ! inconsistent function arguments used in collective API
+ NF90_EMULTIDEFINE_FILL_MODE = NF_EMULTIDEFINE_FILL_MODE , & ! inconsistent dataset fill mode
+ NF90_EMULTIDEFINE_VAR_FILL_MODE = NF_EMULTIDEFINE_VAR_FILL_MODE, & ! inconsistent variable fill mode
+ NF90_EMULTIDEFINE_VAR_FILL_VALUE = NF_EMULTIDEFINE_VAR_FILL_VALUE, & ! inconsistent variable fill value
+ NF90_ECMODE = NF_EMULTIDEFINE_OMODE , &
+ NF90_EDIMS_NELEMS_MULTIDEFINE = NF_EMULTIDEFINE_DIM_NUM , &
+ NF90_EDIMS_SIZE_MULTIDEFINE = NF_EMULTIDEFINE_DIM_SIZE , &
+ NF90_EDIMS_NAME_MULTIDEFINE = NF_EMULTIDEFINE_DIM_NAME , &
+ NF90_EVARS_NELEMS_MULTIDEFINE = NF_EMULTIDEFINE_VAR_NUM , &
+ NF90_EVARS_NAME_MULTIDEFINE = NF_EMULTIDEFINE_VAR_NAME , &
+ NF90_EVARS_NDIMS_MULTIDEFINE = NF_EMULTIDEFINE_VAR_NDIMS , &
+ NF90_EVARS_DIMIDS_MULTIDEFINE = NF_EMULTIDEFINE_VAR_DIMIDS , &
+ NF90_EVARS_TYPE_MULTIDEFINE = NF_EMULTIDEFINE_VAR_TYPE , &
+ NF90_EVARS_LEN_MULTIDEFINE = NF_EMULTIDEFINE_VAR_LEN , &
+ NF90_ENUMRECS_MULTIDEFINE = NF_EMULTIDEFINE_NUMRECS , &
+ NF90_EVARS_BEGIN_MULTIDEFINE = NF_EMULTIDEFINE_VAR_BEGIN
diff --git a/src/libf90/nfmpi_constants.f90.in b/src/libf90/nfmpi_constants.f90.in
new file mode 100644
index 0000000..083f049
--- /dev/null
+++ b/src/libf90/nfmpi_constants.f90.in
@@ -0,0 +1,423 @@
+!
+! Copyright (C) 2013, Northwestern University and Argonne National Laboratory
+! See COPYRIGHT notice in top-level directory.
+!
+! $Id: nfmpi_constants.f90.in 2195 2015-11-27 18:42:11Z wkliao $
+!
+! This file lists the Fortran constants used by PnetCDF
+!
+!
+
+!
+! PnetCDF library version numbers
+!
+ integer PNETCDF_VERSION_MAJOR
+ integer PNETCDF_VERSION_MINOR
+ integer PNETCDF_VERSION_SUB
+
+ parameter (PNETCDF_VERSION_MAJOR = @PNETCDF_VERSION_MAJOR@)
+ parameter (PNETCDF_VERSION_MINOR = @PNETCDF_VERSION_MINOR@)
+ parameter (PNETCDF_VERSION_SUB = @PNETCDF_VERSION_SUB@)
+
+!
+! external netcdf data types:
+!
+ integer, parameter, public :: &
+ nf_byte = 1, &
+ nf_int1 = nf_byte, &
+ nf_char = 2, &
+ nf_short = 3, &
+ nf_int2 = nf_short, &
+ nf_int = 4, &
+ nf_float = 5, &
+ nf_real = nf_float, &
+ nf_double = 6, &
+ nf_ubyte = 7, &
+ nf_ushort = 8, &
+ nf_uint = 9, &
+ nf_int64 = 10, &
+ nf_uint64 = 11
+
+!
+! default fill values:
+!
+ integer, parameter, public :: &
+ nf_fill_byte = -127, &
+ nf_fill_int1 = nf_fill_byte, &
+ nf_fill_char = 0, &
+ nf_fill_short = -32767, &
+ nf_fill_int2 = nf_fill_short, &
+ nf_fill_int = -2147483647, &
+ nf_fill_ubyte = 255, &
+ nf_fill_ushort = 65535
+
+ real, parameter, public :: &
+ nf_fill_float = 9.9692099683868690e+36, &
+ nf_fill_real = nf_fill_float
+
+ double precision, parameter, public :: &
+ nf_fill_double = 9.9692099683868690e+36, &
+ nf_fill_uint64 = 1.8446744073709551614e+19
+
+ integer (KIND=EightByteInt), parameter, public :: &
+ nf_fill_uint = 4294967295_EightByteInt, &
+ nf_fill_int64 = -9223372036854775806_EightByteInt
+
+!
+! mode flags for opening and creating a netcdf dataset:
+!
+ integer, parameter, public :: &
+ nf_nowrite = 0, &
+ nf_write = 1, &
+ nf_clobber = 0, &
+ nf_noclobber = 4, &
+ nf_fill = 0, &
+ nf_nofill = 256, &
+ nf_lock = 1024, &
+ nf_share = 2048, &
+ nf_64bit_offset = 512, &
+ nf_64bit_data = 32, &
+ nf_32bit = 16777216, &
+ nf_sizehint_default = 0, &
+ nf_align_chunk = -1, &
+ nf_format_classic = 1, &
+ nf_format_cdf2 = 2, &
+ nf_format_cdf5 = 5, &
+ nf_format_64bit = nf_format_cdf2, &
+ nf_format_64bit_offset = nf_format_cdf2, &
+ nf_format_64bit_data = nf_format_cdf5
+
+!
+! size argument for defining an unlimited dimension:
+!
+ integer, parameter, public :: &
+ nf_unlimited = 0
+
+ integer(KIND=MPI_OFFSET_KIND), parameter, public :: &
+ nfmpi_unlimited = 0
+
+!
+! global attribute id:
+!
+ integer, parameter, public :: &
+ nf_global = 0
+
+!
+! implementation limits:
+!
+ integer, parameter, public :: &
+ nf_max_dims = 1024, &
+ nf_max_attrs = 8192, &
+ nf_max_vars = 8192, &
+ nf_max_name = 256, &
+ nf_max_var_dims = nf_max_dims
+
+!
+! error codes:
+!
+ integer, parameter, public :: &
+ NF_NOERR = 0, & ! No Error
+ NF2_ERR = -1, & ! Returned for all errors in the v2 API
+ NF_EBADID = -33, & ! Not a netcdf id
+ NF_ENFILE = -34, & ! Too many netcdfs open
+ NF_EEXIST = -35, & ! netcdf file exists and NF_NOCLOBBER
+ NF_EINVAL = -36, & ! Invalid Argument
+ NF_EPERM = -37, & ! Write to read only
+ NF_ENOTINDEFINE = -38, & ! Operation not allowed in data mode
+ NF_EINDEFINE = -39, & ! Operation not allowed in define mode
+ NF_EINVALCOORDS = -40, & ! Index exceeds dimension bound
+ NF_EMAXDIMS = -41, & ! NF_MAX_DIMS exceeded
+ NF_ENAMEINUSE = -42, & ! String match to name in use
+ NF_ENOTATT = -43, & ! Attribute not found
+ NF_EMAXATTS = -44, & ! NF_MAX_ATTRS exceeded
+ NF_EBADTYPE = -45, & ! Not a netcdf data type
+ NF_EBADDIM = -46, & ! Invalid dimension id or name
+ NF_EUNLIMPOS = -47, & ! NFMPI_UNLIMITED in the wrong index
+ NF_EMAXVARS = -48, & ! NF_MAX_VARS exceeded
+ NF_ENOTVAR = -49, & ! Variable not found
+ NF_EGLOBAL = -50, & ! Action prohibited on NF_GLOBAL varid
+ NF_ENOTNC = -51, & ! Not a netcdf file
+ NF_ESTS = -52, & ! In Fortran, string too short
+ NF_EMAXNAME = -53, & ! NF_MAX_NAME exceeded
+ NF_EUNLIMIT = -54, & ! NFMPI_UNLIMITED size already in use
+ NF_ENORECVARS = -55, & ! nc_rec op when there are no record vars
+ NF_ECHAR = -56, & ! Attempt to convert between text & numbers
+ NF_EEDGE = -57, & ! Edge+start exceeds dimension bound
+ NF_ESTRIDE = -58, & ! Illegal stride
+ NF_EBADNAME = -59, & ! Attribute or variable name contains illegal characters
+ NF_ERANGE = -60, & ! Math result not representable
+ NF_ENOMEM = -61, & ! Memory allocation (malloc) failure
+ NF_EVARSIZE = -62, & ! One or more variable sizes violate format constraints
+ NF_EDIMSIZE = -63, & ! Invalid dimension size
+ NF_ETRUNC = -64, & ! File likely truncated or possibly corrupted
+ NF_EAXISTYPE = -65 ! Unknown axis type
+
+! Following errors are added for DAP
+ integer, parameter, public :: &
+ NF_EDAP = -66, & ! Generic DAP error
+ NF_ECURL = -67, & ! Generic libcurl error
+ NF_EIO = -68, & ! Generic IO error
+ NF_ENODATA = -69, & ! Attempt to access variable with no data
+ NF_EDAPSVC = -70, & ! DAP server error
+ NF_EDAS = -71, & ! Malformed or inaccessible DAS
+ NF_EDDS = -72, & ! Malformed or inaccessible DDS
+ NF_EDATADDS = -73, & ! Malformed or inaccessible DATADDS
+ NF_EDAPURL = -74, & ! Malformed DAP URL
+ NF_EDAPCONSTRAINT = -75, & ! Malformed DAP Constraint
+ NF_ETRANSLATION = -76, & ! Untranslatable construct
+ NF_EACCESS = -77, & ! Access Failure
+ NF_EAUTH = -78 ! Authorization Failure
+
+! Misc. additional errors
+ integer, parameter, public :: &
+ NF_ENOTFOUND = -90, & ! No such file
+ NF_ECANTREMOVE = -91 ! Can't remove file
+
+! netCDF-4 error codes (copied from netCDF release)
+ integer, parameter, public :: &
+ NF_EHDFERR = -101, & ! Error at HDF5 layer.
+ NF_ECANTREAD = -102, & ! Can't read.
+ NF_ECANTWRITE = -103, & ! Can't write.
+ NF_ECANTCREATE = -104, & ! Can't create.
+ NF_EFILEMETA = -105, & ! Problem with file metadata.
+ NF_EDIMMETA = -106, & ! Problem with dimension metadata.
+ NF_EATTMETA = -107, & ! Problem with attribute metadata.
+ NF_EVARMETA = -108, & ! Problem with variable metadata.
+ NF_ENOCOMPOUND = -109, & ! Not a compound type.
+ NF_EATTEXISTS = -110, & ! Attribute already exists.
+ NF_ENOTNC4 = -111, & ! Attempting netcdf-4 operation on netcdf-3 file.
+ NF_ESTRICTNC3 = -112, & ! Attempting netcdf-4 operation on strict nc3 netcdf-4 file.
+ NF_ENOTNC3 = -113, & ! Attempting netcdf-3 operation on netcdf-4 file.
+ NF_ENOPAR = -114, & ! Parallel operation on file opened for non-parallel access.
+ NF_EPARINIT = -115, & ! Error initializing for parallel access.
+ NF_EBADGRPID = -116, & ! Bad group ID.
+ NF_EBADTYPID = -117, & ! Bad type ID.
+ NF_ETYPDEFINED = -118, & ! Type has already been defined and may not be edited.
+ NF_EBADFIELD = -119, & ! Bad field ID.
+ NF_EBADCLASS = -120, & ! Bad class.
+ NF_EMAPTYPE = -121, & ! Mapped access for atomic types only.
+ NF_ELATEFILL = -122, & ! Attempt to define fill value when data already exists.
+ NF_ELATEDEF = -123, & ! Attempt to define var properties, like deflate, after enddef.
+ NF_EDIMSCALE = -124, & ! Probem with HDF5 dimscales.
+ NF_ENOGRP = -125, & ! No group found.
+ NF_ESTORAGE = -126, & ! Can't specify both contiguous and chunking.
+ NF_EBADCHUNK = -127, & ! Bad chunksize.
+ NF_ENOTBUILT = -128, & ! Attempt to use feature that was not turned on when netCDF was built.
+ NF_EDISKLESS = -129, & ! Error in using diskless access.
+ NF_ECANTEXTEND = -130, & ! Attempt to extend dataset during ind. I/O operation.
+ NF_EMPI = -131 ! MPI operation failed.
+
+
+! PnetCDF error codes start here
+ integer, parameter, public :: &
+ NF_ESMALL = -201, & ! size of off_t too small for format
+ NF_ENOTINDEP = -202, & ! Operation not allowed in collective data mode
+ NF_EINDEP = -203, & ! Operation not allowed in independent data mode
+ NF_EFILE = -204, & ! Unknown error in file operation
+ NF_EREAD = -205, & ! Unknown error in reading file
+ NF_EWRITE = -206, & ! Unknown error in writting to file
+ NF_EOFILE = -207, & ! file open/creation failed
+ NF_EMULTITYPES = -208, & ! Multiple types used in memory data
+ NF_EIOMISMATCH = -209, & ! Input/Output data amount mismatch
+ NF_ENEGATIVECNT = -210, & ! Negative count is specified
+ NF_EUNSPTETYPE = -211, & ! Unsupported etype in memory MPI datatype
+ NF_EINVAL_REQUEST = -212, & ! invalid nonblocking request ID
+ NF_EAINT_TOO_SMALL = -213, & ! MPI_Aint not large enough to hold requested value
+ NF_ENOTSUPPORT = -214, & ! feature is not yet supported
+ NF_ENULLBUF = -215, & ! trying to attach a NULL buffer
+ NF_EPREVATTACHBUF = -216, & ! previous attached buffer is found
+ NF_ENULLABUF = -217, & ! no attached buffer is found
+ NF_EPENDINGBPUT = -218, & ! pending bput is found, cannot detach buffer
+ NF_EINSUFFBUF = -219, & ! attached buffer is too small
+ NF_ENOENT = -220, & ! File does not exist when calling nfmpi_open()
+ NF_EINTOVERFLOW = -221, & ! Overflow when type cast to 4-byte integer
+ NF_ENOTENABLED = -222, & ! feature is not enabled
+ NF_EBAD_FILE = -223, & ! Invalid file name (e.g., path name too long)
+ NF_ENO_SPACE = -224, & ! Not enough space
+ NF_EQUOTA = -225, & ! Quota exceeded
+ NF_ENULLSTART = -226, & ! argument start is a NULL pointer
+ NF_ENULLCOUNT = -227, & ! argument count is a NULL pointer
+ NF_EINVAL_CMODE = -228, & ! Invalid file create mode, cannot have both NC_64BIT_OFFSET & NC_64BIT_DATA
+ NF_ETYPESIZE = -229, & ! MPI derived data type size error (bigger than the variable size)
+ NF_ETYPE_MISMATCH = -230, & ! element type of the MPI derived data type mismatches the variable type
+ NF_ETYPESIZE_MISMATCH = -231, & ! file type size mismatches buffer type size
+ NF_ESTRICTCDF2 = -232, & ! Attempting CDF-5 operation on CDF-2 file
+ NF_ENOTRECVAR = -233, & ! Attempting operation only for record variables */
+ NF_ENOTFILL = -234 ! Attempting to fill a variable when its fill mode is off */
+
+! header inconsistency error starts in -250
+ integer, parameter, public :: &
+ NF_EMULTIDEFINE = -250, & ! NC definitions on multiprocesses conflict
+ NF_EMULTIDEFINE_OMODE = -251, & ! file create/open modes are inconsistent among processes
+ NF_EMULTIDEFINE_DIM_NUM = -252, & ! inconsistent number of dimensions
+ NF_EMULTIDEFINE_DIM_SIZE = -253, & ! inconsistent size of dimension
+ NF_EMULTIDEFINE_DIM_NAME = -254, & ! inconsistent dimension names
+ NF_EMULTIDEFINE_VAR_NUM = -255, & ! inconsistent number of variables
+ NF_EMULTIDEFINE_VAR_NAME = -256, & ! inconsistent variable name
+ NF_EMULTIDEFINE_VAR_NDIMS = -257, & ! inconsistent variable's number of dimensions
+ NF_EMULTIDEFINE_VAR_DIMIDS = -258, & ! inconsistent variable's dimid
+ NF_EMULTIDEFINE_VAR_TYPE = -259, & ! inconsistent variable's data type
+ NF_EMULTIDEFINE_VAR_LEN = -260, & ! inconsistent variable's size
+ NF_EMULTIDEFINE_NUMRECS = -261, & ! inconsistent number of records
+ NF_EMULTIDEFINE_VAR_BEGIN = -262, & ! inconsistent variable file begin offset (internal use)
+ NF_EMULTIDEFINE_ATTR_NUM = -263, & ! inconsistent number of attributes
+ NF_EMULTIDEFINE_ATTR_SIZE = -264, & ! inconsistent memory space used by attribute (internal use)
+ NF_EMULTIDEFINE_ATTR_NAME = -265, & ! inconsistent attribute name
+ NF_EMULTIDEFINE_ATTR_TYPE = -266, & ! inconsistent attribute type
+ NF_EMULTIDEFINE_ATTR_LEN = -267, & ! inconsistent attribute length
+ NF_EMULTIDEFINE_ATTR_VAL = -268, & ! inconsistent attribute value
+ NF_EMULTIDEFINE_FNC_ARGS = -269, & ! inconsistent function arguments used in collective API
+ NF_EMULTIDEFINE_FILL_MODE = -270, & ! inconsistent dataset fill mode
+ NF_EMULTIDEFINE_VAR_FILL_MODE = -271, & ! inconsistent variable fill mode
+ NF_EMULTIDEFINE_VAR_FILL_VALUE = -272, & ! inconsistent variable fill value
+ NF_ECMODE = NF_EMULTIDEFINE_OMODE, &
+ NF_EDIMS_NELEMS_MULTIDEFINE = NF_EMULTIDEFINE_DIM_NUM, &
+ NF_EDIMS_SIZE_MULTIDEFINE = NF_EMULTIDEFINE_DIM_SIZE, &
+ NF_EDIMS_NAME_MULTIDEFINE = NF_EMULTIDEFINE_DIM_NAME, &
+ NF_EVARS_NELEMS_MULTIDEFINE = NF_EMULTIDEFINE_VAR_NUM, &
+ NF_EVARS_NAME_MULTIDEFINE = NF_EMULTIDEFINE_VAR_NAME, &
+ NF_EVARS_NDIMS_MULTIDEFINE = NF_EMULTIDEFINE_VAR_NDIMS, &
+ NF_EVARS_DIMIDS_MULTIDEFINE = NF_EMULTIDEFINE_VAR_DIMIDS, &
+ NF_EVARS_TYPE_MULTIDEFINE = NF_EMULTIDEFINE_VAR_TYPE, &
+ NF_EVARS_LEN_MULTIDEFINE = NF_EMULTIDEFINE_VAR_LEN, &
+ NF_ENUMRECS_MULTIDEFINE = NF_EMULTIDEFINE_NUMRECS, &
+ NF_EVARS_BEGIN_MULTIDEFINE = NF_EMULTIDEFINE_VAR_BEGIN
+
+! error handling modes:
+!
+ integer, parameter, public :: &
+ nf_fatal = 1, &
+ nf_verbose = 2
+
+! NULL request for non-blocking I/O APIs
+ integer, parameter, public :: &
+ NF_REQ_NULL = -1
+
+! indicate to flush all pending non-blocking requests
+ integer, parameter, public :: &
+ NF_REQ_ALL = -1
+
+!ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
+! begin netcdf 2.4 backward compatibility:
+!
+
+!
+! functions in the fortran interface
+!
+
+!
+! netcdf data types:
+!
+ integer, parameter, public :: &
+ ncbyte = 1, &
+ ncchar = 2, &
+ ncshort = 3, &
+ nclong = 4, &
+ ncfloat = 5, &
+ ncdouble = 6
+
+!
+! masks for the struct nc flag field; passed in as 'mode' arg to
+! nccreate and ncopen.
+!
+ integer, parameter, public :: &
+ ncrdwr = 1, & ! read/write, 0 => readonly
+ nccreat = 2, & ! in create phase, cleared by ncendef
+ ncexcl = 4, & ! on create destroy existing file
+ ncindef = 8, & ! in define mode, cleared by ncendef
+ ncnsync = 16, & ! synchronise numrecs on change (x'10')
+ nchsync = 32, & ! synchronise whole header on change (x'20')
+ ncndirty = 64, & ! numrecs has changed (x'40')
+ nchdirty = 128, & ! header info has changed (x'80')
+ ncfill = 0, & ! prefill vars on endef and increase of record, the default behavior
+ ncnofill = 256, & ! do not fill vars on endef and increase of record (x'100')
+ nclink = 32768 ! isa link (x'8000')
+
+!
+! 'mode' arguments for nccreate and ncopen
+!
+ integer, parameter, public :: &
+ ncnowrit = 0, &
+ ncwrite = ncrdwr, &
+ ncclob = nf_clobber, &
+ ncnoclob = nf_noclobber
+
+!
+! 'size' argument to ncdimdef for an unlimited dimension
+!
+ integer, parameter, public :: &
+ ncunlim = 0
+
+!
+! attribute id to put/get a global attribute
+!
+ integer, parameter, public :: &
+ ncglobal = 0
+
+!
+! advisory maximums:
+!
+ integer, parameter, public :: &
+ maxncop = 32, &
+ maxncdim = 100, &
+ maxncatt = 2000, &
+ maxncvar = 2000
+
+! not enforced
+ integer, parameter, public :: &
+ maxncnam = 128, &
+ maxvdims = maxncdim
+
+!
+! global netcdf error status variable
+! initialized in error.c
+!
+ integer, parameter, public :: &
+ ncnoerr = nf_noerr, & ! no error
+ ncebadid = nf_ebadid, & ! not a netcdf id
+ ncenfile = -31, & ! nc_syserr too many netcdfs open
+ nceexist = nf_eexist, & ! netcdf file exists && ncnoclob
+ nceinval = nf_einval, & ! invalid argument
+ nceperm = nf_eperm, & ! write to read only
+ ncenotin = nf_enotindefine, & ! operation not allowed in data mode
+ nceindef = nf_eindefine, & ! operation not allowed in define mode
+ ncecoord = nf_einvalcoords, & ! coordinates out of domain
+ ncemaxds = nf_emaxdims, & ! maxncdims exceeded
+ ncename = nf_enameinuse, & ! string match to name in use
+ ncenoatt = nf_enotatt, & ! attribute not found
+ ncemaxat = nf_emaxatts, & ! maxncattrs exceeded
+ ncebadty = nf_ebadtype, & ! not a netcdf data type
+ ncebadd = nf_ebaddim, & ! invalid dimension id
+ nceunlim = nf_eunlimpos, & ! ncunlimited in the wrong index
+ ncemaxvs = nf_emaxvars, & ! maxncvars exceeded
+ ncenotvr = nf_enotvar, & ! variable not found
+ nceglob = nf_eglobal, & ! action prohibited on ncglobal varid
+ ncenotnc = nf_enotnc, & ! not a netcdf file
+ ncests = nf_ests, &
+ ncentool = nf_emaxname, &
+ ncfoobar = 32, &
+ ncsyserr = -31
+
+!
+! global options variable. used to determine behavior of error handler.
+! initialized in lerror.c
+!
+ integer, parameter, public :: &
+ ncfatal = 1, &
+ ncverbos = 2
+
+!
+! default fill values. these must be the same as in the c interface.
+!
+ integer, parameter, public :: &
+ filbyte = -127, &
+ filchar = 0, &
+ filshort = -32767, &
+ fillong = -2147483647
+
+ real, parameter, public :: &
+ filfloat = 9.9692099683868690e+36
+
+ double precision, parameter, public :: &
+ fildoub = 9.9692099683868690e+36
+
diff --git a/src/libf90/overloads.f90 b/src/libf90/overloads.f90
new file mode 100644
index 0000000..f8b1099
--- /dev/null
+++ b/src/libf90/overloads.f90
@@ -0,0 +1,693 @@
+!
+! Copyright (C) 2013, Northwestern University and Argonne National Laboratory
+! See COPYRIGHT notice in top-level directory.
+!
+! $Id: overloads.f90 2002 2015-02-12 07:34:35Z wkliao $
+!
+! This file is taken from netcdf_overloads.f90 with changes for PnetCDF use
+!
+!
+
+ ! Overloaded variable functions
+ interface nf90mpi_def_var
+ module procedure nf90mpi_def_var_Scalar, nf90mpi_def_var_oneDim, nf90mpi_def_var_ManyDims
+ end interface ! nf90mpi_def_var
+
+ ! Overloaded variable fill functions
+ interface nf90mpi_def_var_fill
+ module procedure nf90mpi_def_var_fill_text, &
+ nf90mpi_def_var_fill_OneByteInt, nf90mpi_def_var_fill_TwoByteInt, &
+ nf90mpi_def_var_fill_FourByteInt, nf90mpi_def_var_fill_EightByteInt, &
+ nf90mpi_def_var_fill_FourByteReal, nf90mpi_def_var_fill_EightByteReal
+ end interface !nf90mpi_def_var_fill
+ interface nf90mpi_inq_var_fill
+ module procedure nf90mpi_inq_var_fill_text, &
+ nf90mpi_inq_var_fill_OneByteInt, nf90mpi_inq_var_fill_TwoByteInt, &
+ nf90mpi_inq_var_fill_FourByteInt, nf90mpi_inq_var_fill_EightByteInt, &
+ nf90mpi_inq_var_fill_FourByteReal, nf90mpi_inq_var_fill_EightByteReal
+ end interface !nf90mpi_inq_var_fill
+
+ ! Overloaded attribute functions
+ interface nf90mpi_put_att
+ module procedure nf90mpi_put_att_text, &
+ nf90mpi_put_att_OneByteInt, nf90mpi_put_att_TwoByteInt, &
+ nf90mpi_put_att_FourByteInt, nf90mpi_put_att_EightByteInt, &
+ nf90mpi_put_att_FourByteReal, nf90mpi_put_att_EightByteReal
+ module procedure nf90mpi_put_att_one_OneByteInt, nf90mpi_put_att_one_TwoByteInt, &
+ nf90mpi_put_att_one_FourByteInt, nf90mpi_put_att_one_EightByteInt, &
+ nf90mpi_put_att_one_FourByteReal, nf90mpi_put_att_one_EightByteReal
+ end interface !nf90mpi_put_att
+ interface nf90mpi_get_att
+ module procedure nf90mpi_get_att_text, &
+ nf90mpi_get_att_OneByteInt, nf90mpi_get_att_TwoByteInt, &
+ nf90mpi_get_att_FourByteInt, nf90mpi_get_att_EightByteInt, &
+ nf90mpi_get_att_FourByteReal, nf90mpi_get_att_EightByteReal
+ module procedure nf90mpi_get_att_one_OneByteInt, nf90mpi_get_att_one_TwoByteInt, &
+ nf90mpi_get_att_one_FourByteInt, nf90mpi_get_att_one_EightByteInt, &
+ nf90mpi_get_att_one_FourByteReal, nf90mpi_get_att_one_EightByteReal
+ end interface ! nf90mpi_get_att
+
+ ! Overloaded variable functions
+ interface nf90mpi_put_var
+ module procedure nf90mpi_put_var_text, &
+ nf90mpi_put_var_OneByteInt, nf90mpi_put_var_TwoByteInt, &
+ nf90mpi_put_var_FourByteInt, nf90mpi_put_var_EightByteInt, &
+ nf90mpi_put_var_FourByteReal, nf90mpi_put_var_EightByteReal
+ module procedure nf90mpi_put_var_1D_text, &
+ nf90mpi_put_var_1D_OneByteInt, nf90mpi_put_var_1D_TwoByteInt, &
+ nf90mpi_put_var_1D_FourByteInt, nf90mpi_put_var_1D_EightByteInt, &
+ nf90mpi_put_var_1D_FourByteReal, nf90mpi_put_var_1D_EightByteReal
+ module procedure nf90mpi_put_var_2D_text, &
+ nf90mpi_put_var_2D_OneByteInt, nf90mpi_put_var_2D_TwoByteInt, &
+ nf90mpi_put_var_2D_FourByteInt, nf90mpi_put_var_2D_EightByteInt, &
+ nf90mpi_put_var_2D_FourByteReal, nf90mpi_put_var_2D_EightByteReal
+ module procedure nf90mpi_put_var_3D_text, &
+ nf90mpi_put_var_3D_OneByteInt, nf90mpi_put_var_3D_TwoByteInt, &
+ nf90mpi_put_var_3D_FourByteInt, nf90mpi_put_var_3D_EightByteInt, &
+ nf90mpi_put_var_3D_FourByteReal, nf90mpi_put_var_3D_EightByteReal
+ module procedure nf90mpi_put_var_4D_text, &
+ nf90mpi_put_var_4D_OneByteInt, nf90mpi_put_var_4D_TwoByteInt, &
+ nf90mpi_put_var_4D_FourByteInt, nf90mpi_put_var_4D_EightByteInt, &
+ nf90mpi_put_var_4D_FourByteReal, nf90mpi_put_var_4D_EightByteReal
+ module procedure nf90mpi_put_var_5D_text, &
+ nf90mpi_put_var_5D_OneByteInt, nf90mpi_put_var_5D_TwoByteInt, &
+ nf90mpi_put_var_5D_FourByteInt, nf90mpi_put_var_5D_EightByteInt, &
+ nf90mpi_put_var_5D_FourByteReal, nf90mpi_put_var_5D_EightByteReal
+ module procedure nf90mpi_put_var_6D_text, &
+ nf90mpi_put_var_6D_OneByteInt, nf90mpi_put_var_6D_TwoByteInt, &
+ nf90mpi_put_var_6D_FourByteInt, nf90mpi_put_var_6D_EightByteInt, &
+ nf90mpi_put_var_6D_FourByteReal, nf90mpi_put_var_6D_EightByteReal
+ module procedure nf90mpi_put_var_7D_text, &
+ nf90mpi_put_var_7D_OneByteInt, nf90mpi_put_var_7D_TwoByteInt, &
+ nf90mpi_put_var_7D_FourByteInt, nf90mpi_put_var_7D_EightByteInt, &
+ nf90mpi_put_var_7D_FourByteReal, nf90mpi_put_var_7D_EightByteReal
+ end interface ! nf90mpi_put_var
+
+ interface nf90mpi_get_var
+ module procedure nf90mpi_get_var_text, &
+ nf90mpi_get_var_OneByteInt, nf90mpi_get_var_TwoByteInt, &
+ nf90mpi_get_var_FourByteInt, nf90mpi_get_var_EightByteInt, &
+ nf90mpi_get_var_FourByteReal, nf90mpi_get_var_EightByteReal
+ module procedure nf90mpi_get_var_1D_text, &
+ nf90mpi_get_var_1D_OneByteInt, nf90mpi_get_var_1D_TwoByteInt, &
+ nf90mpi_get_var_1D_FourByteInt, nf90mpi_get_var_1D_EightByteInt, &
+ nf90mpi_get_var_1D_FourByteReal, nf90mpi_get_var_1D_EightByteReal
+ module procedure nf90mpi_get_var_2D_text, &
+ nf90mpi_get_var_2D_OneByteInt, nf90mpi_get_var_2D_TwoByteInt, &
+ nf90mpi_get_var_2D_FourByteInt, nf90mpi_get_var_2D_EightByteInt, &
+ nf90mpi_get_var_2D_FourByteReal, nf90mpi_get_var_2D_EightByteReal
+ module procedure nf90mpi_get_var_3D_text, &
+ nf90mpi_get_var_3D_OneByteInt, nf90mpi_get_var_3D_TwoByteInt, &
+ nf90mpi_get_var_3D_FourByteInt, nf90mpi_get_var_3D_EightByteInt, &
+ nf90mpi_get_var_3D_FourByteReal, nf90mpi_get_var_3D_EightByteReal
+ module procedure nf90mpi_get_var_4D_text, &
+ nf90mpi_get_var_4D_OneByteInt, nf90mpi_get_var_4D_TwoByteInt, &
+ nf90mpi_get_var_4D_FourByteInt, nf90mpi_get_var_4D_EightByteInt, &
+ nf90mpi_get_var_4D_FourByteReal, nf90mpi_get_var_4D_EightByteReal
+ module procedure nf90mpi_get_var_5D_text, &
+ nf90mpi_get_var_5D_OneByteInt, nf90mpi_get_var_5D_TwoByteInt, &
+ nf90mpi_get_var_5D_FourByteInt, nf90mpi_get_var_5D_EightByteInt, &
+ nf90mpi_get_var_5D_FourByteReal, nf90mpi_get_var_5D_EightByteReal
+ module procedure nf90mpi_get_var_6D_text, &
+ nf90mpi_get_var_6D_OneByteInt, nf90mpi_get_var_6D_TwoByteInt, &
+ nf90mpi_get_var_6D_FourByteInt, nf90mpi_get_var_6D_EightByteInt, &
+ nf90mpi_get_var_6D_FourByteReal, nf90mpi_get_var_6D_EightByteReal
+ module procedure nf90mpi_get_var_7D_text, &
+ nf90mpi_get_var_7D_OneByteInt, nf90mpi_get_var_7D_TwoByteInt, &
+ nf90mpi_get_var_7D_FourByteInt, nf90mpi_get_var_7D_EightByteInt, &
+ nf90mpi_get_var_7D_FourByteReal, nf90mpi_get_var_7D_EightByteReal
+ end interface ! nf90mpi_get_var
+
+ ! Overloaded variable functions varn
+ interface nf90mpi_put_varn
+ module procedure nf90mpi_put_varn_text, &
+ nf90mpi_put_varn_OneByteInt, nf90mpi_put_varn_TwoByteInt, &
+ nf90mpi_put_varn_FourByteInt, nf90mpi_put_varn_EightByteInt, &
+ nf90mpi_put_varn_FourByteReal, nf90mpi_put_varn_EightByteReal
+ module procedure nf90mpi_put_varn_1D_text, &
+ nf90mpi_put_varn_1D_OneByteInt, nf90mpi_put_varn_1D_TwoByteInt, &
+ nf90mpi_put_varn_1D_FourByteInt, nf90mpi_put_varn_1D_EightByteInt, &
+ nf90mpi_put_varn_1D_FourByteReal, nf90mpi_put_varn_1D_EightByteReal
+ module procedure nf90mpi_put_varn_2D_text, &
+ nf90mpi_put_varn_2D_OneByteInt, nf90mpi_put_varn_2D_TwoByteInt, &
+ nf90mpi_put_varn_2D_FourByteInt, nf90mpi_put_varn_2D_EightByteInt, &
+ nf90mpi_put_varn_2D_FourByteReal, nf90mpi_put_varn_2D_EightByteReal
+ module procedure nf90mpi_put_varn_3D_text, &
+ nf90mpi_put_varn_3D_OneByteInt, nf90mpi_put_varn_3D_TwoByteInt, &
+ nf90mpi_put_varn_3D_FourByteInt, nf90mpi_put_varn_3D_EightByteInt, &
+ nf90mpi_put_varn_3D_FourByteReal, nf90mpi_put_varn_3D_EightByteReal
+ module procedure nf90mpi_put_varn_4D_text, &
+ nf90mpi_put_varn_4D_OneByteInt, nf90mpi_put_varn_4D_TwoByteInt, &
+ nf90mpi_put_varn_4D_FourByteInt, nf90mpi_put_varn_4D_EightByteInt, &
+ nf90mpi_put_varn_4D_FourByteReal, nf90mpi_put_varn_4D_EightByteReal
+ module procedure nf90mpi_put_varn_5D_text, &
+ nf90mpi_put_varn_5D_OneByteInt, nf90mpi_put_varn_5D_TwoByteInt, &
+ nf90mpi_put_varn_5D_FourByteInt, nf90mpi_put_varn_5D_EightByteInt, &
+ nf90mpi_put_varn_5D_FourByteReal, nf90mpi_put_varn_5D_EightByteReal
+ module procedure nf90mpi_put_varn_6D_text, &
+ nf90mpi_put_varn_6D_OneByteInt, nf90mpi_put_varn_6D_TwoByteInt, &
+ nf90mpi_put_varn_6D_FourByteInt, nf90mpi_put_varn_6D_EightByteInt, &
+ nf90mpi_put_varn_6D_FourByteReal, nf90mpi_put_varn_6D_EightByteReal
+ module procedure nf90mpi_put_varn_7D_text, &
+ nf90mpi_put_varn_7D_OneByteInt, nf90mpi_put_varn_7D_TwoByteInt, &
+ nf90mpi_put_varn_7D_FourByteInt, nf90mpi_put_varn_7D_EightByteInt, &
+ nf90mpi_put_varn_7D_FourByteReal, nf90mpi_put_varn_7D_EightByteReal
+ end interface ! nf90mpi_put_varn
+
+ interface nf90mpi_get_varn
+ module procedure nf90mpi_get_varn_text, &
+ nf90mpi_get_varn_OneByteInt, nf90mpi_get_varn_TwoByteInt, &
+ nf90mpi_get_varn_FourByteInt, nf90mpi_get_varn_EightByteInt, &
+ nf90mpi_get_varn_FourByteReal, nf90mpi_get_varn_EightByteReal
+ module procedure nf90mpi_get_varn_1D_text, &
+ nf90mpi_get_varn_1D_OneByteInt, nf90mpi_get_varn_1D_TwoByteInt, &
+ nf90mpi_get_varn_1D_FourByteInt, nf90mpi_get_varn_1D_EightByteInt, &
+ nf90mpi_get_varn_1D_FourByteReal, nf90mpi_get_varn_1D_EightByteReal
+ module procedure nf90mpi_get_varn_2D_text, &
+ nf90mpi_get_varn_2D_OneByteInt, nf90mpi_get_varn_2D_TwoByteInt, &
+ nf90mpi_get_varn_2D_FourByteInt, nf90mpi_get_varn_2D_EightByteInt, &
+ nf90mpi_get_varn_2D_FourByteReal, nf90mpi_get_varn_2D_EightByteReal
+ module procedure nf90mpi_get_varn_3D_text, &
+ nf90mpi_get_varn_3D_OneByteInt, nf90mpi_get_varn_3D_TwoByteInt, &
+ nf90mpi_get_varn_3D_FourByteInt, nf90mpi_get_varn_3D_EightByteInt, &
+ nf90mpi_get_varn_3D_FourByteReal, nf90mpi_get_varn_3D_EightByteReal
+ module procedure nf90mpi_get_varn_4D_text, &
+ nf90mpi_get_varn_4D_OneByteInt, nf90mpi_get_varn_4D_TwoByteInt, &
+ nf90mpi_get_varn_4D_FourByteInt, nf90mpi_get_varn_4D_EightByteInt, &
+ nf90mpi_get_varn_4D_FourByteReal, nf90mpi_get_varn_4D_EightByteReal
+ module procedure nf90mpi_get_varn_5D_text, &
+ nf90mpi_get_varn_5D_OneByteInt, nf90mpi_get_varn_5D_TwoByteInt, &
+ nf90mpi_get_varn_5D_FourByteInt, nf90mpi_get_varn_5D_EightByteInt, &
+ nf90mpi_get_varn_5D_FourByteReal, nf90mpi_get_varn_5D_EightByteReal
+ module procedure nf90mpi_get_varn_6D_text, &
+ nf90mpi_get_varn_6D_OneByteInt, nf90mpi_get_varn_6D_TwoByteInt, &
+ nf90mpi_get_varn_6D_FourByteInt, nf90mpi_get_varn_6D_EightByteInt, &
+ nf90mpi_get_varn_6D_FourByteReal, nf90mpi_get_varn_6D_EightByteReal
+ module procedure nf90mpi_get_varn_7D_text, &
+ nf90mpi_get_varn_7D_OneByteInt, nf90mpi_get_varn_7D_TwoByteInt, &
+ nf90mpi_get_varn_7D_FourByteInt, nf90mpi_get_varn_7D_EightByteInt, &
+ nf90mpi_get_varn_7D_FourByteReal, nf90mpi_get_varn_7D_EightByteReal
+ end interface ! nf90mpi_get_varn
+
+ ! Overloaded variable functions vard
+ interface nf90mpi_put_vard
+ module procedure nf90mpi_put_vard_text, &
+ nf90mpi_put_vard_OneByteInt, nf90mpi_put_vard_TwoByteInt, &
+ nf90mpi_put_vard_FourByteInt, nf90mpi_put_vard_EightByteInt, &
+ nf90mpi_put_vard_FourByteReal, nf90mpi_put_vard_EightByteReal
+ module procedure nf90mpi_put_vard_1D_text, &
+ nf90mpi_put_vard_1D_OneByteInt, nf90mpi_put_vard_1D_TwoByteInt, &
+ nf90mpi_put_vard_1D_FourByteInt, nf90mpi_put_vard_1D_EightByteInt, &
+ nf90mpi_put_vard_1D_FourByteReal, nf90mpi_put_vard_1D_EightByteReal
+ module procedure nf90mpi_put_vard_2D_text, &
+ nf90mpi_put_vard_2D_OneByteInt, nf90mpi_put_vard_2D_TwoByteInt, &
+ nf90mpi_put_vard_2D_FourByteInt, nf90mpi_put_vard_2D_EightByteInt, &
+ nf90mpi_put_vard_2D_FourByteReal, nf90mpi_put_vard_2D_EightByteReal
+ module procedure nf90mpi_put_vard_3D_text, &
+ nf90mpi_put_vard_3D_OneByteInt, nf90mpi_put_vard_3D_TwoByteInt, &
+ nf90mpi_put_vard_3D_FourByteInt, nf90mpi_put_vard_3D_EightByteInt, &
+ nf90mpi_put_vard_3D_FourByteReal, nf90mpi_put_vard_3D_EightByteReal
+ module procedure nf90mpi_put_vard_4D_text, &
+ nf90mpi_put_vard_4D_OneByteInt, nf90mpi_put_vard_4D_TwoByteInt, &
+ nf90mpi_put_vard_4D_FourByteInt, nf90mpi_put_vard_4D_EightByteInt, &
+ nf90mpi_put_vard_4D_FourByteReal, nf90mpi_put_vard_4D_EightByteReal
+ module procedure nf90mpi_put_vard_5D_text, &
+ nf90mpi_put_vard_5D_OneByteInt, nf90mpi_put_vard_5D_TwoByteInt, &
+ nf90mpi_put_vard_5D_FourByteInt, nf90mpi_put_vard_5D_EightByteInt, &
+ nf90mpi_put_vard_5D_FourByteReal, nf90mpi_put_vard_5D_EightByteReal
+ module procedure nf90mpi_put_vard_6D_text, &
+ nf90mpi_put_vard_6D_OneByteInt, nf90mpi_put_vard_6D_TwoByteInt, &
+ nf90mpi_put_vard_6D_FourByteInt, nf90mpi_put_vard_6D_EightByteInt, &
+ nf90mpi_put_vard_6D_FourByteReal, nf90mpi_put_vard_6D_EightByteReal
+ module procedure nf90mpi_put_vard_7D_text, &
+ nf90mpi_put_vard_7D_OneByteInt, nf90mpi_put_vard_7D_TwoByteInt, &
+ nf90mpi_put_vard_7D_FourByteInt, nf90mpi_put_vard_7D_EightByteInt, &
+ nf90mpi_put_vard_7D_FourByteReal, nf90mpi_put_vard_7D_EightByteReal
+ end interface ! nf90mpi_put_vard
+
+ interface nf90mpi_get_vard
+ module procedure nf90mpi_get_vard_text, &
+ nf90mpi_get_vard_OneByteInt, nf90mpi_get_vard_TwoByteInt, &
+ nf90mpi_get_vard_FourByteInt, nf90mpi_get_vard_EightByteInt, &
+ nf90mpi_get_vard_FourByteReal, nf90mpi_get_vard_EightByteReal
+ module procedure nf90mpi_get_vard_1D_text, &
+ nf90mpi_get_vard_1D_OneByteInt, nf90mpi_get_vard_1D_TwoByteInt, &
+ nf90mpi_get_vard_1D_FourByteInt, nf90mpi_get_vard_1D_EightByteInt, &
+ nf90mpi_get_vard_1D_FourByteReal, nf90mpi_get_vard_1D_EightByteReal
+ module procedure nf90mpi_get_vard_2D_text, &
+ nf90mpi_get_vard_2D_OneByteInt, nf90mpi_get_vard_2D_TwoByteInt, &
+ nf90mpi_get_vard_2D_FourByteInt, nf90mpi_get_vard_2D_EightByteInt, &
+ nf90mpi_get_vard_2D_FourByteReal, nf90mpi_get_vard_2D_EightByteReal
+ module procedure nf90mpi_get_vard_3D_text, &
+ nf90mpi_get_vard_3D_OneByteInt, nf90mpi_get_vard_3D_TwoByteInt, &
+ nf90mpi_get_vard_3D_FourByteInt, nf90mpi_get_vard_3D_EightByteInt, &
+ nf90mpi_get_vard_3D_FourByteReal, nf90mpi_get_vard_3D_EightByteReal
+ module procedure nf90mpi_get_vard_4D_text, &
+ nf90mpi_get_vard_4D_OneByteInt, nf90mpi_get_vard_4D_TwoByteInt, &
+ nf90mpi_get_vard_4D_FourByteInt, nf90mpi_get_vard_4D_EightByteInt, &
+ nf90mpi_get_vard_4D_FourByteReal, nf90mpi_get_vard_4D_EightByteReal
+ module procedure nf90mpi_get_vard_5D_text, &
+ nf90mpi_get_vard_5D_OneByteInt, nf90mpi_get_vard_5D_TwoByteInt, &
+ nf90mpi_get_vard_5D_FourByteInt, nf90mpi_get_vard_5D_EightByteInt, &
+ nf90mpi_get_vard_5D_FourByteReal, nf90mpi_get_vard_5D_EightByteReal
+ module procedure nf90mpi_get_vard_6D_text, &
+ nf90mpi_get_vard_6D_OneByteInt, nf90mpi_get_vard_6D_TwoByteInt, &
+ nf90mpi_get_vard_6D_FourByteInt, nf90mpi_get_vard_6D_EightByteInt, &
+ nf90mpi_get_vard_6D_FourByteReal, nf90mpi_get_vard_6D_EightByteReal
+ module procedure nf90mpi_get_vard_7D_text, &
+ nf90mpi_get_vard_7D_OneByteInt, nf90mpi_get_vard_7D_TwoByteInt, &
+ nf90mpi_get_vard_7D_FourByteInt, nf90mpi_get_vard_7D_EightByteInt, &
+ nf90mpi_get_vard_7D_FourByteReal, nf90mpi_get_vard_7D_EightByteReal
+ end interface ! nf90mpi_get_vard
+
+ !
+ ! Collective APIs
+ !
+
+ ! Overloaded variable functions
+ interface nf90mpi_put_var_all
+ module procedure nf90mpi_put_var_text_all, &
+ nf90mpi_put_var_OneByteInt_all, nf90mpi_put_var_TwoByteInt_all, &
+ nf90mpi_put_var_FourByteInt_all, nf90mpi_put_var_EightByteInt_all, &
+ nf90mpi_put_var_FourByteReal_all, nf90mpi_put_var_EightByteReal_all
+ module procedure nf90mpi_put_var_1D_text_all, &
+ nf90mpi_put_var_1D_OneByteInt_all, nf90mpi_put_var_1D_TwoByteInt_all, &
+ nf90mpi_put_var_1D_FourByteInt_all, nf90mpi_put_var_1D_EightByteInt_all, &
+ nf90mpi_put_var_1D_FourByteReal_all, nf90mpi_put_var_1D_EightByteReal_all
+ module procedure nf90mpi_put_var_2D_text_all, &
+ nf90mpi_put_var_2D_OneByteInt_all, nf90mpi_put_var_2D_TwoByteInt_all, &
+ nf90mpi_put_var_2D_FourByteInt_all, nf90mpi_put_var_2D_EightByteInt_all, &
+ nf90mpi_put_var_2D_FourByteReal_all, nf90mpi_put_var_2D_EightByteReal_all
+ module procedure nf90mpi_put_var_3D_text_all, &
+ nf90mpi_put_var_3D_OneByteInt_all, nf90mpi_put_var_3D_TwoByteInt_all, &
+ nf90mpi_put_var_3D_FourByteInt_all, nf90mpi_put_var_3D_EightByteInt_all, &
+ nf90mpi_put_var_3D_FourByteReal_all, nf90mpi_put_var_3D_EightByteReal_all
+ module procedure nf90mpi_put_var_4D_text_all, &
+ nf90mpi_put_var_4D_OneByteInt_all, nf90mpi_put_var_4D_TwoByteInt_all, &
+ nf90mpi_put_var_4D_FourByteInt_all, nf90mpi_put_var_4D_EightByteInt_all, &
+ nf90mpi_put_var_4D_FourByteReal_all, nf90mpi_put_var_4D_EightByteReal_all
+ module procedure nf90mpi_put_var_5D_text_all, &
+ nf90mpi_put_var_5D_OneByteInt_all, nf90mpi_put_var_5D_TwoByteInt_all, &
+ nf90mpi_put_var_5D_FourByteInt_all, nf90mpi_put_var_5D_EightByteInt_all, &
+ nf90mpi_put_var_5D_FourByteReal_all, nf90mpi_put_var_5D_EightByteReal_all
+ module procedure nf90mpi_put_var_6D_text_all, &
+ nf90mpi_put_var_6D_OneByteInt_all, nf90mpi_put_var_6D_TwoByteInt_all, &
+ nf90mpi_put_var_6D_FourByteInt_all, nf90mpi_put_var_6D_EightByteInt_all, &
+ nf90mpi_put_var_6D_FourByteReal_all, nf90mpi_put_var_6D_EightByteReal_all
+ module procedure nf90mpi_put_var_7D_text_all, &
+ nf90mpi_put_var_7D_OneByteInt_all, nf90mpi_put_var_7D_TwoByteInt_all, &
+ nf90mpi_put_var_7D_FourByteInt_all, nf90mpi_put_var_7D_EightByteInt_all, &
+ nf90mpi_put_var_7D_FourByteReal_all, nf90mpi_put_var_7D_EightByteReal_all
+ end interface ! nf90mpi_put_var_all
+
+ interface nf90mpi_get_var_all
+ module procedure nf90mpi_get_var_text_all, &
+ nf90mpi_get_var_OneByteInt_all, nf90mpi_get_var_TwoByteInt_all, &
+ nf90mpi_get_var_FourByteInt_all, nf90mpi_get_var_EightByteInt_all, &
+ nf90mpi_get_var_FourByteReal_all, nf90mpi_get_var_EightByteReal_all
+ module procedure nf90mpi_get_var_1D_text_all, &
+ nf90mpi_get_var_1D_OneByteInt_all, nf90mpi_get_var_1D_TwoByteInt_all, &
+ nf90mpi_get_var_1D_FourByteInt_all, nf90mpi_get_var_1D_EightByteInt_all, &
+ nf90mpi_get_var_1D_FourByteReal_all, nf90mpi_get_var_1D_EightByteReal_all
+ module procedure nf90mpi_get_var_2D_text_all, &
+ nf90mpi_get_var_2D_OneByteInt_all, nf90mpi_get_var_2D_TwoByteInt_all, &
+ nf90mpi_get_var_2D_FourByteInt_all, nf90mpi_get_var_2D_EightByteInt_all, &
+ nf90mpi_get_var_2D_FourByteReal_all, nf90mpi_get_var_2D_EightByteReal_all
+ module procedure nf90mpi_get_var_3D_text_all, &
+ nf90mpi_get_var_3D_OneByteInt_all, nf90mpi_get_var_3D_TwoByteInt_all, &
+ nf90mpi_get_var_3D_FourByteInt_all, nf90mpi_get_var_3D_EightByteInt_all, &
+ nf90mpi_get_var_3D_FourByteReal_all, nf90mpi_get_var_3D_EightByteReal_all
+ module procedure nf90mpi_get_var_4D_text_all, &
+ nf90mpi_get_var_4D_OneByteInt_all, nf90mpi_get_var_4D_TwoByteInt_all, &
+ nf90mpi_get_var_4D_FourByteInt_all, nf90mpi_get_var_4D_EightByteInt_all, &
+ nf90mpi_get_var_4D_FourByteReal_all, nf90mpi_get_var_4D_EightByteReal_all
+ module procedure nf90mpi_get_var_5D_text_all, &
+ nf90mpi_get_var_5D_OneByteInt_all, nf90mpi_get_var_5D_TwoByteInt_all, &
+ nf90mpi_get_var_5D_FourByteInt_all, nf90mpi_get_var_5D_EightByteInt_all, &
+ nf90mpi_get_var_5D_FourByteReal_all, nf90mpi_get_var_5D_EightByteReal_all
+ module procedure nf90mpi_get_var_6D_text_all, &
+ nf90mpi_get_var_6D_OneByteInt_all, nf90mpi_get_var_6D_TwoByteInt_all, &
+ nf90mpi_get_var_6D_FourByteInt_all, nf90mpi_get_var_6D_EightByteInt_all, &
+ nf90mpi_get_var_6D_FourByteReal_all, nf90mpi_get_var_6D_EightByteReal_all
+ module procedure nf90mpi_get_var_7D_text_all, &
+ nf90mpi_get_var_7D_OneByteInt_all, nf90mpi_get_var_7D_TwoByteInt_all, &
+ nf90mpi_get_var_7D_FourByteInt_all, nf90mpi_get_var_7D_EightByteInt_all, &
+ nf90mpi_get_var_7D_FourByteReal_all, nf90mpi_get_var_7D_EightByteReal_all
+ end interface ! nf90mpi_get_var_all
+
+ ! Overloaded variable functions varn
+ interface nf90mpi_put_varn_all
+ module procedure nf90mpi_put_varn_text_all, &
+ nf90mpi_put_varn_OneByteInt_all, nf90mpi_put_varn_TwoByteInt_all, &
+ nf90mpi_put_varn_FourByteInt_all, nf90mpi_put_varn_EightByteInt_all, &
+ nf90mpi_put_varn_FourByteReal_all, nf90mpi_put_varn_EightByteReal_all
+ module procedure nf90mpi_put_varn_1D_text_all, &
+ nf90mpi_put_varn_1D_OneByteInt_all, nf90mpi_put_varn_1D_TwoByteInt_all, &
+ nf90mpi_put_varn_1D_FourByteInt_all, nf90mpi_put_varn_1D_EightByteInt_all, &
+ nf90mpi_put_varn_1D_FourByteReal_all, nf90mpi_put_varn_1D_EightByteReal_all
+ module procedure nf90mpi_put_varn_2D_text_all, &
+ nf90mpi_put_varn_2D_OneByteInt_all, nf90mpi_put_varn_2D_TwoByteInt_all, &
+ nf90mpi_put_varn_2D_FourByteInt_all, nf90mpi_put_varn_2D_EightByteInt_all, &
+ nf90mpi_put_varn_2D_FourByteReal_all, nf90mpi_put_varn_2D_EightByteReal_all
+ module procedure nf90mpi_put_varn_3D_text_all, &
+ nf90mpi_put_varn_3D_OneByteInt_all, nf90mpi_put_varn_3D_TwoByteInt_all, &
+ nf90mpi_put_varn_3D_FourByteInt_all, nf90mpi_put_varn_3D_EightByteInt_all, &
+ nf90mpi_put_varn_3D_FourByteReal_all, nf90mpi_put_varn_3D_EightByteReal_all
+ module procedure nf90mpi_put_varn_4D_text_all, &
+ nf90mpi_put_varn_4D_OneByteInt_all, nf90mpi_put_varn_4D_TwoByteInt_all, &
+ nf90mpi_put_varn_4D_FourByteInt_all, nf90mpi_put_varn_4D_EightByteInt_all, &
+ nf90mpi_put_varn_4D_FourByteReal_all, nf90mpi_put_varn_4D_EightByteReal_all
+ module procedure nf90mpi_put_varn_5D_text_all, &
+ nf90mpi_put_varn_5D_OneByteInt_all, nf90mpi_put_varn_5D_TwoByteInt_all, &
+ nf90mpi_put_varn_5D_FourByteInt_all, nf90mpi_put_varn_5D_EightByteInt_all, &
+ nf90mpi_put_varn_5D_FourByteReal_all, nf90mpi_put_varn_5D_EightByteReal_all
+ module procedure nf90mpi_put_varn_6D_text_all, &
+ nf90mpi_put_varn_6D_OneByteInt_all, nf90mpi_put_varn_6D_TwoByteInt_all, &
+ nf90mpi_put_varn_6D_FourByteInt_all, nf90mpi_put_varn_6D_EightByteInt_all, &
+ nf90mpi_put_varn_6D_FourByteReal_all, nf90mpi_put_varn_6D_EightByteReal_all
+ module procedure nf90mpi_put_varn_7D_text_all, &
+ nf90mpi_put_varn_7D_OneByteInt_all, nf90mpi_put_varn_7D_TwoByteInt_all, &
+ nf90mpi_put_varn_7D_FourByteInt_all, nf90mpi_put_varn_7D_EightByteInt_all, &
+ nf90mpi_put_varn_7D_FourByteReal_all, nf90mpi_put_varn_7D_EightByteReal_all
+ end interface ! nf90mpi_put_varn_all
+
+ interface nf90mpi_get_varn_all
+ module procedure nf90mpi_get_varn_text_all, &
+ nf90mpi_get_varn_OneByteInt_all, nf90mpi_get_varn_TwoByteInt_all, &
+ nf90mpi_get_varn_FourByteInt_all, nf90mpi_get_varn_EightByteInt_all, &
+ nf90mpi_get_varn_FourByteReal_all, nf90mpi_get_varn_EightByteReal_all
+ module procedure nf90mpi_get_varn_1D_text_all, &
+ nf90mpi_get_varn_1D_OneByteInt_all, nf90mpi_get_varn_1D_TwoByteInt_all, &
+ nf90mpi_get_varn_1D_FourByteInt_all, nf90mpi_get_varn_1D_EightByteInt_all, &
+ nf90mpi_get_varn_1D_FourByteReal_all, nf90mpi_get_varn_1D_EightByteReal_all
+ module procedure nf90mpi_get_varn_2D_text_all, &
+ nf90mpi_get_varn_2D_OneByteInt_all, nf90mpi_get_varn_2D_TwoByteInt_all, &
+ nf90mpi_get_varn_2D_FourByteInt_all, nf90mpi_get_varn_2D_EightByteInt_all, &
+ nf90mpi_get_varn_2D_FourByteReal_all, nf90mpi_get_varn_2D_EightByteReal_all
+ module procedure nf90mpi_get_varn_3D_text_all, &
+ nf90mpi_get_varn_3D_OneByteInt_all, nf90mpi_get_varn_3D_TwoByteInt_all, &
+ nf90mpi_get_varn_3D_FourByteInt_all, nf90mpi_get_varn_3D_EightByteInt_all, &
+ nf90mpi_get_varn_3D_FourByteReal_all, nf90mpi_get_varn_3D_EightByteReal_all
+ module procedure nf90mpi_get_varn_4D_text_all, &
+ nf90mpi_get_varn_4D_OneByteInt_all, nf90mpi_get_varn_4D_TwoByteInt_all, &
+ nf90mpi_get_varn_4D_FourByteInt_all, nf90mpi_get_varn_4D_EightByteInt_all, &
+ nf90mpi_get_varn_4D_FourByteReal_all, nf90mpi_get_varn_4D_EightByteReal_all
+ module procedure nf90mpi_get_varn_5D_text_all, &
+ nf90mpi_get_varn_5D_OneByteInt_all, nf90mpi_get_varn_5D_TwoByteInt_all, &
+ nf90mpi_get_varn_5D_FourByteInt_all, nf90mpi_get_varn_5D_EightByteInt_all, &
+ nf90mpi_get_varn_5D_FourByteReal_all, nf90mpi_get_varn_5D_EightByteReal_all
+ module procedure nf90mpi_get_varn_6D_text_all, &
+ nf90mpi_get_varn_6D_OneByteInt_all, nf90mpi_get_varn_6D_TwoByteInt_all, &
+ nf90mpi_get_varn_6D_FourByteInt_all, nf90mpi_get_varn_6D_EightByteInt_all, &
+ nf90mpi_get_varn_6D_FourByteReal_all, nf90mpi_get_varn_6D_EightByteReal_all
+ module procedure nf90mpi_get_varn_7D_text_all, &
+ nf90mpi_get_varn_7D_OneByteInt_all, nf90mpi_get_varn_7D_TwoByteInt_all, &
+ nf90mpi_get_varn_7D_FourByteInt_all, nf90mpi_get_varn_7D_EightByteInt_all, &
+ nf90mpi_get_varn_7D_FourByteReal_all, nf90mpi_get_varn_7D_EightByteReal_all
+ end interface ! nf90mpi_get_varn_all
+
+ ! Overloaded variable functions vard
+ ! Overloaded variable functions vard
+ interface nf90mpi_put_vard_all
+ module procedure nf90mpi_put_vard_text_all, &
+ nf90mpi_put_vard_OneByteInt_all, nf90mpi_put_vard_TwoByteInt_all, &
+ nf90mpi_put_vard_FourByteInt_all, nf90mpi_put_vard_EightByteInt_all, &
+ nf90mpi_put_vard_FourByteReal_all, nf90mpi_put_vard_EightByteReal_all
+ module procedure nf90mpi_put_vard_1D_text_all, &
+ nf90mpi_put_vard_1D_OneByteInt_all, nf90mpi_put_vard_1D_TwoByteInt_all, &
+ nf90mpi_put_vard_1D_FourByteInt_all, nf90mpi_put_vard_1D_EightByteInt_all, &
+ nf90mpi_put_vard_1D_FourByteReal_all, nf90mpi_put_vard_1D_EightByteReal_all
+ module procedure nf90mpi_put_vard_2D_text_all, &
+ nf90mpi_put_vard_2D_OneByteInt_all, nf90mpi_put_vard_2D_TwoByteInt_all, &
+ nf90mpi_put_vard_2D_FourByteInt_all, nf90mpi_put_vard_2D_EightByteInt_all, &
+ nf90mpi_put_vard_2D_FourByteReal_all, nf90mpi_put_vard_2D_EightByteReal_all
+ module procedure nf90mpi_put_vard_3D_text_all, &
+ nf90mpi_put_vard_3D_OneByteInt_all, nf90mpi_put_vard_3D_TwoByteInt_all, &
+ nf90mpi_put_vard_3D_FourByteInt_all, nf90mpi_put_vard_3D_EightByteInt_all, &
+ nf90mpi_put_vard_3D_FourByteReal_all, nf90mpi_put_vard_3D_EightByteReal_all
+ module procedure nf90mpi_put_vard_4D_text_all, &
+ nf90mpi_put_vard_4D_OneByteInt_all, nf90mpi_put_vard_4D_TwoByteInt_all, &
+ nf90mpi_put_vard_4D_FourByteInt_all, nf90mpi_put_vard_4D_EightByteInt_all, &
+ nf90mpi_put_vard_4D_FourByteReal_all, nf90mpi_put_vard_4D_EightByteReal_all
+ module procedure nf90mpi_put_vard_5D_text_all, &
+ nf90mpi_put_vard_5D_OneByteInt_all, nf90mpi_put_vard_5D_TwoByteInt_all, &
+ nf90mpi_put_vard_5D_FourByteInt_all, nf90mpi_put_vard_5D_EightByteInt_all, &
+ nf90mpi_put_vard_5D_FourByteReal_all, nf90mpi_put_vard_5D_EightByteReal_all
+ module procedure nf90mpi_put_vard_6D_text_all, &
+ nf90mpi_put_vard_6D_OneByteInt_all, nf90mpi_put_vard_6D_TwoByteInt_all, &
+ nf90mpi_put_vard_6D_FourByteInt_all, nf90mpi_put_vard_6D_EightByteInt_all, &
+ nf90mpi_put_vard_6D_FourByteReal_all, nf90mpi_put_vard_6D_EightByteReal_all
+ module procedure nf90mpi_put_vard_7D_text_all, &
+ nf90mpi_put_vard_7D_OneByteInt_all, nf90mpi_put_vard_7D_TwoByteInt_all, &
+ nf90mpi_put_vard_7D_FourByteInt_all, nf90mpi_put_vard_7D_EightByteInt_all, &
+ nf90mpi_put_vard_7D_FourByteReal_all, nf90mpi_put_vard_7D_EightByteReal_all
+ end interface ! nf90mpi_put_vard_all
+
+ interface nf90mpi_get_vard_all
+ module procedure nf90mpi_get_vard_text_all, &
+ nf90mpi_get_vard_OneByteInt_all, nf90mpi_get_vard_TwoByteInt_all, &
+ nf90mpi_get_vard_FourByteInt_all, nf90mpi_get_vard_EightByteInt_all, &
+ nf90mpi_get_vard_FourByteReal_all, nf90mpi_get_vard_EightByteReal_all
+ module procedure nf90mpi_get_vard_1D_text_all, &
+ nf90mpi_get_vard_1D_OneByteInt_all, nf90mpi_get_vard_1D_TwoByteInt_all, &
+ nf90mpi_get_vard_1D_FourByteInt_all, nf90mpi_get_vard_1D_EightByteInt_all, &
+ nf90mpi_get_vard_1D_FourByteReal_all, nf90mpi_get_vard_1D_EightByteReal_all
+ module procedure nf90mpi_get_vard_2D_text_all, &
+ nf90mpi_get_vard_2D_OneByteInt_all, nf90mpi_get_vard_2D_TwoByteInt_all, &
+ nf90mpi_get_vard_2D_FourByteInt_all, nf90mpi_get_vard_2D_EightByteInt_all, &
+ nf90mpi_get_vard_2D_FourByteReal_all, nf90mpi_get_vard_2D_EightByteReal_all
+ module procedure nf90mpi_get_vard_3D_text_all, &
+ nf90mpi_get_vard_3D_OneByteInt_all, nf90mpi_get_vard_3D_TwoByteInt_all, &
+ nf90mpi_get_vard_3D_FourByteInt_all, nf90mpi_get_vard_3D_EightByteInt_all, &
+ nf90mpi_get_vard_3D_FourByteReal_all, nf90mpi_get_vard_3D_EightByteReal_all
+ module procedure nf90mpi_get_vard_4D_text_all, &
+ nf90mpi_get_vard_4D_OneByteInt_all, nf90mpi_get_vard_4D_TwoByteInt_all, &
+ nf90mpi_get_vard_4D_FourByteInt_all, nf90mpi_get_vard_4D_EightByteInt_all, &
+ nf90mpi_get_vard_4D_FourByteReal_all, nf90mpi_get_vard_4D_EightByteReal_all
+ module procedure nf90mpi_get_vard_5D_text_all, &
+ nf90mpi_get_vard_5D_OneByteInt_all, nf90mpi_get_vard_5D_TwoByteInt_all, &
+ nf90mpi_get_vard_5D_FourByteInt_all, nf90mpi_get_vard_5D_EightByteInt_all, &
+ nf90mpi_get_vard_5D_FourByteReal_all, nf90mpi_get_vard_5D_EightByteReal_all
+ module procedure nf90mpi_get_vard_6D_text_all, &
+ nf90mpi_get_vard_6D_OneByteInt_all, nf90mpi_get_vard_6D_TwoByteInt_all, &
+ nf90mpi_get_vard_6D_FourByteInt_all, nf90mpi_get_vard_6D_EightByteInt_all, &
+ nf90mpi_get_vard_6D_FourByteReal_all, nf90mpi_get_vard_6D_EightByteReal_all
+ module procedure nf90mpi_get_vard_7D_text_all, &
+ nf90mpi_get_vard_7D_OneByteInt_all, nf90mpi_get_vard_7D_TwoByteInt_all, &
+ nf90mpi_get_vard_7D_FourByteInt_all, nf90mpi_get_vard_7D_EightByteInt_all, &
+ nf90mpi_get_vard_7D_FourByteReal_all, nf90mpi_get_vard_7D_EightByteReal_all
+ end interface ! nf90mpi_get_vard_all
+
+ !
+ ! Nonblocking APIs
+ !
+ interface nf90mpi_iput_var
+ module procedure nf90mpi_iput_var_text, &
+ nf90mpi_iput_var_OneByteInt, nf90mpi_iput_var_TwoByteInt, &
+ nf90mpi_iput_var_FourByteInt, nf90mpi_iput_var_EightByteInt, &
+ nf90mpi_iput_var_FourByteReal, nf90mpi_iput_var_EightByteReal
+ module procedure nf90mpi_iput_var_1D_text, &
+ nf90mpi_iput_var_1D_OneByteInt, nf90mpi_iput_var_1D_TwoByteInt, &
+ nf90mpi_iput_var_1D_FourByteInt, nf90mpi_iput_var_1D_EightByteInt, &
+ nf90mpi_iput_var_1D_FourByteReal, nf90mpi_iput_var_1D_EightByteReal
+ module procedure nf90mpi_iput_var_2D_text, &
+ nf90mpi_iput_var_2D_OneByteInt, nf90mpi_iput_var_2D_TwoByteInt, &
+ nf90mpi_iput_var_2D_FourByteInt, nf90mpi_iput_var_2D_EightByteInt, &
+ nf90mpi_iput_var_2D_FourByteReal, nf90mpi_iput_var_2D_EightByteReal
+ module procedure nf90mpi_iput_var_3D_text, &
+ nf90mpi_iput_var_3D_OneByteInt, nf90mpi_iput_var_3D_TwoByteInt, &
+ nf90mpi_iput_var_3D_FourByteInt, nf90mpi_iput_var_3D_EightByteInt, &
+ nf90mpi_iput_var_3D_FourByteReal, nf90mpi_iput_var_3D_EightByteReal
+ module procedure nf90mpi_iput_var_4D_text, &
+ nf90mpi_iput_var_4D_OneByteInt, nf90mpi_iput_var_4D_TwoByteInt, &
+ nf90mpi_iput_var_4D_FourByteInt, nf90mpi_iput_var_4D_EightByteInt, &
+ nf90mpi_iput_var_4D_FourByteReal, nf90mpi_iput_var_4D_EightByteReal
+ module procedure nf90mpi_iput_var_5D_text, &
+ nf90mpi_iput_var_5D_OneByteInt, nf90mpi_iput_var_5D_TwoByteInt, &
+ nf90mpi_iput_var_5D_FourByteInt, nf90mpi_iput_var_5D_EightByteInt, &
+ nf90mpi_iput_var_5D_FourByteReal, nf90mpi_iput_var_5D_EightByteReal
+ module procedure nf90mpi_iput_var_6D_text, &
+ nf90mpi_iput_var_6D_OneByteInt, nf90mpi_iput_var_6D_TwoByteInt, &
+ nf90mpi_iput_var_6D_FourByteInt, nf90mpi_iput_var_6D_EightByteInt, &
+ nf90mpi_iput_var_6D_FourByteReal, nf90mpi_iput_var_6D_EightByteReal
+ module procedure nf90mpi_iput_var_7D_text, &
+ nf90mpi_iput_var_7D_OneByteInt, nf90mpi_iput_var_7D_TwoByteInt, &
+ nf90mpi_iput_var_7D_FourByteInt, nf90mpi_iput_var_7D_EightByteInt, &
+ nf90mpi_iput_var_7D_FourByteReal, nf90mpi_iput_var_7D_EightByteReal
+ end interface ! nf90mpi_iput_var
+
+ interface nf90mpi_iget_var
+ module procedure nf90mpi_iget_var_text, &
+ nf90mpi_iget_var_OneByteInt, nf90mpi_iget_var_TwoByteInt, &
+ nf90mpi_iget_var_FourByteInt, nf90mpi_iget_var_EightByteInt, &
+ nf90mpi_iget_var_FourByteReal, nf90mpi_iget_var_EightByteReal
+ module procedure nf90mpi_iget_var_1D_text, &
+ nf90mpi_iget_var_1D_OneByteInt, nf90mpi_iget_var_1D_TwoByteInt, &
+ nf90mpi_iget_var_1D_FourByteInt, nf90mpi_iget_var_1D_EightByteInt, &
+ nf90mpi_iget_var_1D_FourByteReal, nf90mpi_iget_var_1D_EightByteReal
+ module procedure nf90mpi_iget_var_2D_text, &
+ nf90mpi_iget_var_2D_OneByteInt, nf90mpi_iget_var_2D_TwoByteInt, &
+ nf90mpi_iget_var_2D_FourByteInt, nf90mpi_iget_var_2D_EightByteInt, &
+ nf90mpi_iget_var_2D_FourByteReal, nf90mpi_iget_var_2D_EightByteReal
+ module procedure nf90mpi_iget_var_3D_text, &
+ nf90mpi_iget_var_3D_OneByteInt, nf90mpi_iget_var_3D_TwoByteInt, &
+ nf90mpi_iget_var_3D_FourByteInt, nf90mpi_iget_var_3D_EightByteInt, &
+ nf90mpi_iget_var_3D_FourByteReal, nf90mpi_iget_var_3D_EightByteReal
+ module procedure nf90mpi_iget_var_4D_text, &
+ nf90mpi_iget_var_4D_OneByteInt, nf90mpi_iget_var_4D_TwoByteInt, &
+ nf90mpi_iget_var_4D_FourByteInt, nf90mpi_iget_var_4D_EightByteInt, &
+ nf90mpi_iget_var_4D_FourByteReal, nf90mpi_iget_var_4D_EightByteReal
+ module procedure nf90mpi_iget_var_5D_text, &
+ nf90mpi_iget_var_5D_OneByteInt, nf90mpi_iget_var_5D_TwoByteInt, &
+ nf90mpi_iget_var_5D_FourByteInt, nf90mpi_iget_var_5D_EightByteInt, &
+ nf90mpi_iget_var_5D_FourByteReal, nf90mpi_iget_var_5D_EightByteReal
+ module procedure nf90mpi_iget_var_6D_text, &
+ nf90mpi_iget_var_6D_OneByteInt, nf90mpi_iget_var_6D_TwoByteInt, &
+ nf90mpi_iget_var_6D_FourByteInt, nf90mpi_iget_var_6D_EightByteInt, &
+ nf90mpi_iget_var_6D_FourByteReal, nf90mpi_iget_var_6D_EightByteReal
+ module procedure nf90mpi_iget_var_7D_text, &
+ nf90mpi_iget_var_7D_OneByteInt, nf90mpi_iget_var_7D_TwoByteInt, &
+ nf90mpi_iget_var_7D_FourByteInt, nf90mpi_iget_var_7D_EightByteInt, &
+ nf90mpi_iget_var_7D_FourByteReal, nf90mpi_iget_var_7D_EightByteReal
+ end interface ! nf90mpi_iget_var
+
+ interface nf90mpi_iput_varn
+ module procedure nf90mpi_iput_varn_text, &
+ nf90mpi_iput_varn_OneByteInt, nf90mpi_iput_varn_TwoByteInt, &
+ nf90mpi_iput_varn_FourByteInt, nf90mpi_iput_varn_EightByteInt, &
+ nf90mpi_iput_varn_FourByteReal, nf90mpi_iput_varn_EightByteReal
+ module procedure nf90mpi_iput_varn_1D_text, &
+ nf90mpi_iput_varn_1D_OneByteInt, nf90mpi_iput_varn_1D_TwoByteInt, &
+ nf90mpi_iput_varn_1D_FourByteInt, nf90mpi_iput_varn_1D_EightByteInt, &
+ nf90mpi_iput_varn_1D_FourByteReal, nf90mpi_iput_varn_1D_EightByteReal
+ module procedure nf90mpi_iput_varn_2D_text, &
+ nf90mpi_iput_varn_2D_OneByteInt, nf90mpi_iput_varn_2D_TwoByteInt, &
+ nf90mpi_iput_varn_2D_FourByteInt, nf90mpi_iput_varn_2D_EightByteInt, &
+ nf90mpi_iput_varn_2D_FourByteReal, nf90mpi_iput_varn_2D_EightByteReal
+ module procedure nf90mpi_iput_varn_3D_text, &
+ nf90mpi_iput_varn_3D_OneByteInt, nf90mpi_iput_varn_3D_TwoByteInt, &
+ nf90mpi_iput_varn_3D_FourByteInt, nf90mpi_iput_varn_3D_EightByteInt, &
+ nf90mpi_iput_varn_3D_FourByteReal, nf90mpi_iput_varn_3D_EightByteReal
+ module procedure nf90mpi_iput_varn_4D_text, &
+ nf90mpi_iput_varn_4D_OneByteInt, nf90mpi_iput_varn_4D_TwoByteInt, &
+ nf90mpi_iput_varn_4D_FourByteInt, nf90mpi_iput_varn_4D_EightByteInt, &
+ nf90mpi_iput_varn_4D_FourByteReal, nf90mpi_iput_varn_4D_EightByteReal
+ module procedure nf90mpi_iput_varn_5D_text, &
+ nf90mpi_iput_varn_5D_OneByteInt, nf90mpi_iput_varn_5D_TwoByteInt, &
+ nf90mpi_iput_varn_5D_FourByteInt, nf90mpi_iput_varn_5D_EightByteInt, &
+ nf90mpi_iput_varn_5D_FourByteReal, nf90mpi_iput_varn_5D_EightByteReal
+ module procedure nf90mpi_iput_varn_6D_text, &
+ nf90mpi_iput_varn_6D_OneByteInt, nf90mpi_iput_varn_6D_TwoByteInt, &
+ nf90mpi_iput_varn_6D_FourByteInt, nf90mpi_iput_varn_6D_EightByteInt, &
+ nf90mpi_iput_varn_6D_FourByteReal, nf90mpi_iput_varn_6D_EightByteReal
+ module procedure nf90mpi_iput_varn_7D_text, &
+ nf90mpi_iput_varn_7D_OneByteInt, nf90mpi_iput_varn_7D_TwoByteInt, &
+ nf90mpi_iput_varn_7D_FourByteInt, nf90mpi_iput_varn_7D_EightByteInt, &
+ nf90mpi_iput_varn_7D_FourByteReal, nf90mpi_iput_varn_7D_EightByteReal
+ end interface ! nf90mpi_iput_varn
+
+ interface nf90mpi_iget_varn
+ module procedure nf90mpi_iget_varn_text, &
+ nf90mpi_iget_varn_OneByteInt, nf90mpi_iget_varn_TwoByteInt, &
+ nf90mpi_iget_varn_FourByteInt, nf90mpi_iget_varn_EightByteInt, &
+ nf90mpi_iget_varn_FourByteReal, nf90mpi_iget_varn_EightByteReal
+ module procedure nf90mpi_iget_varn_1D_text, &
+ nf90mpi_iget_varn_1D_OneByteInt, nf90mpi_iget_varn_1D_TwoByteInt, &
+ nf90mpi_iget_varn_1D_FourByteInt, nf90mpi_iget_varn_1D_EightByteInt, &
+ nf90mpi_iget_varn_1D_FourByteReal, nf90mpi_iget_varn_1D_EightByteReal
+ module procedure nf90mpi_iget_varn_2D_text, &
+ nf90mpi_iget_varn_2D_OneByteInt, nf90mpi_iget_varn_2D_TwoByteInt, &
+ nf90mpi_iget_varn_2D_FourByteInt, nf90mpi_iget_varn_2D_EightByteInt, &
+ nf90mpi_iget_varn_2D_FourByteReal, nf90mpi_iget_varn_2D_EightByteReal
+ module procedure nf90mpi_iget_varn_3D_text, &
+ nf90mpi_iget_varn_3D_OneByteInt, nf90mpi_iget_varn_3D_TwoByteInt, &
+ nf90mpi_iget_varn_3D_FourByteInt, nf90mpi_iget_varn_3D_EightByteInt, &
+ nf90mpi_iget_varn_3D_FourByteReal, nf90mpi_iget_varn_3D_EightByteReal
+ module procedure nf90mpi_iget_varn_4D_text, &
+ nf90mpi_iget_varn_4D_OneByteInt, nf90mpi_iget_varn_4D_TwoByteInt, &
+ nf90mpi_iget_varn_4D_FourByteInt, nf90mpi_iget_varn_4D_EightByteInt, &
+ nf90mpi_iget_varn_4D_FourByteReal, nf90mpi_iget_varn_4D_EightByteReal
+ module procedure nf90mpi_iget_varn_5D_text, &
+ nf90mpi_iget_varn_5D_OneByteInt, nf90mpi_iget_varn_5D_TwoByteInt, &
+ nf90mpi_iget_varn_5D_FourByteInt, nf90mpi_iget_varn_5D_EightByteInt, &
+ nf90mpi_iget_varn_5D_FourByteReal, nf90mpi_iget_varn_5D_EightByteReal
+ module procedure nf90mpi_iget_varn_6D_text, &
+ nf90mpi_iget_varn_6D_OneByteInt, nf90mpi_iget_varn_6D_TwoByteInt, &
+ nf90mpi_iget_varn_6D_FourByteInt, nf90mpi_iget_varn_6D_EightByteInt, &
+ nf90mpi_iget_varn_6D_FourByteReal, nf90mpi_iget_varn_6D_EightByteReal
+ module procedure nf90mpi_iget_varn_7D_text, &
+ nf90mpi_iget_varn_7D_OneByteInt, nf90mpi_iget_varn_7D_TwoByteInt, &
+ nf90mpi_iget_varn_7D_FourByteInt, nf90mpi_iget_varn_7D_EightByteInt, &
+ nf90mpi_iget_varn_7D_FourByteReal, nf90mpi_iget_varn_7D_EightByteReal
+ end interface ! nf90mpi_iget_varn
+
+ interface nf90mpi_bput_var
+ module procedure nf90mpi_bput_var_text, &
+ nf90mpi_bput_var_OneByteInt, nf90mpi_bput_var_TwoByteInt, &
+ nf90mpi_bput_var_FourByteInt, nf90mpi_bput_var_EightByteInt, &
+ nf90mpi_bput_var_FourByteReal, nf90mpi_bput_var_EightByteReal
+ module procedure nf90mpi_bput_var_1D_text, &
+ nf90mpi_bput_var_1D_OneByteInt, nf90mpi_bput_var_1D_TwoByteInt, &
+ nf90mpi_bput_var_1D_FourByteInt, nf90mpi_bput_var_1D_EightByteInt, &
+ nf90mpi_bput_var_1D_FourByteReal, nf90mpi_bput_var_1D_EightByteReal
+ module procedure nf90mpi_bput_var_2D_text, &
+ nf90mpi_bput_var_2D_OneByteInt, nf90mpi_bput_var_2D_TwoByteInt, &
+ nf90mpi_bput_var_2D_FourByteInt, nf90mpi_bput_var_2D_EightByteInt, &
+ nf90mpi_bput_var_2D_FourByteReal, nf90mpi_bput_var_2D_EightByteReal
+ module procedure nf90mpi_bput_var_3D_text, &
+ nf90mpi_bput_var_3D_OneByteInt, nf90mpi_bput_var_3D_TwoByteInt, &
+ nf90mpi_bput_var_3D_FourByteInt, nf90mpi_bput_var_3D_EightByteInt, &
+ nf90mpi_bput_var_3D_FourByteReal, nf90mpi_bput_var_3D_EightByteReal
+ module procedure nf90mpi_bput_var_4D_text, &
+ nf90mpi_bput_var_4D_OneByteInt, nf90mpi_bput_var_4D_TwoByteInt, &
+ nf90mpi_bput_var_4D_FourByteInt, nf90mpi_bput_var_4D_EightByteInt, &
+ nf90mpi_bput_var_4D_FourByteReal, nf90mpi_bput_var_4D_EightByteReal
+ module procedure nf90mpi_bput_var_5D_text, &
+ nf90mpi_bput_var_5D_OneByteInt, nf90mpi_bput_var_5D_TwoByteInt, &
+ nf90mpi_bput_var_5D_FourByteInt, nf90mpi_bput_var_5D_EightByteInt, &
+ nf90mpi_bput_var_5D_FourByteReal, nf90mpi_bput_var_5D_EightByteReal
+ module procedure nf90mpi_bput_var_6D_text, &
+ nf90mpi_bput_var_6D_OneByteInt, nf90mpi_bput_var_6D_TwoByteInt, &
+ nf90mpi_bput_var_6D_FourByteInt, nf90mpi_bput_var_6D_EightByteInt, &
+ nf90mpi_bput_var_6D_FourByteReal, nf90mpi_bput_var_6D_EightByteReal
+ module procedure nf90mpi_bput_var_7D_text, &
+ nf90mpi_bput_var_7D_OneByteInt, nf90mpi_bput_var_7D_TwoByteInt, &
+ nf90mpi_bput_var_7D_FourByteInt, nf90mpi_bput_var_7D_EightByteInt, &
+ nf90mpi_bput_var_7D_FourByteReal, nf90mpi_bput_var_7D_EightByteReal
+ end interface ! nf90mpi_bput_var
+
+ interface nf90mpi_bput_varn
+ module procedure nf90mpi_bput_varn_text, &
+ nf90mpi_bput_varn_OneByteInt, nf90mpi_bput_varn_TwoByteInt, &
+ nf90mpi_bput_varn_FourByteInt, nf90mpi_bput_varn_EightByteInt, &
+ nf90mpi_bput_varn_FourByteReal, nf90mpi_bput_varn_EightByteReal
+ module procedure nf90mpi_bput_varn_1D_text, &
+ nf90mpi_bput_varn_1D_OneByteInt, nf90mpi_bput_varn_1D_TwoByteInt, &
+ nf90mpi_bput_varn_1D_FourByteInt, nf90mpi_bput_varn_1D_EightByteInt, &
+ nf90mpi_bput_varn_1D_FourByteReal, nf90mpi_bput_varn_1D_EightByteReal
+ module procedure nf90mpi_bput_varn_2D_text, &
+ nf90mpi_bput_varn_2D_OneByteInt, nf90mpi_bput_varn_2D_TwoByteInt, &
+ nf90mpi_bput_varn_2D_FourByteInt, nf90mpi_bput_varn_2D_EightByteInt, &
+ nf90mpi_bput_varn_2D_FourByteReal, nf90mpi_bput_varn_2D_EightByteReal
+ module procedure nf90mpi_bput_varn_3D_text, &
+ nf90mpi_bput_varn_3D_OneByteInt, nf90mpi_bput_varn_3D_TwoByteInt, &
+ nf90mpi_bput_varn_3D_FourByteInt, nf90mpi_bput_varn_3D_EightByteInt, &
+ nf90mpi_bput_varn_3D_FourByteReal, nf90mpi_bput_varn_3D_EightByteReal
+ module procedure nf90mpi_bput_varn_4D_text, &
+ nf90mpi_bput_varn_4D_OneByteInt, nf90mpi_bput_varn_4D_TwoByteInt, &
+ nf90mpi_bput_varn_4D_FourByteInt, nf90mpi_bput_varn_4D_EightByteInt, &
+ nf90mpi_bput_varn_4D_FourByteReal, nf90mpi_bput_varn_4D_EightByteReal
+ module procedure nf90mpi_bput_varn_5D_text, &
+ nf90mpi_bput_varn_5D_OneByteInt, nf90mpi_bput_varn_5D_TwoByteInt, &
+ nf90mpi_bput_varn_5D_FourByteInt, nf90mpi_bput_varn_5D_EightByteInt, &
+ nf90mpi_bput_varn_5D_FourByteReal, nf90mpi_bput_varn_5D_EightByteReal
+ module procedure nf90mpi_bput_varn_6D_text, &
+ nf90mpi_bput_varn_6D_OneByteInt, nf90mpi_bput_varn_6D_TwoByteInt, &
+ nf90mpi_bput_varn_6D_FourByteInt, nf90mpi_bput_varn_6D_EightByteInt, &
+ nf90mpi_bput_varn_6D_FourByteReal, nf90mpi_bput_varn_6D_EightByteReal
+ module procedure nf90mpi_bput_varn_7D_text, &
+ nf90mpi_bput_varn_7D_OneByteInt, nf90mpi_bput_varn_7D_TwoByteInt, &
+ nf90mpi_bput_varn_7D_FourByteInt, nf90mpi_bput_varn_7D_EightByteInt, &
+ nf90mpi_bput_varn_7D_FourByteReal, nf90mpi_bput_varn_7D_EightByteReal
+ end interface ! nf90mpi_bput_varn
+
diff --git a/src/libf90/pnetcdf.f90 b/src/libf90/pnetcdf.f90
new file mode 100644
index 0000000..3b1775c
--- /dev/null
+++ b/src/libf90/pnetcdf.f90
@@ -0,0 +1,40 @@
+!
+! Copyright (C) 2013, Northwestern University and Argonne National Laboratory
+! See COPYRIGHT notice in top-level directory.
+!
+! $Id: pnetcdf.f90 1816 2014-10-11 04:19:56Z wkliao $
+!
+! This file is taken from netcdf.f90 with changes for PnetCDF use
+!
+!
+ module pnetcdf
+ use mpi, only: MPI_OFFSET_KIND
+
+ implicit none
+ private
+
+ integer, parameter :: OneByteInt = selected_int_kind(2), &
+ TwoByteInt = selected_int_kind(4), &
+ FourByteInt = selected_int_kind(9), &
+ EightByteInt = selected_int_kind(18)
+
+ integer, parameter :: &
+ FourByteReal = selected_real_kind(P = 6, R = 37), &
+ EightByteReal = selected_real_kind(P = 13, R = 307)
+
+ include "nfmpi_constants.f90"
+ include "nf90_constants.f90"
+ include "api.f90"
+ include "overloads.f90"
+ include "visibility.f90"
+
+contains
+ include "file.f90"
+ include "dims.f90"
+ include "attributes.f90"
+ include "variables.f90"
+ include "getput_text.f90"
+ include "getput_var.f90"
+ include "getput_varn.f90"
+ include "getput_vard.f90"
+end module pnetcdf
diff --git a/src/libf90/variables.f90 b/src/libf90/variables.f90
new file mode 100644
index 0000000..b6a520f
--- /dev/null
+++ b/src/libf90/variables.f90
@@ -0,0 +1,229 @@
+!
+! Copyright (C) 2013, Northwestern University and Argonne National Laboratory
+! See COPYRIGHT notice in top-level directory.
+!
+! $Id: variables.f90 2012 2015-02-16 05:52:44Z wkliao $
+!
+! This file is taken from netcdf_variables.f90 with changes for PnetCDF use
+!
+!
+
+ ! -----
+ ! Variable definitions and inquiry
+ ! -----
+ function nf90mpi_def_var_Scalar(ncid, name, xtype, varid)
+ integer, intent( in) :: ncid
+ character (len = *), intent( in) :: name
+ integer, intent( in) :: xtype
+ integer, intent(out) :: varid
+ integer :: nf90mpi_def_var_Scalar
+
+ ! Dummy - shouldn't get used
+ integer, dimension(1) :: dimids
+
+ nf90mpi_def_var_Scalar = nfmpi_def_var(ncid, name, xtype, 0, dimids, varid)
+ end function nf90mpi_def_var_Scalar
+ ! -----
+ function nf90mpi_def_var_oneDim(ncid, name, xtype, dimids, varid)
+ integer, intent( in) :: ncid
+ character (len = *), intent( in) :: name
+ integer, intent( in) :: xtype
+ integer, intent( in) :: dimids
+ integer, intent(out) :: varid
+ integer :: nf90mpi_def_var_oneDim
+
+ integer, dimension(1) :: dimidsA
+ dimidsA(1) = dimids
+ nf90mpi_def_var_oneDim = nfmpi_def_var(ncid, name, xtype, 1, dimidsA, varid)
+ end function nf90mpi_def_var_oneDim
+ ! -----
+ function nf90mpi_def_var_ManyDims(ncid, name, xtype, dimids, varid)
+ integer, intent( in) :: ncid
+ character (len = *), intent( in) :: name
+ integer, intent( in) :: xtype
+ integer, dimension(:), intent( in) :: dimids
+ integer, intent(out) :: varid
+ integer :: nf90mpi_def_var_ManyDims
+
+ nf90mpi_def_var_ManyDims = nfmpi_def_var(ncid, name, xtype, size(dimids), dimids, varid)
+ end function nf90mpi_def_var_ManyDims
+ ! -----
+ function nf90mpi_inq_varid(ncid, name, varid)
+ integer, intent( in) :: ncid
+ character (len = *), intent( in) :: name
+ integer, intent(out) :: varid
+ integer :: nf90mpi_inq_varid
+
+ nf90mpi_inq_varid = nfmpi_inq_varid(ncid, name, varid)
+ end function nf90mpi_inq_varid
+ ! -----
+ function nf90mpi_inquire_variable(ncid, varid, name, xtype, ndims, dimids, nAtts)
+ integer, intent( in) :: ncid, varid
+ character (len = *), optional, intent(out) :: name
+ integer, optional, intent(out) :: xtype, ndims
+ integer, dimension(:), optional, intent(out) :: dimids
+ integer, optional, intent(out) :: nAtts
+ integer :: nf90mpi_inquire_variable
+
+ ! Local variables
+ character (len = nf90_max_name) :: varName
+ integer :: externalType, numDimensions
+ integer, dimension(nf90_max_var_dims) :: dimensionIDs
+ integer :: numAttributes
+
+ nf90mpi_inquire_variable = nfmpi_inq_var(ncid, varid, varName, externalType, &
+ numDimensions, dimensionIDs, numAttributes)
+ if (nf90mpi_inquire_variable == nf90_noerr) then
+ if(present(name)) name = trim(varName)
+ if(present(xtype)) xtype = externalType
+ if(present(ndims)) ndims = numDimensions
+ if(present(dimids)) then
+ if (size(dimids) .ge. numDimensions) then
+ dimids(:numDimensions) = dimensionIDs(:numDimensions)
+ else
+ nf90mpi_inquire_variable = nf90_einval
+ endif
+ endif
+ if(present(nAtts)) nAtts = numAttributes
+ endif
+ end function nf90mpi_inquire_variable
+ ! -----
+ function nf90mpi_rename_var(ncid, varid, newname)
+ integer, intent( in) :: ncid, varid
+ character (len = *), intent( in) :: newname
+ integer :: nf90mpi_rename_var
+
+ nf90mpi_rename_var = nfmpi_rename_var(ncid, varid, newname)
+ end function nf90mpi_rename_var
+ ! -----
+ ! nf90mpi_def_var_fill
+ ! -----
+ function nf90mpi_def_var_fill_text(ncid, varid, no_fill, fill_value)
+ integer, intent( in) :: ncid, varid, no_fill
+ character, intent( in) :: fill_value
+ integer :: nf90mpi_def_var_fill_text
+
+ nf90mpi_def_var_fill_text = nfmpi_def_var_fill(ncid, varid, no_fill, fill_value)
+ end function nf90mpi_def_var_fill_text
+ ! -----
+ function nf90mpi_def_var_fill_OneByteInt(ncid, varid, no_fill, fill_value)
+ integer, intent( in) :: ncid, varid, no_fill
+ integer(kind=OneByteInt), intent( in) :: fill_value
+ integer :: nf90mpi_def_var_fill_OneByteInt
+
+ nf90mpi_def_var_fill_OneByteInt = nfmpi_def_var_fill(ncid, varid, no_fill, fill_value)
+ end function nf90mpi_def_var_fill_OneByteInt
+ ! -----
+ function nf90mpi_def_var_fill_TwoByteInt(ncid, varid, no_fill, fill_value)
+ integer, intent( in) :: ncid, varid, no_fill
+ integer(kind=TwoByteInt), intent( in) :: fill_value
+ integer :: nf90mpi_def_var_fill_TwoByteInt
+
+ nf90mpi_def_var_fill_TwoByteInt = nfmpi_def_var_fill(ncid, varid, no_fill, fill_value)
+ end function nf90mpi_def_var_fill_TwoByteInt
+ ! -----
+ function nf90mpi_def_var_fill_FourByteInt(ncid, varid, no_fill, fill_value)
+ integer, intent( in) :: ncid, varid, no_fill
+ integer(kind=FourByteInt), intent( in) :: fill_value
+ integer :: nf90mpi_def_var_fill_FourByteInt
+
+ nf90mpi_def_var_fill_FourByteInt = nfmpi_def_var_fill(ncid, varid, no_fill, fill_value)
+ end function nf90mpi_def_var_fill_FourByteInt
+ ! -----
+ function nf90mpi_def_var_fill_EightByteInt(ncid, varid, no_fill, fill_value)
+ integer, intent( in) :: ncid, varid, no_fill
+ integer(kind=EightByteInt), intent( in) :: fill_value
+ integer :: nf90mpi_def_var_fill_EightByteInt
+
+ nf90mpi_def_var_fill_EightByteInt = nfmpi_def_var_fill(ncid, varid, no_fill, fill_value)
+ end function nf90mpi_def_var_fill_EightByteInt
+ ! -----
+ function nf90mpi_def_var_fill_FourByteReal(ncid, varid, no_fill, fill_value)
+ integer, intent( in) :: ncid, varid, no_fill
+ real(kind=FourByteReal), intent( in) :: fill_value
+ integer :: nf90mpi_def_var_fill_FourByteReal
+
+ nf90mpi_def_var_fill_FourByteReal = nfmpi_def_var_fill(ncid, varid, no_fill, fill_value)
+ end function nf90mpi_def_var_fill_FourByteReal
+ ! -----
+ function nf90mpi_def_var_fill_EightByteReal(ncid, varid, no_fill, fill_value)
+ integer, intent( in) :: ncid, varid, no_fill
+ real(kind=EightByteReal), intent( in) :: fill_value
+ integer :: nf90mpi_def_var_fill_EightByteReal
+
+ nf90mpi_def_var_fill_EightByteReal = nfmpi_def_var_fill(ncid, varid, no_fill, fill_value)
+ end function nf90mpi_def_var_fill_EightByteReal
+ ! -----
+ ! nf90mpi_inq_var_fill
+ ! -----
+ function nf90mpi_inq_var_fill_text(ncid, varid, no_fill, fill_value)
+ integer, intent( in) :: ncid, varid
+ integer, intent(out) :: no_fill
+ character, intent(out) :: fill_value
+ integer :: nf90mpi_inq_var_fill_text
+
+ nf90mpi_inq_var_fill_text = nfmpi_inq_var_fill(ncid, varid, no_fill, fill_value)
+ end function nf90mpi_inq_var_fill_text
+ ! -----
+ function nf90mpi_inq_var_fill_OneByteInt(ncid, varid, no_fill, fill_value)
+ integer, intent( in) :: ncid, varid
+ integer, intent(out) :: no_fill
+ integer(kind=OneByteInt), intent(out) :: fill_value
+ integer :: nf90mpi_inq_var_fill_OneByteInt
+
+ nf90mpi_inq_var_fill_OneByteInt = nfmpi_inq_var_fill(ncid, varid, no_fill, fill_value)
+ end function nf90mpi_inq_var_fill_OneByteInt
+ ! -----
+ function nf90mpi_inq_var_fill_TwoByteInt(ncid, varid, no_fill, fill_value)
+ integer, intent( in) :: ncid, varid
+ integer, intent(out) :: no_fill
+ integer(kind=TwoByteInt), intent(out) :: fill_value
+ integer :: nf90mpi_inq_var_fill_TwoByteInt
+
+ nf90mpi_inq_var_fill_TwoByteInt = nfmpi_inq_var_fill(ncid, varid, no_fill, fill_value)
+ end function nf90mpi_inq_var_fill_TwoByteInt
+ ! -----
+ function nf90mpi_inq_var_fill_FourByteInt(ncid, varid, no_fill, fill_value)
+ integer, intent( in) :: ncid, varid
+ integer, intent(out) :: no_fill
+ integer(kind=FourByteInt), intent(out) :: fill_value
+ integer :: nf90mpi_inq_var_fill_FourByteInt
+
+ nf90mpi_inq_var_fill_FourByteInt = nfmpi_inq_var_fill(ncid, varid, no_fill, fill_value)
+ end function nf90mpi_inq_var_fill_FourByteInt
+ ! -----
+ function nf90mpi_inq_var_fill_EightByteInt(ncid, varid, no_fill, fill_value)
+ integer, intent( in) :: ncid, varid
+ integer, intent(out) :: no_fill
+ integer(kind=EightByteInt), intent(out) :: fill_value
+ integer :: nf90mpi_inq_var_fill_EightByteInt
+
+ nf90mpi_inq_var_fill_EightByteInt = nfmpi_inq_var_fill(ncid, varid, no_fill, fill_value)
+ end function nf90mpi_inq_var_fill_EightByteInt
+ ! -----
+ function nf90mpi_inq_var_fill_FourByteReal(ncid, varid, no_fill, fill_value)
+ integer, intent( in) :: ncid, varid
+ integer, intent(out) :: no_fill
+ real(kind=FourByteReal), intent(out) :: fill_value
+ integer :: nf90mpi_inq_var_fill_FourByteReal
+
+ nf90mpi_inq_var_fill_FourByteReal = nfmpi_inq_var_fill(ncid, varid, no_fill, fill_value)
+ end function nf90mpi_inq_var_fill_FourByteReal
+ ! -----
+ function nf90mpi_inq_var_fill_EightByteReal(ncid, varid, no_fill, fill_value)
+ integer, intent( in) :: ncid, varid
+ integer, intent(out) :: no_fill
+ real(kind=EightByteReal), intent(out) :: fill_value
+ integer :: nf90mpi_inq_var_fill_EightByteReal
+
+ nf90mpi_inq_var_fill_EightByteReal = nfmpi_inq_var_fill(ncid, varid, no_fill, fill_value)
+ end function nf90mpi_inq_var_fill_EightByteReal
+ ! -----
+ function nf90mpi_fill_var_rec(ncid, varid, recno)
+ integer, intent(in) :: ncid, varid
+ integer(kind=MPI_OFFSET_KIND), intent(in) :: recno
+ integer :: nf90mpi_fill_var_rec
+
+ nf90mpi_fill_var_rec = nfmpi_fill_var_rec(ncid, varid, recno)
+ end function nf90mpi_fill_var_rec
+ ! -----
diff --git a/src/libf90/visibility.f90 b/src/libf90/visibility.f90
new file mode 100644
index 0000000..96362da
--- /dev/null
+++ b/src/libf90/visibility.f90
@@ -0,0 +1,617 @@
+!
+! Copyright (C) 2013, Northwestern University and Argonne National Laboratory
+! See COPYRIGHT notice in top-level directory.
+!
+! $Id: visibility.f90 2013 2015-02-18 17:14:26Z wkliao $
+!
+! This file is taken from netcdf_visibility.f90 with changes for PnetCDF use
+!
+!
+
+ ! Library version, error string
+ public :: nf90mpi_inq_libvers, nf90mpi_strerror
+
+ ! Control routines
+ public :: nf90mpi_create, nf90mpi_open, &
+ nf90mpi_set_fill, nf90mpi_redef, &
+ nf90mpi_enddef, nf90mpi_sync, &
+ nf90mpi_abort, nf90mpi_close, &
+ nf90mpi_delete, nf90mpi_set_default_format
+
+ ! File level inquiry
+ public :: nf90mpi_inquire, nf90mpi_inq_striping, &
+ nf90mpi_inq_num_rec_vars, nf90mpi_inq_num_fix_vars, &
+ nf90mpi_inq_default_format
+
+ ! Dimension routines
+ public :: nf90mpi_def_dim, nf90mpi_inq_dimid, &
+ nf90mpi_rename_dim, nf90mpi_inquire_dimension
+
+ ! attribute routines
+ public :: nf90mpi_copy_att, nf90mpi_rename_att, &
+ nf90mpi_del_att, nf90mpi_inq_attname, &
+ nf90mpi_inquire_attribute
+
+ ! overloaded functions
+ public :: nf90mpi_put_att, nf90mpi_get_att
+
+ ! Variable routines
+ public :: nf90mpi_def_var, nf90mpi_inq_varid, &
+ nf90mpi_rename_var, nf90mpi_inquire_variable, &
+ nf90mpi_def_var_fill, nf90mpi_inq_var_fill, &
+ nf90mpi_fill_var_rec
+
+ ! overloaded functions
+ ! independent APIs
+ public :: nf90mpi_put_var, nf90mpi_get_var, &
+ nf90mpi_put_varn, nf90mpi_get_varn, &
+ nf90mpi_put_vard, nf90mpi_get_vard
+
+ ! collective APIs
+ public :: nf90mpi_put_var_all, nf90mpi_get_var_all, &
+ nf90mpi_put_varn_all, nf90mpi_get_varn_all, &
+ nf90mpi_put_vard_all, nf90mpi_get_vard_all
+
+ ! nonblocking APIs
+ public :: nf90mpi_iput_var, nf90mpi_iget_var, &
+ nf90mpi_iput_varn, nf90mpi_iget_varn, &
+ nf90mpi_bput_varn, nf90mpi_bput_var, &
+ nf90mpi_inq_nreqs, nf90mpi_buffer_attach, &
+ nf90mpi_inq_buffer_usage, nf90mpi_buffer_detach, &
+ nf90mpi_wait, nf90mpi_wait_all, &
+ nf90mpi_cancel, nf90mpi_inq_buffer_size
+
+ public :: nf90mpi_begin_indep_data, nf90mpi_end_indep_data, &
+ nf90mpi_inq_put_size, nf90mpi_inq_get_size, &
+ nf90mpi_inq_header_size, nf90mpi_inq_header_extent, &
+ nf90mpi_inq_varoffset, nf90mpi_inq_file_info, &
+ nf90mpi_get_file_info, nf90mpi_inq_malloc_size, &
+ nf90mpi_inq_malloc_max_size, nf90mpi_inq_malloc_list, &
+ nf90mpi_inq_files_opened, nf90mpi_inq_recsize
+
+!
+! F77 APIs
+!
+
+ public :: &
+ nfmpi_inq_libvers, &
+ nfmpi_strerror, &
+ nfmpi_issyserr
+!
+! control subroutines:
+!
+ public :: &
+ nfmpi_create, &
+ nfmpi_open, &
+ nfmpi_inq_format, &
+ nfmpi_inq_file_format, &
+ nfmpi_inq_file_info, &
+ nfmpi_get_file_info, &
+ nfmpi_delete, &
+ nfmpi_enddef, &
+ nfmpi__enddef, &
+ nfmpi_redef, &
+ nfmpi_set_default_format, &
+ nfmpi_inq_default_format, &
+ nfmpi_sync, &
+ nfmpi_abort, &
+ nfmpi_close, &
+ nfmpi_set_fill
+!
+! general inquiry subroutines:
+!
+ public :: &
+ nfmpi_inq, &
+ nfmpi_inq_ndims, &
+ nfmpi_inq_nvars, &
+ nfmpi_inq_num_rec_vars, &
+ nfmpi_inq_num_fix_vars, &
+ nfmpi_inq_natts, &
+ nfmpi_inq_unlimdim, &
+ nfmpi_inq_striping
+!
+! dimension subroutines:
+!
+ public :: &
+ nfmpi_def_dim, &
+ nfmpi_inq_dimid, &
+ nfmpi_inq_dim, &
+ nfmpi_inq_dimname, &
+ nfmpi_inq_dimlen, &
+ nfmpi_rename_dim
+!
+! general attribute subroutines:
+!
+ public :: &
+ nfmpi_inq_att, &
+ nfmpi_inq_attid, &
+ nfmpi_inq_atttype, &
+ nfmpi_inq_attlen, &
+ nfmpi_inq_attname, &
+ nfmpi_copy_att, &
+ nfmpi_rename_att, &
+ nfmpi_del_att
+!
+! attribute put/get subroutines:
+!
+ integer nfmpi_put_att, nfmpi_get_att
+ external nfmpi_put_att, nfmpi_get_att
+
+ public :: &
+ nfmpi_put_att_text, &
+ nfmpi_get_att_text, &
+ nfmpi_put_att_int1, &
+ nfmpi_get_att_int1, &
+ nfmpi_put_att_int2, &
+ nfmpi_get_att_int2, &
+ nfmpi_put_att_int, &
+ nfmpi_get_att_int, &
+ nfmpi_put_att_real, &
+ nfmpi_get_att_real, &
+ nfmpi_put_att_double, &
+ nfmpi_get_att_double, &
+ nfmpi_put_att_int8, &
+ nfmpi_get_att_int8
+!
+! independent data mode subroutines:
+!
+ public :: &
+ nfmpi_begin_indep_data, &
+ nfmpi_end_indep_data
+!
+! general variable subroutines:
+!
+ public :: &
+ nfmpi_def_var, &
+ nfmpi_inq_var, &
+ nfmpi_inq_varid, &
+ nfmpi_inq_varname, &
+ nfmpi_inq_vartype, &
+ nfmpi_inq_varndims, &
+ nfmpi_inq_vardimid, &
+ nfmpi_inq_varnatts, &
+ nfmpi_rename_var, &
+ nfmpi_def_var_fill, &
+ nfmpi_inq_var_fill, &
+ nfmpi_fill_var_rec
+
+!
+! entire variable put/get subroutines:
+!
+ public :: &
+ nfmpi_put_var_text, &
+ nfmpi_get_var_text, &
+ nfmpi_get_var_text_all, &
+ nfmpi_put_var_int1, &
+ nfmpi_get_var_int1, &
+ nfmpi_get_var_int1_all, &
+ nfmpi_put_var_int2, &
+ nfmpi_get_var_int2, &
+ nfmpi_get_var_int2_all, &
+ nfmpi_put_var_int, &
+ nfmpi_get_var_int, &
+ nfmpi_get_var_int_all, &
+ nfmpi_put_var_real, &
+ nfmpi_get_var_real, &
+ nfmpi_get_var_real_all, &
+ nfmpi_put_var_double, &
+ nfmpi_get_var_double, &
+ nfmpi_get_var_double_all, &
+ nfmpi_put_var_int8, &
+ nfmpi_get_var_int8, &
+ nfmpi_get_var_int8_all
+!
+! single variable put/get subroutines:
+!
+ public :: &
+ nfmpi_put_var1_text, &
+ nfmpi_put_var1_text_all, &
+ nfmpi_get_var1_text, &
+ nfmpi_get_var1_text_all, &
+ nfmpi_put_var1_int1, &
+ nfmpi_put_var1_int1_all, &
+ nfmpi_get_var1_int1, &
+ nfmpi_get_var1_int1_all, &
+ nfmpi_put_var1_int2, &
+ nfmpi_put_var1_int2_all, &
+ nfmpi_get_var1_int2, &
+ nfmpi_get_var1_int2_all, &
+ nfmpi_put_var1_int, &
+ nfmpi_put_var1_int_all, &
+ nfmpi_get_var1_int, &
+ nfmpi_get_var1_int_all, &
+ nfmpi_put_var1_real, &
+ nfmpi_put_var1_real_all, &
+ nfmpi_get_var1_real, &
+ nfmpi_get_var1_real_all, &
+ nfmpi_put_var1_double, &
+ nfmpi_put_var1_double_all, &
+ nfmpi_get_var1_double, &
+ nfmpi_get_var1_double_all, &
+ nfmpi_put_var1_int8, &
+ nfmpi_put_var1_int8_all, &
+ nfmpi_get_var1_int8, &
+ nfmpi_get_var1_int8_all
+
+!
+! variable array put/get subroutines:
+!
+ public :: &
+ nfmpi_put_vara_text, &
+ nfmpi_put_vara_text_all, &
+ nfmpi_get_vara_text, &
+ nfmpi_get_vara_text_all, &
+ nfmpi_put_vara_int1, &
+ nfmpi_put_vara_int1_all, &
+ nfmpi_get_vara_int1, &
+ nfmpi_get_vara_int1_all, &
+ nfmpi_put_vara_int2, &
+ nfmpi_put_vara_int2_all, &
+ nfmpi_get_vara_int2, &
+ nfmpi_get_vara_int2_all, &
+ nfmpi_put_vara_int, &
+ nfmpi_put_vara_int_all, &
+ nfmpi_get_vara_int, &
+ nfmpi_get_vara_int_all, &
+ nfmpi_put_vara_real, &
+ nfmpi_put_vara_real_all, &
+ nfmpi_get_vara_real, &
+ nfmpi_get_vara_real_all, &
+ nfmpi_put_vara_double, &
+ nfmpi_put_vara_double_all, &
+ nfmpi_get_vara_double, &
+ nfmpi_get_vara_double_all, &
+ nfmpi_put_vara_int8, &
+ nfmpi_put_vara_int8_all, &
+ nfmpi_get_vara_int8, &
+ nfmpi_get_vara_int8_all
+
+!
+! strided variable put/get subroutines:
+!
+ public :: &
+ nfmpi_put_vars_text, &
+ nfmpi_put_vars_text_all, &
+ nfmpi_get_vars_text, &
+ nfmpi_get_vars_text_all, &
+ nfmpi_put_vars_int1, &
+ nfmpi_put_vars_int1_all, &
+ nfmpi_get_vars_int1, &
+ nfmpi_get_vars_int1_all, &
+ nfmpi_put_vars_int2, &
+ nfmpi_put_vars_int2_all, &
+ nfmpi_get_vars_int2, &
+ nfmpi_get_vars_int2_all, &
+ nfmpi_put_vars_int, &
+ nfmpi_put_vars_int_all, &
+ nfmpi_get_vars_int, &
+ nfmpi_get_vars_int_all, &
+ nfmpi_put_vars_real, &
+ nfmpi_put_vars_real_all, &
+ nfmpi_get_vars_real, &
+ nfmpi_get_vars_real_all, &
+ nfmpi_put_vars_double, &
+ nfmpi_put_vars_double_all, &
+ nfmpi_get_vars_double, &
+ nfmpi_get_vars_double_all, &
+ nfmpi_put_vars_int8, &
+ nfmpi_put_vars_int8_all, &
+ nfmpi_get_vars_int8, &
+ nfmpi_get_vars_int8_all
+
+!
+! mapped variable put/get subroutines:
+!
+ public :: &
+ nfmpi_put_varm_text, &
+ nfmpi_put_varm_text_all, &
+ nfmpi_get_varm_text, &
+ nfmpi_get_varm_text_all, &
+ nfmpi_put_varm_int1, &
+ nfmpi_put_varm_int1_all, &
+ nfmpi_get_varm_int1, &
+ nfmpi_get_varm_int1_all, &
+ nfmpi_put_varm_int2, &
+ nfmpi_put_varm_int2_all, &
+ nfmpi_get_varm_int2, &
+ nfmpi_get_varm_int2_all, &
+ nfmpi_put_varm_int , &
+ nfmpi_put_varm_int_all, &
+ nfmpi_get_varm_int , &
+ nfmpi_get_varm_int_all, &
+ nfmpi_put_varm_real, &
+ nfmpi_put_varm_real_all, &
+ nfmpi_get_varm_real, &
+ nfmpi_get_varm_real_all, &
+ nfmpi_put_varm_double, &
+ nfmpi_put_varm_double_all, &
+ nfmpi_get_varm_double, &
+ nfmpi_get_varm_double_all, &
+ nfmpi_put_varm_int8, &
+ nfmpi_put_varm_int8_all, &
+ nfmpi_get_varm_int8, &
+ nfmpi_get_varm_int8_all
+
+!
+! non-blocking variable array iput/iget subroutines:
+!
+
+!
+! entire variable iput/iget subroutines:
+!
+ public :: &
+ nfmpi_iput_var_text, &
+ nfmpi_iget_var_text, &
+ nfmpi_iput_var_int1, &
+ nfmpi_iget_var_int1, &
+ nfmpi_iput_var_int2, &
+ nfmpi_iget_var_int2, &
+ nfmpi_iput_var_int, &
+ nfmpi_iget_var_int, &
+ nfmpi_iput_var_real, &
+ nfmpi_iget_var_real, &
+ nfmpi_iput_var_double, &
+ nfmpi_iget_var_double, &
+ nfmpi_iput_var_int8, &
+ nfmpi_iget_var_int8
+
+!
+! single variable iput/iget subroutines:
+!
+ public :: &
+ nfmpi_iput_var1_text, &
+ nfmpi_iget_var1_text, &
+ nfmpi_iput_var1_int1, &
+ nfmpi_iget_var1_int1, &
+ nfmpi_iput_var1_int2, &
+ nfmpi_iget_var1_int2, &
+ nfmpi_iput_var1_int, &
+ nfmpi_iget_var1_int, &
+ nfmpi_iput_var1_real, &
+ nfmpi_iget_var1_real, &
+ nfmpi_iput_var1_double, &
+ nfmpi_iget_var1_double, &
+ nfmpi_iput_var1_int8, &
+ nfmpi_iget_var1_int8
+
+!
+! variable array iput/iget subroutines:
+!
+ public :: &
+ nfmpi_iput_vara_text, &
+ nfmpi_iget_vara_text, &
+ nfmpi_iput_vara_int1, &
+ nfmpi_iget_vara_int1, &
+ nfmpi_iput_vara_int2, &
+ nfmpi_iget_vara_int2, &
+ nfmpi_iput_vara_int, &
+ nfmpi_iget_vara_int, &
+ nfmpi_iput_vara_real, &
+ nfmpi_iget_vara_real, &
+ nfmpi_iput_vara_double, &
+ nfmpi_iget_vara_double, &
+ nfmpi_iput_vara_int8, &
+ nfmpi_iget_vara_int8
+
+!
+! strided variable iput/iget subroutines:
+!
+ public :: &
+ nfmpi_iput_vars_text, &
+ nfmpi_iget_vars_text, &
+ nfmpi_iput_vars_int1, &
+ nfmpi_iget_vars_int1, &
+ nfmpi_iput_vars_int2, &
+ nfmpi_iget_vars_int2, &
+ nfmpi_iput_vars_int, &
+ nfmpi_iget_vars_int, &
+ nfmpi_iput_vars_real, &
+ nfmpi_iget_vars_real, &
+ nfmpi_iput_vars_double, &
+ nfmpi_iget_vars_double, &
+ nfmpi_iput_vars_int8, &
+ nfmpi_iget_vars_int8
+
+!
+! mapped variable iput/iget subroutines:
+!
+ public :: &
+ nfmpi_iput_varm_text, &
+ nfmpi_iget_varm_text, &
+ nfmpi_iput_varm_int1, &
+ nfmpi_iget_varm_int1, &
+ nfmpi_iput_varm_int2, &
+ nfmpi_iget_varm_int2, &
+ nfmpi_iput_varm_int , &
+ nfmpi_iget_varm_int , &
+ nfmpi_iput_varm_real, &
+ nfmpi_iget_varm_real, &
+ nfmpi_iput_varm_double, &
+ nfmpi_iget_varm_double, &
+ nfmpi_iput_varm_int8, &
+ nfmpi_iget_varm_int8
+
+!
+! Begin buffered put non-blocking subroutines:
+!
+ public :: &
+ nfmpi_bput_var_text, &
+ nfmpi_bput_var_int1, &
+ nfmpi_bput_var_int2, &
+ nfmpi_bput_var_int, &
+ nfmpi_bput_var_real, &
+ nfmpi_bput_var_double, &
+ nfmpi_bput_var_int8, &
+ nfmpi_bput_var1_text, &
+ nfmpi_bput_var1_int1, &
+ nfmpi_bput_var1_int2, &
+ nfmpi_bput_var1_int, &
+ nfmpi_bput_var1_real, &
+ nfmpi_bput_var1_double, &
+ nfmpi_bput_var1_int8, &
+ nfmpi_bput_vara_text, &
+ nfmpi_bput_vara_int1, &
+ nfmpi_bput_vara_int2, &
+ nfmpi_bput_vara_int, &
+ nfmpi_bput_vara_real, &
+ nfmpi_bput_vara_double, &
+ nfmpi_bput_vara_int8, &
+ nfmpi_bput_vars_text, &
+ nfmpi_bput_vars_int1, &
+ nfmpi_bput_vars_int2, &
+ nfmpi_bput_vars_int, &
+ nfmpi_bput_vars_real, &
+ nfmpi_bput_vars_double, &
+ nfmpi_bput_vars_int8, &
+ nfmpi_bput_varm_text, &
+ nfmpi_bput_varm_int1, &
+ nfmpi_bput_varm_int2, &
+ nfmpi_bput_varm_int , &
+ nfmpi_bput_varm_real, &
+ nfmpi_bput_varm_double, &
+ nfmpi_bput_varm_int8, &
+ nfmpi_buffer_attach, &
+ nfmpi_buffer_detach, &
+ nfmpi_inq_buffer_usage, &
+ nfmpi_inq_buffer_size
+
+!
+! End buffered put non-blocking subroutines:
+!
+ public :: &
+ nfmpi_wait, &
+ nfmpi_wait_all, &
+ nfmpi_cancel, &
+ nfmpi_inq_put_size, &
+ nfmpi_inq_get_size, &
+ nfmpi_inq_header_size, &
+ nfmpi_inq_header_extent, &
+ nfmpi_inq_varoffset, &
+ nfmpi_inq_nreqs, &
+ nfmpi_inq_malloc_size, &
+ nfmpi_inq_malloc_max_size, &
+ nfmpi_inq_malloc_list, &
+ nfmpi_inq_files_opened, &
+ nfmpi_inq_recsize
+
+!
+! Begin of varn subroutines:
+!
+ public :: &
+ nfmpi_get_varn_text, &
+ nfmpi_get_varn_int1, &
+ nfmpi_get_varn_int2, &
+ nfmpi_get_varn_int, &
+ nfmpi_get_varn_real, &
+ nfmpi_get_varn_double, &
+ nfmpi_get_varn_int8, &
+ nfmpi_get_varn_text_all, &
+ nfmpi_get_varn_int1_all, &
+ nfmpi_get_varn_int2_all, &
+ nfmpi_get_varn_int_all, &
+ nfmpi_get_varn_real_all, &
+ nfmpi_get_varn_double_all, &
+ nfmpi_get_varn_int8_all, &
+ nfmpi_put_varn_text, &
+ nfmpi_put_varn_int1, &
+ nfmpi_put_varn_int2, &
+ nfmpi_put_varn_int, &
+ nfmpi_put_varn_real, &
+ nfmpi_put_varn_double, &
+ nfmpi_put_varn_int8, &
+ nfmpi_put_varn_text_all, &
+ nfmpi_put_varn_int1_all, &
+ nfmpi_put_varn_int2_all, &
+ nfmpi_put_varn_int_all, &
+ nfmpi_put_varn_real_all, &
+ nfmpi_put_varn_double_all, &
+ nfmpi_put_varn_int8_all, &
+ nfmpi_iget_varn_text, &
+ nfmpi_iget_varn_int1, &
+ nfmpi_iget_varn_int2, &
+ nfmpi_iget_varn_int, &
+ nfmpi_iget_varn_real, &
+ nfmpi_iget_varn_double, &
+ nfmpi_iget_varn_int8, &
+ nfmpi_iput_varn_text, &
+ nfmpi_iput_varn_int1, &
+ nfmpi_iput_varn_int2, &
+ nfmpi_iput_varn_int, &
+ nfmpi_iput_varn_real, &
+ nfmpi_iput_varn_double, &
+ nfmpi_iput_varn_int8, &
+ nfmpi_bput_varn_text, &
+ nfmpi_bput_varn_int1, &
+ nfmpi_bput_varn_int2, &
+ nfmpi_bput_varn_int, &
+ nfmpi_bput_varn_real, &
+ nfmpi_bput_varn_double, &
+ nfmpi_bput_varn_int8
+
+!
+! End of varn subroutines:
+!
+
+! PnetCDF flexible APIs
+ public :: &
+ nfmpi_put_var, &
+ nfmpi_put_var1, &
+ nfmpi_put_vara, &
+ nfmpi_put_vars, &
+ nfmpi_put_varm, &
+ nfmpi_get_var, &
+ nfmpi_get_var1, &
+ nfmpi_get_vara, &
+ nfmpi_get_vars, &
+ nfmpi_get_varm
+
+! nfmpi_put_var_all
+! collective put an entire variable does not make sense
+!
+
+ public :: &
+ nfmpi_put_var1_all, &
+ nfmpi_put_vara_all, &
+ nfmpi_put_vars_all, &
+ nfmpi_put_varm_all, &
+ nfmpi_get_var_all, &
+ nfmpi_get_var1_all, &
+ nfmpi_get_vara_all, &
+ nfmpi_get_vars_all, &
+ nfmpi_get_varm_all, &
+ nfmpi_iput_var, &
+ nfmpi_iput_var1, &
+ nfmpi_iput_vara, &
+ nfmpi_iput_vars, &
+ nfmpi_iput_varm, &
+ nfmpi_iget_var, &
+ nfmpi_iget_var1, &
+ nfmpi_iget_vara, &
+ nfmpi_iget_vars, &
+ nfmpi_iget_varm, &
+ nfmpi_bput_var, &
+ nfmpi_bput_var1, &
+ nfmpi_bput_vara, &
+ nfmpi_bput_vars, &
+ nfmpi_bput_varm, &
+ nfmpi_get_varn, &
+ nfmpi_put_varn, &
+ nfmpi_get_varn_all, &
+ nfmpi_put_varn_all, &
+ nfmpi_iget_varn, &
+ nfmpi_iput_varn, &
+ nfmpi_bput_varn
+
+!
+! Begin of vard subroutines:
+!
+ public :: &
+ nfmpi_get_vard, &
+ nfmpi_get_vard_all, &
+ nfmpi_put_vard, &
+ nfmpi_put_vard_all
+
+!
+! End of vard subroutines:
+!
+
diff --git a/src/utils/Makefile.in b/src/utils/Makefile.in
new file mode 100644
index 0000000..76a1474
--- /dev/null
+++ b/src/utils/Makefile.in
@@ -0,0 +1,34 @@
+#
+# Copyright (C) 2003, Northwestern University and Argonne National Laboratory
+# See COPYRIGHT notice in top-level directory.
+#
+# $Id: Makefile.in 2285 2015-12-30 20:48:25Z wkliao $
+#
+# @configure_input@
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+include ../../macros.make
+
+SUBDIRS = ncmpigen ncmpidump ncmpidiff ncmpivalid pnetcdf_version ncoffsets
+
+PACKING_LIST = Makefile.in
+
+PACKING_SUBDIRS = $(SUBDIRS)
+
+all: $(SUBDIRS)
+$(SUBDIRS):
+ $(MAKE) $(MFLAGS) -C $@
+
+INSTALLDIRS = $(SUBDIRS:%=install-%)
+install: $(INSTALLDIRS)
+$(INSTALLDIRS):
+ $(MAKE) $(MFLAGS) -C $(@:install-%=%) install
+
+UNINSTALLDIRS = $(SUBDIRS:%=uninstall-%)
+uninstall: $(UNINSTALLDIRS)
+$(UNINSTALLDIRS):
+ $(MAKE) $(MFLAGS) -C $(@:uninstall-%=%) uninstall
+
+include $(srcdir)/../../rules.make
diff --git a/src/utils/ncmpidiff/Makefile.in b/src/utils/ncmpidiff/Makefile.in
new file mode 100644
index 0000000..c40e95e
--- /dev/null
+++ b/src/utils/ncmpidiff/Makefile.in
@@ -0,0 +1,63 @@
+#
+# Copyright (C) 2012, Northwestern University and Argonne National Laboratory
+# See COPYRIGHT notice in top-level directory.
+#
+# $Id: Makefile.in 2103 2015-09-18 23:34:03Z wkliao $
+#
+# @configure_input@
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+include ../../../macros.make
+
+# For VPATH build:
+# Add ../../lib into search path because ../../lib/pnetcdf.h is created in
+# the build directory at configure time and is included by C files here.
+INCLUDES = -I../../lib
+
+LDFLAGS += -L../../lib
+LIBS := -lpnetcdf $(LIBS) @LCOV_LIB@
+
+C_SOURCES = ncmpidiff.c
+HEADERS =
+
+OBJS = $(C_SOURCES:.c=.o)
+
+PROGRAM = ncmpidiff
+MANUAL = ncmpidiff.1
+
+PACKING_LIST = $(C_SOURCES) $(HEADERS) $(MANUAL) \
+ depend Makefile.in
+
+GARBAGE = $(PROGRAM)
+
+all: $(PROGRAM)
+
+$(PROGRAM): $(LIBRARY) $(OBJS)
+ $(LINK.c) $(OBJS) $(LDFLAGS) $(LIBS)
+
+install: $(PROGRAM) $(MANUAL)
+ $(INSTALL) -d -m 755 $(MANDIR)/man1
+ $(INSTALL_DATA) $(srcdir)/$(MANUAL) $(MANDIR)/man1/$(MANUAL)
+
+ $(INSTALL) -d $(BINDIR)
+ $(INSTALL) -m 755 $(PROGRAM) $(BINDIR)/$(PROGRAM)
+
+uninstall:
+ $(RM) -f $(BINDIR)/$(PROGRAM)
+ $(RM) -f $(MANDIR)/man1/$(MANUAL)
+
+$(PROGRAM)_oc : $(C_SOURCES)
+ #setopt primary_language C
+ #load -C $(CPPFLAGS) $(C_SOURCES)
+ #load -C $(LIBS)
+ #setopt program_name $(PROGRAM)
+
+TAGS: FORCE
+ etags `echo $(PACKING_LIST) | fmt -1 | $(EGREP) '\.c|\.h'
+
+include $(srcdir)/../../../rules.make
+include $(srcdir)/depend
+
+.PHONY: $(LIBRARY)
diff --git a/src/utils/ncmpidiff/depend b/src/utils/ncmpidiff/depend
new file mode 100644
index 0000000..f36f816
--- /dev/null
+++ b/src/utils/ncmpidiff/depend
@@ -0,0 +1 @@
+ncmpidiff.o: ncmpidiff.c ../../lib/pnetcdf.h
diff --git a/src/utils/ncmpidiff/ncmpidiff.1 b/src/utils/ncmpidiff/ncmpidiff.1
new file mode 100644
index 0000000..3a7b045
--- /dev/null
+++ b/src/utils/ncmpidiff/ncmpidiff.1
@@ -0,0 +1,41 @@
+.\" $Header$
+.nr yr \n(yr+1900
+.af mo 01
+.af dy 01
+.TH NCMPIDIFF 1 2013-11-17 "Printed: \n(yr-\n(mo-\n(dy" "UTILITIES"
+.SH NAME
+ncmpidiff \- compares two netCDF files in parallel
+.SH SYNOPSIS
+.ft B
+.HP
+mpiexec -n 4 ncmpidiff
+.nh
+\%[-b]
+\%[-h]
+\%[-v \fIvar1,...\fP]
+\%\fIfile1 file2\fP
+.hy
+.ft
+.SH DESCRIPTION
+\fBncmpidiff\fP compares the contents of the two files and reports
+the difference to the standard output.
+
+If no argument is given besides the two file names, the entire
+files are compared.
+.SH OPTIONS
+.IP "\fB-b\fP"
+Verbose mode
+.IP "\fB-h\fP"
+Compare file header only
+.IP "\fB-v\fP \fIvar1,...,varn\fP"
+Compare only the given list of variables
+
+.SH "SEE ALSO"
+.LP
+.BR ncmpidump (1),
+.BR pnetcdf (3)
+.SH DATE
+$Date: 2013-11-17 00:21:28 -0600 (Sun, 17 Nov 2013) $
+.LP
+
+
diff --git a/src/utils/ncmpidiff/ncmpidiff.c b/src/utils/ncmpidiff/ncmpidiff.c
new file mode 100644
index 0000000..0ae97f3
--- /dev/null
+++ b/src/utils/ncmpidiff/ncmpidiff.c
@@ -0,0 +1,782 @@
+/*
+ * Copyright (C) 2010, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ */
+/* $Id: ncmpidiff.c 2150 2015-10-10 05:52:57Z wkliao $ */
+
+/* wkliao: This diff utility compares header and variables of two files
+ * regardless the define order of the variables and attributes.
+ *
+ * It can also compare a subset of the variables, for example
+ * mpiexec -n 8 ncmpidiff -v var1,var2 file1.nc file2.nc
+ *
+ * or compare the header only, for example,
+ * mpiexec -n 8 ncmpidiff -h file1.nc file2.nc
+ *
+ * or compare header + a subset of variables, for example,
+ * mpiexec -n 8 ncmpidiff -h -v var1,var2 file1.nc file2.nc
+ */
+
+#if HAVE_CONFIG_H
+# include <ncconfig.h>
+#endif
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <mpi.h>
+#include <pnetcdf.h>
+
+#ifndef ubyte
+#define ubyte unsigned char
+#endif
+#ifndef ushort
+#define ushort unsigned short
+#endif
+#ifndef uint
+#define uint unsigned int
+#endif
+#ifndef int64
+#define int64 long long
+#endif
+#ifndef uint64
+#define uint64 unsigned long long
+#endif
+
+#define OOM_ERROR { \
+ fprintf(stderr, "Error: malloc() out of memory at line %d\n",__LINE__); \
+ exit(1); \
+}
+
+#define HANDLE_ERROR { \
+ if (err != NC_NOERR) { \
+ fprintf(stderr, "Error at line %d (%s)\n", __LINE__, \
+ ncmpi_strerror(err)); \
+ MPI_Abort(MPI_COMM_WORLD, -1); \
+ exit(-1); \
+ } \
+}
+
+#define CHECK_GLOBAL_ATT_DIFF(type, func, nctype) { \
+ int pos, len = attlen1 * sizeof(type); \
+ type *b1 = (type *)malloc(len); \
+ if (!b1) OOM_ERROR \
+ type *b2 = (type *)malloc(len); \
+ if (!b2) OOM_ERROR \
+ err = func(ncid1, NC_GLOBAL, name1, b1); \
+ HANDLE_ERROR \
+ err = func(ncid2, NC_GLOBAL, name1, b2); \
+ HANDLE_ERROR \
+ if ((pos = memcmp(b1, b2, len)) != 0) { \
+ printf("DIFF: global attribute \"%s\" of type \"%s\" (%d)\n", \
+ name1,#nctype,pos); \
+ numHeadDIFF++; \
+ } \
+ else if (verbose) \
+ printf("\tSAME: attribute contents\n"); \
+ free(b1); \
+ free(b2); \
+ break; \
+}
+
+#define CHECK_VAR_ATT_DIFF(type, func, nctype) { \
+ int pos, len = attlen1 * sizeof(type); \
+ type *b1 = (type *)malloc(len); \
+ if (!b1) OOM_ERROR \
+ type *b2 = (type *)malloc(len); \
+ if (!b2) OOM_ERROR \
+ err = func(ncid1, i, attrname, b1); \
+ HANDLE_ERROR \
+ err = func(ncid2, varid, attrname, b2); \
+ HANDLE_ERROR \
+ if ((pos = memcmp(b1, b2, len)) != 0) { \
+ printf("DIFF: variable \"%s\" attribute \"%s\" of type \"%s\" (%d)\n",\
+ name1,attrname,#nctype,pos); \
+ numHeadDIFF++; \
+ } \
+ else if (verbose) \
+ printf("\t\tSAME: attribute contents\n"); \
+ free(b1); \
+ free(b2); \
+ break; \
+}
+
+#define CHECK_VAR_DIFF(type, func, nctype) { \
+ int pos, isDiff, len = varsize * sizeof(type); \
+ type *b1 = (type *)malloc(len); \
+ if (!b1) OOM_ERROR \
+ type *b2 = (type *)malloc(len); \
+ if (!b2) OOM_ERROR \
+ err = func(ncid1, varid1, start, shape, b1); \
+ HANDLE_ERROR \
+ err = func(ncid2, varid2, start, shape, b2); \
+ HANDLE_ERROR \
+ if ((pos = memcmp(b1, b2, len)) != 0) { \
+ printf("DIFF: variable \"%s\" of type \"%s\" (%d)\n", \
+ name1,#nctype,pos); \
+ numVarDIFF++; \
+ } \
+ MPI_Allreduce(&pos, &isDiff, 1, MPI_INT, MPI_MAX, comm); \
+ if (isDiff == 0 && !rank && verbose) \
+ printf("\tSAME: variable \"%s\" contents\n",name1); \
+ free(b1); \
+ free(b2); \
+ break; \
+}
+
+char *progname;
+
+#ifndef EXIT_FAILURE
+#ifndef vms
+#define EXIT_SUCCESS 0
+#define EXIT_FAILURE 1
+#else
+#define EXIT_SUCCESS 1
+#define EXIT_FAILURE 0
+#endif
+#endif
+
+/*
+ * * Print error message to stderr and exit
+ */
+#if 0
+static void
+error(const char *fmt, ...)
+{
+ va_list args ;
+
+ (void) fprintf(stderr,"%s: ", progname);
+ va_start(args, fmt) ;
+ (void) vfprintf(stderr,fmt,args) ;
+ va_end(args) ;
+
+ (void) fprintf(stderr, "\n") ;
+ (void) fflush(stderr); /* to ensure log files are current */
+ exit(EXIT_FAILURE);
+}
+#endif
+
+/*----< usage() >-------------------------------------------------------------*/
+static void
+usage(int rank, char *progname)
+{
+#define USAGE "\
+ Compare the contents of two netCDF files.\n\n\
+ [-b] Verbose output\n\
+ [-h] Compare header information only, no data\n\
+ [-q] quiet mode (return 0/1 for same/different)\n\
+ [-v var1[,...]] Compare variable(s) <var1>,... only\n\
+ file1 file2 File names of two input netCDF files to be compared\n"
+
+ if (rank == 0) {
+ printf(" %s [-h] [-v ...] [-b] file1 file2\n%s", progname, USAGE);
+ printf(" PnetCDF library version %s\n", ncmpi_inq_libvers());
+ }
+ MPI_Finalize();
+ exit(1);
+}
+
+struct vspec {
+ int nvars;
+ char **names; /* [nvars] */
+};
+
+/*----< get_var_names() >-----------------------------------------------------*/
+static void
+get_var_names(char *optarg, struct vspec* vspecp)
+{
+ char *cp=optarg, **cpp;
+ int nvars = 1;
+
+ /* compute number of variable names in comma-delimited list */
+ vspecp->nvars = 1;
+ while (*cp++)
+ if (*cp == ',')
+ nvars++;
+
+ vspecp->names = (char **) malloc(nvars * sizeof(char*));
+ if (!vspecp->names) OOM_ERROR
+
+ cpp = vspecp->names;
+ /* copy variable names into list */
+ for (cp = strtok(optarg, ",");
+ cp != NULL;
+ cp = strtok((char *) NULL, ",")) {
+
+ *cpp = (char *) malloc(strlen(cp) + 1);
+ if (!*cpp) OOM_ERROR
+ strcpy(*cpp, cp);
+ cpp++;
+ }
+ vspecp->nvars = nvars;
+}
+
+/*----< get_type() >----------------------------------------------------------*/
+static char*
+get_type(int type)
+{
+ switch (type) {
+ case NC_CHAR: return "char";
+ case NC_SHORT: return "short";
+ case NC_INT: return "int";
+ case NC_FLOAT: return "float";
+ case NC_DOUBLE: return "double";
+ case NC_UBYTE: return "unsigned char";
+ case NC_USHORT: return "unsigned short";
+ case NC_UINT: return "unsigned int";
+ case NC_INT64: return "long long";
+ case NC_UINT64: return "unsigned long long";
+ }
+ return "";
+}
+
+/*----< main() >--------------------------------------------------------------*/
+int main(int argc, char **argv)
+{
+ int i, j, c, err, rank, nprocs, verbose, quiet;
+ int ncid1, ndims1, nvars1, natts1, unlimdimid1, *dimids1;
+ int ncid2, ndims2, nvars2, natts2, unlimdimid2, *dimids2;
+ char *name1, *name2;
+ MPI_Offset *shape, varsize, *start;
+ MPI_Offset attlen1, dimlen1, attlen2, dimlen2;
+ nc_type type1, type2;
+ MPI_Comm comm=MPI_COMM_WORLD;
+ int nvars, check_header, check_variable_list, check_entire_file;
+ long long numVarDIFF=0, numHeadDIFF=0, varDIFF, numDIFF;
+ struct vspec var_list;
+ extern char *optarg;
+ extern int optind;
+ MPI_Info info;
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_size(comm, &nprocs);
+ MPI_Comm_rank(comm, &rank);
+
+ progname = argv[0];
+ verbose = 0;
+ quiet = 0;
+ check_header = 0;
+ check_variable_list = 0;
+ check_entire_file = 0;
+ var_list.names = NULL;
+ var_list.nvars = 0;
+
+ while ((c = getopt(argc, argv, "bhqv:")) != -1)
+ switch(c) {
+ case 'h': /* compare header only */
+ check_header = 1;
+ break;
+ case 'v': /* variable names */
+ /* make list of names of variables specified */
+ get_var_names(optarg, &var_list);
+ check_variable_list = 1;
+ break;
+ case 'b':
+ verbose = 1;
+ break;
+ case 'q':
+ quiet = 1;
+ break;
+ case '?':
+ usage(rank, argv[0]);
+ break;
+ }
+
+ /* quiet overwrites verbose */
+ if (quiet) verbose = 0;
+
+ if (argc - optind != 2) usage(rank, argv[0]);
+
+ if (check_header == 0 && check_variable_list == 0) {
+ check_entire_file = 1;
+ check_header = 1;
+ }
+
+ dimids1 = (int*) malloc(NC_MAX_DIMS * sizeof(int));
+ if (!dimids1) OOM_ERROR
+ dimids2 = (int*) malloc(NC_MAX_DIMS * sizeof(int));
+ if (!dimids2) OOM_ERROR
+ name1 = (char*) malloc(NC_MAX_NAME);
+ if (!name1) OOM_ERROR
+ name2 = (char*) malloc(NC_MAX_NAME);
+ if (!name2) OOM_ERROR
+ shape = (MPI_Offset*) malloc(NC_MAX_VAR_DIMS * sizeof(MPI_Offset));
+ if (!shape) OOM_ERROR
+ start = (MPI_Offset*) malloc(NC_MAX_VAR_DIMS * sizeof(MPI_Offset));
+ if (!start) OOM_ERROR
+
+ /* Nov. 18, 2014 -- disable subfiling as it does not correctly handle the
+ * cases when nprocs < num_subfiles */
+ MPI_Info_create (&info);
+ MPI_Info_set (info, "pnetcdf_subfiling", "disable");
+
+ /* open files */
+ err = ncmpi_open(comm, argv[optind], NC_NOWRITE, info, &ncid1);
+ HANDLE_ERROR
+ err = ncmpi_open(comm, argv[optind+1], NC_NOWRITE, info, &ncid2);
+ HANDLE_ERROR
+
+ MPI_Info_free(&info);
+
+ /* check header */
+ if (check_header && rank == 0) { /* only root checks header */
+ int attnump;
+
+ err = ncmpi_inq(ncid1, &ndims1, &nvars1, &natts1, &unlimdimid1);
+ HANDLE_ERROR
+ err = ncmpi_inq(ncid2, &ndims2, &nvars2, &natts2, &unlimdimid2);
+ HANDLE_ERROR
+ if (ndims1 != ndims2) { /* check number of dimensions if equal */
+ if (!quiet) printf("DIFF: number of dimensions (%d) != (%d)\n",ndims1, ndims2);
+ numHeadDIFF++;
+ }
+ else if (verbose)
+ printf("SAME: number of dimensions (%d)\n",ndims1);
+ if (nvars1 != nvars2) { /* check number of variables if equal */
+ if (!quiet) printf("DIFF: number of variables (%d) != (%d)\n",nvars1, nvars2);
+ numHeadDIFF++;
+ }
+ else if (verbose)
+ printf("SAME: number of variables (%d)\n",nvars1);
+ if (natts1 != natts2) { /* check number of global attributes if equal */
+ if (!quiet) printf("DIFF: number of global attributes (%d) != (%d)\n",natts1, natts2);
+ numHeadDIFF++;
+ }
+ else if (verbose)
+ printf("SAME: number of global attributes (%d)\n",natts1);
+
+ /* Compare global attributes, assume CHAR attributes. */
+ for (i=0; i<natts1; i++) { /* check what's in file1 also in file2 */
+ err = ncmpi_inq_attname(ncid1, NC_GLOBAL, i, name1);
+ HANDLE_ERROR
+ /* find the attr with the same name from ncid2 */
+ err = ncmpi_inq_attid(ncid2, NC_GLOBAL, name1, &attnump);
+ if (err == NC_ENOTATT) {
+ if (!quiet) printf("DIFF: global attribute \"%s\" not found in file %s\n",
+ name1,argv[optind+1]);
+ numHeadDIFF++;
+ continue;
+ }
+
+ err = ncmpi_inq_att(ncid1, NC_GLOBAL, name1, &type1, &attlen1);
+ HANDLE_ERROR
+ err = ncmpi_inq_att(ncid2, NC_GLOBAL, name1, &type2, &attlen2);
+ HANDLE_ERROR
+ if (type1 != type2) {
+ if (!quiet) printf("DIFF: global attribute \"%s\" data type (%s) != (%s)\n",
+ name1,get_type(type1),get_type(type2));
+ numHeadDIFF++;
+ continue;
+ }
+ else if (verbose) {
+ printf("Global attribute \"%s\":\n",name1);
+ printf("\tSAME: data type (%s)\n",get_type(type1));
+ }
+
+ if (attlen1 != attlen2) {
+ if (!quiet) printf("DIFF: global attribute \"%s\" length (%lld) != (%lld)\n",
+ name1,(long long int)attlen1,(long long int)attlen2);
+ numHeadDIFF++;
+ continue;
+ }
+ else if (verbose)
+ printf("\tSAME: length (%lld)\n",(long long int)attlen1);
+
+ switch (type1) {
+ case NC_CHAR: CHECK_GLOBAL_ATT_DIFF(char, ncmpi_get_att_text, NC_CHAR)
+ case NC_SHORT: CHECK_GLOBAL_ATT_DIFF(short, ncmpi_get_att_short, NC_SHORT)
+ case NC_INT: CHECK_GLOBAL_ATT_DIFF(int, ncmpi_get_att_int, NC_INT)
+ case NC_FLOAT: CHECK_GLOBAL_ATT_DIFF(float, ncmpi_get_att_float, NC_FLOAT)
+ case NC_DOUBLE: CHECK_GLOBAL_ATT_DIFF(double, ncmpi_get_att_double, NC_DOUBLE)
+ case NC_UBYTE: CHECK_GLOBAL_ATT_DIFF(ubyte, ncmpi_get_att_uchar, NC_UBYTE)
+ case NC_USHORT: CHECK_GLOBAL_ATT_DIFF(ushort, ncmpi_get_att_ushort, NC_USHORT)
+ case NC_UINT: CHECK_GLOBAL_ATT_DIFF(uint, ncmpi_get_att_uint, NC_UINT)
+ case NC_INT64: CHECK_GLOBAL_ATT_DIFF(int64, ncmpi_get_att_longlong, NC_INT64)
+ case NC_UINT64: CHECK_GLOBAL_ATT_DIFF(uint64, ncmpi_get_att_ulonglong, NC_UINT64)
+ default: ; /* TODO: handle unexpected types */
+ }
+ }
+ for (i=0; i<natts2; i++) { /* check attributes in file2 but not in file1 */
+ err = ncmpi_inq_attname(ncid2, NC_GLOBAL, i, name2);
+ HANDLE_ERROR
+ /* find the attr with the same name from ncid1 */
+ if (ncmpi_inq_attid(ncid1, NC_GLOBAL, name2, &attnump) == NC_ENOTATT) {
+ numHeadDIFF++;
+ if (!quiet) printf("DIFF: global attribute \"%s\" not found in file %s\n",
+ name1,argv[optind]);
+ }
+ }
+
+ /* Compare dimension */
+ if (ndims1 && verbose)
+ printf("Dimension:\n");
+
+ for (i=0; i<ndims1; i++) { /* check dimensions in file1 also in file2 */
+ int dimid;
+ err = ncmpi_inq_dim(ncid1, i, name1, &dimlen1);
+ HANDLE_ERROR
+ /* find the dim with the same name from ncid2 */
+ err = ncmpi_inq_dimid(ncid2, name1, &dimid);
+ if (err == NC_EBADDIM) {
+ if (!quiet) printf("DIFF: dimension \"%s\" not found in file %s\n",
+ name1,argv[optind+1]);
+ numHeadDIFF++;
+ continue;
+ }
+
+ err = ncmpi_inq_dimlen(ncid2, dimid, &dimlen2);
+ HANDLE_ERROR
+ if (dimlen1 != dimlen2) {
+ /* cast to quiet warning on 32 bit platforms */
+ if (!quiet) printf("DIFF: dimension \"%s\" length (%lld) != (%lld)\n",
+ name1,(long long int)dimlen1,(long long int)dimlen2);
+ numHeadDIFF++;
+ }
+ else if (verbose)
+ printf("\tSAME: dimension \"%s\" length (%lld)\n",
+ name1,(long long int)dimlen1);
+ }
+ for (i=0; i<ndims2; i++) { /* check dimensions in file2 but not in file1 */
+ int dimid;
+ err = ncmpi_inq_dim(ncid2, i, name2, &dimlen2);
+ HANDLE_ERROR
+ /* find the dim with the same name from ncid1 */
+ if (ncmpi_inq_dimid(ncid2, name1, &dimid) == NC_EBADDIM) {
+ if (!quiet) printf("DIFF: dimension \"%s\" not found in file %s\n",
+ name1,argv[optind]);
+ numHeadDIFF++;
+ }
+ }
+
+ /* Compare variables' metadata */
+ for (i=0; i<nvars1; i++) {
+ int varid;
+ err = ncmpi_inq_var(ncid1, i, name1, &type1, &ndims1, dimids1, &natts1);
+ HANDLE_ERROR
+ /* find the variable with the same name from ncid2 */
+ err = ncmpi_inq_varid(ncid2, name1, &varid);
+ if (err == NC_ENOTVAR) {
+ if (!quiet) printf("DIFF: variable \"%s\" not found in file %s\n",
+ name1,argv[optind+1]);
+ numHeadDIFF++;
+ numVarDIFF++;
+ continue;
+ }
+ err = ncmpi_inq_var(ncid2, varid, name2, &type2, &ndims2, dimids2, &natts2);
+ HANDLE_ERROR
+
+ if (type1 != type2) {
+ if (!quiet) printf("DIFF: variable \"%s\" data type (%s) != (%s)\n",
+ name1,get_type(type1),get_type(type2));
+ numHeadDIFF++;
+ }
+ else if (verbose) {
+ printf("Variable \"%s\":\n",name1);
+ printf("\tSAME: data type (%s)\n",get_type(type1));
+ }
+
+ if (ndims1 != ndims2) {
+ if (!quiet) printf("DIFF: variable \"%s\" number of dimensions (%d) != (%d)\n",
+ name1,ndims1,ndims2);
+ numHeadDIFF++;
+ }
+ else {
+ if (verbose)
+ printf("\tSAME: number of dimensions (%d)\n",ndims1);
+
+ for (j=0; j<ndims1; j++) { /* check variable's dimensionality */
+ char dimname1[NC_MAX_NAME], dimname2[NC_MAX_NAME];
+ /* get dim name for each dim ID */
+ err = ncmpi_inq_dim(ncid1, dimids1[j], dimname1, &dimlen1);
+ HANDLE_ERROR
+ err = ncmpi_inq_dim(ncid1, dimids2[j], dimname2, &dimlen2);
+ HANDLE_ERROR
+ if (verbose)
+ printf("\tdimension %d:\n",j);
+ if (strcmp(dimname1, dimname2) != 0) {
+ if (!quiet) printf("DIFF: variable \"%s\" of type \"%s\" dimension %d's name (%s) != (%s)\n",
+ name1,get_type(type1),j,dimname1,dimname2);
+ numHeadDIFF++;
+ }
+ else if (verbose)
+ printf("\t\tSAME: name (%s)\n",dimname1);
+ if (dimlen1 != dimlen2) {
+ if (!quiet) printf("DIFF: variable \"%s\" of type \"%s\" dimension %d's length (%lld) != (%lld)\n",
+ name1,get_type(type1),j,(long long int)dimlen1,(long long int)dimlen2);
+ numHeadDIFF++;
+ }
+ else if (verbose)
+ printf("\t\tSAME: length (%lld)\n",(long long int)dimlen1);
+ }
+ }
+
+ if (natts1 != natts2) {
+ if (!quiet) printf("DIFF: variable \"%s\" number of attributes (%d) != (%d)\n",
+ name1,natts1,natts2);
+ numHeadDIFF++;
+ }
+ else if (verbose)
+ printf("\tSAME: number of attributes (%d)\n",natts1);
+
+ /* var attributes, assume CHAR attributes */
+ for (j=0; j<natts1; j++) {
+ char attrname[NC_MAX_NAME];
+ err = ncmpi_inq_attname(ncid1, i, j, attrname);
+ HANDLE_ERROR
+ err = ncmpi_inq_att(ncid1, i, attrname, &type1, &attlen1);
+ HANDLE_ERROR
+ /* find the variable attr with the same name from ncid2 */
+ err = ncmpi_inq_att(ncid2, varid, attrname, &type2, &attlen2);
+ if (err == NC_ENOTATT) {
+ if (!quiet) printf("DIFF: variable \"%s\" attribute \"%s\" not found in file %s\n",
+ name1,attrname,argv[optind+1]);
+ numHeadDIFF++;
+ continue;
+ }
+ if (verbose)
+ printf("\tattribute \"%s\":\n",attrname);
+
+ if (type1 != type2) {
+ if (!quiet) printf("DIFF: variable \"%s\" attribute \"%s\" data type (%s) != (%s)\n",
+ name1,attrname,get_type(type1),get_type(type2));
+ numHeadDIFF++;
+ continue; /* skip this attribute */
+ }
+ else if (verbose)
+ printf("\t\tSAME: data type (%s)\n",get_type(type1));
+ if (attlen1 != attlen2) {
+ if (!quiet) printf("DIFF: variable \"%s\" attribute \"%s\" length (%lld) != (%lld)\n",
+ name1,attrname,(long long int)attlen1,(long long int)attlen2);
+ numHeadDIFF++;
+ continue; /* skip this attribute */
+ }
+ else if (verbose)
+ printf("\t\tSAME: length (%lld)\n",(long long int)attlen1);
+
+ switch (type1) {
+ case NC_CHAR: CHECK_VAR_ATT_DIFF(char, ncmpi_get_att_text, NC_CHAR)
+ case NC_SHORT: CHECK_VAR_ATT_DIFF(short, ncmpi_get_att_short, NC_SHORT)
+ case NC_INT: CHECK_VAR_ATT_DIFF(int, ncmpi_get_att_int, NC_INT)
+ case NC_FLOAT: CHECK_VAR_ATT_DIFF(float, ncmpi_get_att_float, NC_FLOAT)
+ case NC_DOUBLE: CHECK_VAR_ATT_DIFF(double, ncmpi_get_att_double, NC_DOUBLE)
+ case NC_UBYTE: CHECK_VAR_ATT_DIFF(ubyte, ncmpi_get_att_uchar, NC_UBYTE)
+ case NC_USHORT: CHECK_VAR_ATT_DIFF(ushort, ncmpi_get_att_ushort, NC_USHORT)
+ case NC_UINT: CHECK_VAR_ATT_DIFF(uint, ncmpi_get_att_uint, NC_UINT)
+ case NC_INT64: CHECK_VAR_ATT_DIFF(int64, ncmpi_get_att_longlong, NC_INT64)
+ case NC_UINT64: CHECK_VAR_ATT_DIFF(uint64, ncmpi_get_att_ulonglong, NC_UINT64)
+ default: ; /* TODO: handle unexpected types */
+ }
+ }
+ for (j=0; j<natts2; j++) {
+ char attrname[NC_MAX_NAME];
+ err = ncmpi_inq_attname(ncid2, varid, j, attrname);
+ HANDLE_ERROR
+ /* find the variable attr with the same name from ncid1 */
+ err = ncmpi_inq_att(ncid1, i, attrname, &type1, &attlen1);
+ if (err == NC_ENOTATT) {
+ if (!quiet) printf("DIFF: variable \"%s\" attribute \"%s\" not found in file %s\n",
+ name1,attrname,argv[optind]);
+ numHeadDIFF++;
+ }
+ }
+ }
+ for (i=0; i<nvars2; i++) { /* check variables in file2 but not in file1 */
+ int varid;
+ err = ncmpi_inq_varname(ncid2, i, name2);
+ HANDLE_ERROR
+ /* find the variable with the same name from ncid1 */
+ err = ncmpi_inq_varid(ncid1, name2, &varid);
+ if (err == NC_ENOTVAR) {
+ if (!quiet) printf("DIFF: variable \"%s\" not found in file %s\n",
+ name2,argv[optind]);
+ numHeadDIFF++;
+ numVarDIFF++;
+ }
+ }
+ }
+
+ /* compare variable contents */
+ for (i=0; i<NC_MAX_VAR_DIMS; i++) start[i] = 0;
+
+ nvars = 0;
+ if (check_variable_list) nvars = var_list.nvars;
+
+ if (check_entire_file) { /* header has been checked */
+ ncmpi_inq_nvars(ncid1, &nvars);
+ var_list.nvars = nvars;
+ var_list.names = (char**) malloc(nvars * sizeof(char*));
+ if (!var_list.names) OOM_ERROR
+ /* get all the variable names from file1 */
+ for (i=0; i<nvars; i++) {
+ ncmpi_inq_varname(ncid1, i, name1);
+ var_list.names[i] = (char *) malloc(strlen(name1) + 1);
+ if (!var_list.names[i]) OOM_ERROR
+ strcpy(var_list.names[i], name1);
+ }
+ }
+ if (!rank && verbose) printf("number of variables to be compared = %d\n",nvars);
+
+ for (i=0; i<nvars; i++) { /* compare one variable at a time */
+ int varid1, varid2;
+
+ err = ncmpi_inq_varid(ncid1, var_list.names[i], &varid1);
+ if (err == NC_ENOTVAR) {
+ if (!check_header && !rank) {
+ if (!quiet) printf("WARN: variable \"%s\" not found in file %s\n",
+ var_list.names[i],argv[optind]);
+ numVarDIFF++;
+ }
+ continue;
+ }
+ err = ncmpi_inq_varid(ncid2, var_list.names[i], &varid2);
+ if (err == NC_ENOTVAR) {
+ if (!check_header && !rank) {
+ if (!quiet) printf("WARN: variable \"%s\" not found in file %s\n",
+ var_list.names[i],argv[optind+1]);
+ numVarDIFF++;
+ }
+ continue;
+ }
+ err = ncmpi_inq_var(ncid1, varid1, name1, &type1, &ndims1, dimids1, &natts1);
+ HANDLE_ERROR
+ err = ncmpi_inq_var(ncid2, varid2, name2, &type2, &ndims2, dimids2, &natts2);
+ HANDLE_ERROR
+
+ /* check data type */
+ if (type1 != type2) {
+ if (!rank) {
+ if (!check_header) /* if header has not been checked */
+ if (!quiet) printf("DIFF: variable \"%s\" data type (%s) != (%s)\n",
+ name1,get_type(type1),get_type(type2));
+ numHeadDIFF++;
+ numVarDIFF++;
+ }
+ continue; /* skip this variable */
+ }
+ else if (!check_header && !rank && verbose) {
+ printf("Variable \"%s\":\n",name1);
+ printf("\tSAME: data type (%s)\n",get_type(type1));
+ }
+
+ /* check number of dimensions */
+ if (ndims1 != ndims2) {
+ if (!rank) {
+ if (!check_header) /* if header has not been checked */
+ if (!quiet) printf("DIFF: variable \"%s\" number of dimensions (%d) != (%d)\n",
+ name1,ndims1,ndims2);
+ numHeadDIFF++;
+ numVarDIFF++;
+ }
+ continue; /* skip this variable */
+ }
+ else if (!check_header && !rank && verbose)
+ printf("\tSAME: number of dimensions (%d)\n",ndims1);
+
+ /* check dimension length only */
+ for (j=0; j<ndims1; j++) { /* check variable's dimensionality */
+ err = ncmpi_inq_dimlen(ncid1, dimids1[j], &dimlen1);
+ HANDLE_ERROR
+ err = ncmpi_inq_dimlen(ncid2, dimids2[j], &dimlen2);
+ HANDLE_ERROR
+ if (!check_header && !rank && verbose)
+ printf("\tDimension %d:\n",j);
+ if (dimlen1 != dimlen2) {
+ if (!rank) {
+ if (!check_header) /* if header has not been checked */
+ if (!quiet) printf("DIFF: variable \"%s\" of type \"%s\" dimension %d's length (%lld) != (%lld)\n",
+ name1,get_type(type1),j,(long long int)dimlen1,(long long int)dimlen2);
+ numHeadDIFF++;
+ numVarDIFF++;
+ }
+ break; /* skip this variable */
+ }
+ else if (!check_header && !rank && verbose)
+ printf("\t\tSAME: length (%lld)\n",(long long int)dimlen1);
+ shape[j] = dimlen1;
+ }
+ if (j != ndims1)
+ continue; /* skip this variable */
+
+ varsize = 1;
+ /* block partition the variable along the 1st dimension */
+ for (j=0; j<ndims1; j++) {
+ if (j == 0) {
+ shape[j] /= nprocs;
+ start[j] = shape[j] * rank;
+ }
+ varsize *= shape[j];
+ }
+
+ /* compare the variable contents */
+ switch (type1) {
+ case NC_CHAR: CHECK_VAR_DIFF(char, ncmpi_get_vara_text_all, NC_CHAR)
+ case NC_SHORT: CHECK_VAR_DIFF(short, ncmpi_get_vara_short_all, NC_SHORT)
+ case NC_INT: CHECK_VAR_DIFF(int, ncmpi_get_vara_int_all, NC_INT)
+ case NC_FLOAT: CHECK_VAR_DIFF(float, ncmpi_get_vara_float_all, NC_FLOAT)
+ case NC_DOUBLE: CHECK_VAR_DIFF(double, ncmpi_get_vara_double_all, NC_DOUBLE)
+ case NC_UBYTE: CHECK_VAR_DIFF(ubyte, ncmpi_get_vara_uchar, NC_UBYTE)
+ case NC_USHORT: CHECK_VAR_DIFF(ushort, ncmpi_get_vara_ushort, NC_USHORT)
+ case NC_UINT: CHECK_VAR_DIFF(uint, ncmpi_get_vara_uint, NC_UINT)
+ case NC_INT64: CHECK_VAR_DIFF(int64, ncmpi_get_vara_longlong, NC_INT64)
+ case NC_UINT64: CHECK_VAR_DIFF(uint64, ncmpi_get_vara_ulonglong, NC_UINT64)
+ default: ; /* TODO: handle unexpected types */
+ }
+ }
+
+ /* close files */
+ err = ncmpi_close(ncid1);
+ HANDLE_ERROR
+ err = ncmpi_close(ncid2);
+ HANDLE_ERROR
+
+ /* summary of the difference */
+ MPI_Reduce(&numVarDIFF, &varDIFF, 1, MPI_LONG_LONG_INT, MPI_SUM, 0, comm);
+ if (!quiet && rank == 0) {
+ if (check_header) {
+ if (numHeadDIFF == 0)
+ printf("Headers of two files are the same\n");
+ else
+ printf("Number of differences in header %lld\n",numHeadDIFF);
+ }
+ if (check_variable_list) {
+ if (varDIFF == 0)
+ printf("Compared variable(s) are the same\n");
+ else
+ printf("Compared variables(s) has %lld differences\n",varDIFF);
+ }
+ if (check_entire_file) {
+ if (varDIFF == 0)
+ printf("All variables of two files are the same\n");
+ else
+ printf("Number of differences in variables %lld\n",varDIFF);
+ }
+ }
+
+ /* free up the memory previously allocated */
+ if (var_list.nvars) {
+ for (i=0; i<var_list.nvars; i++)
+ free(var_list.names[i]);
+ free(var_list.names);
+ }
+ free(dimids1);
+ free(dimids2);
+ free(name1);
+ free(name2);
+ free(shape);
+ free(start);
+
+ if (rank == 0) numDIFF = varDIFF + numHeadDIFF;
+ MPI_Bcast(&numDIFF, 1, MPI_LONG_LONG_INT, 0, comm);
+
+ MPI_Finalize();
+#ifdef vms
+ if (quiet) exit((numDIFF == 0) ? 0 : 1);
+ else exit(EXIT_SUCCESS);
+#else
+ if (quiet) return ((numDIFF == 0) ? 0 : 1);
+ else return EXIT_SUCCESS;
+#endif
+}
diff --git a/src/utils/ncmpidump/Makefile.in b/src/utils/ncmpidump/Makefile.in
new file mode 100644
index 0000000..34193ce
--- /dev/null
+++ b/src/utils/ncmpidump/Makefile.in
@@ -0,0 +1,74 @@
+#
+# Copyright (C) 2012, Northwestern University and Argonne National Laboratory
+# See COPYRIGHT notice in top-level directory.
+#
+# $Id: Makefile.in 2103 2015-09-18 23:34:03Z wkliao $
+#
+# @configure_input@
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+include ../../../macros.make
+
+NCGEN = ../ncmpigen/ncmpigen
+
+# For VPATH build:
+# Add ../../lib into search path because ../../lib/pnetcdf.h is created in
+# the build directory at configure time and is included by C files here.
+INCLUDES = -I../../lib
+
+LDFLAGS += -L../../lib
+LIBS := -lpnetcdf $(LIBS) @LCOV_LIB@
+
+C_SOURCES = ncmpidump.c vardata.c dumplib.c
+HEADERS = ncmpidump.h vardata.h dumplib.h
+
+OBJS = $(C_SOURCES:.c=.o)
+
+PROGRAM = ncmpidump
+MANUAL = ncmpidump.1
+
+PACKING_LIST = $(C_SOURCES) $(HEADERS) $(MANUAL) \
+ depend Makefile.in \
+ test0.cdl
+
+GARBAGE = $(PROGRAM) test0.nc test1.nc test1.cdl test2.cdl
+
+all: $(PROGRAM)
+
+$(PROGRAM): $(LIBRARY) $(OBJS)
+ $(LINK.c) $(OBJS) $(LDFLAGS) $(LIBS)
+
+test: $(PROGRAM) FORCE
+ $(NCGEN) -b $(srcdir)/test0.cdl -o `pwd`/test0.nc
+ ./$(PROGRAM) -n test1 test0.nc > test1.cdl
+ $(NCGEN) -b `pwd`/test1.cdl -o `pwd`/test1.nc
+ ./$(PROGRAM) test1.nc > test2.cdl
+ @cmp test1.cdl test2.cdl && \
+ echo "*** $(PROGRAM) test successful ***"
+
+install: $(PROGRAM) $(MANUAL)
+ $(INSTALL) -d -m 755 $(MANDIR)/man1
+ $(INSTALL_DATA) $(srcdir)/$(MANUAL) $(MANDIR)/man1/$(MANUAL)
+
+ $(INSTALL) -d $(BINDIR)
+ $(INSTALL) -m 755 $(PROGRAM) $(BINDIR)/$(PROGRAM)
+
+uninstall:
+ $(RM) -f $(BINDIR)/$(PROGRAM)
+ $(RM) -f $(MANDIR)/man1/$(MANUAL)
+
+$(PROGRAM)_oc : $(C_SOURCES)
+ #setopt primary_language C
+ #load -C $(CPPFLAGS) $(C_SOURCES)
+ #load -C $(LIBS)
+ #setopt program_name $(PROGRAM)
+
+TAGS: FORCE
+ etags `echo $(PACKING_LIST) | fmt -1 | $(EGREP) '\.c|\.h'
+
+include $(srcdir)/../../../rules.make
+include $(srcdir)/depend
+
+.PHONY: $(LIBRARY)
diff --git a/src/utils/ncmpidump/depend b/src/utils/ncmpidump/depend
new file mode 100644
index 0000000..de556d1
--- /dev/null
+++ b/src/utils/ncmpidump/depend
@@ -0,0 +1,3 @@
+dumplib.o: dumplib.c dumplib.h ../../lib/pnetcdf.h
+ncmpidump.o: ncmpidump.c dumplib.h ncmpidump.h vardata.h ../../lib/pnetcdf.h
+vardata.o: vardata.c dumplib.h ncmpidump.h vardata.h ../../lib/pnetcdf.h
diff --git a/src/utils/ncmpidump/dumplib.c b/src/utils/ncmpidump/dumplib.c
new file mode 100644
index 0000000..d772d52
--- /dev/null
+++ b/src/utils/ncmpidump/dumplib.c
@@ -0,0 +1,225 @@
+/*********************************************************************
+ * Copyright 1993, University Corporation for Atmospheric Research
+ * See netcdf/README file for copying and redistribution conditions.
+ * $Header$
+ *********************************************************************/
+/* $Id: dumplib.c 1123 2013-01-26 17:35:03Z wkliao $ */
+
+/*
+ * We potentially include <stdarg.h> before <stdio.h> in order to obtain a
+ * definition for va_list from the GNU C compiler.
+ */
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "pnetcdf.h"
+#include "dumplib.h"
+
+#define ncmpi_advise(x, y, z)
+
+static char* has_c_format_att(int ncid, int varid);
+static vnode* newvnode(void);
+
+int float_precision_specified = 0; /* -p option specified float precision */
+int double_precision_specified = 0; /* -p option specified double precision */
+char float_var_fmt[] = "%.NNg";
+char double_var_fmt[] = "%.NNg";
+char float_att_fmt[] = "%#.NNgf";
+char double_att_fmt[] = "%#.NNg";
+
+/*
+ * Print error message to stderr and exit
+ */
+void
+error(const char *fmt, ...)
+{
+ va_list args ;
+
+ (void) fprintf(stderr,"%s: ", progname);
+ va_start(args, fmt) ;
+ (void) vfprintf(stderr,fmt,args) ;
+ va_end(args) ;
+
+ (void) fprintf(stderr, "\n") ;
+ (void) fflush(stderr); /* to ensure log files are current */
+ exit(EXIT_FAILURE);
+}
+
+#define LINEPIND " " /* indent of continued lines */
+
+static int linep;
+static int max_line_len;
+
+void
+set_indent(int in)
+{
+ linep = in;
+}
+
+
+void
+set_max_len(int len)
+{
+ max_line_len = len-2;
+}
+
+
+void
+lput(const char *cp)
+{
+ size_t nn = strlen(cp);
+
+ if (nn+linep > max_line_len && nn > 2) {
+ (void) fputs("\n", stdout);
+ (void) fputs(LINEPIND, stdout);
+ linep = (int)strlen(LINEPIND);
+ }
+ (void) fputs(cp,stdout);
+ linep += nn;
+}
+
+/* In case different formats specified with -d option, set them here. */
+void
+set_formats(int float_digits, int double_digits)
+{
+ (void) sprintf(float_var_fmt, "%%.%dg", float_digits);
+ (void) sprintf(double_var_fmt, "%%.%dg", double_digits);
+ (void) sprintf(float_att_fmt, "%%#.%dgf", float_digits);
+ (void) sprintf(double_att_fmt, "%%#.%dg", double_digits);
+}
+
+
+static char *
+has_c_format_att(
+ int ncid, /* netcdf id */
+ int varid /* variable id */
+ )
+{
+ nc_type cfmt_type;
+ MPI_Offset cfmt_len;
+#define C_FMT_NAME "C_format" /* name of C format attribute */
+#define MAX_CFMT_LEN 100 /* max length of C format attribute */
+ static char cfmt[MAX_CFMT_LEN];
+
+ /* we expect ncmpi_inq_att to fail if there is no "C_format" attribute */
+ int ncmpi_stat = ncmpi_inq_att(ncid, varid, "C_format", &cfmt_type, &cfmt_len);
+
+ switch(ncmpi_stat) {
+ case NC_NOERR:
+ if (cfmt_type == NC_CHAR && cfmt_len != 0 && cfmt_len < MAX_CFMT_LEN) {
+ ncmpi_stat = ncmpi_get_att_text(ncid, varid, "C_format", cfmt);
+ if(ncmpi_stat != NC_NOERR)
+ ncmpi_advise("Getting 'C_format' attribute", ncmpi_stat, "");
+ return &cfmt[0];
+ }
+ break;
+ case NC_ENOTATT:
+ break;
+ default:
+ ncmpi_advise("Inquiring about 'C_format' attribute", ncmpi_stat, "");
+ break;
+ }
+ return 0;
+}
+
+
+/*
+ * Determine print format to use for each value for this variable. Use value
+ * of attribute C_format if it exists, otherwise a sensible default.
+ */
+const char *
+get_fmt(
+ int ncid, /* netcdf id */
+ int varid, /* variable id */
+ nc_type type /* netCDF data type */
+ )
+{
+ char *c_format_att;
+
+ /* float or double precision specified with -p option overrides any
+ C_format attribute value, so check for that first. */
+
+ if (float_precision_specified && type == NC_FLOAT)
+ return float_var_fmt;
+
+ if (double_precision_specified && type == NC_DOUBLE)
+ return double_var_fmt;
+
+ /* If C_format attribute exists, return it */
+ c_format_att = has_c_format_att(ncid, varid);
+ if (c_format_att)
+ return c_format_att;
+
+ /* Otherwise return sensible default. */
+ switch (type) {
+ case NC_BYTE: return "%hhd";
+ case NC_CHAR: return "%s";
+ case NC_SHORT: return "%hd";
+ case NC_INT: return "%d";
+ case NC_FLOAT: return float_var_fmt;
+ case NC_DOUBLE: return double_var_fmt;
+ case NC_UBYTE: return "%hhu";
+ case NC_USHORT: return "%hu";
+ case NC_UINT: return "%u";
+ case NC_INT64: return "%lld";
+ case NC_UINT64: return "%llu";
+ default:
+ error("pr_vals: bad type");
+ }
+
+ return 0;
+}
+
+
+static vnode*
+newvnode(void)
+{
+ vnode *newvp = (vnode*) malloc(sizeof(vnode));
+
+ if (!newvp) {
+ error("out of memory!");
+ }
+ return newvp;
+}
+
+
+/*
+ * Get a new, empty variable list.
+ */
+vnode*
+newvlist(void)
+{
+ vnode *vp = newvnode();
+
+ vp -> next = 0;
+ vp -> id = -1; /* bad id */
+
+ return vp;
+}
+
+
+void
+varadd(vnode* vlist, int varid)
+{
+ vnode *newvp = newvnode();
+
+ newvp -> next = vlist -> next;
+ newvp -> id = varid;
+ vlist -> next = newvp;
+}
+
+
+int
+varmember(const vnode* vlist, int varid)
+{
+ vnode *vp = vlist -> next;
+
+ for (; vp ; vp = vp->next)
+ if (vp->id == varid)
+ return 1;
+ return 0;
+}
+
+
diff --git a/src/utils/ncmpidump/dumplib.h b/src/utils/ncmpidump/dumplib.h
new file mode 100644
index 0000000..3654c59
--- /dev/null
+++ b/src/utils/ncmpidump/dumplib.h
@@ -0,0 +1,73 @@
+/*********************************************************************
+ * Copyright 1993, University Corporation for Atmospheric Research
+ * See netcdf/COPYRIGHT file for copying and redistribution conditions.
+ * $Header$
+ *********************************************************************/
+/* $Id: dumplib.h 1468 2013-10-26 16:53:18Z wkliao $ */
+
+extern char *progname; /* for error messages */
+
+#define NO_NETCDF_2 /* assert we aren't using any netcdf-2 stuff */
+
+#ifndef EXIT_FAILURE
+#ifndef vms
+#define EXIT_SUCCESS 0
+#define EXIT_FAILURE 1
+#else
+#define EXIT_SUCCESS 1
+#define EXIT_FAILURE 0
+#endif
+#endif
+
+#define FLT_DIGITS 7 /* default sig. digits for float data */
+#define DBL_DIGITS 15 /* default sig. digits for double data */
+
+extern int float_precision_specified; /* -p option specified float precision */
+extern int double_precision_specified; /* -p option specified double precision */
+extern char float_var_fmt[];
+extern char double_var_fmt[];
+extern char float_att_fmt[];
+extern char double_att_fmt[];
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Print error message to stderr and exit */
+extern void error ( const char *fmt, ... );
+
+/* set position in line before lput() calls */
+extern void set_indent ( int indent );
+
+/* set maximum line length */
+extern void set_max_len ( int len );
+
+/* splits lines to keep them short */
+extern void lput ( const char *string );
+
+/* In case different formats specified with -d option, set them here. */
+extern void set_formats ( int flt_digs, int dbl_digs );
+
+/* Determine print format to use for each value for this variable. */
+const char * get_fmt ( int ncid, int varid, nc_type type );
+
+/* structure for list of variables specified with -v option */
+struct vnode
+{
+ struct vnode* next;
+ int id;
+};
+typedef struct vnode vnode;
+
+/* Get new variable list */
+extern vnode* newvlist ( void );
+
+/* Add a variable id to variable list */
+extern void varadd ( vnode* vlist, int varid );
+
+/* Test if a variable id is in variable list */
+extern int varmember ( const vnode* vlist, int varid );
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/src/utils/ncmpidump/ncmpidump.1 b/src/utils/ncmpidump/ncmpidump.1
new file mode 100644
index 0000000..dfa5c74
--- /dev/null
+++ b/src/utils/ncmpidump/ncmpidump.1
@@ -0,0 +1,200 @@
+.\" $Header$
+.nr yr \n(yr+1900
+.af mo 01
+.af dy 01
+.TH NCMPIDUMP 1 "2013-11-17" "Printed: \n(yr-\n(mo-\n(dy" "UTILITIES"
+.SH NAME
+ncmpidump \- Convert netCDF files to ASCII form (CDL)
+.SH SYNOPSIS
+.ft B
+.HP
+ncmpidump
+.nh
+\%[-ch]
+\%[-v \fIvar1,...\fP]
+\%[-b \fIlang\fP]
+\%[-f \fIlang\fP]
+\%[-l \fIlen\fP]
+\%[-n \fIname\fP]
+\%[-p \fIf_digits[,d_digits]\fP]
+\%\fIfile\fP
+.br
+.ft B
+.HP
+ncmpidump
+.nh
+\%-k
+\%\fIfile\fP
+.hy
+.ft
+.SH DESCRIPTION
+\fBncmpidump\fP generates an ASCII representation of a specified netCDF file on
+standard output. The ASCII representation is in a form called CDL
+(``network Common Data form Language'') that can be viewed, edited, or serve
+as input to \fBncmpigen\fP. \fBncmpigen\fP is a companion program that can
+generate a binary netCDF file from a CDL file. Hence \fBncmpigen\fP and
+\fBncmpidump\fP can be used as inverses to transform the data representation
+between binary and ASCII representations. See \fBncmpigen\fP for a description
+of CDL and netCDF representations.
+.LP
+\fBncmpidump\fP may also be used to determine what kind of netCDF file is used
+(which variant of the netCDF file format) with the -k option.
+.LP
+\fBncmpidump\fP defines a default format used for each type of netCDF data, but
+this can be changed if a `C_format' attribute is defined for a netCDF
+variable. In this case, \fBncmpidump\fP will use the `C_format' attribute to
+format each value. For example, if floating-point data for the netCDF
+variable `Z' is known to be accurate to only three significant digits, it
+would be appropriate to use the variable attribute
+.RS
+.HP
+Z:C_format = "%.3g"
+.RE
+.LP
+\fBncmpidump\fP may also be used as a simple browser for netCDF data
+files, to display the dimension names and sizes; variable names, types,
+and shapes; attribute names and values; and optionally, the values of
+data for all variables or selected variables in a netCDF file.
+.LP
+\fBncmpidump\fP uses `_' to represent data values that are equal to the
+`_FillValue' attribute for a variable, intended to represent data that
+has not yet been written. If a variable has no `_FillValue' attribute, the
+default fill value for the variable type is used if the variable is not of
+byte type.
+.SH OPTIONS
+.IP "\fB-c\fP"
+Show the values of \fIcoordinate\fP variables (variables that are also
+dimensions) as well as the declarations of all dimensions, variables, and
+attribute values. Data values of non-coordinate variables are not included
+in the output. This is the most suitable option to use for a brief look at
+the structure and contents of a netCDF file.
+.IP "\fB-h\fP"
+Show only the \fIheader\fP information in the output, that is the
+declarations of dimensions, variables, and attributes but no data values for
+any variables. The output is identical to using the \fB-c\fP option except
+that the values of coordinate variables are not included. (At most one of
+\fB-c\fP or \fB-h\fP options may be present.)
+.IP "\fB-v\fP \fIvar1,...,varn\fP"
+The output will include data values for the specified variables, in addition
+to the declarations of all dimensions, variables, and attributes. One or
+more variables must be specified by name in the comma-delimited list
+following this option. The list must be a single argument to the command,
+hence cannot contain blanks or other white space characters. The named
+variables must be valid netCDF variables in the input-file. The default,
+without this option and in the absence of the \fB-c\fP or \fB-h\fP
+options, is to include data values for \fIall\fP variables in the output.
+.IP "\fB-b\fP \fIlang\fP"
+A brief annotation in the form of a CDL comment (text beginning with the
+characters ``//'') will be included in the data section of the output for
+each `row' of data, to help identify data values for multidimensional
+variables. If \fIlang\fP begins with `C' or `c', then C language
+conventions will be used (zero-based indices, last dimension varying
+fastest). If \fIlang\fP begins with `F' or `f', then Fortran language
+conventions will be used (one-based indices, first dimension varying
+fastest). In either case, the data will be presented in the same order;
+only the annotations will differ. This option is useful for browsing
+through large volumes of multidimensional data.
+.IP "\fB-f\fP \fIlang\fP"
+Full annotations in the form of trailing CDL comments (text beginning with
+the characters ``//'') for every data value (except individual characters in
+character arrays) will be included in the data section. If \fIlang\fP
+begins with `C' or `c', then C language conventions will be used (zero-based
+indices, last dimension varying fastest). If \fIlang\fP begins with `F' or
+`f', then Fortran language conventions will be used (one-based indices,
+first dimension varying fastest). In either case, the data will be
+presented in the same order; only the annotations will differ. This option
+may be useful for piping data into other filters, since each data value
+appears on a separate line, fully identified.
+.IP "\fB-l\fP \fIlen\fP"
+Changes the default maximum line length (80) used in formatting lists of
+non-character data values.
+.IP "\fB-n\fP \fIname\fP"
+CDL requires a name for a netCDF data set, for use by \fBncmpigen -b\fP in
+generating a default netCDF file name. By default, \fIncmpidump\fP constructs
+this name from the last component of the pathname of the input netCDF file
+by stripping off any extension it has. Use the \fB-n\fP option to specify a
+different name. Although the output file name used by \fBncmpigen -b\fP can be
+specified, it may be wise to have \fIncmpidump\fP change the default name to
+avoid inadvertantly overwriting a valuable netCDF file when using
+\fBncmpidump\fP, editing the resulting CDL file, and using \fBncmpigen -b\fP to
+generate a new netCDF file from the edited CDL file.
+.IP "\fB-p\fP \fIfloat_digits[,double_digits]\fP"
+Specifies default precision (number of significant digits) to use in displaying
+floating-point or double precision data values for attributes and variables.
+If specified, this value overrides the value of the `C_format' attribute for
+any variable that has such an attribute.
+Floating-point data will be displayed with
+\fIfloat_digits\fP significant digits. If \fIdouble_digits\fP is also
+specified, double-precision values will be displayed with that many
+significant digits. In the absence of any
+\fB-p\fP specifications, floating-point and double-precision data are
+displayed with 7 and 15 significant digits respectively. CDL files can be
+made smaller if less precision is required. If both floating-point and
+double-presision precisions are specified, the two values must appear
+separated by a comma (no blanks) as a single argument to the command.
+If you really want every last bit of precision from the netCDF file
+represented in the CDL file for all possible floating-point values, you will
+have to specify this with \fB-p 9,17\fP (according to Theorem 15 of the
+paper listed under REFERENCES).
+.IP "\fB-k\fP"
+Reports the kind of netCDF file: classic, 64-bit offset, or 64-bit data.
+Before netCDF version 3.6, there was only one kind of netCDF file,
+designated as `classic' (also know as format variant 1 or CDF-1).
+Large file support introduced another variant of the format, designated as
+`64-bit offset' (known as format variant 2 or CDF-2).
+Large data support introduced another variant of the format, designated as
+`64-bit data' (known as format variant 5 or CDF-5).
+
+.SH EXAMPLES
+.LP
+Look at the structure of the data in the netCDF file `\fBfoo.nc\fP':
+.RS
+.HP
+ncmpidump -c foo.nc
+.RE
+.LP
+Produce an annotated CDL version of the structure and data in the
+netCDF file `\fBfoo.nc\fP', using C-style indexing for the annotations:
+.RS
+.HP
+ncmpidump -b c foo.nc > foo.cdl
+.RE
+.LP
+Output data for only the variables `uwind' and `vwind' from the netCDF file
+`\fBfoo.nc\fP', and show the floating-point data with only three significant
+digits of precision:
+.RS
+.HP
+ncmpidump -v uwind,vwind -p 3 foo.nc
+.RE
+.LP
+Produce a fully-annotated (one data value per line) listing of the data for
+the variable `omega', using Fortran conventions for indices, and changing the
+netCDF dataset name in the resulting CDL file to `omega':
+.RS
+.HP
+ncmpidump -v omega -f fortran -n omega foo.nc > Z.cdl
+.RE
+.SH REFERENCES
+ \fIWhat
+Every Computer Scientist should Know About Floating-Point Arithmetic\fP, D.
+Goldberg, \fBACM Computing Surveys, Vol. 23, No. 1\fP, March 1991, pp. 5-48.
+
+.SH "SEE ALSO"
+.LP
+.BR ncmpigen (1),
+.BR pnetcdf (3)
+.SH DATE
+$Date: 2013-11-17 00:21:28 -0600 (Sun, 17 Nov 2013) $
+.SH BUGS
+.LP
+Character arrays that contain a null-byte are treated like C strings, so no
+characters after the null byte appear in the output.
+
+Multidimensional character string arrays are not handled well, since the CDL
+syntax for breaking a long character string into several shorter lines is
+weak.
+
+There should be a way to specify that the data should be displayed in
+`record' order, that is with the all the values for `record' variables
+together that have the same value of the record dimension.
diff --git a/src/utils/ncmpidump/ncmpidump.c b/src/utils/ncmpidump/ncmpidump.c
new file mode 100644
index 0000000..d3dcac9
--- /dev/null
+++ b/src/utils/ncmpidump/ncmpidump.c
@@ -0,0 +1,823 @@
+/*********************************************************************
+ * Copyright 1993, University Corporation for Atmospheric Research
+ * See netcdf/README file for copying and redistribution conditions.
+ * $Header$
+ *********************************************************************/
+/* $Id: ncmpidump.c 2060 2015-08-03 22:39:58Z wkliao $ */
+
+#if HAVE_CONFIG_H
+# include <ncconfig.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h> /* strtol() */
+#include <string.h> /* strrchr() */
+#include <ctype.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <mpi.h>
+#include <pnetcdf.h>
+#include "ncmpidump.h"
+#include "dumplib.h"
+#include "vardata.h"
+
+static void usage(void);
+static char* name_path(const char* path);
+static const char* type_name(nc_type type);
+static void tztrim(char* ss);
+static void pr_att_string(size_t len, const char* string);
+static void pr_att_vals(nc_type type, size_t len, const double* vals);
+static void pr_att(int ncid, int varid, const char *varname, int ia);
+static void do_ncdump(const char* path, struct fspec* specp);
+static void make_lvars(char* optarg, struct fspec* fspecp);
+static void set_sigdigs( const char* optarg);
+static void set_precision( const char *optarg);
+int main(int argc, char** argv);
+
+#define STREQ(a, b) (*(a) == *(b) && strcmp((a), (b)) == 0)
+
+char *progname;
+
+static void
+usage(void)
+{
+#define USAGE "\
+ [-c] Coordinate variable data and header information\n\
+ [-h] Header information only, no data\n\
+ [-v var1[,...]] Data for variable(s) <var1>,... only\n\
+ [-b [c|f]] Brief annotations for C or Fortran indices in data\n\
+ [-f [c|f]] Full annotations for C or Fortran indices in data\n\
+ [-l len] Line length maximum in data section (default 80)\n\
+ [-n name] Name for netCDF (default derived from file name)\n\
+ [-p n[,n]] Display floating-point values with less precision\n\
+ [-V] Print the file format (CDF-1, CDF-2, or CDF-5)\n\
+ [-k] Print kind of file (classic, 64-bit offset, or 64-bit data)\n\
+ file File name of input netCDF file\n"
+
+ fprintf(stderr,
+ "%s [-c|-h] [-v ...] [[-b|-f] [c|f]] [-l len] [-n name] [-p n[,n]] [-k] [-V] file\n%s",
+ progname, USAGE);
+
+ fprintf(stderr, "PnetCDF library version %s\n", ncmpi_inq_libvers());
+}
+
+
+/*
+ * convert pathname of netcdf file into name for cdl unit, by taking
+ * last component of path and stripping off any extension.
+ */
+static char *
+name_path(const char *path)
+{
+ const char *cp;
+ char *new;
+ char *sp;
+
+#ifdef vms
+#define FILE_DELIMITER ']'
+#endif
+#ifdef MSDOS
+#define FILE_DELIMITER '\\'
+#endif
+#ifndef FILE_DELIMITER /* default to unix */
+#define FILE_DELIMITER '/'
+#endif
+ cp = strrchr(path, FILE_DELIMITER);
+ if (cp == 0) /* no delimiter */
+ cp = path;
+ else /* skip delimeter */
+ cp++;
+
+ new = (char *) malloc((unsigned) (strlen(cp)+1));
+ if (new == 0) error("out of memory!");
+
+ strcpy(new, cp); /* copy last component of path */
+ if ((sp = strrchr(new, '.')) != NULL)
+ *sp = '\0'; /* strip off any extension */
+ return new;
+}
+
+
+static const char *
+type_name(nc_type type)
+{
+ switch (type) { /* conform with netcdf4 */
+ case NC_BYTE: return "byte";
+ case NC_CHAR: return "char";
+ case NC_SHORT: return "short";
+ case NC_INT: return "int";
+ case NC_FLOAT: return "float";
+ case NC_DOUBLE: return "double";
+ case NC_UBYTE: return "ubyte";
+ case NC_USHORT: return "ushort";
+ case NC_UINT: return "uint";
+ case NC_INT64: return "int64";
+ case NC_UINT64: return "uint64";
+ default:
+ error("type_name: bad type %d", type);
+ return "bogus";
+ }
+}
+
+
+/*
+ * Remove trailing zeros (after decimal point) but not trailing decimal
+ * point from ss, a string representation of a floating-point number that
+ * might include an exponent part.
+ */
+static void
+tztrim(char *ss)
+{
+ char *cp, *ep;
+
+ cp = ss;
+ if (*cp == '-')
+ cp++;
+ while(isdigit((int)*cp) || *cp == '.')
+ cp++;
+ if (*--cp == '.')
+ return;
+ ep = cp+1;
+ while (*cp == '0')
+ cp--;
+ cp++;
+ if (cp == ep)
+ return;
+ while (*ep)
+ *cp++ = *ep++;
+ *cp = '\0';
+ return;
+}
+
+
+/*
+ * Print attribute string, for text attributes.
+ */
+static void
+pr_att_string(size_t len,
+ const char *string)
+{
+ int iel;
+ const char *cp;
+ const char *sp;
+ unsigned char uc;
+
+ cp = string;
+ Printf ("\"");
+ /* adjust len so trailing nulls don't get printed */
+ sp = cp + len - 1;
+ while (len != 0 && *sp-- == '\0')
+ len--;
+
+ for (iel = 0; iel < len; iel++)
+ switch (uc = *cp++ & 0377) {
+ case '\b':
+ Printf ("\\b");
+ break;
+ case '\f':
+ Printf ("\\f");
+ break;
+ case '\n': /* generate linebreaks after new-lines */
+ Printf ("\\n\",\n \"");
+ break;
+ case '\r':
+ Printf ("\\r");
+ break;
+ case '\t':
+ Printf ("\\t");
+ break;
+ case '\v':
+ Printf ("\\v");
+ break;
+ case '\\':
+ Printf ("\\\\");
+ break;
+ case '\'':
+ Printf ("\\'");
+ break;
+ case '\"':
+ Printf ("\\\"");
+ break;
+ default:
+ Printf ("%c",uc);
+ break;
+ }
+
+ Printf ("\"");
+}
+
+
+/*
+ * Print list of attribute values, for numeric attributes. Attribute values
+ * must be printed with explicit type tags, because CDL doesn't have explicit
+ * syntax to declare an attribute type.
+ */
+static void
+pr_att_vals(nc_type type,
+ size_t len,
+ const double *vals)
+{
+ int iel;
+ char gps[30];
+ signed char sc;
+ unsigned char uc;
+ short ss;
+ unsigned short us;
+ int si;
+ unsigned int ui;
+ float ff;
+ double dd;
+ long long sll;
+ unsigned long long ull;
+
+ if (len == 0) return;
+
+ for (iel=0; iel<len; iel++) {
+ switch (type) {
+ case NC_BYTE:
+ sc = (signed char) vals[iel] & 0377;
+ Printf ("%hhdb", sc);
+ break;
+ case NC_SHORT:
+ ss = vals[iel];
+ Printf ("%hds", ss);
+ break;
+ case NC_INT:
+ si = (int) vals[iel];
+ Printf ("%d", si);
+ break;
+ case NC_FLOAT:
+ ff = vals[iel];
+ (void) sprintf(gps, float_att_fmt, ff);
+ tztrim(gps); /* trim trailing 0's after '.' */
+ Printf ("%s", gps);
+ break;
+ case NC_DOUBLE:
+ dd = vals[iel];
+ (void) sprintf(gps, double_att_fmt, dd);
+ tztrim(gps);
+ Printf ("%s", gps);
+ break;
+ case NC_UBYTE:
+ uc = (unsigned char) vals[iel] & 0377;
+ Printf ("%hhuUB", uc); /* match netCDF4 ncdump type indicator */
+ break;
+ case NC_USHORT:
+ us = vals[iel];
+ Printf ("%huUS", us); /* match netCDF4 ncdump type indicator */
+ break;
+ case NC_UINT:
+ ui = vals[iel];
+ Printf ("%uU", ui); /* match netCDF4 ncdump type indicator */
+ break;
+ case NC_INT64:
+ sll = vals[iel];
+ Printf ("%lldL", sll); /* match netCDF4 ncdump type indicator */
+ break;
+ case NC_UINT64:
+ ull = vals[iel];
+ Printf ("%lluUL", ull);/* match netCDF4 ncdump type indicator */
+ break;
+ default:
+ error("pr_att_vals: bad type");
+ }
+ /* if not the last element */
+ if (iel < len-1) Printf (", ");
+ }
+}
+
+
+static void
+pr_att(int ncid,
+ int varid,
+ const char *varname,
+ int ia)
+{
+ struct ncatt att; /* attribute */
+
+ NC_CHECK(ncmpi_inq_attname(ncid, varid, ia, att.name));
+
+ Printf ("\t\t%s:%s = ", varname, att.name);
+
+ NC_CHECK(ncmpi_inq_att(ncid, varid, att.name, &att.type, &att.len));
+
+ if (att.len == 0) { /* show 0-length attributes as empty strings */
+ Printf ("\"\" ;\n");
+ return;
+ }
+ switch (att.type) {
+ case NC_CHAR:
+ att.string = (char *) malloc(att.len);
+ if (!att.string) {
+ error("Out of memory!");
+ NC_CHECK(ncmpi_close(ncid));
+ return;
+ }
+ NC_CHECK(ncmpi_get_att_text(ncid, varid, att.name, att.string));
+ pr_att_string(att.len, att.string);
+ free(att.string);
+ break;
+ default:
+ att.vals = (double *) malloc(att.len * sizeof(double));
+ if (!att.vals) {
+ error("Out of memory!");
+ NC_CHECK( ncmpi_close(ncid) );
+ return;
+ }
+ NC_CHECK(ncmpi_get_att_double(ncid, varid, att.name, att.vals));
+ pr_att_vals(att.type, att.len, att.vals);
+ free(att.vals);
+ break;
+ }
+ Printf (" ;\n");
+}
+
+
+static void
+do_ncdump(const char *path, struct fspec* specp)
+{
+ int ndims; /* number of dimensions */
+ int nvars; /* number of variables */
+ int ngatts; /* number of global attributes */
+ int xdimid; /* id of unlimited dimension */
+ int dimid; /* dimension id */
+ int varid; /* variable id */
+ struct ncdim dims[NC_MAX_DIMS]; /* dimensions */
+ size_t vdims[NC_MAX_DIMS]; /* dimension sizes for a single variable */
+ struct ncvar var; /* variable */
+ struct ncatt att; /* attribute */
+ int id; /* dimension number per variable */
+ int ia; /* attribute number */
+ int iv; /* variable number */
+ int is_coord; /* true if variable is a coordinate variable */
+ int ncid; /* netCDF id */
+ vnode* vlist = 0; /* list for vars specified with -v option */
+ int ncmpi_status; /* return from netcdf calls */
+ int NC_mode;
+ MPI_Info info;
+
+ /* Nov. 18, 2014 -- disable subfiling as it does not correctly handle the
+ * cases when nprocs < num_subfiles */
+ MPI_Info_create (&info);
+ MPI_Info_set (info, "pnetcdf_subfiling", "disable");
+
+ ncmpi_status = ncmpi_open(MPI_COMM_WORLD, path, NC_NOWRITE,
+ info, &ncid);
+ if (ncmpi_status != NC_NOERR)
+ error("%s: %s", path, ncmpi_strerror(ncmpi_status));
+ MPI_Info_free(&info);
+
+ /*
+ * If any vars were specified with -v option, get list of associated
+ * variable ids
+ */
+ if (specp->nlvars > 0) {
+ vlist = newvlist(); /* list for vars specified with -v option */
+ for (iv=0; iv < specp->nlvars; iv++) {
+ NC_CHECK(ncmpi_inq_varid(ncid, specp->lvars[iv], &varid));
+ varadd(vlist, varid);
+ }
+ }
+
+ /* if name not specified, derive it from path */
+ if (specp->name == (char *)0)
+ specp->name = name_path (path);
+
+ ncmpi_inq_version(ncid, &NC_mode);
+ if (specp->version) {
+ if (NC_mode == NC_64BIT_DATA)
+ Printf ("%s file format: CDF-5 (big variables)\n", specp->name);
+ else if (NC_mode == NC_64BIT_OFFSET)
+ Printf ("%s file format: CDF-2 (large file)\n", specp->name);
+ else
+ Printf ("%s file format: CDF-1\n", specp->name);
+ } else if (specp->kind) {
+ if (NC_mode == NC_64BIT_DATA)
+ Printf ("64-bit data\n");
+ else if (NC_mode == NC_64BIT_OFFSET)
+ Printf ("64-bit offset\n");
+ else
+ Printf ("classic\n");
+ } else {
+ Printf ("netcdf %s {\n", specp->name);
+
+ if (NC_mode == NC_64BIT_DATA)
+ Printf ("// file format: CDF-5 (big variables)\n");
+ else if (NC_mode == NC_64BIT_OFFSET)
+ Printf ("// file format: CDF-2 (large file)\n");
+ else
+ Printf ("// file format: CDF-1\n");
+ /*
+ * get number of dimensions, number of variables, number of global
+ * atts, and dimension id of unlimited dimension, if any
+ */
+ NC_CHECK(ncmpi_inq(ncid, &ndims, &nvars, &ngatts, &xdimid));
+
+ /* print dimension info */
+ if (ndims > 0) Printf ("dimensions:\n");
+
+ for (dimid = 0; dimid < ndims; dimid++) {
+ NC_CHECK(ncmpi_inq_dim(ncid, dimid, dims[dimid].name,
+ &dims[dimid].size) );
+ if (dimid == xdimid)
+ Printf ("\t%s = %s ; // (%lld currently)\n",dims[dimid].name,
+ "UNLIMITED", (long long int)(dims[dimid].size));
+ else
+ Printf ("\t%s = %lld ;\n", dims[dimid].name,
+ (long long int)(dims[dimid].size));
+ }
+
+ if (nvars > 0) Printf ("variables:\n");
+
+ /* get variable info, with variable attributes */
+ for (varid = 0; varid < nvars; varid++) {
+ NC_CHECK(ncmpi_inq_var(ncid, varid, var.name, &var.type,
+ &var.ndims, var.dims, &var.natts) );
+ Printf ("\t%s %s", type_name(var.type), var.name);
+ if (var.ndims > 0) Printf ("(");
+ for (id = 0; id < var.ndims; id++) {
+ Printf ("%s%s", dims[var.dims[id]].name,
+ id < var.ndims-1 ? ", " : ")");
+ }
+ Printf (" ;\n");
+
+ /* get variable attributes */
+ for (ia = 0; ia < var.natts; ia++)
+ pr_att(ncid, varid, var.name, ia); /* print ia-th attribute */
+ }
+
+
+ /* get global attributes */
+ if (ngatts > 0) Printf ("\n// global attributes:\n");
+
+ for (ia = 0; ia < ngatts; ia++)
+ pr_att(ncid, NC_GLOBAL, "", ia); /* print ia-th global attribute */
+
+ if (! specp->header_only) {
+ if (nvars > 0) Printf ("data:\n");
+ /* output variable data */
+ for (varid = 0; varid < nvars; varid++) {
+ /* if var list specified, test for membership */
+ if (specp->nlvars > 0 && ! varmember(vlist, varid))
+ continue;
+ NC_CHECK(ncmpi_inq_var(ncid, varid, var.name, &var.type,
+ &var.ndims, var.dims, &var.natts));
+ if (specp->coord_vals) {
+ /* Find out if this is a coordinate variable */
+ is_coord = 0;
+ for (dimid = 0; dimid < ndims; dimid++) {
+ if (strcmp(dims[dimid].name, var.name) == 0 &&
+ var.ndims == 1) {
+ is_coord = 1;
+ break;
+ }
+ }
+ if (! is_coord) /* don't get data for non-coordinate vars */
+ continue;
+ }
+ /*
+ * Only get data for variable if it is not a record variable,
+ * or if it is a record variable and at least one record has
+ * been written.
+ */
+ if (var.ndims == 0 || var.dims[0] != xdimid ||
+ dims[xdimid].size != 0) {
+ /* Collect variable's dim sizes */
+ for (id = 0; id < var.ndims; id++)
+ vdims[id] = dims[var.dims[id]].size;
+
+ var.has_fillval = 1; /* by default, but turn off for bytes */
+
+ /* get _FillValue attribute */
+ ncmpi_status = ncmpi_inq_att(ncid, varid, _FillValue,
+ &att.type, &att.len);
+ if (ncmpi_status == NC_NOERR &&
+ att.type == var.type && att.len == 1) {
+ if (var.type == NC_CHAR) {
+ char fillc;
+ NC_CHECK(ncmpi_get_att_text(ncid, varid, _FillValue,
+ &fillc));
+ var.fillval = fillc;
+ } else
+ NC_CHECK(ncmpi_get_att_double(ncid, varid, _FillValue,
+ &var.fillval));
+ } else {
+ switch (var.type) {
+ case NC_BYTE:
+ /* don't do default fill-values for bytes, too risky */
+ var.has_fillval = 0;
+ break;
+ case NC_UBYTE:
+ var.fillval = NC_FILL_UBYTE;
+ break;
+ case NC_CHAR:
+ var.fillval = NC_FILL_CHAR;
+ break;
+ case NC_SHORT:
+ var.fillval = NC_FILL_SHORT;
+ break;
+ case NC_USHORT:
+ var.fillval = NC_FILL_USHORT;
+ break;
+ case NC_INT:
+ var.fillval = NC_FILL_INT;
+ break;
+ case NC_UINT:
+ var.fillval = NC_FILL_UINT;
+ break;
+ case NC_FLOAT:
+ var.fillval = NC_FILL_FLOAT;
+ break;
+ case NC_DOUBLE:
+ var.fillval = NC_FILL_DOUBLE;
+ break;
+ case NC_INT64:
+ var.fillval = NC_FILL_INT64;
+ break;
+ case NC_UINT64:
+ var.fillval = NC_FILL_UINT64;
+ break;
+ default:
+ break;
+ }
+ }
+ if (vardata(&var, vdims, ncid, varid, specp) == -1) {
+ error("can't output data for variable %s", var.name);
+ NC_CHECK(ncmpi_close(ncid));
+ if (vlist) free(vlist);
+ return;
+ }
+ }
+ }
+ }
+ Printf ("}\n");
+ }
+ NC_CHECK(ncmpi_close(ncid));
+ if (vlist) free(vlist);
+}
+
+
+static void
+make_lvars(char *optarg, struct fspec* fspecp)
+{
+ char *cp = optarg;
+ int nvars = 1;
+ char ** cpp;
+
+ /* compute number of variable names in comma-delimited list */
+ fspecp->nlvars = 1;
+ while (*cp++)
+ if (*cp == ',')
+ nvars++;
+
+ fspecp->lvars = (char **) malloc(nvars * sizeof(char*));
+ if (!fspecp->lvars) error("out of memory");
+
+ cpp = fspecp->lvars;
+ /* copy variable names into list */
+ for (cp = strtok(optarg, ",");
+ cp != NULL;
+ cp = strtok((char *) NULL, ",")) {
+
+ *cpp = (char *) malloc(strlen(cp) + 1);
+ if (!*cpp) error("out of memory");
+
+ strcpy(*cpp, cp);
+ cpp++;
+ }
+ fspecp->nlvars = nvars;
+}
+
+
+/*
+ * Extract the significant-digits specifiers from the -d argument on the
+ * command-line and update the default data formats appropriately.
+ */
+static void
+set_sigdigs(const char *optarg)
+{
+ char *ptr1 = 0;
+ char *ptr2 = 0;
+ int flt_digits = FLT_DIGITS; /* default floating-point digits */
+ int dbl_digits = DBL_DIGITS; /* default double-precision digits */
+
+ if (optarg != 0 && (int) strlen(optarg) > 0 && optarg[0] != ',')
+ flt_digits = (int)strtol(optarg, &ptr1, 10);
+
+ if (flt_digits < 1 || flt_digits > 20)
+ error("unreasonable value for float significant digits: %d",
+ flt_digits);
+
+ if (*ptr1 == ',')
+ dbl_digits = (int)strtol(ptr1+1, &ptr2, 10);
+
+ if (ptr2 == ptr1+1 || dbl_digits < 1 || dbl_digits > 20)
+ error("unreasonable value for double significant digits: %d",
+ dbl_digits);
+
+ set_formats(flt_digits, dbl_digits);
+}
+
+
+/*
+ * Extract the significant-digits specifiers from the -p argument on the
+ * command-line, set flags so we can override C_format attributes (if any),
+ * and update the default data formats appropriately.
+ */
+static void
+set_precision(const char *optarg)
+{
+ char *ptr1 = 0;
+ char *ptr2 = 0;
+ int flt_digits = FLT_DIGITS; /* default floating-point digits */
+ int dbl_digits = DBL_DIGITS; /* default double-precision digits */
+
+ if (optarg != 0 && (int) strlen(optarg) > 0 && optarg[0] != ',') {
+ flt_digits = (int)strtol(optarg, &ptr1, 10);
+ float_precision_specified = 1;
+ }
+
+ if (flt_digits < 1 || flt_digits > 20)
+ error("unreasonable value for float significant digits: %d",
+ flt_digits);
+
+ if (*ptr1 == ',') {
+ dbl_digits = (int) strtol(ptr1+1, &ptr2, 10);
+ double_precision_specified = 1;
+ }
+
+ if (ptr2 == ptr1+1 || dbl_digits < 1 || dbl_digits > 20)
+ error("unreasonable value for double significant digits: %d",
+ dbl_digits);
+
+ set_formats(flt_digits, dbl_digits);
+}
+
+
+int
+main(int argc, char *argv[])
+{
+ extern int optind;
+ extern int opterr;
+ extern char *optarg;
+ static struct fspec fspec = /* defaults, overridden on command line */
+ {
+ 0, /* construct netcdf name from file name */
+ false, /* print header info only, no data? */
+ false, /* print CDF version, no data, no header */
+ false, /* print file kind, no data, no header */
+ false, /* just print coord vars? */
+ false, /* brief comments in data section? */
+ false, /* full annotations in data section? */
+ LANG_C, /* language conventions for indices */
+ 0, /* if -v specified, number of variables */
+ 0 /* if -v specified, list of variable names */
+ };
+ int c, rank, err=EXIT_SUCCESS;
+ int max_len = 80; /* default maximum line length */
+ int nameopt = 0;
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+
+ /* If the user called ncmpidump without arguments, print the usage
+ * message and return peacefully. */
+ if (argc <= 1) {
+ if (rank == 0) usage();
+ goto fn_exit;
+ }
+
+ opterr = 1;
+ progname = argv[0];
+ set_formats(FLT_DIGITS, DBL_DIGITS); /* default for float, double data */
+
+ while ((c = getopt(argc, argv, "b:cf:hVkl:n:v:d:p:")) != EOF)
+ switch(c) {
+ case 'h': /* dump header only, no data */
+ fspec.header_only = true;
+ break;
+ case 'V': /* dump CDF version, no data, no header */
+ fspec.version = true;
+ break;
+ case 'k': /* dump CDF version, no data, no header */
+ fspec.kind = true;
+ break;
+ case 'c': /* header, data only for coordinate dims */
+ fspec.coord_vals = true;
+ break;
+ case 'n': /* provide different name than derived from
+ * file name
+ */
+ fspec.name = optarg;
+ nameopt = 1;
+ break;
+ case 'b': /* brief comments in data section */
+ fspec.brief_data_cmnts = true;
+ switch (tolower(optarg[0])) {
+ case 'c':
+ fspec.data_lang = LANG_C;
+ break;
+ case 'f':
+ fspec.data_lang = LANG_F;
+ break;
+ default:
+ if (rank == 0)
+ fprintf(stderr,"invalid value for -b option: %s",
+ optarg);
+ err = EXIT_FAILURE;
+ goto fn_exit;
+ }
+ break;
+ case 'f': /* full comments in data section */
+ fspec.full_data_cmnts = true;
+ switch (tolower(optarg[0])) {
+ case 'c':
+ fspec.data_lang = LANG_C;
+ break;
+ case 'f':
+ fspec.data_lang = LANG_F;
+ break;
+ default:
+ if (rank == 0)
+ fprintf(stderr,"invalid value for -f option: %s",
+ optarg);
+ err = EXIT_FAILURE;
+ goto fn_exit;
+ }
+ break;
+ case 'l': /* maximum line length */
+ max_len = (int) strtol(optarg, 0, 0);
+ if (max_len < 10) {
+ if (rank == 0)
+ fprintf(stderr,
+ "unreasonably small line length specified: %d",
+ max_len);
+ err = EXIT_FAILURE;
+ goto fn_exit;
+ }
+ break;
+ case 'v': /* variable names */
+ /* make list of names of variables specified */
+ make_lvars (optarg, &fspec);
+ break;
+ case 'd': /* specify precision for floats (old option) */
+ set_sigdigs(optarg);
+ break;
+ case 'p': /* specify precision for floats */
+ set_precision(optarg);
+ break;
+ case '?':
+ if (rank == 0) usage();
+ goto fn_exit;
+ default:
+ break;
+ }
+
+ set_max_len(max_len);
+
+ argc -= optind;
+ argv += optind;
+
+#ifndef MULTI_FILE_DUMP
+ /* If no input file, print usage message. */
+ if (argc != 1) {
+ if (rank == 0) {
+ if (argc == 0)
+ fprintf(stderr,"Error: input filename is missing\n\n");
+ else
+ fprintf(stderr,"Error: only one input file is allowed\n\n");
+ usage();
+ }
+ err = EXIT_FAILURE;
+ goto fn_exit;
+ }
+
+ if (!nameopt) fspec.name = (char *)0;
+ do_ncdump(argv[0], &fspec);
+#else
+ /* support multiple input files */
+ if (argc < 1) {
+ if (rank == 0) {
+ fprintf(stderr,"Error: input filename(s) is missing\n\n");
+ usage();
+ }
+ err = EXIT_FAILURE;
+ goto fn_exit;
+ }
+ int i = 0;
+ do {
+ if (!nameopt) fspec.name = (char *)0;
+ if (argc > 0)
+ do_ncdump(argv[i], &fspec);
+ } while (++i < argc);
+#endif
+
+fn_exit:
+ MPI_Finalize();
+#ifdef vms
+ exit(err);
+#else
+ return err;
+#endif
+}
diff --git a/src/utils/ncmpidump/ncmpidump.h b/src/utils/ncmpidump/ncmpidump.h
new file mode 100644
index 0000000..e340cea
--- /dev/null
+++ b/src/utils/ncmpidump/ncmpidump.h
@@ -0,0 +1,83 @@
+/*********************************************************************
+ * Copyright 1993, UCAR/Unidata
+ * See netcdf/COPYRIGHT file for copying and redistribution conditions.
+ * $Header$
+ *********************************************************************/
+/* $Id: ncmpidump.h 1468 2013-10-26 16:53:18Z wkliao $ */
+
+
+/* error checking macro */
+#define NC_CHECK(status) {\
+ int nc_status = status;\
+ if(nc_status != NC_NOERR)\
+ error(ncmpi_strerror(nc_status));\
+ }
+
+#define Printf (void) printf
+
+typedef int boolean;
+enum {false=0, true=1};
+
+struct ncdim { /* dimension */
+ char name[NC_MAX_NAME];
+ MPI_Offset size;
+};
+
+struct ncvar { /* variable */
+ char name[NC_MAX_NAME];
+ nc_type type;
+ int ndims;
+ int dims[NC_MAX_VAR_DIMS];
+ int natts;
+ boolean has_fillval;
+ double fillval;
+};
+
+struct ncatt { /* attribute */
+ int var;
+ char name[NC_MAX_NAME];
+ nc_type type;
+ MPI_Offset len;
+ char *string; /* for text attributes (type = NC_CHAR) */
+ double *vals; /* for numeric attributes of all types */
+};
+
+typedef
+enum {LANG_C, LANG_F} Nclang;
+
+struct fspec { /* specification for how to format dump */
+
+ char *name; /* name specified with -n or derived from
+ * file name */
+
+ boolean header_only; /* if true, don't print any variable data */
+
+ boolean version; /* if true, print version */
+ boolean kind; /* if true, print kind of file format */
+
+ boolean coord_vals; /* if true, print header and coordinate
+ * dimension values (values of variables
+ * that are also dimensions), but no other
+ * variable data */
+
+ boolean brief_data_cmnts; /* if true, put // comments in data section
+ * identifying variable and indices, useful
+ * for navigating through large
+ * multi-dimensional data lists. */
+
+ boolean full_data_cmnts; /* if true, put // comments in data section
+ * identifying every value, useful for
+ * navigating through large
+ * multi-dimensional data lists. */
+
+ Nclang data_lang; /* Specifies index conventions used in data
+ * comments, either LANG_C (C, 0-based,
+ * column major) or LANG_F (Fortran,
+ * 1-based, row major) */
+
+ int nlvars; /* Number of variables specified with -v
+ * option on command line */
+
+ char** lvars; /* list of variable names specified with -v
+ * option on command line */
+};
diff --git a/src/utils/ncmpidump/test0.cdl b/src/utils/ncmpidump/test0.cdl
new file mode 100644
index 0000000..1e94bcf
--- /dev/null
+++ b/src/utils/ncmpidump/test0.cdl
@@ -0,0 +1,41 @@
+netcdf test0 {
+
+dimensions:
+ i = 2;
+ j = 3;
+ k = unlimited;
+ l = 3 ;
+
+variables:
+ char broiled(i,j,l);
+ broiled:act = "text string\n\t123";
+ broiled:acb = 10b;
+ broiled:acs = -200s ;
+ broiled:acl = 17000 ;
+ broiled:acf = -2.0f, 1.f, 0.0f ;
+ broiled:acd = -1.0, 2.7182818284590455;
+ short order(i,j);
+ int rigue(i,j);
+ float a_loan(i,j);
+ double entendre(i,j);
+ char cscalar;
+ double dscalar;
+ char cnodata(i);
+ short snodata(i);
+ int inodata(i);
+ float fnodata(i);
+ double dnodata(i);
+ int i(i);
+ float j(j);
+
+ :glob = "Global attribute" ;
+
+data:
+ broiled = "indistinguishable" ;
+ order = 1s, 2s, 3s, 4s, 5s, 6s;
+ rigue = 2, 3, 4, 5, 6, 7 ;
+ a_loan = 3.f, 4.f, 5.f, 6.f, 7.f, 1.0e12f ;
+ entendre = '\4', 5s, 6, 7.0f, 8.0, 1.0e30 ;
+ i = 10, 20;
+ j = 2, 4, 6;
+}
diff --git a/src/utils/ncmpidump/vardata.c b/src/utils/ncmpidump/vardata.c
new file mode 100644
index 0000000..540d376
--- /dev/null
+++ b/src/utils/ncmpidump/vardata.c
@@ -0,0 +1,738 @@
+/*********************************************************************
+ * Copyright 1993, UCAR/Unidata
+ * See netcdf/COPYRIGHT file for copying and redistribution conditions.
+ * $Header$
+ *********************************************************************/
+/* $Id: vardata.c 1440 2013-10-05 03:47:56Z wkliao $ */
+
+#if HAVE_CONFIG_H
+# include <ncconfig.h>
+#endif
+#include <stdio.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+#ifndef NO_FLOAT_H
+#include <float.h> /* for FLT_EPSILON, DBL_EPSILON */
+#endif /* NO_FLOAT_H */
+
+#include <pnetcdf.h>
+#include "ncmpidump.h"
+#include "dumplib.h"
+#include "vardata.h"
+
+static float float_epsilon(void);
+static double double_epsilon(void);
+static void init_epsilons(void);
+static void printbval(char* sout, const char* fmt, const struct ncvar* varp,
+ signed char val);
+static void printsval(char* sout, const char* fmt, const struct ncvar* varp,
+ short val);
+static void printival(char* sout, const char* fmt, const struct ncvar* varp,
+ int val);
+static void printfval(char* sout, const char* fmt, const struct ncvar* varp,
+ float val);
+static void printdval(char* sout, const char* fmt, const struct ncvar* varp,
+ double val);
+static void lastdelim(boolean more, boolean lastrow);
+static void annotate(const struct ncvar* vp, const struct fspec* fsp,
+ const MPI_Offset* cor, long iel);
+static void pr_tvals(const struct ncvar *vp, size_t len, const char *fmt,
+ boolean more, boolean lastrow, const char *vals,
+ const struct fspec* fsp, const MPI_Offset *cor);
+static void pr_bvals(const struct ncvar *vp, size_t len, const char *fmt,
+ boolean more, boolean lastrow, const signed char *vals,
+ const struct fspec* fsp, const MPI_Offset *cor);
+static void pr_ubvals(const struct ncvar *vp, size_t len, const char *fmt,
+ boolean more, boolean lastrow, const unsigned char *vals,
+ const struct fspec* fsp, const MPI_Offset *cor);
+static void pr_svals(const struct ncvar *vp, size_t len, const char *fmt,
+ boolean more, boolean lastrow, const short *vals,
+ const struct fspec* fsp, const MPI_Offset *cor);
+static void pr_usvals(const struct ncvar *vp, size_t len, const char *fmt,
+ boolean more, boolean lastrow, const unsigned short *vals,
+ const struct fspec* fsp, const MPI_Offset *cor);
+static void pr_ivals(const struct ncvar *vp, size_t len, const char *fmt,
+ boolean more, boolean lastrow, const int *vals,
+ const struct fspec* fsp, const MPI_Offset *cor);
+static void pr_uivals(const struct ncvar *vp, size_t len, const char *fmt,
+ boolean more, boolean lastrow, const unsigned int *vals,
+ const struct fspec* fsp, const MPI_Offset *cor);
+static void pr_fvals(const struct ncvar *vp, size_t len, const char *fmt,
+ boolean more, boolean lastrow, const float *vals,
+ const struct fspec* fsp, const MPI_Offset *cor);
+static void pr_dvals(const struct ncvar *vp, size_t len, const char *fmt,
+ boolean more, boolean lastrow, const double *vals,
+ const struct fspec* fsp, const MPI_Offset *cor);
+static void pr_llvals(const struct ncvar *vp, size_t len, const char *fmt,
+ boolean more, boolean lastrow, const long long *vals,
+ const struct fspec* fsp, const MPI_Offset *cor);
+static void pr_ullvals(const struct ncvar *vp, size_t len, const char *fmt,
+ boolean more, boolean lastrow, const unsigned long long *vals,
+ const struct fspec* fsp, const MPI_Offset *cor);
+static int upcorner(const size_t* dims, int ndims, MPI_Offset* odom,
+ const size_t* add);
+static void lastdelim2 (boolean more, boolean lastrow);
+
+#define STREQ(a, b) (*(a) == *(b) && strcmp((a), (b)) == 0)
+
+static float float_eps;
+static double double_eps;
+
+static float
+float_epsilon(void)
+{
+ float float_eps;
+#ifndef NO_FLOAT_H
+ float_eps = FLT_EPSILON;
+#else /* NO_FLOAT_H */
+ {
+ float etop, ebot, eps;
+ float one = 1.0;
+ float two = 2.0;
+ etop = 1.0;
+ ebot = 0.0;
+ eps = ebot + (etop - ebot)/two;
+ while (eps != ebot && eps != etop) {
+ float epsp1;
+
+ epsp1 = one + eps;
+ if (epsp1 > one)
+ etop = eps;
+ else
+ ebot = eps;
+ eps = ebot + (etop - ebot)/two;
+ }
+ float_eps = two * etop;
+ }
+#endif /* NO_FLOAT_H */
+ return float_eps;
+}
+
+
+static double
+double_epsilon(void)
+{
+ double double_eps;
+#ifndef NO_FLOAT_H
+ double_eps = DBL_EPSILON;
+#else /* NO_FLOAT_H */
+ {
+ double etop, ebot, eps;
+ double one = 1.0;
+ double two = 2.0;
+ etop = 1.0;
+ ebot = 0.0;
+ eps = ebot + (etop - ebot)/two;
+ while (eps != ebot && eps != etop) {
+ double epsp1;
+
+ epsp1 = one + eps;
+ if (epsp1 > one)
+ etop = eps;
+ else
+ ebot = eps;
+ eps = ebot + (etop - ebot)/two;
+ }
+ double_eps = two * etop;
+ }
+#endif /* NO_FLOAT_H */
+ return double_eps;
+}
+
+
+static void
+init_epsilons(void)
+{
+ float_eps = float_epsilon();
+ double_eps = double_epsilon();
+}
+
+/*
+ * Output a value of a "type" variable, except if there is a fill value for
+ * the variable and the value is the fill value, print the fill-value string
+ * instead.
+ */
+#define PRINT_VAL(fn, type) \
+static void \
+print##fn(char *sout, /* string where output goes */ \
+ const char *fmt, /* printf format used for value */ \
+ const struct ncvar *varp, /* variable */ \
+ type val) /* value */ \
+{ \
+ if (varp->has_fillval) { \
+ double fillval = varp->fillval; \
+ if (fillval == val) { \
+ sprintf(sout, FILL_STRING); \
+ return; \
+ } \
+ } \
+ sprintf(sout, fmt, val); \
+}
+
+/*----< printbval() >---------------------------------------------------------*/
+/*----< printubval() >--------------------------------------------------------*/
+/*----< printsval() >---------------------------------------------------------*/
+/*----< printusval() >--------------------------------------------------------*/
+/*----< printival() >---------------------------------------------------------*/
+/*----< printuival() >--------------------------------------------------------*/
+/*----< printllval() >--------------------------------------------------------*/
+/*----< printullval() >-------------------------------------------------------*/
+PRINT_VAL(bval, signed char)
+PRINT_VAL(ubval, unsigned char)
+PRINT_VAL(sval, short)
+PRINT_VAL(usval, unsigned short)
+PRINT_VAL(ival, int)
+PRINT_VAL(uival, unsigned int)
+PRINT_VAL(llval, long long)
+PRINT_VAL(ullval, unsigned long long)
+
+#define absval(x) ( (x) < 0 ? -(x) : (x) )
+
+/*
+ * Output a value of a float variable, except if there is a fill value for
+ * the variable and the value is the fill value, print the fill-value string
+ * instead. Floating-point fill values need only be within machine epsilon of
+ * defined fill value.
+ */
+static void
+printfval(
+ char *sout, /* string where output goes */
+ const char *fmt, /* printf format used for value */
+ const struct ncvar *varp, /* variable */
+ float val /* value */
+ )
+{
+ if(varp->has_fillval) {
+ double fillval = varp->fillval;
+ if((val > 0) == (fillval > 0) && /* prevents potential overflow */
+ (absval(val - fillval) <= absval(float_eps * fillval))) {
+ (void) sprintf(sout, FILL_STRING);
+ return;
+ }
+ }
+ (void) sprintf(sout, fmt, val);
+}
+
+
+/*
+ * Output a value of a double variable, except if there is a fill value for
+ * the variable and the value is the fill value, print the fill-value string
+ * instead. Floating-point fill values need only be within machine epsilon of
+ * defined fill value.
+ */
+static void
+printdval(
+ char *sout, /* string where output goes */
+ const char *fmt, /* printf format used for value */
+ const struct ncvar *varp, /* variable */
+ double val /* value */
+ )
+{
+ if(varp->has_fillval) {
+ double fillval = varp->fillval;
+ if((val > 0) == (fillval > 0) && /* prevents potential overflow */
+ (absval(val - fillval) <= absval(double_eps * fillval))) {
+ (void) sprintf(sout, FILL_STRING);
+ return;
+ }
+ }
+ (void) sprintf(sout, fmt, val);
+}
+
+
+/*
+ * print last delimiter in each line before annotation (, or ;)
+ */
+static void
+lastdelim (boolean more, boolean lastrow)
+{
+ if (more) {
+ Printf(", ");
+ } else {
+ if(lastrow) {
+ Printf(";");
+ } else {
+ Printf(",");
+ }
+ }
+}
+
+/*
+ * print last delimiter in each line before annotation (, or ;)
+ */
+static void
+lastdelim2 (boolean more, boolean lastrow)
+{
+ if (more) {
+ lput(", ");
+ } else {
+ if(lastrow) {
+ lput(" ;");
+ lput("\n");
+ } else {
+ lput(",\n");
+ lput(" ");
+ }
+ }
+}
+
+
+/*
+ * Annotates a value in data section with var name and indices in comment
+ */
+static void
+annotate(
+ const struct ncvar *vp, /* variable */
+ const struct fspec* fsp, /* formatting specs */
+ const MPI_Offset *cor, /* corner coordinates */
+ long iel /* which element in current row */
+ )
+{
+ int vrank = vp->ndims;
+ int id;
+
+ /* print indices according to data_lang */
+ (void) printf(" // %s(", vp->name);
+ switch (fsp->data_lang) {
+ case LANG_C:
+ /* C variable indices */
+ for (id = 0; id < vrank-1; id++)
+ Printf("%lu,", (unsigned long) cor[id]);
+ Printf("%lu", (unsigned long) cor[id] + iel);
+ break;
+ case LANG_F:
+ /* Fortran variable indices */
+ Printf("%lu", (unsigned long) cor[vrank-1] + iel + 1);
+ for (id = vrank-2; id >=0 ; id--) {
+ Printf(",%lu", 1 + (unsigned long) cor[id]);
+ }
+ break;
+ }
+ Printf(")\n ");
+}
+
+
+/*
+ * Print a number of char variable values, where the optional comments
+ * for each value identify the variable, and each dimension index.
+ */
+static void
+pr_tvals(
+ const struct ncvar *vp, /* variable */
+ size_t len, /* number of values to print */
+ const char *fmt, /* printf format used for each value. If
+ * ncmpi_type is NC_CHAR and this is NULL,
+ * character arrays will be printed as
+ * strings enclosed in quotes. */
+ boolean more, /* true if more data for this row will
+ * follow, so add trailing comma */
+ boolean lastrow, /* true if this is the last row for this
+ * variable, so terminate with ";" instead
+ * of "," */
+ const char *vals, /* pointer to block of values */
+ const struct fspec* fsp, /* formatting specs */
+ const MPI_Offset *cor /* corner coordinates */
+ )
+{
+ long iel;
+ const char *sp;
+ unsigned char uc;
+ char sout[100]; /* temporary string for each encoded output */
+
+ if (fmt == 0 || STREQ(fmt,"%s") || STREQ(fmt,"")) { /* as string */
+ Printf("\"");
+ /* adjust len so trailing nulls don't get printed */
+ sp = vals + len;
+ while (len != 0 && *--sp == '\0')
+ len--;
+ for (iel = 0; iel < len; iel++)
+ switch (uc = *vals++ & 0377) {
+ case '\b':
+ Printf("\\b");
+ break;
+ case '\f':
+ Printf("\\f");
+ break;
+ case '\n': /* generate linebreaks after new-lines */
+ Printf("\\n\",\n \"");
+ break;
+ case '\r':
+ Printf("\\r");
+ break;
+ case '\t':
+ Printf("\\t");
+ break;
+ case '\v':
+ Printf("\\v");
+ break;
+ case '\\':
+ Printf("\\\\");
+ break;
+ case '\'':
+ Printf("\\\'");
+ break;
+ case '\"':
+ Printf("\\\"");
+ break;
+ default:
+ if (isprint(uc))
+ Printf("%c",uc);
+ else
+ Printf("\\%.3o",uc);
+ break;
+ }
+ Printf("\"");
+ if (fsp->full_data_cmnts) {
+ Printf("\"");
+ lastdelim (more, lastrow);
+ annotate (vp, fsp, (MPI_Offset*)cor, 0L);
+ }
+ } else { /* use format from C_format attribute */
+ for (iel = 0; iel < len-1; iel++) {
+ if (fsp->full_data_cmnts) {
+ Printf(fmt, *vals++);
+ Printf(", ");
+ annotate (vp, fsp, (MPI_Offset *)cor, iel);
+ } else {
+ (void) sprintf(sout, fmt, *vals++);
+ (void) strcat(sout, ", ");
+ lput(sout);
+ }
+ }
+ if (fsp->full_data_cmnts) {
+ Printf(fmt, *vals++);
+ lastdelim (more, lastrow);
+ annotate (vp, fsp, (MPI_Offset *)cor, iel);
+ } else {
+ (void) sprintf(sout, fmt, *vals++);
+ lput(sout);
+ }
+ }
+ if (!fsp->full_data_cmnts) {
+ lastdelim2 (more, lastrow);
+ }
+}
+
+
+/*
+ * Print a number of byte variable values, where the optional comments
+ * for each value identify the variable, and each dimension index.
+ */
+#define PR_VALS(fn, type) \
+static void \
+pr_##fn##vals(const struct ncvar *vp, /* variable */ \
+ size_t len, /* number of values to print */ \
+ const char *fmt, /* printf format used for each \
+ value. If ncmpi_type is NC_CHAR \
+ and this is NULL, character \
+ arrays will be printed as \
+ strings enclosed in quotes. */ \
+ boolean more, /* true if more data for this row \
+ will follow, so add trailing \
+ comma */ \
+ boolean lastrow,/* true if this is the last row \
+ for this variable, so terminate \
+ with ";" instead of "," */ \
+ const type *vals, /* pointer to block of values */ \
+ const struct fspec *fsp, /* formatting specs */ \
+ const MPI_Offset *cor) /* corner coordinates */ \
+{ \
+ long iel; \
+ char sout[100]; /* temporary string for each encoded output */ \
+ \
+ for (iel = 0; iel < len-1; iel++) { \
+ print##fn##val(sout, fmt, vp, *vals++); \
+ if (fsp->full_data_cmnts) { \
+ Printf("%s", sout); \
+ Printf(","); \
+ annotate (vp, fsp, cor, iel); \
+ } else { \
+ (void) strcat(sout, ", "); \
+ lput(sout); \
+ } \
+ } \
+ print##fn##val(sout, fmt, vp, *vals++); \
+ if (fsp->full_data_cmnts) { \
+ Printf("%s", sout); \
+ lastdelim (more, lastrow); \
+ annotate (vp, fsp, cor, iel); \
+ } else { \
+ lput(sout); \
+ lastdelim2 (more, lastrow); \
+ } \
+}
+
+/*----< pr_bvals() >----------------------------------------------------------*/
+/*----< pr_ubvals() >---------------------------------------------------------*/
+/*----< pr_svals() >----------------------------------------------------------*/
+/*----< pr_usvals() >---------------------------------------------------------*/
+/*----< pr_ivals() >----------------------------------------------------------*/
+/*----< pr_uivals() >---------------------------------------------------------*/
+/*----< pr_fvals() >----------------------------------------------------------*/
+/*----< pr_dvals() >----------------------------------------------------------*/
+/*----< pr_llvals() >---------------------------------------------------------*/
+/*----< pr_ullvals() >--------------------------------------------------------*/
+PR_VALS(b, signed char)
+PR_VALS(ub, unsigned char)
+PR_VALS(s, short)
+PR_VALS(us, unsigned short)
+PR_VALS(i, int)
+PR_VALS(ui, unsigned int)
+PR_VALS(f, float)
+PR_VALS(d, double)
+PR_VALS(ll, long long)
+PR_VALS(ull, unsigned long long)
+
+/*
+ * Updates a vector of ints, odometer style. Returns 0 if odometer
+ * overflowed, else 1.
+ */
+static int
+upcorner(
+ const size_t *dims, /* The "odometer" limits for each dimension */
+ int ndims, /* Number of dimensions */
+ MPI_Offset* odom, /* The "odometer" vector to be updated */
+ const size_t* add /* A vector to "add" to odom on each update */
+ )
+{
+ int id;
+ int ret = 1;
+
+ for (id = ndims-1; id > 0; id--) {
+ odom[id] += add[id];
+ if(odom[id] >= dims[id]) {
+ odom[id-1]++;
+ odom[id] -= dims[id];
+ }
+ }
+ odom[0] += add[0];
+ if (odom[0] >= dims[0])
+ ret = 0;
+ return ret;
+}
+
+
+/* Output the data for a single variable, in CDL syntax. */
+int
+vardata(
+ const struct ncvar *vp, /* variable */
+ size_t vdims[], /* variable dimension sizes */
+ int ncid, /* netcdf id */
+ int varid, /* variable id */
+ const struct fspec* fsp /* formatting specs */
+ )
+{
+ MPI_Offset cor[NC_MAX_DIMS]; /* corner coordinates */
+ MPI_Offset edg[NC_MAX_DIMS]; /* edges of hypercube */
+ size_t add[NC_MAX_DIMS]; /* "odometer" increment to next "row" */
+
+ int id;
+ int ir;
+ MPI_Offset nels;
+ MPI_Offset ncols;
+ MPI_Offset nrows;
+ int vrank = vp->ndims;
+ static int initeps = 0;
+
+ /* printf format used to print each value */
+ const char *fmt = get_fmt(ncid, varid, vp->type);
+
+#define VALBUFSIZ 1048576
+ double *vals ; /* aligned buffer */
+ int xsz=1; /* variable element size in byte */
+ int gulp;
+
+ switch(vp->type) {
+ case NC_CHAR:
+ case NC_BYTE:
+ case NC_UBYTE:
+ xsz = 1;
+ break;
+ case NC_SHORT:
+ case NC_USHORT:
+ xsz = 2;
+ break;
+ case NC_INT:
+ case NC_UINT:
+ case NC_FLOAT:
+ xsz = 4;
+ break;
+ case NC_DOUBLE:
+ case NC_INT64:
+ case NC_UINT64:
+ xsz = 8;
+ break;
+ default:
+ error("vardata: bad type");
+ }
+ gulp = VALBUFSIZ / xsz;
+ vals = (double*) malloc(VALBUFSIZ);
+
+ if (!initeps) { /* make sure epsilons get initialized */
+ init_epsilons();
+ initeps = 1;
+ }
+
+ nels = 1;
+ for (id = 0; id < vrank; id++) {
+ cor[id] = 0;
+ edg[id] = 1;
+ nels *= vdims[id]; /* total number of values for variable */
+ }
+
+ if (vrank <= 1) {
+ Printf("\n %s = ", vp->name);
+ set_indent ((int)strlen(vp->name) + 4);
+ } else {
+ Printf("\n %s =\n ", vp->name);
+ set_indent (2);
+ }
+
+ if (vrank < 1) {
+ ncols = 1;
+ } else {
+ ncols = vdims[vrank-1]; /* size of "row" along last dimension */
+ edg[vrank-1] = vdims[vrank-1];
+ for (id = 0; id < vrank; id++)
+ add[id] = 0;
+ if (vrank > 1)
+ add[vrank-2] = 1;
+ }
+ nrows = nels/ncols; /* number of "rows" */
+
+ for (ir = 0; ir < nrows; ir++) {
+ /*
+ * rather than just printing a whole row at once (which might exceed
+ * the capacity of MSDOS platforms, for example), we break each row
+ * into smaller chunks, if necessary.
+ */
+ size_t corsav = 0;
+ int left = (int)ncols;
+ boolean lastrow;
+
+ if (vrank > 0) {
+ corsav = cor[vrank-1];
+ if (fsp->brief_data_cmnts != false
+ && vrank > 1
+ && left > 0) { /* print brief comment with indices range */
+ Printf("// %s(",vp->name);
+ switch (fsp->data_lang) {
+ case LANG_C:
+ /* print brief comment with C variable indices */
+ for (id = 0; id < vrank-1; id++)
+ Printf("%lu,", (unsigned long)cor[id]);
+ if (vdims[vrank-1] == 1)
+ Printf("0");
+ else
+ Printf(" 0-%lu", (unsigned long)vdims[vrank-1]-1);
+ break;
+ case LANG_F:
+ /* print brief comment with Fortran variable indices */
+ if (vdims[vrank-1] == 1)
+ Printf("1");
+ else
+ Printf("1-%lu ", (unsigned long)vdims[vrank-1]);
+ for (id = vrank-2; id >=0 ; id--) {
+ Printf(",%lu", (unsigned long)(1 + cor[id]));
+ }
+ break;
+ }
+ Printf(")\n ");
+ set_indent(4);
+ }
+ }
+ lastrow = (boolean)(ir == nrows-1);
+ while (left > 0) {
+ size_t toget = left < gulp ? left : gulp;
+ if (vrank > 0)
+ edg[vrank-1] = toget;
+ switch(vp->type) {
+ case NC_CHAR:
+ NC_CHECK(
+ ncmpi_get_vara_text_all(ncid, varid, cor, edg, (char *)vals) );
+ pr_tvals(vp, toget, fmt, left > toget, lastrow,
+ (char *) vals, fsp, cor);
+ break;
+ case NC_BYTE:
+ NC_CHECK(
+ ncmpi_get_vara_schar_all(ncid, varid, cor, edg, (signed char *)vals) );
+ pr_bvals(vp, toget, fmt, left > toget, lastrow,
+ (signed char *) vals, fsp, cor);
+ break;
+ case NC_SHORT:
+ NC_CHECK(
+ ncmpi_get_vara_short_all(ncid, varid, cor, edg, (short *)vals) );
+ pr_svals(vp, toget, fmt, left > toget, lastrow,
+ (short *) vals, fsp, cor);
+ break;
+ case NC_INT:
+ NC_CHECK(
+ ncmpi_get_vara_int_all(ncid, varid, cor, edg, (int *)vals) );
+ pr_ivals(vp, toget, fmt, left > toget, lastrow,
+ (int *) vals, fsp, cor);
+ break;
+ case NC_FLOAT:
+ NC_CHECK(
+ ncmpi_get_vara_float_all(ncid, varid, cor, edg, (float *)vals) );
+ pr_fvals(vp, toget, fmt, left > toget, lastrow,
+ (float *) vals, fsp, cor);
+ break;
+ case NC_DOUBLE:
+ NC_CHECK(
+ ncmpi_get_vara_double_all(ncid, varid, cor, edg, (double *)vals) );
+ pr_dvals(vp, toget, fmt, left > toget, lastrow,
+ (double *) vals, fsp, cor);
+ break;
+ case NC_UBYTE:
+ NC_CHECK(
+ ncmpi_get_vara_uchar_all(ncid, varid, cor, edg, (unsigned char *)vals) );
+ pr_ubvals(vp, toget, fmt, left > toget, lastrow,
+ (unsigned char *) vals, fsp, cor);
+ break;
+ case NC_USHORT:
+ NC_CHECK(
+ ncmpi_get_vara_ushort_all(ncid, varid, cor, edg, (unsigned short *)vals) );
+ pr_usvals(vp, toget, fmt, left > toget, lastrow,
+ (unsigned short *) vals, fsp, cor);
+ break;
+ case NC_UINT:
+ NC_CHECK(
+ ncmpi_get_vara_uint_all(ncid, varid, cor, edg, (unsigned int *)vals) );
+ pr_uivals(vp, toget, fmt, left > toget, lastrow,
+ (unsigned int *) vals, fsp, cor);
+ break;
+ case NC_INT64:
+ NC_CHECK(
+ ncmpi_get_vara_longlong_all(ncid, varid, cor, edg, (long long *)vals) );
+ pr_llvals(vp, toget, fmt, left > toget, lastrow,
+ (long long *) vals, fsp, cor);
+ break;
+ case NC_UINT64:
+ NC_CHECK(
+ ncmpi_get_vara_ulonglong_all(ncid, varid, cor, edg, (unsigned long long *)vals) );
+ pr_ullvals(vp, toget, fmt, left > toget, lastrow,
+ (unsigned long long *) vals, fsp, cor);
+ break;
+ default:
+ error("vardata: bad type");
+ }
+ left -= toget;
+ if (vrank > 0)
+ cor[vrank-1] += toget;
+ }
+ if (vrank > 0)
+ cor[vrank-1] = corsav;
+ if (ir < nrows-1)
+ if (!upcorner(vdims,vp->ndims,cor,add))
+ error("vardata: odometer overflowed!");
+ set_indent(2);
+
+ /* to avoid residue contents from previous read, especially
+ when read beyond the end of file (i.e. read size returned 0) */
+ memset(vals, 0, VALBUFSIZ);
+ }
+ free(vals);
+
+ return 0;
+}
diff --git a/src/utils/ncmpidump/vardata.h b/src/utils/ncmpidump/vardata.h
new file mode 100644
index 0000000..c0cb5bd
--- /dev/null
+++ b/src/utils/ncmpidump/vardata.h
@@ -0,0 +1,28 @@
+/*********************************************************************
+ * Copyright 1993, University Corporation for Atmospheric Research
+ * See netcdf/COPYRIGHT file for copying and redistribution conditions.
+ * $Header$
+ *********************************************************************/
+/* $Id: vardata.h 1468 2013-10-26 16:53:18Z wkliao $ */
+
+extern char *progname; /* for error messages */
+
+/* Display for user-defined fill values and default floating-point fill
+ values; should match what ncgen looks for in ../ncgen/ncgen.l */
+#define FILL_STRING "_"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Output the data for a single variable, in CDL syntax. */
+extern int vardata ( const struct ncvar*, /* variable */
+ size_t [], /* variable dimension lengths */
+ int, /* netcdf id */
+ int, /* variable id */
+ const struct fspec* /* formatting specs */
+ );
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/src/utils/ncmpigen/Makefile.in b/src/utils/ncmpigen/Makefile.in
new file mode 100644
index 0000000..18b1011
--- /dev/null
+++ b/src/utils/ncmpigen/Makefile.in
@@ -0,0 +1,179 @@
+#
+# Copyright (C) 2012, Northwestern University and Argonne National Laboratory
+# See COPYRIGHT notice in top-level directory.
+#
+# $Id: Makefile.in 2264 2015-12-22 15:42:59Z wkliao $
+#
+# @configure_input@
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+include ../../../macros.make
+
+lex = @LEX@ -Pncmpi
+yacc = @YACC@ -p ncmpi
+
+NCMPIDUMP = ../ncmpidump/ncmpidump
+PROGRAM = ncmpigen
+MANUAL = ncmpigen.1
+
+# For VPATH build:
+# Add ../../lib into search path because ../../lib/pnetcdf.h is created in
+# the build directory at configure time and is included by C files here.
+INCLUDES = -I$(srcdir) -I../../lib
+
+LDFLAGS += -L../../lib
+LIBS := -lpnetcdf $(LIBS) @LCOV_LIB@
+
+C_SOURCES = main.c load.c escapes.c getfill.c init.c genlib.c ncmpigentab.c
+HEADERS = generic.h genlib.h ncmpigen.h ncmpigentab.h
+
+PROGRAM_SRCS = $(C_SOURCES)
+
+OBJS = $(PROGRAM_SRCS:.c=.o)
+
+PACKING_LIST = $(C_SOURCES) $(HEADERS) $(MANUAL) \
+ ncmpigenyy.c depend Makefile.in \
+ ncmpigen.l ncmpigen.y c0.cdl
+
+GARBAGE = $(PROGRAM) \
+ c0.nc c1.cdl c1.nc c2.cdl \
+ f0.nc \
+ ctest.c ctest ctest0.nc ctest1.cdl \
+ ftest.f ftest ftest0.nc ftest1.cdl \
+ lex.ncmpi.c y.tab.c y.tab.h
+
+all: $(PROGRAM)
+
+# generating the fortran does not work yet
+#test: $(PROGRAM) b-test c-test f-test FORCE
+test: $(PROGRAM) b-test c-test FORCE
+
+install: $(PROGRAM) $(MANUAL)
+ $(INSTALL) -d -m 755 $(MANDIR)/man1
+ $(INSTALL_DATA) $(srcdir)/$(MANUAL) $(MANDIR)/man1/$(MANUAL)
+
+ $(INSTALL) -d $(BINDIR)
+ $(INSTALL) -m 755 $(PROGRAM) $(BINDIR)/$(PROGRAM)
+
+uninstall:
+ $(RM) -f $(BINDIR)/$(PROGRAM)
+ $(RM) -f $(MANDIR)/man1/$(MANUAL)
+
+$(PROGRAM): $(OBJS) $(LIBRARY)
+ $(LINK.c) $(OBJS) $(LDFLAGS) $(LIBS)
+
+# Below is used if a PnetCDF developer wants to rebuild ncmpigenyy.c or
+# ncmpigentab.c. In that case, configure.in at the root directory needs
+# to check the availability of commands yacc/lex/bison. Otherwise the
+# below is never invoked, but records how to do it.
+$(srcdir)/ncmpigentab.c \
+$(srcdir)/ncmpigentab.h: ncmpigen.y ncmpigenyy.c ncmpigen.h
+ifeq (@have_yacc_lex@, yes)
+ $(yacc) -d $(srcdir)/ncmpigen.y; \
+ cp -f y.tab.c ncmpigentab.c; \
+ cp -f y.tab.h ncmpigentab.h
+else
+ @echo "Error: one of $? is modified, but cannot find bison or yacc, required to re-generate $@"
+endif
+
+ncmpigenyy.c: ncmpigen.l
+ifeq (@have_yacc_lex@, yes)
+ $(lex) $(srcdir)/ncmpigen.l; \
+ cp -f lex.ncmpi.c ncmpigenyy.c
+else
+ @echo "Error: $? is modified, but cannot find flex or lex, required to re-generate $@"
+endif
+
+vmstab.h \
+vmstab.c: ncmpigen.y
+ @echo 1>&2 "$@ is out-of-date with respect to $?"
+ @echo 1>&2 "It must be recreated via POSIX yacc(1) on a VMS system"
+ false
+vms_yy.c: ncmpigenyy.c
+ @echo 1>&2 "$@ is out-of-date with respect to $?"
+ @echo 1>&2 "It must be recreated via POSIX lex(1) on a VMS system"
+ false
+
+#
+# test "-b" option of ncmpigen
+#
+b-test: $(PROGRAM) c1.cdl
+ @./$(PROGRAM) -b c1.cdl && \
+ $(NCMPIDUMP) `pwd`/c1.nc > c2.cdl
+ @if diff c1.cdl c2.cdl; then \
+ echo "*** $(PROGRAM) -b test successful ***"; \
+ else \
+ echo "*** $(PROGRAM) -b test failed ***"; \
+ exit 1; \
+ fi
+
+#
+# test "-c" option of ncmpigen
+#
+c-test: $(PROGRAM) c1.cdl
+ ./$(PROGRAM) -c -o ctest0.nc $(srcdir)/c0.cdl > ctest.c && \
+ $(COMPILE.c) ctest.c && \
+ $(LINK.c) ctest.o -o ctest $(LDFLAGS) $(LIBS) && \
+ ./ctest && \
+ $(NCMPIDUMP) -n c1 `pwd`/ctest0.nc > ctest1.cdl
+ @if diff c1.cdl ctest1.cdl; then \
+ echo "*** $(PROGRAM) -c test successful ***"; \
+ else \
+ echo "*** $(PROGRAM) -c test failed ***"; \
+ exit 1; \
+ fi
+
+c1.cdl: $(PROGRAM) c0.cdl
+ ./$(PROGRAM) -b -o c0.nc $(srcdir)/c0.cdl
+ $(NCMPIDUMP) -n c1 `pwd`/c0.nc > $@
+
+#
+# test "-f" option of ncmpigen
+#
+f-test: $(PROGRAM) c0.cdl c1.cdl
+ @if [ -n "$(MPIF77)" ]; then \
+ $(MAKE) $(MFLAGS) ftest1.cdl && \
+ if diff c1.cdl ftest1.cdl; then \
+ echo "*** $(PROGRAM) -f test successful ***"; \
+ else \
+ echo "*** $(PROGRAM) -f test failed ***"; \
+ exit 1; \
+ fi; \
+ else \
+ echo 1>&2 "\`$@' not made because no FORTRAN compiler"; \
+ fi
+
+ftest1.cdl: $(PROGRAM) c0.cdl pnetcdf.inc
+ ./$(PROGRAM) -f -o ftest0.nc $(srcdir)/c0.cdl > ftest.f
+ $(COMPILE.f) ftest.f
+ $(LINK.f) -o ftest ftest.o $(LDFLAGS) $(LIBS)
+ ./ftest
+ $(NCMPIDUMP) -n c1 ftest0.nc > ftest1.cdl
+
+pnetcdf.inc:
+ @if [ -n "$(MPIF77)" ]; then \
+ cp $(srcdir)/../../libf/$@ .; \
+ else \
+ echo 1>&2 "\`$@' not made because no FORTRAN compiler"; \
+ fi
+
+$(PROGRAM)_src : $(PROGRAM_SRCS)
+ #setopt primary_language C
+ #load -C $(CPPFLAGS) $(PROGRAM_SRCS)
+ #load -C $(LIBS)
+ #load -C /usr/lang/SC2.0.1/libansi.a
+ #setopt program_name gribtonc
+
+$(PROGRAM)_obj : $(PROGRAM_SRCS)
+ #setopt primary_language C
+ #load -C $(CPPFLAGS) $(OBJS)
+ #load -C $(LIBS)
+ #setopt program_name gribtonc
+
+include $(srcdir)/../../../rules.make
+
+include $(srcdir)/depend
+
+.PHONY: $(LIBRARY)
diff --git a/src/utils/ncmpigen/c0.cdl b/src/utils/ncmpigen/c0.cdl
new file mode 100644
index 0000000..b1940c8
--- /dev/null
+++ b/src/utils/ncmpigen/c0.cdl
@@ -0,0 +1,331 @@
+netcdf c0 {
+dimensions:
+ Dr = UNLIMITED ; // (2 currently)
+ D1 = 1 ;
+ D2 = 2 ;
+ D3 = 3 ;
+ dim-name-dashes = 4 ;
+ dim.name.dots = 5 ;
+variables:
+ char c ;
+ c:att-name-dashes = 4 ;
+ c:att.name.dots = 5 ;
+ short s ;
+ s:b = 0b, 127b, -128b, -1b ;
+ s:s = -32768s, 0s, 32767s ;
+ int i ;
+ i:i = -2147483647, 0, 2147483647 ;
+ i:f = -1.e+36f, 0.f, 1.e+36f ;
+ i:d = -1.e+308, 0., 1.e+308 ;
+ float f ;
+ f:c = "x" ;
+ double d ;
+ d:c = "abcd\tZ$&" ;
+ char cr(Dr) ;
+ short sr(Dr) ;
+ int ir(Dr) ;
+ float fr(Dr) ;
+ double dr(Dr) ;
+ char c1(D1) ;
+ short s1(D1) ;
+ int i1(D1) ;
+ float f1(D1) ;
+ double d1(D1) ;
+ char c2(D2) ;
+ short s2(D2) ;
+ int i2(D2) ;
+ float f2(D2) ;
+ double d2(D2) ;
+ char c3(D3) ;
+ short s3(D3) ;
+ int i3(D3) ;
+ float f3(D3) ;
+ double d3(D3) ;
+ char cr1(Dr, D1) ;
+ short sr3(Dr, D3) ;
+ float f11(D1, D1) ;
+ double d12(D1, D2) ;
+ char c13(D1, D3) ;
+ short s21(D2, D1) ;
+ int i22(D2, D2) ;
+ float f23(D2, D3) ;
+ char c31(D3, D1) ;
+ short s33(D3, D3) ;
+ short sr11(Dr, D1, D1) ;
+ int ir12(Dr, D1, D2) ;
+ float fr13(Dr, D1, D3) ;
+ char cr21(Dr, D2, D1) ;
+ short sr23(Dr, D2, D3) ;
+ float fr31(Dr, D3, D1) ;
+ double dr32(Dr, D3, D2) ;
+ char cr33(Dr, D3, D3) ;
+ char c111(D1, D1, D1) ;
+ short s113(D1, D1, D3) ;
+ float f121(D1, D2, D1) ;
+ double d122(D1, D2, D2) ;
+ char c123(D1, D2, D3) ;
+ short s131(D1, D3, D1) ;
+ int i132(D1, D3, D2) ;
+ float f133(D1, D3, D3) ;
+ float f211(D2, D1, D1) ;
+ double d212(D2, D1, D2) ;
+ char c213(D2, D1, D3) ;
+ short s221(D2, D2, D1) ;
+ int i222(D2, D2, D2) ;
+ float f223(D2, D2, D3) ;
+ char c231(D2, D3, D1) ;
+ short s233(D2, D3, D3) ;
+ short s311(D3, D1, D1) ;
+ int i312(D3, D1, D2) ;
+ float f313(D3, D1, D3) ;
+ double var-name-dashes ;
+ double var.name.dots ;
+
+// global attributes:
+ :Gc = "" ;
+ :Gb = -128b, 127b ;
+ :Gs = -32768s, 0s, 32767s ;
+ :Gi = -2147483647, 0, 2147483647 ;
+ :Gf = -1.e+36f, 0.f, 1.e+36f ;
+ :Gd = -1.e+308, 0., 1.e+308 ;
+ :Gatt-name-dashes = -1 ;
+ :Gatt.name.dots = -2 ;
+data:
+
+ c = "2" ;
+
+ s = -5 ;
+
+ i = -20 ;
+
+ f = -9 ;
+
+ d = -10 ;
+
+ cr = "ab" ;
+
+ sr = -32768, 32767 ;
+
+ ir = -2147483646, 2147483647 ;
+
+ fr = -1e+36, 1e+36 ;
+
+ dr = -1e+308, 1e+308 ;
+
+ c1 = "" ;
+
+ s1 = -32768 ;
+
+ i1 = -2147483646 ;
+
+ f1 = -1e+36 ;
+
+ d1 = -1e+308 ;
+
+ c2 = "ab" ;
+
+
+ s2 = -32768, 32767 ;
+
+ i2 = -2147483646, 2147483647 ;
+
+ f2 = -1e+36, 1e+36 ;
+
+ d2 = -1e+308, 1e+308 ;
+
+ c3 = "\001\300." ;
+
+ s3 = -32768, 0, 32767 ;
+
+ i3 = -2147483646, 0, 2147483647 ;
+
+ f3 = -1e+36, 0, 1e+36 ;
+
+ d3 = -1e+308, 0, 1e+308 ;
+
+ cr1 =
+ "x",
+ "y" ;
+
+ sr3 =
+ -375, -380, -385,
+ -350, -355, -360 ;
+
+ f11 =
+ -2187 ;
+
+ d12 =
+ -3000, -3010 ;
+
+ c13 =
+ "\tb\177" ;
+
+ s21 =
+ -375,
+ -350 ;
+
+ i22 =
+ -24000, -24020,
+ -23600, -23620 ;
+
+ f23 =
+ -2187, -2196, -2205,
+ -2106, -2115, -2124 ;
+
+ c31 =
+ "+",
+ "-",
+ " " ;
+
+ s33 =
+ -375, -380, -385,
+ -350, -355, -360,
+ -325, -330, -335 ;
+
+ sr11 =
+ 2500,
+ 2375 ;
+
+ ir12 =
+ 640000, 639980,
+ 632000, 631980 ;
+
+ fr13 =
+ 26244, 26235, 26226,
+ 25515, 25506, 25497 ;
+
+ cr21 =
+ "@",
+ "D",
+ "H",
+ "L" ;
+
+ sr23 =
+ 2500, 2495, 2490,
+ 2525, 2520, 2515,
+ 2375, 2370, 2365,
+ 2400, 2395, 2390 ;
+
+ fr31 =
+ 26244,
+ 26325,
+ 26406,
+ 25515,
+ 25596,
+ 25677 ;
+
+ dr32 =
+ 40000, 39990,
+ 40100, 40090,
+ 40200, 40190,
+ 39000, 38990,
+ 39100, 39090,
+ 39200, 39190 ;
+
+ cr33 =
+ "1",
+ "two",
+ "3",
+ "4",
+ "5",
+ "six" ;
+
+ c111 =
+ "@" ;
+
+ s113 =
+ 2500, 2495, 2490 ;
+
+ f121 =
+ 26244,
+ 26325 ;
+
+ d122 =
+ 40000, 39990,
+ 40100, 40090 ;
+
+ c123 =
+ "one",
+ "2" ;
+
+ s131 =
+ 2500,
+ 2525,
+ 2550 ;
+
+ i132 =
+ 640000, 639980,
+ 640400, 640380,
+ 640800, 640780 ;
+
+ f133 =
+ 26244, 26235, 26226,
+ 26325, 26316, 26307,
+ 26406, 26397, 26388 ;
+
+ f211 =
+ 26244,
+ 25515 ;
+
+ d212 =
+ 40000, 39990,
+ 39000, 38990 ;
+
+// The following trips a bug on Cray T3E, but should work on other platforms
+// c213 =
+// "1",
+// "two" ;
+
+ s221 =
+ 2500,
+ 2525,
+ 2375,
+ 2400 ;
+
+ i222 =
+ 640000, 639980,
+ 640400, 640380,
+ 632000, 631980,
+ 632400, 632380 ;
+
+ f223 =
+ 26244, 26235, 26226,
+ 26325, 26316, 26307,
+ 25515, 25506, 25497,
+ 25596, 25587, 25578 ;
+
+ c231 =
+ "@",
+ "D",
+ "H",
+ "H",
+ "L",
+ "P" ;
+
+ s233 =
+ 2500, 2495, 2490,
+ 2525, 2520, 2515,
+ 2550, 2545, 2540,
+ 2375, 2370, 2365,
+ 2400, 2395, 2390,
+ 2425, 2420, 2415 ;
+
+ s311 =
+ 2500,
+ 2375,
+ 2250 ;
+
+ i312 =
+ 640000, 639980,
+ 632000, 631980,
+ 624000, 623980 ;
+
+ f313 =
+ 26244, 26235, 26226,
+ 25515, 25506, 25497,
+ 24786, 24777, 24768 ;
+
+ var-name-dashes = -1 ;
+
+ var.name.dots = -2 ;
+}
diff --git a/src/utils/ncmpigen/depend b/src/utils/ncmpigen/depend
new file mode 100644
index 0000000..d3ca56f
--- /dev/null
+++ b/src/utils/ncmpigen/depend
@@ -0,0 +1,9 @@
+escapes.o: escapes.c generic.h ncmpigen.h genlib.h ../../lib/pnetcdf.h
+genlib.o: genlib.c generic.h ncmpigen.h genlib.h ../../lib/pnetcdf.h
+getfill.o: getfill.c generic.h ncmpigen.h genlib.h ../../lib/pnetcdf.h
+init.o: init.c generic.h ncmpigen.h genlib.h ../../lib/pnetcdf.h
+load.o: load.c generic.h ncmpigen.h genlib.h ../../lib/pnetcdf.h
+main.o: main.c generic.h ncmpigen.h genlib.h ../../lib/pnetcdf.h
+ncmpigenyy.o: ncmpigenyy.c genlib.h ncmpigentab.h ../../lib/pnetcdf.h
+ncmpigentab.o: ncmpigentab.c generic.h ncmpigen.h genlib.h ncmpigenyy.c \
+ ncmpigentab.h ../../lib/pnetcdf.h
diff --git a/src/utils/ncmpigen/escapes.c b/src/utils/ncmpigen/escapes.c
new file mode 100644
index 0000000..35686ba
--- /dev/null
+++ b/src/utils/ncmpigen/escapes.c
@@ -0,0 +1,96 @@
+/*********************************************************************
+ * Copyright 1993, UCAR/Unidata
+ * See netcdf/COPYRIGHT file for copying and redistribution conditions.
+ * $Header$
+ *********************************************************************/
+
+#include <stdlib.h>
+#include <pnetcdf.h>
+#include "generic.h"
+#include "ncmpigen.h"
+#include "genlib.h"
+
+/*
+ * "Expands" valid escape sequences in yystring (read by lex) into the
+ * apropriate characters in termstring. For example, the two character
+ * sequence "\t" in yystring would be converted into a single tab character
+ * in termstring. On return, termstring is properly terminated.
+ */
+
+void
+expand_escapes(
+ char *termstring, /* returned, with escapes expanded */
+ char *yytext,
+ int yyleng)
+{
+ char *s, *t, *endp;
+
+ yytext[yyleng-1]='\0'; /* don't copy quotes */
+ /* expand "\" escapes, e.g. "\t" to tab character */
+ s = termstring;
+ t = yytext+1;
+ while(*t) {
+ if (*t == '\\') {
+ t++;
+ switch (*t) {
+ case 'a':
+ *s++ = '\007'; t++; /* will use '\a' when STDC */
+ break;
+ case 'b':
+ *s++ = '\b'; t++;
+ break;
+ case 'f':
+ *s++ = '\f'; t++;
+ break;
+ case 'n':
+ *s++ = '\n'; t++;
+ break;
+ case 'r':
+ *s++ = '\r'; t++;
+ break;
+ case 't':
+ *s++ = '\t'; t++;
+ break;
+ case 'v':
+ *s++ = '\v'; t++;
+ break;
+ case '\\':
+ *s++ = '\\'; t++;
+ break;
+ case '?':
+ *s++ = '\177'; t++;
+ break;
+ case '\'':
+ *s++ = '\''; t++;
+ break;
+ case '\"':
+ *s++ = '\"'; t++;
+ break;
+ case 'x':
+ t++; /* now t points to one or more hex digits */
+ *s++ = (char) strtol(t, &endp, 16);
+ t = endp;
+ break;
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ /* t now points to octal digits */
+ *s++ = (char) strtol(t, &endp, 8);
+ t = endp;
+ break;
+ default:
+ *s++ = *t++;
+ break;
+ }
+ } else {
+ *s++ = *t++;
+ }
+ }
+ *s = '\0';
+ return;
+}
diff --git a/src/utils/ncmpigen/generic.h b/src/utils/ncmpigen/generic.h
new file mode 100644
index 0000000..5c84fff
--- /dev/null
+++ b/src/utils/ncmpigen/generic.h
@@ -0,0 +1,23 @@
+/*********************************************************************
+ * Copyright 1993, UCAR/Unidata
+ * See netcdf/COPYRIGHT file for copying and redistribution conditions.
+ * $Header$
+ *********************************************************************/
+
+#ifndef UD_GENERIC_H
+#define UD_GENERIC_H
+
+union generic { /* used to hold any kind of fill_value */
+ float floatv;
+ double doublev;
+ int intv;
+ short shortv;
+ char charv;
+ unsigned char ubytev;
+ unsigned short ushortv;
+ unsigned int uintv;
+ long long int64v;
+ unsigned long long uint64v;
+};
+
+#endif
diff --git a/src/utils/ncmpigen/genlib.c b/src/utils/ncmpigen/genlib.c
new file mode 100644
index 0000000..b159c64
--- /dev/null
+++ b/src/utils/ncmpigen/genlib.c
@@ -0,0 +1,2043 @@
+/*********************************************************************
+ * Copyright 1993, UCAR/Unidata
+ * See netcdf/COPYRIGHT file for copying and redistribution conditions.
+ * $Header$
+ *********************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h> /* for isprint() */
+#ifndef NO_STDARG
+#include <stdarg.h>
+#else
+/* try varargs instead */
+#include <varargs.h>
+#endif /* !NO_STDARG */
+#include <pnetcdf.h>
+#include "generic.h"
+#include "ncmpigen.h"
+#include "genlib.h"
+
+#include <mpi.h>
+extern char *netcdf_name; /* output netCDF filename, if on command line. */
+extern int netcdf_flag;
+extern int c_flag;
+extern int fortran_flag;
+extern int giantfile_flag;
+extern int giantvar_flag;
+extern int nofill_flag;
+
+int lineno = 1;
+int derror_count = 0;
+
+
+
+/* create netCDF from in-memory structure */
+static void
+gen_netcdf(
+ char *filename) /* name for output netcdf file */
+{
+ int idim, ivar, iatt;
+ int dimid;
+ int varid;
+ int stat;
+
+ if (giantfile_flag) {
+ stat = ncmpi_create(MPI_COMM_WORLD, filename,
+ NC_CLOBBER|NC_64BIT_OFFSET, MPI_INFO_NULL, &ncid);
+ } else if (giantvar_flag) {
+ stat = ncmpi_create(MPI_COMM_WORLD, filename,
+ NC_CLOBBER|NC_64BIT_DATA, MPI_INFO_NULL, &ncid);
+ } else {
+ stat = ncmpi_create(MPI_COMM_WORLD, filename,
+ NC_CLOBBER, MPI_INFO_NULL, &ncid);
+ }
+ check_err(stat, "ncmpi_create", __func__, __LINE__, __FILE__);
+
+ /* define dimensions from info in dims array */
+ for (idim = 0; idim < ndims; idim++) {
+ stat = ncmpi_def_dim(ncid, dims[idim].name, dims[idim].size, &dimid);
+ check_err(stat, "ncmpi_def_dim", __func__, __LINE__, __FILE__);
+ }
+
+ /* define variables from info in vars array */
+ for (ivar = 0; ivar < nvars; ivar++) {
+ stat = ncmpi_def_var(ncid,
+ vars[ivar].name,
+ vars[ivar].type,
+ vars[ivar].ndims,
+ vars[ivar].dims,
+ &varid);
+ check_err(stat, "ncmpi_def_var", __func__, __LINE__, __FILE__);
+ }
+
+ /* define attributes from info in atts array */
+ for (iatt = 0; iatt < natts; iatt++) {
+ varid = (atts[iatt].var == -1) ? NC_GLOBAL : atts[iatt].var;
+ switch(atts[iatt].type) {
+ case NC_BYTE:
+ stat = ncmpi_put_att_schar(ncid, varid, atts[iatt].name,
+ atts[iatt].type, atts[iatt].len,
+ (signed char *) atts[iatt].val);
+ break;
+ case NC_CHAR:
+ stat = ncmpi_put_att_text(ncid, varid, atts[iatt].name,
+ atts[iatt].len,
+ (char *) atts[iatt].val);
+ break;
+ case NC_SHORT:
+ stat = ncmpi_put_att_short(ncid, varid, atts[iatt].name,
+ atts[iatt].type, atts[iatt].len,
+ (short *) atts[iatt].val);
+ break;
+ case NC_INT:
+ stat = ncmpi_put_att_int(ncid, varid, atts[iatt].name,
+ atts[iatt].type, atts[iatt].len,
+ (int *) atts[iatt].val);
+ break;
+ case NC_FLOAT:
+ stat = ncmpi_put_att_float(ncid, varid, atts[iatt].name,
+ atts[iatt].type, atts[iatt].len,
+ (float *) atts[iatt].val);
+ break;
+ case NC_DOUBLE:
+ stat = ncmpi_put_att_double(ncid, varid, atts[iatt].name,
+ atts[iatt].type, atts[iatt].len,
+ (double *) atts[iatt].val);
+ break;
+ case NC_UBYTE:
+ stat = ncmpi_put_att_ubyte(ncid, varid, atts[iatt].name,
+ atts[iatt].type, atts[iatt].len,
+ (unsigned char *) atts[iatt].val);
+ break;
+ case NC_USHORT:
+ stat = ncmpi_put_att_ushort(ncid, varid, atts[iatt].name,
+ atts[iatt].type, atts[iatt].len,
+ (unsigned short *) atts[iatt].val);
+ break;
+ case NC_UINT:
+ stat = ncmpi_put_att_uint(ncid, varid, atts[iatt].name,
+ atts[iatt].type, atts[iatt].len,
+ (unsigned int *) atts[iatt].val);
+ break;
+ case NC_INT64:
+ stat = ncmpi_put_att_longlong(ncid, varid, atts[iatt].name,
+ atts[iatt].type, atts[iatt].len,
+ (long long *) atts[iatt].val);
+ break;
+ case NC_UINT64:
+ stat = ncmpi_put_att_ulonglong(ncid, varid, atts[iatt].name,
+ atts[iatt].type, atts[iatt].len,
+ (unsigned long long *) atts[iatt].val);
+ break;
+ default:
+ stat = NC_EBADTYPE;
+ }
+ check_err(stat, "ncmpi_put_att_xxx", __func__, __LINE__, __FILE__);
+ }
+
+ /* serial netcdf calls nc_set_fill(NC_NOFILL) here, but we do not
+ * implement that routine (NC_NOFILL is our default and only behavior) */
+
+ stat = ncmpi_enddef(ncid);
+ check_err(stat, "ncmpi_enddef", __func__, __LINE__, __FILE__);
+}
+
+
+/*
+ * Given a netcdf type, a pointer to a vector of values of that type,
+ * and the index of the vector element desired, returns a pointer to a
+ * malloced string representing the value in C.
+ */
+static char *
+cstring(
+ nc_type type, /* netCDF type code */
+ void *valp, /* pointer to vector of values */
+ int num) /* element of vector desired */
+{
+ static char *cp, *sp, ch;
+ signed char *bytep;
+ short *shortp;
+ int *intp;
+ float *floatp;
+ double *doublep;
+ unsigned char *ubytep;
+ unsigned short *ushortp;
+ unsigned int *uintp;
+ long long *int64p;
+ unsigned long long *uint64p;
+
+ switch (type) {
+ case NC_CHAR:
+ sp = cp = (char *) emalloc (7);
+ *cp++ = '\'';
+ ch = *((char *)valp + num);
+ switch (ch) {
+ case '\b': *cp++ = '\\'; *cp++ = 'b'; break;
+ case '\f': *cp++ = '\\'; *cp++ = 'f'; break;
+ case '\n': *cp++ = '\\'; *cp++ = 'n'; break;
+ case '\r': *cp++ = '\\'; *cp++ = 'r'; break;
+ case '\t': *cp++ = '\\'; *cp++ = 't'; break;
+ case '\v': *cp++ = '\\'; *cp++ = 'v'; break;
+ case '\\': *cp++ = '\\'; *cp++ = '\\'; break;
+ case '\'': *cp++ = '\\'; *cp++ = '\''; break;
+ default:
+ if (!isprint(ch)) {
+ static char octs[] = "01234567";
+ int rem = ((unsigned char)ch)%64;
+ *cp++ = '\\';
+ *cp++ = octs[((unsigned char)ch)/64]; /* to get, e.g. '\177' */
+ *cp++ = octs[rem/8];
+ *cp++ = octs[rem%8];
+ } else {
+ *cp++ = ch;
+ }
+ break;
+ }
+ *cp++ = '\'';
+ *cp = '\0';
+ return sp;
+
+ case NC_BYTE:
+ cp = (char *) emalloc (7);
+ bytep = (signed char *)valp;
+ /* Need to convert '\377' to -1, for example, on all platforms */
+ (void) sprintf(cp,"%d", (signed char) *(bytep+num));
+ return cp;
+
+ case NC_SHORT:
+ cp = (char *) emalloc (10);
+ shortp = (short *)valp;
+ (void) sprintf(cp,"%d",* (shortp + num));
+ return cp;
+
+ case NC_INT:
+ cp = (char *) emalloc (20);
+ intp = (int *)valp;
+ (void) sprintf(cp,"%d",* (intp + num));
+ return cp;
+
+ case NC_FLOAT:
+ cp = (char *) emalloc (20);
+ floatp = (float *)valp;
+ (void) sprintf(cp,"%.8g",* (floatp + num));
+ return cp;
+
+ case NC_DOUBLE:
+ cp = (char *) emalloc (20);
+ doublep = (double *)valp;
+ (void) sprintf(cp,"%.16g",* (doublep + num));
+ return cp;
+
+ case NC_UBYTE:
+ cp = (char *) emalloc (7);
+ ubytep = (unsigned char *)valp;
+ /* Need to convert '\377' to -1, for example, on all platforms */
+ (void) sprintf(cp,"%hhu", (unsigned char) *(ubytep+num));
+ return cp;
+
+ case NC_USHORT:
+ cp = (char *) emalloc (10);
+ ushortp = (unsigned short *)valp;
+ (void) sprintf(cp,"%hu",* (ushortp + num));
+ return cp;
+
+ case NC_UINT:
+ cp = (char *) emalloc (20);
+ uintp = (unsigned int *)valp;
+ (void) sprintf(cp,"%u",* (uintp + num));
+ return cp;
+
+ case NC_INT64:
+ cp = (char *) emalloc (20);
+ int64p = (long long *)valp;
+ (void) sprintf(cp,"%lld",* (int64p + num));
+ return cp;
+
+ case NC_UINT64:
+ cp = (char *) emalloc (20);
+ uint64p = (unsigned long long *)valp;
+ (void) sprintf(cp,"%llu",* (uint64p + num));
+ return cp;
+
+ default:
+ derror("cstring: bad type code");
+ return 0;
+ }
+}
+
+
+/*
+ * Generate C code for creating netCDF from in-memory structure.
+ */
+static void
+gen_c(
+ const char *filename)
+{
+ int idim, ivar, iatt, jatt, maxdims;
+ int vector_atts;
+ char *val_string;
+ char stmnt[C_MAX_STMNT];
+
+ /* wrap in main program */
+ cline("#include <stdio.h>");
+ cline("#include <stdlib.h>");
+ cline("#include <pnetcdf.h>");
+ cline("#include <mpi.h>");
+ cline("");
+ cline("void");
+ cline("check_err(int stat, const char *ncmpi_func, const char *calling_func, int lineno, const char *calling_file) {");
+ cline(" if (stat != NC_NOERR) {");
+ cline(" fprintf(stderr, \"ncmpigen error when calling %s in %s() at line %d of %s: %s\\n\", ncmpi_func, calling_func, lineno, calling_file, ncmpi_strerror(stat));");
+ cline(" exit(1);");
+ cline(" }");
+ cline("}");
+ cline("");
+ cline("int");
+ sprintf(stmnt, "main(int argc, char **argv) {\t\t\t/* create %s */", filename);
+ cline(stmnt);
+
+ /* create necessary declarations */
+ cline("");
+ cline(" int stat;\t\t\t/* return status */");
+ cline(" int ncid;\t\t\t/* netCDF id */");
+
+ if (ndims > 0) {
+ cline("");
+ cline(" /* dimension ids */");
+ for (idim = 0; idim < ndims; idim++) {
+ sprintf(stmnt, " int %s_dim;", dims[idim].lname);
+ cline(stmnt);
+ }
+
+ cline("");
+ cline(" /* dimension lengths */");
+ for (idim = 0; idim < ndims; idim++) {
+ if (dims[idim].size == NC_UNLIMITED) {
+ sprintf(stmnt, " MPI_Offset %s_len = NC_UNLIMITED;",
+ dims[idim].lname);
+ } else {
+ sprintf(stmnt, " MPI_Offset %s_len = %lu;",
+ dims[idim].lname,
+ (unsigned long) dims[idim].size);
+ }
+ cline(stmnt);
+ }
+ }
+
+ maxdims = 0; /* most dimensions of any variable */
+ for (ivar = 0; ivar < nvars; ivar++)
+ if (vars[ivar].ndims > maxdims)
+ maxdims = vars[ivar].ndims;
+
+ if (nvars > 0) {
+ cline("");
+ cline(" /* variable ids */");
+ for (ivar = 0; ivar < nvars; ivar++) {
+ sprintf(stmnt, " int %s_id;", vars[ivar].lname);
+ cline(stmnt);
+ }
+
+ cline("");
+ cline(" /* rank (number of dimensions) for each variable */");
+ for (ivar = 0; ivar < nvars; ivar++) {
+ sprintf(stmnt, "# define RANK_%s %d", vars[ivar].lname,
+ vars[ivar].ndims);
+ cline(stmnt);
+ }
+ if (maxdims > 0) { /* we have dimensioned variables */
+ cline("");
+ cline(" /* variable shapes */");
+ for (ivar = 0; ivar < nvars; ivar++) {
+ if (vars[ivar].ndims > 0) {
+ sprintf(stmnt, " int %s_dims[RANK_%s];",
+ vars[ivar].lname, vars[ivar].lname);
+ cline(stmnt);
+ }
+ }
+ }
+ }
+
+ /* determine if we need any attribute vectors */
+ vector_atts = 0;
+ for (iatt = 0; iatt < natts; iatt++) {
+ if (atts[iatt].type != NC_CHAR) {
+ vector_atts = 1;
+ break;
+ }
+ }
+ if (vector_atts) {
+ cline("");
+ cline(" /* attribute vectors */");
+ for (iatt = 0; iatt < natts; iatt++) {
+ if (atts[iatt].type != NC_CHAR) {
+ sprintf(stmnt,
+ " %s %s_%s[%lu];",
+ ncatype(atts[iatt].type),
+ atts[iatt].var == -1 ? "cdf" : vars[atts[iatt].var].lname,
+ atts[iatt].lname,
+ (unsigned long) atts[iatt].len);
+ cline(stmnt);
+ }
+ }
+ }
+
+ /* create netCDF file, uses NC_CLOBBER mode */
+ cline("");
+ /* stat already declared above */
+ cline(" MPI_Init(&argc, &argv);");
+ cline(" /* enter define mode */");
+
+ if (giantfile_flag) {
+ sprintf(stmnt,
+ " stat = ncmpi_create(MPI_COMM_WORLD, \"%s\", NC_CLOBBER|NC_64BIT_OFFSET, MPI_INFO_NULL, &ncid);",
+ filename);
+ } else if (giantvar_flag) {
+ sprintf(stmnt,
+ " stat = ncmpi_create(MPI_COMM_WORLD, \"%s\", NC_CLOBBER|NC_64BIT_DATA, MPI_INFO_NULL, &ncid);",
+ filename);
+ } else {
+ sprintf(stmnt, " stat = ncmpi_create(MPI_COMM_WORLD, \"%s\", NC_CLOBBER, MPI_INFO_NULL, &ncid);",
+ filename);
+ }
+ cline(stmnt);
+ cline(" check_err(stat,\"ncmpi_create\", __func__, __LINE__,__FILE__);");
+
+ /* define dimensions from info in dims array */
+ if (ndims > 0) {
+ cline("");
+ cline(" /* define dimensions */");
+ }
+ for (idim = 0; idim < ndims; idim++) {
+ sprintf(stmnt,
+ " stat = ncmpi_def_dim(ncid, \"%s\", %s_len, &%s_dim);",
+ dims[idim].name, dims[idim].lname, dims[idim].lname);
+ cline(stmnt);
+ cline(" check_err(stat,\"ncmpi_def_dim\", __func__, __LINE__,__FILE__);");
+ }
+
+ /* define variables from info in vars array */
+ if (nvars > 0) {
+ cline("");
+ cline(" /* define variables */");
+ for (ivar = 0; ivar < nvars; ivar++) {
+ cline("");
+ for (idim = 0; idim < vars[ivar].ndims; idim++) {
+ sprintf(stmnt,
+ " %s_dims[%d] = %s_dim;",
+ vars[ivar].lname,
+ idim,
+ dims[vars[ivar].dims[idim]].lname);
+ cline(stmnt);
+ }
+ if (vars[ivar].ndims > 0) { /* a dimensioned variable */
+ sprintf(stmnt,
+ " stat = ncmpi_def_var(ncid, \"%s\", %s, RANK_%s, %s_dims, &%s_id);",
+ vars[ivar].name,
+ nctype(vars[ivar].type),
+ vars[ivar].lname,
+ vars[ivar].lname,
+ vars[ivar].lname);
+ } else { /* a scalar */
+ sprintf(stmnt,
+ " stat = ncmpi_def_var(ncid, \"%s\", %s, RANK_%s, 0, &%s_id);",
+ vars[ivar].name,
+ nctype(vars[ivar].type),
+ vars[ivar].lname,
+ vars[ivar].lname);
+ }
+ cline(stmnt);
+ cline(" check_err(stat,\"ncmpi_def_var\", __func__, __LINE__,__FILE__);");
+ }
+ }
+
+ /* define attributes from info in atts array */
+ if (natts > 0) {
+ cline("");
+ cline(" /* assign attributes */");
+ for (iatt = 0; iatt < natts; iatt++) {
+ if (atts[iatt].type == NC_CHAR) { /* string */
+ val_string = cstrstr((char *) atts[iatt].val, atts[iatt].len);
+ sprintf(stmnt,
+ " stat = ncmpi_put_att_text(ncid, %s%s, \"%s\", %lu, %s);",
+ atts[iatt].var == -1 ? "NC_GLOBAL" : vars[atts[iatt].var].lname,
+ atts[iatt].var == -1 ? "" : "_id",
+ atts[iatt].name,
+ (unsigned long) atts[iatt].len,
+ val_string);
+ cline(stmnt);
+ free (val_string);
+ }
+ else { /* vector attribute */
+ for (jatt = 0; jatt < atts[iatt].len ; jatt++) {
+ val_string = cstring(atts[iatt].type,atts[iatt].val,jatt);
+ sprintf(stmnt, " %s_%s[%d] = %s;",
+ atts[iatt].var == -1 ? "cdf" : vars[atts[iatt].var].lname,
+ atts[iatt].lname,
+ jatt,
+ val_string);
+ cline(stmnt);
+ free (val_string);
+ }
+
+ sprintf(stmnt,
+ " stat = ncmpi_put_att_%s(ncid, %s%s, \"%s\", %s, %lu, %s_%s);",
+ ncatype(atts[iatt].type),
+ atts[iatt].var == -1 ? "NC_GLOBAL" : vars[atts[iatt].var].lname,
+ atts[iatt].var == -1 ? "" : "_id",
+ atts[iatt].name,
+ nctype(atts[iatt].type),
+ (unsigned long) atts[iatt].len,
+ atts[iatt].var == -1 ? "cdf" : vars[atts[iatt].var].lname,
+ atts[iatt].lname);
+ cline(stmnt);
+ }
+ cline(" check_err(stat,\"ncmpi_put_att_xxx\", __func__, __LINE__,__FILE__);");
+ }
+ }
+ /* here's another place where serial netcdf would insert a call to
+ * setfill(NOFILL), but that's our only supported behavior, so skip */
+ cline("");
+ cline(" /* leave define mode */");
+ cline(" stat = ncmpi_enddef (ncid);");
+ cline(" check_err(stat,\"ncmpi_enddef\", __func__, __LINE__,__FILE__);");
+}
+
+
+/* return Fortran type name for netCDF type, given type code */
+static const char *
+ncftype(
+ nc_type type) /* netCDF type code */
+{
+ switch (type) {
+
+ case NC_BYTE:
+ return "integer";
+ case NC_CHAR:
+ return "character";
+ case NC_SHORT:
+ return "integer";
+ case NC_INT:
+#ifdef MSDOS
+ return "integer*4";
+#else
+ return "integer";
+#endif
+ case NC_FLOAT:
+ return "real";
+#ifdef _CRAY
+ case NC_DOUBLE:
+ return "real"; /* we don't support CRAY 128-bit doubles */
+#else
+ case NC_DOUBLE:
+ return "double precision";
+#endif
+ default:
+ derror("ncftype: bad type code");
+ return 0;
+
+ }
+}
+
+
+/* return Fortran type suffix for netCDF type, given type code */
+const char *
+nfstype(
+ nc_type type) /* netCDF type code */
+{
+ switch (type) {
+ case NC_BYTE:
+ return "int1";
+ case NC_CHAR:
+ return "text";
+ case NC_SHORT:
+ return "int2";
+ case NC_INT:
+ return "int";
+ case NC_FLOAT:
+ return "real";
+ case NC_DOUBLE:
+ return "double";
+ default:
+ derror("nfstype: bad type code");
+ return 0;
+
+ }
+}
+
+
+/* Return Fortran function suffix for netCDF type, given type code.
+ * This should correspond to the Fortran type name in ncftype().
+ */
+const char *
+nfftype(
+ nc_type type) /* netCDF type code */
+{
+ switch (type) {
+ case NC_BYTE:
+ return "int";
+ case NC_CHAR:
+ return "text";
+ case NC_SHORT:
+ return "int";
+ case NC_INT:
+ return "int";
+ case NC_FLOAT:
+ return "real";
+#ifdef _CRAY
+ case NC_DOUBLE:
+ return "real"; /* we don't support CRAY 128-bit doubles */
+#else
+ case NC_DOUBLE:
+ return "double";
+#endif
+ default:
+ derror("nfstype: bad type code");
+ return 0;
+
+ }
+}
+
+
+/* return FORTRAN name for netCDF type, given type code */
+static const char *
+ftypename(
+ nc_type type) /* netCDF type code */
+{
+ switch (type) {
+ case NC_BYTE:
+ return "NF_INT1";
+ case NC_CHAR:
+ return "NF_CHAR";
+ case NC_SHORT:
+ return "NF_INT2";
+ case NC_INT:
+ return "NF_INT";
+ case NC_FLOAT:
+ return "NF_REAL";
+ case NC_DOUBLE:
+ return "NF_DOUBLE";
+ default:
+ derror("ftypename: bad type code");
+ return 0;
+ }
+}
+
+
+/*
+ * Generate FORTRAN code for creating netCDF from in-memory structure.
+ */
+static void
+gen_fortran(
+ const char *filename)
+{
+ int idim, ivar, iatt, jatt, itype, maxdims;
+ int vector_atts;
+ char *val_string;
+ char stmnt[FORT_MAX_STMNT];
+ char s2[NC_MAX_NAME + 10];
+ char *sp;
+ /* Need how many netCDF types there are, because we create an array
+ * for each type of attribute. */
+ int ntypes = 6; /* number of netCDF types, NC_BYTE, ... */
+ nc_type types[6]; /* at least ntypes */
+ MPI_Offset max_atts[NC_DOUBLE + 1];
+
+ types[0] = NC_BYTE;
+ types[1] = NC_CHAR;
+ types[2] = NC_SHORT;
+ types[3] = NC_INT;
+ types[4] = NC_FLOAT;
+ types[5] = NC_DOUBLE;
+
+ fline("program fgennc");
+
+ fline("include 'pnetcdf.inc'");
+
+ /* create necessary declarations */
+ fline("* error status return");
+ fline("integer iret");
+ fline("* netCDF id");
+ fline("integer ncid");
+ if (nofill_flag) {
+ fline(" * to save old fill mode before changing it temporarily");
+ fline ("integer oldmode");
+ }
+
+ if (ndims > 0) {
+ fline("* dimension ids");
+ for (idim = 0; idim < ndims; idim++) {
+ sprintf(stmnt, "integer %s_dim", dims[idim].lname);
+ fline(stmnt);
+ }
+
+ fline("* dimension lengths");
+ for (idim = 0; idim < ndims; idim++) {
+ sprintf(stmnt, "integer %s_len", dims[idim].lname);
+ fline(stmnt);
+ }
+ for (idim = 0; idim < ndims; idim++) {
+ if (dims[idim].size == NC_UNLIMITED) {
+ sprintf(stmnt, "parameter (%s_len = NFMPI_UNLIMITED)",
+ dims[idim].lname);
+ } else {
+ sprintf(stmnt, "parameter (%s_len = %lu)",
+ dims[idim].lname,
+ (unsigned long) dims[idim].size);
+ }
+ fline(stmnt);
+ }
+
+ }
+
+ maxdims = 0; /* most dimensions of any variable */
+ for (ivar = 0; ivar < nvars; ivar++)
+ if (vars[ivar].ndims > maxdims)
+ maxdims = vars[ivar].ndims;
+
+ if (nvars > 0) {
+ fline("* variable ids");
+ for (ivar = 0; ivar < nvars; ivar++) {
+ sprintf(stmnt, "integer %s_id", vars[ivar].lname);
+ fline(stmnt);
+ }
+
+ fline("* rank (number of dimensions) for each variable");
+ for (ivar = 0; ivar < nvars; ivar++) {
+ sprintf(stmnt, "integer %s_rank", vars[ivar].lname);
+ fline(stmnt);
+ }
+ for (ivar = 0; ivar < nvars; ivar++) {
+ sprintf(stmnt, "parameter (%s_rank = %d)", vars[ivar].lname,
+ vars[ivar].ndims);
+ fline(stmnt);
+ }
+
+ fline("* variable shapes");
+ for (ivar = 0; ivar < nvars; ivar++) {
+ if (vars[ivar].ndims > 0) {
+ sprintf(stmnt, "integer %s_dims(%s_rank)",
+ vars[ivar].lname, vars[ivar].lname);
+ fline(stmnt);
+ }
+ }
+ }
+
+ /* declarations for variables to be initialized */
+ if (nvars > 0) { /* we have variables */
+ fline("* data variables");
+ for (ivar = 0; ivar < nvars; ivar++) {
+ struct vars *v = &vars[ivar];
+ /* Generate declarations here for non-record data variables only.
+ Record variables are declared in separate subroutine later,
+ when we know how big they are. */
+ if (v->ndims > 0 && v->dims[0] == rec_dim) {
+ continue;
+ }
+ /* Make declarations for non-text variables only;
+ for text variables, just include string in nfmpi_put_var call */
+ if (v->type == NC_CHAR) {
+ continue;
+ }
+ if (v->ndims == 0) { /* scalar */
+ sprintf(stmnt, "%s %s", ncftype(v->type),
+ v->lname);
+ } else {
+ sprintf(stmnt, "%s %s(", ncftype(v->type),
+ v->lname);
+ /* reverse dimensions for FORTRAN */
+ for (idim = v->ndims-1; idim >= 0; idim--) {
+ sprintf(s2, "%s_len, ",
+ dims[v->dims[idim]].lname);
+ strcat(stmnt, s2);
+ }
+ sp = strrchr(stmnt, ',');
+ if(sp != NULL) {
+ *sp = '\0';
+ }
+ strcat(stmnt, ")");
+ }
+ fline(stmnt);
+ }
+ }
+
+ /* determine what attribute vectors needed */
+ for (itype = 0; itype < ntypes; itype++)
+ max_atts[(int)types[itype]] = 0;
+
+ vector_atts = 0;
+ for (iatt = 0; iatt < natts; iatt++) {
+ if (atts[iatt].len > max_atts[(int) atts[iatt].type]) {
+ max_atts[(int)atts[iatt].type] = atts[iatt].len;
+ vector_atts = 1;
+ }
+ }
+ if (vector_atts) {
+ fline("* attribute vectors");
+ for (itype = 0; itype < ntypes; itype++) {
+ if (types[itype] != NC_CHAR && max_atts[(int)types[itype]] > 0) {
+ sprintf(stmnt, "%s %sval(%lu)", ncftype(types[itype]),
+ nfstype(types[itype]),
+ (unsigned long) max_atts[(int)types[itype]]);
+ fline(stmnt);
+ }
+ }
+ }
+
+ /* create netCDF file, uses NC_CLOBBER mode */
+ fline("* enter define mode");
+ if (giantfile_flag) {
+ sprintf(stmnt, "iret = nfmpi_create(\'%s\', OR(NF_CLOBBER|NF_64BIT_OFFSET), ncid)", filename);
+ } else if (giantvar_flag) {
+ sprintf(stmnt, "iret = nfmpi_create(\'%s\', OR(NF_CLOBBER|NF_64BIT_DATA), ncid)", filename);
+ } else {
+ sprintf(stmnt, "iret = nfmpi_create(\'%s\', NF_CLOBBER, ncid)", filename);
+ }
+ fline(stmnt);
+ fline("call check_err(iret,\"nfmpi_create\", __func__, __LINE__,__FILE__)");
+
+ /* define dimensions from info in dims array */
+ if (ndims > 0)
+ fline("* define dimensions");
+ for (idim = 0; idim < ndims; idim++) {
+ if (dims[idim].size == NC_UNLIMITED)
+ sprintf(stmnt, "iret = nfmpi_def_dim(ncid, \'%s\', NFMPI_UNLIMITED, %s_dim)",
+ dims[idim].name, dims[idim].lname);
+ else
+ sprintf(stmnt, "iret = nfmpi_def_dim(ncid, \'%s\', %lu, %s_dim)",
+ dims[idim].name, (unsigned long) dims[idim].size,
+ dims[idim].lname);
+ fline(stmnt);
+ fline("call check_err(iret,\"nfmpi_def_dim\", __func__, __LINE__,__FILE__)");
+ }
+
+ /* define variables from info in vars array */
+ if (nvars > 0) {
+ fline("* define variables");
+ for (ivar = 0; ivar < nvars; ivar++) {
+ for (idim = 0; idim < vars[ivar].ndims; idim++) {
+ sprintf(stmnt, "%s_dims(%d) = %s_dim",
+ vars[ivar].lname,
+ vars[ivar].ndims - idim, /* reverse dimensions */
+ dims[vars[ivar].dims[idim]].lname);
+ fline(stmnt);
+ }
+ if (vars[ivar].ndims > 0) { /* a dimensioned variable */
+ sprintf(stmnt,
+ "iret = nfmpi_def_var(ncid, \'%s\', %s, %s_rank, %s_dims, %s_id)",
+ vars[ivar].name,
+ ftypename(vars[ivar].type),
+ vars[ivar].lname,
+ vars[ivar].lname,
+ vars[ivar].lname);
+ } else { /* a scalar */
+ sprintf(stmnt,
+ "iret = nfmpi_def_var(ncid, \'%s\', %s, %s_rank, 0, %s_id)",
+ vars[ivar].name,
+ ftypename(vars[ivar].type),
+ vars[ivar].lname,
+ vars[ivar].lname);
+ }
+ fline(stmnt);
+ fline("call check_err(iret,\"nfmpi_def_var\", __func__, __LINE__,__FILE__)");
+ }
+ }
+
+ /* define attributes from info in atts array */
+ if (natts > 0) {
+ fline("* assign attributes");
+ for (iatt = 0; iatt < natts; iatt++) {
+ if (atts[iatt].type == NC_CHAR) { /* string */
+ val_string = fstrstr((char *) atts[iatt].val, atts[iatt].len);
+ sprintf(stmnt,
+ "iret = nfmpi_put_att_text(ncid, %s%s, \'%s\', %lu, %s)",
+ atts[iatt].var == -1 ? "NF_GLOBAL" : vars[atts[iatt].var].lname,
+ atts[iatt].var == -1 ? "" : "_id",
+ atts[iatt].name,
+ (unsigned long) atts[iatt].len,
+ val_string);
+ fline(stmnt);
+ fline("call check_err(iret,\"nfmpi_put_att_text\", __func__, __LINE__,__FILE__)");
+ free(val_string);
+ } else {
+ for (jatt = 0; jatt < atts[iatt].len ; jatt++) {
+ val_string = fstring(atts[iatt].type,atts[iatt].val,jatt);
+ sprintf(stmnt, "%sval(%d) = %s",
+ nfstype(atts[iatt].type),
+ jatt+1,
+ val_string);
+ fline(stmnt);
+ free (val_string);
+ }
+
+ sprintf(stmnt,
+ "iret = nfmpi_put_att_%s(ncid, %s%s, \'%s\', %s, %lu, %sval)",
+ nfftype(atts[iatt].type),
+ atts[iatt].var == -1 ? "NCGLOBAL" : vars[atts[iatt].var].lname,
+ atts[iatt].var == -1 ? "" : "_id",
+ atts[iatt].name,
+ ftypename(atts[iatt].type),
+ (unsigned long) atts[iatt].len,
+ nfstype(atts[iatt].type));
+ fline(stmnt);
+ fline("call check_err(iret,\"nfmpi_put_att_xxx\", __func__, __LINE__,__FILE__)");
+ }
+ }
+ }
+ /* skip the call to nfmpi_set_fill until we implement it */
+ fline("* leave define mode");
+ fline("iret = nfmpi_enddef(ncid)");
+ fline("call check_err(iret,\"nfmpi_enddef\", __func__, __LINE__,__FILE__)");
+}
+
+
+/*
+ * Output a C statement.
+ */
+void
+cline(
+ const char *stmnt)
+{
+ FILE *cout = stdout;
+
+ fputs(stmnt, cout);
+ fputs("\n", cout);
+}
+
+/*
+ * From a long line FORTRAN statment, generates the necessary FORTRAN
+ * lines with continuation characters in column 6. If stmnt starts with "*",
+ * it is treated as a one-line comment. Statement labels are *not* handled,
+ * but since we don't generate any labels, we don't care.
+ */
+void
+fline(
+ const char *stmnt)
+{
+ FILE *fout = stdout;
+ int len = (int) strlen(stmnt);
+ int line = 0;
+ static char cont[] = { /* continuation characters */
+ ' ', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+ '+', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+ '+', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
+
+ if(stmnt[0] == '*') {
+ fputs(stmnt, fout);
+ fputs("\n", fout);
+ return;
+ }
+
+ while (len > 0) {
+ if (line >= FORT_MAX_LINES)
+ derror("FORTRAN statement too long: %s",stmnt);
+ (void) fprintf(fout, " %c", cont[line++]);
+ (void) fprintf(fout, "%.66s\n", stmnt);
+ len -= 66;
+ if (len > 0)
+ stmnt += 66;
+ }
+}
+
+
+/* return C name for netCDF type, given type code */
+const char *
+nctype(
+ nc_type type) /* netCDF type code */
+{
+ switch (type) {
+ case NC_BYTE: return "NC_BYTE";
+ case NC_CHAR: return "NC_CHAR";
+ case NC_SHORT: return "NC_SHORT";
+ case NC_INT: return "NC_INT";
+ case NC_FLOAT: return "NC_FLOAT";
+ case NC_DOUBLE: return "NC_DOUBLE";
+ case NC_UBYTE: return "NC_UBYTE";
+ case NC_USHORT: return "NC_USHORT";
+ case NC_UINT: return "NC_UINT";
+ case NC_INT64: return "NC_INT64";
+ case NC_UINT64: return "NC_UINT64";
+ default:
+ derror("nctype: bad type code");
+ return 0;
+ }
+}
+
+
+/*
+ * Return C type name for netCDF type, given type code.
+ */
+const char *
+ncctype(
+ nc_type type) /* netCDF type code */
+{
+ switch (type) {
+ case NC_BYTE:
+ return "signed char";
+ case NC_CHAR:
+ return "char";
+ case NC_SHORT:
+ return "short";
+ case NC_INT:
+ return "int";
+ case NC_FLOAT:
+ return "float";
+ case NC_DOUBLE:
+ return "double";
+ case NC_UBYTE:
+ return "unsigned char";
+ case NC_USHORT:
+ return "unsigned short";
+ case NC_UINT:
+ return "unsigned int";
+ case NC_INT64:
+ return "long long";
+ case NC_UINT64:
+ return "unsigned long long";
+ default:
+ derror("ncctype: bad type code");
+ return 0;
+ }
+}
+
+
+
+/*
+ * Return C type name for netCDF type suffix, given type code.
+ */
+const char *
+ncstype(
+ nc_type type) /* netCDF type code */
+{
+ switch (type) {
+ case NC_BYTE:
+ return "schar";
+ case NC_CHAR:
+ return "text";
+ case NC_SHORT:
+ return "short";
+ case NC_INT:
+ return "int";
+ case NC_FLOAT:
+ return "float";
+ case NC_DOUBLE:
+ return "double";
+ case NC_UBYTE:
+ return "uchar";
+ case NC_USHORT:
+ return "ushort";
+ case NC_UINT:
+ return "uint";
+ case NC_INT64:
+ return "longlong";
+ case NC_UINT64:
+ return "ulonglong";
+ default:
+ derror("ncstype: bad type code");
+ return 0;
+ }
+}
+
+
+/*
+ * Return C type name for netCDF attribute container type, given type code.
+ */
+const char *
+ncatype(
+ nc_type type) /* netCDF type code */
+{
+ switch (type) {
+ case NC_BYTE:
+ return "int"; /* avoids choosing between uchar and schar */
+ case NC_CHAR:
+ return "text";
+ case NC_SHORT:
+ return "short";
+ case NC_INT:
+ return "int";
+ case NC_FLOAT:
+ return "float";
+ case NC_DOUBLE:
+ return "double";
+ case NC_UBYTE: return "uchar";
+ case NC_USHORT: return "ushort";
+ case NC_UINT: return "uint";
+ case NC_INT64: return "ulonglong";
+ case NC_UINT64: return "longlong";
+ default:
+ derror("ncatype: bad type code");
+ return 0;
+ }
+}
+
+
+/* return internal size for values of specified netCDF type */
+MPI_Offset
+nctypesize(
+ nc_type type) /* netCDF type code */
+{
+ switch (type) {
+ case NC_BYTE:
+ return sizeof(char);
+ case NC_CHAR:
+ return sizeof(char);
+ case NC_SHORT:
+ return sizeof(short);
+ case NC_INT:
+ return sizeof(int);
+ case NC_FLOAT:
+ return sizeof(float);
+ case NC_DOUBLE:
+ return sizeof(double);
+ case NC_UBYTE:
+ return sizeof(unsigned char);
+ case NC_USHORT:
+ return sizeof(unsigned short);
+ case NC_UINT:
+ return sizeof(unsigned int);
+ case NC_INT64:
+ return sizeof(long long);
+ case NC_UINT64:
+ return sizeof(unsigned long long);
+ default:
+ derror("nctypesize: bad type code");
+ return 0;
+ }
+}
+
+
+/*
+ * Given a netcdf numeric type, a pointer to a vector of values of that
+ * type, and the index of the vector element desired, returns a pointer
+ * to a malloced string representing the value in FORTRAN. Since this
+ * may be used in a DATA statement, it must not include non-constant
+ * expressions, such as "char(26)".
+ */
+char *
+fstring(
+ nc_type type, /* netCDF type code */
+ void *valp, /* pointer to vector of values */
+ int num) /* element of vector desired */
+{
+ static char *cp;
+ signed char *schp;
+ short *shortp;
+ int *intp;
+ float *floatp;
+ double *doublep;
+
+ switch (type) {
+ case NC_BYTE:
+ cp = (char *) emalloc (10);
+ schp = (signed char *)valp;
+ sprintf(cp,"%d", schp[num]);
+ return cp;
+
+ case NC_SHORT:
+ cp = (char *) emalloc (10);
+ shortp = (short *)valp;
+ (void) sprintf(cp,"%d",* (shortp + num));
+ return cp;
+
+ case NC_INT:
+ cp = (char *) emalloc (20);
+ intp = (int *)valp;
+ (void) sprintf(cp,"%d",* (intp + num));
+ return cp;
+
+ case NC_FLOAT:
+ cp = (char *) emalloc (20);
+ floatp = (float *)valp;
+ (void) sprintf(cp,"%.8g",* (floatp + num));
+ return cp;
+
+ case NC_DOUBLE:
+ cp = (char *) emalloc (25);
+ doublep = (double *)valp;
+ (void) sprintf(cp,"%.16g",* (doublep + num));
+ expe2d(cp); /* change 'e' to 'd' in exponent */
+ return cp;
+
+ default:
+ derror("fstring: bad type code");
+ return 0;
+ }
+}
+
+
+/*
+ * Given a pointer to a counted string, returns a pointer to a malloced string
+ * representing the string as a C constant.
+ */
+char *
+cstrstr(
+ const char *valp, /* pointer to vector of characters*/
+ MPI_Offset len) /* number of characters in valp */
+{
+ static char *sp;
+ char *cp;
+ char *istr, *istr0; /* for null-terminated copy */
+ int ii;
+
+ if(4*len+3 != (unsigned)(4*len+3)) {
+ derror("too much character data!");
+ exit(9);
+ }
+ sp = cp = (char *) emalloc(4*len+3);
+
+ if(len == 1 && *valp == 0) { /* empty string */
+ strcpy(sp,"\"\"");
+ return sp;
+ }
+
+ istr0 = istr = (char *) emalloc(len + 1);
+ for(ii = 0; ii < len; ii++) {
+ istr[ii] = valp[ii];
+ }
+ istr[len] = '\0';
+
+ *cp++ = '"';
+ for(ii = 0; ii < len; ii++) {
+ switch (*istr) {
+ case '\0': *cp++ = '\\'; *cp++ = '0'; *cp++ = '0'; *cp++ = '0'; break;
+ case '\b': *cp++ = '\\'; *cp++ = 'b'; break;
+ case '\f': *cp++ = '\\'; *cp++ = 'f'; break;
+ case '\n': *cp++ = '\\'; *cp++ = 'n'; break;
+ case '\r': *cp++ = '\\'; *cp++ = 'r'; break;
+ case '\t': *cp++ = '\\'; *cp++ = 't'; break;
+ case '\v': *cp++ = '\\'; *cp++ = 'v'; break;
+ case '\\': *cp++ = '\\'; *cp++ = '\\'; break;
+ case '\"': *cp++ = '\\'; *cp++ = '\"'; break;
+ default:
+ if (!isprint(*istr)) {
+ static char octs[] = "01234567";
+ int rem = ((unsigned char)*istr)%64;
+ *cp++ = '\\';
+ *cp++ = octs[((unsigned char)*istr)/64]; /* to get, e.g. '\177' */
+ *cp++ = octs[rem/8];
+ *cp++ = octs[rem%8];
+ } else {
+ *cp++ = *istr;
+ }
+ break;
+ }
+ istr++;
+ }
+ *cp++ = '"';
+ *cp = '\0';
+ free(istr0);
+ return sp;
+}
+
+
+/* Given a pointer to a counted string (not necessarily
+ * null-terminated), returns a pointer to a malloced string representing
+ * the string as a FORTRAN string expression. For example, the string
+ * "don't" would yield the FORTRAN string "'don''t'", and the string
+ * "ab\ncd" would yield "'ab'//char(10)//'cd'". The common
+ * interpretation of "\"-escaped characters is non-standard, so the
+ * generated Fortran may require adjustment in compilers that don't
+ * recognize "\" as anything special in a character context. */
+char *
+fstrstr(
+ const char *str, /* pointer to vector of characters */
+ MPI_Offset ilen) /* number of characters in istr */
+{
+ static char *ostr;
+ char *cp, tstr[12];
+ int was_print = 0; /* true if last character was printable */
+ char *istr, *istr0; /* for null-terminated copy */
+ int ii;
+
+ if(12*ilen != (MPI_Offset)(12*ilen)) {
+ derror("too much character data!");
+ exit(9);
+ }
+ istr0 = istr = (char *) emalloc(ilen + 1);
+ for(ii = 0; ii < ilen; ii++) {
+ istr[ii] = str[ii];
+ }
+ istr[ilen] = '\0';
+
+ if (*istr == '\0') { /* empty string input, not legal in FORTRAN */
+ ostr = (char*) emalloc(strlen("char(0)") + 1);
+ strcpy(ostr, "char(0)");
+ free(istr0);
+ return ostr;
+ }
+ ostr = cp = (char *) emalloc(12*ilen);
+ *ostr = '\0';
+ if (isprint(*istr)) { /* handle first character in input */
+ *cp++ = '\'';
+ switch (*istr) {
+ case '\'':
+ *cp++ = '\'';
+ *cp++ = '\'';
+ break;
+ case '\\':
+ *cp++ = '\\';
+ *cp++ = '\\';
+ break;
+ default:
+ *cp++ = *istr;
+ break;
+ }
+ *cp = '\0';
+ was_print = 1;
+ } else {
+ sprintf(tstr, "char(%d)", (unsigned char)*istr);
+ strcat(cp, tstr);
+ cp += strlen(tstr);
+ was_print = 0;
+ }
+ istr++;
+
+ for(ii = 1; ii < ilen; ii++) { /* handle subsequent characters in input */
+ if (isprint(*istr)) {
+ if (! was_print) {
+ strcat(cp, "//'");
+ cp += 3;
+ }
+ switch (*istr) {
+ case '\'':
+ *cp++ = '\'';
+ *cp++ = '\'';
+ break;
+ case '\\':
+ *cp++ = '\\';
+ *cp++ = '\\';
+ break;
+ default:
+ *cp++ = *istr;
+ break;
+ }
+ *cp = '\0';
+ was_print = 1;
+ } else {
+ if (was_print) {
+ *cp++ = '\'';
+ *cp = '\0';
+ }
+ sprintf(tstr, "//char(%d)", (unsigned char)*istr);
+ strcat(cp, tstr);
+ cp += strlen(tstr);
+ was_print = 0;
+ }
+ istr++;
+ }
+ if (was_print)
+ *cp++ = '\'';
+ *cp = '\0';
+ free(istr0);
+ return ostr;
+}
+
+
+static void
+cl_netcdf(void)
+{
+ int stat = ncmpi_close(ncid);
+ check_err(stat, "ncmpi_close", __func__, __LINE__, __FILE__);
+}
+
+
+static void
+cl_c(void)
+{
+ cline(" stat = ncmpi_close(ncid);");
+ cline(" check_err(stat,\"ncmpi_close\", __func__, __LINE__,__FILE__);");
+ cline(" MPI_Finalize();");
+#ifndef vms
+ cline(" return 0;");
+#else
+ cline(" return 1;");
+#endif
+ cline("}");
+}
+
+/* Returns true if dimension used in at least one record variable,
+ otherwise false. This is an inefficient algorithm, but we don't call
+ it very often ... */
+static int
+used_in_rec_var(
+ int idim /* id of dimension */
+ ) {
+ int ivar;
+
+ for (ivar = 0; ivar < nvars; ivar++) {
+ if (vars[ivar].ndims > 0 && vars[ivar].dims[0] == rec_dim) {
+ int jdim;
+ for (jdim = 0; jdim < vars[ivar].ndims; jdim++) {
+ if (vars[ivar].dims[jdim] == idim)
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
+
+
+/* Return name for Fortran fill constant of specified type */
+static const char *
+f_fill_name(
+ nc_type type
+ )
+{
+ switch(type) {
+ case NC_BYTE:
+ return "NF_FILL_BYTE";
+ case NC_CHAR:
+ return "NF_FILL_CHAR";
+ case NC_SHORT:
+ return "NF_FILL_SHORT";
+ case NC_INT:
+ return "NF_FILL_INT";
+ case NC_FLOAT:
+ return "NF_FILL_FLOAT";
+ case NC_DOUBLE:
+ return "NF_FILL_DOUBLE";
+ default:
+ derror("f_fill_name: bad type code");
+ }
+ return 0;
+}
+
+
+/* Generate Fortran for cleaning up and closing file */
+static void
+cl_fortran(void)
+{
+ int ivar;
+ int idim;
+ char stmnt[FORT_MAX_STMNT];
+ char s2[FORT_MAX_STMNT];
+ char*sp;
+ int have_rec_var = 0;
+
+ /* do we have any record variables? */
+ for (ivar = 0; ivar < nvars; ivar++) {
+ struct vars *v = &vars[ivar];
+ if (v->ndims > 0 && v->dims[0] == rec_dim) {
+ have_rec_var = 1;
+ break;
+ }
+ }
+
+ if (have_rec_var) {
+ fline(" ");
+ fline("* Write record variables");
+ sprintf(stmnt, "call writerecs(ncid,");
+ /* generate parameter list for subroutine to write record vars */
+ for (ivar = 0; ivar < nvars; ivar++) {
+ struct vars *v = &vars[ivar];
+ /* if a record variable, include id in parameter list */
+ if (v->ndims > 0 && v->dims[0] == rec_dim) {
+ sprintf(s2, "%s_id,", v->lname);
+ strcat(stmnt, s2);
+ }
+ }
+ sp = strrchr(stmnt, ',');
+ if(sp != NULL) {
+ *sp = '\0';
+ }
+ strcat(stmnt, ")");
+ fline(stmnt);
+ }
+
+ fline(" ");
+ fline("iret = nfmpi_close(ncid)");
+ fline("call check_err(iret,\"nfmpi_close\", __func__, __LINE__,__FILE__)");
+ fline("end");
+
+ fline(" ");
+
+ if (have_rec_var) {
+ sprintf(stmnt, "subroutine writerecs(ncid,");
+ for (ivar = 0; ivar < nvars; ivar++) {
+ struct vars *v = &vars[ivar];
+ if (v->ndims > 0 && v->dims[0] == rec_dim) {
+ sprintf(s2, "%s_id,", v->lname);
+ strcat(stmnt, s2);
+ }
+ }
+ sp = strrchr(stmnt, ',');
+ if(sp != NULL) {
+ *sp = '\0';
+ }
+ strcat(stmnt, ")");
+ fline(stmnt);
+ fline(" ");
+ fline("* netCDF id");
+ fline("integer ncid");
+
+ fline("* variable ids");
+ for (ivar = 0; ivar < nvars; ivar++) {
+ struct vars *v = &vars[ivar];
+ if (v->ndims > 0 && v->dims[0] == rec_dim) {
+ sprintf(stmnt, "integer %s_id", v->lname);
+ fline(stmnt);
+ }
+ }
+
+ fline(" ");
+ fline("include 'pnetcdf.inc'");
+
+ /* create necessary declarations */
+ fline("* error status return");
+ fline("integer iret");
+
+ /* generate integer/parameter declarations for all dimensions
+ used in record variables, except record dimension. */
+ fline(" ");
+ fline("* netCDF dimension sizes for dimensions used with record variables");
+ for (idim = 0; idim < ndims; idim++) {
+ /* if used in a record variable and not record dimension */
+ if (used_in_rec_var(idim) && dims[idim].size != NC_UNLIMITED) {
+ sprintf(stmnt, "integer %s_len", dims[idim].lname);
+ fline(stmnt);
+ sprintf(stmnt, "parameter (%s_len = %lu)",
+ dims[idim].lname, (unsigned long) dims[idim].size);
+ fline(stmnt);
+ }
+ }
+
+ fline(" ");
+ fline("* rank (number of dimensions) for each variable");
+ for (ivar = 0; ivar < nvars; ivar++) {
+ struct vars *v = &vars[ivar];
+ if (v->ndims > 0 && v->dims[0] == rec_dim) {
+ sprintf(stmnt, "integer %s_rank", v->lname);
+ fline(stmnt);
+ }
+ }
+ for (ivar = 0; ivar < nvars; ivar++) {
+ struct vars *v = &vars[ivar];
+ if (v->ndims > 0 && v->dims[0] == rec_dim) {
+ sprintf(stmnt, "parameter (%s_rank = %d)", v->lname,
+ v->ndims);
+ fline(stmnt);
+ }
+ }
+
+ fline("* starts and counts for array sections of record variables");
+ for (ivar = 0; ivar < nvars; ivar++) {
+ struct vars *v = &vars[ivar];
+ if (v->ndims > 0 && v->dims[0] == rec_dim) {
+ sprintf(stmnt,
+ "integer %s_start(%s_rank), %s_count(%s_rank)",
+ v->lname, v->lname, v->lname, v->lname);
+ fline(stmnt);
+ }
+ }
+
+ fline(" ");
+ fline("* data variables");
+
+ for (ivar = 0; ivar < nvars; ivar++) {
+ struct vars *v = &vars[ivar];
+ if (v->ndims > 0 && v->dims[0] == rec_dim) {
+ fline(" ");
+ sprintf(stmnt, "integer %s_nr", v->lname);
+ fline(stmnt);
+ if (v->nrecs > 0) {
+ sprintf(stmnt, "parameter (%s_nr = %lu)",
+ v->lname, (unsigned long) v->nrecs);
+ } else {
+ sprintf(stmnt, "parameter (%s_nr = 1)",
+ v->lname);
+ }
+ fline(stmnt);
+ if (v->type != NC_CHAR) {
+ char *sp;
+ sprintf(stmnt, "%s %s(", ncftype(v->type),
+ v->lname);
+ /* reverse dimensions for FORTRAN */
+ for (idim = v->ndims-1; idim >= 0; idim--) {
+ if(v->dims[idim] == rec_dim) {
+ sprintf(s2, "%s_nr, ", v->lname);
+ } else {
+ sprintf(s2, "%s_len, ",
+ dims[v->dims[idim]].lname);
+ }
+ strcat(stmnt, s2);
+ }
+ sp = strrchr(stmnt, ',');
+ if(sp != NULL) {
+ *sp = '\0';
+ }
+ strcat(stmnt, ")");
+ fline(stmnt);
+ }
+ }
+ }
+
+ fline(" ");
+
+ /* Emit DATA statements after declarations, because f2c on Linux can't
+ handle interspersing them */
+ for (ivar = 0; ivar < nvars; ivar++) {
+ struct vars *v = &vars[ivar];
+
+ if (v->ndims > 0 && v->dims[0] == rec_dim && v->type != NC_CHAR) {
+ if (v->has_data) {
+ fline(v->data_stmnt);
+ } else { /* generate data statement for FILL record */
+ MPI_Offset rec_len = 1;
+ for (idim = 1; idim < v->ndims; idim++) {
+ rec_len *= dims[v->dims[idim]].size;
+ }
+ sprintf(stmnt,"data %s /%lu * %s/", v->lname,
+ (unsigned long) rec_len,
+ f_fill_name(v->type));
+ fline(stmnt);
+ }
+ }
+ }
+ fline(" ");
+ for (ivar = 0; ivar < nvars; ivar++) {
+ struct vars *v = &vars[ivar];
+ /* if a record variable, declare starts and counts */
+ if (v->ndims > 0 && v->dims[0] == rec_dim) {
+ if (!v->has_data)
+ continue;
+ sprintf(stmnt, "* store %s", v->name);
+ fline(stmnt);
+
+ for (idim = 0; idim < v->ndims; idim++) {
+ sprintf(stmnt, "%s_start(%d) = 1", v->lname, idim+1);
+ fline(stmnt);
+ }
+ for (idim = v->ndims-1; idim > 0; idim--) {
+ sprintf(stmnt, "%s_count(%d) = %s_len", v->lname,
+ v->ndims - idim, dims[v->dims[idim]].lname);
+ fline(stmnt);
+ }
+ sprintf(stmnt, "%s_count(%d) = %s_nr", v->lname,
+ v->ndims, v->lname);
+ fline(stmnt);
+
+ if (v->type != NC_CHAR) {
+ sprintf(stmnt,
+ "iret = nfmpi_put_vara_%s_all(ncid, %s_id, %s_start, %s_count, %s)",
+ nfftype(v->type), v->lname, v->lname, v->lname, v->lname);
+ } else {
+ sprintf(stmnt,
+ "iret = nfmpi_put_vara_%s_all(ncid, %s_id, %s_start, %s_count, %s)",
+ nfftype(v->type), v->lname, v->lname, v->lname,
+ v->data_stmnt);
+ }
+
+ fline(stmnt);
+ fline("call check_err(iret,\"nfmpi_put_vara_xxx\", __func__, __LINE__,__FILE__)");
+ }
+ }
+
+ fline(" ");
+
+ fline("end");
+
+ fline(" ");
+ }
+
+ fline("subroutine check_err(iret, nfmpi_func, calling_func, lineno, calling_file)");
+ fline("integer iret");
+ fline("character*80 nfmpi_func");
+ fline("character*80 calling_func");
+ fline("character*80 calling_file");
+ fline("integer lineno");
+ fline("include 'pnetcdf.inc'");
+ fline("if (iret .ne. NF_NOERR) then");
+ fline("print *, \"ncmpigen error when calling \",trim(nfmpi_func),\" in \",trim(ncmpi_func),\"() at line \",lineno, \" of \",trim(calling_file),\": \", nfmpi_strerror(iret)");
+ fline("stop");
+ fline("endif");
+ fline("end");
+}
+
+
+/* invoke netcdf calls (or generate C or Fortran code) to create netcdf
+ * from in-memory structure. */
+void
+define_netcdf(
+ char *netcdfname)
+{
+ char *filename; /* output file name */
+
+ if (netcdf_name) { /* name given on command line */
+ filename = netcdf_name;
+ } else { /* construct name from CDL name */
+ filename = (char *) emalloc(strlen(netcdfname) + 5);
+ (void) strcpy(filename,netcdfname);
+ if (netcdf_flag == -1)
+ (void) strcat(filename,".cdf"); /* old, deprecated extension */
+ else
+ (void) strcat(filename,".nc"); /* new, favored extension */
+ }
+ if (netcdf_flag)
+ gen_netcdf(filename); /* create netcdf */
+ if (c_flag) /* create C code to create netcdf */
+ gen_c(filename);
+ if (fortran_flag) /* create Fortran code to create netcdf */
+ gen_fortran(filename);
+ free(filename);
+}
+
+
+void
+close_netcdf(void)
+{
+ if (netcdf_flag)
+ cl_netcdf(); /* close netcdf */
+ if (c_flag) /* create C code to close netcdf */
+ cl_c();
+ if (fortran_flag) /* create Fortran code to close netcdf */
+ cl_fortran();
+}
+
+
+void
+check_err(int stat, const char *ncmpi_func, const char *calling_func, int lineno, const char *calling_file) {
+ if (stat != NC_NOERR) {
+ fprintf(stderr, "ncmpigen error when calling %s in %s() at line %d of %s: %s\n", ncmpi_func, calling_func, lineno, calling_file, ncmpi_strerror(stat));
+ derror_count++;
+ }
+}
+
+/*
+ * For logging error conditions.
+ */
+#ifndef NO_STDARG
+void
+derror(const char *fmt, ...)
+#else
+/*VARARGS1*/
+void
+derror(fmt, va_alist)
+ const char *fmt ; /* error-message printf-style format */
+ va_dcl /* variable number of error args, if any */
+#endif /* !NO_STDARG */
+{
+ va_list args ;
+
+
+ if (lineno == 1)
+ (void) fprintf(stderr,"%s: %s: ", progname, cdlname);
+ else
+ (void) fprintf(stderr,"%s: %s line %d: ", progname, cdlname, lineno);
+
+#ifndef NO_STDARG
+ va_start(args ,fmt) ;
+#else
+ va_start(args) ;
+#endif /* !NO_STDARG */
+
+ (void) vfprintf(stderr,fmt,args) ;
+ va_end(args) ;
+
+ (void) fputc('\n',stderr) ;
+ (void) fflush(stderr); /* to ensure log files are current */
+ derror_count++;
+}
+
+
+void *
+emalloc ( /* check return from malloc */
+ size_t size)
+{
+ void *p;
+
+ p = (void *) malloc (size);
+ if (p == 0) {
+ derror ("out of memory\n");
+ exit(3);
+ }
+ return p;
+}
+
+void *
+ecalloc ( /* check return from calloc */
+ size_t size)
+{
+ void *p;
+
+ p = (void *) calloc (size, 1);
+ if (p == 0) {
+ derror ("out of memory\n");
+ exit(3);
+ }
+ return p;
+}
+
+void *
+erealloc ( /* check return from realloc */
+ void *ptr,
+ size_t size) /* if 0, this is really a free */
+{
+ void *p;
+
+ p = (void *) realloc (ptr, size);
+
+ if (p == 0 && size != 0) {
+ derror ("out of memory");
+ exit(3);
+ }
+ return p;
+}
+
+
+/*
+ * For generated Fortran, change 'e' to 'd' in exponent of double precision
+ * constants.
+ */
+void
+expe2d(
+ char *cp) /* string containing double constant */
+{
+ char *expchar = strrchr(cp,'e');
+ if (expchar) {
+ *expchar = 'd';
+ }
+}
+
+
+
+/* Returns non-zero if n is a power of 2, 0 otherwise */
+static
+int
+pow2(
+ int n)
+{
+ int m = n;
+ int p = 1;
+
+ while (m > 0) {
+ m /= 2;
+ p *= 2;
+ }
+ return p == 2*n;
+}
+
+
+/*
+ * Grow an integer array as necessary.
+ *
+ * Assumption: nar never incremented by more than 1 from last call.
+ *
+ * Makes sure an array is within a factor of 2 of the size needed.
+ *
+ * Make sure *arpp points to enough space to hold nar integers. If not big
+ * enough, malloc more space, copy over existing stuff, free old. When
+ * called for first time, *arpp assumed to be uninitialized.
+ */
+void
+grow_iarray(
+ int nar, /* array must be at least this big */
+ int **arpp) /* address of start of int array */
+{
+ if (nar == 0) {
+ *arpp = (int *) emalloc(1 * sizeof(int));
+ return;
+ }
+ if (! pow2(nar)) /* return unless nar is a power of two */
+ return;
+ *arpp = (int *) erealloc(*arpp, 2 * nar * sizeof(int));
+}
+
+
+/*
+ * Grow an array of variables as necessary.
+ *
+ * Assumption: nar never incremented by more than 1 from last call.
+ *
+ * Makes sure array is within a factor of 2 of the size needed.
+ *
+ * Make sure *arpp points to enough space to hold nar variables. If not big
+ * enough, malloc more space, copy over existing stuff, free old. When
+ * called for first time, *arpp assumed to be uninitialized.
+ */
+void
+grow_varray(
+ int nar, /* array must be at least this big */
+ struct vars **arpp) /* address of start of var array */
+{
+ if (nar == 0) {
+ *arpp = (struct vars *) emalloc(1 * sizeof(struct vars));
+ return;
+ }
+ if (! pow2(nar)) /* return unless nar is a power of two */
+ return;
+ *arpp = (struct vars *) erealloc(*arpp, 2 * nar * sizeof(struct vars));
+}
+
+
+/*
+ * Grow an array of dimensions as necessary.
+ *
+ * Assumption: nar never incremented by more than 1 from last call.
+ *
+ * Makes sure array is within a factor of 2 of the size needed.
+ *
+ * Make sure *arpp points to enough space to hold nar dimensions. If not big
+ * enough, malloc more space, copy over existing stuff, free old. When
+ * called for first time, *arpp assumed to be uninitialized.
+ */
+void
+grow_darray(
+ int nar, /* array must be at least this big */
+ struct dims **arpp) /* address of start of var array */
+{
+ if (nar == 0) {
+ *arpp = (struct dims *) emalloc(1 * sizeof(struct dims));
+ return;
+ }
+ if (! pow2(nar)) /* return unless nar is a power of two */
+ return;
+ *arpp = (struct dims *) erealloc(*arpp, 2 * nar * sizeof(struct dims));
+}
+
+
+/*
+ * Grow an array of attributes as necessary.
+ *
+ * Assumption: nar never incremented by more than 1 from last call.
+ *
+ * Makes sure array is within a factor of 2 of the size needed.
+ *
+ * Make sure *arpp points to enough space to hold nar attributes. If not big
+ * enough, malloc more space, copy over existing stuff, free old. When
+ * called for first time, *arpp assumed to be uninitialized.
+ */
+void
+grow_aarray(
+ int nar, /* array must be at least this big */
+ struct atts **arpp) /* address of start of var array */
+{
+ if (nar == 0) {
+ *arpp = (struct atts *) emalloc(1 * sizeof(struct atts));
+ return;
+ }
+ if (! pow2(nar)) /* return unless nar is a power of two */
+ return;
+ *arpp = (struct atts *) erealloc(*arpp, 2 * nar * sizeof(struct atts));
+}
+
+
+/*
+ * Replace dashes and dots in name so it can be used in C and
+ * Fortran without causing syntax errors. Here we just replace each "-"
+ * in a name with "_dash_" and each "." with "_dot_", though any
+ * similar replacement that doesn't clash with existing names would
+ * work.
+ */
+extern char*
+decodify (
+ const char *name)
+{
+ int count=0; /* number of minus signs in name */
+ char *newname;
+ const char *cp = name;
+ char *sp;
+
+ while(*cp != '\0') {
+ switch (*cp) {
+ case '-':
+ count += strlen("_dash_") - 1;
+ break;
+ case '.':
+ count += strlen("_dot_") - 1;
+ break;
+ case '@':
+ count += strlen("_at_") - 1;
+ break;
+ case '#':
+ count += strlen("_hash_") - 1;
+ break;
+ case '[':
+ count += strlen("_lbr_") - 1;
+ break;
+ case ']':
+ count += strlen("_rbr_") - 1;
+ break;
+ default:
+ break;
+ }
+ cp++;
+ }
+ newname = (char *) ecalloc(strlen(name) + count + 1);
+ cp = name;
+ sp = newname;
+ while(*cp != '\0') {
+ switch (*cp) {
+ case '-':
+ strcat(sp, "_dash_");
+ sp += strlen("_dash_");
+ break;
+ case '.':
+ strcat(sp, "_dot_");
+ sp += strlen("_dot_");
+ break;
+ case '@':
+ strcat(sp, "_at_");
+ sp += strlen("_at_");
+ break;
+ case '#':
+ strcat(sp, "_hash_");
+ sp += strlen("_hash_");
+ break;
+ case '[':
+ strcat(sp, "_lbr_");
+ sp += strlen("_lbr_");
+ break;
+ case ']':
+ strcat(sp, "_rbr_");
+ sp += strlen("_rbr_");
+ break;
+ default:
+ *sp++ = *cp;
+ break;
+ }
+ cp++;
+ }
+ *sp = '\0';
+ return newname;
+}
+
+/*
+ * Replace escaped chars in CDL representation of name such as
+ * 'abc\:def\ gh\\i' with unescaped version, such as 'abc:def gh\i'.
+ */
+void
+deescapify (char *name)
+{
+ const char *cp = name;
+ char *sp;
+ size_t len = strlen(name);
+ char *newname;
+
+ if(strchr(name, '\\') == NULL)
+ return;
+
+ newname = (char *) emalloc(len + 1);
+ cp = name;
+ sp = newname;
+ while(*cp != '\0') { /* delete '\' chars, except change '\\' to '\' */
+ switch (*cp) {
+ case '\\':
+ if(*(cp+1) == '\\') {
+ *sp++ = '\\';
+ cp++;
+ }
+ break;
+ default:
+ *sp++ = *cp;
+ break;
+ }
+ cp++;
+ }
+ *sp = '\0';
+ /* assert(strlen(newname) <= strlen(name)); */
+ strncpy(name, newname, len);
+ free(newname);
+ return;
+}
+
diff --git a/src/utils/ncmpigen/genlib.h b/src/utils/ncmpigen/genlib.h
new file mode 100644
index 0000000..1d10e3a
--- /dev/null
+++ b/src/utils/ncmpigen/genlib.h
@@ -0,0 +1,98 @@
+#ifndef NC_GENLIB_H
+#define NC_GENLIB_H
+/*********************************************************************
+ * Copyright 1993, UCAR/Unidata
+ * See netcdf/COPYRIGHT file for copying and redistribution conditions.
+ * $Header$
+ *********************************************************************/
+#include <stdlib.h>
+#include <stdio.h> /* FILE */
+#include <limits.h>
+
+extern const char *progname; /* for error messages */
+extern const char *cdlname; /* for error messages */
+
+#define FORT_MAX_LINES 20 /* max lines in FORTRAN statement */
+#define FORT_MAX_STMNT 66*FORT_MAX_LINES /* max chars in FORTRAN statement */
+#define C_MAX_STMNT FORT_MAX_STMNT /* until we fix to break up C lines */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern void cline ( const char* stmnt );
+extern void fline ( const char* stmnt );
+extern const char* nctype ( nc_type type );
+extern const char* ncctype ( nc_type type );
+extern const char* ncstype ( nc_type type );
+extern const char* ncatype ( nc_type type );
+extern const char* nfstype ( nc_type type );
+extern const char* nfftype ( nc_type type );
+extern char* fstring ( nc_type type, void* valp, int num );
+extern char* cstrstr ( const char* valp, MPI_Offset len );
+extern char* fstrstr ( const char* str, MPI_Offset ilen );
+extern MPI_Offset nctypesize( nc_type type );
+
+extern void derror ( const char *fmt, ... )
+#ifdef _GNUC_
+ __attribute__ ((format (printf, 1, 2)))
+#endif
+;
+extern void check_err(int stat, const char *ncmpi_func, const char *calling_func, int lineno, const char *calling_file);
+extern void *emalloc ( size_t size );
+extern void *ecalloc ( size_t size );
+extern void *erealloc ( void *ptr, size_t size );
+extern void expe2d ( char *ptr );
+extern void grow_iarray ( int narray, int **array );
+extern void grow_varray ( int narray, struct vars **array );
+extern void grow_darray ( int narray, struct dims **array );
+extern void grow_aarray ( int narray, struct atts **array );
+extern char* decodify (const char *name);
+extern void deescapify (char *name);
+
+extern int put_variable ( void* rec_start );
+
+/* initializes netcdf counts (e.g. nvars), defined in init.c */
+extern void init_netcdf ( void );
+
+/* generates all define mode stuff, defined in genlib.c */
+extern void define_netcdf(char *netcdfname);
+
+/* generates variable puts, defined in load.c */
+extern void load_netcdf ( void* rec_start );
+
+/* generates close, defined in close.c */
+extern void close_netcdf ( void );
+
+/* defined in escapes.c */
+extern void expand_escapes ( char* termstring, char* yytext, int yyleng );
+
+/* to get fill value for various types, defined in getfill.c */
+extern void nc_getfill ( nc_type type, union generic* gval );
+
+/* to put fill value for various types, defined in getfill.c */
+extern void nc_putfill ( nc_type type, void* val, union generic* gval );
+
+/* fills a generic array with a value, defined in getfill.c */
+extern void nc_fill ( nc_type type, MPI_Offset num, void* datp,
+ union generic fill_val );
+
+/* reset symbol table to empty, defined in ncmpigen.y */
+extern void clearout(void);
+
+extern int ncmpiwrap(void);
+extern int ncmpiget_lineno(void);
+extern FILE *ncmpiget_in(void);
+extern FILE *ncmpiget_out(void);
+extern char *ncmpiget_text(void);
+extern void ncmpiset_lineno(int line_number);
+extern void ncmpiset_in(FILE *in_str);
+extern void ncmpiset_out (FILE *out_str);
+extern int ncmpiget_debug(void);
+extern void ncmpiset_debug(int bdebug);
+extern int ncmpilex_destroy(void);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /*!NC_GENLIB_H*/
diff --git a/src/utils/ncmpigen/getfill.c b/src/utils/ncmpigen/getfill.c
new file mode 100644
index 0000000..437d137
--- /dev/null
+++ b/src/utils/ncmpigen/getfill.c
@@ -0,0 +1,151 @@
+/*********************************************************************
+ * Copyright 1993, UCAR/Unidata
+ * See netcdf/COPYRIGHT file for copying and redistribution conditions.
+ * $Header$
+ *********************************************************************/
+
+#include <pnetcdf.h>
+#include "generic.h"
+#include "ncmpigen.h"
+#include "genlib.h"
+
+
+/*
+ * Given netCDF type, return a default fill_value appropriate for
+ * that type.
+ */
+void
+nc_getfill(
+ nc_type type,
+ union generic *gval)
+{
+ switch(type) {
+ case NC_CHAR:
+ gval->charv = NC_FILL_CHAR;
+ return;
+ case NC_BYTE:
+ gval->charv = NC_FILL_BYTE;
+ return;
+ case NC_SHORT:
+ gval->shortv = NC_FILL_SHORT;
+ return;
+ case NC_INT:
+ gval->intv = NC_FILL_INT;
+ return;
+ case NC_FLOAT:
+ gval->floatv = NC_FILL_FLOAT;
+ return;
+ case NC_DOUBLE:
+ gval->doublev = NC_FILL_DOUBLE;
+ return;
+ case NC_UBYTE:
+ gval->ubytev = NC_FILL_UBYTE;
+ return;
+ case NC_USHORT:
+ gval->ushortv = NC_FILL_USHORT;
+ return;
+ case NC_UINT:
+ gval->uintv = NC_FILL_UINT;
+ return;
+ case NC_INT64:
+ gval->int64v = NC_FILL_INT64;
+ return;
+ case NC_UINT64:
+ gval->uint64v = NC_FILL_UINT64;
+ return;
+ default:
+ derror("nc_getfill: unrecognized type");
+ }
+}
+
+
+void
+nc_fill(
+ nc_type type, /* netcdf type code */
+ MPI_Offset num, /* number of values to fill */
+ void *datp, /* where to start filling */
+ union generic fill_val) /* value to use */
+{
+ char *char_valp=NULL; /* pointers used to accumulate data values */
+ short *short_valp=NULL;
+ int *long_valp=NULL;
+ float *float_valp=NULL;
+ double *double_valp=NULL;
+
+ switch (type) {
+ case NC_CHAR:
+ case NC_BYTE:
+ char_valp = (char *) datp;
+ break;
+ case NC_SHORT:
+ short_valp = (short *) datp;
+ break;
+ case NC_INT:
+ long_valp = (int *) datp;
+ break;
+ case NC_FLOAT:
+ float_valp = (float *) datp;
+ break;
+ case NC_DOUBLE:
+ double_valp = (double *) datp;
+ break;
+ default:
+ derror("nc_fill: unrecognized type");
+ break;
+ }
+ while (num--) {
+ switch (type) {
+ case NC_CHAR:
+ case NC_BYTE:
+ *char_valp++ = fill_val.charv;
+ break;
+ case NC_SHORT:
+ *short_valp++ = fill_val.shortv;
+ break;
+ case NC_INT:
+ *long_valp++ = fill_val.intv;
+ break;
+ case NC_FLOAT:
+ *float_valp++ = fill_val.floatv;
+ break;
+ case NC_DOUBLE:
+ *double_valp++ = fill_val.doublev;
+ break;
+ default:
+ derror("nc_fill: unrecognized type");
+ break;
+ }
+ }
+}
+
+
+/*
+ * Given netCDF type, put a value of that type into a fill_value
+ */
+void
+nc_putfill(
+ nc_type type,
+ void *val, /* value of type to be put */
+ union generic *gval) /* where the value is to be put */
+{
+ switch(type) {
+ case NC_CHAR:
+ case NC_BYTE:
+ gval->charv = *(char *)val;
+ return;
+ case NC_SHORT:
+ gval->shortv = *(short *)val;
+ return;
+ case NC_INT:
+ gval->intv = *(int *)val;
+ return;
+ case NC_FLOAT:
+ gval->floatv = *(float *)val;
+ return;
+ case NC_DOUBLE:
+ gval->doublev = *(double *)val;
+ return;
+ default:
+ derror("nc_putfill: unrecognized type");
+ }
+}
diff --git a/src/utils/ncmpigen/init.c b/src/utils/ncmpigen/init.c
new file mode 100644
index 0000000..e51620b
--- /dev/null
+++ b/src/utils/ncmpigen/init.c
@@ -0,0 +1,43 @@
+/*********************************************************************
+ * Copyright 1993, UCAR/Unidata
+ * See netcdf/COPYRIGHT file for copying and redistribution conditions.
+ * $Header$
+ *********************************************************************/
+
+#include <stdio.h>
+#include <pnetcdf.h>
+#include "generic.h"
+#include "ncmpigen.h"
+#include "genlib.h"
+
+extern int netcdf_flag;
+extern int c_flag;
+extern int fortran_flag;
+
+struct dims *dims; /* table of netcdf dimensions */
+
+int ncid; /* handle for netCDF */
+int ndims; /* number of dimensions declared for netcdf */
+int nvars; /* number of variables declared for netcdf */
+int natts; /* number of attributes */
+int nvdims; /* number of dimensions for variables */
+int dimnum; /* dimension number index for variables */
+int varnum; /* variable number index for attributes */
+int valnum; /* value number index for attributes */
+int rec_dim; /* number of the unlimited dimension, if any */
+MPI_Offset var_len; /* variable length (product of dimensions) */
+MPI_Offset rec_len; /* number of elements for a record of data */
+MPI_Offset var_size; /* size of each element of variable */
+
+struct vars *vars; /* a malloc'ed list */
+
+struct atts *atts; /* table of variable and global attributes */
+
+void
+init_netcdf(void) { /* initialize global counts, flags */
+
+ clearout(); /* reset symbol table to empty */
+ ndims = 0;
+ nvars = 0;
+ rec_dim = -1; /* means no unlimited dimension (yet) */
+}
diff --git a/src/utils/ncmpigen/load.c b/src/utils/ncmpigen/load.c
new file mode 100644
index 0000000..e7c8e14
--- /dev/null
+++ b/src/utils/ncmpigen/load.c
@@ -0,0 +1,835 @@
+/*********************************************************************
+ * Copyright 1993, UCAR/Unidata
+ * See netcdf/COPYRIGHT file for copying and redistribution conditions.
+ * $Id: load.c 2243 2015-12-19 01:12:41Z wkliao $
+ *********************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <string.h>
+#include <ctype.h>
+#include <pnetcdf.h>
+#include "generic.h"
+#include "ncmpigen.h"
+#include "genlib.h"
+
+extern int netcdf_flag;
+extern int c_flag;
+extern int fortran_flag;
+
+#define fpr (void) fprintf
+
+#ifndef INT_MAX
+#define INT_MAX 2147483647
+#endif
+
+/*
+ * Remove trailing zeros (after decimal point) but not trailing decimal
+ * point from ss, a string representation of a floating-point number that
+ * might include an exponent part.
+ */
+static void
+tztrim(
+ char *ss /* returned string representing dd */
+ )
+{
+ char *cp, *ep;
+
+ cp = ss;
+ if (*cp == '-')
+ cp++;
+ while(isdigit((int)*cp) || *cp == '.')
+ cp++;
+ if (*--cp == '.')
+ return;
+ ep = cp+1;
+ while (*cp == '0')
+ cp--;
+ cp++;
+ if (cp == ep)
+ return;
+ while (*ep)
+ *cp++ = *ep++;
+ *cp = '\0';
+ return;
+}
+
+
+/* generate C to put netCDF record from in-memory data */
+static void
+gen_load_c(
+ void *rec_start
+ )
+{
+ int idim, ival;
+ char *val_string;
+ char *charvalp = NULL;
+ short *shortvalp = NULL;
+ int *intvalp = NULL;
+ float *floatvalp = NULL;
+ double *doublevalp = NULL;
+ unsigned char *ubytevalp = NULL;
+ unsigned short *ushortvalp = NULL;
+ unsigned int *uintvalp = NULL;
+ long long *int64valp = NULL;
+ unsigned long long *uint64valp = NULL;
+ char stmnt[C_MAX_STMNT];
+ MPI_Offset stmnt_len;
+ char s2[C_MAX_STMNT];
+
+ if (!vars[varnum].has_data)
+ return;
+
+ cline("");
+ sprintf(stmnt, " {\t\t\t/* store %s */", vars[varnum].name);
+ cline(stmnt);
+
+ if (vars[varnum].ndims > 0) {
+ if (vars[varnum].dims[0] == rec_dim) {
+ sprintf(stmnt, " static MPI_Offset %s_start[RANK_%s];",
+ vars[varnum].lname, vars[varnum].lname);
+ cline(stmnt);
+
+ sprintf(stmnt, " static MPI_Offset %s_count[RANK_%s];",
+ vars[varnum].lname, vars[varnum].lname);
+ cline(stmnt);
+ }
+
+ /* load variable with data values using static initialization */
+ sprintf(stmnt, " static %s %s[] = {",
+ ncctype(vars[varnum].type),
+ vars[varnum].lname);
+
+ stmnt_len = strlen(stmnt);
+ switch (vars[varnum].type) {
+ case NC_CHAR:
+ val_string = cstrstr((char *) rec_start, var_len);
+ sprintf(s2, "%s", val_string);
+ strncat(stmnt, s2, C_MAX_STMNT - strlen(stmnt) );
+ free(val_string);
+ break;
+ default:
+ switch (vars[varnum].type) {
+ case NC_BYTE:
+ charvalp = (char *) rec_start;
+ break;
+ case NC_SHORT:
+ shortvalp = (short *) rec_start;
+ break;
+ case NC_INT:
+ intvalp = (int *) rec_start;
+ break;
+ case NC_FLOAT:
+ floatvalp = (float *) rec_start;
+ break;
+ case NC_DOUBLE:
+ doublevalp = (double *) rec_start;
+ break;
+ case NC_UBYTE:
+ ubytevalp = (unsigned char *) rec_start;
+ break;
+ case NC_USHORT:
+ ushortvalp = (unsigned short *) rec_start;
+ break;
+ case NC_UINT:
+ uintvalp = (unsigned int *) rec_start;
+ break;
+ case NC_INT64:
+ int64valp = (long long *) rec_start;
+ break;
+ case NC_UINT64:
+ uint64valp = (unsigned long long *) rec_start;
+ break;
+ default:
+ derror("Unhandled type %d\n", vars[varnum].type);
+ break;
+ }
+ for (ival = 0; ival < var_len-1; ival++) {
+ switch (vars[varnum].type) {
+ case NC_BYTE:
+ sprintf(s2, "%d, ", *charvalp++);
+ break;
+ case NC_SHORT:
+ sprintf(s2, "%d, ", *shortvalp++);
+ break;
+ case NC_INT:
+ sprintf(s2, "%ld, ", (long)*intvalp++);
+ break;
+ case NC_FLOAT:
+ sprintf(s2, "%.8g, ", *floatvalp++);
+ break;
+ case NC_DOUBLE:
+ sprintf(s2, "%#.16g", *doublevalp++);
+ tztrim(s2);
+ strcat(s2, ", ");
+ break;
+ case NC_UBYTE:
+ sprintf(s2, "%hhu, ", (unsigned char)*ubytevalp++);
+ break;
+ case NC_USHORT:
+ sprintf(s2, "%hu, ", (unsigned short)*ushortvalp++);
+ break;
+ case NC_UINT:
+ sprintf(s2, "%u, ", (unsigned int)*uintvalp++);
+ break;
+ case NC_INT64:
+ sprintf(s2, "%lld, ", (long long)*int64valp++);
+ break;
+ case NC_UINT64:
+ sprintf(s2, "%llu, ", (unsigned long long)*uint64valp++);
+ break;
+ default:
+ derror("Unhandled type %d\n", vars[varnum].type);
+ break;
+
+ }
+ stmnt_len += strlen(s2);
+ if (stmnt_len < C_MAX_STMNT)
+ strcat(stmnt, s2);
+ else {
+ cline(stmnt);
+ strcpy(stmnt,s2);
+ stmnt_len = strlen(stmnt);
+ }
+ }
+ for (;ival < var_len; ival++) {
+ switch (vars[varnum].type) {
+ case NC_BYTE:
+ sprintf(s2, "%d", *charvalp);
+ break;
+ case NC_SHORT:
+ sprintf(s2, "%d", *shortvalp);
+ break;
+ case NC_INT:
+ sprintf(s2, "%ld", (long)*intvalp);
+ break;
+ case NC_FLOAT:
+ sprintf(s2, "%.8g", *floatvalp);
+ break;
+ case NC_DOUBLE:
+ sprintf(s2, "%#.16g", *doublevalp++);
+ tztrim(s2);
+ break;
+ case NC_UBYTE:
+ sprintf(s2, "%hhu, ", (unsigned char)*ubytevalp++);
+ break;
+ case NC_USHORT:
+ sprintf(s2, "%hu, ", (unsigned short)*ushortvalp++);
+ break;
+ case NC_UINT:
+ sprintf(s2, "%u, ", (unsigned int)*uintvalp++);
+ break;
+ case NC_INT64:
+ sprintf(s2, "%lld, ", (long long)*int64valp++);
+ break;
+ case NC_UINT64:
+ sprintf(s2, "%llu, ", (unsigned long long)*uint64valp++);
+ break;
+ default:
+ derror("Unhandled type %d\n", vars[varnum].type);
+ break;
+ }
+ stmnt_len += strlen(s2);
+ if (stmnt_len < C_MAX_STMNT)
+ strcat(stmnt, s2);
+ else {
+ cline(stmnt);
+ strcpy(stmnt,s2);
+ stmnt_len = strlen(stmnt);
+ }
+ }
+ break;
+ }
+ strcat(stmnt,"};");
+ cline(stmnt);
+
+ if (vars[varnum].dims[0] == rec_dim) {
+ sprintf(stmnt,
+ " %s_len = %lu; /* number of records of %s data */",
+ dims[rec_dim].lname,
+ (unsigned long)vars[varnum].nrecs, /* number of recs for this variable */
+ vars[varnum].name);
+ cline(stmnt);
+
+ for (idim = 0; idim < vars[varnum].ndims; idim++) {
+ sprintf(stmnt, " %s_start[%d] = 0;",
+ vars[varnum].lname,
+ idim);
+ cline(stmnt);
+ }
+
+ for (idim = 0; idim < vars[varnum].ndims; idim++) {
+ sprintf(stmnt, " %s_count[%d] = %s_len;",
+ vars[varnum].lname,
+ idim,
+ dims[vars[varnum].dims[idim]].lname);
+ cline(stmnt);
+ }
+ }
+
+ if (vars[varnum].dims[0] == rec_dim) {
+ sprintf(stmnt,
+ " stat = ncmpi_put_vara_%s_all(ncid, %s_id, %s_start, %s_count, %s);",
+ ncstype(vars[varnum].type),
+ vars[varnum].lname,
+ vars[varnum].lname,
+ vars[varnum].lname,
+ vars[varnum].lname);
+ cline(stmnt);
+ } else { /* non-record variables */
+ cline(" ncmpi_begin_indep_data(ncid);");
+ sprintf(stmnt,
+ " stat = ncmpi_put_var_%s(ncid, %s_id, %s);",
+ ncstype(vars[varnum].type),
+ vars[varnum].lname,
+ vars[varnum].lname);
+ cline(stmnt);
+ cline(" ncmpi_end_indep_data(ncid);");
+ }
+ } else { /* scalar variables */
+ /* load variable with data values using static initialization */
+ sprintf(stmnt, " static %s %s = ",
+ ncctype(vars[varnum].type),
+ vars[varnum].lname);
+
+ switch (vars[varnum].type) {
+ case NC_CHAR:
+ val_string = cstrstr((char *) rec_start, var_len);
+ val_string[strlen(val_string)-1] = '\0';
+ sprintf(s2, "'%s'", &val_string[1]);
+ free(val_string);
+ break;
+ case NC_BYTE:
+ charvalp = (char *) rec_start;
+ sprintf(s2, "%d", *charvalp);
+ break;
+ case NC_SHORT:
+ shortvalp = (short *) rec_start;
+ sprintf(s2, "%d", *shortvalp);
+ break;
+ case NC_INT:
+ intvalp = (int *) rec_start;
+ sprintf(s2, "%ld", (long)*intvalp);
+ break;
+ case NC_FLOAT:
+ floatvalp = (float *) rec_start;
+ sprintf(s2, "%.8g", *floatvalp);
+ break;
+ case NC_DOUBLE:
+ doublevalp = (double *) rec_start;
+ sprintf(s2, "%#.16g", *doublevalp++);
+ tztrim(s2);
+ break;
+ case NC_UBYTE:
+ ubytevalp = (unsigned char *) rec_start;
+ sprintf(s2, "%hhu", (unsigned char)*ubytevalp);
+ break;
+ case NC_USHORT:
+ ushortvalp = (unsigned short *) rec_start;
+ sprintf(s2, "%hu", (unsigned short)*ushortvalp);
+ break;
+ case NC_UINT:
+ uintvalp = (unsigned int *) rec_start;
+ sprintf(s2, "%u", (unsigned int)*uintvalp);
+ break;
+ case NC_INT64:
+ int64valp = (long long *) rec_start;
+ sprintf(s2, "%lld", (long long)*int64valp);
+ break;
+ case NC_UINT64:
+ uint64valp = (unsigned long long *) rec_start;
+ sprintf(s2, "%llu", (unsigned long long)*uint64valp);
+ break;
+ default:
+ derror("Unhandled type %d\n", vars[varnum].type);
+ break;
+ }
+ strncat(stmnt, s2, C_MAX_STMNT - strlen(stmnt) );
+ strcat(stmnt,";");
+ cline(stmnt);
+ cline(" ncmpi_begin_indep_data(ncid);");
+ sprintf(stmnt,
+ " stat = ncmpi_put_var_%s(ncid, %s_id, &%s);",
+ ncstype(vars[varnum].type),
+ vars[varnum].lname,
+ vars[varnum].lname);
+ cline(stmnt);
+ cline(" ncmpi_end_indep_data(ncid);");
+ }
+ cline(" check_err(stat,__LINE__,__FILE__);");
+ cline(" }");
+}
+
+
+/*
+ * Add to a partial Fortran statement, checking if it's too long. If it is too
+ * long, output the first part of it as a single statement with continuation
+ * characters and start a new (probably invalid) statement with the remainder.
+ * This will cause a Fortran compiler error, but at least all the information
+ * will be available.
+ */
+static void
+fstrcat(
+ char *s, /* source string of stement being built */
+ const char *t, /* string to be appended to source */
+ MPI_Offset *slenp /* pointer to length of source string */
+ )
+{
+ *slenp += strlen(t);
+ if (*slenp >= FORT_MAX_STMNT) {
+ derror("FORTRAN statement too long: %s",s);
+ fline(s);
+ strcpy(s, t);
+ *slenp = strlen(s);
+ } else {
+ strcat(s, t);
+ }
+}
+
+/*
+ * Create Fortran data statement to initialize numeric variable with
+ * values.
+ */
+static void
+f_var_init(
+ int varnum, /* which variable */
+ void *rec_start /* start of data */
+ )
+{
+ char *val_string;
+ char *charvalp;
+ short *shortvalp;
+ int *intvalp;
+ float *floatvalp;
+ double *doublevalp;
+ unsigned char *ubytevalp;
+ unsigned short *ushortvalp;
+ unsigned int *uintvalp;
+ long long *int64valp;
+ unsigned long long *uint64valp;
+ char stmnt[FORT_MAX_STMNT];
+ MPI_Offset stmnt_len;
+ char s2[FORT_MAX_STMNT];
+ int ival;
+
+ /* load variable with data values */
+ sprintf(stmnt, "data %s /",vars[varnum].lname);
+ stmnt_len = strlen(stmnt);
+ switch (vars[varnum].type) {
+ case NC_BYTE:
+ charvalp = (char *) rec_start;
+ for (ival = 0; ival < var_len-1; ival++) {
+ val_string = fstring(NC_BYTE,(void *)charvalp++,0);
+ sprintf(s2, "%s, ", val_string);
+ fstrcat(stmnt, s2, &stmnt_len);
+ free(val_string);
+ }
+ val_string = fstring(NC_BYTE,(void *)charvalp++,0);
+ fstrcat(stmnt, val_string, &stmnt_len);
+ free(val_string);
+ break;
+ case NC_SHORT:
+ shortvalp = (short *) rec_start;
+ for (ival = 0; ival < var_len-1; ival++) {
+ sprintf(s2, "%d, ", *shortvalp++);
+ fstrcat(stmnt, s2, &stmnt_len);
+ }
+ sprintf(s2, "%d", *shortvalp);
+ fstrcat(stmnt, s2, &stmnt_len);
+ break;
+ case NC_INT:
+ intvalp = (int *) rec_start;
+ for (ival = 0; ival < var_len-1; ival++) {
+ sprintf(s2, "%ld, ", (long)*intvalp++);
+ fstrcat(stmnt, s2, &stmnt_len);
+ }
+ sprintf(s2, "%ld", (long)*intvalp);
+ fstrcat(stmnt, s2, &stmnt_len);
+ break;
+ case NC_FLOAT:
+ floatvalp = (float *) rec_start;
+ for (ival = 0; ival < var_len-1; ival++) {
+ sprintf(s2, "%.8g, ", *floatvalp++);
+ fstrcat(stmnt, s2, &stmnt_len);
+ }
+ sprintf(s2, "%.8g", *floatvalp);
+ fstrcat(stmnt, s2, &stmnt_len);
+ break;
+ case NC_DOUBLE:
+ doublevalp = (double *) rec_start;
+ for (ival = 0; ival < var_len-1; ival++) {
+ sprintf(s2, "%#.16g", *doublevalp++);
+ tztrim(s2);
+ expe2d(s2); /* change 'e' to 'd' in exponent */
+ fstrcat(s2, ", ", &stmnt_len);
+ fstrcat(stmnt, s2, &stmnt_len);
+ }
+ sprintf(s2, "%#.16g", *doublevalp++);
+ tztrim(s2);
+ expe2d(s2);
+ fstrcat(stmnt, s2, &stmnt_len);
+ break;
+ case NC_UBYTE:
+ ubytevalp = (unsigned char *) rec_start;
+ for (ival = 0; ival < var_len-1; ival++) {
+ sprintf(s2, "%hhu, ", (unsigned char)*ubytevalp++);
+ fstrcat(stmnt, s2, &stmnt_len);
+ }
+ sprintf(s2, "%hhu", (unsigned char)*ubytevalp);
+ fstrcat(stmnt, s2, &stmnt_len);
+ break;
+ case NC_USHORT:
+ ushortvalp = (unsigned short *) rec_start;
+ for (ival = 0; ival < var_len-1; ival++) {
+ sprintf(s2, "%hu, ", (unsigned short)*ushortvalp++);
+ fstrcat(stmnt, s2, &stmnt_len);
+ }
+ sprintf(s2, "%hu", (unsigned short)*ushortvalp);
+ fstrcat(stmnt, s2, &stmnt_len);
+ break;
+ case NC_UINT:
+ uintvalp = (unsigned int *) rec_start;
+ for (ival = 0; ival < var_len-1; ival++) {
+ sprintf(s2, "%u, ", (unsigned int)*uintvalp++);
+ fstrcat(stmnt, s2, &stmnt_len);
+ }
+ sprintf(s2, "%u", (unsigned int)*uintvalp);
+ fstrcat(stmnt, s2, &stmnt_len);
+ break;
+ case NC_INT64:
+ int64valp = (long long *) rec_start;
+ for (ival = 0; ival < var_len-1; ival++) {
+ sprintf(s2, "%lld, ", (long long)*int64valp++);
+ fstrcat(stmnt, s2, &stmnt_len);
+ }
+ sprintf(s2, "%lld", (long long)*int64valp);
+ fstrcat(stmnt, s2, &stmnt_len);
+ break;
+ case NC_UINT64:
+ uint64valp = (unsigned long long *) rec_start;
+ for (ival = 0; ival < var_len-1; ival++) {
+ sprintf(s2, "%llu, ", (unsigned long long)*uint64valp++);
+ fstrcat(stmnt, s2, &stmnt_len);
+ }
+ sprintf(s2, "%llu", (unsigned long long)*uint64valp);
+ fstrcat(stmnt, s2, &stmnt_len);
+ break;
+ default:
+ derror("fstrstr: bad type");
+ break;
+ }
+ fstrcat(stmnt, "/", &stmnt_len);
+
+ /* For record variables, store data statement for later use;
+ otherwise, just print it. */
+ if (vars[varnum].ndims > 0 && vars[varnum].dims[0] == rec_dim) {
+ char *dup_stmnt = (char*) emalloc(strlen(stmnt)+1);
+ strcpy(dup_stmnt, stmnt); /* ULTRIX missing strdup */
+ vars[varnum].data_stmnt = dup_stmnt;
+ } else {
+ fline(stmnt);
+ }
+}
+
+
+/* make Fortran to put record */
+static void
+gen_load_fortran(
+ void *rec_start
+ )
+{
+ char stmnt[FORT_MAX_STMNT];
+ struct vars *v = &vars[varnum];
+
+ if (!v->has_data)
+ return;
+
+ if (v->ndims == 0 || v->dims[0] != rec_dim) {
+ sprintf(stmnt, "* store %s", v->name);
+ fline(stmnt);
+ }
+
+ /* generate code to initialize variable with values found in CDL input */
+ if (v->type != NC_CHAR) {
+ f_var_init(varnum, (char*)rec_start);
+ } else {
+ v->data_stmnt = (char*) fstrstr((char*)rec_start, valnum);
+ }
+
+ if (v->ndims >0 && v->dims[0] == rec_dim) {
+ return;
+ }
+ if (v->type != NC_CHAR) {
+ sprintf(stmnt, "iret = nf_put_var_%s(ncid, %s_id, %s)",
+ nfftype(v->type), v->lname, v->lname);
+ } else {
+ char *char_expr = (char*) fstrstr((char*)rec_start, valnum);
+ sprintf(stmnt, "iret = nf_put_var_%s(ncid, %s_id, %s)",
+ nfftype(v->type), v->lname, char_expr);
+ free(char_expr);
+ }
+
+ fline(stmnt);
+ fline("call check_err(iret)");
+}
+
+
+/* invoke netcdf calls (or generate C or Fortran code) to load netcdf variable
+ * from in-memory data. Assumes following global variables set from yacc
+ * parser:
+ * int varnum - number of variable to be loaded.
+ * struct vars[varnum] - structure containing info on variable, specifically
+ * name, type, ndims, dims, fill_value, has_data
+ * int rec_dim - id of record dimension, or -1 if none
+ * struct dims[] - structure containing name and size of dimensions.
+ */
+int
+put_variable(void *rec_start) /* points to data to be loaded */
+{
+ if (netcdf_flag)
+ load_netcdf(rec_start); /* put variable values */
+ if (c_flag) /* create C code to put values */
+ gen_load_c(rec_start);
+ if (fortran_flag) /* create Fortran code to put values */
+ gen_load_fortran(rec_start);
+
+ return 0;
+}
+
+
+/* write out variable's data from in-memory structure */
+void
+load_netcdf(void *rec_start)
+{
+ int i, idim;
+ int stat = NC_NOERR;
+ MPI_Offset start[NC_MAX_VAR_DIMS];
+ MPI_Offset count[NC_MAX_VAR_DIMS];
+ char *charvalp = NULL;
+ short *shortvalp = NULL;
+ int *intvalp = NULL;
+ float *floatvalp = NULL;
+ double *doublevalp = NULL;
+ unsigned char *ubytevalp = NULL;
+ unsigned short *ushortvalp = NULL;
+ unsigned int *uintvalp = NULL;
+ long long *int64valp = NULL;
+ unsigned long long *uint64valp = NULL;
+ MPI_Offset total_size;
+
+ /* load values into variable */
+
+ switch (vars[varnum].type) {
+ case NC_CHAR:
+ case NC_BYTE:
+ charvalp = (char *) rec_start;
+ break;
+ case NC_SHORT:
+ shortvalp = (short *) rec_start;
+ break;
+ case NC_INT:
+ intvalp = (int *) rec_start;
+ break;
+ case NC_FLOAT:
+ floatvalp = (float *) rec_start;
+ break;
+ case NC_DOUBLE:
+ doublevalp = (double *) rec_start;
+ break;
+ case NC_UBYTE:
+ ubytevalp = (unsigned char *) rec_start;
+ break;
+ case NC_USHORT:
+ ushortvalp = (unsigned short *) rec_start;
+ break;
+ case NC_UINT:
+ uintvalp = (unsigned int *) rec_start;
+ break;
+ case NC_INT64:
+ int64valp = (long long *) rec_start;
+ break;
+ case NC_UINT64:
+ uint64valp = (unsigned long long *) rec_start;
+ break;
+ default:
+ derror("Unhandled type %d\n", vars[varnum].type);
+ break;
+ }
+ if (vars[varnum].ndims > 0) {
+ /* initialize start to upper left corner (0,0,0,...) */
+ start[0] = 0;
+ if (vars[varnum].dims[0] == rec_dim) {
+ count[0] = vars[varnum].nrecs;
+ }
+ else {
+ count[0] = dims[vars[varnum].dims[0]].size;
+ }
+ }
+
+ for (idim = 1; idim < vars[varnum].ndims; idim++) {
+ start[idim] = 0;
+ count[idim] = dims[vars[varnum].dims[idim]].size;
+ }
+
+ total_size = nctypesize(vars[varnum].type);
+ for (idim=0; idim<vars[varnum].ndims; idim++)
+ total_size *= count[idim];
+
+ /* If the total put size is more than 2GB, then put one subarray at a time.
+ * Here the subarray is from 1, 2, ... ndims, except 0.
+ * This is not a perfect solution. To be improved.
+ */
+ if (total_size > INT_MAX) {
+ MPI_Offset nchunks=count[0];
+ MPI_Offset subarray_nelems=1;
+ for (idim=1; idim<vars[varnum].ndims; idim++)
+ subarray_nelems *= count[idim];
+
+ count[0] = 1;
+ switch (vars[varnum].type) {
+ case NC_BYTE:
+ for (i=0; i<nchunks; i++) {
+ start[0] = i;
+ stat = ncmpi_put_vara_schar_all(ncid, varnum, start, count, (signed char *)charvalp);
+ check_err(stat, "ncmpi_put_vara_schar_all", __func__, __LINE__, __FILE__);
+ charvalp += subarray_nelems;
+ }
+ break;
+ case NC_CHAR:
+ for (i=0; i<nchunks; i++) {
+ start[0] = i;
+ stat = ncmpi_put_vara_text_all(ncid, varnum, start, count, charvalp);
+ check_err(stat, "ncmpi_put_vara_text_all", __func__, __LINE__, __FILE__);
+ charvalp += subarray_nelems;
+ }
+ break;
+ case NC_SHORT:
+ for (i=0; i<nchunks; i++) {
+ start[0] = i;
+ stat = ncmpi_put_vara_short_all(ncid, varnum, start, count, shortvalp);
+ check_err(stat, "ncmpi_put_vara_short_all", __func__, __LINE__, __FILE__);
+ shortvalp += subarray_nelems;
+ }
+ break;
+ case NC_INT:
+ for (i=0; i<nchunks; i++) {
+ start[0] = i;
+ stat = ncmpi_put_vara_int_all(ncid, varnum, start, count, intvalp);
+ check_err(stat, "ncmpi_put_vara_int_all", __func__, __LINE__, __FILE__);
+ intvalp += subarray_nelems;
+ }
+ break;
+ case NC_FLOAT:
+ for (i=0; i<nchunks; i++) {
+ start[0] = i;
+ stat = ncmpi_put_vara_float_all(ncid, varnum, start, count, floatvalp);
+ check_err(stat, "ncmpi_put_vara_float_all", __func__, __LINE__, __FILE__);
+ floatvalp += subarray_nelems;
+ }
+ break;
+ case NC_DOUBLE:
+ for (i=0; i<nchunks; i++) {
+ start[0] = i;
+ stat = ncmpi_put_vara_double_all(ncid, varnum, start, count, doublevalp);
+ check_err(stat, "ncmpi_put_vara_double_all", __func__, __LINE__, __FILE__);
+ doublevalp += subarray_nelems;
+ }
+ break;
+ case NC_UBYTE:
+ for (i=0; i<nchunks; i++) {
+ start[0] = i;
+ stat = ncmpi_put_vara_uchar_all(ncid, varnum, start, count, ubytevalp);
+ check_err(stat, "ncmpi_put_vara_uchar_all", __func__, __LINE__, __FILE__);
+ ubytevalp += subarray_nelems;
+ }
+ break;
+ case NC_USHORT:
+ for (i=0; i<nchunks; i++) {
+ start[0] = i;
+ stat = ncmpi_put_vara_ushort_all(ncid, varnum, start, count, ushortvalp);
+ check_err(stat, "ncmpi_put_vara_ushort_all", __func__, __LINE__, __FILE__);
+ ushortvalp += subarray_nelems;
+ }
+ break;
+ case NC_UINT:
+ for (i=0; i<nchunks; i++) {
+ start[0] = i;
+ stat = ncmpi_put_vara_uint_all(ncid, varnum, start, count, uintvalp);
+ check_err(stat, "ncmpi_put_vara_uint_all", __func__, __LINE__, __FILE__);
+ uintvalp += subarray_nelems;
+ }
+ break;
+ case NC_INT64:
+ for (i=0; i<nchunks; i++) {
+ start[0] = i;
+ stat = ncmpi_put_vara_longlong_all(ncid, varnum, start, count, int64valp);
+ check_err(stat, "ncmpi_put_vara_longlong_all", __func__, __LINE__, __FILE__);
+ int64valp += subarray_nelems;
+ }
+ break;
+ case NC_UINT64:
+ for (i=0; i<nchunks; i++) {
+ start[0] = i;
+ stat = ncmpi_put_vara_ulonglong_all(ncid, varnum, start, count, uint64valp);
+ check_err(stat, "ncmpi_put_vara_ulonglong_all", __func__, __LINE__, __FILE__);
+ uint64valp += subarray_nelems;
+ }
+ break;
+ default:
+ derror("Unhandled type %d\n", vars[varnum].type);
+ break;
+ }
+ }
+ else {
+ switch (vars[varnum].type) {
+ case NC_BYTE:
+ stat = ncmpi_put_vara_schar_all(ncid, varnum, start, count, (signed char *)charvalp);
+ check_err(stat, "ncmpi_put_vara_schar_all", __func__, __LINE__, __FILE__);
+ break;
+ case NC_CHAR:
+ stat = ncmpi_put_vara_text_all(ncid, varnum, start, count, charvalp);
+ check_err(stat, "ncmpi_put_vara_text_all", __func__, __LINE__, __FILE__);
+ break;
+ case NC_SHORT:
+ stat = ncmpi_put_vara_short_all(ncid, varnum, start, count, shortvalp);
+ check_err(stat, "ncmpi_put_vara_short_all", __func__, __LINE__, __FILE__);
+ break;
+ case NC_INT:
+ stat = ncmpi_put_vara_int_all(ncid, varnum, start, count, intvalp);
+ check_err(stat, "ncmpi_put_vara_int_all", __func__, __LINE__, __FILE__);
+ break;
+ case NC_FLOAT:
+ stat = ncmpi_put_vara_float_all(ncid, varnum, start, count, floatvalp);
+ check_err(stat, "ncmpi_put_vara_float_all", __func__, __LINE__, __FILE__);
+ break;
+ case NC_DOUBLE:
+ stat = ncmpi_put_vara_double_all(ncid, varnum, start, count, doublevalp);
+ check_err(stat, "ncmpi_put_vara_double_all", __func__, __LINE__, __FILE__);
+ break;
+ case NC_UBYTE:
+ stat = ncmpi_put_vara_uchar_all(ncid, varnum, start, count, ubytevalp);
+ check_err(stat, "ncmpi_put_vara_uchar_all", __func__, __LINE__, __FILE__);
+ break;
+ case NC_USHORT:
+ stat = ncmpi_put_vara_ushort_all(ncid, varnum, start, count, ushortvalp);
+ check_err(stat, "ncmpi_put_vara_ushort_all", __func__, __LINE__, __FILE__);
+ break;
+ case NC_UINT:
+ stat = ncmpi_put_vara_uint_all(ncid, varnum, start, count, uintvalp);
+ check_err(stat, "ncmpi_put_vara_uint_all", __func__, __LINE__, __FILE__);
+ break;
+ case NC_INT64:
+ stat = ncmpi_put_vara_longlong_all(ncid, varnum, start, count, int64valp);
+ check_err(stat, "ncmpi_put_vara_longlong_all", __func__, __LINE__, __FILE__);
+ break;
+ case NC_UINT64:
+ stat = ncmpi_put_vara_ulonglong_all(ncid, varnum, start, count, uint64valp);
+ check_err(stat, "ncmpi_put_vara_ulonglong_all", __func__, __LINE__, __FILE__);
+ break;
+ default:
+ derror("Unhandled type %d\n", vars[varnum].type);
+ break;
+ }
+ }
+}
diff --git a/src/utils/ncmpigen/main.c b/src/utils/ncmpigen/main.c
new file mode 100644
index 0000000..00e96d8
--- /dev/null
+++ b/src/utils/ncmpigen/main.c
@@ -0,0 +1,223 @@
+/*********************************************************************
+ * Copyright 1993, UCAR/Unidata
+ * See netcdf/COPYRIGHT file for copying and redistribution conditions.
+ * $Header$
+ *********************************************************************/
+
+#if HAVE_CONFIG_H
+# include <ncconfig.h>
+#endif
+
+#include <stdio.h> /* has getopt() under VMS */
+#include <string.h>
+
+#ifdef __hpux
+#include <locale.h> /* setlocale() */
+#endif
+
+#include <pnetcdf.h>
+
+#include <unistd.h>
+
+#include "generic.h"
+#include "ncmpigen.h"
+#include "genlib.h"
+
+extern int ncmpiparse(void);
+
+const char *progname; /* for error messages */
+const char *cdlname;
+
+int c_flag;
+int fortran_flag;
+int netcdf_flag;
+int giantfile_flag;
+int giantvar_flag;
+int nofill_flag;
+char *netcdf_name = NULL; /* name of output netCDF file to write */
+
+extern FILE *ncmpiin;
+
+static const char* ubasename ( const char* av0 );
+static void usage ( void );
+int main ( int argc, char** argv );
+
+
+/* strip off leading path */
+static const char *
+ubasename(
+ const char *av0)
+{
+ const char *logident ;
+#ifdef VMS
+#define SEP ']'
+#endif
+#ifdef MSDOS
+#define SEP '\\'
+#endif
+#ifndef SEP
+#define SEP '/'
+#endif
+ if ((logident = strrchr(av0, SEP)) == NULL)
+ logident = av0 ;
+ else
+ logident++ ;
+ return logident ;
+}
+
+
+static void usage(void)
+{
+ derror("Usage: %s [ -b ] [ -c ] [ -f ] [ -v version ] [ -x ] [ -o outfile] [ file ... ]",
+ progname);
+ derror("PnetCDF library version %s", ncmpi_inq_libvers());
+}
+
+
+int
+main(int argc, char *argv[])
+{
+ extern int optind;
+ extern int opterr;
+ extern char *optarg;
+ int c;
+ int ret;
+ FILE *fp;
+
+ MPI_Init(&argc, &argv);
+
+#ifdef __hpux
+ setlocale(LC_CTYPE,"");
+#endif
+
+#ifdef MDEBUG
+ malloc_debug(2) ; /* helps find malloc/free errors on Sun */
+#endif /* MDEBUG */
+
+ opterr = 1; /* print error message if bad option */
+ progname = ubasename(argv[0]);
+ cdlname = "-";
+
+ c_flag = 0;
+ fortran_flag = 0;
+ netcdf_flag = 0;
+ giantfile_flag = 0;
+ giantvar_flag = 0;
+ nofill_flag = 0;
+
+#if 0
+#if _CRAYMPP && 0
+ /* initialize CRAY MPP parallel-I/O library */
+ (void) par_io_init(32, 32);
+#endif
+#endif
+
+ while ((c = getopt(argc, argv, "bcfl:no:v:x")) != EOF)
+ switch(c) {
+ case 'c': /* for c output. old version of '-lc' */
+ c_flag = 1;
+ break;
+ case 'f': /* for fortran output. old version of '-lf' */
+ fortran_flag = 1;
+ break;
+ case 'b': /* for binary netcdf output, ".nc" extension */
+ netcdf_flag = 1;
+ break;
+ case 'l': /* specify language, instead of -c or -f */
+ {
+ char *lang_name = (char *) emalloc(strlen(optarg)+1);
+ if (! lang_name) {
+ derror ("%s: out of memory", progname);
+ return(1);
+ }
+ (void)strcpy(lang_name, optarg);
+ if (strcmp(lang_name, "c") == 0 || strcmp(lang_name, "C") == 0) {
+ c_flag = 1;
+ }
+ else if (strcmp(lang_name, "f77") == 0 ||
+ strcmp(lang_name, "fortran77") == 0 ||
+ strcmp(lang_name, "Fortran77") == 0) {
+ fortran_flag = 1;
+ } else { /* Fortran90, Java, C++, Perl, Python, Ruby, ... */
+ derror("%s: output language %s not implemented",
+ progname, lang_name);
+ return(1);
+ }
+ }
+ break;
+ case 'n': /* old version of -b, uses ".cdf" extension */
+ netcdf_flag = -1;
+ break;
+ case 'o': /* to explicitly specify output name */
+ netcdf_flag = 1;
+ netcdf_name = (char *) emalloc(strlen(optarg)+1);
+ if (! netcdf_name) {
+ derror ("%s: out of memory", progname);
+ return(1);
+ }
+ (void)strcpy(netcdf_name,optarg);
+ break;
+ case 'x': /* set nofill mode to speed up creation fo large files */
+ nofill_flag = 1;
+ break;
+ case 'v': /* for creating 64-bit offet files, specify version 2 */
+ {
+ char *version_name = (char *)emalloc(strlen(optarg)+1);
+ if (! version_name) {
+ derror ("%s: out of memory", progname);
+ return (1);
+ }
+ (void)strcpy(version_name, optarg);
+ /* the default version is version 1, with 32-bit offsets */
+ if (strcmp(version_name, "1") == 0 ||
+ strcmp(version_name, "classic") == 0) {
+ giantfile_flag = 0;
+ }
+ /* the 64-bit offset version (2) should only be used if
+ * actually needed */
+ else if (strcmp(version_name, "2") == 0 ||
+ strcmp(version_name, "64-bit-offset") == 0) {
+ giantfile_flag = 1;
+ } else if (strcmp(version_name, "5") == 0 ||
+ strcmp(version_name,
+ "64-bit-variables") == 0) {
+ giantvar_flag = 1;
+ }
+ }
+ break;
+ case '?':
+ usage();
+ return(8);
+ }
+
+ if (fortran_flag && c_flag) {
+ derror("Only one of -c or -f may be specified");
+ return(8);
+ }
+ if (fortran_flag) {
+ derror("Generating Fortran interface currently not supported yet");
+ return(0);
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ if (argc > 1) {
+ derror ("%s: only one input file argument permitted",progname);
+ return(6);
+ }
+
+ fp = stdin;
+ if (argc > 0 && strcmp(argv[0], "-") != 0) {
+ if ((fp = fopen(argv[0], "r")) == NULL) {
+ derror ("can't open file %s for reading: ", argv[0]);
+ perror("");
+ return(7);
+ }
+ cdlname = argv[0];
+ }
+ ncmpiin = fp;
+ ret = ncmpiparse();
+ MPI_Finalize();
+ return ret;
+}
diff --git a/src/utils/ncmpigen/ncmpigen.1 b/src/utils/ncmpigen/ncmpigen.1
new file mode 100644
index 0000000..094a956
--- /dev/null
+++ b/src/utils/ncmpigen/ncmpigen.1
@@ -0,0 +1,373 @@
+.\" $Header$
+.nr yr \n(yr+1900
+.af mo 01
+.af dy 01
+.TH NCMPIGEN 1 2013-11-17 "Printed: \n(yr-\n(mo-\n(dy" "UTILITIES"
+.SH NAME
+ncmpigen \- From a CDL file generate a netCDF file, a C program, or a Fortran
+program
+.SH SYNOPSIS
+.HP
+ncmpigen
+.nh
+\%[-b]
+\%[-c]
+\%[-f]
+\%[-n]
+\%[-o \fInetcdf_filename\fP]
+\%[-v \fIfile_format\fP]
+\%\fIinput_file\fP
+.hy
+.ft
+.SH DESCRIPTION
+\fBncmpigen\fP generates either a netCDF file, or C or Fortran source code to
+create a netCDF file. The input to \fBncmpigen\fP is a description of a netCDF
+file in a small language known as CDL (network Common Data form Language),
+described below.
+If no options are specified in invoking \fBncmpigen\fP, it merely checks the
+syntax of the input CDL file, producing error messages for
+any violations of CDL syntax. Other options can be used to create the
+corresponding netCDF file, to generate a C program that uses the netCDF C
+interface to create the netCDF file, or to generate a Fortran program that
+uses the netCDF Fortran interface to create the same netCDF file.
+.LP
+\fBncmpigen\fP may be used with the companion program \fBncmpidump\fP to perform
+some simple operations on netCDF files. For example, to rename a dimension
+in a netCDF file, use \fBncmpidump\fP to get a CDL version of the netCDF file,
+edit the CDL file to change the name of the dimensions, and use \fBncmpigen\fP
+to generate the corresponding netCDF file from the edited CDL file.
+.SH OPTIONS
+.IP "\fB-b\fP"
+Create a (binary) netCDF file. If the \fB-o\fP option is absent, a default
+file name will be constructed from the netCDF name (specified after the
+\fBnetcdf\fP keyword in the input) by appending the `.nc' extension. If a
+file already exists with the specified name, it will be overwritten.
+.IP "\fB-c\fP"
+Generate
+.B C
+source code that will create a netCDF file
+matching the netCDF specification. The C source code is written to
+standard output.
+.IP "\fB-f\fP"
+Generate
+.B Fortran
+source code that will create a netCDF file
+matching the netCDF specification. The Fortran source code is written
+to standard output.
+.IP "\fB-o\fP \fRnetcdf_file\fP"
+Name for the binary netCDF file created. If this option is specified, it implies
+the "\fB-b\fP" option. (This option is necessary because netCDF files
+cannot be written directly to standard output, since standard output is not
+seekable.)
+.IP "\fB-n\fP"
+Like \fB-b\fP option, except creates netCDF file with the obsolete `.cdf'
+extension instead of the `.nc' extension, in the absence of an output
+filename specified by the \fB-o\fP option. This option is only supported
+for backward compatibility.
+.IP "\fB-v\fP \fRfile_format\fP"
+File format of the output netCDF file. The value of \fRfile_format\fP can
+be:
+1 or classic for CDF-1 format.
+2 or 64-bit-offset is CDF-2.
+5 or 64-bit-variable for CDF-5.
+The default (if this option is not given) is CDF-1, the classic format.
+.SH EXAMPLES
+.LP
+Check the syntax of the CDL file `\fBfoo.cdl\fP':
+.RS
+.HP
+ncmpigen foo.cdl
+.RE
+.LP
+From the CDL file `\fBfoo.cdl\fP', generate an equivalent binary netCDF file
+named `\fBx.nc\fP':
+.RS
+.HP
+ncmpigen -o x.nc foo.cdl
+.RE
+.LP
+From the CDL file `\fBfoo.cdl\fP', generate a C program containing the
+netCDF function invocations necessary to create an equivalent binary netCDF
+file named `\fBx.nc\fP':
+.RS
+.HP
+ncmpigen -c -o x.nc foo.cdl
+.RE
+.LP
+.SH USAGE
+.SS "CDL Syntax Summary"
+.LP
+Below is an example of CDL syntax, describing a netCDF file with several
+named dimensions (lat, lon, and time), variables (Z, t, p, rh, lat, lon,
+time), variable attributes (units, long_name, valid_range, _FillValue), and
+some data. CDL keywords are in boldface. (This example is intended to
+illustrate the syntax; a real CDL file would have a more complete set of
+attributes so that the data would be more completely self-describing.)
+
+.RS
+.nf
+\fBnetcdf\fP foo { // an example netCDF specification in CDL
+
+\fBdimensions\fP:
+ lat = 10, lon = 5, time = \fBunlimited\fP ;
+
+\fBvariables\fP:
+ \fBlong\fP lat(lat), lon(lon), time(time);
+ \fBfloat\fP Z(time,lat,lon), t(time,lat,lon);
+ \fBdouble\fP p(time,lat,lon);
+ \fBlong\fP rh(time,lat,lon);
+
+ // variable attributes
+ lat:long_name = "latitude";
+ lat:units = "degrees_north";
+ lon:long_name = "longitude";
+ lon:units = "degrees_east";
+ time:units = "seconds since 1992-1-1 00:00:00";
+ Z:units = "geopotential meters";
+ Z:valid_range = 0., 5000.;
+ p:_FillValue = -9999.;
+ rh:_FillValue = -1;
+
+\fBdata\fP:
+ lat = 0, 10, 20, 30, 40, 50, 60, 70, 80, 90;
+ lon = -140, -118, -96, -84, -52;
+}
+.fi
+.RE
+.LP
+All CDL statements are terminated by a semicolon. Spaces, tabs,
+and newlines can be used freely for readability.
+Comments may follow the characters `//' on any line.
+.LP
+A CDL description consists of three optional parts: \fIdimensions\fP,
+\fIvariables\fP, and \fIdata\fP, beginning with the keyword
+.BR dimensions: ,
+.BR variables: ,
+and
+.BR data ,
+respectively.
+The variable part may contain \fIvariable
+declarations\fP and \fIattribute assignments\fP.
+.LP
+A netCDF \fIdimension\fP is used to define the shape of one or more of the
+multidimensional variables contained in the netCDF file. A netCDF
+dimension has a name and a size. At most one dimension in a netCDF file
+can have the \fBunlimited\fP size, which means a variable using this
+dimension can grow to any length (like a record number in a file).
+.LP
+A \fIvariable\fP represents a multidimensional array of values of the
+same type. A variable has a name, a data type, and a shape described
+by its list of dimensions. Each variable may also have associated
+\fIattributes\fP (see below) as well as data values. The name, data
+type, and shape of a variable are specified by its declaration in the
+\fIvariable\fP section of a CDL description. A variable may have the same
+name as a dimension; by convention such a variable is one-dimensional
+and contains coordinates of the dimension it names. Dimensions need
+not have corresponding variables.
+.LP
+A netCDF \fIattribute\fP contains information about a netCDF variable or
+about the whole netCDF dataset. Attributes are used
+to specify such properties as units, special values, maximum and
+minimum valid values, scaling factors, offsets, and parameters. Attribute
+information is represented by single values or arrays of values. For
+example, "units" is an attribute represented by a character array such
+as "celsius". An attribute has an associated variable, a name,
+a data type, a length, and a value. In contrast to variables that are
+intended for data, attributes are intended for metadata (data about
+data).
+.LP
+In CDL, an attribute is designated by a variable and attribute name,
+separated by `:'. It is possible to assign \fIglobal\fP attributes
+not associated with any variable to the netCDF as a whole by using
+`:' before the attribute name. The data type of an attribute in CDL
+is derived from the type of the value assigned to it. The length of
+an attribute is the number of data values assigned to it, or the
+number of characters in the character string assigned to it. Multiple
+values are assigned to non-character attributes by separating the
+values with commas. All values assigned to an attribute must be of
+the same type.
+.LP
+The names for CDL dimensions, variables, and attributes must begin with an
+alphabetic character or `_', and subsequent characters may be alphanumeric
+or `_' or `-'.
+.LP
+The optional \fIdata\fP section of a CDL specification is where
+netCDF variables may be initialized. The syntax of an initialization
+is simple: a variable name, an equals sign, and a
+comma-delimited list of constants (possibly separated by spaces, tabs
+and newlines) terminated with a semicolon. For multi-dimensional
+arrays, the last dimension varies fastest. Thus row-order rather than
+column order is used for matrices. If fewer values are supplied than
+are needed to fill a variable, it is extended with a type-dependent
+`fill value', which can be overridden by supplying a value for a
+distinguished variable attribute named `_FillValue'. The
+types of constants need not match the type declared for a variable;
+coercions are done to convert integers to floating point, for example.
+The constant `_' can be used to designate the fill value for a variable.
+.SS "Primitive Data Types"
+.LP
+.RS
+.nf
+\fBchar\fP characters
+\fBbyte\fP 8-bit data
+\fBshort\fP 16-bit signed integers
+\fBlong\fP 32-bit signed integers
+\fBint\fP (synonymous with \fBlong\fP)
+\fBfloat\fP IEEE single precision floating point (32 bits)
+\fBreal\fP (synonymous with \fBfloat\fP)
+\fBdouble\fP IEEE double precision floating point (64 bits)
+.fi
+.RE
+.LP
+Except for the added data-type \fBbyte\fP and the lack of
+\fBunsigned\fP,
+CDL supports the same primitive data types as C.
+The names for the primitive data types are reserved words in CDL,
+so the names of variables, dimensions, and attributes must not be
+type names. In declarations, type names may be specified
+in either upper or lower case.
+.LP
+Bytes differ from characters in that they are intended to hold a full eight
+bits of data, and the zero byte has no special significance, as it
+does for character data.
+\fBncmpigen\fP converts \fBbyte\fP declarations to \fBchar\fP
+declarations in the output C code and to the nonstandard \fBBYTE\fP
+declaration in output Fortran code.
+.LP
+Shorts can hold values between -32768 and 32767.
+\fBncmpigen\fP converts \fBshort\fP declarations to \fBshort\fP
+declarations in the output C code and to the nonstandard \fBINTEGER*2\fP
+declaration in output Fortran code.
+.LP
+Longs can hold values between -2147483648 and 2147483647.
+\fBncmpigen\fP converts \fBlong\fP declarations to \fBlong\fP
+declarations in the output C code and to \fBINTEGER\fP
+declarations in output Fortran code. \fBint\fP and \fBinteger\fP are
+accepted as synonyms for \fBlong\fP in CDL declarations.
+Now that there are platforms with 64-bit representations for C longs, it may
+be better to use the \fBint\fP synonym to avoid confusion.
+.LP
+Floats can hold values between about -3.4+38 and 3.4+38. Their
+external representation is as 32-bit IEEE normalized single-precision
+floating point numbers. \fBncmpigen\fP converts \fBfloat\fP
+declarations to \fBfloat\fP declarations in the output C code and to
+\fBREAL\fP declarations in output Fortran code. \fBreal\fP is accepted
+as a synonym for \fBfloat\fP in CDL declarations.
+.LP
+Doubles can hold values between about -1.7+308 and 1.7+308. Their
+external representation is as 64-bit IEEE standard normalized
+double-precision floating point numbers. \fBncmpigen\fP converts
+\fBdouble\fP declarations to \fBdouble\fP declarations in the output C
+code and to \fBDOUBLE PRECISION\fP declarations in output Fortran
+code.
+.LP
+.SS "CDL Constants"
+.LP
+Constants assigned to attributes or variables may be of any of the
+basic netCDF types. The syntax for constants is similar to C syntax,
+except that type suffixes must be appended to shorts and floats to
+distinguish them from longs and doubles.
+.LP
+A \fIbyte\fP constant is represented by a single character or multiple
+character escape sequence enclosed in single quotes. For example,
+.RS
+.nf
+ 'a' // ASCII `a'
+ '\\0' // a zero byte
+ '\\n' // ASCII newline character
+ '\\33' // ASCII escape character (33 octal)
+ '\\x2b' // ASCII plus (2b hex)
+ '\\377' // 377 octal = 255 decimal, non-ASCII
+.fi
+.RE
+.LP
+Character constants are enclosed in double quotes. A character array
+may be represented as a string enclosed in double quotes. The usual C
+string escape conventions are honored. For example
+.RS
+.nf
+"a" // ASCII `a'
+"Two\\nlines\\n" // a 10-character string with two embedded newlines
+"a bell:\\007" // a string containing an ASCII bell
+.fi
+.RE
+Note that the netCDF character array "a" would fit in a one-element
+variable, since no terminating NULL character is assumed. However, a zero
+byte in a character array is interpreted as the end of the significant
+characters by the \fBncmpidump\fP program, following the C convention.
+Therefore, a NULL byte should not be embedded in a character string unless
+at the end: use the \fIbyte\fP data type instead for byte arrays that
+contain the zero byte. NetCDF and CDL have no string type, but only
+fixed-length character arrays, which may be multi-dimensional.
+.LP
+\fIshort\fP integer constants are intended for representing 16-bit
+signed quantities. The form of a \fIshort\fP constant is an integer
+constant with an `s' or `S' appended. If a \fIshort\fP constant
+begins with `0', it is interpreted as octal, except that if it begins with
+`0x', it is interpreted as a hexadecimal constant. For example:
+.RS
+.nf
+-2s // a short -2
+0123s // octal
+0x7ffs //hexadecimal
+.fi
+.RE
+.LP
+\fILong\fP integer constants are intended for representing 32-bit signed
+quantities. The form of a \fIlong\fP constant is an ordinary integer
+constant, although it is acceptable to append an optional `l' or
+`L'. If a \fIlong\fP constant begins with `0', it is interpreted as
+octal, except that if it begins with `0x', it is interpreted as a hexadecimal
+constant. Examples of valid \fIlong\fP constants include:
+.RS
+.nf
+-2
+1234567890L
+0123 // octal
+0x7ff // hexadecimal
+.fi
+.RE
+.LP
+Floating point constants of type \fIfloat\fP are appropriate for representing
+floating point data with about seven significant digits of precision.
+The form of a \fIfloat\fP constant is the same as a C floating point
+constant with an `f' or `F' appended. For example the following
+are all acceptable \fIfloat\fP constants:
+.RS
+.nf
+-2.0f
+3.14159265358979f // will be truncated to less precision
+1.f
+.1f
+.fi
+.RE
+.LP
+Floating point constants of type \fIdouble\fP are appropriate for
+representing floating point data with about sixteen significant digits
+of precision. The form of a \fIdouble\fP constant is the same as a C
+floating point constant. An optional `d' or `D' may be appended.
+For example the following are all acceptable \fIdouble\fP constants:
+.RS
+.nf
+-2.0
+3.141592653589793
+1.0e-20
+1.d
+.fi
+.RE
+.SH DATE
+$Date: 2014-04-16 13:38:34 -0500 (Wed, 16 Apr 2014) $
+.SH BUGS
+.LP
+The programs generated by \fBncmpigen\fP when using the \fB-c\fP or \fB-f\fP
+use initialization statements to store data in variables, and will fail to
+produce compilable programs if you try to use them for large datasets, since
+the resulting statements may exceed the line length or number of
+continuation statements permitted by the compiler.
+.LP
+The CDL syntax makes it easy to assign what looks like an array of
+variable-length strings to a netCDF variable, but the strings will simply be
+concatenated into a single array of characters, since netCDF cannot
+represent an array of variable-length strings in one netCDF variable.
+.LP
+NetCDF and CDL do not yet support a type corresponding to a 64-bit integer.
diff --git a/src/utils/ncmpigen/ncmpigen.h b/src/utils/ncmpigen/ncmpigen.h
new file mode 100644
index 0000000..a5d0af9
--- /dev/null
+++ b/src/utils/ncmpigen/ncmpigen.h
@@ -0,0 +1,57 @@
+#ifndef NC_NCGEN_H
+#define NC_NCGEN_H
+/*********************************************************************
+ * Copyright 1993, UCAR/Unidata
+ * See netcdf/COPYRIGHT file for copying and redistribution conditions.
+ * $Header$
+ *********************************************************************/
+
+#define MAX_NC_ATTSIZE 20000 /* max size of attribute (for ncmpigen) */
+#define MAXTRST 5000 /* max size of string value (for ncmpigen) */
+
+#include <stdlib.h> /* size_t */
+#include "generic.h"
+
+extern int ncid; /* handle for netCDF */
+extern int ndims; /* number of dimensions declared for netcdf */
+extern int nvars; /* number of variables declared for netcdf */
+extern int natts; /* number of attributes */
+extern int nvdims; /* number of dimensions for variables */
+extern int dimnum; /* dimension number index for variables */
+extern int varnum; /* variable number index for attributes */
+extern int valnum; /* number of values specified for variable */
+extern int rec_dim; /* number of the unlimited dimension, if any */
+extern MPI_Offset rec_len; /* number of elements for a record of data */
+extern MPI_Offset var_len; /* variable length (product of dimensions) */
+extern MPI_Offset var_size; /* size of each element of variable */
+
+extern struct dims {
+ MPI_Offset size;
+ char *name;
+ char *lname; /* with no "-" characters, for C and Fortran */
+} *dims; /* table of dimensions */
+
+extern struct vars {
+ char *name;
+ nc_type type;
+ int ndims;
+ int *dims; /* array of dimension ids */
+ union generic fill_value; /* set to value of _FillValue attribute */
+ int has_data; /* 1 if data specified, 0 otherwise */
+ MPI_Offset nrecs; /* for record variables, number of records
+ * of data in CDL */
+ char *data_stmnt; /* for record variables, to avoid
+ * two passes with -f option */
+ char *lname; /* with no "-" characters, for C and Fortran */
+} *vars; /* table of variables */
+
+
+extern struct atts {
+ int var; /* number of variable for this attribute */
+ char *name;
+ nc_type type;
+ MPI_Offset len;
+ void *val;
+ char *lname; /* with no "-" characters, for C and Fortran */
+} *atts; /* table of variable and global attributes */
+#endif /*!NC_NCGEN_H*/
diff --git a/src/utils/ncmpigen/ncmpigen.l b/src/utils/ncmpigen/ncmpigen.l
new file mode 100644
index 0000000..914390c
--- /dev/null
+++ b/src/utils/ncmpigen/ncmpigen.l
@@ -0,0 +1,216 @@
+%{
+/*********************************************************************
+ * Copyright 1993, UCAR/Unidata
+ * See netcdf/COPYRIGHT file for copying and redistribution conditions.
+ * $Id: ncmpigen.l 2034 2015-05-29 18:52:08Z wkliao $
+ *********************************************************************/
+
+/* lex specification for tokens for ncmpigen */
+
+/* Fill value used by ncdump from version 2.4 and later. Should match
+ definition of FILL_STRING in ../ncdump/vardata.h */
+#define FILL_STRING "_"
+#define XDR_INT_MIN (-2147483647-1)
+#define XDR_INT_MAX 2147483647
+#define XDR_INT64_MIN (-9223372036854775807LL-1)
+#define XDR_INT64_MAX (9223372036854775807LL)
+
+char errstr[100]; /* for short error messages */
+
+#include <string.h>
+#include <ctype.h>
+#include <errno.h> /* errno */
+#include "genlib.h"
+#include "ncmpigentab.h"
+
+#define YY_BREAK /* defining as nothing eliminates unreachable
+ statement warnings from flex output,
+ but make sure every action ends with
+ "return" or "break"! */
+
+%}
+
+%p 6000
+
+escaped \\.
+nonquotes ([^"\\]|{escaped})*
+exp ([eE][+-]?[0-9]+)
+%%
+\/\/.* { /* comment */
+ break;
+ }
+
+\"{nonquotes}\" {
+ if(yyleng > MAXTRST) {
+ yyerror("string too long, truncated\n");
+ yytext[MAXTRST-1] = '\0';
+ }
+ expand_escapes(termstring,(char *)yytext,yyleng);
+ return (TERMSTRING);
+ }
+
+float|FLOAT|real|REAL {return (FLOAT_K);}
+char|CHAR {return (CHAR_K);}
+byte|BYTE {return (BYTE_K);}
+short|SHORT {return (SHORT_K);}
+long|LONG|int|INT|integer|INTEGER {return (INT_K);}
+double|DOUBLE {return (DOUBLE_K);}
+ubyte|UBYTE {return (UBYTE_K);}
+ushort|USHORT {return (USHORT_K);}
+uint|UINT {return (UINT_K);}
+int64|INT64 {return (INT64_K);}
+uint64|UINT64 {return (UINT64_K);}
+unlimited|UNLIMITED {int_val = -1;
+ return (NC_UNLIMITED_K);}
+
+dimensions:|DIMENSIONS: {return (DIMENSIONS);}
+variables:|VARIABLES: {return (VARIABLES);}
+data:|DATA: {return (DATA);}
+(netcdf|NETCDF|netCDF)[ \t]+[^\{]+ {
+ char *s = (char*)yytext+strlen("netcdf");
+ char *t = (char*)yytext+yyleng-1;
+ while (isspace(*s))
+ s++;
+ while (isspace(*t))
+ t--;
+ t++;
+ if (t-s+1 < 1) {
+ yyerror("netCDF name required");
+ return (DATA); /* generate syntax error */
+ }
+ netcdfname = (char *) emalloc(t-s+1);
+ (void) strncpy(netcdfname, s, t-s);
+ netcdfname[t-s] = '\0';
+ return (NETCDF);
+ }
+DoubleInf|NaN|-?Infinity { /* missing value (pre-2.4 backward compatibility) */
+ if (yytext[0] == '-') {
+ double_val = -NC_FILL_DOUBLE;
+ } else {
+ double_val = NC_FILL_DOUBLE;
+ }
+ return (DOUBLE_CONST);
+ }
+FloatInf|-?Inff { /* missing value (pre-2.4 backward compatibility) */
+ if (yytext[0] == '-') {
+ float_val = -NC_FILL_FLOAT;
+ } else {
+ float_val = NC_FILL_FLOAT;
+ }
+ return (FLOAT_CONST);
+ }
+[A-Za-z_][A-Z.@#\[\]a-z_0-9+-]* {
+ if (STREQ((char *)yytext, FILL_STRING))
+ return (FILLVALUE);
+ if ((yylval = lookup((char *)yytext)) == NULL) {
+ yylval = install((char *)yytext);
+ }
+ return (IDENT);
+ }
+
+\n {
+ lineno++ ;
+ break;
+ }
+
+[+-]?[0-9]*[0-9][Bb] {
+ int ii;
+ if (sscanf((char*)yytext, "%d", &ii) != 1) {
+ sprintf(errstr,"bad byte constant: %s",(char*)yytext);
+ yyerror(errstr);
+ }
+ byte_val = ii;
+ if (ii != (int)byte_val) {
+ sprintf(errstr,"byte constant out of range (-128,127): %s",(char*)yytext);
+ yyerror(errstr);
+ }
+ return (BYTE_CONST);
+ }
+
+[+-]?[0-9]*\.[0-9]*{exp}?[LlDd]?|[+-]?[0-9]*{exp}[LlDd]? {
+ if (sscanf((char*)yytext, "%le", &double_val) != 1) {
+ sprintf(errstr,"bad long or double constant: %s",(char*)yytext);
+ yyerror(errstr);
+ }
+ return (DOUBLE_CONST);
+ }
+[+-]?[0-9]*\.[0-9]*{exp}?[Ff]|[+-]?[0-9]*{exp}[Ff] {
+ if (sscanf((char*)yytext, "%e", &float_val) != 1) {
+ sprintf(errstr,"bad float constant: %s",(char*)yytext);
+ yyerror(errstr);
+ }
+ return (FLOAT_CONST);
+ }
+[+-]?[0-9]+[sS]|0[xX][0-9a-fA-F]+[sS] {
+ if (sscanf((char*)yytext, "%hd", &short_val) != 1) {
+ sprintf(errstr,"bad short constant: %s",(char*)yytext);
+ yyerror(errstr);
+ }
+ return (SHORT_CONST);
+ }
+[+-]?([1-9][0-9]*|0)[lL]? {
+ char *ptr;
+ errno = 0;
+ double_val = strtod((char*)yytext, &ptr);
+ if (errno != 0 && double_val == 0.0) {
+ sprintf(errstr,"bad numerical constant: %s",(char*)yytext);
+ yyerror(errstr);
+ }
+ if (double_val < XDR_INT_MIN ||double_val > XDR_INT_MAX) {
+ return DOUBLE_CONST;
+ } else {
+ int_val = (int) double_val;
+ return INT_CONST;
+ }
+ }
+0[xX]?[0-9a-fA-F]+[lL]? {
+ char *ptr;
+ long long_val;
+ errno = 0;
+ long_val = strtol((char*)yytext, &ptr, 0);
+ if (errno != 0) {
+ sprintf(errstr,"bad long constant: %s",(char*)yytext);
+ yyerror(errstr);
+ }
+ if (long_val < XDR_INT_MIN || long_val > XDR_INT_MAX) {
+ double_val = (double) long_val;
+ return DOUBLE_CONST;
+ } else {
+ int_val = (int) long_val;
+ return INT_CONST;
+ }
+ }
+\'[^\\]\' {
+ (void) sscanf((char*)&yytext[1],"%c",&byte_val);
+ return (BYTE_CONST);
+ }
+\'\\[0-7][0-7]?[0-7]?\' {
+ byte_val = (char) strtol((char*)&yytext[2], (char **) 0, 8);
+ return (BYTE_CONST);
+ }
+\'\\[xX][0-9a-fA-F][0-9a-fA-F]?\' {
+ byte_val = (char) strtol((char*)&yytext[3], (char **) 0, 16);
+ return (BYTE_CONST);
+ }
+\'\\.\' {
+ switch ((char)yytext[2]) {
+ case 'a': byte_val = '\007'; break; /* not everyone under-
+ * stands '\a' yet */
+ case 'b': byte_val = '\b'; break;
+ case 'f': byte_val = '\f'; break;
+ case 'n': byte_val = '\n'; break;
+ case 'r': byte_val = '\r'; break;
+ case 't': byte_val = '\t'; break;
+ case 'v': byte_val = '\v'; break;
+ case '\\': byte_val = '\\'; break;
+ case '?': byte_val = '\177'; break;
+ case '\'': byte_val = '\''; break;
+ default: byte_val = (char)yytext[2];
+ }
+ return (BYTE_CONST);
+ }
+
+[ \t\f]+ { /* whitespace */
+ break;
+ }
+. return (yytext[0]) ;
diff --git a/src/utils/ncmpigen/ncmpigen.y b/src/utils/ncmpigen/ncmpigen.y
new file mode 100644
index 0000000..600ea79
--- /dev/null
+++ b/src/utils/ncmpigen/ncmpigen.y
@@ -0,0 +1,1317 @@
+/*********************************************************************
+ * Copyright 1993, UCAR/Unidata
+ * See netcdf/COPYRIGHT file for copying and redistribution conditions.
+ * $Id: ncmpigen.y 2238 2015-12-18 18:20:25Z wkliao $
+ *********************************************************************/
+
+/* yacc source for "ncmpigen", a netCDL parser and netCDF generator */
+
+%{
+#ifdef sccs
+static char SccsId[] = "$Id: ncmpigen.y 2238 2015-12-18 18:20:25Z wkliao $";
+#endif
+
+#include <string.h>
+#include <stdlib.h>
+#include <stddef.h> /* ptrdiff_t */
+#include <pnetcdf.h>
+#include "generic.h"
+#include "ncmpigen.h"
+#include "genlib.h" /* for grow_darray() et al */
+
+typedef struct Symbol { /* symbol table entry */
+ char *name;
+ struct Symbol *next;
+ unsigned is_dim : 1; /* appears as netCDF dimension */
+ unsigned is_var : 1; /* appears as netCDF variable */
+ unsigned is_att : 1; /* appears as netCDF attribute */
+ int dnum; /* handle as a dimension */
+ int vnum; /* handle as a variable */
+ } *YYSTYPE1;
+
+/* True if string a equals string b*/
+#define STREQ(a, b) (*(a) == *(b) && strcmp((a), (b)) == 0)
+#define NC_UNSPECIFIED ((nc_type)0) /* unspecified (as yet) type */
+
+#define YYSTYPE YYSTYPE1
+YYSTYPE symlist; /* symbol table: linked list */
+
+extern int derror_count; /* counts errors in netcdf definition */
+extern int lineno; /* line number for error messages */
+
+static int not_a_string; /* whether last constant read was a string */
+static char termstring[MAXTRST]; /* last terminal string read */
+static double double_val; /* last double value read */
+static float float_val; /* last float value read */
+static int int_val; /* last int value read */
+static short short_val; /* last short value read */
+static char char_val; /* last char value read */
+static signed char byte_val; /* last byte value read */
+static unsigned char ubyte_val; /* last byte value read */
+static unsigned short ushort_val; /* last byte value read */
+static unsigned int uint_val; /* last byte value read */
+static long long int64_val; /* last byte value read */
+static unsigned long long uint64_val; /* last byte value read */
+
+static nc_type type_code; /* holds declared type for variables */
+static nc_type atype_code; /* holds derived type for attributes */
+static char *netcdfname; /* to construct netcdf file name */
+static void *att_space; /* pointer to block for attribute values */
+static nc_type valtype; /* type code for list of attribute values */
+
+static char *char_valp; /* pointers used to accumulate data values */
+static signed char *byte_valp;
+static short *short_valp;
+static int *int_valp;
+static float *float_valp;
+static double *double_valp;
+static unsigned char *ubyte_valp;
+static unsigned short *ushort_valp;
+static unsigned int *uint_valp;
+static long long *int64_valp;
+static unsigned long long *uint64_valp;
+
+static void *rec_cur; /* pointer to where next data value goes */
+static void *rec_start; /* start of space for data */
+
+/* Forward declarations */
+void defatt(void);
+void equalatt(void);
+
+#ifdef YYLEX_PARAM
+int yylex(YYLEX_PARAM);
+#else
+int yylex(void);
+#endif
+
+#ifdef vms
+void yyerror(char*);
+#else
+int yyerror(char*);
+#endif
+%}
+
+/* DECLARATIONS */
+
+%token
+ NC_UNLIMITED_K /* keyword for unbounded record dimension */
+ BYTE_K /* keyword for byte datatype */
+ CHAR_K /* keyword for char datatype */
+ SHORT_K /* keyword for short datatype */
+ INT_K /* keyword for int datatype */
+ FLOAT_K /* keyword for float datatype */
+ DOUBLE_K /* keyword for double datatype */
+ UBYTE_K /* keyword for unsigned char datatype */
+ USHORT_K /* keyword for unsigned short datatype */
+ UINT_K /* keyword for unsigned int datatype */
+ INT64_K /* keyword for long long datatype */
+ UINT64_K /* keyword for unsigned long long datatype */
+ IDENT /* name for a dimension, variable, or attribute */
+ TERMSTRING /* terminal string */
+ BYTE_CONST /* byte constant */
+ CHAR_CONST /* char constant */
+ SHORT_CONST /* short constant */
+ INT_CONST /* int constant */
+ FLOAT_CONST /* float constant */
+ DOUBLE_CONST /* double constant */
+ UBYTE_CONST /* unsigned char constant */
+ USHORT_CONST /* unsigned short constant */
+ UINT_CONST /* unsigned int constant */
+ INT64_CONST /* long long constant */
+ UINT64_CONST /* unsigned long long constant */
+ DIMENSIONS /* keyword starting dimensions section, if any */
+ VARIABLES /* keyword starting variables section, if any */
+ NETCDF /* keyword declaring netcdf name */
+ DATA /* keyword starting data section, if any */
+ FILLVALUE /* fill value, from _FillValue attribute or default */
+
+%start ncdesc /* start symbol for grammar */
+
+%%
+
+/* RULES */
+
+ncdesc: NETCDF
+ '{'
+ { init_netcdf(); }
+ dimsection /* dimension declarations */
+ vasection /* variable and attribute declarations */
+ {
+ if (derror_count == 0)
+ define_netcdf(netcdfname);
+ if (derror_count > 0)
+ exit(6);
+ }
+ datasection /* data, variables loaded as encountered */
+ '}'
+ {
+ if (derror_count == 0)
+ close_netcdf();
+ }
+ ;
+dimsection: /* empty */
+ | DIMENSIONS dimdecls
+ ;
+dimdecls: dimdecline ';'
+ | dimdecls dimdecline ';'
+ ;
+dimdecline: dimdecl
+ | dimdecline ',' dimdecl
+ ;
+dimdecl: dimd '=' INT_CONST
+ { if (int_val <= 0)
+ derror("dimension length must be positive");
+ dims[ndims].size = int_val;
+ ndims++;
+ }
+ | dimd '=' DOUBLE_CONST
+ { /* for rare case where 2^31 < dimsize < 2^32 */
+ if (double_val <= 0)
+ derror("dimension length must be positive");
+ if (double_val > 4294967295.0)
+ derror("dimension too large");
+ if (double_val - (MPI_Offset) double_val > 0)
+ derror("dimension length must be an integer");
+ dims[ndims].size = (MPI_Offset) double_val;
+ ndims++;
+ }
+ | dimd '=' NC_UNLIMITED_K
+ { if (rec_dim != -1)
+ derror("only one NC_UNLIMITED dimension allowed");
+ rec_dim = ndims; /* the unlimited (record) dimension */
+ dims[ndims].size = NC_UNLIMITED;
+ ndims++;
+ }
+ ;
+dimd: dim
+ {
+ if ($1->is_dim == 1) {
+ derror( "duplicate dimension declaration for %s",
+ $1->name);
+ }
+ $1->is_dim = 1;
+ $1->dnum = ndims;
+ /* make sure dims array will hold dimensions */
+ grow_darray(ndims, /* must hold ndims+1 dims */
+ &dims); /* grow as needed */
+ dims[ndims].name = (char *) emalloc(strlen($1->name)+1);
+ (void) strcpy(dims[ndims].name, $1->name);
+ /* name for use in generated Fortran and C variables */
+ dims[ndims].lname = decodify($1->name);
+ }
+ ;
+dim: IDENT
+ ;
+vasection: /* empty */
+ | VARIABLES vadecls
+ | gattdecls
+ ;
+vadecls: vadecl ';'
+ | vadecls vadecl ';'
+ ;
+vadecl: vardecl | attdecl | gattdecl
+ ;
+gattdecls: gattdecl ';'
+ | gattdecls gattdecl ';'
+ ;
+vardecl: type varlist
+ ;
+type: BYTE_K { type_code = NC_BYTE; }
+ | CHAR_K { type_code = NC_CHAR; }
+ | SHORT_K { type_code = NC_SHORT; }
+ | INT_K { type_code = NC_INT; }
+ | FLOAT_K { type_code = NC_FLOAT; }
+ | DOUBLE_K{ type_code = NC_DOUBLE; }
+ | UBYTE_K { type_code = NC_UBYTE; }
+ | USHORT_K{ type_code = NC_USHORT; }
+ | UINT_K { type_code = NC_UINT; }
+ | INT64_K { type_code = NC_INT64; }
+ | UINT64_K{ type_code = NC_UINT64; }
+ ;
+varlist: varspec
+ | varlist ',' varspec
+ ;
+varspec: var
+ {
+ static struct vars dummyvar;
+
+ dummyvar.name = "dummy";
+ dummyvar.type = NC_DOUBLE;
+ dummyvar.ndims = 0;
+ dummyvar.dims = 0;
+ dummyvar.fill_value.doublev = NC_FILL_DOUBLE;
+ dummyvar.has_data = 0;
+
+ nvdims = 0;
+ /* make sure variable not re-declared */
+ if ($1->is_var == 1) {
+ derror( "duplicate variable declaration for %s",
+ $1->name);
+ }
+ $1->is_var = 1;
+ $1->vnum = nvars;
+ /* make sure vars array will hold variables */
+ grow_varray(nvars, /* must hold nvars+1 vars */
+ &vars); /* grow as needed */
+ vars[nvars] = dummyvar; /* to make Purify happy */
+ vars[nvars].name = (char *) emalloc(strlen($1->name)+1);
+ (void) strcpy(vars[nvars].name, $1->name);
+ /* name for use in generated Fortran and C variables */
+ vars[nvars].lname = decodify($1->name);
+ vars[nvars].type = type_code;
+ /* set default fill value. You can override this with
+ * the variable attribute "_FillValue". */
+ nc_getfill(type_code, &vars[nvars].fill_value);
+ vars[nvars].has_data = 0; /* has no data (yet) */
+ }
+ dimspec
+ {
+ vars[nvars].ndims = nvdims;
+ nvars++;
+ }
+ ;
+var: IDENT
+ ;
+dimspec: /* empty */
+ | '(' dimlist ')'
+ ;
+dimlist: vdim
+ | dimlist ',' vdim
+ ;
+vdim: dim
+ {
+ if (nvdims >= NC_MAX_VAR_DIMS) {
+ derror("%s has too many dimensions",vars[nvars].name);
+ }
+ if ($1->is_dim == 1)
+ dimnum = $1->dnum;
+ else {
+ derror( "%s is not declared as a dimension",
+ $1->name);
+ dimnum = ndims;
+ }
+ if (rec_dim != -1 && dimnum == rec_dim && nvdims != 0) {
+ derror("unlimited dimension must be first");
+ }
+ grow_iarray(nvdims, /* must hold nvdims+1 ints */
+ &vars[nvars].dims); /* grow as needed */
+ vars[nvars].dims[nvdims] = dimnum;
+ nvdims++;
+ }
+ ;
+attdecl: att
+ {
+ defatt();
+ }
+ '=' attvallist
+ {
+ equalatt();
+ }
+ ;
+gattdecl: gatt
+ {
+ defatt();
+ }
+ '=' attvallist
+ {
+ equalatt();
+ }
+ ;
+
+att: avar ':' attr
+
+gatt: ':' attr
+ {
+ varnum = NC_GLOBAL; /* handle of "global" attribute */
+ }
+ ;
+
+avar: var
+ { if ($1->is_var == 1)
+ varnum = $1->vnum;
+ else {
+ derror("%s not declared as a variable, fatal error",
+ $1->name);
+ YYABORT;
+ }
+ }
+ ;
+attr: IDENT
+ {
+ /* make sure atts array will hold attributes */
+ grow_aarray(natts, /* must hold natts+1 atts */
+ &atts); /* grow as needed */
+ atts[natts].name = (char *) emalloc(strlen($1->name)+1);
+ (void) strcpy(atts[natts].name,$1->name);
+ /* name for use in generated Fortran and C variables */
+ atts[natts].lname = decodify($1->name);
+ }
+ ;
+attvallist: aconst
+ | attvallist ',' aconst
+ ;
+aconst: attconst
+ {
+ if (valtype == NC_UNSPECIFIED)
+ valtype = atype_code;
+ if (valtype != atype_code)
+ derror("values for attribute must be all of same type");
+ }
+ ;
+
+attconst: CHAR_CONST
+ {
+ atype_code = NC_CHAR;
+ *char_valp++ = char_val;
+ valnum++;
+ }
+ | TERMSTRING
+ {
+ atype_code = NC_CHAR;
+ {
+ /* don't null-terminate attribute strings */
+ MPI_Offset len = strlen(termstring);
+ if (len == 0) /* need null if that's only value */
+ len = 1;
+ (void)strncpy(char_valp,termstring,len);
+ valnum += len;
+ char_valp += len;
+ }
+ }
+ | BYTE_CONST
+ {
+ atype_code = NC_BYTE;
+ *byte_valp++ = byte_val;
+ valnum++;
+ }
+ | SHORT_CONST
+ {
+ atype_code = NC_SHORT;
+ *short_valp++ = short_val;
+ valnum++;
+ }
+ | INT_CONST
+ {
+ atype_code = NC_INT;
+ *int_valp++ = int_val;
+ valnum++;
+ }
+ | FLOAT_CONST
+ {
+ atype_code = NC_FLOAT;
+ *float_valp++ = float_val;
+ valnum++;
+ }
+ | DOUBLE_CONST
+ {
+ atype_code = NC_DOUBLE;
+ *double_valp++ = double_val;
+ valnum++;
+ }
+ | UBYTE_CONST
+ {
+ atype_code = NC_UBYTE;
+ *ubyte_valp++ = ubyte_val;
+ valnum++;
+ }
+ | USHORT_CONST
+ {
+ atype_code = NC_USHORT;
+ *ushort_valp++ = ushort_val;
+ valnum++;
+ }
+ | UINT_CONST
+ {
+ atype_code = NC_UINT;
+ *uint_valp++ = uint_val;
+ valnum++;
+ }
+ | INT64_CONST
+ {
+ atype_code = NC_INT64;
+ *int64_valp++ = int64_val;
+ valnum++;
+ }
+ | UINT64_CONST
+ {
+ atype_code = NC_UINT64;
+ *uint64_valp++ = uint64_val;
+ valnum++;
+ }
+ ;
+
+datasection: /* empty */
+ | DATA datadecls
+ | DATA
+ ;
+
+datadecls: datadecl ';'
+ | datadecls datadecl ';'
+ ;
+datadecl: avar
+ {
+ valtype = vars[varnum].type; /* variable type */
+ valnum = 0; /* values accumulated for variable */
+ vars[varnum].has_data = 1;
+ /* compute dimensions product */
+ var_size = nctypesize(valtype);
+ if (vars[varnum].ndims == 0) { /* scalar */
+ var_len = 1;
+ } else if (vars[varnum].dims[0] == rec_dim) {
+ var_len = 1; /* one record for unlimited vars */
+ } else {
+ var_len = dims[vars[varnum].dims[0]].size;
+ }
+ for(dimnum = 1; dimnum < vars[varnum].ndims; dimnum++)
+ var_len = var_len*dims[vars[varnum].dims[dimnum]].size;
+ /* allocate memory for variable data */
+ if (var_len*var_size != (MPI_Offset)(var_len*var_size)) {
+ derror("variable %s too large for memory",
+ vars[varnum].name);
+ exit(9);
+ }
+ rec_len = var_len;
+ rec_start = malloc ((MPI_Offset)(rec_len*var_size));
+ if (rec_start == 0) {
+ derror ("out of memory\n");
+ exit(3);
+ }
+ rec_cur = rec_start;
+ switch (valtype) {
+ case NC_CHAR:
+ char_valp = (char *) rec_start;
+ break;
+ case NC_BYTE:
+ byte_valp = (signed char *) rec_start;
+ break;
+ case NC_SHORT:
+ short_valp = (short *) rec_start;
+ break;
+ case NC_INT:
+ int_valp = (int *) rec_start;
+ break;
+ case NC_FLOAT:
+ float_valp = (float *) rec_start;
+ break;
+ case NC_DOUBLE:
+ double_valp = (double *) rec_start;
+ break;
+ case NC_UBYTE:
+ ubyte_valp = (unsigned char *) rec_start;
+ break;
+ case NC_USHORT:
+ ushort_valp = (unsigned short *) rec_start;
+ break;
+ case NC_UINT:
+ uint_valp = (unsigned int *) rec_start;
+ break;
+ case NC_INT64:
+ int64_valp = (long long *) rec_start;
+ break;
+ case NC_UINT64:
+ uint64_valp = (unsigned long long *) rec_start;
+ break;
+ default: break;
+ }
+ }
+ '=' constlist
+ {
+ if (valnum < var_len) { /* leftovers */
+ nc_fill(valtype,
+ var_len - valnum,
+ rec_cur,
+ vars[varnum].fill_value);
+ }
+ /* put out var_len values */
+ /* vars[varnum].nrecs = valnum / rec_len; */
+ vars[varnum].nrecs = var_len / rec_len;
+ if (derror_count == 0)
+ put_variable(rec_start);
+ free ((char *) rec_start);
+ }
+ ;
+constlist: dconst
+ | constlist ',' dconst
+ ;
+dconst:
+ {
+ if(valnum >= var_len) {
+ if (vars[varnum].dims[0] != rec_dim) { /* not recvar */
+ derror("too many values for this variable, %d >= %d",
+ valnum, var_len);
+ exit (4);
+ } else { /* a record variable, so grow data
+ container and increment var_len by
+ multiple of record size */
+ ptrdiff_t rec_inc = (char *)rec_cur
+ - (char *)rec_start;
+ var_len = rec_len * (1 + valnum / rec_len);
+ rec_start = erealloc(rec_start, var_len*var_size);
+ rec_cur = (char *)rec_start + rec_inc;
+ char_valp = (char *) rec_cur;
+ byte_valp = (signed char *) rec_cur;
+ short_valp = (short *) rec_cur;
+ int_valp = (int *) rec_cur;
+ float_valp = (float *) rec_cur;
+ double_valp = (double *) rec_cur;
+ ubyte_valp = (unsigned char *) rec_cur;
+ ushort_valp = (unsigned short *) rec_cur;
+ uint_valp = (unsigned int *) rec_cur;
+ int64_valp = (long long *) rec_cur;
+ uint64_valp = (unsigned long long *) rec_cur;
+ }
+ }
+ not_a_string = 1;
+ }
+ const
+ {
+ if (not_a_string) {
+ switch (valtype) {
+ case NC_CHAR:
+ rec_cur = (void *) char_valp;
+ break;
+ case NC_BYTE:
+ rec_cur = (void *) byte_valp;
+ break;
+ case NC_SHORT:
+ rec_cur = (void *) short_valp;
+ break;
+ case NC_INT:
+ rec_cur = (void *) int_valp;
+ break;
+ case NC_FLOAT:
+ rec_cur = (void *) float_valp;
+ break;
+ case NC_DOUBLE:
+ rec_cur = (void *) double_valp;
+ break;
+ case NC_UBYTE:
+ rec_cur = (void *) ubyte_valp;
+ break;
+ case NC_USHORT:
+ rec_cur = (void *) ushort_valp;
+ break;
+ case NC_UINT:
+ rec_cur = (void *) uint_valp;
+ break;
+ case NC_INT64:
+ rec_cur = (void *) int64_valp;
+ break;
+ case NC_UINT64:
+ rec_cur = (void *) uint64_valp;
+ break;
+ default: break;
+ }
+ }
+ }
+;
+
+const: CHAR_CONST
+ {
+ atype_code = NC_CHAR;
+ switch (valtype) {
+ case NC_CHAR:
+ *char_valp++ = char_val;
+ break;
+ case NC_BYTE:
+ *byte_valp++ = char_val;
+ break;
+ case NC_SHORT:
+ *short_valp++ = char_val;
+ break;
+ case NC_INT:
+ *int_valp++ = char_val;
+ break;
+ case NC_FLOAT:
+ *float_valp++ = char_val;
+ break;
+ case NC_DOUBLE:
+ *double_valp++ = char_val;
+ break;
+ case NC_UBYTE:
+ *ubyte_valp++ = char_val;
+ break;
+ case NC_USHORT:
+ *ushort_valp++ = char_val;
+ break;
+ case NC_UINT:
+ *uint_valp++ = char_val;
+ break;
+ case NC_INT64:
+ *int64_valp++ = char_val;
+ break;
+ case NC_UINT64:
+ *uint64_valp++ = char_val;
+ break;
+ default: break;
+ }
+ valnum++;
+ }
+ | TERMSTRING
+ {
+ not_a_string = 0;
+ atype_code = NC_CHAR;
+ {
+ MPI_Offset len = strlen(termstring);
+
+ if(valnum + len > var_len) {
+ if (vars[varnum].dims[0] != rec_dim) {
+ derror("too many values for this variable, %d>%d",
+ valnum+len, var_len);
+ exit (5);
+ } else {/* a record variable so grow it */
+ ptrdiff_t rec_inc = (char *)rec_cur
+ - (char *)rec_start;
+ var_len += rec_len * (len + valnum - var_len)/rec_len;
+ rec_start = erealloc(rec_start, var_len*var_size);
+ rec_cur = (char *)rec_start + rec_inc;
+ char_valp = (char *) rec_cur;
+ }
+ }
+ switch (valtype) {
+ case NC_CHAR:
+ {
+ int ld;
+ MPI_Offset i, sl;
+ (void)strncpy(char_valp,termstring,len);
+ ld = vars[varnum].ndims-1;
+ if (ld > 0) {/* null-fill to size of last dim */
+ sl = dims[vars[varnum].dims[ld]].size;
+ for (i =len;i<sl;i++)
+ char_valp[i] = '\0';
+ if (sl < len)
+ sl = len;
+ valnum += sl;
+ char_valp += sl;
+ } else { /* scalar or 1D strings */
+ valnum += len;
+ char_valp += len;
+ }
+ rec_cur = (void *) char_valp;
+ }
+ break;
+ case NC_BYTE:
+ case NC_SHORT:
+ case NC_INT:
+ case NC_FLOAT:
+ case NC_DOUBLE:
+ derror("string value invalid for %s variable",
+ nctype(valtype));
+ break;
+ default: break;
+ }
+ }
+ }
+ | BYTE_CONST
+ {
+ atype_code = NC_BYTE;
+ switch (valtype) {
+ case NC_CHAR:
+ *char_valp++ = byte_val;
+ break;
+ case NC_BYTE:
+ *byte_valp++ = byte_val;
+ break;
+ case NC_SHORT:
+ *short_valp++ = byte_val;
+ break;
+ case NC_INT:
+ *int_valp++ = byte_val;
+ break;
+ case NC_FLOAT:
+ *float_valp++ = byte_val;
+ break;
+ case NC_DOUBLE:
+ *double_valp++ = byte_val;
+ break;
+ case NC_UBYTE:
+ *ubyte_valp++ = byte_val;
+ break;
+ case NC_USHORT:
+ *ushort_valp++ = byte_val;
+ break;
+ case NC_UINT:
+ *uint_valp++ = byte_val;
+ break;
+ case NC_INT64:
+ *int64_valp++ = byte_val;
+ break;
+ case NC_UINT64:
+ *uint64_valp++ = byte_val;
+ break;
+ default: break;
+ }
+ valnum++;
+ }
+ | SHORT_CONST
+ {
+ atype_code = NC_SHORT;
+ switch (valtype) {
+ case NC_CHAR:
+ *char_valp++ = short_val;
+ break;
+ case NC_BYTE:
+ *byte_valp++ = short_val;
+ break;
+ case NC_SHORT:
+ *short_valp++ = short_val;
+ break;
+ case NC_INT:
+ *int_valp++ = short_val;
+ break;
+ case NC_FLOAT:
+ *float_valp++ = short_val;
+ break;
+ case NC_DOUBLE:
+ *double_valp++ = short_val;
+ break;
+ case NC_UBYTE:
+ *ubyte_valp++ = short_val;
+ break;
+ case NC_USHORT:
+ *ushort_valp++ = short_val;
+ break;
+ case NC_UINT:
+ *uint_valp++ = short_val;
+ break;
+ case NC_INT64:
+ *int64_valp++ = short_val;
+ break;
+ case NC_UINT64:
+ *uint64_valp++ = short_val;
+ break;
+ default: break;
+ }
+ valnum++;
+ }
+ | INT_CONST
+ {
+ atype_code = NC_INT;
+ switch (valtype) {
+ case NC_CHAR:
+ *char_valp++ = int_val;
+ break;
+ case NC_BYTE:
+ *byte_valp++ = int_val;
+ break;
+ case NC_SHORT:
+ *short_valp++ = int_val;
+ break;
+ case NC_INT:
+ *int_valp++ = int_val;
+ break;
+ case NC_FLOAT:
+ *float_valp++ = int_val;
+ break;
+ case NC_DOUBLE:
+ *double_valp++ = int_val;
+ break;
+ case NC_UBYTE:
+ *ubyte_valp++ = int_val;
+ break;
+ case NC_USHORT:
+ *ushort_valp++ = int_val;
+ break;
+ case NC_UINT:
+ *uint_valp++ = int_val;
+ break;
+ case NC_INT64:
+ *int64_valp++ = int_val;
+ break;
+ case NC_UINT64:
+ *uint64_valp++ = int_val;
+ break;
+ default: break;
+ }
+ valnum++;
+ }
+ | FLOAT_CONST
+ {
+ atype_code = NC_FLOAT;
+ switch (valtype) {
+ case NC_CHAR:
+ *char_valp++ = float_val;
+ break;
+ case NC_BYTE:
+ *byte_valp++ = float_val;
+ break;
+ case NC_SHORT:
+ *short_valp++ = float_val;
+ break;
+ case NC_INT:
+ *int_valp++ = float_val;
+ break;
+ case NC_FLOAT:
+ *float_valp++ = float_val;
+ break;
+ case NC_DOUBLE:
+ *double_valp++ = float_val;
+ break;
+ case NC_UBYTE:
+ *ubyte_valp++ = float_val;
+ break;
+ case NC_USHORT:
+ *ushort_valp++ = float_val;
+ break;
+ case NC_UINT:
+ *uint_valp++ = float_val;
+ break;
+ case NC_INT64:
+ *int64_valp++ = float_val;
+ break;
+ case NC_UINT64:
+ *uint64_valp++ = float_val;
+ break;
+ default: break;
+ }
+ valnum++;
+ }
+ | DOUBLE_CONST
+ {
+ atype_code = NC_DOUBLE;
+ switch (valtype) {
+ case NC_CHAR:
+ *char_valp++ = double_val;
+ break;
+ case NC_BYTE:
+ *byte_valp++ = double_val;
+ break;
+ case NC_SHORT:
+ *short_valp++ = double_val;
+ break;
+ case NC_INT:
+ *int_valp++ = double_val;
+ break;
+ case NC_FLOAT:
+ if (double_val == NC_FILL_DOUBLE)
+ *float_valp++ = NC_FILL_FLOAT;
+ else
+ *float_valp++ = double_val;
+ break;
+ case NC_DOUBLE:
+ *double_valp++ = double_val;
+ break;
+ case NC_UBYTE:
+ *ubyte_valp++ = double_val;
+ break;
+ case NC_USHORT:
+ *ushort_valp++ = double_val;
+ break;
+ case NC_UINT:
+ *uint_valp++ = double_val;
+ break;
+ case NC_INT64:
+ *int64_valp++ = double_val;
+ break;
+ case NC_UINT64:
+ *uint64_valp++ = double_val;
+ break;
+ default: break;
+ }
+ valnum++;
+ }
+ | UBYTE_CONST
+ {
+ atype_code = NC_UBYTE;
+ switch (valtype) {
+ case NC_CHAR:
+ *char_valp++ = ubyte_val;
+ break;
+ case NC_BYTE:
+ *byte_valp++ = ubyte_val;
+ break;
+ case NC_SHORT:
+ *short_valp++ = ubyte_val;
+ break;
+ case NC_INT:
+ *int_valp++ = ubyte_val;
+ break;
+ case NC_FLOAT:
+ *float_valp++ = ubyte_val;
+ break;
+ case NC_DOUBLE:
+ *double_valp++ = ubyte_val;
+ break;
+ case NC_UBYTE:
+ *ubyte_valp++ = ubyte_val;
+ break;
+ case NC_USHORT:
+ *ushort_valp++ = ubyte_val;
+ break;
+ case NC_UINT:
+ *uint_valp++ = ubyte_val;
+ break;
+ case NC_INT64:
+ *int64_valp++ = ubyte_val;
+ break;
+ case NC_UINT64:
+ *uint64_valp++ = ubyte_val;
+ break;
+ default:
+ derror("Unhandled type %d\n", valtype);
+ break;
+ }
+ valnum++;
+ }
+ | USHORT_CONST
+ {
+ atype_code = NC_USHORT;
+ switch (valtype) {
+ case NC_CHAR:
+ *char_valp++ = ushort_val;
+ break;
+ case NC_BYTE:
+ *byte_valp++ = ushort_val;
+ break;
+ case NC_SHORT:
+ *short_valp++ = ushort_val;
+ break;
+ case NC_INT:
+ *int_valp++ = ushort_val;
+ break;
+ case NC_FLOAT:
+ *float_valp++ = ushort_val;
+ break;
+ case NC_DOUBLE:
+ *double_valp++ = ushort_val;
+ break;
+ case NC_UBYTE:
+ *ubyte_valp++ = ushort_val;
+ break;
+ case NC_USHORT:
+ *ushort_valp++ = ushort_val;
+ break;
+ case NC_UINT:
+ *uint_valp++ = ushort_val;
+ break;
+ case NC_INT64:
+ *int64_valp++ = ushort_val;
+ break;
+ case NC_UINT64:
+ *uint64_valp++ = ushort_val;
+ break;
+ default:
+ derror("Unhandled type %d\n", valtype);
+ break;
+ }
+ valnum++;
+ }
+ | UINT_CONST
+ {
+ atype_code = NC_UINT;
+ switch (valtype) {
+ case NC_CHAR:
+ *char_valp++ = uint_val;
+ break;
+ case NC_BYTE:
+ *byte_valp++ = uint_val;
+ break;
+ case NC_SHORT:
+ *short_valp++ = uint_val;
+ break;
+ case NC_INT:
+ *int_valp++ = uint_val;
+ break;
+ case NC_FLOAT:
+ *float_valp++ = uint_val;
+ break;
+ case NC_DOUBLE:
+ *double_valp++ = uint_val;
+ break;
+ case NC_UBYTE:
+ *ubyte_valp++ = uint_val;
+ break;
+ case NC_USHORT:
+ *ushort_valp++ = uint_val;
+ break;
+ case NC_UINT:
+ *uint_valp++ = uint_val;
+ break;
+ case NC_INT64:
+ *int64_valp++ = uint_val;
+ break;
+ case NC_UINT64:
+ *uint64_valp++ = uint_val;
+ break;
+ default:
+ derror("Unhandled type %d\n", valtype);
+ break;
+ }
+ valnum++;
+ }
+ | INT64_CONST
+ {
+ atype_code = NC_INT64;
+ switch (valtype) {
+ case NC_CHAR:
+ *char_valp++ = int64_val;
+ break;
+ case NC_BYTE:
+ *byte_valp++ = int64_val;
+ break;
+ case NC_SHORT:
+ *short_valp++ = int64_val;
+ break;
+ case NC_INT:
+ *int_valp++ = int64_val;
+ break;
+ case NC_FLOAT:
+ *float_valp++ = int64_val;
+ break;
+ case NC_DOUBLE:
+ *double_valp++ = int64_val;
+ break;
+ case NC_UBYTE:
+ *ubyte_valp++ = int64_val;
+ break;
+ case NC_USHORT:
+ *ushort_valp++ = int64_val;
+ break;
+ case NC_UINT:
+ *uint_valp++ = int64_val;
+ break;
+ case NC_INT64:
+ *int64_valp++ = int64_val;
+ break;
+ case NC_UINT64:
+ *uint64_valp++ = int64_val;
+ break;
+ default:
+ derror("Unhandled type %d\n", valtype);
+ break;
+ }
+ valnum++;
+ }
+ | UINT64_CONST
+ {
+ atype_code = NC_UINT64;
+ switch (valtype) {
+ case NC_CHAR:
+ *char_valp++ = uint64_val;
+ break;
+ case NC_BYTE:
+ *byte_valp++ = uint64_val;
+ break;
+ case NC_SHORT:
+ *short_valp++ = uint64_val;
+ break;
+ case NC_INT:
+ *int_valp++ = uint64_val;
+ break;
+ case NC_FLOAT:
+ *float_valp++ = uint64_val;
+ break;
+ case NC_DOUBLE:
+ *double_valp++ = uint64_val;
+ break;
+ case NC_UBYTE:
+ *ubyte_valp++ = uint64_val;
+ break;
+ case NC_USHORT:
+ *ushort_valp++ = uint64_val;
+ break;
+ case NC_UINT:
+ *uint_valp++ = uint64_val;
+ break;
+ case NC_INT64:
+ *int64_valp++ = uint64_val;
+ break;
+ case NC_UINT64:
+ *uint64_valp++ = uint64_val;
+ break;
+ default:
+ derror("Unhandled type %d\n", valtype);
+ break;
+ }
+ valnum++;
+ }
+ | FILLVALUE
+ {
+ /* store fill_value */
+ switch (valtype) {
+ case NC_CHAR:
+ nc_fill(valtype, 1, (void *)char_valp++,
+ vars[varnum].fill_value);
+ break;
+ case NC_BYTE:
+ nc_fill(valtype, 1, (void *)byte_valp++,
+ vars[varnum].fill_value);
+ break;
+ case NC_SHORT:
+ nc_fill(valtype, 1, (void *)short_valp++,
+ vars[varnum].fill_value);
+ break;
+ case NC_INT:
+ nc_fill(valtype, 1, (void *)int_valp++,
+ vars[varnum].fill_value);
+ break;
+ case NC_FLOAT:
+ nc_fill(valtype, 1, (void *)float_valp++,
+ vars[varnum].fill_value);
+ break;
+ case NC_DOUBLE:
+ nc_fill(valtype, 1, (void *)double_valp++,
+ vars[varnum].fill_value);
+ break;
+ case NC_UBYTE:
+ nc_fill(valtype, 1, (void *)ubyte_valp++,
+ vars[varnum].fill_value);
+ break;
+ case NC_USHORT:
+ nc_fill(valtype, 1, (void *)ushort_valp++,
+ vars[varnum].fill_value);
+ break;
+ case NC_UINT:
+ nc_fill(valtype, 1, (void *)uint_valp++,
+ vars[varnum].fill_value);
+ break;
+ case NC_INT64:
+ nc_fill(valtype, 1, (void *)int64_valp++,
+ vars[varnum].fill_value);
+ break;
+ case NC_UINT64:
+ nc_fill(valtype, 1, (void *)uint64_valp++,
+ vars[varnum].fill_value);
+ break;
+ default: break;
+ }
+ valnum++;
+ }
+ ;
+
+/* END OF RULES */
+
+%%
+
+/* HELPER PROGRAMS */
+void defatt(void)
+{
+ valnum = 0;
+ valtype = NC_UNSPECIFIED;
+ /* get a large block for attributes, realloc later */
+ att_space = emalloc(MAX_NC_ATTSIZE);
+ /* make all kinds of pointers point to it */
+ char_valp = (char *) att_space;
+ byte_valp = (signed char *) att_space;
+ short_valp = (short *) att_space;
+ int_valp = (int *) att_space;
+ float_valp = (float *) att_space;
+ double_valp = (double *) att_space;
+ ubyte_valp = (unsigned char *) att_space;
+ ushort_valp = (unsigned short *) att_space;
+ uint_valp = (unsigned int *) att_space;
+ int64_valp = (long long *) att_space;
+ uint64_valp = (unsigned long long *) att_space;
+}
+
+void equalatt(void)
+{
+ /* check if duplicate attribute for this var */
+ int i;
+ for(i=0; i<natts; i++) { /* expensive */
+ if(atts[i].var == varnum &&
+ STREQ(atts[i].name,atts[natts].name)) {
+ derror("duplicate attribute %s:%s",
+ vars[varnum].name,atts[natts].name);
+ }
+ }
+ atts[natts].var = varnum ;
+ atts[natts].type = valtype;
+ atts[natts].len = valnum;
+ /* shrink space down to what was really needed */
+ att_space = erealloc(att_space, valnum*nctypesize(valtype));
+ atts[natts].val = att_space;
+ if (STREQ(atts[natts].name, _FillValue) &&
+ atts[natts].var != NC_GLOBAL) {
+ nc_putfill(atts[natts].type,atts[natts].val,
+ &vars[atts[natts].var].fill_value);
+ if(atts[natts].type != vars[atts[natts].var].type) {
+ derror("variable %s: %s type mismatch",
+ vars[atts[natts].var].name, _FillValue);
+ }
+ }
+ natts++;
+}
+/* PROGRAMS */
+
+#ifdef vms
+void
+#else
+int
+#endif
+yyerror( /* called for yacc syntax error */
+ char *s)
+{
+ derror(s);
+#ifndef vms
+ return -1;
+#endif
+}
+
+/* undefine yywrap macro, in case we are using bison instead of yacc */
+#ifdef ncmpiwrap
+#undef ncmpiwrap
+#endif
+
+int
+ncmpiwrap(void) /* returns 1 on EOF if no more input */
+{
+ return 1;
+}
+
+
+/* Symbol table operations for ncmpigen tool */
+
+/* Find CDL name in symbol table (linear search). Note, this has a
+ * side-effect: it handles escape characters in the name, deleting
+ * single escape characters from the CDL name, before looking it up.
+ */
+YYSTYPE lookup(char *sname)
+{
+ YYSTYPE sp;
+ deescapify(sname); /* delete escape chars from names,
+ * e.g. 'ab\:cd\ ef' becomes
+ * 'ab:cd ef' */
+ for (sp = symlist; sp != (YYSTYPE) 0; sp = sp -> next)
+ if (STREQ(sp -> name, sname)) {
+ return sp;
+ }
+ return 0; /* 0 ==> not found */
+}
+
+YYSTYPE install( /* install sname in symbol table */
+ const char *sname)
+{
+ YYSTYPE sp;
+
+ sp = (YYSTYPE) emalloc (sizeof (struct Symbol));
+ sp -> name = (char *) emalloc (strlen (sname) + 1);/* +1 for '\0' */
+ (void) strcpy (sp -> name, sname);
+ sp -> next = symlist; /* put at front of list */
+ sp -> is_dim = 0;
+ sp -> is_var = 0;
+ sp -> is_att = 0;
+ symlist = sp;
+ return sp;
+}
+
+void
+clearout(void) /* reset symbol table to empty */
+{
+ YYSTYPE sp, tp;
+ for (sp = symlist; sp != (YYSTYPE) 0;) {
+ tp = sp -> next;
+ free (sp -> name);
+ free ((char *) sp);
+ sp = tp;
+ }
+ symlist = 0;
+}
+
+/* get lexical input routine generated by lex */
+
+/* Keep compile quiet */
+#define YY_NO_UNPUT
+#define YY_NO_INPUT
+
+#include "ncmpigenyy.c"
diff --git a/src/utils/ncmpigen/ncmpigentab.c b/src/utils/ncmpigen/ncmpigentab.c
new file mode 100644
index 0000000..2892264
--- /dev/null
+++ b/src/utils/ncmpigen/ncmpigentab.c
@@ -0,0 +1,1919 @@
+#ifndef lint
+static const char yysccsid[] = "@(#)yaccpar 1.9 (Berkeley) 02/21/93";
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+
+#define YYBYACC 1
+#define YYMAJOR 1
+#define YYMINOR 9
+#define YYPATCH 20070509
+
+#define YYEMPTY (-1)
+#define yyclearin (yychar = YYEMPTY)
+#define yyerrok (yyerrflag = 0)
+#define YYRECOVERING (yyerrflag != 0)
+
+extern int yyparse(void);
+
+static int yygrowstack(void);
+#define yyparse ncmpiparse
+#define yylex ncmpilex
+#define yyerror ncmpierror
+#define yychar ncmpichar
+#define yyval ncmpival
+#define yylval ncmpilval
+#define yydebug ncmpidebug
+#define yynerrs ncmpinerrs
+#define yyerrflag ncmpierrflag
+#define yyss ncmpiss
+#define yyssp ncmpissp
+#define yyvs ncmpivs
+#define yyvsp ncmpivsp
+#define yylhs ncmpilhs
+#define yylen ncmpilen
+#define yydefred ncmpidefred
+#define yydgoto ncmpidgoto
+#define yysindex ncmpisindex
+#define yyrindex ncmpirindex
+#define yygindex ncmpigindex
+#define yytable ncmpitable
+#define yycheck ncmpicheck
+#define yyname ncmpiname
+#define yyrule ncmpirule
+#define YYPREFIX "ncmpi"
+#line 10 "./ncmpigen.y"
+#ifdef sccs
+static char SccsId[] = "$Id: ncmpigentab.c 2242 2015-12-19 00:37:52Z wkliao $";
+#endif
+
+#include <string.h>
+#include <stdlib.h>
+#include <stddef.h> /* ptrdiff_t */
+#include <pnetcdf.h>
+#include "generic.h"
+#include "ncmpigen.h"
+#include "genlib.h" /* for grow_darray() et al */
+
+typedef struct Symbol { /* symbol table entry */
+ char *name;
+ struct Symbol *next;
+ unsigned is_dim : 1; /* appears as netCDF dimension */
+ unsigned is_var : 1; /* appears as netCDF variable */
+ unsigned is_att : 1; /* appears as netCDF attribute */
+ int dnum; /* handle as a dimension */
+ int vnum; /* handle as a variable */
+ } *YYSTYPE1;
+
+/* True if string a equals string b*/
+#define STREQ(a, b) (*(a) == *(b) && strcmp((a), (b)) == 0)
+#define NC_UNSPECIFIED ((nc_type)0) /* unspecified (as yet) type */
+
+#define YYSTYPE YYSTYPE1
+YYSTYPE symlist; /* symbol table: linked list */
+
+extern int derror_count; /* counts errors in netcdf definition */
+extern int lineno; /* line number for error messages */
+
+static int not_a_string; /* whether last constant read was a string */
+static char termstring[MAXTRST]; /* last terminal string read */
+static double double_val; /* last double value read */
+static float float_val; /* last float value read */
+static int int_val; /* last int value read */
+static short short_val; /* last short value read */
+static char char_val; /* last char value read */
+static signed char byte_val; /* last byte value read */
+static unsigned char ubyte_val; /* last byte value read */
+static unsigned short ushort_val; /* last byte value read */
+static unsigned int uint_val; /* last byte value read */
+static long long int64_val; /* last byte value read */
+static unsigned long long uint64_val; /* last byte value read */
+
+static nc_type type_code; /* holds declared type for variables */
+static nc_type atype_code; /* holds derived type for attributes */
+static char *netcdfname; /* to construct netcdf file name */
+static void *att_space; /* pointer to block for attribute values */
+static nc_type valtype; /* type code for list of attribute values */
+
+static char *char_valp; /* pointers used to accumulate data values */
+static signed char *byte_valp;
+static short *short_valp;
+static int *int_valp;
+static float *float_valp;
+static double *double_valp;
+static unsigned char *ubyte_valp;
+static unsigned short *ushort_valp;
+static unsigned int *uint_valp;
+static long long *int64_valp;
+static unsigned long long *uint64_valp;
+
+static void *rec_cur; /* pointer to where next data value goes */
+static void *rec_start; /* start of space for data */
+
+/* Forward declarations */
+void defatt(void);
+void equalatt(void);
+
+#ifdef YYLEX_PARAM
+int yylex(YYLEX_PARAM);
+#else
+int yylex(void);
+#endif
+
+#ifdef vms
+void yyerror(char*);
+#else
+int yyerror(char*);
+#endif
+#line 130 "y.tab.c"
+#define NC_UNLIMITED_K 257
+#define BYTE_K 258
+#define CHAR_K 259
+#define SHORT_K 260
+#define INT_K 261
+#define FLOAT_K 262
+#define DOUBLE_K 263
+#define UBYTE_K 264
+#define USHORT_K 265
+#define UINT_K 266
+#define INT64_K 267
+#define UINT64_K 268
+#define IDENT 269
+#define TERMSTRING 270
+#define BYTE_CONST 271
+#define CHAR_CONST 272
+#define SHORT_CONST 273
+#define INT_CONST 274
+#define FLOAT_CONST 275
+#define DOUBLE_CONST 276
+#define UBYTE_CONST 277
+#define USHORT_CONST 278
+#define UINT_CONST 279
+#define INT64_CONST 280
+#define UINT64_CONST 281
+#define DIMENSIONS 282
+#define VARIABLES 283
+#define NETCDF 284
+#define DATA 285
+#define FILLVALUE 286
+#define YYERRCODE 256
+short ncmpilhs[] = { -1,
+ 2, 5, 0, 1, 1, 6, 6, 7, 7, 8,
+ 8, 8, 9, 10, 3, 3, 3, 11, 11, 13,
+ 13, 13, 12, 12, 14, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 18, 18, 22, 19,
+ 20, 21, 21, 23, 23, 24, 26, 15, 29, 16,
+ 25, 28, 30, 31, 27, 27, 32, 33, 33, 33,
+ 33, 33, 33, 33, 33, 33, 33, 33, 33, 4,
+ 4, 4, 34, 34, 36, 35, 37, 37, 40, 38,
+ 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
+ 39, 39, 39,
+};
+short ncmpilen[] = { 2,
+ 0, 0, 8, 0, 2, 2, 3, 1, 3, 3,
+ 3, 3, 1, 1, 0, 2, 1, 2, 3, 1,
+ 1, 1, 2, 3, 2, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 3, 0, 3,
+ 1, 0, 3, 1, 3, 1, 0, 4, 0, 4,
+ 3, 2, 1, 1, 1, 3, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
+ 2, 1, 2, 3, 0, 4, 1, 3, 0, 2,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1,
+};
+short ncmpidefred[] = { 0,
+ 0, 0, 1, 0, 0, 0, 14, 0, 0, 8,
+ 0, 13, 0, 0, 2, 0, 0, 49, 0, 6,
+ 0, 0, 26, 27, 28, 29, 30, 31, 32, 33,
+ 34, 35, 36, 41, 0, 0, 20, 21, 22, 0,
+ 53, 47, 0, 54, 52, 0, 0, 23, 0, 7,
+ 9, 12, 10, 11, 0, 18, 0, 37, 39, 0,
+ 0, 0, 0, 24, 0, 19, 0, 0, 0, 51,
+ 75, 0, 0, 3, 59, 60, 58, 61, 62, 63,
+ 64, 65, 66, 67, 68, 69, 0, 55, 57, 38,
+ 0, 40, 0, 0, 0, 73, 0, 46, 0, 44,
+ 79, 74, 56, 0, 43, 0, 77, 0, 45, 79,
+ 82, 83, 81, 84, 85, 86, 87, 88, 89, 90,
+ 91, 92, 93, 80, 78,
+};
+short ncmpidgoto[] = { 2,
+ 6, 4, 15, 63, 46, 8, 9, 10, 11, 12,
+ 35, 16, 36, 37, 38, 39, 40, 57, 58, 41,
+ 92, 68, 99, 100, 42, 60, 87, 18, 49, 43,
+ 45, 88, 89, 72, 73, 94, 106, 107, 124, 108,
+};
+short ncmpisindex[] = { -253,
+ -90, 0, 0, -246, -215, -54, 0, -215, -35, 0,
+ -6, 0, -56, -213, 0, -1, 1, 0, -22, 0,
+ -215, -249, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, -56, 2, 0, 0, 0, -211,
+ 0, 0, 4, 0, 0, -226, 5, 0, 8, 0,
+ 0, 0, 0, 0, 6, 0, 19, 0, 0, 9,
+ -213, -211, -59, 0, -228, 0, -211, 31, -228, 0,
+ 0, -211, 13, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 29, 0, 0, 0,
+ -215, 0, 29, 14, 15, 0, -228, 0, -9, 0,
+ 0, 0, 0, -215, 0, 32, 0, -260, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+};
+short ncmpirindex[] = { 0,
+ 0, 0, 0, -58, 0, -122, 0, -57, 0, 0,
+ 0, 0, 0, 0, 0, -120, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, -119, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, -48, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 20, 0, 0, 0,
+ 0, -47, 0, 0, 0, 0, 0, -21, 0, 0,
+ 0, -45, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 22, 0, 0, 0,
+ 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 24, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+};
+short ncmpigindex[] = { 0,
+ 0, 0, 0, 0, 0, 0, 74, 63, 0, -63,
+ 0, 0, 50, 0, 0, 23, 0, 0, 21, -33,
+ 0, 0, 0, -18, 0, 0, 18, 0, 0, -32,
+ 28, -7, 0, 0, 25, 0, 0, -19, 0, 0,
+};
+#define YYTABLESIZE 229
+short ncmpitable[] = { 4,
+ 5, 14, 15, 14, 17, 16, 59, 52, 21, 111,
+ 112, 113, 114, 115, 116, 117, 118, 119, 120, 121,
+ 122, 21, 42, 20, 53, 123, 54, 98, 17, 71,
+ 1, 105, 3, 59, 104, 5, 50, 42, 47, 71,
+ 98, 75, 76, 77, 78, 79, 80, 81, 82, 83,
+ 84, 85, 86, 7, 22, 44, 14, 34, 62, 48,
+ 56, 61, 67, 64, 66, 74, 4, 5, 65, 69,
+ 91, 96, 97, 102, 101, 110, 70, 72, 25, 71,
+ 50, 19, 76, 51, 55, 109, 93, 90, 70, 103,
+ 125, 0, 0, 0, 0, 0, 95, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 15, 0, 17, 16, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+ 32, 33, 34, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 4, 5, 4, 5, 13,
+};
+short ncmpicheck[] = { 58,
+ 58, 58, 125, 58, 125, 125, 40, 257, 44, 270,
+ 271, 272, 273, 274, 275, 276, 277, 278, 279, 280,
+ 281, 44, 44, 59, 274, 286, 276, 91, 6, 62,
+ 284, 41, 123, 67, 44, 282, 59, 59, 16, 72,
+ 104, 270, 271, 272, 273, 274, 275, 276, 277, 278,
+ 279, 280, 281, 269, 61, 269, 58, 269, 285, 59,
+ 59, 58, 44, 59, 59, 125, 125, 125, 61, 61,
+ 40, 59, 44, 59, 61, 44, 125, 125, 59, 125,
+ 59, 8, 59, 21, 35, 104, 69, 67, 61, 97,
+ 110, -1, -1, -1, -1, -1, 72, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 285, -1, 285, 285, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 258, 259, 260, 261, 262, 263, 264, 265, 266,
+ 267, 268, 269, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 283, 283, 285, 285, 283,
+};
+#define YYFINAL 2
+#ifndef YYDEBUG
+#define YYDEBUG 0
+#endif
+#define YYMAXTOKEN 286
+#if YYDEBUG
+char *ncmpiname[] = {
+"end-of-file",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,"'('","')'",0,0,"','",0,0,0,0,0,0,0,0,0,0,0,0,0,"':'","';'",0,"'='",
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"'{'",0,"'}'",0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+"NC_UNLIMITED_K","BYTE_K","CHAR_K","SHORT_K","INT_K","FLOAT_K","DOUBLE_K",
+"UBYTE_K","USHORT_K","UINT_K","INT64_K","UINT64_K","IDENT","TERMSTRING",
+"BYTE_CONST","CHAR_CONST","SHORT_CONST","INT_CONST","FLOAT_CONST",
+"DOUBLE_CONST","UBYTE_CONST","USHORT_CONST","UINT_CONST","INT64_CONST",
+"UINT64_CONST","DIMENSIONS","VARIABLES","NETCDF","DATA","FILLVALUE",
+};
+char *ncmpirule[] = {
+"$accept : ncdesc",
+"$$1 :",
+"$$2 :",
+"ncdesc : NETCDF '{' $$1 dimsection vasection $$2 datasection '}'",
+"dimsection :",
+"dimsection : DIMENSIONS dimdecls",
+"dimdecls : dimdecline ';'",
+"dimdecls : dimdecls dimdecline ';'",
+"dimdecline : dimdecl",
+"dimdecline : dimdecline ',' dimdecl",
+"dimdecl : dimd '=' INT_CONST",
+"dimdecl : dimd '=' DOUBLE_CONST",
+"dimdecl : dimd '=' NC_UNLIMITED_K",
+"dimd : dim",
+"dim : IDENT",
+"vasection :",
+"vasection : VARIABLES vadecls",
+"vasection : gattdecls",
+"vadecls : vadecl ';'",
+"vadecls : vadecls vadecl ';'",
+"vadecl : vardecl",
+"vadecl : attdecl",
+"vadecl : gattdecl",
+"gattdecls : gattdecl ';'",
+"gattdecls : gattdecls gattdecl ';'",
+"vardecl : type varlist",
+"type : BYTE_K",
+"type : CHAR_K",
+"type : SHORT_K",
+"type : INT_K",
+"type : FLOAT_K",
+"type : DOUBLE_K",
+"type : UBYTE_K",
+"type : USHORT_K",
+"type : UINT_K",
+"type : INT64_K",
+"type : UINT64_K",
+"varlist : varspec",
+"varlist : varlist ',' varspec",
+"$$3 :",
+"varspec : var $$3 dimspec",
+"var : IDENT",
+"dimspec :",
+"dimspec : '(' dimlist ')'",
+"dimlist : vdim",
+"dimlist : dimlist ',' vdim",
+"vdim : dim",
+"$$4 :",
+"attdecl : att $$4 '=' attvallist",
+"$$5 :",
+"gattdecl : gatt $$5 '=' attvallist",
+"att : avar ':' attr",
+"gatt : ':' attr",
+"avar : var",
+"attr : IDENT",
+"attvallist : aconst",
+"attvallist : attvallist ',' aconst",
+"aconst : attconst",
+"attconst : CHAR_CONST",
+"attconst : TERMSTRING",
+"attconst : BYTE_CONST",
+"attconst : SHORT_CONST",
+"attconst : INT_CONST",
+"attconst : FLOAT_CONST",
+"attconst : DOUBLE_CONST",
+"attconst : UBYTE_CONST",
+"attconst : USHORT_CONST",
+"attconst : UINT_CONST",
+"attconst : INT64_CONST",
+"attconst : UINT64_CONST",
+"datasection :",
+"datasection : DATA datadecls",
+"datasection : DATA",
+"datadecls : datadecl ';'",
+"datadecls : datadecls datadecl ';'",
+"$$6 :",
+"datadecl : avar $$6 '=' constlist",
+"constlist : dconst",
+"constlist : constlist ',' dconst",
+"$$7 :",
+"dconst : $$7 const",
+"const : CHAR_CONST",
+"const : TERMSTRING",
+"const : BYTE_CONST",
+"const : SHORT_CONST",
+"const : INT_CONST",
+"const : FLOAT_CONST",
+"const : DOUBLE_CONST",
+"const : UBYTE_CONST",
+"const : USHORT_CONST",
+"const : UINT_CONST",
+"const : INT64_CONST",
+"const : UINT64_CONST",
+"const : FILLVALUE",
+};
+#endif
+#ifndef YYSTYPE
+typedef int YYSTYPE;
+#endif
+#if YYDEBUG
+#include <stdio.h>
+#endif
+
+/* define the initial stack-sizes */
+#ifdef YYSTACKSIZE
+#undef YYMAXDEPTH
+#define YYMAXDEPTH YYSTACKSIZE
+#else
+#ifdef YYMAXDEPTH
+#define YYSTACKSIZE YYMAXDEPTH
+#else
+#define YYSTACKSIZE 10000
+#define YYMAXDEPTH 10000
+#endif
+#endif
+
+#define YYINITSTACKSIZE 500
+
+int yydebug;
+int yynerrs;
+int yyerrflag;
+int yychar;
+short *yyssp;
+YYSTYPE *yyvsp;
+YYSTYPE yyval;
+YYSTYPE yylval;
+
+/* variables for the parser stack */
+static short *yyss;
+static short *yysslim;
+static YYSTYPE *yyvs;
+static int yystacksize;
+#line 1185 "./ncmpigen.y"
+
+/* HELPER PROGRAMS */
+void defatt(void)
+{
+ valnum = 0;
+ valtype = NC_UNSPECIFIED;
+ /* get a large block for attributes, realloc later */
+ att_space = emalloc(MAX_NC_ATTSIZE);
+ /* make all kinds of pointers point to it */
+ char_valp = (char *) att_space;
+ byte_valp = (signed char *) att_space;
+ short_valp = (short *) att_space;
+ int_valp = (int *) att_space;
+ float_valp = (float *) att_space;
+ double_valp = (double *) att_space;
+ ubyte_valp = (unsigned char *) att_space;
+ ushort_valp = (unsigned short *) att_space;
+ uint_valp = (unsigned int *) att_space;
+ int64_valp = (long long *) att_space;
+ uint64_valp = (unsigned long long *) att_space;
+}
+
+void equalatt(void)
+{
+ /* check if duplicate attribute for this var */
+ int i;
+ for(i=0; i<natts; i++) { /* expensive */
+ if(atts[i].var == varnum &&
+ STREQ(atts[i].name,atts[natts].name)) {
+ derror("duplicate attribute %s:%s",
+ vars[varnum].name,atts[natts].name);
+ }
+ }
+ atts[natts].var = varnum ;
+ atts[natts].type = valtype;
+ atts[natts].len = valnum;
+ /* shrink space down to what was really needed */
+ att_space = erealloc(att_space, valnum*nctypesize(valtype));
+ atts[natts].val = att_space;
+ if (STREQ(atts[natts].name, _FillValue) &&
+ atts[natts].var != NC_GLOBAL) {
+ nc_putfill(atts[natts].type,atts[natts].val,
+ &vars[atts[natts].var].fill_value);
+ if(atts[natts].type != vars[atts[natts].var].type) {
+ derror("variable %s: %s type mismatch",
+ vars[atts[natts].var].name, _FillValue);
+ }
+ }
+ natts++;
+}
+/* PROGRAMS */
+
+#ifdef vms
+void
+#else
+int
+#endif
+yyerror( /* called for yacc syntax error */
+ char *s)
+{
+ derror(s);
+#ifndef vms
+ return -1;
+#endif
+}
+
+/* undefine yywrap macro, in case we are using bison instead of yacc */
+#ifdef ncmpiwrap
+#undef ncmpiwrap
+#endif
+
+int
+ncmpiwrap(void) /* returns 1 on EOF if no more input */
+{
+ return 1;
+}
+
+
+/* Symbol table operations for ncmpigen tool */
+
+/* Find CDL name in symbol table (linear search). Note, this has a
+ * side-effect: it handles escape characters in the name, deleting
+ * single escape characters from the CDL name, before looking it up.
+ */
+YYSTYPE lookup(char *sname)
+{
+ YYSTYPE sp;
+ deescapify(sname); /* delete escape chars from names,
+ * e.g. 'ab\:cd\ ef' becomes
+ * 'ab:cd ef' */
+ for (sp = symlist; sp != (YYSTYPE) 0; sp = sp -> next)
+ if (STREQ(sp -> name, sname)) {
+ return sp;
+ }
+ return 0; /* 0 ==> not found */
+}
+
+YYSTYPE install( /* install sname in symbol table */
+ const char *sname)
+{
+ YYSTYPE sp;
+
+ sp = (YYSTYPE) emalloc (sizeof (struct Symbol));
+ sp -> name = (char *) emalloc (strlen (sname) + 1);/* +1 for '\0' */
+ (void) strcpy (sp -> name, sname);
+ sp -> next = symlist; /* put at front of list */
+ sp -> is_dim = 0;
+ sp -> is_var = 0;
+ sp -> is_att = 0;
+ symlist = sp;
+ return sp;
+}
+
+void
+clearout(void) /* reset symbol table to empty */
+{
+ YYSTYPE sp, tp;
+ for (sp = symlist; sp != (YYSTYPE) 0;) {
+ tp = sp -> next;
+ free (sp -> name);
+ free ((char *) sp);
+ sp = tp;
+ }
+ symlist = 0;
+}
+
+/* get lexical input routine generated by lex */
+
+/* Keep compile quiet */
+#define YY_NO_UNPUT
+#define YY_NO_INPUT
+
+#include "ncmpigenyy.c"
+#line 581 "y.tab.c"
+/* allocate initial stack or double stack size, up to YYMAXDEPTH */
+static int yygrowstack(void)
+{
+ int newsize, i;
+ short *newss;
+ YYSTYPE *newvs;
+
+ if ((newsize = yystacksize) == 0)
+ newsize = YYINITSTACKSIZE;
+ else if (newsize >= YYMAXDEPTH)
+ return -1;
+ else if ((newsize *= 2) > YYMAXDEPTH)
+ newsize = YYMAXDEPTH;
+
+ i = yyssp - yyss;
+ newss = (yyss != 0)
+ ? (short *)realloc(yyss, newsize * sizeof(*newss))
+ : (short *)malloc(newsize * sizeof(*newss));
+ if (newss == 0)
+ return -1;
+
+ yyss = newss;
+ yyssp = newss + i;
+ newvs = (yyvs != 0)
+ ? (YYSTYPE *)realloc(yyvs, newsize * sizeof(*newvs))
+ : (YYSTYPE *)malloc(newsize * sizeof(*newvs));
+ if (newvs == 0)
+ return -1;
+
+ yyvs = newvs;
+ yyvsp = newvs + i;
+ yystacksize = newsize;
+ yysslim = yyss + newsize - 1;
+ return 0;
+}
+
+#define YYABORT goto yyabort
+#define YYREJECT goto yyabort
+#define YYACCEPT goto yyaccept
+#define YYERROR goto yyerrlab
+int
+yyparse(void)
+{
+ register int yym, yyn, yystate;
+#if YYDEBUG
+ register const char *yys;
+
+ if ((yys = getenv("YYDEBUG")) != 0)
+ {
+ yyn = *yys;
+ if (yyn >= '0' && yyn <= '9')
+ yydebug = yyn - '0';
+ }
+#endif
+
+ yynerrs = 0;
+ yyerrflag = 0;
+ yychar = YYEMPTY;
+
+ if (yyss == NULL && yygrowstack()) goto yyoverflow;
+ yyssp = yyss;
+ yyvsp = yyvs;
+ *yyssp = yystate = 0;
+
+yyloop:
+ if ((yyn = yydefred[yystate]) != 0) goto yyreduce;
+ if (yychar < 0)
+ {
+ if ((yychar = yylex()) < 0) yychar = 0;
+#if YYDEBUG
+ if (yydebug)
+ {
+ yys = 0;
+ if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
+ if (!yys) yys = "illegal-symbol";
+ printf("%sdebug: state %d, reading %d (%s)\n",
+ YYPREFIX, yystate, yychar, yys);
+ }
+#endif
+ }
+ if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 &&
+ yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
+ {
+#if YYDEBUG
+ if (yydebug)
+ printf("%sdebug: state %d, shifting to state %d\n",
+ YYPREFIX, yystate, yytable[yyn]);
+#endif
+ if (yyssp >= yysslim && yygrowstack())
+ {
+ goto yyoverflow;
+ }
+ *++yyssp = yystate = yytable[yyn];
+ *++yyvsp = yylval;
+ yychar = YYEMPTY;
+ if (yyerrflag > 0) --yyerrflag;
+ goto yyloop;
+ }
+ if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 &&
+ yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
+ {
+ yyn = yytable[yyn];
+ goto yyreduce;
+ }
+ if (yyerrflag) goto yyinrecovery;
+
+ yyerror("syntax error");
+
+#ifdef lint
+ goto yyerrlab;
+#endif
+
+yyerrlab:
+ ++yynerrs;
+
+yyinrecovery:
+ if (yyerrflag < 3)
+ {
+ yyerrflag = 3;
+ for (;;)
+ {
+ if ((yyn = yysindex[*yyssp]) && (yyn += YYERRCODE) >= 0 &&
+ yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE)
+ {
+#if YYDEBUG
+ if (yydebug)
+ printf("%sdebug: state %d, error recovery shifting\
+ to state %d\n", YYPREFIX, *yyssp, yytable[yyn]);
+#endif
+ if (yyssp >= yysslim && yygrowstack())
+ {
+ goto yyoverflow;
+ }
+ *++yyssp = yystate = yytable[yyn];
+ *++yyvsp = yylval;
+ goto yyloop;
+ }
+ else
+ {
+#if YYDEBUG
+ if (yydebug)
+ printf("%sdebug: error recovery discarding state %d\n",
+ YYPREFIX, *yyssp);
+#endif
+ if (yyssp <= yyss) goto yyabort;
+ --yyssp;
+ --yyvsp;
+ }
+ }
+ }
+ else
+ {
+ if (yychar == 0) goto yyabort;
+#if YYDEBUG
+ if (yydebug)
+ {
+ yys = 0;
+ if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
+ if (!yys) yys = "illegal-symbol";
+ printf("%sdebug: state %d, error recovery discards token %d (%s)\n",
+ YYPREFIX, yystate, yychar, yys);
+ }
+#endif
+ yychar = YYEMPTY;
+ goto yyloop;
+ }
+
+yyreduce:
+#if YYDEBUG
+ if (yydebug)
+ printf("%sdebug: state %d, reducing by rule %d (%s)\n",
+ YYPREFIX, yystate, yyn, yyrule[yyn]);
+#endif
+ yym = yylen[yyn];
+ if (yym)
+ yyval = yyvsp[1-yym];
+ else
+ memset(&yyval, 0, sizeof yyval);
+ switch (yyn)
+ {
+case 1:
+#line 136 "./ncmpigen.y"
+{ init_netcdf(); }
+break;
+case 2:
+#line 139 "./ncmpigen.y"
+{
+ if (derror_count == 0)
+ define_netcdf(netcdfname);
+ if (derror_count > 0)
+ exit(6);
+ }
+break;
+case 3:
+#line 147 "./ncmpigen.y"
+{
+ if (derror_count == 0)
+ close_netcdf();
+ }
+break;
+case 10:
+#line 162 "./ncmpigen.y"
+{ if (int_val <= 0)
+ derror("dimension length must be positive");
+ dims[ndims].size = int_val;
+ ndims++;
+ }
+break;
+case 11:
+#line 168 "./ncmpigen.y"
+{ /* for rare case where 2^31 < dimsize < 2^32 */
+ if (double_val <= 0)
+ derror("dimension length must be positive");
+ if (double_val > 4294967295.0)
+ derror("dimension too large");
+ if (double_val - (MPI_Offset) double_val > 0)
+ derror("dimension length must be an integer");
+ dims[ndims].size = (MPI_Offset) double_val;
+ ndims++;
+ }
+break;
+case 12:
+#line 179 "./ncmpigen.y"
+{ if (rec_dim != -1)
+ derror("only one NC_UNLIMITED dimension allowed");
+ rec_dim = ndims; /* the unlimited (record) dimension */
+ dims[ndims].size = NC_UNLIMITED;
+ ndims++;
+ }
+break;
+case 13:
+#line 187 "./ncmpigen.y"
+{
+ if (yyvsp[0]->is_dim == 1) {
+ derror( "duplicate dimension declaration for %s",
+ yyvsp[0]->name);
+ }
+ yyvsp[0]->is_dim = 1;
+ yyvsp[0]->dnum = ndims;
+ /* make sure dims array will hold dimensions */
+ grow_darray(ndims, /* must hold ndims+1 dims */
+ &dims); /* grow as needed */
+ dims[ndims].name = (char *) emalloc(strlen(yyvsp[0]->name)+1);
+ (void) strcpy(dims[ndims].name, yyvsp[0]->name);
+ /* name for use in generated Fortran and C variables */
+ dims[ndims].lname = decodify(yyvsp[0]->name);
+ }
+break;
+case 26:
+#line 219 "./ncmpigen.y"
+{ type_code = NC_BYTE; }
+break;
+case 27:
+#line 220 "./ncmpigen.y"
+{ type_code = NC_CHAR; }
+break;
+case 28:
+#line 221 "./ncmpigen.y"
+{ type_code = NC_SHORT; }
+break;
+case 29:
+#line 222 "./ncmpigen.y"
+{ type_code = NC_INT; }
+break;
+case 30:
+#line 223 "./ncmpigen.y"
+{ type_code = NC_FLOAT; }
+break;
+case 31:
+#line 224 "./ncmpigen.y"
+{ type_code = NC_DOUBLE; }
+break;
+case 32:
+#line 225 "./ncmpigen.y"
+{ type_code = NC_UBYTE; }
+break;
+case 33:
+#line 226 "./ncmpigen.y"
+{ type_code = NC_USHORT; }
+break;
+case 34:
+#line 227 "./ncmpigen.y"
+{ type_code = NC_UINT; }
+break;
+case 35:
+#line 228 "./ncmpigen.y"
+{ type_code = NC_INT64; }
+break;
+case 36:
+#line 229 "./ncmpigen.y"
+{ type_code = NC_UINT64; }
+break;
+case 39:
+#line 235 "./ncmpigen.y"
+{
+ static struct vars dummyvar;
+
+ dummyvar.name = "dummy";
+ dummyvar.type = NC_DOUBLE;
+ dummyvar.ndims = 0;
+ dummyvar.dims = 0;
+ dummyvar.fill_value.doublev = NC_FILL_DOUBLE;
+ dummyvar.has_data = 0;
+
+ nvdims = 0;
+ /* make sure variable not re-declared */
+ if (yyvsp[0]->is_var == 1) {
+ derror( "duplicate variable declaration for %s",
+ yyvsp[0]->name);
+ }
+ yyvsp[0]->is_var = 1;
+ yyvsp[0]->vnum = nvars;
+ /* make sure vars array will hold variables */
+ grow_varray(nvars, /* must hold nvars+1 vars */
+ &vars); /* grow as needed */
+ vars[nvars] = dummyvar; /* to make Purify happy */
+ vars[nvars].name = (char *) emalloc(strlen(yyvsp[0]->name)+1);
+ (void) strcpy(vars[nvars].name, yyvsp[0]->name);
+ /* name for use in generated Fortran and C variables */
+ vars[nvars].lname = decodify(yyvsp[0]->name);
+ vars[nvars].type = type_code;
+ /* set default fill value. You can override this with
+ * the variable attribute "_FillValue". */
+ nc_getfill(type_code, &vars[nvars].fill_value);
+ vars[nvars].has_data = 0; /* has no data (yet) */
+ }
+break;
+case 40:
+#line 268 "./ncmpigen.y"
+{
+ vars[nvars].ndims = nvdims;
+ nvars++;
+ }
+break;
+case 46:
+#line 282 "./ncmpigen.y"
+{
+ if (nvdims >= NC_MAX_VAR_DIMS) {
+ derror("%s has too many dimensions",vars[nvars].name);
+ }
+ if (yyvsp[0]->is_dim == 1)
+ dimnum = yyvsp[0]->dnum;
+ else {
+ derror( "%s is not declared as a dimension",
+ yyvsp[0]->name);
+ dimnum = ndims;
+ }
+ if (rec_dim != -1 && dimnum == rec_dim && nvdims != 0) {
+ derror("unlimited dimension must be first");
+ }
+ grow_iarray(nvdims, /* must hold nvdims+1 ints */
+ &vars[nvars].dims); /* grow as needed */
+ vars[nvars].dims[nvdims] = dimnum;
+ nvdims++;
+ }
+break;
+case 47:
+#line 303 "./ncmpigen.y"
+{
+ defatt();
+ }
+break;
+case 48:
+#line 307 "./ncmpigen.y"
+{
+ equalatt();
+ }
+break;
+case 49:
+#line 312 "./ncmpigen.y"
+{
+ defatt();
+ }
+break;
+case 50:
+#line 316 "./ncmpigen.y"
+{
+ equalatt();
+ }
+break;
+case 52:
+#line 324 "./ncmpigen.y"
+{
+ varnum = NC_GLOBAL; /* handle of "global" attribute */
+ }
+break;
+case 53:
+#line 330 "./ncmpigen.y"
+{ if (yyvsp[0]->is_var == 1)
+ varnum = yyvsp[0]->vnum;
+ else {
+ derror("%s not declared as a variable, fatal error",
+ yyvsp[0]->name);
+ YYABORT;
+ }
+ }
+break;
+case 54:
+#line 340 "./ncmpigen.y"
+{
+ /* make sure atts array will hold attributes */
+ grow_aarray(natts, /* must hold natts+1 atts */
+ &atts); /* grow as needed */
+ atts[natts].name = (char *) emalloc(strlen(yyvsp[0]->name)+1);
+ (void) strcpy(atts[natts].name,yyvsp[0]->name);
+ /* name for use in generated Fortran and C variables */
+ atts[natts].lname = decodify(yyvsp[0]->name);
+ }
+break;
+case 57:
+#line 354 "./ncmpigen.y"
+{
+ if (valtype == NC_UNSPECIFIED)
+ valtype = atype_code;
+ if (valtype != atype_code)
+ derror("values for attribute must be all of same type");
+ }
+break;
+case 58:
+#line 363 "./ncmpigen.y"
+{
+ atype_code = NC_CHAR;
+ *char_valp++ = char_val;
+ valnum++;
+ }
+break;
+case 59:
+#line 369 "./ncmpigen.y"
+{
+ atype_code = NC_CHAR;
+ {
+ /* don't null-terminate attribute strings */
+ MPI_Offset len = strlen(termstring);
+ if (len == 0) /* need null if that's only value */
+ len = 1;
+ (void)strncpy(char_valp,termstring,len);
+ valnum += len;
+ char_valp += len;
+ }
+ }
+break;
+case 60:
+#line 382 "./ncmpigen.y"
+{
+ atype_code = NC_BYTE;
+ *byte_valp++ = byte_val;
+ valnum++;
+ }
+break;
+case 61:
+#line 388 "./ncmpigen.y"
+{
+ atype_code = NC_SHORT;
+ *short_valp++ = short_val;
+ valnum++;
+ }
+break;
+case 62:
+#line 394 "./ncmpigen.y"
+{
+ atype_code = NC_INT;
+ *int_valp++ = int_val;
+ valnum++;
+ }
+break;
+case 63:
+#line 400 "./ncmpigen.y"
+{
+ atype_code = NC_FLOAT;
+ *float_valp++ = float_val;
+ valnum++;
+ }
+break;
+case 64:
+#line 406 "./ncmpigen.y"
+{
+ atype_code = NC_DOUBLE;
+ *double_valp++ = double_val;
+ valnum++;
+ }
+break;
+case 65:
+#line 412 "./ncmpigen.y"
+{
+ atype_code = NC_UBYTE;
+ *ubyte_valp++ = ubyte_val;
+ valnum++;
+ }
+break;
+case 66:
+#line 418 "./ncmpigen.y"
+{
+ atype_code = NC_USHORT;
+ *ushort_valp++ = ushort_val;
+ valnum++;
+ }
+break;
+case 67:
+#line 424 "./ncmpigen.y"
+{
+ atype_code = NC_UINT;
+ *uint_valp++ = uint_val;
+ valnum++;
+ }
+break;
+case 68:
+#line 430 "./ncmpigen.y"
+{
+ atype_code = NC_INT64;
+ *int64_valp++ = int64_val;
+ valnum++;
+ }
+break;
+case 69:
+#line 436 "./ncmpigen.y"
+{
+ atype_code = NC_UINT64;
+ *uint64_valp++ = uint64_val;
+ valnum++;
+ }
+break;
+case 75:
+#line 452 "./ncmpigen.y"
+{
+ valtype = vars[varnum].type; /* variable type */
+ valnum = 0; /* values accumulated for variable */
+ vars[varnum].has_data = 1;
+ /* compute dimensions product */
+ var_size = nctypesize(valtype);
+ if (vars[varnum].ndims == 0) { /* scalar */
+ var_len = 1;
+ } else if (vars[varnum].dims[0] == rec_dim) {
+ var_len = 1; /* one record for unlimited vars */
+ } else {
+ var_len = dims[vars[varnum].dims[0]].size;
+ }
+ for(dimnum = 1; dimnum < vars[varnum].ndims; dimnum++)
+ var_len = var_len*dims[vars[varnum].dims[dimnum]].size;
+ /* allocate memory for variable data */
+ if (var_len*var_size != (MPI_Offset)(var_len*var_size)) {
+ derror("variable %s too large for memory",
+ vars[varnum].name);
+ exit(9);
+ }
+ rec_len = var_len;
+ rec_start = malloc ((MPI_Offset)(rec_len*var_size));
+ if (rec_start == 0) {
+ derror ("out of memory\n");
+ exit(3);
+ }
+ rec_cur = rec_start;
+ switch (valtype) {
+ case NC_CHAR:
+ char_valp = (char *) rec_start;
+ break;
+ case NC_BYTE:
+ byte_valp = (signed char *) rec_start;
+ break;
+ case NC_SHORT:
+ short_valp = (short *) rec_start;
+ break;
+ case NC_INT:
+ int_valp = (int *) rec_start;
+ break;
+ case NC_FLOAT:
+ float_valp = (float *) rec_start;
+ break;
+ case NC_DOUBLE:
+ double_valp = (double *) rec_start;
+ break;
+ case NC_UBYTE:
+ ubyte_valp = (unsigned char *) rec_start;
+ break;
+ case NC_USHORT:
+ ushort_valp = (unsigned short *) rec_start;
+ break;
+ case NC_UINT:
+ uint_valp = (unsigned int *) rec_start;
+ break;
+ case NC_INT64:
+ int64_valp = (long long *) rec_start;
+ break;
+ case NC_UINT64:
+ uint64_valp = (unsigned long long *) rec_start;
+ break;
+ default: break;
+ }
+ }
+break;
+case 76:
+#line 518 "./ncmpigen.y"
+{
+ if (valnum < var_len) { /* leftovers */
+ nc_fill(valtype,
+ var_len - valnum,
+ rec_cur,
+ vars[varnum].fill_value);
+ }
+ /* put out var_len values */
+ /* vars[varnum].nrecs = valnum / rec_len; */
+ vars[varnum].nrecs = var_len / rec_len;
+ if (derror_count == 0)
+ put_variable(rec_start);
+ free ((char *) rec_start);
+ }
+break;
+case 79:
+#line 537 "./ncmpigen.y"
+{
+ if(valnum >= var_len) {
+ if (vars[varnum].dims[0] != rec_dim) { /* not recvar */
+ derror("too many values for this variable, %d >= %d",
+ valnum, var_len);
+ exit (4);
+ } else { /* a record variable, so grow data
+ container and increment var_len by
+ multiple of record size */
+ ptrdiff_t rec_inc = (char *)rec_cur
+ - (char *)rec_start;
+ var_len = rec_len * (1 + valnum / rec_len);
+ rec_start = erealloc(rec_start, var_len*var_size);
+ rec_cur = (char *)rec_start + rec_inc;
+ char_valp = (char *) rec_cur;
+ byte_valp = (signed char *) rec_cur;
+ short_valp = (short *) rec_cur;
+ int_valp = (int *) rec_cur;
+ float_valp = (float *) rec_cur;
+ double_valp = (double *) rec_cur;
+ ubyte_valp = (unsigned char *) rec_cur;
+ ushort_valp = (unsigned short *) rec_cur;
+ uint_valp = (unsigned int *) rec_cur;
+ int64_valp = (long long *) rec_cur;
+ uint64_valp = (unsigned long long *) rec_cur;
+ }
+ }
+ not_a_string = 1;
+ }
+break;
+case 80:
+#line 567 "./ncmpigen.y"
+{
+ if (not_a_string) {
+ switch (valtype) {
+ case NC_CHAR:
+ rec_cur = (void *) char_valp;
+ break;
+ case NC_BYTE:
+ rec_cur = (void *) byte_valp;
+ break;
+ case NC_SHORT:
+ rec_cur = (void *) short_valp;
+ break;
+ case NC_INT:
+ rec_cur = (void *) int_valp;
+ break;
+ case NC_FLOAT:
+ rec_cur = (void *) float_valp;
+ break;
+ case NC_DOUBLE:
+ rec_cur = (void *) double_valp;
+ break;
+ case NC_UBYTE:
+ rec_cur = (void *) ubyte_valp;
+ break;
+ case NC_USHORT:
+ rec_cur = (void *) ushort_valp;
+ break;
+ case NC_UINT:
+ rec_cur = (void *) uint_valp;
+ break;
+ case NC_INT64:
+ rec_cur = (void *) int64_valp;
+ break;
+ case NC_UINT64:
+ rec_cur = (void *) uint64_valp;
+ break;
+ default: break;
+ }
+ }
+ }
+break;
+case 81:
+#line 610 "./ncmpigen.y"
+{
+ atype_code = NC_CHAR;
+ switch (valtype) {
+ case NC_CHAR:
+ *char_valp++ = char_val;
+ break;
+ case NC_BYTE:
+ *byte_valp++ = char_val;
+ break;
+ case NC_SHORT:
+ *short_valp++ = char_val;
+ break;
+ case NC_INT:
+ *int_valp++ = char_val;
+ break;
+ case NC_FLOAT:
+ *float_valp++ = char_val;
+ break;
+ case NC_DOUBLE:
+ *double_valp++ = char_val;
+ break;
+ case NC_UBYTE:
+ *ubyte_valp++ = char_val;
+ break;
+ case NC_USHORT:
+ *ushort_valp++ = char_val;
+ break;
+ case NC_UINT:
+ *uint_valp++ = char_val;
+ break;
+ case NC_INT64:
+ *int64_valp++ = char_val;
+ break;
+ case NC_UINT64:
+ *uint64_valp++ = char_val;
+ break;
+ default: break;
+ }
+ valnum++;
+ }
+break;
+case 82:
+#line 651 "./ncmpigen.y"
+{
+ not_a_string = 0;
+ atype_code = NC_CHAR;
+ {
+ MPI_Offset len = strlen(termstring);
+
+ if(valnum + len > var_len) {
+ if (vars[varnum].dims[0] != rec_dim) {
+ derror("too many values for this variable, %d>%d",
+ valnum+len, var_len);
+ exit (5);
+ } else {/* a record variable so grow it */
+ ptrdiff_t rec_inc = (char *)rec_cur
+ - (char *)rec_start;
+ var_len += rec_len * (len + valnum - var_len)/rec_len;
+ rec_start = erealloc(rec_start, var_len*var_size);
+ rec_cur = (char *)rec_start + rec_inc;
+ char_valp = (char *) rec_cur;
+ }
+ }
+ switch (valtype) {
+ case NC_CHAR:
+ {
+ int ld;
+ MPI_Offset i, sl;
+ (void)strncpy(char_valp,termstring,len);
+ ld = vars[varnum].ndims-1;
+ if (ld > 0) {/* null-fill to size of last dim */
+ sl = dims[vars[varnum].dims[ld]].size;
+ for (i =len;i<sl;i++)
+ char_valp[i] = '\0';
+ if (sl < len)
+ sl = len;
+ valnum += sl;
+ char_valp += sl;
+ } else { /* scalar or 1D strings */
+ valnum += len;
+ char_valp += len;
+ }
+ rec_cur = (void *) char_valp;
+ }
+ break;
+ case NC_BYTE:
+ case NC_SHORT:
+ case NC_INT:
+ case NC_FLOAT:
+ case NC_DOUBLE:
+ derror("string value invalid for %s variable",
+ nctype(valtype));
+ break;
+ default: break;
+ }
+ }
+ }
+break;
+case 83:
+#line 706 "./ncmpigen.y"
+{
+ atype_code = NC_BYTE;
+ switch (valtype) {
+ case NC_CHAR:
+ *char_valp++ = byte_val;
+ break;
+ case NC_BYTE:
+ *byte_valp++ = byte_val;
+ break;
+ case NC_SHORT:
+ *short_valp++ = byte_val;
+ break;
+ case NC_INT:
+ *int_valp++ = byte_val;
+ break;
+ case NC_FLOAT:
+ *float_valp++ = byte_val;
+ break;
+ case NC_DOUBLE:
+ *double_valp++ = byte_val;
+ break;
+ case NC_UBYTE:
+ *ubyte_valp++ = byte_val;
+ break;
+ case NC_USHORT:
+ *ushort_valp++ = byte_val;
+ break;
+ case NC_UINT:
+ *uint_valp++ = byte_val;
+ break;
+ case NC_INT64:
+ *int64_valp++ = byte_val;
+ break;
+ case NC_UINT64:
+ *uint64_valp++ = byte_val;
+ break;
+ default: break;
+ }
+ valnum++;
+ }
+break;
+case 84:
+#line 747 "./ncmpigen.y"
+{
+ atype_code = NC_SHORT;
+ switch (valtype) {
+ case NC_CHAR:
+ *char_valp++ = short_val;
+ break;
+ case NC_BYTE:
+ *byte_valp++ = short_val;
+ break;
+ case NC_SHORT:
+ *short_valp++ = short_val;
+ break;
+ case NC_INT:
+ *int_valp++ = short_val;
+ break;
+ case NC_FLOAT:
+ *float_valp++ = short_val;
+ break;
+ case NC_DOUBLE:
+ *double_valp++ = short_val;
+ break;
+ case NC_UBYTE:
+ *ubyte_valp++ = short_val;
+ break;
+ case NC_USHORT:
+ *ushort_valp++ = short_val;
+ break;
+ case NC_UINT:
+ *uint_valp++ = short_val;
+ break;
+ case NC_INT64:
+ *int64_valp++ = short_val;
+ break;
+ case NC_UINT64:
+ *uint64_valp++ = short_val;
+ break;
+ default: break;
+ }
+ valnum++;
+ }
+break;
+case 85:
+#line 788 "./ncmpigen.y"
+{
+ atype_code = NC_INT;
+ switch (valtype) {
+ case NC_CHAR:
+ *char_valp++ = int_val;
+ break;
+ case NC_BYTE:
+ *byte_valp++ = int_val;
+ break;
+ case NC_SHORT:
+ *short_valp++ = int_val;
+ break;
+ case NC_INT:
+ *int_valp++ = int_val;
+ break;
+ case NC_FLOAT:
+ *float_valp++ = int_val;
+ break;
+ case NC_DOUBLE:
+ *double_valp++ = int_val;
+ break;
+ case NC_UBYTE:
+ *ubyte_valp++ = int_val;
+ break;
+ case NC_USHORT:
+ *ushort_valp++ = int_val;
+ break;
+ case NC_UINT:
+ *uint_valp++ = int_val;
+ break;
+ case NC_INT64:
+ *int64_valp++ = int_val;
+ break;
+ case NC_UINT64:
+ *uint64_valp++ = int_val;
+ break;
+ default: break;
+ }
+ valnum++;
+ }
+break;
+case 86:
+#line 829 "./ncmpigen.y"
+{
+ atype_code = NC_FLOAT;
+ switch (valtype) {
+ case NC_CHAR:
+ *char_valp++ = float_val;
+ break;
+ case NC_BYTE:
+ *byte_valp++ = float_val;
+ break;
+ case NC_SHORT:
+ *short_valp++ = float_val;
+ break;
+ case NC_INT:
+ *int_valp++ = float_val;
+ break;
+ case NC_FLOAT:
+ *float_valp++ = float_val;
+ break;
+ case NC_DOUBLE:
+ *double_valp++ = float_val;
+ break;
+ case NC_UBYTE:
+ *ubyte_valp++ = float_val;
+ break;
+ case NC_USHORT:
+ *ushort_valp++ = float_val;
+ break;
+ case NC_UINT:
+ *uint_valp++ = float_val;
+ break;
+ case NC_INT64:
+ *int64_valp++ = float_val;
+ break;
+ case NC_UINT64:
+ *uint64_valp++ = float_val;
+ break;
+ default: break;
+ }
+ valnum++;
+ }
+break;
+case 87:
+#line 870 "./ncmpigen.y"
+{
+ atype_code = NC_DOUBLE;
+ switch (valtype) {
+ case NC_CHAR:
+ *char_valp++ = double_val;
+ break;
+ case NC_BYTE:
+ *byte_valp++ = double_val;
+ break;
+ case NC_SHORT:
+ *short_valp++ = double_val;
+ break;
+ case NC_INT:
+ *int_valp++ = double_val;
+ break;
+ case NC_FLOAT:
+ if (double_val == NC_FILL_DOUBLE)
+ *float_valp++ = NC_FILL_FLOAT;
+ else
+ *float_valp++ = double_val;
+ break;
+ case NC_DOUBLE:
+ *double_valp++ = double_val;
+ break;
+ case NC_UBYTE:
+ *ubyte_valp++ = double_val;
+ break;
+ case NC_USHORT:
+ *ushort_valp++ = double_val;
+ break;
+ case NC_UINT:
+ *uint_valp++ = double_val;
+ break;
+ case NC_INT64:
+ *int64_valp++ = double_val;
+ break;
+ case NC_UINT64:
+ *uint64_valp++ = double_val;
+ break;
+ default: break;
+ }
+ valnum++;
+ }
+break;
+case 88:
+#line 914 "./ncmpigen.y"
+{
+ atype_code = NC_UBYTE;
+ switch (valtype) {
+ case NC_CHAR:
+ *char_valp++ = ubyte_val;
+ break;
+ case NC_BYTE:
+ *byte_valp++ = ubyte_val;
+ break;
+ case NC_SHORT:
+ *short_valp++ = ubyte_val;
+ break;
+ case NC_INT:
+ *int_valp++ = ubyte_val;
+ break;
+ case NC_FLOAT:
+ *float_valp++ = ubyte_val;
+ break;
+ case NC_DOUBLE:
+ *double_valp++ = ubyte_val;
+ break;
+ case NC_UBYTE:
+ *ubyte_valp++ = ubyte_val;
+ break;
+ case NC_USHORT:
+ *ushort_valp++ = ubyte_val;
+ break;
+ case NC_UINT:
+ *uint_valp++ = ubyte_val;
+ break;
+ case NC_INT64:
+ *int64_valp++ = ubyte_val;
+ break;
+ case NC_UINT64:
+ *uint64_valp++ = ubyte_val;
+ break;
+ default:
+ derror("Unhandled type %d\n", valtype);
+ break;
+ }
+ valnum++;
+ }
+break;
+case 89:
+#line 957 "./ncmpigen.y"
+{
+ atype_code = NC_USHORT;
+ switch (valtype) {
+ case NC_CHAR:
+ *char_valp++ = ushort_val;
+ break;
+ case NC_BYTE:
+ *byte_valp++ = ushort_val;
+ break;
+ case NC_SHORT:
+ *short_valp++ = ushort_val;
+ break;
+ case NC_INT:
+ *int_valp++ = ushort_val;
+ break;
+ case NC_FLOAT:
+ *float_valp++ = ushort_val;
+ break;
+ case NC_DOUBLE:
+ *double_valp++ = ushort_val;
+ break;
+ case NC_UBYTE:
+ *ubyte_valp++ = ushort_val;
+ break;
+ case NC_USHORT:
+ *ushort_valp++ = ushort_val;
+ break;
+ case NC_UINT:
+ *uint_valp++ = ushort_val;
+ break;
+ case NC_INT64:
+ *int64_valp++ = ushort_val;
+ break;
+ case NC_UINT64:
+ *uint64_valp++ = ushort_val;
+ break;
+ default:
+ derror("Unhandled type %d\n", valtype);
+ break;
+ }
+ valnum++;
+ }
+break;
+case 90:
+#line 1000 "./ncmpigen.y"
+{
+ atype_code = NC_UINT;
+ switch (valtype) {
+ case NC_CHAR:
+ *char_valp++ = uint_val;
+ break;
+ case NC_BYTE:
+ *byte_valp++ = uint_val;
+ break;
+ case NC_SHORT:
+ *short_valp++ = uint_val;
+ break;
+ case NC_INT:
+ *int_valp++ = uint_val;
+ break;
+ case NC_FLOAT:
+ *float_valp++ = uint_val;
+ break;
+ case NC_DOUBLE:
+ *double_valp++ = uint_val;
+ break;
+ case NC_UBYTE:
+ *ubyte_valp++ = uint_val;
+ break;
+ case NC_USHORT:
+ *ushort_valp++ = uint_val;
+ break;
+ case NC_UINT:
+ *uint_valp++ = uint_val;
+ break;
+ case NC_INT64:
+ *int64_valp++ = uint_val;
+ break;
+ case NC_UINT64:
+ *uint64_valp++ = uint_val;
+ break;
+ default:
+ derror("Unhandled type %d\n", valtype);
+ break;
+ }
+ valnum++;
+ }
+break;
+case 91:
+#line 1043 "./ncmpigen.y"
+{
+ atype_code = NC_INT64;
+ switch (valtype) {
+ case NC_CHAR:
+ *char_valp++ = int64_val;
+ break;
+ case NC_BYTE:
+ *byte_valp++ = int64_val;
+ break;
+ case NC_SHORT:
+ *short_valp++ = int64_val;
+ break;
+ case NC_INT:
+ *int_valp++ = int64_val;
+ break;
+ case NC_FLOAT:
+ *float_valp++ = int64_val;
+ break;
+ case NC_DOUBLE:
+ *double_valp++ = int64_val;
+ break;
+ case NC_UBYTE:
+ *ubyte_valp++ = int64_val;
+ break;
+ case NC_USHORT:
+ *ushort_valp++ = int64_val;
+ break;
+ case NC_UINT:
+ *uint_valp++ = int64_val;
+ break;
+ case NC_INT64:
+ *int64_valp++ = int64_val;
+ break;
+ case NC_UINT64:
+ *uint64_valp++ = int64_val;
+ break;
+ default:
+ derror("Unhandled type %d\n", valtype);
+ break;
+ }
+ valnum++;
+ }
+break;
+case 92:
+#line 1086 "./ncmpigen.y"
+{
+ atype_code = NC_UINT64;
+ switch (valtype) {
+ case NC_CHAR:
+ *char_valp++ = uint64_val;
+ break;
+ case NC_BYTE:
+ *byte_valp++ = uint64_val;
+ break;
+ case NC_SHORT:
+ *short_valp++ = uint64_val;
+ break;
+ case NC_INT:
+ *int_valp++ = uint64_val;
+ break;
+ case NC_FLOAT:
+ *float_valp++ = uint64_val;
+ break;
+ case NC_DOUBLE:
+ *double_valp++ = uint64_val;
+ break;
+ case NC_UBYTE:
+ *ubyte_valp++ = uint64_val;
+ break;
+ case NC_USHORT:
+ *ushort_valp++ = uint64_val;
+ break;
+ case NC_UINT:
+ *uint_valp++ = uint64_val;
+ break;
+ case NC_INT64:
+ *int64_valp++ = uint64_val;
+ break;
+ case NC_UINT64:
+ *uint64_valp++ = uint64_val;
+ break;
+ default:
+ derror("Unhandled type %d\n", valtype);
+ break;
+ }
+ valnum++;
+ }
+break;
+case 93:
+#line 1129 "./ncmpigen.y"
+{
+ /* store fill_value */
+ switch (valtype) {
+ case NC_CHAR:
+ nc_fill(valtype, 1, (void *)char_valp++,
+ vars[varnum].fill_value);
+ break;
+ case NC_BYTE:
+ nc_fill(valtype, 1, (void *)byte_valp++,
+ vars[varnum].fill_value);
+ break;
+ case NC_SHORT:
+ nc_fill(valtype, 1, (void *)short_valp++,
+ vars[varnum].fill_value);
+ break;
+ case NC_INT:
+ nc_fill(valtype, 1, (void *)int_valp++,
+ vars[varnum].fill_value);
+ break;
+ case NC_FLOAT:
+ nc_fill(valtype, 1, (void *)float_valp++,
+ vars[varnum].fill_value);
+ break;
+ case NC_DOUBLE:
+ nc_fill(valtype, 1, (void *)double_valp++,
+ vars[varnum].fill_value);
+ break;
+ case NC_UBYTE:
+ nc_fill(valtype, 1, (void *)ubyte_valp++,
+ vars[varnum].fill_value);
+ break;
+ case NC_USHORT:
+ nc_fill(valtype, 1, (void *)ushort_valp++,
+ vars[varnum].fill_value);
+ break;
+ case NC_UINT:
+ nc_fill(valtype, 1, (void *)uint_valp++,
+ vars[varnum].fill_value);
+ break;
+ case NC_INT64:
+ nc_fill(valtype, 1, (void *)int64_valp++,
+ vars[varnum].fill_value);
+ break;
+ case NC_UINT64:
+ nc_fill(valtype, 1, (void *)uint64_valp++,
+ vars[varnum].fill_value);
+ break;
+ default: break;
+ }
+ valnum++;
+ }
+break;
+#line 1860 "y.tab.c"
+ }
+ yyssp -= yym;
+ yystate = *yyssp;
+ yyvsp -= yym;
+ yym = yylhs[yyn];
+ if (yystate == 0 && yym == 0)
+ {
+#if YYDEBUG
+ if (yydebug)
+ printf("%sdebug: after reduction, shifting from state 0 to\
+ state %d\n", YYPREFIX, YYFINAL);
+#endif
+ yystate = YYFINAL;
+ *++yyssp = YYFINAL;
+ *++yyvsp = yyval;
+ if (yychar < 0)
+ {
+ if ((yychar = yylex()) < 0) yychar = 0;
+#if YYDEBUG
+ if (yydebug)
+ {
+ yys = 0;
+ if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
+ if (!yys) yys = "illegal-symbol";
+ printf("%sdebug: state %d, reading %d (%s)\n",
+ YYPREFIX, YYFINAL, yychar, yys);
+ }
+#endif
+ }
+ if (yychar == 0) goto yyaccept;
+ goto yyloop;
+ }
+ if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 &&
+ yyn <= YYTABLESIZE && yycheck[yyn] == yystate)
+ yystate = yytable[yyn];
+ else
+ yystate = yydgoto[yym];
+#if YYDEBUG
+ if (yydebug)
+ printf("%sdebug: after reduction, shifting from state %d \
+to state %d\n", YYPREFIX, *yyssp, yystate);
+#endif
+ if (yyssp >= yysslim && yygrowstack())
+ {
+ goto yyoverflow;
+ }
+ *++yyssp = yystate;
+ *++yyvsp = yyval;
+ goto yyloop;
+
+yyoverflow:
+ yyerror("yacc stack overflow");
+
+yyabort:
+ return (1);
+
+yyaccept:
+ return (0);
+}
+
diff --git a/src/utils/ncmpigen/ncmpigentab.h b/src/utils/ncmpigen/ncmpigentab.h
new file mode 100644
index 0000000..d728a0c
--- /dev/null
+++ b/src/utils/ncmpigen/ncmpigentab.h
@@ -0,0 +1,30 @@
+#define NC_UNLIMITED_K 257
+#define BYTE_K 258
+#define CHAR_K 259
+#define SHORT_K 260
+#define INT_K 261
+#define FLOAT_K 262
+#define DOUBLE_K 263
+#define UBYTE_K 264
+#define USHORT_K 265
+#define UINT_K 266
+#define INT64_K 267
+#define UINT64_K 268
+#define IDENT 269
+#define TERMSTRING 270
+#define BYTE_CONST 271
+#define CHAR_CONST 272
+#define SHORT_CONST 273
+#define INT_CONST 274
+#define FLOAT_CONST 275
+#define DOUBLE_CONST 276
+#define UBYTE_CONST 277
+#define USHORT_CONST 278
+#define UINT_CONST 279
+#define INT64_CONST 280
+#define UINT64_CONST 281
+#define DIMENSIONS 282
+#define VARIABLES 283
+#define NETCDF 284
+#define DATA 285
+#define FILLVALUE 286
diff --git a/src/utils/ncmpigen/ncmpigenyy.c b/src/utils/ncmpigen/ncmpigenyy.c
new file mode 100644
index 0000000..3558068
--- /dev/null
+++ b/src/utils/ncmpigen/ncmpigenyy.c
@@ -0,0 +1,2294 @@
+
+#line 3 "lex.ncmpi.c"
+
+#define YY_INT_ALIGNED short int
+
+/* A lexical scanner generated by flex */
+
+#define yy_create_buffer ncmpi_create_buffer
+#define yy_delete_buffer ncmpi_delete_buffer
+#define yy_flex_debug ncmpi_flex_debug
+#define yy_init_buffer ncmpi_init_buffer
+#define yy_flush_buffer ncmpi_flush_buffer
+#define yy_load_buffer_state ncmpi_load_buffer_state
+#define yy_switch_to_buffer ncmpi_switch_to_buffer
+#define yyin ncmpiin
+#define yyleng ncmpileng
+#define yylex ncmpilex
+#define yylineno ncmpilineno
+#define yyout ncmpiout
+#define yyrestart ncmpirestart
+#define yytext ncmpitext
+#define yywrap ncmpiwrap
+#define yyalloc ncmpialloc
+#define yyrealloc ncmpirealloc
+#define yyfree ncmpifree
+
+#define FLEX_SCANNER
+#define YY_FLEX_MAJOR_VERSION 2
+#define YY_FLEX_MINOR_VERSION 5
+#define YY_FLEX_SUBMINOR_VERSION 35
+#if YY_FLEX_SUBMINOR_VERSION > 0
+#define FLEX_BETA
+#endif
+
+/* First, we deal with platform-specific or compiler-specific issues. */
+
+/* begin standard C headers. */
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+
+/* end standard C headers. */
+
+/* flex integer type definitions */
+
+#ifndef FLEXINT_H
+#define FLEXINT_H
+
+/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
+
+#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+
+/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
+ * if you want the limit (max/min) macros for int types.
+ */
+#ifndef __STDC_LIMIT_MACROS
+#define __STDC_LIMIT_MACROS 1
+#endif
+
+#include <inttypes.h>
+typedef int8_t flex_int8_t;
+typedef uint8_t flex_uint8_t;
+typedef int16_t flex_int16_t;
+typedef uint16_t flex_uint16_t;
+typedef int32_t flex_int32_t;
+typedef uint32_t flex_uint32_t;
+#else
+typedef signed char flex_int8_t;
+typedef short int flex_int16_t;
+typedef int flex_int32_t;
+typedef unsigned char flex_uint8_t;
+typedef unsigned short int flex_uint16_t;
+typedef unsigned int flex_uint32_t;
+#endif /* ! C99 */
+
+/* Limits of integral types. */
+#ifndef INT8_MIN
+#define INT8_MIN (-128)
+#endif
+#ifndef INT16_MIN
+#define INT16_MIN (-32767-1)
+#endif
+#ifndef INT32_MIN
+#define INT32_MIN (-2147483647-1)
+#endif
+#ifndef INT8_MAX
+#define INT8_MAX (127)
+#endif
+#ifndef INT16_MAX
+#define INT16_MAX (32767)
+#endif
+#ifndef INT32_MAX
+#define INT32_MAX (2147483647)
+#endif
+#ifndef UINT8_MAX
+#define UINT8_MAX (255U)
+#endif
+#ifndef UINT16_MAX
+#define UINT16_MAX (65535U)
+#endif
+#ifndef UINT32_MAX
+#define UINT32_MAX (4294967295U)
+#endif
+
+#endif /* ! FLEXINT_H */
+
+#ifdef __cplusplus
+
+/* The "const" storage-class-modifier is valid. */
+#define YY_USE_CONST
+
+#else /* ! __cplusplus */
+
+/* C99 requires __STDC__ to be defined as 1. */
+#if defined (__STDC__)
+
+#define YY_USE_CONST
+
+#endif /* defined (__STDC__) */
+#endif /* ! __cplusplus */
+
+#ifdef YY_USE_CONST
+#define yyconst const
+#else
+#define yyconst
+#endif
+
+/* Returned upon end-of-file. */
+#define YY_NULL 0
+
+/* Promotes a possibly negative, possibly signed char to an unsigned
+ * integer for use as an array index. If the signed char is negative,
+ * we want to instead treat it as an 8-bit unsigned char, hence the
+ * double cast.
+ */
+#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
+
+/* Enter a start condition. This macro really ought to take a parameter,
+ * but we do it the disgusting crufty way forced on us by the ()-less
+ * definition of BEGIN.
+ */
+#define BEGIN (yy_start) = 1 + 2 *
+
+/* Translate the current start state into a value that can be later handed
+ * to BEGIN to return to the state. The YYSTATE alias is for lex
+ * compatibility.
+ */
+#define YY_START (((yy_start) - 1) / 2)
+#define YYSTATE YY_START
+
+/* Action number for EOF rule of a given start state. */
+#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
+
+/* Special action meaning "start processing a new file". */
+#define YY_NEW_FILE ncmpirestart(ncmpiin )
+
+#define YY_END_OF_BUFFER_CHAR 0
+
+/* Size of default input buffer. */
+#ifndef YY_BUF_SIZE
+#define YY_BUF_SIZE 16384
+#endif
+
+/* The state buf must be large enough to hold one state per character in the main buffer.
+ */
+#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type))
+
+#ifndef YY_TYPEDEF_YY_BUFFER_STATE
+#define YY_TYPEDEF_YY_BUFFER_STATE
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+#endif
+
+extern int ncmpileng;
+
+extern FILE *ncmpiin, *ncmpiout;
+
+#define EOB_ACT_CONTINUE_SCAN 0
+#define EOB_ACT_END_OF_FILE 1
+#define EOB_ACT_LAST_MATCH 2
+
+ #define YY_LESS_LINENO(n)
+
+/* Return all but the first "n" matched characters back to the input stream. */
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up ncmpitext. */ \
+ int yyless_macro_arg = (n); \
+ YY_LESS_LINENO(yyless_macro_arg);\
+ *yy_cp = (yy_hold_char); \
+ YY_RESTORE_YY_MORE_OFFSET \
+ (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \
+ YY_DO_BEFORE_ACTION; /* set up ncmpitext again */ \
+ } \
+ while ( 0 )
+
+#define unput(c) yyunput( c, (yytext_ptr) )
+
+#ifndef YY_TYPEDEF_YY_SIZE_T
+#define YY_TYPEDEF_YY_SIZE_T
+typedef size_t yy_size_t;
+#endif
+
+#ifndef YY_STRUCT_YY_BUFFER_STATE
+#define YY_STRUCT_YY_BUFFER_STATE
+struct yy_buffer_state
+ {
+ FILE *yy_input_file;
+
+ char *yy_ch_buf; /* input buffer */
+ char *yy_buf_pos; /* current position in input buffer */
+
+ /* Size of input buffer in bytes, not including room for EOB
+ * characters.
+ */
+ yy_size_t yy_buf_size;
+
+ /* Number of characters read into yy_ch_buf, not including EOB
+ * characters.
+ */
+ int yy_n_chars;
+
+ /* Whether we "own" the buffer - i.e., we know we created it,
+ * and can realloc() it to grow it, and should free() it to
+ * delete it.
+ */
+ int yy_is_our_buffer;
+
+ /* Whether this is an "interactive" input source; if so, and
+ * if we're using stdio for input, then we want to use getc()
+ * instead of fread(), to make sure we stop fetching input after
+ * each newline.
+ */
+ int yy_is_interactive;
+
+ /* Whether we're considered to be at the beginning of a line.
+ * If so, '^' rules will be active on the next match, otherwise
+ * not.
+ */
+ int yy_at_bol;
+
+ int yy_bs_lineno; /**< The line count. */
+ int yy_bs_column; /**< The column count. */
+
+ /* Whether to try to fill the input buffer when we reach the
+ * end of it.
+ */
+ int yy_fill_buffer;
+
+ int yy_buffer_status;
+
+#define YY_BUFFER_NEW 0
+#define YY_BUFFER_NORMAL 1
+ /* When an EOF's been seen but there's still some text to process
+ * then we mark the buffer as YY_EOF_PENDING, to indicate that we
+ * shouldn't try reading from the input source any more. We might
+ * still have a bunch of tokens to match, though, because of
+ * possible backing-up.
+ *
+ * When we actually see the EOF, we change the status to "new"
+ * (via ncmpirestart()), so that the user can continue scanning by
+ * just pointing ncmpiin at a new input file.
+ */
+#define YY_BUFFER_EOF_PENDING 2
+
+ };
+#endif /* !YY_STRUCT_YY_BUFFER_STATE */
+
+/* Stack of input buffers. */
+static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */
+static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */
+static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */
+
+/* We provide macros for accessing buffer states in case in the
+ * future we want to put the buffer states in a more general
+ * "scanner state".
+ *
+ * Returns the top of the stack, or NULL.
+ */
+#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \
+ ? (yy_buffer_stack)[(yy_buffer_stack_top)] \
+ : NULL)
+
+/* Same as previous macro, but useful when we know that the buffer stack is not
+ * NULL or when we need an lvalue. For internal use only.
+ */
+#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)]
+
+/* yy_hold_char holds the character lost when ncmpitext is formed. */
+static char yy_hold_char;
+static int yy_n_chars; /* number of characters read into yy_ch_buf */
+int ncmpileng;
+
+/* Points to current character in buffer. */
+static char *yy_c_buf_p = (char *) 0;
+static int yy_init = 0; /* whether we need to initialize */
+static int yy_start = 0; /* start state number */
+
+/* Flag which is used to allow ncmpiwrap()'s to do buffer switches
+ * instead of setting up a fresh ncmpiin. A bit of a hack ...
+ */
+static int yy_did_buffer_switch_on_eof;
+
+void ncmpirestart (FILE *input_file );
+void ncmpi_switch_to_buffer (YY_BUFFER_STATE new_buffer );
+YY_BUFFER_STATE ncmpi_create_buffer (FILE *file,int size );
+void ncmpi_delete_buffer (YY_BUFFER_STATE b );
+void ncmpi_flush_buffer (YY_BUFFER_STATE b );
+void ncmpipush_buffer_state (YY_BUFFER_STATE new_buffer );
+void ncmpipop_buffer_state (void );
+
+static void ncmpiensure_buffer_stack (void );
+static void ncmpi_load_buffer_state (void );
+static void ncmpi_init_buffer (YY_BUFFER_STATE b,FILE *file );
+
+#define YY_FLUSH_BUFFER ncmpi_flush_buffer(YY_CURRENT_BUFFER )
+
+YY_BUFFER_STATE ncmpi_scan_buffer (char *base,yy_size_t size );
+YY_BUFFER_STATE ncmpi_scan_string (yyconst char *yy_str );
+YY_BUFFER_STATE ncmpi_scan_bytes (yyconst char *bytes,int len );
+
+void *ncmpialloc (yy_size_t );
+void *ncmpirealloc (void *,yy_size_t );
+void ncmpifree (void * );
+
+#define yy_new_buffer ncmpi_create_buffer
+
+#define yy_set_interactive(is_interactive) \
+ { \
+ if ( ! YY_CURRENT_BUFFER ){ \
+ ncmpiensure_buffer_stack (); \
+ YY_CURRENT_BUFFER_LVALUE = \
+ ncmpi_create_buffer(ncmpiin,YY_BUF_SIZE ); \
+ } \
+ YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
+ }
+
+#define yy_set_bol(at_bol) \
+ { \
+ if ( ! YY_CURRENT_BUFFER ){\
+ ncmpiensure_buffer_stack (); \
+ YY_CURRENT_BUFFER_LVALUE = \
+ ncmpi_create_buffer(ncmpiin,YY_BUF_SIZE ); \
+ } \
+ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
+ }
+
+#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
+
+typedef unsigned char YY_CHAR;
+
+FILE *ncmpiin = (FILE *) 0, *ncmpiout = (FILE *) 0;
+
+typedef int yy_state_type;
+
+extern int ncmpilineno;
+
+int ncmpilineno = 1;
+
+extern char *ncmpitext;
+#define yytext_ptr ncmpitext
+
+static yy_state_type yy_get_previous_state (void );
+static yy_state_type yy_try_NUL_trans (yy_state_type current_state );
+static int yy_get_next_buffer (void );
+static void yy_fatal_error (yyconst char msg[] );
+
+/* Done after the current pattern has been matched and before the
+ * corresponding action - sets up ncmpitext.
+ */
+#define YY_DO_BEFORE_ACTION \
+ (yytext_ptr) = yy_bp; \
+ ncmpileng = (size_t) (yy_cp - yy_bp); \
+ (yy_hold_char) = *yy_cp; \
+ *yy_cp = '\0'; \
+ (yy_c_buf_p) = yy_cp;
+
+#define YY_NUM_RULES 35
+#define YY_END_OF_BUFFER 36
+/* This struct is not used in this scanner,
+ but its presence is necessary. */
+struct yy_trans_info
+ {
+ flex_int32_t yy_verify;
+ flex_int32_t yy_nxt;
+ };
+static yyconst flex_int16_t yy_accept[277] =
+ { 0,
+ 0, 0, 36, 34, 33, 22, 34, 34, 34, 34,
+ 24, 34, 27, 27, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 33, 0,
+ 2, 0, 0, 0, 24, 27, 27, 0, 0, 24,
+ 24, 0, 25, 1, 28, 28, 23, 28, 27, 26,
+ 0, 27, 23, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+
+ 21, 21, 29, 0, 0, 0, 0, 0, 24, 0,
+ 0, 24, 1, 28, 24, 28, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 7, 21, 21, 21,
+ 19, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 7, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 32, 30, 0, 0, 24, 0,
+ 24, 25, 24, 5, 4, 21, 21, 21, 21, 21,
+ 21, 21, 21, 20, 21, 7, 21, 3, 21, 21,
+ 11, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 11, 21, 21, 21, 30, 0,
+
+ 31, 0, 20, 0, 17, 21, 21, 21, 21, 12,
+ 21, 21, 21, 6, 9, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 0, 21,
+ 8, 21, 21, 21, 21, 21, 13, 21, 10, 21,
+ 21, 21, 21, 21, 0, 21, 21, 21, 21, 0,
+ 21, 21, 21, 21, 21, 0, 21, 21, 18, 18,
+ 21, 21, 21, 21, 21, 19, 21, 14, 21, 21,
+ 21, 21, 16, 21, 15, 0
+ } ;
+
+static yyconst flex_int32_t yy_ec[256] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 2, 3,
+ 1, 4, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 1, 5, 6, 1, 1, 1, 7, 1,
+ 1, 1, 8, 1, 9, 10, 11, 12, 13, 13,
+ 13, 14, 13, 15, 13, 16, 16, 17, 1, 1,
+ 1, 1, 1, 6, 18, 19, 20, 21, 22, 23,
+ 24, 25, 26, 27, 27, 28, 29, 30, 31, 27,
+ 27, 32, 33, 34, 35, 36, 27, 37, 38, 27,
+ 6, 39, 6, 1, 27, 1, 40, 41, 42, 43,
+
+ 44, 45, 46, 47, 48, 27, 27, 49, 50, 51,
+ 52, 27, 27, 53, 54, 55, 56, 57, 27, 37,
+ 58, 27, 59, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1
+ } ;
+
+static yyconst flex_int32_t yy_meta[60] =
+ { 0,
+ 1, 1, 2, 1, 1, 3, 4, 3, 3, 3,
+ 1, 5, 5, 5, 5, 5, 1, 5, 5, 5,
+ 5, 5, 5, 3, 3, 3, 3, 6, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 1, 5,
+ 5, 5, 5, 5, 5, 3, 3, 3, 6, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 7
+ } ;
+
+static yyconst flex_int16_t yy_base[287] =
+ { 0,
+ 0, 0, 514, 515, 58, 515, 56, 474, 53, 88,
+ 121, 501, 161, 206, 0, 473, 485, 53, 73, 42,
+ 42, 478, 52, 486, 482, 87, 488, 447, 457, 59,
+ 454, 451, 449, 456, 455, 451, 67, 457, 74, 85,
+ 515, 493, 488, 113, 0, 139, 0, 228, 443, 0,
+ 515, 249, 515, 0, 110, 45, 81, 258, 515, 515,
+ 0, 0, 515, 0, 459, 474, 457, 461, 454, 432,
+ 217, 296, 456, 434, 451, 439, 453, 448, 451, 462,
+ 448, 440, 447, 448, 450, 442, 418, 432, 416, 420,
+ 413, 416, 412, 415, 393, 401, 385, 362, 368, 369,
+
+ 369, 361, 515, 406, 178, 405, 91, 263, 334, 366,
+ 268, 372, 0, 515, 293, 113, 388, 377, 390, 385,
+ 387, 364, 0, 0, 386, 363, 101, 32, 378, 381,
+ 0, 371, 366, 363, 362, 368, 361, 365, 346, 336,
+ 342, 337, 339, 338, 68, 330, 119, 326, 321, 318,
+ 317, 323, 318, 321, 515, 515, 239, 361, 515, 100,
+ 129, 158, 515, 0, 0, 350, 336, 337, 315, 329,
+ 306, 346, 335, 0, 307, 0, 335, 0, 320, 331,
+ 337, 322, 312, 325, 323, 286, 286, 279, 319, 286,
+ 310, 287, 274, 284, 312, 276, 272, 283, 515, 315,
+
+ 515, 313, 515, 267, 515, 282, 291, 262, 279, 0,
+ 282, 255, 277, 0, 0, 285, 272, 263, 277, 241,
+ 250, 249, 269, 246, 276, 241, 233, 246, 237, 243,
+ 0, 242, 208, 224, 194, 246, 0, 211, 0, 210,
+ 187, 174, 171, 175, 168, 186, 163, 168, 154, 209,
+ 187, 186, 148, 155, 153, 138, 165, 143, 0, 185,
+ 151, 136, 117, 120, 106, 515, 125, 0, 139, 77,
+ 112, 105, 515, 79, 515, 515, 421, 428, 433, 439,
+ 446, 449, 59, 452, 454, 459
+ } ;
+
+static yyconst flex_int16_t yy_def[287] =
+ { 0,
+ 276, 1, 276, 276, 276, 276, 277, 278, 276, 276,
+ 276, 276, 276, 276, 279, 279, 279, 279, 279, 279,
+ 279, 279, 279, 279, 279, 279, 279, 279, 279, 279,
+ 279, 279, 279, 279, 279, 279, 279, 279, 276, 277,
+ 276, 277, 276, 280, 11, 14, 14, 276, 276, 11,
+ 276, 276, 276, 281, 13, 282, 282, 282, 276, 276,
+ 283, 14, 276, 279, 279, 279, 279, 279, 279, 279,
+ 279, 279, 279, 279, 279, 279, 279, 279, 279, 279,
+ 279, 279, 279, 279, 279, 279, 279, 279, 279, 279,
+ 279, 279, 279, 279, 279, 279, 279, 279, 279, 279,
+
+ 279, 279, 276, 276, 276, 284, 46, 276, 276, 276,
+ 276, 276, 281, 276, 58, 283, 279, 279, 279, 279,
+ 279, 279, 279, 279, 279, 279, 279, 279, 279, 279,
+ 279, 279, 279, 279, 279, 279, 279, 279, 279, 279,
+ 279, 279, 279, 279, 279, 279, 279, 279, 279, 279,
+ 279, 279, 279, 279, 276, 276, 276, 285, 276, 276,
+ 282, 282, 276, 279, 279, 279, 279, 279, 279, 279,
+ 279, 279, 279, 279, 279, 279, 279, 279, 279, 279,
+ 279, 279, 279, 279, 279, 279, 279, 279, 279, 279,
+ 279, 279, 279, 279, 279, 279, 279, 279, 276, 276,
+
+ 276, 276, 276, 276, 276, 279, 279, 279, 279, 279,
+ 279, 279, 279, 279, 279, 279, 279, 279, 279, 279,
+ 279, 279, 279, 279, 279, 279, 279, 279, 276, 279,
+ 279, 279, 279, 279, 279, 279, 279, 279, 279, 279,
+ 279, 279, 279, 279, 276, 279, 279, 279, 279, 286,
+ 279, 279, 279, 279, 279, 276, 279, 279, 286, 286,
+ 279, 279, 279, 279, 279, 276, 279, 279, 279, 279,
+ 279, 279, 276, 279, 276, 0, 276, 276, 276, 276,
+ 276, 276, 276, 276, 276, 276
+ } ;
+
+static yyconst flex_int16_t yy_nxt[575] =
+ { 0,
+ 4, 5, 6, 5, 7, 4, 8, 9, 10, 11,
+ 12, 13, 14, 14, 14, 14, 4, 15, 16, 17,
+ 18, 19, 20, 15, 15, 21, 15, 22, 15, 23,
+ 15, 24, 25, 15, 26, 27, 15, 15, 4, 15,
+ 28, 29, 30, 19, 31, 15, 15, 32, 33, 15,
+ 34, 15, 35, 36, 15, 37, 38, 15, 4, 39,
+ 41, 39, 45, 116, 46, 47, 47, 47, 47, 73,
+ 67, 75, 114, 78, 48, 39, 174, 39, 68, 175,
+ 71, 71, 189, 69, 72, 72, 72, 72, 72, 41,
+ 74, 79, 76, 114, 42, 275, 48, 45, 89, 46,
+
+ 47, 47, 47, 47, 70, 82, 90, 98, 114, 48,
+ 91, 190, 83, 49, 99, 172, 84, 100, 276, 85,
+ 101, 275, 173, 42, 105, 105, 105, 105, 273, 114,
+ 274, 48, 50, 50, 50, 50, 50, 114, 191, 276,
+ 114, 51, 52, 53, 203, 60, 276, 204, 51, 106,
+ 107, 107, 107, 107, 107, 273, 114, 272, 114, 271,
+ 192, 114, 268, 51, 52, 53, 60, 270, 269, 51,
+ 45, 268, 55, 55, 55, 55, 55, 114, 56, 57,
+ 56, 56, 58, 56, 156, 114, 260, 131, 59, 157,
+ 157, 157, 157, 60, 267, 266, 265, 61, 264, 263,
+
+ 56, 57, 56, 56, 58, 56, 114, 262, 261, 59,
+ 260, 131, 174, 258, 60, 45, 257, 62, 62, 62,
+ 62, 62, 256, 255, 63, 254, 176, 48, 72, 72,
+ 72, 72, 72, 59, 253, 108, 108, 252, 60, 109,
+ 109, 109, 109, 109, 251, 199, 63, 250, 249, 48,
+ 200, 200, 200, 200, 59, 176, 111, 111, 248, 60,
+ 112, 112, 112, 112, 112, 108, 108, 247, 246, 115,
+ 115, 115, 115, 115, 109, 109, 109, 109, 109, 112,
+ 112, 112, 112, 112, 245, 114, 244, 239, 243, 237,
+ 236, 236, 242, 231, 241, 240, 239, 238, 237, 236,
+
+ 276, 276, 235, 234, 233, 232, 114, 72, 72, 72,
+ 72, 72, 231, 161, 230, 162, 123, 229, 124, 201,
+ 163, 199, 228, 123, 227, 226, 225, 215, 214, 224,
+ 223, 222, 210, 178, 221, 161, 220, 162, 123, 205,
+ 124, 163, 219, 218, 123, 109, 109, 109, 109, 109,
+ 217, 216, 215, 214, 159, 213, 53, 212, 211, 210,
+ 209, 159, 178, 208, 207, 206, 205, 201, 198, 197,
+ 196, 195, 194, 193, 178, 176, 159, 188, 53, 187,
+ 186, 185, 159, 112, 112, 112, 112, 112, 165, 164,
+ 184, 183, 51, 182, 53, 181, 180, 179, 178, 51,
+
+ 177, 176, 171, 170, 169, 168, 167, 166, 165, 164,
+ 160, 155, 155, 154, 51, 153, 53, 152, 151, 150,
+ 51, 40, 40, 40, 40, 40, 40, 40, 43, 43,
+ 43, 43, 43, 43, 43, 64, 149, 64, 64, 104,
+ 148, 104, 104, 104, 104, 104, 113, 147, 113, 113,
+ 113, 113, 113, 56, 56, 158, 158, 202, 202, 259,
+ 259, 259, 259, 259, 259, 146, 145, 144, 143, 142,
+ 141, 140, 139, 138, 137, 136, 135, 134, 133, 132,
+ 131, 130, 129, 128, 127, 126, 125, 122, 121, 120,
+ 119, 118, 117, 110, 103, 276, 102, 97, 96, 95,
+
+ 94, 93, 92, 88, 87, 86, 81, 80, 77, 66,
+ 65, 54, 44, 276, 3, 276, 276, 276, 276, 276,
+ 276, 276, 276, 276, 276, 276, 276, 276, 276, 276,
+ 276, 276, 276, 276, 276, 276, 276, 276, 276, 276,
+ 276, 276, 276, 276, 276, 276, 276, 276, 276, 276,
+ 276, 276, 276, 276, 276, 276, 276, 276, 276, 276,
+ 276, 276, 276, 276, 276, 276, 276, 276, 276, 276,
+ 276, 276, 276, 276
+ } ;
+
+static yyconst flex_int16_t yy_chk[575] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 5,
+ 7, 5, 9, 283, 9, 9, 9, 9, 9, 20,
+ 18, 21, 56, 23, 9, 39, 128, 39, 18, 128,
+ 19, 19, 145, 18, 19, 19, 19, 19, 19, 40,
+ 20, 23, 21, 56, 7, 274, 9, 10, 30, 10,
+
+ 10, 10, 10, 10, 18, 26, 30, 37, 57, 10,
+ 30, 145, 26, 10, 37, 127, 26, 37, 107, 26,
+ 37, 272, 127, 40, 44, 44, 44, 44, 271, 57,
+ 270, 10, 11, 11, 11, 11, 11, 55, 147, 107,
+ 116, 11, 11, 11, 160, 116, 55, 160, 11, 44,
+ 46, 46, 46, 46, 46, 269, 161, 267, 55, 265,
+ 147, 116, 264, 11, 11, 11, 116, 263, 262, 11,
+ 13, 261, 13, 13, 13, 13, 13, 161, 13, 13,
+ 13, 13, 13, 13, 105, 162, 260, 258, 13, 105,
+ 105, 105, 105, 13, 257, 256, 255, 13, 254, 253,
+
+ 13, 13, 13, 13, 13, 13, 162, 252, 251, 13,
+ 250, 249, 248, 247, 13, 14, 246, 14, 14, 14,
+ 14, 14, 245, 244, 14, 243, 242, 14, 71, 71,
+ 71, 71, 71, 14, 241, 48, 48, 240, 14, 48,
+ 48, 48, 48, 48, 238, 157, 14, 236, 235, 14,
+ 157, 157, 157, 157, 14, 234, 52, 52, 233, 14,
+ 52, 52, 52, 52, 52, 58, 58, 232, 230, 58,
+ 58, 58, 58, 58, 108, 108, 108, 108, 108, 111,
+ 111, 111, 111, 111, 229, 58, 228, 227, 226, 225,
+ 224, 223, 222, 221, 220, 219, 218, 217, 216, 213,
+
+ 115, 115, 212, 211, 209, 208, 58, 72, 72, 72,
+ 72, 72, 207, 115, 206, 115, 72, 204, 72, 202,
+ 115, 200, 198, 72, 197, 196, 195, 194, 193, 192,
+ 191, 190, 189, 188, 187, 115, 186, 115, 72, 185,
+ 72, 115, 184, 183, 72, 109, 109, 109, 109, 109,
+ 182, 181, 180, 179, 109, 177, 109, 175, 173, 172,
+ 171, 109, 170, 169, 168, 167, 166, 158, 154, 153,
+ 152, 151, 150, 149, 148, 146, 109, 144, 109, 143,
+ 142, 141, 109, 112, 112, 112, 112, 112, 140, 139,
+ 138, 137, 112, 136, 112, 135, 134, 133, 132, 112,
+
+ 130, 129, 126, 125, 122, 121, 120, 119, 118, 117,
+ 110, 106, 104, 102, 112, 101, 112, 100, 99, 98,
+ 112, 277, 277, 277, 277, 277, 277, 277, 278, 278,
+ 278, 278, 278, 278, 278, 279, 97, 279, 279, 280,
+ 96, 280, 280, 280, 280, 280, 281, 95, 281, 281,
+ 281, 281, 281, 282, 282, 284, 284, 285, 285, 286,
+ 286, 286, 286, 286, 286, 94, 93, 92, 91, 90,
+ 89, 88, 87, 86, 85, 84, 83, 82, 81, 80,
+ 79, 78, 77, 76, 75, 74, 73, 70, 69, 68,
+ 67, 66, 65, 49, 43, 42, 38, 36, 35, 34,
+
+ 33, 32, 31, 29, 28, 27, 25, 24, 22, 17,
+ 16, 12, 8, 3, 276, 276, 276, 276, 276, 276,
+ 276, 276, 276, 276, 276, 276, 276, 276, 276, 276,
+ 276, 276, 276, 276, 276, 276, 276, 276, 276, 276,
+ 276, 276, 276, 276, 276, 276, 276, 276, 276, 276,
+ 276, 276, 276, 276, 276, 276, 276, 276, 276, 276,
+ 276, 276, 276, 276, 276, 276, 276, 276, 276, 276,
+ 276, 276, 276, 276
+ } ;
+
+static yy_state_type yy_last_accepting_state;
+static char *yy_last_accepting_cpos;
+
+extern int ncmpi_flex_debug;
+int ncmpi_flex_debug = 0;
+
+/* The intent behind this definition is that it'll catch
+ * any uses of REJECT which flex missed.
+ */
+#define REJECT reject_used_but_not_detected
+#define yymore() yymore_used_but_not_detected
+#define YY_MORE_ADJ 0
+#define YY_RESTORE_YY_MORE_OFFSET
+char *ncmpitext;
+#line 1 "./ncmpigen.l"
+#line 2 "./ncmpigen.l"
+/*********************************************************************
+ * Copyright 1993, UCAR/Unidata
+ * See netcdf/COPYRIGHT file for copying and redistribution conditions.
+ * $Id: ncmpigenyy.c 2035 2015-05-29 18:58:33Z wkliao $
+ *********************************************************************/
+
+/* lex specification for tokens for ncmpigen */
+
+/* Fill value used by ncdump from version 2.4 and later. Should match
+ definition of FILL_STRING in ../ncdump/vardata.h */
+#define FILL_STRING "_"
+#define XDR_INT_MIN (-2147483647-1)
+#define XDR_INT_MAX 2147483647
+#define XDR_INT64_MIN (-9223372036854775807LL-1)
+#define XDR_INT64_MAX (9223372036854775807LL)
+
+char errstr[100]; /* for short error messages */
+
+#include <string.h>
+#include <ctype.h>
+#include <errno.h> /* errno */
+#include "genlib.h"
+#include "ncmpigentab.h"
+
+#define YY_BREAK /* defining as nothing eliminates unreachable
+ statement warnings from flex output,
+ but make sure every action ends with
+ "return" or "break"! */
+
+#line 714 "lex.ncmpi.c"
+
+#define INITIAL 0
+
+#ifndef YY_NO_UNISTD_H
+/* Special case for "unistd.h", since it is non-ANSI. We include it way
+ * down here because we want the user's section 1 to have been scanned first.
+ * The user has a chance to override it with an option.
+ */
+#include <unistd.h>
+#endif
+
+#ifndef YY_EXTRA_TYPE
+#define YY_EXTRA_TYPE void *
+#endif
+
+static int yy_init_globals (void );
+
+/* Accessor methods to globals.
+ These are made visible to non-reentrant scanners for convenience. */
+
+int ncmpilex_destroy (void );
+
+int ncmpiget_debug (void );
+
+void ncmpiset_debug (int debug_flag );
+
+YY_EXTRA_TYPE ncmpiget_extra (void );
+
+void ncmpiset_extra (YY_EXTRA_TYPE user_defined );
+
+FILE *ncmpiget_in (void );
+
+void ncmpiset_in (FILE * in_str );
+
+FILE *ncmpiget_out (void );
+
+void ncmpiset_out (FILE * out_str );
+
+int ncmpiget_leng (void );
+
+char *ncmpiget_text (void );
+
+int ncmpiget_lineno (void );
+
+void ncmpiset_lineno (int line_number );
+
+/* Macros after this point can all be overridden by user definitions in
+ * section 1.
+ */
+
+#ifndef YY_SKIP_YYWRAP
+#ifdef __cplusplus
+extern "C" int ncmpiwrap (void );
+#else
+extern int ncmpiwrap (void );
+#endif
+#endif
+
+ static void yyunput (int c,char *buf_ptr );
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char *,yyconst char *,int );
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (yyconst char * );
+#endif
+
+#ifndef YY_NO_INPUT
+
+#ifdef __cplusplus
+static int yyinput (void );
+#else
+static int input (void );
+#endif
+
+#endif
+
+/* Amount of stuff to slurp up with each read. */
+#ifndef YY_READ_BUF_SIZE
+#define YY_READ_BUF_SIZE 8192
+#endif
+
+/* Copy whatever the last rule matched to the standard output. */
+#ifndef ECHO
+/* This used to be an fputs(), but since the string might contain NUL's,
+ * we now use fwrite().
+ */
+#define ECHO do { if (fwrite( ncmpitext, ncmpileng, 1, ncmpiout )) {} } while (0)
+#endif
+
+/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL,
+ * is returned in "result".
+ */
+#ifndef YY_INPUT
+#define YY_INPUT(buf,result,max_size) \
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
+ { \
+ int c = '*'; \
+ unsigned n; \
+ for ( n = 0; n < max_size && \
+ (c = getc( ncmpiin )) != EOF && c != '\n'; ++n ) \
+ buf[n] = (char) c; \
+ if ( c == '\n' ) \
+ buf[n++] = (char) c; \
+ if ( c == EOF && ferror( ncmpiin ) ) \
+ YY_FATAL_ERROR( "input in flex scanner failed" ); \
+ result = n; \
+ } \
+ else \
+ { \
+ errno=0; \
+ while ( (result = fread(buf, 1, max_size, ncmpiin))==0 && ferror(ncmpiin)) \
+ { \
+ if( errno != EINTR) \
+ { \
+ YY_FATAL_ERROR( "input in flex scanner failed" ); \
+ break; \
+ } \
+ errno=0; \
+ clearerr(ncmpiin); \
+ } \
+ }\
+\
+
+#endif
+
+/* No semi-colon after return; correct usage is to write "yyterminate();" -
+ * we don't want an extra ';' after the "return" because that will cause
+ * some compilers to complain about unreachable statements.
+ */
+#ifndef yyterminate
+#define yyterminate() return YY_NULL
+#endif
+
+/* Number of entries by which start-condition stack grows. */
+#ifndef YY_START_STACK_INCR
+#define YY_START_STACK_INCR 25
+#endif
+
+/* Report a fatal error. */
+#ifndef YY_FATAL_ERROR
+#define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
+#endif
+
+/* end tables serialization structures and prototypes */
+
+/* Default declaration of generated scanner - a define so the user can
+ * easily add parameters.
+ */
+#ifndef YY_DECL
+#define YY_DECL_IS_OURS 1
+
+extern int ncmpilex (void);
+
+#define YY_DECL int ncmpilex (void)
+#endif /* !YY_DECL */
+
+/* Code executed at the beginning of each rule, after ncmpitext and ncmpileng
+ * have been set up.
+ */
+#ifndef YY_USER_ACTION
+#define YY_USER_ACTION
+#endif
+
+/* Code executed at the end of each rule. */
+#ifndef YY_BREAK
+#define YY_BREAK break;
+#endif
+
+#define YY_RULE_SETUP \
+ YY_USER_ACTION
+
+/** The main scanner function which does all the work.
+ */
+YY_DECL
+{
+ register yy_state_type yy_current_state;
+ register char *yy_cp, *yy_bp;
+ register int yy_act;
+
+#line 38 "./ncmpigen.l"
+
+#line 898 "lex.ncmpi.c"
+
+ if ( !(yy_init) )
+ {
+ (yy_init) = 1;
+
+#ifdef YY_USER_INIT
+ YY_USER_INIT;
+#endif
+
+ if ( ! (yy_start) )
+ (yy_start) = 1; /* first start state */
+
+ if ( ! ncmpiin )
+ ncmpiin = stdin;
+
+ if ( ! ncmpiout )
+ ncmpiout = stdout;
+
+ if ( ! YY_CURRENT_BUFFER ) {
+ ncmpiensure_buffer_stack ();
+ YY_CURRENT_BUFFER_LVALUE =
+ ncmpi_create_buffer(ncmpiin,YY_BUF_SIZE );
+ }
+
+ ncmpi_load_buffer_state( );
+ }
+
+ while ( 1 ) /* loops until end-of-file is reached */
+ {
+ yy_cp = (yy_c_buf_p);
+
+ /* Support of ncmpitext. */
+ *yy_cp = (yy_hold_char);
+
+ /* yy_bp points to the position in yy_ch_buf of the start of
+ * the current run.
+ */
+ yy_bp = yy_cp;
+
+ yy_current_state = (yy_start);
+yy_match:
+ do
+ {
+ register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];
+ if ( yy_accept[yy_current_state] )
+ {
+ (yy_last_accepting_state) = yy_current_state;
+ (yy_last_accepting_cpos) = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 277 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ ++yy_cp;
+ }
+ while ( yy_base[yy_current_state] != 515 );
+
+yy_find_action:
+ yy_act = yy_accept[yy_current_state];
+ if ( yy_act == 0 )
+ { /* have to back up */
+ yy_cp = (yy_last_accepting_cpos);
+ yy_current_state = (yy_last_accepting_state);
+ yy_act = yy_accept[yy_current_state];
+ }
+
+ YY_DO_BEFORE_ACTION;
+
+do_action: /* This label is used only to access EOF actions. */
+
+ switch ( yy_act )
+ { /* beginning of action switch */
+ case 0: /* must back up */
+ /* undo the effects of YY_DO_BEFORE_ACTION */
+ *yy_cp = (yy_hold_char);
+ yy_cp = (yy_last_accepting_cpos);
+ yy_current_state = (yy_last_accepting_state);
+ goto yy_find_action;
+
+case 1:
+YY_RULE_SETUP
+#line 39 "./ncmpigen.l"
+{ /* comment */
+ break;
+ }
+ YY_BREAK
+case 2:
+/* rule 2 can match eol */
+YY_RULE_SETUP
+#line 43 "./ncmpigen.l"
+{
+ if(ncmpileng > MAXTRST) {
+ yyerror("string too long, truncated\n");
+ ncmpitext[MAXTRST-1] = '\0';
+ }
+ expand_escapes(termstring,(char *)ncmpitext,ncmpileng);
+ return (TERMSTRING);
+ }
+ YY_BREAK
+case 3:
+YY_RULE_SETUP
+#line 52 "./ncmpigen.l"
+{return (FLOAT_K);}
+ YY_BREAK
+case 4:
+YY_RULE_SETUP
+#line 53 "./ncmpigen.l"
+{return (CHAR_K);}
+ YY_BREAK
+case 5:
+YY_RULE_SETUP
+#line 54 "./ncmpigen.l"
+{return (BYTE_K);}
+ YY_BREAK
+case 6:
+YY_RULE_SETUP
+#line 55 "./ncmpigen.l"
+{return (SHORT_K);}
+ YY_BREAK
+case 7:
+YY_RULE_SETUP
+#line 56 "./ncmpigen.l"
+{return (INT_K);}
+ YY_BREAK
+case 8:
+YY_RULE_SETUP
+#line 57 "./ncmpigen.l"
+{return (DOUBLE_K);}
+ YY_BREAK
+case 9:
+YY_RULE_SETUP
+#line 58 "./ncmpigen.l"
+{return (UBYTE_K);}
+ YY_BREAK
+case 10:
+YY_RULE_SETUP
+#line 59 "./ncmpigen.l"
+{return (USHORT_K);}
+ YY_BREAK
+case 11:
+YY_RULE_SETUP
+#line 60 "./ncmpigen.l"
+{return (UINT_K);}
+ YY_BREAK
+case 12:
+YY_RULE_SETUP
+#line 61 "./ncmpigen.l"
+{return (INT64_K);}
+ YY_BREAK
+case 13:
+YY_RULE_SETUP
+#line 62 "./ncmpigen.l"
+{return (UINT64_K);}
+ YY_BREAK
+case 14:
+YY_RULE_SETUP
+#line 63 "./ncmpigen.l"
+{int_val = -1;
+ return (NC_UNLIMITED_K);}
+ YY_BREAK
+case 15:
+YY_RULE_SETUP
+#line 66 "./ncmpigen.l"
+{return (DIMENSIONS);}
+ YY_BREAK
+case 16:
+YY_RULE_SETUP
+#line 67 "./ncmpigen.l"
+{return (VARIABLES);}
+ YY_BREAK
+case 17:
+YY_RULE_SETUP
+#line 68 "./ncmpigen.l"
+{return (DATA);}
+ YY_BREAK
+case 18:
+/* rule 18 can match eol */
+YY_RULE_SETUP
+#line 69 "./ncmpigen.l"
+{
+ char *s = (char*)ncmpitext+strlen("netcdf");
+ char *t = (char*)ncmpitext+ncmpileng-1;
+ while (isspace(*s))
+ s++;
+ while (isspace(*t))
+ t--;
+ t++;
+ if (t-s+1 < 1) {
+ yyerror("netCDF name required");
+ return (DATA); /* generate syntax error */
+ }
+ netcdfname = (char *) emalloc(t-s+1);
+ (void) strncpy(netcdfname, s, t-s);
+ netcdfname[t-s] = '\0';
+ return (NETCDF);
+ }
+ YY_BREAK
+case 19:
+YY_RULE_SETUP
+#line 86 "./ncmpigen.l"
+{ /* missing value (pre-2.4 backward compatibility) */
+ if (ncmpitext[0] == '-') {
+ double_val = -NC_FILL_DOUBLE;
+ } else {
+ double_val = NC_FILL_DOUBLE;
+ }
+ return (DOUBLE_CONST);
+ }
+ YY_BREAK
+case 20:
+YY_RULE_SETUP
+#line 94 "./ncmpigen.l"
+{ /* missing value (pre-2.4 backward compatibility) */
+ if (ncmpitext[0] == '-') {
+ float_val = -NC_FILL_FLOAT;
+ } else {
+ float_val = NC_FILL_FLOAT;
+ }
+ return (FLOAT_CONST);
+ }
+ YY_BREAK
+case 21:
+YY_RULE_SETUP
+#line 102 "./ncmpigen.l"
+{
+ if (STREQ((char *)ncmpitext, FILL_STRING))
+ return (FILLVALUE);
+ if ((yylval = lookup((char *)ncmpitext)) == NULL) {
+ yylval = install((char *)ncmpitext);
+ }
+ return (IDENT);
+ }
+ YY_BREAK
+case 22:
+/* rule 22 can match eol */
+YY_RULE_SETUP
+#line 111 "./ncmpigen.l"
+{
+ lineno++ ;
+ break;
+ }
+ YY_BREAK
+case 23:
+YY_RULE_SETUP
+#line 116 "./ncmpigen.l"
+{
+ int ii;
+ if (sscanf((char*)ncmpitext, "%d", &ii) != 1) {
+ sprintf(errstr,"bad byte constant: %s",(char*)ncmpitext);
+ yyerror(errstr);
+ }
+ byte_val = ii;
+ if (ii != (int)byte_val) {
+ sprintf(errstr,"byte constant out of range (-128,127): %s",(char*)ncmpitext);
+ yyerror(errstr);
+ }
+ return (BYTE_CONST);
+ }
+ YY_BREAK
+case 24:
+YY_RULE_SETUP
+#line 130 "./ncmpigen.l"
+{
+ if (sscanf((char*)ncmpitext, "%le", &double_val) != 1) {
+ sprintf(errstr,"bad long or double constant: %s",(char*)ncmpitext);
+ yyerror(errstr);
+ }
+ return (DOUBLE_CONST);
+ }
+ YY_BREAK
+case 25:
+YY_RULE_SETUP
+#line 137 "./ncmpigen.l"
+{
+ if (sscanf((char*)ncmpitext, "%e", &float_val) != 1) {
+ sprintf(errstr,"bad float constant: %s",(char*)ncmpitext);
+ yyerror(errstr);
+ }
+ return (FLOAT_CONST);
+ }
+ YY_BREAK
+case 26:
+YY_RULE_SETUP
+#line 144 "./ncmpigen.l"
+{
+ if (sscanf((char*)ncmpitext, "%hd", &short_val) != 1) {
+ sprintf(errstr,"bad short constant: %s",(char*)ncmpitext);
+ yyerror(errstr);
+ }
+ return (SHORT_CONST);
+ }
+ YY_BREAK
+case 27:
+YY_RULE_SETUP
+#line 151 "./ncmpigen.l"
+{
+ char *ptr;
+ errno = 0;
+ double_val = strtod((char*)ncmpitext, &ptr);
+ if (errno != 0 && double_val == 0.0) {
+ sprintf(errstr,"bad numerical constant: %s",(char*)ncmpitext);
+ yyerror(errstr);
+ }
+ if (double_val < XDR_INT_MIN ||double_val > XDR_INT_MAX) {
+ return DOUBLE_CONST;
+ } else {
+ int_val = (int) double_val;
+ return INT_CONST;
+ }
+ }
+ YY_BREAK
+case 28:
+YY_RULE_SETUP
+#line 166 "./ncmpigen.l"
+{
+ char *ptr;
+ long long_val;
+ errno = 0;
+ long_val = strtol((char*)ncmpitext, &ptr, 0);
+ if (errno != 0) {
+ sprintf(errstr,"bad long constant: %s",(char*)ncmpitext);
+ yyerror(errstr);
+ }
+ if (long_val < XDR_INT_MIN || long_val > XDR_INT_MAX) {
+ double_val = (double) long_val;
+ return DOUBLE_CONST;
+ } else {
+ int_val = (int) long_val;
+ return INT_CONST;
+ }
+ }
+ YY_BREAK
+case 29:
+/* rule 29 can match eol */
+YY_RULE_SETUP
+#line 183 "./ncmpigen.l"
+{
+ (void) sscanf((char*)&ncmpitext[1],"%c",&byte_val);
+ return (BYTE_CONST);
+ }
+ YY_BREAK
+case 30:
+YY_RULE_SETUP
+#line 187 "./ncmpigen.l"
+{
+ byte_val = (char) strtol((char*)&ncmpitext[2], (char **) 0, 8);
+ return (BYTE_CONST);
+ }
+ YY_BREAK
+case 31:
+YY_RULE_SETUP
+#line 191 "./ncmpigen.l"
+{
+ byte_val = (char) strtol((char*)&ncmpitext[3], (char **) 0, 16);
+ return (BYTE_CONST);
+ }
+ YY_BREAK
+case 32:
+YY_RULE_SETUP
+#line 195 "./ncmpigen.l"
+{
+ switch ((char)ncmpitext[2]) {
+ case 'a': byte_val = '\007'; break; /* not everyone under-
+ * stands '\a' yet */
+ case 'b': byte_val = '\b'; break;
+ case 'f': byte_val = '\f'; break;
+ case 'n': byte_val = '\n'; break;
+ case 'r': byte_val = '\r'; break;
+ case 't': byte_val = '\t'; break;
+ case 'v': byte_val = '\v'; break;
+ case '\\': byte_val = '\\'; break;
+ case '?': byte_val = '\177'; break;
+ case '\'': byte_val = '\''; break;
+ default: byte_val = (char)ncmpitext[2];
+ }
+ return (BYTE_CONST);
+ }
+ YY_BREAK
+case 33:
+YY_RULE_SETUP
+#line 213 "./ncmpigen.l"
+{ /* whitespace */
+ break;
+ }
+ YY_BREAK
+case 34:
+YY_RULE_SETUP
+#line 216 "./ncmpigen.l"
+return (ncmpitext[0]) ;
+ YY_BREAK
+case 35:
+YY_RULE_SETUP
+#line 217 "./ncmpigen.l"
+ECHO;
+ YY_BREAK
+#line 1297 "lex.ncmpi.c"
+case YY_STATE_EOF(INITIAL):
+ yyterminate();
+
+ case YY_END_OF_BUFFER:
+ {
+ /* Amount of text matched not including the EOB char. */
+ int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1;
+
+ /* Undo the effects of YY_DO_BEFORE_ACTION. */
+ *yy_cp = (yy_hold_char);
+ YY_RESTORE_YY_MORE_OFFSET
+
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW )
+ {
+ /* We're scanning a new file or input source. It's
+ * possible that this happened because the user
+ * just pointed ncmpiin at a new source and called
+ * ncmpilex(). If so, then we have to assure
+ * consistency between YY_CURRENT_BUFFER and our
+ * globals. Here is the right place to do so, because
+ * this is the first action (other than possibly a
+ * back-up) that will match for the new input source.
+ */
+ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+ YY_CURRENT_BUFFER_LVALUE->yy_input_file = ncmpiin;
+ YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;
+ }
+
+ /* Note that here we test for yy_c_buf_p "<=" to the position
+ * of the first EOB in the buffer, since yy_c_buf_p will
+ * already have been incremented past the NUL character
+ * (since all states make transitions on EOB to the
+ * end-of-buffer state). Contrast this with the test
+ * in input().
+ */
+ if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
+ { /* This was really a NUL. */
+ yy_state_type yy_next_state;
+
+ (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state( );
+
+ /* Okay, we're now positioned to make the NUL
+ * transition. We couldn't have
+ * yy_get_previous_state() go ahead and do it
+ * for us because it doesn't know how to deal
+ * with the possibility of jamming (and we don't
+ * want to build jamming into it because then it
+ * will run more slowly).
+ */
+
+ yy_next_state = yy_try_NUL_trans( yy_current_state );
+
+ yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+
+ if ( yy_next_state )
+ {
+ /* Consume the NUL. */
+ yy_cp = ++(yy_c_buf_p);
+ yy_current_state = yy_next_state;
+ goto yy_match;
+ }
+
+ else
+ {
+ yy_cp = (yy_c_buf_p);
+ goto yy_find_action;
+ }
+ }
+
+ else switch ( yy_get_next_buffer( ) )
+ {
+ case EOB_ACT_END_OF_FILE:
+ {
+ (yy_did_buffer_switch_on_eof) = 0;
+
+ if ( ncmpiwrap( ) )
+ {
+ /* Note: because we've taken care in
+ * yy_get_next_buffer() to have set up
+ * ncmpitext, we can now set up
+ * yy_c_buf_p so that if some total
+ * hoser (like flex itself) wants to
+ * call the scanner after we return the
+ * YY_NULL, it'll still work - another
+ * YY_NULL will get returned.
+ */
+ (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ;
+
+ yy_act = YY_STATE_EOF(YY_START);
+ goto do_action;
+ }
+
+ else
+ {
+ if ( ! (yy_did_buffer_switch_on_eof) )
+ YY_NEW_FILE;
+ }
+ break;
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ (yy_c_buf_p) =
+ (yytext_ptr) + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state( );
+
+ yy_cp = (yy_c_buf_p);
+ yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+ goto yy_match;
+
+ case EOB_ACT_LAST_MATCH:
+ (yy_c_buf_p) =
+ &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)];
+
+ yy_current_state = yy_get_previous_state( );
+
+ yy_cp = (yy_c_buf_p);
+ yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+ goto yy_find_action;
+ }
+ break;
+ }
+
+ default:
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--no action found" );
+ } /* end of action switch */
+ } /* end of scanning one token */
+} /* end of ncmpilex */
+
+/* yy_get_next_buffer - try to read in a new buffer
+ *
+ * Returns a code representing an action:
+ * EOB_ACT_LAST_MATCH -
+ * EOB_ACT_CONTINUE_SCAN - continue scanning from current position
+ * EOB_ACT_END_OF_FILE - end of file
+ */
+static int yy_get_next_buffer (void)
+{
+ register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
+ register char *source = (yytext_ptr);
+ register int number_to_move, i;
+ int ret_val;
+
+ if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] )
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--end of buffer missed" );
+
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 )
+ { /* Don't try to fill the buffer, so this is an EOF. */
+ if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 )
+ {
+ /* We matched a single character, the EOB, so
+ * treat this as a final EOF.
+ */
+ return EOB_ACT_END_OF_FILE;
+ }
+
+ else
+ {
+ /* We matched some text prior to the EOB, first
+ * process it.
+ */
+ return EOB_ACT_LAST_MATCH;
+ }
+ }
+
+ /* Try to read more data. */
+
+ /* First move last chars to start of buffer. */
+ number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1;
+
+ for ( i = 0; i < number_to_move; ++i )
+ *(dest++) = *(source++);
+
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING )
+ /* don't do the read, it's not guaranteed to return an EOF,
+ * just force an EOF
+ */
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0;
+
+ else
+ {
+ int num_to_read =
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
+
+ while ( num_to_read <= 0 )
+ { /* Not enough room in the buffer - grow it. */
+
+ /* just a shorter name for the current buffer */
+ YY_BUFFER_STATE b = YY_CURRENT_BUFFER;
+
+ int yy_c_buf_p_offset =
+ (int) ((yy_c_buf_p) - b->yy_ch_buf);
+
+ if ( b->yy_is_our_buffer )
+ {
+ int new_size = b->yy_buf_size * 2;
+
+ if ( new_size <= 0 )
+ b->yy_buf_size += b->yy_buf_size / 8;
+ else
+ b->yy_buf_size *= 2;
+
+ b->yy_ch_buf = (char *)
+ /* Include room in for 2 EOB chars. */
+ ncmpirealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 );
+ }
+ else
+ /* Can't grow it, we don't own it. */
+ b->yy_ch_buf = 0;
+
+ if ( ! b->yy_ch_buf )
+ YY_FATAL_ERROR(
+ "fatal error - scanner input buffer overflow" );
+
+ (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset];
+
+ num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size -
+ number_to_move - 1;
+
+ }
+
+ if ( num_to_read > YY_READ_BUF_SIZE )
+ num_to_read = YY_READ_BUF_SIZE;
+
+ /* Read in more data. */
+ YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
+ (yy_n_chars), (size_t) num_to_read );
+
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+ }
+
+ if ( (yy_n_chars) == 0 )
+ {
+ if ( number_to_move == YY_MORE_ADJ )
+ {
+ ret_val = EOB_ACT_END_OF_FILE;
+ ncmpirestart(ncmpiin );
+ }
+
+ else
+ {
+ ret_val = EOB_ACT_LAST_MATCH;
+ YY_CURRENT_BUFFER_LVALUE->yy_buffer_status =
+ YY_BUFFER_EOF_PENDING;
+ }
+ }
+
+ else
+ ret_val = EOB_ACT_CONTINUE_SCAN;
+
+ if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
+ /* Extend the array by 50%, plus the number we really need. */
+ yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1);
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) ncmpirealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size );
+ if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
+ }
+
+ (yy_n_chars) += number_to_move;
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR;
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR;
+
+ (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0];
+
+ return ret_val;
+}
+
+/* yy_get_previous_state - get the state just before the EOB char was reached */
+
+ static yy_state_type yy_get_previous_state (void)
+{
+ register yy_state_type yy_current_state;
+ register char *yy_cp;
+
+ yy_current_state = (yy_start);
+
+ for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp )
+ {
+ register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
+ if ( yy_accept[yy_current_state] )
+ {
+ (yy_last_accepting_state) = yy_current_state;
+ (yy_last_accepting_cpos) = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 277 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ }
+
+ return yy_current_state;
+}
+
+/* yy_try_NUL_trans - try to make a transition on the NUL character
+ *
+ * synopsis
+ * next_state = yy_try_NUL_trans( current_state );
+ */
+ static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state )
+{
+ register int yy_is_jam;
+ register char *yy_cp = (yy_c_buf_p);
+
+ register YY_CHAR yy_c = 1;
+ if ( yy_accept[yy_current_state] )
+ {
+ (yy_last_accepting_state) = yy_current_state;
+ (yy_last_accepting_cpos) = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 277 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ yy_is_jam = (yy_current_state == 276);
+
+ return yy_is_jam ? 0 : yy_current_state;
+}
+
+ static void yyunput (int c, register char * yy_bp )
+{
+ register char *yy_cp;
+
+ yy_cp = (yy_c_buf_p);
+
+ /* undo effects of setting up ncmpitext */
+ *yy_cp = (yy_hold_char);
+
+ if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
+ { /* need to shift things up to make room */
+ /* +2 for EOB chars. */
+ register int number_to_move = (yy_n_chars) + 2;
+ register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2];
+ register char *source =
+ &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move];
+
+ while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
+ *--dest = *--source;
+
+ yy_cp += (int) (dest - source);
+ yy_bp += (int) (dest - source);
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars =
+ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size;
+
+ if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
+ YY_FATAL_ERROR( "flex scanner push-back overflow" );
+ }
+
+ *--yy_cp = (char) c;
+
+ (yytext_ptr) = yy_bp;
+ (yy_hold_char) = *yy_cp;
+ (yy_c_buf_p) = yy_cp;
+}
+
+#ifndef YY_NO_INPUT
+#ifdef __cplusplus
+ static int yyinput (void)
+#else
+ static int input (void)
+#endif
+
+{
+ int c;
+
+ *(yy_c_buf_p) = (yy_hold_char);
+
+ if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR )
+ {
+ /* yy_c_buf_p now points to the character we want to return.
+ * If this occurs *before* the EOB characters, then it's a
+ * valid NUL; if not, then we've hit the end of the buffer.
+ */
+ if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
+ /* This was really a NUL. */
+ *(yy_c_buf_p) = '\0';
+
+ else
+ { /* need more input */
+ int offset = (yy_c_buf_p) - (yytext_ptr);
+ ++(yy_c_buf_p);
+
+ switch ( yy_get_next_buffer( ) )
+ {
+ case EOB_ACT_LAST_MATCH:
+ /* This happens because yy_g_n_b()
+ * sees that we've accumulated a
+ * token and flags that we need to
+ * try matching the token before
+ * proceeding. But for input(),
+ * there's no matching to consider.
+ * So convert the EOB_ACT_LAST_MATCH
+ * to EOB_ACT_END_OF_FILE.
+ */
+
+ /* Reset buffer status. */
+ ncmpirestart(ncmpiin );
+
+ /*FALLTHROUGH*/
+
+ case EOB_ACT_END_OF_FILE:
+ {
+ if ( ncmpiwrap( ) )
+ return EOF;
+
+ if ( ! (yy_did_buffer_switch_on_eof) )
+ YY_NEW_FILE;
+#ifdef __cplusplus
+ return yyinput();
+#else
+ return input();
+#endif
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ (yy_c_buf_p) = (yytext_ptr) + offset;
+ break;
+ }
+ }
+ }
+
+ c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */
+ *(yy_c_buf_p) = '\0'; /* preserve ncmpitext */
+ (yy_hold_char) = *++(yy_c_buf_p);
+
+ return c;
+}
+#endif /* ifndef YY_NO_INPUT */
+
+/** Immediately switch to a different input stream.
+ * @param input_file A readable stream.
+ *
+ * @note This function does not reset the start condition to @c INITIAL .
+ */
+ void ncmpirestart (FILE * input_file )
+{
+
+ if ( ! YY_CURRENT_BUFFER ){
+ ncmpiensure_buffer_stack ();
+ YY_CURRENT_BUFFER_LVALUE =
+ ncmpi_create_buffer(ncmpiin,YY_BUF_SIZE );
+ }
+
+ ncmpi_init_buffer(YY_CURRENT_BUFFER,input_file );
+ ncmpi_load_buffer_state( );
+}
+
+/** Switch to a different input buffer.
+ * @param new_buffer The new input buffer.
+ *
+ */
+ void ncmpi_switch_to_buffer (YY_BUFFER_STATE new_buffer )
+{
+
+ /* TODO. We should be able to replace this entire function body
+ * with
+ * ncmpipop_buffer_state();
+ * ncmpipush_buffer_state(new_buffer);
+ */
+ ncmpiensure_buffer_stack ();
+ if ( YY_CURRENT_BUFFER == new_buffer )
+ return;
+
+ if ( YY_CURRENT_BUFFER )
+ {
+ /* Flush out information for old buffer. */
+ *(yy_c_buf_p) = (yy_hold_char);
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+ }
+
+ YY_CURRENT_BUFFER_LVALUE = new_buffer;
+ ncmpi_load_buffer_state( );
+
+ /* We don't actually know whether we did this switch during
+ * EOF (ncmpiwrap()) processing, but the only time this flag
+ * is looked at is after ncmpiwrap() is called, so it's safe
+ * to go ahead and always set it.
+ */
+ (yy_did_buffer_switch_on_eof) = 1;
+}
+
+static void ncmpi_load_buffer_state (void)
+{
+ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+ (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos;
+ ncmpiin = YY_CURRENT_BUFFER_LVALUE->yy_input_file;
+ (yy_hold_char) = *(yy_c_buf_p);
+}
+
+/** Allocate and initialize an input buffer state.
+ * @param file A readable stream.
+ * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.
+ *
+ * @return the allocated buffer state.
+ */
+ YY_BUFFER_STATE ncmpi_create_buffer (FILE * file, int size )
+{
+ YY_BUFFER_STATE b;
+
+ b = (YY_BUFFER_STATE) ncmpialloc(sizeof( struct yy_buffer_state ) );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in ncmpi_create_buffer()" );
+
+ b->yy_buf_size = size;
+
+ /* yy_ch_buf has to be 2 characters longer than the size given because
+ * we need to put in 2 end-of-buffer characters.
+ */
+ b->yy_ch_buf = (char *) ncmpialloc(b->yy_buf_size + 2 );
+ if ( ! b->yy_ch_buf )
+ YY_FATAL_ERROR( "out of dynamic memory in ncmpi_create_buffer()" );
+
+ b->yy_is_our_buffer = 1;
+
+ ncmpi_init_buffer(b,file );
+
+ return b;
+}
+
+/** Destroy the buffer.
+ * @param b a buffer created with ncmpi_create_buffer()
+ *
+ */
+ void ncmpi_delete_buffer (YY_BUFFER_STATE b )
+{
+
+ if ( ! b )
+ return;
+
+ if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */
+ YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
+
+ if ( b->yy_is_our_buffer )
+ ncmpifree((void *) b->yy_ch_buf );
+
+ ncmpifree((void *) b );
+}
+
+#ifndef __cplusplus
+extern int isatty (int );
+#endif /* __cplusplus */
+
+/* Initializes or reinitializes a buffer.
+ * This function is sometimes called more than once on the same buffer,
+ * such as during a ncmpirestart() or at EOF.
+ */
+ static void ncmpi_init_buffer (YY_BUFFER_STATE b, FILE * file )
+
+{
+ int oerrno = errno;
+
+ ncmpi_flush_buffer(b );
+
+ b->yy_input_file = file;
+ b->yy_fill_buffer = 1;
+
+ /* If b is the current buffer, then ncmpi_init_buffer was _probably_
+ * called from ncmpirestart() or through yy_get_next_buffer.
+ * In that case, we don't want to reset the lineno or column.
+ */
+ if (b != YY_CURRENT_BUFFER){
+ b->yy_bs_lineno = 1;
+ b->yy_bs_column = 0;
+ }
+
+ b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
+
+ errno = oerrno;
+}
+
+/** Discard all buffered characters. On the next scan, YY_INPUT will be called.
+ * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
+ *
+ */
+ void ncmpi_flush_buffer (YY_BUFFER_STATE b )
+{
+ if ( ! b )
+ return;
+
+ b->yy_n_chars = 0;
+
+ /* We always need two end-of-buffer characters. The first causes
+ * a transition to the end-of-buffer state. The second causes
+ * a jam in that state.
+ */
+ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
+ b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
+
+ b->yy_buf_pos = &b->yy_ch_buf[0];
+
+ b->yy_at_bol = 1;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ if ( b == YY_CURRENT_BUFFER )
+ ncmpi_load_buffer_state( );
+}
+
+/** Pushes the new state onto the stack. The new state becomes
+ * the current state. This function will allocate the stack
+ * if necessary.
+ * @param new_buffer The new state.
+ *
+ */
+void ncmpipush_buffer_state (YY_BUFFER_STATE new_buffer )
+{
+ if (new_buffer == NULL)
+ return;
+
+ ncmpiensure_buffer_stack();
+
+ /* This block is copied from ncmpi_switch_to_buffer. */
+ if ( YY_CURRENT_BUFFER )
+ {
+ /* Flush out information for old buffer. */
+ *(yy_c_buf_p) = (yy_hold_char);
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+ }
+
+ /* Only push if top exists. Otherwise, replace top. */
+ if (YY_CURRENT_BUFFER)
+ (yy_buffer_stack_top)++;
+ YY_CURRENT_BUFFER_LVALUE = new_buffer;
+
+ /* copied from ncmpi_switch_to_buffer. */
+ ncmpi_load_buffer_state( );
+ (yy_did_buffer_switch_on_eof) = 1;
+}
+
+/** Removes and deletes the top of the stack, if present.
+ * The next element becomes the new top.
+ *
+ */
+void ncmpipop_buffer_state (void)
+{
+ if (!YY_CURRENT_BUFFER)
+ return;
+
+ ncmpi_delete_buffer(YY_CURRENT_BUFFER );
+ YY_CURRENT_BUFFER_LVALUE = NULL;
+ if ((yy_buffer_stack_top) > 0)
+ --(yy_buffer_stack_top);
+
+ if (YY_CURRENT_BUFFER) {
+ ncmpi_load_buffer_state( );
+ (yy_did_buffer_switch_on_eof) = 1;
+ }
+}
+
+/* Allocates the stack if it does not exist.
+ * Guarantees space for at least one push.
+ */
+static void ncmpiensure_buffer_stack (void)
+{
+ int num_to_alloc;
+
+ if (!(yy_buffer_stack)) {
+
+ /* First allocation is just for 2 elements, since we don't know if this
+ * scanner will even need a stack. We use 2 instead of 1 to avoid an
+ * immediate realloc on the next call.
+ */
+ num_to_alloc = 1;
+ (yy_buffer_stack) = (struct yy_buffer_state**)ncmpialloc
+ (num_to_alloc * sizeof(struct yy_buffer_state*)
+ );
+ if ( ! (yy_buffer_stack) )
+ YY_FATAL_ERROR( "out of dynamic memory in ncmpiensure_buffer_stack()" );
+
+ memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*));
+
+ (yy_buffer_stack_max) = num_to_alloc;
+ (yy_buffer_stack_top) = 0;
+ return;
+ }
+
+ if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){
+
+ /* Increase the buffer to prepare for a possible push. */
+ int grow_size = 8 /* arbitrary grow size */;
+
+ num_to_alloc = (yy_buffer_stack_max) + grow_size;
+ (yy_buffer_stack) = (struct yy_buffer_state**)ncmpirealloc
+ ((yy_buffer_stack),
+ num_to_alloc * sizeof(struct yy_buffer_state*)
+ );
+ if ( ! (yy_buffer_stack) )
+ YY_FATAL_ERROR( "out of dynamic memory in ncmpiensure_buffer_stack()" );
+
+ /* zero only the new slots.*/
+ memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*));
+ (yy_buffer_stack_max) = num_to_alloc;
+ }
+}
+
+/** Setup the input buffer state to scan directly from a user-specified character buffer.
+ * @param base the character buffer
+ * @param size the size in bytes of the character buffer
+ *
+ * @return the newly allocated buffer state object.
+ */
+YY_BUFFER_STATE ncmpi_scan_buffer (char * base, yy_size_t size )
+{
+ YY_BUFFER_STATE b;
+
+ if ( size < 2 ||
+ base[size-2] != YY_END_OF_BUFFER_CHAR ||
+ base[size-1] != YY_END_OF_BUFFER_CHAR )
+ /* They forgot to leave room for the EOB's. */
+ return 0;
+
+ b = (YY_BUFFER_STATE) ncmpialloc(sizeof( struct yy_buffer_state ) );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in ncmpi_scan_buffer()" );
+
+ b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */
+ b->yy_buf_pos = b->yy_ch_buf = base;
+ b->yy_is_our_buffer = 0;
+ b->yy_input_file = 0;
+ b->yy_n_chars = b->yy_buf_size;
+ b->yy_is_interactive = 0;
+ b->yy_at_bol = 1;
+ b->yy_fill_buffer = 0;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ ncmpi_switch_to_buffer(b );
+
+ return b;
+}
+
+/** Setup the input buffer state to scan a string. The next call to ncmpilex() will
+ * scan from a @e copy of @a str.
+ * @param yystr a NUL-terminated string to scan
+ *
+ * @return the newly allocated buffer state object.
+ * @note If you want to scan bytes that may contain NUL values, then use
+ * ncmpi_scan_bytes() instead.
+ */
+YY_BUFFER_STATE ncmpi_scan_string (yyconst char * yystr )
+{
+
+ return ncmpi_scan_bytes(yystr,strlen(yystr) );
+}
+
+/** Setup the input buffer state to scan the given bytes. The next call to ncmpilex() will
+ * scan from a @e copy of @a bytes.
+ * @param bytes the byte buffer to scan
+ * @param len the number of bytes in the buffer pointed to by @a bytes.
+ *
+ * @return the newly allocated buffer state object.
+ */
+YY_BUFFER_STATE ncmpi_scan_bytes (yyconst char * yybytes, int _yybytes_len )
+{
+ YY_BUFFER_STATE b;
+ char *buf;
+ yy_size_t n;
+ int i;
+
+ /* Get memory for full buffer, including space for trailing EOB's. */
+ n = _yybytes_len + 2;
+ buf = (char *) ncmpialloc(n );
+ if ( ! buf )
+ YY_FATAL_ERROR( "out of dynamic memory in ncmpi_scan_bytes()" );
+
+ for ( i = 0; i < _yybytes_len; ++i )
+ buf[i] = yybytes[i];
+
+ buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
+
+ b = ncmpi_scan_buffer(buf,n );
+ if ( ! b )
+ YY_FATAL_ERROR( "bad buffer in ncmpi_scan_bytes()" );
+
+ /* It's okay to grow etc. this buffer, and we should throw it
+ * away when we're done.
+ */
+ b->yy_is_our_buffer = 1;
+
+ return b;
+}
+
+#ifndef YY_EXIT_FAILURE
+#define YY_EXIT_FAILURE 2
+#endif
+
+static void yy_fatal_error (yyconst char* msg )
+{
+ (void) fprintf( stderr, "%s\n", msg );
+ exit( YY_EXIT_FAILURE );
+}
+
+/* Redefine yyless() so it works in section 3 code. */
+
+#undef yyless
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up ncmpitext. */ \
+ int yyless_macro_arg = (n); \
+ YY_LESS_LINENO(yyless_macro_arg);\
+ ncmpitext[ncmpileng] = (yy_hold_char); \
+ (yy_c_buf_p) = ncmpitext + yyless_macro_arg; \
+ (yy_hold_char) = *(yy_c_buf_p); \
+ *(yy_c_buf_p) = '\0'; \
+ ncmpileng = yyless_macro_arg; \
+ } \
+ while ( 0 )
+
+/* Accessor methods (get/set functions) to struct members. */
+
+/** Get the current line number.
+ *
+ */
+int ncmpiget_lineno (void)
+{
+
+ return ncmpilineno;
+}
+
+/** Get the input stream.
+ *
+ */
+FILE *ncmpiget_in (void)
+{
+ return ncmpiin;
+}
+
+/** Get the output stream.
+ *
+ */
+FILE *ncmpiget_out (void)
+{
+ return ncmpiout;
+}
+
+/** Get the length of the current token.
+ *
+ */
+int ncmpiget_leng (void)
+{
+ return ncmpileng;
+}
+
+/** Get the current token.
+ *
+ */
+
+char *ncmpiget_text (void)
+{
+ return ncmpitext;
+}
+
+/** Set the current line number.
+ * @param line_number
+ *
+ */
+void ncmpiset_lineno (int line_number )
+{
+
+ ncmpilineno = line_number;
+}
+
+/** Set the input stream. This does not discard the current
+ * input buffer.
+ * @param in_str A readable stream.
+ *
+ * @see ncmpi_switch_to_buffer
+ */
+void ncmpiset_in (FILE * in_str )
+{
+ ncmpiin = in_str ;
+}
+
+void ncmpiset_out (FILE * out_str )
+{
+ ncmpiout = out_str ;
+}
+
+int ncmpiget_debug (void)
+{
+ return ncmpi_flex_debug;
+}
+
+void ncmpiset_debug (int bdebug )
+{
+ ncmpi_flex_debug = bdebug ;
+}
+
+static int yy_init_globals (void)
+{
+ /* Initialization is the same as for the non-reentrant scanner.
+ * This function is called from ncmpilex_destroy(), so don't allocate here.
+ */
+
+ (yy_buffer_stack) = 0;
+ (yy_buffer_stack_top) = 0;
+ (yy_buffer_stack_max) = 0;
+ (yy_c_buf_p) = (char *) 0;
+ (yy_init) = 0;
+ (yy_start) = 0;
+
+/* Defined in main.c */
+#ifdef YY_STDINIT
+ ncmpiin = stdin;
+ ncmpiout = stdout;
+#else
+ ncmpiin = (FILE *) 0;
+ ncmpiout = (FILE *) 0;
+#endif
+
+ /* For future reference: Set errno on error, since we are called by
+ * ncmpilex_init()
+ */
+ return 0;
+}
+
+/* ncmpilex_destroy is for both reentrant and non-reentrant scanners. */
+int ncmpilex_destroy (void)
+{
+
+ /* Pop the buffer stack, destroying each element. */
+ while(YY_CURRENT_BUFFER){
+ ncmpi_delete_buffer(YY_CURRENT_BUFFER );
+ YY_CURRENT_BUFFER_LVALUE = NULL;
+ ncmpipop_buffer_state();
+ }
+
+ /* Destroy the stack itself. */
+ ncmpifree((yy_buffer_stack) );
+ (yy_buffer_stack) = NULL;
+
+ /* Reset the globals. This is important in a non-reentrant scanner so the next time
+ * ncmpilex() is called, initialization will occur. */
+ yy_init_globals( );
+
+ return 0;
+}
+
+/*
+ * Internal utility routines.
+ */
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char* s1, yyconst char * s2, int n )
+{
+ register int i;
+ for ( i = 0; i < n; ++i )
+ s1[i] = s2[i];
+}
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (yyconst char * s )
+{
+ register int n;
+ for ( n = 0; s[n]; ++n )
+ ;
+
+ return n;
+}
+#endif
+
+void *ncmpialloc (yy_size_t size )
+{
+ return (void *) malloc( size );
+}
+
+void *ncmpirealloc (void * ptr, yy_size_t size )
+{
+ /* The cast to (char *) in the following accommodates both
+ * implementations that use char* generic pointers, and those
+ * that use void* generic pointers. It works with the latter
+ * because both ANSI C and C++ allow castless assignment from
+ * any pointer type to void*, and deal with argument conversions
+ * as though doing an assignment.
+ */
+ return (void *) realloc( (char *) ptr, size );
+}
+
+void ncmpifree (void * ptr )
+{
+ free( (char *) ptr ); /* see ncmpirealloc() for (char *) cast */
+}
+
+#define YYTABLES_NAME "yytables"
+
+#line 217 "./ncmpigen.l"
diff --git a/src/utils/ncmpivalid/Makefile.in b/src/utils/ncmpivalid/Makefile.in
new file mode 100644
index 0000000..cc21cd2
--- /dev/null
+++ b/src/utils/ncmpivalid/Makefile.in
@@ -0,0 +1,65 @@
+#
+# Copyright (C) 2012, Northwestern University and Argonne National Laboratory
+# See COPYRIGHT notice in top-level directory.
+#
+# $Id: Makefile.in 2103 2015-09-18 23:34:03Z wkliao $
+#
+# @configure_input@
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+include ../../../macros.make
+
+# For VPATH build:
+# Add ../../lib into search path because ../../lib/pnetcdf.h is created at the
+# configure time and included by ncmpivalid.c
+# Add $(srcdir)/../../lib into search path because $(srcdir)/../../lib/ncx.h
+# and $(srcdir)/../../lib/macro.h are included by ncmpivalid.c
+INCLUDES = -I../../lib -I$(srcdir)/../../lib
+
+LDFLAGS += -L../../lib
+LIBS := -lpnetcdf $(LIBS) @LCOV_LIB@
+
+C_SOURCES = ncmpivalid.c
+HEADERS =
+
+OBJS = $(C_SOURCES:.c=.o)
+
+PROGRAM = ncmpivalid
+MANUAL = ncmpivalid.1
+
+PACKING_LIST = $(C_SOURCES) $(HEADERS) $(MANUAL) \
+ Makefile.in depend
+
+GARBAGE = $(PROGRAM)
+
+all: $(PROGRAM)
+
+$(PROGRAM): $(LIBRARY) $(OBJS)
+ $(LINK.c) $(OBJS) $(LDFLAGS) $(LIBS)
+
+install: $(PROGRAM) $(MANUAL)
+ $(INSTALL) -d -m 755 $(MANDIR)/man1
+ $(INSTALL_DATA) $(srcdir)/$(MANUAL) $(MANDIR)/man1/$(MANUAL)
+
+ $(INSTALL) -d $(BINDIR)
+ $(INSTALL) -m 755 $(PROGRAM) $(BINDIR)/$(PROGRAM)
+
+uninstall:
+ $(RM) -f $(BINDIR)/$(PROGRAM)
+ $(RM) -f $(MANDIR)/man1/$(MANUAL)
+
+$(PROGRAM)_oc : $(C_SOURCES)
+ #setopt primary_language C
+ #load -C $(CPPFLAGS) $(C_SOURCES)
+ #load -C $(LIBS)
+ #setopt program_name $(PROGRAM)
+
+TAGS: FORCE
+ etags `echo $(PACKING_LIST) | fmt -1 | $(EGREP) '\.c|\.h'
+
+include $(srcdir)/../../../rules.make
+include $(srcdir)/depend
+
+.PHONY: $(LIBRARY)
diff --git a/src/utils/ncmpivalid/depend b/src/utils/ncmpivalid/depend
new file mode 100644
index 0000000..5a9acdb
--- /dev/null
+++ b/src/utils/ncmpivalid/depend
@@ -0,0 +1 @@
+ncmpivalid.o: ncmpivalid.c ../../lib/ncx.h ../../lib/macro.h
diff --git a/src/utils/ncmpivalid/ncmpivalid.1 b/src/utils/ncmpivalid/ncmpivalid.1
new file mode 100644
index 0000000..9b2dba7
--- /dev/null
+++ b/src/utils/ncmpivalid/ncmpivalid.1
@@ -0,0 +1,28 @@
+.\" $Header$
+.nr yr \n(yr+1900
+.af mo 01
+.af dy 01
+.TH NCMPIVALID 1 2013-11-17 "Printed: \n(yr-\n(mo-\n(dy" "UTILITIES"
+.SH NAME
+ncmpivalid \- validates a netCDF file in parallel
+.SH SYNOPSIS
+.ft B
+.HP
+mpiexec -n 4 ncmpivalid
+.nh
+\%\fIfile\fP
+.hy
+.ft
+.SH DESCRIPTION
+\fBncmpivalid\fP checks a netCDF file whether it conforms
+the CDF file format.
+
+.SH "SEE ALSO"
+.LP
+.BR ncmpidump (1),
+.BR pnetcdf (3)
+.SH DATE
+$Date: 2013-11-17 00:21:28 -0600 (Sun, 17 Nov 2013) $
+.LP
+
+
diff --git a/src/utils/ncmpivalid/ncmpivalid.c b/src/utils/ncmpivalid/ncmpivalid.c
new file mode 100644
index 0000000..9fbbf4a
--- /dev/null
+++ b/src/utils/ncmpivalid/ncmpivalid.c
@@ -0,0 +1,870 @@
+/*
+ * Copyright (C) 2003, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ */
+/* $Id: ncmpivalid.c 2299 2016-01-09 06:14:37Z wkliao $ */
+
+#if HAVE_CONFIG_H
+# include <ncconfig.h>
+#endif
+
+#include <assert.h>
+#include <sys/types.h> /* open() */
+#include <sys/stat.h> /* open() */
+#include <fcntl.h> /* open() */
+#include <unistd.h> /* read() */
+#include <string.h>
+#include <stdio.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
+#include <mpi.h>
+
+#include <ncx.h>
+#include <macro.h>
+
+/*
+ * "magic number" at beginning of file: 0x43444601 (big endian)
+ */
+static const schar ncmagic[] = {'C', 'D', 'F', 0x01};
+
+/* Prototypes for functions used only in this file */
+static int val_get_NCtype(bufferinfo *gbp, NCtype *typep);
+static int val_get_size_t(bufferinfo *gbp, MPI_Offset *sp);
+static int val_get_NC_string(bufferinfo *gbp, NC_string **ncstrpp);
+static int val_get_NC_dim(bufferinfo *gbp, NC_dim **dimpp);
+static int val_get_NC_dimarray(bufferinfo *gbp, NC_dimarray *ncap);
+static int val_get_nc_type(bufferinfo *gbp, nc_type *typep);
+static int val_get_NC_attrV(bufferinfo *gbp, NC_attr *attrp);
+static int val_get_NC_attr(bufferinfo *gbp, NC_attr **attrpp);
+static int val_get_NC_attrarray(bufferinfo *gbp, NC_attrarray *ncap);
+static int val_get_NC_var(bufferinfo *gbp, NC_var **varpp);
+static int val_get_NC_vararray(bufferinfo *gbp, NC_vararray *ncap);
+static int val_get_NC(NC *ncp);
+
+static int val_fetch(bufferinfo *gbp, MPI_Offset fsize);
+static int val_check_buffer(bufferinfo *gbp, MPI_Offset nextread);
+
+
+#define ABORT {printf("Abort: at line=%d func=%s\n", __LINE__,__func__); fflush(stdout); MPI_Abort(MPI_COMM_WORLD, -1);}
+
+/* Begin Of get NC */
+
+/*
+ * Fetch the next header chunk.
+ */
+static int
+val_fetch(bufferinfo *gbp, MPI_Offset fsize) {
+ ssize_t nn = 0;
+ MPI_Offset slack; /* any leftover data in the buffer */
+ MPI_Aint pos_addr, base_addr;
+
+ assert(gbp->base != NULL);
+
+#ifdef HAVE_MPI_GET_ADDRESS
+ MPI_Get_address(gbp->pos, &pos_addr);
+ MPI_Get_address(gbp->base, &base_addr);
+#else
+ MPI_Address(gbp->pos, &pos_addr);
+ MPI_Address(gbp->base, &base_addr);
+#endif
+ slack = gbp->size - (pos_addr - base_addr);
+ /* . if gbp->pos and gbp->base are the same, there is no leftover buffer data
+ * to worry about.
+ * In the other extreme, where gbp->size == (gbp->pos - gbp->base), then all
+ * data in the buffer has been consumed */
+ if (slack == gbp->size) slack = 0;
+
+ memset(gbp->base, 0, gbp->size);
+ gbp->pos = gbp->base;
+ gbp->index = 0;
+
+ lseek(gbp->nciop->fd, gbp->offset-slack, SEEK_SET);
+ nn = read(gbp->nciop->fd, gbp->base, gbp->size);
+ if (nn < gbp->size) {
+ printf("Error: Unexpected EOF ");
+ return -1;
+ }
+ gbp->offset += (gbp->size - slack);
+
+ return NC_NOERR;
+}
+
+/*
+ * Ensure that 'nextread' bytes are available.
+ */
+static int
+val_check_buffer(bufferinfo *gbp,
+ MPI_Offset nextread)
+{
+ MPI_Aint pos_addr, base_addr;
+
+#ifdef HAVE_MPI_GET_ADDRESS
+ MPI_Get_address(gbp->pos, &pos_addr);
+ MPI_Get_address(gbp->base, &base_addr);
+#else
+ MPI_Address(gbp->pos, &pos_addr);
+ MPI_Address(gbp->base, &base_addr);
+#endif
+ if (pos_addr + nextread <= base_addr + gbp->size)
+ return NC_NOERR;
+
+ return val_fetch(gbp, MIN(gbp->size, nextread));
+}
+
+static int
+val_get_NCtype(bufferinfo *gbp, NCtype *typep) {
+ unsigned int type = 0;
+ int status = val_check_buffer(gbp, X_SIZEOF_INT);
+ if (status != NC_NOERR) {
+ printf("NC component type is expected for ");
+ return status;
+ }
+
+ status = ncmpix_get_uint32((const void**)(&gbp->pos), &type);
+ if (status != NC_NOERR)
+ return status;
+ *typep = (NCtype) type;
+ return NC_NOERR;
+}
+
+static int
+val_get_size_t(bufferinfo *gbp, MPI_Offset *sp) {
+ int sizeof_t = (gbp->version == 5) ? 8 : 4;
+ int status = val_check_buffer(gbp, sizeof_t);
+ if (status != NC_NOERR) {
+ printf("size is expected for ");
+ return status;
+ }
+ if (gbp->version == 5) {
+ unsigned long long tmp=0;
+ status = ncmpix_get_uint64((const void **)(&gbp->pos), &tmp);
+ *sp = (MPI_Offset)tmp;
+ }
+ else {
+ unsigned int tmp=0;
+ status = ncmpix_get_uint32((const void **)(&gbp->pos), &tmp);
+ *sp = (MPI_Offset)tmp;
+ }
+ return status;
+}
+
+static int
+val_get_NC_string(bufferinfo *gbp, NC_string **ncstrpp) {
+ int status;
+ MPI_Offset nchars = 0, padding, bufremain, strcount;
+ NC_string *ncstrp;
+ char *cpos, pad[X_ALIGN-1];
+ MPI_Aint pos_addr, base_addr;
+
+ status = val_get_size_t(gbp, &nchars);
+ if (status != NC_NOERR) {
+ printf("the name string of ");
+ return status;
+ }
+
+ ncstrp = ncmpii_new_NC_string(nchars, NULL);
+ if (ncstrp == NULL)
+ return NC_ENOMEM;
+
+ padding = _RNDUP(X_SIZEOF_CHAR * ncstrp->nchars, X_ALIGN)
+ - X_SIZEOF_CHAR * ncstrp->nchars;
+#ifdef HAVE_MPI_GET_ADDRESS
+ MPI_Get_address(gbp->pos, &pos_addr);
+ MPI_Get_address(gbp->base, &base_addr);
+#else
+ MPI_Address(gbp->pos, &pos_addr);
+ MPI_Address(gbp->base, &base_addr);
+#endif
+ bufremain = gbp->size - (pos_addr - base_addr);
+ cpos = ncstrp->cp;
+
+ while (nchars > 0) {
+ if (bufremain > 0) {
+ strcount = MIN(bufremain, X_SIZEOF_CHAR * nchars);
+ (void) memcpy(cpos, gbp->pos, strcount);
+ nchars -= strcount/X_SIZEOF_CHAR;
+ gbp->pos = (void *)((char *)gbp->pos + strcount);
+ cpos += strcount;
+ bufremain -= strcount;
+ } else {
+ status = val_fetch(gbp, MIN(gbp->size, X_SIZEOF_CHAR * nchars));
+ if(status != NC_NOERR) {
+ printf("fetching the name string of ");
+ ncmpii_free_NC_string(ncstrp);
+ return status;
+ }
+ bufremain = gbp->size;
+ }
+ }
+
+ memset(pad, 0, X_ALIGN-1);
+ status = val_check_buffer(gbp, padding);
+ if(status != NC_NOERR) {
+ printf("fetching padding for the name string of ");
+ ncmpii_free_NC_string(ncstrp);
+ return status;
+ }
+ if (memcmp(gbp->pos, pad, padding) != 0) {
+ printf("Error @ [0x%8.8Lx]: \n\tPadding should be 0x00 for the name string alignment of ", (long long unsigned)
+ (((size_t) gbp->pos - (size_t) gbp->base) + gbp->offset - gbp->size));
+ ncmpii_free_NC_string(ncstrp);
+ return NC_EINVAL;
+ }
+ gbp->pos = (void *)((char *)gbp->pos + padding);
+
+ *ncstrpp = ncstrp;
+
+ return NC_NOERR;
+}
+
+static int
+val_get_NC_dim(bufferinfo *gbp, NC_dim **dimpp) {
+ int status;
+ NC_string *ncstrp;
+ NC_dim *dimp;
+
+ status = val_get_NC_string(gbp, &ncstrp);
+ if (status != NC_NOERR)
+ return status;
+
+ dimp = ncmpii_new_x_NC_dim(ncstrp);
+ if(dimp == NULL)
+ return NC_ENOMEM;
+
+ status = val_get_size_t(gbp, &dimp->size);
+ if(status != NC_NOERR) {
+ printf("\"%s\" - ", ncstrp->cp);
+ ncmpii_free_NC_dim(dimp); /* frees name */
+ return status;
+ }
+
+ *dimpp = dimp;
+
+ return NC_NOERR;
+}
+
+static int
+val_get_NC_dimarray(bufferinfo *gbp, NC_dimarray *ncap) {
+ int status;
+ NCtype type = NC_UNSPECIFIED;
+ NC_dim **dpp, **end;
+ int dim;
+ MPI_Offset tmp;
+
+ assert(gbp != NULL && gbp->pos != NULL);
+ assert(ncap != NULL);
+ assert(ncap->value == NULL);
+
+ status = val_get_NCtype(gbp, &type);
+ if(status != NC_NOERR) {
+ printf("preamble of ");
+ return status;
+ }
+
+ status = val_get_size_t(gbp, &tmp);
+ if(status != NC_NOERR) {
+ printf("the length of ");
+ return status;
+ }
+ ncap->ndefined = tmp; /* number of allowable defined variables < 2^32 */
+
+ if(ncap->ndefined == 0) {
+ if (type != NC_DIMENSION && type != NC_UNSPECIFIED) {
+ printf("Error @ [0x%8.8Lx]: \n\tInvalid NC component type, while ",
+ (long long unsigned) (((size_t) gbp->pos - (size_t) gbp->base) + gbp->offset - gbp->size - 2 * X_SIZEOF_SIZE_T));
+ printf("NC_DIMENSION or NC_UNSPECIFIED is expected for ");
+ return NC_EINVAL;
+ }
+ } else {
+ if(type != NC_DIMENSION) {
+ printf("Error @ [0x%8.8Lx]: \n\tInvalid NC component type, while ",
+ (long long unsigned) (((size_t) gbp->pos - (size_t) gbp->base) + gbp->offset - gbp->size - 2 * X_SIZEOF_SIZE_T));
+ printf("NC_DIMENSION is expected since number of dimensions is %d for ", ncap->ndefined);
+ return NC_EINVAL;
+ }
+
+ ncap->value = (NC_dim **) NCI_Malloc(ncap->ndefined * sizeof(NC_dim *));
+ if(ncap->value == NULL)
+ return NC_ENOMEM;
+ ncap->nalloc = ncap->ndefined;
+
+ dpp = ncap->value;
+ end = &dpp[ncap->ndefined];
+ for( /*NADA*/ dim = 0; dpp < end; dpp++, dim++) {
+ status = val_get_NC_dim(gbp, dpp);
+ if (status != NC_NOERR) {
+ printf("dimension[%d] in ", dim);
+ ncap->ndefined = dpp - ncap->value;
+ ncmpii_free_NC_dimarray(ncap);
+ return status;
+ }
+ }
+ }
+
+ return NC_NOERR;
+}
+
+static int
+val_get_nc_type(bufferinfo *gbp, nc_type *typep) {
+ /* NCtype is 4-byte integer */
+ unsigned int type = 0;
+ int status = val_check_buffer(gbp, 4);
+ if (status != NC_NOERR) return status;
+
+ /* get a 4-byte integer */
+ status = ncmpix_get_uint32((const void**)(&gbp->pos), &type);
+ gbp->index += X_SIZEOF_INT;
+ if (status != NC_NOERR) return status;
+
+ if ( type != NC_BYTE
+ && type != NC_UBYTE
+ && type != NC_CHAR
+ && type != NC_SHORT
+ && type != NC_USHORT
+ && type != NC_INT
+ && type != NC_UINT
+ && type != NC_FLOAT
+ && type != NC_DOUBLE
+ && type != NC_INT64
+ && type != NC_UINT64) {
+ printf("Error @ [0x%8.8Lx]: \n\tUnknown data type for the values of ",
+ (long long unsigned) (((size_t) gbp->pos - (size_t) gbp->base) + gbp->offset - gbp->size - X_SIZEOF_INT));
+ return NC_EINVAL;
+ }
+
+ *typep = (nc_type) type;
+
+ return NC_NOERR;
+}
+
+/*
+ * Get the values of an attribute
+ */
+static int
+val_get_NC_attrV(bufferinfo *gbp, NC_attr *attrp) {
+ int status;
+ void *value = attrp->xvalue;
+ char pad[X_ALIGN-1];
+ MPI_Offset nvalues = attrp->nelems, esz, padding, bufremain, attcount;
+ MPI_Aint pos_addr, base_addr;
+
+ esz = ncmpix_len_nctype(attrp->type);
+ padding = attrp->xsz - esz * nvalues;
+#ifdef HAVE_MPI_GET_ADDRESS
+ MPI_Get_address(gbp->pos, &pos_addr);
+ MPI_Get_address(gbp->base, &base_addr);
+#else
+ MPI_Address(gbp->pos, &pos_addr);
+ MPI_Address(gbp->base, &base_addr);
+#endif
+ bufremain = gbp->size - (pos_addr - base_addr);
+
+ while (nvalues > 0) {
+ if (bufremain > 0) {
+ attcount = MIN(bufremain, esz * nvalues);
+ (void) memcpy(value, gbp->pos, attcount);
+ nvalues -= attcount/esz;
+ gbp->pos = (void *)((char *)gbp->pos + attcount);
+ value = (void *)((char *)value + attcount);
+ bufremain -= attcount;
+ } else {
+ status = val_fetch(gbp, MIN(gbp->size, esz * nvalues));
+ if(status != NC_NOERR) {
+ printf("fetching the values of ");
+ return status;
+ }
+ bufremain = gbp->size;
+ }
+ }
+
+ memset(pad, 0, X_ALIGN-1);
+ if (memcmp(gbp->pos, pad, padding) != 0) {
+ printf("Error @ [0x%8.8Lx]: \n\tPadding should be 0x00 for the values alignment of ",
+ (long long unsigned) (((size_t) gbp->pos - (size_t) gbp->base) + gbp->offset - gbp->size));
+ return NC_EINVAL;
+ }
+ gbp->pos = (void *)((char *)gbp->pos + padding);
+
+ return NC_NOERR;
+}
+
+static int
+val_get_NC_attr(bufferinfo *gbp, NC_attr **attrpp) {
+ NC_string *strp;
+ int status;
+ nc_type type;
+ MPI_Offset nelems;
+ NC_attr *attrp;
+
+ status = val_get_NC_string(gbp, &strp);
+ if(status != NC_NOERR)
+ return status;
+
+ status = val_get_nc_type(gbp, &type);
+ if(status != NC_NOERR) {
+ printf("\"%s\" - ", strp->cp);
+ ncmpii_free_NC_string(strp);
+ return status;
+ }
+
+ status = val_get_size_t(gbp, &nelems);
+ if(status != NC_NOERR) {
+ printf("the values of \"%s\" - ", strp->cp);
+ ncmpii_free_NC_string(strp);
+ return status;
+ }
+
+ attrp = ncmpii_new_x_NC_attr(strp, type, nelems);
+ if(attrp == NULL) {
+ ncmpii_free_NC_string(strp);
+ return status;
+ }
+
+ status = val_get_NC_attrV(gbp, attrp);
+ if(status != NC_NOERR) {
+ printf("\"%s\" - ", strp->cp);
+ ncmpii_free_NC_attr(attrp); /* frees strp */
+ return status;
+ }
+
+ *attrpp = attrp;
+
+ return NC_NOERR;
+}
+
+static int
+val_get_NC_attrarray(bufferinfo *gbp, NC_attrarray *ncap){
+ int status;
+ NCtype type = NC_UNSPECIFIED;
+ NC_attr **app, **end;
+ int att;
+ MPI_Offset tmp;
+
+ assert(gbp != NULL && gbp->pos != NULL);
+ assert(ncap != NULL);
+ assert(ncap->value == NULL);
+
+ status = val_get_NCtype(gbp, &type);
+ if(status != NC_NOERR) {
+ printf("preamble of ");
+ return status;
+ }
+
+ status = val_get_size_t(gbp, &tmp);
+ if(status != NC_NOERR) {
+ printf("the length of ");
+ return status;
+ }
+ ncap->ndefined = tmp; /* number of allowable defined variables < 2^32 */
+
+ if(ncap->ndefined == 0) {
+ if (type != NC_ATTRIBUTE && type != NC_UNSPECIFIED) {
+ printf("Error @ [0x%8.8Lx]: \n\tInvalid NC component type, while ",
+ (long long unsigned) (((size_t) gbp->pos - (size_t) gbp->base) + gbp->offset - gbp->size - 2 * X_SIZEOF_SIZE_T));
+ printf("NC_ATTRIBUTE or NC_UNSPECIFIED is expected for ");
+ return NC_EINVAL;
+ }
+ } else {
+ if(type != NC_ATTRIBUTE) {
+ printf("Error @ [0x%8.8Lx]: \n\tInvalid NC component type, while ",
+ (long long unsigned) (((size_t) gbp->pos - (size_t) gbp->base) + gbp->offset - gbp->size - 2 * X_SIZEOF_SIZE_T));
+ printf("NC_ATTRIBUTE is expected since number of attributes is %d for ", (int)ncap->ndefined);
+ return NC_EINVAL;
+ }
+
+ ncap->value = (NC_attr **) NCI_Malloc(ncap->ndefined * sizeof(NC_attr *));
+ if(ncap->value == NULL)
+ return NC_ENOMEM;
+ ncap->nalloc = ncap->ndefined;
+
+ app = ncap->value;
+ end = &app[ncap->ndefined];
+ for( /*NADA*/ att = 0; app < end; app++, att++) {
+ status = val_get_NC_attr(gbp, app);
+ if (status != NC_NOERR) {
+ printf("attribute[%d] of ", att);
+ ncap->ndefined = app - ncap->value;
+ ncmpii_free_NC_attrarray(ncap);
+ return status;
+ }
+ }
+ }
+
+ return NC_NOERR;
+}
+
+static int
+val_get_NC_var(bufferinfo *gbp, NC_var **varpp) {
+ NC_string *strp;
+ int status;
+ MPI_Offset ndims, *tmp_dim;
+ size_t dim;
+ NC_var *varp;
+
+ status = val_get_NC_string(gbp, &strp);
+ if(status != NC_NOERR)
+ return status;
+
+ status = val_get_size_t(gbp, &ndims);
+ if(status != NC_NOERR) {
+ printf("the dimid list of \"%s\" - ", strp->cp);
+ ncmpii_free_NC_string(strp);
+ return status;
+ }
+
+ varp = ncmpii_new_x_NC_var(strp, ndims);
+ if(varp == NULL) {
+ ncmpii_free_NC_string(strp);
+ return NC_ENOMEM;
+ }
+
+ for (dim = 0; dim < ndims; dim++ ) {
+ status = val_check_buffer(gbp, (gbp->version == 5 ? 8 : 4));
+ if(status != NC_NOERR) {
+ printf("the dimid[%d] is expected for \"%s\" - ", (int)dim, strp->cp);
+ ncmpii_free_NC_var(varp);
+ return status;
+ }
+ tmp_dim = (MPI_Offset*) (varp->dimids + dim);
+ if (gbp->version == 5) {
+ unsigned long long tmp=0;
+ status = ncmpix_get_uint64((const void **)(&gbp->pos), &tmp);
+ *tmp_dim = (MPI_Offset)tmp;
+ }
+ else {
+ unsigned int tmp=0;
+ status = ncmpix_get_uint32((const void **)(&gbp->pos), &tmp);
+ *tmp_dim = (MPI_Offset)tmp;
+ }
+ if(status != NC_NOERR) {
+ ncmpii_free_NC_var(varp);
+ return status;
+ }
+ }
+
+ status = val_get_NC_attrarray(gbp, &varp->attrs);
+ if(status != NC_NOERR) {
+ printf("ATTRIBUTE list of \"%s\" - ", strp->cp);
+ ncmpii_free_NC_var(varp);
+ return status;
+ }
+
+ status = val_get_nc_type(gbp, &varp->type);
+ if(status != NC_NOERR) {
+ printf("\"%s\" - ", strp->cp);
+ ncmpii_free_NC_var(varp);
+ return status;
+ }
+
+ status = val_get_size_t(gbp, &varp->len);
+ if(status != NC_NOERR) {
+ printf("the data of \"%s\" - ", strp->cp);
+ ncmpii_free_NC_var(varp);
+ return status;
+ }
+
+ status = val_check_buffer(gbp, (gbp->version == 5 ? 8 : 4));
+ if(status != NC_NOERR) {
+ printf("offset is expected for the data of \"%s\" - ", strp->cp);
+ ncmpii_free_NC_var(varp);
+ return status;
+ }
+ if (gbp->version == 1) {
+ unsigned int tmp=0;
+ status = ncmpix_get_uint32((const void **)(&gbp->pos), &tmp);
+ varp->begin = (MPI_Offset)tmp;
+ }
+ else {
+ unsigned long long tmp=0;
+ status = ncmpix_get_uint64((const void **)(&gbp->pos), &tmp);
+ varp->begin = (MPI_Offset)tmp;
+ }
+ if(status != NC_NOERR) {
+ ncmpii_free_NC_var(varp);
+ return status;
+ }
+
+ *varpp = varp;
+ return NC_NOERR;
+}
+
+static int
+val_get_NC_vararray(bufferinfo *gbp, NC_vararray *ncap) {
+ int status;
+ NCtype type = NC_UNSPECIFIED;
+ NC_var **vpp, **end;
+ int var;
+ MPI_Offset tmp;
+
+ assert(gbp != NULL && gbp->pos != NULL);
+ assert(ncap != NULL);
+ assert(ncap->value == NULL);
+
+ status = val_get_NCtype(gbp, &type);
+ if(status != NC_NOERR) {
+ printf("preamble of ");
+ return status;
+ }
+
+ status = val_get_size_t(gbp, &tmp);
+ if(status != NC_NOERR) {
+ printf("the length of ");
+ return status;
+ }
+ ncap->ndefined = tmp; /* number of allowable defined variables < 2^32 */
+
+ if(ncap->ndefined == 0) {
+ if (type != NC_VARIABLE && type != NC_UNSPECIFIED) {
+ printf("Error @ [0x%8.8Lx]: \n\tInvalid NC component type, while ",
+ (long long unsigned) (((size_t) gbp->pos - (size_t) gbp->base) + gbp->offset - gbp->size - 2 * X_SIZEOF_SIZE_T));
+ printf("NC_VARIABLE or NC_UNSPECIFIED is expected for ");
+ return NC_EINVAL;
+ }
+ } else {
+ if(type != NC_VARIABLE) {
+ printf("Error @ [0x%8.8Lx]: \n\tInvalid NC component type, while ",
+ (long long unsigned) (((size_t) gbp->pos - (size_t) gbp->base) + gbp->offset - gbp->size - 2 * X_SIZEOF_SIZE_T));
+ printf("NC_VARIABLE is expected since number of variables is %d for ", ncap->ndefined);
+ return NC_EINVAL;
+ }
+
+ ncap->value = (NC_var **) NCI_Malloc(ncap->ndefined * sizeof(NC_var *));
+ if(ncap->value == NULL)
+ return NC_ENOMEM;
+ ncap->nalloc = ncap->ndefined;
+
+ vpp = ncap->value;
+ end = &vpp[ncap->ndefined];
+ for( /*NADA*/ var = 0; vpp < end; vpp++, var++) {
+ status = val_get_NC_var(gbp, vpp);
+ if (status != NC_NOERR) {
+ printf("variable[%d] in ", var);
+ ncap->ndefined = vpp - ncap->value;
+ ncmpii_free_NC_vararray(ncap);
+ return status;
+ }
+ }
+ }
+
+ return NC_NOERR;
+}
+
+static int
+val_get_NC(NC *ncp) {
+ int status;
+ bufferinfo getbuf;
+ schar magic[sizeof(ncmagic)];
+ MPI_Offset nrecs = 0;
+ MPI_Aint pos_addr, base_addr;
+
+ assert(ncp != NULL);
+
+ /* Initialize the get buffer that stores the header read from the file */
+ getbuf.nciop = ncp->nciop;
+ getbuf.offset = 0; /* read from start of the file */
+ getbuf.put_size = 0; /* amount of writes so far in bytes */
+ getbuf.get_size = 0; /* amount of reads so far in bytes */
+
+ /* CDF-5's minimum header size is 4 bytes more than CDF-1 and CDF-2's */
+ getbuf.size = _RNDUP( MAX(MIN_NC_XSZ+4, ncp->chunk), X_ALIGN );
+ if (getbuf.size > NC_DEFAULT_CHUNKSIZE)
+ getbuf.size = NC_DEFAULT_CHUNKSIZE;
+
+ getbuf.pos = getbuf.base = (void *)NCI_Malloc(getbuf.size);
+ getbuf.index = 0;
+
+ /* Fetch the next header chunk. The chunk is 'gbp->size' bytes big */
+ status = val_fetch(&getbuf, sizeof(magic));
+ if (status != NC_NOERR) {
+ printf("magic number (C D F \\001) is expected!\n");
+ return status;
+ }
+
+ /* First get the file format information, magic */
+ memset(magic, 0, sizeof(magic));
+ status = ncmpix_getn_schar_schar((const void **)(&getbuf.pos),
+ sizeof(magic), magic);
+ getbuf.index += sizeof(magic);
+
+ if (memcmp(magic, ncmagic, sizeof(ncmagic)-1) != 0) {
+ printf("Error @ [0x%8.8x]: \n\tUnknow magic number, while (C D F \\001, \\002, or \\005) is expected!\n", (unsigned) 0);
+ NCI_Free(getbuf.base);
+ return NC_ENOTNC;
+ }
+
+ /* check version number in last byte of magic */
+ if (magic[sizeof(ncmagic)-1] == 0x1) {
+ getbuf.version = 1;
+ fSet(ncp->flags, NC_32BIT);
+ } else if (magic[sizeof(ncmagic)-1] == 0x2) {
+ getbuf.version = 2;
+ fSet(ncp->flags, NC_64BIT_OFFSET);
+ if (sizeof(MPI_Offset) != 8) {
+ /* take the easy way out: if we can't support all CDF-2
+ * files, return immediately */
+ NCI_Free(getbuf.base);
+ return NC_ESMALL;
+ }
+ } else if (magic[sizeof(ncmagic)-1] == 0x5) {
+ getbuf.version = 5;
+ fSet(ncp->flags, NC_64BIT_DATA);
+ if (sizeof(MPI_Offset) != 8) {
+ NCI_Free(getbuf.base);
+ return NC_ESMALL;
+ }
+ } else {
+ NCI_Free(getbuf.base);
+ return NC_ENOTNC;
+ }
+
+ /* status = val_check_buffer(&getbuf, X_SIZEOF_SIZE_T); */
+ status = val_check_buffer(&getbuf, (getbuf.version == 1) ? 4 : 8);
+ if (status != NC_NOERR) {
+ printf("number of records is expected!\n");
+ NCI_Free(getbuf.base);
+ return status;
+ }
+
+ /* get numrecs from getbuf into ncp */
+ if (getbuf.version == 5) {
+ unsigned long long tmp=0;
+ status = ncmpix_get_uint64((const void **)(&getbuf.pos), &tmp);
+ nrecs = (MPI_Offset)tmp;
+ }
+ else {
+ unsigned int tmp=0;
+ status = ncmpix_get_uint32((const void **)(&getbuf.pos), &tmp);
+ nrecs = (MPI_Offset)tmp;
+ }
+ if (status != NC_NOERR) {
+ NCI_Free(getbuf.base);
+ return status;
+ }
+
+ if (getbuf.version == 5)
+ getbuf.index += X_SIZEOF_INT64;
+ else
+ getbuf.index += X_SIZEOF_SIZE_T;
+
+ ncp->numrecs = nrecs;
+
+#ifdef HAVE_MPI_GET_ADDRESS
+ MPI_Get_address(getbuf.pos, &pos_addr);
+ MPI_Get_address(getbuf.base, &base_addr);
+#else
+ MPI_Address(getbuf.pos, &pos_addr);
+ MPI_Address(getbuf.base, &base_addr);
+#endif
+ assert(pos_addr < base_addr + getbuf.size);
+
+ /* get dim_list from getbuf into ncp */
+ status = val_get_NC_dimarray(&getbuf, &ncp->dims);
+ if (status != NC_NOERR) {
+ printf("DIMENSION list!\n");
+ NCI_Free(getbuf.base);
+ return status;
+ }
+
+ status = val_get_NC_attrarray(&getbuf, &ncp->attrs);
+ if (status != NC_NOERR) {
+ printf("GLOBAL ATTRIBUTE list!\n");
+ NCI_Free(getbuf.base);
+ return status;
+ }
+
+ status = val_get_NC_vararray(&getbuf, &ncp->vars);
+ if(status != NC_NOERR) {
+ printf("VARIABLE list!\n");
+ NCI_Free(getbuf.base);
+ return status;
+ }
+
+ ncp->xsz = ncmpii_hdr_len_NC(ncp);
+ status = ncmpii_NC_computeshapes(ncp);
+ NCI_Free(getbuf.base);
+
+ return status;
+}
+
+/* End Of get NC */
+
+int main(int argc, char **argv) {
+
+ char *ncfile;
+ int status;
+ NC *ncp;
+ struct stat ncfilestat;
+
+ MPI_Init(&argc, &argv);
+
+ if (argc != 2) {
+ printf("Usage: %s <ncfile>\n", argv[0]);
+ MPI_Finalize();
+ return 1;
+ }
+
+ ncfile = argv[1];
+
+ /* open the netCDF file */
+ ncp = ncmpii_new_NC(NULL);
+ if (ncp == NULL) {
+ printf("ncmpii_new_NC(): Not enough memory!\n");
+ ABORT
+ }
+
+ ncp->nciop = ncmpiio_new(ncfile, NC_NOWRITE);
+ if (ncp->nciop == NULL) {
+ ncmpii_free_NC(ncp);
+ printf("ncmpiio_new(): Not enough memory!\n");
+ ABORT
+ }
+
+ if ( (*((int *)&ncp->nciop->fd) = open(ncfile, O_RDONLY)) < 0 ) {
+ printf("Can not open file: %s\n", ncfile);
+ ncmpiio_free(ncp->nciop);
+ ncmpii_free_NC(ncp);
+ ABORT
+ }
+
+ /* read to validate the header */
+ status = val_get_NC(ncp);
+ if (status != NC_NOERR) {
+ printf("Error at line %d (%s)\n",__LINE__,ncmpi_strerror(status));
+ close(ncp->nciop->fd);
+ ncmpiio_free(ncp->nciop);
+ ncmpii_free_NC(ncp);
+ ABORT
+ }
+
+ /* check data size */
+ fstat(ncp->nciop->fd, &ncfilestat);
+ if ( ncp->begin_rec + ncp->recsize * ncp->numrecs < ncfilestat.st_size ) {
+ printf("Error: \n\tData size is larger than defined!\n");
+ close(ncp->nciop->fd);
+ ncmpiio_free(ncp->nciop);
+ ncmpii_free_NC(ncp);
+ return 0;
+ } else if ( ncp->numrecs > 0 &&
+ ncp->begin_rec + ncp->recsize * (ncp->numrecs - 1) > ncfilestat.st_size ) {
+ printf("Error: \n\tData size is less than expected!\n");
+ printf("\tbegin_rec=%lld recsize=%lld numrecs=%lld ncfilestat.st_size=%lld\n",ncp->begin_rec, ncp->recsize, ncp->numrecs, (long long) ncfilestat.st_size);
+ close(ncp->nciop->fd);
+ ncmpiio_free(ncp->nciop);
+ ncmpii_free_NC(ncp);
+ return 0;
+ }
+
+
+ /* close the file */
+
+ close(ncp->nciop->fd);
+ ncmpiio_free(ncp->nciop);
+ ncmpii_free_NC(ncp);
+
+ printf("The netCDF file is validated!\n");
+
+ MPI_Finalize();
+ return 0;
+}
diff --git a/src/utils/ncoffsets/Makefile.in b/src/utils/ncoffsets/Makefile.in
new file mode 100644
index 0000000..7d77a0b
--- /dev/null
+++ b/src/utils/ncoffsets/Makefile.in
@@ -0,0 +1,38 @@
+#
+# Copyright (C) 2015, Northwestern University and Argonne National Laboratory
+# See COPYRIGHT notice in top-level directory.
+#
+# $Id: Makefile.in 2253 2015-12-22 01:45:40Z wkliao $
+#
+# @configure_input@
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+include ../../../macros.make
+
+C_SOURCES = ncoffsets.c
+OBJS = $(C_SOURCES:.c=.o)
+
+PROGRAM = $(C_SOURCES:.c=)
+MANUAL = ncoffsets.1
+PACKING_LIST = $(C_SOURCES) $(MANUAL) Makefile.in
+GARBAGE = $(PROGRAM)
+
+all: $(PROGRAM)
+
+ncoffsets: ncoffsets.c
+ $(SEQ_CC) -o $@ $<
+
+install: $(PROGRAM) $(MANUAL)
+ $(INSTALL) -d -m 755 $(MANDIR)/man1
+ $(INSTALL_DATA) $(srcdir)/$(MANUAL) $(MANDIR)/man1/$(MANUAL)
+ $(INSTALL) -d $(BINDIR)
+ $(INSTALL) -m 755 $(PROGRAM) $(BINDIR)/$(PROGRAM)
+
+uninstall:
+ $(RM) -f $(BINDIR)/$(PROGRAM)
+ $(RM) -f $(MANDIR)/man1/$(MANUAL)
+
+include $(srcdir)/../../../rules.make
+
diff --git a/src/utils/ncoffsets/ncoffsets.1 b/src/utils/ncoffsets/ncoffsets.1
new file mode 100644
index 0000000..0191668
--- /dev/null
+++ b/src/utils/ncoffsets/ncoffsets.1
@@ -0,0 +1,109 @@
+.\" $Header$
+.nr yr \n(yr+1900
+.af mo 01
+.af dy 01
+.TH PNETCDF_VERSION 1 2014-04-15 "Printed: \n(yr-\n(mo-\n(dy" "UTILITIES"
+.SH NAME
+ncoffsets \- print the starting/ending file offsets for netCDF variables
+.SH SYNOPSIS
+.ft B
+.HP
+ncoffsets
+.nh
+\%[\fB-h\fP] |
+\%[\fB-x\fP] |
+\%[\fB-sgr\fP]
+\%[\fB-v\fP var1[,...]]
+\%\fIfile\fP
+.hy
+.ft
+.SH DESCRIPTION
+\fBncoffsets\fP prints the file offsets information of variables defined in
+a given netCDF file. The ending offsets reported is an exclusive offset, i.e.
+1 byte more than the last byte occupied by the variable. In other words, the
+ending offset is equal to the sum of starting offset and the variable size.
+For record variables, only the offsets of first record are printed. Add
+option \fB-r\fP to print the offsets of all records.
+
+If no argument is given, command usage information is printed.
+.SH OPTIONS
+.IP "\fB-v\fP var1[,...]"
+The output will include data values for the specified variables. One or more
+variables must be specified by name in the comma-delimited list following this
+option. The list must be a single argument to the command, hence cannot
+contain blanks or other white space characters. The named variables must be
+valid netCDF variables in the input-file. The default, without this option is
+to include data values for \fIall\fP variables in the output.
+.IP "\fB-s\fP"
+Print the variable size in bytes. For record variables, only the size of one
+record is printed.
+.IP "\fB-g\fP"
+Print the gap in bytes from the previous variable. For the first defined
+variable, print the gap from the end of file header. For record variables,
+there is no gap between records.
+.IP "\fB-r\fP"
+Output the offset information for all records of the selected record variables.
+Without this option, only the offsets of first record are printed.
+.IP "\fB-x\fP"
+Check all fixed-size variable for file space gaps in between any two
+immediately adjacent variables. It prints "1" on stdout if gaps are found,
+"0" for otherwise. This option disables all other options.
+.IP "\fB-h\fP"
+Print the available command-line options
+
+.SH EXAMPLES
+.LP
+Print the file offset information for all variables in a netCDF file.
+
+% ncoffsets -sg testfile.nc
+.nf
+netcdf test_double.nc {
+//file format: CDF-1
+
+file header:
+ size = 340 bytes
+ extent = 340 bytes
+
+dimensions:
+ x = 100
+ y = 100
+ z = 100
+ time = UNLIMITED // (100 currently)
+
+fixed-size variables:
+ double square(x, y):
+ start file offset = 340
+ end file offset = 80340
+ size in bytes = 80000
+ gap from prev var = 0
+ double cube(x, y, z):
+ start file offset = 80340
+ end file offset = 8080340
+ size in bytes = 8000000
+ gap from prev var = 0
+
+record variables:
+ double time(time):
+ start file offset = 8080340 (record 0)
+ end file offset = 8081140 (record 0)
+ size in bytes = 8 (of one record)
+ gap from prev var = 0
+ double xytime(time, x, y):
+ start file offset = 8080348 (record 0)
+ end file offset = 16080348 (record 0)
+ size in bytes = 80000 (of one record)
+ gap from prev var = 0
+}
+.LP
+Check if there are gaps in between two adjacent fixed-size variables.
+
+% ncoffsets -x testfile.nc
+0
+.fi
+
+.SH "SEE ALSO"
+.LP
+.BR pnetcdf (3)
+.SH DATE
+$Date: 2016-01-10 14:33:45 -0600 (Sun, 10 Jan 2016) $
+.LP
diff --git a/src/utils/ncoffsets/ncoffsets.c b/src/utils/ncoffsets/ncoffsets.c
new file mode 100644
index 0000000..3eb876b
--- /dev/null
+++ b/src/utils/ncoffsets/ncoffsets.c
@@ -0,0 +1,2099 @@
+/*
+ * Copyright (C) 2015, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ */
+/* $Id: ncoffsets.c 2302 2016-01-10 20:33:45Z wkliao $ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h> /* strcpy() */
+#include <errno.h> /* errno, strerror() */
+#include <sys/types.h> /* open() */
+#include <sys/stat.h> /* open() */
+#include <fcntl.h> /* open() */
+#include <unistd.h> /* read() */
+#include <assert.h> /* assert() */
+#include <inttypes.h> /* check for Endianness */
+
+static int endianness;
+
+#ifndef MIN
+#define MIN(mm,nn) (((mm) < (nn)) ? (mm) : (nn))
+#endif
+
+static int verbose_debug;
+
+#define DEBUG_RETURN_ERROR(err) { \
+ if (verbose_debug) \
+ fprintf(stderr, "Error code %s at line %d of %s\n", \
+ ncmpii_err_code_name(err),__LINE__,__FILE__); \
+ return err; \
+}
+#define DEBUG_ASSIGN_ERROR(status, err) { \
+ if (verbose_debug) \
+ fprintf(stderr, "Error code %s at line %d of %s\n", \
+ ncmpii_err_code_name(err),__LINE__,__FILE__); \
+ status = err; \
+}
+
+#define IS_RECVAR(vp) \
+ ((vp)->shape != NULL ? (*(vp)->shape == NC_UNLIMITED) : 0 )
+
+#define MALLOC_CHECK(ptr) { \
+ if ((ptr) == NULL) { \
+ fprintf(stderr, "Error at line %d: malloc out of memory",__LINE__); \
+ exit(1); \
+ } \
+}
+
+#define NC_NOERR 0
+#define NC_EINVAL (-36) /**< Invalid Argument */
+#define NC_EBADDIM (-46) /**< Invalid dimension id or name */
+#define NC_EUNLIMPOS (-47) /**< NC_UNLIMITED in the wrong index */
+#define NC_ENOTNC (-51) /**< Not a netcdf file */
+#define NC_EVARSIZE (-62) /**< One or more variable sizes violate format constraints */
+
+#define NC_UNLIMITED 0L
+
+typedef enum {
+ NC_UNSPECIFIED = 0,
+ NC_DIMENSION = 10,
+ NC_VARIABLE = 11,
+ NC_ATTRIBUTE = 12
+} NCtype;
+
+#define NC_NAT 0 /**< Not A Type */
+#define NC_BYTE 1 /**< signed 1 byte integer */
+#define NC_CHAR 2 /**< ISO/ASCII character */
+#define NC_SHORT 3 /**< signed 2 byte integer */
+#define NC_INT 4 /**< signed 4 byte integer */
+#define NC_LONG NC_INT
+#define NC_FLOAT 5 /**< single precision floating point number */
+#define NC_DOUBLE 6 /**< double precision floating point number */
+#define NC_UBYTE 7 /**< unsigned 1 byte int */
+#define NC_USHORT 8 /**< unsigned 2-byte int */
+#define NC_UINT 9 /**< unsigned 4-byte int */
+#define NC_INT64 10 /**< signed 8-byte int */
+#define NC_UINT64 11 /**< unsigned 8-byte int */
+
+#define NC_DEFAULT_CHUNKSIZE 1048576
+
+/* sizes of external data types */
+#define X_SIZEOF_CHAR 1
+#define X_SIZEOF_SHORT 2
+#define X_SIZEOF_INT 4
+#define X_SIZEOF_FLOAT 4
+#define X_SIZEOF_DOUBLE 8
+#define X_SIZEOF_UBYTE 1
+#define X_SIZEOF_USHORT 2
+#define X_SIZEOF_UINT 4
+#define X_SIZEOF_LONGLONG 8
+#define X_SIZEOF_ULONGLONG 8
+#define X_SIZEOF_INT64 8
+#define X_SIZEOF_UINT64 8
+
+#define X_UINT_MAX 4294967295U
+
+#define X_ALIGN 4
+
+/* useful for aligning memory */
+#define _RNDUP(x, unit) ((((x) + (unit) - 1) / (unit)) * (unit))
+#define M_RND_UNIT X_SIZEOF_DOUBLE
+#define M_RNDUP(x) _RNDUP(x, M_RND_UNIT)
+
+#define ncmpix_len_char(nelems) _RNDUP((nelems), X_ALIGN)
+#define ncmpix_len_short(nelems) (((nelems) + (nelems)%2) * X_SIZEOF_SHORT)
+#define ncmpix_len_int(nelems) ((nelems) * X_SIZEOF_INT)
+#define ncmpix_len_long(nelems) ((nelems) * X_SIZEOF_LONG)
+#define ncmpix_len_float(nelems) ((nelems) * X_SIZEOF_FLOAT)
+#define ncmpix_len_double(nelems) ((nelems) * X_SIZEOF_DOUBLE)
+#define ncmpix_len_ubyte(nelems) _RNDUP((nelems), X_ALIGN)
+#define ncmpix_len_ushort(nelems) (((nelems) + (nelems)%2) * X_SIZEOF_USHORT)
+#define ncmpix_len_uint(nelems) ((nelems) * X_SIZEOF_UINT)
+#define ncmpix_len_int64(nelems) ((nelems) * X_SIZEOF_INT64)
+#define ncmpix_len_uint64(nelems) ((nelems) * X_SIZEOF_UINT64)
+
+typedef int nc_type;
+
+typedef struct {
+ long long nchars;
+ char *cp; /* [nchars+1] one additional char for '\0' */
+} NC_string;
+
+typedef struct {
+ NC_string *name;
+ long long size;
+} NC_dim;
+
+typedef struct NC_dimarray {
+ int nalloc; /* number allocated >= ndefined */
+ int ndefined; /* number of defined dimensions */
+ NC_dim **value;
+} NC_dimarray;
+
+typedef struct {
+ long long xsz; /* amount of space at xvalue (4-byte aligned) */
+ NC_string *name; /* name of the attributes */
+ nc_type type; /* the discriminant */
+ long long nelems; /* number of attribute elements */
+ void *xvalue; /* the actual data, in external representation */
+} NC_attr;
+
+typedef struct NC_attrarray {
+ int nalloc; /* number allocated >= ndefined */
+ int ndefined; /* number of defined attributes */
+ NC_attr **value;
+} NC_attrarray;
+
+typedef struct {
+ int xsz; /* byte size of 1 array element */
+ long long *shape; /* dim->size of each dim */
+ long long *dsizes; /* the right to left product of shape */
+ NC_string *name; /* name of the variable */
+ int ndims; /* number of dimensions */
+ int *dimids; /* array of dimension IDs */
+ NC_attrarray attrs; /* attribute array */
+ nc_type type; /* variable's data type */
+ long long len; /* this is the "vsize" defined in header format, the
+ total size in bytes of the array variable.
+ For record variable, this is the record size */
+ long long begin; /* starting file offset of this variable */
+} NC_var;
+
+typedef struct NC_vararray {
+ int nalloc; /* number allocated >= ndefined */
+ int ndefined; /* number of defined variables */
+ int num_rec_vars;/* number of defined record variables */
+ NC_var **value;
+} NC_vararray;
+
+typedef struct NC {
+ int flags;
+ char path[1024];
+ long long xsz; /* external size of this header, <= var[0].begin */
+ long long begin_var;/* file offset of the first (non-record) var */
+ long long begin_rec;/* file offset of the first 'record' */
+
+ long long recsize; /* length of 'record': sum of single record sizes
+ of all the record variables */
+ long long numrecs; /* number of 'records' allocated */
+ NC_dimarray dims; /* dimensions defined */
+ NC_attrarray attrs; /* global attributes defined */
+ NC_vararray vars; /* variables defined */
+} NC;
+
+typedef struct bufferinfo {
+ int fd;
+ off_t offset; /* current read/write offset in the file */
+ int version; /* 1, 2, and 5 for CDF-1, 2, and 5 respectively */
+ void *base; /* beginning of read/write buffer */
+ void *pos; /* current position in buffer */
+ long long size; /* size of the buffer */
+} bufferinfo;
+
+/*
+ * "magic number" at beginning of file: 0x43444601 (big endian)
+ */
+static const char ncmagic1[] = {'C', 'D', 'F', 0x01};
+static const char ncmagic2[] = {'C', 'D', 'F', 0x02};
+static const char ncmagic5[] = {'C', 'D', 'F', 0x05};
+
+const char * ncmpii_err_code_name(int err);
+
+static int is_little_endian(void) {
+ volatile uint32_t i=0x01234567;
+ // return 0 for big endian, 1 for little endian.
+ return (*((uint8_t*)(&i))) == 0x67;
+}
+
+static void
+swap4b(int *val)
+{
+ unsigned int tmp = *val;
+ char *ip = (char*) &tmp;
+ char *op = (char*) val;
+ op[0] = ip[3];
+ op[1] = ip[2];
+ op[2] = ip[1];
+ op[3] = ip[0];
+}
+
+static void
+swap8b(long long *val)
+{
+ unsigned long long tmp = *val;
+ char *ip = (char*) &tmp;
+ char *op = (char*) val;
+ op[0] = ip[7];
+ op[1] = ip[6];
+ op[2] = ip[5];
+ op[3] = ip[4];
+ op[4] = ip[3];
+ op[5] = ip[2];
+ op[6] = ip[1];
+ op[7] = ip[0];
+}
+
+static unsigned long long
+get_uint8(bufferinfo *gbp) {
+ unsigned long long tmp;
+ memcpy(&tmp, gbp->pos, 8);
+ if (endianness) swap8b(&tmp);
+ gbp->pos += 8;
+ return tmp;
+}
+
+static unsigned int
+get_uint4(bufferinfo *gbp) {
+ unsigned int tmp;
+ memcpy(&tmp, gbp->pos, 4);
+ if (endianness) swap4b(&tmp);
+ gbp->pos += 4;
+ return tmp;
+}
+
+static int
+type_size(nc_type type) {
+ switch (type) {
+ case NC_BYTE: return X_SIZEOF_CHAR;
+ case NC_CHAR: return X_SIZEOF_CHAR;
+ case NC_SHORT: return X_SIZEOF_SHORT;
+ case NC_INT: return X_SIZEOF_INT;
+ case NC_FLOAT: return X_SIZEOF_FLOAT;
+ case NC_DOUBLE: return X_SIZEOF_DOUBLE;
+ case NC_UBYTE: return X_SIZEOF_UBYTE;
+ case NC_USHORT: return X_SIZEOF_USHORT;
+ case NC_UINT: return X_SIZEOF_UINT;
+ case NC_INT64: return X_SIZEOF_INT64;
+ case NC_UINT64: return X_SIZEOF_UINT64;
+ default: return -1;
+ }
+}
+
+static const char *
+type_name(nc_type type) {
+ switch (type) {
+ case NC_BYTE: return "byte";
+ case NC_CHAR: return "char";
+ case NC_SHORT: return "short";
+ case NC_INT: return "int";
+ case NC_FLOAT: return "float";
+ case NC_DOUBLE: return "double";
+ case NC_UBYTE: return "ubyte";
+ case NC_USHORT: return "ushort";
+ case NC_UINT: return "uint";
+ case NC_INT64: return "int64";
+ case NC_UINT64: return "uint64";
+ default: return "bogus";
+ }
+}
+
+static NC_string *
+ncmpii_new_NC_string(long long slen,
+ const char *str)
+{
+ /* str may not be NULL terminated */
+ NC_string *ncstrp;
+ size_t sizeof_NC_string = M_RNDUP(sizeof(NC_string));
+ size_t sz = slen + sizeof_NC_string + 1;
+ /* one char more space for NULL terminate char */
+
+ ncstrp = (NC_string *) calloc(sz, sizeof(char));
+ if (ncstrp == NULL) return NULL;
+
+ /* make space occupied by ncstrp->cp part of ncstrp */
+ ncstrp->nchars = slen;
+ ncstrp->cp = (char *)ncstrp + sizeof_NC_string;
+
+ /* in PnetCDF, we want to make name->cp always NULL character terminated */
+ if (str != NULL && *str != '\0') {
+ strncpy(ncstrp->cp, str, slen);
+ ncstrp->cp[slen] = '\0'; /* NULL terminated */
+ }
+
+ return(ncstrp);
+}
+
+static NC_dim *
+ncmpii_elem_NC_dimarray(const NC_dimarray *ncap,
+ int dimid)
+{
+ /* returns the dimension ID defined earlier */
+ assert(ncap != NULL);
+
+ if (dimid < 0 || ncap->ndefined == 0 || dimid >= ncap->ndefined)
+ return NULL;
+
+ assert(ncap->value != NULL);
+
+ return ncap->value[dimid];
+}
+
+/*----< ncmpix_len_nctype() >------------------------------------------------*/
+static int
+ncmpix_len_nctype(nc_type type) {
+ switch(type) {
+ case NC_BYTE:
+ case NC_CHAR:
+ case NC_UBYTE: return X_SIZEOF_CHAR;
+ case NC_SHORT:
+ case NC_USHORT: return X_SIZEOF_SHORT;
+ case NC_INT:
+ case NC_UINT: return X_SIZEOF_INT;
+ case NC_FLOAT: return X_SIZEOF_FLOAT;
+ case NC_DOUBLE: return X_SIZEOF_DOUBLE;
+ case NC_INT64:
+ case NC_UINT64: return X_SIZEOF_INT64;
+ default: assert("ncmpix_len_nctype bad type" == 0);
+ }
+ return 0;
+}
+
+static int
+ncmpii_NC_var_shape64(NC *ncp,
+ NC_var *varp,
+ const NC_dimarray *dims)
+{
+ int i;
+ long long product = 1;
+
+ /* set the size of 1 element */
+ varp->xsz = ncmpix_len_nctype(varp->type);
+
+ if (varp->ndims == 0) goto out;
+
+ /*
+ * use the user supplied dimension indices to determine the shape
+ */
+ for (i=0; i<varp->ndims; i++) {
+ const NC_dim *dimp;
+
+ if (varp->dimids[i] < 0)
+ DEBUG_RETURN_ERROR(NC_EBADDIM);
+
+ if (varp->dimids[i] >= ((dims != NULL) ? dims->ndefined : 1))
+ DEBUG_RETURN_ERROR(NC_EBADDIM);
+
+ /* get the pointer to the dim object */
+ dimp = ncmpii_elem_NC_dimarray(dims, varp->dimids[i]);
+ varp->shape[i] = dimp->size;
+
+ /* check for record variable, only the highest dimension can
+ * be unlimited */
+ if (varp->shape[i] == NC_UNLIMITED && i != 0)
+ DEBUG_RETURN_ERROR(NC_EUNLIMPOS);
+ }
+
+ /*
+ * compute the dsizes, the right to left product of shape
+ */
+ product = 1;
+ if (varp->ndims == 1) {
+ if (varp->shape[0] == NC_UNLIMITED)
+ varp->dsizes[0] = 1;
+ else {
+ varp->dsizes[0] = varp->shape[0];
+ product = varp->shape[0];
+ }
+ }
+ else { /* varp->ndims > 1 */
+ varp->dsizes[varp->ndims-1] = varp->shape[varp->ndims-1];
+ product = varp->shape[varp->ndims-1];
+ for (i=varp->ndims-2; i>=0; i--) {
+ if (varp->shape[i] != NC_UNLIMITED)
+ product *= varp->shape[i];
+ varp->dsizes[i] = product;
+ }
+ }
+
+out :
+ /*
+ * For CDF-1 and CDF-2 formats, the total number of array elements
+ * cannot exceed 2^32, unless this variable is the last fixed-size
+ * variable, there is no record variable, and the file starting
+ * offset of this variable is less than 2GiB.
+ * We will check this in ncmpi_enddef() which calls ncmpii_NC_enddef()
+ * which calls ncmpii_NC_check_vlens()
+ if (ncp->flags != 5 && product >= X_UINT_MAX)
+ DEBUG_RETURN_ERROR(NC_EVARSIZE);
+ */
+
+ /*
+ * align variable size to 4 byte boundary, required by all netcdf file
+ * formats
+ */
+ varp->len = product * varp->xsz;
+ if (varp->len % 4 > 0)
+ varp->len += 4 - varp->len % 4; /* round up */
+
+ return NC_NOERR;
+}
+
+/*
+ * Recompute the shapes of all variables
+ * Sets ncp->begin_var to start of first variable.
+ * Sets ncp->begin_rec to start of first record variable.
+ * Returns -1 on error. The only possible error is an reference
+ * to a non existent dimension, which would occur for a corrupt
+ * netcdf file.
+ */
+static int
+ncmpii_NC_computeshapes(NC *ncp)
+{
+ NC_var **vpp = (NC_var **)ncp->vars.value;
+ NC_var *const *const end = &vpp[ncp->vars.ndefined];
+ NC_var *first_var = NULL; /* first "non-record" var */
+ NC_var *first_rec = NULL; /* first "record" var */
+ int status;
+
+ ncp->begin_var = ncp->xsz;
+ ncp->begin_rec = ncp->xsz;
+ ncp->recsize = 0;
+
+ if (ncp->vars.ndefined == 0) return NC_NOERR;
+
+ for ( /*NADA*/; vpp < end; vpp++) {
+ /* (*vpp)->len is recomputed from dimensions in ncmpii_NC_var_shape64() */
+ status = ncmpii_NC_var_shape64(ncp, *vpp, &ncp->dims);
+
+ if (status != NC_NOERR) return status ;
+
+ if (IS_RECVAR(*vpp)) {
+ if (first_rec == NULL)
+ first_rec = *vpp;
+ ncp->recsize += (*vpp)->len;
+ }
+ else {
+ if (first_var == NULL)
+ first_var = *vpp;
+ /*
+ * Overwritten each time thru.
+ * Usually overwritten in first_rec != NULL clause.
+ */
+ ncp->begin_rec = (*vpp)->begin + (*vpp)->len;
+ }
+ }
+
+ if (first_rec != NULL) {
+ if (ncp->begin_rec > first_rec->begin)
+ DEBUG_RETURN_ERROR(NC_ENOTNC); /* not a netCDF file or corrupted */
+
+ ncp->begin_rec = first_rec->begin;
+ /*
+ * for special case of exactly one record variable, pack value
+ */
+ if (ncp->recsize == first_rec->len)
+ ncp->recsize = *first_rec->dsizes * first_rec->xsz;
+ }
+
+ if (first_var != NULL)
+ ncp->begin_var = first_var->begin;
+ else
+ ncp->begin_var = ncp->begin_rec;
+
+ if (ncp->begin_var <= 0 ||
+ ncp->xsz > ncp->begin_var ||
+ ncp->begin_rec <= 0 ||
+ ncp->begin_var > ncp->begin_rec)
+ DEBUG_RETURN_ERROR(NC_ENOTNC); /* not a netCDF file or corrupted */
+
+ return NC_NOERR;
+}
+
+/*
+ * To compute how much space will the xdr'd header take
+ */
+
+#define X_SIZEOF_NC_TYPE X_SIZEOF_INT
+#define X_SIZEOF_NCTYPE X_SIZEOF_INT
+
+/*----< hdr_len_NC_name() >--------------------------------------------------*/
+static long long
+hdr_len_NC_name(const NC_string *ncstrp,
+ int sizeof_t) /* NON_NEG */
+{
+ /* netCDF file format:
+ * name = nelems namestring
+ * nelems = NON_NEG
+ * namestring = ID1 [IDN ...] padding
+ * ID1 = alphanumeric | '_'
+ * IDN = alphanumeric | special1 | special2
+ * padding = <0, 1, 2, or 3 bytes to next 4-byte boundary>
+ * NON_NEG = <non-negative INT> | // CDF-1 and CDF-2
+ * <non-negative INT64> // CDF-5
+ */
+ long long sz = sizeof_t; /* nelems */
+
+ assert(ncstrp != NULL);
+
+ if (ncstrp->nchars != 0) /* namestring */
+ sz += _RNDUP(ncstrp->nchars, X_ALIGN);
+
+ return sz;
+}
+
+/*----< hdr_len_NC_dim() >---------------------------------------------------*/
+static long long
+hdr_len_NC_dim(const NC_dim *dimp,
+ int sizeof_t) /* NON_NEG */
+{
+ /* netCDF file format:
+ * ...
+ * dim = name dim_length
+ * dim_length = NON_NEG
+ * NON_NEG = <non-negative INT> | // CDF-1 and CDF-2
+ * <non-negative INT64> // CDF-5
+ */
+ long long sz;
+
+ assert(dimp != NULL);
+
+ sz = hdr_len_NC_name(dimp->name, sizeof_t); /* name */
+ sz += sizeof_t; /* dim_length */
+
+ return sz;
+}
+
+/*----< hdr_len_NC_dimarray() >----------------------------------------------*/
+static long long
+hdr_len_NC_dimarray(const NC_dimarray *ncap,
+ int sizeof_t) /* NON_NEG */
+{
+ /* netCDF file format:
+ * ...
+ * dim_list = ABSENT | NC_DIMENSION nelems [dim ...]
+ * ABSENT = ZERO ZERO | // list is not present for CDF-1 and 2
+ * ZERO ZERO64 // for CDF-5
+ * ZERO = \x00 \x00 \x00 \x00 // 32-bit zero
+ * ZERO64 = \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 // 64-bit zero
+ * NC_DIMENSION = \x00 \x00 \x00 \x0A // tag for list of dimensions
+ * nelems = NON_NEG // number of elements in following sequence
+ * NON_NEG = <non-negative INT> | // CDF-1 and CDF-2
+ * <non-negative INT64> // CDF-5
+ */
+ int i;
+ long long xlen;
+
+ xlen = X_SIZEOF_NCTYPE; /* NC_DIMENSION */
+ xlen += sizeof_t; /* nelems */
+
+ if (ncap == NULL) /* ABSENT: no dimension is defined */
+ return xlen;
+
+ /* [dim ...] */
+ for (i=0; i<ncap->ndefined; i++)
+ xlen += hdr_len_NC_dim(ncap->value[i], sizeof_t);
+
+ return xlen;
+}
+
+/*----< hdr_len_NC_attr() >--------------------------------------------------*/
+static long long
+hdr_len_NC_attr(const NC_attr *attrp,
+ int sizeof_t) /* NON_NEG */
+{
+ /* netCDF file format:
+ * ...
+ * attr = name nc_type nelems [values ...]
+ * nc_type = NC_BYTE | NC_CHAR | NC_SHORT | ...
+ * nelems = NON_NEG // number of elements in following sequence
+ * values = bytes | chars | shorts | ints | floats | doubles
+ * bytes = [BYTE ...] padding
+ * chars = [CHAR ...] padding
+ * shorts = [SHORT ...] padding
+ * ints = [INT ...]
+ * floats = [FLOAT ...]
+ * doubles = [DOUBLE ...]
+ * padding = <0, 1, 2, or 3 bytes to next 4-byte boundary>
+ * NON_NEG = <non-negative INT> | // CDF-1 and CDF-2
+ * <non-negative INT64> // CDF-5
+ */
+ long long sz;
+
+ assert(attrp != NULL);
+
+ sz = hdr_len_NC_name(attrp->name, sizeof_t); /* name */
+ sz += X_SIZEOF_NC_TYPE; /* nc_type */
+ sz += sizeof_t; /* nelems */
+ sz += attrp->xsz; /* [values ...] */
+
+ return sz;
+}
+
+/*----< hdr_len_NC_attrarray() >---------------------------------------------*/
+static long long
+hdr_len_NC_attrarray(const NC_attrarray *ncap,
+ int sizeof_t) /* NON_NEG */
+{
+ /* netCDF file format:
+ * ...
+ * att_list = ABSENT | NC_ATTRIBUTE nelems [attr ...]
+ * ABSENT = ZERO ZERO | // list is not present for CDF-1 and 2
+ * ZERO ZERO64 // for CDF-5
+ * ZERO = \x00 \x00 \x00 \x00 // 32-bit zero
+ * ZERO64 = \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 // 64-bit zero
+ * NC_ATTRIBUTE = \x00 \x00 \x00 \x0C // tag for list of attributes
+ * nelems = NON_NEG // number of elements in following sequence
+ * NON_NEG = <non-negative INT> | // CDF-1 and CDF-2
+ * <non-negative INT64> // CDF-5
+ */
+ int i;
+ long long xlen;
+
+ xlen = X_SIZEOF_NCTYPE; /* NC_ATTRIBUTE */
+ xlen += sizeof_t; /* nelems */
+
+ if (ncap == NULL) /* ABSENT: no attribute is defined */
+ return xlen;
+
+ for (i=0; i<ncap->ndefined; i++) /* [attr ...] */
+ xlen += hdr_len_NC_attr(ncap->value[i], sizeof_t);
+
+ return xlen;
+}
+
+/*----< hdr_len_NC_var() >---------------------------------------------------*/
+static long long
+hdr_len_NC_var(const NC_var *varp,
+ int sizeof_off_t, /* OFFSET */
+ int sizeof_t) /* NON_NEG */
+{
+ /* netCDF file format:
+ * netcdf_file = header data
+ * header = magic numrecs dim_list gatt_list var_list
+ * ...
+ * var = name nelems [dimid ...] vatt_list nc_type vsize begin
+ * nelems = NON_NEG
+ * dimid = NON_NEG
+ * vatt_list = att_list
+ * nc_type = NC_BYTE | NC_CHAR | NC_SHORT | ...
+ * vsize = NON_NEG
+ * begin = OFFSET // Variable start location.
+ * OFFSET = <non-negative INT> | // CDF-1
+ * <non-negative INT64> // CDF-2 and CDF-5
+ * NON_NEG = <non-negative INT> | // CDF-1 and CDF-2
+ * <non-negative INT64> // CDF-5
+ */
+ long long sz;
+
+ assert(varp != NULL);
+
+ /* for CDF-1, sizeof_off_t == 4 && sizeof_t == 4
+ * for CDF-2, sizeof_off_t == 8 && sizeof_t == 4
+ * for CDF-5, sizeof_off_t == 8 && sizeof_t == 8
+ */
+ sz = hdr_len_NC_name(varp->name, sizeof_t); /* name */
+ sz += sizeof_t; /* nelems */
+ sz += sizeof_t * varp->ndims; /* [dimid ...] */
+ sz += hdr_len_NC_attrarray(&varp->attrs, sizeof_t); /* vatt_list */
+ sz += X_SIZEOF_NC_TYPE; /* nc_type */
+ sz += sizeof_t; /* vsize */
+ sz += sizeof_off_t; /* begin */
+
+ return sz;
+}
+
+/*----< hdr_len_NC_vararray() >----------------------------------------------*/
+static long long
+hdr_len_NC_vararray(const NC_vararray *ncap,
+ int sizeof_t, /* NON_NEG */
+ int sizeof_off_t) /* OFFSET */
+{
+ /* netCDF file format:
+ * netcdf_file = header data
+ * header = magic numrecs dim_list gatt_list var_list
+ * ...
+ * var_list = ABSENT | NC_VARIABLE nelems [var ...]
+ * ABSENT = ZERO ZERO | // list is not present for CDF-1 and 2
+ * ZERO ZERO64 // for CDF-5
+ * ZERO = \x00 \x00 \x00 \x00 // 32-bit zero
+ * ZERO64 = \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 // 64-bit zero
+ * NC_VARIABLE = \x00 \x00 \x00 \x0B // tag for list of variables
+ * nelems = NON_NEG // number of elements in following sequence
+ * NON_NEG = <non-negative INT> | // CDF-1 and CDF-2
+ * <non-negative INT64> // CDF-5
+ */
+ int i;
+ long long xlen;
+
+ xlen = X_SIZEOF_NCTYPE; /* NC_VARIABLE */
+ xlen += sizeof_t; /* nelems */
+
+ if (ncap == NULL) /* ABSENT: no variable is defined */
+ return xlen;
+
+ /* for CDF-1, sizeof_off_t == 4 && sizeof_t == 4
+ * for CDF-2, sizeof_off_t == 8 && sizeof_t == 4
+ * for CDF-5, sizeof_off_t == 8 && sizeof_t == 8
+ */
+ for (i=0; i<ncap->ndefined; i++) /* [var ...] */
+ xlen += hdr_len_NC_var(ncap->value[i], sizeof_off_t, sizeof_t);
+
+ return xlen;
+}
+
+/*----< ncmpii_hdr_len_NC() >------------------------------------------------*/
+static long long
+ncmpii_hdr_len_NC(const NC *ncp)
+{
+ /* netCDF file format:
+ * netcdf_file = header data
+ * header = magic numrecs dim_list gatt_list var_list
+ * ...
+ * numrecs = NON_NEG | STREAMING // length of record dimension
+ * NON_NEG = <non-negative INT> | // CDF-1 and CDF-2
+ * <non-negative INT64> // CDF-5
+ */
+
+ int sizeof_t, sizeof_off_t;
+ long long xlen;
+
+ assert(ncp != NULL);
+
+ if (ncp->flags == 5) { /* CDF-5 */
+ sizeof_t = X_SIZEOF_INT64; /* 8-byte integer for all integers */
+ sizeof_off_t = X_SIZEOF_INT64; /* 8-byte integer for var begin */
+ }
+ else if (ncp->flags == 2) { /* CDF-2 */
+ sizeof_t = X_SIZEOF_INT; /* 4-byte integer in CDF-1 */
+ sizeof_off_t = X_SIZEOF_INT64; /* 8-byte integer for var begin */
+ }
+ else { /* CDF-1 */
+ sizeof_t = X_SIZEOF_INT; /* 4-byte integer in CDF-1 */
+ sizeof_off_t = X_SIZEOF_INT; /* 4-byte integer in CDF-1 */
+ }
+
+ xlen = sizeof(ncmagic1); /* magic */
+ xlen += sizeof_t; /* numrecs */
+ xlen += hdr_len_NC_dimarray(&ncp->dims, sizeof_t); /* dim_list */
+ xlen += hdr_len_NC_attrarray(&ncp->attrs, sizeof_t); /* gatt_list */
+ xlen += hdr_len_NC_vararray(&ncp->vars, sizeof_t, sizeof_off_t); /* var_list */
+
+ return xlen; /* return the header size (not yet aligned) */
+}
+
+static int
+hdr_fetch(bufferinfo *gbp) {
+ int err=NC_NOERR;
+ size_t slack; /* any leftover data in the buffer */
+
+ assert(gbp->base != NULL);
+
+ slack = gbp->size - (gbp->pos - gbp->base);
+ /* if gbp->pos and gbp->base are the same, there is no leftover buffer
+ * data to worry about.
+ * In the other extreme, where gbp->size == (gbp->pos - gbp->base), then
+ * all data in the buffer has been consumed */
+ if (slack == gbp->size) slack = 0;
+
+ memset(gbp->base, 0, (size_t)gbp->size);
+ gbp->pos = gbp->base;
+
+ lseek(gbp->fd, (gbp->offset)-slack, SEEK_SET);
+ size_t read_amount = read(gbp->fd, gbp->base, gbp->size);
+ if (read_amount == -1) {
+ fprintf(stderr,"ERROR at line %d: read error %s\n",__LINE__,strerror(errno));
+ exit(1);
+ }
+ /* we might have had to backtrack */
+ gbp->offset += (gbp->size - slack);
+
+ return err;
+}
+
+/*----< hdr_check_buffer() >--------------------------------------------------*/
+/* Ensure that 'nextread' bytes are available. */
+static int
+hdr_check_buffer(bufferinfo *gbp,
+ size_t nextread)
+{
+ if (gbp->pos + nextread <= gbp->base + gbp->size)
+ return NC_NOERR;
+
+ /* read the next chunk from file */
+ return hdr_fetch(gbp);
+}
+
+/*----< hdr_get_NCtype() >----------------------------------------------------*/
+static int
+hdr_get_NCtype(bufferinfo *gbp,
+ NCtype *typep)
+{
+ /* NCtype is 4-byte integer */
+ int status = hdr_check_buffer(gbp, 4);
+ if (status != NC_NOERR) return status;
+
+ /* get a 4-byte integer */
+ *typep = get_uint4(gbp);
+
+ return NC_NOERR;
+}
+
+/*----< hdr_get_nc_type() >---------------------------------------------------*/
+static int
+hdr_get_nc_type(bufferinfo *gbp,
+ nc_type *typep)
+{
+ /* nc_type is 4-byte integer, X_SIZEOF_INT */
+ int type, status;
+
+ status = hdr_check_buffer(gbp, X_SIZEOF_INT);
+ if (status != NC_NOERR) return status;
+
+ type = get_uint4(gbp);
+
+ if (type != NC_BYTE &&
+ type != NC_CHAR &&
+ type != NC_UBYTE &&
+ type != NC_SHORT &&
+ type != NC_USHORT &&
+ type != NC_INT &&
+ type != NC_UINT &&
+ type != NC_FLOAT &&
+ type != NC_DOUBLE &&
+ type != NC_INT64 &&
+ type != NC_UINT64
+ )
+ DEBUG_RETURN_ERROR(NC_EINVAL);
+
+ *typep = (nc_type) type;
+ return NC_NOERR;
+}
+
+/*----< hdr_get_NC_name() >---------------------------------------------------*/
+static int
+hdr_get_NC_name(bufferinfo *gbp,
+ NC_string **ncstrpp)
+{
+ /* netCDF file format:
+ * ...
+ * name = nelems namestring
+ * nelems = NON_NEG
+ * namestring = ID1 [IDN ...] padding
+ * ID1 = alphanumeric | '_'
+ * IDN = alphanumeric | special1 | special2
+ * padding = <0, 1, 2, or 3 bytes to next 4-byte boundary>
+ * NON_NEG = <non-negative INT> | // CDF-1 and CDF-2
+ * <non-negative INT64> // CDF-5
+ */
+ int status;
+ size_t nchars, nbytes, padding, bufremain, strcount;
+ NC_string *ncstrp;
+ char *cpos, pad[X_ALIGN-1];
+
+ /* get nelems */
+ if (gbp->version == 5)
+ nchars = get_uint8(gbp);
+ else
+ nchars = get_uint4(gbp);
+
+ /* Allocate a NC_string structure large enough to hold nchars characters */
+ ncstrp = ncmpii_new_NC_string(nchars, NULL);
+
+ nbytes = nchars;
+ padding = _RNDUP(ncstrp->nchars, X_ALIGN) - ncstrp->nchars;
+ bufremain = gbp->size - (gbp->pos - gbp->base);
+ cpos = ncstrp->cp;
+
+ /* get namestring with padding */
+ while (nbytes > 0) {
+ if (bufremain > 0) {
+ strcount = MIN(bufremain, nbytes);
+ memcpy(cpos, gbp->pos, strcount);
+ nbytes -= strcount;
+ gbp->pos = (void *)((char *)gbp->pos + strcount);
+ cpos += strcount;
+ bufremain -= strcount;
+ } else {
+ status = hdr_fetch(gbp);
+ if (status != NC_NOERR) {
+ free(ncstrp);
+ return status;
+ }
+ bufremain = gbp->size;
+ }
+ }
+
+ /* handle the padding */
+ if (padding > 0) {
+ memset(pad, 0, X_ALIGN-1);
+ if (memcmp(gbp->pos, pad, padding) != 0) {
+ free(ncstrp);
+ DEBUG_RETURN_ERROR(NC_EINVAL);
+ }
+ gbp->pos = (void *)((char *)gbp->pos + padding);
+ }
+
+ *ncstrpp = ncstrp;
+
+ return NC_NOERR;
+}
+
+static NC_dim *
+ncmpii_new_x_NC_dim(NC_string *name)
+{
+ NC_dim *dimp;
+
+ dimp = (NC_dim *) malloc(sizeof(NC_dim));
+ MALLOC_CHECK(dimp)
+
+ dimp->name = name;
+ dimp->size = 0;
+
+ return(dimp);
+}
+
+/*----< hdr_get_NC_dim() >----------------------------------------------------*/
+static int
+hdr_get_NC_dim(bufferinfo *gbp,
+ NC_dim **dimpp)
+{
+ /* netCDF file format:
+ * ...
+ * dim = name dim_length
+ * dim_length = NON_NEG
+ * NON_NEG = <non-negative INT> | // CDF-1 and CDF-2
+ * <non-negative INT64> // CDF-5
+ */
+ int status;
+ NC_string *ncstrp;
+ NC_dim *dimp;
+
+ /* get name */
+ status = hdr_get_NC_name(gbp, &ncstrp);
+ if (status != NC_NOERR) return status;
+
+ dimp = ncmpii_new_x_NC_dim(ncstrp);
+
+ /* get dim_length */
+ if (gbp->version == 5)
+ dimp->size = get_uint8(gbp);
+ else
+ dimp->size = get_uint4(gbp);
+
+ *dimpp = dimp;
+ return NC_NOERR;
+}
+
+static void
+ncmpii_free_NC_dim(NC_dim *dimp)
+{
+ if (dimp == NULL) return;
+ free(dimp->name);
+ free(dimp);
+}
+
+static void
+ncmpii_free_NC_dimarray(NC_dimarray *ncap)
+{
+ int i;
+
+ assert(ncap != NULL);
+ if (ncap->nalloc == 0) return;
+
+ assert(ncap->value != NULL);
+ for (i=0; i<ncap->ndefined; i++)
+ ncmpii_free_NC_dim(ncap->value[i]);
+
+ free(ncap->value);
+ ncap->value = NULL;
+ ncap->nalloc = 0;
+ ncap->ndefined = 0;
+}
+
+
+/*----< hdr_get_NC_dimarray() >-----------------------------------------------*/
+static int
+hdr_get_NC_dimarray(bufferinfo *gbp,
+ NC_dimarray *ncap)
+{
+ /* netCDF file format:
+ * ...
+ * dim_list = ABSENT | NC_DIMENSION nelems [dim ...]
+ * ABSENT = ZERO ZERO | // list is not present for CDF-1 and 2
+ * ZERO ZERO64 // for CDF-5
+ * ZERO = \x00 \x00 \x00 \x00 // 32-bit zero
+ * ZERO64 = \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 // 64-bit zero
+ * NC_DIMENSION = \x00 \x00 \x00 \x0A // tag for list of dimensions
+ * nelems = NON_NEG // number of elements in following sequence
+ * NON_NEG = <non-negative INT> | // CDF-1 and CDF-2
+ * <non-negative INT64> // CDF-5
+ */
+ int i, status;
+ NCtype type = NC_UNSPECIFIED;
+ size_t ndefined;
+
+ /* get NCtype (NC_DIMENSION) */
+ status = hdr_get_NCtype(gbp, &type);
+ if (status != NC_NOERR) return status;
+
+ /* get nelems */
+ if (gbp->version == 5)
+ ndefined = get_uint8(gbp);
+ else
+ ndefined = get_uint4(gbp);
+ ncap->ndefined = (int)ndefined;
+
+ if (ndefined == 0) {
+ if (type != NC_DIMENSION && type != NC_UNSPECIFIED)
+ DEBUG_RETURN_ERROR(NC_EINVAL);
+ } else {
+ if (type != NC_DIMENSION) DEBUG_RETURN_ERROR(NC_EINVAL);
+
+ ncap->value = (NC_dim **) malloc(ndefined * sizeof(NC_dim*));
+ MALLOC_CHECK(ncap->value)
+ ncap->nalloc = (int)ndefined;
+
+ for (i=0; i<ndefined; i++) {
+ status = hdr_get_NC_dim(gbp, ncap->value + i);
+ if (status != NC_NOERR) { /* error: fail to get the next dim */
+ ncap->ndefined = i;
+ ncmpii_free_NC_dimarray(ncap);
+ return status;
+ }
+ }
+ }
+
+ return NC_NOERR;
+}
+
+/*----< hdr_get_NC_attrV() >--------------------------------------------------*/
+static int
+hdr_get_NC_attrV(bufferinfo *gbp,
+ NC_attr *attrp)
+{
+ /* netCDF file format:
+ * ...
+ * attr = name nc_type nelems [values ...]
+ * ...
+ * values = bytes | chars | shorts | ints | floats | doubles
+ * bytes = [BYTE ...] padding
+ * chars = [CHAR ...] padding
+ * shorts = [SHORT ...] padding
+ * ints = [INT ...]
+ * floats = [FLOAT ...]
+ * doubles = [DOUBLE ...]
+ * padding = <0, 1, 2, or 3 bytes to next 4-byte boundary>
+ */
+ int status;
+ void *value = attrp->xvalue;
+ char pad[X_ALIGN-1];
+ size_t nbytes, padding, bufremain, attcount;
+
+ nbytes = attrp->nelems * ncmpix_len_nctype(attrp->type);
+ padding = attrp->xsz - nbytes;
+ bufremain = gbp->size - (gbp->pos - gbp->base);
+
+ /* get values */
+ while (nbytes > 0) {
+ if (bufremain > 0) {
+ attcount = MIN(bufremain, nbytes);
+ memcpy(value, gbp->pos, (size_t)attcount);
+ nbytes -= attcount;
+ gbp->pos = (void *)((char *)gbp->pos + attcount);
+ value = (void *)((char *)value + attcount);
+ bufremain -= attcount;
+ } else {
+ status = hdr_fetch(gbp);
+ if (status != NC_NOERR) return status;
+ bufremain = gbp->size;
+ }
+ }
+
+ /* handle the padding */
+ if (padding > 0) {
+ memset(pad, 0, X_ALIGN-1);
+ if (memcmp(gbp->pos, pad, (size_t)padding) != 0)
+ DEBUG_RETURN_ERROR(NC_EINVAL);
+ gbp->pos = (void *)((char *)gbp->pos + padding);
+ }
+
+ return NC_NOERR;
+}
+
+static long long
+ncmpix_len_NC_attrV(nc_type type,
+ long long nelems)
+{
+ switch(type) {
+ case NC_BYTE:
+ case NC_CHAR:
+ case NC_UBYTE: return ncmpix_len_char(nelems);
+ case NC_SHORT: return ncmpix_len_short(nelems);
+ case NC_USHORT: return ncmpix_len_ushort(nelems);
+ case NC_INT: return ncmpix_len_int(nelems);
+ case NC_UINT: return ncmpix_len_uint(nelems);
+ case NC_FLOAT: return ncmpix_len_float(nelems);
+ case NC_DOUBLE: return ncmpix_len_double(nelems);
+ case NC_INT64: return ncmpix_len_int64(nelems);
+ case NC_UINT64: return ncmpix_len_uint64(nelems);
+ default: assert("ncmpix_len_NC_attr bad type" == 0);
+ }
+ return 0;
+}
+
+static NC_attr *
+ncmpii_new_x_NC_attr(NC_string *strp,
+ nc_type type,
+ size_t nelems)
+{
+ NC_attr *attrp;
+ const long long xsz = ncmpix_len_NC_attrV(type, nelems);
+ size_t sz = M_RNDUP(sizeof(NC_attr));
+
+ assert(!(xsz == 0 && nelems != 0));
+
+ sz += (size_t)xsz;
+
+ attrp = (NC_attr *) malloc(sz);
+ MALLOC_CHECK(attrp)
+
+ attrp->xsz = xsz;
+ attrp->name = strp;
+ attrp->type = type;
+ attrp->nelems = nelems;
+
+ if (xsz != 0)
+ attrp->xvalue = (char *)attrp + M_RNDUP(sizeof(NC_attr));
+ else
+ attrp->xvalue = NULL;
+
+ return(attrp);
+}
+
+static void
+ncmpii_free_NC_attr(NC_attr *attrp)
+{
+ if (attrp == NULL) return;
+ free(attrp->name);
+ free(attrp);
+}
+
+
+/*----< hdr_get_NC_attr() >---------------------------------------------------*/
+static int
+hdr_get_NC_attr(bufferinfo *gbp,
+ NC_attr **attrpp)
+{
+ /* netCDF file format:
+ * ...
+ * attr = name nc_type nelems [values ...]
+ * nc_type = NC_BYTE | NC_CHAR | NC_SHORT | ...
+ * nelems = NON_NEG // number of elements in following sequence
+ * NON_NEG = <non-negative INT> | // CDF-1 and CDF-2
+ * <non-negative INT64> // CDF-5
+ */
+ int status;
+ NC_string *strp;
+ nc_type type;
+ size_t nelems;
+ NC_attr *attrp;
+
+ /* get name */
+ status = hdr_get_NC_name(gbp, &strp);
+ if (status != NC_NOERR) return status;
+
+ /* get nc_type */
+ status = hdr_get_nc_type(gbp, &type);
+ if (status != NC_NOERR) {
+ free(strp);
+ return status;
+ }
+
+ /* get nelems */
+ if (gbp->version == 5)
+ nelems = get_uint8(gbp);
+ else
+ nelems = get_uint4(gbp);
+
+ /* allocate space for attribute object */
+ attrp = ncmpii_new_x_NC_attr(strp, type, nelems);
+ if (attrp == NULL) {
+ free(strp);
+ return status;
+ }
+
+ /* get [values ...] */
+ status = hdr_get_NC_attrV(gbp, attrp);
+ if (status != NC_NOERR) {
+ ncmpii_free_NC_attr(attrp); /* frees strp */
+ return status;
+ }
+
+ *attrpp = attrp;
+ return NC_NOERR;
+}
+
+static void
+ncmpii_free_NC_attrarray(NC_attrarray *ncap)
+{
+ int i;
+
+ assert(ncap != NULL);
+ if (ncap->nalloc == 0) return;
+ assert(ncap->value != NULL);
+ for (i=0; i<ncap->ndefined; i++)
+ ncmpii_free_NC_attr(ncap->value[i]);
+
+ free(ncap->value);
+ ncap->value = NULL;
+ ncap->nalloc = 0;
+ ncap->ndefined = 0;
+}
+/*----< hdr_get_NC_attrarray() >----------------------------------------------*/
+static int
+hdr_get_NC_attrarray(bufferinfo *gbp,
+ NC_attrarray *ncap)
+{
+ /* netCDF file format:
+ * ...
+ * att_list = ABSENT | NC_ATTRIBUTE nelems [attr ...]
+ * ABSENT = ZERO ZERO | // list is not present for CDF-1 and 2
+ * ZERO ZERO64 // for CDF-5
+ * ZERO = \x00 \x00 \x00 \x00 // 32-bit zero
+ * ZERO64 = \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 // 64-bit zero
+ * NC_ATTRIBUTE = \x00 \x00 \x00 \x0C // tag for list of attributes
+ * nelems = NON_NEG // number of elements in following sequence
+ * NON_NEG = <non-negative INT> | // CDF-1 and CDF-2
+ * <non-negative INT64> // CDF-5
+ */
+ int i, status;
+ NCtype type = NC_UNSPECIFIED;
+ size_t ndefined;
+
+ /* get NCtype (NC_ATTRIBUTE) */
+ status = hdr_get_NCtype(gbp, &type);
+ if (status != NC_NOERR) return status;
+
+ /* get nelems */
+ if (gbp->version == 5)
+ ndefined = get_uint8(gbp);
+ else
+ ndefined = get_uint4(gbp);
+ ncap->ndefined = (int)ndefined;
+
+ if (ndefined == 0) {
+ if (type != NC_ATTRIBUTE && type != NC_UNSPECIFIED)
+ DEBUG_RETURN_ERROR(NC_EINVAL);
+ } else {
+ if (type != NC_ATTRIBUTE)
+ DEBUG_RETURN_ERROR(NC_EINVAL);
+
+ ncap->value = (NC_attr **)malloc((size_t)ndefined * sizeof(NC_attr*));
+ MALLOC_CHECK(ncap->value)
+ ncap->nalloc = (int)ndefined;
+
+ /* get [attr ...] */
+ for (i=0; i<ndefined; i++) {
+ status = hdr_get_NC_attr(gbp, ncap->value + i);
+ if (status != NC_NOERR) { /* Error: fail to get the next att */
+ ncap->ndefined = i;
+ ncmpii_free_NC_attrarray(ncap);
+ return status;
+ }
+ }
+ }
+
+ return NC_NOERR;
+}
+
+static NC_var *
+ncmpii_new_x_NC_var(NC_string *strp,
+ int ndims)
+{
+ NC_var *varp;
+ int shape_space = M_RNDUP(ndims * 8);
+ int dsizes_space = M_RNDUP(ndims * 8);
+ int dimids_space = M_RNDUP(ndims * 4);
+ size_t sizeof_NC_var = M_RNDUP(sizeof(NC_var));
+ size_t sz = sizeof_NC_var + (size_t)(shape_space + dsizes_space + dimids_space);
+
+ varp = (NC_var *) malloc(sz);
+ MALLOC_CHECK(varp)
+
+ memset(varp, 0, sz);
+
+ varp->name = strp;
+ varp->ndims = ndims;
+
+ if (ndims != 0) {
+ varp->shape = (long long *)((char *)varp + sizeof_NC_var);
+ varp->dsizes = (long long *)((char *)varp->shape + shape_space);
+ varp->dimids = (int *) ((char *)varp->dsizes + dsizes_space);
+ }
+
+ varp->xsz = 0;
+ varp->len = 0;
+ varp->begin = 0;
+ return varp;
+}
+
+static void
+ncmpii_free_NC_var(NC_var *varp)
+{
+ if (varp == NULL) return;
+ ncmpii_free_NC_attrarray(&varp->attrs);
+ free(varp->name);
+ free(varp);
+}
+
+/*----< hdr_get_NC_var() >---------------------------------------------------*/
+static int
+hdr_get_NC_var(bufferinfo *gbp,
+ NC_var **varpp)
+{
+ /* netCDF file format:
+ * netcdf_file = header data
+ * header = magic numrecs dim_list gatt_list var_list
+ * ...
+ * var = name nelems [dimid ...] vatt_list nc_type vsize begin
+ * nelems = NON_NEG
+ * dimid = NON_NEG
+ * vatt_list = att_list
+ * nc_type = NC_BYTE | NC_CHAR | NC_SHORT | ...
+ * vsize = NON_NEG
+ * begin = OFFSET // Variable start location.
+ * OFFSET = <non-negative INT> | // CDF-1
+ * <non-negative INT64> // CDF-2 and CDF-5
+ * NON_NEG = <non-negative INT> | // CDF-1 and CDF-2
+ * <non-negative INT64> // CDF-5
+ */
+ int status;
+ NC_string *strp;
+ size_t ndims=0, dim;
+ NC_var *varp;
+
+ /* get name */
+ status = hdr_get_NC_name(gbp, &strp);
+ if (status != NC_NOERR) return status;
+
+ /* nelems */
+ if (gbp->version == 5)
+ ndims = get_uint8(gbp);
+ else
+ ndims = get_uint4(gbp);
+
+ /* allocate space for var object */
+ varp = ncmpii_new_x_NC_var(strp, (int)ndims);
+
+ /* get [dimid ...] */
+ for (dim=0; dim<ndims; dim++) {
+ status = hdr_check_buffer(gbp, (gbp->version == 5 ? 8 : 4));
+ if (status != NC_NOERR) {
+ ncmpii_free_NC_var(varp);
+ return status;
+ }
+ if (gbp->version == 5)
+ varp->dimids[dim] = get_uint8(gbp);
+ else
+ varp->dimids[dim] = get_uint4(gbp);
+ }
+
+ /* get vatt_list */
+ status = hdr_get_NC_attrarray(gbp, &varp->attrs);
+ if (status != NC_NOERR) {
+ ncmpii_free_NC_var(varp);
+ return status;
+ }
+
+ /* get nc_type */
+ status = hdr_get_nc_type(gbp, &varp->type);
+ if (status != NC_NOERR) {
+ ncmpii_free_NC_var(varp);
+ return status;
+ }
+
+ /* get vsize */
+ if (gbp->version == 5)
+ varp->len = get_uint8(gbp);
+ else
+ varp->len = get_uint4(gbp);
+
+ /* next element is 'begin' */
+ status = hdr_check_buffer(gbp, (gbp->version == 1 ? 4 : 8));
+ if (status != NC_NOERR) {
+ ncmpii_free_NC_var(varp);
+ return status;
+ }
+
+ /* get begin */
+ if (gbp->version == 1)
+ varp->begin = get_uint4(gbp);
+ else
+ varp->begin = get_uint8(gbp);
+
+ *varpp = varp;
+ return NC_NOERR;
+}
+
+static void
+ncmpii_free_NC_vararray(NC_vararray *ncap)
+{
+ int i;
+
+ assert(ncap != NULL);
+ if (ncap->nalloc == 0) return;
+
+ assert(ncap->value != NULL);
+ for (i=0; i<ncap->ndefined; i++) {
+ if (ncap->value[i] != NULL)
+ ncmpii_free_NC_var(ncap->value[i]);
+ }
+
+ free(ncap->value);
+ ncap->value = NULL;
+ ncap->nalloc = 0;
+ ncap->ndefined = 0;
+}
+
+/*----< hdr_get_NC_vararray() >----------------------------------------------*/
+static int
+hdr_get_NC_vararray(bufferinfo *gbp,
+ NC_vararray *ncap)
+{
+ /* netCDF file format:
+ * netcdf_file = header data
+ * header = magic numrecs dim_list gatt_list var_list
+ * ...
+ * var_list = ABSENT | NC_VARIABLE nelems [var ...]
+ * ABSENT = ZERO ZERO | // list is not present for CDF-1 and 2
+ * ZERO ZERO64 // for CDF-5
+ * ZERO = \x00 \x00 \x00 \x00 // 32-bit zero
+ * ZERO64 = \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 // 64-bit zero
+ * NC_VARIABLE = \x00 \x00 \x00 \x0B // tag for list of variables
+ * nelems = NON_NEG // number of elements in following sequence
+ * NON_NEG = <non-negative INT> | // CDF-1 and CDF-2
+ * <non-negative INT64> // CDF-5
+ */
+ int i, status;
+ NCtype type = NC_UNSPECIFIED;
+ size_t ndefined;
+
+ assert(gbp != NULL && gbp->pos != NULL);
+ assert(ncap != NULL);
+ assert(ncap->value == NULL);
+
+ /* get NCtype (NC_VARIABLE) from gbp buffer */
+ status = hdr_get_NCtype(gbp, &type);
+ if (status != NC_NOERR) return status;
+
+ /* get nelems (number of variables) from gbp buffer */
+ if (gbp->version == 5)
+ ndefined = get_uint8(gbp);
+ else
+ ndefined = get_uint4(gbp);
+ ncap->ndefined = (int)ndefined;
+
+ if (ndefined == 0) { /* no variable defined */
+ if (type != NC_VARIABLE && type != NC_UNSPECIFIED)
+ DEBUG_RETURN_ERROR(NC_EINVAL);
+ } else {
+ if (type != NC_VARIABLE)
+ DEBUG_RETURN_ERROR(NC_EINVAL);
+
+ ncap->value = (NC_var **) malloc((size_t)ndefined * sizeof(NC_var*));
+ MALLOC_CHECK(ncap->value)
+ ncap->nalloc = (int)ndefined;
+
+ /* get [var ...] */
+ for (i=0; i<ndefined; i++) {
+ status = hdr_get_NC_var(gbp, ncap->value + i);
+ if (status != NC_NOERR) { /* Error: fail to get the next var */
+ ncap->ndefined = i;
+ ncmpii_free_NC_vararray(ncap);
+ return status;
+ }
+ }
+ }
+
+ return NC_NOERR;
+}
+
+/*----< ncmpii_hdr_get_NC() >------------------------------------------------*/
+/* CDF format specification
+ * netcdf_file = header data
+ * header = magic numrecs dim_list gatt_list var_list
+ * magic = 'C' 'D' 'F' VERSION
+ * VERSION = \x01 | // classic format
+ * \x02 | // 64-bit offset format
+ * \x05 // 64-bit data format
+ * numrecs = NON_NEG | STREAMING // length of record dimension
+ * dim_list = ABSENT | NC_DIMENSION nelems [dim ...]
+ * gatt_list = att_list // global attributes
+ * att_list = ABSENT | NC_ATTRIBUTE nelems [attr ...]
+ * var_list = ABSENT | NC_VARIABLE nelems [var ...]
+ */
+static int
+ncmpii_hdr_get_NC(int fd, NC *ncp)
+{
+ int i, status;
+ bufferinfo getbuf;
+ char *magic;
+
+ /* Initialize the get buffer that stores the header read from the file */
+ getbuf.fd = fd;
+ getbuf.offset = 0; /* read from start of the file */
+ getbuf.size = NC_DEFAULT_CHUNKSIZE;
+ getbuf.base = (void *)malloc((size_t)getbuf.size);
+ MALLOC_CHECK(getbuf.base)
+ getbuf.pos = getbuf.base;
+
+ /* Fetch the next header chunk. The chunk is 'gbp->size' bytes big */
+ status = hdr_fetch(&getbuf);
+ if (status != NC_NOERR) return status;
+
+ /* processing the header from getbuf, the get buffer */
+
+ /* First get the file format information, magic */
+ magic = getbuf.base;
+ getbuf.pos += 4;
+
+ /* don't need to worry about CDF-1 or CDF-2
+ * if the first bits are not 'CDF'
+ */
+ if (memcmp(magic, ncmagic1, sizeof(ncmagic1)-1) != 0) {
+ DEBUG_ASSIGN_ERROR(status, NC_ENOTNC)
+ goto fn_exit;
+ }
+
+ /* check version number in last byte of magic */
+ if (magic[sizeof(ncmagic1)-1] == 0x1) {
+ getbuf.version = 1;
+ ncp->flags = 1;
+ } else if (magic[sizeof(ncmagic1)-1] == 0x2) {
+ getbuf.version = 2;
+ ncp->flags = 2;
+ } else if (magic[sizeof(ncmagic1)-1] == 0x5) {
+ getbuf.version = 5;
+ ncp->flags = 5;
+ } else {
+ DEBUG_ASSIGN_ERROR(status, NC_ENOTNC); /* not an netCDF file */
+ goto fn_exit;
+ }
+
+ /** Ensure that 'nextread' bytes (numrecs) are available. */
+ status = hdr_check_buffer(&getbuf, (getbuf.version == 5) ? 8 : 4);
+ if(status != NC_NOERR) goto fn_exit;
+
+ /* get numrecs from getbuf into ncp */
+ if (getbuf.version == 5)
+ ncp->numrecs = get_uint8(&getbuf);
+ else
+ ncp->numrecs = get_uint4(&getbuf);
+
+ /* get dim_list from getbuf into ncp */
+ status = hdr_get_NC_dimarray(&getbuf, &ncp->dims);
+ if (status != NC_NOERR) goto fn_exit;
+
+ /* get gatt_list from getbuf into ncp */
+ status = hdr_get_NC_attrarray(&getbuf, &ncp->attrs);
+ if (status != NC_NOERR) goto fn_exit;
+
+ /* get var_list from getbuf into ncp */
+ status = hdr_get_NC_vararray(&getbuf, &ncp->vars);
+ if (status != NC_NOERR) goto fn_exit;
+
+ /* get the un-aligned size occupied by the file header */
+ ncp->xsz = ncmpii_hdr_len_NC(ncp);
+
+ /* Recompute the shapes of all variables
+ * Sets ncp->begin_var to start of first variable.
+ * Sets ncp->begin_rec to start of first record variable.
+ */
+ status = ncmpii_NC_computeshapes(ncp);
+
+ /* update the total number of record variables */
+ ncp->vars.num_rec_vars = 0;
+ for (i=0; i<ncp->vars.ndefined; i++)
+ ncp->vars.num_rec_vars += IS_RECVAR(ncp->vars.value[i]);
+
+fn_exit:
+ free(getbuf.base);
+ return status;
+}
+
+/*----< ncmpii_free_NC() >----------------------------------------------------*/
+static void
+ncmpii_free_NC(NC *ncp)
+{
+ if (ncp == NULL) return;
+ ncmpii_free_NC_dimarray(&ncp->dims);
+ ncmpii_free_NC_attrarray(&ncp->attrs);
+ ncmpii_free_NC_vararray(&ncp->vars);
+}
+
+const char *
+ncmpi_strerror(int err)
+{
+ switch(err)
+ {
+ case NC_NOERR:
+ return "No error";
+ case NC_EINVAL:
+ return "NetCDF: Invalid argument";
+ case NC_EBADDIM:
+ return "NetCDF: Invalid dimension ID or name";
+ case NC_EUNLIMPOS:
+ return "NetCDF: NC_UNLIMITED in the wrong index";
+ case NC_ENOTNC:
+ return "NetCDF: Unknown file format";
+ case NC_EVARSIZE:
+ return "NetCDF: One or more variable sizes violate format constraints";
+ default:
+ printf("Unknown error code %d\n",err);
+ return "Unknown error code";
+ }
+}
+
+const char *
+ncmpii_err_code_name(int err)
+{
+ switch(err)
+ {
+ case NC_NOERR: return "NC_NOERR";
+ case NC_EINVAL: return "NC_EINVAL";
+ case NC_EBADDIM: return "NC_EBADDIM";
+ case NC_EUNLIMPOS: return "NC_EUNLIMPOS";
+ case NC_ENOTNC: return "NC_ENOTNC";
+ case NC_EVARSIZE : return "NC_EVARSIZE";
+ default:
+ printf("Unknown error code %d\n",err);
+ return "Unknown error code";
+ }
+}
+
+struct fspec {
+ int nlvars; /* Number of variables specified with -v
+ * option on command line */
+ char** lvars; /* list of variable names specified with -v
+ * option on command line */
+ NC_var **varp; /* [nlvars] */
+ int *varids; /* [nlvars] */
+};
+
+static void
+make_lvars(char *optarg, struct fspec* fspecp)
+{
+ char *cp = optarg;
+ int nvars = 1;
+ char ** cpp;
+
+ /* compute number of variable names in comma-delimited list */
+ fspecp->nlvars = 1;
+ while (*cp++)
+ if (*cp == ',')
+ nvars++;
+
+ fspecp->lvars = (char **) malloc(nvars * sizeof(char*));
+ MALLOC_CHECK(fspecp->lvars)
+
+ cpp = fspecp->lvars;
+ /* copy variable names into list */
+ for (cp = strtok(optarg, ",");
+ cp != NULL;
+ cp = strtok((char *) NULL, ",")) {
+
+ *cpp = (char *) malloc(strlen(cp) + 1);
+ MALLOC_CHECK(*cpp)
+
+ strcpy(*cpp, cp);
+ cpp++;
+ }
+ fspecp->nlvars = nvars;
+ fspecp->varp = (NC_var**) malloc(nvars * sizeof(NC_var*));
+ MALLOC_CHECK(fspecp->varp)
+}
+
+static int
+check_gap_in_fixed_vars(NC *ncp)
+{
+ int i, j;
+ long long size, prev_end;
+ NC_var *varp, *prev;
+
+ /* check only fixed-size variables */
+ for (i=1; i<ncp->vars.ndefined; i++) {
+ varp = ncp->vars.value[i];
+
+ if (IS_RECVAR(varp)) continue;
+
+ /* calculate the size in bytes of this variable */
+ size = type_size(varp->type);
+ if (varp->ndims) size *= varp->dsizes[0];
+
+ /* search for the previous fixed-size variable */
+ prev = NULL;
+ for (j=i-1; j>=0; j--) {
+ if (!IS_RECVAR(ncp->vars.value[j])) {
+ prev = ncp->vars.value[j];
+ break;
+ }
+ }
+ if (prev == NULL) /* first defined fixed-size variable */
+ continue;
+
+ /* not the first fixed-size variable */
+ prev_end = prev->begin;
+ if (prev->ndims == 0)
+ prev_end += type_size(prev->type);
+ else
+ prev_end += type_size(prev->type) * prev->dsizes[0];
+
+ /* check the gap between the begin of this variable from the end of
+ * variable immediately before it */
+ if (varp->begin - prev_end) return 1;
+ }
+ return 0;
+}
+
+static void
+usage(char *cmd)
+{
+ char *help =
+"Usage: %s [-h] | [-x] | [-sgr] [-v var1[,...]] file\n"
+" [-h] Print help\n"
+" [-v var1[,...]] Output for variable(s) <var1>,... only\n"
+" [-s] Output variable size. For record variables, output\n"
+" the size of one record only\n"
+" [-g] Output gap from the previous variable\n"
+" [-r] Output offsets for all records\n"
+" [-x] Check gaps in fixed-size variables, ouput 1 if gaps\n"
+" are found, 0 for otherwise.\n"
+" file Input netCDF file name\n"
+"*Parallel netCDF library version 1.7.0\n";
+ fprintf(stderr, help, cmd);
+}
+
+/*----< main() >-------------------------------------------------------------*/
+int main(int argc, char *argv[])
+{
+ extern int optind;
+ char *filename, cmd[256], *env_str;
+ int i, j, err, opt, nvars;
+ int print_var_size=0, print_gap=0, check_gap=0, print_all_rec=0;
+ NC *ncp;
+ struct fspec *fspecp=NULL;
+
+ fspecp = (struct fspec*) calloc(1, sizeof(struct fspec));
+ strcpy(cmd,argv[0]);
+
+ /* get command-line arguments */
+ while ((opt = getopt(argc, argv, "v:sghqxr")) != EOF) {
+ switch(opt) {
+ case 'v': make_lvars (optarg, fspecp);
+ break;
+ case 's': print_var_size = 1;
+ break;
+ case 'g': print_gap = 1;
+ break;
+ case 'r': print_all_rec = 1;
+ break;
+ case 'x': check_gap = 1;
+ break;
+ case 'h':
+ default: usage(cmd);
+ free(fspecp);
+ return 0;
+ }
+ }
+ argc -= optind;
+ argv += optind;
+ if (argc != 1) {
+ fprintf(stderr, "%s: missing file name\n", cmd);
+ usage(cmd);
+ if (fspecp->varp != NULL) free(fspecp->varp);
+ for (i=0; i<fspecp->nlvars; i++)
+ free(fspecp->lvars[i]);
+ if (fspecp->lvars != NULL) free(fspecp->lvars);
+ free(fspecp);
+ return 1;
+ }
+ filename = argv[0]; /* required argument */
+
+ verbose_debug = 0;
+ env_str = getenv("PNETCDF_VERBOSE_DEBUG_MODE");
+ if (env_str != NULL && *env_str != '0') verbose_debug = 1;
+
+ /* find Endianness of the running machine */
+ endianness = is_little_endian();
+
+ /* open file */
+ int fd = open(filename, O_RDONLY, 0666);
+ if (fd == -1) {
+ printf("Error: file open %s (%s)\n",filename,strerror(errno));
+ exit(1);
+ }
+
+ ncp = (NC*) calloc(1, sizeof(NC));
+ strcpy(ncp->path, filename);
+
+ /* read the header from file */
+ err = ncmpii_hdr_get_NC(fd, ncp);
+ if (err != NC_NOERR) {
+ fprintf(stderr,"Error: %s\n", ncmpii_err_code_name(err));
+ exit(1);
+ }
+
+ if (check_gap) {
+ int ret = check_gap_in_fixed_vars(ncp);
+ ncmpii_free_NC(ncp);
+ free(ncp);
+ close(fd);
+ printf("%d\n",ret);
+ return 0;
+ }
+
+ /* First check if all selected variables can be found in input file. */
+ if (fspecp->nlvars > 0) {
+ /* print a selected list of variables */
+ fspecp->varids = (int*) malloc(fspecp->nlvars * sizeof(int));
+ MALLOC_CHECK(fspecp->varids)
+ for (i=0; i<fspecp->nlvars; i++) {
+ for (j=0; j<ncp->vars.ndefined; j++) {
+ if (!strcmp(fspecp->lvars[i], ncp->vars.value[j]->name->cp)) {
+ fspecp->varp[i] = ncp->vars.value[j];
+ fspecp->varids[i] = j;
+ break;
+ }
+ }
+ if (j == ncp->vars.ndefined) {
+ printf("Error: variable %s not found\n",fspecp->lvars[i]);
+ return 1;
+ }
+ }
+ }
+
+ /* print file name and format */
+ printf("netcdf %s {\n",filename);
+ printf("// file format: CDF-%d\n",ncp->flags);
+ printf("\n");
+
+ /* print file header size and extent */
+ printf("file header:\n");
+ printf("\tsize = %lld bytes\n",ncp->xsz);
+ printf("\textent = %lld bytes\n",ncp->begin_var);
+
+ /* print dimensions */
+ if (ncp->dims.ndefined > 0) printf("\ndimensions:\n");
+ for (i=0; i<ncp->dims.ndefined; i++) {
+ long long size;
+ size = ncp->dims.value[i]->size;
+ printf("\t%s = ",ncp->dims.value[i]->name->cp);
+ if (size == NC_UNLIMITED)
+ printf("UNLIMITED // (%lld currently)\n",ncp->numrecs);
+ else
+ printf("%lld\n",size);
+ }
+
+ if (fspecp->nlvars == 0) { /* print all variables */
+ fspecp = (struct fspec*) malloc(sizeof(struct fspec));
+ MALLOC_CHECK(fspecp)
+ fspecp->varp = (NC_var**) malloc(ncp->vars.ndefined * sizeof(NC_var*));
+ MALLOC_CHECK(fspecp->varp)
+ fspecp->varids = (int*) malloc(ncp->vars.ndefined * sizeof(int));
+ MALLOC_CHECK(fspecp->varids)
+ fspecp->nlvars = ncp->vars.ndefined;
+ fspecp->lvars = NULL;
+ for (i=0; i<ncp->vars.ndefined; i++) {
+ fspecp->varp[i] = ncp->vars.value[i];
+ fspecp->varids[i] = i;
+ }
+ }
+
+ /* find how many variables are record variables */
+ int num_rec_vars = 0;
+ int num_fix_vars = 0;
+ for (i=0; i<fspecp->nlvars; i++) {
+ if (IS_RECVAR(fspecp->varp[i])) num_rec_vars++;
+ else num_fix_vars++;
+ }
+
+ int last_fix_varid = -1;
+ for (i=0; i<ncp->vars.ndefined; i++) {
+ if (IS_RECVAR(ncp->vars.value[i])) continue;
+ last_fix_varid = i;
+ }
+
+ int first_rec_varid = -1;
+ for (i=0; i<ncp->vars.ndefined; i++) {
+ if (IS_RECVAR(ncp->vars.value[i])) {
+ first_rec_varid = i;
+ break;
+ }
+ }
+
+ /* print fixed-size variables first */
+ if (num_fix_vars) printf("\nfixed-size variables:\n");
+ for (i=0; i<fspecp->nlvars; i++) {
+ int j, ndims;
+ char type_str[16], str[1024], line[1024];
+ long long size;
+ NC_var *varp = fspecp->varp[i];
+
+ if (IS_RECVAR(varp)) continue;
+
+ /* calculate the size in bytes of this variable */
+ size = type_size(varp->type);
+ if (varp->ndims) size *= varp->dsizes[0];
+
+ line[0]='\0';
+ sprintf(type_str,"%-6s", type_name(varp->type));
+ sprintf(line,"%s", varp->name->cp);
+ ndims = varp->ndims;
+ if (ndims > 0) strcat(line,"(");
+ for (j=0; j<ndims; j++) {
+ NC_dim *dimp = ncp->dims.value[varp->dimids[j]];
+ if (dimp->size == NC_UNLIMITED)
+ size *= ncp->numrecs;
+ sprintf(str, "%s%s", dimp->name->cp, j < ndims-1 ? ", " : ")");
+ strcat(line, str);
+ }
+
+ /* print the data type, variable name, and its dimensions */
+ printf("\t%6s %s:\n", type_str, line);
+
+ /* print the starting and ending file offset of this variable */
+ printf("\t start file offset =%12lld\n", varp->begin);
+ printf("\t end file offset =%12lld\n", varp->begin+size);
+
+ /* print variable size in bytes */
+ if (print_var_size)
+ printf("\t size in bytes =%12lld\n", size);
+
+ /* print the gap between the begin of this variable from the end of
+ * variable immediately before it */
+ if (print_gap) {
+ NC_var *prev=NULL;
+ for (j=fspecp->varids[i]-1; j>=0; j--) {
+ /* search for the previous fixed-size variable */
+ if (!IS_RECVAR(ncp->vars.value[j])) {
+ prev = ncp->vars.value[j];
+ break;
+ }
+ }
+ if (fspecp->varids[i] == 0 || prev == NULL) {
+ /* first defined fixed-size variable */
+ printf("\t gap from prev var =%12lld\n",
+ varp->begin - ncp->xsz);
+ }
+ else {
+ /* not the first fixed-size variable */
+ long long prev_end = prev->begin;
+ if (prev->ndims == 0)
+ prev_end += type_size(prev->type);
+ else
+ prev_end += type_size(prev->type) * prev->dsizes[0];
+ printf("\t gap from prev var =%12lld\n",
+ varp->begin - prev_end);
+ }
+ }
+ }
+
+ /* print record variables */
+ if (num_rec_vars) printf("\nrecord variables:\n");
+ for (i=0; i<fspecp->nlvars; i++) {
+ int j, ndims;
+ char type_str[16], str[1024], line[1024];
+ long long var_begin, var_end, size, numrecs;
+ NC_var *varp = fspecp->varp[i];
+
+ if (!IS_RECVAR(varp)) continue;
+
+ /* calculate the size in bytes of this variable */
+ size = type_size(varp->type);
+ if (varp->ndims) size *= varp->dsizes[0];
+
+ line[0]='\0';
+ sprintf(type_str,"%-6s", type_name(varp->type));
+ sprintf(line,"%s", varp->name->cp);
+ ndims = varp->ndims;
+ if (ndims > 0) strcat(line,"(");
+ for (j=0; j<ndims; j++) {
+ NC_dim *dimp = ncp->dims.value[varp->dimids[j]];
+ sprintf(str, "%s%s", dimp->name->cp, j < ndims-1 ? ", " : ")");
+ strcat(line, str);
+ }
+
+ /* print the data type, variable name, and its dimensions */
+ printf("\t%6s %s:\n", type_str, line);
+
+ /* print the starting and ending file offset of this variable */
+ numrecs = ncp->numrecs;
+ var_begin = varp->begin;
+ var_end = varp->begin + size;
+ if (print_all_rec == 0) numrecs = 1;
+ for (j=0; j<numrecs; j++) {
+ char rec_num[32];
+ if (j % 10 == 1) sprintf(rec_num, "%dst", j);
+ else if (j % 10 == 2) sprintf(rec_num, "%dnd", j);
+ else if (j % 10 == 3) sprintf(rec_num, "%drd", j);
+ else sprintf(rec_num, "%dth", j);
+ printf("\t start file offset =%12lld (%s record)\n", var_begin,rec_num);
+ printf("\t end file offset =%12lld (%s record)\n", var_end,rec_num);
+ var_begin += ncp->recsize;
+ var_end += ncp->recsize;
+ }
+
+ /* print variable size in bytes (one record only)
+ * size *= ncp->numrecs; (if for all records)
+ */
+ if (print_var_size)
+ printf("\t size in bytes =%12lld (of one record)\n", size);
+
+ /* print the gap between the begin of this variable from the end of
+ * variable immediately before it */
+ if (print_gap) {
+ NC_var *prev=NULL;
+ long long prev_end;
+ for (j=fspecp->varids[i]-1; j>=0; j--) {
+ /* search for the previous record variable */
+ if (IS_RECVAR(ncp->vars.value[j])) {
+ prev = ncp->vars.value[j];
+ break;
+ }
+ }
+ if (fspecp->varids[i] == 0 && last_fix_varid == -1) {
+ /* first record variable and no fixed-size variable */
+ printf("\t gap from prev var =%12lld\n",
+ varp->begin - ncp->xsz);
+ }
+ else if (fspecp->varids[i] == first_rec_varid) {
+ /* first record variable and there are fixed-size variables */
+ prev = ncp->vars.value[last_fix_varid];
+ prev_end = prev->begin;
+ if (prev->ndims == 0)
+ prev_end += type_size(prev->type);
+ else
+ prev_end += type_size(prev->type) * prev->dsizes[0];
+ printf("\t gap from prev var =%12lld\n",
+ varp->begin - prev_end);
+ }
+ else {
+ /* not the first record variable */
+ prev_end = prev->begin;
+ if (prev->ndims == 0)
+ prev_end += type_size(prev->type);
+ else
+ prev_end += type_size(prev->type) * prev->dsizes[0];
+ printf("\t gap from prev var =%12lld\n",
+ varp->begin - prev_end);
+ }
+ }
+ }
+ printf("}\n");
+
+ free(fspecp->varp);
+ if (fspecp->lvars != NULL) {
+ for (i=0; i<fspecp->nlvars; i++)
+ free(fspecp->lvars[i]);
+ free(fspecp->lvars);
+ }
+ free(fspecp->varids);
+ free(fspecp);
+ ncmpii_free_NC(ncp);
+ free(ncp);
+ close(fd);
+
+ return 0;
+}
+
diff --git a/src/utils/pnetcdf_version/Makefile.in b/src/utils/pnetcdf_version/Makefile.in
new file mode 100644
index 0000000..1d6e216
--- /dev/null
+++ b/src/utils/pnetcdf_version/Makefile.in
@@ -0,0 +1,56 @@
+#
+# Copyright (C) 2014, Northwestern University and Argonne National Laboratory
+# See COPYRIGHT notice in top-level directory.
+#
+# $Id: Makefile.in 2264 2015-12-22 15:42:59Z wkliao $
+#
+# @configure_input@
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+include ../../../macros.make
+
+DEFS = -DMPICC="\"$(MPICC)\"" -DCFLAGS="\"$(CFLAGS)\""
+DEFS += -DCONFIGURE_ARGS_CLEAN="\"@CONFIGURE_ARGS_CLEAN@\""
+DEFS += -DPNETCDF_VERSION="\"@PNETCDF_VERSION@\""
+DEFS += -DPNETCDF_RELEASE_DATE="\"@PNETCDF_RELEASE_DATE@\""
+
+ifeq (@has_mpicxx@, yes)
+DEFS += -DMPICXX="\"$(MPICXX)\"" -DCXXFLAGS="\"$(CXXFLAGS)\""
+endif
+
+ifeq (@has_fortran@, yes)
+DEFS += -DMPIF77="\"$(MPIF77)\"" -DF77FLAGS="\"$(F77FLAGS)\""
+DEFS += -DMPIF90="\"$(MPIF90)\"" -DF90FLAGS="\"$(F90FLAGS)\""
+endif
+
+C_SOURCES = pnetcdf_version.c
+
+PROGRAM = pnetcdf_version
+MANUAL = pnetcdf_version.1
+
+PACKING_LIST = $(C_SOURCES) $(MANUAL) \
+ Makefile.in depend
+
+GARBAGE = $(PROGRAM)
+
+all: $(PROGRAM)
+
+pnetcdf_version: pnetcdf_version.c
+ $(SEQ_CC) $(DEFS) -o $@ $<
+
+install: $(PROGRAM) $(MANUAL)
+ $(INSTALL) -d -m 755 $(MANDIR)/man1
+ $(INSTALL_DATA) $(srcdir)/$(MANUAL) $(MANDIR)/man1/$(MANUAL)
+ $(INSTALL) -d $(BINDIR)
+ $(INSTALL) -m 755 $(PROGRAM) $(BINDIR)/$(PROGRAM)
+
+uninstall:
+ $(RM) -f $(BINDIR)/$(PROGRAM)
+ $(RM) -f $(MANDIR)/man1/$(MANUAL)
+
+include $(srcdir)/../../../rules.make
+include $(srcdir)/depend
+
+.PHONY: $(LIBRARY)
diff --git a/src/utils/pnetcdf_version/depend b/src/utils/pnetcdf_version/depend
new file mode 100644
index 0000000..568a29a
--- /dev/null
+++ b/src/utils/pnetcdf_version/depend
@@ -0,0 +1 @@
+pnetcdf_version.o: pnetcdf_version.c
diff --git a/src/utils/pnetcdf_version/pnetcdf_version.1 b/src/utils/pnetcdf_version/pnetcdf_version.1
new file mode 100644
index 0000000..35463d9
--- /dev/null
+++ b/src/utils/pnetcdf_version/pnetcdf_version.1
@@ -0,0 +1,61 @@
+.\" $Header$
+.nr yr \n(yr+1900
+.af mo 01
+.af dy 01
+.TH PNETCDF_VERSION 1 2014-04-15 "Printed: \n(yr-\n(mo-\n(dy" "UTILITIES"
+.SH NAME
+pnetcdf_version \- print the version information of PnetCDF library
+.SH SYNOPSIS
+.ft B
+.HP
+pnetcdf_version
+.nh
+
+\%[-v]
+\%[-d]
+\%[-c]
+\%[-b]
+\%[-h]
+.hy
+.ft
+.SH DESCRIPTION
+\fBpnetcdf_version\fP prints the version information of PnetCDF library and
+the configure command line used to build the library
+
+If no argument is given, all information is printed.
+.SH OPTIONS
+.IP "\fB-v\fP"
+Version number of this PnetCDF release.
+.IP "\fB-d\fP"
+Release date.
+.IP "\fB-c\fP"
+Configure command-line arguments used to build this PnetCDF
+.IP "\fB-b\fP"
+MPI compilers used to build this PnetCDF library
+.IP "\fB-h\fP"
+Print the available command-line options of pnetcdf_version
+
+.SH EXAMPLES
+.LP
+Print all information about the PnetCDF library by running the command with no options.
+
+% pnetcdf_version
+.sp
+.nf
+PnetCDF Version: 1.4.2.pre1
+PnetCDF Release date: 15 Apr 2014
+PnetCDF configure: --with-mpi=/usr/local/bin
+MPICC: /usr/local/bin/mpicc -g -O2
+MPICXX: /usr/local/bin/mpicxx -g -O2
+MPIF77: /usr/local/bin/mpif77 -g -O2
+MPIF90: /usr/local/bin/mpif90 -g -O2
+.fi
+
+.SH "SEE ALSO"
+.LP
+.BR pnetcdf (3)
+.SH DATE
+$Date: 2014-07-11 13:07:40 -0500 (Fri, 11 Jul 2014) $
+.LP
+
+
diff --git a/src/utils/pnetcdf_version/pnetcdf_version.c b/src/utils/pnetcdf_version/pnetcdf_version.c
new file mode 100644
index 0000000..bfae58b
--- /dev/null
+++ b/src/utils/pnetcdf_version/pnetcdf_version.c
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2014, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ */
+/* $Id: pnetcdf_version.c 2264 2015-12-22 15:42:59Z wkliao $ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h> /* getopt */
+
+typedef enum {
+ Version_number = 0,
+ Date = 1,
+ Patches = 2,
+ Configure_args = 3,
+ Compilers = 4,
+ LastField
+} fields;
+
+/*
+ * pnetcdf_version - Report on the PnetCDF version
+ */
+
+/*---< usage() >-------------------------------------------------------------*/
+static void usage(char *argv0) {
+ char *help =
+ "Usage: %s [switches]\n"
+ " -v : version number\n"
+ " -d : release date\n"
+ " -c : configure arguments used to build PnetCDF\n"
+ " -b : MPI compilers used\n"
+ " -h : print this help (available command-line options)\n";
+ fprintf(stderr, help, argv0);
+ exit(-1);
+}
+
+/*----< main() >-------------------------------------------------------------*/
+int main( int argc, char *argv[] )
+{
+ int opt;
+
+ int i, flags[10];
+
+ if (argc <= 1) {
+ /* Show all values */
+ for (i=0; i<LastField; i++) flags[i] = 1;
+ }
+ else {
+ /* Show only requested values */
+ for (i=0; i<LastField; i++) flags[i] = 0;
+ }
+
+ while ( (opt=getopt(argc,argv,"vdcbh"))!= EOF) {
+ switch (opt) {
+ case 'v': flags[Version_number] = 1;
+ break;
+ case 'd': flags[Date] = 1;
+ break;
+ case 'c': flags[Configure_args] = 1;
+ break;
+ case 'b': flags[Compilers] = 1;
+ break;
+ case 'h':
+ default: usage(argv[0]);
+ break;
+ }
+ }
+
+ /* Print out the information, one item per line */
+ if (flags[Version_number]) {
+ printf( "PnetCDF Version: \t%s\n", PNETCDF_VERSION);
+ }
+ if (flags[Date]) {
+ printf( "PnetCDF Release date:\t%s\n", PNETCDF_RELEASE_DATE);
+ }
+ if (flags[Configure_args]) {
+ printf( "PnetCDF configure: \t%s\n", CONFIGURE_ARGS_CLEAN);
+ }
+ if (flags[Compilers]) {
+ if (strcmp(CFLAGS, ""))
+ printf( "MPICC: %s %s\n", MPICC, CFLAGS);
+ else
+ printf( "MPICC: %s\n", MPICC);
+#ifdef MPICXX
+ if (strcmp(CXXFLAGS, ""))
+ printf( "MPICXX: %s %s\n", MPICXX, CXXFLAGS);
+ else
+ printf( "MPICXX: %s\n", MPICXX);
+#endif
+#ifdef MPIF77
+ if (strcmp(F77FLAGS, ""))
+ printf( "MPIF77: %s %s\n", MPIF77, F77FLAGS);
+ else
+ printf( "MPIF77: %s\n", MPIF77);
+#endif
+#ifdef MPIF90
+ if (strcmp(F90FLAGS, ""))
+ printf( "MPIF90: %s %s\n", MPIF90, F90FLAGS);
+ else
+ printf( "MPIF90: %s\n", MPIF90);
+#endif
+ }
+
+ return 0;
+}
+
diff --git a/stamp-h.in b/stamp-h.in
new file mode 100644
index 0000000..9788f70
--- /dev/null
+++ b/stamp-h.in
@@ -0,0 +1 @@
+timestamp
diff --git a/test/C/Makefile.in b/test/C/Makefile.in
new file mode 100644
index 0000000..3501c82
--- /dev/null
+++ b/test/C/Makefile.in
@@ -0,0 +1,76 @@
+#
+# Copyright (C) 2003, Northwestern University and Argonne National Laboratory
+# See COPYRIGHT notice in top-level directory.
+#
+# $Id: Makefile.in 2259 2015-12-22 04:51:01Z wkliao $
+#
+# @configure_input@
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+include ../../macros.make
+
+INCLUDES = -I../../src/lib -I$(srcdir)/../common
+LDFLAGS := $(LDFLAGS) -L../common
+LIBS := $(LIBRARY) -ltestutils $(LIBS) @LCOV_LIB@
+ifeq (@PNC_DEBUG@, yes)
+CPPFLAGS := $(CPPFLAGS) -DPNC_DEBUG
+endif
+
+SRCS = pres_temp_4D_wr.c \
+ pres_temp_4D_rd.c
+
+OBJS = $(SRCS:.c=.o)
+PROGS = $(SRCS:.c=)
+
+GARBAGE = $(PROGS) *.nc
+PACKING_LIST = $(SRCS) Makefile.in
+
+all: $(PROGS)
+
+$(OBJS): $(srcdir)/../common/testutils.h
+
+$(PROGS): ../common/libtestutils.a
+
+../common/libtestutils.a:
+ set -e; cd ../common && $(MAKE) $(MFLAGS) all
+
+pres_temp_4D_wr.o: pres_temp_4D_wr.c
+
+pres_temp_4D_wr: pres_temp_4D_wr.o $(LIBRARY)
+ $(LINK.c) $< $(LDFLAGS) $(LIBS)
+
+pres_temp_4D_rd.o: pres_temp_4D_rd.c
+
+pres_temp_4D_rd: pres_temp_4D_rd.o $(LIBRARY)
+ $(LINK.c) $< $(LDFLAGS) $(LIBS)
+
+check testing verbose_testing: $(PROGS)
+ @for i in $(PROGS); do ( \
+ $(TEST_SEQRUN) ./$$i $(TEST_OUTDIR)/testfile.nc \
+ ; ) ; done
+
+TEST_MPIRUN_2 = $(subst NP,2,$(TEST_MPIRUN))
+TEST_MPIRUN_4 = $(subst NP,4,$(TEST_MPIRUN))
+
+ptest2: $(PROGS)
+ @for i in $(PROGS); do ( \
+ $(TEST_MPIRUN_2) ./$$i $(TEST_OUTDIR)/testfile.nc \
+ ; ) ; done
+
+ptest4: $(PROGS)
+ @for i in $(PROGS); do ( \
+ $(TEST_MPIRUN_4) ./$$i $(TEST_OUTDIR)/testfile.nc \
+ ; ) ; done
+
+ptest: ptest4
+
+ptests: ptest2 ptest4
+
+ptest6 ptest8 ptest10:
+
+include $(srcdir)/../../rules.make
+
+$(LIBRARY): ;
+
diff --git a/test/C/pres_temp_4D_rd.c b/test/C/pres_temp_4D_rd.c
new file mode 100644
index 0000000..315417f
--- /dev/null
+++ b/test/C/pres_temp_4D_rd.c
@@ -0,0 +1,205 @@
+/*
+ * Copyright (C) 2003, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ */
+/* $Id: pres_temp_4D_rd.c 2133 2015-09-26 19:16:01Z wkliao $ */
+
+/*
+ This is an example which reads some 4D pressure and
+ temperatures. The data file read by this program is produced by the
+ companion program pres_temp_4D_wr.c. It is intended to illustrate
+ the use of the netCDF C API.
+
+ This program is part of the netCDF tutorial:
+ http://www.unidata.ucar.edu/software/netcdf/docs/netcdf-tutorial
+
+ Full documentation of the netCDF C API can be found at:
+ http://www.unidata.ucar.edu/software/netcdf/docs/netcdf-c
+
+ $Id: pres_temp_4D_rd.c 2133 2015-09-26 19:16:01Z wkliao $
+*/
+
+#include <stdio.h>
+#include <string.h>
+#include <pnetcdf.h>
+#include <mpi.h>
+#include <testutils.h>
+
+/* This is the name of the data file we will read. */
+#define FILE_NAME "pres_temp_4D.nc"
+
+/* We are reading 4D data, a 2 x 6 x 12 lvl-lat-lon grid, with 2
+ timesteps of data. */
+#define NDIMS 4
+#define NLAT 6
+#define NLON 12
+#define LAT_NAME "latitude"
+#define LON_NAME "longitude"
+#define NREC 2
+#define REC_NAME "time"
+#define LVL_NAME "level"
+#define NLVL 4
+
+/* Names of things. */
+#define PRES_NAME "pressure"
+#define TEMP_NAME "temperature"
+#define UNITS "units"
+#define DEGREES_EAST "degrees_east"
+#define DEGREES_NORTH "degrees_north"
+
+/* These are used to calculate the values we expect to find. */
+#define SAMPLE_PRESSURE 900
+#define SAMPLE_TEMP 9.0
+#define START_LAT 25.0
+#define START_LON -125.0
+
+/* For the units attributes. */
+#define UNITS "units"
+#define PRES_UNITS "hPa"
+#define TEMP_UNITS "celsius"
+#define LAT_UNITS "degrees_north"
+#define LON_UNITS "degrees_east"
+#define MAX_ATT_LEN 80
+
+/* Handle errors by printing an error message and exiting with a
+ * non-zero status. */
+#define CHECK_ERR { \
+ if (err != NC_NOERR) { \
+ nerrs++; \
+ printf("Error: %s a5 line %d (%s)\n", __FILE__,__LINE__,ncmpi_strerror(err)); } }
+
+
+int
+main(int argc, char **argv)
+{
+ int rank, nprocs, ncid, pres_varid, temp_varid;
+ int lat_varid, lon_varid;
+
+ /* The start and count arrays will tell the netCDF library where to
+ read our data. */
+ MPI_Offset start[NDIMS], count[NDIMS];
+
+ /* Program variables to hold the data we will read. We will only
+ need enough space to hold one timestep of data; one record. */
+ float pres_in[NLVL][NLAT][NLON];
+ float temp_in[NLVL][NLAT][NLON];
+
+ /* These program variables hold the latitudes and longitudes. */
+ float lats[NLAT], lons[NLON];
+
+ /* Loop indexes. */
+ int lvl, lat, lon, rec, i = 0;
+
+ /* Error handling. */
+ int err, nerrs=0;
+
+ char *filename = FILE_NAME;
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+
+ if (argc > 2) {
+ if (!rank) printf("Usage: %s [filename]\n",argv[0]);
+ MPI_Finalize();
+ return 0;
+ }
+ if (argc == 2) filename = argv[1];
+
+ if (rank == 0) {
+ char cmd_str[256];
+ sprintf(cmd_str, "*** TESTING C %s for reading file", argv[0]);
+ printf("%-66s ------ ", cmd_str);
+ }
+
+ /* Open the file. */
+ err = ncmpi_open(MPI_COMM_WORLD, filename, NC_NOWRITE, MPI_INFO_NULL, &ncid);
+ CHECK_ERR
+
+ /* Get the varids of the latitude and longitude coordinate
+ * variables. */
+ err = ncmpi_inq_varid(ncid, LAT_NAME, &lat_varid);
+ CHECK_ERR
+ err = ncmpi_inq_varid(ncid, LON_NAME, &lon_varid);
+ CHECK_ERR
+
+ /* Read the coordinate variable data. */
+ err = ncmpi_get_var_float_all(ncid, lat_varid, &lats[0]);
+ CHECK_ERR
+ err = ncmpi_get_var_float_all(ncid, lon_varid, &lons[0]);
+ CHECK_ERR
+
+ /* Check the coordinate variable data. */
+ for (lat = 0; lat < NLAT; lat++)
+ if (lats[lat] != START_LAT + 5.*lat)
+ return 2;
+ for (lon = 0; lon < NLON; lon++)
+ if (lons[lon] != START_LON + 5.*lon)
+ return 2;
+
+ /* Get the varids of the pressure and temperature netCDF
+ * variables. */
+ err = ncmpi_inq_varid(ncid, PRES_NAME, &pres_varid);
+ CHECK_ERR
+ err = ncmpi_inq_varid(ncid, TEMP_NAME, &temp_varid);
+ CHECK_ERR
+
+ /* Read the data. Since we know the contents of the file we know
+ * that the data arrays in this program are the correct size to
+ * hold one timestep. */
+ count[0] = 1;
+ count[1] = NLVL/nprocs;
+ count[2] = NLAT;
+ count[3] = NLON;
+ start[1] = 0;
+ start[2] = 0;
+ start[3] = 0;
+
+ /* Read and check one record at a time. */
+ for (rec = 0; rec < NREC; rec++)
+ {
+ start[0] = rec;
+ err = ncmpi_get_vara_float_all(ncid, pres_varid, start,
+ count, &pres_in[0][0][0]);
+ CHECK_ERR
+ err = ncmpi_get_vara_float_all(ncid, temp_varid, start,
+ count, &temp_in[0][0][0]);
+ CHECK_ERR
+
+ /* Check the data. */
+ i = 0;
+ for (lvl = 0; lvl < NLVL/nprocs; lvl++)
+ for (lat = 0; lat < NLAT; lat++)
+ for (lon = 0; lon < NLON; lon++)
+ {
+ if (pres_in[lvl][lat][lon] != SAMPLE_PRESSURE + i)
+ return 2;
+ if (temp_in[lvl][lat][lon] != SAMPLE_TEMP + i)
+ return 2;
+ i++;
+ }
+
+ } /* next record */
+
+ /* Close the file. */
+ err = ncmpi_close(ncid);
+ CHECK_ERR
+
+ /* check if there is any malloc residue */
+ MPI_Offset malloc_size, sum_size;
+ err = ncmpi_inq_malloc_size(&malloc_size);
+ if (err == NC_NOERR) {
+ MPI_Reduce(&malloc_size, &sum_size, 1, MPI_OFFSET, MPI_SUM, 0, MPI_COMM_WORLD);
+ if (rank == 0 && sum_size > 0)
+ printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n",
+ sum_size);
+ }
+
+ if (rank == 0) {
+ if (nerrs) printf(FAIL_STR,nerrs);
+ else printf(PASS_STR);
+ }
+
+ MPI_Finalize();
+ return 0;
+}
diff --git a/test/C/pres_temp_4D_wr.c b/test/C/pres_temp_4D_wr.c
new file mode 100644
index 0000000..325692a
--- /dev/null
+++ b/test/C/pres_temp_4D_wr.c
@@ -0,0 +1,262 @@
+/*
+ * Copyright (C) 2003, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ */
+/* $Id: pres_temp_4D_wr.c 2133 2015-09-26 19:16:01Z wkliao $ */
+
+
+/*
+ This is an example program which writes some 4D pressure and
+ temperatures. It is intended to illustrate the use of the netCDF
+ C API. The companion program pres_temp_4D_rd.c shows how
+ to read the netCDF data file created by this program.
+
+ This program is part of the netCDF tutorial:
+ http://www.unidata.ucar.edu/software/netcdf/docs/netcdf-tutorial
+
+ Full documentation of the netCDF C API can be found at:
+ http://www.unidata.ucar.edu/software/netcdf/docs/netcdf-c
+
+ $Id: pres_temp_4D_wr.c 2133 2015-09-26 19:16:01Z wkliao $
+*/
+
+#include <stdio.h>
+#include <string.h>
+#include <pnetcdf.h>
+#include <mpi.h>
+#include <testutils.h>
+
+/* This is the name of the data file we will create. */
+#define FILE_NAME "pres_temp_4D.nc"
+
+/* We are writing 4D data, a 2 x 6 x 12 lvl-lat-lon grid, with 2
+ timesteps of data. */
+#define NDIMS 4
+#define NLAT 6
+#define NLON 12
+#define LAT_NAME "latitude"
+#define LON_NAME "longitude"
+#define NREC 2
+#define REC_NAME "time"
+#define LVL_NAME "level"
+#define NLVL 4
+
+/* Names of things. */
+#define PRES_NAME "pressure"
+#define TEMP_NAME "temperature"
+#define UNITS "units"
+#define DEGREES_EAST "degrees_east"
+#define DEGREES_NORTH "degrees_north"
+
+/* These are used to construct some example data. */
+#define SAMPLE_PRESSURE 900
+#define SAMPLE_TEMP 9.0
+#define START_LAT 25.0
+#define START_LON -125.0
+
+/* For the units attributes. */
+#define UNITS "units"
+#define PRES_UNITS "hPa"
+#define TEMP_UNITS "celsius"
+#define LAT_UNITS "degrees_north"
+#define LON_UNITS "degrees_east"
+#define MAX_ATT_LEN 80
+
+/* Handle errors by printing an error message and exiting with a
+ * non-zero status. */
+#define ERR(e) {printf("Error: %s\n", nc_strerror(e)); return 2;}
+
+#define CHECK_ERR { \
+ if (err != NC_NOERR) { \
+ nerrs++; \
+ printf("Error: %s at line %d: %s\n", __FILE__,__LINE__,ncmpi_strerror(err)); \
+ } \
+}
+
+
+int
+main(int argc, char ** argv)
+{
+ /* IDs for the netCDF file, dimensions, and variables. */
+ int nprocs, rank, nerrs=0;
+ int ncid;
+ int lon_dimid, lat_dimid, lvl_dimid, rec_dimid;
+ int lat_varid, lon_varid, pres_varid, temp_varid;
+ int dimids[NDIMS];
+
+ /* The start and count arrays will tell the netCDF library where to
+ write our data. */
+ MPI_Offset start[NDIMS], count[NDIMS];
+
+ /* Program variables to hold the data we will write out. We will only
+ need enough space to hold one timestep of data; one record. */
+ float pres_out[NLVL][NLAT][NLON];
+ float temp_out[NLVL][NLAT][NLON];
+
+ /* These program variables hold the latitudes and longitudes. */
+ float lats[NLAT], lons[NLON];
+
+ /* Loop indexes. */
+ int lvl, lat, lon, rec, i = 0;
+
+ /* Error handling. */
+ int err;
+
+ char *filename=FILE_NAME;
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+
+ if (argc > 2) {
+ if (!rank) printf("Usage: %s [filename]\n",argv[0]);
+ MPI_Finalize();
+ return 0;
+ }
+ if (argc == 2) filename = argv[1];
+
+ if (rank == 0) {
+ char cmd_str[256];
+ sprintf(cmd_str, "*** TESTING C %s for writing file", argv[0]);
+ printf("%-66s ------ ", cmd_str);
+ }
+
+ /* Create some pretend data. If this wasn't an example program, we
+ * would have some real data to write, for example, model
+ * output. */
+ for (lat = 0; lat < NLAT; lat++)
+ lats[lat] = START_LAT + 5.*lat;
+ for (lon = 0; lon < NLON; lon++)
+ lons[lon] = START_LON + 5.*lon;
+
+ for (lvl = 0; lvl < NLVL; lvl++)
+ for (lat = 0; lat < NLAT; lat++)
+ for (lon = 0; lon < NLON; lon++)
+ {
+ pres_out[lvl][lat][lon] = SAMPLE_PRESSURE + i;
+ temp_out[lvl][lat][lon] = SAMPLE_TEMP + i++;
+ }
+
+ /* Create the file. */
+ err = ncmpi_create(MPI_COMM_WORLD, filename, NC_CLOBBER, MPI_INFO_NULL, &ncid);
+
+ CHECK_ERR
+
+ /* Define the dimensions. The record dimension is defined to have
+ * unlimited length - it can grow as needed. In this example it is
+ * the time dimension.*/
+ err = ncmpi_def_dim(ncid, LVL_NAME, NLVL, &lvl_dimid);
+ CHECK_ERR
+ err = ncmpi_def_dim(ncid, LAT_NAME, NLAT, &lat_dimid);
+ CHECK_ERR
+ err = ncmpi_def_dim(ncid, LON_NAME, NLON, &lon_dimid);
+ CHECK_ERR
+ err = ncmpi_def_dim(ncid, REC_NAME, NC_UNLIMITED, &rec_dimid);
+ CHECK_ERR
+
+ /* Define the coordinate variables. We will only define coordinate
+ variables for lat and lon. Ordinarily we would need to provide
+ an array of dimension IDs for each variable's dimensions, but
+ since coordinate variables only have one dimension, we can
+ simply provide the address of that dimension ID (&lat_dimid) and
+ similarly for (&lon_dimid). */
+ err = ncmpi_def_var(ncid, LAT_NAME, NC_FLOAT, 1, &lat_dimid, &lat_varid);
+ CHECK_ERR
+ err = ncmpi_def_var(ncid, LON_NAME, NC_FLOAT, 1, &lon_dimid, &lon_varid);
+ CHECK_ERR
+
+ /* Assign units attributes to coordinate variables. */
+ err = ncmpi_put_att_text(ncid, lat_varid, UNITS,
+ strlen(DEGREES_NORTH), DEGREES_NORTH);
+ CHECK_ERR
+ err = ncmpi_put_att_text(ncid, lon_varid, UNITS,
+ strlen(DEGREES_EAST), DEGREES_EAST);
+ CHECK_ERR
+
+ /* The dimids array is used to pass the dimids of the dimensions of
+ the netCDF variables. Both of the netCDF variables we are
+ creating share the same four dimensions. In C, the
+ unlimited dimension must come first on the list of dimids. */
+ dimids[0] = rec_dimid;
+ dimids[1] = lvl_dimid;
+ dimids[2] = lat_dimid;
+ dimids[3] = lon_dimid;
+
+ /* Define the netCDF variables for the pressure and temperature
+ * data. */
+ err = ncmpi_def_var(ncid, PRES_NAME, NC_FLOAT, NDIMS, dimids, &pres_varid);
+ CHECK_ERR
+ err = ncmpi_def_var(ncid, TEMP_NAME, NC_FLOAT, NDIMS, dimids, &temp_varid);
+ CHECK_ERR
+
+ /* Assign units attributes to the netCDF variables. */
+ err = ncmpi_put_att_text(ncid, pres_varid, UNITS,
+ strlen(PRES_UNITS), PRES_UNITS);
+ CHECK_ERR
+ err = ncmpi_put_att_text(ncid, temp_varid, UNITS,
+ strlen(TEMP_UNITS), TEMP_UNITS);
+ CHECK_ERR
+
+ /* End define mode. */
+ err = ncmpi_enddef(ncid);
+ CHECK_ERR
+
+ err = ncmpi_begin_indep_data(ncid);
+ /* Write the coordinate variable data. This will put the latitudes
+ and longitudes of our data grid into the netCDF file. */
+ err = ncmpi_put_var_float(ncid, lat_varid, &lats[0]);
+ CHECK_ERR
+ err = ncmpi_put_var_float(ncid, lon_varid, &lons[0]);
+ CHECK_ERR
+ err = ncmpi_end_indep_data(ncid);
+ CHECK_ERR
+
+ /* These settings tell netcdf to write one timestep of data. (The
+ setting of start[0] inside the loop below tells netCDF which
+ &data[0][0][0]);
+ timestep to write.) */
+ count[0] = 1;
+ count[1] = NLVL/nprocs;
+ count[2] = NLAT;
+ count[3] = NLON;
+ start[1] = 0;
+ start[2] = 0;
+ start[3] = 0;
+
+ /* Write the pretend data. This will write our surface pressure and
+ surface temperature data. The arrays only hold one timestep worth
+ of data. We will just rewrite the same data for each timestep. In
+ a real application, the data would change between timesteps. */
+
+ for (rec = 0; rec < NREC; rec++)
+ {
+ start[0] = rec;
+ err = ncmpi_put_vara_float_all(ncid, pres_varid, start, count, &pres_out[0][0][0]);
+ CHECK_ERR
+ err = ncmpi_put_vara_float_all(ncid, temp_varid, start, count, &temp_out[0][0][0]);
+ CHECK_ERR
+ }
+
+ /* Close the file. */
+ err = ncmpi_close(ncid);
+ CHECK_ERR
+
+ /* check if there is any malloc residue */
+ MPI_Offset malloc_size, sum_size;
+ err = ncmpi_inq_malloc_size(&malloc_size);
+ if (err == NC_NOERR) {
+ MPI_Reduce(&malloc_size, &sum_size, 1, MPI_OFFSET, MPI_SUM, 0, MPI_COMM_WORLD);
+ if (rank == 0 && sum_size > 0)
+ printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n",
+ sum_size);
+ }
+
+ if (rank == 0) {
+ if (nerrs) printf(FAIL_STR,nerrs);
+ else printf(PASS_STR);
+ }
+
+ MPI_Finalize();
+
+ return 0;
+}
diff --git a/test/CXX/Makefile.in b/test/CXX/Makefile.in
new file mode 100644
index 0000000..beadd0e
--- /dev/null
+++ b/test/CXX/Makefile.in
@@ -0,0 +1,79 @@
+#
+# Copyright (C) 2014, Northwestern University and Argonne National Laboratory
+# See COPYRIGHT notice in top-level directory.
+#
+# $Id: Makefile.in 2251 2015-12-20 21:13:42Z wkliao $
+#
+# @configure_input@
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+include ../../macros.make
+
+INCLUDES = -I../../src/lib -I../../src/libcxx -I$(srcdir)/../common
+LDFLAGS := $(LDFLAGS) -L../common
+LIBS := $(LIBRARY) -ltestutils $(LIBS) @LCOV_LIB@
+ifeq (@PNC_DEBUG@, yes)
+CXXCPPFLAGS := $(CXXCPPFLAGS) -DPNC_DEBUG
+endif
+
+SRCS = nctst.cpp \
+ test_classic.cpp
+
+OBJS = $(SRCS:.cpp=.o)
+PROGS = $(SRCS:.cpp=)
+
+GARBAGE = $(PROGS) *.nc
+PACKING_LIST = $(SRCS) Makefile.in
+
+all: $(PROGS)
+
+$(OBJS): $(srcdir)/../common/testutils.h
+
+$(PROGS): ../common/libtestutils.a
+
+../common/libtestutils.a:
+ set -e; cd ../common && $(MAKE) $(MFLAGS) all
+
+nctst.o: nctst.cpp
+
+nctst: nctst.o $(LIBRARY) $(LIBRARY)
+ $(LINK.cxx) $< $(LDFLAGS) $(LIBS)
+
+test_classic.o: test_classic.cpp
+
+test_classic: test_classic.o $(LIBRARY)
+ $(LINK.cxx) $< $(LDFLAGS) $(LIBS)
+
+check testing verbose_testing: $(PROGS)
+ $(TEST_SEQRUN) ./nctst $(TEST_OUTDIR)/testfile.nc
+ $(TEST_SEQRUN) ./test_classic $(TEST_OUTDIR)/testfile.nc
+
+TEST_MPIRUN_2 = $(subst NP,2,$(TEST_MPIRUN))
+TEST_MPIRUN_4 = $(subst NP,4,$(TEST_MPIRUN))
+TEST_MPIRUN_6 = $(subst NP,6,$(TEST_MPIRUN))
+
+ptest4: $(PROGS)
+ @for i in $(PROGS); do ( \
+ $(TEST_MPIRUN_4) ./$$i $(TEST_OUTDIR)/testfile.nc \
+ ; ) ; done
+
+ptest2: $(PROGS)
+ @for i in $(PROGS); do ( \
+ $(TEST_MPIRUN_2) ./$$i $(TEST_OUTDIR)/testfile.nc \
+ ; ) ; done
+
+ptest6: $(PROGS)
+ @for i in $(PROGS); do ( \
+ $(TEST_MPIRUN_6) ./$$i $(TEST_OUTDIR)/testfile.nc \
+ ; ) ; done
+
+ptest: ptest4
+ptests: ptest2 ptest4 ptest6
+ptest8 ptest10:
+
+include $(srcdir)/../../rules.make
+
+$(LIBRARY): ;
+
diff --git a/test/CXX/nctst.cpp b/test/CXX/nctst.cpp
new file mode 100644
index 0000000..1b9dcd7
--- /dev/null
+++ b/test/CXX/nctst.cpp
@@ -0,0 +1,560 @@
+/*********************************************************************
+ *
+ * Copyright (C) 2014, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ *
+ *********************************************************************/
+/* $Id: nctst.cpp 2208 2015-11-29 00:52:26Z wkliao $ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <iostream>
+using namespace std;
+
+#include <string.h>
+#include <pnetcdf>
+#include <testutils.h>
+
+using namespace PnetCDF;
+using namespace PnetCDF::exceptions;
+
+const char LAT[] = "lat";
+const char LON[] = "lon";
+const char FRTIME[] = "frtime";
+const char TIMELEN1[] = "timelen";
+const char P_NAME[] = "P";
+const char PRES_MAX_WIND[] = "pressure at maximum wind";
+const char LONG_NAME[] = "long_name";
+const char UNITS[] = "units";
+const char VALID_RANGE[] = "valid_range";
+const char FILL_VALUE[] = "_FillValue";
+const char DEGREES_NORTH[] = "degrees_north";
+const char LONGITUDE[] = "longitude";
+const char LATITUDE[] = "latitude";
+const char HECTOPASCALS[] = "hectopascals";
+const char DEGREES_EAST[] = "degrees_east";
+const char HOURS[] = "hours";
+const char FORECAST_TIME[] = "forecast time";
+const char REFERENCE_TIME[] = "reference time";
+const char REFTIME[] = "reftime";
+const char TEXT_TIME[] = "text_time";
+const char SCALARV[] = "scalarv";
+const char SCALAR_ATT[] = "scalar_att";
+const int SCALAR_VALUE = 1;
+const char HISTORY[] = "history";
+const char TITLE[] = "title";
+const char HISTORY_STR[] = "created by Unidata LDM from NPS broadcast";
+const char TITLE_STR[] = "NMC Global Product Set: Pressure at Maximum Wind";
+
+const int NC_ERR = 2;
+const int NLATS = 4;
+const int NLONS = 3;
+const int NFRTIMES = 2;
+const int TIMESTRINGLEN = 20;
+const MPI_Offset NRANGES = 2;
+
+// These are data values written out by the gen() function, and read
+// in again and checked by the read() function.
+static float range[] = {0., 1500.};
+static float lats[NLATS] = {-90, -87.5, -85, -82.5};
+static float lons[NLONS] = {-180, -175, -170};
+static int frtimes[NFRTIMES] = {12, 18};
+static const char* s = "1992-3-21 12:00";
+static float fill_value = -9999.0;
+static float P_data[NFRTIMES][NLATS][NLONS] = {
+ {{950, 951, 952}, {953, 954, 955}, {956, 957, 958}, {959, 960, 961}},
+ {{962, 963, 964}, {965, 966, 967}, {968, 969, 970}, {971, 972, 973}}
+};
+
+
+// Check a string attribute to make sure it has the correct value.
+int
+check_string_att(NcmpiAtt &att, const char *theName, const char *value)
+{
+ if (att.isNull() || att.getName().compare(theName) != 0 ||
+ att.getType() != ncmpiChar || att.getAttLength() != (long)strlen(value))
+ return NC_ERR;
+
+ char *value_in = (char*)malloc(strlen(value)+1);
+ att.getValues(value_in);
+ if (strncmp(value_in, value, strlen(value)))
+ return NC_ERR;
+ free(value_in);
+
+ return 0;
+}
+
+// Check the units and long_name attributes of a var to make sure they
+// are what is expected.
+int
+check_u_ln_atts(NcmpiVar &var, const char *units, const char *long_name)
+{
+ NcmpiVarAtt att = var.getAtt(UNITS);
+ if (check_string_att(att, UNITS, units))
+ return NC_ERR;
+
+ att = var.getAtt(LONG_NAME);
+ if (check_string_att(att, LONG_NAME, long_name))
+ return NC_ERR;
+
+ return 0;
+}
+
+// This reads the netCDF file created by gen() and ensures that
+// everything is there as expected.
+int read(const MPI_Comm &comm,
+ const char *path,
+ NcmpiFile::FileFormat format)
+{
+ try {
+ // open the file
+ NcmpiFile nc(comm, path, NcmpiFile::read);
+
+ // Check the format.
+ if (nc.getFormat() != format) {
+ cout << "unexpected file format"<<endl;
+ throw NcmpiException("read Error ",__FILE__,__LINE__);
+ }
+
+ // Check the number of dimensions.
+ int ndims = nc.getDimCount();
+ if (ndims != 4 && ndims != 6 && ndims != 2) {
+ cout << "nc.getDimCount()="<<ndims<<" != 2, 4, 6"<<endl;
+ throw NcmpiException("read Error ",__FILE__,__LINE__);
+ }
+
+ // Check the global attributes.
+ NcmpiGroupAtt att = nc.getAtt(HISTORY);
+ if (check_string_att(att, HISTORY, HISTORY_STR)) {
+ cout << "global attribute "<<HISTORY_STR<<" != "<<HISTORY<<endl;
+ throw NcmpiException("read Error ",__FILE__,__LINE__);
+ }
+
+ att = nc.getAtt(TITLE);
+ if (check_string_att(att, TITLE, TITLE_STR)) {
+ cout << "global attribute "<<TITLE_STR<<" != "<<TITLE<<endl;
+ throw NcmpiException("read Error ",__FILE__,__LINE__);
+ }
+
+ // Check the dimensions.
+ NcmpiDim latDim = nc.getDim(LAT);
+ if (latDim.isNull() || latDim.getName().compare(LAT) != 0 ||
+ latDim.getSize() != NLATS || latDim.isUnlimited())
+ throw NcmpiException("read Error: dimension lat ",__FILE__,__LINE__);
+
+ NcmpiDim lonDim = nc.getDim(LON);
+ if (lonDim.isNull() || lonDim.getName().compare(LON) != 0 ||
+ lonDim.getSize() != NLONS || lonDim.isUnlimited())
+ throw NcmpiException("read Error: dimension lon ",__FILE__,__LINE__);
+
+ NcmpiDim frtimeDim = nc.getDim(FRTIME);
+ if (frtimeDim.isNull() || frtimeDim.getName().compare(FRTIME) != 0 ||
+ frtimeDim.getSize() != NFRTIMES || !frtimeDim.isUnlimited())
+ throw NcmpiException("read Error: unlimited dimension frtime ",__FILE__,__LINE__);
+
+ NcmpiDim timeLenDim = nc.getDim(TIMELEN1);
+ if (timeLenDim.isNull() || timeLenDim.getName().compare(TIMELEN1) != 0 ||
+ timeLenDim.getSize() != TIMESTRINGLEN || timeLenDim.isUnlimited())
+ throw NcmpiException("read Error: dimension timeLen ",__FILE__,__LINE__);
+
+ // Check the coordinate variables.
+
+ // Get the latitude.
+ NcmpiVar latVar = nc.getVar(LAT);
+
+ // Check units and long name.
+ if (check_u_ln_atts(latVar, DEGREES_NORTH, LATITUDE))
+ throw NcmpiException("read Error: check_u_ln_atts lat ",__FILE__,__LINE__);
+
+ // Get the longitude.
+ NcmpiVar lonVar = nc.getVar(LON);
+
+ // Check units and long name.
+ if (check_u_ln_atts(lonVar, DEGREES_EAST, LONGITUDE))
+ throw NcmpiException("read Error: check_u_ln_atts lon ",__FILE__,__LINE__);
+
+ // Get the forecast time coordinate variable.
+ NcmpiVar frtimeVar = nc.getVar(FRTIME);
+
+ // Check units and long name.
+ if (check_u_ln_atts(frtimeVar, HOURS, FORECAST_TIME)) {
+ cout << "check_u_ln_atts frtime err"<<endl;
+ throw NcmpiException("read Error ",__FILE__,__LINE__);
+ }
+
+ // Get the refTime coordinate variable.
+ NcmpiVar refTimeVar = nc.getVar(REFTIME);
+
+ // Check units and long name.
+ if (check_u_ln_atts(refTimeVar, TEXT_TIME, REFERENCE_TIME))
+ throw NcmpiException("read Error: check_u_ln_atts refTime ",__FILE__,__LINE__);
+
+ // Check the data variables.
+ NcmpiVar pVar = nc.getVar(P_NAME);
+
+ // Check units and long name.
+ if (check_u_ln_atts(pVar, HECTOPASCALS, PRES_MAX_WIND))
+ throw NcmpiException("read Error: check_u_ln_atts HECTOPASCALS ",__FILE__,__LINE__);
+
+ // Check the valid range, and check the values.
+ NcmpiVarAtt vatt = pVar.getAtt(VALID_RANGE);
+ if (vatt.isNull() || vatt.getName().compare(VALID_RANGE) != 0 ||
+ vatt.getType() != ncmpiFloat || vatt.getAttLength() != NRANGES)
+ throw NcmpiException("read Error: VALID_RANGE ",__FILE__,__LINE__);
+
+ float range_in[NRANGES];
+ vatt.getValues(range_in);
+ if (range_in[0] != range[0] || range_in[1] != range[1])
+ throw NcmpiException("read Error: range value ",__FILE__,__LINE__);
+
+ // Check the fill value, and check the value.
+ vatt = pVar.getAtt(FILL_VALUE);
+ if (vatt.isNull() || vatt.getName().compare(FILL_VALUE) != 0 ||
+ vatt.getType() != ncmpiFloat || vatt.getAttLength() != 1)
+ throw NcmpiException("read Error: FILL_VALUE ",__FILE__,__LINE__);
+
+ float fill_value_in;
+ vatt.getValues(&fill_value_in);
+ if (fill_value_in != fill_value)
+ throw NcmpiException("Fill value mismatch Error ",__FILE__,__LINE__);
+
+ // Check the data in the pressure variable.
+ float P_data_in[NFRTIMES][NLATS][NLONS];
+ // pVar.getVar(NFRTIMES, NLATS, NLONS, &P_data_in[0][0][0]);
+ pVar.getVar_all(&P_data_in[0][0][0]);
+ for (int f = 0; f < NFRTIMES; f++)
+ for (int la = 0; la < NLATS; la++)
+ for (int lo = 0; lo < NLONS; lo++)
+ if (P_data_in[f][la][lo] != P_data[f][la][lo])
+ throw NcmpiException("read Error: unexpect variable value ",__FILE__,__LINE__);
+
+ // Get the scalar variable.
+ NcmpiVar scalarVar = nc.getVar(SCALARV);
+
+ // Check for the scalar attribute of the scalar variable and check its value.
+ vatt = scalarVar.getAtt(SCALAR_ATT);
+ if (vatt.isNull() || vatt.getName().compare(SCALAR_ATT) != 0 ||
+ vatt.getType() != ncmpiInt || vatt.getAttLength() != 1)
+ throw NcmpiException("read Error: SCALAR_ATT ",__FILE__,__LINE__);
+
+ int value_in;
+ vatt.getValues(&value_in);
+ if (value_in != SCALAR_VALUE)
+ throw NcmpiException("read Error: SCALAR_VALUE ",__FILE__,__LINE__);
+
+ // Check the value of the scalar variable.
+ }
+ catch(NcmpiException& e)
+ {
+ cout << e.what() << " error code=" << e.errorCode() << " Error!\n";
+ return -1;
+ }
+
+ return 0;
+}
+
+// Generate a netCDF file
+int gen(const MPI_Comm &comm,
+ const char *path,
+ NcmpiFile::FileFormat format)
+{
+ try {
+ // Create a new file, leave in define mode
+ NcmpiFile nc(comm, path, NcmpiFile::replace, format);
+
+ // Create dimensions
+ NcmpiDim latd = nc.addDim(LAT, NLATS);
+ NcmpiDim lond = nc.addDim(LON, NLONS);
+ NcmpiDim frtimed = nc.addDim(FRTIME); // unlimited dimension
+ NcmpiDim timelend = nc.addDim(TIMELEN1, TIMESTRINGLEN);
+
+ vector<NcmpiDim> dim3D(3);
+ dim3D[0]=frtimed;
+ dim3D[1]=latd;
+ dim3D[2]=lond;
+
+ // Create variables and their attributes
+ NcmpiVar P = nc.addVar(P_NAME, ncmpiFloat, dim3D);
+ P.putAtt(LONG_NAME, PRES_MAX_WIND);
+ P.putAtt(UNITS, HECTOPASCALS);
+ P.putAtt(VALID_RANGE, ncmpiFloat, NRANGES, range);
+ P.putAtt(FILL_VALUE, ncmpiFloat, fill_value);
+
+ NcmpiVar lat = nc.addVar(LAT, ncmpiFloat, latd);
+ lat.putAtt(LONG_NAME, LATITUDE);
+ lat.putAtt(UNITS, DEGREES_NORTH);
+
+ NcmpiVar lon = nc.addVar(LON, ncmpiFloat, lond);
+ lon.putAtt(LONG_NAME, LONGITUDE);
+ lon.putAtt(UNITS, DEGREES_EAST);
+
+ NcmpiVar frtime = nc.addVar(FRTIME, ncmpiInt, frtimed);
+ frtime.putAtt(LONG_NAME, FORECAST_TIME);
+ frtime.putAtt(UNITS, HOURS);
+
+ NcmpiVar reftime = nc.addVar(REFTIME, ncmpiChar, timelend);
+ reftime.putAtt(LONG_NAME, REFERENCE_TIME);
+ reftime.putAtt(UNITS, TEXT_TIME);
+
+ NcmpiVar scalar = nc.addVar(SCALARV, ncmpiInt);
+ scalar.putAtt(SCALAR_ATT, ncmpiInt, SCALAR_VALUE);
+
+ // Global attributes
+ nc.putAtt(HISTORY, HISTORY_STR);
+ nc.putAtt(TITLE, TITLE_STR);
+
+ // Start writing data, implictly leaves define mode
+
+ lat.putVar_all(lats);
+
+ lon.putVar_all(lons);
+
+ // make sure tailing characters are all '\0'
+ char *str = (char*) calloc(TIMESTRINGLEN, 1);
+ strcpy(str, s);
+ reftime.putVar_all(str);
+ free(str);
+
+ // we write one record at a time
+ vector<MPI_Offset> startp,countp;
+ startp.push_back(0);
+ startp.push_back(0);
+ startp.push_back(0);
+ countp.push_back(1);
+ countp.push_back(NLATS);
+ countp.push_back(NLONS);
+
+ P.putVar_all(startp,countp,&P_data[0][0][0]); // write 1st record
+
+ startp[0] = 1;
+ P.putVar_all(startp,countp,&P_data[1][0][0]); // write 2nd record
+
+ frtime.putVar_all(frtimes);
+
+ // close of nc takes place in destructor
+ }
+ catch(NcmpiException& e)
+ {
+ cout << e.what() << " error code=" << e.errorCode() << " Error!\n";
+ return -1;
+ }
+
+ return 0;
+}
+
+/*
+ * Convert pathname of netcdf file into name for CDL, by taking last component
+ * of path and stripping off any extension. The returned string is in static
+ * storage, so copy it if you need to keep it.
+ */
+static char*
+cdl_name(const char* path)
+{
+ const char* cp = path + strlen(path);
+ while (*(cp-1) != '/' && cp != path) // assumes UNIX path separator
+ cp--;
+
+ static char np[NC_MAX_NAME];
+ strncpy(&np[0], cp, NC_MAX_NAME);
+
+ char* ep = np + strlen(np);
+ while (*ep != '.' && ep != np)
+ ep--;
+ if (*ep == '.')
+ *ep = '\0';
+ return np;
+}
+
+// A derived class, just like NcmpiFile except knows how to "dump" its
+// dimensions, variables, global attributes, and data in ASCII form.
+class DumpableNcmpiFile : public NcmpiFile
+{
+ public:
+ DumpableNcmpiFile(const MPI_Comm &comm,
+ const char* path, NcmpiFile::FileMode mode = read)
+ : NcmpiFile(comm, path, mode) {} ;
+ void dumpdims( void );
+ void dumpvars( void );
+ void dumpgatts( void );
+ void dumpdata( void );
+};
+
+void DumpableNcmpiFile::dumpdims( void )
+{
+ multimap<string,NcmpiDim> dimMap = getDims();
+
+ for (multimap<string,NcmpiDim>::iterator iter=dimMap.begin(); iter!=dimMap.end(); ++iter) {
+ NcmpiDim *ptr = &(*iter).second;
+ cout << "\t" << ptr->getName() << " = " ;
+ if (ptr->isUnlimited())
+ cout << "UNLIMITED" << " ;\t " << "// " << ptr->getSize() <<
+ " currently\n";
+ else
+ cout << ptr->getSize() << " ;\n";
+ }
+}
+
+void dumpatts(NcmpiVar& var)
+{
+ std::map<std::string,NcmpiVarAtt> attMap = var.getAtts();
+
+ for (std::map<std::string,NcmpiVarAtt>::iterator iter=attMap.begin(); iter!=attMap.end(); ++iter) {
+ NcmpiAtt *ptr = &(*iter).second;
+ cout << "\t\t" << var.getName() << ":" << ptr->getName() << " = " ;
+ vector<double> atest(ptr->getAttLength());
+ ptr->getValues(&atest[0]);
+ cout << &atest[0] << " ;" << endl ;
+ }
+}
+
+void DumpableNcmpiFile::dumpvars( void )
+{
+ multimap<string,NcmpiVar> vMap = getVars();
+
+ for (multimap<string,NcmpiVar>::iterator iter=vMap.begin(); iter!=vMap.end(); ++iter) {
+ NcmpiVar *vp = &(*iter).second;
+ cout << "\t" << vp->getType().getName() << " " << vp->getName() ;
+
+ if (vp->getDimCount() > 0) {
+ cout << "(";
+ for (int d = 0; d < vp->getDimCount(); d++) {
+ NcmpiDim dim = vp->getDim(d);
+ cout << dim.getName();
+ if (d < vp->getDimCount()-1)
+ cout << ", ";
+ }
+ cout << ")";
+ }
+ cout << " ;\n";
+ // now dump each of this variable's attributes
+ dumpatts(*vp);
+ }
+}
+
+void DumpableNcmpiFile::dumpgatts( void )
+{
+ std::multimap<std::string,NcmpiGroupAtt> attMap = getAtts();
+
+ for (std::multimap<std::string,NcmpiGroupAtt>::iterator iter=attMap.begin(); iter!=attMap.end(); ++iter) {
+ NcmpiGroupAtt *ap = &(*iter).second;
+ cout << "\t\t" << ":" << ap->getName() << " = " ;
+ vector<double> atest(ap->getAttLength());
+ ap->getValues(&atest[0]);
+ cout << &atest[0] << " ;" << endl ;
+ }
+}
+
+void DumpableNcmpiFile::dumpdata( )
+{
+ std::multimap<std::string,NcmpiVar> vMap = getVars();
+
+ for (std::multimap<std::string,NcmpiVar>::iterator iter=vMap.begin(); iter!=vMap.end(); ++iter) {
+ NcmpiVar *vp = &(*iter).second;
+ cout << " " << vp->getName() << " = ";
+
+ MPI_Offset vSize = 1;
+ std::vector<NcmpiDim> dimMap = vp->getDims();
+ for (std::vector<NcmpiDim>::iterator iterD=dimMap.begin(); iterD!=dimMap.end(); ++iterD) {
+ vSize *= iterD->getSize();
+ }
+
+ vector<double> vals(vSize);
+ vp->getVar_all(&vals[0]);
+ cout << &vals[0] << " ;" << endl ;
+ }
+}
+
+void dump(const MPI_Comm &comm, const char* path)
+{
+ DumpableNcmpiFile nc(comm, path); // default is open in read-only mode
+
+ cout << "netcdf " << cdl_name(path) << " {" << endl <<
+ "dimensions:" << endl ;
+
+ nc.dumpdims();
+
+ cout << "variables:" << endl;
+
+ nc.dumpvars();
+
+ if (nc.getAttCount() > 0)
+ cout << "// global attributes" << endl ;
+
+ nc.dumpgatts();
+
+ cout << "data:" << endl;
+
+ nc.dumpdata();
+
+ cout << "}" << endl;
+}
+
+/* Test everything for classic, 64-bit offset, an 64-bit data files. */
+#define NUM_FORMATS (3)
+
+int
+main(int argc, char* argv[]) // test new netCDF interface
+{
+ char filename[256];
+ int rank, nprocs, verbose=0;
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+
+ if (argc > 2) {
+ if (!rank) printf("Usage: %s [filename]\n",argv[0]);
+ MPI_Finalize();
+ return 0;
+ }
+ strcpy(filename, "testfile.nc");
+ if (argc == 2) strcpy(filename, argv[1]);
+
+ if (rank == 0) {
+ char cmd_str[256];
+ sprintf(cmd_str, "*** TESTING C++ %s for APIs with different netCDF formats ", argv[0]);
+ printf("%-66s ------ ", cmd_str);
+ }
+
+ // Set up the format constants.
+ NcmpiFile::FileFormat format[NUM_FORMATS] =
+ {NcmpiFile::classic, NcmpiFile::classic2, NcmpiFile::classic5};
+
+ char format_name[NUM_FORMATS][NC_MAX_NAME] =
+ {"classic", "classic2", "classic5"};
+
+ int nerrs = 0;
+ for (int i = 0; i < NUM_FORMATS; i++)
+ {
+ if (gen(MPI_COMM_WORLD, filename, format[i]) ||
+ read(MPI_COMM_WORLD, filename, format[i]))
+ {
+ if (verbose)
+ cout << "*** FAILURE with format " << format_name[i] << "\n";
+ nerrs++;
+ }
+ else if (verbose)
+ cout << "*** SUCCESS with format " << format_name[i] << "\n";
+ }
+
+ if (verbose) cout << "\n*** Total number of failures: " << nerrs << "\n";
+
+ MPI_Offset malloc_size, sum_size;
+ int err = ncmpi_inq_malloc_size(&malloc_size);
+ if (err == NC_NOERR) {
+ MPI_Reduce(&malloc_size, &sum_size, 1, MPI_OFFSET, MPI_SUM, 0, MPI_COMM_WORLD);
+ if (rank == 0 && sum_size > 0)
+ printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n",
+ sum_size);
+ }
+
+ if (rank == 0) {
+ if (nerrs) printf(FAIL_STR,nerrs);
+ else printf(PASS_STR);
+ }
+
+
+ MPI_Finalize();
+ return nerrs;
+}
diff --git a/test/CXX/test_classic.cpp b/test/CXX/test_classic.cpp
new file mode 100644
index 0000000..f9b6b1f
--- /dev/null
+++ b/test/CXX/test_classic.cpp
@@ -0,0 +1,96 @@
+#include <stdio.h>
+#include <string.h>
+#include <iostream>
+#include <pnetcdf>
+#include <testutils.h>
+
+using namespace std;
+using namespace PnetCDF;
+using namespace PnetCDF::exceptions;
+
+int main( int argc, char *argv[] )
+{
+ char filename[256];
+ int rank, nerrs=0, verbose=0;
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ if (argc > 2) {
+ if (!rank) printf("Usage: %s [filename]\n",argv[0]);
+ MPI_Finalize();
+ return 0;
+ }
+ strcpy(filename, "testfile.nc");
+ if (argc == 2) strcpy(filename, argv[1]);
+
+ if (rank == 0) {
+ char cmd_str[256];
+ sprintf(cmd_str, "*** TESTING C++ %s for creation of classic format file", argv[0]);
+ printf("%-66s ------ ", cmd_str);
+ }
+
+ try
+ {
+ if (verbose) cout << "Test creation of classic format file" << endl;
+ {
+ NcmpiFile ncFile(MPI_COMM_WORLD, filename, NcmpiFile::replace,
+ NcmpiFile::classic);
+ NcmpiDim dim1 = ncFile.addDim("dim1",11);
+ NcmpiDim dim2 = ncFile.addDim("dim2");
+ NcmpiDim dim3 = ncFile.addDim("dim3",13);
+
+ NcmpiVar var_gw = ncFile.addVar("George_Washington", ncmpiInt, dim1);
+ // add a 2D record variable
+ vector<NcmpiDim> dimArray(2);
+ dimArray[0]=dim2;
+ dimArray[1]=dim1;
+ NcmpiVar varA1_3 = ncFile.addVar("varA1_3", ncmpiInt, dimArray);
+
+ // ncFile.enddef(); is no need in C++ program
+
+ // and inserting some data that needs leaving the define mode
+ if (verbose) cout << "testing the switch to DATA mode..." << endl;
+ int arr[] = {1,2,3,4,5,6,7,8,9,10,11};
+ var_gw.putVar_all(arr);
+ }
+
+ // Now test reading.
+ {
+ NcmpiFile ncFile(MPI_COMM_WORLD, filename, NcmpiFile::read);
+
+ if (ncFile.getVarCount() != 2)
+ throw NcmpiException( "Holy Mother of Pearl!", __FILE__, __LINE__);
+ }
+
+ // and redefinition
+ {
+ NcmpiFile ncFile(MPI_COMM_WORLD, filename, NcmpiFile::write);
+ if (verbose) cout << "testing the switch to DEFINE mode..." << endl;
+ ncFile.putAtt(string("name"),string("value"));
+ }
+
+ if (verbose) cout << " ----------- passed\n";
+ }
+ catch(NcmpiException& e)
+ {
+ cout << e.what() << " error code=" << e.errorCode() << " Error!\n";
+ nerrs++;
+ }
+
+ MPI_Offset malloc_size, sum_size;
+ int err = ncmpi_inq_malloc_size(&malloc_size);
+ if (err == NC_NOERR) {
+ MPI_Reduce(&malloc_size, &sum_size, 1, MPI_OFFSET, MPI_SUM, 0, MPI_COMM_WORLD);
+ if (rank == 0 && sum_size > 0)
+ printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n",
+ sum_size);
+ }
+
+ if (rank == 0) {
+ if (nerrs) printf(FAIL_STR,nerrs);
+ else printf(PASS_STR);
+ }
+
+ MPI_Finalize();
+ return 0;
+}
diff --git a/test/F90/Makefile.in b/test/F90/Makefile.in
new file mode 100644
index 0000000..7462058
--- /dev/null
+++ b/test/F90/Makefile.in
@@ -0,0 +1,142 @@
+#
+# Copyright (C) 2012, Northwestern University and Argonne National Laboratory
+# See COPYRIGHT notice in top-level directory.
+#
+# $Id: Makefile.in 2251 2015-12-20 21:13:42Z wkliao $
+#
+# @configure_input@
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+include ../../macros.make
+
+INCLUDES =
+FPPFLAGS += @FC_MODINC at ../../src/libf90 @FC_MODINC at ../common
+F90FLAGS += @FC_MODOUT at .
+LDFLAGS := $(LDFLAGS) -L../common
+LIBS := $(LIBRARY) -ltestutils $(LIBS) @LCOV_LIB@
+
+F90_SRCS = tst_f90.f90 \
+ tst_io.f90 \
+ f90tst_vars.f90 \
+ tst_types2.f90 \
+ tst_f90_cdf5.f90 \
+ f90tst_vars2.f90 \
+ f90tst_vars3.f90 \
+ f90tst_vars4.f90 \
+ tst_flarge.f90 \
+ f90tst_parallel.f90 \
+ f90tst_parallel2.f90 \
+ f90tst_parallel3.f90 \
+ f90tst_parallel4.f90 \
+ test_intent.f90
+
+PROGS = $(F90_SRCS:.f90=)
+OBJS = $(F90_SRCS:.f90=.o)
+
+GARBAGE = $(PROGS) *.nc *. at FC_MODEXT@
+
+PACKING_LIST = $(F90_SRCS) Makefile.in depend
+
+all: $(PROGS)
+
+$(PROGS): ../common/libtestutils.a
+
+../common/libtestutils.a:
+ set -e; cd ../common && $(MAKE) $(MFLAGS) all
+
+tst_f90: tst_f90.o $(LIBRARY)
+ $(LINK.F90) $< $(LDFLAGS) $(LIBS)
+
+tst_io: tst_io.o $(LIBRARY)
+ $(LINK.F90) $< $(LDFLAGS) $(LIBS)
+
+f90tst_vars: f90tst_vars.o $(LIBRARY)
+ $(LINK.F90) $< $(LDFLAGS) $(LIBS)
+
+tst_types2: tst_types2.o $(LIBRARY)
+ $(LINK.F90) $< $(LDFLAGS) $(LIBS)
+
+tst_f90_cdf5: tst_f90_cdf5.o $(LIBRARY)
+ $(LINK.F90) $< $(LDFLAGS) $(LIBS)
+
+f90tst_vars2: f90tst_vars2.o $(LIBRARY)
+ $(LINK.F90) $< $(LDFLAGS) $(LIBS)
+
+f90tst_vars3: f90tst_vars3.o $(LIBRARY)
+ $(LINK.F90) $< $(LDFLAGS) $(LIBS)
+
+f90tst_vars4: f90tst_vars4.o $(LIBRARY)
+ $(LINK.F90) $< $(LDFLAGS) $(LIBS)
+
+tst_flarge: tst_flarge.o $(LIBRARY)
+ $(LINK.F90) $< $(LDFLAGS) $(LIBS)
+
+f90tst_parallel: f90tst_parallel.o $(LIBRARY)
+ $(LINK.F90) $< $(LDFLAGS) $(LIBS)
+
+f90tst_parallel2: f90tst_parallel2.o $(LIBRARY)
+ $(LINK.F90) $< $(LDFLAGS) $(LIBS)
+
+f90tst_parallel3: f90tst_parallel3.o $(LIBRARY)
+ $(LINK.F90) $< $(LDFLAGS) $(LIBS)
+
+f90tst_parallel4: f90tst_parallel4.o $(LIBRARY)
+ $(LINK.F90) $< $(LDFLAGS) $(LIBS)
+
+test_intent: test_intent.o $(LIBRARY)
+ $(LINK.F90) $< $(LDFLAGS) $(LIBS)
+
+testing check verbose_testing: $(PROGS)
+ $(TEST_SEQRUN) ./test_intent $(TEST_OUTDIR)/testfile.nc
+ $(TEST_SEQRUN) ./tst_f90 $(TEST_OUTDIR)/testfile.nc
+ $(TEST_SEQRUN) ./f90tst_vars $(TEST_OUTDIR)/testfile.nc
+ $(TEST_SEQRUN) ./tst_types2 $(TEST_OUTDIR)/testfile.nc
+ $(TEST_SEQRUN) ./tst_f90_cdf5 $(TEST_OUTDIR)/testfile.nc
+ $(TEST_SEQRUN) ./f90tst_vars2 $(TEST_OUTDIR)/testfile.nc
+ $(TEST_SEQRUN) ./f90tst_vars3 $(TEST_OUTDIR)/testfile.nc
+ $(TEST_SEQRUN) ./f90tst_vars4 $(TEST_OUTDIR)/testfile.nc
+ $(TEST_SEQRUN) ./tst_flarge $(TEST_OUTDIR)/testfile.nc
+ $(TEST_SEQRUN) ./tst_io $(TEST_OUTDIR)
+
+PARALLEL_PROGS = f90tst_parallel f90tst_parallel2 f90tst_parallel3 f90tst_parallel4
+
+TEST_MPIRUN_2 = $(subst NP,2,$(TEST_MPIRUN))
+TEST_MPIRUN_4 = $(subst NP,4,$(TEST_MPIRUN))
+TEST_MPIRUN_8 = $(subst NP,8,$(TEST_MPIRUN))
+TEST_MPIRUN_10 = $(subst NP,10,$(TEST_MPIRUN))
+
+ptest4: $(PARALLEL_PROGS)
+ @for i in $(PARALLEL_PROGS); do ( \
+ $(TEST_MPIRUN_4) ./$$i $(TEST_OUTDIR)/testfile.nc \
+ ; ) ; done
+
+ptest2: $(PARALLEL_PROGS)
+ @for i in $(PARALLEL_PROGS); do ( \
+ $(TEST_MPIRUN_2) ./$$i $(TEST_OUTDIR)/testfile.nc \
+ ; ) ; done
+
+ptest8: $(PARALLEL_PROGS)
+ @for i in $(PARALLEL_PROGS); do ( \
+ $(TEST_MPIRUN_8) ./$$i $(TEST_OUTDIR)/testfile.nc \
+ ; ) ; done
+
+ptest10: $(PARALLEL_PROGS)
+ @for i in $(PARALLEL_PROGS); do ( \
+ $(TEST_MPIRUN_10) ./$$i $(TEST_OUTDIR)/testfile.nc \
+ ; ) ; done
+
+ptest: ptest4
+ptests: ptest2 ptest4 ptest8 ptest10
+ptest6:
+
+install:
+
+uninstall:
+
+include $(srcdir)/depend
+include $(srcdir)/../../rules.make
+
+$(LIBRARY): ;
+
diff --git a/test/F90/depend b/test/F90/depend
new file mode 100644
index 0000000..d4b6d2c
--- /dev/null
+++ b/test/F90/depend
@@ -0,0 +1,13 @@
+tst_f90.o: tst_f90.f90
+tst_io.o: tst_io.f90
+f90tst_vars.o: f90tst_vars.f90
+tst_types2.o: tst_types2.f90
+tst_f90_cdf5.o: tst_f90_cdf5.f90
+f90tst_vars2.o: f90tst_vars2.f90
+f90tst_vars3.o: f90tst_vars3.f90
+f90tst_vars4.o: f90tst_vars4.f90
+tst_flarge.o: tst_flarge.f90
+f90tst_parallel.o: f90tst_parallel.f90
+f90tst_parallel2.o: f90tst_parallel2.f90
+f90tst_parallel3.o: f90tst_parallel3.f90
+f90tst_parallel4.o: f90tst_parallel4.f90
diff --git a/test/F90/f90tst_parallel.f90 b/test/F90/f90tst_parallel.f90
new file mode 100644
index 0000000..bf838bd
--- /dev/null
+++ b/test/F90/f90tst_parallel.f90
@@ -0,0 +1,169 @@
+!
+! Copyright (C) 2013, Northwestern University and Argonne National Laboratory
+! See COPYRIGHT notice in top-level directory.
+!
+! This is part of the PnetCDF package.
+!
+! $Id: f90tst_parallel.f90 2131 2015-09-25 22:33:12Z wkliao $
+
+! This program tests PnetCDF parallel I/O functions from fortran 90.
+!
+! We are writing 2D data, a 6 x 12 grid, on 4 processors. Each
+! processor will write it's rank to it's quarter of the array. The
+! result will be (in CDL):
+!
+! netcdf f90tst_parallel {
+! dimensions:
+! x = 16 ;
+! y = 16 ;
+! variables:
+! int data(x, y) ;
+! data:
+!
+! data =
+! 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1,
+! 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1,
+! 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1,
+! 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1,
+! 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1,
+! 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1,
+! 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1,
+! 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1,
+! 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
+! 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
+! 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
+! 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
+! 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
+! 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
+! 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
+! 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3 ;
+! }
+
+program f90tst_parallel
+ use mpi
+ use pnetcdf
+ implicit none
+
+ ! This is the name of the data file we will create.
+ character (len = *), parameter :: FILE_NAME = "f90tst_parallel.nc"
+
+ integer, parameter :: MAX_DIMS = 2
+ integer, parameter :: NX = 16, NY = 16
+ integer, parameter :: NUM_PROC = 4
+ integer :: ncid, varid, dimids(MAX_DIMS)
+ integer :: x_dimid, y_dimid
+ integer :: data_out(NY / 2, NX / 2), data_in(NY / 2, NX / 2)
+ integer :: mode_flag
+ integer :: nvars, ngatts, ndims, unlimdimid, file_format
+ integer :: x, y
+ integer :: p, my_rank, err, ierr, get_args
+ integer(KIND=MPI_OFFSET_KIND) :: start(MAX_DIMS), count(MAX_DIMS)
+ integer(KIND=MPI_OFFSET_KIND) :: nx_ll, ny_ll
+ character(LEN=256) filename, cmd, msg
+
+ call MPI_Init(ierr)
+ call MPI_Comm_rank(MPI_COMM_WORLD, my_rank, ierr)
+ call MPI_Comm_size(MPI_COMM_WORLD, p, ierr)
+
+ ! take filename from command-line argument if there is any
+ if (my_rank .EQ. 0) then
+ filename = FILE_NAME
+ err = get_args(cmd, filename)
+ endif
+ call MPI_Bcast(err, 1, MPI_INTEGER, 0, MPI_COMM_WORLD, ierr)
+ if (err .EQ. 0) goto 999
+
+ call MPI_Bcast(filename, 256, MPI_CHARACTER, 0, MPI_COMM_WORLD, ierr)
+
+! if (p .ne. 4 .AND. my_rank .eq. 0) then
+! print *, 'Warning: ',trim(cmd),' is design to run on 4 processes.'
+! endif
+
+ ! Create some pretend data.
+ do x = 1, NX / 2
+ do y = 1, NY / 2
+ data_out(y, x) = my_rank
+ end do
+ end do
+
+ ! Create the netCDF file.
+ mode_flag = IOR(NF90_CLOBBER, NF90_64BIT_DATA)
+ call handle_err(nf90mpi_create(MPI_COMM_WORLD, filename, mode_flag, MPI_INFO_NULL, ncid))
+
+ ! Define the dimensions.
+ nx_ll = NX
+ ny_ll = NY
+ call handle_err(nf90mpi_def_dim(ncid, "x", nx_ll, x_dimid))
+ call handle_err(nf90mpi_def_dim(ncid, "y", ny_ll, y_dimid))
+ dimids = (/ y_dimid, x_dimid /)
+
+ ! Define the variable.
+ call handle_err(nf90mpi_def_var(ncid, "data", NF90_INT, dimids, varid))
+
+ call handle_err(nf90mpi_enddef(ncid))
+
+ ! Determine what part of the variable will be written for this
+ ! processor. It's a checkerboard decomposition.
+ count = (/ NX / 2, NY / 2 /)
+ if (my_rank .eq. 0) then
+ start = (/ 1, 1 /)
+ else if (my_rank .eq. 1) then
+ start = (/ NX / 2 + 1, 1 /)
+ else if (my_rank .eq. 2) then
+ start = (/ 1, NY / 2 + 1 /)
+ else if (my_rank .eq. 3) then
+ start = (/ NX / 2 + 1, NY / 2 + 1 /)
+ else
+ start = (/ 1, 1 /)
+ count = 0
+ endif
+
+ ! Write this processor's data.
+ call handle_err(nf90mpi_put_var_all(ncid, varid, data_out, start = start, count = count))
+
+ ! Close the file.
+ call handle_err(nf90mpi_close(ncid))
+
+ ! Reopen the file.
+ call handle_err(nf90mpi_open(MPI_COMM_WORLD, filename, nf90_nowrite, MPI_INFO_NULL, ncid))
+
+ ! Check some stuff out.
+ call handle_err(nf90mpi_inquire(ncid, ndims, nvars, ngatts, unlimdimid, file_format))
+ if (ndims /= 2 .or. nvars /= 1 .or. ngatts /= 0 .or. unlimdimid /= -1 .or. &
+ file_format /= nf90_format_cdf5) stop 3
+
+ ! Read this processor's data.
+ call handle_err(nf90mpi_get_var_all(ncid, varid, data_in, start = start, count = count))
+
+ ! Check the data.
+ if (my_rank .LT. 4) then
+ do x = 1, NX / 2
+ do y = 1, NY / 2
+ if (data_in(y, x) .ne. my_rank) stop 4
+ end do
+ end do
+ endif
+
+ ! Close the file.
+ call handle_err(nf90mpi_close(ncid))
+
+ msg = '*** TESTING F90 '//trim(cmd)
+ if (my_rank .eq. 0) call pass_fail(0, msg)
+
+ 999 call MPI_Finalize(ierr)
+
+
+contains
+! This subroutine handles errors by printing an error message and
+! exiting with a non-zero status.
+ subroutine handle_err(errcode)
+ implicit none
+ integer, intent(in) :: errcode
+
+ if(errcode /= nf90_noerr) then
+ print *, 'Error: ', trim(nf90mpi_strerror(errcode))
+ stop 2
+ endif
+ end subroutine handle_err
+end program f90tst_parallel
+
diff --git a/test/F90/f90tst_parallel2.f90 b/test/F90/f90tst_parallel2.f90
new file mode 100644
index 0000000..1662a43
--- /dev/null
+++ b/test/F90/f90tst_parallel2.f90
@@ -0,0 +1,176 @@
+!
+! Copyright (C) 2013, Northwestern University and Argonne National Laboratory
+! See COPYRIGHT notice in top-level directory.
+!
+! This is part of the PnetCDF package.
+!
+! $Id: f90tst_parallel2.f90 2131 2015-09-25 22:33:12Z wkliao $
+
+! This program tests PnetCDF parallel I/O functions from fortran 90.
+
+! We are writing 2D data, a 6 x 12 grid, on 4 processors. We only
+! have half that amount of input data, because a stride is used so
+! that only every other value is written to the file. Each
+! processor will write it's rank to every other value in it's
+! quarter of the array. The result will be (in CDL):
+!
+! netcdf f90tst_parallel2 {
+! dimensions:
+! x = 16 ;
+! y = 16 ;
+! variables:
+! int data(x, y) ;
+! data:
+
+! data =
+! 0, _, 0, _, 0, _, 0, _, 1, _, 1, _, 1, _, 1, _,
+! _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _,
+! 0, _, 0, _, 0, _, 0, _, 0, _, 0, _, 0, _, 0, _,
+! _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _,
+! 0, _, 0, _, 0, _, 0, _, 1, _, 1, _, 1, _, 1, _,
+! _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _,
+! 0, _, 0, _, 0, _, 0, _, 0, _, 0, _, 0, _, 0, _,
+! _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _,
+! 2, _, 2, _, 2, _, 2, _, 3, _, 3, _, 3, _, 3, _,
+! _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _,
+! 0, _, 0, _, 0, _, 0, _, 0, _, 0, _, 0, _, 0, _,
+! _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _,
+! 2, _, 2, _, 2, _, 2, _, 3, _, 3, _, 3, _, 3, _,
+! _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _,
+! 0, _, 0, _, 0, _, 0, _, 0, _, 0, _, 0, _, 0, _,
+! _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _ ;
+! }
+
+! $Id: f90tst_parallel2.f90 2131 2015-09-25 22:33:12Z wkliao $
+
+program f90tst_parallel
+ use mpi
+ use pnetcdf
+ implicit none
+
+ ! This is the name of the data file we will create.
+ character (len = *), parameter :: FILE_NAME = "f90tst_parallel2.nc"
+
+ integer, parameter :: MAX_DIMS = 2
+ integer, parameter :: NX = 16, NY = 16
+ integer, parameter :: NUM_PROC = 4
+ integer :: ncid, varid, dimids(MAX_DIMS)
+ integer :: x_dimid, y_dimid
+ integer :: data_out(NY / 4, NX / 4), data_in(NY / 4, NX / 4)
+ integer :: mode_flag
+ integer :: nvars, ngatts, ndims, unlimdimid, file_format
+ integer :: x, y
+ integer :: p, my_rank, err, ierr, get_args
+ integer(KIND=MPI_OFFSET_KIND) :: start(MAX_DIMS), count(MAX_DIMS), stride(MAX_DIMS)
+ integer(KIND=MPI_OFFSET_KIND) :: nx_ll, ny_ll
+ character(LEN=256) filename, cmd, msg
+
+ call MPI_Init(ierr)
+ call MPI_Comm_rank(MPI_COMM_WORLD, my_rank, ierr)
+ call MPI_Comm_size(MPI_COMM_WORLD, p, ierr)
+
+ ! take filename from command-line argument if there is any
+ if (my_rank .EQ. 0) then
+ filename = FILE_NAME
+ err = get_args(cmd, filename)
+ endif
+ call MPI_Bcast(err, 1, MPI_INTEGER, 0, MPI_COMM_WORLD, ierr)
+ if (err .EQ. 0) goto 999
+
+ call MPI_Bcast(filename, 256, MPI_CHARACTER, 0, MPI_COMM_WORLD, ierr)
+
+! if (p .ne. 4 .AND. my_rank .eq. 0) then
+! print *, 'Warning: ',trim(cmd),' is design to run on 4 processes.'
+! endif
+
+ ! Create some pretend data.
+ do x = 1, NX / 4
+ do y = 1, NY / 4
+ data_out(y, x) = my_rank
+ end do
+ end do
+
+ ! Create the netCDF file.
+ mode_flag = IOR(NF90_CLOBBER, NF90_64BIT_DATA)
+ call handle_err(nf90mpi_create(MPI_COMM_WORLD, filename, mode_flag, MPI_INFO_NULL, ncid))
+
+ ! Define the dimensions.
+ nx_ll = NX
+ ny_ll = NY
+ call handle_err(nf90mpi_def_dim(ncid, "x", nx_ll, x_dimid))
+ call handle_err(nf90mpi_def_dim(ncid, "y", ny_ll, y_dimid))
+ dimids = (/ y_dimid, x_dimid /)
+
+ ! Define the variable.
+ call handle_err(nf90mpi_def_var(ncid, "data", NF90_INT, dimids, varid))
+
+ ! With classic model netCDF-4 file, enddef must be called.
+ call handle_err(nf90mpi_enddef(ncid))
+
+ ! Determine what part of the variable will be written for this
+ ! processor. It's a checkerboard decomposition.
+ count = (/ NX / 4, NY / 4 /)
+ stride = (/ 2, 2 /)
+ if (my_rank .eq. 0) then
+ start = (/ 1, 1 /)
+ else if (my_rank .eq. 1) then
+ start = (/ NX / 2 + 1, 1 /)
+ else if (my_rank .eq. 2) then
+ start = (/ 1, NY / 2 + 1 /)
+ else if (my_rank .eq. 3) then
+ start = (/ NX / 2 + 1, NY / 2 + 1 /)
+ else
+ start = (/ 1, 1 /)
+ count = 0
+ endif
+
+ ! Write this processor's data.
+ call handle_err(nf90mpi_put_var_all(ncid, varid, data_out, start = start, &
+ count = count, stride = stride))
+
+ ! Close the file.
+ call handle_err(nf90mpi_close(ncid))
+
+ ! Reopen the file.
+ call handle_err(nf90mpi_open(MPI_COMM_WORLD, filename, nf90_nowrite, MPI_INFO_NULL, ncid))
+
+ ! Check some stuff out.
+ call handle_err(nf90mpi_inquire(ncid, ndims, nvars, ngatts, unlimdimid, file_format))
+ if (ndims /= 2 .or. nvars /= 1 .or. ngatts /= 0 .or. unlimdimid /= -1 .or. &
+ file_format /= nf90_format_cdf5) stop 3
+
+ ! Read this processor's data.
+ call handle_err(nf90mpi_get_var_all(ncid, varid, data_in, start = start, count = count, &
+ stride = stride))
+
+ ! Check the data.
+ if (my_rank .LT. 4) then
+ do x = 1, NX / 4
+ do y = 1, NY / 4
+ if (data_in(y, x) .ne. my_rank) stop 4
+ end do
+ end do
+ endif
+
+ ! Close the file.
+ call handle_err(nf90mpi_close(ncid))
+
+ msg = '*** TESTING F90 '//trim(cmd)//' for strided access'
+ if (my_rank .eq. 0) call pass_fail(0, msg)
+
+ 999 call MPI_Finalize(ierr)
+
+contains
+! This subroutine handles errors by printing an error message and
+! exiting with a non-zero status.
+ subroutine handle_err(errcode)
+ implicit none
+ integer, intent(in) :: errcode
+
+ if(errcode /= nf90_noerr) then
+ print *, 'Error: ', trim(nf90mpi_strerror(errcode))
+ stop 5
+ endif
+ end subroutine handle_err
+end program f90tst_parallel
+
diff --git a/test/F90/f90tst_parallel3.f90 b/test/F90/f90tst_parallel3.f90
new file mode 100644
index 0000000..efaa595
--- /dev/null
+++ b/test/F90/f90tst_parallel3.f90
@@ -0,0 +1,196 @@
+!
+! Copyright (C) 2013, Northwestern University and Argonne National Laboratory
+! See COPYRIGHT notice in top-level directory.
+!
+! This is part of the PnetCDF package.
+!
+! $Id: f90tst_parallel3.f90 2136 2015-10-07 19:25:34Z wkliao $
+
+! This program tests PnetCDF parallel I/O from
+! fortran. It creates a file like this:
+
+! netcdf f90tst_parallel3 {
+! dimensions:
+! x = 16 ;
+! y = 16 ;
+! variables:
+! byte byte__(x, y) ;
+! short short_(x, y) ;
+! int int__(x, y) ;
+! float float_(x, y) ;
+! double double(x, y) ;
+! int64 int64_(x, y) ;
+
+
+program f90tst_parallel3
+ use mpi
+ use pnetcdf
+ implicit none
+
+ integer, parameter :: OneByteInt = selected_int_kind(2), &
+ TwoByteInt = selected_int_kind(4), &
+ FourByteInt = selected_int_kind(9), &
+ EightByteInt = selected_int_kind(18)
+
+ ! This is the name of the data file we will create.
+ character (len = *), parameter :: FILE_NAME = "f90tst_parallel3.nc"
+ integer, parameter :: MAX_DIMS = 2
+ integer, parameter :: NX = 16, NY = 16
+ integer, parameter :: HALF_NX = NX/2, HALF_NY = NY/2
+ integer, parameter :: NUM_PROC = 4
+ integer, parameter :: NUM_VARS = 6
+ integer, parameter :: CACHE_SIZE = 4194304, CACHE_NELEMS = 1013
+ integer, parameter :: CACHE_PREEMPTION = 79
+ character (len = *), parameter :: var_name(NUM_VARS) = &
+ (/ 'byte__', 'short_', 'int___', 'float_', 'double', 'int64_' /)
+ integer :: ncid, varid(NUM_VARS), dimids(MAX_DIMS)
+ integer :: var_type(NUM_VARS) = (/ nf90_byte, nf90_short, nf90_int, &
+ nf90_float, nf90_double, nf90_int64 /)
+ integer :: x_dimid, y_dimid
+ integer(kind=OneByteInt) :: byte_out(HALF_NY, HALF_NX), byte_in(HALF_NY, HALF_NX)
+ integer(kind=TwoByteInt) :: short_out(HALF_NY, HALF_NX), short_in(HALF_NY, HALF_NX)
+ integer :: int_out(HALF_NY, HALF_NX), int_in(HALF_NY, HALF_NX)
+ real :: areal_out(HALF_NY, HALF_NX), areal_in(HALF_NY, HALF_NX)
+ double precision :: double_out(HALF_NY, HALF_NX), double_in(HALF_NY, HALF_NX)
+ integer (kind=EightByteInt) :: int64_out(HALF_NY, HALF_NX), int64_in(HALF_NY, HALF_NX)
+ integer :: nvars, ngatts, ndims, unlimdimid, file_format
+ integer :: x, y, v
+ integer :: p, my_rank, err, ierr, get_args
+ integer(KIND=MPI_OFFSET_KIND) :: start(MAX_DIMS), count(MAX_DIMS)
+ integer :: cmode
+ integer(KIND=MPI_OFFSET_KIND) :: nx_ll, ny_ll
+ character(LEN=256) filename, cmd, msg
+
+ call MPI_Init(ierr)
+ call MPI_Comm_rank(MPI_COMM_WORLD, my_rank, ierr)
+ call MPI_Comm_size(MPI_COMM_WORLD, p, ierr)
+
+ ! take filename from command-line argument if there is any
+ if (my_rank .EQ. 0) then
+ filename = FILE_NAME
+ err = get_args(cmd, filename)
+ endif
+ call MPI_Bcast(err, 1, MPI_INTEGER, 0, MPI_COMM_WORLD, ierr)
+ if (err .EQ. 0) goto 999
+
+ call MPI_Bcast(filename, 256, MPI_CHARACTER, 0, MPI_COMM_WORLD, ierr)
+
+! if (p .ne. 4 .AND. my_rank .eq. 0) then
+! print *, 'Warning: ',trim(cmd),' is design to run on 4 processes.'
+! endif
+
+ ! Create some pretend data.
+ do x = 1, HALF_NX
+ do y = 1, HALF_NY
+ byte_out(y, x) = INT(my_rank,1) * (-1_1)
+ short_out(y, x) = INT(my_rank, TwoByteInt) * (-2_2)
+ int_out(y, x) = my_rank * (-4)
+ areal_out(y, x) = my_rank * 2.5
+ double_out(y, x) = my_rank * (-4.5)
+ int64_out(y, x) = my_rank * 4
+ end do
+ end do
+
+ ! Create the netCDF file.
+ cmode = IOR(NF90_CLOBBER, NF90_64BIT_DATA)
+ call check(nf90mpi_create(MPI_COMM_WORLD, filename, cmode, MPI_INFO_NULL, ncid))
+
+ ! Define the dimensions.
+ nx_ll = NX
+ ny_ll = NY
+ call check(nf90mpi_def_dim(ncid, "x", nx_ll, x_dimid))
+ call check(nf90mpi_def_dim(ncid, "y", ny_ll, y_dimid))
+ dimids = (/ y_dimid, x_dimid /)
+
+ ! Define the variables.
+ do v = 1, NUM_VARS
+ call check(nf90mpi_def_var(ncid, var_name(v), var_type(v), dimids, varid(v)))
+ end do
+
+ ! This will be the last collective operation.
+ call check(nf90mpi_enddef(ncid))
+
+ ! Determine what part of the variable will be written/read for this
+ ! processor. It's a checkerboard decomposition.
+ count = (/ HALF_NX, HALF_NY /)
+ if (my_rank .eq. 0) then
+ start = (/ 1, 1 /)
+ else if (my_rank .eq. 1) then
+ start = (/ HALF_NX + 1, 1 /)
+ else if (my_rank .eq. 2) then
+ start = (/ 1, HALF_NY + 1 /)
+ else if (my_rank .eq. 3) then
+ start = (/ HALF_NX + 1, HALF_NY + 1 /)
+ else
+ start = (/ 1, 1 /)
+ count = 0
+ endif
+
+ ! Write this processor's data, except for processor zero.
+ if (my_rank .EQ. 0) count = (/ 0, 0 /)
+ call check(nf90mpi_put_var_all(ncid, varid(1), byte_out, start = start, count = count))
+ call check(nf90mpi_put_var_all(ncid, varid(2), short_out, start = start, count = count))
+ call check(nf90mpi_put_var_all(ncid, varid(3), int_out, start = start, count = count))
+ call check(nf90mpi_put_var_all(ncid, varid(4), areal_out, start = start, count = count))
+ call check(nf90mpi_put_var_all(ncid, varid(5), double_out, start = start, count = count))
+ call check(nf90mpi_put_var_all(ncid, varid(6), int64_out, start = start, count = count))
+
+ ! Close the file.
+ call check(nf90mpi_close(ncid))
+
+ ! Reopen the file.
+ call check(nf90mpi_open(MPI_COMM_WORLD, filename, nf90_nowrite, MPI_INFO_NULL, ncid))
+
+ ! Check some stuff out.
+ call check(nf90mpi_inquire(ncid, ndims, nvars, ngatts, unlimdimid, file_format))
+ if (ndims /= 2 .or. nvars /= NUM_VARS .or. ngatts /= 0 .or. unlimdimid /= -1 .or. &
+ file_format /= nf90_format_cdf5) stop 2
+
+ ! Read this processor's data.
+ if (my_rank .EQ. 0) count = (/ HALF_NX, HALF_NY /)
+ call check(nf90mpi_get_var_all(ncid, varid(1), byte_in, start = start, count = count))
+ call check(nf90mpi_get_var_all(ncid, varid(2), short_in, start = start, count = count))
+ call check(nf90mpi_get_var_all(ncid, varid(3), int_in, start = start, count = count))
+ call check(nf90mpi_get_var_all(ncid, varid(4), areal_in, start = start, count = count))
+ call check(nf90mpi_get_var_all(ncid, varid(5), double_in, start = start, count = count))
+ call check(nf90mpi_get_var_all(ncid, varid(6), int64_in, start = start, count = count))
+
+ ! Check the data. All the data from the processor zero are fill
+ ! value.
+ if (my_rank .LT. 4) then
+ do x = 1, HALF_NX
+ do y = 1, HALF_NY
+ if (my_rank .NE. 0) then
+ if (byte_in(y, x) .ne. (my_rank * (-1))) stop 13
+ if (short_in(y, x) .ne. (my_rank * (-2))) stop 14
+ if (int_in(y, x) .ne. (my_rank * (-4))) stop 15
+ if (areal_in(y, x) .ne. (my_rank * (2.5))) stop 16
+ if (double_in(y, x) .ne. (my_rank * (-4.5))) stop 17
+ if (int64_in(y, x) .ne. (my_rank * (4))) stop 20
+ endif
+ end do
+ end do
+ endif
+
+ ! Close the file.
+ call check(nf90mpi_close(ncid))
+
+ msg = '*** TESTING F90 '//trim(cmd)
+ if (my_rank .eq. 0) call pass_fail(0, msg)
+
+ 999 call MPI_Finalize(ierr)
+
+contains
+! This subroutine handles errors by printing an error message and
+! exiting with a non-zero status.
+ subroutine check(errcode)
+ implicit none
+ integer, intent(in) :: errcode
+
+ if(errcode /= nf90_noerr) then
+ print *, 'Error: ', trim(nf90mpi_strerror(errcode))
+ stop 99
+ endif
+ end subroutine check
+end program f90tst_parallel3
+
diff --git a/test/F90/f90tst_parallel4.f90 b/test/F90/f90tst_parallel4.f90
new file mode 100644
index 0000000..8c6a889
--- /dev/null
+++ b/test/F90/f90tst_parallel4.f90
@@ -0,0 +1,105 @@
+!
+! Copyright (C) 2013, Northwestern University and Argonne National Laboratory
+! See COPYRIGHT notice in top-level directory.
+!
+! This is part of the PnetCDF package.
+!
+! $Id: f90tst_parallel4.f90 2136 2015-10-07 19:25:34Z wkliao $
+
+! This parallel test was contributed by Jim Edwards at UCAR. Thanks Jim!
+program f90tst
+ use mpi
+ use pnetcdf
+ implicit none
+
+ character (len = *), parameter :: FILE_NAME = "f90tst_nc4_par.nc"
+ integer :: nmode, err, ierr, fh, my_rank, nprocs, i, varid, get_args
+ integer :: dimid(3)
+ integer(KIND=MPI_OFFSET_KIND) :: start(3), count(3)
+ real :: f(3)
+ character(LEN=256) filename, cmd, msg
+
+ call MPI_INIT(ierr)
+ call MPI_COMM_RANK(MPI_COMM_WORLD, my_rank, ierr)
+ call MPI_COMM_SIZE(MPI_COMM_WORLD, nprocs, ierr)
+
+ ! take filename from command-line argument if there is any
+ if (my_rank .EQ. 0) then
+ filename = FILE_NAME
+ err = get_args(cmd, filename)
+ endif
+ call MPI_Bcast(err, 1, MPI_INTEGER, 0, MPI_COMM_WORLD, ierr)
+ if (err .EQ. 0) goto 999
+
+ call MPI_Bcast(filename, 256, MPI_CHARACTER, 0, MPI_COMM_WORLD, ierr)
+
+! if (nprocs .ne. 8 .AND. my_rank .eq. 0) then
+! print *, 'Warning: ',trim(cmd),' is design to run on 8 processes.'
+! endif
+
+ nmode = ior(NF90_CLOBBER,NF90_64BIT_DATA)
+
+ call handle_err(nf90mpi_create(MPI_COMM_WORLD, filename, nmode, MPI_INFO_NULL, fh))
+
+ call handle_err(nf90mpi_def_dim(fh, 'dim1', 6_MPI_OFFSET_KIND, dimid(1)))
+ call handle_err(nf90mpi_def_dim(fh, 'dim2', 4_MPI_OFFSET_KIND, dimid(2)))
+ call handle_err(nf90mpi_def_dim(fh, 'dim3', 1_MPI_OFFSET_KIND, dimid(3)))
+
+
+ call handle_err(nf90mpi_def_var(fh, 'var1', NF90_DOUBLE, dimid, varid))
+ call handle_err(nf90mpi_enddef(fh))
+
+
+ do i=1,3
+ f(i) = my_rank*3+i
+ end do
+
+ count = (/3,1,1/)
+ start(1) = mod(my_rank,2)*3+1
+ start(2) = my_rank/2+1
+ start(3) = 1
+ if (my_rank .GE. 8) then
+ start = 1
+ count = 0
+ endif
+
+ call handle_err(nf90mpi_put_var_all(fh, varid, f,start=start,count=count))
+
+ call handle_err(nf90mpi_close(fh))
+
+ ! Reopen the file and check it.
+ call handle_err(nf90mpi_open(MPI_COMM_WORLD, filename, NF90_NOWRITE, MPI_INFO_NULL, fh))
+
+ call handle_err(nf90mpi_get_var_all(fh, varid, f, start=start, count=count))
+
+ if (my_rank .LE. 8) then
+ do i=1,3
+ if (f(i) .ne. my_rank*3+i) then
+ print *, 'Error: unexpected read value ',f(i),' should be ', my_rank*3+i
+ goto 999
+ endif
+ end do
+ endif
+
+ call handle_err(nf90mpi_close(fh))
+
+ msg = '*** TESTING F90 '//trim(cmd)
+ if (my_rank .eq. 0) call pass_fail(0, msg)
+
+ 999 call MPI_Finalize(ierr)
+
+contains
+ ! This subroutine handles errors by printing an error message and
+ ! exiting with a non-zero status.
+ subroutine handle_err(errcode)
+ implicit none
+ integer, intent(in) :: errcode
+
+ if(errcode /= nf90_noerr) then
+ print *, 'Error: ', trim(nf90mpi_strerror(errcode))
+ stop 2
+ endif
+ end subroutine handle_err
+
+end program f90tst
+
diff --git a/test/F90/f90tst_vars.f90 b/test/F90/f90tst_vars.f90
new file mode 100644
index 0000000..ca74588
--- /dev/null
+++ b/test/F90/f90tst_vars.f90
@@ -0,0 +1,139 @@
+!
+! Copyright (C) 2013, Northwestern University and Argonne National Laboratory
+! See COPYRIGHT notice in top-level directory.
+!
+! This is part of the PnetCDF package.
+!
+! $Id: f90tst_vars.f90 2131 2015-09-25 22:33:12Z wkliao $
+
+! This program tests PnetCDF variable functions from fortran 90.
+
+
+program f90tst_vars
+ use mpi
+ use pnetcdf
+ implicit none
+
+ ! This is the name of the data file we will create.
+ character (len = *), parameter :: FILE_NAME = "f90tst_vars.nc"
+
+ ! We are writing 2D data, a 6 x 12 grid.
+ integer, parameter :: MAX_DIMS = 2
+ integer, parameter :: NX = 6, NY = 12
+ integer :: data_out(NY, NX), data_in(NY, NX)
+
+ ! We need these ids and other gunk for netcdf.
+ integer :: ncid, varid, dimids(MAX_DIMS)
+ integer :: x_dimid, y_dimid
+ integer :: mode_flag
+ integer :: nvars, ngatts, ndims, unlimdimid, file_format
+ integer :: x, y
+ integer, parameter :: CACHE_SIZE = 1000000
+ integer :: info, err, ierr, get_args
+ integer(KIND=MPI_OFFSET_KIND) :: nx_ll, ny_ll
+ character(LEN=256) filename, cmd, msg
+ integer my_rank, p
+
+ call MPI_Init(ierr)
+ call MPI_Comm_rank(MPI_COMM_WORLD, my_rank, ierr)
+ call MPI_Comm_size(MPI_COMM_WORLD, p, ierr)
+
+ ! take filename from command-line argument if there is any
+ if (my_rank .EQ. 0) then
+ filename = FILE_NAME
+ err = get_args(cmd, filename)
+ endif
+ call MPI_Bcast(err, 1, MPI_INTEGER, 0, MPI_COMM_WORLD, ierr)
+ if (err .EQ. 0) goto 999
+
+ call MPI_Bcast(filename, 256, MPI_CHARACTER, 0, MPI_COMM_WORLD, ierr)
+
+! if (p .ne. 1 .AND. my_rank .eq. 0) then
+! print *, 'Warning: ',trim(cmd),' is design to run on 1 process'
+! endif
+
+ ! Create some pretend data.
+ do x = 1, NX
+ do y = 1, NY
+ data_out(y, x) = (x - 1) * NY + (y - 1)
+ end do
+ end do
+
+ call MPI_Info_create(info, ierr)
+ call MPI_Info_set(info, "nc_header_align_size", "1024", ierr)
+ call MPI_Info_set(info, "nc_var_align_size", "512", ierr)
+ call MPI_Info_set(info, "nc_header_read_chunk_size", "256", ierr)
+
+ ! Create the netCDF file.
+ mode_flag = IOR(NF90_CLOBBER, NF90_64BIT_DATA)
+ call handle_err(nf90mpi_create(MPI_COMM_WORLD, filename, mode_flag, info, ncid))
+ call MPI_Info_free(info, ierr)
+
+ ! Define the dimensions.
+ nx_ll = NX
+ ny_ll = NY
+ call handle_err(nf90mpi_def_dim(ncid, "x", nx_ll, x_dimid))
+ call handle_err(nf90mpi_def_dim(ncid, "y", ny_ll, y_dimid))
+ dimids = (/ y_dimid, x_dimid /)
+
+ ! Define the variable.
+ call handle_err(nf90mpi_def_var(ncid, "data", NF90_INT, dimids, varid))
+
+ ! With classic model netCDF-4 file, enddef must be called.
+ call handle_err(nf90mpi_enddef(ncid))
+
+ ! enter independent data mode
+ call handle_err(nf90mpi_begin_indep_data(ncid))
+
+ ! Write the pretend data to the file.
+ call handle_err(nf90mpi_put_var(ncid, varid, data_out))
+
+ ! Close the file.
+ call handle_err(nf90mpi_close(ncid))
+
+ ! Reopen the file.
+ call handle_err(nf90mpi_open(MPI_COMM_WORLD, filename, nf90_nowrite, MPI_INFO_NULL, ncid))
+
+ ! Check some stuff out.
+ call handle_err(nf90mpi_inquire(ncid, ndims, nvars, ngatts, unlimdimid, file_format))
+ if (ndims /= 2 .or. nvars /= 1 .or. ngatts /= 0 .or. unlimdimid /= -1 .or. &
+ file_format /= nf90_format_cdf5) then
+ print*,'ndims should be 2 but got ',ndims
+ print*,'nvars should be 1 but got ',nvars
+ print*,'ngatts should be 0 but got ',ngatts
+ print*,'unlimdimid should be -1 but got ',unlimdimid
+ print*,'file_format should be 5 but got ',file_format
+ stop 2
+ endif
+
+ ! Check the data.
+ call handle_err(nf90mpi_get_var_all(ncid, varid, data_in))
+ do x = 1, NX
+ do y = 1, NY
+ if (data_out(y, x) .ne. data_in(y, x)) stop 3
+ end do
+ end do
+
+ ! Close the file.
+ call handle_err(nf90mpi_close(ncid))
+
+ msg = '*** TESTING F90 '//trim(cmd)//' for def_var API'
+ if (my_rank .eq. 0) call pass_fail(0, msg)
+
+ 999 call MPI_Finalize(ierr)
+
+contains
+! This subroutine handles errors by printing an error message and
+! exiting with a non-zero status.
+ subroutine handle_err(errcode)
+ use pnetcdf
+ implicit none
+ integer, intent(in) :: errcode
+
+ if(errcode /= nf90_noerr) then
+ print *, 'Error: ', trim(nf90mpi_strerror(errcode))
+ stop 2
+ endif
+ end subroutine handle_err
+end program f90tst_vars
+
diff --git a/test/F90/f90tst_vars2.f90 b/test/F90/f90tst_vars2.f90
new file mode 100644
index 0000000..f53f899
--- /dev/null
+++ b/test/F90/f90tst_vars2.f90
@@ -0,0 +1,194 @@
+!
+! Copyright (C) 2013, Northwestern University and Argonne National Laboratory
+! See COPYRIGHT notice in top-level directory.
+!
+! This is part of the PnetCDF package.
+!
+! $Id: f90tst_vars2.f90 2136 2015-10-07 19:25:34Z wkliao $
+
+! This program tests PnetCDF variable functions from fortran 90.
+
+program f90tst_vars2
+ use mpi
+ use pnetcdf
+ implicit none
+
+ ! This is the name of the data file we will create.
+ character (len = *), parameter :: FILE_NAME = "f90tst_vars2.nc"
+
+ ! We are writing 2D data, a 6 x 12 grid.
+ integer, parameter :: MAX_DIMS = 2
+ integer, parameter :: NX = 6, NY = 12
+ integer :: data_out(NY, NX), data_in(NY, NX)
+ integer :: data_out_1d(NX), data_in_1d(NX)
+
+ ! We need these ids and other gunk for netcdf.
+ integer :: ncid, varid1, varid2, varid3, varid4, varid5, dimids(MAX_DIMS)
+ integer :: x_dimid, y_dimid
+ integer :: nvars, ngatts, ndims, unlimdimid, file_format
+ integer :: x, y
+ integer, parameter :: DEFLATE_LEVEL = 4
+ integer, parameter :: EightByteInt = selected_int_kind(18)
+ integer (kind = EightByteInt) :: TOE_SAN_VALUE = 2147483648_EightByteInt
+ character (len = *), parameter :: VAR1_NAME = "Chon-Ji"
+ character (len = *), parameter :: VAR2_NAME = "Tan-Gun"
+ character (len = *), parameter :: VAR3_NAME = "Toe-San"
+ character (len = *), parameter :: VAR4_NAME = "Won-Hyo"
+ character (len = *), parameter :: VAR5_NAME = "Yul-Guk"
+ integer, parameter :: CACHE_SIZE = 8, CACHE_NELEMS = 571
+ integer, parameter :: CACHE_PREEMPTION = 66
+
+ ! Information read back from the file to check correctness.
+ integer :: varid1_in, varid2_in, varid3_in, varid4_in, varid5_in
+ integer :: xtype_in, ndims_in, natts_in, dimids_in(MAX_DIMS)
+ character (len = nf90_max_name) :: name_in
+ integer (kind = EightByteInt) :: toe_san_in(1)
+ integer :: cmode, err, ierr, get_args
+ integer(KIND=MPI_OFFSET_KIND) :: nx_ll, ny_ll
+ character(LEN=256) filename, cmd, msg
+ integer my_rank, p
+
+ call MPI_Init(ierr)
+ call MPI_Comm_rank(MPI_COMM_WORLD, my_rank, ierr)
+ call MPI_Comm_size(MPI_COMM_WORLD, p, ierr)
+
+ ! take filename from command-line argument if there is any
+ if (my_rank .EQ. 0) then
+ filename = FILE_NAME
+ err = get_args(cmd, filename)
+ endif
+ call MPI_Bcast(err, 1, MPI_INTEGER, 0, MPI_COMM_WORLD, ierr)
+ if (err .EQ. 0) goto 999
+
+ call MPI_Bcast(filename, 256, MPI_CHARACTER, 0, MPI_COMM_WORLD, ierr)
+
+! if (p .ne. 1 .AND. my_rank .eq. 0) then
+! print *, 'Warning: ',trim(cmd),' is design to run on 1 process'
+! endif
+
+ ! Create some pretend data.
+ do x = 1, NX
+ do y = 1, NY
+ data_out(y, x) = (x - 1) * NY + (y - 1)
+ end do
+ end do
+ do x = 1, NX
+ data_out_1d(x) = x
+ end do
+
+ ! Create the netCDF file.
+ cmode = IOR(NF90_CLOBBER, NF90_64BIT_DATA)
+ call check(nf90mpi_create(MPI_COMM_WORLD, filename, cmode, MPI_INFO_NULL, ncid))
+
+ ! Define the dimensions.
+ nx_ll = NX
+ ny_ll = NY
+ call check(nf90mpi_def_dim(ncid, "x", nx_ll, x_dimid))
+ call check(nf90mpi_def_dim(ncid, "y", ny_ll, y_dimid))
+ dimids = (/ y_dimid, x_dimid /)
+
+ ! Define some variables.
+ call check(nf90mpi_def_var(ncid, VAR1_NAME, NF90_INT, dimids, varid1))
+ call check(nf90mpi_def_var(ncid, VAR2_NAME, NF90_INT, dimids, varid2))
+ call check(nf90mpi_def_var(ncid, VAR3_NAME, NF90_INT64, varid3))
+ call check(nf90mpi_def_var(ncid, VAR4_NAME, NF90_INT, x_dimid, varid4))
+ call check(nf90mpi_def_var(ncid, VAR5_NAME, NF90_INT, dimids, varid5))
+
+ call check(nf90mpi_enddef(ncid))
+
+ ! enter independent data mode
+ call check(nf90mpi_begin_indep_data(ncid))
+
+ ! Write the pretend data to the file.
+ call check(nf90mpi_put_var(ncid, varid1, data_out))
+ call check(nf90mpi_put_var(ncid, varid2, data_out))
+ call check(nf90mpi_put_var(ncid, varid3, TOE_SAN_VALUE))
+ call check(nf90mpi_put_var(ncid, varid4, data_out_1d))
+ call check(nf90mpi_put_var(ncid, varid5, data_out))
+
+ ! Close the file.
+ call check(nf90mpi_close(ncid))
+
+ ! Reopen the file.
+ call check(nf90mpi_open(MPI_COMM_WORLD, filename, nf90_nowrite, MPI_INFO_NULL, ncid))
+
+ ! Check some stuff out.
+ call check(nf90mpi_inquire(ncid, ndims, nvars, ngatts, unlimdimid, file_format))
+ if (ndims /= 2 .or. nvars /= 5 .or. ngatts /= 0 .or. unlimdimid /= -1 .or. &
+ file_format /= nf90_format_cdf5) stop 2
+
+ ! Get varids.
+ call check(nf90mpi_inq_varid(ncid, VAR1_NAME, varid1_in))
+ call check(nf90mpi_inq_varid(ncid, VAR2_NAME, varid2_in))
+ call check(nf90mpi_inq_varid(ncid, VAR3_NAME, varid3_in))
+ call check(nf90mpi_inq_varid(ncid, VAR4_NAME, varid4_in))
+ call check(nf90mpi_inq_varid(ncid, VAR5_NAME, varid5_in))
+
+ ! Check variable 1.
+ call check(nf90mpi_inquire_variable(ncid, varid1_in, name_in, xtype_in, ndims_in, dimids_in, natts_in))
+ if (name_in .ne. VAR1_NAME .or. xtype_in .ne. NF90_INT .or. ndims_in .ne. MAX_DIMS .or. &
+ natts_in .ne. 0 .or. dimids_in(1) .ne. dimids(1) .or. dimids_in(2) .ne. dimids(2)) stop 3
+
+ ! Check variable 2.
+ call check(nf90mpi_inquire_variable(ncid, varid2_in, name_in, xtype_in, ndims_in, dimids_in, natts_in))
+ if (name_in .ne. VAR2_NAME .or. xtype_in .ne. NF90_INT .or. ndims_in .ne. MAX_DIMS .or. &
+ natts_in .ne. 0 .or. dimids_in(1) .ne. dimids(1) .or. dimids_in(2) .ne. dimids(2)) stop 6
+
+ ! Check variable 3.
+ call check(nf90mpi_inquire_variable(ncid, varid3_in, name_in, xtype_in, ndims_in, dimids_in, natts_in))
+ if (name_in .ne. VAR3_NAME .or. xtype_in .ne. NF90_INT64 .or. ndims_in .ne. 0 .or. &
+ natts_in .ne. 0) stop 8
+
+ ! Check variable 4.
+ call check(nf90mpi_inquire_variable(ncid, varid4_in, name_in, xtype_in, ndims_in, dimids_in, natts_in))
+ if (name_in .ne. VAR4_NAME .or. xtype_in .ne. NF90_INT .or. ndims_in .ne. 1 .or. &
+ natts_in .ne. 0 .or. dimids_in(1) .ne. x_dimid) stop 10
+
+ ! Check the data.
+ call check(nf90mpi_get_var_all(ncid, varid1_in, data_in))
+ do x = 1, NX
+ do y = 1, NY
+ if (data_out(y, x) .ne. data_in(y, x)) stop 12
+ end do
+ end do
+ call check(nf90mpi_get_var_all(ncid, varid2_in, data_in))
+ do x = 1, NX
+ do y = 1, NY
+ if (data_out(y, x) .ne. data_in(y, x)) stop 13
+ end do
+ end do
+ call check(nf90mpi_get_var_all(ncid, varid3_in, toe_san_in))
+ if (toe_san_in(1) .ne. TOE_SAN_VALUE) stop 14
+ call check(nf90mpi_get_var_all(ncid, varid4_in, data_in_1d))
+ do x = 1, NX
+ if (data_out_1d(x) .ne. data_in_1d(x)) stop 15
+ end do
+ call check(nf90mpi_get_var_all(ncid, varid5_in, data_in))
+ do x = 1, NX
+ do y = 1, NY
+ if (data_out(y, x) .ne. data_in(y, x)) stop 12
+ end do
+ end do
+
+ ! Close the file.
+ call check(nf90mpi_close(ncid))
+
+ msg = '*** TESTING F90 '//trim(cmd)//' for def_var API'
+ if (my_rank .eq. 0) call pass_fail(0, msg)
+
+ 999 call MPI_Finalize(ierr)
+
+contains
+! This subroutine handles errors by printing an error message and
+! exiting with a non-zero status.
+ subroutine check(errcode)
+ implicit none
+ integer, intent(in) :: errcode
+
+ if(errcode /= nf90_noerr) then
+ print *, 'Error: ', trim(nf90mpi_strerror(errcode))
+ stop 2
+ endif
+ end subroutine check
+end program f90tst_vars2
+
diff --git a/test/F90/f90tst_vars3.f90 b/test/F90/f90tst_vars3.f90
new file mode 100644
index 0000000..74fe403
--- /dev/null
+++ b/test/F90/f90tst_vars3.f90
@@ -0,0 +1,193 @@
+!
+! Copyright (C) 2013, Northwestern University and Argonne National Laboratory
+! See COPYRIGHT notice in top-level directory.
+!
+! This is part of the PnetCDF package.
+!
+! $Id: f90tst_vars3.f90 2136 2015-10-07 19:25:34Z wkliao $
+
+! This program tests PnetCDF variable functions from fortran 90.
+
+program f90tst_vars3
+ use mpi
+ use pnetcdf
+ implicit none
+
+ ! This is the name of the data file we will create.
+ character (len = *), parameter :: FILE_NAME = "f90tst_vars3.nc"
+
+ ! We are writing 2D data, a 6 x 12 grid.
+ integer, parameter :: MAX_DIMS = 2
+ integer, parameter :: NX = 6, NY = 12
+ integer :: data_out(NY, NX), data_in(NY, NX)
+ integer :: data_out_1d(NX), data_in_1d(NX)
+
+ ! We need these ids and other gunk for netcdf.
+ integer :: ncid, varid1, varid2, varid3, varid4, varid5, dimids(MAX_DIMS)
+ integer :: x_dimid, y_dimid
+ integer :: nvars, ngatts, ndims, unlimdimid, file_format
+ integer :: x, y
+ integer, parameter :: DEFAULT_CACHE_NELEMS = 10000, DEFAULT_CACHE_SIZE = 1000000
+ integer, parameter :: DEFAULT_CACHE_PREEMPTION = 22
+ integer, parameter :: DEFLATE_LEVEL = 4
+ integer, parameter :: EightByteInt = selected_int_kind(18)
+ integer (kind = EightByteInt) :: TOE_SAN_VALUE = 2147483648_EightByteInt
+ character (len = *), parameter :: VAR1_NAME = "Chon-Ji"
+ character (len = *), parameter :: VAR2_NAME = "Tan-Gun"
+ character (len = *), parameter :: VAR3_NAME = "Toe-San"
+ character (len = *), parameter :: VAR4_NAME = "Won-Hyo"
+ character (len = *), parameter :: VAR5_NAME = "Yul-Guk"
+ integer, parameter :: CACHE_SIZE = 8, CACHE_NELEMS = 571, CACHE_PREEMPTION = 66
+
+ ! Information read back from the file to check correctness.
+ integer :: varid1_in, varid2_in, varid3_in, varid4_in, varid5_in
+ integer :: xtype_in, ndims_in, natts_in, dimids_in(MAX_DIMS)
+ character (len = nf90_max_name) :: name_in
+ integer (kind = EightByteInt) :: toe_san_in(1)
+ integer :: cmode, err, ierr, get_args
+ integer(KIND=MPI_OFFSET_KIND) :: nx_ll, ny_ll
+ character(LEN=256) filename, cmd, msg
+ integer my_rank, p
+
+ call MPI_Init(ierr)
+ call MPI_Comm_rank(MPI_COMM_WORLD, my_rank, ierr)
+ call MPI_Comm_size(MPI_COMM_WORLD, p, ierr)
+
+ ! take filename from command-line argument if there is any
+ if (my_rank .EQ. 0) then
+ filename = FILE_NAME
+ err = get_args(cmd, filename)
+ endif
+ call MPI_Bcast(err, 1, MPI_INTEGER, 0, MPI_COMM_WORLD, ierr)
+ if (err .EQ. 0) goto 999
+
+ call MPI_Bcast(filename, 256, MPI_CHARACTER, 0, MPI_COMM_WORLD, ierr)
+
+! if (p .ne. 1 .AND. my_rank .eq. 0) then
+! print *, 'Warning: ',trim(cmd),' is design to run on 1 process'
+! endif
+
+ ! Create some pretend data.
+ do x = 1, NX
+ do y = 1, NY
+ data_out(y, x) = (x - 1) * NY + (y - 1)
+ end do
+ end do
+ do x = 1, NX
+ data_out_1d(x) = x
+ end do
+
+ ! Create the netCDF file.
+ cmode = IOR(NF90_CLOBBER, NF90_64BIT_DATA)
+ call check(nf90mpi_create(MPI_COMM_WORLD, filename, cmode, MPI_INFO_NULL, ncid))
+
+ ! Define the dimensions.
+ nx_ll = NX
+ ny_ll = NY
+ call check(nf90mpi_def_dim(ncid, "x", nx_ll, x_dimid))
+ call check(nf90mpi_def_dim(ncid, "y", ny_ll, y_dimid))
+ dimids = (/ y_dimid, x_dimid /)
+
+ ! Define some variables.
+ call check(nf90mpi_def_var(ncid, VAR1_NAME, NF90_INT, dimids, varid1))
+ call check(nf90mpi_def_var(ncid, VAR2_NAME, NF90_INT, dimids, varid2))
+ call check(nf90mpi_def_var(ncid, VAR3_NAME, NF90_INT64, varid3))
+ call check(nf90mpi_def_var(ncid, VAR4_NAME, NF90_INT, x_dimid, varid4))
+ call check(nf90mpi_def_var(ncid, VAR5_NAME, NF90_INT, dimids, varid5))
+
+ call check(nf90mpi_enddef(ncid))
+ call check(nf90mpi_begin_indep_data(ncid))
+
+ ! Write the pretend data to the file.
+ call check(nf90mpi_put_var(ncid, varid1, data_out))
+ call check(nf90mpi_put_var(ncid, varid2, data_out))
+ call check(nf90mpi_put_var(ncid, varid3, TOE_SAN_VALUE))
+ call check(nf90mpi_put_var(ncid, varid4, data_out_1d))
+ call check(nf90mpi_put_var(ncid, varid5, data_out))
+
+ ! Close the file.
+ call check(nf90mpi_close(ncid))
+
+ ! Reopen the file.
+ call check(nf90mpi_open(MPI_COMM_WORLD, filename, nf90_nowrite, MPI_INFO_NULL, ncid))
+
+ ! Check some stuff out.
+ call check(nf90mpi_inquire(ncid, ndims, nvars, ngatts, unlimdimid, file_format))
+ if (ndims /= 2 .or. nvars /= 5 .or. ngatts /= 0 .or. unlimdimid /= -1 .or. &
+ file_format /= nf90_format_cdf5) stop 2
+
+ ! Get varids.
+ call check(nf90mpi_inq_varid(ncid, VAR1_NAME, varid1_in))
+ call check(nf90mpi_inq_varid(ncid, VAR2_NAME, varid2_in))
+ call check(nf90mpi_inq_varid(ncid, VAR3_NAME, varid3_in))
+ call check(nf90mpi_inq_varid(ncid, VAR4_NAME, varid4_in))
+ call check(nf90mpi_inq_varid(ncid, VAR5_NAME, varid5_in))
+
+ ! Check variable 1.
+ call check(nf90mpi_inquire_variable(ncid, varid1_in, name_in, xtype_in, ndims_in, dimids_in, natts_in))
+ if (name_in .ne. VAR1_NAME .or. xtype_in .ne. NF90_INT .or. ndims_in .ne. MAX_DIMS .or. &
+ natts_in .ne. 0 .or. dimids_in(1) .ne. dimids(1) .or. dimids_in(2) .ne. dimids(2)) stop 3
+
+ ! Check variable 2.
+ call check(nf90mpi_inquire_variable(ncid, varid2_in, name_in, xtype_in, ndims_in, dimids_in, natts_in))
+ if (name_in .ne. VAR2_NAME .or. xtype_in .ne. NF90_INT .or. ndims_in .ne. MAX_DIMS .or. &
+ natts_in .ne. 0 .or. dimids_in(1) .ne. dimids(1) .or. dimids_in(2) .ne. dimids(2)) stop 6
+
+ ! Check variable 3.
+ call check(nf90mpi_inquire_variable(ncid, varid3_in, name_in, xtype_in, ndims_in, dimids_in, natts_in))
+ if (name_in .ne. VAR3_NAME .or. xtype_in .ne. NF90_INT64 .or. ndims_in .ne. 0 .or. &
+ natts_in .ne. 0) stop 8
+
+ ! Check variable 4.
+ call check(nf90mpi_inquire_variable(ncid, varid4_in, name_in, xtype_in, ndims_in, dimids_in, natts_in))
+ if (name_in .ne. VAR4_NAME .or. xtype_in .ne. NF90_INT .or. ndims_in .ne. 1 .or. &
+ natts_in .ne. 0 .or. dimids_in(1) .ne. x_dimid) stop 10
+
+ ! Check the data.
+ call check(nf90mpi_get_var_all(ncid, varid1_in, data_in))
+ do x = 1, NX
+ do y = 1, NY
+ if (data_out(y, x) .ne. data_in(y, x)) stop 12
+ end do
+ end do
+ call check(nf90mpi_get_var_all(ncid, varid2_in, data_in))
+ do x = 1, NX
+ do y = 1, NY
+ if (data_out(y, x) .ne. data_in(y, x)) stop 13
+ end do
+ end do
+ call check(nf90mpi_get_var_all(ncid, varid3_in, toe_san_in))
+ if (toe_san_in(1) .ne. TOE_SAN_VALUE) stop 14
+ call check(nf90mpi_get_var_all(ncid, varid4_in, data_in_1d))
+ do x = 1, NX
+ if (data_out_1d(x) .ne. data_in_1d(x)) stop 15
+ end do
+ call check(nf90mpi_get_var_all(ncid, varid5_in, data_in))
+ do x = 1, NX
+ do y = 1, NY
+ if (data_out(y, x) .ne. data_in(y, x)) stop 12
+ end do
+ end do
+
+ ! Close the file.
+ call check(nf90mpi_close(ncid))
+
+ msg = '*** TESTING F90 '//trim(cmd)//' for def_var API'
+ if (my_rank .eq. 0) call pass_fail(0, msg)
+
+ 999 call MPI_Finalize(ierr)
+
+contains
+! This subroutine handles errors by printing an error message and
+! exiting with a non-zero status.
+ subroutine check(errcode)
+ implicit none
+ integer, intent(in) :: errcode
+
+ if(errcode /= nf90_noerr) then
+ print *, 'Error: ', trim(nf90mpi_strerror(errcode))
+ stop 2
+ endif
+ end subroutine check
+end program f90tst_vars3
+
diff --git a/test/F90/f90tst_vars4.f90 b/test/F90/f90tst_vars4.f90
new file mode 100644
index 0000000..c4fdfbd
--- /dev/null
+++ b/test/F90/f90tst_vars4.f90
@@ -0,0 +1,131 @@
+!
+! Copyright (C) 2013, Northwestern University and Argonne National Laboratory
+! See COPYRIGHT notice in top-level directory.
+!
+! This is part of the PnetCDF package.
+!
+! $Id: f90tst_vars4.f90 2131 2015-09-25 22:33:12Z wkliao $
+
+! This program tests PnetCDF variable functions from fortran 90.
+
+program f90tst_vars4
+ use mpi
+ use pnetcdf
+ implicit none
+
+ ! This is the name of the data file we will create.
+ character (len = *), parameter :: FILE_NAME = "f90tst_vars4.nc"
+
+ integer, parameter :: MAX_DIMS = 2
+ integer, parameter :: NX = 40, NY = 4096
+ integer :: data_out(NY, NX), data_in(NY, NX)
+
+ ! We need these ids and other gunk for netcdf.
+ integer :: ncid, varid, dimids(MAX_DIMS)
+ integer :: x_dimid, y_dimid
+ integer :: mode_flag
+ integer :: nvars, ngatts, ndims, unlimdimid, file_format
+ integer :: x, y
+ integer, parameter :: CACHE_SIZE = 1000000
+ integer :: xtype_in, natts_in, dimids_in(MAX_DIMS)
+ character (len = NF90_MAX_NAME) :: name_in
+ integer :: err, ierr, get_args
+ integer(KIND=MPI_OFFSET_KIND) :: nx_ll, ny_ll
+ character(LEN=256) filename, cmd, msg
+ integer my_rank, p
+
+ call MPI_Init(ierr)
+ call MPI_Comm_rank(MPI_COMM_WORLD, my_rank, ierr)
+ call MPI_Comm_size(MPI_COMM_WORLD, p, ierr)
+
+ ! take filename from command-line argument if there is any
+ if (my_rank .EQ. 0) then
+ filename = FILE_NAME
+ err = get_args(cmd, filename)
+ endif
+ call MPI_Bcast(err, 1, MPI_INTEGER, 0, MPI_COMM_WORLD, ierr)
+ if (err .EQ. 0) goto 999
+
+ call MPI_Bcast(filename, 256, MPI_CHARACTER, 0, MPI_COMM_WORLD, ierr)
+
+! if (p .ne. 1 .AND. my_rank .eq. 0) then
+! print *, 'Warning: ',trim(cmd),' is design to run on 1 process'
+! endif
+
+ ! Create some pretend data.
+ do x = 1, NX
+ do y = 1, NY
+ data_out(y, x) = (x - 1) * NY + (y - 1)
+ end do
+ end do
+
+ ! Create the netCDF file.
+ mode_flag = IOR(NF90_CLOBBER, NF90_64BIT_DATA)
+ call handle_err(nf90mpi_create(MPI_COMM_WORLD, filename, mode_flag, MPI_INFO_NULL, ncid))
+
+ ! Define the dimensions.
+ nx_ll = NX
+ ny_ll = NY
+ call handle_err(nf90mpi_def_dim(ncid, "x", nx_ll, x_dimid))
+ call handle_err(nf90mpi_def_dim(ncid, "y", ny_ll, y_dimid))
+ dimids = (/ y_dimid, x_dimid /)
+
+ ! Define the variable.
+ call handle_err(nf90mpi_def_var(ncid, 'data', NF90_INT, dimids, varid))
+
+ ! enddef must be called.
+ call handle_err(nf90mpi_enddef(ncid))
+
+ call handle_err(nf90mpi_begin_indep_data(ncid))
+
+ ! Write the pretend data to the file.
+ call handle_err(nf90mpi_put_var(ncid, varid, data_out))
+
+ ! Close the file.
+ call handle_err(nf90mpi_close(ncid))
+
+ ! Reopen the file.
+ call handle_err(nf90mpi_open(MPI_COMM_WORLD, filename, nf90_nowrite, MPI_INFO_NULL, ncid))
+
+ ! Check some stuff out.
+ call handle_err(nf90mpi_inquire(ncid, ndims, nvars, ngatts, unlimdimid, file_format))
+ if (ndims /= 2 .or. nvars /= 1 .or. ngatts /= 0 .or. unlimdimid /= -1 .or. &
+ file_format /= nf90_format_cdf5) stop 3
+
+ call handle_err(nf90mpi_inquire_variable(ncid, varid, name_in, xtype_in, ndims, dimids_in, &
+ natts_in))
+ if (name_in .ne. 'data' .or. xtype_in .ne. NF90_INT .or. ndims .ne. MAX_DIMS .or. &
+ dimids_in(1) /= y_dimid .or. dimids_in(2) /= x_dimid .or. &
+ natts_in .ne. 0) &
+ stop 4
+
+ ! Check the data.
+ call handle_err(nf90mpi_get_var_all(ncid, varid, data_in))
+ do x = 1, NX
+ do y = 1, NY
+ if (data_out(y, x) .ne. data_in(y, x)) stop 3
+ end do
+ end do
+
+ ! Close the file.
+ call handle_err(nf90mpi_close(ncid))
+
+ msg = '*** TESTING F90 '//trim(cmd)//' for def_var API'
+ if (my_rank .eq. 0) call pass_fail(0, msg)
+
+ 999 call MPI_Finalize(ierr)
+
+contains
+! This subroutine handles errors by printing an error message and
+! exiting with a non-zero status.
+ subroutine handle_err(errcode)
+ implicit none
+ integer, intent(in) :: errcode
+
+ if(errcode /= nf90_noerr) then
+ print *, 'Error: ', trim(nf90mpi_strerror(errcode))
+ stop 2
+ endif
+ end subroutine handle_err
+end program f90tst_vars4
+
diff --git a/test/F90/test_intent.f90 b/test/F90/test_intent.f90
new file mode 100644
index 0000000..0a0c607
--- /dev/null
+++ b/test/F90/test_intent.f90
@@ -0,0 +1,150 @@
+!
+! Copyright (C) 2013, Northwestern University and Argonne National Laboratory
+! See COPYRIGHT notice in top-level directory.
+!
+! $Id: test_intent.f90 2231 2015-12-16 21:08:02Z wkliao $
+
+!
+! This program tests Fortran 90 INTENT modifier used in PnetCDF.
+! It also tests put_att on Little Endian when using parameter
+! buffer (read-only memory)
+!
+ subroutine check(err, message)
+ use mpi
+ use pnetcdf
+ implicit none
+ integer err
+ character(len=*) message
+ character(len=256) msg
+
+ ! It is a good idea to check returned value for possible error
+ if (err .NE. NF90_NOERR) then
+ write(6,*) trim(message), trim(nf90mpi_strerror(err))
+ msg = '*** TESTING F90 test_intent.f90 '
+ call pass_fail(1, msg)
+ call MPI_Abort(MPI_COMM_WORLD, -1, err)
+ end if
+ end subroutine check
+
+ program main
+ use mpi
+ use pnetcdf
+ implicit none
+
+ integer, parameter :: OneByteInt = selected_int_kind(2), &
+ TwoByteInt = selected_int_kind(4), &
+ FourByteInt = selected_int_kind(9), &
+ EightByteInt = selected_int_kind(18)
+
+ character(LEN=256) filename, cmd, msg
+ integer err, ierr, rank, get_args
+ integer cmode, ncid, varid, dimid(1), req(1), status(1)
+ integer(kind=MPI_OFFSET_KIND) start(1)
+ integer(kind=MPI_OFFSET_KIND) count(1)
+ integer(kind=MPI_OFFSET_KIND) bufsize
+
+ character(LEN=3) cbuf
+ integer(KIND=OneByteInt) i1buf(3)
+ integer(KIND=TwoByteInt) sbuf(3)
+ integer ibuf(3)
+ real rbuf(3)
+ double precision dbuf(3)
+ integer(KIND=EightByteInt) i8buf(3)
+
+ PARAMETER( cbuf="123")
+ PARAMETER(i1buf=(/1_OneByteInt,2_OneByteInt,3_OneByteInt/))
+ PARAMETER( sbuf=(/1_TwoByteInt,2_TwoByteInt,3_TwoByteInt/))
+ PARAMETER( ibuf=(/1,2,3/))
+ PARAMETER( rbuf=(/1.0,2.0,3.0/))
+ PARAMETER( dbuf=(/1.0,2.0,3.0/))
+ PARAMETER(i8buf=(/1_EightByteInt,2_EightByteInt,3_EightByteInt/))
+
+ call MPI_Init(ierr)
+ call MPI_Comm_rank(MPI_COMM_WORLD, rank, ierr)
+
+ ! take filename from command-line argument if there is any
+ if (rank .EQ. 0) then
+ filename = 'testfile.nc'
+ err = get_args(cmd, filename)
+ endif
+ call MPI_Bcast(err, 1, MPI_INTEGER, 0, MPI_COMM_WORLD, ierr)
+ if (err .EQ. 0) goto 999
+
+ call MPI_Bcast(filename, 256, MPI_CHARACTER, 0, MPI_COMM_WORLD, ierr)
+
+ ! create file, truncate it if exists
+ cmode = IOR(NF90_CLOBBER, NF90_64BIT_DATA)
+ err = nf90mpi_create(MPI_COMM_WORLD, filename, cmode, &
+ MPI_INFO_NULL, ncid)
+ call check(err, 'In nf90mpi_create: ')
+
+ err = nf90mpi_put_att(ncid, NF90_GLOBAL, 'nf90_attr_text', cbuf)
+ call check(err, 'In nf90mpi_put_att: ')
+ err = nf90mpi_put_att(ncid, NF90_GLOBAL, 'nf90_attr_int1', i1buf)
+ call check(err, 'In nf90mpi_put_att: ')
+ err = nf90mpi_put_att(ncid, NF90_GLOBAL, 'nf90_attr_int2', sbuf)
+ call check(err, 'In nf90mpi_put_att: ')
+ err = nf90mpi_put_att(ncid, NF90_GLOBAL, 'nf90_attr_int', ibuf)
+ call check(err, 'In nf90mpi_put_att: ')
+ err = nf90mpi_put_att(ncid, NF90_GLOBAL, 'nf90_attr_real', rbuf)
+ call check(err, 'In nf90mpi_put_att: ')
+ err = nf90mpi_put_att(ncid, NF90_GLOBAL, 'nf90_attr_double', dbuf)
+ call check(err, 'In nf90mpi_put_att: ')
+ err = nf90mpi_put_att(ncid, NF90_GLOBAL, 'nf90_attr_int8', i8buf)
+ call check(err, 'In nf90mpi_put_att: ')
+
+ err = nfmpi_put_att_text(ncid, NF90_GLOBAL, 'nf_attr_text', 3_MPI_OFFSET_KIND, cbuf)
+ call check(err, 'In nfmpi_put_att_text: ')
+ err = nfmpi_put_att_int1(ncid, NF90_GLOBAL, 'nf_attr_int1', NF90_INT1, 3_MPI_OFFSET_KIND, i1buf)
+ call check(err, 'In nfmpi_put_att_int1: ')
+ err = nfmpi_put_att_int2(ncid, NF90_GLOBAL, 'nf_attr_int2', NF90_INT2, 3_MPI_OFFSET_KIND, sbuf)
+ call check(err, 'In nfmpi_put_att_int2: ')
+ err = nfmpi_put_att_int(ncid, NF90_GLOBAL, 'nf_attr_int', NF90_INT, 3_MPI_OFFSET_KIND, ibuf)
+ call check(err, 'In nfmpi_put_att_int: ')
+ err = nfmpi_put_att_real(ncid, NF90_GLOBAL, 'nf_attr_real', NF90_FLOAT, 3_MPI_OFFSET_KIND, rbuf)
+ call check(err, 'In nfmpi_put_att_real: ')
+ err = nfmpi_put_att_double(ncid, NF90_GLOBAL, 'nf_attr_double', NF90_DOUBLE, 3_MPI_OFFSET_KIND, dbuf)
+ call check(err, 'In nfmpi_put_att_double: ')
+ err = nfmpi_put_att_int8(ncid, NF90_GLOBAL, 'nf_attr_int8', NF90_INT64, 3_MPI_OFFSET_KIND, i8buf)
+ call check(err, 'In nfmpi_put_att_int8: ')
+
+ ! define a variable of an integer array of size 3 in the nc file
+ err = nfmpi_def_dim(ncid, 'X', 3_MPI_OFFSET_KIND, dimid(1))
+ call check(err, 'In nfmpi_def_dim: ')
+
+ err = nfmpi_def_var(ncid, 'var', NF90_INT, 1, dimid, varid)
+ call check(err, 'In nfmpi_def_var: ')
+
+ err = nfmpi_enddef(ncid)
+ call check(err, 'In nfmpi_enddef: ')
+
+ ! bufsize must be max of data type converted before and after
+ bufsize = 3*4
+ err = nfmpi_buffer_attach(ncid, bufsize)
+ call check(err, 'In nfmpi_buffer_attach: ')
+
+ start(1) = 1
+ count(1) = 3
+ err = nfmpi_bput_vara_int(ncid, varid, start, count, ibuf, req(1))
+ call check(err, 'In nfmpi_bput_vara_int: ')
+
+ err = nfmpi_wait_all(ncid, 1, req, status)
+ call check(err, 'In nfmpi_wait_all: ')
+
+ if (status(1) .ne. NF90_NOERR) then
+ print*,'Error at bput status ', nfmpi_strerror(status(1))
+ endif
+
+ err = nfmpi_buffer_detach(ncid)
+ call check(err, 'In nfmpi_buffer_detach: ')
+
+ ! close the file
+ err = nf90mpi_close(ncid)
+ call check(err, 'In nf90mpi_close: ')
+
+ msg = '*** TESTING F90 '//trim(cmd)//' for INTENT modifier '
+ if (rank .eq. 0) call pass_fail(0, msg)
+
+ 999 call MPI_Finalize(ierr)
+ end program main
+
diff --git a/test/F90/tst_f90.f90 b/test/F90/tst_f90.f90
new file mode 100644
index 0000000..4b57043
--- /dev/null
+++ b/test/F90/tst_f90.f90
@@ -0,0 +1,207 @@
+!
+! Copyright (C) 2013, Northwestern University and Argonne National Laboratory
+! See COPYRIGHT notice in top-level directory.
+!
+! This is part of the PnetCDF package.
+!
+! $Id: tst_f90.f90 2136 2015-10-07 19:25:34Z wkliao $
+
+! This program provides an elementary check of some of the parts of the
+! Fortran 90 interface to netCDF 3.5. It is a Fortran 90 implementation
+! of the nctst.cpp program provided with the C++ interface to netcdf
+! (in the src/cxx directory of the netcdf distribution).
+!
+module typeSizes
+ implicit none
+ public
+ integer, parameter :: OneByteInt = selected_int_kind(2), &
+ TwoByteInt = selected_int_kind(4), &
+ FourByteInt = selected_int_kind(9), &
+ EightByteInt = selected_int_kind(18)
+
+ integer, parameter :: &
+ FourByteReal = selected_real_kind(P = 6, R = 37), &
+ EightByteReal = selected_real_kind(P = 13, R = 307)
+contains
+ logical function byteSizesOK()
+ ! Users may call this function once to ensure that the kind parameters
+ ! the module defines are available with the current compiler.
+ ! We can't ensure that the two REAL kinds are actually four and
+ ! eight bytes long, but we can ensure that they are distinct.
+ ! Early Fortran 90 compilers would sometimes report incorrect results for
+ ! the bit_size intrinsic, but I haven't seen this in a long time.
+
+ ! Local variables
+ integer (kind = OneByteInt) :: One
+ integer (kind = TwoByteInt) :: Two
+ integer (kind = FourByteInt) :: Four
+
+ if (bit_size( One) == 8 .and. bit_size( Two) == 16 .and. &
+ bit_size(Four) == 32 .and. &
+ FourByteReal > 0 .and. EightByteReal > 0 .and. &
+ FourByteReal /= EightByteReal) then
+ byteSizesOK = .true.
+ else
+ byteSizesOK = .false.
+ end if
+ end function byteSizesOK
+end module typeSizes
+
+program netcdfTest
+ use mpi
+ use typeSizes
+ use pnetcdf
+ implicit none
+
+ ! netcdf related variables
+ integer :: ncFileID, &
+ latDimID, lonDimID, frTimeDimID, timeDimID, &
+ pressVarID, latVarID, lonVarID, frTimeVarID, refTimeVarID, scalarVarID
+
+ ! Local variables
+ integer (kind = EightByteInt), parameter :: numLats = 4, numLons = 3, &
+ numFrTimes = 2, timeStringLen = 20
+ character (len = *), parameter :: FILE_NAME = "tst_f90.nc"
+ integer :: counter, err, ierr, get_args
+ real, dimension(numLons, numLats, numFrTimes) :: pressure
+ integer (kind = FourByteInt), dimension(numFrTimes) :: frTimeVals
+ real (kind = FourByteReal) fillVal, scalarVarBuf
+ real (kind = FourByteReal), dimension(2) :: validRange
+ character (len = 20) frTimeUnits
+ real (kind = FourByteReal), dimension(numLats) :: latVarBuf
+ real (kind = FourByteReal), dimension(numLons) :: lonVarBuf
+ character(LEN=256) filename, cmd, msg
+ integer my_rank, p, info
+
+ call MPI_Init(ierr)
+ call MPI_Comm_rank(MPI_COMM_WORLD, my_rank, ierr)
+ call MPI_Comm_size(MPI_COMM_WORLD, p, ierr)
+
+ ! take filename from command-line argument if there is any
+ if (my_rank .EQ. 0) then
+ filename = FILE_NAME
+ err = get_args(cmd, filename)
+ endif
+ call MPI_Bcast(err, 1, MPI_INTEGER, 0, MPI_COMM_WORLD, ierr)
+ if (err .EQ. 0) goto 999
+
+ call MPI_Bcast(filename, 256, MPI_CHARACTER, 0, MPI_COMM_WORLD, ierr)
+
+! if (p .ne. 1 .AND. my_rank .eq. 0) then
+! print *, 'Warning: ',trim(cmd),' is design to run on 1 process'
+! endif
+
+! --------------------
+ ! Code begins
+ ! --------------------
+ if(.not. byteSizesOK()) then
+ print *, "Compiler does not appear to support required kinds of variables."
+ stop
+ end if
+
+ call MPI_Info_create(info, ierr)
+ ! call MPI_Info_set(info, "romio_pvfs2_posix_write", "enable",ierr)
+
+ ! Create the file
+ call check(nf90mpi_create(MPI_COMM_WORLD, filename, nf90_clobber, info, ncFileID))
+
+ ! Define the dimensions
+ call check(nf90mpi_def_dim(ncid = ncFileID, name = "lat", len = numLats, dimid = latDimID))
+ call check(nf90mpi_def_dim(ncid = ncFileID, name = "lon", len = numLons, dimid = lonDimID))
+ call check(nf90mpi_def_dim(ncid = ncFileID, name = "frtime", len = nf90mpi_unlimited, dimid = frTimeDimID))
+ call check(nf90mpi_def_dim(ncid = ncFileID, name = "timelen", len = timeStringLen, dimid = timeDimID))
+
+ ! Create variables and attributes
+ call check(nf90mpi_def_var(ncid = ncFileID, name = "P", xtype = nf90_float, &
+ dimids = (/ lonDimID, latDimID, frTimeDimID /), varID = pressVarID) )
+ call check(nf90mpi_put_att(ncFileID, pressVarID, "long_name", "pressure at maximum wind"))
+ call check(nf90mpi_put_att(ncFileID, pressVarID, "units", "hectopascals") )
+ ! Use 4-byte reals explicitly, to match 4-byte attribute type in test file
+ validRange(1) = 0.
+ validRange(2) = 1500
+ call check(nf90mpi_put_att(ncFileID, pressVarID, "valid_range", validRange))
+ ! Use a 4-byte float constant, to match variable type
+ fillVal = -9999.0
+ call check(nf90mpi_put_att(ncFileID, pressVarID, "_FillValue", fillVal ) )
+
+ call check(nf90mpi_def_var(ncFileID, "lat", nf90_float, dimids = latDimID, varID = latVarID) )
+ call check(nf90mpi_put_att(ncFileID, latVarID, "long_name", "latitude"))
+ call check(nf90mpi_put_att(ncFileID, latVarID, "units", "degrees_north"))
+
+ call check(nf90mpi_def_var(ncFileID, "lon", nf90_float, lonDimID, lonVarID) )
+ call check(nf90mpi_put_att(ncFileID, lonVarID, "long_name", "longitude"))
+ call check(nf90mpi_put_att(ncFileID, lonVarID, "units", "degrees_east"))
+
+ call check(nf90mpi_def_var(ncFileID, "frtime", nf90_int, frTimeDimID, frTimeVarID) )
+ call check(nf90mpi_put_att(ncFileID, frTimeVarID, "long_name", "forecast time"))
+ call check(nf90mpi_put_att(ncFileID, frTimeVarID, "units", "hours"))
+
+ call check(nf90mpi_def_var(ncFileID, "reftime", nf90_char, timeDimID, refTimeVarID) )
+ call check(nf90mpi_put_att(ncFileID, refTimeVarID, "long_name", "reference time"))
+ call check(nf90mpi_put_att(ncFileID, refTimeVarID, "units", "text_time"))
+
+ ! In the C++ interface the define a scalar variable - do we know how to do this?
+ call check(nf90mpi_def_var(ncFileID, "ScalarVariable", nf90_real, scalarVarID))
+
+ ! Global attributes
+ call check(nf90mpi_put_att(ncFileID, nf90_global, "history", &
+ "created by Unidata LDM from NPS broadcast"))
+ call check(nf90mpi_put_att(ncFileID, nf90_global, "title", &
+ "NMC Global Product Set: Pressure at Maximum Wind"))
+
+ ! Leave define mode
+ call check(nf90mpi_enddef(ncfileID))
+
+ ! Write the dimension variables
+ latVarBuf = (/ -90., -87.5, -85., -82.5 /)
+ call check(nf90mpi_put_var_all(ncFileID, latVarID, latVarBuf))
+ lonVarBuf = (/ -180, -175, -170 /)
+ call check(nf90mpi_put_var_all(ncFileID, lonVarID, lonVarBuf))
+ ! Don't use anonymous array here, in case platform has 8-byte integers
+ frTimeVals(1) = 12
+ frTimeVals(2) = 18
+ call check(nf90mpi_put_var_all(ncFileID, frTimeVarID, frTimeVals ) )
+ call check(nf90mpi_put_var_all(ncFileID, reftimeVarID, "1992-3-21 12:00" ) )
+
+ ! Write the pressure variable. Write a slab at a time to check incrementing.
+ pressure = 949. + real(reshape( (/ (counter, counter = 1, numLats * numLons * numFrTimes) /), &
+ (/ numLons, numLats, numFrTimes /) ) )
+ call check(nf90mpi_put_var_all(ncFileID, pressVarID, pressure(:, :, 1:1)) )
+ call check(nf90mpi_put_var_all(ncFileID, pressVarID, pressure(:, :, 2:2), &
+ start = (/ 1_EightByteInt, 1_EightByteInt, 2_EightByteInt /)) )
+
+ call check(nfmpi_begin_indep_data(ncFileID))
+ scalarVarBuf = 10
+ call check(nf90mpi_put_var(ncFileID, scalarVarID, scalarVarBuf))
+ call check(nfmpi_end_indep_data(ncFileID))
+
+ call check(nf90mpi_close(ncFileID))
+
+ ! Now open the file to read and check a few values
+ call check(nf90mpi_open(MPI_COMM_WORLD, filename, NF90_NOWRITE, info, ncFileID))
+ call check(nf90mpi_inq_varid(ncFileID,"frtime",frTimeVarID))
+ call check(nf90mpi_get_att(ncFileID,frTimeVarID,"units",frTimeUnits))
+ if(frTimeUnits .ne. "hours") then
+ print *, 'Attribute value not what was written:', frTimeUnits
+ stop 2
+ endif
+ call check(nf90mpi_close(ncFileID))
+ call MPI_Info_free(info, ierr)
+
+ msg = '*** TESTING F90 '//trim(cmd)
+ if (my_rank .eq. 0) call pass_fail(0, msg)
+
+ 999 call MPI_Finalize(ierr)
+
+contains
+ ! Internal subroutine - checks error status after each netcdf, prints out text message each time
+ ! an error code is returned.
+ subroutine check(status)
+ integer, intent ( in) :: status
+
+ if(status /= nf90_noerr) then
+ print *, trim(nf90mpi_strerror(status))
+ stop 2
+ end if
+ end subroutine check
+end program netcdfTest
diff --git a/test/F90/tst_f90_cdf5.f90 b/test/F90/tst_f90_cdf5.f90
new file mode 100644
index 0000000..a62fcbe
--- /dev/null
+++ b/test/F90/tst_f90_cdf5.f90
@@ -0,0 +1,79 @@
+!
+! Copyright (C) 2013, Northwestern University and Argonne National Laboratory
+! See COPYRIGHT notice in top-level directory.
+!
+! This is part of the PnetCDF package.
+!
+! $Id: tst_f90_cdf5.f90 2131 2015-09-25 22:33:12Z wkliao $
+
+
+program tst_f90_nc4
+ use mpi
+ use pnetcdf
+ implicit none
+ integer :: fh, cmode, err, ierr, dimid, varid, ndim, nvar, get_args
+ character (len = *), parameter :: FILE_NAME = "tst_f90_nc4.nc"
+ integer(KIND=MPI_OFFSET_KIND) :: ten=10
+ character(LEN=256) filename, cmd, msg
+ integer my_rank, p
+
+ call MPI_Init(ierr)
+ call MPI_Comm_rank(MPI_COMM_WORLD, my_rank, ierr)
+ call MPI_Comm_size(MPI_COMM_WORLD, p, ierr)
+
+ ! take filename from command-line argument if there is any
+ if (my_rank .EQ. 0) then
+ filename = FILE_NAME
+ err = get_args(cmd, filename)
+ endif
+ call MPI_Bcast(err, 1, MPI_INTEGER, 0, MPI_COMM_WORLD, ierr)
+ if (err .EQ. 0) goto 999
+
+ call MPI_Bcast(filename, 256, MPI_CHARACTER, 0, MPI_COMM_WORLD, ierr)
+
+! if (p .ne. 1 .AND. my_rank .eq. 0) then
+! print *, 'Warning: ',trim(cmd),' is design to run on 1 process'
+! endif
+
+ cmode = IOR(NF90_CLOBBER, NF90_64BIT_DATA)
+ call check(nf90mpi_create(MPI_COMM_WORLD, filename, cmode, MPI_INFO_NULL, fh))
+ call check(nf90mpi_def_dim(fh, 'fred', ten, dimid))
+ call check(nf90mpi_def_var(fh, 'john', NF90_INT, (/dimid/), varid))
+ call check(nf90mpi_close(fh))
+
+ ! Check the file.
+ call check(nf90mpi_open(MPI_COMM_WORLD, filename, NF90_WRITE, MPI_INFO_NULL, fh))
+ call check(nf90mpi_inquire(fh, nDimensions = ndim, nVariables = nvar))
+ if (nvar .ne. 1 .or. ndim .ne. 1) stop 3
+ call check(nf90mpi_close(fh))
+
+ call check(nf90mpi_create(MPI_COMM_WORLD, filename, cmode, MPI_INFO_NULL, fh))
+ call check(nf90mpi_def_dim(fh, 'fred', ten, dimid))
+ call check(nf90mpi_def_var(fh, 'john', NF90_INT, (/dimid/), varid))
+ call check(nf90mpi_close(fh))
+
+ ! Check the file.
+ call check(nf90mpi_open(MPI_COMM_WORLD, filename, NF90_WRITE, MPI_INFO_NULL, fh))
+ call check(nf90mpi_inquire(fh, nDimensions = ndim, nVariables = nvar))
+ if (nvar .ne. 1 .or. ndim .ne. 1) stop 3
+ call check(nf90mpi_close(fh))
+
+ msg = '*** TESTING F90 '//trim(cmd)
+ if (my_rank .eq. 0) call pass_fail(0, msg)
+
+ 999 call MPI_Finalize(ierr)
+
+contains
+! This subroutine handles errors by printing an error message and
+! exiting with a non-zero status.
+ subroutine check(errcode)
+ implicit none
+ integer, intent(in) :: errcode
+
+ if(errcode /= nf90_noerr) then
+ print *, 'Error: ', trim(nf90mpi_strerror(errcode))
+ stop 2
+ endif
+ end subroutine check
+end program tst_f90_nc4
+
diff --git a/test/F90/tst_flarge.f90 b/test/F90/tst_flarge.f90
new file mode 100644
index 0000000..b228da0
--- /dev/null
+++ b/test/F90/tst_flarge.f90
@@ -0,0 +1,102 @@
+!
+! Copyright (C) 2013, Northwestern University and Argonne National Laboratory
+! See COPYRIGHT notice in top-level directory.
+!
+! This is part of the PnetCDF package.
+!
+! $Id: tst_flarge.f90 2131 2015-09-25 22:33:12Z wkliao $
+
+! This program tests large files (> 4 GB)
+
+program tst_flarge
+ use mpi
+ use pnetcdf
+ implicit none
+
+ integer :: ncFileID, dimID, varID1, varID2
+ integer(KIND=MPI_OFFSET_KIND) :: BIG_DIMENSION = 300000000
+ character (len = *), parameter :: FILE_NAME = "tst_flarge.nc"
+ character (len = *), parameter :: dimName = "really_big_dimension"
+ character (len = *), parameter :: var1Name = "TweedleDum"
+ character (len = *), parameter :: var2Name = "TweedleDee"
+ double precision, parameter :: VAL1 = 42.5
+ double precision, parameter :: VAL2 = -42.5
+ double precision :: val1_in
+ double precision :: val2_in
+ integer :: cmode, err, ierr, get_args
+ double precision dbl_buf(1)
+ integer(KIND=MPI_OFFSET_KIND) :: start(1), count(1)
+ character(LEN=256) filename, cmd, msg
+ integer my_rank, p
+
+ call MPI_Init(ierr)
+ call MPI_Comm_rank(MPI_COMM_WORLD, my_rank, ierr)
+ call MPI_Comm_size(MPI_COMM_WORLD, p, ierr)
+
+ ! take filename from command-line argument if there is any
+ if (my_rank .EQ. 0) then
+ filename = FILE_NAME
+ err = get_args(cmd, filename)
+ endif
+ call MPI_Bcast(err, 1, MPI_INTEGER, 0, MPI_COMM_WORLD, ierr)
+ if (err .EQ. 0) goto 999
+
+ call MPI_Bcast(filename, 256, MPI_CHARACTER, 0, MPI_COMM_WORLD, ierr)
+
+! if (p .ne. 1 .AND. my_rank .eq. 0) then
+! print *, 'Warning: ',trim(cmd),' is design to run on 1 process'
+! endif
+
+ ! Create the file with 2 NF90_DOUBLE vars, each with one really long dimension.
+ cmode = IOR(NF90_CLOBBER, NF90_64BIT_DATA)
+ call check(nf90mpi_create(MPI_COMM_WORLD, filename, cmode, MPI_INFO_NULL, ncFileID))
+ call check(nf90mpi_def_dim(ncFileID, dimName, BIG_DIMENSION, dimID))
+ call check(nf90mpi_def_var(ncFileID, var1Name, nf90_double, (/ dimID /), varID1) )
+ call check(nf90mpi_def_var(ncFileID, var2Name, nf90_double, (/ dimID /), varID2) )
+
+ call check(nf90mpi_enddef(ncFileID))
+ call check(nf90mpi_begin_indep_data(ncFileID))
+
+ ! Write a value in each variable.
+ dbl_buf(1) = 42.5
+ start(1) = 1
+ count(1) = 1
+ call check(nf90mpi_put_var(ncFileID, VarID1, dbl_buf, start, count))
+ dbl_buf(1) = -42.5
+ start(1) = BIG_DIMENSION
+ count(1) = 1
+ call check(nf90mpi_put_var(ncFileID, VarID2, dbl_buf, start, count))
+
+ call check(nf90mpi_close(ncFileID))
+
+ ! Now open the file to read and check a few values
+ call check(nf90mpi_open(MPI_COMM_WORLD, filename, NF90_NOWRITE, MPI_INFO_NULL, ncFileID))
+ call check(nf90mpi_begin_indep_data(ncFileID))
+ start(1) = 1
+ call check(nf90mpi_get_var(ncFileID, VarID1, val1_in, start))
+ start(1) = BIG_DIMENSION
+ call check(nf90mpi_get_var(ncFileID, VarID2, val2_in, start))
+ if(val1_in /= VAL1 .or. val2_in /= VAL2) then
+ print *, 'Variable value not what was written'
+ stop 2
+ end if
+
+ call check(nf90mpi_close(ncFileID))
+
+ msg = '*** TESTING F90 '//trim(cmd)//' for large files'
+ if (my_rank .eq. 0) call pass_fail(0, msg)
+
+ 999 call MPI_Finalize(ierr)
+
+contains
+ ! Internal subroutine - checks error status after each netcdf, prints out text message each time
+ ! an error code is returned.
+ subroutine check(status)
+ integer, intent ( in) :: status
+
+ if(status /= nf90_noerr) then
+ print *, trim(nf90mpi_strerror(status))
+ stop 2
+ end if
+ end subroutine check
+end program tst_flarge
diff --git a/test/F90/tst_io.f90 b/test/F90/tst_io.f90
new file mode 100644
index 0000000..29f2d55
--- /dev/null
+++ b/test/F90/tst_io.f90
@@ -0,0 +1,176 @@
+!
+! Copyright (C) 2013, Northwestern University and Argonne National Laboratory
+! See COPYRIGHT notice in top-level directory.
+!
+! This is part of the PnetCDF package.
+!
+! $Id: tst_io.f90 2147 2015-10-09 23:50:26Z wkliao $
+
+! This program tests large files (> 4 GB) in PnetCDF.
+
+program tst_io
+ use mpi
+ use pnetcdf
+ implicit none
+ integer, parameter :: EightByteInt = selected_int_kind(18)
+ integer(kind=EightByteInt), parameter :: prsz1 = 50, prsz2 = 50, &
+ prsz3 = 50, prsz4 = 50, repct = 10
+ integer :: i1, i2, i3, i4
+ real :: psr
+ integer :: err, ierr, get_args
+ integer :: start, now, ncint1, ncint2, size
+ ! integer :: wrint1, wrint2, wrint3, ncint3
+ real, dimension (prsz1, prsz2, prsz3, prsz4) :: s, t, u, v, w, x, y, z
+ character(len = *), parameter :: nclFilenm1 = 'tst_io1.nc', &
+ nclFilenm2 = 'tst_io2.nc', nclFilenm3 = 'tst_io3.nc', &
+ nclFilenm4 = 'tst_io4.nc', nclFilenm5 = 'tst_io5.nc', &
+ nclFilenm6 = 'tst_io6.nc', nclFilenm7 = 'tst_io7.nc', &
+ nclFilenm8 = 'tst_io8.nc', nclFilenm9 = 'tst_io9.nc', &
+ nclFilenm10 = 'tst_io10.nc', nclFilenm11 = 'tst_io11.nc'
+ ! needed for netcdf
+ integer :: ncid, x1id, x2id, x3id, x4id, vrid
+ ! integer :: vrids, vridt, vridu, vridv, vridw, vridx, vridy, vridz
+ character(LEN=256) dirpath, cmd, msg
+ integer my_rank, p
+
+ call MPI_Init(ierr)
+ call MPI_Comm_rank(MPI_COMM_WORLD, my_rank, ierr)
+ call MPI_Comm_size(MPI_COMM_WORLD, p, ierr)
+
+ ! take filename from command-line argument if there is any
+ if (my_rank .EQ. 0) then
+ dirpath = '.'
+ err = get_args(cmd, dirpath)
+ endif
+ call MPI_Bcast(err, 1, MPI_INTEGER, 0, MPI_COMM_WORLD, ierr)
+ if (err .EQ. 0) goto 999
+
+ call MPI_Bcast(dirpath, 256, MPI_CHARACTER, 0, MPI_COMM_WORLD, ierr)
+
+! if (p .ne. 1 .AND. my_rank .eq. 0) then
+! print *, 'Warning: ',trim(cmd),' is design to run on 1 process'
+! endif
+
+ psr = 1.7/real(prsz1)
+ ! print *, "Starting data initialization."
+ size = (prsz1 * prsz2 * prsz3 * prsz4 )/ 250000
+ do i1 = 1, prsz1
+ do i2 = 1, prsz2
+ do i3 = 1, prsz3 ! Jackson Pollock it is not
+ do i4 = 1, prsz4
+ x(i1, i2, i3, i4) = sin(i1*psr)*(0.5 + cos(i2*psr))+(psr/i3)+ i4/(10.0*prsz4)
+ s(i1, i2, i3, i4) = x(i1, i2, i3, i4) - 5.0
+ t(i1, i2, i3, i4) = x(i1, i2, i3, i4) - 4.0
+ u(i1, i2, i3, i4) = x(i1, i2, i3, i4) - 3.0
+ v(i1, i2, i3, i4) = x(i1, i2, i3, i4) - 2.0
+ w(i1, i2, i3, i4) = x(i1, i2, i3, i4) - 1.0
+ y(i1, i2, i3, i4) = x(i1, i2, i3, i4) + 1.0
+ z(i1, i2, i3, i4) = x(i1, i2, i3, i4) + 2.0
+ enddo
+ enddo
+ enddo
+ enddo
+
+ ! call setupNetCDF (trim(dirpath)//'/'//nclFilenm1, ncid, vrid, x, prsz1, prsz2, prsz3, prsz4, &
+ call setupNetCDF (trim(dirpath)//'/'//nclFilenm1, ncid, vrid, prsz1, prsz2, prsz3, prsz4, &
+ x1id, x2id, x3id, x4id, NF90_CLOBBER, 20)
+ call system_clock(start)
+ call check(nfmpi_begin_indep_data(ncid), 11)
+ call check (NF90MPI_PUT_VAR(ncid, vrid, x), 18)
+ call check(nfmpi_end_indep_data(ncid), 11)
+ call system_clock(now)
+ ncint1 = now - start
+! print 3, size, "MB"," netcdf write = ", ncint1 * clockRate, &
+! real(ncint1)/real (wrint1)
+! 3 format("Time for", i5, a, a25, i7, " msec. Spd ratio = ", f5.2)
+
+ call check (NF90MPI_CLOSE(ncid), 14)
+
+ call system_clock(start)
+ do i1 = 1, repct
+ ! call setupNetCDF (trim(dirpath)//'/'//nclFilenm1, ncid, vrid, x, prsz1, prsz2, prsz3, prsz4, &
+ call setupNetCDF (trim(dirpath)//'/'//nclFilenm1, ncid, vrid, prsz1, prsz2, prsz3, prsz4, &
+ x1id, x2id, x3id, x4id, NF90_CLOBBER, 130)
+ call check(nfmpi_begin_indep_data(ncid), 11)
+ call check (NF90MPI_PUT_VAR(ncid, vrid, x), 23 + i1)
+ call check(nfmpi_end_indep_data(ncid), 11)
+ call check (NF90MPI_CLOSE(ncid), 15)
+ enddo
+ call system_clock(now)
+ ncint2 = now - start
+! print 4, size, repct, " repeated netcdf writes = ", ncint2 * clockRate, &
+! real(ncint2)/real(wrint2);
+! 4 format("Time for", i5, "MB", i3, a22, i7, " msec. Spd ratio = ", f5.2)
+
+! call system_clock(start)
+! call setupNetCDF (trim(dirpath)//'/'//nclFilenm3, ncid, vrids, s, prsz1, prsz2, prsz3, prsz4, &
+! x1id, x2id, x3id, x4id, NF90_CLOBBER, 20)
+! call setupNetCDF (trim(dirpath)//'/'//nclFilenm4, ncid, vridt, t, prsz1, prsz2, prsz3, prsz4, &
+! x1id, x2id, x3id, x4id, NF90_CLOBBER, 30)
+! call setupNetCDF (trim(dirpath)//'/'//nclFilenm5, ncid, vridu, u, prsz1, prsz2, prsz3, prsz4, &
+! x1id, x2id, x3id, x4id, NF90_CLOBBER, 40)
+! call setupNetCDF (trim(dirpath)//'/'//nclFilenm6, ncid, vridv, v, prsz1, prsz2, prsz3, prsz4, &
+! x1id, x2id, x3id, x4id, NF90_CLOBBER, 50)
+! call setupNetCDF (trim(dirpath)//'/'//nclFilenm7, ncid, vridw, w, prsz1, prsz2, prsz3, prsz4, &
+! x1id, x2id, x3id, x4id, NF90_CLOBBER, 60)
+! call setupNetCDF (trim(dirpath)//'/'//nclFilenm8, ncid, vridx, x, prsz1, prsz2, prsz3, prsz4, &
+! x1id, x2id, x3id, x4id, NF90_CLOBBER, 70)
+! call setupNetCDF (trim(dirpath)//'/'//nclFilenm9, ncid, vridy, y, prsz1, prsz2, prsz3, prsz4, &
+! x1id, x2id, x3id, x4id, NF90_CLOBBER, 80)
+! call setupNetCDF (trim(dirpath)//'/'//nclFilenm10, ncid, vridz, z, prsz1, prsz2, prsz3, prsz4, &
+! x1id, x2id, x3id, x4id, NF90_CLOBBER, 90)
+! call check(nfmpi_begin_indep_data(ncid), 11)
+! call check (NF90MPI_PUT_VAR(ncid, vrids, s), 118)
+! call check (NF90MPI_PUT_VAR(ncid, vridt, t), 119)
+! call check (NF90MPI_PUT_VAR(ncid, vridu, u), 120)
+! call check (NF90MPI_PUT_VAR(ncid, vridv, v), 121)
+! call check (NF90MPI_PUT_VAR(ncid, vridw, w), 122)
+! call check (NF90MPI_PUT_VAR(ncid, vridx, x), 123)
+! call check (NF90MPI_PUT_VAR(ncid, vridy, y), 124)
+! call check (NF90MPI_PUT_VAR(ncid, vridz, z), 125)
+! call check(nfmpi_end_indep_data(ncid), 11)
+! call system_clock(now)
+! ncint3 = now - start
+! call check (NF90MPI_CLOSE(ncid), 16)
+! print 4, size, 8, " netcdf file writes = ", ncint3 * clockRate, &
+! real(ncint3)/real(wrint3);
+
+ msg = '*** TESTING F90 '//trim(cmd)
+ if (my_rank .eq. 0) call pass_fail(0, msg)
+
+ 999 call MPI_Finalize(ierr)
+
+contains
+ subroutine check (st, n) ! checks the return error code
+ integer, intent (in) :: st, n
+ if ((n < 10.and.st /= 0).or.(n > 10.and.st /= NF90_noerr))then
+ print *, "I/O error at", n, " status = ", st
+ stop 2
+ endif
+ end subroutine check
+
+! subroutine setupNetCDF(fn, nc, vr, vrnam, d1, d2, d3, d4, do1, do2, &
+! real, dimension (:, :, :, :), intent (in) :: vrnam
+ subroutine setupNetCDF(fn, nc, vr, d1, d2, d3, d4, do1, do2, &
+ do3, do4, stat, deb)
+
+ character(len = *), intent(in) :: fn
+ integer(kind=EightByteInt), intent(in) :: d1, d2, d3, d4
+ integer, intent(in) :: stat, deb
+ integer, intent(out) :: do1, do2, do3, do4, vr
+ integer, intent(inout) :: nc
+ integer, dimension(4) :: dimids (4)
+
+ call check (NF90MPI_CREATE (MPI_COMM_WORLD, fn, stat, MPI_INFO_NULL, nc), deb + 1)
+ call check (NF90MPI_DEF_DIM(nc, "d1", d1, do1), deb + 2)
+ call check (NF90MPI_DEF_DIM(nc, "d2", d2, do2), deb + 3)
+ call check (NF90MPI_DEF_DIM(nc, "d3", d3, do3), deb + 4)
+ call check (NF90MPI_DEF_DIM(nc, "d4", d4, do4), deb + 5)
+
+ dimids = (/ do1, do2, do3, do4 /)
+ call check (NF90MPI_DEF_VAR(nc, "data", NF90_REAL, dimids, vr), deb + 6)
+ call check (NF90MPI_ENDDEF (nc), deb + 7)
+
+ end subroutine setupNetCDF
+
+end program tst_io
diff --git a/test/F90/tst_types2.f90 b/test/F90/tst_types2.f90
new file mode 100644
index 0000000..cdcb9b1
--- /dev/null
+++ b/test/F90/tst_types2.f90
@@ -0,0 +1,293 @@
+!
+! Copyright (C) 2013, Northwestern University and Argonne National Laboratory
+! See COPYRIGHT notice in top-level directory.
+!
+! This is part of the PnetCDF package.
+!
+! $Id: tst_types2.f90 2136 2015-10-07 19:25:34Z wkliao $
+
+! This program tests PnetCDF int64 types from fortran 90.
+
+program tst_types2
+ use mpi
+ use pnetcdf
+ implicit none
+
+ ! This is the name of the data file we will create.
+ character (len = *), parameter :: FILE_NAME = "tst_types2.nc"
+
+ integer :: ncid, varid1, varid2, varid3, varid4, varid5, varid6, varid7
+ integer :: dimid1, dimid2, dimid3, dimid4, dimid5, dimid6, dimid7
+ integer :: dimids1(1), dimids2(2), dimids3(3), dimids4(4), dimids5(5), dimids6(6), dimids7(7)
+ integer :: i1, i2, i3, i4, i5, i6, i7
+ integer, parameter :: DLEN = 2
+ integer, parameter :: EightByteInt = selected_int_kind(18)
+ integer (kind = EightByteInt) :: data1_in(DLEN), data1_out(DLEN)
+ integer (kind = EightByteInt) :: data2_in(DLEN, DLEN), data2_out(DLEN, DLEN)
+ integer (kind = EightByteInt) :: data3_in(DLEN, DLEN, DLEN), data3_out(DLEN, DLEN, DLEN)
+ integer (kind = EightByteInt) :: data4_in(DLEN, DLEN, DLEN, DLEN), data4_out(DLEN, DLEN, DLEN, DLEN)
+ integer (kind = EightByteInt) :: data5_in(DLEN, DLEN, DLEN, DLEN, DLEN), data5_out(DLEN, DLEN, DLEN, DLEN, DLEN)
+ integer (kind = EightByteInt) :: data6_in(DLEN, DLEN, DLEN, DLEN, DLEN, DLEN), data6_out(DLEN, DLEN, DLEN, DLEN, DLEN, DLEN)
+ integer (kind = EightByteInt) :: data7_in(DLEN, DLEN, DLEN, DLEN, DLEN, DLEN, DLEN), &
+ data7_out(DLEN, DLEN, DLEN, DLEN, DLEN, DLEN, DLEN)
+ integer (kind = EightByteInt), parameter :: REALLY_BIG = 9223372036854775807_EightByteInt
+
+ integer :: cmode, err, ierr, get_args
+ integer(KIND=MPI_OFFSET_KIND) :: dlen_ll
+ character(LEN=256) filename, cmd, msg
+ integer my_rank, p
+ logical verbose
+
+ call MPI_Init(ierr)
+ call MPI_Comm_rank(MPI_COMM_WORLD, my_rank, ierr)
+ call MPI_Comm_size(MPI_COMM_WORLD, p, ierr)
+
+ ! take filename from command-line argument if there is any
+ if (my_rank .EQ. 0) then
+ filename = FILE_NAME
+ err = get_args(cmd, filename)
+ endif
+ call MPI_Bcast(err, 1, MPI_INTEGER, 0, MPI_COMM_WORLD, ierr)
+ if (err .EQ. 0) goto 999
+
+ call MPI_Bcast(filename, 256, MPI_CHARACTER, 0, MPI_COMM_WORLD, ierr)
+
+ verbose = .FALSE.
+ if (p .ne. 4 .AND. my_rank .eq. 0 .AND. verbose) then
+ print *, 'Warning: ',trim(cmd),' is design to run on 4 processes.'
+ endif
+
+ do i1 = 1, DLEN
+ data1_out(i1) = REALLY_BIG
+ end do
+ do i2 = 1, DLEN
+ do i1 = 1, DLEN
+ data2_out(i1, i2) = REALLY_BIG - i1 - i2
+ end do
+ end do
+ do i3 = 1, DLEN
+ do i2 = 1, DLEN
+ do i1 = 1, DLEN
+ data3_out(i1, i2, i3) = REALLY_BIG - i1 - i2 - i3
+ end do
+ end do
+ end do
+ do i4 = 1, DLEN
+ do i3 = 1, DLEN
+ do i2 = 1, DLEN
+ do i1 = 1, DLEN
+ data4_out(i1, i2, i3, i4) = REALLY_BIG - i1 - i2 - i3 - i4
+ end do
+ end do
+ end do
+ end do
+ do i5 = 1, DLEN
+ do i4 = 1, DLEN
+ do i3 = 1, DLEN
+ do i2 = 1, DLEN
+ do i1 = 1, DLEN
+ data5_out(i1, i2, i3, i4, i5) = REALLY_BIG - i1 - i2 - i3 - i4 - i5
+ end do
+ end do
+ end do
+ end do
+ end do
+ do i6 = 1, DLEN
+ do i5 = 1, DLEN
+ do i4 = 1, DLEN
+ do i3 = 1, DLEN
+ do i2 = 1, DLEN
+ do i1 = 1, DLEN
+ data6_out(i1, i2, i3, i4, i5, i6) = REALLY_BIG - i1 - i2 - i3 - i4 - i5 - i6
+ end do
+ end do
+ end do
+ end do
+ end do
+ end do
+ do i7 = 1, DLEN
+ do i6 = 1, DLEN
+ do i5 = 1, DLEN
+ do i4 = 1, DLEN
+ do i3 = 1, DLEN
+ do i2 = 1, DLEN
+ do i1 = 1, DLEN
+ data7_out(i1, i2, i3, i4, i5, i6, i7) = REALLY_BIG - i1 - i2 - i3 - i4 - i5 - i6 - i7
+ end do
+ end do
+ end do
+ end do
+ end do
+ end do
+ end do
+
+ ! Create the netCDF file.
+ cmode = IOR(NF90_CLOBBER, NF90_64BIT_DATA)
+ call check(nf90mpi_create(MPI_COMM_WORLD, filename, cmode, MPI_INFO_NULL, ncid))
+
+ ! Define dimensions.
+ dlen_ll = DLEN
+ call check(nf90mpi_def_dim(ncid, "d1", dlen_ll, dimid1))
+ call check(nf90mpi_def_dim(ncid, "d2", dlen_ll, dimid2))
+ call check(nf90mpi_def_dim(ncid, "d3", dlen_ll, dimid3))
+ call check(nf90mpi_def_dim(ncid, "d4", dlen_ll, dimid4))
+ call check(nf90mpi_def_dim(ncid, "d5", dlen_ll, dimid5))
+ call check(nf90mpi_def_dim(ncid, "d6", dlen_ll, dimid6))
+ call check(nf90mpi_def_dim(ncid, "d7", dlen_ll, dimid7))
+
+ ! Create some int64 variables, from 1 to 7D.
+ dimids1(1) = dimid1
+ call check(nf90mpi_def_var(ncid, "v1", nf90_int64, dimids1, varid1))
+ dimids2(1) = dimid1
+ dimids2(2) = dimid2
+ call check(nf90mpi_def_var(ncid, "v2", nf90_int64, dimids2, varid2))
+ dimids3(1) = dimid1
+ dimids3(2) = dimid2
+ dimids3(3) = dimid3
+ call check(nf90mpi_def_var(ncid, "v3", nf90_int64, dimids3, varid3))
+ dimids4(1) = dimid1
+ dimids4(2) = dimid2
+ dimids4(3) = dimid3
+ dimids4(4) = dimid4
+ call check(nf90mpi_def_var(ncid, "v4", nf90_int64, dimids4, varid4))
+ dimids5(1) = dimid1
+ dimids5(2) = dimid2
+ dimids5(3) = dimid3
+ dimids5(4) = dimid4
+ dimids5(5) = dimid5
+ call check(nf90mpi_def_var(ncid, "v5", nf90_int64, dimids5, varid5))
+ dimids6(1) = dimid1
+ dimids6(2) = dimid2
+ dimids6(3) = dimid3
+ dimids6(4) = dimid4
+ dimids6(5) = dimid5
+ dimids6(6) = dimid6
+ call check(nf90mpi_def_var(ncid, "v6", nf90_int64, dimids6, varid6))
+ dimids7(1) = dimid1
+ dimids7(2) = dimid2
+ dimids7(3) = dimid3
+ dimids7(4) = dimid4
+ dimids7(5) = dimid5
+ dimids7(6) = dimid6
+ dimids7(7) = dimid7
+ call check(nf90mpi_def_var(ncid, "v7", nf90_int64, dimids7, varid7))
+
+ call check(nf90mpi_enddef(ncid))
+ ! enter independent data mode
+ call check(nf90mpi_begin_indep_data(ncid))
+
+ ! Write some large integers.
+ call check(nf90mpi_put_var(ncid, varid1, data1_out))
+ call check(nf90mpi_put_var(ncid, varid2, data2_out))
+ call check(nf90mpi_put_var(ncid, varid3, data3_out))
+ call check(nf90mpi_put_var(ncid, varid4, data4_out))
+ call check(nf90mpi_put_var(ncid, varid5, data5_out))
+ call check(nf90mpi_put_var(ncid, varid6, data6_out))
+ call check(nf90mpi_put_var(ncid, varid7, data7_out))
+
+ ! Close the file.
+ call check(nf90mpi_close(ncid))
+
+ ! Reopen the netCDF file.
+ call check(nf90mpi_open(MPI_COMM_WORLD, filename, nf90_nowrite, MPI_INFO_NULL, ncid))
+
+ ! Read in the large numbers.
+ call check(nf90mpi_get_var_all(ncid, varid1, data1_in))
+ call check(nf90mpi_get_var_all(ncid, varid2, data2_in))
+ call check(nf90mpi_get_var_all(ncid, varid3, data3_in))
+ call check(nf90mpi_get_var_all(ncid, varid4, data4_in))
+ call check(nf90mpi_get_var_all(ncid, varid5, data5_in))
+ call check(nf90mpi_get_var_all(ncid, varid6, data6_in))
+ call check(nf90mpi_get_var_all(ncid, varid7, data7_in))
+
+ ! Check the values for correctness.
+ do i1 = 1, DLEN
+ if (data1_in(i1) .ne. data1_out(i1)) stop 2
+ end do
+ do i2 = 1, DLEN
+ do i1 = 1, DLEN
+ if (data2_in(i1, i2) .ne. data2_out(i1, i2)) stop 2
+ end do
+ end do
+ do i3 = 1, DLEN
+ do i2 = 1, DLEN
+ do i1 = 1, DLEN
+ if (data3_in(i1, i2, i3) .ne. data3_out(i1, i2, i3)) stop 2
+ end do
+ end do
+ end do
+ do i4 = 1, DLEN
+ do i3 = 1, DLEN
+ do i2 = 1, DLEN
+ do i1 = 1, DLEN
+ if (data4_in(i1, i2, i3, i4) .ne. &
+ data4_out(i1, i2, i3, i4)) stop 2
+ end do
+ end do
+ end do
+ end do
+ do i5 = 1, DLEN
+ do i4 = 1, DLEN
+ do i3 = 1, DLEN
+ do i2 = 1, DLEN
+ do i1 = 1, DLEN
+ if (data5_in(i1, i2, i3, i4, i5) .ne. &
+ data5_out(i1, i2, i3, i4, i5)) stop 2
+ end do
+ end do
+ end do
+ end do
+ end do
+ do i6 = 1, DLEN
+ do i5 = 1, DLEN
+ do i4 = 1, DLEN
+ do i3 = 1, DLEN
+ do i2 = 1, DLEN
+ do i1 = 1, DLEN
+ if (data6_in(i1, i2, i3, i4, i5, i6) .ne. &
+ data6_out(i1, i2, i3, i4, i5, i6)) stop 2
+ end do
+ end do
+ end do
+ end do
+ end do
+ end do
+ do i7 = 1, DLEN
+ do i6 = 1, DLEN
+ do i5 = 1, DLEN
+ do i4 = 1, DLEN
+ do i3 = 1, DLEN
+ do i2 = 1, DLEN
+ do i1 = 1, DLEN
+ if (data7_in(i1, i2, i3, i4, i5, i6, i7) .ne. &
+ data7_out(i1, i2, i3, i4, i5, i6, i7)) stop 2
+ end do
+ end do
+ end do
+ end do
+ end do
+ end do
+ end do
+
+ ! Close the file.
+ call check(nf90mpi_close(ncid))
+
+ msg = '*** TESTING F90 '//trim(cmd)//' for 64-bit integer types'
+ if (my_rank .eq. 0) call pass_fail(0, msg)
+
+ 999 call MPI_Finalize(ierr)
+
+! This subroutine handles errors by printing an error message and
+! exiting with a non-zero status.
+contains
+ subroutine check(status)
+ integer, intent ( in) :: status
+
+ if(status /= nf90_noerr) then
+ print *, trim(nf90mpi_strerror(status))
+ stop 2
+ end if
+ end subroutine check
+
+end program tst_types2
+
diff --git a/test/Makefile.in b/test/Makefile.in
new file mode 100644
index 0000000..a5fdd02
--- /dev/null
+++ b/test/Makefile.in
@@ -0,0 +1,106 @@
+#
+# Copyright (C) 2003, Northwestern University and Argonne National Laboratory
+# See COPYRIGHT notice in top-level directory.
+#
+# $Id: Makefile.in 2249 2015-12-20 20:36:46Z wkliao $
+#
+# @configure_input@
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+include ../macros.make
+
+SUBDIRS = common \
+ nc_test \
+ C \
+ fandc \
+ nonblocking \
+ cdf_format \
+ header \
+ testcases
+
+# Packing subdirs must include all directories
+PACKING_SUBDIRS := $(SUBDIRS) largefile nf_test nf90_test F90 subfile CXX
+
+ifeq (@large_file_test@, yes)
+SUBDIRS += largefile
+endif
+
+ifeq (@has_mpicxx@, yes)
+SUBDIRS += CXX
+endif
+
+ifeq (@has_fortran@, yes)
+SUBDIRS += nf_test
+SUBDIRS += nf90_test
+SUBDIRS += F90
+endif
+
+ifeq (@enable_subfiling@, yes)
+SUBDIRS += subfile
+endif
+
+PACKING_LIST = Makefile.in
+
+all: $(SUBDIRS)
+$(SUBDIRS):
+ $(MAKE) $(MFLAGS) -C $@
+
+tests: all
+
+test_int: common
+test_float: common
+test_double_int: common
+test_double: common
+
+CHECK_DIRS = $(SUBDIRS:%=check-%)
+check testing: $(CHECK_DIRS)
+$(CHECK_DIRS):
+ $(MAKE) $(MFLAGS) -C $(@:check-%=%) testing
+
+VCHECK_DIRS = $(SUBDIRS:%=vcheck-%)
+verbose_check verbose_testing: $(VCHECK_DIRS)
+$(VCHECK_DIRS):
+ $(MAKE) $(MFLAGS) -C $(@:vcheck-%=%) verbose_testing
+
+ptest: all
+ifeq (@enable_coverage@, yes)
+ echo "Parallel test is disabled because coverage analysis was enabled"
+else
+ (echo "=============================================") && \
+ (echo " Parallel testing on 4 MPI processes") && \
+ (echo "=============================================") && \
+ ( for d in $(SUBDIRS) ; do \
+ $(MAKE) $(MFLAGS) -C $$d ptest4 ; \
+ done ) ;
+endif
+
+ptests: all
+ifeq (@enable_coverage@, yes)
+ echo "Parallel test is disabled because coverage analysis was enabled"
+else
+ for i in 2 4 6 8 10 ; do \
+ (echo "=============================================") && \
+ (echo " Parallel testing on $$i MPI processes") && \
+ (echo "=============================================") && \
+ ( for d in $(SUBDIRS) ; do \
+ $(MAKE) $(MFLAGS) -C $$d ptest$$i ; \
+ done ) ; \
+ done ;
+endif
+
+INSTALLDIRS = $(SUBDIRS:%=install-%)
+install: all $(INSTALLDIRS)
+$(INSTALLDIRS):
+ $(MAKE) $(MFLAGS) -C $(@:install-%=%) install
+
+UNINSTALLDIRS = $(SUBDIRS:%=uninstall-%)
+uninstall: $(UNINSTALLDIRS)
+$(UNINSTALLDIRS):
+ $(MAKE) $(MFLAGS) -C $(@:uninstall-%=%) uninstall
+
+include $(srcdir)/../rules.make
+
+.NOTPARALLEL:
+
diff --git a/test/cdf_format/Makefile.in b/test/cdf_format/Makefile.in
new file mode 100644
index 0000000..2bdd397
--- /dev/null
+++ b/test/cdf_format/Makefile.in
@@ -0,0 +1,77 @@
+#
+# Copyright (C) 2003, Northwestern University and Argonne National Laboratory
+# See COPYRIGHT notice in top-level directory.
+#
+# $Id: Makefile.in 2306 2016-01-12 19:34:31Z wkliao $
+#
+# @configure_input@
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+include ../../macros.make
+
+INCLUDES = -I../../src/lib -I$(srcdir)/../common
+LDFLAGS := $(LDFLAGS) -L../common
+LIBS := $(LIBRARY) -ltestutils $(LIBS) @LCOV_LIB@
+ifeq (@PNC_DEBUG@, yes)
+CPPFLAGS := $(CPPFLAGS) -DPNC_DEBUG
+endif
+
+SRCS = test_inq_format.c \
+ cdf_type.c \
+ dim_cdf12.c
+
+OBJS = $(SRCS:.c=.o)
+PROGS = $(SRCS:.c=)
+
+GARBAGE = $(PROGS) testfile.nc
+PACKING_LIST = $(SRCS) Makefile.in depend \
+ test_cdf1.nc test_cdf2.nc test_cdf5.nc
+
+all: $(PROGS)
+
+$(OBJS): $(srcdir)/../common/testutils.h
+
+$(PROGS): ../common/libtestutils.a
+
+../common/libtestutils.a:
+ set -e; cd ../common && $(MAKE) $(MFLAGS) all
+
+test_inq_format: test_inq_format.o $(LIBRARY)
+ $(LINK.c) $< $(LDFLAGS) $(LIBS)
+
+cdf_type: cdf_type.o $(LIBRARY)
+ $(LINK.c) $< $(LDFLAGS) $(LIBS)
+
+dim_cdf12: dim_cdf12.o $(LIBRARY)
+ $(LINK.c) $< $(LDFLAGS) $(LIBS)
+
+testing check verbose_testing: all
+ $(TEST_SEQRUN) ./test_inq_format $(srcdir)
+ $(TEST_SEQRUN) ./cdf_type $(TEST_OUTDIR)/testfile.nc
+ $(TEST_SEQRUN) ./dim_cdf12 $(TEST_OUTDIR)/testfile.nc
+
+# Some of these tests are designed to run on one process,
+# # Run them on 4 processes to see if they can handle well
+# Some of these tests are designed to run on 4 processes,
+# # Run them on 2, 4, and 6 processes to see if they can handle well
+TEST_MPIRUN_2 = $(subst NP,2,$(TEST_MPIRUN))
+TEST_MPIRUN_4 = $(subst NP,4,$(TEST_MPIRUN))
+TEST_MPIRUN_6 = $(subst NP,6,$(TEST_MPIRUN))
+TEST_MPIRUN_8 = $(subst NP,8,$(TEST_MPIRUN))
+TEST_MPIRUN_10 = $(subst NP,10,$(TEST_MPIRUN))
+
+ptest4: $(PROGS)
+ $(TEST_MPIRUN_4) ./test_inq_format $(srcdir)
+ $(TEST_MPIRUN_4) ./cdf_type $(TEST_OUTDIR)/testfile.nc
+ $(TEST_MPIRUN_4) ./dim_cdf12 $(TEST_OUTDIR)/testfile.nc
+
+ptest ptests: ptest4
+
+ptest2 ptest6 ptest8 ptest10:
+
+include $(srcdir)/../../rules.make
+include $(srcdir)/depend
+
+$(LIBRARY): ;
diff --git a/test/cdf_format/cdf_type.c b/test/cdf_format/cdf_type.c
new file mode 100644
index 0000000..a7fb131
--- /dev/null
+++ b/test/cdf_format/cdf_type.c
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2013, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ */
+/* $Id: cdf_type.c 2133 2015-09-26 19:16:01Z wkliao $ */
+
+/* This program tests if PnetCDF can detect CDF-5 data types that are not
+ * available in CDF-1 and CDF-2 formats
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <mpi.h>
+#include <pnetcdf.h>
+#include <testutils.h>
+
+#define ERR {if(err!=NC_NOERR) {printf("Error(%d) at line %d: %s\n",err,__LINE__,ncmpi_strerror(err)); nerrs++; }}
+
+/*----< test_attr_types() >---------------------------------------------------*/
+static
+int test_attr_types(char *filename,
+ int format)
+{
+ int i, err, rank, ncid, cmode, nerrs=0, attr=0;
+ MPI_Info info=MPI_INFO_NULL;
+ MPI_Comm comm=MPI_COMM_WORLD;
+ nc_type xtype[5]={NC_UBYTE, NC_USHORT, NC_UINT, NC_INT64, NC_UINT64};
+
+ MPI_Comm_rank(comm, &rank);
+ cmode = NC_CLOBBER|format;
+
+ /* create a file in CDF-1 or CDF-2 format */
+ err = ncmpi_create(comm, filename, cmode, info, &ncid); ERR
+ for (i=0; i<5; i++) {
+ char name[32];
+ sprintf(name, "gattr_%d", i);
+ err = ncmpi_put_att_int(ncid, NC_GLOBAL, name, xtype[i], 1, &attr);
+ if (err != NC_ESTRICTCDF2) {
+ printf("Error (line=%d): expecting NC_ESTRICTCDF2 but got %s\n", __LINE__,nc_err_code_name(err));
+ nerrs++;
+ }
+ }
+
+ err = ncmpi_close(ncid); ERR
+
+ return nerrs;
+}
+
+/*----< test_var_types() >----------------------------------------------------*/
+static
+int test_var_types(char *filename,
+ int format)
+{
+ int i, err, rank, ncid, cmode, nerrs=0;
+ int dimid, varid[5];
+ MPI_Info info=MPI_INFO_NULL;
+ MPI_Comm comm=MPI_COMM_WORLD;
+ nc_type xtype[5]={NC_UBYTE, NC_USHORT, NC_UINT, NC_INT64, NC_UINT64};
+
+ MPI_Comm_rank(comm, &rank);
+ cmode = NC_CLOBBER|format;
+
+ /* create a file in CDF-1 or CDF-2 format */
+ err = ncmpi_create(comm, filename, cmode, info, &ncid); ERR
+ err = ncmpi_def_dim(ncid, "dim", NC_UNLIMITED, &dimid); ERR
+ for (i=0; i<5; i++) {
+ char name[32];
+ sprintf(name, "var_%d", i);
+ err = ncmpi_def_var(ncid, name, xtype[i], 1, &dimid, &varid[i]);
+ if (err != NC_ESTRICTCDF2) {
+ printf("Error (line=%d): expecting NC_ESTRICTCDF2 but got %s\n", __LINE__,nc_err_code_name(err));
+ nerrs++;
+ }
+ }
+ err = ncmpi_close(ncid); ERR
+
+ return nerrs;
+}
+
+/*----< main() >--------------------------------------------------------------*/
+int main(int argc, char **argv)
+{
+ char *filename="testfile.nc";
+ int rank, nerrs=0;
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+
+ if (argc > 2) {
+ if (!rank) printf("Usage: %s [filename]\n",argv[0]);
+ MPI_Finalize();
+ return 0;
+ }
+ if (argc == 2) filename = argv[1];
+
+ if (rank == 0) {
+ char cmd_str[256];
+ sprintf(cmd_str, "*** TESTING C %s for CDF-5 type in CDF-1 and 2 ", argv[0]);
+ printf("%-66s ------ ", cmd_str);
+ }
+
+ nerrs += test_attr_types(filename, 0);
+ nerrs += test_attr_types(filename, NC_64BIT_OFFSET);
+
+ nerrs += test_var_types(filename, 0);
+ nerrs += test_var_types(filename, NC_64BIT_OFFSET);
+
+ MPI_Offset malloc_size, sum_size;
+ int err = ncmpi_inq_malloc_size(&malloc_size);
+ if (err == NC_NOERR) {
+ MPI_Reduce(&malloc_size, &sum_size, 1, MPI_OFFSET, MPI_SUM, 0, MPI_COMM_WORLD);
+ if (rank == 0 && sum_size > 0)
+ printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n",
+ sum_size);
+ }
+
+ if (rank == 0) {
+ if (nerrs) printf(FAIL_STR,nerrs);
+ else printf(PASS_STR);
+ }
+
+ MPI_Finalize();
+ return 0;
+}
+
diff --git a/test/cdf_format/depend b/test/cdf_format/depend
new file mode 100644
index 0000000..09cc529
--- /dev/null
+++ b/test/cdf_format/depend
@@ -0,0 +1,3 @@
+test_inq_format.o: test_inq_format.c
+cdf_type.o: cdf_type.c
+dim_cdf12.o: dim_cdf12.c
diff --git a/test/cdf_format/dim_cdf12.c b/test/cdf_format/dim_cdf12.c
new file mode 100644
index 0000000..0431ded
--- /dev/null
+++ b/test/cdf_format/dim_cdf12.c
@@ -0,0 +1,202 @@
+/*********************************************************************
+ *
+ * Copyright (C) 2016, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ *
+ *********************************************************************/
+/* $Id$ */
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ *
+ * This program is to test CDF-1, CDF-2 file formats using the allowable
+ * maximal dimension size
+ *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h> /* strcpy() */
+#include <limits.h>
+#include <mpi.h>
+#include <pnetcdf.h>
+#include <testutils.h>
+
+#define FOUR_G 4294967296
+#define TWO_G 2147483648
+#define ONE_G 1073741824
+
+#define NZ 4
+#define NY 10
+#define NX TWO_G
+
+#define ERR if (err!=NC_NOERR) {printf("Error at line %d: err=%s (%s)\n", __LINE__,nc_err_code_name(err),ncmpi_strerror(err)); nerrs++;}
+
+#define ERR_EXPECT(exp) if (err!=exp) {printf("Error at line %d: expect error %s but got %s\n", __LINE__,nc_err_code_name(exp),nc_err_code_name(err)); nerrs++;}
+
+int main(int argc, char** argv)
+{
+ char filename[256];
+ int rank, nprocs, err, nerrs=0;
+ int ncid, cmode, varid, dimid[3];
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+
+ /* get command-line arguments */
+ if (argc > 2) {
+ if (!rank) printf("Usage: %s [filename]\n",argv[0]);
+ MPI_Finalize();
+ return 0;
+ }
+ strcpy(filename, "testfile.nc");
+ if (argc == 2) strcpy(filename, argv[1]);
+ MPI_Bcast(filename, 256, MPI_CHAR, 0, MPI_COMM_WORLD);
+
+ if (rank == 0) {
+ char cmd_str[256];
+ sprintf(cmd_str, "*** TESTING C %s for defining dim in CDF-1/2 format ", argv[0]);
+ printf("%-66s ------ ", cmd_str); fflush(stdout);
+ }
+
+ /* create a new CDF-1 file ----------------------------------------------*/
+ cmode = NC_CLOBBER;
+
+ /* max dimension size for CDF-2 file is 2^31-3 = 2147483647 - 3 */
+ err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, MPI_INFO_NULL, &ncid); ERR
+ err = ncmpi_def_dim(ncid, "Y", INT_MAX, &dimid[0]);
+ ERR_EXPECT(NC_EDIMSIZE)
+ err = ncmpi_def_dim(ncid, "Y", INT_MAX-3, &dimid[0]); ERR
+ err = ncmpi_close(ncid); ERR
+ err = ncmpi_open(MPI_COMM_WORLD, filename, NC_NOWRITE, MPI_INFO_NULL, &ncid); ERR
+ err = ncmpi_close(ncid); ERR
+
+ err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, MPI_INFO_NULL, &ncid); ERR
+ err = ncmpi_def_dim(ncid, "Y", INT_MAX-3, &dimid[0]); ERR
+ err = ncmpi_def_var(ncid, "var0", NC_CHAR, 1, dimid, &varid); ERR
+ err = ncmpi_close(ncid); ERR
+ err = ncmpi_open(MPI_COMM_WORLD, filename, NC_NOWRITE, MPI_INFO_NULL, &ncid); ERR
+ err = ncmpi_close(ncid); ERR
+
+ err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, MPI_INFO_NULL, &ncid); ERR
+ err = ncmpi_def_dim(ncid, "Y", INT_MAX-3, &dimid[0]); ERR
+ err = ncmpi_def_dim(ncid, "X", 2, &dimid[1]); ERR
+ err = ncmpi_def_var(ncid, "var0", NC_CHAR, 1, &dimid[0], &varid); ERR
+ err = ncmpi_def_var(ncid, "var1", NC_INT, 1, &dimid[1], &varid); ERR
+ err = ncmpi_close(ncid);
+ ERR_EXPECT(NC_EVARSIZE)
+
+ err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, MPI_INFO_NULL, &ncid); ERR
+ err = ncmpi_def_dim(ncid, "Y", INT_MAX-1024, &dimid[0]); ERR
+ err = ncmpi_def_dim(ncid, "X", 2, &dimid[1]); ERR
+ err = ncmpi_def_var(ncid, "var0", NC_CHAR, 1, &dimid[0], &varid); ERR
+ err = ncmpi_def_var(ncid, "var1", NC_INT, 1, &dimid[1], &varid); ERR
+ err = ncmpi_close(ncid); ERR
+ err = ncmpi_open(MPI_COMM_WORLD, filename, NC_NOWRITE, MPI_INFO_NULL, &ncid); ERR
+ err = ncmpi_close(ncid); ERR
+
+ err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, MPI_INFO_NULL, &ncid); ERR
+ err = ncmpi_def_dim(ncid, "Y", INT_MAX-3, &dimid[0]); ERR
+ err = ncmpi_def_dim(ncid, "X", 2, &dimid[1]); ERR
+ err = ncmpi_def_var(ncid, "var0", NC_SHORT, 1, &dimid[0], &varid); ERR
+ err = ncmpi_def_var(ncid, "var1", NC_CHAR, 1, &dimid[1], &varid); ERR
+ err = ncmpi_close(ncid);
+ ERR_EXPECT(NC_EVARSIZE)
+
+ err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, MPI_INFO_NULL, &ncid); ERR
+ err = ncmpi_def_dim(ncid, "Y", INT_MAX-3-512-8, &dimid[0]); ERR
+ err = ncmpi_def_dim(ncid, "X", 2, &dimid[1]); ERR
+ err = ncmpi_def_var(ncid, "var0", NC_CHAR, 1, &dimid[0], &varid); ERR
+ err = ncmpi_def_var(ncid, "var1", NC_INT, 1, &dimid[1], &varid); ERR
+ err = ncmpi_close(ncid); ERR
+
+ err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, MPI_INFO_NULL, &ncid); ERR
+ err = ncmpi_def_dim(ncid, "Y", INT_MAX/2+1, &dimid[0]); ERR
+ err = ncmpi_def_dim(ncid, "X", 2, &dimid[1]); ERR
+ err = ncmpi_def_var(ncid, "var0", NC_INT, 1, &dimid[0], &varid); ERR
+ err = ncmpi_def_var(ncid, "var1", NC_INT, 1, &dimid[1], &varid); ERR
+ err = ncmpi_close(ncid);
+ ERR_EXPECT(NC_EVARSIZE)
+
+ /* create a new CDF-2 file ----------------------------------------------*/
+ cmode = NC_CLOBBER;
+ cmode = NC_CLOBBER | NC_64BIT_OFFSET;
+
+ /* max dimension size for CDF-2 file is 2^32-3 = 4294967295 - 3 */
+ err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, MPI_INFO_NULL, &ncid); ERR
+ err = ncmpi_def_dim(ncid, "Y", UINT_MAX, &dimid[0]);
+ ERR_EXPECT(NC_EDIMSIZE)
+ err = ncmpi_def_dim(ncid, "Y", UINT_MAX-3, &dimid[0]); ERR
+ err = ncmpi_close(ncid); ERR
+ err = ncmpi_open(MPI_COMM_WORLD, filename, NC_NOWRITE, MPI_INFO_NULL, &ncid); ERR
+ err = ncmpi_close(ncid); ERR
+
+ err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, MPI_INFO_NULL, &ncid); ERR
+ err = ncmpi_def_dim(ncid, "Y", UINT_MAX-3, &dimid[0]); ERR
+ err = ncmpi_def_var(ncid, "var0", NC_CHAR, 1, dimid, &varid); ERR
+ err = ncmpi_close(ncid); ERR
+ err = ncmpi_open(MPI_COMM_WORLD, filename, NC_NOWRITE, MPI_INFO_NULL, &ncid); ERR
+ err = ncmpi_close(ncid); ERR
+
+ err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, MPI_INFO_NULL, &ncid); ERR
+ err = ncmpi_def_dim(ncid, "Y", UINT_MAX-3, &dimid[0]); ERR
+ err = ncmpi_def_dim(ncid, "X", 2, &dimid[1]); ERR
+ err = ncmpi_def_var(ncid, "var0", NC_CHAR, 1, &dimid[0], &varid); ERR
+ err = ncmpi_def_var(ncid, "var1", NC_INT, 1, &dimid[1], &varid); ERR
+ err = ncmpi_close(ncid); ERR
+ err = ncmpi_open(MPI_COMM_WORLD, filename, NC_NOWRITE, MPI_INFO_NULL, &ncid); ERR
+ err = ncmpi_close(ncid); ERR
+
+ err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, MPI_INFO_NULL, &ncid); ERR
+ err = ncmpi_def_dim(ncid, "Y", UINT_MAX-3, &dimid[0]); ERR
+ err = ncmpi_def_dim(ncid, "X", 2, &dimid[1]); ERR
+ err = ncmpi_def_var(ncid, "var0", NC_SHORT, 1, &dimid[0], &varid); ERR
+ err = ncmpi_def_var(ncid, "var1", NC_INT, 1, &dimid[1], &varid); ERR
+ err = ncmpi_close(ncid);
+ ERR_EXPECT(NC_EVARSIZE)
+
+ err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, MPI_INFO_NULL, &ncid); ERR
+ err = ncmpi_def_dim(ncid, "Y", INT_MAX, &dimid[0]); ERR
+ err = ncmpi_def_dim(ncid, "X", 2, &dimid[1]); ERR
+ err = ncmpi_def_var(ncid, "var0", NC_INT, 1, &dimid[0], &varid); ERR
+ err = ncmpi_def_var(ncid, "var1", NC_INT, 1, &dimid[1], &varid); ERR
+ err = ncmpi_close(ncid);
+ ERR_EXPECT(NC_EVARSIZE)
+
+ err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, MPI_INFO_NULL, &ncid); ERR
+ err = ncmpi_def_dim(ncid, "Y", INT_MAX/2+1, &dimid[0]); ERR
+ err = ncmpi_def_dim(ncid, "X", 2, &dimid[1]); ERR
+ err = ncmpi_def_var(ncid, "var0", NC_INT, 1, &dimid[0], &varid); ERR
+ err = ncmpi_def_var(ncid, "var1", NC_INT, 1, &dimid[1], &varid); ERR
+ err = ncmpi_close(ncid);
+ ERR_EXPECT(NC_EVARSIZE)
+
+ err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, MPI_INFO_NULL, &ncid); ERR
+ err = ncmpi_def_dim(ncid, "Y", INT_MAX/2, &dimid[0]); ERR
+ err = ncmpi_def_dim(ncid, "X", 2, &dimid[1]); ERR
+ err = ncmpi_def_var(ncid, "var0", NC_INT, 1, &dimid[0], &varid); ERR
+ err = ncmpi_def_var(ncid, "var1", NC_INT, 1, &dimid[1], &varid); ERR
+ err = ncmpi_close(ncid); ERR
+ err = ncmpi_open(MPI_COMM_WORLD, filename, NC_NOWRITE, MPI_INFO_NULL, &ncid); ERR
+ err = ncmpi_close(ncid); ERR
+
+ /* check if PnetCDF freed all internal malloc */
+ MPI_Offset malloc_size, sum_size;
+ err = ncmpi_inq_malloc_size(&malloc_size);
+ if (err == NC_NOERR) {
+ MPI_Reduce(&malloc_size, &sum_size, 1, MPI_OFFSET, MPI_SUM, 0, MPI_COMM_WORLD);
+ if (rank == 0 && sum_size > 0)
+ printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n",
+ sum_size);
+ }
+
+ MPI_Allreduce(MPI_IN_PLACE, &nerrs, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
+ if (rank == 0) {
+ if (nerrs) printf(FAIL_STR,nerrs);
+ else printf(PASS_STR);
+ }
+
+ MPI_Finalize();
+ return 0;
+}
+
diff --git a/test/cdf_format/test_cdf1.nc b/test/cdf_format/test_cdf1.nc
new file mode 100644
index 0000000..39fc9f1
Binary files /dev/null and b/test/cdf_format/test_cdf1.nc differ
diff --git a/test/cdf_format/test_cdf2.nc b/test/cdf_format/test_cdf2.nc
new file mode 100644
index 0000000..71c6e61
Binary files /dev/null and b/test/cdf_format/test_cdf2.nc differ
diff --git a/test/cdf_format/test_cdf5.nc b/test/cdf_format/test_cdf5.nc
new file mode 100644
index 0000000..c171175
Binary files /dev/null and b/test/cdf_format/test_cdf5.nc differ
diff --git a/test/cdf_format/test_inq_format.c b/test/cdf_format/test_inq_format.c
new file mode 100644
index 0000000..4222aaf
--- /dev/null
+++ b/test/cdf_format/test_inq_format.c
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2013, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ */
+/* $Id: test_inq_format.c 2250 2015-12-20 21:12:59Z wkliao $ */
+
+/* This program tests if PnetCDF can report correct file formats */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <mpi.h>
+#include <pnetcdf.h>
+#include <testutils.h>
+
+#define ERR {if(err!=NC_NOERR) {printf("Error(%d) at line %d: %s\n",err,__LINE__,ncmpi_strerror(err)); nerrs++; }}
+
+int main(int argc, char **argv) {
+ char dir_name[256], filename[256];
+ int err, rank, nerrs=0, format, ncid;
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+
+ if (argc != 2) {
+ if (!rank) printf("Usage: %s dir_name\n",argv[0]);
+ MPI_Finalize();
+ return 0;
+ }
+ strcpy(dir_name, argv[1]);
+ MPI_Bcast(dir_name, 256, MPI_CHAR, 0, MPI_COMM_WORLD);
+
+ if (rank == 0) {
+ char cmd_str[256];
+ sprintf(cmd_str, "*** TESTING C %s for inquiring CDF file formats ", argv[0]);
+ printf("%-66s ------ ", cmd_str);
+ }
+
+ /* test CDF-1 -----------------------------------------------------------*/
+ sprintf(filename,"%s/test_cdf1.nc",dir_name);
+ err = ncmpi_open(MPI_COMM_WORLD, filename, 0, MPI_INFO_NULL, &ncid); ERR
+ err = ncmpi_inq_format(ncid, &format); ERR
+ if (format != NC_FORMAT_CLASSIC) {
+ printf("Error (line=%d): expecting CDF-1 format for file %s but got %d\n",
+ __LINE__,filename,format);
+ nerrs++;
+ }
+ err = ncmpi_close(ncid); ERR
+
+ err = ncmpi_inq_file_format(filename, &format); ERR
+ if (format != NC_FORMAT_CLASSIC) {
+ printf("Error (line=%d): expecting CDF-1 format for file %s but got %d\n",
+ __LINE__,filename,format);
+ nerrs++;
+ }
+
+ /* test CDF-2 -----------------------------------------------------------*/
+ sprintf(filename,"%s/test_cdf2.nc",dir_name);
+ err = ncmpi_open(MPI_COMM_WORLD, filename, 0, MPI_INFO_NULL, &ncid); ERR
+ err = ncmpi_inq_format(ncid, &format); ERR
+ if (format != NC_FORMAT_CDF2) {
+ printf("Error (line=%d): expecting CDF-2 format for file %s but got %d\n",
+ __LINE__,filename,format);
+ nerrs++;
+ }
+ err = ncmpi_close(ncid); ERR
+
+ err = ncmpi_inq_file_format(filename, &format); ERR
+ if (format != NC_FORMAT_CDF2) {
+ printf("Error (line=%d): expecting CDF-2 format for file %s but got %d\n",
+ __LINE__,filename,format);
+ nerrs++;
+ }
+
+ /* test CDF-5 -----------------------------------------------------------*/
+ sprintf(filename,"%s/test_cdf5.nc",dir_name);
+ err = ncmpi_open(MPI_COMM_WORLD, filename, 0, MPI_INFO_NULL, &ncid); ERR
+ err = ncmpi_inq_format(ncid, &format); ERR
+ if (format != NC_FORMAT_CDF5) {
+ printf("Error (line=%d): expecting CDF-5 format for file %s but got %d\n",
+ __LINE__,filename,format);
+ nerrs++;
+ }
+ err = ncmpi_close(ncid); ERR
+
+ err = ncmpi_inq_file_format(filename, &format); ERR
+ if (format != NC_FORMAT_CDF5) {
+ printf("Error (line=%d): expecting CDF-5 format for file %s but got %d\n",
+ __LINE__,filename,format);
+ nerrs++;
+ }
+
+ MPI_Offset malloc_size, sum_size;
+ err = ncmpi_inq_malloc_size(&malloc_size);
+ if (err == NC_NOERR) {
+ MPI_Reduce(&malloc_size, &sum_size, 1, MPI_OFFSET, MPI_SUM, 0, MPI_COMM_WORLD);
+ if (rank == 0 && sum_size > 0)
+ printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n",
+ sum_size);
+ }
+
+ MPI_Allreduce(MPI_IN_PLACE, &nerrs, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
+ if (rank == 0) {
+ if (nerrs) printf(FAIL_STR,nerrs);
+ else printf(PASS_STR);
+ }
+
+ MPI_Finalize();
+ return 0;
+}
diff --git a/test/common/Makefile.in b/test/common/Makefile.in
new file mode 100644
index 0000000..fb4f214
--- /dev/null
+++ b/test/common/Makefile.in
@@ -0,0 +1,55 @@
+#
+# Copyright (C) 2003, Northwestern University and Argonne National Laboratory
+# See COPYRIGHT notice in top-level directory.
+#
+# $Id: Makefile.in 2219 2015-12-11 22:30:03Z wkliao $
+#
+# @configure_input@
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+include ../../macros.make
+
+INCLUDES = -I../../src/lib
+
+ifeq (@PNC_DEBUG@, yes)
+CPPFLAGS := $(CPPFLAGS) -DPNC_DEBUG
+FPPFLAGS := $(FPPFLAGS) @FC_DEFINE at PNC_DEBUG
+endif
+
+C_SRCS = testutils.c
+
+F_SRCS = testutilsf.F90
+
+HEADERS = testutils.h
+
+OBJS = $(C_SRCS:.c=.o)
+ifeq (@has_fortran@, yes)
+OBJS += $(F_SRCS:.F90=.o)
+endif
+
+UTIL_LIB = libtestutils.a
+
+GARBAGE = $(UTIL_LIB) *.mod
+PACKING_LIST = $(C_SRCS) $(F_SRCS) $(HEADERS) Makefile.in
+
+all: $(UTIL_LIB)
+
+$(C_SRCS:.c=.o) : $(HEADERS)
+
+$(UTIL_LIB): $(OBJS)
+ $(AR) $(ARFLAGS) $@ $(OBJS)
+
+testutils.o: testutils.c testutils.h
+
+testutilsf.o: testutilsf.F90
+
+testing check verbose_testing: $(UTIL_LIB)
+
+ptest ptests: $(UTIL_LIB)
+
+ptest2 ptest4 ptest6 ptest8 ptest10:
+
+include $(srcdir)/../../rules.make
+
diff --git a/test/common/testutils.c b/test/common/testutils.c
new file mode 100644
index 0000000..c49e03c
--- /dev/null
+++ b/test/common/testutils.c
@@ -0,0 +1,207 @@
+/*
+ * Copyright (C) 2003, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ */
+/* $Id: testutils.c 2247 2015-12-20 20:29:06Z wkliao $ */
+
+
+#include <stdio.h>
+#include <limits.h>
+#include <string.h>
+#include <mpi.h>
+
+#include <pnetcdf.h>
+#include "testutils.h"
+
+void parse_read_args(int argc, char **argv, int rank, params *p)
+{
+ int inlen, outlen;
+ if ( rank == 0 ) {
+ if (argc == 3 ) {
+ strcpy(p->infname, argv[1]);
+ strcpy(p->outfname, argv[2]);
+ } else if (argc == 1) {
+ strcpy(p->infname, "../data/test_double.nc");
+ strcpy(p->outfname, "testread.nc");
+ } else {
+ fprintf(stderr, "Usage: %s: <source> <destination>\n",
+ argv[0]);
+ MPI_Abort(MPI_COMM_WORLD, 1);
+ }
+ inlen = strlen(p->infname);
+ outlen = strlen(p->outfname);
+ }
+ MPI_Bcast(&inlen, 1, MPI_INT, 0, MPI_COMM_WORLD);
+ MPI_Bcast(p->infname, inlen+1, MPI_CHAR, 0, MPI_COMM_WORLD);
+ MPI_Bcast(&outlen, 1, MPI_INT, 0, MPI_COMM_WORLD);
+ MPI_Bcast(p->outfname, outlen+1, MPI_CHAR, 0, MPI_COMM_WORLD);
+}
+
+void parse_write_args(int argc, char **argv, int rank, params *p)
+{
+ int outlen;
+ if ( rank == 0 ) {
+ if (argc == 2 ) {
+ strcpy(p->outfname, argv[1]);
+ } else if (argc == 1) {
+ strcpy(p->outfname, "testwrite.nc");
+ } else {
+ fprintf(stderr, "Usage: %s: <destination>\n", argv[0]);
+ MPI_Abort(MPI_COMM_WORLD, 1);
+ }
+ outlen = strlen(p->outfname);
+ }
+ MPI_Bcast(&outlen, 1, MPI_INT, 0, MPI_COMM_WORLD);
+ MPI_Bcast(p->outfname, outlen+1, MPI_CHAR, 0, MPI_COMM_WORLD);
+}
+
+
+char* nc_err_code_name(int err)
+{
+ static char unknown_str[32];
+ switch (err) {
+ case (NC_NOERR): return "NC_NOERR";
+ case (NC_EBADID): return "NC_EBADID";
+ case (NC_ENFILE): return "NC_ENFILE";
+ case (NC_EEXIST): return "NC_EEXIST";
+ case (NC_EINVAL): return "NC_EINVAL";
+ case (NC_EPERM): return "NC_EPERM";
+ case (NC_ENOTINDEFINE): return "NC_ENOTINDEFINE";
+ case (NC_EINDEFINE): return "NC_EINDEFINE";
+ case (NC_EINVALCOORDS): return "NC_EINVALCOORDS";
+ case (NC_EMAXDIMS): return "NC_EMAXDIMS";
+ case (NC_ENAMEINUSE): return "NC_ENAMEINUSE";
+ case (NC_ENOTATT): return "NC_ENOTATT";
+ case (NC_EMAXATTS): return "NC_EMAXATTS";
+ case (NC_EBADTYPE): return "NC_EBADTYPE";
+ case (NC_EBADDIM): return "NC_EBADDIM";
+ case (NC_EUNLIMPOS): return "NC_EUNLIMPOS";
+ case (NC_EMAXVARS): return "NC_EMAXVARS";
+ case (NC_ENOTVAR): return "NC_ENOTVAR";
+ case (NC_EGLOBAL): return "NC_EGLOBAL";
+ case (NC_ENOTNC): return "NC_ENOTNC";
+ case (NC_ESTS): return "NC_ESTS";
+ case (NC_EMAXNAME): return "NC_EMAXNAME";
+ case (NC_EUNLIMIT): return "NC_EUNLIMIT";
+ case (NC_ENORECVARS): return "NC_ENORECVARS";
+ case (NC_ECHAR): return "NC_ECHAR";
+ case (NC_EEDGE): return "NC_EEDGE";
+ case (NC_ESTRIDE): return "NC_ESTRIDE";
+ case (NC_EBADNAME): return "NC_EBADNAME";
+ case (NC_ERANGE): return "NC_ERANGE";
+ case (NC_ENOMEM): return "NC_ENOMEM";
+ case (NC_EVARSIZE): return "NC_EVARSIZE";
+ case (NC_EDIMSIZE): return "NC_EDIMSIZE";
+ case (NC_ETRUNC): return "NC_ETRUNC";
+ case (NC_EAXISTYPE): return "NC_EAXISTYPE";
+ case (NC_EDAP): return "NC_EDAP";
+ case (NC_ECURL): return "NC_ECURL";
+ case (NC_EIO): return "NC_EIO";
+ case (NC_ENODATA): return "NC_ENODATA";
+ case (NC_EDAPSVC): return "NC_EDAPSVC";
+ case (NC_EDAS): return "NC_EDAS";
+ case (NC_EDDS): return "NC_EDDS";
+ case (NC_EDATADDS): return "NC_EDATADDS";
+ case (NC_EDAPURL): return "NC_EDAPURL";
+ case (NC_EDAPCONSTRAINT): return "NC_EDAPCONSTRAINT";
+ case (NC_ETRANSLATION): return "NC_ETRANSLATION";
+ case (NC_EACCESS): return "NC_EACCESS";
+ case (NC_EAUTH): return "NC_EAUTH";
+ case (NC_ENOTFOUND): return "NC_ENOTFOUND";
+ case (NC_ECANTREMOVE): return "NC_ECANTREMOVE";
+ case (NC_EHDFERR): return "NC_EHDFERR";
+ case (NC_ECANTREAD): return "NC_ECANTREAD";
+ case (NC_ECANTWRITE): return "NC_ECANTWRITE";
+ case (NC_ECANTCREATE): return "NC_ECANTCREATE";
+ case (NC_EFILEMETA): return "NC_EFILEMETA";
+ case (NC_EDIMMETA): return "NC_EDIMMETA";
+ case (NC_EATTMETA): return "NC_EATTMETA";
+ case (NC_EVARMETA): return "NC_EVARMETA";
+ case (NC_ENOCOMPOUND): return "NC_ENOCOMPOUND";
+ case (NC_EATTEXISTS): return "NC_EATTEXISTS";
+ case (NC_ENOTNC4): return "NC_ENOTNC4";
+ case (NC_ESTRICTNC3): return "NC_ESTRICTNC3";
+ case (NC_ENOTNC3): return "NC_ENOTNC3";
+ case (NC_ENOPAR): return "NC_ENOPAR";
+ case (NC_EPARINIT): return "NC_EPARINIT";
+ case (NC_EBADGRPID): return "NC_EBADGRPID";
+ case (NC_EBADTYPID): return "NC_EBADTYPID";
+ case (NC_ETYPDEFINED): return "NC_ETYPDEFINED";
+ case (NC_EBADFIELD): return "NC_EBADFIELD";
+ case (NC_EBADCLASS): return "NC_EBADCLASS";
+ case (NC_EMAPTYPE): return "NC_EMAPTYPE";
+ case (NC_ELATEFILL): return "NC_ELATEFILL";
+ case (NC_ELATEDEF): return "NC_ELATEDEF";
+ case (NC_EDIMSCALE): return "NC_EDIMSCALE";
+ case (NC_ENOGRP): return "NC_ENOGRP";
+ case (NC_ESTORAGE): return "NC_ESTORAGE";
+ case (NC_EBADCHUNK): return "NC_EBADCHUNK";
+ case (NC_ENOTBUILT): return "NC_ENOTBUILT";
+ case (NC_EDISKLESS): return "NC_EDISKLESS";
+ case (NC_ECANTEXTEND): return "NC_ECANTEXTEND";
+ case (NC_EMPI): return "NC_EMPI";
+ // case (NC_EURL): return "NC_EURL";
+ // case (NC_ECONSTRAINT): return "NC_ECONSTRAINT";
+ case (NC_ESMALL): return "NC_ESMALL";
+ case (NC_ENOTINDEP): return "NC_ENOTINDEP";
+ case (NC_EINDEP): return "NC_EINDEP";
+ case (NC_EFILE): return "NC_EFILE";
+ case (NC_EREAD): return "NC_EREAD";
+ case (NC_EWRITE): return "NC_EWRITE";
+ case (NC_EOFILE): return "NC_EOFILE";
+ case (NC_EMULTITYPES): return "NC_EMULTITYPES";
+ case (NC_EIOMISMATCH): return "NC_EIOMISMATCH";
+ case (NC_ENEGATIVECNT): return "NC_ENEGATIVECNT";
+ case (NC_EUNSPTETYPE): return "NC_EUNSPTETYPE";
+ case (NC_EINVAL_REQUEST): return "NC_EINVAL_REQUEST";
+ case (NC_EAINT_TOO_SMALL): return "NC_EAINT_TOO_SMALL";
+ case (NC_ENOTSUPPORT): return "NC_ENOTSUPPORT";
+ case (NC_ENULLBUF): return "NC_ENULLBUF";
+ case (NC_EPREVATTACHBUF): return "NC_EPREVATTACHBUF";
+ case (NC_ENULLABUF): return "NC_ENULLABUF";
+ case (NC_EPENDINGBPUT): return "NC_EPENDINGBPUT";
+ case (NC_EINSUFFBUF): return "NC_EINSUFFBUF";
+ case (NC_ENOENT): return "NC_ENOENT";
+ case (NC_EINTOVERFLOW): return "NC_EINTOVERFLOW";
+ case (NC_ENOTENABLED): return "NC_ENOTENABLED";
+ case (NC_EBAD_FILE): return "NC_EBAD_FILE";
+ case (NC_ENO_SPACE): return "NC_ENO_SPACE";
+ case (NC_EQUOTA): return "NC_EQUOTA";
+ case (NC_ENULLSTART): return "NC_ENULLSTART";
+ case (NC_ENULLCOUNT): return "NC_ENULLCOUNT";
+ case (NC_EINVAL_CMODE): return "NC_EINVAL_CMODE";
+ case (NC_ETYPESIZE): return "NC_ETYPESIZE";
+ case (NC_ETYPE_MISMATCH): return "NC_ETYPE_MISMATCH";
+ case (NC_ETYPESIZE_MISMATCH): return "NC_ETYPESIZE_MISMATCH";
+ case (NC_ESTRICTCDF2): return "NC_ESTRICTCDF2";
+ case (NC_ENOTRECVAR): return "NC_ENOTRECVAR";
+ case (NC_ENOTFILL): return "NC_ENOTFILL";
+ case (NC_EMULTIDEFINE): return "NC_EMULTIDEFINE";
+ case (NC_EMULTIDEFINE_OMODE): return "NC_EMULTIDEFINE_OMODE";
+ case (NC_EMULTIDEFINE_DIM_NUM): return "NC_EMULTIDEFINE_DIM_NUM";
+ case (NC_EMULTIDEFINE_DIM_SIZE): return "NC_EMULTIDEFINE_DIM_SIZE";
+ case (NC_EMULTIDEFINE_DIM_NAME): return "NC_EMULTIDEFINE_DIM_NAME";
+ case (NC_EMULTIDEFINE_VAR_NUM): return "NC_EMULTIDEFINE_VAR_NUM";
+ case (NC_EMULTIDEFINE_VAR_NAME): return "NC_EMULTIDEFINE_VAR_NAME";
+ case (NC_EMULTIDEFINE_VAR_NDIMS): return "NC_EMULTIDEFINE_VAR_NDIMS";
+ case (NC_EMULTIDEFINE_VAR_DIMIDS): return "NC_EMULTIDEFINE_VAR_DIMIDS";
+ case (NC_EMULTIDEFINE_VAR_TYPE): return "NC_EMULTIDEFINE_VAR_TYPE";
+ case (NC_EMULTIDEFINE_VAR_LEN): return "NC_EMULTIDEFINE_VAR_LEN";
+ case (NC_EMULTIDEFINE_NUMRECS): return "NC_EMULTIDEFINE_NUMRECS";
+ case (NC_EMULTIDEFINE_VAR_BEGIN): return "NC_EMULTIDEFINE_VAR_BEGIN";
+ case (NC_EMULTIDEFINE_ATTR_NUM): return "NC_EMULTIDEFINE_ATTR_NUM";
+ case (NC_EMULTIDEFINE_ATTR_SIZE): return "NC_EMULTIDEFINE_ATTR_SIZE";
+ case (NC_EMULTIDEFINE_ATTR_NAME): return "NC_EMULTIDEFINE_ATTR_NAME";
+ case (NC_EMULTIDEFINE_ATTR_TYPE): return "NC_EMULTIDEFINE_ATTR_TYPE";
+ case (NC_EMULTIDEFINE_ATTR_LEN): return "NC_EMULTIDEFINE_ATTR_LEN";
+ case (NC_EMULTIDEFINE_ATTR_VAL): return "NC_EMULTIDEFINE_ATTR_VAL";
+ case (NC_EMULTIDEFINE_FNC_ARGS): return "NC_EMULTIDEFINE_FNC_ARGS";
+ case (NC_EMULTIDEFINE_FILL_MODE): return "NC_EMULTIDEFINE_FILL_MODE";
+ case (NC_EMULTIDEFINE_VAR_FILL_MODE): return "NC_EMULTIDEFINE_VAR_FILL_MODE";
+ case (NC_EMULTIDEFINE_VAR_FILL_VALUE): return "NC_EMULTIDEFINE_VAR_FILL_VALUE";
+ default:
+ sprintf(unknown_str,"Unknown code %d",err);
+ }
+ return unknown_str;
+}
+
diff --git a/test/common/testutils.h b/test/common/testutils.h
new file mode 100644
index 0000000..ef2b7a4
--- /dev/null
+++ b/test/common/testutils.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2003, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ */
+/* $Id: testutils.h 2133 2015-09-26 19:16:01Z wkliao $ */
+
+
+#ifndef _UTILS_H
+#define _UTILS_H
+
+#include <limits.h>
+
+#ifndef PATH_MAX
+#define PATH_MAX 4096
+#endif
+
+typedef struct {
+ char infname[PATH_MAX];
+ char outfname[PATH_MAX];
+} params;
+
+void parse_read_args(int argc, char **argv, int rank, params *p);
+void parse_write_args(int argc, char **argv, int rank, params *p);
+
+#ifdef PNC_DEBUG
+#define PASS_STR "\x1b[32mpass\x1b[0m\n"
+#define FAIL_STR "\x1b[31mfail\x1b[0m with %d mismatches\n"
+#else
+#define PASS_STR "pass\n"
+#define FAIL_STR "fail with %d mismatches\n"
+#endif
+
+extern char* nc_err_code_name(int err);
+
+#endif
diff --git a/test/common/testutilsf.F90 b/test/common/testutilsf.F90
new file mode 100644
index 0000000..cfc7657
--- /dev/null
+++ b/test/common/testutilsf.F90
@@ -0,0 +1,59 @@
+!
+! Copyright (C) 2015, Northwestern University and Argonne National Laboratory
+! See COPYRIGHT notice in top-level directory.
+!
+! This is part of the PnetCDF package.
+!
+! $Id: testutilsf.F90 2133 2015-09-26 19:16:01Z wkliao $
+
+ ! This function gets the executable name and output file name from the
+ ! command line.
+ integer function get_args(cmd, filename)
+#ifdef NAGf90Fortran
+ USE F90_UNIX_ENV, only : iargc, getarg
+ implicit none
+#else
+ implicit none
+ integer iargc
+#endif
+ integer argc
+ character(len=*) cmd, filename
+
+ get_args = 1
+ call getarg(0, cmd)
+ argc = IARGC()
+ if (argc .GT. 1) then
+ print*,'Usage: ',trim(cmd),' [filename]'
+ get_args = 0
+ return
+ endif
+ if (argc .EQ. 1) call getarg(1, filename)
+ end function get_args
+
+ ! This function prints the pass/fail message on screen
+ subroutine pass_fail(nerrs, msg)
+ implicit none
+ integer nerrs
+ character(len=*) msg
+
+ ! local variables
+ CHARACTER ESC
+ PARAMETER (ESC=char(27))
+
+#ifdef PNC_DEBUG
+ CHARACTER (LEN=20) PASS_STR, FAIL_STR
+ PARAMETER (PASS_STR='------ '//ESC//'[32mpass'//ESC//'[0m')
+ PARAMETER (FAIL_STR='------ '//ESC//'[31mfail'//ESC//'[0m')
+#else
+ CHARACTER (LEN=11) PASS_STR, FAIL_STR
+ PARAMETER (PASS_STR='------ pass')
+ PARAMETER (FAIL_STR='------ fail')
+#endif
+
+ if (nerrs .EQ. 0) then
+ write(*,"(A67,A)") msg, PASS_STR
+ else
+ write(*,"(A67,A)") msg, FAIL_STR
+ endif
+ end subroutine pass_fail
+
diff --git a/test/fandc/Makefile.in b/test/fandc/Makefile.in
new file mode 100644
index 0000000..e91e3a3
--- /dev/null
+++ b/test/fandc/Makefile.in
@@ -0,0 +1,88 @@
+#
+# Copyright (C) 2003, Northwestern University and Argonne National Laboratory
+# See COPYRIGHT notice in top-level directory.
+#
+# $Id: Makefile.in 2251 2015-12-20 21:13:42Z wkliao $
+#
+# @configure_input@
+
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+include ../../macros.make
+
+INCLUDES = -I../../src/lib -I$(srcdir)/../common
+FPPFLAGS += -I../../src/libf @FC_MODINC at ../../src/libf90
+LDFLAGS := $(LDFLAGS) -L../common
+LIBS := $(LIBRARY) -ltestutils $(LIBS) @LCOV_LIB@
+ifeq (@PNC_DEBUG@, yes)
+CPPFLAGS := $(CPPFLAGS) -DPNC_DEBUG
+endif
+
+C_SRCS = pnctest.c \
+ csnap.c
+
+F77_SRCS = pnf_test.f \
+ pnctestf.f
+
+ifeq (@F77_SUPPORT_FREEFORM@, yes)
+F77_SRCS += freeform.f
+endif
+
+F90_SRCS = fixedform.f90
+
+PROGS = $(C_SRCS:.c=)
+OBJS = $(C_SRCS:.c=.o)
+ifeq (@has_fortran@, yes)
+PROGS += $(F77_SRCS:.f=) $(F90_SRCS:.f90=)
+OBJS += $(F77_SRCS:.f=.o) $(F90_SRCS:.f90=.o)
+endif
+
+GARBAGE = $(PROGS) *.nc
+PACKING_LIST = $(C_SRCS) $(F77_SRCS) $(F90_SRCS) Makefile.in depend
+
+all: $(PROGS)
+
+$(C_SRCS:.c=.o): $(srcdir)/../common/testutils.h
+
+$(PROGS): ../common/libtestutils.a
+
+../common/libtestutils.a:
+ set -e; cd ../common && $(MAKE) $(MFLAGS) all
+
+pnctest: pnctest.o $(LIBRARY)
+ $(LINK.c) $< $(LDFLAGS) $(LIBS)
+
+csnap: csnap.o $(LIBRARY)
+ $(LINK.c) $< $(LDFLAGS) $(LIBS) -lm
+
+pnctestf: pnctestf.o $(LIBRARY)
+ $(LINK.F90) $< $(LDFLAGS) $(LIBS)
+
+pnf_test: pnf_test.o $(LIBRARY)
+ $(LINK.F90) $< $(LDFLAGS) $(LIBS)
+
+# check F77 program to see if accept Fortran free form
+freeform.o: freeform.f
+ $(COMPILE.f) @FFREEFORMFLAG@ $<
+
+freeform: freeform.o
+ $(LINK.F90) $< $(LDFLAGS) $(LIBS)
+
+# check F90 program to see if accept Fortran fixed form
+fixedform.o: fixedform.f90
+ $(COMPILE.f90) @FFIXEDFORMFLAG@ $<
+
+fixedform: fixedform.o
+ $(LINK.F90) $< $(LDFLAGS) $(LIBS)
+
+testing check verbose_testing:
+
+ptest ptests ptest2 ptest4 ptest6 ptest8 ptest10:
+
+include $(srcdir)/../../rules.make
+include $(srcdir)/depend
+
+$(LIBRARY): ;
+
diff --git a/test/fandc/csnap.c b/test/fandc/csnap.c
new file mode 100644
index 0000000..e7de071
--- /dev/null
+++ b/test/fandc/csnap.c
@@ -0,0 +1,475 @@
+/*
+ * Copyright (C) 2003, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ */
+/* $Id: csnap.c 2258 2015-12-22 04:50:40Z wkliao $ */
+
+
+/******************************************************************************
+
+ This code writes one or two arrays, tt[k][j][i] (and smf[j][i], if
+ 'only_3d' is 0), into the file 'csnap.nc.' It then reads the field(s)
+ from the file, and compares with the original field values.
+
+ i=longitude, j=latitude, k=level
+
+ To run: Set the global sizes, parallel decomposition and other I/O
+ parameters below.
+
+ By Woo-Sun Yang and Chris Ding
+ NERSC, Lawrence Berkeley National Laboratory
+
+ *****************************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h> /* srand(), rand() */
+#include <string.h> /* strcpy() */
+#include <unistd.h>
+#include <math.h> /* sqrt() */
+#include <limits.h>
+#include <float.h>
+#include <mpi.h>
+#include <pnetcdf.h>
+#include <testutils.h>
+
+#define ERR {if(err!=NC_NOERR){printf("Error at line=%d: %s\n", __LINE__, ncmpi_strerror(err));nerrs++;}}
+
+/*** Field parameters ***/
+static int verbose, nerrs;
+
+const MPI_Offset totsiz_3d[3] = { 256, 256, 256 }; /* global sizes of 3D field */
+MPI_Offset totsiz_2d[2]; /* global sizes of 2D field */
+MPI_Offset locsiz_3d[3]; /* local sizes of 3D fields */
+MPI_Offset locsiz_2d[2]; /* local sizes of 2D fields */
+MPI_Offset istart, jstart, kstart; /* offsets of 3D field */
+
+const int random_fields = 0; /* random fields? 1 or 0 */
+const int only_3d = 1; /* I/O 3D field only? 1 or 0 */
+
+int has_2d; /* contains valid 2D data? */
+
+const int nwrites = 5; /* number of write samples */
+const int nreads = 5; /* number of read samples */
+
+const int fillmode = NC_NOFILL; /* NC_FILL or NC_NOFILL; actually
+ prefilling not supported */
+
+/*** Parallel domain decomposition parameters ***/
+
+MPI_Comm comm_cart; /* Cartesian communicator */
+int mype; /* rank in comm_cart */
+int totpes; /* total number of PEs */
+int numpes[3] = { 0, 1, 1 }; /* number of PEs along axes;
+ determined by MPI where
+ a zero is specified */
+int pe_coords[3]; /* Cartesian PE coords */
+
+/*** function prototypes ***/
+
+void find_locnx(MPI_Offset nx, int mype, int totpes, MPI_Offset *locnx, MPI_Offset *xbegin);
+void write_file(char *filename, double *t);
+void read_file(char *filename, double *t);
+void get_fields(double *tt, double *smf);
+void compare_vec(double *a, double *b, int ndims, MPI_Offset *sizes, int corr_data);
+
+
+int main(int argc, char *argv[]) {
+ int isperiodic[3] = {0, 0, 0};
+ int reorder = 0;
+ double t[20], t_g[20];
+ double file_size;
+ double rates_l[4], rates_g[4];
+ int i, rank;
+ char filename[256];
+
+ MPI_Init(&argc,&argv);
+ MPI_Comm_size(MPI_COMM_WORLD,&totpes);
+ MPI_Comm_rank(MPI_COMM_WORLD,&rank);
+
+ if (argc > 2) {
+ if (!rank) printf("Usage: %s [filename]\n",argv[0]);
+ MPI_Finalize();
+ return 0;
+ }
+ strcpy(filename, "testfile.nc");
+ if (argc == 2) strcpy(filename, argv[1]);
+ MPI_Bcast(filename, 256, MPI_CHAR, 0, MPI_COMM_WORLD);
+
+ if (rank == 0) {
+ char cmd_str[256];
+ sprintf(cmd_str, "*** TESTING C %s for 3D array write/read ", argv[0]);
+ printf("%-66s ------ ", cmd_str); fflush(stdout);
+ }
+
+ verbose = 0;
+ nerrs = 0;
+
+ MPI_Dims_create(totpes,3,numpes);
+ MPI_Cart_create(MPI_COMM_WORLD,3,numpes,isperiodic,reorder,&comm_cart);
+ MPI_Comm_rank(comm_cart,&mype);
+ MPI_Cart_coords(comm_cart,mype,3,pe_coords);
+
+/*
+ Determine local sizes for tt (locsiz_3d) and smf (locsiz_2d).
+ Also determine whether the current processor contains valid 2D data.
+ Compute file_size in 1e6 Bytes
+ */
+
+ find_locnx(totsiz_3d[0],pe_coords[0],numpes[0],&locsiz_3d[0],&kstart);
+ find_locnx(totsiz_3d[1],pe_coords[1],numpes[1],&locsiz_3d[1],&jstart);
+ find_locnx(totsiz_3d[2],pe_coords[2],numpes[2],&locsiz_3d[2],&istart);
+
+ totsiz_2d[0] = totsiz_3d[1];
+ totsiz_2d[1] = totsiz_3d[2];
+
+ locsiz_2d[0] = locsiz_3d[1];
+ locsiz_2d[1] = locsiz_3d[2];
+
+ has_2d = (! only_3d) && (pe_coords[0] == numpes[0] - 1);
+
+ if (only_3d)
+ file_size = (((double) totsiz_3d[0])*((double) totsiz_3d[1])
+ * ((double) totsiz_3d[2])) * 1.0e-6 * sizeof(double);
+ else
+ file_size = (((double) totsiz_3d[0])*((double) totsiz_3d[1])
+ * ((double) totsiz_3d[2])
+ + ((double) totsiz_2d[0])*((double) totsiz_2d[1]))
+ * 1.0e-6 * sizeof(double);
+
+/* Print data decomposition information */
+
+ if (mype == 0 && verbose)
+ printf("mype pe_coords totsiz_3d locsiz_3d "
+ "kstart,jstart,istart\n");
+
+ MPI_Barrier(comm_cart);
+
+ if (verbose)
+ printf("%3d %2d %2d %2d %4lld %4lld %4lld %4lld %4lld %4lld %6lld %6lld %6lld\n",
+ mype, pe_coords[0], pe_coords[1], pe_coords[2],
+ totsiz_3d[0], totsiz_3d[1], totsiz_3d[2],
+ locsiz_3d[0], locsiz_3d[1], locsiz_3d[2],
+ kstart, jstart, istart);
+
+/* Write and then read back */
+
+ for (i=0; i < 20; t[i++] = DBL_MAX); /* ready for timing */
+
+ write_file(filename, &t[ 0]);
+ read_file (filename, &t[10]);
+
+/* Compute I/O rates */
+
+ rates_l[0] = file_size / t[1]; /* write rate */
+ rates_l[1] = file_size /(t[0] + t[1]); /* effective write rate */
+ rates_l[2] = file_size / t[11]; /* read rate */
+ rates_l[3] = file_size /(t[10] + t[11]); /* effective read rate */
+
+ MPI_Allreduce(rates_l, rates_g, 4, MPI_DOUBLE, MPI_MIN, comm_cart);
+ MPI_Allreduce(t, t_g, 20, MPI_DOUBLE, MPI_MAX, comm_cart);
+
+ if (mype == 0 && verbose) {
+ printf("File size: %10.3e MB\n", file_size);
+ printf(" Write: %9.3f MB/s (eff., %9.3f MB/s)\n",
+ rates_g[0], rates_g[1]);
+ printf(" Read : %9.3f MB/s (eff., %9.3f MB/s)\n",
+ rates_g[2], rates_g[3]);
+ printf(" %c %10.3e %3d %10.3e %10.3e %8.3f %10.3e %10.3e %8.3f\n",
+ ((fillmode == NC_FILL) ? 'f' : 'n'), file_size, totpes,
+ t_g[0], t_g[1], rates_g[1], t_g[10], t_g[11], rates_g[3]);
+ }
+
+ MPI_Comm_free(&comm_cart);
+
+ MPI_Offset malloc_size, sum_size;
+ int err = ncmpi_inq_malloc_size(&malloc_size);
+ if (err == NC_NOERR) {
+ MPI_Reduce(&malloc_size, &sum_size, 1, MPI_OFFSET, MPI_SUM, 0, MPI_COMM_WORLD);
+ if (mype == 0 && sum_size > 0)
+ printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n",
+ sum_size);
+ }
+
+ MPI_Allreduce(MPI_IN_PLACE, &nerrs, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
+ if (rank == 0) {
+ if (nerrs) printf(FAIL_STR,nerrs);
+ else printf(PASS_STR);
+ }
+
+ MPI_Finalize();
+ return 0;
+}
+
+
+void write_file(char *filename, double *t) {
+ double *tt = NULL;
+ double *smf = NULL;
+ double t1, t2, t3;
+ int dim_id[3];
+ int lon_id, lat_id, lev_id;
+ int err;
+ int file_id;
+ int t_id, smf_id;
+ int ii;
+ MPI_Offset start_3d[3];
+ MPI_Offset count_3d[3];
+ MPI_Offset start_2d[2];
+ MPI_Offset count_2d[2];
+
+ start_3d[0] = kstart;
+ start_3d[1] = jstart;
+ start_3d[2] = istart;
+ count_3d[0] = locsiz_3d[0];
+ count_3d[1] = locsiz_3d[1];
+ count_3d[2] = locsiz_3d[2];
+ start_2d[0] = jstart;
+ start_2d[1] = istart;
+ count_2d[0] = locsiz_2d[0];
+ count_2d[1] = locsiz_2d[1];
+
+ tt = (double*)malloc(locsiz_3d[0]*locsiz_3d[1]*locsiz_3d[2]*sizeof(double));
+
+ if (has_2d)
+ smf = (double*)malloc(locsiz_2d[0]*locsiz_2d[1]*sizeof(double));
+ else
+ smf = (double*)malloc(sizeof(double));
+
+ for (ii = 1; ii <= nwrites; ii++) {
+
+ if(mype == 0) unlink(filename);
+
+ get_fields(tt, smf);
+ MPI_Barrier(comm_cart);
+
+ t1 = MPI_Wtime();
+
+ err = ncmpi_create(comm_cart, filename, NC_CLOBBER, MPI_INFO_NULL,
+ &file_id); ERR
+
+/* err = nc_set_fill(file_id,fillmode,&old_fillmode); ERR */
+
+ err = ncmpi_def_dim(file_id,"level", (MPI_Offset) totsiz_3d[0],&lev_id); ERR
+ err = ncmpi_def_dim(file_id,"latitude", (MPI_Offset) totsiz_3d[1],&lat_id); ERR
+ err = ncmpi_def_dim(file_id,"longitude",(MPI_Offset) totsiz_3d[2],&lon_id); ERR
+
+ dim_id[0] = lev_id; dim_id[1] = lat_id; dim_id[2] = lon_id;
+
+ err = ncmpi_def_var(file_id,"t",NC_DOUBLE,3,dim_id,&t_id); ERR
+
+ if (! only_3d) {
+ err = ncmpi_def_var(file_id,"smf",NC_DOUBLE,2,&dim_id[1],&smf_id); ERR
+ }
+
+ err = ncmpi_enddef(file_id); ERR
+
+ t2 = MPI_Wtime();
+
+ err = ncmpi_put_vara_double_all(file_id,t_id,start_3d,count_3d,tt); ERR
+
+ if (! only_3d) {
+ err = ncmpi_begin_indep_data(file_id); ERR
+
+ if (has_2d) {
+ err = ncmpi_put_vara_double(file_id,smf_id,start_2d,count_2d,smf); ERR
+ }
+
+ err = ncmpi_end_indep_data(file_id); ERR
+ }
+
+ err = ncmpi_close(file_id); ERR
+
+ MPI_Barrier(comm_cart);
+ t3 = MPI_Wtime();
+
+ if (t2 - t1 < t[0]) t[0] = t2 - t1;
+ if (t3 - t2 < t[1]) t[1] = t3 - t2;
+ if (mype == 0 && verbose) printf("write %d: %9.3e %9.3e\n", ii, t2-t1, t3-t2);
+ }
+
+ free(tt);
+ free(smf);
+}
+
+
+void read_file(char *filename, double *t) {
+ double *tt = NULL;
+ double *smf = NULL;
+ double *buf = NULL;
+ double t1, t2, t3;
+ double dt1, dt2=0;
+ int ncid;
+ int vid_t, vid_smf;
+ int i, j, k, ii, err;
+
+ MPI_Offset start_3d[3];
+ MPI_Offset count_3d[3];
+ MPI_Offset start_2d[2];
+ MPI_Offset count_2d[2];
+
+ start_3d[0] = kstart;
+ start_3d[1] = jstart;
+ start_3d[2] = istart;
+ count_3d[0] = locsiz_3d[0];
+ count_3d[1] = locsiz_3d[1];
+ count_3d[2] = locsiz_3d[2];
+ start_2d[0] = jstart;
+ start_2d[1] = istart;
+ count_2d[0] = locsiz_2d[0];
+ count_2d[1] = locsiz_2d[1];
+
+ tt = (double*)malloc(locsiz_3d[0]*locsiz_3d[1]*locsiz_3d[2]*sizeof(double));
+
+ if (has_2d)
+ smf = (double*)malloc(locsiz_2d[0]*locsiz_2d[1]*sizeof(double));
+ else
+ smf = (double*)malloc(sizeof(double));
+
+ buf = (double*)malloc(locsiz_3d[0]*locsiz_3d[1]*locsiz_3d[2]*sizeof(double));
+
+ get_fields(tt, smf);
+
+ for (ii = 1; ii <= nreads; ii++) {
+
+ double *ptr = buf;
+ for (k = 0; k < locsiz_3d[0]; k++)
+ for (j = 0; j < locsiz_3d[1]; j++)
+ for (i = 0; i < locsiz_3d[2]; i++)
+ *ptr++ = 4.444;
+
+ MPI_Barrier(comm_cart);
+ t1 = MPI_Wtime();
+
+ err = ncmpi_open(comm_cart, filename, NC_NOWRITE, MPI_INFO_NULL, &ncid); ERR
+
+ err = ncmpi_inq_varid(ncid,"t",&vid_t); ERR
+ if (! only_3d) {
+ err = ncmpi_inq_varid(ncid,"smf",&vid_smf); ERR
+ }
+
+ t2 = MPI_Wtime();
+
+ err = ncmpi_get_vara_double_all(ncid,vid_t,start_3d,count_3d,buf); ERR
+
+ dt1 = MPI_Wtime();
+ if (ii == 1) compare_vec(tt,buf,3,locsiz_3d,1);
+ dt1 = MPI_Wtime() - dt1;
+
+ if (! only_3d) {
+ err = ncmpi_begin_indep_data(ncid); ERR
+
+ if (has_2d) {
+ err = ncmpi_get_vara_double(ncid,vid_smf,start_2d,count_2d,buf); ERR
+ }
+
+ dt2 = MPI_Wtime();
+ if (ii == 1) compare_vec(smf,buf,2,locsiz_2d,has_2d);
+ dt2 = MPI_Wtime() - dt2;
+
+ err = ncmpi_end_indep_data(ncid); ERR
+ }
+
+ err = ncmpi_close(ncid); ERR
+
+ MPI_Barrier(comm_cart);
+ t3 = MPI_Wtime();
+
+ if (t2 - t1 < t[0]) t[0] = t2 - t1;
+ if ((t3 - t2) - (dt1 + dt2) < t[1]) t[1] = (t3 - t2) - (dt1 + dt2);
+ if (mype == 0 && verbose)
+ printf(" read %d: %9.3e %9.3e\n", ii, t2-t1, (t3-t2)-(dt1+dt2));
+ }
+
+ free(tt);
+ free(smf);
+ free(buf);
+}
+
+
+void find_locnx(MPI_Offset nx, int mype, int totpes, MPI_Offset *locnx, MPI_Offset *xbegin) {
+ MPI_Offset xremain;
+
+ *locnx = nx / totpes;
+ xremain = nx - totpes*(*locnx);
+ if (mype < xremain) (*locnx)++;
+ *xbegin = mype*(nx/totpes) + xremain;
+ if (mype < xremain) *xbegin += mype - xremain;
+}
+
+
+void get_fields(double *tt, double *smf) {
+ int i, j, k;
+
+ if (random_fields) {
+ unsigned int seed = (INT_MAX / totpes) * mype;
+ srand(seed);
+
+ for (k = 0; k < locsiz_3d[0]; k++)
+ for (j = 0; j < locsiz_3d[1]; j++)
+ for (i = 0; i < locsiz_3d[2]; i++) {
+ double tmp = rand();
+ *tt++ = tmp / (RAND_MAX + 1.);
+ }
+
+ if (has_2d)
+ for (j = 0; j < locsiz_2d[0]; j++)
+ for (i = 0; i < locsiz_2d[1]; i++) {
+ double tmp = rand();
+ *smf++ = tmp / (RAND_MAX + 1.);
+ }
+ }
+ else {
+ for (k = 0; k < locsiz_3d[0]; k++)
+ for (j = 0; j < locsiz_3d[1]; j++)
+ for (i = 0; i < locsiz_3d[2]; i++)
+ *tt++ = (istart + i + 1 + totsiz_3d[2]*(jstart + j
+ + totsiz_3d[1]*(kstart + k)))*1.e-3;
+
+ if (has_2d)
+ for (j = 0; j < locsiz_2d[0]; j++)
+ for (i = 0; i < locsiz_2d[1]; i++)
+ *smf++ = (istart + i + 1 + totsiz_2d[1]*(jstart + j))*1.e-2;
+ }
+}
+
+
+void compare_vec(double *a, double *b, int ndims, MPI_Offset *sizes, int corr_data) {
+ double diff, delta, delmax, delmin;
+ double ws[5], wr[5];
+ MPI_Offset totsiz;
+ int i;
+
+ if (corr_data) {
+ totsiz = 1;
+ for (i = 0; i < ndims; i++)
+ totsiz = totsiz * sizes[i];
+
+ ws[0] = 0.; /* diff */
+ ws[1] = 0.; /* sumsq */
+ ws[2] = totsiz; /* totsiz */
+ ws[3] = 0.; /* delmax */
+ ws[4] = DBL_MAX; /* delmin */
+
+ for (i = 0; i < totsiz; i++) {
+ delta = (a[i] - b[i]) * (a[i] - b[i]);
+ ws[0] = ws[0] + delta;
+ ws[1] = ws[1] + a[i] * a[i];
+ if (delta > ws[3]) ws[3] = delta;
+ if (delta < ws[4]) ws[4] = delta;
+ }
+ }
+ else {
+ ws[0] = ws[1] = ws[2] = ws[3] = 0.;
+ ws[4] = DBL_MAX;
+ }
+
+ MPI_Allreduce( ws, wr, 3, MPI_DOUBLE, MPI_SUM, comm_cart);
+ MPI_Allreduce(&ws[3], &delmax, 1, MPI_DOUBLE, MPI_MAX, comm_cart);
+ MPI_Allreduce(&ws[4], &delmin, 1, MPI_DOUBLE, MPI_MIN, comm_cart);
+
+ diff = sqrt(wr[0]/wr[1]); /* Normalized error */
+ delmax = sqrt(wr[2]*delmax/wr[1]); /* Normalized max difference */
+ delmin = sqrt(wr[2]*delmin/wr[1]); /* Normalized min difference */
+
+ if (mype == 0 && verbose)
+ printf("diff, delmax, delmin = %9.3e %9.3e %9.3e\n", diff, delmax, delmin);
+}
diff --git a/test/fandc/depend b/test/fandc/depend
new file mode 100644
index 0000000..12bd79a
--- /dev/null
+++ b/test/fandc/depend
@@ -0,0 +1,2 @@
+pnf_test.o: pnf_test.f
+pnctestf.o: pnctestf.f
diff --git a/test/fandc/fixedform.f90 b/test/fandc/fixedform.f90
new file mode 100644
index 0000000..1ce6ab4
--- /dev/null
+++ b/test/fandc/fixedform.f90
@@ -0,0 +1,27 @@
+!
+! Copyright (C) 2013, Northwestern University and Argonne National Laboratory
+! See COPYRIGHT notice in top-level directory.
+!
+! $Id: fixedform.f90 2257 2015-12-22 04:50:00Z wkliao $
+
+!
+! This program tests whether header file pnetcdf.inc conforms Fortran fixed
+! form. Hence this test is for compilation only.
+!
+
+ program main
+ implicit none
+ include "mpif.h"
+ include "pnetcdf.inc"
+
+ character(LEN=80) pnetcdf_version
+ integer err
+
+ call MPI_Init(err)
+
+ pnetcdf_version = nfmpi_inq_libvers()
+
+ call MPI_Finalize(err)
+
+ end program main
+
diff --git a/test/fandc/freeform.f b/test/fandc/freeform.f
new file mode 100644
index 0000000..6a87520
--- /dev/null
+++ b/test/fandc/freeform.f
@@ -0,0 +1,27 @@
+!
+! Copyright (C) 2013, Northwestern University and Argonne National Laboratory
+! See COPYRIGHT notice in top-level directory.
+!
+! $Id: freeform.f 2257 2015-12-22 04:50:00Z wkliao $
+
+!
+! This program tests whether header file pnetcdf.inc conforms Fortran free form
+! for compilation only, not execution
+!
+
+program main
+ implicit none
+ include "mpif.h"
+ include "pnetcdf.inc"
+
+ character(LEN=80) pnetcdf_version
+ integer err
+
+ call MPI_Init(err)
+
+ pnetcdf_version = nfmpi_inq_libvers()
+
+ call MPI_Finalize(err)
+
+end program main
+
diff --git a/test/fandc/pnctest.c b/test/fandc/pnctest.c
new file mode 100644
index 0000000..9811e50
--- /dev/null
+++ b/test/fandc/pnctest.c
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2003, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ */
+/* $Id: pnctest.c 2258 2015-12-22 04:50:40Z wkliao $ */
+
+#include <stdio.h>
+#include <mpi.h>
+#include <pnetcdf.h>
+#include <testutils.h>
+
+/* Test program thanks to From: John Tannahill <tannahill1 at llnl.gov> */
+
+#define ERR if (err!=NC_NOERR) {printf("Error at line %d: %s\n", __LINE__,ncmpi_strerror(err)); nerrs++;}
+
+int main (int argc, char *argv[])
+{
+ int dim_id[3], isperiodic[3] = { 0, 0, 0 };
+ int err, lat_id, lev_id, lon_id, ncid, totpes, rank, tt_id;
+ int reorder=0, nerrs=0;
+ int numpes[3] = { 0, 1, 1 }; /* number of PEs along axes;
+ determined by MPI where a
+ zero is specified */
+ MPI_Offset TOTSIZ_3D[3] = { 10, 20, 30 };
+ MPI_Comm comm_cart;
+
+ MPI_Init (&argc, &argv);
+ MPI_Comm_size (MPI_COMM_WORLD, &totpes);
+ MPI_Comm_size (MPI_COMM_WORLD, &rank);
+
+ MPI_Dims_create (totpes, 3, numpes);
+ MPI_Cart_create (MPI_COMM_WORLD, 3, numpes, isperiodic, reorder, &comm_cart);
+
+ err = ncmpi_create (comm_cart, "testfile.nc", NC_CLOBBER, MPI_INFO_NULL,
+ &ncid); ERR
+
+ err = ncmpi_def_dim (ncid, "level", TOTSIZ_3D[0], &lev_id); ERR
+ err = ncmpi_def_dim (ncid, "latitude", TOTSIZ_3D[1], &lat_id); ERR
+ err = ncmpi_def_dim (ncid, "longitude", TOTSIZ_3D[2], &lon_id); ERR
+
+ dim_id[0] = lev_id;
+ dim_id[1] = lat_id;
+ dim_id[2] = lon_id;
+
+ err = ncmpi_def_var (ncid, "tt", NC_FLOAT, 3, dim_id, &tt_id); ERR
+
+ err = ncmpi_enddef (ncid); ERR
+
+ err = ncmpi_close (ncid); ERR
+
+ MPI_Comm_free (&comm_cart);
+
+ MPI_Offset malloc_size, sum_size;
+ err = ncmpi_inq_malloc_size(&malloc_size);
+ if (err == NC_NOERR) {
+ MPI_Reduce(&malloc_size, &sum_size, 1, MPI_OFFSET, MPI_SUM, 0, MPI_COMM_WORLD);
+ if (rank == 0 && sum_size > 0)
+ printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n",
+ sum_size);
+ }
+
+ MPI_Allreduce(MPI_IN_PLACE, &nerrs, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
+ if (rank == 0) {
+ if (nerrs) printf(FAIL_STR,nerrs);
+ else printf(PASS_STR);
+ }
+
+ MPI_Finalize ( );
+ return 0;
+}
diff --git a/test/fandc/pnctestf.f b/test/fandc/pnctestf.f
new file mode 100644
index 0000000..7d7d577
--- /dev/null
+++ b/test/fandc/pnctestf.f
@@ -0,0 +1,74 @@
+!
+! Copyright (C) 2003, Northwestern University and Argonne National Laboratory
+! See COPYRIGHT notice in top-level directory.
+!
+! $Id: pnctestf.f 2224 2015-12-16 06:10:36Z wkliao $
+!
+ program Pnf_Test
+! Test program thanks to From: John Tannahill <tannahill1 at llnl.gov>
+
+ implicit none
+ include "mpif.h"
+ include "pnetcdf.inc"
+
+ integer*8 TOTSIZ_3D(3)
+
+ logical reorder
+
+ logical isperiodic(3)
+
+ integer comm_cart
+ integer ierr
+ integer lat_id, lev_id, lon_id
+ integer ncid
+ integer totpes
+ integer tt_id
+
+ integer dim_id(3)
+
+ integer numpes(3)
+! number of PEs along axes;
+! determined by MPI where a zero is specified
+
+ data totsiz_3d/10,20,30/
+ data reorder /.false./
+ data isperiodic /.false., .false., .false./
+ data numpes/1,1,0/
+
+ call MPI_Init(ierr)
+
+ call MPI_Comm_Size(MPI_COMM_WORLD, totpes, ierr)
+
+ call MPI_Dims_Create(totpes, 3, numpes, ierr)
+
+ call MPI_Cart_Create(MPI_COMM_WORLD, 3, numpes, isperiodic,
+ + reorder, comm_cart, ierr)
+
+ ierr = nfmpi_create(comm_cart, "pnf_test.nc", NF_CLOBBER,
+ + MPI_INFO_NULL, ncid)
+
+ ierr = nfmpi_def_dim(ncid, "level", totsiz_3d(1), lev_id)
+ ierr = nfmpi_def_dim(ncid, "latitude", totsiz_3d(2), lat_id)
+ ierr = nfmpi_def_dim(ncid, "longitude", totsiz_3d(3), lon_id)
+
+ dim_id(1) = lev_id
+ dim_id(2) = lat_id
+ dim_id(3) = lon_id
+
+ ierr = nfmpi_def_var(ncid, "tt", NF_FLOAT, 3, dim_id, tt_id)
+
+ ierr = nfmpi_enddef(ncid)
+
+ ierr = nfmpi_close(ncid)
+
+ call MPI_Comm_Free(comm_cart, ierr)
+
+ call MPI_Finalize (ierr)
+
+ Write (6,10)
+
+ 10 format(" No Errors")
+
+ Stop
+
+ end ! program Pnf_Test
diff --git a/test/fandc/pnf_test.f b/test/fandc/pnf_test.f
new file mode 100644
index 0000000..6de5120
--- /dev/null
+++ b/test/fandc/pnf_test.f
@@ -0,0 +1,696 @@
+!
+! Copyright (C) 2003, Northwestern University and Argonne National Laboratory
+! See COPYRIGHT notice in top-level directory.
+!
+! $Id: pnf_test.f 2224 2015-12-16 06:10:36Z wkliao $
+!
+!=============================================================================
+!
+! CODE DEVELOPER
+! John Tannahill, LLNL
+! jrt at llnl.gov
+! Note that this code was adapted from csnap.c, which was written by:
+! Woo-Sun Yang and Chris Ding
+! NERSC, Lawrence Berkeley National Laboratory
+!
+! FILE
+! pnf_test.F
+!
+! ROUTINES
+! Pnf_Test (Program)
+!
+! The purpose of this program is to test the Fortran interface to the
+! parallel netCDF library being developed at Argonne National Lab and
+! Northwestern Univ.
+!
+! This code writes the array, tt(k)(j)(i), into the file 'pnf_test.nc'. It
+! then reads the array from the file, and compares it with the original
+! values.
+!
+! i=longitude, j=latitude, k=level
+!
+!=============================================================================
+
+ program Pnf_Test
+
+ implicit none
+
+ include "mpif.h"
+ include "pnetcdf.inc"
+
+
+! -----------------------
+! Parameter declarations.
+! -----------------------
+
+ integer NREADS, NWRITES
+ parameter (NREADS = 5, NWRITES = 5 )
+ ! number of read samples
+ ! number of write samples
+
+ integer*8 TOTSIZ_3D(3) ! global sizes of 3D field
+
+
+! ----------------------
+! Variable declarations.
+! ----------------------
+
+ logical reorder
+
+ logical isperiodic(3)
+
+ integer comm_cart ! Cartesian communicator
+ integer ierr
+ integer*8 istart, jstart, kstart ! offsets of 3D field
+ integer*8 locsiz
+ integer mype ! rank in comm_cart
+ integer totpes ! total number of PEs
+
+ integer*8 locsiz_3d(3) ! local sizes of 3D fields
+ integer pe_coords(3) ! Cartesian PE coords
+
+ integer numpes(3) ! number of PEs along axes;
+ ! determined by MPI where a
+ ! zero is specified
+
+ double precision filsiz
+
+ real*4 rdt_g(2)
+ real*4 rdt_l(2)
+ real*4 wrt_g(2)
+ real*4 wrt_l(2)
+
+ real*4 rrates_g(2)
+ real*4 rrates_l(2)
+ real*4 wrates_g(2)
+ real*4 wrates_l(2)
+
+
+ data reorder / .false. /
+ data isperiodic / .false., .false., .false. /
+ data numpes / 1, 1, 0 /
+ data TOTSIZ_3D / 256, 256, 256 /
+
+! ----------------
+! Begin execution.
+! ----------------
+
+ call MPI_Init (ierr)
+
+ call MPI_Comm_Size (MPI_COMM_WORLD, totpes, ierr)
+
+ call MPI_Dims_Create (totpes, 3, numpes, ierr)
+
+ call MPI_Cart_Create
+ & (MPI_COMM_WORLD, 3, numpes, isperiodic, reorder,
+ & comm_cart, ierr)
+
+ call MPI_Comm_Rank (comm_cart, mype, ierr)
+
+ call MPI_Cart_Coords (comm_cart, mype, 3, pe_coords, ierr)
+
+
+ rdt_l(1) = 1.0e38
+ rdt_l(2) = 1.0e38
+ wrt_l(1) = 1.0e38
+ wrt_l(2) = 1.0e38
+! rdt_l(:) = Huge (rdt_l) ! initialize for timing
+! wrt_l(:) = Huge (wrt_l)
+
+
+! ----------------------------------------
+! Determine local size for tt (locsiz_3d).
+! ----------------------------------------
+
+! ===============
+ call Find_Locnx
+ & (TOTSIZ_3D(1), pe_coords(1), numpes(1), locsiz_3d(1), istart)
+ call Find_Locnx
+ & (TOTSIZ_3D(2), pe_coords(2), numpes(2), locsiz_3d(2), jstart)
+ call Find_Locnx
+ & (TOTSIZ_3D(3), pe_coords(3), numpes(3), locsiz_3d(3), kstart)
+! ===============
+
+
+! -------------------------------
+! Compute file size in 1d6 bytes.
+! -------------------------------
+
+ filsiz = (TOTSIZ_3D(1) * TOTSIZ_3D(2) * TOTSIZ_3D(3)) *
+ & 1.0d-6 * 4.0d0
+
+
+! -------------------------------------
+! Print data decomposition information.
+! -------------------------------------
+
+ if (mype .EQ. 0) Write (6,900)
+
+ call MPI_Barrier (comm_cart, ierr)
+
+ Write (6, 902)
+ & mype, pe_coords(1), pe_coords(2), pe_coords(3),
+ & TOTSIZ_3D(1), TOTSIZ_3D(2), TOTSIZ_3D(3),
+ & locsiz_3d(1), locsiz_3d(2), locsiz_3d(3),
+ & kstart, jstart, istart
+
+ 900 format ("mype pe_coords totsiz_3d locsiz_3d ",
+ & "kstart,jstart,istart")
+ 902 format (i3,3x,i2,1x,i2,1x,i2,2x,i4,1x,i4,1x,i4,4x,i4,1x,i4,1x,i4,
+ & 3x,i6,1x,i6,1x,i6)
+
+
+! -------------------------
+! Write and then read back.
+! -------------------------
+
+ locsiz = locsiz_3d(1) * locsiz_3d(2) * locsiz_3d(3)
+
+! ===============
+ call Write_File
+! ===============
+ & ("pnf_test.nc", NWRITES, mype, comm_cart, istart, jstart,
+ & kstart, locsiz, locsiz_3d, TOTSIZ_3D, wrt_l)
+!!! Write (6,*) wrt_l(1), wrt_l(2)
+
+! ==============
+ call Read_File
+! ==============
+ & ("pnf_test.nc", NREADS, mype, comm_cart, istart, jstart,
+ & kstart, locsiz, locsiz_3d, TOTSIZ_3D, rdt_l)
+
+
+! ----------------------------
+! Compute and print I/O rates.
+! ----------------------------
+
+ wrates_l(1) = real(filsiz / wrt_l(2)) ! write rate
+ wrates_l(2) = real(filsiz / (wrt_l(1) + wrt_l(2))) ! effective write rate
+
+ rrates_l(1) = real(filsiz / rdt_l(2)) ! read rate
+ rrates_l(2) = real(filsiz / (rdt_l(1) + rdt_l(2))) ! effective read rate
+
+
+ call MPI_Allreduce
+ & (wrates_l, wrates_g, 2, MPI_REAL, MPI_MIN, comm_cart, ierr)
+ call MPI_Allreduce
+ & (rrates_l, rrates_g, 2, MPI_REAL, MPI_MIN, comm_cart, ierr)
+
+ call MPI_Allreduce
+ & (wrt_l, wrt_g, 2, MPI_REAL, MPI_MAX, comm_cart, ierr)
+ call MPI_Allreduce
+ & (rdt_l, rdt_g, 2, MPI_REAL, MPI_MAX, comm_cart, ierr)
+
+
+ if (mype .EQ. 0) then
+ Write (6,905) filsiz
+ Write (6,910) wrates_g(1), wrates_g(2)
+ Write (6,915) rrates_g(1), rrates_g(2)
+ Write (6,920) totpes
+ Write (6,922) wrt_g(1), wrt_g(2), wrates_g(2),
+ & rdt_g(1), rdt_g(2), rrates_g(2)
+ end if
+
+ 905 format ("File size: ", e10.3, " MB")
+ 910 format (" Write: ", f9.3, " MB/s (eff., ", f9.3, " MB/s)")
+ 915 format (" Read : ", f9.3, " MB/s (eff., ", f9.3, " MB/s)")
+ 920 format ("Total number PEs: ", i4)
+ 922 format (e11.3, e11.3, f9.3, e11.3, e11.3, f9.3)
+
+
+ call MPI_Comm_Free (comm_cart, ierr)
+
+ call MPI_Finalize (ierr)
+
+
+ Stop
+
+ end ! program Pnf_Test
+
+
+! ------------
+
+
+ subroutine Write_File
+ & (filename, nwrites, mype, comm_cart, istart, jstart, kstart,
+ & locsiz, locsiz_3d, totsiz_3d, wrt_l)
+
+ implicit none
+
+ include "mpif.h"
+ include "pnetcdf.inc"
+
+
+! ----------------------
+! Argument declarations.
+! ----------------------
+
+ character*(*) filename
+ integer nwrites
+ integer mype
+ integer comm_cart
+ integer*8 istart, jstart, kstart
+ integer*8 locsiz
+ integer*8 locsiz_3d(3)
+ integer*8 totsiz_3d(3)
+ real*4 wrt_l(2)
+
+
+! ----------------------------
+! Local variable declarations.
+! ----------------------------
+
+ integer ierr
+ integer lon_id, lat_id, lev_id
+ integer ncid
+ integer nw
+ integer tt_id
+
+ integer*8 count_3d(3)
+ integer*8 start_3d(3)
+
+ integer dim_id(3)
+
+ double precision t1, t2, t3
+
+ integer max_loc_size
+ parameter( max_loc_size = 20000000 )
+ real*4 tt(max_loc_size) ! Need tt(locsiz)
+
+
+ if (locsiz .gt. MAX_LOC_SIZE) then
+ print *, 'locsiz = ', locsiz, ' larger than MAX_LOC_SIZE'
+ stop
+ endif
+! ----------------
+! Begin execution.
+! ----------------
+
+! start_3d(1:3) = (/ kstart, jstart, istart /)
+! count_3d(:) = locsiz_3d(:)
+ start_3d(1) = istart
+ start_3d(2) = jstart
+ start_3d(3) = kstart
+ count_3d(1) = locsiz_3d(1)
+ count_3d(2) = locsiz_3d(2)
+ count_3d(3) = locsiz_3d(3)
+
+
+ do nw = 1, nwrites
+
+! ==============
+ call Get_Field
+! ==============
+ & (istart, jstart, kstart, locsiz, locsiz_3d, totsiz_3d, tt)
+
+
+ call MPI_Barrier (comm_cart, ierr)
+ t1 = MPI_Wtime ( )
+
+
+! =================
+ ierr = Nfmpi_Create
+! =================
+ & (comm_cart, filename, NF_CLOBBER, MPI_INFO_NULL, ncid)
+
+
+! ==================
+ ierr = Nfmpi_Def_Dim
+ & (ncid, "level", totsiz_3d(1), lon_id)
+ ierr = Nfmpi_Def_Dim
+ & (ncid, "latitude", totsiz_3d(2), lat_id)
+ ierr = Nfmpi_Def_Dim
+ & (ncid, "longitude", totsiz_3d(3), lev_id)
+! ==================
+
+
+ dim_id(1) = lon_id
+ dim_id(2) = lat_id
+ dim_id(3) = lev_id
+
+! ==================
+ ierr = Nfmpi_Def_Var
+! ==================
+ & (ncid, "tt", NF_REAL, 3, dim_id, tt_id)
+
+
+! =================
+ ierr = Nfmpi_Enddef (ncid)
+! =================
+
+
+ t2 = MPI_Wtime ( )
+
+
+! =============================
+ ierr = Nfmpi_Put_Vara_Real_All
+! =============================
+ & (ncid, tt_id, start_3d, count_3d, tt)
+
+
+! ================
+ ierr = Nfmpi_Close (ncid)
+! ================
+
+
+ call MPI_Barrier (comm_cart, ierr)
+ t3 = MPI_Wtime ( )
+
+
+ if (t2 - t1 .LT. wrt_l(1)) wrt_l(1) = real(t2 - t1)
+ if (t3 - t2 .LT. wrt_l(2)) wrt_l(2) = real(t3 - t2)
+
+ if (mype .EQ. 0) Write (6,950) nw, t2-t1, t3-t2
+
+ end do
+
+
+ 950 format ("write ", i1, ": ", e10.3, 1x, e10.3)
+
+
+ Return
+
+ end
+
+
+! ------------
+
+
+ subroutine Read_File
+ & (filename, nreads, mype, comm_cart, istart, jstart, kstart,
+ & locsiz, locsiz_3d, totsiz_3d, rdt_l)
+
+ implicit none
+
+ include "mpif.h"
+ include "pnetcdf.inc"
+
+
+! ----------------------
+! Argument declarations.
+! ----------------------
+
+ character*(*) filename
+ integer nreads
+ integer mype
+ integer comm_cart
+ integer*8 istart, jstart, kstart
+ integer*8 locsiz
+ integer*8 locsiz_3d(3)
+ integer*8 totsiz_3d(3)
+ real*4 rdt_l(2)
+
+
+! ----------------------------
+! Local variable declarations.
+! ----------------------------
+
+ integer ierr
+ integer ncid
+ integer nr
+ integer tt_id
+ integer ii
+
+ integer*8 count_3d(3)
+ integer*8 start_3d(3)
+
+ double precision t1, t2, t3
+
+ integer max_loc_size
+ parameter( max_loc_size = 20000000 )
+ real*4 buf(max_loc_size)
+ real*4 tt (max_loc_size)
+
+
+! ----------------
+! Begin execution.
+! ----------------
+
+! ==============
+ call Get_Field
+! ==============
+ & (istart, jstart, kstart, locsiz, locsiz_3d, totsiz_3d, tt)
+
+
+! start_3d(1:3) = (/ kstart, jstart, istart /)
+! count_3d(:) = locsiz_3d(:)
+ start_3d(1) = istart
+ start_3d(2) = jstart
+ start_3d(3) = kstart
+ count_3d(1) = locsiz_3d(1)
+ count_3d(2) = locsiz_3d(2)
+ count_3d(3) = locsiz_3d(3)
+
+
+ do nr = 1, nreads
+
+ do ii=1, int(locsiz)
+ buf(ii) = -99.99
+ enddo
+
+
+ call MPI_Barrier (comm_cart, ierr)
+ t1 = MPI_Wtime ( )
+
+
+! ===============
+ ierr = Nfmpi_Open
+! ===============
+ & (comm_cart, filename, NF_NOWRITE, MPI_INFO_NULL, ncid)
+
+
+! ====================
+ ierr = Nfmpi_Inq_Varid
+! ====================
+ & (ncid, "tt", tt_id)
+
+
+ t2 = MPI_Wtime ( )
+
+
+! =============================
+ ierr = Nfmpi_Get_Vara_Real_All
+! =============================
+ & (ncid, tt_id, start_3d, count_3d, buf)
+
+
+! ================
+ ierr = Nfmpi_Close (ncid)
+! ================
+
+
+ call MPI_Barrier (comm_cart, ierr)
+ t3 = MPI_Wtime ( )
+
+
+ if (t2 - t1 .LT. rdt_l(1)) rdt_l(1) = real(t2 - t1)
+ if (t3 - t2 .LT. rdt_l(2)) rdt_l(2) = real(t3 - t2)
+
+ if (mype .EQ. 0) Write (6,970) nr, t2-t1, t3-t2
+
+
+ if (nr .EQ. 1) then
+! ================
+ call Compare_Vec
+! ================
+ & (mype, comm_cart, locsiz, tt, buf)
+ end if
+
+ end do
+
+
+ 970 format (" read ", i1, ": ", e10.3, 1x, e10.3)
+
+
+ Return
+
+ end
+
+
+! ------------
+
+
+ subroutine Find_Locnx
+ & (nx, mype, totpes, locnx, ibegin)
+
+ implicit none
+
+ include "mpif.h"
+ include "pnetcdf.inc"
+
+! ----------------------
+! Argument declarations.
+! ----------------------
+
+ integer*8 nx
+ integer mype
+ integer totpes
+ integer*8 locnx
+ integer*8 ibegin
+
+
+! ----------------------------
+! Local variable declarations.
+! ----------------------------
+
+ integer*8 iremain
+
+
+! ----------------
+! Begin execution.
+! ----------------
+
+ locnx = nx / totpes
+
+ iremain = nx - (totpes * locnx)
+
+ if (mype .LT. iremain) locnx = locnx + 1
+
+ ibegin = mype * (nx / totpes) + iremain + 1
+
+ if (mype .LT. iremain) ibegin = ibegin + (mype - iremain)
+
+
+ Return
+
+ end
+
+
+! ------------
+
+
+ subroutine Get_Field
+ & (istart, jstart, kstart, locsiz, locsiz_3d, totsiz_3d, tt)
+
+ implicit none
+
+ include "mpif.h"
+ include "pnetcdf.inc"
+
+
+! ----------------------
+! Argument declarations.
+! ----------------------
+
+ integer*8 istart, jstart, kstart
+ integer*8 locsiz
+ integer*8 locsiz_3d(3)
+ integer*8 totsiz_3d(3)
+ real*4 tt(locsiz)
+
+
+! ----------------------------
+! Local variable declarations.
+! ----------------------------
+
+ integer ii, jj, kk
+ integer ind
+
+
+! ----------------
+! Begin execution.
+! ----------------
+
+ ind = 1
+
+
+ do kk = 1, int(locsiz_3d(3))
+ do jj = 1, int(locsiz_3d(2))
+ do ii = 1, int(locsiz_3d(1))
+
+ tt(ind) = real(
+ & (istart-1 +(ii - 1) + 1 + totsiz_3d(3)*(jstart-1 +
+ & (jj - 1) + totsiz_3d(2)*(kstart-1 +
+ & (kk-1)))) * 1.0d-3)
+ ind = ind + 1
+
+ end do
+ end do
+ end do
+
+
+ Return
+
+ end
+
+
+! ------------
+
+
+ subroutine Compare_Vec
+ & (mype, comm_cart, locsiz, tt, buf)
+
+ implicit none
+
+ include "mpif.h"
+
+
+! ----------------------
+! Argument declarations.
+! ----------------------
+
+ integer mype
+ integer comm_cart
+ integer*8 locsiz
+ real*4 tt (locsiz)
+ real*4 buf(locsiz)
+
+
+! ----------------------------
+! Local variable declarations.
+! ----------------------------
+
+ integer ierr
+ integer ii
+
+ real*4 delmax, delmin, delta
+ real*4 diff
+
+ real*4 wr(5)
+ real*4 ws(5)
+
+
+! ----------------
+! Begin execution.
+! ----------------
+
+ ws(1) = 0.0d0 ! diff
+ ws(2) = 0.0d0 ! sumsq
+ ws(3) = int(locsiz) ! locsiz
+ ws(4) = 0.0d0 ! delmax
+ ws(5) = 1.0d38 ! Huge (ws) ! delmin
+
+
+ do ii = 1, int(locsiz)
+ delta = (tt(ii) - buf(ii)) * (tt(ii) - buf(ii))
+ ws(1) = ws(1) + delta
+ ws(2) = ws(2) + tt(ii) * tt(ii)
+ if (delta .GT. ws(4)) ws(4) = delta
+ if (delta .LT. ws(5)) ws(5) = delta
+ end do
+
+
+ call MPI_Allreduce
+ & (ws, wr, 3, MPI_REAL, MPI_SUM, comm_cart, ierr)
+ call MPI_Allreduce
+ & (ws(4), delmax, 1, MPI_REAL, MPI_MAX, comm_cart, ierr)
+ call MPI_Allreduce
+ & (ws(5), delmin, 1, MPI_REAL, MPI_MIN, comm_cart, ierr)
+
+
+ diff = Sqrt (wr(1) / wr(2)) ! normalized error
+ delmax = Sqrt (wr(3) * delmax/wr(2)) ! normalized max difference
+ delmin = Sqrt (wr(3) * delmin/wr(2)) ! normalized min difference
+
+
+ if (mype .EQ. 0) Write (6,990) diff, delmax, delmin
+
+ 990 format ("diff, delmax, delmin = ",
+ & e10.3, 1x, e10.3, 1x, e10.3)
+
+
+
+ Return
+
+ end
+
diff --git a/test/header/Makefile.in b/test/header/Makefile.in
new file mode 100644
index 0000000..9dd45fa
--- /dev/null
+++ b/test/header/Makefile.in
@@ -0,0 +1,64 @@
+#
+# Copyright (C) 2003, Northwestern University and Argonne National Laboratory
+# See COPYRIGHT notice in top-level directory.
+#
+# $Id: Makefile.in 2251 2015-12-20 21:13:42Z wkliao $
+#
+# @configure_input@
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+include ../../macros.make
+
+INCLUDES = -I../../src/lib -I$(srcdir)/../common
+LDFLAGS := $(LDFLAGS) -L../common
+LIBS := $(LIBRARY) -ltestutils $(LIBS) @LCOV_LIB@
+ifeq (@PNC_DEBUG@, yes)
+CPPFLAGS := $(CPPFLAGS) -DPNC_DEBUG
+endif
+
+SRCS = header_consistency.c
+
+OBJS = $(SRCS:.c=.o)
+PROGS = $(SRCS:.c=)
+
+GARBAGE = $(PROGS) *.nc
+PACKING_LIST = $(SRCS) Makefile.in
+
+all: $(PROGS)
+
+$(OBJS): $(srcdir)/../common/testutils.h
+
+$(PROGS): ../common/libtestutils.a
+
+../common/libtestutils.a:
+ set -e; cd ../common && $(MAKE) $(MFLAGS) all
+
+header_consistency: header_consistency.o $(LIBRARY)
+ $(LINK.c) $< $(LDFLAGS) $(LIBS)
+
+testing check verbose_testing:
+
+TEST_MPIRUN_2 = $(subst NP,2,$(TEST_MPIRUN))
+TEST_MPIRUN_4 = $(subst NP,4,$(TEST_MPIRUN))
+
+ptest2: $(PROGS)
+ @for i in $(PROGS); do ( \
+ $(TEST_MPIRUN_2) ./$$i $(TEST_OUTDIR)/testfile.nc \
+ ; ) ; done
+
+ptest4: $(PROGS)
+ @for i in $(PROGS); do ( \
+ $(TEST_MPIRUN_4) ./$$i $(TEST_OUTDIR)/testfile.nc \
+ ; ) ; done
+
+ptest: ptest4
+
+ptests: ptest2 ptest4
+ptest6 ptest8 ptest10:
+
+include $(srcdir)/../../rules.make
+
+$(LIBRARY): ;
+
diff --git a/test/header/header_consistency.c b/test/header/header_consistency.c
new file mode 100644
index 0000000..235adf2
--- /dev/null
+++ b/test/header/header_consistency.c
@@ -0,0 +1,621 @@
+/*
+ * Copyright (C) 2013, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ */
+/* $Id: header_consistency.c 2200 2015-11-28 17:54:14Z wkliao $ */
+
+/* This program tests if PnetCDF can detect file header inconsistency and
+ * overwrite the inconsistent header with root's.
+ * This program is designed to run on more than 2 MPI processes.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <mpi.h>
+#include <pnetcdf.h>
+#include <testutils.h>
+
+#define ERR_EXP(e, exp) {if (e != exp) { printf("Error (line %d): expecting error code %s but got %s\n", __LINE__, nc_err_code_name(exp), nc_err_code_name(e)); nerrs++; }}
+#define ERR_EXP2(e, exp1, exp2) {if (e != exp1 && e != exp2) { printf("Error (line %d): expecting error code %s or %s but got %s\n", __LINE__, nc_err_code_name(exp1), nc_err_code_name(exp2), nc_err_code_name(e)); nerrs++; }}
+
+#define CHECK_ERR(expect) { \
+ if (safe_mode) { \
+ if (err != NC_EMULTIDEFINE && err != expect) { \
+ printf("Error (line %d): expecting error code NC_EMULTIDEFINE or %s but got %s\n", __LINE__, nc_err_code_name(expect), nc_err_code_name(err)); \
+ nerrs++; \
+ } \
+ } \
+ else if (rank > 0) { \
+ if (err != expect) { \
+ printf("Error (line %d): expecting error code %s but got %s\n", __LINE__, nc_err_code_name(expect), nc_err_code_name(err)); \
+ nerrs++; \
+ } \
+ } \
+}
+
+#define ERR {if(err!=NC_NOERR) {printf("Error(%d) at line %d: %s\n",err,__LINE__,ncmpi_strerror(err)); nerrs++; }}
+
+/*----< test_open_mode() >----------------------------------------------------*/
+static
+int test_open_mode(char *filename, int safe_mode)
+{
+ int err, rank, ncid, cmode, omode, nerrs=0;
+ MPI_Info info=MPI_INFO_NULL;
+ MPI_Comm comm=MPI_COMM_WORLD;
+
+ MPI_Comm_rank(comm, &rank);
+
+ /* Test inconsistent cmode -----------------------------------------------*/
+ cmode = NC_CLOBBER|NC_64BIT_OFFSET;
+ if (rank == 0) cmode = NC_CLOBBER;
+ err = ncmpi_create(comm, filename, cmode, info, &ncid);
+ /* if safe_mode is on, then we expect all non-root ranks to print a warning
+ * message "inconsistent file create mode, overwrite with root's" and error
+ * code NC_EMULTIDEFINE_OMODE from non-root processes.
+ * if safe_mode is off, then no error code should be returned.
+ */
+ if (safe_mode && rank > 0) ERR_EXP(err, NC_EMULTIDEFINE_OMODE)
+ else ERR
+
+ err = ncmpi_close(ncid);
+ /* if safe_mode is on, then no error code should be returned.
+ * if safe_mode is off, then we expect error code NC_EMULTIDEFINE_OMODE
+ * from all non-root processes and NC_EMULTIDEFINE from root process.
+ */
+ if (safe_mode) ERR
+ else if (rank > 0) ERR_EXP(err, NC_EMULTIDEFINE_OMODE)
+
+ int format;
+ err = ncmpi_inq_file_format(filename, &format); ERR
+ if (format != 1) {
+ printf("Error (line %d): output file should be in CDF-1 format\n",__LINE__);
+ nerrs++;
+ }
+
+ /* Test inconsistent omode -----------------------------------------------*/
+ omode = NC_WRITE;
+ if (rank == 0) omode = NC_NOWRITE;
+ err = ncmpi_open(comm, filename, omode, info, &ncid);
+ if (safe_mode) {
+ /* in safe_mode, we expect all non-root ranks to print a warning message
+ * "inconsistent file open mode, overwrite with root's" and error code
+ * code NC_EMULTIDEFINE_OMODE and no error on root process.
+ */
+ if (rank == 0) ERR
+ else ERR_EXP(err, NC_EMULTIDEFINE_OMODE)
+
+ /* in safe mode, open mode inconsistent is not a fatal error, file is
+ * still opened, with root's omode overwriting others. Hence, once the
+ * test is done, we need to close the file */
+ err = ncmpi_close(ncid); ERR
+ }
+ else {
+ /* expected errors: NC_EMULTIDEFINE_OMODE or NC_EMULTIDEFINE_FNC_ARGS */
+ ERR_EXP2(err, NC_EMULTIDEFINE_OMODE, NC_EMULTIDEFINE_FNC_ARGS)
+
+ /* When not in safe mode, the inconsistent omode will be passed to
+ * MPI_File_open(). MPI-IO should return error class MPI_ERR_NOT_SAME
+ * which will be translated to NC_EMULTIDEFINE_FNC_ARGS in PnetCDF.
+ * If MPI-IO reports error class MPI_ERR_AMODE instead, then it will be
+ * translated to NC_EMULTIDEFINE_OMODE in PnetCDF. In any case, the file
+ * will not be opened by MPI-IO and hence we need not close the file.
+ */
+ }
+ return nerrs;
+}
+
+/*----< test_dim() >----------------------------------------------------------*/
+static
+int test_dim(char *filename, int safe_mode)
+{
+ int err, rank, ncid, cmode, ndims, dimid1, dimid2, dimid3, nerrs=0;
+ MPI_Offset dimlen;
+ MPI_Info info=MPI_INFO_NULL;
+ MPI_Comm comm=MPI_COMM_WORLD;
+
+ MPI_Comm_rank(comm, &rank);
+ cmode = NC_CLOBBER|NC_64BIT_OFFSET;
+
+ /* Test inconsistency on number of dimensions ----------------------------*/
+ err = ncmpi_create(comm, filename, cmode, info, &ncid); ERR
+ err = ncmpi_def_dim(ncid, "x", 100, &dimid1); ERR
+ if (rank == 0) {
+ err = ncmpi_def_dim(ncid, "y", 100, &dimid2); ERR
+ }
+ err = ncmpi_enddef(ncid);
+ /* expected errors: NC_EMULTIDEFINE or NC_EMULTIDEFINE_DIM_NUM */
+ CHECK_ERR(NC_EMULTIDEFINE_DIM_NUM)
+
+ err = ncmpi_inq_ndims(ncid, &ndims); ERR
+ if (ndims != 2) {
+ printf("Error (line %d): number of dimesnions (%d) defined should be 2\n",__LINE__,ndims);
+ nerrs++;
+ }
+ /* all processes should be able to see dim "y" */
+ err = ncmpi_inq_dimid(ncid, "y", &dimid2);
+ if (err != NC_NOERR) {
+ printf("Error (line %d): all processes should be able to see dim \"y\"\n",__LINE__);
+ nerrs++;
+ ERR
+ }
+ err = ncmpi_close(ncid); ERR
+
+ /* Test inconsistency on number of dimensions ----------------------------*/
+ err = ncmpi_create(comm, filename, cmode, info, &ncid); ERR
+ err = ncmpi_def_dim(ncid, "x", 100, &dimid1); ERR
+ if (rank > 0) {
+ err = ncmpi_def_dim(ncid, "y", 100, &dimid2); ERR
+ }
+ err = ncmpi_enddef(ncid);
+ /* expected errors: NC_EMULTIDEFINE or NC_EMULTIDEFINE_DIM_NUM */
+ CHECK_ERR(NC_EMULTIDEFINE_DIM_NUM)
+
+ err = ncmpi_inq_ndims(ncid, &ndims); ERR
+ if (ndims != 1) {
+ printf("Error (line %d): number of dimesnions (%d) defined should be 1\n",__LINE__,ndims);
+ nerrs++;
+ }
+ /* no process should be able to get dim "y" */
+ err = ncmpi_inq_dimid(ncid, "y", &dimid2);
+ CHECK_ERR(NC_EBADDIM)
+
+ err = ncmpi_close(ncid); ERR
+
+ /* Test inconsistency on dimension names ---------------------------------*/
+ err = ncmpi_create(comm, filename, cmode, info, &ncid); ERR
+ if (rank == 0)
+ err = ncmpi_def_dim(ncid, "y", 100, &dimid1);
+ else
+ err = ncmpi_def_dim(ncid, "xx", 100, &dimid1);
+ ERR
+ err = ncmpi_enddef(ncid);
+ /* expected errors: NC_EMULTIDEFINE or NC_EMULTIDEFINE_DIM_NAME */
+ CHECK_ERR(NC_EMULTIDEFINE_DIM_NAME)
+
+ /* all processes should be able to get dim "y" */
+ err = ncmpi_inq_dimid(ncid, "y", &dimid2); ERR
+
+ /* no process should be able to get dim "x" */
+ err = ncmpi_inq_dimid(ncid, "xx", &dimid3);
+ CHECK_ERR(NC_EBADDIM)
+
+ err = ncmpi_close(ncid); ERR
+
+ /* Test inconsistency on dimension size ----------------------------------*/
+ err = ncmpi_create(comm, filename, cmode, info, &ncid); ERR
+ if (rank == 0)
+ err = ncmpi_def_dim(ncid, "x", 99, &dimid1);
+ else
+ err = ncmpi_def_dim(ncid, "x", 100, &dimid1);
+ ERR
+ err = ncmpi_enddef(ncid);
+ /* expected errors: NC_EMULTIDEFINE or NC_EMULTIDEFINE_DIM_SIZE */
+ CHECK_ERR(NC_EMULTIDEFINE_DIM_SIZE)
+
+ /* all processes should be able to get dim "x" of size == 99 */
+ err = ncmpi_inq_dimlen(ncid, dimid1, &dimlen); ERR
+ if (dimlen != 99) {
+ printf("Error (line %d): dimesnion size (%lld) should be 99\n",__LINE__,dimlen);
+ nerrs++;
+ }
+
+ err = ncmpi_close(ncid); ERR
+ return nerrs;
+}
+
+/*----< test_attr() >---------------------------------------------------------*/
+static
+int test_attr(char *filename, int safe_mode)
+{
+ int err, rank, ncid, cmode, nerrs=0;
+ char gattr[128];
+ int int_attr;
+ float flt_attr;
+ MPI_Info info=MPI_INFO_NULL;
+ MPI_Comm comm=MPI_COMM_WORLD;
+
+ MPI_Comm_rank(comm, &rank);
+ cmode = NC_CLOBBER|NC_64BIT_OFFSET;
+
+ /* Test inconsistent global attribute numbers ----------------------------*/
+ err = ncmpi_create(comm, filename, cmode, info, &ncid); ERR
+ int_attr = 1;
+ flt_attr = 1.0;
+ err = ncmpi_put_att_int(ncid, NC_GLOBAL, "gattr_1", NC_INT, 1, &int_attr);
+ ERR
+ if (rank == 0) {
+ err = ncmpi_put_att_float(ncid, NC_GLOBAL, "gattr_2", NC_FLOAT, 1,
+ &flt_attr); ERR
+ }
+ err = ncmpi_enddef(ncid);
+ CHECK_ERR(NC_EMULTIDEFINE_ATTR_NUM)
+ err = ncmpi_close(ncid); ERR
+
+ /* Test inconsistent global attribute name -------------------------------*/
+ err = ncmpi_create(comm, filename, cmode, info, &ncid); ERR
+ int_attr = 1;
+ sprintf(gattr, "gattr_name.%d",rank);
+ err = ncmpi_put_att_int(ncid, NC_GLOBAL, gattr, NC_INT, 1, &int_attr); ERR
+ err = ncmpi_enddef(ncid);
+ CHECK_ERR(NC_EMULTIDEFINE_ATTR_NAME)
+ err = ncmpi_close(ncid); ERR
+
+ /* Test inconsistent global attribute type -------------------------------*/
+ err = ncmpi_create(comm, filename, cmode, info, &ncid); ERR
+ if (rank == 0)
+ err = ncmpi_put_att_int(ncid, NC_GLOBAL, "gatt", NC_INT, 1, &int_attr);
+ else
+ err = ncmpi_put_att_float(ncid, NC_GLOBAL, "gatt", NC_FLOAT, 1, &flt_attr);
+ ERR
+ err = ncmpi_enddef(ncid);
+ CHECK_ERR(NC_EMULTIDEFINE_ATTR_TYPE)
+ err = ncmpi_close(ncid); ERR
+
+ /* Test inconsistent global attribute length -----------------------------*/
+ err = ncmpi_create(comm, filename, cmode, info, &ncid); ERR
+ int intv[2]={1,2};
+ if (rank == 0)
+ err = ncmpi_put_att_int(ncid, NC_GLOBAL, "gatt", NC_INT, 2, intv);
+ else
+ err = ncmpi_put_att_int(ncid, NC_GLOBAL, "gatt", NC_INT, 1, intv);
+ ERR
+ err = ncmpi_enddef(ncid);
+ CHECK_ERR(NC_EMULTIDEFINE_ATTR_LEN)
+ err = ncmpi_close(ncid); ERR
+
+ /* Test inconsistent global attribute length -----------------------------*/
+ err = ncmpi_create(comm, filename, cmode, info, &ncid); ERR
+ if (rank == 0) intv[1]=3;
+ err = ncmpi_put_att_int(ncid, NC_GLOBAL, "gatt", NC_INT, 2, intv);
+ ERR
+ err = ncmpi_enddef(ncid);
+ CHECK_ERR(NC_EMULTIDEFINE_ATTR_VAL)
+ err = ncmpi_close(ncid); ERR
+
+ return nerrs;
+}
+
+/*----< test_var() >----------------------------------------------------------*/
+static
+int test_var(char *filename, int safe_mode)
+{
+ int err, rank, ncid, cmode, nerrs=0;
+ int ndims, dimid[3], nvars, varid1, varid2, int_attr;
+ float flt_attr;
+ char name[128], var_attr[128];
+ nc_type xtype;
+ MPI_Offset dimlen;
+ MPI_Info info=MPI_INFO_NULL;
+ MPI_Comm comm=MPI_COMM_WORLD;
+
+ MPI_Comm_rank(comm, &rank);
+ cmode = NC_CLOBBER|NC_64BIT_OFFSET;
+
+ /* Test inconsistent variable attribute numbers --------------------------*/
+ err = ncmpi_create(comm, filename, cmode, info, &ncid); ERR
+ err = ncmpi_def_dim(ncid, "dim1", NC_UNLIMITED, &dimid[0]); ERR
+ err = ncmpi_def_var(ncid, "var1", NC_INT, 1, dimid, &varid1); ERR
+ int_attr = 1;
+ flt_attr = 1.0;
+ err = ncmpi_put_att_int(ncid, varid1, "var_attr_1", NC_INT, 1, &int_attr);
+ ERR
+ if (rank == 0) {
+ err = ncmpi_put_att_float(ncid, varid1, "var_attr_2", NC_FLOAT, 1,
+ &flt_attr); ERR
+ }
+ err = ncmpi_enddef(ncid);
+ CHECK_ERR(NC_EMULTIDEFINE_ATTR_NUM)
+ err = ncmpi_close(ncid); ERR
+
+ /* Test inconsistent global attribute name -------------------------------*/
+ err = ncmpi_create(comm, filename, cmode, info, &ncid); ERR
+ err = ncmpi_def_dim(ncid, "dim1", NC_UNLIMITED, &dimid[0]); ERR
+ err = ncmpi_def_var(ncid, "var1", NC_INT, 1, dimid, &varid1); ERR
+ int_attr = 1;
+ sprintf(var_attr, "var_attr_name.%d",rank);
+ err = ncmpi_put_att_int(ncid, varid1, var_attr, NC_INT, 1, &int_attr); ERR
+ err = ncmpi_enddef(ncid);
+ CHECK_ERR(NC_EMULTIDEFINE_ATTR_NAME)
+ err = ncmpi_close(ncid); ERR
+
+ /* Test inconsistent global attribute type -------------------------------*/
+ err = ncmpi_create(comm, filename, cmode, info, &ncid); ERR
+ err = ncmpi_def_dim(ncid, "dim1", NC_UNLIMITED, &dimid[0]); ERR
+ err = ncmpi_def_var(ncid, "var1", NC_INT, 1, dimid, &varid1); ERR
+ if (rank == 0)
+ err = ncmpi_put_att_int(ncid, varid1, "var_att", NC_INT, 1, &int_attr);
+ else
+ err = ncmpi_put_att_float(ncid, varid1, "var_att", NC_FLOAT, 1, &flt_attr);
+ ERR
+ err = ncmpi_enddef(ncid);
+ CHECK_ERR(NC_EMULTIDEFINE_ATTR_TYPE)
+ err = ncmpi_close(ncid); ERR
+
+ /* Test inconsistent global attribute length -----------------------------*/
+ err = ncmpi_create(comm, filename, cmode, info, &ncid); ERR
+ err = ncmpi_def_dim(ncid, "dim1", NC_UNLIMITED, &dimid[0]); ERR
+ err = ncmpi_def_var(ncid, "var1", NC_INT, 1, dimid, &varid1); ERR
+ int intv[2]={1,2};
+ if (rank == 0)
+ err = ncmpi_put_att_int(ncid, varid1, "var_att", NC_INT, 2, intv);
+ else
+ err = ncmpi_put_att_int(ncid, varid1, "var_att", NC_INT, 1, intv);
+ ERR
+ err = ncmpi_enddef(ncid);
+ CHECK_ERR(NC_EMULTIDEFINE_ATTR_LEN)
+ err = ncmpi_close(ncid); ERR
+
+ /* Test inconsistent global attribute length -----------------------------*/
+ err = ncmpi_create(comm, filename, cmode, info, &ncid); ERR
+ err = ncmpi_def_dim(ncid, "dim1", NC_UNLIMITED, &dimid[0]); ERR
+ err = ncmpi_def_var(ncid, "var1", NC_INT, 1, dimid, &varid1); ERR
+ if (rank == 0) intv[1]=3;
+ err = ncmpi_put_att_int(ncid, varid1, "var_att", NC_INT, 2, intv);
+ ERR
+ err = ncmpi_enddef(ncid);
+ CHECK_ERR(NC_EMULTIDEFINE_ATTR_VAL)
+ err = ncmpi_close(ncid); ERR
+
+ /* Test inconsistent number of variables ---------------------------------*/
+ err = ncmpi_create(comm, filename, cmode, info, &ncid); ERR
+ err = ncmpi_def_dim(ncid, "dim1", NC_UNLIMITED, &dimid[0]); ERR
+ err = ncmpi_def_var(ncid, "var1", NC_INT, 1, dimid, &varid1); ERR
+ if (rank == 0) {
+ err = ncmpi_def_var(ncid, "var2", NC_INT, 1, dimid, &varid2); ERR
+ }
+ err = ncmpi_enddef(ncid);
+ CHECK_ERR(NC_EMULTIDEFINE_VAR_NUM)
+
+ err = ncmpi_inq_nvars(ncid, &nvars); ERR
+ if (nvars != 2) {
+ printf("Error (line %d): all processes should see 2 variables\n",__LINE__);
+ nerrs++;
+ }
+ err = ncmpi_close(ncid); ERR
+
+ /* Test inconsistent variable name ---------------------------------------*/
+ err = ncmpi_create(comm, filename, cmode, info, &ncid); ERR
+ err = ncmpi_def_dim(ncid, "dim1", NC_UNLIMITED, &dimid[0]); ERR
+ sprintf(name, "var.%d",rank);
+ err = ncmpi_def_var(ncid, name, NC_INT, 1, dimid, &varid1); ERR
+ err = ncmpi_enddef(ncid);
+ CHECK_ERR(NC_EMULTIDEFINE_VAR_NAME)
+
+ err = ncmpi_inq_varname(ncid, varid1, name); ERR
+ if (strcmp(name, "var.0")) {
+ printf("Error (line %d): all processes should see variable name: \"var.0\"\n",__LINE__);
+ nerrs++;
+ }
+ err = ncmpi_close(ncid); ERR
+
+ /* Test inconsistent variable ndims --------------------------------------*/
+ err = ncmpi_create(comm, filename, cmode, info, &ncid); ERR
+ err = ncmpi_def_dim(ncid, "dim0", 3, &dimid[0]); ERR
+ err = ncmpi_def_dim(ncid, "dim1", 2, &dimid[1]); ERR
+ if (rank == 0)
+ err = ncmpi_def_var(ncid, "var", NC_FLOAT, 2, dimid, &varid1);
+ else
+ err = ncmpi_def_var(ncid, "var", NC_FLOAT, 1, dimid, &varid1);
+ ERR
+ err = ncmpi_enddef(ncid);
+ CHECK_ERR(NC_EMULTIDEFINE_VAR_NDIMS)
+
+ err = ncmpi_inq_varndims(ncid, varid1, &ndims); ERR
+ if (ndims != 2) {
+ printf("Error (line %d): all processes should see var has 2 dimensions\n",__LINE__);
+ nerrs++;
+ }
+ err = ncmpi_close(ncid); ERR
+
+ /* Test inconsistent variable type ---------------------------------------*/
+ err = ncmpi_create(comm, filename, cmode, info, &ncid); ERR
+ err = ncmpi_def_dim(ncid, "dim1", NC_UNLIMITED, &dimid[0]); ERR
+ if (rank == 0)
+ err = ncmpi_def_var(ncid, "var", NC_INT, 1, dimid, &varid1);
+ else
+ err = ncmpi_def_var(ncid, "var", NC_FLOAT, 1, dimid, &varid1);
+ ERR
+ err = ncmpi_enddef(ncid);
+ CHECK_ERR(NC_EMULTIDEFINE_VAR_TYPE)
+
+ err = ncmpi_inq_vartype(ncid, varid1, &xtype); ERR
+ if (xtype != NC_INT) {
+ printf("Error (line %d): all processes should see var is of type NC_INT\n",__LINE__);
+ nerrs++;
+ }
+ err = ncmpi_close(ncid); ERR
+
+ /* Test inconsistent variable length -------------------------------------*/
+ err = ncmpi_create(comm, filename, cmode, info, &ncid); ERR
+ err = ncmpi_def_dim(ncid, "dim0", 5, &dimid[0]); ERR
+ err = ncmpi_def_dim(ncid, "dim1", 4, &dimid[1]); ERR
+ err = ncmpi_def_dim(ncid, "dim2", 3, &dimid[2]); ERR
+ if (rank == 0) {
+ err = ncmpi_def_var(ncid, "var", NC_FLOAT, 2, dimid, &varid1); ERR
+ }
+ else {
+ err = ncmpi_def_var(ncid, "var", NC_FLOAT, 2, dimid+1, &varid1); ERR
+ }
+ err = ncmpi_enddef(ncid);
+ CHECK_ERR(NC_EMULTIDEFINE_VAR_LEN)
+
+ err = ncmpi_inq_vardimid(ncid, varid1, dimid); ERR
+ err = ncmpi_inq_dimname(ncid, dimid[0], name); ERR
+ if (strcmp(name, "dim0")) {
+ printf("Error (line %d): all processes should see var's dim[0] name \"dim0\"\n",__LINE__);
+ nerrs++;
+ }
+ err = ncmpi_inq_dimname(ncid, dimid[1], name); ERR
+ if (strcmp(name, "dim1")) {
+ printf("Error (line %d): all processes should see var's dim[1] name \"dim1\"\n",__LINE__);
+ nerrs++;
+ }
+ err = ncmpi_inq_dimlen(ncid, dimid[0], &dimlen); ERR
+ if (dimlen != 5) {
+ printf("Error (line %d): all processes should see var's dim[0] len == 5\n",__LINE__);
+ nerrs++;
+ }
+ err = ncmpi_inq_dimlen(ncid, dimid[1], &dimlen); ERR
+ if (dimlen != 4) {
+ printf("Error (line %d): all processes should see var's dim[1] len == 4\n",__LINE__);
+ nerrs++;
+ }
+ err = ncmpi_close(ncid); ERR
+
+ /* Test inconsistent variable dimension IDs ------------------------------*/
+ err = ncmpi_create(comm, filename, cmode, info, &ncid); ERR
+ err = ncmpi_def_dim(ncid, "Z", 3, &dimid[0]); ERR
+ err = ncmpi_def_dim(ncid, "Y", 3, &dimid[1]); ERR
+ err = ncmpi_def_dim(ncid, "X", 3, &dimid[2]); ERR
+ if (rank == 0) {
+ err = ncmpi_def_var(ncid, "var", NC_FLOAT, 2, dimid+1, &varid1); ERR
+ }
+ else {
+ err = ncmpi_def_var(ncid, "var", NC_FLOAT, 2, dimid, &varid1); ERR
+ }
+ err = ncmpi_enddef(ncid);
+ CHECK_ERR(NC_EMULTIDEFINE_VAR_DIMIDS)
+
+ err = ncmpi_inq_vardimid(ncid, varid1, dimid); ERR
+ err = ncmpi_inq_dimname(ncid, dimid[0], name); ERR
+ if (strcmp(name, "Y")) {
+ printf("Error (line %d): all processes should see var's dim[0] name \"Y\"\n",__LINE__);
+ nerrs++;
+ }
+ err = ncmpi_inq_dimname(ncid, dimid[1], name); ERR
+ if (strcmp(name, "X")) {
+ printf("Error (line %d): all processes should see var's dim[1] name \"X\"\n",__LINE__);
+ nerrs++;
+ }
+ err = ncmpi_close(ncid); ERR
+
+ return nerrs;
+}
+
+/*----< test_dim_var() >------------------------------------------------------*/
+static
+int test_dim_var(char *filename, int safe_mode)
+{
+ int i, err, rank, ncid, cmode, nerrs=0;
+ int ndims, dimid[3], varid1;
+ char name[128], dimname[128];
+ MPI_Offset dimlen;
+ MPI_Info info=MPI_INFO_NULL;
+ MPI_Comm comm=MPI_COMM_WORLD;
+
+ MPI_Comm_rank(comm, &rank);
+ cmode = NC_CLOBBER|NC_64BIT_OFFSET;
+
+ /* Test inconsistent of dimensions impact to variables -------------------*/
+ err = ncmpi_create(comm, filename, cmode, info, &ncid); ERR
+ err = ncmpi_def_dim(ncid, "dim1", 5, &dimid[0]); ERR
+ err = ncmpi_def_dim(ncid, "dim2", 4, &dimid[1]); ERR
+ if (rank == 0) {
+ err = ncmpi_def_dim(ncid, "dim3", 3, &dimid[2]); ERR
+ err = ncmpi_def_var(ncid, "var1", NC_INT, 2, dimid+1, &varid1); ERR
+ }
+ else {
+ err = ncmpi_def_var(ncid, "var1", NC_INT, 2, dimid, &varid1); ERR
+ }
+ err = ncmpi_enddef(ncid);
+ CHECK_ERR(NC_EMULTIDEFINE_DIM_NUM)
+
+ err = ncmpi_inq_ndims(ncid, &ndims); ERR
+ if (ndims != 3) {
+ printf("Error (line %d): all processes should see 3 dimensions\n",__LINE__);
+ nerrs++;
+ }
+ dimid[0] = dimid[1] = dimid[2] = -1;
+ err = ncmpi_inq_vardimid(ncid, varid1, dimid); ERR
+ for (i=0; i<2; i++) {
+ err = ncmpi_inq_dimname(ncid, dimid[i], name); ERR
+ sprintf(dimname, "dim%d", i);
+ if (!strcmp(name, dimname)) {
+ printf("Error (line %d): all processes should see dimid[%d] name \"%s\"\n",__LINE__,i,dimname);
+ nerrs++;
+ }
+ }
+ err = ncmpi_inq_dimlen(ncid, dimid[0], &dimlen); ERR
+ if (dimlen != 4) {
+ printf("Error (line %d): all processes should see dimid[0] len = 4\n",__LINE__);
+ nerrs++;
+ }
+ err = ncmpi_inq_dimlen(ncid, dimid[1], &dimlen); ERR
+ if (dimlen != 3) {
+ printf("Error (line %d): all processes should see dimid[1] len = 3\n",__LINE__);
+ nerrs++;
+ }
+ err = ncmpi_close(ncid); ERR
+
+
+ return nerrs;
+}
+
+/*----< main() >--------------------------------------------------------------*/
+int main(int argc, char **argv)
+{
+ char *filename="testfile.nc", *mode[2] = {"0", "1"};
+ int i, rank, nprocs, verbose, nerrs=0;
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+
+ if (nprocs < 2) {
+ if (!rank) printf("This program is for running 2 or more processes. Exiting ...\n");
+ MPI_Finalize();
+ return 0;
+ }
+
+ if (argc > 2) {
+ if (!rank) printf("Usage: %s [filename]\n",argv[0]);
+ MPI_Finalize();
+ return 0;
+ }
+ if (argc == 2) filename = argv[1];
+
+ if (rank == 0) {
+ char cmd_str[256];
+ sprintf(cmd_str, "*** TESTING C %s for header consistency", argv[0]);
+ printf("%-66s ------ ", cmd_str);
+ }
+
+ verbose = 0;
+ for (i=verbose; i>=0; i--) {
+ /* test with safe mode off and on :
+ * Note even if --enable-debug is set at configure time, safe mode
+ * can still be disabled by setting the environment variable
+ * PNETCDF_SAFE_MODE to 0.
+ */
+ setenv("PNETCDF_SAFE_MODE", mode[i], 1);
+ nerrs += test_open_mode(filename, i);
+
+ nerrs += test_dim(filename, i);
+
+ nerrs += test_attr(filename, i);
+
+ nerrs += test_var(filename, i);
+
+ nerrs += test_dim_var(filename, i);
+ }
+
+ MPI_Offset malloc_size, sum_size;
+ int err = ncmpi_inq_malloc_size(&malloc_size);
+ if (err == NC_NOERR) {
+ MPI_Reduce(&malloc_size, &sum_size, 1, MPI_OFFSET, MPI_SUM, 0, MPI_COMM_WORLD);
+ if (rank == 0 && sum_size > 0)
+ printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n",
+ sum_size);
+ }
+
+ MPI_Allreduce(MPI_IN_PLACE, &nerrs, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
+ if (rank == 0) {
+ if (nerrs) printf(FAIL_STR,nerrs);
+ else printf(PASS_STR);
+ }
+
+ MPI_Finalize();
+ return 0;
+}
+
diff --git a/test/largefile/Makefile.in b/test/largefile/Makefile.in
new file mode 100644
index 0000000..c931567
--- /dev/null
+++ b/test/largefile/Makefile.in
@@ -0,0 +1,86 @@
+#
+# Copyright (C) 2003, Northwestern University and Argonne National Laboratory
+# See COPYRIGHT notice in top-level directory.
+#
+# $Id: Makefile.in 2251 2015-12-20 21:13:42Z wkliao $
+#
+# @configure_input@
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+include ../../macros.make
+
+INCLUDES = -I../../src/lib -I$(srcdir)/../common
+LDFLAGS := $(LDFLAGS) -L../common
+LIBS := $(LIBRARY) -ltestutils $(LIBS) @LCOV_LIB@
+ifeq (@PNC_DEBUG@, yes)
+CPPFLAGS := $(CPPFLAGS) -DPNC_DEBUG
+endif
+
+ifeq (@is_bigendian@, yes)
+DEFS := $(DEFS) -DWORDS_BIGENDIAN
+endif
+
+SRCS = large_files.c \
+ large_var.c
+
+OBJS = $(SRCS:.c=.o)
+PROGS = $(SRCS:.c=)
+
+GARBAGE = $(PROGS) *.nc
+PACKING_LIST = $(SRCS) Makefile.in
+
+all: $(PROGS)
+
+$(OBJS): $(srcdir)/../common/testutils.h
+
+$(PROGS): ../common/libtestutils.a
+
+../common/libtestutils.a:
+ set -e; cd ../common && $(MAKE) $(MFLAGS) all
+
+large_files: large_files.o $(LIBRARY)
+ $(LINK.c) $< $(LDFLAGS) $(LIBS)
+
+large_var: large_var.o $(LIBRARY)
+ $(LINK.c) $< $(LDFLAGS) $(LIBS)
+
+testing check verbose_testing: $(PROGS)
+ $(RM) -f $(TEST_OUTDIR)/testfile.nc $(TEST_OUTDIR)/testfile.nc
+ for i in $< ; do ( \
+ $(TEST_SEQRUN) ./$$i $(TEST_OUTDIR)/testfile.nc \
+ ; ) ; done
+
+# Some of these tests are designed to run on one processes,
+# Run them on 4 processes to see if they can handle well
+TEST_MPIRUN_2 = $(subst NP,2,$(TEST_MPIRUN))
+TEST_MPIRUN_4 = $(subst NP,4,$(TEST_MPIRUN))
+TEST_MPIRUN_6 = $(subst NP,6,$(TEST_MPIRUN))
+
+ptest4: $(PROGS)
+ $(RM) -f $(TEST_OUTDIR)/testfile.nc $(TEST_OUTDIR)/testfile.nc
+ for i in $< ; do ( \
+ $(TEST_MPIRUN_4) ./$$i $(TEST_OUTDIR)/testfile.nc \
+ ; ) ; done
+
+ptest2: $(PROGS)
+ $(RM) -f $(TEST_OUTDIR)/testfile.nc $(TEST_OUTDIR)/testfile.nc
+ @for i in $(PROGS); do ( \
+ $(TEST_MPIRUN_2) ./$$i $(TEST_OUTDIR)/testfile.nc \
+ ; ) ; done
+
+ptest6: $(PROGS)
+ $(RM) -f $(TEST_OUTDIR)/testfile.nc $(TEST_OUTDIR)/testfile.nc
+ @for i in $(PROGS); do ( \
+ $(TEST_MPIRUN_6) ./$$i $(TEST_OUTDIR)/testfile.nc \
+ ; ) ; done
+
+ptest: ptest4
+ptests: ptest2 ptest4 ptest6
+ptest8 ptest10:
+
+include $(srcdir)/../../rules.make
+
+$(LIBRARY): ;
+
diff --git a/test/largefile/large_files.c b/test/largefile/large_files.c
new file mode 100644
index 0000000..efa0d8a
--- /dev/null
+++ b/test/largefile/large_files.c
@@ -0,0 +1,194 @@
+/*
+ Copyright 2004-2006, UCAR/Unidata
+ See COPYRIGHT file for copying and redistribution conditions.
+
+ This is part of netCDF.
+
+ This program also takes a long time to run - it writes some data in
+ a very large file, and then reads it all back to be sure it's
+ correct.
+
+ This program is an add-on test to check very large 64-bit offset
+ files (8 GB, so make sure you have the disk space!).
+
+ $Id: large_files.c 2133 2015-09-26 19:16:01Z wkliao $
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <mpi.h>
+#include <pnetcdf.h>
+
+#define FILE_NAME "./testfile.nc"
+
+static
+void check_err(const int stat, const int line, const char *file) {
+ if (stat != NC_NOERR) {
+ (void) fprintf(stderr, "line %d of %s: %s\n", line, file, ncmpi_strerror(stat));
+ exit(1);
+ }
+}
+
+int
+main(int argc, char **argv) {
+
+ int stat; /* return status */
+ int ncid; /* netCDF id */
+ int rec, i, j, k, rank, nprocs, nerrs=0;
+ signed char x[] = {42, 21};
+
+ /* dimension ids */
+ int rec_dim;
+ int i_dim;
+ int j_dim;
+ int k_dim;
+ int n_dim;
+
+#define NUMRECS 1
+#define I_LEN 4104
+#define J_LEN 1023
+#define K_LEN 1023
+#define N_LEN 2
+
+ /* dimension lengths */
+ MPI_Offset rec_len = NC_UNLIMITED;
+ MPI_Offset i_len = I_LEN;
+ MPI_Offset j_len = J_LEN;
+ MPI_Offset k_len = K_LEN;
+ MPI_Offset n_len = N_LEN;
+
+ /* variable ids */
+ int var1_id;
+ int x_id;
+
+ /* rank (number of dimensions) for each variable */
+# define RANK_var1 4
+# define RANK_x 2
+
+ /* variable shapes */
+ int var1_dims[RANK_var1];
+ int x_dims[RANK_x];
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+ if (rank > 0) goto fn_exit;
+
+ printf("\n*** Testing large files, slowly.\n");
+ printf("*** Creating large file %s...", FILE_NAME);
+
+ /* enter define mode */
+ stat = ncmpi_create(MPI_COMM_SELF, FILE_NAME, NC_CLOBBER|NC_64BIT_DATA,
+ MPI_INFO_NULL, &ncid);
+ check_err(stat,__LINE__,__FILE__);
+
+ /* define dimensions */
+ stat = ncmpi_def_dim(ncid, "rec", rec_len, &rec_dim);
+ check_err(stat,__LINE__,__FILE__);
+ stat = ncmpi_def_dim(ncid, "i", i_len, &i_dim);
+ check_err(stat,__LINE__,__FILE__);
+ stat = ncmpi_def_dim(ncid, "j", j_len, &j_dim);
+ check_err(stat,__LINE__,__FILE__);
+ stat = ncmpi_def_dim(ncid, "k", k_len, &k_dim);
+ check_err(stat,__LINE__,__FILE__);
+ stat = ncmpi_def_dim(ncid, "n", n_len, &n_dim);
+ check_err(stat,__LINE__,__FILE__);
+
+ /* define variables */
+
+ var1_dims[0] = rec_dim;
+ var1_dims[1] = i_dim;
+ var1_dims[2] = j_dim;
+ var1_dims[3] = k_dim;
+ stat = ncmpi_def_var(ncid, "var1", NC_BYTE, RANK_var1, var1_dims, &var1_id);
+ check_err(stat,__LINE__,__FILE__);
+
+ x_dims[0] = rec_dim;
+ x_dims[1] = n_dim;
+ stat = ncmpi_def_var(ncid, "x", NC_BYTE, RANK_x, x_dims, &x_id);
+ check_err(stat,__LINE__,__FILE__);
+ /* don't initialize variables with fill values */
+ stat = ncmpi_set_fill(ncid, NC_NOFILL, 0);
+ check_err(stat,__LINE__,__FILE__);
+
+ /* leave define mode */
+ stat = ncmpi_enddef (ncid);
+ check_err(stat,__LINE__,__FILE__);
+
+ { /* store var1 */
+ int n = 0;
+ static signed char var1[J_LEN][K_LEN];
+ static MPI_Offset var1_start[RANK_var1] = {0, 0, 0, 0};
+ static MPI_Offset var1_count[RANK_var1] = {1, 1, J_LEN, K_LEN};
+ static MPI_Offset x_start[RANK_x] = {0, 0};
+ static MPI_Offset x_count[RANK_x] = {1, N_LEN};
+ for(rec=0; rec<NUMRECS; rec++) {
+ var1_start[0] = rec;
+ x_start[0] = rec;
+ for(i=0; i<I_LEN; i++) {
+ for(j=0; j<J_LEN; j++) {
+ for (k=0; k<K_LEN; k++) {
+ var1[j][k] = n++;
+ }
+ }
+ var1_start[1] = i;
+ stat = ncmpi_put_vara_schar_all(ncid, var1_id, var1_start, var1_count, &var1[0][0]);
+ check_err(stat,__LINE__,__FILE__);
+ }
+ }
+ stat = ncmpi_put_vara_schar_all(ncid, x_id, x_start, x_count, x);
+ check_err(stat,__LINE__,__FILE__);
+ }
+
+ stat = ncmpi_close(ncid);
+ check_err(stat,__LINE__,__FILE__);
+
+ printf("ok\n");
+ printf("*** Reading large file %s...", FILE_NAME);
+
+ stat = ncmpi_open(MPI_COMM_SELF, FILE_NAME, NC_NOWRITE,
+ MPI_INFO_NULL, &ncid);
+ check_err(stat,__LINE__,__FILE__);
+
+ { /* read var1 */
+ int n = 0;
+ static signed char var1[J_LEN][K_LEN];
+ static MPI_Offset var1_start[RANK_var1] = {0, 0, 0, 0};
+ static MPI_Offset var1_count[RANK_var1] = {1, 1, J_LEN, K_LEN};
+ static MPI_Offset x_start[RANK_x] = {0, 0};
+ static MPI_Offset x_count[RANK_x] = {1, N_LEN};
+ for(rec=0; rec<NUMRECS; rec++) {
+ var1_start[0] = rec;
+ x_start[0] = rec;
+ for(i=0; i<I_LEN; i++) {
+ var1_start[1] = i;
+ stat = ncmpi_get_vara_schar_all(ncid, var1_id, var1_start, var1_count, &var1[0][0]);
+ check_err(stat,__LINE__,__FILE__);
+ for(j=0; j<J_LEN; j++) {
+ for (k=0; k<K_LEN; k++) {
+ if (var1[j][k] != (signed char) n) {
+ printf("Error on read, var1[%d, %d, %d, %d] = %d wrong, "
+ "should be %d !\n", rec, i, j, k, var1[j][k], (signed char) n);
+ nerrs++;
+ }
+ n++;
+ }
+ }
+ }
+ ncmpi_get_vara_schar_all(ncid, x_id, x_start, x_count, x);
+ if(x[0] != 42 || x[1] != 21) {
+ printf("Error on read, x[] = %d, %d\n", x[0], x[1]);
+ nerrs++;
+ }
+ }
+ }
+ stat = ncmpi_close(ncid);
+ check_err(stat,__LINE__,__FILE__);
+
+ printf("ok\n");
+ printf("*** Tests successful!\n");
+
+fn_exit:
+ MPI_Finalize();
+ return 0;
+}
diff --git a/test/largefile/large_var.c b/test/largefile/large_var.c
new file mode 100644
index 0000000..19b9800
--- /dev/null
+++ b/test/largefile/large_var.c
@@ -0,0 +1,293 @@
+/*********************************************************************
+ *
+ * Copyright (C) 2014, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ *
+ *********************************************************************/
+/* $Id: large_var.c 2300 2016-01-09 06:16:29Z wkliao $ */
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ *
+ * This program is to test if MPI filetypes are defined correctly for accessing
+ * arrays with more than 2G elements.
+ *
+ * This program calls ncmpi_put_vara_int_all() and ncmpi_iput_vara_int()
+ * to write multiple subarray of a large 3D 4-byte integer array. It first
+ * defines a netCDF variable of size 4 x 10 x 4294967296.
+ * 1st write: subarray of 1 x 2 x 10 at the start 1 x 8 x (2G + rank * 10)
+ * 2nd write: subarray of 1 x 2 x 5 at the start 3 x 8 x (2G + rank * 10)
+ * 3rd write: subarray of 1 x 1 x 5 at the start 3 x 8 x (2G + rank * 10 + 5)
+ * 4th write: subarray of 1 x 1 x 5 at the start 3 x 9 x (2G + rank * 10 + 5)
+ *
+ * The written contents are read back by a different process to check
+ * correctness. Two reads are performed: PnetCDF and MPI-IO.
+ *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h> /* strcpy() */
+#include <mpi.h>
+#include <pnetcdf.h>
+#include <testutils.h>
+
+#define FOUR_G 4294967296
+#define TWO_G 2147483648
+#define ONE_G 1073741824
+
+#define NZ 4
+#define NY 10
+#define NX FOUR_G
+
+#define ERR if (err!=NC_NOERR) {printf("Error at line %d: err=%s (%s)\n", __LINE__,nc_err_code_name(err),ncmpi_strerror(err)); exit(-1);}
+
+#ifndef WORDS_BIGENDIAN
+/* Endianness byte swap: done in-place */
+#define SWAP(x,y) {tmp = (x); (x) = (y); (y) = tmp;}
+static void
+swapn(void *buf,
+ MPI_Offset nelems)
+{
+ int i;
+ unsigned char tmp, *op = (unsigned char*)buf;
+
+ while (nelems-- > 0) {
+ for (i=0; i<2; i++)
+ SWAP(op[i], op[3-i])
+ op += 4;
+ }
+}
+#endif
+
+int main(int argc, char** argv)
+{
+ char filename[256];
+ int i, j, rank, nprocs, err, nerrs=0, bufsize;
+ int ncid, cmode, varid, dimid[3], req[3], st[3], *buf, *buf_ptr;
+ MPI_Offset offset, var_offset, start[3], count[3];
+ MPI_File fh;
+ MPI_Status status;
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+
+ /* get command-line arguments */
+ if (argc > 2) {
+ if (!rank) printf("Usage: %s [filename]\n",argv[0]);
+ MPI_Finalize();
+ return 0;
+ }
+ strcpy(filename, "testfile.nc");
+ if (argc == 2) strcpy(filename, argv[1]);
+ MPI_Bcast(filename, 256, MPI_CHAR, 0, MPI_COMM_WORLD);
+
+ if (rank == 0) {
+ char cmd_str[256];
+ sprintf(cmd_str, "*** TESTING C %s for writing to a large variable ", argv[0]);
+ printf("%-66s ------ ", cmd_str); fflush(stdout);
+ }
+
+ /* create a new file for writing ----------------------------------------*/
+ cmode = NC_CLOBBER | NC_64BIT_DATA;
+ err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, MPI_INFO_NULL, &ncid);
+ ERR
+
+ /* define dimensions Z, Y, and X */
+ err = ncmpi_def_dim(ncid, "Z", NZ, &dimid[0]);
+ ERR
+ err = ncmpi_def_dim(ncid, "Y", NY, &dimid[1]);
+ ERR
+ err = ncmpi_def_dim(ncid, "X", NX, &dimid[2]);
+ ERR
+
+ /* define a 3D variable of integer type */
+ err = ncmpi_def_var(ncid, "var", NC_INT, 3, dimid, &varid);
+ ERR
+
+ /* do not forget to exit define mode */
+ err = ncmpi_enddef(ncid);
+ ERR
+
+ /* get the beginning of file offset for the varaiable */
+ err = ncmpi_inq_varoffset(ncid, varid, &var_offset);
+ ERR
+
+ /* now we are in data mode */
+ start[0] = 1;
+ start[1] = NY - 2;
+ start[2] = TWO_G + 10 * rank;
+ count[0] = 1;
+ count[1] = 2;
+ count[2] = 10;
+
+ bufsize = count[0]*count[1]*count[2];
+ buf = (int*) malloc(bufsize * sizeof(int));
+ for (i=0; i<bufsize; i++) buf[i] = rank*100 + i;
+
+ err = ncmpi_put_vara_int_all(ncid, varid, start, count, buf);
+ ERR
+
+ /* now test nonblocking put */
+ /* rearrange buffer contents */
+ for (i=5; i<10; i++) buf[i] = rank*100 + i + 5;
+ for (i=10; i<15; i++) buf[i] = rank*100 + i - 5;
+
+ start[0] = NZ-1;
+ count[2] = 5;
+ err = ncmpi_iput_vara_int(ncid, varid, start, count, buf, &req[0]);
+ ERR
+
+ start[2] += 5;
+ count[1] = 1;
+ err = ncmpi_iput_vara_int(ncid, varid, start, count, buf+10, &req[1]);
+ ERR
+
+ start[1]++;
+ err = ncmpi_iput_vara_int(ncid, varid, start, count, buf+15, &req[2]);
+ ERR
+
+ err = ncmpi_wait_all(ncid, 3, req, st);
+ ERR
+
+ err = ncmpi_close(ncid);
+ ERR
+
+ /* open the same file and read back for validation */
+ err = ncmpi_open(MPI_COMM_WORLD, filename, NC_NOWRITE, MPI_INFO_NULL,
+ &ncid); ERR
+
+ err = ncmpi_inq_varid(ncid, "var", &varid); ERR
+
+ /* initialize the contents of the array to a different value */
+ for (i=0; i<bufsize; i++) buf[i] = -1;
+
+ /* read back subarray written by the process (rank+1)%nprocs */
+ start[0] = 1;
+ start[1] = NY - 2;
+ start[2] = TWO_G + ((rank == nprocs - 1) ? 0 : 10 * (rank + 1));
+ count[0] = 1;
+ count[1] = 2;
+ count[2] = 10;
+
+ err = ncmpi_get_vara_int_all(ncid, varid, start, count, buf); ERR
+
+ /* check if the contents of buf are expected */
+ for (i=0; i<bufsize; i++) {
+ int expected = (rank == nprocs - 1) ? i : (rank+1)*100 + i;
+ if (buf[i] != expected) {
+ printf("%d (at line %d): Unexpected read buf[%d]=%d, should be %d\n",
+ rank, __LINE__, i, buf[i], expected);
+ nerrs++;
+ }
+ }
+
+ for (i=0; i<bufsize; i++) buf[i] = -1;
+
+ start[0] = NZ-1;
+ err = ncmpi_get_vara_int_all(ncid, varid, start, count, buf); ERR
+
+ /* check if the contents of buf are expected */
+ for (i=0; i<bufsize; i++) {
+ int expected = (rank == nprocs - 1) ? i : (rank+1)*100 + i;
+ if (buf[i] != expected) {
+ printf("%d (at line %d): Unexpected read buf[%d]=%d, should be %d\n",
+ rank, __LINE__, i, buf[i], expected);
+ nerrs++;
+ }
+ }
+
+ err = ncmpi_close(ncid); ERR
+
+ /* MPI file open the same file and read back for validation */
+ err = MPI_File_open(MPI_COMM_WORLD, filename, MPI_MODE_RDONLY, MPI_INFO_NULL, &fh);
+ if (err != MPI_SUCCESS) {
+ int errorStringLen;
+ char errorString[MPI_MAX_ERROR_STRING];
+ MPI_Error_string(err, errorString, &errorStringLen);
+ printf("MPI error MPI_File_open : %s\n", errorString);
+ }
+
+ /* initialize the contents of the array to a different value */
+ for (i=0; i<bufsize; i++) buf[i] = -1;
+
+ /* read back subarray written by the process (rank+1)%nprocs */
+ start[0] = 1;
+ start[1] = NY - 2;
+ start[2] = TWO_G + ((rank == nprocs - 1) ? 0 : 10 * (rank + 1));
+ count[0] = 1;
+ count[1] = 2;
+ count[2] = 10;
+
+ buf_ptr = buf;
+ for (i=0; i<count[0]; i++) {
+ for (j=0; j<count[1]; j++) {
+ offset = var_offset + ((start[0] + i) * NY * NX + (start[1] + j) * NX + start[2]) * sizeof(int);
+ MPI_File_read_at(fh, offset, buf_ptr, count[2], MPI_INT, &status);
+#ifndef WORDS_BIGENDIAN
+ swapn(buf_ptr, count[2]);
+#endif
+ buf_ptr += count[2];
+ }
+ }
+
+ /* check if the contents of buf are expected */
+ for (i=0; i<bufsize; i++) {
+ int expected = (rank == nprocs - 1) ? i : (rank+1)*100 + i;
+ if (buf[i] != expected) {
+ printf("%d (at line %d): Unexpected read buf[%d]=%d, should be %d\n",
+ rank, __LINE__, i, buf[i], expected);
+ nerrs++;
+ }
+ }
+
+ for (i=0; i<bufsize; i++) buf[i] = -1;
+
+ start[0] = NZ-1;
+
+ buf_ptr = buf;
+ for (i=0; i<count[0]; i++) {
+ for (j=0; j<count[1]; j++) {
+ offset = var_offset + ((start[0] + i) * NY * NX + (start[1] + j) * NX + start[2]) * sizeof(int);
+ MPI_File_read_at(fh, offset, buf_ptr, count[2], MPI_INT, &status);
+#ifndef WORDS_BIGENDIAN
+ swapn(buf_ptr, count[2]);
+#endif
+ buf_ptr += count[2];
+ }
+ }
+
+ /* check if the contents of buf are expected */
+ for (i=0; i<bufsize; i++) {
+ int expected = (rank == nprocs - 1) ? i : (rank+1)*100 + i;
+ if (buf[i] != expected) {
+ printf("%d (at line %d): Unexpected read buf[%d]=%d, should be %d\n",
+ rank, __LINE__, i, buf[i], expected);
+ nerrs++;
+ }
+ }
+
+ MPI_File_close(&fh);
+
+ free(buf);
+
+ /* check if PnetCDF freed all internal malloc */
+ MPI_Offset malloc_size, sum_size;
+ err = ncmpi_inq_malloc_size(&malloc_size);
+ if (err == NC_NOERR) {
+ MPI_Reduce(&malloc_size, &sum_size, 1, MPI_OFFSET, MPI_SUM, 0, MPI_COMM_WORLD);
+ if (rank == 0 && sum_size > 0)
+ printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n",
+ sum_size);
+ }
+
+ MPI_Allreduce(MPI_IN_PLACE, &nerrs, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
+ if (rank == 0) {
+ if (nerrs) printf(FAIL_STR,nerrs);
+ else printf(PASS_STR);
+ }
+
+ MPI_Finalize();
+ return 0;
+}
+
diff --git a/test/nc_test/Makefile.in b/test/nc_test/Makefile.in
new file mode 100644
index 0000000..3940659
--- /dev/null
+++ b/test/nc_test/Makefile.in
@@ -0,0 +1,138 @@
+#
+# Copyright (C) 2003, Northwestern University and Argonne National Laboratory
+# See COPYRIGHT notice in top-level directory.
+#
+# $Id: Makefile.in 2294 2016-01-06 20:10:13Z wkliao $
+#
+# @configure_input@
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+include ../../macros.make
+
+INCLUDES = -I../../src/lib -I$(srcdir) -I$(srcdir)/../common
+LDFLAGS := -L../common $(LDFLAGS)
+LIBS := $(LIBRARY) -ltestutils $(LIBS) -lm @LCOV_LIB@
+ifeq (@PNC_DEBUG@, yes)
+CPPFLAGS := $(CPPFLAGS) -DPNC_DEBUG
+endif
+
+SRCS = test_read.c \
+ test_write.c \
+ error.c \
+ util.c
+
+PROG_SRCS = nc_test.c \
+ t_nc.c \
+ tst_misc.c \
+ tst_norm.c \
+ tst_small.c \
+ tst_names.c \
+ tst_atts3.c \
+ tst_atts.c \
+ tst_nofill.c
+
+M4_SRCS = test_get.m4 \
+ test_put.m4 \
+ test_iget.m4 \
+ test_iput.m4
+
+HEADERS = tests.h \
+ error.h
+
+OBJS = $(SRCS:.c=.o) $(M4_SRCS:.m4=.o)
+
+PROGS = $(PROG_SRCS:.c=)
+
+GARBAGE = $(PROGS) $(M4_SRCS:.m4=.c) \
+ test.nc testfile.nc scratch.nc testfile.nc.2 \
+ testfile.nc.nofill testfile.nc.fill
+
+PACKING_LIST = $(SRCS) $(M4_SRCS) $(HEADERS) $(PROG_SRCS) \
+ Makefile.in depend README
+
+all: $(PROGS)
+
+$(OBJS): $(srcdir)/../common/testutils.h
+
+$(PROG_SRCS:.c=.o): $(srcdir)/../common/testutils.h
+
+$(PROGS): ../common/libtestutils.a
+
+../common/libtestutils.a:
+ set -e; cd ../common && $(MAKE) $(MFLAGS) all
+
+nc_test: nc_test.o $(OBJS) $(LIBRARY)
+ $(LINK.c) $< $(OBJS) $(LDFLAGS) $(LIBS)
+
+t_nc: t_nc.o $(LIBRARY)
+ $(LINK.c) $< $(LDFLAGS) $(LIBS)
+
+tst_misc: tst_misc.o $(LIBRARY)
+ $(LINK.c) $< $(LDFLAGS) $(LIBS)
+
+tst_norm: tst_norm.o $(LIBRARY)
+ $(LINK.c) $< $(LDFLAGS) $(LIBS)
+
+tst_small: tst_small.o $(LIBRARY)
+ $(LINK.c) $< $(LDFLAGS) $(LIBS)
+
+tst_names: tst_names.o $(LIBRARY)
+ $(LINK.c) $< $(LDFLAGS) $(LIBS)
+
+tst_atts3: tst_atts3.o $(LIBRARY)
+ $(LINK.c) $< $(LDFLAGS) $(LIBS)
+
+tst_atts: tst_atts.o $(LIBRARY)
+ $(LINK.c) $< $(LDFLAGS) $(LIBS)
+
+tst_nofill: tst_nofill.o $(LIBRARY)
+ $(LINK.c) $< $(LDFLAGS) $(LIBS)
+
+# This simple testing target ensures that the test files are present
+check testing: all
+ $(RM) -f $(TEST_OUTDIR)/scratch.nc
+ $(RM) -f $(TEST_OUTDIR)/testfile.nc
+ $(RM) -f $(TEST_OUTDIR)/tooth-fairy.nc
+ $(TEST_SEQRUN) ./nc_test -c -d $(TEST_OUTDIR)
+ $(TEST_SEQRUN) ./nc_test -d $(TEST_OUTDIR)
+ $(TEST_SEQRUN) ./nc_test -c -2 -d $(TEST_OUTDIR)
+ $(TEST_SEQRUN) ./nc_test -2 -d $(TEST_OUTDIR)
+ $(TEST_SEQRUN) ./nc_test -c -5 -d $(TEST_OUTDIR)
+ $(TEST_SEQRUN) ./nc_test -5 -d $(TEST_OUTDIR)
+ $(TEST_SEQRUN) ./t_nc $(TEST_OUTDIR)/testfile.nc
+ $(TEST_SEQRUN) ./tst_misc $(TEST_OUTDIR)/testfile.nc
+ $(TEST_SEQRUN) ./tst_norm $(TEST_OUTDIR)/testfile.nc
+ $(TEST_SEQRUN) ./tst_small $(TEST_OUTDIR)/testfile.nc
+ $(TEST_SEQRUN) ./tst_names $(TEST_OUTDIR)/testfile.nc
+ $(TEST_SEQRUN) ./tst_atts3 $(TEST_OUTDIR)/testfile.nc
+ $(TEST_SEQRUN) ./tst_atts $(TEST_OUTDIR)/testfile.nc
+ $(TEST_SEQRUN) ./tst_nofill $(TEST_OUTDIR)/testfile.nc
+
+verbose_testing: all
+ $(RM) -f $(TEST_OUTDIR)/scratch.nc
+ $(RM) -f $(TEST_OUTDIR)/testfile.nc
+ $(RM) -f $(TEST_OUTDIR)/tooth-fairy.nc
+ $(TEST_SEQRUN) ./nc_test -c -v -d $(TEST_OUTDIR)
+ $(TEST_SEQRUN) ./nc_test -v -d $(TEST_OUTDIR)
+ $(TEST_SEQRUN) ./nc_test -c -v -2 -d $(TEST_OUTDIR)
+ $(TEST_SEQRUN) ./nc_test -v -2 -d $(TEST_OUTDIR)
+ $(TEST_SEQRUN) ./nc_test -c -v -5 -d $(TEST_OUTDIR)
+ $(TEST_SEQRUN) ./nc_test -v -5 -d $(TEST_OUTDIR)
+ $(TEST_SEQRUN) ./t_nc $(TEST_OUTDIR)/testfile.nc
+ $(TEST_SEQRUN) ./tst_misc $(TEST_OUTDIR)/testfile.nc
+ $(TEST_SEQRUN) ./tst_norm $(TEST_OUTDIR)/testfile.nc
+ $(TEST_SEQRUN) ./tst_small $(TEST_OUTDIR)/testfile.nc
+ $(TEST_SEQRUN) ./tst_names $(TEST_OUTDIR)/testfile.nc
+ $(TEST_SEQRUN) ./tst_atts3 $(TEST_OUTDIR)/testfile.nc
+ $(TEST_SEQRUN) ./tst_atts $(TEST_OUTDIR)/testfile.nc
+ $(TEST_SEQRUN) ./tst_nofill $(TEST_OUTDIR)/testfile.nc
+
+ptest ptests ptest2 ptest4 ptest6 ptest8 ptest10:
+
+include $(srcdir)/../../rules.make
+include $(srcdir)/depend
+
+$(LIBRARY): ;
+
diff --git a/test/nc_test/README b/test/nc_test/README
new file mode 100644
index 0000000..95d2f43
--- /dev/null
+++ b/test/nc_test/README
@@ -0,0 +1,9 @@
+This test is ported from Unidata netCDF-3.5 to test the functionality
+of the PnetCDF API C interface particularly on a single processor.
+
+The typical way to run the test includes two steps:
+
+ (1) create test.nc by "<mpirun -np 1> ./nc_test -c"
+ (2) run the test by "<mpirun -np 1> ./nc_test -v"
+
+
diff --git a/test/nc_test/depend b/test/nc_test/depend
new file mode 100644
index 0000000..a29bc04
--- /dev/null
+++ b/test/nc_test/depend
@@ -0,0 +1,41 @@
+error.o: error.c
+nc_test.o: ../../src/lib/pnetcdf.h
+nc_test.o: error.h
+nc_test.o: nc_test.c
+nc_test.o: tests.h
+test_get.o: ../../src/lib/pnetcdf.h
+test_get.o: error.h
+test_get.o: test_get.c
+test_get.o: tests.h
+test_put.o: ../../src/lib/pnetcdf.h
+test_put.o: error.h
+test_put.o: test_put.c
+test_put.o: tests.h
+test_iget.o: ../../src/lib/pnetcdf.h
+test_iget.o: error.h
+test_iget.o: test_iget.c
+test_iget.o: tests.h
+test_iput.o: ../../src/lib/pnetcdf.h
+test_iput.o: error.h
+test_iput.o: test_iput.c
+test_iput.o: tests.h
+test_read.o: ../../src/lib/pnetcdf.h
+test_read.o: error.h
+test_read.o: test_read.c
+test_read.o: tests.h
+test_write.o: ../../src/lib/pnetcdf.h
+test_write.o: error.h
+test_write.o: test_write.c
+test_write.o: tests.h
+util.o: ../../src/lib/pnetcdf.h
+util.o: error.h
+util.o: tests.h
+util.o: util.c
+t_nc.o: t_nc.c
+tst_misc.o: tst_misc.c
+tst_norm.o: tst_norm.c
+tst_small.o: tst_small.c
+tst_names.o: tst_names.c
+tst_atts3.o: tst_atts3.c
+tst_atts.o: tst_atts.c
+tst_nofill.o: tst_nofill.c
diff --git a/test/nc_test/error.c b/test/nc_test/error.c
new file mode 100644
index 0000000..5bad4d8
--- /dev/null
+++ b/test/nc_test/error.c
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2003, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ *
+ * $Id: error.c 1468 2013-10-26 16:53:18Z wkliao $
+ */
+
+#include <stddef.h> /* because gcc 2.7.2.2 doesn't define size_t */
+ /* in <stdio.h> and it cannot hurt */
+#include <stdio.h>
+#include <stdarg.h>
+
+#include <mpi.h>
+
+extern int nfails; /* number of failures in specific test */
+extern int max_nmpt; /* max. number of messages per test */
+
+/* Prototypes */
+void error(const char *fmt, ...);
+void print(const char *fmt, ...);
+int ifFail(const int expr, const int line, const char *file);
+void print_n_size_t(size_t nelems, const MPI_Offset *array);
+
+/*
+ * Use for logging error conditions
+ */
+void
+error(const char *fmt, ...)
+{
+ va_list args ;
+
+ va_start(args, fmt) ;
+ if (nfails <= max_nmpt)
+ (void) vfprintf(stderr,fmt,args) ;
+ va_end(args) ;
+}
+
+/*
+ * Use for general printing (other than error conditions)
+ * This also currently goes to stderr, but this could change
+ */
+void
+print(const char *fmt, ...)
+{
+ va_list args ;
+
+ va_start(args, fmt) ;
+ (void) vfprintf(stderr,fmt,args) ;
+ va_end(args) ;
+}
+
+/*
+ * Called by macro IF
+ */
+int
+ifFail(const int expr, const int line, const char *file)
+{
+ if (expr) {
+ ++nfails;
+ error("\n\tFAILURE at line %d of %s: ", line, file);
+ }
+ return expr;
+}
+
+/* TODO:
+ * This diagnostic doesn't fit very well with the diagnostic message
+ * "architecture" of this program.
+ */
+void
+print_n_size_t(size_t nelems, const MPI_Offset *array)
+{
+ fprintf(stderr, "[");
+ while(nelems-- > 0)
+ {
+ fprintf(stderr, "%ld", (long)*array++);
+ if(nelems > 0)
+ fprintf(stderr, " ");
+ }
+ fprintf(stderr, "]");
+}
diff --git a/test/nc_test/error.h b/test/nc_test/error.h
new file mode 100644
index 0000000..47e13b3
--- /dev/null
+++ b/test/nc_test/error.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2003, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ */
+/* $Id: error.h 1468 2013-10-26 16:53:18Z wkliao $ */
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Print error message to stderr, don't exit */
+extern void error (const char *fmt, ...)
+#ifdef _GNUC_
+__attribute__ ((format (printf, 1, 2)))
+#endif
+;
+
+
+void print(const char *fmt, ...)
+#ifdef _GNUC_
+__attribute__ ((format (printf, 1, 2)))
+#endif
+;
+
+
+extern int ifFail(const int expr, const int line, const char *file);
+
+extern void
+print_n_size_t(size_t nelems, const MPI_Offset *array);
+
+#ifdef __cplusplus
+}
+#endif
+
+#define IF(EXPR) if (ifFail(EXPR, __LINE__, __FILE__))
+#define ELSE_NOK else {nok++;}
diff --git a/test/nc_test/nc_test.c b/test/nc_test/nc_test.c
new file mode 100644
index 0000000..a88bec5
--- /dev/null
+++ b/test/nc_test/nc_test.c
@@ -0,0 +1,549 @@
+/*
+ * Copyright (C) 2003, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ *
+ * $Id: nc_test.c 2302 2016-01-10 20:33:45Z wkliao $
+ */
+
+#include <unistd.h>
+
+int cdf_format; /* 1: CDF-1, 2: CDF-2 5: CDF-5 */
+int extra_flags; /* if using CDF-2 format, will be set to NC_64BIT_OFFSET
+ if using CDF-5 format, will be set to NC_64BIT_DATA */
+int numGatts; /* number of global attributes */
+int numVars; /* number of variables */
+int numTypes; /* number of netCDF data types to test */
+
+#include "tests.h"
+
+/*
+ * Test driver for netCDF-3 interface. This program performs tests against
+ * the netCDF-3 specification for all user-level functions in an
+ * implementation of the netCDF library.
+ *
+ * Unless invoked with "-r" (read_only) option, must be invoked from a
+ * directory in which the invoker has write permission.
+ *
+ * Files:
+ * The read-only tests read files:
+ * test.nc (see below)
+ * test_get.c (used merely as an example of a non-netCDF file)
+ *
+ * The write tests
+ * read test.nc (see below)
+ * write scratch.nc (deleted after each test)
+ *
+ * The file test.nc is created by running nc_test with the -c (create) option.
+ * It is described by the following global variables.
+ */
+
+
+/*
+ * global variables (defined by function init_gvars) describing file test.nc
+ */
+char dim_name[NDIMS][3];
+MPI_Offset dim_len[NDIMS];
+char var_name[NVARS][2+MAX_RANK];
+nc_type var_type[NVARS];
+size_t var_rank[NVARS];
+int var_dimid[NVARS][MAX_RANK];
+MPI_Offset var_shape[NVARS][MAX_RANK];
+size_t var_nels[NVARS];
+size_t var_natts[NVARS];
+char att_name[NVARS][MAX_NATTS][2];
+char gatt_name[NGATTS][3];
+nc_type att_type[NVARS][NGATTS];
+nc_type gatt_type[NGATTS];
+size_t att_len[NVARS][MAX_NATTS];
+size_t gatt_len[NGATTS];
+
+/*
+ * command-line options
+ */
+static int create_file; /* if 1, create file test.nc */
+int read_only; /* if 1, don't try to change files */
+int verbose; /* if 1, print details of tests */
+int max_nmpt; /* max. number of messages per test */
+
+/*
+ * Misc. global variables
+ */
+int nfails; /* number of failures in specific test */
+char testfile[128];
+char scratch[128];
+MPI_Comm comm = MPI_COMM_WORLD; /* mpi communicator for parallel-netcdf */
+MPI_Info info;
+
+static void
+usage(char *progname)
+{
+ error("%s [-c | -hrv -n <MAX_NMPT>]\n", progname);
+ error(" [-h] Print help\n" );
+ error(" [-c] Create file test.nc (Do not do tests)\n" );
+ error(" [-r] Just do read-only tests\n" );
+ error(" [-v] Verbose mode\n" );
+ error(" [-2] (with -c) create file with CDF-2 format\n" );
+ error(" [-n <MAX_NMPT>] max. number of messages per test (Default: 8)\n");
+ error(" [-d directory] directory for storing input/output files\n");
+}
+
+#define NC_TEST(func) { \
+ char func_name[64]; \
+ int noks; \
+ nfails = 0; \
+ sprintf(func_name, "test_%s",#func); \
+ noks = test_ ## func(); \
+ nfailsTotal += nfails; \
+ if (verbose && nfails == 0) { \
+ if (verbose) printf( "*** Testing %-30s ... ",func_name); \
+ if (noks > 0) \
+ printf("%4d good comparisons. ok\n", noks); \
+ else \
+ printf("\n"); \
+ } \
+ else if (nfails > 0) { \
+ if (verbose) print( "*** Testing %-30s ... ",func_name); \
+ print("\n\t### %d FAILURES TESTING %s! Stop ... ###\n", \
+ nfails,func_name); \
+ goto fn_exit; \
+ } \
+}
+
+#if 1 /* both CRAY MPP and OSF/1 Alpha systems need this */
+#include <signal.h>
+#endif /* T90 */
+
+int
+main(int argc, char *argv[])
+{
+ extern char *optarg;
+ int c;
+ int nfailsTotal = 0; /* total number of failures */
+
+#if 1 /* both CRAY MPP and OSF/1 Alpha systems need this */
+ /*
+ * Some of the extreme test assignments in this program trigger
+ * floating point exceptions on CRAY T90
+ */
+ (void) signal(SIGFPE, SIG_IGN);
+#endif
+
+ MPI_Init(&argc, &argv);
+
+ cdf_format = 1; /* 1: CDF-1, 2: CDF-2 5: CDF-5 */
+ extra_flags = 0; /* NC_64BIT_OFFSET or NC_64BIT_DATA */
+ create_file = 0; /* file test.nc will normally already exist */
+ read_only = 0; /* assume may write in test dir as default */
+ verbose = 0;
+ max_nmpt = 8;
+ strcpy(testfile, "test.nc"); /* read-only testfile */
+ strcpy(scratch, "scratch.nc"); /* writable scratch file */
+
+ while ((c = getopt(argc, argv, "c25hrvn:d:")) != EOF)
+ switch(c) {
+ case 'c': /* Create file test.nc */
+ create_file = 1;
+ break;
+ case 'r': /* just perform read-only tests */
+ read_only = 1;
+ break;
+ case 'v': /* verbose mode */
+ verbose = 1;
+ break;
+ case 'n': /* verbose mode */
+ max_nmpt = atoi(optarg);
+ break;
+ case '2':
+ cdf_format = 2;
+ extra_flags = NC_64BIT_OFFSET;
+ break;
+ case '5':
+ cdf_format = 5;
+ extra_flags = NC_64BIT_DATA;
+ case 'd':
+ sprintf(testfile, "%s/test.nc", optarg);
+ sprintf(scratch, "%s/scratch.nc", optarg);
+ break;
+ case 'h':
+ case '?':
+ usage(argv[0]);
+ return 1;
+ }
+
+ MPI_Info_create(&info);
+ /* MPI_Info_set(info, "romio_pvfs2_posix_write", "enable"); */
+
+ numGatts = 6;
+ numVars = 136;
+ numTypes = 6;
+ if (cdf_format == 5) {
+ numGatts = NGATTS;
+ numVars = NVARS;
+ numTypes = NTYPES;
+ }
+
+ /* Initialize global variables defining test file */
+ init_gvars();
+
+ if ( create_file ) {
+ write_file(testfile);
+ MPI_Info_free(&info);
+ MPI_Finalize();
+ return nfailsTotal > 0;
+ }
+
+ /* delete any existing scratch netCDF file */
+ if ( ! read_only ) {
+ if (access(scratch, F_OK) == 0)
+ unlink(scratch);
+ }
+
+ char cmd_str[256];
+ sprintf(cmd_str, "*** TESTING C %s for format CDF-%d ", argv[0], cdf_format);
+ printf("%-66s ------ ",cmd_str);
+
+ /* Test read-only functions, using pregenerated test-file */
+ NC_TEST(ncmpi_strerror);
+ NC_TEST(ncmpi_open);
+ NC_TEST(ncmpi_close);
+ NC_TEST(ncmpi_inq);
+ NC_TEST(ncmpi_inq_dimid);
+ NC_TEST(ncmpi_inq_dim);
+ NC_TEST(ncmpi_inq_dimlen);
+ NC_TEST(ncmpi_inq_dimname);
+ NC_TEST(ncmpi_inq_varid);
+ NC_TEST(ncmpi_inq_var);
+ NC_TEST(ncmpi_inq_natts);
+ NC_TEST(ncmpi_inq_ndims);
+ NC_TEST(ncmpi_inq_nvars);
+ NC_TEST(ncmpi_inq_unlimdim);
+ NC_TEST(ncmpi_inq_vardimid);
+ NC_TEST(ncmpi_inq_varname);
+ NC_TEST(ncmpi_inq_varnatts);
+ NC_TEST(ncmpi_inq_varndims);
+ NC_TEST(ncmpi_inq_vartype);
+ NC_TEST(ncmpi_get_var_text);
+ NC_TEST(ncmpi_get_var_schar);
+ NC_TEST(ncmpi_get_var_short);
+ NC_TEST(ncmpi_get_var_int);
+ NC_TEST(ncmpi_get_var_long);
+ NC_TEST(ncmpi_get_var_float);
+ NC_TEST(ncmpi_get_var_double);
+ NC_TEST(ncmpi_get_var_uchar);
+ NC_TEST(ncmpi_get_var_ushort);
+ NC_TEST(ncmpi_get_var_uint);
+ NC_TEST(ncmpi_get_var_longlong);
+ NC_TEST(ncmpi_get_var_ulonglong);
+ NC_TEST(ncmpi_get_var1_text);
+ NC_TEST(ncmpi_get_var1_schar);
+ NC_TEST(ncmpi_get_var1_short);
+ NC_TEST(ncmpi_get_var1_int);
+ NC_TEST(ncmpi_get_var1_long);
+ NC_TEST(ncmpi_get_var1_float);
+ NC_TEST(ncmpi_get_var1_double);
+ NC_TEST(ncmpi_get_var1_uchar);
+ NC_TEST(ncmpi_get_var1_ushort);
+ NC_TEST(ncmpi_get_var1_uint);
+ NC_TEST(ncmpi_get_var1_longlong);
+ NC_TEST(ncmpi_get_var1_ulonglong);
+ NC_TEST(ncmpi_get_var1);
+ NC_TEST(ncmpi_get_vara_text);
+ NC_TEST(ncmpi_get_vara_schar);
+ NC_TEST(ncmpi_get_vara_short);
+ NC_TEST(ncmpi_get_vara_int);
+ NC_TEST(ncmpi_get_vara_long);
+ NC_TEST(ncmpi_get_vara_float);
+ NC_TEST(ncmpi_get_vara_double);
+ NC_TEST(ncmpi_get_vara_uchar);
+ NC_TEST(ncmpi_get_vara_ushort);
+ NC_TEST(ncmpi_get_vara_uint);
+ NC_TEST(ncmpi_get_vara_longlong);
+ NC_TEST(ncmpi_get_vara_ulonglong);
+ NC_TEST(ncmpi_get_vara);
+ NC_TEST(ncmpi_get_vars_text);
+ NC_TEST(ncmpi_get_vars_schar);
+ NC_TEST(ncmpi_get_vars_short);
+ NC_TEST(ncmpi_get_vars_int);
+ NC_TEST(ncmpi_get_vars_long);
+ NC_TEST(ncmpi_get_vars_float);
+ NC_TEST(ncmpi_get_vars_double);
+ NC_TEST(ncmpi_get_vars_uchar);
+ NC_TEST(ncmpi_get_vars_ushort);
+ NC_TEST(ncmpi_get_vars_uint);
+ NC_TEST(ncmpi_get_vars_longlong);
+ NC_TEST(ncmpi_get_vars_ulonglong);
+ NC_TEST(ncmpi_get_vars);
+ NC_TEST(ncmpi_get_varm_text);
+ NC_TEST(ncmpi_get_varm_schar);
+ NC_TEST(ncmpi_get_varm_short);
+ NC_TEST(ncmpi_get_varm_int);
+ NC_TEST(ncmpi_get_varm_long);
+ NC_TEST(ncmpi_get_varm_float);
+ NC_TEST(ncmpi_get_varm_double);
+ NC_TEST(ncmpi_get_varm_uchar);
+ NC_TEST(ncmpi_get_varm_ushort);
+ NC_TEST(ncmpi_get_varm_uint);
+ NC_TEST(ncmpi_get_varm_longlong);
+ NC_TEST(ncmpi_get_varm_ulonglong);
+ NC_TEST(ncmpi_get_varm);
+ NC_TEST(ncmpi_get_att_text);
+ NC_TEST(ncmpi_get_att_schar);
+ NC_TEST(ncmpi_get_att_short);
+ NC_TEST(ncmpi_get_att_int);
+ NC_TEST(ncmpi_get_att_long);
+ NC_TEST(ncmpi_get_att_float);
+ NC_TEST(ncmpi_get_att_double);
+ NC_TEST(ncmpi_get_att_uchar);
+ NC_TEST(ncmpi_get_att_ushort);
+ NC_TEST(ncmpi_get_att_uint);
+ NC_TEST(ncmpi_get_att_longlong);
+ NC_TEST(ncmpi_get_att_ulonglong);
+ NC_TEST(ncmpi_get_att);
+ NC_TEST(ncmpi_inq_att);
+ NC_TEST(ncmpi_inq_attname);
+ NC_TEST(ncmpi_inq_attid);
+ NC_TEST(ncmpi_inq_attlen);
+ NC_TEST(ncmpi_inq_atttype);
+
+ /* nonblocking I/O */
+ NC_TEST(ncmpi_iget_var_text);
+ NC_TEST(ncmpi_iget_var_schar);
+ NC_TEST(ncmpi_iget_var_short);
+ NC_TEST(ncmpi_iget_var_int);
+ NC_TEST(ncmpi_iget_var_long);
+ NC_TEST(ncmpi_iget_var_float);
+ NC_TEST(ncmpi_iget_var_double);
+ NC_TEST(ncmpi_iget_var_uchar);
+ NC_TEST(ncmpi_iget_var_ushort);
+ NC_TEST(ncmpi_iget_var_uint);
+ NC_TEST(ncmpi_iget_var_longlong);
+ NC_TEST(ncmpi_iget_var_ulonglong);
+ NC_TEST(ncmpi_iget_var);
+ NC_TEST(ncmpi_iget_var1_text);
+ NC_TEST(ncmpi_iget_var1_schar);
+ NC_TEST(ncmpi_iget_var1_short);
+ NC_TEST(ncmpi_iget_var1_int);
+ NC_TEST(ncmpi_iget_var1_long);
+ NC_TEST(ncmpi_iget_var1_float);
+ NC_TEST(ncmpi_iget_var1_double);
+ NC_TEST(ncmpi_iget_var1_uchar);
+ NC_TEST(ncmpi_iget_var1_ushort);
+ NC_TEST(ncmpi_iget_var1_uint);
+ NC_TEST(ncmpi_iget_var1_longlong);
+ NC_TEST(ncmpi_iget_var1_ulonglong);
+ NC_TEST(ncmpi_iget_var1);
+ NC_TEST(ncmpi_iget_vara_text);
+ NC_TEST(ncmpi_iget_vara_schar);
+ NC_TEST(ncmpi_iget_vara_short);
+ NC_TEST(ncmpi_iget_vara_int);
+ NC_TEST(ncmpi_iget_vara_long);
+ NC_TEST(ncmpi_iget_vara_float);
+ NC_TEST(ncmpi_iget_vara_double);
+ NC_TEST(ncmpi_iget_vara_uchar);
+ NC_TEST(ncmpi_iget_vara_ushort);
+ NC_TEST(ncmpi_iget_vara_uint);
+ NC_TEST(ncmpi_iget_vara_longlong);
+ NC_TEST(ncmpi_iget_vara_ulonglong);
+ NC_TEST(ncmpi_iget_vara);
+ NC_TEST(ncmpi_iget_vars_text);
+ NC_TEST(ncmpi_iget_vars_schar);
+ NC_TEST(ncmpi_iget_vars_short);
+ NC_TEST(ncmpi_iget_vars_int);
+ NC_TEST(ncmpi_iget_vars_long);
+ NC_TEST(ncmpi_iget_vars_float);
+ NC_TEST(ncmpi_iget_vars_double);
+ NC_TEST(ncmpi_iget_vars_uchar);
+ NC_TEST(ncmpi_iget_vars_ushort);
+ NC_TEST(ncmpi_iget_vars_uint);
+ NC_TEST(ncmpi_iget_vars_longlong);
+ NC_TEST(ncmpi_iget_vars_ulonglong);
+ NC_TEST(ncmpi_iget_vars);
+ NC_TEST(ncmpi_iget_varm_text);
+ NC_TEST(ncmpi_iget_varm_schar);
+ NC_TEST(ncmpi_iget_varm_short);
+ NC_TEST(ncmpi_iget_varm_int);
+ NC_TEST(ncmpi_iget_varm_long);
+ NC_TEST(ncmpi_iget_varm_float);
+ NC_TEST(ncmpi_iget_varm_double);
+ NC_TEST(ncmpi_iget_varm_uchar);
+ NC_TEST(ncmpi_iget_varm_ushort);
+ NC_TEST(ncmpi_iget_varm_uint);
+ NC_TEST(ncmpi_iget_varm_longlong);
+ NC_TEST(ncmpi_iget_varm_ulonglong);
+ NC_TEST(ncmpi_iget_varm);
+
+ /* Test write functions */
+ if (! read_only) {
+ NC_TEST(ncmpi_create);
+ NC_TEST(ncmpi_redef);
+ /* NC_TEST(ncmpi_enddef); redundant, as it calls test_ncmpi_redef() */
+ NC_TEST(ncmpi_sync);
+ NC_TEST(ncmpi_abort);
+ NC_TEST(ncmpi_def_dim);
+ NC_TEST(ncmpi_rename_dim);
+ NC_TEST(ncmpi_def_var);
+ NC_TEST(ncmpi_put_var_text);
+ NC_TEST(ncmpi_put_var_schar);
+ NC_TEST(ncmpi_put_var_short);
+ NC_TEST(ncmpi_put_var_int);
+ NC_TEST(ncmpi_put_var_long);
+ NC_TEST(ncmpi_put_var_float);
+ NC_TEST(ncmpi_put_var_double);
+ NC_TEST(ncmpi_put_var_uchar);
+ NC_TEST(ncmpi_put_var_ushort);
+ NC_TEST(ncmpi_put_var_uint);
+ NC_TEST(ncmpi_put_var_longlong);
+ NC_TEST(ncmpi_put_var_ulonglong);
+ NC_TEST(ncmpi_put_var1_text);
+ NC_TEST(ncmpi_put_var1_schar);
+ NC_TEST(ncmpi_put_var1_short);
+ NC_TEST(ncmpi_put_var1_int);
+ NC_TEST(ncmpi_put_var1_long);
+ NC_TEST(ncmpi_put_var1_float);
+ NC_TEST(ncmpi_put_var1_double);
+ NC_TEST(ncmpi_put_var1_uchar);
+ NC_TEST(ncmpi_put_var1_ushort);
+ NC_TEST(ncmpi_put_var1_uint);
+ NC_TEST(ncmpi_put_var1_longlong);
+ NC_TEST(ncmpi_put_var1_ulonglong);
+ NC_TEST(ncmpi_put_var1);
+ NC_TEST(ncmpi_put_vara_text);
+ NC_TEST(ncmpi_put_vara_schar);
+ NC_TEST(ncmpi_put_vara_short);
+ NC_TEST(ncmpi_put_vara_int);
+ NC_TEST(ncmpi_put_vara_long);
+ NC_TEST(ncmpi_put_vara_float);
+ NC_TEST(ncmpi_put_vara_double);
+ NC_TEST(ncmpi_put_vara_uchar);
+ NC_TEST(ncmpi_put_vara_ushort);
+ NC_TEST(ncmpi_put_vara_uint);
+ NC_TEST(ncmpi_put_vara_longlong);
+ NC_TEST(ncmpi_put_vara_ulonglong);
+ NC_TEST(ncmpi_put_vara);
+ NC_TEST(ncmpi_put_vars_text);
+ NC_TEST(ncmpi_put_vars_schar);
+ NC_TEST(ncmpi_put_vars_short);
+ NC_TEST(ncmpi_put_vars_int);
+ NC_TEST(ncmpi_put_vars_long);
+ NC_TEST(ncmpi_put_vars_float);
+ NC_TEST(ncmpi_put_vars_double);
+ NC_TEST(ncmpi_put_vars_uchar);
+ NC_TEST(ncmpi_put_vars_ushort);
+ NC_TEST(ncmpi_put_vars_uint);
+ NC_TEST(ncmpi_put_vars_longlong);
+ NC_TEST(ncmpi_put_vars_ulonglong);
+ NC_TEST(ncmpi_put_vars);
+ NC_TEST(ncmpi_put_varm_text);
+ NC_TEST(ncmpi_put_varm_schar);
+ NC_TEST(ncmpi_put_varm_short);
+ NC_TEST(ncmpi_put_varm_int);
+ NC_TEST(ncmpi_put_varm_long);
+ NC_TEST(ncmpi_put_varm_float);
+ NC_TEST(ncmpi_put_varm_double);
+ NC_TEST(ncmpi_put_varm_uchar);
+ NC_TEST(ncmpi_put_varm_ushort);
+ NC_TEST(ncmpi_put_varm_uint);
+ NC_TEST(ncmpi_put_varm_longlong);
+ NC_TEST(ncmpi_put_varm_ulonglong);
+ NC_TEST(ncmpi_put_varm);
+ NC_TEST(ncmpi_rename_var);
+ NC_TEST(ncmpi_put_att_text);
+ NC_TEST(ncmpi_put_att_schar);
+ NC_TEST(ncmpi_put_att_short);
+ NC_TEST(ncmpi_put_att_int);
+ NC_TEST(ncmpi_put_att_long);
+ NC_TEST(ncmpi_put_att_float);
+ NC_TEST(ncmpi_put_att_double);
+ NC_TEST(ncmpi_put_att_uchar);
+ NC_TEST(ncmpi_put_att_ushort);
+ NC_TEST(ncmpi_put_att_uint);
+ NC_TEST(ncmpi_put_att_longlong);
+ NC_TEST(ncmpi_put_att_ulonglong);
+ NC_TEST(ncmpi_put_att);
+ NC_TEST(ncmpi_copy_att);
+ NC_TEST(ncmpi_rename_att);
+ NC_TEST(ncmpi_del_att);
+ NC_TEST(ncmpi_set_fill);
+ NC_TEST(ncmpi_delete);
+
+ /* test nonblocking APIs */
+ NC_TEST(ncmpi_iput_var_text);
+ NC_TEST(ncmpi_iput_var_schar);
+ NC_TEST(ncmpi_iput_var_short);
+ NC_TEST(ncmpi_iput_var_int);
+ NC_TEST(ncmpi_iput_var_long);
+ NC_TEST(ncmpi_iput_var_float);
+ NC_TEST(ncmpi_iput_var_double);
+ NC_TEST(ncmpi_iput_var_uchar);
+ NC_TEST(ncmpi_iput_var_ushort);
+ NC_TEST(ncmpi_iput_var_uint);
+ NC_TEST(ncmpi_iput_var_longlong);
+ NC_TEST(ncmpi_iput_var_ulonglong);
+ NC_TEST(ncmpi_iput_var);
+ NC_TEST(ncmpi_iput_var1_text);
+ NC_TEST(ncmpi_iput_var1_schar);
+ NC_TEST(ncmpi_iput_var1_short);
+ NC_TEST(ncmpi_iput_var1_int);
+ NC_TEST(ncmpi_iput_var1_long);
+ NC_TEST(ncmpi_iput_var1_float);
+ NC_TEST(ncmpi_iput_var1_double);
+ NC_TEST(ncmpi_iput_var1_uchar);
+ NC_TEST(ncmpi_iput_var1_ushort);
+ NC_TEST(ncmpi_iput_var1_uint);
+ NC_TEST(ncmpi_iput_var1_longlong);
+ NC_TEST(ncmpi_iput_var1_ulonglong);
+ NC_TEST(ncmpi_iput_var1);
+ NC_TEST(ncmpi_iput_vara_text);
+ NC_TEST(ncmpi_iput_vara_schar);
+ NC_TEST(ncmpi_iput_vara_short);
+ NC_TEST(ncmpi_iput_vara_int);
+ NC_TEST(ncmpi_iput_vara_long);
+ NC_TEST(ncmpi_iput_vara_float);
+ NC_TEST(ncmpi_iput_vara_double);
+ NC_TEST(ncmpi_iput_vara_uchar);
+ NC_TEST(ncmpi_iput_vara_ushort);
+ NC_TEST(ncmpi_iput_vara_uint);
+ NC_TEST(ncmpi_iput_vara_longlong);
+ NC_TEST(ncmpi_iput_vara_ulonglong);
+ NC_TEST(ncmpi_iput_vara);
+ NC_TEST(ncmpi_iput_vars_text);
+ NC_TEST(ncmpi_iput_vars_schar);
+ NC_TEST(ncmpi_iput_vars_short);
+ NC_TEST(ncmpi_iput_vars_int);
+ NC_TEST(ncmpi_iput_vars_long);
+ NC_TEST(ncmpi_iput_vars_float);
+ NC_TEST(ncmpi_iput_vars_double);
+ NC_TEST(ncmpi_iput_vars_uchar);
+ NC_TEST(ncmpi_iput_vars_ushort);
+ NC_TEST(ncmpi_iput_vars_uint);
+ NC_TEST(ncmpi_iput_vars_longlong);
+ NC_TEST(ncmpi_iput_vars_ulonglong);
+ NC_TEST(ncmpi_iput_vars);
+ NC_TEST(ncmpi_iput_varm_text);
+ NC_TEST(ncmpi_iput_varm_schar);
+ NC_TEST(ncmpi_iput_varm_short);
+ NC_TEST(ncmpi_iput_varm_int);
+ NC_TEST(ncmpi_iput_varm_long);
+ NC_TEST(ncmpi_iput_varm_float);
+ NC_TEST(ncmpi_iput_varm_double);
+ NC_TEST(ncmpi_iput_varm_uchar);
+ NC_TEST(ncmpi_iput_varm_ushort);
+ NC_TEST(ncmpi_iput_varm_uint);
+ NC_TEST(ncmpi_iput_varm_longlong);
+ NC_TEST(ncmpi_iput_varm_ulonglong);
+ NC_TEST(ncmpi_iput_varm);
+ }
+
+fn_exit:
+ MPI_Info_free(&info);
+
+ if (nfailsTotal == 0) {
+ printf(PASS_STR);
+ }
+ else {
+ print("\n%s: expects 0 failures ... ",argv[0]);
+ printf(FAIL_STR, nfailsTotal);
+ }
+ MPI_Finalize();
+ return nfailsTotal > 0;
+}
diff --git a/test/nc_test/t_nc.c b/test/nc_test/t_nc.c
new file mode 100644
index 0000000..fddcdfe
--- /dev/null
+++ b/test/nc_test/t_nc.c
@@ -0,0 +1,664 @@
+/*
+ * Copyright (C) 2014, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ */
+/* $Id: t_nc.c 2219 2015-12-11 22:30:03Z wkliao $ */
+
+/* This program is based on the test program t_nc.c of the netCDF package */
+
+/* Copyright 1988-2010 University Corporation for Atmospheric Research
+ See netcdf/COPYRIGHT file for copying and redistribution
+ conditions.
+
+ Program to create a cdf, exercise all cdf functions. Creates cdf,
+ stuff it full of numbers, closes it. Then reopens it, and checks
+ for consistency. Leaves the file around afterwards.
+
+ Based on a program to test the nasa look-alike program, so not the
+ most appropropriate test. See ../nctest for a complete spec test.
+*/
+
+#define REDEF
+/* #define SYNCDEBUG */
+
+#undef NDEBUG /* always active assert() in this file */
+
+#include <stdio.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <mpi.h>
+#include <pnetcdf.h>
+
+#include <testutils.h>
+
+#define MAXSHORT 32767
+#define MAXINT 2147483647
+#define MAXBYTE 127
+
+
+#define NUM_DIMS 3
+#define DONT_CARE -1
+/* make these numbers big when you want to give this a real workout */
+#define NUM_RECS 8
+#define SIZE_1 7
+#define SIZE_2 8
+
+static struct {
+ int num_dims;
+ int num_vars;
+ int num_attrs;
+ int xtendim;
+} cdesc[1];
+
+static struct {
+ char mnem[NC_MAX_NAME];
+ nc_type type;
+ int ndims;
+ int dims[NC_MAX_VAR_DIMS];
+ int num_attrs;
+} vdesc[1];
+
+static struct {
+ char mnem[NC_MAX_NAME];
+ nc_type type;
+ MPI_Offset len;
+} adesc[1];
+
+union getret
+{
+ char by[8];
+ short sh[4];
+ int in[2];
+ float fl[2];
+ double dbl;
+};
+
+
+#define ERR {if (err != NC_NOERR) {printf("Error at %s line %d: %s\n",__func__,__LINE__,ncmpi_strerror(err)); return 1;}}
+
+static void
+chkgot(nc_type type, union getret got, double check)
+{
+ switch(type){
+ case NC_BYTE :
+ assert( (char)check == got.by[0] );
+ break;
+ case NC_CHAR : /* TODO */
+ assert( (char)check == got.by[0] );
+ break;
+ case NC_SHORT :
+ assert( (short)check == got.sh[0] );
+ break;
+ case NC_INT :
+ assert( (int)check == got.in[0] );
+ break;
+ case NC_FLOAT :
+ assert( (float)check == got.fl[0] );
+ break;
+ case NC_DOUBLE :
+ assert( check == got.dbl );
+ break;
+ default:
+ break;
+ }
+}
+
+
+static size_t num_dims = NUM_DIMS;
+static MPI_Offset sizes[] = { NC_UNLIMITED, SIZE_1 , SIZE_2 };
+static const char * const dim_names[] = { "record", "ixx", "iyy"};
+
+static int
+createtestdims(int cdfid, size_t num_dims, const MPI_Offset *sizes, const char * const dim_names[])
+{
+ int dimid, err;
+ while(num_dims-- != 0)
+ {
+ err = ncmpi_def_dim(cdfid, *dim_names++, *sizes, &dimid); ERR
+ sizes++;
+ }
+ return 0;
+}
+
+
+static int
+testdims(int cdfid, size_t num_dims, MPI_Offset *sizes, const char * const dim_names[])
+{
+ int ii, err;
+ MPI_Offset size;
+ char cp[NC_MAX_NAME];
+ for(ii=0; (size_t) ii < num_dims; ii++, sizes++)
+ {
+ err = ncmpi_inq_dim(cdfid, ii, cp, &size); ERR
+ if( size != *sizes)
+ (void) fprintf(stderr, "%d: %lu != %lu\n",
+ ii, (unsigned long)size, (unsigned long)*sizes);
+ if ( size != *sizes) return 1;
+ if ( strcmp(cp, *dim_names++) != 0) return 1;
+ }
+ return 0;
+}
+
+
+
+static const char * const reqattr[] = {
+ "UNITS",
+ "VALIDMIN",
+ "VALIDMAX",
+ "SCALEMIN",
+ "SCALEMAX",
+ "FIELDNAM",
+ _FillValue
+};
+#define NUM_RATTRS 6
+
+static struct tcdfvar {
+ const char *mnem;
+ nc_type type;
+ const char *fieldnam;
+ double validmin;
+ double validmax;
+ double scalemin;
+ double scalemax;
+ const char *units;
+ int ndims;
+ int dims[NUM_DIMS];
+} const testvars[] = {
+#define Byte_id 0
+ { "Byte", NC_BYTE, "Byte sized integer variable",
+ -MAXBYTE, MAXBYTE, -MAXBYTE, MAXBYTE , "ones",
+ 2, {0,1,DONT_CARE} },
+#define Char_id 1
+ { "Char", NC_CHAR, "char (string) variable",
+ DONT_CARE, DONT_CARE, DONT_CARE, DONT_CARE, "(unitless)",
+ 2, {0,2,DONT_CARE} },
+#define Short_id 2
+ { "Short", NC_SHORT, "Short variable",
+ -MAXSHORT, MAXSHORT, -MAXSHORT, MAXSHORT , "ones",
+ 2, {0, 2, DONT_CARE }},
+#define Long_id 3
+ { "Long", NC_INT, "Long Integer variable", /* 2.x backward strings */
+ -MAXINT, MAXINT, -MAXINT, MAXINT, "ones",
+ 2, {1, 2, DONT_CARE}},
+#define Float_id 4
+ { "Float", NC_FLOAT, "Single Precision Floating Point variable",
+ -MAXINT, MAXINT, -MAXINT, MAXINT, "flots",
+ 3, {0, 1, 2 }},
+#define Double_id 5
+ { "Double", NC_DOUBLE, "Double Precision Floating Point variable",
+ -MAXINT, MAXINT, -MAXINT, MAXINT, "dflots",
+ 3, {0, 1, 2 }},
+};
+#define NUM_TESTVARS 6
+
+static int
+createtestvars(int id, const struct tcdfvar *testvars, size_t count)
+{
+ int ii, err;
+ int varid;
+ const struct tcdfvar *vp = testvars;
+
+ for(ii = 0; (size_t) ii < count; ii++, vp++ )
+ {
+ err = ncmpi_def_var(id, vp->mnem, vp->type, vp->ndims, vp->dims, &varid); ERR
+
+ err = ncmpi_put_att_text(id,ii,reqattr[0],strlen(vp->units), vp->units); ERR
+ err = ncmpi_put_att_double(id,ii,reqattr[1],NC_DOUBLE,1, &vp->validmin); ERR
+ err = ncmpi_put_att_double(id,ii,reqattr[2],NC_DOUBLE,1, &vp->validmax); ERR
+ err = ncmpi_put_att_double(id,ii,reqattr[3],NC_DOUBLE,1, &vp->scalemin); ERR
+ err = ncmpi_put_att_double(id,ii,reqattr[4],NC_DOUBLE,1, &vp->scalemax); ERR
+ err = ncmpi_put_att_text(id,ii,reqattr[5],strlen(vp->fieldnam), vp->fieldnam); ERR
+ }
+ return 0;
+}
+
+/* static void */
+/* parray(const char *label, size_t count, const size_t array[]) */
+/* { */
+/* (void) fprintf(stdout, "%s", label); */
+/* (void) fputc('\t',stdout); */
+/* for(; count != 0; count--, array++) */
+/* (void) fprintf(stdout," %lu", (unsigned long) *array); */
+/* } */
+
+
+static int
+fill_seq(int id)
+{
+ int err;
+ float values[NUM_RECS * SIZE_1 * SIZE_2];
+ MPI_Offset vindices[NUM_DIMS];
+
+ {
+ size_t ii = 0;
+ for(; ii < sizeof(values)/sizeof(values[0]); ii++)
+ {
+ values[ii] = (float) ii;
+ }
+ }
+
+ /* zero the vindices */
+ {
+ MPI_Offset *cc = vindices;
+ while (cc < &vindices[num_dims])
+ *cc++ = 0;
+ }
+
+ sizes[0] = NUM_RECS;
+ err = ncmpi_put_vara_float(id, Float_id, vindices, sizes, values); ERR
+ return 0;
+}
+
+static int
+check_fill_seq(int id)
+{
+ MPI_Offset vindices[NUM_DIMS];
+ MPI_Offset *cc, *mm;
+ union getret got;
+ int ii = 0;
+ /*float val;*/
+
+ sizes[0] = NUM_RECS;
+ cc = vindices;
+ while (cc < &vindices[num_dims])
+ *cc++ = 0;
+
+ /* ripple counter */
+ cc = vindices;
+ mm = sizes;
+ while (*vindices < *sizes)
+ {
+ while (*cc < *mm)
+ {
+ if (mm == &sizes[num_dims - 1])
+ {
+ if(ncmpi_get_var1_float(id, Float_id, vindices, &got.fl[0]) == -1)
+ goto bad_ret;
+ /* val = (float) ii; */
+ /* if(val != got.fl[0]) */
+ /* { */
+ /* parray("indices", NUM_DIMS, vindices); */
+ /* (void) printf("\t%f != %f\n", val, got.fl[0]); */
+ /* } */
+ (*cc)++; ii++;
+ continue;
+ }
+ cc++;
+ mm++;
+ }
+ if(cc == vindices)
+ break;
+ *cc = 0;
+ cc--;
+ mm--;
+ (*cc)++;
+ }
+ return 0;
+bad_ret :
+ (void) printf("couldn't get a var in check_fill_seq() %d\n", ii);
+ return 1;
+}
+
+static MPI_Offset indices[][3] = {
+ {0, 1, 3},
+ {0, 3, 0},
+ {1, 2, 3},
+ {3, 2, 1},
+ {2, 1, 3},
+ {1, 0, 0},
+ {0, 0, 0},
+};
+
+static const char chs[] = {'A','B', ((char)0xff) };
+static const MPI_Offset s_start[] = {0,1};
+static const MPI_Offset s_edges[] = {NUM_RECS, SIZE_1 - 1};
+static char sentence[NUM_RECS* SIZE_1 -1] =
+ "The red death had long devastated the country.";
+static short shs[] = {97, 99};
+static int birthday = 82555;
+#define M_E 2.7182818284590452354
+static float e = (float) M_E;
+static double pinot = 3.25;
+static double zed = 0.0;
+
+
+/*ARGSUSED*/
+static
+int t_nc(char *filename, int cmode)
+{
+ int id, err;
+ char buf[256];
+#ifdef SYNCDEBUG
+ char *str = "one";
+#endif
+ int ii;
+ MPI_Offset ui;
+ const struct tcdfvar *tvp = testvars;
+ union getret got;
+ MPI_Offset align = 8192/32;
+
+ err = ncmpi_create(MPI_COMM_WORLD, filename,cmode, MPI_INFO_NULL, &id); ERR
+
+ err = ncmpi_put_att_text(id, NC_GLOBAL, "TITLE", 12, "another name"); ERR
+ err = ncmpi_get_att_text(id, NC_GLOBAL, "TITLE", buf); ERR
+/* (void) printf("title 1 \"%s\"\n", buf); */
+ err = ncmpi_put_att_text(id, NC_GLOBAL, "TITLE", strlen(filename), filename); ERR
+ err = ncmpi_get_att_text(id, NC_GLOBAL, "TITLE", buf); ERR
+ buf[strlen(filename)] = 0;
+/* (void) printf("title 2 \"%s\"\n", buf); */
+ assert(strcmp(filename, buf) == 0);
+
+ err = createtestdims(id, NUM_DIMS, sizes, dim_names); ERR
+ testdims(id, NUM_DIMS, sizes, dim_names);
+
+ err = createtestvars(id, testvars, NUM_TESTVARS); ERR
+
+ {
+ int ifill = -1; double dfill = -9999;
+ err = ncmpi_put_att_int(id, Long_id, _FillValue, NC_INT, 1, &ifill); ERR
+ err = ncmpi_put_att_double(id, Double_id, _FillValue, NC_DOUBLE, 1, &dfill); ERR
+ }
+
+#ifdef REDEF
+ err = ncmpi__enddef(id, 0, align, 0, 2*align); ERR
+ err = ncmpi_begin_indep_data(id); ERR
+ err = ncmpi_put_var1_int(id, Long_id, indices[3], &birthday); ERR
+ err = fill_seq(id); ERR
+ err = ncmpi_end_indep_data(id); ERR
+
+ err = ncmpi_redef(id); ERR
+/* err = ncmpi_rename_dim(id,2, "a long dim name"); ERR */
+#endif
+
+ err = ncmpi_rename_dim(id,1, "IXX"); ERR
+ err = ncmpi_inq_dim(id, 1, buf, &ui); ERR
+ /* (void) printf("dimrename: %s\n", buf); */
+ err = ncmpi_rename_dim(id,1, dim_names[1]); ERR
+
+#ifdef ATTRX
+ err = ncmpi_rename_att(id, 1, "UNITS", "units"); ERR
+ err = ncmpi_del_att(id, 4, "FIELDNAM"); ERR
+ err = ncmpi_del_att(id, 2, "SCALEMIN"); ERR
+ err = ncmpi_del_att(id, 2, "SCALEMAX"); ERR
+#endif /* ATTRX */
+
+ err = ncmpi__enddef(id, 0, align, 0, 2*align); ERR
+ err = ncmpi_begin_indep_data(id); ERR
+
+#ifndef REDEF
+ err = fill_seq(id); ERR
+ err = ncmpi_put_var1_int(id, Long_id, indices[3], &birthday); ERR
+#endif
+
+ err = ncmpi_put_vara_schar(id, Byte_id, s_start, s_edges, (signed char *)sentence); ERR
+ err = ncmpi_put_var1_schar(id, Byte_id, indices[6], (signed char *)(chs+1)); ERR
+ err = ncmpi_put_var1_schar(id, Byte_id, indices[5], (signed char *)chs); ERR
+
+ err = ncmpi_put_vara_text(id, Char_id, s_start, s_edges, sentence); ERR
+ err = ncmpi_put_var1_text(id, Char_id, indices[6], (chs+1)); ERR
+ err = ncmpi_put_var1_text(id, Char_id, indices[5], chs); ERR
+
+ err = ncmpi_put_var1_short(id, Short_id, indices[4], shs); ERR
+
+ err = ncmpi_put_var1_float(id, Float_id, indices[2], &e); ERR
+
+ err = ncmpi_put_var1_double(id, Double_id, indices[1], &zed); ERR
+ err = ncmpi_put_var1_double(id, Double_id, indices[0], &pinot); ERR
+
+#ifdef SYNCDEBUG
+ (void) printf("Hit Return to sync\n");
+ gets(str);
+ ncmpi_sync(id,0);
+ (void) printf("Sync done. Hit Return to continue\n");
+ gets(str);
+#endif /* SYNCDEBUG */
+
+ err = ncmpi_close(id); ERR
+
+
+/*
+ * read it
+ */
+ err = ncmpi_open(MPI_COMM_WORLD, filename,NC_NOWRITE, MPI_INFO_NULL, &id); ERR
+ err = ncmpi_begin_indep_data(id); ERR
+
+ /* NC */
+ /* (void) printf("NC "); */
+ err = ncmpi_inq(id, &(cdesc->num_dims), &(cdesc->num_vars), &(cdesc->num_attrs), &(cdesc->xtendim) ); ERR
+ assert((MPI_Offset) cdesc->num_dims == num_dims);
+ assert(cdesc->num_attrs == 1);
+ assert(cdesc->num_vars == NUM_TESTVARS);
+ /* (void) printf("done\n"); */
+
+ /* GATTR */
+ /* (void) printf("GATTR "); */
+
+ err = ncmpi_inq_attname(id, NC_GLOBAL, 0, adesc->mnem); ERR
+ assert(strcmp("TITLE",adesc->mnem) == 0);
+ err = ncmpi_inq_att(id, NC_GLOBAL, adesc->mnem, &(adesc->type), &(adesc->len)); ERR
+ assert( adesc->type == NC_CHAR );
+ assert( adesc->len == strlen(filename) );
+ err = ncmpi_get_att_text(id, NC_GLOBAL, "TITLE", buf); ERR
+ buf[adesc->len] = 0;
+ assert( strcmp(filename, buf) == 0);
+
+ /* VAR */
+ /* (void) printf("VAR "); */
+ assert( cdesc->num_vars == NUM_TESTVARS );
+
+ for(ii = 0; ii < cdesc->num_vars; ii++, tvp++ )
+ {
+ int jj;
+ err = ncmpi_inq_var(id, ii,
+ vdesc->mnem,
+ &(vdesc->type),
+ &(vdesc->ndims),
+ vdesc->dims,
+ &(vdesc->num_attrs)); ERR
+ if(strcmp(tvp->mnem , vdesc->mnem) != 0)
+ {
+ (void) printf("attr %d mnem mismatch %s, %s\n",
+ ii, tvp->mnem, vdesc->mnem);
+ continue;
+ }
+ if(tvp->type != vdesc->type)
+ {
+ (void) printf("attr %d type mismatch %d, %d\n",
+ ii, (int)tvp->type, (int)vdesc->type);
+ continue;
+ }
+ for(jj = 0; jj < vdesc->ndims; jj++ )
+ {
+ if(tvp->dims[jj] != vdesc->dims[jj] )
+ {
+ (void) printf(
+ "inconsistent dim[%d] for variable %d: %d != %d\n",
+ jj, ii, tvp->dims[jj], vdesc->dims[jj] );
+ continue;
+ }
+ }
+
+ /* VATTR */
+ /* (void) printf("VATTR\n"); */
+ for(jj=0; jj<vdesc->num_attrs; jj++ )
+ {
+ err = ncmpi_inq_attname(id, ii, jj, adesc->mnem); ERR
+ if( strcmp(adesc->mnem, reqattr[jj]) != 0 )
+ {
+ (void) printf("var %d attr %d mismatch %s != %s\n",
+ ii, jj, adesc->mnem, reqattr[jj] );
+ break;
+ }
+ }
+
+ if( ncmpi_inq_att(id, ii, reqattr[0], &(adesc->type), &(adesc->len))
+ != -1) {
+ assert( adesc->type == NC_CHAR );
+ assert( adesc->len == strlen(tvp->units) );
+ err = ncmpi_get_att_text(id,ii,reqattr[0],buf); ERR
+ buf[adesc->len] = 0;
+ assert( strcmp(tvp->units, buf) == 0);
+ }
+
+ if(
+ ncmpi_inq_att(id, ii, reqattr[1], &(adesc->type), &(adesc->len))
+ != -1)
+ {
+ assert( adesc->type == NC_DOUBLE );
+ assert( adesc->len == 1 );
+ err = ncmpi_get_att_double(id, ii, reqattr[1], &got.dbl); ERR
+ chkgot(adesc->type, got, tvp->validmin);
+ }
+
+ if(
+ ncmpi_inq_att(id, ii, reqattr[2], &(adesc->type), &(adesc->len))
+ != -1)
+ {
+ assert( adesc->type == NC_DOUBLE );
+ assert( adesc->len == 1 );
+ err = ncmpi_get_att_double(id, ii, reqattr[2], &got.dbl); ERR
+ chkgot(adesc->type, got, tvp->validmax);
+ }
+
+ if(
+ ncmpi_inq_att(id, ii, reqattr[3], &(adesc->type), &(adesc->len))
+ != -1)
+ {
+ assert( adesc->type == NC_DOUBLE );
+ assert( adesc->len ==1 );
+ err = ncmpi_get_att_double(id, ii, reqattr[3], &got.dbl); ERR
+ chkgot(adesc->type, got, tvp->scalemin);
+ }
+
+ if(
+ ncmpi_inq_att(id, ii, reqattr[4], &(adesc->type), &(adesc->len))
+ != -1)
+ {
+ assert( adesc->type == NC_DOUBLE );
+ assert( adesc->len == 1 );
+ err = ncmpi_get_att_double(id, ii, reqattr[4], &got.dbl); ERR
+ chkgot(adesc->type, got, tvp->scalemax);
+ }
+
+ if( ncmpi_inq_att(id, ii, reqattr[5], &(adesc->type), &(adesc->len)) == NC_NOERR)
+ {
+ assert( adesc->type == NC_CHAR );
+ assert( adesc->len == strlen(tvp->fieldnam) );
+ err = ncmpi_get_att_text(id,ii,reqattr[5],buf); ERR
+ buf[adesc->len] = 0;
+ assert( strcmp(tvp->fieldnam, buf) == 0);
+ }
+ }
+
+ /* (void) printf("fill_seq "); */
+ err = check_fill_seq(id); ERR
+ /* (void) printf("Done\n"); */
+
+ err = ncmpi_get_var1_double(id, Double_id, indices[0], &got.dbl); ERR
+ /* (void) printf("got val = %f\n", got.dbl ); */
+
+ err = ncmpi_get_var1_double(id, Double_id, indices[1], &got.dbl); ERR
+ /* (void) printf("got val = %f\n", got.dbl ); */
+
+ err = ncmpi_get_var1_float(id, Float_id, indices[2], &got.fl[0]); ERR
+ /* (void) printf("got val = %f\n", got.fl[0] ); */
+
+ err = ncmpi_get_var1_int(id, Long_id, indices[3], &got.in[0]); ERR
+ /* (void) printf("got val = %d\n", got.in[0] ); */
+
+ err = ncmpi_get_var1_short(id, Short_id, indices[4], &got.sh[0]); ERR
+ /* (void) printf("got val = %d\n", got.sh[0] ); */
+
+ err = ncmpi_get_var1_text(id, Char_id, indices[5], &got.by[0]); ERR
+ /* (void) printf("got NC_CHAR val = %c (0x%02x) \n", */
+ /* got.by[0] , got.by[0]); */
+
+ err = ncmpi_get_var1_text(id, Char_id, indices[6], &got.by[0]); ERR
+ /* (void) printf("got NC_CHAR val = %c (0x%02x) \n", */
+ /* got.by[0], got.by[0] ); */
+
+ (void) memset(buf,0,sizeof(buf));
+ err = ncmpi_get_vara_text(id, Char_id, s_start, s_edges, buf); ERR
+ /* (void) printf("got NC_CHAR val = \"%s\"\n", buf); */
+
+ err = ncmpi_get_var1_schar(id, Byte_id, indices[5], (signed char *)&got.by[0]); ERR
+ /* (void) printf("got val = %c (0x%02x) \n", got.by[0] , got.by[0]); */
+
+ err = ncmpi_get_var1_schar(id, Byte_id, indices[6], (signed char *)&got.by[0]); ERR
+ /* (void) printf("got val = %c (0x%02x) \n", got.by[0], got.by[0] ); */
+
+ (void) memset(buf,0,sizeof(buf));
+ err = ncmpi_get_vara_schar(id, Byte_id, s_start, s_edges, (signed char *)buf); ERR
+ /* (void) printf("got val = \"%s\"\n", buf); */
+
+ {
+ double dbuf[NUM_RECS * SIZE_1 * SIZE_2];
+ err = ncmpi_get_var_double(id, Float_id, dbuf); ERR
+
+ /* (void) printf("got vals = %f ... %f\n", dbuf[0], */
+ /* dbuf[NUM_RECS * SIZE_1 * SIZE_2 -1] ); */
+ }
+
+ err = ncmpi_close(id); ERR
+
+ return 0;
+}
+
+int main(int argc, char *argv[])
+{
+ char filename[256];
+ int rank, nprocs, cmode, err, nerrs=0;
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+
+ if (argc > 2) {
+ if (!rank) printf("Usage: %s [filename]\n",argv[0]);
+ MPI_Finalize();
+ return 0;
+ }
+ strcpy(filename, "testfile.nc");
+ if (argc == 2) strcpy(filename, argv[1]);
+ MPI_Bcast(filename, 256, MPI_CHAR, 0, MPI_COMM_WORLD);
+
+ if (rank == 0) {
+ char cmd_str[256];
+ sprintf(cmd_str, "*** TESTING C %s for emulating netCDF t_nc ", argv[0]);
+ printf("%-66s ------ ", cmd_str);
+ }
+
+ /* test CDF-1 format */
+ cmode = NC_CLOBBER;
+ nerrs += t_nc(filename, cmode);
+
+ /* test CDF-2 format */
+ cmode = NC_CLOBBER | NC_64BIT_OFFSET;
+ nerrs += t_nc(filename, cmode);
+
+ /* test CDF-5 format */
+ cmode = NC_CLOBBER | NC_64BIT_DATA;
+ nerrs += t_nc(filename, cmode);
+
+ /* check if PnetCDF freed all internal malloc */
+ MPI_Offset malloc_size, sum_size;
+ err = ncmpi_inq_malloc_size(&malloc_size);
+ if (err == NC_NOERR) {
+ MPI_Reduce(&malloc_size, &sum_size, 1, MPI_OFFSET, MPI_SUM, 0, MPI_COMM_WORLD);
+ if (rank == 0 && sum_size > 0)
+ printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n",
+ sum_size);
+ }
+
+ MPI_Allreduce(MPI_IN_PLACE, &nerrs, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
+ if (rank == 0) {
+ if (nerrs) printf(FAIL_STR,nerrs);
+ else printf(PASS_STR);
+ }
+
+ MPI_Finalize();
+ return 0;
+}
+
diff --git a/test/nc_test/test_get.m4 b/test/nc_test/test_get.m4
new file mode 100644
index 0000000..7d91848
--- /dev/null
+++ b/test/nc_test/test_get.m4
@@ -0,0 +1,958 @@
+dnl This is m4 source.
+dnl Process using m4 to produce 'C' language file.
+dnl
+dnl If you see this line, you can ignore the next one.
+/* Do not edit this file. It is produced from the corresponding .m4 source */
+dnl
+/*
+ * Copyright (C) 2003, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ */
+/* $Id: test_get.m4 2292 2016-01-04 05:30:45Z wkliao $ */
+
+
+undefine(`index')dnl
+dnl dnl dnl
+dnl
+dnl Macros
+dnl
+dnl dnl dnl
+dnl
+dnl Upcase(str)
+dnl
+define(`Upcase',dnl
+`dnl
+translit($1, abcdefghijklmnopqrstuvwxyz, ABCDEFGHIJKLMNOPQRSTUVWXYZ)')dnl
+dnl dnl dnl
+dnl
+dnl NCT_ITYPE(type)
+dnl
+define(`NCT_ITYPE', ``NCT_'Upcase($1)')dnl
+dnl
+
+define(`CheckText', `ifelse(`$1',`text', , `== (NCT_ITYPE($1) == NCT_TEXT)')')dnl
+define(`CheckRange',`ifelse(`$1',`text', `1', `($2 >= $1_min && $2 <= $1_max)')')dnl
+define(`IfCheckTextChar', `ifelse(`$1',`text', `if ($2 != NC_CHAR)')')dnl
+define(`CheckNumRange',
+ `ifelse(`$1',`text', `1',
+ `inRange3($2,$3,NCT_ITYPE($1)) && ($2 >= $1_min && $2 <= $1_max)')')dnl
+
+#include "tests.h"
+
+dnl TEST_NC_GET_VAR1(TYPE)
+dnl
+define(`TEST_NC_GET_VAR1',dnl
+`dnl
+int
+test_ncmpi_get_var1_$1(void)
+{
+ int ncid;
+ int i;
+ int j;
+ int err;
+ int nok = 0; /* count of valid comparisons */
+ MPI_Offset index[MAX_RANK];
+ int canConvert; /* Both text or both numeric */
+ double expect;
+ $1 value;
+
+ err = ncmpi_open(comm, testfile, NC_NOWRITE, info, &ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_open: %s", ncmpi_strerror(err));
+
+ ncmpi_begin_indep_data(ncid);
+ for (i = 0; i < numVars; i++) {
+ canConvert = (var_type[i] == NC_CHAR) CheckText($1);
+ for (j = 0; j < var_rank[i]; j++)
+ index[j] = 0;
+
+ /* check if pnetcdf can detect a bad file ID */
+ err = ncmpi_get_var1_$1(BAD_ID, i, index, &value);
+ IF (err != NC_EBADID)
+ error("bad ncid: err = %d", err);
+
+ /* check if pnetcdf can detect a bad variable ID */
+ err = ncmpi_get_var1_$1(ncid, BAD_VARID, index, &value);
+ IF (err != NC_ENOTVAR)
+ error("bad var id: err = %d", err);
+
+ /* check if pnetcdf can detect out of boundary requests */
+ for (j = 0; j < var_rank[i]; j++) {
+ index[j] = var_shape[i][j]; /* make an out-of-boundary starts[] */
+ err = ncmpi_get_var1_$1(ncid, i, index, &value);
+ if (!canConvert) {
+ IF (err != NC_ECHAR)
+ error("conversion: err = %d", err);
+ } else IF (err != NC_EINVALCOORDS)
+ error("bad index: err = %d", err);
+ index[j] = 0;
+ }
+
+ /* check if the contents are supposed to be */
+ for (j = 0; j < var_nels[i]; j++) {
+ err = toMixedBase(j, var_rank[i], var_shape[i], index);
+ IF (err != NC_NOERR)
+ error("error in toMixedBase 1");
+
+ /* when file is created the variable contents are generated by
+ * hash functions */
+ expect = hash4( var_type[i], var_rank[i], index, NCT_ITYPE($1) );
+
+ if (var_rank[i] == 0 && i%2 )
+ /* this var has no dim, a scalar variable */
+ err = ncmpi_get_var1_$1(ncid, i, NULL, &value);
+ else
+ err = ncmpi_get_var1_$1(ncid, i, index, &value);
+
+ if (canConvert) {
+ if (inRange3(expect,var_type[i], NCT_ITYPE($1))) {
+ if (CheckRange($1, expect)) {
+ IF (err != NC_NOERR) {
+ error("%s", ncmpi_strerror(err));
+ } else {
+ IF (!equal(value,expect,var_type[i],NCT_ITYPE($1))) {
+ error("expected: %G, got: %G", expect, (double) value);
+ } else {
+ nok++;
+ }
+ }
+ } else {
+ IF (err != NC_ERANGE)
+ error("Range error: err = %d", err);
+ }
+ } else {
+ IF (err != NC_NOERR && err != NC_ERANGE)
+ error("OK or Range error: err = %d", err);
+ }
+ } else {
+ IF (err != NC_ECHAR)
+ error("wrong type: err = %d", err);
+ }
+ }
+ }
+ ncmpi_end_indep_data(ncid);
+ err = ncmpi_close(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_close: %s", ncmpi_strerror(err));
+ return nok;
+}
+')dnl
+
+TEST_NC_GET_VAR1(text)
+TEST_NC_GET_VAR1(schar)
+TEST_NC_GET_VAR1(uchar)
+TEST_NC_GET_VAR1(short)
+TEST_NC_GET_VAR1(int)
+TEST_NC_GET_VAR1(long)
+TEST_NC_GET_VAR1(float)
+TEST_NC_GET_VAR1(double)
+TEST_NC_GET_VAR1(ushort)
+TEST_NC_GET_VAR1(uint)
+TEST_NC_GET_VAR1(longlong)
+TEST_NC_GET_VAR1(ulonglong)
+
+
+dnl TEST_NC_GET_VAR(TYPE)
+dnl
+define(`TEST_NC_GET_VAR',dnl
+`dnl
+int
+test_ncmpi_get_var_$1(void)
+{
+ int ncid;
+ int i;
+ int j;
+ int err;
+ int allInExtRange; /* all values within range of external data type */
+ int allInIntRange; /* all values within range of internal data type */
+ int nels;
+ int nok = 0; /* count of valid comparisons */
+ MPI_Offset index[MAX_RANK];
+ int canConvert; /* Both text or both numeric */
+ double expect[MAX_NELS];
+ $1 value[MAX_NELS];
+
+ err = ncmpi_open(comm, testfile, NC_NOWRITE, info, &ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_open: %s", ncmpi_strerror(err));
+
+ for (i = 0; i < numVars; i++) {
+ canConvert = (var_type[i] == NC_CHAR) CheckText($1);
+ assert(var_rank[i] <= MAX_RANK);
+ assert(var_nels[i] <= MAX_NELS);
+
+ /* check if pnetcdf can detect a bad file ID */
+ err = ncmpi_get_var_$1_all(BAD_ID, i, value);
+ IF (err != NC_EBADID)
+ error("bad ncid: err = %d", err);
+
+ /* check if pnetcdf can detect a bad variable ID */
+ err = ncmpi_get_var_$1_all(ncid, BAD_VARID, value);
+ IF (err != NC_ENOTVAR)
+ error("bad var id: err = %d", err);
+
+ /* check if the contents are supposed to be */
+ nels = 1;
+ for (j = 0; j < var_rank[i]; j++) {
+ nels *= var_shape[i][j];
+ }
+ allInExtRange = allInIntRange = 1;
+ for (j = 0; j < nels; j++) {
+ err = toMixedBase(j, var_rank[i], var_shape[i], index);
+ IF (err != NC_NOERR)
+ error("error in toMixedBase 1");
+ expect[j] = hash4(var_type[i], var_rank[i], index, NCT_ITYPE($1));
+ if (inRange3(expect[j],var_type[i], NCT_ITYPE($1))) {
+ IfCheckTextChar($1, var_type[i])
+ allInIntRange &= CheckRange($1,expect[j]);
+ } else {
+ allInExtRange = 0;
+ }
+ }
+ err = ncmpi_get_var_$1_all(ncid, i, value);
+ if (canConvert) {
+ if (allInExtRange) {
+ if (allInIntRange) {
+ IF (err != NC_NOERR)
+ error("(%s) %s", ncmpii_err_code_name(err),ncmpi_strerror(err));
+ } else {
+ IF (err != NC_ERANGE)
+ error("Range error: err = %d", err);
+ }
+ } else {
+ IF (err != NC_NOERR && err != NC_ERANGE)
+ error("OK or Range error: err = %d", err);
+ }
+ for (j = 0; j < nels; j++) {
+ if (CheckNumRange($1, expect[j], var_type[i])) {
+ IF (!equal(value[j],expect[j],var_type[i],NCT_ITYPE($1))){
+ error("value read not that expected");
+ if (verbose) {
+ error("\n");
+ error("varid: %d, ", i);
+ error("var_name: %s, ", var_name[i]);
+ error("var_type: %s, ", s_nc_type(var_type[i]));
+ error("element number: %d, ", j);
+ error("expect: %g, ", expect[j]);
+ error("got: %g", (double) value[j]);
+ }
+ } else {
+ nok++;
+ }
+ }
+ }
+ } else {
+ IF (nels > 0 && err != NC_ECHAR)
+ error("wrong type: err = %d", err);
+ }
+ }
+ err = ncmpi_close(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_close: %s", ncmpi_strerror(err));
+ return nok;
+}
+')dnl
+
+TEST_NC_GET_VAR(text)
+TEST_NC_GET_VAR(uchar)
+TEST_NC_GET_VAR(schar)
+TEST_NC_GET_VAR(short)
+TEST_NC_GET_VAR(int)
+TEST_NC_GET_VAR(long)
+TEST_NC_GET_VAR(float)
+TEST_NC_GET_VAR(double)
+TEST_NC_GET_VAR(ushort)
+TEST_NC_GET_VAR(uint)
+TEST_NC_GET_VAR(longlong)
+TEST_NC_GET_VAR(ulonglong)
+
+
+dnl TEST_NC_GET_VARA(TYPE)
+dnl
+define(`TEST_NC_GET_VARA',dnl
+`dnl
+int
+test_ncmpi_get_vara_$1(void)
+{
+ int ncid;
+ int d;
+ int i;
+ int j;
+ int k;
+ int err;
+ int allInExtRange; /* all values within external range? */
+ int allInIntRange; /* all values within internal range? */
+ int nels;
+ int nslabs;
+ int nok = 0; /* count of valid comparisons */
+ MPI_Offset start[MAX_RANK];
+ MPI_Offset edge[MAX_RANK];
+ MPI_Offset index[MAX_RANK];
+ MPI_Offset mid[MAX_RANK];
+ int canConvert; /* Both text or both numeric */
+ double expect[MAX_NELS];
+ $1 value[MAX_NELS];
+
+ err = ncmpi_open(comm, testfile, NC_NOWRITE, info, &ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_open: %s", ncmpi_strerror(err));
+ for (i = 0; i < numVars; i++) {
+ canConvert = (var_type[i] == NC_CHAR) CheckText($1);
+ assert(var_rank[i] <= MAX_RANK);
+ assert(var_nels[i] <= MAX_NELS);
+ for (j = 0; j < var_rank[i]; j++) {
+ start[j] = 0;
+ edge[j] = 1;
+ }
+ err = ncmpi_get_vara_$1_all(BAD_ID, i, start, edge, value);
+ IF (err != NC_EBADID)
+ error("bad ncid: err = %d", err);
+ err = ncmpi_get_vara_$1_all(ncid, BAD_VARID, start, edge, value);
+ IF (err != NC_ENOTVAR)
+ error("bad var id: err = %d", err);
+ for (j = 0; j < var_rank[i]; j++) {
+ start[j] = var_shape[i][j]; /* causes NC_EINVALCOORDS */
+ err = ncmpi_get_vara_$1_all(ncid, i, start, edge, value);
+ IF (canConvert && err != NC_EINVALCOORDS)
+ error("bad index: err = %d", err);
+ start[j] = 0;
+ edge[j] = var_shape[i][j] + 1; /* causes NC_EEDGE */
+ err = ncmpi_get_vara_$1_all(ncid, i, start, edge, value);
+ IF (canConvert && err != NC_EEDGE)
+ error("bad edge: err = %d", err);
+ edge[j] = 1;
+ }
+ /* Check non-scalars for correct error returned even when */
+ /* there is nothing to get (edge[j]==0) */
+ if (var_rank[i] > 0) {
+ for (j = 0; j < var_rank[i]; j++) {
+ edge[j] = 0;
+ }
+ err = ncmpi_get_vara_$1_all(BAD_ID, i, start, edge, value);
+ IF (err != NC_EBADID)
+ error("bad ncid: err = %d", err);
+ err = ncmpi_get_vara_$1_all(ncid, BAD_VARID, start, edge, value);
+ IF (err != NC_ENOTVAR)
+ error("bad var id: err = %d", err);
+ for (j = 0; j < var_rank[i]; j++) {
+ if (var_dimid[i][j] > 0) { /* skip record dim */
+ start[j] = var_shape[i][j];
+ err = ncmpi_get_vara_$1_all(ncid, i, start, edge, value);
+ IF (canConvert && err != NC_EINVALCOORDS)
+ error("bad start: err = %d", err);
+ start[j] = 0;
+ }
+ }
+ err = ncmpi_get_vara_$1_all(ncid, i, start, edge, value);
+ if (canConvert) {
+ IF (err != NC_NOERR)
+ error("%s", ncmpi_strerror(err));
+ } else {
+ IF (err != NC_ECHAR)
+ error("wrong type: err = %d", err);
+ }
+ for (j = 0; j < var_rank[i]; j++) {
+ edge[j] = 1;
+ }
+ }
+ /* Choose a random point dividing each dim into 2 parts */
+ /* get 2^rank (nslabs) slabs so defined */
+ nslabs = 1;
+ for (j = 0; j < var_rank[i]; j++) {
+ mid[j] = roll( var_shape[i][j] );
+ nslabs *= 2;
+ }
+ /* bits of k determine whether to get lower or upper part of dim */
+ for (k = 0; k < nslabs; k++) {
+ nels = 1;
+ for (j = 0; j < var_rank[i]; j++) {
+ if ((k >> j) & 1) {
+ start[j] = 0;
+ edge[j] = mid[j];
+ } else {
+ start[j] = mid[j];
+ edge[j] = var_shape[i][j] - mid[j];
+ }
+ nels *= edge[j];
+ }
+ allInExtRange = allInIntRange = 1;
+ for (j = 0; j < nels; j++) {
+ err = toMixedBase(j, var_rank[i], edge, index);
+ IF (err != NC_NOERR)
+ error("error in toMixedBase 1");
+ for (d = 0; d < var_rank[i]; d++)
+ index[d] += start[d];
+ expect[j] = hash4(var_type[i], var_rank[i], index, NCT_ITYPE($1));
+ if (inRange3(expect[j],var_type[i], NCT_ITYPE($1))) {
+ IfCheckTextChar($1, var_type[i])
+ allInIntRange &= CheckRange($1,expect[j]);
+ } else {
+ allInExtRange = 0;
+ }
+ }
+ if (var_rank[i] == 0 && i%2)
+ err = ncmpi_get_vara_$1_all(ncid, i, NULL, NULL, value);
+ else
+ err = ncmpi_get_vara_$1_all(ncid, i, start, edge, value);
+ if (canConvert) {
+ if (allInExtRange) {
+ if (allInIntRange) {
+ IF (err != NC_NOERR)
+ error("%s", ncmpi_strerror(err));
+ } else {
+ IF (err != NC_ERANGE)
+ error("Range error: err = %d", err);
+ }
+ } else {
+ IF (err != NC_NOERR && err != NC_ERANGE)
+ error("OK or Range error: err = %d", err);
+ }
+ for (j = 0; j < nels; j++) {
+ if (CheckNumRange($1, expect[j], var_type[i])) {
+ IF (!equal(value[j],expect[j],var_type[i],NCT_ITYPE($1))){
+ error("value read not that expected");
+ if (verbose) {
+ error("\n");
+ error("varid: %d, ", i);
+ error("var_name: %s, ", var_name[i]);
+ error("var_type: %s, ", s_nc_type(var_type[i]));
+ error("element number: %d, ", j);
+ error("expect: %g, ", expect[j]);
+ error("got: %g", (double) value[j]);
+ }
+ } else {
+ nok++;
+ }
+ }
+ }
+ } else {
+ IF (nels > 0 && err != NC_ECHAR)
+ error("wrong type: err = %d", err);
+ }
+ }
+ }
+ err = ncmpi_close(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_close: %s", ncmpi_strerror(err));
+ return nok;
+}
+')dnl
+
+TEST_NC_GET_VARA(text)
+TEST_NC_GET_VARA(uchar)
+TEST_NC_GET_VARA(schar)
+TEST_NC_GET_VARA(short)
+TEST_NC_GET_VARA(int)
+TEST_NC_GET_VARA(long)
+TEST_NC_GET_VARA(float)
+TEST_NC_GET_VARA(double)
+TEST_NC_GET_VARA(ushort)
+TEST_NC_GET_VARA(uint)
+TEST_NC_GET_VARA(longlong)
+TEST_NC_GET_VARA(ulonglong)
+
+
+dnl TEST_NC_GET_VARS(TYPE)
+dnl
+define(`TEST_NC_GET_VARS',dnl
+`dnl
+int
+test_ncmpi_get_vars_$1(void)
+{
+ int ncid;
+ int d;
+ int i;
+ int j;
+ int k;
+ int m;
+ int err;
+ int allInExtRange; /* all values within external range? */
+ int allInIntRange; /* all values within internal range? */
+ int nels;
+ int nslabs;
+ int nstarts; /* number of different starts */
+ int nok = 0; /* count of valid comparisons */
+ MPI_Offset start[MAX_RANK];
+ MPI_Offset edge[MAX_RANK];
+ MPI_Offset index[MAX_RANK];
+ MPI_Offset index2[MAX_RANK];
+ MPI_Offset mid[MAX_RANK];
+ MPI_Offset count[MAX_RANK];
+ MPI_Offset sstride[MAX_RANK];
+ MPI_Offset stride[MAX_RANK];
+ int canConvert; /* Both text or both numeric */
+ double expect[MAX_NELS];
+ $1 value[MAX_NELS];
+
+ err = ncmpi_open(comm, testfile, NC_NOWRITE, info, &ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_open: %s", ncmpi_strerror(err));
+ for (i = 0; i < numVars; i++) {
+ canConvert = (var_type[i] == NC_CHAR) CheckText($1);
+ assert(var_rank[i] <= MAX_RANK);
+ assert(var_nels[i] <= MAX_NELS);
+ for (j = 0; j < var_rank[i]; j++) {
+ start[j] = 0;
+ edge[j] = 1;
+ stride[j] = 1;
+ }
+ err = ncmpi_get_vars_$1_all(BAD_ID, i, start, edge, stride, value);
+ IF (err != NC_EBADID)
+ error("bad ncid: err = %d", err);
+ err = ncmpi_get_vars_$1_all(ncid, BAD_VARID, start, edge, stride, value);
+ IF (err != NC_ENOTVAR)
+ error("bad var id: err = %d", err);
+ for (j = 0; j < var_rank[i]; j++) {
+ start[j] = var_shape[i][j];
+ err = ncmpi_get_vars_$1_all(ncid, i, start, edge, stride, value);
+ if (!canConvert) {
+ IF (err != NC_ECHAR)
+ error("conversion: err = %d", err);
+ } else {
+ IF (err != NC_EINVALCOORDS)
+ error("bad index: err = %d", err);
+ start[j] = 0;
+ edge[j] = var_shape[i][j] + 1;
+ err = ncmpi_get_vars_$1_all(ncid, i, start, edge, stride, value);
+ IF (err != NC_EEDGE)
+ error("bad edge: err = %d", err);
+ edge[j] = 1;
+ stride[j] = 0;
+ err = ncmpi_get_vars_$1_all(ncid, i, start, edge, stride, value);
+ IF (err != NC_ESTRIDE)
+ error("bad stride: err = %d", err);
+ stride[j] = 1;
+ }
+ }
+ /* Choose a random point dividing each dim into 2 parts */
+ /* get 2^rank (nslabs) slabs so defined */
+ nslabs = 1;
+ for (j = 0; j < var_rank[i]; j++) {
+ mid[j] = roll( var_shape[i][j] );
+ nslabs *= 2;
+ }
+ /* bits of k determine whether to get lower or upper part of dim */
+ /* choose random stride from 1 to edge */
+ for (k = 0; k < nslabs; k++) {
+ nstarts = 1;
+ for (j = 0; j < var_rank[i]; j++) {
+ if ((k >> j) & 1) {
+ start[j] = 0;
+ edge[j] = mid[j];
+ } else {
+ start[j] = mid[j];
+ edge[j] = var_shape[i][j] - mid[j];
+ }
+ sstride[j] = stride[j] = edge[j] > 0 ? 1+roll(edge[j]) : 1;
+ nstarts *= stride[j];
+ }
+ for (m = 0; m < nstarts; m++) {
+ err = toMixedBase(m, var_rank[i], sstride, index);
+ IF (err != NC_NOERR)
+ error("error in toMixedBase");
+ nels = 1;
+ for (j = 0; j < var_rank[i]; j++) {
+ count[j] = 1 + (edge[j] - index[j] - 1) / stride[j];
+ nels *= count[j];
+ index[j] += start[j];
+ }
+ /* Random choice of forward or backward */
+/* TODO
+ if ( roll(2) ) {
+ for (j = 0; j < var_rank[i]; j++) {
+ index[j] += (count[j] - 1) * stride[j];
+ stride[j] = -stride[j];
+ }
+ }
+*/
+ allInExtRange = allInIntRange = 1;
+ for (j = 0; j < nels; j++) {
+ err = toMixedBase(j, var_rank[i], count, index2);
+ IF (err != NC_NOERR)
+ error("error in toMixedBase 1");
+ for (d = 0; d < var_rank[i]; d++)
+ index2[d] = index[d] + index2[d] * stride[d];
+ expect[j] = hash4(var_type[i], var_rank[i], index2,
+ NCT_ITYPE($1));
+ if (inRange3(expect[j],var_type[i],NCT_ITYPE($1))) {
+ IfCheckTextChar($1, var_type[i])
+ allInIntRange &= CheckRange($1,expect[j]);
+ } else {
+ allInExtRange = 0;
+ }
+ }
+ if (var_rank[i] == 0 && i%2 )
+ err = ncmpi_get_vars_$1_all(ncid, i, NULL, NULL, NULL, value);
+ else
+ err = ncmpi_get_vars_$1_all(ncid, i, index, count, stride, value);
+ if (canConvert) {
+ if (allInExtRange) {
+ if (allInIntRange) {
+ IF (err != NC_NOERR)
+ error("%s", ncmpi_strerror(err));
+ } else {
+ IF (err != NC_ERANGE)
+ error("Range error: err = %d", err);
+ }
+ } else {
+ IF (err != NC_NOERR && err != NC_ERANGE)
+ error("OK or Range error: err = %d", err);
+ }
+ for (j = 0; j < nels; j++) {
+ if (CheckNumRange($1, expect[j], var_type[i])) {
+ IF (!equal(value[j],expect[j],var_type[i], NCT_ITYPE($1))){
+ error("value read not that expected");
+ if (verbose) {
+ error("\n");
+ error("varid: %d, ", i);
+ error("var_name: %s, ", var_name[i]);
+ error("var_type: %s, ", s_nc_type(var_type[i]));
+ error("element number: %d, ", j);
+ error("expect: %g, ", expect[j]);
+ error("got: %g", (double) value[j]);
+ }
+ } else {
+ nok++;
+ }
+ }
+ }
+ } else {
+ IF (nels > 0 && err != NC_ECHAR)
+ error("wrong type: err = %d", err);
+ }
+ }
+ }
+
+ }
+ err = ncmpi_close(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_close: %s", ncmpi_strerror(err));
+ return nok;
+}
+')dnl
+
+TEST_NC_GET_VARS(text)
+TEST_NC_GET_VARS(uchar)
+TEST_NC_GET_VARS(schar)
+TEST_NC_GET_VARS(short)
+TEST_NC_GET_VARS(int)
+TEST_NC_GET_VARS(long)
+TEST_NC_GET_VARS(float)
+TEST_NC_GET_VARS(double)
+TEST_NC_GET_VARS(ushort)
+TEST_NC_GET_VARS(uint)
+TEST_NC_GET_VARS(longlong)
+TEST_NC_GET_VARS(ulonglong)
+
+
+dnl TEST_NC_GET_VARM(TYPE)
+dnl
+define(`TEST_NC_GET_VARM',dnl
+`dnl
+int
+test_ncmpi_get_varm_$1(void)
+{
+ int ncid;
+ int d;
+ int i;
+ int j;
+ int k;
+ int m;
+ int err;
+ int allInExtRange; /* all values within external range? */
+ int allInIntRange; /* all values within internal range? */
+ int nels;
+ int nslabs;
+ int nstarts; /* number of different starts */
+ int nok = 0; /* count of valid comparisons */
+ MPI_Offset start[MAX_RANK];
+ MPI_Offset edge[MAX_RANK];
+ MPI_Offset index[MAX_RANK];
+ MPI_Offset index2[MAX_RANK];
+ MPI_Offset mid[MAX_RANK];
+ MPI_Offset count[MAX_RANK];
+ MPI_Offset sstride[MAX_RANK];
+ MPI_Offset stride[MAX_RANK];
+ MPI_Offset imap[MAX_RANK];
+ int canConvert; /* Both text or both numeric */
+ double expect[MAX_NELS];
+ $1 value[MAX_NELS];
+
+ err = ncmpi_open(comm, testfile, NC_NOWRITE, info, &ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_open: %s", ncmpi_strerror(err));
+ for (i = 0; i < numVars; i++) {
+ canConvert = (var_type[i] == NC_CHAR) CheckText($1);
+ assert(var_rank[i] <= MAX_RANK);
+ assert(var_nels[i] <= MAX_NELS);
+ for (j = 0; j < var_rank[i]; j++) {
+ start[j] = 0;
+ edge[j] = 1;
+ stride[j] = 1;
+ imap[j] = 1;
+ }
+ err = ncmpi_get_varm_$1_all(BAD_ID, i, start, edge, stride, imap, value);
+ IF (err != NC_EBADID)
+ error("bad ncid: err = %d", err);
+ err = ncmpi_get_varm_$1_all(ncid, BAD_VARID, start, edge, stride, imap, value);
+ IF (err != NC_ENOTVAR)
+ error("bad var id: err = %d", err);
+ for (j = 0; j < var_rank[i]; j++) {
+ start[j] = var_shape[i][j];
+ err = ncmpi_get_varm_$1_all(ncid, i, start, edge, stride, imap, value);
+ if (!canConvert) {
+ IF (err != NC_ECHAR)
+ error("conversion: err = %d", err);
+ } else {
+ IF (err != NC_EINVALCOORDS)
+ error("bad index: err = %d", err);
+ start[j] = 0;
+ edge[j] = var_shape[i][j] + 1;
+ err = ncmpi_get_varm_$1_all(ncid, i, start, edge, stride, imap, value);
+ IF (err != NC_EEDGE)
+ error("bad edge: err = %d", err);
+ edge[j] = 1;
+ stride[j] = 0;
+ err = ncmpi_get_varm_$1_all(ncid, i, start, edge, stride, imap, value);
+ IF (err != NC_ESTRIDE)
+ error("bad stride: err = %d", err);
+ stride[j] = 1;
+ }
+ }
+ /* Choose a random point dividing each dim into 2 parts */
+ /* get 2^rank (nslabs) slabs so defined */
+ nslabs = 1;
+ for (j = 0; j < var_rank[i]; j++) {
+ mid[j] = roll( var_shape[i][j] );
+ nslabs *= 2;
+ }
+ /* bits of k determine whether to get lower or upper part of dim */
+ /* choose random stride from 1 to edge */
+ for (k = 0; k < nslabs; k++) {
+ nstarts = 1;
+ for (j = 0; j < var_rank[i]; j++) {
+ if ((k >> j) & 1) {
+ start[j] = 0;
+ edge[j] = mid[j];
+ } else {
+ start[j] = mid[j];
+ edge[j] = var_shape[i][j] - mid[j];
+ }
+ sstride[j] = stride[j] = edge[j] > 0 ? 1+roll(edge[j]) : 1;
+ nstarts *= stride[j];
+ }
+ for (m = 0; m < nstarts; m++) {
+ err = toMixedBase(m, var_rank[i], sstride, index);
+ IF (err != NC_NOERR)
+ error("error in toMixedBase");
+ nels = 1;
+ for (j = 0; j < var_rank[i]; j++) {
+ count[j] = 1 + (edge[j] - index[j] - 1) / stride[j];
+ nels *= count[j];
+ index[j] += start[j];
+ }
+ /* Random choice of forward or backward */
+/* TODO
+ if ( roll(2) ) {
+ for (j = 0; j < var_rank[i]; j++) {
+ index[j] += (count[j] - 1) * stride[j];
+ stride[j] = -stride[j];
+ }
+ }
+ */
+ if (var_rank[i] > 0) {
+ j = var_rank[i] - 1;
+ imap[j] = 1;
+ for (; j > 0; j--)
+ imap[j-1] = imap[j] * count[j];
+ }
+ allInExtRange = allInIntRange = 1;
+ for (j = 0; j < nels; j++) {
+ err = toMixedBase(j, var_rank[i], count, index2);
+ IF (err != NC_NOERR)
+ error("error in toMixedBase 1");
+ for (d = 0; d < var_rank[i]; d++)
+ index2[d] = index[d] + index2[d] * stride[d];
+ expect[j] = hash4(var_type[i], var_rank[i], index2,
+ NCT_ITYPE($1));
+ if (inRange3(expect[j],var_type[i],NCT_ITYPE($1))) {
+ IfCheckTextChar($1, var_type[i])
+ allInIntRange &= CheckRange($1,expect[j]);
+ } else {
+ allInExtRange = 0;
+ }
+ }
+ if (var_rank[i] == 0 && i%2 )
+ err = ncmpi_get_varm_$1_all(ncid,i,NULL,NULL,NULL,NULL,value);
+ else
+ err = ncmpi_get_varm_$1_all(ncid,i,index,count,stride,imap,value);
+ if (canConvert) {
+ if (allInExtRange) {
+ if (allInIntRange) {
+ IF (err != NC_NOERR)
+ error("%s", ncmpi_strerror(err));
+ } else {
+ IF (err != NC_ERANGE)
+ error("Range error: err = %d", err);
+ }
+ } else {
+ IF (err != NC_NOERR && err != NC_ERANGE)
+ error("OK or Range error: err = %d", err);
+ }
+ for (j = 0; j < nels; j++) {
+ if (CheckNumRange($1, expect[j], var_type[i])) {
+ IF (!equal(value[j],expect[j],var_type[i], NCT_ITYPE($1))){
+ error("value read not that expected");
+ if (verbose) {
+ error("\n");
+ error("varid: %d, ", i);
+ error("var_name: %s, ", var_name[i]);
+ error("var_type: %s, ", s_nc_type(var_type[i]));
+ error("element number: %d, ", j);
+ error("expect: %g, ", expect[j]);
+ error("got: %g", (double) value[j]);
+ }
+ } else {
+ nok++;
+ }
+ }
+ }
+ } else {
+ IF (nels > 0 && err != NC_ECHAR)
+ error("wrong type: err = %d", err);
+ }
+ }
+ }
+ }
+ err = ncmpi_close(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_close: %s", ncmpi_strerror(err));
+ return nok;
+}
+')dnl
+
+TEST_NC_GET_VARM(text)
+TEST_NC_GET_VARM(uchar)
+TEST_NC_GET_VARM(schar)
+TEST_NC_GET_VARM(short)
+TEST_NC_GET_VARM(int)
+TEST_NC_GET_VARM(long)
+TEST_NC_GET_VARM(float)
+TEST_NC_GET_VARM(double)
+TEST_NC_GET_VARM(ushort)
+TEST_NC_GET_VARM(uint)
+TEST_NC_GET_VARM(longlong)
+TEST_NC_GET_VARM(ulonglong)
+
+
+dnl TEST_NC_GET_ATT(TYPE)
+dnl
+define(`TEST_NC_GET_ATT',dnl
+`dnl
+int
+test_ncmpi_get_att_$1(void)
+{
+ int ncid;
+ int i;
+ int j;
+ MPI_Offset k;
+ int err;
+ int allInExtRange;
+ int allInIntRange;
+ int canConvert; /* Both text or both numeric */
+ int nok = 0; /* count of valid comparisons */
+ double expect[MAX_NELS];
+ $1 value[MAX_NELS];
+
+ err = ncmpi_open(comm, testfile, NC_NOWRITE, info, &ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_open: %s", ncmpi_strerror(err));
+
+ for (i = -1; i < numVars; i++) {
+ for (j = 0; j < NATTS(i); j++) {
+ canConvert = (ATT_TYPE(i,j) == NC_CHAR) CheckText($1);
+ err = ncmpi_get_att_$1(BAD_ID, i, ATT_NAME(i,j), value);
+ IF (err != NC_EBADID)
+ error("bad ncid: err = %d", err);
+ err = ncmpi_get_att_$1(ncid, BAD_VARID, ATT_NAME(i,j), value);
+ IF (err != NC_ENOTVAR)
+ error("bad var id: err = %d", err);
+ err = ncmpi_get_att_$1(ncid, i, "noSuch", value);
+ IF (err != NC_ENOTATT)
+ error("Bad attribute name: err = %d", err);
+ allInExtRange = allInIntRange = 1;
+ for (k = 0; k < ATT_LEN(i,j); k++) {
+ expect[k] = hash4(ATT_TYPE(i,j), -1, &k, NCT_ITYPE($1));
+ if (inRange3(expect[k],ATT_TYPE(i,j),NCT_ITYPE($1))) {
+ /* netCDF specification make a special case for type
+ * conversion between uchar and scahr: do not check for
+ * range error. See
+ * http://www.unidata.ucar.edu/software/netcdf/docs_rc/data_type.html#type_conversion
+ */
+ IfCheckTextChar($1, ATT_TYPE(i,j))
+ ifelse(`$1',`uchar', `if (ATT_TYPE(i,j) != NC_BYTE)')
+ allInIntRange &= CheckRange($1,expect[k]);
+ } else {
+ allInExtRange = 0;
+ }
+ }
+ err = ncmpi_get_att_$1(ncid, i, ATT_NAME(i,j), value);
+ if (canConvert || ATT_LEN(i,j) == 0) {
+ if (allInExtRange) {
+ if (allInIntRange) {
+ IF (err != NC_NOERR)
+ error("%s", ncmpi_strerror(err));
+ } else {
+ IF (err != NC_ERANGE)
+ error("Range error: err = %d", err);
+ }
+ } else {
+ IF (err != NC_NOERR && err != NC_ERANGE)
+ error("OK or Range error: err = %d", err);
+ }
+ for (k = 0; k < ATT_LEN(i,j); k++) {
+ if (CheckNumRange($1, expect[k], ATT_TYPE(i,j))) {
+ IF (!equal(value[k],expect[k],ATT_TYPE(i,j), NCT_ITYPE($1))){
+ error("value read not that expected");
+ if (verbose) {
+ error("\n");
+ error("varid: %d, ", i);
+ error("att_name: %s, ", ATT_NAME(i,j));
+ error("var_type: %s, ", s_nc_type(var_type[i]));
+ error("att_type: %s, ", s_nc_type(ATT_TYPE(i,j)));
+ error("element number: %d, ", k);
+ error("expect: %g, ", expect[k]);
+ error("got: %g", (double) value[k]);
+ }
+ } else {
+ nok++;
+ }
+ }
+ }
+ } else {
+ IF (err != NC_ECHAR)
+ error("wrong type: err = %d", err);
+ }
+ }
+ }
+
+ err = ncmpi_close(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_close: %s", ncmpi_strerror(err));
+ return nok;
+}
+')dnl
+
+TEST_NC_GET_ATT(text)
+TEST_NC_GET_ATT(uchar)
+TEST_NC_GET_ATT(schar)
+TEST_NC_GET_ATT(short)
+TEST_NC_GET_ATT(int)
+TEST_NC_GET_ATT(long)
+TEST_NC_GET_ATT(float)
+TEST_NC_GET_ATT(double)
+TEST_NC_GET_ATT(ushort)
+TEST_NC_GET_ATT(uint)
+TEST_NC_GET_ATT(longlong)
+TEST_NC_GET_ATT(ulonglong)
+
diff --git a/test/nc_test/test_iget.m4 b/test/nc_test/test_iget.m4
new file mode 100644
index 0000000..d54a30b
--- /dev/null
+++ b/test/nc_test/test_iget.m4
@@ -0,0 +1,1547 @@
+dnl This is m4 source.
+dnl Process using m4 to produce 'C' language file.
+dnl
+dnl If you see this line, you can ignore the next one.
+/* Do not edit this file. It is produced from the corresponding .m4 source */
+dnl
+/*
+ * Copyright (C) 2003, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ */
+/* $Id: test_iget.m4 2293 2016-01-06 03:43:04Z wkliao $ */
+
+
+undefine(`index')dnl
+dnl dnl dnl
+dnl
+dnl Macros
+dnl
+dnl dnl dnl
+dnl
+dnl Upcase(str)
+dnl
+define(`Upcase',dnl
+`dnl
+translit($1, abcdefghijklmnopqrstuvwxyz, ABCDEFGHIJKLMNOPQRSTUVWXYZ)')dnl
+dnl dnl dnl
+dnl
+dnl NCT_ITYPE(type)
+dnl
+define(`NCT_ITYPE', ``NCT_'Upcase($1)')dnl
+dnl
+
+define(`CheckText', `ifelse(`$1',`text', , `== (NCT_ITYPE($1) == NCT_TEXT)')')dnl
+define(`CheckRange',`ifelse(`$1',`text', `1', `($2 >= $1_min && $2 <= $1_max)')')dnl
+define(`IfCheckTextChar', `ifelse(`$1',`text', `if ($2 != NC_CHAR)')')dnl
+define(`CheckNumRange',
+ `ifelse(`$1',`text', `1',
+ `inRange3($2,$3,NCT_ITYPE($1)) && ($2 >= $1_min && $2 <= $1_max)')')dnl
+
+#include "tests.h"
+
+int
+test_ncmpi_iget_var1(void)
+{
+ int i, j, err, ncid, nok = 0; /* count of valid comparisons */
+ MPI_Offset index[MAX_RANK];
+ double expect, value, buf[1];
+ int reqid, status;
+ MPI_Datatype datatype;
+
+ err = ncmpi_open(comm, testfile, NC_NOWRITE, info, &ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_open: %s", ncmpi_strerror(err));
+
+ for (i = 0; i < numVars; i++) {
+ for (j = 0; j < var_rank[i]; j++) index[j] = 0;
+ datatype = nc_mpi_type(var_type[i]);
+
+ /* check if pnetcdf can detect a bad file ID */
+ err = ncmpi_iget_var1(BAD_ID, i, index, buf, 1, datatype, &reqid);
+ IF (err != NC_EBADID)
+ error("bad ncid: err = %d", err);
+ ELSE_NOK
+ err = ncmpi_iget_var1(ncid, BAD_VARID, index, buf, 1, datatype, &reqid);
+ IF (err != NC_ENOTVAR)
+ error("bad var id: err = %d", err);
+ ELSE_NOK
+ /* check if pnetcdf can detect out of boundary requests */
+ for (j = 0; j < var_rank[i]; j++) {
+ index[j] = var_shape[i][j]; /* make an out-of-boundary starts[] */
+ err = ncmpi_iget_var1(ncid, i, index, buf, 1, datatype, &reqid);
+ IF (err != NC_EINVALCOORDS)
+ error("bad index: err = %d", err);
+ ELSE_NOK
+ index[j] = 0;
+ }
+ /* check if the contents are supposed to be */
+ for (j = 0; j < var_nels[i]; j++) {
+ err = toMixedBase(j, var_rank[i], var_shape[i], index);
+ IF (err != NC_NOERR)
+ error("error in toMixedBase 1");
+
+ /* when file is created the variable contents are generated by
+ * hash functions */
+ expect = hash(var_type[i], var_rank[i], index);
+ if (var_rank[i] == 0 && i%2 )
+ err = ncmpi_iget_var1(ncid, i, NULL, buf, 1, datatype, &reqid);
+ else
+ err = ncmpi_iget_var1(ncid, i, index, buf, 1, datatype, &reqid);
+ IF (err != NC_NOERR)
+ error("ncmpi_iget_var: %s", ncmpi_strerror(err));
+ ELSE_NOK
+
+ err = ncmpi_wait_all(ncid, 1, &reqid, &status);
+ IF (err != NC_NOERR)
+ error("ncmpi_wait_all: %s", ncmpi_strerror(err));
+ ELSE_NOK
+
+ err = nc2dbl( var_type[i], buf, &value );
+ IF (err)
+ error("error in nc2dbl");
+ if (inRange(expect,var_type[i])) {
+ IF (!equal2(value,expect,var_type[i])) {
+ error("expected: %G, got: %G", expect, value);
+ } else {
+ nok++;
+ }
+ }
+ }
+ }
+ err = ncmpi_close(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_close: %s", ncmpi_strerror(err));
+ return nok;
+}
+
+dnl TEST_NC_IGET_VAR1(TYPE)
+dnl
+define(`TEST_NC_IGET_VAR1',dnl
+`dnl
+int
+test_ncmpi_iget_var1_$1(void)
+{
+ int ncid;
+ int i;
+ int j;
+ int err;
+ int nok = 0; /* count of valid comparisons */
+ MPI_Offset index[MAX_RANK];
+ int canConvert; /* Both text or both numeric */
+ double expect;
+ $1 value;
+ int reqid, status;
+
+ err = ncmpi_open(comm, testfile, NC_NOWRITE, info, &ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_open: %s", ncmpi_strerror(err));
+
+ for (i = 0; i < numVars; i++) {
+ canConvert = (var_type[i] == NC_CHAR) CheckText($1);
+ for (j = 0; j < var_rank[i]; j++)
+ index[j] = 0;
+
+ /* check if pnetcdf can detect a bad file ID */
+ err = ncmpi_iget_var1_$1(BAD_ID, i, index, &value, &reqid);
+ IF (err != NC_EBADID)
+ error("bad ncid: err = %d", err);
+ ELSE_NOK
+ err = ncmpi_iget_var1_$1(ncid, BAD_VARID, index, &value, &reqid);
+ IF (err != NC_ENOTVAR)
+ error("bad var id: err = %d", err);
+ ELSE_NOK
+ /* check if pnetcdf can detect out of boundary requests */
+ for (j = 0; j < var_rank[i]; j++) {
+ index[j] = var_shape[i][j]; /* make an out-of-boundary starts[] */
+ err = ncmpi_iget_var1_$1(ncid, i, index, &value, &reqid);
+ if (!canConvert) {
+ IF (err != NC_ECHAR)
+ error("conversion: err = %d", err);
+ } else IF (err != NC_EINVALCOORDS)
+ error("bad index: err = %d", err);
+ ELSE_NOK
+ index[j] = 0;
+ }
+ /* check if the contents are supposed to be */
+ for (j = 0; j < var_nels[i]; j++) {
+ err = toMixedBase(j, var_rank[i], var_shape[i], index);
+ IF (err != NC_NOERR)
+ error("error in toMixedBase 1");
+
+ /* when file is created the variable contents are generated by
+ * hash functions */
+ expect = hash4( var_type[i], var_rank[i], index, NCT_ITYPE($1) );
+
+ if (var_rank[i] == 0 && i%2 )
+ err = ncmpi_iget_var1_$1(ncid, i, NULL, &value, &reqid);
+ else
+ err = ncmpi_iget_var1_$1(ncid, i, index, &value, &reqid);
+ if (err == NC_NOERR)
+ ncmpi_wait_all(ncid, 1, &reqid, &status);
+
+ if (canConvert) {
+ if (inRange3(expect,var_type[i], NCT_ITYPE($1))) {
+ if (CheckRange($1, expect)) {
+ IF (status != NC_NOERR) {
+ error("%s", ncmpi_strerror(status));
+ } else {
+ IF (!equal(value,expect,var_type[i],NCT_ITYPE($1)))
+ error("expected: %G, got: %G", expect,
+ (double) value);
+ ELSE_NOK
+ }
+ } else {
+ IF (status != NC_ERANGE)
+ error("Range error: status = %d", status);
+ ELSE_NOK
+ }
+ } else {
+ IF (status != NC_NOERR && status != NC_ERANGE)
+ error("OK or Range error: status = %d", status);
+ ELSE_NOK
+ }
+ } else {
+ IF (err != NC_ECHAR)
+ error("wrong type: err = %d", err);
+ ELSE_NOK
+ }
+ }
+ }
+ err = ncmpi_close(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_close: %s", ncmpi_strerror(err));
+ return nok;
+}
+')dnl
+
+TEST_NC_IGET_VAR1(text)
+TEST_NC_IGET_VAR1(uchar)
+TEST_NC_IGET_VAR1(schar)
+TEST_NC_IGET_VAR1(short)
+TEST_NC_IGET_VAR1(int)
+TEST_NC_IGET_VAR1(long)
+TEST_NC_IGET_VAR1(float)
+TEST_NC_IGET_VAR1(double)
+TEST_NC_IGET_VAR1(ushort)
+TEST_NC_IGET_VAR1(uint)
+TEST_NC_IGET_VAR1(longlong)
+TEST_NC_IGET_VAR1(ulonglong)
+
+int
+test_ncmpi_iget_var(void)
+{
+ int ncid;
+ int i;
+ int j;
+ int err, num_err;
+ int nels;
+ int nok = 0; /* count of valid comparisons */
+ MPI_Offset index[MAX_RANK];
+ double expect[MAX_NELS];
+ double buf[MAX_NELS];
+ int reqid, status;
+ MPI_Datatype datatype;
+
+ err = ncmpi_open(comm, testfile, NC_NOWRITE, info, &ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_open: %s", ncmpi_strerror(err));
+ for (i = 0; i < numVars; i++) {
+ datatype = nc_mpi_type(var_type[i]);
+ assert(var_rank[i] <= MAX_RANK);
+ assert(var_nels[i] <= MAX_NELS);
+
+ /* check if pnetcdf can detect a bad file ID */
+ err = ncmpi_iget_var(BAD_ID, i, buf, 1, datatype, &reqid);
+ IF (err != NC_EBADID)
+ error("bad ncid: err = %d", err);
+ ELSE_NOK
+ /* check if pnetcdf can detect a bad variable ID */
+ err = ncmpi_iget_var(ncid, BAD_VARID, buf, 1, datatype, &reqid);
+ IF (err != NC_ENOTVAR)
+ error("bad var id: err = %d", err);
+ ELSE_NOK
+
+ /* check if the contents are supposed to be */
+ nels = 1;
+ for (j = 0; j < var_rank[i]; j++) {
+ nels *= var_shape[i][j];
+ }
+ for (j = 0; j < nels; j++) {
+ err = toMixedBase(j, var_rank[i], var_shape[i], index);
+ IF (err != NC_NOERR)
+ error("error in toMixedBase 1");
+ expect[j] = hash(var_type[i], var_rank[i], index);
+ }
+ err = ncmpi_iget_var(ncid, i, buf, nels, datatype, &reqid);
+ IF (err != NC_NOERR)
+ error("ncmpi_iget_var: %s", ncmpi_strerror(err));
+ ELSE_NOK
+
+ err = ncmpi_wait_all(ncid, 1, &reqid, &status);
+ IF (err != NC_NOERR)
+ error("ncmpi_wait_all: %s", ncmpi_strerror(err));
+ ELSE_NOK
+
+ num_err = 0;
+ for (j = 0; j < nels; j++) {
+ double got;
+ char *p = (char *) buf;
+ p += j * nctypelen(var_type[i]);
+ if (inRange(expect[j],var_type[i])) {
+ err = nc2dbl(var_type[i], p, &got);
+ IF (err != NC_NOERR)
+ error("error in nc2dbl");
+ IF (!equal2(got,expect[j],var_type[i])) {
+ error("value read not that expected");
+ if (verbose) {
+ error("\n");
+ error("varid: %d, ", i);
+ error("var_name: %s, ", var_name[i]);
+ error("element number: %d ", j);
+ error("expect: %g", expect[j]);
+ error("got: %g", got);
+ }
+ num_err++;
+ }
+ }
+ if (num_err == 0) nok++;
+ }
+ }
+ err = ncmpi_close(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_close: %s", ncmpi_strerror(err));
+ return nok;
+}
+
+dnl TEST_NC_IGET_VAR(TYPE)
+dnl
+define(`TEST_NC_IGET_VAR',dnl
+`dnl
+int
+test_ncmpi_iget_var_$1(void)
+{
+ int ncid;
+ int i;
+ int j;
+ int err, num_err;
+ int allInExtRange; /* all values within external range? */
+ int allInIntRange; /* all values within internal range? */
+ int nels;
+ int nok = 0; /* count of valid comparisons */
+ MPI_Offset index[MAX_RANK];
+ int canConvert; /* Both text or both numeric */
+ double expect[MAX_NELS];
+ $1 value[MAX_NELS];
+ int reqid, status;
+
+ err = ncmpi_open(comm, testfile, NC_NOWRITE, info, &ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_open: %s", ncmpi_strerror(err));
+ for (i = 0; i < numVars; i++) {
+ canConvert = (var_type[i] == NC_CHAR) CheckText($1);
+ assert(var_rank[i] <= MAX_RANK);
+ assert(var_nels[i] <= MAX_NELS);
+
+ /* check if pnetcdf can detect a bad file ID */
+ err = ncmpi_iget_var_$1(BAD_ID, i, value, &reqid);
+ IF (err != NC_EBADID)
+ error("bad ncid: err = %d", err);
+ ELSE_NOK
+ /* check if pnetcdf can detect a bad variable ID */
+ err = ncmpi_iget_var_$1(ncid, BAD_VARID, value, &reqid);
+ IF (err != NC_ENOTVAR)
+ error("bad var id: err = %d", err);
+ ELSE_NOK
+
+ /* check if the contents are supposed to be */
+ nels = 1;
+ for (j = 0; j < var_rank[i]; j++) {
+ nels *= var_shape[i][j];
+ }
+ allInExtRange = allInIntRange = 1;
+ for (j = 0; j < nels; j++) {
+ err = toMixedBase(j, var_rank[i], var_shape[i], index);
+ IF (err != NC_NOERR)
+ error("error in toMixedBase 1");
+ expect[j] = hash4(var_type[i], var_rank[i], index, NCT_ITYPE($1));
+ if (inRange3(expect[j],var_type[i], NCT_ITYPE($1))) {
+ IfCheckTextChar($1, var_type[i])
+ allInIntRange &= CheckRange($1, expect[j]);
+ } else {
+ allInExtRange = 0;
+ }
+ }
+ err = ncmpi_iget_var_$1(ncid, i, value, &reqid);
+ if (err == NC_NOERR)
+ ncmpi_wait_all(ncid, 1, &reqid, &status);
+ ELSE_NOK
+ if (canConvert) {
+ if (allInExtRange) {
+ if (allInIntRange) {
+ IF (status != NC_NOERR)
+ error("%s", ncmpi_strerror(status));
+ ELSE_NOK
+ } else {
+ IF (status != NC_ERANGE)
+ error("Range error: status = %d", status);
+ ELSE_NOK
+ }
+ } else {
+ IF (status != NC_NOERR && status != NC_ERANGE)
+ error("OK or Range error: status = %d", status);
+ ELSE_NOK
+ }
+ num_err = 0;
+ for (j = 0; j < nels; j++) {
+ if (CheckNumRange($1, expect[j], var_type[i])) {
+ IF (!equal(value[j],expect[j],var_type[i],NCT_ITYPE($1))){
+ error("value read not that expected");
+ if (verbose) {
+ error("\n");
+ error("varid: %d, ", i);
+ error("var_name: %s, ", var_name[i]);
+ error("element number: %d ", j);
+ error("expect: %g", expect[j]);
+ error("got: %g", (double) value[j]);
+ }
+ num_err++;
+ }
+ }
+ }
+ if (num_err == 0) nok++;
+ } else {
+ IF (nels > 0 && err != NC_ECHAR)
+ error("wrong type: err = %d", err);
+ ELSE_NOK
+ }
+ }
+ err = ncmpi_close(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_close: %s", ncmpi_strerror(err));
+ return nok;
+}
+')dnl
+
+TEST_NC_IGET_VAR(text)
+TEST_NC_IGET_VAR(uchar)
+TEST_NC_IGET_VAR(schar)
+TEST_NC_IGET_VAR(short)
+TEST_NC_IGET_VAR(int)
+TEST_NC_IGET_VAR(long)
+TEST_NC_IGET_VAR(float)
+TEST_NC_IGET_VAR(double)
+TEST_NC_IGET_VAR(ushort)
+TEST_NC_IGET_VAR(uint)
+TEST_NC_IGET_VAR(longlong)
+TEST_NC_IGET_VAR(ulonglong)
+
+
+int
+test_ncmpi_iget_vara(void)
+{
+ int ncid, d, i, j, k, err, num_err, nels, nslabs;
+ int nok = 0; /* count of valid comparisons */
+ MPI_Offset start[MAX_RANK];
+ MPI_Offset edge[MAX_RANK];
+ MPI_Offset index[MAX_RANK];
+ MPI_Offset mid[MAX_RANK];
+ MPI_Datatype datatype;
+ double buf[MAX_NELS];
+ double expect[MAX_NELS];
+ int reqid, status;
+
+ err = ncmpi_open(comm, testfile, NC_NOWRITE, info, &ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_open: %s", ncmpi_strerror(err));
+ for (i = 0; i < numVars; i++) {
+ datatype = nc_mpi_type(var_type[i]);
+ assert(var_rank[i] <= MAX_RANK);
+ assert(var_nels[i] <= MAX_NELS);
+ for (j = 0; j < var_rank[i]; j++) {
+ start[j] = 0;
+ edge[j] = 1;
+ }
+ err = ncmpi_iget_vara(BAD_ID, i, start, edge, buf, 1, datatype, &reqid);
+ IF (err != NC_EBADID)
+ error("bad ncid: err = %d", err);
+ ELSE_NOK
+ err = ncmpi_iget_vara(ncid, BAD_VARID, start, edge, buf, 1, datatype, &reqid);
+ IF (err != NC_ENOTVAR)
+ error("bad var id: err = %d", err);
+ ELSE_NOK
+ for (j = 0; j < var_rank[i]; j++) {
+ start[j] = var_shape[i][j]; /* out of boundary check */
+ err = ncmpi_iget_vara(ncid, i, start, edge, buf, 1, datatype, &reqid);
+ IF (err != NC_EINVALCOORDS)
+ error("bad index: err = %d", err);
+ ELSE_NOK
+ start[j] = 0;
+ edge[j] = var_shape[i][j] + 1; /* edge error check */
+ err = ncmpi_iget_vara(ncid, i, start, edge, buf, 1, datatype, &reqid);
+ IF (err != NC_EEDGE)
+ error("bad index/edge: err = %d", err);
+ ELSE_NOK
+ edge[j] = 1;
+ }
+ /* Check non-scalars for correct error returned even when */
+ /* there is nothing to get (edge[j]==0) */
+ if (var_rank[i] > 0) {
+ for (j = 0; j < var_rank[i]; j++)
+ edge[j] = 0;
+ err = ncmpi_iget_vara(BAD_ID, i, start, edge, buf, 1, datatype, &reqid);
+ IF (err != NC_EBADID)
+ error("bad ncid: err = %d", err);
+ ELSE_NOK
+ err = ncmpi_iget_vara(ncid, BAD_VARID, start, edge, buf, 1, datatype, &reqid);
+ IF (err != NC_ENOTVAR)
+ error("bad var id: err = %d", err);
+ ELSE_NOK
+ for (j = 0; j < var_rank[i]; j++) {
+ if (var_dimid[i][j] > 0) { /* skip record dim */
+ start[j] = var_shape[i][j]; /* out of boundary check */
+ err = ncmpi_iget_vara(ncid, i, start, edge, buf, 1, datatype, &reqid);
+ IF (err != NC_EINVALCOORDS)
+ error("bad start: err = %d", err);
+ ELSE_NOK
+ start[j] = 0;
+ }
+ }
+ for (j = 0; j < var_rank[i]; j++)
+ edge[j] = 1;
+ }
+ /* Choose a random point dividing each dim into 2 parts */
+ /* get 2^rank (nslabs) slabs so defined */
+ nslabs = 1;
+ for (j = 0; j < var_rank[i]; j++) {
+ mid[j] = roll( var_shape[i][j] );
+ nslabs *= 2;
+ }
+ /* bits of k determine whether to get lower or upper part of dim */
+ for (k = 0; k < nslabs; k++) {
+ nels = 1;
+ for (j = 0; j < var_rank[i]; j++) {
+ if ((k >> j) & 1) {
+ start[j] = 0;
+ edge[j] = mid[j];
+ } else {
+ start[j] = mid[j];
+ edge[j] = var_shape[i][j] - mid[j];
+ }
+ nels *= edge[j];
+ }
+ for (j = 0; j < nels; j++) {
+ err = toMixedBase(j, var_rank[i], edge, index);
+ IF (err != NC_NOERR)
+ error("error in toMixedBase 1");
+ for (d = 0; d < var_rank[i]; d++)
+ index[d] += start[d];
+ expect[j] = hash(var_type[i], var_rank[i], index);
+ }
+ if (var_rank[i] == 0 && i%2)
+ err = ncmpi_iget_vara(ncid, i, NULL, NULL, buf, 1, datatype, &reqid);
+ else
+ err = ncmpi_iget_vara(ncid, i, start, edge, buf, nels, datatype, &reqid);
+ IF (err != NC_NOERR)
+ error("ncmpi_iget_vara %s", ncmpi_strerror(err));
+ ELSE_NOK
+
+ err = ncmpi_wait_all(ncid, 1, &reqid, &status);
+ IF (err != NC_NOERR)
+ error("ncmpi_wait_all %s", ncmpi_strerror(err));
+ ELSE_NOK
+
+ num_err = 0;
+ for (j = 0; j < nels; j++) {
+ double got;
+ char *p = (char *) buf;
+ p += j * nctypelen(var_type[i]);
+ if (inRange(expect[j],var_type[i])) {
+ err = nc2dbl(var_type[i], p, &got);
+ IF (err != NC_NOERR)
+ error("error in nc2dbl");
+ IF (!equal2(got,expect[j],var_type[i])) {
+ error("value read not that expected");
+ if (verbose) {
+ error("\n");
+ error("varid: %d, ", i);
+ error("var_name: %s, ", var_name[i]);
+ error("element number: %d ", j);
+ error("expect: %g", expect[j]);
+ error("got: %g", got);
+ }
+ num_err++;
+ }
+ }
+ if (num_err == 0) nok++;
+ }
+ }
+ }
+ err = ncmpi_close(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_close: %s", ncmpi_strerror(err));
+ return nok;
+}
+
+dnl TEST_NC_IGET_VARA(TYPE)
+dnl
+define(`TEST_NC_IGET_VARA',dnl
+`dnl
+int
+test_ncmpi_iget_vara_$1(void)
+{
+ int ncid;
+ int d;
+ int i;
+ int j;
+ int k;
+ int err, num_err;
+ int allInExtRange; /* all values within external range? */
+ int allInIntRange; /* all values within internal range? */
+ int nels;
+ int nslabs;
+ int nok = 0; /* count of valid comparisons */
+ MPI_Offset start[MAX_RANK];
+ MPI_Offset edge[MAX_RANK];
+ MPI_Offset index[MAX_RANK];
+ MPI_Offset mid[MAX_RANK];
+ int canConvert; /* Both text or both numeric */
+ double expect[MAX_NELS];
+ $1 value[MAX_NELS];
+ int reqid, status;
+
+ err = ncmpi_open(comm, testfile, NC_NOWRITE, info, &ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_open: %s", ncmpi_strerror(err));
+ for (i = 0; i < numVars; i++) {
+ canConvert = (var_type[i] == NC_CHAR) CheckText($1);
+ assert(var_rank[i] <= MAX_RANK);
+ assert(var_nels[i] <= MAX_NELS);
+ for (j = 0; j < var_rank[i]; j++) {
+ start[j] = 0;
+ edge[j] = 1;
+ }
+ err = ncmpi_iget_vara_$1(BAD_ID, i, start, edge, value, &reqid);
+ IF (err != NC_EBADID)
+ error("bad ncid: err = %d", err);
+ ELSE_NOK
+ err = ncmpi_iget_vara_$1(ncid, BAD_VARID, start, edge, value, &reqid);
+ IF (err != NC_ENOTVAR)
+ error("bad var id: err = %d", err);
+ ELSE_NOK
+ for (j = 0; j < var_rank[i]; j++) {
+ start[j] = var_shape[i][j]; /* out of boundary check */
+ err = ncmpi_iget_vara_$1(ncid, i, start, edge, value, &reqid);
+ IF (canConvert && err != NC_EINVALCOORDS)
+ error("bad index: err = %d", err);
+ ELSE_NOK
+ if (err == NC_NOERR) ncmpi_wait_all(ncid, 1, &reqid, &status);
+ start[j] = 0;
+ edge[j] = var_shape[i][j] + 1; /* edge error check */
+ err = ncmpi_iget_vara_$1(ncid, i, start, edge, value, &reqid);
+ IF (canConvert && err != NC_EEDGE)
+ error("bad index/edge: err = %d", err);
+ ELSE_NOK
+ if (err == NC_NOERR) ncmpi_wait_all(ncid, 1, &reqid, &status);
+ edge[j] = 1;
+ }
+ /* Check non-scalars for correct error returned even when */
+ /* there is nothing to get (edge[j]==0) */
+ if (var_rank[i] > 0) {
+ for (j = 0; j < var_rank[i]; j++) {
+ edge[j] = 0;
+ }
+ err = ncmpi_iget_vara_$1(BAD_ID, i, start, edge, value, &reqid);
+ IF (err != NC_EBADID)
+ error("bad ncid: err = %d", err);
+ ELSE_NOK
+ err = ncmpi_iget_vara_$1(ncid, BAD_VARID, start, edge, value, &reqid);
+ IF (err != NC_ENOTVAR)
+ error("bad var id: err = %d", err);
+ ELSE_NOK
+ for (j = 0; j < var_rank[i]; j++) {
+ if (var_dimid[i][j] > 0) { /* skip record dim */
+ start[j] = var_shape[i][j]; /* out of boundary check */
+ err = ncmpi_iget_vara_$1(ncid, i, start, edge, value, &reqid);
+ IF (canConvert && err != NC_EINVALCOORDS)
+ error("bad start: err = %d", err);
+ ELSE_NOK
+ if (err == NC_NOERR) ncmpi_wait_all(ncid, 1, &reqid, &status);
+ start[j] = 0;
+ }
+ }
+ err = ncmpi_iget_vara_$1(ncid, i, start, edge, value, &reqid);
+ if (canConvert) {
+ IF (err != NC_NOERR)
+ error("Error: ncmpi_iget_vara_$1 %s",ncmpi_strerror(err));
+ } else {
+ IF (err != NC_ECHAR)
+ error("wrong type: err = %d", err);
+ ELSE_NOK
+ }
+ if (err == NC_NOERR) ncmpi_wait_all(ncid, 1, &reqid, &status);
+ for (j = 0; j < var_rank[i]; j++) {
+ edge[j] = 1;
+ }
+ }
+ /* Choose a random point dividing each dim into 2 parts */
+ /* get 2^rank (nslabs) slabs so defined */
+ nslabs = 1;
+ for (j = 0; j < var_rank[i]; j++) {
+ mid[j] = roll( var_shape[i][j] );
+ nslabs *= 2;
+ }
+ /* bits of k determine whether to get lower or upper part of dim */
+ for (k = 0; k < nslabs; k++) {
+ nels = 1;
+ for (j = 0; j < var_rank[i]; j++) {
+ if ((k >> j) & 1) {
+ start[j] = 0;
+ edge[j] = mid[j];
+ } else {
+ start[j] = mid[j];
+ edge[j] = var_shape[i][j] - mid[j];
+ }
+ nels *= edge[j];
+ }
+ allInExtRange = allInIntRange = 1;
+ for (j = 0; j < nels; j++) {
+ err = toMixedBase(j, var_rank[i], edge, index);
+ IF (err != NC_NOERR)
+ error("error in toMixedBase 1");
+ for (d = 0; d < var_rank[i]; d++)
+ index[d] += start[d];
+ expect[j] = hash4(var_type[i], var_rank[i], index, NCT_ITYPE($1));
+ if (inRange3(expect[j],var_type[i], NCT_ITYPE($1))) {
+ IfCheckTextChar($1, var_type[i])
+ allInIntRange &= CheckRange($1, expect[j]);
+ } else {
+ allInExtRange = 0;
+ }
+ }
+ if (var_rank[i] == 0 && i%2)
+ err = ncmpi_iget_vara_$1(ncid, i, NULL, NULL, value, &reqid);
+ else
+ err = ncmpi_iget_vara_$1(ncid, i, start, edge, value, &reqid);
+ if (err == NC_NOERR)
+ ncmpi_wait_all(ncid, 1, &reqid, &status);
+ if (canConvert) {
+ if (allInExtRange) {
+ if (allInIntRange) {
+ IF (status != NC_NOERR)
+ error("%s", ncmpi_strerror(status));
+ ELSE_NOK
+ } else {
+ IF (status != NC_ERANGE)
+ error("Range error: status = %d", status);
+ ELSE_NOK
+ }
+ } else {
+ IF (status != NC_NOERR && status != NC_ERANGE)
+ error("OK or Range error: status = %d", status);
+ ELSE_NOK
+ }
+ num_err = 0;
+ for (j = 0; j < nels; j++) {
+ if (CheckNumRange($1, expect[j], var_type[i])) {
+ IF (!equal(value[j],expect[j],var_type[i],NCT_ITYPE($1))){
+ error("value read not that expected");
+ if (verbose) {
+ error("\n");
+ error("varid: %d, ", i);
+ error("var_name: %s, ", var_name[i]);
+ error("element number: %d ", j);
+ error("expect: %g", expect[j]);
+ error("got: %g", (double) value[j]);
+ }
+ num_err++;
+ }
+ }
+ }
+ if (num_err == 0) nok++;
+ } else {
+ IF (nels > 0 && err != NC_ECHAR)
+ error("wrong type: err = %d", err);
+ ELSE_NOK
+ }
+ }
+ }
+ err = ncmpi_close(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_close: %s", ncmpi_strerror(err));
+ return nok;
+}
+')dnl
+
+TEST_NC_IGET_VARA(text)
+TEST_NC_IGET_VARA(uchar)
+TEST_NC_IGET_VARA(schar)
+TEST_NC_IGET_VARA(short)
+TEST_NC_IGET_VARA(int)
+TEST_NC_IGET_VARA(long)
+TEST_NC_IGET_VARA(float)
+TEST_NC_IGET_VARA(double)
+TEST_NC_IGET_VARA(ushort)
+TEST_NC_IGET_VARA(uint)
+TEST_NC_IGET_VARA(longlong)
+TEST_NC_IGET_VARA(ulonglong)
+
+int
+test_ncmpi_iget_vars(void)
+{
+ int ncid;
+ int d;
+ int i;
+ int j;
+ int k;
+ int m;
+ int err, num_err;
+ int nels;
+ int nslabs;
+ int nstarts; /* number of different starts */
+ int nok = 0; /* count of valid comparisons */
+ MPI_Offset start[MAX_RANK];
+ MPI_Offset edge[MAX_RANK];
+ MPI_Offset index[MAX_RANK];
+ MPI_Offset index2[MAX_RANK];
+ MPI_Offset mid[MAX_RANK];
+ MPI_Offset count[MAX_RANK];
+ MPI_Offset sstride[MAX_RANK];
+ MPI_Offset stride[MAX_RANK];
+ double buf[MAX_NELS];
+ double expect[MAX_NELS];
+ int reqid, status;
+ MPI_Datatype datatype;
+
+ err = ncmpi_open(comm, testfile, NC_NOWRITE, info, &ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_open: %s", ncmpi_strerror(err));
+ for (i = 0; i < numVars; i++) {
+ datatype = nc_mpi_type(var_type[i]);
+ assert(var_rank[i] <= MAX_RANK);
+ assert(var_nels[i] <= MAX_NELS);
+ for (j = 0; j < var_rank[i]; j++) {
+ start[j] = 0;
+ edge[j] = 1;
+ stride[j] = 1;
+ }
+ err = ncmpi_iget_vars(BAD_ID, i, start, edge, stride, buf, 1, datatype, &reqid);
+ IF (err != NC_EBADID)
+ error("bad ncid: err = %d", err);
+ ELSE_NOK
+ err = ncmpi_iget_vars(ncid, BAD_VARID, start, edge, stride, buf, 1, datatype, &reqid);
+ IF (err != NC_ENOTVAR)
+ error("bad var id: err = %d", err);
+ ELSE_NOK
+ for (j = 0; j < var_rank[i]; j++) {
+ start[j] = var_shape[i][j]; /* out of boundary check */
+ err = ncmpi_iget_vars(ncid, i, start, edge, stride, buf, 1, datatype, &reqid);
+ IF (err != NC_EINVALCOORDS)
+ error("bad index: err = %d", err);
+ ELSE_NOK
+
+ start[j] = 0;
+ edge[j] = var_shape[i][j] + 1; /* edge error check */
+ err = ncmpi_iget_vars(ncid, i, start, edge, stride, buf, 1, datatype, &reqid);
+ IF (err != NC_EEDGE)
+ error("bad edge: err = %d", err);
+ ELSE_NOK
+ edge[j] = 1;
+ stride[j] = 0;
+ err = ncmpi_iget_vars(ncid, i, start, edge, stride, buf, 1, datatype, &reqid);
+ IF (err != NC_ESTRIDE)
+ error("bad stride: err = %d", err);
+ ELSE_NOK
+ stride[j] = 1;
+ }
+ /* Choose a random point dividing each dim into 2 parts */
+ /* get 2^rank (nslabs) slabs so defined */
+ nslabs = 1;
+ for (j = 0; j < var_rank[i]; j++) {
+ mid[j] = roll( var_shape[i][j] );
+ nslabs *= 2;
+ }
+ /* bits of k determine whether to get lower or upper part of dim */
+ /* choose random stride from 1 to edge */
+ for (k = 0; k < nslabs; k++) {
+ nstarts = 1;
+ for (j = 0; j < var_rank[i]; j++) {
+ if ((k >> j) & 1) {
+ start[j] = 0;
+ edge[j] = mid[j];
+ } else {
+ start[j] = mid[j];
+ edge[j] = var_shape[i][j] - mid[j];
+ }
+ sstride[j] = stride[j] = edge[j] > 0 ? 1+roll(edge[j]) : 1;
+ nstarts *= stride[j];
+ }
+ for (m = 0; m < nstarts; m++) {
+ err = toMixedBase(m, var_rank[i], sstride, index);
+ IF (err != NC_NOERR)
+ error("error in toMixedBase");
+ ELSE_NOK
+ nels = 1;
+ for (j = 0; j < var_rank[i]; j++) {
+ count[j] = 1 + (edge[j] - index[j] - 1) / stride[j];
+ nels *= count[j];
+ index[j] += start[j];
+ }
+ /* Random choice of forward or backward */
+/* TODO
+ if ( roll(2) ) {
+ for (j = 0; j < var_rank[i]; j++) {
+ index[j] += (count[j] - 1) * stride[j];
+ stride[j] = -stride[j];
+ }
+ }
+*/
+ for (j = 0; j < nels; j++) {
+ err = toMixedBase(j, var_rank[i], count, index2);
+ IF (err != NC_NOERR)
+ error("error in toMixedBase 1");
+ ELSE_NOK
+ for (d = 0; d < var_rank[i]; d++)
+ index2[d] = index[d] + index2[d] * stride[d];
+ expect[j] = hash(var_type[i], var_rank[i], index2);
+ }
+ if (var_rank[i] == 0 && i%2 )
+ err = ncmpi_iget_vars(ncid, i, NULL, NULL, NULL, buf, 1, datatype, &reqid);
+ else
+ err = ncmpi_iget_vars(ncid, i, index, count, stride, buf, nels, datatype, &reqid);
+ IF (err != NC_NOERR)
+ error("%s", ncmpi_strerror(err));
+ ELSE_NOK
+
+ err = ncmpi_wait_all(ncid, 1, &reqid, &status);
+ IF (err != NC_NOERR)
+ error("%s", ncmpi_strerror(err));
+ ELSE_NOK
+
+ num_err = 0;
+ for (j = 0; j < nels; j++) {
+ double got;
+ char *p = (char *) buf;
+ p += j * nctypelen(var_type[i]);
+ if (inRange(expect[j],var_type[i])) {
+ err = nc2dbl(var_type[i], p, &got);
+ IF (err != NC_NOERR)
+ error("error in nc2dbl");
+ IF (!equal2(got,expect[j],var_type[i])) {
+ error("value read not that expected");
+ if (verbose) {
+ error("\n");
+ error("varid: %d, ", i);
+ error("var_name: %s, ", var_name[i]);
+ error("element number: %d ", j);
+ error("expect: %g, ", expect[j]);
+ error("got: %g", got);
+ }
+ num_err++;
+ }
+ }
+ }
+ if (num_err == 0) nok++;
+ }
+ }
+
+ }
+ err = ncmpi_close(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_close: %s", ncmpi_strerror(err));
+ return nok;
+}
+
+dnl TEST_NC_IGET_VARS(TYPE)
+dnl
+define(`TEST_NC_IGET_VARS',dnl
+`dnl
+int
+test_ncmpi_iget_vars_$1(void)
+{
+ int ncid;
+ int d;
+ int i;
+ int j;
+ int k;
+ int m;
+ int err, num_err;
+ int allInExtRange; /* all values within external range? */
+ int allInIntRange; /* all values within internal range? */
+ int nels;
+ int nslabs;
+ int nstarts; /* number of different starts */
+ int nok = 0; /* count of valid comparisons */
+ MPI_Offset start[MAX_RANK];
+ MPI_Offset edge[MAX_RANK];
+ MPI_Offset index[MAX_RANK];
+ MPI_Offset index2[MAX_RANK];
+ MPI_Offset mid[MAX_RANK];
+ MPI_Offset count[MAX_RANK];
+ MPI_Offset sstride[MAX_RANK];
+ MPI_Offset stride[MAX_RANK];
+ int canConvert; /* Both text or both numeric */
+ double expect[MAX_NELS];
+ $1 value[MAX_NELS];
+ int reqid, status;
+
+ err = ncmpi_open(comm, testfile, NC_NOWRITE, info, &ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_open: %s", ncmpi_strerror(err));
+ for (i = 0; i < numVars; i++) {
+ canConvert = (var_type[i] == NC_CHAR) CheckText($1);
+ assert(var_rank[i] <= MAX_RANK);
+ assert(var_nels[i] <= MAX_NELS);
+ for (j = 0; j < var_rank[i]; j++) {
+ start[j] = 0;
+ edge[j] = 1;
+ stride[j] = 1;
+ }
+ err = ncmpi_iget_vars_$1(BAD_ID, i, start, edge, stride, value, &reqid);
+ IF (err != NC_EBADID)
+ error("bad ncid: err = %d", err);
+ ELSE_NOK
+ err = ncmpi_iget_vars_$1(ncid, BAD_VARID, start, edge, stride, value, &reqid);
+ IF (err != NC_ENOTVAR)
+ error("bad var id: err = %d", err);
+ ELSE_NOK
+ for (j = 0; j < var_rank[i]; j++) {
+ start[j] = var_shape[i][j]; /* out of boundary check */
+ err = ncmpi_iget_vars_$1(ncid, i, start, edge, stride, value, &reqid);
+ if (!canConvert) {
+ IF (err != NC_ECHAR)
+ error("conversion: err = %d", err);
+ } else {
+ IF (err != NC_EINVALCOORDS)
+ error("bad index: err = %d", err);
+ ELSE_NOK
+
+ start[j] = 0;
+ edge[j] = var_shape[i][j] + 1; /* edge error check */
+ err = ncmpi_iget_vars_$1(ncid, i, start, edge, stride, value, &reqid);
+ IF (err != NC_EEDGE)
+ error("bad edge: err = %d", err);
+ ELSE_NOK
+ edge[j] = 1;
+ stride[j] = 0;
+ err = ncmpi_iget_vars_$1(ncid, i, start, edge, stride, value, &reqid);
+ IF (err != NC_ESTRIDE)
+ error("bad stride: err = %d", err);
+ ELSE_NOK
+ stride[j] = 1;
+ }
+ }
+ /* Choose a random point dividing each dim into 2 parts */
+ /* get 2^rank (nslabs) slabs so defined */
+ nslabs = 1;
+ for (j = 0; j < var_rank[i]; j++) {
+ mid[j] = roll( var_shape[i][j] );
+ nslabs *= 2;
+ }
+ /* bits of k determine whether to get lower or upper part of dim */
+ /* choose random stride from 1 to edge */
+ for (k = 0; k < nslabs; k++) {
+ nstarts = 1;
+ for (j = 0; j < var_rank[i]; j++) {
+ if ((k >> j) & 1) {
+ start[j] = 0;
+ edge[j] = mid[j];
+ } else {
+ start[j] = mid[j];
+ edge[j] = var_shape[i][j] - mid[j];
+ }
+ sstride[j] = stride[j] = edge[j] > 0 ? 1+roll(edge[j]) : 1;
+ nstarts *= stride[j];
+ }
+ for (m = 0; m < nstarts; m++) {
+ err = toMixedBase(m, var_rank[i], sstride, index);
+ IF (err != NC_NOERR)
+ error("error in toMixedBase");
+ ELSE_NOK
+ nels = 1;
+ for (j = 0; j < var_rank[i]; j++) {
+ count[j] = 1 + (edge[j] - index[j] - 1) / stride[j];
+ nels *= count[j];
+ index[j] += start[j];
+ }
+ /* Random choice of forward or backward */
+/* TODO
+ if ( roll(2) ) {
+ for (j = 0; j < var_rank[i]; j++) {
+ index[j] += (count[j] - 1) * stride[j];
+ stride[j] = -stride[j];
+ }
+ }
+*/
+ allInExtRange = allInIntRange = 1;
+ for (j = 0; j < nels; j++) {
+ err = toMixedBase(j, var_rank[i], count, index2);
+ IF (err != NC_NOERR)
+ error("error in toMixedBase 1");
+ ELSE_NOK
+ for (d = 0; d < var_rank[i]; d++)
+ index2[d] = index[d] + index2[d] * stride[d];
+ expect[j] = hash4(var_type[i], var_rank[i], index2,
+ NCT_ITYPE($1));
+ if (inRange3(expect[j],var_type[i],NCT_ITYPE($1))) {
+ IfCheckTextChar($1, var_type[i])
+ allInIntRange &= CheckRange($1, expect[j]);
+ } else {
+ allInExtRange = 0;
+ }
+ }
+ if (var_rank[i] == 0 && i%2 )
+ err = ncmpi_iget_vars_$1(ncid, i, NULL, NULL, NULL, value, &reqid);
+ else
+ err = ncmpi_iget_vars_$1(ncid, i, index, count, stride, value, &reqid);
+ if (err == NC_NOERR)
+ ncmpi_wait_all(ncid, 1, &reqid, &status);
+ if (canConvert) {
+ if (allInExtRange) {
+ if (allInIntRange) {
+ IF (status != NC_NOERR)
+ error("%s", ncmpi_strerror(status));
+ ELSE_NOK
+ } else {
+ IF (status != NC_ERANGE)
+ error("Range error: status = %d", status);
+ ELSE_NOK
+ }
+ } else {
+ IF (status != NC_NOERR && status != NC_ERANGE)
+ error("OK or Range error: status = %d", status);
+ ELSE_NOK
+ }
+ num_err = 0;
+ for (j = 0; j < nels; j++) {
+ if (CheckNumRange($1, expect[j], var_type[i])) {
+ IF (!equal(value[j],expect[j],var_type[i], NCT_ITYPE($1))){
+ error("value read not that expected");
+ if (verbose) {
+ error("\n");
+ error("varid: %d, ", i);
+ error("var_name: %s, ", var_name[i]);
+ error("element number: %d ", j);
+ error("expect: %g, ", expect[j]);
+ error("got: %g", (double) value[j]);
+ }
+ num_err++;
+ }
+ }
+ }
+ if (num_err == 0) nok++;
+ } else {
+ IF (nels > 0 && err != NC_ECHAR)
+ error("wrong type: err = %d", err);
+ ELSE_NOK
+ }
+ }
+ }
+
+ }
+ err = ncmpi_close(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_close: %s", ncmpi_strerror(err));
+ return nok;
+}
+')dnl
+
+TEST_NC_IGET_VARS(text)
+TEST_NC_IGET_VARS(uchar)
+TEST_NC_IGET_VARS(schar)
+TEST_NC_IGET_VARS(short)
+TEST_NC_IGET_VARS(int)
+TEST_NC_IGET_VARS(long)
+TEST_NC_IGET_VARS(float)
+TEST_NC_IGET_VARS(double)
+TEST_NC_IGET_VARS(ushort)
+TEST_NC_IGET_VARS(uint)
+TEST_NC_IGET_VARS(longlong)
+TEST_NC_IGET_VARS(ulonglong)
+
+int
+test_ncmpi_iget_varm(void)
+{
+ int ncid;
+ int d;
+ int i;
+ int j;
+ int k;
+ int m;
+ int err, num_err;
+ int nels;
+ int nslabs;
+ int nstarts; /* number of different starts */
+ int nok = 0; /* count of valid comparisons */
+ MPI_Offset start[MAX_RANK];
+ MPI_Offset edge[MAX_RANK];
+ MPI_Offset index[MAX_RANK];
+ MPI_Offset index2[MAX_RANK];
+ MPI_Offset mid[MAX_RANK];
+ MPI_Offset count[MAX_RANK];
+ MPI_Offset sstride[MAX_RANK];
+ MPI_Offset stride[MAX_RANK];
+ MPI_Offset imap[MAX_RANK];
+ double buf[MAX_NELS], expect[MAX_NELS];
+ int reqid, status;
+ MPI_Datatype datatype;
+
+ err = ncmpi_open(comm, testfile, NC_NOWRITE, info, &ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_open: %s", ncmpi_strerror(err));
+ for (i = 0; i < numVars; i++) {
+ datatype = nc_mpi_type(var_type[i]);
+ assert(var_rank[i] <= MAX_RANK);
+ assert(var_nels[i] <= MAX_NELS);
+ for (j = 0; j < var_rank[i]; j++) {
+ start[j] = 0;
+ edge[j] = 1;
+ stride[j] = 1;
+ imap[j] = 1;
+ }
+ err = ncmpi_iget_varm(BAD_ID, i, start, edge, stride, imap, buf, 1, datatype, &reqid);
+ IF (err != NC_EBADID)
+ error("bad ncid: err = %d", err);
+ ELSE_NOK
+ err = ncmpi_iget_varm(ncid, BAD_VARID, start, edge, stride, imap, buf, 1, datatype, &reqid);
+ IF (err != NC_ENOTVAR)
+ error("bad var id: err = %d", err);
+ ELSE_NOK
+ for (j = 0; j < var_rank[i]; j++) {
+ start[j] = var_shape[i][j]; /* out of boundary check */
+ err = ncmpi_iget_varm(ncid, i, start, edge, stride, imap, buf, 1, datatype, &reqid);
+ IF (err != NC_EINVALCOORDS)
+ error("bad index: err = %d", err);
+ ELSE_NOK
+
+ start[j] = 0;
+ edge[j] = var_shape[i][j] + 1; /* edge error check */
+ err = ncmpi_iget_varm(ncid, i, start, edge, stride, imap, buf, 1, datatype, &reqid);
+ IF (err != NC_EEDGE)
+ error("bad edge: err = %d", err);
+ ELSE_NOK
+ edge[j] = 1;
+ stride[j] = 0;
+ err = ncmpi_iget_varm(ncid, i, start, edge, stride, imap, buf, 1, datatype, &reqid);
+ IF (err != NC_ESTRIDE)
+ error("bad stride: err = %d", err);
+ ELSE_NOK
+ stride[j] = 1;
+ }
+ /* Choose a random point dividing each dim into 2 parts */
+ /* get 2^rank (nslabs) slabs so defined */
+ nslabs = 1;
+ for (j = 0; j < var_rank[i]; j++) {
+ mid[j] = roll( var_shape[i][j] );
+ nslabs *= 2;
+ }
+ /* bits of k determine whether to get lower or upper part of dim */
+ /* choose random stride from 1 to edge */
+ for (k = 0; k < nslabs; k++) {
+ nstarts = 1;
+ for (j = 0; j < var_rank[i]; j++) {
+ if ((k >> j) & 1) {
+ start[j] = 0;
+ edge[j] = mid[j];
+ } else {
+ start[j] = mid[j];
+ edge[j] = var_shape[i][j] - mid[j];
+ }
+ sstride[j] = stride[j] = edge[j] > 0 ? 1+roll(edge[j]) : 1;
+ nstarts *= stride[j];
+ }
+ for (m = 0; m < nstarts; m++) {
+ err = toMixedBase(m, var_rank[i], sstride, index);
+ IF (err != NC_NOERR)
+ error("error in toMixedBase");
+ ELSE_NOK
+ nels = 1;
+ for (j = 0; j < var_rank[i]; j++) {
+ count[j] = 1 + (edge[j] - index[j] - 1) / stride[j];
+ index[j] += start[j];
+ nels *= count[j];
+ }
+ /* Random choice of forward or backward */
+/* TODO
+ if ( roll(2) ) {
+ for (j = 0; j < var_rank[i]; j++) {
+ index[j] += (count[j] - 1) * stride[j];
+ stride[j] = -stride[j];
+ }
+ }
+ */
+ if (var_rank[i] > 0) {
+ j = var_rank[i] - 1;
+ imap[j] = 1;
+ for (; j > 0; j--)
+ imap[j-1] = imap[j] * count[j];
+ }
+ for (j = 0; j < nels; j++) {
+ err = toMixedBase(j, var_rank[i], count, index2);
+ IF (err != NC_NOERR)
+ error("error in toMixedBase 1");
+ ELSE_NOK
+ for (d = 0; d < var_rank[i]; d++)
+ index2[d] = index[d] + index2[d] * stride[d];
+ expect[j] = hash(var_type[i], var_rank[i], index2);
+ }
+ if (var_rank[i] == 0 && i%2 )
+ err = ncmpi_iget_varm(ncid,i,NULL,NULL,NULL,NULL,buf, 1, datatype, &reqid);
+ else
+ err = ncmpi_iget_varm(ncid,i,index,count,stride,imap,buf, nels, datatype, &reqid);
+ IF (err != NC_NOERR)
+ error("%s", ncmpi_strerror(err));
+ ELSE_NOK
+
+ err = ncmpi_wait_all(ncid, 1, &reqid, &status);
+ IF (err != NC_NOERR)
+ error("%s", ncmpi_strerror(err));
+ ELSE_NOK
+
+ num_err = 0;
+ for (j = 0; j < nels; j++) {
+ double got;
+ char *p = (char *) buf;
+ p += j * nctypelen(var_type[i]);
+ if (inRange(expect[j],var_type[i])) {
+ err = nc2dbl(var_type[i], p, &got);
+ IF (err != NC_NOERR)
+ error("error in nc2dbl");
+ IF (!equal2(got,expect[j],var_type[i])) {
+ error("value read not that expected");
+ if (verbose) {
+ error("\n");
+ error("varid: %d, ", i);
+ error("var_name: %s, ", var_name[i]);
+ error("element number: %d ", j);
+ error("expect: %g, ", expect[j]);
+ error("got: %g", got);
+ }
+ num_err++;
+ }
+ }
+ if (num_err == 0) nok++;
+ }
+ }
+ }
+ }
+ err = ncmpi_close(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_close: %s", ncmpi_strerror(err));
+ return nok;
+}
+
+dnl TEST_NC_IGET_VARM(TYPE)
+dnl
+define(`TEST_NC_IGET_VARM',dnl
+`dnl
+int
+test_ncmpi_iget_varm_$1(void)
+{
+ int ncid;
+ int d;
+ int i;
+ int j;
+ int k;
+ int m;
+ int err, num_err;
+ int allInExtRange; /* all values within external range? */
+ int allInIntRange; /* all values within internal range? */
+ int nels;
+ int nslabs;
+ int nstarts; /* number of different starts */
+ int nok = 0; /* count of valid comparisons */
+ MPI_Offset start[MAX_RANK];
+ MPI_Offset edge[MAX_RANK];
+ MPI_Offset index[MAX_RANK];
+ MPI_Offset index2[MAX_RANK];
+ MPI_Offset mid[MAX_RANK];
+ MPI_Offset count[MAX_RANK];
+ MPI_Offset sstride[MAX_RANK];
+ MPI_Offset stride[MAX_RANK];
+ MPI_Offset imap[MAX_RANK];
+ int canConvert; /* Both text or both numeric */
+ double expect[MAX_NELS];
+ $1 value[MAX_NELS];
+ int reqid, status;
+
+ err = ncmpi_open(comm, testfile, NC_NOWRITE, info, &ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_open: %s", ncmpi_strerror(err));
+ for (i = 0; i < numVars; i++) {
+ canConvert = (var_type[i] == NC_CHAR) CheckText($1);
+ assert(var_rank[i] <= MAX_RANK);
+ assert(var_nels[i] <= MAX_NELS);
+ for (j = 0; j < var_rank[i]; j++) {
+ start[j] = 0;
+ edge[j] = 1;
+ stride[j] = 1;
+ imap[j] = 1;
+ }
+ err = ncmpi_iget_varm_$1(BAD_ID, i, start, edge, stride, imap, value, &reqid);
+ IF (err != NC_EBADID)
+ error("bad ncid: err = %d", err);
+ ELSE_NOK
+ err = ncmpi_iget_varm_$1(ncid, BAD_VARID, start, edge, stride, imap, value, &reqid);
+ IF (err != NC_ENOTVAR)
+ error("bad var id: err = %d", err);
+ ELSE_NOK
+ for (j = 0; j < var_rank[i]; j++) {
+ start[j] = var_shape[i][j]; /* out of boundary check */
+ err = ncmpi_iget_varm_$1(ncid, i, start, edge, stride, imap, value, &reqid);
+ if (!canConvert) {
+ IF (err != NC_ECHAR)
+ error("conversion: err = %d", err);
+ } else {
+ IF (err != NC_EINVALCOORDS)
+ error("bad index: err = %d", err);
+ ELSE_NOK
+
+ start[j] = 0;
+ edge[j] = var_shape[i][j] + 1; /* edge error check */
+ err = ncmpi_iget_varm_$1(ncid, i, start, edge, stride, imap, value, &reqid);
+ IF (err != NC_EEDGE)
+ error("bad edge: err = %d", err);
+ ELSE_NOK
+ edge[j] = 1;
+ stride[j] = 0;
+ err = ncmpi_iget_varm_$1(ncid, i, start, edge, stride, imap, value, &reqid);
+ IF (err != NC_ESTRIDE)
+ error("bad stride: err = %d", err);
+ ELSE_NOK
+ stride[j] = 1;
+ }
+ }
+ /* Choose a random point dividing each dim into 2 parts */
+ /* get 2^rank (nslabs) slabs so defined */
+ nslabs = 1;
+ for (j = 0; j < var_rank[i]; j++) {
+ mid[j] = roll( var_shape[i][j] );
+ nslabs *= 2;
+ }
+ /* bits of k determine whether to get lower or upper part of dim */
+ /* choose random stride from 1 to edge */
+ for (k = 0; k < nslabs; k++) {
+ nstarts = 1;
+ for (j = 0; j < var_rank[i]; j++) {
+ if ((k >> j) & 1) {
+ start[j] = 0;
+ edge[j] = mid[j];
+ } else {
+ start[j] = mid[j];
+ edge[j] = var_shape[i][j] - mid[j];
+ }
+ sstride[j] = stride[j] = edge[j] > 0 ? 1+roll(edge[j]) : 1;
+ nstarts *= stride[j];
+ }
+ for (m = 0; m < nstarts; m++) {
+ err = toMixedBase(m, var_rank[i], sstride, index);
+ IF (err != NC_NOERR)
+ error("error in toMixedBase");
+ ELSE_NOK
+ nels = 1;
+ for (j = 0; j < var_rank[i]; j++) {
+ count[j] = 1 + (edge[j] - index[j] - 1) / stride[j];
+ nels *= count[j];
+ index[j] += start[j];
+ }
+ /* Random choice of forward or backward */
+/* TODO
+ if ( roll(2) ) {
+ for (j = 0; j < var_rank[i]; j++) {
+ index[j] += (count[j] - 1) * stride[j];
+ stride[j] = -stride[j];
+ }
+ }
+ */
+ if (var_rank[i] > 0) {
+ j = var_rank[i] - 1;
+ imap[j] = 1;
+ for (; j > 0; j--)
+ imap[j-1] = imap[j] * count[j];
+ }
+ allInExtRange = allInIntRange = 1;
+ for (j = 0; j < nels; j++) {
+ err = toMixedBase(j, var_rank[i], count, index2);
+ IF (err != NC_NOERR)
+ error("error in toMixedBase 1");
+ ELSE_NOK
+ for (d = 0; d < var_rank[i]; d++)
+ index2[d] = index[d] + index2[d] * stride[d];
+ expect[j] = hash4(var_type[i], var_rank[i], index2,
+ NCT_ITYPE($1));
+ if (inRange3(expect[j],var_type[i],NCT_ITYPE($1))) {
+ IfCheckTextChar($1, var_type[i])
+ allInIntRange &= CheckRange($1, expect[j]);
+ } else {
+ allInExtRange = 0;
+ }
+ }
+ if (var_rank[i] == 0 && i%2 )
+ err = ncmpi_iget_varm_$1(ncid,i,NULL,NULL,NULL,NULL,value, &reqid);
+ else
+ err = ncmpi_iget_varm_$1(ncid,i,index,count,stride,imap,value, &reqid);
+ if (err == NC_NOERR)
+ ncmpi_wait_all(ncid, 1, &reqid, &status);
+ if (canConvert) {
+ if (allInExtRange) {
+ if (allInIntRange) {
+ IF (status != NC_NOERR)
+ error("%s", ncmpi_strerror(status));
+ ELSE_NOK
+ } else {
+ IF (status != NC_ERANGE)
+ error("Range error: status = %d", status);
+ ELSE_NOK
+ }
+ } else {
+ IF (status != NC_NOERR && status != NC_ERANGE)
+ error("OK or Range error: status = %d", status);
+ ELSE_NOK
+ }
+ num_err = 0;
+ for (j = 0; j < nels; j++) {
+ if (CheckNumRange($1, expect[j], var_type[i])) {
+ IF (!equal(value[j],expect[j],var_type[i], NCT_ITYPE($1))){
+ error("value read not that expected");
+ if (verbose) {
+ error("\n");
+ error("varid: %d, ", i);
+ error("var_name: %s, ", var_name[i]);
+ error("element number: %d ", j);
+ error("expect: %g, ", expect[j]);
+ error("got: %g", (double) value[j]);
+ }
+ num_err++;
+ }
+ }
+ }
+ if (num_err == 0) nok++;
+ } else {
+ IF (nels > 0 && err != NC_ECHAR)
+ error("wrong type: err = %d", err);
+ ELSE_NOK
+ }
+ }
+ }
+ }
+ err = ncmpi_close(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_close: %s", ncmpi_strerror(err));
+ return nok;
+}
+')dnl
+
+TEST_NC_IGET_VARM(text)
+TEST_NC_IGET_VARM(uchar)
+TEST_NC_IGET_VARM(schar)
+TEST_NC_IGET_VARM(short)
+TEST_NC_IGET_VARM(int)
+TEST_NC_IGET_VARM(long)
+TEST_NC_IGET_VARM(float)
+TEST_NC_IGET_VARM(double)
+TEST_NC_IGET_VARM(ushort)
+TEST_NC_IGET_VARM(uint)
+TEST_NC_IGET_VARM(longlong)
+TEST_NC_IGET_VARM(ulonglong)
+
+
diff --git a/test/nc_test/test_iput.m4 b/test/nc_test/test_iput.m4
new file mode 100644
index 0000000..9a5423e
--- /dev/null
+++ b/test/nc_test/test_iput.m4
@@ -0,0 +1,1732 @@
+dnl This is m4 source.
+dnl Process using m4 to produce 'C' language file.
+dnl
+dnl If you see this line, you can ignore the next one.
+/* Do not edit this file. It is produced from the corresponding .m4 source */
+dnl
+/*
+ * Copyright (C) 2003, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ */
+/* $Id: test_iput.m4 2295 2016-01-06 20:28:09Z wkliao $ */
+
+
+undefine(`index')dnl
+dnl dnl dnl
+dnl
+dnl Macros
+dnl
+dnl dnl dnl
+dnl
+dnl Upcase(str)
+dnl
+define(`Upcase',dnl
+`dnl
+translit($1, abcdefghijklmnopqrstuvwxyz, ABCDEFGHIJKLMNOPQRSTUVWXYZ)')dnl
+dnl dnl dnl
+dnl
+dnl NCT_ITYPE(type)
+dnl
+define(`NCT_ITYPE', ``NCT_'Upcase($1)')dnl
+dnl
+
+define(`CheckText', `ifelse(`$1',`text', , `== (NCT_ITYPE($1) == NCT_TEXT)')')dnl
+define(`IfCheckTextChar', `ifelse(`$1',`text', `if ($2 != NC_CHAR)')')dnl
+define(`CheckNumRange',
+ `ifelse(`$1',`text', `1',
+ `inRange3($2,$3,NCT_ITYPE($1)) && ($2 >= $1_min && $2 <= $1_max)')')dnl
+define(`CheckRange3',
+ `ifelse(`$1',`text', `1',
+ `inRange3($2,$3,NCT_ITYPE($1))')')dnl
+
+
+#include "tests.h"
+
+dnl HASH(TYPE)
+dnl
+define(`HASH',dnl
+`dnl
+/*
+ * ensure hash value within range for internal TYPE
+ */
+static
+double
+hash_$1(
+ const nc_type type,
+ const int rank,
+ const MPI_Offset *index,
+ const nct_itype itype)
+{
+ const double min = $1_min;
+ const double max = $1_max;
+
+ return MAX(min, MIN(max, hash4( type, rank, index, itype)));
+}
+')dnl
+
+dnl HASH(text)
+#define hash_text hash4
+
+HASH(uchar)
+HASH(schar)
+HASH(short)
+HASH(int)
+HASH(long)
+HASH(float)
+HASH(double)
+HASH(ushort)
+HASH(uint)
+HASH(longlong)
+HASH(ulonglong)
+
+
+dnl CHECK_VARS(TYPE)
+dnl
+define(`CHECK_VARS',dnl
+`dnl
+/*
+ * check all vars in file which are (text/numeric) compatible with TYPE
+ */
+static
+int
+check_vars_$1(const char *filename)
+{
+ int ncid; /* netCDF id */
+ MPI_Offset index[MAX_RANK];
+ int err; /* status */
+ int d;
+ int i;
+ size_t j;
+ $1 value;
+ nc_type datatype;
+ int ndims;
+ int dimids[MAX_RANK];
+ char name[NC_MAX_NAME];
+ MPI_Offset length;
+ int canConvert; /* Both text or both numeric */
+ int nok = 0; /* count of valid comparisons */
+ double expect;
+
+ err = ncmpi_open(comm, filename, NC_NOWRITE, info, &ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_open: %s", ncmpi_strerror(err));
+
+ for (i = 0; i < numVars; i++) {
+ canConvert = (var_type[i] == NC_CHAR) CheckText($1);
+ if (canConvert) {
+ err = ncmpi_inq_var(ncid, i, name, &datatype, &ndims, dimids, NULL);
+ IF (err != NC_NOERR)
+ error("ncmpi_inq_var: %s", ncmpi_strerror(err));
+ IF (strcmp(name, var_name[i]) != 0)
+ error("Unexpected var_name");
+ IF (datatype != var_type[i])
+ error("Unexpected type");
+ IF (ndims != var_rank[i])
+ error("Unexpected rank");
+ for (j = 0; j < ndims; j++) {
+ err = ncmpi_inq_dim(ncid, dimids[j], 0, &length);
+ IF (err != NC_NOERR)
+ error("ncmpi_inq_dim: %s", ncmpi_strerror(err));
+ IF (length != var_shape[i][j])
+ error("Unexpected shape");
+ }
+ for (j = 0; j < var_nels[i]; j++) {
+ err = toMixedBase(j, var_rank[i], var_shape[i], index);
+ IF (err != NC_NOERR)
+ error("error in toMixedBase 2");
+ expect = hash4( var_type[i], var_rank[i], index, NCT_ITYPE($1));
+ err = ncmpi_get_var1_$1_all(ncid, i, index, &value);
+ if (CheckNumRange($1, expect, datatype)) {
+ IF (err != NC_NOERR) {
+ error("error in ncmpi_get_var1_$1_all $s",__func__);
+ } else IF (!equal(value,expect,var_type[i],NCT_ITYPE($1))) {
+ error("Var value read not that expected");
+ if (verbose) {
+ error("\n");
+ error("varid: %d, ", i);
+ error("var_name: %s, ", var_name[i]);
+ error("var_type: %s, ", s_nc_type(var_type[i]));
+ error("put type: $1, ");
+ error("index:");
+ for (d = 0; d < var_rank[i]; d++)
+ error(" %d", index[d]);
+ error(", expect: %g, ", expect);
+ error("got: %g", (double) value);
+ }
+ } else {
+ ++nok;
+ }
+ }
+ }
+ }
+ }
+ err = ncmpi_close(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_close: %s", ncmpi_strerror(err));
+ return nok;
+}
+')dnl
+
+CHECK_VARS(text)
+CHECK_VARS(uchar)
+CHECK_VARS(schar)
+CHECK_VARS(short)
+CHECK_VARS(int)
+CHECK_VARS(long)
+CHECK_VARS(float)
+CHECK_VARS(double)
+CHECK_VARS(ushort)
+CHECK_VARS(uint)
+CHECK_VARS(longlong)
+CHECK_VARS(ulonglong)
+
+static double
+hash2nc(const nc_type var_type, int var_rank, MPI_Offset *index)
+{
+ double min;
+ double max;
+
+ switch (var_type) {
+ case NC_CHAR: min = X_CHAR_MIN; max = X_CHAR_MAX; break;
+ case NC_BYTE: min = X_BYTE_MIN; max = X_BYTE_MAX; break;
+ case NC_SHORT: min = X_SHORT_MIN; max = X_SHORT_MAX; break;
+ case NC_INT: min = X_INT_MIN; max = X_INT_MAX; break;
+ case NC_FLOAT: min = X_FLOAT_MIN; max = X_FLOAT_MAX; break;
+ case NC_DOUBLE: min = X_DOUBLE_MIN; max = X_DOUBLE_MAX; break;
+ case NC_UBYTE: min = 0; max = X_UCHAR_MAX; break;
+ case NC_USHORT: min = 0; max = X_USHORT_MAX; break;
+ case NC_UINT: min = 0; max = X_UINT_MAX; break;
+ case NC_INT64: min = X_INT64_MIN; max = X_INT64_MAX; break;
+ case NC_UINT64: min = 0; max = X_UINT64_MAX; break;
+ default:
+ return NC_EBADTYPE;
+ }
+
+ return MAX(min, MIN(max, hash(var_type, var_rank, index)));
+}
+
+static int
+dbls2ncs(int nels, int var_type, double *inBuf, void *outBuf)
+{
+ int i;
+ char *p = (char*)outBuf;
+ for (i=0; i<nels; i++) {
+ switch (var_type) {
+ case NC_CHAR: {char a = inBuf[i]; memcpy(p, &a, 1); break;}
+ case NC_BYTE: {schar a = inBuf[i]; memcpy(p, &a, 1); break;}
+ case NC_SHORT: {short a = inBuf[i]; memcpy(p, &a, 2); break;}
+ case NC_INT: {int a = inBuf[i]; memcpy(p, &a, 4); break;}
+ case NC_FLOAT: {float a = inBuf[i]; memcpy(p, &a, 4); break;}
+ case NC_DOUBLE: {double a = inBuf[i]; memcpy(p, &a, 8); break;}
+ case NC_UBYTE: {uchar a = inBuf[i]; memcpy(p, &a, 1); break;}
+ case NC_USHORT: {ushort a = inBuf[i]; memcpy(p, &a, 2); break;}
+ case NC_UINT: {uint a = inBuf[i]; memcpy(p, &a, 4); break;}
+ case NC_INT64: {longlong a = inBuf[i]; memcpy(p, &a, 8); break;}
+ case NC_UINT64: {ulonglong a = inBuf[i]; memcpy(p, &a, 8); break;}
+ default:
+ return NC_EBADTYPE;
+ }
+ p += nctypelen(var_type);
+ }
+ return NC_NOERR;
+}
+
+int
+test_ncmpi_iput_var1(void)
+{
+ int ncid, nok=0;
+ int i;
+ int j;
+ int err;
+ MPI_Offset index[MAX_RANK];
+ double value = 5; /* any value would do - only for error cases */
+ int reqid, status=NC_NOERR;
+ MPI_Datatype datatype;
+
+ err = ncmpi_create(comm, scratch, NC_CLOBBER|extra_flags, info, &ncid);
+ IF (err != NC_NOERR) {
+ error("ncmpi_create: %s", ncmpi_strerror(err));
+ return nok;
+ }
+ def_dims(ncid);
+ def_vars(ncid);
+ err = ncmpi_enddef(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_enddef: %s", ncmpi_strerror(err));
+
+ for (i = 0; i < numVars; i++) {
+ datatype = nc_mpi_type(var_type[i]);
+ for (j = 0; j < var_rank[i]; j++)
+ index[j] = 0;
+ err = ncmpi_iput_var1(BAD_ID, i, index, &value, 1, datatype, &reqid);
+ IF (err != NC_EBADID)
+ error("bad ncid: err = %d", err);
+ ELSE_NOK
+ err = ncmpi_iput_var1(ncid, BAD_VARID, index, &value, 1, datatype, &reqid);
+ IF (err != NC_ENOTVAR)
+ error("bad var id: err = %d", err);
+ ELSE_NOK
+ for (j = 0; j < var_rank[i]; j++) {
+ if (var_dimid[i][j] > 0) { /* skip record dim */
+ index[j] = var_shape[i][j]; /* out of boundary check */
+ err = ncmpi_iput_var1(ncid, i, index, &value, 1, datatype, &reqid);
+ IF (err != NC_EINVALCOORDS)
+ error("bad index: err = %d", err);
+ ELSE_NOK
+ index[j] = 0;
+ }
+ }
+ for (j = 0; j < var_nels[i]; j++) {
+ double buf;
+ err = toMixedBase(j, var_rank[i], var_shape[i], index);
+ IF (err != NC_NOERR)
+ error("error in toMixedBase 1");
+ value = hash2nc(var_type[i], var_rank[i], index);
+ err = dbl2nc(value, var_type[i], &buf);
+ IF (err != NC_NOERR)
+ error("error in dbl2nc");
+
+ if (var_rank[i] == 0 && i%2 == 0)
+ err = ncmpi_iput_var1(ncid, i, NULL, &buf, 1, datatype, &reqid);
+ else
+ err = ncmpi_iput_var1(ncid, i, index, &buf, 1, datatype, &reqid);
+ IF (err != NC_NOERR)
+ error("ncmpi_iput_var1: %s", ncmpi_strerror(err));
+ ELSE_NOK
+
+ err = ncmpi_wait_all(ncid, 1, &reqid, &status);
+ IF (err != NC_NOERR)
+ error("ncmpi_wait_all: %s", ncmpi_strerror(err));
+ ELSE_NOK
+ }
+ }
+
+ check_vars(ncid);
+
+ err = ncmpi_close(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_close: %s", ncmpi_strerror(err));
+
+ err = ncmpi_delete(scratch, info);
+ IF (err != NC_NOERR)
+ error("remove of %s failed", scratch);
+ return nok;
+}
+
+dnl TEST_NC_IPUT_VAR1(TYPE)
+dnl
+define(`TEST_NC_IPUT_VAR1',dnl
+`dnl
+int
+test_ncmpi_iput_var1_$1(void)
+{
+ int ncid, nok=0;
+ int i;
+ int j;
+ int err;
+ MPI_Offset index[MAX_RANK];
+ int canConvert; /* Both text or both numeric */
+ $1 value = 5; /* any value would do - only for error cases */
+ int reqid, status=NC_NOERR;
+
+ err = ncmpi_create(comm, scratch, NC_CLOBBER|extra_flags, info, &ncid);
+ IF (err != NC_NOERR) {
+ error("ncmpi_create: %s", ncmpi_strerror(err));
+ return nok;
+ }
+ def_dims(ncid);
+ def_vars(ncid);
+ err = ncmpi_enddef(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_enddef: %s", ncmpi_strerror(err));
+
+ for (i = 0; i < numVars; i++) {
+ canConvert = (var_type[i] == NC_CHAR) CheckText($1);
+ for (j = 0; j < var_rank[i]; j++)
+ index[j] = 0;
+ err = ncmpi_iput_var1_$1(BAD_ID, i, index, &value, &reqid);
+ IF (err != NC_EBADID)
+ error("bad ncid: err = %d", err);
+ ELSE_NOK
+ err = ncmpi_iput_var1_$1(ncid, BAD_VARID, index, &value, &reqid);
+ IF (err != NC_ENOTVAR)
+ error("bad var id: err = %d", err);
+ ELSE_NOK
+ for (j = 0; j < var_rank[i]; j++) {
+ if (var_dimid[i][j] > 0) { /* skip record dim */
+ index[j] = var_shape[i][j]; /* out of boundary check */
+ err = ncmpi_iput_var1_$1(ncid, i, index, &value, &reqid);
+ IF (canConvert && err != NC_EINVALCOORDS)
+ error("bad index: err = %d", err);
+ ELSE_NOK
+ if (err == NC_NOERR) ncmpi_wait_all(ncid, 1, &reqid, &status);
+ index[j] = 0;
+ }
+ }
+ for (j = 0; j < var_nels[i]; j++) {
+ err = toMixedBase(j, var_rank[i], var_shape[i], index);
+ IF (err != NC_NOERR)
+ error("error in toMixedBase 1");
+ value = hash_$1( var_type[i], var_rank[i], index, NCT_ITYPE($1));
+ if (var_rank[i] == 0 && i%2 == 0)
+ err = ncmpi_iput_var1_$1(ncid, i, NULL, &value, &reqid);
+ else
+ err = ncmpi_iput_var1_$1(ncid, i, index, &value, &reqid);
+ if (err == NC_NOERR || err == NC_ERANGE)
+ /* NC_ERANGE is not fatal, must continue */
+ ncmpi_wait_all(ncid, 1, &reqid, &status);
+ if (canConvert) {
+ if (CheckRange3($1, value, var_type[i])) {
+ IF (err != NC_NOERR)
+ error("%s", ncmpi_strerror(err));
+ ELSE_NOK
+ IF (status != NC_NOERR)
+ error("%s", ncmpi_strerror(status));
+ ELSE_NOK
+ } else {
+ /* NC_ERANGE is checked at ncmpi_iput_var1_$1() */
+ IF (err != NC_ERANGE) {
+ error("Range error: err = %d", err);
+ error("\n\t\tfor type %s value %.17e %ld",
+ s_nc_type(var_type[i]),
+ (double)value, (long)value, &reqid);
+ }
+ ELSE_NOK
+ }
+ } else {
+ /* NC_ECHAR is checked at ncmpi_iput_var1_$1() */
+ IF (err != NC_ECHAR)
+ error("wrong type: err = %d", err);
+ ELSE_NOK
+ }
+ }
+ }
+
+ err = ncmpi_close(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_close: %s", ncmpi_strerror(err));
+
+ nok += check_vars_$1(scratch);
+
+ err = ncmpi_delete(scratch, info);
+ IF (err != NC_NOERR)
+ error("remove of %s failed", scratch);
+ return nok;
+}
+')dnl
+
+TEST_NC_IPUT_VAR1(text)
+TEST_NC_IPUT_VAR1(uchar)
+TEST_NC_IPUT_VAR1(schar)
+TEST_NC_IPUT_VAR1(short)
+TEST_NC_IPUT_VAR1(int)
+TEST_NC_IPUT_VAR1(long)
+TEST_NC_IPUT_VAR1(float)
+TEST_NC_IPUT_VAR1(double)
+TEST_NC_IPUT_VAR1(ushort)
+TEST_NC_IPUT_VAR1(uint)
+TEST_NC_IPUT_VAR1(longlong)
+TEST_NC_IPUT_VAR1(ulonglong)
+
+int
+test_ncmpi_iput_var(void)
+{
+ int ncid, nok=0, varid, i, j, err, nels;
+ MPI_Offset index[MAX_RANK];
+ double value[MAX_NELS];
+ int reqid, status=NC_NOERR;
+ MPI_Datatype datatype;
+
+ err = ncmpi_create(comm, scratch, NC_CLOBBER|extra_flags, info, &ncid);
+ IF (err != NC_NOERR) {
+ error("ncmpi_create: %s", ncmpi_strerror(err));
+ return nok;
+ }
+ def_dims(ncid);
+ def_vars(ncid);
+ err = ncmpi_enddef(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_enddef: %s", ncmpi_strerror(err));
+
+ /* Because var API is writing the entire variables. We need at first
+ * make sure there are non-zero records to write */
+
+ /* Write record number NRECS to force writing of preceding records */
+ /* Assumes variable cr is char vector with UNLIMITED dimension */
+ err = ncmpi_inq_varid(ncid, "cr", &varid);
+ IF (err != NC_NOERR)
+ error("ncmpi_inq_varid: %s", ncmpi_strerror(err));
+ index[0] = NRECS-1;
+ err = ncmpi_iput_var1_text(ncid, varid, index, "x", &reqid);
+ IF (err != NC_NOERR)
+ error("ncmpi_iput_var1_text: %s", ncmpi_strerror(err));
+ err = ncmpi_wait_all(ncid, 1, &reqid, &status);
+ IF (err != NC_NOERR)
+ error("ncmpi_wait_all: %s", ncmpi_strerror(err));
+
+ for (i = 0; i < numVars; i++) {
+ datatype = nc_mpi_type(var_type[i]);
+ assert(var_rank[i] <= MAX_RANK);
+ assert(var_nels[i] <= MAX_NELS);
+ err = ncmpi_iput_var(BAD_ID, i, value, 1, datatype, &reqid);
+ IF (err != NC_EBADID)
+ error("bad ncid: err = %d", err);
+ ELSE_NOK
+ err = ncmpi_iput_var(ncid, BAD_VARID, value, 1, datatype, &reqid);
+ IF (err != NC_ENOTVAR)
+ error("bad var id: err = %d", err);
+ ELSE_NOK
+
+ nels = 1;
+ for (j = 0; j < var_rank[i]; j++) {
+ nels *= var_shape[i][j];
+ index[j] = 0;
+ }
+ double ncbuf[MAX_NELS];
+ for (j = 0; j < nels; j++) {
+ err = toMixedBase(j, var_rank[i], var_shape[i], index);
+ IF (err != NC_NOERR)
+ error("error in toMixedBase 1");
+ ncbuf[j] = hash2nc(var_type[i], var_rank[i], index);
+ }
+ /* type convert ncbuf[] to value[] */
+ err = dbls2ncs(nels, var_type[i], ncbuf, value);
+ IF (err != NC_NOERR)
+ error("error in dbls2ncs");
+ err = ncmpi_iput_var(ncid, i, value, nels, datatype, &reqid);
+ IF (err != NC_NOERR)
+ error("ncmpi_iput_var: %s", ncmpi_strerror(err));
+ ELSE_NOK
+
+ err = ncmpi_wait_all(ncid, 1, &reqid, &status);
+ IF (err != NC_NOERR)
+ error("ncmpi_wait_all: %s", ncmpi_strerror(err));
+ ELSE_NOK
+ }
+
+ check_vars(ncid);
+
+ err = ncmpi_close(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_close: %s", ncmpi_strerror(err));
+
+ err = ncmpi_delete(scratch, info);
+ IF (err != NC_NOERR)
+ error("remove of %s failed", scratch);
+
+ return nok;
+}
+
+dnl TEST_NC_IPUT_VAR(TYPE)
+dnl
+define(`TEST_NC_IPUT_VAR',dnl
+`dnl
+int
+test_ncmpi_iput_var_$1(void)
+{
+ int ncid, nok=0;
+ int varid;
+ int i;
+ int j;
+ int err;
+ int nels;
+ MPI_Offset index[MAX_RANK];
+ int canConvert; /* Both text or both numeric */
+ int allInExtRange; /* all values within external range? */
+ $1 value[MAX_NELS];
+ int reqid, status=NC_NOERR;
+
+ err = ncmpi_create(comm, scratch, NC_CLOBBER|extra_flags, info, &ncid);
+ IF (err != NC_NOERR) {
+ error("ncmpi_create: %s", ncmpi_strerror(err));
+ return nok;
+ }
+ def_dims(ncid);
+ def_vars(ncid);
+ err = ncmpi_enddef(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_enddef: %s", ncmpi_strerror(err));
+
+ for (i = 0; i < numVars; i++) {
+ canConvert = (var_type[i] == NC_CHAR) CheckText($1);
+ assert(var_rank[i] <= MAX_RANK);
+ assert(var_nels[i] <= MAX_NELS);
+ err = ncmpi_iput_var_$1(BAD_ID, i, value, &reqid);
+ IF (err != NC_EBADID)
+ error("bad ncid: err = %d", err);
+ ELSE_NOK
+ err = ncmpi_iput_var_$1(ncid, BAD_VARID, value, &reqid);
+ IF (err != NC_ENOTVAR)
+ error("bad var id: err = %d", err);
+ ELSE_NOK
+
+ nels = 1;
+ for (j = 0; j < var_rank[i]; j++) {
+ nels *= var_shape[i][j];
+ }
+ for (allInExtRange = 1, j = 0; j < nels; j++) {
+ err = toMixedBase(j, var_rank[i], var_shape[i], index);
+ IF (err != NC_NOERR)
+ error("error in toMixedBase 1");
+ value[j]= hash_$1(var_type[i], var_rank[i], index, NCT_ITYPE($1));
+ IfCheckTextChar($1, var_type[i])
+ allInExtRange &= inRange3(value[j], var_type[i], NCT_ITYPE($1));
+ }
+ err = ncmpi_iput_var_$1(ncid, i, value, &reqid);
+ if (err == NC_NOERR || err == NC_ERANGE)
+ /* NC_ERANGE is not fatal, must continue */
+ ncmpi_wait_all(ncid, 1, &reqid, &status);
+
+ if (canConvert) {
+ if (allInExtRange) {
+ IF (err != NC_NOERR)
+ error("%s", ncmpi_strerror(err));
+ ELSE_NOK
+ IF (status != NC_NOERR)
+ error("%s", ncmpi_strerror(status));
+ ELSE_NOK
+ } else {
+ /* NC_ERANGE is checked at ncmpi_iput_var_$1() */
+ IF (err != NC_ERANGE && var_dimid[i][0] != RECDIM)
+ error("expecting range error, but err = %d", err);
+ ELSE_NOK
+ }
+ } else { /* should flag wrong type even if nothing to write */
+ /* NC_ECHAR is checked at ncmpi_iput_var_$1() */
+ IF (nels > 0 && err != NC_ECHAR)
+ error("wrong type: err = %d", err);
+ ELSE_NOK
+ }
+ }
+
+ /* Preceeding has written nothing for record variables, now try */
+ /* again with more than 0 records */
+
+ /* Write record number NRECS to force writing of preceding records */
+ /* Assumes variable cr is char vector with UNLIMITED dimension */
+ err = ncmpi_inq_varid(ncid, "cr", &varid);
+ IF (err != NC_NOERR)
+ error("ncmpi_inq_varid: %s", ncmpi_strerror(err));
+ index[0] = NRECS-1;
+ err = ncmpi_iput_var1_text(ncid, varid, index, "x", &reqid);
+ IF (err != NC_NOERR)
+ error("ncmpi_iput_var1_text: %s", ncmpi_strerror(err));
+ else
+ ncmpi_wait_all(ncid, 1, &reqid, &status);
+
+ for (i = 0; i < numVars; i++) {
+ if (var_dimid[i][0] == RECDIM) { /* only test record variables here */
+ canConvert = (var_type[i] == NC_CHAR) CheckText($1);
+ assert(var_rank[i] <= MAX_RANK);
+ assert(var_nels[i] <= MAX_NELS);
+ err = ncmpi_iput_var_$1(BAD_ID, i, value, &reqid);
+ IF (err != NC_EBADID)
+ error("expecting bad ncid, but err = %d", err);
+ ELSE_NOK
+
+ nels = 1;
+ for (j = 0; j < var_rank[i]; j++) {
+ nels *= var_shape[i][j];
+ }
+ for (allInExtRange = 1, j = 0; j < nels; j++) {
+ err = toMixedBase(j, var_rank[i], var_shape[i], index);
+ IF (err != NC_NOERR)
+ error("error in toMixedBase 1");
+ ELSE_NOK
+ value[j]= hash_$1(var_type[i], var_rank[i], index, NCT_ITYPE($1));
+ IfCheckTextChar($1, var_type[i])
+ allInExtRange &= inRange3(value[j], var_type[i], NCT_ITYPE($1));
+ }
+ err = ncmpi_iput_var_$1(ncid, i, value, &reqid);
+ if (err == NC_NOERR || err == NC_ERANGE)
+ /* NC_ERANGE is not fatal, must continue */
+ ncmpi_wait_all(ncid, 1, &reqid, &status);
+ if (canConvert) {
+ if (allInExtRange) {
+ IF (err != NC_NOERR)
+ error("%s", ncmpi_strerror(err));
+ ELSE_NOK
+ IF (status != NC_NOERR)
+ error("%s", ncmpi_strerror(status));
+ ELSE_NOK
+ } else {
+ /* NC_ERANGE is checked at ncmpi_iput_var_$1() */
+ IF (err != NC_ERANGE)
+ error("range error: err = %d", err);
+ ELSE_NOK
+ }
+ } else {
+ /* NC_ECHAR is checked at ncmpi_iput_var_$1() */
+ IF (nels > 0 && err != NC_ECHAR)
+ error("wrong type: err = %d", err);
+ ELSE_NOK
+ }
+ }
+ }
+
+ err = ncmpi_close(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_close: %s", ncmpi_strerror(err));
+
+ nok += check_vars_$1(scratch);
+
+ err = ncmpi_delete(scratch, info);
+ IF (err != NC_NOERR)
+ error("remove of %s failed", scratch);
+
+ return nok;
+}
+')dnl
+
+TEST_NC_IPUT_VAR(text)
+TEST_NC_IPUT_VAR(uchar)
+TEST_NC_IPUT_VAR(schar)
+TEST_NC_IPUT_VAR(short)
+TEST_NC_IPUT_VAR(int)
+TEST_NC_IPUT_VAR(long)
+TEST_NC_IPUT_VAR(float)
+TEST_NC_IPUT_VAR(double)
+TEST_NC_IPUT_VAR(ushort)
+TEST_NC_IPUT_VAR(uint)
+TEST_NC_IPUT_VAR(longlong)
+TEST_NC_IPUT_VAR(ulonglong)
+
+int
+test_ncmpi_iput_vara(void)
+{
+ int ncid, nok=0, d, i, j, k, err, nslabs, nels;
+ MPI_Offset start[MAX_RANK];
+ MPI_Offset edge[MAX_RANK];
+ MPI_Offset mid[MAX_RANK];
+ MPI_Offset index[MAX_RANK];
+ double value[MAX_NELS];
+ int reqid, status=NC_NOERR;
+ MPI_Datatype datatype;
+
+ err = ncmpi_create(comm, scratch, NC_CLOBBER|extra_flags, info, &ncid);
+ IF (err != NC_NOERR) {
+ error("ncmpi_create: %s", ncmpi_strerror(err));
+ return nok;
+ }
+ def_dims(ncid);
+ def_vars(ncid);
+ err = ncmpi_enddef(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_enddef: %s", ncmpi_strerror(err));
+
+ value[0] = 0;
+ for (i = 0; i < numVars; i++) {
+ datatype = nc_mpi_type(var_type[i]);
+ assert(var_rank[i] <= MAX_RANK);
+ assert(var_nels[i] <= MAX_NELS);
+ for (j = 0; j < var_rank[i]; j++) {
+ start[j] = 0;
+ edge[j] = 1;
+ }
+ err = ncmpi_iput_vara(BAD_ID, i, start, edge, value, 1, datatype, &reqid);
+ IF (err != NC_EBADID)
+ error("bad ncid: err = %d", err);
+ ELSE_NOK
+ err = ncmpi_iput_vara(ncid, BAD_VARID, start, edge, value, 1, datatype, &reqid);
+ IF (err != NC_ENOTVAR)
+ error("bad var id: err = %d", err);
+ ELSE_NOK
+ for (j = 0; j < var_rank[i]; j++) {
+ if (var_dimid[i][j] > 0) { /* skip record dim */
+ start[j] = var_shape[i][j]; /* out of bundary check */
+ err = ncmpi_iput_vara(ncid, i, start, edge, value, 1, datatype, &reqid);
+ IF (err != NC_EINVALCOORDS)
+ error("expecting bad start, but err = %d", err);
+ ELSE_NOK
+ start[j] = 0;
+ edge[j] = var_shape[i][j] + 1; /* edge error check */
+ err = ncmpi_iput_vara(ncid, i, start, edge, value, 1, datatype, &reqid);
+ IF (err != NC_EEDGE)
+ error("expecting bad edge, but err = %d", err);
+ ELSE_NOK
+ edge[j] = 1;
+ }
+ }
+ /* Check correct error returned even when nothing to put */
+ for (j = 0; j < var_rank[i]; j++) {
+ edge[j] = 0;
+ }
+ err = ncmpi_iput_vara(BAD_ID, i, start, edge, value, 1, datatype, &reqid);
+ IF (err != NC_EBADID)
+ error("bad ncid: err = %d", err);
+ ELSE_NOK
+ err = ncmpi_iput_vara(ncid, BAD_VARID, start, edge, value, 1, datatype, &reqid);
+ IF (err != NC_ENOTVAR)
+ error("bad var id: err = %d", err);
+ ELSE_NOK
+ for (j = 0; j < var_rank[i]; j++) {
+ if (var_dimid[i][j] > 0) { /* skip record dim */
+ start[j] = var_shape[i][j]; /* out of boundary check */
+ err = ncmpi_iput_vara(ncid, i, start, edge, value, 1, datatype, &reqid);
+ IF (err != NC_EINVALCOORDS)
+ error("bad start: err = %d", err);
+ ELSE_NOK
+ start[j] = 0;
+ }
+ }
+
+ for (j = 0; j < var_rank[i]; j++) {
+ edge[j] = 1;
+ }
+
+ /* Choose a random point dividing each dim into 2 parts */
+ /* Put 2^rank (nslabs) slabs so defined */
+ nslabs = 1;
+ for (j = 0; j < var_rank[i]; j++) {
+ mid[j] = roll( var_shape[i][j] );
+ nslabs *= 2;
+ }
+ /* bits of k determine whether to put lower or upper part of dim */
+ for (k = 0; k < nslabs; k++) {
+ nels = 1;
+ for (j = 0; j < var_rank[i]; j++) {
+ if ((k >> j) & 1) {
+ start[j] = 0;
+ edge[j] = mid[j];
+ } else {
+ start[j] = mid[j];
+ edge[j] = var_shape[i][j] - mid[j];
+ }
+ nels *= edge[j];
+ }
+ double ncbuf[MAX_NELS];
+ for (j = 0; j < nels; j++) {
+ err = toMixedBase(j, var_rank[i], edge, index);
+ IF (err != NC_NOERR)
+ error("error in toMixedBase 1");
+ ELSE_NOK
+ for (d = 0; d < var_rank[i]; d++)
+ index[d] += start[d];
+ ncbuf[j] = hash2nc(var_type[i], var_rank[i], index);
+ }
+ /* type convert ncbuf[] to value[] */
+ err = dbls2ncs(nels, var_type[i], ncbuf, value);
+ IF (err != NC_NOERR)
+ error("error in dbls2ncs");
+
+ if (var_rank[i] == 0 && i%2 == 0)
+ err = ncmpi_iput_vara(ncid, i, NULL, NULL, value, nels, datatype, &reqid);
+ else
+ err = ncmpi_iput_vara(ncid, i, start, edge, value, nels, datatype, &reqid);
+ IF (err != NC_NOERR)
+ error("ncmpi_iput_var1: %s", ncmpi_strerror(err));
+ ELSE_NOK
+
+ err = ncmpi_wait_all(ncid, 1, &reqid, &status);
+ IF (err != NC_NOERR)
+ error("ncmpi_wait_all: %s", ncmpi_strerror(err));
+ ELSE_NOK
+ }
+ }
+
+ check_vars(ncid);
+
+ err = ncmpi_close(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_close: %s", ncmpi_strerror(err));
+
+ err = ncmpi_delete(scratch, info);
+ IF (err != NC_NOERR)
+ error("remove of %s failed", scratch);
+ return nok;
+}
+
+dnl TEST_NC_IPUT_VARA(TYPE)
+dnl
+define(`TEST_NC_IPUT_VARA',dnl
+`dnl
+int
+test_ncmpi_iput_vara_$1(void)
+{
+ int ncid, nok=0;
+ int d;
+ int i;
+ int j;
+ int k;
+ int err;
+ int nslabs;
+ int nels;
+ MPI_Offset start[MAX_RANK];
+ MPI_Offset edge[MAX_RANK];
+ MPI_Offset mid[MAX_RANK];
+ MPI_Offset index[MAX_RANK];
+ int canConvert; /* Both text or both numeric */
+ int allInExtRange; /* all values within external range? */
+ $1 value[MAX_NELS];
+ int reqid, status=NC_NOERR;
+
+ err = ncmpi_create(comm, scratch, NC_CLOBBER|extra_flags, info, &ncid);
+ IF (err != NC_NOERR) {
+ error("ncmpi_create: %s", ncmpi_strerror(err));
+ return nok;
+ }
+ def_dims(ncid);
+ def_vars(ncid);
+ err = ncmpi_enddef(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_enddef: %s", ncmpi_strerror(err));
+
+ value[0] = 0;
+ for (i = 0; i < numVars; i++) {
+ canConvert = (var_type[i] == NC_CHAR) CheckText($1);
+ assert(var_rank[i] <= MAX_RANK);
+ assert(var_nels[i] <= MAX_NELS);
+ for (j = 0; j < var_rank[i]; j++) {
+ start[j] = 0;
+ edge[j] = 1;
+ }
+ err = ncmpi_iput_vara_$1(BAD_ID, i, start, edge, value, &reqid);
+ IF (err != NC_EBADID)
+ error("bad ncid: err = %d", err);
+ ELSE_NOK
+ err = ncmpi_iput_vara_$1(ncid, BAD_VARID, start, edge, value, &reqid);
+ IF (err != NC_ENOTVAR)
+ error("bad var id: err = %d", err);
+ ELSE_NOK
+ for (j = 0; j < var_rank[i]; j++) {
+ if (var_dimid[i][j] > 0) { /* skip record dim */
+ start[j] = var_shape[i][j]; /* out of bundary check */
+ err = ncmpi_iput_vara_$1(ncid, i, start, edge, value, &reqid);
+ IF (canConvert && err != NC_EINVALCOORDS)
+ error("expecting bad start, but err = %d", err);
+ ELSE_NOK
+ if (err == NC_NOERR) ncmpi_wait_all(ncid, 1, &reqid, &status);
+ start[j] = 0;
+ edge[j] = var_shape[i][j] + 1; /* edge error check */
+ err = ncmpi_iput_vara_$1(ncid, i, start, edge, value, &reqid);
+ IF (canConvert && err != NC_EEDGE)
+ error("expecting bad edge, but err = %d", err);
+ ELSE_NOK
+ if (err == NC_NOERR) ncmpi_wait_all(ncid, 1, &reqid, &status);
+ edge[j] = 1;
+ }
+ }
+ /* Check correct error returned even when nothing to put */
+ for (j = 0; j < var_rank[i]; j++) {
+ edge[j] = 0;
+ }
+ err = ncmpi_iput_vara_$1(BAD_ID, i, start, edge, value, &reqid);
+ IF (err != NC_EBADID)
+ error("bad ncid: err = %d", err);
+ ELSE_NOK
+ err = ncmpi_iput_vara_$1(ncid, BAD_VARID, start, edge, value, &reqid);
+ IF (err != NC_ENOTVAR)
+ error("bad var id: err = %d", err);
+ ELSE_NOK
+ for (j = 0; j < var_rank[i]; j++) {
+ if (var_dimid[i][j] > 0) { /* skip record dim */
+ start[j] = var_shape[i][j]; /* out of boundary check */
+ err = ncmpi_iput_vara_$1(ncid, i, start, edge, value, &reqid);
+ IF (canConvert && err != NC_EINVALCOORDS)
+ error("bad start: err = %d", err);
+ ELSE_NOK
+ if (err == NC_NOERR) ncmpi_wait_all(ncid, 1, &reqid, &status);
+ start[j] = 0;
+ }
+ }
+
+ for (j = 0; j < var_rank[i]; j++) {
+ edge[j] = 1;
+ }
+
+ /* Choose a random point dividing each dim into 2 parts */
+ /* Put 2^rank (nslabs) slabs so defined */
+ nslabs = 1;
+ for (j = 0; j < var_rank[i]; j++) {
+ mid[j] = roll( var_shape[i][j] );
+ nslabs *= 2;
+ }
+ /* bits of k determine whether to put lower or upper part of dim */
+ for (k = 0; k < nslabs; k++) {
+ nels = 1;
+ for (j = 0; j < var_rank[i]; j++) {
+ if ((k >> j) & 1) {
+ start[j] = 0;
+ edge[j] = mid[j];
+ } else {
+ start[j] = mid[j];
+ edge[j] = var_shape[i][j] - mid[j];
+ }
+ nels *= edge[j];
+ }
+ for (allInExtRange = 1, j = 0; j < nels; j++) {
+ err = toMixedBase(j, var_rank[i], edge, index);
+ IF (err != NC_NOERR)
+ error("error in toMixedBase 1");
+ ELSE_NOK
+ for (d = 0; d < var_rank[i]; d++)
+ index[d] += start[d];
+ value[j]= hash_$1(var_type[i], var_rank[i], index, NCT_ITYPE($1));
+ IfCheckTextChar($1, var_type[i])
+ allInExtRange &= inRange3(value[j], var_type[i], NCT_ITYPE($1));
+ }
+ if (var_rank[i] == 0 && i%2 == 0)
+ err = ncmpi_iput_vara_$1(ncid, i, NULL, NULL, value, &reqid);
+ else
+ err = ncmpi_iput_vara_$1(ncid, i, start, edge, value, &reqid);
+ if (err == NC_NOERR || err == NC_ERANGE)
+ /* NC_ERANGE is not fatal, must continue */
+ ncmpi_wait_all(ncid, 1, &reqid, &status);
+ if (canConvert) {
+ if (allInExtRange) {
+ IF (err != NC_NOERR)
+ error("%s", ncmpi_strerror(err));
+ ELSE_NOK
+ IF (status != NC_NOERR)
+ error("%s", ncmpi_strerror(status));
+ ELSE_NOK
+ } else {
+ /* NC_ERANGE is checked at ncmpi_iput_vara_$1() */
+ IF (err != NC_ERANGE)
+ error("range error: err = %d", err);
+ ELSE_NOK
+ }
+ } else {
+ /* NC_ECHAR is checked at ncmpi_iput_vara_$1() */
+ IF (nels > 0 && err != NC_ECHAR)
+ error("wrong type: err = %d", err);
+ ELSE_NOK
+ }
+ }
+ }
+
+ err = ncmpi_close(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_close: %s", ncmpi_strerror(err));
+
+ nok += check_vars_$1(scratch);
+
+ err = ncmpi_delete(scratch, info);
+ IF (err != NC_NOERR)
+ error("remove of %s failed", scratch);
+ return nok;
+}
+')dnl
+
+TEST_NC_IPUT_VARA(text)
+TEST_NC_IPUT_VARA(uchar)
+TEST_NC_IPUT_VARA(schar)
+TEST_NC_IPUT_VARA(short)
+TEST_NC_IPUT_VARA(int)
+TEST_NC_IPUT_VARA(long)
+TEST_NC_IPUT_VARA(float)
+TEST_NC_IPUT_VARA(double)
+TEST_NC_IPUT_VARA(ushort)
+TEST_NC_IPUT_VARA(uint)
+TEST_NC_IPUT_VARA(longlong)
+TEST_NC_IPUT_VARA(ulonglong)
+
+int
+test_ncmpi_iput_vars(void)
+{
+ int ncid, nok=0, d, i, j, k, m, err, nels, nslabs;
+ int nstarts; /* number of different starts */
+ MPI_Offset start[MAX_RANK];
+ MPI_Offset edge[MAX_RANK];
+ MPI_Offset index[MAX_RANK];
+ MPI_Offset index2[MAX_RANK];
+ MPI_Offset mid[MAX_RANK];
+ MPI_Offset count[MAX_RANK];
+ MPI_Offset sstride[MAX_RANK];
+ MPI_Offset stride[MAX_RANK];
+ double value[MAX_NELS];
+ int reqid, status=NC_NOERR;
+ MPI_Datatype datatype;
+
+ err = ncmpi_create(comm, scratch, NC_CLOBBER|extra_flags, info, &ncid);
+ IF (err != NC_NOERR) {
+ error("ncmpi_create: %s", ncmpi_strerror(err));
+ return nok;
+ }
+ def_dims(ncid);
+ def_vars(ncid);
+ err = ncmpi_enddef(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_enddef: %s", ncmpi_strerror(err));
+
+ for (i = 0; i < numVars; i++) {
+ datatype = nc_mpi_type(var_type[i]);
+ assert(var_rank[i] <= MAX_RANK);
+ assert(var_nels[i] <= MAX_NELS);
+ for (j = 0; j < var_rank[i]; j++) {
+ start[j] = 0;
+ edge[j] = 1;
+ stride[j] = 1;
+ }
+ err = ncmpi_iput_vars(BAD_ID, i, start, edge, stride, value, 1, datatype, &reqid);
+ IF (err != NC_EBADID)
+ error("bad ncid: err = %d", err);
+ ELSE_NOK
+ err = ncmpi_iput_vars(ncid, BAD_VARID, start, edge, stride, value, 1, datatype, &reqid);
+ IF (err != NC_ENOTVAR)
+ error("bad var id: err = %d", err);
+ ELSE_NOK
+ for (j = 0; j < var_rank[i]; j++) {
+ if (var_dimid[i][j] > 0) { /* skip record dim */
+ start[j] = var_shape[i][j]; /* out of boundary check */
+ err = ncmpi_iput_vars(ncid, i, start, edge, stride, value, 1, datatype, &reqid);
+ IF (err != NC_EINVALCOORDS)
+ error("expecting bad start, but err = %d", err);
+ ELSE_NOK
+ start[j] = 0;
+ edge[j] = var_shape[i][j] + 1; /* edge error check */
+ err = ncmpi_iput_vars(ncid, i, start, edge, stride, value, 1, datatype, &reqid);
+ IF (err != NC_EEDGE)
+ error("expecting bad edge, but err = %d", err);
+ ELSE_NOK
+ edge[j] = 1;
+ stride[j] = 0; /* strided edge error check */
+ err = ncmpi_iput_vars(ncid, i, start, edge, stride, value, 1, datatype, &reqid);
+ IF (err != NC_ESTRIDE)
+ error("expecting bad stride, but err = %d", err);
+ ELSE_NOK
+ stride[j] = 1;
+ }
+ }
+ /* Choose a random point dividing each dim into 2 parts */
+ /* Put 2^rank (nslabs) slabs so defined */
+ nslabs = 1;
+ for (j = 0; j < var_rank[i]; j++) {
+ mid[j] = roll( var_shape[i][j] );
+ nslabs *= 2;
+ }
+ /* bits of k determine whether to put lower or upper part of dim */
+ /* choose random stride from 1 to edge */
+ for (k = 0; k < nslabs; k++) {
+ nstarts = 1;
+ for (j = 0; j < var_rank[i]; j++) {
+ if ((k >> j) & 1) {
+ start[j] = 0;
+ edge[j] = mid[j];
+ } else {
+ start[j] = mid[j];
+ edge[j] = var_shape[i][j] - mid[j];
+ }
+ sstride[j] = stride[j] = edge[j] > 0 ? 1+roll(edge[j]) : 1;
+ nstarts *= stride[j];
+ }
+ for (m = 0; m < nstarts; m++) {
+ err = toMixedBase(m, var_rank[i], sstride, index);
+ IF (err != NC_NOERR)
+ error("error in toMixedBase");
+ nels = 1;
+ for (j = 0; j < var_rank[i]; j++) {
+ count[j] = 1 + (edge[j] - index[j] - 1) / stride[j];
+ nels *= count[j];
+ index[j] += start[j];
+ }
+ /* Random choice of forward or backward */
+/* TODO
+ if ( roll(2) ) {
+ for (j = 0; j < var_rank[i]; j++) {
+ index[j] += (count[j] - 1) * stride[j];
+ stride[j] = -stride[j];
+ }
+ }
+*/
+ double ncbuf[MAX_NELS];
+ for (j = 0; j < nels; j++) {
+ err = toMixedBase(j, var_rank[i], count, index2);
+ IF (err != NC_NOERR)
+ error("error in toMixedBase");
+ ELSE_NOK
+ for (d = 0; d < var_rank[i]; d++)
+ index2[d] = index[d] + index2[d] * stride[d];
+ ncbuf[j] = hash2nc(var_type[i], var_rank[i], index2);
+ }
+ /* type convert ncbuf[] to value[] */
+ err = dbls2ncs(nels, var_type[i], ncbuf, value);
+ IF (err != NC_NOERR)
+ error("error in dbls2ncs");
+
+ if (var_rank[i] == 0 && i%2 == 0)
+ err = ncmpi_iput_vars(ncid, i, NULL, NULL, stride, value, nels, datatype, &reqid);
+ else
+ err = ncmpi_iput_vars(ncid, i, index, count, stride, value, nels, datatype, &reqid);
+ IF (err != NC_NOERR)
+ error("ncmpi_iput_var1: %s", ncmpi_strerror(err));
+ ELSE_NOK
+
+ err = ncmpi_wait_all(ncid, 1, &reqid, &status);
+ IF (err != NC_NOERR)
+ error("ncmpi_wait_all: %s", ncmpi_strerror(err));
+ ELSE_NOK
+ }
+ }
+ }
+
+ check_vars(ncid);
+
+ err = ncmpi_close(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_close: %s", ncmpi_strerror(err));
+
+ err = ncmpi_delete(scratch, info);
+ IF (err != NC_NOERR)
+ error("remove of %s failed", scratch);
+ return nok;
+}
+
+dnl TEST_NC_IPUT_VARS(TYPE)
+dnl
+define(`TEST_NC_IPUT_VARS',dnl
+`dnl
+int
+test_ncmpi_iput_vars_$1(void)
+{
+ int ncid, nok=0;
+ int d;
+ int i;
+ int j;
+ int k;
+ int m;
+ int err;
+ int nels;
+ int nslabs;
+ int nstarts; /* number of different starts */
+ MPI_Offset start[MAX_RANK];
+ MPI_Offset edge[MAX_RANK];
+ MPI_Offset index[MAX_RANK];
+ MPI_Offset index2[MAX_RANK];
+ MPI_Offset mid[MAX_RANK];
+ MPI_Offset count[MAX_RANK];
+ MPI_Offset sstride[MAX_RANK];
+ MPI_Offset stride[MAX_RANK];
+ int canConvert; /* Both text or both numeric */
+ int allInExtRange; /* all values within external range? */
+ $1 value[MAX_NELS];
+ int reqid, status=NC_NOERR;
+
+ err = ncmpi_create(comm, scratch, NC_CLOBBER|extra_flags, info, &ncid);
+ IF (err != NC_NOERR) {
+ error("ncmpi_create: %s", ncmpi_strerror(err));
+ return nok;
+ }
+ def_dims(ncid);
+ def_vars(ncid);
+ err = ncmpi_enddef(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_enddef: %s", ncmpi_strerror(err));
+
+ for (i = 0; i < numVars; i++) {
+ canConvert = (var_type[i] == NC_CHAR) CheckText($1);
+ assert(var_rank[i] <= MAX_RANK);
+ assert(var_nels[i] <= MAX_NELS);
+ for (j = 0; j < var_rank[i]; j++) {
+ start[j] = 0;
+ edge[j] = 1;
+ stride[j] = 1;
+ }
+ err = ncmpi_iput_vars_$1(BAD_ID, i, start, edge, stride, value, &reqid);
+ IF (err != NC_EBADID)
+ error("bad ncid: err = %d", err);
+ ELSE_NOK
+ err = ncmpi_iput_vars_$1(ncid, BAD_VARID, start, edge, stride, value, &reqid);
+ IF (err != NC_ENOTVAR)
+ error("bad var id: err = %d", err);
+ ELSE_NOK
+ for (j = 0; j < var_rank[i]; j++) {
+ if (var_dimid[i][j] > 0) { /* skip record dim */
+ start[j] = var_shape[i][j]; /* out of boundary check */
+ err = ncmpi_iput_vars_$1(ncid, i, start, edge, stride, value, &reqid);
+ if (!canConvert) {
+ IF (err != NC_ECHAR)
+ error("conversion: err = %d", err);
+ ELSE_NOK
+ } else {
+ IF (err != NC_EINVALCOORDS)
+ error("expecting bad start, but err = %d", err);
+ ELSE_NOK
+ start[j] = 0;
+ edge[j] = var_shape[i][j] + 1; /* edge error check */
+ err = ncmpi_iput_vars_$1(ncid, i, start, edge, stride, value, &reqid);
+ IF (err != NC_EEDGE)
+ error("expecting bad edge, but err = %d", err);
+ ELSE_NOK
+ edge[j] = 1;
+ stride[j] = 0; /* strided edge error check */
+ err = ncmpi_iput_vars_$1(ncid, i, start, edge, stride, value, &reqid);
+ IF (err != NC_ESTRIDE)
+ error("expecting bad stride, but err = %d", err);
+ ELSE_NOK
+ stride[j] = 1;
+ }
+ }
+ }
+ /* Choose a random point dividing each dim into 2 parts */
+ /* Put 2^rank (nslabs) slabs so defined */
+ nslabs = 1;
+ for (j = 0; j < var_rank[i]; j++) {
+ mid[j] = roll( var_shape[i][j] );
+ nslabs *= 2;
+ }
+ /* bits of k determine whether to put lower or upper part of dim */
+ /* choose random stride from 1 to edge */
+ for (k = 0; k < nslabs; k++) {
+ nstarts = 1;
+ for (j = 0; j < var_rank[i]; j++) {
+ if ((k >> j) & 1) {
+ start[j] = 0;
+ edge[j] = mid[j];
+ } else {
+ start[j] = mid[j];
+ edge[j] = var_shape[i][j] - mid[j];
+ }
+ sstride[j] = stride[j] = edge[j] > 0 ? 1+roll(edge[j]) : 1;
+ nstarts *= stride[j];
+ }
+ for (m = 0; m < nstarts; m++) {
+ err = toMixedBase(m, var_rank[i], sstride, index);
+ IF (err != NC_NOERR)
+ error("error in toMixedBase");
+ nels = 1;
+ for (j = 0; j < var_rank[i]; j++) {
+ count[j] = 1 + (edge[j] - index[j] - 1) / stride[j];
+ nels *= count[j];
+ index[j] += start[j];
+ }
+ /* Random choice of forward or backward */
+/* TODO
+ if ( roll(2) ) {
+ for (j = 0; j < var_rank[i]; j++) {
+ index[j] += (count[j] - 1) * stride[j];
+ stride[j] = -stride[j];
+ }
+ }
+*/
+ for (allInExtRange = 1, j = 0; j < nels; j++) {
+ err = toMixedBase(j, var_rank[i], count, index2);
+ IF (err != NC_NOERR)
+ error("error in toMixedBase");
+ ELSE_NOK
+ for (d = 0; d < var_rank[i]; d++)
+ index2[d] = index[d] + index2[d] * stride[d];
+ value[j] = hash_$1(var_type[i], var_rank[i], index2, NCT_ITYPE($1));
+ IfCheckTextChar($1, var_type[i])
+ allInExtRange &= inRange3(value[j], var_type[i], NCT_ITYPE($1));
+ }
+ if (var_rank[i] == 0 && i%2 == 0)
+ err = ncmpi_iput_vars_$1(ncid, i, NULL, NULL, stride, value, &reqid);
+ else
+ err = ncmpi_iput_vars_$1(ncid, i, index, count, stride, value, &reqid);
+ if (err == NC_NOERR || err == NC_ERANGE)
+ /* NC_ERANGE is not fatal, must continue */
+ ncmpi_wait_all(ncid, 1, &reqid, &status);
+ if (canConvert) {
+ if (allInExtRange) {
+ IF (err != NC_NOERR)
+ error("%s", ncmpi_strerror(err));
+ ELSE_NOK
+ IF (status != NC_NOERR)
+ error("%s", ncmpi_strerror(status));
+ ELSE_NOK
+ } else {
+ /* NC_ERANGE is checked at ncmpi_iput_vars_$1() */
+ IF (err != NC_ERANGE)
+ error("range error: err = %d", err);
+ ELSE_NOK
+ }
+ } else {
+ /* NC_ECHAR is checked at ncmpi_iput_vars_$1() */
+ IF (nels > 0 && err != NC_ECHAR)
+ error("wrong type: err = %d", err);
+ ELSE_NOK
+ }
+ }
+ }
+ }
+
+ err = ncmpi_close(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_close: %s", ncmpi_strerror(err));
+
+ nok += check_vars_$1(scratch);
+
+ err = ncmpi_delete(scratch, info);
+ IF (err != NC_NOERR)
+ error("remove of %s failed", scratch);
+ return nok;
+}
+')dnl
+
+TEST_NC_IPUT_VARS(text)
+TEST_NC_IPUT_VARS(uchar)
+TEST_NC_IPUT_VARS(schar)
+TEST_NC_IPUT_VARS(short)
+TEST_NC_IPUT_VARS(int)
+TEST_NC_IPUT_VARS(long)
+TEST_NC_IPUT_VARS(float)
+TEST_NC_IPUT_VARS(double)
+TEST_NC_IPUT_VARS(ushort)
+TEST_NC_IPUT_VARS(uint)
+TEST_NC_IPUT_VARS(longlong)
+TEST_NC_IPUT_VARS(ulonglong)
+
+int
+test_ncmpi_iput_varm(void)
+{
+ int ncid, nok=0, d, i, j, k, m, err, nels, nslabs;
+ int nstarts; /* number of different starts */
+ MPI_Offset start[MAX_RANK];
+ MPI_Offset edge[MAX_RANK];
+ MPI_Offset index[MAX_RANK];
+ MPI_Offset index2[MAX_RANK];
+ MPI_Offset mid[MAX_RANK];
+ MPI_Offset count[MAX_RANK];
+ MPI_Offset sstride[MAX_RANK];
+ MPI_Offset stride[MAX_RANK];
+ MPI_Offset imap[MAX_RANK];
+ double value[MAX_NELS];
+ int reqid, status=NC_NOERR;
+ MPI_Datatype datatype;
+
+ err = ncmpi_create(comm, scratch, NC_CLOBBER|extra_flags, info, &ncid);
+ IF (err != NC_NOERR) {
+ error("ncmpi_create: %s", ncmpi_strerror(err));
+ return nok;
+ }
+ def_dims(ncid);
+ def_vars(ncid);
+ err = ncmpi_enddef(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_enddef: %s", ncmpi_strerror(err));
+
+ for (i = 0; i < numVars; i++) {
+ datatype = nc_mpi_type(var_type[i]);
+ assert(var_rank[i] <= MAX_RANK);
+ assert(var_nels[i] <= MAX_NELS);
+ for (j = 0; j < var_rank[i]; j++) {
+ start[j] = 0;
+ edge[j] = 1;
+ stride[j] = 1;
+ imap[j] = 1;
+ }
+ err = ncmpi_iput_varm(BAD_ID, i, start, edge, stride, imap, value, 1, datatype, &reqid);
+ IF (err != NC_EBADID)
+ error("bad ncid: err = %d", err);
+ ELSE_NOK
+ err = ncmpi_iput_varm(ncid, BAD_VARID, start, edge, stride, imap, value, 1, datatype, &reqid);
+ IF (err != NC_ENOTVAR)
+ error("bad var id: err = %d", err);
+ ELSE_NOK
+ for (j = 0; j < var_rank[i]; j++) {
+ if (var_dimid[i][j] > 0) { /* skip record dim */
+ start[j] = var_shape[i][j]; /* out of boundary check */
+ err = ncmpi_iput_varm(ncid, i, start, edge, stride, imap, value, 1, datatype, &reqid);
+ IF (err != NC_EINVALCOORDS)
+ error("expecting bad start, but err = %d", err);
+ ELSE_NOK
+ start[j] = 0;
+ edge[j] = var_shape[i][j] + 1; /* edge error check */
+ err = ncmpi_iput_varm(ncid, i, start, edge, stride, imap, value, 1, datatype, &reqid);
+ IF (err != NC_EEDGE)
+ error("expecting bad edge, but err = %d", err);
+ ELSE_NOK
+ edge[j] = 1;
+ stride[j] = 0; /* strided edge error check */
+ err = ncmpi_iput_varm(ncid, i, start, edge, stride, imap, value, 1, datatype, &reqid);
+ IF (err != NC_ESTRIDE)
+ error("expecting bad stride, but err = %d", err);
+ ELSE_NOK
+ stride[j] = 1;
+ }
+ }
+ /* Choose a random point dividing each dim into 2 parts */
+ /* Put 2^rank (nslabs) slabs so defined */
+ nslabs = 1;
+ for (j = 0; j < var_rank[i]; j++) {
+ mid[j] = roll( var_shape[i][j] );
+ nslabs *= 2;
+ }
+ /* bits of k determine whether to put lower or upper part of dim */
+ /* choose random stride from 1 to edge */
+ for (k = 0; k < nslabs; k++) {
+ nstarts = 1;
+ for (j = 0; j < var_rank[i]; j++) {
+ if ((k >> j) & 1) {
+ start[j] = 0;
+ edge[j] = mid[j];
+ } else {
+ start[j] = mid[j];
+ edge[j] = var_shape[i][j] - mid[j];
+ }
+ sstride[j] = stride[j] = edge[j] > 0 ? 1+roll(edge[j]) : 1;
+ nstarts *= stride[j];
+ }
+ for (m = 0; m < nstarts; m++) {
+ err = toMixedBase(m, var_rank[i], sstride, index);
+ IF (err != NC_NOERR)
+ error("error in toMixedBase");
+ ELSE_NOK
+ nels = 1;
+ for (j = 0; j < var_rank[i]; j++) {
+ count[j] = 1 + (edge[j] - index[j] - 1) / stride[j];
+ nels *= count[j];
+ index[j] += start[j];
+ }
+ /* Random choice of forward or backward */
+/* TODO
+ if ( roll(2) ) {
+ for (j = 0; j < var_rank[i]; j++) {
+ index[j] += (count[j] - 1) * stride[j];
+ stride[j] = -stride[j];
+ }
+ }
+*/
+ if (var_rank[i] > 0) {
+ j = var_rank[i] - 1;
+ imap[j] = 1;
+ for (; j > 0; j--)
+ imap[j-1] = imap[j] * count[j];
+ }
+ double ncbuf[MAX_NELS];
+ for (j = 0; j < nels; j++) {
+ err = toMixedBase(j, var_rank[i], count, index2);
+ IF (err != NC_NOERR)
+ error("error in toMixedBase");
+ for (d = 0; d < var_rank[i]; d++)
+ index2[d] = index[d] + index2[d] * stride[d];
+ ncbuf[j] = hash2nc(var_type[i], var_rank[i], index2);
+ }
+ /* type convert ncbuf[] to value[] */
+ err = dbls2ncs(nels, var_type[i], ncbuf, value);
+ IF (err != NC_NOERR)
+ error("error in dbls2ncs");
+
+ if (var_rank[i] == 0 && i%2 == 0)
+ err = ncmpi_iput_varm(ncid,i,NULL,NULL,NULL,NULL,value, nels, datatype, &reqid);
+ else
+ err = ncmpi_iput_varm(ncid,i,index,count,stride,imap,value, nels, datatype,&reqid);
+ IF (err != NC_NOERR)
+ error("ncmpi_iput_var1: %s", ncmpi_strerror(err));
+ ELSE_NOK
+
+ err = ncmpi_wait_all(ncid, 1, &reqid, &status);
+ IF (err != NC_NOERR)
+ error("ncmpi_wait_all: %s", ncmpi_strerror(err));
+ ELSE_NOK
+ }
+ }
+ }
+
+ check_vars(ncid);
+
+ err = ncmpi_close(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_close: %s", ncmpi_strerror(err));
+
+ err = ncmpi_delete(scratch, info);
+ IF (err != NC_NOERR)
+ error("remove of %s failed", scratch);
+ return nok;
+}
+
+dnl TEST_NC_IPUT_VARM(TYPE)
+dnl
+define(`TEST_NC_IPUT_VARM',dnl
+`dnl
+int
+test_ncmpi_iput_varm_$1(void)
+{
+ int ncid, nok=0;
+ int d;
+ int i;
+ int j;
+ int k;
+ int m;
+ int err;
+ int nels;
+ int nslabs;
+ int nstarts; /* number of different starts */
+ MPI_Offset start[MAX_RANK];
+ MPI_Offset edge[MAX_RANK];
+ MPI_Offset index[MAX_RANK];
+ MPI_Offset index2[MAX_RANK];
+ MPI_Offset mid[MAX_RANK];
+ MPI_Offset count[MAX_RANK];
+ MPI_Offset sstride[MAX_RANK];
+ MPI_Offset stride[MAX_RANK];
+ MPI_Offset imap[MAX_RANK];
+ int canConvert; /* Both text or both numeric */
+ int allInExtRange; /* all values within external range? */
+ $1 value[MAX_NELS];
+ int reqid, status=NC_NOERR;
+
+ err = ncmpi_create(comm, scratch, NC_CLOBBER|extra_flags, info, &ncid);
+ IF (err != NC_NOERR) {
+ error("ncmpi_create: %s", ncmpi_strerror(err));
+ return nok;
+ }
+ def_dims(ncid);
+ def_vars(ncid);
+ err = ncmpi_enddef(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_enddef: %s", ncmpi_strerror(err));
+
+ for (i = 0; i < numVars; i++) {
+ canConvert = (var_type[i] == NC_CHAR) CheckText($1);
+ assert(var_rank[i] <= MAX_RANK);
+ assert(var_nels[i] <= MAX_NELS);
+ for (j = 0; j < var_rank[i]; j++) {
+ start[j] = 0;
+ edge[j] = 1;
+ stride[j] = 1;
+ imap[j] = 1;
+ }
+ err = ncmpi_iput_varm_$1(BAD_ID, i, start, edge, stride, imap, value, &reqid);
+ IF (err != NC_EBADID)
+ error("bad ncid: err = %d", err);
+ ELSE_NOK
+ err = ncmpi_iput_varm_$1(ncid, BAD_VARID, start, edge, stride, imap, value, &reqid);
+ IF (err != NC_ENOTVAR)
+ error("bad var id: err = %d", err);
+ ELSE_NOK
+ for (j = 0; j < var_rank[i]; j++) {
+ if (var_dimid[i][j] > 0) { /* skip record dim */
+ start[j] = var_shape[i][j]; /* out of boundary check */
+ err = ncmpi_iput_varm_$1(ncid, i, start, edge, stride, imap, value, &reqid);
+ if (!canConvert) {
+ IF (err != NC_ECHAR)
+ error("conversion: err = %d", err);
+ ELSE_NOK
+ } else {
+ IF (err != NC_EINVALCOORDS)
+ error("expecting bad start, but err = %d", err);
+ ELSE_NOK
+ start[j] = 0;
+ edge[j] = var_shape[i][j] + 1; /* edge error check */
+ err = ncmpi_iput_varm_$1(ncid, i, start, edge, stride, imap, value, &reqid);
+ IF (err != NC_EEDGE)
+ error("expecting bad edge, but err = %d", err);
+ ELSE_NOK
+ edge[j] = 1;
+ stride[j] = 0; /* strided edge error check */
+ err = ncmpi_iput_varm_$1(ncid, i, start, edge, stride, imap, value, &reqid);
+ IF (err != NC_ESTRIDE)
+ error("expecting bad stride, but err = %d", err);
+ ELSE_NOK
+ stride[j] = 1;
+ }
+ }
+ }
+ /* Choose a random point dividing each dim into 2 parts */
+ /* Put 2^rank (nslabs) slabs so defined */
+ nslabs = 1;
+ for (j = 0; j < var_rank[i]; j++) {
+ mid[j] = roll( var_shape[i][j] );
+ nslabs *= 2;
+ }
+ /* bits of k determine whether to put lower or upper part of dim */
+ /* choose random stride from 1 to edge */
+ for (k = 0; k < nslabs; k++) {
+ nstarts = 1;
+ for (j = 0; j < var_rank[i]; j++) {
+ if ((k >> j) & 1) {
+ start[j] = 0;
+ edge[j] = mid[j];
+ } else {
+ start[j] = mid[j];
+ edge[j] = var_shape[i][j] - mid[j];
+ }
+ sstride[j] = stride[j] = edge[j] > 0 ? 1+roll(edge[j]) : 1;
+ nstarts *= stride[j];
+ }
+ for (m = 0; m < nstarts; m++) {
+ err = toMixedBase(m, var_rank[i], sstride, index);
+ IF (err != NC_NOERR)
+ error("error in toMixedBase");
+ ELSE_NOK
+ nels = 1;
+ for (j = 0; j < var_rank[i]; j++) {
+ count[j] = 1 + (edge[j] - index[j] - 1) / stride[j];
+ nels *= count[j];
+ index[j] += start[j];
+ }
+ /* Random choice of forward or backward */
+/* TODO
+ if ( roll(2) ) {
+ for (j = 0; j < var_rank[i]; j++) {
+ index[j] += (count[j] - 1) * stride[j];
+ stride[j] = -stride[j];
+ }
+ }
+*/
+ if (var_rank[i] > 0) {
+ j = var_rank[i] - 1;
+ imap[j] = 1;
+ for (; j > 0; j--)
+ imap[j-1] = imap[j] * count[j];
+ }
+ for (allInExtRange = 1, j = 0; j < nels; j++) {
+ err = toMixedBase(j, var_rank[i], count, index2);
+ IF (err != NC_NOERR)
+ error("error in toMixedBase");
+ for (d = 0; d < var_rank[i]; d++)
+ index2[d] = index[d] + index2[d] * stride[d];
+ value[j] = hash_$1(var_type[i], var_rank[i], index2, NCT_ITYPE($1));
+ IfCheckTextChar($1, var_type[i])
+ allInExtRange &= inRange3(value[j], var_type[i], NCT_ITYPE($1));
+ }
+ if (var_rank[i] == 0 && i%2 == 0)
+ err = ncmpi_iput_varm_$1(ncid,i,NULL,NULL,NULL,NULL,value, &reqid);
+ else
+ err = ncmpi_iput_varm_$1(ncid,i,index,count,stride,imap,value,&reqid);
+ if (err == NC_NOERR || err == NC_ERANGE)
+ /* NC_ERANGE is not fatal, must continue */
+ ncmpi_wait_all(ncid, 1, &reqid, &status);
+ if (canConvert) {
+ if (allInExtRange) {
+ IF (err != NC_NOERR)
+ error("%s", ncmpi_strerror(err));
+ ELSE_NOK
+ IF (status != NC_NOERR)
+ error("%s", ncmpi_strerror(status));
+ ELSE_NOK
+ } else {
+ /* NC_ERANGE is checked at ncmpi_iput_varm_$1() */
+ IF (err != NC_ERANGE)
+ error("range error: err = %d", err);
+ ELSE_NOK
+ }
+ } else {
+ /* NC_ECHAR is checked at ncmpi_iput_varm_$1() */
+ IF (nels > 0 && err != NC_ECHAR)
+ error("wrong type: err = %d", err);
+ ELSE_NOK
+ }
+ }
+ }
+ }
+
+ err = ncmpi_close(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_close: %s", ncmpi_strerror(err));
+
+ nok += check_vars_$1(scratch);
+
+ err = ncmpi_delete(scratch, info);
+ IF (err != NC_NOERR)
+ error("remove of %s failed", scratch);
+ return nok;
+}
+')dnl
+
+TEST_NC_IPUT_VARM(text)
+TEST_NC_IPUT_VARM(uchar)
+TEST_NC_IPUT_VARM(schar)
+TEST_NC_IPUT_VARM(short)
+TEST_NC_IPUT_VARM(int)
+TEST_NC_IPUT_VARM(long)
+TEST_NC_IPUT_VARM(float)
+TEST_NC_IPUT_VARM(double)
+TEST_NC_IPUT_VARM(ushort)
+TEST_NC_IPUT_VARM(uint)
+TEST_NC_IPUT_VARM(longlong)
+TEST_NC_IPUT_VARM(ulonglong)
+
+
diff --git a/test/nc_test/test_put.m4 b/test/nc_test/test_put.m4
new file mode 100644
index 0000000..cb0391b
--- /dev/null
+++ b/test/nc_test/test_put.m4
@@ -0,0 +1,1265 @@
+dnl This is m4 source.
+dnl Process using m4 to produce 'C' language file.
+dnl
+dnl If you see this line, you can ignore the next one.
+/* Do not edit this file. It is produced from the corresponding .m4 source */
+dnl
+/*
+ * Copyright (C) 2003, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ */
+/* $Id: test_put.m4 2295 2016-01-06 20:28:09Z wkliao $ */
+
+
+undefine(`index')dnl
+dnl dnl dnl
+dnl
+dnl Macros
+dnl
+dnl dnl dnl
+dnl
+dnl Upcase(str)
+dnl
+define(`Upcase',dnl
+`dnl
+translit($1, abcdefghijklmnopqrstuvwxyz, ABCDEFGHIJKLMNOPQRSTUVWXYZ)')dnl
+dnl dnl dnl
+dnl
+dnl NCT_ITYPE(type)
+dnl
+define(`NCT_ITYPE', ``NCT_'Upcase($1)')dnl
+define(`NC_TYPE', ``NC_'Upcase($1)')dnl
+define(`X_MIN', ``X_'Upcase($1)_MIN')dnl
+define(`X_MAX', ``X_'Upcase($1)_MAX')dnl
+dnl
+
+define(`CheckText', `ifelse(`$1',`text', , `== (NCT_ITYPE($1) == NCT_TEXT)')')dnl
+define(`IfCheckTextChar', `ifelse(`$1',`text', `if ($2 != NC_CHAR)')')dnl
+define(`CheckNumRange',
+ `ifelse(`$1',`text', `1',
+ `inRange3($2,$3,NCT_ITYPE($1)) && ($2 >= $1_min && $2 <= $1_max)')')dnl
+define(`CheckRange',
+ `ifelse(`$1',`text', `0', `($2 >= $1_min && $2 <= $1_max)')')dnl
+define(`CheckRange3',
+ `ifelse(`$1',`text', `1',
+ `inRange3($2,$3,NCT_ITYPE($1))')')dnl
+
+#include "tests.h"
+
+dnl HASH(TYPE)
+dnl
+define(`HASH',dnl
+`dnl
+/*
+ * ensure hash value within range for internal TYPE
+ */
+static
+double
+hash_$1(
+ const nc_type type,
+ const int rank,
+ const MPI_Offset *index,
+ const nct_itype itype)
+{
+ const double min = $1_min;
+ const double max = $1_max;
+
+ return MAX(min, MIN(max, hash4( type, rank, index, itype)));
+}
+')dnl
+
+dnl HASH(text)
+#define hash_text hash4
+
+HASH(uchar)
+HASH(schar)
+HASH(short)
+HASH(int)
+HASH(long)
+HASH(float)
+HASH(double)
+HASH(ushort)
+HASH(uint)
+HASH(longlong)
+HASH(ulonglong)
+
+
+dnl CHECK_VARS(TYPE)
+dnl
+define(`CHECK_VARS',dnl
+`dnl
+/*
+ * check all vars in file which are (text/numeric) compatible with TYPE
+ */
+static
+int
+check_vars_$1(const char *filename)
+{
+ int ncid; /* netCDF id */
+ MPI_Offset index[MAX_RANK];
+ int err;
+ int d;
+ int i;
+ size_t j;
+ $1 value;
+ nc_type datatype;
+ int ndims;
+ int dimids[MAX_RANK];
+ char name[NC_MAX_NAME];
+ MPI_Offset length;
+ int canConvert; /* Both text or both numeric */
+ int nok = 0; /* count of valid comparisons */
+ double expect;
+
+ err = ncmpi_open(comm, filename, NC_NOWRITE, info, &ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_open: %s", ncmpi_strerror(err));
+
+ for (i = 0; i < numVars; i++) {
+ canConvert = (var_type[i] == NC_CHAR) CheckText($1);
+ if (canConvert) {
+ err = ncmpi_inq_var(ncid, i, name, &datatype, &ndims, dimids, NULL);
+ IF (err != NC_NOERR)
+ error("ncmpi_inq_var: %s", ncmpi_strerror(err));
+ IF (strcmp(name, var_name[i]) != 0)
+ error("Unexpected var_name");
+ IF (datatype != var_type[i])
+ error("Unexpected type");
+ IF (ndims != var_rank[i])
+ error("Unexpected rank");
+ for (j = 0; j < ndims; j++) {
+ err = ncmpi_inq_dim(ncid, dimids[j], 0, &length);
+ IF (err != NC_NOERR)
+ error("ncmpi_inq_dim: %s", ncmpi_strerror(err));
+ IF (length != var_shape[i][j])
+ error("Unexpected shape");
+ }
+ for (j = 0; j < var_nels[i]; j++) {
+ err = toMixedBase(j, var_rank[i], var_shape[i], index);
+ IF (err != NC_NOERR)
+ error("error in toMixedBase 2");
+ expect = hash4( var_type[i], var_rank[i], index, NCT_ITYPE($1));
+ err = ncmpi_get_var1_$1_all(ncid, i, index, &value);
+ if (CheckNumRange($1, expect, datatype)) {
+ IF (err != NC_NOERR) {
+ error("ncmpi_get_var1_$1_all: %s", ncmpi_strerror(err));
+ } else {
+ IF (!equal(value,expect,var_type[i],NCT_ITYPE($1))) {
+ error("Var value read not that expected");
+ if (verbose) {
+ error("\n");
+ error("varid: %d, ", i);
+ error("var_name: %s, ", var_name[i]);
+ error("var_type: %s, ", s_nc_type(var_type[i]));
+ error("index:");
+ for (d = 0; d < var_rank[i]; d++)
+ error(" %d", index[d]);
+ error(", expect: %g, ", expect);
+ error("got: %g", (double) value);
+ }
+ } else {
+ ++nok;
+ }
+ }
+ }
+ }
+ }
+ }
+ err = ncmpi_close(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_close: %s", ncmpi_strerror(err));
+ return nok;
+}
+')dnl
+
+CHECK_VARS(text)
+CHECK_VARS(uchar)
+CHECK_VARS(schar)
+CHECK_VARS(short)
+CHECK_VARS(int)
+CHECK_VARS(long)
+CHECK_VARS(float)
+CHECK_VARS(double)
+CHECK_VARS(ushort)
+CHECK_VARS(uint)
+CHECK_VARS(longlong)
+CHECK_VARS(ulonglong)
+
+
+dnl CHECK_ATTS(TYPE) numeric only
+dnl
+define(`CHECK_ATTS',dnl
+`dnl
+/*
+ * check all attributes in file which are (text/numeric) compatible with TYPE
+ * ignore any attributes containing values outside range of TYPE
+ */
+static
+int
+check_atts_$1(int ncid)
+{
+ int err;
+ int i;
+ int j;
+ MPI_Offset k;
+ $1 value[MAX_NELS];
+ nc_type datatype;
+ MPI_Offset length;
+ size_t nInExtRange; /* number values within external range */
+ size_t nInIntRange; /* number values within internal range */
+ int canConvert; /* Both text or both numeric */
+ int nok = 0; /* count of valid comparisons */
+ double expect[MAX_NELS];
+
+ for (i = -1; i < numVars; i++) {
+ for (j = 0; j < NATTS(i); j++) {
+ canConvert = (ATT_TYPE(i,j) == NC_CHAR) CheckText($1);
+ if (!canConvert) continue;
+
+ err = ncmpi_inq_att(ncid, i, ATT_NAME(i,j), &datatype, &length);
+ IF (err != NC_NOERR)
+ error("ncmpi_inq_att: %s", ncmpi_strerror(err));
+ IF (datatype != ATT_TYPE(i,j))
+ error("ncmpi_inq_att: unexpected type");
+ IF (length != ATT_LEN(i,j))
+ error("ncmpi_inq_att: unexpected length");
+ assert(length <= MAX_NELS);
+ nInIntRange = nInExtRange = 0;
+ for (k = 0; k < length; k++) {
+ expect[k] = hash4( datatype, -1, &k, NCT_ITYPE($1));
+ if (inRange3(expect[k], datatype, NCT_ITYPE($1))) {
+ ++nInExtRange;
+ if (CheckRange($1, expect[k]))
+ ++nInIntRange;
+ }
+ }
+ err = ncmpi_get_att_$1(ncid, i, ATT_NAME(i,j), value);
+ if (nInExtRange == length && nInIntRange == length) {
+ IF (err != NC_NOERR)
+ error("%s", ncmpi_strerror(err));
+ } else {
+ IF (err != NC_NOERR && err != NC_ERANGE)
+ error("OK or Range error: err = %d", err);
+ }
+ for (k = 0; k < length; k++) {
+ if (CheckNumRange($1, expect[k], datatype)) {
+ IF (!equal(value[k],expect[k],datatype,NCT_ITYPE($1))) {
+ error("att. value read not that expected");
+ if (verbose) {
+ error("\n");
+ error("varid: %d, ", i);
+ error("att_name: %s, ", ATT_NAME(i,j));
+ error("att_type: %s, ", s_nc_type(ATT_TYPE(i,j)));
+ error("element number: %d ", k);
+ error("expect: %g, ", expect[k]);
+ error("got: %g", (double) value[k]);
+ }
+ } else {
+ nok++;
+ }
+ }
+ }
+ }
+ }
+ return nok;
+}
+')dnl
+
+CHECK_ATTS(text)
+CHECK_ATTS(uchar)
+CHECK_ATTS(schar)
+CHECK_ATTS(short)
+CHECK_ATTS(int)
+CHECK_ATTS(long)
+CHECK_ATTS(float)
+CHECK_ATTS(double)
+CHECK_ATTS(ushort)
+CHECK_ATTS(uint)
+CHECK_ATTS(longlong)
+CHECK_ATTS(ulonglong)
+
+
+dnl TEST_NC_PUT_VAR1(TYPE)
+dnl
+define(`TEST_NC_PUT_VAR1',dnl
+`dnl
+int
+test_ncmpi_put_var1_$1(void)
+{
+ int ncid, nok=0;
+ int i;
+ int j;
+ int err;
+ MPI_Offset index[MAX_RANK];
+ int canConvert; /* Both text or both numeric */
+ $1 value = 5; /* any value would do - only for error cases */
+
+ err = ncmpi_create(comm, scratch, NC_CLOBBER|extra_flags, info, &ncid);
+ IF (err != NC_NOERR) {
+ error("ncmpi_create: %s", ncmpi_strerror(err));
+ return nok;
+ }
+ def_dims(ncid);
+ def_vars(ncid);
+ err = ncmpi_enddef(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_enddef: %s", ncmpi_strerror(err));
+
+ for (i = 0; i < numVars; i++) {
+ canConvert = (var_type[i] == NC_CHAR) CheckText($1);
+ for (j = 0; j < var_rank[i]; j++)
+ index[j] = 0;
+ err = ncmpi_put_var1_$1_all(BAD_ID, i, index, &value);
+ IF (err != NC_EBADID)
+ error("expecting NC_EBADID (bad ncid), but err = %s", nc_err_code_name(err));
+ ELSE_NOK
+ err = ncmpi_put_var1_$1_all(ncid, BAD_VARID, index, &value);
+ IF (err != NC_ENOTVAR)
+ error("expecting NC_ENOTVAR (bad var id), but err = %s", nc_err_code_name(err));
+ ELSE_NOK
+ for (j = 0; j < var_rank[i]; j++) {
+ if (var_dimid[i][j] > 0) { /* skip record dim */
+ index[j] = var_shape[i][j]; /* out of boundary check */
+ err = ncmpi_put_var1_$1_all(ncid, i, index, &value);
+ IF (canConvert && err != NC_EINVALCOORDS)
+ error("expecting NC_EINVALCOORDS (bad index), but err = %s", nc_err_code_name(err));
+ ELSE_NOK
+ index[j] = 0;
+ }
+ }
+ for (j = 0; j < var_nels[i]; j++) {
+ err = toMixedBase(j, var_rank[i], var_shape[i], index);
+ IF (err != NC_NOERR)
+ error("error in toMixedBase 1");
+ value = hash_$1( var_type[i], var_rank[i], index, NCT_ITYPE($1));
+ if (var_rank[i] == 0 && i%2 == 0)
+ err = ncmpi_put_var1_$1_all(ncid, i, NULL, &value);
+ else
+ err = ncmpi_put_var1_$1_all(ncid, i, index, &value);
+ if (canConvert) {
+ if (CheckRange3($1, value, var_type[i])) {
+ IF (err != NC_NOERR)
+ error("%s", ncmpi_strerror(err));
+ ELSE_NOK
+ } else {
+ IF (err != NC_ERANGE) {
+ error("Range error: err = %d", err);
+ error("\n\t\tfor type %s value %.17e %ld",
+ s_nc_type(var_type[i]),
+ (double)value, (long)value);
+ }
+ ELSE_NOK
+ }
+ } else {
+ IF (err != NC_ECHAR)
+ error("wrong type: err = %d", err);
+ ELSE_NOK
+ }
+ }
+ }
+
+ err = ncmpi_close(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_close: %s", ncmpi_strerror(err));
+
+ nok += check_vars_$1(scratch);
+
+ err = ncmpi_delete(scratch, info);
+ IF (err != NC_NOERR)
+ error("remove of %s failed", scratch);
+ return nok;
+}
+')dnl
+
+TEST_NC_PUT_VAR1(text)
+TEST_NC_PUT_VAR1(uchar)
+TEST_NC_PUT_VAR1(schar)
+TEST_NC_PUT_VAR1(short)
+TEST_NC_PUT_VAR1(int)
+TEST_NC_PUT_VAR1(long)
+TEST_NC_PUT_VAR1(float)
+TEST_NC_PUT_VAR1(double)
+TEST_NC_PUT_VAR1(ushort)
+TEST_NC_PUT_VAR1(uint)
+TEST_NC_PUT_VAR1(longlong)
+TEST_NC_PUT_VAR1(ulonglong)
+
+
+dnl TEST_NC_PUT_VAR(TYPE)
+dnl
+define(`TEST_NC_PUT_VAR',dnl
+`dnl
+int
+test_ncmpi_put_var_$1(void)
+{
+ int ncid, nok=0;
+ int varid;
+ int i;
+ int j;
+ int err;
+ int nels;
+ MPI_Offset index[MAX_RANK];
+ int canConvert; /* Both text or both numeric */
+ int allInExtRange; /* all values within external range? */
+ $1 value[MAX_NELS];
+
+ err = ncmpi_create(comm, scratch, NC_CLOBBER|extra_flags, info, &ncid);
+ IF (err != NC_NOERR) {
+ error("ncmpi_create: %s", ncmpi_strerror(err));
+ return nok;
+ }
+ def_dims(ncid);
+ def_vars(ncid);
+ err = ncmpi_enddef(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_enddef: %s", ncmpi_strerror(err));
+
+ for (i = 0; i < numVars; i++) {
+ canConvert = (var_type[i] == NC_CHAR) CheckText($1);
+ assert(var_rank[i] <= MAX_RANK);
+ assert(var_nels[i] <= MAX_NELS);
+ err = ncmpi_put_var_$1_all(BAD_ID, i, value);
+ IF (err != NC_EBADID)
+ error("expecting bad ncid, but err = %d", err);
+ ELSE_NOK
+ err = ncmpi_put_var_$1_all(ncid, BAD_VARID, value);
+ IF (err != NC_ENOTVAR)
+ error("expecting bad var id, but err = %d", err);
+ ELSE_NOK
+
+ nels = 1;
+ for (j = 0; j < var_rank[i]; j++) {
+ nels *= var_shape[i][j];
+ }
+ for (allInExtRange = 1, j = 0; j < nels; j++) {
+ err = toMixedBase(j, var_rank[i], var_shape[i], index);
+ IF (err != NC_NOERR)
+ error("error in toMixedBase 1");
+ value[j]= hash_$1(var_type[i], var_rank[i], index, NCT_ITYPE($1));
+ IfCheckTextChar($1, var_type[i])
+ allInExtRange &= inRange3(value[j], var_type[i], NCT_ITYPE($1));
+ }
+ err = ncmpi_put_var_$1_all(ncid, i, value);
+ if (canConvert) {
+ if (allInExtRange) {
+ IF (err != NC_NOERR)
+ error("%s", ncmpi_strerror(err));
+ ELSE_NOK
+ } else {
+ IF (err != NC_ERANGE && var_dimid[i][0] != RECDIM)
+ error("expecting range error, but err = %d", err);
+ ELSE_NOK
+ }
+ } else { /* should flag wrong type even if nothing to write */
+ IF (nels > 0 && err != NC_ECHAR)
+ error("wrong type: err = %d", err);
+ ELSE_NOK
+ }
+ }
+
+ /* Preceeding has written nothing for record variables, now try */
+ /* again with more than 0 records */
+
+ /* Write record number NRECS to force writing of preceding records */
+ /* Assumes variable cr is char vector with UNLIMITED dimension */
+ err = ncmpi_inq_varid(ncid, "cr", &varid);
+ IF (err != NC_NOERR)
+ error("ncmpi_inq_varid: %s", ncmpi_strerror(err));
+ index[0] = NRECS-1;
+ err = ncmpi_put_var1_text_all(ncid, varid, index, "x");
+ IF (err != NC_NOERR)
+ error("ncmpi_put_var1_text_all: %s", ncmpi_strerror(err));
+
+ for (i = 0; i < numVars; i++) {
+ if (var_dimid[i][0] == RECDIM) { /* only test record variables here */
+ canConvert = (var_type[i] == NC_CHAR) CheckText($1);
+ assert(var_rank[i] <= MAX_RANK);
+ assert(var_nels[i] <= MAX_NELS);
+ err = ncmpi_put_var_$1_all(BAD_ID, i, value);
+ IF (err != NC_EBADID)
+ error("expecting bad ncid, but err = %d", err);
+ ELSE_NOK
+
+ nels = 1;
+ for (j = 0; j < var_rank[i]; j++) {
+ nels *= var_shape[i][j];
+ }
+ for (allInExtRange = 1, j = 0; j < nels; j++) {
+ err = toMixedBase(j, var_rank[i], var_shape[i], index);
+ IF (err != NC_NOERR)
+ error("error in toMixedBase 1");
+ ELSE_NOK
+ value[j]= hash_$1(var_type[i], var_rank[i], index, NCT_ITYPE($1));
+ IfCheckTextChar($1, var_type[i])
+ allInExtRange &= inRange3(value[j], var_type[i], NCT_ITYPE($1));
+ }
+ err = ncmpi_put_var_$1_all(ncid, i, value);
+ if (canConvert) {
+ if (allInExtRange) {
+ IF (err != NC_NOERR)
+ error("%s", ncmpi_strerror(err));
+ ELSE_NOK
+ } else {
+ IF (err != NC_ERANGE)
+ error("expecting range error, but err = %d", err);
+ ELSE_NOK
+ }
+ } else {
+ IF (nels > 0 && err != NC_ECHAR)
+ error("wrong type: err = %d", err);
+ ELSE_NOK
+ }
+ }
+ }
+
+ err = ncmpi_close(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_close: %s", ncmpi_strerror(err));
+
+ nok += check_vars_$1(scratch);
+
+ err = ncmpi_delete(scratch, info);
+ IF (err != NC_NOERR)
+ error("remove of %s failed", scratch);
+ return nok;
+}
+')dnl
+
+TEST_NC_PUT_VAR(text)
+TEST_NC_PUT_VAR(uchar)
+TEST_NC_PUT_VAR(schar)
+TEST_NC_PUT_VAR(short)
+TEST_NC_PUT_VAR(int)
+TEST_NC_PUT_VAR(long)
+TEST_NC_PUT_VAR(float)
+TEST_NC_PUT_VAR(double)
+TEST_NC_PUT_VAR(ushort)
+TEST_NC_PUT_VAR(uint)
+TEST_NC_PUT_VAR(longlong)
+TEST_NC_PUT_VAR(ulonglong)
+
+
+dnl TEST_NC_PUT_VARA(TYPE)
+dnl
+define(`TEST_NC_PUT_VARA',dnl
+`dnl
+int
+test_ncmpi_put_vara_$1(void)
+{
+ int ncid, nok=0;
+ int d;
+ int i;
+ int j;
+ int k;
+ int err;
+ int nslabs;
+ int nels;
+ MPI_Offset start[MAX_RANK];
+ MPI_Offset edge[MAX_RANK];
+ MPI_Offset mid[MAX_RANK];
+ MPI_Offset index[MAX_RANK];
+ int canConvert; /* Both text or both numeric */
+ int allInExtRange; /* all values within external range? */
+ $1 value[MAX_NELS];
+
+ err = ncmpi_create(comm, scratch, NC_CLOBBER|extra_flags, info, &ncid);
+ IF (err != NC_NOERR) {
+ error("ncmpi_create: %s", ncmpi_strerror(err));
+ return nok;
+ }
+ def_dims(ncid);
+ def_vars(ncid);
+ err = ncmpi_enddef(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_enddef: %s", ncmpi_strerror(err));
+
+ value[0] = 0;
+ for (i = 0; i < numVars; i++) {
+ canConvert = (var_type[i] == NC_CHAR) CheckText($1);
+ assert(var_rank[i] <= MAX_RANK);
+ assert(var_nels[i] <= MAX_NELS);
+ for (j = 0; j < var_rank[i]; j++) {
+ start[j] = 0;
+ edge[j] = 1;
+ }
+ err = ncmpi_put_vara_$1_all(BAD_ID, i, start, edge, value);
+ IF (err != NC_EBADID)
+ error("expecting bad ncid, but err = %d", err);
+ ELSE_NOK
+ err = ncmpi_put_vara_$1_all(ncid, BAD_VARID, start, edge, value);
+ IF (err != NC_ENOTVAR)
+ error("expecting bad var id, but err = %d", err);
+ ELSE_NOK
+ for (j = 0; j < var_rank[i]; j++) {
+ if (var_dimid[i][j] > 0) { /* skip record dim */
+ start[j] = var_shape[i][j];
+ err = ncmpi_put_vara_$1_all(ncid, i, start, edge, value);
+ IF (canConvert && err != NC_EINVALCOORDS)
+ error("expecting bad start, but err = %d", err);
+ ELSE_NOK
+ start[j] = 0;
+ edge[j] = var_shape[i][j] + 1;
+ err = ncmpi_put_vara_$1_all(ncid, i, start, edge, value);
+ IF (canConvert && err != NC_EEDGE)
+ error("expecting bad edge, but err = %d", err);
+ ELSE_NOK
+ edge[j] = 1;
+ }
+ }
+
+ /* Check correct error returned even when nothing to put */
+ for (j = 0; j < var_rank[i]; j++) {
+ edge[j] = 0;
+ }
+ err = ncmpi_put_vara_$1_all(BAD_ID, i, start, edge, value);
+ IF (err != NC_EBADID)
+ error("expecting bad ncid, but err = %d", err);
+ ELSE_NOK
+ err = ncmpi_put_vara_$1_all(ncid, BAD_VARID, start, edge, value);
+ IF (err != NC_ENOTVAR)
+ error("expecting bad var id, but err = %d", err);
+ ELSE_NOK
+ for (j = 0; j < var_rank[i]; j++) {
+ if (var_dimid[i][j] > 0) { /* skip record dim */
+ start[j] = var_shape[i][j];
+ err = ncmpi_put_vara_$1_all(ncid, i, start, edge, value);
+ IF (canConvert && err != NC_EINVALCOORDS)
+ error("expecting bad start, but err = %d", err);
+ ELSE_NOK
+ start[j] = 0;
+ }
+ }
+
+/* wkliao: this test below of put_vara is redundant and incorrectly uses the
+ value[] set from the previously iteration. There is no such test
+ in put_vars and put_varm.
+
+ err = ncmpi_put_vara_$1_all(ncid, i, start, edge, value);
+ if (canConvert) {
+ IF (err != NC_NOERR)
+ error("%s", ncmpi_strerror(err));
+ ELSE_NOK
+ } else {
+ IF (err != NC_ECHAR)
+ error("wrong type: err = %d", err);
+ ELSE_NOK
+ }
+*/
+ for (j = 0; j < var_rank[i]; j++) {
+ edge[j] = 1;
+ }
+
+ /* Choose a random point dividing each dim into 2 parts */
+ /* Put 2^rank (nslabs) slabs so defined */
+ nslabs = 1;
+ for (j = 0; j < var_rank[i]; j++) {
+ mid[j] = roll( var_shape[i][j] );
+ nslabs *= 2;
+ }
+ /* bits of k determine whether to put lower or upper part of dim */
+ for (k = 0; k < nslabs; k++) {
+ nels = 1;
+ for (j = 0; j < var_rank[i]; j++) {
+ if ((k >> j) & 1) {
+ start[j] = 0;
+ edge[j] = mid[j];
+ } else {
+ start[j] = mid[j];
+ edge[j] = var_shape[i][j] - mid[j];
+ }
+ nels *= edge[j];
+ }
+ for (allInExtRange = 1, j = 0; j < nels; j++) {
+ err = toMixedBase(j, var_rank[i], edge, index);
+ IF (err != NC_NOERR)
+ error("error in toMixedBase 1");
+ for (d = 0; d < var_rank[i]; d++)
+ index[d] += start[d];
+ value[j]= hash_$1(var_type[i], var_rank[i], index, NCT_ITYPE($1));
+ IfCheckTextChar($1, var_type[i])
+ allInExtRange &= inRange3(value[j], var_type[i], NCT_ITYPE($1));
+ }
+ if (var_rank[i] == 0 && i%2 == 0)
+ err = ncmpi_put_vara_$1_all(ncid, i, NULL, NULL, value);
+ else
+ err = ncmpi_put_vara_$1_all(ncid, i, start, edge, value);
+ if (canConvert) {
+ if (allInExtRange) {
+ IF (err != NC_NOERR)
+ error("%s", ncmpi_strerror(err));
+ ELSE_NOK
+ } else {
+ IF (err != NC_ERANGE)
+ error("expecting range error, but err = %d", err);
+ ELSE_NOK
+ }
+ } else {
+ IF (nels > 0 && err != NC_ECHAR)
+ error("wrong type: err = %d", err);
+ ELSE_NOK
+ }
+ }
+ }
+
+ err = ncmpi_close(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_close: %s", ncmpi_strerror(err));
+
+ nok += check_vars_$1(scratch);
+
+ err = ncmpi_delete(scratch, info);
+ IF (err != NC_NOERR)
+ error("remove of %s failed", scratch);
+ return nok;
+}
+')dnl
+
+TEST_NC_PUT_VARA(text)
+TEST_NC_PUT_VARA(uchar)
+TEST_NC_PUT_VARA(schar)
+TEST_NC_PUT_VARA(short)
+TEST_NC_PUT_VARA(int)
+TEST_NC_PUT_VARA(long)
+TEST_NC_PUT_VARA(float)
+TEST_NC_PUT_VARA(double)
+TEST_NC_PUT_VARA(ushort)
+TEST_NC_PUT_VARA(uint)
+TEST_NC_PUT_VARA(longlong)
+TEST_NC_PUT_VARA(ulonglong)
+
+
+dnl TEST_NC_PUT_VARS(TYPE)
+dnl
+define(`TEST_NC_PUT_VARS',dnl
+`dnl
+int
+test_ncmpi_put_vars_$1(void)
+{
+ int ncid, nok=0;
+ int d;
+ int i;
+ int j;
+ int k;
+ int m;
+ int err;
+ int nels;
+ int nslabs;
+ int nstarts; /* number of different starts */
+ MPI_Offset start[MAX_RANK];
+ MPI_Offset edge[MAX_RANK];
+ MPI_Offset index[MAX_RANK];
+ MPI_Offset index2[MAX_RANK];
+ MPI_Offset mid[MAX_RANK];
+ MPI_Offset count[MAX_RANK];
+ MPI_Offset sstride[MAX_RANK];
+ MPI_Offset stride[MAX_RANK];
+ int canConvert; /* Both text or both numeric */
+ int allInExtRange; /* all values within external range? */
+ $1 value[MAX_NELS];
+
+ err = ncmpi_create(comm, scratch, NC_CLOBBER|extra_flags, info, &ncid);
+ IF (err != NC_NOERR) {
+ error("ncmpi_create: %s", ncmpi_strerror(err));
+ return nok;
+ }
+ def_dims(ncid);
+ def_vars(ncid);
+ err = ncmpi_enddef(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_enddef: %s", ncmpi_strerror(err));
+
+ for (i = 0; i < numVars; i++) {
+ canConvert = (var_type[i] == NC_CHAR) CheckText($1);
+ assert(var_rank[i] <= MAX_RANK);
+ assert(var_nels[i] <= MAX_NELS);
+ for (j = 0; j < var_rank[i]; j++) {
+ start[j] = 0;
+ edge[j] = 1;
+ stride[j] = 1;
+ }
+ err = ncmpi_put_vars_$1_all(BAD_ID, i, start, edge, stride, value);
+ IF (err != NC_EBADID)
+ error("expecting bad ncid, but err = %d", err);
+ ELSE_NOK
+ err = ncmpi_put_vars_$1_all(ncid, BAD_VARID, start, edge, stride, value);
+ IF (err != NC_ENOTVAR)
+ error("expecting bad var id, but err = %d", err);
+ ELSE_NOK
+ for (j = 0; j < var_rank[i]; j++) {
+ if (var_dimid[i][j] > 0) { /* skip record dim */
+ start[j] = var_shape[i][j];
+ err = ncmpi_put_vars_$1_all(ncid, i, start, edge, stride, value);
+ if (!canConvert) {
+ IF (err != NC_ECHAR)
+ error("conversion: err = %d", err);
+ ELSE_NOK
+ } else {
+ IF (err != NC_EINVALCOORDS)
+ error("expecting bad start, but err = %d", err);
+ ELSE_NOK
+ start[j] = 0;
+ edge[j] = var_shape[i][j] + 1;
+ err = ncmpi_put_vars_$1_all(ncid, i, start, edge, stride, value);
+ IF (err != NC_EEDGE)
+ error("expecting bad edge, but err = %d", err);
+ ELSE_NOK
+ edge[j] = 1;
+ stride[j] = 0;
+ err = ncmpi_put_vars_$1_all(ncid, i, start, edge, stride, value);
+ IF (err != NC_ESTRIDE)
+ error("expecting bad stride, but err = %d", err);
+ ELSE_NOK
+ stride[j] = 1;
+ }
+ }
+ }
+
+ /* Choose a random point dividing each dim into 2 parts */
+ /* Put 2^rank (nslabs) slabs so defined */
+ nslabs = 1;
+ for (j = 0; j < var_rank[i]; j++) {
+ mid[j] = roll( var_shape[i][j] );
+ nslabs *= 2;
+ }
+ /* bits of k determine whether to put lower or upper part of dim */
+ /* choose random stride from 1 to edge */
+ for (k = 0; k < nslabs; k++) {
+ nstarts = 1;
+ for (j = 0; j < var_rank[i]; j++) {
+ if ((k >> j) & 1) {
+ start[j] = 0;
+ edge[j] = mid[j];
+ } else {
+ start[j] = mid[j];
+ edge[j] = var_shape[i][j] - mid[j];
+ }
+ sstride[j] = stride[j] = edge[j] > 0 ? 1+roll(edge[j]) : 1;
+ nstarts *= stride[j];
+ }
+ for (m = 0; m < nstarts; m++) {
+ err = toMixedBase(m, var_rank[i], sstride, index);
+ IF (err != NC_NOERR)
+ error("error in toMixedBase");
+ nels = 1;
+ for (j = 0; j < var_rank[i]; j++) {
+ count[j] = 1 + (edge[j] - index[j] - 1) / stride[j];
+ nels *= count[j];
+ index[j] += start[j];
+ }
+ /* Random choice of forward or backward */
+/* TODO
+ if ( roll(2) ) {
+ for (j = 0; j < var_rank[i]; j++) {
+ index[j] += (count[j] - 1) * stride[j];
+ stride[j] = -stride[j];
+ }
+ }
+*/
+ for (allInExtRange = 1, j = 0; j < nels; j++) {
+ err = toMixedBase(j, var_rank[i], count, index2);
+ IF (err != NC_NOERR)
+ error("error in toMixedBase");
+ for (d = 0; d < var_rank[i]; d++)
+ index2[d] = index[d] + index2[d] * stride[d];
+ value[j] = hash_$1(var_type[i], var_rank[i], index2,
+ NCT_ITYPE($1));
+ IfCheckTextChar($1, var_type[i])
+ allInExtRange &= inRange3(value[j], var_type[i], NCT_ITYPE($1));
+ }
+ if (var_rank[i] == 0 && i%2 == 0)
+ err = ncmpi_put_vars_$1_all(ncid, i, NULL, NULL, stride, value);
+ else
+ err = ncmpi_put_vars_$1_all(ncid, i, index, count, stride, value);
+ if (canConvert) {
+ if (allInExtRange) {
+ IF (err != NC_NOERR)
+ error("%s", ncmpi_strerror(err));
+ ELSE_NOK
+ } else {
+ IF (err != NC_ERANGE)
+ error("expecting range error, but err = %d", err);
+ ELSE_NOK
+ }
+ } else {
+ IF (nels > 0 && err != NC_ECHAR)
+ error("wrong type: err = %d", err);
+ ELSE_NOK
+ }
+ }
+ }
+ }
+
+ err = ncmpi_close(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_close: %s", ncmpi_strerror(err));
+
+ nok += check_vars_$1(scratch);
+
+ err = ncmpi_delete(scratch, info);
+ IF (err != NC_NOERR)
+ error("remove of %s failed", scratch);
+ return nok;
+}
+')dnl
+
+TEST_NC_PUT_VARS(text)
+TEST_NC_PUT_VARS(uchar)
+TEST_NC_PUT_VARS(schar)
+TEST_NC_PUT_VARS(short)
+TEST_NC_PUT_VARS(int)
+TEST_NC_PUT_VARS(long)
+TEST_NC_PUT_VARS(float)
+TEST_NC_PUT_VARS(double)
+TEST_NC_PUT_VARS(ushort)
+TEST_NC_PUT_VARS(uint)
+TEST_NC_PUT_VARS(longlong)
+TEST_NC_PUT_VARS(ulonglong)
+
+
+dnl TEST_NC_PUT_VARM(TYPE)
+dnl
+define(`TEST_NC_PUT_VARM',dnl
+`dnl
+int
+test_ncmpi_put_varm_$1(void)
+{
+ int ncid, nok=0;
+ int d;
+ int i;
+ int j;
+ int k;
+ int m;
+ int err;
+ int nels;
+ int nslabs;
+ int nstarts; /* number of different starts */
+ MPI_Offset start[MAX_RANK];
+ MPI_Offset edge[MAX_RANK];
+ MPI_Offset index[MAX_RANK];
+ MPI_Offset index2[MAX_RANK];
+ MPI_Offset mid[MAX_RANK];
+ MPI_Offset count[MAX_RANK];
+ MPI_Offset sstride[MAX_RANK];
+ MPI_Offset stride[MAX_RANK];
+ MPI_Offset imap[MAX_RANK];
+ int canConvert; /* Both text or both numeric */
+ int allInExtRange; /* all values within external range? */
+ $1 value[MAX_NELS];
+
+ err = ncmpi_create(comm, scratch, NC_CLOBBER|extra_flags, info, &ncid);
+ IF (err != NC_NOERR) {
+ error("ncmpi_create: %s", ncmpi_strerror(err));
+ return nok;
+ }
+ def_dims(ncid);
+ def_vars(ncid);
+ err = ncmpi_enddef(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_enddef: %s", ncmpi_strerror(err));
+
+ for (i = 0; i < numVars; i++) {
+ canConvert = (var_type[i] == NC_CHAR) CheckText($1);
+ assert(var_rank[i] <= MAX_RANK);
+ assert(var_nels[i] <= MAX_NELS);
+ for (j = 0; j < var_rank[i]; j++) {
+ start[j] = 0;
+ edge[j] = 1;
+ stride[j] = 1;
+ imap[j] = 1;
+ }
+ err = ncmpi_put_varm_$1_all(BAD_ID, i, start, edge, stride, imap, value);
+ IF (err != NC_EBADID)
+ error("expecting bad ncid, but err = %d", err);
+ ELSE_NOK
+ err = ncmpi_put_varm_$1_all(ncid, BAD_VARID, start, edge, stride, imap, value);
+ IF (err != NC_ENOTVAR)
+ error("expecting bad var id, but err = %d", err);
+ ELSE_NOK
+ for (j = 0; j < var_rank[i]; j++) {
+ if (var_dimid[i][j] > 0) { /* skip record dim */
+ start[j] = var_shape[i][j];
+ err = ncmpi_put_varm_$1_all(ncid, i, start, edge, stride, imap, value);
+ if (!canConvert) {
+ IF (err != NC_ECHAR)
+ error("conversion: err = %d", err);
+ ELSE_NOK
+ } else {
+ IF (err != NC_EINVALCOORDS)
+ error("expecting bad start, but err = %d", err);
+ ELSE_NOK
+ start[j] = 0;
+ edge[j] = var_shape[i][j] + 1;
+ err = ncmpi_put_varm_$1_all(ncid, i, start, edge, stride, imap, value);
+ IF (err != NC_EEDGE)
+ error("expecting bad edge, but err = %d", err);
+ ELSE_NOK
+ edge[j] = 1;
+ stride[j] = 0;
+ err = ncmpi_put_varm_$1_all(ncid, i, start, edge, stride, imap, value);
+ IF (err != NC_ESTRIDE)
+ error("expecting bad stride, but err = %d", err);
+ ELSE_NOK
+ stride[j] = 1;
+ }
+ }
+ }
+
+ /* Choose a random point dividing each dim into 2 parts */
+ /* Put 2^rank (nslabs) slabs so defined */
+ nslabs = 1;
+ for (j = 0; j < var_rank[i]; j++) {
+ mid[j] = roll( var_shape[i][j] );
+ nslabs *= 2;
+ }
+ /* bits of k determine whether to put lower or upper part of dim */
+ /* choose random stride from 1 to edge */
+ for (k = 0; k < nslabs; k++) {
+ nstarts = 1;
+ for (j = 0; j < var_rank[i]; j++) {
+ if ((k >> j) & 1) {
+ start[j] = 0;
+ edge[j] = mid[j];
+ } else {
+ start[j] = mid[j];
+ edge[j] = var_shape[i][j] - mid[j];
+ }
+ sstride[j] = stride[j] = edge[j] > 0 ? 1+roll(edge[j]) : 1;
+ nstarts *= stride[j];
+ }
+ for (m = 0; m < nstarts; m++) {
+ err = toMixedBase(m, var_rank[i], sstride, index);
+ IF (err != NC_NOERR)
+ error("error in toMixedBase");
+ nels = 1;
+ for (j = 0; j < var_rank[i]; j++) {
+ count[j] = 1 + (edge[j] - index[j] - 1) / stride[j];
+ nels *= count[j];
+ index[j] += start[j];
+ }
+ /* Random choice of forward or backward */
+/* TODO
+ if ( roll(2) ) {
+ for (j = 0; j < var_rank[i]; j++) {
+ index[j] += (count[j] - 1) * stride[j];
+ stride[j] = -stride[j];
+ }
+ }
+*/
+ if (var_rank[i] > 0) {
+ j = var_rank[i] - 1;
+ imap[j] = 1;
+ for (; j > 0; j--)
+ imap[j-1] = imap[j] * count[j];
+ }
+ for (allInExtRange = 1, j = 0; j < nels; j++) {
+ err = toMixedBase(j, var_rank[i], count, index2);
+ IF (err != NC_NOERR)
+ error("error in toMixedBase");
+ for (d = 0; d < var_rank[i]; d++)
+ index2[d] = index[d] + index2[d] * stride[d];
+ value[j] = hash_$1(var_type[i], var_rank[i], index2,
+ NCT_ITYPE($1));
+ IfCheckTextChar($1, var_type[i])
+ allInExtRange &= inRange3(value[j], var_type[i], NCT_ITYPE($1));
+ }
+ if (var_rank[i] == 0 && i%2 == 0)
+ err = ncmpi_put_varm_$1_all(ncid,i,NULL,NULL,NULL,NULL,value);
+ else
+ err = ncmpi_put_varm_$1_all(ncid,i,index,count,stride,imap,value);
+ if (canConvert) {
+ if (allInExtRange) {
+ IF (err != NC_NOERR)
+ error("%s", ncmpi_strerror(err));
+ ELSE_NOK
+ } else {
+ IF (err != NC_ERANGE)
+ error("expecting range error, but err = %d", err);
+ ELSE_NOK
+ }
+ } else {
+ IF (nels > 0 && err != NC_ECHAR)
+ error("wrong type: err = %d", err);
+ ELSE_NOK
+ }
+ }
+ }
+ }
+
+ err = ncmpi_close(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_close: %s", ncmpi_strerror(err));
+
+ nok += check_vars_$1(scratch);
+
+ err = ncmpi_delete(scratch, info);
+ IF (err != NC_NOERR)
+ error("remove of %s failed", scratch);
+ return nok;
+}
+')dnl
+
+TEST_NC_PUT_VARM(text)
+TEST_NC_PUT_VARM(uchar)
+TEST_NC_PUT_VARM(schar)
+TEST_NC_PUT_VARM(short)
+TEST_NC_PUT_VARM(int)
+TEST_NC_PUT_VARM(long)
+TEST_NC_PUT_VARM(float)
+TEST_NC_PUT_VARM(double)
+TEST_NC_PUT_VARM(ushort)
+TEST_NC_PUT_VARM(uint)
+TEST_NC_PUT_VARM(longlong)
+TEST_NC_PUT_VARM(ulonglong)
+
+
+int
+test_ncmpi_put_att_text(void)
+{
+ int ncid, nok=0;
+ int i;
+ int j;
+ MPI_Offset k;
+ int err;
+ text value[MAX_NELS];
+
+ err = ncmpi_create(comm, scratch, NC_NOCLOBBER|extra_flags, info, &ncid);
+ IF (err != NC_NOERR) {
+ error("ncmpi_create: %s", ncmpi_strerror(err));
+ return nok;
+ }
+ def_dims(ncid);
+ def_vars(ncid);
+
+ {
+ const char *const tval = "value for bad name";
+ const size_t tval_len = strlen(tval);
+
+ err = ncmpi_put_att_text(ncid, 0, "", tval_len, tval);
+ IF (err != NC_EBADNAME)
+ error("should be NC_EBADNAME: err = %d", err);
+ ELSE_NOK
+ }
+ for (i = -1; i < numVars; i++) {
+ for (j = 0; j < NATTS(i); j++) {
+ if (ATT_TYPE(i,j) == NC_CHAR) {
+ assert(ATT_LEN(i,j) <= MAX_NELS);
+ err = ncmpi_put_att_text(BAD_ID, i, ATT_NAME(i,j), ATT_LEN(i,j),
+ value);
+ IF (err != NC_EBADID)
+ error("expecting bad ncid, but err = %d", err);
+ ELSE_NOK
+ err = ncmpi_put_att_text(ncid, BAD_VARID, ATT_NAME(i,j),
+ ATT_LEN(i,j), value);
+ IF (err != NC_ENOTVAR)
+ error("expecting bad var id, but err = %d", err);
+ ELSE_NOK
+ for (k = 0; k < ATT_LEN(i,j); k++) {
+ value[k] = hash(ATT_TYPE(i,j), -1, &k);
+ }
+ err = ncmpi_put_att_text(ncid, i, ATT_NAME(i,j),
+ ATT_LEN(i,j), value);
+ IF (err != NC_NOERR)
+ error("%s", ncmpi_strerror(err));
+ ELSE_NOK
+ }
+ }
+ }
+
+ nok += check_atts_text(ncid);
+ err = ncmpi_close(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_close: %s", ncmpi_strerror(err));
+
+ err = ncmpi_delete(scratch, info);
+ IF (err != NC_NOERR)
+ error("remove of %s failed", scratch);
+ return nok;
+}
+
+
+dnl TEST_NC_PUT_ATT(TYPE) numeric only
+dnl
+define(`TEST_NC_PUT_ATT',dnl
+`dnl
+int
+test_ncmpi_put_att_$1(void)
+{
+ int ncid, nok=0;
+ int i;
+ int j;
+ MPI_Offset k;
+ int err;
+ $1 value[MAX_NELS];
+ int allInExtRange; /* all values within external range? */
+
+ err = ncmpi_create(comm, scratch, NC_NOCLOBBER|extra_flags, info, &ncid);
+ IF (err != NC_NOERR) {
+ error("ncmpi_create: %s", ncmpi_strerror(err));
+ return nok;
+ }
+ def_dims(ncid);
+ def_vars(ncid);
+
+ for (i = -1; i < numVars; i++) {
+ for (j = 0; j < NATTS(i); j++) {
+ if (!(ATT_TYPE(i,j) == NC_CHAR)) {
+ assert(ATT_LEN(i,j) <= MAX_NELS);
+ err = ncmpi_put_att_$1(BAD_ID, i, ATT_NAME(i,j), ATT_TYPE(i,j),
+ ATT_LEN(i,j), value);
+ IF (err != NC_EBADID)
+ error("expecting bad ncid, but err = %d", err);
+ ELSE_NOK
+ err = ncmpi_put_att_$1(ncid, BAD_VARID, ATT_NAME(i,j),
+ ATT_TYPE(i,j), ATT_LEN(i,j), value);
+ IF (err != NC_ENOTVAR)
+ error("expecting bad var id, but err = %d", err);
+ ELSE_NOK
+ err = ncmpi_put_att_$1(ncid, i, ATT_NAME(i,j), BAD_TYPE,
+ ATT_LEN(i,j), value);
+ IF (err != NC_EBADTYPE)
+ error("expecting bad type, but err = %d", err);
+ ELSE_NOK
+ for (allInExtRange = 1, k = 0; k < ATT_LEN(i,j); k++) {
+ value[k] = hash_$1(ATT_TYPE(i,j), -1, &k, NCT_ITYPE($1));
+ IfCheckTextChar($1, ATT_TYPE(i,j))
+ allInExtRange &= inRange3(value[k], ATT_TYPE(i,j), NCT_ITYPE($1));
+ }
+ err = ncmpi_put_att_$1(ncid, i, ATT_NAME(i,j), ATT_TYPE(i,j),
+ ATT_LEN(i,j), value);
+ if (allInExtRange) {
+ IF (err != NC_NOERR)
+ error("%s", ncmpi_strerror(err));
+ ELSE_NOK
+ } else {
+ IF (err != NC_ERANGE)
+ error("expecting range error, but err = %d", err);
+ ELSE_NOK
+ }
+ }
+ }
+ }
+
+ nok += check_atts_$1(ncid);
+ err = ncmpi_close(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_close: %s", ncmpi_strerror(err));
+
+ err = ncmpi_delete(scratch, info);
+ IF (err != NC_NOERR)
+ error("remove of %s failed", scratch);
+ return nok;
+}
+')dnl
+
+TEST_NC_PUT_ATT(uchar)
+TEST_NC_PUT_ATT(schar)
+TEST_NC_PUT_ATT(short)
+TEST_NC_PUT_ATT(int)
+TEST_NC_PUT_ATT(long)
+TEST_NC_PUT_ATT(float)
+TEST_NC_PUT_ATT(double)
+TEST_NC_PUT_ATT(ushort)
+TEST_NC_PUT_ATT(uint)
+TEST_NC_PUT_ATT(longlong)
+TEST_NC_PUT_ATT(ulonglong)
+
diff --git a/test/nc_test/test_read.c b/test/nc_test/test_read.c
new file mode 100644
index 0000000..18c9169
--- /dev/null
+++ b/test/nc_test/test_read.c
@@ -0,0 +1,1792 @@
+/*
+ * Copyright (C) 2003, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ *
+ * $Id: test_read.c 2297 2016-01-06 22:22:33Z wkliao $
+ */
+
+#include <sys/types.h> /* open() */
+#include <sys/stat.h> /* open() */
+#include <fcntl.h> /* open() */
+#include <unistd.h> /* unlink(), write() */
+#include "tests.h"
+
+/*
+ * Test ncmpi_strerror.
+ * Try on a bad error status.
+ * Test for each defined error status.
+ */
+int
+test_ncmpi_strerror(void)
+{
+ int i;
+ const char *message, *expected_msg;
+ int nok=0;
+
+ static const struct {
+ int status;
+ const char *msg;
+ } ncerrs[] = {
+ {NC_NOERR, "No error"},
+ {NC_EBADID, "NetCDF: Not a valid ID"},
+ {NC_ENFILE, "NetCDF: Too many files open"},
+ {NC_EEXIST, "NetCDF: File exists && NC_NOCLOBBER"},
+ {NC_EINVAL, "NetCDF: Invalid argument"},
+ {NC_EPERM, "NetCDF: Write to read only"},
+ {NC_ENOTINDEFINE, "NetCDF: Operation not allowed in data mode"},
+ {NC_EINDEFINE, "NetCDF: Operation not allowed in define mode"},
+ {NC_EINVALCOORDS, "NetCDF: Index exceeds dimension bound"},
+ {NC_EMAXDIMS, "NetCDF: NC_MAX_DIMS exceeded"},
+ {NC_ENAMEINUSE, "NetCDF: String match to name in use"},
+ {NC_ENOTATT, "NetCDF: Attribute not found"},
+ {NC_EMAXATTS, "NetCDF: NC_MAX_ATTRS exceeded"},
+ {NC_EBADTYPE, "NetCDF: Not a valid data type or _FillValue type mismatch"},
+ {NC_EBADDIM, "NetCDF: Invalid dimension ID or name"},
+ {NC_EUNLIMPOS, "NetCDF: NC_UNLIMITED in the wrong index"},
+ {NC_EMAXVARS, "NetCDF: NC_MAX_VARS exceeded"},
+ {NC_ENOTVAR, "NetCDF: Variable not found"},
+ {NC_EGLOBAL, "NetCDF: Action prohibited on NC_GLOBAL varid"},
+ {NC_ENOTNC, "NetCDF: Unknown file format"},
+ {NC_ESTS, "NetCDF: In Fortran, string too short"},
+ {NC_EMAXNAME, "NetCDF: NC_MAX_NAME exceeded"},
+ {NC_EUNLIMIT, "NetCDF: NC_UNLIMITED size already in use"},
+ {NC_ENORECVARS, "NetCDF: nc_rec op when there are no record vars"},
+ {NC_ECHAR, "NetCDF: Attempt to convert between text & numbers"},
+ {NC_EEDGE, "NetCDF: Start+count exceeds dimension bound"},
+ {NC_ESTRIDE, "NetCDF: Illegal stride"},
+ {NC_EBADNAME, "NetCDF: Name contains illegal characters"},
+ {NC_ERANGE, "NetCDF: Numeric conversion not representable"},
+ {NC_ENOMEM, "NetCDF: Memory allocation (malloc) failure"},
+ {NC_EVARSIZE, "NetCDF: One or more variable sizes violate format constraints"},
+ {NC_EDIMSIZE, "NetCDF: Invalid dimension size"}
+ };
+
+ /* Try on a bad error status */
+ message = ncmpi_strerror(-666);/* should fail */
+ expected_msg = "Unknown Error";
+ IF (strncmp(message, expected_msg, strlen(expected_msg)) != 0)
+ error("ncmpi_strerror on bad error status returned: %s", message);
+ ELSE_NOK
+
+ /* Try on each legitimate error status */
+ for (i=0; i<LEN_OF(ncerrs); i++) {
+ const char *message = ncmpi_strerror(ncerrs[i].status);
+ IF (strcmp(message, ncerrs[i].msg) != 0)
+ error("ncmpi_strerror(%d) should return `%s', not `%s'",
+ ncerrs[i].status, ncerrs[i].msg, message);
+ ELSE_NOK
+ }
+ return nok;
+}
+
+
+/*
+ * Test ncmpi_open.
+ * If in read-only section of tests,
+ * Try to open a non-existent netCDF file, check error return.
+ * Open a file that is not a netCDF file, check error return.
+ * Open a netCDF file with a bad mode argument, check error return.
+ * Open a netCDF file with NC_NOWRITE, info mode, try to write, check error.
+ * Try to open a netcdf twice, check whether returned netcdf ids different.
+ * If in writable section of tests,
+ * Open a netCDF file with NC_WRITE mode, write something, close it.
+ * On exit, any open netCDF files are closed.
+ */
+#define NOT_NC_FILE "dummy_not_nc_file"
+int
+test_ncmpi_open(void)
+{
+ int err, fd;
+ int ncid;
+ int ncid2;
+ int nok=0;
+ ssize_t w_len;
+
+ /* Try to open a nonexistent file */
+ err = ncmpi_open(comm, "tooth-fairy.nc", NC_NOWRITE, info, &ncid);/* should fail */
+
+ /* on some systems, opening an nonexisting file will actually create the
+ * file. In this case, we print the error messages on screen and move on
+ * to the next test, instead of aborting the entire test.
+ */
+ if (err == NC_NOERR)
+ fprintf(stderr, "opening a nonexistent file expects to fail, but got NC_NOERR\n");
+ else if (err != NC_ENOENT)
+ fprintf(stderr, "opening a nonexistent file expects NC_ENOENT, but got %s\n",nc_err_code_name(err));
+ else {
+ /* printf("Expected error message complaining: \"File tooth-fairy.nc does not exist\"\n"); */
+ nok++;
+ }
+
+ /* create a not-nc file */
+ fd = open(NOT_NC_FILE, O_CREAT|O_WRONLY, 0600);
+ w_len = write(fd, "0123456789abcdefghijklmnopqrstuvwxyz", 36);
+ assert(w_len >= 0);
+ close(fd);
+
+ /* Open a file that is not a netCDF file. */
+ err = ncmpi_open(comm, NOT_NC_FILE, NC_NOWRITE, info, &ncid);/* should fail */
+ IF (err != NC_ENOTNC)
+ error("ncmpi_open of non-netCDF file: expecting NC_ENOTNC but got %s", nc_err_code_name(err));
+ ELSE_NOK
+
+ /* delete the not-nc file */
+ unlink(NOT_NC_FILE);
+
+ /* Open a netCDF file in read-only mode, check that write fails */
+ err = ncmpi_open(comm, testfile, NC_NOWRITE, info, &ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_open: %s", ncmpi_strerror(err));
+ ELSE_NOK
+ err = ncmpi_redef(ncid); /* should fail */
+ IF (err != NC_EPERM)
+ error("ncmpi_redef of read-only file should fail");
+ /* Opened OK, see if can open again and get a different netCDF ID */
+ err = ncmpi_open(comm, testfile, NC_NOWRITE, info, &ncid2);
+ IF (err != NC_NOERR)
+ error("ncmpi_open: %s", ncmpi_strerror(err));
+ else {
+ ncmpi_close(ncid2);
+ nok++;
+ }
+ IF (ncid2 == ncid)
+ error("netCDF IDs for first and second ncmpi_open calls should differ");
+
+ if (! read_only) { /* tests using netCDF scratch file */
+ err = ncmpi_create(comm, scratch, NC_NOCLOBBER|extra_flags, info, &ncid2);
+ IF (err != NC_NOERR)
+ error("ncmpi_create: %s", ncmpi_strerror(err));
+ else
+ ncmpi_close(ncid2);
+ err = ncmpi_open(comm, scratch, NC_WRITE, info, &ncid2);
+ IF (err != NC_NOERR)
+ error("ncmpi_open: %s", ncmpi_strerror(err));
+ else {
+ ncmpi_close(ncid2);
+ nok++;
+ }
+ err = ncmpi_delete(scratch, info);
+ IF (err != NC_NOERR)
+ error("remove of %s failed", scratch);
+ }
+
+ err = ncmpi_close(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_close: %s", ncmpi_strerror(err));
+ return nok;
+}
+
+
+/*
+ * Test ncmpi_close.
+ * Try to close a netCDF file twice, check whether second close fails.
+ * Try on bad handle, check error return.
+ * Try in define mode and data mode.
+ */
+int
+test_ncmpi_close(void)
+{
+ int ncid, nok=0;
+ int err = ncmpi_open(comm, testfile, NC_NOWRITE, info, &ncid);
+
+ IF (err != NC_NOERR)
+ error("ncmpi_open: %s", ncmpi_strerror(err));
+
+ /* Close a netCDF file twice, second time should fail */
+ err = ncmpi_close(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_close failed: %s", ncmpi_strerror(err));
+ ELSE_NOK
+ err = ncmpi_close(ncid);
+ IF (err != NC_EBADID)
+ error("ncmpi_close of closed file should have failed");
+ ELSE_NOK
+
+ /* Try with a bad netCDF ID */
+ err = ncmpi_close(BAD_ID);/* should fail */
+ IF (err != NC_EBADID)
+ error("ncmpi_close with bad netCDF ID returned wrong error (%d)", err);
+ ELSE_NOK
+
+ /* Close in data mode */
+ err = ncmpi_open(comm, testfile, NC_NOWRITE, info, &ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_open: %s", ncmpi_strerror(err));
+ err = ncmpi_close(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_close in data mode failed: %s", ncmpi_strerror(err));
+ ELSE_NOK
+
+ if (! read_only) { /* tests using netCDF scratch file */
+ err = ncmpi_create(comm, scratch, NC_NOCLOBBER|extra_flags, info, &ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_create: %s", ncmpi_strerror(err));
+ err = ncmpi_close(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_close in define mode: %s", ncmpi_strerror(err));
+ ELSE_NOK
+ err = ncmpi_delete(scratch, info);
+ IF (err != NC_NOERR)
+ error("remove of %s failed", scratch);
+ }
+ return nok;
+}
+
+
+/*
+ * Test ncmpi_inq.
+ * Try on bad handle, check error return.
+ * Try in data mode, check returned values.
+ * Try asking for subsets of info.
+ * If in writable section of tests,
+ * Try in define mode, after adding an unlimited dimension, variable.
+ * On exit, any open netCDF files are closed.
+ */
+int
+test_ncmpi_inq(void)
+{
+ int ncid;
+ int ndims; /* number of dimensions */
+ int nvars; /* number of variables */
+ int ngatts; /* number of global attributes */
+ int recdim; /* id of unlimited dimension */
+ int err = ncmpi_open(comm, testfile, NC_NOWRITE, info, &ncid);
+ int nok=0;
+
+ IF (err != NC_NOERR)
+ error("ncmpi_open: %s", ncmpi_strerror(err));
+
+ /* Try on bad handle */
+ err = ncmpi_inq(BAD_ID, 0, 0, 0, 0);
+ IF (err != NC_EBADID)
+ error("bad ncid: status = %d", err);
+ ELSE_NOK
+
+ err = ncmpi_inq(ncid, &ndims, &nvars, &ngatts, &recdim);
+ IF (err != NC_NOERR)
+ error("ncmpi_inq: %s", ncmpi_strerror(err));
+ else IF (ndims != NDIMS)
+ error("ncmpi_inq: wrong number of dimensions returned, %d", ndims);
+ else IF (nvars != numVars)
+ error("ncmpi_inq: wrong number of variables returned, %d", nvars);
+ else IF (ngatts != numGatts)
+ error("ncmpi_inq: wrong number of global atts returned, %d", ngatts);
+ else IF (recdim != RECDIM)
+ error("ncmpi_inq: wrong record dimension ID returned, %d", recdim);
+ ELSE_NOK
+
+ /* Inguire for no info (useless, but should still work) */
+ err = ncmpi_inq(ncid, 0, 0, 0, 0);
+ IF (err != NC_NOERR)
+ error("ncmpi_inq for no info failed: %s", ncmpi_strerror(err));
+ ELSE_NOK
+
+ /* Inguire for subsets of info */
+ ngatts = numGatts - 1; /* wipe out previous correct value */
+ err = ncmpi_inq(ncid, 0, 0, &ngatts, 0);
+ IF (err != NC_NOERR)
+ error("ncmpi_inq for one item failed: %s", ncmpi_strerror(err));
+ else IF (ngatts != numGatts)
+ error("ncmpi_inq subset: wrong number of global atts returned, %d", ngatts);
+ ELSE_NOK
+ ndims = NDIMS - 1;
+ nvars = numVars - 1;
+ err = ncmpi_inq(ncid, &ndims, &nvars, 0, 0);
+ IF (err != NC_NOERR)
+ error("ncmpi_inq for two items failed: %s", ncmpi_strerror(err));
+ else IF (ndims != NDIMS)
+ error("ncmpi_inq subset: wrong number of dimensions returned, %d", ndims);
+ else IF (nvars != numVars)
+ error("ncmpi_inq subset: wrong number of variables returned, %d", nvars);
+ ELSE_NOK
+
+ if (! read_only) { /* tests using netCDF scratch file */
+ int ncid2; /* for scratch netCDF dataset */
+
+ err = ncmpi_create(comm, scratch, NC_NOCLOBBER|extra_flags, info, &ncid2);
+ IF (err != NC_NOERR) {
+ error("ncmpi_create: %s", ncmpi_strerror(err));
+ } else { /* add dim, var, gatt, check inq */
+ int ndims0;
+ int nvars0;
+ int ngatts0;
+ int recdim0;
+ err = ncmpi_enddef(ncid2); /* enter data mode */
+ err = ncmpi_inq(ncid2, &ndims0, &nvars0, &ngatts0, &recdim0);
+ IF (err != NC_NOERR)
+ error("ncmpi_inq: %s", ncmpi_strerror(err));
+ ELSE_NOK
+ err = ncmpi_redef(ncid2); /* enter define mode */
+ /* Check that inquire still works in define mode */
+ err = ncmpi_inq(ncid2, &ndims, &nvars, &ngatts, &recdim);
+ IF (err != NC_NOERR)
+ error("ncmpi_inq in define mode: %s", ncmpi_strerror(err));
+ else IF (ndims != ndims0)
+ error("ncmpi_inq in define mode: ndims wrong, %d", ndims);
+ else IF (nvars != nvars0)
+ error("ncmpi_inq in define mode: nvars wrong, %d", nvars);
+ else IF (ngatts != ngatts0)
+ error("ncmpi_inq in define mode: ngatts wrong, %d", ngatts);
+ else IF (recdim != recdim0)
+ error("ncmpi_inq in define mode: recdim wrong, %d", recdim);
+ ELSE_NOK
+
+ {
+ int did, vid;
+ /* Add dim, var, global att */
+ err = ncmpi_def_dim(ncid2, "inqd", 1L, &did);
+ IF (err != NC_NOERR)
+ error("ncmpi_def_dim: %s", ncmpi_strerror(err));
+ err = ncmpi_def_var(ncid2, "inqv", NC_FLOAT, 0, 0, &vid);
+ IF (err != NC_NOERR)
+ error("ncmpi_def_var: %s", ncmpi_strerror(err));
+ }
+ err = ncmpi_put_att_text(ncid2, NC_GLOBAL, "inqa", 1+strlen("stuff"),
+ "stuff");
+ IF (err != NC_NOERR)
+ error("ncmpi_put_att_text: %s", ncmpi_strerror(err));
+
+ /* Make sure ncmpi_inq sees the additions while in define mode */
+ err = ncmpi_inq(ncid2, &ndims, &nvars, &ngatts, &recdim);
+ IF (err != NC_NOERR)
+ error("ncmpi_inq in define mode: %s", ncmpi_strerror(err));
+ else IF (ndims != ndims0 + 1)
+ error("ncmpi_inq in define mode: ndims wrong, %d", ndims);
+ else IF (nvars != nvars0 + 1)
+ error("ncmpi_inq in define mode: nvars wrong, %d", nvars);
+ else IF (ngatts != ngatts0 + 1)
+ error("ncmpi_inq in define mode: ngatts wrong, %d", ngatts);
+ ELSE_NOK
+ err = ncmpi_enddef(ncid2);
+ IF (err != NC_NOERR)
+ error("ncmpi_enddef: %s", ncmpi_strerror(err));
+
+ /* Make sure ncmpi_inq stills sees additions in data mode */
+ err = ncmpi_inq(ncid2, &ndims, &nvars, &ngatts, &recdim);
+ IF (err != NC_NOERR)
+ error("ncmpi_inq failed in data mode: %s", ncmpi_strerror(err));
+ else IF (ndims != ndims0 + 1)
+ error("ncmpi_inq in define mode: ndims wrong, %d", ndims);
+ else IF (nvars != nvars0 + 1)
+ error("ncmpi_inq in define mode: nvars wrong, %d", nvars);
+ else IF (ngatts != ngatts0 + 1)
+ error("ncmpi_inq in define mode: ngatts wrong, %d", ngatts);
+ ELSE_NOK
+ ncmpi_close(ncid2);
+ err = ncmpi_delete(scratch, info);
+ IF (err != NC_NOERR)
+ error("remove of %s failed", scratch);
+ }
+ }
+
+ err = ncmpi_close(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_close: %s", ncmpi_strerror(err));
+ return nok;
+}
+
+
+int
+test_ncmpi_inq_natts(void)
+{
+ int ncid;
+ int ngatts; /* number of global attributes */
+ int err, nok=0;
+
+ err = ncmpi_inq_natts(BAD_ID, &ngatts);
+ IF (err != NC_EBADID)
+ error("bad ncid: status = %d", err);
+ ELSE_NOK
+ err = ncmpi_open(comm, testfile, NC_NOWRITE, info, &ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_open: %s", ncmpi_strerror(err));
+ err = ncmpi_inq_natts(ncid, &ngatts);
+ IF (err != NC_NOERR)
+ error("ncmpi_inq_natts: %s", ncmpi_strerror(err));
+ else IF (ngatts != numGatts)
+ error("ncmpi_inq_natts: wrong number of global atts returned, %d", ngatts);
+ ELSE_NOK
+ err = ncmpi_close(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_close: %s", ncmpi_strerror(err));
+ return nok;
+}
+
+
+int
+test_ncmpi_inq_ndims(void)
+{
+ int ncid;
+ int ndims;
+ int err;
+ int nok=0;
+
+ err = ncmpi_inq_ndims(BAD_ID, &ndims);
+ IF (err != NC_EBADID)
+ error("bad ncid: status = %d", err);
+ ELSE_NOK
+ err = ncmpi_open(comm, testfile, NC_NOWRITE, info, &ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_open: %s", ncmpi_strerror(err));
+ err = ncmpi_inq_ndims(ncid, &ndims);
+ IF (err != NC_NOERR)
+ error("ncmpi_inq_ndims: %s", ncmpi_strerror(err));
+ else IF (ndims != NDIMS)
+ error("ncmpi_inq_ndims: wrong number returned, %d", ndims);
+ ELSE_NOK
+ err = ncmpi_close(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_close: %s", ncmpi_strerror(err));
+ return nok;
+}
+
+
+int
+test_ncmpi_inq_nvars(void)
+{
+ int ncid;
+ int nvars;
+ int err;
+ int nok=0;
+
+ err = ncmpi_inq_nvars(BAD_ID, &nvars);
+ IF (err != NC_EBADID)
+ error("bad ncid: status = %d", err);
+ ELSE_NOK
+ err = ncmpi_open(comm, testfile, NC_NOWRITE, info, &ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_open: %s", ncmpi_strerror(err));
+ err = ncmpi_inq_nvars(ncid, &nvars);
+ IF (err != NC_NOERR)
+ error("ncmpi_inq_nvars: %s", ncmpi_strerror(err));
+ else IF (nvars != numVars)
+ error("ncmpi_inq_nvars: wrong number returned, %d", nvars);
+ ELSE_NOK
+ err = ncmpi_close(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_close: %s", ncmpi_strerror(err));
+ return nok;
+}
+
+
+int
+test_ncmpi_inq_unlimdim(void)
+{
+ int ncid;
+ int unlimdim;
+ int err;
+ int nok=0;
+
+ err = ncmpi_inq_unlimdim(BAD_ID, &unlimdim);
+ IF (err != NC_EBADID)
+ error("bad ncid: status = %d", err);
+ ELSE_NOK
+ err = ncmpi_open(comm, testfile, NC_NOWRITE, info, &ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_open: %s", ncmpi_strerror(err));
+ err = ncmpi_inq_unlimdim(ncid, &unlimdim);
+ IF (err != NC_NOERR)
+ error("ncmpi_inq_unlimdim: %s", ncmpi_strerror(err));
+ else IF (unlimdim != RECDIM)
+ error("ncmpi_inq_unlimdim: wrong number returned, %d", unlimdim);
+ ELSE_NOK
+ err = ncmpi_close(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_close: %s", ncmpi_strerror(err));
+ return nok;
+}
+
+
+int
+test_ncmpi_inq_dimid(void)
+{
+ int ncid;
+ int dimid;
+ int i;
+ int err;
+ int nok=0;
+
+ err = ncmpi_open(comm, testfile, NC_NOWRITE, info, &ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_open: %s", ncmpi_strerror(err));
+ err = ncmpi_inq_dimid(ncid, "noSuch", &dimid);
+ IF (err != NC_EBADDIM)
+ error("bad dim name: status = %d", err);
+ ELSE_NOK
+ for (i = 0; i < NDIMS; i++) {
+ err = ncmpi_inq_dimid(BAD_ID, dim_name[i], &dimid);
+ IF (err != NC_EBADID)
+ error("bad ncid: status = %d", err);
+ ELSE_NOK
+ err = ncmpi_inq_dimid(ncid, dim_name[i], &dimid);
+ IF (err != NC_NOERR)
+ error("ncmpi_inq_dimid: %s", ncmpi_strerror(err));
+ else IF (dimid != i)
+ error("expected %d, got %d", i, dimid);
+ ELSE_NOK
+ }
+ err = ncmpi_close(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_close: %s", ncmpi_strerror(err));
+ return nok;
+}
+
+
+int
+test_ncmpi_inq_dim(void)
+{
+ int ncid;
+ int i;
+ int err;
+ char name[NC_MAX_NAME];
+ MPI_Offset length;
+ int nok=0;
+
+ err = ncmpi_open(comm, testfile, NC_NOWRITE, info, &ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_open: %s", ncmpi_strerror(err));
+ for (i = 0; i < NDIMS; i++) {
+ err = ncmpi_inq_dim(BAD_ID, i, name, &length);
+ IF (err != NC_EBADID)
+ error("bad ncid: status = %d", err);
+ ELSE_NOK
+ err = ncmpi_inq_dim(ncid, BAD_DIMID, name, &length);
+ IF (err != NC_EBADDIM)
+ error("bad dimid: status = %d", err);
+ ELSE_NOK
+ err = ncmpi_inq_dim(ncid, i, 0, 0);
+ IF (err != NC_NOERR)
+ error("ncmpi_inq_dim: %s", ncmpi_strerror(err));
+ ELSE_NOK
+ err = ncmpi_inq_dim(ncid, i, name, &length);
+ IF (err != NC_NOERR)
+ error("ncmpi_inq_dim: %s", ncmpi_strerror(err));
+ else IF (strcmp(dim_name[i],name))
+ error("name expected: %s, got: %s",dim_name[i],name);
+ else IF (dim_len[i] != length)
+ error("size expected: %d, got: %d",dim_len[i],length);
+ ELSE_NOK
+ err = ncmpi_inq_dim(ncid, i, name, 0);
+ IF (err != NC_NOERR)
+ error("ncmpi_inq_dim: %s", ncmpi_strerror(err));
+ else IF (strcmp(dim_name[i],name))
+ error("name expected: %s, got: %s",dim_name[i],name);
+ ELSE_NOK
+ err = ncmpi_inq_dim(ncid, i, 0, &length);
+ IF (err != NC_NOERR)
+ error("ncmpi_inq_dim: %s", ncmpi_strerror(err));
+ else IF (dim_len[i] != length)
+ error("size expected: %d, got: %d",dim_len[i],length);
+ ELSE_NOK
+ }
+ err = ncmpi_close(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_close: %s", ncmpi_strerror(err));
+ return nok;
+}
+
+
+int
+test_ncmpi_inq_dimlen(void)
+{
+ int ncid;
+ int i;
+ int err;
+ MPI_Offset length;
+ int nok=0;
+
+ err = ncmpi_open(comm, testfile, NC_NOWRITE, info, &ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_open: %s", ncmpi_strerror(err));
+ for (i = 0; i < NDIMS; i++) {
+ err = ncmpi_inq_dimlen(BAD_ID, i, &length);
+ IF (err != NC_EBADID)
+ error("bad ncid: status = %d", err);
+ ELSE_NOK
+ err = ncmpi_inq_dimlen(ncid, BAD_DIMID, &length);
+ IF (err != NC_EBADDIM)
+ error("bad dimid: status = %d", err);
+ ELSE_NOK
+ err = ncmpi_inq_dimlen(ncid, i, &length);
+ IF (err != NC_NOERR)
+ error("ncmpi_inq_dimlen: %s", ncmpi_strerror(err));
+ else IF (dim_len[i] != length)
+ error("size expected: %d, got: %d",dim_len[i],length);
+ ELSE_NOK
+ }
+ err = ncmpi_close(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_close: %s", ncmpi_strerror(err));
+ return nok;
+}
+
+
+int
+test_ncmpi_inq_dimname(void)
+{
+ int ncid;
+ int i;
+ int err;
+ char name[NC_MAX_NAME];
+ int nok=0;
+
+ err = ncmpi_open(comm, testfile, NC_NOWRITE, info, &ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_open: %s", ncmpi_strerror(err));
+ for (i = 0; i < NDIMS; i++) {
+ err = ncmpi_inq_dimname(BAD_ID, i, name);
+ IF (err != NC_EBADID)
+ error("bad ncid: status = %d", err);
+ ELSE_NOK
+ err = ncmpi_inq_dimname(ncid, BAD_DIMID, name);
+ IF (err != NC_EBADDIM)
+ error("bad dimid: status = %d", err);
+ ELSE_NOK
+ err = ncmpi_inq_dimname(ncid, i, name);
+ IF (err != NC_NOERR)
+ error("ncmpi_inq_dimname: %s", ncmpi_strerror(err));
+ else IF (strcmp(dim_name[i],name))
+ error("name expected: %s, got: %s",dim_name[i],name);
+ ELSE_NOK
+ }
+ err = ncmpi_close(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_close: %s", ncmpi_strerror(err));
+ return nok;
+}
+
+
+int
+test_ncmpi_inq_varid(void)
+{
+ int ncid;
+ int varid;
+ int i;
+ int err;
+ int nok=0;
+
+ err = ncmpi_open(comm, testfile, NC_NOWRITE, info, &ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_open: %s", ncmpi_strerror(err));
+
+ err = ncmpi_inq_varid(ncid, "noSuch", &varid);
+ IF (err != NC_ENOTVAR)
+ error("bad ncid: status = %d", err);
+ ELSE_NOK
+
+ for (i = 0; i < numVars; i++) {
+ err = ncmpi_inq_varid(BAD_ID, var_name[i], &varid);
+ IF (err != NC_EBADID)
+ error("bad ncid: status = %d", err);
+ ELSE_NOK
+ err = ncmpi_inq_varid(ncid, var_name[i], &varid);
+ IF (err != NC_NOERR)
+ error("ncmpi_inq_varid: %s", ncmpi_strerror(err));
+ else IF (varid != i)
+ error("expected %d, got %d", i, varid);
+ ELSE_NOK
+ }
+
+ err = ncmpi_close(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_close: %s", ncmpi_strerror(err));
+ return nok;
+}
+
+
+int
+test_ncmpi_inq_var(void)
+{
+ int ncid;
+ int i;
+ int err;
+ char name[NC_MAX_NAME];
+ nc_type datatype;
+ int ndims;
+ int dimids[MAX_RANK];
+ int natts;
+ int nok=0;
+
+ err = ncmpi_open(comm, testfile, NC_NOWRITE, info, &ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_open: %s", ncmpi_strerror(err));
+ for (i = 0; i < numVars; i++) {
+ err = ncmpi_inq_var(BAD_ID, i, name, &datatype, &ndims, dimids, &natts);
+ IF (err != NC_EBADID)
+ error("bad ncid: status = %d", err);
+ ELSE_NOK
+ err = ncmpi_inq_var(ncid,BAD_VARID,name,&datatype,&ndims,dimids,&natts);
+ IF (err != NC_ENOTVAR)
+ error("bad var id: status = %d", err);
+ ELSE_NOK
+ err = ncmpi_inq_var(ncid, i, 0, 0, 0, 0, 0);
+ IF (err != NC_NOERR)
+ error("ncmpi_inq_var: %s", ncmpi_strerror(err));
+ ELSE_NOK
+ err = ncmpi_inq_var(ncid, i, name, &datatype, &ndims, dimids, &natts);
+ IF (err != NC_NOERR)
+ error("ncmpi_inq_var: %s", ncmpi_strerror(err));
+ else IF (strcmp(var_name[i],name))
+ error("name expected: %s, got: %s",var_name[i],name);
+ else IF (var_type[i] != datatype)
+ error("type expected: %d, got: %d",var_type[i],datatype);
+ else IF (var_rank[i] != ndims)
+ error("ndims expected: %d, got: %d",var_rank[i],ndims);
+ else IF (!int_vec_eq(var_dimid[i],dimids,ndims))
+ error("unexpected dimid");
+ else IF (var_natts[i] != natts)
+ error("natts expected: %d, got: %d",var_natts[i],natts);
+ ELSE_NOK
+ err = ncmpi_inq_var(ncid, i, name, 0, 0, 0, 0);
+ IF (err != NC_NOERR)
+ error("ncmpi_inq_var: %s", ncmpi_strerror(err));
+ else IF (strcmp(var_name[i],name))
+ error("name expected: %s, got: %s",var_name[i],name);
+ ELSE_NOK
+ err = ncmpi_inq_var(ncid, i, 0, &datatype, 0, 0, 0);
+ IF (err != NC_NOERR)
+ error("ncmpi_inq_var: %s", ncmpi_strerror(err));
+ else IF (var_type[i] != datatype)
+ error("type expected: %d, got: %d",var_type[i],datatype);
+ ELSE_NOK
+ err = ncmpi_inq_var(ncid, i, 0, 0, &ndims, 0, 0);
+ IF (err != NC_NOERR)
+ error("ncmpi_inq_var: %s", ncmpi_strerror(err));
+ else IF (var_rank[i] != ndims)
+ error("ndims expected: %d, got: %d",var_rank[i],ndims);
+ ELSE_NOK
+ err = ncmpi_inq_var(ncid, i, 0, 0, 0, dimids, 0);
+ IF (err != NC_NOERR)
+ error("ncmpi_inq_var: %s", ncmpi_strerror(err));
+ else IF (!int_vec_eq(var_dimid[i],dimids,ndims))
+ error("unexpected dimid");
+ ELSE_NOK
+ err = ncmpi_inq_var(ncid, i, 0, 0, 0, 0, &natts);
+ IF (err != NC_NOERR)
+ error("ncmpi_inq_var: %s", ncmpi_strerror(err));
+ else IF (var_natts[i] != natts)
+ error("natts expected: %d, got: %d",var_natts[i],natts);
+ ELSE_NOK
+ }
+ err = ncmpi_close(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_close: %s", ncmpi_strerror(err));
+ return nok;
+}
+
+
+int
+test_ncmpi_inq_vardimid(void)
+{
+ int ncid;
+ int i;
+ int err;
+ int dimids[MAX_RANK];
+ int nok=0;
+
+ err = ncmpi_open(comm, testfile, NC_NOWRITE, info, &ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_open: %s", ncmpi_strerror(err));
+ for (i = 0; i < numVars; i++) {
+ err = ncmpi_inq_vardimid(BAD_ID, i, dimids);
+ IF (err != NC_EBADID)
+ error("bad ncid: status = %d", err);
+ ELSE_NOK
+ err = ncmpi_inq_vardimid(ncid, BAD_VARID, dimids);
+ IF (err != NC_ENOTVAR)
+ error("bad var id: status = %d", err);
+ ELSE_NOK
+ err = ncmpi_inq_vardimid(ncid, i, dimids);
+ IF (err != NC_NOERR)
+ error("ncmpi_inq_vardimid: %s", ncmpi_strerror(err));
+ else IF (!int_vec_eq(var_dimid[i], dimids, var_rank[i]))
+ error("unexpected dimid");
+ ELSE_NOK
+ }
+ err = ncmpi_close(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_close: %s", ncmpi_strerror(err));
+ return nok;
+}
+
+
+int
+test_ncmpi_inq_varname(void)
+{
+ int ncid;
+ int i;
+ int err;
+ char name[NC_MAX_NAME];
+ int nok=0;
+
+ err = ncmpi_open(comm, testfile, NC_NOWRITE, info, &ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_open: %s", ncmpi_strerror(err));
+ for (i = 0; i < numVars; i++) {
+ err = ncmpi_inq_varname(BAD_ID, i, name);
+ IF (err != NC_EBADID)
+ error("bad ncid: status = %d", err);
+ nok++;
+ err = ncmpi_inq_varname(ncid, BAD_VARID, name);
+ IF (err != NC_ENOTVAR)
+ error("bad var id: status = %d", err);
+ ELSE_NOK
+ err = ncmpi_inq_varname(ncid, i, name);
+ IF (err != NC_NOERR)
+ error("ncmpi_inq_varname: %s", ncmpi_strerror(err));
+ else IF (strcmp(var_name[i],name))
+ error("name expected: %s, got: %s",var_name[i],name);
+ ELSE_NOK
+ }
+ err = ncmpi_close(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_close: %s", ncmpi_strerror(err));
+ return nok;
+}
+
+
+int
+test_ncmpi_inq_varnatts(void)
+{
+ int ncid;
+ int i;
+ int err;
+ int natts;
+ int nok=0;
+
+ err = ncmpi_open(comm, testfile, NC_NOWRITE, info, &ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_open: %s", ncmpi_strerror(err));
+ for (i = -1; i < numVars; i++) {
+ err = ncmpi_inq_varnatts(BAD_ID, i, &natts);
+ IF (err != NC_EBADID)
+ error("bad ncid: status = %d", err);
+ ELSE_NOK
+ err = ncmpi_inq_varnatts(ncid, BAD_VARID, &natts);
+ IF (err != NC_ENOTVAR)
+ error("bad var id: status = %d", err);
+ ELSE_NOK
+ err = ncmpi_inq_varnatts(ncid, VARID(i), &natts);
+ IF (err != NC_NOERR)
+ error("ncmpi_inq_varnatts: %s", ncmpi_strerror(err));
+ else IF (NATTS(i) != natts)
+ error("natts expected: %d, got: %d",NATTS(i),natts);
+ ELSE_NOK
+ }
+ err = ncmpi_close(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_close: %s", ncmpi_strerror(err));
+ return nok;
+}
+
+
+int
+test_ncmpi_inq_varndims(void)
+{
+ int ncid;
+ int i;
+ int err;
+ int ndims;
+ int nok=0;
+
+ err = ncmpi_open(comm, testfile, NC_NOWRITE, info, &ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_open: %s", ncmpi_strerror(err));
+ for (i = 0; i < numVars; i++) {
+ err = ncmpi_inq_varndims(BAD_ID, i, &ndims);
+ IF (err != NC_EBADID)
+ error("bad ncid: status = %d", err);
+ ELSE_NOK
+ err = ncmpi_inq_varndims(ncid, BAD_VARID, &ndims);
+ IF (err != NC_ENOTVAR)
+ error("bad var id: status = %d", err);
+ ELSE_NOK
+ err = ncmpi_inq_varndims(ncid, i, &ndims);
+ IF (err != NC_NOERR)
+ error("ncmpi_inq_varndims: %s", ncmpi_strerror(err));
+ else IF (var_rank[i] != ndims)
+ error("ndims expected: %d, got: %d",var_rank[i],ndims);
+ ELSE_NOK
+ }
+ err = ncmpi_close(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_close: %s", ncmpi_strerror(err));
+ return nok;
+}
+
+
+int
+test_ncmpi_inq_vartype(void)
+{
+ int ncid;
+ int i;
+ int err;
+ nc_type datatype;
+ int nok=0;
+
+ err = ncmpi_open(comm, testfile, NC_NOWRITE, info, &ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_open: %s", ncmpi_strerror(err));
+ for (i = 0; i < numVars; i++) {
+ err = ncmpi_inq_vartype(BAD_ID, i, &datatype);
+ IF (err != NC_EBADID)
+ error("bad ncid: status = %d", err);
+ ELSE_NOK
+ err = ncmpi_inq_vartype(ncid, BAD_VARID, &datatype);
+ IF (err != NC_ENOTVAR)
+ error("bad var id: status = %d", err);
+ ELSE_NOK
+ err = ncmpi_inq_vartype(ncid, i, &datatype);
+ IF (err != NC_NOERR)
+ error("ncmpi_inq_vartype: %s", ncmpi_strerror(err));
+ else IF (var_type[i] != datatype)
+ error("type expected: %d, got: %d", var_type[i], datatype);
+ ELSE_NOK
+ }
+ err = ncmpi_close(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_close: %s", ncmpi_strerror(err));
+ return nok;
+}
+
+
+/*
+ * Test ncmpi_put_var1
+ */
+int
+test_ncmpi_get_var1(void)
+{
+ int ncid;
+ int i;
+ int j;
+ int err;
+ double expect;
+ int nok = 0; /* count of valid comparisons */
+ double buf[1]; /* (void *) buffer */
+ double value;
+ MPI_Offset index[MAX_RANK];
+ MPI_Datatype datatype;
+
+ err = ncmpi_open(comm, testfile, NC_NOWRITE, info, &ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_open: %s", ncmpi_strerror(err));
+ err = ncmpi_begin_indep_data(ncid);
+ for (i = 0; i < numVars; i++) {
+ datatype = nc_mpi_type(var_type[i]);
+ for (j = 0; j < var_rank[i]; j++)
+ index[j] = 0;
+ err = ncmpi_get_var1(BAD_ID, i, index, buf, 1, datatype);
+ IF (err != NC_EBADID)
+ error("bad ncid: status = %d", err);
+ ELSE_NOK
+ err = ncmpi_get_var1(ncid, BAD_VARID, index, buf, 1, datatype);
+ IF (err != NC_ENOTVAR)
+ error("bad var id: status = %d", err);
+ ELSE_NOK
+ for (j = 0; j < var_rank[i]; j++) {
+ index[j] = var_shape[i][j];
+ err = ncmpi_get_var1(ncid, i, index, buf, 1, datatype);
+ IF (err != NC_EINVALCOORDS)
+ error("bad index: status = %d", err);
+ ELSE_NOK
+ index[j] = 0;
+ }
+ for (j = 0; j < var_nels[i]; j++) {
+ err = toMixedBase(j, var_rank[i], var_shape[i], index);
+ IF (err != NC_NOERR)
+ error("error in toMixedBase 2");
+ expect = hash( var_type[i], var_rank[i], index );
+ if (var_rank[i] == 0 && i%2 )
+ err = ncmpi_get_var1(ncid, i, NULL, buf, 1, datatype);
+ else
+ err = ncmpi_get_var1(ncid, i, index, buf, 1, datatype);
+ IF (err != NC_NOERR)
+ error("%s", ncmpi_strerror(err));
+ ELSE_NOK
+ err = nc2dbl( var_type[i], buf, &value );
+ IF (err != NC_NOERR)
+ error("error in nc2dbl");
+ if (inRange(expect,var_type[i])) {
+ IF (!equal2(value,expect,var_type[i]))
+ error("expected: %G, got: %G", expect, value);
+ ELSE_NOK
+ }
+ }
+ }
+ err = ncmpi_close(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_close: %s", ncmpi_strerror(err));
+ return nok;
+}
+
+
+/*
+ * Test ncmpi_get_vara
+ * Choose a random point dividing each dim into 2 parts
+ * Get 2^rank (nslabs) slabs so defined
+ * Each get overwrites buffer, so check after each get.
+ */
+int
+test_ncmpi_get_vara(void)
+{
+ int ncid, d, i, j, k, err, nels, nslabs;
+ int nok = 0; /* count of valid comparisons */
+ MPI_Offset start[MAX_RANK];
+ MPI_Offset edge[MAX_RANK];
+ MPI_Offset index[MAX_RANK];
+ MPI_Offset mid[MAX_RANK];
+ MPI_Datatype datatype;
+ double buf[MAX_NELS]; /* (void *) buffer */
+ double expect;
+
+ err = ncmpi_open(comm, testfile, NC_NOWRITE, info, &ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_open: %s", ncmpi_strerror(err));
+ err = ncmpi_begin_indep_data(ncid);
+ for (i = 0; i < numVars; i++) {
+ datatype = nc_mpi_type(var_type[i]);
+ assert(var_rank[i] <= MAX_RANK);
+ assert(var_nels[i] <= MAX_NELS);
+ for (j = 0; j < var_rank[i]; j++) {
+ start[j] = 0;
+ edge[j] = 1;
+ }
+ err = ncmpi_get_vara(BAD_ID, i, start, edge, buf, 1, datatype);
+ IF (err != NC_EBADID)
+ error("bad ncid: status = %d", err);
+ ELSE_NOK
+ err = ncmpi_get_vara(ncid, BAD_VARID, start, edge, buf, 1, datatype);
+ IF (err != NC_ENOTVAR)
+ error("bad var id: status = %d", err);
+ ELSE_NOK
+ for (j = 0; j < var_rank[i]; j++) {
+ start[j] = var_shape[i][j];
+ err = ncmpi_get_vara(ncid, i, start, edge, buf, 1, datatype);
+ IF (err != NC_EINVALCOORDS)
+ error("bad index: status = %d", err);
+ ELSE_NOK
+ start[j] = 0;
+ edge[j] = var_shape[i][j] + 1;
+ err = ncmpi_get_vara(ncid, i, start, edge, buf, 1, datatype);
+ IF (err != NC_EEDGE)
+ error("bad edge: status = %d", err);
+ ELSE_NOK
+ edge[j] = 1;
+ }
+ /* Choose a random point dividing each dim into 2 parts */
+ /* get 2^rank (nslabs) slabs so defined */
+ nslabs = 1;
+ for (j = 0; j < var_rank[i]; j++) {
+ mid[j] = roll( var_shape[i][j] );
+ nslabs *= 2;
+ }
+ /* bits of k determine whether to get lower or upper part of dim */
+ for (k = 0; k < nslabs; k++) {
+ nels = 1;
+ for (j = 0; j < var_rank[i]; j++) {
+ if ((k >> j) & 1) {
+ start[j] = 0;
+ edge[j] = mid[j];
+ }else{
+ start[j] = mid[j];
+ edge[j] = var_shape[i][j] - mid[j];
+ }
+ nels *= edge[j];
+ }
+ if (var_rank[i] == 0 && i%2 )
+ err = ncmpi_get_vara(ncid, i, NULL, NULL, buf, nels, datatype);
+ else
+ err = ncmpi_get_vara(ncid, i, start, edge, buf, nels, datatype);
+ IF (err != NC_NOERR) {
+ error("%s", ncmpi_strerror(err));
+ } else {
+ nok++;
+ for (j = 0; j < nels; j++) {
+ double got;
+ char *p = (char *) buf;
+ p += j * nctypelen(var_type[i]);
+ err = nc2dbl( var_type[i], p, & got );
+ IF (err != NC_NOERR)
+ error("error in nc2dbl");
+ err = toMixedBase(j, var_rank[i], edge, index);
+ IF (err != NC_NOERR)
+ error("error in toMixedBase 1");
+ for (d = 0; d < var_rank[i]; d++)
+ index[d] += start[d];
+ expect = hash(var_type[i], var_rank[i], index);
+ if (inRange(expect,var_type[i])) {
+ IF (!equal2(got,expect,var_type[i])) {
+ error("value read not that expected");
+ if (verbose) {
+ error("\n");
+ error("varid: %d, ", i);
+ error("var_name: %s, ", var_name[i]);
+ error("element number: %d ", j);
+ error("expect: %g", expect);
+ error("got: %g", got);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ err = ncmpi_close(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_close: %s", ncmpi_strerror(err));
+ return nok;
+}
+
+
+/*
+ * Test ncmpi_get_vars
+ * Choose a random point dividing each dim into 2 parts
+ * Get 2^rank (nslabs) slabs so defined
+ * Each get overwrites buffer, so check after each get.
+ */
+int
+test_ncmpi_get_vars(void)
+{
+ int ncid;
+ int d;
+ int i;
+ int j;
+ int k;
+ int m;
+ int err;
+ int nels;
+ int nslabs;
+ int nstarts; /* number of different starts */
+ int nok = 0; /* total count of valid comparisons */
+ int n; /* count of valid comparisons within var */
+ MPI_Offset start[MAX_RANK];
+ MPI_Offset edge[MAX_RANK];
+ MPI_Offset index[MAX_RANK];
+ MPI_Offset index2[MAX_RANK];
+ MPI_Offset mid[MAX_RANK];
+ MPI_Offset count[MAX_RANK];
+ MPI_Offset sstride[MAX_RANK];
+ MPI_Offset stride[MAX_RANK];
+ MPI_Datatype datatype;
+ double buf[MAX_NELS]; /* (void *) buffer */
+ char *p; /* (void *) pointer */
+ double expect;
+ double got;
+
+ err = ncmpi_open(comm, testfile, NC_NOWRITE, info, &ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_open: %s", ncmpi_strerror(err));
+ err = ncmpi_begin_indep_data(ncid);
+ for (i = 0; i < numVars; i++) {
+ datatype = nc_mpi_type(var_type[i]);
+ assert(var_rank[i] <= MAX_RANK);
+ assert(var_nels[i] <= MAX_NELS);
+ for (j = 0; j < var_rank[i]; j++) {
+ start[j] = 0;
+ edge[j] = 1;
+ stride[j] = 1;
+ }
+ err = ncmpi_get_vars(BAD_ID, i, start, edge, stride, buf, 1, datatype);
+ IF (err != NC_EBADID)
+ error("bad ncid: status = %d", err);
+ ELSE_NOK
+ err = ncmpi_get_vars(ncid, BAD_VARID, start, edge, stride, buf, 1, datatype);
+ IF (err != NC_ENOTVAR)
+ error("bad var id: status = %d", err);
+ ELSE_NOK
+ for (j = 0; j < var_rank[i]; j++) {
+ start[j] = var_shape[i][j];
+ err = ncmpi_get_vars(ncid, i, start, edge, stride, buf, 1, datatype);
+ IF (err != NC_EINVALCOORDS)
+ error("bad index: status = %d", err);
+ ELSE_NOK
+ start[j] = 0;
+ edge[j] = var_shape[i][j] + 1;
+ err = ncmpi_get_vars(ncid, i, start, edge, stride, buf, 1, datatype);
+ IF (err != NC_EEDGE)
+ error("bad edge: status = %d", err);
+ ELSE_NOK
+ edge[j] = 1;
+ stride[j] = 0;
+ err = ncmpi_get_vars(ncid, i, start, edge, stride, buf, 1, datatype);
+ IF (err != NC_ESTRIDE)
+ error("bad stride: status = %d", err);
+ ELSE_NOK
+ stride[j] = 1;
+ }
+ /* Choose a random point dividing each dim into 2 parts */
+ /* get 2^rank (nslabs) slabs so defined */
+ nslabs = 1;
+ for (j = 0; j < var_rank[i]; j++) {
+ mid[j] = roll( var_shape[i][j] );
+ nslabs *= 2;
+ }
+ /* bits of k determine whether to get lower or upper part of dim */
+ /* choose random stride from 1 to edge */
+ n = 0;
+ for (k = 0; k < nslabs; k++) {
+ nstarts = 1;
+ for (j = 0; j < var_rank[i]; j++) {
+ if ((k >> j) & 1) {
+ start[j] = 0;
+ edge[j] = mid[j];
+ }else{
+ start[j] = mid[j];
+ edge[j] = var_shape[i][j] - mid[j];
+ }
+ sstride[j] = stride[j] = edge[j] > 0 ? 1+roll(edge[j]) : 1;
+ nstarts *= stride[j];
+ }
+ for (m = 0; m < nstarts; m++) {
+ err = toMixedBase(m, var_rank[i], sstride, index);
+ IF (err != NC_NOERR)
+ error("error in toMixedBase");
+ nels = 1;
+ for (j = 0; j < var_rank[i]; j++) {
+ count[j] = 1 + (edge[j] - index[j] - 1) / stride[j];
+ nels *= count[j];
+ index[j] += start[j];
+ }
+ /* Random choice of forward or backward */
+/* TODO
+ if ( roll(2) ) {
+ for (j = 0; j < var_rank[i]; j++) {
+ index[j] += (count[j] - 1) * stride[j];
+ stride[j] = -stride[j];
+ }
+ }
+ */
+ if (var_rank[i] == 0 && i%2 )
+ err = ncmpi_get_vars(ncid, i, NULL, NULL, NULL, buf, 1, datatype);
+ else
+ err = ncmpi_get_vars(ncid, i, index, count, stride, buf, nels, datatype);
+ IF (err != NC_NOERR) {
+ error("%s", ncmpi_strerror(err));
+ } else {
+ nok++;
+ for (j = 0; j < nels; j++) {
+ p = (char *) buf;
+ p += j * nctypelen(var_type[i]);
+ err = nc2dbl( var_type[i], p, & got );
+ IF (err != NC_NOERR)
+ error("error in nc2dbl");
+ err = toMixedBase(j, var_rank[i], count, index2);
+ IF (err != NC_NOERR)
+ error("error in toMixedBase 1");
+ for (d = 0; d < var_rank[i]; d++)
+ index2[d] = index[d] + index2[d] * stride[d];
+ expect = hash(var_type[i], var_rank[i], index2);
+ if (inRange(expect,var_type[i])) {
+ IF (!equal2(got,expect,var_type[i])) {
+ error("value read not that expected");
+ if (verbose) {
+ error("\n");
+ error("varid: %d, ", i);
+ error("var_name: %s, ", var_name[i]);
+ error("element number: %d ", j);
+ error("expect: %g, ", expect);
+ error("got: %g ", got);
+ }
+ }
+ }
+ n++;
+ }
+ }
+ }
+ }
+ IF (n != var_nels[i]) {
+ error("count != nels");
+ if (verbose) {
+ error("\n");
+ error("varid: %d, ", i);
+ error("var_name: %s, ", var_name[i]);
+ error("count: %d, ", n);
+ error("nels: %d ", var_nels[i]);
+ }
+ }
+ }
+ err = ncmpi_close(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_close: %s", ncmpi_strerror(err));
+ return nok;
+}
+
+
+/*
+ * Test ncmpi_get_varm
+ * Choose a random point dividing each dim into 2 parts
+ * Get 2^rank (nslabs) slabs so defined
+ * Choose random stride from 1 to edge
+ * Buffer should end up being bit image of external variable.
+ * So all gets for a variable store in different elements of buffer
+ */
+int
+test_ncmpi_get_varm(void)
+{
+ int ncid;
+ int i;
+ int j;
+ int k;
+ int m;
+ int err;
+ int nslabs;
+ int nstarts; /* number of different starts */
+ int nok = 0; /* total count of valid comparisons */
+ MPI_Offset start[MAX_RANK];
+ MPI_Offset edge[MAX_RANK];
+ MPI_Offset index[MAX_RANK];
+ MPI_Offset mid[MAX_RANK];
+ MPI_Offset count[MAX_RANK];
+ MPI_Offset sstride[MAX_RANK];
+ MPI_Offset stride[MAX_RANK];
+ MPI_Offset imap[MAX_RANK];
+ MPI_Offset imap2[MAX_RANK];
+ MPI_Offset nels;
+ MPI_Datatype datatype;
+ double buf[MAX_NELS]; /* (void *) buffer */
+ char *p; /* (void *) pointer */
+ double expect;
+ double got;
+
+ err = ncmpi_open(comm, testfile, NC_NOWRITE, info, &ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_open: %s", ncmpi_strerror(err));
+ err = ncmpi_begin_indep_data(ncid);
+ for (i = 0; i < numVars; i++) {
+ datatype = nc_mpi_type(var_type[i]);
+ assert(var_rank[i] <= MAX_RANK);
+ assert(var_nels[i] <= MAX_NELS);
+ for (j = 0; j < var_rank[i]; j++) {
+ start[j] = 0;
+ edge[j] = 1;
+ stride[j] = 1;
+ }
+ if (var_rank[i] > 0) {
+ j = var_rank[i] - 1;
+ /* imap[j] = nctypelen(var_type[i]); */
+ imap[j] = 1; /* in numbers of elements */
+ for (; j > 0; j--)
+ imap[j-1] = imap[j] * var_shape[i][j];
+ }
+ err = ncmpi_get_varm(BAD_ID, i, start, edge, stride, imap, buf, 1, datatype);
+ IF (err != NC_EBADID)
+ error("bad ncid: status = %d", err);
+ ELSE_NOK
+ err = ncmpi_get_varm(ncid, BAD_VARID, start, edge, stride, imap, buf, 1, datatype);
+ IF (err != NC_ENOTVAR)
+ error("bad var id: status = %d", err);
+ ELSE_NOK
+ for (j = 0; j < var_rank[i]; j++) {
+ start[j] = var_shape[i][j];
+ err = ncmpi_get_varm(ncid, i, start, edge, stride, imap, buf, 1, datatype);
+ IF (err != NC_EINVALCOORDS)
+ error("bad index: status = %d", err);
+ ELSE_NOK
+ start[j] = 0;
+ edge[j] = var_shape[i][j] + 1;
+ err = ncmpi_get_varm(ncid, i, start, edge, stride, imap, buf, 1, datatype);
+ IF (err != NC_EEDGE)
+ error("bad edge: status = %d", err);
+ ELSE_NOK
+ edge[j] = 1;
+ stride[j] = 0;
+ err = ncmpi_get_varm(ncid, i, start, edge, stride, imap, buf, 1, datatype);
+ IF (err != NC_ESTRIDE)
+ error("bad stride: status = %d", err);
+ ELSE_NOK
+ stride[j] = 1;
+ }
+ /* Choose a random point dividing each dim into 2 parts */
+ /* get 2^rank (nslabs) slabs so defined */
+ nslabs = 1;
+ for (j = 0; j < var_rank[i]; j++) {
+ mid[j] = roll( var_shape[i][j] );
+ nslabs *= 2;
+ }
+ /* bits of k determine whether to get lower or upper part of dim */
+ /* choose random stride from 1 to edge */
+ for (k = 0; k < nslabs; k++) {
+ nstarts = 1;
+ for (j = 0; j < var_rank[i]; j++) {
+ if ((k >> j) & 1) {
+ start[j] = 0;
+ edge[j] = mid[j];
+ }else{
+ start[j] = mid[j];
+ edge[j] = var_shape[i][j] - mid[j];
+ }
+ sstride[j] = stride[j] = edge[j] > 0 ? 1+roll(edge[j]) : 1;
+ imap2[j] = imap[j] * sstride[j];
+ nstarts *= stride[j];
+ }
+ for (m = 0; m < nstarts; m++) {
+ if (var_rank[i] == 0 && i%2 ) {
+ err = ncmpi_get_varm(ncid, i, NULL, NULL, NULL, NULL, buf, var_nels[i], datatype);
+ } else {
+ err = toMixedBase(m, var_rank[i], sstride, index);
+ IF (err != NC_NOERR)
+ error("error in toMixedBase");
+ nels = 1;
+ for (j = 0; j < var_rank[i]; j++) {
+ count[j] = 1 + (edge[j] - index[j] - 1) / stride[j];
+ index[j] += start[j];
+ nels *= count[j];
+ }
+ /* Random choice of forward or backward */
+/* TODO
+ if ( roll(2) ) {
+ for (j = 0; j < var_rank[i]; j++) {
+ index[j] += (count[j] - 1) * stride[j];
+ stride[j] = -stride[j];
+ }
+ }
+ */
+ j = fromMixedBase(var_rank[i], index, var_shape[i]);
+ p = (char *) buf + j * nctypelen(var_type[i]);
+ err = ncmpi_get_varm(ncid, i, index, count, stride, imap2, p, nels, datatype);
+ }
+ IF (err != NC_NOERR)
+ error("%s", ncmpi_strerror(err));
+ ELSE_NOK
+ }
+ }
+ p = (char *) buf;
+ for (j = 0; j < var_nels[i]; j++) {
+ err = toMixedBase(j, var_rank[i], var_shape[i], index);
+ IF (err != NC_NOERR)
+ error("error in toMixedBase");
+ expect = hash( var_type[i], var_rank[i], index);
+ err = nc2dbl( var_type[i], p, & got );
+ IF (err != NC_NOERR)
+ error("error in nc2dbl");
+ if (inRange(expect,var_type[i])) {
+ IF (!equal2(got,expect,var_type[i])) {
+ error("value read not that expected");
+ if (verbose) {
+ error("\n");
+ error("varid: %d, ", i);
+ error("var_name: %s, ", var_name[i]);
+ error("element number: %d ", j);
+ error("expect: %g, ", expect);
+ error("got: %g ", got);
+ }
+ }
+ ELSE_NOK
+ }
+ p += nctypelen(var_type[i]);
+ }
+ }
+ err = ncmpi_close(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_close: %s", ncmpi_strerror(err));
+ return nok;
+}
+
+
+int
+test_ncmpi_get_att(void)
+{
+ int ncid;
+ int i;
+ int j;
+ MPI_Offset k;
+ int err;
+ double buf[MAX_NELS]; /* (void *) buffer */
+ char *p; /* (void *) pointer */
+ double expect;
+ double got;
+ int nok = 0; /* count of valid comparisons */
+
+ err = ncmpi_open(comm, testfile, NC_NOWRITE, info, &ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_open: %s", ncmpi_strerror(err));
+
+ for (i = -1; i < numVars; i++) {
+ for (j = 0; j < NATTS(i); j++) {
+ err = ncmpi_get_att(BAD_ID, i, ATT_NAME(i,j), buf);
+ IF (err != NC_EBADID)
+ error("bad ncid: status = %d", err);
+ ELSE_NOK
+ err = ncmpi_get_att(ncid, BAD_VARID, ATT_NAME(i,j), buf);
+ IF (err != NC_ENOTVAR)
+ error("bad var id: status = %d", err);
+ ELSE_NOK
+ err = ncmpi_get_att(ncid, i, "noSuch", buf);
+ IF (err != NC_ENOTATT)
+ error("Bad attribute name: status = %d", err);
+ ELSE_NOK
+ err = ncmpi_get_att(ncid, i, ATT_NAME(i,j), buf);
+ IF (err != NC_NOERR) {
+ error("%s", ncmpi_strerror(err));
+ } else {
+ nok++;
+ for (k = 0; k < ATT_LEN(i,j); k++) {
+ expect = hash(ATT_TYPE(i,j), -1, &k );
+ p = (char *) buf;
+ p += k * nctypelen(ATT_TYPE(i,j));
+ err = nc2dbl( ATT_TYPE(i,j), p, &got );
+ IF (err != NC_NOERR)
+ error("error in nc2dbl");
+ if (inRange(expect,ATT_TYPE(i,j))) {
+ IF (!equal2(got,expect,ATT_TYPE(i,j))) {
+ error("value read not that expected");
+ if (verbose) {
+ error("\n");
+ error("varid: %d, ", i);
+ error("var_name: %s, ",
+ i >= 0 ? var_name[i] : "Global");
+ error("att_name: %s, ", ATT_NAME(i,j));
+ error("element number: %d\n", k);
+ error("expect: %-23.16e\n", expect);
+ error(" got: %-23.16e", got);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ err = ncmpi_close(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_close: %s", ncmpi_strerror(err));
+ return nok;
+}
+
+
+int
+test_ncmpi_inq_att(void)
+{
+ int ncid;
+ int i;
+ int j;
+ int err;
+ nc_type t;
+ MPI_Offset n;
+ int nok=0;
+
+ err = ncmpi_open(comm, testfile, NC_NOWRITE, info, &ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_open: %s", ncmpi_strerror(err));
+
+ for (i = -1; i < numVars; i++) {
+ for (j = 0; j < NATTS(i); j++) {
+ err = ncmpi_inq_att(BAD_ID, i, ATT_NAME(i,j), &t, &n);
+ IF (err != NC_EBADID)
+ error("bad ncid: status = %d", err);
+ ELSE_NOK
+ err = ncmpi_inq_att(ncid, BAD_VARID, ATT_NAME(i,j), &t, &n);
+ IF (err != NC_ENOTVAR)
+ error("bad var id: status = %d", err);
+ ELSE_NOK
+ err = ncmpi_inq_att(ncid, i, "noSuch", &t, &n);
+ IF (err != NC_ENOTATT)
+ error("Bad attribute name: status = %d", err);
+ ELSE_NOK
+ err = ncmpi_inq_att(ncid, i, ATT_NAME(i,j), &t, &n);
+ IF (err != NC_NOERR) {
+ error("%s", ncmpi_strerror(err));
+ } else {
+ IF (t != ATT_TYPE(i,j))
+ error("type not that expected");
+ else IF (n != ATT_LEN(i,j))
+ error("length not that expected");
+ ELSE_NOK
+ }
+ }
+ }
+
+ err = ncmpi_close(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_close: %s", ncmpi_strerror(err));
+ return nok;
+}
+
+
+int
+test_ncmpi_inq_attlen(void)
+{
+ int ncid;
+ int i;
+ int j;
+ int err;
+ MPI_Offset len;
+ int nok=0;
+
+ err = ncmpi_open(comm, testfile, NC_NOWRITE, info, &ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_open: %s", ncmpi_strerror(err));
+
+ for (i = -1; i < numVars; i++) {
+ err = ncmpi_inq_attlen(ncid, i, "noSuch", &len);
+ IF (err != NC_ENOTATT)
+ error("Bad attribute name: status = %d", err);
+ ELSE_NOK
+ for (j = 0; j < NATTS(i); j++) {
+ err = ncmpi_inq_attlen(BAD_ID, i, ATT_NAME(i,j), &len);
+ IF (err != NC_EBADID)
+ error("bad ncid: status = %d", err);
+ ELSE_NOK
+ err = ncmpi_inq_attlen(ncid, BAD_VARID, ATT_NAME(i,j), &len);
+ IF (err != NC_ENOTVAR)
+ error("bad varid: status = %d", err);
+ ELSE_NOK
+ err = ncmpi_inq_attlen(ncid, i, ATT_NAME(i,j), &len);
+ IF (err != NC_NOERR) {
+ error("%s", ncmpi_strerror(err));
+ } else {
+ IF (len != ATT_LEN(i,j))
+ error("len not that expected");
+ ELSE_NOK
+ }
+ }
+ }
+
+ err = ncmpi_close(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_close: %s", ncmpi_strerror(err));
+ return nok;
+}
+
+
+int
+test_ncmpi_inq_atttype(void)
+{
+ int ncid;
+ int i;
+ int j;
+ int err;
+ nc_type datatype;
+ int nok=0;
+
+ err = ncmpi_open(comm, testfile, NC_NOWRITE, info, &ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_open: %s", ncmpi_strerror(err));
+
+ for (i = -1; i < numVars; i++) {
+ err = ncmpi_inq_atttype(ncid, i, "noSuch", &datatype);
+ IF (err != NC_ENOTATT)
+ error("Bad attribute name: status = %d", err);
+ ELSE_NOK
+ for (j = 0; j < NATTS(i); j++) {
+ err = ncmpi_inq_atttype(BAD_ID, i, ATT_NAME(i,j), &datatype);
+ IF (err != NC_EBADID)
+ error("bad ncid: status = %d", err);
+ ELSE_NOK
+ err = ncmpi_inq_atttype(ncid, BAD_VARID, ATT_NAME(i,j), &datatype);
+ IF (err != NC_ENOTVAR)
+ error("bad varid: status = %d", err);
+ ELSE_NOK
+ err = ncmpi_inq_atttype(ncid, i, ATT_NAME(i,j), &datatype);
+ IF (err != NC_NOERR) {
+ error("%s", ncmpi_strerror(err));
+ } else {
+ IF (datatype != ATT_TYPE(i,j))
+ error("type not that expected");
+ ELSE_NOK
+ }
+ }
+ }
+
+ err = ncmpi_close(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_close: %s", ncmpi_strerror(err));
+ return nok;
+}
+
+
+int
+test_ncmpi_inq_attname(void)
+{
+ int ncid;
+ int i;
+ int j;
+ int err;
+ char name[NC_MAX_NAME];
+ int nok=0;
+
+ err = ncmpi_open(comm, testfile, NC_NOWRITE, info, &ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_open: %s", ncmpi_strerror(err));
+
+ for (i = -1; i < numVars; i++) {
+ err = ncmpi_inq_attname(ncid, i, BAD_ATTNUM, name);
+ IF (err != NC_ENOTATT)
+ error("Bad attribute number: status = %d", err);
+ ELSE_NOK
+ err = ncmpi_inq_attname(ncid, i, NATTS(i), name);
+ IF (err != NC_ENOTATT)
+ error("Bad attribute number: status = %d", err);
+ ELSE_NOK
+ for (j = 0; j < NATTS(i); j++) {
+ err = ncmpi_inq_attname(BAD_ID, i, j, name);
+ IF (err != NC_EBADID)
+ error("bad ncid: status = %d", err);
+ ELSE_NOK
+ err = ncmpi_inq_attname(ncid, BAD_VARID, j, name);
+ IF (err != NC_ENOTVAR)
+ error("bad var id: status = %d", err);
+ ELSE_NOK
+ err = ncmpi_inq_attname(ncid, i, j, name);
+ IF (err != NC_NOERR) {
+ error("%s", ncmpi_strerror(err));
+ } else {
+ IF (strcmp(ATT_NAME(i,j), name) != 0)
+ error("name not that expected");
+ ELSE_NOK
+ }
+ }
+ }
+
+ err = ncmpi_close(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_close: %s", ncmpi_strerror(err));
+ return nok;
+}
+
+
+int
+test_ncmpi_inq_attid(void)
+{
+ int ncid;
+ int i;
+ int j;
+ int err;
+ int attnum;
+ int nok=0;
+
+ err = ncmpi_open(comm, testfile, NC_NOWRITE, info, &ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_open: %s", ncmpi_strerror(err));
+
+ for (i = -1; i < numVars; i++) {
+ err = ncmpi_inq_attid(ncid, i, "noSuch", &attnum);
+ IF (err != NC_ENOTATT)
+ error("Bad attribute name: status = %d", err);
+ ELSE_NOK
+ for (j = 0; j < NATTS(i); j++) {
+ err = ncmpi_inq_attid(BAD_ID, i, ATT_NAME(i,j), &attnum);
+ IF (err != NC_EBADID)
+ error("bad ncid: status = %d", err);
+ ELSE_NOK
+ err = ncmpi_inq_attid(ncid, BAD_VARID, ATT_NAME(i,j), &attnum);
+ IF (err != NC_ENOTVAR)
+ error("bad varid: status = %d", err);
+ ELSE_NOK
+ err = ncmpi_inq_attid(ncid, i, ATT_NAME(i,j), &attnum);
+ IF (err != NC_NOERR) {
+ error("%s", ncmpi_strerror(err));
+ } else {
+ IF (attnum != j)
+ error("attnum not that expected");
+ ELSE_NOK
+ }
+ }
+ }
+
+ err = ncmpi_close(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_close: %s", ncmpi_strerror(err));
+ return nok;
+}
+
diff --git a/test/nc_test/test_write.c b/test/nc_test/test_write.c
new file mode 100644
index 0000000..604601e
--- /dev/null
+++ b/test/nc_test/test_write.c
@@ -0,0 +1,2185 @@
+/*
+ * Copyright (C) 2003, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ *
+ * $Id: test_write.c 2289 2016-01-02 08:26:40Z wkliao $
+ */
+
+#include "tests.h"
+#include "math.h"
+
+
+/*
+ * Test ncmpi_create
+ * For mode in NC_NOCLOBBER|extra_flags, NC_CLOBBER, info do:
+ * create netcdf file 'scratch.nc' with no data, close it
+ * test that it can be opened, do ncmpi_inq to check nvars = 0, etc.
+ * Try again in NC_NOCLOBBER|extra_flags mode, check error return
+ * On exit, delete this file
+ */
+int
+test_ncmpi_create(void)
+{
+ int clobber; /* 0 for NC_NOCLOBBER|extra_flags, 1 for NC_CLOBBER, info */
+ int err;
+ int ncid;
+ int ndims; /* number of dimensions */
+ int nvars; /* number of variables */
+ int ngatts; /* number of global attributes */
+ int recdim; /* id of unlimited dimension */
+ int nok=0;
+
+ for (clobber = 0; clobber < 2; clobber++) {
+ err = ncmpi_create(comm, scratch, clobber ? NC_CLOBBER|extra_flags : NC_NOCLOBBER, info, &ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_create: %s", ncmpi_strerror(err));
+ ELSE_NOK
+ err = ncmpi_close(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_close: %s", ncmpi_strerror(err));
+ err = ncmpi_open(comm, scratch, NC_NOWRITE, info, &ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_open: %s", ncmpi_strerror(err));
+ err = ncmpi_inq(ncid, &ndims, &nvars, &ngatts, &recdim);
+ IF (err != NC_NOERR)
+ error("ncmpi_inq: %s", ncmpi_strerror(err));
+ else IF (ndims != 0)
+ error("ncmpi_inq: wrong number of dimensions returned, %d", ndims);
+ else IF (nvars != 0)
+ error("ncmpi_inq: wrong number of variables returned, %d", nvars);
+ else IF (ngatts != 0)
+ error("ncmpi_inq: wrong number of global atts returned, %d", ngatts);
+ else IF (recdim != -1)
+ error("ncmpi_inq: wrong record dimension ID returned, %d", recdim);
+ ELSE_NOK
+ err = ncmpi_close(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_close: %s", ncmpi_strerror(err));
+ }
+
+ err = ncmpi_create(comm, scratch, NC_NOCLOBBER|extra_flags, info, &ncid);
+ IF (err != NC_EEXIST)
+ error("attempt to overwrite file: status = %d", err);
+ ELSE_NOK
+
+ err = ncmpi_delete(scratch, info);
+ IF (err != NC_NOERR)
+ error("remove of %s failed", scratch);
+ return nok;
+}
+
+
+/*
+ * Test ncmpi_redef
+ * (In fact also tests ncmpi_enddef - called from test_ncmpi_enddef)
+ * BAD_ID
+ * attempt redef (error) & enddef on read-only file
+ * create file, define dims & vars.
+ * attempt put var (error)
+ * attempt redef (error) & enddef.
+ * put vars
+ * attempt def new dims (error)
+ * redef
+ * def new dims, vars.
+ * put atts
+ * enddef
+ * put vars
+ * close
+ * check file: vars & atts
+ */
+int
+test_ncmpi_redef(void)
+{
+ int ncid; /* netcdf id */
+ /* used to force effective test of ncio->move() in redef */
+ size_t sizehint = 8192;
+ int dimid; /* dimension id */
+ int varid; /* variable id */
+ int varid1; /* variable id */
+ int nok=0, err;
+ const char * title = "Not funny";
+ double var;
+ char name[NC_MAX_NAME];
+ MPI_Offset length;
+
+ /* BAD_ID tests */
+ err = ncmpi_redef(BAD_ID);
+ IF (err != NC_EBADID)
+ error("bad ncid: status = %d", err);
+ ELSE_NOK
+ err = ncmpi_enddef(BAD_ID);
+ IF (err != NC_EBADID)
+ error("bad ncid: status = %d", err);
+ ELSE_NOK
+
+ /* read-only tests */
+ err = ncmpi_open(comm, testfile, NC_NOWRITE, info, &ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_open: %s", ncmpi_strerror(err));
+ err = ncmpi_redef(ncid);
+ IF (err != NC_EPERM)
+ error("ncmpi_redef in NC_NOWRITE, info mode: status = %d", err);
+ ELSE_NOK
+ err = ncmpi_enddef(ncid);
+ IF (err != NC_ENOTINDEFINE)
+ error("ncmpi_endfef in NC_NOWRITE, info mode: status = %d", err);
+ ELSE_NOK
+ err = ncmpi_close(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_close: %s", ncmpi_strerror(err));
+
+ /* tests using scratch file */
+ err = ncmpi_create(comm, scratch, NC_NOCLOBBER|extra_flags, info, &ncid);
+ /* err = ncmpi__create(scratch, NC_NOCLOBBER|extra_flags, 0, &sizehint, &ncid); */
+ IF (err != NC_NOERR) {
+ error("ncmpi_create: %s", ncmpi_strerror(err));
+ return nok;
+ }
+ /* limit for ncio implementations which which have infinite chunksize */
+ if(sizehint > 32768)
+ sizehint = 16384;
+ def_dims(ncid);
+ def_vars(ncid);
+ put_atts(ncid);
+ err = ncmpi_inq_varid(ncid, "d", &varid);
+ IF (err != NC_NOERR)
+ error("ncmpi_inq_varid: %s", ncmpi_strerror(err));
+ var = 1.0;
+ err = ncmpi_begin_indep_data(ncid);
+ IF (err != NC_EINDEFINE)
+ error("ncmpi_begin_indep_data... in define mode: status = %d", err);
+ err = ncmpi_put_var1_double(ncid, varid, NULL, &var);
+ IF (err != NC_EINDEFINE)
+ error("ncmpi_put_var... in define mode: status = %d", err);
+ err = ncmpi_end_indep_data(ncid);
+ IF (err != NC_ENOTINDEP)
+ error("ncmpi_end_indep_data... not in indep mode: status = %d", err);
+ err = ncmpi_redef(ncid);
+ IF (err != NC_EINDEFINE)
+ error("ncmpi_redef in define mode: status = %d", err);
+ ELSE_NOK
+ err = ncmpi_enddef(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_enddef: %s", ncmpi_strerror(err));
+ ELSE_NOK
+ put_vars(ncid);
+ err = ncmpi_def_dim(ncid, "abc", sizehint, &dimid);
+ IF (err != NC_ENOTINDEFINE)
+ error("ncmpi_def_dim in define mode: status = %d", err);
+ err = ncmpi_redef(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_redef: %s", ncmpi_strerror(err));
+ ELSE_NOK
+ err = ncmpi_set_fill(ncid, NC_NOFILL, NULL);
+ IF (err != NC_NOERR)
+ error("ncmpi_set_fill: %s", ncmpi_strerror(err));
+ err = ncmpi_def_dim(ncid, "abc", sizehint, &dimid);
+ IF (err != NC_NOERR)
+ error("ncmpi_def_dim: %s", ncmpi_strerror(err));
+ err = ncmpi_def_var(ncid, "abcScalar", NC_INT, 0, NULL, &varid);
+ IF (err != NC_NOERR)
+ error("ncmpi_def_var: %s", ncmpi_strerror(err));
+ err = ncmpi_def_var(ncid, "abc", NC_INT, 1, &dimid, &varid1);
+ IF (err != NC_NOERR)
+ error("ncmpi_def_var: %s", ncmpi_strerror(err));
+ {
+ int dimids[NDIMS +1];
+ int ii = 0;
+ for(ii = 0; ii < NDIMS; ii++)
+ dimids[ii] = ii;
+ dimids[NDIMS] = dimid;
+ err = ncmpi_def_var(ncid, "abcRec", NC_INT, NDIMS, dimids, &varid1);
+ IF (err != NC_NOERR)
+ error("ncmpi_def_var: %s", ncmpi_strerror(err));
+ }
+ err = ncmpi_put_att_text(ncid, NC_GLOBAL, "title", 1+strlen(title), title);
+ IF (err != NC_NOERR)
+ error("ncmpi_put_att_text: %s", ncmpi_strerror(err));
+ err = ncmpi_enddef(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_enddef: %s", ncmpi_strerror(err));
+ ELSE_NOK
+ var = 1.0;
+ err = ncmpi_end_indep_data(ncid);
+ IF (err != NC_ENOTINDEP)
+ error("ncmpi_end_indep_data: in collective mode status = %s", ncmpi_strerror(err));
+ err = ncmpi_begin_indep_data(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_begin_indep_data: %s", ncmpi_strerror(err));
+ err = ncmpi_put_var1_double(ncid, varid, NULL, &var);
+ IF (err != NC_NOERR)
+ error("ncmpi_put_var1_double: %s", ncmpi_strerror(err));
+ err = ncmpi_end_indep_data(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_begin_indep_data: %s", ncmpi_strerror(err));
+ err = ncmpi_close(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_close: %s", ncmpi_strerror(err));
+
+ /* check scratch file written as expected */
+ check_file(scratch);
+ err = ncmpi_open(comm, scratch, NC_NOWRITE, info, &ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_open: %s", ncmpi_strerror(err));
+ err = ncmpi_inq_dim(ncid, dimid, name, &length);
+ IF (err != NC_NOERR)
+ error("ncmpi_inq_dim: %s", ncmpi_strerror(err));
+ IF (strcmp(name, "abc") != 0)
+ error("Unexpected dim name");
+ IF (length != sizehint)
+ error("Unexpected dim length");
+ ncmpi_begin_indep_data(ncid);
+ err = ncmpi_get_var1_double(ncid, varid, NULL, &var);
+ IF (err != NC_NOERR)
+ error("ncmpi_get_var1_double: %s", ncmpi_strerror(err));
+ ncmpi_end_indep_data(ncid);
+ IF (var != 1.0)
+ error("ncmpi_get_var1_double: unexpected value");
+ err = ncmpi_close(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_close: %s", ncmpi_strerror(err));
+
+ err = ncmpi_delete(scratch, info);
+ IF (err != NC_NOERR)
+ error("remove of %s failed", scratch);
+ return nok;
+}
+
+
+/*
+ * Test ncmpi_enddef
+ * Simply calls test_ncmpi_redef which tests both ncmpi_redef & ncmpi_enddef
+ */
+int
+test_ncmpi_enddef(void)
+{
+ return test_ncmpi_redef();
+}
+
+
+/*
+ * Test ncmpi_sync
+ * try with bad handle, check error
+ * try in define mode, check error
+ * try writing with one handle, reading with another on same netCDF
+ */
+int
+test_ncmpi_sync(void)
+{
+ int ncidw; /* netcdf id for writing */
+ int ncidr; /* netcdf id for reading */
+ int nok=0, err;
+
+ /* BAD_ID test */
+ err = ncmpi_sync(BAD_ID);
+ IF (err != NC_EBADID)
+ error("bad ncid: status = %d", err);
+ ELSE_NOK
+
+ /* create scratch file & try ncmpi_sync in define mode */
+ err = ncmpi_create(comm, scratch, NC_NOCLOBBER|extra_flags, info, &ncidw);
+ IF (err != NC_NOERR) {
+ error("ncmpi_create: %s", ncmpi_strerror(err));
+ return nok;
+ }
+ err = ncmpi_sync(ncidw);
+ IF (err != NC_EINDEFINE)
+ error("ncmpi_sync called in define mode: status = %d", err);
+ ELSE_NOK
+
+ /* write using same handle */
+ def_dims(ncidw);
+ def_vars(ncidw);
+ put_atts(ncidw);
+ err = ncmpi_enddef(ncidw);
+ IF (err != NC_NOERR)
+ error("ncmpi_enddef: %s", ncmpi_strerror(err));
+ put_vars(ncidw);
+ err = ncmpi_sync(ncidw);
+ IF (err != NC_NOERR)
+ error("ncmpi_sync of ncidw failed: %s", ncmpi_strerror(err));
+ ELSE_NOK
+
+ /* open another handle, ncmpi_sync, read (check) */
+ err = ncmpi_open(comm, scratch, NC_NOWRITE, info, &ncidr);
+ IF (err != NC_NOERR)
+ error("ncmpi_open: %s", ncmpi_strerror(err));
+ err = ncmpi_sync(ncidr);
+ IF (err != NC_NOERR)
+ error("ncmpi_sync of ncidr failed: %s", ncmpi_strerror(err));
+ ELSE_NOK
+ check_dims(ncidr);
+ check_atts(ncidr);
+ check_vars(ncidr);
+
+ /* close both handles */
+ err = ncmpi_close(ncidr);
+ IF (err != NC_NOERR)
+ error("ncmpi_close: %s", ncmpi_strerror(err));
+ err = ncmpi_close(ncidw);
+ IF (err != NC_NOERR)
+ error("ncmpi_close: %s", ncmpi_strerror(err));
+
+ err = ncmpi_delete(scratch, info);
+ IF (err != NC_NOERR)
+ error("remove of %s failed", scratch);
+ return nok;
+}
+
+
+/*
+ * Test ncmpi_abort
+ * try with bad handle, check error
+ * try in define mode before anything written, check that file was deleted
+ * try after ncmpi_enddef, ncmpi_redef, define new dims, vars, atts
+ * try after writing variable
+ */
+int
+test_ncmpi_abort(void)
+{
+ int ncid; /* netcdf id */
+ int err;
+ int ndims;
+ int nvars;
+ int ngatts;
+ int nok=0;
+
+ /* BAD_ID test */
+ err = ncmpi_abort(BAD_ID);
+ IF (err != NC_EBADID)
+ error("bad ncid: status = %d", err);
+ ELSE_NOK
+
+ /* create scratch file & try ncmpi_abort in define mode */
+ err = ncmpi_create(comm, scratch, NC_NOCLOBBER|extra_flags, info, &ncid);
+ IF (err != NC_NOERR) {
+ error("ncmpi_create: %s", ncmpi_strerror(err));
+ return nok;
+ }
+ def_dims(ncid);
+ def_vars(ncid);
+ put_atts(ncid);
+ err = ncmpi_abort(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_abort of ncid failed: %s", ncmpi_strerror(err));
+ ELSE_NOK
+ err = ncmpi_close(ncid); /* should already be closed */
+ IF (err != NC_EBADID)
+ error("bad ncid: status = %d", err);
+ err = ncmpi_delete(scratch, info); /* should already be deleted */
+ IF (!err) /* err is expected to be NC_ENOENT */
+ error("file %s should not exist", scratch);
+
+ /*
+ * create scratch file
+ * do ncmpi_enddef & ncmpi_redef
+ * define new dims, vars, atts
+ * try ncmpi_abort: should restore previous state (no dims, vars, atts)
+ */
+ err = ncmpi_create(comm, scratch, NC_NOCLOBBER|extra_flags, info, &ncid);
+ IF (err != NC_NOERR) {
+ error("ncmpi_create: %s", ncmpi_strerror(err));
+ return nok;
+ }
+ err = ncmpi_enddef(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_enddef: %s", ncmpi_strerror(err));
+ err = ncmpi_redef(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_redef: %s", ncmpi_strerror(err));
+ def_dims(ncid);
+ def_vars(ncid);
+ put_atts(ncid);
+ err = ncmpi_abort(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_abort of ncid failed: %s", ncmpi_strerror(err));
+ ELSE_NOK
+ err = ncmpi_close(ncid); /* should already be closed */
+ IF (err != NC_EBADID)
+ error("bad ncid: status = %d", err);
+ err = ncmpi_open(comm, scratch, NC_NOWRITE, info, &ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_open: %s", ncmpi_strerror(err));
+ err = ncmpi_inq (ncid, &ndims, &nvars, &ngatts, NULL);
+ IF (err != NC_NOERR)
+ error("ncmpi_inq: %s", ncmpi_strerror(err));
+ IF (ndims != 0)
+ error("ndims should be 0");
+ IF (nvars != 0)
+ error("nvars should be 0");
+ IF (ngatts != 0)
+ error("ngatts should be 0");
+ err = ncmpi_close (ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_close: %s", ncmpi_strerror(err));
+
+ /* try ncmpi_abort in data mode - should just close */
+ err = ncmpi_create(comm, scratch, NC_CLOBBER|extra_flags, info, &ncid);
+ IF (err != NC_NOERR) {
+ error("ncmpi_create: %s", ncmpi_strerror(err));
+ return nok;
+ }
+ def_dims(ncid);
+ def_vars(ncid);
+ put_atts(ncid);
+ err = ncmpi_enddef(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_enddef: %s", ncmpi_strerror(err));
+ put_vars(ncid);
+ err = ncmpi_abort(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_abort of ncid failed: %s", ncmpi_strerror(err));
+ ELSE_NOK
+ err = ncmpi_close(ncid); /* should already be closed */
+ IF (err != NC_EBADID)
+ error("bad ncid: status = %d", err);
+ check_file(scratch);
+ err = ncmpi_delete(scratch, info);
+ IF (err != NC_NOERR)
+ error("remove of %s failed", scratch);
+ return nok;
+}
+
+
+/*
+ * Test ncmpi_def_dim
+ * try with bad netCDF handle, check error
+ * try in data mode, check error
+ * check that returned id is one more than previous id
+ * try adding same dimension twice, check error
+ * try with illegal sizes, check error
+ * make sure unlimited size works, shows up in ncmpi_inq_unlimdim
+ * try to define a second unlimited dimension, check error
+ */
+int
+test_ncmpi_def_dim(void)
+{
+ int ncid;
+ int err; /* status */
+ int i, nok=0;
+ int dimid; /* dimension id */
+ MPI_Offset length;
+
+ /* BAD_ID test */
+ err = ncmpi_def_dim(BAD_ID, "abc", 8, &dimid);
+ IF (err != NC_EBADID)
+ error("bad ncid: status = %d", err);
+ ELSE_NOK
+
+ /* data mode test */
+ err = ncmpi_create(comm, scratch, NC_CLOBBER|extra_flags, info, &ncid);
+ IF (err != NC_NOERR) {
+ error("ncmpi_create: %s", ncmpi_strerror(err));
+ return nok;
+ }
+ err = ncmpi_enddef(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_enddef: %s", ncmpi_strerror(err));
+ err = ncmpi_def_dim(ncid, "abc", 8, &dimid);
+ IF (err != NC_ENOTINDEFINE)
+ error("bad ncid: status = %d", err);
+ ELSE_NOK
+
+ /* define-mode tests: unlimited dim */
+ err = ncmpi_redef(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_redef: %s", ncmpi_strerror(err));
+ err = ncmpi_def_dim(ncid, dim_name[0], NC_UNLIMITED, &dimid);
+ IF (err != NC_NOERR)
+ error("ncmpi_def_dim: %s", ncmpi_strerror(err));
+ ELSE_NOK
+ IF (dimid != 0)
+ error("Unexpected dimid");
+ ELSE_NOK
+ err = ncmpi_inq_unlimdim(ncid, &dimid);
+ IF (err != NC_NOERR)
+ error("ncmpi_inq_unlimdim: %s", ncmpi_strerror(err));
+ IF (dimid != 0)
+ error("Unexpected recdim");
+ err = ncmpi_inq_dimlen(ncid, dimid, &length);
+ IF (length != 0)
+ error("Unexpected length");
+ err = ncmpi_def_dim(ncid, "abc", NC_UNLIMITED, &dimid);
+ IF (err != NC_EUNLIMIT)
+ error("2nd unlimited dimension: status = %d", err);
+ ELSE_NOK
+
+ /* define-mode tests: remaining dims */
+ for (i = 1; i < NDIMS; i++) {
+ err = ncmpi_def_dim(ncid, dim_name[i-1], dim_len[i], &dimid);
+ IF (err != NC_ENAMEINUSE)
+ error("duplicate name: status = %d", err);
+ ELSE_NOK
+ err = ncmpi_def_dim(ncid, BAD_NAME, dim_len[i], &dimid);
+ IF (err != NC_EBADNAME)
+ error("bad name: status = %d", err);
+ ELSE_NOK
+ err = ncmpi_def_dim(ncid, dim_name[i], NC_UNLIMITED-1, &dimid);
+ IF (err != NC_EDIMSIZE)
+ error("bad size: status = %d", err);
+ ELSE_NOK
+ err = ncmpi_def_dim(ncid, dim_name[i], dim_len[i], &dimid);
+ IF (err != NC_NOERR)
+ error("ncmpi_def_dim: %s", ncmpi_strerror(err));
+ ELSE_NOK
+ IF (dimid != i)
+ error("Unexpected dimid");
+ }
+
+ /* Following just to expand unlimited dim */
+ def_vars(ncid);
+ err = ncmpi_enddef(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_enddef: %s", ncmpi_strerror(err));
+ put_vars(ncid);
+
+ /* Check all dims */
+ check_dims(ncid);
+
+ err = ncmpi_close(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_close: %s", ncmpi_strerror(err));
+ err = ncmpi_delete(scratch, info);
+ IF (err != NC_NOERR)
+ error("remove of %s failed", scratch);
+ return nok;
+}
+
+
+/*
+ * Test ncmpi_rename_dim
+ * try with bad netCDF handle, check error
+ * check that proper rename worked with ncmpi_inq_dim
+ * try renaming to existing dimension name, check error
+ * try with bad dimension handle, check error
+ */
+int
+test_ncmpi_rename_dim(void)
+{
+ int ncid;
+ int err, nok=0; /* status */
+ char name[NC_MAX_NAME];
+
+ /* BAD_ID test */
+ err = ncmpi_rename_dim(BAD_ID, 0, "abc");
+ IF (err != NC_EBADID)
+ error("bad ncid: status = %d", err);
+ ELSE_NOK
+
+ /* main tests */
+ err = ncmpi_create(comm, scratch, NC_NOCLOBBER|extra_flags, info, &ncid);
+ IF (err != NC_NOERR) {
+ error("ncmpi_create: %s", ncmpi_strerror(err));
+ return nok;
+ }
+ def_dims(ncid);
+ err = ncmpi_rename_dim(ncid, BAD_DIMID, "abc");
+ IF (err != NC_EBADDIM)
+ error("bad dimid: status = %d", err);
+ ELSE_NOK
+ err = ncmpi_rename_dim(ncid, 2, "abc");
+ IF (err != NC_NOERR)
+ error("ncmpi_rename_dim: %s", ncmpi_strerror(err));
+ ELSE_NOK
+ err = ncmpi_inq_dimname(ncid, 2, name);
+ IF (strcmp(name, "abc") != 0)
+ error("Unexpected name: %s", name);
+ err = ncmpi_rename_dim(ncid, 0, "abc");
+ IF (err != NC_ENAMEINUSE)
+ error("duplicate name: status = %d", err);
+ ELSE_NOK
+
+ err = ncmpi_close(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_close: %s", ncmpi_strerror(err));
+ err = ncmpi_delete(scratch, info);
+ IF (err != NC_NOERR)
+ error("remove of %s failed", scratch);
+ return nok;
+}
+
+
+/*
+ * Test ncmpi_def_var
+ * try with bad netCDF handle, check error
+ * try with bad name, check error
+ * scalar tests:
+ * check that proper define worked with ncmpi_inq_var
+ * try redefining an existing variable, check error
+ * try with bad datatype, check error
+ * try with bad number of dimensions, check error
+ * try in data mode, check error
+ * check that returned id is one more than previous id
+ * try with bad dimension ids, check error
+ */
+int
+test_ncmpi_def_var(void)
+{
+ int ncid;
+ int varid;
+ int err, nok=0; /* status */
+ int i;
+ int ndims;
+ int natts;
+ char name[NC_MAX_NAME];
+ int dimids[MAX_RANK];
+ nc_type datatype;
+
+ /* BAD_ID test */
+ err = ncmpi_def_var(BAD_ID, "abc", NC_SHORT, 0, NULL, &varid);
+ IF (err != NC_EBADID)
+ error("bad ncid: status = %d", err);
+ ELSE_NOK
+
+ /* scalar tests */
+ err = ncmpi_create(comm, scratch, NC_NOCLOBBER|extra_flags, info, &ncid);
+ IF (err != NC_NOERR) {
+ error("ncmpi_create: %s", ncmpi_strerror(err));
+ return nok;
+ }
+ err = ncmpi_def_var(ncid, "abc", NC_SHORT, 0, NULL, &varid);
+ IF (err != NC_NOERR)
+ error("ncmpi_def_var: %s", ncmpi_strerror(err));
+ ELSE_NOK
+ err = ncmpi_inq_var(ncid, varid, name, &datatype, &ndims, dimids, &natts);
+ IF (err != NC_NOERR)
+ error("ncmpi_inq_var: %s", ncmpi_strerror(err));
+ IF (strcmp(name, "abc") != 0)
+ error("Unexpected name: %s", name);
+ IF (datatype != NC_SHORT)
+ error("Unexpected datatype");
+ IF (ndims != 0)
+ error("Unexpected rank");
+ err = ncmpi_def_var(ncid, BAD_NAME, NC_SHORT, 0, NULL, &varid);
+ IF (err != NC_EBADNAME)
+ error("bad name: status = %d", err);
+ ELSE_NOK
+ err = ncmpi_def_var(ncid, "abc", NC_SHORT, 0, NULL, &varid);
+ IF (err != NC_ENAMEINUSE)
+ error("duplicate name: status = %d", err);
+ ELSE_NOK
+ err = ncmpi_def_var(ncid, "ABC", BAD_TYPE, -1, dimids, &varid);
+ IF (err != NC_EBADTYPE)
+ error("bad type: status = %d", err);
+ ELSE_NOK
+ err = ncmpi_def_var(ncid, "ABC", NC_SHORT, -1, dimids, &varid);
+ IF (err != NC_EINVAL)
+ error("bad rank: status = %d", err);
+ ELSE_NOK
+ err = ncmpi_enddef(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_enddef: %s", ncmpi_strerror(err));
+ err = ncmpi_def_var(ncid, "ABC", NC_SHORT, 0, dimids, &varid);
+ IF (err != NC_ENOTINDEFINE)
+ error("ncmpi_def_var called in data mode: status = %d", err);
+ ELSE_NOK
+ err = ncmpi_close(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_close: %s", ncmpi_strerror(err));
+ err = ncmpi_delete(scratch, info);
+ IF (err != NC_NOERR)
+ error("remove of %s failed", scratch);
+
+ /* general tests using global vars */
+ err = ncmpi_create(comm, scratch, NC_CLOBBER|extra_flags, info, &ncid);
+ IF (err != NC_NOERR) {
+ error("ncmpi_create: %s", ncmpi_strerror(err));
+ return nok;
+ }
+ def_dims(ncid);
+ for (i = 0; i < numVars; i++) {
+ err = ncmpi_def_var(ncid, var_name[i], var_type[i], var_rank[i],
+ var_dimid[i], &varid);
+ IF (err != NC_NOERR)
+ error("ncmpi_def_var: %s", ncmpi_strerror(err));
+ ELSE_NOK
+ IF (varid != i)
+ error("Unexpected varid");
+ ELSE_NOK
+ }
+
+ /* try bad dim ids */
+ dimids[0] = BAD_DIMID;
+ err = ncmpi_def_var(ncid, "abc", NC_SHORT, 1, dimids, &varid);
+ IF (err != NC_EBADDIM)
+ error("bad dim ids: status = %d", err);
+ ELSE_NOK
+ err = ncmpi_close(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_close: %s", ncmpi_strerror(err));
+
+ err = ncmpi_delete(scratch, info);
+ IF (err != NC_NOERR)
+ error("remove of %s failed", scratch);
+ return nok;
+}
+
+
+/*
+ * Test ncmpi_put_var1
+ */
+int
+test_ncmpi_put_var1(void)
+{
+ int i, j, err, ncid, nok=0;
+ MPI_Offset index[MAX_RANK];
+ MPI_Datatype buftype;
+ double value;
+ double buf[1]; /* (void *) buffer */
+
+ err = ncmpi_create(comm, scratch, NC_NOCLOBBER|extra_flags, info, &ncid);
+ IF (err != NC_NOERR) {
+ error("ncmpi_create: %s", ncmpi_strerror(err));
+ return nok;
+ }
+ def_dims(ncid);
+ def_vars(ncid);
+ err = ncmpi_enddef(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_enddef: %s", ncmpi_strerror(err));
+
+ /* var1 is only available for indep mode */
+ err = ncmpi_begin_indep_data(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_begin_indep_data: %s", ncmpi_strerror(err));
+
+ for (i = 0; i < numVars; i++) {
+ buftype = nc_mpi_type(var_type[i]);
+ for (j = 0; j < var_rank[i]; j++)
+ index[j] = 0;
+ err = ncmpi_put_var1(BAD_ID, i, index, buf, 1, buftype);
+ IF (err != NC_EBADID)
+ error("bad ncid: status = %d", err);
+ ELSE_NOK
+ err = ncmpi_put_var1(ncid, BAD_VARID, index, buf, 1, buftype);
+ IF (err != NC_ENOTVAR)
+ error("bad var id: status = %d", err);
+ ELSE_NOK
+ for (j = 0; j < var_rank[i]; j++) {
+ if (var_dimid[i][j] > 0) { /* skip record dim */
+ index[j] = var_shape[i][j];
+ err = ncmpi_put_var1(ncid, i, index, buf, 1, buftype);
+ IF (err != NC_EINVALCOORDS)
+ error("bad index: status = %d", err);
+ ELSE_NOK
+ index[j] = 0;
+ }
+ }
+ for (j = 0; j < var_nels[i]; j++) {
+ err = toMixedBase(j, var_rank[i], var_shape[i], index);
+ IF (err != NC_NOERR)
+ error("error in toMixedBase");
+ value = hash(var_type[i], var_rank[i], index);
+ if (inRange(value, var_type[i])) {
+ err = dbl2nc(value, var_type[i], buf);
+ IF (err != NC_NOERR)
+ error("error in dbl2nc");
+ if (var_rank[i] == 0 && i%2 == 0)
+ err = ncmpi_put_var1(ncid, i, NULL, buf, 1, buftype);
+ else
+ err = ncmpi_put_var1(ncid, i, index, buf, 1, buftype);
+ IF (err != NC_NOERR)
+ error("%s", ncmpi_strerror(err));
+ ELSE_NOK
+ }
+ }
+ }
+ err = ncmpi_end_indep_data(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_end_indep_data: %s", ncmpi_strerror(err));
+
+ check_vars(ncid);
+ err = ncmpi_close(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_close: %s", ncmpi_strerror(err));
+
+ err = ncmpi_delete(scratch, info);
+ IF (err != NC_NOERR)
+ error("remove of %s failed", scratch);
+ return nok;
+}
+
+
+/*
+ * Test ncmpi_put_vara
+ * Choose a random point dividing each dim into 2 parts
+ * Put 2^rank (nslabs) slabs so defined
+ * Redefine buffer for each put.
+ * At end check all variables using check_vars
+ */
+int
+test_ncmpi_put_vara(void)
+{
+ int d, i, j, k, err, nels,nslabs, ncid, nok=0;
+ MPI_Offset start[MAX_RANK];
+ MPI_Offset edge[MAX_RANK];
+ MPI_Offset index[MAX_RANK];
+ MPI_Offset mid[MAX_RANK];
+ MPI_Offset bufcount;
+ MPI_Datatype buftype;
+ double buf[MAX_NELS]; /* (void *) buffer */
+ char *p; /* (void *) pointer */
+ double value;
+
+ err = ncmpi_create(comm, scratch, NC_NOCLOBBER|extra_flags, info, &ncid);
+ IF (err != NC_NOERR) {
+ error("ncmpi_create: %s", ncmpi_strerror(err));
+ return nok;
+ }
+ def_dims(ncid);
+ def_vars(ncid);
+ err = ncmpi_enddef(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_enddef: %s", ncmpi_strerror(err));
+
+ for (i = 0; i < numVars; i++) {
+ assert(var_rank[i] <= MAX_RANK);
+ assert(var_nels[i] <= MAX_NELS);
+ for (j = 0; j < var_rank[i]; j++) {
+ start[j] = 0;
+ edge[j] = 1;
+ }
+ buftype = nc_mpi_type(var_type[i]);
+ for (bufcount=1,j=0; j<var_rank[i]; j++) bufcount *= edge[j];
+ err = ncmpi_put_vara_all(BAD_ID, i, start, edge, buf, bufcount, buftype);
+ IF (err != NC_EBADID)
+ error("expecting bad ncid: status = %d", err);
+ ELSE_NOK
+ err = ncmpi_put_vara_all(ncid, BAD_VARID, start, edge, buf, bufcount, buftype);
+ IF (err != NC_ENOTVAR)
+ error("expecting bad var id: status = %d", err);
+ ELSE_NOK
+ for (j = 0; j < var_rank[i]; j++) {
+ if (var_dimid[i][j] > 0) { /* skip record dim */
+ start[j] = var_shape[i][j];
+ for (bufcount=1,k=0; k<var_rank[i]; k++) bufcount *= edge[k];
+ err = ncmpi_put_vara_all(ncid, i, start, edge, buf, bufcount, buftype);
+ IF (err != NC_EINVALCOORDS)
+ error("expecting bad start, but err = %d", err);
+ ELSE_NOK
+ start[j] = 0;
+ edge[j] = var_shape[i][j] + 1;
+ for (bufcount=1,k=0; k<var_rank[i]; k++) bufcount *= edge[k];
+ err = ncmpi_put_vara_all(ncid, i, start, edge, buf, bufcount, buftype);
+ IF (err != NC_EEDGE)
+ error("expecting bad edge, but err = %d", err);
+ ELSE_NOK
+ edge[j] = 1;
+ }
+ }
+ /* Choose a random point dividing each dim into 2 parts */
+ /* put 2^rank (nslabs) slabs so defined */
+ nslabs = 1;
+ for (j = 0; j < var_rank[i]; j++) {
+ mid[j] = roll( var_shape[i][j] );
+ nslabs *= 2;
+ }
+ /* bits of k determine whether to put lower or upper part of dim */
+ for (k = 0; k < nslabs; k++) {
+ nels = 1;
+ for (j = 0; j < var_rank[i]; j++) {
+ if ((k >> j) & 1) {
+ start[j] = 0;
+ edge[j] = mid[j];
+ }else{
+ start[j] = mid[j];
+ edge[j] = var_shape[i][j] - mid[j];
+ }
+ nels *= edge[j];
+ }
+ p = (char *) buf;
+ for (j = 0; j < nels; j++) {
+ err = toMixedBase(j, var_rank[i], edge, index);
+ IF (err != NC_NOERR)
+ error("error in toMixedBase");
+ for (d = 0; d < var_rank[i]; d++)
+ index[d] += start[d];
+ value = hash(var_type[i], var_rank[i], index);
+ if (!inRange(value, var_type[i]))
+ value = 0;
+ err = dbl2nc(value, var_type[i], p);
+ IF (err != NC_NOERR)
+ error("error in dbl2nc");
+ p += nctypelen(var_type[i]);
+ }
+ for (bufcount=1,j=0; j<var_rank[i]; j++) bufcount *= edge[j];
+ if (var_rank[i] == 0 && i%2 == 0)
+ err = ncmpi_put_vara_all(ncid, i, NULL, NULL, buf, bufcount, buftype);
+ else
+ err = ncmpi_put_vara_all(ncid, i, start, edge, buf, bufcount, buftype);
+ IF (err != NC_NOERR)
+ error("%s", ncmpi_strerror(err));
+ ELSE_NOK
+ }
+ }
+
+ check_vars(ncid);
+ err = ncmpi_close(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_close: %s", ncmpi_strerror(err));
+
+ err = ncmpi_delete(scratch, info);
+ IF (err != NC_NOERR)
+ error("remove of %s failed", scratch);
+ return nok;
+}
+
+
+/*
+ * Test ncmpi_put_vars
+ * Choose a random point dividing each dim into 2 parts
+ * Put 2^rank (nslabs) slabs so defined
+ * Choose random stride from 1 to edge
+ * Redefine buffer for each put.
+ * At end check all variables using check_vars
+ */
+int
+test_ncmpi_put_vars(void)
+{
+ int ncid, d, i, j, k, m, err, nels, nslabs, nok=0;
+ int nstarts; /* number of different starts */
+ MPI_Offset start[MAX_RANK];
+ MPI_Offset edge[MAX_RANK];
+ MPI_Offset index[MAX_RANK];
+ MPI_Offset index2[MAX_RANK];
+ MPI_Offset mid[MAX_RANK];
+ MPI_Offset count[MAX_RANK];
+ MPI_Offset sstride[MAX_RANK];
+ MPI_Offset stride[MAX_RANK];
+ MPI_Offset bufcount;
+ MPI_Datatype buftype;
+ double buf[MAX_NELS]; /* (void *) buffer */
+ char *p; /* (void *) pointer */
+ double value;
+
+ err = ncmpi_create(comm, scratch, NC_NOCLOBBER|extra_flags, info, &ncid);
+ IF (err != NC_NOERR) {
+ error("ncmpi_create: %s", ncmpi_strerror(err));
+ return nok;
+ }
+ def_dims(ncid);
+ def_vars(ncid);
+ err = ncmpi_enddef(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_enddef: %s", ncmpi_strerror(err));
+
+ for (i = 0; i < numVars; i++) {
+ assert(var_rank[i] <= MAX_RANK);
+ assert(var_nels[i] <= MAX_NELS);
+ for (j = 0; j < var_rank[i]; j++) {
+ start[j] = 0;
+ edge[j] = 1;
+ stride[j] = 1;
+ }
+ buftype = nc_mpi_type(var_type[i]);
+ for (bufcount=1,j=0; j<var_rank[i]; j++) bufcount *= edge[j];
+ err = ncmpi_put_vars_all(BAD_ID, i, start, edge, stride, buf, bufcount, buftype);
+ IF (err != NC_EBADID)
+ error("bad ncid: status = %d", err);
+ ELSE_NOK
+ err = ncmpi_put_vars_all(ncid, BAD_VARID, start, edge, stride, buf, bufcount, buftype);
+ IF (err != NC_ENOTVAR)
+ error("bad var id: status = %d", err);
+ ELSE_NOK
+ for (j = 0; j < var_rank[i]; j++) {
+ if (var_dimid[i][j] > 0) { /* skip record dim */
+ start[j] = var_shape[i][j];
+ for (bufcount=1,k=0; k<var_rank[i]; k++) bufcount *= edge[k];
+ err = ncmpi_put_vars_all(ncid, i, start, edge, stride, buf, bufcount, buftype);
+ IF (err != NC_EINVALCOORDS)
+ error("bad index: status = %d", err);
+ ELSE_NOK
+ start[j] = 0;
+ edge[j] = var_shape[i][j] + 1;
+ for (bufcount=1,k=0; k<var_rank[i]; k++) bufcount *= edge[k];
+ err = ncmpi_put_vars_all(ncid, i, start, edge, stride, buf, bufcount, buftype);
+ IF (err != NC_EEDGE)
+ error("bad edge: status = %d", err);
+ ELSE_NOK
+ edge[j] = 1;
+ stride[j] = 0;
+ for (bufcount=1,k=0; k<var_rank[i]; k++) bufcount *= edge[k];
+ err = ncmpi_put_vars_all(ncid, i, start, edge, stride, buf, bufcount, buftype);
+ IF (err != NC_ESTRIDE)
+ error("bad stride: status = %d", err);
+ ELSE_NOK
+ stride[j] = 1;
+ }
+ }
+ /* Choose a random point dividing each dim into 2 parts */
+ /* put 2^rank (nslabs) slabs so defined */
+ nslabs = 1;
+ for (j = 0; j < var_rank[i]; j++) {
+ mid[j] = roll( var_shape[i][j] );
+ nslabs *= 2;
+ }
+ /* bits of k determine whether to put lower or upper part of dim */
+ /* choose random stride from 1 to edge */
+ for (k = 0; k < nslabs; k++) {
+ nstarts = 1;
+ for (j = 0; j < var_rank[i]; j++) {
+ if ((k >> j) & 1) {
+ start[j] = 0;
+ edge[j] = mid[j];
+ }else{
+ start[j] = mid[j];
+ edge[j] = var_shape[i][j] - mid[j];
+ }
+ sstride[j] = stride[j] = edge[j] > 0 ? 1+roll(edge[j]) : 1;
+ nstarts *= stride[j];
+ }
+ for (m = 0; m < nstarts; m++) {
+ err = toMixedBase(m, var_rank[i], sstride, index);
+ IF (err != NC_NOERR)
+ error("error in toMixedBase");
+ nels = 1;
+ for (j = 0; j < var_rank[i]; j++) {
+ count[j] = 1 + (edge[j] - index[j] - 1) / stride[j];
+ nels *= count[j];
+ index[j] += start[j];
+ }
+ /* Random choice of forward or backward */
+/* TODO
+ if ( roll(2) ) {
+ for (j = 0; j < var_rank[i]; j++) {
+ index[j] += (count[j] - 1) * stride[j];
+ stride[j] = -stride[j];
+ }
+ }
+ */
+ p = (char *) buf;
+ for (j = 0; j < nels; j++) {
+ err = toMixedBase(j, var_rank[i], count, index2);
+ IF (err != NC_NOERR)
+ error("error in toMixedBase");
+ for (d = 0; d < var_rank[i]; d++)
+ index2[d] = index[d] + index2[d] * stride[d];
+ value = hash(var_type[i], var_rank[i], index2);
+ if (!inRange(value, var_type[i]))
+ value = 0;
+ err = dbl2nc(value, var_type[i], p);
+ IF (err != NC_NOERR)
+ error("error in dbl2nc");
+ p += nctypelen(var_type[i]);
+ }
+ for (bufcount=1,j=0; j<var_rank[i]; j++) bufcount *= count[j];
+ if (var_rank[i] == 0 && i%2 == 0)
+ err = ncmpi_put_vars_all(ncid, i, NULL, NULL, NULL, buf, bufcount, buftype);
+ else
+ err = ncmpi_put_vars_all(ncid, i, index, count, stride, buf, bufcount, buftype);
+ IF (err != NC_NOERR)
+ error("%s", ncmpi_strerror(err));
+ ELSE_NOK
+ }
+ }
+ }
+
+ check_vars(ncid);
+ err = ncmpi_close(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_close: %s", ncmpi_strerror(err));
+
+ err = ncmpi_delete(scratch, info);
+ IF (err != NC_NOERR)
+ error("remove of %s failed", scratch);
+ return nok;
+}
+
+
+/*
+ * Test ncmpi_put_varm
+ * Choose a random point dividing each dim into 2 parts
+ * Put 2^rank (nslabs) slabs so defined
+ * Choose random stride from 1 to edge
+ * Buffer is bit image of whole external variable.
+ * So all puts for a variable put different elements of buffer
+ * At end check all variables using check_vars
+ */
+int
+test_ncmpi_put_varm(void)
+{
+ int ncid, nok=0;
+ int i;
+ int j;
+ int k;
+ int m;
+ int err;
+ int nslabs;
+ int nstarts; /* number of different starts */
+ MPI_Offset start[MAX_RANK];
+ MPI_Offset edge[MAX_RANK];
+ MPI_Offset index[MAX_RANK];
+ MPI_Offset mid[MAX_RANK];
+ MPI_Offset count[MAX_RANK];
+ MPI_Offset sstride[MAX_RANK];
+ MPI_Offset stride[MAX_RANK];
+ MPI_Offset imap[MAX_RANK];
+ MPI_Offset imap2[MAX_RANK];
+ MPI_Offset bufcount;
+ MPI_Datatype buftype;
+ double buf[MAX_NELS]; /* (void *) buffer */
+ char *p; /* (void *) pointer */
+ double value;
+
+ err = ncmpi_create(comm, scratch, NC_NOCLOBBER|extra_flags, info, &ncid);
+ IF (err != NC_NOERR) {
+ error("ncmpi_create: %s", ncmpi_strerror(err));
+ return nok;
+ }
+ def_dims(ncid);
+ def_vars(ncid);
+ err = ncmpi_enddef(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_enddef: %s", ncmpi_strerror(err));
+
+ for (i = 0; i < numVars; i++) {
+ assert(var_rank[i] <= MAX_RANK);
+ assert(var_nels[i] <= MAX_NELS);
+ for (j = 0; j < var_rank[i]; j++) {
+ start[j] = 0;
+ edge[j] = 1;
+ stride[j] = 1;
+ }
+ if (var_rank[i] > 0) {
+ j = var_rank[i] - 1;
+ imap[j] = nctypelen(var_type[i]); /* netCDF considers imap in bytes */
+ imap[j] = 1; /* PnetCDF considers imap in elements */
+ for (; j > 0; j--)
+ imap[j-1] = imap[j] * var_shape[i][j];
+ }
+ p = (char *) buf;
+ for (j = 0; j < var_nels[i]; j++) {
+ err = toMixedBase(j, var_rank[i], var_shape[i], index);
+ IF (err != NC_NOERR)
+ error("error in toMixedBase");
+ value = hash(var_type[i], var_rank[i], index);
+ if (!inRange(value, var_type[i]))
+ value = 0;
+ err = dbl2nc(value, var_type[i], p);
+ IF (err != NC_NOERR)
+ error("error in dbl2nc");
+ p += nctypelen(var_type[i]);
+ }
+ buftype = nc_mpi_type(var_type[i]);
+ for (bufcount=1,j=0; j<var_rank[i]; j++) bufcount *= edge[j];
+ err = ncmpi_put_varm_all(BAD_ID, i, start, edge, stride, imap, buf, bufcount, buftype);
+ IF (err != NC_EBADID)
+ error("bad ncid: status = %d", err);
+ ELSE_NOK
+ err = ncmpi_put_varm_all(ncid, BAD_VARID, start, edge, stride, imap, buf, bufcount, buftype);
+ IF (err != NC_ENOTVAR)
+ error("bad var id: status = %d", err);
+ ELSE_NOK
+ for (j = 0; j < var_rank[i]; j++) {
+ if (var_dimid[i][j] > 0) { /* skip record dim */
+ start[j] = var_shape[i][j];
+ for (bufcount=1,k=0; k<var_rank[i]; k++) bufcount *= edge[k];
+ err = ncmpi_put_varm_all(ncid, i, start, edge, stride, imap, buf, bufcount, buftype);
+ IF (err != NC_EINVALCOORDS)
+ error("bad index: status = %d", err);
+ ELSE_NOK
+ start[j] = 0;
+ edge[j] = var_shape[i][j] + 1;
+ for (bufcount=1,k=0; k<var_rank[i]; k++) bufcount *= edge[k];
+ err = ncmpi_put_varm_all(ncid, i, start, edge, stride, imap, buf, bufcount, buftype);
+ IF (err != NC_EEDGE)
+ error("bad edge: status = %d", err);
+ ELSE_NOK
+ edge[j] = 1;
+ stride[j] = 0;
+ for (bufcount=1,k=0; k<var_rank[i]; k++) bufcount *= edge[k];
+ err = ncmpi_put_varm_all(ncid, i, start, edge, stride, imap, buf, bufcount, buftype);
+ IF (err != NC_ESTRIDE)
+ error("bad stride: status = %d", err);
+ ELSE_NOK
+ stride[j] = 1;
+ }
+ }
+ /* Choose a random point dividing each dim into 2 parts */
+ /* put 2^rank (nslabs) slabs so defined */
+ nslabs = 1;
+ for (j = 0; j < var_rank[i]; j++) {
+ mid[j] = roll( var_shape[i][j] );
+ nslabs *= 2;
+ }
+ /* bits of k determine whether to put lower or upper part of dim */
+ /* choose random stride from 1 to edge */
+ for (k = 0; k < nslabs; k++) {
+ nstarts = 1;
+ for (j = 0; j < var_rank[i]; j++) {
+ if ((k >> j) & 1) {
+ start[j] = 0;
+ edge[j] = mid[j];
+ }else{
+ start[j] = mid[j];
+ edge[j] = var_shape[i][j] - mid[j];
+ }
+ sstride[j] = stride[j] = edge[j] > 0 ? 1+roll(edge[j]) : 1;
+ imap2[j] = imap[j] * sstride[j];
+ nstarts *= stride[j];
+ }
+ for (m = 0; m < nstarts; m++) {
+ if (var_rank[i] == 0 && i%2 == 0) {
+ err = ncmpi_put_varm_all(ncid, i, NULL, NULL, NULL, NULL, buf, 1, buftype);
+ } else {
+ err = toMixedBase(m, var_rank[i], sstride, index);
+ IF (err != NC_NOERR)
+ error("error in toMixedBase");
+ for (j = 0; j < var_rank[i]; j++) {
+ count[j] = 1 + (edge[j] - index[j] - 1) / stride[j];
+ index[j] += start[j];
+ }
+ /* Random choice of forward or backward */
+/* TODO
+ if ( roll(2) ) {
+ for (j = 0; j < var_rank[i]; j++) {
+ index[j] += (count[j] - 1) * stride[j];
+ stride[j] = -stride[j];
+ }
+ }
+ */
+ j = fromMixedBase(var_rank[i], index, var_shape[i]);
+ p = (char *) buf + j * nctypelen(var_type[i]);
+ for (bufcount=1,j=0; j<var_rank[i]; j++) bufcount *= count[j];
+ err = ncmpi_put_varm_all(ncid, i, index, count, stride, imap2, p, bufcount, buftype);
+ }
+ IF (err != NC_NOERR)
+ error("i=%d var_rank[i]=%d %s", i,var_rank[i],ncmpi_strerror(err));
+ ELSE_NOK
+ }
+ }
+ }
+
+ check_vars(ncid);
+ err = ncmpi_close(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_close: %s", ncmpi_strerror(err));
+
+ err = ncmpi_delete(scratch, info);
+ IF (err != NC_NOERR)
+ error("remove of %s failed", scratch);
+ return nok;
+}
+
+
+/*
+ * Test ncmpi_rename_var
+ * try with bad netCDF handle, check error
+ * try with bad variable handle, check error
+ * try renaming to existing variable name, check error
+ * check that proper rename worked with ncmpi_inq_varid
+ * try in data mode, check error
+ */
+int
+test_ncmpi_rename_var(void)
+{
+ int ncid;
+ int varid;
+ int err, nok=0;
+ int i;
+ char name[NC_MAX_NAME];
+
+ err = ncmpi_create(comm, scratch, NC_NOCLOBBER|extra_flags, info, &ncid);
+ IF (err != NC_NOERR) {
+ error("ncmpi_create: %s", ncmpi_strerror(err));
+ return nok;
+ }
+ err = ncmpi_rename_var(ncid, BAD_VARID, "newName");
+ IF (err != NC_ENOTVAR)
+ error("bad var id: status = %d", err);
+ ELSE_NOK
+ def_dims(ncid);
+ def_vars(ncid);
+
+ /* Prefix "new_" to each name */
+ for (i = 0; i < numVars; i++) {
+ err = ncmpi_rename_var(BAD_ID, i, "newName");
+ IF (err != NC_EBADID)
+ error("bad ncid: status = %d", err);
+ ELSE_NOK
+ err = ncmpi_rename_var(ncid, i, var_name[numVars-1]);
+ IF (err != NC_ENAMEINUSE)
+ error("duplicate name: status = %d", err);
+ ELSE_NOK
+ strcpy(name, "new_");
+ strcat(name, var_name[i]);
+ err = ncmpi_rename_var(ncid, i, name);
+ IF (err != NC_NOERR)
+ error("ncmpi_rename_var: %s", ncmpi_strerror(err));
+ ELSE_NOK
+ err = ncmpi_inq_varid(ncid, name, &varid);
+ IF (err != NC_NOERR)
+ error("ncmpi_inq_varid: %s", ncmpi_strerror(err));
+ IF (varid != i)
+ error("Unexpected varid");
+ }
+
+ /* Change to data mode */
+ /* Try making names even longer. Then restore original names */
+ err = ncmpi_enddef(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_enddef: %s", ncmpi_strerror(err));
+ for (i = 0; i < numVars; i++) {
+ strcpy(name, "even_longer_");
+ strcat(name, var_name[i]);
+ err = ncmpi_rename_var(ncid, i, name);
+ IF (err != NC_ENOTINDEFINE)
+ error("longer name in data mode: status = %d", err);
+ ELSE_NOK
+ err = ncmpi_rename_var(ncid, i, var_name[i]);
+ IF (err != NC_NOERR)
+ error("ncmpi_rename_var: %s", ncmpi_strerror(err));
+ ELSE_NOK
+ err = ncmpi_inq_varid(ncid, var_name[i], &varid);
+ IF (err != NC_NOERR)
+ error("ncmpi_inq_varid: %s", ncmpi_strerror(err));
+ IF (varid != i)
+ error("Unexpected varid");
+ }
+
+ put_vars(ncid);
+ check_vars(ncid);
+
+ err = ncmpi_close(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_close: %s", ncmpi_strerror(err));
+
+ err = ncmpi_delete(scratch, info);
+ IF (err != NC_NOERR)
+ error("remove of %s failed", scratch);
+ return nok;
+}
+
+
+int
+test_ncmpi_put_att(void)
+{
+ int ncid, nok=0;
+ int varid;
+ int i;
+ int j;
+ MPI_Offset k;
+ int err;
+ double buf[MAX_NELS]; /* (void *) buffer */
+ char *p; /* (void *) pointer */
+ char *name; /* of att */
+ nc_type datatype; /* of att */
+ MPI_Offset length; /* of att */
+ double value;
+
+ err = ncmpi_create(comm, scratch, NC_NOCLOBBER|extra_flags, info, &ncid);
+ IF (err != NC_NOERR) {
+ error("ncmpi_create: %s", ncmpi_strerror(err));
+ return nok;
+ }
+ def_dims(ncid);
+ def_vars(ncid);
+
+ for (i = -1; i < numVars; i++) {
+ varid = VARID(i);
+ for (j = 0; j < NATTS(i); j++) {
+ name = ATT_NAME(i,j);
+ datatype = ATT_TYPE(i,j);
+ length = ATT_LEN(i,j);
+ err = ncmpi_put_att(BAD_ID, varid, name, datatype, length, buf);
+ IF (err != NC_EBADID)
+ error("bad ncid: status = %d", err);
+ ELSE_NOK
+ err = ncmpi_put_att(ncid, varid, BAD_NAME, datatype, length, buf);
+ IF (err != NC_EBADNAME)
+ error("bad name: status = %d", err);
+ ELSE_NOK
+ err = ncmpi_put_att(ncid, BAD_VARID, name, datatype, length, buf);
+ IF (err != NC_ENOTVAR)
+ error("bad var id: status = %d", err);
+ ELSE_NOK
+ err = ncmpi_put_att(ncid, varid, name, BAD_TYPE, length, buf);
+ IF (err != NC_EBADTYPE)
+ error("bad type: status = %d", err);
+ ELSE_NOK
+ p = (char *) buf;
+ for (k=0; k<length; k++) {
+ value = hash(datatype, -1, &k);
+ if (!inRange(value, datatype))
+ value = 0;
+ err = dbl2nc(value, datatype, p);
+ IF (err != NC_NOERR)
+ error("error in dbl2nc");
+ p += nctypelen(datatype);
+ }
+ err = ncmpi_put_att(ncid, varid, name, datatype, length, buf);
+ IF (err != NC_NOERR)
+ error("%s", ncmpi_strerror(err));
+ ELSE_NOK
+ }
+ }
+
+ check_atts(ncid);
+ err = ncmpi_close(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_close: %s", ncmpi_strerror(err));
+
+ err = ncmpi_delete(scratch, info);
+ IF (err != NC_NOERR)
+ error("remove of %s failed", scratch);
+ return nok;
+}
+
+
+/*
+ * Test ncmpi_copy_att
+ * try with bad source or target netCDF handles, check error
+ * try with bad source or target variable handle, check error
+ * try with nonexisting attribute, check error
+ * check that NC_GLOBAL variable for source or target works
+ * check that new attribute put works with target in define mode
+ * check that old attribute put works with target in data mode
+ * check that changing type and length of an attribute work OK
+ * try with same ncid for source and target, different variables
+ * try with same ncid for source and target, same variable
+ */
+int
+test_ncmpi_copy_att(void)
+{
+ int ncid_in;
+ int ncid_out;
+ int varid;
+ int err, nok=0;
+ int i;
+ int j=0;
+ char *name; /* of att */
+ nc_type datatype; /* of att */
+ MPI_Offset length; /* of att */
+ char value;
+
+ err = ncmpi_open(comm, testfile, NC_NOWRITE, info, &ncid_in);
+ IF (err != NC_NOERR)
+ error("ncmpi_open: %s", ncmpi_strerror(err));
+ err = ncmpi_create(comm, scratch, NC_NOCLOBBER|extra_flags, info, &ncid_out);
+ IF (err != NC_NOERR) {
+ error("ncmpi_create: %s", ncmpi_strerror(err));
+ return nok;
+ }
+ def_dims(ncid_out);
+ def_vars(ncid_out);
+
+ for (i = -1; i < numVars; i++) {
+ varid = VARID(i);
+ for (j = 0; j < NATTS(i); j++) {
+ name = ATT_NAME(i,j);
+ err = ncmpi_copy_att(ncid_in, BAD_VARID, name, ncid_out, varid);
+ IF (err != NC_ENOTVAR)
+ error("bad var id: status = %d", err);
+ ELSE_NOK
+ err = ncmpi_copy_att(ncid_in, varid, name, ncid_out, BAD_VARID);
+ IF (err != NC_ENOTVAR)
+ error("bad var id: status = %d", err);
+ ELSE_NOK
+ err = ncmpi_copy_att(BAD_ID, varid, name, ncid_out, varid);
+ IF (err != NC_EBADID)
+ error("bad ncid: status = %d", err);
+ ELSE_NOK
+ err = ncmpi_copy_att(ncid_in, varid, name, BAD_ID, varid);
+ IF (err != NC_EBADID)
+ error("bad ncid: status = %d", err);
+ ELSE_NOK
+ err = ncmpi_copy_att(ncid_in, varid, "noSuch", ncid_out, varid);
+ IF (err != NC_ENOTATT)
+ error("bad attname: status = %d", err);
+ ELSE_NOK
+ err = ncmpi_copy_att(ncid_in, varid, name, ncid_out, varid);
+ IF (err != NC_NOERR)
+ error("ncmpi_copy_att: %s", ncmpi_strerror(err));
+ ELSE_NOK
+ err = ncmpi_copy_att(ncid_out, varid, name, ncid_out, varid);
+ IF (err != NC_NOERR)
+ error("source = target: %s", ncmpi_strerror(err));
+ ELSE_NOK
+ }
+ }
+
+ err = ncmpi_close(ncid_in);
+ IF (err != NC_NOERR)
+ error("ncmpi_close: %s", ncmpi_strerror(err));
+
+ /* Close scratch. Reopen & check attributes */
+ err = ncmpi_close(ncid_out);
+ IF (err != NC_NOERR)
+ error("ncmpi_close: %s", ncmpi_strerror(err));
+ err = ncmpi_open(comm, scratch, NC_WRITE, info, &ncid_out);
+ IF (err != NC_NOERR)
+ error("ncmpi_open: %s", ncmpi_strerror(err));
+ check_atts(ncid_out);
+
+ /*
+ * change to define mode
+ * define single char. global att. ':a' with value 'A'
+ * This will be used as source for following copies
+ */
+ err = ncmpi_redef(ncid_out);
+ IF (err != NC_NOERR)
+ error("ncmpi_redef: %s", ncmpi_strerror(err));
+ err = ncmpi_put_att_text(ncid_out, NC_GLOBAL, "a", 1, "A");
+ IF (err != NC_NOERR)
+ error("ncmpi_put_att_text: %s", ncmpi_strerror(err));
+
+ /*
+ * change to data mode
+ * Use scratch as both source & dest.
+ * try copy to existing att. change type & decrease length
+ * rename 1st existing att of each var (if any) 'a'
+ * if this att. exists them copy ':a' to it
+ */
+ err = ncmpi_enddef(ncid_out);
+ IF (err != NC_NOERR)
+ error("ncmpi_enddef: %s", ncmpi_strerror(err));
+ for (i = 0; i < numVars; i++) {
+ if (NATTS(i) > 0 && ATT_LEN(i,j) > 0) {
+ err = ncmpi_rename_att(ncid_out, i, att_name[i][0], "a");
+ IF (err != NC_NOERR)
+ error("ncmpi_rename_att: %s", ncmpi_strerror(err));
+ err = ncmpi_copy_att(ncid_out, NC_GLOBAL, "a", ncid_out, i);
+ IF (err != NC_NOERR)
+ error("ncmpi_copy_att: %s", ncmpi_strerror(err));
+ ELSE_NOK
+ }
+ }
+ err = ncmpi_close(ncid_out);
+ IF (err != NC_NOERR)
+ error("ncmpi_close: %s", ncmpi_strerror(err));
+
+ /* Reopen & check */
+ err = ncmpi_open(comm, scratch, NC_WRITE, info, &ncid_out);
+ IF (err != NC_NOERR)
+ error("ncmpi_open: %s", ncmpi_strerror(err));
+ for (i = 0; i < numVars; i++) {
+ if (NATTS(i) > 0 && ATT_LEN(i,j) > 0) {
+ err = ncmpi_inq_att(ncid_out, i, "a", &datatype, &length);
+ IF (err != NC_NOERR)
+ error("ncmpi_inq_att: %s", ncmpi_strerror(err));
+ IF (datatype != NC_CHAR)
+ error("Unexpected type");
+ IF (length != 1)
+ error("Unexpected length");
+ err = ncmpi_get_att_text(ncid_out, i, "a", &value);
+ IF (err != NC_NOERR)
+ error("ncmpi_get_att_text: %s", ncmpi_strerror(err));
+ IF (value != 'A')
+ error("Unexpected value");
+ }
+ }
+
+ err = ncmpi_close(ncid_out);
+ IF (err != NC_NOERR)
+ error("ncmpi_close: %s", ncmpi_strerror(err));
+ err = ncmpi_delete(scratch, info);
+ IF (err != NC_NOERR)
+ error("remove of %s failed", scratch);
+ return nok;
+}
+
+
+/*
+ * Test ncmpi_rename_att
+ * try with bad netCDF handle, check error
+ * try with bad variable handle, check error
+ * try with nonexisting att name, check error
+ * try renaming to existing att name, check error
+ * check that proper rename worked with ncmpi_inq_attid
+ * try in data mode, check error
+ */
+int
+test_ncmpi_rename_att(void)
+{
+ int ncid;
+ int varid;
+ int err;
+ int i;
+ int j;
+ MPI_Offset k;
+ int attnum;
+ char *attname;
+ char name[NC_MAX_NAME];
+ char oldname[NC_MAX_NAME];
+ char newname[NC_MAX_NAME];
+ int nok = 0; /* count of valid comparisons */
+ nc_type datatype;
+ nc_type atttype;
+ MPI_Offset length;
+ size_t attlength;
+ char text[MAX_NELS];
+ double value[MAX_NELS];
+ double expect;
+
+ err = ncmpi_create(comm, scratch, NC_NOCLOBBER|extra_flags, info, &ncid);
+ IF (err != NC_NOERR) {
+ error("ncmpi_create: %s", ncmpi_strerror(err));
+ return nok;
+ }
+ err = ncmpi_rename_att(ncid, BAD_VARID, "abc", "newName");
+ IF (err != NC_ENOTVAR)
+ error("bad var id: status = %d", err);
+ ELSE_NOK
+ def_dims(ncid);
+ def_vars(ncid);
+ put_atts(ncid);
+
+ for (i = -1; i < numVars; i++) {
+ varid = VARID(i);
+ for (j = 0; j < NATTS(i); j++) {
+ attname = ATT_NAME(i,j);
+ err = ncmpi_rename_att(BAD_ID, varid, attname, "newName");
+ IF (err != NC_EBADID)
+ error("bad ncid: status = %d", err);
+ ELSE_NOK
+ err = ncmpi_rename_att(ncid, varid, "noSuch", "newName");
+ IF (err != NC_ENOTATT)
+ error("bad attname: status = %d", err);
+ ELSE_NOK
+ strcpy(newname, "new_");
+ strcat(newname, attname);
+ err = ncmpi_rename_att(ncid, varid, attname, newname);
+ IF (err != NC_NOERR)
+ error("ncmpi_rename_att: %s", ncmpi_strerror(err));
+ ELSE_NOK
+ err = ncmpi_inq_attid(ncid, varid, newname, &attnum);
+ IF (err != NC_NOERR)
+ error("ncmpi_inq_attid: %s", ncmpi_strerror(err));
+ IF (attnum != j)
+ error("Unexpected attnum");
+ }
+ }
+
+ /* Close. Reopen & check */
+ err = ncmpi_close(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_close: %s", ncmpi_strerror(err));
+ err = ncmpi_open(comm, scratch, NC_WRITE, info, &ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_open: %s", ncmpi_strerror(err));
+
+ for (i = -1; i < numVars; i++) {
+ varid = VARID(i);
+ for (j = 0; j < NATTS(i); j++) {
+ attname = ATT_NAME(i,j);
+ atttype = ATT_TYPE(i,j);
+ attlength = ATT_LEN(i,j);
+ strcpy(newname, "new_");
+ strcat(newname, attname);
+ err = ncmpi_inq_attname(ncid, varid, j, name);
+ IF (err != NC_NOERR)
+ error("ncmpi_inq_attname: %s", ncmpi_strerror(err));
+ IF (strcmp(name, newname) != 0)
+ error("ncmpi_inq_attname: unexpected name");
+ err = ncmpi_inq_att(ncid, varid, name, &datatype, &length);
+ IF (err != NC_NOERR)
+ error("ncmpi_inq_att: %s", ncmpi_strerror(err));
+ IF (datatype != atttype)
+ error("ncmpi_inq_att: unexpected type");
+ IF (length != attlength)
+ error("ncmpi_inq_att: unexpected length");
+ if (datatype == NC_CHAR) {
+ err = ncmpi_get_att_text(ncid, varid, name, text);
+ IF (err != NC_NOERR)
+ error("ncmpi_get_att_text: %s", ncmpi_strerror(err));
+ for (k = 0; k < attlength; k++) {
+ expect = hash(datatype, -1, &k);
+ IF (text[k] != (char)expect)
+ error("ncmpi_get_att_text: unexpected value");
+ }
+ } else {
+ err = ncmpi_get_att_double(ncid, varid, name, value);
+ IF (err != NC_NOERR)
+ error("ncmpi_get_att_double: %s", ncmpi_strerror(err));
+ for (k = 0; k < attlength; k++) {
+ expect = hash(datatype, -1, &k);
+ if (inRange(expect, datatype)) {
+ IF (!equal(value[k],expect,datatype,NCT_DOUBLE))
+ error("ncmpi_get_att_double: unexpected value");
+ }
+ }
+ }
+ }
+ }
+
+ /* Now in data mode */
+ /* Try making names even longer. Then restore original names */
+
+ for (i = -1; i < numVars; i++) {
+ varid = VARID(i);
+ for (j = 0; j < NATTS(i); j++) {
+ attname = ATT_NAME(i,j);
+ strcpy(oldname, "new_");
+ strcat(oldname, attname);
+ strcpy(newname, "even_longer_");
+ strcat(newname, attname);
+ err = ncmpi_rename_att(ncid, varid, oldname, newname);
+ IF (err != NC_ENOTINDEFINE)
+ error("longer name in data mode: status = %d", err);
+ ELSE_NOK
+ err = ncmpi_rename_att(ncid, varid, oldname, attname);
+ IF (err != NC_NOERR)
+ error("ncmpi_rename_att: %s", ncmpi_strerror(err));
+ ELSE_NOK
+ err = ncmpi_inq_attid(ncid, varid, attname, &attnum);
+ IF (err != NC_NOERR)
+ error("ncmpi_inq_attid: %s", ncmpi_strerror(err));
+ IF (attnum != j)
+ error("Unexpected attnum");
+ }
+ }
+
+ err = ncmpi_close(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_close: %s", ncmpi_strerror(err));
+
+ err = ncmpi_delete(scratch, info);
+ IF (err != NC_NOERR)
+ error("remove of %s failed", scratch);
+ return nok;
+}
+
+
+/*
+ * Test ncmpi_del_att
+ * try with bad netCDF handle, check error
+ * try with bad variable handle, check error
+ * try with nonexisting att name, check error
+ * check that proper delete worked using:
+ * ncmpi_inq_attid, ncmpi_inq_natts, ncmpi_inq_varnatts
+ */
+int
+test_ncmpi_del_att(void)
+{
+ int ncid;
+ int err, nok=0;
+ int i;
+ int j;
+ int attnum;
+ int natts;
+ int numatts;
+ int varid;
+ char *name; /* of att */
+
+ err = ncmpi_create(comm, scratch, NC_NOCLOBBER|extra_flags, info, &ncid);
+ IF (err != NC_NOERR) {
+ error("ncmpi_create: %s", ncmpi_strerror(err));
+ return nok;
+ }
+ err = ncmpi_del_att(ncid, BAD_VARID, "abc");
+ IF (err != NC_ENOTVAR)
+ error("bad var id: status = %d", err);
+ ELSE_NOK
+ def_dims(ncid);
+ def_vars(ncid);
+ put_atts(ncid);
+
+ for (i = -1; i < numVars; i++) {
+ varid = VARID(i);
+ numatts = NATTS(i);
+ for (j = 0; j < numatts; j++) {
+ name = ATT_NAME(i,j);
+ err = ncmpi_del_att(BAD_ID, varid, name);
+ IF (err != NC_EBADID)
+ error("bad ncid: status = %d", err);
+ ELSE_NOK
+ err = ncmpi_del_att(ncid, varid, "noSuch");
+ IF (err != NC_ENOTATT)
+ error("bad attname: status = %d", err);
+ ELSE_NOK
+ err = ncmpi_del_att(ncid, varid, name);
+ IF (err != NC_NOERR)
+ error("ncmpi_del_att: %s", ncmpi_strerror(err));
+ ELSE_NOK
+ err = ncmpi_inq_attid(ncid, varid, name, &attnum);
+ IF (err != NC_ENOTATT)
+ error("bad attname: status = %d", err);
+ if (i < 0) {
+ err = ncmpi_inq_natts(ncid, &natts);
+ IF (err != NC_NOERR)
+ error("ncmpi_inq_natts: %s", ncmpi_strerror(err));
+ IF (natts != numatts-j-1)
+ error("natts: expected %d, got %d", numatts-j-1, natts);
+ }
+ err = ncmpi_inq_varnatts(ncid, varid, &natts);
+ IF (err != NC_NOERR)
+ error("ncmpi_inq_natts: %s", ncmpi_strerror(err));
+ IF (natts != numatts-j-1)
+ error("natts: expected %d, got %d", numatts-j-1, natts);
+ }
+ }
+
+ /* Close. Reopen & check no attributes left */
+ err = ncmpi_close(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_close: %s", ncmpi_strerror(err));
+ err = ncmpi_open(comm, scratch, NC_WRITE, info, &ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_open: %s", ncmpi_strerror(err));
+ err = ncmpi_inq_natts(ncid, &natts);
+ IF (err != NC_NOERR)
+ error("ncmpi_inq_natts: %s", ncmpi_strerror(err));
+ IF (natts != 0)
+ error("natts: expected %d, got %d", 0, natts);
+ for (i = -1; i < numVars; i++) {
+ varid = VARID(i);
+ err = ncmpi_inq_varnatts(ncid, varid, &natts);
+ IF (err != NC_NOERR)
+ error("ncmpi_inq_natts: %s", ncmpi_strerror(err));
+ IF (natts != 0)
+ error("natts: expected %d, got %d", 0, natts);
+ }
+
+ /* restore attributes. change to data mode. try to delete */
+ err = ncmpi_redef(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_redef: %s", ncmpi_strerror(err));
+ put_atts(ncid);
+ err = ncmpi_enddef(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_enddef: %s", ncmpi_strerror(err));
+
+ for (i = -1; i < numVars; i++) {
+ varid = VARID(i);
+ numatts = NATTS(i);
+ for (j = 0; j < numatts; j++) {
+ name = ATT_NAME(i,j);
+ err = ncmpi_del_att(ncid, varid, name);
+ IF (err != NC_ENOTINDEFINE)
+ error("in data mode: status = %d", err);
+ ELSE_NOK
+ }
+ }
+
+ err = ncmpi_close(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_close: %s", ncmpi_strerror(err));
+ err = ncmpi_delete(scratch, info);
+ IF (err != NC_NOERR)
+ error("remove of %s failed", scratch);
+ return nok;
+}
+
+
+/*
+ * Test ncmpi_set_fill
+ * try with bad netCDF handle, check error
+ * try in read-only mode, check error
+ * try with bad new_fillmode, check error
+ * try in data mode, check error
+ * check that proper set to NC_FILL works for record & non-record variables
+ * (note that it is not possible to test NC_NOFILL mode!)
+ * close file & create again for test using attribute _FillValue
+ */
+int
+test_ncmpi_set_fill(void)
+{
+ int ncid;
+ int varid;
+ int err;
+ int i;
+ int j;
+ int old_fillmode;
+ int nok = 0; /* count of valid comparisons */
+ char text = 0;
+ double value = 0;
+ double fill;
+ MPI_Offset index[MAX_RANK];
+
+ /* bad ncid */
+ err = ncmpi_set_fill(BAD_ID, NC_NOFILL, &old_fillmode);
+ IF (err != NC_EBADID)
+ error("bad ncid: status = %d", err);
+
+ /* try in read-only mode */
+ err = ncmpi_open(comm, testfile, NC_NOWRITE, info, &ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_open: %s", ncmpi_strerror(err));
+ err = ncmpi_set_fill(ncid, NC_NOFILL, &old_fillmode);
+ IF (err != NC_EPERM)
+ error("read-only: status = %d", err);
+ err = ncmpi_close(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_close: %s", ncmpi_strerror(err));
+
+ /* create scratch */
+ err = ncmpi_create(comm, scratch, NC_NOCLOBBER|extra_flags, info, &ncid);
+ IF (err != NC_NOERR) {
+ error("ncmpi_create: %s", ncmpi_strerror(err));
+ return nok;
+ }
+
+ /* BAD_FILLMODE */
+ err = ncmpi_set_fill(ncid, BAD_FILLMODE, &old_fillmode);
+ IF (err != NC_EINVAL)
+ error("bad fillmode: status = %d", err);
+
+ /* proper calls */
+ err = ncmpi_set_fill(ncid, NC_NOFILL, &old_fillmode);
+ IF (err != NC_NOERR)
+ error("ncmpi_set_fill: %s", ncmpi_strerror(err));
+ IF (old_fillmode != NC_NOFILL)
+ error("Unexpected old fill mode: %d", old_fillmode);
+ err = ncmpi_set_fill(ncid, NC_FILL, &old_fillmode);
+ IF (err != NC_NOERR)
+ error("ncmpi_set_fill: %s", ncmpi_strerror(err));
+ IF (old_fillmode != NC_NOFILL)
+ error("Unexpected old fill mode: %d", old_fillmode);
+
+ /* define dims & vars */
+ def_dims(ncid);
+ def_vars(ncid);
+
+ /* Change to data mode. Set fillmode again */
+ err = ncmpi_enddef(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_enddef: %s", ncmpi_strerror(err));
+ err = ncmpi_set_fill(ncid, NC_FILL, &old_fillmode);
+ IF (err != NC_ENOTINDEFINE)
+ error("ncmpi_set_fill: %s", ncmpi_strerror(err));
+
+ /* Write record number NRECS to force writing of preceding records */
+ /* Assumes variable cr is char vector with UNLIMITED dimension */
+ err = ncmpi_inq_varid(ncid, "cr", &varid);
+ IF (err != NC_NOERR)
+ error("ncmpi_inq_varid: %s", ncmpi_strerror(err));
+ index[0] = NRECS;
+ for (i=0; i<=index[0]; i++)
+ err = ncmpi_fill_var_rec(ncid, varid, i);
+ err = ncmpi_put_var1_text_all(ncid, varid, index, &text);
+ IF (err != NC_NOERR)
+ error("ncmpi_put_var1_text_all: %s", ncmpi_strerror(err));
+
+ /* get all variables & check all values equal default fill */
+ for (i = 0; i < numVars; i++) {
+ if (var_dimid[i][0] == RECDIM) continue; /* skip record variables */
+ switch (var_type[i]) {
+ case NC_CHAR: fill = NC_FILL_CHAR; break;
+ case NC_BYTE: fill = NC_FILL_BYTE; break;
+ case NC_SHORT: fill = NC_FILL_SHORT; break;
+ case NC_INT: fill = NC_FILL_INT; break;
+ case NC_FLOAT: fill = NC_FILL_FLOAT; break;
+ case NC_DOUBLE: fill = NC_FILL_DOUBLE; break;
+ case NC_UBYTE: fill = NC_FILL_UBYTE; break;
+ case NC_USHORT: fill = NC_FILL_USHORT; break;
+ case NC_UINT: fill = NC_FILL_UINT; break;
+ case NC_INT64: fill = NC_FILL_INT64; break;
+ case NC_UINT64: fill = NC_FILL_UINT64; break;
+ default: assert(0);
+ }
+ for (j = 0; j < var_nels[i]; j++) {
+ err = toMixedBase(j, var_rank[i], var_shape[i], index);
+ IF (err != NC_NOERR)
+ error("error in toMixedBase");
+ if (var_type[i] == NC_CHAR) {
+ err = ncmpi_get_var1_text_all(ncid, i, index, &text);
+ IF (err != NC_NOERR)
+ error("ncmpi_get_var1_text_all failed: %s", ncmpi_strerror(err));
+ value = text;
+ } else {
+ err = ncmpi_get_var1_double_all(ncid, i, index, &value);
+ IF (err != NC_NOERR)
+ error("ncmpi_get_var1_double_all failed: %s", ncmpi_strerror(err));
+ }
+ IF (value != fill && fabs((fill - value)/fill) > DBL_EPSILON)
+ error("\n\t\t%s Value expected: %-23.17e,\n\t\t read: %-23.17e\n",
+ var_name[i],fill, value);
+ ELSE_NOK
+ }
+ }
+
+ /* close scratch & create again for test using attribute _FillValue */
+ err = ncmpi_close(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_close: %s", ncmpi_strerror(err));
+ err = ncmpi_create(comm, scratch, NC_CLOBBER|extra_flags, info, &ncid);
+ IF (err != NC_NOERR) {
+ error("ncmpi_create: %s", ncmpi_strerror(err));
+ return nok;
+ }
+ def_dims(ncid);
+ def_vars(ncid);
+
+ /* set _FillValue = 42 for all vars */
+ text = fill = 42;
+ for (i = 0; i < numVars; i++) {
+ if (var_type[i] == NC_CHAR) {
+ err = ncmpi_put_att_text(ncid, i, "_FillValue", 1, &text);
+ IF (err != NC_NOERR)
+ error("ncmpi_put_att_text: %s", ncmpi_strerror(err));
+ } else {
+ err = ncmpi_put_att_double(ncid, i, "_FillValue",var_type[i],1,&fill);
+ IF (err != NC_NOERR)
+ error("ncmpi_put_att_double: %s", ncmpi_strerror(err));
+ }
+ }
+
+ /* data mode. write records */
+ err = ncmpi_enddef(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_enddef: %s", ncmpi_strerror(err));
+ index[0] = NRECS;
+ for (i=0; i<=index[0]; i++)
+ err = ncmpi_fill_var_rec(ncid, varid, i);
+ err = ncmpi_put_var1_text_all(ncid, varid, index, &text);
+ IF (err != NC_NOERR)
+ error("ncmpi_put_var1_text_all: %s", ncmpi_strerror(err));
+
+ /* get all variables & check all values equal 42 */
+ for (i = 0; i < numVars; i++) {
+ if (var_dimid[i][0] == RECDIM) continue; /* skip record variables */
+ for (j = 0; j < var_nels[i]; j++) {
+ err = toMixedBase(j, var_rank[i], var_shape[i], index);
+ IF (err != NC_NOERR)
+ error("error in toMixedBase");
+ if (var_type[i] == NC_CHAR) {
+ err = ncmpi_get_var1_text_all(ncid, i, index, &text);
+ IF (err != NC_NOERR)
+ error("ncmpi_get_var1_text_all failed: %s", ncmpi_strerror(err));
+ value = text;
+ } else {
+ err = ncmpi_get_var1_double_all(ncid, i, index, &value);
+ IF (err != NC_NOERR)
+ error("ncmpi_get_var1_double_all failed: %s", ncmpi_strerror(err));
+ }
+ IF (value != fill)
+ error(" %s Value expected: %g, read: %g\n", var_name[i],fill, value);
+ ELSE_NOK
+ }
+ }
+ err = ncmpi_close(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_close: %s", ncmpi_strerror(err));
+ err = ncmpi_delete(scratch, info);
+ IF (err != NC_NOERR)
+ error("remove of %s failed", scratch);
+
+ return nok;
+}
+
+
+/* This function gets the version of a netCDF file, 1 is for netCDF
+ classic, 2 for 64-bit offset format, (someday) 3 for HDF5 format.
+*/
+#define MAGIC_NUM_LEN 4
+static
+int ncmpi_get_file_version(char *path, int *version)
+{
+ FILE *fp;
+ char magic[MAGIC_NUM_LEN];
+
+ /* Need two valid pointers - check for NULL. */
+ if (!version || !path)
+ return NC_EINVAL;
+
+ /* Figure out if this is a netcdf or hdf5 file. */
+ if (!(fp = fopen(path, "r")) ||
+ fread(magic, MAGIC_NUM_LEN, 1, fp) != 1)
+ return errno;
+ fclose(fp);
+ if (strncmp(magic, "CDF", MAGIC_NUM_LEN-1)==0)
+ {
+ if (magic[MAGIC_NUM_LEN-1] == NC_FORMAT_CLASSIC ||
+ magic[MAGIC_NUM_LEN-1] == NC_FORMAT_CDF2 ||
+ magic[MAGIC_NUM_LEN-1] == NC_FORMAT_CDF2)
+ *version = magic[MAGIC_NUM_LEN-1];
+ else
+ return NC_ENOTNC;
+ }
+ /* tomorrow, tomorrow, I love you tomorrow, you're always a day
+ away! */
+ /*if (magic[1] == 'H' && magic[2] == 'D' && magic[3] == 'F')
+ *version = 3;*/
+ return NC_NOERR;
+}
+
+/*
+ * Test nc_set_default_format
+ * try with bad default format
+ * try with NULL old_formatp
+ * try in data mode, check error
+ * check that proper set to NC_FILL works for record & non-record variables
+ * (note that it is not possible to test NC_NOFILL mode!)
+ * close file & create again for test using attribute _FillValue
+ */
+int
+test_ncmpi_set_default_format(void)
+{
+ int ncid, nok=0;
+ int err;
+ int i;
+ int version=1;
+ int old_format;
+
+ /* bad format */
+ err = ncmpi_set_default_format(BAD_DEFAULT_FORMAT, &old_format);
+ IF (err != NC_EINVAL)
+ error("bad default format: status = %d", err);
+ ELSE_NOK
+
+ /* NULL old_formatp */
+ err = ncmpi_set_default_format(NC_FORMAT_CDF2, NULL);
+ IF (err != NC_NOERR)
+ error("null old_fortmatp: status = %d", err);
+ ELSE_NOK
+
+ /* Cycle through available formats. */
+ for(i=1; i<5; i++)
+ {
+ if (i == 3 || i == 4) continue; /* test classic formats only */
+
+ if ((err = ncmpi_set_default_format(i, NULL)))
+ error("setting classic format: status = %d", err);
+ ELSE_NOK
+ if ((err=ncmpi_create(comm, scratch, NC_CLOBBER, info, &ncid)))
+ error("bad nc_create: status = %d", err);
+ if ((err=ncmpi_put_att_text(ncid, NC_GLOBAL, "testatt",
+ sizeof("blah"), "blah")))
+ error("bad put_att: status = %d", err);
+ if ( (err=ncmpi_close(ncid)))
+ error("bad close: status = %d", err);
+ if ( (err = ncmpi_get_file_version(scratch, &version)) )
+ error("bad file version = %d", err);
+ if (version != i) {
+ if (i == 4) {
+ if (version == 3) continue;
+ printf("expect version 3 but got %d (file=%s)",version,scratch);
+ continue;
+ }
+ printf("expect version %d but got %d (file=%s)",i,version,scratch);
+ error("bad file version = %d", version);
+ }
+ }
+
+ /* Remove the left-over file. */
+ if ((err = ncmpi_delete(scratch, info)))
+ error("remove of %s failed", scratch);
+ return nok;
+}
+
+
+
+
+/*
+ * Test ncmpi_delete
+ * create netcdf file 'scratch.nc' with no data, close it
+ * delete the file
+ */
+int
+test_ncmpi_delete(void)
+{
+ int err, nok=0;;
+ int ncid;
+
+ err = ncmpi_create(comm, scratch, NC_CLOBBER|extra_flags, info, &ncid);
+ IF (err != NC_NOERR)
+ error("error creating scratch file %s, status = %d\n", scratch,err);
+ err = ncmpi_close(ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_close: %s", ncmpi_strerror(err));
+ err = ncmpi_delete(scratch, info);
+ IF (err != NC_NOERR)
+ error("remove of %s failed", scratch);
+ ELSE_NOK
+ return nok;
+}
diff --git a/test/nc_test/tests.h b/test/nc_test/tests.h
new file mode 100644
index 0000000..ffcead3
--- /dev/null
+++ b/test/nc_test/tests.h
@@ -0,0 +1,793 @@
+/*
+ * Copyright (C) 2003, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ */
+/* $Id: tests.h 2293 2016-01-06 03:43:04Z wkliao $ */
+
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <limits.h>
+#include <float.h>
+#define NO_NETCDF_2 1
+#include <errno.h>
+#include <mpi.h>
+
+#include <pnetcdf.h>
+#include <testutils.h>
+#include "error.h"
+
+#include "ncconfig.h" /* output of 'configure' */
+
+#if defined(_CRAY) && !defined(_CRAYIEEE)
+#define CRAYFLOAT 1 /* CRAY Floating point */
+#elif defined(_SX) && defined(_FLOAT2) /* NEC SUPER-UX in CRAY mode */
+#define CRAYFLOAT 1 /* CRAY Floating point */
+#endif
+
+/* Limits of external types (based on those in ncx.h) */
+
+/* Note: In CDF format specification, NC_CHAR is for text characters, which
+ * is considered an 8-bit unsigned integer. Since it is for printable text
+ * characters, its values should range from 0 (X_CHAR_MIN) to 255 (X_CHAR_MAX).
+ */
+#define X_CHAR_MIN 0
+#define X_CHAR_MAX 255
+
+#define X_SCHAR_MIN (-128)
+#define X_SCHAR_MAX 127
+#define X_UCHAR_MAX 255
+#define X_UCHAR_MIN 0
+#define X_BYTE_MIN X_SCHAR_MIN
+#define X_BYTE_MAX X_SCHAR_MAX
+#define X_SHORT_MIN (-32768)
+#define X_SHORT_MAX 32767
+#define X_INT_MIN (-2147483647-1)
+#define X_INT_MAX 2147483647
+#if defined(FLT_MAX_EXP) && FLT_MAX_EXP < 128
+/* FLT_MAX < X_FLOAT_MAX */
+#define X_FLOAT_MAX FLT_MAX
+#else
+#define X_FLOAT_MAX 3.40282347e+38f
+#endif
+#define X_FLOAT_MIN (-X_FLOAT_MAX)
+#if defined(CRAYFLOAT) && CRAYFLOAT != 0
+/* ldexp(1. - ldexp(.5 , -46), 1024) */
+#define X_DOUBLE_MAX 1.79769313486230e+308
+#else
+/* scalb(1. - scalb(.5 , -52), 1024) */
+#define X_DOUBLE_MAX DBL_MAX
+#endif
+#define X_DOUBLE_MIN -(DBL_MAX)
+
+#define X_UBYTE_MAX X_UCHAR_MAX
+#define X_UBYTE_MIN X_UCHAR_MIN
+#define X_USHORT_MAX 65535U
+#define X_USHORT_MIN 0
+#define X_UINT_MAX 4294967295U
+#define X_UINT_MIN 0
+
+#ifndef LLONG_MAX
+#define LLONG_MAX 0x7fffffffffffffffLL
+#endif
+#ifndef LLONG_MIN
+#define LLONG_MIN (-0x7fffffffffffffffLL-1)
+#endif
+#ifndef ULLONG_MAX
+#define ULLONG_MAX 0xffffffffffffffffULL
+#endif
+
+#ifndef X_INT64_MAX
+#define X_INT64_MAX LLONG_MAX
+#endif
+#ifndef X_INT64_MIN
+#define X_INT64_MIN LLONG_MIN
+#endif
+#ifndef X_UINT64_MAX
+#define X_UINT64_MAX ULLONG_MAX
+#endif
+#ifndef X_UINT64_MIN
+#define X_UINT64_MIN ULLONG_MIN
+#endif
+
+
+#if defined(_SX) && _SX != 0 /* NEC SUPER UX */
+#if _INT64
+#undef INT_MAX /* workaround cpp bug */
+#define INT_MAX X_INT_MAX
+#undef INT_MIN /* workaround cpp bug */
+#define INT_MIN X_INT_MIN
+#undef LONG_MAX /* workaround cpp bug */
+#define LONG_MAX X_INT_MAX
+#undef LONG_MIN /* workaround cpp bug */
+#define LONG_MIN X_INT_MIN
+#elif _LONG64
+#undef LONG_MAX /* workaround cpp bug */
+#define LONG_MAX 4294967295L
+#undef LONG_MIN /* workaround cpp bug */
+#define LONG_MIN -4294967295L
+#endif
+#endif /* _SX */
+
+
+#ifndef MAX
+#define MAX(a,b) ((a) > (b) ? (a) : (b))
+#endif /* MAX */
+
+#ifndef MIN
+#define MIN(a,b) ((a) < (b) ? (a) : (b))
+#endif /* MIN */
+
+#ifndef ABS
+#define ABS(x) ((x) < 0 ? -(x) : (x))
+#endif /* ABS */
+
+ /* Parameters of test data */
+
+#define NTYPES 11 /* number of nc_types to test */
+#define NDIMS 5
+#define NRECS 2
+#define NGATTS NTYPES
+#define RECDIM 0
+#define MAX_RANK 3
+#define MAX_NELS 64
+#define MAX_DIM_LEN 4
+#define MAX_NATTS 3
+/*
+ * #define NVARS 136 when NTYPES==6
+ * #define NVARS 142 when NTYPES==7
+ * #define NVARS 148 when NTYPES==8
+ * #define NVARS 154 when NTYPES==9
+ * #define NVARS 160 when NTYPES==10
+ * #define NVARS 166 when NTYPES==11
+ * c:char, b:byte, s:short, i:int, f:float, d:double, y:ubyte, t:ushort,
+ * u:uint, x:int64, z:uint64
+ */
+#define NVARS 166
+
+/*
+ * * global variables (defined by command line processing in main())
+ * * related use of CDF-1 vs CDF-2 file formats
+ * */
+extern int cdf_format; /* 1: CDF-1, 2: CDF-2 5: CDF-5 */
+extern int extra_flags; /* if using CDF-2 format, will be set to NC_64BIT_OFFSET
+ if using CDF-5 format, will be set to NC_64BIT_DATA */
+extern int numGatts; /* number of global attributes */
+extern int numVars; /* number of variables */
+extern int numTypes; /* number of netCDF data types to test */
+
+
+/* Here is how NVARS is acalculated in init_gvars().
+MAX_RANK=3
+MAX_DIM_LEN==4
+max_dim_len[MAX_RANK] = {MAX_DIM_LEN +1, MAX_DIM_LEN, MAX_DIM_LEN };
+rank==0, nvars=1 ntypes=NTYPES (if rank < 2)
+rank==1, nvars=5 ntypes=NTYPES (if rank < 2)
+rank==2, nvars=5*4 ntypes=1 (if rank >= 2)
+rank==3, nvars=5*4*4 ntypes=1 (if rank >= 2)
+nv=1* 6+5* 6+5*4+5*4*4= 6+30+20+80 = 136 (if NTYPES==6)
+nv=1* 7+5* 7+5*4+5*4*4= 7+35+20+80 = 142 (if NTYPES==7)
+nv=1* 8+5* 8+5*4+5*4*4= 8+40+20+80 = 148 (if NTYPES==8)
+nv=1* 9+5* 9+5*4+5*4*4= 9+45+20+80 = 154 (if NTYPES==9)
+nv=1*10+5*10+5*4+5*4*4=10+50+20+80 = 160 (if NTYPES==10)
+nv=1*11+5*11+5*4+5*4*4=11+55+20+80 = 166 (if NTYPES==11)
+*/
+
+/* Limits of internal types */
+
+/* Remove the use of text_min and text_max, becuase in NetCDF, there is no
+ * situation that would cause to check the range of a text or NC_CHAR value.
+ * In netCDF, a NC_CHAR variable must be read/written/created by netCDF text
+ * APIs. Otherwise, NC_ECHAR error will return. In the text APIs, the user
+ * buffers will be treated as a text array. For put APIs, a local signed char
+ * value (if the local char is signed) will be type-casted to an unsigned char
+ * value before writing to the file. For get APIs, an external unsigned char
+ * (NC_CHAR) value will be type-casted to a local signed char value. If the
+ * local char is unsigned, then no type casting will even happen. Also note
+ * that netCDF text APIs never returns NC_ERANGE error code.
+
+#define text_min CHAR_MIN
+#define text_max CHAR_MAX
+*/
+
+#define uchar_min 0
+#define schar_min SCHAR_MIN
+#define short_min SHRT_MIN
+#define int_min INT_MIN
+#define long_min LONG_MIN
+#define float_min (-FLT_MAX)
+#define double_min (-DBL_MAX)
+#define ushort_min 0
+#define uint_min 0
+#define ulong_min 0
+#define int64_min LLONG_MIN
+#define longlong_min int64_min
+#define uint64_min 0
+#define ulonglong_min uint64_min
+
+#define uchar_max UCHAR_MAX
+#define schar_max SCHAR_MAX
+#define short_max SHRT_MAX
+#define int_max INT_MAX
+#define long_max LONG_MAX
+#define float_max FLT_MAX
+#define double_max DBL_MAX
+#define ushort_max USHRT_MAX
+#define uint_max UINT_MAX
+#define ulong_max ULONG_MAX
+#define int64_max LLONG_MAX
+#define longlong_max int64_max
+#define uint64_max ULLONG_MAX
+#define ulonglong_max uint64_max
+
+
+
+ /* Examples of invalid argument values */
+
+#define BAD_ID -1 /* invalid netCDF ID */
+#define BAD_DIMID -1 /* invalid dim ID */
+#define BAD_VARID -2 /* invalid var ID */
+#define BAD_ATTNUM -1 /* invalid att number */
+#define BAD_TYPE (nc_type) 0 /* invalid data type */
+#define BAD_FILLMODE -1 /* invalid fill mode */
+#define BAD_NAME "a/b" /* invalid name */
+#define BAD_DEFAULT_FORMAT 12 /* invalid default format */
+
+#define LEN_OF(array) ((sizeof array) / (sizeof array[0]))
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+ /* Non-standard internal types */
+
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+
+typedef char text;
+typedef signed char schar;
+#if !defined(HAVE_UCHAR) && !defined(__osf__) && !defined(_AIX)
+typedef unsigned char uchar;
+#endif
+
+#ifndef HAVE_USHORT
+typedef unsigned short int ushort;
+#endif
+
+#ifndef HAVE_UINT
+typedef unsigned int uint;
+#endif
+
+#ifndef HAVE_INT64
+typedef long long int64;
+#endif
+
+#ifndef HAVE_UINT64
+typedef unsigned long long uint64;
+#endif
+
+typedef long long longlong;
+typedef unsigned long long ulonglong;
+
+
+ /* Global variables - filenames */
+
+extern char testfile[128]; /* netCDF read-only test data */
+extern char scratch[128]; /* netCDF test file for writing */
+
+ /* Global variables - command-line arguments */
+
+extern int read_only; /* if 1, don't try to change files */
+extern int verbose; /* if 1, print details of tests */
+extern int nfails; /* number of failures in specific test */
+extern int use_cdf2; /* if 1, use CDF-2 format (offset >2GB ) */
+extern int extra_flags; /* if using CDF-2, need extra flags for create*/
+extern int max_nmpt; /* max number of messages per test */
+
+
+ /* Global variables - test data */
+
+extern char dim_name[NDIMS][3];
+extern MPI_Offset dim_len[NDIMS];
+extern char var_name[NVARS][2+MAX_RANK];
+extern nc_type var_type[NVARS];
+extern size_t var_rank[NVARS];
+extern int var_dimid[NVARS][MAX_RANK];
+extern MPI_Offset var_shape[NVARS][MAX_RANK];
+extern size_t var_nels[NVARS];
+extern size_t var_natts[NVARS];
+extern char att_name[NVARS][MAX_NATTS][2];
+extern char gatt_name[NGATTS][3];
+extern nc_type att_type[NVARS][NGATTS];
+extern nc_type gatt_type[NGATTS];
+extern size_t att_len[NVARS][MAX_NATTS];
+extern size_t gatt_len[NGATTS];
+
+/* Global variables: MPI data */
+extern MPI_Comm comm;
+extern MPI_Info info;
+
+ /* Macros for accessing attribute test data */
+ /* varid is -1 for NC_GLOBAL so can do global atts in same loop */
+
+#define VARID(varid) (varid < 0 ? NC_GLOBAL : varid)
+#define NATTS(varid) (varid < 0 ? numGatts : var_natts[varid])
+#define ATT_NAME(varid,j) (varid < 0 ? gatt_name[j] : att_name[varid][j])
+#define ATT_TYPE(varid,j) (varid < 0 ? gatt_type[j] : att_type[varid][j])
+#define ATT_LEN(varid,j) (varid < 0 ? gatt_len[j] : att_len[varid][j])
+
+extern const char *s_nc_type(nc_type);
+
+extern int test_ncmpi_strerror(void);
+extern int test_ncmpi_open(void);
+extern int test_ncmpi_close(void);
+extern int test_ncmpi_delete(void);
+
+extern int test_ncmpi_inq(void);
+extern int test_ncmpi_inq_natts(void);
+extern int test_ncmpi_inq_ndims(void);
+extern int test_ncmpi_inq_nvars(void);
+extern int test_ncmpi_inq_unlimdim(void);
+
+extern int test_ncmpi_inq_dimid(void);
+extern int test_ncmpi_inq_dim(void);
+extern int test_ncmpi_inq_dimlen(void);
+extern int test_ncmpi_inq_dimname(void);
+
+extern int test_ncmpi_inq_varid(void);
+extern int test_ncmpi_inq_vardimid(void);
+extern int test_ncmpi_inq_varname(void);
+extern int test_ncmpi_inq_varnatts(void);
+extern int test_ncmpi_inq_varndims(void);
+extern int test_ncmpi_inq_vartype(void);
+extern int test_ncmpi_inq_var(void);
+
+extern int test_ncmpi_get_var(void);
+extern int test_ncmpi_get_var_text(void);
+extern int test_ncmpi_get_var_schar(void);
+extern int test_ncmpi_get_var_uchar(void);
+extern int test_ncmpi_get_var_short(void);
+extern int test_ncmpi_get_var_int(void);
+extern int test_ncmpi_get_var_long(void);
+extern int test_ncmpi_get_var_float(void);
+extern int test_ncmpi_get_var_double(void);
+extern int test_ncmpi_get_var_ushort(void);
+extern int test_ncmpi_get_var_uint(void);
+extern int test_ncmpi_get_var_longlong(void);
+extern int test_ncmpi_get_var_ulonglong(void);
+
+extern int test_ncmpi_get_var1(void);
+extern int test_ncmpi_get_var1_text(void);
+extern int test_ncmpi_get_var1_schar(void);
+extern int test_ncmpi_get_var1_uchar(void);
+extern int test_ncmpi_get_var1_short(void);
+extern int test_ncmpi_get_var1_int(void);
+extern int test_ncmpi_get_var1_long(void);
+extern int test_ncmpi_get_var1_float(void);
+extern int test_ncmpi_get_var1_double(void);
+extern int test_ncmpi_get_var1_ushort(void);
+extern int test_ncmpi_get_var1_uint(void);
+extern int test_ncmpi_get_var1_longlong(void);
+extern int test_ncmpi_get_var1_ulonglong(void);
+
+extern int test_ncmpi_get_vara(void);
+extern int test_ncmpi_get_vara_text(void);
+extern int test_ncmpi_get_vara_schar(void);
+extern int test_ncmpi_get_vara_uchar(void);
+extern int test_ncmpi_get_vara_short(void);
+extern int test_ncmpi_get_vara_int(void);
+extern int test_ncmpi_get_vara_long(void);
+extern int test_ncmpi_get_vara_float(void);
+extern int test_ncmpi_get_vara_double(void);
+extern int test_ncmpi_get_vara_ushort(void);
+extern int test_ncmpi_get_vara_uint(void);
+extern int test_ncmpi_get_vara_longlong(void);
+extern int test_ncmpi_get_vara_ulonglong(void);
+
+extern int test_ncmpi_get_vars(void);
+extern int test_ncmpi_get_vars_text(void);
+extern int test_ncmpi_get_vars_schar(void);
+extern int test_ncmpi_get_vars_uchar(void);
+extern int test_ncmpi_get_vars_short(void);
+extern int test_ncmpi_get_vars_int(void);
+extern int test_ncmpi_get_vars_long(void);
+extern int test_ncmpi_get_vars_float(void);
+extern int test_ncmpi_get_vars_double(void);
+extern int test_ncmpi_get_vars_ushort(void);
+extern int test_ncmpi_get_vars_uint(void);
+extern int test_ncmpi_get_vars_longlong(void);
+extern int test_ncmpi_get_vars_ulonglong(void);
+
+extern int test_ncmpi_get_varm(void);
+extern int test_ncmpi_get_varm_text(void);
+extern int test_ncmpi_get_varm_schar(void);
+extern int test_ncmpi_get_varm_uchar(void);
+extern int test_ncmpi_get_varm_short(void);
+extern int test_ncmpi_get_varm_int(void);
+extern int test_ncmpi_get_varm_long(void);
+extern int test_ncmpi_get_varm_float(void);
+extern int test_ncmpi_get_varm_double(void);
+extern int test_ncmpi_get_varm_ushort(void);
+extern int test_ncmpi_get_varm_uint(void);
+extern int test_ncmpi_get_varm_longlong(void);
+extern int test_ncmpi_get_varm_ulonglong(void);
+
+extern int test_ncmpi_iget_var(void);
+extern int test_ncmpi_iget_var_text(void);
+extern int test_ncmpi_iget_var_schar(void);
+extern int test_ncmpi_iget_var_uchar(void);
+extern int test_ncmpi_iget_var_short(void);
+extern int test_ncmpi_iget_var_int(void);
+extern int test_ncmpi_iget_var_long(void);
+extern int test_ncmpi_iget_var_float(void);
+extern int test_ncmpi_iget_var_double(void);
+extern int test_ncmpi_iget_var_ushort(void);
+extern int test_ncmpi_iget_var_uint(void);
+extern int test_ncmpi_iget_var_longlong(void);
+extern int test_ncmpi_iget_var_ulonglong(void);
+
+extern int test_ncmpi_iget_var1(void);
+extern int test_ncmpi_iget_var1_text(void);
+extern int test_ncmpi_iget_var1_schar(void);
+extern int test_ncmpi_iget_var1_uchar(void);
+extern int test_ncmpi_iget_var1_short(void);
+extern int test_ncmpi_iget_var1_int(void);
+extern int test_ncmpi_iget_var1_long(void);
+extern int test_ncmpi_iget_var1_float(void);
+extern int test_ncmpi_iget_var1_double(void);
+extern int test_ncmpi_iget_var1_ushort(void);
+extern int test_ncmpi_iget_var1_uint(void);
+extern int test_ncmpi_iget_var1_longlong(void);
+extern int test_ncmpi_iget_var1_ulonglong(void);
+
+extern int test_ncmpi_iget_vara(void);
+extern int test_ncmpi_iget_vara_text(void);
+extern int test_ncmpi_iget_vara_schar(void);
+extern int test_ncmpi_iget_vara_uchar(void);
+extern int test_ncmpi_iget_vara_short(void);
+extern int test_ncmpi_iget_vara_int(void);
+extern int test_ncmpi_iget_vara_long(void);
+extern int test_ncmpi_iget_vara_float(void);
+extern int test_ncmpi_iget_vara_double(void);
+extern int test_ncmpi_iget_vara_ushort(void);
+extern int test_ncmpi_iget_vara_uint(void);
+extern int test_ncmpi_iget_vara_longlong(void);
+extern int test_ncmpi_iget_vara_ulonglong(void);
+
+extern int test_ncmpi_iget_vars(void);
+extern int test_ncmpi_iget_vars_text(void);
+extern int test_ncmpi_iget_vars_schar(void);
+extern int test_ncmpi_iget_vars_uchar(void);
+extern int test_ncmpi_iget_vars_short(void);
+extern int test_ncmpi_iget_vars_int(void);
+extern int test_ncmpi_iget_vars_long(void);
+extern int test_ncmpi_iget_vars_float(void);
+extern int test_ncmpi_iget_vars_double(void);
+extern int test_ncmpi_iget_vars_ushort(void);
+extern int test_ncmpi_iget_vars_uint(void);
+extern int test_ncmpi_iget_vars_longlong(void);
+extern int test_ncmpi_iget_vars_ulonglong(void);
+
+extern int test_ncmpi_iget_varm(void);
+extern int test_ncmpi_iget_varm_text(void);
+extern int test_ncmpi_iget_varm_schar(void);
+extern int test_ncmpi_iget_varm_uchar(void);
+extern int test_ncmpi_iget_varm_short(void);
+extern int test_ncmpi_iget_varm_int(void);
+extern int test_ncmpi_iget_varm_long(void);
+extern int test_ncmpi_iget_varm_float(void);
+extern int test_ncmpi_iget_varm_double(void);
+extern int test_ncmpi_iget_varm_ushort(void);
+extern int test_ncmpi_iget_varm_uint(void);
+extern int test_ncmpi_iget_varm_longlong(void);
+extern int test_ncmpi_iget_varm_ulonglong(void);
+
+extern int test_ncmpi_get_att(void);
+extern int test_ncmpi_get_att_text(void);
+extern int test_ncmpi_get_att_schar(void);
+extern int test_ncmpi_get_att_uchar(void);
+extern int test_ncmpi_get_att_short(void);
+extern int test_ncmpi_get_att_int(void);
+extern int test_ncmpi_get_att_long(void);
+extern int test_ncmpi_get_att_float(void);
+extern int test_ncmpi_get_att_double(void);
+extern int test_ncmpi_get_att_ushort(void);
+extern int test_ncmpi_get_att_uint(void);
+extern int test_ncmpi_get_att_longlong(void);
+extern int test_ncmpi_get_att_ulonglong(void);
+
+extern int test_ncmpi_put_var(void);
+extern int test_ncmpi_put_var_text(void);
+extern int test_ncmpi_put_var_schar(void);
+extern int test_ncmpi_put_var_uchar(void);
+extern int test_ncmpi_put_var_short(void);
+extern int test_ncmpi_put_var_int(void);
+extern int test_ncmpi_put_var_long(void);
+extern int test_ncmpi_put_var_float(void);
+extern int test_ncmpi_put_var_double(void);
+extern int test_ncmpi_put_var_ushort(void);
+extern int test_ncmpi_put_var_uint(void);
+extern int test_ncmpi_put_var_longlong(void);
+extern int test_ncmpi_put_var_ulonglong(void);
+
+extern int test_ncmpi_put_var1(void);
+extern int test_ncmpi_put_var1_text(void);
+extern int test_ncmpi_put_var1_schar(void);
+extern int test_ncmpi_put_var1_uchar(void);
+extern int test_ncmpi_put_var1_short(void);
+extern int test_ncmpi_put_var1_int(void);
+extern int test_ncmpi_put_var1_long(void);
+extern int test_ncmpi_put_var1_float(void);
+extern int test_ncmpi_put_var1_double(void);
+extern int test_ncmpi_put_var1_ushort(void);
+extern int test_ncmpi_put_var1_uint(void);
+extern int test_ncmpi_put_var1_longlong(void);
+extern int test_ncmpi_put_var1_ulonglong(void);
+
+extern int test_ncmpi_put_vara(void);
+extern int test_ncmpi_put_vara_text(void);
+extern int test_ncmpi_put_vara_schar(void);
+extern int test_ncmpi_put_vara_uchar(void);
+extern int test_ncmpi_put_vara_short(void);
+extern int test_ncmpi_put_vara_int(void);
+extern int test_ncmpi_put_vara_long(void);
+extern int test_ncmpi_put_vara_float(void);
+extern int test_ncmpi_put_vara_double(void);
+extern int test_ncmpi_put_vara_ushort(void);
+extern int test_ncmpi_put_vara_uint(void);
+extern int test_ncmpi_put_vara_longlong(void);
+extern int test_ncmpi_put_vara_ulonglong(void);
+
+extern int test_ncmpi_put_vars(void);
+extern int test_ncmpi_put_vars_text(void);
+extern int test_ncmpi_put_vars_schar(void);
+extern int test_ncmpi_put_vars_uchar(void);
+extern int test_ncmpi_put_vars_short(void);
+extern int test_ncmpi_put_vars_int(void);
+extern int test_ncmpi_put_vars_long(void);
+extern int test_ncmpi_put_vars_float(void);
+extern int test_ncmpi_put_vars_double(void);
+extern int test_ncmpi_put_vars_ushort(void);
+extern int test_ncmpi_put_vars_uint(void);
+extern int test_ncmpi_put_vars_longlong(void);
+extern int test_ncmpi_put_vars_ulonglong(void);
+
+extern int test_ncmpi_put_varm(void);
+extern int test_ncmpi_put_varm_text(void);
+extern int test_ncmpi_put_varm_schar(void);
+extern int test_ncmpi_put_varm_uchar(void);
+extern int test_ncmpi_put_varm_short(void);
+extern int test_ncmpi_put_varm_int(void);
+extern int test_ncmpi_put_varm_long(void);
+extern int test_ncmpi_put_varm_float(void);
+extern int test_ncmpi_put_varm_double(void);
+extern int test_ncmpi_put_varm_ushort(void);
+extern int test_ncmpi_put_varm_uint(void);
+extern int test_ncmpi_put_varm_longlong(void);
+extern int test_ncmpi_put_varm_ulonglong(void);
+
+extern int test_ncmpi_iput_var(void);
+extern int test_ncmpi_iput_var_text(void);
+extern int test_ncmpi_iput_var_schar(void);
+extern int test_ncmpi_iput_var_uchar(void);
+extern int test_ncmpi_iput_var_short(void);
+extern int test_ncmpi_iput_var_int(void);
+extern int test_ncmpi_iput_var_long(void);
+extern int test_ncmpi_iput_var_float(void);
+extern int test_ncmpi_iput_var_double(void);
+extern int test_ncmpi_iput_var_ushort(void);
+extern int test_ncmpi_iput_var_uint(void);
+extern int test_ncmpi_iput_var_longlong(void);
+extern int test_ncmpi_iput_var_ulonglong(void);
+
+extern int test_ncmpi_iput_var1(void);
+extern int test_ncmpi_iput_var1_text(void);
+extern int test_ncmpi_iput_var1_schar(void);
+extern int test_ncmpi_iput_var1_uchar(void);
+extern int test_ncmpi_iput_var1_short(void);
+extern int test_ncmpi_iput_var1_int(void);
+extern int test_ncmpi_iput_var1_long(void);
+extern int test_ncmpi_iput_var1_float(void);
+extern int test_ncmpi_iput_var1_double(void);
+extern int test_ncmpi_iput_var1_ushort(void);
+extern int test_ncmpi_iput_var1_uint(void);
+extern int test_ncmpi_iput_var1_longlong(void);
+extern int test_ncmpi_iput_var1_ulonglong(void);
+
+extern int test_ncmpi_iput_vara(void);
+extern int test_ncmpi_iput_vara_text(void);
+extern int test_ncmpi_iput_vara_schar(void);
+extern int test_ncmpi_iput_vara_uchar(void);
+extern int test_ncmpi_iput_vara_short(void);
+extern int test_ncmpi_iput_vara_int(void);
+extern int test_ncmpi_iput_vara_long(void);
+extern int test_ncmpi_iput_vara_float(void);
+extern int test_ncmpi_iput_vara_double(void);
+extern int test_ncmpi_iput_vara_ushort(void);
+extern int test_ncmpi_iput_vara_uint(void);
+extern int test_ncmpi_iput_vara_longlong(void);
+extern int test_ncmpi_iput_vara_ulonglong(void);
+
+extern int test_ncmpi_iput_vars(void);
+extern int test_ncmpi_iput_vars_text(void);
+extern int test_ncmpi_iput_vars_schar(void);
+extern int test_ncmpi_iput_vars_uchar(void);
+extern int test_ncmpi_iput_vars_short(void);
+extern int test_ncmpi_iput_vars_int(void);
+extern int test_ncmpi_iput_vars_long(void);
+extern int test_ncmpi_iput_vars_float(void);
+extern int test_ncmpi_iput_vars_double(void);
+extern int test_ncmpi_iput_vars_ushort(void);
+extern int test_ncmpi_iput_vars_uint(void);
+extern int test_ncmpi_iput_vars_longlong(void);
+extern int test_ncmpi_iput_vars_ulonglong(void);
+
+extern int test_ncmpi_iput_varm(void);
+extern int test_ncmpi_iput_varm_text(void);
+extern int test_ncmpi_iput_varm_schar(void);
+extern int test_ncmpi_iput_varm_uchar(void);
+extern int test_ncmpi_iput_varm_short(void);
+extern int test_ncmpi_iput_varm_int(void);
+extern int test_ncmpi_iput_varm_long(void);
+extern int test_ncmpi_iput_varm_float(void);
+extern int test_ncmpi_iput_varm_double(void);
+extern int test_ncmpi_iput_varm_ushort(void);
+extern int test_ncmpi_iput_varm_uint(void);
+extern int test_ncmpi_iput_varm_longlong(void);
+extern int test_ncmpi_iput_varm_ulonglong(void);
+
+extern int test_ncmpi_put_att(void);
+extern int test_ncmpi_put_att_text(void);
+extern int test_ncmpi_put_att_schar(void);
+extern int test_ncmpi_put_att_uchar(void);
+extern int test_ncmpi_put_att_short(void);
+extern int test_ncmpi_put_att_int(void);
+extern int test_ncmpi_put_att_long(void);
+extern int test_ncmpi_put_att_float(void);
+extern int test_ncmpi_put_att_double(void);
+extern int test_ncmpi_put_att_ushort(void);
+extern int test_ncmpi_put_att_uint(void);
+extern int test_ncmpi_put_att_longlong(void);
+extern int test_ncmpi_put_att_ulonglong(void);
+
+extern int test_ncmpi_create(void);
+extern int test_ncmpi_redef(void);
+extern int test_ncmpi_enddef(void);
+extern int test_ncmpi_sync(void);
+extern int test_ncmpi_abort(void);
+extern int test_ncmpi_def_dim(void);
+extern int test_ncmpi_rename_dim(void);
+extern int test_ncmpi_def_var(void);
+extern int test_ncmpi_rename_var(void);
+extern int test_ncmpi_copy_att(void);
+
+extern int test_ncmpi_inq_att(void);
+extern int test_ncmpi_inq_attname(void);
+extern int test_ncmpi_inq_attid(void);
+extern int test_ncmpi_inq_attlen(void);
+extern int test_ncmpi_inq_atttype(void);
+
+extern int test_ncmpi_rename_att(void);
+extern int test_ncmpi_del_att(void);
+extern int test_ncmpi_set_fill(void);
+extern int test_ncmpi_set_default_format(void);
+
+extern void print_nok(int nok);
+
+#define PRINT_NOK(nok) if (verbose) print("%4d good comparisons.\n",nok);
+
+
+/*
+ * internal types
+ */
+typedef enum {
+ NCT_UNSPECIFIED = 0,
+ NCT_UCHAR = 1, /* unsigned char */
+ NCT_TEXT = 16, /* char */
+#define NCT_CHAR NCT_TEXT
+ NCT_SCHAR = 17, /* signed char */
+ NCT_SHORT = 18, /* short */
+ NCT_INT = 20, /* int */
+ NCT_LONG = 22, /* long */
+ NCT_FLOAT = 36, /* float */
+ NCT_DOUBLE = 40, /* double */
+ NCT_USHORT = 41,
+ NCT_UINT = 42,
+ NCT_INT64 = 43,
+#define NCT_LONGLONG NCT_INT64
+ NCT_UINT64 = 44
+#define NCT_ULONGLONG NCT_UINT64
+} nct_itype;
+
+extern int
+inRange(const double value, const nc_type datatype);
+
+extern int
+inRange3(const double value, const nc_type datatype, const nct_itype itype);
+
+extern int
+equal(double x, double y, nc_type extType, nct_itype itype);
+
+extern int
+equal2(double x, double y, nc_type extType);
+
+extern int
+int_vec_eq(const int *v1, const int *v2, const int n);
+
+extern int
+roll(int n);
+
+extern int
+toMixedBase(
+ size_t number, /* number to be converted to mixed base */
+ size_t length,
+ const MPI_Offset base[], /* dimensioned [length], base[0] ignored */
+ MPI_Offset result[]); /* dimensioned [length] */
+
+extern size_t
+fromMixedBase(
+ size_t length,
+ MPI_Offset number[], /* dimensioned [length] */
+ MPI_Offset base[]); /* dimensioned [length], base[0] ignored */
+
+extern int
+nc2dbl ( const nc_type datatype, const void *p, double *result);
+
+extern int
+dbl2nc ( const double d, const nc_type datatype, void *p);
+
+extern double
+hash( const nc_type type, const int rank, const MPI_Offset *index );
+
+extern long long
+hashx_llong(const int rank, const MPI_Offset *index);
+
+extern double
+hash4(const nc_type type, const int rank, const MPI_Offset *index, const nct_itype itype);
+
+extern void
+init_gvars(void);
+
+extern void
+def_dims(int ncid);
+
+extern void
+def_vars(int ncid);
+
+extern void
+put_atts(int ncid);
+
+extern void
+put_vars(int ncid);
+
+extern void
+write_file(char *filename);
+
+extern void
+check_dims(int ncid);
+
+extern void
+check_vars(int ncid);
+
+extern void
+check_atts(int ncid);
+
+extern void
+check_file(char *filename);
+
+extern int
+nctypelen(nc_type type);
+
+extern MPI_Datatype
+nc_mpi_type(nc_type type);
+
+extern char*
+ncmpii_err_code_name(int err);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/test/nc_test/tst_atts.c b/test/nc_test/tst_atts.c
new file mode 100644
index 0000000..25ae1fd
--- /dev/null
+++ b/test/nc_test/tst_atts.c
@@ -0,0 +1,2246 @@
+/*
+ * Copyright (C) 2014, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ */
+/* $Id: tst_atts.c 2270 2015-12-23 19:14:45Z wkliao $ */
+
+/* This program is based on the test program tst_atts.c of the netCDF package */
+
+/* This is part of the netCDF package.
+ Copyright 2006 University Corporation for Atmospheric Research/Unidata.
+ See COPYRIGHT file for conditions of use.
+
+ This is a very simple example which writes a netCDF file with
+ Unicode names encoded with UTF-8. It is the NETCDF3 equivalent
+ of tst_unicode.c
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h> /* INT_MIN */
+#include <pnetcdf.h>
+
+#include <testutils.h>
+
+static int verbose;
+
+#define ERR {if (err != NC_NOERR) {printf("Error at %s line %d: %s\n",__func__,__LINE__,ncmpi_strerror(err)); return 1;}}
+#define ERRV {printf("Unexpected result at %s line %d\n",__func__,__LINE__); return 1;}
+
+
+#if 0
+static void
+check_err(const int stat, const int line, const char *file) {
+ if (stat != NC_NOERR) {
+ (void)fprintf(stderr,"line %d of %s: %s\n", line, file, ncmpi_strerror(stat));
+ fflush(stderr);
+ exit(1);
+ }
+}
+#endif
+
+static int
+create_file(char *filename, int cmode)
+{
+ int err; /* return status */
+ int ncid; /* netCDF id */
+
+ /* dimension ids */
+ int Dr_dim;
+ int D1_dim;
+ int D2_dim;
+ int D3_dim;
+ int D4_dim;
+
+ /* dimension lengths */
+ MPI_Offset Dr_len = NC_UNLIMITED;
+ MPI_Offset D1_len = 1;
+ MPI_Offset D2_len = 2;
+ MPI_Offset D3_len = 3;
+ MPI_Offset D4_len = 4;
+
+ /* variable ids */
+ int c_id;
+ int b_id;
+ int s_id;
+ int i_id;
+ int f_id;
+ int d_id;
+ int cr_id;
+ int br_id;
+ int sr_id;
+ int ir_id;
+ int fr_id;
+ int dr_id;
+ int c1_id;
+ int b1_id;
+ int s1_id;
+ int i1_id;
+ int f1_id;
+ int d1_id;
+ int c2_id;
+ int b2_id;
+ int s2_id;
+ int i2_id;
+ int f2_id;
+ int d2_id;
+ int c3_id;
+ int b3_id;
+ int s3_id;
+ int i3_id;
+ int f3_id;
+ int d3_id;
+ int c4_id;
+ int b4_id;
+ int s4_id;
+ int i4_id;
+ int f4_id;
+ int d4_id;
+ int cr1_id;
+ int br2_id;
+ int sr3_id;
+ int ir4_id;
+ int f11_id;
+ int d12_id;
+ int c13_id;
+ int b14_id;
+ int s21_id;
+ int i22_id;
+ int f23_id;
+ int d24_id;
+ int c31_id;
+ int b32_id;
+ int s33_id;
+ int i34_id;
+ int f41_id;
+ int d42_id;
+ int c43_id;
+ int b44_id;
+ int sr11_id;
+ int ir12_id;
+ int fr13_id;
+ int dr14_id;
+ int cr21_id;
+ int br22_id;
+ int sr23_id;
+ int ir24_id;
+ int fr31_id;
+ int dr32_id;
+ int cr33_id;
+ int br34_id;
+ int sr41_id;
+ int ir42_id;
+ int fr43_id;
+ int dr44_id;
+ int c111_id;
+ int b112_id;
+ int s113_id;
+ int i114_id;
+ int f121_id;
+ int d122_id;
+ int c123_id;
+ int b124_id;
+ int s131_id;
+ int i132_id;
+ int f133_id;
+ int d134_id;
+ int c141_id;
+ int b142_id;
+ int s143_id;
+ int i144_id;
+ int f211_id;
+ int d212_id;
+ int c213_id;
+ int b214_id;
+ int s221_id;
+ int i222_id;
+ int f223_id;
+ int d224_id;
+ int c231_id;
+ int b232_id;
+ int s233_id;
+ int i234_id;
+ int f241_id;
+ int d242_id;
+ int c243_id;
+ int b244_id;
+ int s311_id;
+ int i312_id;
+ int f313_id;
+ int d314_id;
+ int c321_id;
+ int b322_id;
+ int s323_id;
+ int i324_id;
+ int f331_id;
+ int d332_id;
+ int c333_id;
+ int b334_id;
+ int s341_id;
+ int i342_id;
+ int f343_id;
+ int d344_id;
+ int c411_id;
+ int b412_id;
+ int s413_id;
+ int i414_id;
+ int f421_id;
+ int d422_id;
+ int c423_id;
+ int b424_id;
+ int s431_id;
+ int i432_id;
+ int f433_id;
+ int d434_id;
+ int c441_id;
+ int b442_id;
+ int s443_id;
+ int i444_id;
+
+ /* rank (number of dimensions) for each variable */
+# define RANK_c 0
+# define RANK_b 0
+# define RANK_s 0
+# define RANK_i 0
+# define RANK_f 0
+# define RANK_d 0
+# define RANK_cr 1
+# define RANK_br 1
+# define RANK_sr 1
+# define RANK_ir 1
+# define RANK_fr 1
+# define RANK_dr 1
+# define RANK_c1 1
+# define RANK_b1 1
+# define RANK_s1 1
+# define RANK_i1 1
+# define RANK_f1 1
+# define RANK_d1 1
+# define RANK_c2 1
+# define RANK_b2 1
+# define RANK_s2 1
+# define RANK_i2 1
+# define RANK_f2 1
+# define RANK_d2 1
+# define RANK_c3 1
+# define RANK_b3 1
+# define RANK_s3 1
+# define RANK_i3 1
+# define RANK_f3 1
+# define RANK_d3 1
+# define RANK_c4 1
+# define RANK_b4 1
+# define RANK_s4 1
+# define RANK_i4 1
+# define RANK_f4 1
+# define RANK_d4 1
+# define RANK_cr1 2
+# define RANK_br2 2
+# define RANK_sr3 2
+# define RANK_ir4 2
+# define RANK_f11 2
+# define RANK_d12 2
+# define RANK_c13 2
+# define RANK_b14 2
+# define RANK_s21 2
+# define RANK_i22 2
+# define RANK_f23 2
+# define RANK_d24 2
+# define RANK_c31 2
+# define RANK_b32 2
+# define RANK_s33 2
+# define RANK_i34 2
+# define RANK_f41 2
+# define RANK_d42 2
+# define RANK_c43 2
+# define RANK_b44 2
+# define RANK_sr11 3
+# define RANK_ir12 3
+# define RANK_fr13 3
+# define RANK_dr14 3
+# define RANK_cr21 3
+# define RANK_br22 3
+# define RANK_sr23 3
+# define RANK_ir24 3
+# define RANK_fr31 3
+# define RANK_dr32 3
+# define RANK_cr33 3
+# define RANK_br34 3
+# define RANK_sr41 3
+# define RANK_ir42 3
+# define RANK_fr43 3
+# define RANK_dr44 3
+# define RANK_c111 3
+# define RANK_b112 3
+# define RANK_s113 3
+# define RANK_i114 3
+# define RANK_f121 3
+# define RANK_d122 3
+# define RANK_c123 3
+# define RANK_b124 3
+# define RANK_s131 3
+# define RANK_i132 3
+# define RANK_f133 3
+# define RANK_d134 3
+# define RANK_c141 3
+# define RANK_b142 3
+# define RANK_s143 3
+# define RANK_i144 3
+# define RANK_f211 3
+# define RANK_d212 3
+# define RANK_c213 3
+# define RANK_b214 3
+# define RANK_s221 3
+# define RANK_i222 3
+# define RANK_f223 3
+# define RANK_d224 3
+# define RANK_c231 3
+# define RANK_b232 3
+# define RANK_s233 3
+# define RANK_i234 3
+# define RANK_f241 3
+# define RANK_d242 3
+# define RANK_c243 3
+# define RANK_b244 3
+# define RANK_s311 3
+# define RANK_i312 3
+# define RANK_f313 3
+# define RANK_d314 3
+# define RANK_c321 3
+# define RANK_b322 3
+# define RANK_s323 3
+# define RANK_i324 3
+# define RANK_f331 3
+# define RANK_d332 3
+# define RANK_c333 3
+# define RANK_b334 3
+# define RANK_s341 3
+# define RANK_i342 3
+# define RANK_f343 3
+# define RANK_d344 3
+# define RANK_c411 3
+# define RANK_b412 3
+# define RANK_s413 3
+# define RANK_i414 3
+# define RANK_f421 3
+# define RANK_d422 3
+# define RANK_c423 3
+# define RANK_b424 3
+# define RANK_s431 3
+# define RANK_i432 3
+# define RANK_f433 3
+# define RANK_d434 3
+# define RANK_c441 3
+# define RANK_b442 3
+# define RANK_s443 3
+# define RANK_i444 3
+
+ /* variable shapes */
+ int cr_dims[RANK_cr];
+ int br_dims[RANK_br];
+ int sr_dims[RANK_sr];
+ int ir_dims[RANK_ir];
+ int fr_dims[RANK_fr];
+ int dr_dims[RANK_dr];
+ int c1_dims[RANK_c1];
+ int b1_dims[RANK_b1];
+ int s1_dims[RANK_s1];
+ int i1_dims[RANK_i1];
+ int f1_dims[RANK_f1];
+ int d1_dims[RANK_d1];
+ int c2_dims[RANK_c2];
+ int b2_dims[RANK_b2];
+ int s2_dims[RANK_s2];
+ int i2_dims[RANK_i2];
+ int f2_dims[RANK_f2];
+ int d2_dims[RANK_d2];
+ int c3_dims[RANK_c3];
+ int b3_dims[RANK_b3];
+ int s3_dims[RANK_s3];
+ int i3_dims[RANK_i3];
+ int f3_dims[RANK_f3];
+ int d3_dims[RANK_d3];
+ int c4_dims[RANK_c4];
+ int b4_dims[RANK_b4];
+ int s4_dims[RANK_s4];
+ int i4_dims[RANK_i4];
+ int f4_dims[RANK_f4];
+ int d4_dims[RANK_d4];
+ int cr1_dims[RANK_cr1];
+ int br2_dims[RANK_br2];
+ int sr3_dims[RANK_sr3];
+ int ir4_dims[RANK_ir4];
+ int f11_dims[RANK_f11];
+ int d12_dims[RANK_d12];
+ int c13_dims[RANK_c13];
+ int b14_dims[RANK_b14];
+ int s21_dims[RANK_s21];
+ int i22_dims[RANK_i22];
+ int f23_dims[RANK_f23];
+ int d24_dims[RANK_d24];
+ int c31_dims[RANK_c31];
+ int b32_dims[RANK_b32];
+ int s33_dims[RANK_s33];
+ int i34_dims[RANK_i34];
+ int f41_dims[RANK_f41];
+ int d42_dims[RANK_d42];
+ int c43_dims[RANK_c43];
+ int b44_dims[RANK_b44];
+ int sr11_dims[RANK_sr11];
+ int ir12_dims[RANK_ir12];
+ int fr13_dims[RANK_fr13];
+ int dr14_dims[RANK_dr14];
+ int cr21_dims[RANK_cr21];
+ int br22_dims[RANK_br22];
+ int sr23_dims[RANK_sr23];
+ int ir24_dims[RANK_ir24];
+ int fr31_dims[RANK_fr31];
+ int dr32_dims[RANK_dr32];
+ int cr33_dims[RANK_cr33];
+ int br34_dims[RANK_br34];
+ int sr41_dims[RANK_sr41];
+ int ir42_dims[RANK_ir42];
+ int fr43_dims[RANK_fr43];
+ int dr44_dims[RANK_dr44];
+ int c111_dims[RANK_c111];
+ int b112_dims[RANK_b112];
+ int s113_dims[RANK_s113];
+ int i114_dims[RANK_i114];
+ int f121_dims[RANK_f121];
+ int d122_dims[RANK_d122];
+ int c123_dims[RANK_c123];
+ int b124_dims[RANK_b124];
+ int s131_dims[RANK_s131];
+ int i132_dims[RANK_i132];
+ int f133_dims[RANK_f133];
+ int d134_dims[RANK_d134];
+ int c141_dims[RANK_c141];
+ int b142_dims[RANK_b142];
+ int s143_dims[RANK_s143];
+ int i144_dims[RANK_i144];
+ int f211_dims[RANK_f211];
+ int d212_dims[RANK_d212];
+ int c213_dims[RANK_c213];
+ int b214_dims[RANK_b214];
+ int s221_dims[RANK_s221];
+ int i222_dims[RANK_i222];
+ int f223_dims[RANK_f223];
+ int d224_dims[RANK_d224];
+ int c231_dims[RANK_c231];
+ int b232_dims[RANK_b232];
+ int s233_dims[RANK_s233];
+ int i234_dims[RANK_i234];
+ int f241_dims[RANK_f241];
+ int d242_dims[RANK_d242];
+ int c243_dims[RANK_c243];
+ int b244_dims[RANK_b244];
+ int s311_dims[RANK_s311];
+ int i312_dims[RANK_i312];
+ int f313_dims[RANK_f313];
+ int d314_dims[RANK_d314];
+ int c321_dims[RANK_c321];
+ int b322_dims[RANK_b322];
+ int s323_dims[RANK_s323];
+ int i324_dims[RANK_i324];
+ int f331_dims[RANK_f331];
+ int d332_dims[RANK_d332];
+ int c333_dims[RANK_c333];
+ int b334_dims[RANK_b334];
+ int s341_dims[RANK_s341];
+ int i342_dims[RANK_i342];
+ int f343_dims[RANK_f343];
+ int d344_dims[RANK_d344];
+ int c411_dims[RANK_c411];
+ int b412_dims[RANK_b412];
+ int s413_dims[RANK_s413];
+ int i414_dims[RANK_i414];
+ int f421_dims[RANK_f421];
+ int d422_dims[RANK_d422];
+ int c423_dims[RANK_c423];
+ int b424_dims[RANK_b424];
+ int s431_dims[RANK_s431];
+ int i432_dims[RANK_i432];
+ int f433_dims[RANK_f433];
+ int d434_dims[RANK_d434];
+ int c441_dims[RANK_c441];
+ int b442_dims[RANK_b442];
+ int s443_dims[RANK_s443];
+ int i444_dims[RANK_i444];
+
+ /* enter define mode */
+ err=ncmpi_create(MPI_COMM_WORLD, filename, cmode, MPI_INFO_NULL, &ncid); ERR
+
+ /* define dimensions */
+ err=ncmpi_def_dim(ncid, "Dr", Dr_len, &Dr_dim); ERR
+ err=ncmpi_def_dim(ncid, "D1", D1_len, &D1_dim); ERR
+ err=ncmpi_def_dim(ncid, "D2", D2_len, &D2_dim); ERR
+ err=ncmpi_def_dim(ncid, "D3", D3_len, &D3_dim); ERR
+ err=ncmpi_def_dim(ncid, "D4", D4_len, &D4_dim); ERR
+
+ /* define variables */
+
+ err=ncmpi_def_var(ncid, "c", NC_CHAR, RANK_c, 0, &c_id); ERR
+
+ err=ncmpi_def_var(ncid, "b", NC_BYTE, RANK_b, 0, &b_id); ERR
+
+ err=ncmpi_def_var(ncid, "s", NC_SHORT, RANK_s, 0, &s_id); ERR
+
+ err=ncmpi_def_var(ncid, "i", NC_INT, RANK_i, 0, &i_id); ERR
+
+ err=ncmpi_def_var(ncid, "f", NC_FLOAT, RANK_f, 0, &f_id); ERR
+
+ err=ncmpi_def_var(ncid, "d", NC_DOUBLE, RANK_d, 0, &d_id); ERR
+
+ cr_dims[0] = Dr_dim;
+ err=ncmpi_def_var(ncid, "cr", NC_CHAR, RANK_cr, cr_dims, &cr_id); ERR
+
+ br_dims[0] = Dr_dim;
+ err=ncmpi_def_var(ncid, "br", NC_BYTE, RANK_br, br_dims, &br_id); ERR
+
+ sr_dims[0] = Dr_dim;
+ err=ncmpi_def_var(ncid, "sr", NC_SHORT, RANK_sr, sr_dims, &sr_id); ERR
+
+ ir_dims[0] = Dr_dim;
+ err=ncmpi_def_var(ncid, "ir", NC_INT, RANK_ir, ir_dims, &ir_id); ERR
+
+ fr_dims[0] = Dr_dim;
+ err=ncmpi_def_var(ncid, "fr", NC_FLOAT, RANK_fr, fr_dims, &fr_id); ERR
+
+ dr_dims[0] = Dr_dim;
+ err=ncmpi_def_var(ncid, "dr", NC_DOUBLE, RANK_dr, dr_dims, &dr_id); ERR
+
+ c1_dims[0] = D1_dim;
+ err=ncmpi_def_var(ncid, "c1", NC_CHAR, RANK_c1, c1_dims, &c1_id); ERR
+
+ b1_dims[0] = D1_dim;
+ err=ncmpi_def_var(ncid, "b1", NC_BYTE, RANK_b1, b1_dims, &b1_id); ERR
+
+ s1_dims[0] = D1_dim;
+ err=ncmpi_def_var(ncid, "s1", NC_SHORT, RANK_s1, s1_dims, &s1_id); ERR
+
+ i1_dims[0] = D1_dim;
+ err=ncmpi_def_var(ncid, "i1", NC_INT, RANK_i1, i1_dims, &i1_id); ERR
+
+ f1_dims[0] = D1_dim;
+ err=ncmpi_def_var(ncid, "f1", NC_FLOAT, RANK_f1, f1_dims, &f1_id); ERR
+
+ d1_dims[0] = D1_dim;
+ err=ncmpi_def_var(ncid, "d1", NC_DOUBLE, RANK_d1, d1_dims, &d1_id); ERR
+
+ c2_dims[0] = D2_dim;
+ err=ncmpi_def_var(ncid, "c2", NC_CHAR, RANK_c2, c2_dims, &c2_id); ERR
+
+ b2_dims[0] = D2_dim;
+ err=ncmpi_def_var(ncid, "b2", NC_BYTE, RANK_b2, b2_dims, &b2_id); ERR
+
+ s2_dims[0] = D2_dim;
+ err=ncmpi_def_var(ncid, "s2", NC_SHORT, RANK_s2, s2_dims, &s2_id); ERR
+
+ i2_dims[0] = D2_dim;
+ err=ncmpi_def_var(ncid, "i2", NC_INT, RANK_i2, i2_dims, &i2_id); ERR
+
+ f2_dims[0] = D2_dim;
+ err=ncmpi_def_var(ncid, "f2", NC_FLOAT, RANK_f2, f2_dims, &f2_id); ERR
+
+ d2_dims[0] = D2_dim;
+ err=ncmpi_def_var(ncid, "d2", NC_DOUBLE, RANK_d2, d2_dims, &d2_id); ERR
+
+ c3_dims[0] = D3_dim;
+ err=ncmpi_def_var(ncid, "c3", NC_CHAR, RANK_c3, c3_dims, &c3_id); ERR
+
+ b3_dims[0] = D3_dim;
+ err=ncmpi_def_var(ncid, "b3", NC_BYTE, RANK_b3, b3_dims, &b3_id); ERR
+
+ s3_dims[0] = D3_dim;
+ err=ncmpi_def_var(ncid, "s3", NC_SHORT, RANK_s3, s3_dims, &s3_id); ERR
+
+ i3_dims[0] = D3_dim;
+ err=ncmpi_def_var(ncid, "i3", NC_INT, RANK_i3, i3_dims, &i3_id); ERR
+
+ f3_dims[0] = D3_dim;
+ err=ncmpi_def_var(ncid, "f3", NC_FLOAT, RANK_f3, f3_dims, &f3_id); ERR
+
+ d3_dims[0] = D3_dim;
+ err=ncmpi_def_var(ncid, "d3", NC_DOUBLE, RANK_d3, d3_dims, &d3_id); ERR
+
+ c4_dims[0] = D4_dim;
+ err=ncmpi_def_var(ncid, "c4", NC_CHAR, RANK_c4, c4_dims, &c4_id); ERR
+
+ b4_dims[0] = D4_dim;
+ err=ncmpi_def_var(ncid, "b4", NC_BYTE, RANK_b4, b4_dims, &b4_id); ERR
+
+ s4_dims[0] = D4_dim;
+ err=ncmpi_def_var(ncid, "s4", NC_SHORT, RANK_s4, s4_dims, &s4_id); ERR
+
+ i4_dims[0] = D4_dim;
+ err=ncmpi_def_var(ncid, "i4", NC_INT, RANK_i4, i4_dims, &i4_id); ERR
+
+ f4_dims[0] = D4_dim;
+ err=ncmpi_def_var(ncid, "f4", NC_FLOAT, RANK_f4, f4_dims, &f4_id); ERR
+
+ d4_dims[0] = D4_dim;
+ err=ncmpi_def_var(ncid, "d4", NC_DOUBLE, RANK_d4, d4_dims, &d4_id); ERR
+
+ cr1_dims[0] = Dr_dim;
+ cr1_dims[1] = D1_dim;
+ err=ncmpi_def_var(ncid, "cr1", NC_CHAR, RANK_cr1, cr1_dims, &cr1_id); ERR
+
+ br2_dims[0] = Dr_dim;
+ br2_dims[1] = D2_dim;
+ err=ncmpi_def_var(ncid, "br2", NC_BYTE, RANK_br2, br2_dims, &br2_id); ERR
+
+ sr3_dims[0] = Dr_dim;
+ sr3_dims[1] = D3_dim;
+ err=ncmpi_def_var(ncid, "sr3", NC_SHORT, RANK_sr3, sr3_dims, &sr3_id); ERR
+
+ ir4_dims[0] = Dr_dim;
+ ir4_dims[1] = D4_dim;
+ err=ncmpi_def_var(ncid, "ir4", NC_INT, RANK_ir4, ir4_dims, &ir4_id); ERR
+
+ f11_dims[0] = D1_dim;
+ f11_dims[1] = D1_dim;
+ err=ncmpi_def_var(ncid, "f11", NC_FLOAT, RANK_f11, f11_dims, &f11_id); ERR
+
+ d12_dims[0] = D1_dim;
+ d12_dims[1] = D2_dim;
+ err=ncmpi_def_var(ncid, "d12", NC_DOUBLE, RANK_d12, d12_dims, &d12_id); ERR
+
+ c13_dims[0] = D1_dim;
+ c13_dims[1] = D3_dim;
+ err=ncmpi_def_var(ncid, "c13", NC_CHAR, RANK_c13, c13_dims, &c13_id); ERR
+
+ b14_dims[0] = D1_dim;
+ b14_dims[1] = D4_dim;
+ err=ncmpi_def_var(ncid, "b14", NC_BYTE, RANK_b14, b14_dims, &b14_id); ERR
+
+ s21_dims[0] = D2_dim;
+ s21_dims[1] = D1_dim;
+ err=ncmpi_def_var(ncid, "s21", NC_SHORT, RANK_s21, s21_dims, &s21_id); ERR
+
+ i22_dims[0] = D2_dim;
+ i22_dims[1] = D2_dim;
+ err=ncmpi_def_var(ncid, "i22", NC_INT, RANK_i22, i22_dims, &i22_id); ERR
+
+ f23_dims[0] = D2_dim;
+ f23_dims[1] = D3_dim;
+ err=ncmpi_def_var(ncid, "f23", NC_FLOAT, RANK_f23, f23_dims, &f23_id); ERR
+
+ d24_dims[0] = D2_dim;
+ d24_dims[1] = D4_dim;
+ err=ncmpi_def_var(ncid, "d24", NC_DOUBLE, RANK_d24, d24_dims, &d24_id); ERR
+
+ c31_dims[0] = D3_dim;
+ c31_dims[1] = D1_dim;
+ err=ncmpi_def_var(ncid, "c31", NC_CHAR, RANK_c31, c31_dims, &c31_id); ERR
+
+ b32_dims[0] = D3_dim;
+ b32_dims[1] = D2_dim;
+ err=ncmpi_def_var(ncid, "b32", NC_BYTE, RANK_b32, b32_dims, &b32_id); ERR
+
+ s33_dims[0] = D3_dim;
+ s33_dims[1] = D3_dim;
+ err=ncmpi_def_var(ncid, "s33", NC_SHORT, RANK_s33, s33_dims, &s33_id); ERR
+
+ i34_dims[0] = D3_dim;
+ i34_dims[1] = D4_dim;
+ err=ncmpi_def_var(ncid, "i34", NC_INT, RANK_i34, i34_dims, &i34_id); ERR
+
+ f41_dims[0] = D4_dim;
+ f41_dims[1] = D1_dim;
+ err=ncmpi_def_var(ncid, "f41", NC_FLOAT, RANK_f41, f41_dims, &f41_id); ERR
+
+ d42_dims[0] = D4_dim;
+ d42_dims[1] = D2_dim;
+ err=ncmpi_def_var(ncid, "d42", NC_DOUBLE, RANK_d42, d42_dims, &d42_id); ERR
+
+ c43_dims[0] = D4_dim;
+ c43_dims[1] = D3_dim;
+ err=ncmpi_def_var(ncid, "c43", NC_CHAR, RANK_c43, c43_dims, &c43_id); ERR
+
+ b44_dims[0] = D4_dim;
+ b44_dims[1] = D4_dim;
+ err=ncmpi_def_var(ncid, "b44", NC_BYTE, RANK_b44, b44_dims, &b44_id); ERR
+
+ sr11_dims[0] = Dr_dim;
+ sr11_dims[1] = D1_dim;
+ sr11_dims[2] = D1_dim;
+ err=ncmpi_def_var(ncid, "sr11", NC_SHORT, RANK_sr11, sr11_dims, &sr11_id); ERR
+
+ ir12_dims[0] = Dr_dim;
+ ir12_dims[1] = D1_dim;
+ ir12_dims[2] = D2_dim;
+ err=ncmpi_def_var(ncid, "ir12", NC_INT, RANK_ir12, ir12_dims, &ir12_id); ERR
+
+ fr13_dims[0] = Dr_dim;
+ fr13_dims[1] = D1_dim;
+ fr13_dims[2] = D3_dim;
+ err=ncmpi_def_var(ncid, "fr13", NC_FLOAT, RANK_fr13, fr13_dims, &fr13_id); ERR
+
+ dr14_dims[0] = Dr_dim;
+ dr14_dims[1] = D1_dim;
+ dr14_dims[2] = D4_dim;
+ err=ncmpi_def_var(ncid, "dr14", NC_DOUBLE, RANK_dr14, dr14_dims, &dr14_id); ERR
+
+ cr21_dims[0] = Dr_dim;
+ cr21_dims[1] = D2_dim;
+ cr21_dims[2] = D1_dim;
+ err=ncmpi_def_var(ncid, "cr21", NC_CHAR, RANK_cr21, cr21_dims, &cr21_id); ERR
+
+ br22_dims[0] = Dr_dim;
+ br22_dims[1] = D2_dim;
+ br22_dims[2] = D2_dim;
+ err=ncmpi_def_var(ncid, "br22", NC_BYTE, RANK_br22, br22_dims, &br22_id); ERR
+
+ sr23_dims[0] = Dr_dim;
+ sr23_dims[1] = D2_dim;
+ sr23_dims[2] = D3_dim;
+ err=ncmpi_def_var(ncid, "sr23", NC_SHORT, RANK_sr23, sr23_dims, &sr23_id); ERR
+
+ ir24_dims[0] = Dr_dim;
+ ir24_dims[1] = D2_dim;
+ ir24_dims[2] = D4_dim;
+ err=ncmpi_def_var(ncid, "ir24", NC_INT, RANK_ir24, ir24_dims, &ir24_id); ERR
+
+ fr31_dims[0] = Dr_dim;
+ fr31_dims[1] = D3_dim;
+ fr31_dims[2] = D1_dim;
+ err=ncmpi_def_var(ncid, "fr31", NC_FLOAT, RANK_fr31, fr31_dims, &fr31_id); ERR
+
+ dr32_dims[0] = Dr_dim;
+ dr32_dims[1] = D3_dim;
+ dr32_dims[2] = D2_dim;
+ err=ncmpi_def_var(ncid, "dr32", NC_DOUBLE, RANK_dr32, dr32_dims, &dr32_id); ERR
+
+ cr33_dims[0] = Dr_dim;
+ cr33_dims[1] = D3_dim;
+ cr33_dims[2] = D3_dim;
+ err=ncmpi_def_var(ncid, "cr33", NC_CHAR, RANK_cr33, cr33_dims, &cr33_id); ERR
+
+ br34_dims[0] = Dr_dim;
+ br34_dims[1] = D3_dim;
+ br34_dims[2] = D4_dim;
+ err=ncmpi_def_var(ncid, "br34", NC_BYTE, RANK_br34, br34_dims, &br34_id); ERR
+
+ sr41_dims[0] = Dr_dim;
+ sr41_dims[1] = D4_dim;
+ sr41_dims[2] = D1_dim;
+ err=ncmpi_def_var(ncid, "sr41", NC_SHORT, RANK_sr41, sr41_dims, &sr41_id); ERR
+
+ ir42_dims[0] = Dr_dim;
+ ir42_dims[1] = D4_dim;
+ ir42_dims[2] = D2_dim;
+ err=ncmpi_def_var(ncid, "ir42", NC_INT, RANK_ir42, ir42_dims, &ir42_id); ERR
+
+ fr43_dims[0] = Dr_dim;
+ fr43_dims[1] = D4_dim;
+ fr43_dims[2] = D3_dim;
+ err=ncmpi_def_var(ncid, "fr43", NC_FLOAT, RANK_fr43, fr43_dims, &fr43_id); ERR
+
+ dr44_dims[0] = Dr_dim;
+ dr44_dims[1] = D4_dim;
+ dr44_dims[2] = D4_dim;
+ err=ncmpi_def_var(ncid, "dr44", NC_DOUBLE, RANK_dr44, dr44_dims, &dr44_id); ERR
+
+ c111_dims[0] = D1_dim;
+ c111_dims[1] = D1_dim;
+ c111_dims[2] = D1_dim;
+ err=ncmpi_def_var(ncid, "c111", NC_CHAR, RANK_c111, c111_dims, &c111_id); ERR
+
+ b112_dims[0] = D1_dim;
+ b112_dims[1] = D1_dim;
+ b112_dims[2] = D2_dim;
+ err=ncmpi_def_var(ncid, "b112", NC_BYTE, RANK_b112, b112_dims, &b112_id); ERR
+
+ s113_dims[0] = D1_dim;
+ s113_dims[1] = D1_dim;
+ s113_dims[2] = D3_dim;
+ err=ncmpi_def_var(ncid, "s113", NC_SHORT, RANK_s113, s113_dims, &s113_id); ERR
+
+ i114_dims[0] = D1_dim;
+ i114_dims[1] = D1_dim;
+ i114_dims[2] = D4_dim;
+ err=ncmpi_def_var(ncid, "i114", NC_INT, RANK_i114, i114_dims, &i114_id); ERR
+
+ f121_dims[0] = D1_dim;
+ f121_dims[1] = D2_dim;
+ f121_dims[2] = D1_dim;
+ err=ncmpi_def_var(ncid, "f121", NC_FLOAT, RANK_f121, f121_dims, &f121_id); ERR
+
+ d122_dims[0] = D1_dim;
+ d122_dims[1] = D2_dim;
+ d122_dims[2] = D2_dim;
+ err=ncmpi_def_var(ncid, "d122", NC_DOUBLE, RANK_d122, d122_dims, &d122_id); ERR
+
+ c123_dims[0] = D1_dim;
+ c123_dims[1] = D2_dim;
+ c123_dims[2] = D3_dim;
+ err=ncmpi_def_var(ncid, "c123", NC_CHAR, RANK_c123, c123_dims, &c123_id); ERR
+
+ b124_dims[0] = D1_dim;
+ b124_dims[1] = D2_dim;
+ b124_dims[2] = D4_dim;
+ err=ncmpi_def_var(ncid, "b124", NC_BYTE, RANK_b124, b124_dims, &b124_id); ERR
+
+ s131_dims[0] = D1_dim;
+ s131_dims[1] = D3_dim;
+ s131_dims[2] = D1_dim;
+ err=ncmpi_def_var(ncid, "s131", NC_SHORT, RANK_s131, s131_dims, &s131_id); ERR
+
+ i132_dims[0] = D1_dim;
+ i132_dims[1] = D3_dim;
+ i132_dims[2] = D2_dim;
+ err=ncmpi_def_var(ncid, "i132", NC_INT, RANK_i132, i132_dims, &i132_id); ERR
+
+ f133_dims[0] = D1_dim;
+ f133_dims[1] = D3_dim;
+ f133_dims[2] = D3_dim;
+ err=ncmpi_def_var(ncid, "f133", NC_FLOAT, RANK_f133, f133_dims, &f133_id); ERR
+
+ d134_dims[0] = D1_dim;
+ d134_dims[1] = D3_dim;
+ d134_dims[2] = D4_dim;
+ err=ncmpi_def_var(ncid, "d134", NC_DOUBLE, RANK_d134, d134_dims, &d134_id); ERR
+
+ c141_dims[0] = D1_dim;
+ c141_dims[1] = D4_dim;
+ c141_dims[2] = D1_dim;
+ err=ncmpi_def_var(ncid, "c141", NC_CHAR, RANK_c141, c141_dims, &c141_id); ERR
+
+ b142_dims[0] = D1_dim;
+ b142_dims[1] = D4_dim;
+ b142_dims[2] = D2_dim;
+ err=ncmpi_def_var(ncid, "b142", NC_BYTE, RANK_b142, b142_dims, &b142_id); ERR
+
+ s143_dims[0] = D1_dim;
+ s143_dims[1] = D4_dim;
+ s143_dims[2] = D3_dim;
+ err=ncmpi_def_var(ncid, "s143", NC_SHORT, RANK_s143, s143_dims, &s143_id); ERR
+
+ i144_dims[0] = D1_dim;
+ i144_dims[1] = D4_dim;
+ i144_dims[2] = D4_dim;
+ err=ncmpi_def_var(ncid, "i144", NC_INT, RANK_i144, i144_dims, &i144_id); ERR
+
+ f211_dims[0] = D2_dim;
+ f211_dims[1] = D1_dim;
+ f211_dims[2] = D1_dim;
+ err=ncmpi_def_var(ncid, "f211", NC_FLOAT, RANK_f211, f211_dims, &f211_id); ERR
+
+ d212_dims[0] = D2_dim;
+ d212_dims[1] = D1_dim;
+ d212_dims[2] = D2_dim;
+ err=ncmpi_def_var(ncid, "d212", NC_DOUBLE, RANK_d212, d212_dims, &d212_id); ERR
+
+ c213_dims[0] = D2_dim;
+ c213_dims[1] = D1_dim;
+ c213_dims[2] = D3_dim;
+ err=ncmpi_def_var(ncid, "c213", NC_CHAR, RANK_c213, c213_dims, &c213_id); ERR
+
+ b214_dims[0] = D2_dim;
+ b214_dims[1] = D1_dim;
+ b214_dims[2] = D4_dim;
+ err=ncmpi_def_var(ncid, "b214", NC_BYTE, RANK_b214, b214_dims, &b214_id); ERR
+
+ s221_dims[0] = D2_dim;
+ s221_dims[1] = D2_dim;
+ s221_dims[2] = D1_dim;
+ err=ncmpi_def_var(ncid, "s221", NC_SHORT, RANK_s221, s221_dims, &s221_id); ERR
+
+ i222_dims[0] = D2_dim;
+ i222_dims[1] = D2_dim;
+ i222_dims[2] = D2_dim;
+ err=ncmpi_def_var(ncid, "i222", NC_INT, RANK_i222, i222_dims, &i222_id); ERR
+
+ f223_dims[0] = D2_dim;
+ f223_dims[1] = D2_dim;
+ f223_dims[2] = D3_dim;
+ err=ncmpi_def_var(ncid, "f223", NC_FLOAT, RANK_f223, f223_dims, &f223_id); ERR
+
+ d224_dims[0] = D2_dim;
+ d224_dims[1] = D2_dim;
+ d224_dims[2] = D4_dim;
+ err=ncmpi_def_var(ncid, "d224", NC_DOUBLE, RANK_d224, d224_dims, &d224_id); ERR
+
+ c231_dims[0] = D2_dim;
+ c231_dims[1] = D3_dim;
+ c231_dims[2] = D1_dim;
+ err=ncmpi_def_var(ncid, "c231", NC_CHAR, RANK_c231, c231_dims, &c231_id); ERR
+
+ b232_dims[0] = D2_dim;
+ b232_dims[1] = D3_dim;
+ b232_dims[2] = D2_dim;
+ err=ncmpi_def_var(ncid, "b232", NC_BYTE, RANK_b232, b232_dims, &b232_id); ERR
+
+ s233_dims[0] = D2_dim;
+ s233_dims[1] = D3_dim;
+ s233_dims[2] = D3_dim;
+ err=ncmpi_def_var(ncid, "s233", NC_SHORT, RANK_s233, s233_dims, &s233_id); ERR
+
+ i234_dims[0] = D2_dim;
+ i234_dims[1] = D3_dim;
+ i234_dims[2] = D4_dim;
+ err=ncmpi_def_var(ncid, "i234", NC_INT, RANK_i234, i234_dims, &i234_id); ERR
+
+ f241_dims[0] = D2_dim;
+ f241_dims[1] = D4_dim;
+ f241_dims[2] = D1_dim;
+ err=ncmpi_def_var(ncid, "f241", NC_FLOAT, RANK_f241, f241_dims, &f241_id); ERR
+
+ d242_dims[0] = D2_dim;
+ d242_dims[1] = D4_dim;
+ d242_dims[2] = D2_dim;
+ err=ncmpi_def_var(ncid, "d242", NC_DOUBLE, RANK_d242, d242_dims, &d242_id); ERR
+
+ c243_dims[0] = D2_dim;
+ c243_dims[1] = D4_dim;
+ c243_dims[2] = D3_dim;
+ err=ncmpi_def_var(ncid, "c243", NC_CHAR, RANK_c243, c243_dims, &c243_id); ERR
+
+ b244_dims[0] = D2_dim;
+ b244_dims[1] = D4_dim;
+ b244_dims[2] = D4_dim;
+ err=ncmpi_def_var(ncid, "b244", NC_BYTE, RANK_b244, b244_dims, &b244_id); ERR
+
+ s311_dims[0] = D3_dim;
+ s311_dims[1] = D1_dim;
+ s311_dims[2] = D1_dim;
+ err=ncmpi_def_var(ncid, "s311", NC_SHORT, RANK_s311, s311_dims, &s311_id); ERR
+
+ i312_dims[0] = D3_dim;
+ i312_dims[1] = D1_dim;
+ i312_dims[2] = D2_dim;
+ err=ncmpi_def_var(ncid, "i312", NC_INT, RANK_i312, i312_dims, &i312_id); ERR
+
+ f313_dims[0] = D3_dim;
+ f313_dims[1] = D1_dim;
+ f313_dims[2] = D3_dim;
+ err=ncmpi_def_var(ncid, "f313", NC_FLOAT, RANK_f313, f313_dims, &f313_id); ERR
+
+ d314_dims[0] = D3_dim;
+ d314_dims[1] = D1_dim;
+ d314_dims[2] = D4_dim;
+ err=ncmpi_def_var(ncid, "d314", NC_DOUBLE, RANK_d314, d314_dims, &d314_id); ERR
+
+ c321_dims[0] = D3_dim;
+ c321_dims[1] = D2_dim;
+ c321_dims[2] = D1_dim;
+ err=ncmpi_def_var(ncid, "c321", NC_CHAR, RANK_c321, c321_dims, &c321_id); ERR
+
+ b322_dims[0] = D3_dim;
+ b322_dims[1] = D2_dim;
+ b322_dims[2] = D2_dim;
+ err=ncmpi_def_var(ncid, "b322", NC_BYTE, RANK_b322, b322_dims, &b322_id); ERR
+
+ s323_dims[0] = D3_dim;
+ s323_dims[1] = D2_dim;
+ s323_dims[2] = D3_dim;
+ err=ncmpi_def_var(ncid, "s323", NC_SHORT, RANK_s323, s323_dims, &s323_id); ERR
+
+ i324_dims[0] = D3_dim;
+ i324_dims[1] = D2_dim;
+ i324_dims[2] = D4_dim;
+ err=ncmpi_def_var(ncid, "i324", NC_INT, RANK_i324, i324_dims, &i324_id); ERR
+
+ f331_dims[0] = D3_dim;
+ f331_dims[1] = D3_dim;
+ f331_dims[2] = D1_dim;
+ err=ncmpi_def_var(ncid, "f331", NC_FLOAT, RANK_f331, f331_dims, &f331_id); ERR
+
+ d332_dims[0] = D3_dim;
+ d332_dims[1] = D3_dim;
+ d332_dims[2] = D2_dim;
+ err=ncmpi_def_var(ncid, "d332", NC_DOUBLE, RANK_d332, d332_dims, &d332_id); ERR
+
+ c333_dims[0] = D3_dim;
+ c333_dims[1] = D3_dim;
+ c333_dims[2] = D3_dim;
+ err=ncmpi_def_var(ncid, "c333", NC_CHAR, RANK_c333, c333_dims, &c333_id); ERR
+
+ b334_dims[0] = D3_dim;
+ b334_dims[1] = D3_dim;
+ b334_dims[2] = D4_dim;
+ err=ncmpi_def_var(ncid, "b334", NC_BYTE, RANK_b334, b334_dims, &b334_id); ERR
+
+ s341_dims[0] = D3_dim;
+ s341_dims[1] = D4_dim;
+ s341_dims[2] = D1_dim;
+ err=ncmpi_def_var(ncid, "s341", NC_SHORT, RANK_s341, s341_dims, &s341_id); ERR
+
+ i342_dims[0] = D3_dim;
+ i342_dims[1] = D4_dim;
+ i342_dims[2] = D2_dim;
+ err=ncmpi_def_var(ncid, "i342", NC_INT, RANK_i342, i342_dims, &i342_id); ERR
+
+ f343_dims[0] = D3_dim;
+ f343_dims[1] = D4_dim;
+ f343_dims[2] = D3_dim;
+ err=ncmpi_def_var(ncid, "f343", NC_FLOAT, RANK_f343, f343_dims, &f343_id); ERR
+
+ d344_dims[0] = D3_dim;
+ d344_dims[1] = D4_dim;
+ d344_dims[2] = D4_dim;
+ err=ncmpi_def_var(ncid, "d344", NC_DOUBLE, RANK_d344, d344_dims, &d344_id); ERR
+
+ c411_dims[0] = D4_dim;
+ c411_dims[1] = D1_dim;
+ c411_dims[2] = D1_dim;
+ err=ncmpi_def_var(ncid, "c411", NC_CHAR, RANK_c411, c411_dims, &c411_id); ERR
+
+ b412_dims[0] = D4_dim;
+ b412_dims[1] = D1_dim;
+ b412_dims[2] = D2_dim;
+ err=ncmpi_def_var(ncid, "b412", NC_BYTE, RANK_b412, b412_dims, &b412_id); ERR
+
+ s413_dims[0] = D4_dim;
+ s413_dims[1] = D1_dim;
+ s413_dims[2] = D3_dim;
+ err=ncmpi_def_var(ncid, "s413", NC_SHORT, RANK_s413, s413_dims, &s413_id); ERR
+
+ i414_dims[0] = D4_dim;
+ i414_dims[1] = D1_dim;
+ i414_dims[2] = D4_dim;
+ err=ncmpi_def_var(ncid, "i414", NC_INT, RANK_i414, i414_dims, &i414_id); ERR
+
+ f421_dims[0] = D4_dim;
+ f421_dims[1] = D2_dim;
+ f421_dims[2] = D1_dim;
+ err=ncmpi_def_var(ncid, "f421", NC_FLOAT, RANK_f421, f421_dims, &f421_id); ERR
+
+ d422_dims[0] = D4_dim;
+ d422_dims[1] = D2_dim;
+ d422_dims[2] = D2_dim;
+ err=ncmpi_def_var(ncid, "d422", NC_DOUBLE, RANK_d422, d422_dims, &d422_id); ERR
+
+ c423_dims[0] = D4_dim;
+ c423_dims[1] = D2_dim;
+ c423_dims[2] = D3_dim;
+ err=ncmpi_def_var(ncid, "c423", NC_CHAR, RANK_c423, c423_dims, &c423_id); ERR
+
+ b424_dims[0] = D4_dim;
+ b424_dims[1] = D2_dim;
+ b424_dims[2] = D4_dim;
+ err=ncmpi_def_var(ncid, "b424", NC_BYTE, RANK_b424, b424_dims, &b424_id); ERR
+
+ s431_dims[0] = D4_dim;
+ s431_dims[1] = D3_dim;
+ s431_dims[2] = D1_dim;
+ err=ncmpi_def_var(ncid, "s431", NC_SHORT, RANK_s431, s431_dims, &s431_id); ERR
+
+ i432_dims[0] = D4_dim;
+ i432_dims[1] = D3_dim;
+ i432_dims[2] = D2_dim;
+ err=ncmpi_def_var(ncid, "i432", NC_INT, RANK_i432, i432_dims, &i432_id); ERR
+
+ f433_dims[0] = D4_dim;
+ f433_dims[1] = D3_dim;
+ f433_dims[2] = D3_dim;
+ err=ncmpi_def_var(ncid, "f433", NC_FLOAT, RANK_f433, f433_dims, &f433_id); ERR
+
+ d434_dims[0] = D4_dim;
+ d434_dims[1] = D3_dim;
+ d434_dims[2] = D4_dim;
+ err=ncmpi_def_var(ncid, "d434", NC_DOUBLE, RANK_d434, d434_dims, &d434_id); ERR
+
+ c441_dims[0] = D4_dim;
+ c441_dims[1] = D4_dim;
+ c441_dims[2] = D1_dim;
+ err=ncmpi_def_var(ncid, "c441", NC_CHAR, RANK_c441, c441_dims, &c441_id); ERR
+
+ b442_dims[0] = D4_dim;
+ b442_dims[1] = D4_dim;
+ b442_dims[2] = D2_dim;
+ err=ncmpi_def_var(ncid, "b442", NC_BYTE, RANK_b442, b442_dims, &b442_id); ERR
+
+ s443_dims[0] = D4_dim;
+ s443_dims[1] = D4_dim;
+ s443_dims[2] = D3_dim;
+ err=ncmpi_def_var(ncid, "s443", NC_SHORT, RANK_s443, s443_dims, &s443_id); ERR
+
+ i444_dims[0] = D4_dim;
+ i444_dims[1] = D4_dim;
+ i444_dims[2] = D4_dim;
+ err=ncmpi_def_var(ncid, "i444", NC_INT, RANK_i444, i444_dims, &i444_id); ERR
+
+ /* assign global attributes */
+ { /* Gc */
+ err=ncmpi_put_att_text(ncid, NC_GLOBAL, "Gc", 1, "\177"); ERR
+ }
+ { /* Gb */
+ static const signed char Gb_att[2] = {-128, 127} ;
+ err=ncmpi_put_att_schar(ncid, NC_GLOBAL, "Gb", NC_BYTE, 2, Gb_att); ERR
+ }
+ { /* Gs */
+ static const short Gs_att[3] = {-32768, 32767, 32767} ;
+ err=ncmpi_put_att_short(ncid, NC_GLOBAL, "Gs", NC_SHORT, 3, Gs_att); ERR
+ }
+ { /* Gi */
+ static const int Gi_att[4] = {INT_MIN, INT_MAX, INT_MIN, INT_MIN} ;
+ err=ncmpi_put_att_int(ncid, NC_GLOBAL, "Gi", NC_INT, 4, Gi_att); ERR
+ }
+ { /* Gf */
+ static const float Gf_att[5] = {-3.4028231e+38, 3.4028231e+38, -9.96921e+36, 9.96921e+36, 531} ;
+ err=ncmpi_put_att_float(ncid, NC_GLOBAL, "Gf", NC_FLOAT, 5, Gf_att); ERR
+ }
+ { /* Gd */
+ static const double Gd_att[6] = {-42, 42, -1, 1, 660, 650} ;
+ err=ncmpi_put_att_double(ncid, NC_GLOBAL, "Gd", NC_DOUBLE, 6, Gd_att); ERR
+ }
+
+
+ /* assign per-variable attributes */
+ { /* c */
+ err=ncmpi_put_att_text(ncid, b_id, "c", 0, ""); ERR
+ }
+ { /* b */
+ static const signed char s_b_att[1] = {-128} ;
+ err=ncmpi_put_att_schar(ncid, s_id, "b", NC_BYTE, 1, s_b_att); ERR
+ }
+ { /* s */
+ static const short s_s_att[2] = {-32768, 32767} ;
+ err=ncmpi_put_att_short(ncid, s_id, "s", NC_SHORT, 2, s_s_att); ERR
+ }
+ { /* i */
+ static const int i_i_att[3] = {INT_MIN, 2147483647, INT_MIN} ;
+ err=ncmpi_put_att_int(ncid, i_id, "i", NC_INT, 3, i_i_att); ERR
+ }
+ { /* f */
+ static const float i_f_att[4] = {-3.4028231e+38, 3.4028231e+38, -9.96921e+36, 9.96921e+36} ;
+ err=ncmpi_put_att_float(ncid, i_id, "f", NC_FLOAT, 4, i_f_att); ERR
+ }
+ { /* d */
+ static const double i_d_att[5] = {-42, 42, -1, 1, 660} ;
+ err=ncmpi_put_att_double(ncid, i_id, "d", NC_DOUBLE, 5, i_d_att); ERR
+ }
+ { /* c */
+ err=ncmpi_put_att_text(ncid, d_id, "c", 6, "blahhh"); ERR
+ }
+
+ /* leave define mode */
+ err=ncmpi_enddef (ncid); ERR
+
+ err=ncmpi_begin_indep_data (ncid); ERR
+
+ /* assign variable data */
+ {
+ MPI_Offset zero = 0;
+ static char c_data[1] = {'\002'};
+ err=ncmpi_put_var1(ncid, c_id, &zero, c_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+ {
+ MPI_Offset zero = 0;
+ static signed char b_data[1] = {-2};
+ err=ncmpi_put_var1(ncid, b_id, &zero, b_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+ {
+ MPI_Offset zero = 0;
+ static short s_data[1] = {-5};
+ err=ncmpi_put_var1(ncid, s_id, &zero, s_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+ {
+ MPI_Offset zero = 0;
+ static int i_data[1] = {-20};
+ err=ncmpi_put_var1(ncid, i_id, &zero, i_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+ {
+ MPI_Offset zero = 0;
+ static float f_data[1] = {-9};
+ err=ncmpi_put_var1(ncid, f_id, &zero, f_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+ {
+ MPI_Offset zero = 0;
+ static double d_data[1] = {-10};
+ err=ncmpi_put_var1(ncid, d_id, &zero, d_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+ {
+ char cr_data[2] = "\177\177" ;
+ MPI_Offset cr_startset[1] = {0} ;
+ MPI_Offset cr_countset[1] = {2} ;
+ err=ncmpi_put_vara(ncid, cr_id, cr_startset, cr_countset, cr_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ signed char br_data[2] = {-128, 127} ;
+ MPI_Offset br_startset[1] = {0} ;
+ MPI_Offset br_countset[1] = {2} ;
+ err=ncmpi_put_vara(ncid, br_id, br_startset, br_countset, br_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ short sr_data[2] = {-32768, 32767} ;
+ MPI_Offset sr_startset[1] = {0} ;
+ MPI_Offset sr_countset[1] = {2} ;
+ err=ncmpi_put_vara(ncid, sr_id, sr_startset, sr_countset, sr_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ int ir_data[2] = {INT_MIN, 2147483647} ;
+ MPI_Offset ir_startset[1] = {0} ;
+ MPI_Offset ir_countset[1] = {2} ;
+ err=ncmpi_put_vara(ncid, ir_id, ir_startset, ir_countset, ir_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ float fr_data[2] = {-3.4028231e+38, 3.4028231e+38} ;
+ MPI_Offset fr_startset[1] = {0} ;
+ MPI_Offset fr_countset[1] = {2} ;
+ err=ncmpi_put_vara(ncid, fr_id, fr_startset, fr_countset, fr_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ double dr_data[2] = {-42, 42} ;
+ MPI_Offset dr_startset[1] = {0} ;
+ MPI_Offset dr_countset[1] = {2} ;
+ err=ncmpi_put_vara(ncid, dr_id, dr_startset, dr_countset, dr_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ char c1_data[1] = "\177" ;
+ MPI_Offset c1_startset[1] = {0} ;
+ MPI_Offset c1_countset[1] = {1} ;
+ err=ncmpi_put_vara(ncid, c1_id, c1_startset, c1_countset, c1_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ signed char b1_data[1] = {-128} ;
+ MPI_Offset b1_startset[1] = {0} ;
+ MPI_Offset b1_countset[1] = {1} ;
+ err=ncmpi_put_vara(ncid, b1_id, b1_startset, b1_countset, b1_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ short s1_data[1] = {-32768} ;
+ MPI_Offset s1_startset[1] = {0} ;
+ MPI_Offset s1_countset[1] = {1} ;
+ err=ncmpi_put_vara(ncid, s1_id, s1_startset, s1_countset, s1_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ int i1_data[1] = {INT_MIN} ;
+ MPI_Offset i1_startset[1] = {0} ;
+ MPI_Offset i1_countset[1] = {1} ;
+ err=ncmpi_put_vara(ncid, i1_id, i1_startset, i1_countset, i1_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ float f1_data[1] = {-3.4028231e+38} ;
+ MPI_Offset f1_startset[1] = {0} ;
+ MPI_Offset f1_countset[1] = {1} ;
+ err=ncmpi_put_vara(ncid, f1_id, f1_startset, f1_countset, f1_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ double d1_data[1] = {-42} ;
+ MPI_Offset d1_startset[1] = {0} ;
+ MPI_Offset d1_countset[1] = {1} ;
+ err=ncmpi_put_vara(ncid, d1_id, d1_startset, d1_countset, d1_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ char c2_data[2] = "\177\177" ;
+ MPI_Offset c2_startset[1] = {0} ;
+ MPI_Offset c2_countset[1] = {2} ;
+ err=ncmpi_put_vara(ncid, c2_id, c2_startset, c2_countset, c2_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ signed char b2_data[2] = {-128, 127} ;
+ MPI_Offset b2_startset[1] = {0} ;
+ MPI_Offset b2_countset[1] = {2} ;
+ err=ncmpi_put_vara(ncid, b2_id, b2_startset, b2_countset, b2_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ short s2_data[2] = {-32768, 32767} ;
+ MPI_Offset s2_startset[1] = {0} ;
+ MPI_Offset s2_countset[1] = {2} ;
+ err=ncmpi_put_vara(ncid, s2_id, s2_startset, s2_countset, s2_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ int i2_data[2] = {INT_MIN, 2147483647} ;
+ MPI_Offset i2_startset[1] = {0} ;
+ MPI_Offset i2_countset[1] = {2} ;
+ err=ncmpi_put_vara(ncid, i2_id, i2_startset, i2_countset, i2_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ float f2_data[2] = {-3.4028231e+38, 3.4028231e+38} ;
+ MPI_Offset f2_startset[1] = {0} ;
+ MPI_Offset f2_countset[1] = {2} ;
+ err=ncmpi_put_vara(ncid, f2_id, f2_startset, f2_countset, f2_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ double d2_data[2] = {-42, 42} ;
+ MPI_Offset d2_startset[1] = {0} ;
+ MPI_Offset d2_countset[1] = {2} ;
+ err=ncmpi_put_vara(ncid, d2_id, d2_startset, d2_countset, d2_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ char c3_data[3] = "\177\177A" ;
+ MPI_Offset c3_startset[1] = {0} ;
+ MPI_Offset c3_countset[1] = {3} ;
+ err=ncmpi_put_vara(ncid, c3_id, c3_startset, c3_countset, c3_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ signed char b3_data[3] = {-128, 127, 127} ;
+ MPI_Offset b3_startset[1] = {0} ;
+ MPI_Offset b3_countset[1] = {3} ;
+ err=ncmpi_put_vara(ncid, b3_id, b3_startset, b3_countset, b3_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ short s3_data[3] = {-32768, 32767, 32767} ;
+ MPI_Offset s3_startset[1] = {0} ;
+ MPI_Offset s3_countset[1] = {3} ;
+ err=ncmpi_put_vara(ncid, s3_id, s3_startset, s3_countset, s3_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ int i3_data[3] = {INT_MIN, 2147483647, INT_MIN} ;
+ MPI_Offset i3_startset[1] = {0} ;
+ MPI_Offset i3_countset[1] = {3} ;
+ err=ncmpi_put_vara(ncid, i3_id, i3_startset, i3_countset, i3_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ float f3_data[3] = {-3.4028231e+38, 3.4028231e+38, -9.96921e+36} ;
+ MPI_Offset f3_startset[1] = {0} ;
+ MPI_Offset f3_countset[1] = {3} ;
+ err=ncmpi_put_vara(ncid, f3_id, f3_startset, f3_countset, f3_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ double d3_data[3] = {-42, 42, -1} ;
+ MPI_Offset d3_startset[1] = {0} ;
+ MPI_Offset d3_countset[1] = {3} ;
+ err=ncmpi_put_vara(ncid, d3_id, d3_startset, d3_countset, d3_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ char c4_data[4] = "\177\177AZ" ;
+ MPI_Offset c4_startset[1] = {0} ;
+ MPI_Offset c4_countset[1] = {4} ;
+ err=ncmpi_put_vara(ncid, c4_id, c4_startset, c4_countset, c4_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ signed char b4_data[4] = {-128, 127, 127, -128} ;
+ MPI_Offset b4_startset[1] = {0} ;
+ MPI_Offset b4_countset[1] = {4} ;
+ err=ncmpi_put_vara(ncid, b4_id, b4_startset, b4_countset, b4_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ short s4_data[4] = {-32768, 32767, 32767, -32768} ;
+ MPI_Offset s4_startset[1] = {0} ;
+ MPI_Offset s4_countset[1] = {4} ;
+ err=ncmpi_put_vara(ncid, s4_id, s4_startset, s4_countset, s4_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ int i4_data[4] = {INT_MIN, 2147483647, INT_MIN, INT_MIN} ;
+ MPI_Offset i4_startset[1] = {0} ;
+ MPI_Offset i4_countset[1] = {4} ;
+ err=ncmpi_put_vara(ncid, i4_id, i4_startset, i4_countset, i4_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ float f4_data[4] = {-3.4028231e+38, 3.4028231e+38, -9.96921e+36, 9.96921e+36} ;
+ MPI_Offset f4_startset[1] = {0} ;
+ MPI_Offset f4_countset[1] = {4} ;
+ err=ncmpi_put_vara(ncid, f4_id, f4_startset, f4_countset, f4_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ double d4_data[4] = {-42, 42, -1, 1} ;
+ MPI_Offset d4_startset[1] = {0} ;
+ MPI_Offset d4_countset[1] = {4} ;
+ err=ncmpi_put_vara(ncid, d4_id, d4_startset, d4_countset, d4_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ char cr1_data[2] = "\030\034" ;
+ MPI_Offset cr1_startset[2] = {0, 0} ;
+ MPI_Offset cr1_countset[2] = {2, 1} ;
+ err=ncmpi_put_vara(ncid, cr1_id, cr1_startset, cr1_countset, cr1_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ signed char br2_data[4] = {-24, -26, -20, -22} ;
+ MPI_Offset br2_startset[2] = {0, 0} ;
+ MPI_Offset br2_countset[2] = {2, 2} ;
+ err=ncmpi_put_vara(ncid, br2_id, br2_startset, br2_countset, br2_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ short sr3_data[6] = {-375, -380, -385, -350, -355, -360} ;
+ MPI_Offset sr3_startset[2] = {0, 0} ;
+ MPI_Offset sr3_countset[2] = {2, 3} ;
+ err=ncmpi_put_vara(ncid, sr3_id, sr3_startset, sr3_countset, sr3_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ int ir4_data[8] = {-24000, -24020, -24040, -24060, -23600, -23620, -23640, -23660} ;
+ MPI_Offset ir4_startset[2] = {0, 0} ;
+ MPI_Offset ir4_countset[2] = {2, 4} ;
+ err=ncmpi_put_vara(ncid, ir4_id, ir4_startset, ir4_countset, ir4_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ float f11_data[1] = {-2187} ;
+ MPI_Offset f11_startset[2] = {0, 0} ;
+ MPI_Offset f11_countset[2] = {1, 1} ;
+ err=ncmpi_put_vara(ncid, f11_id, f11_startset, f11_countset, f11_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ double d12_data[2] = {-3000, -3010} ;
+ MPI_Offset d12_startset[2] = {0, 0} ;
+ MPI_Offset d12_countset[2] = {1, 2} ;
+ err=ncmpi_put_vara(ncid, d12_id, d12_startset, d12_countset, d12_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ char c13_data[3] = "\030\032\034" ;
+ MPI_Offset c13_startset[2] = {0, 0} ;
+ MPI_Offset c13_countset[2] = {1, 3} ;
+ err=ncmpi_put_vara(ncid, c13_id, c13_startset, c13_countset, c13_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ signed char b14_data[4] = {-24, -26, -28, -30} ;
+ MPI_Offset b14_startset[2] = {0, 0} ;
+ MPI_Offset b14_countset[2] = {1, 4} ;
+ err=ncmpi_put_vara(ncid, b14_id, b14_startset, b14_countset, b14_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ short s21_data[2] = {-375, -350} ;
+ MPI_Offset s21_startset[2] = {0, 0} ;
+ MPI_Offset s21_countset[2] = {2, 1} ;
+ err=ncmpi_put_vara(ncid, s21_id, s21_startset, s21_countset, s21_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ int i22_data[4] = {-24000, -24020, -23600, -23620} ;
+ MPI_Offset i22_startset[2] = {0, 0} ;
+ MPI_Offset i22_countset[2] = {2, 2} ;
+ err=ncmpi_put_vara(ncid, i22_id, i22_startset, i22_countset, i22_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ float f23_data[6] = {-2187, -2196, -2205, -2106, -2115, -2124} ;
+ MPI_Offset f23_startset[2] = {0, 0} ;
+ MPI_Offset f23_countset[2] = {2, 3} ;
+ err=ncmpi_put_vara(ncid, f23_id, f23_startset, f23_countset, f23_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ double d24_data[8] = {-3000, -3010, -3020, -3030, -2900, -2910, -2920, -2930} ;
+ MPI_Offset d24_startset[2] = {0, 0} ;
+ MPI_Offset d24_countset[2] = {2, 4} ;
+ err=ncmpi_put_vara(ncid, d24_id, d24_startset, d24_countset, d24_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ char c31_data[3] = "\030\034 " ;
+ MPI_Offset c31_startset[2] = {0, 0} ;
+ MPI_Offset c31_countset[2] = {3, 1} ;
+ err=ncmpi_put_vara(ncid, c31_id, c31_startset, c31_countset, c31_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ signed char b32_data[6] = {-24, -26, -20, -22, -16, -18} ;
+ MPI_Offset b32_startset[2] = {0, 0} ;
+ MPI_Offset b32_countset[2] = {3, 2} ;
+ err=ncmpi_put_vara(ncid, b32_id, b32_startset, b32_countset, b32_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ short s33_data[9] = {-375, -380, -385, -350, -355, -360, -325, -330, -335} ;
+ MPI_Offset s33_startset[2] = {0, 0} ;
+ MPI_Offset s33_countset[2] = {3, 3} ;
+ err=ncmpi_put_vara(ncid, s33_id, s33_startset, s33_countset, s33_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ int i34_data[12] = {-24000, -24020, -24040, -24060, -23600, -23620, -23640, -23660, -23200, -23220, -23240, -23260} ;
+ MPI_Offset i34_startset[2] = {0, 0} ;
+ MPI_Offset i34_countset[2] = {3, 4} ;
+ err=ncmpi_put_vara(ncid, i34_id, i34_startset, i34_countset, i34_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ float f41_data[4] = {-2187, -2106, -2025, -1944} ;
+ MPI_Offset f41_startset[2] = {0, 0} ;
+ MPI_Offset f41_countset[2] = {4, 1} ;
+ err=ncmpi_put_vara(ncid, f41_id, f41_startset, f41_countset, f41_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ double d42_data[8] = {-3000, -3010, -2900, -2910, -2800, -2810, -2700, -2710} ;
+ MPI_Offset d42_startset[2] = {0, 0} ;
+ MPI_Offset d42_countset[2] = {4, 2} ;
+ err=ncmpi_put_vara(ncid, d42_id, d42_startset, d42_countset, d42_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ char c43_data[12] = "\030\032\034\034\036 \"$$&(" ;
+ MPI_Offset c43_startset[2] = {0, 0} ;
+ MPI_Offset c43_countset[2] = {4, 3} ;
+ err=ncmpi_put_vara(ncid, c43_id, c43_startset, c43_countset, c43_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ signed char b44_data[16] = {-24, -26, -28, -30, -20, -22, -24, -26, -16, -18, -20, -22, -12, -14, -16, -18} ;
+ MPI_Offset b44_startset[2] = {0, 0} ;
+ MPI_Offset b44_countset[2] = {4, 4} ;
+ err=ncmpi_put_vara(ncid, b44_id, b44_startset, b44_countset, b44_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ short sr11_data[2] = {2500, 2375} ;
+ MPI_Offset sr11_startset[3] = {0, 0, 0} ;
+ MPI_Offset sr11_countset[3] = {2, 1, 1} ;
+ err=ncmpi_put_vara(ncid, sr11_id, sr11_startset, sr11_countset, sr11_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ int ir12_data[4] = {640000, 639980, 632000, 631980} ;
+ MPI_Offset ir12_startset[3] = {0, 0, 0} ;
+ MPI_Offset ir12_countset[3] = {2, 1, 2} ;
+ err=ncmpi_put_vara(ncid, ir12_id, ir12_startset, ir12_countset, ir12_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ float fr13_data[6] = {26244, 26235, 26226, 25515, 25506, 25497} ;
+ MPI_Offset fr13_startset[3] = {0, 0, 0} ;
+ MPI_Offset fr13_countset[3] = {2, 1, 3} ;
+ err=ncmpi_put_vara(ncid, fr13_id, fr13_startset, fr13_countset, fr13_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ double dr14_data[8] = {40000, 39990, 39980, 39970, 39000, 38990, 38980, 38970} ;
+ MPI_Offset dr14_startset[3] = {0, 0, 0} ;
+ MPI_Offset dr14_countset[3] = {2, 1, 4} ;
+ err=ncmpi_put_vara(ncid, dr14_id, dr14_startset, dr14_countset, dr14_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ char cr21_data[4] = "@DHL" ;
+ MPI_Offset cr21_startset[3] = {0, 0, 0} ;
+ MPI_Offset cr21_countset[3] = {2, 2, 1} ;
+ err=ncmpi_put_vara(ncid, cr21_id, cr21_startset, cr21_countset, cr21_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ signed char br22_data[8] = {64, 62, 68, 66, 56, 54, 60, 58} ;
+ MPI_Offset br22_startset[3] = {0, 0, 0} ;
+ MPI_Offset br22_countset[3] = {2, 2, 2} ;
+ err=ncmpi_put_vara(ncid, br22_id, br22_startset, br22_countset, br22_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ short sr23_data[12] = {2500, 2495, 2490, 2525, 2520, 2515, 2375, 2370, 2365, 2400, 2395, 2390} ;
+ MPI_Offset sr23_startset[3] = {0, 0, 0} ;
+ MPI_Offset sr23_countset[3] = {2, 2, 3} ;
+ err=ncmpi_put_vara(ncid, sr23_id, sr23_startset, sr23_countset, sr23_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ int ir24_data[16] = {640000, 639980, 639960, 639940, 640400, 640380, 640360, 640340, 632000, 631980, 631960, 631940, 632400, 632380, 632360, 632340} ;
+ MPI_Offset ir24_startset[3] = {0, 0, 0} ;
+ MPI_Offset ir24_countset[3] = {2, 2, 4} ;
+ err=ncmpi_put_vara(ncid, ir24_id, ir24_startset, ir24_countset, ir24_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ float fr31_data[6] = {26244, 26325, 26406, 25515, 25596, 25677} ;
+ MPI_Offset fr31_startset[3] = {0, 0, 0} ;
+ MPI_Offset fr31_countset[3] = {2, 3, 1} ;
+ err=ncmpi_put_vara(ncid, fr31_id, fr31_startset, fr31_countset, fr31_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ double dr32_data[12] = {40000, 39990, 40100, 40090, 40200, 40190, 39000, 38990, 39100, 39090, 39200, 39190} ;
+ MPI_Offset dr32_startset[3] = {0, 0, 0} ;
+ MPI_Offset dr32_countset[3] = {2, 3, 2} ;
+ err=ncmpi_put_vara(ncid, dr32_id, dr32_startset, dr32_countset, dr32_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ char cr33_data[18] = "@BDDFHHJLHJLLNPPRT" ;
+ MPI_Offset cr33_startset[3] = {0, 0, 0} ;
+ MPI_Offset cr33_countset[3] = {2, 3, 3} ;
+ err=ncmpi_put_vara(ncid, cr33_id, cr33_startset, cr33_countset, cr33_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ signed char br34_data[24] = {64, 62, 60, 58, 68, 66, 64, 62, 72, 70, 68, 66, 56, 54, 52, 50, 60, 58, 56, 54, 64, 62, 60, 58} ;
+ MPI_Offset br34_startset[3] = {0, 0, 0} ;
+ MPI_Offset br34_countset[3] = {2, 3, 4} ;
+ err=ncmpi_put_vara(ncid, br34_id, br34_startset, br34_countset, br34_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ short sr41_data[8] = {2500, 2525, 2550, 2575, 2375, 2400, 2425, 2450} ;
+ MPI_Offset sr41_startset[3] = {0, 0, 0} ;
+ MPI_Offset sr41_countset[3] = {2, 4, 1} ;
+ err=ncmpi_put_vara(ncid, sr41_id, sr41_startset, sr41_countset, sr41_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ int ir42_data[16] = {640000, 639980, 640400, 640380, 640800, 640780, 641200, 641180, 632000, 631980, 632400, 632380, 632800, 632780, 633200, 633180} ;
+ MPI_Offset ir42_startset[3] = {0, 0, 0} ;
+ MPI_Offset ir42_countset[3] = {2, 4, 2} ;
+ err=ncmpi_put_vara(ncid, ir42_id, ir42_startset, ir42_countset, ir42_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ float fr43_data[24] = {26244, 26235, 26226, 26325, 26316, 26307, 26406, 26397, 26388, 26487, 26478, 26469, 25515, 25506, 25497, 25596, 25587, 25578, 25677, 25668, 25659, 25758, 25749, 25740} ;
+ MPI_Offset fr43_startset[3] = {0, 0, 0} ;
+ MPI_Offset fr43_countset[3] = {2, 4, 3} ;
+ err=ncmpi_put_vara(ncid, fr43_id, fr43_startset, fr43_countset, fr43_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ double dr44_data[32] = {40000, 39990, 39980, 39970, 40100, 40090, 40080, 40070, 40200, 40190, 40180, 40170, 40300, 40290, 40280, 40270, 39000, 38990, 38980, 38970, 39100, 39090, 39080, 39070, 39200, 39190, 39180, 39170, 39300, 39290, 39280, 39270} ;
+ MPI_Offset dr44_startset[3] = {0, 0, 0} ;
+ MPI_Offset dr44_countset[3] = {2, 4, 4} ;
+ err=ncmpi_put_vara(ncid, dr44_id, dr44_startset, dr44_countset, dr44_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ char c111_data[1] = "@" ;
+ MPI_Offset c111_startset[3] = {0, 0, 0} ;
+ MPI_Offset c111_countset[3] = {1, 1, 1} ;
+ err=ncmpi_put_vara(ncid, c111_id, c111_startset, c111_countset, c111_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ signed char b112_data[2] = {64, 62} ;
+ MPI_Offset b112_startset[3] = {0, 0, 0} ;
+ MPI_Offset b112_countset[3] = {1, 1, 2} ;
+ err=ncmpi_put_vara(ncid, b112_id, b112_startset, b112_countset, b112_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ short s113_data[3] = {2500, 2495, 2490} ;
+ MPI_Offset s113_startset[3] = {0, 0, 0} ;
+ MPI_Offset s113_countset[3] = {1, 1, 3} ;
+ err=ncmpi_put_vara(ncid, s113_id, s113_startset, s113_countset, s113_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ int i114_data[4] = {640000, 639980, 639960, 639940} ;
+ MPI_Offset i114_startset[3] = {0, 0, 0} ;
+ MPI_Offset i114_countset[3] = {1, 1, 4} ;
+ err=ncmpi_put_vara(ncid, i114_id, i114_startset, i114_countset, i114_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ float f121_data[2] = {26244, 26325} ;
+ MPI_Offset f121_startset[3] = {0, 0, 0} ;
+ MPI_Offset f121_countset[3] = {1, 2, 1} ;
+ err=ncmpi_put_vara(ncid, f121_id, f121_startset, f121_countset, f121_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ double d122_data[4] = {40000, 39990, 40100, 40090} ;
+ MPI_Offset d122_startset[3] = {0, 0, 0} ;
+ MPI_Offset d122_countset[3] = {1, 2, 2} ;
+ err=ncmpi_put_vara(ncid, d122_id, d122_startset, d122_countset, d122_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ char c123_data[6] = "@BDDFH" ;
+ MPI_Offset c123_startset[3] = {0, 0, 0} ;
+ MPI_Offset c123_countset[3] = {1, 2, 3} ;
+ err=ncmpi_put_vara(ncid, c123_id, c123_startset, c123_countset, c123_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ signed char b124_data[8] = {64, 62, 60, 58, 68, 66, 64, 62} ;
+ MPI_Offset b124_startset[3] = {0, 0, 0} ;
+ MPI_Offset b124_countset[3] = {1, 2, 4} ;
+ err=ncmpi_put_vara(ncid, b124_id, b124_startset, b124_countset, b124_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ short s131_data[3] = {2500, 2525, 2550} ;
+ MPI_Offset s131_startset[3] = {0, 0, 0} ;
+ MPI_Offset s131_countset[3] = {1, 3, 1} ;
+ err=ncmpi_put_vara(ncid, s131_id, s131_startset, s131_countset, s131_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ int i132_data[6] = {640000, 639980, 640400, 640380, 640800, 640780} ;
+ MPI_Offset i132_startset[3] = {0, 0, 0} ;
+ MPI_Offset i132_countset[3] = {1, 3, 2} ;
+ err=ncmpi_put_vara(ncid, i132_id, i132_startset, i132_countset, i132_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ float f133_data[9] = {26244, 26235, 26226, 26325, 26316, 26307, 26406, 26397, 26388} ;
+ MPI_Offset f133_startset[3] = {0, 0, 0} ;
+ MPI_Offset f133_countset[3] = {1, 3, 3} ;
+ err=ncmpi_put_vara(ncid, f133_id, f133_startset, f133_countset, f133_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ double d134_data[12] = {40000, 39990, 39980, 39970, 40100, 40090, 40080, 40070, 40200, 40190, 40180, 40170} ;
+ MPI_Offset d134_startset[3] = {0, 0, 0} ;
+ MPI_Offset d134_countset[3] = {1, 3, 4} ;
+ err=ncmpi_put_vara(ncid, d134_id, d134_startset, d134_countset, d134_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ char c141_data[4] = "@DHL" ;
+ MPI_Offset c141_startset[3] = {0, 0, 0} ;
+ MPI_Offset c141_countset[3] = {1, 4, 1} ;
+ err=ncmpi_put_vara(ncid, c141_id, c141_startset, c141_countset, c141_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ signed char b142_data[8] = {64, 62, 68, 66, 72, 70, 76, 74} ;
+ MPI_Offset b142_startset[3] = {0, 0, 0} ;
+ MPI_Offset b142_countset[3] = {1, 4, 2} ;
+ err=ncmpi_put_vara(ncid, b142_id, b142_startset, b142_countset, b142_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ short s143_data[12] = {2500, 2495, 2490, 2525, 2520, 2515, 2550, 2545, 2540, 2575, 2570, 2565} ;
+ MPI_Offset s143_startset[3] = {0, 0, 0} ;
+ MPI_Offset s143_countset[3] = {1, 4, 3} ;
+ err=ncmpi_put_vara(ncid, s143_id, s143_startset, s143_countset, s143_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ int i144_data[16] = {640000, 639980, 639960, 639940, 640400, 640380, 640360, 640340, 640800, 640780, 640760, 640740, 641200, 641180, 641160, 641140} ;
+ MPI_Offset i144_startset[3] = {0, 0, 0} ;
+ MPI_Offset i144_countset[3] = {1, 4, 4} ;
+ err=ncmpi_put_vara(ncid, i144_id, i144_startset, i144_countset, i144_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ float f211_data[2] = {26244, 25515} ;
+ MPI_Offset f211_startset[3] = {0, 0, 0} ;
+ MPI_Offset f211_countset[3] = {2, 1, 1} ;
+ err=ncmpi_put_vara(ncid, f211_id, f211_startset, f211_countset, f211_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ double d212_data[4] = {40000, 39990, 39000, 38990} ;
+ MPI_Offset d212_startset[3] = {0, 0, 0} ;
+ MPI_Offset d212_countset[3] = {2, 1, 2} ;
+ err=ncmpi_put_vara(ncid, d212_id, d212_startset, d212_countset, d212_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ char c213_data[6] = "@BDHJL" ;
+ MPI_Offset c213_startset[3] = {0, 0, 0} ;
+ MPI_Offset c213_countset[3] = {2, 1, 3} ;
+ err=ncmpi_put_vara(ncid, c213_id, c213_startset, c213_countset, c213_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ signed char b214_data[8] = {64, 62, 60, 58, 56, 54, 52, 50} ;
+ MPI_Offset b214_startset[3] = {0, 0, 0} ;
+ MPI_Offset b214_countset[3] = {2, 1, 4} ;
+ err=ncmpi_put_vara(ncid, b214_id, b214_startset, b214_countset, b214_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ short s221_data[4] = {2500, 2525, 2375, 2400} ;
+ MPI_Offset s221_startset[3] = {0, 0, 0} ;
+ MPI_Offset s221_countset[3] = {2, 2, 1} ;
+ err=ncmpi_put_vara(ncid, s221_id, s221_startset, s221_countset, s221_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ int i222_data[8] = {640000, 639980, 640400, 640380, 632000, 631980, 632400, 632380} ;
+ MPI_Offset i222_startset[3] = {0, 0, 0} ;
+ MPI_Offset i222_countset[3] = {2, 2, 2} ;
+ err=ncmpi_put_vara(ncid, i222_id, i222_startset, i222_countset, i222_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ float f223_data[12] = {26244, 26235, 26226, 26325, 26316, 26307, 25515, 25506, 25497, 25596, 25587, 25578} ;
+ MPI_Offset f223_startset[3] = {0, 0, 0} ;
+ MPI_Offset f223_countset[3] = {2, 2, 3} ;
+ err=ncmpi_put_vara(ncid, f223_id, f223_startset, f223_countset, f223_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ double d224_data[16] = {40000, 39990, 39980, 39970, 40100, 40090, 40080, 40070, 39000, 38990, 38980, 38970, 39100, 39090, 39080, 39070} ;
+ MPI_Offset d224_startset[3] = {0, 0, 0} ;
+ MPI_Offset d224_countset[3] = {2, 2, 4} ;
+ err=ncmpi_put_vara(ncid, d224_id, d224_startset, d224_countset, d224_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ char c231_data[6] = "@DHHLP" ;
+ MPI_Offset c231_startset[3] = {0, 0, 0} ;
+ MPI_Offset c231_countset[3] = {2, 3, 1} ;
+ err=ncmpi_put_vara(ncid, c231_id, c231_startset, c231_countset, c231_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ signed char b232_data[12] = {64, 62, 68, 66, 72, 70, 56, 54, 60, 58, 64, 62} ;
+ MPI_Offset b232_startset[3] = {0, 0, 0} ;
+ MPI_Offset b232_countset[3] = {2, 3, 2} ;
+ err=ncmpi_put_vara(ncid, b232_id, b232_startset, b232_countset, b232_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ short s233_data[18] = {2500, 2495, 2490, 2525, 2520, 2515, 2550, 2545, 2540, 2375, 2370, 2365, 2400, 2395, 2390, 2425, 2420, 2415} ;
+ MPI_Offset s233_startset[3] = {0, 0, 0} ;
+ MPI_Offset s233_countset[3] = {2, 3, 3} ;
+ err=ncmpi_put_vara(ncid, s233_id, s233_startset, s233_countset, s233_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ int i234_data[24] = {640000, 639980, 639960, 639940, 640400, 640380, 640360, 640340, 640800, 640780, 640760, 640740, 632000, 631980, 631960, 631940, 632400, 632380, 632360, 632340, 632800, 632780, 632760, 632740} ;
+ MPI_Offset i234_startset[3] = {0, 0, 0} ;
+ MPI_Offset i234_countset[3] = {2, 3, 4} ;
+ err=ncmpi_put_vara(ncid, i234_id, i234_startset, i234_countset, i234_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ float f241_data[8] = {26244, 26325, 26406, 26487, 25515, 25596, 25677, 25758} ;
+ MPI_Offset f241_startset[3] = {0, 0, 0} ;
+ MPI_Offset f241_countset[3] = {2, 4, 1} ;
+ err=ncmpi_put_vara(ncid, f241_id, f241_startset, f241_countset, f241_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ double d242_data[16] = {40000, 39990, 40100, 40090, 40200, 40190, 40300, 40290, 39000, 38990, 39100, 39090, 39200, 39190, 39300, 39290} ;
+ MPI_Offset d242_startset[3] = {0, 0, 0} ;
+ MPI_Offset d242_countset[3] = {2, 4, 2} ;
+ err=ncmpi_put_vara(ncid, d242_id, d242_startset, d242_countset, d242_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ char c243_data[24] = "@BDDFHHJLLNPHJLLNPPRTTVX" ;
+ MPI_Offset c243_startset[3] = {0, 0, 0} ;
+ MPI_Offset c243_countset[3] = {2, 4, 3} ;
+ err=ncmpi_put_vara(ncid, c243_id, c243_startset, c243_countset, c243_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ signed char b244_data[32] = {64, 62, 60, 58, 68, 66, 64, 62, 72, 70, 68, 66, 76, 74, 72, 70, 56, 54, 52, 50, 60, 58, 56, 54, 64, 62, 60, 58, 68, 66, 64, 62} ;
+ MPI_Offset b244_startset[3] = {0, 0, 0} ;
+ MPI_Offset b244_countset[3] = {2, 4, 4} ;
+ err=ncmpi_put_vara(ncid, b244_id, b244_startset, b244_countset, b244_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ short s311_data[3] = {2500, 2375, 2250} ;
+ MPI_Offset s311_startset[3] = {0, 0, 0} ;
+ MPI_Offset s311_countset[3] = {3, 1, 1} ;
+ err=ncmpi_put_vara(ncid, s311_id, s311_startset, s311_countset, s311_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ int i312_data[6] = {640000, 639980, 632000, 631980, 624000, 623980} ;
+ MPI_Offset i312_startset[3] = {0, 0, 0} ;
+ MPI_Offset i312_countset[3] = {3, 1, 2} ;
+ err=ncmpi_put_vara(ncid, i312_id, i312_startset, i312_countset, i312_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ float f313_data[9] = {26244, 26235, 26226, 25515, 25506, 25497, 24786, 24777, 24768} ;
+ MPI_Offset f313_startset[3] = {0, 0, 0} ;
+ MPI_Offset f313_countset[3] = {3, 1, 3} ;
+ err=ncmpi_put_vara(ncid, f313_id, f313_startset, f313_countset, f313_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ double d314_data[12] = {40000, 39990, 39980, 39970, 39000, 38990, 38980, 38970, 38000, 37990, 37980, 37970} ;
+ MPI_Offset d314_startset[3] = {0, 0, 0} ;
+ MPI_Offset d314_countset[3] = {3, 1, 4} ;
+ err=ncmpi_put_vara(ncid, d314_id, d314_startset, d314_countset, d314_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ char c321_data[6] = "@DHLPT" ;
+ MPI_Offset c321_startset[3] = {0, 0, 0} ;
+ MPI_Offset c321_countset[3] = {3, 2, 1} ;
+ err=ncmpi_put_vara(ncid, c321_id, c321_startset, c321_countset, c321_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ signed char b322_data[12] = {64, 62, 68, 66, 56, 54, 60, 58, 48, 46, 52, 50} ;
+ MPI_Offset b322_startset[3] = {0, 0, 0} ;
+ MPI_Offset b322_countset[3] = {3, 2, 2} ;
+ err=ncmpi_put_vara(ncid, b322_id, b322_startset, b322_countset, b322_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ short s323_data[18] = {2500, 2495, 2490, 2525, 2520, 2515, 2375, 2370, 2365, 2400, 2395, 2390, 2250, 2245, 2240, 2275, 2270, 2265} ;
+ MPI_Offset s323_startset[3] = {0, 0, 0} ;
+ MPI_Offset s323_countset[3] = {3, 2, 3} ;
+ err=ncmpi_put_vara(ncid, s323_id, s323_startset, s323_countset, s323_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ int i324_data[24] = {640000, 639980, 639960, 639940, 640400, 640380, 640360, 640340, 632000, 631980, 631960, 631940, 632400, 632380, 632360, 632340, 624000, 623980, 623960, 623940, 624400, 624380, 624360, 624340} ;
+ MPI_Offset i324_startset[3] = {0, 0, 0} ;
+ MPI_Offset i324_countset[3] = {3, 2, 4} ;
+ err=ncmpi_put_vara(ncid, i324_id, i324_startset, i324_countset, i324_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ float f331_data[9] = {26244, 26325, 26406, 25515, 25596, 25677, 24786, 24867, 24948} ;
+ MPI_Offset f331_startset[3] = {0, 0, 0} ;
+ MPI_Offset f331_countset[3] = {3, 3, 1} ;
+ err=ncmpi_put_vara(ncid, f331_id, f331_startset, f331_countset, f331_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ double d332_data[18] = {40000, 39990, 40100, 40090, 40200, 40190, 39000, 38990, 39100, 39090, 39200, 39190, 38000, 37990, 38100, 38090, 38200, 38190} ;
+ MPI_Offset d332_startset[3] = {0, 0, 0} ;
+ MPI_Offset d332_countset[3] = {3, 3, 2} ;
+ err=ncmpi_put_vara(ncid, d332_id, d332_startset, d332_countset, d332_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ char c333_data[27] = "@BDDFHHJLHJLLNPPRTPRTTVXXZ\\" ;
+ MPI_Offset c333_startset[3] = {0, 0, 0} ;
+ MPI_Offset c333_countset[3] = {3, 3, 3} ;
+ err=ncmpi_put_vara(ncid, c333_id, c333_startset, c333_countset, c333_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ signed char b334_data[36] = {64, 62, 60, 58, 68, 66, 64, 62, 72, 70, 68, 66, 56, 54, 52, 50, 60, 58, 56, 54, 64, 62, 60, 58, 48, 46, 44, 42, 52, 50, 48, 46, 56, 54, 52, 50} ;
+ MPI_Offset b334_startset[3] = {0, 0, 0} ;
+ MPI_Offset b334_countset[3] = {3, 3, 4} ;
+ err=ncmpi_put_vara(ncid, b334_id, b334_startset, b334_countset, b334_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ short s341_data[12] = {2500, 2525, 2550, 2575, 2375, 2400, 2425, 2450, 2250, 2275, 2300, 2325} ;
+ MPI_Offset s341_startset[3] = {0, 0, 0} ;
+ MPI_Offset s341_countset[3] = {3, 4, 1} ;
+ err=ncmpi_put_vara(ncid, s341_id, s341_startset, s341_countset, s341_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ int i342_data[24] = {640000, 639980, 640400, 640380, 640800, 640780, 641200, 641180, 632000, 631980, 632400, 632380, 632800, 632780, 633200, 633180, 624000, 623980, 624400, 624380, 624800, 624780, 625200, 625180} ;
+ MPI_Offset i342_startset[3] = {0, 0, 0} ;
+ MPI_Offset i342_countset[3] = {3, 4, 2} ;
+ err=ncmpi_put_vara(ncid, i342_id, i342_startset, i342_countset, i342_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ float f343_data[36] = {26244, 26235, 26226, 26325, 26316, 26307, 26406, 26397, 26388, 26487, 26478, 26469, 25515, 25506, 25497, 25596, 25587, 25578, 25677, 25668, 25659, 25758, 25749, 25740, 24786, 24777, 24768, 24867, 24858, 24849, 24948, 24939, 24930, 25029, 25020, 25011} ;
+ MPI_Offset f343_startset[3] = {0, 0, 0} ;
+ MPI_Offset f343_countset[3] = {3, 4, 3} ;
+ err=ncmpi_put_vara(ncid, f343_id, f343_startset, f343_countset, f343_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ double d344_data[48] = {40000, 39990, 39980, 39970, 40100, 40090, 40080, 40070, 40200, 40190, 40180, 40170, 40300, 40290, 40280, 40270, 39000, 38990, 38980, 38970, 39100, 39090, 39080, 39070, 39200, 39190, 39180, 39170, 39300, 39290, 39280, 39270, 38000, 37990, 37980, 37970, 38100, 38090, 38080, 38070, 38200, 38190, 38180, 38170, 38300, 38290, 38280, 38270} ;
+ MPI_Offset d344_startset[3] = {0, 0, 0} ;
+ MPI_Offset d344_countset[3] = {3, 4, 4} ;
+ err=ncmpi_put_vara(ncid, d344_id, d344_startset, d344_countset, d344_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ char c411_data[4] = "@HPX" ;
+ MPI_Offset c411_startset[3] = {0, 0, 0} ;
+ MPI_Offset c411_countset[3] = {4, 1, 1} ;
+ err=ncmpi_put_vara(ncid, c411_id, c411_startset, c411_countset, c411_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ signed char b412_data[8] = {64, 62, 56, 54, 48, 46, 40, 38} ;
+ MPI_Offset b412_startset[3] = {0, 0, 0} ;
+ MPI_Offset b412_countset[3] = {4, 1, 2} ;
+ err=ncmpi_put_vara(ncid, b412_id, b412_startset, b412_countset, b412_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ short s413_data[12] = {2500, 2495, 2490, 2375, 2370, 2365, 2250, 2245, 2240, 2125, 2120, 2115} ;
+ MPI_Offset s413_startset[3] = {0, 0, 0} ;
+ MPI_Offset s413_countset[3] = {4, 1, 3} ;
+ err=ncmpi_put_vara(ncid, s413_id, s413_startset, s413_countset, s413_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ int i414_data[16] = {640000, 639980, 639960, 639940, 632000, 631980, 631960, 631940, 624000, 623980, 623960, 623940, 616000, 615980, 615960, 615940} ;
+ MPI_Offset i414_startset[3] = {0, 0, 0} ;
+ MPI_Offset i414_countset[3] = {4, 1, 4} ;
+ err=ncmpi_put_vara(ncid, i414_id, i414_startset, i414_countset, i414_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ float f421_data[8] = {26244, 26325, 25515, 25596, 24786, 24867, 24057, 24138} ;
+ MPI_Offset f421_startset[3] = {0, 0, 0} ;
+ MPI_Offset f421_countset[3] = {4, 2, 1} ;
+ err=ncmpi_put_vara(ncid, f421_id, f421_startset, f421_countset, f421_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ double d422_data[16] = {40000, 39990, 40100, 40090, 39000, 38990, 39100, 39090, 38000, 37990, 38100, 38090, 37000, 36990, 37100, 37090} ;
+ MPI_Offset d422_startset[3] = {0, 0, 0} ;
+ MPI_Offset d422_countset[3] = {4, 2, 2} ;
+ err=ncmpi_put_vara(ncid, d422_id, d422_startset, d422_countset, d422_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ char c423_data[24] = "@BDDFHHJLLNPPRTTVXXZ\\\\^`" ;
+ MPI_Offset c423_startset[3] = {0, 0, 0} ;
+ MPI_Offset c423_countset[3] = {4, 2, 3} ;
+ err=ncmpi_put_vara(ncid, c423_id, c423_startset, c423_countset, c423_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ signed char b424_data[32] = {64, 62, 60, 58, 68, 66, 64, 62, 56, 54, 52, 50, 60, 58, 56, 54, 48, 46, 44, 42, 52, 50, 48, 46, 40, 38, 36, 34, 44, 42, 40, 38} ;
+ MPI_Offset b424_startset[3] = {0, 0, 0} ;
+ MPI_Offset b424_countset[3] = {4, 2, 4} ;
+ err=ncmpi_put_vara(ncid, b424_id, b424_startset, b424_countset, b424_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ short s431_data[12] = {2500, 2525, 2550, 2375, 2400, 2425, 2250, 2275, 2300, 2125, 2150, 2175} ;
+ MPI_Offset s431_startset[3] = {0, 0, 0} ;
+ MPI_Offset s431_countset[3] = {4, 3, 1} ;
+ err=ncmpi_put_vara(ncid, s431_id, s431_startset, s431_countset, s431_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ int i432_data[24] = {640000, 639980, 640400, 640380, 640800, 640780, 632000, 631980, 632400, 632380, 632800, 632780, 624000, 623980, 624400, 624380, 624800, 624780, 616000, 615980, 616400, 616380, 616800, 616780} ;
+ MPI_Offset i432_startset[3] = {0, 0, 0} ;
+ MPI_Offset i432_countset[3] = {4, 3, 2} ;
+ err=ncmpi_put_vara(ncid, i432_id, i432_startset, i432_countset, i432_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ float f433_data[36] = {26244, 26235, 26226, 26325, 26316, 26307, 26406, 26397, 26388, 25515, 25506, 25497, 25596, 25587, 25578, 25677, 25668, 25659, 24786, 24777, 24768, 24867, 24858, 24849, 24948, 24939, 24930, 24057, 24048, 24039, 24138, 24129, 24120, 24219, 24210, 24201} ;
+ MPI_Offset f433_startset[3] = {0, 0, 0} ;
+ MPI_Offset f433_countset[3] = {4, 3, 3} ;
+ err=ncmpi_put_vara(ncid, f433_id, f433_startset, f433_countset, f433_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ double d434_data[48] = {40000, 39990, 39980, 39970, 40100, 40090, 40080, 40070, 40200, 40190, 40180, 40170, 39000, 38990, 38980, 38970, 39100, 39090, 39080, 39070, 39200, 39190, 39180, 39170, 38000, 37990, 37980, 37970, 38100, 38090, 38080, 38070, 38200, 38190, 38180, 38170, 37000, 36990, 36980, 36970, 37100, 37090, 37080, 37070, 37200, 37190, 37180, 37170} ;
+ MPI_Offset d434_startset[3] = {0, 0, 0} ;
+ MPI_Offset d434_countset[3] = {4, 3, 4} ;
+ err=ncmpi_put_vara(ncid, d434_id, d434_startset, d434_countset, d434_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ char c441_data[16] = "@DHLHLPTPTX\\X\\`d" ;
+ MPI_Offset c441_startset[3] = {0, 0, 0} ;
+ MPI_Offset c441_countset[3] = {4, 4, 1} ;
+ err=ncmpi_put_vara(ncid, c441_id, c441_startset, c441_countset, c441_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ signed char b442_data[32] = {64, 62, 68, 66, 72, 70, 76, 74, 56, 54, 60, 58, 64, 62, 68, 66, 48, 46, 52, 50, 56, 54, 60, 58, 40, 38, 44, 42, 48, 46, 52, 50} ;
+ MPI_Offset b442_startset[3] = {0, 0, 0} ;
+ MPI_Offset b442_countset[3] = {4, 4, 2} ;
+ err=ncmpi_put_vara(ncid, b442_id, b442_startset, b442_countset, b442_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ short s443_data[48] = {2500, 2495, 2490, 2525, 2520, 2515, 2550, 2545, 2540, 2575, 2570, 2565, 2375, 2370, 2365, 2400, 2395, 2390, 2425, 2420, 2415, 2450, 2445, 2440, 2250, 2245, 2240, 2275, 2270, 2265, 2300, 2295, 2290, 2325, 2320, 2315, 2125, 2120, 2115, 2150, 2145, 2140, 2175, 2170, 2165, 2200, 2195, 2190} ;
+ MPI_Offset s443_startset[3] = {0, 0, 0} ;
+ MPI_Offset s443_countset[3] = {4, 4, 3} ;
+ err=ncmpi_put_vara(ncid, s443_id, s443_startset, s443_countset, s443_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+ {
+ int i444_data[64] = {640000, 639980, 639960, 639940, 640400, 640380, 640360, 640340, 640800, 640780, 640760, 640740, 641200, 641180, 641160, 641140, 632000, 631980, 631960, 631940, 632400, 632380, 632360, 632340, 632800, 632780, 632760, 632740, 633200, 633180, 633160, 633140, 624000, 623980, 623960, 623940, 624400, 624380, 624360, 624340, 624800, 624780, 624760, 624740, 625200, 625180, 625160, 625140, 616000, 615980, 615960, 615940, 616400, 616380, 616360, 616340, 616800, 616780, 616 [...]
+ MPI_Offset i444_startset[3] = {0, 0, 0} ;
+ MPI_Offset i444_countset[3] = {4, 4, 4} ;
+ err=ncmpi_put_vara(ncid, i444_id, i444_startset, i444_countset, i444_data, 0,MPI_DATATYPE_NULL); ERR
+ }
+
+
+ err=ncmpi_close(ncid); ERR
+ return 0;
+
+}
+
+static int
+tst_atts(char *filename, int cmode)
+{
+ int err;
+
+ if (verbose) printf("\n*** Testing netCDF attributes.\n");
+ if (verbose) printf("*** testing attribute renaming for memory leak, like ncmpi_test...");
+ {
+#define A1_NAME "a"
+#define B1_NAME "b"
+#define VAR_NAME "var"
+
+ int ncid, nvars, v, natts, varid;
+ char name_in[NC_MAX_NAME + 1];
+ char char_data = 'a';
+
+ /* Create a file with a var with two atts. */
+ err=ncmpi_create(MPI_COMM_WORLD, filename, cmode, MPI_INFO_NULL, &ncid); ERR
+ err=ncmpi_def_var(ncid, VAR_NAME, NC_INT, 0, NULL, &varid); ERR
+ err=ncmpi_put_att(ncid, varid, A1_NAME, NC_CHAR, 1, &char_data); ERR
+ err=ncmpi_put_att(ncid, varid, B1_NAME, NC_CHAR, 1, &char_data); ERR
+
+ /* Add a global attribute A1_NAME. */
+ err=ncmpi_put_att(ncid, NC_GLOBAL, A1_NAME, NC_CHAR, 1, &char_data); ERR
+
+ /* Change the name of the first att of each variable to
+ * A1_NAME. Then copy the global att called A1_NAME, overwriting
+ * the one we just changed. */
+ err=ncmpi_inq_nvars(ncid, &nvars); ERR
+ if (nvars != 1) ERRV
+ err=ncmpi_inq_varnatts(ncid, 0, &natts); ERR
+ if (natts != 2) ERRV
+ err=ncmpi_copy_att(ncid, NC_GLOBAL, A1_NAME, ncid, 0); ERR
+
+ /* Also test for fix of another bug, allowing invalid _FillValue
+ * attribute (not of same type as variable or with 0 values or more
+ * than 1 value) to be created. */
+ {
+ static const int var_FillValue_atts[] = {42, -99} ;
+ float var_FillValue_att = -99 ;
+ /* This should return error, because attribute has too many values */
+ if ((err=ncmpi_put_att_int(ncid, varid, "_FillValue", NC_INT, 2, var_FillValue_atts)) != NC_EINVAL) ERR
+ /* This also should return error, because types don't match */
+ if ((err=ncmpi_put_att_float(ncid, varid, "_FillValue", NC_FLOAT, 1, &var_FillValue_att)) != NC_EBADTYPE) ERR
+ /* This should succeed, _FillValue is valid */
+ err=ncmpi_put_att_int(ncid, varid, "_FillValue", NC_INT, 1, var_FillValue_atts); ERR
+ }
+
+ err=ncmpi_close(ncid); ERR
+
+ /* Reopen the file and check it. */
+ err=ncmpi_open(MPI_COMM_WORLD, filename, NC_WRITE, MPI_INFO_NULL, &ncid); ERR
+ err=ncmpi_inq_nvars(ncid, &nvars); ERR
+ if (nvars != 1) ERRV
+ for (v = 0; v < nvars; v++)
+ {
+ err=ncmpi_inq_varnatts(ncid, v, &natts); ERR
+ if (natts)
+ {
+ err=ncmpi_inq_attname(ncid, v, 0, name_in); ERR
+ if (strcmp(name_in, A1_NAME)) ERRV
+ }
+ }
+ err=ncmpi_close(ncid); ERR
+
+ }
+ if (verbose) printf("ok\n");
+ if (verbose) printf("*** testing attribute renaming for memory leak, like ncmpi_test...");
+ {
+#define NVARS 136
+#define A_NAME "a"
+ int ncid, nvars, v, natts;
+ char name_in[NC_MAX_NAME + 1];
+ char char_data = 'a';
+
+ /* Create the same file as ncmpi_test uses (almost). */
+ if (create_file(filename, cmode)) ERRV
+
+ /* Open the file. */
+ err=ncmpi_open(MPI_COMM_WORLD, filename, NC_WRITE, MPI_INFO_NULL, &ncid); ERR
+ err=ncmpi_redef(ncid); ERR
+
+ /* Add a global attribute A_NAME. */
+ err=ncmpi_put_att(ncid, NC_GLOBAL, A_NAME, NC_CHAR, 1, &char_data); ERR
+
+ /* Change the name of the first att of each variable to
+ * A_NAME. Then copy the global att called A_NAME, overwriting
+ * the one we just changed. */
+ err=ncmpi_inq_nvars(ncid, &nvars); ERR
+ if (nvars != NVARS) ERRV
+ for (v = 0; v < nvars; v++)
+ {
+ err=ncmpi_inq_varnatts(ncid, v, &natts); ERR
+ if (natts)
+ {
+ err=ncmpi_inq_attname(ncid, v, 0, name_in); ERR
+ err=ncmpi_rename_att(ncid, v, name_in, A_NAME); ERR
+ err=ncmpi_copy_att(ncid, NC_GLOBAL, A_NAME, ncid, v); ERR
+ }
+ }
+ err=ncmpi_close(ncid); ERR
+
+ /* Reopen the file and check it. */
+ err=ncmpi_open(MPI_COMM_WORLD, filename, NC_WRITE, MPI_INFO_NULL, &ncid); ERR
+ err=ncmpi_inq_nvars(ncid, &nvars); ERR
+ if (nvars != NVARS) ERRV
+ for (v = 0; v < nvars; v++)
+ {
+ err=ncmpi_inq_varnatts(ncid, v, &natts); ERR
+ if (natts)
+ {
+ err=ncmpi_inq_attname(ncid, v, 0, name_in); ERR
+ if (strcmp(name_in, A_NAME)) ERRV
+ }
+ }
+ err=ncmpi_close(ncid); ERR
+
+ }
+ if (verbose) printf("ok\n");
+ return 0;
+}
+
+int main(int argc, char *argv[])
+{
+ char filename[256];
+ int cmode, rank, nprocs, err, nerrs=0;
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+
+ if (argc > 2) {
+ if (!rank) printf("Usage: %s [filename]\n",argv[0]);
+ MPI_Finalize();
+ return 0;
+ }
+ strcpy(filename, "testfile.nc");
+ if (argc == 2) strcpy(filename, argv[1]);
+ MPI_Bcast(filename, 256, MPI_CHAR, 0, MPI_COMM_WORLD);
+
+ char cmd_str[256];
+ sprintf(cmd_str, "*** TESTING C %s for emulating netCDF tst_atts ", argv[0]);
+ if (rank == 0) printf("%-66s ------ ", cmd_str);
+
+ verbose = 0;
+
+ cmode = NC_CLOBBER;
+ nerrs += tst_atts(filename, cmode);
+
+ cmode = NC_CLOBBER | NC_64BIT_OFFSET;
+ nerrs += tst_atts(filename, cmode);
+
+ cmode = NC_CLOBBER | NC_64BIT_DATA;
+ nerrs += tst_atts(filename, cmode);
+
+ MPI_Allreduce(MPI_IN_PLACE, &nerrs, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
+
+ /* check if PnetCDF freed all internal malloc */
+ MPI_Offset malloc_size, sum_size;
+ err = ncmpi_inq_malloc_size(&malloc_size);
+ if (err == NC_NOERR) {
+ MPI_Reduce(&malloc_size, &sum_size, 1, MPI_OFFSET, MPI_SUM, 0, MPI_COMM_WORLD);
+ if (rank == 0 && sum_size > 0)
+ printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n",
+ sum_size);
+ }
+
+ if (rank == 0) {
+ if (nerrs) printf(FAIL_STR,nerrs);
+ else printf(PASS_STR);
+ }
+
+ MPI_Finalize();
+ return 0;
+}
+
diff --git a/test/nc_test/tst_atts3.c b/test/nc_test/tst_atts3.c
new file mode 100644
index 0000000..1bf2ddc
--- /dev/null
+++ b/test/nc_test/tst_atts3.c
@@ -0,0 +1,804 @@
+/*
+ * Copyright (C) 2014, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ */
+/* $Id: tst_atts3.c 2219 2015-12-11 22:30:03Z wkliao $ */
+
+/* This program is based on the test program tst_atts3.c of the netCDF package */
+
+/* This is part of the netCDF package. Copyright 2005-2007 University
+ Corporation for Atmospheric Research/Unidata. See COPYRIGHT file
+ for conditions of use.
+
+ Test attributes.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <pnetcdf.h>
+#include <signal.h>
+
+#include <testutils.h>
+
+#define ERR {if (err != NC_NOERR) {printf("Error at %s line %d: %s\n",__func__,__LINE__,ncmpi_strerror(err)); nerrs++;}}
+#define ERRV {printf("Unexpected result at %s line %d\n",__func__,__LINE__); nerrs++;}
+static int verbose;
+
+#define VAR1_NAME "Horace_Rumpole"
+#define VAR2_NAME "Claude_Erskine-Brown"
+#define VAR3_NAME "Phillida_Erskine-Brown_Q.C."
+#define DIM1_NAME "Old_Bailey_case_number"
+#define DIM1_LEN 10
+#define DIM2_NAME "occupancy_in_chambers"
+#define DIM2_LEN 15
+#define ATT_INT_NAME "Old_Bailey_Room_Numbers"
+#define ATT_DOUBLE_NAME "Equity_Court_Canteen_Charges"
+#define ATT_SHORT_NAME "Ecclesiastical_Court_Appearences"
+#define ATT_TEXT_NAME "Speech_to_Jury"
+#define ATT_TEXT_NAME2 "Speech_to_She_Who_Must_be_Obeyed"
+#define ATT_UCHAR_NAME "Number_of_current_briefs"
+#define ATT_SCHAR_NAME "Slate_totals_at_Pomeroys_Wine_Bar"
+#define ATT_USHORT_NAME "brief_no"
+#define ATT_UINT_NAME "Orders_from_SWMBO"
+#define ATT_INT64_NAME "judges_golf_score"
+#define ATT_UINT64_NAME "Number_of_drinks_in_career_to_date"
+
+/*
+#define ATT_USHORT_NAME "Chamber_Gas_Electric_and_Telephone_Bill_Share"
+*/
+#define ATT_FLOAT_NAME "Average_Nanoseconds_for_Lose_Win_or_Appeal"
+#define ATT_LEN 3
+
+char speech[] = "Once more unto the breach, dear friends, once more;\n\
+Or close the wall up with our English dead.\n\
+In peace there's nothing so becomes a man\n\
+As modest stillness and humility:\n\
+But when the blast of war blows in our ears,\n\
+Then imitate the action of the tiger;\n\
+Stiffen the sinews, summon up the blood,\n\
+Disguise fair nature with hard-favour'd rage;\n\
+Then lend the eye a terrible aspect;\n\
+Let pry through the portage of the head\n\
+Like the brass cannon; let the brow o'erwhelm it\n\
+As fearfully as doth a galled rock\n\
+O'erhang and jutty his confounded base,\n\
+Swill'd with the wild and wasteful ocean.\n\
+Now set the teeth and stretch the nostril wide,\n\
+Hold hard the breath and bend up every spirit\n\
+To his full height. On, on, you noblest English.\n\
+Whose blood is fet from fathers of war-proof!\n\
+Fathers that, like so many Alexanders,\n\
+Have in these parts from morn till even fought\n\
+And sheathed their swords for lack of argument:\n\
+Dishonour not your mothers; now attest\n\
+That those whom you call'd fathers did beget you.\n\
+Be copy now to men of grosser blood,\n\
+And teach them how to war. And you, good yeoman,\n\
+Whose limbs were made in England, show us here\n\
+The mettle of your pasture; let us swear\n\
+That you are worth your breeding; which I doubt not;\n\
+For there is none of you so mean and base,\n\
+That hath not noble lustre in your eyes.\n\
+I see you stand like greyhounds in the slips,\n\
+Straining upon the start. The game's afoot:\n\
+Follow your spirit, and upon this charge\n\
+Cry 'God for Harry, England, and Saint George!'";
+
+/* Test the ordering of atts for a cmode. */
+#define NUM_ATTS 8
+#define ATT_MAX_NAME 25
+static int
+tst_att_ordering(char *filename, int cmode)
+{
+ int ncid, err, nerrs=0;
+ char name[NUM_ATTS][ATT_MAX_NAME + 1] = {"Gc", "Gb", "Gs", "Gi", "Gf",
+ "Gd", "Gatt-name-dashes", "Gatt.name.dots"};
+ int len[NUM_ATTS] = {0, 2, 3, 3, 3, 3, 1, 1};
+ signed char b[2] = {-128, 127};
+ short s[3] = {-32768, 0, 32767};
+ int i[3] = {42, 0, -42};
+ float f[3] = {42.0, -42.0, 42.0};
+ double d[3] = {420.0, -420.0, 420.0};
+ int att_name_dashes = -1, att_name_dots = -2;
+ char name_in[NC_MAX_NAME];
+ int j;
+
+ /* Create a file with some global atts. */
+ err=ncmpi_create(MPI_COMM_WORLD, filename, cmode, MPI_INFO_NULL,&ncid); ERR
+ err=ncmpi_put_att_text(ncid, NC_GLOBAL, name[0], len[0], NULL); ERR
+ err=ncmpi_put_att_schar(ncid, NC_GLOBAL, name[1], NC_BYTE, len[1], b); ERR
+ err=ncmpi_put_att_short(ncid, NC_GLOBAL, name[2], NC_SHORT, len[2], s); ERR
+ err=ncmpi_put_att_int(ncid, NC_GLOBAL, name[3], NC_INT, len[3], i); ERR
+ err=ncmpi_put_att_float(ncid, NC_GLOBAL, name[4], NC_FLOAT, len[4], f); ERR
+ err=ncmpi_put_att_double(ncid, NC_GLOBAL, name[5], NC_DOUBLE, len[5], d); ERR
+ err=ncmpi_put_att_int(ncid, NC_GLOBAL, name[6], NC_INT, len[6], &att_name_dashes); ERR
+ err=ncmpi_put_att_int(ncid, NC_GLOBAL, name[7], NC_INT, len[7], &att_name_dots); ERR
+ err=ncmpi_close(ncid); ERR
+
+ /* Reopen the file and check the order. */
+ err=ncmpi_open(MPI_COMM_WORLD, filename, NC_NOWRITE, MPI_INFO_NULL, &ncid); ERR
+ for (j = 0; j < NUM_ATTS; j++)
+ {
+ err=ncmpi_inq_attname(ncid, NC_GLOBAL, j, name_in); ERR
+ if (strcmp(name_in, name[j])) ERRV
+ }
+
+ /* Close up shop. */
+ err=ncmpi_close(ncid); ERR
+ return nerrs;
+}
+
+static int
+tst_atts3(char *filename, int cmode)
+{
+ char filename2[128];
+ int err, nerrs=0;
+ signed char schar_in[ATT_LEN], schar_out[ATT_LEN] = {NC_MIN_BYTE, 1, NC_MAX_BYTE};
+ unsigned char uchar_in[ATT_LEN];
+ short short_in[ATT_LEN], short_out[ATT_LEN] = {NC_MIN_SHORT, -128, NC_MAX_SHORT};
+ int int_in[ATT_LEN], int_out[ATT_LEN] = {-100000, 128, 100000};
+ float float_in[ATT_LEN], float_out[ATT_LEN] = {-0.5, 0.25, 0.125};
+ double double_in[ATT_LEN], double_out[ATT_LEN] = {-0.25, .5, 0.125};
+ long long longlong_in[ATT_LEN] = {-1LL, -1LL, -1LL};
+#ifdef USE_NETCDF4
+ long long_in[ATT_LEN];
+ unsigned short ushort_in[ATT_LEN], ushort_out[ATT_LEN] = {0, 128, NC_MAX_USHORT};
+ unsigned int uint_in[ATT_LEN], uint_out[ATT_LEN] = {0, 128, NC_MAX_UINT};
+ long long longlong_out[ATT_LEN] = {-3123456789LL, 128LL, 3123456789LL};
+ unsigned long long ulonglong_in[ATT_LEN] = {NC_MAX_UINT64, NC_MAX_UINT64, NC_MAX_UINT64};
+ unsigned long long ulonglong_out[ATT_LEN] = {0LL, 128LL, 3123456789LL};
+#endif
+
+ (void) signal(SIGFPE, SIG_IGN);
+
+ sprintf(filename2, "%s.2", filename);
+
+ if (verbose) printf("\n*** Testing netcdf-3 attribute functions.\n");
+ if (verbose) printf("*** testing really simple global atts...");
+#define NUM_SIMPLE_ATTS 9
+ {
+ int ncid;
+ char name[NUM_SIMPLE_ATTS][ATT_MAX_NAME + 1] = {"Gc", "Gb", "Gs", "Gi", "Gf",
+ "Gd", "G7", "G8", "G9"};
+ char name_in[NC_MAX_NAME];
+ int j;
+
+ /* Create a file with some global atts. */
+ err=ncmpi_create(MPI_COMM_WORLD, filename, cmode, MPI_INFO_NULL,&ncid); ERR
+ for (j = 0; j < NUM_SIMPLE_ATTS; j++)
+ err=ncmpi_put_att_int(ncid, NC_GLOBAL, name[j], NC_INT, 0, NULL); ERR
+ err=ncmpi_close(ncid); ERR
+
+ /* Reopen the file and check the order. */
+ err=ncmpi_open(MPI_COMM_WORLD, filename, NC_NOWRITE, MPI_INFO_NULL, &ncid); ERR
+ for (j = 0; j < NUM_SIMPLE_ATTS; j++)
+ {
+ err=ncmpi_inq_attname(ncid, NC_GLOBAL, j, name_in); ERR
+ if (strcmp(name_in, name[j])) ERRV
+ }
+
+ /* Close up shop. */
+ err=ncmpi_close(ncid); ERR
+ }
+ if (verbose) printf("ok\n");
+ if (verbose) printf("*** testing simple global atts...");
+ {
+ int ncid;
+ nc_type att_type;
+ MPI_Offset att_len;
+ int i;
+
+ char *speech_in;
+
+ /* This won't work, because classic files can't create these types. */
+ err=ncmpi_create(MPI_COMM_WORLD, filename, cmode, MPI_INFO_NULL,&ncid); ERR
+ err=ncmpi_put_att_int(ncid, NC_GLOBAL, ATT_INT_NAME, NC_INT, ATT_LEN, int_out); ERR
+ /* It is also OK to read classic types converted into
+ * supported C types. though the conversion may encounter
+ * out-of-range values */
+ if ((err=ncmpi_get_att_uchar(ncid, NC_GLOBAL, ATT_INT_NAME, uchar_in)) != NC_ERANGE) ERR
+ for (i = 0; i < ATT_LEN; i++) {
+ if (i == 0 || i == 2) continue;
+ if (uchar_in[i] != (unsigned char) int_out[i]) ERRV
+ }
+
+ /* This was bug NCF-171: on 32-bit platforms, bad values returned */
+ err=ncmpi_get_att_longlong(ncid, NC_GLOBAL, ATT_INT_NAME, longlong_in); ERR
+ for (i = 0; i < ATT_LEN; i++)
+ if (longlong_in[i] != (long long) int_out[i]) ERRV
+ err=ncmpi_close(ncid); ERR
+
+ /* Create a file with a global attribute of each type. */
+ err=ncmpi_create(MPI_COMM_WORLD, filename, cmode, MPI_INFO_NULL,&ncid); ERR
+ err=ncmpi_put_att_text(ncid, NC_GLOBAL, ATT_TEXT_NAME, strlen(speech)+1, speech); ERR
+ err=ncmpi_put_att_schar(ncid, NC_GLOBAL, ATT_SCHAR_NAME, NC_BYTE, ATT_LEN, schar_out); ERR
+ err=ncmpi_put_att_short(ncid, NC_GLOBAL, ATT_SHORT_NAME, NC_SHORT, ATT_LEN, short_out); ERR
+ err=ncmpi_put_att_int(ncid, NC_GLOBAL, ATT_INT_NAME, NC_INT, ATT_LEN, int_out); ERR
+ err=ncmpi_put_att_float(ncid, NC_GLOBAL, ATT_FLOAT_NAME, NC_FLOAT, ATT_LEN, float_out); ERR
+ err=ncmpi_put_att_double(ncid, NC_GLOBAL, ATT_DOUBLE_NAME, NC_DOUBLE, ATT_LEN, double_out); ERR
+ err=ncmpi_close(ncid); ERR
+
+ /* Open the file and check attributes. */
+ err=ncmpi_open(MPI_COMM_WORLD, filename, NC_NOWRITE, MPI_INFO_NULL, &ncid); ERR
+ /* Check text. */
+ err=ncmpi_inq_att(ncid, NC_GLOBAL, ATT_TEXT_NAME, &att_type, &att_len); ERR
+ if (att_type != NC_CHAR || att_len != strlen(speech) + 1) ERRV
+ if (!(speech_in = malloc(att_len + 1))) ERRV
+ err=ncmpi_get_att_text(ncid, NC_GLOBAL, ATT_TEXT_NAME, speech_in); ERR
+ if (strcmp(speech, speech_in)) ERRV
+ free(speech_in);
+ /* Check numeric values. */
+ err=ncmpi_get_att_schar(ncid, NC_GLOBAL, ATT_SCHAR_NAME, schar_in); ERR
+ for (i = 0; i < ATT_LEN; i++)
+ if (schar_in[i] != schar_out[i]) ERRV
+ err=ncmpi_get_att_short(ncid, NC_GLOBAL, ATT_SHORT_NAME, short_in); ERR
+ for (i = 0; i < ATT_LEN; i++)
+ if (short_in[i] != short_out[i]) ERRV
+ err=ncmpi_get_att_int(ncid, NC_GLOBAL, ATT_INT_NAME, int_in); ERR
+ for (i = 0; i < ATT_LEN; i++)
+ if (int_in[i] != int_out[i]) ERRV
+ err=ncmpi_get_att_float(ncid, NC_GLOBAL, ATT_FLOAT_NAME, float_in); ERR
+ for (i = 0; i < ATT_LEN; i++)
+ if (float_in[i] != float_out[i]) ERRV
+ err=ncmpi_get_att_double(ncid, NC_GLOBAL, ATT_DOUBLE_NAME, double_in); ERR
+ for (i = 0; i < ATT_LEN; i++)
+ if (double_in[i] != double_out[i]) ERRV
+ err=ncmpi_close(ncid); ERR
+ }
+ if (verbose) printf("ok\n");
+ if (verbose) printf("*** testing attribute data type conversions...");
+
+ {
+ int ncid;
+ int i;
+
+ /* Reopen the file and try different type conversions. */
+ err=ncmpi_open(MPI_COMM_WORLD, filename, NC_NOWRITE, MPI_INFO_NULL, &ncid); ERR
+ /* No text conversions are allowed, and people who try them should
+ * be locked up, away from decent folk! */
+ if ((err=ncmpi_get_att_short(ncid, NC_GLOBAL, ATT_TEXT_NAME, short_in)) != NC_ECHAR) ERR
+ if ((err=ncmpi_get_att_int(ncid, NC_GLOBAL, ATT_TEXT_NAME, int_in)) != NC_ECHAR) ERR
+ if ((err=ncmpi_get_att_float(ncid, NC_GLOBAL, ATT_TEXT_NAME, float_in)) != NC_ECHAR) ERR
+ if ((err=ncmpi_get_att_double(ncid, NC_GLOBAL, ATT_TEXT_NAME, double_in)) != NC_ECHAR) ERR
+
+ /* Read all atts (except text) as double. */
+ err=ncmpi_get_att_double(ncid, NC_GLOBAL, ATT_SCHAR_NAME, double_in); ERR
+ for (i = 0; i < ATT_LEN; i++)
+ if (double_in[i] != schar_out[i]) ERRV
+ err=ncmpi_get_att_double(ncid, NC_GLOBAL, ATT_SHORT_NAME, double_in); ERR
+ for (i = 0; i < ATT_LEN; i++)
+ if (double_in[i] != short_out[i]) ERRV
+ err=ncmpi_get_att_double(ncid, NC_GLOBAL, ATT_INT_NAME, double_in); ERR
+ for (i = 0; i < ATT_LEN; i++)
+ if (double_in[i] != int_out[i]) ERRV
+ err=ncmpi_get_att_double(ncid, NC_GLOBAL, ATT_FLOAT_NAME, double_in); ERR
+ for (i = 0; i < ATT_LEN; i++)
+ if (double_in[i] != float_out[i]) ERRV
+ err=ncmpi_get_att_double(ncid, NC_GLOBAL, ATT_DOUBLE_NAME, double_in); ERR
+ for (i = 0; i < ATT_LEN; i++)
+ if (double_in[i] != double_out[i]) ERRV
+
+ /* Read all atts (except text) as float. */
+ err=ncmpi_get_att_float(ncid, NC_GLOBAL, ATT_SCHAR_NAME, float_in); ERR
+ for (i = 0; i < ATT_LEN; i++)
+ if (float_in[i] != schar_out[i]) ERRV
+ err=ncmpi_get_att_float(ncid, NC_GLOBAL, ATT_SHORT_NAME, float_in); ERR
+ for (i = 0; i < ATT_LEN; i++)
+ if (float_in[i] != short_out[i]) ERRV
+ err=ncmpi_get_att_float(ncid, NC_GLOBAL, ATT_INT_NAME, float_in); ERR
+ for (i = 0; i < ATT_LEN; i++)
+ if (float_in[i] != int_out[i]) ERRV
+ err=ncmpi_get_att_float(ncid, NC_GLOBAL, ATT_FLOAT_NAME, float_in); ERR
+ for (i = 0; i < ATT_LEN; i++)
+ if (float_in[i] != float_out[i]) ERRV
+ err=ncmpi_get_att_float(ncid, NC_GLOBAL, ATT_DOUBLE_NAME, float_in); ERR
+ for (i = 0; i < ATT_LEN; i++)
+ if (float_in[i] != (float) double_out[i]) ERRV
+
+ /* Read all atts (except text) as int. */
+ err=ncmpi_get_att_int(ncid, NC_GLOBAL, ATT_SCHAR_NAME, int_in); ERR
+ for (i = 0; i < ATT_LEN; i++)
+ if (int_in[i] != schar_out[i]) ERRV
+ err=ncmpi_get_att_int(ncid, NC_GLOBAL, ATT_SHORT_NAME, int_in); ERR
+ for (i = 0; i < ATT_LEN; i++)
+ if (int_in[i] != short_out[i]) ERRV
+ err=ncmpi_get_att_int(ncid, NC_GLOBAL, ATT_INT_NAME, int_in); ERR
+ for (i = 0; i < ATT_LEN; i++)
+ if (int_in[i] != int_out[i]) ERRV
+ err=ncmpi_get_att_int(ncid, NC_GLOBAL, ATT_FLOAT_NAME, int_in); ERR
+ for (i = 0; i < ATT_LEN; i++)
+ if (int_in[i] != (int) float_out[i]) ERRV
+ err=ncmpi_get_att_int(ncid, NC_GLOBAL, ATT_DOUBLE_NAME, int_in); ERR
+ for (i = 0; i < ATT_LEN; i++)
+ if (int_in[i] != (int) double_out[i]) ERRV
+
+ /* Read all atts (except text) as short. */
+ err=ncmpi_get_att_short(ncid, NC_GLOBAL, ATT_SCHAR_NAME, short_in); ERR
+ for (i = 0; i < ATT_LEN; i++)
+ if (short_in[i] != schar_out[i]) ERRV
+ err=ncmpi_get_att_short(ncid, NC_GLOBAL, ATT_SHORT_NAME, short_in); ERR
+ for (i = 0; i < ATT_LEN; i++)
+ if (short_in[i] != short_out[i]) ERRV
+ if ((err=ncmpi_get_att_short(ncid, NC_GLOBAL, ATT_INT_NAME, short_in)) != NC_ERANGE) ERR
+ for (i = 0; i < ATT_LEN; i++) {
+ if (i == 0 || i == 2) continue;
+ if (short_in[i] != (short) int_out[i]) ERRV
+ }
+ err=ncmpi_get_att_short(ncid, NC_GLOBAL, ATT_FLOAT_NAME, short_in); ERR
+ for (i = 0; i < ATT_LEN; i++)
+ if (short_in[i] != (short) float_out[i]) ERRV
+ err=ncmpi_get_att_short(ncid, NC_GLOBAL, ATT_DOUBLE_NAME, short_in); ERR
+ for (i = 0; i < ATT_LEN; i++)
+ if (short_in[i] != (short) double_out[i]) ERRV
+
+ /* Read all atts (except text) as schar. */
+ err=ncmpi_get_att_schar(ncid, NC_GLOBAL, ATT_SCHAR_NAME, schar_in); ERR
+ for (i = 0; i < ATT_LEN; i++)
+ if (schar_in[i] != schar_out[i]) ERRV
+ if ((err=ncmpi_get_att_schar(ncid, NC_GLOBAL, ATT_SHORT_NAME, schar_in)) != NC_ERANGE) ERR
+ for (i = 0; i < ATT_LEN; i++) {
+ if (i == 0 || i == 2) continue;
+ if (schar_in[i] != (signed char) short_out[i]) ERRV
+ }
+ if ((err=ncmpi_get_att_schar(ncid, NC_GLOBAL, ATT_INT_NAME, schar_in)) != NC_ERANGE) ERR
+ for (i = 0; i < ATT_LEN; i++) {
+ if (i == 0 || i == 2) continue;
+ if (schar_in[i] != (signed char) int_out[i]) ERRV
+ }
+ err=ncmpi_get_att_schar(ncid, NC_GLOBAL, ATT_FLOAT_NAME, schar_in); ERR
+ for (i = 0; i < ATT_LEN; i++)
+ if (schar_in[i] != (signed char) float_out[i]) ERRV
+ err=ncmpi_get_att_schar(ncid, NC_GLOBAL, ATT_DOUBLE_NAME, schar_in); ERR
+ for (i = 0; i < ATT_LEN; i++)
+ if (schar_in[i] != (signed char) double_out[i]) ERRV
+
+ /* Read all atts (except text) as uchar. */
+ err=ncmpi_get_att_uchar(ncid, NC_GLOBAL, ATT_SCHAR_NAME, uchar_in); ERR
+ for (i = 0; i < ATT_LEN; i++)
+ if (uchar_in[i] != (unsigned char) schar_out[i]) ERRV
+ if ((err=ncmpi_get_att_uchar(ncid, NC_GLOBAL, ATT_SHORT_NAME, uchar_in)) != NC_ERANGE) ERR
+/*
+ for (i = 0; i < ATT_LEN; i++)
+ if (uchar_in[i] != (unsigned char) short_out[i]) ERRV
+*/
+ if ((err=ncmpi_get_att_uchar(ncid, NC_GLOBAL, ATT_INT_NAME, uchar_in)) != NC_ERANGE) ERR
+ for (i = 0; i < ATT_LEN; i++) {
+ if (i == 0 || i == 2) continue;
+ if (uchar_in[i] != (unsigned char) int_out[i]) ERRV
+ }
+ if ((err=ncmpi_get_att_uchar(ncid, NC_GLOBAL, ATT_FLOAT_NAME, uchar_in)) != NC_ERANGE) ERR
+ for (i = 0; i < ATT_LEN; i++) {
+ if (i == 0) continue;
+ if (uchar_in[i] != (unsigned char) float_out[i]) ERRV
+ }
+ if ((err=ncmpi_get_att_uchar(ncid, NC_GLOBAL, ATT_DOUBLE_NAME, uchar_in)) != NC_ERANGE) ERR
+ for (i = 0; i < ATT_LEN; i++) {
+ if (i == 0) continue;
+ if (uchar_in[i] != (unsigned char) double_out[i]) ERRV
+ }
+
+ /* Read all atts (except text) into long long variable. */
+ err=ncmpi_get_att_longlong(ncid, NC_GLOBAL, ATT_SCHAR_NAME, longlong_in); ERR
+ for (i = 0; i < ATT_LEN; i++)
+ if (longlong_in[i] != schar_out[i]) ERRV
+ err=ncmpi_get_att_longlong(ncid, NC_GLOBAL, ATT_SHORT_NAME, longlong_in); ERR
+ for (i = 0; i < ATT_LEN; i++)
+ if (longlong_in[i] != short_out[i]) ERRV
+ err=ncmpi_get_att_longlong(ncid, NC_GLOBAL, ATT_INT_NAME, longlong_in); ERR
+ /* This was bug NCF-171: on 32-bit platforms, bad values returned */
+ err=ncmpi_get_att_longlong(ncid, NC_GLOBAL, ATT_INT_NAME, longlong_in); ERR
+ for (i = 0; i < ATT_LEN; i++)
+ if (longlong_in[i] != (long long) int_out[i]) ERRV
+ err=ncmpi_get_att_longlong(ncid, NC_GLOBAL, ATT_FLOAT_NAME, longlong_in); ERR
+ for (i = 0; i < ATT_LEN; i++)
+ if (longlong_in[i] != (long long)float_out[i]) ERRV
+ err=ncmpi_get_att_longlong(ncid, NC_GLOBAL, ATT_DOUBLE_NAME, longlong_in); ERR
+ for (i = 0; i < ATT_LEN; i++)
+ if (longlong_in[i] != (long long)double_out[i]) ERRV
+
+ err=ncmpi_close(ncid); ERR
+ }
+ if (verbose) printf("ok\n");
+ if (verbose) printf("*** testing zero-length attributes...");
+ {
+ int ncid;
+
+ /*int int_in[ATT_LEN], int_out[ATT_LEN] = {NC_MIN_INT, 128, NC_MAX_INT};*/
+
+ /* Create a file with a global attribute of each type of zero length. */
+ err=ncmpi_create(MPI_COMM_WORLD, filename, cmode, MPI_INFO_NULL,&ncid); ERR
+ err=ncmpi_put_att_text(ncid, NC_GLOBAL, ATT_TEXT_NAME, 0, NULL); ERR
+ err=ncmpi_put_att_schar(ncid, NC_GLOBAL, ATT_SCHAR_NAME, NC_BYTE, 0, NULL); ERR
+ err=ncmpi_put_att_short(ncid, NC_GLOBAL, ATT_SHORT_NAME, NC_SHORT, 0, NULL); ERR
+ err=ncmpi_put_att_int(ncid, NC_GLOBAL, ATT_INT_NAME, NC_INT, 0, NULL); ERR
+ err=ncmpi_put_att_float(ncid, NC_GLOBAL, ATT_FLOAT_NAME, NC_FLOAT, 0, NULL); ERR
+ err=ncmpi_put_att_double(ncid, NC_GLOBAL, ATT_DOUBLE_NAME, NC_DOUBLE, 0, NULL); ERR
+ err=ncmpi_close(ncid); ERR
+ }
+
+ /* Make sure we can read all these zero-length atts. */
+ {
+ int ncid;
+ signed char schar_in[ATT_LEN];
+ short short_in[ATT_LEN];
+ /*int int_in[ATT_LEN], int_out[ATT_LEN] = {NC_MIN_INT, 128, NC_MAX_INT};*/
+ int int_in[ATT_LEN];
+ float float_in[ATT_LEN];
+ double double_in[ATT_LEN];
+ MPI_Offset len;
+ nc_type xtype;
+
+ err=ncmpi_open(MPI_COMM_WORLD, filename, NC_NOWRITE, MPI_INFO_NULL, &ncid); ERR
+ err=ncmpi_get_att_text(ncid, NC_GLOBAL, ATT_TEXT_NAME, NULL); ERR
+ err=ncmpi_inq_att(ncid, NC_GLOBAL, ATT_TEXT_NAME, &xtype, &len); ERR
+ if (len || xtype != NC_CHAR) ERRV
+ err=ncmpi_get_att_schar(ncid, NC_GLOBAL, ATT_SCHAR_NAME, schar_in); ERR
+ err=ncmpi_inq_att(ncid, NC_GLOBAL, ATT_SCHAR_NAME, &xtype, &len); ERR
+ if (len || xtype != NC_BYTE) ERRV
+ err=ncmpi_get_att_short(ncid, NC_GLOBAL, ATT_SHORT_NAME, short_in); ERR
+ err=ncmpi_inq_att(ncid, NC_GLOBAL, ATT_SHORT_NAME, &xtype, &len); ERR
+ if (len || xtype != NC_SHORT) ERRV
+ err=ncmpi_get_att_int(ncid, NC_GLOBAL, ATT_INT_NAME, int_in); ERR
+ err=ncmpi_inq_att(ncid, NC_GLOBAL, ATT_INT_NAME, &xtype, &len); ERR
+ if (len || xtype != NC_INT) ERRV
+ err=ncmpi_get_att_float(ncid, NC_GLOBAL, ATT_FLOAT_NAME, float_in); ERR
+ err=ncmpi_inq_att(ncid, NC_GLOBAL, ATT_FLOAT_NAME, &xtype, &len); ERR
+ if (len || xtype != NC_FLOAT) ERRV
+ err=ncmpi_get_att_double(ncid, NC_GLOBAL, ATT_DOUBLE_NAME, double_in); ERR
+ err=ncmpi_inq_att(ncid, NC_GLOBAL, ATT_DOUBLE_NAME, &xtype, &len); ERR
+ if (len || xtype != NC_DOUBLE) ERRV
+ /* Conversions no longer result in range errors, since there's no data. */
+ err=ncmpi_get_att_schar(ncid, NC_GLOBAL, ATT_DOUBLE_NAME, schar_in); ERR
+ err=ncmpi_get_att_schar(ncid, NC_GLOBAL, ATT_FLOAT_NAME, schar_in); ERR
+ err=ncmpi_get_att_schar(ncid, NC_GLOBAL, ATT_INT_NAME, schar_in); ERR
+ err=ncmpi_get_att_schar(ncid, NC_GLOBAL, ATT_SHORT_NAME, schar_in); ERR
+ err=ncmpi_close(ncid); ERR
+ }
+
+ if (verbose) printf("ok\n");
+ if (verbose) printf("*** testing zero-length attributes and redef...");
+ {
+ int ncid;
+ signed char schar_in[ATT_LEN];
+ short short_in[ATT_LEN];
+ int int_in[ATT_LEN];
+ float float_in[ATT_LEN];
+ double double_in[ATT_LEN];
+
+
+ /* Create a file with a global attribute of each type of zero length. */
+ err=ncmpi_create(MPI_COMM_WORLD, filename, cmode, MPI_INFO_NULL,&ncid); ERR
+ err=ncmpi_enddef(ncid); ERR
+ err=ncmpi_redef(ncid); ERR
+ err=ncmpi_put_att_text(ncid, NC_GLOBAL, ATT_TEXT_NAME, 0, NULL); ERR
+ err=ncmpi_put_att_schar(ncid, NC_GLOBAL, ATT_SCHAR_NAME, NC_BYTE, 0, NULL); ERR
+ err=ncmpi_put_att_short(ncid, NC_GLOBAL, ATT_SHORT_NAME, NC_SHORT, 0, NULL); ERR
+ err=ncmpi_put_att_int(ncid, NC_GLOBAL, ATT_INT_NAME, NC_INT, 0, NULL); ERR
+ err=ncmpi_put_att_float(ncid, NC_GLOBAL, ATT_FLOAT_NAME, NC_FLOAT, 0, NULL); ERR
+ err=ncmpi_put_att_double(ncid, NC_GLOBAL, ATT_DOUBLE_NAME, NC_DOUBLE, 0, NULL); ERR
+ err=ncmpi_close(ncid); ERR
+
+ /* Make sure we can read all these zero-length atts added during a
+ * redef. */
+ err=ncmpi_open(MPI_COMM_WORLD, filename, NC_NOWRITE, MPI_INFO_NULL, &ncid); ERR
+ err=ncmpi_get_att_text(ncid, NC_GLOBAL, ATT_TEXT_NAME, NULL); ERR
+ err=ncmpi_get_att_schar(ncid, NC_GLOBAL, ATT_SCHAR_NAME, schar_in); ERR
+ err=ncmpi_get_att_short(ncid, NC_GLOBAL, ATT_SHORT_NAME, short_in); ERR
+ err=ncmpi_get_att_int(ncid, NC_GLOBAL, ATT_INT_NAME, int_in); ERR
+ err=ncmpi_get_att_float(ncid, NC_GLOBAL, ATT_FLOAT_NAME, float_in); ERR
+ err=ncmpi_get_att_double(ncid, NC_GLOBAL, ATT_DOUBLE_NAME, double_in); ERR
+ /* Conversions no longer result in range errors, since there's no data. */
+ err=ncmpi_get_att_schar(ncid, NC_GLOBAL, ATT_DOUBLE_NAME, schar_in); ERR
+ err=ncmpi_get_att_schar(ncid, NC_GLOBAL, ATT_FLOAT_NAME, schar_in); ERR
+ err=ncmpi_get_att_schar(ncid, NC_GLOBAL, ATT_INT_NAME, schar_in); ERR
+ err=ncmpi_get_att_schar(ncid, NC_GLOBAL, ATT_SHORT_NAME, schar_in); ERR
+ err=ncmpi_close(ncid); ERR
+ }
+
+ if (verbose) printf("ok\n");
+ if (verbose) printf("*** testing attribute deletes and renames...");
+ {
+ int ncid, varid, dimids[2];
+ nc_type att_type;
+ MPI_Offset att_len;
+ char *speech_in;
+ char name_in[NC_MAX_NAME + 1];
+ int attid_in, natts_in;
+ int int_out[ATT_LEN] = {-100000, 128, 100000};
+
+ /* Create a file with a global attribute. */
+ err=ncmpi_create(MPI_COMM_WORLD, filename, cmode, MPI_INFO_NULL,&ncid); ERR
+ err=ncmpi_put_att_text(ncid, NC_GLOBAL, ATT_TEXT_NAME, strlen(speech)+1, speech); ERR
+ err=ncmpi_close(ncid); ERR
+
+ /* Rename it. */
+ err=ncmpi_open(MPI_COMM_WORLD, filename, NC_WRITE, MPI_INFO_NULL, &ncid); ERR
+ err=ncmpi_inq_attid(ncid, NC_GLOBAL, ATT_TEXT_NAME, &attid_in); ERR
+ if (attid_in != 0) ERRV
+ err=ncmpi_inq_attname(ncid, NC_GLOBAL, attid_in, name_in); ERR
+ if (strcmp(name_in, ATT_TEXT_NAME)) ERRV
+ err=ncmpi_redef(ncid); ERR
+ err=ncmpi_rename_att(ncid, NC_GLOBAL, ATT_TEXT_NAME, ATT_TEXT_NAME2); ERR
+ err=ncmpi_inq_attname(ncid, NC_GLOBAL, attid_in, name_in); ERR
+ if (strcmp(name_in, ATT_TEXT_NAME2)) ERRV
+ err=ncmpi_close(ncid); ERR
+
+ err=ncmpi_open(MPI_COMM_WORLD, filename, NC_WRITE, MPI_INFO_NULL, &ncid); ERR
+ err=ncmpi_inq_att(ncid, NC_GLOBAL, ATT_TEXT_NAME2, &att_type, &att_len); ERR
+ if (att_type != NC_CHAR || att_len != strlen(speech) + 1) ERRV
+ if (!(speech_in = malloc(att_len + 1))) ERRV
+ err=ncmpi_get_att_text(ncid, NC_GLOBAL, ATT_TEXT_NAME2, speech_in); ERR
+ if (strcmp(speech, speech_in)) ERRV
+ free(speech_in);
+ if ((err=ncmpi_get_att_text(ncid, NC_GLOBAL, ATT_TEXT_NAME, speech_in)) != NC_ENOTATT) ERR
+ err=ncmpi_close(ncid); ERR
+
+ /* Now delete the att. */
+ err=ncmpi_open(MPI_COMM_WORLD, filename, NC_WRITE, MPI_INFO_NULL, &ncid); ERR
+ err=ncmpi_redef(ncid); ERR
+ err=ncmpi_del_att(ncid, NC_GLOBAL, ATT_TEXT_NAME2); ERR
+ err=ncmpi_close(ncid); ERR
+
+ /* Now create a file with a variable, which has an att. */
+ err=ncmpi_create(MPI_COMM_WORLD, filename, cmode, MPI_INFO_NULL,&ncid); ERR
+ err=ncmpi_put_att_text(ncid, NC_GLOBAL, ATT_TEXT_NAME, strlen(speech)+1, speech); ERR
+ err=ncmpi_def_dim(ncid, DIM1_NAME, DIM1_LEN, &dimids[0]); ERR
+ err=ncmpi_def_dim(ncid, DIM2_NAME, DIM2_LEN, &dimids[1]); ERR
+ err=ncmpi_def_var(ncid, VAR1_NAME, NC_INT, 2, dimids, &varid); ERR
+ err=ncmpi_put_att_int(ncid, varid, ATT_INT_NAME, NC_INT, 3, int_out); ERR
+ err=ncmpi_close(ncid); ERR
+
+ /* Reopen the file and delete it. Make sure it's gone. */
+ err=ncmpi_open(MPI_COMM_WORLD, filename, NC_WRITE, MPI_INFO_NULL, &ncid); ERR
+ err=ncmpi_redef(ncid); ERR
+ err=ncmpi_del_att(ncid, 0, ATT_INT_NAME); ERR
+ err=ncmpi_close(ncid); ERR
+
+ /* Reopen the file and readd the attribute. Enddef and redef,
+ * and delete it, then check to make sure it's gone. */
+ err=ncmpi_open(MPI_COMM_WORLD, filename, NC_WRITE, MPI_INFO_NULL, &ncid); ERR
+ err=ncmpi_redef(ncid); ERR
+ err=ncmpi_put_att_int(ncid, varid, ATT_INT_NAME, NC_INT, 3, int_out); ERR
+ err=ncmpi_enddef(ncid); ERR
+ err=ncmpi_redef(ncid); ERR
+ err=ncmpi_del_att(ncid, 0, ATT_INT_NAME); ERR
+ err=ncmpi_inq_varnatts(ncid, 0, &natts_in); ERR
+ if (natts_in != 0) ERRV
+ err=ncmpi_close(ncid); ERR
+ }
+
+ if (verbose) printf("ok\n");
+ if (verbose) printf("*** testing attribute create order...");
+
+#define ATT0 "Maturin"
+#define ATT1 "Aubery"
+ {
+ int ncid, varid, dimids[2];
+ int attid_in;
+ const int number = 42;
+
+ /* Create a file with several global attributes. */
+ err=ncmpi_create(MPI_COMM_WORLD, filename, cmode, MPI_INFO_NULL,&ncid); ERR
+ err=ncmpi_put_att_int(ncid, NC_GLOBAL, ATT0, NC_INT, 1, &number); ERR
+ err=ncmpi_put_att_int(ncid, NC_GLOBAL, ATT1, NC_INT, 1, &number); ERR
+ err=ncmpi_close(ncid); ERR
+
+ /* Open it and check the order. */
+ err=ncmpi_open(MPI_COMM_WORLD, filename, NC_WRITE, MPI_INFO_NULL, &ncid); ERR
+ err=ncmpi_inq_attid(ncid, NC_GLOBAL, ATT0, &attid_in); ERR
+ if (attid_in != 0) ERRV
+ err=ncmpi_inq_attid(ncid, NC_GLOBAL, ATT1, &attid_in); ERR
+ if (attid_in != 1) ERRV
+ err=ncmpi_close(ncid); ERR
+
+ /* Now create a file with a variable, which has two atts. */
+ err=ncmpi_create(MPI_COMM_WORLD, filename, cmode, MPI_INFO_NULL,&ncid); ERR
+ err=ncmpi_def_dim(ncid, DIM1_NAME, DIM1_LEN, &dimids[0]); ERR
+ err=ncmpi_def_dim(ncid, DIM2_NAME, DIM2_LEN, &dimids[1]); ERR
+ err=ncmpi_def_var(ncid, VAR1_NAME, NC_INT, 2, dimids, &varid); ERR
+ err=ncmpi_put_att_int(ncid, varid, ATT0, NC_INT, 1, &number); ERR
+ err=ncmpi_put_att_int(ncid, varid, ATT1, NC_INT, 1, &number); ERR
+ err=ncmpi_close(ncid); ERR
+
+ /* Reopen the file and check the order of the attributes on the var. */
+ err=ncmpi_open(MPI_COMM_WORLD, filename, NC_WRITE, MPI_INFO_NULL, &ncid); ERR
+ err=ncmpi_inq_attid(ncid, 0, ATT0, &attid_in); ERR
+ if (attid_in != 0) ERRV
+ err=ncmpi_inq_attid(ncid, 0, ATT1, &attid_in); ERR
+ if (attid_in != 1) ERRV
+ err=ncmpi_close(ncid); ERR
+ }
+
+ if (verbose) printf("ok\n");
+ if (verbose) printf("*** testing attribute ordering some more...");
+
+#define VAR_NAME "i"
+#define A1_NAME "i"
+#define A2_NAME "f"
+#define A3_NAME "d"
+#define A1_LEN 3
+#define A2_LEN 4
+#define A3_LEN 5
+ {
+ int ncid;
+ int varid, natts, nvars;
+ double dvalue[] = {999.99, 999.99, 999.99, 999.99, 999.99};
+ char name_in[NC_MAX_NAME + 1];
+
+ /* Create a file with one var, and attach three atts to it. */
+ err=ncmpi_create(MPI_COMM_WORLD, filename, cmode, MPI_INFO_NULL,&ncid); ERR
+ err=ncmpi_def_var(ncid, VAR_NAME, NC_INT, 0, NULL, &varid); ERR
+ err=ncmpi_put_att_double(ncid, varid, A1_NAME, NC_INT, A1_LEN, dvalue); ERR
+ err=ncmpi_put_att_double(ncid, varid, A2_NAME, NC_INT, A2_LEN, dvalue); ERR
+ err=ncmpi_put_att_double(ncid, varid, A3_NAME, NC_INT, A3_LEN, dvalue); ERR
+ err=ncmpi_close(ncid); ERR
+
+ /* Reopen the file and check. */
+ err=ncmpi_open(MPI_COMM_WORLD, filename, NC_NOWRITE, MPI_INFO_NULL, &ncid); ERR
+ err=ncmpi_inq_nvars(ncid, &nvars); ERR
+ if (nvars != 1) ERRV
+ err=ncmpi_inq_varnatts(ncid, 0, &natts); ERR
+ if (natts != 3) ERRV
+ err=ncmpi_inq_attname(ncid, 0, 0, name_in); ERR
+ if (strcmp(name_in, A1_NAME)) ERRV
+ err=ncmpi_inq_attname(ncid, 0, 1, name_in); ERR
+ if (strcmp(name_in, A2_NAME)) ERRV
+ err=ncmpi_inq_attname(ncid, 0, 2, name_in); ERR
+ if (strcmp(name_in, A3_NAME)) ERRV
+
+ /* Close up shop. */
+ err=ncmpi_close(ncid); ERR
+ }
+
+ if (verbose) printf("ok\n");
+ if (verbose) printf("*** testing attribute ordering even more...");
+
+ /* Test the ordering of atts for each cmode. */
+ if (tst_att_ordering(filename, cmode)) ERRV
+ if (tst_att_ordering(filename, cmode)) ERRV
+
+ if (verbose) printf("ok\n");
+ if (verbose) printf("*** testing attributes and enddef/redef...");
+
+#define ATT_1 "a"
+#define ATT_2 "b"
+#define ATT_3 "c"
+ {
+ int ncid, att = 1;
+
+ err=ncmpi_create(MPI_COMM_WORLD, filename, cmode, MPI_INFO_NULL,&ncid); ERR
+ err=ncmpi_enddef(ncid); ERR
+ err=ncmpi_redef(ncid); ERR
+ err=ncmpi_put_att(ncid, NC_GLOBAL, ATT_1, NC_INT, 1, &att); ERR
+ err=ncmpi_put_att(ncid, NC_GLOBAL, ATT_2, NC_INT, 1, &att); ERR
+ err=ncmpi_put_att(ncid, NC_GLOBAL, ATT_3, NC_INT, 1, &att); ERR
+
+ err=ncmpi_close(ncid); ERR
+
+ err=ncmpi_open(MPI_COMM_WORLD, filename, NC_NOWRITE, MPI_INFO_NULL, &ncid); ERR
+ err=ncmpi_close(ncid); ERR
+ }
+
+ if (verbose) printf("ok\n");
+ if (verbose) printf("*** testing copy of simple global atts...");
+ {
+ int ncid, ncid2;
+ nc_type att_type;
+ MPI_Offset att_len;
+ int i;
+
+ char *speech_in;
+ signed char schar_in[ATT_LEN], schar_out[ATT_LEN] = {NC_MIN_BYTE, 1, NC_MAX_BYTE};
+ short short_in[ATT_LEN], short_out[ATT_LEN] = {NC_MIN_SHORT, -128, NC_MAX_SHORT};
+ int int_in[ATT_LEN], int_out[ATT_LEN] = {-100000, 128, 100000};
+ float float_in[ATT_LEN], float_out[ATT_LEN] = {.5, 0.25, 0.125};
+ double double_in[ATT_LEN], double_out[ATT_LEN] = {0.25, .5, 0.125};
+
+ /* Create a file with a global attribute of each type. */
+ err=ncmpi_create(MPI_COMM_WORLD, filename, cmode, MPI_INFO_NULL,&ncid); ERR
+ err=ncmpi_put_att_text(ncid, NC_GLOBAL, ATT_TEXT_NAME, strlen(speech)+1, speech); ERR
+ err=ncmpi_put_att_schar(ncid, NC_GLOBAL, ATT_SCHAR_NAME, NC_BYTE, ATT_LEN, schar_out); ERR
+ err=ncmpi_put_att_short(ncid, NC_GLOBAL, ATT_SHORT_NAME, NC_SHORT, ATT_LEN, short_out); ERR
+ err=ncmpi_put_att_int(ncid, NC_GLOBAL, ATT_INT_NAME, NC_INT, ATT_LEN, int_out); ERR
+ err=ncmpi_put_att_float(ncid, NC_GLOBAL, ATT_FLOAT_NAME, NC_FLOAT, ATT_LEN, float_out); ERR
+ err=ncmpi_put_att_double(ncid, NC_GLOBAL, ATT_DOUBLE_NAME, NC_DOUBLE, ATT_LEN, double_out); ERR
+
+ /* Create another file and copy all the attributes. */
+ err=ncmpi_create(MPI_COMM_WORLD, filename2, cmode, MPI_INFO_NULL,&ncid2); ERR
+ err=ncmpi_copy_att(ncid, NC_GLOBAL, ATT_TEXT_NAME, ncid2, NC_GLOBAL); ERR
+ err=ncmpi_copy_att(ncid, NC_GLOBAL, ATT_SCHAR_NAME, ncid2, NC_GLOBAL); ERR
+ err=ncmpi_copy_att(ncid, NC_GLOBAL, ATT_SHORT_NAME, ncid2, NC_GLOBAL); ERR
+ err=ncmpi_copy_att(ncid, NC_GLOBAL, ATT_INT_NAME, ncid2, NC_GLOBAL); ERR
+ err=ncmpi_copy_att(ncid, NC_GLOBAL, ATT_FLOAT_NAME, ncid2, NC_GLOBAL); ERR
+ err=ncmpi_copy_att(ncid, NC_GLOBAL, ATT_DOUBLE_NAME, ncid2, NC_GLOBAL); ERR
+
+ /* Close both files. */
+ err=ncmpi_close(ncid); ERR
+ err=ncmpi_close(ncid2); ERR
+
+ /* Open the file and check attributes. */
+ err=ncmpi_open(MPI_COMM_WORLD, filename2, NC_NOWRITE, MPI_INFO_NULL, &ncid); ERR
+ /* Check text. */
+ err=ncmpi_inq_att(ncid, NC_GLOBAL, ATT_TEXT_NAME, &att_type, &att_len); ERR
+ if (att_type != NC_CHAR || att_len != strlen(speech) + 1) ERRV
+ if (!(speech_in = malloc(att_len + 1))) ERRV
+ err=ncmpi_get_att_text(ncid, NC_GLOBAL, ATT_TEXT_NAME, speech_in); ERR
+ if (strcmp(speech, speech_in)) ERRV
+ free(speech_in);
+ /* Check numeric values. */
+ err=ncmpi_get_att_schar(ncid, NC_GLOBAL, ATT_SCHAR_NAME, schar_in); ERR
+ for (i = 0; i < ATT_LEN; i++)
+ if (schar_in[i] != schar_out[i]) ERRV
+ err=ncmpi_get_att_short(ncid, NC_GLOBAL, ATT_SHORT_NAME, short_in); ERR
+ for (i = 0; i < ATT_LEN; i++)
+ if (short_in[i] != short_out[i]) ERRV
+ err=ncmpi_get_att_int(ncid, NC_GLOBAL, ATT_INT_NAME, int_in); ERR
+ for (i = 0; i < ATT_LEN; i++)
+ if (int_in[i] != int_out[i]) ERRV
+ err=ncmpi_get_att_float(ncid, NC_GLOBAL, ATT_FLOAT_NAME, float_in); ERR
+ for (i = 0; i < ATT_LEN; i++)
+ if (float_in[i] != float_out[i]) ERRV
+ err=ncmpi_get_att_double(ncid, NC_GLOBAL, ATT_DOUBLE_NAME, double_in); ERR
+ for (i = 0; i < ATT_LEN; i++)
+ if (double_in[i] != double_out[i]) ERRV
+ err=ncmpi_close(ncid); ERR
+ }
+ if (verbose) printf("ok\n");
+ return nerrs;
+}
+
+int main(int argc, char *argv[])
+{
+ char filename[128];
+ int cmode, rank, nprocs, err, nerrs=0;
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+
+ if (argc > 2) {
+ if (!rank) printf("Usage: %s [filename]\n",argv[0]);
+ MPI_Finalize();
+ return 0;
+ }
+ strcpy(filename, "testfile.nc");
+ if (argc == 2) strcpy(filename, argv[1]);
+ MPI_Bcast(filename, 128, MPI_CHAR, 0, MPI_COMM_WORLD);
+
+ char cmd_str[256];
+ sprintf(cmd_str, "*** TESTING C %s for emulating netCDF tst_atts3 ", argv[0]);
+ if (rank == 0) printf("%-66s ------ ", cmd_str);
+
+ verbose = 0;
+
+ cmode = NC_CLOBBER;
+ nerrs += tst_atts3(filename, cmode);
+
+ cmode = NC_CLOBBER | NC_64BIT_OFFSET;
+ nerrs += tst_atts3(filename, cmode);
+
+ cmode = NC_CLOBBER | NC_64BIT_DATA;
+ nerrs += tst_atts3(filename, cmode);
+
+ MPI_Allreduce(MPI_IN_PLACE, &nerrs, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
+
+ /* check if PnetCDF freed all internal malloc */
+ MPI_Offset malloc_size, sum_size;
+ err = ncmpi_inq_malloc_size(&malloc_size);
+ if (err == NC_NOERR) {
+ MPI_Reduce(&malloc_size, &sum_size, 1, MPI_OFFSET, MPI_SUM, 0, MPI_COMM_WORLD);
+ if (rank == 0 && sum_size > 0)
+ printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n",
+ sum_size);
+ }
+
+ if (rank == 0) {
+ if (nerrs) printf(FAIL_STR,nerrs);
+ else printf(PASS_STR);
+ }
+
+ MPI_Finalize();
+ return 0;
+}
+
diff --git a/test/nc_test/tst_misc.c b/test/nc_test/tst_misc.c
new file mode 100644
index 0000000..f978ccb
--- /dev/null
+++ b/test/nc_test/tst_misc.c
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2014, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ */
+/* $Id: tst_misc.c 2133 2015-09-26 19:16:01Z wkliao $ */
+
+/* This program is based on the test program tst_misc.c of the netCDF package */
+
+/*
+ Copyright 2007, UCAR/Unidata
+ See COPYRIGHT file for copying and redistribution conditions.
+
+ This is part of netCDF.
+
+ This program runs some extra tests.
+
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <pnetcdf.h>
+
+#include <testutils.h>
+
+int
+main(int argc, char **argv)
+{
+ char filename[128];
+ int rank, nprocs, err, nerrs=0;
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+
+ if (argc > 2) {
+ if (!rank) printf("Usage: %s [filename]\n",argv[0]);
+ MPI_Finalize();
+ return 0;
+ }
+ strcpy(filename, "testfile.nc");
+ if (argc == 2) strcpy(filename, argv[1]);
+ if (rank > 0) goto fn_exit;
+
+ char cmd_str[256];
+ sprintf(cmd_str, "*** TESTING C %s for emulating netCDF t_misc ", argv[0]);
+ if (rank == 0) printf("%-66s ------ ", cmd_str);
+/*
+ printf("\n*** Testing some extra stuff.\n");
+ printf("*** Trying to open non-netCDF files of tiny length...");
+*/
+ {
+#define DATA_LEN 32
+ int ncid,openstat;
+ char dummy_data[DATA_LEN];
+ FILE *file;
+ int i, nerrs=0;
+
+ /* Appease valgrind by initializing our data. */
+ for (i = 0; i < DATA_LEN; i++)
+ dummy_data[i] = i;
+
+ for (i = DATA_LEN; i >= 0; i--)
+ {
+ /* Create a small file which is not a netCDF file. */
+ if (!(file = fopen(filename, "w+"))) nerrs++;
+ if (fwrite(dummy_data, 1, i, file) != i) nerrs++;
+ if (fclose(file)) nerrs++;
+
+ /* Make sure that netCDF rejects this file politely. */
+ openstat = ncmpi_open(MPI_COMM_SELF, filename, NC_NOWRITE, MPI_INFO_NULL, &ncid);
+ /* Some platforms (OSX, buddy) return stat = 2 (file not found)
+ for index i == 2. Not sure why, but this is a work around. */
+ if(openstat != NC_ENOTNC && openstat != NC_ENOENT) {
+ printf("Expecting error code %d or %d but got %d\n",NC_ENOTNC,NC_ENOENT,openstat);
+ nerrs++;
+ }
+ }
+ }
+
+ /* check if PnetCDF freed all internal malloc */
+ MPI_Offset malloc_size, sum_size;
+ err = ncmpi_inq_malloc_size(&malloc_size);
+ if (err == NC_NOERR) {
+ MPI_Reduce(&malloc_size, &sum_size, 1, MPI_OFFSET, MPI_SUM, 0, MPI_COMM_WORLD);
+ if (rank == 0 && sum_size > 0)
+ printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n",
+ sum_size);
+ }
+
+fn_exit:
+ MPI_Allreduce(MPI_IN_PLACE, &nerrs, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
+ if (rank == 0) {
+ if (nerrs) printf(FAIL_STR,nerrs);
+ else printf(PASS_STR);
+ }
+
+ MPI_Finalize();
+ return 0;
+}
diff --git a/test/nc_test/tst_names.c b/test/nc_test/tst_names.c
new file mode 100644
index 0000000..4ce6b31
--- /dev/null
+++ b/test/nc_test/tst_names.c
@@ -0,0 +1,327 @@
+/*
+ * Copyright (C) 2014, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ */
+/* $Id: tst_names.c 2133 2015-09-26 19:16:01Z wkliao $ */
+
+/* This program is based on the test program tst_names.c of the netCDF package */
+
+/* This is part of the netCDF package.
+ Copyright 2006 University Corporation for Atmospheric Research/Unidata.
+ See COPYRIGHT file for conditions of use.
+
+ This is a very simple example which tests rejection of bad names for
+ netCDF data objects, including names with "/" character, trailing spaces,
+ leading special characters, and invalid UTF-8 strings.
+*/
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <pnetcdf.h>
+
+#include <testutils.h>
+
+/* The data file we will create. */
+#define NDIMS 1
+#define DIMLEN 1
+
+int
+main(int argc, char **argv)
+{
+ char *valid[] = {
+ /* pressure in 23 languages */
+ "\xd8\xa7\xd9\x84\xd8\xb6\xd8\xba\xd8\xb7",
+ "\xd0\xbd\xd0\xb0\xd0\xbb\xd1\x8f\xd0\xb3\xd0\xb0\xd0\xbd\xd0\xb5",
+ "\xe5\x8e\x8b\xe5\x8a\x9b",
+ "\xe5\xa3\x93\xe5\x8a\x9b",
+ "pritisak",
+ "tlaku",
+ "pres",
+ "druk",
+ "pressure",
+ "paine",
+ "pression",
+ "Druck",
+ "\xcf\x80\xce\xaf\xce\xb5\xcf\x83\xce\xb7",
+ "\xe0\xa4\xa6\xe0\xa4\xac\xe0\xa4\xbe\xe0\xa4\xb5",
+ "pressione",
+ "\xe5\x9c\xa7\xe5\x8a\x9b",
+ "\xec\x95\x95\xeb\xa0\xa5",
+ "press",
+ "ci\xc5\x9bnienie",
+ "Press\xc3\xa3o",
+ "presiune",
+ "\xd0\xb4\xd0\xb0\xd0\xb2\xd0\xbb\xd0\xb5\xd0\xbd\xd0\xb8\xd0\xb5",
+ "presi\xc3\xb3n",
+ /* special characters in names, numeric characters at the start of names */
+ "has blank",
+ "has:colon",
+ "a",
+ "A",
+ "0leading_numeric_char",
+ "1",
+ "0x123"
+ };
+ char *notvalid[] = {
+ "-leading_special_char",
+ "trailing_space ",
+ "trailing_tab\t",
+ "trailing_newline\n",
+ "has_control_char_\a_in_name",
+ "has ascii_del_\x7f_in name",
+ /* Invalid UTF-8 of various sorts, thanks to Markus Kuhn */
+ "\xA0\xB0\xC0\xD0",
+ "xyz\x80", /* unexpected continuation bytes */
+ "\x80xyz",
+ "xyz\xBF",
+ "\xBFxyz",
+ "\xC0xyz", /* lonely start characters */
+ "x\xC0yz",
+ "xy\xC0z",
+ "xyz\xC0",
+ "\xDFxyz",
+ "x\xDFyz",
+ "xy\xDFz",
+ "xyz\xDF",
+ "\xE0xyz",
+ "x\xE0yz",
+ "xy\xE0z",
+ "xyz\xE0",
+ "\xE0\xBFxy",
+ "x\xE0\xBFy",
+ "xy\xE0\xBF",
+ "\xEFxyz",
+ "x\xEFyz",
+ "xy\xEFz",
+ "xyz\xEF",
+ "\xEF\x80xy",
+ "x\xEF\x80y",
+ "xy\xEF\x80",
+ "\xF0xyz",
+ "x\xF0yz",
+ "xy\xF0z",
+ "xyz\xF0",
+ "\xF7xyz",
+ "x\xF7yz",
+ "xy\xF7z",
+ "xyz\xF7",
+ "\xF8xyz",
+ "x\xF8yz",
+ "xy\xF8z",
+ "xyz\xF8",
+ "\xFBxyz",
+ "x\xFByz",
+ "xy\xFBz",
+ "xyz\xFB",
+ "\xFCxyz",
+ "x\xFCyz",
+ "xy\xFCz",
+ "xyz\xFC",
+ "\xFDxyz",
+ "x\xFDyz",
+ "xy\xFDz",
+ "xyz\xFD",
+ "\xC0\xC0xy", /* last continuation byte missing */
+ "x\xC0\xC0y",
+ "xy\xC0\xC0",
+ "\xDF\xDFxy",
+ "x\xDF\xDFy",
+ "xy\xDF\xDF",
+ "\xE0\x80xy",
+ "x\xE0\x80y",
+ "xy\xE0\x80",
+ "\xEF\x80xy",
+ "x\xEF\x80y",
+ "xy\xEF\x80",
+ "\xF0\x80\x80x",
+ "x\xF0\x80\x80",
+ "\xF7\x80\x80x",
+ "x\xF7\x80\x80",
+ "\xF8\x80\x80\x80x",
+ "x\xF8\x80\x80\x80",
+ "\xFB\x80\x80\x80x",
+ "x\xFB\x80\x80\x80",
+ "\xFC\x80\x80\x80\x80x",
+ "x\xFC\x80\x80\x80\x80",
+ "\xFD\x80\x80\x80\x80x",
+ "x\xFD\x80\x80\x80\x80",
+ "\xFExyz", /* impossible bytes */
+ "x\xFEyz",
+ "xy\xFEz",
+ "xyz\xFE",
+ "\xFFxyz",
+ "x\xFFyz",
+ "xy\xFFz",
+ "xyz\xFF",
+ "\xC0\xAFxy", /* overlong sequences */
+ "x\xC0\xAFy",
+ "xy\xC0\xAF",
+ "\xE0\x80\xAFx",
+ "x\xE0\x80\xAF",
+ "\xF0\x80\x80\xAFx",
+ "x\xF0\x80\x80\xAF",
+ "\xF8\x80\x80\x80\xAFx",
+ "x\xF8\x80\x80\x80\xAF",
+ "\xFC\x80\x80\x80\x80\xAFx",
+ "x\xFC\x80\x80\x80\x80\xAF",
+ "\xC1\xBFxy",
+ "x\xC1\xBFy",
+ "xy\xC1\xBF",
+ "\xE0\x9F\xBFx",
+ "x\xE0\x9F\xBF",
+ "\xF0\x8F\xBF\xBFx",
+ "x\xF0\x8F\xBF\xBF",
+ "\xF8\x87\xBF\xBF\xBFx",
+ "x\xF8\x87\xBF\xBF\xBF",
+ "\xFC\x83\xBF\xBF\xBF\xBFx",
+ "x\xFC\x83\xBF\xBF\xBF\xBF",
+ "x\xC0\x80", /* overlong NULs */
+ "x\xE0\x80\x80",
+ "x\xF0\x80\x80\x80",
+ "x\xF8\x80\x80\x80\x80",
+ "x\xFC\x80\x80\x80\x80\x80",
+ /* single UTF-16 surrogates */
+ "x\xED\xA0\x80",
+ "x\xED\xAD\xBF",
+ "x\xED\xAE\x80",
+ "x\xED\xAF\xBF",
+ "x\xED\xB0\x80",
+ "x\xED\xBE\x80",
+ "x\xED\xBF\xBF",
+ "x\xED\xA0\x80\xED\xB0\x80", /* paired UTF-16 surrogates */
+ "x\xED\xA0\x80\xED\xBF\xBF",
+ "x\xED\xAD\xBF\xED\xB0\x80",
+ "x\xED\xAD\xBF\xED\xBF\xBF",
+ "x\xED\xAE\x80\xED\xB0\x80",
+ "x\xED\xAE\x80\xED\xBF\xBF",
+ "x\xED\xAF\xBF\xED\xB0\x80",
+ "x\xED\xAF\xBF\xED\xBF\xBF",
+ "x\xEF\xBF\xBE", /* other illegal code positions */
+ "x\xEF\xBF\xBF"
+ };
+ int i, j;
+#define NUM_BAD (sizeof notvalid / sizeof notvalid[0])
+#define NUM_GOOD (sizeof valid / sizeof valid[0])
+ int ncid, dimid, varid, res;
+ double attvals[] = {-2.0};
+ double attvals_in[1];
+#define NATTVALS (sizeof attvals / sizeof attvals[0])
+ char *attstring = "text";
+#define MAX_ATTSTRING_LEN 100
+ char attstr_in[MAX_ATTSTRING_LEN];
+ int dimids[NUM_GOOD];
+ int varids[NUM_GOOD];
+#if 0
+ int attnums[NUM_GOOD];
+#endif
+ char *format_names[] = { "CDF-2", "CDF-5" };
+ int cmode[2] = {NC_64BIT_OFFSET, NC_64BIT_DATA};
+
+ char filename[128];
+ int rank, nprocs, err, nerrs=0, verbose=0;
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+
+ if (argc > 2) {
+ if (!rank) printf("Usage: %s [filename]\n",argv[0]);
+ MPI_Finalize();
+ return 0;
+ }
+ strcpy(filename, "testfile.nc");
+ if (argc == 2) strcpy(filename, argv[1]);
+
+ char cmd_str[256];
+ sprintf(cmd_str, "*** TESTING C %s for emulating netCDF tst_names ", argv[0]);
+ if (rank == 0) printf("%-66s ------ ", cmd_str);
+
+#define ERROR {printf("Error at line %d: %s\n",__LINE__,ncmpi_strerror(res)); nerrs++;}
+#define ERRORI {printf("Error at line %d (loop=%d): %s\n",__LINE__,i,ncmpi_strerror(res)); nerrs++;}
+
+ if (verbose) printf("\n*** testing names with file %s...\n", filename);
+ for (j = 0; j < 2; j++)
+ {
+ if (verbose) printf("*** switching to netCDF %s format...", format_names[j]);
+ if((res = ncmpi_create(MPI_COMM_WORLD, filename, NC_CLOBBER|cmode[j], MPI_INFO_NULL, &ncid)))
+ ERROR
+
+ /* Define dimensions, variables, and attributes with various
+ * acceptable names */
+ for (i = 0; i < NUM_GOOD; i++) {
+ if ((res = ncmpi_def_dim(ncid, valid[i], DIMLEN, &dimid)))
+ ERRORI
+
+ dimids[i] = dimid;
+ /* Define variable with same name */
+ if ((res = ncmpi_def_var(ncid, valid[i], NC_FLOAT, NDIMS, &dimids[i], &varid)))
+ ERRORI
+ varids[i] = varid;
+ /* Define variable and global attributes with same name and value */
+ if ((res = ncmpi_put_att_text(ncid, varid, valid[i], strlen(valid[i]), valid[i])))
+ ERRORI
+ if ((res = ncmpi_put_att_double(ncid, NC_GLOBAL, valid[i], NC_DOUBLE, NATTVALS, attvals)))
+ ERRORI
+#if 0
+ attnums[i] = i;
+#endif
+ }
+
+ /* Try defining dimensions, variables, and attributes with various
+ * bad names and make sure these are rejected */
+ for (i = 0; i < NUM_BAD; i++) {
+ if ((res = ncmpi_def_dim(ncid, notvalid[i], DIMLEN, &dimid)) != NC_EBADNAME)
+ ERRORI
+ if ((res = ncmpi_def_var(ncid, notvalid[i], NC_FLOAT, NDIMS, dimids, &varid)) != NC_EBADNAME)
+ ERRORI
+ if ((res = ncmpi_put_att_text(ncid, varid, notvalid[i], strlen(attstring), attstring)) != NC_EBADNAME)
+ ERRORI
+ if ((res = ncmpi_put_att_double(ncid, NC_GLOBAL, notvalid[i], NC_DOUBLE, NATTVALS, attvals)) != NC_EBADNAME)
+ ERRORI
+ }
+ if ((res = ncmpi_enddef(ncid)))
+ ERROR
+ if ((res = ncmpi_close(ncid)))
+ ERROR
+
+ /* Check it out, make sure all objects with good names were defined OK */
+ if ((res = ncmpi_open(MPI_COMM_WORLD, filename, NC_NOWRITE, MPI_INFO_NULL, &ncid)))
+ ERROR
+ for (i = 0; i < NUM_GOOD; i++) {
+ MPI_Offset attlen;
+ if ((res = ncmpi_inq_dimid(ncid, valid[i], &dimid)) || dimid != dimids[i])
+ ERRORI
+ if ((res = ncmpi_inq_varid(ncid, valid[i], &varid)) || varid != varids[i])
+ ERRORI
+ res = ncmpi_inq_attlen(ncid, varid, valid[i], &attlen);
+ if ((res = ncmpi_get_att_text(ncid, varid, valid[i], attstr_in)))
+ ERRORI
+ attstr_in[attlen] = '\0';
+ if (strcmp(valid[i], attstr_in) != 0)
+ ERRORI
+ if ((res = ncmpi_get_att_double(ncid, NC_GLOBAL, valid[i], attvals_in)) || attvals[0] != attvals_in[0])
+ ERRORI
+ }
+ if ((res = ncmpi_close(ncid)))
+ ERROR
+ }
+
+ /* check if PnetCDF freed all internal malloc */
+ MPI_Offset malloc_size, sum_size;
+ err = ncmpi_inq_malloc_size(&malloc_size);
+ if (err == NC_NOERR) {
+ MPI_Reduce(&malloc_size, &sum_size, 1, MPI_OFFSET, MPI_SUM, 0, MPI_COMM_WORLD);
+ if (rank == 0 && sum_size > 0)
+ printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n",
+ sum_size);
+ }
+
+ MPI_Allreduce(MPI_IN_PLACE, &nerrs, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
+ if (rank == 0) {
+ if (nerrs) printf(FAIL_STR,nerrs);
+ else printf(PASS_STR);
+ }
+
+ MPI_Finalize();
+ return 0;
+}
diff --git a/test/nc_test/tst_nofill.c b/test/nc_test/tst_nofill.c
new file mode 100644
index 0000000..1115df3
--- /dev/null
+++ b/test/nc_test/tst_nofill.c
@@ -0,0 +1,484 @@
+/*
+ Copyright 2007, UCAR/Unidata
+ See COPYRIGHT file for copying and redistribution conditions.
+
+ This is part of netCDF.
+
+ This program tests for a bug discovered with nofill mode that failed
+ only on file systems with block size in a particular range. It fails
+ when invoked with the blksize argument between 2091953 and 2150032,
+ inclusive, and succeeds for other blksizes.
+
+ $Id: tst_nofill.c 2219 2015-12-11 22:30:03Z wkliao $
+*/
+
+#include <stdio.h>
+#include <string.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <pnetcdf.h>
+
+#include <testutils.h>
+
+#define ERR {if (err != NC_NOERR) {printf("Error at %s line %d: %s\n",__func__,__LINE__,ncmpi_strerror(err)); return 1;}}
+
+static void
+check_err(const int stat, const int line, const char *file) {
+ if (stat != NC_NOERR) {
+ (void) fprintf(stderr, "line %d of %s: %s\n", line, file, ncmpi_strerror(stat));
+ fflush(stderr);
+ exit(1);
+ }
+}
+
+#define LON_LEN 240
+#define LAT_LEN 121
+#define LVL_LEN 31
+#define TIME_LEN 1
+
+static int
+create_file(char *file_name, int fill_mode)
+{
+ int i;
+ int stat; /* return status */
+ int ncid; /* netCDF id */
+
+ /* dimension ids */
+ int lon_dim;
+ int lat_dim;
+ int lvl_dim;
+ int time_dim;
+
+ /* dimension lengths */
+ MPI_Offset lon_len = LON_LEN;
+ MPI_Offset lat_len = LAT_LEN;
+ MPI_Offset lvl_len = LVL_LEN;
+ MPI_Offset time_len = TIME_LEN;
+
+ /* variable ids */
+ int time_id;
+ int lat_id;
+ int lon_id;
+ int lvl_id;
+ int sfc_pres_id;
+ int temp_scrn_id;
+ int qsair_scrn_id;
+ int topog_id;
+ int mslp_id;
+ int sfc_temp_id;
+ int zonal_wnd_id;
+
+ /* rank (number of dimensions) for each variable */
+# define RANK_time 1
+# define RANK_lat 1
+# define RANK_lon 1
+# define RANK_lvl 1
+# define RANK_sfc_pres 3
+# define RANK_temp_scrn 3
+# define RANK_qsair_scrn 3
+# define RANK_topog 3
+# define RANK_mslp 3
+# define RANK_sfc_temp 3
+# define RANK_zonal_wnd 4
+
+ /* variable shapes */
+ int time_dims[RANK_time];
+ int lat_dims[RANK_lat];
+ int lon_dims[RANK_lon];
+ int lvl_dims[RANK_lvl];
+ int sfc_pres_dims[RANK_sfc_pres];
+ int temp_scrn_dims[RANK_temp_scrn];
+ int qsair_scrn_dims[RANK_qsair_scrn];
+ int topog_dims[RANK_topog];
+ int mslp_dims[RANK_mslp];
+ int sfc_temp_dims[RANK_sfc_temp];
+ int zonal_wnd_dims[RANK_zonal_wnd];
+
+ MPI_Offset zonal_wnd_start[RANK_zonal_wnd];
+ MPI_Offset zonal_wnd_count[RANK_zonal_wnd];
+ float zonal_wnd[LON_LEN*LAT_LEN*TIME_LEN];
+ int ii;
+
+ int old_fill_mode;
+
+ stat = ncmpi_create(MPI_COMM_WORLD, file_name,NC_CLOBBER, MPI_INFO_NULL, &ncid);
+
+ check_err(stat,__LINE__,__FILE__);
+ stat = ncmpi_set_fill(ncid, fill_mode, &old_fill_mode);
+ check_err(stat,__LINE__,__FILE__);
+
+ /* define dimensions */
+ stat = ncmpi_def_dim(ncid, "lon", lon_len, &lon_dim);
+ check_err(stat,__LINE__,__FILE__);
+ stat = ncmpi_def_dim(ncid, "lat", lat_len, &lat_dim);
+ check_err(stat,__LINE__,__FILE__);
+ stat = ncmpi_def_dim(ncid, "lvl", lvl_len, &lvl_dim);
+ check_err(stat,__LINE__,__FILE__);
+ stat = ncmpi_def_dim(ncid, "time", time_len, &time_dim);
+ check_err(stat,__LINE__,__FILE__);
+
+ /* define variables */
+ time_dims[0] = time_dim;
+ stat = ncmpi_def_var(ncid, "time", NC_DOUBLE, RANK_time, time_dims, &time_id);
+ check_err(stat,__LINE__,__FILE__);
+
+ lat_dims[0] = lat_dim;
+ stat = ncmpi_def_var(ncid, "lat", NC_FLOAT, RANK_lat, lat_dims, &lat_id);
+ check_err(stat,__LINE__,__FILE__);
+
+ lon_dims[0] = lon_dim;
+ stat = ncmpi_def_var(ncid, "lon", NC_FLOAT, RANK_lon, lon_dims, &lon_id);
+ check_err(stat,__LINE__,__FILE__);
+
+ lvl_dims[0] = lvl_dim;
+ stat = ncmpi_def_var(ncid, "lvl", NC_FLOAT, RANK_lvl, lvl_dims, &lvl_id);
+ check_err(stat,__LINE__,__FILE__);
+
+ sfc_pres_dims[0] = time_dim;
+ sfc_pres_dims[1] = lat_dim;
+ sfc_pres_dims[2] = lon_dim;
+ stat = ncmpi_def_var(ncid, "sfc_pres", NC_FLOAT, RANK_sfc_pres, sfc_pres_dims, &sfc_pres_id);
+ check_err(stat,__LINE__,__FILE__);
+
+ temp_scrn_dims[0] = time_dim;
+ temp_scrn_dims[1] = lat_dim;
+ temp_scrn_dims[2] = lon_dim;
+ stat = ncmpi_def_var(ncid, "temp_scrn", NC_FLOAT, RANK_temp_scrn, temp_scrn_dims, &temp_scrn_id);
+ check_err(stat,__LINE__,__FILE__);
+
+ qsair_scrn_dims[0] = time_dim;
+ qsair_scrn_dims[1] = lat_dim;
+ qsair_scrn_dims[2] = lon_dim;
+ stat = ncmpi_def_var(ncid, "qsair_scrn", NC_FLOAT, RANK_qsair_scrn, qsair_scrn_dims, &qsair_scrn_id);
+ check_err(stat,__LINE__,__FILE__);
+
+ topog_dims[0] = time_dim;
+ topog_dims[1] = lat_dim;
+ topog_dims[2] = lon_dim;
+ stat = ncmpi_def_var(ncid, "topog", NC_FLOAT, RANK_topog, topog_dims, &topog_id);
+ check_err(stat,__LINE__,__FILE__);
+
+ mslp_dims[0] = time_dim;
+ mslp_dims[1] = lat_dim;
+ mslp_dims[2] = lon_dim;
+ stat = ncmpi_def_var(ncid, "mslp", NC_FLOAT, RANK_mslp, mslp_dims, &mslp_id);
+ check_err(stat,__LINE__,__FILE__);
+
+ sfc_temp_dims[0] = time_dim;
+ sfc_temp_dims[1] = lat_dim;
+ sfc_temp_dims[2] = lon_dim;
+ stat = ncmpi_def_var(ncid, "sfc_temp", NC_FLOAT, RANK_sfc_temp, sfc_temp_dims, &sfc_temp_id);
+ check_err(stat,__LINE__,__FILE__);
+
+ zonal_wnd_dims[0] = time_dim;
+ zonal_wnd_dims[1] = lvl_dim;
+ zonal_wnd_dims[2] = lat_dim;
+ zonal_wnd_dims[3] = lon_dim;
+ stat = ncmpi_def_var(ncid, "zonal_wnd", NC_FLOAT, RANK_zonal_wnd, zonal_wnd_dims, &zonal_wnd_id);
+ check_err(stat,__LINE__,__FILE__);
+
+ /* leave define mode */
+ stat = ncmpi_enddef (ncid);
+ check_err(stat,__LINE__,__FILE__);
+
+ { /* store time */
+ MPI_Offset time_start[RANK_time];
+ MPI_Offset time_count[RANK_time];
+ double time[TIME_LEN] = {1.};
+ time_len = 1;
+ time_start[0] = 0;
+ time_count[0] = time_len;
+ stat = ncmpi_put_vara_double_all(ncid, time_id, time_start, time_count, time);
+ check_err(stat,__LINE__,__FILE__);
+ }
+
+ { /* store lat */
+ float lat[] = {90, 88.5, 87, 85.5, 84, 82.5, 81, 79.5, 78, 76.5, 75, 73.5, 72, 70.5, 69, 67.5, 66, 64.5, 63, 61.5, 60, 58.5, 57, 55.5, 54, 52.5, 51, 49.5, 48, 46.5, 45, 43.5, 42, 40.5, 39, 37.5, 36, 34.5, 33, 31.5, 30, 28.5, 27, 25.5, 24, 22.5, 21, 19.5, 18, 16.5, 15, 13.5, 12, 10.5, 9, 7.5, 6, 4.5, 3, 1.5, 0, -1.5, -3, -4.5, -6, -7.5, -9, -10.5, -12, -13.5, -15, -16.5, -18, -19.5, -21, -22.5, -24, -25.5, -27, -28.5, -30, -31.5, -33, -34.5, -36, -37.5, -39, -40.5, -42, -43.5, -45, [...]
+ stat = ncmpi_put_var_float_all(ncid, lat_id, lat);
+ check_err(stat,__LINE__,__FILE__);
+ }
+
+ { /* store lon */
+ float lon[] = {0, 1.5, 3, 4.5, 6, 7.5, 9, 10.5, 12, 13.5, 15, 16.5, 18, 19.5, 21, 22.5, 24, 25.5, 27, 28.5, 30, 31.5, 33, 34.5, 36, 37.5, 39, 40.5, 42, 43.5, 45, 46.5, 48, 49.5, 51, 52.5, 54, 55.5, 57, 58.5, 60, 61.5, 63, 64.5, 66, 67.5, 69, 70.5, 72, 73.5, 75, 76.5, 78, 79.5, 81, 82.5, 84, 85.5, 87, 88.5, 90, 91.5, 93, 94.5, 96, 97.5, 99, 100.5, 102, 103.5, 105, 106.5, 108, 109.5, 111, 112.5, 114, 115.5, 117, 118.5, 120, 121.5, 123, 124.5, 126, 127.5, 129, 130.5, 132, 133.5, 135, [...]
+ stat = ncmpi_put_var_float_all(ncid, lon_id, lon);
+ check_err(stat,__LINE__,__FILE__);
+ }
+
+ { /* store lvl */
+ float lvl[] = {1000, 995, 990, 985, 975, 950, 925, 900, 875, 850, 800, 750, 700, 600, 500, 450, 400, 350, 300, 275, 250, 225, 200, 175, 150, 100, 70, 50, 30, 20, 10};
+ stat = ncmpi_put_var_float_all(ncid, lvl_id, lvl);
+ check_err(stat,__LINE__,__FILE__);
+ }
+
+ { /* store sfc_pres */
+ MPI_Offset sfc_pres_start[RANK_sfc_pres];
+ MPI_Offset sfc_pres_count[RANK_sfc_pres];
+ float sfc_pres[LON_LEN*LAT_LEN];
+
+ for(ii = 0; ii < LAT_LEN * LON_LEN; ii++) {
+ sfc_pres[ii] = 6;
+ }
+ sfc_pres_start[0] = 0;
+ sfc_pres_start[1] = 0;
+ sfc_pres_start[2] = 0;
+ sfc_pres_count[0] = time_len;
+ sfc_pres_count[1] = lat_len;
+ sfc_pres_count[2] = lon_len;
+ stat = ncmpi_put_vara_float_all(ncid, sfc_pres_id, sfc_pres_start, sfc_pres_count, sfc_pres);
+ check_err(stat,__LINE__,__FILE__);
+ }
+
+ { /* store temp_scrn */
+ MPI_Offset temp_scrn_start[RANK_temp_scrn];
+ MPI_Offset temp_scrn_count[RANK_temp_scrn];
+ float temp_scrn[LON_LEN*LAT_LEN];
+
+ for(ii = 0; ii < LAT_LEN * LON_LEN; ii++) {
+ temp_scrn[ii] = 11;
+ }
+ temp_scrn_start[0] = 0;
+ temp_scrn_start[1] = 0;
+ temp_scrn_start[2] = 0;
+ temp_scrn_count[0] = time_len;
+ temp_scrn_count[1] = lat_len;
+ temp_scrn_count[2] = lon_len;
+ stat = ncmpi_put_vara_float_all(ncid, temp_scrn_id, temp_scrn_start, temp_scrn_count, temp_scrn);
+ check_err(stat,__LINE__,__FILE__);
+ }
+
+ { /* store qsair_scrn */
+ MPI_Offset qsair_scrn_start[RANK_qsair_scrn];
+ MPI_Offset qsair_scrn_count[RANK_qsair_scrn];
+ float qsair_scrn[LON_LEN*LAT_LEN];
+
+ for(ii = 0; ii < LAT_LEN * LON_LEN; ii++) {
+ qsair_scrn[ii] = 22;
+ }
+ qsair_scrn_start[0] = 0;
+ qsair_scrn_start[1] = 0;
+ qsair_scrn_start[2] = 0;
+ qsair_scrn_count[0] = time_len;
+ qsair_scrn_count[1] = lat_len;
+ qsair_scrn_count[2] = lon_len;
+ stat = ncmpi_put_vara_float_all(ncid, qsair_scrn_id, qsair_scrn_start, qsair_scrn_count, qsair_scrn);
+ check_err(stat,__LINE__,__FILE__);
+ }
+
+ { /* store topog */
+ MPI_Offset topog_start[RANK_topog];
+ MPI_Offset topog_count[RANK_topog];
+ float topog[LON_LEN*LAT_LEN];
+
+ for(ii = 0; ii < LAT_LEN * LON_LEN; ii++) {
+ topog[ii] = 33;
+ }
+ topog_start[0] = 0;
+ topog_start[1] = 0;
+ topog_start[2] = 0;
+ topog_count[0] = time_len;
+ topog_count[1] = lat_len;
+ topog_count[2] = lon_len;
+ stat = ncmpi_put_vara_float_all(ncid, topog_id, topog_start, topog_count, topog);
+ check_err(stat,__LINE__,__FILE__);
+ }
+
+ { /* store mslp */
+ MPI_Offset mslp_start[RANK_mslp];
+ MPI_Offset mslp_count[RANK_mslp];
+ float mslp[LON_LEN*LAT_LEN];
+
+ for(ii = 0; ii < LAT_LEN * LON_LEN; ii++) {
+ mslp[ii] = 44;
+ }
+ mslp_start[0] = 0;
+ mslp_start[1] = 0;
+ mslp_start[2] = 0;
+ mslp_count[0] = time_len;
+ mslp_count[1] = lat_len;
+ mslp_count[2] = lon_len;
+ stat = ncmpi_put_vara_float_all(ncid, mslp_id, mslp_start, mslp_count, mslp);
+ check_err(stat,__LINE__,__FILE__);
+ }
+
+ { /* store sfc_temp */
+ MPI_Offset sfc_temp_start[RANK_sfc_temp];
+ MPI_Offset sfc_temp_count[RANK_sfc_temp];
+ float sfc_temp[LON_LEN*LAT_LEN];
+
+ for(ii = 0; ii < LAT_LEN * LON_LEN; ii++) {
+ sfc_temp[ii] = 55;
+ }
+ sfc_temp_start[0] = 0;
+ sfc_temp_start[1] = 0;
+ sfc_temp_start[2] = 0;
+ sfc_temp_count[0] = time_len;
+ sfc_temp_count[1] = lat_len;
+ sfc_temp_count[2] = lon_len;
+ stat = ncmpi_put_vara_float_all(ncid, sfc_temp_id, sfc_temp_start, sfc_temp_count, sfc_temp);
+ check_err(stat,__LINE__,__FILE__);
+ }
+
+ { /* store zonal_wnd */
+ /* Bug exposed when written in reverse order. */
+ for(i = LVL_LEN - 1; i>=0; i--)
+ /* for(i = 0; i < LVL_LEN; i++) */
+ {
+ int izw;
+ for(izw = 0; izw < TIME_LEN * LAT_LEN * LON_LEN; izw++) {
+ zonal_wnd[izw] = 100 + i;
+ }
+ zonal_wnd_start[0] = 0;
+ zonal_wnd_start[1] = i;
+ zonal_wnd_start[2] = 0;
+ zonal_wnd_start[3] = 0;
+ zonal_wnd_count[0] = time_len;
+ zonal_wnd_count[1] = 1;
+ zonal_wnd_count[2] = lat_len;
+ zonal_wnd_count[3] = lon_len;
+ stat = ncmpi_put_vara_float_all(ncid, zonal_wnd_id, zonal_wnd_start, zonal_wnd_count, zonal_wnd);
+ check_err(stat,__LINE__,__FILE__);
+ }
+ }
+ stat = ncmpi_close(ncid);
+ check_err(stat,__LINE__,__FILE__);
+ return 0;
+}
+
+int
+main(int argc, char **argv)
+{
+ char filename[256], fill_filename[256], nofill_filename[256];
+ int rank, nprocs, err, nerrs=0;
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+
+ if (argc > 2) {
+ if (!rank) printf("Usage: %s [filename]\n",argv[0]);
+ MPI_Finalize();
+ return 0;
+ }
+ strcpy(filename, "testfile.nc");
+ if (argc == 2) strcpy(filename, argv[1]);
+ MPI_Bcast(filename, 256, MPI_CHAR, 0, MPI_COMM_WORLD);
+
+ char cmd_str[256];
+ sprintf(cmd_str, "*** TESTING C %s for fill/nofill modes ", argv[0]);
+ if (rank == 0) printf("%-66s ------ ", cmd_str);
+
+ sprintf(fill_filename, "%s.fill", filename);
+ sprintf(nofill_filename, "%s.nofill", filename);
+ nerrs += create_file(nofill_filename, NC_NOFILL);
+ nerrs += create_file(fill_filename, NC_FILL);
+ {
+ int ncid1, ncid2;
+ int nvars1, nvars2;
+ int varid;
+ int badvars;
+
+ /* compare data in two files created with nofill mode and fill
+ * mode, which should be identical if all the data were written */
+ err = ncmpi_open(MPI_COMM_WORLD, nofill_filename, NC_NOWRITE, MPI_INFO_NULL, &ncid1); ERR
+ err = ncmpi_open(MPI_COMM_WORLD, fill_filename, NC_NOWRITE, MPI_INFO_NULL, &ncid2); ERR
+
+ err = ncmpi_inq_nvars(ncid1, &nvars1); ERR
+ err = ncmpi_inq_nvars(ncid2, &nvars2); ERR
+ if (nvars1 != nvars2) {
+ printf("Number of variables disagree %d != %d\n",nvars1,nvars2);
+ nerrs++;
+ }
+ badvars = 0;
+ for(varid = 0; varid < nvars1; varid++) {
+ MPI_Offset nvals, nn;
+ int ndims, *dimids, dim;
+ nc_type vtype;
+ char varname1[NC_MAX_NAME];
+ char varname2[NC_MAX_NAME];
+ /* How many values in this variable to compare? */
+ err = ncmpi_inq_varndims(ncid1, varid, &ndims); ERR
+ dimids = malloc((ndims + 1) * sizeof(int));
+ if (!dimids) printf("Error in file %s line %d\n",__FILE__,__LINE__);
+ err = ncmpi_inq_vardimid (ncid1, varid, dimids); ERR
+ nvals = 1;
+ for(dim = 0; dim < ndims; dim++) {
+ MPI_Offset len;
+ err = ncmpi_inq_dimlen(ncid1, dimids[dim], &len); ERR
+ nvals *= len;
+ }
+ err = ncmpi_inq_vartype(ncid1, varid, &vtype); ERR
+ err = ncmpi_inq_varname(ncid1, varid, varname1); ERR
+ err = ncmpi_inq_varname(ncid1, varid, varname2); ERR
+
+ if (vtype != NC_CHAR) { /* numeric data, just read in as doubles */
+ double *data1, *data2;
+ /* Allocate space to hold values in both files */
+ data1 = malloc((nvals + 1) * sizeof(double));
+ if (!data1) printf("Error in file %s line %d\n",__FILE__,__LINE__);
+ data2 = malloc((nvals + 1) * sizeof(double));
+ if (!data2) printf("Error in file %s line %d\n",__FILE__,__LINE__);
+ /* Read in values */
+ err = ncmpi_get_var_double_all(ncid1, varid, data1); ERR
+ err = ncmpi_get_var_double_all(ncid2, varid, data2); ERR
+ /* Compare values */
+ for(nn = 0; nn < nvals; nn++) {
+ if (data1[nn] != data2[nn]) {
+ badvars++;
+ fprintf(stderr,
+ "\tFrom nofill file, %s[%lu] = %.15g\tFrom fill file, %s[%lu] = %.15g\n",
+ varname1, (unsigned long)nn, data1[nn], varname2, (unsigned long)nn, data2[nn]);
+ break;
+ };
+ }
+ free(data1);
+ free(data2);
+ } else { /* character data */
+ char *data1, *data2;
+ /* Allocate space to hold values in both files */
+ data1 = malloc((nvals + 1) * sizeof(char));
+ if (!data1) printf("Error in file %s line %d\n",__FILE__,__LINE__);
+ data2 = malloc((nvals + 1) * sizeof(char));
+ if (!data2) printf("Error in file %s line %d\n",__FILE__,__LINE__);
+ /* Read in values */
+ err = ncmpi_get_var_text_all(ncid1, varid, data1); ERR
+ err = ncmpi_get_var_text_all(ncid2, varid, data2); ERR
+ /* Compare values */
+ for(nn = 0; nn < nvals; nn++) {
+ if (data1[nn] != data2[nn]) {
+ badvars++;
+ fprintf(stderr,
+ "\tFrom nofill file, %s[%lu] = %d\tFrom fill file, %s[%lu] = %d\n",
+ varname1, (unsigned long)nn, data1[nn], varname2, (unsigned long)nn, data2[nn]);
+ break;
+ };
+ }
+ free(data1);
+ free(data2);
+ }
+ free(dimids);
+ }
+ if(badvars > 0) printf("Error in file %s line %d\n",__FILE__,__LINE__);
+ err = ncmpi_close(ncid1); ERR
+ err = ncmpi_close(ncid2); ERR
+ }
+
+ /* check if PnetCDF freed all internal malloc */
+ MPI_Offset malloc_size, sum_size;
+ err = ncmpi_inq_malloc_size(&malloc_size);
+ if (err == NC_NOERR) {
+ MPI_Reduce(&malloc_size, &sum_size, 1, MPI_OFFSET, MPI_SUM, 0, MPI_COMM_WORLD);
+ if (rank == 0 && sum_size > 0)
+ printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n",
+ sum_size);
+ }
+
+ MPI_Allreduce(MPI_IN_PLACE, &nerrs, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
+ if (rank == 0) {
+ if (nerrs) printf(FAIL_STR,nerrs);
+ else printf(PASS_STR);
+ }
+
+ MPI_Finalize();
+ return 0;
+}
diff --git a/test/nc_test/tst_norm.c b/test/nc_test/tst_norm.c
new file mode 100644
index 0000000..57a5261
--- /dev/null
+++ b/test/nc_test/tst_norm.c
@@ -0,0 +1,218 @@
+/*
+ * Copyright (C) 2014, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ */
+/* $Id: tst_norm.c 2219 2015-12-11 22:30:03Z wkliao $ */
+
+/* This program is based on the test program tst_norm.c of the netCDF package */
+
+/* This is part of the netCDF package.
+ Copyright 2006 University Corporation for Atmospheric Research/Unidata.
+ See COPYRIGHT file for conditions of use.
+
+ This is a very simple example which tests NFC normalization of
+ Unicode names encoded with UTF-8.
+*/
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <pnetcdf.h>
+
+#include <testutils.h>
+
+/* The data file we will create. */
+#define UNITS "units"
+#define NDIMS 1
+#define NX 18
+
+#define ERR {if (err != NC_NOERR) {printf("Error at %s line %d: %s\n",__func__,__LINE__,ncmpi_strerror(err)); return 1;}}
+
+static
+int tst_norm(char *filename, int cmode)
+{
+ int ncid, dimid, varid;
+ int dimids[NDIMS];
+
+ /* unnormalized UTF-8 encoding for Unicode 8-character "Hello" in Greek: */
+ unsigned char uname_utf8[] = {
+ 0x41, /* LATIN CAPITAL LETTER A */
+ 0xCC, 0x80, /* COMBINING GRAVE ACCENT */
+ 0x41, /* LATIN CAPITAL LETTER A */
+ 0xCC, 0x81, /* COMBINING ACUTE ACCENT */
+ 0x41, /* LATIN CAPITAL LETTER A */
+ 0xCC, 0x82, /* COMBINING CIRCUMFLEX ACCENT */
+ 0x41, /* LATIN CAPITAL LETTER A */
+ 0xCC, 0x83, /* COMBINING TILDE */
+ 0x41, /* LATIN CAPITAL LETTER A */
+ 0xCC, 0x88, /* COMBINING DIAERESIS */
+ 0x41, /* LATIN CAPITAL LETTER A */
+ 0xCC, 0x8A, /* COMBINING RING ABOVE */
+ 0x43, /* LATIN CAPITAL LETTER C */
+ 0xCC, 0xA7, /* COMBINING CEDILLA */
+ 0x45, /* LATIN CAPITAL LETTER E */
+ 0xCC, 0x80, /* COMBINING GRAVE ACCENT */
+ 0x45, /* LATIN CAPITAL LETTER E */
+ 0xCC, 0x81, /* COMBINING ACUTE ACCENT */
+ 0x45, /* LATIN CAPITAL LETTER E */
+ 0xCC, 0x82, /* COMBINING CIRCUMFLEX ACCENT */
+ 0x45, /* LATIN CAPITAL LETTER E */
+ 0xCC, 0x88, /* COMBINING DIAERESIS */
+ 0x49, /* LATIN CAPITAL LETTER I */
+ 0xCC, 0x80, /* COMBINING GRAVE ACCENT */
+ 0x49, /* LATIN CAPITAL LETTER I */
+ 0xCC, 0x81, /* COMBINING ACUTE ACCENT */
+ 0x49, /* LATIN CAPITAL LETTER I */
+ 0xCC, 0x82, /* COMBINING CIRCUMFLEX ACCENT */
+ 0x49, /* LATIN CAPITAL LETTER I */
+ 0xCC, 0x88, /* COMBINING DIAERESIS */
+ 0x4E, /* LATIN CAPITAL LETTER N */
+ 0xCC, 0x83, /* COMBINING TILDE */
+ 0x00
+ };
+
+ /* NFC normalized UTF-8 encoding for same Unicode string: */
+ unsigned char nname_utf8[] = {
+ 0xC3, 0x80, /* LATIN CAPITAL LETTER A WITH GRAVE */
+ 0xC3, 0x81, /* LATIN CAPITAL LETTER A WITH ACUTE */
+ 0xC3, 0x82, /* LATIN CAPITAL LETTER A WITH CIRCUMFLEX */
+ 0xC3, 0x83, /* LATIN CAPITAL LETTER A WITH TILDE */
+ 0xC3, 0x84, /* LATIN CAPITAL LETTER A WITH DIAERESIS */
+ 0xC3, 0x85, /* LATIN CAPITAL LETTER A WITH RING ABOVE */
+ 0xC3, 0x87, /* LATIN CAPITAL LETTER C WITH CEDILLA */
+ 0xC3, 0x88, /* LATIN CAPITAL LETTER E WITH GRAVE */
+ 0xC3, 0x89, /* LATIN CAPITAL LETTER E WITH ACUTE */
+ 0xC3, 0x8A, /* LATIN CAPITAL LETTER E WITH CIRCUMFLEX */
+ 0xC3, 0x8B, /* LATIN CAPITAL LETTER E WITH DIAERESIS */
+ 0xC3, 0x8C, /* LATIN CAPITAL LETTER I WITH GRAVE */
+ 0xC3, 0x8D, /* LATIN CAPITAL LETTER I WITH ACUTE */
+ 0xC3, 0x8E, /* LATIN CAPITAL LETTER I WITH CIRCUMFLEX */
+ 0xC3, 0x8F, /* LATIN CAPITAL LETTER I WITH DIAERESIS */
+ 0xC3, 0x91, /* LATIN CAPITAL LETTER N WITH TILDE */
+ 0x00
+ };
+
+/* Unnormalized name used for dimension, variable, and attribute value */
+#define UNAME ((char *) uname_utf8)
+#define UNAMELEN (sizeof uname_utf8)
+/* Normalized name */
+#define NNAME ((char *) nname_utf8)
+#define NNAMELEN (sizeof nname_utf8)
+
+ char name_in[UNAMELEN + 1], strings_in[UNAMELEN + 1];
+ nc_type att_type;
+ MPI_Offset att_len;
+ int err, dimid_in, varid_in, attnum_in;
+ int attvals[] = {42};
+#define ATTNUM ((sizeof attvals)/(sizeof attvals[0]))
+
+ err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, MPI_INFO_NULL,&ncid); ERR
+
+ /* Define dimension with unnormalized Unicode UTF-8 encoded name */
+ err = ncmpi_def_dim(ncid, UNAME, NX, &dimid); ERR
+ dimids[0] = dimid;
+
+ /* Define variable with same name */
+ err = ncmpi_def_var(ncid, UNAME, NC_CHAR, NDIMS, dimids, &varid); ERR
+
+ /* Create string attribute with same value */
+ err = ncmpi_put_att_text(ncid, varid, UNITS, UNAMELEN, UNAME); ERR
+
+ /* Create int attribute with same name */
+ err = ncmpi_put_att_int(ncid, varid, UNAME, NC_INT, ATTNUM, attvals); ERR
+
+ /* Try to create dimension and variable with NFC-normalized
+ * version of same name. These should fail, as unnormalized name
+ * should have been normalized in library, so these are attempts to
+ * create duplicate netCDF objects. */
+ if ((err = ncmpi_def_dim(ncid, NNAME, NX, &dimid)) != NC_ENAMEINUSE) {
+ printf("Error at line %d: expecting error code %d but got %d\n",__LINE__,NC_ENAMEINUSE,err);
+ return 1;
+ }
+
+ if ((err=ncmpi_def_var(ncid, NNAME, NC_CHAR, NDIMS, dimids, &varid)) != NC_ENAMEINUSE) {
+ printf("Error at line %d: expecting error code %d but got %d\n",__LINE__,NC_ENAMEINUSE,err);
+ return 1;
+ }
+ err = ncmpi_enddef(ncid); ERR
+
+ /* Write string data, UTF-8 encoded, to the file */
+ err = ncmpi_put_var_text_all(ncid, varid, UNAME); ERR
+ err = ncmpi_close(ncid); ERR
+
+ /* Check it out. */
+ err = ncmpi_open(MPI_COMM_WORLD, filename, NC_NOWRITE, MPI_INFO_NULL, &ncid); ERR
+ err = ncmpi_inq_varid(ncid, UNAME, &varid); ERR
+ err = ncmpi_inq_varname(ncid, varid, name_in); ERR
+ err = strncmp(NNAME, name_in, NNAMELEN); ERR
+ err = ncmpi_inq_varid(ncid, NNAME, &varid_in); ERR
+ if ((err = ncmpi_inq_dimid(ncid, UNAME, &dimid_in)) || dimid != dimid_in)
+ {printf("Error at line %d\n",__LINE__);return 1;}
+ if ((err = ncmpi_inq_dimid(ncid, NNAME, &dimid_in)) || dimid != dimid_in)
+ {printf("Error at line %d\n",__LINE__);return 1;}
+ err = ncmpi_inq_att(ncid, varid, UNITS, &att_type, &att_len); ERR
+ if ( att_type != NC_CHAR || att_len != UNAMELEN)
+ {printf("Error at line %d\n",__LINE__);return 1;}
+ err = ncmpi_get_att_text(ncid, varid, UNITS, strings_in); ERR
+ strings_in[UNAMELEN] = '\0';
+ err = strncmp(UNAME, strings_in, UNAMELEN); ERR
+ if ((err = ncmpi_inq_attid(ncid, varid, UNAME, &attnum_in)) || ATTNUM != attnum_in)
+ {printf("Error at line %d\n",__LINE__);return 1;}
+ if ((err = ncmpi_inq_attid(ncid, varid, NNAME, &attnum_in)) || ATTNUM != attnum_in)
+ {printf("Error at line %d\n",__LINE__);return 1;}
+ err = ncmpi_close(ncid); ERR
+
+ return 0;
+}
+
+int
+main(int argc, char **argv)
+{
+ char filename[256];
+ int rank, nprocs, cmode, err, nerrs=0, verbose=0;
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+
+ if (argc > 2) {
+ if (!rank) printf("Usage: %s [filename]\n",argv[0]);
+ MPI_Finalize();
+ return 0;
+ }
+ strcpy(filename, "testfile.nc");
+ if (argc == 2) strcpy(filename, argv[1]);
+ MPI_Bcast(filename, 256, MPI_CHAR, 0, MPI_COMM_WORLD);
+
+ char cmd_str[256];
+ sprintf(cmd_str, "*** TESTING C %s for emulating netCDF tst_norm ", argv[0]);
+ if (rank == 0) printf("%-66s ------ ", cmd_str);
+
+ if (verbose) printf("\n*** testing UTF-8 normalization...");
+
+ /* test CDF-2 format */
+ cmode = NC_CLOBBER | NC_64BIT_OFFSET;
+ nerrs += tst_norm(filename, cmode);
+
+ /* test CDF-5 format */
+ cmode = NC_CLOBBER | NC_64BIT_DATA;
+ nerrs += tst_norm(filename, cmode);
+
+ /* check if PnetCDF freed all internal malloc */
+ MPI_Offset malloc_size, sum_size;
+ err = ncmpi_inq_malloc_size(&malloc_size);
+ if (err == NC_NOERR) {
+ MPI_Reduce(&malloc_size, &sum_size, 1, MPI_OFFSET, MPI_SUM, 0, MPI_COMM_WORLD);
+ if (rank == 0 && sum_size > 0)
+ printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n",
+ sum_size);
+ }
+
+ MPI_Allreduce(MPI_IN_PLACE, &nerrs, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
+ if (rank == 0) {
+ if (nerrs) printf(FAIL_STR,nerrs);
+ else printf(PASS_STR);
+ }
+
+ MPI_Finalize();
+ return 0;
+}
diff --git a/test/nc_test/tst_small.c b/test/nc_test/tst_small.c
new file mode 100644
index 0000000..10fd706
--- /dev/null
+++ b/test/nc_test/tst_small.c
@@ -0,0 +1,481 @@
+/*
+ * Copyright (C) 2014, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ */
+/* $Id: tst_small.c 2205 2015-11-28 20:41:50Z wkliao $ */
+
+/* This program is based on the test program tst_small.c of the netCDF package */
+
+/* This is part of the netCDF package. Copyright 2005 University
+ Corporation for Atmospheric Research/Unidata See COPYRIGHT file for
+ conditions of use. See www.unidata.ucar.edu for more info.
+
+ Test small files.
+*/
+
+#include <stdio.h>
+#include <string.h>
+#include <mpi.h>
+#include <pnetcdf.h>
+
+#include <testutils.h>
+
+/* Test everything for classic, 64-bit offseti, and 64-bit data files. */
+#define NUM_FORMATS 3
+
+#define ATT_NAME "Atom"
+#define MAX_LEN 7
+
+#define ERR {if (err != NC_NOERR) {printf("Error at %s line %d: %s\n",__func__,__LINE__,ncmpi_strerror(err)); return 1;}}
+
+static int
+test_small_atts(const char *testfile, int cmode)
+{
+ int ncid, err;
+ char att[MAX_LEN + 1], att_in[MAX_LEN + 1], source[MAX_LEN + 1] = "0123456";
+ int ndims, nvars, natts, unlimdimid;
+ MPI_Offset len_in;
+ int t, f;
+
+ /* Run this with and without fill mode. */
+ for (f = 0; f < 2; f++)
+ {
+ /* Create small files with an attribute that grows by one each
+ * time. */
+ for (t = 1; t < MAX_LEN; t++)
+ {
+ /* Create null-terminated text string of correct length. */
+ strncpy(att, source, t);
+
+ /* Create a file with one attribute. */
+ err = ncmpi_create(MPI_COMM_WORLD, testfile,cmode, MPI_INFO_NULL, &ncid); ERR
+ err = ncmpi_put_att_text(ncid, NC_GLOBAL, ATT_NAME, t + 1, att); ERR
+ if (f) { err=ncmpi_set_fill(ncid, NC_NOFILL, NULL); ERR}
+ err=ncmpi_close(ncid); ERR;
+
+ /* Reopen the file and check it. */
+ err=ncmpi_open(MPI_COMM_WORLD, testfile, NC_NOWRITE, MPI_INFO_NULL, &ncid); ERR
+ err=ncmpi_inq(ncid, &ndims, &nvars, &natts, &unlimdimid); ERR
+ if (ndims != 0 && nvars != 0 && natts != 1 && unlimdimid != -1) {printf("Error at line %d\n",__LINE__);return 1;}
+ err=ncmpi_inq_attlen(ncid, NC_GLOBAL, ATT_NAME, &len_in); ERR
+ if (len_in != t + 1) {printf("Error at line %d\n",__LINE__);return 1;}
+ err=ncmpi_get_att_text(ncid, NC_GLOBAL, ATT_NAME, att_in); ERR
+ if (strncmp(att_in, att, t)) {printf("Error at line %d\n",__LINE__);return 1;}
+ err=ncmpi_close(ncid); ERR
+ }
+ }
+ return 0;
+}
+
+#define DIM1_NAME "Time"
+#define DIM2_NAME "DataStrLen"
+#define VAR_NAME "Times"
+#define STR_LEN 19
+#define NUM_VALS 2
+#define NDIMS 2
+#define TITLE " OUTPUT FROM WRF V2.0.3.1 MODEL"
+#define ATT_NAME2 "TITLE"
+
+/* Test a small file with an unlimited dimension. NOTE: Normally I
+ * write a NULL terminator for my attributes and text strings, but
+ * this reproduces a bug that a fortran user sent us. So string data
+ * are written to the file without null terminators. - Ed */
+static int
+test_small_unlim(const char *testfile, int cmode)
+{
+ int i, err, ncid, dimids[NDIMS], varid;
+ char data[NUM_VALS][STR_LEN + 1], data_in[NUM_VALS][STR_LEN];
+ int ndims, nvars, natts, unlimdimid;
+ MPI_Offset start[NDIMS], count[NDIMS];
+
+ /* Create null-terminated text strings of correct length. */
+ /*for (i = 0; i < NUM_VALS; i++)
+ strcpy(data[i], source);*/
+ strcpy(data[0], "2005-04-11_12:00:00");
+ strcpy(data[1], "2005-04-11_13:00:00");
+
+ /* Create a file with two dimensions, one unlimited, and one
+ * var, and a global att. */
+ err=ncmpi_create(MPI_COMM_WORLD, testfile,cmode, MPI_INFO_NULL, &ncid); ERR
+ err=ncmpi_def_dim(ncid, DIM1_NAME, NC_UNLIMITED, dimids); ERR
+ err=ncmpi_def_dim(ncid, DIM2_NAME, STR_LEN, &dimids[1]); ERR
+ err=ncmpi_def_var(ncid, VAR_NAME, NC_CHAR, 2, dimids, &varid); ERR
+ err=ncmpi_put_att_text(ncid, NC_GLOBAL, ATT_NAME2, strlen(TITLE), TITLE); ERR
+ err=ncmpi_enddef(ncid); ERR
+
+ /* Write some records of var data. */
+ count[0] = 1;
+ count[1] = STR_LEN;
+ start[1] = 0;
+ for (start[0] = 0; start[0] < NUM_VALS; start[0]++) {
+ err=ncmpi_put_vara_text_all(ncid, varid, start, count, data[start[0]]); ERR
+ }
+
+ /* We're done! */
+ err=ncmpi_close(ncid); ERR
+
+ /* Reopen the file and check it. */
+ err=ncmpi_open(MPI_COMM_WORLD, testfile, NC_NOWRITE, MPI_INFO_NULL, &ncid); ERR
+ err=ncmpi_inq(ncid, &ndims, &nvars, &natts, &unlimdimid); ERR
+ if (ndims != 2 && nvars != 1 && natts != 0 && unlimdimid != 0) {printf("Error at line %d\n",__LINE__);return 1;}
+ err=ncmpi_get_var_text_all(ncid, varid, (char *)data_in); ERR
+ for (i = 0; i < NUM_VALS; i++)
+ /* if (strncmp(data[i], data_in[i], STR_LEN)) {printf("Error at line %d\n",__LINE__);return 1;} */
+ if (strncmp(data[i], data_in[i], STR_LEN)) {
+printf("i=%d data=%s data_in=%s\n",i,data[i],data_in[i]);
+ }
+ err=ncmpi_close(ncid); ERR
+ return 0;
+}
+
+/* Test a small file with a fixed dimension. */
+static int
+test_small_fixed(const char *testfile, int cmode)
+{
+ int i, err, ncid, dimids[NDIMS], varid;
+ char data[NUM_VALS][STR_LEN + 1], data_in[NUM_VALS][STR_LEN];
+ int ndims, nvars, natts, unlimdimid;
+ MPI_Offset start[NDIMS], count[NDIMS];
+
+ /* Create null-terminated text strings of correct length. */
+ /*for (i = 0; i < NUM_VALS; i++)
+ strcpy(data[i], source);*/
+ strcpy(data[0], "2005-04-11_12:00:00");
+ strcpy(data[1], "2005-04-11_13:00:00");
+
+ /* Create a file with two dimensions, one unlimited, and one
+ * var, and a global att. */
+ err=ncmpi_create(MPI_COMM_WORLD, testfile,cmode, MPI_INFO_NULL, &ncid); ERR
+ err=ncmpi_def_dim(ncid, DIM1_NAME, NUM_VALS, dimids); ERR
+ err=ncmpi_def_dim(ncid, DIM2_NAME, STR_LEN, &dimids[1]); ERR
+ err=ncmpi_def_var(ncid, VAR_NAME, NC_CHAR, NDIMS, dimids, &varid); ERR
+ err=ncmpi_put_att_text(ncid, NC_GLOBAL, ATT_NAME2, strlen(TITLE), TITLE); ERR
+ err=ncmpi_enddef(ncid); ERR
+
+ /* Write some records of var data. */
+ count[0] = 1;
+ count[1] = STR_LEN;
+ start[1] = 0;
+ for (start[0] = 0; start[0] < NUM_VALS; start[0]++) {
+ err=ncmpi_put_vara_text_all(ncid, varid, start, count, data[start[0]]); ERR
+ }
+
+ /* We're done! */
+ err=ncmpi_close(ncid); ERR
+
+ /* Reopen the file and check it. */
+ err=ncmpi_open(MPI_COMM_WORLD, testfile, NC_NOWRITE, MPI_INFO_NULL, &ncid); ERR
+ err=ncmpi_inq(ncid, &ndims, &nvars, &natts, &unlimdimid); ERR
+ if (ndims != 2 && nvars != 1 && natts != 0 && unlimdimid != -1) {printf("Error at line %d\n",__LINE__);return 1;}
+ err=ncmpi_get_var_text_all(ncid, varid, (char *)data_in); ERR
+ for (i = 0; i < NUM_VALS; i++)
+ if (strncmp(data[i], data_in[i], STR_LEN)) {printf("Error at line %d\n",__LINE__);return 1;}
+ err=ncmpi_close(ncid); ERR
+ return 0;
+}
+
+/* Test a small file with one var. */
+static int
+test_small_one(const char *testfile, int cmode)
+{
+ int err, ncid, dimid, varid;
+ char data = 'h', data_in;
+ int ndims, nvars, natts, unlimdimid;
+ MPI_Offset start[NDIMS], count[NDIMS];
+
+ /* Create a file with one ulimited dimensions, and one var. */
+ err=ncmpi_create(MPI_COMM_WORLD, testfile,cmode, MPI_INFO_NULL, &ncid); ERR
+ err=ncmpi_def_dim(ncid, DIM1_NAME, NC_UNLIMITED, &dimid); ERR
+ err=ncmpi_def_var(ncid, VAR_NAME, NC_CHAR, 1, &dimid, &varid); ERR
+ err=ncmpi_enddef(ncid); ERR
+
+ /* Write one record of var data, a single character. */
+ count[0] = 1;
+ start[0] = 0;
+ err=ncmpi_put_vara_text_all(ncid, varid, start, count, &data); ERR
+
+ /* We're done! */
+ err=ncmpi_close(ncid); ERR
+
+ /* Reopen the file and check it. */
+ err=ncmpi_open(MPI_COMM_WORLD, testfile, NC_NOWRITE, MPI_INFO_NULL, &ncid); ERR
+ err=ncmpi_inq(ncid, &ndims, &nvars, &natts, &unlimdimid); ERR
+ if (ndims != 1 && nvars != 1 && natts != 0 && unlimdimid != 0) {printf("Error at line %d\n",__LINE__);return 1;}
+ err=ncmpi_get_var_text_all(ncid, varid, &data_in); ERR
+ if (data_in != data) {printf("Error at line %d\n",__LINE__);return 1;}
+ err=ncmpi_close(ncid); ERR
+ return 0;
+}
+
+#define ONE_DIM 1
+#define MAX_RECS 10
+
+/* Test a small file with one record var, which grows. */
+static int
+test_one_growing(const char *testfile, int cmode)
+{
+ int err, ncid, dimid, varid;
+ char data[MAX_RECS], data_in;
+ MPI_Offset start[ONE_DIM], count[ONE_DIM], index[ONE_DIM], len_in;
+ int r, f;
+
+ /* Create some phoney data. */
+ for (data[0] = 'a', r = 1; r < MAX_RECS; r++)
+ data[r] = data[r - 1] + 1;
+
+ /* Run this with and without fill mode. */
+ for (f = 0; f < 2; f++)
+ {
+ /* Create a file with one ulimited dimensions, and one var. */
+ err=ncmpi_create(MPI_COMM_WORLD, testfile,cmode, MPI_INFO_NULL, &ncid); ERR
+ err=ncmpi_def_dim(ncid, DIM1_NAME, NC_UNLIMITED, &dimid); ERR
+ err=ncmpi_def_var(ncid, VAR_NAME, NC_CHAR, 1, &dimid, &varid); ERR
+ err=ncmpi_close(ncid); ERR
+
+ /* Normally one would not close and reopen the file for each
+ * record, but I am giving the library a little work-out here... */
+ for (r = 0; r < MAX_RECS; r++)
+ {
+ /* Write one record of var data, a single character. */
+ err=ncmpi_open(MPI_COMM_WORLD, testfile, NC_WRITE, MPI_INFO_NULL, &ncid); ERR
+ /* if (f) { err=ncmpi_set_fill(ncid, NC_NOFILL, NULL); ERR} */
+ count[0] = 1;
+ start[0] = r;
+ err=ncmpi_put_vara_text_all(ncid, varid, start, count, &data[r]); ERR
+ err=ncmpi_close(ncid); ERR
+
+ /* Reopen the file and check it. */
+ err=ncmpi_open(MPI_COMM_WORLD, testfile, NC_NOWRITE, MPI_INFO_NULL, &ncid); ERR
+ err=ncmpi_inq_dimlen(ncid, 0, &len_in); ERR
+ if (len_in != r + 1) {printf("Error at line %d\n",__LINE__);return 1;}
+ index[0] = r;
+ err=ncmpi_begin_indep_data(ncid); ERR
+ err=ncmpi_get_var1_text(ncid, 0, index, &data_in); ERR
+ if (data_in != data[r]) {printf("Error at line %d\n",__LINE__);return 1;}
+ err=ncmpi_close(ncid); ERR
+ } /* Next record. */
+ }
+ return 0;
+}
+
+#define ONE_DIM 1
+#define MAX_RECS 10
+
+/* Test a small file with one record var, which grows, and has
+ * attributes. */
+static int
+test_one_growing_with_att(const char *testfile, int cmode)
+{
+ int err, ncid, dimid, varid;
+ char data[MAX_RECS], data_in;
+ char att_name[NC_MAX_NAME + 1];
+ MPI_Offset start[ONE_DIM], count[ONE_DIM], index[ONE_DIM], len_in;
+ int r;
+
+ /* Create a file with one ulimited dimensions, and one var. */
+ err=ncmpi_create(MPI_COMM_WORLD, testfile,cmode, MPI_INFO_NULL, &ncid); ERR
+ err=ncmpi_def_dim(ncid, DIM1_NAME, NC_UNLIMITED, &dimid); ERR
+ err=ncmpi_def_var(ncid, VAR_NAME, NC_CHAR, 1, &dimid, &varid); ERR
+ err=ncmpi_close(ncid); ERR
+
+ /* Create some phoney data. */
+ for (data[0] = 'a', r = 1; r < MAX_RECS; r++)
+ data[r] = data[r - 1] + 1;
+
+ /* Normally one would not close and reopen the file for each
+ * record, nor add an attribute each time I add a record, but I am
+ * giving the library a little work-out here... */
+ for (r = 0; r < MAX_RECS; r++)
+ {
+ /* Write one record of var data, a single character. */
+ err=ncmpi_open(MPI_COMM_WORLD, testfile, NC_WRITE, MPI_INFO_NULL, &ncid); ERR
+ count[0] = 1;
+ start[0] = r;
+ err=ncmpi_put_vara_text_all(ncid, varid, start, count, &data[r]); ERR
+ sprintf(att_name, "a_%d", data[r]);
+ err=ncmpi_redef(ncid); ERR
+ err=ncmpi_put_att_text(ncid, varid, att_name, 1, &data[r]); ERR
+ err=ncmpi_close(ncid); ERR
+
+ /* Reopen the file and check it. */
+ err=ncmpi_open(MPI_COMM_WORLD, testfile, NC_NOWRITE, MPI_INFO_NULL, &ncid); ERR
+ err=ncmpi_inq_dimlen(ncid, 0, &len_in); ERR
+ if (len_in != r + 1) {printf("Error at line %d\n",__LINE__);return 1;}
+ index[0] = r;
+ err=ncmpi_begin_indep_data(ncid); ERR
+ err=ncmpi_get_var1_text(ncid, 0, index, &data_in); ERR
+ if (data_in != data[r]) {printf("Error at line %d\n",__LINE__);return 1;}
+ err=ncmpi_get_att_text(ncid, varid, att_name, &data_in); ERR
+ if (data_in != data[r]) {printf("Error at line %d\n",__LINE__);return 1;}
+ err=ncmpi_close(ncid); ERR
+ } /* Next record. */
+ return 0;
+}
+
+#define VAR_NAME2 "var2"
+#define NUM_VARS 2
+
+/* Test a small file with two record vars, which grow, and has
+ * attributes added. */
+static int
+test_two_growing_with_att(const char *testfile, int cmode)
+{
+ int err, ncid, dimid, varid[NUM_VARS];
+ char data[MAX_RECS], data_in;
+ char att_name[NC_MAX_NAME + 1];
+ MPI_Offset start[ONE_DIM], count[ONE_DIM], index[ONE_DIM], len_in;
+ int v, r;
+
+ /* Create a file with one ulimited dimensions, and one var. */
+ err=ncmpi_create(MPI_COMM_WORLD, testfile,cmode, MPI_INFO_NULL, &ncid); ERR
+ err=ncmpi_def_dim(ncid, DIM1_NAME, NC_UNLIMITED, &dimid); ERR
+ err=ncmpi_def_var(ncid, VAR_NAME, NC_CHAR, 1, &dimid, &varid[0]); ERR
+ err=ncmpi_def_var(ncid, VAR_NAME2, NC_CHAR, 1, &dimid, &varid[1]); ERR
+ err=ncmpi_close(ncid); ERR
+
+ /* Create some phoney data. */
+ for (data[0] = 'a', r = 1; r < MAX_RECS; r++)
+ data[r] = data[r - 1] + 1;
+
+ /* Normally one would not close and reopen the file for each
+ * record, nor add an attribute each time I add a record, but I am
+ * giving the library a little work-out here... */
+ for (r = 0; r < MAX_RECS; r++)
+ {
+ /* Write one record of var data, a single character. */
+ err=ncmpi_open(MPI_COMM_WORLD, testfile, NC_WRITE, MPI_INFO_NULL, &ncid); ERR
+ count[0] = 1;
+ start[0] = r;
+ sprintf(att_name, "a_%d", data[r]);
+ for (v = 0; v < NUM_VARS; v++)
+ {
+ err=ncmpi_put_vara_text_all(ncid, varid[v], start, count, &data[r]); ERR
+ err=ncmpi_redef(ncid); ERR
+ err=ncmpi_put_att_text(ncid, varid[v], att_name, 1, &data[r]); ERR
+ err=ncmpi_enddef(ncid); ERR
+ }
+ err=ncmpi_close(ncid); ERR
+
+ /* Reopen the file and check it. */
+ err=ncmpi_open(MPI_COMM_WORLD, testfile, NC_NOWRITE, MPI_INFO_NULL, &ncid); ERR
+ err=ncmpi_inq_dimlen(ncid, 0, &len_in); ERR
+ if (len_in != r + 1) {printf("Error at line %d\n",__LINE__);return 1;}
+ index[0] = r;
+ err=ncmpi_begin_indep_data(ncid); ERR
+ for (v = 0; v < NUM_VARS; v++)
+ {
+ err=ncmpi_get_var1_text(ncid, varid[v], index, &data_in); ERR
+ if (data_in != data[r]) {printf("Error at line %d\n",__LINE__);return 1;}
+ }
+ err=ncmpi_close(ncid); ERR
+ } /* Next record. */
+ return 0;
+}
+
+/* Test a small file with one var and one att. */
+static int
+test_one_with_att(const char *testfile, int cmode)
+{
+ int err, ncid, dimid, varid;
+ char data = 'h', data_in;
+ int ndims, nvars, natts, unlimdimid;
+ MPI_Offset start[NDIMS], count[NDIMS];
+
+ /* Create a file with one ulimited dimensions, and one var. */
+ err=ncmpi_create(MPI_COMM_WORLD, testfile,cmode, MPI_INFO_NULL, &ncid); ERR
+ err=ncmpi_def_dim(ncid, DIM1_NAME, NC_UNLIMITED, &dimid); ERR
+ err=ncmpi_def_var(ncid, VAR_NAME, NC_CHAR, 1, &dimid, &varid); ERR
+ err=ncmpi_put_att_text(ncid, NC_GLOBAL, ATT_NAME, 1, &data); ERR
+ err=ncmpi_enddef(ncid); ERR
+
+ /* Write one record of var data, a single character. */
+ count[0] = 1;
+ start[0] = 0;
+ err=ncmpi_put_vara_text_all(ncid, varid, start, count, &data); ERR
+
+ /* We're done! */
+ err=ncmpi_close(ncid); ERR
+
+ /* Reopen the file and check it. */
+ err=ncmpi_open(MPI_COMM_WORLD, testfile, NC_NOWRITE, MPI_INFO_NULL, &ncid); ERR
+ err=ncmpi_inq(ncid, &ndims, &nvars, &natts, &unlimdimid); ERR
+ if (ndims != 1 && nvars != 1 && natts != 0 && unlimdimid != 0) {printf("Error at line %d\n",__LINE__);return 1;}
+ err=ncmpi_get_var_text_all(ncid, varid, &data_in); ERR
+ if (data_in != data) {printf("Error at line %d\n",__LINE__);return 1;}
+ err=ncmpi_get_att_text(ncid, NC_GLOBAL, ATT_NAME, &data_in); ERR
+ if (data_in != data) {printf("Error at line %d\n",__LINE__);return 1;}
+ err=ncmpi_close(ncid); ERR
+ return 0;
+}
+
+int main(int argc, char *argv[])
+{
+ char filename[256];
+ int i, rank, nprocs, err, nerrs=0, verbose=0;
+ int cmode[NUM_FORMATS]={0, NC_64BIT_OFFSET, NC_64BIT_DATA};
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+
+ if (argc > 2) {
+ if (!rank) printf("Usage: %s [filename]\n",argv[0]);
+ MPI_Finalize();
+ return 0;
+ }
+ strcpy(filename, "testfile.nc");
+ if (argc == 2) strcpy(filename, argv[1]);
+ MPI_Bcast(filename, 256, MPI_CHAR, 0, MPI_COMM_WORLD);
+
+ char cmd_str[256];
+ sprintf(cmd_str, "*** TESTING C %s for emulating netCDF tst_small ", argv[0]);
+ if (rank == 0) printf("%-66s ------ ", cmd_str);
+
+ for (i=0; i<NUM_FORMATS; i++) {
+ if (verbose) printf("*** testing simple small file with a global attribute...");
+ nerrs += test_small_atts(filename, cmode[i]|NC_CLOBBER);
+
+ if (verbose) printf("*** testing simple small file with fixed dimensions...");
+ nerrs += test_small_fixed(filename, cmode[i]|NC_CLOBBER);
+
+ if (verbose) printf("*** testing simple small file with an unlimited dimension...");
+ nerrs += test_small_unlim(filename, cmode[i]|NC_CLOBBER);
+
+ if (verbose) printf("*** testing small file with one variable...");
+ nerrs += test_small_one(filename, cmode[i]|NC_CLOBBER);
+
+ if (verbose) printf("*** testing small file with one variable and one att...");
+ nerrs += test_one_with_att(filename, cmode[i]|NC_CLOBBER);
+
+ if (verbose) printf("*** testing small file with one record variable, which grows...");
+ nerrs += test_one_growing(filename, cmode[i]|NC_CLOBBER);
+
+ if (verbose) printf("*** testing small file with one growing record "
+ "variable, with attributes added...");
+ nerrs += test_one_growing_with_att(filename, cmode[i]|NC_CLOBBER);
+
+ if (verbose) printf("*** testing small file with two growing record "
+ "variables, with attributes added...");
+ nerrs += test_two_growing_with_att(filename, cmode[i]|NC_CLOBBER);
+ }
+
+ /* check if PnetCDF freed all internal malloc */
+ MPI_Offset malloc_size, sum_size;
+ err = ncmpi_inq_malloc_size(&malloc_size);
+ if (err == NC_NOERR) {
+ MPI_Reduce(&malloc_size, &sum_size, 1, MPI_OFFSET, MPI_SUM, 0, MPI_COMM_WORLD);
+ if (rank == 0 && sum_size > 0)
+ printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n",
+ sum_size);
+ }
+
+ MPI_Allreduce(MPI_IN_PLACE, &nerrs, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
+ if (rank == 0) {
+ if (nerrs) printf(FAIL_STR,nerrs);
+ else printf(PASS_STR);
+ }
+
+ MPI_Finalize();
+ return 0;
+}
+
diff --git a/test/nc_test/util.c b/test/nc_test/util.c
new file mode 100644
index 0000000..620436f
--- /dev/null
+++ b/test/nc_test/util.c
@@ -0,0 +1,1055 @@
+/*
+ * Copyright (C) 2003, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ *
+ * $Id: util.c 2293 2016-01-06 03:43:04Z wkliao $
+ */
+
+#include <math.h> /* floor() */
+#include "tests.h"
+
+/* Prototypes */
+
+void
+print_nok(int nok)
+{
+ if (verbose || nfails > 0)
+ print("\n");
+ print("%4d good comparisons. ", nok);
+}
+
+
+/* Is value within external type range? */
+int
+inRange(const double value, const nc_type datatype)
+{
+ switch (datatype) {
+ case NC_CHAR: return value >= X_CHAR_MIN && value <= X_CHAR_MAX;
+ case NC_BYTE: return value >= X_BYTE_MIN && value <= X_BYTE_MAX;
+ case NC_SHORT: return value >= X_SHORT_MIN && value <= X_SHORT_MAX;
+ case NC_INT: return value >= X_INT_MIN && value <= X_INT_MAX;
+ case NC_FLOAT: return value >= X_FLOAT_MIN && value <= X_FLOAT_MAX;
+ case NC_DOUBLE: return value >= X_DOUBLE_MIN && value <= X_DOUBLE_MAX;
+ case NC_UBYTE: return value >= 0 && value <= X_UCHAR_MAX;
+ case NC_USHORT: return value >= 0 && value <= X_USHORT_MAX;
+ case NC_UINT: return value >= 0 && value <= X_UINT_MAX;
+ case NC_INT64: return value >= X_INT64_MIN && value <= X_INT64_MAX;
+ case NC_UINT64: return value >= 0 && value <= X_UINT64_MAX;
+ default:
+ assert(0);
+ return(0);
+ }
+}
+
+static int
+inRange_uchar(const double value, const nc_type datatype)
+{
+ /* check value of type datatype if within uchar range */
+
+ if (datatype == NC_BYTE) {
+ /* netCDF specification make a special case for type conversion between
+ * uchar and scahr: do not check for range error. See
+ * http://www.unidata.ucar.edu/software/netcdf/docs_rc/data_type.html#type_conversion
+ */
+ return(value >= 0 && value <= 255);
+ /* this is to ensure value is within the range of uchar */
+ }
+ /* else */
+ return inRange(value, datatype);
+}
+
+static int
+inRange_float(const double value, const nc_type datatype)
+{
+ double min, max;
+
+ switch (datatype) {
+ case NC_CHAR: min = X_CHAR_MIN; max = X_CHAR_MAX; break;
+ case NC_BYTE: min = X_BYTE_MIN; max = X_BYTE_MAX; break;
+ case NC_SHORT: min = X_SHORT_MIN; max = X_SHORT_MAX; break;
+ case NC_INT: min = X_INT_MIN; max = X_INT_MAX; break;
+ case NC_FLOAT:
+ if (FLT_MAX < X_FLOAT_MAX) {
+ min = (-FLT_MAX);
+ max = FLT_MAX;
+ } else {
+ min = X_FLOAT_MIN;
+ max = X_FLOAT_MAX;
+ }
+ break;
+ case NC_DOUBLE:
+ if (FLT_MAX < X_DOUBLE_MAX) {
+ min = (-FLT_MAX);
+ max = FLT_MAX;
+ } else {
+ min = X_DOUBLE_MIN;
+ max = X_DOUBLE_MAX;
+ }
+ break;
+ case NC_UBYTE: min = 0; max = X_UCHAR_MAX; break;
+ case NC_USHORT: min = 0; max = X_USHORT_MAX; break;
+ case NC_UINT: min = 0; max = X_UINT_MAX; break;
+ case NC_INT64: min = X_INT64_MIN; max = X_INT64_MAX; break;
+ case NC_UINT64: min = 0; max = X_UINT64_MAX; break;
+ default:
+ min = 0.0;
+ max = 0.0;
+ assert(0);
+ }
+ if (!( value >= min && value <= max)) {
+#if 0 /* DEBUG */
+ if (datatype == NC_FLOAT) {
+ fprintf(stderr, "\n");
+ fprintf(stderr, "min % .17e\n", min);
+ fprintf(stderr, "value % .17e\n", value);
+ fprintf(stderr, "max % .17e\n", max);
+ }
+#endif
+ return 0;
+ }
+#if FLT_MANT_DIG != DBL_MANT_DIG
+ /* else */
+ {
+ const float fvalue = value;
+ return fvalue >= min && fvalue <= max;
+ }
+#else
+ return 1;
+#endif
+}
+
+/* wrapper for inRange to handle special NC_BYTE/uchar adjustment */
+/* this function checks whether "value" to be casted to type "itype" is
+ * within the range of external "datatype".
+ */
+int
+inRange3(const double value,
+ const nc_type datatype,
+ const nct_itype itype)
+{
+ /* netCDF specification make a special case for type conversion between
+ * uchar and scahr: do not check for range error. See
+ * http://www.unidata.ucar.edu/software/netcdf/docs_rc/data_type.html#type_conversion
+ * The _uchar and _schar functions were introduced in netCDF-3 to eliminate
+ * an ambiguity, and support both signed and unsigned byte data. In
+ * netCDF-2, whether the external NC_BYTE type represented signed or
+ * unsigned values was left up to the user. In netcdf-3, we treat NC_BYTE
+ * as signed for the purposes of conversion to short, int, long, float, or
+ * double. (Of course, no conversion takes place when the internal type is
+ * signed char.) In the _uchar functions, we treat NC_BYTE as if it were
+ * unsigned. Thus, no NC_ERANGE error can occur converting between NC_BYTE
+ * and unsigned char.
+ */
+ switch (itype) {
+ case NCT_UCHAR:
+ return inRange_uchar(value, datatype);
+ case NCT_FLOAT:
+ return inRange_float(value, datatype);
+ default:
+ break;
+ }
+ return inRange(value, datatype);
+}
+
+
+/*
+ * Does x == y, where one is internal and other external (netCDF)?
+ * Use tolerant comparison based on IEEE FLT_EPSILON or DBL_EPSILON.
+ */
+int
+equal(double x,
+ double y,
+ nc_type extType, /* external data type */
+ nct_itype itype)
+{
+ const double flt_epsilon = 1.19209290E-07;
+ const double dbl_epsilon = 2.2204460492503131E-16;
+ double epsilon;
+
+ epsilon = extType == NC_FLOAT ||
+ itype == NCT_FLOAT ? flt_epsilon : dbl_epsilon;
+
+ if (extType == NC_CHAR && itype == NCT_TEXT) {
+ /* because in-memory data type char can be signed or unsigned,
+ * type cast the value from external NC_CHAR before the comparison
+ */
+ char x2 = (char) x;
+ char y2 = (char) y;
+ x = x2;
+ y = y2;
+ }
+ return ABS(x-y) <= epsilon * MAX( ABS(x), ABS(y));
+}
+
+/* this function is for the APIs without itype, i.e. extType == itype */
+int
+equal2(
+ double x,
+ double y,
+ nc_type extType) /* external data type */
+{
+ const double flt_epsilon = 1.19209290E-07;
+ const double dbl_epsilon = 2.2204460492503131E-16;
+ double epsilon;
+
+ epsilon = extType == NC_FLOAT ? flt_epsilon : dbl_epsilon;
+
+ if (extType == NC_CHAR) {
+ /* because in-memory data type char can be signed or unsigned,
+ * type cast the value from external NC_CHAR before the comparison
+ */
+ char x2 = (char) x;
+ char y2 = (char) y;
+ x = x2;
+ y = y2;
+ }
+
+ return ABS(x-y) <= epsilon * MAX( ABS(x), ABS(y));
+}
+
+/* Test whether two int vectors are equal. If so return 1, else 0 */
+int
+int_vec_eq(const int *v1, const int *v2, const int n)
+{
+ int i;
+ for (i= 0; i < n && v1[i] == v2[i]; i++)
+ ;
+ return i == n;
+}
+
+
+/*
+ * Generate random integer from 0 to n-1
+ * Like throwing an n-sided dice marked 0, 1, 2, ..., n-1
+ */
+int roll( int n )
+{
+ int r;
+
+ do
+ /*
+ * Compute a pseudo-random value between 0.0 and 1.0, multiply
+ * it by n-1, and then find the nearest integer.
+ *
+ * We don't use RAND_MAX here because not all compilation
+ * environments define it (e.g. gcc(1) under SunOS 4.1.4).
+ */
+ r = ((rand() % 32768) / 32767.0) * (n - 1) + 0.5;
+ while (r >= n);
+
+ return r;
+}
+
+
+/*
+ * Convert number to mixed base
+ *
+ * E.g. to convert 41 inches to yards, feet and inches:
+ * MPI_Offset base[] = {1, 3, 12};
+ * MPI_Offset result[3];
+ * status = toMixedBase(41, 3, base, result);
+ *
+ * Author: Harvey Davies, Unidata/UCAR, Boulder, Colorado
+ *
+ * wkliao: this is like finding the N-dimensional array index
+ * given a linearized length. For example, given a 2x3x4 array,
+ * if number==37, then the result=(2,2,5)
+ * because 37 = 2x(3x4) + 2x(4) + 5
+ */
+int
+toMixedBase(size_t number, /* to be converted to mixed base */
+ size_t length,
+ const MPI_Offset base[], /* in: [length], base[0] ignored */
+ MPI_Offset result[]) /* out: [length] */
+{
+ size_t i;
+
+ if (length > 0) {
+ for (i = length - 1; i > 0; i--) {
+ if (base[i] == 0) return 1;
+ result[i] = number % base[i];
+ number = number / base[i];
+ }
+ result[0] = number;
+ }
+ return 0;
+}
+
+/*
+ * Convert number from mixed base
+ *
+ * E.g. to convert 1 yard, 0 feet, 5 inches to inches:
+ * MPI_Offset number[] = {1, 0, 5};
+ * MPI_Offset base[] = {1, 3, 12};
+ * inches = fromMixedBase(3, number, base);
+ *
+ * Author: Harvey Davies, Unidata/UCAR, Boulder, Colorado
+ */
+size_t
+fromMixedBase(size_t length,
+ MPI_Offset number[], /* [length] */
+ MPI_Offset base[]) /* [length], base[0] ignored */
+{
+ size_t i;
+ size_t result = 0;
+
+ for (i = 1; i < length; i++) {
+ result += number[i-1];
+ result *= base[i];
+ }
+ if (length > 0)
+ result += number[i-1];
+ return result;
+}
+
+
+/* Convert any nc_type to double */
+int nc2dbl ( const nc_type datatype, const void *p, double *result)
+{
+ if ( ! p ) return 2;
+ if ( ! result ) return 3;
+ switch (datatype) {
+ case NC_CHAR: *result = *((signed char *) p); break;
+ case NC_BYTE: *result = *((signed char *) p); break;
+ case NC_UBYTE: *result = *((unsigned char *) p); break;
+ case NC_SHORT: *result = *((short *) p); break;
+ case NC_USHORT: *result = *((unsigned short *) p); break;
+ case NC_INT:
+#if INT_MAX >= X_INT_MAX
+ *result = *((int *) p); break;
+#else
+ *result = *((long *) p); break;
+#endif
+ case NC_UINT:
+#if UINT_MAX >= X_UINT_MAX
+ *result = *((unsigned int *) p); break;
+#else
+ *result = *((unsigned long *) p); break;
+#endif
+ case NC_FLOAT: *result = *((float *) p); break;
+ case NC_DOUBLE: *result = *((double *) p); break;
+ case NC_INT64: *result = *((long long *) p); break;
+ case NC_UINT64: *result = *((unsigned long long *) p); break;
+ default: return 1;
+ }
+ return 0;
+}
+
+
+/* Convert double to any nc_type */
+int dbl2nc ( const double d, const nc_type datatype, void *p)
+{
+ double r; /* rounded value */
+
+ if (p == NULL) return 1;
+ switch (datatype) {
+ case NC_CHAR:
+ r = floor(0.5+d);
+ /* d is obtained from hash() which may be set to X_CHAR_MIN (0)
+ * or X_CHAR_MAX (255). When in-memory data type char is signed
+ * (i.e. ranged from -128 to 127), we should still allow a type
+ * cast a unsigned value > 127 to a signed char without reporting
+ * it as a range error.
+ */
+ if ( r < X_CHAR_MIN || r > X_CHAR_MAX ) return 2;
+#if defined(__CHAR_UNSIGNED__) && __CHAR_UNSIGNED__ != 0
+ *((signed char*) p) = r;
+#else
+ *((char *) p) = r;
+#endif
+ break;
+ case NC_BYTE:
+ r = floor(0.5+d);
+ if ( r < schar_min || r > schar_max ) return 2;
+ *((signed char *) p) = r;
+ break;
+ case NC_UBYTE:
+ r = floor(0.5+d);
+ if ( r < 0.0 || r > uchar_max ) return 2;
+ *((unsigned char *) p) = r;
+ break;
+ case NC_SHORT:
+ r = floor(0.5+d);
+ if ( r < short_min || r > short_max ) return 2;
+ *((short *) p) = r;
+ break;
+ case NC_USHORT:
+ r = floor(0.5+d);
+ if ( r < 0.0 || r > ushort_max ) return 2;
+ *((unsigned short *) p) = r;
+ break;
+ case NC_INT:
+ r = floor(0.5+d);
+ if ( r < long_min || r > long_max ) return 2;
+#if INT_MAX >= X_INT_MAX
+ *((int *) p) = r;
+#else
+ *((long *) p) = r;
+#endif
+ break;
+ case NC_UINT:
+ r = floor(0.5+d);
+ if ( r < 0.0 || r > uint_max ) return 2;
+#if UINT_MAX >= X_UINT_MAX
+ *((unsigned int *) p) = r;
+#else
+ *((unsigned long *) p) = r;
+#endif
+ break;
+ case NC_FLOAT:
+ if ( fabs(d) > float_max ) return 2;
+ *((float *) p) = d;
+ break;
+ case NC_DOUBLE:
+ *((double *) p) = d;
+ break;
+ case NC_INT64:
+ r = floor(0.5+d);
+ if ( r < int64_min || r > int64_max ) return 2;
+ *((long long *) p) = r;
+ break;
+ case NC_UINT64:
+ r = floor(0.5+d);
+ if ( r < 0.0 || r > uint64_max ) return 2;
+ *((unsigned long long *) p) = r;
+ break;
+ default:
+ return 1;
+ }
+ return 0;
+}
+
+
+#define FUZZ (1.19209290E-07)
+
+/* Generate data values as function of type, rank (-1 for attribute), index */
+double
+hash( const nc_type type, const int rank, const MPI_Offset *index )
+{
+ double base;
+ double result = 0.0;
+ int d; /* index of dimension */
+
+ /* If vector then elements 0 & 1 are min & max. Elements 2 & 3 are */
+ /* just < min & > max (except for NC_CHAR & NC_DOUBLE) */
+ if (abs(rank) == 1 && index[0] <= 3) {
+ switch (index[0]) {
+ case 0:
+ switch (type) { /* test if can get/put MIN value */
+ case NC_CHAR: return X_CHAR_MIN;
+ case NC_BYTE: return X_BYTE_MIN;
+ case NC_SHORT: return X_SHORT_MIN;
+ case NC_INT: return X_INT_MIN;
+ case NC_FLOAT: return X_FLOAT_MIN;
+ case NC_DOUBLE: return X_DOUBLE_MIN;
+ case NC_UBYTE: return 0;
+ case NC_USHORT: return 0;
+ case NC_UINT: return 0;
+ case NC_INT64: return X_INT_MIN - 128.0; /* slight smaller
+ than INT_MIN */
+ case NC_UINT64: return 0;
+ default: assert(0);
+ }
+ case 1:
+ switch (type) { /* test if can get/put MAX value */
+ case NC_CHAR: return X_CHAR_MAX;
+ case NC_BYTE: return X_BYTE_MAX;
+ case NC_SHORT: return X_SHORT_MAX;
+ case NC_INT: return X_INT_MAX;
+ case NC_FLOAT: return X_FLOAT_MAX;
+ case NC_DOUBLE: return X_DOUBLE_MAX;
+ case NC_UBYTE: return X_UCHAR_MAX;
+ case NC_USHORT: return X_USHORT_MAX;
+ case NC_UINT: return X_UINT_MAX;
+ case NC_INT64: return X_INT_MAX + 128.0;
+ /* slightly bigger than INT_MAX */
+ case NC_UINT64: return X_UINT_MAX + 128.0;
+ /* slightly bigger than UINT_MAX */
+ default: assert(0);
+ }
+ case 2:
+ switch (type) { /* test if can detect out-of-boundary value */
+ case NC_CHAR: return 'A';
+ case NC_BYTE: return X_BYTE_MIN-1.0;
+ case NC_SHORT: return X_SHORT_MIN-1.0;
+ case NC_INT: return X_INT_MIN-1.0;
+ case NC_FLOAT: return X_FLOAT_MIN * (1.0 + FUZZ);
+ case NC_DOUBLE: return -1.0; /* skip test */
+ case NC_UBYTE: return -1.0;
+ case NC_USHORT: return -1.0;
+ case NC_UINT: return -1.0;
+ case NC_INT64: return -1.0; /* skip test */
+ case NC_UINT64: return -1.0;
+ default: assert(0);
+ }
+ case 3:
+ switch (type) { /* test if can detect out-of-boundary value */
+ case NC_CHAR: return 'Z';
+ case NC_BYTE: return X_BYTE_MAX +1.0;
+ case NC_SHORT: return X_SHORT_MAX +1.0;
+ case NC_INT: return X_INT_MAX +1.0;
+ case NC_FLOAT: return X_FLOAT_MAX * (1.0 + FUZZ);
+ case NC_DOUBLE: return 1.0; /* skip test */
+ case NC_UBYTE: return X_UCHAR_MAX +1.0;
+ case NC_USHORT: return X_USHORT_MAX+1.0;
+ case NC_UINT: return X_UINT_MAX +1.0;
+ case NC_INT64: return 1.0; /* skip test */
+ case NC_UINT64: return 1.0; /* skip test */
+ default: assert(0);
+ }
+ }
+ } else { /* for array with more than 4 elements, pick some random numbers */
+ /* wkliao: what is "base" ? */
+ switch (type) {
+ case NC_CHAR: base = 2; break;
+ case NC_BYTE: base = -2; break;
+ case NC_SHORT: base = -5; break;
+ case NC_INT: base = -20; break;
+ case NC_FLOAT: base = -9; break;
+ case NC_DOUBLE: base = -10; break;
+
+ /* not sure what right values are */
+ case NC_UBYTE: base = 2; break;
+ case NC_USHORT: base = 5; break;
+ case NC_UINT: base = 20; break;
+ case NC_INT64: base = -20; break;
+ case NC_UINT64: base = 20; break;
+ default:
+ base = 0;
+ assert(0);
+ }
+ if (rank < 0) /* attribute */
+ result = base * 7;
+ else
+ result = base * (rank + 1);
+
+ for (d=0; d<abs(rank); d++)
+ result = base * (result + index[d]);
+ }
+ return result;
+}
+
+/* wrapper for hash to handle special NC_BYTE/uchar adjustment */
+double
+hash4(const nc_type type,
+ const int rank,
+ const MPI_Offset *index,
+ const nct_itype itype)
+{
+ double result;
+
+ result = hash(type, rank, index);
+ if (itype == NCT_UCHAR && type == NC_BYTE && result >= -128 && result < 0)
+ result += 256;
+ return result;
+}
+
+static nc_type
+char2type(char letter) {
+ switch (letter) {
+ case 'c': return NC_CHAR;
+ case 'b': return NC_BYTE;
+ case 's': return NC_SHORT;
+ case 'i': return NC_INT;
+ case 'f': return NC_FLOAT;
+ case 'd': return NC_DOUBLE;
+ case 'y': return NC_UBYTE;
+ case 't': return NC_USHORT;
+ case 'u': return NC_UINT;
+ case 'x': return NC_INT64;
+ case 'z': return NC_UINT64;
+ default: assert(0);
+ }
+ return NC_CHAR; /* Just to keep compiler happy */
+}
+
+
+static void
+init_dims(const char *digit)
+{
+ int dimid; /* index of dimension */
+
+ for (dimid = 0; dimid < NDIMS; dimid++) {
+ dim_len[dimid] = dimid == 0 ? NRECS : dimid;
+ /* lengths = 1, 2, 3, ...
+ * names = Dr, D1, D1, D2, ...
+ */
+ dim_name[dimid][0] = 'D';
+ dim_name[dimid][1] = digit[dimid];
+ dim_name[dimid][2] = '\0';
+ }
+}
+
+static void
+init_gatts(const char *type_letter)
+{
+ int attid;
+ for (attid = 0; attid < numGatts; attid++) {
+ gatt_name[attid][0] = 'G';
+ gatt_name[attid][1] = type_letter[attid];
+ gatt_name[attid][2] = '\0';
+ gatt_len[attid] = 1 + attid;
+ gatt_type[attid] = char2type (type_letter[attid]);
+ }
+}
+
+static MPI_Offset
+product(size_t nn, const MPI_Offset *sp)
+{
+ MPI_Offset result = 1;
+ while (nn-- > 0)
+ result *= *sp++;
+ return result; /* == sp[0] * sp[1] * ... * sp[nn-1] */
+}
+
+/*
+ define global variables:
+ dim_name, dim_len,
+ var_name, var_type, var_rank, var_shape, var_natts, var_dimid, var_nels
+ att_name, gatt_name, att_type, gatt_type, att_len, gatt_len
+ */
+void
+init_gvars (void)
+{
+ const MPI_Offset max_dim_len[MAX_RANK] = {MAX_DIM_LEN +1,
+ MAX_DIM_LEN,
+ MAX_DIM_LEN };
+ const char type_letter[] = "cbsifdytuxz";
+ /* c:char, b:byte, s:short, i:int, f:float, d:double, y:ubyte, t:ushort,
+ * u:uint, x:int64, z:uint64
+ */
+ const char digit[] = "r123456789";
+
+ size_t rank;
+ int vn; /* var number */
+ int xtype; /* index of type */
+ int an; /* attribute number */
+
+ assert(sizeof(max_dim_len)/sizeof(max_dim_len[0]) >= MAX_RANK);
+
+ init_dims(digit);
+
+ for (vn=0; vn<numVars; vn++)
+ memset(var_name[vn], 0, 2+MAX_RANK);
+
+ vn = 0;
+ xtype = 0;
+ an = 0;
+ for (rank=0; rank<=MAX_RANK; rank++) { /* dimension ranks */
+ /* number variables of a type and rank
+ * == max_dim_len[0] * max_dim_len[1] * ... * max_dim_len[rank-1] */
+ const size_t nvars = product(rank, max_dim_len);
+
+ int jj;
+ for (jj=0; jj<nvars; jj++) {
+ /* number types of this shape */
+ const int ntypes = rank < 2 ? numTypes : 1;
+
+ int ac, tc;
+ for (tc=0; tc<ntypes; tc++, vn++, xtype = (xtype + 1) % numTypes) {
+ MPI_Offset tmp[MAX_RANK];
+
+ var_name[vn][0] = type_letter[xtype];
+ var_type[vn] = char2type(type_letter[xtype]);
+ var_rank[vn] = rank;
+ var_natts[vn] = rank == 0 ? vn % (MAX_NATTS + 1) : 0;
+
+ /* ac block */
+ for (ac=0; ac<var_natts[vn]; ac++, an++) {
+ att_name[vn][ac][0] = type_letter[an % numTypes];
+ att_name[vn][ac][1] = '\0';
+ att_len[vn][ac] = an;
+ att_type[vn][ac] = char2type(type_letter[an % numTypes]);
+ }
+#ifndef NDEBUG
+ assert(toMixedBase(jj, rank, max_dim_len, tmp) == 0);
+#else
+ toMixedBase(jj, rank, max_dim_len, tmp);
+#endif
+ /* dn block */
+ int dn; /* dimension number */
+ for (dn=0; dn<rank; dn++)
+ var_dimid[vn][dn] = (int)tmp[dn];
+
+ for (dn=0, var_nels[vn]=1; dn<rank; dn++) {
+ var_dimid[vn][dn] += dn > 0;
+ assert (var_dimid[vn][dn] <= 9);
+ var_name[vn][dn + 1] = digit[var_dimid[vn][dn]];
+ var_shape[vn][dn] = var_dimid[vn][dn] ?
+ var_dimid[vn][dn] : NRECS;
+ var_nels[vn] *= var_shape[vn][dn];
+ }
+ }
+ }
+ }
+ init_gatts(type_letter);
+}
+
+
+/* define dims defined by global variables */
+void
+def_dims(int ncid)
+{
+ int i, err, dimid;
+
+ for (i=0; i<NDIMS; i++) {
+ err = ncmpi_def_dim(ncid, dim_name[i],
+ i==0 ? NC_UNLIMITED : dim_len[i], &dimid);
+ IF (err != NC_NOERR) error("ncmpi_def_dim: %s", ncmpi_strerror(err));
+ }
+}
+
+
+/* define vars defined by global variables */
+void
+def_vars(int ncid)
+{
+ int i, err, var_id;
+
+ for (i = 0; i < numVars; i++) {
+ err = ncmpi_def_var(ncid, var_name[i], var_type[i], var_rank[i],
+ var_dimid[i], &var_id);
+ IF (err != NC_NOERR) error("ncmpi_def_var: %s", ncmpi_strerror(err));
+ }
+}
+
+
+/* put attributes defined by global variables */
+void
+put_atts(int ncid)
+{
+ int i, j, allInRange, err;
+ MPI_Offset k;
+ char catt[MAX_NELS];
+ double att[MAX_NELS];
+
+ for (i=-1; i<numVars; i++) { /* -1: global attribute */
+ for (j=0; j<NATTS(i); j++) {
+ if (ATT_TYPE(i,j) == NC_CHAR) {
+ for (k=0; k<ATT_LEN(i,j); k++) {
+ catt[k] = hash(ATT_TYPE(i,j), -1, &k);
+ }
+ err = ncmpi_put_att_text(ncid, i, ATT_NAME(i,j),
+ ATT_LEN(i,j), catt);
+ IF (err != NC_NOERR)
+ error("ncmpi_put_att_text: %s", ncmpi_strerror(err));
+ } else {
+ for (allInRange=1, k=0; k<ATT_LEN(i,j); k++) {
+ att[k] = hash(ATT_TYPE(i,j), -1, &k);
+ allInRange = allInRange && inRange(att[k], ATT_TYPE(i,j));
+ }
+ err = ncmpi_put_att_double(ncid, i, ATT_NAME(i,j),
+ ATT_TYPE(i,j), ATT_LEN(i,j), att);
+ if (allInRange) {
+ IF (err != NC_NOERR)
+ error("ncmpi_put_att_double: %s", ncmpi_strerror(err));
+ } else {
+ /* when ATT_LEN(i,j) >= 3, some values returned for 3rd,
+ * 4th, ... will be specially made to cause NC_ERANG
+ */
+ IF (err != NC_ERANGE)
+ error("type-conversion range error: status = %d", err);
+ }
+ }
+ }
+ }
+}
+
+/* put variables defined by global variables */
+void
+put_vars(int ncid)
+{
+ MPI_Offset start[MAX_RANK];
+ MPI_Offset index[MAX_RANK];
+ int i, j, err, allInRange;
+ double value[MAX_NELS];
+ char text[MAX_NELS];
+
+ for (j = 0; j < MAX_RANK; j++) start[j] = 0;
+ for (i = 0; i < numVars; i++) {
+ for (allInRange = 1, j = 0; j < var_nels[i]; j++) {
+ err = toMixedBase(j, var_rank[i], var_shape[i], index);
+ IF (err != NC_NOERR) error("toMixedBase");
+ if (var_name[i][0] == 'c') { /* var_type[i] is NC_CHAR */
+ text[j] = hash(var_type[i], var_rank[i], index);
+ } else {
+ value[j] = hash(var_type[i], var_rank[i], index);
+ allInRange = allInRange && inRange(value[j], var_type[i]);
+ }
+ }
+ if (var_name[i][0] == 'c') {
+ err = ncmpi_put_vara_text_all(ncid, i, start, var_shape[i], text);
+ IF (err != NC_NOERR)
+ error("ncmpi_put_vara_text_all: %s", ncmpi_strerror(err));
+ } else {
+ err = ncmpi_put_vara_double_all(ncid, i, start, var_shape[i],value);
+ if (allInRange) {
+ IF (err != NC_NOERR)
+ error("ncmpi_put_vara_double_all: %s", ncmpi_strerror(err));
+ } else {
+ IF (err != NC_ERANGE)
+ error("type-conversion range error: status = %d", err);
+ }
+ }
+ }
+}
+
+
+/* Create & write all of specified file using global variables */
+void
+write_file(char *filename)
+{
+ int err, ncid;
+
+ err = ncmpi_create(comm, filename, NC_CLOBBER|extra_flags, info,
+ &ncid);
+ IF (err != NC_NOERR) error("ncmpi_create: %s", ncmpi_strerror(err));
+
+ def_dims(ncid);
+ def_vars(ncid);
+ put_atts(ncid);
+
+ err = ncmpi_enddef(ncid);
+ IF (err != NC_NOERR) error("ncmpi_enddef: %s", ncmpi_strerror(err));
+
+ put_vars(ncid);
+
+ err = ncmpi_close (ncid);
+ IF (err != NC_NOERR) error("ncmpi_close: %s", ncmpi_strerror(err));
+}
+
+
+/*
+ * check dimensions of specified file have expected name & length
+ */
+void
+check_dims(int ncid)
+{
+ char name[NC_MAX_NAME];
+ MPI_Offset length;
+ int i, err;
+
+ for (i = 0; i < NDIMS; i++) {
+ err = ncmpi_inq_dim(ncid, i, name, &length);
+ IF (err != NC_NOERR)
+ error("ncmpi_inq_dim: %s", ncmpi_strerror(err));
+ IF (strcmp(name, dim_name[i]) != 0)
+ error("Unexpected name of dimension %d", i);
+ IF (length != dim_len[i])
+ error("Unexpected length %d of dimension %d", length, i);
+ }
+}
+
+
+/*
+ * check variables of specified file have expected name, type, shape & values
+ */
+void
+check_vars(int ncid)
+{
+ MPI_Offset index[MAX_RANK];
+ char text, name[NC_MAX_NAME];
+ int i, j, err;
+ int nok = 0; /* count of valid comparisons */
+ int isChar, ndims, dimids[MAX_RANK];
+ double value, expect;
+ nc_type datatype;
+ MPI_Offset length;
+
+ for (i = 0; i < numVars; i++) {
+ isChar = var_type[i] == NC_CHAR;
+ err = ncmpi_inq_var(ncid, i, name, &datatype, &ndims, dimids, NULL);
+ IF (err != NC_NOERR)
+ error("ncmpi_inq_var: %s", ncmpi_strerror(err));
+ IF (strcmp(name, var_name[i]) != 0)
+ error("Unexpected var_name");
+ IF (datatype != var_type[i])
+ error("Unexpected type");
+ IF (ndims != var_rank[i])
+ error("Unexpected rank");
+ for (j = 0; j < ndims; j++) {
+ err = ncmpi_inq_dim(ncid, dimids[j], name, &length);
+ IF (err != NC_NOERR)
+ error("ncmpi_inq_dim: %s", ncmpi_strerror(err));
+ IF (length != var_shape[i][j])
+ error("Unexpected shape");
+ }
+ for (j = 0; j < var_nels[i]; j++) {
+ err = toMixedBase(j, var_rank[i], var_shape[i], index);
+ IF (err != NC_NOERR)
+ error("error in toMixedBase 2");
+ expect = hash( var_type[i], var_rank[i], index );
+ if (isChar) {
+ ncmpi_begin_indep_data(ncid);
+ err = ncmpi_get_var1_text(ncid, i, index, &text);
+ IF (err != NC_NOERR)
+ error("ncmpi_get_var1_text: %s", ncmpi_strerror(err));
+ IF (text != (char)expect) {
+ error("Var %s (varid=%d) value read 0x%02x not that expected 0x%02x ",
+ var_name[i], i, text, (char)expect);
+ print_n_size_t(var_rank[i], index);
+ } else {
+ nok++;
+ }
+ ncmpi_end_indep_data(ncid);
+ } else {
+ ncmpi_begin_indep_data(ncid);
+ err = ncmpi_get_var1_double(ncid, i, index, &value);
+ if (inRange(expect,var_type[i])) {
+ IF (err != NC_NOERR) {
+ error("ncmpi_get_var1_double: %s", ncmpi_strerror(err));
+ } else {
+ IF (!equal(value,expect,var_type[i], NCT_DOUBLE)) {
+ error("Var %s (varid=%d) value read % 12.5e not that expected % 12.7e ",
+ var_name[i], i, value, expect);
+ print_n_size_t(var_rank[i], index);
+ } else {
+ nok++;
+ }
+ }
+ }
+ ncmpi_end_indep_data(ncid);
+ }
+ }
+ }
+ /* print_nok(nok); */
+}
+
+
+/*
+ * check attributes of specified file have expected name, type, length & values
+ */
+void
+check_atts(int ncid)
+{
+ char name[NC_MAX_NAME], text[MAX_NELS];
+ int i, j, err; /* status */
+ nc_type datatype;
+ MPI_Offset k, length;
+ double expect, value[MAX_NELS];
+ int nok = 0; /* count of valid comparisons */
+
+ for (i = -1; i < numVars; i++) {
+ for (j = 0; j < NATTS(i); j++) {
+ err = ncmpi_inq_attname(ncid, i, j, name);
+ IF (err != NC_NOERR)
+ error("ncmpi_inq_attname: %s", ncmpi_strerror(err));
+ IF (strcmp(name, ATT_NAME(i,j)) != 0)
+ error("ncmpi_inq_attname: unexpected name");
+ err = ncmpi_inq_att(ncid, i, name, &datatype, &length);
+ IF (err != NC_NOERR)
+ error("ncmpi_inq_att: %s", ncmpi_strerror(err));
+ IF (datatype != ATT_TYPE(i,j))
+ error("ncmpi_inq_att: unexpected type");
+ IF (length != ATT_LEN(i,j))
+ error("ncmpi_inq_att: unexpected length");
+ if (datatype == NC_CHAR) {
+ err = ncmpi_get_att_text(ncid, i, name, text);
+ IF (err != NC_NOERR)
+ error("ncmpi_get_att_text: %s", ncmpi_strerror(err));
+ for (k = 0; k < ATT_LEN(i,j); k++) {
+ expect = hash(datatype, -1, &k);
+ if (text[k] != (char)expect) {
+ error("ncmpi_get_att_text: unexpected value");
+ } else {
+ nok++;
+ }
+ }
+ } else {
+ err = ncmpi_get_att_double(ncid, i, name, value);
+ for (k = 0; k < ATT_LEN(i,j); k++) {
+ expect = hash(datatype, -1, &k);
+ if (inRange(expect,ATT_TYPE(i,j))) {
+ IF (err != NC_NOERR)
+ error("ncmpi_get_att_double: %s", ncmpi_strerror(err));
+ IF (!equal(value[k], expect, ATT_TYPE(i,j), NCT_DOUBLE)) {
+ error("Att value read not that expected");
+ } else {
+ nok++;
+ }
+ }
+ }
+ }
+ }
+ }
+ /* print_nok(nok); */
+}
+
+
+/* Check file (dims, vars, atts) corresponds to global variables */
+void
+check_file(char *filename)
+{
+ int ncid, err;
+
+ err = ncmpi_open(comm, filename, NC_NOWRITE, info, &ncid);
+ IF (err != NC_NOERR) {
+ error("ncmpi_open: %s", ncmpi_strerror(err));
+ } else {
+ check_dims(ncid);
+ check_vars(ncid);
+ check_atts(ncid);
+ err = ncmpi_close (ncid);
+ IF (err != NC_NOERR)
+ error("ncmpi_close: %s", ncmpi_strerror(err));
+ }
+}
+
+/* TODO: Maybe this function belongs in the netcdf library. */
+const char *
+s_nc_type(nc_type type)
+{
+ switch((int)type){
+ case NC_CHAR: return "NC_CHAR";
+ case NC_BYTE: return "NC_BYTE";
+ case NC_UBYTE: return "NC_UBYTE";
+ case NC_SHORT: return "NC_SHORT";
+ case NC_USHORT: return "NC_USHORT";
+ case NC_INT: return "NC_INT";
+ case NC_UINT: return "NC_UINT";
+ case NC_FLOAT: return "NC_FLOAT";
+ case NC_DOUBLE: return "NC_DOUBLE";
+ case NC_INT64: return "NC_INT64";
+ case NC_UINT64: return "NC_UINT64";
+ }
+ return "";
+}
+
+int
+nctypelen(nc_type type)
+{
+ switch(type){
+ case NC_BYTE :
+ case NC_CHAR : return((int)sizeof(char));
+ case NC_SHORT : return((int)sizeof(short));
+ case NC_INT : return((int)sizeof(int));
+ case NC_FLOAT : return((int)sizeof(float));
+ case NC_DOUBLE : return((int)sizeof(double));
+ case NC_UBYTE : return(1);
+ case NC_USHORT : return((int)sizeof(unsigned short));
+ case NC_UINT : return((int)sizeof(unsigned int));
+ case NC_INT64 : return((int)sizeof(long long));
+ case NC_UINT64 : return((int)sizeof(unsigned long long));
+ default: return -1;
+ }
+}
+
+MPI_Datatype
+nc_mpi_type(nc_type type)
+{
+ switch(type){
+ case NC_BYTE : return MPI_SIGNED_CHAR;
+ case NC_CHAR : return MPI_CHAR;
+ case NC_SHORT : return MPI_SHORT;
+ case NC_INT : return MPI_INT;
+ case NC_FLOAT : return MPI_FLOAT;
+ case NC_DOUBLE : return MPI_DOUBLE;
+ case NC_UBYTE : return MPI_UNSIGNED_CHAR;
+ case NC_USHORT : return MPI_UNSIGNED_SHORT;
+ case NC_UINT : return MPI_UNSIGNED;
+ case NC_INT64 : return MPI_LONG_LONG_INT;
+ case NC_UINT64 : return MPI_UNSIGNED_LONG_LONG;
+ default: return MPI_DATATYPE_NULL;
+ }
+}
+
diff --git a/test/nf90_test/Makefile.in b/test/nf90_test/Makefile.in
new file mode 100644
index 0000000..b534681
--- /dev/null
+++ b/test/nf90_test/Makefile.in
@@ -0,0 +1,92 @@
+#
+# Copyright (C) 2003, Northwestern University and Argonne National Laboratory
+# See COPYRIGHT notice in top-level directory.
+#
+# $Id: Makefile.in 2251 2015-12-20 21:13:42Z wkliao $
+#
+# @configure_input@
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+include ../../macros.make
+
+INCLUDES = -I../../src/lib -I../../src/libf
+INCLUDES += -I$(srcdir) -I$(srcdir)/../../src/libf
+INCLUDES += @FC_MODINC at ../../src/libf90
+LDFLAGS := $(LDFLAGS) -L../common
+LIBS := $(LIBRARY) -ltestutils $(LIBS) @LCOV_LIB@
+
+M4SRCS = test_get.m4 \
+ test_put.m4 \
+ test_iget.m4 \
+ test_iput.m4
+
+M4SRCS_F90 = $(M4SRCS:.m4=.F90)
+
+F90_SRCS = nf90_error.F90 \
+ nf90_test.F90 \
+ test_read.F90 \
+ test_write.F90 \
+ util.F90
+
+C_SRCS = fortlib.c
+
+HEADERS = tests.inc
+
+C_OBJS = $(C_SRCS:.c=.o)
+F90_OBJS = $(F90_SRCS:.F90=.o) $(M4SRCS_F90:.F90=.o)
+OBJS = $(C_OBJS) $(F90_OBJS)
+
+PROGS = nf90_test
+
+GARBAGE = $(PROGS) $(M4SRCS_F90) \
+ scratch.nc test.nc
+
+PACKING_LIST = $(C_SRCS) $(F90_SRCS) $(M4SRCS) $(HEADERS) depend Makefile.in README
+
+all: $(PROGS)
+
+$(C_OBJS): $(srcdir)/../common/testutils.h
+
+$(PROGS): ../common/libtestutils.a
+
+../common/libtestutils.a:
+ set -e; cd ../common && $(MAKE) $(MFLAGS) all
+
+nf90_test: $(OBJS) $(LIBRARY)
+ $(LINK.F90) $(OBJS) $(LDFLAGS) $(LIBS)
+
+tags: $(F90_SRCS) $(C_SRCS) FORCE
+ ctags -t $(F90_SRCS) $(C_SRCS) ../fortran/*.c ../libsrc/*.c
+
+# This simple testing target ensures that the test files are present
+testing check: all
+ $(RM) -f $(TEST_OUTDIR)/scratch.nc $(TEST_OUTDIR)/test.nc
+ $(TEST_SEQRUN) ./nf90_test -c -d $(TEST_OUTDIR)
+ $(TEST_SEQRUN) ./nf90_test -d $(TEST_OUTDIR)
+ $(TEST_SEQRUN) ./nf90_test -c -2 -d $(TEST_OUTDIR)
+ $(TEST_SEQRUN) ./nf90_test -2 -d $(TEST_OUTDIR)
+ $(TEST_SEQRUN) ./nf90_test -c -5 -d $(TEST_OUTDIR)
+ $(TEST_SEQRUN) ./nf90_test -5 -d $(TEST_OUTDIR)
+
+verbose_testing: all
+ $(RM) -f $(TEST_OUTDIR)/scratch.nc $(TEST_OUTDIR)/test.nc
+ $(TEST_SEQRUN) ./nf90_test -v -c -d $(TEST_OUTDIR)
+ $(TEST_SEQRUN) ./nf90_test -v -d $(TEST_OUTDIR)
+ $(TEST_SEQRUN) ./nf90_test -v -c -2 -d $(TEST_OUTDIR)
+ $(TEST_SEQRUN) ./nf90_test -v -2 -d $(TEST_OUTDIR)
+ $(TEST_SEQRUN) ./nf90_test -v -c -5 -d $(TEST_OUTDIR)
+ $(TEST_SEQRUN) ./nf90_test -v -5 -d $(TEST_OUTDIR)
+
+#test.nc:
+# (cd ../nc_test && $(MAKE) $(MFLAGS) nc_test && ./nc_test -c)
+# cp ../nc_test/test.nc .
+
+ptest ptests ptest2 ptest4 ptest6 ptest8 ptest10:
+
+include $(srcdir)/../../rules.make
+include $(srcdir)/depend
+
+$(LIBRARY): ;
+
diff --git a/test/nf90_test/README b/test/nf90_test/README
new file mode 100644
index 0000000..11cf35d
--- /dev/null
+++ b/test/nf90_test/README
@@ -0,0 +1,3 @@
+This test is ported from ../nf_test to test the functionality
+of the PnetCDF API Fortran 90 interface particularly on a single processor.
+
diff --git a/test/nf90_test/depend b/test/nf90_test/depend
new file mode 100644
index 0000000..ace6d17
--- /dev/null
+++ b/test/nf90_test/depend
@@ -0,0 +1,28 @@
+fortlib.o: fortlib.c
+nf90_error.o: ../../src/libf/pnetcdf.inc
+nf90_error.o: nf90_error.F90
+nf90_error.o: tests.inc
+nf90_test.o: ../../src/libf/pnetcdf.inc
+nf90_test.o: nf90_test.F90
+nf90_test.o: tests.inc
+test_get.o: ../../src/libf/pnetcdf.inc
+test_get.o: test_get.F90
+test_get.o: tests.inc
+test_put.o: ../../src/libf/pnetcdf.inc
+test_put.o: test_put.F90
+test_put.o: tests.inc
+test_iget.o: ../../src/libf/pnetcdf.inc
+test_iget.o: test_iget.F90
+test_iget.o: tests.inc
+test_iput.o: ../../src/libf/pnetcdf.inc
+test_iput.o: test_iput.F90
+test_iput.o: tests.inc
+test_read.o: ../../src/libf/pnetcdf.inc
+test_read.o: test_read.F90
+test_read.o: tests.inc
+test_write.o: ../../src/libf/pnetcdf.inc
+test_write.o: test_write.F90
+test_write.o: tests.inc
+util.o: ../../src/libf/pnetcdf.inc
+util.o: tests.inc
+util.o: util.F90
diff --git a/test/nf90_test/fortlib.c b/test/nf90_test/fortlib.c
new file mode 100644
index 0000000..6d2303d
--- /dev/null
+++ b/test/nf90_test/fortlib.c
@@ -0,0 +1,289 @@
+/*
+ * $Id: fortlib.c 1468 2013-10-26 16:53:18Z wkliao $
+ *
+ * This file contains support functions for FORTRAN code. For example,
+ * under HP-UX A.09.05, the U77 library doesn't contain the exit()
+ * routine -- so we create one here.
+ *
+ * This file is heavily modified from nf_test/fortlib.c in the serial netcdf
+ * source.
+ */
+
+
+#include <stdlib.h>
+#include <limits.h>
+#include <float.h>
+#include <unistd.h>
+#include <stdint.h>
+#include <mpinetcdf_impl.h>
+#include <mpifnetcdf.h>
+
+extern FORTRAN_API void FORT_CALL ud_exit_(int *v1);
+extern FORTRAN_API void FORT_CALL ud_abort_(int *v1);
+extern FORTRAN_API double FORT_CALL ud_rand_(int *seed);
+extern FORTRAN_API int FORT_CALL ud_shift_(int * value, int *amount);
+extern FORTRAN_API void FORT_CALL nc_ignorefpe_(int *doit);
+extern FORTRAN_API double FORT_CALL min_schar_(void);
+extern FORTRAN_API double FORT_CALL min_short_(void);
+extern FORTRAN_API double FORT_CALL min_int_(void);
+extern FORTRAN_API double FORT_CALL min_int64_(void);
+extern FORTRAN_API double FORT_CALL max_schar_(void);
+extern FORTRAN_API double FORT_CALL max_short_(void);
+extern FORTRAN_API double FORT_CALL max_int_(void);
+extern FORTRAN_API double FORT_CALL max_int64_(void);
+extern FORTRAN_API double FORT_CALL max_float_(void);
+extern FORTRAN_API double FORT_CALL max_double_(void);
+
+
+#ifdef F77_NAME_UPPER
+#define ud_exit_ UD_EXIT
+#elif defined(F77_NAME_LOWER_2USCORE)
+#define ud_exit_ ud_exit__
+#elif !defined(F77_NAME_LOWER_USCORE)
+#define ud_exit_ ud_exit
+/* Else leave name alone */
+#endif
+
+FORTRAN_API void FORT_CALL ud_exit_(int *v1) {
+ if (*v1 == 0) {
+ MPI_Finalize();
+ exit(0);
+ }
+ MPI_Abort(MPI_COMM_WORLD, *v1);
+ return;
+}
+
+#ifdef F77_NAME_UPPER
+#define ud_abort_ UD_ABORT
+#elif defined(F77_NAME_LOWER_2USCORE)
+#define ud_abort_ ud_abort__
+#elif !defined(F77_NAME_LOWER_USCORE)
+#define ud_abort_ ud_abort
+/* Else leave name alone */
+#endif
+
+FORTRAN_API void FORT_CALL ud_abort_(int *v1) {
+ MPI_Abort(MPI_COMM_WORLD, *v1);
+ return;
+}
+
+#ifdef F77_NAME_UPPER
+#define ud_rand_ UD_RAND
+#elif defined(F77_NAME_LOWER_2USCORE)
+#define ud_rand_ ud_rand__
+#elif !defined(F77_NAME_LOWER_USCORE)
+#define ud_rand_ ud_rand
+/* Else leave name alone */
+#endif
+
+/*
+* Return a pseudo-random value between 0.0 and 1.0.
+*
+* We don't use RAND_MAX here because not all compilation
+* environments define it (e.g. gcc(1) under SunOS 4.1.3).
+*/
+FORTRAN_API double FORT_CALL ud_rand_(int *seed) {
+ if (*seed != 0)
+ srand(*seed);
+ return (rand() % 32768 )/ 32767.0;
+}
+
+#ifdef F77_NAME_UPPER
+#define ud_shift_ UD_SHIFT
+#elif defined(F77_NAME_LOWER_2USCORE)
+#define ud_shift_ ud_shift__
+#elif !defined(F77_NAME_LOWER_USCORE)
+#define ud_shift_ ud_shift
+/* Else leave name alone */
+#endif
+
+FORTRAN_API int FORT_CALL ud_shift_(int * value, int *amount) {
+ if(*amount < 0)
+ *value >>= -*amount;
+ else if (*amount > 0)
+ *value <<= *amount;
+ return *value;
+}
+
+#ifdef F77_NAME_UPPER
+#define nc_ignorefpe_ NC_IGNOREFPE
+#elif defined(F77_NAME_LOWER_2USCORE)
+#define nc_ignorefpe_ nc_ignorefpe__
+#elif !defined(F77_NAME_LOWER_USCORE)
+#define nc_ignorefpe_ nc_ignorefpe
+/* Else leave name alone */
+#endif
+#include <signal.h>
+FORTRAN_API void FORT_CALL nc_ignorefpe_(int *doit)
+{
+ if(doit)
+ (void) signal(SIGFPE, SIG_IGN);
+}
+
+#ifdef F77_NAME_UPPER
+#define min_schar_ MIN_SCHAR
+#elif defined(F77_NAME_LOWER_2USCORE)
+#define min_schar_ min_schar__
+#elif !defined(F77_NAME_LOWER_USCORE)
+#define min_schar_ min_schar
+/* Else leave name alone */
+#endif
+FORTRAN_API double FORT_CALL min_schar_(void) {
+ return SCHAR_MIN;
+}
+
+#ifdef F77_NAME_UPPER
+#define min_short_ MIN_SHORT
+#elif defined(F77_NAME_LOWER_2USCORE)
+#define min_short_ min_short__
+#elif !defined(F77_NAME_LOWER_USCORE)
+#define min_short_ min_short
+/* Else leave name alone */
+#endif
+FORTRAN_API double FORT_CALL min_short_(void) {
+ return SHRT_MIN;
+}
+
+#ifdef F77_NAME_UPPER
+#define min_int_ MIN_INT
+#elif defined(F77_NAME_LOWER_2USCORE)
+#define min_int_ min_int__
+#elif !defined(F77_NAME_LOWER_USCORE)
+#define min_int_ min_int
+/* Else leave name alone */
+#endif
+FORTRAN_API double FORT_CALL min_int_(void) {
+ return INT_MIN;
+}
+
+#ifdef F77_NAME_UPPER
+#define min_int64_ MIN_INT64
+#elif defined(F77_NAME_LOWER_2USCORE)
+#define min_int64_ min_int64__
+#elif !defined(F77_NAME_LOWER_USCORE)
+#define min_int64_ min_int64
+/* Else leave name alone */
+#endif
+FORTRAN_API double FORT_CALL min_int64_(void) {
+ return INT64_MIN;
+}
+
+#ifdef F77_NAME_UPPER
+#define max_schar_ MAX_SCHAR
+#elif defined(F77_NAME_LOWER_2USCORE)
+#define max_schar_ max_schar__
+#elif !defined(F77_NAME_LOWER_USCORE)
+#define max_schar_ max_schar
+/* Else leave name alone */
+#endif
+FORTRAN_API double FORT_CALL max_schar_(void) {
+ return SCHAR_MAX;
+}
+
+#ifdef F77_NAME_UPPER
+#define max_short_ MAX_SHORT
+#elif defined(F77_NAME_LOWER_2USCORE)
+#define max_short_ max_short__
+#elif !defined(F77_NAME_LOWER_USCORE)
+#define max_short_ max_short
+/* Else leave name alone */
+#endif
+FORTRAN_API double FORT_CALL max_short_(void) {
+ return SHRT_MAX;
+}
+
+#ifdef F77_NAME_UPPER
+#define max_int_ MAX_INT
+#elif defined(F77_NAME_LOWER_2USCORE)
+#define max_int_ max_int__
+#elif !defined(F77_NAME_LOWER_USCORE)
+#define max_int_ max_int
+/* Else leave name alone */
+#endif
+FORTRAN_API double FORT_CALL max_int_(void) {
+ return INT_MAX;
+}
+
+#ifdef F77_NAME_UPPER
+#define max_int64_ MAX_INT64
+#elif defined(F77_NAME_LOWER_2USCORE)
+#define max_int64_ max_int64__
+#elif !defined(F77_NAME_LOWER_USCORE)
+#define max_int64_ max_int64
+/* Else leave name alone */
+#endif
+FORTRAN_API double FORT_CALL max_int64_(void) {
+ return INT64_MAX;
+}
+
+#ifdef F77_NAME_UPPER
+#define max_float_ MAX_FLOAT
+#elif defined(F77_NAME_LOWER_2USCORE)
+#define max_float_ max_float__
+#elif !defined(F77_NAME_LOWER_USCORE)
+#define max_float_ max_float
+/* Else leave name alone */
+#endif
+FORTRAN_API double FORT_CALL max_float_(void) {
+ return FLT_MAX;
+}
+
+#ifdef F77_NAME_UPPER
+#define max_double_ MAX_DOUBLE
+#elif defined(F77_NAME_LOWER_2USCORE)
+#define max_double_ max_double__
+#elif !defined(F77_NAME_LOWER_USCORE)
+#define max_double_ max_double
+/* Else leave name alone */
+#endif
+FORTRAN_API double FORT_CALL max_double_(void) {
+ return DBL_MAX;
+}
+
+#if 0 /* this is implemented in library src now */
+
+#ifdef F77_NAME_UPPER
+#define nfmpi_issyserr_ NFMPI_ISSYSERR
+#elif defined(F77_NAME_LOWER_2USCORE)
+#define nfmpi_issyserr_ nfmpi_issyserr__
+#elif !defined(F77_NAME_LOWER_USCORE)
+#define nfmpi_issyserr_ nfmpi_issyserr
+/* Else leave name alone */
+#endif
+
+FORTRAN_API int FORT_CALL nfmpi_issyserr_(int * A1) {
+ if (*A1 > 0)
+ return 1;
+ else
+ return 0;
+}
+
+
+#ifdef F77_NAME_UPPER
+#define nfmpi_delete_ NFMPI_DELETE
+#elif defined(F77_NAME_LOWER_2USCORE)
+#define nfmpi_delete_ nfmpi_delete__
+#elif !defined(F77_NAME_LOWER_USCORE)
+#define nfmpi_delete_ nfmpi_delete
+/* Else leave name alone */
+#endif
+FORTRAN_API void FORT_CALL nfmpi_delete_(char * name, int *err, int d1) {
+ char *p1;
+
+ {char *p = name + d1 - 1;
+ int li;
+ while (*p == ' ' && p > name) p--;
+ p++;
+ p1 = (char *)malloc( p-name + 1 );
+ for (li=0; li<(p-name); li++) { p1[li] = name[li]; }
+ p1[li] = 0;
+ }
+
+ if ( unlink(p1) != 0 )
+ *err = errno;
+ else
+ *err = 0;
+ free(p1);
+}
+
+#endif
diff --git a/test/nf90_test/nf90_error.F90 b/test/nf90_test/nf90_error.F90
new file mode 100644
index 0000000..9daaba2
--- /dev/null
+++ b/test/nf90_test/nf90_error.F90
@@ -0,0 +1,80 @@
+!
+! Copyright (C) 2013, Northwestern University and Argonne National Laboratory
+! See COPYRIGHT notice in top-level directory.
+!
+! $Id: nf90_error.F90 1468 2013-10-26 16:53:18Z wkliao $
+!
+
+!
+! Use for logging error messages
+!
+ subroutine error(msg)
+ use pnetcdf
+ implicit none
+ character*(*) msg
+#include "tests.inc"
+
+ nfails = nfails + 1
+ if (nfails .le. max_nmpt) print *, msg
+ end
+
+
+!
+! Use for logging error conditions
+!
+ subroutine errori(msg, i)
+ use pnetcdf
+ implicit none
+ character*(*) msg
+ integer i
+#include "tests.inc"
+
+ nfails = nfails + 1
+ if (nfails .le. max_nmpt) print *, msg, i
+ end
+
+
+!
+! Use for logging error conditions
+!
+ subroutine errord(msg, d)
+ use pnetcdf
+ implicit none
+ character*(*) msg
+ doubleprecision d
+#include "tests.inc"
+
+ nfails = nfails + 1
+ if (nfails .le. max_nmpt) print *, msg, d
+ end
+
+
+!
+! Use for logging error conditions
+!
+ subroutine errorc(msg, string)
+ use pnetcdf
+ implicit none
+ character*(*) msg
+ character*(*) string
+#include "tests.inc"
+
+ nfails = nfails + 1
+ if (nfails .le. max_nmpt) print *, msg, &
+ trim(string)
+ end
+
+
+!
+! Use for logging error conditions
+!
+ subroutine errore(msg, err)
+ use pnetcdf
+ implicit none
+ character*(*) msg
+ integer err
+#include "tests.inc"
+
+ nfails = nfails + 1
+ call errorc(msg, nf90mpi_strerror(err))
+ end
diff --git a/test/nf90_test/nf90_test.F90 b/test/nf90_test/nf90_test.F90
new file mode 100644
index 0000000..e905bb7
--- /dev/null
+++ b/test/nf90_test/nf90_test.F90
@@ -0,0 +1,849 @@
+!
+! Copyright (C) 2013, Northwestern University and Argonne National Laboratory
+! See COPYRIGHT notice in top-level directory.
+!
+! $Id: nf90_test.F90 2131 2015-09-25 22:33:12Z wkliao $
+!
+
+!
+! Test driver for netCDF-3 interface. This program performs tests against
+! the netCDF-3 specification for all user-level functions in an
+! implementation of the netCDF library.
+!
+! Unless invoked with "-r" (readonly) option, must be invoked from a
+! directory in which the invoker has write permission.
+!
+! Files:
+! The read-only tests read files:
+! test.nc (see below)
+! test_get.F (used merely as an example of a non-netCDF file)
+!
+! The write tests
+! read test.nc (see below)
+! write scratch.nc (deleted after each test)
+!
+! The file test.nc is created by running nc_test with the -c (create) option.
+!
+
+ subroutine usage()
+ use pnetcdf
+ implicit none
+#include "tests.inc"
+
+ call error('usage: nf90_test [-hrv] [-n <MAX_NMPT>]')
+ call error(' nf90_test [-c]')
+ call error(' [-h] Print help' )
+ call error(' [-c] Create file test.nc (Do not do tests)' )
+ call error(' [-1] test CDF-1 format' )
+ call error(' [-2] test CDF-2 format' )
+ call error(' [-5] test CDF-5 format' )
+ call error(' [-r] Just do read-only tests' )
+ call error( &
+ ' [-d directory] directory for storing input/output files' )
+ call error(' [-v] Verbose mode' )
+ call error( &
+ ' [-n <max>] max. number of messages per test (Default: 20)')
+ end
+
+ subroutine report_test
+ implicit none
+ character*128 msg
+#include "tests.inc"
+
+ write(msg,"(A,I1)") '*** TESTING F90 '//trim(PROGNAME)// &
+ ' for CDF-', cdf_format
+ if (nfailsTotal .ne. 0) then
+ write(*,*) trim(PROGNAME)//' expects to see 0 failure ... '//&
+ 'Total number of failures: ', nfailsTotal
+ endif
+ call pass_fail(nfailsTotal, msg)
+ end
+
+ subroutine test(name, func)
+ use pnetcdf
+ implicit none
+ character*(*) name
+ character(len=25) name_str
+ integer name_len
+ external func
+#include "tests.inc"
+
+ name_len = LEN_TRIM(name)
+ name_str(1:name_len) = name(:)
+ name_str(name_len+1:25) = ' '
+ if (verbose) write(*, 1, advance="no") name_str
+1 format('*** Testing ', a, ' ... ')
+
+ nfails = 0
+ call func()
+ nfailsTotal = nfailsTotal + nfails
+ if ( nfails .ne. 0) then
+ print *, ' '
+ print *, ' ### ', nfails, ' FAILURES TESTING ', name, &
+ '! Stop ... ###'
+ call report_test
+ stop
+ end if
+ end
+
+
+#if _CRAYIEEE
+! which machines need this?
+ subroutine getarg(iarg, carg)
+ use pnetcdf
+ implicit none
+ integer iarg
+ character*(*) carg
+ integer ilen
+ integer ierror
+ call PXFGETARG(iarg, carg, ilen, ierror)
+ end
+#endif
+
+ program nf_test
+ use pnetcdf
+#if defined(VISUAL_CPLUSPLUS)
+! DIGITAL Visual Fortran needs DFLIB for getarg
+ USE DFLIB
+! DIGITAL Visual Fortran needs DFPORT for iargc
+ USE DFPORT
+ implicit none
+#elif defined(NAGf90Fortran)
+ USE F90_UNIX_ENV, only : iargc, getarg
+ implicit none
+#else
+ implicit none
+ integer iargc
+#endif
+#if defined(__crayx1)
+ integer ipxfargc
+#endif
+#include "tests.inc"
+
+ integer argc
+ character*80 arg
+ integer iarg
+ integer iopt
+ character*1 opt
+ integer lastopt
+ logical skiparg
+ integer err
+
+ external test_nf90mpi_strerror
+ external test_nf90mpi_open
+ external test_nf90mpi_close
+ external test_nf90mpi_inq
+ external test_nf90mpi_inq_dimid
+ external test_nf90mpi_inq_dim
+ external test_nf90mpi_inq_dimlen
+ external test_nf90mpi_inq_dimname
+ external test_nf90mpi_inq_varid
+ external test_nf90mpi_inq_var
+ external test_nf90mpi_inq_natts
+ external test_nf90mpi_inq_ndims
+ external test_nf90mpi_inq_nvars
+ external test_nf90mpi_inq_unlimdim
+ external test_nf90mpi_inq_vardimid
+ external test_nf90mpi_inq_varname
+ external test_nf90mpi_inq_varnatts
+ external test_nf90mpi_inq_varndims
+ external test_nf90mpi_inq_vartype
+ external test_nf90mpi_get_var1_text
+#if defined(NF_INT1_T)
+ external test_nf90mpi_get_var1_int1
+#endif
+#if defined(NF_INT2_T)
+ external test_nf90mpi_get_var1_int2
+#endif
+ external test_nf90mpi_get_var1_int
+ external test_nf90mpi_get_var1_real
+ external test_nf90mpi_get_var1_double
+ external test_nf90mpi_get_var1_int8
+ external test_nf90mpi_get_var_text
+#if defined(NF_INT1_T)
+ external test_nf90mpi_get_var_int1
+#endif
+#if defined(NF_INT2_T)
+ external test_nf90mpi_get_var_int2
+#endif
+ external test_nf90mpi_get_var_int
+ external test_nf90mpi_get_var_real
+ external test_nf90mpi_get_var_double
+ external test_nf90mpi_get_var_int8
+ external test_nf90mpi_get_vara_text
+#if defined(NF_INT1_T)
+ external test_nf90mpi_get_vara_int1
+#endif
+#if defined(NF_INT2_T)
+ external test_nf90mpi_get_vara_int2
+#endif
+ external test_nf90mpi_get_vara_int
+ external test_nf90mpi_get_vara_real
+ external test_nf90mpi_get_vara_double
+ external test_nf90mpi_get_vara_int8
+ external test_nf90mpi_get_vars_text
+#if defined(NF_INT1_T)
+ external test_nf90mpi_get_vars_int1
+#endif
+#if defined(NF_INT2_T)
+ external test_nf90mpi_get_vars_int2
+#endif
+ external test_nf90mpi_get_vars_int
+ external test_nf90mpi_get_vars_real
+ external test_nf90mpi_get_vars_double
+ external test_nf90mpi_get_vars_int8
+
+ external test_nf90mpi_get_varm_text
+#if defined(NF_INT1_T)
+ external test_nf90mpi_get_varm_int1
+#endif
+#if defined(NF_INT2_T)
+ external test_nf90mpi_get_varm_int2
+#endif
+ external test_nf90mpi_get_varm_int
+ external test_nf90mpi_get_varm_real
+ external test_nf90mpi_get_varm_double
+ external test_nf90mpi_get_varm_int8
+
+ external test_nf90mpi_iget_var1_text
+#if defined(NF_INT1_T)
+ external test_nf90mpi_iget_var1_int1
+#endif
+#if defined(NF_INT2_T)
+ external test_nf90mpi_iget_var1_int2
+#endif
+ external test_nf90mpi_iget_var1_int
+ external test_nf90mpi_iget_var1_real
+ external test_nf90mpi_iget_var1_double
+ external test_nf90mpi_iget_var1_int8
+ external test_nf90mpi_iget_var_text
+#if defined(NF_INT1_T)
+ external test_nf90mpi_iget_var_int1
+#endif
+#if defined(NF_INT2_T)
+ external test_nf90mpi_iget_var_int2
+#endif
+ external test_nf90mpi_iget_var_int
+ external test_nf90mpi_iget_var_real
+ external test_nf90mpi_iget_var_double
+ external test_nf90mpi_iget_var_int8
+ external test_nf90mpi_iget_vara_text
+#if defined(NF_INT1_T)
+ external test_nf90mpi_iget_vara_int1
+#endif
+#if defined(NF_INT2_T)
+ external test_nf90mpi_iget_vara_int2
+#endif
+ external test_nf90mpi_iget_vara_int
+ external test_nf90mpi_iget_vara_real
+ external test_nf90mpi_iget_vara_double
+ external test_nf90mpi_iget_vara_int8
+ external test_nf90mpi_iget_vars_text
+#if defined(NF_INT1_T)
+ external test_nf90mpi_iget_vars_int1
+#endif
+#if defined(NF_INT2_T)
+ external test_nf90mpi_iget_vars_int2
+#endif
+ external test_nf90mpi_iget_vars_int
+ external test_nf90mpi_iget_vars_real
+ external test_nf90mpi_iget_vars_double
+ external test_nf90mpi_iget_vars_int8
+
+ external test_nf90mpi_iget_varm_text
+#if defined(NF_INT1_T)
+ external test_nf90mpi_iget_varm_int1
+#endif
+#if defined(NF_INT2_T)
+ external test_nf90mpi_iget_varm_int2
+#endif
+ external test_nf90mpi_iget_varm_int
+ external test_nf90mpi_iget_varm_real
+ external test_nf90mpi_iget_varm_double
+ external test_nf90mpi_iget_varm_int8
+
+ external test_nf90mpi_get_att_text
+#if defined(NF_INT1_T)
+ external test_nf90mpi_get_att_int1
+#endif
+#if defined(NF_INT2_T)
+ external test_nf90mpi_get_att_int2
+#endif
+ external test_nf90mpi_get_att_int
+ external test_nf90mpi_get_att_real
+ external test_nf90mpi_get_att_double
+ external test_nf90mpi_get_att_int8
+ external test_nf90mpi_inq_att
+ external test_nf90mpi_inq_attname
+ external test_nf90mpi_inq_attid
+ external test_nf90mpi_inq_attlen
+ external test_nf90mpi_inq_atttype
+ external test_nf90mpi_create
+ external test_nf90mpi_redef
+ external test_nf90mpi_enddef
+ external test_nf90mpi_sync
+ external test_nf90mpi_abort
+ external test_nf90mpi_def_dim
+ external test_nf90mpi_rename_dim
+ external test_nf90mpi_def_var
+ external test_nf90mpi_put_var1_text
+#if defined(NF_INT1_T)
+ external test_nf90mpi_put_var1_int1
+#endif
+#if defined(NF_INT2_T)
+ external test_nf90mpi_put_var1_int2
+#endif
+ external test_nf90mpi_put_var1_int
+ external test_nf90mpi_put_var1_real
+ external test_nf90mpi_put_var1_double
+ external test_nf90mpi_put_var1_int8
+ external test_nf90mpi_put_var_text
+#if defined(NF_INT1_T)
+ external test_nf90mpi_put_var_int1
+#endif
+#if defined(NF_INT2_T)
+ external test_nf90mpi_put_var_int2
+#endif
+ external test_nf90mpi_put_var_int
+ external test_nf90mpi_put_var_real
+ external test_nf90mpi_put_var_double
+ external test_nf90mpi_put_var_int8
+ external test_nf90mpi_put_vara_text
+#if defined(NF_INT1_T)
+ external test_nf90mpi_put_vara_int1
+#endif
+#if defined(NF_INT2_T)
+ external test_nf90mpi_put_vara_int2
+#endif
+ external test_nf90mpi_put_vara_int
+ external test_nf90mpi_put_vara_real
+ external test_nf90mpi_put_vara_double
+ external test_nf90mpi_put_vara_int8
+ external test_nf90mpi_put_vars_text
+#if defined(NF_INT1_T)
+ external test_nf90mpi_put_vars_int1
+#endif
+#if defined(NF_INT2_T)
+ external test_nf90mpi_put_vars_int2
+#endif
+ external test_nf90mpi_put_vars_int
+ external test_nf90mpi_put_vars_real
+ external test_nf90mpi_put_vars_double
+ external test_nf90mpi_put_vars_int8
+
+ external test_nf90mpi_put_varm_text
+#if defined(NF_INT1_T)
+ external test_nf90mpi_put_varm_int1
+#endif
+#if defined(NF_INT2_T)
+ external test_nf90mpi_put_varm_int2
+#endif
+ external test_nf90mpi_put_varm_int
+ external test_nf90mpi_put_varm_real
+ external test_nf90mpi_put_varm_double
+ external test_nf90mpi_put_varm_int8
+
+ external test_nf90mpi_iput_var1_text
+#if defined(NF_INT1_T)
+ external test_nf90mpi_iput_var1_int1
+#endif
+#if defined(NF_INT2_T)
+ external test_nf90mpi_iput_var1_int2
+#endif
+ external test_nf90mpi_iput_var1_int
+ external test_nf90mpi_iput_var1_real
+ external test_nf90mpi_iput_var1_double
+ external test_nf90mpi_iput_var1_int8
+ external test_nf90mpi_iput_var_text
+#if defined(NF_INT1_T)
+ external test_nf90mpi_iput_var_int1
+#endif
+#if defined(NF_INT2_T)
+ external test_nf90mpi_iput_var_int2
+#endif
+ external test_nf90mpi_iput_var_int
+ external test_nf90mpi_iput_var_real
+ external test_nf90mpi_iput_var_double
+ external test_nf90mpi_iput_var_int8
+ external test_nf90mpi_iput_vara_text
+#if defined(NF_INT1_T)
+ external test_nf90mpi_iput_vara_int1
+#endif
+#if defined(NF_INT2_T)
+ external test_nf90mpi_iput_vara_int2
+#endif
+ external test_nf90mpi_iput_vara_int
+ external test_nf90mpi_iput_vara_real
+ external test_nf90mpi_iput_vara_double
+ external test_nf90mpi_iput_vara_int8
+ external test_nf90mpi_iput_vars_text
+#if defined(NF_INT1_T)
+ external test_nf90mpi_iput_vars_int1
+#endif
+#if defined(NF_INT2_T)
+ external test_nf90mpi_iput_vars_int2
+#endif
+ external test_nf90mpi_iput_vars_int
+ external test_nf90mpi_iput_vars_real
+ external test_nf90mpi_iput_vars_double
+ external test_nf90mpi_iput_vars_int8
+
+ external test_nf90mpi_iput_varm_text
+#if defined(NF_INT1_T)
+ external test_nf90mpi_iput_varm_int1
+#endif
+#if defined(NF_INT2_T)
+ external test_nf90mpi_iput_varm_int2
+#endif
+ external test_nf90mpi_iput_varm_int
+ external test_nf90mpi_iput_varm_real
+ external test_nf90mpi_iput_varm_double
+ external test_nf90mpi_iput_varm_int8
+
+ external test_nf90mpi_rename_var
+ external test_nf90mpi_put_att_text
+#if defined(NF_INT1_T)
+ external test_nf90mpi_put_att_int1
+#endif
+#if defined(NF_INT2_T)
+ external test_nf90mpi_put_att_int2
+#endif
+ external test_nf90mpi_put_att_int
+ external test_nf90mpi_put_att_real
+ external test_nf90mpi_put_att_double
+ external test_nf90mpi_put_att_int8
+ external test_nf90mpi_copy_att
+ external test_nf90mpi_rename_att
+ external test_nf90mpi_del_att
+ external test_nf90mpi_set_fill
+#if 0
+ external test_nf90mpi_set_default_format
+#endif
+ external nc_ignorefpe
+
+ call MPI_INIT(err)
+ comm = MPI_COMM_WORLD
+
+ call nc_ignorefpe(1)
+
+ testfile = 'test.nc'
+ scratch = 'scratch.nc'
+
+ nfailsTotal = 0
+ call getarg(0, progname)
+ create_file = .false. !/* file test.nc will normally already exist */
+ readonly = .false. !/* assume may write in test dir as default */
+ verbose = .false.
+ max_nmpt = 20
+ skiparg = .false.
+ cdf_format = 1
+ extra_flags = 0
+
+#if defined(__crayx1)
+ argc = ipxfargc()
+#else
+ argc = iargc()
+#endif
+ call getarg(0, PROGNAME)
+
+ do 1, iarg = 1, argc
+ if (skiparg) then
+ skiparg = .false.
+ else
+ call getarg(iarg, arg)
+ if (arg(1:1) .eq. '-') then
+ lastopt = index(arg, ' ') - 1
+ do 2, iopt = 2, lastopt
+ opt = arg(iopt:iopt)
+ if (opt .eq. 'c') then
+ create_file = .true.
+ else if (opt .eq. 'r') then
+ readonly = .true.
+ else if (opt .eq. 'v') then
+ verbose = .true.
+ else if (opt .eq. 'n') then
+ call getarg(iarg+1, arg)
+ ! NOTE: The UNICOS 8 fort77(1) compiler does
+ ! not support list-directed I/O from an internal
+ ! file -- so we use a format specification.
+ read (arg, '(i6)') max_nmpt
+ skiparg = .true.
+ go to 1
+ else if (opt .eq. '1') then
+ cdf_format = 1
+ else if (opt .eq. '2') then
+ cdf_format = 2
+ extra_flags = NF90_64BIT_OFFSET
+ else if (opt .eq. '5') then
+ cdf_format = 5
+ extra_flags = NF90_64BIT_DATA
+ else if (opt .eq. 'd') then
+ call getarg(iarg+1, arg)
+ testfile = trim(arg) // "/test.nc"
+ scratch = trim(arg) // "/scratch.nc"
+ skiparg = .true.
+ go to 1
+ else
+ call usage
+ call ud_exit(1)
+ end if
+ 2 continue
+ else
+ call usage
+ call ud_exit(1)
+ end if
+ end if
+1 continue
+
+ call MPI_Info_create(info, err)
+ ! call MPI_Info_set(info, "romio_pvfs2_posix_write", "enable",err)
+
+ numGatts = 6
+ numVars = 136
+ numTypes = 6
+ if (cdf_format .EQ. 5) then
+ numGatts = NGATTS
+ numVars = NVARS
+ numTypes = NTYPES
+ endif
+
+! /* Initialize global variables defining test file */
+ call init_gvars
+
+ if ( create_file ) then
+ call write_file(testfile)
+ call MPI_Info_free(info, err)
+ if (nfailsTotal .eq. 0) &
+ call ud_exit(0)
+ call ud_exit(1)
+ end if
+
+! /* delete any existing scratch netCDF file */
+ if ( .not. readonly ) &
+ err = nf90mpi_delete(scratch, info)
+
+! /* Test read-only functions, using pregenerated test-file */
+ call test('nf90mpi_strerror', test_nf90mpi_strerror)
+ call test('nf90mpi_open', test_nf90mpi_open)
+ call test('nf90mpi_close', test_nf90mpi_close)
+ call test('nf90mpi_inq', test_nf90mpi_inq)
+ call test('nf90mpi_inq_dimid', test_nf90mpi_inq_dimid)
+ call test('nf90mpi_inq_dim', test_nf90mpi_inq_dim)
+ call test('nf90mpi_inq_dimlen', test_nf90mpi_inq_dimlen)
+ call test('nf90mpi_inq_dimname', test_nf90mpi_inq_dimname)
+ call test('nf90mpi_inq_varid', test_nf90mpi_inq_varid)
+ call test('nf90mpi_inq_var', test_nf90mpi_inq_var)
+ call test('nf90mpi_inq_natts', test_nf90mpi_inq_natts)
+ call test('nf90mpi_inq_ndims', test_nf90mpi_inq_ndims)
+ call test('nf90mpi_inq_nvars', test_nf90mpi_inq_nvars)
+ call test('nf90mpi_inq_unlimdim', test_nf90mpi_inq_unlimdim)
+ call test('nf90mpi_inq_vardimid', test_nf90mpi_inq_vardimid)
+ call test('nf90mpi_inq_varname', test_nf90mpi_inq_varname)
+ call test('nf90mpi_inq_varnatts', test_nf90mpi_inq_varnatts)
+ call test('nf90mpi_inq_varndims', test_nf90mpi_inq_varndims)
+ call test('nf90mpi_inq_vartype', test_nf90mpi_inq_vartype)
+
+ call test('nf90mpi_get_var1_text', test_nf90mpi_get_var1_text)
+#if defined(NF_INT1_T)
+ call test('nf90mpi_get_var1_int1', test_nf90mpi_get_var1_int1)
+#endif
+#if defined(NF_INT2_T)
+ call test('nf90mpi_get_var1_int2', test_nf90mpi_get_var1_int2)
+#endif
+ call test('nf90mpi_get_var1_int', test_nf90mpi_get_var1_int)
+ call test('nf90mpi_get_var1_real', test_nf90mpi_get_var1_real)
+ call test('nf90mpi_get_var1_double', test_nf90mpi_get_var1_double)
+ call test('nf90mpi_get_var1_int8', test_nf90mpi_get_var1_int8)
+
+ call test('nf90mpi_get_var_text', test_nf90mpi_get_var_text)
+#if defined(NF_INT1_T)
+ call test('nf90mpi_get_var_int1', test_nf90mpi_get_var_int1)
+#endif
+#if defined(NF_INT2_T)
+ call test('nf90mpi_get_var_int2', test_nf90mpi_get_var_int2)
+#endif
+ call test('nf90mpi_get_var_int', test_nf90mpi_get_var_int)
+ call test('nf90mpi_get_var_real', test_nf90mpi_get_var_real)
+ call test('nf90mpi_get_var_double', test_nf90mpi_get_var_double)
+ call test('nf90mpi_get_var_int8', test_nf90mpi_get_var_int8)
+
+ call test('nf90mpi_get_vara_text', test_nf90mpi_get_vara_text)
+#if defined(NF_INT1_T)
+ call test('nf90mpi_get_vara_int1', test_nf90mpi_get_vara_int1)
+#endif
+#if defined(NF_INT2_T)
+ call test('nf90mpi_get_vara_int2', test_nf90mpi_get_vara_int2)
+#endif
+ call test('nf90mpi_get_vara_int', test_nf90mpi_get_vara_int)
+ call test('nf90mpi_get_vara_real', test_nf90mpi_get_vara_real)
+ call test('nf90mpi_get_vara_double', test_nf90mpi_get_vara_double)
+ call test('nf90mpi_get_vara_int8', test_nf90mpi_get_vara_int8)
+
+ call test('nf90mpi_get_vars_text', test_nf90mpi_get_vars_text)
+#if defined(NF_INT1_T)
+ call test('nf90mpi_get_vars_int1', test_nf90mpi_get_vars_int1)
+#endif
+#if defined(NF_INT2_T)
+ call test('nf90mpi_get_vars_int2', test_nf90mpi_get_vars_int2)
+#endif
+ call test('nf90mpi_get_vars_int', test_nf90mpi_get_vars_int)
+ call test('nf90mpi_get_vars_real', test_nf90mpi_get_vars_real)
+ call test('nf90mpi_get_vars_double', test_nf90mpi_get_vars_double)
+ call test('nf90mpi_get_vars_int8', test_nf90mpi_get_vars_int8)
+
+ call test('nf90mpi_get_varm_text', test_nf90mpi_get_varm_text)
+#if defined(NF_INT1_T)
+ call test('nf90mpi_get_varm_int1', test_nf90mpi_get_varm_int1)
+#endif
+#if defined(NF_INT2_T)
+ call test('nf90mpi_get_varm_int2', test_nf90mpi_get_varm_int2)
+#endif
+ call test('nf90mpi_get_varm_int', test_nf90mpi_get_varm_int)
+ call test('nf90mpi_get_varm_real', test_nf90mpi_get_varm_real)
+ call test('nf90mpi_get_varm_double', test_nf90mpi_get_varm_double)
+ call test('nf90mpi_get_varm_int8', test_nf90mpi_get_varm_int8)
+
+ call test('nf90mpi_iget_var1_text', test_nf90mpi_iget_var1_text)
+#if defined(NF_INT1_T)
+ call test('nf90mpi_iget_var1_int1', test_nf90mpi_iget_var1_int1)
+#endif
+#if defined(NF_INT2_T)
+ call test('nf90mpi_iget_var1_int2', test_nf90mpi_iget_var1_int2)
+#endif
+ call test('nf90mpi_iget_var1_int', test_nf90mpi_iget_var1_int)
+ call test('nf90mpi_iget_var1_real', test_nf90mpi_iget_var1_real)
+ call test('nf90mpi_iget_var1_double', test_nf90mpi_iget_var1_double)
+ call test('nf90mpi_iget_var1_int8', test_nf90mpi_iget_var1_int8)
+
+ call test('nf90mpi_iget_var_text', test_nf90mpi_iget_var_text)
+#if defined(NF_INT1_T)
+ call test('nf90mpi_iget_var_int1', test_nf90mpi_iget_var_int1)
+#endif
+#if defined(NF_INT2_T)
+ call test('nf90mpi_iget_var_int2', test_nf90mpi_iget_var_int2)
+#endif
+ call test('nf90mpi_iget_var_int', test_nf90mpi_iget_var_int)
+ call test('nf90mpi_iget_var_real', test_nf90mpi_iget_var_real)
+ call test('nf90mpi_iget_var_double', test_nf90mpi_iget_var_double)
+ call test('nf90mpi_iget_var_int8', test_nf90mpi_iget_var_int8)
+
+ call test('nf90mpi_iget_vara_text', test_nf90mpi_iget_vara_text)
+#if defined(NF_INT1_T)
+ call test('nf90mpi_iget_vara_int1', test_nf90mpi_iget_vara_int1)
+#endif
+#if defined(NF_INT2_T)
+ call test('nf90mpi_iget_vara_int2', test_nf90mpi_iget_vara_int2)
+#endif
+ call test('nf90mpi_iget_vara_int', test_nf90mpi_iget_vara_int)
+ call test('nf90mpi_iget_vara_real', test_nf90mpi_iget_vara_real)
+ call test('nf90mpi_iget_vara_double', test_nf90mpi_iget_vara_double)
+ call test('nf90mpi_iget_vara_int8', test_nf90mpi_iget_vara_int8)
+
+ call test('nf90mpi_iget_vars_text', test_nf90mpi_iget_vars_text)
+#if defined(NF_INT1_T)
+ call test('nf90mpi_iget_vars_int1', test_nf90mpi_iget_vars_int1)
+#endif
+#if defined(NF_INT2_T)
+ call test('nf90mpi_iget_vars_int2', test_nf90mpi_iget_vars_int2)
+#endif
+ call test('nf90mpi_iget_vars_int', test_nf90mpi_iget_vars_int)
+ call test('nf90mpi_iget_vars_real', test_nf90mpi_iget_vars_real)
+ call test('nf90mpi_iget_vars_double', test_nf90mpi_iget_vars_double)
+ call test('nf90mpi_iget_vars_int8', test_nf90mpi_iget_vars_int8)
+
+ call test('nf90mpi_iget_varm_text', test_nf90mpi_iget_varm_text)
+#if defined(NF_INT1_T)
+ call test('nf90mpi_iget_varm_int1', test_nf90mpi_iget_varm_int1)
+#endif
+#if defined(NF_INT2_T)
+ call test('nf90mpi_iget_varm_int2', test_nf90mpi_iget_varm_int2)
+#endif
+ call test('nf90mpi_iget_varm_int', test_nf90mpi_iget_varm_int)
+ call test('nf90mpi_iget_varm_real', test_nf90mpi_iget_varm_real)
+ call test('nf90mpi_iget_varm_double', test_nf90mpi_iget_varm_double)
+ call test('nf90mpi_iget_varm_int8', test_nf90mpi_iget_varm_int8)
+
+ call test('nf90mpi_get_att_text', test_nf90mpi_get_att_text)
+#if defined(NF_INT1_T)
+ call test('nf90mpi_get_att_int1', test_nf90mpi_get_att_int1)
+#endif
+#if defined(NF_INT2_T)
+ call test('nf90mpi_get_att_int2', test_nf90mpi_get_att_int2)
+#endif
+ call test('nf90mpi_get_att_int', test_nf90mpi_get_att_int)
+ call test('nf90mpi_get_att_real', test_nf90mpi_get_att_real)
+ call test('nf90mpi_get_att_double', test_nf90mpi_get_att_double)
+ call test('nf90mpi_get_att_int8', test_nf90mpi_get_att_int8)
+ call test('nf90mpi_inq_att', test_nf90mpi_inq_att)
+ call test('nf90mpi_inq_attname', test_nf90mpi_inq_attname)
+ call test('nf90mpi_inq_attid', test_nf90mpi_inq_attid)
+ call test('nf90mpi_inq_attlen', test_nf90mpi_inq_attlen)
+ call test('nf90mpi_inq_atttype', test_nf90mpi_inq_atttype)
+
+! /* Test write functions */
+ if (.not. readonly) then
+ call test('nf90mpi_create', test_nf90mpi_create)
+ call test('nf90mpi_redef', test_nf90mpi_redef)
+ call test('nf90mpi_enddef', test_nf90mpi_enddef)
+ call test('nf90mpi_sync', test_nf90mpi_sync)
+ call test('nf90mpi_abort', test_nf90mpi_abort)
+ call test('nf90mpi_def_dim', test_nf90mpi_def_dim)
+ call test('nf90mpi_rename_dim', test_nf90mpi_rename_dim)
+ call test('nf90mpi_def_var', test_nf90mpi_def_var)
+ call test('nf90mpi_put_var1_text', test_nf90mpi_put_var1_text)
+#if defined(NF_INT1_T)
+ call test('nf90mpi_put_var1_int1', test_nf90mpi_put_var1_int1)
+#endif
+#if defined(NF_INT2_T)
+ call test('nf90mpi_put_var1_int2', test_nf90mpi_put_var1_int2)
+#endif
+ call test('nf90mpi_put_var1_int', test_nf90mpi_put_var1_int)
+ call test('nf90mpi_put_var1_real', test_nf90mpi_put_var1_real)
+ call test('nf90mpi_put_var1_double', &
+ test_nf90mpi_put_var1_double)
+ call test('nf90mpi_put_var1_int8', test_nf90mpi_put_var1_int8)
+ call test('nf90mpi_put_var_text', test_nf90mpi_put_var_text)
+#if defined(NF_INT1_T)
+ call test('nf90mpi_put_var_int1', test_nf90mpi_put_var_int1)
+#endif
+#if defined(NF_INT2_T)
+ call test('nf90mpi_put_var_int2', test_nf90mpi_put_var_int2)
+#endif
+ call test('nf90mpi_put_var_int', test_nf90mpi_put_var_int)
+ call test('nf90mpi_put_var_real', test_nf90mpi_put_var_real)
+ call test('nf90mpi_put_var_double', &
+ test_nf90mpi_put_var_double)
+ call test('nf90mpi_put_var_int8', test_nf90mpi_put_var_int8)
+ call test('nf90mpi_put_vara_text', test_nf90mpi_put_vara_text)
+#if defined(NF_INT1_T)
+ call test('nf90mpi_put_vara_int1', test_nf90mpi_put_vara_int1)
+#endif
+#if defined(NF_INT2_T)
+ call test('nf90mpi_put_vara_int2', test_nf90mpi_put_vara_int2)
+#endif
+ call test('nf90mpi_put_vara_int', test_nf90mpi_put_vara_int)
+ call test('nf90mpi_put_vara_real', test_nf90mpi_put_vara_real)
+ call test('nf90mpi_put_vara_double', &
+ test_nf90mpi_put_vara_double)
+ call test('nf90mpi_put_vara_int8', test_nf90mpi_put_vara_int8)
+ call test('nf90mpi_put_vars_text', test_nf90mpi_put_vars_text)
+#if defined(NF_INT1_T)
+ call test('nf90mpi_put_vars_int1', test_nf90mpi_put_vars_int1)
+#endif
+#if defined(NF_INT2_T)
+ call test('nf90mpi_put_vars_int2', test_nf90mpi_put_vars_int2)
+#endif
+ call test('nf90mpi_put_vars_int', test_nf90mpi_put_vars_int)
+ call test('nf90mpi_put_vars_real', test_nf90mpi_put_vars_real)
+ call test('nf90mpi_put_vars_double', &
+ test_nf90mpi_put_vars_double)
+ call test('nf90mpi_put_vars_int8', test_nf90mpi_put_vars_int8)
+
+ call test('nf90mpi_put_varm_text', test_nf90mpi_put_varm_text)
+#if defined(NF_INT1_T)
+ call test('nf90mpi_put_varm_int1', test_nf90mpi_put_varm_int1)
+#endif
+#if defined(NF_INT2_T)
+ call test('nf90mpi_put_varm_int2', test_nf90mpi_put_varm_int2)
+#endif
+ call test('nf90mpi_put_varm_int', test_nf90mpi_put_varm_int)
+ call test('nf90mpi_put_varm_real', test_nf90mpi_put_varm_real)
+ call test('nf90mpi_put_varm_double', &
+ test_nf90mpi_put_varm_double)
+ call test('nf90mpi_put_varm_int8', test_nf90mpi_put_varm_int8)
+
+ call test('nf90mpi_iput_var1_text', test_nf90mpi_iput_var1_text)
+#if defined(NF_INT1_T)
+ call test('nf90mpi_iput_var1_int1', test_nf90mpi_iput_var1_int1)
+#endif
+#if defined(NF_INT2_T)
+ call test('nf90mpi_iput_var1_int2', test_nf90mpi_iput_var1_int2)
+#endif
+ call test('nf90mpi_iput_var1_int', test_nf90mpi_iput_var1_int)
+ call test('nf90mpi_iput_var1_real', test_nf90mpi_iput_var1_real)
+ call test('nf90mpi_iput_var1_double', &
+ test_nf90mpi_iput_var1_double)
+ call test('nf90mpi_iput_var1_int8', test_nf90mpi_iput_var1_int8)
+
+ call test('nf90mpi_iput_var_text', test_nf90mpi_iput_var_text)
+#if defined(NF_INT1_T)
+ call test('nf90mpi_iput_var_int1', test_nf90mpi_iput_var_int1)
+#endif
+#if defined(NF_INT2_T)
+ call test('nf90mpi_iput_var_int2', test_nf90mpi_iput_var_int2)
+#endif
+ call test('nf90mpi_iput_var_int', test_nf90mpi_iput_var_int)
+ call test('nf90mpi_iput_var_real', test_nf90mpi_iput_var_real)
+ call test('nf90mpi_iput_var_double', &
+ test_nf90mpi_iput_var_double)
+ call test('nf90mpi_iput_var_int8', test_nf90mpi_iput_var_int8)
+
+ call test('nf90mpi_iput_vara_text', test_nf90mpi_iput_vara_text)
+#if defined(NF_INT1_T)
+ call test('nf90mpi_iput_vara_int1', test_nf90mpi_iput_vara_int1)
+#endif
+#if defined(NF_INT2_T)
+ call test('nf90mpi_iput_vara_int2', test_nf90mpi_iput_vara_int2)
+#endif
+ call test('nf90mpi_iput_vara_int', test_nf90mpi_iput_vara_int)
+ call test('nf90mpi_iput_vara_real', test_nf90mpi_iput_vara_real)
+ call test('nf90mpi_iput_vara_double', &
+ test_nf90mpi_iput_vara_double)
+ call test('nf90mpi_iput_vara_int8', test_nf90mpi_iput_vara_int8)
+
+ call test('nf90mpi_iput_vars_text', test_nf90mpi_iput_vars_text)
+#if defined(NF_INT1_T)
+ call test('nf90mpi_iput_vars_int1', test_nf90mpi_iput_vars_int1)
+#endif
+#if defined(NF_INT2_T)
+ call test('nf90mpi_iput_vars_int2', test_nf90mpi_iput_vars_int2)
+#endif
+ call test('nf90mpi_iput_vars_int', test_nf90mpi_iput_vars_int)
+ call test('nf90mpi_iput_vars_real', test_nf90mpi_iput_vars_real)
+ call test('nf90mpi_iput_vars_double', &
+ test_nf90mpi_iput_vars_double)
+ call test('nf90mpi_iput_vars_int8', test_nf90mpi_iput_vars_int8)
+
+ call test('nf90mpi_iput_varm_text', test_nf90mpi_iput_varm_text)
+#if defined(NF_INT1_T)
+ call test('nf90mpi_iput_varm_int1', test_nf90mpi_iput_varm_int1)
+#endif
+#if defined(NF_INT2_T)
+ call test('nf90mpi_iput_varm_int2', test_nf90mpi_iput_varm_int2)
+#endif
+ call test('nf90mpi_iput_varm_int', test_nf90mpi_iput_varm_int)
+ call test('nf90mpi_iput_varm_real', test_nf90mpi_iput_varm_real)
+ call test('nf90mpi_iput_varm_double', &
+ test_nf90mpi_iput_varm_double)
+ call test('nf90mpi_iput_varm_int8', test_nf90mpi_iput_varm_int8)
+
+ call test('nf90mpi_rename_var', test_nf90mpi_rename_var)
+ call test('nf90mpi_put_att_text', test_nf90mpi_put_att_text)
+#if defined(NF_INT1_T)
+ call test('nf90mpi_put_att_int1', test_nf90mpi_put_att_int1)
+#endif
+#if defined(NF_INT2_T)
+ call test('nf90mpi_put_att_int2', test_nf90mpi_put_att_int2)
+#endif
+ call test('nf90mpi_put_att_int', test_nf90mpi_put_att_int)
+ call test('nf90mpi_put_att_real', test_nf90mpi_put_att_real)
+ call test('nf90mpi_put_att_double', &
+ test_nf90mpi_put_att_double)
+ call test('nf90mpi_put_att_int8', test_nf90mpi_put_att_int8)
+ call test('nf90mpi_copy_att', test_nf90mpi_copy_att)
+ call test('nf90mpi_rename_att', test_nf90mpi_rename_att)
+ call test('nf90mpi_del_att', test_nf90mpi_del_att)
+ call test('nf90mpi_set_fill', test_nf90mpi_set_fill)
+#if 0
+ call test('nf90mpi_set_default_format', &
+ test_nf90mpi_set_default_format);
+#endif
+ end if
+
+ call MPI_Info_free(info, err)
+
+ call report_test
+
+ ! if (nfailsTotal .eq. 0) call ud_exit(0)
+ call ud_exit(0)
+ end
diff --git a/test/nf90_test/test_get.m4 b/test/nf90_test/test_get.m4
new file mode 100644
index 0000000..402cf80
--- /dev/null
+++ b/test/nf90_test/test_get.m4
@@ -0,0 +1,1163 @@
+dnl
+dnl Copyright (C) 2013, Northwestern University and Argonne National Laboratory
+dnl See COPYRIGHT notice in top-level directory.
+dnl
+dnl $Id: test_get.m4 1699 2014-07-05 00:32:53Z wkliao $
+dnl
+
+divert(-1)
+
+dnl This is m4 source.
+dnl Process using m4 to produce FORTRAN language file.
+
+changequote([,])
+
+undefine([index])dnl
+
+dnl Macros
+
+dnl Upcase(str)
+dnl
+define([Upcase],[dnl
+translit($1, abcdefghijklmnopqrstuvwxyz, ABCDEFGHIJKLMNOPQRSTUVWXYZ)])
+
+dnl NFT_ITYPE(type)
+dnl
+define([NFT_ITYPE], [NFT_[]Upcase($1)])
+
+dnl ARITH_VAR1(itype, value)
+dnl
+define([ARITH_VAR1], [ifelse($1, text, ichar($2(1:1)), $2(1))])
+
+dnl ARITH3(itype, value)
+dnl
+define([ARITH3], [ifelse($1, text, ichar($2($3:$3)), $2($3,1))])
+
+dnl VALUE3(itype, value)
+dnl
+define([VALUE3], [ifelse($1, text, $2(1:nels), $2(1:nels,1))])
+
+dnl ATTARITH3(itype, value)
+dnl
+define([ATTARITH3], [ifelse($1, text, ichar($2($3:$3)), $2($3))])
+
+dnl DATATYPE(funf_suffix)
+dnl
+define([DATATYPE], [dnl
+dnl ifelse($1, text, character(len=MAX_NELS) $2,
+ifelse($1, text, character(len=$3) $2,
+ifelse($1, int1, NF_INT1_T $2($3,1),
+ifelse($1, int2, NF_INT2_T $2($3,1),
+ifelse($1, int, integer $2($3,1),
+ifelse($1, int8, NF_INT8_T $2($3,1),
+ifelse($1, real, real $2($3,1),
+ifelse($1, double, doubleprecision $2($3,1))[]dnl
+)[]dnl
+)[]dnl
+)[]dnl
+)[]dnl
+)[]dnl
+)[]dnl
+])
+
+dnl DATATYPE_VAR1(funf_suffix)
+dnl
+define([DATATYPE_VAR1], [dnl
+ifelse($1, text, character(len=1) $2,
+ifelse($1, int1, NF_INT1_T $2(1),
+ifelse($1, int2, NF_INT2_T $2(1),
+ifelse($1, int, integer $2(1),
+ifelse($1, int8, NF_INT8_T $2(1),
+ifelse($1, real, real $2(1),
+ifelse($1, double, doubleprecision $2(1))[]dnl
+)[]dnl
+)[]dnl
+)[]dnl
+)[]dnl
+)[]dnl
+)[]dnl
+])
+
+dnl ATTDATATYPE(funf_suffix)
+dnl
+define([ATTDATATYPE], [dnl
+dnl ifelse($1, text, character(len=MAX_NELS) $2,
+ifelse($1, text, character(len=$3) $2,
+ifelse($1, int1, NF_INT1_T $2($3),
+ifelse($1, int2, NF_INT2_T $2($3),
+ifelse($1, int, integer $2($3),
+ifelse($1, int8, NF_INT8_T $2($3),
+ifelse($1, real, real $2($3),
+ifelse($1, double, doubleprecision $2($3))[]dnl
+)[]dnl
+)[]dnl
+)[]dnl
+)[]dnl
+)[]dnl
+)[]dnl
+])
+
+dnl TEST_NFMPI_GET_VAR1(TYPE)
+dnl
+define([TEST_NFMPI_GET_VAR1],[dnl
+ subroutine test_nf90mpi_get_var1_$1()
+ use pnetcdf
+ implicit none
+#include "tests.inc"
+ integer index2indexes
+ double precision hash4
+ logical inRange3, in_internal_range, equal
+
+ integer ncid
+ integer i
+ integer j
+ integer err
+ integer nok
+ integer(kind=MPI_OFFSET_KIND) index(MAX_RANK)
+ doubleprecision expect
+ logical canConvert
+ DATATYPE_VAR1($1, value)
+ doubleprecision val
+
+ nok = 0
+
+ err = nf90mpi_open(comm, testfile, NF90_NOWRITE, info, &
+ ncid)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_open: ', err)
+ err = nf90mpi_begin_indep_data(ncid)
+ do 1, i = 1, numVars
+ canConvert = (var_type(i) .eq. NF90_CHAR) .eqv. &
+ (NFT_ITYPE($1) .eq. NFT_TEXT)
+ do 2, j = 1, var_rank(i)
+ index(j) = 1
+2 continue
+ err = nf90mpi_get_var(BAD_ID, i, value(1:1), index)
+ if (err .ne. NF90_EBADID) &
+ call errore('bad ncid: ', err)
+ err = nf90mpi_get_var(ncid, BAD_VARID, value(1:1), index)
+ if (err .ne. NF90_ENOTVAR) &
+ call errore('bad var id: ', err)
+ do 3, j = 1, var_rank(i)
+ index(j) = var_shape(j,i) + 1
+ err = nf90mpi_get_var(ncid, i, value(1:1), index)
+ if (.not. canConvert) then
+ if (err .ne. NF90_ECHAR) &
+ call errore('conversion: ', err)
+ else
+ if (err .ne. NF90_EINVALCOORDS) &
+ call errore('bad index: ', err)
+ endif
+ index(j) = 1
+3 continue
+ do 4, j = 1, var_nels(i)
+ err = index2indexes(j, var_rank(i), var_shape(1,i), &
+ index)
+ if (err .ne. NF90_NOERR) &
+ call error('error in index2indexes 1')
+ expect = hash4( var_type(i), var_rank(i), index, &
+ NFT_ITYPE($1) )
+ err = nf90mpi_get_var(ncid, i, value(1:1), index)
+ if (canConvert) then
+ if (inRange3(expect,var_type(i), &
+ NFT_ITYPE($1))) then
+ if (in_internal_range(NFT_ITYPE($1), &
+ expect)) then
+ if (err .ne. NF90_NOERR) then
+ call errore('nf90mpi_get_var: ', err)
+ else
+ val = ARITH_VAR1($1, value)
+ if (.not. equal(val, expect, &
+ var_type(i), &
+ NFT_ITYPE($1))) then
+ call errord('unexpected: ', val)
+ else
+ nok = nok + 1
+ end if
+ end if
+ else
+ if (err .ne. NF90_ERANGE) &
+ call errore('Range error: ', err)
+ end if
+ else
+ if (err .ne. NF90_NOERR .and. err .ne. NF90_ERANGE) &
+ call errore('OK or Range error: ', err)
+ end if
+ else
+ if (err .ne. NF90_ECHAR) &
+ call errore('wrong type: ', err)
+ end if
+4 continue
+1 continue
+ err = nf90mpi_end_indep_data(ncid)
+ err = nf90mpi_close(ncid)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_close: ', err)
+ call print_nok(nok)
+ end
+])
+
+dnl TEST_NFMPI_GET_VAR(TYPE)
+dnl
+define([TEST_NFMPI_GET_VAR],[dnl
+ subroutine test_nf90mpi_get_var_$1()
+ use pnetcdf
+ implicit none
+#include "tests.inc"
+ integer index2indexes
+ double precision hash4
+ logical inrange3, in_internal_range, equal
+
+ integer ncid
+ integer i
+ integer j
+ integer err
+ logical allInExtRange
+ logical allInIntRange
+ integer(kind=MPI_OFFSET_KIND) nels
+ integer nok
+ integer(kind=MPI_OFFSET_KIND) index(MAX_RANK)
+ doubleprecision expect(MAX_NELS)
+ logical canConvert
+ DATATYPE($1, value, MAX_NELS)
+ doubleprecision val
+
+ nok = 0
+
+ err = nf90mpi_open(comm, testfile, NF90_NOWRITE, info, &
+ ncid)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_open: ', err)
+ do 1, i = 1, numVars
+ canConvert = (var_type(i) .eq. NF90_CHAR) .eqv. &
+ (NFT_ITYPE($1) .eq. NFT_TEXT)
+ err = nf90mpi_get_var_all(BAD_ID, i, value)
+ if (err .ne. NF90_EBADID) &
+ call errore('bad ncid: ', err)
+ err = nf90mpi_get_var_all(ncid, BAD_VARID, value)
+ if (err .ne. NF90_ENOTVAR) &
+ call errore('bad var id: ', err)
+ nels = 1
+ do 3, j = 1, var_rank(i)
+ nels = nels * var_shape(j,i)
+3 continue
+ allInExtRange = .true.
+ allInIntRange = .true.
+ do 4, j = 1, var_nels(i)
+ err = index2indexes(j, var_rank(i), var_shape(1,i), &
+ index)
+ if (err .ne. NF90_NOERR) &
+ call error('error in index2indexes 1')
+ expect(j) = hash4( var_type(i), var_rank(i), index, &
+ NFT_ITYPE($1) )
+ if (inRange3(expect(j),var_type(i), NFT_ITYPE($1))) then
+ allInIntRange = allInIntRange .and. &
+ in_internal_range(NFT_ITYPE($1), expect(j))
+ else
+ allInExtRange = .false.
+ end if
+4 continue
+ err = nf90mpi_get_var_all(ncid, i, VALUE3($1, value), count=var_shape(:,i))
+ if (canConvert) then
+ if (allInExtRange) then
+ if (allInIntRange) then
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_get_var_all: ', err)
+ else
+ if (err .ne. NF90_ERANGE) &
+ call errore('Range error: ', err)
+ endif
+ else
+ if (err .ne. NF90_NOERR .and. err .ne. NF90_ERANGE) &
+ call errore('Range error: ', err)
+ endif
+ do 5, j = 1, var_nels(i)
+ if (inRange3(expect(j),var_type(i), &
+ NFT_ITYPE($1)) .and. &
+ in_internal_range(NFT_ITYPE($1), &
+ expect(j))) then
+ val = ARITH3($1, value, j)
+ if (.not. equal(val, expect(j), &
+ var_type(i), &
+ NFT_ITYPE($1))) then
+ call errord('unexpected: ', val)
+ else
+ nok = nok + 1
+ end if
+ endif
+5 continue
+ else
+ if (err .ne. NF90_ECHAR) &
+ call errore('wrong type: ', err)
+ end if
+1 continue
+ err = nf90mpi_close(ncid)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_close: ', err)
+ call print_nok(nok)
+ end
+])
+
+
+dnl TEST_NFMPI_GET_VARA(TYPE)
+dnl
+define([TEST_NFMPI_GET_VARA],[dnl
+ subroutine test_nf90mpi_get_vara_$1()
+ use pnetcdf
+ implicit none
+#include "tests.inc"
+ integer index2indexes, roll
+ double precision hash4
+ logical inrange3, in_internal_range, equal
+
+ integer ncid
+ integer d
+ integer i
+ integer j
+ integer k
+ integer err
+ logical allInExtRange
+ logical allInIntRange
+ integer(kind=MPI_OFFSET_KIND) nels
+ integer nslabs
+ integer nok
+ integer(kind=MPI_OFFSET_KIND) start(MAX_RANK)
+ integer(kind=MPI_OFFSET_KIND) edge(MAX_RANK)
+ integer(kind=MPI_OFFSET_KIND) index(MAX_RANK)
+ integer(kind=MPI_OFFSET_KIND) mid(MAX_RANK)
+ logical canConvert
+ DATATYPE($1, value, MAX_NELS)
+ doubleprecision expect(MAX_NELS)
+ doubleprecision val
+ integer ud_shift
+
+ nok = 0
+
+ err = nf90mpi_open(comm, testfile, NF90_NOWRITE, info, &
+ ncid)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_open: ', err)
+ do 1, i = 1, numVars
+ canConvert = (var_type(i) .eq. NF90_CHAR) .eqv. &
+ (NFT_ITYPE($1) .eq. NFT_TEXT)
+ if (.not.(var_rank(i) .le. MAX_RANK)) stop 'assert'
+ if (.not.(var_nels(i) .le. MAX_NELS)) stop 'assert'
+ do 2, j = 1, var_rank(i)
+ start(j) = 1
+ edge(j) = 1
+2 continue
+ err = nf90mpi_get_var_all(BAD_ID, i, value, start, &
+ edge)
+ if (err .ne. NF90_EBADID) &
+ call errore('bad ncid: ', err)
+ err = nf90mpi_get_var_all(ncid, BAD_VARID, value, start, &
+ edge)
+ if (err .ne. NF90_ENOTVAR) &
+ call errore('bad var id: ', err)
+ do 3, j = 1, var_rank(i)
+ start(j) = var_shape(j,i) + 1
+ err = nf90mpi_get_var_all(ncid, i, value, start, &
+ edge)
+ if (canConvert .and. err .ne. NF90_EINVALCOORDS) &
+ call errore('bad index: ', err)
+ start(j) = 1
+ edge(j) = var_shape(j,i) + 1
+ err = nf90mpi_get_var_all(ncid, i, value, start, &
+ edge)
+ if (canConvert .and. err .ne. NF90_EEDGE) &
+ call errore('bad edge: ', err)
+ edge(j) = 1
+3 continue
+
+! /* Check non-scalars for correct error returned even when */
+! /* there is nothing to get (edge(j).eq.0) */
+ if (var_rank(i) .gt. 0) then
+ do 10, j = 1, var_rank(i)
+ edge(j) = 0
+10 continue
+ err = nf90mpi_get_var_all(BAD_ID, i, value, start, &
+ edge)
+ if (err .ne. NF90_EBADID) &
+ call errore('bad ncid: ', err)
+ err = nf90mpi_get_var_all(ncid, BAD_VARID, value, &
+ start, edge)
+ if (err .ne. NF90_ENOTVAR) &
+ call errore('bad var id: ', err)
+ do 11, j = 1, var_rank(i)
+ if (var_dimid(j,i) .gt. 1) then !/* skip record dim */
+ start(j) = var_shape(j,i) + 1
+ err = nf90mpi_get_var_all(ncid, i, value, &
+ start, edge)
+ if (canConvert .and. err .ne. NF90_EINVALCOORDS) &
+ call errore('bad start: ', err)
+ start(j) = 1
+ endif
+11 continue
+ err = nf90mpi_get_var_all(ncid, i, value, start, &
+ edge)
+ if (canConvert) then
+ if (err .ne. NF90_NOERR) &
+ call error(nf90mpi_strerror(err))
+ else
+ if (err .ne. NF90_ECHAR) &
+ call errore('wrong type: ', err)
+ endif
+ do 12, j = 1, var_rank(i)
+ edge(j) = 1
+12 continue
+ endif
+
+! Choose a random point dividing each dim into 2 parts
+! get 2^rank (nslabs) slabs so defined
+ nslabs = 1
+ do 4, j = 1, var_rank(i)
+ mid(j) = roll( var_shape(j,i) )
+ nslabs = nslabs * 2
+4 continue
+! bits of k determine whether to get lower or upper part of dim
+ do 5, k = 1, nslabs
+ nels = 1
+ do 6, j = 1, var_rank(i)
+ if (mod(ud_shift((k-1), -(j-1)), 2) .eq. 1) then
+ start(j) = 1
+ edge(j) = mid(j)
+ else
+ start(j) = 1 + mid(j)
+ edge(j) = var_shape(j,i) - mid(j)
+ end if
+ nels = nels * edge(j)
+6 continue
+ allInIntRange = .true.
+ allInExtRange = .true.
+ do 7, j = 1, INT(nels)
+ err = index2indexes(j, var_rank(i), edge, index)
+ if (err .ne. NF90_NOERR) &
+ call error('error in index2indexes 1')
+ do 8, d = 1, var_rank(i)
+ index(d) = index(d) + start(d) - 1
+8 continue
+ expect(j) = hash4(var_type(i), var_rank(i), index, &
+ NFT_ITYPE($1))
+ if (inRange3(expect(j),var_type(i), &
+ NFT_ITYPE($1))) then
+ allInIntRange = &
+ allInIntRange .and. &
+ in_internal_range(NFT_ITYPE($1), expect(j))
+ else
+ allInExtRange = .false.
+ end if
+7 continue
+ err = nf90mpi_get_var_all(ncid, i, value, start, &
+ edge)
+ if (canConvert) then
+ if (allInExtRange) then
+ if (allInIntRange) then
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_get_var:', &
+ err)
+ else
+ if (err .ne. NF90_ERANGE) &
+ call errore('Range error: ', err)
+ end if
+ else
+ if (err .ne. NF90_NOERR .and. err .ne. NF90_ERANGE) &
+ call errore('OK or Range error: ', err)
+ end if
+ do 9, j = 1, INT(nels)
+ if (inRange3(expect(j),var_type(i), &
+ NFT_ITYPE($1)) .and. &
+ in_internal_range(NFT_ITYPE($1), expect(j))) &
+ then
+ val = ARITH3($1, value, j)
+ if (.not.equal(val,expect(j), &
+ var_type(i),NFT_ITYPE($1))) &
+ then
+ call error( &
+ 'value read not that expected')
+ if (verbose) then
+ call error(' ')
+ call errori('varid: ', i)
+ call errorc('var_name: ', &
+ var_name(i))
+ call errori('element number: %d ', &
+ j)
+ call errord('expect: ', expect(j))
+ call errord('got: ', val)
+ end if
+ else
+ nok = nok + 1
+ end if
+ end if
+9 continue
+ else
+ if (nels .gt. 0 .and. err .ne. NF90_ECHAR) &
+ call errore('wrong type: ', err)
+ end if
+5 continue
+1 continue
+ err = nf90mpi_close(ncid)
+ if (err .ne. NF90_NOERR) &
+ call errorc('nf90mpi_close: ', nf90mpi_strerror(err))
+ call print_nok(nok)
+ end
+])dnl
+
+
+dnl TEST_NFMPI_GET_VARS(TYPE)
+dnl
+define([TEST_NFMPI_GET_VARS],dnl
+[dnl
+ subroutine test_nf90mpi_get_vars_$1()
+ use pnetcdf
+ implicit none
+#include "tests.inc"
+ integer index2indexes, roll
+ double precision hash4
+ logical inrange3, in_internal_range, equal
+
+ integer ncid
+ integer d
+ integer i
+ integer j
+ integer k
+ integer m
+ integer err
+ logical allInExtRange
+ logical allInIntRange
+ integer(kind=MPI_OFFSET_KIND) nels
+ integer nslabs
+ integer(kind=MPI_OFFSET_KIND) nstarts
+ integer nok
+ integer(kind=MPI_OFFSET_KIND) start(MAX_RANK)
+ integer(kind=MPI_OFFSET_KIND) edge(MAX_RANK)
+ integer(kind=MPI_OFFSET_KIND) index(MAX_RANK)
+ integer(kind=MPI_OFFSET_KIND) index2(MAX_RANK)
+ integer(kind=MPI_OFFSET_KIND) mid(MAX_RANK)
+ integer(kind=MPI_OFFSET_KIND) count(MAX_RANK)
+ integer(kind=MPI_OFFSET_KIND) sstride(MAX_RANK)
+ integer(kind=MPI_OFFSET_KIND) stride(MAX_RANK)
+ logical canConvert
+ DATATYPE($1, value, MAX_NELS)
+ doubleprecision expect(MAX_NELS)
+ doubleprecision val
+ integer ud_shift
+
+ nok = 0
+
+ err = nf90mpi_open(comm, testfile, NF90_NOWRITE, info, &
+ ncid)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_open: ', err)
+ do 1, i = 1, numVars
+ canConvert = (var_type(i) .eq. NF90_CHAR) .eqv. &
+ (NFT_ITYPE($1) .eq. NFT_TEXT)
+ if (.not.(var_rank(i) .le. MAX_RANK)) stop 'assert'
+ if (.not.(var_nels(i) .le. MAX_NELS)) stop 'assert'
+ do 2, j = 1, var_rank(i)
+ start(j) = 1
+ edge(j) = 1
+ stride(j) = 1
+2 continue
+ err = nf90mpi_get_var_all(BAD_ID, i, value, start, &
+ edge, stride)
+ if (err .ne. NF90_EBADID) &
+ call errore('bad ncid: ', err)
+ err = nf90mpi_get_var_all(ncid, BAD_VARID, value, &
+ start, edge, stride)
+ if (err .ne. NF90_ENOTVAR) &
+ call errore('bad var id: ', err)
+ do 3, j = 1, var_rank(i)
+ start(j) = var_shape(j,i) + 1
+ err = nf90mpi_get_var_all(ncid, i, value, start, &
+ edge, stride)
+ if (.not. canConvert) then
+ if (err .ne. NF90_ECHAR) &
+ call errore('conversion: ', err)
+ else
+ if (err .ne. NF90_EINVALCOORDS) &
+ call errore('bad index: ', err)
+ endif
+ start(j) = 1
+ edge(j) = var_shape(j,i) + 1
+ err = nf90mpi_get_var_all(ncid, i, value, start, &
+ edge, stride)
+ if (.not. canConvert) then
+ if (err .ne. NF90_ECHAR) &
+ call errore('conversion: ', err)
+ else
+ if (err .ne. NF90_EEDGE) &
+ call errore('bad edge: ', err)
+ endif
+ edge(j) = 1
+ stride(j) = 0
+ err = nf90mpi_get_var_all(ncid, i, value, start, &
+ edge, stride)
+ if (.not. canConvert) then
+ if (err .ne. NF90_ECHAR) &
+ call errore('conversion: ', err)
+ else
+ if (err .ne. NF90_ESTRIDE) &
+ call errore('bad stride: ', err)
+ endif
+ stride(j) = 1
+3 continue
+! Choose a random point dividing each dim into 2 parts
+! get 2^rank (nslabs) slabs so defined
+ nslabs = 1
+ do 4, j = 1, var_rank(i)
+ mid(j) = roll( var_shape(j,i) )
+ nslabs = nslabs * 2
+4 continue
+! bits of k determine whether to get lower or upper part of dim
+! choose random stride from 1 to edge
+ do 5, k = 1, nslabs
+ nstarts = 1
+ do 6, j = 1, var_rank(i)
+ if (mod(ud_shift(k-1, j-1), 2) .eq. 1) then
+ start(j) = 1
+ edge(j) = mid(j)
+ else
+ start(j) = 1 + mid(j)
+ edge(j) = var_shape(j,i) - mid(j)
+ end if
+ if (edge(j) .gt. 0) then
+ sstride(j) = 1 + roll(edge(j))
+ else
+ sstride(j) = 1
+ end if
+ nstarts = nstarts * stride(j)
+6 continue
+ do 7, m = 1, INT(nstarts)
+ err = index2indexes(m, var_rank(i), sstride, &
+ index)
+ if (err .ne. NF90_NOERR) &
+ call error('error in index2indexes')
+ nels = 1
+ do 8, j = 1, var_rank(i)
+ count(j) = 1 + (edge(j) - index(j)) / &
+ stride(j)
+ nels = nels * count(j)
+ index(j) = index(j) + start(j) - 1
+8 continue
+! Random choice of forward or backward
+! /* TODO
+! if ( roll(2) ) then
+! for (j = 0 j < var_rank(i) j++) {
+! index(j) += (count(j) - 1) * stride(j)
+! stride(j) = -stride(j)
+! }
+! end if
+! */
+ allInIntRange = .true.
+ allInExtRange = .true.
+ do 9, j = 1, INT(nels)
+ err = index2indexes(j, var_rank(i), count, &
+ index2)
+ if (err .ne. NF90_NOERR) &
+ call error('error in index2indexes() 1')
+ do 10, d = 1, var_rank(i)
+ index2(d) = index(d) + (index2(d)-1) * &
+ stride(d)
+10 continue
+ expect(j) = hash4(var_type(i), var_rank(i), &
+ index2, NFT_ITYPE($1))
+ if (inRange3(expect(j),var_type(i), &
+ NFT_ITYPE($1))) then
+ allInIntRange = &
+ allInIntRange .and. &
+ in_internal_range(NFT_ITYPE($1), &
+ expect(j))
+ else
+ allInExtRange = .false.
+ end if
+9 continue
+ err = nf90mpi_get_var_all(ncid, i, value, index, &
+ count, stride)
+ if (canConvert) then
+ if (allInExtRange) then
+ if (allInIntRange) then
+ if (err .ne. NF90_NOERR) &
+ call error(nf90mpi_strerror(err))
+ else
+ if (err .ne. NF90_ERANGE) &
+ call errore('Range error: ', err)
+ end if
+ else
+ if (err .ne. NF90_NOERR .and. &
+ err .ne. NF90_ERANGE) &
+ call errore('OK or Range error: ', err)
+ end if
+ do 11, j = 1, INT(nels)
+ if (inRange3(expect(j),var_type(i), &
+ NFT_ITYPE($1)) .and. &
+ in_internal_range(NFT_ITYPE($1), &
+ expect(j))) then
+ val = ARITH3($1, value, j)
+ if (.not.equal(val, expect(j), &
+ var_type(i), NFT_ITYPE($1))) then
+ call error( &
+ 'value read not that expected')
+ if (verbose) then
+ call error(' ')
+ call errori('varid: ', i)
+ call errorc('var_name: ', &
+ var_name(i))
+ call errori('element number: ', &
+ j)
+ call errord('expect: ', &
+ expect(j))
+ call errord('got: ', val)
+ end if
+ else
+ nok = nok + 1
+ end if
+ end if
+11 continue
+ else
+ if (nels .gt. 0 .and. err .ne. NF90_ECHAR) &
+ call errore('wrong type: ', err)
+ end if
+7 continue
+5 continue
+
+1 continue
+ err = nf90mpi_close(ncid)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_close: ', err)
+ call print_nok(nok)
+ end
+])dnl
+
+
+dnl TEST_NFMPI_GET_VARM(TYPE)
+dnl
+define([TEST_NFMPI_GET_VARM],dnl
+[dnl
+ subroutine test_nf90mpi_get_varm_$1()
+ use pnetcdf
+ implicit none
+#include "tests.inc"
+ integer index2indexes, roll
+ double precision hash4
+ logical inrange3, in_internal_range, equal
+
+ integer ncid
+ integer d
+ integer i
+ integer j
+ integer k
+ integer m
+ integer err
+ logical allInExtRange
+ logical allInIntRange
+ integer(kind=MPI_OFFSET_KIND) nels
+ integer nslabs
+ integer(kind=MPI_OFFSET_KIND) nstarts
+ integer nok
+ integer(kind=MPI_OFFSET_KIND) start(MAX_RANK)
+ integer(kind=MPI_OFFSET_KIND) edge(MAX_RANK)
+ integer(kind=MPI_OFFSET_KIND) index(MAX_RANK)
+ integer(kind=MPI_OFFSET_KIND) index2(MAX_RANK)
+ integer(kind=MPI_OFFSET_KIND) mid(MAX_RANK)
+ integer(kind=MPI_OFFSET_KIND) count(MAX_RANK)
+ integer(kind=MPI_OFFSET_KIND) sstride(MAX_RANK)
+ integer(kind=MPI_OFFSET_KIND) stride(MAX_RANK)
+ integer(kind=MPI_OFFSET_KIND) imap(MAX_RANK)
+ logical canConvert
+ DATATYPE($1, value, MAX_NELS)
+ doubleprecision expect(MAX_NELS)
+ doubleprecision val
+ integer ud_shift
+
+ nok = 0
+
+ err = nf90mpi_open(comm, testfile, NF90_NOWRITE, info, &
+ ncid)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_open: ', err)
+ do 1, i = 1, numVars
+ canConvert = (var_type(i) .eq. NF90_CHAR) .eqv. &
+ (NFT_ITYPE($1) .eq. NFT_TEXT)
+ if (.not.(var_rank(i) .le. MAX_RANK)) stop 'assertion'
+ if (.not.(var_nels(i) .le. MAX_NELS)) stop 'assertion'
+ do 2, j = 1, var_rank(i)
+ start(j) = 1
+ edge(j) = 1
+ stride(j) = 1
+ imap(j) = 1
+2 continue
+ err = nf90mpi_get_var_all(BAD_ID, i, value, start, edge, &
+ stride, imap)
+ if (err .ne. NF90_EBADID) &
+ call errore('bad ncid: ', err)
+ err = nf90mpi_get_var_all(ncid, BAD_VARID, value, start, &
+ edge, stride, imap)
+ if (err .ne. NF90_ENOTVAR) &
+ call errore('bad var id: ', err)
+ do 3, j = 1, var_rank(i)
+ start(j) = var_shape(j,i) + 1
+ err = nf90mpi_get_var_all(ncid, i, value, start, &
+ edge, stride, imap)
+ if (.not. canConvert) then
+ if (err .ne. NF90_ECHAR) &
+ call errore('conversion: ', err)
+ else
+ if (err .ne. NF90_EINVALCOORDS) &
+ call errore('bad index: ', err)
+ endif
+ start(j) = 1
+ edge(j) = var_shape(j,i) + 1
+ err = nf90mpi_get_var_all(ncid, i, value, start, &
+ edge, stride, imap)
+ if (.not. canConvert) then
+ if (err .ne. NF90_ECHAR) &
+ call errore('conversion: ', err)
+ else
+ if (err .ne. NF90_EEDGE) &
+ call errore('bad edge: ', err)
+ endif
+ edge(j) = 1
+ stride(j) = 0
+ err = nf90mpi_get_var_all(ncid, i, value, start, &
+ edge, stride, imap)
+ if (.not. canConvert) then
+ if (err .ne. NF90_ECHAR) &
+ call errore('conversion: ', err)
+ else
+ if (err .ne. NF90_ESTRIDE) &
+ call errore('bad stride: ', err)
+ endif
+ stride(j) = 1
+3 continue
+! Choose a random point dividing each dim into 2 parts
+! get 2^rank (nslabs) slabs so defined
+ nslabs = 1
+ do 4, j = 1, var_rank(i)
+ mid(j) = roll( var_shape(j,i) )
+ nslabs = nslabs * 2
+4 continue
+! /* bits of k determine whether to get lower or upper part
+! * of dim
+! * choose random stride from 1 to edge */
+ do 5, k = 1, nslabs
+ nstarts = 1
+ do 6, j = 1, var_rank(i)
+ if (mod(ud_shift((k-1), -(j-1)), 2) .ne. 0) then
+ start(j) = 1
+ edge(j) = mid(j)
+ else
+ start(j) = 1 + mid(j)
+ edge(j) = var_shape(j,i) - mid(j)
+ end if
+ if (edge(j) .gt. 0) then
+ stride(j) = 1+roll(edge(j))
+ else
+ stride(j) = 1
+ end if
+ sstride(j) = stride(j)
+ nstarts = nstarts * stride(j)
+6 continue
+ do 7, m = 1, INT(nstarts)
+ err = index2indexes(m, var_rank(i), sstride, index)
+ if (err .ne. NF90_NOERR) &
+ call error('error in index2indexes')
+ nels = 1
+ do 8, j = 1, var_rank(i)
+ count(j) = 1 + (edge(j) - index(j)) / &
+ stride(j)
+ nels = nels * count(j)
+ index(j) = index(j) + start(j) - 1
+8 continue
+! Random choice of forward or backward
+! /* TODO
+! if ( roll(2) ) then
+! for (j = 0 j < var_rank(i) j++) {
+! index(j) += (count(j) - 1) * stride(j)
+! stride(j) = -stride(j)
+! }
+! end if
+! */
+ if (var_rank(i) .gt. 0) then
+ imap(1) = 1
+ do 9, j = 2, var_rank(i)
+ imap(j) = imap(j-1) * count(j-1)
+9 continue
+ end if
+ allInIntRange = .true.
+ allInExtRange = .true.
+ do 10, j = 1, INT(nels)
+ err = index2indexes(j, var_rank(i), count, &
+ index2)
+ if (err .ne. NF90_NOERR) &
+ call error('error in index2indexes 1')
+ do 11, d = 1, var_rank(i)
+ index2(d) = index(d) + (index2(d)-1) * &
+ stride(d)
+11 continue
+ expect(j) = hash4(var_type(i), var_rank(i), &
+ index2, NFT_ITYPE($1))
+ if (inRange3(expect(j),var_type(i), &
+ NFT_ITYPE($1))) then
+ allInIntRange = &
+ allInIntRange .and. &
+ in_internal_range(NFT_ITYPE($1), &
+ expect(j))
+ else
+ allInExtRange = .false.
+ end if
+10 continue
+ err = nf90mpi_get_var_all(ncid,i,value,index,count, &
+ stride,imap)
+ if (canConvert) then
+ if (allInExtRange) then
+ if (allInIntRange) then
+ if (err .ne. NF90_NOERR) &
+ call error(nf90mpi_strerror(err))
+ else
+ if (err .ne. NF90_ERANGE) &
+ call errore('Range error: ', err)
+ end if
+ else
+ if (err .ne. NF90_NOERR .and. &
+ err .ne. NF90_ERANGE) &
+ call errore('OK or Range error: ', err)
+ end if
+ do 12, j = 1, INT(nels)
+ if (inRange3(expect(j),var_type(i), &
+ NFT_ITYPE($1)) .and. &
+ in_internal_range(NFT_ITYPE($1), &
+ expect(j))) then
+ val = ARITH3($1, value, j)
+ if (.not.equal(val, expect(j), &
+ var_type(i), &
+ NFT_ITYPE($1))) then
+ call error( &
+ 'value read not that expected')
+ if (verbose) then
+ call error(' ')
+ call errori('varid: ', i)
+ call errorc('var_name: ', &
+ var_name(i))
+ call errori('element number: ', &
+ j)
+ call errord('expect: ', &
+ expect(j))
+ call errord('got: ', val)
+ end if
+ else
+ nok = nok + 1
+ end if
+ end if
+12 continue
+ else
+ if (nels .gt. 0 .and. err .ne. NF90_ECHAR) &
+ call errore('wrong type: ', err)
+ end if
+7 continue
+5 continue
+1 continue
+ err = nf90mpi_close(ncid)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_close: ', err)
+ call print_nok(nok)
+ end
+])dnl
+
+
+dnl TEST_NFMPI_GET_ATT(TYPE)
+dnl
+define([TEST_NFMPI_GET_ATT],dnl
+[dnl
+ subroutine test_nf90mpi_get_att_$1()
+ use pnetcdf
+ implicit none
+#include "tests.inc"
+ character*2 ATT_NAME
+ integer ATT_TYPE, NATTS, ATT_LEN
+ double precision hash4
+ logical equal, inRange3, in_internal_range
+
+ integer ncid
+ integer i
+ integer j
+ integer k
+ integer err
+ integer(kind=MPI_OFFSET_KIND) ndx(1)
+ logical allInExtRange
+ logical allInIntRange
+ logical canConvert
+ ATTDATATYPE($1, value, MAX_NELS)
+ doubleprecision expect(MAX_NELS)
+ integer nok
+ doubleprecision val
+
+ nok = 0
+
+ err = nf90mpi_open(comm, testfile, NF90_NOWRITE, info, &
+ ncid)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_open: ', err)
+
+ do 1, i = 0, numVars
+ do 2, j = 1, NATTS(i)
+ canConvert = (ATT_TYPE(j,i) .eq. NF90_CHAR) .eqv. &
+ (NFT_ITYPE($1) .eq. NFT_TEXT)
+ err = nf90mpi_get_att(BAD_ID, i, ATT_NAME(j,i), value)
+ if (err .ne. NF90_EBADID) &
+ call errore('bad ncid: ', err)
+ err = nf90mpi_get_att(ncid, BAD_VARID, ATT_NAME(j,i), value)
+ if (err .ne. NF90_ENOTVAR) &
+ call errore('bad var id: ', err)
+ err = nf90mpi_get_att(ncid, i, 'noSuch', value)
+ if (err .ne. NF90_ENOTATT) &
+ call errore('Bad attribute name: ', err)
+ allInIntRange = .true.
+ allInExtRange = .true.
+ do 3, k = 1, ATT_LEN(j,i)
+ ndx(1) = k
+ expect(k) = hash4(ATT_TYPE(j,i), -1, ndx, &
+ NFT_ITYPE($1))
+ if (inRange3(expect(k),ATT_TYPE(j,i), &
+ NFT_ITYPE($1))) then
+ allInIntRange = &
+ allInIntRange .and. &
+ in_internal_range(NFT_ITYPE($1), expect(k))
+ else
+ allInExtRange = .false.
+ end if
+3 continue
+ err = nf90mpi_get_att(ncid, i, ATT_NAME(j,i), value)
+ if (canConvert .or. ATT_LEN(j,i) .eq. 0) then
+ if (allInExtRange) then
+ if (allInIntRange) then
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_get_att ', &
+ err)
+ else
+ if (err .ne. NF90_ERANGE) &
+ call errore('Range error: ', err)
+ end if
+ else
+ if (err .ne. NF90_NOERR .and. err .ne. NF90_ERANGE) &
+ call errore('OK or Range error: ', &
+ err)
+ end if
+ do 4, k = 1, ATT_LEN(j,i)
+ if (inRange3(expect(k),ATT_TYPE(j,i), &
+ NFT_ITYPE($1)) .and. &
+ in_internal_range(NFT_ITYPE($1), &
+ expect(k))) then
+ val = ATTARITH3($1, value, k)
+ if (.not.equal(val, expect(k), &
+ ATT_TYPE(j,i), &
+ NFT_ITYPE($1)))then
+ call error( &
+ 'value read not that expected')
+ if (verbose) then
+ call error(' ')
+ call errori('varid: ', i)
+ call errorc('att_name: ', &
+ ATT_NAME(j,i))
+ call errori('element number: ', k)
+ call errord('expect: ', expect(k))
+ call errord('got: ', val)
+ end if
+ else
+ nok = nok + 1
+ end if
+ end if
+4 continue
+ else
+ if (err .ne. NF90_ECHAR) &
+ call errore('wrong type: ', err)
+ end if
+2 continue
+1 continue
+
+ err = nf90mpi_close(ncid)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_close: ', err)
+ call print_nok(nok)
+ end
+])dnl
+
+divert(0)dnl
+dnl If you see this line, you can ignore the next one.
+! Do not edit this file. It is produced from the corresponding .m4 source */
+
+!
+! Copyright (C) 2013, Northwestern University and Argonne National Laboratory
+! See COPYRIGHT notice in top-level directory.
+!
+
+TEST_NFMPI_GET_VAR1(text)
+#ifdef NF_INT1_T
+TEST_NFMPI_GET_VAR1(int1)
+#endif
+#ifdef NF_INT2_T
+TEST_NFMPI_GET_VAR1(int2)
+#endif
+TEST_NFMPI_GET_VAR1(int)
+TEST_NFMPI_GET_VAR1(int8)
+TEST_NFMPI_GET_VAR1(real)
+TEST_NFMPI_GET_VAR1(double)
+
+TEST_NFMPI_GET_VAR(text)
+#ifdef NF_INT1_T
+TEST_NFMPI_GET_VAR(int1)
+#endif
+#ifdef NF_INT2_T
+TEST_NFMPI_GET_VAR(int2)
+#endif
+TEST_NFMPI_GET_VAR(int)
+TEST_NFMPI_GET_VAR(int8)
+TEST_NFMPI_GET_VAR(real)
+TEST_NFMPI_GET_VAR(double)
+
+TEST_NFMPI_GET_VARA(text)
+#ifdef NF_INT1_T
+TEST_NFMPI_GET_VARA(int1)
+#endif
+#ifdef NF_INT2_T
+TEST_NFMPI_GET_VARA(int2)
+#endif
+TEST_NFMPI_GET_VARA(int)
+TEST_NFMPI_GET_VARA(int8)
+TEST_NFMPI_GET_VARA(real)
+TEST_NFMPI_GET_VARA(double)
+
+TEST_NFMPI_GET_VARS(text)
+#ifdef NF_INT1_T
+TEST_NFMPI_GET_VARS(int1)
+#endif
+#ifdef NF_INT2_T
+TEST_NFMPI_GET_VARS(int2)
+#endif
+TEST_NFMPI_GET_VARS(int)
+TEST_NFMPI_GET_VARS(int8)
+TEST_NFMPI_GET_VARS(real)
+TEST_NFMPI_GET_VARS(double)
+
+TEST_NFMPI_GET_VARM(text)
+#ifdef NF_INT1_T
+TEST_NFMPI_GET_VARM(int1)
+#endif
+#ifdef NF_INT2_T
+TEST_NFMPI_GET_VARM(int2)
+#endif
+TEST_NFMPI_GET_VARM(int)
+TEST_NFMPI_GET_VARM(int8)
+TEST_NFMPI_GET_VARM(real)
+TEST_NFMPI_GET_VARM(double)
+
+TEST_NFMPI_GET_ATT(text)
+#ifdef NF_INT1_T
+TEST_NFMPI_GET_ATT(int1)
+#endif
+#ifdef NF_INT2_T
+TEST_NFMPI_GET_ATT(int2)
+#endif
+TEST_NFMPI_GET_ATT(int)
+TEST_NFMPI_GET_ATT(int8)
+TEST_NFMPI_GET_ATT(real)
+TEST_NFMPI_GET_ATT(double)
diff --git a/test/nf90_test/test_iget.m4 b/test/nf90_test/test_iget.m4
new file mode 100644
index 0000000..1bed4ef
--- /dev/null
+++ b/test/nf90_test/test_iget.m4
@@ -0,0 +1,1018 @@
+dnl
+dnl Copyright (C) 2013, Northwestern University and Argonne National Laboratory
+dnl See COPYRIGHT notice in top-level directory.
+dnl
+dnl $Id: test_iget.m4 2081 2015-08-20 01:00:47Z wkliao $
+dnl
+
+divert(-1)
+
+dnl This is m4 source.
+dnl Process using m4 to produce FORTRAN language file.
+
+changequote([,])
+
+undefine([index])dnl
+
+dnl Macros
+
+dnl Upcase(str)
+dnl
+define([Upcase],[dnl
+translit($1, abcdefghijklmnopqrstuvwxyz, ABCDEFGHIJKLMNOPQRSTUVWXYZ)])
+
+dnl NFT_ITYPE(type)
+dnl
+define([NFT_ITYPE], [NFT_[]Upcase($1)])
+
+dnl ARITH_VAR1(itype, value)
+dnl
+define([ARITH_VAR1], [ifelse($1, text, ichar($2), $2)])
+
+dnl ARITH3(itype, value)
+dnl
+define([ARITH3], [ifelse($1, text, ichar($2($3:$3)), $2($3))])
+
+dnl DATATYPE(funf_suffix)
+dnl
+define([DATATYPE], [dnl
+ifelse($1, text, character(len=MAX_NELS) $2,
+ifelse($1, int1, NF_INT1_T $2$3,
+ifelse($1, int2, NF_INT2_T $2$3,
+ifelse($1, int, integer $2$3,
+ifelse($1, int8, NF_INT8_T $2$3,
+ifelse($1, real, real $2$3,
+ifelse($1, double, doubleprecision $2$3)[]dnl
+)[]dnl
+)[]dnl
+)[]dnl
+)[]dnl
+)[]dnl
+)[]dnl
+])
+
+dnl DATATYPE_VAR1(funf_suffix)
+dnl
+define([DATATYPE_VAR1], [dnl
+ifelse($1, text, character $2,
+ifelse($1, int1, NF_INT1_T $2,
+ifelse($1, int2, NF_INT2_T $2,
+ifelse($1, int, integer $2,
+ifelse($1, int8, NF_INT8_T $2,
+ifelse($1, real, real $2,
+ifelse($1, double, doubleprecision $2)[]dnl
+)[]dnl
+)[]dnl
+)[]dnl
+)[]dnl
+)[]dnl
+)[]dnl
+])
+
+dnl TEST_NFMPI_IGET_VAR1(TYPE)
+dnl
+define([TEST_NFMPI_IGET_VAR1],[dnl
+ subroutine test_nf90mpi_iget_var1_$1()
+ use pnetcdf
+ implicit none
+#include "tests.inc"
+ integer index2indexes
+ double precision hash4
+ logical equal, inRange3, in_internal_range
+
+ integer ncid
+ integer i
+ integer j
+ integer err
+ integer nok
+ integer(kind=MPI_OFFSET_KIND) index(MAX_RANK)
+ doubleprecision expect
+ logical canConvert
+ DATATYPE_VAR1($1, value)
+ doubleprecision val
+ integer err_w, reqid(1), st(1)
+
+ nok = 0
+
+ err = nf90mpi_open(comm, testfile, NF90_NOWRITE, info, &
+ ncid)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_open: ', err)
+ do 1, i = 1, numVars
+ canConvert = (var_type(i) .eq. NF90_CHAR) .eqv. &
+ (NFT_ITYPE($1) .eq. NFT_TEXT)
+ do 2, j = 1, var_rank(i)
+ index(j) = 1
+2 continue
+ err = nf90mpi_iget_var(BAD_ID,i,value, reqid(1),index)
+ if (err .ne. NF90_EBADID) &
+ call errore('bad ncid: ', err)
+ err = nf90mpi_iget_var(ncid,BAD_VARID, value, reqid(1), index)
+ if (err .ne. NF90_ENOTVAR) &
+ call errore('bad var id: ', err)
+ do 3, j = 1, var_rank(i)
+ index(j) = var_shape(j,i) + 1
+ err = nf90mpi_iget_var(ncid,i,value, reqid(1),index)
+ if (err .eq. NF90_NOERR .or. err .eq. NF90_ERANGE) &
+ err_w = nf90mpi_wait_all(ncid,1,reqid,st)
+ if (.not. canConvert) then
+ if (err .ne. NF90_ECHAR) &
+ call errore('conversion: ', err)
+ else
+ if (err .ne. NF90_EINVALCOORDS) &
+ call errore('bad index: ', err)
+ endif
+ index(j) = 1
+3 continue
+ do 4, j = 1, var_nels(i)
+ err = index2indexes(j, var_rank(i), var_shape(1,i), &
+ index)
+ if (err .ne. NF90_NOERR) &
+ call error('error in index2indexes 1')
+ expect = hash4( var_type(i), var_rank(i), index, &
+ NFT_ITYPE($1) )
+ err = nf90mpi_iget_var(ncid,i,value, reqid(1),index)
+ if (err .eq. NF90_NOERR .or. err .eq. NF90_ERANGE) &
+ err_w = nf90mpi_wait_all(ncid,1,reqid,st)
+ if (canConvert) then
+ if (inRange3(expect,var_type(i), &
+ NFT_ITYPE($1))) then
+ if (in_internal_range(NFT_ITYPE($1), &
+ expect)) then
+ if (st(1) .ne. 0) then
+ call errore('nf90mpi_iget_var: ',st(1))
+ else
+ val = ARITH_VAR1($1, value)
+ if (.not. equal(val, expect, &
+ var_type(i), &
+ NFT_ITYPE($1))) then
+ call errord('unexpected: ', val)
+ else
+ nok = nok + 1
+ end if
+ end if
+ else
+ if (st(1) .ne. NF90_ERANGE) &
+ call errore('Range error: ', st(1))
+ end if
+ else
+ if (st(1) .ne. 0 .and. st(1) .ne. NF90_ERANGE) &
+ call errore('OK or Range error: ', st(1))
+ end if
+ else
+ if (err .ne. NF90_ECHAR) &
+ call errore('wrong type: ', err)
+ end if
+4 continue
+1 continue
+ err = nf90mpi_close(ncid)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_close: ', err)
+ call print_nok(nok)
+ end
+])
+
+dnl TEST_NFMPI_IGET_VAR(TYPE)
+dnl
+define([TEST_NFMPI_IGET_VAR],[dnl
+ subroutine test_nf90mpi_iget_var_$1()
+ use pnetcdf
+ implicit none
+#include "tests.inc"
+ integer index2indexes
+ double precision hash4
+ logical equal, inRange3, in_internal_range
+
+ integer ncid
+ integer i
+ integer j
+ integer err
+ logical allInExtRange
+ logical allInIntRange
+ integer(kind=MPI_OFFSET_KIND) nels
+ integer nok
+ integer(kind=MPI_OFFSET_KIND) index(MAX_RANK)
+ doubleprecision expect(MAX_NELS)
+ logical canConvert
+ DATATYPE($1, value, (MAX_NELS))
+ doubleprecision val
+ integer err_w, reqid(1), st(1)
+
+ nok = 0
+
+ err = nf90mpi_open(comm, testfile, NF90_NOWRITE, info, &
+ ncid)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_open: ', err)
+ do 1, i = 1, numVars
+ canConvert = (var_type(i) .eq. NF90_CHAR) .eqv. &
+ (NFT_ITYPE($1) .eq. NFT_TEXT)
+ err = nf90mpi_iget_var(BAD_ID, i, value,reqid(1))
+ if (err .ne. NF90_EBADID) &
+ call errore('bad ncid: ', err)
+ err = nf90mpi_iget_var(ncid, BAD_VARID, value,reqid(1))
+ if (err .ne. NF90_ENOTVAR) &
+ call errore('bad var id: ', err)
+ nels = 1
+ do 3, j = 1, var_rank(i)
+ nels = nels * var_shape(j,i)
+3 continue
+ allInExtRange = .true.
+ allInIntRange = .true.
+ do 4, j = 1, var_nels(i)
+ err = index2indexes(j, var_rank(i), var_shape(1,i), &
+ index)
+ if (err .ne. NF90_NOERR) &
+ call error('error in index2indexes 1')
+ expect(j) = hash4( var_type(i), var_rank(i), index, &
+ NFT_ITYPE($1) )
+ if (inRange3(expect(j),var_type(i), NFT_ITYPE($1))) then
+ allInIntRange = allInIntRange .and. &
+ in_internal_range(NFT_ITYPE($1), expect(j))
+ else
+ allInExtRange = .false.
+ end if
+4 continue
+ err = nf90mpi_iget_var(ncid, i, value,reqid(1), count=var_shape(:,i))
+ if (err .eq. NF90_NOERR .or. err .eq. NF90_ERANGE) &
+ err_w = nf90mpi_wait_all(ncid,1,reqid,st)
+ if (canConvert) then
+ if (allInExtRange) then
+ if (allInIntRange) then
+ if (st(1) .ne. 0) &
+ call errore('nf90mpi_iget_var: ', st(1))
+ else
+ if (st(1) .ne. NF90_ERANGE) &
+ call errore('Range error: ', st(1))
+ endif
+ else
+ if (st(1) .ne. 0 .and. st(1) .ne. NF90_ERANGE) &
+ call errore('Range error: ', st(1))
+ endif
+ do 5, j = 1, var_nels(i)
+ if (inRange3(expect(j),var_type(i), &
+ NFT_ITYPE($1)) .and. &
+ in_internal_range(NFT_ITYPE($1), &
+ expect(j))) then
+ val = ARITH3($1, value, j)
+ if (.not. equal(val, expect(j), &
+ var_type(i), &
+ NFT_ITYPE($1))) then
+ call errord('unexpected: ', val)
+ else
+ nok = nok + 1
+ end if
+ endif
+5 continue
+ else
+ if (err .ne. NF90_ECHAR) &
+ call errore('wrong type: ', err)
+ end if
+1 continue
+ err = nf90mpi_close(ncid)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_close: ', err)
+ call print_nok(nok)
+ end
+])
+
+
+dnl TEST_NFMPI_IGET_VARA(TYPE)
+dnl
+define([TEST_NFMPI_IGET_VARA],[dnl
+ subroutine test_nf90mpi_iget_vara_$1()
+ use pnetcdf
+ implicit none
+#include "tests.inc"
+ integer roll, index2indexes
+ double precision hash4
+ logical equal, inRange3, in_internal_range
+
+ integer ncid
+ integer d
+ integer i
+ integer j
+ integer k
+ integer err
+ logical allInExtRange
+ logical allInIntRange
+ integer(kind=MPI_OFFSET_KIND) nels
+ integer nslabs
+ integer nok
+ integer(kind=MPI_OFFSET_KIND) start(MAX_RANK)
+ integer(kind=MPI_OFFSET_KIND) edge(MAX_RANK)
+ integer(kind=MPI_OFFSET_KIND) index(MAX_RANK)
+ integer(kind=MPI_OFFSET_KIND) mid(MAX_RANK)
+ logical canConvert
+ DATATYPE($1, value, (MAX_NELS))
+ doubleprecision expect(MAX_NELS)
+ doubleprecision val
+ integer ud_shift
+ integer err_w, reqid(1), st(1)
+
+ nok = 0
+
+ err = nf90mpi_open(comm, testfile, NF90_NOWRITE, info, &
+ ncid)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_open: ', err)
+ do 1, i = 1, numVars
+ canConvert = (var_type(i) .eq. NF90_CHAR) .eqv. &
+ (NFT_ITYPE($1) .eq. NFT_TEXT)
+ if (.not.(var_rank(i) .le. MAX_RANK)) stop 'assert'
+ if (.not.(var_nels(i) .le. MAX_NELS)) stop 'assert'
+ do 2, j = 1, var_rank(i)
+ start(j) = 1
+ edge(j) = 1
+2 continue
+ err = nf90mpi_iget_var(BAD_ID, i, value,reqid(1), start, edge)
+ if (err .ne. NF90_EBADID) &
+ call errore('bad ncid: ', err)
+ err = nf90mpi_iget_var(ncid, BAD_VARID, value,reqid(1), start, edge)
+ if (err .ne. NF90_ENOTVAR) &
+ call errore('bad var id: ', err)
+ do 3, j = 1, var_rank(i)
+ start(j) = var_shape(j,i) + 1
+ err = nf90mpi_iget_var(ncid, i, value,reqid(1), start, edge)
+ if (err .eq. NF90_NOERR .or. err .eq. NF90_ERANGE) &
+ err_w = nf90mpi_wait_all(ncid,1,reqid,st)
+ if (canConvert .and. err .ne. NF90_EINVALCOORDS) &
+ call errore('bad index: ', err)
+ start(j) = 1
+ edge(j) = var_shape(j,i) + 1
+ err = nf90mpi_iget_var(ncid, i, value,reqid(1), start, edge)
+ if (err .eq. NF90_NOERR .or. err .eq. NF90_ERANGE) &
+ err_w = nf90mpi_wait_all(ncid,1,reqid,st)
+ if (canConvert .and. err .ne. NF90_EEDGE) &
+ call errore('bad edge: ', err)
+ edge(j) = 1
+3 continue
+
+! /* Check non-scalars for correct error returned even when */
+! /* there is nothing to get (edge(j).eq.0) */
+ if (var_rank(i) .gt. 0) then
+ do 10, j = 1, var_rank(i)
+ edge(j) = 0
+10 continue
+ err = nf90mpi_iget_var(BAD_ID, i, value,reqid(1), start, edge)
+ if (err .ne. NF90_EBADID) &
+ call errore('bad ncid: ', err)
+ err = nf90mpi_iget_var(ncid, BAD_VARID, value,reqid(1), start, edge)
+ if (err .ne. NF90_ENOTVAR) &
+ call errore('bad var id: ', err)
+ do 11, j = 1, var_rank(i)
+ if (var_dimid(j,i) .gt. 1) then !/* skip record dim */
+ start(j) = var_shape(j,i) + 1
+ err = nf90mpi_iget_var(ncid, i, value,reqid(1), start, edge)
+ if (err .eq. NF90_NOERR .or. err .eq. NF90_ERANGE) &
+ err_w = nf90mpi_wait_all(ncid,1,reqid,st)
+ if (canConvert .and. err .ne. NF90_EINVALCOORDS) &
+ call errore('bad start: ', err)
+ start(j) = 1
+ endif
+11 continue
+ err = nf90mpi_iget_var(ncid, i, value,reqid(1), start, edge)
+ if (err .eq. NF90_NOERR .or. err .eq. NF90_ERANGE) &
+ err_w = nf90mpi_wait_all(ncid,1,reqid,st)
+ if (canConvert) then
+ if (err .ne. NF90_NOERR) &
+ call error(nf90mpi_strerror(err))
+ else
+ if (err .ne. NF90_ECHAR) &
+ call errore('wrong type: ', err)
+ endif
+ do 12, j = 1, var_rank(i)
+ edge(j) = 1
+12 continue
+ endif
+
+! Choose a random point dividing each dim into 2 parts
+! get 2^rank (nslabs) slabs so defined
+ nslabs = 1
+ do 4, j = 1, var_rank(i)
+ mid(j) = roll( var_shape(j,i) )
+ nslabs = nslabs * 2
+4 continue
+! bits of k determine whether to get lower or upper part of dim
+ do 5, k = 1, nslabs
+ nels = 1
+ do 6, j = 1, var_rank(i)
+ if (mod(ud_shift((k-1), -(j-1)), 2) .eq. 1) then
+ start(j) = 1
+ edge(j) = mid(j)
+ else
+ start(j) = 1 + mid(j)
+ edge(j) = var_shape(j,i) - mid(j)
+ end if
+ nels = nels * edge(j)
+6 continue
+ allInIntRange = .true.
+ allInExtRange = .true.
+ do 7, j = 1, INT(nels)
+ err = index2indexes(j, var_rank(i), edge, index)
+ if (err .ne. NF90_NOERR) &
+ call error('error in index2indexes 1')
+ do 8, d = 1, var_rank(i)
+ index(d) = index(d) + start(d) - 1
+8 continue
+ expect(j) = hash4(var_type(i), var_rank(i), index, &
+ NFT_ITYPE($1))
+ if (inRange3(expect(j),var_type(i), &
+ NFT_ITYPE($1))) then
+ allInIntRange = &
+ allInIntRange .and. &
+ in_internal_range(NFT_ITYPE($1), expect(j))
+ else
+ allInExtRange = .false.
+ end if
+7 continue
+ err = nf90mpi_iget_var(ncid, i, value,reqid(1), start, edge)
+ if (err .eq. NF90_NOERR .or. err .eq. NF90_ERANGE) &
+ err_w = nf90mpi_wait_all(ncid,1,reqid,st)
+ if (canConvert) then
+ if (allInExtRange) then
+ if (allInIntRange) then
+ if (st(1) .ne. 0) &
+ call errore( &
+ 'nf90mpi_iget_var:',st(1))
+ else
+ if (st(1) .ne. NF90_ERANGE) &
+ call errore('Range error: ', st(1))
+ end if
+ else
+ if (st(1) .ne. 0 .and. st(1) .ne. NF90_ERANGE) &
+ call errore('OK or Range error: ', st(1))
+ end if
+ do 9, j = 1, INT(nels)
+ if (inRange3(expect(j),var_type(i), &
+ NFT_ITYPE($1)) .and. &
+ in_internal_range(NFT_ITYPE($1), expect(j))) &
+ then
+ val = ARITH3($1, value, j)
+ if (.not.equal(val,expect(j), &
+ var_type(i),NFT_ITYPE($1))) &
+ then
+ call error( &
+ 'value read not that expected')
+ if (verbose) then
+ call error(' ')
+ call errori('varid: ', i)
+ call errorc('var_name: ', &
+ var_name(i))
+ call errori('element number: %d ', &
+ j)
+ call errord('expect: ', expect(j))
+ call errord('got: ', val)
+ end if
+ else
+ nok = nok + 1
+ end if
+ end if
+9 continue
+ else
+ if (nels .gt. 0 .and. err .ne. NF90_ECHAR) &
+ call errore('wrong type: ', err)
+ end if
+5 continue
+1 continue
+ err = nf90mpi_close(ncid)
+ if (err .ne. NF90_NOERR) &
+ call errorc('nf90mpi_close: ', nf90mpi_strerror(err))
+ call print_nok(nok)
+ end
+])dnl
+
+
+dnl TEST_NFMPI_IGET_VARS(TYPE)
+dnl
+define([TEST_NFMPI_IGET_VARS],dnl
+[dnl
+ subroutine test_nf90mpi_iget_vars_$1()
+ use pnetcdf
+ implicit none
+#include "tests.inc"
+ integer roll, index2indexes
+ double precision hash4
+ logical equal, inRange3, in_internal_range
+
+ integer ncid
+ integer d
+ integer i
+ integer j
+ integer k
+ integer m
+ integer err
+ logical allInExtRange
+ logical allInIntRange
+ integer(kind=MPI_OFFSET_KIND) nels
+ integer nslabs
+ integer(kind=MPI_OFFSET_KIND) nstarts
+ integer nok
+ integer(kind=MPI_OFFSET_KIND) start(MAX_RANK)
+ integer(kind=MPI_OFFSET_KIND) edge(MAX_RANK)
+ integer(kind=MPI_OFFSET_KIND) index(MAX_RANK)
+ integer(kind=MPI_OFFSET_KIND) index2(MAX_RANK)
+ integer(kind=MPI_OFFSET_KIND) mid(MAX_RANK)
+ integer(kind=MPI_OFFSET_KIND) count(MAX_RANK)
+ integer(kind=MPI_OFFSET_KIND) sstride(MAX_RANK)
+ integer(kind=MPI_OFFSET_KIND) stride(MAX_RANK)
+ logical canConvert
+ DATATYPE($1, value, (MAX_NELS))
+ doubleprecision expect(MAX_NELS)
+ doubleprecision val
+ integer ud_shift
+ integer err_w, reqid(1), st(1)
+
+ nok = 0
+
+ err = nf90mpi_open(comm, testfile, NF90_NOWRITE, info, &
+ ncid)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_open: ', err)
+ do 1, i = 1, numVars
+ canConvert = (var_type(i) .eq. NF90_CHAR) .eqv. &
+ (NFT_ITYPE($1) .eq. NFT_TEXT)
+ if (.not.(var_rank(i) .le. MAX_RANK)) stop 'assert'
+ if (.not.(var_nels(i) .le. MAX_NELS)) stop 'assert'
+ do 2, j = 1, var_rank(i)
+ start(j) = 1
+ edge(j) = 1
+ stride(j) = 1
+2 continue
+ err = nf90mpi_iget_var(BAD_ID, i, value,reqid(1), start, edge, stride)
+ if (err .ne. NF90_EBADID) &
+ call errore('bad ncid: ', err)
+ err = nf90mpi_iget_var(ncid, BAD_VARID, value,reqid(1), start, edge, stride)
+ if (err .ne. NF90_ENOTVAR) &
+ call errore('bad var id: ', err)
+ do 3, j = 1, var_rank(i)
+ start(j) = var_shape(j,i) + 1
+ err = nf90mpi_iget_var(ncid, i, value,reqid(1), start, edge, stride)
+ if (err .eq. NF90_NOERR .or. err .eq. NF90_ERANGE) &
+ err_w = nf90mpi_wait_all(ncid,1,reqid,st)
+ if (.not. canConvert) then
+ if (err .ne. NF90_ECHAR) &
+ call errore('conversion: ', err)
+ else
+ if (err .ne. NF90_EINVALCOORDS) &
+ call errore('bad index: ', err)
+ endif
+ start(j) = 1
+ edge(j) = var_shape(j,i) + 1
+ err = nf90mpi_iget_var(ncid, i, value,reqid(1), start, edge, stride)
+ if (err .eq. NF90_NOERR .or. err .eq. NF90_ERANGE) &
+ err_w = nf90mpi_wait_all(ncid,1,reqid,st)
+ if (.not. canConvert) then
+ if (err .ne. NF90_ECHAR) &
+ call errore('conversion: ', err)
+ else
+ if (err .ne. NF90_EEDGE) &
+ call errore('bad edge: ', err)
+ endif
+ edge(j) = 1
+ stride(j) = 0
+ err = nf90mpi_iget_var(ncid, i, value,reqid(1), start, edge, stride)
+ if (err .eq. NF90_NOERR .or. err .eq. NF90_ERANGE) &
+ err_w = nf90mpi_wait_all(ncid,1,reqid,st)
+ if (.not. canConvert) then
+ if (err .ne. NF90_ECHAR) &
+ call errore('conversion: ', err)
+ else
+ if (err .ne. NF90_ESTRIDE) &
+ call errore('bad stride: ', err)
+ endif
+ stride(j) = 1
+3 continue
+! Choose a random point dividing each dim into 2 parts
+! get 2^rank (nslabs) slabs so defined
+ nslabs = 1
+ do 4, j = 1, var_rank(i)
+ mid(j) = roll( var_shape(j,i) )
+ nslabs = nslabs * 2
+4 continue
+! bits of k determine whether to get lower or upper part of dim
+! choose random stride from 1 to edge
+ do 5, k = 1, nslabs
+ nstarts = 1
+ do 6, j = 1, var_rank(i)
+ if (mod(ud_shift(k-1, j-1), 2) .eq. 1) then
+ start(j) = 1
+ edge(j) = mid(j)
+ else
+ start(j) = 1 + mid(j)
+ edge(j) = var_shape(j,i) - mid(j)
+ end if
+ if (edge(j) .gt. 0) then
+ sstride(j) = 1 + roll(edge(j))
+ else
+ sstride(j) = 1
+ end if
+ nstarts = nstarts * stride(j)
+6 continue
+ do 7, m = 1, INT(nstarts)
+ err = index2indexes(m, var_rank(i), sstride, &
+ index)
+ if (err .ne. NF90_NOERR) &
+ call error('error in index2indexes')
+ nels = 1
+ do 8, j = 1, var_rank(i)
+ count(j) = 1 + (edge(j) - index(j)) / &
+ stride(j)
+ nels = nels * count(j)
+ index(j) = index(j) + start(j) - 1
+8 continue
+! Random choice of forward or backward
+! /* TODO
+! if ( roll(2) ) then
+! for (j = 0 j < var_rank(i) j++) {
+! index(j) += (count(j) - 1) * stride(j)
+! stride(j) = -stride(j)
+! }
+! end if
+! */
+ allInIntRange = .true.
+ allInExtRange = .true.
+ do 9, j = 1, INT(nels)
+ err = index2indexes(j, var_rank(i), count, &
+ index2)
+ if (err .ne. NF90_NOERR) &
+ call error('error in index2indexes() 1')
+ do 10, d = 1, var_rank(i)
+ index2(d) = index(d) + (index2(d)-1) * &
+ stride(d)
+10 continue
+ expect(j) = hash4(var_type(i), var_rank(i), &
+ index2, NFT_ITYPE($1))
+ if (inRange3(expect(j),var_type(i), &
+ NFT_ITYPE($1))) then
+ allInIntRange = &
+ allInIntRange .and. &
+ in_internal_range(NFT_ITYPE($1), &
+ expect(j))
+ else
+ allInExtRange = .false.
+ end if
+9 continue
+ err = nf90mpi_iget_var(ncid, i,value,reqid(1), index, count,stride)
+ if (err .eq. NF90_NOERR .or. err .eq. NF90_ERANGE) &
+ err_w = nf90mpi_wait_all(ncid,1,reqid,st)
+ if (canConvert) then
+ if (allInExtRange) then
+ if (allInIntRange) then
+ if (st(1) .ne. 0) &
+ call error(nf90mpi_strerror(st(1)))
+ else
+ if (st(1) .ne. NF90_ERANGE) &
+ call errore('Range error: ', st(1))
+ end if
+ else
+ if (st(1) .ne. 0 .and. st(1) .ne. NF90_ERANGE) &
+ call errore('OK or Range error: ',st(1))
+ end if
+ do 11, j = 1, INT(nels)
+ if (inRange3(expect(j),var_type(i), &
+ NFT_ITYPE($1)) .and. &
+ in_internal_range(NFT_ITYPE($1), &
+ expect(j))) then
+ val = ARITH3($1, value, j)
+ if (.not.equal(val, expect(j), &
+ var_type(i), NFT_ITYPE($1))) then
+ call error( &
+ 'value read not that expected')
+ if (verbose) then
+ call error(' ')
+ call errori('varid: ', i)
+ call errorc('var_name: ', &
+ var_name(i))
+ call errori('element number: ', &
+ j)
+ call errord('expect: ', &
+ expect(j))
+ call errord('got: ', val)
+ end if
+ else
+ nok = nok + 1
+ end if
+ end if
+11 continue
+ else
+ if (nels .gt. 0 .and. err .ne. NF90_ECHAR) &
+ call errore('wrong type: ', err)
+ end if
+7 continue
+5 continue
+
+1 continue
+ err = nf90mpi_close(ncid)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_close: ', err)
+ call print_nok(nok)
+ end
+])dnl
+
+
+dnl TEST_NFMPI_IGET_VARM(TYPE)
+dnl
+define([TEST_NFMPI_IGET_VARM],dnl
+[dnl
+ subroutine test_nf90mpi_iget_varm_$1()
+ use pnetcdf
+ implicit none
+#include "tests.inc"
+ integer roll, index2indexes
+ double precision hash4
+ logical equal, inRange3, in_internal_range
+
+ integer ncid
+ integer d
+ integer i
+ integer j
+ integer k
+ integer m
+ integer err
+ logical allInExtRange
+ logical allInIntRange
+ integer(kind=MPI_OFFSET_KIND) nels
+ integer nslabs
+ integer(kind=MPI_OFFSET_KIND) nstarts
+ integer nok
+ integer(kind=MPI_OFFSET_KIND) start(MAX_RANK)
+ integer(kind=MPI_OFFSET_KIND) edge(MAX_RANK)
+ integer(kind=MPI_OFFSET_KIND) index(MAX_RANK)
+ integer(kind=MPI_OFFSET_KIND) index2(MAX_RANK)
+ integer(kind=MPI_OFFSET_KIND) mid(MAX_RANK)
+ integer(kind=MPI_OFFSET_KIND) count(MAX_RANK)
+ integer(kind=MPI_OFFSET_KIND) sstride(MAX_RANK)
+ integer(kind=MPI_OFFSET_KIND) stride(MAX_RANK)
+ integer(kind=MPI_OFFSET_KIND) imap(MAX_RANK)
+ logical canConvert
+ DATATYPE($1, value, (MAX_NELS))
+ doubleprecision expect(MAX_NELS)
+ doubleprecision val
+ integer ud_shift
+ integer err_w, reqid(1), st(1)
+
+ nok = 0
+
+ err = nf90mpi_open(comm, testfile, NF90_NOWRITE, info, &
+ ncid)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_open: ', err)
+ do 1, i = 1, numVars
+ canConvert = (var_type(i) .eq. NF90_CHAR) .eqv. &
+ (NFT_ITYPE($1) .eq. NFT_TEXT)
+ if (.not.(var_rank(i) .le. MAX_RANK)) stop 'assertion'
+ if (.not.(var_nels(i) .le. MAX_NELS)) stop 'assertion'
+ do 2, j = 1, var_rank(i)
+ start(j) = 1
+ edge(j) = 1
+ stride(j) = 1
+ imap(j) = 1
+2 continue
+ err = nf90mpi_iget_var(BAD_ID, i, value,reqid(1), start, edge, stride, imap)
+ if (err .ne. NF90_EBADID) &
+ call errore('bad ncid: ', err)
+ err = nf90mpi_iget_var(ncid, BAD_VARID, value,reqid(1), start, edge, stride, imap)
+ if (err .ne. NF90_ENOTVAR) &
+ call errore('bad var id: ', err)
+ do 3, j = 1, var_rank(i)
+ start(j) = var_shape(j,i) + 1
+ err = nf90mpi_iget_var(ncid, i, value,reqid(1), start, edge, stride, imap)
+ if (err .eq. NF90_NOERR .or. err .eq. NF90_ERANGE) &
+ err_w = nf90mpi_wait_all(ncid,1,reqid,st)
+ if (.not. canConvert) then
+ if (err .ne. NF90_ECHAR) &
+ call errore('conversion: ', err)
+ else
+ if (err .ne. NF90_EINVALCOORDS) &
+ call errore('bad index: ', err)
+ endif
+ start(j) = 1
+ edge(j) = var_shape(j,i) + 1
+ err = nf90mpi_iget_var(ncid, i, value,reqid(1), start, edge, stride, imap)
+ if (err .eq. NF90_NOERR .or. err .eq. NF90_ERANGE) &
+ err_w = nf90mpi_wait_all(ncid,1,reqid,st)
+ if (.not. canConvert) then
+ if (err .ne. NF90_ECHAR) &
+ call errore('conversion: ', err)
+ else
+ if (err .ne. NF90_EEDGE) &
+ call errore('bad edge: ', err)
+ endif
+ edge(j) = 1
+ stride(j) = 0
+ err = nf90mpi_iget_var(ncid, i, value, reqid(1), start, edge, stride, imap)
+ if (err .eq. NF90_NOERR .or. err .eq. NF90_ERANGE) &
+ err_w = nf90mpi_wait_all(ncid,1,reqid,st)
+ if (.not. canConvert) then
+ if (err .ne. NF90_ECHAR) &
+ call errore('conversion: ', err)
+ else
+ if (err .ne. NF90_ESTRIDE) &
+ call errore('bad stride: ', err)
+ endif
+ stride(j) = 1
+3 continue
+! Choose a random point dividing each dim into 2 parts
+! get 2^rank (nslabs) slabs so defined
+ nslabs = 1
+ do 4, j = 1, var_rank(i)
+ mid(j) = roll( var_shape(j,i) )
+ nslabs = nslabs * 2
+4 continue
+! /* bits of k determine whether to get lower or upper part
+! * of dim
+! * choose random stride from 1 to edge */
+ do 5, k = 1, nslabs
+ nstarts = 1
+ do 6, j = 1, var_rank(i)
+ if (mod(ud_shift((k-1), -(j-1)), 2) .ne. 0) then
+ start(j) = 1
+ edge(j) = mid(j)
+ else
+ start(j) = 1 + mid(j)
+ edge(j) = var_shape(j,i) - mid(j)
+ end if
+ if (edge(j) .gt. 0) then
+ stride(j) = 1+roll(edge(j))
+ else
+ stride(j) = 1
+ end if
+ sstride(j) = stride(j)
+ nstarts = nstarts * stride(j)
+6 continue
+ do 7, m = 1, INT(nstarts)
+ err = index2indexes(m, var_rank(i), sstride, index)
+ if (err .ne. NF90_NOERR) &
+ call error('error in index2indexes')
+ nels = 1
+ do 8, j = 1, var_rank(i)
+ count(j) = 1 + (edge(j) - index(j)) / &
+ stride(j)
+ nels = nels * count(j)
+ index(j) = index(j) + start(j) - 1
+8 continue
+! Random choice of forward or backward
+! /* TODO
+! if ( roll(2) ) then
+! for (j = 0 j < var_rank(i) j++) {
+! index(j) += (count(j) - 1) * stride(j)
+! stride(j) = -stride(j)
+! }
+! end if
+! */
+ if (var_rank(i) .gt. 0) then
+ imap(1) = 1
+ do 9, j = 2, var_rank(i)
+ imap(j) = imap(j-1) * count(j-1)
+9 continue
+ end if
+ allInIntRange = .true.
+ allInExtRange = .true.
+ do 10, j = 1, INT(nels)
+ err = index2indexes(j, var_rank(i), count, &
+ index2)
+ if (err .ne. NF90_NOERR) &
+ call error('error in index2indexes 1')
+ do 11, d = 1, var_rank(i)
+ index2(d) = index(d) + (index2(d)-1) * &
+ stride(d)
+11 continue
+ expect(j) = hash4(var_type(i), var_rank(i), &
+ index2, NFT_ITYPE($1))
+ if (inRange3(expect(j),var_type(i), &
+ NFT_ITYPE($1))) then
+ allInIntRange = &
+ allInIntRange .and. &
+ in_internal_range(NFT_ITYPE($1), &
+ expect(j))
+ else
+ allInExtRange = .false.
+ end if
+10 continue
+ err = nf90mpi_iget_var(ncid,i, value, reqid(1), index, count, stride, imap)
+ if (err .eq. NF90_NOERR .or. err .eq. NF90_ERANGE) &
+ err_w = nf90mpi_wait_all(ncid,1,reqid,st)
+ if (canConvert) then
+ if (allInExtRange) then
+ if (allInIntRange) then
+ if (st(1) .ne. 0) &
+ call error(nf90mpi_strerror(st(1)))
+ else
+ if (st(1) .ne. NF90_ERANGE) &
+ call errore('Range error: ', st(1))
+ end if
+ else
+ if (st(1) .ne. 0 .and. st(1) .ne. NF90_ERANGE) &
+ call errore('OK or Range error: ',st(1))
+ end if
+ do 12, j = 1, INT(nels)
+ if (inRange3(expect(j),var_type(i), &
+ NFT_ITYPE($1)) .and. &
+ in_internal_range(NFT_ITYPE($1), &
+ expect(j))) then
+ val = ARITH3($1, value, j)
+ if (.not.equal(val, expect(j), &
+ var_type(i), &
+ NFT_ITYPE($1))) then
+ call error( &
+ 'value read not that expected')
+ if (verbose) then
+ call error(' ')
+ call errori('varid: ', i)
+ call errorc('var_name: ', &
+ var_name(i))
+ call errori('element number: ', &
+ j)
+ call errord('expect: ', &
+ expect(j))
+ call errord('got: ', val)
+ end if
+ else
+ nok = nok + 1
+ end if
+ end if
+12 continue
+ else
+ if (nels .gt. 0 .and. err .ne. NF90_ECHAR) &
+ call errore('wrong type: ', err)
+ end if
+7 continue
+5 continue
+1 continue
+ err = nf90mpi_close(ncid)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_close: ', err)
+ call print_nok(nok)
+ end
+])dnl
+
+divert(0)dnl
+dnl If you see this line, you can ignore the next one.
+! Do not edit this file. It is produced from the corresponding .m4 source */
+
+!
+! Copyright (C) 2013, Northwestern University and Argonne National Laboratory
+! See COPYRIGHT notice in top-level directory.
+!
+
+TEST_NFMPI_IGET_VAR1(text)
+#ifdef NF_INT1_T
+TEST_NFMPI_IGET_VAR1(int1)
+#endif
+#ifdef NF_INT2_T
+TEST_NFMPI_IGET_VAR1(int2)
+#endif
+TEST_NFMPI_IGET_VAR1(int)
+TEST_NFMPI_IGET_VAR1(int8)
+TEST_NFMPI_IGET_VAR1(real)
+TEST_NFMPI_IGET_VAR1(double)
+
+TEST_NFMPI_IGET_VAR(text)
+#ifdef NF_INT1_T
+TEST_NFMPI_IGET_VAR(int1)
+#endif
+#ifdef NF_INT2_T
+TEST_NFMPI_IGET_VAR(int2)
+#endif
+TEST_NFMPI_IGET_VAR(int)
+TEST_NFMPI_IGET_VAR(int8)
+TEST_NFMPI_IGET_VAR(real)
+TEST_NFMPI_IGET_VAR(double)
+
+TEST_NFMPI_IGET_VARA(text)
+#ifdef NF_INT1_T
+TEST_NFMPI_IGET_VARA(int1)
+#endif
+#ifdef NF_INT2_T
+TEST_NFMPI_IGET_VARA(int2)
+#endif
+TEST_NFMPI_IGET_VARA(int)
+TEST_NFMPI_IGET_VARA(int8)
+TEST_NFMPI_IGET_VARA(real)
+TEST_NFMPI_IGET_VARA(double)
+
+TEST_NFMPI_IGET_VARS(text)
+#ifdef NF_INT1_T
+TEST_NFMPI_IGET_VARS(int1)
+#endif
+#ifdef NF_INT2_T
+TEST_NFMPI_IGET_VARS(int2)
+#endif
+TEST_NFMPI_IGET_VARS(int)
+TEST_NFMPI_IGET_VARS(int8)
+TEST_NFMPI_IGET_VARS(real)
+TEST_NFMPI_IGET_VARS(double)
+
+TEST_NFMPI_IGET_VARM(text)
+#ifdef NF_INT1_T
+TEST_NFMPI_IGET_VARM(int1)
+#endif
+#ifdef NF_INT2_T
+TEST_NFMPI_IGET_VARM(int2)
+#endif
+TEST_NFMPI_IGET_VARM(int)
+TEST_NFMPI_IGET_VARM(int8)
+TEST_NFMPI_IGET_VARM(real)
+TEST_NFMPI_IGET_VARM(double)
+
diff --git a/test/nf90_test/test_iput.m4 b/test/nf90_test/test_iput.m4
new file mode 100644
index 0000000..fc7fa36
--- /dev/null
+++ b/test/nf90_test/test_iput.m4
@@ -0,0 +1,1087 @@
+dnl
+dnl Copyright (C) 2013, Northwestern University and Argonne National Laboratory
+dnl See COPYRIGHT notice in top-level directory.
+dnl
+dnl $Id: test_iput.m4 2156 2015-10-12 01:15:25Z wkliao $
+dnl
+
+divert(-1)
+
+dnl This is m4 source.
+dnl Process using m4 to produce FORTRAN language file.
+
+changequote([,]) dnl
+
+undefine([index])dnl
+
+dnl Macros
+
+dnl Upcase(str)
+dnl
+define([Upcase],[dnl
+translit($1, abcdefghijklmnopqrstuvwxyz, ABCDEFGHIJKLMNOPQRSTUVWXYZ)])
+
+dnl NFT_ITYPE(type)
+dnl
+define([NFT_ITYPE], [NFT_[]Upcase($1)])
+
+dnl ARITH3(itype, value)
+dnl
+define([ARITH3], [ifelse($1, text, ichar($2($3:$3)), $2($3))])
+
+dnl VALUE3(itype, value)
+dnl
+define([VALUE3], [ifelse($1, text, $2(1:nels), $2(1:nels))])
+
+dnl VAR_ELEM(itype, value)
+dnl
+define([VAR_ELEM], [ifelse($1, text, $2($3:$3), $2($3))])
+
+dnl ARITH_VAR1(itype, value)
+dnl
+define([ARITH_VAR1], [ifelse($1, text, ichar($2(1:1)), $2(1))])
+
+dnl DATATYPE(funf_suffix)
+dnl
+define([DATATYPE], [dnl
+ifelse($1, text, character(len=$3) $2,
+ifelse($1, int1, NF_INT1_T $2($3),
+ifelse($1, int2, NF_INT2_T $2($3),
+ifelse($1, int, integer $2($3),
+ifelse($1, int8, NF_INT8_T $2($3),
+ifelse($1, real, real $2($3),
+ifelse($1, double, doubleprecision $2($3))[]dnl
+)[]dnl
+)[]dnl
+)[]dnl
+)[]dnl
+)[]dnl
+)[]dnl
+])
+
+dnl DATATYPE_VAR1(funf_suffix)
+dnl
+define([DATATYPE_VAR1], [dnl
+ifelse($1, text, character(len=1) $2,
+ifelse($1, int1, NF_INT1_T $2(1),
+ifelse($1, int2, NF_INT2_T $2(1),
+ifelse($1, int, integer $2(1),
+ifelse($1, int8, NF_INT8_T $2(1),
+ifelse($1, real, real $2(1),
+ifelse($1, double, double precision $2(1))[]dnl
+)[]dnl
+)[]dnl
+)[]dnl
+)[]dnl
+)[]dnl
+)[]dnl
+])
+
+dnl MAKE_ARITH_VAR1(funf_suffix, var)
+dnl
+define([MAKE_ARITH_VAR1], [dnl
+ifelse($1, text, ichar($2), $2)[]dnl
+])
+
+dnl MAKE_ARITH3(funf_suffix, var)
+dnl
+define([MAKE_ARITH3], [dnl
+ifelse($1, text, ichar($2($3:$3)), $2($3))[]dnl
+])
+
+dnl MAKE_DOUBLE(funf_suffix, var)
+dnl
+define([MAKE_DOUBLE], [dnl
+ifelse($1, text, dble(ichar($2)), dble($2))[]dnl
+])
+
+dnl MAKE_TYPE(funf_suffix, var)
+dnl
+define([MAKE_TYPE], [dnl
+ifelse($1, text, char(int($2)),
+ ifelse($1, int, INT($2),
+ ifelse($1, int1, INT($2,KIND=INT1_KIND),
+ ifelse($1, int2, INT($2,KIND=INT2_KIND),
+ ifelse($1, int8, INT($2,KIND=INT8_KIND),
+ ifelse($1, real, REAL($2),
+ $2))))))[]dnl
+])
+
+dnl MAKE_TYPE2(funf_suffix, var_dest, var_src)
+dnl
+define([MAKE_TYPE2], [dnl
+ifelse($1, text, $2 = char(int($3)),
+ ifelse($1, int, $2 = INT($3),
+ ifelse($1, int1, $2 = INT($3,KIND=INT1_KIND),
+ ifelse($1, int2, $2 = INT($3,KIND=INT2_KIND),
+ ifelse($1, int8,
+ if ($3 .EQ. X_INT8_MAX) then
+ $2 = X_INT8_MAX
+ else
+ $2 = INT($3,KIND=INT8_KIND)
+ endif,
+ ifelse($1, real, $2 = REAL($3),
+ $2 = $3))))))[]dnl
+])
+
+dnl TEST_NFMPI_IPUT_VAR1(TYPE)
+dnl
+define([TEST_NFMPI_IPUT_VAR1],dnl
+[dnl
+ subroutine test_nf90mpi_iput_var1_$1()
+ use pnetcdf
+ implicit none
+#include "tests.inc"
+ integer index2indexes
+ double precision hash_$1
+ logical inRange3
+
+ integer ncid
+ integer i
+ integer j
+ integer err, flags
+ integer(kind=MPI_OFFSET_KIND) index(MAX_RANK)
+ logical canConvert !/* Both text or both numeric */
+ DATATYPE_VAR1($1, value)
+ double precision val
+ integer err_w, reqid(1), st(1)
+
+ value = MAKE_TYPE($1, 5)!/* any value would do - only for error cases */
+
+ flags = IOR(NF90_CLOBBER, extra_flags)
+ err = nf90mpi_create(comm, scratch, flags, info, &
+ ncid)
+ if (err .ne. NF90_NOERR) then
+ call errore('nf90mpi_create: ', err)
+ return
+ end if
+ call def_dims(ncid)
+ call def_vars(ncid)
+ err = nf90mpi_enddef(ncid)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_enddef: ', err)
+ do 1, i = 1, numVars
+ canConvert = (var_type(i) .eq. NF90_CHAR) .eqv. &
+ (NFT_ITYPE($1) .eq. NFT_TEXT)
+ do 2, j = 1, var_rank(i)
+ index(j) = 1
+2 continue
+ err = nf90mpi_iput_var(BAD_ID, i, value(1:1), reqid(1), index)
+ if (err .ne. NF90_EBADID) &
+ call errore('bad ncid: ', err)
+ err = nf90mpi_iput_var(ncid, BAD_VARID, value(1:1),reqid(1), index)
+ if (err .ne. NF90_ENOTVAR) &
+ call errore('bad var id: ', err)
+ do 3, j = 1, var_rank(i)
+ if (var_dimid(j,i) .gt. 1) then !/* skip record dim */
+ index(j) = var_shape(j,i) + 1
+ err = nf90mpi_iput_var(ncid, i, value(1:1),reqid(1), index)
+ if (err .eq. NF90_NOERR .or. err .eq. NF90_ERANGE) &
+ err_w = nf90mpi_wait_all(ncid,1,reqid,st)
+ if (.not. canConvert) then
+ if (err .ne. NF90_ECHAR) &
+ call errore('conversion: ', err)
+ else
+ if (err .ne. NF90_EINVALCOORDS) &
+ call errore('bad index: ', err)
+ endif
+ index(j) = 0
+ end if
+3 continue
+ do 4, j = 1, var_nels(i)
+ err = index2indexes(j, var_rank(i), var_shape(1,i), &
+ index)
+ if (err .ne. NF90_NOERR) &
+ call error('error in index2indexes 1')
+ val = hash_$1(var_type(i),var_rank(i), &
+ index, NFT_ITYPE($1))
+ MAKE_TYPE2($1, value, val)
+ err = nf90mpi_iput_var(ncid, i, value(1:1), reqid(1), index)
+ if (err .eq. NF90_NOERR .or. err .eq. NF90_ERANGE) &
+ err_w = nf90mpi_wait_all(ncid,1,reqid,st)
+ if (canConvert) then
+ val = ARITH_VAR1($1, value)
+ if (inRange3(val, var_type(i), NFT_ITYPE($1))) then
+ if (st(1) .ne. 0) &
+ call error(nf90mpi_strerror(st(1)))
+ else
+ if (err .ne. NF90_ERANGE) &
+ call errore('Range error: ', err)
+ end if
+ else
+ if (err .ne. NF90_ECHAR) &
+ call errore('wrong type: ', err)
+ end if
+4 continue
+1 continue
+ err = nf90mpi_close(ncid)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_close: ', err)
+
+ call check_vars_$1(scratch)
+
+ err = nf90mpi_delete(scratch, info)
+ if (err .ne. NF90_NOERR) &
+ call errorc('delete of scratch file failed: ', &
+ scratch)
+ end
+])dnl
+
+
+dnl TEST_NFMPI_IPUT_VAR(TYPE)
+dnl
+define([TEST_NFMPI_IPUT_VAR],dnl
+[dnl
+ subroutine test_nf90mpi_iput_var_$1()
+ use pnetcdf
+ implicit none
+#include "tests.inc"
+ integer index2indexes
+ double precision hash_$1
+ logical inRange3
+
+ integer ncid
+ integer vid
+ integer i
+ integer j
+ integer err, flags
+ integer(kind=MPI_OFFSET_KIND) nels
+ integer(kind=MPI_OFFSET_KIND) index(MAX_RANK)
+ logical canConvert !/* Both text or both numeric */
+ logical allInExtRange !/* All values within external range?*/
+ DATATYPE($1, value, MAX_NELS)
+ doubleprecision val
+ integer err_w, reqid(1), st(1)
+
+ flags = IOR(NF90_CLOBBER, extra_flags)
+ err = nf90mpi_create(comm, scratch, flags, info, &
+ ncid)
+ if (err .ne. NF90_NOERR) then
+ call errore('nf90mpi_create: ', err)
+ return
+ end if
+ call def_dims(ncid)
+ call def_vars(ncid)
+ err = nf90mpi_enddef(ncid)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_enddef: ', err)
+ do 1, i = 1, numVars
+ canConvert = (var_type(i) .eq. NF90_CHAR) .eqv. &
+ (NFT_ITYPE($1) .eq. NFT_TEXT)
+ err = nf90mpi_iput_var(BAD_ID, i, value, reqid(1))
+ if (err .ne. NF90_EBADID) &
+ call errore('bad ncid: ', err)
+ err = nf90mpi_iput_var(ncid, BAD_VARID, value, reqid(1))
+ if (err .ne. NF90_ENOTVAR) &
+ call errore('bad var id: ', err)
+ nels = 1
+ do 3, j = 1, var_rank(i)
+ nels = nels * var_shape(j,i)
+3 continue
+ allInExtRange = .true.
+ do 4, j = 1, var_nels(i)
+ err = index2indexes(j, var_rank(i), var_shape(1,i), &
+ index)
+ if (err .ne. NF90_NOERR) &
+ call error('error in index2indexes 1')
+ val = hash_$1(var_type(i), var_rank(i), &
+ index, NFT_ITYPE($1))
+ MAKE_TYPE2($1, VAR_ELEM($1, value, j), val)
+ val = ARITH3($1, value, j)
+ allInExtRange = allInExtRange .and. &
+ inRange3(val, var_type(i), NFT_ITYPE($1))
+4 continue
+ err = nf90mpi_iput_var(ncid, i, value, reqid(1), count=var_shape(:,i))
+ if (err .eq. NF90_NOERR .or. err .eq. NF90_ERANGE) &
+ err_w = nf90mpi_wait_all(ncid, 1, reqid, st)
+ ! NF90_ERANGE is not a fatal error
+
+ if (canConvert) then
+ if (allInExtRange) then
+ if (err .ne. NF90_NOERR) &
+ call error(nf90mpi_strerror(err))
+ else
+ if (err .ne. NF90_ERANGE .and. &
+ var_dimid(var_rank(i),i) .ne. RECDIM) &
+ call errore('Range error: ', err)
+ endif
+ else
+ if (err .ne. NF90_ECHAR) &
+ call errore('wrong type: ', err)
+ endif
+1 continue
+
+! The preceeding has written nothing for record variables, now try
+! again with more than 0 records.
+
+! Write record number NRECS to force writing of preceding records.
+! Assumes variable cr is char vector with UNLIMITED dimension.
+
+ err = nf90mpi_inq_varid(ncid, "cr", vid)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_inq_varid: ', err)
+ index(1) = NRECS
+ err = nf90mpi_iput_var(ncid, vid, 'x',reqid(1), index)
+ if (err .ne. NF90_NOERR) then
+ call errore('nf90mpi_iput_var: ', err)
+ else
+ err_w = nf90mpi_wait_all(ncid, 1, reqid, st)
+ endif
+
+ do 5 i = 1, numVars
+! Only test record variables here
+ if (var_rank(i) .ge. 1 .and. &
+ var_dimid(var_rank(i),i) .eq. RECDIM) then
+ canConvert = (var_type(i) .eq. NF90_CHAR) .eqv. &
+ (NFT_ITYPE($1) .eq. NFT_TEXT)
+ if (var_rank(i) .gt. MAX_RANK) &
+ stop 'var_rank(i) .gt. MAX_RANK'
+ if (var_nels(i) .gt. MAX_NELS) &
+ stop 'var_nels(i) .gt. MAX_NELS'
+
+ nels = 1
+ do 6 j = 1, var_rank(i)
+ nels = nels * var_shape(j,i)
+6 continue
+ allInExtRange = .true.
+ do 7, j = 1, INT(nels)
+ err = index2indexes(j, var_rank(i), var_shape(1,i), &
+ index)
+ if (err .ne. NF90_NOERR) &
+ call error('error in index2indexes()')
+ val = hash_$1(var_type(i), var_rank(i), &
+ index, NFT_ITYPE($1))
+ MAKE_TYPE2($1, VAR_ELEM($1, value, j), val)
+ val = ARITH3($1, value, j)
+ allInExtRange = allInExtRange .and. &
+ inRange3(val, var_type(i), NFT_ITYPE($1))
+7 continue
+ err = nf90mpi_iput_var(ncid, i, value, reqid(1), count=var_shape(:,i))
+ if (err .eq. NF90_NOERR .or. err .eq. NF90_ERANGE) &
+ err_w = nf90mpi_wait_all(ncid, 1, reqid, st)
+ ! NF90_ERANGE is not a fatal error
+ if (canConvert) then
+ if (allInExtRange) then
+ if (err .ne. NF90_NOERR) &
+ call error(nf90mpi_strerror(err))
+ else
+ if (err .ne. NF90_ERANGE) &
+ call errore('range error: ', err)
+ endif
+ else
+ if (nels .gt. 0 .and. err .ne. NF90_ECHAR) &
+ call errore('wrong type: ', err)
+ endif
+ endif
+5 continue
+ err = nf90mpi_close(ncid)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_close: ', err)
+
+ call check_vars_$1(scratch)
+
+ err = nf90mpi_delete(scratch, info)
+ if (err .ne. NF90_NOERR) &
+ call errorc('delete of scratch file failed: ', &
+ scratch)
+ end
+])dnl
+
+
+dnl TEST_NFMPI_IPUT_VARA(TYPE)
+dnl
+define([TEST_NFMPI_IPUT_VARA],dnl
+[dnl
+ subroutine test_nf90mpi_iput_vara_$1()
+ use pnetcdf
+ implicit none
+#include "tests.inc"
+ integer roll, index2indexes
+ double precision hash_$1
+ logical inRange3
+
+ integer ncid
+ integer i
+ integer j
+ integer k
+ integer d
+ integer err, flags
+ integer nslabs
+ integer(kind=MPI_OFFSET_KIND) nels
+ integer(kind=MPI_OFFSET_KIND) start(MAX_RANK)
+ integer(kind=MPI_OFFSET_KIND) edge(MAX_RANK)
+ integer(kind=MPI_OFFSET_KIND) mid(MAX_RANK)
+ integer(kind=MPI_OFFSET_KIND) index(MAX_RANK)
+ logical canConvert !/* Both text or both numeric */
+ logical allInExtRange !/* all values within external range? */
+ DATATYPE($1, value, (MAX_NELS))
+ doubleprecision val
+ integer ud_shift
+ integer err_w, reqid(1), st(1)
+
+ flags = IOR(NF90_CLOBBER, extra_flags)
+ err = nf90mpi_create(comm, scratch, flags, info, &
+ ncid)
+ if (err .ne. NF90_NOERR) then
+ call errore('nf90mpi_create: ', err)
+ return
+ end if
+ call def_dims(ncid)
+ call def_vars(ncid)
+ err = nf90mpi_enddef(ncid)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_enddef: ', err)
+
+ do 1, i = 1, numVars
+ canConvert = (var_type(i) .eq. NF90_CHAR) .eqv. &
+ (NFT_ITYPE($1) .eq. NFT_TEXT)
+ if (.not.(var_rank(i) .le. MAX_RANK)) &
+ stop 'assert(var_rank(i) .le. MAX_RANK)'
+ if (.not.(var_nels(i) .le. MAX_NELS)) &
+ stop 'assert(var_nels(i) .le. MAX_NELS)'
+ do 2, j = 1, var_rank(i)
+ start(j) = 1
+ edge(j) = 1
+2 continue
+ err = nf90mpi_iput_var(BAD_ID, i, value,reqid(1), start, edge)
+ if (err .ne. NF90_EBADID) &
+ call errore('bad ncid: ', err)
+ err = nf90mpi_iput_var(ncid, BAD_VARID, &
+ value,reqid(1), start, edge)
+ if (err .ne. NF90_ENOTVAR) &
+ call errore('bad var id: ', err)
+ do 3, j = 1, var_rank(i)
+ if (var_dimid(j,i) .ne. RECDIM) then !/* skip record dim */
+ start(j) = var_shape(j,i) + 1
+ err = nf90mpi_iput_var(ncid, i, value,reqid(1), start, edge)
+ if (err .eq. NF90_NOERR .or. err .eq. NF90_ERANGE) &
+ err_w = nf90mpi_wait_all(ncid,1,reqid,st)
+ ! NF90_ERANGE is not a fatal error
+ if (.not. canConvert) then
+ if (err .ne. NF90_ECHAR) &
+ call errore('conversion: ', err)
+ else
+ if (err .ne. NF90_EINVALCOORDS) &
+ call errore('bad start: ', err)
+ endif
+ start(j) = 1
+ edge(j) = var_shape(j,i) + 1
+ err = nf90mpi_iput_var(ncid, i, value,reqid(1), start, edge)
+ if (err .eq. NF90_NOERR .or. err .eq. NF90_ERANGE) &
+ err_w = nf90mpi_wait_all(ncid,1,reqid,st)
+ ! NF90_ERANGE is not a fatal error
+ if (.not. canConvert) then
+ if (err .ne. NF90_ECHAR) &
+ call errore('conversion: ', err)
+ else
+ if (err .ne. NF90_EEDGE) &
+ call errore('bad edge: ', err)
+ endif
+ edge(j) = 1
+ end if
+3 continue
+
+! /* Check correct error returned even when nothing to put */
+ do 20, j = 1, var_rank(i)
+ edge(j) = 0
+20 continue
+ err = nf90mpi_iput_var(BAD_ID, i, value,reqid(1), start, edge)
+ if (err .ne. NF90_EBADID) &
+ call errore('bad ncid: ', err)
+ err = nf90mpi_iput_var(ncid, BAD_VARID, value,reqid(1), start, edge)
+ if (err .ne. NF90_ENOTVAR) &
+ call errore('bad var id: ', err)
+ do 21, j = 1, var_rank(i)
+ if (var_dimid(j,i) .gt. 1) then ! skip record dim
+ start(j) = var_shape(j,i) + 1
+ err = nf90mpi_iput_var(ncid, i, value,reqid(1), start, edge)
+ if (err .eq. NF90_NOERR .or. err .eq. NF90_ERANGE) &
+ err_w = nf90mpi_wait_all(ncid, 1, reqid, st)
+ ! NF90_ERANGE is not a fatal error
+ if (.not. canConvert) then
+ if (err .ne. NF90_ECHAR) &
+ call errore('conversion: ', err)
+ else
+ if (err .ne. NF90_EINVALCOORDS) &
+ call errore('bad start: ', err)
+ endif
+ start(j) = 1
+ endif
+21 continue
+ err = nf90mpi_iput_var(ncid, i, value, reqid(1), start, edge)
+ if (err .eq. NF90_NOERR .or. err .eq. NF90_ERANGE) &
+ err_w = nf90mpi_wait_all(ncid,1,reqid,st)
+ if (canConvert) then
+ if (st(1) .ne. 0) &
+ call error(nf90mpi_strerror(st(1)))
+ else
+ if (err .ne. NF90_ECHAR) &
+ call errore('wrong type: ', err)
+ endif
+ do 22, j = 1, var_rank(i)
+ edge(j) = 1
+22 continue
+
+
+ !/* Choose a random point dividing each dim into 2 parts */
+ !/* Put 2^rank (nslabs) slabs so defined */
+ nslabs = 1
+ do 4, j = 1, var_rank(i)
+ mid(j) = roll( var_shape(j,i) )
+ nslabs = nslabs * 2
+4 continue
+ !/* bits of k determine whether to put lower or upper part of dim */
+ do 5, k = 1, nslabs
+ nels = 1
+ do 6, j = 1, var_rank(i)
+ if (mod(ud_shift(k-1, -(j-1)), 2) .eq. 1) then
+ start(j) = 1
+ edge(j) = mid(j)
+ else
+ start(j) = 1 + mid(j)
+ edge(j) = var_shape(j,i) - mid(j)
+ end if
+ nels = nels * edge(j)
+6 continue
+ allInExtRange = .true.
+ do 7, j = 1, INT(nels)
+ err = index2indexes(j, var_rank(i), edge, index)
+ if (err .ne. NF90_NOERR) &
+ call error('error in index2indexes 1')
+ do 8, d = 1, var_rank(i)
+ index(d) = index(d) + start(d) - 1
+8 continue
+ val = hash_$1(var_type(i), var_rank(i), &
+ index, NFT_ITYPE($1))
+ MAKE_TYPE2($1, VAR_ELEM($1, value, j), val)
+ val = ARITH3($1, value, j)
+ allInExtRange = allInExtRange .and. &
+ inRange3(val, var_type(i), NFT_ITYPE($1))
+7 continue
+ err = nf90mpi_iput_var(ncid, i, value,reqid(1), start, edge)
+ if (err .eq. NF90_NOERR .or. err .eq. NF90_ERANGE) &
+ err_w = nf90mpi_wait_all(ncid,1,reqid,st)
+ ! NF90_ERANGE is not a fatal error
+ if (canConvert) then
+ if (allInExtRange) then
+ if (st(1) .ne. 0) &
+ call error(nf90mpi_strerror(st(1)))
+ else
+ if (err .ne. NF90_ERANGE) &
+ call errore('range error: ', err)
+ end if
+ else
+ if (nels .gt. 0 .and. err .ne. NF90_ECHAR) &
+ call errore('wrong type: ', err)
+ end if
+5 continue
+1 continue
+
+ err = nf90mpi_close(ncid)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_close: ', err)
+
+ call check_vars_$1(scratch)
+
+ err = nf90mpi_delete(scratch, info)
+ if (err .ne. NF90_NOERR) &
+ call errorc('delete of scratch file failed: ', &
+ scratch)
+ end
+])dnl
+
+
+dnl TEST_NFMPI_IPUT_VARS(TYPE)
+dnl
+define([TEST_NFMPI_IPUT_VARS],dnl
+[dnl
+ subroutine test_nf90mpi_iput_vars_$1()
+ use pnetcdf
+ implicit none
+#include "tests.inc"
+ integer roll, index2indexes
+ double precision hash_$1
+ logical inRange3
+
+ integer ncid
+ integer d
+ integer i
+ integer j
+ integer k
+ integer m
+ integer err, flags
+ integer(kind=MPI_OFFSET_KIND) nels
+ integer nslabs
+ integer(kind=MPI_OFFSET_KIND) nstarts !/* number of different starts */
+ integer(kind=MPI_OFFSET_KIND) start(MAX_RANK)
+ integer(kind=MPI_OFFSET_KIND) edge(MAX_RANK)
+ integer(kind=MPI_OFFSET_KIND) index(MAX_RANK)
+ integer(kind=MPI_OFFSET_KIND) index2(MAX_RANK)
+ integer(kind=MPI_OFFSET_KIND) mid(MAX_RANK)
+ integer(kind=MPI_OFFSET_KIND) count(MAX_RANK)
+ integer(kind=MPI_OFFSET_KIND) sstride(MAX_RANK)
+ integer(kind=MPI_OFFSET_KIND) stride(MAX_RANK)
+ logical canConvert !/* Both text or both numeric */
+ logical allInExtRange !/* all values within external range? */
+ DATATYPE($1, value, (MAX_NELS))
+ doubleprecision val
+ integer ud_shift
+ integer err_w, reqid(1), st(1)
+
+ flags = IOR(NF90_CLOBBER, extra_flags)
+ err = nf90mpi_create(comm, scratch, flags, info, &
+ ncid)
+ if (err .ne. NF90_NOERR) then
+ call errore('nf90mpi_create: ', err)
+ return
+ end if
+ call def_dims(ncid)
+ call def_vars(ncid)
+ err = nf90mpi_enddef(ncid)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_enddef: ', err)
+
+ do 1, i = 1, numVars
+ canConvert = (var_type(i) .eq. NF90_CHAR) .eqv. &
+ (NFT_ITYPE($1) .eq. NFT_TEXT)
+ if (.not.(var_rank(i) .le. MAX_RANK)) &
+ stop 'assert(var_rank(i) .le. MAX_RANK)'
+ if (.not.(var_nels(i) .le. MAX_NELS)) &
+ stop 'assert(var_nels(i) .le. MAX_NELS)'
+ do 2, j = 1, var_rank(i)
+ start(j) = 1
+ edge(j) = 1
+ stride(j) = 1
+2 continue
+ err = nf90mpi_iput_var(BAD_ID, i, value,reqid(1), start, edge, stride)
+ if (err .ne. NF90_EBADID) &
+ call errore('bad ncid: ', err)
+ err = nf90mpi_iput_var(ncid, BAD_VARID, value,reqid(1), start, edge, stride)
+ if (err .ne. NF90_ENOTVAR) &
+ call errore('bad var id: ', err)
+ do 3, j = 1, var_rank(i)
+ if (var_dimid(j,i) .ne. RECDIM) then ! skip record dim
+ start(j) = var_shape(j,i) + 1
+ err = nf90mpi_iput_var(ncid, i, value,reqid(1), start, edge, stride)
+ if (err .eq. NF90_NOERR .or. err .eq. NF90_ERANGE) &
+ err_w = nf90mpi_wait_all(ncid,1,reqid,st)
+ if (.not. canConvert) then
+ if (err .ne. NF90_ECHAR) &
+ call errore('conversion: ', err)
+ else
+ if (err .ne. NF90_EINVALCOORDS) &
+ call errore('bad start: ', err)
+ endif
+ start(j) = 1
+ edge(j) = var_shape(j,i) + 1
+ err = nf90mpi_iput_var(ncid, i, value,reqid(1), start, edge, stride)
+ if (err .eq. NF90_NOERR .or. err .eq. NF90_ERANGE) &
+ err_w = nf90mpi_wait_all(ncid,1,reqid,st)
+ if (.not. canConvert) then
+ if (err .ne. NF90_ECHAR) &
+ call errore('conversion: ', err)
+ else
+ if (err .ne. NF90_EEDGE) &
+ call errore('bad edge: ', err)
+ endif
+ edge(j) = 1
+ stride(j) = 0
+ err = nf90mpi_iput_var(ncid, i, value,reqid(1), start, edge, stride)
+ if (err .eq. NF90_NOERR .or. err .eq. NF90_ERANGE) &
+ err_w = nf90mpi_wait_all(ncid,1,reqid,st)
+ if (.not. canConvert) then
+ if (err .ne. NF90_ECHAR) &
+ call errore('conversion: ', err)
+ else
+ if (err .ne. NF90_ESTRIDE) &
+ call errore('bad stride: ', err)
+ endif
+ stride(j) = 1
+ end if
+3 continue
+ !/* Choose a random point dividing each dim into 2 parts */
+ !/* Put 2^rank (nslabs) slabs so defined */
+ nslabs = 1
+ do 4, j = 1, var_rank(i)
+ mid(j) = roll( var_shape(j,i) )
+ nslabs = nslabs * 2
+4 continue
+ !/* bits of k determine whether to put lower or upper part of dim */
+ !/* choose random stride from 1 to edge */
+ do 5, k = 1, nslabs
+ nstarts = 1
+ do 6, j = 1, var_rank(i)
+ if (mod(ud_shift(k-1, -(j-1)), 2) .eq. 1) then
+ start(j) = 1
+ edge(j) = mid(j)
+ else
+ start(j) = 1 + mid(j)
+ edge(j) = var_shape(j,i) - mid(j)
+ end if
+ if (edge(j) .gt. 0) then
+ stride(j) = 1+roll(edge(j))
+ else
+ stride(j) = 1
+ end if
+ sstride(j) = stride(j)
+ nstarts = nstarts * stride(j)
+6 continue
+ do 7, m = 1, INT(nstarts)
+ err = index2indexes(m, var_rank(i), sstride, index)
+ if (err .ne. NF90_NOERR) &
+ call error('error in index2indexes')
+ nels = 1
+ do 8, j = 1, var_rank(i)
+ count(j) = 1 + (edge(j) - index(j)) / stride(j)
+ nels = nels * count(j)
+ index(j) = index(j) + start(j) - 1
+8 continue
+ !/* Random choice of forward or backward */
+! TODO
+! if ( roll(2) ) {
+! for (j = 1 j .lt. var_rank(i) j++) {
+! index(j) += (count(j) - 1) * stride(j)
+! stride(j) = -stride(j)
+! }
+! }
+!
+ allInExtRange = .true.
+ do 9, j = 1, INT(nels)
+ err = index2indexes(j, var_rank(i), count, &
+ index2)
+ if (err .ne. NF90_NOERR) &
+ call error('error in index2indexes')
+ do 10, d = 1, var_rank(i)
+ index2(d) = index(d) + &
+ (index2(d)-1) * stride(d)
+10 continue
+ val = hash_$1(var_type(i), var_rank(i), &
+ index2, NFT_ITYPE($1))
+ MAKE_TYPE2($1, VAR_ELEM($1, value, j), val)
+ val = ARITH3($1, value, j)
+ allInExtRange = allInExtRange .and. &
+ inRange3(val, var_type(i), &
+ NFT_ITYPE($1))
+9 continue
+ err = nf90mpi_iput_var(ncid, i, value,reqid(1), index, count, stride)
+ if (err .eq. NF90_NOERR .or. err .eq. NF90_ERANGE) &
+ err_w = nf90mpi_wait_all(ncid,1,reqid,st)
+ if (canConvert) then
+ if (allInExtRange) then
+ if (st(1) .ne. 0) &
+ call error(nf90mpi_strerror(st(1)))
+ else
+ if (err .ne. NF90_ERANGE) &
+ call errore('range error: ', err)
+ end if
+ else
+ if (nels .gt. 0 .and. err .ne. NF90_ECHAR) &
+ call errore('wrong type: ', err)
+ end if
+7 continue
+5 continue
+1 continue
+
+ err = nf90mpi_close(ncid)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_close: ', err)
+
+ call check_vars_$1(scratch)
+
+ err = nf90mpi_delete(scratch, info)
+ if (err .ne. NF90_NOERR) &
+ call errorc('delete of scratch file failed:', &
+ scratch)
+ end
+])dnl
+
+
+dnl since parallel-netcdf doesn't have varm type, we haven't completed the
+dnl parallel-netcdf-ification of these routines
+dnl TEST_NFMPI_IPUT_VARM(TYPE)
+dnl
+define([TEST_NFMPI_IPUT_VARM],dnl
+[dnl
+ subroutine test_nf90mpi_iput_varm_$1()
+ use pnetcdf
+ implicit none
+#include "tests.inc"
+ integer roll, index2indexes
+ double precision hash_$1
+ logical inRange3
+
+ integer ncid
+ integer d
+ integer i
+ integer j
+ integer k
+ integer m
+ integer err, flags
+ integer(kind=MPI_OFFSET_KIND) nels
+ integer nslabs
+ integer(kind=MPI_OFFSET_KIND) nstarts !/* number of different starts */
+ integer(kind=MPI_OFFSET_KIND) start(MAX_RANK)
+ integer(kind=MPI_OFFSET_KIND) edge(MAX_RANK)
+ integer(kind=MPI_OFFSET_KIND) index(MAX_RANK)
+ integer(kind=MPI_OFFSET_KIND) index2(MAX_RANK)
+ integer(kind=MPI_OFFSET_KIND) mid(MAX_RANK)
+ integer(kind=MPI_OFFSET_KIND) count(MAX_RANK)
+ integer(kind=MPI_OFFSET_KIND) sstride(MAX_RANK)
+ integer(kind=MPI_OFFSET_KIND) stride(MAX_RANK)
+ integer(kind=MPI_OFFSET_KIND) imap(MAX_RANK)
+ logical canConvert !/* Both text or both numeric */
+ logical allInExtRange !/* all values within external range? */
+ DATATYPE($1, value, (MAX_NELS))
+ doubleprecision val
+ integer ud_shift
+ integer err_w, reqid(1), st(1)
+
+ flags = IOR(NF90_CLOBBER, extra_flags)
+ err = nf90mpi_create(comm, scratch, flags, info, &
+ ncid)
+ if (err .ne. NF90_NOERR) then
+ call errore('nf90mpi_create: ', err)
+ return
+ end if
+ call def_dims(ncid)
+ call def_vars(ncid)
+ err = nf90mpi_enddef(ncid)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_enddef: ', err)
+
+ do 1, i = 1, numVars
+ canConvert = (var_type(i) .eq. NF90_CHAR) .eqv. &
+ (NFT_ITYPE($1) .eq. NFT_TEXT)
+ if (.not.(var_rank(i) .le. MAX_RANK)) &
+ stop 'assert(var_rank(i) .le. MAX_RANK)'
+ if (.not.(var_nels(i) .le. MAX_NELS)) &
+ stop 'assert(var_nels(i) .le. MAX_NELS)'
+ do 2, j = 1, var_rank(i)
+ start(j) = 1
+ edge(j) = 1
+ stride(j) = 1
+ imap(j) = 1
+2 continue
+ err = nf90mpi_iput_var(BAD_ID, i, value,reqid(1), start, edge, stride, imap)
+ if (err .ne. NF90_EBADID) &
+ call errore('bad ncid: ', err)
+ err = nf90mpi_iput_var(ncid, BAD_VARID, &
+ value,reqid(1), start, edge, stride, imap)
+ if (err .ne. NF90_ENOTVAR) &
+ call errore('bad var id: ', err)
+ do 3, j = 1, var_rank(i)
+ if (var_dimid(j,i) .ne. RECDIM) then !/* skip record dim */
+ start(j) = var_shape(j,i) + 1
+ err = nf90mpi_iput_var(ncid, i, &
+ value,reqid(1), start, edge, stride, imap)
+ if (err .eq. NF90_NOERR .or. err .eq. NF90_ERANGE) &
+ err_w = nf90mpi_wait_all(ncid,1,reqid,st)
+ if (.not. canConvert) then
+ if (err .ne. NF90_ECHAR) &
+ call errore('conversion: ', err)
+ else
+ if (err .ne. NF90_EINVALCOORDS) &
+ call errore('bad start: ', err)
+ endif
+ start(j) = 1
+ edge(j) = var_shape(j,i) + 1
+ err = nf90mpi_iput_var(ncid, i, &
+ value,reqid(1), start, edge, stride, imap)
+ if (err .eq. NF90_NOERR .or. err .eq. NF90_ERANGE) &
+ err_w = nf90mpi_wait_all(ncid,1,reqid,st)
+ if (.not. canConvert) then
+ if (err .ne. NF90_ECHAR) &
+ call errore('conversion: ', err)
+ else
+ if (err .ne. NF90_EEDGE) &
+ call errore('bad edge: ', err)
+ endif
+ edge(j) = 1
+ stride(j) = 0
+ err = nf90mpi_iput_var(ncid, i, &
+ value,reqid(1), start, edge, stride, imap)
+ if (err .eq. NF90_NOERR .or. err .eq. NF90_ERANGE) &
+ err_w = nf90mpi_wait_all(ncid,1,reqid,st)
+ if (.not. canConvert) then
+ if (err .ne. NF90_ECHAR) &
+ call errore('conversion: ', err)
+ else
+ if (err .ne. NF90_ESTRIDE) &
+ call errore('bad stride: ', err)
+ endif
+ stride(j) = 1
+ end if
+3 continue
+ !/* Choose a random point dividing each dim into 2 parts */
+ !/* Put 2^rank (nslabs) slabs so defined */
+ nslabs = 1
+ do 4, j = 1, var_rank(i)
+ mid(j) = roll( var_shape(j,i) )
+ nslabs = nslabs * 2
+4 continue
+ !/* bits of k determine whether to put lower or upper part of dim */
+ !/* choose random stride from 1 to edge */
+ do 5, k = 1, nslabs
+ nstarts = 1
+ do 6, j = 1, var_rank(i)
+ if (mod(ud_shift(k-1, -(j-1)), 2) .eq. 1) then
+ start(j) = 1
+ edge(j) = mid(j)
+ else
+ start(j) = 1 + mid(j)
+ edge(j) = var_shape(j,i) - mid(j)
+ end if
+ if (edge(j) .gt. 0) then
+ stride(j) = 1+roll(edge(j))
+ else
+ stride(j) = 1
+ end if
+ sstride(j) = stride(j)
+ nstarts = nstarts * stride(j)
+6 continue
+ do 7, m = 1, INT(nstarts)
+ err = index2indexes(m, var_rank(i), sstride, index)
+ if (err .ne. NF90_NOERR) &
+ call error('error in index2indexes')
+ nels = 1
+ do 8, j = 1, var_rank(i)
+ count(j) = 1 + (edge(j) - index(j)) / stride(j)
+ nels = nels * count(j)
+ index(j) = index(j) + start(j) - 1
+8 continue
+ !/* Random choice of forward or backward */
+! TODO
+! if ( roll(2) ) then
+! do 9, j = 1, var_rank(i)
+! index(j) = index(j) + &
+! (count(j) - 1) * stride(j)
+! stride(j) = -stride(j)
+!9 continue
+! end if
+!
+ if (var_rank(i) .gt. 0) then
+ imap(1) = 1
+ do 10, j = 2, var_rank(i)
+ imap(j) = imap(j-1) * count(j-1)
+10 continue
+ end if
+ allInExtRange = .true.
+ do 11 j = 1, INT(nels)
+ err = index2indexes(j, var_rank(i), count, &
+ index2)
+ if (err .ne. NF90_NOERR) &
+ call error('error in index2indexes')
+ do 12, d = 1, var_rank(i)
+ index2(d) = index(d) + &
+ (index2(d)-1) * stride(d)
+12 continue
+ val = hash_$1(var_type(i),var_rank(i), &
+ index2, NFT_ITYPE($1))
+ MAKE_TYPE2($1, VAR_ELEM($1, value, j), val)
+ val = ARITH3($1, value, j)
+ allInExtRange = allInExtRange .and. &
+ inRange3(val, var_type(i), &
+ NFT_ITYPE($1))
+11 continue
+ err = nf90mpi_iput_var(ncid,i,&
+ value,reqid(1), index, count, stride, imap)
+ if (err .eq. NF90_NOERR .or. err .eq. NF90_ERANGE) &
+ err_w = nf90mpi_wait_all(ncid,1,reqid,st)
+ if (canConvert) then
+ if (allInExtRange) then
+ if (st(1) .ne. 0) &
+ call error(nf90mpi_strerror(st(1)))
+ else
+ if (err .ne. NF90_ERANGE) &
+ call errore('range error: ', err)
+ end if
+ else
+ if (nels .gt. 0 .and. err .ne. NF90_ECHAR) &
+ call errore('wrong type: ', err)
+ end if
+7 continue
+5 continue
+1 continue
+
+ err = nf90mpi_close(ncid)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_close: ', err)
+
+ call check_vars_$1(scratch)
+
+ err = nf90mpi_delete(scratch, info)
+ if (err .ne. NF90_NOERR) &
+ call errorc('delete of scratch file failed:', &
+ scratch)
+ end
+])dnl
+
+
+divert(0)dnl
+dnl If you see this line, you can ignore the next one.
+! Do not edit this file. It is produced from the corresponding .m4 source */
+
+!
+! Copyright (C) 2013, Northwestern University and Argonne National Laboratory
+! See COPYRIGHT notice in top-level directory.
+!
+
+TEST_NFMPI_IPUT_VAR1(text)
+#ifdef NF_INT1_T
+TEST_NFMPI_IPUT_VAR1(int1)
+#endif
+#ifdef NF_INT2_T
+TEST_NFMPI_IPUT_VAR1(int2)
+#endif
+TEST_NFMPI_IPUT_VAR1(int)
+TEST_NFMPI_IPUT_VAR1(int8)
+TEST_NFMPI_IPUT_VAR1(real)
+TEST_NFMPI_IPUT_VAR1(double)
+
+TEST_NFMPI_IPUT_VAR(text)
+#ifdef NF_INT1_T
+TEST_NFMPI_IPUT_VAR(int1)
+#endif
+#ifdef NF_INT2_T
+TEST_NFMPI_IPUT_VAR(int2)
+#endif
+TEST_NFMPI_IPUT_VAR(int)
+TEST_NFMPI_IPUT_VAR(int8)
+TEST_NFMPI_IPUT_VAR(real)
+TEST_NFMPI_IPUT_VAR(double)
+
+TEST_NFMPI_IPUT_VARA(text)
+#ifdef NF_INT1_T
+TEST_NFMPI_IPUT_VARA(int1)
+#endif
+#ifdef NF_INT2_T
+TEST_NFMPI_IPUT_VARA(int2)
+#endif
+TEST_NFMPI_IPUT_VARA(int)
+TEST_NFMPI_IPUT_VARA(int8)
+TEST_NFMPI_IPUT_VARA(real)
+TEST_NFMPI_IPUT_VARA(double)
+
+TEST_NFMPI_IPUT_VARS(text)
+#ifdef NF_INT1_T
+TEST_NFMPI_IPUT_VARS(int1)
+#endif
+#ifdef NF_INT2_T
+TEST_NFMPI_IPUT_VARS(int2)
+#endif
+TEST_NFMPI_IPUT_VARS(int)
+TEST_NFMPI_IPUT_VARS(int8)
+TEST_NFMPI_IPUT_VARS(real)
+TEST_NFMPI_IPUT_VARS(double)
+
+TEST_NFMPI_IPUT_VARM(text)
+#ifdef NF_INT1_T
+TEST_NFMPI_IPUT_VARM(int1)
+#endif
+#ifdef NF_INT2_T
+TEST_NFMPI_IPUT_VARM(int2)
+#endif
+TEST_NFMPI_IPUT_VARM(int)
+TEST_NFMPI_IPUT_VARM(int8)
+TEST_NFMPI_IPUT_VARM(real)
+TEST_NFMPI_IPUT_VARM(double)
diff --git a/test/nf90_test/test_put.m4 b/test/nf90_test/test_put.m4
new file mode 100644
index 0000000..a1c9733
--- /dev/null
+++ b/test/nf90_test/test_put.m4
@@ -0,0 +1,1518 @@
+dnl
+dnl Copyright (C) 2013, Northwestern University and Argonne National Laboratory
+dnl See COPYRIGHT notice in top-level directory.
+dnl
+dnl $Id: test_put.m4 2156 2015-10-12 01:15:25Z wkliao $
+dnl
+
+divert(-1)
+
+dnl This is m4 source.
+dnl Process using m4 to produce FORTRAN language file.
+
+changequote([,]) dnl
+
+undefine([index])dnl
+
+dnl Macros
+
+dnl Upcase(str)
+dnl
+define([Upcase],[dnl
+translit($1, abcdefghijklmnopqrstuvwxyz, ABCDEFGHIJKLMNOPQRSTUVWXYZ)])
+
+dnl NFT_ITYPE(type)
+dnl
+define([NFT_ITYPE], [NFT_[]Upcase($1)])
+
+dnl ARITH3(itype, value)
+dnl
+define([ARITH3], [ifelse($1, text, ichar($2($3:$3)), $2($3))])
+
+dnl VALUE3(itype, value)
+dnl
+define([VALUE3], [ifelse($1, text, $2(1:nels), $2(1:nels))])
+
+dnl VAR_ELEM(itype, value)
+dnl
+define([VAR_ELEM], [ifelse($1, text, $2($3:$3), $2($3))])
+
+dnl ARITH_VAR1(itype, value)
+dnl
+define([ARITH_VAR1], [ifelse($1, text, ichar($2(1:1)), $2(1))])
+
+dnl DATATYPE(funf_suffix)
+dnl
+define([DATATYPE], [dnl
+ifelse($1, text, character(len=$3) $2,
+ifelse($1, int1, NF_INT1_T $2($3),
+ifelse($1, int2, NF_INT2_T $2($3),
+ifelse($1, int, integer $2($3),
+ifelse($1, int8, NF_INT8_T $2($3),
+ifelse($1, real, real $2($3),
+ifelse($1, double, doubleprecision $2($3))[]dnl
+)[]dnl
+)[]dnl
+)[]dnl
+)[]dnl
+)[]dnl
+)[]dnl
+])
+
+dnl DATATYPE_VAR1(funf_suffix)
+dnl
+define([DATATYPE_VAR1], [dnl
+ifelse($1, text, character(len=1) $2,
+ifelse($1, int1, NF_INT1_T $2(1),
+ifelse($1, int2, NF_INT2_T $2(1),
+ifelse($1, int, integer $2(1),
+ifelse($1, int8, NF_INT8_T $2(1),
+ifelse($1, real, real $2(1),
+ifelse($1, double, doubleprecision $2(1))[]dnl
+)[]dnl
+)[]dnl
+)[]dnl
+)[]dnl
+)[]dnl
+)[]dnl
+])
+
+dnl ATTDATATYPE(funf_suffix)
+dnl
+define([ATTDATATYPE], [dnl
+dnl ifelse($1, text, character(len=MAX_NELS) $2,
+ifelse($1, text, character(len=$3) $2,
+ifelse($1, int1, NF_INT1_T $2($3),
+ifelse($1, int2, NF_INT2_T $2($3),
+ifelse($1, int, integer $2($3),
+ifelse($1, int8, NF_INT8_T $2($3),
+ifelse($1, real, real $2($3),
+ifelse($1, double, doubleprecision $2($3))[]dnl
+)[]dnl
+)[]dnl
+)[]dnl
+)[]dnl
+)[]dnl
+)[]dnl
+])
+
+dnl MAKE_ARITH_VAR1(funf_suffix, var)
+dnl
+define([MAKE_ARITH_VAR1], [dnl
+ifelse($1, text, ichar($2(1:1)), $2(1))[]dnl
+])
+
+dnl MAKE_ARITH3(funf_suffix, var)
+dnl
+define([MAKE_ARITH3], [dnl
+ifelse($1, text, ichar($2($3:$3)), $2($3))[]dnl
+])
+
+dnl MAKE_DOUBLE(funf_suffix, var)
+dnl
+define([MAKE_DOUBLE], [dnl
+ifelse($1, text, dble(ichar($2)), dble($2))[]dnl
+])
+
+dnl MAKE_TYPE(funf_suffix, var)
+dnl
+define([MAKE_TYPE], [dnl
+ifelse($1, text, char(int($2)),
+ ifelse($1, int, INT($2),
+ ifelse($1, int1, INT($2,KIND=INT1_KIND),
+ ifelse($1, int2, INT($2,KIND=INT2_KIND),
+ ifelse($1, int8, INT($2,KIND=INT8_KIND),
+ ifelse($1, real, REAL($2),
+ $2))))))[]dnl
+])
+
+dnl MAKE_TYPE2(funf_suffix, var_dest, var_src)
+dnl
+define([MAKE_TYPE2], [dnl
+ifelse($1, text, $2 = char(int($3)),
+ ifelse($1, int, $2 = INT($3),
+ ifelse($1, int1, $2 = INT($3,KIND=INT1_KIND),
+ ifelse($1, int2, $2 = INT($3,KIND=INT2_KIND),
+ ifelse($1, int8,
+ if ($3 .EQ. X_INT8_MAX) then
+ $2 = X_INT8_MAX
+ else
+ $2 = INT($3,KIND=INT8_KIND)
+ endif,
+ ifelse($1, real, $2 = REAL($3),
+ $2 = $3))))))[]dnl
+])
+
+
+dnl HASH(TYPE)
+dnl
+define([HASH],
+[dnl
+!
+! ensure hash value within range for internal TYPE
+!
+ doubleprecision function hash_$1(type, rank, index, itype)
+ use pnetcdf
+ implicit none
+#include "tests.inc"
+ integer type
+ integer rank
+ integer(kind=MPI_OFFSET_KIND) index(1)
+ integer itype
+ doubleprecision minimum
+ doubleprecision maximum
+ doubleprecision internal_min, internal_max, hash4
+
+ minimum = internal_min(itype)
+ maximum = internal_max(itype)
+
+ hash_$1 = max(minimum, min(maximum, hash4( type, rank, &
+ index, itype)))
+ end
+])dnl
+
+
+dnl CHECK_VARS(TYPE)
+dnl
+define([CHECK_VARS],dnl
+[dnl
+!
+! check all vars in file which are (text/numeric) compatible with TYPE
+!
+ subroutine check_vars_$1(filename)
+ use pnetcdf
+ implicit none
+#include "tests.inc"
+ integer index2indexes
+ double precision hash4
+ logical equal, inRange3, in_internal_range
+
+ character*(*) filename
+ integer ncid ! netCDF id
+ integer(kind=MPI_OFFSET_KIND) index(MAX_RANK)
+ integer err
+ integer d
+ integer i
+ integer j
+ DATATYPE_VAR1($1, value)
+ integer datatype
+ integer ndims
+ integer dimids(MAX_RANK)
+ integer ngatts
+ doubleprecision expect
+ character*(NF90_MAX_NAME) name
+ integer(kind=MPI_OFFSET_KIND) length
+ logical canConvert ! Both text or both numeric
+ integer nok ! count of valid comparisons
+ doubleprecision val
+ integer intindex
+
+ nok = 0
+
+ err = nf90mpi_open(comm, filename, NF90_NOWRITE, info, &
+ ncid)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_open: ', err)
+ err = nf90mpi_begin_indep_data(ncid)
+ do 1, i = 1, numVars
+ canConvert = (var_type(i) .eq. NF90_CHAR) .eqv. &
+ (NFT_ITYPE($1) .eq. NFT_TEXT)
+ if (canConvert) then
+ err = nf90mpi_inquire_variable(ncid, i, name, datatype, ndims, &
+ dimids, ngatts)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_inquire_variable: ', err)
+ if (name .ne. var_name(i)) &
+ call error('Unexpected var_name')
+ if (datatype .ne. var_type(i)) &
+ call error('Unexpected type')
+ if (ndims .ne. var_rank(i)) &
+ call error('Unexpected rank')
+ do 2, j = 1, ndims
+ err = nf90mpi_inquire_dimension(ncid, dimids(j), name, &
+ length)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_inquire_dimension: ', err)
+ if (length .ne. var_shape(j,i)) &
+ call error('Unexpected shape')
+2 continue
+ do 3, j = 1, var_nels(i)
+ err = index2indexes(j, var_rank(i), var_shape(1,i), &
+ index)
+ if (err .ne. NF90_NOERR) &
+ call error('error in index2indexes()')
+ expect = hash4( var_type(i), var_rank(i), index, &
+ NFT_ITYPE($1))
+ err = nf90mpi_get_var(ncid, i, value, index)
+ if (inRange3(expect,datatype,NFT_ITYPE($1))) then
+ if (in_internal_range(NFT_ITYPE($1), expect)) then
+ if (err .ne. NF90_NOERR) then
+ call errore &
+ ('nf90mpi_get_var: ', err)
+ else
+ val = MAKE_ARITH_VAR1($1,value)
+ if (.not.equal( &
+ val, &
+ expect,var_type(i), &
+ NFT_ITYPE($1))) then
+ call error( &
+ 'Var value read not that expected')
+ if (verbose) then
+ call error(' ')
+ call errori('varid: %d', i)
+ call errorc('var_name: ', &
+ var_name(i))
+ call error('index:')
+ do 4, d = 1, var_rank(i)
+ intindex = INT(index(d))
+ call errori(' ', intindex)
+4 continue
+ call errord('expect: ', expect)
+ call errord('got: ', val)
+ end if
+ else
+ nok = nok + 1
+ end if
+ end if
+ end if
+ end if
+3 continue
+ end if
+1 continue
+ err = nf90mpi_end_indep_data(ncid)
+ err = nf90mpi_close (ncid)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_close: ', err)
+ call print_nok(nok)
+ end
+])dnl
+
+
+dnl CHECK_ATTS(TYPE) numeric only
+dnl
+define([CHECK_ATTS],dnl
+[dnl
+!
+! check all attributes in file which are (text/numeric) compatible with TYPE
+! ignore any attributes containing values outside range of TYPE
+!
+ subroutine check_atts_$1(ncid)
+ use pnetcdf
+ implicit none
+#include "tests.inc"
+ character*2 ATT_NAME
+ integer ATT_TYPE, NATTS, ATT_LEN
+ double precision hash4
+ logical equal, inRange3, in_internal_range
+
+ integer ncid
+ integer err
+ integer i
+ integer j
+ integer k
+ integer(kind=MPI_OFFSET_KIND) ndx(1)
+ ATTDATATYPE($1, value, MAX_NELS)
+ integer datatype
+ doubleprecision expect(MAX_NELS)
+ integer(kind=MPI_OFFSET_KIND) length
+ integer nInExtRange !/* number values within external range */
+ integer nInIntRange !/* number values within internal range */
+ logical canConvert !/* Both text or both numeric */
+ integer nok !/* count of valid comparisons */
+ doubleprecision val
+
+ nok = 0
+
+ do 1, i = 0, numVars
+ do 2, j = 1, NATTS(i)
+ canConvert = (ATT_TYPE(j,i) .eq. NF90_CHAR) .eqv. &
+ (NFT_ITYPE($1) .eq. NFT_TEXT)
+ if (canConvert) then
+ err = nf90mpi_inquire_attribute(ncid, i, ATT_NAME(j,i), &
+ datatype, length)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_inquire_attribute: ', err)
+ if (datatype .ne. ATT_TYPE(j,i)) &
+ call error('nf90mpi_inquire_attribute: unexpected type')
+ if (length .ne. ATT_LEN(j,i)) &
+ call error('nf90mpi_inquire_attribute: unexpected length')
+ if (.not.(length .le. MAX_NELS)) &
+ stop 'assert(length .le. MAX_NELS)'
+ nInIntRange = 0
+ nInExtRange = 0
+ do 4, k = 1, INT(length)
+ ndx(1) = k
+ expect(k) = hash4( datatype, -1, ndx, &
+ NFT_ITYPE($1))
+ if (inRange3(expect(k), datatype, &
+ NFT_ITYPE($1))) then
+ nInExtRange = nInExtRange + 1
+ if (in_internal_range(NFT_ITYPE($1), &
+ expect(k))) &
+ nInIntRange = nInIntRange + 1
+ end if
+4 continue
+ err = nf90mpi_get_att(ncid, i, ATT_NAME(j,i), value)
+ if (nInExtRange .eq. length .and. &
+ nInIntRange .eq. length) then
+ if (err .ne. NF90_NOERR) &
+ call error(nf90mpi_strerror(err))
+ else
+ if (err .ne. NF90_NOERR .and. err .ne. NF90_ERANGE) &
+ call errore('OK or Range error: ', err)
+ end if
+ do 3, k = 1, INT(length)
+ if (inRange3(expect(k),datatype,NFT_ITYPE($1)) &
+ .and. &
+ in_internal_range(NFT_ITYPE($1), &
+ expect(k))) then
+ val = MAKE_ARITH3($1,value,k)
+ if (.not.equal( &
+ val, &
+ expect(k),datatype, &
+ NFT_ITYPE($1))) then
+ call error( &
+ 'att. value read not that expected')
+ if (verbose) then
+ call error(' ')
+ call errori('varid: ', i)
+ call errorc('att_name: ', &
+ ATT_NAME(j,i))
+ call errori('element number: ', k)
+ call errord('expect: ', expect(k))
+ call errord('got: ', val)
+ end if
+ else
+ nok = nok + 1
+ end if
+ end if
+3 continue
+ end if
+2 continue
+1 continue
+
+ call print_nok(nok)
+ end
+])dnl
+
+
+dnl TEST_NFMPI_PUT_VAR1(TYPE)
+dnl
+define([TEST_NFMPI_PUT_VAR1],dnl
+[dnl
+ subroutine test_nf90mpi_put_var1_$1()
+ use pnetcdf
+ implicit none
+#include "tests.inc"
+ integer index2indexes
+ double precision hash_$1
+ logical inRange3
+
+ integer ncid
+ integer i
+ integer j
+ integer err, flags
+ integer(kind=MPI_OFFSET_KIND) index(MAX_RANK)
+ logical canConvert !/* Both text or both numeric */
+ DATATYPE_VAR1($1, value)
+ doubleprecision val
+
+ value = MAKE_TYPE($1, 5)!/* any value would do - only for error cases */
+
+ flags = IOR(NF90_CLOBBER, extra_flags)
+ err = nf90mpi_create(comm, scratch, flags, info, &
+ ncid)
+ if (err .ne. NF90_NOERR) then
+ call errore('nf90mpi_create: ', err)
+ return
+ end if
+ call def_dims(ncid)
+ call def_vars(ncid)
+ err = nf90mpi_enddef(ncid)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_enddef: ', err)
+ err = nf90mpi_begin_indep_data(ncid)
+ do 1, i = 1, numVars
+ canConvert = (var_type(i) .eq. NF90_CHAR) .eqv. &
+ (NFT_ITYPE($1) .eq. NFT_TEXT)
+ do 2, j = 1, var_rank(i)
+ index(j) = 1
+2 continue
+ err = nf90mpi_put_var(BAD_ID, i, value(1:1), index)
+ if (err .ne. NF90_EBADID) &
+ call errore('bad ncid: ', err)
+ err = nf90mpi_put_var(ncid, BAD_VARID, value(1:1), index)
+ if (err .ne. NF90_ENOTVAR) &
+ call errore('bad var id: ', err)
+ do 3, j = 1, var_rank(i)
+ if (var_dimid(j,i) .gt. 1) then !/* skip record dim */
+ index(j) = var_shape(j,i) + 1
+ err = nf90mpi_put_var(ncid, i, value(1:1), index)
+ if (.not. canConvert) then
+ if (err .ne. NF90_ECHAR) &
+ call errore('conversion: ', err)
+ else
+ if (err .ne. NF90_EINVALCOORDS) &
+ call errore('bad index: ', err)
+ endif
+ index(j) = 0
+ end if
+3 continue
+ do 4, j = 1, var_nels(i)
+ err = index2indexes(j, var_rank(i), var_shape(1,i), index)
+ if (err .ne. NF90_NOERR) &
+ call error('error in index2indexes 1')
+ val = hash_$1(var_type(i),var_rank(i), &
+ index, NFT_ITYPE($1))
+ MAKE_TYPE2($1, value, val)
+ err = nf90mpi_put_var(ncid, i, value(1:1), index)
+ if (canConvert) then
+ val = ARITH_VAR1($1, value)
+ if (inRange3(val, var_type(i), NFT_ITYPE($1))) then
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_put_var: ', err)
+ else
+ if (err .ne. NF90_ERANGE) &
+ call errore('Range error: ', err)
+ end if
+ else
+ if (err .ne. NF90_ECHAR) &
+ call errore('wrong type: ', err)
+ end if
+4 continue
+1 continue
+ err = nf90mpi_end_indep_data(ncid)
+ err = nf90mpi_close(ncid)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_close: ', err)
+
+ call check_vars_$1(scratch)
+
+ err = nf90mpi_delete(scratch, info)
+ if (err .ne. NF90_NOERR) &
+ call errorc('delete of scratch file failed: ', &
+ scratch)
+ end
+])dnl
+
+
+dnl TEST_NFMPI_PUT_VAR(TYPE)
+dnl
+define([TEST_NFMPI_PUT_VAR],dnl
+[dnl
+ subroutine test_nf90mpi_put_var_$1()
+ use pnetcdf
+ implicit none
+#include "tests.inc"
+ integer index2indexes
+ double precision hash_$1
+ logical inRange3
+
+ integer ncid
+ integer vid
+ integer i
+ integer j
+ integer err, flags
+ integer(kind=MPI_OFFSET_KIND) nels
+ integer(kind=MPI_OFFSET_KIND) index(MAX_RANK)
+ logical canConvert !/* Both text or both numeric */
+ logical allInExtRange !/* All values within external range?*/
+ DATATYPE($1, value, MAX_NELS)
+ doubleprecision val
+
+ flags = IOR(NF90_CLOBBER, extra_flags)
+ err = nf90mpi_create(comm, scratch, flags, info, &
+ ncid)
+ if (err .ne. NF90_NOERR) then
+ call errore('nf90mpi_create: ', err)
+ return
+ end if
+ call def_dims(ncid)
+ call def_vars(ncid)
+ err = nf90mpi_enddef(ncid)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_enddef: ', err)
+ err = nf90mpi_begin_indep_data(ncid)
+ do 1, i = 1, numVars
+ canConvert = (var_type(i) .eq. NF90_CHAR) .eqv. &
+ (NFT_ITYPE($1) .eq. NFT_TEXT)
+ err = nf90mpi_put_var(BAD_ID, i, value)
+ if (err .ne. NF90_EBADID) &
+ call errore('bad ncid: ', err)
+ err = nf90mpi_put_var(ncid, BAD_VARID, value)
+ if (err .ne. NF90_ENOTVAR) &
+ call errore('bad var id: ', err)
+ nels = 1
+ do 3, j = 1, var_rank(i)
+ nels = nels * var_shape(j,i)
+3 continue
+ allInExtRange = .true.
+ do 4, j = 1, var_nels(i)
+ err = index2indexes(j, var_rank(i), var_shape(1,i), &
+ index)
+ if (err .ne. NF90_NOERR) &
+ call error('error in index2indexes 1')
+ val = hash_$1(var_type(i), var_rank(i), &
+ index, NFT_ITYPE($1))
+ MAKE_TYPE2($1, VAR_ELEM($1, value, j), val)
+ val = ARITH3($1, value, j)
+ allInExtRange = allInExtRange .and. &
+ inRange3(val, var_type(i), NFT_ITYPE($1))
+4 continue
+ err = nf90mpi_put_var(ncid, i, VALUE3($1, value), count=var_shape(:,i))
+ if (canConvert) then
+ if (allInExtRange) then
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_put_var: ', err)
+ else
+ if (err .ne. NF90_ERANGE .and. &
+ var_dimid(var_rank(i),i) .ne. RECDIM) &
+ call errore('Range error: ', err)
+ endif
+ else
+ if (err .ne. NF90_ECHAR) &
+ call errore('wrong type: ', err)
+ endif
+1 continue
+ err = nf90mpi_end_indep_data(ncid)
+
+! The preceeding has written nothing for record variables, now try
+! again with more than 0 records.
+
+! Write record number NRECS to force writing of preceding records.
+! Assumes variable cr is char vector with UNLIMITED dimension.
+
+ err = nf90mpi_inq_varid(ncid, "cr", vid)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_inq_varid: ', err)
+ index(1) = NRECS
+ err = nf90mpi_begin_indep_data(ncid)
+ err = nf90mpi_put_var(ncid, vid, 'x', index)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_put_var: ', err)
+
+ do 5 i = 1, numVars
+! Only test record variables here
+ if (var_rank(i) .ge. 1 .and. &
+ var_dimid(var_rank(i),i) .eq. RECDIM) then
+ canConvert = (var_type(i) .eq. NF90_CHAR) .eqv. &
+ (NFT_ITYPE($1) .eq. NFT_TEXT)
+ if (var_rank(i) .gt. MAX_RANK) &
+ stop 'var_rank(i) .gt. MAX_RANK'
+ if (var_nels(i) .gt. MAX_NELS) &
+ stop 'var_nels(i) .gt. MAX_NELS'
+
+ nels = 1
+ do 6 j = 1, var_rank(i)
+ nels = nels * var_shape(j,i)
+6 continue
+ allInExtRange = .true.
+ do 7, j = 1, INT(nels)
+ err = index2indexes(j, var_rank(i), var_shape(1,i), &
+ index)
+ if (err .ne. NF90_NOERR) &
+ call error('error in index2indexes()')
+ val = hash_$1(var_type(i), var_rank(i), &
+ index, NFT_ITYPE($1))
+ MAKE_TYPE2($1, VAR_ELEM($1, value, j), val)
+ val = ARITH3($1, value, j)
+ allInExtRange = allInExtRange .and. &
+ inRange3(val, var_type(i), NFT_ITYPE($1))
+7 continue
+ err = nf90mpi_put_var(ncid, i, value, count=var_shape(:,i))
+ if (canConvert) then
+ if (allInExtRange) then
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_put_var: ', err)
+ else
+ if (err .ne. NF90_ERANGE) &
+ call errore('range error: ', err)
+ endif
+ else
+ if (nels .gt. 0 .and. err .ne. NF90_ECHAR) &
+ call errore('wrong type: ', err)
+ endif
+ endif
+5 continue
+ err = nf90mpi_end_indep_data(ncid);
+ err = nf90mpi_close(ncid)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_close: ', err)
+
+ call check_vars_$1(scratch)
+
+ err = nf90mpi_delete(scratch, info)
+ if (err .ne. NF90_NOERR) &
+ call errorc('delete of scratch file failed: ', &
+ scratch)
+ end
+])dnl
+
+
+dnl TEST_NFMPI_PUT_VARA(TYPE)
+dnl
+define([TEST_NFMPI_PUT_VARA],dnl
+[dnl
+ subroutine test_nf90mpi_put_vara_$1()
+ use pnetcdf
+ implicit none
+#include "tests.inc"
+ integer index2indexes, roll
+ double precision hash_$1
+ logical inRange3
+
+ integer ncid
+ integer i
+ integer j
+ integer k
+ integer d
+ integer err, flags
+ integer nslabs
+ integer(kind=MPI_OFFSET_KIND) nels
+ integer(kind=MPI_OFFSET_KIND) start(MAX_RANK)
+ integer(kind=MPI_OFFSET_KIND) edge(MAX_RANK)
+ integer(kind=MPI_OFFSET_KIND) mid(MAX_RANK)
+ integer(kind=MPI_OFFSET_KIND) index(MAX_RANK)
+ logical canConvert !/* Both text or both numeric */
+ logical allInExtRange !/* all values within external range? */
+ DATATYPE($1, value, (MAX_NELS))
+ doubleprecision val
+ integer ud_shift
+
+ flags = IOR(NF90_CLOBBER, extra_flags)
+ err = nf90mpi_create(comm, scratch, flags, info, &
+ ncid)
+ if (err .ne. NF90_NOERR) then
+ call errore('nf90mpi_create: ', err)
+ return
+ end if
+ call def_dims(ncid)
+ call def_vars(ncid)
+ err = nf90mpi_enddef(ncid)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_enddef: ', err)
+
+ do 1, i = 1, numVars
+ canConvert = (var_type(i) .eq. NF90_CHAR) .eqv. &
+ (NFT_ITYPE($1) .eq. NFT_TEXT)
+ if (.not.(var_rank(i) .le. MAX_RANK)) &
+ stop 'assert(var_rank(i) .le. MAX_RANK)'
+ if (.not.(var_nels(i) .le. MAX_NELS)) &
+ stop 'assert(var_nels(i) .le. MAX_NELS)'
+ do 2, j = 1, var_rank(i)
+ start(j) = 1
+ edge(j) = 1
+2 continue
+ err = nf90mpi_put_var_all(BAD_ID, i, value, start, edge)
+ if (err .ne. NF90_EBADID) &
+ call errore('bad ncid: ', err)
+ err = nf90mpi_put_var_all(ncid, BAD_VARID, value, start, edge)
+ if (err .ne. NF90_ENOTVAR) &
+ call errore('bad var id: ', err)
+ do 3, j = 1, var_rank(i)
+ if (var_dimid(j,i) .ne. RECDIM) then !/* skip record dim */
+ start(j) = var_shape(j,i) + 1
+ err = nf90mpi_put_var_all(ncid, i, value, start, edge)
+ if (.not. canConvert) then
+ if (err .ne. NF90_ECHAR) &
+ call errore('conversion: ', err)
+ else
+ if (err .ne. NF90_EINVALCOORDS) &
+ call errore('bad start: ', err)
+ endif
+ start(j) = 1
+ edge(j) = var_shape(j,i) + 1
+ err = nf90mpi_put_var_all(ncid, i, value, start, edge)
+ if (.not. canConvert) then
+ if (err .ne. NF90_ECHAR) &
+ call errore('conversion: ', err)
+ else
+ if (err .ne. NF90_EEDGE) &
+ call errore('bad edge: ', err)
+ endif
+ edge(j) = 1
+ end if
+3 continue
+
+! /* Check correct error returned even when nothing to put */
+ do 20, j = 1, var_rank(i)
+ edge(j) = 0
+20 continue
+ err = nf90mpi_put_var_all(BAD_ID, i, value, start, edge)
+ if (err .ne. NF90_EBADID) &
+ call errore('bad ncid: ', err)
+ err = nf90mpi_put_var_all(ncid, BAD_VARID, value, start, edge)
+ if (err .ne. NF90_ENOTVAR) &
+ call errore('bad var id: ', err)
+ do 21, j = 1, var_rank(i)
+ if (var_dimid(j,i) .gt. 1) then ! skip record dim
+ start(j) = var_shape(j,i) + 1
+ err = nf90mpi_put_var_all(ncid, i, value, start, edge)
+ if (.not. canConvert) then
+ if (err .ne. NF90_ECHAR) &
+ call errore('conversion: ', err)
+ else
+ if (err .ne. NF90_EINVALCOORDS) &
+ call errore('bad start: ', err)
+ endif
+ start(j) = 1
+ endif
+21 continue
+
+! wkliao: this test below of put_vara is redundant and incorrectly uses the
+! value[] set from the previously iteration. There is no such test
+! in put_vars and put_varm.
+!
+! err = nf90mpi_put_var_all(ncid, i, value, start, edge)
+! if (canConvert) then
+! if (err .ne. NF90_NOERR) &
+! call error(nf90mpi_strerror(err))
+! else
+! if (err .ne. NF90_ECHAR) &
+! call errore('wrong type: ', err)
+! endif
+
+ do 22, j = 1, var_rank(i)
+ edge(j) = 1
+22 continue
+
+
+ !/* Choose a random point dividing each dim into 2 parts */
+ !/* Put 2^rank (nslabs) slabs so defined */
+ nslabs = 1
+ do 4, j = 1, var_rank(i)
+ mid(j) = roll( var_shape(j,i) )
+ nslabs = nslabs * 2
+4 continue
+ !/* bits of k determine whether to put lower or upper part of dim */
+ do 5, k = 1, nslabs
+ nels = 1
+ do 6, j = 1, var_rank(i)
+ if (mod(ud_shift(k-1, -(j-1)), 2) .eq. 1) then
+ start(j) = 1
+ edge(j) = mid(j)
+ else
+ start(j) = 1 + mid(j)
+ edge(j) = var_shape(j,i) - mid(j)
+ end if
+ nels = nels * edge(j)
+6 continue
+ allInExtRange = .true.
+ do 7, j = 1, INT(nels)
+ err = index2indexes(j, var_rank(i), edge, index)
+ if (err .ne. NF90_NOERR) &
+ call error('error in index2indexes 1')
+ do 8, d = 1, var_rank(i)
+ index(d) = index(d) + start(d) - 1
+8 continue
+ val = hash_$1(var_type(i), var_rank(i), &
+ index, NFT_ITYPE($1))
+ MAKE_TYPE2($1, VAR_ELEM($1, value, j), val)
+ val = ARITH3($1, value, j)
+ allInExtRange = allInExtRange .and. &
+ inRange3(val, var_type(i), NFT_ITYPE($1))
+7 continue
+ err = nf90mpi_put_var_all(ncid, i, value, start, edge)
+ if (canConvert) then
+ if (allInExtRange) then
+ if (err .ne. NF90_NOERR) &
+ call error(nf90mpi_strerror(err))
+ else
+ if (err .ne. NF90_ERANGE) &
+ call errore('range error: ', err)
+ end if
+ else
+ if (nels .gt. 0 .and. err .ne. NF90_ECHAR) &
+ call errore('wrong type: ', err)
+ end if
+5 continue
+1 continue
+
+ err = nf90mpi_close(ncid)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_close: ', err)
+
+ call check_vars_$1(scratch)
+
+ err = nf90mpi_delete(scratch, info)
+ if (err .ne. NF90_NOERR) &
+ call errorc('delete of scratch file failed: ', &
+ scratch)
+ end
+])dnl
+
+
+dnl TEST_NFMPI_PUT_VARS(TYPE)
+dnl
+define([TEST_NFMPI_PUT_VARS],dnl
+[dnl
+ subroutine test_nf90mpi_put_vars_$1()
+ use pnetcdf
+ implicit none
+#include "tests.inc"
+ double precision hash_$1
+ logical inRange3
+ integer roll, index2indexes
+
+ integer ncid
+ integer d
+ integer i
+ integer j
+ integer k
+ integer m
+ integer err, flags
+ integer(kind=MPI_OFFSET_KIND) nels
+ integer nslabs
+ integer(kind=MPI_OFFSET_KIND) nstarts !/* number of different starts */
+ integer(kind=MPI_OFFSET_KIND) start(MAX_RANK)
+ integer(kind=MPI_OFFSET_KIND) edge(MAX_RANK)
+ integer(kind=MPI_OFFSET_KIND) index(MAX_RANK)
+ integer(kind=MPI_OFFSET_KIND) index2(MAX_RANK)
+ integer(kind=MPI_OFFSET_KIND) mid(MAX_RANK)
+ integer(kind=MPI_OFFSET_KIND) count(MAX_RANK)
+ integer(kind=MPI_OFFSET_KIND) sstride(MAX_RANK)
+ integer(kind=MPI_OFFSET_KIND) stride(MAX_RANK)
+ logical canConvert !/* Both text or both numeric */
+ logical allInExtRange !/* all values within external range? */
+ DATATYPE($1, value, (MAX_NELS))
+ doubleprecision val
+ integer ud_shift
+
+ flags = IOR(NF90_CLOBBER, extra_flags)
+ err = nf90mpi_create(comm, scratch, flags, info, &
+ ncid)
+ if (err .ne. NF90_NOERR) then
+ call errore('nf90mpi_create: ', err)
+ return
+ end if
+ call def_dims(ncid)
+ call def_vars(ncid)
+ err = nf90mpi_enddef(ncid)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_enddef: ', err)
+
+ do 1, i = 1, numVars
+ canConvert = (var_type(i) .eq. NF90_CHAR) .eqv. &
+ (NFT_ITYPE($1) .eq. NFT_TEXT)
+ if (.not.(var_rank(i) .le. MAX_RANK)) &
+ stop 'assert(var_rank(i) .le. MAX_RANK)'
+ if (.not.(var_nels(i) .le. MAX_NELS)) &
+ stop 'assert(var_nels(i) .le. MAX_NELS)'
+ do 2, j = 1, var_rank(i)
+ start(j) = 1
+ edge(j) = 1
+ stride(j) = 1
+2 continue
+ err = nf90mpi_put_var_all(BAD_ID, i, value, start, edge, stride)
+ if (err .ne. NF90_EBADID) &
+ call errore('bad ncid: ', err)
+ err = nf90mpi_put_var_all(ncid, BAD_VARID, value, start, edge, stride)
+ if (err .ne. NF90_ENOTVAR) &
+ call errore('bad var id: ', err)
+ do 3, j = 1, var_rank(i)
+ if (var_dimid(j,i) .ne. RECDIM) then ! skip record dim
+ start(j) = var_shape(j,i) + 1
+ err = nf90mpi_put_var_all(ncid, i, value, start, &
+ edge, stride)
+ if (.not. canConvert) then
+ if (err .ne. NF90_ECHAR) &
+ call errore('conversion: ', err)
+ else
+ if (err .ne. NF90_EINVALCOORDS) &
+ call errore('bad start: ', err)
+ endif
+ start(j) = 1
+ edge(j) = var_shape(j,i) + 1
+ err = nf90mpi_put_var_all(ncid, i, value, start, &
+ edge, stride)
+ if (.not. canConvert) then
+ if (err .ne. NF90_ECHAR) &
+ call errore('conversion: ', err)
+ else
+ if (err .ne. NF90_EEDGE) &
+ call errore('bad edge: ', err)
+ endif
+ edge(j) = 1
+ stride(j) = 0
+ err = nf90mpi_put_var_all(ncid, i, value, start, &
+ edge, stride)
+ if (.not. canConvert) then
+ if (err .ne. NF90_ECHAR) &
+ call errore('conversion: ', err)
+ else
+ if (err .ne. NF90_ESTRIDE) &
+ call errore('bad stride: ', err)
+ endif
+ stride(j) = 1
+ end if
+3 continue
+ !/* Choose a random point dividing each dim into 2 parts */
+ !/* Put 2^rank (nslabs) slabs so defined */
+ nslabs = 1
+ do 4, j = 1, var_rank(i)
+ mid(j) = roll( var_shape(j,i) )
+ nslabs = nslabs * 2
+4 continue
+ !/* bits of k determine whether to put lower or upper part of dim */
+ !/* choose random stride from 1 to edge */
+ do 5, k = 1, nslabs
+ nstarts = 1
+ do 6, j = 1, var_rank(i)
+ if (mod(ud_shift(k-1, -(j-1)), 2) .eq. 1) then
+ start(j) = 1
+ edge(j) = mid(j)
+ else
+ start(j) = 1 + mid(j)
+ edge(j) = var_shape(j,i) - mid(j)
+ end if
+ if (edge(j) .gt. 0) then
+ stride(j) = 1+roll(edge(j))
+ else
+ stride(j) = 1
+ end if
+ sstride(j) = stride(j)
+ nstarts = nstarts * stride(j)
+6 continue
+ do 7, m = 1, INT(nstarts)
+ err = index2indexes(m, var_rank(i), sstride, index)
+ if (err .ne. NF90_NOERR) &
+ call error('error in index2indexes')
+ nels = 1
+ do 8, j = 1, var_rank(i)
+ count(j) = 1 + (edge(j) - index(j)) / stride(j)
+ nels = nels * count(j)
+ index(j) = index(j) + start(j) - 1
+8 continue
+ !/* Random choice of forward or backward */
+! TODO
+! if ( roll(2) ) {
+! for (j = 1 j .lt. var_rank(i) j++) {
+! index(j) += (count(j) - 1) * stride(j)
+! stride(j) = -stride(j)
+! }
+! }
+!
+ allInExtRange = .true.
+ do 9, j = 1, INT(nels)
+ err = index2indexes(j, var_rank(i), count, &
+ index2)
+ if (err .ne. NF90_NOERR) &
+ call error('error in index2indexes')
+ do 10, d = 1, var_rank(i)
+ index2(d) = index(d) + &
+ (index2(d)-1) * stride(d)
+10 continue
+ val = hash_$1(var_type(i), var_rank(i), &
+ index2, NFT_ITYPE($1))
+ MAKE_TYPE2($1, VAR_ELEM($1, value, j), val)
+ val = ARITH3($1, value, j)
+ allInExtRange = allInExtRange .and. &
+ inRange3(val, var_type(i), &
+ NFT_ITYPE($1))
+9 continue
+ err = nf90mpi_put_var_all(ncid, i, value, index, &
+ count, stride)
+ if (canConvert) then
+ if (allInExtRange) then
+ if (err .ne. NF90_NOERR) &
+ call error(nf90mpi_strerror(err))
+ else
+ if (err .ne. NF90_ERANGE) &
+ call errore('range error: ', err)
+ end if
+ else
+ if (nels .gt. 0 .and. err .ne. NF90_ECHAR) &
+ call errore('wrong type: ', err)
+ end if
+7 continue
+5 continue
+1 continue
+
+ err = nf90mpi_close(ncid)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_close: ', err)
+
+ call check_vars_$1(scratch)
+
+ err = nf90mpi_delete(scratch, info)
+ if (err .ne. NF90_NOERR) &
+ call errorc('delete of scratch file failed:', &
+ scratch)
+ end
+])dnl
+
+
+dnl since parallel-netcdf doesn't have varm type, we haven't completed the
+dnl parallel-netcdf-ification of these routines
+dnl TEST_NFMPI_PUT_VARM(TYPE)
+dnl
+define([TEST_NFMPI_PUT_VARM],dnl
+[dnl
+ subroutine test_nf90mpi_put_varm_$1()
+ use pnetcdf
+ implicit none
+#include "tests.inc"
+ integer index2indexes, roll
+ double precision hash_$1
+ logical inRange3
+
+ integer ncid
+ integer d
+ integer i
+ integer j
+ integer k
+ integer m
+ integer err, flags
+ integer(kind=MPI_OFFSET_KIND) nels
+ integer nslabs
+ integer(kind=MPI_OFFSET_KIND) nstarts !/* number of different starts */
+ integer(kind=MPI_OFFSET_KIND) start(MAX_RANK)
+ integer(kind=MPI_OFFSET_KIND) edge(MAX_RANK)
+ integer(kind=MPI_OFFSET_KIND) index(MAX_RANK)
+ integer(kind=MPI_OFFSET_KIND) index2(MAX_RANK)
+ integer(kind=MPI_OFFSET_KIND) mid(MAX_RANK)
+ integer(kind=MPI_OFFSET_KIND) count(MAX_RANK)
+ integer(kind=MPI_OFFSET_KIND) sstride(MAX_RANK)
+ integer(kind=MPI_OFFSET_KIND) stride(MAX_RANK)
+ integer(kind=MPI_OFFSET_KIND) imap(MAX_RANK)
+ logical canConvert !/* Both text or both numeric */
+ logical allInExtRange !/* all values within external range? */
+ DATATYPE($1, value, (MAX_NELS))
+ doubleprecision val
+ integer ud_shift
+
+ flags = IOR(NF90_CLOBBER, extra_flags)
+ err = nf90mpi_create(comm, scratch, flags, info, &
+ ncid)
+ if (err .ne. NF90_NOERR) then
+ call errore('nf90mpi_create: ', err)
+ return
+ end if
+ call def_dims(ncid)
+ call def_vars(ncid)
+ err = nf90mpi_enddef(ncid)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_enddef: ', err)
+
+ do 1, i = 1, numVars
+ canConvert = (var_type(i) .eq. NF90_CHAR) .eqv. &
+ (NFT_ITYPE($1) .eq. NFT_TEXT)
+ if (.not.(var_rank(i) .le. MAX_RANK)) &
+ stop 'assert(var_rank(i) .le. MAX_RANK)'
+ if (.not.(var_nels(i) .le. MAX_NELS)) &
+ stop 'assert(var_nels(i) .le. MAX_NELS)'
+ do 2, j = 1, var_rank(i)
+ start(j) = 1
+ edge(j) = 1
+ stride(j) = 1
+ imap(j) = 1
+2 continue
+ err = nf90mpi_put_var_all(BAD_ID, i, value, start, &
+ edge, stride, imap)
+ if (err .ne. NF90_EBADID) &
+ call errore('bad ncid: ', err)
+ err = nf90mpi_put_var_all(ncid, BAD_VARID, value, start, &
+ edge, stride, imap)
+ if (err .ne. NF90_ENOTVAR) &
+ call errore('bad var id: ', err)
+ do 3, j = 1, var_rank(i)
+ if (var_dimid(j,i) .ne. RECDIM) then !/* skip record dim */
+ start(j) = var_shape(j,i) + 1
+ err = nf90mpi_put_var_all(ncid, i, value, start, &
+ edge, stride, imap)
+ if (.not. canConvert) then
+ if (err .ne. NF90_ECHAR) &
+ call errore('conversion: ', err)
+ else
+ if (err .ne. NF90_EINVALCOORDS) &
+ call errore('bad start: ', err)
+ endif
+ start(j) = 1
+ edge(j) = var_shape(j,i) + 1
+ err = nf90mpi_put_var_all(ncid, i, value, start, &
+ edge, stride, imap)
+ if (.not. canConvert) then
+ if (err .ne. NF90_ECHAR) &
+ call errore('conversion: ', err)
+ else
+ if (err .ne. NF90_EEDGE) &
+ call errore('bad edge: ', err)
+ endif
+ edge(j) = 1
+ stride(j) = 0
+ err = nf90mpi_put_var_all(ncid, i, value, start, &
+ edge, stride, imap)
+ if (.not. canConvert) then
+ if (err .ne. NF90_ECHAR) &
+ call errore('conversion: ', err)
+ else
+ if (err .ne. NF90_ESTRIDE) &
+ call errore('bad stride: ', err)
+ endif
+ stride(j) = 1
+ end if
+3 continue
+ !/* Choose a random point dividing each dim into 2 parts */
+ !/* Put 2^rank (nslabs) slabs so defined */
+ nslabs = 1
+ do 4, j = 1, var_rank(i)
+ mid(j) = roll( var_shape(j,i) )
+ nslabs = nslabs * 2
+4 continue
+ !/* bits of k determine whether to put lower or upper part of dim */
+ !/* choose random stride from 1 to edge */
+ do 5, k = 1, nslabs
+ nstarts = 1
+ do 6, j = 1, var_rank(i)
+ if (mod(ud_shift(k-1, -(j-1)), 2) .eq. 1) then
+ start(j) = 1
+ edge(j) = mid(j)
+ else
+ start(j) = 1 + mid(j)
+ edge(j) = var_shape(j,i) - mid(j)
+ end if
+ if (edge(j) .gt. 0) then
+ stride(j) = 1+roll(edge(j))
+ else
+ stride(j) = 1
+ end if
+ sstride(j) = stride(j)
+ nstarts = nstarts * stride(j)
+6 continue
+ do 7, m = 1, INT(nstarts)
+ err = index2indexes(m, var_rank(i), sstride, index)
+ if (err .ne. NF90_NOERR) &
+ call error('error in index2indexes')
+ nels = 1
+ do 8, j = 1, var_rank(i)
+ count(j) = 1 + (edge(j) - index(j)) / stride(j)
+ nels = nels * count(j)
+ index(j) = index(j) + start(j) - 1
+8 continue
+ !/* Random choice of forward or backward */
+! TODO
+! if ( roll(2) ) then
+! do 9, j = 1, var_rank(i)
+! index(j) = index(j) + &
+! (count(j) - 1) * stride(j)
+! stride(j) = -stride(j)
+!9 continue
+! end if
+!
+ if (var_rank(i) .gt. 0) then
+ imap(1) = 1
+ do 10, j = 2, var_rank(i)
+ imap(j) = imap(j-1) * count(j-1)
+10 continue
+ end if
+ allInExtRange = .true.
+ do 11 j = 1, INT(nels)
+ err = index2indexes(j, var_rank(i), count, &
+ index2)
+ if (err .ne. NF90_NOERR) &
+ call error('error in index2indexes')
+ do 12, d = 1, var_rank(i)
+ index2(d) = index(d) + &
+ (index2(d)-1) * stride(d)
+12 continue
+ val = hash_$1(var_type(i),var_rank(i), &
+ index2, NFT_ITYPE($1))
+ MAKE_TYPE2($1, VAR_ELEM($1, value, j), val)
+ val = ARITH3($1, value, j)
+ allInExtRange = allInExtRange .and. &
+ inRange3(val, var_type(i), &
+ NFT_ITYPE($1))
+11 continue
+ err = nf90mpi_put_var_all(ncid,i,value,index,count, &
+ stride,imap)
+ if (canConvert) then
+ if (allInExtRange) then
+ if (err .ne. NF90_NOERR) &
+ call error(nf90mpi_strerror(err))
+ else
+ if (err .ne. NF90_ERANGE) &
+ call errore('range error: ', err)
+ end if
+ else
+ if (nels .gt. 0 .and. err .ne. NF90_ECHAR) &
+ call errore('wrong type: ', err)
+ end if
+7 continue
+5 continue
+1 continue
+
+ err = nf90mpi_close(ncid)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_close: ', err)
+
+ call check_vars_$1(scratch)
+
+ err = nf90mpi_delete(scratch, info)
+ if (err .ne. NF90_NOERR) &
+ call errorc('delete of scratch file failed:', &
+ scratch)
+ end
+])dnl
+
+
+dnl TEST_NFMPI_PUT_ATT(TYPE) numeric only
+dnl
+define([TEST_NFMPI_PUT_ATT],dnl
+[dnl
+ subroutine test_nf90mpi_put_att_$1()
+ use pnetcdf
+ implicit none
+#include "tests.inc"
+ character*2 ATT_NAME
+ integer ATT_TYPE, NATTS, ATT_LEN
+ integer(kind=MPI_OFFSET_KIND) ATT_LEN_LL
+ double precision hash_$1
+ logical inRange3
+
+ integer ncid
+ integer i
+ integer j
+ integer k
+ integer(kind=MPI_OFFSET_KIND) ndx(1)
+ integer err, flags
+ ATTDATATYPE($1, value, MAX_NELS)
+ logical allInExtRange !/* all values within external range? */
+ doubleprecision val
+
+ flags = IOR(NF90_NOCLOBBER, extra_flags)
+ err = nf90mpi_create(comm, scratch, flags, info, &
+ ncid)
+ if (err .ne. NF90_NOERR) then
+ call errore('nf90mpi_create: ', err)
+ return
+ end if
+ call def_dims(ncid)
+ call def_vars(ncid)
+
+ do 1, i = 0, numVars
+ do 2, j = 1, NATTS(i)
+ if (.not.(ATT_TYPE(j,i) .eq. NF90_CHAR)) then
+ ATT_LEN_LL = ATT_LEN(j,i)
+ if (.not.((ATT_LEN_LL .le. MAX_NELS))) &
+ stop 'assert(ATT_LEN_LL .le. MAX_NELS)'
+ err = nf90mpi_put_att(BAD_ID, i, ATT_NAME(j,i), value)
+ if (err .ne. NF90_EBADID) &
+ call errore('bad ncid: ', err)
+ err = nf90mpi_put_att(ncid, BAD_VARID, ATT_NAME(j,i), value)
+ if (err .ne. NF90_ENOTVAR) &
+ call errore('bad var id: ', err)
+ allInExtRange = .true.
+ do 3, k = 1, INT(ATT_LEN_LL)
+ ndx(1) = k
+ val = hash_$1(ATT_TYPE(j,i), &
+ -1, ndx, NFT_ITYPE($1))
+ MAKE_TYPE2($1, VAR_ELEM($1, value, k), val)
+ val = ARITH3($1, value, k)
+ allInExtRange = allInExtRange .and. &
+ inRange3(val, ATT_TYPE(j,i), &
+ NFT_ITYPE($1))
+3 continue
+ ! err = nf90mpi_put_att(ncid, i, ATT_NAME(j,i), value(1:ATT_LEN_LL))
+ ! cannot use F90 API, as type casting is performed,
+ ! as ATT_TYPE(j,i) may not be the same as value's type
+ err = nfmpi_put_att_$1(ncid, i, ATT_NAME(j,i), &
+ ATT_TYPE(j,i), ATT_LEN_LL, value)
+ if (allInExtRange) then
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_put_att: ', err)
+ else
+ if (err .ne. NF90_ERANGE) &
+ call errore('range error: ', err)
+ end if
+ end if
+2 continue
+1 continue
+
+ call check_atts_$1(ncid)
+ err = nf90mpi_close(ncid)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_close: ', err)
+
+ err = nf90mpi_delete(scratch, info)
+ if (err .ne. NF90_NOERR) &
+ call errorc('delete of scratch file failed:', &
+ scratch)
+ end
+])dnl
+
+divert(0)dnl
+dnl If you see this line, you can ignore the next one.
+! Do not edit this file. It is produced from the corresponding .m4 source */
+
+!
+! Copyright (C) 2013, Northwestern University and Argonne National Laboratory
+! See COPYRIGHT notice in top-level directory.
+!
+! $Id: test_put.m4 2156 2015-10-12 01:15:25Z wkliao $
+!
+
+HASH(text)
+#ifdef NF_INT1_T
+HASH(int1)
+#endif
+#ifdef NF_INT2_T
+HASH(int2)
+#endif
+HASH(int)
+HASH(int8)
+HASH(real)
+HASH(double)
+
+CHECK_VARS(text)
+#ifdef NF_INT1_T
+CHECK_VARS(int1)
+#endif
+#ifdef NF_INT2_T
+CHECK_VARS(int2)
+#endif
+CHECK_VARS(int)
+CHECK_VARS(int8)
+CHECK_VARS(real)
+CHECK_VARS(double)
+
+CHECK_ATTS(text)
+#ifdef NF_INT1_T
+CHECK_ATTS(int1)
+#endif
+#ifdef NF_INT2_T
+CHECK_ATTS(int2)
+#endif
+CHECK_ATTS(int)
+CHECK_ATTS(int8)
+CHECK_ATTS(real)
+CHECK_ATTS(double)
+
+TEST_NFMPI_PUT_VAR1(text)
+#ifdef NF_INT1_T
+TEST_NFMPI_PUT_VAR1(int1)
+#endif
+#ifdef NF_INT2_T
+TEST_NFMPI_PUT_VAR1(int2)
+#endif
+TEST_NFMPI_PUT_VAR1(int)
+TEST_NFMPI_PUT_VAR1(int8)
+TEST_NFMPI_PUT_VAR1(real)
+TEST_NFMPI_PUT_VAR1(double)
+
+TEST_NFMPI_PUT_VAR(text)
+#ifdef NF_INT1_T
+TEST_NFMPI_PUT_VAR(int1)
+#endif
+#ifdef NF_INT2_T
+TEST_NFMPI_PUT_VAR(int2)
+#endif
+TEST_NFMPI_PUT_VAR(int)
+TEST_NFMPI_PUT_VAR(int8)
+TEST_NFMPI_PUT_VAR(real)
+TEST_NFMPI_PUT_VAR(double)
+
+TEST_NFMPI_PUT_VARA(text)
+#ifdef NF_INT1_T
+TEST_NFMPI_PUT_VARA(int1)
+#endif
+#ifdef NF_INT2_T
+TEST_NFMPI_PUT_VARA(int2)
+#endif
+TEST_NFMPI_PUT_VARA(int)
+TEST_NFMPI_PUT_VARA(int8)
+TEST_NFMPI_PUT_VARA(real)
+TEST_NFMPI_PUT_VARA(double)
+
+TEST_NFMPI_PUT_VARS(text)
+#ifdef NF_INT1_T
+TEST_NFMPI_PUT_VARS(int1)
+#endif
+#ifdef NF_INT2_T
+TEST_NFMPI_PUT_VARS(int2)
+#endif
+TEST_NFMPI_PUT_VARS(int)
+TEST_NFMPI_PUT_VARS(int8)
+TEST_NFMPI_PUT_VARS(real)
+TEST_NFMPI_PUT_VARS(double)
+
+TEST_NFMPI_PUT_VARM(text)
+#ifdef NF_INT1_T
+TEST_NFMPI_PUT_VARM(int1)
+#endif
+#ifdef NF_INT2_T
+TEST_NFMPI_PUT_VARM(int2)
+#endif
+TEST_NFMPI_PUT_VARM(int)
+TEST_NFMPI_PUT_VARM(int8)
+TEST_NFMPI_PUT_VARM(real)
+TEST_NFMPI_PUT_VARM(double)
+
+ subroutine test_nf90mpi_put_att_text()
+ use pnetcdf
+ implicit none
+#include "tests.inc"
+ character*2 ATT_NAME
+ integer ATT_TYPE, NATTS, ATT_LEN
+ double precision hash
+
+ integer ncid
+ integer i
+ integer j
+ integer(kind=MPI_OFFSET_KIND) k
+ integer err, flags
+ character(len=MAX_NELS) value
+
+ flags = IOR(NF90_NOCLOBBER, extra_flags)
+ err = nf90mpi_create(comm, scratch, flags, info, &
+ ncid)
+ if (err .ne. NF90_NOERR) then
+ call errore('nf90mpi_create: ', err)
+ return
+ end if
+ call def_dims(ncid)
+ call def_vars(ncid)
+
+ do 1, i = 0, numVars
+ do 2, j = 1, NATTS(i)
+ if (ATT_TYPE(j,i) .eq. NF90_CHAR) then
+ if (.not.(ATT_LEN(j,i) .le. MAX_NELS)) &
+ stop 'assert(ATT_LEN(j,i) .le. MAX_NELS)'
+ err = nf90mpi_put_att(BAD_ID, i, ATT_NAME(j,i), value)
+ if (err .ne. NF90_EBADID) &
+ call errore('bad ncid: ', err)
+ err = nf90mpi_put_att(ncid, BAD_VARID, &
+ ATT_NAME(j,i), value)
+ if (err .ne. NF90_ENOTVAR) &
+ call errore('bad var id: ', err)
+ do 3, k = 1, ATT_LEN(j,i)
+ value(k:k) = char(int(hash(ATT_TYPE(j,i), &
+ -1, k)))
+3 continue
+ err = nf90mpi_put_att(ncid, i, ATT_NAME(j,i), value(1:ATT_LEN(j,i)))
+ if (err .ne. NF90_NOERR) &
+ call error(nf90mpi_strerror(err))
+ end if
+2 continue
+1 continue
+
+ call check_atts_text(ncid)
+ err = nf90mpi_close(ncid)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_close: ', err)
+
+ err = nf90mpi_delete(scratch, info)
+ if (err .ne. NF90_NOERR) &
+ call errorc('delete of scratch file failed:', &
+ scratch)
+ end
+
+#ifdef NF_INT1_T
+TEST_NFMPI_PUT_ATT(int1)
+#endif
+#ifdef NF_INT2_T
+TEST_NFMPI_PUT_ATT(int2)
+#endif
+TEST_NFMPI_PUT_ATT(int)
+TEST_NFMPI_PUT_ATT(int8)
+TEST_NFMPI_PUT_ATT(real)
+TEST_NFMPI_PUT_ATT(double)
diff --git a/test/nf90_test/test_read.F90 b/test/nf90_test/test_read.F90
new file mode 100644
index 0000000..aa6193f
--- /dev/null
+++ b/test/nf90_test/test_read.F90
@@ -0,0 +1,1454 @@
+!
+! Copyright (C) 2013, Northwestern University and Argonne National Laboratory
+! See COPYRIGHT notice in top-level directory.
+!
+! $Id: test_read.F90 2296 2016-01-06 21:19:36Z wkliao $
+!
+
+! Test nf90mpi_strerror.
+! Try on a bad error status.
+! Test for each defined error status.
+!
+ subroutine test_nf90mpi_strerror()
+ use pnetcdf
+ implicit none
+#include "tests.inc"
+ integer number_of_messages
+ parameter (number_of_messages = 27)
+
+ integer i, msg_len
+ integer status(number_of_messages)
+ character*80 message, unknown_err_msg
+ character*80 msg(number_of_messages)
+ integer nok
+
+ data status(1) / NF90_NOERR/
+ data status(2) / NF90_EBADID /
+ data status(3) / NF90_EEXIST /
+ data status(4) / NF90_EINVAL /
+ data status(5) / NF90_EPERM /
+ data status(6) / NF90_ENOTINDEFINE /
+ data status(7) / NF90_EINDEFINE /
+ data status(8) / NF90_EINVALCOORDS /
+ data status(9) / NF90_EMAXDIMS /
+ data status(10) / NF90_ENAMEINUSE /
+ data status(11) / NF90_ENOTATT /
+ data status(12) / NF90_EMAXATTS /
+ data status(13) / NF90_EBADTYPE /
+ data status(14) / NF90_EBADDIM /
+ data status(15) / NF90_EUNLIMPOS /
+ data status(16) / NF90_EMAXVARS /
+ data status(17) / NF90_ENOTVAR /
+ data status(18) / NF90_EGLOBAL /
+ data status(19) / NF90_ENOTNC /
+ data status(20) / NF90_ESTS /
+ data status(21) / NF90_EMAXNAME /
+ data status(22) / NF90_EUNLIMIT /
+ data status(23) / NF90_ENORECVARS /
+ data status(24) / NF90_ECHAR /
+ data status(25) / NF90_EEDGE /
+ data status(26) / NF90_ESTRIDE /
+ data status(27) / NF90_EBADNAME /
+
+ data msg(1) / 'No error' /
+ data msg(2) / 'NetCDF: Not a valid ID' /
+ data msg(3) / 'NetCDF: File exists && NC_NOCLOBBER' /
+ data msg(4) / 'NetCDF: Invalid argument' /
+ data msg(5) / 'NetCDF: Write to read only' /
+ data msg(6) / 'NetCDF: Operation not allowed in data mode' /
+ data msg(7) / 'NetCDF: Operation not allowed in define mode' /
+ data msg(8) / 'NetCDF: Index exceeds dimension bound' /
+ data msg(9) / 'NetCDF: NC_MAX_DIMS exceeded' /
+ data msg(10) / 'NetCDF: String match to name in use' /
+ data msg(11) / 'NetCDF: Attribute not found' /
+ data msg(12) / 'NetCDF: NC_MAX_ATTRS exceeded' /
+ data msg(13) &
+ / 'NetCDF: Not a valid data type or _FillValue type mismatch' /
+ data msg(14) / 'NetCDF: Invalid dimension ID or name' /
+ data msg(15) / 'NetCDF: NC_UNLIMITED in the wrong index' /
+ data msg(16) / 'NetCDF: NC_MAX_VARS exceeded' /
+ data msg(17) / 'NetCDF: Variable not found' /
+ data msg(18) / 'NetCDF: Action prohibited on NC_GLOBAL varid' /
+ data msg(19) / 'NetCDF: Unknown file format' /
+ data msg(20) / 'NetCDF: In Fortran, string too short' /
+ data msg(21) / 'NetCDF: NC_MAX_NAME exceeded' /
+ data msg(22) / 'NetCDF: NC_UNLIMITED size already in use' /
+ data msg(23) &
+ / 'NetCDF: nc_rec op when there are no record vars' /
+ data msg(24) &
+ /'NetCDF: Attempt to convert between text & numbers'/
+ data msg(25) / 'NetCDF: Start+count exceeds dimension bound' /
+ data msg(26) / 'NetCDF: Illegal stride' /
+ data msg(27) / 'NetCDF: Name contains illegal characters' /
+
+ nok = 0
+
+! /* Try on a bad error status */
+ message = nf90mpi_strerror(-666)!/* should fail */
+! pnetcdf differs from serial netcdf in that we report the error
+! code along with the message.
+
+ unknown_err_msg = "Unknown Error"
+ msg_len = LEN(TRIM(unknown_err_msg))
+ if (message(1:msg_len) .ne. unknown_err_msg(1:msg_len)) then
+ call errorc('nf90mpi_strerror on bad error status returned: ', &
+ message)
+ else
+ nok = nok + 1
+ endif
+
+! /* Try on each legitimate error status */
+ do 1, i=1, number_of_messages
+ message = nf90mpi_strerror(status(i))
+ if (trim(message) .ne. trim(msg(i))) then
+ call error('nf90mpi_strerror() should return "' &
+ // trim(msg(i)) // '"' // ' but got '// &
+ '"' // trim(message) // '"')
+ else
+ nok = nok + 1
+ endif
+1 continue
+ call print_nok(nok)
+ end
+
+
+! Test nf90mpi_open.
+! If in read-only section of tests,
+! Try to open a non-existent netCDF file, check error return.
+! Open a file that is not a netCDF file, check error return.
+! Open a netCDF file with a bad mode argument, check error return.
+! Open a netCDF file with NFMPI_NOWRITE mode, try to write, check error.
+! Try to open a netcdf twice, check whether returned netcdf ids different.
+! If in writable section of tests,
+! Open a netCDF file with NFMPI_WRITE mode, write something, close it.
+! On exit, any open netCDF files are closed.
+ subroutine test_nf90mpi_open()
+ use pnetcdf
+ implicit none
+#include "tests.inc"
+ integer err
+ integer ncid
+ integer ncid2
+ integer nok, flags
+
+ nok = 0
+
+! /* Try to open a nonexistent file */
+ err = nf90mpi_open(comm, 'tooth-fairy.nc', NF90_NOWRITE, &
+ info, ncid)!/* should fail */
+
+! On some systems, opening an nonexisting file will actually create the
+! file. In this case, we print the error messages on screen and move on
+! to the next test, instead of aborting the entire test.
+
+ if (err .eq. NF90_NOERR) then
+ print*, &
+ 'opening a nonexistent file expects to fail, but got NF90_NOERR'
+ elseif (err .ne. NF90_ENOENT) then
+ print*, &
+ 'opening a nonexistent file expects NF90_ENOENT, but got ',err
+ else
+! print*, "Expected error message complaining: "// &
+! "File tooth-fairy.nc does not exist"
+ nok = nok + 1
+ endif
+
+! Open a file that is not a netCDF file. This call should fail
+ err = nf90mpi_open(comm, 'test_get.F90', NF90_NOWRITE, &
+ info, ncid)
+ if (err .ne. NF90_ENOTNC .and. err .ne. NF90_EOFILE) then
+ call errore('nf90mpi_open of non-netCDF file: ', err)
+ else
+ nok = nok + 1
+ endif
+
+! Open a netCDF file in read-only mode, check that write fails
+ err = nf90mpi_open(comm, testfile, NF90_NOWRITE, info, ncid)
+ if (err .NE. NF90_NOERR) then
+ call errore('nf90mpi_open: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nf90mpi_redef(ncid) !/* should fail */
+ if (err .ne. NF90_EPERM) &
+ call error('nf90mpi_redef of read-only file should fail')
+! Opened OK, see if can open again and get a different netCDF ID
+ err = nf90mpi_open(comm, testfile, NF90_NOWRITE, info, &
+ ncid2)
+ if (err .NE. NF90_NOERR) then
+ call errore('nf90mpi_open: ', err)
+ else
+ err = nf90mpi_close(ncid2)
+ nok = nok + 1
+ end if
+ if (ncid2 .eq. ncid) &
+ call error('netCDF IDs for first and second '// &
+ 'nf90mpi_open calls should differ')
+
+ if (.not. readonly) then !/* tests using netCDF scratch file */
+ flags = IOR(NF90_NOCLOBBER, extra_flags)
+ err = nf90mpi_create(comm, scratch, flags, &
+ info, ncid2)
+ if (err .NE. NF90_NOERR) then
+ call errore('nf90mpi_create: ', err)
+ else
+ err = nf90mpi_close(ncid2)
+ end if
+ err = nf90mpi_open(comm, scratch, NF90_WRITE, info, &
+ ncid2)
+ if (err .NE. NF90_NOERR) then
+ call errore('nf90mpi_open: ', err)
+ else
+ err = nf90mpi_close(ncid2)
+ nok = nok + 1
+ end if
+ err = nf90mpi_delete(scratch, info)
+ if (err .NE. NF90_NOERR) &
+ call errorc('delete of scratch file failed: ', scratch)
+ end if
+
+ err = nf90mpi_close(ncid)
+ if (err .NE. NF90_NOERR) &
+ call errore('nf90mpi_close: ', err)
+ call print_nok(nok)
+ end
+
+
+!
+! Test nf90mpi_close.
+! Try to close a netCDF file twice, check whether second close fails.
+! Try on bad handle, check error return.
+! Try in define mode and data mode.
+!
+ subroutine test_nf90mpi_close()
+ use pnetcdf
+ implicit none
+#include "tests.inc"
+ integer ncid
+ integer err
+ integer nok, flags
+
+ nok = 0
+
+ err = nf90mpi_open(comm, testfile, NF90_NOWRITE, info, &
+ ncid)
+ if (err .NE. NF90_NOERR) &
+ call errore('nf90mpi_open: ', err)
+
+! /* Close a netCDF file twice, second time should fail */
+ err = nf90mpi_close(ncid)
+ if (err .NE. NF90_NOERR) then
+ call errore('nf90mpi_close failed: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nf90mpi_close(ncid)
+ if (err .ne. NF90_EBADID) then
+ call error('nf90mpi_close of closed file should have failed')
+ else
+ nok = nok + 1
+ endif
+
+! /* Try with a bad netCDF ID */
+ err = nf90mpi_close(BAD_ID)!/* should fail */
+ if (err .ne. NF90_EBADID) then
+ call errore( &
+ 'nf90mpi_close with bad netCDF ID returned wrong error: ', &
+ err)
+ else
+ nok = nok + 1
+ endif
+
+! /* Close in data mode */
+ err = nf90mpi_open(comm, testfile, NF90_NOWRITE, info, &
+ ncid)
+ if (err .NE. NF90_NOERR) &
+ call errore('nf90mpi_open: ', err)
+ err = nf90mpi_close(ncid)
+ if (err .NE. NF90_NOERR) then
+ call errore('nf90mpi_close in data mode failed: ', err)
+ else
+ nok = nok + 1
+ endif
+
+ if (.not. readonly) then !/* tests using netCDF scratch file */
+ flags = IOR(NF90_NOCLOBBER, extra_flags)
+ err = nf90mpi_create(comm, scratch, flags, &
+ info, ncid)
+ if (err .NE. NF90_NOERR) &
+ call errore('nf90mpi_create: ', err)
+ err = nf90mpi_close(ncid)
+ if (err .NE. NF90_NOERR) then
+ call errore('nf90mpi_close in define mode: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nf90mpi_delete(scratch, info)
+ if (err .NE. NF90_NOERR) then
+ call errorc('delete of scratch file failed: ', &
+ scratch)
+ else
+ nok = nok + 1
+ endif
+ end if
+ call print_nok(nok)
+ end
+
+
+! Test nf90mpi_inq.
+! Try on bad handle, check error return.
+! Try in data mode, check returned values.
+! Try asking for subsets of info.
+! If in writable section of tests,
+! Try in define mode, after adding an unlimited dimension, variable.
+! On exit, any open netCDF files are closed.
+ subroutine test_nf90mpi_inq()
+ use pnetcdf
+ implicit none
+#include "tests.inc"
+ integer ncid
+ integer ncid2 !/* for scratch netCDF dataset */
+ integer ndims !/* number of dimensions */
+ integer nvars !/* number of variables */
+ integer ngatts !/* number of global attributes */
+ integer recdim !/* id of unlimited dimension */
+ integer err
+ integer ndims0
+ integer nvars0
+ integer ngatts0
+ integer recdim0
+ integer did
+ integer vid
+ integer(kind=MPI_OFFSET_KIND) length
+ integer VDIMS(1)
+ integer nok, flags
+
+ nok = 0
+
+ err = nf90mpi_open(comm, testfile, NF90_NOWRITE, info, &
+ ncid)
+ if (err .NE. NF90_NOERR) &
+ call errore('nf90mpi_open: ', err)
+
+! /* Try on bad handle */
+ err = nf90mpi_inquire(BAD_ID, ndims, nvars, ngatts, recdim)
+ if (err .ne. NF90_EBADID) then
+ call errore('bad ncid: ', err)
+ else
+ nok = nok + 1
+ endif
+
+ err = nf90mpi_inquire(ncid, ndims, nvars, ngatts, recdim)
+ if (err .ne. NF90_NOERR) then
+ call errore('nf90mpi_inquire: ', err)
+ else if (ndims .ne. NDIMS) then
+ call errori &
+ ('nf90mpi_inquire: wrong number of dimensions returned: ', ndims)
+ else if (nvars .ne. numVars) then
+ call errori &
+ ('nf90mpi_inquire: wrong number of variables returned: ', nvars)
+ else if (ngatts .ne. numGatts) then
+ call errori( &
+ 'nf90mpi_inquire: wrong number of global atts returned: ', &
+ ngatts)
+ else if (recdim .ne. RECDIM) then
+ call errori &
+ ('nf90mpi_inquire: wrong record dimension ID returned: ', recdim)
+ else
+ nok = nok + 1
+ end if
+
+ if (.not. readonly) then ! tests using netCDF scratch file
+ flags = IOR(NF90_NOCLOBBER, extra_flags)
+ err = nf90mpi_create(comm, scratch, flags, &
+ info, ncid2)
+ if (err .NE. NF90_NOERR) then
+ call errore('nf90mpi_create: ', err)
+ else ! add dim, var, gatt, check inq
+ err = nf90mpi_enddef(ncid2) ! enter data mode
+ err = nf90mpi_inquire(ncid2, ndims0, nvars0, &
+ ngatts0, recdim0)
+ if (err .NE. NF90_NOERR) then
+ call errore('nf90mpi_inquire: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nf90mpi_redef(ncid2) !/* enter define mode */
+! /* Check that inquire still works in define mode */
+ err = nf90mpi_inquire(ncid2, ndims, nvars, ngatts, recdim)
+ if (err .NE. NF90_NOERR) then
+ call errore('nf90mpi_inquire in define mode: ', err)
+ else if (ndims .ne. ndims0) then
+ call errori &
+ ('nf90mpi_inquire in define mode: ndims wrong, ', ndims)
+ else if (nvars .ne. nvars0) then
+ call errori &
+ ('nf90mpi_inquire in define mode: nvars wrong, ', nvars)
+ else if (ngatts .ne. ngatts0) then
+ call errori( &
+ 'nf90mpi_inquire in define mode: ngatts wrong, ', ngatts)
+ print *, ' expected ', ngatts0
+ else if (recdim .ne. recdim0) then
+ call errori &
+ ('nf90mpi_inquire in define mode: recdim wrong, ', recdim)
+ else
+ nok = nok + 1
+ end if
+
+! /* Add dim, var, global att */
+ length = 1
+ err = nf90mpi_def_dim(ncid2, 'inqd', length, did)
+ if (err .NE. NF90_NOERR) &
+ call errore('nf90mpi_def_dim: ', err)
+ VDIMS = 0
+ err = nf90mpi_def_var(ncid2, 'inqv', NF90_FLOAT, varid=vid)
+ if (err .NE. NF90_NOERR) &
+ call errore('nf90mpi_def_var: ', err)
+
+ length = len('stuff')
+ err = nf90mpi_put_att(ncid2, NF90_GLOBAL, 'inqa', &
+ 'stuff')
+ if (err .NE. NF90_NOERR) &
+ call errore('nf90mpi_put_att: ', err)
+
+! Make sure nf90mpi_inquire sees the additions while in define mode
+ err = nf90mpi_inquire(ncid2, ndims, nvars, ngatts, recdim)
+ if (err .NE. NF90_NOERR) then
+ call errore('nf90mpi_inquire in define mode: ', err)
+ else if (ndims .ne. ndims0 + 1) then
+ call errori &
+ ('nf90mpi_inquire in define mode: ndims wrong, ', ndims)
+ else if (nvars .ne. nvars0 + 1) then
+ call errori &
+ ('nf90mpi_inquire in define mode: nvars wrong, ', nvars)
+ else if (ngatts .ne. ngatts0 + 1) then
+ call errori &
+ ('nf90mpi_inquire in define mode: ngatts wrong, ', ngatts)
+ print *, ' expected (added attr)', ngatts0 + 1
+ else
+ nok = nok + 1
+ end if
+ err = nf90mpi_enddef(ncid2)
+ if (err .NE. NF90_NOERR) &
+ call errore('nf90mpi_enddef: ', err)
+
+! Make sure nf90mpi_inquire stills sees additions in data mode
+ err = nf90mpi_inquire(ncid2, ndims, nvars, ngatts, recdim)
+ if (err .NE. NF90_NOERR) then
+ call errore('nf90mpi_inquire failed in data mode: ',err)
+ else if (ndims .ne. ndims0 + 1) then
+ call errori &
+ ('nf90mpi_inquire in define mode: ndims wrong, ', ndims)
+ else if (nvars .ne. nvars0 + 1) then
+ call errori &
+ ('nf90mpi_inquire in define mode: nvars wrong, ', nvars)
+ else if (ngatts .ne. ngatts0 + 1) then
+ call errori &
+ ('nf90mpi_inquire in define mode: ngatts wrong, ', ngatts)
+ else
+ nok = nok + 1
+ end if
+ err = nf90mpi_close(ncid2)
+ err = nf90mpi_delete(scratch, info)
+ if (err .NE. NF90_NOERR) &
+ call errorc('delete of scratch file failed: ', &
+ scratch)
+ end if
+ end if
+
+ err = nf90mpi_close(ncid)
+ if (err .NE. NF90_NOERR) &
+ call errore('nf90mpi_close: ', err)
+ call print_nok(nok)
+ end
+
+
+ subroutine test_nf90mpi_inq_natts()
+ use pnetcdf
+ implicit none
+#include "tests.inc"
+ integer ncid
+ integer ngatts ! number of global attributes
+ integer err
+ integer nok
+
+ nok = 0
+
+ err = nf90mpi_inquire(BAD_ID, nAttributes=ngatts)
+ if (err .ne. NF90_EBADID) then
+ call errore('bad ncid: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nf90mpi_open(comm, testfile, NF90_NOWRITE, info, &
+ ncid)
+ if (err .NE. NF90_NOERR) &
+ call errore('nf90mpi_open: ', err)
+ err = nf90mpi_inquire(ncid, nAttributes=ngatts)
+ if (err .NE. NF90_NOERR) then
+ call errore('nf90mpi_inquire: ', err)
+ else if (ngatts .ne. numGatts) then
+ call errori &
+ ('nf90mpi_inquire: wrong number of global atts returned, ', &
+ ngatts)
+ else
+ nok = nok + 1
+ end if
+ err = nf90mpi_close(ncid)
+ if (err .NE. NF90_NOERR) &
+ call errore('nf90mpi_close: ', err)
+ call print_nok(nok)
+ end
+
+
+ subroutine test_nf90mpi_inq_ndims()
+ use pnetcdf
+ implicit none
+#include "tests.inc"
+ integer ncid
+ integer ndims
+ integer err
+ integer nok
+
+ nok = 0
+
+ err = nf90mpi_inquire(BAD_ID, ndims)
+ if (err .ne. NF90_EBADID) then
+ call errore('bad ncid: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nf90mpi_open(comm, testfile, NF90_NOWRITE, info, &
+ ncid)
+ if (err .NE. NF90_NOERR) &
+ call errore('nf90mpi_open: ', err)
+ err = nf90mpi_inquire(ncid, ndims)
+ if (err .NE. NF90_NOERR) then
+ call errore('nf90mpi_inquire: ', err)
+ else if (ndims .ne. NDIMS) then
+ call errori &
+ ('nf90mpi_inquire: wrong number returned, ', ndims)
+ else
+ nok = nok + 1
+ end if
+ err = nf90mpi_close(ncid)
+ if (err .NE. NF90_NOERR) &
+ call errore('nf90mpi_close: ', err)
+ call print_nok(nok)
+ end
+
+
+ subroutine test_nf90mpi_inq_nvars()
+ use pnetcdf
+ implicit none
+#include "tests.inc"
+ integer ncid
+ integer nvars
+ integer err
+ integer nok
+
+ nok = 0
+
+ err = nf90mpi_inquire(BAD_ID, nVariables=nvars)
+ if (err .ne. NF90_EBADID) then
+ call errore('bad ncid: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nf90mpi_open(comm, testfile, NF90_NOWRITE, info, &
+ ncid)
+ if (err .NE. NF90_NOERR) &
+ call errore('nf90mpi_open: ', err)
+ err = nf90mpi_inquire(ncid, nVariables=nvars)
+ if (err .NE. NF90_NOERR) then
+ call errore('nf90mpi_inquire: ', err)
+ else if (nvars .ne. numVars) then
+ call errori &
+ ('nf90mpi_inquire: wrong number returned, ', nvars)
+ else
+ nok = nok + 1
+ end if
+ err = nf90mpi_close(ncid)
+ if (err .NE. NF90_NOERR) &
+ call errore('nf90mpi_close: ', err)
+ call print_nok(nok)
+ end
+
+
+ subroutine test_nf90mpi_inq_unlimdim()
+ use pnetcdf
+ implicit none
+#include "tests.inc"
+ integer ncid
+ integer unlimdim
+ integer err
+ integer nok
+
+ nok = 0
+
+ err = nf90mpi_inquire(BAD_ID, unlimitedDimId=unlimdim)
+ if (err .ne. NF90_EBADID) then
+ call errore('bad ncid: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nf90mpi_open(comm, testfile, NF90_NOWRITE, info, &
+ ncid)
+ if (err .NE. NF90_NOERR) &
+ call errore('nf90mpi_open: ', err)
+ err = nf90mpi_inquire(ncid, unlimitedDimId=unlimdim)
+ if (err .NE. NF90_NOERR) then
+ call errore('nf90mpi_inquire: ', err)
+ else if (unlimdim .ne. RECDIM) then
+ call errori &
+ ('nf90mpi_inquire: wrong number returned, ', unlimdim)
+ print *, 'expected ', RECDIM
+ else
+ nok = nok + 1
+ end if
+ err = nf90mpi_close(ncid)
+ if (err .NE. NF90_NOERR) &
+ call errore('nf90mpi_close: ', err)
+ call print_nok(nok)
+ end
+
+
+ subroutine test_nf90mpi_inq_dimid()
+ use pnetcdf
+ implicit none
+#include "tests.inc"
+ integer ncid
+ integer dimid
+ integer i
+ integer err
+ integer nok
+
+ nok = 0
+
+ err = nf90mpi_open(comm, testfile, NF90_NOWRITE, info, &
+ ncid)
+ if (err .NE. NF90_NOERR) &
+ call errore('nf90mpi_open: ', err)
+ err = nf90mpi_inq_dimid(ncid, 'noSuch', dimid)
+ if (err .ne. NF90_EBADDIM) then
+ call errore('bad dim name: ', err)
+ else
+ nok = nok + 1
+ endif
+ do 1, i = 1, NDIMS
+ err = nf90mpi_inq_dimid(BAD_ID, dim_name(i), dimid)
+ if (err .ne. NF90_EBADID) then
+ call errore('bad ncid: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nf90mpi_inq_dimid(ncid, dim_name(i), dimid)
+ if (err .NE. NF90_NOERR) then
+ call errore('nf90mpi_inq_dimid: ', err)
+ else if (dimid .ne. i) then
+ call errori('expected ', i)
+ call errori('got ', dimid)
+ else
+ nok = nok + 1
+ end if
+1 continue
+ err = nf90mpi_close(ncid)
+ if (err .NE. NF90_NOERR) &
+ call errore('nf90mpi_close: ', err)
+ call print_nok(nok)
+ end
+
+
+ subroutine test_nf90mpi_inq_dim()
+ use pnetcdf
+ implicit none
+#include "tests.inc"
+ integer ncid
+ integer i
+ integer err
+ character*(NF90_MAX_NAME) name
+ integer(kind=MPI_OFFSET_KIND) length
+ integer intlen
+ integer nok
+
+ nok = 0
+
+ err = nf90mpi_open(comm, testfile, NF90_NOWRITE, info, &
+ ncid)
+ if (err .NE. NF90_NOERR) &
+ call errore('nf90mpi_open: ', err)
+ do 1, i = 1, NDIMS
+ err = nf90mpi_inquire_dimension(BAD_ID, i, name, length)
+ if (err .ne. NF90_EBADID) then
+ call errore('bad ncid: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nf90mpi_inquire_dimension(ncid, BAD_DIMID, name, length)
+ if (err .ne. NF90_EBADDIM) then
+ call errore('bad dimid: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nf90mpi_inquire_dimension(ncid, i, name, length)
+ if (err .NE. NF90_NOERR) then
+ call errore('nf90mpi_inquire_dimension: ', err)
+ else if (dim_name(i) .ne. name) then
+ call errorc('name unexpected: ', name)
+ print *, ' expected ', dim_name(i),' for the ',i,'entry'
+ else if (dim_len(i) .ne. length) then
+ intlen = INT(length)
+ call errori('size unexpected: ', intlen)
+ else
+ nok = nok + 1
+ end if
+1 continue
+ err = nf90mpi_close(ncid)
+ if (err .NE. NF90_NOERR) &
+ call errore('nf90mpi_close: ', err)
+ call print_nok(nok)
+ end
+
+
+ subroutine test_nf90mpi_inq_dimlen()
+ use pnetcdf
+ implicit none
+#include "tests.inc"
+ integer ncid
+ integer i
+ integer err
+ integer(kind=MPI_OFFSET_KIND) length
+ integer intlen
+ integer nok
+
+ nok = 0
+
+ err = nf90mpi_open(comm, testfile, NF90_NOWRITE, info, &
+ ncid)
+ if (err .NE. NF90_NOERR) &
+ call errore('nf90mpi_open: ', err)
+ do 1, i = 1, NDIMS
+ err = nf90mpi_inquire_dimension(BAD_ID, i, len=length)
+ if (err .ne. NF90_EBADID) then
+ call errore('bad ncid: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nf90mpi_inquire_dimension(ncid, BAD_DIMID, len=length)
+ if (err .ne. NF90_EBADDIM) &
+ call errore('bad dimid: ', err)
+ err = nf90mpi_inquire_dimension(ncid, i, len=length)
+ if (err .NE. NF90_NOERR) then
+ call errore('nf90mpi_inquire_dimension: ', err)
+ else if (dim_len(i) .ne. length) then
+ intlen = INT(length)
+ call errori('size unexpected: ', intlen)
+ print *, 'expected ', dim_len(i),' for the ',i,'entry'
+ else
+ nok = nok + 1
+ end if
+1 continue
+ err = nf90mpi_close(ncid)
+ if (err .NE. NF90_NOERR) &
+ call errore('nf90mpi_close: ', err)
+ call print_nok(nok)
+ end
+
+
+ subroutine test_nf90mpi_inq_dimname()
+ use pnetcdf
+ implicit none
+#include "tests.inc"
+ integer ncid
+ integer i
+ integer err
+ character*(NF90_MAX_NAME) name
+ integer nok
+
+ nok = 0
+
+ err = nf90mpi_open(comm, testfile, NF90_NOWRITE, info, &
+ ncid)
+ if (err .NE. NF90_NOERR) &
+ call errore('nf90mpi_open: ', err)
+ do 1, i = 1, NDIMS
+ err = nf90mpi_inquire_dimension(BAD_ID, i, name)
+ if (err .ne. NF90_EBADID) then
+ call errore('bad ncid: ', err)
+ else
+ nok = nok + 1
+ end if
+ err = nf90mpi_inquire_dimension(ncid, BAD_DIMID, name)
+ if (err .ne. NF90_EBADDIM) then
+ call errore('bad dimid: ', err)
+ else
+ nok = nok + 1
+ end if
+ err = nf90mpi_inquire_dimension(ncid, i, name)
+ if (err .NE. NF90_NOERR) then
+ call errore('nf90mpi_inquire_dimension: ', err)
+ else if (dim_name(i) .ne. name) then
+ call errorc('name unexpected: ', name)
+ else
+ nok = nok + 1
+ end if
+1 continue
+ err = nf90mpi_close(ncid)
+ if (err .NE. NF90_NOERR) &
+ call errore('nf90mpi_close: ', err)
+ call print_nok(nok)
+ end
+
+
+ subroutine test_nf90mpi_inq_varid()
+ use pnetcdf
+ implicit none
+#include "tests.inc"
+ integer ncid
+ integer vid
+ integer i
+ integer err
+ integer nok
+
+ nok = 0
+
+ err = nf90mpi_open(comm, testfile, NF90_NOWRITE, info, &
+ ncid)
+ if (err .NE. NF90_NOERR) &
+ call errore('nf90mpi_open: ', err)
+
+ err = nf90mpi_inq_varid(ncid, 'noSuch', vid)
+ if (err .ne. NF90_ENOTVAR) &
+ call errore('bad ncid: ', err)
+
+ do 1, i = 1, numVars
+ err = nf90mpi_inq_varid(BAD_ID, var_name(i), vid)
+ if (err .ne. NF90_EBADID) then
+ call errore('bad ncid: ', err)
+ else
+ nok = nok + 1
+ end if
+ err = nf90mpi_inq_varid(ncid, var_name(i), vid)
+ if (err .NE. NF90_NOERR) then
+ call errore('nf90mpi_inq_varid: ', err)
+ else if (vid .ne. i) then
+ call errori('varid unexpected: ', vid)
+ else
+ nok = nok + 1
+ endif
+1 continue
+
+ err = nf90mpi_close(ncid)
+ if (err .NE. NF90_NOERR) &
+ call errore('nf90mpi_close: ', err)
+ call print_nok(nok)
+ end
+
+
+ subroutine test_nf90mpi_inq_var()
+ use pnetcdf
+ implicit none
+#include "tests.inc"
+ LOGICAL INT_VEC_EQ
+
+ integer ncid
+ integer i
+ integer err
+ character*(NF90_MAX_NAME) name
+ integer datatype
+ integer ndims
+ integer dimids(MAX_RANK)
+ integer na
+ integer nok
+
+ nok = 0
+
+ err = nf90mpi_open(comm, testfile, NF90_NOWRITE, info, &
+ ncid)
+ if (err .NE. NF90_NOERR) &
+ call errore('nf90mpi_open: ', err)
+ do 1, i = 1, numVars
+ err = nf90mpi_inquire_variable(BAD_ID, i, name, datatype, ndims, &
+ dimids, na)
+ if (err .ne. NF90_EBADID) then
+ call errore('bad ncid: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nf90mpi_inquire_variable(ncid,BAD_VARID,name,datatype,ndims, &
+ dimids,na)
+ if (err .ne. NF90_ENOTVAR) then
+ call errore('bad var id: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nf90mpi_inquire_variable(ncid, i, name, datatype, ndims, dimids, &
+ na)
+ if (err .NE. NF90_NOERR) then
+ call errore('nf90mpi_inquire_variable: ', err)
+ else if (var_name(i) .ne. name) then
+ call errorc('name unexpected: ', name)
+ else if (var_type(i) .ne. datatype) then
+ call errori('type unexpected: ', datatype)
+ else if (var_rank(i) .ne. ndims) then
+ call errori('ndims expected: ', ndims)
+ else if (.not.int_vec_eq(var_dimid(1,i),dimids,ndims)) then
+ call error('unexpected dimid')
+ else if (var_natts(i) .ne. na) then
+ call errori('natts unexpected: ', na)
+ else
+ nok = nok + 1
+ end if
+1 continue
+ err = nf90mpi_close(ncid)
+ if (err .NE. NF90_NOERR) &
+ call errore('nf90mpi_close: ', err)
+ call print_nok(nok)
+ end
+
+
+ subroutine test_nf90mpi_inq_vardimid()
+ use pnetcdf
+ implicit none
+#include "tests.inc"
+ LOGICAL INT_VEC_EQ
+
+ integer ncid
+ integer i
+ integer err
+ integer dimids(MAX_RANK)
+ integer nok
+
+ nok = 0
+
+ err = nf90mpi_open(comm, testfile, NF90_NOWRITE, info, &
+ ncid)
+ if (err .NE. NF90_NOERR) &
+ call errore('nf90mpi_open: ', err)
+ do 1, i = 1, numVars
+ err = nf90mpi_inquire_variable(BAD_ID, i, dimids=dimids)
+ if (err .ne. NF90_EBADID) then
+ call errore('bad ncid: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nf90mpi_inquire_variable(ncid, BAD_VARID, dimids=dimids)
+ if (err .ne. NF90_ENOTVAR) then
+ call errore('bad var id: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nf90mpi_inquire_variable(ncid, i, dimids=dimids)
+ if (err .NE. NF90_NOERR) then
+ call errore('nf90mpi_inquire_variable: ', err)
+ else if (.not.int_vec_eq(var_dimid(1,i), dimids, &
+ var_rank(i))) then
+ call error('unexpected dimid')
+ print *, ' for variable ', i
+ else
+ nok = nok + 1
+ end if
+1 continue
+ err = nf90mpi_close(ncid)
+ if (err .NE. NF90_NOERR) &
+ call errore('nf90mpi_close: ', err)
+ call print_nok(nok)
+ end
+
+
+ subroutine test_nf90mpi_inq_varname()
+ use pnetcdf
+ implicit none
+#include "tests.inc"
+ integer ncid
+ integer i
+ integer err
+ character*(NF90_MAX_NAME) name
+ integer nok
+
+ nok = 0
+
+ err = nf90mpi_open(comm, testfile, NF90_NOWRITE, info, &
+ ncid)
+ if (err .NE. NF90_NOERR) &
+ call errore('nf90mpi_open: ', err)
+ do 1, i = 1, numVars
+ err = nf90mpi_inquire_variable(BAD_ID, i, name)
+ if (err .ne. NF90_EBADID) then
+ call errore('bad ncid: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nf90mpi_inquire_variable(ncid, BAD_VARID, name)
+ if (err .ne. NF90_ENOTVAR) then
+ call errore('bad var id: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nf90mpi_inquire_variable(ncid, i, name)
+ if (err .NE. NF90_NOERR) then
+ call errore('nf90mpi_inquire_variable: ', err)
+ else if (var_name(i) .ne. name) then
+ call errorc('name unexpected: ', name)
+ else
+ nok = nok + 1
+ end if
+1 continue
+ err = nf90mpi_close(ncid)
+ if (err .NE. NF90_NOERR) &
+ call errore('nf90mpi_close: ', err)
+ call print_nok(nok)
+ end
+
+
+ subroutine test_nf90mpi_inq_varnatts()
+ use pnetcdf
+ implicit none
+#include "tests.inc"
+ integer VARID, NATTS
+
+ integer ncid
+ integer i
+ integer err
+ integer na
+ integer nok
+
+ nok = 0
+
+ err = nf90mpi_open(comm, testfile, NF90_NOWRITE, info, &
+ ncid)
+ if (err .NE. NF90_NOERR) &
+ call errore('nf90mpi_open: ', err)
+ do 1, i = 0, numVars ! start with global attributes
+ err = nf90mpi_inquire_variable(BAD_ID, i, nAtts=na)
+ if (err .ne. NF90_EBADID) then
+ call errore('bad ncid: ', err)
+ else
+ nok = nok + 1
+ end if
+ err = nf90mpi_inquire_variable(ncid, BAD_VARID, nAtts=na)
+ if (err .ne. NF90_ENOTVAR) then
+ call errore('bad var id: ', err)
+ else
+ nok = nok + 1
+ end if
+ if (i .eq. 0) then
+ err = nf90mpi_inquire(ncid, nAttributes=na)
+ else
+ err = nf90mpi_inquire_variable(ncid, VARID(i), nAtts=na)
+ endif
+ if (err .NE. NF90_NOERR) then
+ call errore('nf90mpi_inquire_variable: ', err)
+ else if (NATTS(i) .ne. na) then ! works for global attributes
+ call errori('natts unexpected: ', na)
+ else
+ nok = nok + 1
+ end if
+1 continue
+ err = nf90mpi_close(ncid)
+ if (err .NE. NF90_NOERR) &
+ call errore('nf90mpi_close: ', err)
+ call print_nok(nok)
+ end
+
+
+ subroutine test_nf90mpi_inq_varndims()
+ use pnetcdf
+ implicit none
+#include "tests.inc"
+ integer ncid
+ integer i
+ integer err
+ integer ndims
+ integer nok
+
+ nok = 0
+
+ err = nf90mpi_open(comm, testfile, NF90_NOWRITE, info, &
+ ncid)
+ if (err .NE. NF90_NOERR) &
+ call errore('nf90mpi_open: ', err)
+ do 1, i = 1, numVars
+ err = nf90mpi_inquire_variable(BAD_ID, i, ndims=ndims)
+ if (err .ne. NF90_EBADID) then
+ call errore('bad ncid: ', err)
+ else
+ nok = nok + 1
+ end if
+ err = nf90mpi_inquire_variable(ncid, BAD_VARID, ndims=ndims)
+ if (err .ne. NF90_ENOTVAR) then
+ call errore('bad var id: ', err)
+ else
+ nok = nok + 1
+ end if
+ err = nf90mpi_inquire_variable(ncid, i, ndims=ndims)
+ if (err .NE. NF90_NOERR) then
+ call errore('nf90mpi_inquire_variable: ', err)
+ else if (var_rank(i) .ne. ndims) then
+ call errori('ndims unexpected: ', ndims)
+ else
+ nok = nok + 1
+ end if
+1 continue
+ err = nf90mpi_close(ncid)
+ if (err .NE. NF90_NOERR) &
+ call errore('nf90mpi_close: ', err)
+ call print_nok(nok)
+ end
+
+
+ subroutine test_nf90mpi_inq_vartype()
+ use pnetcdf
+ implicit none
+#include "tests.inc"
+ integer ncid
+ integer i
+ integer err
+ integer datatype
+ integer nok
+
+ nok = 0
+
+ err = nf90mpi_open(comm, testfile, NF90_NOWRITE, info, &
+ ncid)
+ if (err .NE. NF90_NOERR) &
+ call errore('nf90mpi_open: ', err)
+ do 1, i = 1, numVars
+ err = nf90mpi_inquire_variable(BAD_ID, i, xtype=datatype)
+ if (err .ne. NF90_EBADID) then
+ call errore('bad ncid: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nf90mpi_inquire_variable(ncid, BAD_VARID, xtype=datatype)
+ if (err .ne. NF90_ENOTVAR) then
+ call errore('bad var id: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nf90mpi_inquire_variable(ncid, i, xtype=datatype)
+ if (err .NE. NF90_NOERR) then
+ call errore('nf90mpi_inquire_variable: ', err)
+ else if (var_type(i) .ne. datatype) then
+ call errori('type unexpected: ', datatype)
+ nok = nok + 1
+ end if
+1 continue
+ err = nf90mpi_close(ncid)
+ if (err .NE. NF90_NOERR) &
+ call errore('nf90mpi_close: ', err)
+ call print_nok(nok)
+ end
+
+
+ subroutine test_nf90mpi_inq_att()
+ use pnetcdf
+ implicit none
+#include "tests.inc"
+ character*2 ATT_NAME
+ integer ATT_TYPE, ATT_LEN, NATTS
+
+ integer ncid, i, j, err, type, nok
+ integer(kind=MPI_OFFSET_KIND) alen
+
+ nok = 0
+
+ err = nf90mpi_open(comm, testfile, NF90_NOWRITE, info, &
+ ncid)
+ if (err .NE. NF90_NOERR) &
+ call errore('nf90mpi_open: ', err)
+
+ do 1, i = 0, numVars
+ ! NF90_GLOBAL is defined to be 0
+ do 2, j = 1, NATTS(i)
+ err = nf90mpi_inquire_attribute(BAD_ID, i, ATT_NAME(j,i), type, alen)
+ if (err .ne. NF90_EBADID) then
+ call errore('bad ncid: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nf90mpi_inquire_attribute &
+ (ncid, BAD_VARID, ATT_NAME(j,i), type, alen)
+ if (err .ne. NF90_ENOTVAR) then
+ call errore('bad var id: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nf90mpi_inquire_attribute(ncid, i, 'noSuch', type, alen)
+ if (err .ne. NF90_ENOTATT) then
+ call errore('Bad attribute name: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nf90mpi_inquire_attribute(ncid, i, ATT_NAME(j,i), type, alen)
+ if (err .NE. NF90_NOERR) then
+ call error(nf90mpi_strerror(err))
+ else
+ if (type .ne. ATT_TYPE(j,i)) then
+ print*,'ATT_NAME=',trim(ATT_NAME(j,i))
+ print*,'i=',i,' j=',j,' type=',type,' ATT_TYPE=',ATT_TYPE(j,i)
+ endif
+ if (type .ne. ATT_TYPE(j,i)) &
+ call error('type not that expected')
+ if (alen .ne. ATT_LEN(j,i)) &
+ call error('length not that expected')
+ nok = nok + 1
+ end if
+2 continue
+1 continue
+
+ err = nf90mpi_close(ncid)
+ if (err .NE. NF90_NOERR) &
+ call errore('nf90mpi_close: ', err)
+ call print_nok(nok)
+ end
+
+
+ subroutine test_nf90mpi_inq_attlen()
+ use pnetcdf
+ implicit none
+#include "tests.inc"
+ integer ATT_LEN, NATTS
+ character*2 ATT_NAME
+
+ integer ncid
+ integer i
+ integer j
+ integer err
+ integer(kind=MPI_OFFSET_KIND) len
+ integer nok
+
+ nok = 0
+
+ err = nf90mpi_open(comm, testfile, NF90_NOWRITE, info, &
+ ncid)
+ if (err .NE. NF90_NOERR) &
+ call errore('nf90mpi_open: ', err)
+
+ do 1, i = 0, numVars
+ err = nf90mpi_inquire_attribute(ncid, i, 'noSuch', len=len)
+ if (err .ne. NF90_ENOTATT) then
+ call errore('Bad attribute name: ', err)
+ else
+ nok = nok + 1
+ endif
+ do 2, j = 1, NATTS(i)
+ err = nf90mpi_inquire_attribute(BAD_ID, i, &
+ ATT_NAME(j,i), len=len)
+ if (err .ne. NF90_EBADID) then
+ call errore('bad ncid: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nf90mpi_inquire_attribute &
+ (ncid, BAD_VARID, ATT_NAME(j,i), len=len)
+ if (err .ne. NF90_ENOTVAR) then
+ call errore('bad varid: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nf90mpi_inquire_attribute(ncid, i, ATT_NAME(j,i), len=len)
+ if (err .NE. NF90_NOERR) then
+ call error(nf90mpi_strerror(err))
+ else
+ if (len .ne. ATT_LEN(j,i)) &
+ call error('len not that expected')
+ nok = nok + 1
+ end if
+2 continue
+1 continue
+
+ err = nf90mpi_close(ncid)
+ if (err .NE. NF90_NOERR) &
+ call errore('nf90mpi_close: ', err)
+ call print_nok(nok)
+ end
+
+
+ subroutine test_nf90mpi_inq_atttype()
+ use pnetcdf
+ implicit none
+#include "tests.inc"
+ character*2 ATT_NAME
+ integer ATT_TYPE, NATTS
+
+ integer ncid
+ integer i
+ integer j
+ integer err
+ integer datatype
+ integer nok
+
+ nok = 0
+
+ err = nf90mpi_open(comm, testfile, NF90_NOWRITE, info, &
+ ncid)
+ if (err .NE. NF90_NOERR) &
+ call errore('nf90mpi_open: ', err)
+
+ do 1, i = 0, numVars
+ err = nf90mpi_inquire_attribute(ncid, i, 'noSuch', datatype)
+ if (err .ne. NF90_ENOTATT) then
+ call errore('Bad attribute name: ', err)
+ else
+ nok = nok + 1
+ endif
+ do 2, j = 1, NATTS(i)
+ err = nf90mpi_inquire_attribute &
+ (BAD_ID, i, ATT_NAME(j,i), datatype)
+ if (err .ne. NF90_EBADID) then
+ call errore('bad ncid: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nf90mpi_inquire_attribute(ncid, BAD_VARID, ATT_NAME(j,i), &
+ datatype)
+ if (err .ne. NF90_ENOTVAR) then
+ call errore('bad varid: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nf90mpi_inquire_attribute &
+ (ncid, i, ATT_NAME(j,i), datatype)
+ if (err .NE. NF90_NOERR) then
+ call error(nf90mpi_strerror(err))
+ else
+ if (datatype .ne. ATT_TYPE(j,i)) &
+ call error('type not that expected')
+ nok = nok + 1
+ end if
+2 continue
+1 continue
+
+ err = nf90mpi_close(ncid)
+ if (err .NE. NF90_NOERR) &
+ call errore('nf90mpi_close: ', err)
+ call print_nok(nok)
+ end
+
+
+ subroutine test_nf90mpi_inq_attname()
+ use pnetcdf
+ implicit none
+#include "tests.inc"
+ character*2 ATT_NAME
+ integer NATTS
+
+ integer ncid
+ integer i
+ integer j
+ integer err
+ character*(NF90_MAX_NAME) name
+ integer nok
+
+ nok = 0
+
+ err = nf90mpi_open(comm, testfile, NF90_NOWRITE, info, &
+ ncid)
+ if (err .NE. NF90_NOERR) &
+ call errore('nf90mpi_open: ', err)
+
+ do 1, i = 0, numVars
+ err = nf90mpi_inq_attname(ncid, i, BAD_ATTNUM, name)
+ if (err .ne. NF90_ENOTATT) then
+ call errore('Bad attribute number: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nf90mpi_inq_attname(ncid, i, NATTS(i)+1, name)
+ if (err .ne. NF90_ENOTATT) then
+ call errore('Bad attribute number: ', err)
+ else
+ nok = nok + 1
+ endif
+ do 2, j = 1, NATTS(i)
+ err = nf90mpi_inq_attname(BAD_ID, i, j, name)
+ if (err .ne. NF90_EBADID) then
+ call errore('bad ncid: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nf90mpi_inq_attname(ncid, BAD_VARID, j, name)
+ if (err .ne. NF90_ENOTVAR) then
+ call errore('bad var id: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nf90mpi_inq_attname(ncid, i, j, name)
+ if (err .NE. NF90_NOERR) then
+ call error(nf90mpi_strerror(err))
+ else
+ if (ATT_NAME(j,i) .ne. name) &
+ call error('name not that expected')
+ nok = nok + 1
+ end if
+2 continue
+1 continue
+
+ err = nf90mpi_close(ncid)
+ if (err .NE. NF90_NOERR) &
+ call errore('nf90mpi_close: ', err)
+ call print_nok(nok)
+ end
+
+
+ subroutine test_nf90mpi_inq_attid()
+ use pnetcdf
+ implicit none
+#include "tests.inc"
+ character*2 ATT_NAME
+ integer NATTS
+
+ integer ncid
+ integer i
+ integer j
+ integer err
+ integer attnum
+ integer nok
+
+ nok = 0
+
+ err = nf90mpi_open(comm, testfile, NF90_NOWRITE, info, &
+ ncid)
+ if (err .NE. NF90_NOERR) &
+ call errore('nf90mpi_open: ', err)
+
+ do 1, i = 0, numVars
+ err = nf90mpi_inquire_attribute(ncid, i, 'noSuch', attnum=attnum)
+ if (err .ne. NF90_ENOTATT) then
+ call errore('Bad attribute name: ', err)
+ else
+ nok = nok + 1
+ endif
+ do 2, j = 1, NATTS(i)
+ err = nf90mpi_inquire_attribute(BAD_ID, i, &
+ ATT_NAME(j,i), attnum=attnum)
+ if (err .ne. NF90_EBADID) then
+ call errore('bad ncid: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nf90mpi_inquire_attribute(ncid, BAD_VARID, ATT_NAME(j,i), &
+ attnum=attnum)
+ if (err .ne. NF90_ENOTVAR) then
+ call errore('bad varid: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nf90mpi_inquire_attribute(ncid, i, &
+ ATT_NAME(j,i), attnum=attnum)
+ if (err .NE. NF90_NOERR) then
+ call error(nf90mpi_strerror(err))
+ else
+ if (attnum .ne. j) &
+ call error('attnum not that expected')
+ nok = nok + 1
+ end if
+2 continue
+1 continue
+
+ err = nf90mpi_close(ncid)
+ if (err .NE. NF90_NOERR) &
+ call errore('nf90mpi_close: ', err)
+ call print_nok(nok)
+ end
diff --git a/test/nf90_test/test_write.F90 b/test/nf90_test/test_write.F90
new file mode 100644
index 0000000..d879c46
--- /dev/null
+++ b/test/nf90_test/test_write.F90
@@ -0,0 +1,1755 @@
+!
+! Copyright (C) 2013, Northwestern University and Argonne National Laboratory
+! See COPYRIGHT notice in top-level directory.
+!
+! $Id: test_write.F90 2011 2015-02-14 19:48:35Z wkliao $
+!
+
+! Test nf90mpi_create
+! For mode in NF90_NOCLOBBER, NF90_CLOBBER do:
+! create netcdf file 'scratch.nc' with no data, close it
+! test that it can be opened, do nf90mpi_inq to check nvars = 0, etc.
+! Try again in NF90_NOCLOBBER mode, check error return
+! On exit, delete this file
+ subroutine test_nf90mpi_create()
+ use pnetcdf
+ implicit none
+#include "tests.inc"
+
+ integer clobber !/* 0 for NF90_NOCLOBBER, 1 for NF90_CLOBBER */
+ integer err
+ integer ncid
+ integer ndims !/* number of dimensions */
+ integer nvars !/* number of variables */
+ integer ngatts !/* number of global attributes */
+ integer recdim !/* id of unlimited dimension */
+ integer flags
+ integer nok
+
+ flags = IOR(NF90_NOCLOBBER, extra_flags)
+ nok = 0
+ do 1, clobber = 0, 1
+ err = nf90mpi_create(comm, scratch, flags, info, &
+ ncid)
+ if (err .ne. NF90_NOERR) then
+ call errore('nf90mpi_create: ', err)
+ end if
+ nok = nok + 1
+ err = nf90mpi_close(ncid)
+ if (err .ne. NF90_NOERR) then
+ call errore('nf90mpi_close: ', err)
+ end if
+ err = nf90mpi_open(comm, scratch, NF90_NOWRITE, info, &
+ ncid)
+ if (err .ne. NF90_NOERR) then
+ call errore('nf90mpi_open: ', err)
+ end if
+ err = nf90mpi_inquire(ncid, ndims, nvars, ngatts, recdim)
+ if (err .ne. NF90_NOERR) then
+ call errore('nf90mpi_inquire: ', err)
+ else if (ndims .ne. 0) then
+ call errori( &
+ 'nf90mpi_inquire: wrong number of dimensions returned, ', &
+ ndims)
+ else if (nvars .ne. 0) then
+ call errori( &
+ 'nf90mpi_inquire: wrong number of variables returned, ', &
+ nvars)
+ else if (ngatts .ne. 0) then
+ call errori( &
+ 'nf90mpi_inquire: wrong number of global atts returned, ', &
+ ngatts)
+ else if (recdim .ge. 1) then
+ call errori( &
+ 'nf90mpi_inquire: wrong record dimension ID returned, ', &
+ recdim)
+ end if
+ err = nf90mpi_close(ncid)
+ if (err .ne. NF90_NOERR) then
+ call errore('nf90mpi_close: ', err)
+ end if
+
+ flags = IOR(NF90_CLOBBER, extra_flags)
+1 continue
+
+ flags = IOR(NF90_NOCLOBBER, extra_flags)
+ err = nf90mpi_create(comm, scratch, flags, info, &
+ ncid)
+ if (err .ne. NF90_EEXIST) then
+ call errore('attempt to overwrite file: ', err)
+ end if
+ nok = nok + 1
+ err = nf90mpi_delete(scratch, info)
+ if (err .ne. NF90_NOERR) then
+ call errori('delete of scratch file failed: ', err)
+ end if
+ call print_nok(nok)
+ end
+
+
+! Test nf90mpi_redef
+! (In fact also tests nf90mpi_enddef - called from test_nf90mpi_enddef)
+! BAD_ID
+! attempt redef (error) & enddef on read-only file
+! create file, define dims & vars.
+! attempt put var (error)
+! attempt redef (error) & enddef.
+! put vars
+! attempt def new dims (error)
+! redef
+! def new dims, vars.
+! put atts
+! enddef
+! put vars
+! close
+! check file: vars & atts
+ subroutine test_nf90mpi_redef()
+ use pnetcdf
+ implicit none
+#include "tests.inc"
+ integer title_len
+ parameter (title_len = 9)
+
+ integer ncid !/* netcdf id */
+ integer dimid !/* dimension id */
+ integer vid !/* variable id */
+ integer err, flags
+ character*(title_len) title
+ doubleprecision var
+ character*(NF90_MAX_NAME) name
+ integer(kind=MPI_OFFSET_KIND) start(1)
+ integer(kind=MPI_OFFSET_KIND) length
+ integer intlen
+ integer dimids(1)
+ integer nok
+
+ nok = 0
+
+ title = 'Not funny'
+
+ ! BAD_ID tests
+ err = nf90mpi_redef(BAD_ID)
+ if (err .ne. NF90_EBADID) then
+ call errore('bad ncid: ', err)
+ endif
+ nok = nok + 1
+ err = nf90mpi_enddef(BAD_ID)
+ if (err .ne. NF90_EBADID) then
+ call errore('bad ncid: ', err)
+ endif
+ nok = nok + 1
+
+ ! read-only tests
+ err = nf90mpi_open(comm, testfile, NF90_NOWRITE, info, &
+ ncid)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_open: ', err)
+ err = nf90mpi_redef(ncid)
+ if (err .ne. NF90_EPERM) then
+ call errore('nf90mpi_redef in NF90_NOWRITE mode: ', err)
+ endif
+ nok = nok + 1
+ err = nf90mpi_enddef(ncid)
+ if (err .ne. NF90_ENOTINDEFINE) then
+ call errore('nf90mpi_redef in NF90_NOWRITE mode: ', err)
+ endif
+ nok = nok + 1
+ err = nf90mpi_close(ncid)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_close: ', err)
+
+! /* tests using scratch file */
+ flags = IOR(NF90_NOCLOBBER, extra_flags)
+ err = nf90mpi_create(comm, scratch, flags, info, &
+ ncid)
+ if (err .ne. NF90_NOERR) then
+ call errore('nf90mpi_create: ', err)
+ return
+ end if
+ call def_dims(ncid)
+ call def_vars(ncid)
+ call put_atts(ncid)
+ err = nf90mpi_inq_varid(ncid, 'd', vid)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_inq_varid: ', err)
+ var = 1.0
+! should not enter indep mode in define mode
+ err = nf90mpi_begin_indep_data(ncid)
+ if (err .ne. NF90_EINDEFINE) &
+ call errore('nf90mpi_begin_indep_data... in define mode: ', err)
+ start = 0
+ err = nf90mpi_put_var(ncid, vid, var, start)
+ if (err .ne. NF90_EINDEFINE) &
+ call errore('nf90mpi_put_var... in define mode: ', err)
+ err = nf90mpi_end_indep_data(ncid)
+ if (err .ne. NF90_ENOTINDEP) &
+ call errore('nf90mpi_end_indep_data... not in indep mode: ', err)
+ err = nf90mpi_redef(ncid)
+ if (err .ne. NF90_EINDEFINE) then
+ call errore('nf90mpi_redef in define mode: ', err)
+ endif
+ nok = nok + 1
+ err = nf90mpi_enddef(ncid)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_enddef: ', err)
+ call put_vars(ncid)
+ length = 8
+ err = nf90mpi_def_dim(ncid, 'abc', length, dimid)
+ if (err .ne. NF90_ENOTINDEFINE) &
+ call errore('nf90mpi_def_dim in define mode: ', err)
+ err = nf90mpi_redef(ncid)
+ if (err .ne. NF90_NOERR) then
+ call errore('nf90mpi_redef: ', err)
+ endif
+ nok = nok + 1
+ length = 8
+ err = nf90mpi_def_dim(ncid, 'abc', length, dimid)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_def_dim: ', err)
+ dimids(1) = 0
+ err = nf90mpi_def_var(ncid, 'abc', NF90_INT, varid=vid)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_def_var: ', err)
+ length = len(title)
+ err = nf90mpi_put_att(ncid, NF90_GLOBAL, 'title', &
+ title)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_put_att: ', err)
+ err = nf90mpi_enddef(ncid)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_enddef: ', err)
+ var = 1.0
+ err = nf90mpi_end_indep_data(ncid)
+ if (err .ne. NF90_ENOTINDEP) &
+ call errore('nf90mpi_end_indep_data: in collective mode: ',err)
+ err = nf90mpi_begin_indep_data(ncid)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_begin_indep_data: ', err)
+ err = nf90mpi_put_var(ncid, vid, var, start)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_put_var: ', err)
+ err = nf90mpi_end_indep_data(ncid)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_end_indep_data: ', err)
+ err = nf90mpi_close(ncid)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_close: ', err)
+
+! /* check scratch file written as expected */
+ call check_file(scratch)
+ err = nf90mpi_open(comm, scratch, NF90_NOWRITE, &
+ info, ncid)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_open: ', err)
+ err = nf90mpi_inquire_dimension(ncid, dimid, name, length)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_inquire_dimension: ', err)
+ if (name .ne. "abc") &
+ call errori('Unexpected dim name in netCDF ', ncid)
+ if (length .ne. 8) then
+ intlen = INT(length)
+ call errori('Unexpected dim length: ', intlen)
+ end if
+ err = nf90mpi_begin_indep_data(ncid)
+ err = nf90mpi_get_var(ncid, vid, var, start)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_get_var: ', err)
+ if (var .ne. 1.0) &
+ call errori( &
+ 'nf90mpi_get_var: unexpected value in netCDF ' &
+ , ncid)
+ err = nf90mpi_end_indep_data(ncid)
+ err = nf90mpi_close(ncid)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_close: ', err)
+
+ err = nf90mpi_delete(scratch, info)
+ if (err .ne. NF90_NOERR) &
+ call errori('delete failed for netCDF: ', err)
+ call print_nok(nok)
+ end
+
+! Test nf90mpi_enddef
+! Simply calls test_nf90mpi_redef which tests both nf90mpi_redef & nf90mpi_enddef
+
+ subroutine test_nf90mpi_enddef()
+ use pnetcdf
+ implicit none
+#include "tests.inc"
+
+ call test_nf90mpi_redef
+ end
+
+
+! Test nf90mpi_sync
+! try with bad handle, check error
+! try in define mode, check error
+! try writing with one handle, reading with another on same netCDF
+ subroutine test_nf90mpi_sync()
+ use pnetcdf
+ implicit none
+#include "tests.inc"
+
+ integer ncidw !/* netcdf id for writing */
+ integer ncidr !/* netcdf id for reading */
+ integer err, flags
+ integer nok
+
+ nok = 0
+! /* BAD_ID test */
+ err = nf90mpi_sync(BAD_ID)
+ if (err .ne. NF90_EBADID) then
+ call errore('bad ncid: ', err)
+ else
+ nok = nok + 1
+ endif
+
+! /* create scratch file & try nf90mpi_sync in define mode */
+ flags = IOR(NF90_NOCLOBBER, extra_flags)
+ err = nf90mpi_create(comm, scratch, flags, info, &
+ ncidw)
+ if (err .ne. NF90_NOERR) then
+ call errore('nf90mpi_create: ', err)
+ return
+ end if
+ err = nf90mpi_sync(ncidw)
+ if (err .ne. NF90_EINDEFINE) then
+ call errore('nf90mpi_sync called in define mode: ', err)
+ else
+ nok = nok + 1
+ endif
+
+! /* write using same handle */
+ call def_dims(ncidw)
+ call def_vars(ncidw)
+ call put_atts(ncidw)
+ err = nf90mpi_enddef(ncidw)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_enddef: ', err)
+ call put_vars(ncidw)
+ err = nf90mpi_sync(ncidw)
+ if (err .ne. NF90_NOERR) then
+ call errore('nf90mpi_sync of ncidw failed: ', err)
+ else
+ nok = nok + 1
+ endif
+
+! /* open another handle, nf90mpi_sync, read (check) */
+ err = nf90mpi_open(comm, scratch, NF90_NOWRITE, info, &
+ ncidr)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_open: ', err)
+ err = nf90mpi_sync(ncidr)
+ if (err .ne. NF90_NOERR) then
+ call errore('nf90mpi_sync of ncidr failed: ', err)
+ else
+ nok = nok + 1
+ endif
+ call check_dims(ncidr)
+ call check_atts(ncidr)
+ call check_vars(ncidr)
+
+! /* close both handles */
+ err = nf90mpi_close(ncidr)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_close: ', err)
+ err = nf90mpi_close(ncidw)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_close: ', err)
+
+ err = nf90mpi_delete(scratch, info)
+ if (err .ne. NF90_NOERR) &
+ call errori('delete of scratch file failed: ', err)
+ call print_nok(nok)
+ end
+
+
+! Test nf90mpi_abort
+! try with bad handle, check error
+! try in define mode before anything written, check that file was deleted
+! try after nf90mpi_enddef, nf90mpi_redef, define new dims, vars, atts
+! try after writing variable
+ subroutine test_nf90mpi_abort()
+ use pnetcdf
+ implicit none
+#include "tests.inc"
+
+ integer ncid !/* netcdf id */
+ integer err, flags
+ integer ndims
+ integer nvars
+ integer ngatts
+ integer recdim
+ integer nok
+
+ nok = 0
+
+! /* BAD_ID test */
+ err = nf90mpi_abort(BAD_ID)
+ if (err .ne. NF90_EBADID) then
+ call errore('bad ncid: status = ', err)
+ else
+ nok = nok + 1
+ endif
+
+! /* create scratch file & try nf90mpi_abort in define mode */
+ flags = IOR(NF90_NOCLOBBER, extra_flags)
+ err = nf90mpi_create(comm, scratch, flags, info, &
+ ncid)
+ if (err .ne. NF90_NOERR) then
+ call errore('nf90mpi_create: ', err)
+ return
+ end if
+ call def_dims(ncid)
+ call def_vars(ncid)
+ call put_atts(ncid)
+ err = nf90mpi_abort(ncid)
+ if (err .ne. NF90_NOERR) then
+ call errore('nf90mpi_abort of ncid failed: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nf90mpi_close(ncid) !/* should already be closed */
+ if (err .ne. NF90_EBADID) &
+ call errore('bad ncid: ', err)
+ err = nf90mpi_delete(scratch, info) !/* should already be deleted */
+ if (err .eq. NF90_NOERR) &
+ call errori('scratch file should not exist: ', err)
+
+! create scratch file
+! do nf90mpi_enddef & nf90mpi_redef
+! define new dims, vars, atts
+! try nf90mpi_abort: should restore previous state (no dims, vars, atts)
+ flags = IOR(NF90_NOCLOBBER, extra_flags)
+ err = nf90mpi_create(comm, scratch, flags, info, &
+ ncid)
+ if (err .ne. NF90_NOERR) then
+ call errore('nf90mpi_create: ', err)
+ return
+ end if
+ err = nf90mpi_enddef(ncid)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_enddef: ', err)
+ err = nf90mpi_redef(ncid)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_redef: ', err)
+ call def_dims(ncid)
+ call def_vars(ncid)
+ call put_atts(ncid)
+ err = nf90mpi_abort(ncid)
+ if (err .ne. NF90_NOERR) then
+ call errore('nf90mpi_abort of ncid failed: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nf90mpi_close(ncid) !/* should already be closed */
+ if (err .ne. NF90_EBADID) &
+ call errore('bad ncid: ', err)
+ err = nf90mpi_open(comm, scratch, NF90_NOWRITE, info, &
+ ncid)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_open: ', err)
+ err = nf90mpi_inquire(ncid, ndims, nvars, ngatts, recdim)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_inquire: ', err)
+ if (ndims .ne. 0) &
+ call errori('ndims should be ', 0)
+ if (nvars .ne. 0) &
+ call errori('nvars should be ', 0)
+ if (ngatts .ne. 0) &
+ call errori('ngatts should be ', 0)
+ err = nf90mpi_close (ncid)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_close: ', err)
+
+! /* try nf90mpi_abort in data mode - should just close */
+ flags = IOR(NF90_CLOBBER, extra_flags)
+ err = nf90mpi_create(comm, scratch, flags, info, &
+ ncid)
+ if (err .ne. NF90_NOERR) then
+ call errore('nf90mpi_create: ', err)
+ return
+ end if
+ call def_dims(ncid)
+ call def_vars(ncid)
+ call put_atts(ncid)
+ err = nf90mpi_enddef(ncid)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_enddef: ', err)
+ call put_vars(ncid)
+ err = nf90mpi_abort(ncid)
+ if (err .ne. NF90_NOERR) then
+ call errore('nf90mpi_abort of ncid failed: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nf90mpi_close(ncid) !/* should already be closed */
+ if (err .ne. NF90_EBADID) &
+ call errore('bad ncid: ', err)
+ call check_file(scratch)
+ err = nf90mpi_delete(scratch, info)
+ if (err .ne. NF90_NOERR) &
+ call errori('delete of scratch file failed: ', err)
+ call print_nok(nok)
+ end
+
+
+! Test nf90mpi_def_dim
+! try with bad netCDF handle, check error
+! try in data mode, check error
+! check that returned id is one more than previous id
+! try adding same dimension twice, check error
+! try with illegal sizes, check error
+! make sure unlimited size works, shows up in nf90mpi_inq_unlimdim
+! try to define a second unlimited dimension, check error
+ subroutine test_nf90mpi_def_dim()
+ use pnetcdf
+ implicit none
+#include "tests.inc"
+
+ integer ncid
+ integer err !/* status */
+ integer i
+ integer dimid !/* dimension id */
+ integer(kind=MPI_OFFSET_KIND) length
+ integer nok, flags
+
+ nok = 0
+
+! /* BAD_ID test */
+ length = 8
+ err = nf90mpi_def_dim(BAD_ID, 'abc', length, dimid)
+ if (err .ne. NF90_EBADID) then
+ call errore('bad ncid: ', err)
+ else
+ nok = nok + 1
+ endif
+
+! /* data mode test */
+ flags = IOR(NF90_CLOBBER, extra_flags)
+ err = nf90mpi_create(comm, scratch, flags, info, &
+ ncid)
+ if (err .ne. NF90_NOERR) then
+ call errore('nf90mpi_create: ', err)
+ return
+ end if
+ err = nf90mpi_enddef(ncid)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_enddef: ', err)
+ length = 8
+ err = nf90mpi_def_dim(ncid, 'abc', length, dimid)
+ if (err .ne. NF90_ENOTINDEFINE) then
+ call errore('bad ncid: ', err)
+ else
+ nok = nok + 1
+ endif
+
+! /* define-mode tests: unlimited dim */
+ err = nf90mpi_redef(ncid)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_redef: ', err)
+ err = nf90mpi_def_dim(ncid, dim_name(1), NF90MPI_UNLIMITED, dimid)
+ if (err .ne. NF90_NOERR) then
+ call errore('nf90mpi_def_dim: ', err)
+ else
+ nok = nok + 1
+ endif
+ if (dimid .ne. 1) &
+ call errori('Unexpected dimid: ', dimid)
+ err = nf90mpi_inquire(ncid, unlimitedDimId=dimid)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_inquire: ', err)
+ if (dimid .ne. RECDIM) &
+ call error('Unexpected recdim: ')
+ err = nf90mpi_inquire_dimension(ncid, dimid, len=length)
+ if (length .ne. 0) &
+ call errori('Unexpected length: ', 0)
+ err = nf90mpi_def_dim(ncid, 'abc', NF90MPI_UNLIMITED, dimid)
+ if (err .ne. NF90_EUNLIMIT) then
+ call errore('2nd unlimited dimension: ', err)
+ else
+ nok = nok + 1
+ endif
+
+! /* define-mode tests: remaining dims */
+ do 1, i = 2, NDIMS
+ err = nf90mpi_def_dim(ncid, dim_name(i-1), dim_len(i), &
+ dimid)
+ if (err .ne. NF90_ENAMEINUSE) then
+ call errore('duplicate name: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nf90mpi_def_dim(ncid, BAD_NAME, dim_len(i), dimid)
+ if (err .ne. NF90_EBADNAME) then
+ call errore('bad name: ', err)
+ else
+ nok = nok + 1
+ endif
+ length = NF90MPI_UNLIMITED - 1
+ err = nf90mpi_def_dim(ncid, dim_name(i), length, &
+ dimid)
+ if (err .ne. NF90_EDIMSIZE) then
+ call errore('bad size: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nf90mpi_def_dim(ncid, dim_name(i), dim_len(i), dimid)
+ if (err .ne. NF90_NOERR) then
+ call errore('nf90mpi_def_dim: ', err)
+ else
+ nok = nok + 1
+ endif
+ if (dimid .ne. i) &
+ call errori('Unexpected dimid: ', 0)
+1 continue
+
+! /* Following just to expand unlimited dim */
+ call def_vars(ncid)
+ err = nf90mpi_enddef(ncid)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_enddef: ', err)
+ call put_vars(ncid)
+
+! /* Check all dims */
+ call check_dims(ncid)
+
+ err = nf90mpi_close(ncid)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_close: ', err)
+ err = nf90mpi_delete(scratch, info)
+ if (err .ne. NF90_NOERR) &
+ call errori('delete of scratch file failed: ', err)
+ call print_nok(nok)
+ end
+
+
+! Test nf90mpi_rename_dim
+! try with bad netCDF handle, check error
+! check that proper rename worked with nf90mpi_inquire_dimension
+! try renaming to existing dimension name, check error
+! try with bad dimension handle, check error
+ subroutine test_nf90mpi_rename_dim()
+ use pnetcdf
+ implicit none
+#include "tests.inc"
+
+ integer ncid
+ integer err !/* status */
+ character*(NF90_MAX_NAME) name
+ integer nok, flags
+
+ nok = 0
+
+! /* BAD_ID test */
+ err = nf90mpi_rename_dim(BAD_ID, 1, 'abc')
+ if (err .ne. NF90_EBADID) then
+ call errore('bad ncid: ', err)
+ else
+ nok = nok + 1
+ endif
+
+! /* main tests */
+ flags = IOR(NF90_NOCLOBBER, extra_flags)
+ err = nf90mpi_create(comm, scratch, flags, info, &
+ ncid)
+ if (err .ne. NF90_NOERR) then
+ call errore('nf90mpi_create: ', err)
+ return
+ end if
+ call def_dims(ncid)
+ err = nf90mpi_rename_dim(ncid, BAD_DIMID, 'abc')
+ if (err .ne. NF90_EBADDIM) then
+ call errore('bad dimid: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nf90mpi_rename_dim(ncid, 3, 'abc')
+ if (err .ne. NF90_NOERR) then
+ call errore('nf90mpi_rename_dim: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nf90mpi_inquire_dimension(ncid, 3, name)
+ if (name .ne. 'abc') &
+ call errorc('Unexpected name: ', name)
+ err = nf90mpi_rename_dim(ncid, 1, 'abc')
+ if (err .ne. NF90_ENAMEINUSE) then
+ call errore('duplicate name: ', err)
+ else
+ nok = nok + 1
+ endif
+
+ err = nf90mpi_close(ncid)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_close: ', err)
+ err = nf90mpi_delete(scratch, info)
+ if (err .ne. NF90_NOERR) &
+ call errori('delete of scratch file failed: ', err)
+ call print_nok(nok)
+ end
+
+
+! Test nf90mpi_def_var
+! try with bad netCDF handle, check error
+! try with bad name, check error
+! scalar tests:
+! check that proper define worked with nf90mpi_inq_var
+! try redefining an existing variable, check error
+! try with bad datatype, check error
+! try with bad number of dimensions, check error
+! try in data mode, check error
+! check that returned id is one more than previous id
+! try with bad dimension ids, check error
+ subroutine test_nf90mpi_def_var()
+ use pnetcdf
+ implicit none
+#include "tests.inc"
+
+ integer ncid
+ integer vid
+ integer err !/* status */
+ integer i
+ integer ndims
+ integer na
+ character*(NF90_MAX_NAME) name
+ integer dimids(MAX_RANK)
+ integer datatype
+ integer nok, flags
+
+ nok = 0
+
+! /* BAD_ID test */
+ err = nf90mpi_def_var(BAD_ID, 'abc', NF90_SHORT, varid=vid)
+ if (err .ne. NF90_EBADID) then
+ call errore('bad ncid: status = ', err)
+ else
+ nok = nok + 1
+ endif
+
+! scalar tests
+ flags = IOR(NF90_NOCLOBBER, extra_flags)
+ err = nf90mpi_create(comm, scratch, flags, info, &
+ ncid)
+ if (err .ne. NF90_NOERR) then
+ call errore('nf90mpi_create: ', err)
+ return
+ end if
+ err = nf90mpi_def_var(ncid, 'abc', NF90_SHORT, varid=vid)
+ if (err .ne. NF90_NOERR) then
+ call errore('nf90mpi_def_var: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nf90mpi_inquire_variable(ncid, vid, name, datatype, ndims, dimids, &
+ na)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_inquire_variable: ', err)
+ if (name .ne. 'abc') &
+ call errorc('Unexpected name: ', name)
+ if (datatype .ne. NF90_SHORT) &
+ call error('Unexpected datatype')
+ if (ndims .ne. 0) &
+ call error('Unexpected rank')
+ err = nf90mpi_def_var(ncid, BAD_NAME, NF90_SHORT, varid=vid)
+ if (err .ne. NF90_EBADNAME) then
+ call errore('bad name: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nf90mpi_def_var(ncid, 'abc', NF90_SHORT, varid=vid)
+ if (err .ne. NF90_ENAMEINUSE) then
+ call errore('duplicate name: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nf90mpi_def_var(ncid, 'ABC', BAD_TYPE, varid=vid)
+ if (err .ne. NF90_EBADTYPE) then
+ call errore('bad type: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nf90mpi_enddef(ncid)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_enddef: ', err)
+ err = nf90mpi_def_var(ncid, 'ABC', NF90_SHORT, varid=vid)
+ if (err .ne. NF90_ENOTINDEFINE) then
+ call errore('nf90mpi_def_var called in data mode: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nf90mpi_close(ncid)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_close: ', err)
+ err = nf90mpi_delete(scratch, info)
+ if (err .ne. NF90_NOERR) &
+ call errorc('delete of scratch file failed: ', scratch)
+
+! /* general tests using global vars */
+ flags = IOR(NF90_CLOBBER, extra_flags)
+ err = nf90mpi_create(comm, scratch, flags, info, &
+ ncid)
+ if (err .ne. NF90_NOERR) then
+ call errore('nf90mpi_create: ', err)
+ return
+ end if
+ call def_dims(ncid)
+ do 1, i = 1, numVars
+ err = nf90mpi_def_var(ncid, var_name(i), var_type(i), &
+ var_dimid(1:var_rank(i),i), vid)
+ if (err .ne. NF90_NOERR) then
+ call errore('nf90mpi_def_var: ', err)
+ else
+ nok = nok + 1
+ endif
+ if (vid .ne. i) &
+ call error('Unexpected varid')
+1 continue
+
+! /* try bad dim ids */
+ dimids(1) = BAD_DIMID
+ err = nf90mpi_def_var(ncid, 'abc', NF90_SHORT, dimids(1:1), vid)
+ if (err .ne. NF90_EBADDIM) then
+ call errore('bad dim ids: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nf90mpi_close(ncid)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_close: ', err)
+
+ err = nf90mpi_delete(scratch, info)
+ if (err .ne. NF90_NOERR) &
+ call errorc('delete of scratch file failed: ', scratch)
+ call print_nok(nok)
+ end
+
+
+! Test nf90mpi_rename_var
+! try with bad netCDF handle, check error
+! try with bad variable handle, check error
+! try renaming to existing variable name, check error
+! check that proper rename worked with nf90mpi_inq_varid
+! try in data mode, check error
+ subroutine test_nf90mpi_rename_var()
+ use pnetcdf
+ implicit none
+#include "tests.inc"
+
+ integer ncid
+ integer vid
+ integer err
+ integer i
+ character*(NF90_MAX_NAME) name
+ integer nok, flags
+
+ nok = 0
+
+ flags = IOR(NF90_NOCLOBBER, extra_flags)
+ err = nf90mpi_create(comm, scratch, flags, info, &
+ ncid)
+ if (err .ne. NF90_NOERR) then
+ call errore('nf90mpi_create: ', err)
+ return
+ end if
+ err = nf90mpi_rename_var(ncid, BAD_VARID, 'newName')
+ if (err .ne. NF90_ENOTVAR) then
+ call errore('bad var id: ', err)
+ else
+ nok = nok + 1
+ endif
+ call def_dims(ncid)
+ call def_vars(ncid)
+
+! /* Prefix "new_" to each name */
+ do 1, i = 1, numVars
+ err = nf90mpi_rename_var(BAD_ID, i, 'newName')
+ if (err .ne. NF90_EBADID) then
+ call errore('bad ncid: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nf90mpi_rename_var(ncid, i, var_name(numVars))
+ if (err .ne. NF90_ENAMEINUSE) then
+ call errore('duplicate name: ', err)
+ else
+ nok = nok + 1
+ endif
+ name = 'new_' // var_name(i)
+ err = nf90mpi_rename_var(ncid, i, name)
+ if (err .ne. NF90_NOERR) then
+ call errore('nf90mpi_rename_var: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nf90mpi_inq_varid(ncid, name, vid)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_inq_varid: ', err)
+ if (vid .ne. i) &
+ call error('Unexpected varid')
+1 continue
+
+! /* Change to data mode */
+! /* Try making names even longer. Then restore original names */
+ err = nf90mpi_enddef(ncid)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_enddef: ', err)
+ do 2, i = 1, numVars
+ name = 'even_longer_' // var_name(i)
+ err = nf90mpi_rename_var(ncid, i, name)
+ if (err .ne. NF90_ENOTINDEFINE) then
+ call errore('longer name in data mode: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nf90mpi_rename_var(ncid, i, var_name(i))
+ if (err .ne. NF90_NOERR) then
+ call errore('nf90mpi_rename_var: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nf90mpi_inq_varid(ncid, var_name(i), vid)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_inq_varid: ', err)
+ if (vid .ne. i) &
+ call error('Unexpected varid')
+2 continue
+
+ call put_vars(ncid)
+ call check_vars(ncid)
+
+ err = nf90mpi_close(ncid)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_close: ', err)
+
+ err = nf90mpi_delete(scratch, info)
+ if (err .ne. NF90_NOERR) &
+ call errorc('delete of scratch file failed: ', scratch)
+ call print_nok(nok)
+ end
+
+
+! Test nf90mpi_copy_att
+! try with bad source or target netCDF handles, check error
+! try with bad source or target variable handle, check error
+! try with nonexisting attribute, check error
+! check that NF90_GLOBAL variable for source or target works
+! check that new attribute put works with target in define mode
+! check that old attribute put works with target in data mode
+! check that changing type and length of an attribute work OK
+! try with same ncid for source and target, different variables
+! try with same ncid for source and target, same variable
+ subroutine test_nf90mpi_copy_att()
+ use pnetcdf
+ implicit none
+#include "tests.inc"
+ character*2 ATT_NAME
+ integer VARID, NATTS, ATT_LEN
+
+ integer ncid_in
+ integer ncid_out
+ integer vid
+ integer err
+ integer i
+ integer j
+ character*(NF90_MAX_NAME) name !/* of att */
+ integer datatype !/* of att */
+ integer(kind=MPI_OFFSET_KIND) length !/* of att */
+ character*1 value
+ integer nok, flags
+
+ nok = 0
+ err = nf90mpi_open(comm, testfile, NF90_NOWRITE, info, &
+ ncid_in)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_open: ', err)
+ flags = IOR(NF90_NOCLOBBER, extra_flags)
+ err = nf90mpi_create(comm, scratch, flags, info, &
+ ncid_out)
+ if (err .ne. NF90_NOERR) then
+ call errore('nf90mpi_create: ', err)
+ return
+ end if
+ call def_dims(ncid_out)
+ call def_vars(ncid_out)
+
+ do 1, i = 0, numVars
+ vid = VARID(i)
+ do 2, j = 1, NATTS(i)
+ name = ATT_NAME(j,i)
+ err = nf90mpi_copy_att(ncid_in, BAD_VARID, name, &
+ ncid_out, vid)
+ if (err .ne. NF90_ENOTVAR) &
+ call errore('bad var id: ', err)
+ nok = nok + 1
+ err = nf90mpi_copy_att(ncid_in, vid, name, ncid_out, &
+ BAD_VARID)
+ if (err .ne. NF90_ENOTVAR) &
+ call errore('bad var id: ', err)
+ nok = nok + 1
+ err = nf90mpi_copy_att(BAD_ID, vid, name, &
+ ncid_out, vid)
+ if (err .ne. NF90_EBADID) &
+ call errore('bad ncid: ', err)
+ nok = nok + 1
+ err = nf90mpi_copy_att(ncid_in, vid, name, &
+ BAD_ID, vid)
+ if (err .ne. NF90_EBADID) &
+ call errore('bad ncid: ', err)
+ nok = nok + 1
+ err = nf90mpi_copy_att(ncid_in, vid, 'noSuch', &
+ ncid_out, vid)
+ if (err .ne. NF90_ENOTATT) &
+ call errore('bad attname: ', err)
+ nok = nok + 1
+ err = nf90mpi_copy_att(ncid_in, vid, name, &
+ ncid_out, vid)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_copy_att: ', err)
+ nok = nok + 1
+ err = nf90mpi_copy_att(ncid_out, vid, name, &
+ ncid_out, vid)
+ if (err .ne. NF90_NOERR) &
+ call errore('source = target: ', err)
+ nok = nok + 1
+2 continue
+1 continue
+
+ err = nf90mpi_close(ncid_in)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_close: ', err)
+
+! /* Close scratch. Reopen & check attributes */
+ err = nf90mpi_close(ncid_out)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_close: ', err)
+ err = nf90mpi_open(comm, scratch, NF90_WRITE, info, &
+ ncid_out)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_open: ', err)
+ call check_atts(ncid_out)
+
+! change to define mode
+! define single char. global att. ':a' with value 'A'
+! This will be used as source for following copies
+ err = nf90mpi_redef(ncid_out)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_redef: ', err)
+ length = 1
+ err = nf90mpi_put_att(ncid_out, NF90_GLOBAL, 'a', 'A')
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_put_att: ', err)
+
+! change to data mode
+! Use scratch as both source & dest.
+! try copy to existing att. change type & decrease length
+! rename 1st existing att of each var (if any) 'a'
+! if this att. exists them copy ':a' to it
+ err = nf90mpi_enddef(ncid_out)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_enddef: ', err)
+ do 3, i = 1, numVars
+ if (NATTS(i) .gt. 0 .and. ATT_LEN(1,i) .gt. 0) then
+ err = nf90mpi_rename_att(ncid_out, i, &
+ att_name(1,i), 'a')
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_rename_att: ', err)
+ err = nf90mpi_copy_att(ncid_out, NF90_GLOBAL, 'a', &
+ ncid_out, i)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_copy_att: ', err)
+ nok = nok + 1
+ end if
+3 continue
+ err = nf90mpi_close(ncid_out)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_close: ', err)
+
+! /* Reopen & check */
+ err = nf90mpi_open(comm, scratch, NF90_WRITE, info, &
+ ncid_out)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_open: ', err)
+ do 4, i = 1, numVars
+ if (NATTS(i) .gt. 0 .and. ATT_LEN(1,i) .gt. 0) then
+ err = nf90mpi_inquire_attribute(ncid_out, i, 'a', &
+ datatype, length)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_inquire_attribute: ', err)
+ if (datatype .ne. NF90_CHAR) &
+ call error('Unexpected type')
+ if (length .ne. 1) &
+ call error('Unexpected length')
+ err = nf90mpi_get_att(ncid_out, i, 'a', value)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_get_att: ', err)
+ if (value .ne. 'A') &
+ call error('Unexpected value')
+ end if
+4 continue
+
+ err = nf90mpi_close(ncid_out)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_close: ', err)
+ err = nf90mpi_delete(scratch, info)
+ if (err .ne. NF90_NOERR) &
+ call errorc('delete of scratch file failed', scratch)
+ call print_nok(nok)
+ end
+
+
+! Test nf90mpi_rename_att
+! try with bad netCDF handle, check error
+! try with bad variable handle, check error
+! try with nonexisting att name, check error
+! try renaming to existing att name, check error
+! check that proper rename worked with nf90mpi_inq_attid
+! try in data mode, check error
+ subroutine test_nf90mpi_rename_att()
+ use pnetcdf
+ implicit none
+#include "tests.inc"
+ character*2 ATT_NAME
+ integer VARID, ATT_TYPE, NATTS, ATT_LEN
+ double precision hash
+ logical equal, inrange
+
+ integer ncid
+ integer vid
+ integer err, flags
+ integer i
+ integer j
+ integer k
+ integer attnum
+ character*(NF90_MAX_NAME) atnam
+ character*(NF90_MAX_NAME) name
+ character*(NF90_MAX_NAME) oldname
+ character*(NF90_MAX_NAME) newname
+ integer nok !/* count of valid comparisons */
+ integer datatype
+ integer attyp
+ integer(kind=MPI_OFFSET_KIND) length
+ integer(kind=MPI_OFFSET_KIND) attlength
+ integer(kind=MPI_OFFSET_KIND) ndx(1)
+ character*(MAX_NELS) text
+ doubleprecision value(MAX_NELS)
+ doubleprecision expect
+
+ nok = 0
+
+ flags = IOR(NF90_NOCLOBBER, extra_flags)
+ err = nf90mpi_create(comm, scratch, flags, info, &
+ ncid)
+ if (err .ne. NF90_NOERR) then
+ call errore('nf90mpi_create: ', err)
+ return
+ end if
+ err = nf90mpi_rename_att(ncid, BAD_VARID, 'abc', 'newName')
+ if (err .ne. NF90_ENOTVAR) &
+ call errore('bad var id: ', err)
+ call def_dims(ncid)
+ call def_vars(ncid)
+ call put_atts(ncid)
+
+ do 1, i = 0, numVars
+ vid = VARID(i)
+ do 2, j = 1, NATTS(i)
+ atnam = ATT_NAME(j,i)
+ err = nf90mpi_rename_att(BAD_ID, vid, atnam, &
+ 'newName')
+ if (err .ne. NF90_EBADID) &
+ call errore('bad ncid: ', err)
+ err = nf90mpi_rename_att(ncid, vid, 'noSuch', &
+ 'newName')
+ if (err .ne. NF90_ENOTATT) &
+ call errore('bad attname: ', err)
+ newname = 'new_' // trim(atnam)
+ err = nf90mpi_rename_att(ncid, vid, atnam, newname)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_rename_att: ', err)
+ err = nf90mpi_inquire_attribute(ncid, vid, newname, attnum=attnum)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_inquire_attribute: ', err)
+ if (attnum .ne. j) &
+ call error('Unexpected attnum')
+2 continue
+1 continue
+
+! /* Close. Reopen & check */
+ err = nf90mpi_close(ncid)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_close: ', err)
+ err = nf90mpi_open(comm, scratch, NF90_WRITE, info, &
+ ncid)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_open: ', err)
+
+ do 3, i = 0, numVars
+ vid = VARID(i)
+ do 4, j = 1, NATTS(i)
+ atnam = ATT_NAME(j,i)
+ attyp = ATT_TYPE(j,i)
+ attlength = ATT_LEN(j,i)
+ newname = 'new_' // trim(atnam)
+ err = nf90mpi_inq_attname(ncid, vid, j, name)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_inq_attname: ', err)
+ if (name .ne. newname) &
+ call error('nf90mpi_inq_attname: unexpected name')
+ err = nf90mpi_inquire_attribute(ncid, vid, name, &
+ datatype, length)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_inquire_attribute: ', err)
+ if (datatype .ne. attyp) &
+ call error('nf90mpi_inquire_attribute: unexpected type')
+ if (length .ne. attlength) &
+ call error('nf90mpi_inquire_attribute: unexpected length')
+ if (datatype .eq. NF90_CHAR) then
+ err = nf90mpi_get_att(ncid, vid, name, text)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_get_att: ', err)
+ do 5, k = 1, INT(attlength)
+ ndx(1) = k
+ expect = hash(datatype, -1, ndx)
+ if (ichar(text(k:k)) .ne. expect) then
+ call error( &
+ 'nf90mpi_get_att: unexpected value')
+ else
+ nok = nok + 1
+ end if
+5 continue
+ else
+ err = nf90mpi_get_att(ncid, vid, name, &
+ value)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_get_att: ', err)
+ do 6, k = 1, INT(attlength)
+ ndx(1) = k
+ expect = hash(datatype, -1, ndx)
+ if (inRange(expect, datatype)) then
+ if (.not. equal(value(k),expect,datatype, &
+ NF90_DOUBLE)) then
+ call error( &
+ 'nf90mpi_get_att: unexpected value')
+ else
+ nok = nok + 1
+ end if
+ end if
+6 continue
+ end if
+4 continue
+3 continue
+ call print_nok(nok)
+
+! /* Now in data mode */
+! /* Try making names even longer. Then restore original names */
+
+ do 7, i = 0, numVars
+ vid = VARID(i)
+ do 8, j = 1, NATTS(i)
+ atnam = ATT_NAME(j,i)
+ oldname = 'new_' // trim(atnam)
+ newname = 'even_longer_' // trim(atnam)
+ err = nf90mpi_rename_att(ncid, vid, oldname, newname)
+ if (err .ne. NF90_ENOTINDEFINE) &
+ call errore('longer name in data mode: ', err)
+ err = nf90mpi_rename_att(ncid, vid, oldname, atnam)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_rename_att: ', err)
+ err = nf90mpi_inquire_attribute(ncid, vid, atnam, attnum=attnum)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_inquire_attribute: ', err)
+ if (attnum .ne. j) &
+ call error('Unexpected attnum')
+8 continue
+7 continue
+
+ err = nf90mpi_close(ncid)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_close: ', err)
+
+ err = nf90mpi_delete(scratch, info)
+ if (err .ne. NF90_NOERR) &
+ call errori('delete of scratch file failed: ', err)
+ end
+
+
+! Test nf90mpi_del_att
+! try with bad netCDF handle, check error
+! try with bad variable handle, check error
+! try with nonexisting att name, check error
+! check that proper delete worked using:
+! nf90mpi_inq_attid, nf90mpi_inq_natts, nf90mpi_inq_varnatts
+ subroutine test_nf90mpi_del_att()
+ use pnetcdf
+ implicit none
+#include "tests.inc"
+ character*2 ATT_NAME
+ integer VARID, NATTS
+
+ integer ncid
+ integer err, flags
+ integer i
+ integer j
+ integer attnum
+ integer na
+ integer numatts
+ integer vid
+ character*(NF90_MAX_NAME) name !/* of att */
+ integer nok !/* count of valid comparisons */
+
+ nok = 0
+
+ flags = IOR(NF90_NOCLOBBER, extra_flags)
+ err = nf90mpi_create(comm, scratch, flags, info, &
+ ncid)
+ if (err .ne. NF90_NOERR) then
+ call errore('nf90mpi_create: ', err)
+ return
+ end if
+ err = nf90mpi_del_att(ncid, BAD_VARID, 'abc')
+ if (err .ne. NF90_ENOTVAR) then
+ call errore('bad var id: ', err)
+ else
+ nok = nok + 1
+ endif
+ call def_dims(ncid)
+ call def_vars(ncid)
+ call put_atts(ncid)
+
+ do 1, i = 0, numVars
+ vid = VARID(i)
+ numatts = NATTS(i)
+ do 2, j = 1, numatts
+ name = ATT_NAME(j,i)
+ err = nf90mpi_del_att(BAD_ID, vid, name)
+ if (err .ne. NF90_EBADID) then
+ call errore('bad ncid: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nf90mpi_del_att(ncid, vid, 'noSuch')
+ if (err .ne. NF90_ENOTATT) then
+ call errore('bad attname: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nf90mpi_del_att(ncid, vid, name)
+ if (err .ne. NF90_NOERR) then
+ call errore('nf90mpi_del_att: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nf90mpi_inquire_attribute(ncid, vid, name, attnum=attnum)
+ if (err .ne. NF90_ENOTATT) &
+ call errore('bad attname: ', err)
+ if (i .lt. 1) then
+ err = nf90mpi_inquire(ncid, nAttributes=na)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_inquire: ', err)
+ if (na .ne. numatts-j) then
+ call errori('natts: expected: ', numatts-j)
+ call errori('natts: got: ', na)
+ endif
+ else
+ err = nf90mpi_inquire_variable(ncid, vid, nAtts=na)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_inquire_variable: ', err)
+ if (na .ne. numatts-j) then
+ call errori('natts: expected: ', numatts-j)
+ call errori('natts: got: ', na)
+ endif
+ endif
+2 continue
+1 continue
+
+! /* Close. Reopen & check no attributes left */
+ err = nf90mpi_close(ncid)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_close: ', err)
+ err = nf90mpi_open(comm, scratch, NF90_WRITE, &
+ info, ncid)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_open: ', err)
+ err = nf90mpi_inquire(ncid, nAttributes=na)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_inquire: ', err)
+ if (na .ne. 0) &
+ call errori('natts: expected 0, got ', na)
+ do 3, i = 0, numVars
+ vid = VARID(i)
+ err = nf90mpi_inquire(ncid, nAttributes=na)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_inquire: ', err)
+ if (na .ne. 0) &
+ call errori('natts: expected 0, got ', na)
+3 continue
+
+! /* restore attributes. change to data mode. try to delete */
+ err = nf90mpi_redef(ncid)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_redef: ', err)
+ call put_atts(ncid)
+ err = nf90mpi_enddef(ncid)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_enddef: ', err)
+
+ do 4, i = 0, numVars
+ vid = VARID(i)
+ numatts = NATTS(i)
+ do 5, j = 1, numatts
+ name = ATT_NAME(j,i)
+ err = nf90mpi_del_att(ncid, vid, name)
+ if (err .ne. NF90_ENOTINDEFINE) then
+ call errore('in data mode: ', err)
+ else
+ nok = nok + 1
+ endif
+5 continue
+4 continue
+
+ err = nf90mpi_close(ncid)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_close: ', err)
+ err = nf90mpi_delete(scratch, info)
+ if (err .ne. NF90_NOERR) &
+ call errori('delete of scratch file failed: ', err)
+ call print_nok(nok)
+ end
+
+! parallel-netcdf doesn't implement set_fill, so i have not
+! parallel-netcdfified this subroutine
+! Test nf90mpi_set_fill
+! try with bad netCDF handle, check error
+! try in read-only mode, check error
+! try with bad new_fillmode, check error
+! try in data mode, check error
+! check that proper set to NF90_FILL works for record & non-record variables
+! (note that it is not possible to test NF90_NOFILL mode!)
+! close file & create again for test using attribute _FillValue
+ subroutine test_nf90mpi_set_fill()
+ use pnetcdf
+ implicit none
+#include "tests.inc"
+ ! character*2 ATT_NAME
+ ! integer VARID, ATT_TYPE, NATTS
+
+ integer ncid
+ integer vid
+ integer err, flags
+ integer i
+ integer j
+ integer old_fillmode
+ character*1 text
+ doubleprecision value
+ doubleprecision fill, fills(1)
+ integer(kind=MPI_OFFSET_KIND) index(MAX_RANK)
+ integer(kind=MPI_OFFSET_KIND) length
+ integer index2indexes
+ integer nok !/* count of valid comparisons */
+
+ value = 0
+ nok = 0
+
+! /* bad ncid */
+ err = nf90mpi_set_fill(BAD_ID, NF90_NOFILL, old_fillmode)
+ if (err .ne. NF90_EBADID) &
+ call errore('bad ncid: ', err)
+
+! /* try in read-only mode */
+ err = nf90mpi_open(comm, testfile, NF90_NOWRITE, info, &
+ ncid)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_open: ', err)
+ err = nf90mpi_set_fill(ncid, NF90_NOFILL, old_fillmode)
+ if (err .ne. NF90_EPERM) &
+ call errore('read-only: ', err)
+ err = nf90mpi_close(ncid)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_close: ', err)
+
+! /* create scratch */
+ flags = IOR(NF90_NOCLOBBER, extra_flags)
+ err = nf90mpi_create(comm, scratch, flags, info, &
+ ncid)
+ if (err .ne. NF90_NOERR) then
+ call errore('nf90mpi_create: ', err)
+ return
+ end if
+
+! /* BAD_FILLMODE */
+ err = nf90mpi_set_fill(ncid, BAD_FILLMODE, old_fillmode)
+ if (err .ne. NF90_EINVAL) &
+ call errore('bad fillmode: ', err)
+
+! /* proper calls */
+ err = nf90mpi_set_fill(ncid, NF90_FILL, old_fillmode)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_set_fill: ', err)
+ if (old_fillmode .ne. NF90_NOFILL) &
+ call errori('Unexpected old fill mode: ', old_fillmode)
+ err = nf90mpi_set_fill(ncid, NF90_NOFILL, old_fillmode)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_set_fill: ', err)
+ if (old_fillmode .ne. NF90_FILL) &
+ call errori('Unexpected old fill mode: ', old_fillmode)
+ err = nf90mpi_set_fill(ncid, NF90_FILL, old_fillmode)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_set_fill: ', err)
+
+! /* define dims & vars */
+ call def_dims(ncid)
+ call def_vars(ncid)
+
+! /* Change to data mode. Set fillmode again */
+ err = nf90mpi_enddef(ncid)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_enddef: ', err)
+ err = nf90mpi_set_fill(ncid, NF90_FILL, old_fillmode)
+ if (err .ne. NF90_ENOTINDEFINE) &
+ call errore('nf90mpi_set_fill: ', err)
+
+! /* Write record number NRECS to force writing of preceding records */
+! /* Assumes variable cr is char vector with UNLIMITED dimension */
+ err = nf90mpi_inq_varid(ncid, 'cr', vid)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_inq_varid: ', err)
+ index(1) = NRECS
+ text = char(NF90_FILL_CHAR)
+ err = nf90mpi_put_var_all(ncid, vid, text, index)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_put_var_all: ', err)
+
+! /* get all variables & check all values equal default fill */
+ do 1, i = 1, numVars
+ if (var_dimid(var_rank(i),i) .eq. RECDIM) cycle ! skip record variables
+
+ if (var_type(i) .eq. NF90_CHAR) then
+ fill = NF90_FILL_CHAR
+ else if (var_type(i) .eq. NF90_BYTE) then
+ fill = NF90_FILL_BYTE
+ else if (var_type(i) .eq. NF90_SHORT) then
+ fill = NF90_FILL_SHORT
+ else if (var_type(i) .eq. NF90_INT) then
+ fill = NF90_FILL_INT
+ else if (var_type(i) .eq. NF90_FLOAT) then
+ fill = NF90_FILL_FLOAT
+ else if (var_type(i) .eq. NF90_DOUBLE) then
+ fill = NF90_FILL_DOUBLE
+ else if (var_type(i) .eq. NF90_UBYTE) then
+ fill = NF90_FILL_UBYTE
+ else if (var_type(i) .eq. NF90_USHORT) then
+ fill = NF90_FILL_USHORT
+ else if (var_type(i) .eq. NF90_UINT) then
+ fill = NF90_FILL_UINT
+ else if (var_type(i) .eq. NF90_INT64) then
+ fill = NF90_FILL_INT64
+ else if (var_type(i) .eq. NF90_UINT64) then
+ fill = NF90_FILL_UINT64
+ else
+ stop 'test_nf90mpi_set_fill(): impossible var_type(i)'
+ end if
+
+ do 2, j = 1, var_nels(i)
+ err = index2indexes(j, var_rank(i), var_shape(1,i), &
+ index)
+ if (err .ne. NF90_NOERR) &
+ call error('error in index2indexes()')
+ if (var_type(i) .eq. NF90_CHAR) then
+ err = nf90mpi_get_var_all(ncid, i, text, index)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_get_var_all failed: ',err)
+ value = ichar(text)
+ else
+ err = nf90mpi_get_var_all(ncid, i, value, index)
+ if (err .ne. NF90_NOERR) &
+ call errore &
+ ('nf90mpi_get_var_all failed: ',err)
+ end if
+ if (value .ne. fill .and. &
+ abs((fill - value)/fill) .gt. 1.0e-9) then
+ call errord('Unexpected fill value: ', value)
+ else
+ nok = nok + 1
+ end if
+2 continue
+1 continue
+
+! /* close scratch & create again for test using attribute _FillValue */
+ err = nf90mpi_close(ncid)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_close: ', err)
+ flags = IOR(NF90_CLOBBER, extra_flags)
+ err = nf90mpi_create(comm, scratch, flags, info, &
+ ncid)
+ if (err .ne. NF90_NOERR) then
+ call errore('nf90mpi_create: ', err)
+ return
+ end if
+ call def_dims(ncid)
+ call def_vars(ncid)
+
+! /* set _FillValue = 42 for all vars */
+ fill = 42
+ text = char(int(fill))
+ length = 1
+ do 3, i = 1, numVars
+ if (var_dimid(var_rank(i),i) .eq. RECDIM) cycle ! skip record variables
+
+ if (var_type(i) .eq. NF90_CHAR) then
+ err = nf90mpi_put_att(ncid, i, '_FillValue', &
+ text)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_put_att: ', err)
+ else
+ ! cannot use overloading, as fill's type must match with variable's
+ ! err = nf90mpi_put_att(ncid, i, '_FillValue', fill)
+ fills(1) = fill
+ err = nfmpi_put_att_double(ncid, i, '_FillValue', &
+ var_type(i),length,fills(1))
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_put_att: ', err)
+ end if
+3 continue
+
+! /* data mode. write records */
+ err = nf90mpi_enddef(ncid)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_enddef: ', err)
+ index(1) = NRECS
+ err = nf90mpi_put_var_all(ncid, vid, text, index)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_put_var_all: ', err)
+
+! /* get all variables & check all values equal 42 */
+ do 4, i = 1, numVars
+ if (var_dimid(var_rank(i),i) .eq. RECDIM) cycle ! skip record variables
+
+ do 5, j = 1, var_nels(i)
+ err = index2indexes(j, var_rank(i), var_shape(1,i), &
+ index)
+ if (err .ne. NF90_NOERR) &
+ call error('error in index2indexes')
+ if (var_type(i) .eq. NF90_CHAR) then
+ err = nf90mpi_get_var_all(ncid, i, text, index)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_get_var_all failed: ',err)
+ value = ichar(text)
+ else
+ err = nf90mpi_get_var_all(ncid, i, value, index)
+ if (err .ne. NF90_NOERR) &
+ call errore &
+ ('nf90mpi_get_var_all failed: ', err)
+ end if
+ if (value .ne. fill) then
+ call errord(' Value expected: ', fill)
+ call errord(' Value read: ', value)
+ else
+ nok = nok + 1
+ end if
+5 continue
+4 continue
+
+ err = nf90mpi_close(ncid)
+ if (err .ne. NF90_NOERR) &
+ call errore('nf90mpi_close: ', err)
+ err = nf90mpi_delete(scratch, info)
+ if (err .ne. NF90_NOERR) &
+ call errori('delete of scratch file failed: ', err)
+
+ call print_nok(nok)
+ end
+
+#if 0
+! * Test nc_set_default_format
+! * try with bad default format
+! * try with NULL old_formatp
+! * try in data mode, check error
+! * check that proper set to NC_FILL works for record & non-record variables
+! * (note that it is not possible to test NC_NOFILL mode!)
+! * close file & create again for test using attribute _FillValue
+ subroutine test_nf90mpi_set_default_format()
+ use pnetcdf
+ implicit none
+#include "tests.inc"
+
+ integer ncid
+ integer err, flags
+ integer i
+ integer version
+ integer old_format
+ integer nf90mpi_get_file_version
+
+! /* bad format */
+ err = nf90mpi_set_default_format(3, old_format)
+ IF (err .ne. NF90_EINVAL) &
+ call errore("bad default format: status = %d", err)
+
+! /* Cycle through available formats. */
+ do 1 i=1, 2
+ err = nf90mpi_set_default_format(i, old_format)
+ if (err .ne. NF90_NOERR) &
+ call errore("setting classic format: status = %d", err)
+ flags = IOR(NF90_CLOBBER, extra_flags)
+ err = nf90mpi_create(comm, scratch, flags, &
+ info, ncid)
+ if (err .ne. NF90_NOERR) &
+ call errore("bad nf90mpi_create: status = %d", err)
+ err = nf90mpi_put_att_text(ncid, NF90_GLOBAL, "testatt", &
+ "blah")
+ if (err .ne. NF90_NOERR) call errore("bad put_att: status = %d", err)
+ err = nf90mpi_close(ncid)
+ if (err .ne. NF90_NOERR) call errore("bad close: status = %d", err)
+ err = nf90mpi_get_file_version(scratch, version)
+ if (err .ne. NF90_NOERR) call errore("bad file version = %d", err)
+ if (version .ne. i) &
+ call errore("bad file version = %d", err)
+ 1 continue
+
+! /* Remove the left-over file. */
+ err = nf90mpi_delete(scratch)
+ if (err .ne. NF90_NOERR) call errore("remove failed", err)
+ end
+
+#endif
+
+! This function looks in a file for the netCDF magic number.
+ integer function nf90mpi_get_file_version(path, version)
+ use pnetcdf
+ implicit none
+#include "tests.inc"
+
+ character*(*) path
+ integer version
+ character magic*4
+ integer ver
+ integer f
+ parameter (f = 10)
+
+ open(f, file=path, status='OLD', form='UNFORMATTED', &
+ access='DIRECT', recl=4)
+
+! Assume this is not a netcdf file.
+ nf90mpi_get_file_version = NF90_ENOTNC
+ version = 0
+
+! Read the magic number, the first 4 bytes of the file.
+ read(f, rec=1, err = 1) magic
+
+! If the first three characters are not "CDF" we're done.
+ if (index(magic, 'CDF') .eq. 1) then
+ ver = ichar(magic(4:4))
+ if (ver .eq. 1) then
+ version = 1
+ nf90mpi_get_file_version = NF90_NOERR
+ elseif (ver .eq. 2) then
+ version = 2
+ nf90mpi_get_file_version = NF90_NOERR
+ endif
+ endif
+
+ 1 close(f)
+ return
+ end
+
+
diff --git a/test/nf90_test/tests.inc b/test/nf90_test/tests.inc
new file mode 100644
index 0000000..296fb3f
--- /dev/null
+++ b/test/nf90_test/tests.inc
@@ -0,0 +1,230 @@
+!
+! Copyright (C) 2013, Northwestern University and Argonne National Laboratory
+! See COPYRIGHT notice in top-level directory.
+!
+! $Id: tests.inc 2137 2015-10-07 23:53:04Z wkliao $
+!
+
+ integer, parameter :: INT1_KIND = selected_int_kind(2)
+ integer, parameter :: INT2_KIND = selected_int_kind(4)
+ integer, parameter :: INT8_KIND = selected_int_kind(18)
+
+!!!!
+! Do not tabify this unless you like hitting the 72 char limit !!!
+!!!
+#ifndef UD_TESTS_INC
+#define UD_TESTS_INC
+
+
+!/* The following prevents non-FORTRAN code from appearing in the output. */
+#if defined(__osf__)
+# undef _POSIX_SOURCE
+# define _POSIX_SOURCE
+#endif
+
+#define NO_NETCDF_2 1
+
+#include "../libf/nfconfig.inc"
+
+
+!/* Parameters of test data */
+
+#ifdef NF_INT1_T
+# define NF_B 1
+#else
+# define NF_B 0
+#endif
+#ifdef NF_INT2_T
+# define NF_S 1
+#else
+# define NF_S 0
+#endif
+! Total number of FORTRAN types:
+#define NUM_FORTRAN_TYPES (3 + NF_S + NF_B)
+#undef NF_B
+#undef NF_S
+
+#define NTYPES 11
+#define NDIMS 5
+#define NRECS 2
+#define NGATTS NTYPES
+#define RECDIM 1
+#define MAX_RANK 3
+#define MAX_NELS 64
+#define MAX_DIM_LEN 4
+#define MAX_NATTS 3
+
+#define NVARS 166
+!
+! #define NVARS 136 when NTYPES==6
+! #define NVARS 142 when NTYPES==7
+! #define NVARS 148 when NTYPES==8
+! #define NVARS 154 when NTYPES==9
+! #define NVARS 160 when NTYPES==10
+! #define NVARS 166 when NTYPES==11
+! c:char, b:byte, s:short, i:int, f:float, d:double, y:ubyte, t:ushort,
+! u:uint, x:int64, z:uint64
+!
+
+
+!/*
+! * Limits of external types (based on those in ncx.h):
+! */
+#define X_CHAR_MIN 0
+#define X_CHAR_MAX 127
+#define X_INT1_MIN (-128)
+#define X_INT1_MAX 127
+#define X_INT2_MIN (-32768)
+#define X_INT2_MAX 32767
+#define X_INT_MIN (-2147483647-1)
+#define X_INT_MAX 2147483647
+#if 0
+#define X_REAL_MAX 3.4028234663852886e+38
+#else
+#define X_REAL_MAX 3.4028234663852886e+37
+#endif
+#define X_REAL_MIN (-X_FLOAT_MAX)
+#if 0
+#define X_DOUBLE_MAX 1.7976931348623157E+308
+#else
+#define X_DOUBLE_MAX 1.7976931348623157D+200
+#endif
+#define X_DOUBLE_MIN (-X_DOUBLE_MAX)
+#define X_INT8_MIN (-9223372036854775807_INT8_KIND)
+#define X_INT8_MAX 9223372036854775807_INT8_KIND
+#define X_UINT8_MIN (-18446744073709551615.0)
+#define X_UINT8_MAX 18446744073709551615.0
+
+#define X_BYTE_MIN X_INT1_MIN
+#define X_BYTE_MAX X_INT1_MAX
+#define X_SHORT_MIN X_INT2_MIN
+#define X_SHORT_MAX X_INT2_MAX
+#define X_FLOAT_MIN X_REAL_MIN
+#define X_FLOAT_MAX X_REAL_MAX
+
+#define X_UCHAR_MAX 255
+#define X_UCHAR_MIN 0
+#define X_UBYTE_MAX X_UCHAR_MAX
+#define X_UBYTE_MIN X_UCHAR_MIN
+#define X_USHORT_MAX 65535
+#define X_USHORT_MIN 0
+#define X_UINT_MAX 4294967295_INT8_KIND
+#define X_UINT_MIN 0
+
+
+!/*
+! * Examples of invalid argument values:
+! */
+#define BAD_ID -1
+#define BAD_DIMID -1
+#define BAD_VARID -2
+#define BAD_ATTNUM -1
+#define BAD_TYPE 0
+#define BAD_FILLMODE -1
+#define BAD_NAME 'a/b'
+
+
+!/*
+! * Internal data types:
+! */
+#define NFT_UNSPECIFIED 0
+#define NFT_TEXT 16
+#define NFT_CHAR NFT_TEXT
+#define NFT_INT1 17
+#define NFT_INT2 18
+#define NFT_INT 20
+#define NFT_REAL 36
+#define NFT_DOUBLE 40
+#define NFT_INT8 43
+
+
+!/*
+! * Define a macro for trimming trailing blanks from character variables.
+! */
+
+
+!
+! FORTRAN GETARG() subroutine:
+!
+#ifdef __hpux
+# define getarg getarg_
+#endif
+
+
+#endif /* UD_TESTS_INC */
+
+#include "mpif.h"
+
+
+! /* Global variables - filenames */
+
+ CHARACTER*128 testfile !/* netCDF read-only test data */
+ CHARACTER*128 scratch !/* netCDF test file for writing */
+
+! /* Global variables - command-line arguments */
+
+ LOGICAL CREATE_FILE
+ LOGICAL READONLY
+ LOGICAL VERBOSE
+ INTEGER NFAILS
+ INTEGER MAX_NMPT !/* max num messages per test */
+
+! /* Global variables - test data */
+
+ CHARACTER*2 DIM_NAME(NDIMS)
+ integer(kind=MPI_OFFSET_KIND) DIM_LEN(NDIMS)
+ CHARACTER*(2+MAX_RANK) VAR_NAME(NVARS)
+ INTEGER VAR_TYPE(NVARS)
+ INTEGER VAR_RANK(NVARS)
+ INTEGER VAR_DIMID(MAX_RANK,NVARS)
+ integer(kind=MPI_OFFSET_KIND) VAR_SHAPE(MAX_RANK,NVARS)
+ INTEGER VAR_NELS(NVARS)
+ INTEGER VAR_NATTS(NVARS)
+ CHARACTER*2 ATTNAME(MAX_NATTS,NVARS)
+ CHARACTER*2 GATT_NAME(NGATTS)
+ INTEGER ATTTYPE(NGATTS,NVARS)
+ INTEGER GATT_TYPE(NGATTS)
+ INTEGER ATTLEN(MAX_NATTS,NVARS)
+ integer(kind=MPI_OFFSET_KIND) GATT_LEN(NGATTS)
+
+! /* Miscellaneous global variables: */
+ CHARACTER*128 PROGNAME !/* name of the program */
+ INTEGER COMM !/* MPI communicator */
+
+ INTEGER NFAILSTOTAL
+
+! /* Common blocks for global variables: */
+
+!/* MPI_OFFSET */
+ COMMON /OFFSETCOM/ DIM_LEN, VAR_SHAPE, GATT_LEN
+
+ COMMON /MPICOM/ COMM
+ COMMON /LOGCOM/ CREATE_FILE, &
+ READONLY, & !/* don't change files */
+ VERBOSE !/* print details of tests */
+
+ COMMON /TXTCOM/ TESTFILE, &
+ SCRATCH, &
+ DIM_NAME, &
+ VAR_NAME, &
+ ATTNAME, &
+ GATT_NAME, &
+ PROGNAME
+
+ COMMON /INTCOM/ NFAILS, & ! number of failures in specific test
+ VAR_TYPE, &
+ VAR_RANK, &
+ VAR_DIMID, &
+ VAR_NELS, &
+ VAR_NATTS, &
+ ATTTYPE, &
+ GATT_TYPE, &
+ ATTLEN, &
+ MAX_NMPT, &
+ NFAILSTOTAL
+
+
+ integer numTypes, numVars, numGatts, cdf_format, extra_flags, info
+ common / PROBLEM_SIZE / numTypes, numVars, numGatts, cdf_format, &
+ extra_flags, info
+
diff --git a/test/nf90_test/util.F90 b/test/nf90_test/util.F90
new file mode 100644
index 0000000..f961d81
--- /dev/null
+++ b/test/nf90_test/util.F90
@@ -0,0 +1,1514 @@
+!
+! Copyright (C) 2013, Northwestern University and Argonne National Laboratory
+! See COPYRIGHT notice in top-level directory.
+!
+! $Id: util.F90 2284 2015-12-30 20:27:18Z wkliao $
+!
+
+ SUBROUTINE PRINT_NOK(NOK)
+ USE PNETCDF
+ IMPLICIT NONE
+ INTEGER NOK
+#include "tests.inc"
+
+ 123 FORMAT(I4,A)
+ IF (NFAILS .GT. 0) PRINT *, ' '
+ IF (VERBOSE) THEN
+ PRINT 123, NOK, ' good comparisons.'
+ ENDIF
+ END
+
+
+! Is value within external type range? */
+ logical FUNCTION INRANGE(VALUE, DATATYPE)
+ USE PNETCDF
+ IMPLICIT NONE
+ DOUBLEPRECISION VALUE
+ INTEGER DATATYPE
+#include "tests.inc"
+
+ DOUBLEPRECISION MIN
+ DOUBLEPRECISION MAX
+
+ MIN = X_DOUBLE_MIN
+ MAX = X_DOUBLE_MAX
+ IF (DATATYPE .EQ. NF90_CHAR) THEN
+ MIN = X_CHAR_MIN
+ MAX = X_CHAR_MAX
+ ELSE IF (DATATYPE .EQ. NF90_BYTE) THEN
+ MIN = X_BYTE_MIN
+ MAX = X_BYTE_MAX
+ ELSE IF (DATATYPE .EQ. NF90_SHORT) THEN
+ MIN = X_SHORT_MIN
+ MAX = X_SHORT_MAX
+ ELSE IF (DATATYPE .EQ. NF90_INT) THEN
+ MIN = X_INT_MIN
+ MAX = X_INT_MAX
+ ELSE IF (DATATYPE .EQ. NF90_FLOAT) THEN
+ MIN = X_FLOAT_MIN
+ MAX = X_FLOAT_MAX
+ ELSE IF (DATATYPE .EQ. NF90_DOUBLE) THEN
+ MIN = X_DOUBLE_MIN
+ MAX = X_DOUBLE_MAX
+ ELSE IF (DATATYPE .EQ. NF90_UBYTE) THEN
+ MIN = 0
+ MAX = X_UCHAR_MAX
+ ELSE IF (DATATYPE .EQ. NF90_USHORT) THEN
+ MIN = 0
+ MAX = X_USHORT_MAX
+ ELSE IF (DATATYPE .EQ. NF90_UINT) THEN
+ MIN = 0
+ MAX = X_UINT_MAX
+ ELSE IF (DATATYPE .EQ. NF90_INT64) THEN
+ INRANGE = (VALUE .GE. X_INT8_MIN) .AND. &
+ (VALUE .LE. X_INT8_MAX)
+ return
+ ELSE IF (DATATYPE .EQ. NF90_UINT64) THEN
+ INRANGE = (VALUE .GE. 0) .AND. &
+ (VALUE .LE. X_UINT8_MAX)
+ return
+ ELSE
+ CALL UD_ABORT
+ END IF
+
+ INRANGE = (VALUE .GE. MIN) .AND. (VALUE .LE. MAX)
+ END
+
+
+ logical FUNCTION INRANGE_UCHAR(VALUE, DATATYPE)
+ USE PNETCDF
+ IMPLICIT NONE
+ DOUBLEPRECISION VALUE
+ INTEGER DATATYPE
+#include "tests.inc"
+ LOGICAL INRANGE
+
+ IF (DATATYPE .EQ. NF90_BYTE) THEN
+ INRANGE_UCHAR = (VALUE .GE. 0) .AND. (VALUE .LE. 255)
+ ELSE
+ INRANGE_UCHAR = INRANGE(VALUE, DATATYPE)
+ END IF
+ END
+
+
+ logical FUNCTION INRANGE_FLOAT(VALUE, DATATYPE)
+ USE PNETCDF
+ IMPLICIT NONE
+ DOUBLEPRECISION VALUE
+ INTEGER DATATYPE
+#include "tests.inc"
+ double precision internal_max
+
+ DOUBLEPRECISION MIN
+ DOUBLEPRECISION MAX
+ REAL FVALUE
+
+ MIN = X_DOUBLE_MIN
+ MAX = X_DOUBLE_MAX
+
+ IF (DATATYPE .EQ. NF90_CHAR) THEN
+ MIN = X_CHAR_MIN
+ MAX = X_CHAR_MAX
+ ELSE IF (DATATYPE .EQ. NF90_BYTE) THEN
+ MIN = X_BYTE_MIN
+ MAX = X_BYTE_MAX
+ ELSE IF (DATATYPE .EQ. NF90_SHORT) THEN
+ MIN = X_SHORT_MIN
+ MAX = X_SHORT_MAX
+ ELSE IF (DATATYPE .EQ. NF90_INT) THEN
+ MIN = X_INT_MIN
+ MAX = X_INT_MAX
+ ELSE IF (DATATYPE .EQ. NF90_FLOAT) THEN
+ IF (internal_max(NFT_REAL) .LT. X_FLOAT_MAX) THEN
+ MIN = -internal_max(NFT_REAL)
+ MAX = internal_max(NFT_REAL)
+ ELSE
+ MIN = X_FLOAT_MIN
+ MAX = X_FLOAT_MAX
+ END IF
+ ELSE IF (DATATYPE .EQ. NF90_DOUBLE) THEN
+ IF (internal_max(NFT_REAL) .LT. X_DOUBLE_MAX) THEN
+ MIN = -internal_max(NFT_REAL)
+ MAX = internal_max(NFT_REAL)
+ ELSE
+ MIN = X_DOUBLE_MIN
+ MAX = X_DOUBLE_MAX
+ END IF
+ ELSE IF (DATATYPE .EQ. NF90_UBYTE) THEN
+ MIN = 0
+ MAX = X_UCHAR_MAX
+ ELSE IF (DATATYPE .EQ. NF90_USHORT) THEN
+ MIN = 0
+ MAX = X_USHORT_MAX
+ ELSE IF (DATATYPE .EQ. NF90_UINT) THEN
+ MIN = 0
+ MAX = X_UINT_MAX
+ ELSE IF (DATATYPE .EQ. NF90_INT64) THEN
+ MIN = X_INT8_MIN
+ MAX = X_INT8_MAX
+ ELSE IF (DATATYPE .EQ. NF90_UINT64) THEN
+ MIN = 0
+ MAX = X_UINT8_MAX
+ ELSE
+ CALL UD_ABORT
+ END IF
+
+ IF (.NOT.((VALUE .GE. MIN) .AND. (VALUE .LE. MAX))) THEN
+ INRANGE_FLOAT = .FALSE.
+ ELSE
+ FVALUE = REAL(VALUE)
+ INRANGE_FLOAT = (FVALUE .GE. MIN) .AND. (FVALUE .LE. MAX)
+ END IF
+ END
+
+
+! wrapper for inrange to handle special NF90_BYTE/uchar adjustment */
+ logical function inrange3(value, datatype, itype)
+ use pnetcdf
+ implicit none
+ doubleprecision value
+ integer datatype
+ integer itype
+#include "tests.inc"
+ logical inrange_float, inrange
+
+ if (itype .eq. NFT_REAL) then
+ inrange3 = inrange_float(value, datatype)
+ else
+ inrange3 = inrange(value, datatype)
+ end if
+ end
+
+
+!
+! Does x == y, where one is internal and other external (netCDF)?
+! Use tolerant comparison based on IEEE FLT_EPSILON or DBL_EPSILON.
+!
+ logical function equal(x, y, extType, itype)
+ use pnetcdf
+ implicit none
+ doubleprecision x
+ doubleprecision y
+ integer extType !!/* external data type */
+ integer itype
+#include "tests.inc"
+
+ doubleprecision epsilon
+
+ if ((extType .eq. NF90_REAL) .or. (itype .eq. NFT_REAL)) then
+ epsilon = 1.19209290E-07
+ else
+ epsilon = 2.2204460492503131E-16
+ end if
+ equal = abs(x-y) .le. epsilon * max( abs(x), abs(y))
+ end
+
+
+! Test whether two int vectors are equal. If so return 1, else 0 */
+ logical function int_vec_eq(v1, v2, n)
+ use pnetcdf
+ implicit none
+ integer n
+ integer v1(n)
+ integer v2(n)
+#include "tests.inc"
+
+ integer i
+
+ int_vec_eq = .true.
+
+ if (n .le. 0) &
+ return
+
+ do 1, i=1, n
+ if (v1(i) .ne. v2(i)) then
+ int_vec_eq = .false.
+ return
+ end if
+1 continue
+ end
+
+
+!
+! Generate random integer from 0 through n-1
+! Like throwing an n-sided dice marked 0, 1, 2, ..., n-1
+!
+ integer function roll(n)
+ use pnetcdf
+ implicit none
+#include "tests.inc"
+ integer(kind=MPI_OFFSET_KIND) n
+
+ doubleprecision ud_rand
+ external ud_rand
+
+1 roll = INT((ud_rand(0) * (n-1)) + 0.5)
+ if (roll .ge. n) goto 1
+ end
+
+
+!
+! Convert an origin-1 cumulative index to a netCDF index vector.
+! Grosset dimension first; finest dimension last.
+!
+! Authors: Harvey Davies, Unidata/UCAR, Boulder, Colorado
+! Steve Emmerson, (same place)
+!
+ integer function index2ncindexes(index, rank, base, indexes)
+ use pnetcdf
+ implicit none
+ integer index !!/* index to be converted */
+ integer rank !/* number of dimensions */
+#include "tests.inc"
+ integer(kind=MPI_OFFSET_KIND) base(rank) !/* base(rank) ignored */
+ integer(kind=MPI_OFFSET_KIND) indexes(rank) !/* returned FORTRAN indexes */
+
+ integer i
+ integer offset
+ integer intbase
+
+ if (rank .gt. 0) then
+ offset = index - 1
+ do 1, i = rank, 1, -1
+ if (base(i) .eq. 0) then
+ index2ncindexes = 1
+ return
+ end if
+ intbase = INT(base(i))
+ indexes(i) = 1 + mod(offset, intbase)
+ offset = offset / INT(base(i))
+1 continue
+ end if
+ index2ncindexes = 0
+ end
+
+
+!
+! Convert an origin-1 cumulative index to a FORTRAN index vector.
+! Finest dimension first; grossest dimension last.
+!
+! Authors: Harvey Davies, Unidata/UCAR, Boulder, Colorado
+! Steve Emmerson, (same place)
+!
+ integer function index2indexes(index, rank, base, indexes)
+ use pnetcdf
+ implicit none
+ integer index !/* index to be converted */
+ integer rank !/* number of dimensions */
+#include "tests.inc"
+ integer(kind=MPI_OFFSET_KIND) base(rank) !/* base(rank) ignored */
+ integer(kind=MPI_OFFSET_KIND) indexes(rank) !/* returned FORTRAN indexes */
+
+ integer i
+ integer offset
+ integer intbase
+
+ if (rank .gt. 0) then
+ offset = index - 1
+ do 1, i = 1, rank
+ if (base(i) .eq. 0) then
+ index2indexes = 1
+ return
+ end if
+ intbase = INT(base(i))
+ indexes(i) = 1 + mod(offset, intbase)
+ offset = offset / INT(base(i))
+1 continue
+ end if
+ index2indexes = 0
+ end
+
+
+!
+! Convert a FORTRAN index vector to an origin-1 cumulative index.
+! Finest dimension first; grossest dimension last.
+!
+! Authors: Harvey Davies, Unidata/UCAR, Boulder, Colorado
+! Steve Emmerson, (same place)
+!
+ integer function indexes2index(rank, indexes, base)
+ use pnetcdf
+ implicit none
+ integer rank !/* number of dimensions */
+ integer indexes(rank) !/* FORTRAN indexes */
+ integer base(rank) !/* base(rank) ignored */
+#include "tests.inc"
+
+ integer i
+
+ indexes2index = 0
+ if (rank .gt. 0) then
+ do 1, i = rank, 1, -1
+ indexes2index = (indexes2index-1) * base(i) + indexes(i)
+1 continue
+ end if
+ end
+
+
+! Generate data values as function of type, rank (-1 for attribute), index */
+ double precision function hash(type, rank, index)
+ use pnetcdf
+ implicit none
+ integer type
+ integer rank
+#include "tests.inc"
+ integer(kind=MPI_OFFSET_KIND) index(*)
+
+ doubleprecision base
+ doubleprecision result
+ integer d !/* index of dimension */
+
+ !/* If vector then elements 1 & 2 are min & max. Elements 3 & 4 are */
+ !/* just < min & > max (except for NF90_CHAR & NF90_DOUBLE) */
+ hash = 0
+ if (abs(rank) .eq. 1 .and. index(1) .le. 4) then
+ if (index(1) .eq. 1) then
+ if (type .eq. NF90_CHAR) then
+ hash = X_CHAR_MIN
+ else if (type .eq. NF90_BYTE) then
+ hash = X_BYTE_MIN
+ else if (type .eq. NF90_SHORT) then
+ hash = X_SHORT_MIN
+ else if (type .eq. NF90_INT) then
+ hash = X_INT_MIN
+ else if (type .eq. NF90_FLOAT) then
+ hash = X_FLOAT_MIN
+ else if (type .eq. NF90_DOUBLE) then
+ hash = X_DOUBLE_MIN
+ else if (type .eq. NF90_UBYTE) then
+ hash = 0
+ else if (type .eq. NF90_USHORT) then
+ hash = 0
+ else if (type .eq. NF90_UINT) then
+ hash = 0
+ else if (type .eq. NF90_INT64) then
+ hash = X_INT_MIN - 128.0
+ else if (type .eq. NF90_UINT64) then
+ hash = 0
+ else
+ call ud_abort
+ end if
+ else if (index(1) .eq. 2) then
+ if (type .eq. NF90_CHAR) then
+ hash = X_CHAR_MAX
+ else if (type .eq. NF90_BYTE) then
+ hash = X_BYTE_MAX
+ else if (type .eq. NF90_SHORT) then
+ hash = X_SHORT_MAX
+ else if (type .eq. NF90_INT) then
+ hash = X_INT_MAX
+ else if (type .eq. NF90_FLOAT) then
+ hash = X_FLOAT_MAX
+ else if (type .eq. NF90_DOUBLE) then
+ hash = X_DOUBLE_MAX
+ else if (type .eq. NF90_UBYTE) then
+ hash = X_UCHAR_MAX
+ else if (type .eq. NF90_USHORT) then
+ hash = X_USHORT_MAX
+ else if (type .eq. NF90_UINT) then
+ hash = X_UINT_MAX
+ else if (type .eq. NF90_INT64) then
+ hash = X_INT_MAX + 128.0
+ else if (type .eq. NF90_UINT64) then
+ hash = X_UINT_MAX + 128.0
+ else
+ call ud_abort
+ end if
+ else if (index(1) .eq. 3) then
+ if (type .eq. NF90_CHAR) then
+ hash = ichar('A')
+ else if (type .eq. NF90_BYTE) then
+ hash = X_BYTE_MIN-1.0
+ else if (type .eq. NF90_SHORT) then
+ hash = X_SHORT_MIN-1.0
+ else if (type .eq. NF90_INT) then
+ hash = X_INT_MIN
+ else if (type .eq. NF90_FLOAT) then
+ hash = X_FLOAT_MIN
+ else if (type .eq. NF90_DOUBLE) then
+ hash = -1.0
+ else if (type .eq. NF90_UBYTE) then
+ hash = -1.0
+ else if (type .eq. NF90_USHORT) then
+ hash = -1.0
+ else if (type .eq. NF90_UINT) then
+ hash = -1.0
+ else if (type .eq. NF90_INT64) then
+ hash = -1.0
+ else if (type .eq. NF90_UINT64) then
+ hash = -1.0
+ else
+ call ud_abort
+ end if
+ else if (index(1) .eq. 4) then
+ if (type .eq. NF90_CHAR) then
+ hash = ichar('Z')
+ else if (type .eq. NF90_BYTE) then
+ hash = X_BYTE_MAX+1.0
+ else if (type .eq. NF90_SHORT) then
+ hash = X_SHORT_MAX+1.0
+ else if (type .eq. NF90_INT) then
+ hash = X_INT_MAX+1.0
+ else if (type .eq. NF90_FLOAT) then
+ hash = X_FLOAT_MAX
+ else if (type .eq. NF90_DOUBLE) then
+ hash = 1.0
+ else if (type .eq. NF90_UBYTE) then
+ hash = X_UCHAR_MAX + 1.0
+ else if (type .eq. NF90_USHORT) then
+ hash = X_USHORT_MAX + 1.0
+ else if (type .eq. NF90_UINT) then
+ hash = X_UINT_MAX + 1.0
+ else if (type .eq. NF90_INT64) then
+ hash = 1.0
+ else if (type .eq. NF90_UINT64) then
+ hash = 1.0
+ else
+ call ud_abort
+ end if
+ end if
+ else
+ if (type .eq. NF90_CHAR) then
+ base = 2
+ else if (type .eq. NF90_BYTE) then
+ base = -2
+ else if (type .eq. NF90_SHORT) then
+ base = -5
+ else if (type .eq. NF90_INT) then
+ base = -20
+ else if (type .eq. NF90_FLOAT) then
+ base = -9
+ else if (type .eq. NF90_DOUBLE) then
+ base = -10
+ else if (type .eq. NF90_UBYTE) then
+ base = 2
+ else if (type .eq. NF90_USHORT) then
+ base = 5
+ else if (type .eq. NF90_UINT) then
+ base = 20
+ else if (type .eq. NF90_INT64) then
+ base = -20
+ else if (type .eq. NF90_UINT64) then
+ base = 20
+ else
+ print*, 'Error: no such nc_type ',type
+ stop 'in hash()'
+ end if
+
+ if (rank .lt. 0) then
+ result = base * 7
+ else
+ result = base * (rank + 1)
+ end if
+
+! /*
+! * NB: Finest netCDF dimension assumed first.
+! */
+ do 1, d = abs(rank), 1, -1
+ result = base * (result + index(d) - 1)
+1 continue
+ hash = result
+ end if
+ end
+
+
+! wrapper for hash to handle special NC_BYTE/uchar adjustment */
+ double precision function hash4(type, rank, index, itype)
+ use pnetcdf
+ implicit none
+ integer type
+ integer rank
+#include "tests.inc"
+ double precision hash
+
+ integer(kind=MPI_OFFSET_KIND) index(*)
+ integer itype
+
+ hash4 = hash( type, rank, index )
+ if ((itype .eq. NFT_CHAR) .and. (type .eq. NF90_BYTE) .and. &
+ (hash4 .ge. -128) .and. (hash4 .lt. 0)) hash4 = hash4 + 256
+ end
+
+
+ integer function char2type(letter)
+ use pnetcdf
+ implicit none
+ character*1 letter
+#include "tests.inc"
+
+ if (letter .eq. 'c') then
+ char2type = NF90_CHAR
+ else if (letter .eq. 'b') then
+ char2type = NF90_BYTE
+ else if (letter .eq. 's') then
+ char2type = NF90_SHORT
+ else if (letter .eq. 'i') then
+ char2type = NF90_INT
+ else if (letter .eq. 'f') then
+ char2type = NF90_FLOAT
+ else if (letter .eq. 'd') then
+ char2type = NF90_DOUBLE
+ else if (letter .eq. 'y') then
+ char2type = NF90_UBYTE
+ else if (letter .eq. 't') then
+ char2type = NF90_USHORT
+ else if (letter .eq. 'u') then
+ char2type = NF90_UINT
+ else if (letter .eq. 'x') then
+ char2type = NF90_INT64
+ else if (letter .eq. 'z') then
+ char2type = NF90_UINT64
+ else
+ stop 'char2type(): invalid type-letter'
+ end if
+ end
+
+
+ subroutine init_dims(digit)
+ use pnetcdf
+ implicit none
+ character*1 digit(NDIMS)
+#include "tests.inc"
+
+ integer dimid !/* index of dimension */
+ do 1, dimid = 1, NDIMS
+ if (dimid .eq. RECDIM) then
+ dim_len(dimid) = NRECS
+ else
+ dim_len(dimid) = dimid - 1
+ endif
+ dim_name(dimid) = 'D' // digit(dimid)
+1 continue
+ end
+
+
+ subroutine init_gatts(type_letter)
+ use pnetcdf
+ implicit none
+ character*1 type_letter(NTYPES)
+#include "tests.inc"
+
+ integer attid
+ integer char2type
+
+ do 1, attid = 1, numTypes
+ gatt_name(attid) = 'G' // type_letter(attid)
+ gatt_len(attid) = attid
+ gatt_type(attid) = char2type(type_letter(attid))
+1 continue
+ end
+
+
+ integer function prod(nn, sp)
+ use pnetcdf
+ implicit none
+ integer nn
+#include "tests.inc"
+ integer(kind=MPI_OFFSET_KIND) sp(MAX_RANK)
+
+ integer i
+
+ prod = 1
+ do 1, i = 1, nn
+ prod = prod * INT(sp(i))
+1 continue
+ end
+
+
+!
+! define global variables:
+! dim_name, dim_len,
+! var_name, var_type, var_rank, var_shape, var_natts, var_dimid, var_nels
+! att_name, gatt_name, att_type, gatt_type, att_len, gatt_len
+!
+
+ subroutine init_gvars
+ use pnetcdf
+ implicit none
+#include "tests.inc"
+ integer index2ncindexes
+
+ integer(kind=MPI_OFFSET_KIND) max_dim_len(MAX_RANK)
+ character*1 type_letter(NTYPES)
+ character*1 digit(10)
+
+ integer rank
+ integer vn !/* var number */
+ integer xtype !/* index of type */
+ integer an !/* origin-0 cumulative attribute index */
+ integer nvars
+ integer jj
+ integer n_types
+ integer tc
+ integer(kind=MPI_OFFSET_KIND) tmp(MAX_RANK)
+ integer ac !/* attribute index */
+ integer dn !/* dimension number */
+ integer prod !/* function */
+ integer char2type !/* function */
+ integer err
+
+ data max_dim_len /0, MAX_DIM_LEN, MAX_DIM_LEN/
+ data type_letter /'c', 'b', 's', 'i', 'f', 'd', 'y', &
+ 't', 'u', 'x', 'z'/
+ data digit /'r', '1', '2', '3', '4', '5', &
+ '6', '7', '8', '9'/
+
+ max_dim_len(1) = MAX_DIM_LEN + 1
+
+ call init_dims(digit)
+
+ vn = 1
+ xtype = 1
+ an = 0
+
+! /* Loop over variable ranks */
+ do 1, rank = 0, MAX_RANK
+ nvars = prod(rank, max_dim_len)
+
+ !/* Loop over variable shape vectors */
+ do 2, jj = 1, nvars !/* 1, 5, 20, 80 */
+ !/* number types of this shape */
+ if (rank .lt. 2) then
+ n_types = numTypes !/* 6 */
+ else
+ n_types = 1
+ end if
+
+ !/* Loop over external data types */
+ do 3, tc = 1, n_types !/* 6, 1 */
+ var_name(vn) = type_letter(xtype)
+ var_type(vn) = char2type(type_letter(xtype))
+ var_rank(vn) = rank
+ if (rank .eq. 0) then
+ var_natts(vn) = mod(vn - 1, MAX_NATTS + 1)
+ else
+ var_natts(vn) = 0
+ end if
+
+ do 4, ac = 1, var_natts(vn)
+ attname(ac,vn) = &
+ type_letter(1+mod(an, numTypes))
+ attlen(ac,vn) = an
+ atttype(ac,vn) = &
+ char2type(type_letter(1+mod(an, numTypes)))
+ an = an + 1
+4 continue
+
+ !/* Construct initial shape vector */
+ err = index2ncindexes(jj, rank, max_dim_len, tmp)
+ do 5, dn = 1, rank
+ var_dimid(dn,vn) = INT(tmp(1+rank-dn))
+5 continue
+
+ var_nels(vn) = 1
+ do 6, dn = 1, rank
+ if (dn .lt. rank) then
+ var_dimid(dn,vn) = var_dimid(dn,vn) + 1
+ end if
+ if (var_dimid(dn,vn) .gt. 9) then
+ stop 'Invalid var_dimid vector'
+ end if
+ var_name(vn)(rank+2-dn:rank+2-dn) = &
+ digit(var_dimid(dn,vn))
+ if (var_dimid(dn,vn) .ne. RECDIM) then
+ var_shape(dn,vn) = var_dimid(dn,vn) - 1
+ else
+ var_shape(dn,vn) = NRECS
+ end if
+ var_nels(vn) = var_nels(vn) * INT(var_shape(dn,vn))
+6 continue
+
+ vn = vn + 1
+ xtype = 1 + mod(xtype, numTypes)
+3 continue
+2 continue
+1 continue
+
+ call init_gatts(type_letter)
+ end
+
+
+! define dims defined by global variables */
+ subroutine def_dims(ncid)
+ use pnetcdf
+ implicit none
+ integer ncid
+#include "tests.inc"
+
+ integer err !/* status */
+ integer i
+ integer dimid !/* dimension id */
+
+ do 1, i = 1, NDIMS
+ if (i .eq. RECDIM) then
+ err = nf90mpi_def_dim(ncid, dim_name(i), &
+ NF90MPI_UNLIMITED, dimid)
+ else
+ err = nf90mpi_def_dim(ncid, dim_name(i), dim_len(i), &
+ dimid)
+ end if
+ if (err .ne. NF90_NOERR) then
+ call errore('nf90mpi_def_dim: ', err)
+ end if
+1 continue
+ end
+
+
+! define vars defined by global variables */
+ subroutine def_vars(ncid)
+ use pnetcdf
+ implicit none
+ integer ncid
+#include "tests.inc"
+
+ integer err !/* status */
+ integer i
+ integer var_id
+
+ do 1, i = 1, numVars
+ err = nf90mpi_def_var(ncid, var_name(i), var_type(i), &
+ var_dimid(1:var_rank(i),i), var_id)
+ if (err .ne. NF90_NOERR) then
+ call errore('nf90mpi_def_var: ', err)
+ end if
+1 continue
+ end
+
+
+! put attributes defined by global variables */
+ subroutine put_atts(ncid)
+ use pnetcdf
+ implicit none
+ integer ncid
+#include "tests.inc"
+ integer(kind=MPI_OFFSET_KIND) ATT_LEN_LL
+ integer VARID, NATTS, ATT_TYPE, ATT_LEN
+ CHARACTER*2 ATT_NAME
+ double precision hash
+ logical inrange
+
+ integer err !/* netCDF status */
+ integer i !/* variable index (0 => global
+ ! * attribute */
+ integer k !/* attribute index */
+ integer j !/* index of attribute */
+ integer(kind=MPI_OFFSET_KIND) ndx(1)
+ logical allInRange
+ double precision att(MAX_NELS)
+ character*(MAX_NELS+2) catt
+
+ do 1, i = 0, numVars !/* var 0 => NF90_GLOBAL attributes */
+ do 2, j = 1, NATTS(i)
+ if (NF90_CHAR .eq. ATT_TYPE(j,i)) then
+ catt = ' '
+ do 3, k = 1, ATT_LEN(j,i)
+ ndx(1) = k
+ catt(k:k) = char(int(hash(ATT_TYPE(j,i), -1, &
+ ndx)))
+3 continue
+! /*
+! * The following ensures that the text buffer doesn't
+! * start with 4 zeros (which is a CFORTRAN NULL pointer
+! * indicator) yet contains a zero (which causes the
+! * CFORTRAN interface to pass the address of the
+! * actual text buffer).
+! */
+ catt(ATT_LEN(j,i)+1:ATT_LEN(j,i)+1) = char(1)
+ catt(ATT_LEN(j,i)+2:ATT_LEN(j,i)+2) = char(0)
+
+ err = nf90mpi_put_att(ncid, varid(i), ATT_NAME(j,i), &
+ catt(1:ATT_LEN(j,i)))
+ if (err .ne. NF90_NOERR) then
+ call errore('nf90mpi_put_att: ', err)
+ end if
+ else
+ allInRange = .true.
+ do 4, k = 1, ATT_LEN(j,i)
+ ndx(1) = k
+ att(k) = hash(ATT_TYPE(j,i), -1, ndx)
+ allInRange = allInRange .and. &
+ inRange(att(k), ATT_TYPE(j,i))
+4 continue
+ ! cannot use nf90mpi_put_att, as it checks data types
+ ATT_LEN_LL = ATT_LEN(j,i)
+ err = nfmpi_put_att_double(ncid, varid(i), ATT_NAME(j,i), &
+ ATT_TYPE(j,i), ATT_LEN_LL, att)
+ if (allInRange) then
+ if (err .ne. NF90_NOERR) then
+ call errore('nf90mpi_put_att: ', err)
+ end if
+ ! F90 skips this error check
+ ! else
+ ! if (err .ne. NF90_ERANGE) then
+ ! call errore( &
+ ! 'type-conversion range error: status = ', &
+ ! err)
+ ! end if
+ end if
+ end if
+2 continue
+1 continue
+ end
+
+
+! put variables defined by global variables */
+ subroutine put_vars(ncid)
+ use pnetcdf
+ implicit none
+ integer ncid
+#include "tests.inc"
+ integer index2indexes
+ double precision hash
+ logical inrange
+
+ integer(kind=MPI_OFFSET_KIND) start(MAX_RANK)
+ integer(kind=MPI_OFFSET_KIND) index(MAX_RANK)
+ integer err !/* netCDF status */
+ integer i
+ integer j
+ doubleprecision value(MAX_NELS)
+ character*(MAX_NELS+2) text
+ logical allInRange
+
+ do 1, j = 1, MAX_RANK
+ start(j) = 1
+1 continue
+
+ err = nf90mpi_begin_indep_data(ncid)
+ do 2, i = 1, numVars
+ allInRange = .true.
+ do 3, j = 1, var_nels(i)
+ err = index2indexes(j, var_rank(i), var_shape(1,i), &
+ index)
+ if (err .ne. NF90_NOERR) then
+ call errori( &
+ 'Error calling index2indexes() for var ', j)
+ end if
+ if (var_name(i)(1:1) .eq. 'c') then
+ text(j:j) = &
+ char(int(hash(var_type(i), var_rank(i), index)))
+ else
+ value(j) = hash(var_type(i), var_rank(i), index)
+ allInRange = allInRange .and. &
+ inRange(value(j), var_type(i))
+ end if
+3 continue
+ if (var_name(i)(1:1) .eq. 'c') then
+! /*
+! * The following statement ensures that the first 4
+! * characters in 'text' are not all zeros (which is
+! * a cfortran.h NULL indicator) and that the string
+! * contains a zero (which will cause the address of the
+! * actual string buffer to be passed).
+! */
+ text(var_nels(i)+1:var_nels(i)+1) = char(1)
+ text(var_nels(i)+2:var_nels(i)+2) = char(0)
+ err = nf90mpi_put_var(ncid, i, text, start, &
+ var_shape(:,i))
+ if (err .ne. NF90_NOERR) then
+ call errore('nf90mpi_put_var: ', err)
+ end if
+ else
+ err = nf90mpi_put_var(ncid, i, value, start, &
+ var_shape(:,i))
+ if (allInRange) then
+ if (err .ne. NF90_NOERR) then
+ call errore('nf90mpi_put_var: ', err)
+ end if
+ else
+ if (err .ne. NF90_ERANGE) then
+ call errore( &
+ 'type-conversion range error: status = ', &
+ err)
+ end if
+ end if
+ end if
+2 continue
+ err = nf90mpi_end_indep_data(ncid)
+ end
+
+
+! Create & write all of specified file using global variables */
+ subroutine write_file(filename)
+ use pnetcdf
+ implicit none
+ character*(*) filename
+#include "tests.inc"
+
+ integer ncid !/* netCDF id */
+ integer err !/* netCDF status */
+ integer flags
+
+ flags = IOR(NF90_CLOBBER, extra_flags)
+ err = nf90mpi_create(comm, filename, flags, info, &
+ ncid)
+ if (err .ne. NF90_NOERR) then
+ call errore('nf90mpi_create: ', err)
+ end if
+
+ call def_dims(ncid)
+ call def_vars(ncid)
+ call put_atts(ncid)
+ err = nf90mpi_enddef(ncid)
+ if (err .ne. NF90_NOERR) then
+ call errore('nf90mpi_enddef: ', err)
+ end if
+ call put_vars(ncid)
+
+ err = nf90mpi_close(ncid)
+ if (err .ne. NF90_NOERR) then
+ call errore('nf90mpi_close: ', err)
+ end if
+ end
+
+
+!
+! check dimensions of specified file have expected name & length
+!
+ subroutine check_dims(ncid)
+ use pnetcdf
+ implicit none
+ integer ncid
+#include "tests.inc"
+
+ character*(NF90_MAX_NAME) name
+ integer(kind=MPI_OFFSET_KIND) length
+ integer i
+ integer err !/* netCDF status */
+
+ do 1, i = 1, NDIMS
+ err = nf90mpi_inquire_dimension(ncid, i, name, length)
+ if (err .ne. NF90_NOERR) then
+ call errore('nf90mpi_inquire_dimension: ', err)
+ end if
+ if (name .ne. dim_name(i)) then
+ call errori('Unexpected name of dimension ', i)
+ end if
+ if (length .ne. dim_len(i)) then
+ call errori('Unexpected length of dimension ', i)
+ end if
+1 continue
+ end
+
+
+!
+! check variables of specified file have expected name, type, shape & values
+!
+ subroutine check_vars(ncid)
+ use pnetcdf
+ implicit none
+ integer ncid
+#include "tests.inc"
+ integer index2indexes
+ double precision hash
+ logical inrange, equal
+
+ integer(kind=MPI_OFFSET_KIND) index(MAX_RANK)
+ integer err !/* netCDF status */
+ integer i
+ integer j
+ character*1 text
+ doubleprecision value
+ integer datatype
+ integer ndims
+ integer natt
+ integer dimids(MAX_RANK)
+ logical isChar
+ doubleprecision expect
+ character*(NF90_MAX_NAME) name
+ integer(kind=MPI_OFFSET_KIND) length
+ integer nok !/* count of valid comparisons */
+
+ nok = 0
+ err = nf90mpi_begin_indep_data(ncid)
+
+ do 1, i = 1, numVars
+ isChar = var_type(i) .eq. NF90_CHAR
+ err = nf90mpi_inquire_variable(ncid, i, name, datatype, ndims, dimids, &
+ natt)
+ if (err .ne. NF90_NOERR) then
+ call errore('nf90mpi_inquire_variable: ', err)
+ end if
+ if (name .ne. var_name(i)) then
+ call errori('Unexpected var_name for variable ', i)
+ end if
+ if (datatype .ne. var_type(i)) then
+ call errori('Unexpected type for variable ', i)
+ end if
+ if (ndims .ne. var_rank(i)) then
+ call errori('Unexpected rank for variable ', i)
+ end if
+ do 2, j = 1, ndims
+ err = nf90mpi_inquire_dimension(ncid, dimids(j), name, length)
+ if (err .ne. NF90_NOERR) then
+ call errore('nf90mpi_inquire_dimension: ', err)
+ end if
+ if (length .ne. var_shape(j,i)) then
+ call errori('Unexpected shape for variable ', i)
+ end if
+2 continue
+ do 3, j = 1, var_nels(i)
+ err = index2indexes(j, var_rank(i), var_shape(1,i), &
+ index)
+ if (err .ne. NF90_NOERR) then
+ call errori('error in index2indexes() 2, variable ', &
+ i)
+ end if
+ expect = hash(var_type(i), var_rank(i), index )
+ if (isChar) then
+ err = nf90mpi_get_var(ncid, i, text, index)
+ if (err .ne. NF90_NOERR) then
+ call errore('nf90mpi_get_var: ', err)
+ end if
+ if (ichar(text) .ne. expect) then
+ call errori( &
+ 'Var value read not that expected for variable ', i)
+ else
+ nok = nok + 1
+ end if
+ else
+ err = nf90mpi_get_var(ncid, i, value, index)
+ if (inRange(expect,var_type(i))) then
+ if (err .ne. NF90_NOERR) then
+ call errore('nf90mpi_get_var: ', err)
+ else
+ if (.not. equal(value,expect,var_type(i), &
+ NFT_DOUBLE)) then
+ call errori( &
+ 'Var value read not that expected for variable ', i)
+ else
+ nok = nok + 1
+ end if
+ end if
+ end if
+ end if
+3 continue
+1 continue
+ err = nf90mpi_end_indep_data(ncid)
+ ! call print_nok(nok)
+ end
+
+
+!
+! check attributes of specified file have expected name, type, length & values
+!
+ subroutine check_atts(ncid)
+ use pnetcdf
+ implicit none
+ integer ncid
+#include "tests.inc"
+ integer VARID, NATTS, ATT_TYPE, ATT_LEN
+ CHARACTER*2 ATT_NAME
+ double precision hash
+ logical inrange, equal
+
+ integer err !/* netCDF status */
+ integer i
+ integer j
+ integer k
+ integer vid !/* "variable" ID */
+ integer datatype
+ integer(kind=MPI_OFFSET_KIND) ndx(1)
+ character*(NF90_MAX_NAME) name
+ integer(kind=MPI_OFFSET_KIND) length
+ character*(MAX_NELS) text
+ doubleprecision value(MAX_NELS)
+ doubleprecision expect
+ integer nok !/* count of valid comparisons */
+
+ nok = 0
+
+ do 1, vid = 0, numVars
+ i = varid(vid)
+
+ do 2, j = 1, NATTS(i)
+ err = nf90mpi_inq_attname(ncid, i, j, name)
+ if (err .ne. NF90_NOERR) then
+ call errore('nf90mpi_inq_attname: ', err)
+ end if
+ if (name .ne. ATT_NAME(j,i)) then
+ call errori( &
+ 'nf90mpi_inq_attname: unexpected name for var ', i)
+ end if
+ err = nf90mpi_inquire_attribute(ncid, i, name, datatype, length)
+ if (err .ne. NF90_NOERR) then
+ call errore('nf90mpi_inquire_attribute: ', err)
+ end if
+ if (datatype .ne. ATT_TYPE(j,i)) then
+ call errori( &
+ 'nf90mpi_inquire_attribute: unexpected type for var ', i)
+ end if
+ if (length .ne. ATT_LEN(j,i)) then
+ call errori( &
+ 'nf90mpi_inquire_attribute: unexpected length for var ', i)
+ end if
+ if (datatype .eq. NF90_CHAR) then
+ err = nf90mpi_get_att(ncid, i, name, text)
+ if (err .ne. NF90_NOERR) then
+ call errore('nf90mpi_get_att: ', err)
+ end if
+ do 3, k = 1, ATT_LEN(j,i)
+ ndx(1) = k
+ if (ichar(text(k:k)) .ne. hash(datatype, -1, &
+ ndx)) &
+ then
+ call errori( &
+ 'nf90mpi_get_att: unexpected value for var ', i)
+ else
+ nok = nok + 1
+ end if
+3 continue
+ else
+ err = nf90mpi_get_att(ncid, i, name, value)
+ do 4, k = 1, ATT_LEN(j,i)
+ ndx(1) = k
+ expect = hash(datatype, -1, ndx)
+ if (inRange(expect,ATT_TYPE(j,i))) then
+ if (err .ne. NF90_NOERR) then
+ call errore( &
+ 'nf90mpi_get_att: ', err)
+ end if
+ if (.not. equal(value(k), expect, &
+ ATT_TYPE(j,i), NFT_DOUBLE)) then
+ call errori( &
+ 'Att value read not that expected for var ', i)
+ else
+ nok = nok + 1
+ end if
+ end if
+4 continue
+ end if
+2 continue
+1 continue
+ ! call print_nok(nok)
+ end
+
+
+! Check file (dims, vars, atts) corresponds to global variables */
+ subroutine check_file(filename)
+ use pnetcdf
+ implicit none
+ character*(*) filename
+#include "tests.inc"
+
+ integer ncid !/* netCDF id */
+ integer err !/* netCDF status */
+
+ err = nf90mpi_open(comm, filename, NF90_NOWRITE, info, &
+ ncid)
+ if (err .ne. NF90_NOERR) then
+ call errore('nf90mpi_open: ', err)
+ else
+ call check_dims(ncid)
+ call check_vars(ncid)
+ call check_atts(ncid)
+ err = nf90mpi_close (ncid)
+ if (err .ne. NF90_NOERR) then
+ call errore('nf90mpi_close: ', err)
+ end if
+ end if
+ end
+
+
+!
+! Functions for accessing attribute test data.
+!
+! NB: 'varid' is 0 for global attributes; thus, global attributes can
+! be handled in the same loop as variable attributes.
+!
+
+ integer FUNCTION VARID(VID)
+ USE PNETCDF
+ IMPLICIT NONE
+ INTEGER VID
+#include "tests.inc"
+ IF (VID .LT. 1) THEN
+ VARID = NF90_GLOBAL
+ ELSE
+ VARID = VID
+ ENDIF
+ end
+
+
+ integer FUNCTION NATTS(VID)
+ USE PNETCDF
+ IMPLICIT NONE
+ INTEGER VID
+#include "tests.inc"
+ IF (VID .LT. 1) THEN
+ NATTS = numGatts
+ ELSE
+ NATTS = VAR_NATTS(VID)
+ ENDIF
+ END
+
+
+ character*2 FUNCTION ATT_NAME(J,VID)
+ USE PNETCDF
+ IMPLICIT NONE
+ INTEGER J
+ INTEGER VID
+#include "tests.inc"
+ IF (VID .LT. 1) THEN
+ ATT_NAME = GATT_NAME(J)
+ ELSE
+ ATT_NAME = ATTNAME(J,VID)
+ ENDIF
+ END
+
+
+ integer FUNCTION ATT_TYPE(J,VID)
+ USE PNETCDF
+ IMPLICIT NONE
+ INTEGER J
+ INTEGER VID
+#include "tests.inc"
+ IF (VID .LT. 1) THEN
+ ATT_TYPE = GATT_TYPE(J)
+ ELSE
+ ATT_TYPE = ATTTYPE(J,VID)
+ ENDIF
+ END
+
+
+ integer FUNCTION ATT_LEN(J,VID)
+ USE PNETCDF
+ IMPLICIT NONE
+ INTEGER J
+ INTEGER VID
+#include "tests.inc"
+ IF (VID .LT. 1) THEN
+ ATT_LEN = INT(GATT_LEN(J))
+ ELSE
+ ATT_LEN = ATTLEN(J,VID)
+ ENDIF
+ END
+
+
+!
+! Return the minimum value of an internal type.
+!
+ DOUBLE PRECISION function internal_min(type)
+ use pnetcdf
+ implicit none
+ integer type
+ doubleprecision min_schar
+ doubleprecision min_short
+ doubleprecision min_int
+ ! doubleprecision min_long
+ doubleprecision max_float
+ doubleprecision max_double
+ doubleprecision min_int64
+#include "tests.inc"
+
+ if (type .eq. NFT_CHAR) then
+ internal_min = 0
+ else if (type .eq. NFT_INT1) then
+#if defined NF90_INT1_IS_C_SIGNED_CHAR
+ internal_min = min_schar()
+#elif defined NF90_INT1_IS_C_SHORT
+ internal_min = min_short()
+#elif defined NF90_INT1_IS_C_INT
+ internal_min = min_int()
+#elif defined NF90_INT1_IS_C_LONG
+ internal_min = min_long()
+#else
+ internal_min = min_schar()
+! #include "No C equivalent to Fortran INTEGER*1"
+#endif
+ else if (type .eq. NFT_INT2) then
+#if defined NF90_INT2_IS_C_SHORT
+ internal_min = min_short()
+#elif defined NF90_INT2_IS_C_INT
+ internal_min = min_int()
+#elif defined NF90_INT2_IS_C_LONG
+ internal_min = min_long()
+#else
+ internal_min = min_short()
+! #include "No C equivalent to Fortran INTEGER*2"
+#endif
+ else if (type .eq. NFT_INT) then
+#if defined NF90_INT_IS_C_INT
+ internal_min = min_int()
+#elif defined NF90_INT_IS_C_LONG
+ internal_min = min_long()
+#else
+ internal_min = min_int()
+! #include "No C equivalent to Fortran INTEGER"
+#endif
+ else if (type .eq. NFT_REAL) then
+#if defined NF90_REAL_IS_C_FLOAT
+ internal_min = -max_float()
+#elif defined NF90_REAL_IS_C_DOUBLE
+ internal_min = -max_double()
+#else
+ internal_min = -max_float()
+! #include "No C equivalent to Fortran REAL"
+#endif
+ else if (type .eq. NFT_DOUBLE) then
+#if defined NF90_DOUBLEPRECISION_IS_C_DOUBLE
+ internal_min = -max_double()
+#elif defined NF90_DOUBLEPRECISION_IS_C_FLOAT
+ internal_min = -max_float()
+#else
+ internal_min = -max_double()
+! #include "No C equivalent to Fortran DOUBLE"
+#endif
+ else if (type .eq. NFT_INT8) then
+ internal_min = min_int64()
+ else
+ stop 'internal_min(): invalid type'
+ end if
+ end
+
+
+!
+! Return the maximum value of an internal type.
+!
+ DOUBLE PRECISION function internal_max(type)
+ use pnetcdf
+ implicit none
+ integer type
+ doubleprecision max_schar
+ doubleprecision max_short
+ doubleprecision max_int
+ ! doubleprecision max_long
+ doubleprecision max_float
+ doubleprecision max_double
+ doubleprecision max_int64
+#include "tests.inc"
+
+ if (type .eq. NFT_CHAR) then
+ internal_max = 255
+ else if (type .eq. NFT_INT1) then
+#if defined NF90_INT1_IS_C_SIGNED_CHAR
+ internal_max = max_schar()
+#elif defined NF90_INT1_IS_C_SHORT
+ internal_max = max_short()
+#elif defined NF90_INT1_IS_C_INT
+ internal_max = max_int()
+#elif defined NF90_INT1_IS_C_LONG
+ internal_max = max_long()
+#else
+ internal_max = max_schar()
+! #include "No C equivalent to Fortran INTEGER*1"
+#endif
+ else if (type .eq. NFT_INT2) then
+#if defined NF90_INT2_IS_C_SHORT
+ internal_max = max_short()
+#elif defined NF90_INT2_IS_C_INT
+ internal_max = max_int()
+#elif defined NF90_INT2_IS_C_LONG
+ internal_max = max_long()
+#else
+ internal_max = max_short()
+! #include "No C equivalent to Fortran INTEGER*2"
+#endif
+ else if (type .eq. NFT_INT) then
+#if defined NF90_INT_IS_C_INT
+ internal_max = max_int()
+#elif defined NF90_INT_IS_C_LONG
+ internal_max = max_long()
+#else
+ internal_max = max_int()
+! #include "No C equivalent to Fortran INTEGER"
+#endif
+ else if (type .eq. NFT_REAL) then
+#if defined NF90_REAL_IS_C_FLOAT
+ internal_max = max_float()
+#elif defined NF90_REAL_IS_C_DOUBLE
+ internal_max = max_double()
+#else
+ internal_max = max_float()
+! #include "No C equivalent to Fortran REAL"
+#endif
+ else if (type .eq. NFT_DOUBLE) then
+#if defined NF90_DOUBLEPRECISION_IS_C_DOUBLE
+ internal_max = max_double()
+#elif defined NF90_DOUBLEPRECISION_IS_C_FLOAT
+ internal_max = max_float()
+#else
+ internal_max = max_double()
+! #include "No C equivalent to Fortran DOUBLE"
+#endif
+ else if (type .eq. NFT_INT8) then
+ internal_max = max_int64()
+ else
+ stop 'internal_max(): invalid type'
+ end if
+ end
+
+
+!
+! Return the minimum value of an external type.
+!
+ DOUBLE PRECISION function external_min(type)
+ use pnetcdf
+ implicit none
+ integer type
+#include "tests.inc"
+
+ if (type .eq. NF90_BYTE) then
+ external_min = X_BYTE_MIN
+ else if (type .eq. NF90_CHAR) then
+ external_min = X_CHAR_MIN
+ else if (type .eq. NF90_SHORT) then
+ external_min = X_SHORT_MIN
+ else if (type .eq. NF90_INT) then
+ external_min = X_INT_MIN
+ else if (type .eq. NF90_FLOAT) then
+ external_min = X_FLOAT_MIN
+ else if (type .eq. NF90_DOUBLE) then
+ external_min = X_DOUBLE_MIN
+ else if (type .eq. NF90_INT64) then
+ external_min = X_INT8_MIN
+ else
+ stop 'external_min(): invalid type'
+ end if
+ end
+
+
+!
+! Return the maximum value of an internal type.
+!
+ DOUBLE PRECISION function external_max(type)
+ use pnetcdf
+ implicit none
+ integer type
+#include "tests.inc"
+
+ if (type .eq. NF90_BYTE) then
+ external_max = X_BYTE_MAX
+ else if (type .eq. NF90_CHAR) then
+ external_max = X_CHAR_MAX
+ else if (type .eq. NF90_SHORT) then
+ external_max = X_SHORT_MAX
+ else if (type .eq. NF90_INT) then
+ external_max = X_INT_MAX
+ else if (type .eq. NF90_FLOAT) then
+ external_max = X_FLOAT_MAX
+ else if (type .eq. NF90_DOUBLE) then
+ external_max = X_DOUBLE_MAX
+ else if (type .eq. NF90_INT64) then
+ external_max = X_INT8_MAX
+ else
+ stop 'external_max(): invalid type'
+ end if
+ end
+
+
+!
+! Indicate whether or not a value lies in the range of an internal type.
+!
+ logical function in_internal_range(itype, value)
+ use pnetcdf
+ implicit none
+ integer itype
+ doubleprecision value
+#include "tests.inc"
+ double precision internal_min, internal_max
+
+ in_internal_range = value .ge. internal_min(itype) .and. &
+ value .le. internal_max(itype)
+ end
+
diff --git a/test/nf_test/Makefile.in b/test/nf_test/Makefile.in
new file mode 100644
index 0000000..9b5c35d
--- /dev/null
+++ b/test/nf_test/Makefile.in
@@ -0,0 +1,93 @@
+#
+# Copyright (C) 2003, Northwestern University and Argonne National Laboratory
+# See COPYRIGHT notice in top-level directory.
+#
+# $Id: Makefile.in 2251 2015-12-20 21:13:42Z wkliao $
+#
+# @configure_input@
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+include ../../macros.make
+
+INCLUDES = -I. -I../../src/lib -I../../src/libf
+INCLUDES += -I$(srcdir)/../../src/libf
+LDFLAGS := $(LDFLAGS) -L../common
+LIBS := $(LIBRARY) -ltestutils $(LIBS) @LCOV_LIB@
+
+M4SRCS = test_get.m4 \
+ test_put.m4 \
+ test_iget.m4 \
+ test_iput.m4
+
+M4SRCS_F = $(M4SRCS:.m4=.F)
+
+F_SRCS = nf_error.F \
+ nf_test.F \
+ test_read.F \
+ test_write.F \
+ util.F
+
+C_SRCS = fortlib.c
+
+HEADERS = tests.inc.in
+
+C_OBJS = $(C_SRCS:.c=.o)
+F_OBJS = $(F_SRCS:.F=.o) $(M4SRCS_F:.F=.o)
+OBJS = $(C_OBJS) $(F_OBJS)
+
+PROGS = nf_test
+
+GARBAGE = $(PROGS) $(M4SRCS_F) \
+ scratch.nc test.nc
+
+DIST_GARBAGE = tests.inc
+
+PACKING_LIST = $(C_SRCS) $(F_SRCS) $(M4SRCS) $(HEADERS) depend Makefile.in README
+
+all: $(PROGS)
+
+$(C_OBJS): $(srcdir)/../common/testutils.h
+
+$(PROGS): ../common/libtestutils.a
+
+../common/libtestutils.a:
+ set -e; cd ../common && $(MAKE) $(MFLAGS) all
+
+nf_test: $(OBJS) $(LIBRARY)
+ $(LINK.F90) $(OBJS) $(LDFLAGS) $(LIBS)
+
+tags: $(F_SRCS) $(C_SRCS) FORCE
+ ctags -t $(F_SRCS) $(C_SRCS) ../fortran/*.c ../libsrc/*.c
+
+# This simple testing target ensures that the test files are present
+testing check: all
+ $(RM) -f $(TEST_OUTDIR)/scratch.nc $(TEST_OUTDIR)/test.nc
+ $(TEST_SEQRUN) ./nf_test -c -d $(TEST_OUTDIR)
+ $(TEST_SEQRUN) ./nf_test -d $(TEST_OUTDIR)
+ $(TEST_SEQRUN) ./nf_test -c -2 -d $(TEST_OUTDIR)
+ $(TEST_SEQRUN) ./nf_test -2 -d $(TEST_OUTDIR)
+ $(TEST_SEQRUN) ./nf_test -c -5 -d $(TEST_OUTDIR)
+ $(TEST_SEQRUN) ./nf_test -5 -d $(TEST_OUTDIR)
+
+verbose_testing: all
+ $(RM) -f $(TEST_OUTDIR)/scratch.nc $(TEST_OUTDIR)/test.nc
+ $(TEST_SEQRUN) ./nf_test -v -c -d $(TEST_OUTDIR)
+ $(TEST_SEQRUN) ./nf_test -v -d $(TEST_OUTDIR)
+ $(TEST_SEQRUN) ./nf_test -v -c -2 -d $(TEST_OUTDIR)
+ $(TEST_SEQRUN) ./nf_test -v -2 -d $(TEST_OUTDIR)
+ $(TEST_SEQRUN) ./nf_test -v -c -5 -d $(TEST_OUTDIR)
+ $(TEST_SEQRUN) ./nf_test -v -5 -d $(TEST_OUTDIR)
+
+#test.nc:
+# (cd ../nc_test && $(MAKE) $(MFLAGS) nc_test && ./nc_test -c)
+# cp ../nc_test/test.nc .
+
+ptest ptests ptest2 ptest4 ptest6 ptest8 ptest10:
+
+include $(srcdir)/../../rules.make
+include $(srcdir)/depend
+
+$(LIBRARY): ;
+
diff --git a/test/nf_test/README b/test/nf_test/README
new file mode 100644
index 0000000..c73c720
--- /dev/null
+++ b/test/nf_test/README
@@ -0,0 +1,9 @@
+This test is ported from Unidata netCDF-3.5 to test the functionality
+of the PnetCDF API Fortran interface particularly on a single processor.
+
+The typical way to run the test includes two steps:
+
+ (1) create test.nc by "<mpirun -np 1> ./nf_test -c"
+ (2) run the test by "<mpirun -np 1> ./nf_test -v"
+
+
diff --git a/test/nf_test/depend b/test/nf_test/depend
new file mode 100644
index 0000000..be7d2a9
--- /dev/null
+++ b/test/nf_test/depend
@@ -0,0 +1,31 @@
+fortlib.o: fortlib.c
+lib.o: ../../src/libf/pnetcdf.inc
+lib.o: lib.F
+lib.o: tests.inc
+nf_error.o: ../../src/libf/pnetcdf.inc
+nf_error.o: nf_error.F
+nf_error.o: tests.inc
+nf_test.o: ../../src/libf/pnetcdf.inc
+nf_test.o: nf_test.F
+nf_test.o: tests.inc
+test_get.o: ../../src/libf/pnetcdf.inc
+test_get.o: test_get.F
+test_get.o: tests.inc
+test_put.o: ../../src/libf/pnetcdf.inc
+test_put.o: test_put.F
+test_put.o: tests.inc
+test_iget.o: ../../src/libf/pnetcdf.inc
+test_iget.o: test_iget.F
+test_iget.o: tests.inc
+test_iput.o: ../../src/libf/pnetcdf.inc
+test_iput.o: test_iput.F
+test_iput.o: tests.inc
+test_read.o: ../../src/libf/pnetcdf.inc
+test_read.o: test_read.F
+test_read.o: tests.inc
+test_write.o: ../../src/libf/pnetcdf.inc
+test_write.o: test_write.F
+test_write.o: tests.inc
+util.o: ../../src/libf/pnetcdf.inc
+util.o: tests.inc
+util.o: util.F
diff --git a/test/nf_test/fortlib.c b/test/nf_test/fortlib.c
new file mode 100644
index 0000000..6d2303d
--- /dev/null
+++ b/test/nf_test/fortlib.c
@@ -0,0 +1,289 @@
+/*
+ * $Id: fortlib.c 1468 2013-10-26 16:53:18Z wkliao $
+ *
+ * This file contains support functions for FORTRAN code. For example,
+ * under HP-UX A.09.05, the U77 library doesn't contain the exit()
+ * routine -- so we create one here.
+ *
+ * This file is heavily modified from nf_test/fortlib.c in the serial netcdf
+ * source.
+ */
+
+
+#include <stdlib.h>
+#include <limits.h>
+#include <float.h>
+#include <unistd.h>
+#include <stdint.h>
+#include <mpinetcdf_impl.h>
+#include <mpifnetcdf.h>
+
+extern FORTRAN_API void FORT_CALL ud_exit_(int *v1);
+extern FORTRAN_API void FORT_CALL ud_abort_(int *v1);
+extern FORTRAN_API double FORT_CALL ud_rand_(int *seed);
+extern FORTRAN_API int FORT_CALL ud_shift_(int * value, int *amount);
+extern FORTRAN_API void FORT_CALL nc_ignorefpe_(int *doit);
+extern FORTRAN_API double FORT_CALL min_schar_(void);
+extern FORTRAN_API double FORT_CALL min_short_(void);
+extern FORTRAN_API double FORT_CALL min_int_(void);
+extern FORTRAN_API double FORT_CALL min_int64_(void);
+extern FORTRAN_API double FORT_CALL max_schar_(void);
+extern FORTRAN_API double FORT_CALL max_short_(void);
+extern FORTRAN_API double FORT_CALL max_int_(void);
+extern FORTRAN_API double FORT_CALL max_int64_(void);
+extern FORTRAN_API double FORT_CALL max_float_(void);
+extern FORTRAN_API double FORT_CALL max_double_(void);
+
+
+#ifdef F77_NAME_UPPER
+#define ud_exit_ UD_EXIT
+#elif defined(F77_NAME_LOWER_2USCORE)
+#define ud_exit_ ud_exit__
+#elif !defined(F77_NAME_LOWER_USCORE)
+#define ud_exit_ ud_exit
+/* Else leave name alone */
+#endif
+
+FORTRAN_API void FORT_CALL ud_exit_(int *v1) {
+ if (*v1 == 0) {
+ MPI_Finalize();
+ exit(0);
+ }
+ MPI_Abort(MPI_COMM_WORLD, *v1);
+ return;
+}
+
+#ifdef F77_NAME_UPPER
+#define ud_abort_ UD_ABORT
+#elif defined(F77_NAME_LOWER_2USCORE)
+#define ud_abort_ ud_abort__
+#elif !defined(F77_NAME_LOWER_USCORE)
+#define ud_abort_ ud_abort
+/* Else leave name alone */
+#endif
+
+FORTRAN_API void FORT_CALL ud_abort_(int *v1) {
+ MPI_Abort(MPI_COMM_WORLD, *v1);
+ return;
+}
+
+#ifdef F77_NAME_UPPER
+#define ud_rand_ UD_RAND
+#elif defined(F77_NAME_LOWER_2USCORE)
+#define ud_rand_ ud_rand__
+#elif !defined(F77_NAME_LOWER_USCORE)
+#define ud_rand_ ud_rand
+/* Else leave name alone */
+#endif
+
+/*
+* Return a pseudo-random value between 0.0 and 1.0.
+*
+* We don't use RAND_MAX here because not all compilation
+* environments define it (e.g. gcc(1) under SunOS 4.1.3).
+*/
+FORTRAN_API double FORT_CALL ud_rand_(int *seed) {
+ if (*seed != 0)
+ srand(*seed);
+ return (rand() % 32768 )/ 32767.0;
+}
+
+#ifdef F77_NAME_UPPER
+#define ud_shift_ UD_SHIFT
+#elif defined(F77_NAME_LOWER_2USCORE)
+#define ud_shift_ ud_shift__
+#elif !defined(F77_NAME_LOWER_USCORE)
+#define ud_shift_ ud_shift
+/* Else leave name alone */
+#endif
+
+FORTRAN_API int FORT_CALL ud_shift_(int * value, int *amount) {
+ if(*amount < 0)
+ *value >>= -*amount;
+ else if (*amount > 0)
+ *value <<= *amount;
+ return *value;
+}
+
+#ifdef F77_NAME_UPPER
+#define nc_ignorefpe_ NC_IGNOREFPE
+#elif defined(F77_NAME_LOWER_2USCORE)
+#define nc_ignorefpe_ nc_ignorefpe__
+#elif !defined(F77_NAME_LOWER_USCORE)
+#define nc_ignorefpe_ nc_ignorefpe
+/* Else leave name alone */
+#endif
+#include <signal.h>
+FORTRAN_API void FORT_CALL nc_ignorefpe_(int *doit)
+{
+ if(doit)
+ (void) signal(SIGFPE, SIG_IGN);
+}
+
+#ifdef F77_NAME_UPPER
+#define min_schar_ MIN_SCHAR
+#elif defined(F77_NAME_LOWER_2USCORE)
+#define min_schar_ min_schar__
+#elif !defined(F77_NAME_LOWER_USCORE)
+#define min_schar_ min_schar
+/* Else leave name alone */
+#endif
+FORTRAN_API double FORT_CALL min_schar_(void) {
+ return SCHAR_MIN;
+}
+
+#ifdef F77_NAME_UPPER
+#define min_short_ MIN_SHORT
+#elif defined(F77_NAME_LOWER_2USCORE)
+#define min_short_ min_short__
+#elif !defined(F77_NAME_LOWER_USCORE)
+#define min_short_ min_short
+/* Else leave name alone */
+#endif
+FORTRAN_API double FORT_CALL min_short_(void) {
+ return SHRT_MIN;
+}
+
+#ifdef F77_NAME_UPPER
+#define min_int_ MIN_INT
+#elif defined(F77_NAME_LOWER_2USCORE)
+#define min_int_ min_int__
+#elif !defined(F77_NAME_LOWER_USCORE)
+#define min_int_ min_int
+/* Else leave name alone */
+#endif
+FORTRAN_API double FORT_CALL min_int_(void) {
+ return INT_MIN;
+}
+
+#ifdef F77_NAME_UPPER
+#define min_int64_ MIN_INT64
+#elif defined(F77_NAME_LOWER_2USCORE)
+#define min_int64_ min_int64__
+#elif !defined(F77_NAME_LOWER_USCORE)
+#define min_int64_ min_int64
+/* Else leave name alone */
+#endif
+FORTRAN_API double FORT_CALL min_int64_(void) {
+ return INT64_MIN;
+}
+
+#ifdef F77_NAME_UPPER
+#define max_schar_ MAX_SCHAR
+#elif defined(F77_NAME_LOWER_2USCORE)
+#define max_schar_ max_schar__
+#elif !defined(F77_NAME_LOWER_USCORE)
+#define max_schar_ max_schar
+/* Else leave name alone */
+#endif
+FORTRAN_API double FORT_CALL max_schar_(void) {
+ return SCHAR_MAX;
+}
+
+#ifdef F77_NAME_UPPER
+#define max_short_ MAX_SHORT
+#elif defined(F77_NAME_LOWER_2USCORE)
+#define max_short_ max_short__
+#elif !defined(F77_NAME_LOWER_USCORE)
+#define max_short_ max_short
+/* Else leave name alone */
+#endif
+FORTRAN_API double FORT_CALL max_short_(void) {
+ return SHRT_MAX;
+}
+
+#ifdef F77_NAME_UPPER
+#define max_int_ MAX_INT
+#elif defined(F77_NAME_LOWER_2USCORE)
+#define max_int_ max_int__
+#elif !defined(F77_NAME_LOWER_USCORE)
+#define max_int_ max_int
+/* Else leave name alone */
+#endif
+FORTRAN_API double FORT_CALL max_int_(void) {
+ return INT_MAX;
+}
+
+#ifdef F77_NAME_UPPER
+#define max_int64_ MAX_INT64
+#elif defined(F77_NAME_LOWER_2USCORE)
+#define max_int64_ max_int64__
+#elif !defined(F77_NAME_LOWER_USCORE)
+#define max_int64_ max_int64
+/* Else leave name alone */
+#endif
+FORTRAN_API double FORT_CALL max_int64_(void) {
+ return INT64_MAX;
+}
+
+#ifdef F77_NAME_UPPER
+#define max_float_ MAX_FLOAT
+#elif defined(F77_NAME_LOWER_2USCORE)
+#define max_float_ max_float__
+#elif !defined(F77_NAME_LOWER_USCORE)
+#define max_float_ max_float
+/* Else leave name alone */
+#endif
+FORTRAN_API double FORT_CALL max_float_(void) {
+ return FLT_MAX;
+}
+
+#ifdef F77_NAME_UPPER
+#define max_double_ MAX_DOUBLE
+#elif defined(F77_NAME_LOWER_2USCORE)
+#define max_double_ max_double__
+#elif !defined(F77_NAME_LOWER_USCORE)
+#define max_double_ max_double
+/* Else leave name alone */
+#endif
+FORTRAN_API double FORT_CALL max_double_(void) {
+ return DBL_MAX;
+}
+
+#if 0 /* this is implemented in library src now */
+
+#ifdef F77_NAME_UPPER
+#define nfmpi_issyserr_ NFMPI_ISSYSERR
+#elif defined(F77_NAME_LOWER_2USCORE)
+#define nfmpi_issyserr_ nfmpi_issyserr__
+#elif !defined(F77_NAME_LOWER_USCORE)
+#define nfmpi_issyserr_ nfmpi_issyserr
+/* Else leave name alone */
+#endif
+
+FORTRAN_API int FORT_CALL nfmpi_issyserr_(int * A1) {
+ if (*A1 > 0)
+ return 1;
+ else
+ return 0;
+}
+
+
+#ifdef F77_NAME_UPPER
+#define nfmpi_delete_ NFMPI_DELETE
+#elif defined(F77_NAME_LOWER_2USCORE)
+#define nfmpi_delete_ nfmpi_delete__
+#elif !defined(F77_NAME_LOWER_USCORE)
+#define nfmpi_delete_ nfmpi_delete
+/* Else leave name alone */
+#endif
+FORTRAN_API void FORT_CALL nfmpi_delete_(char * name, int *err, int d1) {
+ char *p1;
+
+ {char *p = name + d1 - 1;
+ int li;
+ while (*p == ' ' && p > name) p--;
+ p++;
+ p1 = (char *)malloc( p-name + 1 );
+ for (li=0; li<(p-name); li++) { p1[li] = name[li]; }
+ p1[li] = 0;
+ }
+
+ if ( unlink(p1) != 0 )
+ *err = errno;
+ else
+ *err = 0;
+ free(p1);
+}
+
+#endif
diff --git a/test/nf_test/nf_error.F b/test/nf_test/nf_error.F
new file mode 100644
index 0000000..fdcbc88
--- /dev/null
+++ b/test/nf_test/nf_error.F
@@ -0,0 +1,81 @@
+#if 0
+ Copyright 1996, UCAR/Unidata
+ See netcdf/COPYRIGHT file for copying and redistribution conditions.
+ $Id: nf_error.F 2223 2015-12-15 16:10:30Z wkliao $
+#endif
+
+
+C
+C Use for logging error messages
+C
+ subroutine error(msg)
+ implicit none
+ character*(*) msg
+ include "pnetcdf.inc"
+#include "tests.inc"
+
+ nfails = nfails + 1
+ if (nfails .le. max_nmpt) print *, msg
+ end
+
+
+C
+C Use for logging error conditions
+C
+ subroutine errori(msg, i)
+ implicit none
+ character*(*) msg
+ integer i
+ include "pnetcdf.inc"
+#include "tests.inc"
+
+ nfails = nfails + 1
+ if (nfails .le. max_nmpt) print *, msg, i
+ end
+
+
+C
+C Use for logging error conditions
+C
+ subroutine errord(msg, d)
+ implicit none
+ character*(*) msg
+ doubleprecision d
+ include "pnetcdf.inc"
+#include "tests.inc"
+
+ nfails = nfails + 1
+ if (nfails .le. max_nmpt) print *, msg, d
+ end
+
+
+C
+C Use for logging error conditions
+C
+ subroutine errorc(msg, string)
+ implicit none
+ character*(*) msg
+ character*(*) string
+ include "pnetcdf.inc"
+#include "tests.inc"
+
+ integer MY_LEN_TRIM
+ nfails = nfails + 1
+ if (nfails .le. max_nmpt) print *, msg,
+ + TRIM(string) ! string(1:len_trim(string))
+ end
+
+
+C
+C Use for logging error conditions
+C
+ subroutine errore(msg, err)
+ implicit none
+ character*(*) msg
+ integer err
+ include "pnetcdf.inc"
+#include "tests.inc"
+
+ nfails = nfails + 1
+ call errorc(msg, nfmpi_strerror(err))
+ end
diff --git a/test/nf_test/nf_test.F b/test/nf_test/nf_test.F
new file mode 100644
index 0000000..d563032
--- /dev/null
+++ b/test/nf_test/nf_test.F
@@ -0,0 +1,861 @@
+#if 0
+/*********************************************************************
+ * Copyright 1996, UCAR/Unidata
+ * See netcdf/COPYRIGHT file for copying and redistribution conditions.
+ * $Id: nf_test.F 2224 2015-12-16 06:10:36Z wkliao $
+ *********************************************************************/
+
+/*
+ * Test driver for netCDF-3 interface. This program performs tests against
+ * the netCDF-3 specification for all user-level functions in an
+ * implementation of the netCDF library.
+ *
+ * Unless invoked with "-r" (readonly) option, must be invoked from a
+ * directory in which the invoker has write permission.
+ *
+ * Files:
+ * The read-only tests read files:
+ * test.nc (see below)
+ * test_get.F (used merely as an example of a non-netCDF file)
+ *
+ * The write tests
+ * read test.nc (see below)
+ * write scratch.nc (deleted after each test)
+ *
+ * The file test.nc is created by running nc_test with the -c (create) option.
+ */
+#endif
+
+ subroutine usage()
+ implicit none
+ include "pnetcdf.inc"
+#include "tests.inc"
+
+ integer MY_LEN_TRIM
+ call error('Usage: '//TRIM(progname)//
+ + ' [-c | -hrv -n <MAX_NMPT>]')
+ call error(' nf_test [-c]')
+ call error(' [-h] Print help' )
+ call error(' [-c] Create file test.nc (Do not do tests)' )
+ call error(' [-1] test CDF-1 format' )
+ call error(' [-2] test CDF-2 format' )
+ call error(' [-5] test CDF-5 format' )
+ call error(' [-r] Just do read-only tests' )
+ call error(
+ + ' [-d directory] directory for storing input/output files' )
+ call error(' [-v] Verbose mode' )
+ call error(
+ + ' [-n <max>] max. number of messages per test (Default: 20)')
+ end
+
+
+ subroutine report_test
+ implicit none
+ character*128 msg
+#include "tests.inc"
+
+ integer MY_LEN_TRIM
+ write(msg,"(A,I1)") '*** TESTING F77 '//
+ + TRIM(PROGNAME)//
+ + ' for CDF-', cdf_format
+ if (nfailsTotal .ne. 0) then
+ write(*,*) TRIM(PROGNAME)//
+ + ' expects to see 0 failure ... '//
+ + 'Total number of failures: ', nfailsTotal
+ endif
+ call pass_fail(nfailsTotal, msg)
+ end
+
+ subroutine test(name, func)
+ implicit none
+ character*(*) name
+ character*25 name_str
+ integer name_len
+ external func
+ include "pnetcdf.inc"
+#include "tests.inc"
+
+ integer MY_LEN_TRIM
+ name_len = MY_LEN_TRIM(name)
+ name_str(1:name_len) = name(:)
+ name_str(name_len+1:25) = ' '
+ if (verbose) write(*, 1) name_str
+1 format('*** Testing ', a, ' ... ')
+
+ nfails = 0
+ call func()
+ nfailsTotal = nfailsTotal + nfails
+ if ( nfails .ne. 0) then
+ print *, ' '
+ print *, ' ### ', nfails, ' FAILURES TESTING ', name,
+ + '! Stop ... ###'
+ call report_test
+ stop
+ end if
+ end
+
+
+#if _CRAYIEEE
+! which machines need this?
+ subroutine getarg(iarg, carg)
+ implicit none
+ integer iarg
+ character*(*) carg
+ integer ilen
+ integer ierror
+ call PXFGETARG(iarg, carg, ilen, ierror)
+ end
+#endif
+
+ program nf_test
+#if defined(VISUAL_CPLUSPLUS)
+! DIGITAL Visual Fortran needs DFLIB for getarg
+ USE DFLIB
+! DIGITAL Visual Fortran needs DFPORT for iargc
+ USE DFPORT
+ implicit none
+#elif defined(NAGf90Fortran)
+ USE F90_UNIX_ENV, only : iargc, getarg
+ implicit none
+#else
+ implicit none
+ integer iargc
+#endif
+#if defined(__crayx1)
+ integer ipxfargc
+#endif
+ include "pnetcdf.inc"
+#include "tests.inc"
+
+ integer argc
+ character*80 arg
+ integer iarg
+ integer iopt
+ character*1 opt
+ integer lastopt
+ logical skiparg
+ integer err
+ integer MY_LEN_TRIM
+
+ external test_nfmpi_strerror
+ external test_nfmpi_open
+ external test_nfmpi_close
+ external test_nfmpi_inq
+ external test_nfmpi_inq_dimid
+ external test_nfmpi_inq_dim
+ external test_nfmpi_inq_dimlen
+ external test_nfmpi_inq_dimname
+ external test_nfmpi_inq_varid
+ external test_nfmpi_inq_var
+ external test_nfmpi_inq_natts
+ external test_nfmpi_inq_ndims
+ external test_nfmpi_inq_nvars
+ external test_nfmpi_inq_unlimdim
+ external test_nfmpi_inq_vardimid
+ external test_nfmpi_inq_varname
+ external test_nfmpi_inq_varnatts
+ external test_nfmpi_inq_varndims
+ external test_nfmpi_inq_vartype
+ external test_nfmpi_get_var1_text
+#if defined(NF_INT1_T)
+ external test_nfmpi_get_var1_int1
+#endif
+#if defined(NF_INT2_T)
+ external test_nfmpi_get_var1_int2
+#endif
+ external test_nfmpi_get_var1_int
+ external test_nfmpi_get_var1_real
+ external test_nfmpi_get_var1_double
+ external test_nfmpi_get_var1_int8
+ external test_nfmpi_get_var_text
+#if defined(NF_INT1_T)
+ external test_nfmpi_get_var_int1
+#endif
+#if defined(NF_INT2_T)
+ external test_nfmpi_get_var_int2
+#endif
+ external test_nfmpi_get_var_int
+ external test_nfmpi_get_var_real
+ external test_nfmpi_get_var_double
+ external test_nfmpi_get_var_int8
+ external test_nfmpi_get_vara_text
+#if defined(NF_INT1_T)
+ external test_nfmpi_get_vara_int1
+#endif
+#if defined(NF_INT2_T)
+ external test_nfmpi_get_vara_int2
+#endif
+ external test_nfmpi_get_vara_int
+ external test_nfmpi_get_vara_real
+ external test_nfmpi_get_vara_double
+ external test_nfmpi_get_vara_int8
+ external test_nfmpi_get_vars_text
+#if defined(NF_INT1_T)
+ external test_nfmpi_get_vars_int1
+#endif
+#if defined(NF_INT2_T)
+ external test_nfmpi_get_vars_int2
+#endif
+ external test_nfmpi_get_vars_int
+ external test_nfmpi_get_vars_real
+ external test_nfmpi_get_vars_double
+ external test_nfmpi_get_vars_int8
+
+ external test_nfmpi_get_varm_text
+#if defined(NF_INT1_T)
+ external test_nfmpi_get_varm_int1
+#endif
+#if defined(NF_INT2_T)
+ external test_nfmpi_get_varm_int2
+#endif
+ external test_nfmpi_get_varm_int
+ external test_nfmpi_get_varm_real
+ external test_nfmpi_get_varm_double
+ external test_nfmpi_get_varm_int8
+
+ external test_nfmpi_iget_var1_text
+#if defined(NF_INT1_T)
+ external test_nfmpi_iget_var1_int1
+#endif
+#if defined(NF_INT2_T)
+ external test_nfmpi_iget_var1_int2
+#endif
+ external test_nfmpi_iget_var1_int
+ external test_nfmpi_iget_var1_real
+ external test_nfmpi_iget_var1_double
+ external test_nfmpi_iget_var1_int8
+ external test_nfmpi_iget_var_text
+#if defined(NF_INT1_T)
+ external test_nfmpi_iget_var_int1
+#endif
+#if defined(NF_INT2_T)
+ external test_nfmpi_iget_var_int2
+#endif
+ external test_nfmpi_iget_var_int
+ external test_nfmpi_iget_var_real
+ external test_nfmpi_iget_var_double
+ external test_nfmpi_iget_var_int8
+ external test_nfmpi_iget_vara_text
+#if defined(NF_INT1_T)
+ external test_nfmpi_iget_vara_int1
+#endif
+#if defined(NF_INT2_T)
+ external test_nfmpi_iget_vara_int2
+#endif
+ external test_nfmpi_iget_vara_int
+ external test_nfmpi_iget_vara_real
+ external test_nfmpi_iget_vara_double
+ external test_nfmpi_iget_vara_int8
+ external test_nfmpi_iget_vars_text
+#if defined(NF_INT1_T)
+ external test_nfmpi_iget_vars_int1
+#endif
+#if defined(NF_INT2_T)
+ external test_nfmpi_iget_vars_int2
+#endif
+ external test_nfmpi_iget_vars_int
+ external test_nfmpi_iget_vars_real
+ external test_nfmpi_iget_vars_double
+ external test_nfmpi_iget_vars_int8
+
+ external test_nfmpi_iget_varm_text
+#if defined(NF_INT1_T)
+ external test_nfmpi_iget_varm_int1
+#endif
+#if defined(NF_INT2_T)
+ external test_nfmpi_iget_varm_int2
+#endif
+ external test_nfmpi_iget_varm_int
+ external test_nfmpi_iget_varm_real
+ external test_nfmpi_iget_varm_double
+ external test_nfmpi_iget_varm_int8
+
+ external test_nfmpi_get_att_text
+#if defined(NF_INT1_T)
+ external test_nfmpi_get_att_int1
+#endif
+#if defined(NF_INT2_T)
+ external test_nfmpi_get_att_int2
+#endif
+ external test_nfmpi_get_att_int
+ external test_nfmpi_get_att_real
+ external test_nfmpi_get_att_double
+ external test_nfmpi_get_att_int8
+ external test_nfmpi_inq_att
+ external test_nfmpi_inq_attname
+ external test_nfmpi_inq_attid
+ external test_nfmpi_inq_attlen
+ external test_nfmpi_inq_atttype
+ external test_nfmpi_create
+ external test_nfmpi_redef
+ external test_nfmpi_enddef
+ external test_nfmpi_sync
+ external test_nfmpi_abort
+ external test_nfmpi_def_dim
+ external test_nfmpi_rename_dim
+ external test_nfmpi_def_var
+ external test_nfmpi_put_var1_text
+#if defined(NF_INT1_T)
+ external test_nfmpi_put_var1_int1
+#endif
+#if defined(NF_INT2_T)
+ external test_nfmpi_put_var1_int2
+#endif
+ external test_nfmpi_put_var1_int
+ external test_nfmpi_put_var1_real
+ external test_nfmpi_put_var1_double
+ external test_nfmpi_put_var1_int8
+ external test_nfmpi_put_var_text
+#if defined(NF_INT1_T)
+ external test_nfmpi_put_var_int1
+#endif
+#if defined(NF_INT2_T)
+ external test_nfmpi_put_var_int2
+#endif
+ external test_nfmpi_put_var_int
+ external test_nfmpi_put_var_real
+ external test_nfmpi_put_var_double
+ external test_nfmpi_put_var_int8
+ external test_nfmpi_put_vara_text
+#if defined(NF_INT1_T)
+ external test_nfmpi_put_vara_int1
+#endif
+#if defined(NF_INT2_T)
+ external test_nfmpi_put_vara_int2
+#endif
+ external test_nfmpi_put_vara_int
+ external test_nfmpi_put_vara_real
+ external test_nfmpi_put_vara_double
+ external test_nfmpi_put_vara_int8
+ external test_nfmpi_put_vars_text
+#if defined(NF_INT1_T)
+ external test_nfmpi_put_vars_int1
+#endif
+#if defined(NF_INT2_T)
+ external test_nfmpi_put_vars_int2
+#endif
+ external test_nfmpi_put_vars_int
+ external test_nfmpi_put_vars_real
+ external test_nfmpi_put_vars_double
+ external test_nfmpi_put_vars_int8
+
+ external test_nfmpi_put_varm_text
+#if defined(NF_INT1_T)
+ external test_nfmpi_put_varm_int1
+#endif
+#if defined(NF_INT2_T)
+ external test_nfmpi_put_varm_int2
+#endif
+ external test_nfmpi_put_varm_int
+ external test_nfmpi_put_varm_real
+ external test_nfmpi_put_varm_double
+ external test_nfmpi_put_varm_int8
+
+ external test_nfmpi_iput_var1_text
+#if defined(NF_INT1_T)
+ external test_nfmpi_iput_var1_int1
+#endif
+#if defined(NF_INT2_T)
+ external test_nfmpi_iput_var1_int2
+#endif
+ external test_nfmpi_iput_var1_int
+ external test_nfmpi_iput_var1_real
+ external test_nfmpi_iput_var1_double
+ external test_nfmpi_iput_var1_int8
+ external test_nfmpi_iput_var_text
+#if defined(NF_INT1_T)
+ external test_nfmpi_iput_var_int1
+#endif
+#if defined(NF_INT2_T)
+ external test_nfmpi_iput_var_int2
+#endif
+ external test_nfmpi_iput_var_int
+ external test_nfmpi_iput_var_real
+ external test_nfmpi_iput_var_double
+ external test_nfmpi_iput_var_int8
+ external test_nfmpi_iput_vara_text
+#if defined(NF_INT1_T)
+ external test_nfmpi_iput_vara_int1
+#endif
+#if defined(NF_INT2_T)
+ external test_nfmpi_iput_vara_int2
+#endif
+ external test_nfmpi_iput_vara_int
+ external test_nfmpi_iput_vara_real
+ external test_nfmpi_iput_vara_double
+ external test_nfmpi_iput_vara_int8
+ external test_nfmpi_iput_vars_text
+#if defined(NF_INT1_T)
+ external test_nfmpi_iput_vars_int1
+#endif
+#if defined(NF_INT2_T)
+ external test_nfmpi_iput_vars_int2
+#endif
+ external test_nfmpi_iput_vars_int
+ external test_nfmpi_iput_vars_real
+ external test_nfmpi_iput_vars_double
+ external test_nfmpi_iput_vars_int8
+
+ external test_nfmpi_iput_varm_text
+#if defined(NF_INT1_T)
+ external test_nfmpi_iput_varm_int1
+#endif
+#if defined(NF_INT2_T)
+ external test_nfmpi_iput_varm_int2
+#endif
+ external test_nfmpi_iput_varm_int
+ external test_nfmpi_iput_varm_real
+ external test_nfmpi_iput_varm_double
+ external test_nfmpi_iput_varm_int8
+
+ external test_nfmpi_rename_var
+ external test_nfmpi_put_att_text
+#if defined(NF_INT1_T)
+ external test_nfmpi_put_att_int1
+#endif
+#if defined(NF_INT2_T)
+ external test_nfmpi_put_att_int2
+#endif
+ external test_nfmpi_put_att_int
+ external test_nfmpi_put_att_real
+ external test_nfmpi_put_att_double
+ external test_nfmpi_put_att_int8
+ external test_nfmpi_copy_att
+ external test_nfmpi_rename_att
+ external test_nfmpi_del_att
+ external test_nfmpi_set_fill
+#if 0
+ external test_nfmpi_set_default_format
+#endif
+ external nc_ignorefpe
+
+ call MPI_INIT(err)
+ comm = MPI_COMM_WORLD
+
+ call nc_ignorefpe(1)
+
+ testfile = 'test.nc'
+ scratch = 'scratch.nc'
+
+ nfailsTotal = 0
+ call getarg(0, progname)
+ create_file = .false. !/* file test.nc will normally already exist */
+ readonly = .false. !/* assume may write in test dir as default */
+ verbose = .false.
+ max_nmpt = 20
+ skiparg = .false.
+ cdf_format = 1
+ extra_flags = 0
+
+#if defined(__crayx1)
+ argc = ipxfargc()
+#else
+ argc = iargc()
+#endif
+ call getarg(0, PROGNAME)
+
+ do 1, iarg = 1, argc
+ if (skiparg) then
+ skiparg = .false.
+ else
+ call getarg(iarg, arg)
+ if (arg(1:1) .eq. '-') then
+ lastopt = index(arg, ' ') - 1
+ do 2, iopt = 2, lastopt
+ opt = arg(iopt:iopt)
+ if (opt .eq. 'c') then
+ create_file = .true.
+ else if (opt .eq. 'r') then
+ readonly = .true.
+ else if (opt .eq. 'v') then
+ verbose = .true.
+ else if (opt .eq. 'n') then
+ call getarg(iarg+1, arg)
+ ! NOTE: The UNICOS 8 fort77(1) compiler does
+ ! not support list-directed I/O from an internal
+ ! file -- so we use a format specification.
+ read (arg, '(i6)') max_nmpt
+ skiparg = .true.
+ go to 1
+ else if (opt .eq. '1') then
+ cdf_format = 1
+ else if (opt .eq. '2') then
+ cdf_format = 2
+ extra_flags = NF_64BIT_OFFSET
+ else if (opt .eq. '5') then
+ cdf_format = 5
+ extra_flags = NF_64BIT_DATA
+ else if (opt .eq. 'd') then
+ call getarg(iarg+1, arg)
+ testfile = TRIM(arg)//
+ + "/test.nc"
+ scratch = TRIM(arg) //
+ + "/scratch.nc"
+ skiparg = .true.
+ go to 1
+ else
+ call usage
+ call ud_exit(1)
+ end if
+ 2 continue
+ else
+ call usage
+ call ud_exit(1)
+ end if
+ end if
+1 continue
+
+ numGatts = 6
+ numVars = 136
+ numTypes = 6
+ if (cdf_format .EQ. 5) then
+ numGatts = NGATTS
+ numVars = NVARS
+ numTypes = NTYPES
+ endif
+
+C PVFS2 driver has a problem of ADIOI_Set_lock when data sieving is
+C enabled
+ call MPI_Info_create(info, err)
+C call MPI_Info_set(info, "romio_pvfs2_posix_write", "enable",err)
+
+C /* Initialize global variables defining test file */
+ call init_gvars
+
+ if ( create_file ) then
+ call write_file(testfile)
+ call MPI_Info_free(info, err)
+ if (nfailsTotal .eq. 0)
+ + call ud_exit(0)
+ call ud_exit(1)
+ end if
+
+C /* delete any existing scratch netCDF file */
+ if ( .not. readonly )
+ + err = nfmpi_delete(scratch, MPI_INFO_NULL)
+
+C /* Test read-only functions, using pregenerated test-file */
+ call test('nfmpi_strerror', test_nfmpi_strerror)
+ call test('nfmpi_open', test_nfmpi_open)
+ call test('nfmpi_close', test_nfmpi_close)
+ call test('nfmpi_inq', test_nfmpi_inq)
+ call test('nfmpi_inq_dimid', test_nfmpi_inq_dimid)
+ call test('nfmpi_inq_dim', test_nfmpi_inq_dim)
+ call test('nfmpi_inq_dimlen', test_nfmpi_inq_dimlen)
+ call test('nfmpi_inq_dimname', test_nfmpi_inq_dimname)
+ call test('nfmpi_inq_varid', test_nfmpi_inq_varid)
+ call test('nfmpi_inq_var', test_nfmpi_inq_var)
+ call test('nfmpi_inq_natts', test_nfmpi_inq_natts)
+ call test('nfmpi_inq_ndims', test_nfmpi_inq_ndims)
+ call test('nfmpi_inq_nvars', test_nfmpi_inq_nvars)
+ call test('nfmpi_inq_unlimdim', test_nfmpi_inq_unlimdim)
+ call test('nfmpi_inq_vardimid', test_nfmpi_inq_vardimid)
+ call test('nfmpi_inq_varname', test_nfmpi_inq_varname)
+ call test('nfmpi_inq_varnatts', test_nfmpi_inq_varnatts)
+ call test('nfmpi_inq_varndims', test_nfmpi_inq_varndims)
+ call test('nfmpi_inq_vartype', test_nfmpi_inq_vartype)
+
+ call test('nfmpi_get_var1_text', test_nfmpi_get_var1_text)
+#if defined(NF_INT1_T)
+ call test('nfmpi_get_var1_int1', test_nfmpi_get_var1_int1)
+#endif
+#if defined(NF_INT2_T)
+ call test('nfmpi_get_var1_int2', test_nfmpi_get_var1_int2)
+#endif
+ call test('nfmpi_get_var1_int', test_nfmpi_get_var1_int)
+ call test('nfmpi_get_var1_real', test_nfmpi_get_var1_real)
+ call test('nfmpi_get_var1_double', test_nfmpi_get_var1_double)
+ call test('nfmpi_get_var1_int8', test_nfmpi_get_var1_int8)
+
+ call test('nfmpi_get_var_text', test_nfmpi_get_var_text)
+#if defined(NF_INT1_T)
+ call test('nfmpi_get_var_int1', test_nfmpi_get_var_int1)
+#endif
+#if defined(NF_INT2_T)
+ call test('nfmpi_get_var_int2', test_nfmpi_get_var_int2)
+#endif
+ call test('nfmpi_get_var_int', test_nfmpi_get_var_int)
+ call test('nfmpi_get_var_real', test_nfmpi_get_var_real)
+ call test('nfmpi_get_var_double', test_nfmpi_get_var_double)
+ call test('nfmpi_get_var_int8', test_nfmpi_get_var_int8)
+
+ call test('nfmpi_get_vara_text', test_nfmpi_get_vara_text)
+#if defined(NF_INT1_T)
+ call test('nfmpi_get_vara_int1', test_nfmpi_get_vara_int1)
+#endif
+#if defined(NF_INT2_T)
+ call test('nfmpi_get_vara_int2', test_nfmpi_get_vara_int2)
+#endif
+ call test('nfmpi_get_vara_int', test_nfmpi_get_vara_int)
+ call test('nfmpi_get_vara_real', test_nfmpi_get_vara_real)
+ call test('nfmpi_get_vara_double', test_nfmpi_get_vara_double)
+ call test('nfmpi_get_vara_int8', test_nfmpi_get_vara_int8)
+
+ call test('nfmpi_get_vars_text', test_nfmpi_get_vars_text)
+#if defined(NF_INT1_T)
+ call test('nfmpi_get_vars_int1', test_nfmpi_get_vars_int1)
+#endif
+#if defined(NF_INT2_T)
+ call test('nfmpi_get_vars_int2', test_nfmpi_get_vars_int2)
+#endif
+ call test('nfmpi_get_vars_int', test_nfmpi_get_vars_int)
+ call test('nfmpi_get_vars_real', test_nfmpi_get_vars_real)
+ call test('nfmpi_get_vars_double', test_nfmpi_get_vars_double)
+ call test('nfmpi_get_vars_int8', test_nfmpi_get_vars_int8)
+
+ call test('nfmpi_get_varm_text', test_nfmpi_get_varm_text)
+#if defined(NF_INT1_T)
+ call test('nfmpi_get_varm_int1', test_nfmpi_get_varm_int1)
+#endif
+#if defined(NF_INT2_T)
+ call test('nfmpi_get_varm_int2', test_nfmpi_get_varm_int2)
+#endif
+ call test('nfmpi_get_varm_int', test_nfmpi_get_varm_int)
+ call test('nfmpi_get_varm_real', test_nfmpi_get_varm_real)
+ call test('nfmpi_get_varm_double', test_nfmpi_get_varm_double)
+ call test('nfmpi_get_varm_int8', test_nfmpi_get_varm_int8)
+
+ call test('nfmpi_iget_var1_text', test_nfmpi_iget_var1_text)
+#if defined(NF_INT1_T)
+ call test('nfmpi_iget_var1_int1', test_nfmpi_iget_var1_int1)
+#endif
+#if defined(NF_INT2_T)
+ call test('nfmpi_iget_var1_int2', test_nfmpi_iget_var1_int2)
+#endif
+ call test('nfmpi_iget_var1_int', test_nfmpi_iget_var1_int)
+ call test('nfmpi_iget_var1_real', test_nfmpi_iget_var1_real)
+ call test('nfmpi_iget_var1_double', test_nfmpi_iget_var1_double)
+ call test('nfmpi_iget_var1_int8', test_nfmpi_iget_var1_int8)
+
+ call test('nfmpi_iget_var_text', test_nfmpi_iget_var_text)
+#if defined(NF_INT1_T)
+ call test('nfmpi_iget_var_int1', test_nfmpi_iget_var_int1)
+#endif
+#if defined(NF_INT2_T)
+ call test('nfmpi_iget_var_int2', test_nfmpi_iget_var_int2)
+#endif
+ call test('nfmpi_iget_var_int', test_nfmpi_iget_var_int)
+ call test('nfmpi_iget_var_real', test_nfmpi_iget_var_real)
+ call test('nfmpi_iget_var_double', test_nfmpi_iget_var_double)
+ call test('nfmpi_iget_var_int8', test_nfmpi_iget_var_int8)
+
+ call test('nfmpi_iget_vara_text', test_nfmpi_iget_vara_text)
+#if defined(NF_INT1_T)
+ call test('nfmpi_iget_vara_int1', test_nfmpi_iget_vara_int1)
+#endif
+#if defined(NF_INT2_T)
+ call test('nfmpi_iget_vara_int2', test_nfmpi_iget_vara_int2)
+#endif
+ call test('nfmpi_iget_vara_int', test_nfmpi_iget_vara_int)
+ call test('nfmpi_iget_vara_real', test_nfmpi_iget_vara_real)
+ call test('nfmpi_iget_vara_double', test_nfmpi_iget_vara_double)
+ call test('nfmpi_iget_vara_int8', test_nfmpi_iget_vara_int8)
+
+ call test('nfmpi_iget_vars_text', test_nfmpi_iget_vars_text)
+#if defined(NF_INT1_T)
+ call test('nfmpi_iget_vars_int1', test_nfmpi_iget_vars_int1)
+#endif
+#if defined(NF_INT2_T)
+ call test('nfmpi_iget_vars_int2', test_nfmpi_iget_vars_int2)
+#endif
+ call test('nfmpi_iget_vars_int', test_nfmpi_iget_vars_int)
+ call test('nfmpi_iget_vars_real', test_nfmpi_iget_vars_real)
+ call test('nfmpi_iget_vars_double', test_nfmpi_iget_vars_double)
+ call test('nfmpi_iget_vars_int8', test_nfmpi_iget_vars_int8)
+
+ call test('nfmpi_iget_varm_text', test_nfmpi_iget_varm_text)
+#if defined(NF_INT1_T)
+ call test('nfmpi_iget_varm_int1', test_nfmpi_iget_varm_int1)
+#endif
+#if defined(NF_INT2_T)
+ call test('nfmpi_iget_varm_int2', test_nfmpi_iget_varm_int2)
+#endif
+ call test('nfmpi_iget_varm_int', test_nfmpi_iget_varm_int)
+ call test('nfmpi_iget_varm_real', test_nfmpi_iget_varm_real)
+ call test('nfmpi_iget_varm_double', test_nfmpi_iget_varm_double)
+ call test('nfmpi_iget_varm_int8', test_nfmpi_iget_varm_int8)
+
+ call test('nfmpi_get_att_text', test_nfmpi_get_att_text)
+#if defined(NF_INT1_T)
+ call test('nfmpi_get_att_int1', test_nfmpi_get_att_int1)
+#endif
+#if defined(NF_INT2_T)
+ call test('nfmpi_get_att_int2', test_nfmpi_get_att_int2)
+#endif
+ call test('nfmpi_get_att_int', test_nfmpi_get_att_int)
+ call test('nfmpi_get_att_real', test_nfmpi_get_att_real)
+ call test('nfmpi_get_att_double', test_nfmpi_get_att_double)
+ call test('nfmpi_get_att_int8', test_nfmpi_get_att_int8)
+ call test('nfmpi_inq_att', test_nfmpi_inq_att)
+ call test('nfmpi_inq_attname', test_nfmpi_inq_attname)
+ call test('nfmpi_inq_attid', test_nfmpi_inq_attid)
+ call test('nfmpi_inq_attlen', test_nfmpi_inq_attlen)
+ call test('nfmpi_inq_atttype', test_nfmpi_inq_atttype)
+
+C /* Test write functions */
+ if (.not. readonly) then
+ call test('nfmpi_create', test_nfmpi_create)
+ call test('nfmpi_redef', test_nfmpi_redef)
+ call test('nfmpi_enddef', test_nfmpi_enddef)
+ call test('nfmpi_sync', test_nfmpi_sync)
+ call test('nfmpi_abort', test_nfmpi_abort)
+ call test('nfmpi_def_dim', test_nfmpi_def_dim)
+ call test('nfmpi_rename_dim', test_nfmpi_rename_dim)
+ call test('nfmpi_def_var', test_nfmpi_def_var)
+ call test('nfmpi_put_var1_text', test_nfmpi_put_var1_text)
+#if defined(NF_INT1_T)
+ call test('nfmpi_put_var1_int1', test_nfmpi_put_var1_int1)
+#endif
+#if defined(NF_INT2_T)
+ call test('nfmpi_put_var1_int2', test_nfmpi_put_var1_int2)
+#endif
+ call test('nfmpi_put_var1_int', test_nfmpi_put_var1_int)
+ call test('nfmpi_put_var1_real', test_nfmpi_put_var1_real)
+ call test('nfmpi_put_var1_double',
+ + test_nfmpi_put_var1_double)
+ call test('nfmpi_put_var1_int8', test_nfmpi_put_var1_int8)
+ call test('nfmpi_put_var_text', test_nfmpi_put_var_text)
+#if defined(NF_INT1_T)
+ call test('nfmpi_put_var_int1', test_nfmpi_put_var_int1)
+#endif
+#if defined(NF_INT2_T)
+ call test('nfmpi_put_var_int2', test_nfmpi_put_var_int2)
+#endif
+ call test('nfmpi_put_var_int', test_nfmpi_put_var_int)
+ call test('nfmpi_put_var_real', test_nfmpi_put_var_real)
+ call test('nfmpi_put_var_double',
+ + test_nfmpi_put_var_double)
+ call test('nfmpi_put_var_int8', test_nfmpi_put_var_int8)
+ call test('nfmpi_put_vara_text', test_nfmpi_put_vara_text)
+#if defined(NF_INT1_T)
+ call test('nfmpi_put_vara_int1', test_nfmpi_put_vara_int1)
+#endif
+#if defined(NF_INT2_T)
+ call test('nfmpi_put_vara_int2', test_nfmpi_put_vara_int2)
+#endif
+ call test('nfmpi_put_vara_int', test_nfmpi_put_vara_int)
+ call test('nfmpi_put_vara_real', test_nfmpi_put_vara_real)
+ call test('nfmpi_put_vara_double',
+ + test_nfmpi_put_vara_double)
+ call test('nfmpi_put_vara_int8', test_nfmpi_put_vara_int8)
+ call test('nfmpi_put_vars_text', test_nfmpi_put_vars_text)
+#if defined(NF_INT1_T)
+ call test('nfmpi_put_vars_int1', test_nfmpi_put_vars_int1)
+#endif
+#if defined(NF_INT2_T)
+ call test('nfmpi_put_vars_int2', test_nfmpi_put_vars_int2)
+#endif
+ call test('nfmpi_put_vars_int', test_nfmpi_put_vars_int)
+ call test('nfmpi_put_vars_real', test_nfmpi_put_vars_real)
+ call test('nfmpi_put_vars_double',
+ + test_nfmpi_put_vars_double)
+ call test('nfmpi_put_vars_int8', test_nfmpi_put_vars_int8)
+
+ call test('nfmpi_put_varm_text', test_nfmpi_put_varm_text)
+#if defined(NF_INT1_T)
+ call test('nfmpi_put_varm_int1', test_nfmpi_put_varm_int1)
+#endif
+#if defined(NF_INT2_T)
+ call test('nfmpi_put_varm_int2', test_nfmpi_put_varm_int2)
+#endif
+ call test('nfmpi_put_varm_int', test_nfmpi_put_varm_int)
+ call test('nfmpi_put_varm_real', test_nfmpi_put_varm_real)
+ call test('nfmpi_put_varm_double',
+ + test_nfmpi_put_varm_double)
+ call test('nfmpi_put_varm_int8', test_nfmpi_put_varm_int8)
+
+ call test('nfmpi_iput_var1_text', test_nfmpi_iput_var1_text)
+#if defined(NF_INT1_T)
+ call test('nfmpi_iput_var1_int1', test_nfmpi_iput_var1_int1)
+#endif
+#if defined(NF_INT2_T)
+ call test('nfmpi_iput_var1_int2', test_nfmpi_iput_var1_int2)
+#endif
+ call test('nfmpi_iput_var1_int', test_nfmpi_iput_var1_int)
+ call test('nfmpi_iput_var1_real', test_nfmpi_iput_var1_real)
+ call test('nfmpi_iput_var1_double',
+ + test_nfmpi_iput_var1_double)
+ call test('nfmpi_iput_var1_int8', test_nfmpi_iput_var1_int8)
+
+ call test('nfmpi_iput_var_text', test_nfmpi_iput_var_text)
+#if defined(NF_INT1_T)
+ call test('nfmpi_iput_var_int1', test_nfmpi_iput_var_int1)
+#endif
+#if defined(NF_INT2_T)
+ call test('nfmpi_iput_var_int2', test_nfmpi_iput_var_int2)
+#endif
+ call test('nfmpi_iput_var_int', test_nfmpi_iput_var_int)
+ call test('nfmpi_iput_var_real', test_nfmpi_iput_var_real)
+ call test('nfmpi_iput_var_double',
+ + test_nfmpi_iput_var_double)
+ call test('nfmpi_iput_var_int8', test_nfmpi_iput_var_int8)
+
+ call test('nfmpi_iput_vara_text', test_nfmpi_iput_vara_text)
+#if defined(NF_INT1_T)
+ call test('nfmpi_iput_vara_int1', test_nfmpi_iput_vara_int1)
+#endif
+#if defined(NF_INT2_T)
+ call test('nfmpi_iput_vara_int2', test_nfmpi_iput_vara_int2)
+#endif
+ call test('nfmpi_iput_vara_int', test_nfmpi_iput_vara_int)
+ call test('nfmpi_iput_vara_real', test_nfmpi_iput_vara_real)
+ call test('nfmpi_iput_vara_double',
+ + test_nfmpi_iput_vara_double)
+ call test('nfmpi_iput_vara_int8', test_nfmpi_iput_vara_int8)
+
+ call test('nfmpi_iput_vars_text', test_nfmpi_iput_vars_text)
+#if defined(NF_INT1_T)
+ call test('nfmpi_iput_vars_int1', test_nfmpi_iput_vars_int1)
+#endif
+#if defined(NF_INT2_T)
+ call test('nfmpi_iput_vars_int2', test_nfmpi_iput_vars_int2)
+#endif
+ call test('nfmpi_iput_vars_int', test_nfmpi_iput_vars_int)
+ call test('nfmpi_iput_vars_real', test_nfmpi_iput_vars_real)
+ call test('nfmpi_iput_vars_double',
+ + test_nfmpi_iput_vars_double)
+ call test('nfmpi_iput_vars_int8', test_nfmpi_iput_vars_int8)
+
+ call test('nfmpi_iput_varm_text', test_nfmpi_iput_varm_text)
+#if defined(NF_INT1_T)
+ call test('nfmpi_iput_varm_int1', test_nfmpi_iput_varm_int1)
+#endif
+#if defined(NF_INT2_T)
+ call test('nfmpi_iput_varm_int2', test_nfmpi_iput_varm_int2)
+#endif
+ call test('nfmpi_iput_varm_int', test_nfmpi_iput_varm_int)
+ call test('nfmpi_iput_varm_real', test_nfmpi_iput_varm_real)
+ call test('nfmpi_iput_varm_double',
+ + test_nfmpi_iput_varm_double)
+ call test('nfmpi_iput_varm_int8', test_nfmpi_iput_varm_int8)
+
+ call test('nfmpi_rename_var', test_nfmpi_rename_var)
+ call test('nfmpi_put_att_text', test_nfmpi_put_att_text)
+#if defined(NF_INT1_T)
+ call test('nfmpi_put_att_int1', test_nfmpi_put_att_int1)
+#endif
+#if defined(NF_INT2_T)
+ call test('nfmpi_put_att_int2', test_nfmpi_put_att_int2)
+#endif
+ call test('nfmpi_put_att_int', test_nfmpi_put_att_int)
+ call test('nfmpi_put_att_real', test_nfmpi_put_att_real)
+ call test('nfmpi_put_att_double',
+ + test_nfmpi_put_att_double)
+ call test('nfmpi_put_att_int8', test_nfmpi_put_att_int8)
+ call test('nfmpi_copy_att', test_nfmpi_copy_att)
+ call test('nfmpi_rename_att', test_nfmpi_rename_att)
+ call test('nfmpi_del_att', test_nfmpi_del_att)
+ call test('nfmpi_set_fill', test_nfmpi_set_fill)
+#if 0
+ call test('nfmpi_set_default_format',
+ + test_nfmpi_set_default_format);
+#endif
+ end if
+
+ call MPI_Info_free(info, err)
+
+ call report_test
+
+ ! if (nfailsTotal .eq. 0) call ud_exit(0)
+ call ud_exit(0)
+ end
diff --git a/test/nf_test/test_get.m4 b/test/nf_test/test_get.m4
new file mode 100644
index 0000000..fc5da7e
--- /dev/null
+++ b/test/nf_test/test_get.m4
@@ -0,0 +1,1149 @@
+divert(-1)
+
+dnl This is m4 source.
+dnl Process using m4 to produce FORTRAN language file.
+
+changequote([,])
+
+undefine([index])dnl
+
+dnl Macros
+
+dnl Upcase(str)
+dnl
+define([Upcase],[dnl
+translit($1, abcdefghijklmnopqrstuvwxyz, ABCDEFGHIJKLMNOPQRSTUVWXYZ)])
+
+dnl NFT_ITYPE(type)
+dnl
+define([NFT_ITYPE], [NFT_[]Upcase($1)])
+
+dnl ARITH_VAR1(itype, value)
+dnl
+define([ARITH_VAR1], [ifelse($1, text, ichar($2), $2)])
+
+dnl ARITH3(itype, value)
+dnl
+define([ARITH3], [ifelse($1, text, ichar($2($3:$3)), $2($3))])
+
+dnl DATATYPE(funf_suffix)
+dnl
+define([DATATYPE], [dnl
+ifelse($1, text, character*MAX_NELS $2,
+ifelse($1, int1, NF_INT1_T $2$3,
+ifelse($1, int2, NF_INT2_T $2$3,
+ifelse($1, int, integer $2$3,
+ifelse($1, int8, NF_INT8_T $2$3,
+ifelse($1, real, real $2$3,
+ifelse($1, double, doubleprecision $2$3)[]dnl
+)[]dnl
+)[]dnl
+)[]dnl
+)[]dnl
+)[]dnl
+)[]dnl
+])
+
+dnl DATATYPE_VAR1(funf_suffix)
+dnl
+define([DATATYPE_VAR1], [dnl
+ifelse($1, text, character $2,
+ifelse($1, int1, NF_INT1_T $2,
+ifelse($1, int2, NF_INT2_T $2,
+ifelse($1, int, integer $2,
+ifelse($1, int8, NF_INT8_T $2,
+ifelse($1, real, real $2,
+ifelse($1, double, doubleprecision $2)[]dnl
+)[]dnl
+)[]dnl
+)[]dnl
+)[]dnl
+)[]dnl
+)[]dnl
+])
+
+dnl TEST_NFMPI_GET_VAR1(TYPE)
+dnl
+define([TEST_NFMPI_GET_VAR1],[dnl
+ subroutine test_nfmpi_get_var1_$1()
+ implicit none
+ include "pnetcdf.inc"
+#include "tests.inc"
+ integer index2indexes
+ double precision hash4
+ logical inRange3, in_internal_range, equal
+
+ integer ncid
+ integer i
+ integer j
+ integer err
+ integer nok
+ integer*8 index(MAX_RANK)
+ doubleprecision expect
+ logical canConvert
+ DATATYPE_VAR1($1, value)
+ doubleprecision val
+
+ nok = 0
+
+ err = nfmpi_open(comm, testfile, NF_NOWRITE, info, ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_open: ', err)
+ err = nfmpi_begin_indep_data(ncid)
+ do 1, i = 1, numVars
+ canConvert = (var_type(i) .eq. NF_CHAR) .eqv.
+ + (NFT_ITYPE($1) .eq. NFT_TEXT)
+ do 2, j = 1, var_rank(i)
+ index(j) = 1
+2 continue
+ err = nfmpi_get_var1_$1(BAD_ID, i, index, value)
+ if (err .ne. NF_EBADID)
+ + call errore('bad ncid: ', err)
+ err = nfmpi_get_var1_$1(ncid, BAD_VARID,
+ + index, value)
+ if (err .ne. NF_ENOTVAR)
+ + call errore('bad var id: ', err)
+ do 3, j = 1, var_rank(i)
+ index(j) = var_shape(j,i) + 1
+ err = nfmpi_get_var1_$1(ncid, i, index, value)
+ if (.not. canConvert) then
+ if (err .ne. NF_ECHAR)
+ + call errore('conversion: ', err)
+ else
+ if (err .ne. NF_EINVALCOORDS)
+ + call errore('bad index: ', err)
+ endif
+ index(j) = 1
+3 continue
+ do 4, j = 1, var_nels(i)
+ err = index2indexes(j, var_rank(i), var_shape(1,i),
+ + index)
+ if (err .ne. NF_NOERR)
+ + call error('error in index2indexes 1')
+ expect = hash4( var_type(i), var_rank(i), index,
+ + NFT_ITYPE($1) )
+ err = nfmpi_get_var1_$1(ncid, i, index,
+ + value)
+ if (canConvert) then
+ if (inRange3(expect,var_type(i),
+ + NFT_ITYPE($1))) then
+ if (in_internal_range(NFT_ITYPE($1),
+ + expect)) then
+ if (err .ne. NF_NOERR) then
+ call errore('nfmpi_get_var1_$1: ',
+ + err)
+ else
+ val = ARITH_VAR1($1, value)
+ if (.not. equal(val, expect,
+ + var_type(i),
+ + NFT_ITYPE($1))) then
+ call errori('varid: ', i)
+ call errorc('var_name: ',
+ + var_name(i))
+ call errord('unexpected: ', val)
+ call errord('expecting: ', expect)
+ else
+ nok = nok + 1
+ end if
+ end if
+ else
+ if (err .ne. NF_ERANGE)
+ + call errore('Range error: ', err)
+ end if
+ else
+ if (err .ne. NF_NOERR .and. err .ne. NF_ERANGE)
+ + call errore('OK or Range error: ', err)
+ end if
+ else
+ if (err .ne. NF_ECHAR)
+ + call errore('wrong type: ', err)
+ end if
+4 continue
+1 continue
+ err = nfmpi_end_indep_data(ncid)
+ err = nfmpi_close(ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_close: ', err)
+ call print_nok(nok)
+ end
+])
+
+dnl TEST_NFMPI_GET_VAR(TYPE)
+dnl
+define([TEST_NFMPI_GET_VAR],[dnl
+ subroutine test_nfmpi_get_var_$1()
+ implicit none
+ include "pnetcdf.inc"
+#include "tests.inc"
+ integer index2indexes
+ double precision hash4
+ logical inRange3, in_internal_range, equal
+
+ integer ncid
+ integer i
+ integer j
+ integer err
+ logical allInExtRange
+ logical allInIntRange
+ integer nels
+ integer nok
+ integer*8 index(MAX_RANK)
+ doubleprecision expect(MAX_NELS)
+ logical canConvert
+ DATATYPE($1, value, (MAX_NELS))
+ doubleprecision val
+
+ nok = 0
+
+ err = nfmpi_open(comm, testfile, NF_NOWRITE, info, ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_open: ', err)
+ do 1, i = 1, numVars
+ canConvert = (var_type(i) .eq. NF_CHAR) .eqv.
+ + (NFT_ITYPE($1) .eq. NFT_TEXT)
+ err = nfmpi_get_var_$1_all(BAD_ID, i, value)
+ if (err .ne. NF_EBADID)
+ + call errore('bad ncid: ', err)
+ err = nfmpi_get_var_$1_all(ncid, BAD_VARID, value)
+ if (err .ne. NF_ENOTVAR)
+ + call errore('bad var id: ', err)
+ nels = 1
+ do 3, j = 1, var_rank(i)
+ nels = nels * int(var_shape(j,i))
+3 continue
+ allInExtRange = .true.
+ allInIntRange = .true.
+ do 4, j = 1, var_nels(i)
+ err = index2indexes(j, var_rank(i), var_shape(1,i),
+ + index)
+ if (err .ne. NF_NOERR)
+ + call error('error in index2indexes 1')
+ expect(j) = hash4( var_type(i), var_rank(i), index,
+ + NFT_ITYPE($1) )
+ if (inRange3(expect(j),var_type(i), NFT_ITYPE($1))) then
+ allInIntRange = allInIntRange .and.
+ + in_internal_range(NFT_ITYPE($1), expect(j))
+ else
+ allInExtRange = .false.
+ end if
+4 continue
+ err = nfmpi_get_var_$1_all(ncid, i, value)
+ if (canConvert) then
+ if (allInExtRange) then
+ if (allInIntRange) then
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_get_var_$1_all: ',
+ + err)
+ else
+ if (err .ne. NF_ERANGE)
+ + call errore('Range error: ', err)
+ endif
+ else
+ if (err .ne. NF_NOERR .and. err .ne. NF_ERANGE)
+ + call errore('Range error: ', err)
+ endif
+ do 5, j = 1, var_nels(i)
+ if (inRange3(expect(j),var_type(i),
+ + NFT_ITYPE($1)) .and.
+ + in_internal_range(NFT_ITYPE($1),
+ + expect(j))) then
+ val = ARITH3($1, value, j)
+ if (.not. equal(val, expect(j),
+ + var_type(i),
+ + NFT_ITYPE($1))) then
+ call errord('unexpected: ', val)
+ call errord('expecting: ', expect(j))
+ else
+ nok = nok + 1
+ end if
+ endif
+5 continue
+ else
+ if (err .ne. NF_ECHAR)
+ + call errore('wrong type: ', err)
+ end if
+1 continue
+ err = nfmpi_close(ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_close: ', err)
+ call print_nok(nok)
+ end
+])
+
+
+dnl TEST_NFMPI_GET_VARA(TYPE)
+dnl
+define([TEST_NFMPI_GET_VARA],[dnl
+ subroutine test_nfmpi_get_vara_$1()
+ implicit none
+ include "pnetcdf.inc"
+#include "tests.inc"
+ integer index2indexes, roll
+ double precision hash4
+ logical inRange3, in_internal_range, equal
+
+ integer ncid
+ integer d
+ integer i
+ integer j
+ integer k
+ integer err
+ logical allInExtRange
+ logical allInIntRange
+ integer nels
+ integer nslabs
+ integer nok
+ integer*8 start(MAX_RANK)
+ integer*8 edge(MAX_RANK)
+ integer*8 index(MAX_RANK)
+ integer*8 mid(MAX_RANK)
+ logical canConvert
+ DATATYPE($1, value, (MAX_NELS))
+ doubleprecision expect(MAX_NELS)
+ doubleprecision val
+ integer ud_shift
+
+ nok = 0
+
+ err = nfmpi_open(comm, testfile, NF_NOWRITE, info, ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_open: ', err)
+ do 1, i = 1, numVars
+ canConvert = (var_type(i) .eq. NF_CHAR) .eqv.
+ + (NFT_ITYPE($1) .eq. NFT_TEXT)
+ if (.not.(var_rank(i) .le. MAX_RANK)) stop 'assert'
+ if (.not.(var_nels(i) .le. MAX_NELS)) stop 'assert'
+ do 2, j = 1, var_rank(i)
+ start(j) = 1
+ edge(j) = 1
+2 continue
+ err = nfmpi_get_vara_$1_all(BAD_ID, i, start,
+ + edge, value)
+ if (err .ne. NF_EBADID)
+ + call errore('bad ncid: ', err)
+ err = nfmpi_get_vara_$1_all(ncid, BAD_VARID, start,
+ + edge, value)
+ if (err .ne. NF_ENOTVAR)
+ + call errore('bad var id: ', err)
+ do 3, j = 1, var_rank(i)
+ start(j) = var_shape(j,i) + 1
+ err = nfmpi_get_vara_$1_all(ncid, i, start,
+ + edge, value)
+ if (canConvert .and. err .ne. NF_EINVALCOORDS)
+ + call errore('bad index: ', err)
+ start(j) = 1
+ edge(j) = var_shape(j,i) + 1
+ err = nfmpi_get_vara_$1_all(ncid, i, start,
+ + edge, value)
+ if (canConvert .and. err .ne. NF_EEDGE)
+ + call errore('bad edge: ', err)
+ edge(j) = 1
+3 continue
+
+C /* Check non-scalars for correct error returned even when */
+C /* there is nothing to get (edge(j).eq.0) */
+ if (var_rank(i) .gt. 0) then
+ do 10, j = 1, var_rank(i)
+ edge(j) = 0
+10 continue
+ err = nfmpi_get_vara_$1_all(BAD_ID, i, start,
+ + edge, value)
+ if (err .ne. NF_EBADID)
+ + call errore('bad ncid: ', err)
+ err = nfmpi_get_vara_$1_all(ncid, BAD_VARID,
+ + start, edge, value)
+ if (err .ne. NF_ENOTVAR)
+ + call errore('bad var id: ', err)
+ do 11, j = 1, var_rank(i)
+ if (var_dimid(j,i) .gt. 1) then !/* skip record dim */
+ start(j) = var_shape(j,i) + 1
+ err = nfmpi_get_vara_$1_all(ncid, i,
+ + start, edge, value)
+ if (canConvert .and. err .ne. NF_EINVALCOORDS)
+ + call errore('bad start: ', err)
+ start(j) = 1
+ endif
+11 continue
+ err = nfmpi_get_vara_$1_all(ncid, i, start,
+ + edge, value)
+ if (canConvert) then
+ if (err .ne. NF_NOERR)
+ + call error(nfmpi_strerror(err))
+ else
+ if (err .ne. NF_ECHAR)
+ + call errore('wrong type: ', err)
+ endif
+ do 12, j = 1, var_rank(i)
+ edge(j) = 1
+12 continue
+ endif
+
+C Choose a random point dividing each dim into 2 parts
+C get 2^rank (nslabs) slabs so defined
+ nslabs = 1
+ do 4, j = 1, var_rank(i)
+ mid(j) = roll( var_shape(j,i) )
+ nslabs = nslabs * 2
+4 continue
+C bits of k determine whether to get lower or upper part of dim
+ do 5, k = 1, nslabs
+ nels = 1
+ do 6, j = 1, var_rank(i)
+ if (mod(ud_shift((k-1), -(j-1)), 2) .eq. 1) then
+ start(j) = 1
+ edge(j) = mid(j)
+ else
+ start(j) = 1 + mid(j)
+ edge(j) = var_shape(j,i) - mid(j)
+ end if
+ nels = nels * int(edge(j))
+6 continue
+ allInIntRange = .true.
+ allInExtRange = .true.
+ do 7, j = 1, nels
+ err = index2indexes(j, var_rank(i), edge, index)
+ if (err .ne. NF_NOERR)
+ + call error('error in index2indexes 1')
+ do 8, d = 1, var_rank(i)
+ index(d) = index(d) + start(d) - 1
+8 continue
+ expect(j) = hash4(var_type(i), var_rank(i), index,
+ + NFT_ITYPE($1))
+ if (inRange3(expect(j),var_type(i),
+ + NFT_ITYPE($1))) then
+ allInIntRange =
+ + allInIntRange .and.
+ + in_internal_range(NFT_ITYPE($1), expect(j))
+ else
+ allInExtRange = .false.
+ end if
+7 continue
+ err = nfmpi_get_vara_$1_all(ncid, i, start,
+ + edge, value)
+ if (canConvert) then
+ if (allInExtRange) then
+ if (allInIntRange) then
+ if (err .ne. NF_NOERR)
+ + call errore(
+ + 'nfmpi_get_vara_$1_all:', err)
+ else
+ if (err .ne. NF_ERANGE)
+ + call errore('Range error: ', err)
+ end if
+ else
+ if (err .ne. NF_NOERR .and. err .ne. NF_ERANGE)
+ + call errore('OK or Range error: ', err)
+ end if
+ do 9, j = 1, nels
+ if (inRange3(expect(j),var_type(i),
+ + NFT_ITYPE($1)) .and.
+ + in_internal_range(NFT_ITYPE($1), expect(j)))
+ + then
+ val = ARITH3($1, value, j)
+ if (.not.equal(val,expect(j),
+ + var_type(i),NFT_ITYPE($1)))
+ + then
+ call error(
+ + 'value read not that expected')
+ if (verbose) then
+ call error(' ')
+ call errori('varid: ', i)
+ call errorc('var_name: ',
+ + var_name(i))
+ call errori('element number: %d ',
+ + j)
+ call errord('expect: ', expect(j))
+ call errord('got: ', val)
+ end if
+ else
+ nok = nok + 1
+ end if
+ end if
+9 continue
+ else
+ if (nels .gt. 0 .and. err .ne. NF_ECHAR)
+ + call errore('wrong type: ', err)
+ end if
+5 continue
+1 continue
+ err = nfmpi_close(ncid)
+ if (err .ne. NF_NOERR)
+ + call errorc('nfmpi_close: ', nfmpi_strerror(err))
+ call print_nok(nok)
+ end
+])dnl
+
+
+dnl TEST_NFMPI_GET_VARS(TYPE)
+dnl
+define([TEST_NFMPI_GET_VARS],dnl
+[dnl
+ subroutine test_nfmpi_get_vars_$1()
+ implicit none
+ include "pnetcdf.inc"
+#include "tests.inc"
+ integer index2indexes, roll
+ double precision hash4
+ logical inRange3, in_internal_range, equal
+
+ integer ncid
+ integer d
+ integer i
+ integer j
+ integer k
+ integer m
+ integer err
+ logical allInExtRange
+ logical allInIntRange
+ integer nels
+ integer nslabs
+ integer nstarts
+ integer nok
+ integer*8 start(MAX_RANK)
+ integer*8 edge(MAX_RANK)
+ integer*8 index(MAX_RANK)
+ integer*8 index2(MAX_RANK)
+ integer*8 mid(MAX_RANK)
+ integer*8 count(MAX_RANK)
+ integer*8 sstride(MAX_RANK)
+ integer*8 stride(MAX_RANK)
+ logical canConvert
+ DATATYPE($1, value, (MAX_NELS))
+ doubleprecision expect(MAX_NELS)
+ doubleprecision val
+ integer ud_shift
+
+ nok = 0
+
+ err = nfmpi_open(comm, testfile, NF_NOWRITE, info, ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_open: ', err)
+ do 1, i = 1, numVars
+ canConvert = (var_type(i) .eq. NF_CHAR) .eqv.
+ + (NFT_ITYPE($1) .eq. NFT_TEXT)
+ if (.not.(var_rank(i) .le. MAX_RANK)) stop 'assert'
+ if (.not.(var_nels(i) .le. MAX_NELS)) stop 'assert'
+ do 2, j = 1, var_rank(i)
+ start(j) = 1
+ edge(j) = 1
+ stride(j) = 1
+2 continue
+ err = nfmpi_get_vars_$1_all(BAD_ID, i, start,
+ + edge, stride, value)
+ if (err .ne. NF_EBADID)
+ + call errore('bad ncid: ', err)
+ err = nfmpi_get_vars_$1_all(ncid, BAD_VARID,
+ + start, edge, stride,
+ + value)
+ if (err .ne. NF_ENOTVAR)
+ + call errore('bad var id: ', err)
+ do 3, j = 1, var_rank(i)
+ start(j) = var_shape(j,i) + 1
+ err = nfmpi_get_vars_$1_all(ncid, i, start,
+ + edge, stride,
+ + value)
+ if (.not. canConvert) then
+ if (err .ne. NF_ECHAR)
+ + call errore('conversion: ', err)
+ else
+ if (err .ne. NF_EINVALCOORDS)
+ + call errore('bad index: ', err)
+ endif
+ start(j) = 1
+ edge(j) = var_shape(j,i) + 1
+ err = nfmpi_get_vars_$1_all(ncid, i, start,
+ + edge, stride,
+ + value)
+ if (.not. canConvert) then
+ if (err .ne. NF_ECHAR)
+ + call errore('conversion: ', err)
+ else
+ if (err .ne. NF_EEDGE)
+ + call errore('bad edge: ', err)
+ endif
+ edge(j) = 1
+ stride(j) = 0
+ err = nfmpi_get_vars_$1_all(ncid, i, start,
+ + edge, stride,value)
+ if (.not. canConvert) then
+ if (err .ne. NF_ECHAR)
+ + call errore('conversion: ', err)
+ else
+ if (err .ne. NF_ESTRIDE)
+ + call errore('bad stride: ', err)
+ endif
+ stride(j) = 1
+3 continue
+C Choose a random point dividing each dim into 2 parts
+C get 2^rank (nslabs) slabs so defined
+ nslabs = 1
+ do 4, j = 1, var_rank(i)
+ mid(j) = roll( var_shape(j,i) )
+ nslabs = nslabs * 2
+4 continue
+C bits of k determine whether to get lower or upper part of dim
+C choose random stride from 1 to edge
+ do 5, k = 1, nslabs
+ nstarts = 1
+ do 6, j = 1, var_rank(i)
+ if (mod(ud_shift(k-1, j-1), 2) .eq. 1) then
+ start(j) = 1
+ edge(j) = mid(j)
+ else
+ start(j) = 1 + mid(j)
+ edge(j) = var_shape(j,i) - mid(j)
+ end if
+ if (edge(j) .gt. 0) then
+ sstride(j) = 1 + roll(edge(j))
+ else
+ sstride(j) = 1
+ end if
+ nstarts = nstarts * int(stride(j))
+6 continue
+ do 7, m = 1, nstarts
+ err = index2indexes(m, var_rank(i), sstride,
+ + index)
+ if (err .ne. NF_NOERR)
+ + call error('error in index2indexes')
+ nels = 1
+ do 8, j = 1, var_rank(i)
+ count(j) = 1 + (edge(j) - index(j)) /
+ + stride(j)
+ nels = nels * int(count(j))
+ index(j) = index(j) + start(j) - 1
+8 continue
+C Random choice of forward or backward
+C /* TODO
+C if ( roll(2) ) then
+C for (j = 0 j < var_rank(i) j++) {
+C index(j) += (count(j) - 1) * stride(j)
+C stride(j) = -stride(j)
+C }
+C end if
+C */
+ allInIntRange = .true.
+ allInExtRange = .true.
+ do 9, j = 1, nels
+ err = index2indexes(j, var_rank(i), count,
+ + index2)
+ if (err .ne. NF_NOERR)
+ + call error('error in index2indexes() 1')
+ do 10, d = 1, var_rank(i)
+ index2(d) = index(d) + (index2(d)-1) *
+ + stride(d)
+10 continue
+ expect(j) = hash4(var_type(i), var_rank(i),
+ + index2, NFT_ITYPE($1))
+ if (inRange3(expect(j),var_type(i),
+ + NFT_ITYPE($1))) then
+ allInIntRange =
+ + allInIntRange .and.
+ + in_internal_range(NFT_ITYPE($1),
+ + expect(j))
+ else
+ allInExtRange = .false.
+ end if
+9 continue
+ err = nfmpi_get_vars_$1_all(ncid, i, index,
+ + count, stride,
+ + value)
+ if (canConvert) then
+ if (allInExtRange) then
+ if (allInIntRange) then
+ if (err .ne. NF_NOERR)
+ + call error(nfmpi_strerror(err))
+ else
+ if (err .ne. NF_ERANGE)
+ + call errore('Range error: ', err)
+ end if
+ else
+ if (err .ne. NF_NOERR .and.
+ + err .ne. NF_ERANGE)
+ + call errore('OK or Range error: ', err)
+ end if
+ do 11, j = 1, nels
+ if (inRange3(expect(j),var_type(i),
+ + NFT_ITYPE($1)) .and.
+ + in_internal_range(NFT_ITYPE($1),
+ + expect(j))) then
+ val = ARITH3($1, value, j)
+ if (.not.equal(val, expect(j),
+ + var_type(i), NFT_ITYPE($1))) then
+ call error(
+ + 'value read not that expected')
+ if (verbose) then
+ call error(' ')
+ call errori('varid: ', i)
+ call errorc('var_name: ',
+ + var_name(i))
+ call errori('element number: ',
+ + j)
+ call errord('expect: ',
+ + expect(j))
+ call errord('got: ', val)
+ end if
+ else
+ nok = nok + 1
+ end if
+ end if
+11 continue
+ else
+ if (nels .gt. 0 .and. err .ne. NF_ECHAR)
+ + call errore('wrong type: ', err)
+ end if
+7 continue
+5 continue
+
+1 continue
+ err = nfmpi_close(ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_close: ', err)
+ call print_nok(nok)
+ end
+])dnl
+
+
+dnl TEST_NFMPI_GET_VARM(TYPE)
+dnl
+define([TEST_NFMPI_GET_VARM],dnl
+[dnl
+ subroutine test_nfmpi_get_varm_$1()
+ implicit none
+ include "pnetcdf.inc"
+#include "tests.inc"
+ integer index2indexes, roll
+ double precision hash4
+ logical inRange3, in_internal_range, equal
+
+ integer ncid
+ integer d
+ integer i
+ integer j
+ integer k
+ integer m
+ integer err
+ logical allInExtRange
+ logical allInIntRange
+ integer nels
+ integer nslabs
+ integer nstarts
+ integer nok
+ integer*8 start(MAX_RANK)
+ integer*8 edge(MAX_RANK)
+ integer*8 index(MAX_RANK)
+ integer*8 index2(MAX_RANK)
+ integer*8 mid(MAX_RANK)
+ integer*8 count(MAX_RANK)
+ integer*8 sstride(MAX_RANK)
+ integer*8 stride(MAX_RANK)
+ integer*8 imap(MAX_RANK)
+ logical canConvert
+ DATATYPE($1, value, (MAX_NELS))
+ doubleprecision expect(MAX_NELS)
+ doubleprecision val
+ integer ud_shift
+
+ nok = 0
+
+ err = nfmpi_open(comm, testfile, NF_NOWRITE, info, ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_open: ', err)
+ do 1, i = 1, numVars
+ canConvert = (var_type(i) .eq. NF_CHAR) .eqv.
+ + (NFT_ITYPE($1) .eq. NFT_TEXT)
+ if (.not.(var_rank(i) .le. MAX_RANK)) stop 'assertion'
+ if (.not.(var_nels(i) .le. MAX_NELS)) stop 'assertion'
+ do 2, j = 1, var_rank(i)
+ start(j) = 1
+ edge(j) = 1
+ stride(j) = 1
+ imap(j) = 1
+2 continue
+ err = nfmpi_get_varm_$1_all(BAD_ID, i, start, edge,
+ + stride, imap,
+ + value)
+ if (err .ne. NF_EBADID)
+ + call errore('bad ncid: ', err)
+ err = nfmpi_get_varm_$1_all(ncid, BAD_VARID, start,
+ + edge, stride,
+ + imap, value)
+ if (err .ne. NF_ENOTVAR)
+ + call errore('bad var id: ', err)
+ do 3, j = 1, var_rank(i)
+ start(j) = var_shape(j,i) + 1
+ err = nfmpi_get_varm_$1_all(ncid, i, start,
+ + edge, stride,
+ + imap, value)
+ if (.not. canConvert) then
+ if (err .ne. NF_ECHAR)
+ + call errore('conversion: ', err)
+ else
+ if (err .ne. NF_EINVALCOORDS)
+ + call errore('bad index: ', err)
+ endif
+ start(j) = 1
+ edge(j) = var_shape(j,i) + 1
+ err = nfmpi_get_varm_$1_all(ncid, i, start,
+ + edge, stride,
+ + imap, value)
+ if (.not. canConvert) then
+ if (err .ne. NF_ECHAR)
+ + call errore('conversion: ', err)
+ else
+ if (err .ne. NF_EEDGE)
+ + call errore('bad edge: ', err)
+ endif
+ edge(j) = 1
+ stride(j) = 0
+ err = nfmpi_get_varm_$1_all(ncid, i, start,
+ + edge, stride,
+ + imap, value)
+ if (.not. canConvert) then
+ if (err .ne. NF_ECHAR)
+ + call errore('conversion: ', err)
+ else
+ if (err .ne. NF_ESTRIDE)
+ + call errore('bad stride: ', err)
+ endif
+ stride(j) = 1
+3 continue
+C Choose a random point dividing each dim into 2 parts
+C get 2^rank (nslabs) slabs so defined
+ nslabs = 1
+ do 4, j = 1, var_rank(i)
+ mid(j) = roll( var_shape(j,i) )
+ nslabs = nslabs * 2
+4 continue
+C /* bits of k determine whether to get lower or upper part
+C * of dim
+C * choose random stride from 1 to edge */
+ do 5, k = 1, nslabs
+ nstarts = 1
+ do 6, j = 1, var_rank(i)
+ if (mod(ud_shift((k-1), -(j-1)), 2) .ne. 0) then
+ start(j) = 1
+ edge(j) = mid(j)
+ else
+ start(j) = 1 + mid(j)
+ edge(j) = var_shape(j,i) - mid(j)
+ end if
+ if (edge(j) .gt. 0) then
+ stride(j) = 1+roll(edge(j))
+ else
+ stride(j) = 1
+ end if
+ sstride(j) = stride(j)
+ nstarts = nstarts * int(stride(j))
+6 continue
+ do 7, m = 1, nstarts
+ err = index2indexes(m, var_rank(i), sstride, index)
+ if (err .ne. NF_NOERR)
+ + call error('error in index2indexes')
+ nels = 1
+ do 8, j = 1, var_rank(i)
+ count(j) = 1 + (edge(j) - index(j)) /
+ + stride(j)
+ nels = nels * int(count(j))
+ index(j) = index(j) + start(j) - 1
+8 continue
+C Random choice of forward or backward
+C /* TODO
+C if ( roll(2) ) then
+C for (j = 0 j < var_rank(i) j++) {
+C index(j) += (count(j) - 1) * stride(j)
+C stride(j) = -stride(j)
+C }
+C end if
+C */
+ if (var_rank(i) .gt. 0) then
+ imap(1) = 1
+ do 9, j = 2, var_rank(i)
+ imap(j) = imap(j-1) * count(j-1)
+9 continue
+ end if
+ allInIntRange = .true.
+ allInExtRange = .true.
+ do 10, j = 1, nels
+ err = index2indexes(j, var_rank(i), count,
+ + index2)
+ if (err .ne. NF_NOERR)
+ + call error('error in index2indexes 1')
+ do 11, d = 1, var_rank(i)
+ index2(d) = index(d) + (index2(d)-1) *
+ + stride(d)
+11 continue
+ expect(j) = hash4(var_type(i), var_rank(i),
+ + index2, NFT_ITYPE($1))
+ if (inRange3(expect(j),var_type(i),
+ + NFT_ITYPE($1))) then
+ allInIntRange =
+ + allInIntRange .and.
+ + in_internal_range(NFT_ITYPE($1),
+ + expect(j))
+ else
+ allInExtRange = .false.
+ end if
+10 continue
+ err = nfmpi_get_varm_$1_all(ncid,i,index,count,
+ + stride,imap,value)
+ if (canConvert) then
+ if (allInExtRange) then
+ if (allInIntRange) then
+ if (err .ne. NF_NOERR)
+ + call error(nfmpi_strerror(err))
+ else
+ if (err .ne. NF_ERANGE)
+ + call errore('Range error: ', err)
+ end if
+ else
+ if (err .ne. NF_NOERR .and.
+ + err .ne. NF_ERANGE)
+ + call errore('OK or Range error: ', err)
+ end if
+ do 12, j = 1, nels
+ if (inRange3(expect(j),var_type(i),
+ + NFT_ITYPE($1)) .and.
+ + in_internal_range(NFT_ITYPE($1),
+ + expect(j))) then
+ val = ARITH3($1, value, j)
+ if (.not.equal(val, expect(j),
+ + var_type(i),
+ + NFT_ITYPE($1))) then
+ call error(
+ + 'value read not that expected')
+ if (verbose) then
+ call error(' ')
+ call errori('varid: ', i)
+ call errorc('var_name: ',
+ + var_name(i))
+ call errori('element number: ',
+ + j)
+ call errord('expect: ',
+ + expect(j))
+ call errord('got: ', val)
+ end if
+ else
+ nok = nok + 1
+ end if
+ end if
+12 continue
+ else
+ if (nels .gt. 0 .and. err .ne. NF_ECHAR)
+ + call errore('wrong type: ', err)
+ end if
+7 continue
+5 continue
+1 continue
+ err = nfmpi_close(ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_close: ', err)
+ call print_nok(nok)
+ end
+])dnl
+
+
+dnl TEST_NFMPI_GET_ATT(TYPE)
+dnl
+define([TEST_NFMPI_GET_ATT],dnl
+[dnl
+ subroutine test_nfmpi_get_att_$1()
+ implicit none
+ include "pnetcdf.inc"
+#include "tests.inc"
+ character*2 ATT_NAME
+ integer ATT_TYPE, NATTS, ATT_LEN
+ double precision hash4
+ logical equal, inRange3, in_internal_range
+
+ integer ncid
+ integer i
+ integer j
+ integer k
+ integer err
+ integer*8 ndx(1)
+ logical allInExtRange
+ logical allInIntRange
+ logical canConvert
+ DATATYPE($1, value, (MAX_NELS))
+ doubleprecision expect(MAX_NELS)
+ integer nok
+ doubleprecision val
+
+ nok = 0
+
+ err = nfmpi_open(comm, testfile, NF_NOWRITE, info, ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_open: ', err)
+
+ do 1, i = 0, numVars
+ do 2, j = 1, NATTS(i)
+ canConvert = (ATT_TYPE(j,i) .eq. NF_CHAR) .eqv.
+ + (NFT_ITYPE($1) .eq. NFT_TEXT)
+ err = nfmpi_get_att_$1(BAD_ID, i,
+ + ATT_NAME(j,i),
+ + value)
+ if (err .ne. NF_EBADID)
+ + call errore('bad ncid: ', err)
+ err = nfmpi_get_att_$1(ncid, BAD_VARID,
+ + ATT_NAME(j,i),
+ + value)
+ if (err .ne. NF_ENOTVAR)
+ + call errore('bad var id: ', err)
+ err = nfmpi_get_att_$1(ncid, i,
+ + 'noSuch',
+ + value)
+ if (err .ne. NF_ENOTATT)
+ + call errore('Bad attribute name: ', err)
+ allInIntRange = .true.
+ allInExtRange = .true.
+ do 3, k = 1, ATT_LEN(j,i)
+ ndx(1) = k
+ expect(k) = hash4(ATT_TYPE(j,i), -1, ndx,
+ + NFT_ITYPE($1))
+ if (inRange3(expect(k),ATT_TYPE(j,i),
+ + NFT_ITYPE($1))) then
+ allInIntRange =
+ + allInIntRange .and.
+ + in_internal_range(NFT_ITYPE($1), expect(k))
+ else
+ allInExtRange = .false.
+ end if
+3 continue
+ err = nfmpi_get_att_$1(ncid, i,
+ + ATT_NAME(j,i),
+ + value)
+ if (canConvert .or. ATT_LEN(j,i) .eq. 0) then
+ if (allInExtRange) then
+ if (allInIntRange) then
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_get_att_$1: ',
+ + err)
+ else
+ if (err .ne. NF_ERANGE)
+ + call errore('Range error: ', err)
+ end if
+ else
+ if (err .ne. NF_NOERR .and. err .ne. NF_ERANGE)
+ + call errore('OK or Range error: ',
+ + err)
+ end if
+ do 4, k = 1, ATT_LEN(j,i)
+ if (inRange3(expect(k),ATT_TYPE(j,i),
+ + NFT_ITYPE($1)) .and.
+ + in_internal_range(NFT_ITYPE($1),
+ + expect(k))) then
+ val = ARITH3($1, value, k)
+ if (.not.equal(val, expect(k),
+ + ATT_TYPE(j,i),
+ + NFT_ITYPE($1)))then
+ call error(
+ + 'value read not that expected')
+ if (verbose) then
+ call error(' ')
+ call errori('varid: ', i)
+ call errorc('att_name: ',
+ + ATT_NAME(j,i))
+ call errori('element number: ', k)
+ call errord('expect: ', expect(k))
+ call errord('got: ', val)
+ end if
+ else
+ nok = nok + 1
+ end if
+ end if
+4 continue
+ else
+ if (err .ne. NF_ECHAR)
+ + call errore('wrong type: ', err)
+ end if
+2 continue
+1 continue
+
+ err = nfmpi_close(ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_close: ', err)
+ call print_nok(nok)
+ end
+])dnl
+
+divert(0)dnl
+dnl If you see this line, you can ignore the next one.
+C Do not edit this file. It is produced from the corresponding .m4 source */
+
+C*********************************************************************
+C Copyright 1996, UCAR/Unidata
+C See netcdf/COPYRIGHT file for copying and redistribution conditions.
+C $Id: test_get.m4 2224 2015-12-16 06:10:36Z wkliao $
+C*********************************************************************
+
+TEST_NFMPI_GET_VAR1(text)
+#ifdef NF_INT1_T
+TEST_NFMPI_GET_VAR1(int1)
+#endif
+#ifdef NF_INT2_T
+TEST_NFMPI_GET_VAR1(int2)
+#endif
+TEST_NFMPI_GET_VAR1(int)
+TEST_NFMPI_GET_VAR1(int8)
+TEST_NFMPI_GET_VAR1(real)
+TEST_NFMPI_GET_VAR1(double)
+
+TEST_NFMPI_GET_VAR(text)
+#ifdef NF_INT1_T
+TEST_NFMPI_GET_VAR(int1)
+#endif
+#ifdef NF_INT2_T
+TEST_NFMPI_GET_VAR(int2)
+#endif
+TEST_NFMPI_GET_VAR(int)
+TEST_NFMPI_GET_VAR(int8)
+TEST_NFMPI_GET_VAR(real)
+TEST_NFMPI_GET_VAR(double)
+
+TEST_NFMPI_GET_VARA(text)
+#ifdef NF_INT1_T
+TEST_NFMPI_GET_VARA(int1)
+#endif
+#ifdef NF_INT2_T
+TEST_NFMPI_GET_VARA(int2)
+#endif
+TEST_NFMPI_GET_VARA(int)
+TEST_NFMPI_GET_VARA(int8)
+TEST_NFMPI_GET_VARA(real)
+TEST_NFMPI_GET_VARA(double)
+
+TEST_NFMPI_GET_VARS(text)
+#ifdef NF_INT1_T
+TEST_NFMPI_GET_VARS(int1)
+#endif
+#ifdef NF_INT2_T
+TEST_NFMPI_GET_VARS(int2)
+#endif
+TEST_NFMPI_GET_VARS(int)
+TEST_NFMPI_GET_VARS(int8)
+TEST_NFMPI_GET_VARS(real)
+TEST_NFMPI_GET_VARS(double)
+
+TEST_NFMPI_GET_VARM(text)
+#ifdef NF_INT1_T
+TEST_NFMPI_GET_VARM(int1)
+#endif
+#ifdef NF_INT2_T
+TEST_NFMPI_GET_VARM(int2)
+#endif
+TEST_NFMPI_GET_VARM(int)
+TEST_NFMPI_GET_VARM(int8)
+TEST_NFMPI_GET_VARM(real)
+TEST_NFMPI_GET_VARM(double)
+
+TEST_NFMPI_GET_ATT(text)
+#ifdef NF_INT1_T
+TEST_NFMPI_GET_ATT(int1)
+#endif
+#ifdef NF_INT2_T
+TEST_NFMPI_GET_ATT(int2)
+#endif
+TEST_NFMPI_GET_ATT(int)
+TEST_NFMPI_GET_ATT(int8)
+TEST_NFMPI_GET_ATT(real)
+TEST_NFMPI_GET_ATT(double)
diff --git a/test/nf_test/test_iget.m4 b/test/nf_test/test_iget.m4
new file mode 100644
index 0000000..db913f1
--- /dev/null
+++ b/test/nf_test/test_iget.m4
@@ -0,0 +1,1033 @@
+divert(-1)
+
+dnl This is m4 source.
+dnl Process using m4 to produce FORTRAN language file.
+
+changequote([,])
+
+undefine([index])dnl
+
+dnl Macros
+
+dnl Upcase(str)
+dnl
+define([Upcase],[dnl
+translit($1, abcdefghijklmnopqrstuvwxyz, ABCDEFGHIJKLMNOPQRSTUVWXYZ)])
+
+dnl NFT_ITYPE(type)
+dnl
+define([NFT_ITYPE], [NFT_[]Upcase($1)])
+
+dnl ARITH_VAR1(itype, value)
+dnl
+define([ARITH_VAR1], [ifelse($1, text, ichar($2), $2)])
+
+dnl ARITH3(itype, value)
+dnl
+define([ARITH3], [ifelse($1, text, ichar($2($3:$3)), $2($3))])
+
+dnl DATATYPE(funf_suffix)
+dnl
+define([DATATYPE], [dnl
+ifelse($1, text, character*MAX_NELS $2,
+ifelse($1, int1, NF_INT1_T $2$3,
+ifelse($1, int2, NF_INT2_T $2$3,
+ifelse($1, int, integer $2$3,
+ifelse($1, int8, NF_INT8_T $2$3,
+ifelse($1, real, real $2$3,
+ifelse($1, double, doubleprecision $2$3)[]dnl
+)[]dnl
+)[]dnl
+)[]dnl
+)[]dnl
+)[]dnl
+)[]dnl
+])
+
+dnl DATATYPE_VAR1(funf_suffix)
+dnl
+define([DATATYPE_VAR1], [dnl
+ifelse($1, text, character $2,
+ifelse($1, int1, NF_INT1_T $2,
+ifelse($1, int2, NF_INT2_T $2,
+ifelse($1, int, integer $2,
+ifelse($1, int8, NF_INT8_T $2,
+ifelse($1, real, real $2,
+ifelse($1, double, doubleprecision $2)[]dnl
+)[]dnl
+)[]dnl
+)[]dnl
+)[]dnl
+)[]dnl
+)[]dnl
+])
+
+dnl TEST_NFMPI_IGET_VAR1(TYPE)
+dnl
+define([TEST_NFMPI_IGET_VAR1],[dnl
+ subroutine test_nfmpi_iget_var1_$1()
+ implicit none
+ include "pnetcdf.inc"
+#include "tests.inc"
+ integer index2indexes
+ double precision hash4
+ logical equal, inRange3, in_internal_range
+
+ integer ncid
+ integer i
+ integer j
+ integer err
+ integer nok
+ integer*8 index(MAX_RANK)
+ doubleprecision expect
+ logical canConvert
+ DATATYPE_VAR1($1, value)
+ doubleprecision val
+ integer err_w, reqid(1), st(1)
+
+ nok = 0
+
+ err = nfmpi_open(comm, testfile, NF_NOWRITE, info, ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_open: ', err)
+ do 1, i = 1, numVars
+ canConvert = (var_type(i) .eq. NF_CHAR) .eqv.
+ + (NFT_ITYPE($1) .eq. NFT_TEXT)
+ do 2, j = 1, var_rank(i)
+ index(j) = 1
+2 continue
+ err = nfmpi_iget_var1_$1(BAD_ID,i,index,value,
+ + reqid(1))
+ if (err .ne. NF_EBADID)
+ + call errore('bad ncid: ', err)
+ err = nfmpi_iget_var1_$1(ncid,BAD_VARID,
+ + index, value, reqid(1))
+ if (err .ne. NF_ENOTVAR)
+ + call errore('bad var id: ', err)
+ do 3, j = 1, var_rank(i)
+ index(j) = var_shape(j,i) + 1
+ err = nfmpi_iget_var1_$1(ncid,i,index,value,
+ + reqid(1))
+ if (err .eq. NF_NOERR)
+ + err_w = nfmpi_wait_all(ncid, 1, reqid, st)
+ if (.not. canConvert) then
+ if (err .ne. NF_ECHAR)
+ + call errore('conversion: ', err)
+ else
+ if (err .ne. NF_EINVALCOORDS)
+ + call errore('bad index: ', err)
+ endif
+ index(j) = 1
+3 continue
+ do 4, j = 1, var_nels(i)
+ err = index2indexes(j, var_rank(i), var_shape(1,i),
+ + index)
+ if (err .ne. NF_NOERR)
+ + call error('error in index2indexes 1')
+ expect = hash4( var_type(i), var_rank(i), index,
+ + NFT_ITYPE($1) )
+ err = nfmpi_iget_var1_$1(ncid,i,index,value,
+ + reqid(1))
+ if (err .eq. NF_NOERR)
+ + err_w = nfmpi_wait_all(ncid, 1, reqid, st)
+ if (canConvert) then
+ if (inRange3(expect,var_type(i),
+ + NFT_ITYPE($1))) then
+ if (in_internal_range(NFT_ITYPE($1),
+ + expect)) then
+ if (st(1) .ne. 0) then
+ call errore('nfmpi_iget_var: ',st(1))
+ else
+ val = ARITH_VAR1($1, value)
+ if (.not. equal(val, expect,
+ + var_type(i),
+ + NFT_ITYPE($1))) then
+ call errord('unexpected: ', val)
+ else
+ nok = nok + 1
+ end if
+ end if
+ else
+ if (st(1) .ne. NF_ERANGE)
+ + call errore('Range error: ', st(1))
+ end if
+ else
+ if (st(1) .ne. 0 .and. st(1) .ne. NF_ERANGE)
+ + call errore('OK or Range error: ', st(1))
+ end if
+ else
+ if (err .ne. NF_ECHAR)
+ + call errore('wrong type: ', err)
+ end if
+4 continue
+1 continue
+ err = nfmpi_close(ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_close: ', err)
+ call print_nok(nok)
+ end
+])
+
+dnl TEST_NFMPI_IGET_VAR(TYPE)
+dnl
+define([TEST_NFMPI_IGET_VAR],[dnl
+ subroutine test_nfmpi_iget_var_$1()
+ implicit none
+ include "pnetcdf.inc"
+#include "tests.inc"
+ integer index2indexes
+ double precision hash4
+ logical equal, inRange3, in_internal_range
+
+ integer ncid
+ integer i
+ integer j
+ integer err
+ logical allInExtRange
+ logical allInIntRange
+ integer nels
+ integer nok
+ integer*8 index(MAX_RANK)
+ doubleprecision expect(MAX_NELS)
+ logical canConvert
+ DATATYPE($1, value, (MAX_NELS))
+ doubleprecision val
+ integer err_w, reqid(1), st(1)
+
+ nok = 0
+
+ err = nfmpi_open(comm, testfile, NF_NOWRITE, info, ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_open: ', err)
+ do 1, i = 1, numVars
+ canConvert = (var_type(i) .eq. NF_CHAR) .eqv.
+ + (NFT_ITYPE($1) .eq. NFT_TEXT)
+ err = nfmpi_iget_var_$1(BAD_ID, i, value,reqid(1))
+ if (err .ne. NF_EBADID)
+ + call errore('bad ncid: ', err)
+ err = nfmpi_iget_var_$1(ncid, BAD_VARID, value,reqid(1))
+ if (err .ne. NF_ENOTVAR)
+ + call errore('bad var id: ', err)
+ nels = 1
+ do 3, j = 1, var_rank(i)
+ nels = nels * int(var_shape(j,i))
+3 continue
+ allInExtRange = .true.
+ allInIntRange = .true.
+ do 4, j = 1, var_nels(i)
+ err = index2indexes(j, var_rank(i), var_shape(1,i),
+ + index)
+ if (err .ne. NF_NOERR)
+ + call error('error in index2indexes 1')
+ expect(j) = hash4( var_type(i), var_rank(i), index,
+ + NFT_ITYPE($1) )
+ if (inRange3(expect(j),var_type(i), NFT_ITYPE($1))) then
+ allInIntRange = allInIntRange .and.
+ + in_internal_range(NFT_ITYPE($1), expect(j))
+ else
+ allInExtRange = .false.
+ end if
+4 continue
+ err = nfmpi_iget_var_$1(ncid, i, value,reqid(1))
+ if (err .eq. NF_NOERR)
+ + err_w = nfmpi_wait_all(ncid,1,reqid,st)
+ if (canConvert) then
+ if (allInExtRange) then
+ if (allInIntRange) then
+ if (st(1) .ne. 0)
+ + call errore('nfmpi_iget_var: ', st(1))
+ else
+ if (st(1) .ne. NF_ERANGE)
+ + call errore('Range error: ', st(1))
+ endif
+ else
+ if (st(1) .ne. 0 .and. st(1) .ne. NF_ERANGE)
+ + call errore('Range error: ', st(1))
+ endif
+ do 5, j = 1, var_nels(i)
+ if (inRange3(expect(j),var_type(i),
+ + NFT_ITYPE($1)) .and.
+ + in_internal_range(NFT_ITYPE($1),
+ + expect(j))) then
+ val = ARITH3($1, value, j)
+ if (.not. equal(val, expect(j),
+ + var_type(i),
+ + NFT_ITYPE($1))) then
+ call errord('unexpected: ', val)
+ else
+ nok = nok + 1
+ end if
+ endif
+5 continue
+ else
+ if (err .ne. NF_ECHAR)
+ + call errore('wrong type: ', err)
+ end if
+1 continue
+ err = nfmpi_close(ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_close: ', err)
+ call print_nok(nok)
+ end
+])
+
+
+dnl TEST_NFMPI_IGET_VARA(TYPE)
+dnl
+define([TEST_NFMPI_IGET_VARA],[dnl
+ subroutine test_nfmpi_iget_vara_$1()
+ implicit none
+ include "pnetcdf.inc"
+#include "tests.inc"
+ integer roll, index2indexes
+ double precision hash4
+ logical equal, inRange3, in_internal_range
+
+ integer ncid
+ integer d
+ integer i
+ integer j
+ integer k
+ integer err
+ logical allInExtRange
+ logical allInIntRange
+ integer nels
+ integer nslabs
+ integer nok
+ integer*8 start(MAX_RANK)
+ integer*8 edge(MAX_RANK)
+ integer*8 index(MAX_RANK)
+ integer*8 mid(MAX_RANK)
+ logical canConvert
+ DATATYPE($1, value, (MAX_NELS))
+ doubleprecision expect(MAX_NELS)
+ doubleprecision val
+ integer ud_shift
+ integer err_w, reqid(1), st(1)
+
+ nok = 0
+
+ err = nfmpi_open(comm, testfile, NF_NOWRITE, info, ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_open: ', err)
+ do 1, i = 1, numVars
+ canConvert = (var_type(i) .eq. NF_CHAR) .eqv.
+ + (NFT_ITYPE($1) .eq. NFT_TEXT)
+ if (.not.(var_rank(i) .le. MAX_RANK)) stop 'assert'
+ if (.not.(var_nels(i) .le. MAX_NELS)) stop 'assert'
+ do 2, j = 1, var_rank(i)
+ start(j) = 1
+ edge(j) = 1
+2 continue
+ err = nfmpi_iget_vara_$1(BAD_ID, i, start,
+ + edge, value,reqid(1))
+ if (err .ne. NF_EBADID)
+ + call errore('bad ncid: ', err)
+ err = nfmpi_iget_vara_$1(ncid, BAD_VARID, start,
+ + edge, value,reqid(1))
+ if (err .ne. NF_ENOTVAR)
+ + call errore('bad var id: ', err)
+ do 3, j = 1, var_rank(i)
+ start(j) = var_shape(j,i) + 1
+ err = nfmpi_iget_vara_$1(ncid, i, start,
+ + edge, value,reqid(1))
+ if (canConvert .and. err .ne. NF_EINVALCOORDS)
+ + call errore('bad index: ', err)
+ if (err .EQ. NF_NOERR)
+ + err_w = nfmpi_wait_all(ncid,1,reqid,st)
+ start(j) = 1
+ edge(j) = var_shape(j,i) + 1
+ err = nfmpi_iget_vara_$1(ncid, i, start,
+ + edge, value,reqid(1))
+ if (canConvert .and. err .ne. NF_EEDGE)
+ + call errore('bad edge: ', err)
+ if (err .EQ. NF_NOERR)
+ + err_w = nfmpi_wait_all(ncid,1,reqid,st)
+ edge(j) = 1
+3 continue
+
+C /* Check non-scalars for correct error returned even when */
+C /* there is nothing to get (edge(j).eq.0) */
+ if (var_rank(i) .gt. 0) then
+ do 10, j = 1, var_rank(i)
+ edge(j) = 0
+10 continue
+ err = nfmpi_iget_vara_$1(BAD_ID, i, start,
+ + edge, value,reqid(1))
+ if (err .ne. NF_EBADID)
+ + call errore('bad ncid: ', err)
+ err = nfmpi_iget_vara_$1(ncid, BAD_VARID,
+ + start, edge, value,reqid(1))
+ if (err .ne. NF_ENOTVAR)
+ + call errore('bad var id: ', err)
+ do 11, j = 1, var_rank(i)
+ if (var_dimid(j,i) .gt. 1) then !/* skip record dim */
+ start(j) = var_shape(j,i) + 1
+ err = nfmpi_iget_vara_$1(ncid, i,
+ + start, edge, value,reqid(1))
+ if (canConvert .and. err .ne. NF_EINVALCOORDS)
+ + call errore('bad start: ', err)
+ if (err .EQ. NF_NOERR)
+ + err_w = nfmpi_wait_all(ncid,1,reqid,st)
+ start(j) = 1
+ endif
+11 continue
+ err = nfmpi_iget_vara_$1(ncid, i, start,
+ + edge, value,reqid(1))
+ if (err .EQ. NF_NOERR)
+ + err_w = nfmpi_wait_all(ncid,1,reqid,st)
+ if (canConvert) then
+ if (err .ne. NF_NOERR) then
+ call error(nfmpi_strerror(err))
+ endif
+ else
+ if (err .ne. NF_ECHAR)
+ + call errore('wrong type: ', err)
+ endif
+ do 12, j = 1, var_rank(i)
+ edge(j) = 1
+12 continue
+ endif
+
+C Choose a random point dividing each dim into 2 parts
+C get 2^rank (nslabs) slabs so defined
+ nslabs = 1
+ do 4, j = 1, var_rank(i)
+ mid(j) = roll( var_shape(j,i) )
+ nslabs = nslabs * 2
+4 continue
+C bits of k determine whether to get lower or upper part of dim
+ do 5, k = 1, nslabs
+ nels = 1
+ do 6, j = 1, var_rank(i)
+ if (mod(ud_shift((k-1), -(j-1)), 2) .eq. 1) then
+ start(j) = 1
+ edge(j) = mid(j)
+ else
+ start(j) = 1 + mid(j)
+ edge(j) = var_shape(j,i) - mid(j)
+ end if
+ nels = nels * int(edge(j))
+6 continue
+ allInIntRange = .true.
+ allInExtRange = .true.
+ do 7, j = 1, nels
+ err = index2indexes(j, var_rank(i), edge, index)
+ if (err .ne. NF_NOERR)
+ + call error('error in index2indexes 1')
+ do 8, d = 1, var_rank(i)
+ index(d) = index(d) + start(d) - 1
+8 continue
+ expect(j) = hash4(var_type(i), var_rank(i), index,
+ + NFT_ITYPE($1))
+ if (inRange3(expect(j),var_type(i),
+ + NFT_ITYPE($1))) then
+ allInIntRange =
+ + allInIntRange .and.
+ + in_internal_range(NFT_ITYPE($1), expect(j))
+ else
+ allInExtRange = .false.
+ end if
+7 continue
+ err = nfmpi_iget_vara_$1(ncid, i, start,
+ + edge, value,reqid(1))
+ if (err .EQ. NF_NOERR)
+ + err_w = nfmpi_wait_all(ncid,1,reqid,st)
+ if (canConvert) then
+ if (allInExtRange) then
+ if (allInIntRange) then
+ if (st(1) .ne. 0)
+ + call errore(
+ + 'nfmpi_iget_vara_$1:',st(1))
+ else
+ if (st(1) .ne. NF_ERANGE)
+ + call errore('Range error: ', st(1))
+ end if
+ else
+ if (st(1) .ne. 0 .and. st(1) .ne. NF_ERANGE)
+ + call errore('OK or Range error: ', st(1))
+ end if
+ do 9, j = 1, nels
+ if (inRange3(expect(j),var_type(i),
+ + NFT_ITYPE($1)) .and.
+ + in_internal_range(NFT_ITYPE($1), expect(j)))
+ + then
+ val = ARITH3($1, value, j)
+ if (.not.equal(val,expect(j),
+ + var_type(i),NFT_ITYPE($1)))
+ + then
+ call error(
+ + 'value read not that expected')
+ if (verbose) then
+ call error(' ')
+ call errori('varid: ', i)
+ call errorc('var_name: ',
+ + var_name(i))
+ call errori('element number: %d ',
+ + j)
+ call errord('expect: ', expect(j))
+ call errord('got: ', val)
+ end if
+ else
+ nok = nok + 1
+ end if
+ end if
+9 continue
+ else
+ if (nels .gt. 0 .and. err .ne. NF_ECHAR)
+ + call errore('wrong type: ', err)
+ end if
+5 continue
+1 continue
+ err = nfmpi_close(ncid)
+ if (err .ne. NF_NOERR)
+ + call errorc('nfmpi_close: ', nfmpi_strerror(err))
+ call print_nok(nok)
+ end
+])dnl
+
+
+dnl TEST_NFMPI_IGET_VARS(TYPE)
+dnl
+define([TEST_NFMPI_IGET_VARS],dnl
+[dnl
+ subroutine test_nfmpi_iget_vars_$1()
+ implicit none
+ include "pnetcdf.inc"
+#include "tests.inc"
+ integer roll, index2indexes
+ double precision hash4
+ logical equal, inRange3, in_internal_range
+
+ integer ncid
+ integer d
+ integer i
+ integer j
+ integer k
+ integer m
+ integer err
+ logical allInExtRange
+ logical allInIntRange
+ integer nels
+ integer nslabs
+ integer nstarts
+ integer nok
+ integer*8 start(MAX_RANK)
+ integer*8 edge(MAX_RANK)
+ integer*8 index(MAX_RANK)
+ integer*8 index2(MAX_RANK)
+ integer*8 mid(MAX_RANK)
+ integer*8 count(MAX_RANK)
+ integer*8 sstride(MAX_RANK)
+ integer*8 stride(MAX_RANK)
+ logical canConvert
+ DATATYPE($1, value, (MAX_NELS))
+ doubleprecision expect(MAX_NELS)
+ doubleprecision val
+ integer ud_shift
+ integer err_w, reqid(1), st(1)
+
+ nok = 0
+
+ err = nfmpi_open(comm, testfile, NF_NOWRITE, info, ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_open: ', err)
+ do 1, i = 1, numVars
+ canConvert = (var_type(i) .eq. NF_CHAR) .eqv.
+ + (NFT_ITYPE($1) .eq. NFT_TEXT)
+ if (.not.(var_rank(i) .le. MAX_RANK)) stop 'assert'
+ if (.not.(var_nels(i) .le. MAX_NELS)) stop 'assert'
+ do 2, j = 1, var_rank(i)
+ start(j) = 1
+ edge(j) = 1
+ stride(j) = 1
+2 continue
+ err = nfmpi_iget_vars_$1(BAD_ID, i, start,
+ + edge, stride, value,reqid(1))
+ if (err .ne. NF_EBADID)
+ + call errore('bad ncid: ', err)
+ err = nfmpi_iget_vars_$1(ncid, BAD_VARID,
+ + start, edge, stride, value,reqid(1))
+ if (err .ne. NF_ENOTVAR)
+ + call errore('bad var id: ', err)
+ do 3, j = 1, var_rank(i)
+ start(j) = var_shape(j,i) + 1
+ err = nfmpi_iget_vars_$1(ncid, i, start, edge,
+ + stride,value,reqid(1))
+ if (err .EQ. NF_NOERR)
+ + err_w = nfmpi_wait_all(ncid,1,reqid,st)
+ if (.not. canConvert) then
+ if (err .ne. NF_ECHAR)
+ + call errore('conversion: ', err)
+ else
+ if (err .ne. NF_EINVALCOORDS)
+ + call errore('bad index: ', err)
+ endif
+ start(j) = 1
+ edge(j) = var_shape(j,i) + 1
+ err = nfmpi_iget_vars_$1(ncid, i, start, edge,
+ + stride,value,reqid(1))
+ if (err .EQ. NF_NOERR)
+ + err_w = nfmpi_wait_all(ncid,1,reqid,st)
+ if (.not. canConvert) then
+ if (err .ne. NF_ECHAR)
+ + call errore('conversion: ', err)
+ else
+ if (err .ne. NF_EEDGE)
+ + call errore('bad edge: ', err)
+ endif
+ edge(j) = 1
+ stride(j) = 0
+ err = nfmpi_iget_vars_$1(ncid, i, start, edge,
+ + stride,value,reqid(1))
+ if (err .EQ. NF_NOERR)
+ + err_w = nfmpi_wait_all(ncid,1,reqid,st)
+ if (.not. canConvert) then
+ if (err .ne. NF_ECHAR)
+ + call errore('conversion: ', err)
+ else
+ if (err .ne. NF_ESTRIDE)
+ + call errore('bad stride: ', err)
+ endif
+ stride(j) = 1
+3 continue
+C Choose a random point dividing each dim into 2 parts
+C get 2^rank (nslabs) slabs so defined
+ nslabs = 1
+ do 4, j = 1, var_rank(i)
+ mid(j) = roll( var_shape(j,i) )
+ nslabs = nslabs * 2
+4 continue
+C bits of k determine whether to get lower or upper part of dim
+C choose random stride from 1 to edge
+ do 5, k = 1, nslabs
+ nstarts = 1
+ do 6, j = 1, var_rank(i)
+ if (mod(ud_shift(k-1, j-1), 2) .eq. 1) then
+ start(j) = 1
+ edge(j) = mid(j)
+ else
+ start(j) = 1 + mid(j)
+ edge(j) = var_shape(j,i) - mid(j)
+ end if
+ if (edge(j) .gt. 0) then
+ sstride(j) = 1 + roll(edge(j))
+ else
+ sstride(j) = 1
+ end if
+ nstarts = nstarts * int(stride(j))
+6 continue
+ do 7, m = 1, nstarts
+ err = index2indexes(m, var_rank(i), sstride,
+ + index)
+ if (err .ne. NF_NOERR)
+ + call error('error in index2indexes')
+ nels = 1
+ do 8, j = 1, var_rank(i)
+ count(j) = 1 + (edge(j) - index(j)) /
+ + stride(j)
+ nels = nels * int(count(j))
+ index(j) = index(j) + start(j) - 1
+8 continue
+C Random choice of forward or backward
+C /* TODO
+C if ( roll(2) ) then
+C for (j = 0 j < var_rank(i) j++) {
+C index(j) += (count(j) - 1) * stride(j)
+C stride(j) = -stride(j)
+C }
+C end if
+C */
+ allInIntRange = .true.
+ allInExtRange = .true.
+ do 9, j = 1, nels
+ err = index2indexes(j, var_rank(i), count,
+ + index2)
+ if (err .ne. NF_NOERR)
+ + call error('error in index2indexes() 1')
+ do 10, d = 1, var_rank(i)
+ index2(d) = index(d) + (index2(d)-1) *
+ + stride(d)
+10 continue
+ expect(j) = hash4(var_type(i), var_rank(i),
+ + index2, NFT_ITYPE($1))
+ if (inRange3(expect(j),var_type(i),
+ + NFT_ITYPE($1))) then
+ allInIntRange =
+ + allInIntRange .and.
+ + in_internal_range(NFT_ITYPE($1),
+ + expect(j))
+ else
+ allInExtRange = .false.
+ end if
+9 continue
+ err = nfmpi_iget_vars_$1(ncid, i, index,
+ + count,stride,value,reqid(1))
+ if (err .EQ. NF_NOERR)
+ + err_w = nfmpi_wait_all(ncid,1,reqid,st)
+ if (canConvert) then
+ if (allInExtRange) then
+ if (allInIntRange) then
+ if (st(1) .ne. 0)
+ + call error(nfmpi_strerror(st(1)))
+ else
+ if (st(1) .ne. NF_ERANGE)
+ + call errore('Range error: ', st(1))
+ end if
+ else
+ if (st(1) .ne. 0 .and. st(1) .ne. NF_ERANGE)
+ + call errore('OK or Range error: ',st(1))
+ end if
+ do 11, j = 1, nels
+ if (inRange3(expect(j),var_type(i),
+ + NFT_ITYPE($1)) .and.
+ + in_internal_range(NFT_ITYPE($1),
+ + expect(j))) then
+ val = ARITH3($1, value, j)
+ if (.not.equal(val, expect(j),
+ + var_type(i), NFT_ITYPE($1))) then
+ call error(
+ + 'value read not that expected')
+ if (verbose) then
+ call error(' ')
+ call errori('varid: ', i)
+ call errorc('var_name: ',
+ + var_name(i))
+ call errori('element number: ',
+ + j)
+ call errord('expect: ',
+ + expect(j))
+ call errord('got: ', val)
+ end if
+ else
+ nok = nok + 1
+ end if
+ end if
+11 continue
+ else
+ if (nels .gt. 0 .and. err .ne. NF_ECHAR)
+ + call errore('wrong type: ', err)
+ end if
+7 continue
+5 continue
+
+1 continue
+ err = nfmpi_close(ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_close: ', err)
+ call print_nok(nok)
+ end
+])dnl
+
+
+dnl TEST_NFMPI_IGET_VARM(TYPE)
+dnl
+define([TEST_NFMPI_IGET_VARM],dnl
+[dnl
+ subroutine test_nfmpi_iget_varm_$1()
+ implicit none
+ include "pnetcdf.inc"
+#include "tests.inc"
+ integer roll, index2indexes
+ double precision hash4
+ logical equal, inRange3, in_internal_range
+
+ integer ncid
+ integer d
+ integer i
+ integer j
+ integer k
+ integer m
+ integer err
+ logical allInExtRange
+ logical allInIntRange
+ integer nels
+ integer nslabs
+ integer nstarts
+ integer nok
+ integer*8 start(MAX_RANK)
+ integer*8 edge(MAX_RANK)
+ integer*8 index(MAX_RANK)
+ integer*8 index2(MAX_RANK)
+ integer*8 mid(MAX_RANK)
+ integer*8 count(MAX_RANK)
+ integer*8 sstride(MAX_RANK)
+ integer*8 stride(MAX_RANK)
+ integer*8 imap(MAX_RANK)
+ logical canConvert
+ DATATYPE($1, value, (MAX_NELS))
+ doubleprecision expect(MAX_NELS)
+ doubleprecision val
+ integer ud_shift
+ integer err_w, reqid(1), st(1)
+
+ nok = 0
+
+ err = nfmpi_open(comm, testfile, NF_NOWRITE, info, ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_open: ', err)
+ do 1, i = 1, numVars
+ canConvert = (var_type(i) .eq. NF_CHAR) .eqv.
+ + (NFT_ITYPE($1) .eq. NFT_TEXT)
+ if (.not.(var_rank(i) .le. MAX_RANK)) stop 'assertion'
+ if (.not.(var_nels(i) .le. MAX_NELS)) stop 'assertion'
+ do 2, j = 1, var_rank(i)
+ start(j) = 1
+ edge(j) = 1
+ stride(j) = 1
+ imap(j) = 1
+2 continue
+ err = nfmpi_iget_varm_$1(BAD_ID, i, start, edge,
+ + stride, imap, value,reqid(1))
+ if (err .ne. NF_EBADID)
+ + call errore('bad ncid: ', err)
+ err = nfmpi_iget_varm_$1(ncid, BAD_VARID, start,
+ + edge, stride, imap, value,reqid(1))
+ if (err .ne. NF_ENOTVAR)
+ + call errore('bad var id: ', err)
+ do 3, j = 1, var_rank(i)
+ start(j) = var_shape(j,i) + 1
+ err = nfmpi_iget_varm_$1(ncid, i, start, edge,
+ + stride, imap, value,reqid(1))
+ if (err .EQ. NF_NOERR)
+ + err_w = nfmpi_wait_all(ncid,1,reqid,st)
+ if (.not. canConvert) then
+ if (err .ne. NF_ECHAR)
+ + call errore('conversion: ', err)
+ else
+ if (err .ne. NF_EINVALCOORDS)
+ + call errore('bad index: ', err)
+ endif
+ start(j) = 1
+ edge(j) = var_shape(j,i) + 1
+ err = nfmpi_iget_varm_$1(ncid, i, start, edge,
+ + stride, imap, value,reqid(1))
+ if (err .EQ. NF_NOERR)
+ + err_w = nfmpi_wait_all(ncid,1,reqid,st)
+ if (.not. canConvert) then
+ if (err .ne. NF_ECHAR)
+ + call errore('conversion: ', err)
+ else
+ if (err .ne. NF_EEDGE)
+ + call errore('bad edge: ', err)
+ endif
+ edge(j) = 1
+ stride(j) = 0
+ err = nfmpi_iget_varm_$1(ncid, i, start, edge,
+ + stride, imap, value, reqid(1))
+ if (err .EQ. NF_NOERR)
+ + err_w = nfmpi_wait_all(ncid,1,reqid,st)
+ if (.not. canConvert) then
+ if (err .ne. NF_ECHAR)
+ + call errore('conversion: ', err)
+ else
+ if (err .ne. NF_ESTRIDE)
+ + call errore('bad stride: ', err)
+ endif
+ stride(j) = 1
+3 continue
+C Choose a random point dividing each dim into 2 parts
+C get 2^rank (nslabs) slabs so defined
+ nslabs = 1
+ do 4, j = 1, var_rank(i)
+ mid(j) = roll( var_shape(j,i) )
+ nslabs = nslabs * 2
+4 continue
+C /* bits of k determine whether to get lower or upper part
+C * of dim
+C * choose random stride from 1 to edge */
+ do 5, k = 1, nslabs
+ nstarts = 1
+ do 6, j = 1, var_rank(i)
+ if (mod(ud_shift((k-1), -(j-1)), 2) .ne. 0) then
+ start(j) = 1
+ edge(j) = mid(j)
+ else
+ start(j) = 1 + mid(j)
+ edge(j) = var_shape(j,i) - mid(j)
+ end if
+ if (edge(j) .gt. 0) then
+ stride(j) = 1+roll(edge(j))
+ else
+ stride(j) = 1
+ end if
+ sstride(j) = stride(j)
+ nstarts = nstarts * int(stride(j))
+6 continue
+ do 7, m = 1, nstarts
+ err = index2indexes(m, var_rank(i), sstride, index)
+ if (err .ne. NF_NOERR)
+ + call error('error in index2indexes')
+ nels = 1
+ do 8, j = 1, var_rank(i)
+ count(j) = 1 + (edge(j) - index(j)) /
+ + stride(j)
+ nels = nels * int(count(j))
+ index(j) = index(j) + start(j) - 1
+8 continue
+C Random choice of forward or backward
+C /* TODO
+C if ( roll(2) ) then
+C for (j = 0 j < var_rank(i) j++) {
+C index(j) += (count(j) - 1) * stride(j)
+C stride(j) = -stride(j)
+C }
+C end if
+C */
+ if (var_rank(i) .gt. 0) then
+ imap(1) = 1
+ do 9, j = 2, var_rank(i)
+ imap(j) = imap(j-1) * count(j-1)
+9 continue
+ end if
+ allInIntRange = .true.
+ allInExtRange = .true.
+ do 10, j = 1, nels
+ err = index2indexes(j, var_rank(i), count,
+ + index2)
+ if (err .ne. NF_NOERR)
+ + call error('error in index2indexes 1')
+ do 11, d = 1, var_rank(i)
+ index2(d) = index(d) + (index2(d)-1) *
+ + stride(d)
+11 continue
+ expect(j) = hash4(var_type(i), var_rank(i),
+ + index2, NFT_ITYPE($1))
+ if (inRange3(expect(j),var_type(i),
+ + NFT_ITYPE($1))) then
+ allInIntRange =
+ + allInIntRange .and.
+ + in_internal_range(NFT_ITYPE($1),
+ + expect(j))
+ else
+ allInExtRange = .false.
+ end if
+10 continue
+ err = nfmpi_iget_varm_$1(ncid,i,index,count,
+ + stride,imap, value, reqid(1))
+ if (err .EQ. NF_NOERR)
+ + err_w = nfmpi_wait_all(ncid,1,reqid,st)
+ if (canConvert) then
+ if (allInExtRange) then
+ if (allInIntRange) then
+ if (st(1) .ne. 0)
+ + call error(nfmpi_strerror(st(1)))
+ else
+ if (st(1) .ne. NF_ERANGE)
+ + call errore('Range error: ', st(1))
+ end if
+ else
+ if (st(1) .ne. 0 .and. st(1) .ne. NF_ERANGE)
+ + call errore('OK or Range error: ',st(1))
+ end if
+ do 12, j = 1, nels
+ if (inRange3(expect(j),var_type(i),
+ + NFT_ITYPE($1)) .and.
+ + in_internal_range(NFT_ITYPE($1),
+ + expect(j))) then
+ val = ARITH3($1, value, j)
+ if (.not.equal(val, expect(j),
+ + var_type(i),
+ + NFT_ITYPE($1))) then
+ call error(
+ + 'value read not that expected')
+ if (verbose) then
+ call error(' ')
+ call errori('varid: ', i)
+ call errorc('var_name: ',
+ + var_name(i))
+ call errori('element number: ',
+ + j)
+ call errord('expect: ',
+ + expect(j))
+ call errord('got: ', val)
+ end if
+ else
+ nok = nok + 1
+ end if
+ end if
+12 continue
+ else
+ if (nels .gt. 0 .and. err .ne. NF_ECHAR)
+ + call errore('wrong type: ', err)
+ end if
+7 continue
+5 continue
+1 continue
+ err = nfmpi_close(ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_close: ', err)
+ call print_nok(nok)
+ end
+])dnl
+
+divert(0)dnl
+dnl If you see this line, you can ignore the next one.
+C Do not edit this file. It is produced from the corresponding .m4 source */
+
+C*********************************************************************
+C Copyright 1996, UCAR/Unidata
+C See netcdf/COPYRIGHT file for copying and redistribution conditions.
+C $Id: test_iget.m4 2224 2015-12-16 06:10:36Z wkliao $
+C*********************************************************************
+
+TEST_NFMPI_IGET_VAR1(text)
+#ifdef NF_INT1_T
+TEST_NFMPI_IGET_VAR1(int1)
+#endif
+#ifdef NF_INT2_T
+TEST_NFMPI_IGET_VAR1(int2)
+#endif
+TEST_NFMPI_IGET_VAR1(int)
+TEST_NFMPI_IGET_VAR1(int8)
+TEST_NFMPI_IGET_VAR1(real)
+TEST_NFMPI_IGET_VAR1(double)
+
+TEST_NFMPI_IGET_VAR(text)
+#ifdef NF_INT1_T
+TEST_NFMPI_IGET_VAR(int1)
+#endif
+#ifdef NF_INT2_T
+TEST_NFMPI_IGET_VAR(int2)
+#endif
+TEST_NFMPI_IGET_VAR(int)
+TEST_NFMPI_IGET_VAR(int8)
+TEST_NFMPI_IGET_VAR(real)
+TEST_NFMPI_IGET_VAR(double)
+
+TEST_NFMPI_IGET_VARA(text)
+#ifdef NF_INT1_T
+TEST_NFMPI_IGET_VARA(int1)
+#endif
+#ifdef NF_INT2_T
+TEST_NFMPI_IGET_VARA(int2)
+#endif
+TEST_NFMPI_IGET_VARA(int)
+TEST_NFMPI_IGET_VARA(int8)
+TEST_NFMPI_IGET_VARA(real)
+TEST_NFMPI_IGET_VARA(double)
+
+TEST_NFMPI_IGET_VARS(text)
+#ifdef NF_INT1_T
+TEST_NFMPI_IGET_VARS(int1)
+#endif
+#ifdef NF_INT2_T
+TEST_NFMPI_IGET_VARS(int2)
+#endif
+TEST_NFMPI_IGET_VARS(int)
+TEST_NFMPI_IGET_VARS(int8)
+TEST_NFMPI_IGET_VARS(real)
+TEST_NFMPI_IGET_VARS(double)
+
+TEST_NFMPI_IGET_VARM(text)
+#ifdef NF_INT1_T
+TEST_NFMPI_IGET_VARM(int1)
+#endif
+#ifdef NF_INT2_T
+TEST_NFMPI_IGET_VARM(int2)
+#endif
+TEST_NFMPI_IGET_VARM(int)
+TEST_NFMPI_IGET_VARM(int8)
+TEST_NFMPI_IGET_VARM(real)
+TEST_NFMPI_IGET_VARM(double)
+
diff --git a/test/nf_test/test_iput.m4 b/test/nf_test/test_iput.m4
new file mode 100644
index 0000000..25670af
--- /dev/null
+++ b/test/nf_test/test_iput.m4
@@ -0,0 +1,1108 @@
+divert(-1)
+
+dnl This is m4 source.
+dnl Process using m4 to produce FORTRAN language file.
+
+changequote([,]) dnl
+
+undefine([index])dnl
+
+dnl Macros
+
+dnl Upcase(str)
+dnl
+define([Upcase],[dnl
+translit($1, abcdefghijklmnopqrstuvwxyz, ABCDEFGHIJKLMNOPQRSTUVWXYZ)])
+
+dnl NFT_ITYPE(type)
+dnl
+define([NFT_ITYPE], [NFT_[]Upcase($1)])
+
+dnl ARITH3(itype, value)
+dnl
+define([ARITH3], [ifelse($1, text, ichar($2($3:$3)), $2($3))])
+
+dnl VAR_ELEM(itype, value)
+dnl
+define([VAR_ELEM], [ifelse($1, text, $2($3:$3), $2($3))])
+
+dnl ARITH_VAR1(itype, value)
+dnl
+define([ARITH_VAR1], [ifelse($1, text, ichar($2), $2)])
+
+dnl DATATYPE(funf_suffix)
+dnl
+define([DATATYPE], [dnl
+ifelse($1, text, character*MAX_NELS $2,
+ifelse($1, int1, NF_INT1_T $2$3,
+ifelse($1, int2, NF_INT2_T $2$3,
+ifelse($1, int, integer $2$3,
+ifelse($1, int8, NF_INT8_T $2$3,
+ifelse($1, real, real $2$3,
+ifelse($1, double, doubleprecision $2$3)[]dnl
+)[]dnl
+)[]dnl
+)[]dnl
+)[]dnl
+)[]dnl
+)[]dnl
+])
+
+dnl DATATYPE_VAR1(funf_suffix)
+dnl
+define([DATATYPE_VAR1], [dnl
+ifelse($1, text, character $2,
+ifelse($1, int1, NF_INT1_T $2,
+ifelse($1, int2, NF_INT2_T $2,
+ifelse($1, int, integer $2,
+ifelse($1, int8, NF_INT8_T $2,
+ifelse($1, real, real $2,
+ifelse($1, double, doubleprecision $2)[]dnl
+)[]dnl
+)[]dnl
+)[]dnl
+)[]dnl
+)[]dnl
+)[]dnl
+])
+
+dnl MAKE_ARITH_VAR1(funf_suffix, var)
+dnl
+define([MAKE_ARITH_VAR1], [dnl
+ifelse($1, text, ichar($2), $2)[]dnl
+])
+
+dnl MAKE_ARITH3(funf_suffix, var)
+dnl
+define([MAKE_ARITH3], [dnl
+ifelse($1, text, ichar($2($3:$3)), $2($3))[]dnl
+])
+
+dnl MAKE_DOUBLE(funf_suffix, var)
+dnl
+define([MAKE_DOUBLE], [dnl
+ifelse($1, text, dble(ichar($2)), dble($2))[]dnl
+])
+
+dnl MAKE_TYPE(funf_suffix, var)
+dnl
+define([MAKE_TYPE], [dnl
+ifelse($1, text, char(int($2)),
+ ifelse($1, int, INT($2),
+ ifelse($1, real, REAL($2),
+ ifelse($1, double, DBLE($2),
+ $2))))[]dnl
+])
+
+dnl MAKE_TYPE2(funf_suffix, var_dest, var_src)
+dnl
+define([MAKE_TYPE2], [dnl
+ifelse($1, text, $2 = char(int($3)),
+ ifelse($1, int, $2 = INT($3),
+ ifelse($1, int8,
+ if ($3 .EQ. X_INT8_MAX) then
+ $2 = X_INT8_MAX
+ else
+ $2 = $3
+ endif,
+ ifelse($1, real, $2 = REAL($3),
+ ifelse($1, double, $2 = DBLE($3),
+ $2 = $3)))))[]dnl
+])
+
+dnl TEST_NFMPI_IPUT_VAR1(TYPE)
+dnl
+define([TEST_NFMPI_IPUT_VAR1],dnl
+[dnl
+ subroutine test_nfmpi_iput_var1_$1()
+ implicit none
+ include "pnetcdf.inc"
+#include "tests.inc"
+ integer index2indexes
+ double precision hash_$1
+ logical inRange3
+
+ integer ncid
+ integer i
+ integer j
+ integer err, flags
+ integer*8 index(MAX_RANK)
+ logical canConvert !/* Both text or both numeric */
+ DATATYPE_VAR1($1, value)
+ doubleprecision val
+ integer err_w, reqid(1), st(1)
+
+ value = MAKE_TYPE($1, 5)!/* any value would do - only for error cases */
+
+ flags = IOR(NF_NOCLOBBER, extra_flags)
+ err = nfmpi_create(comm, scratch, flags, info, ncid)
+ if (err .ne. NF_NOERR) then
+ call errore('nfmpi_create: ', err)
+ return
+ end if
+ call def_dims(ncid)
+ call def_vars(ncid)
+ err = nfmpi_enddef(ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_enddef: ', err)
+ do 1, i = 1, numVars
+ canConvert = (var_type(i) .eq. NF_CHAR) .eqv.
+ + (NFT_ITYPE($1) .eq. NFT_TEXT)
+ do 2, j = 1, var_rank(i)
+ index(j) = 1
+2 continue
+ err = nfmpi_iput_var1_$1(BAD_ID, i, index, value,
+ + reqid(1))
+ if (err .ne. NF_EBADID)
+ + call errore('bad ncid: ', err)
+ err = nfmpi_iput_var1_$1(ncid, BAD_VARID,
+ + index, value,reqid(1))
+ if (err .ne. NF_ENOTVAR)
+ + call errore('bad var id: ', err)
+ do 3, j = 1, var_rank(i)
+ if (var_dimid(j,i) .gt. 1) then !/* skip record dim */
+ index(j) = var_shape(j,i) + 1
+ err = nfmpi_iput_var1_$1(ncid, i,
+ + index, value,reqid(1))
+ if (err .eq. NF_NOERR .or. err .eq. NF_ERANGE)
+ + err_w = nfmpi_wait_all(ncid,1,reqid,st)
+ if (.not. canConvert) then
+ if (err .ne. NF_ECHAR)
+ + call errore('conversion: ', err)
+ else
+ if (err .ne. NF_EINVALCOORDS)
+ + call errore('bad index: ', err)
+ endif
+ index(j) = 0
+ end if
+3 continue
+ do 4, j = 1, var_nels(i)
+ err = index2indexes(j, var_rank(i), var_shape(1,i),
+ + index)
+ if (err .ne. NF_NOERR)
+ + call error('error in index2indexes 1')
+ val = hash_$1(var_type(i),var_rank(i),
+ + index, NFT_ITYPE($1))
+ MAKE_TYPE2($1, value, val)
+ err = nfmpi_iput_var1_$1(ncid, i, index, value,
+ + reqid(1))
+ if (err .eq. NF_NOERR .or. err .eq. NF_ERANGE)
+ + err_w = nfmpi_wait_all(ncid,1,reqid,st)
+ if (canConvert) then
+ val = ARITH_VAR1($1, value)
+ if (inRange3(val, var_type(i), NFT_ITYPE($1))) then
+ if (st(1) .ne. 0)
+ + call error(nfmpi_strerror(st(1)))
+ else
+ if (err .ne. NF_ERANGE)
+ + call errore('Range error: ', err)
+ err = nfmpi_cancel(ncid, 1, reqid,st)
+ end if
+ else
+ if (err .ne. NF_ECHAR)
+ + call errore('wrong type: ', err)
+ end if
+4 continue
+1 continue
+ err = nfmpi_close(ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_close: ', err)
+
+ call check_vars_$1(scratch)
+
+ err = nfmpi_delete(scratch, info)
+ if (err .ne. NF_NOERR)
+ + call errorc('delete of scratch file failed: ',
+ + scratch)
+ end
+])dnl
+
+
+dnl TEST_NFMPI_IPUT_VAR(TYPE)
+dnl
+define([TEST_NFMPI_IPUT_VAR],dnl
+[dnl
+ subroutine test_nfmpi_iput_var_$1()
+ implicit none
+ include "pnetcdf.inc"
+#include "tests.inc"
+ integer index2indexes
+ double precision hash_$1
+ logical inRange3
+
+ integer ncid
+ integer vid
+ integer i
+ integer j
+ integer err, flags
+ integer nels
+ integer*8 index(MAX_RANK)
+ logical canConvert !/* Both text or both numeric */
+ logical allInExtRange !/* All values within external range?*/
+ DATATYPE($1, value, (MAX_NELS))
+ doubleprecision val
+ integer err_w, reqid(1), st(1)
+
+ flags = IOR(NF_CLOBBER, extra_flags)
+ err = nfmpi_create(comm, scratch, flags, info, ncid)
+ if (err .ne. NF_NOERR) then
+ call errore('nfmpi_create: ', err)
+ return
+ end if
+ call def_dims(ncid)
+ call def_vars(ncid)
+ err = nfmpi_enddef(ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_enddef: ', err)
+ do 1, i = 1, numVars
+ canConvert = (var_type(i) .eq. NF_CHAR) .eqv.
+ + (NFT_ITYPE($1) .eq. NFT_TEXT)
+ err = nfmpi_iput_var_$1(BAD_ID, i, value,reqid(1))
+ if (err .ne. NF_EBADID)
+ + call errore('bad ncid: ', err)
+ err = nfmpi_iput_var_$1(ncid, BAD_VARID, value,
+ + reqid(1))
+ if (err .ne. NF_ENOTVAR)
+ + call errore('bad var id: ', err)
+ nels = 1
+ do 3, j = 1, var_rank(i)
+ nels = nels * int(var_shape(j,i))
+3 continue
+ allInExtRange = .true.
+ do 4, j = 1, var_nels(i)
+ err = index2indexes(j, var_rank(i), var_shape(1,i),
+ + index)
+ if (err .ne. NF_NOERR)
+ + call error('error in index2indexes 1')
+ val = hash_$1(var_type(i), var_rank(i),
+ + index, NFT_ITYPE($1))
+ MAKE_TYPE2($1, VAR_ELEM($1, value, j), val)
+ val = ARITH3($1, value, j)
+ allInExtRange = allInExtRange .and.
+ + inRange3(val, var_type(i), NFT_ITYPE($1))
+4 continue
+ err = nfmpi_iput_var_$1(ncid, i, value,reqid(1))
+ if (err .eq. NF_NOERR .or. err .eq. NF_ERANGE)
+ + err_w = nfmpi_wait_all(ncid, 1, reqid, st)
+ ! NF_ERANGE is not a fatal error
+
+ if (canConvert) then
+ if (allInExtRange) then
+ if (err .ne. NF_NOERR)
+ + call error(nfmpi_strerror(err))
+ else
+ if (err .ne. NF_ERANGE .and.
+ + var_dimid(var_rank(i),i) .ne. RECDIM)
+ + call errore('Range error: ', err)
+ endif
+ else
+ if (err .ne. NF_ECHAR)
+ + call errore('wrong type: ', err)
+ endif
+1 continue
+
+C The preceeding has written nothing for record variables, now try
+C again with more than 0 records.
+
+C Write record number NRECS to force writing of preceding records.
+C Assumes variable cr is char vector with UNLIMITED dimension.
+
+ err = nfmpi_inq_varid(ncid, "cr", vid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_inq_varid: ', err)
+ index(1) = NRECS
+ err = nfmpi_iput_var1_text(ncid, vid, index, 'x',reqid(1))
+ if (err .ne. NF_NOERR) then
+ call errore('nfmpi_iput_var1_text: ', err)
+ else
+ err_w = nfmpi_wait_all(ncid, 1, reqid, st)
+ endif
+
+ do 5 i = 1, numVars
+C Only test record variables here
+ if (var_rank(i) .ge. 1 .and.
+ + var_dimid(var_rank(i),i) .eq. RECDIM) then
+ canConvert = (var_type(i) .eq. NF_CHAR) .eqv.
+ + (NFT_ITYPE($1) .eq. NFT_TEXT)
+ if (var_rank(i) .gt. MAX_RANK)
+ + stop 'var_rank(i) .gt. MAX_RANK'
+ if (var_nels(i) .gt. MAX_NELS)
+ + stop 'var_nels(i) .gt. MAX_NELS'
+
+ nels = 1
+ do 6 j = 1, var_rank(i)
+ nels = nels * int(var_shape(j,i))
+6 continue
+ allInExtRange = .true.
+ do 7, j = 1, nels
+ err = index2indexes(j, var_rank(i), var_shape(1,i),
+ + index)
+ if (err .ne. NF_NOERR)
+ + call error('error in index2indexes()')
+ val = hash_$1(var_type(i), var_rank(i),
+ + index, NFT_ITYPE($1))
+ MAKE_TYPE2($1, VAR_ELEM($1, value, j), val)
+ val = ARITH3($1, value, j)
+ allInExtRange = allInExtRange .and.
+ + inRange3(val, var_type(i), NFT_ITYPE($1))
+7 continue
+ err = nfmpi_iput_var_$1(ncid, i, value,reqid(1))
+ if (err .eq. NF_NOERR .or. err .eq. NF_ERANGE)
+ + err_w = nfmpi_wait_all(ncid, 1, reqid, st)
+ ! NF_ERANGE is not a fatal error?
+ if (canConvert) then
+ if (allInExtRange) then
+ if (err .ne. NF_NOERR)
+ + call error(nfmpi_strerror(err))
+ else
+ if (err .ne. NF_ERANGE)
+ + call errore('range error: ', err)
+ endif
+ else
+ if (nels .gt. 0 .and. err .ne. NF_ECHAR)
+ + call errore('wrong type: ', err)
+ endif
+ endif
+5 continue
+ err = nfmpi_close(ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_close: ', err)
+
+ call check_vars_$1(scratch)
+
+ err = nfmpi_delete(scratch, info)
+ if (err .ne. NF_NOERR)
+ + call errorc('delete of scratch file failed: ',
+ + scratch)
+ end
+])dnl
+
+
+dnl TEST_NFMPI_IPUT_VARA(TYPE)
+dnl
+define([TEST_NFMPI_IPUT_VARA],dnl
+[dnl
+ subroutine test_nfmpi_iput_vara_$1()
+ implicit none
+ include "pnetcdf.inc"
+#include "tests.inc"
+ integer index2indexes, roll
+ double precision hash_$1
+ logical inRange3
+
+ integer ncid
+ integer i
+ integer j
+ integer k
+ integer d
+ integer err, flags
+ integer nslabs
+ integer nels
+ integer*8 start(MAX_RANK)
+ integer*8 edge(MAX_RANK)
+ integer*8 mid(MAX_RANK)
+ integer*8 index(MAX_RANK)
+ logical canConvert !/* Both text or both numeric */
+ logical allInExtRange !/* all values within external range? */
+ DATATYPE($1, value, (MAX_NELS))
+ doubleprecision val
+ integer ud_shift
+ integer err_w, reqid(1), st(1)
+
+ flags = IOR(NF_CLOBBER, extra_flags)
+ err = nfmpi_create(comm, scratch, flags, info, ncid)
+ if (err .ne. NF_NOERR) then
+ call errore('nfmpi_create: ', err)
+ return
+ end if
+ call def_dims(ncid)
+ call def_vars(ncid)
+ err = nfmpi_enddef(ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_enddef: ', err)
+
+ do 1, i = 1, numVars
+ canConvert = (var_type(i) .eq. NF_CHAR) .eqv.
+ + (NFT_ITYPE($1) .eq. NFT_TEXT)
+ if (.not.(var_rank(i) .le. MAX_RANK))
+ + stop 'assert(var_rank(i) .le. MAX_RANK)'
+ if (.not.(var_nels(i) .le. MAX_NELS))
+ + stop 'assert(var_nels(i) .le. MAX_NELS)'
+ do 2, j = 1, var_rank(i)
+ start(j) = 1
+ edge(j) = 1
+2 continue
+ err = nfmpi_iput_vara_$1(BAD_ID, i, start,
+ + edge, value,reqid(1))
+ if (err .ne. NF_EBADID)
+ + call errore('bad ncid: ', err)
+ err = nfmpi_iput_vara_$1(ncid, BAD_VARID,
+ + start, edge, value,reqid(1))
+ if (err .ne. NF_ENOTVAR)
+ + call errore('bad var id: ', err)
+ do 3, j = 1, var_rank(i)
+ if (var_dimid(j,i) .ne. RECDIM) then !/* skip record dim */
+ start(j) = var_shape(j,i) + 1
+ err = nfmpi_iput_vara_$1(ncid, i, start,
+ + edge, value,reqid(1))
+ if (err .eq. NF_NOERR .or. err .eq. NF_ERANGE)
+ + err_w = nfmpi_wait_all(ncid, 1, reqid, st)
+ ! NF_ERANGE is not a fatal error
+ if (.not. canConvert) then
+ if (err .ne. NF_ECHAR)
+ + call errore('conversion: ', err)
+ else
+ if (err .ne. NF_EINVALCOORDS)
+ + call errore('bad start: ', err)
+ endif
+ start(j) = 1
+ edge(j) = var_shape(j,i) + 1
+ err = nfmpi_iput_vara_$1(ncid, i, start,
+ + edge, value,reqid(1))
+ if (err .eq. NF_NOERR .or. err .eq. NF_ERANGE)
+ + err_w = nfmpi_wait_all(ncid, 1, reqid, st)
+ ! NF_ERANGE is not a fatal error
+ if (.not. canConvert) then
+ if (err .ne. NF_ECHAR)
+ + call errore('conversion: ', err)
+ else
+ if (err .ne. NF_EEDGE)
+ + call errore('bad edge: ', err)
+ endif
+ edge(j) = 1
+ end if
+3 continue
+
+C /* Check correct error returned even when nothing to put */
+ do 20, j = 1, var_rank(i)
+ edge(j) = 0
+20 continue
+ err = nfmpi_iput_vara_$1(BAD_ID, i, start,
+ + edge, value,reqid(1))
+ if (err .ne. NF_EBADID)
+ + call errore('bad ncid: ', err)
+ err = nfmpi_iput_vara_$1(ncid, BAD_VARID,
+ + start, edge, value,reqid(1))
+ if (err .ne. NF_ENOTVAR)
+ + call errore('bad var id: ', err)
+ do 21, j = 1, var_rank(i)
+ if (var_dimid(j,i) .gt. 1) then ! skip record dim
+ start(j) = var_shape(j,i) + 1
+ err = nfmpi_iput_vara_$1(ncid, i, start,
+ + edge, value,reqid(1))
+ if (err .eq. NF_NOERR .or. err .eq. NF_ERANGE)
+ + err_w = nfmpi_wait_all(ncid, 1, reqid, st)
+ ! NF_ERANGE is not a fatal error
+ if (.not. canConvert) then
+ if (err .ne. NF_ECHAR)
+ + call errore('conversion: ', err)
+ else
+ if (err .ne. NF_EINVALCOORDS)
+ + call errore('bad start: ', err)
+ endif
+ start(j) = 1
+ endif
+21 continue
+ err = nfmpi_iput_vara_$1(ncid, i, start, edge, value,
+ + reqid(1))
+ if (err .eq. NF_NOERR .or. err .eq. NF_ERANGE)
+ + err_w = nfmpi_wait_all(ncid, 1, reqid, st)
+ ! NF_ERANGE is not a fatal error
+ if (canConvert) then
+ if (st(1) .ne. 0)
+ + call error(nfmpi_strerror(st(1)))
+ else
+ if (err .ne. NF_ECHAR)
+ + call errore('wrong type: ', err)
+ endif
+ do 22, j = 1, var_rank(i)
+ edge(j) = 1
+22 continue
+
+
+ !/* Choose a random point dividing each dim into 2 parts */
+ !/* Put 2^rank (nslabs) slabs so defined */
+ nslabs = 1
+ do 4, j = 1, var_rank(i)
+ mid(j) = roll( var_shape(j,i) )
+ nslabs = nslabs * 2
+4 continue
+ !/* bits of k determine whether to put lower or upper part of dim */
+ do 5, k = 1, nslabs
+ nels = 1
+ do 6, j = 1, var_rank(i)
+ if (mod(ud_shift(k-1, -(j-1)), 2) .eq. 1) then
+ start(j) = 1
+ edge(j) = mid(j)
+ else
+ start(j) = 1 + mid(j)
+ edge(j) = var_shape(j,i) - mid(j)
+ end if
+ nels = nels * int(edge(j))
+6 continue
+ allInExtRange = .true.
+ do 7, j = 1, nels
+ err = index2indexes(j, var_rank(i), edge, index)
+ if (err .ne. NF_NOERR)
+ + call error('error in index2indexes 1')
+ do 8, d = 1, var_rank(i)
+ index(d) = index(d) + start(d) - 1
+8 continue
+ val = hash_$1(var_type(i), var_rank(i),
+ + index, NFT_ITYPE($1))
+ MAKE_TYPE2($1, VAR_ELEM($1, value, j), val)
+ val = ARITH3($1, value, j)
+ allInExtRange = allInExtRange .and.
+ + inRange3(val, var_type(i), NFT_ITYPE($1))
+7 continue
+ err = nfmpi_iput_vara_$1(ncid, i, start,
+ + edge, value,reqid(1))
+ if (err .eq. NF_NOERR .or. err .eq. NF_ERANGE)
+ + err_w = nfmpi_wait_all(ncid,1,reqid,st)
+ ! NF_ERANGE is not a fatal error?
+ if (canConvert) then
+ if (allInExtRange) then
+ if (st(1) .ne. 0)
+ + call error(nfmpi_strerror(st(1)))
+ else
+ if (err .ne. NF_ERANGE)
+ + call errore('range error: ', err)
+ end if
+ else
+ if (nels .gt. 0 .and. err .ne. NF_ECHAR)
+ + call errore('wrong type: ', err)
+ end if
+5 continue
+1 continue
+
+ err = nfmpi_close(ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_close: ', err)
+
+ call check_vars_$1(scratch)
+
+ err = nfmpi_delete(scratch, info)
+ if (err .ne. NF_NOERR)
+ + call errorc('delete of scratch file failed: ',
+ + scratch)
+ end
+])dnl
+
+
+dnl TEST_NFMPI_IPUT_VARS(TYPE)
+dnl
+define([TEST_NFMPI_IPUT_VARS],dnl
+[dnl
+ subroutine test_nfmpi_iput_vars_$1()
+ implicit none
+ include "pnetcdf.inc"
+#include "tests.inc"
+ integer index2indexes, roll
+ double precision hash_$1
+ logical inRange3
+
+ integer ncid
+ integer d
+ integer i
+ integer j
+ integer k
+ integer m
+ integer err, flags
+ integer nels
+ integer nslabs
+ integer nstarts !/* number of different starts */
+ integer*8 start(MAX_RANK)
+ integer*8 edge(MAX_RANK)
+ integer*8 index(MAX_RANK)
+ integer*8 index2(MAX_RANK)
+ integer*8 mid(MAX_RANK)
+ integer*8 count(MAX_RANK)
+ integer*8 sstride(MAX_RANK)
+ integer*8 stride(MAX_RANK)
+ logical canConvert !/* Both text or both numeric */
+ logical allInExtRange !/* all values within external range? */
+ DATATYPE($1, value, (MAX_NELS))
+ doubleprecision val
+ integer ud_shift
+ integer err_w, reqid(1), st(1)
+
+ flags = IOR(NF_CLOBBER, extra_flags)
+ err = nfmpi_create(comm, scratch, flags, info, ncid)
+ if (err .ne. NF_NOERR) then
+ call errore('nfmpi_create: ', err)
+ return
+ end if
+ call def_dims(ncid)
+ call def_vars(ncid)
+ err = nfmpi_enddef(ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_enddef: ', err)
+
+ do 1, i = 1, numVars
+ canConvert = (var_type(i) .eq. NF_CHAR) .eqv.
+ + (NFT_ITYPE($1) .eq. NFT_TEXT)
+ if (.not.(var_rank(i) .le. MAX_RANK))
+ + stop 'assert(var_rank(i) .le. MAX_RANK)'
+ if (.not.(var_nels(i) .le. MAX_NELS))
+ + stop 'assert(var_nels(i) .le. MAX_NELS)'
+ do 2, j = 1, var_rank(i)
+ start(j) = 1
+ edge(j) = 1
+ stride(j) = 1
+2 continue
+ err = nfmpi_iput_vars_$1(BAD_ID, i, start,
+ + edge, stride, value,reqid(1))
+ if (err .ne. NF_EBADID)
+ + call errore('bad ncid: ', err)
+ err = nfmpi_iput_vars_$1(ncid, BAD_VARID, start,
+ + edge, stride,
+ + value,reqid(1))
+ if (err .ne. NF_ENOTVAR)
+ + call errore('bad var id: ', err)
+ do 3, j = 1, var_rank(i)
+ if (var_dimid(j,i) .ne. RECDIM) then ! skip record dim
+ start(j) = var_shape(j,i) + 1
+ err = nfmpi_iput_vars_$1(ncid, i, start,
+ + edge, stride,
+ + value,reqid(1))
+ if (err .eq. NF_NOERR .or. err .eq. NF_ERANGE)
+ + err_w = nfmpi_wait_all(ncid,1,reqid,st)
+ ! NF_ERANGE is not a fatal error?
+ if (.not. canConvert) then
+ if (err .ne. NF_ECHAR)
+ + call errore('conversion: ', err)
+ else
+ if (err .ne. NF_EINVALCOORDS)
+ + call errore('bad start: ', err)
+ endif
+ start(j) = 1
+ edge(j) = var_shape(j,i) + 1
+ err = nfmpi_iput_vars_$1(ncid, i, start,
+ + edge, stride,
+ + value,reqid(1))
+ if (err .eq. NF_NOERR .or. err .eq. NF_ERANGE)
+ + err_w = nfmpi_wait_all(ncid,1,reqid,st)
+ ! NF_ERANGE is not a fatal error?
+ if (.not. canConvert) then
+ if (err .ne. NF_ECHAR)
+ + call errore('conversion: ', err)
+ else
+ if (err .ne. NF_EEDGE)
+ + call errore('bad edge: ', err)
+ endif
+ edge(j) = 1
+ stride(j) = 0
+ err = nfmpi_iput_vars_$1(ncid, i, start,
+ + edge, stride,
+ + value,reqid(1))
+ if (err .eq. NF_NOERR .or. err .eq. NF_ERANGE)
+ + err_w = nfmpi_wait_all(ncid,1,reqid,st)
+ ! NF_ERANGE is not a fatal error?
+ if (.not. canConvert) then
+ if (err .ne. NF_ECHAR)
+ + call errore('conversion: ', err)
+ else
+ if (err .ne. NF_ESTRIDE)
+ + call errore('bad stride: ', err)
+ endif
+ stride(j) = 1
+ end if
+3 continue
+ !/* Choose a random point dividing each dim into 2 parts */
+ !/* Put 2^rank (nslabs) slabs so defined */
+ nslabs = 1
+ do 4, j = 1, var_rank(i)
+ mid(j) = roll( var_shape(j,i) )
+ nslabs = nslabs * 2
+4 continue
+ !/* bits of k determine whether to put lower or upper part of dim */
+ !/* choose random stride from 1 to edge */
+ do 5, k = 1, nslabs
+ nstarts = 1
+ do 6, j = 1, var_rank(i)
+ if (mod(ud_shift(k-1, -(j-1)), 2) .eq. 1) then
+ start(j) = 1
+ edge(j) = mid(j)
+ else
+ start(j) = 1 + mid(j)
+ edge(j) = var_shape(j,i) - mid(j)
+ end if
+ if (edge(j) .gt. 0) then
+ stride(j) = 1+roll(edge(j))
+ else
+ stride(j) = 1
+ end if
+ sstride(j) = stride(j)
+ nstarts = nstarts * int(stride(j))
+6 continue
+ do 7, m = 1, nstarts
+ err = index2indexes(m, var_rank(i), sstride, index)
+ if (err .ne. NF_NOERR)
+ + call error('error in index2indexes')
+ nels = 1
+ do 8, j = 1, var_rank(i)
+ count(j) = 1 + (edge(j) - index(j)) / stride(j)
+ nels = nels * int(count(j))
+ index(j) = index(j) + start(j) - 1
+8 continue
+ !/* Random choice of forward or backward */
+C/* TODO
+C if ( roll(2) ) {
+C for (j = 1 j .lt. var_rank(i) j++) {
+C index(j) += (count(j) - 1) * stride(j)
+C stride(j) = -stride(j)
+C }
+C }
+C*/
+ allInExtRange = .true.
+ do 9, j = 1, nels
+ err = index2indexes(j, var_rank(i), count,
+ + index2)
+ if (err .ne. NF_NOERR)
+ + call error('error in index2indexes')
+ do 10, d = 1, var_rank(i)
+ index2(d) = index(d) +
+ + (index2(d)-1) * stride(d)
+10 continue
+ val = hash_$1(var_type(i), var_rank(i),
+ + index2, NFT_ITYPE($1))
+ MAKE_TYPE2($1, VAR_ELEM($1, value, j), val)
+ val = ARITH3($1, value, j)
+ allInExtRange = allInExtRange .and.
+ + inRange3(val, var_type(i),
+ + NFT_ITYPE($1))
+9 continue
+ err = nfmpi_iput_vars_$1(ncid, i, index,
+ + count, stride,
+ + value,reqid(1))
+ if (err .eq. NF_NOERR .or. err .eq. NF_ERANGE)
+ + err_w = nfmpi_wait_all(ncid,1,reqid,st)
+ if (canConvert) then
+ if (allInExtRange) then
+ if (st(1) .ne. 0)
+ + call error(nfmpi_strerror(st(1)))
+ else
+ if (err .ne. NF_ERANGE)
+ + call errore('range error: ', err)
+ end if
+ else
+ if (nels .gt. 0 .and. err .ne. NF_ECHAR)
+ + call errore('wrong type: ', err)
+ end if
+7 continue
+5 continue
+1 continue
+
+ err = nfmpi_close(ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_close: ', err)
+
+ call check_vars_$1(scratch)
+
+ err = nfmpi_delete(scratch, info)
+ if (err .ne. NF_NOERR)
+ + call errorc('delete of scratch file failed:',
+ + scratch)
+ end
+])dnl
+
+
+dnl since parallel-netcdf doesn't have varm type, we haven't completed the
+dnl parallel-netcdf-ification of these routines
+dnl TEST_NFMPI_IPUT_VARM(TYPE)
+dnl
+define([TEST_NFMPI_IPUT_VARM],dnl
+[dnl
+ subroutine test_nfmpi_iput_varm_$1()
+ implicit none
+ include "pnetcdf.inc"
+#include "tests.inc"
+ integer index2indexes, roll
+ double precision hash_$1
+ logical inRange3
+
+ integer ncid
+ integer d
+ integer i
+ integer j
+ integer k
+ integer m
+ integer err, flags
+ integer nels
+ integer nslabs
+ integer nstarts !/* number of different starts */
+ integer*8 start(MAX_RANK)
+ integer*8 edge(MAX_RANK)
+ integer*8 index(MAX_RANK)
+ integer*8 index2(MAX_RANK)
+ integer*8 mid(MAX_RANK)
+ integer*8 count(MAX_RANK)
+ integer*8 sstride(MAX_RANK)
+ integer*8 stride(MAX_RANK)
+ integer*8 imap(MAX_RANK)
+ logical canConvert !/* Both text or both numeric */
+ logical allInExtRange !/* all values within external range? */
+ DATATYPE($1, value, (MAX_NELS))
+ doubleprecision val
+ integer ud_shift
+ integer err_w, reqid(1), st(1)
+
+ flags = IOR(NF_NOCLOBBER, extra_flags)
+ err = nfmpi_create(comm, scratch, flags, info, ncid)
+ if (err .ne. NF_NOERR) then
+ call errore('nfmpi_create: ', err)
+ return
+ end if
+ call def_dims(ncid)
+ call def_vars(ncid)
+ err = nfmpi_enddef(ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_enddef: ', err)
+
+ do 1, i = 1, numVars
+ canConvert = (var_type(i) .eq. NF_CHAR) .eqv.
+ + (NFT_ITYPE($1) .eq. NFT_TEXT)
+ if (.not.(var_rank(i) .le. MAX_RANK))
+ + stop 'assert(var_rank(i) .le. MAX_RANK)'
+ if (.not.(var_nels(i) .le. MAX_NELS))
+ + stop 'assert(var_nels(i) .le. MAX_NELS)'
+ do 2, j = 1, var_rank(i)
+ start(j) = 1
+ edge(j) = 1
+ stride(j) = 1
+ imap(j) = 1
+2 continue
+ err = nfmpi_iput_varm_$1(BAD_ID, i, start,
+ + edge, stride, imap,
+ + value,reqid(1))
+ if (err .ne. NF_EBADID)
+ + call errore('bad ncid: ', err)
+ err = nfmpi_iput_varm_$1(ncid, BAD_VARID, start,
+ + edge, stride,
+ + imap, value,reqid(1))
+ if (err .ne. NF_ENOTVAR)
+ + call errore('bad var id: ', err)
+ do 3, j = 1, var_rank(i)
+ if (var_dimid(j,i) .ne. RECDIM) then !/* skip record dim */
+ start(j) = var_shape(j,i) + 1
+ err = nfmpi_iput_varm_$1(ncid, i, start,
+ + edge, stride,
+ + imap, value,reqid(1))
+ if (err .eq. NF_NOERR .or. err .eq. NF_ERANGE)
+ + err_w = nfmpi_wait_all(ncid,1,reqid,st)
+ ! NF_ERANGE is not a fatal error?
+ if (.not. canConvert) then
+ if (err .ne. NF_ECHAR)
+ + call errore('conversion: ', err)
+ else
+ if (err .ne. NF_EINVALCOORDS)
+ + call errore('bad start: ', err)
+ endif
+ start(j) = 1
+ edge(j) = var_shape(j,i) + 1
+ err = nfmpi_iput_varm_$1(ncid, i, start,
+ + edge, stride,
+ + imap, value,reqid(1))
+ if (err .eq. NF_NOERR .or. err .eq. NF_ERANGE)
+ + err_w = nfmpi_wait_all(ncid,1,reqid,st)
+ ! NF_ERANGE is not a fatal error?
+ if (.not. canConvert) then
+ if (err .ne. NF_ECHAR)
+ + call errore('conversion: ', err)
+ else
+ if (err .ne. NF_EEDGE)
+ + call errore('bad edge: ', err)
+ endif
+ edge(j) = 1
+ stride(j) = 0
+ err = nfmpi_iput_varm_$1(ncid, i, start,
+ + edge, stride,
+ + imap, value,reqid(1))
+ if (err .eq. NF_NOERR .or. err .eq. NF_ERANGE)
+ + err_w = nfmpi_wait_all(ncid,1,reqid,st)
+ ! NF_ERANGE is not a fatal error?
+ if (.not. canConvert) then
+ if (err .ne. NF_ECHAR)
+ + call errore('conversion: ', err)
+ else
+ if (err .ne. NF_ESTRIDE)
+ + call errore('bad stride: ', err)
+ endif
+ stride(j) = 1
+ end if
+3 continue
+ !/* Choose a random point dividing each dim into 2 parts */
+ !/* Put 2^rank (nslabs) slabs so defined */
+ nslabs = 1
+ do 4, j = 1, var_rank(i)
+ mid(j) = roll( var_shape(j,i) )
+ nslabs = nslabs * 2
+4 continue
+ !/* bits of k determine whether to put lower or upper part of dim */
+ !/* choose random stride from 1 to edge */
+ do 5, k = 1, nslabs
+ nstarts = 1
+ do 6, j = 1, var_rank(i)
+ if (mod(ud_shift(k-1, -(j-1)), 2) .eq. 1) then
+ start(j) = 1
+ edge(j) = mid(j)
+ else
+ start(j) = 1 + mid(j)
+ edge(j) = var_shape(j,i) - mid(j)
+ end if
+ if (edge(j) .gt. 0) then
+ stride(j) = 1+roll(edge(j))
+ else
+ stride(j) = 1
+ end if
+ sstride(j) = stride(j)
+ nstarts = nstarts * int(stride(j))
+6 continue
+ do 7, m = 1, nstarts
+ err = index2indexes(m, var_rank(i), sstride, index)
+ if (err .ne. NF_NOERR)
+ + call error('error in index2indexes')
+ nels = 1
+ do 8, j = 1, var_rank(i)
+ count(j) = 1 + (edge(j) - index(j)) / stride(j)
+ nels = nels * int(count(j))
+ index(j) = index(j) + start(j) - 1
+8 continue
+ !/* Random choice of forward or backward */
+C/* TODO
+C if ( roll(2) ) then
+C do 9, j = 1, var_rank(i)
+C index(j) = index(j) +
+C + (count(j) - 1) * stride(j)
+C stride(j) = -stride(j)
+C9 continue
+C end if
+C*/
+ if (var_rank(i) .gt. 0) then
+ imap(1) = 1
+ do 10, j = 2, var_rank(i)
+ imap(j) = imap(j-1) * count(j-1)
+10 continue
+ end if
+ allInExtRange = .true.
+ do 11 j = 1, nels
+ err = index2indexes(j, var_rank(i), count,
+ + index2)
+ if (err .ne. NF_NOERR)
+ + call error('error in index2indexes')
+ do 12, d = 1, var_rank(i)
+ index2(d) = index(d) +
+ + (index2(d)-1) * stride(d)
+12 continue
+ val = hash_$1(var_type(i),var_rank(i),
+ + index2, NFT_ITYPE($1))
+ MAKE_TYPE2($1, VAR_ELEM($1, value, j), val)
+ val = ARITH3($1, value, j)
+ allInExtRange = allInExtRange .and.
+ + inRange3(val, var_type(i),
+ + NFT_ITYPE($1))
+11 continue
+ err = nfmpi_iput_varm_$1(ncid,i,index,count,
+ + stride,imap,
+ + value,reqid(1))
+ if (err .eq. NF_NOERR .or. err .eq. NF_ERANGE)
+ + err_w = nfmpi_wait_all(ncid,1,reqid,st)
+ if (canConvert) then
+ if (allInExtRange) then
+ if (st(1) .ne. 0)
+ + call error(nfmpi_strerror(st(1)))
+ else
+ if (err .ne. NF_ERANGE)
+ + call errore('range error: ', err)
+ end if
+ else
+ if (nels .gt. 0 .and. err .ne. NF_ECHAR)
+ + call errore('wrong type: ', err)
+ end if
+7 continue
+5 continue
+1 continue
+
+ err = nfmpi_close(ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_close: ', err)
+
+ call check_vars_$1(scratch)
+
+ err = nfmpi_delete(scratch, info)
+ if (err .ne. NF_NOERR)
+ + call errorc('delete of scratch file failed:',
+ + scratch)
+ end
+])dnl
+
+
+divert(0)dnl
+dnl If you see this line, you can ignore the next one.
+C Do not edit this file. It is produced from the corresponding .m4 source */
+
+C********************************************************************
+C Copyright 1996, UCAR/Unidata
+C See netcdf/COPYRIGHT file for copying and redistribution conditions.
+C $Id: test_iput.m4 2232 2015-12-16 22:16:52Z wkliao $
+C********************************************************************
+
+TEST_NFMPI_IPUT_VAR1(text)
+#ifdef NF_INT1_T
+TEST_NFMPI_IPUT_VAR1(int1)
+#endif
+#ifdef NF_INT2_T
+TEST_NFMPI_IPUT_VAR1(int2)
+#endif
+TEST_NFMPI_IPUT_VAR1(int)
+TEST_NFMPI_IPUT_VAR1(int8)
+TEST_NFMPI_IPUT_VAR1(real)
+TEST_NFMPI_IPUT_VAR1(double)
+
+TEST_NFMPI_IPUT_VAR(text)
+#ifdef NF_INT1_T
+TEST_NFMPI_IPUT_VAR(int1)
+#endif
+#ifdef NF_INT2_T
+TEST_NFMPI_IPUT_VAR(int2)
+#endif
+TEST_NFMPI_IPUT_VAR(int)
+TEST_NFMPI_IPUT_VAR(int8)
+TEST_NFMPI_IPUT_VAR(real)
+TEST_NFMPI_IPUT_VAR(double)
+
+TEST_NFMPI_IPUT_VARA(text)
+#ifdef NF_INT1_T
+TEST_NFMPI_IPUT_VARA(int1)
+#endif
+#ifdef NF_INT2_T
+TEST_NFMPI_IPUT_VARA(int2)
+#endif
+TEST_NFMPI_IPUT_VARA(int)
+TEST_NFMPI_IPUT_VARA(int8)
+TEST_NFMPI_IPUT_VARA(real)
+TEST_NFMPI_IPUT_VARA(double)
+
+TEST_NFMPI_IPUT_VARS(text)
+#ifdef NF_INT1_T
+TEST_NFMPI_IPUT_VARS(int1)
+#endif
+#ifdef NF_INT2_T
+TEST_NFMPI_IPUT_VARS(int2)
+#endif
+TEST_NFMPI_IPUT_VARS(int)
+TEST_NFMPI_IPUT_VARS(int8)
+TEST_NFMPI_IPUT_VARS(real)
+TEST_NFMPI_IPUT_VARS(double)
+
+TEST_NFMPI_IPUT_VARM(text)
+#ifdef NF_INT1_T
+TEST_NFMPI_IPUT_VARM(int1)
+#endif
+#ifdef NF_INT2_T
+TEST_NFMPI_IPUT_VARM(int2)
+#endif
+TEST_NFMPI_IPUT_VARM(int)
+TEST_NFMPI_IPUT_VARM(int8)
+TEST_NFMPI_IPUT_VARM(real)
+TEST_NFMPI_IPUT_VARM(double)
diff --git a/test/nf_test/test_put.m4 b/test/nf_test/test_put.m4
new file mode 100644
index 0000000..841cd1b
--- /dev/null
+++ b/test/nf_test/test_put.m4
@@ -0,0 +1,1518 @@
+divert(-1)
+
+dnl This is m4 source.
+dnl Process using m4 to produce FORTRAN language file.
+
+changequote([,]) dnl
+
+undefine([index])dnl
+
+dnl Macros
+
+dnl Upcase(str)
+dnl
+define([Upcase],[dnl
+translit($1, abcdefghijklmnopqrstuvwxyz, ABCDEFGHIJKLMNOPQRSTUVWXYZ)])
+
+dnl NFT_ITYPE(type)
+dnl
+define([NFT_ITYPE], [NFT_[]Upcase($1)])
+
+dnl ARITH3(itype, value)
+dnl
+define([ARITH3], [ifelse($1, text, ichar($2($3:$3)), $2($3))])
+
+dnl VAR_ELEM(itype, value)
+dnl
+define([VAR_ELEM], [ifelse($1, text, $2($3:$3), $2($3))])
+
+dnl ARITH_VAR1(itype, value)
+dnl
+define([ARITH_VAR1], [ifelse($1, text, ichar($2), $2)])
+
+dnl DATATYPE(funf_suffix)
+dnl
+define([DATATYPE], [dnl
+ifelse($1, text, character*MAX_NELS $2,
+ifelse($1, int1, NF_INT1_T $2$3,
+ifelse($1, int2, NF_INT2_T $2$3,
+ifelse($1, int, integer $2$3,
+ifelse($1, int8, NF_INT8_T $2$3,
+ifelse($1, real, real $2$3,
+ifelse($1, double, doubleprecision $2$3)[]dnl
+)[]dnl
+)[]dnl
+)[]dnl
+)[]dnl
+)[]dnl
+)[]dnl
+])
+
+dnl DATATYPE_VAR1(funf_suffix)
+dnl
+define([DATATYPE_VAR1], [dnl
+ifelse($1, text, character $2,
+ifelse($1, int1, NF_INT1_T $2,
+ifelse($1, int2, NF_INT2_T $2,
+ifelse($1, int, integer $2,
+ifelse($1, int8, NF_INT8_T $2,
+ifelse($1, real, real $2,
+ifelse($1, double, doubleprecision $2)[]dnl
+)[]dnl
+)[]dnl
+)[]dnl
+)[]dnl
+)[]dnl
+)[]dnl
+])
+
+dnl MAKE_ARITH_VAR1(funf_suffix, var)
+dnl
+define([MAKE_ARITH_VAR1], [dnl
+ifelse($1, text, ichar($2), $2)[]dnl
+])
+
+dnl MAKE_ARITH3(funf_suffix, var)
+dnl
+define([MAKE_ARITH3], [dnl
+ifelse($1, text, ichar($2($3:$3)), $2($3))[]dnl
+])
+
+dnl MAKE_DOUBLE(funf_suffix, var)
+dnl
+define([MAKE_DOUBLE], [dnl
+ifelse($1, text, dble(ichar($2)), dble($2))[]dnl
+])
+
+dnl MAKE_TYPE(funf_suffix, var)
+dnl
+define([MAKE_TYPE], [dnl
+ifelse($1, text, char(int($2)),
+ ifelse($1, int, INT($2),
+ ifelse($1, real, REAL($2),
+ ifelse($1, double, DBLE($2),
+ $2))))[]dnl
+])
+
+dnl MAKE_TYPE2(funf_suffix, var_dest, var_src)
+dnl
+define([MAKE_TYPE2], [dnl
+ifelse($1, text, $2 = char(int($3)),
+ ifelse($1, int, $2 = INT($3),
+ ifelse($1, int8,
+ if ($3 .EQ. X_INT8_MAX) then
+ $2 = X_INT8_MAX
+ else
+ $2 = $3
+ endif,
+ ifelse($1, real, $2 = REAL($3),
+ ifelse($1, double, $2 = DBLE($3),
+ $2 = $3)))))[]dnl
+])
+
+dnl HASH(TYPE)
+dnl
+define([HASH],
+[dnl
+C
+C ensure hash value within range for internal TYPE
+C
+ doubleprecision function hash_$1(type, rank, index, itype)
+ implicit none
+ include "pnetcdf.inc"
+#include "tests.inc"
+ integer type
+ integer rank
+ integer*8 index(1)
+ integer itype
+ doubleprecision minimum
+ doubleprecision maximum
+ doubleprecision internal_min, internal_max, hash4
+
+ minimum = internal_min(itype)
+ maximum = internal_max(itype)
+
+ hash_$1 = max(minimum, min(maximum, hash4( type, rank,
+ + index, itype)))
+ end
+])dnl
+
+
+dnl CHECK_VARS(TYPE)
+dnl
+define([CHECK_VARS],dnl
+[dnl
+C
+C check all vars in file which are (text/numeric) compatible with TYPE
+C
+ subroutine check_vars_$1(filename)
+ implicit none
+ include "pnetcdf.inc"
+#include "tests.inc"
+ integer index2indexes
+ double precision hash4
+ logical equal, inRange3, in_internal_range
+
+ character*(*) filename
+ integer ncid !/* netCDF id */
+ integer*8 index(MAX_RANK)
+ integer err
+ integer d
+ integer i
+ integer j
+ DATATYPE_VAR1($1, value)
+ integer datatype
+ integer ndims
+ integer dimids(MAX_RANK)
+ integer ngatts
+ doubleprecision expect
+ character*(NF_MAX_NAME) name
+ integer*8 length
+ logical canConvert !/* Both text or both numeric */
+ integer nok !/* count of valid comparisons */
+ doubleprecision val
+ integer intindex
+
+ nok = 0
+
+ err = nfmpi_open(comm, filename, NF_NOWRITE, info, ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_open: ', err)
+ err = nfmpi_begin_indep_data(ncid)
+ do 1, i = 1, numVars
+ canConvert = (var_type(i) .eq. NF_CHAR) .eqv.
+ + (NFT_ITYPE($1) .eq. NFT_TEXT)
+ if (canConvert) then
+ err = nfmpi_inq_var(ncid, i, name, datatype, ndims,
+ + dimids, ngatts)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_inq_var: ', err)
+ if (name .ne. var_name(i))
+ + call error('Unexpected var_name')
+ if (datatype .ne. var_type(i))
+ + call error('Unexpected type')
+ if (ndims .ne. var_rank(i))
+ + call error('Unexpected rank')
+ do 2, j = 1, ndims
+ err = nfmpi_inq_dim(ncid, dimids(j), name,
+ + length)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_inq_dim: ', err)
+ if (length .ne. var_shape(j,i))
+ + call error('Unexpected shape')
+2 continue
+ do 3, j = 1, var_nels(i)
+ err = index2indexes(j, var_rank(i), var_shape(1,i),
+ + index)
+ if (err .ne. NF_NOERR)
+ + call error('error in index2indexes()')
+ expect = hash4( var_type(i), var_rank(i), index,
+ + NFT_ITYPE($1))
+ err = nfmpi_get_var1_$1(ncid, i, index,
+ + value)
+ if (inRange3(expect,datatype,NFT_ITYPE($1))) then
+ if (in_internal_range(NFT_ITYPE($1),
+ + expect)) then
+ if (err .ne. NF_NOERR) then
+ call errore
+ + ('nfmpi_get_var1_$1: ',
+ + err)
+ else
+ val = MAKE_ARITH_VAR1($1,value)
+ if (.not.equal(
+ + val,
+ + expect,var_type(i),
+ + NFT_ITYPE($1))) then
+ call error(
+ + 'Var value read not that expected')
+ if (verbose) then
+ call error(' ')
+ call errori('varid: %d', i)
+ call errorc('var_name: ',
+ + var_name(i))
+ call error('index:')
+ do 4, d = 1, var_rank(i)
+ intindex = int(index(d))
+ call errori(' ', intindex)
+4 continue
+ call errord('expect: ', expect)
+ call errord('got: ', val)
+ end if
+ else
+ nok = nok + 1
+ end if
+ end if
+ end if
+ end if
+3 continue
+ end if
+1 continue
+ err = nfmpi_end_indep_data(ncid)
+ err = nfmpi_close (ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_close: ', err)
+ call print_nok(nok)
+ end
+])dnl
+
+
+dnl CHECK_ATTS(TYPE) numeric only
+dnl
+define([CHECK_ATTS],dnl
+[dnl
+C/*
+C * check all attributes in file which are (text/numeric) compatible with TYPE
+C * ignore any attributes containing values outside range of TYPE
+C */
+ subroutine check_atts_$1(ncid)
+ implicit none
+ include "pnetcdf.inc"
+#include "tests.inc"
+ character*2 ATT_NAME
+ integer ATT_TYPE, NATTS, ATT_LEN
+ double precision hash4
+ logical equal, inRange3, in_internal_range
+
+ integer ncid
+ integer err
+ integer i
+ integer j
+ integer k
+ integer*8 ndx(1)
+ DATATYPE($1, value, (MAX_NELS))
+ integer datatype
+ doubleprecision expect(MAX_NELS)
+ integer*8 length
+ integer nInExtRange !/* number values within external range */
+ integer nInIntRange !/* number values within internal range */
+ logical canConvert !/* Both text or both numeric */
+ integer nok !/* count of valid comparisons */
+ doubleprecision val
+
+ nok = 0
+
+ do 1, i = 0, numVars
+ do 2, j = 1, NATTS(i)
+ canConvert = (ATT_TYPE(j,i) .eq. NF_CHAR) .eqv.
+ + (NFT_ITYPE($1) .eq. NFT_TEXT)
+ if (canConvert) then
+ err = nfmpi_inq_att(ncid, i, ATT_NAME(j,i),
+ + datatype, length)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_inq_att: ', err)
+ if (datatype .ne. ATT_TYPE(j,i))
+ + call error('nfmpi_inq_att: unexpected type')
+ if (length .ne. ATT_LEN(j,i))
+ + call error('nfmpi_inq_att: unexpected length')
+ if (.not.(length .le. MAX_NELS))
+ + stop 'assert(length .le. MAX_NELS)'
+ nInIntRange = 0
+ nInExtRange = 0
+ do 4, k = 1, int(length)
+ ndx(1) = k
+ expect(k) = hash4( datatype, -1, ndx,
+ + NFT_ITYPE($1))
+ if (inRange3(expect(k), datatype,
+ + NFT_ITYPE($1))) then
+ nInExtRange = nInExtRange + 1
+ if (in_internal_range(NFT_ITYPE($1),
+ + expect(k)))
+ + nInIntRange = nInIntRange + 1
+ end if
+4 continue
+ err = nfmpi_get_att_$1(ncid, i,
+ + ATT_NAME(j,i), value)
+ if (nInExtRange .eq. length .and.
+ + nInIntRange .eq. length) then
+ if (err .ne. NF_NOERR)
+ + call error(nfmpi_strerror(err))
+ else
+ if (err .ne. NF_NOERR .and. err .ne. NF_ERANGE)
+ + call errore('OK or Range error: ', err)
+ end if
+ do 3, k = 1, int(length)
+ if (inRange3(expect(k),datatype,NFT_ITYPE($1))
+ + .and.
+ + in_internal_range(NFT_ITYPE($1),
+ + expect(k))) then
+ val = MAKE_ARITH3($1,value,k)
+ if (.not.equal(
+ + val,
+ + expect(k),datatype,
+ + NFT_ITYPE($1))) then
+ call error(
+ + 'att. value read not that expected')
+ if (verbose) then
+ call error(' ')
+ call errori('varid: ', i)
+ call errorc('att_name: ',
+ + ATT_NAME(j,i))
+ call errori('element number: ', k)
+ call errord('expect: ', expect(k))
+ call errord('got: ', val)
+ end if
+ else
+ nok = nok + 1
+ end if
+ end if
+3 continue
+ end if
+2 continue
+1 continue
+
+ call print_nok(nok)
+ end
+])dnl
+
+
+dnl TEST_NFMPI_PUT_VAR1(TYPE)
+dnl
+define([TEST_NFMPI_PUT_VAR1],dnl
+[dnl
+ subroutine test_nfmpi_put_var1_$1()
+ implicit none
+ include "pnetcdf.inc"
+#include "tests.inc"
+ integer index2indexes
+ double precision hash_$1
+ logical inRange3
+
+ integer ncid
+ integer i
+ integer j
+ integer err, flags
+ integer*8 index(MAX_RANK)
+ logical canConvert !/* Both text or both numeric */
+ DATATYPE_VAR1($1, value)
+ doubleprecision val
+
+ value = MAKE_TYPE($1, 5)!/* any value would do - only for error cases */
+
+ flags = IOR(NF_CLOBBER, extra_flags)
+ err = nfmpi_create(comm, scratch, flags, info, ncid)
+ if (err .ne. NF_NOERR) then
+ call errore('nfmpi_create: ', err)
+ return
+ end if
+ call def_dims(ncid)
+ call def_vars(ncid)
+ err = nfmpi_enddef(ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_enddef: ', err)
+ err = nfmpi_begin_indep_data(ncid)
+ do 1, i = 1, numVars
+ canConvert = (var_type(i) .eq. NF_CHAR) .eqv.
+ + (NFT_ITYPE($1) .eq. NFT_TEXT)
+ do 2, j = 1, var_rank(i)
+ index(j) = 1
+2 continue
+ err = nfmpi_put_var1_$1(BAD_ID, i, index, value)
+ if (err .ne. NF_EBADID)
+ + call errore('bad ncid: ', err)
+ err = nfmpi_put_var1_$1(ncid, BAD_VARID,
+ + index, value)
+ if (err .ne. NF_ENOTVAR)
+ + call errore('bad var id: ', err)
+ do 3, j = 1, var_rank(i)
+ if (var_dimid(j,i) .gt. 1) then !/* skip record dim */
+ index(j) = var_shape(j,i) + 1
+ err = nfmpi_put_var1_$1(ncid, i,
+ + index, value)
+ if (.not. canConvert) then
+ if (err .ne. NF_ECHAR)
+ + call errore('conversion: ', err)
+ else
+ if (err .ne. NF_EINVALCOORDS)
+ + call errore('bad index: ', err)
+ endif
+ index(j) = 0
+ end if
+3 continue
+ do 4, j = 1, var_nels(i)
+ err = index2indexes(j, var_rank(i), var_shape(1,i),
+ + index)
+ if (err .ne. NF_NOERR)
+ + call error('error in index2indexes 1')
+ val = hash_$1(var_type(i),var_rank(i),
+ + index, NFT_ITYPE($1))
+ MAKE_TYPE2($1, value, val)
+ err = nfmpi_put_var1_$1(ncid, i, index, value)
+ if (canConvert) then
+ val = ARITH_VAR1($1, value)
+ if (inRange3(val, var_type(i), NFT_ITYPE($1))) then
+ if (err .ne. NF_NOERR)
+ + call error(nfmpi_strerror(err))
+ else
+ if (err .ne. NF_ERANGE)
+ + call errore('Range error: ', err)
+ end if
+ else
+ if (err .ne. NF_ECHAR)
+ + call errore('wrong type: ', err)
+ end if
+4 continue
+1 continue
+ err = nfmpi_end_indep_data(ncid)
+ err = nfmpi_close(ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_close: ', err)
+
+ call check_vars_$1(scratch)
+
+ err = nfmpi_delete(scratch, info)
+ if (err .ne. NF_NOERR)
+ + call errorc('delete of scratch file failed: ',
+ + scratch)
+ end
+])dnl
+
+
+dnl TEST_NFMPI_PUT_VAR(TYPE)
+dnl
+define([TEST_NFMPI_PUT_VAR],dnl
+[dnl
+ subroutine test_nfmpi_put_var_$1()
+ implicit none
+ include "pnetcdf.inc"
+#include "tests.inc"
+ integer index2indexes
+ double precision hash_$1
+ logical inRange3
+
+ integer ncid
+ integer vid
+ integer i
+ integer j
+ integer err, flags
+ integer nels
+ integer*8 index(MAX_RANK)
+ logical canConvert !/* Both text or both numeric */
+ logical allInExtRange !/* All values within external range?*/
+ DATATYPE($1, value, (MAX_NELS))
+ doubleprecision val
+
+ flags = IOR(NF_CLOBBER, extra_flags)
+ err = nfmpi_create(comm, scratch, flags, info, ncid)
+ if (err .ne. NF_NOERR) then
+ call errore('nfmpi_create: ', err)
+ return
+ end if
+ call def_dims(ncid)
+ call def_vars(ncid)
+ err = nfmpi_enddef(ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_enddef: ', err)
+ err = nfmpi_begin_indep_data(ncid)
+ do 1, i = 1, numVars
+ canConvert = (var_type(i) .eq. NF_CHAR) .eqv.
+ + (NFT_ITYPE($1) .eq. NFT_TEXT)
+ err = nfmpi_put_var_$1(BAD_ID, i, value)
+ if (err .ne. NF_EBADID)
+ + call errore('bad ncid: ', err)
+ err = nfmpi_put_var_$1(ncid, BAD_VARID, value)
+ if (err .ne. NF_ENOTVAR)
+ + call errore('bad var id: ', err)
+ nels = 1
+ do 3, j = 1, var_rank(i)
+ nels = nels * int(var_shape(j,i))
+3 continue
+ allInExtRange = .true.
+ do 4, j = 1, var_nels(i)
+ err = index2indexes(j, var_rank(i), var_shape(1,i),
+ + index)
+ if (err .ne. NF_NOERR)
+ + call error('error in index2indexes 1')
+ val = hash_$1(var_type(i), var_rank(i),
+ + index, NFT_ITYPE($1))
+ MAKE_TYPE2($1, VAR_ELEM($1, value, j), val)
+ val = ARITH3($1, value, j)
+ allInExtRange = allInExtRange .and.
+ + inRange3(val, var_type(i), NFT_ITYPE($1))
+4 continue
+ err = nfmpi_put_var_$1(ncid, i, value)
+ if (canConvert) then
+ if (allInExtRange) then
+ if (err .ne. NF_NOERR)
+ + call error(nfmpi_strerror(err))
+ else
+ if (err .ne. NF_ERANGE .and.
+ + var_dimid(var_rank(i),i) .ne. RECDIM)
+ + call errore('Range error: ', err)
+ endif
+ else
+ if (err .ne. NF_ECHAR)
+ + call errore('wrong type: ', err)
+ endif
+1 continue
+ err = nfmpi_end_indep_data(ncid)
+
+C The preceeding has written nothing for record variables, now try
+C again with more than 0 records.
+
+C Write record number NRECS to force writing of preceding records.
+C Assumes variable cr is char vector with UNLIMITED dimension.
+
+ err = nfmpi_inq_varid(ncid, "cr", vid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_inq_varid: ', err)
+ index(1) = NRECS
+ err = nfmpi_begin_indep_data(ncid)
+ err = nfmpi_put_var1_text(ncid, vid, index, 'x')
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_put_var1_text: ', err)
+
+ do 5 i = 1, numVars
+C Only test record variables here
+ if (var_rank(i) .ge. 1 .and.
+ + var_dimid(var_rank(i),i) .eq. RECDIM) then
+ canConvert = (var_type(i) .eq. NF_CHAR) .eqv.
+ + (NFT_ITYPE($1) .eq. NFT_TEXT)
+ if (var_rank(i) .gt. MAX_RANK)
+ + stop 'var_rank(i) .gt. MAX_RANK'
+ if (var_nels(i) .gt. MAX_NELS)
+ + stop 'var_nels(i) .gt. MAX_NELS'
+ err = nfmpi_put_var_$1(BAD_ID, i, value)
+
+ nels = 1
+ do 6 j = 1, var_rank(i)
+ nels = nels * int(var_shape(j,i))
+6 continue
+ allInExtRange = .true.
+ do 7, j = 1, nels
+ err = index2indexes(j, var_rank(i), var_shape(1,i),
+ + index)
+ if (err .ne. NF_NOERR)
+ + call error('error in index2indexes()')
+ val = hash_$1(var_type(i), var_rank(i),
+ + index, NFT_ITYPE($1))
+ MAKE_TYPE2($1, VAR_ELEM($1, value, j), val)
+ val = ARITH3($1, value, j)
+ allInExtRange = allInExtRange .and.
+ + inRange3(val, var_type(i), NFT_ITYPE($1))
+7 continue
+ err = nfmpi_put_var_$1(ncid, i, value)
+ if (canConvert) then
+ if (allInExtRange) then
+ if (err .ne. NF_NOERR)
+ + call error(nfmpi_strerror(err))
+ else
+ if (err .ne. NF_ERANGE)
+ + call errore('range error: ', err)
+ endif
+ else
+ if (nels .gt. 0 .and. err .ne. NF_ECHAR)
+ + call errore('wrong type: ', err)
+ endif
+ endif
+5 continue
+ err = nfmpi_end_indep_data(ncid)
+ err = nfmpi_close(ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_close: ', err)
+
+ call check_vars_$1(scratch)
+
+ err = nfmpi_delete(scratch, info)
+ if (err .ne. NF_NOERR)
+ + call errorc('delete of scratch file failed: ',
+ + scratch)
+ end
+])dnl
+
+
+dnl TEST_NFMPI_PUT_VARA(TYPE)
+dnl
+define([TEST_NFMPI_PUT_VARA],dnl
+[dnl
+ subroutine test_nfmpi_put_vara_$1()
+ implicit none
+ include "pnetcdf.inc"
+#include "tests.inc"
+ integer index2indexes, roll
+ double precision hash_$1
+ logical inRange3
+
+ integer ncid
+ integer i
+ integer j
+ integer k
+ integer d
+ integer err, flags
+ integer nslabs
+ integer nels
+ integer*8 start(MAX_RANK)
+ integer*8 edge(MAX_RANK)
+ integer*8 mid(MAX_RANK)
+ integer*8 index(MAX_RANK)
+ logical canConvert !/* Both text or both numeric */
+ logical allInExtRange !/* all values within external range? */
+ DATATYPE($1, value, (MAX_NELS))
+ doubleprecision val
+ integer ud_shift
+
+ flags = IOR(NF_CLOBBER, extra_flags)
+ err = nfmpi_create(comm, scratch, flags, info, ncid)
+ if (err .ne. NF_NOERR) then
+ call errore('nfmpi_create: ', err)
+ return
+ end if
+ call def_dims(ncid)
+ call def_vars(ncid)
+ err = nfmpi_enddef(ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_enddef: ', err)
+
+ do 1, i = 1, numVars
+ canConvert = (var_type(i) .eq. NF_CHAR) .eqv.
+ + (NFT_ITYPE($1) .eq. NFT_TEXT)
+ if (.not.(var_rank(i) .le. MAX_RANK))
+ + stop 'assert(var_rank(i) .le. MAX_RANK)'
+ if (.not.(var_nels(i) .le. MAX_NELS))
+ + stop 'assert(var_nels(i) .le. MAX_NELS)'
+ do 2, j = 1, var_rank(i)
+ start(j) = 1
+ edge(j) = 1
+2 continue
+ err = nfmpi_put_vara_$1_all(BAD_ID, i, start,
+ + edge, value)
+ if (err .ne. NF_EBADID)
+ + call errore('bad ncid: ', err)
+ err = nfmpi_put_vara_$1_all(ncid, BAD_VARID,
+ + start, edge, value)
+ if (err .ne. NF_ENOTVAR)
+ + call errore('bad var id: ', err)
+ do 3, j = 1, var_rank(i)
+ if (var_dimid(j,i) .ne. RECDIM) then !/* skip record dim */
+ start(j) = var_shape(j,i) + 1
+ err = nfmpi_put_vara_$1_all(ncid, i, start,
+ + edge, value)
+ if (.not. canConvert) then
+ if (err .ne. NF_ECHAR)
+ + call errore('conversion: ', err)
+ else
+ if (err .ne. NF_EINVALCOORDS)
+ + call errore('bad start: ', err)
+ endif
+ start(j) = 1
+ edge(j) = var_shape(j,i) + 1
+ err = nfmpi_put_vara_$1_all(ncid, i, start,
+ + edge, value)
+ if (.not. canConvert) then
+ if (err .ne. NF_ECHAR)
+ + call errore('conversion: ', err)
+ else
+ if (err .ne. NF_EEDGE)
+ + call errore('bad edge: ', err)
+ endif
+ edge(j) = 1
+ end if
+3 continue
+
+C /* Check correct error returned even when nothing to put */
+ do 20, j = 1, var_rank(i)
+ edge(j) = 0
+20 continue
+ err = nfmpi_put_vara_$1_all(BAD_ID, i, start,
+ + edge, value)
+ if (err .ne. NF_EBADID)
+ + call errore('bad ncid: ', err)
+ err = nfmpi_put_vara_$1_all(ncid, BAD_VARID,
+ + start, edge, value)
+ if (err .ne. NF_ENOTVAR)
+ + call errore('bad var id: ', err)
+ do 21, j = 1, var_rank(i)
+ if (var_dimid(j,i) .gt. 1) then ! skip record dim
+ start(j) = var_shape(j,i) + 1
+ err = nfmpi_put_vara_$1_all(ncid, i,
+ + start, edge, value)
+ if (.not. canConvert) then
+ if (err .ne. NF_ECHAR)
+ + call errore('conversion: ', err)
+ else
+ if (err .ne. NF_EINVALCOORDS)
+ + call errore('bad start: ', err)
+ endif
+ start(j) = 1
+ endif
+21 continue
+
+! wkliao: this test below of put_vara is redundant and incorrectly uses the
+! value[] set from the previously iteration. There is no such test
+! in put_vars and put_varm.
+!
+! err = nfmpi_put_vara_$1_all(ncid, i, start,
+! + edge, value)
+! if (canConvert) then
+! if (err .ne. NF_NOERR)
+! + call error(nfmpi_strerror(err))
+! else
+! if (err .ne. NF_ECHAR)
+! + call errore('wrong type: ', err)
+! endif
+
+ do 22, j = 1, var_rank(i)
+ edge(j) = 1
+22 continue
+
+
+ !/* Choose a random point dividing each dim into 2 parts */
+ !/* Put 2^rank (nslabs) slabs so defined */
+ nslabs = 1
+ do 4, j = 1, var_rank(i)
+ mid(j) = roll( var_shape(j,i) )
+ nslabs = nslabs * 2
+4 continue
+ !/* bits of k determine whether to put lower or upper part of dim */
+ do 5, k = 1, nslabs
+ nels = 1
+ do 6, j = 1, var_rank(i)
+ if (mod(ud_shift(k-1, -(j-1)), 2) .eq. 1) then
+ start(j) = 1
+ edge(j) = mid(j)
+ else
+ start(j) = 1 + mid(j)
+ edge(j) = var_shape(j,i) - mid(j)
+ end if
+ nels = nels * int(edge(j))
+6 continue
+ allInExtRange = .true.
+ do 7, j = 1, nels
+ err = index2indexes(j, var_rank(i), edge, index)
+ if (err .ne. NF_NOERR)
+ + call error('error in index2indexes 1')
+ do 8, d = 1, var_rank(i)
+ index(d) = index(d) + start(d) - 1
+8 continue
+ val = hash_$1(var_type(i), var_rank(i),
+ + index, NFT_ITYPE($1))
+ MAKE_TYPE2($1, VAR_ELEM($1, value, j), val)
+ val = ARITH3($1, value, j)
+ allInExtRange = allInExtRange .and.
+ + inRange3(val, var_type(i), NFT_ITYPE($1))
+7 continue
+ err = nfmpi_put_vara_$1_all(ncid, i, start,
+ + edge, value)
+ if (canConvert) then
+ if (allInExtRange) then
+ if (err .ne. NF_NOERR)
+ + call error(nfmpi_strerror(err))
+ else
+ if (err .ne. NF_ERANGE)
+ + call errore('range error: ', err)
+ end if
+ else
+ if (nels .gt. 0 .and. err .ne. NF_ECHAR)
+ + call errore('wrong type: ', err)
+ end if
+5 continue
+1 continue
+
+ err = nfmpi_close(ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_close: ', err)
+
+ call check_vars_$1(scratch)
+
+ err = nfmpi_delete(scratch, info)
+ if (err .ne. NF_NOERR)
+ + call errorc('delete of scratch file failed: ',
+ + scratch)
+ end
+])dnl
+
+
+dnl TEST_NFMPI_PUT_VARS(TYPE)
+dnl
+define([TEST_NFMPI_PUT_VARS],dnl
+[dnl
+ subroutine test_nfmpi_put_vars_$1()
+ implicit none
+ include "pnetcdf.inc"
+#include "tests.inc"
+ double precision hash_$1
+ logical inRange3
+ integer roll, index2indexes
+
+ integer ncid
+ integer d
+ integer i
+ integer j
+ integer k
+ integer m
+ integer err, flags
+ integer nels
+ integer nslabs
+ integer nstarts !/* number of different starts */
+ integer*8 start(MAX_RANK)
+ integer*8 edge(MAX_RANK)
+ integer*8 index(MAX_RANK)
+ integer*8 index2(MAX_RANK)
+ integer*8 mid(MAX_RANK)
+ integer*8 count(MAX_RANK)
+ integer*8 sstride(MAX_RANK)
+ integer*8 stride(MAX_RANK)
+ logical canConvert !/* Both text or both numeric */
+ logical allInExtRange !/* all values within external range? */
+ DATATYPE($1, value, (MAX_NELS))
+ doubleprecision val
+ integer ud_shift
+
+ flags = IOR(NF_CLOBBER, extra_flags)
+ err = nfmpi_create(comm, scratch, flags, info, ncid)
+ if (err .ne. NF_NOERR) then
+ call errore('nfmpi_create: ', err)
+ return
+ end if
+ call def_dims(ncid)
+ call def_vars(ncid)
+ err = nfmpi_enddef(ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_enddef: ', err)
+
+ do 1, i = 1, numVars
+ canConvert = (var_type(i) .eq. NF_CHAR) .eqv.
+ + (NFT_ITYPE($1) .eq. NFT_TEXT)
+ if (.not.(var_rank(i) .le. MAX_RANK))
+ + stop 'assert(var_rank(i) .le. MAX_RANK)'
+ if (.not.(var_nels(i) .le. MAX_NELS))
+ + stop 'assert(var_nels(i) .le. MAX_NELS)'
+ do 2, j = 1, var_rank(i)
+ start(j) = 1
+ edge(j) = 1
+ stride(j) = 1
+2 continue
+ err = nfmpi_put_vars_$1_all(BAD_ID, i, start,
+ + edge, stride, value)
+ if (err .ne. NF_EBADID)
+ + call errore('bad ncid: ', err)
+ err = nfmpi_put_vars_$1_all(ncid, BAD_VARID, start,
+ + edge, stride,
+ + value)
+ if (err .ne. NF_ENOTVAR)
+ + call errore('bad var id: ', err)
+ do 3, j = 1, var_rank(i)
+ if (var_dimid(j,i) .ne. RECDIM) then ! skip record dim
+ start(j) = var_shape(j,i) + 1
+ err = nfmpi_put_vars_$1_all(ncid, i, start,
+ + edge, stride,
+ + value)
+ if (.not. canConvert) then
+ if (err .ne. NF_ECHAR)
+ + call errore('conversion: ', err)
+ else
+ if (err .ne. NF_EINVALCOORDS)
+ + call errore('bad start: ', err)
+ endif
+ start(j) = 1
+ edge(j) = var_shape(j,i) + 1
+ err = nfmpi_put_vars_$1_all(ncid, i, start,
+ + edge, stride,
+ + value)
+ if (.not. canConvert) then
+ if (err .ne. NF_ECHAR)
+ + call errore('conversion: ', err)
+ else
+ if (err .ne. NF_EEDGE)
+ + call errore('bad edge: ', err)
+ endif
+ edge(j) = 1
+ stride(j) = 0
+ err = nfmpi_put_vars_$1_all(ncid, i, start,
+ + edge, stride,
+ + value)
+ if (.not. canConvert) then
+ if (err .ne. NF_ECHAR)
+ + call errore('conversion: ', err)
+ else
+ if (err .ne. NF_ESTRIDE)
+ + call errore('bad stride: ', err)
+ endif
+ stride(j) = 1
+ end if
+3 continue
+ !/* Choose a random point dividing each dim into 2 parts */
+ !/* Put 2^rank (nslabs) slabs so defined */
+ nslabs = 1
+ do 4, j = 1, var_rank(i)
+ mid(j) = roll( var_shape(j,i) )
+ nslabs = nslabs * 2
+4 continue
+ !/* bits of k determine whether to put lower or upper part of dim */
+ !/* choose random stride from 1 to edge */
+ do 5, k = 1, nslabs
+ nstarts = 1
+ do 6, j = 1, var_rank(i)
+ if (mod(ud_shift(k-1, -(j-1)), 2) .eq. 1) then
+ start(j) = 1
+ edge(j) = mid(j)
+ else
+ start(j) = 1 + mid(j)
+ edge(j) = var_shape(j,i) - mid(j)
+ end if
+ if (edge(j) .gt. 0) then
+ stride(j) = 1+roll(edge(j))
+ else
+ stride(j) = 1
+ end if
+ sstride(j) = stride(j)
+ nstarts = nstarts * INT(stride(j))
+6 continue
+ do 7, m = 1, nstarts
+ err = index2indexes(m, var_rank(i), sstride, index)
+ if (err .ne. NF_NOERR)
+ + call error('error in index2indexes')
+ nels = 1
+ do 8, j = 1, var_rank(i)
+ count(j) = 1 + (edge(j) - index(j)) / stride(j)
+ nels = nels * int(count(j))
+ index(j) = index(j) + start(j) - 1
+8 continue
+ !/* Random choice of forward or backward */
+C/* TODO
+C if ( roll(2) ) {
+C for (j = 1 j .lt. var_rank(i) j++) {
+C index(j) += (count(j) - 1) * stride(j)
+C stride(j) = -stride(j)
+C }
+C }
+C*/
+ allInExtRange = .true.
+ do 9, j = 1, nels
+ err = index2indexes(j, var_rank(i), count,
+ + index2)
+ if (err .ne. NF_NOERR)
+ + call error('error in index2indexes')
+ do 10, d = 1, var_rank(i)
+ index2(d) = index(d) +
+ + (index2(d)-1) * stride(d)
+10 continue
+ val = hash_$1(var_type(i), var_rank(i),
+ + index2, NFT_ITYPE($1))
+ MAKE_TYPE2($1, VAR_ELEM($1, value, j), val)
+ val = ARITH3($1, value, j)
+ allInExtRange = allInExtRange .and.
+ + inRange3(val, var_type(i),
+ + NFT_ITYPE($1))
+9 continue
+ err = nfmpi_put_vars_$1_all(ncid, i, index,
+ + count, stride,
+ + value)
+ if (canConvert) then
+ if (allInExtRange) then
+ if (err .ne. NF_NOERR)
+ + call error(nfmpi_strerror(err))
+ else
+ if (err .ne. NF_ERANGE)
+ + call errore('range error: ', err)
+ end if
+ else
+ if (nels .gt. 0 .and. err .ne. NF_ECHAR)
+ + call errore('wrong type: ', err)
+ end if
+7 continue
+5 continue
+1 continue
+
+ err = nfmpi_close(ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_close: ', err)
+
+ call check_vars_$1(scratch)
+
+ err = nfmpi_delete(scratch, info)
+ if (err .ne. NF_NOERR)
+ + call errorc('delete of scratch file failed:',
+ + scratch)
+ end
+])dnl
+
+
+dnl since parallel-netcdf doesn't have varm type, we haven't completed the
+dnl parallel-netcdf-ification of these routines
+dnl TEST_NFMPI_PUT_VARM(TYPE)
+dnl
+define([TEST_NFMPI_PUT_VARM],dnl
+[dnl
+ subroutine test_nfmpi_put_varm_$1()
+ implicit none
+ include "pnetcdf.inc"
+#include "tests.inc"
+ integer index2indexes, roll
+ double precision hash_$1
+ logical inRange3
+
+ integer ncid
+ integer d
+ integer i
+ integer j
+ integer k
+ integer m
+ integer err, flags
+ integer nels
+ integer nslabs
+ integer nstarts !/* number of different starts */
+ integer*8 start(MAX_RANK)
+ integer*8 edge(MAX_RANK)
+ integer*8 index(MAX_RANK)
+ integer*8 index2(MAX_RANK)
+ integer*8 mid(MAX_RANK)
+ integer*8 count(MAX_RANK)
+ integer*8 sstride(MAX_RANK)
+ integer*8 stride(MAX_RANK)
+ integer*8 imap(MAX_RANK)
+ logical canConvert !/* Both text or both numeric */
+ logical allInExtRange !/* all values within external range? */
+ DATATYPE($1, value, (MAX_NELS))
+ doubleprecision val
+ integer ud_shift
+
+ flags = IOR(NF_CLOBBER, extra_flags)
+ err = nfmpi_create(comm, scratch, flags, info, ncid)
+ if (err .ne. NF_NOERR) then
+ call errore('nfmpi_create: ', err)
+ return
+ end if
+ call def_dims(ncid)
+ call def_vars(ncid)
+ err = nfmpi_enddef(ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_enddef: ', err)
+
+ do 1, i = 1, numVars
+ canConvert = (var_type(i) .eq. NF_CHAR) .eqv.
+ + (NFT_ITYPE($1) .eq. NFT_TEXT)
+ if (.not.(var_rank(i) .le. MAX_RANK))
+ + stop 'assert(var_rank(i) .le. MAX_RANK)'
+ if (.not.(var_nels(i) .le. MAX_NELS))
+ + stop 'assert(var_nels(i) .le. MAX_NELS)'
+ do 2, j = 1, var_rank(i)
+ start(j) = 1
+ edge(j) = 1
+ stride(j) = 1
+ imap(j) = 1
+2 continue
+ err = nfmpi_put_varm_$1_all(BAD_ID, i, start,
+ + edge, stride, imap,
+ + value)
+ if (err .ne. NF_EBADID)
+ + call errore('bad ncid: ', err)
+ err = nfmpi_put_varm_$1_all(ncid, BAD_VARID, start,
+ + edge, stride,
+ + imap, value)
+ if (err .ne. NF_ENOTVAR)
+ + call errore('bad var id: ', err)
+ do 3, j = 1, var_rank(i)
+ if (var_dimid(j,i) .ne. RECDIM) then !/* skip record dim */
+ start(j) = var_shape(j,i) + 1
+ err = nfmpi_put_varm_$1_all(ncid, i, start,
+ + edge, stride,
+ + imap, value)
+ if (.not. canConvert) then
+ if (err .ne. NF_ECHAR)
+ + call errore('conversion: ', err)
+ else
+ if (err .ne. NF_EINVALCOORDS)
+ + call errore('bad start: ', err)
+ endif
+ start(j) = 1
+ edge(j) = var_shape(j,i) + 1
+ err = nfmpi_put_varm_$1_all(ncid, i, start,
+ + edge, stride,
+ + imap, value)
+ if (.not. canConvert) then
+ if (err .ne. NF_ECHAR)
+ + call errore('conversion: ', err)
+ else
+ if (err .ne. NF_EEDGE)
+ + call errore('bad edge: ', err)
+ endif
+ edge(j) = 1
+ stride(j) = 0
+ err = nfmpi_put_varm_$1_all(ncid, i, start,
+ + edge, stride,
+ + imap, value)
+ if (.not. canConvert) then
+ if (err .ne. NF_ECHAR)
+ + call errore('conversion: ', err)
+ else
+ if (err .ne. NF_ESTRIDE)
+ + call errore('bad stride: ', err)
+ endif
+ stride(j) = 1
+ end if
+3 continue
+ !/* Choose a random point dividing each dim into 2 parts */
+ !/* Put 2^rank (nslabs) slabs so defined */
+ nslabs = 1
+ do 4, j = 1, var_rank(i)
+ mid(j) = roll( var_shape(j,i) )
+ nslabs = nslabs * 2
+4 continue
+ !/* bits of k determine whether to put lower or upper part of dim */
+ !/* choose random stride from 1 to edge */
+ do 5, k = 1, nslabs
+ nstarts = 1
+ do 6, j = 1, var_rank(i)
+ if (mod(ud_shift(k-1, -(j-1)), 2) .eq. 1) then
+ start(j) = 1
+ edge(j) = mid(j)
+ else
+ start(j) = 1 + mid(j)
+ edge(j) = var_shape(j,i) - mid(j)
+ end if
+ if (edge(j) .gt. 0) then
+ stride(j) = 1+roll(edge(j))
+ else
+ stride(j) = 1
+ end if
+ sstride(j) = stride(j)
+ nstarts = nstarts * INT(stride(j))
+6 continue
+ do 7, m = 1, nstarts
+ err = index2indexes(m, var_rank(i), sstride, index)
+ if (err .ne. NF_NOERR)
+ + call error('error in index2indexes')
+ nels = 1
+ do 8, j = 1, var_rank(i)
+ count(j) = 1 + (edge(j) - index(j)) / stride(j)
+ nels = nels * int(count(j))
+ index(j) = index(j) + start(j) - 1
+8 continue
+ !/* Random choice of forward or backward */
+C/* TODO
+C if ( roll(2) ) then
+C do 9, j = 1, var_rank(i)
+C index(j) = index(j) +
+C + (count(j) - 1) * stride(j)
+C stride(j) = -stride(j)
+C9 continue
+C end if
+C*/
+ if (var_rank(i) .gt. 0) then
+ imap(1) = 1
+ do 10, j = 2, var_rank(i)
+ imap(j) = imap(j-1) * count(j-1)
+10 continue
+ end if
+ allInExtRange = .true.
+ do 11 j = 1, nels
+ err = index2indexes(j, var_rank(i), count,
+ + index2)
+ if (err .ne. NF_NOERR)
+ + call error('error in index2indexes')
+ do 12, d = 1, var_rank(i)
+ index2(d) = index(d) +
+ + (index2(d)-1) * stride(d)
+12 continue
+ val = hash_$1(var_type(i),var_rank(i),
+ + index2, NFT_ITYPE($1))
+ MAKE_TYPE2($1, VAR_ELEM($1, value, j), val)
+ val = ARITH3($1, value, j)
+ allInExtRange = allInExtRange .and.
+ + inRange3(val, var_type(i),
+ + NFT_ITYPE($1))
+11 continue
+ err = nfmpi_put_varm_$1_all(ncid,i,index,count,
+ + stride,imap,
+ + value)
+ if (canConvert) then
+ if (allInExtRange) then
+ if (err .ne. NF_NOERR)
+ + call error(nfmpi_strerror(err))
+ else
+ if (err .ne. NF_ERANGE)
+ + call errore('range error: ', err)
+ end if
+ else
+ if (nels .gt. 0 .and. err .ne. NF_ECHAR)
+ + call errore('wrong type: ', err)
+ end if
+7 continue
+5 continue
+1 continue
+
+ err = nfmpi_close(ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_close: ', err)
+
+ call check_vars_$1(scratch)
+
+ err = nfmpi_delete(scratch, info)
+ if (err .ne. NF_NOERR)
+ + call errorc('delete of scratch file failed:',
+ + scratch)
+ end
+])dnl
+
+
+dnl TEST_NFMPI_PUT_ATT(TYPE) numeric only
+dnl
+define([TEST_NFMPI_PUT_ATT],dnl
+[dnl
+ subroutine test_nfmpi_put_att_$1()
+ implicit none
+ include "pnetcdf.inc"
+#include "tests.inc"
+ character*2 ATT_NAME
+ integer ATT_TYPE, NATTS, ATT_LEN
+ integer*8 ATT_LEN_LL
+ double precision hash_$1
+ logical inRange3
+
+ integer ncid
+ integer i
+ integer j
+ integer k
+ integer*8 ndx(1)
+ integer err, flags
+ DATATYPE($1, value, (MAX_NELS))
+ logical allInExtRange !/* all values within external range? */
+ doubleprecision val
+
+ flags = IOR(NF_NOCLOBBER, extra_flags)
+ err = nfmpi_create(comm, scratch, flags, info, ncid)
+ if (err .ne. NF_NOERR) then
+ call errore('nfmpi_create: ', err)
+ return
+ end if
+ call def_dims(ncid)
+ call def_vars(ncid)
+
+ do 1, i = 0, numVars
+ do 2, j = 1, NATTS(i)
+ if (.not.(ATT_TYPE(j,i) .eq. NF_CHAR)) then
+ ATT_LEN_LL = ATT_LEN(j,i)
+ if (.not.((ATT_LEN_LL .le. MAX_NELS)))
+ + stop 'assert(ATT_LEN_LL .le. MAX_NELS)'
+ err = nfmpi_put_att_$1(BAD_ID, i,
+ + ATT_NAME(j,i),
+ + ATT_TYPE(j,i),
+ + ATT_LEN_LL, value)
+ if (err .ne. NF_EBADID)
+ + call errore('bad ncid: ', err)
+ err = nfmpi_put_att_$1(ncid, BAD_VARID,
+ + ATT_NAME(j,i),
+ + ATT_TYPE(j,i), ATT_LEN_LL, value)
+ if (err .ne. NF_ENOTVAR)
+ + call errore('bad var id: ', err)
+ err = nfmpi_put_att_$1(ncid, i,
+ + ATT_NAME(j,i), BAD_TYPE,
+ + ATT_LEN_LL, value)
+ if (err .ne. NF_EBADTYPE)
+ + call errore('bad type: ', err)
+ allInExtRange = .true.
+ do 3, k = 1, int(ATT_LEN_LL)
+ ndx(1) = k
+ val = hash_$1(ATT_TYPE(j,i),
+ + -1, ndx, NFT_ITYPE($1))
+ MAKE_TYPE2($1, VAR_ELEM($1, value, k), val)
+ val = ARITH3($1, value, k)
+ allInExtRange = allInExtRange .and.
+ + inRange3(val, ATT_TYPE(j,i),
+ + NFT_ITYPE($1))
+3 continue
+ err = nfmpi_put_att_$1(ncid, i, ATT_NAME(j,i),
+ + ATT_TYPE(j,i), ATT_LEN_LL,
+ + value)
+ if (allInExtRange) then
+ if (err .ne. NF_NOERR)
+ + call error(nfmpi_strerror(err))
+ else
+ if (err .ne. NF_ERANGE)
+ + call errore('range error: ', err)
+ end if
+ end if
+2 continue
+1 continue
+
+ call check_atts_$1(ncid)
+ err = nfmpi_close(ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_close: ', err)
+
+ err = nfmpi_delete(scratch, info)
+ if (err .ne. NF_NOERR)
+ + call errorc('delete of scratch file failed:',
+ + scratch)
+ end
+])dnl
+
+divert(0)dnl
+dnl If you see this line, you can ignore the next one.
+C Do not edit this file. It is produced from the corresponding .m4 source */
+
+C********************************************************************
+C Copyright 1996, UCAR/Unidata
+C See netcdf/COPYRIGHT file for copying and redistribution conditions.
+C $Id: test_put.m4 2232 2015-12-16 22:16:52Z wkliao $
+C********************************************************************
+
+HASH(text)
+#ifdef NF_INT1_T
+HASH(int1)
+#endif
+#ifdef NF_INT2_T
+HASH(int2)
+#endif
+HASH(int)
+HASH(int8)
+HASH(real)
+HASH(double)
+
+CHECK_VARS(text)
+#ifdef NF_INT1_T
+CHECK_VARS(int1)
+#endif
+#ifdef NF_INT2_T
+CHECK_VARS(int2)
+#endif
+CHECK_VARS(int)
+CHECK_VARS(int8)
+CHECK_VARS(real)
+CHECK_VARS(double)
+
+CHECK_ATTS(text)
+#ifdef NF_INT1_T
+CHECK_ATTS(int1)
+#endif
+#ifdef NF_INT2_T
+CHECK_ATTS(int2)
+#endif
+CHECK_ATTS(int)
+CHECK_ATTS(int8)
+CHECK_ATTS(real)
+CHECK_ATTS(double)
+
+TEST_NFMPI_PUT_VAR1(text)
+#ifdef NF_INT1_T
+TEST_NFMPI_PUT_VAR1(int1)
+#endif
+#ifdef NF_INT2_T
+TEST_NFMPI_PUT_VAR1(int2)
+#endif
+TEST_NFMPI_PUT_VAR1(int)
+TEST_NFMPI_PUT_VAR1(int8)
+TEST_NFMPI_PUT_VAR1(real)
+TEST_NFMPI_PUT_VAR1(double)
+
+TEST_NFMPI_PUT_VAR(text)
+#ifdef NF_INT1_T
+TEST_NFMPI_PUT_VAR(int1)
+#endif
+#ifdef NF_INT2_T
+TEST_NFMPI_PUT_VAR(int2)
+#endif
+TEST_NFMPI_PUT_VAR(int)
+TEST_NFMPI_PUT_VAR(int8)
+TEST_NFMPI_PUT_VAR(real)
+TEST_NFMPI_PUT_VAR(double)
+
+TEST_NFMPI_PUT_VARA(text)
+#ifdef NF_INT1_T
+TEST_NFMPI_PUT_VARA(int1)
+#endif
+#ifdef NF_INT2_T
+TEST_NFMPI_PUT_VARA(int2)
+#endif
+TEST_NFMPI_PUT_VARA(int)
+TEST_NFMPI_PUT_VARA(int8)
+TEST_NFMPI_PUT_VARA(real)
+TEST_NFMPI_PUT_VARA(double)
+
+TEST_NFMPI_PUT_VARS(text)
+#ifdef NF_INT1_T
+TEST_NFMPI_PUT_VARS(int1)
+#endif
+#ifdef NF_INT2_T
+TEST_NFMPI_PUT_VARS(int2)
+#endif
+TEST_NFMPI_PUT_VARS(int)
+TEST_NFMPI_PUT_VARS(int8)
+TEST_NFMPI_PUT_VARS(real)
+TEST_NFMPI_PUT_VARS(double)
+
+TEST_NFMPI_PUT_VARM(text)
+#ifdef NF_INT1_T
+TEST_NFMPI_PUT_VARM(int1)
+#endif
+#ifdef NF_INT2_T
+TEST_NFMPI_PUT_VARM(int2)
+#endif
+TEST_NFMPI_PUT_VARM(int)
+TEST_NFMPI_PUT_VARM(int8)
+TEST_NFMPI_PUT_VARM(real)
+TEST_NFMPI_PUT_VARM(double)
+
+ subroutine test_nfmpi_put_att_text()
+ implicit none
+ include "pnetcdf.inc"
+#include "tests.inc"
+ character*2 ATT_NAME
+ integer ATT_TYPE, NATTS, ATT_LEN
+ integer*8 ATT_LEN_LL
+ double precision hash
+
+ integer ncid
+ integer i
+ integer j
+ integer*8 k
+ integer err, flags
+ character*MAX_NELS value
+
+ flags = IOR(NF_NOCLOBBER, extra_flags)
+ err = nfmpi_create(comm, scratch, flags, info, ncid)
+ if (err .ne. NF_NOERR) then
+ call errore('nfmpi_create: ', err)
+ return
+ end if
+ call def_dims(ncid)
+ call def_vars(ncid)
+
+ do 1, i = 0, numVars
+ do 2, j = 1, NATTS(i)
+ if (ATT_TYPE(j,i) .eq. NF_CHAR) then
+ ATT_LEN_LL = ATT_LEN(j,i)
+ if (.not.(ATT_LEN_LL .le. MAX_NELS))
+ + stop 'assert(ATT_LEN_LL .le. MAX_NELS)'
+ err = nfmpi_put_att_text(BAD_ID, i,
+ + ATT_NAME(j,i), ATT_LEN_LL, value)
+ if (err .ne. NF_EBADID)
+ + call errore('bad ncid: ', err)
+ err = nfmpi_put_att_text(ncid, BAD_VARID,
+ + ATT_NAME(j,i),
+ + ATT_LEN_LL, value)
+ if (err .ne. NF_ENOTVAR)
+ + call errore('bad var id: ', err)
+ do 3, k = 1, int(ATT_LEN_LL)
+ value(k:k) = char(int(hash(ATT_TYPE(j,i),
+ + -1, k)))
+3 continue
+ err = nfmpi_put_att_text(ncid, i, ATT_NAME(j,i),
+ + ATT_LEN_LL, value)
+ if (err .ne. NF_NOERR)
+ + call error(nfmpi_strerror(err))
+ end if
+2 continue
+1 continue
+
+ call check_atts_text(ncid)
+ err = nfmpi_close(ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_close: ', err)
+
+ err = nfmpi_delete(scratch, info)
+ if (err .ne. NF_NOERR)
+ + call errorc('delete of scratch file failed:',
+ + scratch)
+ end
+
+#ifdef NF_INT1_T
+TEST_NFMPI_PUT_ATT(int1)
+#endif
+#ifdef NF_INT2_T
+TEST_NFMPI_PUT_ATT(int2)
+#endif
+TEST_NFMPI_PUT_ATT(int)
+TEST_NFMPI_PUT_ATT(int8)
+TEST_NFMPI_PUT_ATT(real)
+TEST_NFMPI_PUT_ATT(double)
diff --git a/test/nf_test/test_read.F b/test/nf_test/test_read.F
new file mode 100644
index 0000000..b4355b6
--- /dev/null
+++ b/test/nf_test/test_read.F
@@ -0,0 +1,1437 @@
+C*********************************************************************
+C Copyright 1996, UCAR/Unidata
+C See netcdf/COPYRIGHT file for copying and redistribution conditions.
+C $Id: test_read.F 2296 2016-01-06 21:19:36Z wkliao $
+C*********************************************************************
+
+C Test nfmpi_strerror.
+C Try on a bad error status.
+C Test for each defined error status.
+C
+ subroutine test_nfmpi_strerror()
+ implicit none
+ include "pnetcdf.inc"
+#include "tests.inc"
+
+ integer MY_LEN_TRIM
+ integer number_of_messages
+ parameter (number_of_messages = 27)
+
+ integer i, msg_len
+ integer status(number_of_messages)
+ character*80 message, unknown_err_msg
+ character*80 msg(number_of_messages)
+ integer nok
+
+ data status(1) / NF_NOERR/
+ data status(2) / NF_EBADID /
+ data status(3) / NF_EEXIST /
+ data status(4) / NF_EINVAL /
+ data status(5) / NF_EPERM /
+ data status(6) / NF_ENOTINDEFINE /
+ data status(7) / NF_EINDEFINE /
+ data status(8) / NF_EINVALCOORDS /
+ data status(9) / NF_EMAXDIMS /
+ data status(10) / NF_ENAMEINUSE /
+ data status(11) / NF_ENOTATT /
+ data status(12) / NF_EMAXATTS /
+ data status(13) / NF_EBADTYPE /
+ data status(14) / NF_EBADDIM /
+ data status(15) / NF_EUNLIMPOS /
+ data status(16) / NF_EMAXVARS /
+ data status(17) / NF_ENOTVAR /
+ data status(18) / NF_EGLOBAL /
+ data status(19) / NF_ENOTNC /
+ data status(20) / NF_ESTS /
+ data status(21) / NF_EMAXNAME /
+ data status(22) / NF_EUNLIMIT /
+ data status(23) / NF_ENORECVARS /
+ data status(24) / NF_ECHAR /
+ data status(25) / NF_EEDGE /
+ data status(26) / NF_ESTRIDE /
+ data status(27) / NF_EBADNAME /
+
+ data msg(1) / 'No error' /
+ data msg(2) / 'NetCDF: Not a valid ID' /
+ data msg(3) / 'NetCDF: File exists && NC_NOCLOBBER' /
+ data msg(4) / 'NetCDF: Invalid argument' /
+ data msg(5) / 'NetCDF: Write to read only' /
+ data msg(6) / 'NetCDF: Operation not allowed in data mode' /
+ data msg(7) / 'NetCDF: Operation not allowed in define mode' /
+ data msg(8) / 'NetCDF: Index exceeds dimension bound' /
+ data msg(9) / 'NetCDF: NC_MAX_DIMS exceeded' /
+ data msg(10) / 'NetCDF: String match to name in use' /
+ data msg(11) / 'NetCDF: Attribute not found' /
+ data msg(12) / 'NetCDF: NC_MAX_ATTRS exceeded' /
+ data msg(13)
+ + / 'NetCDF: Not a valid data type or _FillValue type mismatch' /
+ data msg(14) / 'NetCDF: Invalid dimension ID or name' /
+ data msg(15) / 'NetCDF: NC_UNLIMITED in the wrong index' /
+ data msg(16) / 'NetCDF: NC_MAX_VARS exceeded' /
+ data msg(17) / 'NetCDF: Variable not found' /
+ data msg(18) / 'NetCDF: Action prohibited on NC_GLOBAL varid' /
+ data msg(19) / 'NetCDF: Unknown file format' /
+ data msg(20) / 'NetCDF: In Fortran, string too short' /
+ data msg(21) / 'NetCDF: NC_MAX_NAME exceeded' /
+ data msg(22) / 'NetCDF: NC_UNLIMITED size already in use' /
+ data msg(23)
+ + / 'NetCDF: nc_rec op when there are no record vars' /
+ data msg(24)
+ + /'NetCDF: Attempt to convert between text & numbers'/
+ data msg(25) / 'NetCDF: Start+count exceeds dimension bound' /
+ data msg(26) / 'NetCDF: Illegal stride' /
+ data msg(27) / 'NetCDF: Name contains illegal characters' /
+
+ nok = 0
+
+C /* Try on a bad error status */
+ message = nfmpi_strerror(-666)!/* should fail */
+C pnetcdf differs from serial netcdf in that we report the error
+C code along with the message.
+
+ unknown_err_msg = "Unknown Error"
+ msg_len = LEN(TRIM(unknown_err_msg))
+ if (message(1:msg_len) .ne. unknown_err_msg(1:msg_len)) then
+ call errorc('nfmpi_strerror on bad error status returned: ',
+ + message)
+ else
+ nok = nok + 1
+ endif
+
+C /* Try on each legitimate error status */
+ do 1, i=1, number_of_messages
+ message = nfmpi_strerror(status(i))
+ if (message .ne. msg(i)) then
+ call error('nfmpi_strerror() should return "'
+ + // msg(i) // '"')
+ else
+ nok = nok + 1
+ endif
+1 continue
+ call print_nok(nok)
+ end
+
+
+C Test nfmpi_open.
+C If in read-only section of tests,
+C Try to open a non-existent netCDF file, check error return.
+C Open a file that is not a netCDF file, check error return.
+C Open a netCDF file with a bad mode argument, check error return.
+C Open a netCDF file with NFMPI_NOWRITE mode, try to write, check error.
+C Try to open a netcdf twice, check whether returned netcdf ids different.
+C If in writable section of tests,
+C Open a netCDF file with NFMPI_WRITE mode, write something, close it.
+C On exit, any open netCDF files are closed.
+ subroutine test_nfmpi_open()
+ implicit none
+ include "pnetcdf.inc"
+#include "tests.inc"
+
+ integer err, flags
+ integer ncid
+ integer ncid2
+ integer nok
+
+ nok = 0
+
+! Try to open a nonexistent file, this call should fail
+ err = nfmpi_open(comm, 'tooth-fairy.nc', NF_NOWRITE, info, ncid)
+
+! On some systems, opening an nonexisting file will actually create the
+! file. In this case, we print the error messages on screen and move on
+! to the next test, instead of aborting the entire test.
+
+ if (err .eq. NF_NOERR) then
+ print*,
+ + 'opening a nonexistent file expects to fail, but got NF_NOERR'
+ elseif (err .ne. NF_ENOENT) then
+ print*,
+ + 'opening a nonexistent file expects NF_ENOENT, but got ',err
+ else
+C print*, "Expected error message complaining: "//
+C + "File tooth-fairy.nc does not exist"
+ nok = nok + 1
+ endif
+
+C /* Open a file that is not a netCDF file. */
+ err = nfmpi_open(comm, 'nf_test', NF_NOWRITE, info, ncid)!/* should fail */
+ if (err .ne. NF_ENOTNC .and. err .ne. NF_EOFILE) then
+ call errore('nfmpi_open of non-netCDF file: ', err)
+ else
+ nok = nok + 1
+ endif
+
+C /* Open a netCDF file in read-only mode, check that write fails */
+ err = nfmpi_open(comm, testfile, NF_NOWRITE, info, ncid)
+ if (err .ne. NF_NOERR) then
+ call errore('nfmpi_open: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nfmpi_redef(ncid) !/* should fail */
+ if (err .ne. NF_EPERM)
+ + call error('nfmpi_redef of read-only file should fail')
+C /* Opened OK, see if can open again and get a different netCDF ID */
+ err = nfmpi_open(comm, testfile, NF_NOWRITE, info, ncid2)
+ if (err .ne. NF_NOERR) then
+ call errore('nfmpi_open: ', err)
+ else
+ err = nfmpi_close(ncid2)
+ nok = nok + 1
+ end if
+ if (ncid2 .eq. ncid)
+ + call error(
+ + 'netCDF IDs for first and second
+ + nfmpi_open calls should differ')
+
+ if (.not. readonly) then !/* tests using netCDF scratch file */
+ flags = IOR(NF_NOCLOBBER, extra_flags)
+ err = nfmpi_create(comm, scratch, flags, info, ncid2)
+ if (err .ne. NF_NOERR) then
+ call errore('nfmpi_create: ', err)
+ else
+ err = nfmpi_close(ncid2)
+ end if
+ err = nfmpi_open(comm, scratch, NF_WRITE, info, ncid2)
+ if (err .ne. NF_NOERR) then
+ call errore('nfmpi_open: ', err)
+ else
+ err = nfmpi_close(ncid2)
+ nok = nok + 1
+ end if
+ err = nfmpi_delete(scratch, info)
+ if (err .ne. NF_NOERR)
+ + call errorc('delete of scratch file failed: ', scratch)
+ end if
+
+ err = nfmpi_close(ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_close: ', err)
+ call print_nok(nok)
+ end
+
+
+C
+C Test nfmpi_close.
+C Try to close a netCDF file twice, check whether second close fails.
+C Try on bad handle, check error return.
+C Try in define mode and data mode.
+C
+ subroutine test_nfmpi_close()
+ implicit none
+ include "pnetcdf.inc"
+#include "tests.inc"
+
+ integer ncid
+ integer err, flags
+ integer nok
+
+ nok = 0
+
+ err = nfmpi_open(comm, testfile, NF_NOWRITE, info, ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_open: ', err)
+
+C /* Close a netCDF file twice, second time should fail */
+ err = nfmpi_close(ncid)
+ if (err .ne. NF_NOERR) then
+ call errore('nfmpi_close failed: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nfmpi_close(ncid)
+ if (err .ne. NF_EBADID) then
+ call error('nfmpi_close of closed file should have failed')
+ else
+ nok = nok + 1
+ endif
+
+C /* Try with a bad netCDF ID */
+ err = nfmpi_close(BAD_ID)!/* should fail */
+ if (err .ne. NF_EBADID) then
+ call errore(
+ + 'nfmpi_close with bad netCDF ID returned wrong error: ',
+ + err)
+ else
+ nok = nok + 1
+ endif
+
+C /* Close in data mode */
+ err = nfmpi_open(comm, testfile, NF_NOWRITE, info, ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_open: ', err)
+ err = nfmpi_close(ncid)
+ if (err .ne. NF_NOERR) then
+ call errore('nfmpi_close in data mode failed: ', err)
+ else
+ nok = nok + 1
+ endif
+
+ if (.not. readonly) then !/* tests using netCDF scratch file */
+ flags = IOR(NF_NOCLOBBER, extra_flags)
+ err = nfmpi_create(comm, scratch, flags, info, ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_create: ', err)
+ err = nfmpi_close(ncid)
+ if (err .ne. NF_NOERR) then
+ call errore('nfmpi_close in define mode: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nfmpi_delete(scratch, info)
+ if (err .ne. NF_NOERR) then
+ call errorc('delete of scratch file failed: ',
+ + scratch)
+ else
+ nok = nok + 1
+ endif
+ end if
+ call print_nok(nok)
+ end
+
+
+C Test nfmpi_inq.
+C Try on bad handle, check error return.
+C Try in data mode, check returned values.
+C Try asking for subsets of info.
+C If in writable section of tests,
+C Try in define mode, after adding an unlimited dimension, variable.
+C On exit, any open netCDF files are closed.
+ subroutine test_nfmpi_inq()
+ implicit none
+ include "pnetcdf.inc"
+#include "tests.inc"
+
+ integer ncid
+ integer ncid2 !/* for scratch netCDF dataset */
+ integer ndims !/* number of dimensions */
+ integer nvars !/* number of variables */
+ integer ngatts !/* number of global attributes */
+ integer recdim !/* id of unlimited dimension */
+ integer err, flags
+ integer ndims0
+ integer nvars0
+ integer ngatts0
+ integer recdim0
+ integer did
+ integer vid
+ integer*8 length
+ integer VDIMS(1)
+ integer nok
+
+ nok = 0
+
+ err = nfmpi_open(comm, testfile, NF_NOWRITE, info, ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_open: ', err)
+
+C /* Try on bad handle */
+ err = nfmpi_inq(BAD_ID, ndims, nvars, ngatts, recdim)
+ if (err .ne. NF_EBADID) then
+ call errore('bad ncid: ', err)
+ else
+ nok = nok + 1
+ endif
+
+ err = nfmpi_inq(ncid, ndims, nvars, ngatts, recdim)
+ if (err .ne. NF_NOERR) then
+ call errore('nfmpi_inq: ', err)
+ else if (ndims .ne. NDIMS) then
+ call errori
+ + ('nfmpi_inq: wrong number of dimensions returned: ', ndims)
+ else if (nvars .ne. numVars) then
+ call errori
+ + ('nfmpi_inq: wrong number of variables returned: ', nvars)
+ else if (ngatts .ne. numGatts) then
+ call errori(
+ + 'nfmpi_inq: wrong number of global atts returned: ',
+ + ngatts)
+ else if (recdim .ne. RECDIM) then
+ call errori
+ + ('nfmpi_inq: wrong record dimension ID returned: ', recdim)
+ else
+ nok = nok + 1
+ end if
+
+ if (.not. readonly) then !/* tests using netCDF scratch file */
+ flags = IOR(NF_NOCLOBBER, extra_flags)
+ err = nfmpi_create(comm, scratch, flags, info, ncid2)
+ if (err .ne. NF_NOERR) then
+ call errore('nfmpi_create: ', err)
+ else !/* add dim, var, gatt, check inq */
+ err = nfmpi_enddef(ncid2) !/* enter data mode */
+ err = nfmpi_inq(ncid2, ndims0, nvars0,
+ + ngatts0, recdim0)
+ if (err .ne. NF_NOERR) then
+ call errore('nfmpi_inq: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nfmpi_redef(ncid2) !/* enter define mode */
+C /* Check that inquire still works in define mode */
+ err = nfmpi_inq(ncid2, ndims, nvars, ngatts, recdim)
+ if (err .ne. NF_NOERR) then
+ call errore('nfmpi_inq in define mode: ', err)
+ else if (ndims .ne. ndims0) then
+ call errori
+ + ('nfmpi_inq in define mode: ndims wrong, ', ndims)
+ else if (nvars .ne. nvars0) then
+ call errori
+ + ('nfmpi_inq in define mode: nvars wrong, ', nvars)
+ else if (ngatts .ne. ngatts0) then
+ call errori(
+ + 'nfmpi_inq in define mode: ngatts wrong, ', ngatts)
+ print *, ' expected ', ngatts0
+ else if (recdim .ne. recdim0) then
+ call errori
+ + ('nfmpi_inq in define mode: recdim wrong, ', recdim)
+ else
+ nok = nok + 1
+ end if
+
+C /* Add dim, var, global att */
+ length = 1
+ err = nfmpi_def_dim(ncid2, 'inqd', length, did)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_def_dim: ', err)
+ VDIMS(1) = 0
+ err = nfmpi_def_var(ncid2, 'inqv', NF_FLOAT,
+ + 0, VDIMS, vid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_def_var: ', err)
+
+ length = len('stuff')
+ err = nfmpi_put_att_text(ncid2, NF_GLOBAL, 'inqa',
+ + length, 'stuff')
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_put_att_text: ', err)
+
+C /* Make sure nfmpi_inq sees the additions while in define mode */
+ err = nfmpi_inq(ncid2, ndims, nvars, ngatts, recdim)
+ if (err .ne. NF_NOERR) then
+ call errore('nfmpi_inq in define mode: ', err)
+ else if (ndims .ne. ndims0 + 1) then
+ call errori
+ + ('nfmpi_inq in define mode: ndims wrong, ', ndims)
+ else if (nvars .ne. nvars0 + 1) then
+ call errori
+ + ('nfmpi_inq in define mode: nvars wrong, ', nvars)
+ else if (ngatts .ne. ngatts0 + 1) then
+ call errori
+ + ('nfmpi_inq in define mode: ngatts wrong, ', ngatts)
+ print *, ' expected (added attr)', ngatts0 + 1
+ else
+ nok = nok + 1
+ end if
+ err = nfmpi_enddef(ncid2)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_enddef: ', err)
+
+C /* Make sure nfmpi_inq stills sees additions in data mode */
+ err = nfmpi_inq(ncid2, ndims, nvars, ngatts, recdim)
+ if (err .ne. NF_NOERR) then
+ call errore('nfmpi_inq failed in data mode: ',err)
+ else if (ndims .ne. ndims0 + 1) then
+ call errori
+ + ('nfmpi_inq in define mode: ndims wrong, ', ndims)
+ else if (nvars .ne. nvars0 + 1) then
+ call errori
+ + ('nfmpi_inq in define mode: nvars wrong, ', nvars)
+ else if (ngatts .ne. ngatts0 + 1) then
+ call errori
+ + ('nfmpi_inq in define mode: ngatts wrong, ', ngatts)
+ else
+ nok = nok + 1
+ end if
+ err = nfmpi_close(ncid2)
+ err = nfmpi_delete(scratch, info)
+ if (err .ne. NF_NOERR)
+ + call errorc('delete of scratch file failed: ',
+ + scratch)
+ end if
+ end if
+
+ err = nfmpi_close(ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_close: ', err)
+ call print_nok(nok)
+ end
+
+
+ subroutine test_nfmpi_inq_natts()
+ implicit none
+ include "pnetcdf.inc"
+#include "tests.inc"
+
+ integer ncid
+ integer ngatts !/* number of global attributes */
+ integer err
+ integer nok
+
+ nok = 0
+
+ err = nfmpi_inq_natts(BAD_ID, ngatts)
+ if (err .ne. NF_EBADID) then
+ call errore('bad ncid: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nfmpi_open(comm, testfile, NF_NOWRITE, info, ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_open: ', err)
+ err = nfmpi_inq_natts(ncid, ngatts)
+ if (err .ne. NF_NOERR) then
+ call errore('nfmpi_inq_natts: ', err)
+ else if (ngatts .ne. numGatts) then
+ call errori
+ + ('nfmpi_inq_natts: wrong number of global atts returned, ',
+ + ngatts)
+ else
+ nok = nok + 1
+ end if
+ err = nfmpi_close(ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_close: ', err)
+ call print_nok(nok)
+ end
+
+
+ subroutine test_nfmpi_inq_ndims()
+ implicit none
+ include "pnetcdf.inc"
+#include "tests.inc"
+
+ integer ncid
+ integer ndims
+ integer err
+ integer nok
+
+ nok = 0
+
+ err = nfmpi_inq_ndims(BAD_ID, ndims)
+ if (err .ne. NF_EBADID) then
+ call errore('bad ncid: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nfmpi_open(comm, testfile, NF_NOWRITE, info, ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_open: ', err)
+ err = nfmpi_inq_ndims(ncid, ndims)
+ if (err .ne. NF_NOERR) then
+ call errore('nfmpi_inq_ndims: ', err)
+ else if (ndims .ne. NDIMS) then
+ call errori
+ + ('nfmpi_inq_ndims: wrong number returned, ', ndims)
+ else
+ nok = nok + 1
+ end if
+ err = nfmpi_close(ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_close: ', err)
+ call print_nok(nok)
+ end
+
+
+ subroutine test_nfmpi_inq_nvars()
+ implicit none
+ include "pnetcdf.inc"
+#include "tests.inc"
+
+ integer ncid
+ integer nvars
+ integer err
+ integer nok
+
+ nok = 0
+
+ err = nfmpi_inq_nvars(BAD_ID, nvars)
+ if (err .ne. NF_EBADID) then
+ call errore('bad ncid: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nfmpi_open(comm, testfile, NF_NOWRITE, info, ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_open: ', err)
+ err = nfmpi_inq_nvars(ncid, nvars)
+ if (err .ne. NF_NOERR) then
+ call errore('nfmpi_inq_nvars: ', err)
+ else if (nvars .ne. numVars) then
+ call errori
+ + ('nfmpi_inq_nvars: wrong number returned, ', nvars)
+ else
+ nok = nok + 1
+ end if
+ err = nfmpi_close(ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_close: ', err)
+ call print_nok(nok)
+ end
+
+
+ subroutine test_nfmpi_inq_unlimdim()
+ implicit none
+ include "pnetcdf.inc"
+#include "tests.inc"
+
+ integer ncid
+ integer unlimdim
+ integer err
+ integer nok
+
+ nok = 0
+
+ err = nfmpi_inq_unlimdim(BAD_ID, unlimdim)
+ if (err .ne. NF_EBADID) then
+ call errore('bad ncid: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nfmpi_open(comm, testfile, NF_NOWRITE, info, ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_open: ', err)
+ err = nfmpi_inq_unlimdim(ncid, unlimdim)
+ if (err .ne. NF_NOERR) then
+ call errore('nfmpi_inq_unlimdim: ', err)
+ else if (unlimdim .ne. RECDIM) then
+ call errori
+ + ('nfmpi_inq_unlimdim: wrong number returned, ', unlimdim)
+ print *, 'expected ', RECDIM
+ else
+ nok = nok + 1
+ end if
+ err = nfmpi_close(ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_close: ', err)
+ call print_nok(nok)
+ end
+
+
+ subroutine test_nfmpi_inq_dimid()
+ implicit none
+ include "pnetcdf.inc"
+#include "tests.inc"
+
+ integer ncid
+ integer dimid
+ integer i
+ integer err
+ integer nok
+
+ nok = 0
+
+ err = nfmpi_open(comm, testfile, NF_NOWRITE, info, ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_open: ', err)
+ err = nfmpi_inq_dimid(ncid, 'noSuch', dimid)
+ if (err .ne. NF_EBADDIM) then
+ call errore('bad dim name: ', err)
+ else
+ nok = nok + 1
+ endif
+ do 1, i = 1, NDIMS
+ err = nfmpi_inq_dimid(BAD_ID, dim_name(i), dimid)
+ if (err .ne. NF_EBADID) then
+ call errore('bad ncid: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nfmpi_inq_dimid(ncid, dim_name(i), dimid)
+ if (err .ne. NF_NOERR) then
+ call errore('nfmpi_inq_dimid: ', err)
+ else if (dimid .ne. i) then
+ call errori('expected ', i)
+ call errori('got ', dimid)
+ else
+ nok = nok + 1
+ end if
+1 continue
+ err = nfmpi_close(ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_close: ', err)
+ call print_nok(nok)
+ end
+
+
+ subroutine test_nfmpi_inq_dim()
+ implicit none
+ include "pnetcdf.inc"
+#include "tests.inc"
+
+ integer ncid
+ integer i
+ integer err
+ character*(NF_MAX_NAME) name
+ integer*8 length
+ integer intlen
+ integer nok
+
+ nok = 0
+
+ err = nfmpi_open(comm, testfile, NF_NOWRITE, info, ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_open: ', err)
+ do 1, i = 1, NDIMS
+ err = nfmpi_inq_dim(BAD_ID, i, name, length)
+ if (err .ne. NF_EBADID) then
+ call errore('bad ncid: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nfmpi_inq_dim(ncid, BAD_DIMID, name, length)
+ if (err .ne. NF_EBADDIM) then
+ call errore('bad dimid: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nfmpi_inq_dim(ncid, i, name, length)
+ if (err .ne. NF_NOERR) then
+ call errore('nfmpi_inq_dim: ', err)
+ else if (dim_name(i) .ne. name) then
+ call errorc('name unexpected: ', name)
+ print *, ' expected ', dim_name(i),' for the ',i,'entry'
+ else if (dim_len(i) .ne. length) then
+ intlen = int(length)
+ call errori('size unexpected: ', intlen)
+ else
+ nok = nok + 1
+ end if
+1 continue
+ err = nfmpi_close(ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_close: ', err)
+ call print_nok(nok)
+ end
+
+
+ subroutine test_nfmpi_inq_dimlen()
+ implicit none
+ include "pnetcdf.inc"
+#include "tests.inc"
+
+ integer ncid
+ integer i
+ integer err
+ integer*8 length
+ integer intlen
+ integer nok
+
+ nok = 0
+
+ err = nfmpi_open(comm, testfile, NF_NOWRITE, info, ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_open: ', err)
+ do 1, i = 1, NDIMS
+ err = nfmpi_inq_dimlen(BAD_ID, i, length)
+ if (err .ne. NF_EBADID) then
+ call errore('bad ncid: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nfmpi_inq_dimlen(ncid, BAD_DIMID, length)
+ if (err .ne. NF_EBADDIM)
+ + call errore('bad dimid: ', err)
+ err = nfmpi_inq_dimlen(ncid, i, length)
+ if (err .ne. NF_NOERR) then
+ call errore('nfmpi_inq_dimlen: ', err)
+ else if (dim_len(i) .ne. length) then
+ intlen = int(length)
+ call errori('size unexpected: ', intlen)
+ print *, 'expected ', dim_len(i),' for the ',i,'entry'
+ else
+ nok = nok + 1
+ end if
+1 continue
+ err = nfmpi_close(ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_close: ', err)
+ call print_nok(nok)
+ end
+
+
+ subroutine test_nfmpi_inq_dimname()
+ implicit none
+ include "pnetcdf.inc"
+#include "tests.inc"
+
+ integer ncid
+ integer i
+ integer err
+ character*(NF_MAX_NAME) name
+ integer nok
+
+ nok = 0
+
+ err = nfmpi_open(comm, testfile, NF_NOWRITE, info, ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_open: ', err)
+ do 1, i = 1, NDIMS
+ err = nfmpi_inq_dimname(BAD_ID, i, name)
+ if (err .ne. NF_EBADID) then
+ call errore('bad ncid: ', err)
+ else
+ nok = nok + 1
+ end if
+ err = nfmpi_inq_dimname(ncid, BAD_DIMID, name)
+ if (err .ne. NF_EBADDIM) then
+ call errore('bad dimid: ', err)
+ else
+ nok = nok + 1
+ end if
+ err = nfmpi_inq_dimname(ncid, i, name)
+ if (err .ne. NF_NOERR) then
+ call errore('nfmpi_inq_dimname: ', err)
+ else if (dim_name(i) .ne. name) then
+ call errorc('name unexpected: ', name)
+ else
+ nok = nok + 1
+ end if
+1 continue
+ err = nfmpi_close(ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_close: ', err)
+ call print_nok(nok)
+ end
+
+
+ subroutine test_nfmpi_inq_varid()
+ implicit none
+ include "pnetcdf.inc"
+#include "tests.inc"
+
+ integer ncid
+ integer vid
+ integer i
+ integer err
+ integer nok
+
+ nok = 0
+
+ err = nfmpi_open(comm, testfile, NF_NOWRITE, info, ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_open: ', err)
+
+ err = nfmpi_inq_varid(ncid, 'noSuch', vid)
+ if (err .ne. NF_ENOTVAR)
+ + call errore('bad ncid: ', err)
+
+ do 1, i = 1, numVars
+ err = nfmpi_inq_varid(BAD_ID, var_name(i), vid)
+ if (err .ne. NF_EBADID) then
+ call errore('bad ncid: ', err)
+ else
+ nok = nok + 1
+ end if
+ err = nfmpi_inq_varid(ncid, var_name(i), vid)
+ if (err .ne. NF_NOERR) then
+ call errore('nfmpi_inq_varid: ', err)
+ else if (vid .ne. i) then
+ call errori('varid unexpected: ', vid)
+ else
+ nok = nok + 1
+ endif
+1 continue
+
+ err = nfmpi_close(ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_close: ', err)
+ call print_nok(nok)
+ end
+
+
+ subroutine test_nfmpi_inq_var()
+ implicit none
+ include "pnetcdf.inc"
+#include "tests.inc"
+ logical int_vec_eq
+
+ integer ncid
+ integer i
+ integer err
+ character*(NF_MAX_NAME) name
+ integer datatype
+ integer ndims
+ integer dimids(MAX_RANK)
+ integer na
+ integer nok
+
+ nok = 0
+
+ err = nfmpi_open(comm, testfile, NF_NOWRITE, info, ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_open: ', err)
+ do 1, i = 1, numVars
+ err = nfmpi_inq_var(BAD_ID, i, name, datatype, ndims,
+ + dimids, na)
+ if (err .ne. NF_EBADID) then
+ call errore('bad ncid: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nfmpi_inq_var(ncid,BAD_VARID,name,datatype,ndims,
+ + dimids,na)
+ if (err .ne. NF_ENOTVAR) then
+ call errore('bad var id: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nfmpi_inq_var(ncid, i, name, datatype, ndims, dimids,
+ + na)
+ if (err .ne. NF_NOERR) then
+ call errore('nfmpi_inq_var: ', err)
+ else if (var_name(i) .ne. name) then
+ call errorc('name unexpected: ', name)
+ else if (var_type(i) .ne. datatype) then
+ call errori('type unexpected: ', datatype)
+ else if (var_rank(i) .ne. ndims) then
+ call errori('ndims expected: ', ndims)
+ else if (.not.int_vec_eq(var_dimid(1,i),dimids,ndims)) then
+ call error('unexpected dimid')
+ else if (var_natts(i) .ne. na) then
+ call errori('natts unexpected: ', na)
+ else
+ nok = nok + 1
+ end if
+1 continue
+ err = nfmpi_close(ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_close: ', err)
+ call print_nok(nok)
+ end
+
+
+ subroutine test_nfmpi_inq_vardimid()
+ implicit none
+ include "pnetcdf.inc"
+#include "tests.inc"
+ logical int_vec_eq
+
+ integer ncid
+ integer i
+ integer err
+ integer dimids(MAX_RANK)
+ integer nok
+
+ nok = 0
+
+ err = nfmpi_open(comm, testfile, NF_NOWRITE, info, ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_open: ', err)
+ do 1, i = 1, numVars
+ err = nfmpi_inq_vardimid(BAD_ID, i, dimids)
+ if (err .ne. NF_EBADID) then
+ call errore('bad ncid: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nfmpi_inq_vardimid(ncid, BAD_VARID, dimids)
+ if (err .ne. NF_ENOTVAR) then
+ call errore('bad var id: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nfmpi_inq_vardimid(ncid, i, dimids)
+ if (err .ne. NF_NOERR) then
+ call errore('nfmpi_inq_vardimid: ', err)
+ else if (.not.int_vec_eq(var_dimid(1,i), dimids,
+ + var_rank(i))) then
+ call error('unexpected dimid')
+ print *, ' for variable ', i
+ else
+ nok = nok + 1
+ end if
+1 continue
+ err = nfmpi_close(ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_close: ', err)
+ call print_nok(nok)
+ end
+
+
+ subroutine test_nfmpi_inq_varname()
+ implicit none
+ include "pnetcdf.inc"
+#include "tests.inc"
+
+ integer ncid
+ integer i
+ integer err
+ character*(NF_MAX_NAME) name
+ integer nok
+
+ nok = 0
+
+ err = nfmpi_open(comm, testfile, NF_NOWRITE, info, ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_open: ', err)
+ do 1, i = 1, numVars
+ err = nfmpi_inq_varname(BAD_ID, i, name)
+ if (err .ne. NF_EBADID) then
+ call errore('bad ncid: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nfmpi_inq_varname(ncid, BAD_VARID, name)
+ if (err .ne. NF_ENOTVAR) then
+ call errore('bad var id: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nfmpi_inq_varname(ncid, i, name)
+ if (err .ne. NF_NOERR) then
+ call errore('nfmpi_inq_varname: ', err)
+ else if (var_name(i) .ne. name) then
+ call errorc('name unexpected: ', name)
+ else
+ nok = nok + 1
+ end if
+1 continue
+ err = nfmpi_close(ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_close: ', err)
+ call print_nok(nok)
+ end
+
+
+ subroutine test_nfmpi_inq_varnatts()
+ implicit none
+ include "pnetcdf.inc"
+#include "tests.inc"
+ integer VARID, NATTS
+
+ integer ncid
+ integer i
+ integer err
+ integer na
+ integer nok
+
+ nok = 0
+
+ err = nfmpi_open(comm, testfile, NF_NOWRITE, info, ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_open: ', err)
+ do 1, i = 0, numVars ! start with global attributes
+ err = nfmpi_inq_varnatts(BAD_ID, i, na)
+ if (err .ne. NF_EBADID) then
+ call errore('bad ncid: ', err)
+ else
+ nok = nok + 1
+ end if
+ err = nfmpi_inq_varnatts(ncid, BAD_VARID, na)
+ if (err .ne. NF_ENOTVAR) then
+ call errore('bad var id: ', err)
+ else
+ nok = nok + 1
+ end if
+ err = nfmpi_inq_varnatts(ncid, VARID(i), na)
+ if (err .ne. NF_NOERR) then
+ call errore('nfmpi_inq_varnatts: ', err)
+ else if (NATTS(i) .ne. na) then ! works for global attributes
+ call errori('natts unexpected: ', na)
+ else
+ nok = nok + 1
+ end if
+1 continue
+ err = nfmpi_close(ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_close: ', err)
+ call print_nok(nok)
+ end
+
+
+ subroutine test_nfmpi_inq_varndims()
+ implicit none
+ include "pnetcdf.inc"
+#include "tests.inc"
+
+ integer ncid
+ integer i
+ integer err
+ integer ndims
+ integer nok
+
+ nok = 0
+
+ err = nfmpi_open(comm, testfile, NF_NOWRITE, info, ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_open: ', err)
+ do 1, i = 1, numVars
+ err = nfmpi_inq_varndims(BAD_ID, i, ndims)
+ if (err .ne. NF_EBADID) then
+ call errore('bad ncid: ', err)
+ else
+ nok = nok + 1
+ end if
+ err = nfmpi_inq_varndims(ncid, BAD_VARID, ndims)
+ if (err .ne. NF_ENOTVAR) then
+ call errore('bad var id: ', err)
+ else
+ nok = nok + 1
+ end if
+ err = nfmpi_inq_varndims(ncid, i, ndims)
+ if (err .ne. NF_NOERR) then
+ call errore('nfmpi_inq_varndims: ', err)
+ else if (var_rank(i) .ne. ndims) then
+ call errori('ndims unexpected: ', ndims)
+ else
+ nok = nok + 1
+ end if
+1 continue
+ err = nfmpi_close(ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_close: ', err)
+ call print_nok(nok)
+ end
+
+
+ subroutine test_nfmpi_inq_vartype()
+ implicit none
+ include "pnetcdf.inc"
+#include "tests.inc"
+
+ integer ncid
+ integer i
+ integer err
+ integer datatype
+ integer nok
+
+ nok = 0
+
+ err = nfmpi_open(comm, testfile, NF_NOWRITE, info, ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_open: ', err)
+ do 1, i = 1, numVars
+ err = nfmpi_inq_vartype(BAD_ID, i, datatype)
+ if (err .ne. NF_EBADID) then
+ call errore('bad ncid: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nfmpi_inq_vartype(ncid, BAD_VARID, datatype)
+ if (err .ne. NF_ENOTVAR) then
+ call errore('bad var id: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nfmpi_inq_vartype(ncid, i, datatype)
+ if (err .ne. NF_NOERR) then
+ call errore('nfmpi_inq_vartype: ', err)
+ else if (var_type(i) .ne. datatype) then
+ call errori('type unexpected: ', datatype)
+ nok = nok + 1
+ end if
+1 continue
+ err = nfmpi_close(ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_close: ', err)
+ call print_nok(nok)
+ end
+
+
+ subroutine test_nfmpi_inq_att()
+ implicit none
+ include "pnetcdf.inc"
+#include "tests.inc"
+ character*2 ATT_NAME
+ integer ATT_TYPE, NATTS, ATT_LEN
+
+ integer ncid
+ integer i
+ integer j
+ integer err
+ integer t
+ integer*8 n
+ integer nok
+
+ nok = 0
+
+ err = nfmpi_open(comm, testfile, NF_NOWRITE, info, ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_open: ', err)
+
+ do 1, i = 0, numVars
+ do 2, j = 1, NATTS(i)
+ err = nfmpi_inq_att(BAD_ID, i, ATT_NAME(j,i), t, n)
+ if (err .ne. NF_EBADID) then
+ call errore('bad ncid: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nfmpi_inq_att
+ + (ncid, BAD_VARID, ATT_NAME(j,i), t, n)
+ if (err .ne. NF_ENOTVAR) then
+ call errore('bad var id: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nfmpi_inq_att(ncid, i, 'noSuch', t, n)
+ if (err .ne. NF_ENOTATT) then
+ call errore('Bad attribute name: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nfmpi_inq_att(ncid, i, ATT_NAME(j,i), t, n)
+ if (err .ne. NF_NOERR) then
+ call error(nfmpi_strerror(err))
+ else
+ if (t .ne. ATT_TYPE(j,i))
+ + call error('type not that expected')
+ if (n .ne. ATT_LEN(j,i))
+ + call error('length not that expected')
+ nok = nok + 1
+ end if
+2 continue
+1 continue
+
+ err = nfmpi_close(ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_close: ', err)
+ call print_nok(nok)
+ end
+
+
+ subroutine test_nfmpi_inq_attlen()
+ implicit none
+ include "pnetcdf.inc"
+#include "tests.inc"
+ character*2 ATT_NAME
+ integer NATTS, ATT_LEN
+
+ integer ncid
+ integer i
+ integer j
+ integer err
+ integer*8 len
+ integer nok
+
+ nok = 0
+
+ err = nfmpi_open(comm, testfile, NF_NOWRITE, info, ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_open: ', err)
+
+ do 1, i = 0, numVars
+ err = nfmpi_inq_attlen(ncid, i, 'noSuch', len)
+ if (err .ne. NF_ENOTATT) then
+ call errore('Bad attribute name: ', err)
+ else
+ nok = nok + 1
+ endif
+ do 2, j = 1, NATTS(i)
+ err = nfmpi_inq_attlen(BAD_ID, i,
+ + ATT_NAME(j,i), len)
+ if (err .ne. NF_EBADID) then
+ call errore('bad ncid: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nfmpi_inq_attlen
+ + (ncid, BAD_VARID, ATT_NAME(j,i), len)
+ if (err .ne. NF_ENOTVAR) then
+ call errore('bad varid: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nfmpi_inq_attlen(ncid, i, ATT_NAME(j,i), len)
+ if (err .ne. NF_NOERR) then
+ call error(nfmpi_strerror(err))
+ else
+ if (len .ne. ATT_LEN(j,i))
+ + call error('len not that expected')
+ nok = nok + 1
+ end if
+2 continue
+1 continue
+
+ err = nfmpi_close(ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_close: ', err)
+ call print_nok(nok)
+ end
+
+
+ subroutine test_nfmpi_inq_atttype()
+ implicit none
+ include "pnetcdf.inc"
+#include "tests.inc"
+ character*2 ATT_NAME
+ integer ATT_TYPE, NATTS
+
+ integer ncid
+ integer i
+ integer j
+ integer err
+ integer datatype
+ integer nok
+
+ nok = 0
+
+ err = nfmpi_open(comm, testfile, NF_NOWRITE, info, ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_open: ', err)
+
+ do 1, i = 0, numVars
+ err = nfmpi_inq_atttype(ncid, i, 'noSuch', datatype)
+ if (err .ne. NF_ENOTATT) then
+ call errore('Bad attribute name: ', err)
+ else
+ nok = nok + 1
+ endif
+ do 2, j = 1, NATTS(i)
+ err = nfmpi_inq_atttype
+ + (BAD_ID, i, ATT_NAME(j,i), datatype)
+ if (err .ne. NF_EBADID) then
+ call errore('bad ncid: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nfmpi_inq_atttype(ncid, BAD_VARID, ATT_NAME(j,i),
+ + datatype)
+ if (err .ne. NF_ENOTVAR) then
+ call errore('bad varid: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nfmpi_inq_atttype
+ + (ncid, i, ATT_NAME(j,i), datatype)
+ if (err .ne. NF_NOERR) then
+ call error(nfmpi_strerror(err))
+ else
+ if (datatype .ne. ATT_TYPE(j,i))
+ + call error('type not that expected')
+ nok = nok + 1
+ end if
+2 continue
+1 continue
+
+ err = nfmpi_close(ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_close: ', err)
+ call print_nok(nok)
+ end
+
+
+ subroutine test_nfmpi_inq_attname()
+ implicit none
+ include "pnetcdf.inc"
+#include "tests.inc"
+ character*2 ATT_NAME
+ integer NATTS
+
+ integer ncid
+ integer i
+ integer j
+ integer err
+ character*(NF_MAX_NAME) name
+ integer nok
+
+ nok = 0
+
+ err = nfmpi_open(comm, testfile, NF_NOWRITE, info, ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_open: ', err)
+
+ do 1, i = 0, numVars
+ err = nfmpi_inq_attname(ncid, i, BAD_ATTNUM, name)
+ if (err .ne. NF_ENOTATT) then
+ call errore('Bad attribute number: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nfmpi_inq_attname(ncid, i, NATTS(i)+1, name)
+ if (err .ne. NF_ENOTATT) then
+ call errore('Bad attribute number: ', err)
+ else
+ nok = nok + 1
+ endif
+ do 2, j = 1, NATTS(i)
+ err = nfmpi_inq_attname(BAD_ID, i, j, name)
+ if (err .ne. NF_EBADID) then
+ call errore('bad ncid: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nfmpi_inq_attname(ncid, BAD_VARID, j, name)
+ if (err .ne. NF_ENOTVAR) then
+ call errore('bad var id: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nfmpi_inq_attname(ncid, i, j, name)
+ if (err .ne. NF_NOERR) then
+ call error(nfmpi_strerror(err))
+ else
+ if (ATT_NAME(j,i) .ne. name)
+ + call error('name not that expected')
+ nok = nok + 1
+ end if
+2 continue
+1 continue
+
+ err = nfmpi_close(ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_close: ', err)
+ call print_nok(nok)
+ end
+
+
+ subroutine test_nfmpi_inq_attid()
+ implicit none
+ include "pnetcdf.inc"
+#include "tests.inc"
+ character*2 ATT_NAME
+ integer NATTS
+
+ integer ncid
+ integer i
+ integer j
+ integer err
+ integer attnum
+ integer nok
+
+ nok = 0
+
+ err = nfmpi_open(comm, testfile, NF_NOWRITE, info, ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_open: ', err)
+
+ do 1, i = 0, numVars
+ err = nfmpi_inq_attid(ncid, i, 'noSuch', attnum)
+ if (err .ne. NF_ENOTATT) then
+ call errore('Bad attribute name: ', err)
+ else
+ nok = nok + 1
+ endif
+ do 2, j = 1, NATTS(i)
+ err = nfmpi_inq_attid(BAD_ID, i,
+ + ATT_NAME(j,i), attnum)
+ if (err .ne. NF_EBADID) then
+ call errore('bad ncid: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nfmpi_inq_attid(ncid, BAD_VARID, ATT_NAME(j,i),
+ + attnum)
+ if (err .ne. NF_ENOTVAR) then
+ call errore('bad varid: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nfmpi_inq_attid(ncid, i,
+ + ATT_NAME(j,i), attnum)
+ if (err .ne. NF_NOERR) then
+ call error(nfmpi_strerror(err))
+ else
+ if (attnum .ne. j)
+ + call error('attnum not that expected')
+ nok = nok + 1
+ end if
+2 continue
+1 continue
+
+ err = nfmpi_close(ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_close: ', err)
+ call print_nok(nok)
+ end
diff --git a/test/nf_test/test_write.F b/test/nf_test/test_write.F
new file mode 100644
index 0000000..92ced17
--- /dev/null
+++ b/test/nf_test/test_write.F
@@ -0,0 +1,1740 @@
+C********************************************************************
+C Copyright 1996, UCAR/Unidata
+C See netcdf/COPYRIGHT file for copying and redistribution conditions.
+C $Id: test_write.F 2224 2015-12-16 06:10:36Z wkliao $
+C********************************************************************
+
+
+C Test nfmpi_create
+C For mode in NF_NOCLOBBER, NF_CLOBBER do:
+C create netcdf file 'scratch.nc' with no data, close it
+C test that it can be opened, do nfmpi_inq to check nvars = 0, etc.
+C Try again in NF_NOCLOBBER mode, check error return
+C On exit, delete this file
+ subroutine test_nfmpi_create()
+ implicit none
+ include "pnetcdf.inc"
+#include "tests.inc"
+
+ integer clobber !/* 0 for NF_NOCLOBBER, 1 for NF_CLOBBER */
+ integer err
+ integer ncid
+ integer ndims !/* number of dimensions */
+ integer nvars !/* number of variables */
+ integer ngatts !/* number of global attributes */
+ integer recdim !/* id of unlimited dimension */
+ integer flags
+ integer nok
+
+ flags = IOR(NF_NOCLOBBER, extra_flags)
+ nok = 0
+ do 1, clobber = 0, 1
+ err = nfmpi_create(comm, scratch, flags, info, ncid)
+ if (err .ne. NF_NOERR) then
+ call errore('nfmpi_create: ', err)
+ end if
+ nok = nok + 1
+ err = nfmpi_close(ncid)
+ if (err .ne. NF_NOERR) then
+ call errore('nfmpi_close: ', err)
+ end if
+ err = nfmpi_open(comm, scratch, NF_NOWRITE, info, ncid)
+ if (err .ne. NF_NOERR) then
+ call errore('nfmpi_open: ', err)
+ end if
+ err = nfmpi_inq(ncid, ndims, nvars, ngatts, recdim)
+ if (err .ne. NF_NOERR) then
+ call errore('nfmpi_inq: ', err)
+ else if (ndims .ne. 0) then
+ call errori(
+ + 'nfmpi_inq: wrong number of dimensions returned, ',
+ + ndims)
+ else if (nvars .ne. 0) then
+ call errori(
+ + 'nfmpi_inq: wrong number of variables returned, ',
+ + nvars)
+ else if (ngatts .ne. 0) then
+ call errori(
+ + 'nfmpi_inq: wrong number of global atts returned, ',
+ + ngatts)
+ else if (recdim .ge. 1) then
+ call errori(
+ + 'nfmpi_inq: wrong record dimension ID returned, ',
+ + recdim)
+ end if
+ err = nfmpi_close(ncid)
+ if (err .ne. NF_NOERR) then
+ call errore('nfmpi_close: ', err)
+ end if
+
+ flags = IOR(NF_CLOBBER, extra_flags)
+1 continue
+
+ flags = IOR(NF_NOCLOBBER, extra_flags)
+ err = nfmpi_create(comm, scratch, flags, info, ncid)
+ if (err .ne. NF_EEXIST) then
+ call errore('attempt to overwrite file: ', err)
+ end if
+ nok = nok + 1
+ err = nfmpi_delete(scratch, info)
+ if (err .ne. NF_NOERR) then
+ call errori('delete of scratch file failed: ', err)
+ end if
+ call print_nok(nok)
+ end
+
+
+C Test nfmpi_redef
+C (In fact also tests nfmpi_enddef - called from test_nfmpi_enddef)
+C BAD_ID
+C attempt redef (error) & enddef on read-only file
+C create file, define dims & vars.
+C attempt put var (error)
+C attempt redef (error) & enddef.
+C put vars
+C attempt def new dims (error)
+C redef
+C def new dims, vars.
+C put atts
+C enddef
+C put vars
+C close
+C check file: vars & atts
+ subroutine test_nfmpi_redef()
+ implicit none
+ include "pnetcdf.inc"
+#include "tests.inc"
+ integer title_len
+ parameter (title_len = 9)
+
+ integer ncid !/* netcdf id */
+ integer dimid !/* dimension id */
+ integer vid !/* variable id */
+ integer err
+ character*(title_len) title
+ doubleprecision var
+ character*(NF_MAX_NAME) name
+ integer*8 start(1)
+ integer*8 length
+ integer intlen
+ integer dimids(1)
+ integer nok, flags
+ nok = 0
+
+ title = 'Not funny'
+
+C /* BAD_ID tests */
+ err = nfmpi_redef(BAD_ID)
+ if (err .ne. NF_EBADID) then
+ call errore('bad ncid: ', err)
+ endif
+ nok = nok + 1
+ err = nfmpi_enddef(BAD_ID)
+ if (err .ne. NF_EBADID) then
+ call errore('bad ncid: ', err)
+ endif
+ nok = nok + 1
+
+C /* read-only tests */
+ err = nfmpi_open(comm, testfile, NF_NOWRITE, info, ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_open: ', err)
+ err = nfmpi_redef(ncid)
+ if (err .ne. NF_EPERM) then
+ call errore('nfmpi_redef in NF_NOWRITE mode: ', err)
+ endif
+ nok = nok + 1
+ err = nfmpi_enddef(ncid)
+ if (err .ne. NF_ENOTINDEFINE) then
+ call errore('nfmpi_redef in NF_NOWRITE mode: ', err)
+ endif
+ nok = nok + 1
+ err = nfmpi_close(ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_close: ', err)
+
+C /* tests using scratch file */
+ flags = IOR(NF_NOCLOBBER, extra_flags)
+ err = nfmpi_create(comm, scratch, flags, info, ncid)
+ if (err .ne. NF_NOERR) then
+ call errore('nfmpi_create: ', err)
+ return
+ end if
+ call def_dims(ncid)
+ call def_vars(ncid)
+ call put_atts(ncid)
+ err = nfmpi_inq_varid(ncid, 'd', vid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_inq_varid: ', err)
+ var = 1.0
+c should not enter indep mode in define mode
+ err = nfmpi_begin_indep_data(ncid)
+ if (err .ne. NF_EINDEFINE)
+ + call errore('nfmpi_begin_indep_data... in define mode: ', err)
+ start(1) = 0
+ err = nfmpi_put_var1_double(ncid, vid, start, var)
+ if (err .ne. NF_EINDEFINE)
+ + call errore('nfmpi_put_var... in define mode: ', err)
+ err = nfmpi_end_indep_data(ncid)
+ if (err .ne. NF_ENOTINDEP)
+ + call errore('nfmpi_end_indep_data... not in indep mode: ',err)
+ err = nfmpi_redef(ncid)
+ if (err .ne. NF_EINDEFINE) then
+ call errore('nfmpi_redef in define mode: ', err)
+ endif
+ nok = nok + 1
+ err = nfmpi_enddef(ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_enddef: ', err)
+ call put_vars(ncid)
+ length = 8
+ err = nfmpi_def_dim(ncid, 'abc', length, dimid)
+ if (err .ne. NF_ENOTINDEFINE)
+ + call errore('nfmpi_def_dim in define mode: ', err)
+ err = nfmpi_redef(ncid)
+ if (err .ne. NF_NOERR) then
+ call errore('nfmpi_redef: ', err)
+ endif
+ nok = nok + 1
+ length = 8
+ err = nfmpi_def_dim(ncid, 'abc', length, dimid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_def_dim: ', err)
+ dimids(1) = 0
+ err = nfmpi_def_var(ncid, 'abc', NF_INT, 0, dimids, vid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_def_var: ', err)
+ length = len(title)
+ err = nfmpi_put_att_text(ncid, NF_GLOBAL, 'title', length,
+ + title)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_put_att_text: ', err)
+ err = nfmpi_enddef(ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_enddef: ', err)
+ var = 1.0
+ err = nfmpi_end_indep_data(ncid)
+ if (err .ne. NF_ENOTINDEP)
+ + call errore('nfmpi_end_indep_data: in collective mode: ',err)
+ err = nfmpi_begin_indep_data(ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_begin_indep_data: ', err)
+ err = nfmpi_put_var1_double(ncid, vid, start, var)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_put_var1_double: ', err)
+ err = nfmpi_end_indep_data(ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_end_indep_data: ', err)
+ err = nfmpi_close(ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_close: ', err)
+
+C /* check scratch file written as expected */
+ call check_file(scratch)
+ err = nfmpi_open(comm, scratch, NF_NOWRITE, info, ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_open: ', err)
+ err = nfmpi_inq_dim(ncid, dimid, name, length)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_inq_dim: ', err)
+ if (name .ne. "abc")
+ + call errori('Unexpected dim name in netCDF ', ncid)
+ if (length .ne. 8) then
+ intlen = int(length)
+ call errori('Unexpected dim length: ', intlen)
+ end if
+ err = nfmpi_begin_indep_data(ncid)
+ err = nfmpi_get_var1_double(ncid, vid, start, var)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_get_var1_double: ', err)
+ if (var .ne. 1.0)
+ + call errori(
+ + 'nfmpi_get_var1_double: unexpected value in netCDF '
+ + , ncid)
+ err = nfmpi_end_indep_data(ncid)
+ err = nfmpi_close(ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_close: ', err)
+
+ err = nfmpi_delete(scratch, info)
+ if (err .ne. NF_NOERR)
+ + call errori('delete failed for netCDF: ', err)
+ call print_nok(nok)
+ end
+
+C Test nfmpi_enddef
+C Simply calls test_nfmpi_redef which tests both nfmpi_redef & nfmpi_enddef
+
+ subroutine test_nfmpi_enddef()
+ implicit none
+ include "pnetcdf.inc"
+#include "tests.inc"
+
+ call test_nfmpi_redef
+ end
+
+
+C Test nfmpi_sync
+C try with bad handle, check error
+C try in define mode, check error
+C try writing with one handle, reading with another on same netCDF
+ subroutine test_nfmpi_sync()
+ implicit none
+ include "pnetcdf.inc"
+#include "tests.inc"
+
+ integer ncidw !/* netcdf id for writing */
+ integer ncidr !/* netcdf id for reading */
+ integer err
+ integer nok, flags
+
+ nok = 0
+C /* BAD_ID test */
+ err = nfmpi_sync(BAD_ID)
+ if (err .ne. NF_EBADID) then
+ call errore('bad ncid: ', err)
+ else
+ nok = nok + 1
+ endif
+
+C /* create scratch file & try nfmpi_sync in define mode */
+ flags = IOR(NF_NOCLOBBER, extra_flags)
+ err = nfmpi_create(comm, scratch, flags, info, ncidw)
+ if (err .ne. NF_NOERR) then
+ call errore('nfmpi_create: ', err)
+ return
+ end if
+ err = nfmpi_sync(ncidw)
+ if (err .ne. NF_EINDEFINE) then
+ call errore('nfmpi_sync called in define mode: ', err)
+ else
+ nok = nok + 1
+ endif
+
+C /* write using same handle */
+ call def_dims(ncidw)
+ call def_vars(ncidw)
+ call put_atts(ncidw)
+ err = nfmpi_enddef(ncidw)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_enddef: ', err)
+ call put_vars(ncidw)
+ err = nfmpi_sync(ncidw)
+ if (err .ne. NF_NOERR) then
+ call errore('nfmpi_sync of ncidw failed: ', err)
+ else
+ nok = nok + 1
+ endif
+
+C /* open another handle, nfmpi_sync, read (check) */
+ err = nfmpi_open(comm, scratch, NF_NOWRITE, info, ncidr)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_open: ', err)
+ err = nfmpi_sync(ncidr)
+ if (err .ne. NF_NOERR) then
+ call errore('nfmpi_sync of ncidr failed: ', err)
+ else
+ nok = nok + 1
+ endif
+ call check_dims(ncidr)
+ call check_atts(ncidr)
+ call check_vars(ncidr)
+
+C /* close both handles */
+ err = nfmpi_close(ncidr)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_close: ', err)
+ err = nfmpi_close(ncidw)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_close: ', err)
+
+ err = nfmpi_delete(scratch, info)
+ if (err .ne. NF_NOERR)
+ + call errori('delete of scratch file failed: ', err)
+ call print_nok(nok)
+ end
+
+
+C Test nfmpi_abort
+C try with bad handle, check error
+C try in define mode before anything written, check that file was deleted
+C try after nfmpi_enddef, nfmpi_redef, define new dims, vars, atts
+C try after writing variable
+ subroutine test_nfmpi_abort()
+ implicit none
+ include "pnetcdf.inc"
+#include "tests.inc"
+
+ integer ncid !/* netcdf id */
+ integer err
+ integer ndims
+ integer nvars
+ integer ngatts
+ integer recdim
+ integer nok, flags
+
+ nok = 0
+
+C /* BAD_ID test */
+ err = nfmpi_abort(BAD_ID)
+ if (err .ne. NF_EBADID) then
+ call errore('bad ncid: status = ', err)
+ else
+ nok = nok + 1
+ endif
+
+C /* create scratch file & try nfmpi_abort in define mode */
+ flags = IOR(NF_NOCLOBBER, extra_flags)
+ err = nfmpi_create(comm, scratch, flags, info, ncid)
+ if (err .ne. NF_NOERR) then
+ call errore('nfmpi_create: ', err)
+ return
+ end if
+ call def_dims(ncid)
+ call def_vars(ncid)
+ call put_atts(ncid)
+ err = nfmpi_abort(ncid)
+ if (err .ne. NF_NOERR) then
+ call errore('nfmpi_abort of ncid failed: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nfmpi_close(ncid) !/* should already be closed */
+ if (err .ne. NF_EBADID)
+ + call errore('bad ncid: ', err)
+ err = nfmpi_delete(scratch, info) !/* should already be deleted */
+ if (err .eq. NF_NOERR)
+ + call errori('scratch file should not exist: ', err)
+
+C create scratch file
+C do nfmpi_enddef & nfmpi_redef
+C define new dims, vars, atts
+C try nfmpi_abort: should restore previous state (no dims, vars, atts)
+ flags = IOR(NF_NOCLOBBER, extra_flags)
+ err = nfmpi_create(comm, scratch, flags, info, ncid)
+ if (err .ne. NF_NOERR) then
+ call errore('nfmpi_create: ', err)
+ return
+ end if
+ err = nfmpi_enddef(ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_enddef: ', err)
+ err = nfmpi_redef(ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_redef: ', err)
+ call def_dims(ncid)
+ call def_vars(ncid)
+ call put_atts(ncid)
+ err = nfmpi_abort(ncid)
+ if (err .ne. NF_NOERR) then
+ call errore('nfmpi_abort of ncid failed: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nfmpi_close(ncid) !/* should already be closed */
+ if (err .ne. NF_EBADID)
+ + call errore('bad ncid: ', err)
+ err = nfmpi_open(comm, scratch, NF_NOWRITE, info, ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_open: ', err)
+ err = nfmpi_inq (ncid, ndims, nvars, ngatts, recdim)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_inq: ', err)
+ if (ndims .ne. 0)
+ + call errori('ndims should be ', 0)
+ if (nvars .ne. 0)
+ + call errori('nvars should be ', 0)
+ if (ngatts .ne. 0)
+ + call errori('ngatts should be ', 0)
+ err = nfmpi_close (ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_close: ', err)
+
+C /* try nfmpi_abort in data mode - should just close */
+ flags = IOR(NF_CLOBBER, extra_flags)
+ err = nfmpi_create(comm, scratch, flags, info, ncid)
+ if (err .ne. NF_NOERR) then
+ call errore('nfmpi_create: ', err)
+ return
+ end if
+ call def_dims(ncid)
+ call def_vars(ncid)
+ call put_atts(ncid)
+ err = nfmpi_enddef(ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_enddef: ', err)
+ call put_vars(ncid)
+ err = nfmpi_abort(ncid)
+ if (err .ne. NF_NOERR) then
+ call errore('nfmpi_abort of ncid failed: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nfmpi_close(ncid) !/* should already be closed */
+ if (err .ne. NF_EBADID)
+ + call errore('bad ncid: ', err)
+ call check_file(scratch)
+ err = nfmpi_delete(scratch, info)
+ if (err .ne. NF_NOERR)
+ + call errori('delete of scratch file failed: ', err)
+ call print_nok(nok)
+ end
+
+
+C Test nfmpi_def_dim
+C try with bad netCDF handle, check error
+C try in data mode, check error
+C check that returned id is one more than previous id
+C try adding same dimension twice, check error
+C try with illegal sizes, check error
+C make sure unlimited size works, shows up in nfmpi_inq_unlimdim
+C try to define a second unlimited dimension, check error
+ subroutine test_nfmpi_def_dim()
+ implicit none
+ include "pnetcdf.inc"
+#include "tests.inc"
+
+ integer ncid
+ integer err !/* status */
+ integer i
+ integer dimid !/* dimension id */
+ integer*8 length
+ integer nok, flags
+
+ nok = 0
+
+C /* BAD_ID test */
+ length = 8
+ err = nfmpi_def_dim(BAD_ID, 'abc', length, dimid)
+ if (err .ne. NF_EBADID) then
+ call errore('bad ncid: ', err)
+ else
+ nok = nok + 1
+ endif
+
+C /* data mode test */
+ flags = IOR(NF_CLOBBER, extra_flags)
+ err = nfmpi_create(comm, scratch, flags, info, ncid)
+ if (err .ne. NF_NOERR) then
+ call errore('nfmpi_create: ', err)
+ return
+ end if
+ err = nfmpi_enddef(ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_enddef: ', err)
+ length = 8
+ err = nfmpi_def_dim(ncid, 'abc', length, dimid)
+ if (err .ne. NF_ENOTINDEFINE) then
+ call errore('bad ncid: ', err)
+ else
+ nok = nok + 1
+ endif
+
+C /* define-mode tests: unlimited dim */
+ err = nfmpi_redef(ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_redef: ', err)
+ err = nfmpi_def_dim(ncid, dim_name(1), NFMPI_UNLIMITED, dimid)
+ if (err .ne. NF_NOERR) then
+ call errore('nfmpi_def_dim: ', err)
+ else
+ nok = nok + 1
+ endif
+ if (dimid .ne. 1)
+ + call errori('Unexpected dimid: ', dimid)
+ err = nfmpi_inq_unlimdim(ncid, dimid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_inq_unlimdim: ', err)
+ if (dimid .ne. RECDIM)
+ + call error('Unexpected recdim: ')
+ err = nfmpi_inq_dimlen(ncid, dimid, length)
+ if (length .ne. 0)
+ + call errori('Unexpected length: ', 0)
+ err = nfmpi_def_dim(ncid, 'abc', NFMPI_UNLIMITED, dimid)
+ if (err .ne. NF_EUNLIMIT) then
+ call errore('2nd unlimited dimension: ', err)
+ else
+ nok = nok + 1
+ endif
+
+C /* define-mode tests: remaining dims */
+ do 1, i = 2, NDIMS
+ err = nfmpi_def_dim(ncid, dim_name(i-1), dim_len(i),
+ + dimid)
+ if (err .ne. NF_ENAMEINUSE) then
+ call errore('duplicate name: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nfmpi_def_dim(ncid, BAD_NAME, dim_len(i), dimid)
+ if (err .ne. NF_EBADNAME) then
+ call errore('bad name: ', err)
+ else
+ nok = nok + 1
+ endif
+ length = NFMPI_UNLIMITED - 1
+ err = nfmpi_def_dim(ncid, dim_name(i), length,
+ + dimid)
+ if (err .ne. NF_EDIMSIZE) then
+ call errore('bad size: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nfmpi_def_dim(ncid, dim_name(i),
+ & dim_len(i), dimid)
+ if (err .ne. NF_NOERR) then
+ call errore('nfmpi_def_dim: ', err)
+ else
+ nok = nok + 1
+ endif
+ if (dimid .ne. i)
+ + call errori('Unexpected dimid: ', 0)
+1 continue
+
+C /* Following just to expand unlimited dim */
+ call def_vars(ncid)
+ err = nfmpi_enddef(ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_enddef: ', err)
+ call put_vars(ncid)
+
+C /* Check all dims */
+ call check_dims(ncid)
+
+ err = nfmpi_close(ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_close: ', err)
+ err = nfmpi_delete(scratch, info)
+ if (err .ne. NF_NOERR)
+ + call errori('delete of scratch file failed: ', err)
+ call print_nok(nok)
+ end
+
+
+C Test nfmpi_rename_dim
+C try with bad netCDF handle, check error
+C check that proper rename worked with nfmpi_inq_dim
+C try renaming to existing dimension name, check error
+C try with bad dimension handle, check error
+ subroutine test_nfmpi_rename_dim()
+ implicit none
+ include "pnetcdf.inc"
+#include "tests.inc"
+
+ integer ncid
+ integer err !/* status */
+ character*(NF_MAX_NAME) name
+ integer nok, flags
+
+ nok = 0
+
+C /* BAD_ID test */
+ err = nfmpi_rename_dim(BAD_ID, 1, 'abc')
+ if (err .ne. NF_EBADID) then
+ call errore('bad ncid: ', err)
+ else
+ nok = nok + 1
+ endif
+
+C /* main tests */
+ flags = IOR(NF_NOCLOBBER, extra_flags)
+ err = nfmpi_create(comm, scratch, flags, info, ncid)
+ if (err .ne. NF_NOERR) then
+ call errore('nfmpi_create: ', err)
+ return
+ end if
+ call def_dims(ncid)
+ err = nfmpi_rename_dim(ncid, BAD_DIMID, 'abc')
+ if (err .ne. NF_EBADDIM) then
+ call errore('bad dimid: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nfmpi_rename_dim(ncid, 3, 'abc')
+ if (err .ne. NF_NOERR) then
+ call errore('nfmpi_rename_dim: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nfmpi_inq_dimname(ncid, 3, name)
+ if (name .ne. 'abc')
+ + call errorc('Unexpected name: ', name)
+ err = nfmpi_rename_dim(ncid, 1, 'abc')
+ if (err .ne. NF_ENAMEINUSE) then
+ call errore('duplicate name: ', err)
+ else
+ nok = nok + 1
+ endif
+
+ err = nfmpi_close(ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_close: ', err)
+ err = nfmpi_delete(scratch, info)
+ if (err .ne. NF_NOERR)
+ + call errori('delete of scratch file failed: ', err)
+ call print_nok(nok)
+ end
+
+
+C Test nfmpi_def_var
+C try with bad netCDF handle, check error
+C try with bad name, check error
+C scalar tests:
+C check that proper define worked with nfmpi_inq_var
+C try redefining an existing variable, check error
+C try with bad datatype, check error
+C try with bad number of dimensions, check error
+C try in data mode, check error
+C check that returned id is one more than previous id
+C try with bad dimension ids, check error
+ subroutine test_nfmpi_def_var()
+ implicit none
+ include "pnetcdf.inc"
+#include "tests.inc"
+
+ integer ncid
+ integer vid
+ integer err !/* status */
+ integer i
+ integer ndims
+ integer na
+ character*(NF_MAX_NAME) name
+ integer dimids(MAX_RANK)
+ integer datatype
+ integer nok, flags
+
+ nok = 0
+
+C /* BAD_ID test */
+ err = nfmpi_def_var(BAD_ID, 'abc', NF_SHORT, 0, dimids, vid)
+ if (err .ne. NF_EBADID) then
+ call errore('bad ncid: status = ', err)
+ else
+ nok = nok + 1
+ endif
+
+C /* scalar tests */
+ flags = IOR(NF_NOCLOBBER, extra_flags)
+ err = nfmpi_create(comm, scratch, flags, info, ncid)
+ if (err .ne. NF_NOERR) then
+ call errore('nfmpi_create: ', err)
+ return
+ end if
+ err = nfmpi_def_var(ncid, 'abc', NF_SHORT, 0, dimids, vid)
+ if (err .ne. NF_NOERR) then
+ call errore('nfmpi_def_var: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nfmpi_inq_var(ncid, vid, name, datatype, ndims, dimids,
+ + na)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_inq_var: ', err)
+ if (name .ne. 'abc')
+ + call errorc('Unexpected name: ', name)
+ if (datatype .ne. NF_SHORT)
+ + call error('Unexpected datatype')
+ if (ndims .ne. 0)
+ + call error('Unexpected rank')
+ err = nfmpi_def_var(ncid, BAD_NAME, NF_SHORT, 0, dimids, vid)
+ if (err .ne. NF_EBADNAME) then
+ call errore('bad name: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nfmpi_def_var(ncid, 'abc', NF_SHORT, 0, dimids, vid)
+ if (err .ne. NF_ENAMEINUSE) then
+ call errore('duplicate name: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nfmpi_def_var(ncid, 'ABC', BAD_TYPE, -1, dimids, vid)
+ if (err .ne. NF_EBADTYPE) then
+ call errore('bad type: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nfmpi_def_var(ncid, 'ABC', NF_SHORT, -1, dimids, vid)
+ if (err .ne. NF_EINVAL) then
+ call errore('bad rank: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nfmpi_enddef(ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_enddef: ', err)
+ err = nfmpi_def_var(ncid, 'ABC', NF_SHORT, 0, dimids, vid)
+ if (err .ne. NF_ENOTINDEFINE) then
+ call errore('nfmpi_def_var called in data mode: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nfmpi_close(ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_close: ', err)
+ err = nfmpi_delete(scratch, info)
+ if (err .ne. NF_NOERR)
+ + call errorc('delete of scratch file failed: ', scratch)
+
+C /* general tests using global vars */
+ flags = IOR(NF_CLOBBER, extra_flags)
+ err = nfmpi_create(comm, scratch, flags, info, ncid)
+ if (err .ne. NF_NOERR) then
+ call errore('nfmpi_create: ', err)
+ return
+ end if
+ call def_dims(ncid)
+ do 1, i = 1, numVars
+ err = nfmpi_def_var(ncid, var_name(i), var_type(i),
+ + var_rank(i), var_dimid(1,i), vid)
+ if (err .ne. NF_NOERR) then
+ call errore('nfmpi_def_var: ', err)
+ else
+ nok = nok + 1
+ endif
+ if (vid .ne. i)
+ + call error('Unexpected varid')
+1 continue
+
+C /* try bad dim ids */
+ dimids(1) = BAD_DIMID
+ err = nfmpi_def_var(ncid, 'abc', NF_SHORT, 1, dimids, vid)
+ if (err .ne. NF_EBADDIM) then
+ call errore('bad dim ids: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nfmpi_close(ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_close: ', err)
+
+ err = nfmpi_delete(scratch, info)
+ if (err .ne. NF_NOERR)
+ + call errorc('delete of scratch file failed: ', scratch)
+ call print_nok(nok)
+ end
+
+
+C Test nfmpi_rename_var
+C try with bad netCDF handle, check error
+C try with bad variable handle, check error
+C try renaming to existing variable name, check error
+C check that proper rename worked with nfmpi_inq_varid
+C try in data mode, check error
+ subroutine test_nfmpi_rename_var()
+ implicit none
+ include "pnetcdf.inc"
+#include "tests.inc"
+
+ integer ncid
+ integer vid
+ integer err
+ integer i
+ character*(NF_MAX_NAME) name
+ integer nok, flags
+
+ nok = 0
+
+ flags = IOR(NF_NOCLOBBER, extra_flags)
+ err = nfmpi_create(comm, scratch, flags, info, ncid)
+ if (err .ne. NF_NOERR) then
+ call errore('nfmpi_create: ', err)
+ return
+ end if
+ err = nfmpi_rename_var(ncid, BAD_VARID, 'newName')
+ if (err .ne. NF_ENOTVAR) then
+ call errore('bad var id: ', err)
+ else
+ nok = nok + 1
+ endif
+ call def_dims(ncid)
+ call def_vars(ncid)
+
+C /* Prefix "new_" to each name */
+ do 1, i = 1, numVars
+ err = nfmpi_rename_var(BAD_ID, i, 'newName')
+ if (err .ne. NF_EBADID) then
+ call errore('bad ncid: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nfmpi_rename_var(ncid, i, var_name(numVars))
+ if (err .ne. NF_ENAMEINUSE) then
+ call errore('duplicate name: ', err)
+ else
+ nok = nok + 1
+ endif
+ name = 'new_' // var_name(i)
+ err = nfmpi_rename_var(ncid, i, name)
+ if (err .ne. NF_NOERR) then
+ call errore('nfmpi_rename_var: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nfmpi_inq_varid(ncid, name, vid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_inq_varid: ', err)
+ if (vid .ne. i)
+ + call error('Unexpected varid')
+1 continue
+
+C /* Change to data mode */
+C /* Try making names even longer. Then restore original names */
+ err = nfmpi_enddef(ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_enddef: ', err)
+ do 2, i = 1, numVars
+ name = 'even_longer_' // var_name(i)
+ err = nfmpi_rename_var(ncid, i, name)
+ if (err .ne. NF_ENOTINDEFINE) then
+ call errore('longer name in data mode: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nfmpi_rename_var(ncid, i, var_name(i))
+ if (err .ne. NF_NOERR) then
+ call errore('nfmpi_rename_var: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nfmpi_inq_varid(ncid, var_name(i), vid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_inq_varid: ', err)
+ if (vid .ne. i)
+ + call error('Unexpected varid')
+2 continue
+
+ call put_vars(ncid)
+ call check_vars(ncid)
+
+ err = nfmpi_close(ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_close: ', err)
+
+ err = nfmpi_delete(scratch, info)
+ if (err .ne. NF_NOERR)
+ + call errorc('delete of scratch file failed: ', scratch)
+ call print_nok(nok)
+ end
+
+
+C Test nfmpi_copy_att
+C try with bad source or target netCDF handles, check error
+C try with bad source or target variable handle, check error
+C try with nonexisting attribute, check error
+C check that NF_GLOBAL variable for source or target works
+C check that new attribute put works with target in define mode
+C check that old attribute put works with target in data mode
+C check that changing type and length of an attribute work OK
+C try with same ncid for source and target, different variables
+C try with same ncid for source and target, same variable
+ subroutine test_nfmpi_copy_att()
+ implicit none
+ include "pnetcdf.inc"
+#include "tests.inc"
+ character*2 ATT_NAME
+ integer VARID, NATTS, ATT_LEN
+
+ integer ncid_in
+ integer ncid_out
+ integer vid
+ integer err
+ integer i
+ integer j
+ character*(NF_MAX_NAME) name !/* of att */
+ integer datatype !/* of att */
+ integer*8 length !/* of att */
+ character*1 value
+ integer nok, flags
+
+ nok = 0
+ err = nfmpi_open(comm, testfile, NF_NOWRITE, info, ncid_in)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_open: ', err)
+ flags = IOR(NF_NOCLOBBER, extra_flags)
+ err = nfmpi_create(comm, scratch, flags, info, ncid_out)
+ if (err .ne. NF_NOERR) then
+ call errore('nfmpi_create: ', err)
+ return
+ end if
+ call def_dims(ncid_out)
+ call def_vars(ncid_out)
+
+ do 1, i = 0, numVars
+ vid = VARID(i)
+ do 2, j = 1, NATTS(i)
+ name = ATT_NAME(j,i)
+ err = nfmpi_copy_att(ncid_in, BAD_VARID, name,
+ + ncid_out, vid)
+ if (err .ne. NF_ENOTVAR)
+ + call errore('bad var id: ', err)
+ nok = nok + 1
+ err = nfmpi_copy_att(ncid_in, vid, name, ncid_out,
+ + BAD_VARID)
+ if (err .ne. NF_ENOTVAR)
+ + call errore('bad var id: ', err)
+ nok = nok + 1
+ err = nfmpi_copy_att(BAD_ID, vid, name,
+ + ncid_out, vid)
+ if (err .ne. NF_EBADID)
+ + call errore('bad ncid: ', err)
+ nok = nok + 1
+ err = nfmpi_copy_att(ncid_in, vid, name,
+ + BAD_ID, vid)
+ if (err .ne. NF_EBADID)
+ + call errore('bad ncid: ', err)
+ nok = nok + 1
+ err = nfmpi_copy_att(ncid_in, vid, 'noSuch',
+ + ncid_out, vid)
+ if (err .ne. NF_ENOTATT)
+ + call errore('bad attname: ', err)
+ nok = nok + 1
+ err = nfmpi_copy_att(ncid_in, vid, name,
+ + ncid_out, vid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_copy_att: ', err)
+ nok = nok + 1
+ err = nfmpi_copy_att(ncid_out, vid, name,
+ + ncid_out, vid)
+ if (err .ne. NF_NOERR)
+ + call errore('source = target: ', err)
+ nok = nok + 1
+2 continue
+1 continue
+
+ err = nfmpi_close(ncid_in)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_close: ', err)
+
+C /* Close scratch. Reopen & check attributes */
+ err = nfmpi_close(ncid_out)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_close: ', err)
+ err = nfmpi_open(comm, scratch, NF_WRITE, info, ncid_out)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_open: ', err)
+ call check_atts(ncid_out)
+
+C change to define mode
+C define single char. global att. ':a' with value 'A'
+C This will be used as source for following copies
+ err = nfmpi_redef(ncid_out)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_redef: ', err)
+ length = 1
+ err = nfmpi_put_att_text(ncid_out, NF_GLOBAL, 'a', length, 'A')
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_put_att_text: ', err)
+
+C change to data mode
+C Use scratch as both source & dest.
+C try copy to existing att. change type & decrease length
+C rename 1st existing att of each var (if any) 'a'
+C if this att. exists them copy ':a' to it
+ err = nfmpi_enddef(ncid_out)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_enddef: ', err)
+ do 3, i = 1, numVars
+ if (NATTS(i) .gt. 0 .and. ATT_LEN(1,i) .gt. 0) then
+ err = nfmpi_rename_att(ncid_out, i,
+ + att_name(1,i), 'a')
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_rename_att: ', err)
+ err = nfmpi_copy_att(ncid_out, NF_GLOBAL, 'a',
+ + ncid_out, i)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_copy_att: ', err)
+ nok = nok + 1
+ end if
+3 continue
+ err = nfmpi_close(ncid_out)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_close: ', err)
+
+C /* Reopen & check */
+ err = nfmpi_open(comm, scratch, NF_WRITE, info, ncid_out)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_open: ', err)
+ do 4, i = 1, numVars
+ if (NATTS(i) .gt. 0 .and. ATT_LEN(1,i) .gt. 0) then
+ err = nfmpi_inq_att(ncid_out, i, 'a',
+ + datatype, length)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_inq_att: ', err)
+ if (datatype .ne. NF_CHAR)
+ + call error('Unexpected type')
+ if (length .ne. 1)
+ + call error('Unexpected length')
+ err = nfmpi_get_att_text(ncid_out, i, 'a', value)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_get_att_text: ', err)
+ if (value .ne. 'A')
+ + call error('Unexpected value')
+ end if
+4 continue
+
+ err = nfmpi_close(ncid_out)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_close: ', err)
+ err = nfmpi_delete(scratch, info)
+ if (err .ne. NF_NOERR)
+ + call errorc('delete of scratch file failed', scratch)
+ call print_nok(nok)
+ end
+
+
+C Test nfmpi_rename_att
+C try with bad netCDF handle, check error
+C try with bad variable handle, check error
+C try with nonexisting att name, check error
+C try renaming to existing att name, check error
+C check that proper rename worked with nfmpi_inq_attid
+C try in data mode, check error
+ subroutine test_nfmpi_rename_att()
+ implicit none
+ include "pnetcdf.inc"
+#include "tests.inc"
+ integer MY_LEN_TRIM
+ character*2 ATT_NAME
+ integer VARID, ATT_TYPE, NATTS, ATT_LEN
+ double precision hash
+ logical equal, inrange
+
+ integer ncid
+ integer vid
+ integer err, flags
+ integer i
+ integer j
+ integer k
+ integer attnum
+ character*(NF_MAX_NAME) atnam
+ character*(NF_MAX_NAME) name
+ character*(NF_MAX_NAME) oldname
+ character*(NF_MAX_NAME) newname
+ integer nok !/* count of valid comparisons */
+ integer datatype
+ integer attyp
+ integer*8 length
+ integer*8 attlength
+ integer*8 ndx(1)
+ character*(MAX_NELS) text
+ doubleprecision value(MAX_NELS)
+ doubleprecision expect
+
+ nok = 0
+
+ flags = IOR(NF_NOCLOBBER, extra_flags)
+ err = nfmpi_create(comm, scratch, flags, info, ncid)
+ if (err .ne. NF_NOERR) then
+ call errore('nfmpi_create: ', err)
+ return
+ end if
+ err = nfmpi_rename_att(ncid, BAD_VARID, 'abc', 'newName')
+ if (err .ne. NF_ENOTVAR)
+ + call errore('bad var id: ', err)
+ call def_dims(ncid)
+ call def_vars(ncid)
+ call put_atts(ncid)
+
+ do 1, i = 0, numVars
+ vid = VARID(i)
+ do 2, j = 1, NATTS(i)
+ atnam = ATT_NAME(j,i)
+ err = nfmpi_rename_att(BAD_ID, vid, atnam,
+ + 'newName')
+ if (err .ne. NF_EBADID)
+ + call errore('bad ncid: ', err)
+ err = nfmpi_rename_att(ncid, vid, 'noSuch',
+ + 'newName')
+ if (err .ne. NF_ENOTATT)
+ + call errore('bad attname: ', err)
+ newname = 'new_' // TRIM(atnam)
+ err = nfmpi_rename_att(ncid, vid, atnam, newname)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_rename_att: ', err)
+ err = nfmpi_inq_attid(ncid, vid, newname, attnum)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_inq_attid: ', err)
+ if (attnum .ne. j)
+ + call error('Unexpected attnum')
+2 continue
+1 continue
+
+C /* Close. Reopen & check */
+ err = nfmpi_close(ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_close: ', err)
+ err = nfmpi_open(comm, scratch, NF_WRITE, info, ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_open: ', err)
+
+ do 3, i = 0, numVars
+ vid = VARID(i)
+ do 4, j = 1, NATTS(i)
+ atnam = ATT_NAME(j,i)
+ attyp = ATT_TYPE(j,i)
+ attlength = ATT_LEN(j,i)
+ newname = 'new_' // TRIM(atnam)
+ err = nfmpi_inq_attname(ncid, vid, j, name)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_inq_attname: ', err)
+ if (name .ne. newname)
+ + call error('nfmpi_inq_attname: unexpected name')
+ err = nfmpi_inq_att(ncid, vid, name,
+ + datatype, length)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_inq_att: ', err)
+ if (datatype .ne. attyp)
+ + call error('nfmpi_inq_att: unexpected type')
+ if (length .ne. attlength)
+ + call error('nfmpi_inq_att: unexpected length')
+ if (datatype .eq. NF_CHAR) then
+ err = nfmpi_get_att_text(ncid, vid, name, text)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_get_att_text: ', err)
+ do 5, k = 1, ATT_LEN(j,i)
+ ndx(1) = k
+ expect = hash(datatype, -1, ndx)
+ if (ichar(text(k:k)) .ne. expect) then
+ call error(
+ + 'nfmpi_get_att_text: unexpected value')
+ else
+ nok = nok + 1
+ end if
+5 continue
+ else
+ err = nfmpi_get_att_double(ncid, vid, name,
+ + value)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_get_att_double: ', err)
+ do 6, k = 1, ATT_LEN(j,i)
+ ndx(1) = k
+ expect = hash(datatype, -1, ndx)
+ if (inRange(expect, datatype)) then
+ if (.not. equal(value(k),expect,datatype,
+ + NF_DOUBLE)) then
+ call error(
+ + 'nfmpi_get_att_double: unexpected value')
+ else
+ nok = nok + 1
+ end if
+ end if
+6 continue
+ end if
+4 continue
+3 continue
+ call print_nok(nok)
+
+C /* Now in data mode */
+C /* Try making names even longer. Then restore original names */
+
+ do 7, i = 0, numVars
+ vid = VARID(i)
+ do 8, j = 1, NATTS(i)
+ atnam = ATT_NAME(j,i)
+ oldname = 'new_' // TRIM(atnam)
+ newname = 'even_longer_' // TRIM(atnam)
+ err = nfmpi_rename_att(ncid, vid, oldname, newname)
+ if (err .ne. NF_ENOTINDEFINE)
+ + call errore('longer name in data mode: ', err)
+ err = nfmpi_rename_att(ncid, vid, oldname, atnam)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_rename_att: ', err)
+ err = nfmpi_inq_attid(ncid, vid, atnam, attnum)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_inq_attid: ', err)
+ if (attnum .ne. j)
+ + call error('Unexpected attnum')
+8 continue
+7 continue
+
+ err = nfmpi_close(ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_close: ', err)
+
+ err = nfmpi_delete(scratch, info)
+ if (err .ne. NF_NOERR)
+ + call errori('delete of scratch file failed: ', err)
+ end
+
+
+C Test nfmpi_del_att
+C try with bad netCDF handle, check error
+C try with bad variable handle, check error
+C try with nonexisting att name, check error
+C check that proper delete worked using:
+C nfmpi_inq_attid, nfmpi_inq_natts, nfmpi_inq_varnatts
+ subroutine test_nfmpi_del_att()
+ implicit none
+ include "pnetcdf.inc"
+#include "tests.inc"
+ character*2 ATT_NAME
+ integer VARID, NATTS
+
+ integer ncid
+ integer err, flags
+ integer i
+ integer j
+ integer attnum
+ integer na
+ integer numatts
+ integer vid
+ character*(NF_MAX_NAME) name !/* of att */
+ integer nok !/* count of valid comparisons */
+
+ nok = 0
+
+ flags = IOR(NF_NOCLOBBER, extra_flags)
+ err = nfmpi_create(comm, scratch, flags, info, ncid)
+ if (err .ne. NF_NOERR) then
+ call errore('nfmpi_create: ', err)
+ return
+ end if
+ err = nfmpi_del_att(ncid, BAD_VARID, 'abc')
+ if (err .ne. NF_ENOTVAR) then
+ call errore('bad var id: ', err)
+ else
+ nok = nok + 1
+ endif
+ call def_dims(ncid)
+ call def_vars(ncid)
+ call put_atts(ncid)
+
+ do 1, i = 0, numVars
+ vid = VARID(i)
+ numatts = NATTS(i)
+ do 2, j = 1, numatts
+ name = ATT_NAME(j,i)
+ err = nfmpi_del_att(BAD_ID, vid, name)
+ if (err .ne. NF_EBADID) then
+ call errore('bad ncid: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nfmpi_del_att(ncid, vid, 'noSuch')
+ if (err .ne. NF_ENOTATT) then
+ call errore('bad attname: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nfmpi_del_att(ncid, vid, name)
+ if (err .ne. NF_NOERR) then
+ call errore('nfmpi_del_att: ', err)
+ else
+ nok = nok + 1
+ endif
+ err = nfmpi_inq_attid(ncid, vid, name, attnum)
+ if (err .ne. NF_ENOTATT)
+ + call errore('bad attname: ', err)
+ if (i .lt. 1) then
+ err = nfmpi_inq_natts(ncid, na)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_inq_natts: ', err)
+ if (na .ne. numatts-j) then
+ call errori('natts: expected: ', numatts-j)
+ call errori('natts: got: ', na)
+ end if
+ end if
+ err = nfmpi_inq_varnatts(ncid, vid, na)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_inq_natts: ', err)
+ if (na .ne. numatts-j) then
+ call errori('natts: expected: ', numatts-j)
+ call errori('natts: got: ', na)
+ end if
+2 continue
+1 continue
+
+C /* Close. Reopen & check no attributes left */
+ err = nfmpi_close(ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_close: ', err)
+ err = nfmpi_open(comm, scratch, NF_WRITE, info, ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_open: ', err)
+ err = nfmpi_inq_natts(ncid, na)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_inq_natts: ', err)
+ if (na .ne. 0)
+ + call errori('natts: expected 0, got ', na)
+ do 3, i = 0, numVars
+ vid = VARID(i)
+ err = nfmpi_inq_varnatts(ncid, vid, na)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_inq_natts: ', err)
+ if (na .ne. 0)
+ + call errori('natts: expected 0, got ', na)
+3 continue
+
+C /* restore attributes. change to data mode. try to delete */
+ err = nfmpi_redef(ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_redef: ', err)
+ call put_atts(ncid)
+ err = nfmpi_enddef(ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_enddef: ', err)
+
+ do 4, i = 0, numVars
+ vid = VARID(i)
+ numatts = NATTS(i)
+ do 5, j = 1, numatts
+ name = ATT_NAME(j,i)
+ err = nfmpi_del_att(ncid, vid, name)
+ if (err .ne. NF_ENOTINDEFINE) then
+ call errore('in data mode: ', err)
+ else
+ nok = nok + 1
+ endif
+5 continue
+4 continue
+
+ err = nfmpi_close(ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_close: ', err)
+ err = nfmpi_delete(scratch, info)
+ if (err .ne. NF_NOERR)
+ + call errori('delete of scratch file failed: ', err)
+ call print_nok(nok)
+ end
+
+C parallel-netcdf doesn't implement set_fill, so i have not
+C parallel-netcdfified this subroutine
+C Test nfmpi_set_fill
+C try with bad netCDF handle, check error
+C try in read-only mode, check error
+C try with bad new_fillmode, check error
+C try in data mode, check error
+C check that proper set to NF_FILL works for record & non-record variables
+C (note that it is not possible to test NF_NOFILL mode!)
+C close file & create again for test using attribute _FillValue
+ subroutine test_nfmpi_set_fill()
+ implicit none
+ include "pnetcdf.inc"
+#include "tests.inc"
+ ! character*2 ATT_NAME
+ ! integer VARID, ATT_TYPE, NATTS
+
+ integer MY_LEN_TRIM
+ integer ncid
+ integer vid
+ integer err, flags
+ integer i
+ integer j
+ integer old_fillmode
+ character*1 text
+ doubleprecision value
+ doubleprecision fill
+ integer*8 index(MAX_RANK)
+ integer*8 length
+ integer index2indexes
+ integer nok !/* count of valid comparisons */
+
+ value = 0
+ nok = 0
+
+C /* bad ncid */
+ err = nfmpi_set_fill(BAD_ID, NF_NOFILL, old_fillmode)
+ if (err .ne. NF_EBADID)
+ + call errore('bad ncid: ', err)
+
+C /* try in read-only mode */
+ err = nfmpi_open(comm, testfile, NF_NOWRITE, info, ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_open: ', err)
+ err = nfmpi_set_fill(ncid, NF_NOFILL, old_fillmode)
+ if (err .ne. NF_EPERM)
+ + call errore('read-only: ', err)
+ err = nfmpi_close(ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_close: ', err)
+
+C /* create scratch */
+ flags = IOR(NF_NOCLOBBER, extra_flags)
+ err = nfmpi_create(comm, scratch, flags, info, ncid)
+ if (err .ne. NF_NOERR) then
+ call errore('nfmpi_create: ', err)
+ return
+ end if
+
+C /* BAD_FILLMODE */
+ err = nfmpi_set_fill(ncid, BAD_FILLMODE, old_fillmode)
+ if (err .ne. NF_EINVAL)
+ + call errore('bad fillmode: ', err)
+
+C /* proper calls */
+ err = nfmpi_set_fill(ncid, NF_FILL, old_fillmode)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_set_fill: ', err)
+ if (old_fillmode .ne. NF_NOFILL)
+ + call errori('Unexpected old fill mode: ', old_fillmode)
+ err = nfmpi_set_fill(ncid, NF_NOFILL, old_fillmode)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_set_fill: ', err)
+ if (old_fillmode .ne. NF_FILL)
+ + call errori('Unexpected old fill mode: ', old_fillmode)
+ err = nfmpi_set_fill(ncid, NF_FILL, old_fillmode)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_set_fill: ', err)
+
+C /* define dims & vars */
+ call def_dims(ncid)
+ call def_vars(ncid)
+
+C /* Change to data mode. Set fillmode again */
+ err = nfmpi_enddef(ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_enddef: ', err)
+ err = nfmpi_set_fill(ncid, NF_FILL, old_fillmode)
+ if (err .ne. NF_ENOTINDEFINE)
+ + call errore('nfmpi_set_fill: ', err)
+
+C /* Write record number NRECS to force writing of preceding records */
+C /* Assumes variable cr is char vector with UNLIMITED dimension */
+ err = nfmpi_inq_varid(ncid, 'cr', vid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_inq_varid: ', err)
+ index(1) = NRECS
+ text = char(NF_FILL_CHAR)
+ err = nfmpi_put_var1_text_all(ncid, vid, index, text)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_put_var1_text_all: ', err)
+
+C /* get all variables & check all values equal default fill */
+ do 1, i = 1, numVars
+ if (var_dimid(var_rank(i),i) .eq. RECDIM) go to 1 ! skip record variables
+
+ if (var_type(i) .eq. NF_CHAR) then
+ fill = NF_FILL_CHAR
+ else if (var_type(i) .eq. NF_BYTE) then
+ fill = NF_FILL_BYTE
+ else if (var_type(i) .eq. NF_SHORT) then
+ fill = NF_FILL_SHORT
+ else if (var_type(i) .eq. NF_INT) then
+ fill = NF_FILL_INT
+ else if (var_type(i) .eq. NF_FLOAT) then
+ fill = NF_FILL_FLOAT
+ else if (var_type(i) .eq. NF_DOUBLE) then
+ fill = NF_FILL_DOUBLE
+ else if (var_type(i) .eq. NF_UBYTE) then
+ fill = NF_FILL_UBYTE
+ else if (var_type(i) .eq. NF_USHORT) then
+ fill = NF_FILL_USHORT
+ else if (var_type(i) .eq. NF_UINT) then
+ fill = NF_FILL_UINT
+ else if (var_type(i) .eq. NF_INT64) then
+ fill = NF_FILL_INT64
+ else if (var_type(i) .eq. NF_UINT64) then
+ ! cycle ! skip uint64
+ fill = NF_FILL_UINT64
+ else
+ print *, 'Unexpected type : ', var_type(i)
+ stop 'test_nfmpi_set_fill(): impossible var_type(i)'
+ end if
+
+ do 2, j = 1, var_nels(i)
+ err = index2indexes(j, var_rank(i), var_shape(1,i),
+ + index)
+ if (err .ne. NF_NOERR)
+ + call error('error in index2indexes()')
+ if (var_type(i) .eq. NF_CHAR) then
+ err = nfmpi_get_var1_text_all(ncid, i, index, text)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_get_var1_text_all failed: ',
+ + err)
+ value = ichar(text)
+ else
+ err = nfmpi_get_var1_double_all(ncid, i, index,
+ + value)
+ if (err .ne. NF_NOERR)
+ + call errore
+ + ('nfmpi_get_var1_double_all failed: ',
+ + err)
+ end if
+ if (value .ne. fill .and.
+ + abs((fill - value)/fill) .gt. 1.0e-9) then
+ print *, 'var_name : ',
+ + TRIM(var_name(i))
+ print *, 'var_type : ', var_type(i)
+ print *, 'fill : ', fill
+ call errord('Unexpected fill value: ', value)
+ else
+ nok = nok + 1
+ end if
+2 continue
+1 continue
+
+C /* close scratch & create again for test using attribute _FillValue */
+ err = nfmpi_close(ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_close: ', err)
+ flags = IOR(NF_CLOBBER, extra_flags)
+ err = nfmpi_create(comm, scratch, flags, info, ncid)
+ if (err .ne. NF_NOERR) then
+ call errore('nfmpi_create: ', err)
+ return
+ end if
+ call def_dims(ncid)
+ call def_vars(ncid)
+
+C /* set _FillValue = 42 for all vars */
+ fill = 42
+ text = char(int(fill))
+ length = 1
+ do 3, i = 1, numVars
+ if (var_type(i) .eq. NF_CHAR) then
+ err = nfmpi_put_att_text(ncid, i, '_FillValue', length,
+ + text)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_put_att_text: ', err)
+ else
+ err = nfmpi_put_att_double(ncid, i, '_FillValue',
+ + var_type(i),length,fill)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_put_att_double: ', err)
+ end if
+3 continue
+
+C /* data mode. write records */
+ err = nfmpi_enddef(ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_enddef: ', err)
+ index(1) = NRECS
+ err = nfmpi_put_var1_text_all(ncid, vid, index, text)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_put_var1_text_all: ', err)
+
+C /* get all variables & check all values equal 42 */
+ do 4, i = 1, numVars
+ if (var_dimid(var_rank(i),i) .eq. RECDIM) go to 4 ! skip record variables
+ do 5, j = 1, var_nels(i)
+ err = index2indexes(j, var_rank(i), var_shape(1,i),
+ + index)
+ if (err .ne. NF_NOERR)
+ + call error('error in index2indexes')
+ if (var_type(i) .eq. NF_CHAR) then
+ err = nfmpi_get_var1_text_all(ncid, i, index, text)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_get_var1_text_all failed: ',
+ + err)
+ value = ichar(text)
+ else
+ err = nfmpi_get_var1_double_all(ncid, i,
+ + index, value)
+ if (err .ne. NF_NOERR)
+ + call errore
+ + ('nfmpi_get_var1_double_all failed: ',
+ + err)
+ end if
+ if (value .ne. fill) then
+ call errord(' Value expected: ', fill)
+ call errord(' Value read: ', value)
+ else
+ nok = nok + 1
+ end if
+5 continue
+4 continue
+
+ err = nfmpi_close(ncid)
+ if (err .ne. NF_NOERR)
+ + call errore('nfmpi_close: ', err)
+ err = nfmpi_delete(scratch, info)
+ if (err .ne. NF_NOERR)
+ + call errori('delete of scratch file failed: ', err)
+ call print_nok(nok)
+ end
+
+#if 0
+C * Test nc_set_default_format
+C * try with bad default format
+C * try with NULL old_formatp
+C * try in data mode, check error
+C * check that proper set to NC_FILL works for record & non-record variables
+C * (note that it is not possible to test NC_NOFILL mode!)
+C * close file & create again for test using attribute _FillValue
+ subroutine test_nfmpi_set_default_format()
+ implicit none
+ include "pnetcdf.inc"
+#include "tests.inc"
+
+ integer ncid
+ integer err, flags
+ integer i
+ integer version
+ integer old_format
+ integer nfmpi_get_file_version
+
+C /* bad format */
+ err = nfmpi_set_default_format(3, old_format)
+ if (err .ne. NF_EINVAL)
+ + call errore("bad default format: status = %d", err)
+
+C /* Cycle through available formats. */
+ do 1 i=1, 2
+ err = nfmpi_set_default_format(i, old_format)
+ if (err .ne. NF_NOERR)
+ + call errore("setting classic format: status = %d", err)
+ flags = IOR(NF_CLOBBER, extra_flags)
+ err = nfmpi_create(comm, scratch, flags, info, ncid)
+ if (err .ne. NF_NOERR)
+ + call errore("bad nfmpi_create: status = %d", err)
+ err = nfmpi_put_att_text(ncid, NF_GLOBAL, "testatt",
+ + 4, "blah")
+ if (err .ne. NF_NOERR)
+ + call errore("bad put_att: status = %d", err)
+ err = nfmpi_close(ncid)
+ if (err .ne. NF_NOERR)
+ + call errore("bad close: status = %d", err)
+ err = nfmpi_get_file_version(scratch, version)
+ if (err .ne. NF_NOERR) call errore("bad file version = %d",err)
+ if (version .ne. i)
+ + call errore("bad file version = %d", err)
+ 1 continue
+
+C /* Remove the left-over file. */
+ err = nfmpi_delete(scratch)
+ if (err .ne. NF_NOERR) call errore("remove failed", err)
+ end
+
+#endif
+
+C This function looks in a file for the netCDF magic number.
+ integer function nfmpi_get_file_version(path, version)
+ implicit none
+ include "pnetcdf.inc"
+#include "tests.inc"
+
+ character*(*) path
+ integer version
+ character magic*4
+ integer ver
+ integer f
+ parameter (f = 10)
+
+ open(f, file=path, status='OLD', form='UNFORMATTED',
+ + access='DIRECT', recl=4)
+
+C Assume this is not a netcdf file.
+ nfmpi_get_file_version = NF_ENOTNC
+ version = 0
+
+C Read the magic number, the first 4 bytes of the file.
+ read(f, rec=1, err = 1) magic
+
+C If the first three characters are not "CDF" we're done.
+ if (index(magic, 'CDF') .eq. 1) then
+ ver = ichar(magic(4:4))
+ if (ver .eq. 1) then
+ version = 1
+ nfmpi_get_file_version = NF_NOERR
+ elseif (ver .eq. 2) then
+ version = 2
+ nfmpi_get_file_version = NF_NOERR
+ endif
+ endif
+
+ 1 close(f)
+ return
+ end
+
+
diff --git a/test/nf_test/tests.inc.in b/test/nf_test/tests.inc.in
new file mode 100644
index 0000000..9bcd322
--- /dev/null
+++ b/test/nf_test/tests.inc.in
@@ -0,0 +1,234 @@
+!
+! Copyright (C) 2003, Northwestern University and Argonne National Laboratory
+! See COPYRIGHT notice in top-level directory.
+!
+! $Id: tests.inc.in 2289 2016-01-02 08:26:40Z wkliao $
+!
+
+!!!!
+! Do not tabify this unless you like hitting the 72 char limit !!!
+!!!
+#ifndef UD_TESTS_INC
+#define UD_TESTS_INC
+
+
+!/* The following prevents non-FORTRAN code from appearing in the output. */
+#if defined(__osf__)
+# undef _POSIX_SOURCE
+# define _POSIX_SOURCE
+#endif
+
+#define NO_NETCDF_2 1
+
+#include "nfconfig.inc"
+
+
+!/* Parameters of test data */
+
+#ifdef NF_INT1_T
+# define NF_B 1
+#else
+# define NF_B 0
+#endif
+#ifdef NF_INT2_T
+# define NF_S 1
+#else
+# define NF_S 0
+#endif
+! Total number of FORTRAN types:
+#define NUM_FORTRAN_TYPES (3 + NF_S + NF_B)
+#undef NF_B
+#undef NF_S
+
+#define NTYPES 11
+#define NDIMS 5
+#define NRECS 2
+#define NGATTS NTYPES
+#define RECDIM 1
+#define MAX_RANK 3
+#define MAX_NELS 64
+#define MAX_DIM_LEN 4
+#define MAX_NATTS 3
+
+#define NVARS 166
+!
+! #define NVARS 136 when NTYPES==6
+! #define NVARS 142 when NTYPES==7
+! #define NVARS 148 when NTYPES==8
+! #define NVARS 154 when NTYPES==9
+! #define NVARS 160 when NTYPES==10
+! #define NVARS 166 when NTYPES==11
+! c:char, b:byte, s:short, i:int, f:float, d:double, y:ubyte, t:ushort,
+! u:uint, x:int64, z:uint64
+!
+
+!
+! Limits of external types (based on those in ncx.h):
+!
+! Note: In CDF format specification, NC_CHAR is for text characters, which
+! is considered an 8-bit unsigned integer. Since it is for printable text
+! characters, its values should range from 0 (X_CHAR_MIN) to 255 (X_CHAR_MAX).
+!
+#define X_CHAR_MIN 0
+#define X_CHAR_MAX 255
+#define X_INT1_MIN (-128)
+#define X_INT1_MAX 127
+#define X_INT2_MIN (-32768)
+#define X_INT2_MAX 32767
+#define X_INT_MIN (-2147483647-1)
+#define X_INT_MAX 2147483647
+#if 0
+#define X_REAL_MAX 3.4028234663852886e+38
+#else
+#define X_REAL_MAX 3.4028234663852886e+37
+#endif
+#define X_REAL_MIN (-X_FLOAT_MAX)
+#if 0
+#define X_DOUBLE_MAX 1.7976931348623157E+308
+#else
+#define X_DOUBLE_MAX 1.7976931348623157D+200
+#endif
+#define X_DOUBLE_MIN (-X_DOUBLE_MAX)
+#define X_INT8_MIN @PNF_X_INT8_MIN@
+#define X_INT8_MAX @PNF_X_INT8_MAX@
+#define X_UINT8_MIN 0
+#define X_UINT8_MAX 18446744073709551615.0
+
+#define X_BYTE_MIN X_INT1_MIN
+#define X_BYTE_MAX X_INT1_MAX
+#define X_SHORT_MIN X_INT2_MIN
+#define X_SHORT_MAX X_INT2_MAX
+#define X_FLOAT_MIN X_REAL_MIN
+#define X_FLOAT_MAX X_REAL_MAX
+
+#define X_UCHAR_MAX 255
+#define X_UCHAR_MIN 0
+#define X_UBYTE_MAX X_UCHAR_MAX
+#define X_UBYTE_MIN X_UCHAR_MIN
+#define X_USHORT_MAX 65535
+#define X_USHORT_MIN 0
+#define X_UINT_MAX @PNF_X_UINT_MAX@
+#define X_UINT_MIN 0
+
+!/*
+! * Examples of invalid argument values:
+! */
+#define BAD_ID -1
+#define BAD_DIMID -1
+#define BAD_VARID -2
+#define BAD_ATTNUM -1
+#define BAD_TYPE 0
+#define BAD_FILLMODE -1
+#define BAD_NAME 'a/b'
+
+
+!/*
+! * Internal data types: (in memory)
+! */
+#define NFT_UNSPECIFIED 0
+! #define NFT_UCHAR 1
+#define NFT_TEXT 16
+#define NFT_CHAR NFT_TEXT
+#define NFT_INT1 17
+! #define NFT_SCHAR NFT_INT1
+#define NFT_INT2 18
+#define NFT_INT 20
+#define NFT_REAL 36
+#define NFT_DOUBLE 40
+! #define NFT_USHORT 41
+! #define NFT_UINT 42
+#define NFT_INT8 43
+! #define NFT_UINT8 44
+
+
+!/*
+! * Define a macro for trimming trailing blanks from character variables.
+! */
+#define TRIM(string) string(1:MY_LEN_TRIM(string))
+
+
+!
+! FORTRAN GETARG() subroutine:
+!
+#ifdef __hpux
+# define getarg getarg_
+#endif
+
+
+#endif /* UD_TESTS_INC */
+
+#include "mpif.h"
+
+
+! /* Global variables - filenames */
+
+ CHARACTER*80 testfile !/* netCDF read-only test data */
+ CHARACTER*80 scratch !/* netCDF test file for writing */
+
+! /* Global variables - command-line arguments */
+
+ LOGICAL CREATE_FILE
+ LOGICAL READONLY
+ LOGICAL VERBOSE
+ INTEGER NFAILS
+ INTEGER MAX_NMPT !/* max num messages per test */
+
+! /* Global variables - test data */
+
+ CHARACTER*2 DIM_NAME(NDIMS)
+ INTEGER*8 DIM_LEN(NDIMS)
+ CHARACTER*(2+MAX_RANK) VAR_NAME(NVARS)
+ INTEGER VAR_TYPE(NVARS)
+ INTEGER VAR_RANK(NVARS)
+ INTEGER VAR_DIMID(MAX_RANK,NVARS)
+ INTEGER*8 VAR_SHAPE(MAX_RANK,NVARS)
+ INTEGER VAR_NELS(NVARS)
+ INTEGER VAR_NATTS(NVARS)
+ CHARACTER*2 ATTNAME(MAX_NATTS,NVARS)
+ CHARACTER*2 GATT_NAME(NGATTS)
+ INTEGER ATTTYPE(NGATTS,NVARS)
+ INTEGER GATT_TYPE(NGATTS)
+ INTEGER ATTLEN(MAX_NATTS,NVARS)
+ INTEGER*8 GATT_LEN(NGATTS)
+
+! /* Miscellaneous global variables: */
+ CHARACTER*128 PROGNAME !/* name of the program */
+ INTEGER COMM !/* MPI communicator */
+
+ INTEGER NFAILSTOTAL
+
+! /* Common blocks for global variables: */
+
+!/* MPI_OFFSET */
+ COMMON /OFFSETCOM/ DIM_LEN, VAR_SHAPE, GATT_LEN
+
+ COMMON /MPICOM/ COMM
+ COMMON /LOGCOM/ CREATE_FILE,
+ * READONLY, !/* don't change files */
+ * VERBOSE !/* print details of tests */
+
+ COMMON /TXTCOM/ TESTFILE,
+ * SCRATCH,
+ * DIM_NAME,
+ * VAR_NAME,
+ * ATTNAME,
+ * GATT_NAME,
+ * PROGNAME
+
+ COMMON /INTCOM/ NFAILS, !/* number of failures in
+ * ! * specific test */
+ * VAR_TYPE,
+ * VAR_RANK,
+ * VAR_DIMID,
+ * VAR_NELS,
+ * VAR_NATTS,
+ * ATTTYPE,
+ * GATT_TYPE,
+ * ATTLEN,
+ * MAX_NMPT,
+ * NFAILSTOTAL
+
+ integer numTypes, numVars, numGatts, cdf_format, extra_flags, info
+ common / PROBLEM_SIZE / numTypes, numVars, numGatts, cdf_format,
+ + extra_flags, info
+
diff --git a/test/nf_test/util.F b/test/nf_test/util.F
new file mode 100644
index 0000000..834449d
--- /dev/null
+++ b/test/nf_test/util.F
@@ -0,0 +1,1531 @@
+!*********************************************************************
+! Copyright 1996, UCAR/Unidata
+! See netcdf/COPYRIGHT file for copying and redistribution conditions.
+! $Id: util.F 2284 2015-12-30 20:27:18Z wkliao $
+!********************************************************************/
+
+ SUBROUTINE PRINT_NOK(NOK)
+ IMPLICIT NONE
+ INTEGER NOK
+ include "pnetcdf.inc"
+#include "tests.inc"
+
+ 123 FORMAT(I4,A)
+ IF (NFAILS .GT. 0) PRINT *, ' '
+ IF (VERBOSE) THEN
+ PRINT 123, NOK, ' good comparisons.'
+ ENDIF
+ END
+
+
+! Is value within external type range? */
+ logical FUNCTION INRANGE(VALUE, DATATYPE)
+ IMPLICIT NONE
+ DOUBLEPRECISION VALUE
+ INTEGER DATATYPE
+ include "pnetcdf.inc"
+#include "tests.inc"
+
+ DOUBLEPRECISION MIN
+ DOUBLEPRECISION MAX
+
+ MIN = X_DOUBLE_MIN
+ MAX = X_DOUBLE_MAX
+
+ IF (DATATYPE .EQ. NF_CHAR) THEN
+ MIN = X_CHAR_MIN
+ MAX = X_CHAR_MAX
+ ELSE IF (DATATYPE .EQ. NF_BYTE) THEN
+ MIN = X_BYTE_MIN
+ MAX = X_BYTE_MAX
+ ELSE IF (DATATYPE .EQ. NF_SHORT) THEN
+ MIN = X_SHORT_MIN
+ MAX = X_SHORT_MAX
+ ELSE IF (DATATYPE .EQ. NF_INT) THEN
+ MIN = X_INT_MIN
+ MAX = X_INT_MAX
+ ELSE IF (DATATYPE .EQ. NF_FLOAT) THEN
+ MIN = X_FLOAT_MIN
+ MAX = X_FLOAT_MAX
+ ELSE IF (DATATYPE .EQ. NF_DOUBLE) THEN
+ MIN = X_DOUBLE_MIN
+ MAX = X_DOUBLE_MAX
+ ELSE IF (DATATYPE .EQ. NF_UBYTE) THEN
+ MIN = 0
+ MAX = X_UCHAR_MAX
+ ELSE IF (DATATYPE .EQ. NF_USHORT) THEN
+ MIN = 0
+ MAX = X_USHORT_MAX
+ ELSE IF (DATATYPE .EQ. NF_UINT) THEN
+ MIN = 0
+ MAX = X_UINT_MAX
+ ELSE IF (DATATYPE .EQ. NF_INT64) THEN
+ INRANGE = (VALUE .GE. X_INT8_MIN) .AND.
+ + (VALUE .LE. X_INT8_MAX)
+ return
+ ELSE IF (DATATYPE .EQ. NF_UINT64) THEN
+ INRANGE = (VALUE .GE. 0) .AND.
+ + (VALUE .LE. X_UINT8_MAX)
+ return
+ ELSE
+ CALL UD_ABORT
+ END IF
+
+ INRANGE = (VALUE .GE. MIN) .AND. (VALUE .LE. MAX)
+ END
+
+
+ logical FUNCTION INRANGE_UCHAR(VALUE, DATATYPE)
+ IMPLICIT NONE
+ DOUBLEPRECISION VALUE
+ INTEGER DATATYPE
+ include "pnetcdf.inc"
+#include "tests.inc"
+ LOGICAL INRANGE
+
+ IF (DATATYPE .EQ. NF_BYTE) THEN
+ INRANGE_UCHAR = (VALUE .GE. 0) .AND. (VALUE .LE. 255)
+ ELSE
+ INRANGE_UCHAR = INRANGE(VALUE, DATATYPE)
+ END IF
+ END
+
+
+ logical FUNCTION INRANGE_FLOAT(VALUE, DATATYPE)
+ IMPLICIT NONE
+ DOUBLEPRECISION VALUE
+ INTEGER DATATYPE
+ include "pnetcdf.inc"
+#include "tests.inc"
+ double precision internal_max
+
+ DOUBLEPRECISION MIN
+ DOUBLEPRECISION MAX
+ REAL FVALUE
+
+ MIN = X_DOUBLE_MIN
+ MAX = X_DOUBLE_MAX
+
+ IF (DATATYPE .EQ. NF_CHAR) THEN
+ MIN = X_CHAR_MIN
+ MAX = X_CHAR_MAX
+ ELSE IF (DATATYPE .EQ. NF_BYTE) THEN
+ MIN = X_BYTE_MIN
+ MAX = X_BYTE_MAX
+ ELSE IF (DATATYPE .EQ. NF_SHORT) THEN
+ MIN = X_SHORT_MIN
+ MAX = X_SHORT_MAX
+ ELSE IF (DATATYPE .EQ. NF_INT) THEN
+ MIN = X_INT_MIN
+ MAX = X_INT_MAX
+ ELSE IF (DATATYPE .EQ. NF_FLOAT) THEN
+ IF (internal_max(NFT_REAL) .LT. X_FLOAT_MAX) THEN
+ MIN = -internal_max(NFT_REAL)
+ MAX = internal_max(NFT_REAL)
+ ELSE
+ MIN = X_FLOAT_MIN
+ MAX = X_FLOAT_MAX
+ END IF
+ ELSE IF (DATATYPE .EQ. NF_DOUBLE) THEN
+ IF (internal_max(NFT_REAL) .LT. X_DOUBLE_MAX) THEN
+ MIN = -internal_max(NFT_REAL)
+ MAX = internal_max(NFT_REAL)
+ ELSE
+ MIN = X_DOUBLE_MIN
+ MAX = X_DOUBLE_MAX
+ END IF
+ ELSE IF (DATATYPE .EQ. NF_UBYTE) THEN
+ MIN = 0
+ MAX = X_UCHAR_MAX
+ ELSE IF (DATATYPE .EQ. NF_USHORT) THEN
+ MIN = 0
+ MAX = X_USHORT_MAX
+ ELSE IF (DATATYPE .EQ. NF_UINT) THEN
+ MIN = 0
+ MAX = X_UINT_MAX
+ ELSE IF (DATATYPE .EQ. NF_INT64) THEN
+ MIN = X_INT8_MIN
+ MAX = X_INT8_MAX
+ ELSE IF (DATATYPE .EQ. NF_UINT64) THEN
+ MIN = 0
+ MAX = X_UINT8_MAX
+ ELSE
+ CALL UD_ABORT
+ END IF
+
+ IF (.NOT.((VALUE .GE. MIN) .AND. (VALUE .LE. MAX))) THEN
+ INRANGE_FLOAT = .FALSE.
+ ELSE
+ FVALUE = real(VALUE)
+ INRANGE_FLOAT = (FVALUE .GE. MIN) .AND. (FVALUE .LE. MAX)
+ END IF
+ END
+
+
+! wrapper for inrange to handle special NF_BYTE/uchar adjustment */
+ logical function inrange3(value, datatype, itype)
+ implicit none
+ doubleprecision value
+ integer datatype
+ integer itype
+ include "pnetcdf.inc"
+#include "tests.inc"
+ logical inrange_float, inrange
+
+ if (itype .eq. NFT_REAL) then
+ inrange3 = inrange_float(value, datatype)
+ else
+ inrange3 = inrange(value, datatype)
+ end if
+ end
+
+
+!
+! Does x == y, where one is internal and other external (netCDF)?
+! Use tolerant comparison based on IEEE FLT_EPSILON or DBL_EPSILON.
+!
+ logical function equal(x, y, extType, itype)
+ implicit none
+ doubleprecision x
+ doubleprecision y
+ integer extType !!/* external data type */
+ integer itype
+ include "pnetcdf.inc"
+#include "tests.inc"
+
+ doubleprecision epsilon
+
+ if ((extType .eq. NF_REAL) .or. (itype .eq. NFT_REAL)) then
+ epsilon = 1.19209290E-07
+ else
+ epsilon = 2.2204460492503131E-16
+ end if
+ equal = abs(x-y) .le. epsilon * max( abs(x), abs(y))
+ end
+
+
+! Test whether two int vectors are equal. If so return 1, else 0 */
+ logical function int_vec_eq(v1, v2, n)
+ implicit none
+ integer n
+ integer v1(n)
+ integer v2(n)
+ include "pnetcdf.inc"
+#include "tests.inc"
+
+ integer i
+
+ int_vec_eq = .true.
+
+ if (n .le. 0)
+ + return
+
+ do 1, i=1, n
+ if (v1(i) .ne. v2(i)) then
+ int_vec_eq = .false.
+ return
+ end if
+1 continue
+ end
+
+
+!
+! Generate random integer from 0 through n-1
+! Like throwing an n-sided dice marked 0, 1, 2, ..., n-1
+!
+ integer function roll(n)
+ implicit none
+ include "pnetcdf.inc"
+#include "tests.inc"
+ integer*8 n
+
+ doubleprecision ud_rand
+ external ud_rand
+
+1 roll = int((ud_rand(0) * (n-1)) + 0.5)
+ if (roll .ge. n) goto 1
+ end
+
+
+!
+! Convert an origin-1 cumulative index to a netCDF index vector.
+! Grosset dimension first; finest dimension last.
+!
+! Authors: Harvey Davies, Unidata/UCAR, Boulder, Colorado
+! Steve Emmerson, (same place)
+!
+ integer function index2ncindexes(index, rank, base, indexes)
+ implicit none
+ integer index !!/* index to be converted */
+ integer rank !/* number of dimensions */
+ include "pnetcdf.inc"
+#include "tests.inc"
+ integer*8 base(rank) !/* base(rank) ignored */
+ integer*8 indexes(rank) !/* returned FORTRAN indexes */
+
+ integer i
+ integer offset
+ integer intbase
+
+ if (rank .gt. 0) then
+ offset = index - 1
+ do 1, i = rank, 1, -1
+ if (base(i) .eq. 0) then
+ index2ncindexes = 1
+ return
+ end if
+ intbase = int(base(i))
+ indexes(i) = 1 + mod(offset, intbase)
+ offset = offset / intbase
+1 continue
+ end if
+ index2ncindexes = 0
+ end
+
+
+!
+! Convert an origin-1 cumulative index to a FORTRAN index vector.
+! Finest dimension first; grossest dimension last.
+!
+! Authors: Harvey Davies, Unidata/UCAR, Boulder, Colorado
+! Steve Emmerson, (same place)
+!
+ integer function index2indexes(index, rank, base, indexes)
+ implicit none
+ integer index !/* index to be converted */
+ integer rank !/* number of dimensions */
+ include "pnetcdf.inc"
+#include "tests.inc"
+ integer*8 base(rank) !/* base(rank) ignored */
+ integer*8 indexes(rank) !/* returned FORTRAN indexes */
+
+ integer i
+ integer offset
+ integer intbase
+
+ if (rank .gt. 0) then
+ offset = index - 1
+ do 1, i = 1, rank
+ if (base(i) .eq. 0) then
+ index2indexes = 1
+ return
+ end if
+ intbase = int(base(i))
+ indexes(i) = 1 + mod(offset, intbase)
+ offset = offset / intbase
+1 continue
+ end if
+ index2indexes = 0
+ end
+
+
+!
+! Convert a FORTRAN index vector to an origin-1 cumulative index.
+! Finest dimension first; grossest dimension last.
+!
+! Authors: Harvey Davies, Unidata/UCAR, Boulder, Colorado
+! Steve Emmerson, (same place)
+!
+ integer function indexes2index(rank, indexes, base)
+ implicit none
+ integer rank !/* number of dimensions */
+ integer indexes(rank) !/* FORTRAN indexes */
+ integer base(rank) !/* base(rank) ignored */
+ include "pnetcdf.inc"
+#include "tests.inc"
+
+ integer i
+
+ indexes2index = 0
+ if (rank .gt. 0) then
+ do 1, i = rank, 1, -1
+ indexes2index = (indexes2index-1) * base(i) + indexes(i)
+1 continue
+ end if
+ end
+
+
+! Generate data values as function of type, rank (-1 for attribute), index */
+ double precision function hash(type, rank, index)
+ implicit none
+ integer type
+ integer rank
+ include "pnetcdf.inc"
+#include "tests.inc"
+ integer*8 index(*)
+
+ doubleprecision base
+ doubleprecision result
+ integer d !/* index of dimension */
+
+ !/* If vector then elements 1 & 2 are min & max. Elements 3 & 4 are */
+ !/* just < min & > max (except for NF_CHAR & NF_DOUBLE) */
+ hash = 0
+ if (abs(rank) .eq. 1 .and. index(1) .le. 4) then
+ if (index(1) .eq. 1) then
+ if (type .eq. NF_CHAR) then
+ hash = X_CHAR_MIN
+ else if (type .eq. NF_BYTE) then
+ hash = X_BYTE_MIN
+ else if (type .eq. NF_SHORT) then
+ hash = X_SHORT_MIN
+ else if (type .eq. NF_INT) then
+ hash = X_INT_MIN
+ else if (type .eq. NF_FLOAT) then
+ hash = X_FLOAT_MIN
+ else if (type .eq. NF_DOUBLE) then
+ hash = X_DOUBLE_MIN
+ else if (type .eq. NF_UBYTE) then
+ hash = 0
+ else if (type .eq. NF_USHORT) then
+ hash = 0
+ else if (type .eq. NF_UINT) then
+ hash = 0
+ else if (type .eq. NF_INT64) then
+ hash = X_INT_MIN - 128.0
+ else if (type .eq. NF_UINT64) then
+ hash = 0
+ else
+ print*, 'Error: no such nc_type ',type
+ call ud_abort
+ end if
+ else if (index(1) .eq. 2) then
+ if (type .eq. NF_CHAR) then
+ hash = X_CHAR_MAX
+ else if (type .eq. NF_BYTE) then
+ hash = X_BYTE_MAX
+ else if (type .eq. NF_SHORT) then
+ hash = X_SHORT_MAX
+ else if (type .eq. NF_INT) then
+ hash = X_INT_MAX
+ else if (type .eq. NF_FLOAT) then
+ hash = X_FLOAT_MAX
+ else if (type .eq. NF_DOUBLE) then
+ hash = X_DOUBLE_MAX
+ else if (type .eq. NF_UBYTE) then
+ hash = X_UCHAR_MAX
+ else if (type .eq. NF_USHORT) then
+ hash = X_USHORT_MAX
+ else if (type .eq. NF_UINT) then
+ hash = X_UINT_MAX
+ else if (type .eq. NF_INT64) then
+ hash = X_INT_MAX + 128.0
+ else if (type .eq. NF_UINT64) then
+ hash = X_UINT_MAX + 128.0
+ else
+ print*, 'Error: no such nc_type ',type
+ call ud_abort
+ end if
+ else if (index(1) .eq. 3) then
+ if (type .eq. NF_CHAR) then
+ hash = ichar('A')
+ else if (type .eq. NF_BYTE) then
+ hash = X_BYTE_MIN-1.0
+ else if (type .eq. NF_SHORT) then
+ hash = X_SHORT_MIN-1.0
+ else if (type .eq. NF_INT) then
+ hash = X_INT_MIN
+ else if (type .eq. NF_FLOAT) then
+ hash = X_FLOAT_MIN
+ else if (type .eq. NF_DOUBLE) then
+ hash = -1.0
+ else if (type .eq. NF_UBYTE) then
+ hash = -1.0
+ else if (type .eq. NF_USHORT) then
+ hash = -1.0
+ else if (type .eq. NF_UINT) then
+ hash = -1.0
+ else if (type .eq. NF_INT64) then
+ hash = -1.0
+ else if (type .eq. NF_UINT64) then
+ hash = -1.0
+ else
+ print*, 'Error: no such nc_type ',type
+ call ud_abort
+ end if
+ else if (index(1) .eq. 4) then
+ if (type .eq. NF_CHAR) then
+ hash = ichar('Z')
+ else if (type .eq. NF_BYTE) then
+ hash = X_BYTE_MAX+1.0
+ else if (type .eq. NF_SHORT) then
+ hash = X_SHORT_MAX+1.0
+ else if (type .eq. NF_INT) then
+ hash = X_INT_MAX+1.0
+ else if (type .eq. NF_FLOAT) then
+ hash = X_FLOAT_MAX
+ else if (type .eq. NF_DOUBLE) then
+ hash = 1.0
+ else if (type .eq. NF_UBYTE) then
+ hash = X_UCHAR_MAX + 1.0
+ else if (type .eq. NF_USHORT) then
+ hash = X_USHORT_MAX + 1.0
+ else if (type .eq. NF_UINT) then
+ hash = X_UINT_MAX + 1.0
+ else if (type .eq. NF_INT64) then
+ hash = 1.0
+ else if (type .eq. NF_UINT64) then
+ hash = 1.0
+ else
+ print*, 'Error: no such nc_type ',type
+ call ud_abort
+ end if
+ end if
+ else
+ if (type .eq. NF_CHAR) then
+ base = 2
+ else if (type .eq. NF_BYTE) then
+ base = -2
+ else if (type .eq. NF_SHORT) then
+ base = -5
+ else if (type .eq. NF_INT) then
+ base = -20
+ else if (type .eq. NF_FLOAT) then
+ base = -9
+ else if (type .eq. NF_DOUBLE) then
+ base = -10
+ else if (type .eq. NF_UBYTE) then
+ base = 2
+ else if (type .eq. NF_USHORT) then
+ base = 5
+ else if (type .eq. NF_UINT) then
+ base = 20
+ else if (type .eq. NF_INT64) then
+ base = -20
+ else if (type .eq. NF_UINT64) then
+ base = 20
+ else
+ print*, 'Error: no such nc_type ',type
+ stop 'in hash()'
+ end if
+
+ if (rank .lt. 0) then
+ result = base * 7
+ else
+ result = base * (rank + 1)
+ end if
+
+! /*
+! * NB: Finest netCDF dimension assumed first.
+! */
+ do 1, d = abs(rank), 1, -1
+ result = base * (result + index(d) - 1)
+1 continue
+ hash = result
+ end if
+ end
+
+
+! wrapper for hash to handle special NC_BYTE/uchar adjustment */
+ double precision function hash4(type, rank, index, itype)
+ implicit none
+ integer type
+ integer rank
+ include "pnetcdf.inc"
+#include "tests.inc"
+ double precision hash
+
+ integer*8 index(*)
+ integer itype
+
+ hash4 = hash( type, rank, index )
+ if ((itype .eq. NFT_CHAR) .and. (type .eq. NF_BYTE) .and.
+ + (hash4 .ge. -128) .and. (hash4 .lt. 0)) hash4 = hash4 + 256
+ end
+
+
+ integer function char2type(letter)
+ implicit none
+ character*1 letter
+ include "pnetcdf.inc"
+#include "tests.inc"
+
+ if (letter .eq. 'c') then
+ char2type = NF_CHAR
+ else if (letter .eq. 'b') then
+ char2type = NF_BYTE
+ else if (letter .eq. 's') then
+ char2type = NF_SHORT
+ else if (letter .eq. 'i') then
+ char2type = NF_INT
+ else if (letter .eq. 'f') then
+ char2type = NF_FLOAT
+ else if (letter .eq. 'd') then
+ char2type = NF_DOUBLE
+ else if (letter .eq. 'y') then
+ char2type = NF_UBYTE
+ else if (letter .eq. 't') then
+ char2type = NF_USHORT
+ else if (letter .eq. 'u') then
+ char2type = NF_UINT
+ else if (letter .eq. 'x') then
+ char2type = NF_INT64
+ else if (letter .eq. 'z') then
+ char2type = NF_UINT64
+ else
+ stop 'char2type(): invalid type-letter'
+ end if
+ end
+
+
+ subroutine init_dims(digit)
+ implicit none
+ character*1 digit(NDIMS)
+ include "pnetcdf.inc"
+#include "tests.inc"
+
+ integer dimid !/* index of dimension */
+ do 1, dimid = 1, NDIMS
+ if (dimid .eq. RECDIM) then
+ dim_len(dimid) = NRECS
+ else
+ dim_len(dimid) = dimid - 1
+ endif
+ dim_name(dimid) = 'D' // digit(dimid)
+1 continue
+ end
+
+
+ subroutine init_gatts(type_letter)
+ implicit none
+ character*1 type_letter(NTYPES)
+ include "pnetcdf.inc"
+#include "tests.inc"
+
+ integer attid
+ integer char2type
+
+ do 1, attid = 1, numTypes
+ gatt_name(attid) = 'G' // type_letter(attid)
+ gatt_len(attid) = attid
+ gatt_type(attid) = char2type(type_letter(attid))
+1 continue
+ end
+
+
+ integer function prod(nn, sp)
+ implicit none
+ integer nn
+ include "pnetcdf.inc"
+#include "tests.inc"
+ integer*8 sp(MAX_RANK)
+
+ integer i
+
+ prod = 1
+ do 1, i = 1, nn
+ prod = prod * int(sp(i))
+1 continue
+ end
+
+
+!
+! define global variables:
+! dim_name, dim_len,
+! var_name, var_type, var_rank, var_shape, var_natts, var_dimid, var_nels
+! att_name, gatt_name, att_type, gatt_type, att_len, gatt_len
+!
+
+ subroutine init_gvars
+ implicit none
+ include "pnetcdf.inc"
+#include "tests.inc"
+ integer index2ncindexes
+
+ integer*8 max_dim_len(MAX_RANK)
+ character*1 type_letter(NTYPES)
+ character*1 digit(10)
+
+ integer rank
+ integer vn !/* var number */
+ integer xtype !/* index of type */
+ integer an !/* origin-0 cumulative attribute index */
+ integer nvars
+ integer jj
+ integer n_types
+ integer tc
+ integer*8 tmp(MAX_RANK)
+ integer ac !/* attribute index */
+ integer dn !/* dimension number */
+ integer prod !/* function */
+ integer char2type !/* function */
+ integer err
+
+ data max_dim_len /0, MAX_DIM_LEN, MAX_DIM_LEN/
+ data type_letter /'c', 'b', 's', 'i', 'f', 'd', 'y',
+ + 't', 'u', 'x', 'z'/
+ data digit /'r', '1', '2', '3', '4', '5',
+ + '6', '7', '8', '9'/
+
+ max_dim_len(1) = MAX_DIM_LEN + 1
+
+ call init_dims(digit)
+
+ vn = 1
+ xtype = 1
+ an = 0
+
+! /* Loop over variable ranks */
+ do 1, rank = 0, MAX_RANK
+ nvars = prod(rank, max_dim_len)
+
+ !/* Loop over variable shape vectors */
+ do 2, jj = 1, nvars !/* 1, 5, 20, 80 */
+ !/* number types of this shape */
+ if (rank .lt. 2) then
+ n_types = numTypes !/* 6 */
+ else
+ n_types = 1
+ end if
+
+ !/* Loop over external data types */
+ do 3, tc = 1, n_types !/* 6, 1 */
+ var_name(vn) = type_letter(xtype)
+ var_type(vn) = char2type(type_letter(xtype))
+ var_rank(vn) = rank
+ if (rank .eq. 0) then
+ var_natts(vn) = mod(vn - 1, MAX_NATTS + 1)
+ else
+ var_natts(vn) = 0
+ end if
+
+ do 4, ac = 1, var_natts(vn)
+ attname(ac,vn) =
+ + type_letter(1+mod(an, numTypes))
+ attlen(ac,vn) = an
+ atttype(ac,vn) =
+ + char2type(type_letter(1+mod(an, numTypes)))
+ an = an + 1
+4 continue
+
+ !/* Construct initial shape vector */
+ err = index2ncindexes(jj, rank, max_dim_len, tmp)
+ do 5, dn = 1, rank
+ var_dimid(dn,vn) = int(tmp(1+rank-dn))
+5 continue
+
+ var_nels(vn) = 1
+ do 6, dn = 1, rank
+ if (dn .lt. rank) then
+ var_dimid(dn,vn) = var_dimid(dn,vn) + 1
+ end if
+ if (var_dimid(dn,vn) .gt. 9) then
+ stop 'Invalid var_dimid vector'
+ end if
+ var_name(vn)(rank+2-dn:rank+2-dn) =
+ + digit(var_dimid(dn,vn))
+ if (var_dimid(dn,vn) .ne. RECDIM) then
+ var_shape(dn,vn) = var_dimid(dn,vn) - 1
+ else
+ var_shape(dn,vn) = NRECS
+ end if
+ var_nels(vn) = var_nels(vn) *
+ + int(var_shape(dn,vn))
+6 continue
+
+ vn = vn + 1
+ xtype = 1 + mod(xtype, numTypes)
+3 continue
+2 continue
+1 continue
+
+ call init_gatts(type_letter)
+ end
+
+
+! define dims defined by global variables */
+ subroutine def_dims(ncid)
+ implicit none
+ integer ncid
+ include "pnetcdf.inc"
+#include "tests.inc"
+
+ integer err !/* status */
+ integer i
+ integer dimid !/* dimension id */
+
+ do 1, i = 1, NDIMS
+ if (i .eq. RECDIM) then
+ err = nfmpi_def_dim(ncid, dim_name(i), NFMPI_UNLIMITED,
+ + dimid)
+ else
+ err = nfmpi_def_dim(ncid, dim_name(i), dim_len(i),
+ + dimid)
+ end if
+ if (err .ne. NF_NOERR) then
+ call errore('nfmpi_def_dim: ', err)
+ end if
+1 continue
+ end
+
+
+! define vars defined by global variables */
+ subroutine def_vars(ncid)
+ implicit none
+ integer ncid
+ include "pnetcdf.inc"
+#include "tests.inc"
+
+ integer err !/* status */
+ integer i
+ integer var_id
+
+ do 1, i = 1, numVars
+ err = nfmpi_def_var(ncid, var_name(i), var_type(i),
+ + var_rank(i), var_dimid(1,i), var_id)
+ if (err .ne. NF_NOERR) then
+ call errore('nfmpi_def_var: ', err)
+ end if
+1 continue
+ end
+
+
+! put attributes defined by global variables */
+ subroutine put_atts(ncid)
+ implicit none
+ integer ncid
+ include "pnetcdf.inc"
+#include "tests.inc"
+ integer VARID, NATTS, ATT_TYPE, ATT_LEN
+ integer*8 ATT_LEN_LL
+ CHARACTER*2 ATT_NAME
+ double precision hash
+ logical inrange
+
+ integer err !/* netCDF status */
+ integer i !/* variable index (0 => global
+ ! * attribute */
+ integer k !/* attribute index */
+ integer j !/* index of attribute */
+ integer*8 ndx(1)
+ logical allInRange
+ doubleprecision att(MAX_NELS)
+ character*(MAX_NELS+2) catt
+
+ do 1, i = 0, numVars !/* var 0 => NF_GLOBAL attributes */
+ do 2, j = 1, NATTS(i)
+ if (NF_CHAR .eq. ATT_TYPE(j,i)) then
+ catt = ' '
+ do 3, k = 1, ATT_LEN(j,i)
+ ndx(1) = k
+ catt(k:k) = char(int(hash(ATT_TYPE(j,i), -1,
+ + ndx)))
+3 continue
+! /*
+! * The following ensures that the text buffer doesn't
+! * start with 4 zeros (which is a CFORTRAN NULL pointer
+! * indicator) yet contains a zero (which causes the
+! * CFORTRAN interface to pass the address of the
+! * actual text buffer).
+! */
+ catt(ATT_LEN(j,i)+1:ATT_LEN(j,i)+1) = char(1)
+ catt(ATT_LEN(j,i)+2:ATT_LEN(j,i)+2) = char(0)
+
+ ATT_LEN_LL = ATT_LEN(j,i)
+ err = nfmpi_put_att_text(ncid, varid(i),
+ + ATT_NAME(j,i),
+ + ATT_LEN_LL, catt)
+ if (err .ne. NF_NOERR) then
+ call errore('nfmpi_put_att_text: ', err)
+ end if
+ else
+ allInRange = .true.
+ do 4, k = 1, ATT_LEN(j,i)
+ ndx(1) = k
+ att(k) = hash(ATT_TYPE(j,i), -1, ndx)
+ allInRange = allInRange .and.
+ + inRange(att(k), ATT_TYPE(j,i))
+4 continue
+ ATT_LEN_LL = ATT_LEN(j,i)
+ err = nfmpi_put_att_double(ncid, varid(i),
+ + ATT_NAME(j,i),
+ + ATT_TYPE(j,i),
+ + ATT_LEN_LL, att)
+ if (allInRange) then
+ if (err .ne. NF_NOERR) then
+ call errore('nfmpi_put_att_double: ', err)
+ end if
+ else
+ if (err .ne. NF_ERANGE) then
+ call errore(
+ + 'type-conversion range error: status = ',
+ + err)
+ end if
+ end if
+ end if
+2 continue
+1 continue
+ end
+
+
+! put variables defined by global variables */
+ subroutine put_vars(ncid)
+ implicit none
+ integer ncid
+ include "pnetcdf.inc"
+#include "tests.inc"
+ integer index2indexes
+ double precision hash
+ logical inrange
+
+ integer*8 start(MAX_RANK)
+ integer*8 index(MAX_RANK)
+ integer err !/* netCDF status */
+ integer i
+ integer j
+ doubleprecision value(MAX_NELS)
+ character*(MAX_NELS+2) text
+ logical allInRange
+
+ do 1, j = 1, MAX_RANK
+ start(j) = 1
+1 continue
+
+ do 2, i = 1, numVars
+ allInRange = .true.
+ do 3, j = 1, var_nels(i)
+ err = index2indexes(j, var_rank(i), var_shape(1,i),
+ + index)
+ if (err .ne. NF_NOERR) then
+ call errori(
+ + 'Error calling index2indexes() for var ', j)
+ end if
+ if (var_name(i)(1:1) .eq. 'c') then
+ text(j:j) =
+ + char(int(hash(var_type(i), var_rank(i), index)))
+ else
+ value(j) = hash(var_type(i), var_rank(i), index)
+ allInRange = allInRange .and.
+ + inRange(value(j), var_type(i))
+ end if
+3 continue
+ if (var_name(i)(1:1) .eq. 'c') then
+! /*
+! * The following statement ensures that the first 4
+! * characters in 'text' are not all zeros (which is
+! * a cfortran.h NULL indicator) and that the string
+! * contains a zero (which will cause the address of the
+! * actual string buffer to be passed).
+! */
+ text(var_nels(i)+1:var_nels(i)+1) = char(1)
+ text(var_nels(i)+2:var_nels(i)+2) = char(0)
+ err = nfmpi_put_vara_text_all(ncid, i, start,
+ + var_shape(1,i), text)
+ if (err .ne. NF_NOERR) then
+ call errore('nfmpi_put_vara_text_all: ', err)
+ end if
+ else
+ err = nfmpi_put_vara_double_all(ncid, i, start,
+ + var_shape(1,i), value)
+ if (allInRange) then
+ if (err .ne. NF_NOERR) then
+ call errore('nfmpi_put_vara_double_all: ', err)
+ end if
+ else
+ if (err .ne. NF_ERANGE) then
+ call errore('put_vars '//
+ + 'type-conversion range error: status = ',
+ + err)
+ end if
+ end if
+ end if
+2 continue
+ end
+
+
+! Create & write all of specified file using global variables */
+ subroutine write_file(filename)
+ implicit none
+ character*(*) filename
+ include "pnetcdf.inc"
+#include "tests.inc"
+
+ integer MY_LEN_TRIM
+ integer ncid !/* netCDF id */
+ integer err !/* netCDF status */
+ integer flags
+
+ flags = IOR(NF_CLOBBER, extra_flags)
+ err = nfmpi_create(comm, filename, flags, info, ncid)
+ if (err .ne. NF_NOERR) then
+ call errore('nfmpi_create: '//
+ + TRIM(filename), err)
+ end if
+
+ call def_dims(ncid)
+ call def_vars(ncid)
+ call put_atts(ncid)
+ err = nfmpi_enddef(ncid)
+ if (err .ne. NF_NOERR) then
+ call errore('nfmpi_enddef: ', err)
+ end if
+ call put_vars(ncid)
+
+ err = nfmpi_close(ncid)
+ if (err .ne. NF_NOERR) then
+ call errore('nfmpi_close: ', err)
+ end if
+ end
+
+
+!
+! check dimensions of specified file have expected name & length
+!
+ subroutine check_dims(ncid)
+ implicit none
+ integer ncid
+ include "pnetcdf.inc"
+#include "tests.inc"
+
+ character*(NF_MAX_NAME) name
+ integer*8 length
+ integer i
+ integer err !/* netCDF status */
+
+ do 1, i = 1, NDIMS
+ err = nfmpi_inq_dim(ncid, i, name, length)
+ if (err .ne. NF_NOERR) then
+ call errore('nfmpi_inq_dim: ', err)
+ end if
+ if (name .ne. dim_name(i)) then
+ call errori('Unexpected name of dimension ', i)
+ end if
+ if (length .ne. dim_len(i)) then
+ call errori('Unexpected length of dimension ', i)
+ end if
+1 continue
+ end
+
+
+!
+! check variables of specified file have expected name, type, shape & values
+!
+ subroutine check_vars(ncid)
+ implicit none
+ integer ncid
+ include "pnetcdf.inc"
+#include "tests.inc"
+ integer index2indexes
+ double precision hash
+ logical inrange, equal
+
+ integer*8 index(MAX_RANK)
+ integer err !/* netCDF status */
+ integer i
+ integer j
+ character*1 text
+ doubleprecision value
+ integer datatype
+ integer ndims
+ integer natt
+ integer dimids(MAX_RANK)
+ logical isChar
+ doubleprecision expect
+ character*(NF_MAX_NAME) name
+ integer*8 length
+ integer nok !/* count of valid comparisons */
+
+ nok = 0
+ err = nfmpi_begin_indep_data(ncid)
+
+ do 1, i = 1, numVars
+ isChar = var_type(i) .eq. NF_CHAR
+ err = nfmpi_inq_var(ncid, i, name, datatype, ndims, dimids,
+ + natt)
+ if (err .ne. NF_NOERR) then
+ call errore('nfmpi_inq_var: ', err)
+ end if
+ if (name .ne. var_name(i)) then
+ call errori('Unexpected var_name for variable ', i)
+ end if
+ if (datatype .ne. var_type(i)) then
+ call errori('Unexpected type for variable ', i)
+ end if
+ if (ndims .ne. var_rank(i)) then
+ call errori('Unexpected rank for variable ', i)
+ end if
+ do 2, j = 1, ndims
+ err = nfmpi_inq_dim(ncid, dimids(j), name, length)
+ if (err .ne. NF_NOERR) then
+ call errore('nfmpi_inq_dim: ', err)
+ end if
+ if (length .ne. var_shape(j,i)) then
+ call errori('Unexpected shape for variable ', i)
+ end if
+2 continue
+ do 3, j = 1, var_nels(i)
+ err = index2indexes(j, var_rank(i), var_shape(1,i),
+ + index)
+ if (err .ne. NF_NOERR) then
+ call errori('error in index2indexes() 2, variable ',
+ + i)
+ end if
+ expect = hash(var_type(i), var_rank(i), index )
+ if (isChar) then
+ err = nfmpi_get_var1_text(ncid, i, index, text)
+ if (err .ne. NF_NOERR) then
+ call errore('nfmpi_get_var1_text: ', err)
+ end if
+ if (ichar(text) .ne. expect) then
+ call errori(
+ + 'Var value read not that expected for variable ', i)
+ call errord(' expecting ',expect)
+ call errori(' but got ', ichar(text))
+ else
+ nok = nok + 1
+ end if
+ else
+ err = nfmpi_get_var1_double(ncid, i, index,
+ + value)
+ if (inRange(expect,var_type(i))) then
+ if (err .ne. NF_NOERR) then
+ call errore('nfmpi_get_var1_double: ', err)
+ else
+ if (.not. equal(value,expect,var_type(i),
+ + NFT_DOUBLE)) then
+ call errori(
+ + 'Var value read not that expected for variable ', i)
+ else
+ nok = nok + 1
+ end if
+ end if
+ end if
+ end if
+3 continue
+1 continue
+ err = nfmpi_end_indep_data(ncid)
+ ! call print_nok(nok)
+ end
+
+
+!
+! check attributes of specified file have expected name, type, length & values
+!
+ subroutine check_atts(ncid)
+ implicit none
+ integer ncid
+ include "pnetcdf.inc"
+#include "tests.inc"
+ integer VARID, NATTS, ATT_TYPE, ATT_LEN
+ CHARACTER*2 ATT_NAME
+ double precision hash
+ logical inrange, equal
+
+ integer err !/* netCDF status */
+ integer i
+ integer j
+ integer k
+ integer vid !/* "variable" ID */
+ integer datatype
+ integer*8 ndx(1)
+ character*(NF_MAX_NAME) name
+ integer*8 length
+ character*(MAX_NELS) text
+ doubleprecision value(MAX_NELS)
+ doubleprecision expect
+ integer nok !/* count of valid comparisons */
+
+ nok = 0
+
+ do 1, vid = 0, numVars
+ i = varid(vid)
+
+ do 2, j = 1, NATTS(i)
+ err = nfmpi_inq_attname(ncid, i, j, name)
+ if (err .ne. NF_NOERR) then
+ call errore('nfmpi_inq_attname: ', err)
+ end if
+ if (name .ne. ATT_NAME(j,i)) then
+ call errori(
+ + 'nfmpi_inq_attname: unexpected name for var ', i)
+ end if
+ err = nfmpi_inq_att(ncid, i, name, datatype, length)
+ if (err .ne. NF_NOERR) then
+ call errore('nfmpi_inq_att: ', err)
+ end if
+ if (datatype .ne. ATT_TYPE(j,i)) then
+ call errori(
+ + 'nfmpi_inq_att: unexpected type for var ', i)
+ end if
+ if (length .ne. ATT_LEN(j,i)) then
+ call errori(
+ + 'nfmpi_inq_att: unexpected length for var ', i)
+ end if
+ if (datatype .eq. NF_CHAR) then
+ err = nfmpi_get_att_text(ncid, i, name, text)
+ if (err .ne. NF_NOERR) then
+ call errore('nfmpi_get_att_text: ', err)
+ end if
+ do 3, k = 1, ATT_LEN(j,i)
+ ndx(1) = k
+ if (ichar(text(k:k)) .ne. hash(datatype, -1,
+ + ndx))
+ + then
+ call errori(
+ + 'nfmpi_get_att_text: unexpected value for var ', i)
+ else
+ nok = nok + 1
+ end if
+3 continue
+ else
+ err = nfmpi_get_att_double(ncid, i, name, value)
+ do 4, k = 1, ATT_LEN(j,i)
+ ndx(1) = k
+ expect = hash(datatype, -1, ndx)
+ if (inRange(expect,ATT_TYPE(j,i))) then
+ if (err .ne. NF_NOERR) then
+ call errore(
+ + 'nfmpi_get_att_double: ', err)
+ end if
+ if (.not. equal(value(k), expect,
+ + ATT_TYPE(j,i), NFT_DOUBLE)) then
+ call errori(
+ + 'Att value read not that expected for var ', i)
+ else
+ nok = nok + 1
+ end if
+ end if
+4 continue
+ end if
+2 continue
+1 continue
+ ! call print_nok(nok)
+ end
+
+
+! Check file (dims, vars, atts) corresponds to global variables */
+ subroutine check_file(filename)
+ implicit none
+ character*(*) filename
+ include "pnetcdf.inc"
+#include "tests.inc"
+
+ integer ncid !/* netCDF id */
+ integer err !/* netCDF status */
+
+ err = nfmpi_open(comm, filename, NF_NOWRITE, info, ncid)
+ if (err .ne. NF_NOERR) then
+ call errore('nfmpi_open: ', err)
+ else
+ call check_dims(ncid)
+ call check_vars(ncid)
+ call check_atts(ncid)
+ err = nfmpi_close (ncid)
+ if (err .ne. NF_NOERR) then
+ call errore('nfmpi_close: ', err)
+ end if
+ end if
+ end
+
+
+!
+! Functions for accessing attribute test data.
+!
+! NB: 'varid' is 0 for global attributes; thus, global attributes can
+! be handled in the same loop as variable attributes.
+!
+
+ integer FUNCTION VARID(VID)
+ IMPLICIT NONE
+ INTEGER VID
+ include "pnetcdf.inc"
+#include "tests.inc"
+ IF (VID .LT. 1) THEN
+ VARID = NF_GLOBAL
+ ELSE
+ VARID = VID
+ ENDIF
+ end
+
+
+ integer FUNCTION NATTS(VID)
+ IMPLICIT NONE
+ INTEGER VID
+ include "pnetcdf.inc"
+#include "tests.inc"
+ IF (VID .LT. 1) THEN
+ NATTS = numGatts
+ ELSE
+ NATTS = VAR_NATTS(VID)
+ ENDIF
+ END
+
+
+ character*2 FUNCTION ATT_NAME(J,VID)
+ IMPLICIT NONE
+ INTEGER J
+ INTEGER VID
+ include "pnetcdf.inc"
+#include "tests.inc"
+ IF (VID .LT. 1) THEN
+ ATT_NAME = GATT_NAME(J)
+ ELSE
+ ATT_NAME = ATTNAME(J,VID)
+ ENDIF
+ END
+
+
+ integer FUNCTION ATT_TYPE(J,VID)
+ IMPLICIT NONE
+ INTEGER J
+ INTEGER VID
+ include "pnetcdf.inc"
+#include "tests.inc"
+ IF (VID .LT. 1) THEN
+ ATT_TYPE = GATT_TYPE(J)
+ ELSE
+ ATT_TYPE = ATTTYPE(J,VID)
+ ENDIF
+ END
+
+
+ integer FUNCTION ATT_LEN(J,VID)
+ IMPLICIT NONE
+ INTEGER J
+ INTEGER VID
+ include "pnetcdf.inc"
+#include "tests.inc"
+ IF (VID .LT. 1) THEN
+ ATT_LEN = int(GATT_LEN(J))
+ ELSE
+ ATT_LEN = ATTLEN(J,VID)
+ ENDIF
+ END
+
+
+!
+! Return the minimum value of an internal type.
+!
+ doubleprecision function internal_min(type)
+ implicit none
+ integer type
+ doubleprecision min_schar
+ doubleprecision min_short
+ doubleprecision min_int
+ ! doubleprecision min_long
+ doubleprecision max_float
+ doubleprecision max_double
+ doubleprecision min_int64
+ include "pnetcdf.inc"
+#include "tests.inc"
+
+ if (type .eq. NFT_CHAR) then
+ internal_min = 0
+ else if (type .eq. NFT_INT1) then
+#if defined NF_INT1_IS_C_SIGNED_CHAR
+ internal_min = min_schar()
+#elif defined NF_INT1_IS_C_SHORT
+ internal_min = min_short()
+#elif defined NF_INT1_IS_C_INT
+ internal_min = min_int()
+#elif defined NF_INT1_IS_C_LONG
+ internal_min = min_long()
+#else
+ internal_min = min_schar()
+! #include "No C equivalent to Fortran INTEGER*1"
+#endif
+ else if (type .eq. NFT_INT2) then
+#if defined NF_INT2_IS_C_SHORT
+ internal_min = min_short()
+#elif defined NF_INT2_IS_C_INT
+ internal_min = min_int()
+#elif defined NF_INT2_IS_C_LONG
+ internal_min = min_long()
+#else
+ internal_min = min_short()
+! #include "No C equivalent to Fortran INTEGER*2"
+#endif
+ else if (type .eq. NFT_INT) then
+#if defined NF_INT_IS_C_INT
+ internal_min = min_int()
+#elif defined NF_INT_IS_C_LONG
+ internal_min = min_long()
+#else
+ internal_min = min_int()
+! #include "No C equivalent to Fortran INTEGER"
+#endif
+ else if (type .eq. NFT_REAL) then
+#if defined NF_REAL_IS_C_FLOAT
+ internal_min = -max_float()
+#elif defined NF_REAL_IS_C_DOUBLE
+ internal_min = -max_double()
+#else
+ internal_min = -max_float()
+! #include "No C equivalent to Fortran REAL"
+#endif
+ else if (type .eq. NFT_DOUBLE) then
+#if defined NF_DOUBLEPRECISION_IS_C_DOUBLE
+ internal_min = -max_double()
+#elif defined NF_DOUBLEPRECISION_IS_C_FLOAT
+ internal_min = -max_float()
+#else
+ internal_min = -max_double()
+! #include "No C equivalent to Fortran DOUBLE"
+#endif
+ else if (type .eq. NFT_INT8) then
+ internal_min = min_int64()
+ else
+ stop 'internal_min(): invalid type'
+ end if
+ end
+
+
+!
+! Return the maximum value of an internal type.
+!
+ doubleprecision function internal_max(type)
+ implicit none
+ integer type
+ doubleprecision max_schar
+ doubleprecision max_short
+ doubleprecision max_int
+ ! doubleprecision max_long
+ doubleprecision max_float
+ doubleprecision max_double
+ doubleprecision max_int64
+ include "pnetcdf.inc"
+#include "tests.inc"
+
+ if (type .eq. NFT_CHAR) then
+ internal_max = 255
+ else if (type .eq. NFT_INT1) then
+#if defined NF_INT1_IS_C_SIGNED_CHAR
+ internal_max = max_schar()
+#elif defined NF_INT1_IS_C_SHORT
+ internal_max = max_short()
+#elif defined NF_INT1_IS_C_INT
+ internal_max = max_int()
+#elif defined NF_INT1_IS_C_LONG
+ internal_max = max_long()
+#else
+ internal_max = max_schar()
+! #include "No C equivalent to Fortran INTEGER*1"
+#endif
+ else if (type .eq. NFT_INT2) then
+#if defined NF_INT2_IS_C_SHORT
+ internal_max = max_short()
+#elif defined NF_INT2_IS_C_INT
+ internal_max = max_int()
+#elif defined NF_INT2_IS_C_LONG
+ internal_max = max_long()
+#else
+ internal_max = max_short()
+! #include "No C equivalent to Fortran INTEGER*2"
+#endif
+ else if (type .eq. NFT_INT) then
+#if defined NF_INT_IS_C_INT
+ internal_max = max_int()
+#elif defined NF_INT_IS_C_LONG
+ internal_max = max_long()
+#else
+ internal_max = max_int()
+! #include "No C equivalent to Fortran INTEGER"
+#endif
+ else if (type .eq. NFT_REAL) then
+#if defined NF_REAL_IS_C_FLOAT
+ internal_max = max_float()
+#elif defined NF_REAL_IS_C_DOUBLE
+ internal_max = max_double()
+#else
+ internal_max = max_float()
+! #include "No C equivalent to Fortran REAL"
+#endif
+ else if (type .eq. NFT_DOUBLE) then
+#if defined NF_DOUBLEPRECISION_IS_C_DOUBLE
+ internal_max = max_double()
+#elif defined NF_DOUBLEPRECISION_IS_C_FLOAT
+ internal_max = max_float()
+#else
+ internal_max = max_double()
+! #include "No C equivalent to Fortran DOUBLE"
+#endif
+ else if (type .eq. NFT_INT8) then
+ internal_max = max_int64()
+ else
+ stop 'internal_max(): invalid type'
+ end if
+ end
+
+
+!
+! Return the minimum value of an external type.
+!
+ doubleprecision function external_min(type)
+ implicit none
+ integer type
+ include "pnetcdf.inc"
+#include "tests.inc"
+
+ if (type .eq. NF_BYTE) then
+ external_min = X_BYTE_MIN
+ else if (type .eq. NF_CHAR) then
+ external_min = X_CHAR_MIN
+ else if (type .eq. NF_SHORT) then
+ external_min = X_SHORT_MIN
+ else if (type .eq. NF_INT) then
+ external_min = X_INT_MIN
+ else if (type .eq. NF_FLOAT) then
+ external_min = X_FLOAT_MIN
+ else if (type .eq. NF_DOUBLE) then
+ external_min = X_DOUBLE_MIN
+ else if (type .eq. NF_INT64) then
+ external_min = X_INT8_MIN
+ else
+ stop 'external_min(): invalid type'
+ end if
+ end
+
+
+!
+! Return the maximum value of an internal type.
+!
+ doubleprecision function external_max(type)
+ implicit none
+ integer type
+ include "pnetcdf.inc"
+#include "tests.inc"
+
+ if (type .eq. NF_BYTE) then
+ external_max = X_BYTE_MAX
+ else if (type .eq. NF_CHAR) then
+ external_max = X_CHAR_MAX
+ else if (type .eq. NF_SHORT) then
+ external_max = X_SHORT_MAX
+ else if (type .eq. NF_INT) then
+ external_max = X_INT_MAX
+ else if (type .eq. NF_FLOAT) then
+ external_max = X_FLOAT_MAX
+ else if (type .eq. NF_DOUBLE) then
+ external_max = X_DOUBLE_MAX
+ else if (type .eq. NF_INT64) then
+ external_max = X_INT8_MAX
+ else
+ stop 'external_max(): invalid type'
+ end if
+ end
+
+
+!
+! Indicate whether or not a value lies in the range of an internal type.
+!
+ logical function in_internal_range(itype, value)
+ implicit none
+ integer itype
+ doubleprecision value
+ include "pnetcdf.inc"
+#include "tests.inc"
+ double precision internal_min, internal_max
+
+ in_internal_range = value .ge. internal_min(itype) .and.
+ + value .le. internal_max(itype)
+ end
+
+! Returns length of string ignoring trailing blanks
+ INTEGER FUNCTION MY_LEN_TRIM(STRING)
+ CHARACTER*(*) STRING
+ DO I = LEN(STRING), 1, -1
+ IF (STRING(I:I) .NE. ' ') go to 10
+ ENDDO
+ 10 MY_LEN_TRIM = I
+ END ! FUNCTION MY_LEN_TRIM
+
diff --git a/test/nonblocking/Makefile.in b/test/nonblocking/Makefile.in
new file mode 100644
index 0000000..b65dc9c
--- /dev/null
+++ b/test/nonblocking/Makefile.in
@@ -0,0 +1,140 @@
+#
+# Copyright (C) 2012, Northwestern University and Argonne National Laboratory
+# See COPYRIGHT notice in top-level directory.
+#
+# $Id: Makefile.in 2251 2015-12-20 21:13:42Z wkliao $
+#
+# @configure_input@
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+include ../../macros.make
+
+INCLUDES = -I../../src/lib -I$(srcdir)/../common
+FPPFLAGS += -I../../src/libf @FC_MODINC at ../../src/libf90 @FC_MODINC at ../common
+LDFLAGS := -L../common $(LDFLAGS)
+LIBS := $(LIBRARY) -ltestutils $(LIBS) @LCOV_LIB@
+ifeq (@PNC_DEBUG@, yes)
+CPPFLAGS := $(CPPFLAGS) -DPNC_DEBUG
+endif
+
+C_SRCS = mcoll_perf.c \
+ test_bput.c \
+ interleaved.c \
+ i_varn_int64.c \
+ bput_varn_uint.c \
+ flexible_bput.c \
+ wait_after_indep.c \
+ column_wise.c \
+ req_all.c \
+ i_varn_indef.c
+
+F77_SRCS = mcoll_testf77.f \
+ test_bputf77.f
+
+F90_SRCS = mcoll_testf.f90 \
+ test_bputf.f90
+
+PROGS = $(C_SRCS:.c=)
+OBJS = $(C_SRCS:.c=.o)
+ifeq (@has_fortran@, yes)
+PROGS += $(F77_SRCS:.f=) $(F90_SRCS:.f90=)
+OBJS += $(F77_SRCS:.f=.o) $(F90_SRCS:.f90=.o)
+endif
+
+GARBAGE = $(PROGS) *.nc
+PACKING_LIST = $(C_SRCS) $(F77_SRCS) $(F90_SRCS) Makefile.in README depend
+
+all: $(PROGS)
+
+$(C_SRCS:.c=.o): $(srcdir)/../common/testutils.h
+
+$(PROGS): ../common/libtestutils.a
+
+../common/libtestutils.a:
+ set -e; cd ../common && $(MAKE) $(MFLAGS) all
+
+mcoll_perf: mcoll_perf.o $(LIBRARY)
+ $(LINK.c) $< $(LDFLAGS) $(LIBS)
+
+test_bput: test_bput.o $(LIBRARY)
+ $(LINK.c) $< $(LDFLAGS) $(LIBS)
+
+i_varn_int64: i_varn_int64.o $(LIBRARY)
+ $(LINK.c) $< $(LDFLAGS) $(LIBS)
+
+bput_varn_uint: bput_varn_uint.o $(LIBRARY)
+ $(LINK.c) $< $(LDFLAGS) $(LIBS)
+
+interleaved: interleaved.o $(LIBRARY)
+ $(LINK.c) $< $(LDFLAGS) $(LIBS)
+
+flexible_bput: flexible_bput.o $(LIBRARY)
+ $(LINK.c) $< $(LDFLAGS) $(LIBS)
+
+wait_after_indep: wait_after_indep.o $(LIBRARY)
+ $(LINK.c) $< $(LDFLAGS) $(LIBS)
+
+column_wise: column_wise.o $(LIBRARY)
+ $(LINK.c) $< $(LDFLAGS) $(LIBS)
+
+req_all: req_all.o $(LIBRARY)
+ $(LINK.c) $< $(LDFLAGS) $(LIBS)
+
+i_varn_indef: i_varn_indef.o $(LIBRARY)
+ $(LINK.c) $< $(LDFLAGS) $(LIBS)
+
+mcoll_testf77: mcoll_testf77.o $(LIBRARY)
+ $(LINK.F90) $< $(LDFLAGS) $(LIBS)
+
+mcoll_testf: mcoll_testf.o $(LIBRARY)
+ $(LINK.F90) $< $(LDFLAGS) $(LIBS)
+
+test_bputf: test_bputf.o $(LIBRARY)
+ $(LINK.F90) $< $(LDFLAGS) $(LIBS)
+
+test_bputf77: test_bputf77.o $(LIBRARY)
+ $(LINK.F90) $< $(LDFLAGS) $(LIBS)
+
+check testing verbose_check verbose_testing: $(PROGS)
+ $(RM) -f $(TEST_OUTDIR)/testfile.nc*
+ for i in $(PROGS); do ( \
+ $(TEST_SEQRUN) ./$$i $(TEST_OUTDIR)/testfile.nc \
+ ; ) ; done
+
+# Some of these tests are designed to run on one process,
+# # Run them on 4 processes to see if they can handle well
+# Some of these tests are designed to run on 4 processes,
+# # Run them on 2, 4, and 6 processes to see if they can handle well
+TEST_MPIRUN_2 = $(subst NP,2,$(TEST_MPIRUN))
+TEST_MPIRUN_4 = $(subst NP,4,$(TEST_MPIRUN))
+TEST_MPIRUN_6 = $(subst NP,6,$(TEST_MPIRUN))
+
+ptest4: $(PROGS)
+ $(RM) -f $(TEST_OUTDIR)/testfile.nc $(TEST_OUTDIR)/redef1.nc
+ for i in $(PROGS); do ( \
+ $(TEST_MPIRUN_4) ./$$i $(TEST_OUTDIR)/testfile.nc \
+ ; ) ; done
+
+ptest2 : $(PROGS)
+ $(RM) -f $(TEST_OUTDIR)/testfile.nc $(TEST_OUTDIR)/redef1.nc
+ for i in $(PROGS); do ( \
+ $(TEST_MPIRUN_2) ./$$i $(TEST_OUTDIR)/testfile.nc \
+ ; ) ; done
+
+ptest6 : $(PROGS)
+ $(RM) -f $(TEST_OUTDIR)/testfile.nc $(TEST_OUTDIR)/redef1.nc
+ for i in $(PROGS); do ( \
+ $(TEST_MPIRUN_6) ./$$i $(TEST_OUTDIR)/testfile.nc \
+ ; ) ; done
+
+ptest: ptest4
+ptests: ptest2 ptest4 ptest6
+ptest8 ptest10:
+
+include $(srcdir)/../../rules.make
+include $(srcdir)/depend
+
+$(LIBRARY): ;
+
diff --git a/test/nonblocking/README b/test/nonblocking/README
new file mode 100644
index 0000000..876c74e
--- /dev/null
+++ b/test/nonblocking/README
@@ -0,0 +1,12 @@
+There are two test cases in this directory.
+(1) C test case
+This test case test non-blocking functions.
+mpiexec -n 4 mcoll_perf //test the blocking I/O and non-blocking I/O
+
+The default path to write output is "./".
+
+You can change the path and output path:
+mpiexec -n 4 mcoll_perf -f testfile.nc
+
+(2) Fortran test case
+mpiexec -n 4 mcoll_testf
diff --git a/test/nonblocking/bput_varn_uint.c b/test/nonblocking/bput_varn_uint.c
new file mode 100644
index 0000000..7ec48d2
--- /dev/null
+++ b/test/nonblocking/bput_varn_uint.c
@@ -0,0 +1,494 @@
+/*********************************************************************
+ *
+ * Copyright (C) 2014, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ *
+ *********************************************************************/
+/* $Id: bput_varn_uint.c 2219 2015-12-11 22:30:03Z wkliao $ */
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * This example tests nonblocking buffered write varn APIs, including
+ * ncmpi_bput_varn_uint() and ncmpi_bput_varn(),
+ * It first writes a sequence of requests with arbitrary array indices and
+ * lengths to four variables of type NC_UINT, and reads back.
+ *
+ * The compile and run commands are given below, together with an ncmpidump of
+ * the output file.
+ *
+ * % mpicc -O2 -o bput_varn_uint bput_varn_uint.c -lpnetcdf
+ * % mpiexec -n 4 ./bput_varn_uint /pvfs2/wkliao/testfile.nc
+ * % ncmpidump /pvfs2/wkliao/testfile.nc
+ * netcdf testfile {
+ * // file format: CDF-5 (big variables)
+ * dimensions:
+ * Y = 4 ;
+ * X = 10 ;
+ * variables:
+ * uint var0(Y, X) ;
+ * uint var1(Y, X) ;
+ * uint var2(Y, X) ;
+ * uint var3(Y, X) ;
+ * data:
+ *
+ * var0 =
+ * 3, 3, 3, 1, 1, 0, 0, 2, 1, 1,
+ * 0, 2, 2, 2, 3, 1, 1, 2, 2, 2,
+ * 1, 1, 2, 3, 3, 3, 0, 0, 1, 1,
+ * 0, 0, 0, 2, 1, 1, 1, 3, 3, 3 ;
+ *
+ * var1 =
+ * 2, 2, 2, 0, 0, 3, 3, 1, 0, 0,
+ * 3, 1, 1, 1, 2, 0, 0, 1, 1, 1,
+ * 0, 0, 1, 2, 2, 2, 3, 3, 0, 0,
+ * 3, 3, 3, 1, 0, 0, 0, 2, 2, 2 ;
+ *
+ * var2 =
+ * 1, 1, 1, 3, 3, 2, 2, 0, 3, 3,
+ * 2, 0, 0, 0, 1, 3, 3, 0, 0, 0,
+ * 3, 3, 0, 1, 1, 1, 2, 2, 3, 3,
+ * 2, 2, 2, 0, 3, 3, 3, 1, 1, 1 ;
+ *
+ * var3 =
+ * 0, 0, 0, 2, 2, 1, 1, 3, 2, 2,
+ * 1, 3, 3, 3, 0, 2, 2, 3, 3, 3,
+ * 2, 2, 3, 0, 0, 0, 1, 1, 2, 2,
+ * 1, 1, 1, 3, 2, 2, 2, 0, 0, 0 ;
+ * }
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h> /* strcpy() */
+#include <mpi.h>
+#include <pnetcdf.h>
+
+#include <testutils.h>
+
+#define NY 4
+#define NX 10
+#define NDIMS 2
+
+#define ERR \
+ if (err != NC_NOERR) { \
+ printf("Error at line=%d: %s\n", __LINE__, ncmpi_strerror(err)); \
+ nerrs++; \
+ }
+
+#define ERRS(n,a) { \
+ int _i; \
+ for (_i=0; _i<(n); _i++) { \
+ if ((a)[_i] != NC_NOERR) { \
+ printf("Error at line=%d: err[%d] %s\n", __LINE__, _i, \
+ ncmpi_strerror((a)[_i])); \
+ nerrs++; \
+ } \
+ } \
+}
+
+static
+void clear_file_contents(int ncid, int *varid)
+{
+ int i, err, rank;
+ unsigned int *w_buffer = (unsigned int*) malloc(NY*NX * sizeof(unsigned int));
+ for (i=0; i<NY*NX; i++) w_buffer[i] = 99999;
+
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+
+ for (i=0; i<4; i++) {
+ err = ncmpi_put_var_uint_all(ncid, varid[i], w_buffer);
+ if (err != NC_NOERR) printf("Error at line=%d: %s\n", __LINE__, ncmpi_strerror(err));
+ }
+ free(w_buffer);
+}
+
+static
+int check_contents_for_fail(int ncid, int *varid)
+{
+ /* all processes read entire variables back and check contents */
+ int i, j, err, nprocs;
+ unsigned int expected[4][NY*NX] = {{3, 3, 3, 1, 1, 0, 0, 2, 1, 1,
+ 0, 2, 2, 2, 3, 1, 1, 2, 2, 2,
+ 1, 1, 2, 3, 3, 3, 0, 0, 1, 1,
+ 0, 0, 0, 2, 1, 1, 1, 3, 3, 3},
+ {2, 2, 2, 0, 0, 3, 3, 1, 0, 0,
+ 3, 1, 1, 1, 2, 0, 0, 1, 1, 1,
+ 0, 0, 1, 2, 2, 2, 3, 3, 0, 0,
+ 3, 3, 3, 1, 0, 0, 0, 2, 2, 2},
+ {1, 1, 1, 3, 3, 2, 2, 0, 3, 3,
+ 2, 0, 0, 0, 1, 3, 3, 0, 0, 0,
+ 3, 3, 0, 1, 1, 1, 2, 2, 3, 3,
+ 2, 2, 2, 0, 3, 3, 3, 1, 1, 1},
+ {0, 0, 0, 2, 2, 1, 1, 3, 2, 2,
+ 1, 3, 3, 3, 0, 2, 2, 3, 3, 3,
+ 2, 2, 3, 0, 0, 0, 1, 1, 2, 2,
+ 1, 1, 1, 3, 2, 2, 2, 0, 0, 0}};
+
+ unsigned int *r_buffer = (unsigned int*) malloc(NY*NX * sizeof(unsigned int));
+
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+ if (nprocs > 4) MPI_Barrier(MPI_COMM_WORLD);
+
+ for (i=0; i<4; i++) {
+ for (j=0; j<NY*NX; j++) r_buffer[j] = 99999;
+ err = ncmpi_get_var_uint_all(ncid, varid[i], r_buffer);
+ if (err != NC_NOERR) printf("Error at line=%d: %s\n", __LINE__, ncmpi_strerror(err));
+
+ /* check if the contents of buf are expected */
+ for (j=0; j<NY*NX; j++) {
+ if (expected[i][j] >= nprocs) continue;
+ if (r_buffer[j] != expected[i][j]) {
+ printf("Expected read buf[%d][%d]=%u, but got %u\n",
+ i,j,expected[i][j],r_buffer[j]);
+ free(r_buffer);
+ return 1;
+ }
+ }
+ }
+ free(r_buffer);
+ return 0;
+}
+
+static int
+check_num_pending_reqs(int ncid, int expected, int lineno)
+/* check if PnetCDF can reports expected number of pending requests */
+{
+ int err, n_pendings;
+ err = ncmpi_inq_nreqs(ncid, &n_pendings);
+ if (err != NC_NOERR) printf("Error at line=%d: %s\n", __LINE__, ncmpi_strerror(err));
+ if (n_pendings != expected) {
+ printf("Error at line %d: expect %d pending requests but got %d\n",
+ lineno, expected, n_pendings);
+ return 1;
+ }
+ return 0;
+}
+
+static
+void check_attached_buffer_usage(int ncid,
+ MPI_Offset expected_size,
+ MPI_Offset expected_usage,
+ int lineno)
+/* check attached buf usage */
+{
+ int err, rank;
+ MPI_Offset usage, buf_size;
+
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ if (rank >= 4) return;
+
+ err = ncmpi_inq_buffer_size(ncid, &buf_size);
+ if (err != NC_NOERR) printf("Error at line=%d: %s\n", __LINE__, ncmpi_strerror(err));
+ if (expected_size != buf_size)
+ printf("Error at line %d: expect buffer size %lld but got %lld\n",
+ lineno, expected_size, buf_size);
+
+ err = ncmpi_inq_buffer_usage(ncid, &usage);
+ if (err != NC_NOERR) printf("Error at line=%d: %s\n", __LINE__, ncmpi_strerror(err));
+ if (expected_usage != usage)
+ printf("Error at line %d: expect buffer usage %lld but got %lld\n",
+ lineno, expected_usage, usage);
+}
+
+/* swap two rows, a and b, of a 2D array */
+static
+void permute(MPI_Offset *a, MPI_Offset *b)
+{
+ int i;
+ MPI_Offset tmp;
+ for (i=0; i<NDIMS; i++) {
+ tmp = a[i]; a[i] = b[i]; b[i] = tmp;
+ }
+}
+
+int main(int argc, char** argv)
+{
+ char filename[256];
+ int i, j, k, rank, nprocs, verbose=0, err, nerrs=0;
+ int ncid, cmode, varid[4], dimid[2], nreqs, reqs[4], sts[4];
+ unsigned int *buffer[4];
+ int num_segs[4] = {4, 6, 5, 4};
+ int req_lens[4], my_nsegs[4];
+ MPI_Offset **starts[4], **counts[4];
+ MPI_Offset n_starts[4][6][2] = {{{0,5}, {1,0}, {2,6}, {3,0}, {0,0}, {0,0}},
+ {{0,3}, {0,8}, {1,5}, {2,0}, {2,8}, {3,4}},
+ {{0,7}, {1,1}, {1,7}, {2,2}, {3,3}, {0,0}},
+ {{0,0}, {1,4}, {2,3}, {3,7}, {0,0}, {0,0}}};
+ MPI_Offset n_counts[4][6][2] = {{{1,2}, {1,1}, {1,2}, {1,3}, {0,0}, {0,0}},
+ {{1,2}, {1,2}, {1,2}, {1,2}, {1,2}, {1,3}},
+ {{1,1}, {1,3}, {1,3}, {1,1}, {1,1}, {0,0}},
+ {{1,3}, {1,1}, {1,3}, {1,3}, {0,0}, {0,0}}};
+
+ /* n_starts[0][][] n_counts[0][][] indicate the following: ("-" means skip)
+ - - - - - X X - - -
+ X - - - - - - - - -
+ - - - - - - X X - -
+ X X X - - - - - - -
+ n_starts[1][][] n_counts[1][][] indicate the following pattern.
+ - - - X X - - - X X
+ - - - - - X X - - -
+ X X - - - - - - X X
+ - - - - X X X - - -
+ n_starts[2][][] n_counts[2][][] indicate the following pattern.
+ - - - - - - - X - -
+ - X X X - - - X X X
+ - - X - - - - - - -
+ - - - X - - - - - -
+ n_starts[3][][] n_counts[3][][] indicate the following pattern.
+ X X X - - - - - - -
+ - - - - X - - - - -
+ - - - X X X - - - -
+ - - - - - - - X X X
+ */
+ MPI_Init(&argc, &argv);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+
+ if (argc > 2) {
+ if (!rank) printf("Usage: %s [filename]\n",argv[0]);
+ MPI_Finalize();
+ return 0;
+ }
+ strcpy(filename, "testfile.nc");
+ if (argc == 2) strcpy(filename, argv[1]);
+ MPI_Bcast(filename, 256, MPI_CHAR, 0, MPI_COMM_WORLD);
+
+ if (rank == 0) {
+ char cmd_str[256];
+ sprintf(cmd_str, "*** TESTING C %s for bput_varn_uint ", argv[0]);
+ printf("%-66s ------ ", cmd_str);
+ }
+
+ if (verbose && nprocs != 4 && rank == 0)
+ printf("Warning: %s is intended to run on 4 processes\n",argv[0]);
+
+ /* create a new file for writing ----------------------------------------*/
+ cmode = NC_CLOBBER | NC_64BIT_DATA;
+ err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, MPI_INFO_NULL, &ncid);
+ ERR
+
+ /* create a global array of size NY * NX */
+ err = ncmpi_def_dim(ncid, "Y", NY, &dimid[0]); ERR
+ err = ncmpi_def_dim(ncid, "X", NX, &dimid[1]); ERR
+ err = ncmpi_def_var(ncid, "var0", NC_UINT, NDIMS, dimid, &varid[0]); ERR
+ err = ncmpi_def_var(ncid, "var1", NC_UINT, NDIMS, dimid, &varid[1]); ERR
+ err = ncmpi_def_var(ncid, "var2", NC_UINT, NDIMS, dimid, &varid[2]); ERR
+ err = ncmpi_def_var(ncid, "var3", NC_UINT, NDIMS, dimid, &varid[3]); ERR
+ err = ncmpi_enddef(ncid); ERR
+
+ /* allocate space for starts and counts */
+ starts[0] = (MPI_Offset**) malloc(4 * 6 * sizeof(MPI_Offset*));
+ counts[0] = (MPI_Offset**) malloc(4 * 6 * sizeof(MPI_Offset*));
+ starts[0][0] = (MPI_Offset*) calloc(4 * 6 * NDIMS, sizeof(MPI_Offset));
+ counts[0][0] = (MPI_Offset*) calloc(4 * 6 * NDIMS, sizeof(MPI_Offset));
+ for (i=1; i<4; i++) {
+ starts[i] = starts[i-1] + 6;
+ counts[i] = counts[i-1] + 6;
+ starts[i][0] = starts[i-1][0] + 6 * NDIMS;
+ counts[i][0] = counts[i-1][0] + 6 * NDIMS;
+ }
+ for (i=0; i<4; i++) {
+ for (j=1; j<6; j++) {
+ starts[i][j] = starts[i][j-1] + NDIMS;
+ counts[i][j] = counts[i][j-1] + NDIMS;
+ }
+ }
+
+ /* set values for starts and counts */
+ for (i=0; i<4; i++) {
+ int n = (i + rank) % 4;
+ my_nsegs[i] = num_segs[n]; /* number of segments for this request */
+ for (j=0; j<6; j++) {
+ for (k=0; k<NDIMS; k++) {
+ starts[i][j][k] = n_starts[n][j][k];
+ counts[i][j][k] = n_counts[n][j][k];
+ }
+ }
+ }
+
+ /* test error code: NC_ENULLABUF */
+ err = ncmpi_bput_varn_uint(ncid, varid[0], 1, NULL, NULL, NULL, &reqs[0]);
+ if (err != NC_ENULLABUF) {
+ printf("Error at line %d: expecting error code NC_ENULLABUF but got %s\n",
+ __LINE__, nc_err_code_name(err));
+ nerrs++;
+ }
+
+ /* only rank 0, 1, 2, and 3 do I/O:
+ * each of ranks 0 to 3 write 4 nonblocking requests */
+ nreqs = 4;
+ if (rank >= 4) nreqs = 0;
+
+ /* bufsize must be max of data type converted before and after */
+ MPI_Offset bufsize = 0;
+
+ /* calculate length of each varn request and allocate write buffer */
+ for (i=0; i<nreqs; i++) {
+ req_lens[i] = 0; /* total length this request */
+ for (j=0; j<my_nsegs[i]; j++) {
+ MPI_Offset req_len=1;
+ for (k=0; k<NDIMS; k++)
+ req_len *= counts[i][j][k];
+ req_lens[i] += req_len;
+ }
+ if (verbose) printf("req_lens[%d]=%d\n",i,req_lens[i]);
+
+ /* allocate I/O buffer and initialize its contents */
+ buffer[i] = (unsigned int*) malloc(req_lens[i] * sizeof(unsigned int));
+ for (j=0; j<req_lens[i]; j++) buffer[i][j] = rank;
+ bufsize += req_lens[i];
+ }
+ bufsize *= sizeof(unsigned int);
+
+ /* give PnetCDF a space to buffer the nonblocking requests */
+ if (bufsize > 0) {
+ err = ncmpi_buffer_attach(ncid, bufsize); ERR
+ }
+ if (verbose) printf("%d: Attach buffer size %lld\n", rank, bufsize);
+
+ /* test error code: NC_ENULLSTART */
+ err = ncmpi_bput_varn_uint(ncid, varid[0], 1, NULL, NULL, NULL, &reqs[0]);
+ if (rank < 4 && err != NC_ENULLSTART) {
+ printf("Error at line %d: expecting error code NC_ENULLSTART but got %s\n",
+ __LINE__, nc_err_code_name(err));
+ nerrs++;
+ }
+
+ /* write usning varn API, one bput call per variable */
+ clear_file_contents(ncid, varid);
+ for (i=0; i<nreqs; i++) {
+ err = ncmpi_bput_varn_uint(ncid, varid[i], my_nsegs[i], starts[i],
+ counts[i], buffer[i], &reqs[i]);
+ ERR
+ }
+ nerrs += check_num_pending_reqs(ncid, nreqs, __LINE__);
+ check_attached_buffer_usage(ncid, bufsize, bufsize, __LINE__);
+ err = ncmpi_wait_all(ncid, nreqs, reqs, sts);
+ ERRS(nreqs, sts)
+
+ check_attached_buffer_usage(ncid, bufsize, 0, __LINE__);
+
+ /* all processes read entire variables back and check contents */
+ nerrs += check_contents_for_fail(ncid, varid);
+
+ /* permute write order: so starts[*] are not in an increasing order:
+ * swap segment 0 with segment 2 and swap segment 1 with segment 3
+ */
+ for (i=0; i<nreqs; i++) {
+ permute(starts[i][0],starts[i][2]); permute(counts[i][0],counts[i][2]);
+ permute(starts[i][1],starts[i][3]); permute(counts[i][1],counts[i][3]);
+ }
+
+ /* write using varn API, one bput call per variable */
+ clear_file_contents(ncid, varid);
+ for (i=0; i<nreqs; i++) {
+ err = ncmpi_bput_varn_uint(ncid, varid[i], my_nsegs[i], starts[i],
+ counts[i], buffer[i], &reqs[i]);
+ ERR
+ }
+ nerrs += check_num_pending_reqs(ncid, nreqs, __LINE__);
+ check_attached_buffer_usage(ncid, bufsize, bufsize, __LINE__);
+ err = ncmpi_wait_all(ncid, nreqs, reqs, sts);
+ ERRS(nreqs, sts)
+
+ check_attached_buffer_usage(ncid, bufsize, 0, __LINE__);
+
+ /* all processes read entire variables back and check contents */
+ nerrs += check_contents_for_fail(ncid, varid);
+
+ for (i=0; i<nreqs; i++) free(buffer[i]);
+
+ /* test flexible API, using a noncontiguous buftype */
+ clear_file_contents(ncid, varid);
+ for (i=0; i<nreqs; i++) {
+ MPI_Datatype buftype;
+ MPI_Type_vector(req_lens[i], 1, 2, MPI_UNSIGNED, &buftype);
+ MPI_Type_commit(&buftype);
+ buffer[i] = (unsigned int*)malloc(req_lens[i]*2*sizeof(unsigned int));
+ for (j=0; j<req_lens[i]*2; j++) buffer[i][j] = rank;
+
+ err = ncmpi_bput_varn(ncid, varid[i], my_nsegs[i], starts[i],
+ counts[i], buffer[i], 1, buftype, &reqs[i]);
+ ERR
+ MPI_Type_free(&buftype);
+ }
+ nerrs += check_num_pending_reqs(ncid, nreqs, __LINE__);
+ check_attached_buffer_usage(ncid, bufsize, bufsize, __LINE__);
+ err = ncmpi_wait_all(ncid, nreqs, reqs, sts);
+ ERRS(nreqs, sts)
+
+ check_attached_buffer_usage(ncid, bufsize, 0, __LINE__);
+
+ /* all processes read entire variables back and check contents */
+ nerrs += check_contents_for_fail(ncid, varid);
+
+ /* permute back to original order */
+ for (i=0; i<nreqs; i++) {
+ permute(starts[i][0],starts[i][2]); permute(counts[i][0],counts[i][2]);
+ permute(starts[i][1],starts[i][3]); permute(counts[i][1],counts[i][3]);
+ }
+
+ /* test flexible API, using a noncontiguous buftype, one bput call per
+ * variable */
+ clear_file_contents(ncid, varid);
+ for (i=0; i<nreqs; i++) {
+ MPI_Datatype buftype;
+ MPI_Type_vector(req_lens[i], 1, 2, MPI_UNSIGNED, &buftype);
+ MPI_Type_commit(&buftype);
+ for (j=0; j<req_lens[i]*2; j++) buffer[i][j] = rank;
+
+ err = ncmpi_bput_varn(ncid, varid[i], my_nsegs[i], starts[i],
+ counts[i], buffer[i], 1, buftype, &reqs[i]);
+ ERR
+ MPI_Type_free(&buftype);
+ }
+ nerrs += check_num_pending_reqs(ncid, nreqs, __LINE__);
+ check_attached_buffer_usage(ncid, bufsize, bufsize, __LINE__);
+ err = ncmpi_wait_all(ncid, nreqs, reqs, sts);
+ ERRS(nreqs, sts)
+
+ check_attached_buffer_usage(ncid, bufsize, 0, __LINE__);
+
+ /* all processes read entire variables back and check contents */
+ nerrs += check_contents_for_fail(ncid, varid);
+
+ /* free the buffer space for bput */
+ if (bufsize > 0) {
+ err = ncmpi_buffer_detach(ncid); ERR
+ }
+
+ /* test error code: NC_ENULLABUF */
+ err = ncmpi_inq_buffer_usage(ncid, NULL);
+ if (err != NC_ENULLABUF) {
+ printf("expecting error code NC_ENULLABUF but got %s\n",
+ nc_err_code_name(err));
+ nerrs++;
+ }
+
+ err = ncmpi_close(ncid); ERR
+
+ for (i=0; i<nreqs; i++) free(buffer[i]);
+ free(starts[0][0]);
+ free(counts[0][0]);
+ free(starts[0]);
+ free(counts[0]);
+
+ /* check if PnetCDF freed all internal malloc */
+ MPI_Offset malloc_size, sum_size;
+ err = ncmpi_inq_malloc_size(&malloc_size);
+ if (err == NC_NOERR) {
+ MPI_Reduce(&malloc_size, &sum_size, 1, MPI_OFFSET, MPI_SUM, 0, MPI_COMM_WORLD);
+ if (rank == 0 && sum_size > 0)
+ printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n",
+ sum_size);
+ }
+
+ MPI_Allreduce(MPI_IN_PLACE, &nerrs, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
+ if (rank == 0) {
+ if (nerrs) printf(FAIL_STR,nerrs);
+ else printf(PASS_STR);
+ }
+
+ MPI_Finalize();
+ return 0;
+}
+
diff --git a/test/nonblocking/column_wise.c b/test/nonblocking/column_wise.c
new file mode 100644
index 0000000..cea39e4
--- /dev/null
+++ b/test/nonblocking/column_wise.c
@@ -0,0 +1,227 @@
+/*********************************************************************
+ *
+ * Copyright (C) 2015, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ *
+ *********************************************************************/
+/* $Id: column_wise.c 2216 2015-12-08 05:47:19Z wkliao $ */
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * This example tests a number of nonblocking API calls, each writes a single
+ * column of a 2D integer array. Each process writes NX columns and any two
+ * consecutive columns are of nprocs columns distance apart from each other. In
+ * this case, the fileview of each process interleaves with all other processes.
+ * If simply concatenating fileviews of all the nonblocking calls will result
+ * in a fileview that violates the MPI-IO requirement on the fileview of which
+ * flattened file offsets must be monotonically non-decreasing. PnetCDF handles
+ * this case by breaking down each nonblocking call into a lsit of offset-length
+ * pairs, merging the pairs across multiple nonblocking calls, and sorting
+ * them into an increasing order. The sorted pairs are used to construct a
+ * fileview that meets the monotonically non-decreasing offset requirement,
+ * and thus the nonblocking requests can be serviced by a single MPI-IO call.
+ *
+ * The compile and run commands are given below, together with an ncmpidump of
+ * the output file.
+ *
+ * % mpicc -O2 -o column_wise column_wise.c -lpnetcdf
+ * % mpiexec -l -n 4 ./column_wise /pvfs2/wkliao/testfile.nc
+ * 0: 0: myOff= 0 myNX= 4
+ * 1: 1: myOff= 4 myNX= 4
+ * 2: 2: myOff= 8 myNX= 4
+ * 3: 3: myOff= 12 myNX= 4
+ * 0: 0: start= 0 0 count= 10 1
+ * 1: 1: start= 0 1 count= 10 1
+ * 2: 2: start= 0 2 count= 10 1
+ * 3: 3: start= 0 3 count= 10 1
+ *
+ * % ncmpidump /pvfs2/wkliao/testfile.nc
+ * netcdf testfile {
+ * // file format: CDF-5 (big variables)
+ * dimensions:
+ * Y = 10 ;
+ * X = 16 ;
+ * variables:
+ * int var(Y, X) ;
+ * data:
+ *
+ * var =
+ * 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3,
+ * 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3,
+ * 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3,
+ * 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3,
+ * 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3,
+ * 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3,
+ * 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3,
+ * 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3,
+ * 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3,
+ * 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3 ;
+ * }
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h> /* strcpy() */
+#include <unistd.h> /* getopt() */
+#include <mpi.h>
+#include <pnetcdf.h>
+
+#include <testutils.h>
+
+#define NY 10
+#define NX 4
+
+#define ERR {if(err!=NC_NOERR){nerrs++; printf("Error at line=%d: %s\n", __LINE__, ncmpi_strerror(err));}}
+
+int main(int argc, char** argv)
+{
+ extern int optind;
+ char filename[256];
+ int i, j, nerrs=0, rank, nprocs, err, myNX, G_NX, myOff, num_reqs;
+ int ncid, cmode, varid, dimid[2], *reqs, *sts, **buf;
+ MPI_Offset start[2], count[2];
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+
+ if (argc > 2) {
+ if (!rank) printf("Usage: %s [filename]\n",argv[0]);
+ MPI_Finalize();
+ return 0;
+ }
+ strcpy(filename, "testfile.nc");
+ if (argc == 2) strcpy(filename, argv[1]);
+ MPI_Bcast(filename, 256, MPI_CHAR, 0, MPI_COMM_WORLD);
+
+ if (rank == 0) {
+ char cmd_str[256];
+ sprintf(cmd_str, "*** TESTING C %s for iput/iget interleaved access ", argv[0]);
+ printf("%-66s ------ ", cmd_str);
+ }
+
+ cmode = NC_CLOBBER | NC_64BIT_DATA;
+ err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, MPI_INFO_NULL, &ncid);
+ ERR
+
+ /* the global array is NY * (NX * nprocs) */
+ G_NX = NX * nprocs;
+ myOff = NX * rank;
+ myNX = NX;
+
+ err = ncmpi_def_dim(ncid, "Y", NY, &dimid[0]);
+ ERR
+ err = ncmpi_def_dim(ncid, "X", G_NX, &dimid[1]);
+ ERR
+ err = ncmpi_def_var(ncid, "var", NC_INT, 2, dimid, &varid);
+ ERR
+ err = ncmpi_enddef(ncid);
+ ERR
+
+ /* First, fill the entire array with zeros, using a blocking I/O.
+ Every process writes a subarray of size NY * myNX */
+ buf = (int**) malloc(myNX * sizeof(int*));
+ buf[0] = (int*) calloc(NY * myNX, sizeof(int));
+ start[0] = 0; start[1] = myOff;
+ count[0] = NY; count[1] = myNX;
+ err = ncmpi_put_vara_int_all(ncid, varid, start, count, buf[0]);
+ free(buf[0]);
+
+ /* initialize the buffer with rank ID. Also make the case interesting,
+ by allocatsing buffersd separately */
+ for (i=0; i<myNX; i++) {
+ buf[i] = (int*) malloc(NY * sizeof(int));
+ for (j=0; j<NY; j++) buf[i][j] = rank;
+ }
+
+ reqs = (int*) malloc(myNX * sizeof(int));
+ sts = (int*) malloc(myNX * sizeof(int));
+
+ /* each proc writes myNX single columns of the 2D array */
+ start[0] = 0; start[1] = rank;
+ count[0] = NY; count[1] = 1;
+
+ num_reqs = 0;
+ for (i=0; i<myNX; i++) {
+ err = ncmpi_iput_vara_int(ncid, varid, start, count, buf[i],
+ &reqs[num_reqs++]);
+ ERR
+ start[1] += nprocs;
+ }
+ err = ncmpi_wait_all(ncid, num_reqs, reqs, sts);
+ ERR
+
+ /* check status of all requests */
+ for (i=0; i<num_reqs; i++) {
+ if (reqs[i] != NC_REQ_NULL) { /* add in PnetCDF v1.7.0 */
+ printf("Error: request ID %d fails to be set to NC_REQ_NULL\n",i);
+ nerrs++;
+ }
+ if (sts[i] != NC_NOERR) {
+ printf("Error: nonblocking write fails on request %d (%s)\n",
+ i, ncmpi_strerror(sts[i]));
+ nerrs++;
+ }
+ }
+
+ /* read back using the same access pattern */
+ for (i=0; i<myNX; i++)
+ for (j=0; j<NY; j++) buf[i][j] = -1;
+
+ /* each proc reads myNX single columns of the 2D array */
+ start[0] = 0; start[1] = rank;
+ count[0] = NY; count[1] = 1;
+
+ num_reqs = 0;
+ for (i=0; i<myNX; i++) {
+ err = ncmpi_iget_vara_int(ncid, varid, start, count, buf[i],
+ &reqs[num_reqs++]);
+ ERR
+ start[1] += nprocs;
+ }
+ err = ncmpi_wait_all(ncid, num_reqs, reqs, sts);
+ ERR
+
+ /* check status of all requests */
+ for (i=0; i<num_reqs; i++)
+ if (sts[i] != NC_NOERR) {
+ printf("Error: nonblocking write fails on request %d (%s)\n",
+ i, ncmpi_strerror(sts[i]));
+ nerrs++;
+ }
+
+ for (i=0; i<myNX; i++) {
+ for (j=0; j<NY; j++)
+ if (buf[i][j] != rank) {
+ printf("Error: expect buf[%d][%d]=%d but got %d\n",i,j,rank,buf[i][j]);
+ nerrs++;
+ }
+ }
+
+ err = ncmpi_close(ncid);
+ ERR
+
+ free(sts);
+ free(reqs);
+ for (i=0; i<myNX; i++) free(buf[i]);
+ free(buf);
+
+ /* check if PnetCDF freed all internal malloc */
+ MPI_Offset malloc_size, sum_size;
+ err = ncmpi_inq_malloc_size(&malloc_size);
+ if (err == NC_NOERR) {
+ MPI_Reduce(&malloc_size, &sum_size, 1, MPI_OFFSET, MPI_SUM, 0, MPI_COMM_WORLD);
+ if (rank == 0 && sum_size > 0)
+ printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n",
+ sum_size);
+ }
+
+ MPI_Allreduce(MPI_IN_PLACE, &nerrs, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
+ if (rank == 0) {
+ if (nerrs) printf(FAIL_STR,nerrs);
+ else printf(PASS_STR);
+ }
+
+ MPI_Finalize();
+ return 0;
+}
+
diff --git a/test/nonblocking/depend b/test/nonblocking/depend
new file mode 100644
index 0000000..f4e3b8c
--- /dev/null
+++ b/test/nonblocking/depend
@@ -0,0 +1,14 @@
+mcoll_perf.c.o: mcoll_perf.c
+mcoll_testf77: mcoll_testf77.f
+mcoll_testf.o: mcoll_testf.f90
+test_bput.o: test_bput.c
+test_bputf.o: test_bputf.f90
+test_bputf77.o: test_bputf77.f
+interleaved.o: interleaved.c
+i_varn_int64.o: i_varn_int64.c
+bput_varn_uint.o: bput_varn_uint.c
+flexible_bput.o: flexible_bput.c
+wait_after_indep.o: wait_after_indep.c
+column_wise.o: column_wise.c
+req_all.o: req_all.c
+i_varn_indef.o: i_varn_indef.c
diff --git a/test/nonblocking/flexible_bput.c b/test/nonblocking/flexible_bput.c
new file mode 100644
index 0000000..2f32dfa
--- /dev/null
+++ b/test/nonblocking/flexible_bput.c
@@ -0,0 +1,270 @@
+/*********************************************************************
+ *
+ * Copyright (C) 2014, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ *
+ *********************************************************************/
+/* $Id: flexible_bput.c 2134 2015-10-03 04:24:18Z wkliao $ */
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ *
+ * This example tests PnetCDF nonblocking buffered flexible varm API, i.e.
+ * ncmpi_bput_varm() to write a 2D array double variable of size NY x NX*nproc
+ * in parallel. In particular, we use a noncontiguous buffer type, a
+ * noncontiguous imap[], and integer type in memory and double in file that
+ * require a type conversion.
+ *
+ * The data partitioning patterns on the variable is column-wise.
+ * The local buffer has ghost cells surrounded along both dimensions.
+ *
+ * The compile and run commands are given below.
+ *
+ * % mpicc -O2 -o flexible_bput flexible_bput.c -lpnetcdf
+ *
+ * % mpiexec -l -n 4 ./flexible_bput /pvfs2/wkliao/testfile.nc
+ *
+ * % ncmpidump /pvfs2/wkliao/testfile.nc
+ * netcdf testfile {
+ * // file format: CDF-5 (big variables)
+ * dimensions:
+ * Y = 6 ;
+ * X = 16 ;
+ * variables:
+ * double var(Y, X) ;
+ * data:
+ *
+ * var =
+ * 0, 6, 12, 18, 0, 6, 12, 18, 0, 6, 12, 18, 0, 6, 12, 18,
+ * 1, 7, 13, 19, 1, 7, 13, 19, 1, 7, 13, 19, 1, 7, 13, 19,
+ * 2, 8, 14, 20, 2, 8, 14, 20, 2, 8, 14, 20, 2, 8, 14, 20,
+ * 3, 9, 15, 21, 3, 9, 15, 21, 3, 9, 15, 21, 3, 9, 15, 21,
+ * 4, 10, 16, 22, 4, 10, 16, 22, 4, 10, 16, 22, 4, 10, 16, 22,
+ * 5, 11, 17, 23, 5, 11, 17, 23, 5, 11, 17, 23, 5, 11, 17, 23 ;
+ * }
+ *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h> /* strcpy() */
+#include <assert.h>
+#include <mpi.h>
+#include <pnetcdf.h>
+
+#include <testutils.h>
+
+#define NY 6
+#define NX 4
+#define GHOST 2
+
+#define ERR {if(err!=NC_NOERR){printf("Error at line=%d: %s\n", __LINE__, ncmpi_strerror(err)); nerrs++;}}
+
+#define INIT_PUT_BUF(buf) \
+ for (i=0; i<array_of_sizes[0]; i++) { \
+ for (j=0; j<array_of_sizes[1]; j++) { \
+ if (i < GHOST || GHOST+array_of_subsizes[0] <= i || \
+ j < GHOST || GHOST+array_of_subsizes[1] <= j) \
+ buf[i][j] = -1; \
+ else \
+ buf[i][j] = (i-GHOST)*array_of_subsizes[1]+(j-GHOST); \
+ } \
+ }
+
+#define CHECK_PUT_BUF(buf) \
+ for (i=0; i<array_of_sizes[0]; i++) { \
+ for (j=0; j<array_of_sizes[1]; j++) { \
+ if (i < GHOST || GHOST+array_of_subsizes[0] <= i || \
+ j < GHOST || GHOST+array_of_subsizes[1] <= j) { \
+ if (buf[i][j] != -1) { \
+ printf("Error: put buffer altered buffer[%d][%d]=%f\n", \
+ i,j,(double)buf[i][j]); \
+ nerrs++; \
+ } \
+ } \
+ else { \
+ if (buf[i][j] != (i-GHOST)*array_of_subsizes[1]+(j-GHOST)) { \
+ printf("Error: put buffer altered buffer[%d][%d]=%f\n", \
+ i,j,(double)buf[i][j]); \
+ nerrs++; \
+ } \
+ } \
+ } \
+ }
+
+#define INIT_GET_BUF(buf) \
+ for (i=0; i<array_of_sizes[0]; i++) \
+ for (j=0; j<array_of_sizes[1]; j++) \
+ buf[i][j] = -2;
+
+#define CHECK_GET_BUF(buf) \
+ for (i=0; i<array_of_sizes[0]; i++) { \
+ for (j=0; j<array_of_sizes[1]; j++) { \
+ if (i < GHOST || GHOST+array_of_subsizes[0] <= i || \
+ j < GHOST || GHOST+array_of_subsizes[1] <= j) { \
+ if (buf[i][j] != -2) { \
+ printf("Unexpected get buffer[%d][%d]=%f\n", \
+ i,j,(double)buf[i][j]); \
+ nerrs++; \
+ } \
+ } \
+ else { \
+ if (buf[i][j] != (i-GHOST)*array_of_subsizes[1]+(j-GHOST)) { \
+ printf("Unexpected get buffer[%d][%d]=%f\n", \
+ i,j,(double)buf[i][j]); \
+ nerrs++; \
+ } \
+ } \
+ } \
+ }
+
+int main(int argc, char** argv)
+{
+ char filename[256];
+ int i, j, rank, nprocs, err, nerrs=0, req, status;
+ int ncid, cmode, varid, dimid[2];
+ int array_of_sizes[2], array_of_subsizes[2], array_of_starts[2];
+ int buf_int[NX+2*GHOST][NY+2*GHOST];
+ double buf_dbl[NX+2*GHOST][NY+2*GHOST];
+ MPI_Offset start[2], count[2], stride[2], imap[2];
+ MPI_Datatype subarray;
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+
+ if (argc > 2) {
+ if (!rank) printf("Usage: %s [filename]\n",argv[0]);
+ MPI_Finalize();
+ return 0;
+ }
+ strcpy(filename, "testfile.nc");
+ if (argc == 2) strcpy(filename, argv[1]);
+ MPI_Bcast(filename, 256, MPI_CHAR, 0, MPI_COMM_WORLD);
+
+ if (rank == 0) {
+ char cmd_str[256];
+ sprintf(cmd_str, "*** TESTING C %s for flexible bput_varm ", argv[0]);
+ printf("%-66s ------ ", cmd_str);
+ }
+
+ /* create a new file for writing ----------------------------------------*/
+ cmode = NC_CLOBBER | NC_64BIT_DATA;
+ err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, MPI_INFO_NULL, &ncid);
+ ERR
+
+ /* define 2 dimensions */
+ err = ncmpi_def_dim(ncid, "Y", NY, &dimid[0]); ERR
+ err = ncmpi_def_dim(ncid, "X", NX*nprocs, &dimid[1]); ERR
+
+ /* define a variable of size NY * (NX * nprocs) */
+ err = ncmpi_def_var(ncid, "var", NC_DOUBLE, 2, dimid, &varid); ERR
+ err = ncmpi_enddef(ncid); ERR
+
+ start[0] = 0; start[1] = NX * rank;
+ count[0] = NY; count[1] = NX;
+ stride[0] = 1; stride[1] = 1;
+ imap[0] = 1; imap[1] = NY; /* would be {NX, 1} if not transposing */
+
+ /* var is partitioned along X dimension in a matrix transported way */
+ array_of_sizes[0] = NX + 2*GHOST;
+ array_of_sizes[1] = NY + 2*GHOST;
+ array_of_subsizes[0] = NX;
+ array_of_subsizes[1] = NY;
+ array_of_starts[0] = GHOST;
+ array_of_starts[1] = GHOST;
+ MPI_Type_create_subarray(2, array_of_sizes, array_of_subsizes,
+ array_of_starts, MPI_ORDER_C, MPI_INT, &subarray);
+ MPI_Type_commit(&subarray);
+
+ /* calling a nonblocking bput_varm flexible API -------------------------*/
+ /* initiate put buffer contents */
+ INIT_PUT_BUF(buf_int)
+
+ MPI_Offset bufsize = sizeof(double);
+ for (i=0; i<2; i++) bufsize *= count[i];
+ err = ncmpi_buffer_attach(ncid, bufsize); ERR
+
+ err = ncmpi_bput_varm(ncid, varid, start, count, stride, imap, buf_int,
+ 1, subarray, &req);
+ ERR
+ err = ncmpi_wait_all(ncid, 1, &req, &status); ERR
+ err = status; ERR
+
+ /* check the contents of put buffer */
+ CHECK_PUT_BUF(buf_int)
+
+ err = ncmpi_buffer_detach(ncid); ERR
+
+ /* read back using a blocking get_varm flexible API ---------------------*/
+ /* initiate get buffer contents */
+ INIT_GET_BUF(buf_int)
+
+ /* calling a blocking flexible API */
+ err = ncmpi_get_varm_all(ncid, varid, start, count, stride, imap, buf_int,
+ 1, subarray);
+ ERR
+
+ /* check the contents of get buffer */
+ CHECK_GET_BUF(buf_int)
+
+ MPI_Type_free(&subarray);
+
+ /* test case for no type conversion =====================================*/
+ MPI_Type_create_subarray(2, array_of_sizes, array_of_subsizes,
+ array_of_starts, MPI_ORDER_C, MPI_DOUBLE,
+ &subarray);
+ MPI_Type_commit(&subarray);
+
+ /* calling a nonblocking bput_varm flexible API -------------------------*/
+ /* initiate put buffer contents */
+ INIT_PUT_BUF(buf_dbl)
+
+ err = ncmpi_buffer_attach(ncid, bufsize); ERR
+
+ err = ncmpi_bput_varm(ncid, varid, start, count, stride, imap, buf_dbl,
+ 1, subarray, &req);
+ ERR
+ err = ncmpi_wait_all(ncid, 1, &req, &status); ERR
+ err = status; ERR
+
+ /* check the contents of put buffer */
+ CHECK_PUT_BUF(buf_dbl)
+
+ err = ncmpi_buffer_detach(ncid); ERR
+
+ /* read back using a blocking get_varm flexible API ---------------------*/
+ /* initiate get buffer contents */
+ INIT_GET_BUF(buf_dbl)
+
+ /* calling a blocking flexible API */
+ err = ncmpi_get_varm_all(ncid, varid, start, count, stride, imap, buf_dbl,
+ 1, subarray);
+ ERR
+
+ /* check the contents of get buffer */
+ CHECK_GET_BUF(buf_dbl)
+
+ MPI_Type_free(&subarray);
+
+ err = ncmpi_close(ncid); ERR
+
+ /* check if PnetCDF freed all internal malloc */
+ MPI_Offset malloc_size, sum_size;
+ err = ncmpi_inq_malloc_size(&malloc_size);
+ if (err == NC_NOERR) {
+ MPI_Reduce(&malloc_size, &sum_size, 1, MPI_OFFSET, MPI_SUM, 0, MPI_COMM_WORLD);
+ if (rank == 0 && sum_size > 0)
+ printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n",
+ sum_size);
+ }
+
+ MPI_Allreduce(MPI_IN_PLACE, &nerrs, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
+ if (rank == 0) {
+ if (nerrs) printf(FAIL_STR,nerrs);
+ else printf(PASS_STR);
+ }
+
+ MPI_Finalize();
+ return 0;
+}
+
diff --git a/test/nonblocking/i_varn_indef.c b/test/nonblocking/i_varn_indef.c
new file mode 100644
index 0000000..84299dc
--- /dev/null
+++ b/test/nonblocking/i_varn_indef.c
@@ -0,0 +1,574 @@
+/*********************************************************************
+ *
+ * Copyright (C) 2015, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ *
+ *********************************************************************/
+/* $Id: i_varn_indef.c 2219 2015-12-11 22:30:03Z wkliao $ */
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * This example tests posting nonblocking varn APIs, including
+ * ncmpi_iput_varn_longlong(), ncmpi_iget_varn_longlong(), ncmpi_iput_varn(),
+ * and ncmpi_iget_varn(), in define mode.
+ * It first writes a sequence of requests with arbitrary array indices and
+ * lengths to four variables of type NC_INT64, and reads back.
+ *
+ * The compile and run commands are given below, together with an ncmpidump of
+ * the output file.
+ *
+ * % mpicc -O2 -o i_varn_indef i_varn_indef.c -lpnetcdf
+ * % mpiexec -n 4 ./i_varn_indef /pvfs2/wkliao/testfile.nc
+ * % ncmpidump /pvfs2/wkliao/testfile.nc
+ * netcdf testfile {
+ * // file format: CDF-5 (big variables)
+ * dimensions:
+ * Y = 4 ;
+ * X = 10 ;
+ * variables:
+ * int64 var0(Y, X) ;
+ * int64 var1(Y, X) ;
+ * int64 var2(Y, X) ;
+ * int64 var3(Y, X) ;
+ * data:
+ *
+ * var0 =
+ * 3, 3, 3, 1, 1, 0, 0, 2, 1, 1,
+ * 0, 2, 2, 2, 3, 1, 1, 2, 2, 2,
+ * 1, 1, 2, 3, 3, 3, 0, 0, 1, 1,
+ * 0, 0, 0, 2, 1, 1, 1, 3, 3, 3 ;
+ *
+ * var1 =
+ * 2, 2, 2, 0, 0, 3, 3, 1, 0, 0,
+ * 3, 1, 1, 1, 2, 0, 0, 1, 1, 1,
+ * 0, 0, 1, 2, 2, 2, 3, 3, 0, 0,
+ * 3, 3, 3, 1, 0, 0, 0, 2, 2, 2 ;
+ *
+ * var2 =
+ * 1, 1, 1, 3, 3, 2, 2, 0, 3, 3,
+ * 2, 0, 0, 0, 1, 3, 3, 0, 0, 0,
+ * 3, 3, 0, 1, 1, 1, 2, 2, 3, 3,
+ * 2, 2, 2, 0, 3, 3, 3, 1, 1, 1 ;
+ *
+ * var3 =
+ * 0, 0, 0, 2, 2, 1, 1, 3, 2, 2,
+ * 1, 3, 3, 3, 0, 2, 2, 3, 3, 3,
+ * 2, 2, 3, 0, 0, 0, 1, 1, 2, 2,
+ * 1, 1, 1, 3, 2, 2, 2, 0, 0, 0 ;
+ * }
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h> /* strcpy() */
+#include <mpi.h>
+#include <pnetcdf.h>
+
+#include <testutils.h>
+
+#define NY 4
+#define NX 10
+#define NDIMS 2
+
+#define ERR \
+ if (err != NC_NOERR) { \
+ printf("Error at line=%d: %s\n", __LINE__, ncmpi_strerror(err)); \
+ nerrs++; \
+ }
+
+#define ERRS(n,a) { \
+ int _i; \
+ for (_i=0; _i<(n); _i++) { \
+ if ((a)[_i] != NC_NOERR) { \
+ printf("Error at line=%d: err[%d] %s\n", __LINE__, _i, \
+ ncmpi_strerror((a)[_i])); \
+ nerrs++; \
+ } \
+ } \
+}
+
+static
+void clear_file_contents(int ncid, int *varid)
+{
+ int i, err, rank;
+ long long *w_buffer = (long long*) malloc(NY*NX * sizeof(long long));
+ for (i=0; i<NY*NX; i++) w_buffer[i] = -1;
+
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+
+ for (i=0; i<4; i++) {
+ err = ncmpi_put_var_longlong_all(ncid, varid[i], w_buffer);
+ if (err != NC_NOERR) printf("Error at line=%d: %s\n", __LINE__, ncmpi_strerror(err));
+ }
+ free(w_buffer);
+}
+
+static
+int check_contents_for_fail(int ncid, int *varid, int lineno)
+{
+ /* all processes read entire variables back and check contents */
+ int i, j, err, nprocs;
+ long long expected[4][NY*NX] = {{3, 3, 3, 1, 1, 0, 0, 2, 1, 1,
+ 0, 2, 2, 2, 3, 1, 1, 2, 2, 2,
+ 1, 1, 2, 3, 3, 3, 0, 0, 1, 1,
+ 0, 0, 0, 2, 1, 1, 1, 3, 3, 3},
+ {2, 2, 2, 0, 0, 3, 3, 1, 0, 0,
+ 3, 1, 1, 1, 2, 0, 0, 1, 1, 1,
+ 0, 0, 1, 2, 2, 2, 3, 3, 0, 0,
+ 3, 3, 3, 1, 0, 0, 0, 2, 2, 2},
+ {1, 1, 1, 3, 3, 2, 2, 0, 3, 3,
+ 2, 0, 0, 0, 1, 3, 3, 0, 0, 0,
+ 3, 3, 0, 1, 1, 1, 2, 2, 3, 3,
+ 2, 2, 2, 0, 3, 3, 3, 1, 1, 1},
+ {0, 0, 0, 2, 2, 1, 1, 3, 2, 2,
+ 1, 3, 3, 3, 0, 2, 2, 3, 3, 3,
+ 2, 2, 3, 0, 0, 0, 1, 1, 2, 2,
+ 1, 1, 1, 3, 2, 2, 2, 0, 0, 0}};
+
+ long long *r_buffer = (long long*) malloc(NY*NX * sizeof(long long));
+
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+ if (nprocs > 4) MPI_Barrier(MPI_COMM_WORLD);
+
+ for (i=0; i<4; i++) {
+ for (j=0; j<NY*NX; j++) r_buffer[j] = -1;
+ err = ncmpi_get_var_longlong_all(ncid, varid[i], r_buffer);
+ if (err != NC_NOERR) printf("Error at line=%d: %s\n", __LINE__, ncmpi_strerror(err));
+
+ /* check if the contents of buf are expected */
+ for (j=0; j<NY*NX; j++) {
+ if (expected[i][j] >= nprocs) continue;
+ if (r_buffer[j] != expected[i][j]) {
+ printf("Error from line %d: Expected read buf[%d][%d]=%lld, but got %lld\n",
+ lineno,i,j,expected[i][j],r_buffer[j]);
+ free(r_buffer);
+ return 1;
+ }
+ }
+ }
+ free(r_buffer);
+ return 0;
+}
+
+static int
+check_num_pending_reqs(int ncid, int expected, int lineno)
+/* check if PnetCDF can reports expected number of pending requests */
+{
+ int err, n_pendings;
+ err = ncmpi_inq_nreqs(ncid, &n_pendings);
+ if (err != NC_NOERR) printf("Error at line=%d: %s\n", __LINE__, ncmpi_strerror(err));
+ if (n_pendings != expected) {
+ printf("Error at line %d: expect %d pending requests but got %d\n",
+ lineno, expected, n_pendings);
+ return 1;
+ }
+ return 0;
+}
+
+/* swap two rows, a and b, of a 2D array */
+static
+void permute(MPI_Offset *a, MPI_Offset *b)
+{
+ int i;
+ MPI_Offset tmp;
+ for (i=0; i<NDIMS; i++) {
+ tmp = a[i]; a[i] = b[i]; b[i] = tmp;
+ }
+}
+
+int main(int argc, char** argv)
+{
+ char filename[256], *varname[4];
+ int i, j, k, rank, nprocs, verbose=0, err, nerrs=0, bufsize=0;
+ int ncid, cmode, varid[4], dimid[2], nreqs, reqs[12], sts[4];
+ long long *buffer[4], *cbuffer[4], *rbuffer[4];
+ int num_segs[4] = {4, 6, 5, 4};
+ int req_lens[4], my_nsegs[4];
+ MPI_Datatype buftype[4];
+ MPI_Offset **starts[4], **counts[4];
+ MPI_Offset n_starts[4][6][2] = {{{0,5}, {1,0}, {2,6}, {3,0}, {0,0}, {0,0}},
+ {{0,3}, {0,8}, {1,5}, {2,0}, {2,8}, {3,4}},
+ {{0,7}, {1,1}, {1,7}, {2,2}, {3,3}, {0,0}},
+ {{0,0}, {1,4}, {2,3}, {3,7}, {0,0}, {0,0}}};
+ MPI_Offset n_counts[4][6][2] = {{{1,2}, {1,1}, {1,2}, {1,3}, {0,0}, {0,0}},
+ {{1,2}, {1,2}, {1,2}, {1,2}, {1,2}, {1,3}},
+ {{1,1}, {1,3}, {1,3}, {1,1}, {1,1}, {0,0}},
+ {{1,3}, {1,1}, {1,3}, {1,3}, {0,0}, {0,0}}};
+
+ /* n_starts[0][][] n_counts[0][][] indicate the following: ("-" means skip)
+ - - - - - X X - - -
+ X - - - - - - - - -
+ - - - - - - X X - -
+ X X X - - - - - - -
+ n_starts[1][][] n_counts[1][][] indicate the following pattern.
+ - - - X X - - - X X
+ - - - - - X X - - -
+ X X - - - - - - X X
+ - - - - X X X - - -
+ n_starts[2][][] n_counts[2][][] indicate the following pattern.
+ - - - - - - - X - -
+ - X X X - - - X X X
+ - - X - - - - - - -
+ - - - X - - - - - -
+ n_starts[3][][] n_counts[3][][] indicate the following pattern.
+ X X X - - - - - - -
+ - - - - X - - - - -
+ - - - X X X - - - -
+ - - - - - - - X X X
+ */
+ MPI_Init(&argc, &argv);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+
+ if (argc > 2) {
+ if (!rank) printf("Usage: %s [filename]\n",argv[0]);
+ MPI_Finalize();
+ return 0;
+ }
+ strcpy(filename, "testfile.nc");
+ if (argc == 2) strcpy(filename, argv[1]);
+ MPI_Bcast(filename, 256, MPI_CHAR, 0, MPI_COMM_WORLD);
+
+ if (rank == 0) {
+ char cmd_str[256];
+ sprintf(cmd_str, "*** TESTING C %s for iput/iget varn in define mode ", argv[0]);
+ printf("%-66s ------ ", cmd_str);
+ }
+
+ if (verbose && nprocs != 4 && rank == 0)
+ printf("Warning: %s is intended to run on 4 processes\n",argv[0]);
+
+ /* allocate space for starts and counts */
+ starts[0] = (MPI_Offset**) malloc(4 * 6 * sizeof(MPI_Offset*));
+ counts[0] = (MPI_Offset**) malloc(4 * 6 * sizeof(MPI_Offset*));
+ starts[0][0] = (MPI_Offset*) calloc(4 * 6 * NDIMS, sizeof(MPI_Offset));
+ counts[0][0] = (MPI_Offset*) calloc(4 * 6 * NDIMS, sizeof(MPI_Offset));
+ for (i=1; i<4; i++) {
+ starts[i] = starts[i-1] + 6;
+ counts[i] = counts[i-1] + 6;
+ starts[i][0] = starts[i-1][0] + 6 * NDIMS;
+ counts[i][0] = counts[i-1][0] + 6 * NDIMS;
+ }
+ for (i=0; i<4; i++) {
+ for (j=1; j<6; j++) {
+ starts[i][j] = starts[i][j-1] + NDIMS;
+ counts[i][j] = counts[i][j-1] + NDIMS;
+ }
+ }
+
+ /* set values for starts and counts */
+ for (i=0; i<4; i++) {
+ int n = (i + rank) % 4;
+ my_nsegs[i] = num_segs[n]; /* number of segments for this request */
+ for (j=0; j<6; j++) {
+ for (k=0; k<NDIMS; k++) {
+ starts[i][j][k] = n_starts[n][j][k];
+ counts[i][j][k] = n_counts[n][j][k];
+ }
+ }
+ }
+
+ /* only rank 0, 1, 2, and 3 do I/O:
+ * each of ranks 0 to 3 write 4 nonblocking requests */
+ nreqs = 4;
+ if (rank >= 4) {
+ nreqs = 0;
+ for (i=0; i<4; i++) my_nsegs[i] = 0;
+ }
+
+ /* calculate length of each varn request and allocate write buffer */
+ for (i=0; i<nreqs; i++) {
+ req_lens[i] = 0; /* total length this request */
+ for (j=0; j<my_nsegs[i]; j++) {
+ MPI_Offset req_len=1;
+ for (k=0; k<NDIMS; k++)
+ req_len *= counts[i][j][k];
+ req_lens[i] += req_len;
+ }
+ if (verbose) printf("req_lens[%d]=%d\n",i,req_lens[i]);
+
+ /* allocate I/O buffer and initialize its contents */
+ buffer[i] = (long long*) malloc(req_lens[i] * sizeof(long long));
+ for (j=0; j<req_lens[i]; j++) buffer[i][j] = rank;
+ }
+ varname[0] = "var0";
+ varname[1] = "var1";
+ varname[2] = "var2";
+ varname[3] = "var3";
+
+ /* create a new file for writing ----------------------------------------*/
+ cmode = NC_CLOBBER | NC_64BIT_DATA;
+ err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, MPI_INFO_NULL, &ncid);
+ ERR
+
+ /* create a global array of size NY * NX */
+ err = ncmpi_def_dim(ncid, "Y", NY, &dimid[0]); ERR
+ err = ncmpi_def_dim(ncid, "X", NX, &dimid[1]); ERR
+
+ /* post write requests while still in define mode */
+ for (i=0; i<4; i++) {
+ err = ncmpi_def_var(ncid, varname[i], NC_INT64, NDIMS, dimid, &varid[i]);
+ ERR
+
+ err = ncmpi_iput_varn_longlong(ncid, varid[i], my_nsegs[i], starts[i],
+ counts[i], buffer[i], &reqs[i]);
+ ERR
+ }
+
+ /* test error code: NC_ENULLSTART */
+ err = ncmpi_iput_varn_longlong(ncid, varid[0], 1, NULL, NULL,
+ NULL, &reqs[4]);
+ if (err != NC_ENULLSTART) {
+ printf("expecting error code NC_ENULLSTART but got %s\n",
+ nc_err_code_name(err));
+ nerrs++;
+ }
+
+ err = ncmpi_enddef(ncid); ERR
+
+ /* clear the file contents using a blocking API, before commit the
+ * nonblocking requests posted in define mode */
+ clear_file_contents(ncid, varid);
+ nerrs += check_num_pending_reqs(ncid, nreqs, __LINE__);
+ err = ncmpi_wait_all(ncid, nreqs, reqs, sts);
+ ERRS(nreqs, sts)
+
+ /* all processes read entire variables back and check contents */
+ nerrs += check_contents_for_fail(ncid, varid, __LINE__);
+
+ err = ncmpi_close(ncid); ERR
+
+ /* try with buffer being a single contiguous space ----------------------*/
+ for (i=0; i<nreqs; i++) bufsize += req_lens[i];
+ if (bufsize>0) cbuffer[0] = (long long*) malloc(bufsize * sizeof(long long));
+ for (i=1; i<nreqs; i++) cbuffer[i] = cbuffer[i-1] + req_lens[i-1];
+ for (i=0; i<bufsize; i++) cbuffer[0][i] = rank;
+
+ /* create a new file for writing */
+ cmode = NC_CLOBBER | NC_64BIT_DATA;
+ err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, MPI_INFO_NULL, &ncid);
+ ERR
+
+ /* create a global array of size NY * NX */
+ err = ncmpi_def_dim(ncid, "Y", NY, &dimid[0]); ERR
+ err = ncmpi_def_dim(ncid, "X", NX, &dimid[1]); ERR
+
+ /* post write requests while still in define mode */
+ for (i=0; i<4; i++) {
+ err = ncmpi_def_var(ncid, varname[i], NC_INT64, NDIMS, dimid, &varid[i]);
+ ERR
+
+ err = ncmpi_iput_varn_longlong(ncid, varid[i], my_nsegs[i], starts[i],
+ counts[i], cbuffer[i], &reqs[i]);
+ ERR
+ }
+
+ err = ncmpi_enddef(ncid); ERR
+
+ /* clear the file contents using a blocking API, before commit the
+ * nonblocking requests posted in define mode */
+ clear_file_contents(ncid, varid);
+ nerrs += check_num_pending_reqs(ncid, nreqs, __LINE__);
+ err = ncmpi_wait_all(ncid, nreqs, reqs, sts);
+ ERRS(nreqs, sts)
+
+ /* all processes read entire variables back and check contents */
+ nerrs += check_contents_for_fail(ncid, varid, __LINE__);
+
+ err = ncmpi_close(ncid); ERR
+
+ /* permute write order: so starts[*] are not in an increasing order:
+ * swap segment 0 with segment 2 and swap segment 1 with segment 3
+ */
+ for (i=0; i<nreqs; i++) {
+ permute(starts[i][0], starts[i][2]); permute(counts[i][0], counts[i][2]);
+ permute(starts[i][1], starts[i][3]); permute(counts[i][1], counts[i][3]);
+ }
+
+ /* create a new file for writing */
+ cmode = NC_CLOBBER | NC_64BIT_DATA;
+ err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, MPI_INFO_NULL, &ncid);
+ ERR
+
+ /* create a global array of size NY * NX */
+ err = ncmpi_def_dim(ncid, "Y", NY, &dimid[0]); ERR
+ err = ncmpi_def_dim(ncid, "X", NX, &dimid[1]); ERR
+
+ /* write requests request while still in define mode */
+ for (i=0; i<4; i++) {
+ err = ncmpi_def_var(ncid, varname[i], NC_INT64, NDIMS, dimid, &varid[i]);
+ ERR
+
+ err = ncmpi_iput_varn_longlong(ncid, varid[i], my_nsegs[i], starts[i],
+ counts[i], buffer[i], &reqs[i]);
+ ERR
+ }
+
+ /* post read requests while still in define mode */
+ for (i=0; i<nreqs; i++) {
+ for (j=0; j<req_lens[i]; j++) cbuffer[i][j] = -1;
+ err = ncmpi_iget_varn_longlong(ncid, varid[i], my_nsegs[i], starts[i],
+ counts[i], cbuffer[i], &reqs[4+i]);
+ ERR
+ }
+
+ err = ncmpi_enddef(ncid); ERR
+
+ /* clear the file contents using a blocking API, before commit the
+ * nonblocking requests posted in define mode */
+ clear_file_contents(ncid, varid);
+ nerrs += check_num_pending_reqs(ncid, nreqs*2, __LINE__);
+ err = ncmpi_wait_all(ncid, nreqs, reqs, sts);
+ ERRS(nreqs, sts)
+
+ /* all processes read entire variables back and check contents */
+ nerrs += check_contents_for_fail(ncid, varid, __LINE__);
+
+ /* commit read requests */
+ nerrs += check_num_pending_reqs(ncid, nreqs, __LINE__);
+ err = ncmpi_wait_all(ncid, nreqs, reqs+4, sts);
+ ERRS(nreqs, sts)
+
+ err = ncmpi_close(ncid); ERR
+
+ for (i=0; i<nreqs; i++) {
+ for (j=0; j<req_lens[i]; j++) {
+ if (cbuffer[i][j] != rank) {
+ printf("Error at line %d: expecting cbuffer[%d][%d]=%d but got %lld\n",
+ __LINE__,i,j,rank,cbuffer[i][j]);
+ nerrs++;
+ }
+ }
+ }
+
+ for (i=0; i<nreqs; i++) free(buffer[i]);
+
+ /* test flexible APIs ---------------------------------------------------*/
+ for (i=0; i<nreqs; i++) {
+ MPI_Type_vector(req_lens[i], 1, 2, MPI_LONG_LONG, &buftype[i]);
+ MPI_Type_commit(&buftype[i]);
+ buffer[i] = (long long*) malloc(req_lens[i] * 2 * sizeof(long long));
+ for (j=0; j<req_lens[i]*2; j++) buffer[i][j] = rank;
+ rbuffer[i] = (long long*) malloc(req_lens[i] * 2 * sizeof(long long));
+ for (j=0; j<req_lens[i]*2; j++) rbuffer[i][j] = -1;
+ }
+
+ /* create a new file for writing */
+ cmode = NC_CLOBBER | NC_64BIT_DATA;
+ err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, MPI_INFO_NULL, &ncid);
+ ERR
+
+ /* create a global array of size NY * NX */
+ err = ncmpi_def_dim(ncid, "Y", NY, &dimid[0]); ERR
+ err = ncmpi_def_dim(ncid, "X", NX, &dimid[1]); ERR
+
+ /* write requests request while still in define mode */
+ for (i=0; i<4; i++) {
+ err = ncmpi_def_var(ncid, varname[i], NC_INT64, NDIMS, dimid, &varid[i]);
+ ERR
+
+ err = ncmpi_iput_varn(ncid, varid[i], my_nsegs[i], starts[i], counts[i],
+ buffer[i], 1, buftype[i], &reqs[i]); ERR
+ ERR
+ }
+
+ /* test flexible get API, using a noncontiguous buftype */
+ for (i=0; i<nreqs; i++) {
+ err = ncmpi_iget_varn(ncid, varid[i], my_nsegs[i], starts[i], counts[i],
+ rbuffer[i], 1, buftype[i], &reqs[i+4]);
+ ERR
+ }
+
+ for (i=0; i<nreqs; i++) MPI_Type_free(&buftype[i]);
+
+ /* read using a contiguous buffer. First swap back the starts[] and counts[].
+ * swap segment 0 with segment 2 and swap segment 1 with segment 3
+ */
+ for (i=0; i<nreqs; i++) {
+ permute(starts[i][0], starts[i][2]); permute(counts[i][0], counts[i][2]);
+ permute(starts[i][1], starts[i][3]); permute(counts[i][1], counts[i][3]);
+ }
+
+ for (i=0; i<bufsize; i++) cbuffer[0][i] = -1;
+ for (i=0; i<nreqs; i++) {
+ err = ncmpi_iget_varn_longlong(ncid, varid[i], my_nsegs[i], starts[i],
+ counts[i], cbuffer[i], &reqs[i+8]);
+ ERR
+ }
+
+ err = ncmpi_enddef(ncid); ERR
+
+ /* clear the file contents using a blocking API, before commit the
+ * nonblocking requests posted in define mode */
+ clear_file_contents(ncid, varid);
+ nerrs += check_num_pending_reqs(ncid, nreqs*3, __LINE__);
+ err = ncmpi_wait_all(ncid, nreqs, reqs, sts);
+ ERRS(nreqs, sts)
+
+ /* all processes read entire variables back and check contents */
+ nerrs += check_contents_for_fail(ncid, varid, __LINE__);
+
+ /* flush nonblocking 1st batch read requests */
+ nerrs += check_num_pending_reqs(ncid, nreqs*2, __LINE__);
+ err = ncmpi_wait_all(ncid, nreqs, reqs+4, sts);
+ ERRS(nreqs, sts)
+
+ for (i=0; i<nreqs; i++) {
+ for (j=0; j<req_lens[i]*2; j++) {
+ if (j%2 && rbuffer[i][j] != -1) {
+ printf("Error at line %d: expecting rbuffer[%d][%d]=-1 but got %lld\n",
+ __LINE__,i,j,rbuffer[i][j]);
+ nerrs++;
+ }
+ if (j%2 == 0 && rbuffer[i][j] != rank) {
+ printf("Error at line %d: expecting rbuffer[%d][%d]=%d but got %lld\n",
+ __LINE__,i,j,rank,rbuffer[i][j]);
+ nerrs++;
+ }
+ }
+ }
+
+ /* flush nonblocking 2nd batch read requests */
+ nerrs += check_num_pending_reqs(ncid, nreqs, __LINE__);
+ err = ncmpi_wait_all(ncid, nreqs, reqs+8, sts);
+ ERRS(nreqs, sts)
+
+ for (i=0; i<nreqs; i++) {
+ for (j=0; j<req_lens[i]; j++) {
+ if (cbuffer[i][j] != rank) {
+ printf("Error at line %d: expecting buffer[%d][%d]=%d but got %lld\n",
+ __LINE__,i,j,rank,cbuffer[i][j]);
+ nerrs++;
+ }
+ }
+ }
+
+ err = ncmpi_close(ncid);
+ ERR
+
+ if (bufsize>0) free(cbuffer[0]);
+ for (i=0; i<nreqs; i++) free(buffer[i]);
+ free(starts[0][0]);
+ free(counts[0][0]);
+ free(starts[0]);
+ free(counts[0]);
+
+ /* check if PnetCDF freed all internal malloc */
+ MPI_Offset malloc_size, sum_size;
+ err = ncmpi_inq_malloc_size(&malloc_size);
+ if (err == NC_NOERR) {
+ MPI_Reduce(&malloc_size, &sum_size, 1, MPI_OFFSET, MPI_SUM, 0, MPI_COMM_WORLD);
+ if (rank == 0 && sum_size > 0)
+ printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n",
+ sum_size);
+ }
+
+ MPI_Allreduce(MPI_IN_PLACE, &nerrs, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
+ if (rank == 0) {
+ if (nerrs) printf(FAIL_STR,nerrs);
+ else printf(PASS_STR);
+ }
+
+ MPI_Finalize();
+ return 0;
+}
+
diff --git a/test/nonblocking/i_varn_int64.c b/test/nonblocking/i_varn_int64.c
new file mode 100644
index 0000000..8dfa1a5
--- /dev/null
+++ b/test/nonblocking/i_varn_int64.c
@@ -0,0 +1,501 @@
+/*********************************************************************
+ *
+ * Copyright (C) 2014, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ *
+ *********************************************************************/
+/* $Id: i_varn_int64.c 2219 2015-12-11 22:30:03Z wkliao $ */
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * This example tests nonblocking varn APIs, including
+ * ncmpi_iput_varn_longlong(), ncmpi_iget_varn_longlong(), ncmpi_iput_varn(),
+ * and ncmpi_iget_varn().
+ * It first writes a sequence of requests with arbitrary array indices and
+ * lengths to four variables of type NC_INT64, and reads back.
+ *
+ * The compile and run commands are given below, together with an ncmpidump of
+ * the output file.
+ *
+ * % mpicc -O2 -o i_varn_int64 i_varn_int64.c -lpnetcdf
+ * % mpiexec -n 4 ./i_varn_int64 /pvfs2/wkliao/testfile.nc
+ * % ncmpidump /pvfs2/wkliao/testfile.nc
+ * netcdf testfile {
+ * // file format: CDF-5 (big variables)
+ * dimensions:
+ * Y = 4 ;
+ * X = 10 ;
+ * variables:
+ * int64 var0(Y, X) ;
+ * int64 var1(Y, X) ;
+ * int64 var2(Y, X) ;
+ * int64 var3(Y, X) ;
+ * data:
+ *
+ * var0 =
+ * 3, 3, 3, 1, 1, 0, 0, 2, 1, 1,
+ * 0, 2, 2, 2, 3, 1, 1, 2, 2, 2,
+ * 1, 1, 2, 3, 3, 3, 0, 0, 1, 1,
+ * 0, 0, 0, 2, 1, 1, 1, 3, 3, 3 ;
+ *
+ * var1 =
+ * 2, 2, 2, 0, 0, 3, 3, 1, 0, 0,
+ * 3, 1, 1, 1, 2, 0, 0, 1, 1, 1,
+ * 0, 0, 1, 2, 2, 2, 3, 3, 0, 0,
+ * 3, 3, 3, 1, 0, 0, 0, 2, 2, 2 ;
+ *
+ * var2 =
+ * 1, 1, 1, 3, 3, 2, 2, 0, 3, 3,
+ * 2, 0, 0, 0, 1, 3, 3, 0, 0, 0,
+ * 3, 3, 0, 1, 1, 1, 2, 2, 3, 3,
+ * 2, 2, 2, 0, 3, 3, 3, 1, 1, 1 ;
+ *
+ * var3 =
+ * 0, 0, 0, 2, 2, 1, 1, 3, 2, 2,
+ * 1, 3, 3, 3, 0, 2, 2, 3, 3, 3,
+ * 2, 2, 3, 0, 0, 0, 1, 1, 2, 2,
+ * 1, 1, 1, 3, 2, 2, 2, 0, 0, 0 ;
+ * }
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h> /* strcpy() */
+#include <mpi.h>
+#include <pnetcdf.h>
+
+#include <testutils.h>
+
+#define NY 4
+#define NX 10
+#define NDIMS 2
+
+#define ERR \
+ if (err != NC_NOERR) { \
+ printf("Error at line=%d: %s\n", __LINE__, ncmpi_strerror(err)); \
+ nerrs++; \
+ }
+
+#define ERRS(n,a) { \
+ int _i; \
+ for (_i=0; _i<(n); _i++) { \
+ if ((a)[_i] != NC_NOERR) { \
+ printf("Error at line=%d: err[%d] %s\n", __LINE__, _i, \
+ ncmpi_strerror((a)[_i])); \
+ nerrs++; \
+ } \
+ } \
+}
+
+static
+void clear_file_contents(int ncid, int *varid)
+{
+ int i, err, rank;
+ long long *w_buffer = (long long*) malloc(NY*NX * sizeof(long long));
+ for (i=0; i<NY*NX; i++) w_buffer[i] = -1;
+
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+
+ for (i=0; i<4; i++) {
+ err = ncmpi_put_var_longlong_all(ncid, varid[i], w_buffer);
+ if (err != NC_NOERR) printf("Error at line=%d: %s\n", __LINE__, ncmpi_strerror(err));
+ }
+ free(w_buffer);
+}
+
+static
+int check_contents_for_fail(int ncid, int *varid)
+{
+ /* all processes read entire variables back and check contents */
+ int i, j, err, nprocs;
+ long long expected[4][NY*NX] = {{3, 3, 3, 1, 1, 0, 0, 2, 1, 1,
+ 0, 2, 2, 2, 3, 1, 1, 2, 2, 2,
+ 1, 1, 2, 3, 3, 3, 0, 0, 1, 1,
+ 0, 0, 0, 2, 1, 1, 1, 3, 3, 3},
+ {2, 2, 2, 0, 0, 3, 3, 1, 0, 0,
+ 3, 1, 1, 1, 2, 0, 0, 1, 1, 1,
+ 0, 0, 1, 2, 2, 2, 3, 3, 0, 0,
+ 3, 3, 3, 1, 0, 0, 0, 2, 2, 2},
+ {1, 1, 1, 3, 3, 2, 2, 0, 3, 3,
+ 2, 0, 0, 0, 1, 3, 3, 0, 0, 0,
+ 3, 3, 0, 1, 1, 1, 2, 2, 3, 3,
+ 2, 2, 2, 0, 3, 3, 3, 1, 1, 1},
+ {0, 0, 0, 2, 2, 1, 1, 3, 2, 2,
+ 1, 3, 3, 3, 0, 2, 2, 3, 3, 3,
+ 2, 2, 3, 0, 0, 0, 1, 1, 2, 2,
+ 1, 1, 1, 3, 2, 2, 2, 0, 0, 0}};
+
+ long long *r_buffer = (long long*) malloc(NY*NX * sizeof(long long));
+
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+ if (nprocs > 4) MPI_Barrier(MPI_COMM_WORLD);
+
+ for (i=0; i<4; i++) {
+ for (j=0; j<NY*NX; j++) r_buffer[j] = -1;
+ err = ncmpi_get_var_longlong_all(ncid, varid[i], r_buffer);
+ if (err != NC_NOERR) printf("Error at line=%d: %s\n", __LINE__, ncmpi_strerror(err));
+
+ /* check if the contents of buf are expected */
+ for (j=0; j<NY*NX; j++) {
+ if (expected[i][j] >= nprocs) continue;
+ if (r_buffer[j] != expected[i][j]) {
+ printf("Expected read buf[%d][%d]=%lld, but got %lld\n",
+ i,j,expected[i][j],r_buffer[j]);
+ free(r_buffer);
+ return 1;
+ }
+ }
+ }
+ free(r_buffer);
+ return 0;
+}
+
+static int
+check_num_pending_reqs(int ncid, int expected, int lineno)
+/* check if PnetCDF can reports expected number of pending requests */
+{
+ int err, n_pendings;
+ err = ncmpi_inq_nreqs(ncid, &n_pendings);
+ if (err != NC_NOERR) printf("Error at line=%d: %s\n", __LINE__, ncmpi_strerror(err));
+ if (n_pendings != expected) {
+ printf("Error at line %d: expect %d pending requests but got %d\n",
+ lineno, expected, n_pendings);
+ return 1;
+ }
+ return 0;
+}
+
+/* swap two rows, a and b, of a 2D array */
+static
+void permute(MPI_Offset *a, MPI_Offset *b)
+{
+ int i;
+ MPI_Offset tmp;
+ for (i=0; i<NDIMS; i++) {
+ tmp = a[i]; a[i] = b[i]; b[i] = tmp;
+ }
+}
+
+int main(int argc, char** argv)
+{
+ char filename[256];
+ int i, j, k, rank, nprocs, verbose=0, err, nerrs=0, bufsize=0;
+ int ncid, cmode, varid[4], dimid[2], nreqs, reqs[4], sts[4];
+ long long *buffer[4], *cbuffer[4];
+ int num_segs[4] = {4, 6, 5, 4};
+ int req_lens[4], my_nsegs[4];
+ MPI_Offset **starts[4], **counts[4];
+ MPI_Offset n_starts[4][6][2] = {{{0,5}, {1,0}, {2,6}, {3,0}, {0,0}, {0,0}},
+ {{0,3}, {0,8}, {1,5}, {2,0}, {2,8}, {3,4}},
+ {{0,7}, {1,1}, {1,7}, {2,2}, {3,3}, {0,0}},
+ {{0,0}, {1,4}, {2,3}, {3,7}, {0,0}, {0,0}}};
+ MPI_Offset n_counts[4][6][2] = {{{1,2}, {1,1}, {1,2}, {1,3}, {0,0}, {0,0}},
+ {{1,2}, {1,2}, {1,2}, {1,2}, {1,2}, {1,3}},
+ {{1,1}, {1,3}, {1,3}, {1,1}, {1,1}, {0,0}},
+ {{1,3}, {1,1}, {1,3}, {1,3}, {0,0}, {0,0}}};
+
+ /* n_starts[0][][] n_counts[0][][] indicate the following: ("-" means skip)
+ - - - - - X X - - -
+ X - - - - - - - - -
+ - - - - - - X X - -
+ X X X - - - - - - -
+ n_starts[1][][] n_counts[1][][] indicate the following pattern.
+ - - - X X - - - X X
+ - - - - - X X - - -
+ X X - - - - - - X X
+ - - - - X X X - - -
+ n_starts[2][][] n_counts[2][][] indicate the following pattern.
+ - - - - - - - X - -
+ - X X X - - - X X X
+ - - X - - - - - - -
+ - - - X - - - - - -
+ n_starts[3][][] n_counts[3][][] indicate the following pattern.
+ X X X - - - - - - -
+ - - - - X - - - - -
+ - - - X X X - - - -
+ - - - - - - - X X X
+ */
+ MPI_Init(&argc, &argv);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+
+ if (argc > 2) {
+ if (!rank) printf("Usage: %s [filename]\n",argv[0]);
+ MPI_Finalize();
+ return 0;
+ }
+ strcpy(filename, "testfile.nc");
+ if (argc == 2) strcpy(filename, argv[1]);
+ MPI_Bcast(filename, 256, MPI_CHAR, 0, MPI_COMM_WORLD);
+
+ if (rank == 0) {
+ char cmd_str[256];
+ sprintf(cmd_str, "*** TESTING C %s for iput/iget varn ", argv[0]);
+ printf("%-66s ------ ", cmd_str);
+ }
+
+ if (verbose && nprocs != 4 && rank == 0)
+ printf("Warning: %s is intended to run on 4 processes\n",argv[0]);
+
+ /* create a new file for writing ----------------------------------------*/
+ cmode = NC_CLOBBER | NC_64BIT_DATA;
+ err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, MPI_INFO_NULL, &ncid);
+ ERR
+
+ /* create a global array of size NY * NX */
+ err = ncmpi_def_dim(ncid, "Y", NY, &dimid[0]); ERR
+ err = ncmpi_def_dim(ncid, "X", NX, &dimid[1]); ERR
+ err = ncmpi_def_var(ncid, "var0", NC_INT64, NDIMS, dimid, &varid[0]); ERR
+ err = ncmpi_def_var(ncid, "var1", NC_INT64, NDIMS, dimid, &varid[1]); ERR
+ err = ncmpi_def_var(ncid, "var2", NC_INT64, NDIMS, dimid, &varid[2]); ERR
+ err = ncmpi_def_var(ncid, "var3", NC_INT64, NDIMS, dimid, &varid[3]); ERR
+ err = ncmpi_enddef(ncid); ERR
+
+ /* allocate space for starts and counts */
+ starts[0] = (MPI_Offset**) malloc(4 * 6 * sizeof(MPI_Offset*));
+ counts[0] = (MPI_Offset**) malloc(4 * 6 * sizeof(MPI_Offset*));
+ starts[0][0] = (MPI_Offset*) calloc(4 * 6 * NDIMS, sizeof(MPI_Offset));
+ counts[0][0] = (MPI_Offset*) calloc(4 * 6 * NDIMS, sizeof(MPI_Offset));
+ for (i=1; i<4; i++) {
+ starts[i] = starts[i-1] + 6;
+ counts[i] = counts[i-1] + 6;
+ starts[i][0] = starts[i-1][0] + 6 * NDIMS;
+ counts[i][0] = counts[i-1][0] + 6 * NDIMS;
+ }
+ for (i=0; i<4; i++) {
+ for (j=1; j<6; j++) {
+ starts[i][j] = starts[i][j-1] + NDIMS;
+ counts[i][j] = counts[i][j-1] + NDIMS;
+ }
+ }
+
+ /* set values for starts and counts */
+ for (i=0; i<4; i++) {
+ int n = (i + rank) % 4;
+ my_nsegs[i] = num_segs[n]; /* number of segments for this request */
+ for (j=0; j<6; j++) {
+ for (k=0; k<NDIMS; k++) {
+ starts[i][j][k] = n_starts[n][j][k];
+ counts[i][j][k] = n_counts[n][j][k];
+ }
+ }
+ }
+
+ /* test error code: NC_ENULLSTART */
+ err = ncmpi_iput_varn_longlong(ncid, varid[0], 1, NULL, NULL,
+ NULL, &reqs[0]);
+ if (err != NC_ENULLSTART) {
+ printf("expecting error code NC_ENULLSTART but got %s\n",
+ nc_err_code_name(err));
+ nerrs++;
+ }
+
+ /* only rank 0, 1, 2, and 3 do I/O:
+ * each of ranks 0 to 3 write 4 nonblocking requests */
+ nreqs = 4;
+ if (rank >= 4) nreqs = 0;
+
+ /* calculate length of each varn request and allocate write buffer */
+ for (i=0; i<nreqs; i++) {
+ req_lens[i] = 0; /* total length this request */
+ for (j=0; j<my_nsegs[i]; j++) {
+ MPI_Offset req_len=1;
+ for (k=0; k<NDIMS; k++)
+ req_len *= counts[i][j][k];
+ req_lens[i] += req_len;
+ }
+ if (verbose) printf("req_lens[%d]=%d\n",i,req_lens[i]);
+
+ /* allocate I/O buffer and initialize its contents */
+ buffer[i] = (long long*) malloc(req_lens[i] * sizeof(long long));
+ for (j=0; j<req_lens[i]; j++) buffer[i][j] = rank;
+ }
+
+ /* write using varn API */
+ clear_file_contents(ncid, varid);
+ for (i=0; i<nreqs; i++) {
+ err = ncmpi_iput_varn_longlong(ncid, varid[i], my_nsegs[i], starts[i],
+ counts[i], buffer[i], &reqs[i]);
+ ERR
+ }
+ nerrs += check_num_pending_reqs(ncid, nreqs, __LINE__);
+ err = ncmpi_wait_all(ncid, nreqs, reqs, sts);
+ ERRS(nreqs, sts)
+
+ /* all processes read entire variables back and check contents */
+ nerrs += check_contents_for_fail(ncid, varid);
+
+ /* try with buffer being a single contiguous space */
+ for (i=0; i<nreqs; i++) bufsize += req_lens[i];
+ if (bufsize>0) cbuffer[0] = (long long*) malloc(bufsize * sizeof(long long));
+ for (i=1; i<nreqs; i++) cbuffer[i] = cbuffer[i-1] + req_lens[i-1];
+ for (i=0; i<bufsize; i++) cbuffer[0][i] = rank;
+
+ /* write usning varn API */
+ clear_file_contents(ncid, varid);
+ for (i=0; i<nreqs; i++) {
+ err = ncmpi_iput_varn_longlong(ncid, varid[i], my_nsegs[i], starts[i],
+ counts[i], cbuffer[i], &reqs[i]);
+ ERR
+ }
+ nerrs += check_num_pending_reqs(ncid, nreqs, __LINE__);
+ err = ncmpi_wait_all(ncid, nreqs, reqs, sts);
+ ERRS(nreqs, sts)
+
+ /* all processes read entire variables back and check contents */
+ nerrs += check_contents_for_fail(ncid, varid);
+
+ /* permute write order: so starts[*] are not in an increasing order:
+ * swap segment 0 with segment 2 and swap segment 1 with segment 3
+ */
+ for (i=0; i<nreqs; i++) {
+ permute(starts[i][0], starts[i][2]); permute(counts[i][0], counts[i][2]);
+ permute(starts[i][1], starts[i][3]); permute(counts[i][1], counts[i][3]);
+ }
+
+ /* write usning varn API */
+ clear_file_contents(ncid, varid);
+ for (i=0; i<nreqs; i++) {
+ err = ncmpi_iput_varn_longlong(ncid, varid[i], my_nsegs[i], starts[i],
+ counts[i], buffer[i], &reqs[i]);
+ ERR
+ }
+ nerrs += check_num_pending_reqs(ncid, nreqs, __LINE__);
+ err = ncmpi_wait_all(ncid, nreqs, reqs, sts);
+ ERRS(nreqs, sts)
+
+ /* all processes read entire variables back and check contents */
+ nerrs += check_contents_for_fail(ncid, varid);
+
+ /* read using get_varn API and check contents */
+ for (i=0; i<nreqs; i++) {
+ for (j=0; j<req_lens[i]; j++) buffer[i][j] = -1;
+ err = ncmpi_iget_varn_longlong(ncid, varid[i], my_nsegs[i], starts[i],
+ counts[i], buffer[i], &reqs[i]);
+ ERR
+ }
+ nerrs += check_num_pending_reqs(ncid, nreqs, __LINE__);
+ err = ncmpi_wait_all(ncid, nreqs, reqs, sts);
+ ERRS(nreqs, sts)
+
+ for (i=0; i<nreqs; i++) {
+ for (j=0; j<req_lens[i]; j++) {
+ if (buffer[i][j] != rank) {
+ printf("Error at line %d: expecting buffer[%d][%d]=%d but got %lld\n",
+ __LINE__,i,j,rank,buffer[i][j]);
+ nerrs++;
+ }
+ }
+ }
+
+ for (i=0; i<nreqs; i++) free(buffer[i]);
+
+ /* test flexible put API, using a noncontiguous buftype */
+ clear_file_contents(ncid, varid);
+ for (i=0; i<nreqs; i++) {
+ MPI_Datatype buftype;
+ MPI_Type_vector(req_lens[i], 1, 2, MPI_LONG_LONG, &buftype);
+ MPI_Type_commit(&buftype);
+ buffer[i] = (long long*) malloc(req_lens[i] * 2 * sizeof(long long));
+ for (j=0; j<req_lens[i]*2; j++) buffer[i][j] = rank;
+
+ err = ncmpi_iput_varn(ncid, varid[i], my_nsegs[i], starts[i],
+ counts[i], buffer[i], 1, buftype, &reqs[i]);
+ ERR
+ MPI_Type_free(&buftype);
+ }
+ nerrs += check_num_pending_reqs(ncid, nreqs, __LINE__);
+ err = ncmpi_wait_all(ncid, nreqs, reqs, sts);
+ ERRS(nreqs, sts)
+
+ /* all processes read entire variables back and check contents */
+ nerrs += check_contents_for_fail(ncid, varid);
+
+ /* test flexible get API, using a noncontiguous buftype */
+ for (i=0; i<nreqs; i++) {
+ MPI_Datatype buftype;
+ MPI_Type_vector(req_lens[i], 1, 2, MPI_LONG_LONG, &buftype);
+ MPI_Type_commit(&buftype);
+ for (j=0; j<req_lens[i]*2; j++) buffer[i][j] = -1;
+ err = ncmpi_iget_varn(ncid, varid[i], my_nsegs[i], starts[i],
+ counts[i], buffer[i], 1, buftype, &reqs[i]);
+ ERR
+ MPI_Type_free(&buftype);
+ }
+ nerrs += check_num_pending_reqs(ncid, nreqs, __LINE__);
+ err = ncmpi_wait_all(ncid, nreqs, reqs, sts);
+ ERRS(nreqs, sts)
+
+ for (i=0; i<nreqs; i++) {
+ for (j=0; j<req_lens[i]*2; j++) {
+ if (j%2 && buffer[i][j] != -1) {
+ printf("Error at line %d: expecting buffer[%d][%d]=-1 but got %lld\n",
+ __LINE__,i,j,buffer[i][j]);
+ nerrs++;
+ }
+ if (j%2 == 0 && buffer[i][j] != rank) {
+ printf("Error at line %d: expecting buffer[%d][%d]=%d but got %lld\n",
+ __LINE__,i,j,rank,buffer[i][j]);
+ nerrs++;
+ }
+ }
+ }
+
+ /* read back using a contiguous buffer. First swap back the starts[] and counts[].
+ * swap segment 0 with segment 2 and swap segment 1 with segment 3
+ */
+ for (i=0; i<nreqs; i++) {
+ permute(starts[i][0], starts[i][2]); permute(counts[i][0], counts[i][2]);
+ permute(starts[i][1], starts[i][3]); permute(counts[i][1], counts[i][3]);
+ }
+
+ for (i=0; i<bufsize; i++) cbuffer[0][i] = -1;
+ for (i=0; i<nreqs; i++) {
+ for (j=0; j<req_lens[i]; j++) buffer[i][j] = -1;
+ err = ncmpi_iget_varn_longlong(ncid, varid[i], my_nsegs[i], starts[i],
+ counts[i], cbuffer[i], &reqs[i]);
+ ERR
+ }
+ nerrs += check_num_pending_reqs(ncid, nreqs, __LINE__);
+ err = ncmpi_wait_all(ncid, nreqs, reqs, sts);
+ ERRS(nreqs, sts)
+
+ for (i=0; i<nreqs; i++) {
+ for (j=0; j<req_lens[i]; j++) {
+ if (cbuffer[i][j] != rank) {
+ printf("Error at line %d: expecting buffer[%d][%d]=%d but got %lld\n",
+ __LINE__,i,j,rank,cbuffer[i][j]);
+ nerrs++;
+ }
+ }
+ }
+
+ err = ncmpi_close(ncid);
+ ERR
+
+ if (bufsize>0) free(cbuffer[0]);
+ for (i=0; i<nreqs; i++) free(buffer[i]);
+ free(starts[0][0]);
+ free(counts[0][0]);
+ free(starts[0]);
+ free(counts[0]);
+
+ /* check if PnetCDF freed all internal malloc */
+ MPI_Offset malloc_size, sum_size;
+ err = ncmpi_inq_malloc_size(&malloc_size);
+ if (err == NC_NOERR) {
+ MPI_Reduce(&malloc_size, &sum_size, 1, MPI_OFFSET, MPI_SUM, 0, MPI_COMM_WORLD);
+ if (rank == 0 && sum_size > 0)
+ printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n",
+ sum_size);
+ }
+
+ MPI_Allreduce(MPI_IN_PLACE, &nerrs, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
+ if (rank == 0) {
+ if (nerrs) printf(FAIL_STR,nerrs);
+ else printf(PASS_STR);
+ }
+
+ MPI_Finalize();
+ return 0;
+}
+
diff --git a/test/nonblocking/interleaved.c b/test/nonblocking/interleaved.c
new file mode 100644
index 0000000..23cc18d
--- /dev/null
+++ b/test/nonblocking/interleaved.c
@@ -0,0 +1,195 @@
+/*********************************************************************
+ *
+ * Copyright (C) 2014, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ *
+ *********************************************************************/
+/* $Id: interleaved.c 2133 2015-09-26 19:16:01Z wkliao $ */
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * This program tests nonblocking APIs for handling interleaved file types.
+ * It makes 3 calls to ncmpi_iput_vara_int(), where the first 2 interleaved and
+ * the third one does not.
+ * It first defines a netCDF variable of size 10 x 20.
+ * First write: a subarray of size 3 x 5 at the start offsets of 6 x 8
+ * Second write: a subarray of size 2 x 5 at the start offsets of 6 x 13
+ * Third write: a subarray of size 1 x 5 at the start offsets of 8 x 13
+ *
+ * % mpiexec -n 1 ./interleaved
+ * % ncmpidump testfile.nc
+ * netcdf testfile {
+ * // file format: CDF-5 (big variables)
+ * dimensions:
+ * Y = 10 ;
+ * X = 20 ;
+ * variables:
+ * int var(Y, X) ;
+ * data:
+ *
+ * var =
+ * -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ * -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ * -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ * -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ * -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ * -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ * -1, -1, -1, -1, -1, -1, -1, -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, -1, -1,
+ * -1, -1, -1, -1, -1, -1, -1, -1, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, -1, -1,
+ * -1, -1, -1, -1, -1, -1, -1, -1, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, -1, -1,
+ * -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ;
+ * }
+ *
+
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h> /* strcpy() */
+#include <mpi.h>
+#include <pnetcdf.h>
+
+#include <testutils.h>
+
+#define NY 10
+#define NX 20
+
+#define ERR if (err!=NC_NOERR) {printf("Error at line %d: %s\n", __LINE__,ncmpi_strerror(err)); exit(-1);}
+
+int main(int argc, char** argv)
+{
+ char filename[256];
+ int i, j, rank, nprocs, err, nerrs=0, expected;
+ int ncid, cmode, varid, dimid[2], req[3], st[3], *buf;
+ MPI_Offset start[2], count[2];
+ MPI_Info info;
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+
+ /* this program is intended to run on one process */
+ if (rank) goto fn_exit;
+
+ /* get command-line arguments */
+ if (argc > 2) {
+ if (!rank) printf("Usage: %s [filename]\n",argv[0]);
+ MPI_Finalize();
+ return 0;
+ }
+ strcpy(filename, "testfile.nc");
+ if (argc == 2) strcpy(filename, argv[1]);
+
+ if (rank == 0) {
+ char cmd_str[256];
+ sprintf(cmd_str, "*** TESTING C %s for writing interleaved fileviews ", argv[0]);
+ printf("%-66s ------ ", cmd_str);
+ }
+
+ MPI_Info_create(&info);
+ MPI_Info_set(info, "romio_cb_write", "disable");
+ MPI_Info_set(info, "ind_wr_buffer_size", "8");
+ /* these 2 hints are required to cause a core dump if r1758 fix is not
+ * presented */
+
+ /* create a new file for writing ----------------------------------------*/
+ cmode = NC_CLOBBER | NC_64BIT_DATA;
+ err = ncmpi_create(MPI_COMM_SELF, filename, cmode, info, &ncid);
+ ERR
+
+ MPI_Info_free(&info);
+
+ /* define dimensions Y and X */
+ err = ncmpi_def_dim(ncid, "Y", NY, &dimid[0]);
+ ERR
+ err = ncmpi_def_dim(ncid, "X", NX, &dimid[1]);
+ ERR
+
+ /* define a 2D variable of integer type */
+ err = ncmpi_def_var(ncid, "var", NC_INT, 2, dimid, &varid);
+ ERR
+
+ /* do not forget to exit define mode */
+ err = ncmpi_enddef(ncid);
+ ERR
+
+ /* now we are in data mode */
+ buf = (int*) malloc(NY*NX * sizeof(int));
+ for (i=0; i<NY*NX; i++) buf[i] = -1;
+
+ /* fill the entire array with -1s */
+ err = ncmpi_put_var_int_all(ncid, varid, buf); ERR
+
+ /* rearrange buffer contents, as buf is 2D */
+ for (i=0; i<5; i++) buf[i] = 10 + i;
+ for (i=5; i<10; i++) buf[i] = 10 + i + 5;
+ for (i=10; i<15; i++) buf[i] = 10 + i + 10;
+ start[0] = 6; start[1] = 8;
+ count[0] = 3; count[1] = 5;
+ err = ncmpi_iput_vara_int(ncid, varid, start, count, buf, &req[0]);
+ ERR
+
+ for (i=15; i<20; i++) buf[i] = 10 + i - 10;
+ for (i=20; i<25; i++) buf[i] = 10 + i - 5;
+ start[0] = 6; start[1] = 13;
+ count[0] = 2; count[1] = 5;
+ err = ncmpi_iput_vara_int(ncid, varid, start, count, buf+15, &req[1]);
+ ERR
+
+ for (i=25; i<30; i++) buf[i] = 10 + i;
+ start[0] = 8; start[1] = 13;
+ count[0] = 1; count[1] = 5;
+ err = ncmpi_iput_vara_int(ncid, varid, start, count, buf+25, &req[2]);
+ ERR
+
+ err = ncmpi_wait_all(ncid, 3, req, st);
+ ERR
+
+ err = ncmpi_close(ncid);
+ ERR
+
+ /* open the same file and read back for validate */
+ err = ncmpi_open(MPI_COMM_SELF, filename, NC_NOWRITE, MPI_INFO_NULL,
+ &ncid); ERR
+
+ err = ncmpi_inq_varid(ncid, "var", &varid); ERR
+
+ /* initialize the contents of the array to a different value */
+ for (i=0; i<NY*NX; i++) buf[i] = -1;
+
+ /* read the entire array */
+ err = ncmpi_get_var_int_all(ncid, varid, buf); ERR
+
+ /* check if the contents of buf are expected */
+ expected = 10;
+ for (j=6; j<9; j++) {
+ for (i=8; i<18; i++) {
+ if (buf[j*NX+i] != expected) {
+ printf("%d: Unexpected read buf[%d]=%d, should be %d\n",
+ rank, i, buf[j*NX+i], expected);
+ nerrs++;
+ }
+ expected++;
+ }
+ }
+
+ err = ncmpi_close(ncid); ERR
+
+ free(buf);
+
+ /* check if PnetCDF freed all internal malloc */
+ MPI_Offset malloc_size;
+ err = ncmpi_inq_malloc_size(&malloc_size);
+ if (err == NC_NOERR && malloc_size > 0)
+ printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n", malloc_size);
+
+fn_exit:
+ MPI_Allreduce(MPI_IN_PLACE, &nerrs, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
+ if (rank == 0) {
+ if (nerrs) printf(FAIL_STR,nerrs);
+ else printf(PASS_STR);
+ }
+
+ MPI_Finalize();
+ return 0;
+}
+
diff --git a/test/nonblocking/mcoll_perf.c b/test/nonblocking/mcoll_perf.c
new file mode 100644
index 0000000..fe50e0f
--- /dev/null
+++ b/test/nonblocking/mcoll_perf.c
@@ -0,0 +1,685 @@
+/* -*- Mode: C; c-basic-offset:4 ; -*- */
+/*
+ * (C) 2001 by Argonne National Laboratory.
+ * See COPYRIGHT in top-level directory.
+ *
+ * $Id: mcoll_perf.c 2150 2015-10-10 05:52:57Z wkliao $
+ */
+#include <mpi.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <pnetcdf.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <testutils.h>
+
+/* The file name is taken as a command-line argument. */
+
+static int verbose;
+static int nerrs;
+
+/* Measures the I/O bandwidth for writing/reading a 3D
+ block-distributed array to a file corresponding to the global array
+ in row-major (C) order.
+ Note that the file access pattern is noncontiguous.
+
+ Array size 128^3. For other array sizes, change array_of_gsizes below.*/
+#define HANDLE_ERROR \
+ if (status != NC_NOERR) { \
+ printf("Error: func=%s line=%d err=%s\n", \
+ __func__,__LINE__,ncmpi_strerror(status)); \
+ nerrs++; \
+ }
+
+#define HANDLE_DIFF(str) { \
+ int doStop, isDiff = (str[0] == '\0') ? 0 : 1; \
+ MPI_Allreduce(&isDiff, &doStop, 1, MPI_INT, MPI_MAX, comm); \
+ if (doStop) { \
+ printf("P%d: diff at line %d (%s)\n",rank,__LINE__,str); \
+ MPI_Finalize(); \
+ exit(1); \
+ } \
+}
+
+#define CHECK_GLOBAL_ATT_DIFF(type, func, nctype) { \
+ int pos, len = attlen1 * sizeof(type); \
+ type *b1 = (type *)malloc(len); \
+ type *b2 = (type *)malloc(len); \
+ status = func(ncid1, NC_GLOBAL, name1, b1); \
+ HANDLE_ERROR \
+ status = func(ncid2, NC_GLOBAL, name2, b2); \
+ HANDLE_ERROR \
+ if ((pos = memcmp(b1, b2, len)) != 0) { \
+ printf("P%d: diff at line %d (attribute[%d] %s: %s buf1 != buf2 at position %d)\n", \
+ rank,__LINE__,i,name1,#nctype,pos); \
+ nerrs++; \
+ } \
+ free(b1); \
+ free(b2); \
+ break; \
+}
+
+#define CHECK_VAR_ATT_DIFF(type, func, nctype) { \
+ int pos, len = attlen1 * sizeof(type); \
+ type *b1 = (type *)malloc(len); \
+ type *b2 = (type *)malloc(len); \
+ status = func(ncid1, i, name1, b1); \
+ HANDLE_ERROR \
+ status = func(ncid2, i, name2, b2); \
+ HANDLE_ERROR \
+ if ((pos = memcmp(b1, b2, len)) != 0) { \
+ printf("P%d: diff at line %d (variable[%d] %s: attribute[%d] %s: %s buf1 != buf2 at position %d)\n", \
+ rank,__LINE__,i,name,j,name1,#nctype,pos); \
+ nerrs++; \
+ } \
+ free(b1); \
+ free(b2); \
+ break; \
+}
+
+
+#define CHECK_VAR_DIFF(type, func, nctype) { \
+ int pos, len = varsize * sizeof(type); \
+ type *b1 = (type *)malloc(len); \
+ type *b2 = (type *)malloc(len); \
+ status = func(ncid1, i, start, shape, b1); \
+ HANDLE_ERROR \
+ status = func(ncid2, i, start, shape, b2); \
+ HANDLE_ERROR \
+ if ((pos = memcmp(b1, b2, len)) != 0) { \
+ printf("P%d: diff at line %d variable[%d] %s: %s buf1 != buf2 at position %d)\n", \
+ rank,__LINE__,i,name,#nctype,pos); \
+ nerrs++; \
+ } \
+ free(b1); \
+ free(b2); \
+ break; \
+}
+
+
+static
+int ncmpi_diff(char *filename1, char *filename2) {
+ int i, j, status, rank, nprocs;
+ int ncid1, ndims1, nvars1, natts1, unlimdimid1, dimids1[NC_MAX_DIMS];
+ int ncid2, ndims2, nvars2, natts2, unlimdimid2, dimids2[NC_MAX_DIMS];
+ char str[512], name1[NC_MAX_NAME], name2[NC_MAX_NAME], name[NC_MAX_NAME];
+ MPI_Offset shape[NC_MAX_VAR_DIMS], varsize, start[NC_MAX_VAR_DIMS];
+ MPI_Offset attlen1, dimlen1, attlen2, dimlen2;
+ nc_type type1, type2;
+ MPI_Comm comm=MPI_COMM_WORLD;
+
+ MPI_Comm_size(comm, &nprocs);
+ MPI_Comm_rank(comm, &rank);
+
+ str[0] = '\0';
+ status = ncmpi_open(comm, filename1, NC_NOWRITE, MPI_INFO_NULL, &ncid1);
+ HANDLE_ERROR
+ status = ncmpi_open(comm, filename2, NC_NOWRITE, MPI_INFO_NULL, &ncid2);
+ HANDLE_ERROR
+
+ /**
+ * Inquire the dataset definitions of input dataset AND
+ * Add dataset definitions for output dataset.
+ */
+ status = ncmpi_inq(ncid1, &ndims1, &nvars1, &natts1, &unlimdimid1);
+ HANDLE_ERROR
+ status = ncmpi_inq(ncid2, &ndims2, &nvars2, &natts2, &unlimdimid2);
+ HANDLE_ERROR
+ if (ndims1 != ndims2)
+ sprintf(str,"ndims1(%d) != ndims2(%d)",ndims1, ndims2);
+ HANDLE_DIFF(str)
+ if (nvars1 != nvars2)
+ sprintf(str,"nvars1(%d) != nvars2(%d)",nvars1, nvars2);
+ HANDLE_DIFF(str)
+ if (natts1 != natts2)
+ sprintf(str,"natts1(%d) != natts2(%d)",natts1, natts2);
+ HANDLE_DIFF(str)
+
+ /* Inquire global attributes, assume CHAR attributes. */
+ for (i=0; i<natts1; i++) {
+ status = ncmpi_inq_attname(ncid1, NC_GLOBAL, i, name1);
+ HANDLE_ERROR
+ status = ncmpi_inq_attname(ncid1, NC_GLOBAL, i, name2);
+ HANDLE_ERROR
+ if (strcmp(name1, name2) != 0)
+ sprintf(str,"attribute[%d] name1(%s) != name2(%s)",i,name1,name2);
+ HANDLE_DIFF(str)
+
+ status = ncmpi_inq_att(ncid1, NC_GLOBAL, name1, &type1, &attlen1);
+ HANDLE_ERROR
+ status = ncmpi_inq_att(ncid2, NC_GLOBAL, name2, &type2, &attlen2);
+ HANDLE_ERROR
+ if (type1 != type2)
+ sprintf(str,"attribute[%d] %s: type1(%d) != type2(%d)",i,name1,type1,type2);
+ HANDLE_DIFF(str)
+ if (attlen1 != attlen2)
+ sprintf(str,"attribute[%d] %s: attlen1(%lld) != attlen2(%lld)",i,name1, attlen1, attlen2);
+ HANDLE_DIFF(str)
+ switch (type1) {
+ case NC_CHAR: CHECK_GLOBAL_ATT_DIFF(char, ncmpi_get_att_text, NC_CHAR)
+ case NC_SHORT: CHECK_GLOBAL_ATT_DIFF(short, ncmpi_get_att_short, NC_SHORT)
+ case NC_INT: CHECK_GLOBAL_ATT_DIFF(int, ncmpi_get_att_int, NC_INT)
+ case NC_FLOAT: CHECK_GLOBAL_ATT_DIFF(float, ncmpi_get_att_float, NC_FLOAT)
+ case NC_DOUBLE: CHECK_GLOBAL_ATT_DIFF(double, ncmpi_get_att_double, NC_DOUBLE)
+ default: ; /* TODO: handle unexpected types */
+ }
+ }
+
+ /* Inquire dimension */
+ for (i=0; i<ndims1; i++) {
+ status = ncmpi_inq_dim(ncid1, i, name1, &dimlen1);
+ HANDLE_ERROR
+ status = ncmpi_inq_dim(ncid2, i, name2, &dimlen2);
+ HANDLE_ERROR
+ if (dimlen1 != dimlen2)
+ sprintf(str,"dimension[%d] %s: dimlen1(%lld) != dimlen2(%lld)",i,name1,dimlen1,dimlen2);
+ HANDLE_DIFF(str)
+ }
+
+ /* Inquire variables */
+ for (i=0; i<nvars1; i++) {
+ status = ncmpi_inq_var(ncid1, i, name1, &type1, &ndims1, dimids1, &natts1);
+ HANDLE_ERROR
+ status = ncmpi_inq_var(ncid2, i, name2, &type2, &ndims2, dimids2, &natts2);
+ HANDLE_ERROR
+ if (strcmp(name1, name2) != 0)
+ sprintf(str,"variable[%d]: name1(%s) != name2(%s)",i,name1,name2);
+ HANDLE_DIFF(str)
+ if (type1 != type2)
+ sprintf(str,"variable[%d] %s: type1(%d) != type2(%d)",i,name1,type1,type2);
+ HANDLE_DIFF(str)
+ if (ndims1 != ndims2)
+ sprintf(str,"variable[%d] %s: ndims1(%d) != ndims2(%d)",i,name1,ndims1,ndims2);
+ HANDLE_DIFF(str)
+ for (j=0; j<ndims1; j++) {
+ if (dimids1[j] != dimids2[j])
+ sprintf(str,"variable[%d] %s: dimids1[%d]=%d != dimids2[%d]=%d",i,name1,j,dimids1[j],j,dimids2[j]);
+ HANDLE_DIFF(str)
+ }
+ if (natts1 != natts2)
+ sprintf(str,"variable[%d] %s: natts1(%d) != natts2(%d)",i,name1,natts1,natts2);
+ HANDLE_DIFF(str)
+
+ strcpy(name,name1);
+
+ /* var attributes, assume CHAR attributes */
+ for (j=0; j<natts1; j++) {
+ status = ncmpi_inq_attname(ncid1, i, j, name1);
+ HANDLE_ERROR
+ status = ncmpi_inq_attname(ncid2, i, j, name2);
+ HANDLE_ERROR
+ if (strcmp(name1, name2) != 0)
+ sprintf(str,"variable[%d] %s: attr name[%d] (%s) != (%s)",i,name,j,name1,name2);
+ HANDLE_DIFF(str)
+
+ status = ncmpi_inq_att(ncid1, i, name1, &type1, &attlen1);
+ HANDLE_ERROR
+ status = ncmpi_inq_att(ncid2, i, name2, &type2, &attlen2);
+ HANDLE_ERROR
+ if (type1 != type2)
+ sprintf(str,"variable[%d] %s: attr type[%d] (%d) != (%d)",i,name,j,type1,type2);
+ HANDLE_DIFF(str)
+ if (attlen1 != attlen2)
+ sprintf(str,"variable[%d] %s: attr attlen[%d] (%lld) != (%lld)",i,name,j, attlen1, attlen2);
+ HANDLE_DIFF(str)
+
+ switch (type1) {
+ case NC_CHAR: CHECK_VAR_ATT_DIFF(char, ncmpi_get_att_text, NC_CHAR)
+ case NC_SHORT: CHECK_VAR_ATT_DIFF(short, ncmpi_get_att_short, NC_SHORT)
+ case NC_INT: CHECK_VAR_ATT_DIFF(int, ncmpi_get_att_int, NC_INT)
+ case NC_FLOAT: CHECK_VAR_ATT_DIFF(float, ncmpi_get_att_float, NC_FLOAT)
+ case NC_DOUBLE: CHECK_VAR_ATT_DIFF(double, ncmpi_get_att_double, NC_DOUBLE)
+ default: ; /* TODO: handle unexpected types */
+ }
+ }
+ }
+
+ /**
+ * Read data of variables from input dataset
+ * (ONLY DEAL WITH: NC_INT, NC_FLOAT, NC_DOUBLE for now)
+ * Write the data out to the corresponding variables in the output dataset
+ *
+ * Data Partition (Assume 4 processors):
+ * square: 2-D, (Block, *), 25*100 from 100*100
+ * cube: 3-D, (Block, *, *), 25*100*100 from 100*100*100
+ * xytime: 3-D, (Block, *, *), 25*100*100 from 100*100*100
+ * time: 1-D, Block-wise, 25 from 100
+ *
+ * Data Mode API: collective
+ */
+
+ for (i=0; i<NC_MAX_VAR_DIMS; i++)
+ start[i] = 0;
+
+ for (i=0; i<nvars1; i++) {
+ varsize = 1;
+ status = ncmpi_inq_var(ncid1, i, name1, &type1, &ndims1, dimids1, &natts1);
+ HANDLE_ERROR
+ strcpy(name,name1);
+ for (j=0; j<ndims1; j++) {
+ status = ncmpi_inq_dim(ncid1, dimids1[j], name2, shape + j);
+ HANDLE_ERROR
+ /* name2 will be discarded */
+ if (j == 0) {
+ shape[j] /= nprocs;
+ start[j] = shape[j] * rank;
+ }
+ varsize *= shape[j];
+ }
+ switch (type1) {
+ case NC_CHAR: CHECK_VAR_DIFF(char, ncmpi_get_vara_text_all, NC_CHAR)
+ case NC_SHORT: CHECK_VAR_DIFF(short, ncmpi_get_vara_short_all, NC_SHORT)
+ case NC_INT: CHECK_VAR_DIFF(int, ncmpi_get_vara_int_all, NC_INT)
+ case NC_FLOAT: CHECK_VAR_DIFF(float, ncmpi_get_vara_float_all, NC_FLOAT)
+ case NC_DOUBLE: CHECK_VAR_DIFF(double, ncmpi_get_vara_double_all, NC_DOUBLE)
+ default: ; /* TODO: handle unexpected types */
+ }
+ }
+
+ status = ncmpi_close(ncid1);
+ HANDLE_ERROR
+ status = ncmpi_close(ncid2);
+ HANDLE_ERROR
+
+ return NC_NOERR;
+}
+
+
+int main(int argc, char **argv)
+{
+ int i, j, array_of_gsizes[3];
+ int nprocs, **buf, rank;
+ MPI_Offset bufcount;
+ int array_of_psizes[3];
+ int status;
+ MPI_Offset array_of_starts[3], stride[3];
+ char basename[256], filename[256];
+ char filename1[256], filename2[256], filename3[256];
+ char dimname[20], varname[20];
+ int ncid, dimids0[3], dimids1[3], rank_dim[3], *varid;
+ MPI_Info info;
+ MPI_Offset **starts, **counts;
+ MPI_Offset *bufcounts;
+ int ndims = 3;
+ int nvars = 10;
+ int k;
+ MPI_Datatype *datatype_list;
+ int length;
+ int *reqs;
+ int *sts;
+ int *buf_var;
+/*
+ int buf_var[32] ={1, 1, 1, 1, 2, 2, 2, 2, 1, 1, 1, 1, 2, 2, 2, 2,
+ 3, 3, 3, 3, 4, 4, 4, 4, 3, 3, 3, 3, 4, 4, 4, 4};
+*/
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+
+ nerrs = 0;
+ verbose = 0;
+ if (argc > 2) {
+ if (!rank) printf("Usage: %s [file base name]\n",argv[0]);
+ MPI_Finalize();
+ return 0;
+ }
+ strcpy(basename, "testfile.nc");
+ if (argc == 2) strcpy(basename, argv[1]);
+ MPI_Bcast(basename, 256, MPI_CHAR, 0, MPI_COMM_WORLD);
+
+ if (rank == 0) {
+ char cmd_str[256];
+ sprintf(cmd_str, "*** TESTING C %s for mput/iput APIs ", argv[0]);
+ printf("%-66s ------ ", cmd_str);
+ }
+
+ length = 2;
+ array_of_gsizes[0] = array_of_gsizes[1] = array_of_gsizes[2] = length;
+
+ nvars = 4;
+
+ buf = (int **)malloc(nvars*sizeof(int*));
+ if (buf == NULL){
+ printf("buf malloc error\n");
+ return 0;
+ }
+ bufcounts = (MPI_Offset *)malloc(nvars*sizeof(MPI_Offset));
+ if (bufcounts == NULL){
+ printf("bufcounts malloc error\n");
+ return 0;
+ }
+ starts = (MPI_Offset **)malloc(nvars*sizeof(MPI_Offset *));
+ if (starts== NULL){
+ printf("starts malloc error\n");
+ return 0;
+ }
+ counts = (MPI_Offset **)malloc(nvars*sizeof(MPI_Offset *));
+ if (counts == NULL){
+ printf("counts malloc error\n");
+ return 0;
+ }
+ datatype_list = (MPI_Datatype*)malloc(nvars*sizeof(MPI_Datatype));
+ if (datatype_list == NULL){
+ printf("counts malloc error\n");
+ return 0;
+ }
+
+ reqs = (int *)malloc(nvars*sizeof(int));
+ sts = (int *)malloc(nvars*sizeof(int));
+
+ for (i=0; i<nvars; i++) {
+ starts[i] = (MPI_Offset *)malloc(ndims*sizeof(MPI_Offset));
+ if (starts[i] == NULL){
+ printf("starts[%d] malloc error\n", i);
+ return 0;
+ }
+ counts[i] = (MPI_Offset *)malloc(ndims*sizeof(MPI_Offset));
+ if (counts[i] == NULL){
+ printf("counts[%d] malloc error\n", i);
+ return 0;
+ }
+ }
+
+ bufcount = 1;
+ for (i=0; i<ndims; i++) {
+ array_of_psizes[i] = 0;
+ bufcount *= length;
+ }
+ MPI_Dims_create(nprocs, ndims, array_of_psizes);
+
+ /* subarray in each process is len x len x len */
+ for (i=0; i<ndims; i++)
+ array_of_gsizes[i] = length * array_of_psizes[i];
+
+ /* mynd's process rank in each dimension (in MPI_ORDER_C) */
+ rank_dim[2] = rank % array_of_psizes[2];
+ rank_dim[1] = (rank / array_of_psizes[2]) % array_of_psizes[1];
+ rank_dim[0] = rank / (array_of_psizes[2] * array_of_psizes[1]);
+
+ /* starting coordinates of the subarray in each dimension */
+ for (i=0; i<ndims; i++)
+ array_of_starts[i] = length * rank_dim[i];
+
+ for (i=0; i<nvars; i++) {
+ for (j=0; j<ndims; j++) {
+ starts[i][j] = array_of_starts[j];
+ counts[i][j] = length;
+ }
+ bufcounts[i] = bufcount;
+ datatype_list[i] = MPI_INT;
+ }
+
+ buf[0] = (int *) malloc(bufcount * nvars * sizeof(int));
+ if (buf[0] == NULL) {
+ printf("buf[i]malloc error\n");
+ return 0;
+ }
+ for (i=1; i<nvars; i++) buf[i] = buf[i-1] + bufcount;
+
+ for (i=0; i<nvars; i++) {
+ for (j=0; j<bufcount; j++)
+ buf[i][j]=rank+1;
+ }
+ buf_var = (int *) malloc(bufcount*nprocs*sizeof(int));
+ for (i=0; i<bufcount*nprocs; i++)
+ buf_var[i] = rank + 1;
+
+ int nvars2 = (nvars > nprocs) ? nvars : nprocs;
+ varid = (int *)malloc(nvars2*sizeof(int));
+ if (varid == NULL){
+ printf("varid malloc error\n");
+ return 0;
+ }
+ MPI_Info_create(&info);
+/*
+ MPI_Info_set(info, "romio_pvfs2_posix_write", "enable");
+ MPI_Info_set(info, "group_cyclic_fd", "enable");
+ MPI_Info_set(info, "cb_buffer_size", "1024");
+ MPI_Info_set(info, "cb_buffer_size", "16777216");
+ MPI_Info_set(info, "romio_no_indep_rw", "true");
+ MPI_Info_set(info, "romio_cb_write", "true");
+ */
+ for (k=0; k<=9; k++){
+ sprintf(filename, "%s.%d.%d.%d.nc", basename, length, nvars, k);
+ if (k==0)
+ strcpy(filename1, filename);
+ else if (k==7)
+ strcpy(filename2, filename);
+ else
+ strcpy(filename3, filename);
+
+ status = ncmpi_create(MPI_COMM_WORLD, filename, NC_CLOBBER|NC_64BIT_OFFSET,
+ info, &ncid);
+ HANDLE_ERROR
+ /* define dimensions */
+ for (i=0; i<ndims; i++){
+ sprintf(dimname, "dim0_%d", i);
+ status = ncmpi_def_dim(ncid, dimname, array_of_gsizes[i], &dimids0[i]);
+ HANDLE_ERROR
+ }
+ sprintf(dimname, "dim1_%d", 0);
+ status = ncmpi_def_dim(ncid, dimname, NC_UNLIMITED, &dimids1[0]);
+ HANDLE_ERROR
+ for (i=1; i<ndims; i++){
+ sprintf(dimname, "dim1_%d", i);
+ status = ncmpi_def_dim(ncid, dimname, array_of_gsizes[i], &dimids1[i]);
+ HANDLE_ERROR
+ }
+
+ /* define variables */
+ if (k<7){
+ for (i=0; i<2; i++){
+ sprintf(varname, "var0_%d", i);
+ status = ncmpi_def_var(ncid, varname, NC_INT, ndims, dimids0, &varid[i]);
+ HANDLE_ERROR
+ }
+ for (i=2; i<nvars; i++){
+ sprintf(varname, "var1_%d", i);
+ status = ncmpi_def_var(ncid, varname, NC_INT, ndims, dimids1, &varid[i]);
+ HANDLE_ERROR
+ }
+ } else {
+ for (i=0; i<nprocs; i++){
+ sprintf(varname, "var0_%d", i);
+ status = ncmpi_def_var(ncid, varname, NC_INT, ndims, dimids0, &varid[i]);
+ HANDLE_ERROR
+ }
+ }
+
+ status = ncmpi_enddef(ncid);
+ HANDLE_ERROR
+
+ if (k == 0) {
+ if (rank == 0 && verbose)
+ printf("*** Testing to write 2 non-record variables and 2 record variables by using ncmpi_put_vara_all() ...");
+ for (i=0; i<nvars; i++){
+ status = ncmpi_put_vara_all(ncid, varid[i], starts[i], counts[i], buf[i], bufcounts[i], MPI_INT);
+ HANDLE_ERROR
+ }
+ }
+
+ if (k == 1) {
+ if (rank == 0 && verbose)
+ printf("*** Testing to write 2 non-record variables and 2 record variables by using ncmpi_put_vara() ...");
+ status = ncmpi_begin_indep_data(ncid);
+ HANDLE_ERROR
+ for (i=0; i<nvars; i++){
+ status = ncmpi_put_vara(ncid, varid[i], starts[i], counts[i], buf[i], bufcounts[i], MPI_INT);
+ HANDLE_ERROR
+ }
+ status = ncmpi_end_indep_data(ncid);
+ HANDLE_ERROR
+ }
+
+ if (k == 2) {
+ if (rank == 0 && verbose)
+ printf("*** Testing to write 2 non-record variables and 2 record variables by using ncmpi_mput_vara_all() ...");
+ status = ncmpi_mput_vara_all(ncid, nvars, varid, starts, counts, (void**)buf, bufcounts, datatype_list);
+ HANDLE_ERROR
+ }
+
+ if (k == 3) {
+ if (rank == 0 && verbose)
+ printf("*** Testing to write 2 non-record variables and 2 record variables by using ncmpi_iput_vara() and ncmpi_wait() ...");
+ status = ncmpi_begin_indep_data(ncid);
+ HANDLE_ERROR
+ for (i=0; i<nvars; i++){
+ status = ncmpi_iput_vara(ncid, varid[i], starts[i], counts[i], buf[i], bufcounts[i], MPI_INT, &reqs[i]);
+ HANDLE_ERROR
+ status = ncmpi_wait(ncid, 1, &reqs[i], &sts[i]);
+ HANDLE_ERROR
+ }
+ status = ncmpi_end_indep_data(ncid);
+ HANDLE_ERROR
+ }
+
+ if (k == 4) {
+ if (rank == 0 && verbose)
+ printf("*** Testing to write 2 non-record variables and 2 record variables by using ncmpi_iput_vara() and ncmpi_wait_all() ...");
+ for (i=0; i<nvars; i++){
+ status = ncmpi_iput_vara(ncid, varid[i], starts[i], counts[i], buf[i], bufcounts[i], MPI_INT, &reqs[i]);
+ HANDLE_ERROR
+ }
+ status = ncmpi_wait_all(ncid, nvars, reqs, sts);
+ HANDLE_ERROR
+ }
+
+ if (k == 5) {
+ if (rank == 0 && verbose)
+ printf("*** Testing to write 2 non-record variables and 2 record variables by using ncmpi_iput_vars() and ncmpi_wait() ...");
+ stride[0] = 1;
+ stride[1] = 1;
+ stride[2] = 1;
+ status = ncmpi_begin_indep_data(ncid);
+ HANDLE_ERROR
+ for (i=0; i<nvars; i++){
+ status = ncmpi_iput_vars(ncid, varid[i], starts[i], counts[i], stride, buf[i], bufcounts[i], MPI_INT, &reqs[i]);
+ HANDLE_ERROR
+ status = ncmpi_wait(ncid, 1, &reqs[i], &sts[i]);
+ HANDLE_ERROR
+ }
+ status = ncmpi_end_indep_data(ncid);
+ HANDLE_ERROR
+ }
+
+ if (k == 6) {
+ if (rank == 0 && verbose)
+ printf("*** Testing to write 2 non-record variables and 2 record variables by using ncmpi_iput_vars() and ncmpi_wait_all() ...");
+ stride[0] = 1;
+ stride[1] = 1;
+ stride[2] = 1;
+ for (i=0; i<nvars; i++){
+ status = ncmpi_iput_vars(ncid, varid[i], starts[i], counts[i], stride, buf[i], bufcounts[i], MPI_INT, &reqs[i]);
+ HANDLE_ERROR
+ }
+ status = ncmpi_wait_all(ncid, nvars, reqs, sts);
+ HANDLE_ERROR
+ }
+ if (k == 7) {
+ if (rank == 0 && verbose)
+ printf("*** Testing to write %d non-record variable(s) by using ncmpi_put_var() ...", nprocs);
+ status = ncmpi_begin_indep_data(ncid);
+ HANDLE_ERROR
+ status = ncmpi_put_var(ncid, varid[rank], buf_var, bufcount*nprocs, MPI_INT);
+ HANDLE_ERROR
+ status = ncmpi_end_indep_data(ncid);
+ HANDLE_ERROR
+ }
+ if (k == 8) {
+ if (rank == 0 && verbose)
+ printf("*** Testing to write %d non-record variable(s) by using ncmpi_iput_var() and ncmpi_wait() ...", nprocs);
+ i = 0;
+ status = ncmpi_iput_var(ncid, varid[rank], buf_var, bufcount*nprocs, MPI_INT, &reqs[i]);
+ HANDLE_ERROR
+ status = ncmpi_begin_indep_data(ncid);
+ HANDLE_ERROR
+ status = ncmpi_wait(ncid, 1, &reqs[i], &sts[i]);
+ HANDLE_ERROR
+ status = ncmpi_end_indep_data(ncid);
+ HANDLE_ERROR
+ }
+ if (k == 9) {
+ if (rank == 0 && verbose)
+ printf("*** Testing to write %d non-record variable(s) by using ncmpi_iput_var() and ncmpi_wait_all() ...", nprocs);
+ status = ncmpi_iput_var(ncid, varid[rank], buf_var, bufcount*nprocs, MPI_INT, &reqs[0]);
+ HANDLE_ERROR
+ status = ncmpi_wait_all(ncid, 1, &reqs[0], &sts[0]);
+ HANDLE_ERROR
+ }
+
+ status = ncmpi_close(ncid);
+ HANDLE_ERROR
+
+ if (status == NC_NOERR){
+ if ((k>0)&&(k<7)){
+ status = ncmpi_diff(filename1, filename3);
+ if (rank == 0 && status == NC_NOERR && verbose)
+ printf("\t OK\n");
+ } else if (k>7){
+/*
+printf("filename2=%s filename3=%s\n",filename2, filename3);
+ status = ncmpi_diff(filename2, filename3);
+ if (rank == 0 && status == NC_NOERR && verbose)
+ printf("\t OK\n");
+*/
+ } else {
+ if (rank == 0 && verbose)
+ printf("\t OK\n");
+ }
+ }
+ }
+
+/*
+ int nkeys;
+ MPI_Info_get_nkeys(info, &nkeys);
+ printf("MPI File Info: nkeys = %d\n",nkeys);
+ for (i=0; i<nkeys; i++) {
+ char key[MPI_MAX_INFO_KEY], value[MPI_MAX_INFO_VAL];
+ int valuelen, flag;
+
+ MPI_Info_get_nthkey(info, i, key);
+ MPI_Info_get_valuelen(info, key, &valuelen, &flag);
+ MPI_Info_get(info, key, valuelen+1, value, &flag);
+ printf("MPI File Info: [%2d] key = %21s, flag = %d, valuelen = %d value = %s\n",
+ i,key,flag,valuelen,value);
+ }
+*/
+
+ MPI_Info_free(&info);
+
+ for (i=0; i<nvars; i++){
+ free(starts[i]);
+ free(counts[i]);
+ }
+ free(buf[0]);
+ free(buf);
+ free(buf_var);
+ free(bufcounts);
+ free(datatype_list);
+ free(reqs);
+ free(sts);
+ free(varid);
+ free(starts);
+ free(counts);
+
+ /* check if PnetCDF freed all internal malloc */
+ MPI_Offset malloc_size, sum_size;
+ int err = ncmpi_inq_malloc_size(&malloc_size);
+ if (err == NC_NOERR) {
+ MPI_Reduce(&malloc_size, &sum_size, 1, MPI_OFFSET, MPI_SUM, 0, MPI_COMM_WORLD);
+ if (rank == 0 && sum_size > 0)
+ printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n",
+ sum_size);
+ }
+
+ MPI_Allreduce(MPI_IN_PLACE, &nerrs, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
+ if (rank == 0) {
+ if (nerrs) printf(FAIL_STR,nerrs);
+ else printf(PASS_STR);
+ }
+
+ MPI_Finalize();
+ return 0;
+}
diff --git a/test/nonblocking/mcoll_testf.f90 b/test/nonblocking/mcoll_testf.f90
new file mode 100644
index 0000000..4bde342
--- /dev/null
+++ b/test/nonblocking/mcoll_testf.f90
@@ -0,0 +1,461 @@
+
+!=============================================================================
+!
+! Note that this code was adapted from fanc/pntf_test.F, which was written by:
+! John Tannahill, LLNL
+!
+! This a multi-variable write test on Fortran.
+!
+! This code writes the array, tt(k)(j)(i), into the file 'testfile.nc'. It
+! then reads the array from the file, and compares it with the original
+! values.
+!
+! i=longitude, j=latitude, k=level
+!
+! $Id: mcoll_testf.f90 2131 2015-09-25 22:33:12Z wkliao $
+!
+!=============================================================================
+
+ program Mcoll_Testf
+
+ use mpi
+ use pnetcdf
+ implicit none
+
+! -----------------------
+! Parameter declarations.
+! -----------------------
+
+ integer NREADS, NWRITES
+ parameter (NREADS = 5, NWRITES = 5 )
+ ! number of read samples
+ ! number of write samples
+ INTEGER(KIND=MPI_OFFSET_KIND) TOTSIZ_3D(3) ! global sizes of 3D field
+
+! ----------------------
+! Variable declarations.
+! ----------------------
+
+ logical reorder
+ logical isperiodic(3)
+ integer comm_cart ! Cartesian communicator
+ integer err, ierr, get_args
+ INTEGER(KIND=MPI_OFFSET_KIND) istart, jstart, kstart ! offsets of 3D field
+ INTEGER(KIND=MPI_OFFSET_KIND) locsiz
+ integer mype ! rank in comm_cart
+ integer totpes ! total number of PEs
+
+ INTEGER(KIND=MPI_OFFSET_KIND) locsiz_3d(3) ! local sizes of 3D fields
+ integer pe_coords(3) ! Cartesian PE coords
+ integer numpes(3) ! number of PEs along axes;
+ ! determined by MPI where a
+ ! zero is specified
+ integer rank, Write_File
+ character(len=256) :: filename, cmd, msg
+
+ real*4 filsiz
+ real*4 rdt_l(2)
+ real*4 wrt_g(2)
+ real*4 wrt_l(2)
+
+ real*4 wrates_g(2)
+ real*4 wrates_l(2)
+
+ data reorder / .false. /
+ data isperiodic / .false., .false., .false. /
+ data numpes / 1, 1, 0 /
+! data TOTSIZ_3D / 256, 256, 256 /
+ data TOTSIZ_3D / 8, 8, 8 /
+
+! ----------------
+! Begin execution.
+! ----------------
+
+ call MPI_Init (ierr)
+ call MPI_Comm_Size(MPI_COMM_WORLD, totpes, ierr)
+ call MPI_Comm_rank(MPI_COMM_WORLD, rank, ierr)
+
+ if (rank .EQ. 0) then
+ filename = 'testfile.nc'
+ err = get_args(cmd, filename)
+ endif
+ call MPI_Bcast(err, 1, MPI_INTEGER, 0, MPI_COMM_WORLD, ierr)
+ if (err .EQ. 0) goto 999
+
+ call MPI_Bcast(filename, 256, MPI_CHARACTER, 0, MPI_COMM_WORLD, ierr)
+
+ call MPI_Dims_Create (totpes, 3, numpes, ierr)
+
+ call MPI_Cart_Create(MPI_COMM_WORLD, 3, numpes, isperiodic, &
+ reorder, comm_cart, ierr)
+
+ call MPI_Comm_Rank (comm_cart, mype, ierr)
+
+ call MPI_Cart_Coords (comm_cart, mype, 3, pe_coords, ierr)
+
+ rdt_l(1) = 1.0e38
+ rdt_l(2) = 1.0e38
+ wrt_l(1) = 1.0e38
+ wrt_l(2) = 1.0e38
+! rdt_l(:) = Huge (rdt_l) ! initialize for timing
+! wrt_l(:) = Huge (wrt_l)
+
+! ----------------------------------------
+! Determine local size for tt (locsiz_3d).
+! ----------------------------------------
+
+! ===============
+ call Find_Locnx(TOTSIZ_3D(1), pe_coords(1), numpes(1), &
+ locsiz_3d(1), istart)
+ call Find_Locnx(TOTSIZ_3D(2), pe_coords(2), numpes(2), &
+ locsiz_3d(2), jstart)
+ call Find_Locnx(TOTSIZ_3D(3), pe_coords(3), numpes(3), &
+ locsiz_3d(3), kstart)
+! ===============
+
+! -------------------------------
+! Compute file size in 1d6 bytes.
+! -------------------------------
+
+ filsiz = real((TOTSIZ_3D(1) * TOTSIZ_3D(2) * TOTSIZ_3D(3)) * &
+ 1.0d-6 * 4.0d0)
+
+! -------------------------------------
+! Print data decomposition information.
+! -------------------------------------
+
+! if (mype == 0) Write (6,900)
+
+ call MPI_Barrier (comm_cart, ierr)
+
+! Write (6, 902)
+! & mype, pe_coords(1), pe_coords(2), pe_coords(3),
+! & TOTSIZ_3D(1), TOTSIZ_3D(2), TOTSIZ_3D(3),
+! & locsiz_3d(1), locsiz_3d(2), locsiz_3d(3),
+! & kstart, jstart, istart
+
+! 900 format ("mype pe_coords totsiz_3d locsiz_3d ",&
+! "kstart,jstart,istart")
+! 902 format (i3,3x,i2,1x,i2,1x,i2,2x,i4,1x,i4,1x,i4,4x,i4,1x,i4,1x, &
+! i4,3x,i6,1x,i6,1x,i6)
+
+! -------------------------
+! Write and then read back.
+! -------------------------
+
+ locsiz = locsiz_3d(1) * locsiz_3d(2) * locsiz_3d(3)
+
+! ===============
+ ierr = Write_File(filename, NWRITES, comm_cart, &
+ istart, jstart, kstart, locsiz, locsiz_3d, &
+ TOTSIZ_3D, wrt_l)
+ if (ierr .NE. NF90_NOERR) then
+ write(6,*) trim(nf90mpi_strerror(ierr))
+ goto 999
+ endif
+!!! Write (6,*) wrt_l(1), wrt_l(2)
+
+! ----------------------------
+! Compute and print I/O rates.
+! ----------------------------
+
+ wrates_l(1) = filsiz / wrt_l(2) ! write rate
+ wrates_l(2) = filsiz / (wrt_l(1) + wrt_l(2)) ! effective write rate
+
+ call MPI_Allreduce(wrates_l, wrates_g, 2, MPI_REAL, MPI_MIN, &
+ comm_cart, ierr)
+ call MPI_Allreduce(wrt_l, wrt_g, 2, MPI_REAL, MPI_MAX, &
+ comm_cart, ierr)
+
+! if (mype == 0) then
+! Write (6,905) filsiz
+! Write (6,910) wrates_g(1), wrates_g(2)
+! end if
+
+! 905 format ("File size: ", e10.3, " MB")
+! 910 format (" Write: ", f9.3, " MB/s (eff., ", f9.3, " MB/s)")
+! 915 format (" Read : ", f9.3, " MB/s (eff., ", f9.3, " MB/s)")
+! 920 format ("Total number PEs: ", i4)
+! 922 format (e11.3, e11.3, f9.3, e11.3, e11.3, f9.3)
+
+ call MPI_Comm_Free (comm_cart, ierr)
+
+ msg = '*** TESTING F90 '//trim(cmd)//' for nf90mpi_iput_var API'
+ if (rank .EQ. 0) call pass_fail(0, msg)
+
+ 999 call MPI_Finalize(ierr)
+
+ end program Mcoll_Testf
+
+! ------------
+
+
+ integer function Write_File(filename, nwrites, comm_cart, &
+ istart, jstart, kstart, locsiz, &
+ locsiz_3d, totsiz_3d, wrt_l)
+
+ use mpi
+ use pnetcdf
+ implicit none
+
+! ----------------------
+! Argument declarations.
+! ----------------------
+
+ character (len=*) filename
+ integer nwrites
+ integer comm_cart
+ INTEGER(KIND=MPI_OFFSET_KIND) istart, jstart, kstart
+ INTEGER(KIND=MPI_OFFSET_KIND) locsiz
+ INTEGER(KIND=MPI_OFFSET_KIND) locsiz_3d(3)
+ INTEGER(KIND=MPI_OFFSET_KIND) totsiz_3d(3)
+ real*4 wrt_l(2)
+
+! ----------------------------
+! Local variable declarations.
+! ----------------------------
+
+ integer ierr, info
+ integer lon_id, lat_id, lev_id
+ integer ncid
+ integer nw
+ integer tt1_id
+ integer req(nwrites)
+ integer stat(nwrites)
+ INTEGER(KIND=MPI_OFFSET_KIND) start_3d(3)
+ INTEGER(KIND=MPI_OFFSET_KIND) count_3d(3)
+ integer dim_id(3)
+ double precision t1, t2, t3
+ integer max_loc_size
+ parameter( max_loc_size = 20000000 )
+ ! real*4 tt1(max_loc_size) ! Need tt(locsiz)
+ real*4, dimension(locsiz_3d(1), locsiz_3d(2), locsiz_3d(3)) :: tt1
+
+ if (locsiz .gt. MAX_LOC_SIZE) then
+ print *, 'locsiz = ', locsiz, ' larger than MAX_LOC_SIZE'
+ stop
+ endif
+! ----------------
+! Begin execution.
+! ----------------
+
+! start_3d(1:3) = (/ kstart, jstart, istart /)
+! count_3d(:) = locsiz_3d(:)
+ start_3d(1) = istart
+ start_3d(2) = jstart
+ start_3d(3) = kstart
+ count_3d(1) = locsiz_3d(1)
+ count_3d(2) = locsiz_3d(2)
+ count_3d(3) = locsiz_3d(3)
+
+! ==============
+ call Get_Field(istart, jstart, kstart, locsiz_3d, &
+ totsiz_3d, tt1)
+
+ call MPI_Barrier (comm_cart, ierr)
+ t1 = MPI_Wtime ( )
+
+! =================
+ call MPI_Info_create(info, ierr)
+ ! call MPI_Info_set(info, "romio_pvfs2_posix_write","enable",ierr)
+
+ Write_File = nf90mpi_create(comm_cart, filename, NF90_CLOBBER, &
+ info, ncid)
+ if (Write_File .NE. NF90_NOERR) return
+
+ call MPI_Info_free(info, ierr)
+
+! ==================
+ Write_File = nf90mpi_def_dim(ncid, "level", totsiz_3d(1)*nwrites, &
+ lon_id)
+ if (Write_File .NE. NF90_NOERR) return
+ Write_File = nf90mpi_def_dim(ncid, "latitude", totsiz_3d(2), lat_id)
+ if (Write_File .NE. NF90_NOERR) return
+ Write_File = nf90mpi_def_dim(ncid, "longitude", totsiz_3d(3), lev_id)
+ if (Write_File .NE. NF90_NOERR) return
+! ==================
+
+ dim_id(1) = lon_id
+ dim_id(2) = lat_id
+ dim_id(3) = lev_id
+
+! ==================
+ Write_File = nf90mpi_def_var(ncid, "tt1", NF90_REAL, dim_id, tt1_id)
+ if (Write_File .NE. NF90_NOERR) return
+
+! =================
+ Write_File = nf90mpi_enddef (ncid)
+ if (Write_File .NE. NF90_NOERR) return
+! =================
+
+ t2 = MPI_Wtime ( )
+
+ do nw = 1, nwrites
+ Write_File = nf90mpi_iput_var(ncid, tt1_id, tt1, req(nw), &
+ start_3d, count_3d)
+ if (Write_File .NE. NF90_NOERR) return
+
+ start_3d(1) = start_3d(1) + count_3d(1)
+ end do
+
+ Write_File = nf90mpi_wait_all(ncid, nwrites, req, stat)
+ if (Write_File .NE. NF90_NOERR) return
+
+! ================
+ Write_File = nf90mpi_close (ncid)
+ if (Write_File .NE. NF90_NOERR) return
+! ================
+
+! 900 format ("mynod:", i1, " reqid : ", i1)
+
+ call MPI_Barrier (comm_cart, ierr)
+ t3 = MPI_Wtime ( )
+
+ if (t2 - t1 < wrt_l(1)) wrt_l(1) = real(t2 - t1)
+ if (t3 - t2 < wrt_l(2)) wrt_l(2) = real(t3 - t2)
+
+ end
+
+! ------------
+
+ subroutine Find_Locnx(nx, mype, totpes, locnx, ibegin)
+
+ use mpi
+ implicit none
+
+! ----------------------
+! Argument declarations.
+! ----------------------
+
+ INTEGER(KIND=MPI_OFFSET_KIND) nx
+ integer mype
+ integer totpes
+ INTEGER(KIND=MPI_OFFSET_KIND) locnx
+ INTEGER(KIND=MPI_OFFSET_KIND) ibegin
+
+! ----------------------------
+! Local variable declarations.
+! ----------------------------
+
+ INTEGER(KIND=MPI_OFFSET_KIND) iremain
+
+! ----------------
+! Begin execution.
+! ----------------
+
+ locnx = nx / totpes
+
+ iremain = nx - (totpes * locnx)
+
+ if (mype < iremain) locnx = locnx + 1
+
+ ibegin = mype * (nx / totpes) + iremain + 1
+
+ if (mype < iremain) ibegin = ibegin + (mype - iremain)
+
+ end
+
+! ------------
+
+ subroutine Get_Field(istart, jstart, kstart, locsiz_3d, &
+ totsiz_3d, tt)
+
+ use mpi
+ implicit none
+
+! ----------------------
+! Argument declarations.
+! ----------------------
+
+ INTEGER(KIND=MPI_OFFSET_KIND) istart, jstart, kstart
+ INTEGER(KIND=MPI_OFFSET_KIND) locsiz_3d(3)
+ INTEGER(KIND=MPI_OFFSET_KIND) totsiz_3d(3)
+ real*4, dimension(locsiz_3d(1),locsiz_3d(2),locsiz_3d(3)) ::tt
+
+! ----------------------------
+! Local variable declarations.
+! ----------------------------
+
+ integer ii, jj, kk
+ integer ind
+
+! ----------------
+! Begin execution.
+! ----------------
+
+ ind = 1
+
+ do kk = 1, int(locsiz_3d(3))
+ do jj = 1, int(locsiz_3d(2))
+ do ii = 1, int(locsiz_3d(1))
+
+ tt(ii,jj,kk) = real( &
+ (istart-1 +(ii - 1) + 1 + totsiz_3d(3)*(jstart-1 + &
+ (jj - 1) + totsiz_3d(2)*(kstart-1 + &
+ (kk-1)))) * 1.0d-3)
+ ind = ind + 1
+
+ end do
+ end do
+ end do
+
+ end
+
+! ------------
+
+ subroutine Compare_Vec(comm_cart, locsiz, tt, buf)
+
+ use mpi
+ implicit none
+
+! ----------------------
+! Argument declarations.
+! ----------------------
+
+ integer comm_cart
+ INTEGER(KIND=MPI_OFFSET_KIND) locsiz
+ real*4 tt (locsiz)
+ real*4 buf(locsiz)
+
+! ----------------------------
+! Local variable declarations.
+! ----------------------------
+
+ integer ierr
+ integer ii
+ real*4 delmax(1), delmin(1), delta
+ real*4 diff
+ real*4 wr(5)
+ real*4 ws(5)
+
+! ----------------
+! Begin execution.
+! ----------------
+
+ ws(1) = 0.0d0 ! diff
+ ws(2) = 0.0d0 ! sumsq
+ ws(3) = real(locsiz) ! locsiz
+ ws(4) = 0.0d0 ! delmax
+ ws(5) = 1.0d38 ! Huge (ws) ! delmin
+
+ do ii = 1, int(locsiz)
+ delta = (tt(ii) - buf(ii)) * (tt(ii) - buf(ii))
+ ws(1) = ws(1) + delta
+ ws(2) = ws(2) + tt(ii) * tt(ii)
+ if (delta > ws(4)) ws(4) = delta
+ if (delta < ws(5)) ws(5) = delta
+ end do
+
+ call MPI_Allreduce(ws, wr, 3, MPI_REAL, MPI_SUM, &
+ comm_cart, ierr)
+ call MPI_Allreduce(ws(4), delmax, 1, MPI_REAL, MPI_MAX, &
+ comm_cart, ierr)
+ call MPI_Allreduce(ws(5), delmin(1), 1, MPI_REAL, MPI_MIN, &
+ comm_cart, ierr)
+
+ diff = Sqrt (wr(1) / wr(2)) ! normalized error
+ delmax(1) = Sqrt (wr(3) * delmax(1)/wr(2)) ! normalized max difference
+ delmin(1) = Sqrt (wr(3) * delmin(1)/wr(2)) ! normalized min difference
+
+ end
+
diff --git a/test/nonblocking/mcoll_testf77.f b/test/nonblocking/mcoll_testf77.f
new file mode 100644
index 0000000..c4cbe35
--- /dev/null
+++ b/test/nonblocking/mcoll_testf77.f
@@ -0,0 +1,521 @@
+!
+! Copyright (C) 2012, Northwestern University and Argonne National Lab
+! See COPYRIGHT notice in top-level directory.
+!
+! Note that this code was adapted from fanc/pntf_test.F, which was written by:
+! John Tannahill, LLNL
+!
+! This a multi-variable write test on Fortran.
+!
+! This code writes the array, tt(k)(j)(i), into the file 'testfile.nc'. It
+! then reads the array from the file, and compares it with the original
+! values.
+!
+! i=longitude, j=latitude, k=level
+!
+! $Id: mcoll_testf77.f 2224 2015-12-16 06:10:36Z wkliao $
+!
+!=============================================================================
+
+ INTEGER FUNCTION XTRIM(STRING)
+ CHARACTER*(*) STRING
+ INTEGER I, N
+ N = LEN(STRING)
+ DO I = N, 1, -1
+ IF (STRING(I:I) .NE. ' ') GOTO 10
+ ENDDO
+ 10 XTRIM = I
+ END ! FUNCTION XTRIM
+
+ program Mcoll_Testf
+
+ implicit none
+ include "mpif.h"
+ include "pnetcdf.inc"
+
+! -----------------------
+! Parameter declarations.
+! -----------------------
+
+ integer XTRIM
+ integer NWRITES
+ parameter (NWRITES = 5 )
+ ! number of read samples
+ ! number of write samples
+
+ integer*8 TOTSIZ_3D(3) ! global sizes of 3D field
+
+
+! ----------------------
+! Variable declarations.
+! ----------------------
+
+ logical reorder
+
+ logical isperiodic(3)
+
+ integer comm_cart ! Cartesian communicator
+ integer err, ierr, get_args
+ integer*8 istart, jstart, kstart ! offsets of 3D field
+ integer*8 locsiz
+ integer mype ! rank in comm_cart
+ integer totpes ! total number of PEs
+
+ integer*8 locsiz_3d(3) ! local sizes of 3D fields
+ integer pe_coords(3) ! Cartesian PE coords
+
+ integer numpes(3) ! number of PEs along axes;
+ ! determined by MPI where a
+ ! zero is specified
+
+ integer rank, Write_File
+ character*256 filename, cmd, msg
+
+ real*4 filsiz
+
+ real*4 rdt_l(2)
+ real*4 wrt_g(2)
+ real*4 wrt_l(2)
+
+ real*4 wrates_g(2)
+ real*4 wrates_l(2)
+
+
+ data reorder / .false. /
+ data isperiodic / .false., .false., .false. /
+ data numpes / 1, 1, 0 /
+! data TOTSIZ_3D / 256, 256, 256 /
+ data TOTSIZ_3D / 8, 8, 8 /
+
+! ----------------
+! Begin execution.
+! ----------------
+
+ call MPI_Init (ierr)
+ call MPI_Comm_Size(MPI_COMM_WORLD, totpes, ierr)
+ call MPI_Comm_rank(MPI_COMM_WORLD, rank, ierr)
+
+ if (rank .EQ. 0) then
+ filename = "testfile.nc"
+ err = get_args(cmd, filename)
+ endif
+ call MPI_Bcast(err, 1, MPI_INTEGER, 0, MPI_COMM_WORLD, ierr)
+ if (err .EQ. 0) goto 999
+
+ call MPI_Bcast(filename, 256, MPI_CHARACTER, 0, MPI_COMM_WORLD,
+ + ierr)
+
+ call MPI_Dims_Create (totpes, 3, numpes, ierr)
+
+ call MPI_Cart_Create(MPI_COMM_WORLD, 3, numpes, isperiodic,
+ + reorder, comm_cart, ierr)
+
+ call MPI_Comm_Rank (comm_cart, mype, ierr)
+
+ call MPI_Cart_Coords (comm_cart, mype, 3, pe_coords, ierr)
+
+
+ rdt_l(1) = 1.0e38
+ rdt_l(2) = 1.0e38
+ wrt_l(1) = 1.0e38
+ wrt_l(2) = 1.0e38
+! rdt_l(:) = Huge (rdt_l) ! initialize for timing
+! wrt_l(:) = Huge (wrt_l)
+
+! ----------------------------------------
+! Determine local size for tt (locsiz_3d).
+! ----------------------------------------
+
+! ===============
+ call Find_Locnx(TOTSIZ_3D(1), pe_coords(1), numpes(1),
+ + locsiz_3d(1), istart)
+ call Find_Locnx(TOTSIZ_3D(2), pe_coords(2), numpes(2),
+ + locsiz_3d(2), jstart)
+ call Find_Locnx(TOTSIZ_3D(3), pe_coords(3), numpes(3),
+ + locsiz_3d(3), kstart)
+! ===============
+
+! -------------------------------
+! Compute file size in 1d6 bytes.
+! -------------------------------
+
+ filsiz = real((TOTSIZ_3D(1) * TOTSIZ_3D(2) * TOTSIZ_3D(3)) *
+ + 1.0d-6 * 4.0d0)
+
+! -------------------------------------
+! Print data decomposition information.
+! -------------------------------------
+
+! if (mype == 0) Write (6,900)
+
+ call MPI_Barrier (comm_cart, ierr)
+
+! Write (6, 902)
+! & mype, pe_coords(1), pe_coords(2), pe_coords(3),
+! & TOTSIZ_3D(1), TOTSIZ_3D(2), TOTSIZ_3D(3),
+! & locsiz_3d(1), locsiz_3d(2), locsiz_3d(3),
+! & kstart, jstart, istart
+
+! 900 format ("mype pe_coords totsiz_3d locsiz_3d ",
+! + "kstart,jstart,istart")
+! 902 format (i3,3x,i2,1x,i2,1x,i2,2x,i4,1x,i4,1x,i4,4x,i4,1x,i4,1x,
+! + i4,3x,i6,1x,i6,1x,i6)
+
+
+! -------------------------
+! Write and then read back.
+! -------------------------
+
+ locsiz = locsiz_3d(1) * locsiz_3d(2) * locsiz_3d(3)
+
+! ===============
+ ierr = Write_File(filename, NWRITES, comm_cart,
+ + istart, jstart, kstart, locsiz, locsiz_3d,
+ + TOTSIZ_3D, wrt_l)
+ if (ierr .NE. NF_NOERR) then
+ write(6,*) nfmpi_strerror(ierr)
+ goto 999
+ endif
+!!! Write (6,*) wrt_l(1), wrt_l(2)
+
+! ----------------------------
+! Compute and print I/O rates.
+! ----------------------------
+
+ wrates_l(1) = filsiz / wrt_l(2) ! write rate
+ wrates_l(2) = filsiz / (wrt_l(1) + wrt_l(2)) ! effective write rate
+
+ call MPI_Allreduce(wrates_l, wrates_g, 2, MPI_REAL, MPI_MIN,
+ + comm_cart, ierr)
+ call MPI_Allreduce(wrt_l, wrt_g, 2, MPI_REAL, MPI_MAX,
+ + comm_cart, ierr)
+
+! if (mype == 0) then
+! Write (6,905) filsiz
+! Write (6,910) wrates_g(1), wrates_g(2)
+! end if
+
+! 905 format ("File size: ", e10.3, " MB")
+! 910 format (" Write: ", f9.3, " MB/s (eff., ", f9.3, " MB/s)")
+! 915 format (" Read : ", f9.3, " MB/s (eff., ", f9.3, " MB/s)")
+! 920 format ("Total number PEs: ", i4)
+! 922 format (e11.3, e11.3, f9.3, e11.3, e11.3, f9.3)
+
+
+ call MPI_Comm_Free (comm_cart, ierr)
+
+ msg = '*** TESTING F77 '//cmd(1:XTRIM(cmd))//' for iput API'
+ if (rank .EQ. 0) call pass_fail(0, msg)
+
+ 999 call MPI_Finalize (ierr)
+
+ end ! program Mcoll_Testf
+
+
+! ------------
+
+
+ integer function Write_File(filename, nwrites, comm_cart,
+ + istart, jstart, kstart, locsiz,
+ + locsiz_3d, totsiz_3d, wrt_l)
+
+ implicit none
+ include "mpif.h"
+ include "pnetcdf.inc"
+
+! ----------------------
+! Argument declarations.
+! ----------------------
+
+ character*(*) filename
+ integer nwrites
+ integer comm_cart
+ integer*8 istart, jstart, kstart
+ integer*8 locsiz
+ integer*8 locsiz_3d(3)
+ integer*8 totsiz_3d(3)
+ real*4 wrt_l(2)
+
+! ----------------------------
+! Local variable declarations.
+! ----------------------------
+
+ integer ierr, info
+ integer lon_id, lat_id, lev_id
+ integer ncid
+ integer nw
+ integer tt1_id
+ integer req1
+ integer req(nwrites)
+ integer stat(nwrites)
+
+ integer*8 count_3d(3)
+ integer*8 start_3d(3)
+
+ integer dim_id(3)
+
+ double precision t1, t2, t3
+
+ integer max_loc_size
+ parameter( max_loc_size = 20000000 )
+ real*4 tt1(max_loc_size) ! Need tt(locsiz)
+
+
+ if (locsiz .gt. MAX_LOC_SIZE) then
+ print *, 'locsiz = ', locsiz, ' larger than MAX_LOC_SIZE'
+ stop
+ endif
+! ----------------
+! Begin execution.
+! ----------------
+
+! start_3d(1:3) = (/ kstart, jstart, istart /)
+! count_3d(:) = locsiz_3d(:)
+ start_3d(1) = istart
+ start_3d(2) = jstart
+ start_3d(3) = kstart
+ count_3d(1) = locsiz_3d(1)
+ count_3d(2) = locsiz_3d(2)
+ count_3d(3) = locsiz_3d(3)
+
+! ==============
+ call Get_Field(istart, jstart, kstart, locsiz, locsiz_3d,
+ + totsiz_3d, tt1)
+
+ call MPI_Barrier (comm_cart, ierr)
+ t1 = MPI_Wtime ( )
+
+! =================
+ call MPI_Info_create(info, ierr)
+ ! call MPI_Info_set(info, "romio_pvfs2_posix_write", "enable",ierr)
+
+ Write_File = nfmpi_create(comm_cart, filename, NF_CLOBBER,
+ + info, ncid)
+ if (Write_File .NE. NF_NOERR) return
+
+ call MPI_Info_free(info, ierr)
+
+! ==================
+ Write_File = nfmpi_def_dim(ncid, "level",
+ + totsiz_3d(1)*nwrites, lon_id)
+ if (Write_File .NE. NF_NOERR) return
+ Write_File = nfmpi_def_dim(ncid, "latitude", totsiz_3d(2),
+ + lat_id)
+ if (Write_File .NE. NF_NOERR) return
+ Write_File = nfmpi_def_dim(ncid, "longitude", totsiz_3d(3),
+ + lev_id)
+ if (Write_File .NE. NF_NOERR) return
+! ==================
+
+ dim_id(1) = lon_id
+ dim_id(2) = lat_id
+ dim_id(3) = lev_id
+
+! ==================
+ Write_File = nfmpi_def_var(ncid, "tt1", NF_REAL, 3, dim_id,
+ + tt1_id)
+ if (Write_File .NE. NF_NOERR) return
+
+! =================
+ Write_File = nfmpi_enddef (ncid)
+ if (Write_File .NE. NF_NOERR) return
+! =================
+
+ t2 = MPI_Wtime ( )
+
+ do nw = 1, nwrites
+
+ Write_File = nfmpi_iput_vara_real(ncid, tt1_id, start_3d,
+ + count_3d, tt1, req1)
+ if (Write_File .NE. NF_NOERR) return
+ req(nw)=req1
+
+ start_3d(1) = start_3d(1) + count_3d(1)
+ end do
+
+ Write_File = nfmpi_wait_all(ncid, nwrites, req, stat)
+ if (Write_File .NE. NF_NOERR) return
+
+! ================
+ Write_File = nfmpi_close (ncid)
+ if (Write_File .NE. NF_NOERR) return
+! ================
+
+! 900 format ("mynod:", i1, " reqid : ", i1)
+
+
+ call MPI_Barrier (comm_cart, ierr)
+ t3 = MPI_Wtime ( )
+
+
+ if (t2 - t1 .LT. wrt_l(1)) wrt_l(1) = real(t2 - t1)
+ if (t3 - t2 .LT. wrt_l(2)) wrt_l(2) = real(t3 - t2)
+
+ Return
+
+ end
+
+
+! ------------
+
+ subroutine Find_Locnx(nx, mype, totpes, locnx, ibegin)
+
+ implicit none
+ include "mpif.h"
+
+! ----------------------
+! Argument declarations.
+! ----------------------
+
+ integer*8 nx
+ integer mype
+ integer totpes
+ integer*8 locnx
+ integer*8 ibegin
+
+! ----------------------------
+! Local variable declarations.
+! ----------------------------
+
+ integer*8 iremain
+
+! ----------------
+! Begin execution.
+! ----------------
+
+ locnx = nx / totpes
+
+ iremain = nx - (totpes * locnx)
+
+ if (mype .LT. iremain) locnx = locnx + 1
+
+ ibegin = mype * (nx / totpes) + iremain + 1
+
+ if (mype .LT. iremain) ibegin = ibegin + (mype - iremain)
+
+ Return
+
+ end
+
+
+! ------------
+
+
+ subroutine Get_Field(istart, jstart, kstart, locsiz, locsiz_3d,
+ + totsiz_3d, tt)
+
+ implicit none
+ include "mpif.h"
+
+! ----------------------
+! Argument declarations.
+! ----------------------
+
+ integer*8 istart, jstart, kstart
+ integer*8 locsiz
+ integer*8 locsiz_3d(3)
+ integer*8 totsiz_3d(3)
+ real*4 tt(locsiz)
+
+! ----------------------------
+! Local variable declarations.
+! ----------------------------
+
+ integer ii, jj, kk
+ integer ind
+
+! ----------------
+! Begin execution.
+! ----------------
+
+ ind = 1
+
+
+ do kk = 1, int(locsiz_3d(3))
+ do jj = 1, int(locsiz_3d(2))
+ do ii = 1, int(locsiz_3d(1))
+
+ tt(ind) = real(
+ + (istart-1 +(ii - 1) + 1 + totsiz_3d(3)*(jstart-1 +
+ + (jj - 1) + totsiz_3d(2)*(kstart-1 +
+ + (kk-1)))) * 1.0d-3)
+ ind = ind + 1
+
+ end do
+ end do
+ end do
+
+
+ Return
+
+ end
+
+
+! ------------
+
+
+ subroutine Compare_Vec(comm_cart, locsiz, tt, buf)
+
+ implicit none
+ include "mpif.h"
+
+! ----------------------
+! Argument declarations.
+! ----------------------
+
+ integer comm_cart
+ integer*8 locsiz
+ real*4 tt (locsiz)
+ real*4 buf(locsiz)
+
+
+! ----------------------------
+! Local variable declarations.
+! ----------------------------
+
+ integer ierr
+ integer ii
+
+ real*4 delmax(1), delmin(1), delta
+ real*4 diff
+
+ real*4 wr(5)
+ real*4 ws(5)
+
+
+! ----------------
+! Begin execution.
+! ----------------
+
+ ws(1) = 0.0d0 ! diff
+ ws(2) = 0.0d0 ! sumsq
+ ws(3) = real(locsiz) ! locsiz
+ ws(4) = 0.0d0 ! delmax
+ ws(5) = 1.0d38 ! Huge (ws) ! delmin
+
+
+ do ii = 1, int(locsiz)
+ delta = (tt(ii) - buf(ii)) * (tt(ii) - buf(ii))
+ ws(1) = ws(1) + delta
+ ws(2) = ws(2) + tt(ii) * tt(ii)
+ if (delta .GT. ws(4)) ws(4) = delta
+ if (delta .LT. ws(5)) ws(5) = delta
+ end do
+
+
+ call MPI_Allreduce(ws, wr, 3, MPI_REAL, MPI_SUM,
+ + comm_cart, ierr)
+ call MPI_Allreduce(ws(4), delmax, 1, MPI_REAL, MPI_MAX,
+ + comm_cart, ierr)
+ call MPI_Allreduce(ws(5), delmin, 1, MPI_REAL, MPI_MIN,
+ + comm_cart, ierr)
+
+ diff = Sqrt (wr(1) / wr(2)) ! normalized error
+ delmax(1) = Sqrt (wr(3) * delmax(1)/wr(2)) ! normalized max difference
+ delmin(1) = Sqrt (wr(3) * delmin(1)/wr(2)) ! normalized min difference
+
+
+ Return
+
+ end
+
diff --git a/test/nonblocking/req_all.c b/test/nonblocking/req_all.c
new file mode 100644
index 0000000..6407792
--- /dev/null
+++ b/test/nonblocking/req_all.c
@@ -0,0 +1,157 @@
+/*********************************************************************
+ *
+ * Copyright (C) 2015, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ *
+ *********************************************************************/
+/* $Id$ */
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * This example shows how to use NC_REQ_ALL in nonblocking I/O operations.
+ * The program writes 2 arrays by calling the nonblocking APIs with NULLs for
+ * argument request ID. When calling ncmpi_wait_all(), NC_REQ_ALL is used to
+ * commit all the pending requests without checking the individual statuses of
+ * the requests.
+ *
+ * To compile:
+ * mpicc -O2 req_all.c -o req_all -lpnetcdf
+ *
+ * Example commands for MPI run and outputs from running ncmpidump on the
+ * NC file produced by this example program:
+ *
+ * % mpiexec -n 4 ./req_all /pvfs2/wkliao/testfile.nc
+ *
+ * % ncmpidump /pvfs2/wkliao/testfile.nc
+ * netcdf testfile {
+ * dimensions:
+ * Y = 8 ;
+ * X = 8 ;
+ * variables:
+ * int var_int(Y, X) ;
+ * float var_flt(Y, X) ;
+ * data:
+ *
+ * var_int =
+ * 0, 0, 1, 1, 2, 2, 3, 3,
+ * 0, 0, 1, 1, 2, 2, 3, 3,
+ * 0, 0, 1, 1, 2, 2, 3, 3,
+ * 0, 0, 1, 1, 2, 2, 3, 3,
+ * 0, 0, 1, 1, 2, 2, 3, 3,
+ * 0, 0, 1, 1, 2, 2, 3, 3,
+ * 0, 0, 1, 1, 2, 2, 3, 3,
+ * 0, 0, 1, 1, 2, 2, 3, 3 ;
+ *
+ * var_flt =
+ * 0.1, 0.1, 1.1, 1.1, 2.1, 2.1, 3.1, 3.1,
+ * 0.1, 0.1, 1.1, 1.1, 2.1, 2.1, 3.1, 3.1,
+ * 0.1, 0.1, 1.1, 1.1, 2.1, 2.1, 3.1, 3.1,
+ * 0.1, 0.1, 1.1, 1.1, 2.1, 2.1, 3.1, 3.1,
+ * 0.1, 0.1, 1.1, 1.1, 2.1, 2.1, 3.1, 3.1,
+ * 0.1, 0.1, 1.1, 1.1, 2.1, 2.1, 3.1, 3.1,
+ * 0.1, 0.1, 1.1, 1.1, 2.1, 2.1, 3.1, 3.1,
+ * 0.1, 0.1, 1.1, 1.1, 2.1, 2.1, 3.1, 3.1 ;
+ * }
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <mpi.h>
+#include <pnetcdf.h>
+
+#include <testutils.h>
+
+#define NY 8
+#define NX 2
+
+#define ERR {if(err!=NC_NOERR) {printf("Error at line=%d: %s\n", __LINE__, ncmpi_strerror(err)); nerrs++;}}
+
+int main(int argc, char** argv)
+{
+ char filename[256];
+ int i, j, rank, nprocs, nerrs=0, err;
+ int ncid, cmode, varid[2], dimid[2], buf_int[NY][NX];
+ float buf_flt[NY][NX];
+ MPI_Offset global_ny, global_nx;
+ MPI_Offset start[2], count[2];
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+
+ if (argc > 2) {
+ if (!rank) printf("Usage: %s [filename]\n",argv[0]);
+ MPI_Finalize();
+ return 0;
+ }
+ strcpy(filename, "testfile.nc");
+ if (argc == 2) strcpy(filename, argv[1]);
+ MPI_Bcast(filename, 256, MPI_CHAR, 0, MPI_COMM_WORLD);
+
+ if (rank == 0) {
+ char cmd_str[256];
+ sprintf(cmd_str, "*** TESTING C %s for NC_REQ_ALL ", argv[0]);
+ printf("%-66s ------ ", cmd_str);
+ }
+
+ /* create a new file for writing ----------------------------------------*/
+ cmode = NC_CLOBBER;
+ err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, MPI_INFO_NULL, &ncid); ERR
+
+ /* the global array is NY * (NX * nprocs) */
+ global_ny = NY;
+ global_nx = NX * nprocs;
+
+ for (i=0; i<NY; i++)
+ for (j=0; j<NX; j++) {
+ buf_int[i][j] = rank;
+ buf_flt[i][j] = 0.1 + rank;
+ }
+
+ /* define dimensions x and y */
+ err = ncmpi_def_dim(ncid, "Y", global_ny, &dimid[0]); ERR
+ err = ncmpi_def_dim(ncid, "X", global_nx, &dimid[1]); ERR
+
+ /* define a 2D variable of integer type */
+ err = ncmpi_def_var(ncid, "var_int", NC_INT, 2, dimid, &varid[0]); ERR
+
+ /* define a 2D variable of float type */
+ err = ncmpi_def_var(ncid, "var_flt", NC_FLOAT, 2, dimid, &varid[1]); ERR
+
+ /* do not forget to exit define mode */
+ err = ncmpi_enddef(ncid); ERR
+
+ /* now we are in data mode */
+ start[0] = 0;
+ start[1] = NX * rank;
+ count[0] = NY;
+ count[1] = NX;
+
+ err = ncmpi_iput_vara_int(ncid, varid[0], start, count, &buf_int[0][0], NULL); ERR
+ err = ncmpi_iput_vara_float(ncid, varid[1], start, count, &buf_flt[0][0], NULL); ERR
+
+ err = ncmpi_wait_all(ncid, NC_REQ_ALL, NULL, NULL); ERR
+
+ err = ncmpi_close(ncid);
+ ERR
+
+ /* check if there is any PnetCDF internal malloc residue */
+ MPI_Offset malloc_size, sum_size;
+ err = ncmpi_inq_malloc_size(&malloc_size);
+ if (err == NC_NOERR) {
+ MPI_Reduce(&malloc_size, &sum_size, 1, MPI_OFFSET, MPI_SUM, 0, MPI_COMM_WORLD);
+ if (rank == 0 && sum_size > 0)
+ printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n",
+ sum_size);
+ }
+
+ MPI_Allreduce(MPI_IN_PLACE, &nerrs, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
+ if (rank == 0) {
+ if (nerrs) printf(FAIL_STR,nerrs);
+ else printf(PASS_STR);
+ }
+
+ MPI_Finalize();
+ return 0;
+}
+
diff --git a/test/nonblocking/test_bput.c b/test/nonblocking/test_bput.c
new file mode 100644
index 0000000..2660132
--- /dev/null
+++ b/test/nonblocking/test_bput.c
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2012, Northwestern University
+ * See COPYRIGHT notice in top-level directory.
+ *
+ * $Id: test_bput.c 2133 2015-09-26 19:16:01Z wkliao $
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <pnetcdf.h>
+
+#include <testutils.h>
+
+#define FILE_NAME "testfile.nc"
+
+#define ERR if (err!=NC_NOERR) {printf("Error at line %d: err=%d %s\n", __LINE__, err, ncmpi_strerror(err)); nerrs++;}
+
+/*----< main() >------------------------------------------------------------*/
+int main(int argc, char **argv) {
+ int i, j, ncid, dimid[2], varid, err, nerrs=0, rank, nprocs, verbose;
+ int req[2], status[2];
+ float var[4][6];
+ char *filename="testfile.nc";
+ MPI_Offset bufsize, start[2], count[2], stride[2], imap[2];
+ MPI_Info info;
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+
+ verbose = 0;
+ if (nprocs > 1 && rank == 0 && verbose)
+ printf("Warning: %s is designed to run on 1 process\n", argv[0]);
+
+ if (argc > 2) {
+ if (!rank) printf("Usage: %s [filename]\n",argv[0]);
+ MPI_Finalize();
+ return 0;
+ }
+ if (argc == 2) filename = argv[1];
+
+ if (rank == 0) {
+ char cmd_str[256];
+ sprintf(cmd_str, "*** TESTING C %s for bput API ", argv[0]);
+ printf("%-66s ------ ", cmd_str);
+ }
+
+ MPI_Info_create(&info);
+ /* MPI_Info_set(info, "romio_pvfs2_posix_write","enable"); */
+
+ err = ncmpi_create(MPI_COMM_WORLD, filename, NC_CLOBBER | NC_64BIT_DATA, info, &ncid); ERR
+ MPI_Info_free(&info);
+
+ /* define a variable of a 6 x 4 integer array in the nc file */
+ err = ncmpi_def_dim(ncid, "Y", 6, &dimid[0]); ERR
+ err = ncmpi_def_dim(ncid, "X", 4, &dimid[1]); ERR
+ err = ncmpi_def_var(ncid, "var", NC_INT64, 2, dimid, &varid); ERR
+ err = ncmpi_enddef(ncid); ERR
+
+ /* set the contents of the write buffer var, a 4 x 6 float array
+ 50, 51, 52, 53, 54, 55,
+ 56, 57, 58, 59, 60, 61,
+ 62, 63, 64, 65, 66, 67,
+ 68, 69, 70, 71, 72, 73
+ */
+ for (j=0; j<4; j++) for (i=0; i<6; i++) var[j][i] = j*6+i + 50;
+
+ /* bufsize must be max of data type converted before and after */
+ bufsize = 4*6*sizeof(long long);
+ err = ncmpi_buffer_attach(ncid, bufsize); ERR
+
+ /* write var to the NC variable in the matrix transposed way */
+ count[0] = 6; count[1] = 2;
+ stride[0] = 1; stride[1] = 1;
+ imap[0] = 1; imap[1] = 6; /* would be {4, 1} if not transposing */
+
+ if (rank > 0) /* non-root processes just participate the call */
+ count[0] = count[1] = 0;
+
+ /* write the first two columns of the NC variable in the matrix transposed way */
+ start[0] = 0; start[1] = 0;
+ err = ncmpi_bput_varm_float(ncid, varid, start, count, stride, imap, &var[0][0], &req[0]); ERR
+
+ /* write the second two columns of the NC variable in the matrix transposed way */
+ start[0] = 0; start[1] = 2;
+ err = ncmpi_bput_varm_float(ncid, varid, start, count, stride, imap, &var[2][0], &req[1]); ERR
+
+ err = ncmpi_wait_all(ncid, 2, req, status); ERR
+
+ /* check each bput status */
+ for (i=0; i<2; i++)
+ if (status[i] != NC_NOERR) {
+ printf("Error at line %d: err=%d %s\n", __LINE__, status[i], ncmpi_strerror(err));
+ nerrs++;
+ }
+
+ err = ncmpi_buffer_detach(ncid); ERR
+
+ /* the output from command "ncmpidump -v var test.nc" should be:
+ var =
+ 50, 56, 62, 68,
+ 51, 57, 63, 69,
+ 52, 58, 64, 70,
+ 53, 59, 65, 71,
+ 54, 60, 66, 72,
+ 55, 61, 67, 73 ;
+ */
+
+ /* check if the contents of write buffer have been altered (should not be) */
+ for (j=0; j<4; j++) {
+ for (i=0; i<6; i++) {
+ if (var[j][i] != j*6+i + 50) {
+#ifdef PRINT_ERR_ON_SCREEN
+ /* this error is a pntecdf internal error, if occurs */
+ printf("Error: bput_varm write buffer has been altered at j=%d i=%d\n",j,i);
+#endif
+ nerrs++;
+ break;
+ }
+ }
+ }
+ err = ncmpi_close(ncid); ERR
+
+ /* check if PnetCDF freed all internal malloc */
+ MPI_Offset malloc_size, sum_size;
+ err = ncmpi_inq_malloc_size(&malloc_size);
+ if (err == NC_NOERR) {
+ MPI_Reduce(&malloc_size, &sum_size, 1, MPI_OFFSET, MPI_SUM, 0, MPI_COMM_WORLD);
+ if (rank == 0 && sum_size > 0)
+ printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n",
+ sum_size);
+ }
+
+ MPI_Allreduce(MPI_IN_PLACE, &nerrs, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
+ if (rank == 0) {
+ if (nerrs) printf(FAIL_STR,nerrs);
+ else printf(PASS_STR);
+ }
+
+ MPI_Finalize();
+
+ return nerrs;
+}
+
diff --git a/test/nonblocking/test_bputf.f90 b/test/nonblocking/test_bputf.f90
new file mode 100644
index 0000000..93f6b84
--- /dev/null
+++ b/test/nonblocking/test_bputf.f90
@@ -0,0 +1,175 @@
+!
+! Copyright (C) 2012, Northwestern University
+! See COPYRIGHT notice in top-level directory.
+!
+! $Id: test_bputf.f90 2131 2015-09-25 22:33:12Z wkliao $
+
+ program main
+
+ use mpi
+ use pnetcdf
+ implicit none
+
+ logical verbose
+ integer i, j, ncid, varid, err, ierr, rank, nprocs, info
+ integer no_err, cmode, get_args
+ integer dimid(2), req(2), status(2)
+ integer(kind=MPI_OFFSET_KIND) start(2)
+ integer(kind=MPI_OFFSET_KIND) count(2)
+ integer(kind=MPI_OFFSET_KIND) stride(2)
+ integer(kind=MPI_OFFSET_KIND) imap(2)
+ integer(kind=MPI_OFFSET_KIND) bufsize
+ real var(6,4)
+ character(len=256) :: filename, cmd, msg
+
+ call MPI_INIT(ierr)
+ call MPI_COMM_RANK(MPI_COMM_WORLD, rank, ierr)
+ call MPI_COMM_SIZE(MPI_COMM_WORLD, nprocs, ierr)
+
+ if (rank .EQ. 0) then
+ filename = "testfile.nc"
+ err = get_args(cmd, filename)
+ endif
+ call MPI_Bcast(err, 1, MPI_INTEGER, 0, MPI_COMM_WORLD, ierr)
+ if (err .EQ. 0) goto 999
+
+ call MPI_Bcast(filename, 256, MPI_CHARACTER, 0, MPI_COMM_WORLD, ierr)
+
+ verbose = .FALSE.
+ if (nprocs > 1 .AND. rank .EQ. 0 .AND. verbose) then
+ print*,'Warning: ',trim(cmd), &
+ ' is designed to run on 1 process'
+ endif
+
+ call MPI_Info_create(info, ierr)
+ ! call MPI_Info_set(info, "romio_pvfs2_posix_write","enable",ierr)
+
+ cmode = IOR(NF90_CLOBBER, NF90_64BIT_DATA)
+ err = nf90mpi_create(MPI_COMM_WORLD, filename, cmode, &
+ info, ncid)
+ if (err < NF90_NOERR) print*,'Error at nf90mpi_create ', &
+ nf90mpi_strerror(err)
+
+ call MPI_Info_free(info, ierr)
+
+ ! define a variable of a 4 x 6 integer array in the nc file
+ err = nf90mpi_def_dim(ncid, 'X', 4_MPI_OFFSET_KIND, dimid(1))
+ if (err < NF90_NOERR) print*,'Error at nf90mpi_def_dim ', &
+ nf90mpi_strerror(err)
+
+ err = nf90mpi_def_dim(ncid, 'Y', 6_MPI_OFFSET_KIND, dimid(2))
+ if (err < NF90_NOERR) print*,'Error at nf90mpi_def_dim ', &
+ nf90mpi_strerror(err)
+
+ err = nf90mpi_def_var(ncid, 'var', NF90_INT64, dimid, varid)
+ if (err < NF90_NOERR) print*,'Error at nf90mpi_def_var ', &
+ nf90mpi_strerror(err)
+
+ err = nf90mpi_enddef(ncid)
+ if (err < NF90_NOERR) print*,'Error at nf90mpi_enddef ', &
+ nf90mpi_strerror(err)
+
+ ! set the contents of write buffer var, a 6 x 4 real array
+ ! 50, 56, 62, 68,
+ ! 51, 57, 63, 69,
+ ! 52, 58, 64, 70,
+ ! 53, 59, 65, 71,
+ ! 54, 60, 66, 72,
+ ! 55, 61, 67, 73
+ do j = 1, 4
+ do i = 1, 6
+ var(i,j) = (j-1)*6+(i-1) + 50
+ enddo
+ enddo
+
+ ! bufsize must be max of data type converted before and after
+ bufsize = 4*6*8
+ err = nf90mpi_buffer_attach(ncid, bufsize)
+ if (err < NF90_NOERR) print*,'Error at nf90mpi_buffer_attach ', &
+ nf90mpi_strerror(err)
+
+ ! write var to the NC variable in the matrix transposed way
+ count(1) = 2
+ count(2) = 6
+ stride(1) = 1
+ stride(2) = 1
+ imap(1) = 6
+ imap(2) = 1 ! imap would be {1, 4} if not transposing
+
+ if (rank .GT. 0) then
+ count(1) = 0
+ count(2) = 0
+ endif
+
+ ! write the first two columns of the NC variable in the matrix transposed way
+ start(1) = 1
+ start(2) = 1
+ err = nf90mpi_bput_var(ncid, varid, var(1:,1:), req(1), start, count, &
+ stride, imap)
+ if (err < NF90_NOERR) print*,'Error at nf90mpi_bput_var', &
+ nf90mpi_strerror(err)
+
+ ! write the second two columns of the NC variable in the matrix transposed way
+ start(1) = 3
+ start(2) = 1
+ err = nf90mpi_bput_var(ncid, varid, var(1:,3:), req(2), start, count, &
+ stride, imap)
+ if (err < NF90_NOERR) print*,'Error at nf90mpi_bput_var', &
+ nf90mpi_strerror(err)
+
+ err = nf90mpi_wait_all(ncid, 2, req, status)
+ if (err < NF90_NOERR) print*,'Error at nf90mpi_wait_all ', &
+ nf90mpi_strerror(err)
+
+ ! check each bput status
+ do i = 1, 2
+ if (status(i) .ne. NF90_NOERR) then
+ print*,'Error at bput status ', nf90mpi_strerror(status(i))
+ endif
+ enddo
+
+ err = nf90mpi_buffer_detach(ncid)
+ if (err < NF90_NOERR) print*,'Error at nf90mpi_buffer_detach ', &
+ nf90mpi_strerror(err)
+
+ ! the output from command "ncmpidump -v var test.nc" should be:
+ ! var =
+ ! 50, 56, 62, 68,
+ ! 51, 57, 63, 69,
+ ! 52, 58, 64, 70,
+ ! 53, 59, 65, 71,
+ ! 54, 60, 66, 72,
+ ! 55, 61, 67, 73 ;
+ ! note that the display of ncmpidump is in C array dimensional order
+
+ ! check if the contents of write buffer have been altered (should not be)
+ no_err = 0
+ if (rank .EQ. 0) then
+ do j = 1, 4
+ do i = 1, 6
+ if (var(i,j) .NE. (j-1)*6+(i-1) + 50) then
+! #ifdef PRINT_ERR_ON_SCREEN
+! ! this error is a pntecdf internal error, if occurs */
+! print*, &
+! 'Error: nf90mpi_bput_var write buffer has been altered at j=', &
+! j,' i=',i,' var=',var(i,j)
+! #endif
+ no_err = no_err + 1
+ endif
+ enddo
+ enddo
+ endif
+
+ err = nf90mpi_close(ncid)
+ if (err < NF90_NOERR) print*,'Error at nf90mpi_close ', &
+ nf90mpi_strerror(err)
+
+ if (rank .EQ. 0) then
+ msg = '*** TESTING F90 '//trim(cmd)//' for bput_var'
+ call pass_fail(no_err, msg)
+ endif
+
+ 999 CALL MPI_Finalize(ierr)
+
+ end program
+
diff --git a/test/nonblocking/test_bputf77.f b/test/nonblocking/test_bputf77.f
new file mode 100644
index 0000000..42c0f20
--- /dev/null
+++ b/test/nonblocking/test_bputf77.f
@@ -0,0 +1,190 @@
+!
+! Copyright (C) 2012, Northwestern University and Argonne National Lab
+! See COPYRIGHT notice in top-level directory.
+!
+! $Id: test_bputf77.f 2224 2015-12-16 06:10:36Z wkliao $
+!
+
+ INTEGER FUNCTION XTRIM(STRING)
+ CHARACTER*(*) STRING
+ INTEGER I, N
+ N = LEN(STRING)
+ DO I = N, 1, -1
+ IF (STRING(I:I) .NE. ' ') GOTO 10
+ ENDDO
+ 10 XTRIM = I
+ END ! FUNCTION XTRIM
+
+ program main
+
+ implicit none
+ include "mpif.h"
+ include "pnetcdf.inc"
+
+ logical verbose
+ integer i, j, ncid, varid, err, ierr, rank, nprocs, info
+ integer no_err, cmode, get_args, XTRIM
+ integer dimid(2), req(2), status(2)
+ integer*8 start(2)
+ integer*8 count(2)
+ integer*8 stride(2)
+ integer*8 imap(2)
+ integer*8 bufsize, dim_size
+ real var(6,4)
+ character*256 filename, cmd, msg
+
+ call MPI_INIT(ierr)
+ call MPI_COMM_RANK(MPI_COMM_WORLD, rank, ierr)
+ call MPI_COMM_SIZE(MPI_COMM_WORLD, nprocs, ierr)
+
+ if (rank .EQ. 0) then
+ filename = "testfile.nc"
+ err = get_args(cmd, filename)
+ endif
+ call MPI_Bcast(err, 1, MPI_INTEGER, 0, MPI_COMM_WORLD, ierr)
+ if (err .EQ. 0) goto 999
+
+ call MPI_Bcast(filename, 256, MPI_CHARACTER, 0, MPI_COMM_WORLD,
+ + ierr)
+
+ verbose = .FALSE.
+ if (nprocs .GT. 1 .AND. rank .EQ. 0 .AND. verbose) then
+ print*,'Warning: ',cmd(1:XTRIM(cmd)),
+ + ' is designed to run on 1 process'
+ endif
+
+ call MPI_Info_create(info, ierr)
+ ! call MPI_Info_set(info, "romio_pvfs2_posix_write","enable",ierr)
+
+ cmode = IOR(NF_CLOBBER, NF_64BIT_DATA)
+ err = nfmpi_create(MPI_COMM_WORLD, 'testfile.nc', cmode,
+ + info, ncid)
+ if (err .NE. NF_NOERR) print*,'Error at nfmpi_create ',
+ + nfmpi_strerror(err)
+
+ call MPI_Info_free(info, ierr)
+
+ ! define a variable of a 4 x 6 integer array in the nc file
+ dim_size = 4
+ err = nfmpi_def_dim(ncid, 'X', dim_size, dimid(1))
+ if (err .NE. NF_NOERR) print*,'Error at nfmpi_def_dim ',
+ + nfmpi_strerror(err)
+
+ dim_size = 6
+ err = nfmpi_def_dim(ncid, 'Y', dim_size, dimid(2))
+ if (err .NE. NF_NOERR) print*,'Error at nfmpi_def_dim ',
+ + nfmpi_strerror(err)
+
+ err = nfmpi_def_var(ncid, 'var', NF_INT64, 2, dimid, varid)
+ if (err .NE. NF_NOERR) print*,'Error at nfmpi_def_var ',
+ + nfmpi_strerror(err)
+
+ err = nfmpi_enddef(ncid)
+ if (err .NE. NF_NOERR) print*,'Error at nfmpi_enddef ',
+ + nfmpi_strerror(err)
+
+ ! set the contents of write buffer var, a 6 x 4 real array
+ ! 50, 56, 62, 68,
+ ! 51, 57, 63, 69,
+ ! 52, 58, 64, 70,
+ ! 53, 59, 65, 71,
+ ! 54, 60, 66, 72,
+ ! 55, 61, 67, 73
+ do j = 1, 4
+ do i = 1, 6
+ var(i,j) = (j-1)*6+(i-1) + 50
+ enddo
+ enddo
+
+ ! bufsize must be max of data type converted before and after
+ bufsize = 4*6*8
+ err = nfmpi_buffer_attach(ncid, bufsize)
+ if (err .NE. NF_NOERR) print*,'Error at nfmpi_buffer_attach ',
+ + nfmpi_strerror(err)
+
+ ! write var to the NC variable in the matrix transposed way
+ count(1) = 2
+ count(2) = 6
+ stride(1) = 1
+ stride(2) = 1
+ imap(1) = 6
+ imap(2) = 1 ! imap would be {1, 4} if not transposing
+
+ if (rank .GT. 0) then
+ count(1) = 0
+ count(2) = 0
+ endif
+
+ ! write the first two columns of the NC variable in the matrix transposed way
+ start(1) = 1
+ start(2) = 1
+ err = nfmpi_bput_varm_real(ncid, varid, start, count, stride,
+ + imap, var(1,1), req(1))
+ if (err .NE. NF_NOERR) print*,'Error at nfmpi_bput_varm_real ',
+ + nfmpi_strerror(err)
+
+ ! write the second two columns of the NC variable in the matrix transposed way
+ start(1) = 3
+ start(2) = 1
+ err = nfmpi_bput_varm_real(ncid, varid, start, count, stride,
+ + imap, var(1,3), req(2))
+ if (err .NE. NF_NOERR) print*,'Error at nfmpi_bput_varm_real ',
+ + nfmpi_strerror(err)
+
+ err = nfmpi_wait_all(ncid, 2, req, status)
+ if (err .NE. NF_NOERR) print*,'Error at nfmpi_wait_all ',
+ + nfmpi_strerror(err)
+
+ ! check each bput status
+ do i = 1, 2
+ if (status(i) .ne. NF_NOERR) then
+ print*,'Error at bput status ', nfmpi_strerror(status(i))
+ endif
+ enddo
+
+ err = nfmpi_buffer_detach(ncid)
+ if (err .NE. NF_NOERR) print*,'Error at nfmpi_buffer_detach ',
+ + nfmpi_strerror(err)
+
+ ! the output from command "ncmpidump -v var test.nc" should be:
+ ! var =
+ ! 50, 56, 62, 68,
+ ! 51, 57, 63, 69,
+ ! 52, 58, 64, 70,
+ ! 53, 59, 65, 71,
+ ! 54, 60, 66, 72,
+ ! 55, 61, 67, 73 ;
+ ! note that the display of ncmpidump is in C array dimensional order
+
+ ! check if the contents of write buffer have been altered (should not be)
+ no_err = 0
+ if (rank .EQ. 0) then
+ do j = 1, 4
+ do i = 1, 6
+ if (var(i,j) .NE. (j-1)*6+(i-1) + 50) then
+! #ifdef PRINT_ERR_ON_SCREEN
+! ! this error is a pntecdf internal error, if occurs */
+! print*, &
+! 'Error: bput_varm write buffer has been altered at j=', &
+! j,' i=',i,' var=',var(i,j)
+! #endif
+ no_err = no_err + 1
+ endif
+ enddo
+ enddo
+ endif
+
+ err = nfmpi_close(ncid)
+ if (err .NE. NF_NOERR) print*,'Error at nfmpi_close ',
+ + nfmpi_strerror(err)
+
+ if (rank .EQ. 0) then
+ msg = '*** TESTING F77 '//cmd(1:XTRIM(cmd))//
+ + ' for bput_varm_real API'
+ call pass_fail(no_err, msg)
+ endif
+
+ 999 CALL MPI_Finalize(ierr)
+
+ end ! program
+
diff --git a/test/nonblocking/wait_after_indep.c b/test/nonblocking/wait_after_indep.c
new file mode 100644
index 0000000..206739d
--- /dev/null
+++ b/test/nonblocking/wait_after_indep.c
@@ -0,0 +1,98 @@
+/*********************************************************************
+ *
+ * Copyright (C) 2014, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ *
+ *********************************************************************/
+/* $Id: wait_after_indep.c 2133 2015-09-26 19:16:01Z wkliao $ */
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ *
+ * This example tests if ncmpi_end_indep_data() works properly when nonblocking
+ * APIs are called in the independent data mode, but the wait call is made later
+ * in collective data mode.
+ *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <mpi.h>
+#include <pnetcdf.h>
+
+#include <testutils.h>
+
+#define NY 4
+#define NX 10
+#define NDIMS 2
+
+#define ERR \
+ if (err != NC_NOERR) { \
+ printf("Error at line=%d: %s\n", __LINE__, ncmpi_strerror(err)); \
+ nerrs++; \
+ }
+
+int main(int argc, char** argv)
+{
+ int i, j, rank, nprocs, err, nerrs=0;
+ int ncid, varid, dimid[2], req, st;
+ MPI_Offset start[2], count[2], stride[2];
+ unsigned char buffer[NY][NX];
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+
+ if (rank == 0) {
+ char cmd_str[256];
+ sprintf(cmd_str, "*** TESTING C %s for ncmpi_end_indep_data ", argv[0]);
+ printf("%-66s ------ ",cmd_str);
+ }
+
+ err = ncmpi_create(MPI_COMM_WORLD, "testfile.nc", NC_CLOBBER|NC_64BIT_DATA,
+ MPI_INFO_NULL, &ncid);
+ ERR
+
+ err = ncmpi_def_dim(ncid, "Y", NC_UNLIMITED, &dimid[0]); ERR
+ err = ncmpi_def_dim(ncid, "X", NX*nprocs, &dimid[1]); ERR
+ err = ncmpi_def_var(ncid, "var", NC_UBYTE, NDIMS, dimid, &varid); ERR
+ err = ncmpi_enddef(ncid); ERR
+
+ for (i=0; i<NY; i++) for (j=0; j<NX; j++) buffer[i][j] = rank;
+
+ start[0] = 0; start[1] = NX*rank;
+ count[0] = NY/2; count[1] = NX/2;
+ stride[0] = 2; stride[1] = 2;
+ err = ncmpi_buffer_attach(ncid, NY*NX); ERR
+
+ err = ncmpi_begin_indep_data(ncid); ERR
+ err = ncmpi_bput_vars_uchar(ncid, varid, start, count, stride,
+ &buffer[0][0], &req);
+ ERR
+ err = ncmpi_end_indep_data(ncid); ERR
+
+ /* calling wait API after exiting independent data mode on purpose */
+ err = ncmpi_wait_all(ncid, 1, &req, &st); ERR
+
+ err = ncmpi_buffer_detach(ncid); ERR
+ err = ncmpi_close(ncid); ERR
+
+ /* check if PnetCDF freed all internal malloc */
+ MPI_Offset malloc_size, sum_size;
+ err = ncmpi_inq_malloc_size(&malloc_size);
+ if (err == NC_NOERR) {
+ MPI_Reduce(&malloc_size, &sum_size, 1, MPI_OFFSET, MPI_SUM, 0, MPI_COMM_WORLD);
+ if (rank == 0 && sum_size > 0)
+ printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n",
+ sum_size);
+ }
+
+ MPI_Allreduce(MPI_IN_PLACE, &nerrs, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
+ if (rank == 0) {
+ if (nerrs) printf(FAIL_STR,nerrs);
+ else printf(PASS_STR);
+ }
+
+ MPI_Finalize();
+ return 0;
+}
+
diff --git a/test/subfile/Makefile.in b/test/subfile/Makefile.in
new file mode 100644
index 0000000..e235239
--- /dev/null
+++ b/test/subfile/Makefile.in
@@ -0,0 +1,79 @@
+#
+# Copyright (C) 2013, Northwestern University and Argonne National Laboratory
+# See COPYRIGHT notice in top-level directory.
+#
+# $Id: Makefile.in 2251 2015-12-20 21:13:42Z wkliao $
+#
+# @configure_input@
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+include ../../macros.make
+
+INCLUDES = -I../../src/lib -I$(srcdir)/../common
+FPPFLAGS += -I../../src/libf @FC_MODINC at ../../src/libf90
+F90FLAGS += @FC_MODOUT at .
+LDFLAGS := $(LDFLAGS) -L../common
+LIBS := $(LIBRARY) -ltestutils $(LIBS) @LCOV_LIB@
+ifeq (@PNC_DEBUG@, yes)
+CPPFLAGS := $(CPPFLAGS) -DPNC_DEBUG
+endif
+
+C_SRCS = test_subfile.c
+
+CXX_SRCS =
+
+F77_SRCS =
+
+PROGS = $(C_SRCS:.c=)
+OBJS = $(C_SRCS:.c=.o)
+ifeq (@has_mpicxx@, yes)
+PROGS += $(CXX_SRCS:.cpp=)
+OBJS += $(CXX_SRCS:.cpp=.o)
+endif
+
+ifeq (@has_fortran@, yes)
+PROGS += $(F77_SRCS:.f=)
+OBJS += $(F77_SRCS:.f=.o)
+endif
+
+GARBAGE = $(PROGS) *.nc
+PACKING_LIST = $(C_SRCS) $(F77_SRCS) $(CXX_SRCS) Makefile.in depend README
+
+all: $(PROGS)
+
+$(C_SRCS:.c=.o) $(CXX_SRCS:.cpp=.o): $(srcdir)/../common/testutils.h
+
+$(PROGS): ../common/libtestutils.a
+
+../common/libtestutils.a:
+ set -e; cd ../common && $(MAKE) $(MFLAGS) all
+
+test_subfile: test_subfile.o $(LIBRARY)
+ $(LINK.c) $< $(LDFLAGS) $(LIBS)
+
+testing check verbose_testing:
+
+TEST_MPIRUN_2 = $(subst NP,2,$(TEST_MPIRUN))
+TEST_MPIRUN_4 = $(subst NP,4,$(TEST_MPIRUN))
+
+ptest2: $(PROGS)
+ @for i in $(PROGS); do ( \
+ $(TEST_MPIRUN_2) ./$$i -f $(TEST_OUTDIR)/testfile.nc -s 2 \
+ ; ) ; done
+
+ptest4: $(PROGS)
+ @for i in $(PROGS); do ( \
+ $(TEST_MPIRUN_4) ./$$i -f $(TEST_OUTDIR)/testfile.nc -s 2 \
+ ; ) ; done
+
+ptest: ptest4
+ptests: ptest2 ptest4
+ptest6 ptest8 ptest10:
+
+include $(srcdir)/../../rules.make
+include $(srcdir)/depend
+
+$(LIBRARY): ;
+
diff --git a/test/subfile/README b/test/subfile/README
new file mode 100644
index 0000000..73f8aad
--- /dev/null
+++ b/test/subfile/README
@@ -0,0 +1,15 @@
+#
+# Copyright (C) 2013, Northwestern University and Argonne National Laboratory
+# See COPYRIGHT notice in top-level directory.
+#
+# $Id: README 1468 2013-10-26 16:53:18Z wkliao $
+#
+
+In order to use the subfiling module, pnetcdf must be configured with "--enable-subfiling" option.
+
+This is a test run to create two subfiles. Note that the number of MPI processes must be equal or larger than the number of subfiles.
+
+$ mpiexec -n 2 ./test_subfile -f test_subfile.nc -s 2
+
+This will create 1 master file (the original file, i.e., test_subfile.nc) and two subfiles, test_subfile.nc.subfile_0.nc and test_subfile.nc.subfile_1.nc.
+Since the file is intended to subfiled, the original file does not have any data; all data is stored in two subfiles.
diff --git a/test/subfile/depend b/test/subfile/depend
new file mode 100644
index 0000000..f0c4e46
--- /dev/null
+++ b/test/subfile/depend
@@ -0,0 +1,2 @@
+test_subfile.o: test_subfile.c
+
diff --git a/test/subfile/test_subfile.c b/test/subfile/test_subfile.c
new file mode 100644
index 0000000..ab8e611
--- /dev/null
+++ b/test/subfile/test_subfile.c
@@ -0,0 +1,417 @@
+/*
+ * Copyright (C) 2013, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ */
+/* $Id: test_subfile.c 2205 2015-11-28 20:41:50Z wkliao $ */
+#include <mpi.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <pnetcdf.h>
+
+#include <testutils.h>
+
+#define MAXLINE 128
+
+/* The file name is taken as a command-line argument. */
+
+/* Measures the I/O bandwidth for writing/reading a 3D
+ block-distributed array to a file corresponding to the global array
+ in row-major (C) order.
+ Note that the file access pattern is noncontiguous.
+
+ Array size 128^3. For other array sizes, change array_of_gsizes below.*/
+#define TEST_HANDLE_ERR(status) \
+ if ((status) != NC_NOERR) { \
+ printf("Error at line %d (%s)\n", __LINE__, \
+ ncmpi_strerror((status)) ); \
+ nerrs++; \
+ } \
+
+int main(int argc, char **argv)
+{
+ int opt, verbose=0;
+ extern char *optarg;
+ extern int optind;
+ int i, j, array_of_gsizes[3];
+ int nprocs, len, **buf, rank;
+ MPI_Offset bufcount;
+ int array_of_psizes[3];
+ int status;
+ MPI_Offset array_of_starts[3];
+ char *basename = NULL, *basename1 = NULL, filename[256];
+ char dimname[20], varname[20];
+ int ncid, dimids0[3], rank_dim[3], *varid=NULL;
+ MPI_Info info=MPI_INFO_NULL, info_used=MPI_INFO_NULL;
+ MPI_Offset **starts_list, **count_list;
+ MPI_Offset *bufcount_list;
+ int ndims=3, nvars=1, ngatts, unlimdimid;
+ MPI_Datatype *datatype_list;
+ int length = 128; /* 8MB per proc */
+ double stim, write_tim, new_write_tim, write_bw;
+ double read_tim, new_read_tim, read_bw;
+ double open_tim, new_open_tim;
+ double close_tim, new_close_tim;
+ int num_sf = 2;
+ int par_dim_id = 0; /* default is 0 */
+ int do_read = 0;
+ int nerrs=0;
+
+ MPI_Init(&argc,&argv);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+
+ /* process 0 takes the file name as a command-line argument and
+ broadcasts it to other processes */
+ if (!rank) {
+ while ((opt = getopt(argc, argv, "f:s:rp:n:l:")) != EOF) {
+ switch (opt) {
+ case 'f': basename = optarg;
+ break;
+ case 's': num_sf = atoi(optarg);
+ break;
+ case 'r': do_read = 1;
+ break;
+ case 'p': par_dim_id = atoi(optarg);
+ break;
+ case 'n': nvars = atoi(optarg);
+ break;
+ case 'l': length = atoi(optarg);
+ break;
+ default:
+ break;
+ }
+ }
+ if (basename == NULL) {
+ fprintf(stderr, "\n*# Usage: test_subfile -f pathname -s num_sf -p par_dim_id \n\n");
+ MPI_Abort(MPI_COMM_WORLD, 1);
+ }
+
+ basename1 = (char *) malloc (MAXLINE);
+ sprintf(basename1, "%s", basename);
+ len = strlen(basename1);
+ MPI_Bcast(&len, 1, MPI_INT, 0, MPI_COMM_WORLD);
+ MPI_Bcast(basename, len+1, MPI_CHAR, 0, MPI_COMM_WORLD);
+ MPI_Bcast(&num_sf, 1, MPI_INT, 0, MPI_COMM_WORLD);
+ MPI_Bcast(&par_dim_id, 1, MPI_INT, 0, MPI_COMM_WORLD);
+ MPI_Bcast(&nvars, 1, MPI_INT, 0, MPI_COMM_WORLD);
+ MPI_Bcast(&do_read, 1, MPI_INT, 0, MPI_COMM_WORLD);
+ MPI_Bcast(&length, 1, MPI_INT, 0, MPI_COMM_WORLD);
+ }
+ else {
+ basename1 = (char *) malloc (MAXLINE);
+ MPI_Bcast(&len, 1, MPI_INT, 0, MPI_COMM_WORLD);
+ MPI_Bcast(basename1, len+1, MPI_CHAR, 0, MPI_COMM_WORLD);
+ MPI_Bcast(&num_sf, 1, MPI_INT, 0, MPI_COMM_WORLD);
+ MPI_Bcast(&par_dim_id, 1, MPI_INT, 0, MPI_COMM_WORLD);
+ MPI_Bcast(&nvars, 1, MPI_INT, 0, MPI_COMM_WORLD);
+ MPI_Bcast(&do_read, 1, MPI_INT, 0, MPI_COMM_WORLD);
+ MPI_Bcast(&length, 1, MPI_INT, 0, MPI_COMM_WORLD);
+ }
+
+ if (rank == 0) {
+ char cmd_str[256];
+ sprintf(cmd_str, "*** TESTING C %s for subfiling", argv[0]);
+ printf("%-66s ------ ", cmd_str);
+ }
+
+ array_of_gsizes[0] = array_of_gsizes[1] = array_of_gsizes[2] = length;
+
+ buf = (int **)malloc(nvars*sizeof(int*));
+ if (buf == NULL){
+ printf("buf malloc error\n");
+ return 0;
+ }
+ bufcount_list = (MPI_Offset *)malloc(nvars*sizeof(MPI_Offset));
+ if (bufcount_list == NULL){
+ printf("bufcount_list malloc error\n");
+ return 0;
+ }
+ starts_list = (MPI_Offset **)malloc(nvars*sizeof(MPI_Offset *));
+ if (starts_list== NULL){
+ printf("starts_list malloc error\n");
+ return 0;
+ }
+ count_list = (MPI_Offset **)malloc(nvars*sizeof(MPI_Offset *));
+ if (count_list == NULL){
+ printf("count_list malloc error\n");
+ return 0;
+ }
+ datatype_list = (MPI_Datatype*)malloc(nvars*sizeof(MPI_Datatype));
+ if (datatype_list == NULL){
+ printf("count_list malloc error\n");
+ return 0;
+ }
+
+ for (i=0; i<nvars; i++) {
+ starts_list[i] = (MPI_Offset *)malloc(ndims*sizeof(MPI_Offset));
+ if (starts_list[i] == NULL){
+ printf("starts_list[%d] malloc error\n", i);
+ return 0;
+ }
+ count_list[i] = (MPI_Offset *)malloc(ndims*sizeof(MPI_Offset));
+ if (count_list[i] == NULL){
+ printf("count_list[%d] malloc error\n", i);
+ return 0;
+ }
+ }
+
+ bufcount = 1;
+ for (i=0; i<ndims; i++) {
+ array_of_psizes[i] = 0;
+ bufcount *= length;
+ }
+ MPI_Dims_create(nprocs, ndims, array_of_psizes);
+ if (verbose)
+ for(i=0; i<ndims&&rank==0; i++)
+ printf("array_of_psizes[%d]=%d\n", i, array_of_psizes[i]);
+
+ /* subarray in each process is len x len x len */
+ for (i=0; i<ndims; i++)
+ array_of_gsizes[i] = length * array_of_psizes[i];
+
+ /* mynd's process rank in each dimension (in MPI_ORDER_C) */
+ rank_dim[2] = rank % array_of_psizes[2];
+ rank_dim[1] = (rank / array_of_psizes[2]) % array_of_psizes[1];
+ rank_dim[0] = rank / (array_of_psizes[2] * array_of_psizes[1]);
+
+ /* starting coordinates of the subarray in each dimension */
+ for (i=0; i<ndims; i++)
+ array_of_starts[i] = length * rank_dim[i];
+
+ for (i=0; i<nvars; i++) {
+ for (j=0; j<ndims; j++) {
+ starts_list[i][j] = array_of_starts[j];
+ count_list[i][j] = length;
+ }
+ bufcount_list[i] = bufcount;
+ datatype_list[i] = MPI_INT;
+ }
+
+ for (i=0; i<nvars; i++) {
+ buf[i] = (int *) malloc(bufcount * sizeof(int));
+ if (buf[i] == NULL){
+ printf("buf[i]malloc error\n");
+ return 0;
+ }
+
+ for (j=0; j<bufcount; j++)
+ buf[i][j]=rank+1;
+ }
+
+ MPI_Info_create(&info);
+ /* set all non-record variable to be subfiled */
+ char tmp[10];
+ sprintf(tmp, "%d", num_sf);
+ MPI_Info_set(info, "nc_num_subfiles", tmp);
+
+ sprintf(filename, "%s.%d.%d.%d.nc", basename1, length, 1, 0);
+
+ if (do_read == 1) goto read;
+
+ stim = MPI_Wtime();
+ status = ncmpi_create(MPI_COMM_WORLD, filename, NC_CLOBBER|NC_64BIT_DATA,
+ info, &ncid);
+ TEST_HANDLE_ERR(status)
+
+ open_tim = MPI_Wtime() - stim;
+
+ MPI_Allreduce(&open_tim, &new_open_tim, 1, MPI_DOUBLE, MPI_MAX,
+ MPI_COMM_WORLD);
+ if (verbose && rank == 0)
+ printf("create time = %f sec\n", new_open_tim);
+
+ /* define dimensions */
+ for (i=0; i<ndims; i++){
+ sprintf(dimname, "dim0_%d", i);
+ status = ncmpi_def_dim(ncid, dimname, array_of_gsizes[i], &dimids0[i]);
+ TEST_HANDLE_ERR(status)
+ }
+
+ /* define variables */
+ varid = (int *)malloc(nvars*sizeof(int));
+ for (i=0; i<nvars; i++) {
+ sprintf(varname, "var0_%d", i);
+ status = ncmpi_def_var(ncid, varname, NC_INT, ndims, dimids0, &varid[i]);
+ TEST_HANDLE_ERR(status)
+ }
+
+ if (par_dim_id != 0) {
+ for (i=0; i<nvars; i++) {
+ status = ncmpi_put_att_int(ncid, varid[i], "par_dim_id",
+ NC_INT, 1, &dimids0[par_dim_id]);
+ TEST_HANDLE_ERR(status)
+ }
+ }
+
+ /* set all non-record variable to be subfiled */
+ /*
+ MPI_Info_set(info, "nc_num_subfiles", "2");
+ status = ncmpi_set_var_info(ncid, varid, info);
+ TEST_HANDLE_ERR(status);
+ */
+
+ status = ncmpi_enddef(ncid);
+ TEST_HANDLE_ERR(status)
+
+ /* test ncmpi_inq_var() */
+ for (i=0; i<nvars; i++) {
+ char name[128];
+ nc_type typep;
+ int ndimsp, dimids[3], nattsp;
+
+ status = ncmpi_inq_var(ncid, varid[i], name, &typep, &ndimsp, dimids,
+ &nattsp);
+ TEST_HANDLE_ERR(status)
+
+ sprintf(varname, "var0_%d", i);
+ if (strcmp(name, varname)) {
+ printf("Error: unexpected var[%d] name %s, should be %s\n",i,name,varname);
+ nerrs++;
+ continue;
+ }
+ if (typep != NC_INT) {
+ printf("Error: unexpected var[%d] type %d, should be %d\n",i,typep,NC_INT);
+ nerrs++;
+ continue;
+ }
+ if (ndimsp != ndims) {
+ printf("Error: unexpected var[%d] ndims %d, should be %d\n",i,ndimsp,ndims);
+ nerrs++;
+ continue;
+ }
+ for (j=0; j<ndims; j++) {
+ if (dimids[j] != dimids0[j]) {
+ printf("Error: unexpected var[%d] dimids[%d] %d, should be %d\n",i,j,dimids0[j],dimids[j]);
+ nerrs++;
+ continue;
+ }
+ }
+ /*
+ printf("var[%d] %s has %d attributes\n",i,name,nattsp);
+ */
+ }
+
+#if 0
+ if (rank == 0)
+ printf("*** Testing to write 1 non-record variable by using ncmpi_put_vara_all() ...");
+#endif
+ stim = MPI_Wtime();
+ for (i=0; i<nvars; i++) {
+ status = ncmpi_put_vara_all(ncid, varid[i],
+ starts_list[i], count_list[i],
+ buf[i],
+ bufcount_list[i], MPI_INT);
+ TEST_HANDLE_ERR(status)
+ }
+ write_tim = MPI_Wtime() - stim;
+
+ MPI_Allreduce(&write_tim, &new_write_tim, 1, MPI_DOUBLE, MPI_MAX,
+ MPI_COMM_WORLD);
+
+ if (verbose && rank == 0) {
+ write_bw = ((double)array_of_gsizes[0]*(double)array_of_gsizes[1]*(double)array_of_gsizes[2]*(double)sizeof(int)*(double)nvars)/(new_write_tim*1024.0*1024.0);
+ printf("Global array size %d x %d x %d integers\n", array_of_gsizes[0], array_of_gsizes[1], array_of_gsizes[2]);
+ printf("Collective write time = %f sec, Collective write bandwidth = %f Mbytes/sec\n", new_write_tim, write_bw);
+ }
+
+ status = ncmpi_inq_file_info(ncid, &info_used);
+ TEST_HANDLE_ERR(status)
+
+ stim = MPI_Wtime();
+ status = ncmpi_close(ncid);
+ TEST_HANDLE_ERR(status)
+ close_tim = MPI_Wtime() - stim;
+
+ MPI_Allreduce(&close_tim, &new_close_tim, 1, MPI_DOUBLE, MPI_MAX,
+ MPI_COMM_WORLD);
+
+ if (verbose && rank == 0) {
+ fprintf(stderr, "close time = %f sec\n", new_close_tim);
+ }
+
+ goto end;
+
+read:
+ status = ncmpi_open(MPI_COMM_WORLD, filename, NC_NOWRITE, MPI_INFO_NULL, &ncid);
+ TEST_HANDLE_ERR(status)
+
+ stim = MPI_Wtime();
+
+ /**
+ * Inquire the dataset definitions of input dataset AND
+ * Add dataset definitions for output dataset.
+ */
+
+ status = ncmpi_inq(ncid, &ndims, &nvars, &ngatts, &unlimdimid);
+ TEST_HANDLE_ERR(status)
+
+ for (i=0; i<nvars; i++) {
+ status = ncmpi_get_vara_all(ncid, i,
+ starts_list[i], count_list[i],
+ buf[i], bufcount_list[i], MPI_INT);
+ TEST_HANDLE_ERR(status)
+ }
+ read_tim = MPI_Wtime() - stim;
+
+ MPI_Allreduce(&read_tim, &new_read_tim, 1, MPI_DOUBLE, MPI_MAX,
+ MPI_COMM_WORLD);
+
+ if (verbose && rank == 0) {
+ read_bw = ((double)array_of_gsizes[0]*(double)array_of_gsizes[1]*(double)array_of_gsizes[2]*sizeof(int)*(double)nvars)/(new_read_tim*1024.0*1024.0);
+ printf("Collective read time = %f sec, Collective read bandwidth = %f Mbytes/sec\n", new_read_tim, read_bw);
+ }
+
+ status = ncmpi_inq_file_info(ncid, &info_used);
+ TEST_HANDLE_ERR(status)
+
+ status = ncmpi_close(ncid);
+ TEST_HANDLE_ERR(status)
+
+end:
+ if (info != MPI_INFO_NULL) MPI_Info_free(&info);
+ if (info_used != MPI_INFO_NULL) MPI_Info_free(&info_used);
+
+ for (i=0; i<nvars; i++){
+ free(buf[i]);
+ free(starts_list[i]);
+ free(count_list[i]);
+ }
+ free(buf);
+ free(bufcount_list);
+ free(datatype_list);
+ if (!do_read) free(varid);
+ free(starts_list);
+ free(count_list);
+ free(basename1);
+
+ MPI_Offset malloc_size, sum_size;
+ int err, nfiles, ncids[10];
+
+ /* check if there are files still left opened */
+ err = ncmpi_inq_files_opened(&nfiles, ncids);
+ TEST_HANDLE_ERR(err)
+ if (nfiles > 0) printf("nfiles %d still opened\n",nfiles);
+
+ /* check for any PnetCDF internal malloc residues */
+ err = ncmpi_inq_malloc_size(&malloc_size);
+ if (err == NC_NOERR) {
+ MPI_Reduce(&malloc_size, &sum_size, 1, MPI_OFFSET, MPI_SUM, 0, MPI_COMM_WORLD);
+ if (rank == 0 && sum_size > 0)
+ printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n",
+ sum_size);
+ }
+
+ MPI_Allreduce(MPI_IN_PLACE, &nerrs, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
+ if (rank == 0) {
+ if (nerrs) printf(FAIL_STR,nerrs);
+ else printf(PASS_STR);
+ }
+
+ MPI_Finalize();
+
+ return 0;
+}
diff --git a/test/testcases/Makefile.in b/test/testcases/Makefile.in
new file mode 100644
index 0000000..0bcbe88
--- /dev/null
+++ b/test/testcases/Makefile.in
@@ -0,0 +1,251 @@
+#
+# Copyright (C) 2003, Northwestern University and Argonne National Laboratory
+# See COPYRIGHT notice in top-level directory.
+#
+# $Id: Makefile.in 2288 2016-01-02 08:14:49Z wkliao $
+#
+# @configure_input@
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+include ../../macros.make
+
+INCLUDES = -I../../src/lib -I$(srcdir)/../common
+FPPFLAGS += -I../../src/libf @FC_MODINC at ../../src/libf90
+ifeq (@SIZEOF_MPI_AINT_IS_4@, yes)
+FPPFLAGS += -DSIZEOF_MPI_AINT_IS_4
+endif
+LDFLAGS := $(LDFLAGS) -L../common
+LIBS := $(LIBRARY) -ltestutils $(LIBS) @LCOV_LIB@
+ifeq (@PNC_DEBUG@, yes)
+CPPFLAGS := $(CPPFLAGS) -DPNC_DEBUG
+endif
+
+NCMPIGEN = ../../src/utils/ncmpigen/ncmpigen
+NCMPIDIFF = ../../src/utils/ncmpidiff/ncmpidiff
+
+C_SRCS = ncmpi_vars_null_stride.c \
+ vectors.c \
+ collective_error.c \
+ test_varm.c \
+ alignment_test.c \
+ flexible.c \
+ flexible2.c \
+ flexible_varm.c \
+ nonblocking.c \
+ noclobber.c \
+ record.c \
+ inq_num_vars.c \
+ varn_int.c \
+ modes.c \
+ one_record.c \
+ inq_recsize.c \
+ test_vard.c \
+ varn_contig.c \
+ ivarn.c \
+ check_striping.c \
+ add_var.c \
+ buftype_free.c \
+ last_large_var.c \
+ check_type.c \
+ test_erange.c \
+ redef1.c
+
+F77_SRCS = varn_intf.f \
+ attrf.f \
+ buftype_freef.f \
+ put_parameter.f
+
+F77F_SRCS = test_vardf.F
+
+F90_SRCS = inq_num_varsf.f90 \
+ inq_recsizef.f90 \
+ test_vardf90.f90 \
+ varn_real.f90
+
+PROGS = $(C_SRCS:.c=)
+OBJS = $(C_SRCS:.c=.o)
+
+ifeq (@has_fortran@, yes)
+PROGS += $(F77_SRCS:.f=) $(F77F_SRCS:.F=) $(F90_SRCS:.f90=)
+OBJS += $(F77_SRCS:.f=.o) $(F77F_SRCS:.F=.o) $(F90_SRCS:.f90=.o)
+ifeq (@large_file_test@, yes)
+PROGS += bigrecords
+OBJS += bigrecords.o
+endif
+endif
+
+GARBAGE = $(PROGS) *.nc
+PACKING_LIST = $(C_SRCS) $(F77_SRCS) $(F77F_SRCS) $(F90_SRCS) \
+ bigrecords.f \
+ Makefile.in depend \
+ geopotential.ncdump \
+ redef-good.ncdump \
+ interop1.sh \
+ redef1.sh
+
+all: $(PROGS)
+
+$(C_SRCS:.c=.o): $(srcdir)/../common/testutils.h
+
+$(PROGS): ../common/libtestutils.a
+
+../common/libtestutils.a:
+ set -e; cd ../common && $(MAKE) $(MFLAGS) all
+
+ncmpi_vars_null_stride: ncmpi_vars_null_stride.o $(LIBRARY)
+ $(LINK.c) $< $(LDFLAGS) $(LIBS)
+
+vectors: vectors.o $(LIBRARY)
+ $(LINK.c) $< $(LDFLAGS) $(LIBS)
+
+bigrecords: bigrecords.o $(LIBRARY)
+ $(LINK.F90) $< $(LDFLAGS) $(LIBS)
+
+redef1: redef1.o $(LIBRARY)
+ $(LINK.c) $< $(LDFLAGS) $(LIBS)
+
+collective_error: collective_error.o $(LIBRARY)
+ $(LINK.c) $< $(LDFLAGS) $(LIBS)
+
+test_varm: test_varm.o $(LIBRARY)
+ $(LINK.c) $< $(LDFLAGS) $(LIBS)
+
+alignment_test: alignment_test.o $(LIBRARY)
+ $(LINK.c) $< $(LDFLAGS) $(LIBS)
+
+flexible: flexible.o $(LIBRARY)
+ $(LINK.c) $< $(LDFLAGS) $(LIBS)
+
+flexible2: flexible2.o $(LIBRARY)
+ $(LINK.c) $< $(LDFLAGS) $(LIBS)
+
+flexible_varm: flexible_varm.o $(LIBRARY)
+ $(LINK.c) $< $(LDFLAGS) $(LIBS)
+
+nonblocking: nonblocking.o $(LIBRARY)
+ $(LINK.c) $< $(LDFLAGS) $(LIBS)
+
+noclobber: noclobber.o $(LIBRARY)
+ $(LINK.c) $< $(LDFLAGS) $(LIBS)
+
+record: record.o $(LIBRARY)
+ $(LINK.c) $< $(LDFLAGS) $(LIBS)
+
+inq_num_vars: inq_num_vars.o $(LIBRARY)
+ $(LINK.c) $< $(LDFLAGS) $(LIBS)
+
+varn_int: varn_int.o $(LIBRARY)
+ $(LINK.c) $< $(LDFLAGS) $(LIBS)
+
+varn_contig: varn_contig.o $(LIBRARY)
+ $(LINK.c) $< $(LDFLAGS) $(LIBS)
+
+modes: modes.o $(LIBRARY)
+ $(LINK.c) $< $(LDFLAGS) $(LIBS)
+
+one_record: one_record.o $(LIBRARY)
+ $(LINK.c) $< $(LDFLAGS) $(LIBS)
+
+inq_recsize: inq_recsize.o $(LIBRARY)
+ $(LINK.c) $< $(LDFLAGS) $(LIBS)
+
+test_vard: test_vard.o $(LIBRARY)
+ $(LINK.c) $< $(LDFLAGS) $(LIBS)
+
+profile: profile.o $(LIBRARY)
+ $(LINK.c) $< $(LDFLAGS) $(LIBS)
+
+ivarn: ivarn.o $(LIBRARY)
+ $(LINK.c) $< $(LDFLAGS) $(LIBS)
+
+check_striping: check_striping.o $(LIBRARY)
+ $(LINK.c) $< $(LDFLAGS) $(LIBS)
+
+add_var: add_var.o $(LIBRARY)
+ $(LINK.c) $< $(LDFLAGS) $(LIBS)
+
+buftype_free: buftype_free.o $(LIBRARY)
+ $(LINK.c) $< $(LDFLAGS) $(LIBS)
+
+last_large_var: last_large_var.o $(LIBRARY)
+ $(LINK.c) $< $(LDFLAGS) $(LIBS)
+
+check_type: check_type.o $(LIBRARY)
+ $(LINK.c) $< $(LDFLAGS) $(LIBS)
+
+test_erange: test_erange.o $(LIBRARY)
+ $(LINK.c) $< $(LDFLAGS) $(LIBS)
+
+inq_num_varsf: inq_num_varsf.o $(LIBRARY)
+ $(LINK.F90) $< $(LDFLAGS) $(LIBS)
+
+inq_recsizef: inq_recsizef.o $(LIBRARY)
+ $(LINK.F90) $< $(LDFLAGS) $(LIBS)
+
+test_vardf: test_vardf.o $(LIBRARY)
+ $(LINK.F90) $< $(LDFLAGS) $(LIBS)
+
+varn_intf: varn_intf.o $(LIBRARY)
+ $(LINK.F90) $< $(LDFLAGS) $(LIBS)
+
+attrf: attrf.o $(LIBRARY)
+ $(LINK.F90) $< $(LDFLAGS) $(LIBS)
+
+buftype_freef: buftype_freef.o $(LIBRARY)
+ $(LINK.F90) $< $(LDFLAGS) $(LIBS)
+
+put_parameter: put_parameter.o $(LIBRARY)
+ $(LINK.F90) $< $(LDFLAGS) $(LIBS)
+
+test_vardf90: test_vardf90.o $(LIBRARY)
+ $(LINK.F90) $< $(LDFLAGS) $(LIBS)
+
+varn_real: varn_real.o $(LIBRARY)
+ $(LINK.F90) $< $(LDFLAGS) $(LIBS)
+
+testing check verbose_testing : $(PROGS)
+ $(RM) -f $(TEST_OUTDIR)/testfile.nc $(TEST_OUTDIR)/redef1.nc
+ for i in $(PROGS); do ( \
+ $(TEST_SEQRUN) ./$$i $(TEST_OUTDIR)/testfile.nc \
+ ; ) ; done
+ $(TEST_SEQRUN) ./redef1 $(TEST_OUTDIR)/testfile.nc
+ $(TEST_SEQRUN) $(NCMPIGEN) -v 2 -o $(TEST_OUTDIR)/redef1.nc $(srcdir)/redef-good.ncdump
+ $(TEST_SEQRUN) $(NCMPIDIFF) $(TEST_OUTDIR)/testfile.nc $(TEST_OUTDIR)/redef1.nc
+
+# Some of these tests are designed to run on one process,
+# Run them on 4 processes to see if they can handle well
+# Some of these tests are designed to run on 4 processes,
+# Run them on 2, 4, and 6 processes to see if they can handle well
+TEST_MPIRUN_2 = $(subst NP,2,$(TEST_MPIRUN))
+TEST_MPIRUN_4 = $(subst NP,4,$(TEST_MPIRUN))
+TEST_MPIRUN_6 = $(subst NP,6,$(TEST_MPIRUN))
+
+ptest4: $(PROGS)
+ $(RM) -f $(TEST_OUTDIR)/testfile.nc $(TEST_OUTDIR)/redef1.nc
+ for i in $(PROGS); do ( \
+ $(TEST_MPIRUN_4) ./$$i $(TEST_OUTDIR)/testfile.nc \
+ ; ) ; done
+
+ptest2: $(PROGS)
+ $(RM) -f $(TEST_OUTDIR)/testfile.nc $(TEST_OUTDIR)/redef1.nc
+ for i in $(PROGS); do ( \
+ $(TEST_MPIRUN_2) ./$$i $(TEST_OUTDIR)/testfile.nc \
+ ; ) ; done
+
+ptest6: $(PROGS)
+ $(RM) -f $(TEST_OUTDIR)/testfile.nc $(TEST_OUTDIR)/redef1.nc
+ for i in $(PROGS); do ( \
+ $(TEST_MPIRUN_6) ./$$i $(TEST_OUTDIR)/testfile.nc \
+ ; ) ; done
+
+ptest: ptest4
+ptests: ptest2 ptest4 ptest6
+ptest8 ptest10:
+
+include $(srcdir)/../../rules.make
+include $(srcdir)/depend
+
+$(LIBRARY): ;
+
diff --git a/test/testcases/add_var.c b/test/testcases/add_var.c
new file mode 100644
index 0000000..725f29d
--- /dev/null
+++ b/test/testcases/add_var.c
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2015, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ *
+ * $Id: add_var.c 2169 2015-11-10 22:44:11Z wkliao $
+ */
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ *
+ * This program adds two new variables to an existing netCDF file.
+ * It is used to test if PnetCDF can correctly calculate the file offsets
+ * for the two new variables, in particular for files that align the
+ * fix-size variables to a boundary larger than 4 bytes, for instance
+ * a file created by PnetCDF with defaut alignment of 512 bytes.
+ *
+ * The compile and run commands are given below.
+ *
+ * % mpicc -g -o add_var add_var.c -lpnetcdf
+ *
+ * % mpiexec -l -n 1 add_var testfile.nc
+ *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <pnetcdf.h>
+
+#include <testutils.h>
+
+#define ERR {if(err!=NC_NOERR){printf("Error at line=%d: %s\n", __LINE__, ncmpi_strerror(err));}}
+
+int main(int argc, char** argv) {
+ char filename[256], var_name[NC_MAX_NAME];
+ int i, nvars, rank, nprocs, err, nerrs=0;
+ int ncid, varid, dimid[2];
+ MPI_Offset prev_off, off;
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+
+ if (argc > 2) {
+ if (!rank) printf("Usage: %s [filename]\n",argv[0]);
+ MPI_Finalize();
+ return 0;
+ }
+ strcpy(filename, "testfile.nc");
+ if (argc == 2) strcpy(filename, argv[1]);
+ MPI_Bcast(filename, 256, MPI_CHAR, 0, MPI_COMM_WORLD);
+
+ if (rank == 0) {
+ char cmd_str[256];
+ sprintf(cmd_str, "*** TESTING C %s for checking offsets of new variables ", argv[0]);
+ printf("%-66s ------ ", cmd_str); fflush(stdout);
+ }
+
+ err = ncmpi_create(MPI_COMM_WORLD, filename, NC_CLOBBER, MPI_INFO_NULL, &ncid); ERR
+
+ /* define dimensions */
+ err = ncmpi_def_dim(ncid, "dim_1", 5, &dimid[0]); ERR
+ err = ncmpi_def_dim(ncid, "dim_2", 4, &dimid[1]); ERR
+
+ /* define a bunch of variables */
+ for (i=0; i<10; i++) {
+ sprintf(var_name, "var_%d", i);
+ err = ncmpi_def_var(ncid, var_name, NC_INT, 2, dimid, &varid); ERR
+ }
+ err = ncmpi_enddef(ncid); ERR
+
+ /* re-enter define mode */
+ err = ncmpi_redef(ncid); ERR
+
+ /* add 2 new dimensions */
+ err = ncmpi_def_dim(ncid, "new_dim_1", 5, &dimid[0]); ERR
+ err = ncmpi_def_dim(ncid, "new_dim_2", 4, &dimid[1]); ERR
+
+ /* add 2 new dimensions */
+ err = ncmpi_def_var(ncid, "new_var1", NC_INT, 2, dimid, &varid); ERR
+ err = ncmpi_def_var(ncid, "new_var2", NC_FLOAT, 2, dimid, &varid); ERR
+ err = ncmpi_enddef(ncid); ERR
+
+ err = ncmpi_inq_nvars(ncid, &nvars); ERR
+ err = ncmpi_inq_varoffset(ncid, 0, &prev_off); ERR
+ for (i=1; i<nvars; i++) {
+ err = ncmpi_inq_varoffset(ncid, i, &off); ERR
+ if (off < prev_off + 5*4*4) { /* each variable is of size 5*4*4 bytes */
+ err = ncmpi_inq_varname(ncid, i, var_name); ERR
+ printf("Error in %s line %d: variable %s offset is set incorrectly\n",
+ __FILE__,__LINE__,var_name);
+ nerrs++;
+ }
+ prev_off = off;
+ }
+
+ err = ncmpi_close(ncid); ERR
+
+ /* check if PnetCDF freed all internal malloc */
+ MPI_Offset malloc_size, sum_size;
+ err = ncmpi_inq_malloc_size(&malloc_size);
+ if (err == NC_NOERR) {
+ MPI_Reduce(&malloc_size, &sum_size, 1, MPI_OFFSET, MPI_SUM, 0, MPI_COMM_WORLD);
+ if (rank == 0 && sum_size > 0)
+ printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n",
+ sum_size);
+ }
+
+ MPI_Allreduce(MPI_IN_PLACE, &nerrs, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
+ if (rank == 0) {
+ if (nerrs) printf(FAIL_STR,nerrs);
+ else printf(PASS_STR);
+ }
+
+ MPI_Finalize();
+ return 0;
+}
+
diff --git a/test/testcases/alignment_test.c b/test/testcases/alignment_test.c
new file mode 100644
index 0000000..862ce02
--- /dev/null
+++ b/test/testcases/alignment_test.c
@@ -0,0 +1,295 @@
+/*
+ * Copyright (C) 2003, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ *
+ * $Id: alignment_test.c 2133 2015-09-26 19:16:01Z wkliao $
+ */
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ *
+ * This program tests if the file header size and variable offsets are properly
+ * set when using a different set of alignment hints to open an existing file
+ * and entering the redef mode to add more dimensions, attributes, and
+ * variables, causing the expansion of the header.
+ *
+ * The compile and run commands are given below.
+ *
+ * % mpicc -g -o alignment_test alignment_test.c -lpnetcdf
+ *
+ * % mpiexec -l -n 4 alignment_test testfile.nc
+ *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <mpi.h>
+#include <pnetcdf.h>
+
+#include <testutils.h>
+
+#define NVARS 8
+#define NX 5
+
+#define ERR {if(err!=NC_NOERR){nerrs++;printf("Error at line=%d: %s\n", __LINE__, ncmpi_strerror(err));}}
+
+int main(int argc, char** argv) {
+ char *filename="redef1.nc";
+ int i, j, rank, nprocs, err, verbose=0, nerrs=0;
+ int ncid, cmode, varid[NVARS], dimid[2], *buf;
+ char str[32];
+ MPI_Offset start[2], count[2];
+ MPI_Offset new_var_off[NVARS*2], old_var_off[NVARS*2];
+ MPI_Offset header_size[2], header_extent[2];
+ MPI_Info info=MPI_INFO_NULL;
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+
+ if (argc > 2) {
+ if (!rank) printf("Usage: %s [filename]\n",argv[0]);
+ MPI_Finalize();
+ return 0;
+ }
+ if (argc == 2) filename = argv[1];
+
+ if (rank == 0) {
+ char cmd_str[256];
+ sprintf(cmd_str, "*** TESTING C %s for alignment ", argv[0]);
+ printf("%-66s ------ ", cmd_str); fflush(stdout);
+ }
+
+ /* create a new file for writing ----------------------------------------*/
+ cmode = NC_CLOBBER | NC_64BIT_DATA;
+ err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, info, &ncid); ERR
+
+ /* define dimension */
+ err = ncmpi_def_dim(ncid, "Y", NC_UNLIMITED, &dimid[0]); ERR
+ err = ncmpi_def_dim(ncid, "X", NX*nprocs, &dimid[1]); ERR
+
+#define TEST_FIXED_VAR
+#define TEST_RECORD_VAR
+ /* Odd numbers are fixed variables, even numbers are record variables */
+ for (i=0; i<NVARS; i++) {
+#ifdef TEST_FIXED_VAR
+ if (i%2) {
+ sprintf(str,"fixed_var_%d",i);
+ err = ncmpi_def_var(ncid, str, NC_INT, 1, dimid+1, &varid[i]); ERR
+ }
+#endif
+#ifdef TEST_RECORD_VAR
+ if (i%2 == 0) {
+ sprintf(str,"record_var_%d",i);
+ err = ncmpi_def_var(ncid, str, NC_INT, 2, dimid, &varid[i]); ERR
+ }
+#endif
+ }
+ err = ncmpi_enddef(ncid); ERR
+
+ /* write all variables */
+ buf = (int*) malloc(NX * sizeof(int));
+ for (i=0; i<NVARS; i++) {
+ for (j=0; j<NX; j++) buf[j] = rank*1000 + i*10 + j;
+#ifdef TEST_FIXED_VAR
+ if (i%2) {
+ start[0] = NX*rank;
+ count[0] = NX;
+ err = ncmpi_put_vara_int_all(ncid, varid[i], start, count, buf); ERR
+ }
+#endif
+#ifdef TEST_RECORD_VAR
+ if (i%2 == 0) {
+ start[0] = 0; start[1] = NX*rank;
+ count[0] = 1; count[1] = NX;
+ err = ncmpi_put_vara_int_all(ncid, varid[i], start, count, buf); ERR
+ for (j=0; j<NX; j++) buf[j] = rank*1000 + 100 + i*10 + j;
+ start[0] = 1; /* write 2nd record */
+ err = ncmpi_put_vara_int_all(ncid, varid[i], start, count, buf); ERR
+ }
+#endif
+ }
+ err = ncmpi_close(ncid); ERR
+
+ /* Now, reopen the file and grow the header and read data back */
+
+ /* mimic netCDF that does not do alignments */
+ MPI_Info_create(&info);
+ MPI_Info_set(info, "nc_header_align_size", "1"); /* size in bytes */
+ MPI_Info_set(info, "nc_var_align_size", "197"); /* size in bytes */
+
+ /* open the file for adding more metadata */
+ err = ncmpi_open(MPI_COMM_WORLD, filename, NC_WRITE, info, &ncid); ERR
+
+ /* get header size and extent, and offsets of all variables */
+ err = ncmpi_inq_header_size(ncid, &header_size[0]); ERR
+ err = ncmpi_inq_header_extent(ncid, &header_extent[0]); ERR
+ for (i=0; i<NVARS; i++) {
+#ifdef TEST_FIXED_VAR
+ if (i%2)
+ err = ncmpi_inq_varoffset(ncid, varid[i], &old_var_off[i]);
+#endif
+#ifdef TEST_RECORD_VAR
+ if (i%2==0)
+ err = ncmpi_inq_varoffset(ncid, varid[i], &old_var_off[i]);
+#endif
+ ERR
+ }
+
+ /* enter redef mode */
+ err = ncmpi_redef(ncid); ERR
+
+ /* add attributes to make header grow */
+ for (i=0; i<NVARS; i++) {
+ sprintf(str, "annotation_for_var_%d",i);
+#ifdef TEST_FIXED_VAR
+ if (i%2)
+ err = ncmpi_put_att_text(ncid, varid[i], "text_attr", strlen(str), str);
+#endif
+#ifdef TEST_RECORD_VAR
+ if (i%2==0)
+ err = ncmpi_put_att_text(ncid, varid[i], "text_attr", strlen(str), str);
+#endif
+ ERR
+ }
+
+ /* add new dimensions */
+ int new_dimid[3];
+ err = ncmpi_def_dim(ncid, "new_dim_a", 5, &new_dimid[0]); ERR
+ err = ncmpi_def_dim(ncid, "new_dim_b", 4, &new_dimid[1]); ERR
+ err = ncmpi_def_dim(ncid, "new_dim_c", NX*nprocs, &new_dimid[2]); ERR
+
+ /* add new variables */
+ int new_varid[NVARS];
+ for (i=0; i<NVARS; i++) {
+#ifdef TEST_FIXED_VAR
+ if (i%2 == 0) {
+ sprintf(str,"fixed_var_%d",i+NVARS);
+ err = ncmpi_def_var(ncid, str, NC_INT, 1, new_dimid+2, &new_varid[i]); ERR
+ }
+#endif
+#ifdef TEST_RECORD_VAR
+ if (i%2 == 1) {
+ sprintf(str,"record_var_%d",i+NVARS);
+ err = ncmpi_def_var(ncid, str, NC_INT, 2, dimid, &new_varid[i]); ERR
+ }
+#endif
+ }
+ err = ncmpi_enddef(ncid); ERR
+
+ /* get the new header size and extent, also all variables' starting
+ file offsets */
+ err = ncmpi_inq_header_size(ncid, &header_size[1]); ERR
+ err = ncmpi_inq_header_extent(ncid, &header_extent[1]); ERR
+ if (rank == 0 && verbose) {
+ printf("NX = %d (integer type)\n",NX);
+ printf("old header_size =%lld new header_size =%lld\n",header_size[0],header_size[1]);
+ printf("old header_extent=%lld new header_extent=%lld\n",header_extent[0],header_extent[1]);
+
+#ifdef TEST_FIXED_VAR
+ for (i=1; i<NVARS; i+=2) {
+ err = ncmpi_inq_varoffset(ncid, varid[i], &new_var_off[i]); ERR
+ printf("old fixed var[%2d] old offset=%4lld new offset=%4lld\n",i,old_var_off[i],new_var_off[i]);
+ }
+ for (i=NVARS; i<2*NVARS; i++) {
+ if (i%2 == 0) {
+ err = ncmpi_inq_varoffset(ncid, new_varid[i-NVARS], &new_var_off[i]); ERR
+ printf("new fixed var[%2d] new offset=%4lld\n",i,new_var_off[i]);
+ }
+ }
+#endif
+#ifdef TEST_RECORD_VAR
+ for (i=0; i<NVARS; i+=2) {
+ err = ncmpi_inq_varoffset(ncid, varid[i], &new_var_off[i]); ERR
+ printf("old record var[%2d] old offset=%4lld new offset=%4lld\n",i,old_var_off[i],new_var_off[i]);
+ }
+ for (i=NVARS; i<2*NVARS; i++) {
+ if (i%2) {
+ err = ncmpi_inq_varoffset(ncid, new_varid[i-NVARS], &new_var_off[i]); ERR
+ printf("new record var[%2d] new offset=%4lld\n",i,new_var_off[i]);
+ }
+ }
+#endif
+ }
+
+ /* write to the new variables */
+ for (i=0; i<NVARS; i++) {
+ for (j=0; j<NX; j++) buf[j] = -1 * (i*10 + j);
+#ifdef TEST_FIXED_VAR
+ if (i%2 == 0) {
+ start[0] = NX*rank;
+ count[0] = NX;
+ err = ncmpi_put_vara_int_all(ncid, new_varid[i], start, count, buf); ERR
+ }
+#endif
+#ifdef TEST_RECORD_VAR
+ if (i%2 == 1) {
+ start[0] = 0; start[1] = NX*rank;
+ count[0] = 1; count[1] = NX;
+ err = ncmpi_put_vara_int_all(ncid, new_varid[i], start, count, buf); ERR
+ for (j=0; j<NX; j++) buf[j] = -1 * (100 + i*10 + j);
+ start[0] = 1; /* write 2nd record */
+ err = ncmpi_put_vara_int_all(ncid, new_varid[i], start, count, buf); ERR
+ }
+#endif
+ }
+
+ /* read old variables and check their contents */
+ for (i=0; i<NVARS; i++) {
+#ifdef TEST_FIXED_VAR
+ if (i%2) {
+ start[0] = NX*rank;
+ count[0] = NX;
+ err = ncmpi_get_vara_int_all(ncid, varid[i], start, count, buf); ERR
+ for (j=0; j<NX; j++)
+ if (buf[j] != rank*1000 + i*10 + j) {
+ printf("read error i=%d buf[j=%d]=%d != %d\n",i,j,buf[j],rank*1000+i*10+j);
+ nerrs++;
+ }
+ }
+#endif
+#ifdef TEST_RECORD_VAR
+ if (i%2 == 0) {
+ start[0] = 0; start[1] = NX*rank;
+ count[0] = 1; count[1] = NX;
+ err = ncmpi_get_vara_int_all(ncid, varid[i], start, count, buf); ERR
+ for (j=0; j<NX; j++)
+ if (buf[j] != rank*1000+i*10+j) {
+ printf("read error i=%d buf[j=%d]=%d != %d\n",i,j,buf[j],rank*1000+i*10+j);
+ nerrs++;
+ }
+ start[0] = 1;
+ err = ncmpi_get_vara_int_all(ncid, varid[i], start, count, buf); ERR
+ for (j=0; j<NX; j++)
+ if (buf[j] != rank*1000 + 100 + i*10 + j) {
+ printf("read error i=%d buf[j=%d]=%d != %d\n",i,j,buf[j],rank*1000+100+i*10+j);
+ nerrs++;
+ }
+ }
+#endif
+ }
+ err = ncmpi_close(ncid); ERR
+ MPI_Info_free(&info);
+ free(buf);
+
+ /* check if PnetCDF freed all internal malloc */
+ MPI_Offset malloc_size, sum_size;
+ err = ncmpi_inq_malloc_size(&malloc_size);
+ if (err == NC_NOERR) {
+ MPI_Reduce(&malloc_size, &sum_size, 1, MPI_OFFSET, MPI_SUM, 0, MPI_COMM_WORLD);
+ if (rank == 0 && sum_size > 0)
+ printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n",
+ sum_size);
+ }
+
+ MPI_Allreduce(MPI_IN_PLACE, &nerrs, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
+ if (rank == 0) {
+ if (nerrs) printf(FAIL_STR,nerrs);
+ else printf(PASS_STR);
+ }
+
+ MPI_Finalize();
+ return 0;
+}
+
diff --git a/test/testcases/attrf.f b/test/testcases/attrf.f
new file mode 100644
index 0000000..cf3eddf
--- /dev/null
+++ b/test/testcases/attrf.f
@@ -0,0 +1,156 @@
+!
+! Copyright (C) 2015, Northwestern University and Argonne National Laboratory
+! See COPYRIGHT notice in top-level directory.
+!
+! $Id: attrf.f 2263 2015-12-22 15:42:05Z wkliao $
+
+! This program tests if NF_ERANGE is properly returned with a coredump
+! when an out-of-range value is used to write to a global attribute.
+! When using NAG Fortran compiler, "Arithmetic exception" and coredump
+! happens.
+!
+! % mpif77 -O2 -o attrf attrf.f -lpnetcdf
+! % mpiexec -n 1 ./attrf /pvfs2/wkliao/testfile.nc
+!
+
+ INTEGER FUNCTION XTRIM(STRING)
+ CHARACTER*(*) STRING
+ INTEGER I, N
+ N = LEN(STRING)
+ DO I = N, 1, -1
+ IF (STRING(I:I) .NE. ' ') GOTO 10
+ ENDDO
+ 10 XTRIM = I
+ END ! FUNCTION XTRIM
+
+ subroutine check(err, message, nerrs)
+ implicit none
+ include "mpif.h"
+ include "pnetcdf.inc"
+ integer err, nerrs, XTRIM
+ character*(*) message
+ character*128 msg
+
+ ! It is a good idea to check returned value for possible error
+ if (err .NE. NF_NOERR) then
+ write(6,*) message(1:XTRIM(message)), nfmpi_strerror(err)
+ msg = '*** TESTING F77 attrf.f for attribute overflow '
+ call pass_fail(1, msg)
+ nerrs = nerrs + 1
+ end if
+ end ! subroutine check
+
+ program main
+ implicit none
+ include "mpif.h"
+ include "pnetcdf.inc"
+
+ real buf_flt
+ double precision buf_dbl
+ integer buf_int, XTRIM
+ integer*2 buf_int2
+ integer*8 buf_int8, one
+
+ character*256 filename, cmd, msg
+ integer ncid, err, ierr, nerrs, nprocs, rank, get_args
+ integer*8 malloc_size, sum_size
+
+ call MPI_Init(ierr)
+ call MPI_Comm_rank(MPI_COMM_WORLD, rank, ierr)
+ call MPI_Comm_size(MPI_COMM_WORLD, nprocs, ierr)
+
+ one = 1
+ ! take filename from command-line argument if there is any
+ if (rank .EQ. 0) then
+ filename = "testfile.nc"
+ err = get_args(cmd, filename)
+ endif
+ call MPI_Bcast(err, 1, MPI_INTEGER, 0, MPI_COMM_WORLD, ierr)
+ if (err .EQ. 0) goto 999
+
+ call MPI_Bcast(filename, 256, MPI_CHARACTER, 0,
+ + MPI_COMM_WORLD, ierr)
+
+ nerrs = 0
+
+ err = nfmpi_create(MPI_COMM_WORLD, filename, NF_CLOBBER,
+ + MPI_INFO_NULL, ncid)
+ call check(err, 'In nfmpi_create: ', nerrs)
+
+ ! use a number > X_INT_MAX (which is 2147483647)
+ buf_flt = 2147483648.0
+ buf_dbl = 2147483648.0
+ buf_int8 = 1073741824
+ buf_int8 = buf_int8 * 2
+
+ err = nfmpi_put_att_real(ncid, NF_GLOBAL, "attr1", NF_INT,
+ + one, buf_flt)
+ if (err .NE. NF_ERANGE) then
+ print*, "Error: expect NF_ERANGE but got ", err
+ if (err .NE. NF_NOERR) print*, nfmpi_strerror(err)
+ nerrs = nerrs + 1
+ ! Note: even with an error, the attribute is still being created
+ endif
+
+ err = nfmpi_put_att_double(ncid, NF_GLOBAL, "attr2", NF_INT,
+ + one, buf_dbl)
+ if (err .NE. NF_ERANGE) then
+ print*, "Error: expect NF_ERANGE but got ", err
+ if (err .NE. NF_NOERR) print*, nfmpi_strerror(err)
+ nerrs = nerrs + 1
+ ! Note: even with an error, the attribute is still being created
+ endif
+
+ err = nfmpi_put_att_int8(ncid, NF_GLOBAL, "attr3", NF_INT,
+ + one, buf_int8)
+ if (err .NE. NF_ERANGE) then
+ print*, "Error: expect NF_ERANGE but got ", err
+ if (err .NE. NF_NOERR) print*, nfmpi_strerror(err)
+ nerrs = nerrs + 1
+ ! Note: even with an error, the attribute is still being created
+ endif
+
+ buf_int = 2147483647
+ err = nfmpi_put_att_int(ncid, NF_GLOBAL, "attr4", NF_INT,
+ + one, buf_int)
+ call check(err, 'In nfmpi_put_att_int: ', nerrs)
+
+ ! because of the NF_ERANGE error, the attributes may become
+ ! inconsistent among processes, So NC_EMULTIDEFINE_ATTR_VAL
+ ! or NF_EMULTIDEFINE may be returned from nfmpi_enddef.
+ ! While in safe mode, the warning message of inconsistent metadata
+ ! may appear on the screen. This is expected.
+ err = nfmpi_enddef(ncid)
+ if (err .NE. NF_NOERR .AND. err .NE. NF_EMULTIDEFINE .AND.
+ + err .NE. NF_EMULTIDEFINE_ATTR_VAL)
+ + call check(err, 'In nfmpi_enddef: ', nerrs)
+
+ err = nfmpi_get_att_int2(ncid, NF_GLOBAL, "attr4", buf_int2)
+ if (err .NE. NF_ERANGE) then
+ print*, "Error: expect NF_ERANGE but got ", err
+ if (err .NE. NF_NOERR) print*, nfmpi_strerror(err)
+ nerrs = nerrs + 1
+ endif
+
+ err = nfmpi_close(ncid)
+ call check(err, 'In nfmpi_close: ', nerrs)
+
+ ! check if there is any PnetCDF internal malloc residue
+ 998 format(A,I13,A)
+ err = nfmpi_inq_malloc_size(malloc_size)
+ if (err .EQ. NF_NOERR) then
+ call MPI_Reduce(malloc_size, sum_size, 1, MPI_OFFSET,
+ + MPI_SUM, 0, MPI_COMM_WORLD, ierr)
+ if (rank .EQ. 0 .AND. sum_size .GT. 0)
+ + print 998,
+ + 'heap memory allocated by PnetCDF internally has ',
+ + sum_size/1048576, ' MiB yet to be freed'
+ endif
+
+ msg ='*** TESTING F77 '//cmd(1:XTRIM(cmd))//
+ + ' for attribute overflow '
+ if (rank .eq. 0) call pass_fail(nerrs, msg)
+
+ 999 call MPI_Finalize(ierr)
+
+ end ! program main
diff --git a/test/testcases/bigrecords.f b/test/testcases/bigrecords.f
new file mode 100644
index 0000000..eed43f9
--- /dev/null
+++ b/test/testcases/bigrecords.f
@@ -0,0 +1,338 @@
+!
+! Copyright (C) 2003, Northwestern University and Argonne National Laboratory
+! See COPYRIGHT notice in top-level directory.
+!
+! $Id: bigrecords.f 2224 2015-12-16 06:10:36Z wkliao $
+
+!
+! this test case came from Annette Koonts at PNNL
+!
+! test creates a dataset with several (large) record variables, but also a
+! smaller 'time' record variable.
+!
+! on 64 bit systems or on BlueGene (where MPI_AINT is 32 bits), this test will
+! read the smaller time variable OK, but on systems with a 32 bit MPI_AINT, the
+! time variable will be garbled.
+
+ INTEGER FUNCTION XTRIM(STRING)
+ CHARACTER*(*) STRING
+ INTEGER I, N
+ N = LEN(STRING)
+ DO I = N, 1, -1
+ IF (STRING(I:I) .NE. ' ') GOTO 10
+ ENDDO
+ 10 XTRIM = I
+ END ! FUNCTION XTRIM
+
+ program main
+ implicit none
+ include "mpif.h"
+ include "pnetcdf.inc"
+
+
+! error status return
+ integer iret
+! netCDF id
+ integer ncid
+! dimension ids
+ integer time_dim
+ integer cells_dim
+ integer interfaces_dim
+ integer XTRIM
+
+! dimension lengths
+ integer*8 cells_len
+ integer interfaces_len
+
+ parameter (cells_len = 41943042)
+ parameter (interfaces_len = 26)
+
+! variable ids
+ integer time_id
+ integer interfaces_id
+ integer pressure_id
+
+ integer (kind=MPI_OFFSET_KIND) :: longlen
+
+ integer (kind=MPI_OFFSET_KIND) :: start1d(1)
+ integer (kind=MPI_OFFSET_KIND) :: count1d(1)
+
+! rank (number of dimensions) for each variable
+ integer time_rank
+ integer interfaces_rank
+ integer pressure_rank
+
+ parameter (time_rank = 1)
+ parameter (interfaces_rank = 1)
+ parameter (pressure_rank = 3)
+
+! variable shapes
+ integer time_dims(time_rank)
+ integer interfaces_dims(interfaces_rank)
+ integer pressure_dims(pressure_rank)
+
+! data variables
+ real interfaces(interfaces_len)
+
+ integer myid, err, ierr, n, get_args
+ integer numprocs
+
+ integer*8 i8_size
+
+ integer*8 time_start(1), time_count(1)
+
+ double precision time(4)
+! data time /0., 20., 40., 60./
+
+ data interfaces /2685.8359, 671.81, 495.91, 425.10001, 393.42999,
+ + 377.5, 367.59, 360.06, 353.85999, 348.66, 342.5, 336, 328.5, 320,
+ + 310, 300, 290, 280, 270, 260, 250, 240, 230, 220, 210, 199.10001/
+
+ character*256 filename, cmd, msg
+
+! attribute vectors
+! enter define mode
+! iret = nf_create('pressure_19010101_000000.nc', OR(NF_CLOBBER,NF_64BIT_OFFSET), ncid)
+
+ call MPI_INIT(ierr)
+ call MPI_COMM_RANK(MPI_COMM_WORLD, myid, ierr)
+ call MPI_COMM_SIZE(MPI_COMM_WORLD, numprocs, ierr)
+
+ if (myid .EQ. 0) then
+ filename = "testfile.nc"
+ err = get_args(cmd, filename)
+ endif
+ call MPI_Bcast(err, 1, MPI_INTEGER, 0, MPI_COMM_WORLD, ierr)
+ if (err .EQ. 0) goto 999
+
+ call MPI_Bcast(filename, 256, MPI_CHARACTER, 0, MPI_COMM_WORLD,
+ + ierr)
+
+ iret = nfmpi_create( MPI_COMM_WORLD, filename,
+ + IOR(NF_CLOBBER,NF_64BIT_DATA),
+ + MPI_INFO_NULL, ncid)
+
+ call check_err("nfmpi_create(): ", iret)
+
+! define dimensions
+
+ iret = nfmpi_def_dim(ncid, 'time', NFMPI_UNLIMITED, time_dim)
+ call check_err("nfmpi_def_dim(): time ", iret)
+
+ i8_size = 41943042
+
+ iret = nfmpi_def_dim(ncid, 'cells', i8_size, cells_dim)
+ call check_err("nfmpi_def_dim(): cells ", iret)
+
+ i8_size = 26
+ iret = nfmpi_def_dim(ncid, 'interfaces',
+ + i8_size, interfaces_dim)
+ call check_err("nfmpi_def_dim(): interfaces ", iret)
+! define variables
+ time_dims(1) = time_dim
+
+ iret = nfmpi_def_var(ncid, 'time', NF_DOUBLE,
+ + time_rank, time_dims,
+ + time_id)
+ call check_err("nfmpi_def_var(): time ", iret)
+ interfaces_dims(1) = interfaces_dim
+
+ iret = nfmpi_def_var(ncid, 'interfaces', NF_REAL,
+ + interfaces_rank,
+ + interfaces_dims, interfaces_id)
+ call check_err("nfmpi_def_var(): interfaces ", iret)
+
+ pressure_dims(3) = time_dim
+ pressure_dims(2) = cells_dim
+ pressure_dims(1) = interfaces_dim
+ iret = nfmpi_def_var(ncid,
+ + 'pressure',
+ + NF_REAL,
+ + pressure_rank,
+ + pressure_dims,
+ + pressure_id)
+
+ call check_err("nfmpi_def_var(): pressure ", iret)
+! assign attributes
+
+ longlen = 4
+ iret = nfmpi_put_att_text(ncid, time_id, 'long_name',
+ + longlen, 'Time')
+ call check_err("nfmpi_put_att_text(): long_name ", iret)
+ longlen = 21
+ iret = nfmpi_put_att_text(ncid, time_id, 'units',
+ + longlen,
+ + 'days since 1901-01-01')
+ call check_err("nfmpi_put_att_text(): units ", iret)
+
+ longlen = 41
+ iret = nfmpi_put_att_text(ncid, interfaces_id, 'long_name',
+ + longlen,
+ + 'Vertical interfaces, in terms of pressure')
+ call check_err("nfmpi_put_att_text(): long_name ", iret)
+
+ longlen = 2
+ iret = nfmpi_put_att_text(ncid, interfaces_id, 'units',
+ + longlen, 'Pa')
+ call check_err("nfmpi_put_att_text(): units ", iret)
+
+ longlen = 8
+ iret = nfmpi_put_att_text(ncid, pressure_id, 'long_name',
+ + longlen,
+ 1 'Pressure')
+ call check_err("nfmpi_put_att_text(): ", iret)
+
+ longlen = 2
+ iret = nfmpi_put_att_text(ncid, pressure_id, 'units',
+ + longlen, 'Pa')
+ call check_err("nfmpi_put_att_text(): units ", iret)
+
+! leave define mode
+ iret = nfmpi_enddef(ncid)
+ call check_err("nfmpi_enddef(): ", iret)
+
+ start1d(1) = 1
+ count1d(1) = 26
+ if (myid .GT. 0) count1d = 0
+
+! store interfaces
+ iret = nfmpi_put_vara_real_all(ncid, interfaces_id,
+ + start1d, count1d, interfaces)
+ call check_err("nfmpi_put_vara_real_all(): ", iret)
+
+ time(1) = 0.0
+ time(2) = 20.0
+ time(3) = 40.0
+ time(4) = 60.0
+
+! this test is tricky because it writes out the time variable one at a time.
+! This element-at-a-time workload does not actually exercise the tricky 32 bit
+! MPI_AINT problem, so the issue only shows up at read time.
+
+ do n = 1, 4
+ time_start(1) = n
+ if(myid .eq. 0) then
+ time_count(1) = 1
+ else
+ time_count(1) = 0
+ endif
+
+ iret = nfmpi_put_vara_double_all(ncid, time_id,
+ + time_start, time_count,
+ + time(n))
+ call check_err("nfmpi_put_vara_double_all(): ", iret)
+ enddo
+
+ iret = nfmpi_close(ncid)
+
+ call MPI_Barrier (MPI_COMM_WORLD, iret)
+
+! todo: insert code to re-open dataset, read time variable all at onece
+!
+ iret = nfmpi_open ( MPI_COMM_SELF,
+ + filename,
+ + IOR(NF_CLOBBER,NF_64BIT_DATA),
+ + MPI_INFO_NULL,
+ + ncid)
+ call check_err("nfmpi_open(): ", iret)
+
+ iret = nfmpi_inq_varid(ncid, 'time', time_id);
+ call check_err("nfmpi_inq_varid(): time ", iret)
+
+ ! deliberately want all processes to end up with the full time array
+ time_start(1) = 1
+ time_count(1) = 4
+ iret = nfmpi_get_vara_double_all(ncid, time_id,
+ + time_start, time_count, time);
+ call check_err("nfmpi_get_vara_double_all(): ", iret)
+
+ iret = nfmpi_close(ncid)
+ call check_err("nfmpi_close(): ", iret)
+
+! write(6,*) "Time array: ", time
+! if ( (time(1) .eq. 0) .and. (time(2) .eq. 20.0)
+! & .and. (time(3) .eq. 40.0) .and. (time(4) .eq. 60))
+! write(6,*) " No Errors"
+! else
+! write(6,*) "Error: time array was ", time
+! endif
+
+ msg = '*** TESTING F77 '//cmd(1:XTRIM(cmd))//' for NF_64BIT_DATA'
+ if (myid .eq. 0) call pass_fail(0, msg)
+
+ 999 call MPI_FINALIZE(ierr)
+ end ! program main
+
+ subroutine writerecs(ncid,time_id)
+
+ implicit none
+ include "mpif.h"
+ include "pnetcdf.inc"
+
+! netCDF id
+ integer ncid
+! variable ids
+ integer time_id
+
+! error status return
+ integer iret
+ integer n
+
+! netCDF dimension sizes for dimensions used with record variables
+ integer cells_len
+ parameter (cells_len = 41943042)
+ integer interfaces_len
+ parameter (interfaces_len = 26)
+
+! rank (number of dimensions) for each variable
+ integer time_rank
+ integer pressure_rank
+ parameter (time_rank = 1)
+ parameter (pressure_rank = 3)
+! starts and counts for array sections of record variables
+ integer*8 time_start(1), time_count(1)
+
+! data variables
+
+ integer time_nr
+ parameter (time_nr = 4)
+
+ integer pressure_nr
+ parameter (pressure_nr = 1)
+! real pressure(interfaces_len, cells_len, pressure_nr)
+
+ double precision time(time_nr)
+ data time /0., 20., 40., 60./
+
+
+! pressure = NF_FILL_FLOAT
+
+! store time
+
+ do n = 1, 4
+ time_start(1) = n
+ time_count(1) = 1
+ iret = nfmpi_put_vara_double_all(ncid, time_id,
+ + time_start, time_count,
+ + time)
+
+ call check_err("nfmpi_put_vara_double_all(): ", iret)
+ enddo
+
+ end ! subroutine writerecs
+
+ subroutine check_err(msg, iret)
+
+ include "pnetcdf.inc"
+
+ character*(*) msg
+ integer iret
+
+ if (iret .ne. NF_NOERR) then
+ print *, msg, nfmpi_strerror(iret)
+ msg = '*** TESTING F77 '//cmd(1:XTRIM(cmd))//
+ + ' for NF_64BIT_DATA'
+ call pass_fail(1, msg)
+ stop
+ endif
+ end ! subroutine check_err
diff --git a/test/testcases/buftype_free.c b/test/testcases/buftype_free.c
new file mode 100644
index 0000000..aa0234f
--- /dev/null
+++ b/test/testcases/buftype_free.c
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2015, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ *
+ * $Id: buftype_free.c 2165 2015-11-05 07:18:49Z wkliao $
+ */
+
+/*
+ * This example tests if PnetCDF duplicates the MPI derived data type supplied
+ * by the user, when calling the flexible APIs. It tests a PnetCDF bug
+ * prior to version 1.6.1.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <mpi.h>
+#include <pnetcdf.h>
+
+#include <testutils.h>
+
+#define NY 4
+#define NX 4
+#define ERR if (err!=NC_NOERR) {printf("Error at line %d: %s\n", __LINE__,ncmpi_strerror(err)); exit(-1);}
+
+/*----< main() >------------------------------------------------------------*/
+int main(int argc, char **argv) {
+
+ char filename[256];
+ int i, j, err, ncid, varid[4], dimids[2], req[4], st[4], nerrs=0;
+ int rank, nprocs, buf[4][(NY+4)*(NX+4)];
+ int gsize[2], subsize[2], a_start[2], ghost;
+ MPI_Offset start[2], count[2];
+ MPI_Datatype buftype[4];
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+
+ if (argc > 2) {
+ if (!rank) printf("Usage: %s [filename]\n",argv[0]);
+ MPI_Finalize();
+ return 0;
+ }
+ strcpy(filename, "testfile.nc");
+ if (argc == 2) strcpy(filename, argv[1]);
+ MPI_Bcast(filename, 256, MPI_CHAR, 0, MPI_COMM_WORLD);
+
+ if (rank == 0) {
+ char cmd_str[256];
+ sprintf(cmd_str, "*** TESTING C %s for free buftype in flexible API ", argv[0]);
+ printf("%-66s ------ ", cmd_str); fflush(stdout);
+ }
+
+ err = ncmpi_create(MPI_COMM_WORLD, filename, NC_CLOBBER, MPI_INFO_NULL, &ncid); ERR
+
+ /* define a 2D array */
+ err = ncmpi_def_dim(ncid, "Y", NY*nprocs, &dimids[0]); ERR
+ err = ncmpi_def_dim(ncid, "X", NX, &dimids[1]); ERR
+ err = ncmpi_def_var(ncid, "var0", NC_INT, 2, dimids, &varid[0]); ERR
+ err = ncmpi_def_var(ncid, "var1", NC_INT, 2, dimids, &varid[1]); ERR
+ err = ncmpi_def_var(ncid, "var2", NC_INT, 2, dimids, &varid[2]); ERR
+ err = ncmpi_def_var(ncid, "var3", NC_INT, 2, dimids, &varid[3]); ERR
+ err = ncmpi_enddef(ncid); ERR
+
+ /* initialize the contents of the array */
+ for (i=0; i<4; i++) for (j=0; j<(NY+4)*(NX+4); j++) buf[i][j] = rank;
+
+ start[0] = NY*rank; start[1] = 0;
+ count[0] = NY; count[1] = NX;
+
+ err = ncmpi_put_vara_int_all(ncid, varid[0], start, count, buf[0]); ERR
+ err = ncmpi_put_vara_int_all(ncid, varid[1], start, count, buf[1]); ERR
+ err = ncmpi_put_vara_int_all(ncid, varid[2], start, count, buf[2]); ERR
+ err = ncmpi_put_vara_int_all(ncid, varid[3], start, count, buf[3]); ERR
+
+
+ /* define an MPI datatype using MPI_Type_create_subarray() */
+ ghost = 2;
+ gsize[1] = NX + 2 * ghost;
+ gsize[0] = NY + 2 * ghost;
+ subsize[1] = NX;
+ subsize[0] = NY;
+ a_start[1] = ghost;
+ a_start[0] = ghost;
+
+ for (i=0; i<4; i++) {
+ req[i] = NC_REQ_NULL;
+ st[i] = NC_NOERR;
+ MPI_Type_create_subarray(2, gsize, subsize, a_start, MPI_ORDER_C, MPI_INT, &buftype[i]);
+ MPI_Type_commit(&buftype[i]);
+
+ err = ncmpi_iget_vara(ncid, varid[i], start, count, buf[i], 1, buftype[i], &req[i]); ERR
+ MPI_Type_free(&buftype[i]);
+ }
+
+ err = ncmpi_wait_all(ncid, 4, req, st); ERR
+ for (i=0; i<4; i++) {
+ if (st[i] != NC_NOERR) {
+ printf("Error: ncmpi_wait_all st[%d] %s\n",i, ncmpi_strerror(st[i]));
+ nerrs++;
+ }
+ }
+
+ err = ncmpi_close(ncid); ERR
+
+ /* check if PnetCDF freed all internal malloc */
+ MPI_Offset malloc_size, sum_size;
+ err = ncmpi_inq_malloc_size(&malloc_size);
+ if (err == NC_NOERR) {
+ MPI_Reduce(&malloc_size, &sum_size, 1, MPI_OFFSET, MPI_SUM, 0, MPI_COMM_WORLD);
+ if (rank == 0 && sum_size > 0)
+ printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n",
+ sum_size);
+ }
+
+ MPI_Allreduce(MPI_IN_PLACE, &nerrs, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
+ if (rank == 0) {
+ if (nerrs) printf(FAIL_STR,nerrs);
+ else printf(PASS_STR);
+ }
+
+ MPI_Finalize();
+ return 0;
+}
+
diff --git a/test/testcases/buftype_freef.f b/test/testcases/buftype_freef.f
new file mode 100644
index 0000000..e3dfcf1
--- /dev/null
+++ b/test/testcases/buftype_freef.f
@@ -0,0 +1,169 @@
+!
+! Copyright (C) 2015, Northwestern University
+! See COPYRIGHT notice in top-level directory.
+!
+! $Id: buftype_freef.f 2224 2015-12-16 06:10:36Z wkliao $
+
+! This example tests if PnetCDF duplicates the MPI derived data type supplied
+! by the user, when calling the flexible APIs. It tests a PnetCDF bug
+! prior to version 1.6.1.
+!
+! The compile and run commands:
+!
+! % mpif77 -O2 -o buftype_freef buftype_freef.f -lpnetcdf
+! % mpiexec -n 4 ./buftype_freef /pvfs2/wkliao/testfile.nc
+!
+
+ INTEGER FUNCTION XTRIM(STRING)
+ CHARACTER*(*) STRING
+ INTEGER I, N
+ N = LEN(STRING)
+ DO I = N, 1, -1
+ IF (STRING(I:I) .NE. ' ') GOTO 10
+ ENDDO
+ 10 XTRIM = I
+ END ! FUNCTION XTRIM
+
+ subroutine check(err, message)
+ implicit none
+ include "mpif.h"
+ include "pnetcdf.inc"
+ integer err, XTRIM
+ character*(*) message
+ character*128 msg
+
+ ! It is a good idea to check returned value for possible error
+ if (err .NE. NF_NOERR) then
+ write(6,*) message(1:XTRIM(message)), nfmpi_strerror(err)
+ msg = '*** TESTING F77 buftype_freef.f for flexible API '
+ call pass_fail(1, msg)
+ call MPI_Abort(MPI_COMM_WORLD, -1, err)
+ end if
+ end ! subroutine check
+
+ program main
+ implicit none
+ include "mpif.h"
+ include "pnetcdf.inc"
+
+ integer NREQS, XTRIM
+ integer*8 NX, NY
+ PARAMETER(NREQS=4, NX=4, NY=4)
+
+ character*256 filename, cmd, msg, varname, str
+ integer i, err, ierr, nprocs, rank, nerrs, get_args
+ integer ncid, ghost
+ integer var(64,4), varid(4), dimid(2), req(4), st(4)
+ integer buftype(4), gsize(2), subsize(2), a_start(2)
+ integer*8 start(2), count(2)
+ integer*8 one, malloc_size, sum_size
+
+ call MPI_Init(ierr)
+ call MPI_Comm_rank(MPI_COMM_WORLD, rank, ierr)
+ call MPI_Comm_size(MPI_COMM_WORLD, nprocs, ierr)
+
+ ! take filename from command-line argument if there is any
+ if (rank .EQ. 0) then
+ filename = "testfile.nc"
+ err = get_args(cmd, filename)
+ endif
+ call MPI_Bcast(err, 1, MPI_INTEGER, 0, MPI_COMM_WORLD, ierr)
+ if (err .EQ. 0) goto 999
+
+ call MPI_Bcast(filename, 256, MPI_CHARACTER, 0,
+ + MPI_COMM_WORLD, ierr)
+
+ nerrs = 0
+
+ ! create file, truncate it if exists
+ err = nfmpi_create(MPI_COMM_WORLD, filename, NF_CLOBBER,
+ + MPI_INFO_NULL, ncid)
+ call check(err, 'In nfmpi_create: ')
+
+ ! define dimensions x and y
+ err = nfmpi_def_dim(ncid, "X", NX, dimid(1))
+ call check(err, 'In nfmpi_def_dim X: ')
+ err = nfmpi_def_dim(ncid, "Y", NY*nprocs, dimid(2))
+ call check(err, 'In nfmpi_def_dim Y: ')
+
+ ! define 2D variables of integer type
+ do i=1, NREQS
+ write(str,'(I1)') i
+ varname = 'var'//str(1:XTRIM(str))
+ err = nfmpi_def_var(ncid,varname,NF_INT,2,dimid,varid(i))
+ call check(err, 'In nfmpi_def_var '//
+ | varname(1:XTRIM(varname))//' : ')
+ enddo
+
+ ! do not forget to exit define mode
+ err = nfmpi_enddef(ncid)
+ call check(err, 'In nfmpi_enddef: ')
+
+ ! Note that in Fortran, array indices start with 1
+ start(1) = 1
+ start(2) = NY * rank + 1
+ count(1) = NX
+ count(2) = NY
+
+ do i=1, NREQS
+ err = nfmpi_put_vara_int_all(ncid, varid(i), start, count,
+ + var(1,i))
+ call check(err, 'In nfmpi_put_vara_int_all: ')
+ enddo
+
+ ! define an MPI datatype using MPI_Type_create_subarray()
+ one = 1
+ ghost = 2
+ gsize(1) = INT(NX) + 2 * ghost
+ gsize(2) = INT(NY) + 2 * ghost
+ subsize(1) = INT(NX)
+ subsize(2) = INT(NY)
+ a_start(1) = ghost - 1
+ a_start(2) = ghost - 1
+
+ do i = 1, NREQS
+ call MPI_Type_create_subarray(2, gsize, subsize, a_start,
+ + MPI_ORDER_FORTRAN, MPI_INTEGER, buftype(i), err)
+ call MPI_Type_commit(buftype(i), err)
+
+ err = nfmpi_iget_vara(ncid, varid(i), start, count,
+ + var(1,i), one, buftype(i), req(i))
+ call check(err, 'In nfmpi_iget_vara ')
+ ! immediately free the data type
+ call MPI_Type_free(buftype(i), err)
+ enddo
+
+ ! wait for the nonblocking I/O to complete
+ err = nfmpi_wait_all(ncid, NREQS, req, st)
+ call check(err, 'In nfmpi_wait_all')
+
+ ! check the status of each nonblocking request
+ do i=1, NREQS
+ write(str,'(I2)') i
+ call check(st(i), 'In nfmpi_wait_all req '//
+ + str(1:XTRIM(str)))
+ enddo
+
+ ! close the file
+ err = nfmpi_close(ncid)
+ call check(err, 'In nfmpi_close')
+
+ ! check if there is any PnetCDF internal malloc residue
+ 998 format(A,I13,A)
+ err = nfmpi_inq_malloc_size(malloc_size)
+ if (err .EQ. NF_NOERR) then
+ call MPI_Reduce(malloc_size, sum_size, 1, MPI_OFFSET,
+ + MPI_SUM, 0, MPI_COMM_WORLD, err)
+ if (rank .EQ. 0 .AND. sum_size .GT. 0)
+ + print 998,
+ + 'heap memory allocated by PnetCDF internally has ',
+ + sum_size/1048576, ' MiB yet to be freed'
+ endif
+
+ msg = '*** TESTING F77 '//cmd(1:XTRIM(cmd))//
+ + ' for flexible API '
+ if (rank .eq. 0) call pass_fail(nerrs, msg)
+
+ 999 call MPI_Finalize(ierr)
+ end ! program main
+
diff --git a/test/testcases/check_striping.c b/test/testcases/check_striping.c
new file mode 100644
index 0000000..06b5092
--- /dev/null
+++ b/test/testcases/check_striping.c
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2015, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ *
+ * $Id: check_striping.c 2133 2015-09-26 19:16:01Z wkliao $
+ */
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ *
+ * This program tests whether the file striping size and count retrieved from
+ * MPI-IO hints are consistent among all MPI processes.
+ *
+ * The compile and run commands are given below.
+ *
+ * % mpicc -g -o get_striping get_striping.c -lpnetcdf
+ *
+ * % mpiexec -l -n 4 get_striping testfile.nc
+ *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <mpi.h>
+#include <pnetcdf.h>
+
+#include <testutils.h>
+
+#define ERR {if(err!=NC_NOERR){nerrs++;printf("Error at line=%d: %s\n", __LINE__, ncmpi_strerror(err));}}
+
+int main(int argc, char** argv) {
+ char *filename="testfile.nc";
+ int rank, nprocs, err, nerrs=0, ncid, cmode;
+ int striping_size, striping_count, root_striping_size, root_striping_count;
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+
+ if (argc > 2) {
+ if (!rank) printf("Usage: %s [filename]\n",argv[0]);
+ MPI_Finalize();
+ return 0;
+ }
+ if (argc == 2) filename = argv[1];
+
+ if (rank == 0) {
+ char cmd_str[256];
+ sprintf(cmd_str, "*** TESTING C %s for strining info ", argv[0]);
+ printf("%-66s ------ ", cmd_str); fflush(stdout);
+ }
+
+ cmode = NC_CLOBBER;
+ err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, MPI_INFO_NULL, &ncid); ERR
+ err = ncmpi_enddef(ncid); ERR
+
+ err = ncmpi_inq_striping(ncid, &striping_size, &striping_count); ERR
+
+ root_striping_size = striping_size;
+ root_striping_count = striping_count;
+ MPI_Bcast(&root_striping_size, 1, MPI_INT, 0, MPI_COMM_WORLD);
+ MPI_Bcast(&root_striping_count, 1, MPI_INT, 0, MPI_COMM_WORLD);
+ if (root_striping_size != striping_size) {
+ printf("Error at PE %2d: inconsistent striping_size (root=%d local=%d)\n",
+ rank, root_striping_size, striping_size);
+ nerrs++;
+ }
+ if (root_striping_count != striping_count) {
+ printf("Error at PE %2d: inconsistent striping_count (root=%d local=%d)\n",
+ rank, root_striping_count, striping_count);
+ nerrs++;
+ }
+/*
+ if (nerrs == 0 && rank == 0)
+ printf("Success: striping_size=%d striping_count=%d\n",striping_size,striping_count);
+*/
+
+ err = ncmpi_close(ncid); ERR
+
+ /* check if PnetCDF freed all internal malloc */
+ MPI_Offset malloc_size, sum_size;
+ err = ncmpi_inq_malloc_size(&malloc_size);
+ if (err == NC_NOERR) {
+ MPI_Reduce(&malloc_size, &sum_size, 1, MPI_OFFSET, MPI_SUM, 0, MPI_COMM_WORLD);
+ if (rank == 0 && sum_size > 0)
+ printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n",
+ sum_size);
+ }
+
+ MPI_Allreduce(MPI_IN_PLACE, &nerrs, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
+ if (rank == 0) {
+ if (nerrs) printf(FAIL_STR,nerrs);
+ else printf(PASS_STR);
+ }
+ MPI_Finalize();
+ return 0;
+}
+
diff --git a/test/testcases/check_type.c b/test/testcases/check_type.c
new file mode 100644
index 0000000..b519ce9
--- /dev/null
+++ b/test/testcases/check_type.c
@@ -0,0 +1,249 @@
+/*
+ * Copyright (C) 2015, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ *
+ * $Id$
+ */
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ *
+ * This program tests conflicted in-memory data types against external data
+ * types and see if the correct error codes were returned.
+ *
+ * The compile and run commands are given below.
+ *
+ * % mpicc -g -o check_type check_type.c -lpnetcdf
+ *
+ * % mpiexec -l -n 1 check_type testfile.nc
+ *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <pnetcdf.h>
+
+#include <testutils.h>
+
+static char* err_code_name(int err);
+
+static char* etype_name(nc_type etype) {
+ switch (etype) {
+ case (0): return "NC_NAT";
+ case (1): return "NC_BYTE";
+ case (2): return "NC_CHAR";
+ case (3): return "NC_SHORT";
+ case (4): return "NC_INT";
+ case (5): return "NC_FLOAT";
+ case (6): return "NC_DOUBLE";
+ case (7): return "NC_UBYTE";
+ case (8): return "NC_USHORT";
+ case (9): return "NC_UINT";
+ case (10): return "NC_INT64";
+ case (11): return "NC_UINT64";
+ default:
+ return "Invalid nc_type";
+ }
+}
+
+#define ERR0 { \
+ if (err != NC_NOERR) { \
+ printf("Error at line %d err=%s\n",__LINE__,err_code_name(err)); \
+ nerrs++; \
+ } \
+}
+
+#define ERR(expect_err,itype,etype) { \
+ if (err != expect_err) { \
+ printf("Error at line %3d: itype=%9s etype=%-9s err=%s\n", \
+ __LINE__,itype,etype_name(etype),err_code_name(err)); \
+ nerrs++; \
+ } \
+}
+
+int main(int argc, char* argv[])
+{
+ char filename[256], *varname[12], buf[1024], attname[256];
+ int i, err, nerrs=0, rank, ncid, dimid, varid[12];
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+
+ if (argc > 2) {
+ if (!rank) printf("Usage: %s [filename]\n",argv[0]);
+ MPI_Finalize();
+ return 0;
+ }
+ strcpy(filename, "testfile.nc");
+ if (argc == 2) strcpy(filename, argv[1]);
+ MPI_Bcast(filename, 256, MPI_CHAR, 0, MPI_COMM_WORLD);
+
+ if (rank == 0) {
+ char cmd_str[256];
+ sprintf(cmd_str, "*** TESTING C %s for checking for type conflict ", argv[0]);
+ printf("%-66s ------ ", cmd_str); fflush(stdout);
+ }
+
+ err = ncmpi_create(MPI_COMM_WORLD, filename, NC_CLOBBER|NC_64BIT_DATA, MPI_INFO_NULL, &ncid); ERR0
+ err = ncmpi_def_dim(ncid, "x", 2, &dimid); ERR0
+
+ varname[0] = "var_nat";
+ varname[1] = "var_byte";
+ varname[2] = "var_char";
+ varname[3] = "var_short";
+ varname[4] = "var_int";
+ varname[5] = "var_float";
+ varname[6] = "var_double";
+ varname[7] = "var_ubyte";
+ varname[8] = "var_ushort";
+ varname[9] = "var_uint";
+ varname[10] = "var_int64";
+ varname[11] = "var_uint64";
+ for (i=NC_BYTE; i<=NC_UINT64; i++) {
+ err = ncmpi_def_var(ncid, varname[i], i, 1, &dimid, &varid[i]); ERR0
+ }
+
+ for (i=0; i<1024; i++) buf[i]=i;
+ err = ncmpi_put_att_text(ncid, NC_GLOBAL, "att_text", 3, (char*)buf); ERR0
+ ERR(NC_NOERR, "text", NC_CHAR)
+
+ for (i=0; i<1024; i++) buf[i]=0;
+ for (i=NC_BYTE; i<=NC_UINT64; i++) {
+ int expect_err = NC_NOERR;
+
+ if (i == NC_CHAR) expect_err = NC_ECHAR;
+
+ sprintf(attname,"att_uchar_for_var_%s",varname[i]);
+ err = ncmpi_put_att_uchar (ncid, NC_GLOBAL, attname, i, 3, (unsigned char*) buf);
+ ERR(expect_err, "uchar", i)
+ sprintf(attname,"att_schar_for_var_%s",varname[i]);
+ err = ncmpi_put_att_schar (ncid, NC_GLOBAL, attname, i, 3, (signed char*) buf);
+ ERR(expect_err, "schar", i)
+ sprintf(attname,"att_short_for_var_%s",varname[i]);
+ err = ncmpi_put_att_short (ncid, NC_GLOBAL, attname, i, 3, (short*) buf);
+ ERR(expect_err, "short", i)
+ sprintf(attname,"att_int_for_var_%s",varname[i]);
+ err = ncmpi_put_att_int (ncid, NC_GLOBAL, attname, i, 3, (int*) buf);
+ ERR(expect_err, "int", i)
+ sprintf(attname,"att_float_for_var_%s",varname[i]);
+ err = ncmpi_put_att_float (ncid, NC_GLOBAL, attname, i, 3, (float*) buf);
+ ERR(expect_err, "float", i)
+ sprintf(attname,"att_double_for_var_%s",varname[i]);
+ err = ncmpi_put_att_double (ncid, NC_GLOBAL, attname, i, 3, (double*) buf);
+ ERR(expect_err, "double", i)
+ sprintf(attname,"att_ushort_for_var_%s",varname[i]);
+ err = ncmpi_put_att_ushort (ncid, NC_GLOBAL, attname, i, 3, (unsigned short*) buf);
+ ERR(expect_err, "ushort", i)
+ sprintf(attname,"att_uint_for_var_%s",varname[i]);
+ err = ncmpi_put_att_uint (ncid, NC_GLOBAL, attname, i, 3, (unsigned int*) buf);
+ ERR(expect_err, "uint", i)
+ sprintf(attname,"att_longlong_for_var_%s",varname[i]);
+ err = ncmpi_put_att_longlong (ncid, NC_GLOBAL, attname, i, 3, (long long*) buf);
+ ERR(expect_err, "longlong", i)
+ sprintf(attname,"att_ulonglong_for_var_%s",varname[i]);
+ err = ncmpi_put_att_ulonglong(ncid, NC_GLOBAL, attname, i, 3, (unsigned long long*) buf);
+ ERR(expect_err, "ulonglong", i)
+ }
+
+ for (i=NC_BYTE; i<=NC_UINT64; i++) {
+ int expect_err = NC_NOERR;
+
+ if (i == NC_CHAR) continue;
+
+ sprintf(attname,"att_uchar_for_var_%s",varname[i]);
+ err = ncmpi_get_att_uchar (ncid, NC_GLOBAL, attname, (unsigned char*) buf);
+ ERR(expect_err, "uchar", i)
+ sprintf(attname,"att_schar_for_var_%s",varname[i]);
+ err = ncmpi_get_att_schar (ncid, NC_GLOBAL, attname, (signed char*) buf);
+ ERR(expect_err, "schar", i)
+ sprintf(attname,"att_short_for_var_%s",varname[i]);
+ err = ncmpi_get_att_short (ncid, NC_GLOBAL, attname, (short*) buf);
+ ERR(expect_err, "short", i)
+ sprintf(attname,"att_int_for_var_%s",varname[i]);
+ err = ncmpi_get_att_int (ncid, NC_GLOBAL, attname, (int*) buf);
+ ERR(expect_err, "int", i)
+ sprintf(attname,"att_float_for_var_%s",varname[i]);
+ err = ncmpi_get_att_float (ncid, NC_GLOBAL, attname, (float*) buf);
+ ERR(expect_err, "float", i)
+ sprintf(attname,"att_double_for_var_%s",varname[i]);
+ err = ncmpi_get_att_double (ncid, NC_GLOBAL, attname, (double*) buf);
+ ERR(expect_err, "double", i)
+ sprintf(attname,"att_ushort_for_var_%s",varname[i]);
+ err = ncmpi_get_att_ushort (ncid, NC_GLOBAL, attname, (unsigned short*) buf);
+ ERR(expect_err, "ushort", i)
+ sprintf(attname,"att_uint_for_var_%s",varname[i]);
+ err = ncmpi_get_att_uint (ncid, NC_GLOBAL, attname, (unsigned int*) buf);
+ ERR(expect_err, "uint", i)
+ sprintf(attname,"att_longlong_for_var_%s",varname[i]);
+ err = ncmpi_get_att_longlong (ncid, NC_GLOBAL, attname, (long long*) buf);
+ ERR(expect_err, "longlong", i)
+ sprintf(attname,"att_ulonglong_for_var_%s",varname[i]);
+ err = ncmpi_get_att_ulonglong(ncid, NC_GLOBAL, attname, (unsigned long long*) buf);
+ ERR(expect_err, "ulonglong", i)
+ }
+
+ err = ncmpi_close(ncid); ERR0
+
+ /* check if PnetCDF freed all internal malloc */
+ MPI_Offset malloc_size, sum_size;
+ err = ncmpi_inq_malloc_size(&malloc_size);
+ if (err == NC_NOERR) {
+ MPI_Reduce(&malloc_size, &sum_size, 1, MPI_OFFSET, MPI_SUM, 0, MPI_COMM_WORLD);
+ if (rank == 0 && sum_size > 0)
+ printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n",
+ sum_size);
+ }
+
+ MPI_Allreduce(MPI_IN_PLACE, &nerrs, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
+ if (rank == 0) {
+ if (nerrs) printf(FAIL_STR,nerrs);
+ else printf(PASS_STR);
+ }
+
+ MPI_Finalize();
+
+ return 0;
+}
+
+static char* err_code_name(int err)
+{
+ static char unknown_str[32];
+ switch (err) {
+ case (NC_NOERR): return "NC_NOERR";
+ case (NC_EBADID): return "NC_EBADID";
+ case (NC_ENFILE): return "NC_ENFILE";
+ case (NC_EEXIST): return "NC_EEXIST";
+ case (NC_EINVAL): return "NC_EINVAL";
+ case (NC_EPERM): return "NC_EPERM";
+ case (NC_ENOTINDEFINE): return "NC_ENOTINDEFINE";
+ case (NC_EINDEFINE): return "NC_EINDEFINE";
+ case (NC_EINVALCOORDS): return "NC_EINVALCOORDS";
+ case (NC_EMAXDIMS): return "NC_EMAXDIMS";
+ case (NC_ENAMEINUSE): return "NC_ENAMEINUSE";
+ case (NC_ENOTATT): return "NC_ENOTATT";
+ case (NC_EMAXATTS): return "NC_EMAXATTS";
+ case (NC_EBADTYPE): return "NC_EBADTYPE";
+ case (NC_EBADDIM): return "NC_EBADDIM";
+ case (NC_EUNLIMPOS): return "NC_EUNLIMPOS";
+ case (NC_EMAXVARS): return "NC_EMAXVARS";
+ case (NC_ENOTVAR): return "NC_ENOTVAR";
+ case (NC_EGLOBAL): return "NC_EGLOBAL";
+ case (NC_ENOTNC): return "NC_ENOTNC";
+ case (NC_ESTS): return "NC_ESTS";
+ case (NC_EMAXNAME): return "NC_EMAXNAME";
+ case (NC_EUNLIMIT): return "NC_EUNLIMIT";
+ case (NC_ENORECVARS): return "NC_ENORECVARS";
+ case (NC_ECHAR): return "NC_ECHAR";
+ case (NC_EEDGE): return "NC_EEDGE";
+ case (NC_ESTRIDE): return "NC_ESTRIDE";
+ case (NC_EBADNAME): return "NC_EBADNAME";
+ case (NC_ERANGE): return "NC_ERANGE";
+ case (NC_ENOMEM): return "NC_ENOMEM";
+ case (NC_EVARSIZE): return "NC_EVARSIZE";
+ case (NC_EDIMSIZE): return "NC_EDIMSIZE";
+ case (NC_ETRUNC): return "NC_ETRUNC";
+ default:
+ sprintf(unknown_str,"Unknown code %d",err);
+ }
+ return unknown_str;
+}
+
diff --git a/test/testcases/collective_error.c b/test/testcases/collective_error.c
new file mode 100644
index 0000000..571176d
--- /dev/null
+++ b/test/testcases/collective_error.c
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2003, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ *
+ * $Id: collective_error.c 2133 2015-09-26 19:16:01Z wkliao $
+ */
+
+/* This test program checks if a collective API can be nicely aborted without
+ * causing the program to hang. It runs on 2 processes. One process deliberately
+ * produces an error (using an illegal start argument), while the other does not.
+ */
+
+#include <mpi.h>
+#include <pnetcdf.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+
+#include <testutils.h>
+
+#define ERR { if (err!=NC_NOERR){printf("PE %d: error at line %d (%s)\n",rank,__LINE__,ncmpi_strerror(err)); nerrs++;}}
+#define CHECK_ERROR(fn) { \
+ if (rank == 0 && err != NC_NOERR) \
+ printf("PE %d: %s error is %s\n",rank,fn,ncmpi_strerror(err)); \
+ if (rank == 1 && err != NC_EINVALCOORDS) \
+ printf("PE %d: %s error code should be NC_EINVALCOORDS but got %s",rank,fn,nc_err_code_name(err)); \
+}
+
+int main(int argc, char *argv[])
+{
+ char *filename="testfile.nc";
+ int rank, nproc, ncid, err, nerrs=0, varid, dimids[1];
+ int req, status, verbose;
+ MPI_Offset start[1], count[1];
+ double buf[2];
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ MPI_Comm_size(MPI_COMM_WORLD, &nproc);
+
+ if (argc > 2) {
+ if (!rank) printf("Usage: %s [filename]\n",argv[0]);
+ MPI_Finalize();
+ return 0;
+ }
+ if (argc == 2) filename = argv[1];
+
+ if (rank == 0) {
+ char cmd_str[256];
+ sprintf(cmd_str, "*** TESTING C %s for collective abort ", argv[0]);
+ printf("%-66s ------ ", cmd_str); fflush(stdout);
+ }
+
+ verbose = 0;
+ if (nproc != 2 && rank == 0 && verbose)
+ printf("Warning: %s is designed to run on 2 processes\n",argv[0]);
+
+ /* Create a 2 element vector of doubles */
+ err = ncmpi_create(MPI_COMM_WORLD, filename, NC_CLOBBER, MPI_INFO_NULL, &ncid);
+ ERR
+
+ err = ncmpi_def_dim(ncid, "dim", 2, &dimids[0]);
+ ERR
+
+ err = ncmpi_def_var(ncid, "var", NC_DOUBLE, 1, dimids, &varid);
+ ERR
+
+ err = ncmpi_enddef(ncid);
+ ERR
+
+ if (rank == 0) {
+ start[0] = 0;
+ count[0] = 2;
+ } else if (rank == 1) {
+ start[0] = 2; /* illegal for a start > defined shape */
+ count[0] = 0;
+ }
+ else
+ count[0] = 0;
+
+ err = ncmpi_put_vara_all(ncid, varid, start, count,
+ buf, count[0], MPI_DOUBLE);
+ CHECK_ERROR("ncmpi_put_vara_all")
+
+ err = ncmpi_put_vara_double_all(ncid, varid, start, count, buf);
+ CHECK_ERROR("ncmpi_put_vara_double_all")
+
+ err = ncmpi_iput_vara_double(ncid, varid, start, count, buf, &req);
+ CHECK_ERROR("ncmpi_iput_vara_double")
+
+ err = ncmpi_wait_all(ncid, 1, &req, &status);
+ ERR
+
+ err = ncmpi_get_vara_all(ncid, varid, start, count,
+ buf, count[0], MPI_DOUBLE);
+ CHECK_ERROR("ncmpi_get_vara_all")
+
+ err = ncmpi_get_vara_double_all(ncid, varid, start, count, buf);
+ CHECK_ERROR("ncmpi_get_vara_double_all")
+
+ err = ncmpi_iget_vara_double(ncid, varid, start, count, buf, &req);
+ CHECK_ERROR("ncmpi_iget_vara_double")
+
+ err = ncmpi_wait_all(ncid, 1, &req, &status);
+ ERR
+
+ err = ncmpi_close(ncid);
+ ERR
+
+ /* check if PnetCDF freed all internal malloc */
+ MPI_Offset malloc_size, sum_size;
+ err = ncmpi_inq_malloc_size(&malloc_size);
+ if (err == NC_NOERR) {
+ MPI_Reduce(&malloc_size, &sum_size, 1, MPI_OFFSET, MPI_SUM, 0, MPI_COMM_WORLD);
+ if (rank == 0 && sum_size > 0)
+ printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n",
+ sum_size);
+ }
+
+ MPI_Allreduce(MPI_IN_PLACE, &nerrs, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
+ if (rank == 0) {
+ if (nerrs) printf(FAIL_STR,nerrs);
+ else printf(PASS_STR);
+ }
+
+ MPI_Finalize();
+ return (nerrs == 0) ? 0 : 1;
+}
diff --git a/test/testcases/depend b/test/testcases/depend
new file mode 100644
index 0000000..3989a50
--- /dev/null
+++ b/test/testcases/depend
@@ -0,0 +1,37 @@
+alignment_test.o: alignment_test.c
+bigrecords.o: bigrecords.f
+collective_error.o: collective_error.c
+flexible.o: flexible.c
+flexible2.o: flexible2.c
+flexible_varm.o: flexible_varm.c
+inq_num_vars.o: inq_num_vars.c
+inq_num_varsf.o: inq_num_varsf.f90
+inq_recsize.o: inq_recsize.c
+inq_recsizef.o: inq_recsizef.f90
+ivarn.o: ivarn.c
+modes.o: modes.c
+ncmpi_vars_null_stride.o: ncmpi_vars_null_stride.c
+noclobber.o: noclobber.c
+nonblocking.o: nonblocking.c
+one_record.o: one_record.c
+profile.o: profile.c
+varn_int.o: varn_int.c
+varn_contig.o: varn_contig.c
+varn_intf.o: varn_intf.f
+varn_real.o: varn_real.f90
+record.o: record.c
+redef1.o: redef1.c
+test_vard.o: test_vard.c
+test_vardf.o: test_vardf.F
+test_vardf90.o: test_vardf90.f90
+test_varm.o: test_varm.c
+vectors.o: vectors.c
+check_striping.o: check_striping.c
+attrf.o: attrf.f
+add_var.o: add_var.c
+buftype_free.o: buftype_free.c
+buftype_freef.o: buftype_freef.f
+put_parameter.o: put_parameter.f
+last_large_var.o: last_large_var.c
+check_type.o: check_type.c
+test_erange.o: test_erange.c
diff --git a/test/testcases/flexible.c b/test/testcases/flexible.c
new file mode 100644
index 0000000..d4085ab
--- /dev/null
+++ b/test/testcases/flexible.c
@@ -0,0 +1,205 @@
+/*
+ * Copyright (C) 2013, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ *
+ * $Id: flexible.c 2133 2015-09-26 19:16:01Z wkliao $
+ */
+
+/*
+ * This program tests the use of flexible API.
+ * The write buffer is a 2D array of size NY x NX
+ * The MPI data type for the buffer is defined by swapping the 1st and 2nd
+ * rows of the array. It uses MPI_Type_create_hindex(). After the write, this
+ * test reads back the array using regular and flexible get APIs (blocking and
+ * nonblokcing) and check the contents.
+ *
+ * The expected reults from the output file contents are:
+ * (when running on 1 MPI process)
+ *
+ * % ncmpidump testfile.nc
+ * netcdf testfile {
+ * // file format: CDF-1
+ * dimensions:
+ * Y = UNLIMITED ; // (2 currently)
+ * X = 5 ;
+ * variables:
+ * int VAR(Y, X) ;
+ * data:
+ *
+ * var =
+ * 1, 1, 1, 1, 1,
+ * 0, 0, 0, 0, 0 ;
+ * }
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <mpi.h>
+#include <pnetcdf.h>
+
+#include <testutils.h>
+
+#define NY 2
+#define NX 5
+#define ERR if (err!=NC_NOERR) {printf("Error at line %d: %s\n", __LINE__,ncmpi_strerror(err)); nerrs++;}
+
+/*----< main() >------------------------------------------------------------*/
+int main(int argc, char **argv) {
+
+ char filename[256];
+ int i, j, err, ncid, varid, dimids[2], debug=0;
+ int rank, nprocs, blocklengths[2], buf[NY][NX], *bufptr;
+ int *ncbuf, req, st, nerrs=0;
+ int array_of_sizes[2], array_of_subsizes[2], array_of_starts[2];
+ MPI_Offset start[2], count[2];
+ MPI_Aint a0, a1, disps[2];
+ MPI_Datatype buftype;
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+
+ if (argc > 2) {
+ if (!rank) printf("Usage: %s [filename]\n",argv[0]);
+ MPI_Finalize();
+ return 0;
+ }
+ strcpy(filename, "testfile.nc");
+ if (argc == 2) strcpy(filename, argv[1]);
+ MPI_Bcast(filename, 256, MPI_CHAR, 0, MPI_COMM_WORLD);
+
+ if (rank == 0) {
+ char cmd_str[256];
+ sprintf(cmd_str, "*** TESTING C %s for flexible put and get ", argv[0]);
+ printf("%-66s ------ ", cmd_str); fflush(stdout);
+ }
+
+ err = ncmpi_create(MPI_COMM_WORLD, filename, NC_CLOBBER, MPI_INFO_NULL,
+ &ncid); ERR
+
+ /* define a 2D array */
+ err = ncmpi_def_dim(ncid, "Y", NC_UNLIMITED, &dimids[0]); ERR
+ err = ncmpi_def_dim(ncid, "X", NX*nprocs, &dimids[1]); ERR
+ err = ncmpi_def_var(ncid, "var", NC_INT, 2, dimids, &varid); ERR
+ err = ncmpi_enddef(ncid); ERR
+
+ /* initialize the contents of the array */
+ for (j=0; j<NY; j++) for (i=0; i<NX; i++) buf[j][i] = j;
+
+ /* construct an MPI derived data type for swapping 1st row with 2nd row */
+ blocklengths[0] = blocklengths[1] = NX;
+ MPI_Get_address(buf[1], &a0);
+ MPI_Get_address(buf[0], &a1);
+ disps[0] = 0;
+ disps[1] = a1 - a0;
+ bufptr = buf[1];
+ err = MPI_Type_create_hindexed(2, blocklengths, disps, MPI_INT, &buftype);
+ if (err != MPI_SUCCESS) printf("MPI error MPI_Type_create_hindexed\n");
+ MPI_Type_commit(&buftype);
+
+ start[0] = 0; start[1] = NX*rank;
+ count[0] = 2; count[1] = NX;
+ if (debug) printf("put start=%lld %lld count=%lld %lld\n",start[0],start[1],count[0],count[1]);
+
+ /* call flexible API */
+ err = ncmpi_put_vara_all(ncid, varid, start, count, bufptr, 1, buftype); ERR
+ MPI_Type_free(&buftype);
+
+ /* check if the contents of buf are altered */
+ for (j=0; j<NY; j++)
+ for (i=0; i<NX; i++)
+ if (buf[j][i] != j)
+ printf("buf[%d][%d] != %d\n",j,i,buf[j][i]);
+
+ /* check if root process can write to file header in data mode */
+ err = ncmpi_rename_var(ncid, varid, "VAR"); ERR
+
+ err = ncmpi_close(ncid); ERR
+
+ /* open the same file and read back for validate */
+ err = ncmpi_open(MPI_COMM_WORLD, filename, NC_NOWRITE, MPI_INFO_NULL,
+ &ncid); ERR
+
+ err = ncmpi_inq_varid(ncid, "VAR", &varid); ERR
+
+ /* initialize the contents of the array to a different value */
+ for (j=0; j<NY; j++) for (i=0; i<NX; i++) buf[j][i] = -1;
+
+ /* read back variable */
+ start[0] = 0; start[1] = NX*rank;
+ count[0] = 2; count[1] = NX;
+ if (debug) printf("get start=%lld %lld count=%lld %lld\n",start[0],start[1],count[0],count[1]);
+
+ err = ncmpi_get_vara_int_all(ncid, varid, start, count, buf[0]); ERR
+
+ /* check if the contents of buf are expected */
+ for (j=0; j<2; j++) {
+ int val = (j == 0) ? 1 : 0;
+ for (i=0; i<NX; i++)
+ if (buf[j][i] != val) {
+ printf("Unexpected buf[%d][%d]=%d != %d\n",j,i,buf[j][i],val);
+ nerrs++;
+ }
+ }
+
+ /* create a buftype with ghost cells on each side */
+ ncbuf = (int *) malloc((count[0]+4)*(count[1]+4)*sizeof(int));
+ array_of_sizes[0] = count[0]+4;
+ array_of_sizes[1] = count[1]+4;
+ array_of_subsizes[0] = count[0];
+ array_of_subsizes[1] = count[1];
+ array_of_starts[0] = 2;
+ array_of_starts[1] = 2;
+ MPI_Type_create_subarray(2, array_of_sizes, array_of_subsizes,
+ array_of_starts, MPI_ORDER_C,
+ MPI_INT, &buftype);
+ MPI_Type_commit(&buftype);
+ err = ncmpi_get_vara_all(ncid, varid, start, count, ncbuf, 1, buftype); ERR
+
+ for (j=0; j<count[0]; j++) {
+ for (i=0; i<count[1]; i++)
+ if (buf[j][i] != ncbuf[(j+2)*(count[1]+4)+(i+2)]) {
+ printf("Error: expecting ncbuf[%d][%d]=%d but got %d\n",
+ j,i,buf[j][i],ncbuf[(j+2)*(count[1]+4)+(i+2)]);
+ nerrs++;
+ }
+ }
+ for (i=0; i<(count[0]+4)*(count[1]+4); i++) ncbuf[i] = -1;
+
+ err = ncmpi_iget_vara(ncid, varid, start, count, ncbuf, 1, buftype, &req); ERR
+ err = ncmpi_wait_all(ncid, 1, &req, &st); ERR
+
+ for (j=0; j<count[0]; j++) {
+ for (i=0; i<count[1]; i++)
+ if (buf[j][i] != ncbuf[(j+2)*(count[1]+4)+(i+2)]) {
+ printf("Error: expecting ncbuf[%d][%d]=%d but got %d\n",
+ j,i,buf[j][i],ncbuf[(j+2)*(count[1]+4)+(i+2)]);
+ nerrs++;
+ }
+ }
+
+ MPI_Type_free(&buftype);
+ free(ncbuf);
+
+ err = ncmpi_close(ncid); ERR
+
+ /* check if PnetCDF freed all internal malloc */
+ MPI_Offset malloc_size, sum_size;
+ err = ncmpi_inq_malloc_size(&malloc_size);
+ if (err == NC_NOERR) {
+ MPI_Reduce(&malloc_size, &sum_size, 1, MPI_OFFSET, MPI_SUM, 0, MPI_COMM_WORLD);
+ if (rank == 0 && sum_size > 0)
+ printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n",
+ sum_size);
+ }
+
+ MPI_Allreduce(MPI_IN_PLACE, &nerrs, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
+ if (rank == 0) {
+ if (nerrs) printf(FAIL_STR,nerrs);
+ else printf(PASS_STR);
+ }
+
+ MPI_Finalize();
+ return 0;
+}
diff --git a/test/testcases/flexible2.c b/test/testcases/flexible2.c
new file mode 100644
index 0000000..8cf89e3
--- /dev/null
+++ b/test/testcases/flexible2.c
@@ -0,0 +1,279 @@
+/*********************************************************************
+ *
+ * Copyright (C) 2014, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ *
+ *********************************************************************/
+/* $Id: flexible2.c 2133 2015-09-26 19:16:01Z wkliao $ */
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ *
+ * This program tests PnetCDF flexible APIs, ncmpi_put_vara_all(),
+ * ncmpi_iput_vara() to write two 2D array variables (one is of 4-byte
+ * integer byte and the other float type) in parallel. It then uses flexible
+ * get/iget APIs to read data back and check the contents. The program first
+ * defines 2 netCDF variables of sizes
+ * var_zy: NZ*nprocs x NY
+ * var_yx: NY x NX*nprocs
+ *
+ * The data partitioning patterns on the 2 variables are row-wise and
+ * column-wise, respectively. Each process writes a subarray of size
+ * NZ x NY and NY x NX to var_zy and var_yx, respectively.
+ * Both local buffers have a ghost cell of length 3 surrounded along each
+ * dimension.
+ *
+ * The compile and run commands are given below.
+ *
+ * % mpicc -O2 -o flexible2 flexible2.c -lpnetcdf
+ *
+ * % mpiexec -l -n 4 ./flexible2 /pvfs2/wkliao/testfile.nc
+ *
+ * % ncmpidump /pvfs2/wkliao/testfile.nc
+ * netcdf testfile {
+ * // file format: CDF-5 (big variables)
+ * dimensions:
+ * Z = 20 ;
+ * Y = 5 ;
+ * X = 20 ;
+ * variables:
+ * int var_zy(Z, Y) ;
+ * float var_yx(Y, X) ;
+ * data:
+ *
+ * var_zy =
+ * 0, 0, 0, 0, 0,
+ * 0, 0, 0, 0, 0,
+ * 0, 0, 0, 0, 0,
+ * 0, 0, 0, 0, 0,
+ * 0, 0, 0, 0, 0,
+ * 1, 1, 1, 1, 1,
+ * 1, 1, 1, 1, 1,
+ * 1, 1, 1, 1, 1,
+ * 1, 1, 1, 1, 1,
+ * 1, 1, 1, 1, 1,
+ * 2, 2, 2, 2, 2,
+ * 2, 2, 2, 2, 2,
+ * 2, 2, 2, 2, 2,
+ * 2, 2, 2, 2, 2,
+ * 2, 2, 2, 2, 2,
+ * 3, 3, 3, 3, 3,
+ * 3, 3, 3, 3, 3,
+ * 3, 3, 3, 3, 3,
+ * 3, 3, 3, 3, 3,
+ * 3, 3, 3, 3, 3 ;
+ *
+ * var_yx =
+ * 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3,
+ * 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3,
+ * 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3,
+ * 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3,
+ * 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3 ;
+ * }
+ *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h> /* strcpy() */
+#include <assert.h>
+#include <mpi.h>
+#include <pnetcdf.h>
+
+#include <testutils.h>
+
+#define NZ 5
+#define NY 5
+#define NX 5
+
+#define ERR {if(err!=NC_NOERR){printf("Error at line=%d: %s\n", __LINE__, ncmpi_strerror(err)); nerrs++;}}
+
+int main(int argc, char** argv)
+{
+ char filename[256];
+ int i, j, rank, nprocs, err, nerrs=0, req, status, ghost_len=3;
+ int ncid, cmode, varid0, varid1, dimid[3], *buf_zy;
+ int array_of_sizes[2], array_of_subsizes[2], array_of_starts[2];
+ double *buf_yx;
+ MPI_Offset start[2], count[2];
+ MPI_Datatype subarray;
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+
+ if (argc > 2) {
+ if (!rank) printf("Usage: %s [filename]\n",argv[0]);
+ MPI_Finalize();
+ return 0;
+ }
+ strcpy(filename, "testfile.nc");
+ if (argc == 2) strcpy(filename, argv[1]);
+ MPI_Bcast(filename, 256, MPI_CHAR, 0, MPI_COMM_WORLD);
+
+ if (rank == 0) {
+ char cmd_str[256];
+ sprintf(cmd_str, "*** TESTING C %s for flexible APIs ", argv[0]);
+ printf("%-66s ------ ", cmd_str); fflush(stdout);
+ }
+
+ /* create a new file for writing ----------------------------------------*/
+ cmode = NC_CLOBBER | NC_64BIT_DATA;
+ err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, MPI_INFO_NULL, &ncid);
+ ERR
+
+ /* define 3 dimensions */
+ err = ncmpi_def_dim(ncid, "Z", NZ*nprocs, &dimid[0]); ERR
+ err = ncmpi_def_dim(ncid, "Y", NY, &dimid[1]); ERR
+ err = ncmpi_def_dim(ncid, "X", NX*nprocs, &dimid[2]); ERR
+
+ /* define a variable of size (NZ * nprocs) * NY */
+ err = ncmpi_def_var(ncid, "var_zy", NC_INT, 2, &dimid[0], &varid0); ERR
+ /* define a variable of size NY * (NX * nprocs) */
+ err = ncmpi_def_var(ncid, "var_yx", NC_FLOAT, 2, &dimid[1], &varid1); ERR
+ err = ncmpi_enddef(ncid); ERR
+
+ /* var_zy is partitioned along Z dimension */
+ array_of_sizes[0] = NZ + 2*ghost_len;
+ array_of_sizes[1] = NY + 2*ghost_len;
+ array_of_subsizes[0] = NZ;
+ array_of_subsizes[1] = NY;
+ array_of_starts[0] = ghost_len;
+ array_of_starts[1] = ghost_len;
+ MPI_Type_create_subarray(2, array_of_sizes, array_of_subsizes,
+ array_of_starts, MPI_ORDER_C, MPI_INT, &subarray);
+ MPI_Type_commit(&subarray);
+
+ int buffer_len = (NZ+2*ghost_len) * (NY+2*ghost_len);
+ buf_zy = (int*) malloc(buffer_len * sizeof(int));
+ for (i=0; i<buffer_len; i++) buf_zy[i] = rank;
+
+ start[0] = NZ * rank; start[1] = 0;
+ count[0] = NZ; count[1] = NY;
+ /* calling a blocking flexible API */
+ err = ncmpi_put_vara_all(ncid, varid0, start, count, buf_zy, 1, subarray);
+ ERR
+
+ /* check the contents of put buffer */
+ for (i=0; i<buffer_len; i++) {
+ if (buf_zy[i] != rank) {
+ printf("Error put buffer[%d] is altered\n",i);
+ nerrs++;
+ }
+ }
+
+ for (i=0; i<buffer_len; i++) buf_zy[i] = -1;
+ /* calling a blocking flexible API */
+ err = ncmpi_get_vara_all(ncid, varid0, start, count, buf_zy, 1, subarray);
+ ERR
+
+ /* check the contents of get buffer */
+ for (i=0; i<array_of_sizes[0]; i++) {
+ for (j=0; j<array_of_sizes[1]; j++) {
+ int index = i*array_of_sizes[1] + j;
+ if (i < ghost_len || ghost_len+array_of_subsizes[0] <= i ||
+ j < ghost_len || ghost_len+array_of_subsizes[1] <= j) {
+ if (buf_zy[index] != -1) {
+ printf("Unexpected get buffer[%d][%d]=%d\n",
+ i,j,buf_zy[index]);
+ nerrs++;
+ }
+ }
+ else {
+ if (buf_zy[index] != rank) {
+ printf("Unexpected get buffer[%d][%d]=%d\n",
+ i,j,buf_zy[index]);
+ nerrs++;
+ }
+ }
+ }
+ }
+ free(buf_zy);
+ MPI_Type_free(&subarray);
+
+ /* var_yx is partitioned along X dimension */
+ array_of_sizes[0] = NY + 2*ghost_len;
+ array_of_sizes[1] = NX + 2*ghost_len;
+ array_of_subsizes[0] = NY;
+ array_of_subsizes[1] = NX;
+ array_of_starts[0] = ghost_len;
+ array_of_starts[1] = ghost_len;
+ MPI_Type_create_subarray(2, array_of_sizes, array_of_subsizes,
+ array_of_starts, MPI_ORDER_C, MPI_DOUBLE,
+ &subarray);
+ MPI_Type_commit(&subarray);
+
+ buffer_len = (NY+2*ghost_len) * (NX+2*ghost_len);
+ buf_yx = (double*) malloc(buffer_len * sizeof(double));
+ for (i=0; i<buffer_len; i++) buf_yx[i] = rank;
+
+ start[0] = 0; start[1] = NX * rank;
+ count[0] = NY; count[1] = NX;
+
+ /* calling a non-blocking flexible API */
+ err = ncmpi_iput_vara(ncid, varid1, start, count, buf_yx, 1, subarray,&req);
+ ERR
+ err = ncmpi_wait_all(ncid, 1, &req, &status); ERR
+ err = status; ERR
+
+ /* check the contents of put buffer */
+ for (i=0; i<buffer_len; i++) {
+ if (buf_yx[i] != rank) {
+ printf("Error iput buffer[%d]=%f is altered\n",i,buf_yx[i]);
+ nerrs++;
+ }
+ }
+
+ for (i=0; i<buffer_len; i++) buf_yx[i] = -1;
+
+ /* calling a non-blocking flexible API */
+ err = ncmpi_iget_vara(ncid, varid1, start, count, buf_yx, 1, subarray,&req);
+ ERR
+ err = ncmpi_wait_all(ncid, 1, &req, &status); ERR
+ err = status; ERR
+
+ /* check the contents of iget buffer */
+ for (i=0; i<array_of_sizes[0]; i++) {
+ for (j=0; j<array_of_sizes[1]; j++) {
+ int index = i*array_of_sizes[1] + j;
+ if (i < ghost_len || ghost_len+array_of_subsizes[0] <= i ||
+ j < ghost_len || ghost_len+array_of_subsizes[1] <= j) {
+ if (buf_yx[index] != -1) {
+ printf("Unexpected get buffer[%d][%d]=%f\n",
+ i,j,buf_yx[index]);
+ nerrs++;
+ }
+ }
+ else {
+ if (buf_yx[index] != rank) {
+ printf("Unexpected get buffer[%d][%d]=%f\n",
+ i,j,buf_yx[index]);
+ nerrs++;
+ }
+ }
+ }
+ }
+ free(buf_yx);
+ MPI_Type_free(&subarray);
+
+ err = ncmpi_close(ncid); ERR
+
+ /* check if PnetCDF freed all internal malloc */
+ MPI_Offset malloc_size, sum_size;
+ err = ncmpi_inq_malloc_size(&malloc_size);
+ if (err == NC_NOERR) {
+ MPI_Reduce(&malloc_size, &sum_size, 1, MPI_OFFSET, MPI_SUM, 0, MPI_COMM_WORLD);
+ if (rank == 0 && sum_size > 0)
+ printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n",
+ sum_size);
+ }
+
+ MPI_Allreduce(MPI_IN_PLACE, &nerrs, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
+ if (rank == 0) {
+ if (nerrs) printf(FAIL_STR,nerrs);
+ else printf(PASS_STR);
+ }
+
+ MPI_Finalize();
+ return 0;
+}
+
diff --git a/test/testcases/flexible_varm.c b/test/testcases/flexible_varm.c
new file mode 100644
index 0000000..3df4ec1
--- /dev/null
+++ b/test/testcases/flexible_varm.c
@@ -0,0 +1,247 @@
+/*********************************************************************
+ *
+ * Copyright (C) 2014, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ *
+ *********************************************************************/
+/* $Id: flexible_varm.c 2133 2015-09-26 19:16:01Z wkliao $ */
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ *
+ * This program tests PnetCDF flexible varm APIs, i.e. ncmpi_put_varm_all(),
+ * ncmpi_get_varm_all(), and their nonblocking versions, to write a 2D array
+ * double variable of size NY x NX*nproc in parallel.
+ *
+ * The data partitioning patterns on the variable is column-wise.
+ * The local buffer has ghost cells surrounded along both dimensions.
+ *
+ * The compile and run commands are given below.
+ *
+ * % mpicc -O2 -o flexible_varm flexible_varm.c -lpnetcdf
+ *
+ * % mpiexec -l -n 4 ./flexible_varm /pvfs2/wkliao/testfile.nc
+ *
+ * % ncmpidump /pvfs2/wkliao/testfile.nc
+ * netcdf testfile {
+ * // file format: CDF-5 (big variables)
+ * dimensions:
+ * Y = 6 ;
+ * X = 16 ;
+ * variables:
+ * double var(Y, X) ;
+ * data:
+ *
+ * var =
+ * 0, 6, 12, 18, 0, 6, 12, 18, 0, 6, 12, 18, 0, 6, 12, 18,
+ * 1, 7, 13, 19, 1, 7, 13, 19, 1, 7, 13, 19, 1, 7, 13, 19,
+ * 2, 8, 14, 20, 2, 8, 14, 20, 2, 8, 14, 20, 2, 8, 14, 20,
+ * 3, 9, 15, 21, 3, 9, 15, 21, 3, 9, 15, 21, 3, 9, 15, 21,
+ * 4, 10, 16, 22, 4, 10, 16, 22, 4, 10, 16, 22, 4, 10, 16, 22,
+ * 5, 11, 17, 23, 5, 11, 17, 23, 5, 11, 17, 23, 5, 11, 17, 23 ;
+ * }
+ *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h> /* strcpy() */
+#include <assert.h>
+#include <mpi.h>
+#include <pnetcdf.h>
+
+#include <testutils.h>
+
+#define NY 6
+#define NX 4
+#define GHOST 2
+
+#define ERR {if(err!=NC_NOERR){printf("Error at line=%d: %s\n", __LINE__, ncmpi_strerror(err)); nerrs++;}}
+
+#define INIT_PUT_BUF \
+ for (i=0; i<array_of_sizes[0]; i++) { \
+ for (j=0; j<array_of_sizes[1]; j++) { \
+ if (i < GHOST || GHOST+array_of_subsizes[0] <= i || \
+ j < GHOST || GHOST+array_of_subsizes[1] <= j) \
+ buf[i][j] = -1; \
+ else \
+ buf[i][j] = (i-GHOST)*array_of_subsizes[1]+(j-GHOST); \
+ } \
+ }
+
+#define CHECK_PUT_BUF \
+ for (i=0; i<array_of_sizes[0]; i++) { \
+ for (j=0; j<array_of_sizes[1]; j++) { \
+ if (i < GHOST || GHOST+array_of_subsizes[0] <= i || \
+ j < GHOST || GHOST+array_of_subsizes[1] <= j) { \
+ if (buf[i][j] != -1) { \
+ printf("Error: put buffer altered buffer[%d][%d]=%d\n", \
+ i,j,buf[i][j]); \
+ nerrs++; \
+ } \
+ } \
+ else { \
+ if (buf[i][j] != (i-GHOST)*array_of_subsizes[1]+(j-GHOST)) { \
+ printf("Error: put buffer altered buffer[%d][%d]=%d\n", \
+ i,j,buf[i][j]); \
+ nerrs++; \
+ } \
+ } \
+ } \
+ }
+
+#define INIT_GET_BUF \
+ for (i=0; i<array_of_sizes[0]; i++) \
+ for (j=0; j<array_of_sizes[1]; j++) \
+ buf[i][j] = -2;
+
+#define CHECK_GET_BUF \
+ for (i=0; i<array_of_sizes[0]; i++) { \
+ for (j=0; j<array_of_sizes[1]; j++) { \
+ if (i < GHOST || GHOST+array_of_subsizes[0] <= i || \
+ j < GHOST || GHOST+array_of_subsizes[1] <= j) { \
+ if (buf[i][j] != -2) { \
+ printf("Unexpected get buffer[%d][%d]=%d\n", \
+ i,j,buf[i][j]); \
+ nerrs++; \
+ } \
+ } \
+ else { \
+ if (buf[i][j] != (i-GHOST)*array_of_subsizes[1]+(j-GHOST)) { \
+ printf("Unexpected get buffer[%d][%d]=%d\n", \
+ i,j,buf[i][j]); \
+ nerrs++; \
+ } \
+ } \
+ } \
+ }
+
+int main(int argc, char** argv)
+{
+ char filename[256];
+ int i, j, rank, nprocs, err, nerrs=0, req, status;
+ int ncid, cmode, varid, dimid[2];
+ int array_of_sizes[2], array_of_subsizes[2], array_of_starts[2];
+ int buf[NX+2*GHOST][NY+2*GHOST];
+ MPI_Offset start[2], count[2], stride[2], imap[2];
+ MPI_Datatype subarray;
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+
+ if (argc > 2) {
+ if (!rank) printf("Usage: %s [filename]\n",argv[0]);
+ MPI_Finalize();
+ return 0;
+ }
+ strcpy(filename, "testfile.nc");
+ if (argc == 2) strcpy(filename, argv[1]);
+ MPI_Bcast(filename, 256, MPI_CHAR, 0, MPI_COMM_WORLD);
+
+ if (rank == 0) {
+ char cmd_str[256];
+ sprintf(cmd_str, "*** TESTING C %s for flexible varm APIs ", argv[0]);
+ printf("%-66s ------ ", cmd_str); fflush(stdout);
+ }
+
+ /* create a new file for writing ----------------------------------------*/
+ cmode = NC_CLOBBER | NC_64BIT_DATA;
+ err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, MPI_INFO_NULL, &ncid);
+ ERR
+
+ /* define 2 dimensions */
+ err = ncmpi_def_dim(ncid, "Y", NY, &dimid[0]); ERR
+ err = ncmpi_def_dim(ncid, "X", NX*nprocs, &dimid[1]); ERR
+
+ /* define a variable of size NY * (NX * nprocs) */
+ err = ncmpi_def_var(ncid, "var", NC_DOUBLE, 2, dimid, &varid); ERR
+ err = ncmpi_enddef(ncid); ERR
+
+ start[0] = 0; start[1] = NX * rank;
+ count[0] = NY; count[1] = NX;
+ stride[0] = 1; stride[1] = 1;
+ imap[0] = 1; imap[1] = NY; /* would be {NX, 1} if not transposing */
+
+ /* var is partitioned along X dimension in a matrix transported way */
+ array_of_sizes[0] = NX + 2*GHOST;
+ array_of_sizes[1] = NY + 2*GHOST;
+ array_of_subsizes[0] = NX;
+ array_of_subsizes[1] = NY;
+ array_of_starts[0] = GHOST;
+ array_of_starts[1] = GHOST;
+ MPI_Type_create_subarray(2, array_of_sizes, array_of_subsizes,
+ array_of_starts, MPI_ORDER_C, MPI_INT, &subarray);
+ MPI_Type_commit(&subarray);
+
+ /* calling a blocking put_varm flexible API -----------------------------*/
+ /* initiate put buffer contents */
+ INIT_PUT_BUF
+ err = ncmpi_put_varm_all(ncid, varid, start, count, stride, imap, buf,
+ 1, subarray);
+ ERR
+
+ /* check the contents of put buffer */
+ CHECK_PUT_BUF
+
+ /* calling a nonblocking put_varm flexible API --------------------------*/
+ /* initiate put buffer contents */
+ INIT_PUT_BUF
+ err = ncmpi_iput_varm(ncid, varid, start, count, stride, imap, buf,
+ 1, subarray, &req);
+ ERR
+ err = ncmpi_wait_all(ncid, 1, &req, &status); ERR
+ err = status; ERR
+
+ /* check the contents of put buffer */
+ CHECK_PUT_BUF
+
+ /* read back using a blocking get_varm flexible API ---------------------*/
+ /* initiate get buffer contents */
+ INIT_GET_BUF
+
+ /* calling a blocking flexible API */
+ err = ncmpi_get_varm_all(ncid, varid, start, count, stride, imap, buf,
+ 1, subarray);
+ ERR
+
+ /* check the contents of get buffer */
+ CHECK_GET_BUF
+
+ /* read back using a non-blocking flexible API --------------------------*/
+ /* initiate get buffer contents */
+ INIT_GET_BUF
+
+ /* calling a blocking flexible API */
+ err = ncmpi_iget_varm(ncid, varid, start, count, stride, imap, buf,
+ 1, subarray, &req);
+ ERR
+ err = ncmpi_wait_all(ncid, 1, &req, &status); ERR
+ err = status; ERR
+
+ /* check the contents of get buffer */
+ CHECK_GET_BUF
+
+ MPI_Type_free(&subarray);
+
+ err = ncmpi_close(ncid); ERR
+
+ /* check if PnetCDF freed all internal malloc */
+ MPI_Offset malloc_size, sum_size;
+ err = ncmpi_inq_malloc_size(&malloc_size);
+ if (err == NC_NOERR) {
+ MPI_Reduce(&malloc_size, &sum_size, 1, MPI_OFFSET, MPI_SUM, 0, MPI_COMM_WORLD);
+ if (rank == 0 && sum_size > 0)
+ printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n",
+ sum_size);
+ }
+
+ MPI_Allreduce(MPI_IN_PLACE, &nerrs, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
+ if (rank == 0) {
+ if (nerrs) printf(FAIL_STR,nerrs);
+ else printf(PASS_STR);
+ }
+
+ MPI_Finalize();
+ return 0;
+}
+
diff --git a/test/testcases/geopotential.ncdump b/test/testcases/geopotential.ncdump
new file mode 100644
index 0000000..511bef7
--- /dev/null
+++ b/test/testcases/geopotential.ncdump
@@ -0,0 +1,48 @@
+netcdf r6_geopotential_19010101_100000 {
+dimensions:
+ time = UNLIMITED ; // (3 currently)
+ cells = 40962 ;
+ cellneighbors = 6 ;
+ interfaces = 26 ;
+ cellcorners = 6 ;
+variables:
+ double time(time) ;
+ time:long_name = "Time" ;
+ time:units = "days since 01-01-1901" ;
+ time:standard_name = "time" ;
+ time:calendar = "no leap year" ;
+ float grid_center_lat(cells) ;
+ grid_center_lat:long_name = "Latitude of cell center" ;
+ grid_center_lat:units = "radians" ;
+ grid_center_lat:standard_name = "latitude" ;
+ grid_center_lat:bounds = "grid_corner_lat" ;
+ float grid_center_lon(cells) ;
+ grid_center_lon:long_name = "Longitude of cell center" ;
+ grid_center_lon:units = "radians" ;
+ grid_center_lon:standard_name = "longitude" ;
+ grid_center_lon:bounds = "grid_corner_lon" ;
+ float area(cells) ;
+ area:long_name = "Cell area" ;
+ area:units = "square radians" ;
+ int cell_neighbors(cells, cellneighbors) ;
+ cell_neighbors:long_name = "List of neighbors to this cell" ;
+ cell_neighbors:units = "unitless" ;
+ float interfaces(interfaces) ;
+ interfaces:long_name = "Vertical interfaces, in terms of pressure" ;
+ interfaces:units = "Pa" ;
+ interfaces:positive = "down" ;
+ interfaces:axis = "Z" ;
+ float geopotential(time, cells, interfaces) ;
+ geopotential:long_name = "Geo Potential" ;
+ geopotential:units = "m**2/sec**2" ;
+ geopotential:coordinates = "grid_center_lat grid_center_lon" ;
+ float grid_corner_lat(cells, cellcorners) ;
+ grid_corner_lat:long_name = "Latitude of cell corner" ;
+ grid_corner_lat:units = "radians" ;
+ float grid_corner_lon(cells, cellcorners) ;
+ grid_corner_lon:long_name = "Longitude of cell corner" ;
+ grid_corner_lon:units = "radians" ;
+
+// global attributes:
+ :history = "Fri Jan 23 15:41:48 2009: ncks -v grid_corner_lat,grid_corner_lon wind_19010101_100000.nc -A geopotential_19010101_100000.nc" ;
+}
diff --git a/test/testcases/inq_num_vars.c b/test/testcases/inq_num_vars.c
new file mode 100644
index 0000000..302743c
--- /dev/null
+++ b/test/testcases/inq_num_vars.c
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2014, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ *
+ * $Id: inq_num_vars.c 2219 2015-12-11 22:30:03Z wkliao $
+ */
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ *
+ * This program tests if one can get the number of record variables and fixed-
+ * sized variables correctly. It first defines some number of fixed-size and
+ * record variables and then calls the APIs
+ * ncmpi_inq_num_rec_vars() and ncmpi_inq_num_fix_vars()
+ * to varify if the numbers are correct.
+ *
+ * The compile and run commands are given below. This program is to be run on
+ * one MPI process.
+ *
+ * % mpicc -g -o inq_num_vars inq_num_vars.c -lpnetcdf
+ *
+ * % mpiexec -l -n 1 inq_num_vars testfile.nc
+ *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <mpi.h>
+#include <pnetcdf.h>
+
+#include <testutils.h>
+
+#define ERR {if(err!=NC_NOERR)printf("Error at line=%d: %s\n", __LINE__, ncmpi_strerror(err));}
+
+static
+void check_num_vars(int ncid,
+ int expected_nvars,
+ int expected_num_rec_vars,
+ int expected_num_fix_vars,
+ int *nerrs)
+{
+ int err, nvars, num_rec_vars, num_fix_vars;
+
+ err = ncmpi_inq_nvars(ncid, &nvars); ERR
+ err = ncmpi_inq_num_rec_vars(ncid, &num_rec_vars); ERR
+ err = ncmpi_inq_num_fix_vars(ncid, &num_fix_vars); ERR
+
+ if (nvars != expected_nvars) {
+ printf("Error: expecting %d number of variables defined, but got %d\n", expected_nvars, nvars);
+ (*nerrs)++;
+ }
+ if (num_rec_vars != expected_num_rec_vars) {
+ printf("Error: expecting %d number of record variables defined, but got %d\n", expected_num_rec_vars, num_rec_vars);
+ (*nerrs)++;
+ }
+ if (num_fix_vars != expected_num_fix_vars) {
+ printf("Error: expecting %d number of fixed-size variables defined, but got %d\n", expected_num_fix_vars, num_fix_vars);
+ (*nerrs)++;
+ }
+}
+
+int main(int argc, char** argv) {
+ char *filename="testfile.nc";
+ int nerrs, rank, nprocs, err;
+ int ncid, cmode, varid[7], dimid[3];
+ MPI_Info info=MPI_INFO_NULL;
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+
+ if (argc > 2) {
+ if (!rank) printf("Usage: %s [filename]\n",argv[0]);
+ goto fn_exit;
+ }
+ if (argc == 2) filename = argv[1];
+
+ if (rank == 0) {
+ char cmd_str[256];
+ sprintf(cmd_str, "*** TESTING C %s for no. record/fixed variables", argv[0]);
+ printf("%-66s ------ ", cmd_str); fflush(stdout);
+ }
+
+ /* printf("PnetCDF version string: \"%s\"\n", ncmpi_inq_libvers()); */
+
+ /* create a new file for writing ----------------------------------------*/
+ cmode = NC_CLOBBER;
+ err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, info, &ncid); ERR
+
+ /* define dimension and variable */
+ err = ncmpi_def_dim(ncid, "REC_DIM", NC_UNLIMITED, &dimid[0]); ERR
+ err = ncmpi_def_dim(ncid, "Y", 2, &dimid[1]); ERR
+ err = ncmpi_def_dim(ncid, "X", 10, &dimid[2]); ERR
+
+ nerrs = 0;
+
+ err = ncmpi_def_var(ncid, "REC_VAR_1", NC_INT, 1, dimid, &varid[0]); ERR
+ err = ncmpi_def_var(ncid, "REC_VAR_2", NC_INT, 3, dimid, &varid[1]); ERR
+ err = ncmpi_def_var(ncid, "REC_VAR_3", NC_INT, 2, dimid, &varid[2]); ERR
+ err = ncmpi_def_var(ncid, "REC_VAR_4", NC_INT, 1, dimid, &varid[3]); ERR
+
+ check_num_vars(ncid, 4, 4, 0, &nerrs);
+
+ err = ncmpi_def_var(ncid, "FIX_VAR_1", NC_INT, 2, dimid+1, &varid[4]); ERR
+ err = ncmpi_def_var(ncid, "FIX_VAR_2", NC_INT, 1, dimid+1, &varid[5]); ERR
+ err = ncmpi_def_var(ncid, "FIX_VAR_3", NC_INT, 1, dimid+2, &varid[6]); ERR
+
+ check_num_vars(ncid, 7, 4, 3, &nerrs);
+
+ err = ncmpi_enddef(ncid); ERR
+
+ check_num_vars(ncid, 7, 4, 3, &nerrs);
+
+ err = ncmpi_close(ncid); ERR
+
+ /* check if PnetCDF freed all internal malloc */
+ MPI_Offset malloc_size, sum_size;
+ err = ncmpi_inq_malloc_size(&malloc_size);
+ if (err == NC_NOERR) {
+ MPI_Reduce(&malloc_size, &sum_size, 1, MPI_OFFSET, MPI_SUM, 0, MPI_COMM_WORLD);
+ if (rank == 0 && sum_size > 0)
+ printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n",
+ sum_size);
+ }
+
+ MPI_Allreduce(MPI_IN_PLACE, &nerrs, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
+ if (rank == 0) {
+ if (nerrs) printf(FAIL_STR,nerrs);
+ else printf(PASS_STR);
+ }
+
+fn_exit:
+ MPI_Finalize();
+ return 0;
+}
+
diff --git a/test/testcases/inq_num_varsf.f90 b/test/testcases/inq_num_varsf.f90
new file mode 100644
index 0000000..3f2fa4d
--- /dev/null
+++ b/test/testcases/inq_num_varsf.f90
@@ -0,0 +1,166 @@
+!
+! Copyright (C) 2014, Northwestern University and Argonne National Laboratory
+! See COPYRIGHT notice in top-level directory.
+!
+! $Id: inq_num_varsf.f90 2205 2015-11-28 20:41:50Z wkliao $
+
+!
+! This program tests if one can get the number of record variables and
+! fixed-size variables correctly. It first defines some number of
+! fixed-size and record variables and then calls the APIs
+! ncmpi_inq_num_rec_vars() and ncmpi_inq_num_fix_vars()
+! to varify if the numbers are correct.
+!
+! The compile and run commands are given below. This program is to be
+! run on one MPI process.
+!
+! % mpif90 -g -o inq_num_varsf inq_num_varsf.f90 -lpnetcdf
+!
+! % mpiexec -l -n 1 inq_num_varsf testfile.nc
+!
+! % ncmpidump -h testfile.nc
+! netcdf testfile {
+! // file format: CDF-2 (large file)
+! dimensions:
+! X = 10 ;
+! Y = 2 ;
+! REC_DIM = UNLIMITED ; // (0 currently)
+! variables:
+! int REC_VAR_1(REC_DIM) ;
+! int REC_VAR_2(REC_DIM, Y, X) ;
+! int REC_VAR_3(REC_DIM, Y) ;
+! int REC_VAR_4(REC_DIM) ;
+! int FIX_VAR_1(Y, X) ;
+! int FIX_VAR_2(X) ;
+! int FIX_VAR_3(X) ;
+! }
+!
+ subroutine check(err, message)
+ use mpi
+ use pnetcdf
+ implicit none
+ integer err
+ character(len=*) message
+ character(len=128) msg
+
+ ! It is a good idea to check returned value for possible error
+ if (err .NE. NF90_NOERR) then
+ write(6,*) trim(message), trim(nf90mpi_strerror(err))
+ msg = '*** TESTING F90 inq_num_varsf.f90 for no. record/fixed variables'
+ call pass_fail(1, msg)
+ call MPI_Abort(MPI_COMM_WORLD, -1, err)
+ end if
+ end subroutine check
+
+ program main
+ use mpi
+ use pnetcdf
+ implicit none
+
+ character(LEN=256) filename, cmd, msg
+ integer err, ierr, nprocs, rank, cmode, ncid, get_args
+ integer varid(7), dimid(3), dimid_1D(1), dimid_2D(2)
+ integer nerrs, nvars, num_rec_vars, num_fix_vars
+ integer(kind=MPI_OFFSET_KIND) malloc_size, sum_size
+
+ call MPI_Init(ierr)
+ call MPI_Comm_rank(MPI_COMM_WORLD, rank, ierr)
+ call MPI_Comm_size(MPI_COMM_WORLD, nprocs, ierr)
+
+ ! take filename from command-line argument if there is any
+ if (rank .EQ. 0) then
+ filename = "testfile.nc"
+ err = get_args(cmd, filename)
+ endif
+ call MPI_Bcast(err, 1, MPI_INTEGER, 0, MPI_COMM_WORLD, ierr)
+ if (err .EQ. 0) goto 999
+
+ call MPI_Bcast(filename, 256, MPI_CHARACTER, 0, MPI_COMM_WORLD, ierr)
+
+ ! create file, truncate it if exists
+ cmode = IOR(NF90_CLOBBER, NF90_64BIT_OFFSET)
+ err = nf90mpi_create(MPI_COMM_WORLD, filename, cmode, &
+ MPI_INFO_NULL, ncid)
+ call check(err, 'In nf90mpi_create: ')
+
+ ! define dimensions
+ err = nf90mpi_def_dim(ncid, "X", 10_MPI_OFFSET_KIND, dimid(1))
+ call check(err, 'In nf90mpi_def_dim X: ')
+ err = nf90mpi_def_dim(ncid, "Y", 2_MPI_OFFSET_KIND, dimid(2))
+ call check(err, 'In nf90mpi_def_dim Y: ')
+ err = nf90mpi_def_dim(ncid, "REC_DIM", NF90MPI_UNLIMITED, dimid(3))
+ call check(err, 'In nf90mpi_def_dim REC_DIM: ')
+
+ ! define some record variables
+ dimid_1D(1) = dimid(3)
+ dimid_2D(1) = dimid(2)
+ dimid_2D(2) = dimid(3)
+
+ err = nf90mpi_def_var(ncid, "REC_VAR_1", NF90_INT, dimid_1D, varid(1))
+ call check(err, 'In nf90mpi_def_var: REC_VAR_1')
+ err = nf90mpi_def_var(ncid, "REC_VAR_2", NF90_INT, dimid, varid(2))
+ call check(err, 'In nf90mpi_def_var: REC_VAR_2')
+ err = nf90mpi_def_var(ncid, "REC_VAR_3", NF90_INT, dimid_2D, varid(3))
+ call check(err, 'In nf90mpi_def_var: REC_VAR_3')
+ err = nf90mpi_def_var(ncid, "REC_VAR_4", NF90_INT, dimid_1D, varid(4))
+ call check(err, 'In nf90mpi_def_var: REC_VAR_4')
+
+ ! define some fixed-size variables
+ dimid_1D(1) = dimid(1)
+ dimid_2D(1) = dimid(1)
+ dimid_2D(2) = dimid(2)
+
+ err = nf90mpi_def_var(ncid, "FIX_VAR_1", NF90_INT, dimid_2D, varid(5))
+ call check(err, 'In nf90mpi_def_var: FIX_VAR_1')
+ err = nf90mpi_def_var(ncid, "FIX_VAR_2", NF90_INT, dimid_1D, varid(6))
+ call check(err, 'In nf90mpi_def_var: FIX_VAR_2')
+ err = nf90mpi_def_var(ncid, "FIX_VAR_3", NF90_INT, dimid_1D, varid(7))
+ call check(err, 'In nf90mpi_def_var: FIX_VAR_3')
+
+ ! do not forget to exit define mode
+ err = nf90mpi_enddef(ncid)
+ call check(err, 'In nf90mpi_enddef: ')
+
+ ! inquire the numbers of variables (record and fixed-size
+ err = nf90mpi_inquire(ncid, nVariables=nvars)
+ call check(err, 'In nf90mpi_inquire: ')
+ err = nf90mpi_inq_num_rec_vars(ncid, num_rec_vars)
+ call check(err, 'In nf90mpi_inq_num_rec_vars: ')
+ err = nf90mpi_inq_num_fix_vars(ncid, num_fix_vars)
+ call check(err, 'In nf90mpi_inq_num_fix_vars: ')
+
+ ! check if the numbers of variables are expected
+ nerrs = 0
+ if (nvars .NE. 7) then
+ write(6,*) "Error: expecting 7 number of variables defined, but got ", nvars
+ nerrs = nerrs + 1
+ endif
+ if (num_rec_vars .NE. 4) then
+ write(6,*) "Error: expecting 4 number of recond variables defined, but got ", nvars
+ nerrs = nerrs + 1
+ endif
+ if (num_fix_vars .NE. 3) then
+ write(6,*) "Error: expecting 3 number of fixed-size variables defined, but got ", nvars
+ nerrs = nerrs + 1
+ endif
+
+ err = nf90mpi_close(ncid)
+ call check(err, 'In nf90mpi_close: ')
+
+ ! check if there is any PnetCDF internal malloc residue
+ 998 format(A,I13,A)
+ err = nfmpi_inq_malloc_size(malloc_size)
+ if (err == NF_NOERR) then
+ call MPI_Reduce(malloc_size, sum_size, 1, MPI_OFFSET, &
+ MPI_SUM, 0, MPI_COMM_WORLD, ierr)
+ if (rank .EQ. 0 .AND. sum_size .GT. 0_MPI_OFFSET_KIND) print 998, &
+ 'heap memory allocated by PnetCDF internally has ', &
+ sum_size/1048576, ' MiB yet to be freed'
+ endif
+
+ msg = '*** TESTING F90 '//trim(cmd)//' for no. record/fixed variables'
+ if (rank .eq. 0) call pass_fail(nerrs, msg)
+
+ 999 call MPI_Finalize(ierr)
+ end program main
+
diff --git a/test/testcases/inq_recsize.c b/test/testcases/inq_recsize.c
new file mode 100644
index 0000000..cf3bea3
--- /dev/null
+++ b/test/testcases/inq_recsize.c
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2014, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ *
+ * $Id: inq_recsize.c 2133 2015-09-26 19:16:01Z wkliao $
+ */
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ *
+ * This program tests if one can get the size of record block correctly. The
+ * record block size is the sum of individual record of all record variables.
+ * It first defines some number of record and fixed-size variables and then
+ * calls the API ncmpi_inq_recsize() and varify if the numbers are correct.
+ *
+ * The compile and run commands are given below. This program is to be run on
+ * one MPI process.
+ *
+ * % mpicc -g -o inq_recsize inq_recsize.c -lpnetcdf
+ *
+ * % mpiexec -l -n 1 inq_recsize testfile.nc
+ *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <mpi.h>
+#include <pnetcdf.h>
+
+#include <testutils.h>
+
+#define ERR {if(err!=NC_NOERR)printf("Error at line=%d: %s\n", __LINE__, ncmpi_strerror(err));}
+
+int main(int argc, char** argv) {
+ char *filename="testfile.nc";
+ int nerrs, rank, nprocs, err;
+ int ncid, cmode, varid[7], dimid[3];
+ MPI_Offset expected_recsize, recsize;
+ MPI_Info info=MPI_INFO_NULL;
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+
+ if (argc > 2) {
+ if (!rank) printf("Usage: %s [filename]\n",argv[0]);
+ goto fn_exit;
+ }
+ if (argc == 2) filename = argv[1];
+
+ if (rank == 0) {
+ char cmd_str[256];
+ sprintf(cmd_str, "*** TESTING C %s for inquiring record size ", argv[0]);
+ printf("%-66s ------ ", cmd_str); fflush(stdout);
+ }
+
+ /* printf("PnetCDF version string: \"%s\"\n", ncmpi_inq_libvers()); */
+
+ /* create a new file for writing ----------------------------------------*/
+ cmode = NC_CLOBBER;
+ err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, info, &ncid); ERR
+
+ /* define dimension and variable */
+ err = ncmpi_def_dim(ncid, "REC_DIM", NC_UNLIMITED, &dimid[0]); ERR
+ err = ncmpi_def_dim(ncid, "Y", 2, &dimid[1]); ERR
+ err = ncmpi_def_dim(ncid, "X", 10, &dimid[2]); ERR
+
+ nerrs = 0;
+ expected_recsize = 0;
+
+ /* define some record variables */
+ err = ncmpi_def_var(ncid, "REC_VAR_1", NC_INT, 1, dimid, &varid[0]); ERR
+ expected_recsize += sizeof(int);
+ err = ncmpi_def_var(ncid, "REC_VAR_2", NC_INT, 3, dimid, &varid[1]); ERR
+ expected_recsize += 2 * 10 * sizeof(int);
+ err = ncmpi_def_var(ncid, "REC_VAR_3", NC_INT, 2, dimid, &varid[2]); ERR
+ expected_recsize += 2 * sizeof(int);
+ err = ncmpi_def_var(ncid, "REC_VAR_4", NC_INT, 1, dimid, &varid[3]); ERR
+ expected_recsize += sizeof(int);
+
+ /* define some fixed-size variables */
+ err = ncmpi_def_var(ncid, "FIX_VAR_1", NC_INT, 2, dimid+1, &varid[4]); ERR
+ err = ncmpi_def_var(ncid, "FIX_VAR_2", NC_INT, 1, dimid+1, &varid[5]); ERR
+ err = ncmpi_def_var(ncid, "FIX_VAR_3", NC_INT, 1, dimid+2, &varid[6]); ERR
+
+ err = ncmpi_enddef(ncid); ERR
+
+ err = ncmpi_inq_recsize(ncid, &recsize); ERR
+ if (expected_recsize != recsize) {
+ printf("Error at line %d: expecting record size %lld but got %lld\n", __LINE__,expected_recsize, recsize);
+ nerrs++;
+ }
+
+ err = ncmpi_close(ncid); ERR
+
+ /* check if PnetCDF freed all internal malloc */
+ MPI_Offset malloc_size, sum_size;
+ err = ncmpi_inq_malloc_size(&malloc_size);
+ if (err == NC_NOERR) {
+ MPI_Reduce(&malloc_size, &sum_size, 1, MPI_OFFSET, MPI_SUM, 0, MPI_COMM_WORLD);
+ if (rank == 0 && sum_size > 0)
+ printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n",
+ sum_size);
+ }
+
+ MPI_Allreduce(MPI_IN_PLACE, &nerrs, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
+ if (rank == 0) {
+ if (nerrs) printf(FAIL_STR,nerrs);
+ else printf(PASS_STR);
+ }
+
+fn_exit:
+ MPI_Finalize();
+ return 0;
+}
+
diff --git a/test/testcases/inq_recsizef.f90 b/test/testcases/inq_recsizef.f90
new file mode 100644
index 0000000..f78a7fa
--- /dev/null
+++ b/test/testcases/inq_recsizef.f90
@@ -0,0 +1,142 @@
+!
+! Copyright (C) 2014, Northwestern University and Argonne National Laboratory
+! See COPYRIGHT notice in top-level directory.
+!
+! $Id: inq_recsizef.f90 2205 2015-11-28 20:41:50Z wkliao $
+
+!
+! This program tests if one can get the size of record block correctly.
+! The record block size is the sum of individual record of all record
+! variables. It first defines some number of record and fixed-size
+! variables and then calls the API ncmpi_inq_recsize() and varify if
+! the numbers are ! correct.
+!
+! The compile and run commands are given below. This program is to be
+! run on one MPI process.
+!
+! % mpif90 -g -o inq_recsizef inq_recsizef.f90 -lpnetcdf
+!
+! % mpiexec -l -n 1 inq_recsizef testfile.nc
+!
+ subroutine check(err, message)
+ use mpi
+ use pnetcdf
+ implicit none
+ integer err
+ character(len=*) message
+ character(len=128) msg
+
+ ! It is a good idea to check returned value for possible error
+ if (err .NE. NF90_NOERR) then
+ write(6,*) trim(message), trim(nf90mpi_strerror(err))
+ msg = '*** TESTING F90 inq_recsizef.f90 for inquiring record size'
+ call pass_fail(1, msg)
+ call MPI_Abort(MPI_COMM_WORLD, -1, err)
+ end if
+ end subroutine check
+
+ program main
+ use mpi
+ use pnetcdf
+ implicit none
+
+ character(LEN=256) filename, cmd, msg
+ integer err, ierr, nprocs, rank, cmode, ncid, nerrs, get_args
+ integer varid(7), dimid(3), dimid_1D(1), dimid_2D(2)
+ integer(kind=MPI_OFFSET_KIND) expected_recsize, recsize
+ integer(kind=MPI_OFFSET_KIND) malloc_size, sum_size
+
+ call MPI_Init(ierr)
+ call MPI_Comm_rank(MPI_COMM_WORLD, rank, ierr)
+ call MPI_Comm_size(MPI_COMM_WORLD, nprocs, ierr)
+
+ ! take filename from command-line argument if there is any
+ if (rank .EQ. 0) then
+ filename = "testfile.nc"
+ err = get_args(cmd, filename)
+ endif
+ call MPI_Bcast(err, 1, MPI_INTEGER, 0, MPI_COMM_WORLD, ierr)
+ if (err .EQ. 0) goto 999
+
+ call MPI_Bcast(filename, 256, MPI_CHARACTER, 0, MPI_COMM_WORLD, ierr)
+
+ ! create file, truncate it if exists
+ cmode = IOR(NF90_CLOBBER, NF90_64BIT_OFFSET)
+ err = nf90mpi_create(MPI_COMM_WORLD, filename, cmode, &
+ MPI_INFO_NULL, ncid)
+ call check(err, 'In nf90mpi_create: ')
+
+ ! define dimensions
+ err = nf90mpi_def_dim(ncid, "X", 10_MPI_OFFSET_KIND, dimid(1))
+ call check(err, 'In nf90mpi_def_dim X: ')
+ err = nf90mpi_def_dim(ncid, "Y", 2_MPI_OFFSET_KIND, dimid(2))
+ call check(err, 'In nf90mpi_def_dim Y: ')
+ err = nf90mpi_def_dim(ncid, "REC_DIM", NF90MPI_UNLIMITED, dimid(3))
+ call check(err, 'In nf90mpi_def_dim REC_DIM: ')
+
+ ! define some record variables
+ dimid_1D(1) = dimid(3)
+ dimid_2D(1) = dimid(2)
+ dimid_2D(2) = dimid(3)
+
+ expected_recsize = 0;
+
+ err = nf90mpi_def_var(ncid, "REC_VAR_1", NF90_INT, dimid_1D, varid(1))
+ call check(err, 'In nf90mpi_def_var: REC_VAR_1')
+ expected_recsize = expected_recsize + 4
+ err = nf90mpi_def_var(ncid, "REC_VAR_2", NF90_INT, dimid, varid(2))
+ call check(err, 'In nf90mpi_def_var: REC_VAR_2')
+ expected_recsize = expected_recsize + 10 * 2 * 4
+ err = nf90mpi_def_var(ncid, "REC_VAR_3", NF90_INT, dimid_2D, varid(3))
+ call check(err, 'In nf90mpi_def_var: REC_VAR_3')
+ expected_recsize = expected_recsize + 2 * 4
+ err = nf90mpi_def_var(ncid, "REC_VAR_4", NF90_INT, dimid_1D, varid(4))
+ call check(err, 'In nf90mpi_def_var: REC_VAR_4')
+ expected_recsize = expected_recsize + 4
+
+ ! define some fixed-size variables
+ dimid_1D(1) = dimid(1)
+ dimid_2D(1) = dimid(1)
+ dimid_2D(2) = dimid(2)
+
+ err = nf90mpi_def_var(ncid, "FIX_VAR_1", NF90_INT, dimid_2D, varid(5))
+ call check(err, 'In nf90mpi_def_var: FIX_VAR_1')
+ err = nf90mpi_def_var(ncid, "FIX_VAR_2", NF90_INT, dimid_1D, varid(6))
+ call check(err, 'In nf90mpi_def_var: FIX_VAR_2')
+ err = nf90mpi_def_var(ncid, "FIX_VAR_3", NF90_INT, dimid_1D, varid(7))
+ call check(err, 'In nf90mpi_def_var: FIX_VAR_3')
+
+ ! do not forget to exit define mode
+ err = nf90mpi_enddef(ncid)
+ call check(err, 'In nf90mpi_enddef: ')
+
+ ! inquire the numbers of variables (record and fixed-size
+ err = nf90mpi_inq_recsize(ncid, recsize)
+ call check(err, 'In nf90mpi_inquire: ')
+
+ nerrs = 0
+ if (expected_recsize .NE. recsize) then
+ write(6,*) "Error: expecting resize ", expected_recsize,", but got ", recsize
+ nerrs = nerrs + 1
+ endif
+
+ err = nf90mpi_close(ncid)
+ call check(err, 'In nf90mpi_close: ')
+
+ ! check if there is any PnetCDF internal malloc residue
+ 998 format(A,I13,A)
+ err = nfmpi_inq_malloc_size(malloc_size)
+ if (err == NF_NOERR) then
+ call MPI_Reduce(malloc_size, sum_size, 1, MPI_OFFSET, &
+ MPI_SUM, 0, MPI_COMM_WORLD, ierr)
+ if (rank .EQ. 0 .AND. sum_size .GT. 0_MPI_OFFSET_KIND) print 998, &
+ 'heap memory allocated by PnetCDF internally has ', &
+ sum_size/1048576, ' MiB yet to be freed'
+ endif
+
+ msg = '*** TESTING F90 '//trim(cmd)//' for inquiring record size'
+ if (rank .eq. 0) call pass_fail(nerrs, msg)
+
+ 999 call MPI_Finalize(ierr)
+ end program main
+
diff --git a/test/testcases/interop1.sh b/test/testcases/interop1.sh
new file mode 100755
index 0000000..77225fc
--- /dev/null
+++ b/test/testcases/interop1.sh
@@ -0,0 +1,37 @@
+#!/bin/bash
+# a test to ensure we can work with files created by serial netcdf. does
+# require both ncgen and ncdump to be in your path.
+
+# Step 0: see if we have the utilities in our path:
+
+which ncgen >/dev/null
+
+if [ $? -ne 0 ] ; then
+ echo "could not find 'ncgen' (from serial netcdf) in path. exiting"
+ exit 1
+fi
+
+which ncmpidump >/dev/null
+
+if [ $? -ne 0 ] ; then
+ echo "could not find 'ncmpidump' (from parallel-netcdf) in path. exiting"
+ exit 1
+fi
+
+OUTPUT=geo-${RANDOM}-${RANDOM}.nc
+rm -f $OUTPUT
+
+# Step 1: create the file:
+ncgen -b -v 2 -o $OUTPUT geopotential.ncdump
+
+# step 2: ensure we can at least parse the header
+ncmpidump -h $OUTPUT >/dev/null
+
+if [ $? -ne 0 ] ; then
+ echo "error parsing generated netcdf file!"
+ exit 1
+else
+ echo " No Errors"
+ rm $OUTPUT
+ exit 0
+fi
diff --git a/test/testcases/ivarn.c b/test/testcases/ivarn.c
new file mode 100644
index 0000000..87ae2f7
--- /dev/null
+++ b/test/testcases/ivarn.c
@@ -0,0 +1,447 @@
+/*********************************************************************
+ *
+ * Copyright (C) 2015, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ *
+ *********************************************************************/
+/* $Id: ivarn.c 2219 2015-12-11 22:30:03Z wkliao $ */
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * This example tests using calls to ncmpi_iput_varn_int(),
+ * ncmpi_iput_varn_float(), ncmpi_iput_varn_double() to write a sequence of
+ * requests with arbitrary array indices and lengths. Note that the request IDs
+ * in the argument array_of_requests[] of ncmpi_wait_all() are in an arbitray
+ * order (instead in an increasing order).
+ *
+ * The compile and run commands are given below, together with an ncmpidump of
+ * the output file.
+ *
+ * % mpicc -O2 -o ivarn ivarn.c -lpnetcdf
+ * % mpiexec -n 4 ./ivarn /pvfs2/wkliao/testfile.nc
+ * % ncmpidump /pvfs2/wkliao/testfile.nc
+ * netcdf testfile {
+ * // file format: CDF-5 (big variables)
+ * dimensions:
+ * netcdf testfile {
+ * dimensions:
+ * dim000001 = 16 ;
+ * time = UNLIMITED ; // (1 currently)
+ * variables:
+ * int vari0001(time, dim000001) ;
+ * float varr0001(time, dim000001) ;
+ * double vard0001(time, dim000001) ;
+ * int vari0002(time, dim000001) ;
+ * float varr0002(time, dim000001) ;
+ * double vard0002(time, dim000001) ;
+ * data:
+ *
+ * vari0001 =
+ * 1, _, 3, 4, 5, 6, 7, _, 9, 10, 11, 12, 13, 14, _, 16 ;
+ *
+ * varr0001 =
+ * 1.1, _, 3.1, 4.1, 5.1, 6.1, 7.1, _, 9.1, 10.1, 11.1, 12.1, 13.1, 14.1, _, 16.1 ;
+ *
+ * vard0001 =
+ * 1.3, _, 3.3, 4.3, 5.3, 6.3, 7.3, _, 9.3, 10.3, 11.3, 12.3, 13.3, 14.3, _, 16.3 ;
+ *
+ * vari0002 =
+ * 1, _, 3, 4, 5, 6, 7, _, 9, 10, 11, 12, 13, 14, _, 16 ;
+ *
+ * varr0002 =
+ * 1.2, _, 3.2, 4.2, 5.2, 6.2, 7.2, _, 9.2, 10.2, 11.2, 12.2, 13.2, 14.2, _, 16.2 ;
+ *
+ * vard0002 =
+ * 1.4, _, 3.4, 4.4, 5.4, 6.4, 7.4, _, 9.4, 10.4, 11.4, 12.4, 13.4, 14.4, _, 16.4 ;
+ * }
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h> /* strcpy() */
+#include <mpi.h>
+#include <pnetcdf.h>
+
+#include <testutils.h>
+
+#define LEN 16
+#define ERR {if(err!=NC_NOERR)printf("Error at line=%d: %s\n", __LINE__, ncmpi_strerror(err));}
+
+static
+int check_int_buf(int *buffer)
+{
+ int i, nprocs;
+ int expected[LEN];
+
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+
+ for (i=0; i<LEN; i++) expected[i] = i+1;
+ expected[1] = expected[7] = expected[14] = NC_FILL_INT;
+
+ /* check if the contents of buf are expected */
+ for (i=0; i<LEN; i++) {
+ if (nprocs == 1) { if (i == 4) break; }
+ else if (nprocs == 2) {
+ if (3 < i && i < 7) continue;
+ if (i == 12) break;
+ }
+ else if (nprocs == 3) { if (i == 12) break; }
+
+ if (buffer[i] != expected[i]) {
+ printf("Expected read buf[%d]=%d, but got %d\n",
+ i,expected[i],buffer[i]);
+ return 1;
+ }
+ }
+ return 0;
+}
+
+static
+int check_flt_buf(float *buffer, float extra)
+{
+ int i, nprocs;
+ float expected[LEN];
+
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+
+ for (i=0; i<LEN; i++) expected[i] = extra+i+1;
+ expected[1] = expected[7] = expected[14] = NC_FILL_FLOAT;
+
+ /* check if the contents of buf are expected */
+ for (i=0; i<LEN; i++) {
+ if (nprocs == 1) { if (i == 4) break; }
+ else if (nprocs == 2) {
+ if (3 < i && i < 7) continue;
+ if (i == 12) break;
+ }
+ else if (nprocs == 3) { if (i == 12) break; }
+
+ if (buffer[i] != expected[i]) {
+ printf("Expected read buf[%d]=%.1f, but got %.1f\n",
+ i,expected[i],buffer[i]);
+ return 1;
+ }
+ }
+ return 0;
+}
+
+static
+int check_dbl_buf(double *buffer, double extra)
+{
+ int i, nprocs;
+ double expected[LEN];
+
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+
+ for (i=0; i<LEN; i++) expected[i] = extra+i+1;
+ expected[1] = expected[7] = expected[14] = NC_FILL_DOUBLE;
+
+ /* check if the contents of buf are expected */
+ for (i=0; i<LEN; i++) {
+ if (nprocs == 1) { if (i == 4) break; }
+ else if (nprocs == 2) {
+ if (3 < i && i < 7) continue;
+ if (i == 12) break;
+ }
+ else if (nprocs == 3) { if (i == 12) break; }
+
+ if (buffer[i] != expected[i]) {
+ printf("Expected read buf[%d]=%.1f, but got %.1f\n",
+ i,expected[i],buffer[i]);
+ return 1;
+ }
+ }
+ return 0;
+}
+
+int main(int argc, char** argv)
+{
+ char filename[256];
+ int i, rank, nprocs, err, verbose=0, nerrs=0;
+ int ncid, cmode, dimid[2];
+ int vari0001, vari0002, varr0001, varr0002, vard0001, vard0002;
+ MPI_Offset **starts, **counts;
+ int req[LEN], st[LEN], num_reqs=0;
+ int ibuf1[LEN], ibuf2[LEN];
+ float rbuf1[LEN], rbuf2[LEN];
+ double dbuf1[LEN], dbuf2[LEN];
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+
+ if (argc > 2) {
+ if (!rank) printf("Usage: %s [filename]\n",argv[0]);
+ MPI_Finalize();
+ return 0;
+ }
+ strcpy(filename, "testfile.nc");
+ if (argc == 2) strcpy(filename, argv[1]);
+ MPI_Bcast(filename, 256, MPI_CHAR, 0, MPI_COMM_WORLD);
+
+ if (rank == 0) {
+ char cmd_str[256];
+ sprintf(cmd_str, "*** TESTING C %s for ncmpi_iput_varn_<type>() ", argv[0]);
+ printf("%-66s ------ ", cmd_str); fflush(stdout);
+ }
+
+ if (verbose && nprocs != 4 && rank == 0)
+ printf("Warning: %s is intended to run on 4 processes\n",argv[0]);
+
+ /* create a new file for writing ----------------------------------------*/
+ cmode = NC_CLOBBER | NC_64BIT_DATA;
+ err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, MPI_INFO_NULL, &ncid); ERR
+
+ err = ncmpi_def_dim(ncid, "dim000001", LEN, &dimid[1]); ERR
+ err = ncmpi_def_dim(ncid, "time", NC_UNLIMITED, &dimid[0]); ERR
+ err = ncmpi_def_var(ncid, "vari0001", NC_INT, 2, dimid, &vari0001); ERR
+ err = ncmpi_def_var(ncid, "varr0001", NC_FLOAT, 2, dimid, &varr0001); ERR
+ err = ncmpi_def_var(ncid, "vard0001", NC_DOUBLE, 2, dimid, &vard0001); ERR
+ err = ncmpi_def_var(ncid, "vari0002", NC_INT, 2, dimid, &vari0002); ERR
+ err = ncmpi_def_var(ncid, "varr0002", NC_FLOAT, 2, dimid, &varr0002); ERR
+ err = ncmpi_def_var(ncid, "vard0002", NC_DOUBLE, 2, dimid, &vard0002); ERR
+ err = ncmpi_enddef(ncid); ERR
+
+ starts = (MPI_Offset**) malloc(2 * sizeof(MPI_Offset*));
+ counts = (MPI_Offset**) malloc(2 * sizeof(MPI_Offset*));
+ starts[0] = (MPI_Offset*) calloc(2 * 2, sizeof(MPI_Offset));
+ counts[0] = (MPI_Offset*) calloc(2 * 2, sizeof(MPI_Offset));
+ for (i=1; i<2; i++) {
+ starts[i] = starts[i-1] + 2;
+ counts[i] = counts[i-1] + 2;
+ }
+
+ /* assign arbitrary starts and counts */
+ if (rank == 0) {
+ /* vari0001 and vari0002 */
+ starts[0][0] = 0; starts[0][1] = 1; counts[0][0] = 1; counts[0][1] = 1;
+ ibuf1[0] = NC_FILL_INT;
+ err = ncmpi_iput_varn_int(ncid, vari0001, 1, starts, counts, ibuf1, &req[1]); ERR
+ ibuf2[0] = NC_FILL_INT;
+ err = ncmpi_iput_varn_int(ncid, vari0002, 1, starts, counts, ibuf2, &req[7]); ERR
+
+ starts[0][0] = 0; starts[0][1] = 0; counts[0][0] = 1; counts[0][1] = 1;
+ starts[1][0] = 0; starts[1][1] = 2; counts[1][0] = 1; counts[1][1] = 2;
+ ibuf1[1] = 1; ibuf1[2] = 3; ibuf1[3] = 4;
+ err = ncmpi_iput_varn_int(ncid, vari0001, 2, starts, counts, ibuf1+1, &req[0]); ERR
+ ibuf2[1] = 1; ibuf2[2] = 3; ibuf2[3] = 4;
+ err = ncmpi_iput_varn_int(ncid, vari0002, 2, starts, counts, ibuf2+1, &req[6]); ERR
+
+ /* varr0001 and varr0002 */
+ starts[0][0] = 0; starts[0][1] = 1; counts[0][0] = 1; counts[0][1] = 1;
+ rbuf1[0] = NC_FILL_FLOAT;
+ err = ncmpi_iput_varn_float(ncid, varr0001, 1, starts, counts, rbuf1, &req[3]); ERR
+ rbuf2[0] = NC_FILL_FLOAT;
+ err = ncmpi_iput_varn_float(ncid, varr0002, 1, starts, counts, rbuf2, &req[9]); ERR
+
+ starts[0][0] = 0; starts[0][1] = 0; counts[0][0] = 1; counts[0][1] = 1;
+ starts[1][0] = 0; starts[1][1] = 2; counts[1][0] = 1; counts[1][1] = 2;
+ rbuf1[1] = 1.1; rbuf1[2] = 3.1; rbuf1[3] = 4.1;
+ err = ncmpi_iput_varn_float(ncid, varr0001, 2, starts, counts, rbuf1+1, &req[2]); ERR
+ rbuf2[1] = 1.2; rbuf2[2] = 3.2; rbuf2[3] = 4.2;
+ err = ncmpi_iput_varn_float(ncid, varr0002, 2, starts, counts, rbuf2+1, &req[8]); ERR
+
+ /* vard0001 and vard0002 */
+ starts[0][0] = 0; starts[0][1] = 1; counts[0][0] = 1; counts[0][1] = 1;
+ dbuf1[0] = NC_FILL_DOUBLE;
+ err = ncmpi_iput_varn_double(ncid, vard0001, 1, starts, counts, dbuf1, &req[5]); ERR
+ dbuf2[0] = NC_FILL_DOUBLE;
+ err = ncmpi_iput_varn_double(ncid, vard0002, 1, starts, counts, dbuf2, &req[11]); ERR
+
+ starts[0][0] = 0; starts[0][1] = 0; counts[0][0] = 1; counts[0][1] = 1;
+ starts[1][0] = 0; starts[1][1] = 2; counts[1][0] = 1; counts[1][1] = 2;
+ dbuf1[1] = 1.3; dbuf1[2] = 3.3; dbuf1[3] = 4.3;
+ err = ncmpi_iput_varn_double(ncid, vard0001, 2, starts, counts, dbuf1+1, &req[4]); ERR
+ dbuf2[1] = 1.4; dbuf2[2] = 3.4; dbuf2[3] = 4.4;
+ err = ncmpi_iput_varn_double(ncid, vard0002, 2, starts, counts, dbuf2+1, &req[10]); ERR
+
+ num_reqs = 12;
+ /* rank 0 is writing the followings: ("x" means skip, "-" means fill value)
+ 1 - 3 4 x x x x x x x x x x x x
+ */
+ } else if (rank ==1) {
+ /* vari0001 and vari0002 */
+ starts[0][0] = 0; starts[0][1] = 7; counts[0][0] = 1; counts[0][1] = 1;
+ ibuf1[0] = NC_FILL_INT;
+ err = ncmpi_iput_varn_int(ncid, vari0001, 1, starts, counts, ibuf1, &req[1]); ERR
+ ibuf2[0] = NC_FILL_INT;
+ err = ncmpi_iput_varn_int(ncid, vari0002, 1, starts, counts, ibuf2, &req[7]); ERR
+
+ starts[0][0] = 0; starts[0][1] = 8; counts[0][0] = 1; counts[0][1] = 4;
+ ibuf1[1] = 9; ibuf1[2] = 10; ibuf1[3] = 11; ibuf1[4] = 12;
+ err = ncmpi_iput_varn_int(ncid, vari0001, 1, starts, counts, ibuf1+1, &req[0]); ERR
+ ibuf2[1] = 9; ibuf2[2] = 10; ibuf2[3] = 11; ibuf2[4] = 12;
+ err = ncmpi_iput_varn_int(ncid, vari0002, 1, starts, counts, ibuf2+1, &req[6]); ERR
+
+ /* varr0001 and varr0002 */
+ starts[0][0] = 0; starts[0][1] = 7; counts[0][0] = 1; counts[0][1] = 1;
+ rbuf1[0] = NC_FILL_FLOAT;
+ err = ncmpi_iput_varn_float(ncid, varr0001, 1, starts, counts, rbuf1, &req[3]); ERR
+ rbuf2[0] = NC_FILL_FLOAT;
+ err = ncmpi_iput_varn_float(ncid, varr0002, 1, starts, counts, rbuf2, &req[9]); ERR
+
+ starts[0][0] = 0; starts[0][1] = 8; counts[0][0] = 1; counts[0][1] = 4;
+ rbuf1[1] = 9.1; rbuf1[2] = 10.1; rbuf1[3] = 11.1; rbuf1[4] = 12.1;
+ err = ncmpi_iput_varn_float(ncid, varr0001, 1, starts, counts, rbuf1+1, &req[2]); ERR
+ rbuf2[1] = 9.2; rbuf2[2] = 10.2; rbuf2[3] = 11.2; rbuf2[4] = 12.2;
+ err = ncmpi_iput_varn_float(ncid, varr0002, 1, starts, counts, rbuf2+1, &req[8]); ERR
+
+ /* vard0001 and vard0002 */
+ starts[0][0] = 0; starts[0][1] = 7; counts[0][0] = 1; counts[0][1] = 1;
+ dbuf1[0] = NC_FILL_DOUBLE;
+ err = ncmpi_iput_varn_double(ncid, vard0001, 1, starts, counts, dbuf1, &req[5]); ERR
+ dbuf2[0] = NC_FILL_DOUBLE;
+ err = ncmpi_iput_varn_double(ncid, vard0002, 1, starts, counts, dbuf2, &req[11]); ERR
+
+ starts[0][0] = 0; starts[0][1] = 8; counts[0][0] = 1; counts[0][1] = 4;
+ dbuf1[1] = 9.3; dbuf1[2] = 10.3; dbuf1[3] = 11.3; dbuf1[4] = 12.3;
+ err = ncmpi_iput_varn_double(ncid, vard0001, 1, starts, counts, dbuf1+1, &req[4]); ERR
+ dbuf2[1] = 9.4; dbuf2[2] = 10.4; dbuf2[3] = 11.4; dbuf2[4] = 12.4;
+ err = ncmpi_iput_varn_double(ncid, vard0002, 1, starts, counts, dbuf2+1, &req[10]); ERR
+
+ num_reqs = 12;
+ /* rank 1 is writing the followings: ("x" means skip, "-" means fill value)
+ vari0001:
+ x x x x x x x x - 9 10 11 12 x x x x
+ */
+ } else if (rank ==2) {
+ /* vari0001 and vari0002 */
+ starts[0][0] = 0; starts[0][1] = 4; counts[0][0] = 1; counts[0][1] = 3;
+ ibuf1[0] = 5; ibuf1[1] = 6; ibuf1[2] = 7;
+ err = ncmpi_iput_varn_int(ncid, vari0001, 1, starts, counts, ibuf1, &req[0]); ERR
+ ibuf2[0] = 5; ibuf2[1] = 6; ibuf2[2] = 7;
+ err = ncmpi_iput_varn_int(ncid, vari0002, 1, starts, counts, ibuf2, &req[1]); ERR
+
+ /* varr0001 and varr0002 */
+ rbuf1[0] = 5.1; rbuf1[1] = 6.1; rbuf1[2] = 7.1;
+ err = ncmpi_iput_varn_float(ncid, varr0001, 1, starts, counts, rbuf1, &req[2]); ERR
+ rbuf2[0] = 5.2; rbuf2[1] = 6.2; rbuf2[2] = 7.2;
+ err = ncmpi_iput_varn_float(ncid, varr0002, 1, starts, counts, rbuf2, &req[3]); ERR
+
+ /* vard0001 and vard0002 */
+ dbuf1[0] = 5.3; dbuf1[1] = 6.3; dbuf1[2] = 7.3;
+ err = ncmpi_iput_varn_double(ncid, vard0001, 1, starts, counts, dbuf1, &req[4]); ERR
+ dbuf2[0] = 5.4; dbuf2[1] = 6.4; dbuf2[2] = 7.4;
+ err = ncmpi_iput_varn_double(ncid, vard0002, 1, starts, counts, dbuf2, &req[5]); ERR
+
+ num_reqs = 6;
+ /* rank 2 is writing the followings: ("x" means skip, "-" means fill value)
+ vari0001:
+ x x x x x 5 6 7 x x x x x x x x x
+ */
+ } else if (rank ==3) {
+ /* vari0001 and vari0002 */
+ starts[0][0] = 0; starts[0][1] = 14; counts[0][0] = 1; counts[0][1] = 1;
+ ibuf1[0] = NC_FILL_INT;
+ err = ncmpi_iput_varn_int(ncid, vari0001, 1, starts, counts, ibuf1, &req[0]); ERR
+ ibuf2[0] = NC_FILL_INT;
+ err = ncmpi_iput_varn_int(ncid, vari0002, 1, starts, counts, ibuf2, &req[1]); ERR
+
+ starts[0][0] = 0; starts[0][1] = 12; counts[0][0] = 1; counts[0][1] = 2;
+ starts[1][0] = 0; starts[1][1] = 15; counts[1][0] = 1; counts[1][1] = 1;
+ ibuf1[1] = 13; ibuf1[2] = 14; ibuf1[3] = 16;
+ err = ncmpi_iput_varn_int(ncid, vari0001, 2, starts, counts, ibuf1+1, &req[2]); ERR
+ ibuf2[1] = 13; ibuf2[2] = 14; ibuf2[3] = 16;
+ err = ncmpi_iput_varn_int(ncid, vari0002, 2, starts, counts, ibuf2+1, &req[3]); ERR
+
+ /* varr0001 and varr0002 */
+ starts[0][0] = 0; starts[0][1] = 14; counts[0][0] = 1; counts[0][1] = 1;
+ rbuf1[0] = NC_FILL_FLOAT;
+ err = ncmpi_iput_varn_float(ncid, varr0001, 1, starts, counts, rbuf1, &req[4]); ERR
+ rbuf2[0] = NC_FILL_FLOAT;
+ err = ncmpi_iput_varn_float(ncid, varr0002, 1, starts, counts, rbuf2, &req[5]); ERR
+
+ starts[0][0] = 0; starts[0][1] = 12; counts[0][0] = 1; counts[0][1] = 2;
+ starts[1][0] = 0; starts[1][1] = 15; counts[1][0] = 1; counts[1][1] = 1;
+ rbuf1[1] = 13.1; rbuf1[2] = 14.1; rbuf1[3] = 16.1;
+ err = ncmpi_iput_varn_float(ncid, varr0001, 2, starts, counts, rbuf1+1, &req[6]); ERR
+ rbuf2[1] = 13.2; rbuf2[2] = 14.2; rbuf2[3] = 16.2;
+ err = ncmpi_iput_varn_float(ncid, varr0002, 2, starts, counts, rbuf2+1, &req[7]); ERR
+
+ /* vard0001 and vard0002 */
+ starts[0][0] = 0; starts[0][1] = 14; counts[0][0] = 1; counts[0][1] = 1;
+ dbuf1[0] = NC_FILL_DOUBLE;
+ err = ncmpi_iput_varn_double(ncid, vard0001, 1, starts, counts, dbuf1, &req[8]); ERR
+ dbuf2[0] = NC_FILL_DOUBLE;
+ err = ncmpi_iput_varn_double(ncid, vard0002, 1, starts, counts, dbuf2, &req[9]); ERR
+
+ starts[0][0] = 0; starts[0][1] = 12; counts[0][0] = 1; counts[0][1] = 2;
+ starts[1][0] = 0; starts[1][1] = 15; counts[1][0] = 1; counts[1][1] = 1;
+ dbuf1[1] = 13.3; dbuf1[2] = 14.3; dbuf1[3] = 16.3;
+ err = ncmpi_iput_varn_double(ncid, vard0001, 2, starts, counts, dbuf1+1, &req[10]); ERR
+ dbuf2[1] = 13.4; dbuf2[2] = 14.4; dbuf2[3] = 16.4;
+ err = ncmpi_iput_varn_double(ncid, vard0002, 2, starts, counts, dbuf2+1, &req[11]); ERR
+
+ num_reqs = 12;
+ /* rank 3 is writing the followings: ("x" means skip, "-" means fill value)
+ vari0001:
+ x x x x x x x x x x x x 13 14 - 16
+ */
+ }
+
+ err = ncmpi_wait_all(ncid, num_reqs, req, st); ERR
+ for (i=0; i<num_reqs; i++) {
+ err = st[i]; ERR
+ }
+
+ err = ncmpi_close(ncid); ERR
+
+ free(starts[0]);
+ free(counts[0]);
+ free(starts);
+ free(counts);
+
+ err = ncmpi_open(MPI_COMM_WORLD, filename, NC_NOWRITE, MPI_INFO_NULL, &ncid); ERR
+
+ err = ncmpi_inq_varid(ncid, "vari0001", &vari0001); ERR
+ err = ncmpi_inq_varid(ncid, "varr0001", &varr0001); ERR
+ err = ncmpi_inq_varid(ncid, "vard0001", &vard0001); ERR
+ err = ncmpi_inq_varid(ncid, "vari0002", &vari0002); ERR
+ err = ncmpi_inq_varid(ncid, "varr0002", &varr0002); ERR
+ err = ncmpi_inq_varid(ncid, "vard0002", &vard0002); ERR
+
+ for (i=0; i<LEN; i++) ibuf1[i] = -1;
+ err = ncmpi_get_var_int_all(ncid, vari0001, ibuf1); ERR
+ nerrs += check_int_buf(ibuf1);
+
+ for (i=0; i<LEN; i++) ibuf2[i] = -1;
+ err = ncmpi_get_var_int_all(ncid, vari0002, ibuf2); ERR
+ nerrs += check_int_buf(ibuf2);
+
+ for (i=0; i<LEN; i++) rbuf1[i] = -1;
+ err = ncmpi_get_var_float_all(ncid, varr0001, rbuf1); ERR
+ nerrs += check_flt_buf(rbuf1, 0.1);
+
+ for (i=0; i<LEN; i++) rbuf2[i] = -1;
+ err = ncmpi_get_var_float_all(ncid, varr0002, rbuf2); ERR
+ nerrs += check_flt_buf(rbuf2, 0.2);
+
+ for (i=0; i<LEN; i++) dbuf1[i] = -1;
+ err = ncmpi_get_var_double_all(ncid, vard0001, dbuf1); ERR
+ nerrs += check_dbl_buf(dbuf1, 0.3);
+
+ for (i=0; i<LEN; i++) dbuf2[i] = -1;
+ err = ncmpi_get_var_double_all(ncid, vard0002, dbuf2); ERR
+ nerrs += check_dbl_buf(dbuf2, 0.4);
+
+ err = ncmpi_close(ncid); ERR
+
+ /* check if PnetCDF freed all internal malloc */
+ MPI_Offset malloc_size, sum_size;
+ err = ncmpi_inq_malloc_size(&malloc_size);
+ if (err == NC_NOERR) {
+ MPI_Reduce(&malloc_size, &sum_size, 1, MPI_OFFSET, MPI_SUM, 0, MPI_COMM_WORLD);
+ if (rank == 0 && sum_size > 0)
+ printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n",
+ sum_size);
+ }
+
+ MPI_Allreduce(MPI_IN_PLACE, &nerrs, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
+ if (rank == 0) {
+ if (nerrs) printf(FAIL_STR,nerrs);
+ else printf(PASS_STR);
+ }
+
+ MPI_Finalize();
+ return 0;
+}
+
diff --git a/test/testcases/last_large_var.c b/test/testcases/last_large_var.c
new file mode 100644
index 0000000..80d0a7b
--- /dev/null
+++ b/test/testcases/last_large_var.c
@@ -0,0 +1,260 @@
+/*********************************************************************
+ *
+ * Copyright (C) 2015, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ *
+ *********************************************************************/
+/* $Id: last_large_var.c 2291 2016-01-03 05:14:45Z wkliao $ */
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * This program tests the special case when there is no record variable, the
+ * last fixed-size variable can be larger than 2GiB if its starting file offset
+ * is less than 2GiB. See NetCDF Classic Format Limitations (The NetCDF Users
+ * Guide). Quoted here:
+ * "If you don't use the unlimited dimension, only one variable can exceed 2
+ * GiB in size, but it can be as large as the underlying file system permits.
+ * It must be the last variable in the dataset, and the offset to the beginning
+ * of this variable must be less than about 2 GiB."
+ * http://www.unidata.ucar.edu/software/netcdf/old_docs/docs_3_6_3/netcdf-c/nc_005fcreate.html
+ *
+ * To compile:
+ * mpicc -O2 last_large_var.c -o last_large_var -lpnetcdf
+ *
+ * Example commands for MPI run and outputs from running ncmpidump on the
+ * NC file produced by this example program:
+ *
+ * % mpiexec -n 4 ./last_large_var /pvfs2/wkliao/testfile.nc
+ *
+ * % ncmpidump /pvfs2/wkliao/testfile.nc
+ * netcdf testfile {
+ * // file format: CDF-1
+ * netcdf testfile {
+ * dimensions:
+ * Y = 4 ;
+ * X = 5 ;
+ * YY = 66661 ;
+ * XX = 66661 ;
+ * variables:
+ * int var(Y, X) ;
+ * float var_last(YY, XX) ;
+ * }
+ *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <pnetcdf.h>
+
+#include <testutils.h>
+
+#define ERR {if(err!=NC_NOERR){printf("Error at line=%d: %s\n", __LINE__, ncmpi_strerror(err)); nerrs++;}}
+
+static
+int check_last_var(char *filename)
+{
+ int err, nerrs=0, ncid, cmode, varid, dimid[4];
+
+ /* create a new file ---------------------------------------------------*/
+ cmode = NC_CLOBBER;
+ err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, MPI_INFO_NULL, &ncid);
+ ERR
+
+ err = ncmpi_def_dim(ncid, "Y", NC_UNLIMITED, &dimid[0]); ERR
+ err = ncmpi_def_dim(ncid, "X", 5, &dimid[1]); ERR
+ err = ncmpi_def_dim(ncid, "YY", 66661, &dimid[2]); ERR
+ err = ncmpi_def_dim(ncid, "XX", 66661, &dimid[3]); ERR
+
+ /* define only fixed-size variables */
+ err = ncmpi_def_var(ncid, "var", NC_INT, 1, dimid+1, &varid); ERR
+ err = ncmpi_def_var(ncid, "var_last", NC_FLOAT, 2, dimid+2, &varid); ERR
+
+ err = ncmpi_enddef(ncid); ERR
+ err = ncmpi_close(ncid); ERR
+
+ return nerrs;
+}
+
+static
+int check_rec_var(char *filename)
+{
+ int err, nerrs=0, ncid, cmode, varid, dimid[4];
+
+ /* create a new file ---------------------------------------------------*/
+ cmode = NC_CLOBBER;
+ err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, MPI_INFO_NULL, &ncid);
+ ERR
+
+ err = ncmpi_def_dim(ncid, "Y", NC_UNLIMITED, &dimid[0]); ERR
+ err = ncmpi_def_dim(ncid, "X", 5, &dimid[1]); ERR
+ err = ncmpi_def_dim(ncid, "YY", 66661, &dimid[2]); ERR
+ err = ncmpi_def_dim(ncid, "XX", 66661, &dimid[3]); ERR
+
+ /* define a record variable */
+ err = ncmpi_def_var(ncid, "var", NC_INT, 1, dimid, &varid); ERR
+ err = ncmpi_def_var(ncid, "var_last", NC_FLOAT, 2, dimid+2, &varid); ERR
+
+ err = ncmpi_enddef(ncid);
+ if (err != NC_EVARSIZE) {
+ printf("\nError at line=%d: expecting error code NC_EVARSIZE but got %s\n",__LINE__,nc_err_code_name(err));
+ nerrs++;
+ }
+ err = ncmpi_close(ncid);
+ if (err != NC_EVARSIZE) {
+ printf("\nError at line=%d: expecting error code NC_EVARSIZE but got %s\n",__LINE__,nc_err_code_name(err));
+ nerrs++;
+ }
+
+ return nerrs;
+}
+
+static
+int check_not_last_var(char *filename)
+{
+ int err, nerrs=0, ncid, cmode, varid, dimid[4];
+
+ /* create a new file ---------------------------------------------------*/
+ cmode = NC_CLOBBER;
+ err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, MPI_INFO_NULL, &ncid);
+ ERR
+
+ err = ncmpi_def_dim(ncid, "Y", NC_UNLIMITED, &dimid[0]); ERR
+ err = ncmpi_def_dim(ncid, "X", 5, &dimid[1]); ERR
+ err = ncmpi_def_dim(ncid, "YY", 66661, &dimid[2]); ERR
+ err = ncmpi_def_dim(ncid, "XX", 66661, &dimid[3]); ERR
+
+ /* the large variable is not the last */
+ err = ncmpi_def_var(ncid, "var_last", NC_FLOAT, 2, dimid+2, &varid); ERR
+ err = ncmpi_def_var(ncid, "var", NC_INT, 1, dimid+1, &varid); ERR
+
+ err = ncmpi_enddef(ncid);
+ if (err != NC_EVARSIZE) {
+ printf("\nError at line=%d: expecting error code NC_EVARSIZE but got %s\n",__LINE__,nc_err_code_name(err));
+ nerrs++;
+ }
+
+ err = ncmpi_close(ncid);
+ if (err != NC_EVARSIZE) {
+ printf("\nError at line=%d: expecting error code NC_EVARSIZE but got %s\n",__LINE__,nc_err_code_name(err));
+ nerrs++;
+ }
+ return nerrs;
+}
+
+static
+int check_add_var(char *filename)
+{
+ int err, nerrs=0, ncid, cmode, varid, dimid[4];
+
+ /* create a new file ---------------------------------------------------*/
+ cmode = NC_CLOBBER;
+ err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, MPI_INFO_NULL, &ncid);
+ ERR
+
+ err = ncmpi_def_dim(ncid, "Y", NC_UNLIMITED, &dimid[0]); ERR
+ err = ncmpi_def_dim(ncid, "X", 5, &dimid[1]); ERR
+ err = ncmpi_def_dim(ncid, "YY", 66661, &dimid[2]); ERR
+ err = ncmpi_def_dim(ncid, "XX", 66661, &dimid[3]); ERR
+
+ err = ncmpi_def_var(ncid, "var", NC_INT, 1, dimid+1, &varid); ERR
+ err = ncmpi_def_var(ncid, "var_last", NC_FLOAT, 2, dimid+2, &varid); ERR
+
+ err = ncmpi_enddef(ncid); ERR
+
+ /* add a new fixed-size variable */
+ err = ncmpi_redef(ncid); ERR
+ err = ncmpi_def_var(ncid, "var_new", NC_INT, 2, dimid, &varid); ERR
+
+ err = ncmpi_enddef(ncid);
+ if (err != NC_EVARSIZE) {
+ printf("\nError at line=%d: expecting error code NC_EVARSIZE but got %s\n",__LINE__,nc_err_code_name(err));
+ nerrs++;
+ }
+
+ err = ncmpi_close(ncid);
+ if (err != NC_EVARSIZE) {
+ printf("\nError at line=%d: expecting error code NC_EVARSIZE but got %s\n",__LINE__,nc_err_code_name(err));
+ nerrs++;
+ }
+ return nerrs;
+}
+
+static
+int check_var_offset(char *filename)
+{
+ int err, nerrs=0, ncid, cmode, varid, dimid[4];
+
+ /* create a new file ---------------------------------------------------*/
+ cmode = NC_CLOBBER;
+ err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, MPI_INFO_NULL, &ncid);
+ ERR
+
+ err = ncmpi_def_dim(ncid, "Y", NC_UNLIMITED, &dimid[0]); ERR
+ err = ncmpi_def_dim(ncid, "X", 5, &dimid[1]); ERR
+ err = ncmpi_def_dim(ncid, "YY", 66661, &dimid[2]); ERR
+ err = ncmpi_def_dim(ncid, "XX", 66661, &dimid[3]); ERR
+
+ err = ncmpi_def_var(ncid, "var", NC_INT, 1, dimid+1, &varid); ERR
+ err = ncmpi_def_var(ncid, "var_last", NC_FLOAT, 2, dimid+2, &varid); ERR
+
+ /* make the file header size larger than 2 GiB */
+ err = ncmpi__enddef(ncid, 2147483648LL, 1, 1, 1);
+ if (err != NC_EVARSIZE) {
+ printf("\nError at line=%d: expecting error code NC_EVARSIZE but got %s\n",__LINE__,nc_err_code_name(err));
+ nerrs++;
+ }
+
+ err = ncmpi_close(ncid); ERR
+ return nerrs;
+}
+
+int main(int argc, char** argv)
+{
+ char filename[256];
+ int rank, nprocs, err, nerrs=0;
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+
+ if (argc > 2) {
+ if (!rank) printf("Usage: %s [filename]\n",argv[0]);
+ MPI_Finalize();
+ return 0;
+ }
+ strcpy(filename, "testfile.nc");
+ if (argc == 2) strcpy(filename, argv[1]);
+ MPI_Bcast(filename, 256, MPI_CHAR, 0, MPI_COMM_WORLD);
+
+ if (rank == 0) {
+ char cmd_str[256];
+ sprintf(cmd_str, "*** TESTING C %s for last large var in CDF-1/2", argv[0]);
+ printf("%-66s ------ ", cmd_str); fflush(stdout);
+ }
+
+ nerrs += check_last_var(filename);
+ nerrs += check_rec_var(filename);
+ nerrs += check_not_last_var(filename);
+ nerrs += check_add_var(filename);
+ nerrs += check_var_offset(filename);
+
+ /* check if PnetCDF freed all internal malloc */
+ MPI_Offset malloc_size, sum_size;
+ err = ncmpi_inq_malloc_size(&malloc_size);
+ if (err == NC_NOERR) {
+ MPI_Reduce(&malloc_size, &sum_size, 1, MPI_OFFSET, MPI_SUM, 0, MPI_COMM_WORLD);
+ if (rank == 0 && sum_size > 0)
+ printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n",
+ sum_size);
+ }
+
+ MPI_Allreduce(MPI_IN_PLACE, &nerrs, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
+ if (rank == 0) {
+ if (nerrs) printf(FAIL_STR,nerrs);
+ else printf(PASS_STR);
+ }
+
+ MPI_Finalize();
+ return 0;
+}
+
diff --git a/test/testcases/modes.c b/test/testcases/modes.c
new file mode 100644
index 0000000..8e9ec21
--- /dev/null
+++ b/test/testcases/modes.c
@@ -0,0 +1,156 @@
+/*********************************************************************
+ *
+ * Copyright (C) 2014, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ *
+ *********************************************************************/
+/* $Id: modes.c 2219 2015-12-11 22:30:03Z wkliao $ */
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * This program tests if the correct error codes are returns given various
+ * create/open modes.
+ *
+ * NC_EINVAL_CMODE should be returned when creating a file using
+ * comde with both NC_64BIT_OFFSET & NC_64BIT_DATA flags set.
+ *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h> /* strcpy() */
+#include <unistd.h> /* unlink(), access() */
+#include <mpi.h>
+#include <pnetcdf.h>
+
+#include <testutils.h>
+
+#define ERR {if(err!=NC_NOERR)printf("Error at line=%d: %s\n", __LINE__, ncmpi_strerror(err));}
+
+#define EXPECT_ERR(err_no) \
+ if (err != err_no) { \
+ nerrs++; \
+ printf("Error at line %d: expect error code %s but got %s\n", \
+ __LINE__,nc_err_code_name(err_no),nc_err_code_name(err)); \
+ }
+
+static
+int check_modes(char *filename)
+{
+ int rank, err, nerrs=0, file_exist;
+ int ncid, cmode;
+
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+
+ /* delete the file and ignore error */
+ unlink(filename);
+ MPI_Barrier(MPI_COMM_WORLD);
+
+ /* create a new file and test various cmodes ----------------------------*/
+ cmode = NC_CLOBBER;
+
+ /* It is illegal to use both NC_64BIT_OFFSET and NC_64BIT_DATA together */
+ cmode |= NC_64BIT_OFFSET | NC_64BIT_DATA;
+
+ err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, MPI_INFO_NULL, &ncid);
+ EXPECT_ERR(NC_EINVAL_CMODE)
+
+ /* The file should not be created */
+ file_exist = 0;
+ if (rank == 0 && access(filename, F_OK) == 0) file_exist = 1;
+ MPI_Bcast(&file_exist, 1, MPI_INT, 0, MPI_COMM_WORLD);
+ if (file_exist) {
+ printf("Error at line %d: file (%s) should not be created\n", __LINE__, filename);
+ nerrs++;
+ }
+
+ /* delete the file and ignore error */
+ unlink(filename);
+ MPI_Barrier(MPI_COMM_WORLD);
+
+ /* Collectively opening a non-existing file for read, expect error code
+ * NC_ENOENT on all processes */
+ err = ncmpi_open(MPI_COMM_WORLD, filename, NC_NOWRITE, MPI_INFO_NULL, &ncid);
+ EXPECT_ERR(NC_ENOENT)
+
+ file_exist = 0;
+ if (rank == 0 && access(filename, F_OK) == 0) file_exist = 1;
+ MPI_Bcast(&file_exist, 1, MPI_INT, 0, MPI_COMM_WORLD);
+ if (file_exist) {
+ printf("Error at line %d: file (%s) should not be created\n", __LINE__, filename);
+ nerrs++;
+ }
+
+ /* delete the file and ignore error */
+ unlink(filename);
+ MPI_Barrier(MPI_COMM_WORLD);
+
+ /* Collectively opening a non-existing file for write, expect error code
+ * NC_ENOENT on all processes */
+ err = ncmpi_open(MPI_COMM_WORLD, filename, NC_WRITE, MPI_INFO_NULL, &ncid);
+ EXPECT_ERR(NC_ENOENT)
+
+ file_exist = 0;
+ if (rank == 0 && access(filename, F_OK) == 0) file_exist = 1;
+ MPI_Bcast(&file_exist, 1, MPI_INT, 0, MPI_COMM_WORLD);
+ if (file_exist) {
+ printf("Error at line %d: file (%s) should not be created\n", __LINE__, filename);
+ nerrs++;
+ }
+
+ /* delete the file and ignore error */
+ unlink(filename);
+
+ return nerrs;
+}
+
+int main(int argc, char** argv)
+{
+ char filename[256];
+ int rank, err, nerrs=0;
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+
+ if (argc > 2) {
+ if (!rank) printf("Usage: %s [filename]\n",argv[0]);
+ MPI_Finalize();
+ return 0;
+ }
+ strcpy(filename, "testfile.nc");
+ if (argc == 2) strcpy(filename, argv[1]);
+ MPI_Bcast(filename, 256, MPI_CHAR, 0, MPI_COMM_WORLD);
+
+ if (rank == 0) {
+ char cmd_str[256];
+ sprintf(cmd_str, "*** TESTING C %s for file create/open modes ", argv[0]);
+ printf("%-66s ------ ", cmd_str); fflush(stdout);
+ }
+
+ /* test under safe mode enabled */
+ setenv("PNETCDF_SAFE_MODE", "1", 1);
+ nerrs += check_modes(filename);
+
+ /* test under safe mode disabled */
+ setenv("PNETCDF_SAFE_MODE", "0", 1);
+ nerrs += check_modes(filename);
+
+ /* check if PnetCDF freed all internal malloc */
+ MPI_Offset malloc_size, sum_size;
+ err = ncmpi_inq_malloc_size(&malloc_size);
+ if (err == NC_NOERR) {
+ MPI_Reduce(&malloc_size, &sum_size, 1, MPI_OFFSET, MPI_SUM, 0, MPI_COMM_WORLD);
+ if (rank == 0 && sum_size > 0)
+ printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n",
+ sum_size);
+ }
+
+ MPI_Allreduce(MPI_IN_PLACE, &nerrs, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
+ if (rank == 0) {
+ if (nerrs) printf(FAIL_STR,nerrs);
+ else printf(PASS_STR);
+ }
+
+ MPI_Finalize();
+ return 0;
+}
+
diff --git a/test/testcases/ncmpi_vars_null_stride.c b/test/testcases/ncmpi_vars_null_stride.c
new file mode 100644
index 0000000..de69c0c
--- /dev/null
+++ b/test/testcases/ncmpi_vars_null_stride.c
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2003, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ *
+ * $Id: ncmpi_vars_null_stride.c 2133 2015-09-26 19:16:01Z wkliao $
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <mpi.h>
+#include <pnetcdf.h>
+
+#include <testutils.h>
+
+#define HANDLE_ERROR(err) { \
+ nerrs++; \
+ fprintf(stderr, "Error at line %d: %s\n", __LINE__, ncmpi_strerror(err)); \
+ goto fn_exit; \
+}
+
+#define NDIMS 1
+int main(int argc, char **argv)
+{
+ int err, nerrs=0, ncfile, dimid, varid, ndims=NDIMS;
+ int i, nprocs, rank;
+ MPI_Offset start[NDIMS] = {0};
+ MPI_Offset count[NDIMS] = {0};
+ int buf[512];
+ char *filename="testfile.nc";
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+
+ if (argc > 2) {
+ if (!rank) printf("Usage: %s [filename]\n",argv[0]);
+ MPI_Finalize();
+ return 0;
+ }
+ if (argc == 2) filename = argv[1];
+
+ if (rank == 0) {
+ char cmd_str[256];
+ sprintf(cmd_str, "*** TESTING C %s for NULL stride ", argv[0]);
+ printf("%-66s ------ ", cmd_str); fflush(stdout);
+ }
+
+ err = ncmpi_create(MPI_COMM_WORLD, filename, 0, MPI_INFO_NULL, &ncfile);
+ if (err != NC_NOERR) HANDLE_ERROR(err)
+
+ err = ncmpi_def_dim(ncfile, "d1", nprocs, &dimid);
+ if (err != NC_NOERR) HANDLE_ERROR(err)
+
+ err = ncmpi_def_var(ncfile, "v1", NC_INT, ndims, &dimid, &varid);
+ if (err != NC_NOERR) HANDLE_ERROR(err)
+
+ err = ncmpi_enddef(ncfile);
+ if (err != NC_NOERR) HANDLE_ERROR(err)
+
+ start[0] = rank;
+ count[0] = 1;
+ for (i=0; i<512; i++) buf[i] = rank;
+ err = ncmpi_put_vars_int_all(ncfile, varid, start, count, NULL, buf);
+ if (err != NC_NOERR) HANDLE_ERROR(err)
+
+ err = ncmpi_close(ncfile);
+ if (err != NC_NOERR) HANDLE_ERROR(err)
+
+ /* check if PnetCDF freed all internal malloc */
+ MPI_Offset malloc_size, sum_size;
+ err = ncmpi_inq_malloc_size(&malloc_size);
+ if (err == NC_NOERR) {
+ MPI_Reduce(&malloc_size, &sum_size, 1, MPI_OFFSET, MPI_SUM, 0, MPI_COMM_WORLD);
+ if (rank == 0 && sum_size > 0)
+ printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n",
+ sum_size);
+ }
+
+fn_exit:
+ MPI_Allreduce(MPI_IN_PLACE, &nerrs, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
+ if (rank == 0) {
+ if (nerrs) printf(FAIL_STR,nerrs);
+ else printf(PASS_STR);
+ }
+
+ MPI_Finalize();
+ return 0;
+}
diff --git a/test/testcases/noclobber.c b/test/testcases/noclobber.c
new file mode 100644
index 0000000..f7e9a82
--- /dev/null
+++ b/test/testcases/noclobber.c
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2013, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ *
+ * $Id: noclobber.c 2133 2015-09-26 19:16:01Z wkliao $
+ */
+
+/*
+ * This program tests if PnetCDF can return the right error code NC_EEXIST
+ * when create mode NC_NOCLOBBER is used and the file exists.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <mpi.h>
+#include <pnetcdf.h>
+
+#include <testutils.h>
+
+#define ERR if (err!=NC_NOERR) {printf("Error at line %d: %s\n", __LINE__,ncmpi_strerror(err)); exit(-1);}
+
+int main(int argc, char **argv) {
+ char filename[256];
+ int err, nerrs=0, ncid, cmode, rank, nprocs;
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+
+ if (argc > 2) {
+ if (!rank) printf("Usage: %s [filename]\n",argv[0]);
+ MPI_Finalize();
+ return 0;
+ }
+ strcpy(filename, "testfile.nc");
+ if (argc == 2) strcpy(filename, argv[1]);
+ MPI_Bcast(filename, 256, MPI_CHAR, 0, MPI_COMM_WORLD);
+
+ if (rank == 0) {
+ char cmd_str[256];
+ sprintf(cmd_str, "*** TESTING C %s for NC_NOCLOBBER and NC_EEXIST ", argv[0]);
+ printf("%-66s ------ ", cmd_str); fflush(stdout);
+ }
+
+ /* create a file if it does not exist */
+ cmode = NC_CLOBBER;
+ err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, MPI_INFO_NULL, &ncid);
+ ERR
+ err = ncmpi_close(ncid); ERR
+
+ /* now the file exists, test if PnetCDF can return correct error code */
+ cmode = NC_NOCLOBBER;
+ err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, MPI_INFO_NULL, &ncid);
+ if (err != NC_EEXIST) /* err == NC_EOFILE */
+ nerrs++;
+
+ /* check if PnetCDF freed all internal malloc */
+ MPI_Offset malloc_size, sum_size;
+ err = ncmpi_inq_malloc_size(&malloc_size);
+ if (err == NC_NOERR) {
+ MPI_Reduce(&malloc_size, &sum_size, 1, MPI_OFFSET, MPI_SUM, 0, MPI_COMM_WORLD);
+ if (rank == 0 && sum_size > 0)
+ printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n",
+ sum_size);
+ }
+
+ MPI_Allreduce(MPI_IN_PLACE, &nerrs, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
+ if (rank == 0) {
+ if (nerrs) printf(FAIL_STR,nerrs);
+ else printf(PASS_STR);
+ }
+
+ MPI_Finalize();
+ return 0;
+}
diff --git a/test/testcases/nonblocking.c b/test/testcases/nonblocking.c
new file mode 100644
index 0000000..b840f28
--- /dev/null
+++ b/test/testcases/nonblocking.c
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2013, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ *
+ * $Id: nonblocking.c 2133 2015-09-26 19:16:01Z wkliao $
+ */
+
+/*
+ * This program tests the use of nonblocking API.
+ * The write buffer is a 2D array of size NY x NX
+ * It writes the 2nd row of the memory buffer to the 1st row of the variable
+ * array in file. Then it writes the 1st row of the memory buffer to the
+ * 2nd row of the variable array in file.
+ *
+ * The expected reults from the output file contents are:
+ * (when running on 1 MPI process)
+ *
+ * % ncmpidump testfile.nc
+ * netcdf testfile {
+ * // file format: CDF-1
+ * dimensions:
+ * Y = UNLIMITED ; // (2 currently)
+ * X = 5 ;
+ * variables:
+ * int VAR(Y, X) ;
+ * data:
+ *
+ * var =
+ * 1, 1, 1, 1, 1,
+ * 0, 0, 0, 0, 0 ;
+ * }
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <mpi.h>
+#include <pnetcdf.h>
+
+#include <testutils.h>
+
+#define NY 4
+#define NX 5
+#define ERR if (err!=NC_NOERR) {printf("Error at line %d: %s\n", __LINE__,ncmpi_strerror(err)); exit(-1);}
+
+/*----< main() >------------------------------------------------------------*/
+int main(int argc, char **argv) {
+
+ char filename[256];
+ int i, j, err, ncid, varid, dimids[2], req[2], st[2], nerrs=0;
+ int rank, nprocs, buf[NY+1][NX];
+ MPI_Offset start[2], count[2];
+ MPI_Info info;
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+
+ if (argc > 2) {
+ if (!rank) printf("Usage: %s [filename]\n",argv[0]);
+ MPI_Finalize();
+ return 0;
+ }
+ strcpy(filename, "testfile.nc");
+ if (argc == 2) strcpy(filename, argv[1]);
+ MPI_Bcast(filename, 256, MPI_CHAR, 0, MPI_COMM_WORLD);
+
+ if (rank == 0) {
+ char cmd_str[256];
+ sprintf(cmd_str, "*** TESTING C %s for using ncmpi_iput_vara_int() ", argv[0]);
+ printf("%-66s ------ ", cmd_str); fflush(stdout);
+ }
+
+ MPI_Info_create(&info);
+ /* When using PVFS2, unexpected buffer value error message might occur.
+ * This is due to a possible bug in ADIOI_PVFS2_OldWriteStrided() when
+ * filetype is contiguous and buftype is non-contiguous.
+ * Fix: Add ROMIO hint to force ADIO driever to use POSIX I/O */
+ /* MPI_Info_set(info, "romio_pvfs2_posix_write", "enable"); */
+
+ err = ncmpi_create(MPI_COMM_WORLD, filename, NC_CLOBBER, info, &ncid); ERR
+ MPI_Info_free(&info);
+
+ /* define a 2D array */
+ err = ncmpi_def_dim(ncid, "Y", NC_UNLIMITED, &dimids[0]); ERR
+ err = ncmpi_def_dim(ncid, "X", NX, &dimids[1]); ERR
+ err = ncmpi_def_var(ncid, "var", NC_INT, 2, dimids, &varid); ERR
+ err = ncmpi_enddef(ncid); ERR
+
+ /* initialize the contents of the array */
+ for (j=0; j<NY+1; j++) for (i=0; i<NX; i++) buf[j][i] = j;
+
+ start[0] = 2*rank; start[1] = 0;
+ count[0] = 1; count[1] = NX;
+
+ /* call nonblocking API */
+ err = ncmpi_iput_vara_int(ncid, varid, start, count, buf[1], &req[0]); ERR
+
+ start[0] += 1;
+ err = ncmpi_iput_vara_int(ncid, varid, start, count, buf[0], &req[1]); ERR
+
+ st[0] = st[1] = NC_NOERR;
+ err = ncmpi_wait_all(ncid, 2, req, st); ERR
+ err = st[0]; ERR
+ err = st[1]; ERR
+
+ /* check if the contents of buf are altered */
+ for (j=0; j<NY; j++)
+ for (i=0; i<NX; i++)
+ if (buf[j][i] != j)
+ printf("Error: buf[%d][%d]=%d != %d\n",j,i,buf[j][i],j);
+
+ /* check if root process can write to file header in data mode */
+ err = ncmpi_rename_var(ncid, varid, "VAR"); ERR
+
+ err = ncmpi_close(ncid); ERR
+
+ /* open the same file and read back for validate */
+ err = ncmpi_open(MPI_COMM_WORLD, filename, NC_NOWRITE, MPI_INFO_NULL,
+ &ncid); ERR
+
+ err = ncmpi_inq_varid(ncid, "VAR", &varid); ERR
+
+ /* initialize the contents of the array to a different value */
+ for (j=0; j<NY; j++) for (i=0; i<NX; i++) buf[j][i] = -1;
+
+ /* read back variable */
+ start[0] = 2*rank; start[1] = 0;
+ count[0] = 2; count[1] = NX;
+ err = ncmpi_get_vara_int_all(ncid, varid, start, count, buf[0]); ERR
+
+ err = ncmpi_close(ncid); ERR
+
+ /* check if the contents of buf are expected */
+ for (j=0; j<2; j++) {
+ int val = (j == 0) ? 1 : 0;
+ for (i=0; i<NX; i++)
+ if (buf[j][i] != val) {
+ printf("Unexpected read buf[%d][%d]=%d, should be %d\n",
+ j,i,buf[j][i],val);
+ nerrs++;
+ }
+ }
+
+ /* check if PnetCDF freed all internal malloc */
+ MPI_Offset malloc_size, sum_size;
+ err = ncmpi_inq_malloc_size(&malloc_size);
+ if (err == NC_NOERR) {
+ MPI_Reduce(&malloc_size, &sum_size, 1, MPI_OFFSET, MPI_SUM, 0, MPI_COMM_WORLD);
+ if (rank == 0 && sum_size > 0)
+ printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n",
+ sum_size);
+ }
+
+ MPI_Allreduce(MPI_IN_PLACE, &nerrs, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
+ if (rank == 0) {
+ if (nerrs) printf(FAIL_STR,nerrs);
+ else printf(PASS_STR);
+ }
+
+ MPI_Finalize();
+ return 0;
+}
diff --git a/test/testcases/one_record.c b/test/testcases/one_record.c
new file mode 100644
index 0000000..23d93e4
--- /dev/null
+++ b/test/testcases/one_record.c
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2014, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ *
+ * $Id: one_record.c 2133 2015-09-26 19:16:01Z wkliao $
+ */
+
+/*
+ * This program tests the special case of ONLY one record variable is defined
+ * and the record size is not aligned with the 4-byte boundary. As defined in
+ * CDF-1 and CDF-2 format specifications:
+ * "A special case: Where there is exactly one record variable, we drop the
+ * requirement that each record be four-byte aligned, so in this case there
+ * is no record padding."
+ *
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <pnetcdf.h>
+
+#include <testutils.h>
+
+#define ERRCODE 2
+#define ERR if (err != NC_NOERR) {printf("Error at line %d: err=%d %s\n", __LINE__, err, ncmpi_strerror(err));}
+
+#define STR_LEN 19
+#define NUM_VALS 2
+
+/*----< main() >------------------------------------------------------------*/
+int main(int argc, char **argv)
+{
+ int i, err, nerrs=0, rank, nprocs, cmode;
+ int ncid, dimids[2], varid;
+ char data[NUM_VALS][STR_LEN + 1], data_in[NUM_VALS*STR_LEN];
+ MPI_Offset start[2];
+ MPI_Offset count[2];
+ char *filename="testfile.nc";
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+
+ if (argc > 2) {
+ if (!rank) printf("Usage: %s [filename]\n",argv[0]);
+ MPI_Finalize();
+ return 0;
+ }
+ if (argc == 2) filename = argv[1];
+
+ if (rank == 0) {
+ char cmd_str[256];
+ sprintf(cmd_str, "*** TESTING C %s for only one record variable ", argv[0]);
+ printf("%-66s ------ ", cmd_str); fflush(stdout);
+ }
+
+ strcpy(data[0], "2005-04-11_12:00:00"); /* 19 bytes not a multiply of 4 */
+ strcpy(data[1], "2005-04-11_13:00:00");
+
+ cmode = NC_CLOBBER | NC_64BIT_DATA;
+ cmode = NC_CLOBBER;
+ err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, MPI_INFO_NULL, &ncid); ERR
+
+ err = ncmpi_def_dim(ncid, "time", NC_UNLIMITED, dimids); ERR
+ err = ncmpi_def_dim(ncid, "text_dim", STR_LEN, &dimids[1]); ERR
+
+ /* create ONLY one record variable of type NC_CHAR and make sure each
+ * record is of size not aligned with 4-byte boundary.
+ */
+ err = ncmpi_def_var(ncid, "text_var", NC_CHAR, 2, dimids, &varid); ERR
+ err = ncmpi_enddef(ncid); ERR
+
+ /* Write some records of var data. */
+ count[0] = 1;
+ count[1] = STR_LEN;
+ start[0] = 0;
+ start[1] = 0;
+ for (i=0; i<NUM_VALS; i++) {
+ err = ncmpi_put_vara_text_all(ncid, varid, start, count, data[start[0]]);
+ ERR
+ start[0]++;
+ }
+
+ /* read the entire data back */
+ err = ncmpi_get_var_text_all(ncid, varid, data_in); ERR
+
+ /* check the contents */
+ for (i=0; i<NUM_VALS; i++)
+ if (strncmp(data[i], data_in+i*STR_LEN, STR_LEN)) {
+ printf("Error: expecting %s but got %s\n", data[i],data_in+i*STR_LEN);
+ nerrs++;
+ }
+
+ err = ncmpi_close(ncid);
+ ERR
+
+ /* check if PnetCDF freed all internal malloc */
+ MPI_Offset malloc_size, sum_size;
+ err = ncmpi_inq_malloc_size(&malloc_size);
+ if (err == NC_NOERR) {
+ MPI_Reduce(&malloc_size, &sum_size, 1, MPI_OFFSET, MPI_SUM, 0, MPI_COMM_WORLD);
+ if (rank == 0 && sum_size > 0)
+ printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n",
+ sum_size);
+ }
+
+ MPI_Allreduce(MPI_IN_PLACE, &nerrs, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
+ if (rank == 0) {
+ if (nerrs) printf(FAIL_STR,nerrs);
+ else printf(PASS_STR);
+ }
+
+ MPI_Finalize();
+
+ return nerrs;
+}
+
diff --git a/test/testcases/put_parameter.f b/test/testcases/put_parameter.f
new file mode 100644
index 0000000..902e024
--- /dev/null
+++ b/test/testcases/put_parameter.f
@@ -0,0 +1,166 @@
+!
+! Copyright (C) 2015, Northwestern University and Argonne National
+! Laboratory
+! See COPYRIGHT notice in top-level directory.
+!
+! $Id: put_parameter.f 2224 2015-12-16 06:10:36Z wkliao $
+
+! This example tests PnetCDF's avoiding in-place Endianness byte swap when
+! the user's write buffer is immutable, i.e. defined as PARAMETER.
+!
+! The compile and run commands are given below, together with an ncmpidump of
+! the output file.
+!
+! % mpif77 -O2 -o put_parameter put_parameter.f -lpnetcdf
+! % mpiexec -n 4 ./put_parameter /pvfs2/wkliao/testfile.nc
+! % ncmpidump /pvfs2/wkliao/testfile.nc
+! netcdf testfile {
+! // file format: CDF-2 (large file)
+! dimensions:
+! X = 4 ;
+! Y = 4 ;
+! variables:
+! int var1(Y, X) ;
+! int var2(Y, X) ;
+! data:
+!
+! var1 =
+! 1, 2, 3, 4,
+! 1, 2, 3, 4,
+! 1, 2, 3, 4,
+! 1, 2, 3, 4 ;
+!
+! var2 =
+! 5, 6, 7, 8,
+! 5, 6, 7, 8,
+! 5, 6, 7, 8,
+! 5, 6, 7, 8 ;
+! }
+!
+! Note the above dump is in C order
+!
+
+ INTEGER FUNCTION XTRIM(STRING)
+ CHARACTER*(*) STRING
+ INTEGER I, N
+ N = LEN(STRING)
+ DO I = N, 1, -1
+ IF (STRING(I:I) .NE. ' ') GOTO 10
+ ENDDO
+ 10 XTRIM = I
+ END ! FUNCTION XTRIM
+
+ subroutine check(err, message)
+ implicit none
+ include "mpif.h"
+ include "pnetcdf.inc"
+ integer err, XTRIM
+ character*(*) message
+ character*128 msg
+
+ ! It is a good idea to check returned value for possible error
+ if (err .NE. NF_NOERR) then
+ write(6,*) message(1:XTRIM(message)), nfmpi_strerror(err)
+ msg = '*** TESTING F77 put_parameter.f for immutable put '
+ call pass_fail(1, msg)
+ call MPI_Abort(MPI_COMM_WORLD, -1, err)
+ end if
+ end ! subroutine check
+
+ program main
+ implicit none
+ include "mpif.h"
+ include "pnetcdf.inc"
+
+ integer NX, buffer(4)
+ PARAMETER(NX=4)
+ data buffer /5,6,7,8/
+
+ character*256 filename, cmd, msg
+ integer err, ierr, nprocs, rank, nerrs, get_args, XTRIM
+ integer cmode, ncid, varid(2), dimid(2)
+ integer*8 len_ll, start(2), count(2)
+ integer*8 malloc_size, sum_size
+
+ call MPI_Init(ierr)
+ call MPI_Comm_rank(MPI_COMM_WORLD, rank, ierr)
+ call MPI_Comm_size(MPI_COMM_WORLD, nprocs, ierr)
+
+ ! take filename from command-line argument if there is any
+ if (rank .EQ. 0) then
+ filename = "testfile.nc"
+ err = get_args(cmd, filename)
+ endif
+ call MPI_Bcast(err, 1, MPI_INTEGER, 0, MPI_COMM_WORLD, ierr)
+ if (err .EQ. 0) goto 999
+
+ call MPI_Bcast(filename, 256, MPI_CHARACTER, 0,
+ + MPI_COMM_WORLD, ierr)
+
+ nerrs = 0
+
+ ! create file, truncate it if exists
+ cmode = IOR(NF_CLOBBER, NF_64BIT_OFFSET)
+ err = nfmpi_create(MPI_COMM_WORLD, filename, cmode,
+ + MPI_INFO_NULL, ncid)
+ call check(err, 'In nfmpi_create: ')
+
+ ! define dimensions x and y
+ len_ll = NX
+ err = nfmpi_def_dim(ncid, "X", len_ll, dimid(1))
+ call check(err, 'In nfmpi_def_dim X: ')
+
+ len_ll = nprocs
+ err = nfmpi_def_dim(ncid, "Y", len_ll, dimid(2))
+ call check(err, 'In nfmpi_def_dim Y: ')
+
+ ! define a 1D variable of integer type
+ err = nfmpi_def_var(ncid, "var1", NF_INT, 2, dimid, varid(1))
+ call check(err, 'In nfmpi_def_var: ')
+
+ err = nfmpi_def_var(ncid, "var2", NF_INT, 2, dimid, varid(2))
+ call check(err, 'In nfmpi_def_var: ')
+
+ ! do not forget to exit define mode
+ err = nfmpi_enddef(ncid)
+ call check(err, 'In nfmpi_enddef: ')
+
+ ! now we are in data mode
+
+ start(1) = 1
+ start(2) = rank + 1
+ count(1) = NX
+ count(2) = 1
+!
+! pgf77 does not like using (/1,2,3,4/) as a function argument
+! err = nfmpi_put_vara_int_all(ncid, varid(1), start, count,
+! + (/1,2,3,4/))
+! call check(err, 'In nfmpi_put_var_int_all: ')
+!
+ err = nfmpi_put_vara_int_all(ncid, varid(2), start, count,
+ + buffer)
+ call check(err, 'In nfmpi_put_var_int_all: ')
+
+ ! close the file
+ err = nfmpi_close(ncid)
+ call check(err, 'In nfmpi_close: ')
+
+ ! check if there is any PnetCDF internal malloc residue
+ 998 format(A,I13,A)
+ err = nfmpi_inq_malloc_size(malloc_size)
+ if (err .EQ. NF_NOERR) then
+ call MPI_Reduce(malloc_size, sum_size, 1, MPI_OFFSET,
+ + MPI_SUM, 0, MPI_COMM_WORLD, err)
+ if (rank .EQ. 0 .AND. sum_size .GT. 0)
+ + print 998,
+ + 'heap memory allocated by PnetCDF internally has ',
+ + sum_size/1048576, ' MiB yet to be freed'
+ endif
+
+ msg = '*** TESTING F77 '//cmd(1:XTRIM(cmd))//
+ + ' for using immutable write buf '
+ if (rank .eq. 0) call pass_fail(nerrs, msg)
+
+ 999 call MPI_Finalize(ierr)
+ end ! program main
+
diff --git a/test/testcases/record.c b/test/testcases/record.c
new file mode 100644
index 0000000..2f3bfdf
--- /dev/null
+++ b/test/testcases/record.c
@@ -0,0 +1,299 @@
+/*
+ * Copyright (C) 2014, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ *
+ * $Id: record.c 2219 2015-12-11 22:30:03Z wkliao $
+ */
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ *
+ * This program tests if the number of records is updated correctly. It first
+ * writes to the 2nd record of a variable, followed by writing to the 1st
+ * record. After the 2nd write, a call to ncmpi_inq_dimlen() or ncmpi_inq_dim()
+ * should report seeing 2 records. Then, it does a similar test under
+ * independent data mode. The same test will repeat for 3 cases:
+ * 1) there is only one 1D record variable
+ * 2) there is only one 3D record variable
+ * 3) there are one 1D record variable and one 3D record variable
+ *
+ * The compile and run commands are given below. This program is to be run on
+ * one MPI process.
+ *
+ * % mpicc -g -o record record.c -lpnetcdf
+ *
+ * % mpiexec -l -n 1 record record.nc
+ *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <mpi.h>
+#include <pnetcdf.h>
+
+#include <testutils.h>
+
+#define ERR {if(err!=NC_NOERR) {nerrs++; printf("Error at line=%d: %s\n", __LINE__, ncmpi_strerror(err));}}
+
+static
+int test_only_record_var_1D(char *filename)
+{
+ int ncid, cmode, varid, dimid, buf[20], err, nerrs=0;
+ MPI_Offset start, count, length;
+ MPI_Info info=MPI_INFO_NULL;
+
+ /* create a new file for writing ----------------------------------------*/
+ cmode = NC_CLOBBER;
+ err = ncmpi_create(MPI_COMM_SELF, filename, cmode, info, &ncid); ERR
+
+ /* define dimension and variable */
+ err = ncmpi_def_dim(ncid, "REC_DIM", NC_UNLIMITED, &dimid); ERR
+ err = ncmpi_def_var(ncid, "REC_VAR_1D", NC_INT, 1, &dimid, &varid); ERR
+ err = ncmpi_enddef(ncid); ERR
+
+ /* write the 2nd record first */
+ buf[0] = 91;
+ start = 1; count = 1;
+ err = ncmpi_put_vara_int_all(ncid, varid, &start, &count, buf); ERR
+
+ /* write the 1st record now */
+ buf[0] = 90;
+ start = 0; count = 1;
+ err = ncmpi_put_vara_int_all(ncid, varid, &start, &count, buf); ERR
+
+ err = ncmpi_inq_dimlen(ncid, dimid, &length); ERR
+ if (length != 2) {
+ printf("Error: expecting 2 records, but got %lld record(s)\n",length);
+ nerrs++;
+ }
+
+ if (nerrs == 0) { /* test independent data mode */
+ err = ncmpi_begin_indep_data(ncid); ERR
+ /* write the 4th record */
+ buf[0] = 93;
+ start = 3; count = 1;
+ err = ncmpi_put_vara_int(ncid, varid, &start, &count, buf); ERR
+
+ /* write the 3rd record */
+ buf[0] = 92; buf[1] = 93;
+ start = 2; count = 2;
+ err = ncmpi_put_vara_int(ncid, varid, &start, &count, buf); ERR
+
+ err = ncmpi_inq_dimlen(ncid, dimid, &length); ERR
+ if (length != 4) {
+ printf("Error: expecting 4 records, but got %lld record(s)\n",
+ length);
+ nerrs++;
+ }
+ err = ncmpi_end_indep_data(ncid); ERR
+ }
+ err = ncmpi_close(ncid); ERR
+ return nerrs;
+}
+
+static
+int test_only_record_var_3D(char *filename)
+{
+ int i, ncid, cmode, varid, dimid[3], buf[20], err, nerrs=0;
+ MPI_Offset start[3], count[3], length;
+ MPI_Info info=MPI_INFO_NULL;
+
+ /* create a new file for writing ----------------------------------------*/
+ cmode = NC_CLOBBER;
+ err = ncmpi_create(MPI_COMM_SELF, filename, cmode, info, &ncid); ERR
+
+ /* define dimension and variable */
+ err = ncmpi_def_dim(ncid, "REC_DIM", NC_UNLIMITED, &dimid[0]); ERR
+ err = ncmpi_def_dim(ncid, "FIX_DIM_Y", 2, &dimid[1]); ERR
+ err = ncmpi_def_dim(ncid, "FIX_DIM_X", 10, &dimid[2]); ERR
+ err = ncmpi_def_var(ncid, "REC_VAR_3D", NC_INT, 3, dimid, &varid); ERR
+ err = ncmpi_enddef(ncid); ERR
+
+ start[1] = 0; start[2] = 0; count[0] = 1; count[1] = 2; count[2] = 5;
+
+ /* write the 2nd record first */
+ for (i=0; i<20; i++) buf[i] = 91;
+ start[0] = 1;
+ err = ncmpi_put_vara_int_all(ncid, varid, start, count, buf); ERR
+
+ /* write the 1st record now */
+ for (i=0; i<20; i++) buf[i] = 90;
+ start[0] = 0;
+ err = ncmpi_put_vara_int_all(ncid, varid, start, count, buf); ERR
+
+ err = ncmpi_inq_dimlen(ncid, dimid[0], &length); ERR
+ if (length != 2) {
+ printf("Error: expecting 2 records, but got %lld record(s)\n",length);
+ nerrs++;
+ }
+
+ if (nerrs == 0) { /* test independent data mode */
+ err = ncmpi_begin_indep_data(ncid); ERR
+ /* write the 4th record */
+ for (i=0; i<20; i++) buf[i] = 93;
+ start[0] = 3;
+ err = ncmpi_put_vara_int(ncid, varid, start, count, buf); ERR
+
+ /* write the 3rd record */
+ for (i=0; i<20; i++) buf[i] = 92;
+ start[0] = 2;
+ err = ncmpi_put_vara_int(ncid, varid, start, count, buf); ERR
+
+ err = ncmpi_inq_dimlen(ncid, dimid[0], &length); ERR
+ if (length != 4) {
+ printf("Error: expecting 4 records, but got %lld record(s)\n",
+ length);
+ nerrs++;
+ }
+ err = ncmpi_end_indep_data(ncid); ERR
+ }
+ err = ncmpi_close(ncid); ERR
+ return nerrs;
+}
+
+static
+int test_two_record_var(char *filename)
+{
+ int i, ncid, cmode, varid[2], dimid[3], buf[20], err, nerrs=0;
+ MPI_Offset start[3], count[3], length;
+ MPI_Info info=MPI_INFO_NULL;
+
+ /* create a new file for writing ----------------------------------------*/
+ cmode = NC_CLOBBER;
+ err = ncmpi_create(MPI_COMM_SELF, filename, cmode, info, &ncid); ERR
+
+ /* define dimension and variable */
+ err = ncmpi_def_dim(ncid, "REC_DIM", NC_UNLIMITED, &dimid[0]); ERR
+ err = ncmpi_def_dim(ncid, "FIX_DIM_Y", 2, &dimid[1]); ERR
+ err = ncmpi_def_dim(ncid, "FIX_DIM_X", 10, &dimid[2]); ERR
+ err = ncmpi_def_var(ncid, "REC_VAR_1D", NC_INT, 1, dimid, &varid[0]); ERR
+ err = ncmpi_def_var(ncid, "REC_VAR_3D", NC_INT, 3, dimid, &varid[1]); ERR
+ err = ncmpi_enddef(ncid); ERR
+
+ /* REC_VAR_1D: write the 2nd record first */
+ buf[0] = 91;
+ start[0] = 1; count[0] = 1;
+ err = ncmpi_put_vara_int_all(ncid, varid[0], start, count, buf); ERR
+
+ /* write the 1st record now */
+ buf[0] = 90;
+ start[0] = 0; count[0] = 1;
+ err = ncmpi_put_vara_int_all(ncid, varid[0], start, count, buf); ERR
+
+ err = ncmpi_inq_dimlen(ncid, dimid[0], &length); ERR
+ if (length != 2) {
+ printf("Error: expecting 2 records, but got %lld record(s)\n",length);
+ nerrs++;
+ }
+
+ if (nerrs == 0) { /* test independent data mode */
+ err = ncmpi_begin_indep_data(ncid); ERR
+ /* write the 4th record */
+ buf[0] = 93;
+ start[0] = 3; count[0] = 1;
+ err = ncmpi_put_vara_int(ncid, varid[0], start, count, buf); ERR
+
+ /* write the 3rd and 4th records */
+ buf[0] = 92; buf[1] = 93;
+ start[0] = 2; count[0] = 2;
+ err = ncmpi_put_vara_int(ncid, varid[0], start, count, buf); ERR
+
+ err = ncmpi_inq_dimlen(ncid, dimid[0], &length); ERR
+ if (length != 4) {
+ printf("Error: expecting 4 records, but got %lld record(s)\n",
+ length);
+ nerrs++;
+ }
+ err = ncmpi_end_indep_data(ncid); ERR
+ }
+
+ /* REC_VAR_3D: write the 2nd record first */
+ start[1] = 0; start[2] = 0; count[0] = 1; count[1] = 2; count[2] = 5;
+
+ for (i=0; i<20; i++) buf[i] = 91;
+ start[0] = 1;
+ err = ncmpi_put_vara_int_all(ncid, varid[1], start, count, buf); ERR
+
+ /* write the 1st record now */
+ for (i=0; i<20; i++) buf[i] = 90;
+ start[0] = 0;
+ err = ncmpi_put_vara_int_all(ncid, varid[1], start, count, buf); ERR
+
+ err = ncmpi_inq_dimlen(ncid, dimid[0], &length); ERR
+ if (length != 4) {
+ printf("Error: expecting 4 records, but got %lld record(s)\n",length);
+ nerrs++;
+ }
+
+ if (nerrs == 0) { /* test independent data mode */
+ err = ncmpi_begin_indep_data(ncid); ERR
+ /* write the 4th record */
+ for (i=0; i<20; i++) buf[i] = 93;
+ start[0] = 3;
+ err = ncmpi_put_vara_int(ncid, varid[1], start, count, buf); ERR
+
+ /* write the 3rd record */
+ for (i=0; i<20; i++) buf[i] = 92;
+ start[0] = 2;
+ err = ncmpi_put_vara_int(ncid, varid[1], start, count, buf); ERR
+
+ err = ncmpi_inq_dimlen(ncid, dimid[0], &length); ERR
+ if (length != 4) {
+ printf("Error: expecting 4 records, but got %lld record(s)\n",
+ length);
+ nerrs++;
+ }
+ err = ncmpi_end_indep_data(ncid); ERR
+ }
+ err = ncmpi_close(ncid); ERR
+ return nerrs;
+}
+
+int main(int argc, char** argv) {
+ char *filename="testfile.nc";
+ int nerrs=0, rank, nprocs, err;
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+
+ if (argc > 2) {
+ if (!rank) printf("Usage: %s [filename]\n",argv[0]);
+ goto fn_exit;
+ }
+ if (argc == 2) filename = argv[1];
+
+ if (rank == 0) {
+ char cmd_str[256];
+ sprintf(cmd_str, "*** TESTING C %s for write records in reversed order", argv[0]);
+ printf("%-66s ------ ", cmd_str); fflush(stdout);
+ }
+
+ if (rank >= 1) goto fn_exit; /* this test is for running 1 process */
+
+ /* test only one 1D record variable */
+ nerrs += test_only_record_var_1D(filename);
+
+ /* test only one 3D record variable */
+ nerrs += test_only_record_var_3D(filename);
+
+ /* test two record variables */
+ nerrs += test_two_record_var(filename);
+
+ /* check if PnetCDF freed all internal malloc */
+ MPI_Offset malloc_size;
+ err = ncmpi_inq_malloc_size(&malloc_size);
+ if (err == NC_NOERR && malloc_size > 0) /* this test is for running 1 process */
+ printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n",
+ malloc_size);
+
+fn_exit:
+ MPI_Allreduce(MPI_IN_PLACE, &nerrs, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
+ if (rank == 0) {
+ if (nerrs) printf(FAIL_STR,nerrs);
+ else printf(PASS_STR);
+ }
+
+ MPI_Finalize();
+ return 0;
+}
+
diff --git a/test/testcases/redef-good.ncdump b/test/testcases/redef-good.ncdump
new file mode 100644
index 0000000..10f1a56
--- /dev/null
+++ b/test/testcases/redef-good.ncdump
@@ -0,0 +1,63 @@
+netcdf test {
+// file format: CDF-2 (large file)
+dimensions:
+ dim0 = 10 ;
+ dim1 = 3 ;
+ dim5 = 5 ;
+ dim9 = 9 ;
+ dim2 = 10 ;
+variables:
+ int xyz(dim0, dim1) ;
+ int connect(dim0, dim5) ;
+ int connect_exterior(dim0, dim9) ;
+ double xyz_r(dim0, dim2) ;
+data:
+
+ xyz =
+ 0, 1, 2,
+ 3, 4, 5,
+ 6, 7, 8,
+ 9, 10, 11,
+ 12, 13, 14,
+ 15, 16, 17,
+ 18, 19, 20,
+ 21, 22, 23,
+ 24, 25, 26,
+ 27, 28, 29 ;
+
+ connect =
+ 0, 1, 2, 3, 4,
+ 5, 6, 7, 8, 9,
+ 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19,
+ 20, 21, 22, 23, 24,
+ 25, 26, 27, 28, 29,
+ 30, 31, 32, 33, 34,
+ 35, 36, 37, 38, 39,
+ 40, 41, 42, 43, 44,
+ 45, 46, 47, 48, 49;
+
+ connect_exterior =
+ 0, 1, 2, 3, 4, 5, 6, 7, 8,
+ 9, 10, 11, 12, 13, 14, 15, 16, 17,
+ 18, 19, 20, 21, 22, 23, 24, 25, 26,
+ 27, 28, 29, 30, 31, 32, 33, 34, 35,
+ 36, 37, 38, 39, 40, 41, 42, 43, 44,
+ 45, 46, 47, 48, 49, 50, 51, 52, 53,
+ 54, 55, 56, 57, 58, 59, 60, 61, 62,
+ 63, 64, 65, 66, 67, 68, 69, 70, 71,
+ 72, 73, 74, 75, 76, 77, 78, 79, 80,
+ 81, 82, 83, 84, 85, 86, 87, 88, 89 ;
+
+ xyz_r =
+ 0, 1, 4, 9, 16, 25, 36, 49, 64, 81,
+ 100, 121, 144, 169, 196, 225, 256, 289, 324, 361,
+ 400, 441, 484, 529, 576, 625, 676, 729, 784, 841,
+ 900, 961, 1024, 1089, 1156, 1225, 1296, 1369, 1444, 1521,
+ 1600, 1681, 1764, 1849, 1936, 2025, 2116, 2209, 2304, 2401,
+ 2500, 2601, 2704, 2809, 2916, 3025, 3136, 3249, 3364, 3481,
+ 3600, 3721, 3844, 3969, 4096, 4225, 4356, 4489, 4624, 4761,
+ 4900, 5041, 5184, 5329, 5476, 5625, 5776, 5929, 6084, 6241,
+ 6400, 6561, 6724, 6889, 7056, 7225, 7396, 7569, 7744, 7921,
+ 8100, 8281, 8464, 8649, 8836, 9025, 9216, 9409, 9604, 9801 ;
+}
diff --git a/test/testcases/redef1.c b/test/testcases/redef1.c
new file mode 100644
index 0000000..2658c50
--- /dev/null
+++ b/test/testcases/redef1.c
@@ -0,0 +1,197 @@
+/*
+ * Copyright (C) 2003, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ *
+ * $Id: redef1.c 2133 2015-09-26 19:16:01Z wkliao $
+ */
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ *
+ * This program tests redefine mode.
+ *
+ * The compile and run commands are given below.
+ *
+ * % mpicc -g -o redef1 redef1.c -lpnetcdf
+ *
+ * % mpiexec -l -n 4 redef1 testfile.nc
+ *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <pnetcdf.h>
+
+#include <testutils.h>
+
+#define PNCDF_Error(err, msg) \
+ if (err != NC_NOERR) { \
+ printf("Error: %s (%s)\n", msg, ncmpi_strerror(err)); \
+ nerrs++; \
+ goto fn_exit; \
+ }
+
+int main(int argc, char** argv)
+{
+ char filename[256]="redef1.nc";
+ int i, j, k, commsize, rank, ncid, verbose=0, err, nerrs=0;
+ int dim0id, dim1id, dim5id, dim9id, dim2id, dimsid[2], dims2id[2];
+ int varid, var3id, var4id, var2id;
+ int *data;
+ double *dbl_data;
+ MPI_Offset len0=10, len1=3, len5=5, len9=9, len2=10;
+ MPI_Offset start[2], count[2];
+ MPI_Comm comm = MPI_COMM_WORLD;
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_size(comm, &commsize);
+ MPI_Comm_rank(comm, &rank);
+
+ if (argc > 2) {
+ if (!rank) printf("Usage: %s [filename]\n",argv[0]);
+ MPI_Finalize();
+ return 0;
+ }
+ if (argc == 2) strcpy(filename, argv[1]);
+
+ if (rank == 0) {
+ char cmd_str[256];
+ sprintf(cmd_str, "*** TESTING C %s for entering re-define mode ", argv[0]);
+ printf("%-66s ------ ", cmd_str); fflush(stdout);
+ }
+
+ if (commsize > 1 && rank == 0 && verbose)
+ printf("Warning: %s is designed to run on 1 process\n",argv[0]);
+
+ err = ncmpi_create(comm, filename, NC_CLOBBER|NC_64BIT_OFFSET,
+ MPI_INFO_NULL, &ncid);
+ PNCDF_Error(err, "create")
+
+ err = ncmpi_def_dim(ncid, "dim0", len0, &dim0id);
+ PNCDF_Error(err, "def_dim0")
+
+ err = ncmpi_def_dim(ncid, "dim1", len1, &dim1id);
+ PNCDF_Error(err, "def_dim1")
+
+ err = ncmpi_def_dim(ncid, "dim5", len5, &dim5id);
+ PNCDF_Error(err, "def_dim5")
+
+ err = ncmpi_def_dim(ncid, "dim9", len9, &dim9id);
+ PNCDF_Error(err, "def_dim9")
+
+ dimsid[0] = dim0id;
+ dimsid[1] = dim1id;
+ err = ncmpi_def_var(ncid, "xyz", NC_INT, 2, dimsid, &varid);
+ PNCDF_Error(err, "def_var")
+
+ dimsid[0] = dim0id;
+ dimsid[1] = dim5id;
+ err = ncmpi_def_var(ncid, "connect", NC_INT, 2, dimsid, &var3id);
+ PNCDF_Error(err, "def_var3")
+
+ dimsid[0] = dim0id;
+ dimsid[1] = dim9id;
+ err = ncmpi_def_var(ncid, "connect_exterior", NC_INT, 2, dimsid, &var4id);
+ PNCDF_Error(err, "def_var4")
+
+ err = ncmpi_enddef(ncid);
+ PNCDF_Error(err, "enddef")
+
+ /* put data */
+ start[0] = 0;
+ start[1] = 0;
+ count[0] = len0;
+ count[1] = len1;
+
+ data = (int*) malloc(len0*len1 * sizeof(int));
+ k=0;
+ for (i=0; i<len0; i++)
+ for (j=0; j<len1; j++)
+ data[i*len1+j] = k++;
+ if (rank > 0) count[0] = count[1] = 0;
+ err = ncmpi_put_vara_int_all(ncid, varid, start, count, &data[0]);
+ PNCDF_Error(err, "put1")
+ free(data);
+
+ count[0] = len0;
+ count[1] = len5;
+ data = (int*) malloc(len0*len5 * sizeof(int));
+ k=0;
+ for (i=0; i<len0; i++)
+ for (j=0; j<len5; j++)
+ data[i*len5+j] = k++;
+ if (rank > 0) count[0] = count[1] = 0;
+ err = ncmpi_put_vara_int_all(ncid, var3id, start, count, &data[0]);
+ PNCDF_Error(err, "put3")
+ free(data);
+
+ count[0] = len0;
+ count[1] = len9;
+ data = (int*) malloc(len0*len9 * sizeof(int));
+ k=0;
+ for (i=0; i<len0; i++)
+ for (j=0; j<len9; j++)
+ data[i*len9+j] = k++;
+ if (rank > 0) count[0] = count[1] = 0;
+ err = ncmpi_put_vara_int_all(ncid, var4id, start, count, &data[0]);
+ PNCDF_Error(err, "put4")
+ free(data);
+
+ err = ncmpi_close(ncid);
+ PNCDF_Error(err, "close")
+
+ err = ncmpi_open(comm, filename, NC_WRITE, MPI_INFO_NULL, &ncid);
+
+ err = ncmpi_redef(ncid);
+ PNCDF_Error(err, "redef")
+
+ err = ncmpi_def_dim(ncid, "dim2", len2, &dim2id);
+ PNCDF_Error(err, "def_dim")
+
+ dims2id[0] = dim0id;
+ dims2id[1] = dim2id;
+ err = ncmpi_def_var(ncid, "xyz_r", NC_DOUBLE, 2, dims2id, &var2id);
+ PNCDF_Error(err, "def_var")
+
+ err = ncmpi_enddef(ncid);
+ PNCDF_Error(err, "enddef")
+
+ start[0] = 0;
+ start[1] = 0;
+ count[0] = len0;
+ count[1] = len2;
+ k=0;
+ dbl_data = (double*) malloc(len0*len2 * sizeof(double));
+ for (i=0; i<len0; i++)
+ for (j=0; j<len2; j++) {
+ dbl_data[i*len2+j] = (k*k);
+ k++;
+ }
+ if (rank > 0) count[0] = count[1] = 0;
+ err = ncmpi_put_vara_double_all(ncid, var2id, start, count, &dbl_data[0]);
+ PNCDF_Error(err, "put2")
+ free(dbl_data);
+
+ err = ncmpi_close(ncid);
+ PNCDF_Error(err, "close")
+
+ /* check if PnetCDF freed all internal malloc */
+ MPI_Offset malloc_size, sum_size;
+ err = ncmpi_inq_malloc_size(&malloc_size);
+ if (err == NC_NOERR) {
+ MPI_Reduce(&malloc_size, &sum_size, 1, MPI_OFFSET, MPI_SUM, 0, MPI_COMM_WORLD);
+ if (rank == 0 && sum_size > 0)
+ printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n",
+ sum_size);
+ }
+
+fn_exit:
+ MPI_Allreduce(MPI_IN_PLACE, &nerrs, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
+ if (rank == 0) {
+ if (nerrs) printf(FAIL_STR,nerrs);
+ else printf(PASS_STR);
+ }
+
+ MPI_Finalize();
+ return 0;
+}
diff --git a/test/testcases/redef1.sh b/test/testcases/redef1.sh
new file mode 100755
index 0000000..b3b0360
--- /dev/null
+++ b/test/testcases/redef1.sh
@@ -0,0 +1,22 @@
+#!/bin/bash
+# quick test of re-entering define mode: the file created by ncmpigen and the
+# file created by test program should be bit-for-bit identical, else there is
+# an error
+
+if [ $# -ne 2 ] ; then
+ echo "usage: $0 <executable> <reference>"
+ echo "example: $0 redef1 redef-good.ncdump"
+ exit -1
+fi
+
+REFERENCE=redef1-a-${RANDOM}-${RANDOM}-${RANDOM}.nc
+
+# dataset via ncmpigen:
+../../src/utils/ncmpigen/ncmpigen -v 2 -o $REFERENCE $2
+
+# dataset via test
+$1
+
+# now compare
+
+diff $REFERENCE redef1.nc
diff --git a/test/testcases/test_erange.c b/test/testcases/test_erange.c
new file mode 100644
index 0000000..d22199b
--- /dev/null
+++ b/test/testcases/test_erange.c
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2015, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ *
+ * $Id$
+ */
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ *
+ * This program tests NC_ERANGE error code for the following 2 case.
+ * 1. get a value of 255 from a NC_UBYTE variable in a netCDF to a memory
+ * buffer of signed char
+ * 2. put a value of -1 of signed char from a in-memory buffer to a NC_UBYTE
+ * variable in a netCDF file
+ *
+ * The compile and run commands are given below.
+ *
+ * % mpicc -g -o test_erange test_erange.c -lpnetcdf
+ *
+ * % mpiexec -l -n 1 test_erange testfile.nc
+ *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <pnetcdf.h>
+
+#include <testutils.h>
+
+#define ERR if (err!=NC_NOERR) {printf("Error at line %d: %s\n",__LINE__,ncmpi_strerror(err));nerrs++;}
+#define EXPECT_ERR if (err != NC_ERANGE) {printf("Error at line %d: expecting NC_ERANGE, but got %d\n",__LINE__,err);nerrs++;}
+
+int main(int argc, char* argv[])
+{
+ char filename[256];
+ int err, nerrs=0, ncid, uc_vid, sc_vid, dimid, rank;
+ unsigned char uc;
+ signed char sc;
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+
+ if (argc > 2) {
+ if (!rank) printf("Usage: %s [filename]\n",argv[0]);
+ MPI_Finalize();
+ return 0;
+ }
+ strcpy(filename, "testfile.nc");
+ if (argc == 2) strcpy(filename, argv[1]);
+ MPI_Bcast(filename, 256, MPI_CHAR, 0, MPI_COMM_WORLD);
+
+ if (rank == 0) {
+ char cmd_str[256];
+ sprintf(cmd_str, "*** TESTING C %s for checking for NC_ERANGE ", argv[0]);
+ printf("%-66s ------ ", cmd_str); fflush(stdout);
+ }
+
+ err = ncmpi_create(MPI_COMM_WORLD, filename, NC_CLOBBER|NC_64BIT_DATA, MPI_INFO_NULL, &ncid); ERR
+
+ uc = 255; /* a value should cause NC_ERANGE at ncmpi_get_att_schar() */
+ err = ncmpi_put_att_uchar(ncid, NC_GLOBAL, "att1", NC_UBYTE, 1, &uc); ERR
+ err = ncmpi_get_att_schar(ncid, NC_GLOBAL, "att1", &sc); EXPECT_ERR
+
+ sc = -1; /* a value should cause NC_ERANGE */
+ err = ncmpi_put_att_schar(ncid, NC_GLOBAL, "att2", NC_UBYTE, 1, &sc); EXPECT_ERR
+
+ err = ncmpi_def_dim(ncid, "x", 2, &dimid); ERR
+ err = ncmpi_def_var(ncid, "var_ubyte", NC_UBYTE, 1, &dimid, &uc_vid); ERR
+ err = ncmpi_def_var(ncid, "var_byte", NC_BYTE, 1, &dimid, &sc_vid); ERR
+ err = ncmpi_enddef(ncid); ERR
+
+ uc = 255; /* a value should cause NC_ERANGE at ncmpi_get_var_schar() */
+ err = ncmpi_put_var_uchar_all(ncid, uc_vid, &uc); ERR
+ err = ncmpi_get_var_schar_all(ncid, uc_vid, &sc); EXPECT_ERR
+
+ sc = -1; /* a value should cause NC_ERANGE */
+ err = ncmpi_put_var_schar_all(ncid, uc_vid, &sc); EXPECT_ERR
+
+ err = ncmpi_close(ncid); ERR
+
+ /* check if PnetCDF freed all internal malloc */
+ MPI_Offset malloc_size, sum_size;
+ err = ncmpi_inq_malloc_size(&malloc_size);
+ if (err == NC_NOERR) {
+ MPI_Reduce(&malloc_size, &sum_size, 1, MPI_OFFSET, MPI_SUM, 0, MPI_COMM_WORLD);
+ if (rank == 0 && sum_size > 0)
+ printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n",
+ sum_size);
+ }
+
+ MPI_Allreduce(MPI_IN_PLACE, &nerrs, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
+ if (rank == 0) {
+ if (nerrs) printf(FAIL_STR,nerrs);
+ else printf(PASS_STR);
+ }
+
+ MPI_Finalize();
+
+ return 0;
+}
diff --git a/test/testcases/test_vard.c b/test/testcases/test_vard.c
new file mode 100644
index 0000000..9250d6b
--- /dev/null
+++ b/test/testcases/test_vard.c
@@ -0,0 +1,322 @@
+/*
+ * Copyright (C) 2014, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ *
+ * $Id: test_vard.c 2219 2015-12-11 22:30:03Z wkliao $
+ */
+
+/*
+ * This program tests the vard API.
+ * The write buffer is a 2D array of size NY x NX
+ * The MPI data type for the buffer is defined by swapping the 1st and 2nd
+ * rows of the array using a butype constructed by MPI_Type_create_hindex().
+ * It also writes a fixed-size variable using a buftype constructed by
+ * MPI_Type_create_subarray(). Both record and foxed-size variables are read
+ * back using various filetypes and buftypes and check the contents.
+ *
+ * The expected reults from the output file contents are:
+ * (when running on 1 MPI process)
+ *
+ * % ncmpidump testfile.nc
+ * netcdf testfile {
+ * // file format: CDF-1
+ * dimensions:
+ * REC_DIM = UNLIMITED ; // (2 currently)
+ * X = 5 ;
+ * FIX_DIM = 2 ;
+ * variables:
+ * int rec_var(REC_DIM, X) ;
+ * int dummy_rec(REC_DIM, X) ;
+ * int fix_var(FIX_DIM, X) ;
+ * data:
+ *
+ * rec_var =
+ * 10, 11, 12, 13, 14,
+ * 0, 1, 2, 3, 4 ;
+ *
+ * dummy_rec =
+ * 0, 0, 0, 0, 0,
+ * 0, 0, 0, 0, 0 ;
+ *
+ * fix_var =
+ * 10, 11, 12, 13, 14,
+ * 0, 1, 2, 3, 4 ;
+ * }
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <mpi.h>
+#include <pnetcdf.h>
+
+#include <testutils.h>
+
+#define NY 2
+#define NX 5
+#define ERR if (err!=NC_NOERR) {printf("Error at line %d: %s\n", __LINE__,ncmpi_strerror(err)); nerrs++;}
+
+#define CHECK_VALUE_PERMUTED { \
+ for (j=0; j<count[0]; j++) { \
+ int val = (j == 0) ? 1 : 0; \
+ val = rank * 100 + val * 10; \
+ for (i=0; i<count[1]; i++) \
+ if (buf[j][i] != val+i) { \
+ printf("line %d: expecting buf[%d][%d]=%d but got %d\n",__LINE__,j,i,val+i,buf[j][i]); \
+ nerrs++; \
+ } \
+ } \
+} \
+
+#define CHECK_VALUE { \
+ for (j=0; j<count[0]; j++) { \
+ for (i=0; i<count[1]; i++) \
+ if (buf[j][i] != rank*100+j*10+i) { \
+ printf("line %d: expecting buf[%d][%d]=%d but got %d\n",__LINE__,j,i,rank*100+j*10+i,buf[j][i]); \
+ nerrs++; \
+ } \
+ } \
+}
+
+static
+int get_var_and_verify(int ncid,
+ int varid,
+ MPI_Offset *start,
+ MPI_Offset *count,
+ int **buf,
+ MPI_Datatype buftype,
+ MPI_Datatype ghost_buftype,
+ MPI_Datatype filetype)
+{
+ int i, j, rank, err, *ncbuf, nerrs=0;
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+
+ ncbuf = (int *) malloc((count[0]+4)*(count[1]+4)*sizeof(int));
+
+ /* clear the contents of the read buffer */
+ for (j=0; j<count[0]; j++) for (i=0; i<count[1]; i++) buf[j][i] = -1;
+
+ /* read back using regular vara API */
+ err = ncmpi_get_vara_int_all(ncid, varid, start, count, buf[0]); ERR
+
+ /* check if the contents of buf are expected */
+ CHECK_VALUE_PERMUTED
+
+ /* clear the contents of the read buffer */
+ for (j=0; j<count[0]; j++) for (i=0; i<count[1]; i++) buf[j][i] = -1;
+
+ /* read back using flexible vara API */
+ err = ncmpi_get_vara_all(ncid, varid, start, count, buf[1], 1, buftype); ERR
+
+ /* check if the contents of buf are expected */
+ CHECK_VALUE
+
+ /* clear the contents of the read buffer */
+ for (j=0; j<count[0]; j++) for (i=0; i<count[1]; i++) buf[j][i] = -1;
+
+ /* read back using vard API and permuted buftype */
+ err = ncmpi_get_vard_all(ncid, varid, filetype, buf[1], 1, buftype); ERR
+
+ /* check if the contents of buf are expected */
+ CHECK_VALUE
+
+ /* clear the contents of the read buffer */
+ for (j=0; j<count[0]; j++) for (i=0; i<count[1]; i++) buf[j][i] = -1;
+
+ /* read back using vard API and no buftype */
+ err = ncmpi_get_vard_all(ncid, varid, filetype, buf[0], 0, MPI_DATATYPE_NULL); ERR
+
+ /* check if the contents of buf are expected */
+ CHECK_VALUE_PERMUTED
+
+ /* clear the contents of the read buffer */
+ for (i=0; i<(count[0]+4)*(count[1]+4); i++) ncbuf[i] = -1;
+
+ /* read back using ghost buftype */
+ err = ncmpi_get_vard_all(ncid, varid, filetype, ncbuf, 1, ghost_buftype); ERR
+
+ for (j=0; j<count[0]; j++) {
+ for (i=0; i<count[1]; i++)
+ if (buf[j][i] != ncbuf[(j+2)*(count[1]+4)+(i+2)]) {
+ printf("Error at line %d: expecting ncbuf[%d][%d]=%d but got %d\n",
+ __LINE__,j,i,buf[j][i],ncbuf[(j+2)*(count[1]+4)+(i+2)]);
+ nerrs++;
+ }
+ }
+ free(ncbuf);
+ return nerrs;
+}
+
+/*----< main() >------------------------------------------------------------*/
+int main(int argc, char **argv) {
+
+ char filename[256];
+ int i, j, err, ncid, varid0, varid1, varid2, dimids[2], nerrs=0;
+ int rank, nprocs, debug=0, blocklengths[2], **buf, *bufptr;
+ int array_of_sizes[2], array_of_subsizes[2], array_of_starts[2];
+ MPI_Offset start[2], count[2];
+ MPI_Aint a0, a1, disps[2];
+ MPI_Datatype buftype, ghost_buftype, rec_filetype, fix_filetype;
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+
+ if (argc > 2) {
+ if (!rank) printf("Usage: %s [filename]\n",argv[0]);
+ MPI_Finalize();
+ return 0;
+ }
+ strcpy(filename, "testfile.nc");
+ if (argc == 2) strcpy(filename, argv[1]);
+ MPI_Bcast(filename, 256, MPI_CHAR, 0, MPI_COMM_WORLD);
+
+ if (rank == 0) {
+ char cmd_str[256];
+ sprintf(cmd_str, "*** TESTING C %s for flexible put and get ", argv[0]);
+ printf("%-66s ------ ", cmd_str); fflush(stdout);
+ }
+
+ buf = (int**)malloc(NY * sizeof(int*));
+ buf[0] = (int*)malloc(NY * NX * sizeof(int));
+ for (i=1; i<NY; i++) buf[i] = buf[i-1] + NX;
+
+ /* construct various MPI derived data types */
+
+ /* construct an MPI derived data type for swapping 1st row with 2nd row */
+ blocklengths[0] = blocklengths[1] = NX;
+ MPI_Get_address(buf[1], &a0);
+ MPI_Get_address(buf[0], &a1);
+ disps[0] = 0;
+ disps[1] = a1 - a0;
+ bufptr = buf[1];
+ err = MPI_Type_create_hindexed(2, blocklengths, disps, MPI_INT, &buftype);
+ if (err != MPI_SUCCESS) printf("MPI error MPI_Type_create_hindexed\n");
+ MPI_Type_commit(&buftype);
+
+ start[0] = 0; start[1] = NX*rank;
+ count[0] = 2; count[1] = NX;
+ if (debug) printf("put start=%lld %lld count=%lld %lld\n",start[0],start[1],count[0],count[1]);
+
+ /* create a file type for the fixed-size variable */
+ array_of_sizes[0] = 2;
+ array_of_sizes[1] = NX*nprocs;
+ array_of_subsizes[0] = count[0];
+ array_of_subsizes[1] = count[1];
+ array_of_starts[0] = start[0];
+ array_of_starts[1] = start[1];
+ MPI_Type_create_subarray(2, array_of_sizes, array_of_subsizes,
+ array_of_starts, MPI_ORDER_C,
+ MPI_INT, &fix_filetype);
+ MPI_Type_commit(&fix_filetype);
+
+ /* create a buftype with ghost cells on each side */
+ array_of_sizes[0] = count[0]+4;
+ array_of_sizes[1] = count[1]+4;
+ array_of_subsizes[0] = count[0];
+ array_of_subsizes[1] = count[1];
+ array_of_starts[0] = 2;
+ array_of_starts[1] = 2;
+ MPI_Type_create_subarray(2, array_of_sizes, array_of_subsizes,
+ array_of_starts, MPI_ORDER_C,
+ MPI_INT, &ghost_buftype);
+ MPI_Type_commit(&ghost_buftype);
+
+ /* create a new file for write */
+ err = ncmpi_create(MPI_COMM_WORLD, filename, NC_CLOBBER, MPI_INFO_NULL,
+ &ncid); ERR
+
+ /* define a 2D array */
+ err = ncmpi_def_dim(ncid, "REC_DIM", NC_UNLIMITED, &dimids[0]); ERR
+ err = ncmpi_def_dim(ncid, "X", NX*nprocs, &dimids[1]); ERR
+ err = ncmpi_def_var(ncid, "rec_var", NC_INT, 2, dimids, &varid0); ERR
+ err = ncmpi_def_var(ncid, "dummy_rec", NC_INT, 2, dimids, &varid2); ERR
+ err = ncmpi_def_dim(ncid, "FIX_DIM", 2, &dimids[0]); ERR
+ err = ncmpi_def_var(ncid, "fix_var", NC_INT, 2, dimids, &varid1); ERR
+ err = ncmpi_enddef(ncid); ERR
+
+ /* create a file type for the record variable */
+ int *array_of_blocklengths=(int*) malloc(count[0]*sizeof(int));
+ MPI_Aint *array_of_displacements=(MPI_Aint*) malloc(count[0]*sizeof(MPI_Aint));
+ MPI_Offset recsize;
+ err = ncmpi_inq_recsize(ncid, &recsize);
+ for (i=0; i<count[0]; i++) {
+ array_of_blocklengths[i] = count[1];
+ array_of_displacements[i] = start[1]*sizeof(int) + recsize * i;
+ }
+ MPI_Type_create_hindexed(2, array_of_blocklengths, array_of_displacements,
+ MPI_INT, &rec_filetype);
+ MPI_Type_commit(&rec_filetype);
+ free(array_of_blocklengths);
+ free(array_of_displacements);
+
+ /* initialize the contents of the array */
+ for (j=0; j<NY; j++) for (i=0; i<NX; i++) buf[j][i] = rank*100 + j*10 + i;
+
+ /* write the record variable */
+ err = ncmpi_put_vard_all(ncid, varid0, rec_filetype, bufptr, 1, buftype); ERR
+
+ /* check if the contents of buf are altered */
+ CHECK_VALUE
+
+ /* check if root process can write to file header in data mode */
+ err = ncmpi_rename_var(ncid, varid0, "rec_VAR"); ERR
+
+ /* write the fixed-size variable */
+ err = ncmpi_put_vard_all(ncid, varid1, fix_filetype, bufptr, 1, buftype); ERR
+
+ /* check if the contents of buf are altered */
+ CHECK_VALUE
+
+ /* check if root process can write to file header in data mode */
+ err = ncmpi_rename_var(ncid, varid0, "rec_var"); ERR
+
+ /* test the same routines in independent data mode */
+ err = ncmpi_begin_indep_data(ncid); ERR
+ err = ncmpi_put_vard(ncid, varid0, rec_filetype, bufptr, 1, buftype); ERR
+ CHECK_VALUE
+ err = ncmpi_rename_var(ncid, varid0, "rec_VAR"); ERR
+ err = ncmpi_put_vard(ncid, varid1, fix_filetype, bufptr, 1, buftype); ERR
+ CHECK_VALUE
+ err = ncmpi_rename_var(ncid, varid0, "rec_var"); ERR
+ err = ncmpi_end_indep_data(ncid); ERR
+
+ err = ncmpi_close(ncid); ERR
+
+ /* open the same file and read back for validate */
+ err = ncmpi_open(MPI_COMM_WORLD, filename, NC_NOWRITE, MPI_INFO_NULL,
+ &ncid); ERR
+
+ err = ncmpi_inq_varid(ncid, "rec_var", &varid0); ERR
+ err = ncmpi_inq_varid(ncid, "fix_var", &varid1); ERR
+
+ nerrs += get_var_and_verify(ncid, varid0, start, count, buf, buftype, ghost_buftype, rec_filetype);
+ nerrs += get_var_and_verify(ncid, varid1, start, count, buf, buftype, ghost_buftype, fix_filetype);
+
+ err = ncmpi_close(ncid); ERR
+
+ MPI_Type_free(&rec_filetype);
+ MPI_Type_free(&fix_filetype);
+ MPI_Type_free(&buftype);
+ MPI_Type_free(&ghost_buftype);
+ free(buf[0]); free(buf);
+
+ /* check if PnetCDF freed all internal malloc */
+ MPI_Offset malloc_size, sum_size;
+ err = ncmpi_inq_malloc_size(&malloc_size);
+ if (err == NC_NOERR) {
+ MPI_Reduce(&malloc_size, &sum_size, 1, MPI_OFFSET, MPI_SUM, 0, MPI_COMM_WORLD);
+ if (rank == 0 && sum_size > 0)
+ printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n",
+ sum_size);
+ }
+
+ MPI_Allreduce(MPI_IN_PLACE, &nerrs, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
+ if (rank == 0) {
+ if (nerrs) printf(FAIL_STR,nerrs);
+ else printf(PASS_STR);
+ }
+
+ MPI_Finalize();
+ return 0;
+}
diff --git a/test/testcases/test_vardf.F b/test/testcases/test_vardf.F
new file mode 100644
index 0000000..a25cecf
--- /dev/null
+++ b/test/testcases/test_vardf.F
@@ -0,0 +1,392 @@
+!
+! Copyright (C) 2014, Northwestern University and Argonne National Laboratory
+! See COPYRIGHT notice in top-level directory.
+!
+! $Id: test_vardf.F 2236 2015-12-18 03:49:41Z wkliao $
+
+!
+! This program tests the vard API.
+! The write buffer is a 2D array of size NX x NY
+! The MPI data type for the buffer is defined by swapping the 1st and 2nd
+! rows of the array using a butype constructed by MPI_Type_create_hindex().
+! It also writes a fixed-size variable using a buftype constructed by
+! MPI_Type_create_subarray(). Both record and foxed-size variables are read
+! back using various filetypes and buftypes and check the contents.
+!
+! The expected reults from the output file contents are:
+! (when running on 1 MPI process)
+!
+! % ncmpidump testfile.nc
+! netcdf testfile {
+! // file format: CDF-1
+! dimensions:
+! REC_DIM = UNLIMITED ; // (2 currently)
+! X = 5 ;
+! FIX_DIM = 2 ;
+! variables:
+! int rec_var(REC_DIM, X) ;
+! int dummy_rec(REC_DIM, X) ;
+! int fix_var(FIX_DIM, X) ;
+! data:
+!
+! rec_var =
+! 10, 11, 12, 13, 14,
+! 0, 1, 2, 3, 4 ;
+!
+! dummy_rec =
+! 0, 0, 0, 0, 0,
+! 0, 0, 0, 0, 0 ;
+!
+! fix_var =
+! 10, 11, 12, 13, 14,
+! 0, 1, 2, 3, 4 ;
+! }
+!
+ INTEGER FUNCTION XTRIM(STRING)
+ CHARACTER*(*) STRING
+ INTEGER I, N
+ N = LEN(STRING)
+ DO I = N, 1, -1
+ IF (STRING(I:I) .NE. ' ') GOTO 10
+ ENDDO
+ 10 XTRIM = I
+ END ! FUNCTION XTRIM
+
+ subroutine check(err, message)
+ implicit none
+ include "mpif.h"
+ include "pnetcdf.inc"
+ integer err, XTRIM
+ character*(*) message
+ character*128 msg
+
+ ! It is a good idea to check returned value for possible error
+ if (err .NE. NF_NOERR) then
+ write(6,*) message(1:XTRIM(message)), nfmpi_strerror(err)
+ msg = '*** TESTING F77 test_vardf.f for vard API '
+ call pass_fail(1, msg)
+ call MPI_Abort(MPI_COMM_WORLD, -1, err)
+ end if
+ end ! subroutine check
+
+ subroutine check_value(rank, nx, ny, buf, nerrs)
+ implicit none
+ include "mpif.h"
+ integer NX, NY
+ integer rank, buf(nx, ny), nerrs
+ integer i, j
+ 543 format(A,I2,A,I2,A,I3,A,I3)
+ do j=1, ny
+ do i=1, nx
+ if (buf(i,j) .NE. rank*100+j*10+i) then
+ print 543,'expecting buf(',i,',',j,')=',
+ + rank*100+j*10+i,' but got ',buf(i,j)
+ nerrs = nerrs + 1
+ endif
+ enddo
+ enddo
+ end ! subroutine check_value
+
+ subroutine check_value_permuted(rank, nx, ny, buf, nerrs)
+ implicit none
+ include "mpif.h"
+ integer NX, NY
+ integer rank, buf(nx, ny), nerrs, val
+ integer i, j
+ 543 format(A,I2,A,I2,A,I3,A,I3)
+ do j=1, ny
+ val = 1
+ if (j .EQ. 1) val = 2
+ val = rank * 100 + val * 10
+ do i=1, nx
+ if (buf(i,j) .NE. val+i) then
+ print 543,'expecting buf(',i,',',j,')=',
+ + val+i,' but got ',buf(i,j)
+ nerrs = nerrs + 1
+ endif
+ enddo
+ enddo
+ end ! subroutine check_value_permuted
+
+ subroutine clear_buf(nx, ny, buf)
+ implicit none
+ include "mpif.h"
+ integer NX, NY
+ integer buf(nx, ny)
+ integer i, j
+ do j=1, NY
+ do i=1, NX
+ buf(i,j) = -1
+ enddo
+ enddo
+ end ! subroutine clear_buf
+
+ subroutine get_var_and_verify(ncid,varid,NX,NY,start,count,buf,
+ + buftype, ghost_buftype, filetype, nerrs)
+ implicit none
+ include "mpif.h"
+ include "pnetcdf.inc"
+ integer NX, NY
+ integer*8 start(2), count(2), one, zero
+ integer i, j, rank, err, ncid, varid, nerrs, buf(NX, NY)
+ integer buftype, ghost_buftype, filetype
+ integer ncbuf(NX+4, NY+4)
+
+ one = 1
+ zero = 0
+ call MPI_Comm_rank(MPI_COMM_WORLD, rank, err)
+ ! clear the contents of the read buffer
+ call clear_buf(NX, NY, buf)
+
+ ! read back using regular vara API
+ err = nfmpi_get_vara_int_all(ncid, varid, start, count, buf)
+ call check(err, 'In nfmpi_get_vara_int_all: ')
+
+ ! check if the contents of buf are expected
+ call check_value_permuted(rank, NX, NY, buf, nerrs)
+ call clear_buf(NX, NY, buf)
+
+ ! read back using flexible vara API
+ err = nfmpi_get_vara_all(ncid, varid, start, count, buf(1,2),
+ + one, buftype)
+ call check(err, 'In nfmpi_get_vara_all: ')
+
+ ! check if the contents of buf are expected
+ call check_value(rank, NX, NY, buf, nerrs)
+ call clear_buf(NX, NY, buf)
+
+ ! read back using vard API and permuted buftype
+ err = nfmpi_get_vard_all(ncid, varid, filetype, buf(1,2),
+ + one, buftype)
+ call check(err, 'In nfmpi_get_vard_all: ')
+
+ ! check if the contents of buf are expected
+ call check_value(rank, NX, NY, buf, nerrs)
+ call clear_buf(NX, NY, buf)
+
+ ! read back using vard API and no buftype
+ err = nfmpi_get_vard_all(ncid, varid, filetype, buf,
+ + zero, MPI_DATATYPE_NULL)
+ call check(err, 'In nfmpi_get_vard_all: ')
+
+ ! check if the contents of buf are expected
+ call check_value_permuted(rank, NX, NY, buf, nerrs)
+
+ ! read back using ghost buftype
+ err = nfmpi_get_vard_all(ncid, varid, filetype, ncbuf,
+ + one, ghost_buftype)
+ call check(err, 'In nfmpi_get_vard_all: ')
+
+ 543 format(A,I2,A,I2,A,I3,A,I3)
+ do j=1, NY
+ do i=1, NX
+ if (buf(i,j) .NE. ncbuf(i+2, j+2)) then
+ print 543,'expecting buf(',i,',',j,')=',
+ + buf(i,j),' but got ',ncbuf(i+2,j+2)
+ nerrs = nerrs + 1
+ endif
+ enddo
+ enddo
+ end ! subroutine get_var_and_verify
+
+ program main
+ implicit none
+ include "mpif.h"
+ include "pnetcdf.inc"
+ character*256 filename, cmd, msg
+ integer err, ierr, nprocs, rank, i, j, get_args
+ integer cmode, ncid, varid0, varid1, varid2, dimid(2), nerrs
+ integer NX, NY, XTRIM
+ PARAMETER(NX=5, NY=2)
+ integer buf(NX, NY)
+ integer buftype, ghost_buftype, rec_filetype, fix_filetype
+ integer array_of_sizes(2), array_of_subsizes(2)
+ integer array_of_starts(2), blocklengths(2)
+ integer*8 start(2), count(2), len, one, two
+ integer*8 malloc_size, sum_size, recsize
+#ifdef SIZEOF_MPI_AINT_IS_4
+ integer a0, a1, disps(2)
+#else
+ integer*8 a0, a1, disps(2)
+#endif
+
+ call MPI_Init(ierr)
+ call MPI_Comm_rank(MPI_COMM_WORLD, rank, ierr)
+ call MPI_Comm_size(MPI_COMM_WORLD, nprocs, ierr)
+
+ one = 1
+ two = 2
+ ! take filename from command-line argument if there is any
+ if (rank .EQ. 0) then
+ filename = "testfile.nc"
+ err = get_args(cmd, filename)
+ endif
+ call MPI_Bcast(err, 1, MPI_INTEGER, 0, MPI_COMM_WORLD, ierr)
+ if (err .EQ. 0) goto 999
+
+ call MPI_Bcast(filename, 256, MPI_CHARACTER, 0,
+ + MPI_COMM_WORLD, ierr)
+
+ nerrs = 0
+
+ start(1) = NX * rank
+ start(2) = 0
+ count(1) = NX
+ count(2) = 2
+
+ ! construct various MPI derived data types
+ blocklengths(1) = NX
+ blocklengths(2) = NX
+ call MPI_Get_address(buf(1,2), a0, ierr)
+ call MPI_Get_address(buf(1,1), a1, ierr)
+ disps(1) = 0
+ disps(2) = a1 - a0
+ call MPI_Type_create_hindexed(2, blocklengths, disps,
+ + MPI_INTEGER, buftype, ierr)
+ call MPI_Type_commit(buftype, ierr)
+
+ ! create a file type for the fixed-size variable
+ array_of_sizes(1) = NX*nprocs
+ array_of_sizes(2) = 2
+ array_of_subsizes(1) = INT(count(1))
+ array_of_subsizes(2) = INT(count(2))
+ array_of_starts(1) = INT(start(1))
+ array_of_starts(2) = INT(start(2))
+ call MPI_Type_create_subarray(2, array_of_sizes,
+ + array_of_subsizes, array_of_starts, MPI_ORDER_FORTRAN,
+ + MPI_INTEGER, fix_filetype, ierr)
+ call MPI_Type_commit(fix_filetype, ierr)
+
+ ! create a buftype with ghost cells on each side */
+ array_of_sizes(1) = INT(count(1))+4
+ array_of_sizes(2) = INT(count(2))+4
+ array_of_subsizes(1) = INT(count(1))
+ array_of_subsizes(2) = INT(count(2))
+ array_of_starts(1) = 2
+ array_of_starts(2) = 2
+ call MPI_Type_create_subarray(2, array_of_sizes,
+ + array_of_subsizes, array_of_starts, MPI_ORDER_FORTRAN,
+ + MPI_INTEGER, ghost_buftype, ierr)
+ call MPI_Type_commit(ghost_buftype, ierr)
+
+ ! initialized buffer contents
+ do j=1, INT(count(2))
+ do i=1, INT(count(1))
+ buf(i, j) = rank*100 + j*10 + i
+ enddo
+ enddo
+
+ ! create file, truncate it if exists
+ cmode = NF_CLOBBER
+ err = nfmpi_create(MPI_COMM_WORLD, filename, cmode,
+ + MPI_INFO_NULL, ncid)
+ call check(err, 'In nfmpi_create: ')
+
+ ! define 2 dimensions
+ err = nfmpi_def_dim(ncid, "REC_DIM", NFMPI_UNLIMITED,dimid(2))
+ call check(err, 'In nfmpi_def_dim REC_DIM: ')
+ len = NX * nprocs
+ err = nfmpi_def_dim(ncid, "X", len, dimid(1))
+ call check(err, 'In nfmpi_def_dim X: ')
+
+ ! define 2D record variables of integer type
+ err = nfmpi_def_var(ncid, "rec_var", NF_INT, 2, dimid, varid0)
+ call check(err, 'In nfmpi_def_var: rec_var ')
+ err = nfmpi_def_var(ncid, "dummy_rec", NF_INT, 2,dimid,varid2)
+ call check(err, 'In nfmpi_def_var: dummy_rec ')
+
+ ! define 2D fixed-size variable of integer type
+ err = nfmpi_def_dim(ncid, "FIX_DIM", two, dimid(2))
+ call check(err, 'In nfmpi_def_dim RECV_DIM: ')
+ err = nfmpi_def_var(ncid, "fix_var", NF_INT, 2, dimid, varid1)
+ call check(err, 'In nfmpi_def_var: fix_var ')
+
+ ! do not forget to exit define mode
+ err = nfmpi_enddef(ncid)
+ call check(err, 'In nfmpi_enddef: ')
+
+ ! now we are in data mode
+
+ ! create a file type for the record variable */
+ err = nfmpi_inq_recsize(ncid, recsize)
+ call check(err, 'In nfmpi_inq_recsize: ')
+ blocklengths(1) = INT(count(1))
+ blocklengths(2) = INT(count(1))
+ disps(1) = start(1)*4
+ disps(2) = recsize + start(1)*4
+ call MPI_Type_create_hindexed(2, blocklengths, disps,
+ + MPI_INTEGER, rec_filetype, ierr)
+ call MPI_Type_commit(rec_filetype, ierr)
+
+ ! write the record variable */
+ err = nfmpi_put_vard_all(ncid, varid0, rec_filetype, buf(1,2),
+ + one, buftype)
+ call check(err, 'In nfmpi_put_vard_all: ')
+ ! check if the contents of buf are altered
+ call check_value(rank, NX, NY, buf, nerrs)
+
+ ! check if root process can write to file header in data mode
+ err = nfmpi_rename_var(ncid, varid0, 'rec_VAR')
+ call check(err, 'In nfmpi_rename_var: ')
+
+ ! write the fixed-size variable
+ err = nfmpi_put_vard_all(ncid, varid1, fix_filetype, buf(1,2),
+ + one, buftype)
+ call check(err, 'In nfmpi_put_vard_all: ')
+ ! check if the contents of buf are altered
+ call check_value(rank, NX, NY, buf, nerrs)
+
+ ! check if root process can write to file header in data mode
+ err = nfmpi_rename_var(ncid, varid0, 'rec_var')
+ call check(err, 'In nfmpi_rename_var: ')
+
+ ! close the file
+ err = nfmpi_close(ncid)
+ call check(err, 'In nfmpi_close: ')
+
+ ! open the same file and read back for validate */
+ err = nfmpi_open(MPI_COMM_WORLD, filename, NF_NOWRITE,
+ + MPI_INFO_NULL, ncid)
+ call check(err, 'In nfmpi_open: ')
+
+ err = nfmpi_inq_varid(ncid, "rec_var", varid0)
+ call check(err, 'In nfmpi_inq_varid rec_var: ')
+ err = nfmpi_inq_varid(ncid, "fix_var", varid1)
+ call check(err, 'In nfmpi_inq_varid fix_var: ')
+
+ ! PnetCDF start() argument starts with 1
+ start(1) = start(1) + 1
+ start(2) = start(2) + 1
+ call get_var_and_verify(ncid, varid0, NX,NY,start, count, buf,
+ + buftype, ghost_buftype, rec_filetype, nerrs)
+
+ call get_var_and_verify(ncid, varid1, NX,NY,start, count, buf,
+ + buftype, ghost_buftype, fix_filetype, nerrs)
+
+ ! close the file
+ err = nfmpi_close(ncid)
+ call check(err, 'In nfmpi_close: ')
+
+ call MPI_Type_free(rec_filetype, ierr)
+ call MPI_Type_free(fix_filetype, ierr)
+ call MPI_Type_free(buftype, ierr)
+ call MPI_Type_free(ghost_buftype, ierr)
+
+ ! check if there is any PnetCDF internal malloc residue
+ 998 format(A,I13,A)
+ err = nfmpi_inq_malloc_size(malloc_size)
+ if (err .EQ. NF_NOERR) then
+ call MPI_Reduce(malloc_size, sum_size, 1, MPI_OFFSET,
+ + MPI_SUM, 0, MPI_COMM_WORLD, ierr)
+ if (rank .EQ. 0 .AND. sum_size .GT. 0)
+ + print 998,
+ + 'heap memory allocated by PnetCDF internally has ',
+ + sum_size/1048576, ' MiB yet to be freed'
+ endif
+
+ msg = '*** TESTING F77 '//cmd(1:XTRIM(cmd))//' for vard API '
+ if (rank .eq. 0) call pass_fail(nerrs, msg)
+
+ 999 call MPI_Finalize(ierr)
+ end ! program main
+
diff --git a/test/testcases/test_vardf90.f90 b/test/testcases/test_vardf90.f90
new file mode 100644
index 0000000..2fe2ffc
--- /dev/null
+++ b/test/testcases/test_vardf90.f90
@@ -0,0 +1,372 @@
+!
+! Copyright (C) 2014, Northwestern University and Argonne National Laboratory
+! See COPYRIGHT notice in top-level directory.
+!
+! $Id: test_vardf90.f90 2205 2015-11-28 20:41:50Z wkliao $
+
+!
+! This program tests the vard API.
+! The write buffer is a 2D array of size NX x NY
+! The MPI data type for the buffer is defined by swapping the 1st and 2nd
+! rows of the array using a butype constructed by MPI_Type_create_hindex().
+! It also writes a fixed-size variable using a buftype constructed by
+! MPI_Type_create_subarray(). Both record and foxed-size variables are read
+! back using various filetypes and buftypes and check the contents.
+!
+! The expected reults from the output file contents are:
+! (when running on 1 MPI process)
+!
+! % ncmpidump testfile.nc
+! netcdf testfile {
+! // file format: CDF-1
+! dimensions:
+! REC_DIM = UNLIMITED ; // (2 currently)
+! X = 5 ;
+! FIX_DIM = 2 ;
+! variables:
+! int rec_var(REC_DIM, X) ;
+! int dummy_rec(REC_DIM, X) ;
+! int fix_var(FIX_DIM, X) ;
+! data:
+!
+! rec_var =
+! 10, 11, 12, 13, 14,
+! 0, 1, 2, 3, 4 ;
+!
+! dummy_rec =
+! 0, 0, 0, 0, 0,
+! 0, 0, 0, 0, 0 ;
+!
+! fix_var =
+! 10, 11, 12, 13, 14,
+! 0, 1, 2, 3, 4 ;
+! }
+!
+ subroutine check(err, message)
+ use mpi
+ use pnetcdf
+ implicit none
+ integer err
+ character(len=*) message
+ character(len=128) msg
+
+ ! It is a good idea to check returned value for possible error
+ if (err .NE. NF90_NOERR) then
+ write(6,*) trim(message), trim(nf90mpi_strerror(err))
+ msg = '*** TESTING F90 test_vardf90.f90 for vard API '
+ call pass_fail(1, msg)
+ call MPI_Abort(MPI_COMM_WORLD, -1, err)
+ end if
+ end subroutine check
+
+ subroutine check_value(rank, nx, ny, buf, nerrs)
+ use mpi
+ implicit none
+ integer NX, NY
+ integer rank, buf(nx, ny), nerrs
+ integer i, j
+ 543 format(A,I2,A,I2,A,I3,A,I3)
+ do j=1, ny
+ do i=1, nx
+ if (buf(i,j) .NE. rank*100+j*10+i) then
+ print 543,'expecting buf(',i,',',j,')=', &
+ rank*100+j*10+i,' but got ',buf(i,j)
+ nerrs = nerrs + 1
+ endif
+ enddo
+ enddo
+ end subroutine check_value
+
+ subroutine check_value_permuted(rank, nx, ny, buf, nerrs)
+ use mpi
+ implicit none
+ integer NX, NY
+ integer rank, buf(nx, ny), nerrs, val
+ integer i, j
+ 543 format(A,I2,A,I2,A,I3,A,I3)
+ do j=1, ny
+ val = 1
+ if (j .EQ. 1) val = 2
+ val = rank * 100 + val * 10
+ do i=1, nx
+ if (buf(i,j) .NE. val+i) then
+ print 543,'expecting buf(',i,',',j,')=', &
+ val+i,' but got ',buf(i,j)
+ nerrs = nerrs + 1
+ endif
+ enddo
+ enddo
+ end subroutine check_value_permuted
+
+ subroutine clear_buf(nx, ny, buf)
+ use mpi
+ implicit none
+ integer NX, NY
+ integer buf(nx, ny)
+ integer i, j
+ do j=1, NY
+ do i=1, NX
+ buf(i,j) = -1
+ enddo
+ enddo
+ end subroutine clear_buf
+
+ subroutine get_var_and_verify(ncid,varid,NX,NY,start,count,buf, &
+ buftype, ghost_buftype, filetype, nerrs)
+ use mpi
+ use pnetcdf
+ implicit none
+ integer NX, NY
+ integer(kind=MPI_OFFSET_KIND) start(2), count(2)
+ integer i, j, rank, err, ncid, varid, nerrs, buf(NX, NY)
+ integer buftype, ghost_buftype, filetype
+ integer ncbuf(NX+4, NY+4)
+
+ call MPI_Comm_rank(MPI_COMM_WORLD, rank, err)
+ ! clear the contents of the read buffer
+ call clear_buf(NX, NY, buf)
+
+ ! read back using regular vara API
+ err = nf90mpi_get_var_all(ncid, varid, buf, start, count)
+ call check(err, 'In nf90mpi_get_var_all: ')
+
+ ! check if the contents of buf are expected
+ call check_value_permuted(rank, NX, NY, buf, nerrs)
+ call clear_buf(NX, NY, buf)
+
+ ! read back using flexible vara API
+ err = nf90mpi_get_var_all(ncid, varid, buf(:,2), start, count, &
+ BUFCOUNT=1_MPI_OFFSET_KIND, BUFTYPE=buftype)
+ call check(err, 'In nf90mpi_get_var_all: ')
+
+ ! check if the contents of buf are expected
+ call check_value(rank, NX, NY, buf, nerrs)
+ call clear_buf(NX, NY, buf)
+
+ ! read back using vard API and permuted buftype
+ err = nf90mpi_get_vard_all(ncid, varid, filetype, buf(:,2), &
+ 1_MPI_OFFSET_KIND, buftype)
+ call check(err, 'In nf90mpi_get_vard_all: ')
+
+ ! check if the contents of buf are expected
+ call check_value(rank, NX, NY, buf, nerrs)
+ call clear_buf(NX, NY, buf)
+
+ ! read back using vard API and no buftype
+ err = nf90mpi_get_vard_all(ncid, varid, filetype, buf, 0_MPI_OFFSET_KIND, &
+ MPI_DATATYPE_NULL)
+ call check(err, 'In nf90mpi_get_vard_all: ')
+
+ ! check if the contents of buf are expected
+ call check_value_permuted(rank, NX, NY, buf, nerrs)
+
+ ! read back using ghost buftype
+ err = nf90mpi_get_vard_all(ncid, varid, filetype, ncbuf, 1_MPI_OFFSET_KIND,&
+ ghost_buftype)
+ call check(err, 'In nf90mpi_get_vard_all: ')
+
+ 543 format(A,I2,A,I2,A,I3,A,I3)
+ do j=1, NY
+ do i=1, NX
+ if (buf(i,j) .NE. ncbuf(i+2, j+2)) then
+ print 543,'expecting buf(',i,',',j,')=', &
+ buf(i,j),' but got ',ncbuf(i+2,j+2)
+ nerrs = nerrs + 1
+ endif
+ enddo
+ enddo
+ end subroutine get_var_and_verify
+
+ program main
+ use mpi
+ use pnetcdf
+ implicit none
+
+ character(LEN=256) filename, cmd, msg
+ integer err, ierr, nprocs, rank, i, j, get_args
+ integer cmode, ncid, varid0, varid1, varid2, dimid(2), nerrs
+ integer NX, NY
+ PARAMETER(NX=5, NY=2)
+ integer buf(NX, NY)
+ integer buftype, ghost_buftype, rec_filetype, fix_filetype
+ integer array_of_sizes(2), array_of_subsizes(2)
+ integer array_of_starts(2), blocklengths(2)
+ integer(kind=MPI_OFFSET_KIND) start(2), count(2)
+ integer(kind=MPI_OFFSET_KIND) len, malloc_size, sum_size, recsize
+ integer(kind=MPI_ADDRESS_KIND) a0, a1, disps(2)
+
+ call MPI_Init(ierr)
+ call MPI_Comm_rank(MPI_COMM_WORLD, rank, ierr)
+ call MPI_Comm_size(MPI_COMM_WORLD, nprocs, ierr)
+
+ ! take filename from command-line argument if there is any
+ if (rank .EQ. 0) then
+ filename = "testfile.nc"
+ err = get_args(cmd, filename)
+ endif
+ call MPI_Bcast(err, 1, MPI_INTEGER, 0, MPI_COMM_WORLD, ierr)
+ if (err .EQ. 0) goto 999
+
+ call MPI_Bcast(filename, 256, MPI_CHARACTER, 0, MPI_COMM_WORLD, ierr)
+
+ nerrs = 0
+
+ start(1) = NX * rank
+ start(2) = 0
+ count(1) = NX
+ count(2) = 2
+
+ ! construct various MPI derived data types
+ blocklengths(1) = NX;
+ blocklengths(2) = NX;
+ call MPI_Get_address(buf(1,2), a0, ierr)
+ call MPI_Get_address(buf(1,1), a1, ierr)
+ disps(1) = 0
+ disps(2) = a1 - a0
+ call MPI_Type_create_hindexed(2, blocklengths, disps, MPI_INTEGER, &
+ buftype, ierr)
+ call MPI_Type_commit(buftype, ierr)
+
+ ! create a file type for the fixed-size variable
+ array_of_sizes(1) = NX*nprocs
+ array_of_sizes(2) = 2
+ array_of_subsizes(1) = INT(count(1))
+ array_of_subsizes(2) = INT(count(2))
+ array_of_starts(1) = INT(start(1))
+ array_of_starts(2) = INT(start(2))
+ call MPI_Type_create_subarray(2, array_of_sizes, array_of_subsizes, &
+ array_of_starts, MPI_ORDER_FORTRAN, MPI_INTEGER, fix_filetype,&
+ ierr)
+ call MPI_Type_commit(fix_filetype, ierr)
+
+ ! create a buftype with ghost cells on each side */
+ array_of_sizes(1) = INT(count(1))+4
+ array_of_sizes(2) = INT(count(2))+4
+ array_of_subsizes(1) = INT(count(1))
+ array_of_subsizes(2) = INT(count(2))
+ array_of_starts(1) = 2
+ array_of_starts(2) = 2
+ call MPI_Type_create_subarray(2, array_of_sizes, array_of_subsizes, &
+ array_of_starts, MPI_ORDER_FORTRAN, MPI_INTEGER, ghost_buftype,&
+ ierr)
+ call MPI_Type_commit(ghost_buftype, ierr)
+
+ ! initialized buffer contents
+ do j=1, INT(count(2))
+ do i=1, INT(count(1))
+ buf(i, j) = rank*100 + j*10 + i
+ enddo
+ enddo
+
+ ! create file, truncate it if exists
+ cmode = NF90_CLOBBER
+ err = nf90mpi_create(MPI_COMM_WORLD, filename, cmode, &
+ MPI_INFO_NULL, ncid)
+ call check(err, 'In nf90mpi_create: ')
+
+ ! define 2 dimensions
+ err = nf90mpi_def_dim(ncid, "RECV_DIM", NF90MPI_UNLIMITED, dimid(2))
+ call check(err, 'In nf90mpi_def_dim RECV_DIM: ')
+ len = NX * nprocs
+ err = nf90mpi_def_dim(ncid, "X", len, dimid(1))
+ call check(err, 'In nf90mpi_def_dim X: ')
+
+ ! define 2D record variables of integer type
+ err = nf90mpi_def_var(ncid, "rec_var", NF90_INT, dimid, varid0)
+ call check(err, 'In nf90mpi_def_var: rec_var ')
+ err = nf90mpi_def_var(ncid, "dummy_rec", NF90_INT, dimid, varid2)
+ call check(err, 'In nf90mpi_def_var: dummy_rec ')
+
+ ! define 2D fixed-size variable of integer type
+ err = nf90mpi_def_dim(ncid, "FIX_DIM", 2_MPI_OFFSET_KIND, dimid(2))
+ call check(err, 'In nf90mpi_def_dim RECV_DIM: ')
+ err = nf90mpi_def_var(ncid, "fix_var", NF90_INT, dimid, varid1)
+ call check(err, 'In nf90mpi_def_var: fix_var ')
+
+ ! do not forget to exit define mode
+ err = nf90mpi_enddef(ncid)
+ call check(err, 'In nf90mpi_enddef: ')
+
+ ! now we are in data mode
+
+ ! create a file type for the record variable */
+ err = nf90mpi_inq_recsize(ncid, recsize)
+ call check(err, 'In nf90mpi_inq_recsize: ')
+ blocklengths(1) = INT(count(1))
+ blocklengths(2) = INT(count(1))
+ disps(1) = start(1)*4
+ disps(2) = recsize + start(1)*4
+ call MPI_Type_create_hindexed(2, blocklengths, disps, &
+ MPI_INTEGER, rec_filetype, err)
+ call MPI_Type_commit(rec_filetype, err)
+
+ ! write the record variable */
+ err = nf90mpi_put_vard_all(ncid, varid0, rec_filetype, buf(:,2), &
+ 1_MPI_OFFSET_KIND, buftype)
+ call check(err, 'In nf90mpi_put_vard_all: ')
+ ! check if the contents of buf are altered
+ call check_value(rank, NX, NY, buf, nerrs)
+
+ ! check if root process can write to file header in data mode
+ err = nf90mpi_rename_var(ncid, varid0, 'rec_VAR')
+ call check(err, 'In nf90mpi_rename_var: ')
+
+ ! write the fixed-size variable
+ err = nf90mpi_put_vard_all(ncid, varid1, fix_filetype, buf(:,2), &
+ 1_MPI_OFFSET_KIND, buftype)
+ call check(err, 'In nf90mpi_put_vard_all: ')
+ ! check if the contents of buf are altered
+ call check_value(rank, NX, NY, buf, nerrs)
+
+ ! check if root process can write to file header in data mode
+ err = nf90mpi_rename_var(ncid, varid0, 'rec_var')
+ call check(err, 'In nf90mpi_rename_var: ')
+
+ ! close the file
+ err = nf90mpi_close(ncid)
+ call check(err, 'In nf90mpi_close: ')
+
+ ! open the same file and read back for validate */
+ err = nf90mpi_open(MPI_COMM_WORLD, filename, NF90_NOWRITE, &
+ MPI_INFO_NULL, ncid)
+ call check(err, 'In nf90mpi_open: ')
+
+ err = nf90mpi_inq_varid(ncid, "rec_var", varid0)
+ call check(err, 'In nf90mpi_inq_varid rec_var: ')
+ err = nf90mpi_inq_varid(ncid, "fix_var", varid1)
+ call check(err, 'In nf90mpi_inq_varid fix_var: ')
+
+ ! PnetCDF start() argument starts with 1
+ start = start + 1
+ call get_var_and_verify(ncid, varid0, NX,NY,start, count, buf, &
+ buftype, ghost_buftype, rec_filetype, nerrs)
+
+ call get_var_and_verify(ncid, varid1, NX,NY,start, count, buf, &
+ buftype, ghost_buftype, fix_filetype, nerrs)
+
+ ! close the file
+ err = nf90mpi_close(ncid)
+ call check(err, 'In nf90mpi_close: ')
+
+ call MPI_Type_free(rec_filetype, ierr)
+ call MPI_Type_free(fix_filetype, ierr)
+ call MPI_Type_free(buftype, ierr)
+ call MPI_Type_free(ghost_buftype, ierr)
+
+ ! check if there is any PnetCDF internal malloc residue
+ 998 format(A,I13,A)
+ err = nfmpi_inq_malloc_size(malloc_size)
+ if (err == NF_NOERR) then
+ call MPI_Reduce(malloc_size, sum_size, 1, MPI_OFFSET, &
+ MPI_SUM, 0, MPI_COMM_WORLD, ierr)
+ if (rank .EQ. 0 .AND. sum_size .GT. 0_MPI_OFFSET_KIND) print 998, &
+ 'heap memory allocated by PnetCDF internally has ', &
+ sum_size/1048576, ' MiB yet to be freed'
+ endif
+
+ msg = '*** TESTING F90 '//trim(cmd)//' for vard API '
+ if (rank .eq. 0) call pass_fail(nerrs, msg)
+
+ 999 call MPI_Finalize(ierr)
+ end program main
+
diff --git a/test/testcases/test_varm.c b/test/testcases/test_varm.c
new file mode 100644
index 0000000..91fee12
--- /dev/null
+++ b/test/testcases/test_varm.c
@@ -0,0 +1,201 @@
+/*
+ * Copyright (C) 2003, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ *
+ * $Id: test_varm.c 2133 2015-09-26 19:16:01Z wkliao $
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <pnetcdf.h>
+
+#include <testutils.h>
+
+#define PRINT_ERR_ON_SCREEN
+
+#define ERRCODE 2
+#define ERR {if (err!=NC_NOERR) {printf("Error at line %d: %s\n", __LINE__, ncmpi_strerror(err)); nerrs++;}}
+
+/*----< main() >------------------------------------------------------------*/
+int main(int argc, char **argv)
+{
+ int i, j, err, nerrs=0, rank, nprocs, verbose;
+ int ncid, dimid[2], varid, req, status;
+
+ MPI_Offset start[2], count[2], stride[2], imap[2];
+ int var[6][4];
+ float rh[4][6];
+ signed char varT[4][6];
+ char *filename="testfile.nc";
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+
+ if (argc > 2) {
+ if (!rank) printf("Usage: %s [filename]\n",argv[0]);
+ MPI_Finalize();
+ return 0;
+ }
+ if (argc == 2) filename = argv[1];
+
+ if (rank == 0) {
+ char cmd_str[256];
+ sprintf(cmd_str, "*** TESTING C %s for get/put varm ", argv[0]);
+ printf("%-66s ------ ", cmd_str); fflush(stdout);
+ }
+
+ verbose = 0;
+ if (nprocs > 1 && rank == 0 && verbose)
+ printf("Warning: %s is designed to run on 1 process\n", argv[0]);
+
+ err = ncmpi_create(MPI_COMM_WORLD, filename, NC_CLOBBER | NC_64BIT_DATA,
+ MPI_INFO_NULL, &ncid); ERR
+
+ /* define a variable of a 6 x 4 integer array in the nc file */
+ err = ncmpi_def_dim(ncid, "Y", 6, &dimid[0]); ERR
+ err = ncmpi_def_dim(ncid, "X", 4, &dimid[1]); ERR
+ err = ncmpi_def_var(ncid, "var", NC_INT, 2, dimid, &varid); ERR
+ err = ncmpi_enddef(ncid); ERR
+
+ /* create a 6 x 4 integer variable in the file with contents:
+ 0, 1, 2, 3,
+ 4, 5, 6, 7,
+ 8, 9, 10, 11,
+ 12, 13, 14, 15,
+ 16, 17, 18, 19,
+ 20, 21, 22, 23
+ */
+ for (j=0; j<6; j++) for (i=0; i<4; i++) var[j][i] = j*4+i;
+
+ start[0] = 0; start[1] = 0;
+ count[0] = 6; count[1] = 4;
+ if (rank > 0) count[0] = count[1] = 0;
+ err = ncmpi_put_vara_int_all(ncid, varid, start, count, &var[0][0]); ERR
+
+ if (nprocs > 1) MPI_Barrier(MPI_COMM_WORLD);
+
+ /* read the variable back in the matrix transposed way, rh is 4 x 6 */
+ count[0] = 6; count[1] = 4;
+ stride[0] = 1; stride[1] = 1;
+ imap[0] = 1; imap[1] = 6; /* would be {4, 1} if not transposing */
+#define TEST_NON_BLOCKING_API
+#ifdef TEST_NON_BLOCKING_API
+ err = ncmpi_iget_varm_float(ncid, varid, start, count, stride, imap, &rh[0][0], &req); ERR
+
+ err = ncmpi_wait_all(ncid, 1, &req, &status); ERR
+
+ if (status != NC_NOERR) ERR
+#else
+ err = ncmpi_get_varm_float_all(ncid, varid, start, count, stride, imap, &rh[0][0]); ERR
+#endif
+
+ /* check the contents of read */
+ float k = 0.0;
+ for (i=0; i<6; i++) {
+ for (j=0; j<4; j++) {
+ if (rh[j][i] != k) {
+#ifdef PRINT_ERR_ON_SCREEN
+ printf("Error: expecting rh[%d][%d]=%f but got %f\n",j,i,k,rh[j][i]);
+#endif
+ nerrs++;
+ break;
+ }
+ k += 1.0;
+ }
+ }
+#ifdef PRINT_ON_SCREEN
+ /* print the contents of read */
+ for (j=0; j<4; j++) {
+ printf("[%2d]: ",j);
+ for (i=0; i<6; i++) {
+ printf("%5.1f",rh[j][i]);
+ }
+ printf("\n");
+ }
+#endif
+ /* the stdout should be:
+ [ 0]: 0.0 4.0 8.0 12.0 16.0 20.0
+ [ 1]: 1.0 5.0 9.0 13.0 17.0 21.0
+ [ 2]: 2.0 6.0 10.0 14.0 18.0 22.0
+ [ 3]: 3.0 7.0 11.0 15.0 19.0 23.0
+ */
+
+ /* testing get_varm(), first zero-out the variable in the file */
+ memset(&var[0][0], 0, 6*4*sizeof(int));
+ start[0] = 0; start[1] = 0;
+ count[0] = 6; count[1] = 4;
+ if (rank > 0) count[0] = count[1] = 0;
+ err = ncmpi_put_vara_int_all(ncid, varid, start, count, &var[0][0]); ERR
+
+ /* set the contents of the write buffer varT, a 4 x 6 char array
+ 50, 51, 52, 53, 54, 55,
+ 56, 57, 58, 59, 60, 61,
+ 62, 63, 64, 65, 66, 67,
+ 68, 69, 70, 71, 72, 73
+ */
+ for (j=0; j<4; j++) for (i=0; i<6; i++) varT[j][i] = j*6+i + 50;
+
+ /* write varT to the NC variable in the matrix transposed way */
+ start[0] = 0; start[1] = 0;
+ count[0] = 6; count[1] = 4;
+ stride[0] = 1; stride[1] = 1;
+ imap[0] = 1; imap[1] = 6; /* would be {4, 1} if not transposing */
+ if (rank > 0) count[0] = count[1] = 0;
+#ifdef TEST_NON_BLOCKING_API
+ err = ncmpi_iput_varm_schar(ncid, varid, start, count, stride, imap, &varT[0][0], &req); ERR
+
+ err = ncmpi_wait_all(ncid, 1, &req, &status); ERR
+
+ if (status != NC_NOERR) ERR
+#else
+ err = ncmpi_put_varm_schar_all(ncid, varid, start, count, stride, imap, &varT[0][0]); ERR
+#endif
+
+ /* the output from command "ncmpidump -v var test.nc" should be:
+ var =
+ 50, 56, 62, 68,
+ 51, 57, 63, 69,
+ 52, 58, 64, 70,
+ 53, 59, 65, 71,
+ 54, 60, 66, 72,
+ 55, 61, 67, 73 ;
+ */
+
+ /* check if the contents of write buffer have been altered */
+ for (j=0; j<4; j++) {
+ for (i=0; i<6; i++) {
+ if (varT[j][i] != j*6+i + 50) {
+#ifdef PRINT_ERR_ON_SCREEN
+ /* this error is a pntecdf internal error, if occurs */
+ printf("Error: expecting varT[%d][%d]=%d but got %d\n",j,i,j*6+i + 50,varT[j][i]);
+#endif
+ nerrs++;
+ break;
+ }
+ }
+ }
+ err = ncmpi_close(ncid); ERR
+
+ /* check if PnetCDF freed all internal malloc */
+ MPI_Offset malloc_size, sum_size;
+ err = ncmpi_inq_malloc_size(&malloc_size);
+ if (err == NC_NOERR) {
+ MPI_Reduce(&malloc_size, &sum_size, 1, MPI_OFFSET, MPI_SUM, 0, MPI_COMM_WORLD);
+ if (rank == 0 && sum_size > 0)
+ printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n",
+ sum_size);
+ }
+
+ MPI_Allreduce(MPI_IN_PLACE, &nerrs, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
+ if (rank == 0) {
+ if (nerrs) printf(FAIL_STR,nerrs);
+ else printf(PASS_STR);
+ }
+
+ MPI_Finalize();
+
+ return (nerrs == 0) ? 0 : 1;
+}
+
diff --git a/test/testcases/varn_contig.c b/test/testcases/varn_contig.c
new file mode 100644
index 0000000..04b55e5
--- /dev/null
+++ b/test/testcases/varn_contig.c
@@ -0,0 +1,240 @@
+/*********************************************************************
+ *
+ * Copyright (C) 2014, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ *
+ *********************************************************************/
+/* $Id: varn_contig.c 2219 2015-12-11 22:30:03Z wkliao $ */
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * This example tests using a single call of ncmpi_put_varn_int_all() to
+ * write a sequence of requests with arbitrary array indices and lengths.
+ * Specifically, the fileview in each process is made a contiguous chunk.
+ *
+ * The compile and run commands are given below, together with an ncmpidump of
+ * the output file.
+ *
+ * % mpicc -O2 -o varn_contig varn_contig.c -lpnetcdf
+ * % mpiexec -n 4 ./varn_contig /pvfs2/wkliao/testfile.nc
+ * % ncmpidump /pvfs2/wkliao/testfile.nc
+ * netcdf testfile {
+ * // file format: CDF-5 (big variables)
+ * dimensions:
+ * Y = 4 ;
+ * X = 10 ;
+ * variables:
+ * int var(Y, X) ;
+ * data:
+ *
+ * var =
+ * 200, 200, 200, 200, 200, 200, 200, 200, 200, 200,
+ * 300, 300, 300, 300, 300, 300, 300, 300, 300, 300,
+ * 400, 400, 400, 400, 400, 400, 400, 400, 400, 400,
+ * 100, 100, 100, 100, 100, 100, 100, 100, 100, 100 ;
+ * }
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h> /* strcpy(), memset() */
+#include <mpi.h>
+#include <pnetcdf.h>
+
+#include <testutils.h>
+
+#define NY 4
+#define NX 10
+#define NDIMS 2
+
+#define ERR {if(err!=NC_NOERR){printf("Error at %s line=%d: %s\n", __FILE__,__LINE__, ncmpi_strerror(err)); nerrs++;}}
+
+static
+int check_contents_for_fail(int *buffer)
+{
+ int i, nprocs;
+ int expected[NY*NX] = {200, 200, 200, 200, 200, 200, 200, 200, 200, 200,
+ 300, 300, 300, 300, 300, 300, 300, 300, 300, 300,
+ 400, 400, 400, 400, 400, 400, 400, 400, 400, 400,
+ 100, 100, 100, 100, 100, 100, 100, 100, 100, 100};
+
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+
+ /* check if the contents of buf are expected */
+ for (i=0; i<NY*NX; i++) {
+ if (expected[i] >= nprocs) continue;
+ if (buffer[i] != expected[i]) {
+ printf("Expected read buf[%d]=%d, but got %d\n",
+ i,expected[i],buffer[i]);
+ return 1;
+ }
+ }
+ return 0;
+}
+
+int main(int argc, char** argv)
+{
+ char filename[256];
+ int i, rank, nprocs, err, verbose=0, nerrs=0;
+ int ncid, cmode, varid[3], dimid[2], num_reqs, *buffer, *r_buffer;
+ MPI_Offset w_len, **starts, **counts;
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+
+ if (argc > 2) {
+ if (!rank) printf("Usage: %s [filename]\n",argv[0]);
+ MPI_Finalize();
+ return 0;
+ }
+ strcpy(filename, "testfile.nc");
+ if (argc == 2) strcpy(filename, argv[1]);
+ MPI_Bcast(filename, 256, MPI_CHAR, 0, MPI_COMM_WORLD);
+
+ if (rank == 0) {
+ char cmd_str[256];
+ sprintf(cmd_str, "*** TESTING C %s for put_varn with contig fileview", argv[0]);
+ printf("%-66s ------ ", cmd_str); fflush(stdout);
+ }
+
+ if (verbose && nprocs != 4 && rank == 0)
+ printf("Warning: %s is intended to run on 4 processes\n",argv[0]);
+
+ /* create a new file for writing ----------------------------------------*/
+ cmode = NC_CLOBBER | NC_64BIT_DATA;
+ err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, MPI_INFO_NULL, &ncid);
+ ERR
+
+ /* create a global array of size NY * NX */
+ err = ncmpi_def_dim(ncid, "Y", NY, &dimid[0]);
+ ERR
+ err = ncmpi_def_dim(ncid, "X", NX, &dimid[1]);
+ ERR
+ err = ncmpi_def_var(ncid, "var", NC_INT, NDIMS, dimid, &varid[0]);
+ ERR
+ err = ncmpi_enddef(ncid);
+ ERR
+
+ /* pick arbitrary numbers of requests for 4 processes */
+ num_reqs = 0;
+ if (rank == 0) num_reqs = 4;
+ else if (rank == 1) num_reqs = 5;
+ else if (rank == 2) num_reqs = 5;
+ else if (rank == 3) num_reqs = 5;
+
+ starts = (MPI_Offset**) malloc(num_reqs * sizeof(MPI_Offset*));
+ counts = (MPI_Offset**) malloc(num_reqs * sizeof(MPI_Offset*));
+ starts[0] = (MPI_Offset*) calloc(num_reqs * NDIMS, sizeof(MPI_Offset));
+ counts[0] = (MPI_Offset*) calloc(num_reqs * NDIMS, sizeof(MPI_Offset));
+ for (i=1; i<num_reqs; i++) {
+ starts[i] = starts[i-1] + NDIMS;
+ counts[i] = counts[i-1] + NDIMS;
+ }
+
+ /* assign arbitrary starts and counts */
+ const int y=0, x=1;
+ if (rank == 0) {
+ starts[0][y] = 3; starts[0][x] = 0; counts[0][y] = 1; counts[0][x] = 3;
+ starts[1][y] = 3; starts[1][x] = 4; counts[1][y] = 1; counts[1][x] = 3;
+ starts[2][y] = 3; starts[2][x] = 3; counts[2][y] = 1; counts[2][x] = 1;
+ starts[3][y] = 3; starts[3][x] = 7; counts[3][y] = 1; counts[3][x] = 3;
+ /* - , - , - , - , - , - , - , - , - , - ,
+ - , - , - , - , - , - , - , - , - , - ,
+ - , - , - , - , - , - , - , - , - , - ,
+ 100, 100, 100, 100, 100, 100, 100, 100, 100, 100
+ req id: 0 0 0 2 1 1 1 3 3 3
+ */
+ } else if (rank ==1) {
+ starts[0][y] = 0; starts[0][x] = 3; counts[0][y] = 1; counts[0][x] = 2;
+ starts[1][y] = 0; starts[1][x] = 8; counts[1][y] = 1; counts[1][x] = 2;
+ starts[2][y] = 0; starts[2][x] = 5; counts[2][y] = 1; counts[2][x] = 2;
+ starts[3][y] = 0; starts[3][x] = 7; counts[3][y] = 1; counts[3][x] = 1;
+ starts[4][y] = 0; starts[4][x] = 0; counts[4][y] = 1; counts[4][x] = 3;
+ /* 200, 200, 200, 200, 200, 200, 200, 200, 200, 200
+ - , - , - , - , - , - , - , - , - , - ,
+ - , - , - , - , - , - , - , - , - , - ,
+ - , - , - , - , - , - , - , - , - , - ,
+ req id: 4 4 4 0 0 2 2 3 1 1
+ */
+ } else if (rank ==2) {
+ starts[0][y] = 1; starts[0][x] = 1; counts[0][y] = 1; counts[0][x] = 3;
+ starts[1][y] = 1; starts[1][x] = 0; counts[1][y] = 1; counts[1][x] = 1;
+ starts[2][y] = 1; starts[2][x] = 5; counts[2][y] = 1; counts[2][x] = 2;
+ starts[3][y] = 1; starts[3][x] = 7; counts[3][y] = 1; counts[3][x] = 3;
+ starts[4][y] = 1; starts[4][x] = 4; counts[4][y] = 1; counts[4][x] = 1;
+ /* - , - , - , - , - , - , - , - , - , - ,
+ 300, 300, 300, 300, 300, 300, 300, 300, 300, 300
+ - , - , - , - , - , - , - , - , - , - ,
+ - , - , - , - , - , - , - , - , - , - ,
+ req id: 1 0 0 0 4 2 3 3 3 3
+ */
+ } else if (rank ==3) {
+ starts[0][y] = 2; starts[0][x] = 3; counts[0][y] = 1; counts[0][x] = 3;
+ starts[1][y] = 2; starts[1][x] = 6; counts[1][y] = 1; counts[1][x] = 2;
+ starts[2][y] = 2; starts[2][x] = 0; counts[2][y] = 1; counts[2][x] = 2;
+ starts[3][y] = 2; starts[3][x] = 8; counts[3][y] = 1; counts[3][x] = 2;
+ starts[4][y] = 2; starts[4][x] = 2; counts[4][y] = 1; counts[4][x] = 1;
+ /* - , - , - , - , - , - , - , - , - , - ,
+ - , - , - , - , - , - , - , - , - , - ,
+ 400, 400, 400, 400, 400, 400, 400, 400, 400, 400
+ - , - , - , - , - , - , - , - , - , - ,
+ req id: 2 2 4 0 0 0 1 1 3 3
+ */
+ }
+
+ w_len = NX; /* total write length for this process */
+
+ /* allocate I/O buffer and initialize its contents */
+ r_buffer = (int*) malloc(NY*NX * sizeof(int));
+ buffer = (int*) malloc(w_len * sizeof(int));
+ for (i=0; i<w_len; i++) buffer[i] = rank*100 + 100;
+
+ /* check error code: NC_ENULLSTART */
+ err = ncmpi_put_varn_int_all(ncid, varid[0], 1, NULL, NULL, NULL);
+ if (err != NC_ENULLSTART) {
+ printf("expecting error code NC_ENULLSTART but got %s\n",nc_err_code_name(err));
+ nerrs++;
+ }
+
+ /* write using varn API */
+ err = ncmpi_put_varn_int_all(ncid, varid[0], num_reqs, starts, counts, buffer);
+ ERR
+
+ if (nprocs > 4) MPI_Barrier(MPI_COMM_WORLD);
+
+ /* read back and check contents */
+ memset(r_buffer, 0, NY*NX*sizeof(int));
+ err = ncmpi_get_var_int_all(ncid, varid[0], r_buffer);
+ ERR
+ nerrs += check_contents_for_fail(r_buffer);
+
+ err = ncmpi_close(ncid);
+ ERR
+
+ free(buffer);
+ free(r_buffer);
+ free(starts[0]);
+ free(counts[0]);
+ free(starts);
+ free(counts);
+
+ /* check if PnetCDF freed all internal malloc */
+ MPI_Offset malloc_size, sum_size;
+ err = ncmpi_inq_malloc_size(&malloc_size);
+ if (err == NC_NOERR) {
+ MPI_Reduce(&malloc_size, &sum_size, 1, MPI_OFFSET, MPI_SUM, 0, MPI_COMM_WORLD);
+ if (rank == 0 && sum_size > 0)
+ printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n",
+ sum_size);
+ }
+
+ MPI_Allreduce(MPI_IN_PLACE, &nerrs, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
+ if (rank == 0) {
+ if (nerrs) printf(FAIL_STR,nerrs);
+ else printf(PASS_STR);
+ }
+
+ MPI_Finalize();
+ return 0;
+}
+
diff --git a/test/testcases/varn_int.c b/test/testcases/varn_int.c
new file mode 100644
index 0000000..8394237
--- /dev/null
+++ b/test/testcases/varn_int.c
@@ -0,0 +1,320 @@
+/*********************************************************************
+ *
+ * Copyright (C) 2014, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ *
+ *********************************************************************/
+/* $Id: varn_int.c 2219 2015-12-11 22:30:03Z wkliao $ */
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * This example tests using a single call of ncmpi_put_varn_int_all() to
+ * write a sequence of requests with arbitrary array indices and lengths.
+ *
+ * The compile and run commands are given below, together with an ncmpidump of
+ * the output file.
+ *
+ * % mpicc -O2 -o varn_int varn_int.c -lpnetcdf
+ * % mpiexec -n 4 ./varn_int /pvfs2/wkliao/testfile.nc
+ * % ncmpidump /pvfs2/wkliao/testfile.nc
+ * netcdf testfile {
+ * // file format: CDF-5 (big variables)
+ * dimensions:
+ * Y = 4 ;
+ * X = 10 ;
+ * REC_DIM = UNLIMITED ; // (4 currently)
+ * variables:
+ * int var(Y, X) ;
+ * int rec_var(REC_DIM, X) ;
+ * data:
+ *
+ * var =
+ * 3, 3, 3, 1, 1, 0, 0, 2, 1, 1,
+ * 0, 2, 2, 2, 3, 1, 1, 2, 2, 2,
+ * 1, 1, 2, 3, 3, 3, 0, 0, 1, 1,
+ * 0, 0, 0, 2, 1, 1, 1, 3, 3, 3 ;
+ *
+ * rec_var =
+ * 3, 3, 3, 1, 1, 0, 0, 2, 1, 1,
+ * 0, 2, 2, 2, 3, 1, 1, 2, 2, 2,
+ * 1, 1, 2, 3, 3, 3, 0, 0, 1, 1,
+ * 0, 0, 0, 2, 1, 1, 1, 3, 3, 3 ;
+ * }
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h> /* strcpy(), memset() */
+#include <mpi.h>
+#include <pnetcdf.h>
+
+#include <testutils.h>
+
+#define NY 4
+#define NX 10
+#define NDIMS 2
+
+#define ERR {if(err!=NC_NOERR){printf("Error at %s line=%d: %s\n", __FILE__,__LINE__, ncmpi_strerror(err)); nerrs++;}}
+
+static
+int check_contents_for_fail(int *buffer)
+{
+ int i, nprocs;
+ int expected[NY*NX] = {3, 3, 3, 1, 1, 0, 0, 2, 1, 1,
+ 0, 2, 2, 2, 3, 1, 1, 2, 2, 2,
+ 1, 1, 2, 3, 3, 3, 0, 0, 1, 1,
+ 0, 0, 0, 2, 1, 1, 1, 3, 3, 3};
+
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+
+ /* check if the contents of buf are expected */
+ for (i=0; i<NY*NX; i++) {
+ if (expected[i] >= nprocs) continue;
+ if (buffer[i] != expected[i]) {
+ printf("Expected read buf[%d]=%d, but got %d\n",
+ i,expected[i],buffer[i]);
+ return 1;
+ }
+ }
+ return 0;
+}
+
+static
+void permute(MPI_Offset a[NDIMS], MPI_Offset b[NDIMS])
+{
+ int i;
+ MPI_Offset tmp;
+ for (i=0; i<NDIMS; i++) {
+ tmp = a[i]; a[i] = b[i]; b[i] = tmp;
+ }
+}
+
+int main(int argc, char** argv)
+{
+ char filename[256];
+ int i, j, rank, nprocs, err, verbose=0, nerrs=0;
+ int ncid, cmode, varid[3], dimid[2], num_reqs, *buffer, *r_buffer;
+ MPI_Offset w_len, **starts, **counts;
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+
+ if (argc > 2) {
+ if (!rank) printf("Usage: %s [filename]\n",argv[0]);
+ MPI_Finalize();
+ return 0;
+ }
+ strcpy(filename, "testfile.nc");
+ if (argc == 2) strcpy(filename, argv[1]);
+ MPI_Bcast(filename, 256, MPI_CHAR, 0, MPI_COMM_WORLD);
+
+ if (rank == 0) {
+ char cmd_str[256];
+ sprintf(cmd_str, "*** TESTING C %s for ncmpi_put_varn_int_all() ", argv[0]);
+ printf("%-66s ------ ", cmd_str); fflush(stdout);
+ }
+
+ if (verbose && nprocs != 4 && rank == 0)
+ printf("Warning: %s is intended to run on 4 processes\n",argv[0]);
+
+ /* create a new file for writing ----------------------------------------*/
+ cmode = NC_CLOBBER | NC_64BIT_DATA;
+ err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, MPI_INFO_NULL, &ncid);
+ ERR
+
+ /* create a global array of size NY * NX */
+ err = ncmpi_def_dim(ncid, "Y", NY, &dimid[0]);
+ ERR
+ err = ncmpi_def_dim(ncid, "X", NX, &dimid[1]);
+ ERR
+ err = ncmpi_def_var(ncid, "var", NC_INT, NDIMS, dimid, &varid[0]);
+ ERR
+ err = ncmpi_def_dim(ncid, "REC_DIM", NC_UNLIMITED, &dimid[0]);
+ ERR
+ err = ncmpi_def_var(ncid, "rec_var", NC_INT, NDIMS, dimid, &varid[1]);
+ ERR
+ err = ncmpi_enddef(ncid);
+ ERR
+
+ /* pick arbitrary numbers of requests for 4 processes */
+ num_reqs = 0;
+ if (rank == 0) num_reqs = 4;
+ else if (rank == 1) num_reqs = 6;
+ else if (rank == 2) num_reqs = 5;
+ else if (rank == 3) num_reqs = 4;
+
+ starts = (MPI_Offset**) malloc(num_reqs * sizeof(MPI_Offset*));
+ counts = (MPI_Offset**) malloc(num_reqs * sizeof(MPI_Offset*));
+ starts[0] = (MPI_Offset*) calloc(num_reqs * NDIMS, sizeof(MPI_Offset));
+ counts[0] = (MPI_Offset*) calloc(num_reqs * NDIMS, sizeof(MPI_Offset));
+ for (i=1; i<num_reqs; i++) {
+ starts[i] = starts[i-1] + NDIMS;
+ counts[i] = counts[i-1] + NDIMS;
+ }
+
+ /* assign arbitrary starts and counts */
+ const int y=0, x=1;
+ if (rank == 0) {
+ starts[0][y] = 0; starts[0][x] = 5; counts[0][y] = 1; counts[0][x] = 2;
+ starts[1][y] = 1; starts[1][x] = 0; counts[1][y] = 1; counts[1][x] = 1;
+ starts[2][y] = 2; starts[2][x] = 6; counts[2][y] = 1; counts[2][x] = 2;
+ starts[3][y] = 3; starts[3][x] = 0; counts[3][y] = 1; counts[3][x] = 3;
+ /* rank 0 is writing the followings: ("-" means skip)
+ - - - - - 0 0 - - -
+ 0 - - - - - - - - -
+ - - - - - - 0 0 - -
+ 0 0 0 - - - - - - -
+ */
+ } else if (rank ==1) {
+ starts[0][y] = 0; starts[0][x] = 3; counts[0][y] = 1; counts[0][x] = 2;
+ starts[1][y] = 0; starts[1][x] = 8; counts[1][y] = 1; counts[1][x] = 2;
+ starts[2][y] = 1; starts[2][x] = 5; counts[2][y] = 1; counts[2][x] = 2;
+ starts[3][y] = 2; starts[3][x] = 0; counts[3][y] = 1; counts[3][x] = 2;
+ starts[4][y] = 2; starts[4][x] = 8; counts[4][y] = 1; counts[4][x] = 2;
+ starts[5][y] = 3; starts[5][x] = 4; counts[5][y] = 1; counts[5][x] = 3;
+ /* rank 1 is writing the followings: ("-" means skip)
+ - - - 1 1 - - - 1 1
+ - - - - - 1 1 - - -
+ 1 1 - - - - - - 1 1
+ - - - - 1 1 1 - - -
+ */
+ } else if (rank ==2) {
+ starts[0][y] = 0; starts[0][x] = 7; counts[0][y] = 1; counts[0][x] = 1;
+ starts[1][y] = 1; starts[1][x] = 1; counts[1][y] = 1; counts[1][x] = 3;
+ starts[2][y] = 1; starts[2][x] = 7; counts[2][y] = 1; counts[2][x] = 3;
+ starts[3][y] = 2; starts[3][x] = 2; counts[3][y] = 1; counts[3][x] = 1;
+ starts[4][y] = 3; starts[4][x] = 3; counts[4][y] = 1; counts[4][x] = 1;
+ /* rank 2 is writing the followings: ("-" means skip)
+ - - - - - - - 2 - -
+ - 2 2 2 - - - 2 2 2
+ - - 2 - - - - - - -
+ - - - 2 - - - - - -
+ */
+ } else if (rank ==3) {
+ starts[0][y] = 0; starts[0][x] = 0; counts[0][y] = 1; counts[0][x] = 3;
+ starts[1][y] = 1; starts[1][x] = 4; counts[1][y] = 1; counts[1][x] = 1;
+ starts[2][y] = 2; starts[2][x] = 3; counts[2][y] = 1; counts[2][x] = 3;
+ starts[3][y] = 3; starts[3][x] = 7; counts[3][y] = 1; counts[3][x] = 3;
+ /* rank 3 is writing the followings: ("-" means skip)
+ 3 3 3 - - - - - - -
+ - - - - 3 - - - - -
+ - - - 3 3 3 - - - -
+ - - - - - - - 3 3 3
+ */
+ }
+
+ w_len = 0; /* total write length for this process */
+ for (i=0; i<num_reqs; i++) {
+ MPI_Offset w_req_len=1;
+ for (j=0; j<NDIMS; j++)
+ w_req_len *= counts[i][j];
+ w_len += w_req_len;
+ }
+
+ /* allocate I/O buffer and initialize its contents */
+ r_buffer = (int*) malloc(NY*NX * sizeof(int));
+ buffer = (int*) malloc(w_len * sizeof(int));
+ for (i=0; i<w_len; i++) buffer[i] = rank;
+
+ /* check error code: NC_ENULLSTART */
+ err = ncmpi_put_varn_int_all(ncid, varid[0], 1, NULL, NULL, NULL);
+ if (err != NC_ENULLSTART) {
+ printf("expecting error code NC_ENULLSTART but got %s\n",nc_err_code_name(err));
+ nerrs++;
+ }
+
+ /* write using varn API */
+ err = ncmpi_put_varn_int_all(ncid, varid[0], num_reqs, starts, counts, buffer);
+ ERR
+
+ if (nprocs > 4) MPI_Barrier(MPI_COMM_WORLD);
+
+ /* read back and check contents */
+ memset(r_buffer, 0, NY*NX*sizeof(int));
+ err = ncmpi_get_var_int_all(ncid, varid[0], r_buffer);
+ ERR
+ nerrs += check_contents_for_fail(r_buffer);
+
+ /* permute write order */
+ if (num_reqs > 0) {
+ permute(starts[1], starts[2]); permute(counts[1], counts[2]);
+ permute(starts[2], starts[3]); permute(counts[2], counts[3]);
+ }
+
+ /* write using varn API */
+ err = ncmpi_put_varn_int_all(ncid, varid[1], num_reqs, starts, counts, buffer);
+ ERR
+
+ /* read back using get_var API and check contents */
+ memset(r_buffer, 0, NY*NX*sizeof(int));
+ err = ncmpi_get_var_int_all(ncid, varid[1], r_buffer);
+ ERR
+ nerrs += check_contents_for_fail(r_buffer);
+
+ /* read back using get_varn API and check contents */
+ for (i=0; i<w_len; i++) buffer[i] = -1;
+ err = ncmpi_get_varn_int_all(ncid, varid[0], num_reqs, starts, counts, buffer);
+ ERR
+
+ for (i=0; i<w_len; i++) {
+ if (buffer[i] != rank) {
+ printf("Error at line %d: expecting buffer[%d]=%d but got %d\n",
+ __LINE__,i,rank,buffer[i]);
+ nerrs++;
+ }
+ }
+
+ /* test flexible API, using a noncontiguous buftype */
+ MPI_Datatype buftype;
+ MPI_Type_vector(w_len, 1, 2, MPI_INT, &buftype);
+ MPI_Type_commit(&buftype);
+ free(buffer);
+ buffer = (int*) malloc(w_len * 2 * sizeof(int));
+ for (i=0; i<2*w_len; i++) buffer[i] = -1;
+ err = ncmpi_get_varn_all(ncid, varid[0], num_reqs, starts, counts, buffer, 1, buftype);
+ ERR
+ MPI_Type_free(&buftype);
+
+ for (i=0; i<w_len*2; i++) {
+ if (i%2 && buffer[i] != -1) {
+ printf("Error at line %d: expecting buffer[%d]=-1 but got %d\n",
+ __LINE__,i,buffer[i]);
+ nerrs++;
+ }
+ if (i%2 == 0 && buffer[i] != rank) {
+ printf("Error at line %d: expecting buffer[%d]=%d but got %d\n",
+ __LINE__,i,rank,buffer[i]);
+ nerrs++;
+ }
+ }
+
+ err = ncmpi_close(ncid);
+ ERR
+
+ free(buffer);
+ free(r_buffer);
+ free(starts[0]);
+ free(counts[0]);
+ free(starts);
+ free(counts);
+
+ /* check if PnetCDF freed all internal malloc */
+ MPI_Offset malloc_size, sum_size;
+ err = ncmpi_inq_malloc_size(&malloc_size);
+ if (err == NC_NOERR) {
+ MPI_Reduce(&malloc_size, &sum_size, 1, MPI_OFFSET, MPI_SUM, 0, MPI_COMM_WORLD);
+ if (rank == 0 && sum_size > 0)
+ printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n",
+ sum_size);
+ }
+
+ MPI_Allreduce(MPI_IN_PLACE, &nerrs, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
+ if (rank == 0) {
+ if (nerrs) printf(FAIL_STR,nerrs);
+ else printf(PASS_STR);
+ }
+
+ MPI_Finalize();
+ return 0;
+}
+
diff --git a/test/testcases/varn_intf.f b/test/testcases/varn_intf.f
new file mode 100644
index 0000000..6b925e7
--- /dev/null
+++ b/test/testcases/varn_intf.f
@@ -0,0 +1,288 @@
+!
+! Copyright (C) 2013, Northwestern University
+! See COPYRIGHT notice in top-level directory.
+!
+! $Id: varn_intf.f 2224 2015-12-16 06:10:36Z wkliao $
+
+! This example shows how to use a single call of nfmpi_put_varn_int_all() to
+! write a sequence of requests with arbitrary array indices and lengths.
+! Using nfmpi_put_varn_int_all() can achieve the same effect of HDF5 writing
+! a sequence of selected file locations through the following 2 APIs.
+!
+! H5Sselect_elements(fid, H5S_SELECT_SET, NUMP, (const hssize_t **)coord);
+! H5Dwrite(dataset, H5T_NATIVE_INT, mid, fid, H5P_DEFAULT, val);
+!
+! Note that in nfmpi_put_varn_int_all(), users can write more than one element
+! starting at each selected location.
+!
+! The compile and run commands are given below, together with an ncmpidump of
+! the output file.
+!
+! % mpif77 -O2 -o varn_int varn_intf.f -lpnetcdf
+! % mpiexec -n 4 ./varn_intf /pvfs2/wkliao/testfile.nc
+! % ncmpidump /pvfs2/wkliao/testfile.nc
+! netcdf testfile {
+! // file format: CDF-5 (big variables)
+! dimensions:
+! X = 4 ;
+! Y = 10 ;
+! variables:
+! int var(Y, X) ;
+! data:
+!
+! var =
+! 2, 2, 1, 1,
+! 2, 2, 0, 0,
+! 1, 1, 0, 0,
+! 1, 1, 3, 3,
+! 3, 3, 2, 2,
+! 0, 0, 1, 1,
+! 0, 0, 1, 1,
+! 2, 2, 0, 0,
+! 3, 3, 3, 3,
+! 3, 3, 3, 3 ;
+! }
+!
+! Note the above dump is in C order
+!
+
+ INTEGER FUNCTION XTRIM(STRING)
+ CHARACTER*(*) STRING
+ INTEGER I, N
+ N = LEN(STRING)
+ DO I = N, 1, -1
+ IF (STRING(I:I) .NE. ' ') GOTO 10
+ ENDDO
+ 10 XTRIM = I
+ END ! FUNCTION XTRIM
+
+ subroutine check(err, message)
+ implicit none
+ include "mpif.h"
+ include "pnetcdf.inc"
+ integer err, XTRIM
+ character*(*) message
+ character*128 msg
+
+ ! It is a good idea to check returned value for possible error
+ if (err .NE. NF_NOERR) then
+ write(6,*) message(1:XTRIM(message)), nfmpi_strerror(err)
+ msg = '*** TESTING F77 varn_intf.f for varn API '
+ call pass_fail(1, msg)
+ call MPI_Abort(MPI_COMM_WORLD, -1, err)
+ end if
+ end ! subroutine check
+
+ program main
+ implicit none
+ include "mpif.h"
+ include "pnetcdf.inc"
+
+ integer NDIMS, XTRIM
+ integer*8 NX, NY
+ PARAMETER(NDIMS=2, NX=4, NY=10)
+
+ character*256 filename, cmd, msg
+ integer i, j, err, ierr, nprocs, rank, nerrs, get_args
+ integer cmode, ncid, varid, dimid(NDIMS), num_reqs
+
+ integer*8 w_len, w_req_len
+ integer*8 starts(NDIMS, 13)
+ integer*8 counts(NDIMS, 13)
+ integer*8 malloc_size, sum_size
+ integer buffer(13)
+
+ call MPI_Init(ierr)
+ call MPI_Comm_rank(MPI_COMM_WORLD, rank, ierr)
+ call MPI_Comm_size(MPI_COMM_WORLD, nprocs, ierr)
+
+ ! take filename from command-line argument if there is any
+ if (rank .EQ. 0) then
+ filename = "testfile.nc"
+ err = get_args(cmd, filename)
+ endif
+ call MPI_Bcast(err, 1, MPI_INTEGER, 0, MPI_COMM_WORLD, ierr)
+ if (err .EQ. 0) goto 999
+
+ call MPI_Bcast(filename, 256, MPI_CHARACTER, 0,
+ + MPI_COMM_WORLD, ierr)
+
+ nerrs = 0
+
+ if (.FALSE. .AND. nprocs .NE. 4 .AND. rank .EQ. 0)
+ + print*,'Warning: ',cmd(1:XTRIM(cmd)),
+ + ' is intended to run on 4 processes'
+
+ ! create file, truncate it if exists
+ cmode = IOR(NF_CLOBBER, NF_64BIT_DATA)
+ err = nfmpi_create(MPI_COMM_WORLD, filename, cmode,
+ + MPI_INFO_NULL, ncid)
+ call check(err, 'In nfmpi_create: ')
+
+ ! define dimensions x and y
+ err = nfmpi_def_dim(ncid, "X", NX, dimid(1))
+ call check(err, 'In nfmpi_def_dim X: ')
+ err = nfmpi_def_dim(ncid, "Y", NY, dimid(2))
+ call check(err, 'In nfmpi_def_dim Y: ')
+
+ ! define a 2D variable of integer type
+ err = nfmpi_def_var(ncid, "var", NF_INT, NDIMS, dimid, varid)
+ call check(err, 'In nfmpi_def_var: ')
+
+ ! do not forget to exit define mode
+ err = nfmpi_enddef(ncid)
+ call check(err, 'In nfmpi_enddef: ')
+
+ ! now we are in data mode
+
+ ! pick arbitrary numbers of requests for 4 processes
+ num_reqs = 0
+ if (rank .EQ. 0) then
+ num_reqs = 3
+ elseif (rank .EQ. 1) then
+ num_reqs = 3
+ elseif (rank .EQ. 2) then
+ num_reqs = 3
+ elseif (rank .EQ. 3) then
+ num_reqs = 3
+ endif
+
+ ! assign arbitrary starts and counts
+ if (rank .EQ. 0) then
+ ! rank 0 is writing the followings: ("-" means skip)
+ ! - - - - - 0 0 - - -
+ ! - - - - - 0 0 - - -
+ ! - 0 0 - - - - 0 - -
+ ! - 0 0 - - - - 0 - -
+ ! Note this is in Fortran order
+ starts(1, 1) = 1
+ starts(2, 1) = 6
+ counts(1, 1) = 2
+ counts(2, 1) = 2
+ starts(1, 2) = 3
+ starts(2, 2) = 2
+ counts(1, 2) = 2
+ counts(2, 2) = 2
+ starts(1, 3) = 3
+ starts(2, 3) = 8
+ counts(1, 3) = 2
+ counts(2, 3) = 1
+ elseif (rank .EQ. 1) then
+ ! rank 1 is writing the followings: ("-" means skip)
+ ! - - 1 1 - - - - - -
+ ! - - 1 1 - - - - - -
+ ! 1 - - - - 1 1 - - -
+ ! 1 - - - - 1 1 - - -
+ ! Note this is in Fortran order
+ starts(1, 1) = 1
+ starts(2, 1) = 3
+ counts(1, 1) = 2
+ counts(2, 1) = 2
+ starts(1, 2) = 3
+ starts(2, 2) = 1
+ counts(1, 2) = 2
+ counts(2, 2) = 1
+ starts(1, 3) = 3
+ starts(2, 3) = 6
+ counts(1, 3) = 2
+ counts(2, 3) = 2
+ elseif (rank .EQ. 2) then
+ ! rank 2 is writing the followings: ("-" means skip)
+ ! 2 2 - - - - - 2 - -
+ ! 2 2 - - - - - 2 - -
+ ! - - - - 2 - - - - -
+ ! - - - - 2 - - - - -
+ ! Note this is in Fortran order
+ starts(1, 1) = 1
+ starts(2, 1) = 1
+ counts(1, 1) = 2
+ counts(2, 1) = 2
+ starts(1, 2) = 1
+ starts(2, 2) = 8
+ counts(1, 2) = 2
+ counts(2, 2) = 1
+ starts(1, 3) = 3
+ starts(2, 3) = 5
+ counts(1, 3) = 2
+ counts(2, 3) = 1
+ elseif (rank .EQ. 3) then
+ ! rank 3 is writing the followings: ("-" means skip)
+ ! - - - - 3 - - - 3 3
+ ! - - - - 3 - - - 3 3
+ ! - - - 3 - - - - 3 3
+ ! - - - 3 - - - - 3 3
+ ! Note this is in Fortran order
+ starts(1, 1) = 1
+ starts(2, 1) = 5
+ counts(1, 1) = 2
+ counts(2, 1) = 1
+ starts(1, 2) = 1
+ starts(2, 2) = 9
+ counts(1, 2) = 4
+ counts(2, 2) = 2
+ starts(1, 3) = 3
+ starts(2, 3) = 4
+ counts(1, 3) = 2
+ counts(2, 3) = 1
+ endif
+
+ ! w_len is total write length for this process
+ w_len = 0
+ do i=1, num_reqs
+ w_req_len = 1
+ do j=1, NDIMS
+ w_req_len = w_req_len * counts(j, i)
+ enddo
+ w_len = w_len + w_req_len
+ enddo
+
+ ! initialize buffer contents
+ do i=1, 13
+ buffer(i) = rank
+ enddo
+
+ err = nfmpi_put_varn_int_all(ncid, varid, num_reqs, starts,
+ + counts, buffer)
+ call check(err, 'In nfmpi_put_varn_int_all: ')
+
+ if (nprocs .GT. 4) call MPI_Barrier(MPI_COMM_WORLD, err)
+
+ ! read back and check the contents
+ do i=1, 13
+ buffer(i) = -1
+ enddo
+ err = nfmpi_get_varn_int_all(ncid, varid, num_reqs, starts,
+ + counts, buffer)
+ call check(err, 'In nfmpi_get_varn_int_all: ')
+
+ 997 format(A,I2,A,I2,A,I2)
+ do i=1, INT(w_len)
+ if (buffer(i) .NE. rank) then
+ print 997, "Error: expecting buffer(",i,")=",rank,
+ + " but got", buffer(i)
+ nerrs = nerrs + 1
+ endif
+ enddo
+
+ ! close the file
+ err = nfmpi_close(ncid)
+ call check(err, 'In nfmpi_close: ')
+
+ ! check if there is any PnetCDF internal malloc residue
+ 998 format(A,I13,A)
+ err = nfmpi_inq_malloc_size(malloc_size)
+ if (err .EQ. NF_NOERR) then
+ call MPI_Reduce(malloc_size, sum_size, 1, MPI_OFFSET,
+ + MPI_SUM, 0, MPI_COMM_WORLD, err)
+ if (rank .EQ. 0 .AND. sum_size .GT. 0)
+ + print 998,
+ + 'heap memory allocated by PnetCDF internally has ',
+ + sum_size/1048576, ' MiB yet to be freed'
+ endif
+
+ msg = '*** TESTING F77 '//cmd(1:XTRIM(cmd))//' for varn API '
+ if (rank .eq. 0) call pass_fail(nerrs, msg)
+
+ 999 call MPI_Finalize(ierr)
+ end ! program main
+
diff --git a/test/testcases/varn_real.f90 b/test/testcases/varn_real.f90
new file mode 100644
index 0000000..1222b6f
--- /dev/null
+++ b/test/testcases/varn_real.f90
@@ -0,0 +1,299 @@
+!
+! Copyright (C) 2012, Northwestern University and Argonne National Laboratory
+! See COPYRIGHT notice in top-level directory.
+!
+! $Id: varn_real.f90 2205 2015-11-28 20:41:50Z wkliao $
+
+!
+! This example shows how to use a single call of nf90mpi_put_varn_all()
+! to write a sequence of one-element requests with arbitrary array indices.
+!
+! The compile and run commands are given below, together with an ncmpidump of
+! the output file.
+!
+! % mpif90 -O2 -o varn_real varn_real.f90 -lpnetcdf
+! % mpiexec -n 4 ./varn_real /pvfs2/wkliao/testfile.nc
+! % ncmpidump /pvfs2/wkliao/testfile.nc
+! netcdf testfile {
+! // file format: CDF-5 (big variables)
+! dimensions:
+! Y = 4 ;
+! X = 10 ;
+! variables:
+! float var(Y, X) ;
+! data:
+!
+! var =
+! 3, 3, 3, 1, 1, 0, 0, 2, 1, 1,
+! 0, 2, 2, 2, 3, 1, 1, 2, 2, 2,
+! 1, 1, 2, 3, 3, 3, 0, 0, 1, 1,
+! 0, 0, 0, 2, 1, 1, 1, 3, 3, 3 ;
+! }
+!
+
+ subroutine check(err, message)
+ use mpi
+ use pnetcdf
+ implicit none
+ integer err
+ character(len=*) message
+ character(len=128) msg
+
+ ! It is a good idea to check returned value for possible error
+ if (err .NE. NF90_NOERR) then
+ write(6,*) message, trim(nf90mpi_strerror(err))
+ msg = '*** TESTING F90 varn_real.f90 for varn API '
+ call pass_fail(1, msg)
+ ! call MPI_Abort(MPI_COMM_WORLD, -1, err)
+ end if
+ end subroutine check
+
+ program main
+ use mpi
+ use pnetcdf
+ implicit none
+
+ integer NDIMS
+ PARAMETER(NDIMS=2)
+
+ character(LEN=256) filename, cmd, msg
+ integer rank, nprocs, err, ierr, num_reqs, get_args
+ integer ncid, cmode, varid, dimid(2), y, x, i, j, nerrs
+ integer, allocatable :: req_lens(:)
+ real, allocatable :: buffer(:), buffer2D(:,:)
+ real oneReal
+ integer(kind=MPI_OFFSET_KIND) NY, NX
+ integer(kind=MPI_OFFSET_KIND) w_len, w_req_len
+ integer(kind=MPI_OFFSET_KIND), allocatable :: starts(:,:)
+ integer(kind=MPI_OFFSET_KIND), allocatable :: counts(:,:)
+ integer(kind=MPI_OFFSET_KIND) malloc_size, sum_size
+
+ NY = 4
+ NX = 10
+
+ call MPI_Init(ierr)
+ call MPI_Comm_rank(MPI_COMM_WORLD, rank, ierr)
+ call MPI_Comm_size(MPI_COMM_WORLD, nprocs, ierr)
+
+ ! take filename from command-line argument if there is any
+ if (rank .EQ. 0) then
+ filename = "testfile.nc"
+ err = get_args(cmd, filename)
+ endif
+ call MPI_Bcast(err, 1, MPI_INTEGER, 0, MPI_COMM_WORLD, ierr)
+ if (err .EQ. 0) goto 999
+
+ call MPI_Bcast(filename, 256, MPI_CHARACTER, 0, MPI_COMM_WORLD, ierr)
+
+ nerrs = 0
+
+ if (.FALSE. .AND. nprocs .NE. 4 .AND. rank .EQ. 0) &
+ print*,'Warning: ',trim(cmd),' is intended to run on ', &
+ '4 processes'
+
+ ! create file, truncate it if exists
+ cmode = IOR(NF90_CLOBBER, NF90_64BIT_DATA)
+ err = nf90mpi_create(MPI_COMM_WORLD, filename, cmode, &
+ MPI_INFO_NULL, ncid)
+ call check(err, 'In nf90mpi_create: ')
+
+ ! create a global array of size NY * NX */
+ err = nf90mpi_def_dim(ncid, "Y", NY, dimid(2))
+ call check(err, 'In nf90mpi_def_dim Y: ')
+ err = nf90mpi_def_dim(ncid, "X", NX, dimid(1))
+ call check(err, 'In nf90mpi_def_dim X: ')
+ err = nf90mpi_def_var(ncid, "var", NF90_FLOAT, dimid, varid)
+ call check(err, 'In nf90mpi_def_var var: ')
+ err = nf90mpi_enddef(ncid)
+ call check(err, 'In nf90mpi_enddef: ')
+
+ ! pick arbitrary numbers of requests for 4 processes
+ num_reqs = 0
+ if (rank .EQ. 0) then
+ num_reqs = 8
+ elseif (rank .EQ. 1) then
+ num_reqs = 13
+ elseif (rank .EQ. 2) then
+ num_reqs = 9
+ elseif (rank .EQ. 3) then
+ num_reqs = 10
+ endif
+
+ ! Note that in Fortran, array indices start with 1
+ ALLOCATE(starts(NDIMS, num_reqs+1))
+ ALLOCATE(counts(NDIMS, num_reqs))
+
+ ! assign arbitrary starts
+ y=2
+ x=1
+ if (rank .EQ. 0) then
+ starts(y, 1) = 1; starts(x, 1) = 6
+ starts(y, 2) = 2; starts(x, 2) = 1
+ starts(y, 3) = 3; starts(x, 3) = 7
+ starts(y, 4) = 4; starts(x, 4) = 1
+ starts(y, 5) = 1; starts(x, 5) = 7
+ starts(y, 6) = 3; starts(x, 6) = 8
+ starts(y, 7) = 4; starts(x, 7) = 2
+ starts(y, 8) = 4; starts(x, 8) = 3
+ ! rank 0 is writing the following locations: ("-" means skip)
+ ! - - - - - 0 0 - - -
+ ! 0 - - - - - - - - -
+ ! - - - - - - 0 0 - -
+ ! 0 0 0 - - - - - - -
+ elseif (rank .EQ. 1) then
+ starts(y, 1) = 1; starts(x, 1) = 4
+ starts(y, 2) = 1; starts(x, 2) = 9
+ starts(y, 3) = 2; starts(x, 3) = 6
+ starts(y, 4) = 3; starts(x, 4) = 1
+ starts(y, 5) = 3; starts(x, 5) = 9
+ starts(y, 6) = 4; starts(x, 6) = 5
+ starts(y, 7) = 1; starts(x, 7) = 5
+ starts(y, 8) = 1; starts(x, 8) = 10
+ starts(y, 9) = 2; starts(x, 9) = 7
+ starts(y, 10) = 3; starts(x, 10) = 2
+ starts(y, 11) = 3; starts(x, 11) = 10
+ starts(y, 12) = 4; starts(x, 12) = 6
+ starts(y, 13) = 4; starts(x, 13) = 7
+ ! rank 1 is writing the following locations: ("-" means skip)
+ ! - - - 1 1 - - - 1 1
+ ! - - - - - 1 1 - - -
+ ! 1 1 - - - - - - 1 1
+ ! - - - - 1 1 1 - - -
+ elseif (rank .EQ. 2) then
+ starts(y, 1) = 1; starts(x, 1) = 8
+ starts(y, 2) = 2; starts(x, 2) = 2
+ starts(y, 3) = 2; starts(x, 3) = 8
+ starts(y, 4) = 3; starts(x, 4) = 3
+ starts(y, 5) = 4; starts(x, 5) = 4
+ starts(y, 6) = 2; starts(x, 6) = 3
+ starts(y, 7) = 2; starts(x, 7) = 9
+ starts(y, 8) = 2; starts(x, 8) = 4
+ starts(y, 9) = 2; starts(x, 9) = 10
+ ! rank 2 is writing the following locations: ("-" means skip)
+ ! - - - - - - - 2 - -
+ ! - 2 2 2 - - - 2 2 2
+ ! - - 2 - - - - - - -
+ ! - - - 2 - - - - - -
+ elseif (rank .EQ. 3) then
+ starts(y, 1) = 1; starts(x, 1) = 1
+ starts(y, 2) = 2; starts(x, 2) = 5
+ starts(y, 3) = 3; starts(x, 3) = 4
+ starts(y, 4) = 4; starts(x, 4) = 8
+ starts(y, 5) = 1; starts(x, 5) = 2
+ starts(y, 6) = 3; starts(x, 6) = 5
+ starts(y, 7) = 4; starts(x, 7) = 9
+ starts(y, 8) = 1; starts(x, 8) = 3
+ starts(y, 9) = 3; starts(x, 9) = 6
+ starts(y, 10) = 4; starts(x, 10) = 10
+ ! rank 3 is writing the following locations: ("-" means skip)
+ ! 3 3 3 - - - - - - -
+ ! - - - - 3 - - - - -
+ ! - - - 3 3 3 - - - -
+ ! - - - - - - - 3 3 3
+ endif
+ counts = 1
+
+ ALLOCATE(req_lens(num_reqs))
+
+ ! allocate I/O buffer and initialize its contents
+ w_len = 0
+ do i=1, num_reqs
+ w_req_len = 1
+ do j=1, NDIMS
+ w_req_len = w_req_len * counts(j, i)
+ enddo
+ req_lens(i) = INT(w_req_len)
+ w_len = w_len + w_req_len
+ enddo
+ ALLOCATE(buffer(w_len))
+ ALLOCATE(buffer2D(3, w_len/3+1))
+ ! Note on 2D buffer, put_varn will fill in the first w_len
+ ! elements in buffer2D, no matter the shape of buffer2D is
+
+ buffer = rank
+ buffer2D = rank
+
+ ! varn write a 2D buffer in memory to a 2D array in file
+ err = nf90mpi_put_varn_all(ncid, varid, buffer2D, num_reqs, &
+ starts, counts)
+ call check(err, 'In nf90mpi_put_varn_all: ')
+
+ ! varn write a 1D buffer in memory to a 2D array in file
+ err = nf90mpi_put_varn_all(ncid, varid, buffer, num_reqs, &
+ starts, counts)
+ call check(err, 'In nf90mpi_put_varn_all: ')
+
+ if (nprocs .GT. 4) call MPI_Barrier(MPI_COMM_WORLD, err)
+
+ ! read a scalar back and check the content
+ oneReal = -1.0 ! a scalar
+ if (rank .GE. 4) starts = 1_MPI_OFFSET_KIND
+ err = nf90mpi_get_varn_all(ncid, varid, oneReal, starts)
+ call check(err, ' 22 In nf90mpi_get_varn_all: ')
+
+ 995 format(A,I2,A,F4.1)
+ if (rank .LT. 4 .AND. oneReal .NE. rank) then
+ print 995, "Error: expecting OneReal=",rank, &
+ " but got", oneReal
+ nerrs = nerrs + 1
+ endif
+
+ ! varn read a 2D array in file to a 2D buffer in memory
+ buffer2D = -1.0;
+ err = nf90mpi_get_varn_all(ncid, varid, buffer2D, num_reqs, &
+ starts, counts)
+ call check(err, 'In nf90mpi_get_varn_all: ')
+
+ 996 format(A,I2,A,I2,A,I2,A,F4.1)
+ do i=1, INT(w_len/3)
+ do j=1, 3
+ if (buffer2D(j,i) .NE. rank) then
+ print 996, "Error: expecting buffer2D(",j,",",i,")=", &
+ rank, " but got", buffer2D(j,i)
+ nerrs = nerrs + 1
+ endif
+ enddo
+ enddo
+
+ ! varn read a 2D array in file to a 1D buffer in memory
+ buffer = -1.0;
+ err = nf90mpi_get_varn_all(ncid, varid, buffer, num_reqs, &
+ starts, counts)
+ call check(err, 'In nf90mpi_get_varn_all: ')
+
+ 997 format(A,I2,A,I2,A,F4.1)
+ do i=1, INT(w_len)
+ if (buffer(i) .NE. rank) then
+ print 997, "Error: expecting buffer(",i,")=",rank, &
+ " but got", buffer(i)
+ nerrs = nerrs + 1
+ endif
+ enddo
+
+ err = nf90mpi_close(ncid);
+ call check(err, 'In nf90mpi_close: ')
+
+ DEALLOCATE(req_lens);
+ DEALLOCATE(buffer);
+ DEALLOCATE(buffer2D);
+ DEALLOCATE(starts);
+ DEALLOCATE(counts);
+
+ ! check if there is any PnetCDF internal malloc residue
+ 998 format(A,I13,A)
+ err = nf90mpi_inq_malloc_size(malloc_size)
+ if (err == NF90_NOERR) then
+ call MPI_Reduce(malloc_size, sum_size, 1, MPI_OFFSET, &
+ MPI_SUM, 0, MPI_COMM_WORLD, ierr)
+ if (rank .EQ. 0 .AND. sum_size .GT. 0_MPI_OFFSET_KIND) print 998, &
+ 'heap memory allocated by PnetCDF internally has ', &
+ sum_size/1048576, ' MiB yet to be freed'
+ endif
+
+ msg = '*** TESTING F90 '//trim(cmd)//' for varn API '
+ if (rank .eq. 0) call pass_fail(nerrs, msg)
+
+ 999 call MPI_Finalize(ierr)
+
+ end program
+
diff --git a/test/testcases/vectors.c b/test/testcases/vectors.c
new file mode 100644
index 0000000..69b68e0
--- /dev/null
+++ b/test/testcases/vectors.c
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2003, Northwestern University and Argonne National Laboratory
+ * See COPYRIGHT notice in top-level directory.
+ *
+ * $Id: vectors.c 2133 2015-09-26 19:16:01Z wkliao $
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <mpi.h>
+#include <pnetcdf.h>
+
+#include <testutils.h>
+
+#define HANDLE_ERR(err) { if (err!=NC_NOERR) {nerrs++; fprintf(stderr, "Error at line %d: %s\n",__LINE__,ncmpi_strerror(err));}}
+
+#define VECCOUNT 4
+#define BLOCKLEN 3
+#define STRIDE 5
+int main(int argc, char ** argv)
+{
+ int ncid, dimid, varid, rank, nprocs, verbose;
+ MPI_Datatype vtype, rtype, usertype;
+ MPI_Aint lb, extent;
+ int userbufsz, *userbuf, *cmpbuf, i, err, errs=0, nerrs=0;
+ int count = 25;
+ double pi = 3.14159;
+ MPI_Offset start, acount;
+ char *filename="testfile.nc";
+
+ MPI_Init(&argc, &argv);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
+
+ if (argc > 2) {
+ if (!rank) printf("Usage: %s [filename]\n",argv[0]);
+ MPI_Finalize();
+ return 0;
+ }
+ if (argc == 2) filename = argv[1];
+
+ if (rank == 0) {
+ char cmd_str[256];
+ sprintf(cmd_str, "*** TESTING C %s for put_vara/get_vara ", argv[0]);
+ printf("%-66s ------ ", cmd_str); fflush(stdout);
+ }
+
+ verbose = 0;
+ if (nprocs > 2 && rank == 0 && verbose)
+ printf("Warning: %s is designed to run on 1 process\n",argv[0]);
+
+ err = ncmpi_create(MPI_COMM_WORLD, filename, NC_CLOBBER, MPI_INFO_NULL, &ncid);
+ HANDLE_ERR(err)
+ err = ncmpi_def_dim(ncid, "50k", 1024*50, &dimid);
+ HANDLE_ERR(err)
+ err = ncmpi_def_var(ncid, "vector", NC_DOUBLE, 1, &dimid, &varid);
+ HANDLE_ERR(err)
+
+ err = ncmpi_enddef(ncid);
+ HANDLE_ERR(err)
+
+ MPI_Type_vector(VECCOUNT, BLOCKLEN, STRIDE, MPI_INT, &vtype);
+ MPI_Type_create_resized(vtype, 0, STRIDE*VECCOUNT*sizeof(int), &rtype);
+ MPI_Type_contiguous(count, rtype, &usertype);
+ MPI_Type_commit(&usertype);
+
+ MPI_Type_free(&vtype);
+ MPI_Type_free(&rtype);
+
+ MPI_Type_get_extent(usertype, &lb, &extent);
+ userbufsz = extent;
+ userbuf = (int*) malloc(userbufsz);
+ cmpbuf = (int*) calloc(userbufsz, 1);
+ for (i=0; i< userbufsz/sizeof(int); i++)
+ userbuf[i] = pi*i;
+
+ start = 10; acount = count*12;
+ err = ncmpi_begin_indep_data(ncid);
+ HANDLE_ERR(err)
+ if (rank == 0) {
+ err = ncmpi_put_vara(ncid, varid, &start, &acount, userbuf, 1, usertype);
+ HANDLE_ERR(err)
+ }
+
+ err = ncmpi_close(ncid);
+ HANDLE_ERR(err)
+
+ err = ncmpi_open(MPI_COMM_WORLD, filename, NC_NOWRITE, MPI_INFO_NULL, &ncid);
+ HANDLE_ERR(err)
+ err = ncmpi_begin_indep_data(ncid);
+ HANDLE_ERR(err)
+ err = ncmpi_inq_varid(ncid, "vector", &varid);
+ HANDLE_ERR(err)
+ err = ncmpi_get_vara(ncid, varid, &start, &acount, cmpbuf, 1, usertype);
+ HANDLE_ERR(err)
+ err = ncmpi_close(ncid);
+ HANDLE_ERR(err)
+
+ for (i=0; errs < 10 && i < acount; i++) {
+ /* vector of 4,3,5, so skip 4th and 5th items of every block */
+ if (i%STRIDE >= BLOCKLEN) continue;
+ if (userbuf[i] != cmpbuf[i]) {
+ errs++;
+ fprintf(stderr, "%d: expected 0x%x got 0x%x\n",
+ i, userbuf[i], cmpbuf[i]);
+ }
+ }
+ nerrs += errs;
+ free(userbuf);
+ free(cmpbuf);
+ MPI_Type_free(&usertype);
+
+ /* check if PnetCDF freed all internal malloc */
+ MPI_Offset malloc_size, sum_size;
+ err = ncmpi_inq_malloc_size(&malloc_size);
+ if (err == NC_NOERR) {
+ MPI_Reduce(&malloc_size, &sum_size, 1, MPI_OFFSET, MPI_SUM, 0, MPI_COMM_WORLD);
+ if (rank == 0 && sum_size > 0)
+ printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n",
+ sum_size);
+ }
+
+ MPI_Allreduce(MPI_IN_PLACE, &nerrs, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
+ if (rank == 0) {
+ if (nerrs) printf(FAIL_STR,nerrs);
+ else printf(PASS_STR);
+ }
+
+ MPI_Finalize();
+
+ return 0;
+}
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/pnetcdf.git
More information about the debian-science-commits
mailing list