[pypy-commit] extradoc extradoc: lua version of runner

hakanardo noreply at buildbot.pypy.org
Tue Aug 14 10:46:43 CEST 2012


Author: Hakan Ardo <hakan at debian.org>
Branch: extradoc
Changeset: r4556:ad4980856b89
Date: 2012-08-14 10:45 +0200
http://bitbucket.org/pypy/extradoc/changeset/ad4980856b89/

Log:	lua version of runner

diff --git a/talk/iwtc11/benchmarks/benchmark.sh b/talk/iwtc11/benchmarks/benchmark.sh
--- a/talk/iwtc11/benchmarks/benchmark.sh
+++ b/talk/iwtc11/benchmarks/benchmark.sh
@@ -24,6 +24,9 @@
     ./runner.py -n 5 -c "$*" scimark/run_LU.c 100 4096
     ./runner.py -n 5 -c "$*" scimark/run_LU.c 1000 2
     rm a.out
+elif [[ "$1" == luajit* ]]; then
+    $* runner.lua SOR 100 32768
+    $* runner.lua SOR 1000 256
 else
     if [ "$1" == "python2.7" ]; then
         EXTRA_OPTS='-w 0 -n 1'
diff --git a/talk/iwtc11/benchmarks/runall.sh b/talk/iwtc11/benchmarks/runall.sh
--- a/talk/iwtc11/benchmarks/runall.sh
+++ b/talk/iwtc11/benchmarks/runall.sh
@@ -10,3 +10,6 @@
 ./benchmark.sh gcc -O3 -march=native -fno-tree-vectorize
 ./benchmark.sh python2.7
 ./benchmark.sh python2.6 psyco-wrapper.py
+./benchmark.sh luajit-2.0.0-beta10
+./benchmark.sh luajit-2.0.0-beta10 -O-loop
+./benchmakr.sh luajit
diff --git a/talk/iwtc11/benchmarks/runner.lua b/talk/iwtc11/benchmarks/runner.lua
new file mode 100644
--- /dev/null
+++ b/talk/iwtc11/benchmarks/runner.lua
@@ -0,0 +1,41 @@
+require('scimark')
+require('stats')
+local pi, clock = math.pi, os.clock
+
+local benchmarks = {}
+
+function benchmarks.SOR(n, cycles)
+    n, cycles = tonumber(n), tonumber(cycles)
+    local mat = scimark.random_matrix(n, n)
+    scimark.sor_run(mat, n, n, cycles, 1.25)
+    return string.format('SOR(%d, %d)', n, cycles)
+end
+
+function measure(name, ...)
+    scimark.array_init()
+    scimark.rand_init(101009)
+    local run = benchmarks[name]
+    io.stderr:write('waming up')
+    for i=1,3 do
+        run(...)
+        io.stderr:write('.')
+    end
+    io.stderr:write('\n')
+    io.stderr:write('benchmarking\n')
+    all = {}
+    for i=1,10 do
+        local tm = clock()
+        fullname = run(...)
+        tm = clock() - tm
+        io.stderr:write(string.format('Next: %f\n', tm))
+        table.insert(all, tm)
+    end
+    io.write(string.format('%s: %f +- %f\n', fullname, stats.stats.mean(all), stats.stats.standardDeviation(all)))
+end
+
+local function main(args)
+    measure(unpack(args))
+end
+
+main(arg)
+
diff --git a/talk/iwtc11/benchmarks/scimark.lua b/talk/iwtc11/benchmarks/scimark.lua
new file mode 100644
--- /dev/null
+++ b/talk/iwtc11/benchmarks/scimark.lua
@@ -0,0 +1,428 @@
+------------------------------------------------------------------------------
+-- 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 ]
+------------------------------------------------------------------------------
+module(..., package.seeall);
+
+local SCIMARK_VERSION = "2010-12-10"
+local SCIMARK_COPYRIGHT = "Copyright (C) 2006-2010 Mike Pall"
+
+local MIN_TIME = 2.0
+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
+
+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
+
+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.
+------------------------------------------------------------------------------
+
+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
+
+function main()
+    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()
+end
+
+-- main()
diff --git a/talk/iwtc11/benchmarks/scimark/run_LU.c b/talk/iwtc11/benchmarks/scimark/run_LU.c
--- a/talk/iwtc11/benchmarks/scimark/run_LU.c
+++ b/talk/iwtc11/benchmarks/scimark/run_LU.c
@@ -26,7 +26,7 @@
         LU_factor(N, N, lu, pivot);
     }
 
-    fprintf(stderr, "LU(%d, %d):    ", N, cycles);
+    fprintf(stderr, "LU(%d,%d):    ", N, cycles);
     return 0;
 }
     
diff --git a/talk/iwtc11/benchmarks/scimark/run_SOR.c b/talk/iwtc11/benchmarks/scimark/run_SOR.c
--- a/talk/iwtc11/benchmarks/scimark/run_SOR.c
+++ b/talk/iwtc11/benchmarks/scimark/run_SOR.c
@@ -12,6 +12,6 @@
     int i;
     for (i=0; i<N; i++) G[i] = calloc(sizeof(double), N);
     SOR_execute(N, N, 1.25, G, cycles);
-    fprintf(stderr, "SOR(%d, %d):  ", N, cycles);
+    fprintf(stderr, "SOR(%d,%d):  ", N, cycles);
     return 0;
 }
diff --git a/talk/iwtc11/benchmarks/scimark/run_SparseMatMult.c b/talk/iwtc11/benchmarks/scimark/run_SparseMatMult.c
--- a/talk/iwtc11/benchmarks/scimark/run_SparseMatMult.c
+++ b/talk/iwtc11/benchmarks/scimark/run_SparseMatMult.c
@@ -43,7 +43,7 @@
         }
 
     SparseCompRow_matmult(N, y, val, row, col, x, cycles);
-    fprintf(stderr, "SparseMatMult(%d, %d, %d):  ", N, nz, cycles);
+    fprintf(stderr, "SparseMatMult(%d,%d,%d):  ", N, nz, cycles);
     return 0;
 }
 
diff --git a/talk/iwtc11/benchmarks/stats.lua b/talk/iwtc11/benchmarks/stats.lua
new file mode 100644
--- /dev/null
+++ b/talk/iwtc11/benchmarks/stats.lua
@@ -0,0 +1,122 @@
+-- Small stats library                      --
+----------------------------------------------
+-- Version History --
+-- 1.0 First written.
+module(..., package.seeall);
+
+-- Tables supplied as arguments are not changed.
+
+
+-- Table to hold statistical functions
+stats={}
+
+-- Get the mean value of a table
+function stats.mean( t )
+  local sum = 0
+  local count= 0
+
+  for k,v in pairs(t) do
+    if type(v) == 'number' then
+      sum = sum + v
+      count = count + 1
+    end
+  end
+
+  return (sum / count)
+end
+
+-- Get the mode of a table.  Returns a table of values.
+-- Works on anything (not just numbers).
+function stats.mode( t )
+  local counts={}
+
+  for k, v in pairs( t ) do
+    if counts[v] == nil then
+      counts[v] = 1
+    else
+      counts[v] = counts[v] + 1
+    end
+  end
+
+  local biggestCount = 0
+
+  for k, v  in pairs( counts ) do
+    if v > biggestCount then
+      biggestCount = v
+    end
+  end
+
+  local temp={}
+
+  for k,v in pairs( counts ) do
+    if v == biggestCount then
+      table.insert( temp, k )
+    end
+  end
+
+  return temp
+end
+
+-- Get the median of a table.
+function stats.median( t )
+  local temp={}
+
+  -- deep copy table so that when we sort it, the original is unchanged
+  -- also weed out any non numbers
+  for k,v in pairs(t) do
+    if type(v) == 'number' then
+      table.insert( temp, v )
+    end
+  end
+
+  table.sort( temp )
+
+  -- If we have an even number of table elements or odd.
+  if math.fmod(#temp,2) == 0 then
+    -- return mean value of middle two elements
+    return ( temp[#temp/2] + temp[(#temp/2)+1] ) / 2
+  else
+    -- return middle element
+    return temp[math.ceil(#temp/2)]
+  end
+end
+    
+
+-- Get the standard deviation of a table
+function stats.standardDeviation( t )
+  local m
+  local vm
+  local sum = 0
+  local count = 0
+  local result
+
+  m = stats.mean( t )
+
+  for k,v in pairs(t) do
+    if type(v) == 'number' then
+      vm = v - m
+      sum = sum + (vm * vm)
+      count = count + 1
+    end
+  end
+
+  result = math.sqrt(sum / (count-1))
+
+  return result
+end
+
+-- Get the max and min for a table
+function stats.maxmin( t )
+  local max = -math.huge
+  local min = math.huge
+
+  for k,v in pairs( t ) do
+    if type(v) == 'number' then
+      max = math.max( max, v )
+      min = math.min( min, v )
+    end
+  end
+
+  return max, min
+end
+


More information about the pypy-commit mailing list