Gameoflife¶
Python Numpy¶
from __future__ import print_function
"""
Game of Life
------------
"""
from benchpress.benchmarks import util
import numpy as np
bench = util.Benchmark("Game of Life", "height*width*iterations*rules")
SURVIVE_LOW = 2
SURVIVE_HIGH = 3
SPAWN = 3
def world(height, width):
state = np.ones((height + 2, width + 2), dtype=bench.dtype)
state[2:-2, 2:-2] = bench.dtype(0)
return state
def world_zeros(height, width):
state = np.zeros((height + 2, width + 2), dtype=bench.dtype)
return state
def play(state, iterations, version=1, visualize=False):
cells = state[1:-1, 1:-1]
ul = state[0:-2, 0:-2]
um = state[0:-2, 1:-1]
ur = state[0:-2, 2:]
ml = state[1:-1, 0:-2]
mr = state[1:-1, 2:]
ll = state[2:, 0:-2]
lm = state[2:, 1:-1]
lr = state[2:, 2:]
def update():
"""
This is the first implementation of the game rules.
"""
neighbors = ul + um + ur + ml + mr + ll + lm + lr # count neighbors
live = neighbors * cells # extract live cells neighbors
stay = (live >= SURVIVE_LOW) & (live <= SURVIVE_HIGH) # find cells the stay alive
dead = neighbors * (cells == 0) # extract dead cell neighbors
spawn = dead == SPAWN # find cells that spaw new life
cells[:] = stay | spawn # save result for next iteration
def update_optimized():
"""
This is an optimized implementation of the game rules.
"""
neighbors = ul + um + ur + ml + mr + ll + lm + lr # Count neighbors
c1 = (neighbors == SURVIVE_LOW) # Life conditions
c2 = (neighbors == SPAWN)
cells[:] = cells * c1 + c2 # Update
if version == 1: # Select the update function
update_func = update
elif version == 2:
update_func = update_optimized
for i in range(iterations): # Run the game
if visualize:
bench.plot_surface(state, "3d", 16, 1, 0)
update_func()
bench.flush()
return state
def main():
(H, W, I, V) = bench.args.size
if V not in [1, 2]:
raise Exception("Unsupported rule-implementation.")
S = world(H, W)
bench.start()
R = play(S, I, V, bench.args.visualize)
bench.stop()
bench.save_data({'res': R})
bench.pprint()
if __name__ == "__main__":
main()
C99 Seq¶
Error
There are issues with the implementation.
In progress…
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <bp_util.h>
void world(double* state, int height, int width)
{
for (int h=0; h<height; ++h) {
for (int w=0; w<width; ++w) {
state[h*width + w] = (((h < 2) && (h > (height-3))) ||
((w < 2) && (w > (width-3))));
}
}
}
void play(double* state, int height, int width, int iterations, int version)
{
printf("%p %d %d %d %d\n", state, height, width, iterations, version);
}
int main (int argc, char **argv)
{
bp_util_type bp = bp_util_create(argc, argv, 4); // Grab arguments
if (bp.args.has_error) {
return 1;
}
const int height = bp.args.sizes[0];
const int width = bp.args.sizes[1];
const int iter = bp.args.sizes[2];
const int version = bp.args.sizes[3];
size_t grid_size = height*width*sizeof(double);
double *state = (double*)malloc(grid_size);
world(state, height, width);
bp.timer_start();
play(state, height, width, iter, version);
bp.timer_stop();
bp.print("gameoflife(c99_seq)");
free(state);
return 0;
}
Cpp11 Omp¶
Error
There are issues with the implementation.
In progress…
#include <iostream>
#include <iomanip>
#include <bp_util.h>
#define HEIGHT 1000
#define WIDTH 1000
static double SURVIVE_LOW = 2.0;
static double SURVIVE_HIGH = 3.0;
static double SPAWN = 3.0;
using namespace std;
template <typename T>
void world(T state)
{
#pragma omp parallel for collapse(2)
for(int h=0; h<HEIGHT+2; ++h) {
for(int w=0; w<WIDTH+2; ++w) {
state[h][w] = (((h<2) and (h>WIDTH-3)) &&
((w<2) and (w>HEIGHT-3)));
}
}
}
template <typename T>
void play(T state, int iterations, int version, int visualize)
{
cout << state << SURVIVE_LOW << SURVIVE_HIGH << SPAWN << endl;
cout << state << iterations << version << visualize << endl;
T* cells, ul, um, ur, ml, mr, ll, lm, lr;
}
template <typename T>
void bench(bp_util_type& bp, const int I, const int V)
{
auto state = new T[HEIGHT][WIDTH]; // Construct matrices
world(state);
bp.timer_start(); // Start timer
play(state, I, V, bp.args.visualize);
bp.timer_stop(); // Stop timer
bp.print("gameoflife(cpp11_omp)"); // Print results..
if (bp.args.verbose) { // ..and value.
cout << fixed << setprecision(10)
<< "Result = " << endl;
}
}
int main(int argc, char* argv[])
{
bp_util_type bp = bp_util_create(argc, argv, 4);// Grab arguments
if (bp.args.has_error) {
return 1;
}
const int W = bp.args.sizes[0];
const int H = bp.args.sizes[1];
const int I = bp.args.sizes[2];
const int V = bp.args.sizes[3];
if (HEIGHT != H) {
cout << "Multidimensional arrays in C11 does not support dynamic size, so it has to be: " << H << "." << endl;
return 0;
}
if (WIDTH != W) {
cout << "Multidimensional arrays in C11 does not support dynamic size, so it has to be: " << W << "." << endl;
return 0;
}
bench<double>(bp, I, V);
return 0;
}