Skip to content

Commit 9246465

Browse files
committed
Remove dev_status.md, as all APIs are considered implemented
1 parent 9a17292 commit 9246465

File tree

6 files changed

+172
-11
lines changed

6 files changed

+172
-11
lines changed

README.md

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -41,15 +41,14 @@ applications that require parallel access to netCDF files.
4141
files created by the programs The default is the current folder.
4242

4343
### Additional Resources
44-
* [PnetCDF-python User Guide](https://pnetcdf-python.readthedocs.io/en/latest/)
45-
* [Data objects in PnetCDF python programming](docs/pnetcdf_objects.md)
46-
* [Comparison between NetCDF4-python and PnetCDF-python](docs/nc4_vs_pnetcdf.md)
47-
* This project is under active development. The current status of API
48-
implementation can be found in [dev_status.md](docs/dev_status.md).
49-
* [PnetCDF](https://parallel-netcdf.github.io/)
44+
* PnetCDF-python [User Guide](https://pnetcdf-python.readthedocs.io/en/latest/)
45+
* [Data objects](docs/pnetcdf_objects.md) in PnetCDF python programming
46+
* [Comparison](docs/nc4_vs_pnetcdf.md) of NetCDF4-python and PnetCDF-python
47+
* [PnetCDF project home page](https://parallel-netcdf.github.io/)
48+
* [PnetCDF repository of C/Fortran library](https://parallel-netcdf.github.io/)
5049

5150
### Acknowledgements
5251
Ongoing development and maintenance of PnetCDF-python is supported by the U.S.
5352
Department of Energy's Office of Science, Scientific Discovery through Advanced
54-
Computing (SciDAC) program, OASIS Institute.
53+
Computing (SciDAC) program, RAPIDS/OASIS Institute.
5554

docs/nc4_vs_pnetcdf.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,9 @@
8989
`put/get` requests and each of them has a small amount. PnetCDF tries to
9090
aggregate and coalesce multiple registered nonblocking requests into a large
9191
one, because I/O usually performs better when the request amounts are large
92-
and contiguous. See an example program in
93-
[nonblocking_write.py](../examples/nonblocking/nonblocking_write.py).
92+
and contiguous. See example programs
93+
[nonblocking_write.py](../examples/nonblocking/nonblocking_write.py) and
94+
[nonblocking_read.py](../examples/nonblocking/nonblocking_read.py).
9495
* Table below shows the difference in python programming between using blocking
9596
and nonblocking APIs.
9697

examples/README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@ instructions can be found at the beginning of each file.
3636
instead. It creates a netcdf file in CDF-5 format and writes a number of
3737
3D integer non-record variables.
3838

39+
* [nonblocking_read.py](./nonblocking/nonblocking_read.py]) --
40+
A counterpart of `nonblocking_write.py` but does reads. It reads the
41+
output file generated from `nonblocking_write.py`.
42+
3943
* [nonblocking_write_def.py](./nonblocking/nonblocking_write_def.py]) --
4044
This example is the same as `nonblocking_write.py` expect all nonblocking
4145
write requests (calls to `iput` and `bput`) are posted in define mode. It

examples/nonblocking/Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44
#
55

66
check_PROGRAMS = nonblocking_write_def.py \
7-
nonblocking_write.py
7+
nonblocking_write.py \
8+
nonblocking_read.py
89

910

1011
TESTS_ENVIRONMENT = export check_PROGRAMS="${check_PROGRAMS}";
Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
#
2+
# Copyright (C) 2024, Northwestern University and Argonne National Laboratory
3+
# See COPYRIGHT notice in top-level directory.
4+
#
5+
6+
"""
7+
This example is the counterpart of nonblocking_write.py, but does reading
8+
instead. It opens the output file created by nonblocking_write.py, a netcdf
9+
file in CDF-5 format, and reads a number of 3D integer non-record variables.
10+
11+
To run:
12+
mpiexec -n num_processes nonblocking_read.py [filename]
13+
14+
All variables are partitioned among all processes in a 3D block-block-block
15+
fashion.
16+
"""
17+
18+
import sys, os, argparse
19+
import numpy as np
20+
from mpi4py import MPI
21+
import pnetcdf
22+
23+
def pnetcdf_io(filename):
24+
# Open the file for reading
25+
f = pnetcdf.File(filename = filename,
26+
mode = 'r',
27+
comm = comm,
28+
info = None)
29+
30+
# obtain the number of variables defined in the input file
31+
nvars = len(f.variables)
32+
if verbose and rank == 0:
33+
print("number of variables =", nvars)
34+
35+
buf = []
36+
reqs = []
37+
38+
for key, value in f.variables.items():
39+
40+
var = value
41+
42+
# print names of all variables
43+
if verbose and rank == 0:
44+
print("variable: ",key," ndim=",var.ndim)
45+
46+
# obtain the number of dimensions of variable
47+
ndim = var.ndim
48+
49+
# obtain sizes of dimensions
50+
dims = var.get_dims()
51+
if verbose and rank == 0:
52+
for i in range(ndim):
53+
print("variable ",key," dim[",i,"] name=",dims[i].name," size=",dims[i].size)
54+
55+
# set up subarray access pattern
56+
start = np.zeros(ndim, dtype=np.int32)
57+
count = np.zeros(ndim, dtype=np.int32)
58+
gsizes = np.zeros(ndim, dtype=np.int32)
59+
60+
psizes = MPI.Compute_dims(nprocs, ndim)
61+
start[0] = rank % psizes[0]
62+
start[1] = (rank // psizes[1]) % psizes[1]
63+
start[2] = (rank // (psizes[0] * psizes[1])) % psizes[2]
64+
65+
# calculate sizes of local read buffers
66+
bufsize = 1
67+
for i in range(ndim):
68+
gsizes[i] = dims[i].size
69+
start[i] *= dims[i].size // psizes[i]
70+
count[i] = dims[i].size // psizes[i]
71+
bufsize *= count[i]
72+
73+
if verbose:
74+
print("rank ",rank," gsizes=",gsizes," start=",start," count=",count," bufsize=",bufsize)
75+
76+
# Allocate read buffer and initialize with all -1
77+
rbuf = np.empty(bufsize, dtype=np.int32)
78+
rbuf.fill(-1)
79+
buf.append(rbuf)
80+
81+
# Read one variable at a time, using iput APIs
82+
req_id = var.iget_var(rbuf, start = start, count = count)
83+
reqs.append(req_id)
84+
85+
# commit posted nonblocking requests
86+
errs = [None] * nvars
87+
f.wait_all(nvars, reqs, errs)
88+
89+
# check errors
90+
for i in range(nvars):
91+
if pnetcdf.strerrno(errs[i]) != "NC_NOERR":
92+
print(f"Error on request {i}:", pnetcdf.strerror(errs[i]))
93+
94+
# verify contents of read buffers
95+
for i in range(nvars):
96+
for j in range(len(buf[i])):
97+
expect = rank * i + 123 + j
98+
if buf[i][j] != expect:
99+
print("Error: buf[",i,"][",j,"] expect ",expect," but got ",buf[i][j])
100+
break
101+
102+
# Close the file
103+
f.close()
104+
105+
106+
def parse_help():
107+
help_flag = "-h" in sys.argv or "--help" in sys.argv
108+
if help_flag and rank == 0:
109+
help_text = (
110+
"Usage: {} [-h | -q] [file_name]\n"
111+
" [-h] Print help\n"
112+
" [-q] Quiet mode (reports when fail)\n"
113+
" [filename] (Optional) input netCDF file name\n"
114+
).format(sys.argv[0])
115+
print(help_text)
116+
return help_flag
117+
118+
119+
if __name__ == "__main__":
120+
comm = MPI.COMM_WORLD
121+
rank = comm.Get_rank()
122+
nprocs = comm.Get_size()
123+
124+
if parse_help():
125+
MPI.Finalize()
126+
sys.exit(1)
127+
128+
# get command-line arguments
129+
args = None
130+
parser = argparse.ArgumentParser()
131+
parser.add_argument("dir", nargs="?", type=str, help="(Optional) input netCDF file name",\
132+
default = "testfile.nc")
133+
parser.add_argument("-q", help="Quiet mode (reports when fail)", action="store_true")
134+
args = parser.parse_args()
135+
136+
verbose = False if args.q else True
137+
138+
filename = args.dir
139+
140+
if verbose and rank == 0:
141+
print("{}: example of calling nonblocking read APIs".format(os.path.basename(__file__)))
142+
143+
try:
144+
pnetcdf_io(filename)
145+
except BaseException as err:
146+
print("Error: type:", type(err), str(err))
147+
raise
148+
149+
MPI.Finalize()
150+

examples/nonblocking/parallel_run.sh

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,13 @@ for prog in $check_PROGRAMS; do
6060

6161
printf '%-60s' "Testing $prog"
6262

63-
CMD="mpiexec -n $NPROC python $prog -q $OUT_DIR/${prog%.*}.nc"
63+
if test "x$prog" = "xnonblocking_read.py" ; then
64+
CMD="mpiexec -n $NPROC python $prog -q $OUT_DIR/nonblocking_write.nc"
65+
else
66+
CMD="mpiexec -n $NPROC python $prog -q $OUT_DIR/${prog%.*}.nc"
67+
fi
68+
# echo "$CMD"
69+
6470
$CMD
6571
status=$?
6672
if [ $status -ne 0 ]; then

0 commit comments

Comments
 (0)