~ubuntu-branches/ubuntu/vivid/emscripten/vivid

« back to all changes in this revision

Viewing changes to tests/lua/scimark.lua

  • Committer: Package Import Robot
  • Author(s): Sylvestre Ledru
  • Date: 2013-06-11 15:45:24 UTC
  • mfrom: (1.2.1) (2.1.1 experimental)
  • Revision ID: package-import@ubuntu.com-20130611154524-rppb3w6tixlegv4n
Tags: 1.4.7~20130611~a1eb425-1
* New snapshot release
* Upload to unstable

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
------------------------------------------------------------------------------
 
2
-- Lua SciMark (2010-12-20).
 
3
--
 
4
-- A literal translation of SciMark 2.0a, written in Java and C.
 
5
-- Credits go to the original authors Roldan Pozo and Bruce Miller.
 
6
-- See: http://math.nist.gov/scimark2/
 
7
------------------------------------------------------------------------------
 
8
-- Copyright (C) 2006-2010 Mike Pall. All rights reserved.
 
9
--
 
10
-- Permission is hereby granted, free of charge, to any person obtaining
 
11
-- a copy of this software and associated documentation files (the
 
12
-- "Software"), to deal in the Software without restriction, including
 
13
-- without limitation the rights to use, copy, modify, merge, publish,
 
14
-- distribute, sublicense, and/or sell copies of the Software, and to
 
15
-- permit persons to whom the Software is furnished to do so, subject to
 
16
-- the following conditions:
 
17
--
 
18
-- The above copyright notice and this permission notice shall be
 
19
-- included in all copies or substantial portions of the Software.
 
20
--
 
21
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 
22
-- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 
23
-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 
24
-- IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 
25
-- CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 
26
-- TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 
27
-- SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
28
--
 
