diff options
author | Jason Gross <jgross@mit.edu> | 2017-08-09 11:07:01 -0400 |
---|---|---|
committer | Jason Gross <jgross@mit.edu> | 2017-08-09 11:07:01 -0400 |
commit | 210e483657de23132c322874efc608bc6a2c0625 (patch) | |
tree | 760abaf9dc7759147cc0f7cfa3d153c54d75e62c /etc | |
parent | 895faf22393ba7d14a54d99adc80d4b16c9b7dac (diff) |
Larger instruction window for zinc
Diffstat (limited to 'etc')
-rwxr-xr-x | etc/compile-by-zinc/compile-to-zinc.py | 561 |
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])) |