Skip to content

Commit

Permalink
Merge pull request #1 from stillwater-sc/computational
Browse files Browse the repository at this point in the history
freeschedule animation
  • Loading branch information
Ravenwater authored Jun 27, 2023
2 parents 5f30403 + 583859e commit ef58e0d
Show file tree
Hide file tree
Showing 6 changed files with 748 additions and 199 deletions.
14 changes: 11 additions & 3 deletions content/introduction/freeschedule.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,14 @@ categories = [ "domain-flow", "schedule" ]
series = [ "introduction" ]

+++

<canvas id="c"></canvas>
<style>
#c {
float: bottom;
padding: 5px;
width: 800px;
height: 600px;
}
</style>

We alluded to the fact that inherently-parallel algorithms exhibit some partial order, and not a total order,
because the instructions that can execute independently do not have any explicit order among each other.
Expand All @@ -39,7 +45,9 @@ then the computational activity of the specification would evolve in what is cal

The free schedule for our matrix multiply is visualized in the following, interactive, simulation:

<div id="freeschedule_animation">_</div>
<div id="freeschedule_animation" style="text-align:center">
<canvas id="c" style="border:5px solid #000;">browser doesn't support canvas tags</canvas>
</div>

We see the activity wavefront of the {{< math >}}$a${{< /math >}} recurrence (blue), the
{{< math >}}$b${{< /math >}} recurrence (purple), and the {{< math >}}$c${{< /math >}} recurrence (red)
Expand Down
1 change: 1 addition & 0 deletions content/introduction/todo.text
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
We are going to update the compitional with a visualization of event propagation
215 changes: 19 additions & 196 deletions layouts/partials/freeschedule.html
Original file line number Diff line number Diff line change
@@ -1,97 +1,32 @@


<script src="{{ .Site.BaseURL }}/js/build/three.js"></script>
<script src="{{ .Site.BaseURL }}/js/controls/OrbitControls.js"></script>
<script src="{{ .Site.BaseURL }}/js/Detector.js"></script>
<script src="{{ .Site.BaseURL }}/js/libs/numeric-1.2.6.js"></script>
<script src="{{ .Site.BaseURL }}/js/dfa/indexspace.js"></script>
<script src="{{ .Site.BaseURL }}/js/dfa/freeschedule.js"></script>
<script src="{{ .Site.BaseURL }}/js/dfa/wavefront.js"></script>

<script type="x-shader/x-vertex" id="vertexshader">

attribute float size;
attribute vec3 customColor;

varying vec3 vColor;

void main() {

vColor = customColor;

vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );

gl_PointSize = size * ( 300.0 / -mvPosition.z );

gl_Position = projectionMatrix * mvPosition;

}

</script>

<script type="x-shader/x-vertex" id="wavefrontshader">
uniform float time;
uniform float cardinality;
attribute float schedule;
attribute float size;
attribute vec3 customColor;

varying vec3 vColor;

void main() {

vColor = customColor;

vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );

// scale particles as objects in 3D space that modulate in size as a computational wavefront passes through
float period = mod(time, cardinality); // set a modulo range so the visualization cycles

