Exemple #1
0
    def build(self, parent, filename, args, shared_args, emcc_args,
              native_args, native_exec, lib_builder, has_output_parser):
        self.parent = parent
        if lib_builder:
            env = {
                'CC': self.cc,
                'CXX': self.cxx,
                'CXXFLAGS': "-Wno-c++11-narrowing"
            }
            env.update(clang_native.get_clang_native_env())
            native_args = native_args + lib_builder(
                self.name, native=True, env_init=env)
        if not native_exec:
            compiler = self.cxx if filename.endswith('cpp') else self.cc
            cmd = [
                compiler, '-fno-math-errno', filename, '-o',
                filename + '.native'
            ] + self.args + shared_args + native_args + clang_native.get_clang_native_args(
            )
            # print(cmd)
            run_process(cmd, env=clang_native.get_clang_native_env())
        else:
            shutil.copyfile(native_exec, filename + '.native')
            shutil.copymode(native_exec, filename + '.native')

        final = os.path.dirname(
            filename) + os.path.sep + self.name + '_' + os.path.basename(
                filename) + '.native'
        shutil.move(filename + '.native', final)
        self.filename = final
    def __enter__(self):
        # compile the server
        # NOTE empty filename support is a hack to support
        # the current test_enet
        if self.filename:
            proc = run_process([
                CLANG_CC,
                test_file(self.filename), '-o', 'server',
                '-DSOCKK=%d' % self.target_port
            ] + clang_native.get_clang_native_args() + self.args,
                               clang_native.get_clang_native_env(),
                               stdout=PIPE,
                               stderr=PIPE)
            print('Socket server build: out:', proc.stdout or '', '/ err:',
                  proc.stderr or '')
            process = Popen([os.path.abspath('server')])
            self.processes.append(process)

        # start the websocket proxy
        print('running websockify on %d, forward to tcp %d' %
              (self.listen_port, self.target_port),
              file=sys.stderr)
        wsp = websockify.WebSocketProxy(verbose=True,
                                        listen_port=self.listen_port,
                                        target_host="127.0.0.1",
                                        target_port=self.target_port,
                                        run_once=True)
        self.websockify = multiprocessing.Process(target=wsp.start_server)
        self.websockify.start()
        self.processes.append(self.websockify)
        # Make sure both the actual server and the websocket proxy are running
        for i in range(10):
            try:
                if self.do_server_check:
                    server_sock = socket.create_connection(
                        ('localhost', self.target_port), timeout=1)
                    server_sock.close()
                proxy_sock = socket.create_connection(
                    ('localhost', self.listen_port), timeout=1)
                proxy_sock.close()
                break
            except IOError:
                time.sleep(1)
        else:
            clean_processes(self.processes)
            raise Exception(
                '[Websockify failed to start up in a timely manner]')

        print('[Websockify on process %s]' % str(self.processes[-2:]))
