Skip to content

Commit 4dca8ad

Browse files
committed
Merge pull request #533 from OP2/min-max-parallel
* fix/min-max-parallel: Allow MIN and MAX accessors on Dats
2 parents 6eac264 + 3f618d1 commit 4dca8ad

File tree

3 files changed

+26
-11
lines changed

3 files changed

+26
-11
lines changed

pyop2/base.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@
4747
import types
4848
from hashlib import md5
4949

50-
from pyop2.datatypes import IntType, as_cstr, _EntityMask, _MapMask
50+
from pyop2.datatypes import IntType, as_cstr, _EntityMask, _MapMask, dtype_limits
5151
from pyop2.configuration import configuration
5252
from pyop2.caching import Cached, ObjectCached
5353
from pyop2.exceptions import *
@@ -473,7 +473,7 @@ def global_to_local_begin(self):
473473
assert self._is_dat, "Doing halo exchanges only makes sense for Dats"
474474
assert not self._in_flight, \
475475
"Halo exchange already in flight for Arg %s" % self
476-
if self.access in [READ, RW, INC]:
476+
if self.access in [READ, RW, INC, MIN, MAX]:
477477
self._in_flight = True
478478
self.data.global_to_local_begin(self.access)
479479

@@ -483,7 +483,7 @@ def global_to_local_end(self):
483483
Doing halo exchanges only makes sense for :class:`Dat` objects.
484484
"""
485485
assert self._is_dat, "Doing halo exchanges only makes sense for Dats"
486-
if self.access in [READ, RW, INC] and self._in_flight:
486+
if self.access in [READ, RW, INC, MIN, MAX] and self._in_flight:
487487
self._in_flight = False
488488
self.data.global_to_local_end(self.access)
489489

@@ -1647,7 +1647,7 @@ class Dat(DataCarrier, _EmptyDataMixin):
16471647
"""
16481648

16491649
_globalcount = 0
1650-
_modes = [READ, WRITE, RW, INC]
1650+
_modes = [READ, WRITE, RW, INC, MIN, MAX]
16511651

16521652
@validate_type(('dataset', (DataCarrier, DataSet, Set), DataSetTypeError),
16531653
('name', str, NameTypeError))
@@ -2121,6 +2121,9 @@ def global_to_local_begin(self, access_mode):
21212121
halo.global_to_local_begin(self, WRITE)
21222122
elif access_mode is INC:
21232123
self._data[self.dataset.size:] = 0
2124+
elif access_mode in [MIN, MAX]:
2125+
min_, max_ = dtype_limits(self.dtype)
2126+
self._data[self.dataset.size:] = {MAX: min_, MIN: max_}[access_mode]
21242127

21252128
@collective
21262129
def global_to_local_end(self, access_mode):
@@ -2134,7 +2137,7 @@ def global_to_local_end(self, access_mode):
21342137
if access_mode in [READ, RW] and not self.halo_valid:
21352138
halo.global_to_local_end(self, WRITE)
21362139
self.halo_valid = True
2137-
elif access_mode is INC:
2140+
elif access_mode in [MIN, MAX, INC]:
21382141
self.halo_valid = False
21392142

21402143
@collective

pyop2/datatypes.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,3 +50,21 @@ class _EntityMask(ctypes.Structure):
5050
_fields_ = [("section", ctypes.c_voidp),
5151
("bottom", ctypes.c_voidp),
5252
("top", ctypes.c_voidp)]
53+
54+
55+
def dtype_limits(dtype):
56+
"""Attempt to determine the min and max values of a datatype.
57+
58+
:arg dtype: A numpy datatype.
59+
:returns: a 2-tuple of min, max
60+
:raises ValueError: If numeric limits could not be determined.
61+
"""
62+
try:
63+
info = numpy.finfo(dtype)
64+
except ValueError:
65+
# maybe an int?
66+
try:
67+
info = numpy.iinfo(dtype)
68+
except ValueError as e:
69+
raise ValueError("Unable to determine numeric limits from %s" % dtype) from e
70+
return info.min, info.max

test/unit/test_api.py

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -790,12 +790,6 @@ def test_dat_initialise_data_type(self, dset):
790790
d = op2.Dat(dset, dtype=np.int32)
791791
assert d.data.dtype == np.int32
792792

793-
@pytest.mark.parametrize("mode", [op2.MAX, op2.MIN])
794-
def test_dat_arg_illegal_mode(self, dat, mode):
795-
"""Dat __call__ should not allow access modes not allowed for a Dat."""
796-
with pytest.raises(exceptions.ModeValueError):
797-
dat(mode)
798-
799793
def test_dat_subscript(self, dat):
800794
"""Extracting component 0 of a Dat should yield self."""
801795
assert dat[0] is dat

0 commit comments

Comments
 (0)