Skip to content

Commit cac00ff

Browse files
committed
make varn APIs separated from var APIs
1. the optional arguments of varn APIs are different from var 2. the dimensionality of starts, and counts are also different
1 parent 2977773 commit cac00ff

File tree

8 files changed

+713
-425
lines changed

8 files changed

+713
-425
lines changed

examples/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,8 @@ be found at the beginning of each file.
9393

9494
* [put_varn_int.py](./put_varn_int.py)
9595
+ This example shows how to use a single call of `Variable` method
96-
`put_var()` to to write a sequence of requests with arbitrary array indices
97-
and lengths.
96+
`put_varn()` to write a sequence of subarray requests to a variable with
97+
arbitrary array indices and lengths.
9898

9999
* [transpose.py](./transpose.py)
100100
+ This example shows how to use `Variable` method `put_var()` to write six 3D

examples/put_varn_int.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
#
55

66
"""
7-
This example shows how to use a single call of `Variable` method `put_var()` to
8-
to write a sequence of requests with arbitrary array indices and lengths.
7+
This example shows how to use a single call of `Variable` method `put_varn()`
8+
to to write a sequence of requests with arbitrary array indices and lengths.
99
1010
To run:
1111
% mpiexec -n num_process python3 put_varn_int.py [test_file_name]
@@ -153,7 +153,7 @@ def pnetcdf_io(file_name, file_format):
153153
w_buf = np.full(w_len, rank, dtype=np.int32)
154154

155155
# set the buffer pointers to different offsets to the I/O buffe
156-
v.put_var_all(w_buf, start = starts, count = counts, num = num_reqs)
156+
v.put_varn_all(w_buf, num = num_reqs, starts = starts, counts = counts)
157157

158158
# close the file
159159
f.close()
@@ -187,7 +187,7 @@ def pnetcdf_io(file_name, file_format):
187187
filename = args.dir
188188

189189
if verbose and rank == 0:
190-
print("{}: example of writing multiple variables in a call".format(os.path.basename(__file__)))
190+
print("{}: example of writing multiple subarrays of a variable in a call".format(os.path.basename(__file__)))
191191

192192
try:
193193
pnetcdf_io(filename, file_format)

src/pnetcdf/_Variable.pyx

Lines changed: 604 additions & 348 deletions
Large diffs are not rendered by default.

test/tst_var_bput_varn.py

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,14 @@
44
#
55

66
"""
7-
This example program is intended to illustrate the use of the pnetCDF python
8-
API. The program runs in non-blocking mode and makes a request to write a list
9-
of subarray of values to a variable into a netCDF variable of an opened netCDF
10-
file using bput_var method of `Variable` class. This method is a buffered
11-
version of bput_var and requires the user to attach an internal buffer of size
12-
equal to the sum of all requests using attach_buff method of `File` class. The
13-
library will internally invoke ncmpi_bput_vara and ncmpi_attach_buffer in C.
7+
This program test ibput_varn() method of `Variable` class, a nonblocking,
8+
buffered API, by making multiple calls to it to write to different NetCDF
9+
variables of an opened netCDF file. Each call also writes to multiple
10+
subarrays of the same variable. This method is a buffered version of
11+
iput_varn() and requires the user to first attach an internal buffer of size
12+
equal to the sum of all requests using attach_buff() method of `File` class.
13+
The library will internally invoke ncmpi_bput_varn() and ncmpi_attach_buffer()
14+
in C.
1415
"""
1516

1617
import numpy as np
@@ -165,8 +166,8 @@ def run_test(format):
165166
for i in range(num_reqs):
166167
v = f.variables[f'data{i}']
167168
assert(f.inq_buff_size() - f.inq_buff_usage() > 0)
168-
# post the request to write an array of values
169-
req_id = v.bput_var(data, start = starts, count = counts, num = num_subarrays)
169+
# post the request to write multiple subarrays
170+
req_id = v.bput_varn(data, num_subarrays, starts, counts)
170171
# track the request ID for each write request
171172
req_ids.append(req_id)
172173

@@ -182,7 +183,7 @@ def run_test(format):
182183
# post requests to write the 2nd half of variables w/o tracking req ids
183184
for i in range(num_reqs):
184185
v = f.variables[f'data{num_reqs + i}']
185-
v.bput_var(data, start = starts, count = counts, num = num_subarrays)
186+
v.bput_varn(data, num_subarrays, starts, counts)
186187

187188
# commit the posted requests all at once using wait_all (collective i/o)
188189
f.wait_all(num = pnetcdf.NC_PUT_REQ_ALL)
@@ -218,3 +219,4 @@ def run_test(format):
218219
except BaseException as err:
219220
print("Error: type:", type(err), str(err))
220221
raise
222+

test/tst_var_get_varn.py

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,17 @@
44
#
55

66
import pnetcdf
7-
from numpy.random import seed, randint
8-
from numpy.testing import assert_array_equal, assert_equal, assert_array_almost_equal
9-
import tempfile, unittest, os, random, sys
7+
from numpy.testing import assert_array_equal
8+
import unittest, os, sys
109
import numpy as np
1110
from mpi4py import MPI
1211
from utils import validate_nc_file
1312
import io
1413
import argparse
1514

16-
1715
file_formats = ['NC_64BIT_DATA', 'NC_64BIT_OFFSET', None]
1816
file_name = "tst_var_get_varn.nc"
1917

20-
2118
comm = MPI.COMM_WORLD
2219
rank = comm.Get_rank()
2320
size = comm.Get_size()
@@ -85,7 +82,8 @@
8582
# - - - - - - - 3 3 3
8683
else:
8784
num_reqs = 0
88-
#Obtain the size of returned array, needed for generating reference array
85+
86+
# Obtain the size of returned array, needed for generating reference array
8987
buf_len = np.sum(np.prod(counts, axis=1))
9088

9189
class VariablesTestCase(unittest.TestCase):
@@ -96,7 +94,9 @@ def setUp(self):
9694
else:
9795
self.file_path = file_name
9896
self._file_format = file_formats.pop(0)
99-
f = pnetcdf.File(filename=self.file_path, mode = 'w', format=self._file_format, comm=comm, info=None)
97+
f = pnetcdf.File(filename=self.file_path, mode = 'w',
98+
format=self._file_format, comm=comm, info=None)
99+
100100
# define dimensions and variables
101101
f.def_dim('x',xdim)
102102
f.def_dim('y',ydim)
@@ -107,8 +107,8 @@ def setUp(self):
107107
var1[:] = data
108108

109109
comm.Barrier()
110-
assert validate_nc_file(os.environ.get('PNETCDF_DIR'), self.file_path) == 0 if os.environ.get('PNETCDF_DIR') is not None else True
111-
110+
if os.environ.get('PNETCDF_DIR') is not None:
111+
assert validate_nc_file(os.environ.get('PNETCDF_DIR'), self.file_path) == 0
112112

113113
def tearDown(self):
114114
# Remove the temporary files
@@ -120,16 +120,19 @@ def runTest(self):
120120
"""testing variable get varn for CDF-5/CDF-2/CDF-1 file"""
121121
dataref = np.full((buf_len,), rank, np.float32)
122122
f = pnetcdf.File(self.file_path, 'r')
123-
# test collective i/o get_var
123+
124+
# test collective i/o get_varn
124125
v1 = f.variables['var1']
125126
buff = np.empty((buf_len,), v1.dtype)
126-
v1.get_var_all(buff, start = starts, count = counts, num = num_reqs)
127+
v1.get_varn_all(buff, num_reqs, starts, counts)
127128
assert_array_equal(buff, dataref)
128-
# test independent i/o get_var
129+
130+
# test independent i/o get_varn
129131
f.begin_indep()
130132
buff = np.empty((buf_len,), v1.dtype)
131-
v1.get_var(buff, start = starts, count = counts, num = num_reqs)
133+
v1.get_varn(buff, num_reqs, starts, counts)
132134
assert_array_equal(buff, dataref)
135+
133136
f.close()
134137

135138
if __name__ == '__main__':
@@ -143,3 +146,4 @@ def runTest(self):
143146
if not result.wasSuccessful():
144147
print(output.getvalue())
145148
sys.exit(1)
149+

test/tst_var_iget_varn.py

Lines changed: 34 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,15 @@
44
#
55

66
"""
7-
This example program is intended to illustrate the use of the pnetCDF python API.
8-
The program runs in non-blocking mode and makes a request to read a list of subarray of
9-
a netCDF variable of an opened netCDF file using iget_var method of `Variable` class. The
10-
library will internally invoke ncmpi_iget_varn in C.
7+
This program tests iget_varn() method of `Variable` class, by making a
8+
nonblocking request to read a list of subarrays of a netCDF variable of an
9+
opened netCDF file. The library will internally invoke ncmpi_iget_varn() in C.
1110
"""
11+
1212
import pnetcdf
13-
from numpy.random import seed, randint
14-
from numpy.testing import assert_array_equal, assert_equal, assert_array_almost_equal
15-
import tempfile, unittest, os, random, sys
13+
from numpy.random import seed
14+
from numpy.testing import assert_array_equal
15+
import unittest, os, random, sys
1616
import numpy as np
1717
from mpi4py import MPI
1818
from pnetcdf import strerror, strerrno
@@ -90,14 +90,16 @@
9090
# - - - - - - - 3 3 3
9191
else:
9292
num_subarray_reqs = 0
93+
9394
# obtain the buffer size of returned array
9495
buf_len = 0
9596
for i in range(num_subarray_reqs):
9697
w_req_len = np.prod(counts[i,:])
9798
buf_len += w_req_len
99+
98100
# generate reference array for comparing at the testing phase
99101
dataref = np.full((buf_len,), rank, np.float32)
100-
# total number of iget_var requests for this test program
102+
# total number of subarray requests for this test program
101103
num_reqs = 10
102104
# initialize a list to store references of variable values
103105
v_datas = []
@@ -110,58 +112,71 @@ def setUp(self):
110112
else:
111113
self.file_path = file_name
112114
self._file_format = file_formats.pop(0)
113-
f = pnetcdf.File(filename=self.file_path, mode = 'w', format=self._file_format, comm=comm, info=None)
115+
116+
f = pnetcdf.File(filename=self.file_path, mode = 'w',
117+
format=self._file_format, comm=comm, info=None)
118+
114119
dx = f.def_dim('x',xdim)
115120
dy = f.def_dim('y',ydim)
116121

117122
# define 20 netCDF variables
118123
for i in range(num_reqs * 2):
119124
v = f.def_var(f'data{i}', pnetcdf.NC_FLOAT, (dx, dy))
120-
# initialize variable values
125+
121126
f.enddef()
127+
128+
# initialize and write variable values
122129
for i in range(num_reqs * 2):
123130
v = f.variables[f'data{i}']
124131
v[:] = data
125-
f.close()
126-
assert validate_nc_file(os.environ.get('PNETCDF_DIR'), self.file_path) == 0 if os.environ.get('PNETCDF_DIR') is not None else True
127132

133+
f.close()
134+
if os.environ.get('PNETCDF_DIR') is not None:
135+
assert validate_nc_file(os.environ.get('PNETCDF_DIR'), self.file_path) == 0
128136

129137

130138
f = pnetcdf.File(self.file_path, 'r')
139+
131140
# each process post 10 requests to read a list of subarrays from the variable
132141
req_ids = []
133142
v_datas.clear()
143+
134144
for i in range(num_reqs):
135145
v = f.variables[f'data{i}']
136146
buff = np.empty(shape = buf_len, dtype = v.datatype)
137147
# post the request to read multiple slices (subarrays) of the variable
138-
req_id = v.iget_var(buff, start = starts, count = counts, num = num_subarray_reqs)
148+
req_id = v.iget_varn(buff, num_subarray_reqs, starts, counts)
139149
# track the reqeust ID for each read reqeust
140150
req_ids.append(req_id)
141151
# store the reference of variable values
142152
v_datas.append(buff)
143-
f.end_indep()
153+
144154
# commit those 10 requests to the file at once using wait_all (collective i/o)
145155
req_errs = [None] * num_reqs
146156
f.wait_all(num_reqs, req_ids, req_errs)
157+
147158
# check request error msg for each unsuccessful requests
148159
for i in range(num_reqs):
149160
if strerrno(req_errs[i]) != "NC_NOERR":
150161
print(f"Error on request {i}:", strerror(req_errs[i]))
151162

152-
# post 10 requests to read an array of values for the last 10 variables w/o tracking req ids
163+
# post 10 requests to read an array of values for the last 10
164+
# variables w/o tracking req ids
153165
for i in range(num_reqs, num_reqs * 2):
154166
v = f.variables[f'data{i}']
155167
buff = np.empty(buf_len, dtype = v.datatype)
156168
# post the request to read a list of subarrays from the variable
157-
v.iget_var(buff, start = starts, count = counts, num = num_subarray_reqs)
169+
v.iget_varn(buff, num_subarray_reqs, starts, counts)
158170
# store the reference of variable values
159171
v_datas.append(buff)
160172

161-
# commit all pending get requests to the file at once using wait_all (collective i/o)
173+
# commit all pending get requests to the file at once using wait_all
174+
# (collective i/o)
162175
req_errs = f.wait_all(num = pnetcdf.NC_GET_REQ_ALL)
176+
163177
f.close()
164-
assert validate_nc_file(os.environ.get('PNETCDF_DIR'), self.file_path) == 0 if os.environ.get('PNETCDF_DIR') is not None else True
178+
if os.environ.get('PNETCDF_DIR') is not None:
179+
assert validate_nc_file(os.environ.get('PNETCDF_DIR'), self.file_path) == 0
165180

166181

167182
def tearDown(self):
@@ -188,3 +203,4 @@ def runTest(self):
188203
if not result.wasSuccessful():
189204
print(output.getvalue())
190205
sys.exit(1)
206+

test/tst_var_iput_varn.py

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,19 @@
44
#
55

66
"""
7-
This example program is intended to illustrate the use of the pnetCDF python API. The program
8-
runs in non-blocking mode and makes a request to write a list of subarray of values to a variable
9-
into a netCDF variable of an opened netCDF file using iput_var method of `Variable` class. The
10-
library will internally invoke ncmpi_iput_varn in C.
7+
This program tests nonblocking method, iput_varn() of `Variable` class, by
8+
making a write request consisting of multiple subarrays to a variable of an
9+
opened netCDF file. The library will internally invoke ncmpi_iput_varn() in C.
1110
"""
1211
import pnetcdf
13-
from numpy.random import seed, randint
14-
from numpy.testing import assert_array_equal, assert_equal, assert_array_almost_equal
15-
import tempfile, unittest, os, random, sys
12+
from numpy.testing import assert_array_equal
13+
import unittest, os, sys
1614
import numpy as np
1715
from mpi4py import MPI
1816
from pnetcdf import strerror, strerrno
1917
from utils import validate_nc_file
2018
import io
2119

22-
seed(0)
2320
file_formats = ['NC_64BIT_DATA', 'NC_64BIT_OFFSET', None]
2421
file_name = "tst_var_iput_varn.nc"
2522

@@ -115,7 +112,10 @@ def setUp(self):
115112
else:
116113
self.file_path = file_name
117114
self._file_format = file_formats.pop(0)
118-
f = pnetcdf.File(filename=self.file_path, mode = 'w', format=self._file_format, comm=comm, info=None)
115+
116+
f = pnetcdf.File(filename=self.file_path, mode = 'w',
117+
format=self._file_format, comm=comm, info=None)
118+
119119
dx = f.def_dim('x',xdim)
120120
dy = f.def_dim('y',ydim)
121121

@@ -136,11 +136,12 @@ def setUp(self):
136136
for i in range(num_reqs):
137137
v = f.variables[f'data{i}']
138138
# post the request to write an array of values
139-
req_id = v.iput_var(data, start = starts, count = counts, num = num_subarrays)
139+
req_id = v.iput_varn(data, num_subarrays, starts, counts)
140140
# track the reqeust ID for each write reqeust
141141
req_ids.append(req_id)
142142

143-
# all processes commit those 10 requests to the file at once using wait_all (collective i/o)
143+
# all processes commit those 10 requests to the file at once using
144+
# wait_all (collective i/o)
144145
req_errs = [None] * num_reqs
145146
f.wait_all(num_reqs, req_ids, req_errs)
146147

@@ -149,13 +150,15 @@ def setUp(self):
149150
if strerrno(req_errs[i]) != "NC_NOERR":
150151
print(f"Error on request {i}:", strerror(req_errs[i]))
151152

152-
# post 10 requests to write an array of values for the last 10 variables w/o tracking req ids
153+
# post 10 requests to write an array of values for the last 10
154+
# variables w/o tracking req ids
153155
for i in range(num_reqs):
154156
v = f.variables[f'data{num_reqs + i}']
155157
# post the request to write an array of values
156-
v.iput_var(data, start = starts, count = counts, num = num_subarrays)
158+
v.iput_varn(data, num_subarrays, starts, counts)
157159

158-
# all processes commit all pending requests to the file at once using wait_all (collective i/o)
160+
# all processes commit all pending requests to the file at once using
161+
# wait_all (collective I/O)
159162
f.wait_all(num = pnetcdf.NC_PUT_REQ_ALL)
160163
f.close()
161164

@@ -186,3 +189,4 @@ def runTest(self):
186189
if not result.wasSuccessful():
187190
print(output.getvalue())
188191
sys.exit(1)
192+

0 commit comments

Comments
 (0)