def test_argument_parser_asm_block(self): # valid --asm-block parser = kc.create_parser() args = parser.parse_args(['-m', self._find_file('phinally_gcc.yaml'), '-p', 'Benchmark', self._find_file('2d-5pt.c'), '--asm-block', 'auto']) kc.check_arguments(args, parser) # valid --asm-block parser = kc.create_parser() args = parser.parse_args(['-m', self._find_file('phinally_gcc.yaml'), '-p', 'Benchmark', self._find_file('2d-5pt.c'), '--asm-block', 'manual']) kc.check_arguments(args, parser) # valid --asm-block parser = kc.create_parser() args = parser.parse_args(['-m', self._find_file('phinally_gcc.yaml'), '-p', 'Benchmark', self._find_file('2d-5pt.c'), '--asm-block', '23']) kc.check_arguments(args, parser) # invalid --asm-block parser = kc.create_parser() args = parser.parse_args(['-m', self._find_file('phinally_gcc.yaml'), '-p', 'Benchmark', self._find_file('2d-5pt.c'), '--asm-block', 'foobar']) with self.assertRaises(SystemExit) as cm: kc.check_arguments(args, parser) self.assertEqual(cm.exception.code, 2)
def test_copy_ECMData_LC(self): store_file = os.path.join(self.temp_dir, 'test_copy_ECMData_LC.pickle') output_stream = StringIO() parser = kc.create_parser() args = parser.parse_args(['-m', self._find_file('hasep1.yaml'), '-p', 'ECMData', self._find_file('copy.c'), '-D', 'N', '1000000', '-vvv', '--unit=cy/CL', '--cache-predictor=LC', '--store', store_file]) kc.check_arguments(args, parser) kc.run(parser, args, output_file=output_stream) with open(store_file, 'rb') as f: results = pickle.load(f) # Output of first result: ecmd = results['copy.c'][((sympy.var('N'), 1000000),)]['ECMData'] # 2 arrays * 1000000 doubles/array * 8 Bytes/double ~ 15MB # -> L3 self.assertAlmostEqual(ecmd['L2'], 6, places=1) self.assertAlmostEqual(ecmd['L3'], 6, places=1) self.assertAlmostEqual(ecmd['MEM'], 0, places=0)
def test_sclar_product_ECMData(self): store_file = os.path.join(self.temp_dir, 'test_scalar_product_ECMData.pickle') output_stream = StringIO() parser = kc.create_parser() args = parser.parse_args([ '-m', self._find_file('hasep1.yaml'), '-p', 'ECMData', self._find_file('scalar_product.c'), '-D', 'N', '10000', '-vvv', '--store', store_file ]) kc.check_arguments(args, parser) kc.run(parser, args, output_file=output_stream) results = pickle.load(open(store_file, 'rb')) # Output of first result: ecmd = results['scalar_product.c'][((sympy.var('N'), 10000), )]['ECMData'] # 2 Misses in L1, since sizeof(a)+sizeof(b) = 156kB > L1 self.assertAlmostEqual(ecmd['L1-L2'], 4, places=1) self.assertAlmostEqual(ecmd['L2-L3'], 0.0, places=1) self.assertAlmostEqual(ecmd['L3-MEM'], 0.0, places=0)
def test_2d5pt_RooflineIACA(self): store_file = os.path.join(self.temp_dir, 'test_2d5pt_RooflineIACA.pickle') output_stream = StringIO() parser = kc.create_parser() args = parser.parse_args(['-m', self._find_file('phinally_gcc.yaml'), '-p', 'RooflineIACA', self._find_file('2d-5pt.c'), '-D', 'N', '4000', '-D', 'M', '1000', '-vvv', '--unit=FLOP/s', '--store', store_file]) kc.check_arguments(args, parser) kc.run(parser, args, output_file=output_stream) results = pickle.load(open(store_file, 'rb')) # Check if results contains correct kernel self.assertEqual(list(results), ['2d-5pt.c']) # Check for correct variations of constants six.assertCountEqual(self, [sorted(map(str, r)) for r in results['2d-5pt.c']], [sorted(map(str, r)) for r in [((sympy.var('M'), 1000), (sympy.var('N'), 4000))]]) # Output of first result: result = list(results['2d-5pt.c'].values())[0] six.assertCountEqual(self, result, ['RooflineIACA']) roofline = result['RooflineIACA'] self.assertAlmostEqual(roofline['min performance'], 2900000000.0, places=0) self.assertEqual(roofline['bottleneck level'], 3)
def test_2d5pt_ECMData(self): store_file = os.path.join(self.temp_dir, 'test_2d5pt_ECMData.pickle') output_stream = StringIO() parser = kc.create_parser() args = parser.parse_args(['-m', self._find_file('phinally_gcc.yaml'), '-p', 'ECMData', self._find_file('2d-5pt.c'), '-D', 'N', '1000-100000:3log10', '-D', 'M', '50', '-vvv', '--store', store_file]) kc.check_arguments(args, parser) kc.run(parser, args, output_file=output_stream) results = pickle.load(open(store_file, 'rb')) # Check if results contains correct kernel self.assertEqual(list(results), ['2d-5pt.c']) # Check for correct variations of constants six.assertCountEqual(self, [sorted(r) for r in results['2d-5pt.c']], [sorted(r) for r in [ (('M', 50), ('N', 1000)), (('M', 50), ('N', 10000)), (('M', 50), ('N', 100000))]]) # Output of first result: result = results['2d-5pt.c'][[k for k in results['2d-5pt.c'] if ('N', 1000) in k][0]] six.assertCountEqual(self, result, ['ECMData']) ecmd = result['ECMData'] self.assertAlmostEqual(ecmd['L1-L2'], 10, places=1) self.assertAlmostEqual(ecmd['L2-L3'], 6, places=1) self.assertAlmostEqual(ecmd['L3-MEM'], 3.891891891891892, places=0)
def test_copy_ECMData(self): store_file = os.path.join(self.temp_dir, 'test_copy_ECMData.pickle') output_stream = StringIO() parser = kc.create_parser() args = parser.parse_args(['-m', self._find_file('hasep1.yaml'), '-p', 'ECMData', self._find_file('copy.c'), '-D', 'N', '1000000', '-vvv', '--unit=cy/CL', '--store', store_file]) kc.check_arguments(args, parser) kc.run(parser, args, output_file=output_stream) results = pickle.load(open(store_file, 'rb')) # Output of first result: ecmd = results['copy.c'][((sympy.var('N'), 1000000),)]['ECMData'] # 2 arrays * 1000000 doubles/array * 8 Bytes/double ~ 15MB # -> L3 # FIXME 2.3cy in L3 due to evicts not respecting cache, should be 0.0 self.assertAlmostEqual(ecmd['L1-L2'], 6, places=1) self.assertAlmostEqual(ecmd['L2-L3'], 6, places=1) self.assertAlmostEqual(ecmd['L3-MEM'], 2.3, places=0)
def test_copy_ECMData_LC(self): store_file = os.path.join(self.temp_dir, 'test_copy_ECMData_LC.pickle') output_stream = StringIO() parser = kc.create_parser() args = parser.parse_args(['-m', self._find_file('hasep1.yaml'), '-p', 'ECMData', self._find_file('copy.c'), '-D', 'N', '1000000', '-vvv', '--unit=cy/CL', '--cache-predictor=LC', '--store', store_file]) kc.check_arguments(args, parser) kc.run(parser, args, output_file=output_stream) with open(store_file, 'rb') as f: results = pickle.load(f) # Output of first result: ecmd = results['copy.c'][((sympy.var('N'), 1000000),)]['ECMData'] # 2 arrays * 1000000 doubles/array * 8 Bytes/double ~ 15MB # -> L3 assert_relativly_equal(ecmd['L2'], 6, 0.05) assert_relativly_equal(ecmd['L3'], 6, 0.05) self.assertAlmostEqual(ecmd['MEM'], 0, places=0)
def test_2d5pt_ECMCPU(self): store_file = os.path.join(self.temp_dir, 'test_2d5pt_ECMCPU.pickle') output_stream = StringIO() parser = kc.create_parser() args = parser.parse_args([ '-m', self._find_file('phinally_gcc.yaml'), '-p', 'ECMCPU', self._find_file('2d-5pt.c'), '-D', 'N', '2000', '-D', 'M', '1000', '-vvv', '--unit=cy/CL', '--compiler=gcc', '--store', store_file ]) kc.check_arguments(args, parser) kc.run(parser, args, output_file=output_stream) results = pickle.load(open(store_file, 'rb')) # Check if results contains correct kernel self.assertEqual(list(results), ['2d-5pt.c']) # Check for correct variations of constants six.assertCountEqual( self, [sorted(map(str, r)) for r in results['2d-5pt.c']], [ sorted(map(str, r)) for r in [((sympy.var('M'), 1000), (sympy.var('N'), 2000))] ]) # Output of first result: result = list(results['2d-5pt.c'].values())[0] six.assertCountEqual(self, result, ['ECMCPU']) ecmd = result['ECMCPU'] self.assertAlmostEqual(ecmd['T_OL'], 12, places=1) self.assertAlmostEqual(ecmd['T_nOL'], 10, places=1)
def test_sclar_product_ECMData(self): store_file = os.path.join(self.temp_dir, 'test_scalar_product_ECMData.pickle') output_stream = StringIO() parser = kc.create_parser() args = parser.parse_args([ '-m', self._find_file('HaswellEP_E5-2695v3.yml'), '-p', 'ECMData', self._find_file('scalar_product.c'), '-D', 'N', '10000', '-vvv', '--store', store_file ]) kc.check_arguments(args, parser) kc.run(parser, args, output_file=output_stream) with open(store_file, 'rb') as f: results = pickle.load(f) # Output of first result: ecmd = results['scalar_product.c'][((sympy.var('N'), 10000), )]['ECMData'] # 2 Misses in L1, since sizeof(a)+sizeof(b) = 156kB > L1 assert_relativly_equal(ecmd['L2'], 2, 0.05) self.assertAlmostEqual(ecmd['L3'], 0.0, places=2) self.assertAlmostEqual(ecmd['MEM'], 0.0, places=2)
def test_2d5pt_ECM(self): store_file = os.path.join(self.temp_dir, 'test_2d5pt_ECM.pickle') parser = kc.create_parser() args = parser.parse_args([ '-m', self._find_file('SandyBridgeEP_E5-2680.yml'), '-p', 'ECM', self._find_file('2d-5pt.c'), '-D', 'N', '2000', '-D', 'M', '1000', '-vvv', '--compiler=gcc', '--unit=cy/CL', '--store', store_file ]) kc.check_arguments(args, parser) kc.run(parser, args, output_file=sys.stdout) with open(store_file, 'rb') as f: results = pickle.load(f) # Output of first result: result = next(iter(results.values())) # 2 * 2000*1000 * 8 = 31MB # -> no full caching # applying layer-conditions: # 3 * 2000 * 8 ~ 47kB # -> layer-condition in L2 assertRelativlyEqual(result['T_comp'], 11, 0.2) assertRelativlyEqual(result['T_RegL1'], 8, 0.2) assertRelativlyEqual(result['L2'], 10, 0.05) assertRelativlyEqual(result['L3'], 6, 0.05) assertRelativlyEqual(result['MEM'], 13, 0.05)
def test_2d5pt_ECMCPU(self): store_file = os.path.join(self.temp_dir, 'test_2d5pt_ECMCPU.pickle') output_stream = StringIO() parser = kc.create_parser() args = parser.parse_args([ '-m', self._find_file('SandyBridgeEP_E5-2680.yml'), '-p', 'ECMCPU', self._find_file('2d-5pt.c'), '-D', 'N', '2000', '-D', 'M', '1000', '-vvv', '--unit=cy/CL', '--compiler=gcc', '--store', store_file ]) kc.check_arguments(args, parser) kc.run(parser, args, output_file=output_stream) with open(store_file, 'rb') as f: results = pickle.load(f) # Check if results contains correct kernel self.assertEqual(list(results), ['2d-5pt.c']) # Check for correct variations of constants self.assertCountEqual( [sorted(map(str, r)) for r in results['2d-5pt.c']], [ sorted(map(str, r)) for r in [((sympy.var('M'), 1000), (sympy.var('N'), 2000))] ]) # Output of first result: result = list(results['2d-5pt.c'].values())[0] self.assertCountEqual(result, ['ECMCPU']) ecmd = result['ECMCPU'] assert_relativly_equal(ecmd['T_comp'], 11, 0.2) assert_relativly_equal(ecmd['T_RegL1'], 8, 0.2)
def test_2d5pt_ECMCPU(self): store_file = os.path.join(self.temp_dir, 'test_2d5pt_ECMCPU.pickle') output_stream = StringIO() parser = kc.create_parser() args = parser.parse_args(['-m', self._find_file('phinally_gcc.yaml'), '-p', 'ECMCPU', self._find_file('2d-5pt.c'), '-D', 'N', '2000', '-D', 'M', '1000', '-vvv', '--unit=cy/CL', '--store', store_file]) kc.check_arguments(args, parser) kc.run(parser, args, output_file=output_stream) results = pickle.load(open(store_file, 'rb')) # Check if results contains correct kernel self.assertEqual(list(results), ['2d-5pt.c']) # Check for correct variations of constants six.assertCountEqual(self, [sorted(r) for r in results['2d-5pt.c']], [sorted(r) for r in [(('M', 1000), ('N', 2000))]]) # Output of first result: result = list(results['2d-5pt.c'].values())[0] six.assertCountEqual(self, result, ['ECMCPU']) ecmd = result['ECMCPU'] self.assertAlmostEqual(ecmd['T_OL'], 24.8, places=1) self.assertAlmostEqual(ecmd['T_nOL'], 20, places=1)
def test_2d5pt_Roofline(self): store_file = os.path.join(self.temp_dir, 'test_2d5pt_Roofline.pickle') output_stream = StringIO() parser = kc.create_parser() args = parser.parse_args(['-m', self._find_file('phinally_gcc.yaml'), '-p', 'Roofline', self._find_file('2d-5pt.c'), '-D', 'N', '1024-4096:3log2', '-D', 'M', '50', '-vvv', '--store', store_file]) kc.check_arguments(args, parser) kc.run(parser, args, output_file=output_stream) results = pickle.load(open(store_file, 'rb')) # Check if results contains correct kernel self.assertEqual(list(results), ['2d-5pt.c']) # Check for correct variations of constants six.assertCountEqual(self, [sorted(r) for r in results['2d-5pt.c']], [sorted(r) for r in [ (('M', 50), ('N', 1024)), (('M', 50), ('N', 2048)), (('M', 50), ('N', 4096))]]) # Output of first result: result = results['2d-5pt.c'][[k for k in results['2d-5pt.c'] if ('N', 4096) in k][0]] six.assertCountEqual(self, result, ['Roofline']) roofline = result['Roofline'] self.assertAlmostEqual(roofline['min performance'], 2900000000.0, places=0) self.assertEqual(roofline['bottleneck level'], 3)
def test_2d5pt_Roofline(self): store_file = os.path.join(self.temp_dir, 'test_2d5pt_Roofline.pickle') output_stream = StringIO() parser = kc.create_parser() args = parser.parse_args(['-m', self._find_file('phinally_gcc.yaml'), '-p', 'Roofline', self._find_file('2d-5pt.c'), '-D', 'N', '1024-4096:3log2', '-D', 'M', '50', '-vvv', '--store', store_file]) kc.check_arguments(args, parser) kc.run(parser, args, output_file=output_stream) results = pickle.load(open(store_file, 'rb')) # Check if results contains correct kernel self.assertEqual(list(results), ['2d-5pt.c']) # Check for correct variations of constants six.assertCountEqual(self, [sorted(map(str, r)) for r in results['2d-5pt.c']], [sorted(map(str, r)) for r in [ ((sympy.var('M'), 50), (sympy.var('N'), 1024)), ((sympy.var('M'), 50), (sympy.var('N'), 2048)), ((sympy.var('M'), 50), (sympy.var('N'), 4096))]]) # Output of first result: result = results['2d-5pt.c'][[k for k in results['2d-5pt.c'] if (sympy.var('N'), 4096) in k][0]] six.assertCountEqual(self, result, ['Roofline']) roofline = result['Roofline'] self.assertAlmostEqual(roofline['min performance'], 5802500000.0, places=0) self.assertEqual(roofline['bottleneck level'], 2) expected_btlncks = [{u'arithmetic intensity': 0.08333333333333333, u'bandwidth': PrefixedUnit(122.97, u'G', u'B/s'), u'bw kernel': 'copy', u'level': u'CPU-L1', u'performance': PrefixedUnit(10247500000.0, u'', u'FLOP/s')}, {u'arithmetic intensity': 0.1, u'bandwidth': PrefixedUnit(61.92, u'G', u'B/s'), u'bw kernel': 'copy', u'level': u'L1-L2', u'performance': PrefixedUnit(6192000000.0, u'', u'FLOP/s')}, {u'arithmetic intensity': 0.16666666666666666, u'bandwidth': PrefixedUnit(34815.0, u'M', u'B/s'), u'bw kernel': 'copy', u'level': u'L2-L3', u'performance': PrefixedUnit(5802500000.0, u'', u'FLOP/s')}, {u'arithmetic intensity': 0.5, u'bandwidth': PrefixedUnit(12.01, u'G', u'B/s'), u'bw kernel': 'load', u'level': u'L3-MEM', u'performance': PrefixedUnit(6005000000.0, u'', u'FLOP/s')}] for i, btlnck in enumerate(expected_btlncks): for k,v in btlnck.items(): self.assertEqual(roofline['mem bottlenecks'][i][k], v)
def test_2d5pt_Roofline(self): store_file = os.path.join(self.temp_dir, 'test_2d5pt_Roofline.pickle') output_stream = StringIO() parser = kc.create_parser() args = parser.parse_args(['-m', self._find_file('phinally_gcc.yaml'), '-p', 'Roofline', self._find_file('2d-5pt.c'), '-D', 'N', '1024-4096:3log2', '-D', 'M', '50', '-vvv', '--store', store_file]) kc.check_arguments(args, parser) kc.run(parser, args, output_file=output_stream) results = pickle.load(open(store_file, 'rb')) # Check if results contains correct kernel self.assertEqual(list(results), ['2d-5pt.c']) # Check for correct variations of constants six.assertCountEqual(self, [sorted(map(str, r)) for r in results['2d-5pt.c']], [sorted(map(str, r)) for r in [ ((sympy.var('M'), 50), (sympy.var('N'), 1024)), ((sympy.var('M'), 50), (sympy.var('N'), 2048)), ((sympy.var('M'), 50), (sympy.var('N'), 4096))]]) # Output of first result: result = results['2d-5pt.c'][[k for k in results['2d-5pt.c'] if (sympy.var('N'), 4096) in k][0]] six.assertCountEqual(self, result, ['Roofline']) roofline = result['Roofline'] self.assertAlmostEqual(roofline['min performance'], 5802500000.0, places=0) self.assertEqual(roofline['bottleneck level'], 2) expected_btlncks = [{u'arithmetic intensity': 0.11764705882352941, u'bandwidth': PrefixedUnit(122.97, u'G', u'B/s'), u'bw kernel': 'copy', u'level': u'L1', u'performance': PrefixedUnit(14467058823.529411, u'', u'FLOP/s')}, {u'arithmetic intensity': 0.1, u'bandwidth': PrefixedUnit(61.92, u'G', u'B/s'), u'bw kernel': 'copy', u'level': u'L2', u'performance': PrefixedUnit(6192000000.0, u'', u'FLOP/s')}, {u'arithmetic intensity': 0.16666666666666666, u'bandwidth': PrefixedUnit(34815.0, u'M', u'B/s'), u'bw kernel': 'copy', u'level': u'L3', u'performance': PrefixedUnit(5802500000.0, u'', u'FLOP/s')}, {u'arithmetic intensity': float(0.5), u'bandwidth': PrefixedUnit(12.01, u'G', u'B/s'), u'bw kernel': 'load', u'level': u'MEM', u'performance': PrefixedUnit(6005000000.0, u'', u'FLOP/s')}] for i, btlnck in enumerate(expected_btlncks): for k,v in btlnck.items(): self.assertEqual(roofline['mem bottlenecks'][i][k], v)
def test_2d5pt_Benchmark(self): store_file = os.path.join(self.temp_dir, 'test_2d5pt_Benchmark.pickle') output_stream = StringIO() # patch environment to include dummy likwid environ_orig = os.environ os.environ['PATH'] = self._find_file( 'dummy_likwid') + ':' + os.environ['PATH'] os.environ['LIKWID_LIB'] = '' os.environ['LIKWID_INCLUDE'] = '-I' + self._find_file( 'dummy_likwid/include') parser = kc.create_parser() args = parser.parse_args([ '-m', self._find_file('SandyBridgeEP_E5-2680.yml'), '-p', 'Benchmark', '--ignore-warnings', self._find_file('2d-5pt.c'), '-D', 'N', '1000', '-D', 'M', '1000', '-vvv', '--compiler=gcc', '--store', store_file ]) kc.check_arguments(args, parser) kc.run(parser, args, output_file=output_stream) # restore environment os.environ = environ_orig with open(store_file, 'rb') as f: results = pickle.load(f) # Check if results contains correct kernel self.assertEqual(list(results), ['2d-5pt.c']) # Check for correct variations of constants self.assertCountEqual( [sorted(map(str, r)) for r in results['2d-5pt.c']], [ sorted(map(str, r)) for r in [((sympy.var('M'), 1000), (sympy.var('N'), 1000))] ]) # Output of first result: result = list(results['2d-5pt.c'].values())[0] self.assertCountEqual(result, ['Benchmark']) roofline = result['Benchmark'] correct_results = { 'Iterations per repetition': 996004, 'MEM BW [MByte/s]': 272.7272, 'MEM volume (per repetition) [B]': 252525.2, 'Performance [MFLOP/s]': 32.27, 'Performance [MIt/s]': 8.07, 'Performance [MLUP/s]': 8.07, 'Runtime (per cacheline update) [cy/CL]': 2677.34, 'Runtime (per repetition) [s]': 0.123456 } for k, v in correct_results.items(): self.assertAlmostEqual(roofline[k], v, places=1)
def test_kernel_requirements(self): output_stream = StringIO() parser = kc.create_parser() args = parser.parse_args(['-m', self._find_file('phinally_gcc.yaml'), '-p', 'LC', self._find_file('2d-5pt-unrolled.c')]) kc.check_arguments(args, parser) with self.assertRaises(ValueError) as cm: kc.run(parser, args, output_file=output_stream)
def test_2d5pt_Benchmark(self): store_file = os.path.join(self.temp_dir, 'test_2d5pt_Benchmark.pickle') output_stream = StringIO() # patch environment to include dummy likwid environ_orig = os.environ os.environ['PATH'] = self._find_file('dummy_likwid') + ':' + os.environ['PATH'] os.environ['LIKWID_LIB'] = '' os.environ['LIKWID_INCLUDE'] = '-I' + self._find_file('dummy_likwid/include') parser = kc.create_parser() args = parser.parse_args(['-m', self._find_file('phinally_gcc.yaml'), '-p', 'Benchmark', '--ignore-warnings', self._find_file('2d-5pt.c'), '-D', 'N', '1000', '-D', 'M', '1000', '-vvv', '--compiler=gcc', '--store', store_file]) kc.check_arguments(args, parser) kc.run(parser, args, output_file=output_stream) # restore environment os.environ = environ_orig with open(store_file, 'rb') as f: results = pickle.load(f) # Check if results contains correct kernel self.assertEqual(list(results), ['2d-5pt.c']) # Check for correct variations of constants self.assertCountEqual( [sorted(map(str, r)) for r in results['2d-5pt.c']], [sorted(map(str, r)) for r in [((sympy.var('M'), 1000), (sympy.var('N'), 1000))]]) # Output of first result: result = list(results['2d-5pt.c'].values())[0] self.assertCountEqual(result, ['Benchmark']) roofline = result['Benchmark'] correct_results = { 'Iterations per repetition': 996004, 'MEM BW [MByte/s]': 272.7272, 'MEM volume (per repetition) [B]': 252525.2, 'Performance [MFLOP/s]': 32.27, 'Performance [MIt/s]': 8.07, 'Performance [MLUP/s]': 8.07, 'Runtime (per cacheline update) [cy/CL]': 2677.34, 'Runtime (per repetition) [s]': 0.123456} for k, v in correct_results.items(): self.assertAlmostEqual(roofline[k], v, places=1)
def test_2d5pt_pragma(self): parser = kc.create_parser() args = parser.parse_args([ '-m', self._find_file('SandyBridgeEP_E5-2680.yml'), '-p', 'ECMData', self._find_file('2d-5pt_pragma.c'), '-D', 'N', '1000', '-D', 'M', '50' ]) kc.check_arguments(args, parser) kc.run(parser, args, output_file=sys.stdout)
def test_2d5pt_pragma(self): output_stream = StringIO() parser = kc.create_parser() args = parser.parse_args(['-m', self._find_file('phinally_gcc.yaml'), '-p', 'ECMData', self._find_file('2d-5pt_pragma.c'), '-D', 'N', '1000', '-D', 'M', '50']) kc.check_arguments(args, parser) kc.run(parser, args, output_file=output_stream)
def test_argument_parser_asm_block(self): # valid --asm-block parser = kc.create_parser() args = parser.parse_args([ '-m', self._find_file('SandyBridgeEP_E5-2680.yml'), '-p', 'Benchmark', self._find_file('2d-5pt.c'), '--asm-block', 'auto' ]) kc.check_arguments(args, parser) # valid --asm-block parser = kc.create_parser() args = parser.parse_args([ '-m', self._find_file('SandyBridgeEP_E5-2680.yml'), '-p', 'Benchmark', self._find_file('2d-5pt.c'), '--asm-block', 'manual' ]) kc.check_arguments(args, parser) # valid --asm-block parser = kc.create_parser() args = parser.parse_args([ '-m', self._find_file('SandyBridgeEP_E5-2680.yml'), '-p', 'Benchmark', self._find_file('2d-5pt.c'), '--asm-block', '23' ]) kc.check_arguments(args, parser) # invalid --asm-block parser = kc.create_parser() args = parser.parse_args([ '-m', self._find_file('SandyBridgeEP_E5-2680.yml'), '-p', 'Benchmark', self._find_file('2d-5pt.c'), '--asm-block', 'foobar' ]) with self.assertRaises(SystemExit) as cm: kc.check_arguments(args, parser) args.code_file.close() args.machine.close() self.assertEqual(cm.exception.code, 2)
def test_constantdim(self): store_file = os.path.join(self.temp_dir, 'test_constantdim_LC.pickle') output_stream = StringIO() parser = kc.create_parser() args = parser.parse_args(['-m', self._find_file('phinally_gcc.yaml'), '-p', 'LC', self._find_file('constantdim.c'), '-D', 'N', '1224', '-D', 'M', '1224', '-vvv', '--store', store_file]) kc.check_arguments(args, parser) kc.run(parser, args, output_file=output_stream) with open(store_file, 'rb') as f: results = pickle.load(f) result = next(iter(results['constantdim.c'].values()))['LC'] N = sympy.var('N') result_expected = { 'dimensions': { 1: { 'slices_sum': 2, 'slices_count': 6, 'caches': { 'L1': {'lt': True}, 'L2': {'lt': True}, 'L3': {'lt': True}, }, 'cache_requirement_bytes': 64, }, 2: { 'slices_sum': 2*N, 'slices_count': 4, 'caches': { 'L1': {'lt': 48*N - 32 <= 32768}, 'L2': {'lt': 48*N - 32 <= 262144}, 'L3': {'lt': 48*N - 32 <= 20971520}, }, 'cache_requirement_bytes': 48*N - 32, }, } } # Iterate over expected results and validate with generated results stack = [((k,), v) for k, v in result_expected.items()] while stack: key_path, value = stack.pop() if isinstance(value, dict): stack.extend([(key_path + (k,), v) for k, v in value.items()]) else: self.assertEqual(value, recursive_dict_get(result, key_path), msg="at key_path={}".format(key_path))
def test_2d5pt_ECMData(self): store_file = os.path.join(self.temp_dir, 'test_2d5pt_ECMData.pickle') output_stream = StringIO() parser = kc.create_parser() args = parser.parse_args([ '-m', self._find_file('phinally_gcc.yaml'), '-p', 'ECMData', self._find_file('2d-5pt.c'), '-D', 'N', '10000-100000:2log10', '-D', 'N', '1000', '-D', 'M', '50', '-vvv', '--store', store_file ]) kc.check_arguments(args, parser) kc.run(parser, args, output_file=output_stream) results = pickle.load(open(store_file, 'rb')) # Check if results contains correct kernel self.assertEqual(list(results), ['2d-5pt.c']) # Check for correct variations of constants six.assertCountEqual(self, [ sorted(map(str, r)) for r in results['2d-5pt.c'] ], [ sorted(map(str, r)) for r in [((sympy.var('M'), 50), (sympy.var('N'), 1000)), ((sympy.var('M'), 50), (sympy.var('N'), 10000)), ((sympy.var('M'), 50), (sympy.var('N'), 100000))] ]) # Output of first result: result = results['2d-5pt.c'][[ k for k in results['2d-5pt.c'] if (sympy.var('N'), 1000) in k ][0]] six.assertCountEqual(self, result, ['ECMData']) ecmd = result['ECMData'] # 2 arrays * 1000*50 doubles/array * 8 Bytes/double = 781kB # -> fully cached in L3 # FIXME 3.9cy in L3-MEM should be 0, but full caching is not respected in stores atm self.assertAlmostEqual(ecmd['L1-L2'], 6, places=1) self.assertAlmostEqual(ecmd['L2-L3'], 6, places=1) self.assertAlmostEqual(ecmd['L3-MEM'], 3.9, places=0) # FIXME should be 0.0
def test_2d5pt_ECMData_LC(self): store_file = os.path.join(self.temp_dir, 'test_2d5pt_ECMData.pickle') output_stream = StringIO() parser = kc.create_parser() args = parser.parse_args([ '-m', self._find_file('SandyBridgeEP_E5-2680.yml'), '-p', 'ECMData', self._find_file('2d-5pt.c'), '-D', 'N', '10000-100000:2log10', '-D', 'N', '1000', '-D', 'M', '50', '-vvv', '--cache-predictor=LC', '--store', store_file ]) kc.check_arguments(args, parser) kc.run(parser, args, output_file=output_stream) with open(store_file, 'rb') as f: results = pickle.load(f) # Check if results contains correct kernel self.assertEqual(list(results), ['2d-5pt.c']) # Check for correct variations of constants self.assertCountEqual([ sorted(map(str, r)) for r in results['2d-5pt.c'] ], [ sorted(map(str, r)) for r in [((sympy.var('M'), 50), (sympy.var('N'), 1000)), ((sympy.var('M'), 50), (sympy.var('N'), 10000)), ((sympy.var('M'), 50), (sympy.var('N'), 100000))] ]) # Output of first result: result = results['2d-5pt.c'][[ k for k in results['2d-5pt.c'] if (sympy.var('N'), 1000) in k ][0]] self.assertCountEqual(result, ['ECMData']) ecmd = result['ECMData'] # 2 arrays * 1000*50 doubles/array * 8 Bytes/double = 781kB # -> fully cached in L3 assert_relativly_equal(ecmd['L2'], 6, 0.05) assert_relativly_equal(ecmd['L3'], 6, 0.05) self.assertAlmostEqual(ecmd['MEM'], 0.0, places=2)
def test_2d5pt_ECMData_SIM(self): store_file = os.path.join(self.temp_dir, 'test_2d5pt_ECMData.pickle') parser = kc.create_parser() args = parser.parse_args([ '-m', self._find_file('SandyBridgeEP_E5-2680.yml'), '-p', 'ECMData', self._find_file('2d-5pt.c'), '-D', 'N', '10000-100000:2log10', '-D', 'N', '1000', '-D', 'M', '50', '-vvv', '--store', store_file ]) kc.check_arguments(args, parser) kc.run(parser, args, output_file=sys.stdout) with open(store_file, 'rb') as f: results = pickle.load(f) # Check for correct variations of constants self.assertEqual(len(results), 3) # Check if results contains correct kernel and variations of constants for key in results: d = dict(key) self.assertEqual(d['code_file'].split('/')[-1], '2d-5pt.c') self.assertEqual(d['machine'].split('/')[-1], 'SandyBridgeEP_E5-2680.yml') self.assertEqual(d['pmodel'], 'ECMData') self.assertTrue( any([('define', (('M', 50), ('N', 1000))) in k for k in results])) self.assertTrue( any([('define', (('M', 50), ('N', 10000))) in k for k in results])) self.assertTrue( any([('define', (('M', 50), ('N', 100000))) in k for k in results])) # Output of first result: key = [ k for k in results if ('define', (('M', 50), ('N', 1000))) in k ][0] result = results[key] # 2 arrays * 1000*50 doubles/array * 8 Bytes/double = 781kB # -> fully cached in L3 assertRelativlyEqual(result['L2'], 6, 0.05) assertRelativlyEqual(result['L3'], 6, 0.05) self.assertAlmostEqual(result['MEM'], 0.0, places=3)
def test_2d5pt_Benchmark(self): store_file = os.path.join(self.temp_dir, 'test_2d5pt_Benchmark.pickle') # patch environment to include dummy likwid environ_orig = os.environ os.environ['PATH'] = self._find_file( 'dummy_likwid') + ':' + os.environ['PATH'] os.environ['LIKWID_LIB'] = '' os.environ['LIKWID_INCLUDE'] = '-I' + self._find_file( 'dummy_likwid/include') parser = kc.create_parser() args = parser.parse_args([ '-m', self._find_file('SandyBridgeEP_E5-2680.yml'), '-p', 'Benchmark', '--ignore-warnings', self._find_file('2d-5pt.c'), '-D', 'N', '1000', '-D', 'M', '1000', '--no-phenoecm', '-vvv', '--compiler=gcc', '--store', store_file ]) kc.check_arguments(args, parser) kc.run(parser, args, output_file=sys.stdout) # restore environment os.environ = environ_orig with open(store_file, 'rb') as f: results = pickle.load(f) # Output of first result: result = next(iter(results.values())) correct_results = { 'Iterations per repetition': 996004, 'MEM BW [MByte/s]': 272.7272, 'MEM volume (per repetition) [B]': 252525.2, 'Performance [MFLOP/s]': 32.27, 'Performance [MIt/s]': 8.07, 'Performance [MLUP/s]': 8.07, 'Runtime (per cacheline update) [cy/CL]': 2677.34, 'Runtime (per repetition) [s]': 0.123456 } for k, v in correct_results.items(): self.assertAlmostEqual(result[k], v, places=1)
def test_2d5pt_ECM(self): store_file = os.path.join(self.temp_dir, 'test_2d5pt_ECM.pickle') output_stream = StringIO() parser = kc.create_parser() args = parser.parse_args(['-m', self._find_file('phinally_gcc.yaml'), '-p', 'ECM', self._find_file('2d-5pt.c'), '-D', 'N', '2000', '-D', 'M', '1000', '-vvv', '--compiler=gcc', '--unit=cy/CL', '--store', store_file]) kc.check_arguments(args, parser) kc.run(parser, args, output_file=output_stream) with open(store_file, 'rb') as f: results = pickle.load(f) # Check if results contains correct kernel self.assertEqual(list(results), ['2d-5pt.c']) # Check for correct variations of constants self.assertCountEqual( [sorted(map(str, r)) for r in results['2d-5pt.c']], [sorted(map(str, r)) for r in [((sympy.var('M'), 1000), (sympy.var('N'), 2000))]]) # Output of first result: result = list(results['2d-5pt.c'].values())[0] self.assertCountEqual(result, ['ECM']) ecmd = result['ECM'] # 2 * 2000*1000 * 8 = 31MB # -> no full caching # applying layer-conditions: # 3 * 2000 * 8 ~ 47kB # -> layer-condition in L2 assert_relativly_equal(ecmd['T_OL'], 11, 0.2) assert_relativly_equal(ecmd['T_nOL'], 8, 0.2) assert_relativly_equal(ecmd['L2'], 10, 0.05) assert_relativly_equal(ecmd['L3'], 6, 0.05) assert_relativly_equal(ecmd['MEM'], 13, 0.05)
def test_2d5pt_ECM(self): store_file = os.path.join(self.temp_dir, 'test_2d5pt_ECM.pickle') output_stream = StringIO() parser = kc.create_parser() args = parser.parse_args(['-m', self._find_file('phinally_gcc.yaml'), '-p', 'ECM', self._find_file('2d-5pt.c'), '-D', 'N', '2000', '-D', 'M', '1000', '-vvv', '--compiler=gcc', '--unit=cy/CL', '--store', store_file]) kc.check_arguments(args, parser) kc.run(parser, args, output_file=output_stream) with open(store_file, 'rb') as f: results = pickle.load(f) # Check if results contains correct kernel self.assertEqual(list(results), ['2d-5pt.c']) # Check for correct variations of constants self.assertCountEqual( [sorted(map(str, r)) for r in results['2d-5pt.c']], [sorted(map(str, r)) for r in [((sympy.var('M'), 1000), (sympy.var('N'), 2000))]]) # Output of first result: result = list(results['2d-5pt.c'].values())[0] self.assertCountEqual(result, ['ECM']) ecmd = result['ECM'] # 2 * 2000*1000 * 8 = 31MB # -> no full caching # applying layer-conditions: # 3 * 2000 * 8 ~ 47kB # -> layer-condition in L2 self.assertAlmostEqual(ecmd['T_OL'], 12, places=1) self.assertAlmostEqual(ecmd['T_nOL'], 10, places=1) self.assertAlmostEqual(ecmd['L2'], 10, places=1) self.assertAlmostEqual(ecmd['L3'], 6, places=1) self.assertAlmostEqual(ecmd['MEM'], 13, places=0)
def test_2d5pt_ECMData_LC(self): store_file = os.path.join(self.temp_dir, 'test_2d5pt_ECMData.pickle') output_stream = StringIO() parser = kc.create_parser() args = parser.parse_args(['-m', self._find_file('phinally_gcc.yaml'), '-p', 'ECMData', self._find_file('2d-5pt.c'), '-D', 'N', '10000-100000:2log10', '-D', 'N', '1000', '-D', 'M', '50', '-vvv', '--cache-predictor=LC', '--store', store_file]) kc.check_arguments(args, parser) kc.run(parser, args, output_file=output_stream) with open(store_file, 'rb') as f: results = pickle.load(f) # Check if results contains correct kernel self.assertEqual(list(results), ['2d-5pt.c']) # Check for correct variations of constants self.assertCountEqual( [sorted(map(str, r)) for r in results['2d-5pt.c']], [sorted(map(str, r)) for r in [ ((sympy.var('M'), 50), (sympy.var('N'), 1000)), ((sympy.var('M'), 50), (sympy.var('N'), 10000)), ((sympy.var('M'), 50), (sympy.var('N'), 100000))]]) # Output of first result: result = results['2d-5pt.c'][ [k for k in results['2d-5pt.c'] if (sympy.var('N'), 1000) in k][0]] self.assertCountEqual(result, ['ECMData']) ecmd = result['ECMData'] # 2 arrays * 1000*50 doubles/array * 8 Bytes/double = 781kB # -> fully cached in L3 assert_relativly_equal(ecmd['L2'], 6, 0.05) assert_relativly_equal(ecmd['L3'], 6, 0.05) self.assertAlmostEqual(ecmd['MEM'], 0.0, places=2)
def test_2d5pt_ECMCPU(self): store_file = os.path.join(self.temp_dir, 'test_2d5pt_ECMCPU.pickle') parser = kc.create_parser() args = parser.parse_args([ '-m', self._find_file('SandyBridgeEP_E5-2680.yml'), '-p', 'ECMCPU', self._find_file('2d-5pt.c'), '-D', 'N', '2000', '-D', 'M', '1000', '-vvv', '--unit=cy/CL', '--compiler=gcc', '--store', store_file ]) kc.check_arguments(args, parser) kc.run(parser, args, output_file=sys.stdout) with open(store_file, 'rb') as f: results = pickle.load(f) # Output of first result: result = next(iter(results.values())) assertRelativlyEqual(result['T_comp'], 11, 0.2) assertRelativlyEqual(result['T_RegL1'], 8, 0.2)
def test_2d5pt_ECMData(self): store_file = os.path.join(self.temp_dir, 'test_2d5pt_ECMData.pickle') output_stream = StringIO() parser = kc.create_parser() args = parser.parse_args(['-m', self._find_file('phinally_gcc.yaml'), '-p', 'ECMData', self._find_file('2d-5pt.c'), '-D', 'N', '10000-100000:2log10', '-D', 'N', '1000', '-D', 'M', '50', '-vvv', '--store', store_file]) kc.check_arguments(args, parser) kc.run(parser, args, output_file=output_stream) results = pickle.load(open(store_file, 'rb')) # Check if results contains correct kernel self.assertEqual(list(results), ['2d-5pt.c']) # Check for correct variations of constants six.assertCountEqual(self, [sorted(map(str, r)) for r in results['2d-5pt.c']], [sorted(map(str, r)) for r in [ ((sympy.var('M'), 50), (sympy.var('N'), 1000)), ((sympy.var('M'), 50), (sympy.var('N'), 10000)), ((sympy.var('M'), 50), (sympy.var('N'), 100000))]]) # Output of first result: result = results['2d-5pt.c'][[k for k in results['2d-5pt.c'] if (sympy.var('N'), 1000) in k][0]] six.assertCountEqual(self, result, ['ECMData']) ecmd = result['ECMData'] # 2 arrays * 1000*50 doubles/array * 8 Bytes/double = 781kB # -> fully cached in L3 # FIXME 3.9cy in L3-MEM should be 0, but full caching is not respected in stores atm self.assertAlmostEqual(ecmd['L1-L2'], 6, places=1) self.assertAlmostEqual(ecmd['L2-L3'], 6, places=1) self.assertAlmostEqual(ecmd['L3-MEM'], 3.9, places=0) # FIXME should be 0.0
def test_copy_ECMData(self): store_file = os.path.join(self.temp_dir, 'test_copy_ECMData.pickle') output_stream = StringIO() parser = kc.create_parser() args = parser.parse_args(['-m', self._find_file('hasep1.yaml'), '-p', 'ECMData', self._find_file('copy.c'), '-D', 'N', '1000000', '-vvv', '--store', store_file]) kc.check_arguments(args, parser) kc.run(parser, args, output_file=output_stream) results = pickle.load(open(store_file, 'rb')) # Output of first result: ecmd = results['copy.c'][(('N', 1000000),)]['ECMData'] self.assertAlmostEqual(ecmd['L1-L2'], 6, places=1) self.assertAlmostEqual(ecmd['L2-L3'], 8.31, places=1) self.assertAlmostEqual(ecmd['L3-MEM'], 16.6, places=0)
def test_2d5pt_RooflineIACA(self): store_file = os.path.join(self.temp_dir, 'test_2d5pt_RooflineIACA.pickle') parser = kc.create_parser() args = parser.parse_args([ '-m', self._find_file('SandyBridgeEP_E5-2680.yml'), '-p', 'RooflineIACA', self._find_file('2d-5pt.c'), '-D', 'N', '4000', '-D', 'M', '1000', '-vvv', '--unit=FLOP/s', '--compiler=gcc', '--store', store_file ]) kc.check_arguments(args, parser) kc.run(parser, args, output_file=sys.stdout) with open(store_file, 'rb') as f: results = pickle.load(f) # Output of first result: result = next(iter(results.values())) assertRelativlyEqual(result['min performance']['FLOP/s'], 2900000000.0, 0.05) self.assertEqual(result['bottleneck level'], 3)
def test_sclar_product_ECMData(self): store_file = os.path.join(self.temp_dir, 'test_scalar_product_ECMData.pickle') output_stream = StringIO() parser = kc.create_parser() args = parser.parse_args(['-m', self._find_file('hasep1.yaml'), '-p', 'ECMData', self._find_file('scalar_product.c'), '-D', 'N', '10000', '-vvv', '--store', store_file]) kc.check_arguments(args, parser) kc.run(parser, args, output_file=output_stream) results = pickle.load(open(store_file, 'rb')) # Output of first result: ecmd = results['scalar_product.c'][((sympy.var('N'), 10000),)]['ECMData'] # 2 Misses in L1, since sizeof(a)+sizeof(b) = 156kB > L1 self.assertAlmostEqual(ecmd['L1-L2'], 4, places=1) self.assertAlmostEqual(ecmd['L2-L3'], 0.0, places=1) self.assertAlmostEqual(ecmd['L3-MEM'], 0.0, places=0)
def test_sclar_product_ECMData(self): store_file = os.path.join(self.temp_dir, 'test_scalar_product_ECMData.pickle') parser = kc.create_parser() args = parser.parse_args([ '-m', self._find_file('HaswellEP_E5-2695v3.yml'), '-p', 'ECMData', self._find_file('scalar_product.c'), '-D', 'N', '10000', '-vvv', '--store', store_file ]) kc.check_arguments(args, parser) kc.run(parser, args, output_file=sys.stdout) with open(store_file, 'rb') as f: results = pickle.load(f) # Output of first result: result = next(iter(results.values())) # 2 Misses in L1, since sizeof(a)+sizeof(b) = 156kB > L1 assertRelativlyEqual(result['L2'], 2, 0.05) self.assertAlmostEqual(result['L3'], 0.0, places=2) self.assertAlmostEqual(result['MEM'], 0.0, places=2)
def test_copy_ECMData_LC(self): store_file = os.path.join(self.temp_dir, 'test_copy_ECMData_LC.pickle') parser = kc.create_parser() args = parser.parse_args([ '-m', self._find_file('HaswellEP_E5-2695v3.yml'), '-p', 'ECMData', self._find_file('copy.c'), '-D', 'N', '1000000', '-vvv', '--unit=cy/CL', '--cache-predictor=LC', '--store', store_file ]) kc.check_arguments(args, parser) kc.run(parser, args, output_file=sys.stdout) with open(store_file, 'rb') as f: results = pickle.load(f) # Output of first result: result = next(iter(results.values())) # 2 arrays * 1000000 doubles/array * 8 Bytes/double ~ 15MB # -> L3 assertRelativlyEqual(result['L2'], 3, 0.05) assertRelativlyEqual(result['L3'], 6, 0.05) self.assertAlmostEqual(result['MEM'], 0, places=0)
def test_2d5pt_Roofline(self): store_file = os.path.join(self.temp_dir, 'test_2d5pt_Roofline.pickle') parser = kc.create_parser() args = parser.parse_args([ '-m', self._find_file('SandyBridgeEP_E5-2680.yml'), '-p', 'Roofline', self._find_file('2d-5pt.c'), '-D', 'N', '1024-4096:3log2', '-D', 'M', '50', '-vvv', '--store', store_file ]) kc.check_arguments(args, parser) kc.run(parser, args, output_file=sys.stdout) with open(store_file, 'rb') as f: results = pickle.load(f) # Check for correct variations of constants self.assertEqual(len(results), 3) # Check if results contains correct kernel and some other infoormation key = [ k for k in results if ('define', (('M', 50), ('N', 4096))) in k ][0] key_dict = dict(key) self.assertEqual(key_dict['pmodel'], 'Roofline') # Output of first result: result = results[key] assertRelativlyEqual(result['min performance']['FLOP/s'], 4720000000.0, 0.01) self.assertEqual(result['bottleneck level'], 1) expected_btlncks = [{ 'arithmetic intensity': 0.029411764705882353, 'bandwidth': PrefixedUnit(84.07, u'G', u'B/s'), 'bw kernel': 'load', 'level': u'L1', 'performance': PrefixedUnit(9.89, u'G', u'FLOP/s') }, { 'arithmetic intensity': 0.025, 'bandwidth': PrefixedUnit(47.24, u'G', u'B/s'), 'bw kernel': 'triad', 'level': u'L2', 'performance': PrefixedUnit(4.72, u'G', u'FLOP/s') }, { 'arithmetic intensity': 0.041, 'bandwidth': PrefixedUnit(32.9, 'G', 'B/s'), 'bw kernel': 'copy', 'level': u'L3', 'performance': PrefixedUnit(5.33, u'G', u'FLOP/s') }, { 'arithmetic intensity': float('inf'), 'bandwidth': PrefixedUnit(12.01, u'G', u'B/s'), 'bw kernel': 'load', 'level': u'MEM', 'performance': PrefixedUnit(float('inf'), u'', u'FLOP/s') }] for i, btlnck in enumerate(expected_btlncks): for k, v in btlnck.items(): if type(v) is not str: if k == 'performance': assertRelativlyEqual( result['mem bottlenecks'][i][k]['FLOP/s'], v, 0.05) else: assertRelativlyEqual(result['mem bottlenecks'][i][k], v, 0.05) else: self.assertEqual(result['mem bottlenecks'][i][k], v)
def test_constantdim(self): store_file = os.path.join(self.temp_dir, 'test_constantdim_LC.pickle') output_stream = StringIO() parser = kc.create_parser() args = parser.parse_args([ '-m', self._find_file('SandyBridgeEP_E5-2680.yml'), '-p', 'LC', self._find_file('constantdim.c'), '-D', 'N', '1224', '-D', 'M', '1224', '-vvv', '--store', store_file ]) kc.check_arguments(args, parser) kc.run(parser, args, output_file=output_stream) with open(store_file, 'rb') as f: results = pickle.load(f) result = next(iter(results.values())) N, M, j, i = sympy.var('N'), sympy.var('M'), sympy.var('j'), sympy.var( 'i') result_expected = \ {'accesses': {'W': [(j, i), (1, j, i)], 'a': [(j - 1, i), (j, i - 1), (j, i), (j, i + 1), (j + 1, i)], 'b': [(j, i)]}, 'cache': [[{'condition': M*N < 1024, 'evicts': 0, 'hits': 8, 'misses': 0, 'tail': oo}, {'condition': 2*M*N + N <= 2048, 'evicts': 1, 'hits': 5, 'misses': 3, 'tail': 8 * M * N}, {'condition': 3*N <= 2050, 'evicts': 1, 'hits': 4, 'misses': 4, 'tail': 8*N - 8}, {'condition': True, 'evicts': 1, 'hits': 2, 'misses': 6, 'tail': 8}], [{'condition': M*N < 8192, 'evicts': 0, 'hits': 8, 'misses': 0, 'tail': oo}, {'condition': 2*M*N + N <= 16384, 'evicts': 1, 'hits': 5, 'misses': 3, 'tail': 8 * M * N}, {'condition': N <= 5462, 'evicts': 1, 'hits': 4, 'misses': 4, 'tail': 8 * N - 8}, {'condition': True, 'evicts': 1, 'hits': 2, 'misses': 6, 'tail': 8}], [{'condition': M*N < 655360, 'evicts': 0, 'hits': 8, 'misses': 0, 'tail': oo}, {'condition': 2*M*N + N <= 1310720, 'evicts': 1, 'hits': 5, 'misses': 3, 'tail': 8 * M * N}, {'condition': 3*N <= 1310722, 'evicts': 1, 'hits': 4, 'misses': 4, 'tail': 8 * N - 8}, {'condition': True, 'evicts': 1, 'hits': 2, 'misses': 6, 'tail': 8}]], 'destinations': {('b', (j, i))}, 'distances': [oo, oo, oo, M * N, N - 1, N - 1, 1, 1], 'distances_bytes': [oo, oo, oo, 8 * M * N, 8 * N - 8, 8 * N - 8, 8, 8]} # Iterate over expected results and validate with generated results stack = [((k, ), v) for k, v in result_expected.items()] while stack: key_path, value = stack.pop() if isinstance(value, dict): stack.extend([(key_path + (k, ), v) for k, v in value.items()]) if isinstance(value, list): stack.extend([(key_path + (i, ), v) for i, v in enumerate(value)]) else: self.assertEqual(value, recursive_dict_get(result, key_path), msg="at key_path={}".format(key_path))
def test_2d5pt_Roofline(self): store_file = os.path.join(self.temp_dir, 'test_2d5pt_Roofline.pickle') output_stream = StringIO() parser = kc.create_parser() args = parser.parse_args(['-m', self._find_file('phinally_gcc.yaml'), '-p', 'Roofline', self._find_file('2d-5pt.c'), '-D', 'N', '1024-4096:3log2', '-D', 'M', '50', '-vvv', '--store', store_file]) kc.check_arguments(args, parser) kc.run(parser, args, output_file=output_stream) with open(store_file, 'rb') as f: results = pickle.load(f) # Check if results contains correct kernel self.assertEqual(list(results), ['2d-5pt.c']) # Check for correct variations of constants self.assertCountEqual( [sorted(map(str, r)) for r in results['2d-5pt.c']], [sorted(map(str, r)) for r in [ ((sympy.var('M'), 50), (sympy.var('N'), 1024)), ((sympy.var('M'), 50), (sympy.var('N'), 2048)), ((sympy.var('M'), 50), (sympy.var('N'), 4096))]]) # Output of first result: result = results['2d-5pt.c'][ [k for k in results['2d-5pt.c'] if (sympy.var('N'), 4096) in k][0]] self.assertCountEqual(result, ['Roofline']) roofline = result['Roofline'] assert_relativly_equal(roofline['min performance']['FLOP/s'], 5115000000.0, 0.01) self.assertEqual(roofline['bottleneck level'], 1) expected_btlncks = [{'arithmetic intensity': 0.11764705882352941, 'bandwidth': PrefixedUnit(81.61, u'G', u'B/s'), 'bw kernel': 'triad', 'level': u'L1', 'performance': PrefixedUnit(9601176470.588236, u'', u'FLOP/s') }, {'arithmetic intensity': 0.1, 'bandwidth': PrefixedUnit(51.15, u'G', u'B/s'), 'bw kernel': 'triad', 'level': u'L2', 'performance': PrefixedUnit(5115000000.0, u'', u'FLOP/s')}, {'arithmetic intensity': 1.0 / 6.0, 'bandwidth': PrefixedUnit(34815.0, 'M', 'B/s'), 'bw kernel': 'copy', 'level': u'L3', 'performance': PrefixedUnit(5802500000.0, u'', u'FLOP/s')}, {'arithmetic intensity': float('inf'), 'bandwidth': PrefixedUnit(12.01, u'G', u'B/s'), 'bw kernel': 'load', 'level': u'MEM', 'performance': PrefixedUnit(float('inf'), u'', u'FLOP/s')}] for i, btlnck in enumerate(expected_btlncks): for k, v in btlnck.items(): if type(v) is not str: if k == 'performance': assert_relativly_equal(roofline['mem bottlenecks'][i][k]['FLOP/s'], v, 0.05) else: assert_relativly_equal(roofline['mem bottlenecks'][i][k], v, 0.05) else: self.assertEqual(roofline['mem bottlenecks'][i][k], v)
def test_2d5pt_Roofline(self): store_file = os.path.join(self.temp_dir, 'test_2d5pt_Roofline.pickle') output_stream = StringIO() parser = kc.create_parser() args = parser.parse_args([ '-m', self._find_file('SandyBridgeEP_E5-2680.yml'), '-p', 'Roofline', self._find_file('2d-5pt.c'), '-D', 'N', '1024-4096:3log2', '-D', 'M', '50', '-vvv', '--store', store_file ]) kc.check_arguments(args, parser) kc.run(parser, args, output_file=output_stream) with open(store_file, 'rb') as f: results = pickle.load(f) # Check if results contains correct kernel self.assertEqual(list(results), ['2d-5pt.c']) # Check for correct variations of constants self.assertCountEqual([ sorted(map(str, r)) for r in results['2d-5pt.c'] ], [ sorted(map(str, r)) for r in [((sympy.var('M'), 50), ( sympy.var('N'), 1024)), ((sympy.var('M'), 50), (sympy.var('N'), 2048)), ((sympy.var('M'), 50), (sympy.var('N'), 4096))] ]) # Output of first result: result = results['2d-5pt.c'][[ k for k in results['2d-5pt.c'] if (sympy.var('N'), 4096) in k ][0]] self.assertCountEqual(result, ['Roofline']) roofline = result['Roofline'] assert_relativly_equal(roofline['min performance']['FLOP/s'], 5115000000.0, 0.01) self.assertEqual(roofline['bottleneck level'], 1) expected_btlncks = [{ 'arithmetic intensity': 0.11764705882352941, 'bandwidth': PrefixedUnit(81.61, u'G', u'B/s'), 'bw kernel': 'triad', 'level': u'L1', 'performance': PrefixedUnit(9601176470.588236, u'', u'FLOP/s') }, { 'arithmetic intensity': 0.1, 'bandwidth': PrefixedUnit(51.15, u'G', u'B/s'), 'bw kernel': 'triad', 'level': u'L2', 'performance': PrefixedUnit(5115000000.0, u'', u'FLOP/s') }, { 'arithmetic intensity': 1.0 / 6.0, 'bandwidth': PrefixedUnit(34815.0, 'M', 'B/s'), 'bw kernel': 'copy', 'level': u'L3', 'performance': PrefixedUnit(5802500000.0, u'', u'FLOP/s') }, { 'arithmetic intensity': float('inf'), 'bandwidth': PrefixedUnit(12.01, u'G', u'B/s'), 'bw kernel': 'load', 'level': u'MEM', 'performance': PrefixedUnit(float('inf'), u'', u'FLOP/s') }] for i, btlnck in enumerate(expected_btlncks): for k, v in btlnck.items(): if type(v) is not str: if k == 'performance': assert_relativly_equal( roofline['mem bottlenecks'][i][k]['FLOP/s'], v, 0.05) else: assert_relativly_equal( roofline['mem bottlenecks'][i][k], v, 0.05) else: self.assertEqual(roofline['mem bottlenecks'][i][k], v)
def test_3d_7pt(self): store_file = os.path.join(self.temp_dir, 'test_3d7pt_LC.pickle') output_stream = StringIO() parser = kc.create_parser() args = parser.parse_args([ '-m', self._find_file('SandyBridgeEP_E5-2680.yml'), '-p', 'LC', self._find_file('3d-7pt.c'), '-D', 'N', '0', '-D', 'M', '0', '-vvv', '--store', store_file ]) kc.check_arguments(args, parser) kc.run(parser, args, output_file=output_stream) with open(store_file, 'rb') as f: results = pickle.load(f) result = next(iter(results['3d-7pt.c'].values()))['LC'] N, M, i, j, k = sympy.var('N, M, i, j, k') result_expected = { 'accesses': { 'a': [(k - 1, j, i), (k, j - 1, i), (k, j, i - 1), (k, j, i), (k, j, i + 1), (k, j + 1, i), (k + 1, j, i)], 'b': [(k, j, i)], 's': [] }, 'cache': [[{ 'condition': 16 * M * N**2 < 32768, 'evicts': 0, 'hits': 8, 'misses': 0, 'tail': oo }, { 'condition': 32 * N**2 - 16 * N <= 32768, 'evicts': 1, 'hits': 6, 'misses': 2, 'tail': 8 * N**2 - 8 * N }, { 'condition': 48 * N - 32 <= 32768, 'evicts': 1, 'hits': 4, 'misses': 4, 'tail': 8 * N - 8 }, { 'condition': True, 'evicts': 1, 'hits': 2, 'misses': 6, 'tail': 8 }], [{ 'condition': 16 * M * N**2 < 262144, 'evicts': 0, 'hits': 8, 'misses': 0, 'tail': oo }, { 'condition': 32 * N**2 - 16 * N <= 262144, 'evicts': 1, 'hits': 6, 'misses': 2, 'tail': 8 * N**2 - 8 * N }, { 'condition': 48 * N - 32 <= 262144, 'evicts': 1, 'hits': 4, 'misses': 4, 'tail': 8 * N - 8 }, { 'condition': True, 'evicts': 1, 'hits': 2, 'misses': 6, 'tail': 8 }], [{ 'condition': 16 * M * N**2 < 20971520, 'evicts': 0, 'hits': 8, 'misses': 0, 'tail': oo }, { 'condition': 32 * N**2 - 16 * N <= 20971520, 'evicts': 1, 'hits': 6, 'misses': 2, 'tail': 8 * N**2 - 8 * N }, { 'condition': 48 * N - 32 <= 20971520, 'evicts': 1, 'hits': 4, 'misses': 4, 'tail': 8 * N - 8 }, { 'condition': True, 'evicts': 1, 'hits': 2, 'misses': 6, 'tail': 8 }]], 'destinations': {('b', (k, j, i))}, 'distances': [oo, oo, N * (N - 1), N * (N - 1), N - 1, N - 1, 1, 1], 'distances_bytes': [ oo, oo, 8 * N * (N - 1), 8 * N * (N - 1), 8 * N - 8, 8 * N - 8, 8, 8 ] } # Iterate over expected results and validate with generated results stack = [((k, ), v) for k, v in result_expected.items()] while stack: key_path, value = stack.pop() if isinstance(value, dict): stack.extend([(key_path + (k, ), v) for k, v in value.items()]) else: self.assertEqual(value, recursive_dict_get(result, key_path), msg="at key_path={}".format(key_path))
def test_argument_parser_define(self): # invalid --define parser = kc.create_parser() with self.assertRaises(SystemExit) as cm: args = parser.parse_args(['-m', self._find_file('phinally_gcc.yaml'), '-p', 'Benchmark', self._find_file('2d-5pt.c'), '--define', 'M', '1000', '23']) kc.check_arguments(args, parser) self.assertEqual(cm.exception.code, 2) # invalid --define parser = kc.create_parser() with self.assertRaises(SystemExit) as cm: args = parser.parse_args(['-m', self._find_file('phinally_gcc.yaml'), '-p', 'Benchmark', self._find_file('2d-5pt.c'), '--define', 'N']) kc.check_arguments(args, parser) self.assertEqual(cm.exception.code, 2) # invalid --define parser = kc.create_parser() with self.assertRaises(SystemExit) as cm: args = parser.parse_args(['-m', self._find_file('phinally_gcc.yaml'), '-p', 'Benchmark', self._find_file('2d-5pt.c'), '--define', 'M', '1000', '23']) self.assertEqual(cm.exception.code, 2) # invalid --define parser = kc.create_parser() with self.assertRaises(SystemExit) as cm: args = parser.parse_args(['-m', self._find_file('phinally_gcc.yaml'), '-p', 'Benchmark', self._find_file('2d-5pt.c'), '--define', 'M']) self.assertEqual(cm.exception.code, 2) # invalid --define parser = kc.create_parser() with self.assertRaises(SystemExit) as cm: args = parser.parse_args(['-m', self._find_file('phinally_gcc.yaml'), '-p', 'Benchmark', self._find_file('2d-5pt.c'), '--define', 'M', 'foobar']) self.assertEqual(cm.exception.code, 2) # valid --define parser = kc.create_parser() args = parser.parse_args(['-m', self._find_file('phinally_gcc.yaml'), '-p', 'Benchmark', self._find_file('2d-5pt.c'), '--define', 'M', '23']) self.assertEqual(cm.exception.code, 2) # valid --define parser = kc.create_parser() args = parser.parse_args(['-m', self._find_file('phinally_gcc.yaml'), '-p', 'Benchmark', self._find_file('2d-5pt.c'), '--define', 'M', '23-42']) self.assertEqual(args.define[0][0], 'M') self.assertEqual(list(args.define[0][1]), list(range(23, 43))) # valid --define parser = kc.create_parser() args = parser.parse_args(['-m', self._find_file('phinally_gcc.yaml'), '-p', 'Benchmark', self._find_file('2d-5pt.c'), '--define', 'M', '23-42:4']) self.assertEqual(args.define[0][0], 'M') self.assertEqual(list(args.define[0][1]), [23, 29, 36, 42]) # valid --define parser = kc.create_parser() args = parser.parse_args(['-m', self._find_file('phinally_gcc.yaml'), '-p', 'Benchmark', self._find_file('2d-5pt.c'), '--define', 'M', '1-8:4log2']) self.assertEqual(args.define[0][0], 'M') self.assertEqual(list(args.define[0][1]), [1, 2, 4, 8]) # valid --define parser = kc.create_parser() args = parser.parse_args(['-m', self._find_file('phinally_gcc.yaml'), '-p', 'Benchmark', self._find_file('2d-5pt.c'), '--define', 'M', '10-1000:3log10']) self.assertEqual(args.define[0][0], 'M') self.assertEqual(list(args.define[0][1]), [10, 100, 1000])