diff options
-rw-r--r-- | src/analyzer.js | 5 | ||||
-rw-r--r-- | src/library_browser.js | 12 | ||||
-rw-r--r-- | src/parseTools.js | 15 | ||||
-rw-r--r-- | src/postamble.js | 4 | ||||
-rw-r--r-- | src/preamble.js | 4 | ||||
-rw-r--r-- | tests/float_tex.cpp | 4 | ||||
-rw-r--r-- | tests/gl_subdata.cpp | 4 | ||||
-rw-r--r-- | tests/lua/binarytrees.lua | 50 | ||||
-rw-r--r-- | tests/lua/scimark.lua | 424 | ||||
-rw-r--r-- | tests/lua/src/Makefile | 2 | ||||
-rwxr-xr-x | tests/runner.py | 185 |
11 files changed, 629 insertions, 80 deletions
diff --git a/src/analyzer.js b/src/analyzer.js index a131406c..2cc46ab6 100644 --- a/src/analyzer.js +++ b/src/analyzer.js @@ -411,8 +411,9 @@ function analyzer(data, sidePass) { // legalize parameters legalizeFunctionParameters(value.params); // legalize return value, if any - if (value.assignTo && isIllegalType(item.type)) { - bits = getBits(value.type); + var returnType = getReturnType(item.type); + if (value.assignTo && isIllegalType(returnType)) { + bits = getBits(returnType); var elements = getLegalVars(item.assignTo, bits); // legalize return value value.assignTo = elements[0].ident; diff --git a/src/library_browser.js b/src/library_browser.js index 97233c36..5f9c4d06 100644 --- a/src/library_browser.js +++ b/src/library_browser.js @@ -311,10 +311,10 @@ mergeInto(LibraryManager.library, { lockPointer: undefined, resizeCanvas: undefined, requestFullScreen: function(lockPointer, resizeCanvas) { - this.lockPointer = lockPointer; - this.resizeCanvas = resizeCanvas; - if (typeof this.lockPointer === 'undefined') this.lockPointer = true; - if (typeof this.resizeCanvas === 'undefined') this.resizeCanvas = false; + Browser.lockPointer = lockPointer; + Browser.resizeCanvas = resizeCanvas; + if (typeof Browser.lockPointer === 'undefined') Browser.lockPointer = true; + if (typeof Browser.resizeCanvas === 'undefined') Browser.resizeCanvas = false; var canvas = Module['canvas']; function fullScreenChange() { @@ -335,8 +335,8 @@ mergeInto(LibraryManager.library, { if (Module['onFullScreen']) Module['onFullScreen'](Browser.isFullScreen); } - if (!this.fullScreenHandlersInstalled) { - this.fullScreenHandlersInstalled = true; + if (!Browser.fullScreenHandlersInstalled) { + Browser.fullScreenHandlersInstalled = true; document.addEventListener('fullscreenchange', fullScreenChange, false); document.addEventListener('mozfullscreenchange', fullScreenChange, false); document.addEventListener('webkitfullscreenchange', fullScreenChange, false); diff --git a/src/parseTools.js b/src/parseTools.js index 1a58b4e7..f30883b5 100644 --- a/src/parseTools.js +++ b/src/parseTools.js @@ -286,11 +286,22 @@ function isVarArgsFunctionType(type) { return type.substr(-varArgsSuffix.length) == varArgsSuffix; } +function getNumVars(type) { // how many variables are needed to represent this type + if (type in Runtime.FLOAT_TYPES) return 1; + return Math.max(getNumIntChunks(type), 1); +} + function countNormalArgs(type, out) { out = out || {}; if (!isFunctionType(type, out)) return -1; - if (isVarArgsFunctionType(type)) out.numArgs--; - return out.numArgs; + var ret = 0; + if (out.segments) { + for (var i = 0; i < out.segments.length; i++) { + ret += getNumVars(out.segments[i][0].text); + } + } + if (isVarArgsFunctionType(type)) ret--; + return ret; } function addIdent(token) { diff --git a/src/postamble.js b/src/postamble.js index 12471a19..d0b737f8 100644 --- a/src/postamble.js +++ b/src/postamble.js @@ -1,7 +1,7 @@ // === Auto-generated postamble setup entry stuff === -Module.callMain = function callMain(args) { +Module['callMain'] = function callMain(args) { assert(runDependencies == 0, 'cannot call main when async dependencies remain! (listen on __ATMAIN__)'); assert(!Module['preRun'] || Module['preRun'].length == 0, 'cannot call main when preRun functions remain to be called'); @@ -84,7 +84,7 @@ function run(args) { var ret = 0; calledRun = true; if (Module['_main'] && shouldRunNow) { - ret = Module.callMain(args); + ret = Module['callMain'](args); if (!Module['noExitRuntime']) { exitRuntime(); } diff --git a/src/preamble.js b/src/preamble.js index d10771e3..dbe5e655 100644 --- a/src/preamble.js +++ b/src/preamble.js @@ -777,7 +777,7 @@ Module['writeArrayToMemory'] = writeArrayToMemory; {{{ reSign }}} #if PRECISE_I32_MUL -if (!Math.imul) Math.imul = function(a, b) { +if (!Math['imul']) Math['imul'] = function(a, b) { var ah = a >>> 16; var al = a & 0xffff; var bh = b >>> 16; @@ -785,7 +785,7 @@ if (!Math.imul) Math.imul = function(a, b) { return (al*bl + ((ah*bl + al*bh) << 16))|0; }; #else -Math.imul = function(a, b) { +Math['imul'] = function(a, b) { return (a*b)|0; // fast but imprecise }; #endif diff --git a/tests/float_tex.cpp b/tests/float_tex.cpp index 475f2bee..61531124 100644 --- a/tests/float_tex.cpp +++ b/tests/float_tex.cpp @@ -9,7 +9,7 @@ extern "C" { } static const char vertex_shader[] = "#ifdef GL_ES\n" - "precision highp float;\n" + "precision lowp float;\n" "#endif\n" "attribute float indices;\n" "uniform sampler2D nodeInfo;\n" @@ -25,7 +25,7 @@ static const char vertex_shader[] = "}\n"; static const char fragment_shader[] = "#ifdef GL_ES\n" - "precision highp float;\n" + "precision lowp float;\n" "#endif\n" "\n" "varying vec4 color;\n" diff --git a/tests/gl_subdata.cpp b/tests/gl_subdata.cpp index d159b2b2..5c6a9926 100644 --- a/tests/gl_subdata.cpp +++ b/tests/gl_subdata.cpp @@ -9,7 +9,7 @@ extern "C" { } static const char vertex_shader[] = "#ifdef GL_ES\n" - "precision highp float;\n" + "precision lowp float;\n" "#endif\n" "attribute float indices;\n" "uniform sampler2D nodeInfo;\n" @@ -25,7 +25,7 @@ static const char vertex_shader[] = "}\n"; static const char fragment_shader[] = "#ifdef GL_ES\n" - "precision highp float;\n" + "precision lowp float;\n" "#endif\n" "\n" "varying vec4 color;\n" diff --git a/tests/lua/binarytrees.lua b/tests/lua/binarytrees.lua new file mode 100644 index 00000000..2ae3dd69 --- /dev/null +++ b/tests/lua/binarytrees.lua @@ -0,0 +1,50 @@ +-- The Computer Language Benchmarks Game +-- http://benchmarksgame.alioth.debian.org/ +-- contributed by Mike Pall + +local function BottomUpTree(item, depth) + if depth > 0 then + local i = item + item + depth = depth - 1 + local left, right = BottomUpTree(i-1, depth), BottomUpTree(i, depth) + return { item, left, right } + else + return { item } + end +end + +local function ItemCheck(tree) + if tree[2] then + return tree[1] + ItemCheck(tree[2]) - ItemCheck(tree[3]) + else + return tree[1] + end +end + +local N = tonumber(arg and arg[1]) or 0 +local mindepth = 4 +local maxdepth = mindepth + 2 +if maxdepth < N then maxdepth = N end + +do + local stretchdepth = maxdepth + 1 + local stretchtree = BottomUpTree(0, stretchdepth) + io.write(string.format("stretch tree of depth %d\t check: %d\n", + stretchdepth, ItemCheck(stretchtree))) +end + +local longlivedtree = BottomUpTree(0, maxdepth) + +for depth=mindepth,maxdepth,2 do + local iterations = 2 ^ (maxdepth - depth + mindepth) + local check = 0 + for i=1,iterations do + check = check + ItemCheck(BottomUpTree(1, depth)) + + ItemCheck(BottomUpTree(-1, depth)) + end + io.write(string.format("%d\t trees of depth %d\t check: %d\n", + iterations*2, depth, check)) +end + +io.write(string.format("long lived tree of depth %d\t check: %d\n", + maxdepth, ItemCheck(longlivedtree))) diff --git a/tests/lua/scimark.lua b/tests/lua/scimark.lua new file mode 100644 index 00000000..7e37c219 --- /dev/null +++ b/tests/lua/scimark.lua @@ -0,0 +1,424 @@ +------------------------------------------------------------------------------ +-- Lua SciMark (2010-12-20). +-- +-- A literal translation of SciMark 2.0a, written in Java and C. +-- Credits go to the original authors Roldan Pozo and Bruce Miller. +-- See: http://math.nist.gov/scimark2/ +------------------------------------------------------------------------------ +-- Copyright (C) 2006-2010 Mike Pall. All rights reserved. +-- +-- Permission is hereby granted, free of charge, to any person obtaining +-- a copy of this software and associated documentation files (the +-- "Software"), to deal in the Software without restriction, including +-- without limitation the rights to use, copy, modify, merge, publish, +-- distribute, sublicense, and/or sell copies of the Software, and to +-- permit persons to whom the Software is furnished to do so, subject to +-- the following conditions: +-- +-- The above copyright notice and this permission notice shall be +-- included in all copies or substantial portions of the Software. +-- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +-- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +-- IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +-- CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +-- TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +-- SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +-- +-- [ MIT license: http://www.opensource.org/licenses/mit-license.php ] +------------------------------------------------------------------------------ + +local SCIMARK_VERSION = "2010-12-10" +local SCIMARK_COPYRIGHT = "Copyright (C) 2006-2010 Mike Pall" + +local MIN_TIME = 0.8 +local RANDOM_SEED = 101009 -- Must be odd. +local SIZE_SELECT = "small" + +local benchmarks = { + "FFT", "SOR", "MC", "SPARSE", "LU", + small = { + FFT = { 1024 }, + SOR = { 100 }, + MC = { }, + SPARSE = { 1000, 5000 }, + LU = { 100 }, + }, + large = { + FFT = { 1048576 }, + SOR = { 1000 }, + MC = { }, + SPARSE = { 100000, 1000000 }, + LU = { 1000 }, + }, +} + +local abs, log, sin, floor = math.abs, math.log, math.sin, math.floor +local pi, clock = math.pi, os.clock +local format = string.format + +------------------------------------------------------------------------------ +-- Select array type: Lua tables or native (FFI) arrays +------------------------------------------------------------------------------ + +local darray, iarray + +local function array_init() + if jit and jit.status and jit.status() then + local ok, ffi = pcall(require, "ffi") + if ok then + darray = ffi.typeof("double[?]") + iarray = ffi.typeof("int[?]") + return + end + end + function darray(n) return {} end + iarray = darray +end + +------------------------------------------------------------------------------ +-- This is a Lagged Fibonacci Pseudo-random Number Generator with +-- j, k, M = 5, 17, 31. Pretty weak, but same as C/Java SciMark. +------------------------------------------------------------------------------ + +local rand, rand_init + +if jit and jit.status and jit.status() then + -- LJ2 has bit operations and zero-based arrays (internally). + local bit = require("bit") + local band, sar = bit.band, bit.arshift + function rand_init(seed) + local Rm, Rj, Ri = iarray(17), 16, 11 + for i=0,16 do Rm[i] = 0 end + for i=16,0,-1 do + seed = band(seed*9069, 0x7fffffff) + Rm[i] = seed + end + function rand() + local i = band(Ri+1, sar(Ri-16, 31)) + local j = band(Rj+1, sar(Rj-16, 31)) + Ri, Rj = i, j + local k = band(Rm[i] - Rm[j], 0x7fffffff) + Rm[j] = k + return k * (1.0/2147483647.0) + end + end +else + -- Better for standard Lua with one-based arrays and without bit operations. + function rand_init(seed) + local Rm, Rj = {}, 1 + for i=1,17 do Rm[i] = 0 end + for i=17,1,-1 do + seed = (seed*9069) % (2^31) + Rm[i] = seed + end + function rand() + local j, m = Rj, Rm + local h = j - 5 + if h < 1 then h = h + 17 end + local k = m[h] - m[j] + if k < 0 then k = k + 2147483647 end + m[j] = k + if j < 17 then Rj = j + 1 else Rj = 1 end + return k * (1.0/2147483647.0) + end + end +end + +local function random_vector(n) + local v = darray(n+1) + for x=1,n do v[x] = rand() end + return v +end + +local function random_matrix(m, n) + local a = {} + for y=1,m do + local v = darray(n+1) + a[y] = v + for x=1,n do v[x] = rand() end + end + return a +end + +------------------------------------------------------------------------------ +-- FFT: Fast Fourier Transform. +------------------------------------------------------------------------------ + +local function fft_bitreverse(v, n) + local j = 0 + for i=0,2*n-4,2 do + if i < j then + v[i+1], v[i+2], v[j+1], v[j+2] = v[j+1], v[j+2], v[i+1], v[i+2] + end + local k = n + while k <= j do j = j - k; k = k / 2 end + j = j + k + end +end + +local function fft_transform(v, n, dir) + if n <= 1 then return end + fft_bitreverse(v, n) + local dual = 1 + repeat + local dual2 = 2*dual + for i=1,2*n-1,2*dual2 do + local j = i+dual2 + local ir, ii = v[i], v[i+1] + local jr, ji = v[j], v[j+1] + v[j], v[j+1] = ir - jr, ii - ji + v[i], v[i+1] = ir + jr, ii + ji + end + local theta = dir * pi / dual + local s, s2 = sin(theta), 2.0 * sin(theta * 0.5)^2 + local wr, wi = 1.0, 0.0 + for a=3,dual2-1,2 do + wr, wi = wr - s*wi - s2*wr, wi + s*wr - s2*wi + for i=a,a+2*(n-dual2),2*dual2 do + local j = i+dual2 + local jr, ji = v[j], v[j+1] + local dr, di = wr*jr - wi*ji, wr*ji + wi*jr + local ir, ii = v[i], v[i+1] + v[j], v[j+1] = ir - dr, ii - di + v[i], v[i+1] = ir + dr, ii + di + end + end + dual = dual2 + until dual >= n +end + +function benchmarks.FFT(n) + local l2n = log(n)/log(2) + if l2n % 1 ~= 0 then + io.stderr:write("Error: FFT data length is not a power of 2\n") + os.exit(1) + end + local v = random_vector(n*2) + return function(cycles) + local norm = 1.0 / n + for p=1,cycles do + fft_transform(v, n, -1) + fft_transform(v, n, 1) + for i=1,n*2 do v[i] = v[i] * norm end + end + return ((5*n-2)*l2n + 2*(n+1)) * cycles + end +end + +------------------------------------------------------------------------------ +-- SOR: Jacobi Successive Over-Relaxation. +------------------------------------------------------------------------------ + +local function sor_run(mat, m, n, cycles, omega) + local om4, om1 = omega*0.25, 1.0-omega + m = m - 1 + n = n - 1 + for i=1,cycles do + for y=2,m do + local v, vp, vn = mat[y], mat[y-1], mat[y+1] + for x=2,n do + v[x] = om4*((vp[x]+vn[x])+(v[x-1]+v[x+1])) + om1*v[x] + end + end + end +end + +function benchmarks.SOR(n) + local mat = random_matrix(n, n) + return function(cycles) + sor_run(mat, n, n, cycles, 1.25) + return (n-1)*(n-1)*cycles*6 + end +end + +------------------------------------------------------------------------------ +-- MC: Monte Carlo Integration. +------------------------------------------------------------------------------ + +local function mc_integrate(cycles) + local under_curve = 0 + local rand = rand + for i=1,cycles do + local x = rand() + local y = rand() + if x*x + y*y <= 1.0 then under_curve = under_curve + 1 end + end + return (under_curve/cycles) * 4 +end + +function benchmarks.MC() + return function(cycles) + local res = mc_integrate(cycles) + assert(math.sqrt(cycles)*math.abs(res-math.pi) < 5.0, "bad MC result") + return cycles * 4 -- Way off, but same as SciMark in C/Java. + end +end + +------------------------------------------------------------------------------ +-- Sparse Matrix Multiplication. +------------------------------------------------------------------------------ + +local function sparse_mult(n, cycles, vy, val, row, col, vx) + for p=1,cycles do + for r=1,n do + local sum = 0 + for i=row[r],row[r+1]-1 do sum = sum + vx[col[i]] * val[i] end + vy[r] = sum + end + end +end + +function benchmarks.SPARSE(n, nz) + local nr = floor(nz/n) + local anz = nr*n + local vx = random_vector(n) + local val = random_vector(anz) + local vy, col, row = darray(n+1), iarray(nz+1), iarray(n+2) + row[1] = 1 + for r=1,n do + local step = floor(r/nr) + if step < 1 then step = 1 end + local rr = row[r] + row[r+1] = rr+nr + for i=0,nr-1 do col[rr+i] = 1+i*step end + end + return function(cycles) + sparse_mult(n, cycles, vy, val, row, col, vx) + return anz*cycles*2 + end +end + +------------------------------------------------------------------------------ +-- LU: Dense Matrix Factorization. +------------------------------------------------------------------------------ + +local function lu_factor(a, pivot, m, n) + local min_m_n = m < n and m or n + for j=1,min_m_n do + local jp, t = j, abs(a[j][j]) + for i=j+1,m do + local ab = abs(a[i][j]) + if ab > t then + jp = i + t = ab + end + end + pivot[j] = jp + if a[jp][j] == 0 then error("zero pivot") end + if jp ~= j then a[j], a[jp] = a[jp], a[j] end + if j < m then + local recp = 1.0 / a[j][j] + for k=j+1,m do + local v = a[k] + v[j] = v[j] * recp + end + end + if j < min_m_n then + for i=j+1,m do + local vi, vj = a[i], a[j] + local eij = vi[j] + for k=j+1,n do vi[k] = vi[k] - eij * vj[k] end + end + end + end +end + +local function matrix_alloc(m, n) + local a = {} + for y=1,m do a[y] = darray(n+1) end + return a +end + +local function matrix_copy(dst, src, m, n) + for y=1,m do + local vd, vs = dst[y], src[y] + for x=1,n do vd[x] = vs[x] end + end +end + +function benchmarks.LU(n) + local mat = random_matrix(n, n) + local tmp = matrix_alloc(n, n) + local pivot = iarray(n+1) + return function(cycles) + for i=1,cycles do + matrix_copy(tmp, mat, n, n) + lu_factor(tmp, pivot, n, n) + end + return 2.0/3.0*n*n*n*cycles + end +end + +------------------------------------------------------------------------------ +-- Main program. +------------------------------------------------------------------------------ + +local function printf(...) + io.write(format(...)) +end + +local function fmtparams(p1, p2) + if p2 then return format("[%d, %d]", p1, p2) + elseif p1 then return format("[%d]", p1) end + return "" +end + +local function measure(min_time, name, ...) + array_init() + rand_init(RANDOM_SEED) + local run = benchmarks[name](...) + local cycles = 1 + repeat + local tm = clock() + local flops = run(cycles, ...) + tm = clock() - tm + if tm >= min_time then + local res = flops / tm * 1.0e-6 + local p1, p2 = ... + printf("%-7s %8.2f %s\n", name, res, fmtparams(...)) + return res + end + cycles = cycles * 2 + until false +end + +--printf("Lua SciMark %s based on SciMark 2.0a. %s.\n\n", +-- SCIMARK_VERSION, SCIMARK_COPYRIGHT) + +while arg and arg[1] do + local a = table.remove(arg, 1) + if a == "-noffi" then + package.preload.ffi = nil + elseif a == "-small" then + SIZE_SELECT = "small" + elseif a == "-large" then + SIZE_SELECT = "large" + elseif benchmarks[a] then + local p = benchmarks[SIZE_SELECT][a] + measure(MIN_TIME, a, tonumber(arg[1]) or p[1], tonumber(arg[2]) or p[2]) + return + else + printf("Usage: scimark [-noffi] [-small|-large] [BENCH params...]\n\n") + printf("BENCH -small -large\n") + printf("---------------------------------------\n") + for _,name in ipairs(benchmarks) do + printf("%-7s %-13s %s\n", name, + fmtparams(unpack(benchmarks.small[name])), + fmtparams(unpack(benchmarks.large[name]))) + end + printf("\n") + os.exit(1) + end +end + +local params = benchmarks[SIZE_SELECT] +local sum = 0 +for _,name in ipairs(benchmarks) do + sum = sum + measure(MIN_TIME, name, unpack(params[name])) +end +printf("\nSciMark %8.2f [%s problem sizes]\n", sum / #benchmarks, SIZE_SELECT) +io.flush() + + diff --git a/tests/lua/src/Makefile b/tests/lua/src/Makefile index 7741ef75..401e7367 100644 --- a/tests/lua/src/Makefile +++ b/tests/lua/src/Makefile @@ -10,7 +10,7 @@ PLAT= none #CC= gcc CFLAGS= -O2 -Wall -DLUA_COMPAT_ALL $(SYSCFLAGS) $(MYCFLAGS) #LDFLAGS= $(SYSLDFLAGS) $(MYLDFLAGS) -#LIBS= -lm $(SYSLIBS) $(MYLIBS) +LIBS= -lm $(SYSLIBS) $(MYLIBS) #AR= ar #RANLIB= ranlib diff --git a/tests/runner.py b/tests/runner.py index ff16cbbe..afb71ad9 100755 --- a/tests/runner.py +++ b/tests/runner.py @@ -366,7 +366,7 @@ process(sys.argv[1]) print >> sys.stderr, '<load %s from cache> ' % cache_name, generated_libs = [] for basename, contents in self.library_cache[cache_name]: - bc_file = os.path.join(build_dir, basename) + bc_file = os.path.join(build_dir, cache_name + '_' + basename) f = open(bc_file, 'wb') f.write(contents) f.close() @@ -1179,6 +1179,53 @@ m_divisor is 1091269979 ''' self.do_run(src, 'Succeeded!') + def test_i64_varargs(self): + if Settings.USE_TYPED_ARRAYS != 2: return self.skip('full i64 stuff only in ta2') + + src = r''' + #include <stdio.h> + #include <stdint.h> + #include <stdarg.h> + + int64_t ccv_cache_generate_signature(char *msg, int len, int64_t sig_start, ...) { + if (sig_start < 10123) + printf("%s\n", msg+len); + va_list v; + va_start(v, sig_start); + if (sig_start > 1413) + printf("%d\n", va_arg(v, int)); + else + printf("nada\n"); + va_end(v); + return len*sig_start*(msg[0]+1); + } + + int main(int argc, char **argv) + { + for (int i = 0; i < argc; i++) { + int64_t x; + if (i % 123123 == 0) + x = ccv_cache_generate_signature(argv[i], i+2, (int64_t)argc*argc, 54.111); + else + x = ccv_cache_generate_signature(argv[i], i+2, (int64_t)argc*argc, 13); + printf("%lld\n", x); + } + }; + ''' + self.do_run(src, '''in/this.program +nada +1536 +a +nada +5760 +fl +nada +6592 +sdfasdfasdf +nada +7840 +''', 'waka fleefl asdfasdfasdfasdf'.split(' ')) + def test_i32_mul_precise(self): if self.emcc_args == None: return self.skip('needs ta2') @@ -12593,9 +12640,18 @@ elif 'benchmark' in str(sys.argv): Building.COMPILER_TEST_OPTS = [] - TEST_REPS = 4 + TEST_REPS = 2 TOTAL_TESTS = 8 + # standard arguments for timing: + # 0: no runtime, just startup + # 1: very little runtime + # 2: 0.5 seconds + # 3: 1 second + # 4: 5 seconds + # 5: 10 seconds + DEFAULT_ARG = '4' + tests_done = 0 total_times = map(lambda x: 0., range(TOTAL_TESTS)) total_native_times = map(lambda x: 0., range(TOTAL_TESTS)) @@ -12633,15 +12689,9 @@ elif 'benchmark' in str(sys.argv): print ' JavaScript: mean: %.3f (+-%.3f) secs median: %.3f range: %.3f-%.3f (noise: %3.3f%%) (%d runs)' % (mean, std, median, min(times), max(times), 100*std/mean, reps) print ' Native : mean: %.3f (+-%.3f) secs median: %.3f range: %.3f-%.3f (noise: %3.3f%%) JS is %.2f X slower' % (mean_native, std_native, median_native, min(native_times), max(native_times), 100*std_native/mean_native, final) - def do_benchmark(self, name, src, expected_output='FAIL', args=[], emcc_args=[], native_args=[], shared_args=[], force_c=False, reps=TEST_REPS): - # standard arguments for timing: - # 0: no runtime, just startup - # 1: very little runtime - # 2: 0.5 seconds - # 3: 1 second - # 4: 5 seconds - # 5: 10 seconds - args = args or ['3'] + def do_benchmark(self, name, src, expected_output='FAIL', args=[], emcc_args=[], native_args=[], shared_args=[], force_c=False, reps=TEST_REPS, native_exec=None, output_parser=None, args_processor=None): + args = args or [DEFAULT_ARG] + if args_processor: args = args_processor(args) dirname = self.get_dir() filename = os.path.join(dirname, name + '.c' + ('' if force_c else 'pp')) @@ -12671,7 +12721,10 @@ elif 'benchmark' in str(sys.argv): if i == 0 and 'uccessfully compiled asm.js code' in js_output: if 'asm.js link error' not in js_output: print "[%s was asm.js'ified]" % name - curr = time.time()-start + if not output_parser: + curr = time.time()-start + else: + curr = output_parser(js_output) times.append(curr) total_times[tests_done] += curr if i == 0: @@ -12679,7 +12732,11 @@ elif 'benchmark' in str(sys.argv): self.assertContained(expected_output, js_output) # Run natively - self.build_native(filename, shared_args + native_args) + if not native_exec: + self.build_native(filename, shared_args + native_args) + else: + shutil.copyfile(native_exec, filename + '.native') + shutil.copymode(native_exec, filename + '.native') global total_native_times native_times = [] for i in range(reps): @@ -12688,7 +12745,10 @@ elif 'benchmark' in str(sys.argv): if i == 0: # Sanity check on output self.assertContained(expected_output, native_output) - curr = time.time()-start + if not output_parser: + curr = time.time()-start + else: + curr = output_parser(native_output) native_times.append(curr) total_native_times[tests_done] += curr @@ -12733,7 +12793,7 @@ elif 'benchmark' in str(sys.argv): return 0; } ''' - self.do_benchmark('primes', src, 'lastprime: 3043739.') + self.do_benchmark('primes', src, 'lastprime:') def test_memops(self): src = ''' @@ -12766,7 +12826,7 @@ elif 'benchmark' in str(sys.argv): return 0; } ''' - self.do_benchmark('memops', src, 'final: 400.') + self.do_benchmark('memops', src, 'final:') def zzztest_files(self): src = r''' @@ -12863,7 +12923,7 @@ elif 'benchmark' in str(sys.argv): return 0; } ''' - self.do_benchmark('copy', src, 'sum:2836\n') + self.do_benchmark('copy', src, 'sum:') def test_fannkuch(self): src = open(path_from_root('tests', 'fannkuch.cpp'), 'r').read().replace( @@ -12883,7 +12943,7 @@ elif 'benchmark' in str(sys.argv): ''' ) assert 'switch(arg)' in src - self.do_benchmark('fannkuch', src, 'Pfannkuchen(11) = 51.') + self.do_benchmark('fannkuch', src, 'Pfannkuchen(') def test_corrections(self): src = r''' @@ -12916,7 +12976,7 @@ elif 'benchmark' in str(sys.argv): return 0; } ''' - self.do_benchmark('corrections', src, 'final: 40006013:10225.', emcc_args=['-s', 'CORRECT_SIGNS=1', '-s', 'CORRECT_OVERFLOWS=1', '-s', 'CORRECT_ROUNDINGS=1']) + self.do_benchmark('corrections', src, 'final:', emcc_args=['-s', 'CORRECT_SIGNS=1', '-s', 'CORRECT_OVERFLOWS=1', '-s', 'CORRECT_ROUNDINGS=1']) def fasta(self, name, double_rep, emcc_args=[]): src = open(path_from_root('tests', 'fasta.cpp'), 'r').read().replace('double', double_rep) @@ -12934,7 +12994,7 @@ elif 'benchmark' in str(sys.argv): } ''') assert 'switch(arg)' in src - self.do_benchmark('fasta', src, '''GGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGA\nTCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACT\nAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAG\nGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCG\nCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGT\nGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCA\nGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAA\nTTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAG\nAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCA\nGCCTGGGCGA''') + self.do_benchmark('fasta', src, '') def test_fasta_float(self): self.fasta('fasta_float', 'float') @@ -12951,59 +13011,62 @@ elif 'benchmark' in str(sys.argv): def test_life(self): src = open(path_from_root('tests', 'life.c'), 'r').read() - self.do_benchmark('life', src, '''-------------------------------- - [][] [] [] - [][] [][] [] [] - [][] [] [] - [][] [] [] - [] [][] [] - [][] [] [] [] [] - [][] [] [] [] [] - [] [][] [] - [][] [][] - [][] [][] [] [] - [][] [][] [][] [] - [][] [] - [] - [] - [] [] -[] [][][] [] [] - [] [][][][][][] [] [][] - [] [][] [] [] [][] [] [] -[] [] [][] [] [] - [][] [] [][][] [][] - [] [] [][][] - [][] [][][][] - [][] [][] [] - [] [][] [] - [][] - [][] [] - [] [][][][][] -[][][] [][] - [][] [] [][][] - [] [] [][] - [] - [] [][] [][][] ---------------------------------''', shared_args=['-std=c99'], force_c=True) - - def test_nbody_java(self): # tests xmlvm compiled java, including bitcasts of doubles, i64 math, etc. + self.do_benchmark('life', src, '''--------------------------------''', shared_args=['-std=c99'], force_c=True) + + def test_zzz_java_nbody(self): # tests xmlvm compiled java, including bitcasts of doubles, i64 math, etc. args = [path_from_root('tests', 'nbody-java', x) for x in os.listdir(path_from_root('tests', 'nbody-java')) if x.endswith('.c')] + \ ['-I' + path_from_root('tests', 'nbody-java')] self.do_benchmark('nbody_java', '', '''Time(s)''', force_c=True, emcc_args=args + ['-s', 'PRECISE_I64_MATH=1', '--llvm-lto', '0'], native_args=args + ['-lgc', '-std=c99', '-target', 'x86_64-pc-linux-gnu', '-lm']) - def test_zlib(self): + def lua(self, benchmark, expected, output_parser=None, args_processor=None): + shutil.copyfile(path_from_root('tests', 'lua', benchmark + '.lua'), benchmark + '.lua') + #shutil.copyfile(path_from_root('tests', 'lua', 'binarytrees.lua'), 'binarytrees.lua') + #shutil.copyfile(path_from_root('tests', 'lua', 'scimark.lua'), 'scimark.lua') + emcc_args = self.get_library('lua', [os.path.join('src', 'lua'), os.path.join('src', 'liblua.a')], make=['make', 'generic'], configure=None) + \ + ['--embed-file', benchmark + '.lua'] + #['--embed-file', 'binarytrees.lua', '--embed-file', 'scimark.lua'] + ['--minify', '0'] + shutil.copyfile(emcc_args[0], emcc_args[0] + '.bc') + emcc_args[0] += '.bc' + native_args = self.get_library('lua_native', [os.path.join('src', 'lua'), os.path.join('src', 'liblua.a')], make=['make', 'generic'], configure=None, native=True) + + self.do_benchmark('lua_' + benchmark, '', expected, + force_c=True, args=[benchmark + '.lua'], emcc_args=emcc_args, native_args=native_args, native_exec=os.path.join('building', 'lua_native', 'src', 'lua'), + output_parser=output_parser, args_processor=args_processor) + + def test_zzz_lua_scimark(self): + def output_parser(output): + return 1.0/float(re.search('\nSciMark +([\d\.]+) ', output).group(1)) + + self.lua('scimark', '[small problem sizes]', output_parser=output_parser) + + def test_zzz_lua_binarytrees(self): + def args_processor(args): + arg = int(DEFAULT_ARG) + if arg == 0: + return args + ['0'] + elif arg == 1: + return args + ['9.5'] + elif arg == 2: + return args + ['11.99'] + elif arg == 3: + retu |