def test_dynamic_nthreads(self): grid = Grid(shape=(16, 16, 16)) f = TimeFunction(name='f', grid=grid) sf = SparseTimeFunction(name='sf', grid=grid, npoint=1, nt=5) eqns = [Eq(f.forward, f + 1)] eqns += sf.interpolate(f) op = Operator(eqns, opt='openmp') parregions = FindNodes(OmpRegion).visit(op) assert len(parregions) == 2 # Check suitable `num_threads` appear in the generated code # Not very elegant, but it does the trick assert 'num_threads(nthreads)' in str(parregions[0].header[0]) assert 'num_threads(nthreads_nonaffine)' in str( parregions[1].header[0]) # Check `op` accepts the `nthreads*` kwargs op.apply(time=0) op.apply(time_m=1, time_M=1, nthreads=4) op.apply(time_m=1, time_M=1, nthreads=4, nthreads_nonaffine=2) op.apply(time_m=1, time_M=1, nthreads_nonaffine=2) assert np.all(f.data[0] == 2.) # Check the actual value assumed by `nthreads` and `nthreads_nonaffine` assert op.arguments(time=0, nthreads=123)['nthreads'] == 123 assert op.arguments( time=0, nthreads_nonaffine=100)['nthreads_nonaffine'] == 100
def test_scheduling(self): """ Affine iterations -> #pragma omp ... schedule(dynamic,1) ... Non-affine iterations -> #pragma omp ... schedule(dynamic,chunk_size) ... """ grid = Grid(shape=(11, 11)) u = TimeFunction(name='u', grid=grid, time_order=2, save=5, space_order=0) sf1 = SparseTimeFunction(name='s', grid=grid, npoint=1, nt=5) eqns = [Eq(u.forward, u + 1)] eqns += sf1.interpolate(u) op = Operator(eqns, dle='openmp') iterations = FindNodes(Iteration).visit(op) assert len(iterations) == 4 assert iterations[1].is_Affine assert 'schedule(dynamic,1)' in iterations[1].pragmas[0].value assert not iterations[3].is_Affine assert 'schedule(dynamic,chunk_size)' in iterations[3].pragmas[0].value
def test_default_sparse_functions(self): """ Test the default argument derivation for composite functions. """ grid = Grid(shape=(5, 6, 7)) f = TimeFunction(name='f', grid=grid) s = SparseTimeFunction(name='s', grid=grid, npoint=3, nt=4) s.coordinates.data[:, 0] = np.arange(0., 3.) s.coordinates.data[:, 1] = np.arange(1., 4.) s.coordinates.data[:, 2] = np.arange(2., 5.) op = Operator(s.interpolate(f)) expected = { 's': s.data, 's_coords': s.coordinates.data, # Default dimensions of the sparse data 'p_s_size': 3, 'p_s_s': 0, 'p_s_e': 3, 'd_size': 3, 'd_s': 0, 'd_e': 3, 'time_size': 4, 'time_s': 0, 'time_e': 4, } self.verify_arguments(op.arguments(), expected)
def test_over_injection(): nt = 10 grid = Grid(shape=(4, 4)) src = SparseTimeFunction(name='src', grid=grid, npoint=1, nt=nt) rec = SparseTimeFunction(name='rec', grid=grid, npoint=1, nt=nt) u = TimeFunction(name="u", grid=grid, time_order=2, space_order=2, save=nt) u1 = TimeFunction(name="u", grid=grid, time_order=2, space_order=2, save=nt) src.data[:] = 1. eqns = ([Eq(u.forward, u + 1)] + src.inject(field=u.forward, expr=src) + rec.interpolate(expr=u.forward)) op0 = Operator(eqns, opt='noop') op1 = Operator(eqns, opt='buffering') # Check generated code assert len(retrieve_iteration_tree(op1)) ==\ 5 + bool(configuration['language'] != 'C') buffers = [i for i in FindSymbols().visit(op1) if i.is_Array] assert len(buffers) == 1 op0.apply(time_M=nt - 2) op1.apply(time_M=nt - 2, u=u1) assert np.all(u.data == u1.data)
def test_interpolation(): nt = 10 grid = Grid(shape=(4, 4)) src = SparseTimeFunction(name='src', grid=grid, npoint=1, nt=nt) rec = SparseTimeFunction(name='rec', grid=grid, npoint=1, nt=nt) u = TimeFunction(name="u", grid=grid, time_order=2) u1 = TimeFunction(name="u", grid=grid, time_order=2) src.data[:] = 1. eqns = ([Eq(u.forward, u + 1)] + src.inject(field=u.forward, expr=src) + rec.interpolate(expr=u.forward)) op0 = Operator(eqns, opt='advanced') op1 = Operator(eqns, opt=('advanced', {'linearize': True})) # Check generated code assert 'uL0' not in str(op0) assert 'uL0' in str(op1) op0.apply(time_M=nt - 2) op1.apply(time_M=nt - 2, u=u1) assert np.all(u.data == u1.data)
def test_scheduling(self): """ Affine iterations -> #pragma omp ... schedule(static,1) ... Non-affine iterations -> #pragma omp ... schedule(static) ... """ grid = Grid(shape=(11, 11)) u = TimeFunction(name='u', grid=grid, time_order=2, save=5, space_order=0) sf1 = SparseTimeFunction(name='s', grid=grid, npoint=1, nt=5) eqns = [Eq(u.forward, u + 1)] eqns += sf1.interpolate(u) op = Operator(eqns, dle='openmp') iterations = FindNodes(Iteration).visit(op) assert len(iterations) == 4 assert iterations[1].is_Affine assert 'schedule(static,1)' in iterations[1].pragmas[0].value assert not iterations[3].is_Affine assert 'schedule(static)' in iterations[3].pragmas[0].value
def test_operator_leakage_sparse(self): """ Test to ensure that Operator creation does not cause memory leaks for SparseTimeFunctions. """ grid = Grid(shape=(5, 6)) a = Function(name='a', grid=grid) s = SparseTimeFunction(name='s', grid=grid, npoint=1, nt=1) w_a = weakref.ref(a) w_s = weakref.ref(s) # Create operator and delete everything again op = Operator(s.interpolate(a)) w_op = weakref.ref(op) del op del s del a clear_cache() # Test whether things are still hanging around assert w_a() is None assert w_s() is None assert w_op() is None
def test_operator_leakage_sparse(): """ Test to ensure that Operator creation does not cause memory leaks for SparseTimeFunctions. """ grid = Grid(shape=(5, 6)) a = Function(name='a', grid=grid) s = SparseTimeFunction(name='s', grid=grid, npoint=1, nt=1) w_a = weakref.ref(a) w_s = weakref.ref(s) # Create operator and delete everything again op = Operator(s.interpolate(a)) w_op = weakref.ref(op) del op del s del a clear_cache() # Test whether things are still hanging around assert w_a() is None assert w_s() is None assert w_op() is None