Commit ce2db752 authored by Adam P. Goucher's avatar Adam P. Goucher

Add further stage in pipeline to allow room for future AIGER support

parent f94dd54a
Pipeline #55099778 passed with stages
in 8 minutes and 20 seconds
from .parsetable import ReadRuleTable
from .parsetree import ReadRuleTree, SurplusTreeError
from .parsetree import ReadRuleTree, SurplusTreeError, FlattenRuleTree
from .writetree import TransitionsToTree
from .writecode import NodesToCode
from .writecode import NodesToCode, MakeStaticTable
import os
import sys
from collections import OrderedDict
from ast import literal_eval
lifelib_dir = os.path.dirname(os.path.abspath(__file__))
while (os.path.basename(lifelib_dir) != 'lifelib'):
......@@ -25,13 +26,18 @@ def minkowski_symmetrise(nhood):
return set([tuple(((x - y) for (x, y) in zip(t, s))) for t in nhood for s in nhood])
def tree_to_code(lines):
def analyse_tree(segments):
lines = segments['@TREE']
print('Reading rule tree...')
n_states, nhood, list_of_nodes = ReadRuleTree(lines)
is16bit = (n_states > 256)
print('Generating code...')
lines = NodesToCode(nhood, list_of_nodes, is16bit)
print('Flattening tree...')
flattened_tree = FlattenRuleTree(n_states, nhood, list_of_nodes)
segments['@FLATTREE'] = MakeStaticTable(flattened_tree)
print('...done!')
# Determine zone of influence for rule:
......@@ -42,8 +48,40 @@ def tree_to_code(lines):
preamble = ['/* %d-bit code generated from ruletree */\n' % (16 if is16bit else 8)]
preamble += ['/* ZOI="%s" */\n' % zoi]
preamble += ['/* BITS="%d" */\n' % (16 if is16bit else 8)]
preamble += ['/* NHOOD="%s" */\n' % nhood]
segments['@PREAMBLE'] = preamble
def create_code(segments):
lines = []
template = 0
nhood = None
bits = None
for l in segments['@PREAMBLE']:
if (nhood is None) and ('NHOOD=' in l):
nhood = literal_eval(l.split('"')[1])
if (bits is None) and ('BITS=' in l):
bits = literal_eval(l.split('"')[1])
if '@FLATTREE' in segments:
template += 1
lines += segments['@FLATTREE']
lines += NodesToCode(nhood, (bits > 8))
if '@AIGER' in segments:
template += 2
raise NotImplementedError("AIGER is currently unsupported")
template = ["row_based_approach.h", "aiger_approach.h", "row_and_aiger.h"][template - 1]
# We have implemented iterate_var_row instead of iterate_var_grid:
lines.append('#include "%s"\n' % template)
segments['@CODE'] = lines
return (lines, preamble)
def segmentate(rulefile):
'''
......@@ -134,8 +172,10 @@ def rule2segs(rulefile):
# Apply transformations
if '@TREE' in segments:
segments['@CODE'], segments['@PREAMBLE'] = tree_to_code(segments['@TREE'])
if ('@PREAMBLE' in segments) and (('@FLATTREE' in segments) or ('@AIGER' in segments)):
create_code(segments)
elif '@TREE' in segments:
analyse_tree(segments)
elif '@TABLE' in segments:
segments['@TREE'] = table_to_tree(segments['@TABLE'])
else:
......
......@@ -175,7 +175,10 @@ def ReadRuleTree(list_of_lines):
ruletree = ParseRuleTree(list_of_lines)
# Optimise the resulting rule tree:
n_states, nhood, list_of_nodes = optimise_tree(*ruletree)
return optimise_tree(*ruletree)
def FlattenRuleTree(n_states, nhood, list_of_nodes):
# Determine whether rule is 2-state isotropic:
if (n_states == 2) and (GetNumberOfInputs(nhood) + 1 == len(nhood)):
......@@ -202,6 +205,4 @@ def ReadRuleTree(list_of_lines):
return children
list_of_nodes = [serialise_node(data) for data in list_of_nodes[::-1]]
return n_states, nhood, list_of_nodes
return [serialise_node(data) for data in list_of_nodes[::-1]]
from .parsetable import GetNumberOfInputs
from .parsetree import normalise_neighbourhood
def NodesToCode(nhood, nodes, is16bit):
def MakeStaticTable(nodes):
# Write rule tree in .data segment of the program:
lines = ["const static uint32_t __ruletree[] __attribute__((aligned(64))) = {\n"]
for (i, l) in enumerate(nodes):
body = ' ' + (','.join([('%du' % x) for x in l]))
body += ('};\n\n' if (i == len(nodes) - 1) else ',\n')
lines.append(body)
lines.append('\n')
return lines
def NodesToCode(nhood, is16bit):
numInputs = GetNumberOfInputs(nhood)
numOutputs = len(nhood) - numInputs
......@@ -22,16 +36,8 @@ def NodesToCode(nhood, nodes, is16bit):
if is16bit:
out_offsets += [t + 256 for t in out_offsets]
# Write rule tree in .data segment of the program:
lines = ["const static uint32_t __ruletree[] __attribute__((aligned(64))) = {\n"]
for (i, l) in enumerate(nodes):
body = ' ' + (','.join([('%du' % x) for x in l]))
body += ('};\n\n' if (i == len(nodes) - 1) else ',\n')
lines.append(body)
lines.append('\n')
# Hopefully simple enough to vectorise:
lines.append('void iterate_var_row(uint8_t* __restrict__ inrow, uint8_t* __restrict__ outrow) {\n')
lines = ['void iterate_var_row(uint8_t* __restrict__ inrow, uint8_t* __restrict__ outrow) {\n']
lines.append(' uint32_t temprow[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};\n')
for offset in in_offsets:
if (is16bit):
......@@ -47,7 +53,4 @@ def NodesToCode(nhood, nodes, is16bit):
lines.append('}\n')
lines.append('\n')
# We have implemented iterate_var_row instead of iterate_var_grid:
lines.append('#include "row_based_approach.h"\n')
return lines
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment