def __init__(self): self.valid_systems = ['*'] self.valid_prog_environs = ['*'] self.sourcesdir = None self.executable = 'echo' self._count = int(type(self).__name__[1:]) self.sanity_patterns = sn.defer(True) self.keep_files = ['out.txt']
def test_filter(self): df = sn.filter(lambda x: x if x % 2 else None, sn.defer([1, 2, 3, 4, 5])) for i, x in sn.enumerate(df, start=1): self.assertEqual(2 * i - 1, x) # Alternative testing self.assertEqual([1, 3, 5], list(sn.evaluate(df)))
def __init__(self): self.valid_systems = ['*'] self.valid_prog_environs = ['*'] self.sanity_patterns = sn.assert_true(1) def foo(): yield True self.sanity_patterns = sn.defer(foo())
def test_filter(): df = sn.filter(lambda x: x if x % 2 else None, sn.defer([1, 2, 3, 4, 5])) for i, x in sn.enumerate(df, start=1): assert 2*i - 1 == x # Alternative testing assert [1, 3, 5] == list(sn.evaluate(df))
def test_assert_found(self): tempfile = self._write_tempfile() assert sn.assert_found(r'Step: \d+', tempfile) assert sn.assert_found( r'Step: \d+', sn.defer(tempfile)) with pytest.raises(SanityError): sn.evaluate(sn.assert_found(r'foo: \d+', tempfile)) os.remove(tempfile)
def test_divmod(): a = sn.defer(3) q, r = divmod(a, 2) assert 1 == q assert 1 == r # Test rdivmod here q, r = divmod(2, a) assert 0 == q assert 2 == r
def test_jsonext_dump(tmp_path): json_dump = tmp_path / 'test.json' with open(json_dump, 'w') as fp: jsonext.dump({'foo': sn.defer(['bar'])}, fp) with open(json_dump, 'r') as fp: assert '{"foo": null}' == fp.read() with open(json_dump, 'w') as fp: jsonext.dump({'foo': sn.defer(['bar']).evaluate()}, fp) with open(json_dump, 'r') as fp: assert '{"foo": ["bar"]}' == fp.read() with open(json_dump, 'w') as fp: jsonext.dump({'foo': sn.defer(['bar'])}, fp, separators=(',', ':')) with open(json_dump, 'r') as fp: assert '{"foo":null}' == fp.read()
def test_divmod(self): a = sn.defer(3) q, r = divmod(a, 2) self.assertEqual(1, q) self.assertEqual(1, r) # Test rdivmod here q, r = divmod(2, a) self.assertEqual(0, q) self.assertEqual(2, r)
def test_zip(self): la = [1, 2, 3] lb = sn.defer(['a', 'b', 'c']) la_new = [] lb_new = [] for a, b in sn.zip(la, lb): la_new.append(a) lb_new.append(b) self.assertEqual([1, 2, 3], la_new) self.assertEqual(['a', 'b', 'c'], lb_new)
def test_zip(): la = [1, 2, 3] lb = sn.defer(['a', 'b', 'c']) la_new = [] lb_new = [] for a, b in sn.zip(la, lb): la_new.append(a) lb_new.append(b) assert [1, 2, 3] == la_new assert ['a', 'b', 'c'] == lb_new
def test_deferrable_perf(): from reframe.core.deferrable import _DeferredPerformanceExpression as dpe a = sn.defer(3) b = dpe.construct_from_deferred_expr(a, 'some_unit') assert b.unit == 'some_unit' # Test wrong unit type with pytest.raises(TypeError): dpe(lambda x: x, 3) # Test not from deferred expr with pytest.raises(TypeError): dpe.construct_from_deferred_expr(lambda x: x, 'some_unit')
def test_assert_false_with_deferrables(self): self.assertTrue(sn.assert_false(sn.defer(False))) self.assertTrue(sn.assert_false(sn.defer(0))) self.assertTrue(sn.assert_false(sn.defer([]))) self.assertRaisesRegex(SanityError, 'True is not False', sn.evaluate, sn.assert_false(sn.defer(True))) self.assertRaisesRegex(SanityError, '1 is not False', sn.evaluate, sn.assert_false(sn.defer(1))) self.assertRaisesRegex(SanityError, r'\[1\] is not False', sn.evaluate, sn.assert_false(sn.defer([1])))
def test_assert_false_with_deferrables(): assert sn.assert_false(sn.defer(False)) assert sn.assert_false(sn.defer(0)) assert sn.assert_false(sn.defer([])) with pytest.raises(SanityError, match='True is not False'): sn.evaluate(sn.assert_false(sn.defer(True))) with pytest.raises(SanityError, match='1 is not False'): sn.evaluate(sn.assert_false(sn.defer(1))) with pytest.raises(SanityError, match=r'\[1\] is not False'): sn.evaluate(sn.assert_false(sn.defer([1])))
def test_assert_true_with_deferrables(): assert sn.assert_true(sn.defer(True)) assert sn.assert_true(sn.defer(1)) assert sn.assert_true(sn.defer([1])) with pytest.raises(SanityError, match='False is not True'): sn.evaluate(sn.assert_true(sn.defer(False))) with pytest.raises(SanityError, match='0 is not True'): sn.evaluate(sn.assert_true(sn.defer(0))) with pytest.raises(SanityError, match=r'\[\] is not True'): sn.evaluate(sn.assert_true(sn.defer([])))
def fake_check(): class _FakeCheck(rfm.RegressionTest): pass @sn.deferrable def error(): raise BaseException # A bit hacky, but we don't want to run a full test every time test = _FakeCheck() test._job = Job.create( getscheduler('local')(), getlauncher('local')(), 'fakejob') test.job._completion_time = time.time() test.job._jobid = 12345 test.job._nodelist = ['localhost'] test.custom = 'hello extras' test.custom_list = ['custom', 3.0, ['hello', 'world']] test.custom_dict = {'a': 1, 'b': 2} test.deferred = sn.defer('hello') test.deferred_error = error() return test
def test_count_uniq(): # Use a custom generator for testing def my_mod_range(n, mod=2): for i in range(n): yield i % mod assert 4 == sn.count_uniq([1, 2, 3, 4, 4, 3, 2, 1]) assert 1 == sn.count_uniq((1, 1, 1)) assert 3 == sn.count_uniq({1, 2, 3, 2, 3}) assert 3 == sn.count_uniq({'a': 1, 'b': 2, 'c': 3}) assert 2 == sn.count_uniq(my_mod_range(10)) assert 3 == sn.count_uniq(my_mod_range(10, 3)) # Test empty sequences assert 0 == sn.count_uniq([]) assert 0 == sn.count_uniq({}) assert 0 == sn.count_uniq(set()) assert 0 == sn.count_uniq(my_mod_range(0)) assert 0 == sn.count_uniq(range(0)) # Test deferred expressions d = [1, 2, 2, 1] assert 2 == sn.count_uniq(sn.defer(d))
def test_count_uniq(self): # Use a custom generator for testing def my_mod_range(n, mod=2): for i in range(n): yield i % mod self.assertEqual(4, sn.count_uniq([1, 2, 3, 4, 4, 3, 2, 1])) self.assertEqual(1, sn.count_uniq((1, 1, 1))) self.assertEqual(3, sn.count_uniq({1, 2, 3, 2, 3})) self.assertEqual(3, sn.count_uniq({'a': 1, 'b': 2, 'c': 3})) self.assertEqual(2, sn.count_uniq(my_mod_range(10))) self.assertEqual(3, sn.count_uniq(my_mod_range(10, 3))) # Test empty sequences self.assertEqual(0, sn.count_uniq([])) self.assertEqual(0, sn.count_uniq({})) self.assertEqual(0, sn.count_uniq(set())) self.assertEqual(0, sn.count_uniq(my_mod_range(0))) self.assertEqual(0, sn.count_uniq(range(0))) # Test deferred expressions d = [1, 2, 2, 1] self.assertEqual(2, sn.count_uniq(sn.defer(d)))
def set_sanity_gpu(self): # {{{ ''' This method runs sanity checks on the following logs: - info cuda devices .. literalinclude:: ../../reframechecks/debug/res/cuda-gdb/info_devices.log :lines: 1-3 - info cuda kernels .. literalinclude:: ../../reframechecks/debug/res/cuda-gdb/info_kernels.log :lines: 5-7 - info cuda threads .. literalinclude:: ../../reframechecks/debug/res/cuda-gdb/info_threads.log :lines: 1-5, 458-459 - navigate between cuda kernels/blocks/threads/ .. literalinclude:: ../../reframechecks/debug/res/cuda-gdb/info_navigate.log :lines: 5-6, 17-18, 33-34 :emphasize-lines: 1, 3, 5 - inspect variables (std::vector) .. literalinclude:: ../../reframechecks/debug/res/cuda-gdb/info_std_vector.log :lines: 1-25 :emphasize-lines: 4 - inspect variables (int*) .. literalinclude:: ../../reframechecks/debug/res/cuda-gdb/info_const_int.log :lines: 6-37 :emphasize-lines: 17 ''' # }}} self.gpu_specs = {} self.gpu_specs_bool = {} ref_gpu_specs = {} ref_gpu_specs['P100'] = {} ref_gpu_specs['V100'] = {} # {{{ info_devices.log: # Dev PCI Bus/Dev ID Name Description SM Type SMs Warps/SM Lanes/Warp # Max Regs/Lane Active SMs Mask # * 0 88:00.0 Tesla V100-SXM2-16GB GV100GL-A sm_70 80 64 ... # ^^^^ ^^^^^ ^^ ^^ # 32 256 0x000000000000ffffffffffffffffffff # ^^ self.rpt = os.path.join(self.stagedir, self.log_devices) ref_gpu_specs = { 'V100': { 'capability': 'sm_70', 'sms': 80, 'WarpsPerSM': 64, 'LanesPerWarp': 32, # = warpSize 'max_threads_per_sm': 2048, 'max_threads_per_device': 163840, }, 'P100': { 'capability': 'sm_60', 'sms': 56, 'WarpsPerSM': 64, 'LanesPerWarp': 32, # = warpSize 'max_threads_per_sm': 2048, 'max_threads_per_device': 114688, }, } regex = (r'Tesla (?P<gpu_name>\S+)-\S+-\S+\s+\S+\s+(?P<cap>sm_\d+)\s+' r'(?P<sms>\d+)\s+(?P<WarpsPerSM>\d+)\s+(?P<LanesPerWarp>\d+)') # --- get gpu_name (V100 or P100): gpu_name = sn.evaluate(sn.extractsingle(regex, self.rpt, 'gpu_name')) # --- get capability (True means that extracted value matches ref): res = sn.extractsingle(regex, self.rpt, 'cap') self.gpu_specs['capability'] = res self.gpu_specs_bool['capability'] = \ (res == ref_gpu_specs[gpu_name]['capability']) # --- get sms: res = sn.extractsingle(regex, self.rpt, 'sms', int) self.gpu_specs['sms'] = res self.gpu_specs_bool['sms'] = (res == ref_gpu_specs[gpu_name]['sms']) # --- get WarpsPerSM: res = sn.extractsingle(regex, self.rpt, 'WarpsPerSM', int) self.gpu_specs['WarpsPerSM'] = res self.gpu_specs_bool['WarpsPerSM'] = \ (res == ref_gpu_specs[gpu_name]['WarpsPerSM']) # --- get LanesPerWarp|warpSize: res = sn.extractsingle(regex, self.rpt, 'LanesPerWarp', int) self.gpu_specs['LanesPerWarp'] = res self.gpu_specs_bool['LanesPerWarp'] = \ (res == ref_gpu_specs[gpu_name]['LanesPerWarp']) # --- threads_per_sm <= LanesPerWarp * WarpsPerSM res = self.gpu_specs['LanesPerWarp'] * self.gpu_specs['WarpsPerSM'] self.gpu_specs['max_threads_per_sm'] = res self.gpu_specs_bool['max_threads_per_sm'] = \ (res == ref_gpu_specs[gpu_name]['max_threads_per_sm']) # --- threads_per_device <= threads_per_sm * sms res = self.gpu_specs['sms'] * self.gpu_specs['max_threads_per_sm'] self.gpu_specs['max_threads_per_device'] = res self.gpu_specs_bool['max_threads_per_device'] = \ (res == ref_gpu_specs[gpu_name]['max_threads_per_device']) # --- max_np of 1gpu = f(max_threads_per_device) where np = cube_size^3 import math self.gpu_specs['max_cubesz'] = sn.defer( math.ceil(pow(sn.evaluate(res), 1 / 3))) # }}} # {{{ info_kernels.log: # Kernel Parent Dev Grid Status SMs Mask GridDim BlockDim Invocation # * 0 - 0 3 Active 0x (106,1,1) (256,1,1) ...::density<double>(n=27000, # ^^^^^^^ ^^^^^^^ ^^^^^ # --------------------------------------------------------------------- self.log = os.path.join(self.stagedir, self.log_kernels) regex = (r'\*.*Active \S+ \((?P<grid_x>\d+),(?P<grid_y>\d+),' r'(?P<grid_z>\d+)\)\s+\((?P<block_x>\d+),(?P<block_y>\d+),' r'(?P<block_z>\d+)\).*\(n=(?P<np>\d+), ') grid_x = sn.extractsingle(regex, self.log, 'grid_x', int) grid_y = sn.extractsingle(regex, self.log, 'grid_y', int) grid_z = sn.extractsingle(regex, self.log, 'grid_z', int) block_x = sn.extractsingle(regex, self.log, 'block_x', int) block_y = sn.extractsingle(regex, self.log, 'block_y', int) block_z = sn.extractsingle(regex, self.log, 'block_z', int) np = sn.extractsingle(regex, self.log, 'np', int) self.kernel_grid = grid_x * grid_y * grid_z self.kernel_block = block_x * block_y * block_z self.kernel_np = np import math self.gpu_specs['cubesz'] = \ sn.defer(math.ceil(pow(sn.evaluate(self.kernel_np), 1/3))) # {{{ TODO:tuple # https://github.com/eth-cscs/reframe/blob/master/cscs-checks/ # prgenv/affinity_check.py#L38 # regex=(r'\*.*Active \S+ (?P<griddim>\(\d+,\d+,\d+\))\s+(?P<blockdim>' # r'\(\d+,\d+,\d+\)).*\(n=(?P<np>\d+), ') # from functools import reduce # self.res = reduce(lambda x, y: x*y, list(res)) # sn.extractsingle(regex, self.stdout, 'nrgy', # conv=lambda x: int(x.replace(',', ''))) # res: ('(', '1', '0', '6', ',', '1', ',', '1', ')') # }}} # }}} # {{{ info_threads.log: # BlockIdx ThreadIdx To BlockIdx ThreadIdx Count Virtual PC Filename L # Kernel 0 # * (0,0,0) (0,0,0) (1,0,0) (63,0,0) 320 0x0... ../cudaDensity.cu 27 # (1,0,0) (64,0,0) (1,0,0) (95,0,0) 32 0x0... ../cudaDensity.cu 26 # etc... sum(^^^) # --------------------------------------------------------------------- self.log = os.path.join(self.stagedir, self.log_threads) regex = r'(\(\S+\)\s+){4}(?P<nth>\d+)\s+0x' self.threads_np = sn.sum(sn.extractall(regex, self.log, 'nth', int)) # }}} # {{{ info_navigate.log: # gridDim=(106,1,1) blockDim=(256,1,1) blockIdx=(0,0,0) \ # threadIdx=(0,0,0) warpSize=32 thid=0 # kernel 0 grid 3 block (0,0,0) thread (0,0,0) device 0 sm 0 warp 0 ... # -- # gridDim=(106,1,1) blockDim=(256,1,1) blockIdx=(105,0,0) # threadIdx=(255,0,0) warpSize=32 thid=27135 # kernel 0 grid 3 block (105,0,0) thread (255,0,0) device 0 sm 43 ... # -- # gridDim=(106,1,1) blockDim=(256,1,1) blockIdx=(55,0,0) # threadIdx=(255,0,0) warpSize=32 thid=14335 # kernel 0 grid 3 block (55,0,0) thread (255,0,0) device 0 sm 55 ... # --------------------------------------------------------------------- self.log = os.path.join(self.stagedir, self.log_navigate) regex = r'^gridDim.*warpSize=\d+ thid=(?P<th>\d+)$' self.thids = sn.extractall(regex, self.log, 'th', int) # }}} # {{{ info_std_vector.log: # --- get vector length(True means that extracted value matches ref): self.rpt = os.path.join(self.stagedir, self.log_stdvector) # std::vector of length 27000, capacity 27000 regex = r'std::vector of length (?P<vec_len1>\d+),' res = sn.extractsingle(regex, self.rpt, 'vec_len1', int) self.gpu_specs['vec_len1'] = res self.gpu_specs_bool['vec_len1'] = (res == self.cubesize**3) # Vector size = 27000 (pvector) regex = r'^Vector size = (?P<vec_len2>\d+)$' res = sn.extractsingle(regex, self.rpt, 'vec_len2', int) self.gpu_specs['vec_len2'] = res self.gpu_specs_bool['vec_len2'] = (res == self.cubesize**3) # }}} # {{{ --- sanity_patterns: self.sanity_patterns = sn.all([ sn.assert_true(self.gpu_specs_bool['capability']), sn.assert_true(self.gpu_specs_bool['sms']), sn.assert_true(self.gpu_specs_bool['WarpsPerSM']), sn.assert_true(self.gpu_specs_bool['LanesPerWarp']), sn.assert_true(self.gpu_specs_bool['max_threads_per_sm']), sn.assert_true(self.gpu_specs_bool['max_threads_per_device']), sn.assert_true(self.gpu_specs_bool['vec_len1']), sn.assert_true(self.gpu_specs_bool['vec_len2']), # NO: sn.assert_true(self.gpu_specs_bool), ])
def test_ipow(): v = V(3) dv = sn.defer(v) dv **= V(2) sn.evaluate(dv) assert 9 == v._value
def test_str(): assert '[1, 2]' == str(sn.defer([1, 2]))
def test_iter(): l = [1, 2, 3] dl = sn.defer(l) l.append(4) for i, e in enumerate(dl, start=1): assert i == e
def a(): return sn.defer(3)
def test_implicit_eval(): # Call to bool() on a deferred expression triggers its immediate # evaluation. a = sn.defer(3) assert 3 == a
def test_ixor(): v = V(7) dv = sn.defer(v) dv ^= V(7) sn.evaluate(dv) assert 0 == v._value
def test_ior(): v = V(2) dv = sn.defer(v) dv |= V(5) sn.evaluate(dv) assert 7 == v._value
def test_iand(): v = V(7) dv = sn.defer(v) dv &= V(2) sn.evaluate(dv) assert 2 == v._value
def test_irshift(): v = V(8) dv = sn.defer(v) dv >>= V(3) sn.evaluate(dv) assert 1 == v._value
def test_ilshift(): v = V(1) dv = sn.defer(v) dv <<= V(2) sn.evaluate(dv) assert 4 == v._value
def test_ifloordiv(): v = V(3) dv = sn.defer(v) dv //= V(2) sn.evaluate(dv) assert 1 == v._value
def test_imod(): v = V(3) dv = sn.defer(v) dv %= V(2) sn.evaluate(dv) assert 1 == v._value