Example #1
0
  def test_returns_value_with_elements_value_placement_literal(self):
    executor = create_test_executor()
    value, type_signature = executor_test_utils.create_dummy_placement_literal()

    element = self.run_sync(executor.create_value(value, type_signature))
    elements = [element] * 3
    type_signature = computation_types.StructType([type_signature] * 3)
    result = self.run_sync(executor.create_struct(elements))

    self.assertIsInstance(result, executor_value_base.ExecutorValue)
    self.assertEqual(result.type_signature.compact_representation(),
                     type_signature.compact_representation())
Example #2
0
class FederatingExecutorCreateTupleTest(executor_test_utils.AsyncTestCase,
                                        parameterized.TestCase):

    # pyformat: disable
    @parameterized.named_parameters([
        ('intrinsic_def', *executor_test_utils.create_dummy_intrinsic_def()),
        ('placement_literal',
         *executor_test_utils.create_dummy_placement_literal()),
        ('computation_impl',
         *executor_test_utils.create_dummy_computation_impl()),
        ('computation_call',
         *executor_test_utils.create_dummy_computation_call()),
        ('computation_intrinsic',
         *executor_test_utils.create_dummy_computation_intrinsic()),
        ('computation_lambda',
         *executor_test_utils.create_dummy_computation_lambda_empty()),
        ('computation_placement',
         *executor_test_utils.create_dummy_computation_placement()),
        ('computation_selection',
         *executor_test_utils.create_dummy_computation_selection()),
        ('computation_tensorflow',
         *executor_test_utils.create_dummy_computation_tensorflow_empty()),
        ('computation_tuple',
         *executor_test_utils.create_dummy_computation_tuple()),
        ('federated_type_clients',
         *executor_test_utils.create_dummy_value_clients()),
        ('federated_type_clients_all_equal',
         *executor_test_utils.create_dummy_value_clients_all_equal()),
        ('federated_type_server',
         *executor_test_utils.create_dummy_value_server()),
        ('unplaced_type', *executor_test_utils.create_dummy_value_unplaced()),
    ])
    # pyformat: enable
    def test_returns_value_with_elements(self, element, type_signature):
        executor = create_test_executor(num_clients=3)

        element = self.run_sync(executor.create_value(element, type_signature))
        elements = [element] * 3
        type_signature = computation_types.NamedTupleType([type_signature] * 3)
        result = self.run_sync(executor.create_tuple(elements))

        self.assertIsInstance(result,
                              federating_executor.FederatingExecutorValue)
        self.assertEqual(result.type_signature.compact_representation(),
                         type_signature.compact_representation())

    def test_raises_type_error_with_unembedded_elements(self):
        executor = create_test_executor(num_clients=3)
        element, _ = executor_test_utils.create_dummy_value_unplaced()

        elements = [element] * 3
        with self.assertRaises(TypeError):
            self.run_sync(executor.create_tuple(elements))
