Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save marioroy/e785bdb94742633b67e1138a21085013 to your computer and use it in GitHub Desktop.
Save marioroy/e785bdb94742633b67e1138a21085013 to your computer and use it in GitHub Desktop.
#!/usr/bin/env perl
# Parallel demonstration for Monte Carlo Pi Calculation
# https://gist.github.com/dmr3/f435e84fb26f4de2e0c8e1f2d2e74f9b
#
# Original source by Demian Riccardi
# Parallel demonstration by Mario Roy
use Mojolicious::Lite;
use MCE::Hobo;
use MCE::Shared;
any '/' => sub {
my $self = shift;
$self->render( 'index', rows => [ [] ] );
};
# setup websocket message handler
websocket '/more_pi' => sub {
my $self = shift;
$self->inactivity_timeout(3000);
$self->on(
json => sub {
my $ws = shift;
my $args = shift;
my ( $pi, $total_runs, $new_runs ) = @$args;
# my $cnt_pi = -1 * ( ( $pi * $total_runs ) / 4 - $total_runs );
# my ( $x, $y );
#
# foreach ( 1 .. $new_runs ) {
# $x = rand(1);
# $y = rand(1);
# $cnt_pi++ if $x * $x + $y * $y > 1;
# }
my $cnt_pi = MCE::Shared->scalar(
-1 * ( ( $pi * $total_runs ) / 4 - $total_runs )
);
my $seq = MCE::Shared->sequence(
{ chunk_size => 5000, bounds_only => 1 },
1, $new_runs
);
my $task = sub {
my ( $cnt, $x, $y ) = ( 0 );
while ( my ( $beg, $end ) = $seq->next ) {
foreach ( $beg .. $end ) {
$x = rand(1);
$y = rand(1);
$cnt++ if $x * $x + $y * $y > 1;
}
}
$cnt_pi->incrby( $cnt );
};
MCE::Hobo->create( { posix_exit => 1 }, $task ) for 1 .. 4;
MCE::Hobo->waitall;
$total_runs += $new_runs;
$pi = 4 * ( $total_runs - $cnt_pi->get ) / $total_runs;
my $html = $ws->render_to_string( 'table',
rows => [ [ $pi, $total_runs ] ] );
$ws->send(
{
json => {
row => $html,
vals => [ $pi, $total_runs, $new_runs ],
target => '#table', #for fun
}
}
);
}
);
};
app->start;
__DATA__
@@ index.html.ep
<!DOCTYPE html>
<html>
<head>
<title>Monte Carlo pi</title>
<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css" rel="stylesheet">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
</head>
<body>
<div class=container>
%= include 'mcpiform'
<div class="row"><div class="col-md-6">
<table class="table table-bordered table-condensed">
<thead>
<tr><th>Calculated &#960;</th><th> Total runs</th></tr>
</thead>
<tbody id="table">
%= include 'table'
</tbody>
</table>
</div></div>
</div>
%= javascript 'js/ws.js'
</body>
</html>
@@ mcpiform.html.ep
<div class="form-inline" role="form">
<div class="form-group">
<label for="mcpi">Starting &#960;</label>
<input type="text" class="form-control" id="mcpif" value="0">
</div>
<div class="form-group">
<label for="truns"> Total runs</label>
<input type="text" class="form-control" id="trunsf" value="0">
</div>
<div class="form-group">
<label for="nruns"> New runs</label>
<input type="text" class="form-control" id="nrunsf" value="10000">
</div>
<div class="form-group">
<label for="nitrs"> Repeats </label>
<input type="text" class="form-control" id="nitrsf" value="1">
</div>
<input type="submit" value="Add" id="pibutton" onclick="update_pi( '<%= url_for('more_pi')->to_abs %>')" >
</div>
@@ table.html.ep
% foreach my $row (@$rows) {
<tr>
% foreach my $text (@$row) {
<td><%= $text %></td>
% }
</tr>
% }
@@ js/ws.js
function update_pi (url) {
if (!("WebSocket" in window)) {
alert('Your browser does not support WebSockets!');
return;
}
$('#pibutton').prop("disabled",true);
var ws = new WebSocket(url);
var counter = $('#nitrsf').val();
var save_cnt = $('#nitrsf').val();
ws.onopen = function () {
var mcpi = $('#mcpif');
var trun = $('#trunsf');
var nrun = $('#nrunsf');
ws.send(JSON.stringify([mcpi.val(),trun.val(),nrun.val()]));
counter--;
};
console.log(counter);
ws.onmessage = function (evt) {
var data = JSON.parse(evt.data);
$(data.target).append(data.row);
if(counter > 0){
ws.send(JSON.stringify( [data.vals[0],data.vals[1],data.vals[2]]));
counter--;
if (counter === 0) {
$('#pibutton').prop("disabled",false);
}
}
//$('#table').append(data.row);
//insert values into form for convenience
$('#mcpif').val(data.vals[0]);
$('#trunsf').val(data.vals[1]);
$('#nrunsf').val(data.vals[2]);
$('#nitrsf').val(save_cnt);
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment