Skip to content

Commit

Permalink
Merge pull request #6316 from stuartarchibald/fix/6315
Browse files Browse the repository at this point in the history
Make IR inliner tests not self mutating.
  • Loading branch information
sklam committed Oct 7, 2020
2 parents 159510a + 6fa07dd commit 5eda874
Showing 1 changed file with 52 additions and 44 deletions.
96 changes: 52 additions & 44 deletions numba/tests/test_ir_inlining.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,8 @@ def check(self, test_impl, *args, **kwargs):
return fir # for use in further analysis

def make_dummy_type(self):
""" Use to generate a dummy type """

# Use test_id to make sure no collision is possible.
test_id = self.id()
DummyType = type('DummyTypeFor{}'.format(test_id), (types.Opaque,), {})
Expand All @@ -151,8 +153,7 @@ def typeof_dummy(val, c):
def unbox_dummy(typ, obj, c):
return NativeValue(c.context.get_dummy_value())

self.Dummy = Dummy
self.DummyType = DummyType
return Dummy, DummyType


# used in _gen_involved
Expand Down Expand Up @@ -506,12 +507,6 @@ def impl():

class TestOverloadInlining(MemoryLeakMixin, InliningBase):

def setUp(self):
# only tests for operators need DummyType
if 'operator' in self._testMethodName:
self.make_dummy_type()
super(TestOverloadInlining, self).setUp()

def test_basic_inline_never(self):
def foo():
pass
Expand Down Expand Up @@ -566,21 +561,22 @@ def impl_noinline(x):
return +x

dummy_unary_impl = lambda x: True
setattr(self.Dummy, '__neg__', dummy_unary_impl)
setattr(self.Dummy, '__pos__', dummy_unary_impl)
Dummy, DummyType = self.make_dummy_type()
setattr(Dummy, '__neg__', dummy_unary_impl)
setattr(Dummy, '__pos__', dummy_unary_impl)

@overload(operator.neg, inline='always')
def overload_dummy_neg(x):
if isinstance(x, self.DummyType):
if isinstance(x, DummyType):
return dummy_unary_impl

@overload(operator.pos, inline='never')
def overload_dummy_pos(x):
if isinstance(x, self.DummyType):
if isinstance(x, DummyType):
return dummy_unary_impl

self.check(impl_inline, self.Dummy(), inline_expect={'neg': True})
self.check(impl_noinline, self.Dummy(), inline_expect={'pos': False})
self.check(impl_inline, Dummy(), inline_expect={'neg': True})
self.check(impl_noinline, Dummy(), inline_expect={'pos': False})

def test_inline_operators_binop(self):

Expand All @@ -590,22 +586,24 @@ def impl_inline(x):
def impl_noinline(x):
return x != 1

Dummy, DummyType = self.make_dummy_type()

dummy_binop_impl = lambda a, b: True
setattr(self.Dummy, '__eq__', dummy_binop_impl)
setattr(self.Dummy, '__ne__', dummy_binop_impl)
setattr(Dummy, '__eq__', dummy_binop_impl)
setattr(Dummy, '__ne__', dummy_binop_impl)

@overload(operator.eq, inline='always')
def overload_dummy_eq(a, b):
if isinstance(a, self.DummyType):
if isinstance(a, DummyType):
return dummy_binop_impl

@overload(operator.ne, inline='never')
def overload_dummy_ne(a, b):
if isinstance(a, self.DummyType):
if isinstance(a, DummyType):
return dummy_binop_impl

self.check(impl_inline, self.Dummy(), inline_expect={'eq': True})
self.check(impl_noinline, self.Dummy(), inline_expect={'ne': False})
self.check(impl_inline, Dummy(), inline_expect={'eq': True})
self.check(impl_noinline, Dummy(), inline_expect={'ne': False})

def test_inline_operators_inplace_binop(self):

Expand All @@ -615,34 +613,36 @@ def impl_inline(x):
def impl_noinline(x):
x -= 1

Dummy, DummyType = self.make_dummy_type()

dummy_inplace_binop_impl = lambda a, b: True
setattr(self.Dummy, '__iadd__', dummy_inplace_binop_impl)
setattr(self.Dummy, '__isub__', dummy_inplace_binop_impl)
setattr(Dummy, '__iadd__', dummy_inplace_binop_impl)
setattr(Dummy, '__isub__', dummy_inplace_binop_impl)

@overload(operator.iadd, inline='always')
def overload_dummy_iadd(a, b):
if isinstance(a, self.DummyType):
if isinstance(a, DummyType):
return dummy_inplace_binop_impl

@overload(operator.isub, inline='never')
def overload_dummy_isub(a, b):
if isinstance(a, self.DummyType):
if isinstance(a, DummyType):
return dummy_inplace_binop_impl

# DummyType is not mutable, so lowering 'inplace_binop' Expr
# re-uses (requires) copying function definition
@overload(operator.add, inline='always')
def overload_dummy_add(a, b):
if isinstance(a, self.DummyType):
if isinstance(a, DummyType):
return dummy_inplace_binop_impl

