Beispiel #1
0
  def __enter__(self):
    # assuming this is only used for WebSocket tests at the moment, validate that
    # the ws module is installed
    global npm_checked
    if not npm_checked:
      child = run_process(NODE_JS + ['-e', 'require("ws");'], check=False)
      assert child.returncode == 0, '"ws" node module not found.  you may need to run npm install'
      npm_checked = True

    # compile the server
    proc = run_process([EMCC, path_from_root('tests', self.filename), '-o', 'server.js', '-DSOCKK=%d' % self.listen_port] + self.args)
    print('Socket server build: out:', proc.stdout or '', '/ err:', proc.stderr or '')

    process = Popen(NODE_JS + ['server.js'])
    self.processes.append(process)
Beispiel #2
0
    def test_sdl_audio_mix_channels(self):
        shutil.copyfile(path_from_root('tests', 'sounds', 'noise.ogg'),
                        os.path.join(self.get_dir(), 'sound.ogg'))
        open(os.path.join(self.get_dir(), 'sdl_audio_mix_channels.c'),
             'w').write(
                 self.with_report_result(
                     open(path_from_root('tests',
                                         'sdl_audio_mix_channels.c')).read()))

        Popen([
            PYTHON, EMCC, '-O2', '--minify', '0',
            os.path.join(self.get_dir(), 'sdl_audio_mix_channels.c'),
            '--preload-file', 'sound.ogg', '-o', 'page.html'
        ]).communicate()
        self.run_browser('page.html', '', '/report_result?1')
Beispiel #3
0
    def test_sdl2_mixer(self):
        shutil.copyfile(
            path_from_root('tests', 'sounds', 'alarmvictory_1.ogg'),
            os.path.join(self.get_dir(), 'sound.ogg'))
        open(os.path.join(self.get_dir(), 'sdl2_mixer.c'), 'w').write(
            self.with_report_result(
                open(path_from_root('tests', 'sdl2_mixer.c')).read()))

        Popen([
            PYTHON, EMCC, '-O2', '--minify', '0',
            os.path.join(self.get_dir(), 'sdl2_mixer.c'), '-s', 'USE_SDL=2',
            '-s', 'USE_SDL_MIXER=2', '-s', 'TOTAL_MEMORY=33554432',
            '--preload-file', 'sound.ogg', '-o', 'page.html'
        ]).communicate()
        self.run_browser('page.html', '', '/report_result?1')
Beispiel #4
0
    def test_sdl_audio_panning(self):
        shutil.copyfile(
            path_from_root('tests', 'sounds', 'the_entertainer.wav'),
            os.path.join(self.get_dir(), 'the_entertainer.wav'))
        open(os.path.join(self.get_dir(), 'sdl_audio_panning.c'), 'w').write(
            self.with_report_result(
                open(path_from_root('tests', 'sdl_audio_panning.c')).read()))

        # use closure to check for a possible bug with closure minifying away newer Audio() attributes
        Popen([
            EMCC, '-O2', '--closure', '1', '--minify', '0',
            os.path.join(self.get_dir(), 'sdl_audio_panning.c'),
            '--preload-file', 'the_entertainer.wav', '-o', 'page.html', '-s',
            'EXPORTED_FUNCTIONS=["_main", "_play"]'
        ]).communicate()
        self.run_browser('page.html', '', '/report_result?1')
Beispiel #5
0
    def test_sdl2_mixer_wav(self):
        shutil.copyfile(
            path_from_root('tests', 'sounds', 'the_entertainer.wav'),
            os.path.join(self.get_dir(), 'sound.wav'))
        open(os.path.join(self.get_dir(), 'sdl2_mixer_wav.c'), 'w').write(
            self.with_report_result(
                open(path_from_root('tests', 'sdl2_mixer_wav.c')).read()))

        Popen([
            EMCC, '-O2', '--minify', '0',
            os.path.join(self.get_dir(),
                         'sdl2_mixer_wav.c'), '-s', 'USE_SDL=2', '-s',
            'USE_SDL_MIXER=2', '-s', 'INITIAL_MEMORY=33554432',
            '--preload-file', 'sound.wav', '-o', 'page.html'
        ]).communicate()
        self.run_browser('page.html', '', '/report_result?1')
Beispiel #6
0
 def test_freealut(self):
     Popen([EMCC, '-O2'] + self.get_freealut_library() +
           ['-o', 'page.html']).communicate()
     self.run_browser('page.html', 'You should hear "Hello World!"')
Beispiel #7
0

def path_from_root(*pathelems):
    return os.path.join(__rootpath__, *pathelems)


sys.path += [path_from_root('')]
from tools import shared
from tools.shared import PYTHON, WINDOWS, CLANG_CXX, EMCC, PIPE, V8_ENGINE
from tools.shared import Popen

temp_dir = tempfile.mkdtemp()

# System info
system_info = Popen([PYTHON, path_from_root('emrun'), '--system_info'],
                    stdout=PIPE,
                    stderr=PIPE).communicate()

# Native info
native_info = Popen(['clang', '-v'], stdout=PIPE, stderr=PIPE).communicate()

# Emscripten info
emscripten_info = Popen([EMCC, '-v'], stdout=PIPE, stderr=PIPE).communicate()

# Run native build
out_file = os.path.join(temp_dir, 'benchmark_sse1_native')
if WINDOWS: out_file += '.exe'
cmd = [CLANG_CXX] + shared.Building.get_native_building_args() + [
    path_from_root('tests', 'sse', 'benchmark_sse1.cpp'), '-O3', '-o', out_file
]
print 'Building native version of the benchmark:'
  def zzztest_sdl2_audio_beeps(self):
    open(os.path.join(self.get_dir(), 'sdl2_audio_beep.cpp'), 'w').write(self.with_report_result(open(path_from_root('tests', 'sdl2_audio_beep.cpp')).read()))

    # use closure to check for a possible bug with closure minifying away newer Audio() attributes
    Popen([PYTHON, EMCC, '-O2', '--closure', '1', '--minify', '0', os.path.join(self.get_dir(), 'sdl2_audio_beep.cpp'), '-s', 'DISABLE_EXCEPTION_CATCHING=0', '-s', 'USE_SDL=2', '-o', 'page.html']).communicate()
    self.run_browser('page.html', '', '/report_result?1')
Beispiel #9
0
  def test_webrtc(self): # XXX see src/settings.js, this is disabled pending investigation
    self.skipTest('WebRTC support is not up to date.')
    host_src = 'webrtc_host.c'
    peer_src = 'webrtc_peer.c'

    host_outfile = 'host.html'
    peer_outfile = 'peer.html'

    host_filepath = path_from_root('tests', 'sockets', host_src)
    temp_host_filepath = os.path.join(self.get_dir(), os.path.basename(host_src))
    with open(host_filepath) as f:
      host_src = f.read()
    with open(temp_host_filepath, 'w') as f:
      f.write(self.with_report_result(host_src))

    peer_filepath = path_from_root('tests', 'sockets', peer_src)
    temp_peer_filepath = os.path.join(self.get_dir(), os.path.basename(peer_src))
    with open(peer_filepath) as f:
      peer_src = f.read()
    with open(temp_peer_filepath, 'w') as f:
      f.write(self.with_report_result(peer_src))

    open(os.path.join(self.get_dir(), 'host_pre.js'), 'w').write('''
      var Module = {
        webrtc: {
          broker: 'http://localhost:8182',
          session: undefined,
          onpeer: function(peer, route) {
            window.open('http://localhost:8888/peer.html?' + route);
            // iframe = document.createElement("IFRAME");
            // iframe.setAttribute("src", "http://localhost:8888/peer.html?" + route);
            // iframe.style.display = "none";
            // document.body.appendChild(iframe);
            peer.listen();
          },
          onconnect: function(peer) {
          },
          ondisconnect: function(peer) {
          },
          onerror: function(error) {
            console.error(error);
          }
        },
        setStatus: function(text) {
          console.log('status: ' + text);
        }
      };
    ''')

    open(os.path.join(self.get_dir(), 'peer_pre.js'), 'w').write('''
      var Module = {
        webrtc: {
          broker: 'http://localhost:8182',
          session: window.location.toString().split('?')[1],
          onpeer: function(peer, route) {
            peer.connect(Module['webrtc']['session']);
          },
          onconnect: function(peer) {
          },
          ondisconnect: function(peer) {
            // Calling window.close() from this handler hangs my browser, so run it in the next turn
            setTimeout(window.close, 0);
          },
          onerror: function(error) {
            console.error(error);
          },
        },
        setStatus: function(text) {
          console.log('status: ' + text);
        }
      };
    ''')

    run_process([EMCC, temp_host_filepath, '-o', host_outfile] + ['-s', 'GL_TESTING=1', '--pre-js', 'host_pre.js', '-s', 'SOCKET_WEBRTC=1', '-s', 'SOCKET_DEBUG=1'])
    run_process([EMCC, temp_peer_filepath, '-o', peer_outfile] + ['-s', 'GL_TESTING=1', '--pre-js', 'peer_pre.js', '-s', 'SOCKET_WEBRTC=1', '-s', 'SOCKET_DEBUG=1'])

    # note: you may need to run this manually yourself, if npm is not in the path, or if you need a version that is not in the path
    run_process([NPM, 'install', path_from_root('tests', 'sockets', 'p2p')])
    broker = Popen(NODE_JS + [path_from_root('tests', 'sockets', 'p2p', 'broker', 'p2p-broker.js')])

    expected = '1'
    self.run_browser(host_outfile, '.', ['/report_result?' + e for e in expected])

    broker.kill()