// modulate a full sinusoid long: (sin(-pi/2), sin(3*pi/2))
if (period > (schedule - 1.0) && period < (schedule + 1.0)) {

gl_PointSize = (1.5 + sin((period - schedule)*3.14 + 1.57)) * ( 300.0 / length( mvPosition.xyz ) );

} else {

gl_PointSize = size * ( 100.0 / -mvPosition.z );

<!-- Import maps polyfill -->
<!-- Remove this when import maps will be widely supported -->
<script async src="https://unpkg.com/es-module-shims@1.3.6/dist/es-module-shims.js"></script>

<script type="importmap">
{
"imports": {
"three": "{{ .Site.BaseURL }}/js/build/three.module.js",
"three/addons/": "{{ .Site.BaseURL }}/jsm/"
}

gl_Position = projectionMatrix * mvPosition;

}
</script>

</script>
<script type="x-shader/x-vertex" id="vertexshader">

<script type="x-shader/x-vertex" id="wavefrontshader2">
uniform float time;
uniform float cardinality;
attribute float schedule;
attribute float size;
attribute vec3 customColor;
attribute vec3 ca;

varying vec3 vColor;

void main() {

vColor = customColor;
vColor = ca;

vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );

// scale particles as objects in 3D space that modulate in size as a computational wavefront passes through
float period = mod(time, cardinality); // set a modulo range so the visualization cycles

// modulate a full sinusoid long: (sin(-pi/2), sin(3*pi/2))
if (period > (schedule - 1.0) && period < (schedule + 1.0)) {

gl_PointSize = (1.5 + sin((period - schedule)*3.14 + 1.57)) * ( 300.0 / length( mvPosition.xyz ) );

} else {

gl_PointSize = size * ( 100.0 / -mvPosition.z );

}
gl_PointSize = size * ( 300.0 / -mvPosition.z );

gl_Position = projectionMatrix * mvPosition;

Expand All @@ -102,131 +37,19 @@
<script type="x-shader/x-fragment" id="fragmentshader">

uniform vec3 color;
uniform sampler2D texture;
uniform sampler2D pointTexture;

varying vec3 vColor;

void main() {

gl_FragColor = vec4( color * vColor, 1.0 );

gl_FragColor = gl_FragColor * texture2D( texture, gl_PointCoord );
vec4 color = vec4( color * vColor, 1.0 ) * texture2D( pointTexture, gl_PointCoord );

if ( gl_FragColor.a < ALPHATEST ) discard;
gl_FragColor = color;

}

</script>

<script>
if ( ! Detector.webgl ) Detector.addGetWebGLMessage();

var scenes = [];
var views = [];
var t, canvas, renderer;
var PARTICLE_SIZE = 2;
var clock = new THREE.Clock( true );

window.onload = init;

function init() {
canvas = document.getElementById( 'c' );

renderer = new THREE.WebGLRenderer( { canvas: canvas, antialias: true } );
renderer.setClearColor( 0xffffff );
renderer.setPixelRatio( window.devicePixelRatio );

var renderTarget = "{{ .Params.RenderTargetName }}";
var view = document.getElementById( renderTarget );
views.push( view );

{ // view to animate the matmul free schedule
var lattice1 = createIndexSpaceGeometry(20, 20, 20, 1, false, true);
var pointSize1 = PARTICLE_SIZE * 0.5;

var texturePath = "{{ .Site.BaseURL }}/textures/sprites/ball.png";
// cardinality of the simulation is from [3, 60]
uniforms1 = {
cardinality: { value: 60.0 },
time: { value: 1.0 },
color: { value: new THREE.Color( 0xffffff ) },
texture: { value: new THREE.TextureLoader().load( texturePath ) }
};
var scene1 = createFreeScheduleWavefrontScene( lattice1, pointSize1, 'wavefrontshader', 'fragmentshader', uniforms1, schedule );
scene1.userData.view = view;

// PerspectiveCamera ( fov, aspectRatio, near clipping plane, var clipping plane )
var camera1 = new THREE.PerspectiveCamera( 75, 1, 0.1, 1000 );
camera1.position.set( 25, 25, 25 ); // ( x = 0, y = 0, z = 25 )
scene1.userData.camera = camera1;

var controls1 = new THREE.OrbitControls( camera1, view );
controls1.minDistance = 20; // zoom can't zoom in further than z = 20
controls1.maxDistance = 500; // zoom can't zoom out further than z = 500
scene1.userData.controls = controls1;

scenes.push( scene1 );
}

t = 0;
animate();

}

function updateSize() {
var width = canvas.clientWidth;
var height = canvas.clientHeight;

if ( canvas.width !== width || canvas.height != height ) {
renderer.setSize( width, height, false );
}
}

function animate() {
render();
requestAnimationFrame( animate );
}

function schedule( tau, index ) {
return numeric.dot(tau, index);
}

function render() {
updateSize();

// the ScissorTest machinery is needed to make the viewport clipping work properly.
renderer.setClearColor( 0xffffff );
renderer.setScissorTest( false );
renderer.clear();

renderer.setClearColor( 0x000000 );
renderer.setScissorTest( true );

scenes.forEach( function( scene ) {

var rect = scene.userData.view.getBoundingClientRect();
// check if it's off-screen. If so skip it
if ( rect.bottom < 0 || rect.top > renderer.domElement.clientHeight ||
rect.right < 0 || rect.left > renderer.domElement.clientWidth ) {
return; // it's off-screen so skip the renderering
}

// set the viewport
var width = rect.right - rect.left;
var height = rect.bottom - rect.top;
var left = rect.left;
var bottom = renderer.domElement.clientHeight - rect.bottom;
renderer.setViewport( left, bottom, width, height );
renderer.setScissor( left, bottom, width, height );

uniforms1.time.value = t;
renderer.render( scene, scene.userData.camera );

scene.children[0].geometry.verticesNeedUpdate = true;

} );
</script>

t = clock.getElapsedTime();
}
<script type="module" src="{{ .Site.BaseURL }}/js/dfa/freeschedule_matmul.js"></script>

</script>
Loading

0 comments on commit ef58e0d

Please sign in to comment.