From 0b450b118494a866f6b61b0057b6f9b1f8ffa10a Mon Sep 17 00:00:00 2001 From: Christopher Haster Date: Sun, 17 Nov 2024 23:36:57 -0600 Subject: [PATCH] scripts: Reverted full C exprs in test/bench define ranges A couple problems: 1. We should probably also support negative ranges, but this is a bit annoying since we can't tell if the range is negative or positive until expr evaluation. 2. Evaluating the range exprs at compile-time is inconsistent from other C exprs in our tests/benches (normal defines, if filters, etc), and severely limiting since we can't use other defines before the define system is initialized. 2. Attempting to move these range exprs into their own lazily evaluated functions does not seem tractable... We'd need to evaluate defines to know how many permutations there are, but how can we evaluate defines before knowing which permutation we're on? I think this circular dependency would make the permutation count undecidable? Even if we could move these exprs to their own lazily evaluated functions (which would solve the inconsistency issue), the complexity risks outweighing the benefit. Keep in mind it's useful if external tools can parse our tests. So reverting for now. Though I am keeping some of the refactoring in test.py/bench.py. Having a special DRange type is useful if we ever want to add more define functions in the future. --- scripts/bench.py | 53 +++++++++++++++++++----------------------------- scripts/test.py | 53 +++++++++++++++++++----------------------------- 2 files changed, 42 insertions(+), 64 deletions(-) diff --git a/scripts/bench.py b/scripts/bench.py index 6710e22e..65758768 100755 --- a/scripts/bench.py +++ b/scripts/bench.py @@ -53,17 +53,18 @@ class DRange: def __init__(self, start, stop=None, step=None): if stop is None: start, stop = None, start - self.start = start if start is not None else '0' + self.start = start if start is not None else 0 self.stop = stop - self.step = step if step is not None else '1' + self.step = step if step is not None else 1 - def len(self): - return '(((%s)-1-(%s))/(%s) + 1)' % ( - self.stop, self.start, self.step) + def __len__(self): + if self.step > 0: + return (self.stop-1 - self.start) // self.step + 1 + else: + return (self.start-1 - self.stop) // -self.step + 1 def next(self, i): - return '((%s)*(%s) + (%s))' % ( - i, self.step, self.start) + return '(%s)*%d + %d' % (i, self.step, self.start) class BenchCase: @@ -124,10 +125,10 @@ class BenchCase: # the runner itself. vs = [] for v_ in csplit(v): - m = re.match(r'^\s*range\b\s*\((?P.*)\)\s*$', v_) + m = re.match(r'^\s*range\s*\((.*)\)\s*$', v_) if m: vs.append(DRange(*[ - s.strip() for s in csplit(m.group('range'))])) + int(a, 0) for a in csplit(m.group(1))])) else: vs.append(v_) return vs @@ -393,20 +394,16 @@ def compile(bench_paths, **args): for v in vs: # generate range if isinstance(v, DRange): - f.writeln(4*' '+'if (i < %s + (%s)) ' + f.writeln(4*' '+'if (i < %d) ' 'return %s;' % ( - j, v.len(), - v.next('i-(%s)' % j))) - j = '%s + %s' % (j, v.len()) + j+len(v), v.next('i-%d' % j))) + j += len(v) # translate index to define else: - f.writeln(4*' '+'if (i == %s) ' + f.writeln(4*' '+'if (i == %d) ' 'return %s;' % ( j, v)) - if isinstance(j, str): - j += ' + 1' - else: - j += 1; + j += 1 f.writeln(4*' '+'__builtin_unreachable();') f.writeln('}') @@ -544,22 +541,14 @@ def compile(bench_paths, **args): f.writeln(20*' '+'[%d] = {' '"%s", &%s, ' '__bench__%s__%s__%d, ' - 'NULL, %s},' % ( + 'NULL, %d},' % ( sorted(suite.defines).index(k), k, k, case.name, k, i, - ft.reduce( - lambda x, y: - '%s + %s' % (x, y) - if isinstance( - x, str) - or isinstance( - y, str) - else x + y, - (v.len() - if isinstance( - v, DRange) - else 1 - for v in vs)))) + sum(len(v) + if isinstance( + v, DRange) + else 1 + for v in vs))) f.writeln(16*' '+'},') f.writeln(12*' '+'},') f.writeln(12*' '+'.permutations = %d,' % ( diff --git a/scripts/test.py b/scripts/test.py index 579c467a..3a2c9b00 100755 --- a/scripts/test.py +++ b/scripts/test.py @@ -54,17 +54,18 @@ class DRange: def __init__(self, start, stop=None, step=None): if stop is None: start, stop = None, start - self.start = start if start is not None else '0' + self.start = start if start is not None else 0 self.stop = stop - self.step = step if step is not None else '1' + self.step = step if step is not None else 1 - def len(self): - return '(((%s)-1-(%s))/(%s) + 1)' % ( - self.stop, self.start, self.step) + def __len__(self): + if self.step > 0: + return (self.stop-1 - self.start) // self.step + 1 + else: + return (self.start-1 - self.stop) // -self.step + 1 def next(self, i): - return '((%s)*(%s) + (%s))' % ( - i, self.step, self.start) + return '(%s)*%d + %d' % (i, self.step, self.start) class TestCase: @@ -130,10 +131,10 @@ class TestCase: # the runner itself. vs = [] for v_ in csplit(v): - m = re.match(r'^\s*range\b\s*\((?P.*)\)\s*$', v_) + m = re.match(r'^\s*range\s*\((.*)\)\s*$', v_) if m: vs.append(DRange(*[ - s.strip() for s in csplit(m.group('range'))])) + int(a, 0) for a in csplit(m.group(1))])) else: vs.append(v_) return vs @@ -405,20 +406,16 @@ def compile(test_paths, **args): for v in vs: # generate range if isinstance(v, DRange): - f.writeln(4*' '+'if (i < %s + (%s)) ' + f.writeln(4*' '+'if (i < %d) ' 'return %s;' % ( - j, v.len(), - v.next('i-(%s)' % j))) - j = '%s + %s' % (j, v.len()) + j+len(v), v.next('i-%d' % j))) + j += len(v) # translate index to define else: - f.writeln(4*' '+'if (i == %s) ' + f.writeln(4*' '+'if (i == %d) ' 'return %s;' % ( j, v)) - if isinstance(j, str): - j += ' + 1' - else: - j += 1; + j += 1 f.writeln(4*' '+'__builtin_unreachable();') f.writeln('}') @@ -562,22 +559,14 @@ def compile(test_paths, **args): f.writeln(20*' '+'[%d] = {' '"%s", &%s, ' '__test__%s__%s__%d, ' - 'NULL, %s},' % ( + 'NULL, %d},' % ( sorted(suite.defines).index(k), k, k, case.name, k, i, - ft.reduce( - lambda x, y: - '%s + %s' % (x, y) - if isinstance( - x, str) - or isinstance( - y, str) - else x + y, - (v.len() - if isinstance( - v, DRange) - else 1 - for v in vs)))) + sum(len(v) + if isinstance( + v, DRange) + else 1 + for v in vs))) f.writeln(16*' '+'},') f.writeln(12*' '+'},') f.writeln(12*' '+'.permutations = %d,' % (