Beispiel #10
0
 def __enter__(self):
   print('Running background server: ' + str(self.args))
   process = Popen(self.args)
   self.processes.append(process)
Beispiel #11
0
  def test_webrtc(self): # XXX see src/settings.js, this is disabled pending investigation
    self.skipTest('WebRTC support is not up to date.')
    host_src = 'webrtc_host.c'
    peer_src = 'webrtc_peer.c'

    host_outfile = 'host.html'
    peer_outfile = 'peer.html'

    host_filepath = path_from_root('tests', 'sockets', host_src)
    temp_host_filepath = os.path.join(self.get_dir(), os.path.basename(host_src))
    with open(host_filepath) as f:
      host_src = f.read()
    with open(temp_host_filepath, 'w') as f:
      f.write(self.with_report_result(host_src))

    peer_filepath = path_from_root('tests', 'sockets', peer_src)
    temp_peer_filepath = os.path.join(self.get_dir(), os.path.basename(peer_src))
    with open(peer_filepath) as f:
      peer_src = f.read()
    with open(temp_peer_filepath, 'w') as f:
      f.write(self.with_report_result(peer_src))

    open(os.path.join(self.get_dir(), 'host_pre.js'), 'w').write('''
      var Module = {
        webrtc: {
          broker: 'http://localhost:8182',
          session: undefined,
          onpeer: function(peer, route) {
            window.open('http://localhost:8888/peer.html?' + route);
            // iframe = document.createElement("IFRAME");
            // iframe.setAttribute("src", "http://localhost:8888/peer.html?" + route);
            // iframe.style.display = "none";
            // document.body.appendChild(iframe);
            peer.listen();
          },
          onconnect: function(peer) {
          },
          ondisconnect: function(peer) {
          },
          onerror: function(error) {
            console.error(error);
          }
        },
        setStatus: function(text) {
          console.log('status: ' + text);
        }
      };
    ''')

    open(os.path.join(self.get_dir(), 'peer_pre.js'), 'w').write('''
      var Module = {
        webrtc: {
          broker: 'http://localhost:8182',
          session: window.location.toString().split('?')[1],
          onpeer: function(peer, route) {
            peer.connect(Module['webrtc']['session']);
          },
          onconnect: function(peer) {
          },
          ondisconnect: function(peer) {
            // Calling window.close() from this handler hangs my browser, so run it in the next turn
            setTimeout(window.close, 0);
          },
          onerror: function(error) {
            console.error(error);
          },
        },
        setStatus: function(text) {
          console.log('status: ' + text);
        }
      };
    ''')

    run_process([PYTHON, EMCC, temp_host_filepath, '-o', host_outfile] + ['-s', 'GL_TESTING=1', '--pre-js', 'host_pre.js', '-s', 'SOCKET_WEBRTC=1', '-s', 'SOCKET_DEBUG=1'])
    run_process([PYTHON, EMCC, temp_peer_filepath, '-o', peer_outfile] + ['-s', 'GL_TESTING=1', '--pre-js', 'peer_pre.js', '-s', 'SOCKET_WEBRTC=1', '-s', 'SOCKET_DEBUG=1'])

    # note: you may need to run this manually yourself, if npm is not in the path, or if you need a version that is not in the path
    run_process([NPM, 'install', path_from_root('tests', 'sockets', 'p2p')])
    broker = Popen(NODE_JS + [path_from_root('tests', 'sockets', 'p2p', 'broker', 'p2p-broker.js')])

    expected = '1'
    self.run_browser(host_outfile, '.', ['/report_result?' + e for e in expected])

    broker.kill()
