Ejemplo n.º 1
0
    def test_openmp(self):
        compiler = CppSwigCompiler()
        input_path = EXAMPLES_ROOTS['cpp14'].joinpath('matmul_openmp.cpp')

        output_dir = make_swig_tmp_folder(input_path)
        with input_path.open() as input_file:
            code = input_file.read()
        output_path = compiler.compile(code, input_path, output_dir)
        self.assertIsInstance(output_path, pathlib.Path)
        binder = Binder()
        with binder.temporarily_bind(output_path) as binding:
            print(type(binding.multiply_martices_example))
            # print(help(binding.main))
            with _TIME.measure('matmul') as timer:
                ret_val = binding.multiply_martices_example(1, 3000, 3000)
            self.assertGreater(timer.elapsed, 0)
            self.assertEqual(ret_val, 0)
            _LOG.info('%s', _TIME.summary)
            json_to_file(_TIME.summary,
                         PERFORMANCE_RESULTS_ROOT.joinpath('{}.run.matmul.json'.format(__name__)))
        output_path.unlink()
        try:
            output_dir.rmdir()
        except OSError:
            pass
Ejemplo n.º 2
0
    def test_compute_pi(self):
        # reader = CodeReader()
        compiler_cpp = CppSwigCompiler()
        transpiler_py_to_f95 = AutoTranspiler(Language.find('Python 3'),
                                              Language.find('Fortran 95'))
        # transpiler_py_to_cpp = AutoTranspiler(Language.find('Python 3'), Language.find('C++14'))
        binder = Binder()

        name = 'compute_pi'
        variants = {}
        variants['py'] = (EXAMPLES_ROOTS['python3'].joinpath(name + '.py'),
                          None)
        if platform.system() == 'Linux':
            path_cpp = EXAMPLES_ROOTS['cpp14'].joinpath(name + '.cpp')
            variants['cpp'] = (compiler_cpp.compile_file(path_cpp), None)
        # variants['py_to_cpp'] = transpiler_py_to_cpp.transpile_file(variants['py'])
        # variants['f95'] = EXAMPLES_ROOTS['f95']
        variants['py_to_f95'] = (transpiler_py_to_f95.transpile_file(
            variants['py'][0]), None)
        variants['py_numba'] = (variants['py'][0], lambda f: numba.jit(f))

        segments_list = [_ for _ in range(0, 20)]

        values = {}
        for segments in segments_list:
            values[segments] = {}

        for variant, (path, transform) in variants.items():
            with binder.temporarily_bind(path) as binding:
                tested_function = getattr(binding, name)
                if transform:
                    tested_function = transform(tested_function)
                for segments in segments_list:
                    with self.subTest(variant=variant,
                                      path=path,
                                      segments=segments):
                        for _ in _TIME.measure_many(
                                '{}.{}.{}'.format(name, segments, variant),
                                1000):
                            value = tested_function(segments)
                        if segments >= 17:
                            self.assertAlmostEqual(value, np.pi, places=5)
                        elif segments > 10:
                            self.assertAlmostEqual(value, np.pi, places=6)
                        elif segments > 4:
                            self.assertAlmostEqual(value, np.pi, places=3)
                        else:
                            self.assertAlmostEqual(value, np.pi, places=0)
                        values[segments][variant] = value
                        # _LOG.warning('timing: %s, value=%f', timer, value)

        for segments in segments_list:
            timings_name = '.'.join([__name__, name, str(segments)])
            summary = timing.query_cache(timings_name).summary
            _LOG.info('%s', summary)
            json_to_file(
                summary,
                PERFORMANCE_RESULTS_ROOT.joinpath(timings_name + '.json'))
