apply_simplex.py (3839B)
1 #!/usr/bin/python 2 # Copyright (c) the JPEG XL Project Authors. All rights reserved. 3 # 4 # Use of this source code is governed by a BSD-style 5 # license that can be found in the LICENSE file. 6 7 """apply_simplex.py: Updates constants based on results of simplex search. 8 9 To use this tool, the simplex search parameters must we wrapped in a bias(n) 10 function call that returns the value of the VARn environment variable. The 11 tool reads a text file containing the simplex definition that simplex_fork.py 12 has written, and updates the target source files by substituting the bias(n) 13 function calls with the (n+1)th coordinate of the simplex vector, and also 14 simplifies these expressions by evaluating them to a sinlge floating point 15 literal. 16 17 The tool recognizes and evaluates the following expressions: 18 <constant> + bias(n), 19 <constant> * bias(n), 20 <constant> + <coeff> * bias(n). 21 22 The --keep_bias command-line flag can be used to continue an aborted simplex 23 search. This will keep the same bias(n) terms in the code, but would update the 24 surronding constants. 25 26 The --index_min and --index_max flags can be used to update only a subset of the 27 bias(n) parameters. 28 """ 29 30 import argparse 31 import re 32 import sys 33 34 def ParseSimplex(fn): 35 """Returns the simplex definition written by simplex_fork.py""" 36 37 with open(fn, "r") as f: 38 line = f.readline() 39 vec = eval(line) 40 return vec 41 42 43 def PythonExpr(c_expr): 44 """Removes the f at the end of float literals""" 45 46 def repl(m): 47 return m.group(1) 48 49 return re.sub("(\d+)f", repl, c_expr) 50 51 52 def UpdateSourceFile(fn, vec, keep_bias, id_min, id_max, minval): 53 """Updates expressions containing a bias(N) term.""" 54 55 with open(fn, "r") as f: 56 lines_in = f.readlines() 57 lines_out = [] 58 rbias = "(bias\((\d+)\))" 59 r = " -?\d+\.\d+f?( (\+|-|\*) (\d+\.\d+f? \* )?" + rbias + ")" 60 for line in lines_in: 61 line_out = line 62 x = re.search(r, line) 63 if x: 64 id = int(x.group(5)) 65 if id >= id_min and id <= id_max: 66 expr = re.sub(rbias, str(vec[id + 1]), x.group(0)) 67 val = eval(PythonExpr(expr)) 68 if minval and val < minval: 69 val = minval 70 expr_out = " " + str(val) + "f" 71 if keep_bias: 72 expr_out += x.group(1) 73 line_out = re.sub(r, expr_out, line) 74 lines_out.append(line_out) 75 76 with open(fn, "w") as f: 77 f.writelines(lines_out) 78 f.close() 79 80 81 def ApplySimplex(args): 82 """Main entry point of the program after parsing parameters.""" 83 84 vec = ParseSimplex(args.simplex) 85 for fn in args.target: 86 UpdateSourceFile(fn, vec, args.keep_bias, args.index_min, args.index_max, 87 args.minval) 88 return 0 89 90 91 def main(): 92 parser = argparse.ArgumentParser(description=__doc__) 93 parser.add_argument('target', type=str, nargs='+', 94 help='source file(s) to update') 95 parser.add_argument('--simplex', default='best_simplex.txt', 96 help='simplex to apply to the code') 97 parser.add_argument('--keep_bias', default=False, action='store_true', 98 help='keep the bias term in the code, can be used to ' + 99 'continue simplex search') 100 parser.add_argument('--index_min', type=int, default=0, 101 help='start index of the simplex to apply') 102 parser.add_argument('--index_max', type=int, default=9999, 103 help='last index of the simplex to apply') 104 parser.add_argument('--minval', type=float, default=None, 105 help='apply a minimum to expression results') 106 args = parser.parse_args() 107 sys.exit(ApplySimplex(args)) 108 109 110 if __name__ == '__main__': 111 main()