From 4fa7012e03e09fa62bd0080f2c7bfbf02b00a6ca Mon Sep 17 00:00:00 2001 From: Marvin Borner Date: Sun, 7 Apr 2024 14:40:15 +0200 Subject: Experiments with parallel reduction workers --- bruijn/Experiments.bruijn | 83 ++----- canvasWorker.js | 104 +++++++++ common.js | 68 ++++++ index.html | 48 +++-- main.js | 289 +++++++++++++++++++++++++ readme.md | 14 ++ reductionWorker.js | 224 +++++++++++++++++++ script.js | 537 ---------------------------------------------- worker.js | 90 -------- 9 files changed, 756 insertions(+), 701 deletions(-) create mode 100644 canvasWorker.js create mode 100644 common.js create mode 100644 main.js create mode 100644 readme.md create mode 100644 reductionWorker.js delete mode 100644 script.js delete mode 100644 worker.js diff --git a/bruijn/Experiments.bruijn b/bruijn/Experiments.bruijn index 2e2173d..d1bc116 100644 --- a/bruijn/Experiments.bruijn +++ b/bruijn/Experiments.bruijn @@ -1,63 +1,26 @@ :import std/Combinator . -:import Screen . - -# stable -s w - -a-sierpinski0 [build w w w w] - -a-sierpinski1 [build tl tr bl br] - tl build w w w (build w s s b) - tr build w w (build s w b s) w - bl build w (build s b w s) w w - br build (build b s s w) w w w - -a-sierpinski2 [build tl tr bl br] - tl build tl tr bl br - tl build w w w (build w s s b) - tr build w w (build s w b s) w - bl build w (build s b w s) w w - br build (build b s s w) s s b - tr build tl tr bl br - tl build w w w (build w s s b) - tr build w w (build s w b s) w - bl build s (build s b w s) b s - br build (build b s s w) w w w - bl build tl tr bl br - tl build w w w (build w s s b) - tr build s b (build s w b s) s - bl build w (build s b w s) w w - br build (build b s s w) w w w - br build tl tr bl br - tl build b s s (build w s s b) - tr build w w (build s w b s) w - bl build w (build s b w s) w w - br build (build b s s w) w w w - -b-sierpinski0 y [gen] - gen qsplit → color - color &[[[[[0 (5 (tl 4)) (5 (tr 3)) (5 (bl 2)) (5 (br 1))]]]]] - tl &[[[[[0 4 3 2 b]]]]] - tr &[[[[[0 4 3 b 1]]]]] - bl &[[[[[0 4 b 2 1]]]]] - br &[[[[[0 b 3 2 1]]]]] - :import std/List . +:import Screen . -b-sierpinski1 color - color [[build tl tr bl br] mut] - mut y* ([[[[build 3 2 1 b]]]] : ([[[[build 3 2 b 0]]]] : ([[[[build 3 b 1 0]]]] : {}[[[[build b 2 1 0]]]]))) - tl ^0 - tr ^(~0) - bl ^(~(~0)) - br ^(~(~(~0))) - -:import std/Number . - -b-sierpinskin y [[[=?1 0 (gen 0)]]] (+7) - gen qsplit → color - color &[[[[[0 (7 --6 (tl 4)) (7 --6 (tr 3)) (7 --6 (bl 2)) (7 --6 (br 1))]]]]] - tl &[[[[[0 4 3 2 b]]]]] - tr &[[[[[0 4 3 b 1]]]]] - bl &[[[[[0 4 b 2 1]]]]] - br &[[[[[0 b 3 2 1]]]]] +t-square-1 [[build tl tr bl br] mut] + mut y* ([[[[build 3 2 1 b]]]] : ([[[[build 3 2 b 0]]]] : ([[[[build 3 b 1 0]]]] : {}[[[[build b 2 1 0]]]]))) + tl ^0 + tr ^(~0) + bl ^(~(~0)) + br ^(~(~(~0))) + +t-square-2 [[build tl tr bl br] mut] + mut y* ([[[[build 3 2 1 (build b w w b)]]]] : ([[[[build 3 2 (build w b b w) 0]]]] : ([[[[build 3 (build w b b w) 1 0]]]] : {}[[[[build (build b w w b) 2 1 0]]]]))) + tl ^0 + tr ^(~0) + bl ^(~(~0)) + br ^(~(~(~0))) + +sierpinski-carpet [[build tl tr bl br] mut] + mut y* ([[[[build 3 2 1 (build (build b w w w) w w b)]]]] : ([[[[build 3 2 (build w (build w b w w) b w) 0]]]] : ([[[[build 3 (build w b (build w w b w) w) 1 0]]]] : {}[[[[build (build b w w (build w w w b)) 2 1 0]]]]))) + tl ^0 + tr ^(~0) + bl ^(~(~0)) + br ^(~(~(~0))) + +sierpinski-triangle [y [build 0 b 0 0]] diff --git a/canvasWorker.js b/canvasWorker.js new file mode 100644 index 0000000..4b1e81b --- /dev/null +++ b/canvasWorker.js @@ -0,0 +1,104 @@ +let canvas, gl; + +const createShader = (gl, type, source) => { + const shader = gl.createShader(type); + gl.shaderSource(shader, source); + gl.compileShader(shader); + const success = gl.getShaderParameter(shader, gl.COMPILE_STATUS); + if (success) return shader; + + console.error(gl.getShaderInfoLog(shader)); + gl.deleteShader(shader); +}; + +const createProgram = (gl, vertexShader, fragmentShader) => { + const program = gl.createProgram(); + gl.attachShader(program, vertexShader); + gl.attachShader(program, fragmentShader); + gl.linkProgram(program); + const success = gl.getProgramParameter(program, gl.LINK_STATUS); + if (success) return program; + + console.error(gl.getProgramInfoLog(program)); + gl.deleteProgram(program); +}; + +const initGL = () => { + const vertexShaderSource = ` + attribute vec2 a_position; + uniform vec2 u_resolution; + void main() { + vec2 inverted = vec2(a_position.x, u_resolution.y - a_position.y - 1.0); // !! :) + vec2 zeroToOne = inverted / u_resolution; + vec2 zeroToTwo = zeroToOne * 2.0; + vec2 clipSpace = zeroToTwo - 1.0; + gl_Position = vec4(clipSpace, 0, 1); + }`; + const fragmentShaderSource = ` + precision mediump float; + uniform vec4 u_color; + void main() { + gl_FragColor = u_color; + }`; + + const vertexShader = createShader(gl, gl.VERTEX_SHADER, vertexShaderSource); + const fragmentShader = createShader( + gl, + gl.FRAGMENT_SHADER, + fragmentShaderSource, + ); + + const program = createProgram(gl, vertexShader, fragmentShader); + const positionAttributeLocation = gl.getAttribLocation(program, "a_position"); + const colorUniformLocation = gl.getUniformLocation(program, "u_color"); + const resolutionUniformLocation = gl.getUniformLocation( + program, + "u_resolution", + ); + + const positionBuffer = gl.createBuffer(); + gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer); + gl.viewport(0, 0, gl.canvas.width, gl.canvas.height); + gl.useProgram(program); + gl.uniform2f(resolutionUniformLocation, gl.canvas.width, gl.canvas.height); + gl.enableVertexAttribArray(positionAttributeLocation); + gl.vertexAttribPointer(positionAttributeLocation, 2, gl.FLOAT, false, 0, 0); + + return (positions, color) => { + gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW); + gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer); + gl.uniform4f(colorUniformLocation, ...color); + gl.drawArrays(gl.TRIANGLE_FAN, 0, 4); + }; +}; + +let draw; +self.onmessage = (msg) => { + if (msg.data == "clear") { + gl.clearColor(0, 0, 0, 0); + gl.clear(gl.COLOR_BUFFER_BIT); + } else if ("canvas" in msg.data) { + canvas = msg.data.canvas; + gl = canvas.getContext("webgl", { preserveDrawingBuffer: true }); + if (!gl) alert("no webgl"); + gl.viewport(0, 0, canvas.width, canvas.height); + draw = initGL(); + } else { + [color, x, y, width, height] = msg.data; + if (width < 2 || height < 2) return; + draw([x, y + height, x + width, y + height, x + width, y, x, y], color); + } +}; + +// self.onmessage = (msg) => { +// if (msg.data == "clear") { +// gl.clearRect(0, 0, canvas.width, canvas.height); +// } else if ("canvas" in msg.data) { +// canvas = msg.data.canvas; +// gl = canvas.getContext("2d"); +// } else { +// [color, x, y, width, height] = msg.data; +// gl.fillStyle = color; +// gl.fillRect(x, y, width, height); +// } +// }; diff --git a/common.js b/common.js new file mode 100644 index 0000000..b8e8464 --- /dev/null +++ b/common.js @@ -0,0 +1,68 @@ +/* lambda calculus */ + +const allHashes = {}; +const hash = (s) => { + let h = 0; + for (let i = 0; i < s.length; i++) { + const chr = s.charCodeAt(i); + h = (h << 5) - h + chr; + h |= 0; + } + while (h in allHashes && allHashes[h] !== s) h += 1; + allHashes[h] = s; + return h; +}; + +const abs = (body) => { + if (body === null) return null; + const t = { type: "abs", body }; + t.hash = hash("abs" + body.hash); + return t; +}; + +const app = (left) => (right) => { + if (left === null || right === null) return null; + const t = { type: "app", left, right }; + t.hash = hash("app" + left.hash + right.hash); + return t; +}; + +const idx = (idx) => { + if (idx === null) return null; + const t = { type: "idx", idx }; + t.hash = hash("idx" + idx); + return t; +}; + +const def = (name) => { + const t = { type: "def", name }; + t.hash = hash("def" + name); + return t; +}; + +/* lambda screen */ + +const WHITE = 0; +const BLACK = 1; +const UNKNOWN = 2; + +// [[1]]=w, [[0]]=b, other=g +const toColor = (t) => { + if (t.type === "abs" && t.body.type === "abs" && t.body.body.type === "idx") + return t.body.body.idx === 1 + ? WHITE + : t.body.body.idx === 0 + ? BLACK + : UNKNOWN; + return UNKNOWN; +}; + +// [((((0 tl) tr) bl) br)] +const seemsScreeny = (t) => + t.type === "abs" && + t.body.type === "app" && + t.body.left.type === "app" && + t.body.left.left.type === "app" && + t.body.left.left.left.type === "app" && + t.body.left.left.left.left.type === "idx" && + t.body.left.left.left.left.idx === 0; diff --git a/index.html b/index.html index d1997cb..e3b28f9 100644 --- a/index.html +++ b/index.html @@ -9,17 +9,17 @@