class FederatingExecutorCreateTupleTest(executor_test_utils.AsyncTestCase,
                                        parameterized.TestCase):

    # pyformat: disable
    @parameterized.named_parameters([
        ('placement_literal',
         *executor_test_utils.create_dummy_placement_literal()),
        ('computation_call',
         *executor_test_utils.create_dummy_computation_call()),
        ('computation_placement',
         *executor_test_utils.create_dummy_computation_placement()),
        ('computation_selection',
         *executor_test_utils.create_dummy_computation_selection()),
        ('computation_tuple',
         *executor_test_utils.create_dummy_computation_tuple()),
        ('federated_type_at_clients',
         *executor_test_utils.create_dummy_value_at_clients()),
        ('federated_type_at_clients_all_equal',
         *executor_test_utils.create_dummy_value_at_clients_all_equal()),
        ('federated_type_at_server',
         *executor_test_utils.create_dummy_value_at_server()),
        ('unplaced_type', *executor_test_utils.create_dummy_value_unplaced()),
    ])
    # pyformat: enable
    def test_returns_value_with_elements_value(self, value, type_signature):
        executor = create_test_executor()

        element = self.run_sync(executor.create_value(value, type_signature))
        elements = [element] * 3
        type_signature = computation_types.NamedTupleType([type_signature] * 3)
        result = self.run_sync(executor.create_tuple(elements))

        self.assertIsInstance(result,
                              federating_executor.FederatingExecutorValue)
        self.assertEqual(result.type_signature.compact_representation(),
                         type_signature.compact_representation())
        # TODO(b/153578410): Some `FederatingExecutorValue` that can can be
        # constructed, can not be computed.

    # pyformat: disable
    @parameterized.named_parameters([
        ('intrinsic_def_federated_eval_at_server', *executor_test_utils.
         create_dummy_intrinsic_def_federated_eval_at_server(),
         *executor_test_utils.create_dummy_computation_tensorflow_constant()),
        ('computation_intrinsic',
         *executor_test_utils.create_dummy_computation_intrinsic(),
         *executor_test_utils.create_dummy_computation_tensorflow_constant()),
    ])
    # pyformat: enable
    def test_returns_value_with_elements_fn_and_arg(self, fn, fn_type, arg,
                                                    arg_type):
        executor = create_test_executor()

        fn = self.run_sync(executor.create_value(fn, fn_type))
        arg = self.run_sync(executor.create_value(arg, arg_type))
        element = self.run_sync(executor.create_call(fn, arg))
        elements = [element] * 3
        type_signature = computation_types.NamedTupleType([fn_type.result] * 3)
        result = self.run_sync(executor.create_tuple(elements))

        self.assertIsInstance(result,
                              federating_executor.FederatingExecutorValue)
        self.assertEqual(result.type_signature.compact_representation(),
                         type_signature.compact_representation())
        actual_result = self.run_sync(result.compute())
        expected_result = [self.run_sync(element.compute())] * 3
        self.assertCountEqual(actual_result, expected_result)

    # pyformat: disable
    @parameterized.named_parameters([
        ('computation_tensorflow',
         *executor_test_utils.create_dummy_computation_tensorflow_empty()),
    ])
    # pyformat: enable
    def test_returns_value_with_elements_fn_only(self, fn, fn_type):
        executor = create_test_executor()

        fn = self.run_sync(executor.create_value(fn, fn_type))
        element = self.run_sync(executor.create_call(fn))
        elements = [element] * 3
        type_signature = computation_types.NamedTupleType([fn_type.result] * 3)
        result = self.run_sync(executor.create_tuple(elements))

        self.assertIsInstance(result,
                              federating_executor.FederatingExecutorValue)
        self.assertEqual(result.type_signature.compact_representation(),
                         type_signature.compact_representation())
        actual_result = self.run_sync(result.compute())
        expected_result = [self.run_sync(element.compute())] * 3
        self.assertCountEqual(actual_result, expected_result)

    def test_raises_type_error_with_unembedded_elements(self):
        executor = create_test_executor()
        element, _ = executor_test_utils.create_dummy_value_unplaced()

        elements = [element] * 3
        with self.assertRaises(TypeError):
            self.run_sync(executor.create_tuple(elements))
