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.
This commit is contained in:
Christopher Haster
2024-11-17 23:36:57 -06:00
parent 608d8a2bc1
commit 0b450b1184
2 changed files with 42 additions and 64 deletions
+18 -29
View File
@@ -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<range>.*)\)\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()
sum(len(v)
if isinstance(
v, DRange)
else 1
for v in vs))))
for v in vs)))
f.writeln(16*' '+'},')
f.writeln(12*' '+'},')
f.writeln(12*' '+'.permutations = %d,' % (
+18 -29
View File
@@ -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<range>.*)\)\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()
sum(len(v)
if isinstance(
v, DRange)
else 1
for v in vs))))
for v in vs)))
f.writeln(16*' '+'},')
f.writeln(12*' '+'},')
f.writeln(12*' '+'.permutations = %d,' % (