@overload(operator.sub, inline='never')
def overload_dummy_sub(a, b):
if isinstance(a, self.DummyType):
if isinstance(a, DummyType):
return dummy_inplace_binop_impl

self.check(impl_inline, self.Dummy(), inline_expect={'iadd': True})
self.check(impl_noinline, self.Dummy(), inline_expect={'isub': False})
self.check(impl_inline, Dummy(), inline_expect={'iadd': True})
self.check(impl_noinline, Dummy(), inline_expect={'isub': False})

def test_inline_always_operators_getitem(self):

Expand All @@ -652,19 +652,20 @@ def impl(x, idx):
def impl_static_getitem(x):
return x[1]

Dummy, DummyType = self.make_dummy_type()

dummy_getitem_impl = lambda obj, idx: None
setattr(self.Dummy, '__getitem__', dummy_getitem_impl)
setattr(Dummy, '__getitem__', dummy_getitem_impl)

@overload(operator.getitem, inline='always')
def overload_dummy_getitem(obj, idx):
if isinstance(obj, self.DummyType):
if isinstance(obj, DummyType):
return dummy_getitem_impl

# note getitem and static_getitem Exprs refer to operator.getitem
# hence they are checked using the same expected key
self.check(impl, self.Dummy(), 1, inline_expect={'getitem': True})
self.check(impl_static_getitem,
self.Dummy(),
self.check(impl, Dummy(), 1, inline_expect={'getitem': True})
self.check(impl_static_getitem, Dummy(),
inline_expect={'getitem': True})

def test_inline_never_operators_getitem(self):
Expand All @@ -675,19 +676,20 @@ def impl(x, idx):
def impl_static_getitem(x):
return x[1]

Dummy, DummyType = self.make_dummy_type()

dummy_getitem_impl = lambda obj, idx: None
setattr(self.Dummy, '__getitem__', dummy_getitem_impl)
setattr(Dummy, '__getitem__', dummy_getitem_impl)

@overload(operator.getitem, inline='never')
def overload_dummy_getitem(obj, idx):
if isinstance(obj, self.DummyType):
if isinstance(obj, DummyType):
return dummy_getitem_impl

# noth getitem and static_getitem Exprs refer to opertor.getitem
# hence they are checked using the same expect key
self.check(impl, self.Dummy(), 1, inline_expect={'getitem': False})
self.check(impl_static_getitem,
self.Dummy(),
self.check(impl, Dummy(), 1, inline_expect={'getitem': False})
self.check(impl_static_getitem, Dummy(),
inline_expect={'getitem': False})

def test_inline_stararg_error(self):
Expand Down Expand Up @@ -1073,7 +1075,9 @@ def check_getattr(self, test_impl, args, expected, block_count,
self.assertTrue(allgetattrs)

def test_overload_method_default_args_always(self):
@overload_method(self.DummyType, "inline_method", inline='always')
Dummy, DummyType = self.make_dummy_type()

@overload_method(DummyType, "inline_method", inline='always')
def _get_inlined_method(obj, val=None, val2=None):
def get(obj, val=None, val2=None):
return ("THIS IS INLINED", val, val2)
Expand All @@ -1084,7 +1088,7 @@ def foo(obj):

self.check_method(
test_impl=foo,
args=[self.Dummy()],
args=[Dummy()],
expected=(("THIS IS INLINED", 123, None),
("THIS IS INLINED", None, 321)),
block_count=1,
Expand All @@ -1094,7 +1098,9 @@ def make_overload_method_test(self, costmodel, should_inline):
def costmodel(*args):
return should_inline

@overload_method(self.DummyType, "inline_method", inline=costmodel)
Dummy, DummyType = self.make_dummy_type()

@overload_method(DummyType, "inline_method", inline=costmodel)
def _get_inlined_method(obj, val):
def get(obj, val):
return ("THIS IS INLINED!!!", val)
Expand All @@ -1105,7 +1111,7 @@ def foo(obj):

self.check_method(
test_impl=foo,
args=[self.Dummy()],
args=[Dummy()],
expected=("THIS IS INLINED!!!", 123),
block_count=1,
expects_inlined=should_inline,
Expand Down Expand Up @@ -1136,7 +1142,9 @@ def test_overload_method_cost_driven_no_inline(self):
)

def make_overload_attribute_test(self, costmodel, should_inline):
@overload_attribute(self.DummyType, "inlineme", inline=costmodel)
Dummy, DummyType = self.make_dummy_type()

@overload_attribute(DummyType, "inlineme", inline=costmodel)
def _get_inlineme(obj):
def get(obj):
return "MY INLINED ATTRS"
Expand All @@ -1147,7 +1155,7 @@ def foo(obj):

self.check_getattr(
test_impl=foo,
args=[self.Dummy()],
args=[Dummy()],
expected="MY INLINED ATTRS",
block_count=1,
expects_inlined=should_inline,
Expand Down

0 comments on commit 5eda874

Please sign in to comment.