Ejemplo n.º 3
0
    def test_copy_array(self):
        name = 'copy_array'
        variants = {
            'py':
            EXAMPLES_ROOTS['python3'].joinpath(name + '.py'),
            'f95':
            F2PyCompiler().compile_file(EXAMPLES_ROOTS['f95'].joinpath(name +
                                                                       '.f90'))
        }
        variants['py_numba'] = variants['py']
        variants['numpy'] = variants['py']
        if platform.system() == 'Linux':
            # variants['cpp'] = CppSwigCompiler().compile_file(
            #     EXAMPLES_ROOTS['cpp14'].joinpath(name + '.cpp'))
            # variants['py_to_cpp'] = AutoTranspiler(
            #     Language.find('Python 3'), Language.find('C++14')).transpile_file(variants['py'])
            pass
        # variants['py_to_f95'] = AutoTranspiler(
        #     Language.find('Python'), Language.find('Fortran 95')).transpile_file(variants['py'])

        transforms = {'py_numba': numba.jit, 'numpy': lambda _: np.copy}

        arrays = [
            np.array(np.random.random_sample((array_size, )), dtype=np.double)
            for array_size in range(1024, 1024 * 64 + 1, 1024 * 4)
        ]

        binder = Binder()
        for variant, path in variants.items():
            with binder.temporarily_bind(path) as binding:
                tested_function = getattr(binding, name)
                if variant in transforms:
                    tested_function = transforms[variant](tested_function)
                for array in arrays:
                    with self.subTest(variant=variant,
                                      path=path,
                                      array_size=array.size):
                        # with _TIME.measure('{}.{}.{}'.format(name, segments, variant)):
                        for _ in _TIME.measure_many(
                                '{}.{}.{}'.format(name, array.size, variant),
                                50):
                            array_copy = tested_function(array)
                        self.assertListEqual(array.tolist(),
                                             array_copy.tolist())

        for array in arrays:
            timings_name = '.'.join([__name__, name, str(array.size)])
            summary = timing.query_cache(timings_name).summary
            _LOG.info('%s', summary)
            json_to_file(
                summary,
                PERFORMANCE_RESULTS_ROOT.joinpath(timings_name + '.json'))
Ejemplo n.º 4
0
    def test_file(self):
        for _, example in EXAMPLES.items():
            with tempfile.NamedTemporaryFile(delete=False) as tmp:
                path = pathlib.Path(tmp.name)
            json_to_file(example, path)
            result = file_to_json(path)
            path.unlink()
            self.assertEqual(example, result)

        with tempfile.NamedTemporaryFile('w', delete=False) as tmp:
            tmp.write(BAD_EXAMPLE)
            path = pathlib.Path(tmp.name)
        with self.assertRaises(ValueError):
            file_to_json(path)
        path.unlink()
Ejemplo n.º 5
0
    def test_do_nothing(self):
        name = 'do_nothing'
        variants = {
            'py':
            EXAMPLES_ROOTS['python3'].joinpath(name + '.py'),
            'f95':
            F2PyCompiler().compile_file(EXAMPLES_ROOTS['f95'].joinpath(name +
                                                                       '.f90'))
        }
        variants['py_numba'] = variants['py']
        if platform.system() == 'Linux':
            variants['cpp'] = CppSwigCompiler().compile_file(
                EXAMPLES_ROOTS['cpp14'].joinpath(name + '.cpp'))

        transforms = {'py_numba': numba.jit}

        binder = Binder()
        for variant, path in variants.items():
            with binder.temporarily_bind(path) as binding:
                tested_function = getattr(binding, name)
                if variant in transforms:
                    tested_function = transforms[variant](tested_function)
                with self.subTest(variant=variant, path=path):
                    # with _TIME.measure('{}.{}'.format(name, variant)) as timer:
                    for _ in _TIME.measure_many('{}.{}'.format(name, variant),
                                                1000):
                        tested_function()
                    # _LOG.warning('timing: %s', timer)

        timings_name = '.'.join([__name__, name])
        summary = timing.query_cache(timings_name).summary
        _LOG.info('%s', summary)
        json_to_file(summary,
                     PERFORMANCE_RESULTS_ROOT.joinpath(timings_name + '.json'))

        if summary['py']['median'] < summary['f95']['median']:
            self.assertAlmostEqual(summary['py']['median'],
                                   summary['f95']['median'],
                                   places=5 if os.environ.get('CI') else 6)
        if platform.system() == 'Linux':
            if summary['py']['median'] < summary['cpp']['median']:
                self.assertAlmostEqual(summary['py']['median'],
                                       summary['cpp']['median'],
                                       places=5 if os.environ.get('CI') else 6)
