Skip to content
Merged
Changes from 1 commit
Commits
Show all changes
63 commits
Select commit Hold shift + click to select a range
61eec43
Add `array-api` spec as submodule, load its signatures
honno Feb 8, 2022
6a4fffc
Rudimentary special case tests on runtime
honno Feb 9, 2022
ee68b89
Rudimentary testing for binary elwise special cases
honno Feb 10, 2022
1ef5b3e
Use `ph` for pos/neg zero utils
honno Feb 11, 2022
14c4793
More binary cases coverage
honno Feb 11, 2022
a937d26
Cover most sign special cases
honno Feb 14, 2022
08aebde
Rudimentary rework of value condition factories
honno Feb 15, 2022
e6f1064
Factories for result check functions
honno Feb 15, 2022
74cc8e5
Skip redundant special cases
honno Feb 15, 2022
03b9c00
Generalise not special cases
honno Feb 15, 2022
0058634
Parse either cases
honno Feb 15, 2022
0116ac5
Parse sign cases
honno Feb 15, 2022
bc85e7a
Parse more awkward equality special cases
honno Feb 16, 2022
1891a79
Parse abs special cases
honno Feb 16, 2022
d7db62d
Cond reprs, merge abs cond logic, fix approx cond factories
honno Feb 16, 2022
b0ed32f
Mark special case tests for CI
honno Feb 17, 2022
05e179e
`repr_` -> `expr`, return `BinaryCond` in `SignCondFactory`
honno Feb 17, 2022
d6f4f56
Fix abs conds not actually absifying
honno Feb 17, 2022
3d0478f
Reorder binary case patterns to avoid false matches
honno Feb 17, 2022
0ba6753
Parse quad cases
honno Feb 17, 2022
404542f
Parse most unary cases again, refactor parse utils
honno Feb 18, 2022
4ea0154
Parse even round case
honno Feb 18, 2022
e808673
Factor out class bloat for unary params
honno Feb 18, 2022
a90760c
Rudimentary generic condition parsing for binary cases
honno Feb 21, 2022
f915993
Bring back full case coverage
honno Feb 21, 2022
a1a5780
Fix local func definitions causing pass-by-reference problems
honno Mar 1, 2022
03b8f32
Use spec reprs for case `expr`
honno Mar 1, 2022
ef10e90
Factor out logic for input eq conds/results
honno Mar 2, 2022
e9e99ab
Enable submodules for NumPy workflow
honno Mar 2, 2022
709cb4c
Rudimentary cond element strategy pattern to ensure good examples
honno Mar 3, 2022
9c7c051
Cond strategies for most binary cases
honno Mar 9, 2022
420a549
Cover binary cases with two unary conds for one array
honno Mar 10, 2022
e6f9548
Cover "equal to" cases (as opposed to "is" cases)
honno Mar 10, 2022
c5a30d0
Test xor scenarios for either special cases
honno Mar 11, 2022
2217bb9
Comment on `__future__` and either case strategies
honno Mar 11, 2022
4372e90
Update NumPy workflow for new special cases
honno Mar 11, 2022
6c775a7
Generate x1 is x2 conds (and visa versa) healthily
honno Mar 14, 2022
6d8c3ca
Favour `ParseError` to assertions
honno Mar 14, 2022
63d63e1
Note check_result def problems
honno Mar 14, 2022
171ee5a
Document `BoundFromDtype` with extensive examples
honno Mar 14, 2022
cb810b9
Document `parse_cond`
honno Mar 14, 2022
ddb287a
Document `parse_result()`
honno Mar 14, 2022
67891b8
Factor out `UnaryCase.from_strings()`
honno Mar 14, 2022
b600230
Better exception messages
honno Mar 14, 2022
a9a5234
Not worry about removing spec package from path
honno Mar 14, 2022
180b152
Doc fixes
honno Mar 15, 2022
6c802c3
Document `parse_unary_docstring()`
honno Mar 15, 2022
eaa3b05
Document `parse_binary_docstring()`
honno Mar 15, 2022
8b24204
Extend `good_examples` comment
honno Mar 15, 2022
5a9ea21
Move `array-api` submodule to the top-level
honno Mar 15, 2022
795fd04
Minor doc fixes
honno Mar 15, 2022
f0c3df4
Document `make_binary_cond()`
honno Mar 16, 2022
546827e
Document `make_eq_input_check_result()`
honno Mar 16, 2022
f5b0975
Make `parse_cond()` only return `BoundFromDtype`
honno Mar 16, 2022
3773a4d
Document `parse_binary_case()`
honno Mar 16, 2022
f82fee5
Generate and test the even rounding halves case correctly
honno Mar 16, 2022
558ffdc
Case expression fixes
honno Mar 16, 2022
456fc6c
Drop outdated `x<1/2>_cond_from_dtype` logic
honno Mar 17, 2022
d95c2ab
Test special cases for operators
honno Mar 17, 2022
9eac45b
Update skipped NumPy workflow tests
honno Mar 17, 2022
2068ee4
Better repr for failing `ipow` special case test
honno Mar 17, 2022
27a00d7
Update workflow with another failing `__ipow__()` case
honno Mar 18, 2022
6642522
Note submodule in readme
honno Mar 22, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Factories for result check functions
  • Loading branch information
