From adc93fc116897979dc62fcd324ca47da7c8f2b80 Mon Sep 17 00:00:00 2001 From: Fabio Luporini Date: Wed, 17 Jan 2024 09:33:12 +0000 Subject: [PATCH] api: Improve halo setup API and docs --- devito/types/dense.py | 45 ++++++++++++++++++++++++++++--------------- tests/test_data.py | 14 +++++++++++++- 2 files changed, 42 insertions(+), 17 deletions(-) diff --git a/devito/types/dense.py b/devito/types/dense.py index b9ee56c0be6..0aa16d2435d 100644 --- a/devito/types/dense.py +++ b/devito/types/dense.py @@ -890,14 +890,20 @@ class Function(DiscreteFunction): provided, shape and dimensions must be given. For MPI execution, a Grid is compulsory. space_order : int or 3-tuple of ints, optional - Discretisation order for space derivatives. Defaults to 1. ``space_order`` also - impacts the number of points available around a generic point of interest. By - default, ``space_order`` points are available on both sides of a generic point of - interest, including those nearby the grid boundary. Sometimes, fewer points - suffice; in other scenarios, more points are necessary. In such cases, instead of - an integer, one can pass a 3-tuple ``(o, lp, rp)`` indicating the discretization - order (``o``) as well as the number of points on the left (``lp``) and right - (``rp``) sides of a generic point of interest. + Discretisation order for space derivatives. Defaults to 1. + `space_order` also impacts the number of points available around a + generic point of interest. By default, `space_order` points are + available on both sides of a generic point of interest, including those + nearby the grid boundary. Sometimes, fewer points suffice; in other + scenarios, more points are necessary. In such cases, instead of an + integer, one can pass: + * a 3-tuple `(o, lp, rp)` indicating the discretization order + (`o`) as well as the number of points on the left (`lp`) and + right (`rp`) sides of a generic point of interest; + * a 2-tuple `(o, ((lp0, rp0), (lp1, rp1), ...))` indicating the + discretization order (`o`) as well as the number of points on + the left/right sides of a generic point of interest for each + SpaceDimension. shape : tuple of ints, optional Shape of the domain region in grid points. Only necessary if `grid` isn't given. @@ -1115,6 +1121,7 @@ def __halo_setup__(self, **kwargs): elif isinstance(space_order, tuple) and len(space_order) == 2: _, space_halo = space_order if not isinstance(space_halo, tuple) or \ + not all(isinstance(i, tuple) for i in space_halo) or \ len(space_halo) != len(self.space_dimensions): raise TypeError("Invalid `space_order`") v = list(space_halo) @@ -1214,14 +1221,20 @@ class TimeFunction(Function): provided, shape and dimensions must be given. For MPI execution, a Grid is compulsory. space_order : int or 3-tuple of ints, optional - Discretisation order for space derivatives. Defaults to 1. ``space_order`` also - impacts the number of points available around a generic point of interest. By - default, ``space_order`` points are available on both sides of a generic point of - interest, including those nearby the grid boundary. Sometimes, fewer points - suffice; in other scenarios, more points are necessary. In such cases, instead of - an integer, one can pass a 3-tuple ``(o, lp, rp)`` indicating the discretization - order (``o``) as well as the number of points on the left (``lp``) and right - (``rp``) sides of a generic point of interest. + Discretisation order for space derivatives. Defaults to 1. + `space_order` also impacts the number of points available around a + generic point of interest. By default, `space_order` points are + available on both sides of a generic point of interest, including those + nearby the grid boundary. Sometimes, fewer points suffice; in other + scenarios, more points are necessary. In such cases, instead of an + integer, one can pass: + * a 3-tuple `(o, lp, rp)` indicating the discretization order + (`o`) as well as the number of points on the left (`lp`) and + right (`rp`) sides of a generic point of interest; + * a 2-tuple `(o, ((lp0, rp0), (lp1, rp1), ...))` indicating the + discretization order (`o`) as well as the number of points on + the left/right sides of a generic point of interest for each + SpaceDimension. time_order : int, optional Discretization order for time derivatives. Defaults to 1. shape : tuple of ints, optional diff --git a/tests/test_data.py b/tests/test_data.py index b6df686118b..232aff9c974 100644 --- a/tests/test_data.py +++ b/tests/test_data.py @@ -316,10 +316,22 @@ def test_w_halo_w_autopadding(self): assert u0.shape_allocated == (4, 4, 16) assert u1._size_halo == ((3, 3), (3, 3), (3, 3)) - assert u1._size_padding == ((0, 0), (0, 0), (0, 6)) # 14 stems from 6 + 8 + assert u1._size_padding == ((0, 0), (0, 0), (0, 6)) # 6 stems from 16-(3+4+3) assert u1._size_nodomain == ((3, 3), (3, 3), (3, 9)) assert u1.shape_allocated == (10, 10, 16) + def test_w_halo_custom(self): + grid = Grid(shape=(4, 4)) + + # Custom halo with not enougn entries raises an exception + with pytest.raises(TypeError): + Function(name='u', grid=grid, space_order=(8, (4, 3))) + + u = TimeFunction(name='u', grid=grid, space_order=(8, ((4, 3), (1, 1)))) + + assert u._size_halo == ((0, 0), (4, 3), (1, 1)) + assert u.shape_allocated == (2, 11, 6) + class TestDecomposition(object):