Ejemplo n.º 6
0
    def test_do_nothing(self):
        # reader = CodeReader()
        compiler_f95 = F2PyCompiler()
        binder = Binder()

        name = 'do_nothing'
        variants = {}
        variants['py'] = (EXAMPLES_ROOTS['python3'].joinpath(name + '.py'),
                          None)
        path_f95 = EXAMPLES_ROOTS['f95'].joinpath(name + '.f90')
        variants['f95'] = (compiler_f95.compile_file(path_f95), None)
        if platform.system() == 'Linux':
            compiler_cpp = CppSwigCompiler()
            path_cpp = EXAMPLES_ROOTS['cpp14'].joinpath(name + '.cpp')
            variants['cpp'] = (compiler_cpp.compile_file(path_cpp), None)
        variants['py_numba'] = (variants['py'][0], numba.jit)

        for variant, (path, transform) in variants.items():
            with binder.temporarily_bind(path) as binding:
                tested_function = getattr(binding, name)
                if transform:
                    tested_function = transform(tested_function)
                with self.subTest(variant=variant, path=path):
                    # with _TIME.measure('{}.{}'.format(name, variant)) as timer:
                    for _ in _TIME.measure_many('{}.{}'.format(name, variant),
                                                1000):
                        tested_function()
                    # _LOG.warning('timing: %s', timer)

        timings_name = '.'.join([__name__, name])
        summary = timing.query_cache(timings_name).summary
        _LOG.info('%s', summary)
        json_to_file(summary,
                     PERFORMANCE_RESULTS_ROOT.joinpath(timings_name + '.json'))

        if summary['py']['median'] < summary['f95']['median']:
            self.assertAlmostEqual(summary['py']['median'],
                                   summary['f95']['median'],
                                   places=5 if os.environ.get('CI') else 6)
        if platform.system() == 'Linux':
            self.assertGreater(summary['py']['median'],
                               summary['cpp']['median'])
Ejemplo n.º 7
0
    def test_openmp(self):
        code_reader = CodeReader()
        binder = Binder()

        input_path = EXAMPLES_ROOTS['f77'].joinpath('matmul.f')
        code = code_reader.read_file(input_path)
        output_dir = make_f2py_tmp_folder(input_path)
        compiler = F2PyCompiler()
        output_path = compiler.compile(code, input_path, output_dir)
        with binder.temporarily_bind(output_path) as binding:
            self.assertIsInstance(binding, types.ModuleType)
            with _TIME.measure('run.matmul.simple'):
                ret_val = binding.intmatmul(20, 1024, 1024)
        self.assertEqual(ret_val, 0)
        output_path.unlink()

        input_path = EXAMPLES_ROOTS['f77'].joinpath('matmul_openmp.f')
        code = code_reader.read_file(input_path)
        output_dir = make_f2py_tmp_folder(input_path)
        compiler_omp = F2PyCompiler(GfortranInterface({'OpenMP'}))
        output_path = compiler_omp.compile(code, input_path, output_dir)
        with binder.temporarily_bind(output_path) as binding:
            self.assertIsInstance(binding, types.ModuleType)
            with _TIME.measure('run.matmul.openmp'):
                ret_val = binding.intmatmul(20, 1024, 1024)
        self.assertEqual(ret_val, 0)
        timings_name = '.'.join([__name__, 'run', 'matmul'])
        summary = timing.query_cache(timings_name).summary
        _LOG.warning('%s', summary)
        json_to_file(summary,
                     PERFORMANCE_RESULTS_ROOT.joinpath(timings_name + '.json'))
        output_path.unlink()

        try:
            output_dir.rmdir()
        except OSError:
            pass