class FederatingExecutorCreateValueTest(executor_test_utils.AsyncTestCase,
                                        parameterized.TestCase):

    # pyformat: disable
    @parameterized.named_parameters([
        ('placement_literal',
         *executor_test_utils.create_dummy_placement_literal()),
        ('computation_call',
         *executor_test_utils.create_dummy_computation_call()),
        ('computation_intrinsic',
         *executor_test_utils.create_dummy_computation_intrinsic()),
        ('computation_lambda',
         *executor_test_utils.create_dummy_computation_lambda_empty()),
        ('computation_placement',
         *executor_test_utils.create_dummy_computation_placement()),
        ('computation_selection',
         *executor_test_utils.create_dummy_computation_selection()),
        ('computation_tensorflow',
         *executor_test_utils.create_dummy_computation_tensorflow_empty()),
        ('computation_tuple',
         *executor_test_utils.create_dummy_computation_tuple()),
        ('federated_type_at_clients',
         *executor_test_utils.create_dummy_value_at_clients()),
        ('federated_type_at_clients_all_equal',
         *executor_test_utils.create_dummy_value_at_clients_all_equal()),
        ('federated_type_at_server',
         *executor_test_utils.create_dummy_value_at_server()),
        ('unplaced_type', *executor_test_utils.create_dummy_value_unplaced()),
    ] + get_named_parameters_for_supported_intrinsics())
    # pyformat: enable
    def test_returns_value_with_value_and_type(self, value, type_signature):
        executor = create_test_executor()

        result = self.run_sync(executor.create_value(value, type_signature))

        self.assertIsInstance(result,
                              federating_executor.FederatingExecutorValue)
        self.assertEqual(result.type_signature.compact_representation(),
                         type_signature.compact_representation())

    # pyformat: disable
    @parameterized.named_parameters([
        ('placement_literal',
         *executor_test_utils.create_dummy_placement_literal()),
        ('computation_call',
         *executor_test_utils.create_dummy_computation_call()),
        ('computation_intrinsic',
         *executor_test_utils.create_dummy_computation_intrinsic()),
        ('computation_lambda',
         *executor_test_utils.create_dummy_computation_lambda_empty()),
        ('computation_placement',
         *executor_test_utils.create_dummy_computation_placement()),
        ('computation_selection',
         *executor_test_utils.create_dummy_computation_selection()),
        ('computation_tensorflow',
         *executor_test_utils.create_dummy_computation_tensorflow_empty()),
        ('computation_tuple',
         *executor_test_utils.create_dummy_computation_tuple()),
    ])
    # pyformat: enable
    def test_returns_value_with_value_only(self, value, type_signature):
        executor = create_test_executor()

        result = self.run_sync(executor.create_value(value))

        self.assertIsInstance(result,
                              federating_executor.FederatingExecutorValue)
        self.assertEqual(result.type_signature.compact_representation(),
                         type_signature.compact_representation())

    # pyformat: disable
    @parameterized.named_parameters([
        ('computation_intrinsic',
         *executor_test_utils.create_dummy_computation_intrinsic()),
        ('computation_lambda',
         *executor_test_utils.create_dummy_computation_lambda_empty()),
        ('computation_tensorflow',
         *executor_test_utils.create_dummy_computation_tensorflow_empty()),
    ])
    # pyformat: enable
    def test_returns_value_with_computation_impl(self, proto, type_signature):
        executor = create_test_executor()
        value = computation_impl.ComputationImpl(
            proto, context_stack_impl.context_stack)

        result = self.run_sync(executor.create_value(value, type_signature))

        self.assertIsInstance(result,
                              federating_executor.FederatingExecutorValue)
        self.assertEqual(result.type_signature.compact_representation(),
                         type_signature.compact_representation())

    # pyformat: disable
    @parameterized.named_parameters([
        ('federated_type_at_clients',
         *executor_test_utils.create_dummy_value_at_clients()),
        ('federated_type_at_clients_all_equal',
         *executor_test_utils.create_dummy_value_at_clients_all_equal()),
        ('federated_type_at_server',
         *executor_test_utils.create_dummy_value_at_server()),
        ('unplaced_type', *executor_test_utils.create_dummy_value_unplaced()),
    ] + get_named_parameters_for_supported_intrinsics())
    # pyformat: enable
    def test_raises_type_error_with_value_only(self, value, type_signature):
        del type_signature  # Unused.
        executor = create_test_executor()

        with self.assertRaises(TypeError):
            self.run_sync(executor.create_value(value))

    # pyformat: disable
    @parameterized.named_parameters([
        ('placement_literal',
         *executor_test_utils.create_dummy_placement_literal()),
        ('computation_placement',
         *executor_test_utils.create_dummy_computation_placement()),
        ('federated_type_at_clients',
         *executor_test_utils.create_dummy_value_at_clients()),
        ('federated_type_at_clients_all_equal',
         *executor_test_utils.create_dummy_value_at_clients_all_equal()),
        ('federated_type_at_server',
         *executor_test_utils.create_dummy_value_at_server()),
        ('unplaced_type', *executor_test_utils.create_dummy_value_unplaced()),
    ] + get_named_parameters_for_supported_intrinsics())
    # pyformat: enable
    def test_raises_type_error_with_value_and_bad_type(self, value,
                                                       type_signature):
        del type_signature  # Unused.
        executor = create_test_executor()
        bad_type_signature = computation_types.TensorType(tf.string)

        with self.assertRaises(TypeError):
            self.run_sync(executor.create_value(value, bad_type_signature))

    # pyformat: disable
    @parameterized.named_parameters([
        ('computation_call',
         *executor_test_utils.create_dummy_computation_call()),
        ('computation_intrinsic',
         *executor_test_utils.create_dummy_computation_intrinsic()),
        ('computation_lambda',
         *executor_test_utils.create_dummy_computation_lambda_empty()),
        ('computation_selection',
         *executor_test_utils.create_dummy_computation_selection()),
        ('computation_tensorflow',
         *executor_test_utils.create_dummy_computation_tensorflow_empty()),
        ('computation_tuple',
         *executor_test_utils.create_dummy_computation_tuple()),
    ])
    # pyformat: enable
    def test_raises_type_error_with_value_and_bad_type_skipped(
            self, value, type_signature):
        del type_signature  # Unused.
        self.skipTest(
            'TODO(b/152449402): `FederatingExecutor.create_value` method should '
            'fail if it is passed a computation and an incompatible type.')
        executor = create_test_executor()
        bad_type_signature = computation_types.TensorType(tf.string)

        with self.assertRaises(TypeError):
            self.run_sync(executor.create_value(value, bad_type_signature))

    # pyformat: disable
    @parameterized.named_parameters([
        ('computation_reference',
         *executor_test_utils.create_dummy_computation_reference()),
        ('function_type', lambda: 10, type_factory.unary_op(tf.int32)),
    ])
    # pyformat: enable
    def test_raises_value_error_with_value(self, value, type_signature):
        executor = create_test_executor()

        with self.assertRaises(ValueError):
            self.run_sync(executor.create_value(value, type_signature))

    def test_raises_value_error_with_unrecognized_computation_intrinsic(self):
        executor = create_test_executor()
        # A `ValueError` will be raised because `create_value` can not recognize the
        # following intrinsic, because it has not been added to the intrinsic
        # registry.
        value = pb.Computation(
            type=type_serialization.serialize_type(tf.int32),
            intrinsic=pb.Intrinsic(uri='unregistered_intrinsic'))
        type_signature = computation_types.TensorType(tf.int32)

        with self.assertRaises(ValueError):
            self.run_sync(executor.create_value(value, type_signature))

    def test_raises_value_error_with_unrecognized_computation_selection(self):
        executor = create_test_executor()
        source, _ = executor_test_utils.create_dummy_computation_tuple()
        type_signature = computation_types.NamedTupleType([])
        # A `ValueError` will be raised because `create_value` can not handle the
        # following `pb.Selection`, because does not set either a name or an index
        # field.
        value = pb.Computation(
            type=type_serialization.serialize_type(type_signature),
            selection=pb.Selection(source=source))

        with self.assertRaises(ValueError):
            self.run_sync(executor.create_value(value, type_signature))

    # pyformat: disable
    @parameterized.named_parameters([
        ('intrinsic_def_federated_broadcast',
         *executor_test_utils.create_dummy_intrinsic_def_federated_broadcast()
         ),
        ('intrinsic_def_federated_eval_at_clients', *executor_test_utils.
         create_dummy_intrinsic_def_federated_eval_at_clients()),
        ('intrinsic_def_federated_map',
         *executor_test_utils.create_dummy_intrinsic_def_federated_map()),
        ('intrinsic_def_federated_map_all_equal', *executor_test_utils.
         create_dummy_intrinsic_def_federated_map_all_equal()),
        ('intrinsic_def_federated_value_at_clients', *executor_test_utils.
         create_dummy_intrinsic_def_federated_value_at_clients()),
        ('federated_type_at_clients_all_equal',
         *executor_test_utils.create_dummy_value_at_clients_all_equal()),
        ('federated_type_at_clients',
         *executor_test_utils.create_dummy_value_at_clients())
    ])
    # pyformat: enable
    def test_raises_value_error_with_no_target_executor_clients(
            self, value, type_signature):
        executor = federating_executor.FederatingExecutor({
            placement_literals.SERVER:
            eager_tf_executor.EagerTFExecutor(),
            None:
            eager_tf_executor.EagerTFExecutor()
        })

        with self.assertRaises(ValueError):
            self.run_sync(executor.create_value(value, type_signature))

    # pyformat: disable
    @parameterized.named_parameters([
        ('intrinsic_def_federated_aggregate',
         *executor_test_utils.create_dummy_intrinsic_def_federated_aggregate()
         ),
        ('intrinsic_def_federated_apply',
         *executor_test_utils.create_dummy_intrinsic_def_federated_apply()),
        ('intrinsic_def_federated_collect',
         *executor_test_utils.create_dummy_intrinsic_def_federated_collect()),
        ('intrinsic_def_federated_eval_at_server', *executor_test_utils.
         create_dummy_intrinsic_def_federated_eval_at_server()),
        ('intrinsic_def_federated_mean',
         *executor_test_utils.create_dummy_intrinsic_def_federated_mean()),
        ('intrinsic_def_federated_sum',
         *executor_test_utils.create_dummy_intrinsic_def_federated_sum()),
        ('intrinsic_def_federated_reduce',
         *executor_test_utils.create_dummy_intrinsic_def_federated_reduce()),
        ('intrinsic_def_federated_value_at_server', *executor_test_utils.
         create_dummy_intrinsic_def_federated_value_at_server()),
        ('intrinsic_def_federated_weighted_mean', *executor_test_utils.
         create_dummy_intrinsic_def_federated_weighted_mean()),
        ('intrinsic_def_federated_zip_at_server', *executor_test_utils.
         create_dummy_intrinsic_def_federated_zip_at_server()),
        ('federated_type_at_server',
         *executor_test_utils.create_dummy_value_at_server()),
    ])
    # pyformat: enable
    def test_raises_value_error_with_no_target_executor_server(
            self, value, type_signature):
        executor = federating_executor.FederatingExecutor({
            placement_literals.CLIENTS:
            eager_tf_executor.EagerTFExecutor(),
            None:
            eager_tf_executor.EagerTFExecutor()
        })
        value, type_signature = executor_test_utils.create_dummy_value_at_server(
        )

        with self.assertRaises(ValueError):
            self.run_sync(executor.create_value(value, type_signature))

    def test_raises_value_error_with_no_target_executor_unplaced(self):
        executor = federating_executor.FederatingExecutor({
            placement_literals.SERVER:
            eager_tf_executor.EagerTFExecutor(),
            placement_literals.CLIENTS:
            eager_tf_executor.EagerTFExecutor(),
        })
        value, type_signature = executor_test_utils.create_dummy_value_unplaced(
        )

        with self.assertRaises(ValueError):
            self.run_sync(executor.create_value(value, type_signature))

    def test_raises_value_error_with_unexpected_federated_type_at_clients(
            self):
        executor = create_test_executor()
        value = [10, 20]
        type_signature = type_factory.at_clients(tf.int32)

        with self.assertRaises(ValueError):
            self.run_sync(executor.create_value(value, type_signature))

    def test_raises_value_error_with_unexpected_federated_type_at_clients_all_equal(
            self):
        executor = create_test_executor()
        value = [10] * 3
        type_signature = type_factory.at_clients(tf.int32, all_equal=True)

        with self.assertRaises(ValueError):
            self.run_sync(executor.create_value(value, type_signature))