def test_fn(): res = TestResource() def f(y): return res.x + y opts = converter.ConversionOptions(recursive=True) api.converted_call(f, None, opts, (1,), {})
def test_converted_call_builtin(self): x = api.converted_call(range, None, converter.ConversionOptions(recursive=True), (3,), {}) self.assertEqual((0, 1, 2), tuple(x)) x = api.converted_call('compile', re, converter.ConversionOptions(recursive=True), ('mnas_v4_a.*\\/.*(weights|kernel):0$',), {}) self.assertIsNotNone(x.match('mnas_v4_a/weights:0'))
def test_fn(): res = TestResource() def f(y): def inner_f(): return res.x + y return inner_f opts = converter.ConversionOptions() api.converted_call(f, None, opts, (1,), {})()
def test_converted_call_already_converted(self): def f(x): return x == 0 x = api.converted_call(f, None, converter.ConversionOptions(), (constant_op.constant(0),), {}) self.assertTrue(self.evaluate(x)) converted_f = api.to_graph(f) x = api.converted_call(converted_f, None, converter.ConversionOptions(), (constant_op.constant(0),), {}) self.assertTrue(self.evaluate(x))
def test_converted_call_already_converted(self): def f(x): return x == 0 with self.cached_session() as sess: x = api.converted_call(f, None, converter.ConversionOptions(), constant_op.constant(0)) self.assertTrue(sess.run(x)) converted_f = api.to_graph(f) x = api.converted_call(converted_f, None, converter.ConversionOptions(), constant_op.constant(0)) self.assertTrue(sess.run(x))
def test_converted_call_already_converted(self): def f(x): return x == 0 with self.test_session() as sess: x = api.converted_call(f, False, False, False, {}, constant_op.constant(0)) self.assertTrue(sess.run(x)) converted_f = api.to_graph(f) x = api.converted_call(converted_f, False, False, False, {}, constant_op.constant(0)) self.assertTrue(sess.run(x))
def test_converted_call_already_converted(self): def f(x): return x == 0 x = api.converted_call(f, None, converter.ConversionOptions(recursive=True), (constant_op.constant(0),), {}) self.assertTrue(self.evaluate(x)) converted_f = api.to_graph( f, experimental_optional_features=converter.Feature.ALL) x = api.converted_call(converted_f, None, converter.ConversionOptions(recursive=True), (constant_op.constant(0),), {}) self.assertTrue(self.evaluate(x))
def test_converted_call_no_user_code(self): def f(x): return len(x) opts = converter.ConversionOptions(internal_convert_user_code=False) # f should not be converted, causing len to error out. with self.assertRaisesRegexp(Exception, 'object of type \'Tensor\' has no len()'): api.converted_call(f, None, opts, constant_op.constant([0])) # len on the other hand should work fine. x = api.converted_call(len, None, opts, constant_op.constant([0])) # The constant has static shape so the result is a primitive not a Tensor. self.assertEqual(x, 1)
def test_converted_call_numpy(self): opts = converter.ConversionOptions(recursive=True) x = api.converted_call(np.arange, None, opts, (5,), {}) self.assertAllEqual(x, list(range(5)))
def test_converted_call_namedtuple(self): opts = converter.ConversionOptions() x = api.converted_call(collections.namedtuple, None, opts, ('TestNamedtuple', ('a', 'b')), {}) self.assertTrue(inspect_utils.isnamedtuple(x))
def test_converted_call_functools_partial(self): def test_fn(x, y, z): if x < 0: return -x, -y, -z return x, y, z x = api.converted_call( functools.partial(test_fn, constant_op.constant(-1), z=-3), None, converter.ConversionOptions(), (constant_op.constant(-2),), {}) self.assertEqual((1, 2, 3), self.evaluate(x)) x = api.converted_call( functools.partial( functools.partial(test_fn, constant_op.constant(-1)), z=-3), None, converter.ConversionOptions(), (constant_op.constant(-2),), {}) self.assertEqual((1, 2, 3), self.evaluate(x))
def test_converted_call_namedtuple_via_collections(self): opts = converter.ConversionOptions(recursive=True) x = api.converted_call('namedtuple', collections, opts, ('TestNamedtuple', ('a', 'b')), {}) self.assertTrue(inspect_utils.isnamedtuple(x))
def test_converted_call_tf_op_forced(self): # TODO(mdan): Add the missing level of support to LOGICAL_EXPRESSIONS. opts = converter.ConversionOptions( force_conversion=True, optional_features=None) x = api.converted_call(gen_math_ops.add, None, opts, (1, 1), {}) self.assertAllEqual(self.evaluate(x), 2)
def test_converted_call_no_kwargs_allowed(self): def f(*args): # Note: np.broadcast rejects any **kwargs, even *{} return np.broadcast(args[:1]) opts = converter.ConversionOptions(internal_convert_user_code=False) self.assertIsNotNone(api.converted_call(f, None, opts, (1, 2, 3, 4), None))
def test_converted_call_function(self): def test_fn(x): if x < 0: return -x return x x = api.converted_call(test_fn, None, converter.ConversionOptions(), (constant_op.constant(-1),), {}) self.assertEqual(1, self.evaluate(x))
def test_converted_call_lambda(self): opts = converter.ConversionOptions(recursive=True) l = lambda x: x == 0 x = api.converted_call(l, None, opts, (constant_op.constant(0),), {}) self.evaluate(variables.global_variables_initializer()) self.assertAllEqual(True, self.evaluate(x))
def test_converted_call_function(self): def test_fn(x): if x < 0: return -x return x with self.cached_session() as sess: x = api.converted_call(test_fn, None, converter.ConversionOptions(), constant_op.constant(-1)) self.assertEqual(1, sess.run(x))
def test_converted_call_lambda(self): opts = converter.ConversionOptions() l = lambda x: x == 0 x = api.converted_call(l, None, opts, constant_op.constant(0)) with self.cached_session() as sess: sess.run(variables.global_variables_initializer()) self.assertAllEqual(True, sess.run(x))
def test_converted_call_function(self): def test_fn(x): if x < 0: return -x return x with self.test_session() as sess: x = api.converted_call(test_fn, False, False, False, {}, constant_op.constant(-1)) self.assertEqual(1, sess.run(x))
def test_converted_call_exec_generated_code(self): temp_mod = imp.new_module('test_module') dynamic_code = ''' def foo(x): return x + 1 ''' exec(textwrap.dedent(dynamic_code), temp_mod.__dict__) # pylint:disable=exec-used opts = converter.ConversionOptions(optional_features=None) x = api.converted_call(temp_mod.foo, None, opts, (1,), {}) self.assertAllEqual(x, 2)
def test_converted_call_whitelisted_method_via_owner(self): opts = converter.ConversionOptions(recursive=True) model = sequential.Sequential([ core.Dense(2) ]) x = api.converted_call('call', model, opts, (constant_op.constant([[0.0]]),), {'training': True}) self.evaluate(variables.global_variables_initializer()) self.assertAllEqual([[0.0, 0.0]], self.evaluate(x))
def test_converted_call_whitelisted_method_via_owner(self): opts = converter.ConversionOptions() model = sequential.Sequential([ core.Dense(2) ]) x = api.converted_call('call', model, opts, constant_op.constant([[0.0]]), training=True) with self.cached_session() as sess: sess.run(variables.global_variables_initializer()) self.assertAllEqual([[0.0, 0.0]], sess.run(x))
def test_converted_call_method_wrapper(self): class TestClass(object): def foo(self): pass tc = TestClass() # `method.__get__()` returns a so-called method-wrapper. wrapper = api.converted_call('__get__', tc.foo, converter.ConversionOptions(recursive=True), (tc,), {}) self.assertEqual(wrapper, tc.foo)
def test_converted_call_mangled_properties(self): class TestClass(object): def __init__(self): self.__private = constant_op.constant(-1) def test_method(self): return self.__private tc = TestClass() with self.assertRaisesRegex(errors.UnsupportedLanguageElementError, 'mangled names'): api.converted_call(tc.test_method, (), None, options=DEFAULT_RECURSIVE) # TODO(mdan): Refactor to avoid this use of global state. ag_logging.set_verbosity(0, True) os.environ['AUTOGRAPH_STRICT_CONVERSION'] = '0' with self.assertPrints('could not transform', 'bug'): api.converted_call(tc.test_method, (), None, options=DEFAULT_RECURSIVE) ag_logging.set_verbosity(0, False) os.environ['AUTOGRAPH_STRICT_CONVERSION'] = '1'
def test_converted_call_functools_partial_kwarg_mutation(self): def test_fn(x, y, z): if x < 0: return -x, -y, -z return x, y, z partial_fn = functools.partial(test_fn, constant_op.constant(-1), z=-3) # Call using kwargs to assign y first to ensure that partial_fn.keywords is # not mutated for subsequent calls (where y is assign through args). x = api.converted_call( partial_fn, args=(), kwargs={ 'y': constant_op.constant(-2), }, options=DEFAULT_RECURSIVE) self.assertEqual((1, 2, 3), self.evaluate(x)) x = api.converted_call( partial_fn, args=(constant_op.constant(-4),), kwargs=None, options=DEFAULT_RECURSIVE) self.assertEqual((1, 4, 3), self.evaluate(x))
def test_converted_call_whitelisted_method_via_owner(self): opts = converter.ConversionOptions() model = sequential.Sequential([core.Dense(2)]) x = api.converted_call('call', model, opts, constant_op.constant([[0.0]]), training=True) with self.cached_session() as sess: self.evaluate(variables.global_variables_initializer()) self.assertAllEqual([[0.0, 0.0]], self.evaluate(x))
def test_converted_call_callable_object(self): class TestClass(object): def __init__(self, x): self.x = x def __call__(self): if self.x < 0: return -self.x return self.x tc = TestClass(constant_op.constant(-1)) x = api.converted_call(tc, None, converter.ConversionOptions(), (), {}) self.assertEqual(1, self.evaluate(x))
def test_converted_call_method_by_class(self): class TestClass(object): def __init__(self, x): self.x = x def test_method(self): if self.x < 0: return -self.x return self.x tc = TestClass(constant_op.constant(-1)) x = api.converted_call(TestClass.test_method, (tc, ), None, options=DEFAULT_RECURSIVE) self.assertEqual(1, self.evaluate(x))
def test_converted_call_callable_object(self): class TestClass(object): def __init__(self, x): self.x = x def __call__(self): if self.x < 0: return -self.x return self.x tc = TestClass(constant_op.constant(-1)) x = api.converted_call(tc, None, converter.ConversionOptions(recursive=True), (), {}) self.assertEqual(1, self.evaluate(x))
def test_converted_call_then_already_converted_dynamic(self): @api.convert() def g(x): if x > 0: return x else: return -x def f(g, x): return g(x) x = api.converted_call(f, None, converter.ConversionOptions(recursive=True), (g, constant_op.constant(1)), {}) self.assertEqual(self.evaluate(x), 1)
def test_converted_call_then_already_converted_dynamic(self): @api.convert() def g(x): if x > 0: return x else: return -x def f(g, x): return g(x) x = api.converted_call(f, converter.ConversionOptions(recursive=True), (g, constant_op.constant(1)), {}) self.assertEqual(self.evaluate(x), 1)
def test_converted_call_method_by_class(self): class TestClass(object): def __init__(self, x): self.x = x def test_method(self): if self.x < 0: return -self.x return self.x tc = TestClass(constant_op.constant(-1)) x = api.converted_call(TestClass.test_method, converter.ConversionOptions(recursive=True), (tc, ), {}) self.assertEqual(1, self.evaluate(x))
def test_converted_call_then_already_converted_dynamic(self): @api.convert() def g(x): if x > 0: return x else: return -x def f(g, x): return g(x) x = api.converted_call(f, (g, constant_op.constant(1)), None, options=DEFAULT_RECURSIVE) self.assertEqual(self.evaluate(x), 1)
def test_converted_call_callable_abc(self): test_self = self @six.add_metaclass(abc.ABCMeta) class TestBase(object): @abc.abstractmethod def __call__(self): test_self.fail('This should not be called') class TestSubclass(TestBase): def __init__(self): test_self.assertFalse( converter_testing.is_inside_generated_code()) def __call__(self, expected): test_self.assertTrue(expected) test_self.assertTrue( converter_testing.is_inside_generated_code()) tc = api.converted_call(TestSubclass, (), None, options=DEFAULT_RECURSIVE) api.converted_call(tc, (True, ), None, options=DEFAULT_RECURSIVE)
def test_converted_call_avoids_triggering_operators(self): test_self = self class Pair(collections.namedtuple('Pair', ['a', 'b'])): def __call__(self): return self.a + self.b def __eq__(self, other): test_self.fail('Triggered operator') p = Pair(constant_op.constant(1), constant_op.constant(2)) x = api.converted_call(p, (), {}, options=DEFAULT_RECURSIVE) self.assertIsNotNone(self.evaluate(x), 3)
def test_converted_call_method_by_class(self): class TestClass(object): def __init__(self, x): self.x = x def test_method(self): if self.x < 0: return -self.x return self.x with self.cached_session() as sess: tc = TestClass(constant_op.constant(-1)) x = api.converted_call(TestClass.test_method, None, converter.ConversionOptions(), tc) self.assertEqual(1, self.evaluate(x))
def test_converted_call_synthetic_method(self): class TestClass(object): def __init__(self, x): self.x = x def test_function(self): if self.x < 0: return -self.x return self.x tc = TestClass(constant_op.constant(-1)) test_method = types.MethodType(test_function, tc) x = api.converted_call(test_method, None, converter.ConversionOptions(), (), {}) self.assertEqual(1, self.evaluate(x))
def test_converted_call_method_by_class(self): class TestClass(object): def __init__(self, x): self.x = x def test_method(self): if self.x < 0: return -self.x return self.x with self.test_session() as sess: tc = TestClass(constant_op.constant(-1)) x = api.converted_call(TestClass.test_method, False, False, False, {}, tc) self.assertEqual(1, sess.run(x))
def test_converted_call_namedtuple_subclass_unbound_method(self): class TestClass(collections.namedtuple('TestNamedtuple', ('a', 'b'))): def test_method(self, x): while tf.reduce_sum(x) > self.a: x //= self.b return x opts = converter.ConversionOptions(recursive=True) obj = TestClass(5, 2) x = api.converted_call(TestClass.test_method, opts, (obj, constant_op.constant([2, 4])), {}) self.assertAllEqual(self.evaluate(x), [1, 2])
def test_converted_call_callable_object(self): class TestClass(object): def __init__(self, x): self.x = x def __call__(self): if self.x < 0: return -self.x return self.x with self.cached_session() as sess: tc = TestClass(constant_op.constant(-1)) x = api.converted_call(tc, None, converter.ConversionOptions()) self.assertEqual(1, sess.run(x))
def test_converted_call_method(self): class TestClass(object): def __init__(self, x): self.x = x def test_method(self): if self.x < 0: return -self.x return self.x with self.cached_session() as sess: tc = TestClass(constant_op.constant(-1)) x = api.converted_call(tc.test_method, api.ConversionOptions.new(), tc) self.assertEqual(1, sess.run(x))
def test_converted_call_namedtuple_subclass_unbound_method(self): class TestClass(collections.namedtuple('TestNamedtuple', ('a', 'b'))): def test_method(self, x): while tf.reduce_sum(x) > self.a: x //= self.b return x obj = TestClass(5, 2) x = api.converted_call( TestClass.test_method, (obj, constant_op.constant([2, 4])), None, options=DEFAULT_RECURSIVE) self.assertAllEqual(self.evaluate(x), [1, 2])
def test_converted_call_constructor(self): class TestClass(object): def __init__(self, x): self.x = x def test_method(self): if self.x < 0: return -self.x return self.x with self.test_session() as sess: tc = api.converted_call(TestClass, False, False, False, {}, constant_op.constant(-1)) # tc is now a converted object. x = tc.test_method() self.assertEqual(1, sess.run(x))
def test_converted_call_method_converts_recursively(self): class TestClass(object): def __init__(self, x): self.x = x def other_method(self): if self.x < 0: return -self.x return self.x def test_method(self): return self.other_method() tc = TestClass(constant_op.constant(-1)) x = api.converted_call(tc.test_method, None, converter.ConversionOptions(recursive=True), tc) self.assertEqual(1, self.evaluate(x))
def test_converted_call_constructor(self): class TestClass(object): def __init__(self, x): self.x = x def test_method(self): if self.x < 0: return -self.x return self.x with self.cached_session() as sess: tc = api.converted_call(TestClass, None, converter.ConversionOptions(), constant_op.constant(-1)) # tc is now a converted object. x = tc.test_method() self.assertEqual(1, self.evaluate(x))
def test_converted_call_method_by_class(self): class TestClass(object): def __init__(self, x): self.x = x def test_method(self): if self.x < 0: return -self.x return self.x tc = TestClass(constant_op.constant(-1)) x = api.converted_call(TestClass.test_method, None, converter.ConversionOptions(recursive=True), (tc,), {}) self.assertEqual(1, self.evaluate(x))
def test_converted_call_defun_object_method(self): # pylint:disable=method-hidden class TestClass(object): def method(self): return 1 def prepare(self): self.method = function.defun(self.method) # pylint:enable=method-hidden tc = TestClass() tc.prepare() x = api.converted_call(tc.method, (), None, options=DEFAULT_RECURSIVE) self.assertAllEqual(1, self.evaluate(x))
def test_converted_call_callable_metaclass(self): class TestMetaclass(type): x = constant_op.constant(-1) def __call__(cls): if cls.x < 0: cls.x = -cls.x return cls tc = TestMetaclass('TestClass', (), {}) # This functools.partial will hide the class form the constructor # check. Not ideal. See b/120224672. tc = functools.partial(tc) converted_tc = api.converted_call(tc, (), None, options=DEFAULT_RECURSIVE) self.assertIsInstance(converted_tc, TestMetaclass) self.assertEqual(1, self.evaluate(converted_tc.x))
def test_converted_call_method_converts_recursively(self): class TestClass(object): def __init__(self, x): self.x = x def other_method(self): if self.x < 0: return -self.x return self.x def test_method(self): return self.other_method() tc = TestClass(constant_op.constant(-1)) x = api.converted_call(tc.test_method, (), None, options=DEFAULT_RECURSIVE) self.assertEqual(1, self.evaluate(x))
def test_converted_call_constructor(self): class TestClass(object): def __init__(self, x): self.x = x def test_method(self): if self.x < 0: return -self.x return self.x tc = api.converted_call(TestClass, (constant_op.constant(-1), ), None, options=DEFAULT_RECURSIVE) # tc is still a TestClass - constructors are whitelisted. # TODO(b/124016764): Support this use case. # The error below is specific to the `if` statement not being converted. with self.assertRaises(TypeError): tc.test_method()
def test_converted_call_constructor(self): class TestClass(object): def __init__(self, x): self.x = x def test_method(self): if self.x < 0: return -self.x return self.x tc = api.converted_call(TestClass, None, converter.ConversionOptions(), (constant_op.constant(-1), ), {}) # tc is still a TestClass - constructors are whitelisted. # TODO(b/124016764): Support this use case. # The error below is specific to the `if` statement not being converted. with self.assertRaisesRegex(TypeError, 'Using a `tf.Tensor` as a Python `bool`'): tc.test_method()
def test_super_with_two_args(self): test_case_self = self class TestBase(object): def plus_three(self, x): return x + 3 class TestSubclass(TestBase): def plus_three(self, x): test_case_self.fail('This should never be called.') def two_args(self, x): return super(TestSubclass, self).plus_three(x) tc = api.converted_call(TestSubclass, (), None, options=DEFAULT_RECURSIVE) self.assertEqual(5, tc.two_args(2))
def test_super_with_two_args(self): test_case_self = self class TestBase(object): def plus_three(self, x): return x + 3 class TestSubclass(TestBase): def plus_three(self, x): test_case_self.fail('This should never be called.') def two_args(self, x): return super(TestSubclass, self).plus_three(x) tc = api.converted_call(TestSubclass, converter.ConversionOptions(recursive=True), (), {}) self.assertEqual(5, tc.two_args(2))
def test_converted_call_method_as_object_attribute(self): class AnotherClass(object): def __init__(self): self.another_class_attr = constant_op.constant(1) def method(self): if self.another_class_attr > 0: return self.another_class_attr + 1 return self.another_class_attr + 10 class TestClass(object): def __init__(self, another_obj_method): self.another_obj_method = another_obj_method obj = AnotherClass() tc = TestClass(obj.method) x = api.converted_call('another_obj_method', tc, converter.ConversionOptions(), (), {}) self.assertEqual(self.evaluate(x), 2)
def test_converted_call_defun_object_method(self): opts = converter.ConversionOptions(recursive=True) # pylint:disable=method-hidden class TestClass(object): def method(self): return 1 def prepare(self): self.method = function.defun(self.method) # pylint:enable=method-hidden tc = TestClass() tc.prepare() x = api.converted_call(tc.method, None, opts, (), {}) self.assertAllEqual(1, self.evaluate(x))
def test_super_with_one_arg(self): test_case_self = self class TestBase(object): def plus_three(self, x): return x + 3 class TestSubclass(TestBase): def plus_three(self, x): test_case_self.fail('This should never be called.') def one_arg(self, x): test_base_unbound = super(TestSubclass) test_base = test_base_unbound.__get__(self, TestSubclass) return test_base.plus_three(x) tc = api.converted_call(TestSubclass, converter.ConversionOptions(recursive=True), (), {}) self.assertEqual(5, tc.one_arg(2))
def test_converted_call_callable_metaclass(self): test_self = self class TestMetaclass(type): def __call__(cls): self.assertTrue(converter_testing.is_inside_generated_code()) inst = object.__new__(cls) inst.__init__() def instance_call(unused_self): test_self.fail( 'The class-bound __call__ should be called, not the instance' ' bound one.') inst.__call__ = instance_call return inst tmc = TestMetaclass('TestClass', (), {}) tc = api.converted_call(tmc, (), None, options=DEFAULT_RECURSIVE) self.assertIsInstance(tc, tmc)
def test_super_with_one_arg(self): test_case_self = self class TestBase(object): def plus_three(self, x): return x + 3 class TestSubclass(TestBase): def plus_three(self, x): test_case_self.fail('This should never be called.') def one_arg(self, x): test_base_unbound = super(TestSubclass) test_base = test_base_unbound.__get__(self, TestSubclass) return test_base.plus_three(x) tc = api.converted_call(TestSubclass, (), None, options=DEFAULT_RECURSIVE) self.assertEqual(5, tc.one_arg(2))