def fromstring(root_func, s, genomelog='', generation=-1, index=-1): """ Constructor from a string s such as 'f.root().parallel(y)\ng.chunk(y)' (same format as returned by str() method). """ if '\\n' in s: raise ValueError('Bad newline character in %r'%s) #print 'Schedule.fromstring', root_func, s all_funcs = halide.all_funcs(root_func) root_func = root_func #print 'Schedule.fromstring', repr(s) #print s.strip().split('\n') #sys.exit(1) d = {} for line in s.strip().split('\n'): line = line.strip() if len(line) == 0: continue if not '.' in line: raise ValueError(s) dot = line.index('.') name = line[:dot] d[name] = FragmentList.fromstring(all_funcs[name], line) ans = {} def callback(f, parent): name = f.name() if name not in d: ans[name] = FragmentList.fromstring(f, '') else: ans[name] = d[name] halide.visit_funcs(root_func, callback) return Schedule(root_func, ans, genomelog, generation, index)
def fromstring(root_func, s, genomelog='', generation=-1, index=-1): """ Constructor from a string s such as 'f.root().parallel(y)\ng.chunk(y)' (same format as returned by str() method). """ if '\\n' in s: raise ValueError('Bad newline character in %r' % s) #print 'Schedule.fromstring', root_func, s all_funcs = halide.all_funcs(root_func) root_func = root_func #print 'Schedule.fromstring', repr(s) #print s.strip().split('\n') #sys.exit(1) d = {} for line in s.strip().split('\n'): line = line.strip() if len(line) == 0: continue if not '.' in line: raise ValueError(s) dot = line.index('.') name = line[:dot] d[name] = FragmentList.fromstring(all_funcs[name], line) ans = {} def callback(f, parent): name = f.name() if name not in d: ans[name] = FragmentList.fromstring(f, '') else: ans[name] = d[name] halide.visit_funcs(root_func, callback) return Schedule(root_func, ans, genomelog, generation, index)
def caller_vars(root_func, func): "Given a root Func and current function return list of variables of the caller." func_name = func.name() for (name, g) in halide.all_funcs(root_func).items(): rhs_names = [x.name() for x in g.rhs().funcs()] if func_name in rhs_names: return func_lhs_var_names(g) return []
def autotune(func, test, scope): """ Autotunes func, using test(func) as a testing function that returns a time in seconds. """ sys.argv = [sys.argv[0], 'dirname'] info = {} cfg = HalideConfigAccessor() func_d = halide.all_funcs(func) hl = HalideHighLevelConfig(info, [(key, halide.func_varlist(value)) for (key, value) in func_d.items()]) hl.randomize(cfg, 1) test_permutation() sgatuner.main(tester_lambda=lambda *a: HalideCandidateTester(hl, *a, test_func=test, func_d=func_d, func=func, scope=scope), pop_lambda=lambda *a: HalidePopulation(hl, *a), hlconfig_lambda=lambda: hl, config_lambda=lambda: cfg)
def crossover(a, b, constraints): "Cross over two schedules, using 2 point crossover." a0 = a b0 = b while True: a = constraints.constrain(copy.copy(a0)) b = constraints.constrain(copy.copy(b0)) funcL = halide.all_funcs(a.root_func, True) names = [x[0] for x in funcL] assert a.root_func is b.root_func aset = set(a.d.keys()) bset = set(b.d.keys()) assert aset == bset, (aset, bset) #== set(names) names = [x for x in names if x in aset] if random.randrange(2) == 0: (a, b) = (b, a) d = {} i1 = random.randrange(len(names)) i2 = random.randrange(len(names)) (i1, i2) = (min(i1, i2), max(i1, i2)) if i1 == 0 and i2 == len(names) - 1: i2 -= 1 for i in range(len(names)): if i1 <= i <= i2: d[names[i]] = copy.copy(a.d[names[i]]) else: d[names[i]] = copy.copy(b.d[names[i]]) ans = Schedule(a.root_func, d) try: ans.apply( constraints ) # Apply schedule to determine if crossover invalidated new variables that were referenced except (NameError, halide.ScheduleError): continue return ans
def crossover(a, b, constraints): "Cross over two schedules, using 2 point crossover." a0 = a b0 = b while True: a = constraints.constrain(copy.copy(a0)) b = constraints.constrain(copy.copy(b0)) funcL = halide.all_funcs(a.root_func, True) names = [x[0] for x in funcL] assert a.root_func is b.root_func aset = set(a.d.keys()) bset = set(b.d.keys()) assert aset == bset, (aset, bset) #== set(names) names = [x for x in names if x in aset] if random.randrange(2) == 0: (a, b) = (b, a) d = {} i1 = random.randrange(len(names)) i2 = random.randrange(len(names)) (i1, i2) = (min(i1, i2), max(i1, i2)) if i1 == 0 and i2 == len(names)-1: i2 -= 1 for i in range(len(names)): if i1 <= i <= i2: d[names[i]] = copy.copy(a.d[names[i]]) else: d[names[i]] = copy.copy(b.d[names[i]]) ans = Schedule(a.root_func, d) try: ans.apply(constraints) # Apply schedule to determine if crossover invalidated new variables that were referenced except (NameError, halide.ScheduleError): continue return ans
def get_bounds(root_func, scope): """ Returns map of func name => list of bounds for each dim, with -1 indicating unbounded. Does not do bound inference. """ bounds = {} varlist = {} for (name, f) in halide.all_funcs(root_func).items(): varlist[name] = halide.func_varlist(f) bounds[name] = [-1] * len(varlist[name]) if 'tune_constraints' in scope: constraints = autotune.Schedule.fromstring(root_func, scope['tune_constraints']) else: return bounds for (name, L) in constraints.d.items(): for x in L: if isinstance(x, autotune.FragmentBound): try: i = varlist[name].index(x.var) except IndexError: raise ValueError('could not find var %s to bound in func %s (varlist is %r)' % (x.var, name, varlist[name])) bounds[name][i] = x.size print 'bounds is:', bounds return bounds