Ejemplo n.º 8
0
    def test_compute_pi(self):
        name = 'compute_pi'

        # t.Dict[str, pathlib.Path]
        variants = {
            'py':
            EXAMPLES_ROOTS['python3'].joinpath(name + '.py'),
            'f95':
            F2PyCompiler().compile_file(EXAMPLES_ROOTS['f95'].joinpath(name +
                                                                       '.f90'))
        }
        variants['py_numba'] = variants['py']
        variants['py_to_f95'] = AutoTranspiler(
            Language.find('Python'),
            Language.find('Fortran 95')).transpile_file(variants['py'])
        if platform.system() == 'Linux':
            variants['cpp'] = CppSwigCompiler().compile_file(
                EXAMPLES_ROOTS['cpp14'].joinpath(name + '.cpp'))
            variants['py_to_cpp'] = AutoTranspiler(
                Language.find('Python'),
                Language.find('C++14')).transpile_file(variants['py'])

        # t.Dict[str, collections.abc.Callable]
        transforms = {'py_numba': numba.jit}

        segments_list = [_ for _ in range(0, 20)]

        # values = {}
        # for segments in segments_list:
        #     values[segments] = {}

        binder = Binder()
        for variant, path in variants.items():
            with binder.temporarily_bind(path) as binding:
                tested_function = getattr(binding, name)
                if variant in transforms:
                    tested_function = transforms[variant](tested_function)
                for segments in segments_list:
                    with self.subTest(variant=variant,
                                      path=path,
                                      segments=segments):
                        for _ in _TIME.measure_many(
                                '{}.{}.{}'.format(name, segments, variant),
                                1000):
                            value = tested_function(segments)
                        if segments >= 17:
                            self.assertAlmostEqual(value, np.pi, places=5)
                        elif segments > 10:
                            self.assertAlmostEqual(value, np.pi, places=6)
                        elif segments > 4:
                            self.assertAlmostEqual(value, np.pi, places=3)
                        else:
                            self.assertAlmostEqual(value, np.pi, places=0)
                        # values[segments][variant] = value
                        # _LOG.warning('timing: %s, value=%f', timer, value)

        for segments in segments_list:
            timings_name = '.'.join([__name__, name, str(segments)])
            summary = timing.query_cache(timings_name).summary
            _LOG.info('%s', summary)
            json_to_file(
                summary,
                PERFORMANCE_RESULTS_ROOT.joinpath(timings_name + '.json'))
Ejemplo n.º 9
0
    def test_directives(self):
        binder = Binder()
        compiler_f95 = F2PyCompiler()
        compiler_f95_omp = F2PyCompiler(GfortranInterface({'OpenMP'}))
        compiler_f95_acc = F2PyCompiler(PgifortranInterface({'OpenACC'}))
        test_acc = shutil.which(
            str(compiler_f95_acc.f2py.f_compiler.executable(
                'compile'))) is not None

        name = 'itemwise_calc'
        variants = {
            'f95':
            compiler_f95.compile_file(EXAMPLES_ROOTS['f95'].joinpath(name +
                                                                     '.f90')),
            'f95_openmp':
            compiler_f95_omp.compile_file(
                EXAMPLES_ROOTS['f95'].joinpath(name + '_openmp.f90'))
        }
        if test_acc:
            variants['f95_openacc'] = compiler_f95_acc.compile_file(
                EXAMPLES_ROOTS['f95'].joinpath(name + '_openacc.f90'))

        arrays = [
            np.array(np.random.random_sample((array_size, )), dtype=np.double)
            for array_size in range(4 * KB, 64 * KB + 1, 4 * KB)
        ]
        arrays += [
            np.array(np.random.random_sample((array_size, )), dtype=np.double)
            for array_size in range(128 * KB, MB + 1, 128 * KB)
        ]
        if test_acc:
            arrays += [
                np.array(np.random.random_sample((array_size, )),
                         dtype=np.double)
                for array_size in range(4 * MB, 32 * MB + 1, 4 * MB)
            ]
            arrays += [
                np.array(np.random.random_sample((array_size, )),
                         dtype=np.double)
                for array_size in range(64 * MB, 256 * MB + 1, 64 * MB)
            ]

        for variant, path in variants.items():
            with binder.temporarily_bind(path) as binding:
                tested_function = getattr(binding, name)
                for array in arrays:
                    with self.subTest(variant=variant,
                                      path=path,
                                      array_size=array.size):
                        # with _TIME.measure('{}.{}.{}'.format(name, segments, variant)):
                        for _ in _TIME.measure_many(
                                'run.{}.{}.{}'.format(name, array.size,
                                                      variant), 10):
                            results = tested_function(array)
                        # self.assertListEqual(array.tolist(), array_copy.tolist())
                        self.assertTrue(results.shape, array.shape)

        for array in arrays:
            timings_name = '.'.join([__name__, 'run', name, str(array.size)])
            summary = timing.query_cache(timings_name).summary
            _LOG.info('%s', summary)
            json_to_file(
                summary,
                PERFORMANCE_RESULTS_ROOT.joinpath(timings_name + '.json'))