// // benchmark // // Neil Gershenfeld // (c) Massachusetts Institute of Technology 2016 // // This work may be reproduced, modified, distributed, performed, and // displayed for any purpose, but must acknowledge the mods // project. Copyright is retained and must be preserved. The work is // provided as is; no warranty is provided, and users accept all // liability. // // closure // (function(){ // // module globals // var mod = {} // // name // var name = 'glsl_benchmark' // // initialization // var init = function() { mod.terms.value = '1e8' } // // inputs // var inputs = { start:{type:'event', event:function(evt){ benchmark()}}} // // outputs // var outputs = { } // // interface // var interface = function(div){ mod.div = div var canvas = document.createElement('canvas'); canvas.style.display = "none"; div.appendChild(canvas) div.appendChild(document.createTextNode('terms to sum: ')) var input = document.createElement('input') input.type = 'text' input.size = 6 div.appendChild(input) mod.terms = input div.appendChild(document.createElement('br')) var btn = document.createElement('button') btn.style.padding = mods.ui.padding btn.style.margin = 1 var text = document.createTextNode('calculate pi') mod.label = text btn.appendChild(text) btn.addEventListener('click',function() { benchmark() }) mod.button = btn div.appendChild(btn) div.appendChild(document.createElement('br')) var text = document.createTextNode('value: ') div.appendChild(text) mod.value = text div.appendChild(document.createElement('br')) var text = document.createTextNode('time (s): ') div.appendChild(text) mod.time = text div.appendChild(document.createElement('br')) var text = document.createTextNode('Mflops: ') div.appendChild(text) mod.mflops = text } // // local functions // function benchmark() { mod.label.nodeValue = 'calculating'; var numTerms = parseFloat(mod.terms.value); var output = calcPI(numTerms); mod.value.nodeValue = 'value: '+output.pi.toFixed(6); var sec = output.dt/1000 mod.time.nodeValue = 'time (s): '+sec var mflops = 5*numTerms/(sec*1e6) mod.mflops.nodeValue = 'Mflops: '+mflops.toFixed(0) mod.label.nodeValue = 'calculate pi' } var vertexShaderSource = "" + "attribute vec2 a_position;"+ "void main() { "+ "gl_Position = vec4(a_position, 0, 1);"+ "}" var fragmentShaderSource = "" + "precision mediump float;"+ "uniform float u_matrixDim;"+ "uniform float u_offset;"+ "" + "float shift_right (float v, float amt) {" + "v = floor(v) + 0.5;" + "return floor(v / exp2(amt));" + "}"+ "float shift_left (float v, float amt) {" + "return floor(v * exp2(amt) + 0.5);" + "}"+ "float mask_last (float v, float bits) {"+ "return mod(v, shift_left(1.0, bits));"+ "}"+ "float extract_bits (float num, float from, float to) {"+ "from = floor(from + 0.5); to = floor(to + 0.5);"+ "return mask_last(shift_right(num, from), to - from);"+ "}"+ "vec4 encode_float (float val) {"+ "if (val == 0.0) return vec4(0, 0, 0, 0);"+ "float sign = val > 0.0 ? 0.0 : 1.0;"+ "val = abs(val);"+ "float exponent = floor(log2(val));"+ "float biased_exponent = exponent + 127.0;" + "float fraction = ((val / exp2(exponent)) - 1.0) * 8388608.0;"+ "float t = biased_exponent / 2.0;"+ "float last_bit_of_biased_exponent = fract(t) * 2.0;"+ "float remaining_bits_of_biased_exponent = floor(t);"+ "float byte4 = extract_bits(fraction, 0.0, 8.0) / 255.0;" + "float byte3 = extract_bits(fraction, 8.0, 16.0) / 255.0;" + "float byte2 = (last_bit_of_biased_exponent * 128.0 + extract_bits(fraction, 16.0, 23.0)) / 255.0;" + "float byte1 = (sign * 128.0 + remaining_bits_of_biased_exponent) / 255.0;" + "return vec4(byte4, byte3, byte2, byte1);" + "}"+ "" + "void main(){" + "vec2 fragCoord = gl_FragCoord.xy;"+ "float index = fragCoord.x + 0.5 + (fragCoord.y-0.5)*u_matrixDim + u_offset;"+ "gl_FragColor = encode_float(0.5/((index-0.75)*(index-0.25)));"+ "}"; /** * Created by ghassaei on 2/20/16. */ function calcPI(numTerms) { // Get A WebGL context var canvas = document.getElementsByTagName("canvas")[0]; var gl = canvas.getContext("webgl", {antialias:false}) || canvas.getContext("experimental-webgl", {antialias:false}); if (!gl) { alert('Could not initialize WebGL, try another browser'); return; } gl.disable(gl.DEPTH_TEST); gl.getExtension('OES_texture_float'); var matrixDim = 1024; var matrixSize = matrixDim*matrixDim; gl.viewport(0, 0, matrixDim, matrixDim); canvas.clientWidth = matrixDim; canvas.clientHeight = matrixDim; var numMatrices = Math.ceil(numTerms/matrixSize); var offsets = []; for (var i=0;i