77import sympy
88
99import 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+
1118from 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):
20592066class 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