aboutsummaryrefslogtreecommitdiff
path: root/etc
diff options
context:
space:
mode:
authorGravatar Jason Gross <jgross@mit.edu>2017-08-09 11:07:01 -0400
committerGravatar Jason Gross <jgross@mit.edu>2017-08-09 11:07:01 -0400
commit210e483657de23132c322874efc608bc6a2c0625 (patch)
tree760abaf9dc7759147cc0f7cfa3d153c54d75e62c /etc
parent895faf22393ba7d14a54d99adc80d4b16c9b7dac (diff)
Larger instruction window for zinc
Diffstat (limited to 'etc')
-rwxr-xr-xetc/compile-by-zinc/compile-to-zinc.py561
1 files changed, 351 insertions, 210 deletions
diff --git a/etc/compile-by-zinc/compile-to-zinc.py b/etc/compile-by-zinc/compile-to-zinc.py
index 632035009..0b91ae073 100755
--- a/etc/compile-by-zinc/compile-to-zinc.py
+++ b/etc/compile-by-zinc/compile-to-zinc.py
@@ -8,7 +8,7 @@ CORES = ('ADD_MUL0', 'ADD_MUL1', 'MUL0', 'LEA_BW0', 'LEA_BW1', 'NOOP_CORE')
OP_NAMES = {'*':'MUL', '+':'ADD', '>>':'SHL', '<<':'SHR', '|':'OR', '&':'AND'}
-MAX_INSTRUCTION_WINDOW = 40
+MAX_INSTRUCTION_WINDOW = 53
INSTRUCTIONS_PER_CYCLE = 4
@@ -54,9 +54,14 @@ def parse_lines(lines):
for line in lines[1:-1]:
datatype, varname, arg1, op, arg2 = re.findall('^(u?int[0-9]*_t) ([^ ]*) = ([^ ]*) ([^ ]*) ([^ ]*);$', line)[0]
ret['lines'].append({'type':datatype, 'out':varname, 'op':op, 'args':(arg1, arg2), 'source':line})
- print('Compiling %d of %d lines...' % (min(MAX_INSTRUCTION_WINDOW, len(ret['lines'])), len(ret['lines'])))
- ret['lines'] = ret['lines'][:MAX_INSTRUCTION_WINDOW]
- return ret
+ print('Compiling %d lines in groups of %d...' % (len(ret['lines']), min(MAX_INSTRUCTION_WINDOW, len(ret['lines']))))
+ ret['lines'] = tuple(ret['lines'])
+ split_ret = []
+ for start in range(0, len(ret['lines']), MAX_INSTRUCTION_WINDOW):
+ cur_ret = dict(ret)
+ cur_ret['lines'] = ret['lines'][start:][:MAX_INSTRUCTION_WINDOW]
+ split_ret.append(cur_ret)
+ return tuple(split_ret)
def get_var_names(input_data):
return tuple(line['out'] for line in input_data['lines'])
@@ -75,189 +80,189 @@ def create_set(name, items):
ret += '\n'
return ret
-######################################################################
-######################################################################
-## Assign locations to instructions ##
-######################################################################
-######################################################################
-def make_assign_locations_to_instructions(data):
- def make_decls(input_data):
- var_names = get_var_names(input_data)
- ret = ''
- ret += create_set('CORE', CORES)
- for var in var_names:
- ret += 'var int: %s_loc;\n' % var
- ret += 'var int: %s_latency;\n' % var
- ret += 'var CORE: %s_core;\n' % var
- ret += 'var int: RET_loc;\n'
- return ret
-
- def make_disjoint(input_data):
- var_names = get_var_names(input_data)
- ret = ''
- for var in var_names:
- ret += 'constraint %s_loc >= 0;\n' % var
- ret += 'constraint %s_latency >= 0;\n' % var
- ret += 'constraint %s_loc + %s_latency <= RET_loc;\n' % (var, var)
- # TODO: Figure out if this next constraint actually helps things....
- MAX_NUMBER_OF_NOPS_PER_INSTRUCTION = 3
- APPROXIMATE_MAX_LATENCY = 6 * INSTRUCTIONS_PER_CYCLE
- max_ret_loc = ('constraint RET_loc <= %d;\n'
- % (len(var_names)
- * MAX_NUMBER_OF_NOPS_PER_INSTRUCTION
- + APPROXIMATE_MAX_LATENCY))
- #ret += max_ret_loc
- ret += '\n'
- for var_i in range(len(var_names)):
- for var_j in range(var_i+1, len(var_names)):
- ret += 'constraint %s_loc != %s_loc;\n' % (var_names[var_i], var_names[var_j])
- ret += '\n'
- return ret
-
- def make_dependencies(input_data):
- var_names = get_var_names(input_data)
- ret = ''
- for line in input_data['lines']:
- for arg in line['args']:
- if arg in var_names and arg[0] not in '0123456789':
- ret += ('constraint %s_loc + %s_latency <= %s_loc;\n'
- % (arg, arg, line['out']))
- ret += '\n'
- return ret
-
- def make_cores(input_data):
- ret = ''
- for line in input_data['lines']:
- ret += 'constraint '
- possible_cores = []
- cores = MODEL[line['op']]
- for core in cores:
- possible_cores.append('(%s_latency == %d /\ %s_core == %s)'
- % (line['out'], core['latency'] * INSTRUCTIONS_PER_CYCLE,
- line['out'], core['core']['name']))
- ret += ' \/ '.join(possible_cores)
- ret += ';\n'
- return ret
-
- def make_cores_disjoint(input_data):
- var_names = get_var_names(input_data)
- ret = ''
- for core in CORES:
- for var_i in range(len(var_names)):
- for var_j in range(var_i+1, len(var_names)):
- op_i = input_data['lines'][var_i]['op']
- op_j = input_data['lines'][var_j]['op']
- latencies_i = [val['core']['latency'] for val in MODEL[op_i] if val['core']['name'] == core]
- latencies_j = [val['core']['latency'] for val in MODEL[op_j] if val['core']['name'] == core]
- if len(latencies_i) == 0 or len(latencies_j) == 0: continue
- assert len(latencies_i) == 1
- assert len(latencies_j) == 1
- ret += ('constraint (%(vari)s_core != %(core)s \\/ %(varj)s_core != %(core)s) \\/ (%(vari)s_loc + %(latencyi)d <= %(varj)s_loc \\/ %(varj)s_loc + %(latencyj)d <= %(vari)s_loc);\n'
- % { 'vari':var_names[var_i] , 'varj':var_names[var_j] , 'core':core ,
- 'latencyi':latencies_i[0] * INSTRUCTIONS_PER_CYCLE,
- 'latencyj':latencies_j[0] * INSTRUCTIONS_PER_CYCLE})
- ret += '\n'
- return ret
-
- def make_output(input_data):
- ret = 'solve minimize RET_loc;\n\n'
- ret += 'output [ "{\\n" ++\n'
- for line in input_data['lines']:
- ret += (' " \'%(var)s_loc\': " ++ show(%(var)s_loc) ++ ", \'%(var)s_latency\': " ++ show(%(var)s_latency) ++ ", \'%(var)s_core\': " ++ show(%(var)s_core) ++ ",\\n" ++\n %% %(source)s\n'
- % { 'var':line['out'] , 'source':line['source'] })
- ret += ' " \'RET_loc\': " ++ show(RET_loc) ++ "\\n" ++\n'
- ret += ' "}" ]\n'
- return ret
-
- return '\n'.join([
- make_decls(data),
- make_disjoint(data),
- make_dependencies(data),
- make_cores(data),
- make_cores_disjoint(data),
- make_output(data)
- ])
-
-
-######################################################################
-######################################################################
-## Assign instructions to locations ##
-######################################################################
-######################################################################
-
-def make_assign_instructions_to_locations(data):
- def make_decls(input_data):
- var_names = get_var_names(input_data)
- ret = ''
- ret += 'include "alldifferent.mzn";\n'
- ret += create_set('CORE', CORES)
- ret += create_set('INSTRUCTION', ['NOOP'] + list(var_names))
- MAX_NUMBER_OF_NOOPS_PER_INSTRUCTION = 3
- APPROXIMATE_MAX_LATENCY = 6 * INSTRUCTIONS_PER_CYCLE
- max_loc = len(var_names) * MAX_NUMBER_OF_NOOPS_PER_INSTRUCTION # + APPROXIMATE_MAX_LATENCY
- ret += 'int: MAX_LOC = %d;\n\n' % max_loc
- ret += 'array[1..MAX_LOC] of var INSTRUCTION: output_instructions;\n'
- ret += 'array[1..MAX_LOC] of var CORE: output_cores;\n'
- ret += 'array[1..MAX_LOC] of var int: output_core_latency;\n'
- ret += 'array[1..MAX_LOC] of var int: output_data_latency;\n'
- ret += 'var int: RET_loc;\n'
- ret += '\n'
- ret += 'constraint 1 <= RET_loc /\\ RET_loc <= MAX_LOC;\n'
- ret += '\n'
- return ret
-
- def make_disjoint(input_data):
- var_names = get_var_names(input_data)
- ret = ''
- #ret += 'constraint alldifferent( [ output_instructions[i] | i in 1..MAX_LOC where output_instructions[i] != NOOP ] );\n'
- ret += 'constraint forall (i,j in 1..MAX_LOC where i < j) (output_instructions[i] == NOOP \\/ output_instructions[i] != output_instructions[j]);\n'
- ret += 'constraint sum( [ 1 | i in 1..MAX_LOC where output_instructions[i] != NOOP ] ) == length(INSTRUCTION) - 1;\n'
- ret += 'constraint forall (i in 1..MAX_LOC where RET_loc <= i) (output_instructions[i] == NOOP);\n'
- ret += 'constraint forall (i,j in 1..MAX_LOC where i < j) ((output_instructions[i] != NOOP /\\ output_instructions[j] != NOOP /\\ output_cores[i] == output_cores[j]) -> i + output_core_latency[i] <= j);\n'
- ret += 'constraint forall (i in 1..MAX_LOC) (output_instructions[i] == NOOP \\/ i + output_data_latency[i] <= RET_loc);\n'
- ret += 'constraint forall (i in 1..MAX_LOC) (output_instructions[i] == NOOP -> (output_core_latency[i] == 0 /\\ output_data_latency[i] == 0 /\\ output_cores[i] == NOOP_CORE));\n'
- return ret
-
- def make_dependencies(input_data):
- var_names = get_var_names(input_data)
- ret = ''
- for line in input_data['lines']:
- for arg in line['args']:
- if arg in var_names and arg[0] not in '0123456789':
- ret += ('constraint forall (i,j in 1..MAX_LOC) ((output_instructions[i] == %s /\\ output_instructions[j] == %s) -> i + output_data_latency[i] <= j);\n'
- % (arg, line['out']))
- ret += '\n'
- return ret
-
- def make_cores(input_data):
- ret = ''
- for line in input_data['lines']:
- ret += 'constraint forall (i in 1..MAX_LOC) (output_instructions[i] == %s -> (' % line['out']
- possible_cores = []
- cores = MODEL[line['op']]
- for core in cores:
- possible_cores.append(r'(output_core_latency[i] == %d /\ output_data_latency[i] == %d /\ output_cores[i] == %s)'
- % (core['core']['latency'] * INSTRUCTIONS_PER_CYCLE,
- core['latency'] * INSTRUCTIONS_PER_CYCLE,
- core['core']['name']))
- ret += ' \/ '.join(possible_cores)
- ret += '));\n'
- ret += '\n'
- return ret
-
- def make_output(input_data):
- ret = 'solve minimize RET_loc;\n\n'
- ret += 'output [ "(" ++ show(INSTRUCTION_NAMES[fix(output_instructions[i])]) ++ ", " ++ show(CORE_NAMES[fix(output_cores[i])]) ++ ", " ++ show(output_core_latency[i]) ++ ", " ++ show(output_data_latency[i]) ++ ") ,\\n"\n'
- ret += ' | i in 1..MAX_LOC ];\n'
- return ret
-
- return '\n'.join([
- make_decls(data),
- make_disjoint(data),
- make_dependencies(data),
- make_cores(data),
- make_output(data)
- ])
+########################################################################
+########################################################################
+#### Assign locations to instructions ##
+########################################################################
+########################################################################
+##def make_assign_locations_to_instructions(data):
+## def make_decls(input_data):
+## var_names = get_var_names(input_data)
+## ret = ''
+## ret += create_set('CORE', CORES)
+## for var in var_names:
+## ret += 'var int: %s_loc;\n' % var
+## ret += 'var int: %s_latency;\n' % var
+## ret += 'var CORE: %s_core;\n' % var
+## ret += 'var int: RET_loc;\n'
+## return ret
+##
+## def make_disjoint(input_data):
+## var_names = get_var_names(input_data)
+## ret = ''
+## for var in var_names:
+## ret += 'constraint %s_loc >= 0;\n' % var
+## ret += 'constraint %s_latency >= 0;\n' % var
+## ret += 'constraint %s_loc + %s_latency <= RET_loc;\n' % (var, var)
+## # TODO: Figure out if this next constraint actually helps things....
+## MAX_NUMBER_OF_NOPS_PER_INSTRUCTION = 3
+## APPROXIMATE_MAX_LATENCY = 6 * INSTRUCTIONS_PER_CYCLE
+## max_ret_loc = ('constraint RET_loc <= %d;\n'
+## % (len(var_names)
+## * MAX_NUMBER_OF_NOPS_PER_INSTRUCTION
+## + APPROXIMATE_MAX_LATENCY))
+## #ret += max_ret_loc
+## ret += '\n'
+## for var_i in range(len(var_names)):
+## for var_j in range(var_i+1, len(var_names)):
+## ret += 'constraint %s_loc != %s_loc;\n' % (var_names[var_i], var_names[var_j])
+## ret += '\n'
+## return ret
+##
+## def make_dependencies(input_data):
+## var_names = get_var_names(input_data)
+## ret = ''
+## for line in input_data['lines']:
+## for arg in line['args']:
+## if arg in var_names and arg[0] not in '0123456789':
+## ret += ('constraint %s_loc + %s_latency <= %s_loc;\n'
+## % (arg, arg, line['out']))
+## ret += '\n'
+## return ret
+##
+## def make_cores(input_data):
+## ret = ''
+## for line in input_data['lines']:
+## ret += 'constraint '
+## possible_cores = []
+## cores = MODEL[line['op']]
+## for core in cores:
+## possible_cores.append('(%s_latency == %d /\ %s_core == %s)'
+## % (line['out'], core['latency'] * INSTRUCTIONS_PER_CYCLE,
+## line['out'], core['core']['name']))
+## ret += ' \/ '.join(possible_cores)
+## ret += ';\n'
+## return ret
+##
+## def make_cores_disjoint(input_data):
+## var_names = get_var_names(input_data)
+## ret = ''
+## for core in CORES:
+## for var_i in range(len(var_names)):
+## for var_j in range(var_i+1, len(var_names)):
+## op_i = input_data['lines'][var_i]['op']
+## op_j = input_data['lines'][var_j]['op']
+## latencies_i = [val['core']['latency'] for val in MODEL[op_i] if val['core']['name'] == core]
+## latencies_j = [val['core']['latency'] for val in MODEL[op_j] if val['core']['name'] == core]
+## if len(latencies_i) == 0 or len(latencies_j) == 0: continue
+## assert len(latencies_i) == 1
+## assert len(latencies_j) == 1
+## ret += ('constraint (%(vari)s_core != %(core)s \\/ %(varj)s_core != %(core)s) \\/ (%(vari)s_loc + %(latencyi)d <= %(varj)s_loc \\/ %(varj)s_loc + %(latencyj)d <= %(vari)s_loc);\n'
+## % { 'vari':var_names[var_i] , 'varj':var_names[var_j] , 'core':core ,
+## 'latencyi':latencies_i[0] * INSTRUCTIONS_PER_CYCLE,
+## 'latencyj':latencies_j[0] * INSTRUCTIONS_PER_CYCLE})
+## ret += '\n'
+## return ret
+##
+## def make_output(input_data):
+## ret = 'solve minimize RET_loc;\n\n'
+## ret += 'output [ "{\\n" ++\n'
+## for line in input_data['lines']:
+## ret += (' " \'%(var)s_loc\': " ++ show(%(var)s_loc) ++ ", \'%(var)s_latency\': " ++ show(%(var)s_latency) ++ ", \'%(var)s_core\': " ++ show(%(var)s_core) ++ ",\\n" ++\n %% %(source)s\n'
+## % { 'var':line['out'] , 'source':line['source'] })
+## ret += ' " \'RET_loc\': " ++ show(RET_loc) ++ "\\n" ++\n'
+## ret += ' "}" ]\n'
+## return ret
+##
+## return '\n'.join([
+## make_decls(data),
+## make_disjoint(data),
+## make_dependencies(data),
+## make_cores(data),
+## make_cores_disjoint(data),
+## make_output(data)
+## ])
+##
+##
+########################################################################
+########################################################################
+#### Assign instructions to locations ##
+########################################################################
+########################################################################
+##
+##def make_assign_instructions_to_locations(data):
+## def make_decls(input_data):
+## var_names = get_var_names(input_data)
+## ret = ''
+## ret += 'include "alldifferent.mzn";\n'
+## ret += create_set('CORE', CORES)
+## ret += create_set('INSTRUCTION', ['NOOP'] + list(var_names))
+## MAX_NUMBER_OF_NOOPS_PER_INSTRUCTION = 3
+## APPROXIMATE_MAX_LATENCY = 6 * INSTRUCTIONS_PER_CYCLE
+## max_loc = len(var_names) * MAX_NUMBER_OF_NOOPS_PER_INSTRUCTION # + APPROXIMATE_MAX_LATENCY
+## ret += 'int: MAX_LOC = %d;\n\n' % max_loc
+## ret += 'array[1..MAX_LOC] of var INSTRUCTION: output_instructions;\n'
+## ret += 'array[1..MAX_LOC] of var CORE: output_cores;\n'
+## ret += 'array[1..MAX_LOC] of var int: output_core_latency;\n'
+## ret += 'array[1..MAX_LOC] of var int: output_data_latency;\n'
+## ret += 'var int: RET_loc;\n'
+## ret += '\n'
+## ret += 'constraint 1 <= RET_loc /\\ RET_loc <= MAX_LOC;\n'
+## ret += '\n'
+## return ret
+##
+## def make_disjoint(input_data):
+## var_names = get_var_names(input_data)
+## ret = ''
+## #ret += 'constraint alldifferent( [ output_instructions[i] | i in 1..MAX_LOC where output_instructions[i] != NOOP ] );\n'
+## ret += 'constraint forall (i,j in 1..MAX_LOC where i < j) (output_instructions[i] == NOOP \\/ output_instructions[i] != output_instructions[j]);\n'
+## ret += 'constraint sum( [ 1 | i in 1..MAX_LOC where output_instructions[i] != NOOP ] ) == length(INSTRUCTION) - 1;\n'
+## ret += 'constraint forall (i in 1..MAX_LOC where RET_loc <= i) (output_instructions[i] == NOOP);\n'
+## ret += 'constraint forall (i,j in 1..MAX_LOC where i < j) ((output_instructions[i] != NOOP /\\ output_instructions[j] != NOOP /\\ output_cores[i] == output_cores[j]) -> i + output_core_latency[i] <= j);\n'
+## ret += 'constraint forall (i in 1..MAX_LOC) (output_instructions[i] == NOOP \\/ i + output_data_latency[i] <= RET_loc);\n'
+## ret += 'constraint forall (i in 1..MAX_LOC) (output_instructions[i] == NOOP -> (output_core_latency[i] == 0 /\\ output_data_latency[i] == 0 /\\ output_cores[i] == NOOP_CORE));\n'
+## return ret
+##
+## def make_dependencies(input_data):
+## var_names = get_var_names(input_data)
+## ret = ''
+## for line in input_data['lines']:
+## for arg in line['args']:
+## if arg in var_names and arg[0] not in '0123456789':
+## ret += ('constraint forall (i,j in 1..MAX_LOC) ((output_instructions[i] == %s /\\ output_instructions[j] == %s) -> i + output_data_latency[i] <= j);\n'
+## % (arg, line['out']))
+## ret += '\n'
+## return ret
+##
+## def make_cores(input_data):
+## ret = ''
+## for line in input_data['lines']:
+## ret += 'constraint forall (i in 1..MAX_LOC) (output_instructions[i] == %s -> (' % line['out']
+## possible_cores = []
+## cores = MODEL[line['op']]
+## for core in cores:
+## possible_cores.append(r'(output_core_latency[i] == %d /\ output_data_latency[i] == %d /\ output_cores[i] == %s)'
+## % (core['core']['latency'] * INSTRUCTIONS_PER_CYCLE,
+## core['latency'] * INSTRUCTIONS_PER_CYCLE,
+## core['core']['name']))
+## ret += ' \/ '.join(possible_cores)
+## ret += '));\n'
+## ret += '\n'
+## return ret
+##
+## def make_output(input_data):
+## ret = 'solve minimize RET_loc;\n\n'
+## ret += 'output [ "(" ++ show(INSTRUCTION_NAMES[fix(output_instructions[i])]) ++ ", " ++ show(CORE_NAMES[fix(output_cores[i])]) ++ ", " ++ show(output_core_latency[i]) ++ ", " ++ show(output_data_latency[i]) ++ ") ,\\n"\n'
+## ret += ' | i in 1..MAX_LOC ];\n'
+## return ret
+##
+## return '\n'.join([
+## make_decls(data),
+## make_disjoint(data),
+## make_dependencies(data),
+## make_cores(data),
+## make_output(data)
+## ])
######################################################################
######################################################################
@@ -310,12 +315,14 @@ def make_assign_locations_to_instructions_cumulatively(data):
ret += 'set of int: LOCATIONS = 1..MAX_LOC;\n'
ret += 'array[INSTRUCTIONS] of var LOCATIONS: output_locations;\n'
ret += 'array[INSTRUCTIONS] of var int: output_data_latency;\n'
+ ret += 'array[INSTRUCTIONS] of var int: output_core_latency;\n'
ret += 'array[INSTRUCTIONS] of var CORE: output_cores;\n'
ret += 'array[INSTRUCTIONS] of OPS: input_ops = [%s];\n' % ', '.join(OP_NAMES[line['op']] for line in input_data['lines'])
for core in CORES:
ret += 'array[INSTRUCTIONS] of var int: output_%s_core_latency;\n' % core
ret += 'array[INSTRUCTIONS] of var 0..1: output_%s_core_use;\n' % core
ret += 'constraint forall (i in INSTRUCTIONS) (0 <= output_%s_core_latency[i]);\n' % core
+ ret += 'constraint forall (i in INSTRUCTIONS) (output_%s_core_use[i] == 1 -> output_core_latency[i] == output_%s_core_latency[i]);\n' % (core, core)
ret += 'var LOCATIONS: RET_loc;\n'
ret += '\n'
return ret
@@ -323,23 +330,17 @@ def make_assign_locations_to_instructions_cumulatively(data):
def make_cores(input_data):
ret = ''
for opc, cores in MODEL.items():
- possible_cores_and = []
- possible_cores_or = []
- for core in cores:
- possible_cores_and.append((r'((output_cores[i] == %s /\ output_%s_core_use[i] == 1 /\ output_%s_core_latency[i] == %d /\ output_data_latency[i] == %d)' +
- r' \/ (output_cores[i] != %s /\ output_%s_core_use[i] == 0 /\ output_%s_core_latency[i] == 0))')
- % (core['core']['name'],
- core['core']['name'],
- core['core']['name'],
- core['core']['latency'] * INSTRUCTIONS_PER_CYCLE,
- core['latency'] * INSTRUCTIONS_PER_CYCLE,
- core['core']['name'],
- core['core']['name'],
- core['core']['name']))
+ possible_cores = []
for core in cores:
- possible_cores_or.append('output_cores[i] == %s' % core['core']['name'])
- ret += ('constraint forall (i in INSTRUCTIONS) (input_ops[i] == %s -> ((%s) /\\ (%s)));\n'
- % (OP_NAMES[opc], r' /\ '.join(possible_cores_and), r' \/ '.join(possible_cores_or)))
+ conjuncts = (['output_cores[i] == %s' % core['core']['name'],
+ 'output_%s_core_use[i] == 1' % core['core']['name'],
+ 'output_%s_core_latency[i] == %d' % (core['core']['name'], core['core']['latency'] * INSTRUCTIONS_PER_CYCLE),
+ 'output_data_latency[i] == %d' % (core['latency'] * INSTRUCTIONS_PER_CYCLE)] +
+ ['output_%s_core_use[i] == 0 /\ output_%s_core_latency[i] == 0' % (other_core, other_core)
+ for other_core in CORES if other_core != core['core']['name']])
+ possible_cores.append('(%s)' % (r' /\ '.join(conjuncts)))
+ ret += ('constraint forall (i in INSTRUCTIONS) (input_ops[i] == %s -> (%s));\n'
+ % (OP_NAMES[opc], r' \/ '.join(possible_cores)))
ret += '\n'
for core in CORES:
ret += ('constraint cumulative(output_locations, output_%s_core_latency, output_%s_core_use, %d);\n'
@@ -352,7 +353,7 @@ def make_assign_locations_to_instructions_cumulatively(data):
ret += 'constraint alldifferent(output_locations);\n'
return ret
- def make_dependencies(input_data):
+ def make_dependencies_old(input_data):
var_names = get_var_names(input_data)
ret = ''
for line in input_data['lines']:
@@ -365,9 +366,22 @@ def make_assign_locations_to_instructions_cumulatively(data):
ret += '\n'
return ret
+ def make_dependencies(input_data):
+ var_names = get_var_names(input_data)
+ ret = ''
+ ret += 'array[INSTRUCTIONS,INSTRUCTIONS] of var 0..1: depends_on;\n'
+ dependencies = {}
+ for line in input_data['lines']:
+ dependencies[line['out']] = tuple(arg for arg in line['args']
+ if arg in var_names and arg[0] not in '0123456789')
+ # HERE
+
+
+
+
def make_output(input_data):
ret = 'solve minimize RET_loc;\n\n'
- ret += 'output [ "(" ++ show(INSTRUCTIONS_NAMES[i]) ++ ", " ++ show(CORE_NAMES[fix(output_cores[i])]) ++ ", " ++ show(output_locations[i]) ++ ", " ++ show(output_data_latency[i]) ++ ") ,\\n"\n'
+ ret += 'output [ "(" ++ show(INSTRUCTIONS_NAMES[i]) ++ ", " ++ show(CORE_NAMES[fix(output_cores[i])]) ++ ", " ++ show(output_locations[i]) ++ ", " ++ show(output_data_latency[i]) ++ ", " ++ show(output_core_latency[i]) ++ ") ,\\n"\n'
ret += ' | i in INSTRUCTIONS ];\n'
ret += 'output [ "RET_loc: " ++ show(RET_loc) ];\n'
return ret
@@ -381,9 +395,136 @@ def make_assign_locations_to_instructions_cumulatively(data):
])
+RESULTS = [
+"""("x20", "ADD_MUL", 9, 12, 4) ,
+("x21", "ADD_MUL", 21, 12, 4) ,
+("x22", "ADD_MUL", 10, 12, 4) ,
+("x23", "ADD_MUL", 34, 4, 4) ,
+("x24", "ADD_MUL", 47, 12, 4) ,
+("x25", "ADD_MUL", 43, 12, 4) ,
+("x26", "ADD_MUL", 59, 4, 4) ,
+("x27", "ADD_MUL", 51, 12, 4) ,
+("x28", "ADD_MUL", 63, 4, 4) ,
+("x29", "ADD_MUL", 75, 12, 4) ,
+("x30", "ADD_MUL", 71, 12, 4) ,
+("x31", "ADD_MUL", 87, 4, 4) ,
+("x32", "ADD_MUL", 79, 12, 4) ,
+("x33", "ADD_MUL", 91, 4, 4) ,
+("x34", "ADD_MUL", 82, 12, 4) ,
+("x35", "ADD_MUL", 95, 4, 4) ,
+("x36", "ADD_MUL", 58, 12, 4) ,
+("x37", "ADD_MUL", 55, 12, 4) ,
+("x38", "ADD_MUL", 70, 4, 4) ,
+("x39", "ADD_MUL", 62, 12, 4) ,
+("x40", "ADD_MUL", 74, 4, 4) ,
+("x41", "ADD_MUL", 66, 12, 4) ,
+("x42", "ADD_MUL", 78, 4, 4) ,
+("x43", "ADD_MUL", 90, 12, 4) ,
+("x44", "ADD_MUL", 102, 4, 4) ,
+("x45", "ADD_MUL", 1, 12, 4) ,
+("x46", "ADD_MUL", 2, 12, 4) ,
+("x47", "ADD_MUL", 5, 12, 4) ,
+("x48", "ADD_MUL", 6, 12, 4) ,
+("x49", "ADD_MUL", 13, 12, 4) ,
+("x50", "ADD_MUL", 25, 4, 4) ,
+("x51", "ADD_MUL", 14, 12, 4) ,
+("x52", "ADD_MUL", 29, 4, 4) ,
+("x53", "ADD_MUL", 17, 12, 4) ,
+("x54", "ADD_MUL", 33, 4, 4) ,
+("x55", "ADD_MUL", 18, 12, 4) ,
+("x56", "ADD_MUL", 37, 4, 4) ,
+("x57", "ADD_MUL", 22, 12, 4) ,
+("x58", "ADD_MUL", 38, 4, 4) ,
+("x59", "ADD_MUL", 30, 12, 4) ,
+("x60", "ADD_MUL", 42, 4, 4) ,
+("x61", "ADD_MUL", 26, 12, 4) ,
+("x62", "ADD_MUL", 46, 4, 4) ,
+("x63", "ADD_MUL", 54, 12, 4) ,
+("x64", "ADD_MUL", 67, 4, 4) ,
+("x65", "ADD_MUL", 86, 12, 4) ,
+("x66", "ADD_MUL", 98, 4, 4) ,
+("x67", "ADD_MUL", 83, 12, 4) ,
+("x68", "ADD_MUL", 99, 4, 4) ,
+("x69", "LEA_BW", 41, 4, 4) ,
+("x70", "LEA_BW", 44, 4, 4) ,
+("x71", "ADD_MUL", 50, 4, 4) ,
+("x72", "LEA_BW", 56, 4, 4) ,
+RET_loc: 106"""
+,
+"""("x73", "LEA_BW", 2, 4, 4) ,
+("x74", "ADD_MUL", 1, 4, 4) ,
+("x75", "LEA_BW", 5, 4, 4) ,
+("x76", "LEA_BW", 6, 4, 4) ,
+("x77", "ADD_MUL", 9, 4, 4) ,
+("x78", "LEA_BW", 13, 4, 4) ,
+("x79", "LEA_BW", 14, 4, 4) ,
+("x80", "ADD_MUL", 17, 4, 4) ,
+("x81", "LEA_BW", 21, 4, 4) ,
+("x82", "LEA_BW", 22, 4, 4) ,
+("x83", "ADD_MUL", 25, 12, 4) ,
+("x84", "ADD_MUL", 37, 4, 4) ,
+("x85", "LEA_BW", 41, 4, 4) ,
+("x86", "LEA_BW", 42, 4, 4) ,
+("x87", "ADD_MUL", 45, 4, 4) ,
+("x88", "LEA_BW", 49, 4, 4) ,
+("x89", "LEA_BW", 50, 4, 4) ,
+("x90", "ADD_MUL", 53, 4, 4) ,
+RET_loc: 57"""
+]
-data = parse_lines(get_lines('femulDisplay.txt'))
-with open('femulDisplay.mzn', 'w') as f:
- #f.write(make_assign_locations_to_instructions(data))
- #f.write(make_assign_instructions_to_locations(data))
- f.write(make_assign_locations_to_instructions_cumulatively(data))
+######################################################################
+######################################################################
+## Parsing minizinc output ##
+######################################################################
+######################################################################
+
+def assemble_output_and_register_allocate(data_list, result_list):
+ def parse_result(result):
+ def parse_val(val):
+ val = val.strip()
+ if val[0] == '(' and val[-1] == ')':
+ return tuple(map(parse_val, val[1:-1].split(',')))
+ if val[0] in '"\'' and val[-1] in '"\'':
+ return val[1:-1]
+ if val.isdigit():
+ return int(val)
+ print('Unknown value: %s' % val)
+ return val
+ ret = {'schedule':list(map(str.strip, result.split(',\n')))}
+ ret['RET_loc'] = [i[len('RET_loc: '):] for i in ret['schedule'] if i[:len('RET_loc: ')] == 'RET_loc: ']
+ assert len(ret['RET_loc']) == 1
+ ret['RET_loc'] = int(ret['RET_loc'][0])
+ ret['schedule'] = tuple(parse_val(val) for val in ret['schedule'] if val[0] == '(' and val[-1] == ')')
+ return ret
+
+ def combine_lists(data_list, result_list):
+ data = data_list[0]
+ data['lines'] = list(data['lines'])
+ for cur_data in data_list:
+ data['lines'] += list(cur_data['lines'])
+ data['lines'] = tuple(data['lines'])
+
+ basepoint = 0
+ results = []
+ for result in map(parse_result, result_list):
+ results += [(var, core_type, basepoint+loc, data_latency, core_latency)
+ for var, core_type, loc, data_latency, core_latency in result['schedule']]
+ basepoint += result['RET_loc']
+ return (data, results)
+
+ def sort_results(data, results):
+ return sorted([(loc, '%s // %s, start: %.2f, end: %.2f' % (line['source'], core_type, loc / 4.0, (loc + data_latency) / 4.0))
+ for (line, (var, core_type, loc, data_latency, core_latency))
+ in zip(data['lines'], results)])
+
+ data, results = combine_lists(data_list, result_list)
+ return '\n'.join(code for i, code in sort_results(data, results))
+
+data_list = parse_lines(get_lines('femulDisplay.log'))
+for i, data in enumerate(data_list):
+ with open('femulDisplay_%d.mzn' % i, 'w') as f:
+ #f.write(make_assign_locations_to_instructions(data))
+ #f.write(make_assign_instructions_to_locations(data))
+ f.write(make_assign_locations_to_instructions_cumulatively(data))
+
+print(assemble_output_and_register_allocate(data_list[:1], RESULTS[:1]))