29
-- [ MIT license: http://www.opensource.org/licenses/mit-license.php ]
 
30
------------------------------------------------------------------------------
 
31
 
 
32
local SCIMARK_VERSION = "2010-12-10"
 
33
local SCIMARK_COPYRIGHT = "Copyright (C) 2006-2010 Mike Pall"
 
34
 
 
35
local MIN_TIME = 0.8
 
36
local RANDOM_SEED = 101009 -- Must be odd.
 
37
local SIZE_SELECT = "small"
 
38
 
 
39
local benchmarks = {
 
40
  "FFT", "SOR", "MC", "SPARSE", "LU",
 
41
  small = {
 
42
    FFT         = { 1024 },
 
43
    SOR         = { 100 },
 
44
    MC          = { },
 
45
    SPARSE      = { 1000, 5000 },
 
46
    LU          = { 100 },
 
47
  },
 
48
  large = {
 
49
    FFT         = { 1048576 },
 
50
    SOR         = { 1000 },
 
51
    MC          = { },
 
52
    SPARSE      = { 100000, 1000000 },
 
53
    LU          = { 1000 },
 
54
  },
 
55
}
 
56
 
 
57
local abs, log, sin, floor = math.abs, math.log, math.sin, math.floor
 
58
local pi, clock = math.pi, os.clock
 
59
local format = string.format
 
60
 
 
61
------------------------------------------------------------------------------
 
62
-- Select array type: Lua tables or native (FFI) arrays
 
63
------------------------------------------------------------------------------
 
64
 
 
65
local darray, iarray
 
66
 
 
67
local function array_init()
 
68
  if jit and jit.status and jit.status() then
 
69
    local ok, ffi = pcall(require, "ffi")
 
70
    if ok then
 
71
      darray = ffi.typeof("double[?]")
 
72
      iarray = ffi.typeof("int[?]")
 
73
      return
 
74
    end
 
75
  end
 
76
  function darray(n) return {} end
 
77
  iarray = darray
 
78
end
 
79
 
 
80
------------------------------------------------------------------------------
 
81
-- This is a Lagged Fibonacci Pseudo-random Number Generator with
 
82
-- j, k, M = 5, 17, 31. Pretty weak, but same as C/Java SciMark.
 
83
------------------------------------------------------------------------------
 
84
 
 
85
local rand, rand_init
 
86
 
 
87
if jit and jit.status and jit.status() then
 
88
  -- LJ2 has bit operations and zero-based arrays (internally).
 
89
  local bit = require("bit")
 
90
  local band, sar = bit.band, bit.arshift
 
91
  function rand_init(seed)
 
92
    local Rm, Rj, Ri = iarray(17), 16, 11
 
93
    for i=0,16 do Rm[i] = 0 end
 
94
    for i=16,0,-1 do
 
95
      seed = band(seed*9069, 0x7fffffff)
 
96
      Rm[i] = seed
 
97
    end
 
98
    function rand()
 
99
      local i = band(Ri+1, sar(Ri-16, 31))
 
100
      local j = band(Rj+1, sar(Rj-16, 31))
 
101
      Ri, Rj = i, j
 
102
      local k = band(Rm[i] - Rm[j], 0x7fffffff)
 
103
      Rm[j] = k
 
104
      return k * (1.0/2147483647.0)
 
105
    end
 
106
  end
 
107
else
 
108
  -- Better for standard Lua with one-based arrays and without bit operations.
 
109
  function rand_init(seed)
 
110
    local Rm, Rj = {}, 1
 
111
    for i=1,17 do Rm[i] = 0 end
 
112
    for i=17,1,-1 do
 
113
      seed = (seed*9069) % (2^31)
 
114
      Rm[i] = seed
 
115
    end
 
116
    function rand()
 
117
      local j, m = Rj, Rm
 
118
      local h = j - 5
 
119
      if h < 1 then h = h + 17 end
 
120
      local k = m[h] - m[j]
 
121
      if k < 0 then k = k + 2147483647 end
 
122
      m[j] = k
 
123
      if j < 17 then Rj = j + 1 else Rj = 1 end
 
124
      return k * (1.0/2147483647.0)
 
125
    end
 
126
  end
 
127
end
 
128
 
 
129
local function random_vector(n)
 
130
  local v = darray(n+1)
 
131
  for x=1,n do v[x] = rand() end
 
132
  return v
 
133
end
 
134
 
 
135
local function random_matrix(m, n)
 
136
  local a = {}
 
137
  for y=1,m do
 
138
    local v = darray(n+1)
 
139
    a[y] = v
 
140
    for x=1,n do v[x] = rand() end
 
141
  end
 
142
  return a
 
143
end
 
144
 
 
145
------------------------------------------------------------------------------
 
146
-- FFT: Fast Fourier Transform.
 
147
------------------------------------------------------------------------------
 
148
 
 
149
local function fft_bitreverse(v, n)
 
150
  local j = 0
 
151
  for i=0,2*n-4,2 do
 
152
    if i < j then
 
153
      v[i+1], v[i+2], v[j+1], v[j+2] = v[j+1], v[j+2], v[i+1], v[i+2]
 
154
    end
 
155
    local k = n
 
156
    while k <= j do j = j - k; k = k / 2 end
 
157
    j = j + k
 
158
  end
 
159
end
 
160
 
 
161
local function fft_transform(v, n, dir)
 
162
  if n <= 1 then return end
 
163
  fft_bitreverse(v, n)
 
164
  local dual = 1
 
165
  repeat
 
166
    local dual2 = 2*dual
 
167
    for i=1,2*n-1,2*dual2 do
 
168
      local j = i+dual2
 
169
      local ir, ii = v[i], v[i+1]
 
170
      local jr, ji = v[j], v[j+1]
 
171
      v[j], v[j+1] = ir - jr, ii - ji
 
172
      v[i], v[i+1] = ir + jr, ii + ji
 
173
    end
 
174
    local theta = dir * pi / dual
 
175
    local s, s2 = sin(theta), 2.0 * sin(theta * 0.5)^2
 
176
    local wr, wi = 1.0, 0.0
 
177
    for a=3,dual2-1,2 do
 
178
      wr, wi = wr - s*wi - s2*wr, wi + s*wr - s2*wi
 
179
      for i=a,a+2*(n-dual2),2*dual2 do
 
180
        local j = i+dual2
 
181
        local jr, ji = v[j], v[j+1]
 
182
        local dr, di = wr*jr - wi*ji, wr*ji + wi*jr
 
183
        local ir, ii = v[i], v[i+1]
 
184
        v[j], v[j+1] = ir - dr, ii - di
 
185
        v[i], v[i+1] = ir + dr, ii + di
 
186
      end
 
187
    end
 
188
    dual = dual2
 
189
  until dual >= n
 
190
end
 
191
 
 
192
function benchmarks.FFT(n)
 
193
  local l2n = log(n)/log(2)
 
194
  if l2n % 1 ~= 0 then
 
195
    io.stderr:write("Error: FFT data length is not a power of 2\n")
 
196
    os.exit(1)
 
197
  end
 
198
  local v = random_vector(n*2)
 
199
  return function(cycles)
 
200
    local norm = 1.0 / n
 
201
    for p=1,cycles do
 
202
      fft_transform(v, n, -1)
 
203
      fft_transform(v, n, 1)
 
204
      for i=1,n*2 do v[i] = v[i] * norm end
 
205
    end
 
206
    return ((5*n-2)*l2n + 2*(n+1)) * cycles
 
207
  end
 
208
end
 
209
 
 
210
------------------------------------------------------------------------------
 
211
-- SOR: Jacobi Successive Over-Relaxation.
 
212
------------------------------------------------------------------------------
 
213
 
 
214
local function sor_run(mat, m, n, cycles, omega)
 
215
  local om4, om1 = omega*0.25, 1.0-omega
 
216
  m = m - 1
 
217
  n = n - 1
 
218
  for i=1,cycles do
 
219
    for y=2,m do
 
220
      local v, vp, vn = mat[y], mat[y-1], mat[y+1]
 
221
      for x=2,n do
 
222
        v[x] = om4*((vp[x]+vn[x])+(v[x-1]+v[x+1])) + om1*v[x]
 
223
      end
 
224
    end
 
225
  end
 
226
end
 
227
 
 
228
function benchmarks.SOR(n)
 
229
  local mat = random_matrix(n, n)
 
230
  return function(cycles)
 
231
    sor_run(mat, n, n, cycles, 1.25)
 
232
    return (n-1)*(n-1)*cycles*6
 
233
  end
 
234
end
 
235
 
 
236
------------------------------------------------------------------------------
 
237
-- MC: Monte Carlo Integration.
 
238
------------------------------------------------------------------------------
 
239
 
 
240
local function mc_integrate(cycles)
 
241
  local under_curve = 0
 
242
  local rand = rand
 
243
  for i=1,cycles do
 
244
    local x = rand()
 
245
    local y = rand()
 
246
    if x*x + y*y <= 1.0 then under_curve = under_curve + 1 end
 
247
  end
 
248
  return (under_curve/cycles) * 4
 
249
end
 
250
 
 
251
function benchmarks.MC()
 
252
  return function(cycles)
 
253
    local res = mc_integrate(cycles)
 
254
    assert(math.sqrt(cycles)*math.abs(res-math.pi) < 5.0, "bad MC result")
 
255
    return cycles * 4 -- Way off, but same as SciMark in C/Java.
 
256
  end
 
257
end
 
258
 
 
259
------------------------------------------------------------------------------
 
260
-- Sparse Matrix Multiplication.
 
261
------------------------------------------------------------------------------
 
262
 
 
263
local function sparse_mult(n, cycles, vy, val, row, col, vx)
 
264
  for p=1,cycles do
 
265
    for r=1,n do
 
266
      local sum = 0
 
267
      for i=row[r],row[r+1]-1 do sum = sum + vx[col[i]] * val[i] end
 
268
      vy[r] = sum
 
269
    end
 
270
  end
 
271
end
 
272
 
 
273
function benchmarks.SPARSE(n, nz)
 
274
  local nr = floor(nz/n)
 
275
  local anz = nr*n
 
276
  local vx = random_vector(n)
 
277
  local val = random_vector(anz)
 
278
  local vy, col, row = darray(n+1), iarray(nz+1), iarray(n+2)
 
279
  row[1] = 1
 
280
  for r=1,n do
 
281
    local step = floor(r/nr)
 
282
    if step < 1 then step = 1 end
 
283
    local rr = row[r]
 
284
    row[r+1] = rr+nr
 
285
    for i=0,nr-1 do col[rr+i] = 1+i*step end
 
286
  end
 
287
  return function(cycles)
 
288
    sparse_mult(n, cycles, vy, val, row, col, vx)
 
289
    return anz*cycles*2
 
290
  end
 
291
end
 
292
 
 
293
------------------------------------------------------------------------------
 
294
-- LU: Dense Matrix Factorization.
 
295
------------------------------------------------------------------------------
 
296
 
 
297
local function lu_factor(a, pivot, m, n)
 
298
  local min_m_n = m < n and m or n
 
299
  for j=1,min_m_n do
 
300
    local jp, t = j, abs(a[j][j])
 
301
    for i=j+1,m do
 
302
      local ab = abs(a[i][j])
 
303
      if ab > t then
 
304
        jp = i
 
305
        t = ab
 
306
      end
 
307
    end
 
308
    pivot[j] = jp
 
309
    if a[jp][j] == 0 then error("zero pivot") end
 
310
    if jp ~= j then a[j], a[jp] = a[jp], a[j] end
 
311
    if j < m then
 
312
      local recp = 1.0 / a[j][j]
 
313
      for k=j+1,m do
 
314
        local v = a[k]
 
315
        v[j] = v[j] * recp
 
316
      end
 
317
    end
 
318
    if j < min_m_n then
 
319
      for i=j+1,m do
 
320
        local vi, vj = a[i], a[j]
 
321
        local eij = vi[j]
 
322
        for k=j+1,n do vi[k] = vi[k] - eij * vj[k] end
 
323
      end
 
324
    end
 
325
  end
 
326
end
 
327
 
 
328
local function matrix_alloc(m, n)
 
329
  local a = {}
 
330
  for y=1,m do a[y] = darray(n+1) end
 
331
  return a
 
332
end
 
333
 
 
334
local function matrix_copy(dst, src, m, n)
 
335
  for y=1,m do
 
336
    local vd, vs = dst[y], src[y]
 
337
    for x=1,n do vd[x] = vs[x] end
 
338
  end
 
339
end
 
340
 
 
341
function benchmarks.LU(n)
 
342
  local mat = random_matrix(n, n)
 
343
  local tmp = matrix_alloc(n, n)
 
344
  local pivot = iarray(n+1)
 
345
  return function(cycles)
 
346
    for i=1,cycles do
 
347
      matrix_copy(tmp, mat, n, n)
 
348
      lu_factor(tmp, pivot, n, n)
 
349
    end
 
350
    return 2.0/3.0*n*n*n*cycles
 
351
  end
 
352
end
 
353
 
 
354
------------------------------------------------------------------------------
 
355
-- Main program.
 
356
------------------------------------------------------------------------------
 
357
 
 
358
local function printf(...)
 
359
  io.write(format(...))
 
360
end
 
361
 
 
362
local function fmtparams(p1, p2)
 
363
  if p2 then return format("[%d, %d]", p1, p2)
 
364
  elseif p1 then return format("[%d]", p1) end
 
365
  return ""
 
366
end
 
367
 
 
368
local function measure(min_time, name, ...)
 
369
  array_init()
 
370
  rand_init(RANDOM_SEED)
 
371
  local run = benchmarks[name](...)
 
372
  local cycles = 1
 
373
  repeat
 
374
    local tm = clock()
 
375
    local flops = run(cycles, ...)
 
376
    tm = clock() - tm
 
377
    if tm >= min_time then
 
378
      local res = flops / tm * 1.0e-6
 
379
      local p1, p2 = ...
 
380
      printf("%-7s %8.2f  %s\n", name, res, fmtparams(...))
 
381
      return res
 
382
    end
 
383
    cycles = cycles * 2
 
384
  until false
 
385
end
 
386
 
 
387
--printf("Lua SciMark %s based on SciMark 2.0a. %s.\n\n",
 
388
--       SCIMARK_VERSION, SCIMARK_COPYRIGHT)
 
389
 
 
390
while arg and arg[1] do
 
391
  local a = table.remove(arg, 1)
 
392
  if a == "-noffi" then
 
393
    package.preload.ffi = nil
 
394
  elseif a == "-small" then
 
395
    SIZE_SELECT = "small"
 
396
  elseif a == "-large" then
 
397
    SIZE_SELECT = "large"
 
398
  elseif benchmarks[a] then
 
399
    local p = benchmarks[SIZE_SELECT][a]
 
400
    measure(MIN_TIME, a, tonumber(arg[1]) or p[1], tonumber(arg[2]) or p[2])
 
401
    return
 
402
  else
 
403
    printf("Usage: scimark [-noffi] [-small|-large] [BENCH params...]\n\n")
 
404
    printf("BENCH   -small         -large\n")
 
405
    printf("---------------------------------------\n")
 
406
    for _,name in ipairs(benchmarks) do
 
407
      printf("%-7s %-13s %s\n", name,
 
408
             fmtparams(unpack(benchmarks.small[name])),
 
409
             fmtparams(unpack(benchmarks.large[name])))
 
410
    end
 
411
    printf("\n")
 
412
    os.exit(1)
 
413
  end
 
414
end
 
415
 
 
416
local params = benchmarks[SIZE_SELECT]
 
417
local sum = 0
 
418
for _,name in ipairs(benchmarks) do
 
419
  sum = sum + measure(MIN_TIME, name, unpack(params[name]))
 
420
end
 
421
printf("\nSciMark %8.2f  [%s problem sizes]\n", sum / #benchmarks, SIZE_SELECT)
 
422
io.flush()
 
423
 
 
424