# System info
system_info = Popen([PYTHON, path_from_root('emrun'), '--system_info'], stdout=PIPE, stderr=PIPE).communicate()

# Native info
native_info = Popen(['clang', '-v'], stdout=PIPE, stderr=PIPE).communicate()

# Emscripten info
emscripten_info = Popen([PYTHON, EMCC, '-v'], stdout=PIPE, stderr=PIPE).communicate()

# Run native build
out_file = os.path.join(temp_dir, 'benchmark_sse1_native')
if WINDOWS: out_file += '.exe'
cmd = [CLANG_CPP] + get_clang_native_args() + [path_from_root('tests', 'benchmark_sse1.cpp'), '-O3', '-o', out_file]
print 'Building native version of the benchmark:'
print ' '.join(cmd)
build = Popen(cmd, env=get_clang_native_env())
out = build.communicate()
if build.returncode != 0:
    sys.exit(1)

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_sse1_html.html')
cmd = [PYTHON, EMCC, path_from_root('tests', 'benchmark_sse1.cpp'), '-O3', '-msse', '--emrun', '-s', 'TOTAL_MEMORY=536870912', '-o', out_file]
print 'Building Emscripten version of the benchmark:'
print ' '.join(cmd)
build = Popen(cmd)
out = build.communicate()
if build.returncode != 0:
Beispiel #13
0
__rootpath__ = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))


def path_from_root(*pathelems):
    return os.path.join(__rootpath__, *pathelems)


sys.path += [path_from_root('')]
from tools.shared import PYTHON, WINDOWS, CLANG_CPP, EMCC, PIPE
from tools.shared import Popen, get_clang_native_args, get_clang_native_env

temp_dir = tempfile.mkdtemp()

# System info
system_info = Popen([PYTHON, path_from_root('emrun'), '--system_info'],
                    stdout=PIPE,
                    stderr=PIPE).communicate()

# Native info
native_info = Popen(['clang', '-v'], stdout=PIPE, stderr=PIPE).communicate()

# Emscripten info
emscripten_info = Popen([PYTHON, EMCC, '-v'], stdout=PIPE,
                        stderr=PIPE).communicate()

# Run native build
out_file = os.path.join(temp_dir, 'benchmark_sse1_native')
if WINDOWS: out_file += '.exe'
cmd = [CLANG_CPP] + get_clang_native_args() + [
    path_from_root('tests', 'benchmark_sse1.cpp'), '-O3', '-o', out_file
]
Beispiel #14
0
  def test_openal_playback(self):
    shutil.copyfile(path_from_root('tests', 'sounds', 'audio.wav'), os.path.join(self.get_dir(), 'audio.wav'))
    open(os.path.join(self.get_dir(), 'openal_playback.cpp'), 'w').write(self.with_report_result(open(path_from_root('tests', 'openal_playback.cpp')).read()))

    Popen([PYTHON, EMCC, '-O2', os.path.join(self.get_dir(), 'openal_playback.cpp'), '--preload-file', 'audio.wav', '-o', 'page.html']).communicate()
    self.run_browser('page.html', '', '/report_result?1')
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] + building.get_native_building_args() + [
        benchmark_file, '-O3', '-o', out_file
    ]
    print 'Building native version of the benchmark:'
    print ' '.join(cmd)
    build = Popen(cmd, env=building.get_building_env(native=True))
    out = build.communicate()
    if build.returncode != 0:
        sys.exit(1)

    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)
    build = Popen(cmd)
    out = build.communicate()
    if build.returncode != 0:
        sys.exit(1)

    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)

    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 + '.'

def path_from_root(*pathelems):
    return os.path.join(__rootpath__, *pathelems)


sys.path += [path_from_root('')]
from tools import shared, building
from tools.shared import PYTHON, WINDOWS, CLANG_CXX, EMCC, PIPE, V8_ENGINE
from tools.shared import Popen

temp_dir = tempfile.mkdtemp()

# System info
system_info = Popen([PYTHON, path_from_root('emrun'), '--system_info'],
                    stdout=PIPE,
                    stderr=PIPE).communicate()

# Native info
native_info = Popen(['clang', '-v'], stdout=PIPE, stderr=PIPE).communicate()

# Emscripten info
emscripten_info = Popen([EMCC, '-v'], stdout=PIPE, stderr=PIPE).communicate()


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] + building.get_native_building_args() + [
        benchmark_file, '-O3', '-o', out_file