Skip to content

Commit 3fce82b

Browse files
committed
tests: Add test for memory estimate on devices
1 parent 09c5406 commit 3fce82b

2 files changed

Lines changed: 40 additions & 7 deletions

File tree

devito/operator/operator.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1429,8 +1429,8 @@ def get_nbytes(obj):
14291429
else:
14301430
host += v
14311431
elif i._mem_mapped:
1432-
if isinstance(self.platform, Device):
1433-
device += v
1432+
# No need to add to device, as it will be counted
1433+
# by nbytes_consumed_memmapped
14341434
host += v
14351435

14361436
return {disk_layer: 0, host_layer: host, device_layer: device}

tests/test_operator.py

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,14 @@
77
import sympy
88

99
import pytest
10-
from conftest import assert_structure, skipif
10+
11+
# Try-except required to allow for import of classes from this file
12+
# for testing in PRO
13+
try:
14+
from ..conftest import assert_structure, skipif
15+
except ImportError:
16+
from conftest import assert_structure, skipif
17+
1118
from devito import (Grid, Eq, Operator, Constant, Function, TimeFunction,
1219
SparseFunction, SparseTimeFunction, Dimension, error, SpaceDimension,
1320
NODE, CELL, dimensions, configuration, TensorFunction,
@@ -2059,6 +2066,8 @@ def test_indirection(self):
20592066
class TestEstimateMemory:
20602067
"""Tests for the Operator.estimate_memory() utility"""
20612068

2069+
_array_temp = "r0[x][y]"
2070+
20622071
def parse_output(self, output, expected):
20632072
"""Parse estimate_memory machine-readable output"""
20642073
# Check that no allocation occurs as estimate_memory should avoid data touch
@@ -2083,7 +2092,7 @@ def test_basic_usage(self, caplog, shape, dtype, so):
20832092
op.estimate_memory(human_readable=False)
20842093

20852094
# Check output of estimate_memory
2086-
host = reduce(mul, [s + 2*so for s in shape])*np.dtype(dtype).itemsize
2095+
host = reduce(mul, f.shape_allocated)*np.dtype(f.dtype).itemsize
20872096
expected = ("Kernel", 0, host, 0)
20882097
self.parse_output(caplog, expected)
20892098

@@ -2163,6 +2172,9 @@ def test_temp_array(self, caplog):
21632172
g = TimeFunction(name='g', grid=grid, space_order=2)
21642173
a = Function(name='a', grid=grid, space_order=2)
21652174

2175+
# Fake array allocated in Python land so that shape_allocated can be used
2176+
b = Function(name='b', grid=grid, space_order=0)
2177+
21662178
# Reuse an expensive function to encourage generation of an array temp
21672179
eq0 = Eq(f.forward, g + sympy.sin(a))
21682180
eq1 = Eq(g.forward, f + sympy.sin(a))
@@ -2172,15 +2184,15 @@ def test_temp_array(self, caplog):
21722184

21732185
# Regression to ensure this test functions as intended
21742186
# Ensure an array temporary is created
2175-
assert "r0[x][y]" in str(op.ccode)
2187+
assert self._array_temp in str(op.ccode)
21762188

21772189
op.estimate_memory(human_readable=False)
21782190

21792191
check = sum(reduce(mul, func.shape_allocated)*np.dtype(func.dtype).itemsize
21802192
for func in (f, g, a))
21812193

21822194
# Factor in the temp array
2183-
check += reduce(mul, a.shape)*np.dtype(a.dtype).itemsize
2195+
check += reduce(mul, b.shape_allocated)*np.dtype(a.dtype).itemsize
21842196

21852197
expected = ("Kernel", 0, check, 0)
21862198
self.parse_output(caplog, expected)
@@ -2217,4 +2229,25 @@ def test_overrides(self, caplog):
22172229
expected = ("Kernel", 0, check, 0)
22182230
self.parse_output(caplog, expected)
22192231

2220-
# Test with OpenACC
2232+
def test_device(self, caplog):
2233+
# Note: this uses switchconfig and runs on all backends to reflect expected
2234+
# usage: users are likely to run the estimate on the orchestration node which
2235+
# may not have the intended hardware, before using this output to determine which
2236+
# nodes to farm jobs out to.
2237+
grid = Grid(shape=(101, 101))
2238+
2239+
f = Function(name='f', grid=grid, space_order=2)
2240+
2241+
# Compiler is never invoked, so this should be fine
2242+
config = {'log_level': 'DEBUG', 'language': 'openacc',
2243+
'platform': 'nvidiaX'}
2244+
with switchconfig(**config), caplog.at_level(logging.DEBUG):
2245+
op = Operator(Eq(f, 1))
2246+
2247+
op.estimate_memory(human_readable=False)
2248+
2249+
check = reduce(mul, f.shape_allocated)*np.dtype(f.dtype).itemsize
2250+
2251+
# Matching memory allocated both on host and device for memmap
2252+
expected = ("Kernel", 0, check, check)
2253+
self.parse_output(caplog, expected)

0 commit comments

Comments
 (0)