honno committed Mar 17, 2022
commit e6f1064d67231257344604bddbd826f1f87cf943
82 changes: 59 additions & 23 deletions array_api_tests/test_special_cases.py
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@ def __call__(self, groups: Tuple[str, ...]) -> BinaryCheck:


r_not_code = re.compile(f"not (?:equal to )?{r_code.pattern}")
r_array_element = re.compile(r"``([+-]?)x[12]_i``")
r_array_element = re.compile(r"``([+-]?)x([12])_i``")
r_gt = re.compile(f"greater than {r_code.pattern}")
r_lt = re.compile(f"less than {r_code.pattern}")
r_either_code = re.compile(f"either {r_code.pattern} or {r_code.pattern}")
Expand Down Expand Up @@ -333,8 +333,8 @@ def cond(i1: float, i2: float) -> bool:
return _cond(i2)

return cond
# this branch must come after checking for array elements
elif m := r_code.match(group):

if m := r_code.match(group):
value = parse_value(m.group(1))
_cond = make_eq(value)
elif m := r_not_code.match(group):
Expand Down Expand Up @@ -398,39 +398,75 @@ def cond(i1: float, i2: float) -> bool:

return cond

def __repr__(self) -> str:
f_cond_factories = ", ".join(
repr(cond_factory) for cond_factory in self.cond_factories
)
return f"{self.__class__.__name__}({f_cond_factories})"

class BinaryCase(NamedTuple):
cond: BinaryCheck
check_result: Callable[[float], bool]

BinaryResultCheck = Callable[[float, float, float], bool]

class BinaryCaseFactory(NamedTuple):
cond_factory: CondFactory
result_re_group: int

def __call__(self, groups: Tuple[str, ...]) -> BinaryCase:
in_cond = self.cond_factory(groups)
class ResultCheckFactory(NamedTuple):
re_group: int

def __call__(self, groups: Tuple[str, ...]) -> BinaryResultCheck:
group = groups[self.re_group]

if m := r_array_element.match(group):
cond_factory = make_eq if m.group(1) != "-" else make_neq

if m.group(2) == "1":

def cond(i1: float, i2: float, result: float) -> bool:
_cond = cond_factory(i1)
return _cond(result)

else:

s_result = groups[self.result_re_group]
if m := r_array_element.match(s_result):
raise ValueParseError(s_result) # TODO
elif m := r_code.match(s_result):
def cond(i1: float, i2: float, result: float) -> bool:
_cond = cond_factory(i2)
return _cond(result)

return cond

if m := r_code.match(group):
value = parse_value(m.group(1))
out_cond = make_eq(value)
elif m := r_approx_value.match(s_result):
_cond = make_eq(value)
elif m := r_approx_value.match(group):
value = parse_value(m.group(1))
out_cond = make_rough_eq(value)
_cond = make_rough_eq(value)
else:
raise ValueParseError(s_result)
raise ValueParseError(group)

def cond(i1: float, i2: float, result: float) -> bool:
return _cond(result)

return cond

return BinaryCase(in_cond, out_cond)

class BinaryCase(NamedTuple):
cond: BinaryCheck
check_result: BinaryResultCheck


class BinaryCaseFactory(NamedTuple):
cond_factory: CondFactory
check_result_factory: ResultCheckFactory

def __call__(self, groups: Tuple[str, ...]) -> BinaryCase:
cond = self.cond_factory(groups)
check_result = self.check_result_factory(groups)
return BinaryCase(cond, check_result)


binary_pattern_to_case_factory: Dict[Pattern, BinaryCaseFactory] = {
re.compile(
"If ``x1_i`` is (.+) and ``x2_i`` is (.+), the result is (.+)"
): BinaryCaseFactory(
AndCondFactory(ValueCondFactory("i1", 0), ValueCondFactory("i2", 1)), 2
AndCondFactory(ValueCondFactory("i1", 0), ValueCondFactory("i2", 1)),
ResultCheckFactory(2),
),
# re.compile(
# "If ``x2_i`` is (.+), the result is (.+), even if ``x1_i`` is .+"
Expand Down Expand Up @@ -671,8 +707,8 @@ def test_binary(func_name, func, cases, x1, x2):
for case in cases:
if case.cond(l, r):
good_example = True
out = float(res[o_idx])
assert case.check_result(out)
o = float(res[o_idx])
assert case.check_result(l, r, o)
# f_left = f"{sh.fmt_idx('x1', l_idx)}={l}"
# f_right = f"{sh.fmt_idx('x2', r_idx)}={r}"
# f_out = f"{sh.fmt_idx('out', o_idx)}={out}"
Expand Down