Exemple #3
0
def run_benchmark(benchmark_file, results_file, build_args):
    # Run native build
    out_file = os.path.join(temp_dir, 'benchmark_sse_native')
    if WINDOWS:
        out_file += '.exe'
    cmd = [CLANG_CXX] + clang_native.get_clang_native_args() + [
        benchmark_file, '-O3', '-o', out_file
    ]
    print('Building native version of the benchmark:')
    print(' '.join(cmd))
    run_process(cmd, env=clang_native.get_clang_native_env())

    native_results = Popen([out_file], stdout=PIPE, stderr=PIPE).communicate()
    print(native_results[0])

    # Run emscripten build
    out_file = os.path.join(temp_dir, 'benchmark_sse_html.js')
    cmd = [
        EMCC, benchmark_file, '-O3', '-s', 'TOTAL_MEMORY=536870912', '-o',
        out_file
    ] + build_args
    print('Building Emscripten version of the benchmark:')
    print(' '.join(cmd))
    run_process(cmd)

    cmd = V8_ENGINE + ['--experimental-wasm-simd', os.path.basename(out_file)]
    print(' '.join(cmd))
    old_dir = os.getcwd()
    os.chdir(os.path.dirname(out_file))
    wasm_results = Popen(cmd, stdout=PIPE, stderr=PIPE).communicate()
    os.chdir(old_dir)

    if not wasm_results:
        raise Exception('Unable to run benchmark in V8!')

    if not wasm_results[0].strip():
        print(wasm_results[1])
        sys.exit(1)

    print(wasm_results[0])

    def strip_comments(text):
        return re.sub('//.*?\n|/\*.*?\*/', '', text, re.S)  # noqa

    benchmark_results = strip_comments(wasm_results[0])

    # Strip out unwanted print output.
    benchmark_results = benchmark_results[benchmark_results.find('{'):].strip()
    if '*************************' in benchmark_results:
        benchmark_results = benchmark_results[:benchmark_results.find(
            '*************************')].strip()

    print(benchmark_results)

    shutil.rmtree(temp_dir)

    native_results = json.loads(native_results[0])
    benchmark_results = benchmark_results[
        benchmark_results.index('{'):benchmark_results.rindex('}') + 1]
    wasm_results = json.loads(benchmark_results)

    # native_workload = native_results['workload']
    # html_workload = wasm_results['workload']

    html = '''<html><head></head><body><h1>SSE JavaScript Benchmark</h1>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
    <script src="https://code.highcharts.com/highcharts.js"></script>
    <script src="https://code.highcharts.com/modules/exporting.js"></script><b>System Info:</b><br/>
    ''' + system_info[0].replace('\n', '<br/>') + '''
    <b>Native Clang Compiler:</b><br/>
    ''' + native_info[1].replace('\n', '<br/>') + '''
    <b>Emscripten Compiler:</b><br/>
    ''' + emscripten_info[0].replace('\n', '<br/>')

    charts_native = {}
    charts_html = {}
    for result in native_results['results']:
        ch = result['chart']
        if ch not in charts_native:
            charts_native[ch] = []
        charts_native[ch] += [result]
    for result in wasm_results['results']:
        ch = result['chart']
        if ch not in charts_html:
            charts_html[ch] = []
        charts_html[ch] += [result]

    def find_result_in_category(results, category):
        for result in results:
            if result['category'] == category:
                return result
        return None

    def format_comparison(a, b):
        if a < b and a != 0:
            return "<span style='color:green;font-weight:bold;'> {:10.2f}".format(
                b / a) + 'x FASTER</span>'
        elif b != 0:
            return "<span style='color:red;font-weight:bold;'> {:10.2f}".format(
                a / b) + 'x SLOWER</span>'
        else:
            return "<span style='color:red;font-weight:bold;'> NaN </span>"

    chartNumber = 0

    total_time_native_scalar = 0
    total_time_native_simd = 0
    total_time_html_scalar = 0
    total_time_html_simd = 0

    for chart_name in charts_native.keys():
        # Extract data for each chart.
        categories = []
        nativeScalarResults = []
        nativeSimdResults = []
        htmlScalarResults = []
        htmlSimdResults = []
        native_results = charts_native[chart_name]
        wasm_results = charts_html[chart_name]
        textual_results_native = '<p>'
        textual_results_html = '<p>'
        textual_results_html2 = '<p>'
        textual_results_html3 = '<p>'
        for result in native_results:
            categories += ["'" + result['category'] + "'"]
            nsc = result['scalar']
            nsi = result['simd']
            nativeScalarResults += [str(nsc)]
            nativeSimdResults += [str(nsi)]
            html_result = find_result_in_category(wasm_results,
                                                  result['category'])
            textual_results_native += 'Native ' + result[
                'category'] + ': ' + "{:10.4f}".format(
                    nsc) + 'ns -> ' + "{:10.4f}".format(nsi) + 'ns. '
            textual_results_native += 'Native SSE is ' + format_comparison(
                nsi, nsc
            ) + ' than native scalar. &nbsp; &nbsp; &nbsp; &nbsp; <br />'

            if html_result is not None:
                hsc = html_result['scalar']
                htmlScalarResults += [str(hsc)]
                hsi = html_result['simd']
                htmlSimdResults += [str(hsi)]
                textual_results_html += 'JS ' + result[
                    'category'] + ': ' + "{:10.4f}".format(
                        hsc) + 'ns -> ' + "{:10.4f}".format(hsi) + 'ns. '
                textual_results_html += 'JS SSE is ' + format_comparison(
                    hsi, hsc
                ) + ' than JS scalar. &nbsp; &nbsp; &nbsp; &nbsp; <br />'
                textual_results_html2 += 'JS ' + result[
                    'category'] + ': JS scalar is ' + format_comparison(
                        hsc, nsc
                    ) + ' than native scalar. &nbsp; &nbsp; &nbsp; &nbsp; <br />'
                textual_results_html3 += 'JS ' + result[
                    'category'] + ': JS SSE is ' + format_comparison(
                        hsi, nsi
                    ) + ' than native SSE. &nbsp; &nbsp; &nbsp; &nbsp; <br />'
                total_time_native_scalar += nsc
                total_time_native_simd += nsi
                total_time_html_scalar += hsc
                total_time_html_simd += hsi
            else:
                htmlScalarResults += [str(-1)]
                htmlSimdResults += [str(-1)]

        chartNumber += 1
        html += '<div id="chart' + str(
            chartNumber
        ) + '" style="width:100%; height:400px; margin-top: 100px;"></div>'
        html += '''<script>$(function () {
        $('#chart''' + str(chartNumber) + '''').highcharts({
            chart: {
                type: 'column'
            },
            title: {
                text: "''' + chart_name + '''"
            },
            subtitle: {
                text: 'Time per operation in nanoseconds'
            },
            xAxis: {
                categories: [''' + ','.join(categories) + '''
                ]
            },
            yAxis: {
                min: 0,
                title: {
                    text: 'Time (nanoseconds)'
                }
            },
            tooltip: {
                headerFormat: '<span style="font-size:10px">{point.key}</span><table>',
                pointFormat: '<tr><td style="color:{series.color};padding:0">{series.name}: </td>' +
                    '<td style="padding:0"><b>{point.y:.3f} ns</b></td></tr>',
                footerFormat: '</table>',
                shared: true,
                useHTML: true
            },
            plotOptions: {
                column: {
                    pointPadding: 0.2,
                    borderWidth: 0
                }
            },
            series: [{
                name: 'Native scalar',
                data: [''' + ','.join(nativeScalarResults) + ''']

            }, {
                name: 'Native SSE',
                data: [''' + ','.join(nativeSimdResults) + ''']

            }, {
                name: 'JS scalar',
                data: [''' + ','.join(htmlScalarResults) + ''']

            }, {
                name: 'JS SSE',
                data: [''' + ','.join(htmlSimdResults) + ''']

            }]
        });
    });</script>''' + '<table><tr><td>' + textual_results_native + '</td><td>' + textual_results_html + '</td></tr><tr><td>' + textual_results_html2 + '</td><td>' + textual_results_html3 + '</td></tr></table>'

    # Final overall score

    html += '<div id="overallscore" style="width:100%; height:400px; margin-top: 100px;"></div>'
    html += '''<script>$(function () {
        $('#overallscore').highcharts({
            chart: {
                type: 'column'
            },
            title: {
                text: "Overall Execution Time"
            },
            xAxis: {
                categories: ['Total time normalized to native']
            },
            yAxis: {
                min: 0,
                title: {
                    text: 'Relative time'
                }
            },
            tooltip: {
                headerFormat: '<span style="font-size:10px">{point.key}</span><table>',
                pointFormat: '<tr><td style="color:{series.color};padding:0">{series.name}: </td>' +
                    '<td style="padding:0"><b>{point.y:.3f}x</b></td></tr>',
                footerFormat: '</table>',
                shared: true,
                useHTML: true
            },
            plotOptions: {
                column: {
                    pointPadding: 0.2,
                    borderWidth: 0
                }
            },
            series: [{
                name: 'Native scalar',
                data: [''' + str(1.0) + ''']

            }, {
                name: 'Native SSE',
                data: [''' + (str(total_time_native_simd /
                                  total_time_native_scalar) if
                              total_time_native_scalar != 0 else 'N/A') + ''']

            }, {
                name: 'JS scalar',
                data: [''' + (str(total_time_html_scalar /
                                  total_time_native_scalar) if
                              total_time_native_scalar != 0 else 'N/A') + ''']

            }, {
                name: 'JS SSE',
                data: [''' + (str(total_time_html_simd /
                                  total_time_native_scalar) if
                              total_time_native_scalar != 0 else 'N/A') + ''']

            }]
        });
    });</script>'''

    html += '</body></html>'

    open(results_file, 'w').write(html)
    print('Wrote ' + str(len(html)) + ' bytes to file ' + results_file + '.')