def test_create_executor_with_server_device(self, tf_device): tf_devices = tf.config.list_logical_devices(tf_device) server_tf_device = None if not tf_devices else tf_devices[0] unplaced_factory = executor_stacks.UnplacedExecutorFactory( use_caching=False, server_device=server_tf_device) unplaced_executor = unplaced_factory.create_executor() self.assertIsInstance(unplaced_executor, executor_base.Executor)
def test_constructs_executor_factory(self): unplaced_factory = executor_stacks.UnplacedExecutorFactory( use_caching=True) federating_factory = executor_stacks.FederatingExecutorFactory( clients_per_thread=1, unplaced_ex_factory=unplaced_factory) self.assertIsInstance(federating_factory, executor_factory.ExecutorFactory)
def test_raises_on_access_of_nonexistent_sizing_executors(self): unplaced_factory = executor_stacks.UnplacedExecutorFactory( use_caching=True) federating_factory = executor_stacks.FederatingExecutorFactory( clients_per_thread=1, unplaced_ex_factory=unplaced_factory) with self.assertRaisesRegex(ValueError, 'not configured'): _ = federating_factory.sizing_executors
def test_callable_raises_negative_clients(self): unplaced_factory = executor_stacks.UnplacedExecutorFactory(use_caching=True) federating_factory = executor_stacks.FederatingExecutorFactory( clients_per_thread=1, unplaced_ex_factory=unplaced_factory) flat_stack_fn = executor_stacks.create_minimal_length_flat_stack_fn( 2, federating_factory) with self.assertRaises(ValueError): flat_stack_fn({placement_literals.CLIENTS: -1})
def test_returns_singleton_list_for_zero_clients(self): unplaced_factory = executor_stacks.UnplacedExecutorFactory(use_caching=True) federating_factory = executor_stacks.FederatingExecutorFactory( clients_per_thread=1, unplaced_ex_factory=unplaced_factory) flat_stack_fn = executor_stacks.create_minimal_length_flat_stack_fn( 3, federating_factory) executor_list = flat_stack_fn({placement_literals.CLIENTS: 0}) self.assertLen(executor_list, 1)
def test_returns_empty_list_of_sizing_executors_if_configured(self): unplaced_factory = executor_stacks.UnplacedExecutorFactory(use_caching=True) federating_factory = executor_stacks.FederatingExecutorFactory( clients_per_thread=1, unplaced_ex_factory=unplaced_factory, use_sizing=True) sizing_ex_list = federating_factory.sizing_executors self.assertIsInstance(sizing_ex_list, list) self.assertEmpty(sizing_ex_list)
def test_construction_raises_with_max_fanout_one(self): unplaced_factory = executor_stacks.UnplacedExecutorFactory( use_caching=True) federating_factory = executor_stacks.FederatingExecutorFactory( clients_per_thread=1, unplaced_ex_factory=unplaced_factory) with self.assertRaises(ValueError): executor_stacks.ComposingExecutorFactory( max_fanout=1, unplaced_ex_factory=unplaced_factory, federated_stack_factory=federating_factory)
def test_create_executor_raises_mismatched_num_clients(self): unplaced_factory = executor_stacks.UnplacedExecutorFactory(use_caching=True) federating_factory = executor_stacks.FederatingExecutorFactory( num_clients=3, clients_per_thread=1, unplaced_ex_factory=unplaced_factory, use_sizing=True) with self.assertRaisesRegex(ValueError, 'configured to return 3 clients'): federating_factory.create_executor( cardinalities={placement_literals.CLIENTS: 5})
def test_constructs_correct_length_list(self, max_clients_per_stack, num_clients): unplaced_factory = executor_stacks.UnplacedExecutorFactory(use_caching=True) federating_factory = executor_stacks.FederatingExecutorFactory( clients_per_thread=1, unplaced_ex_factory=unplaced_factory) flat_stack_fn = executor_stacks.create_minimal_length_flat_stack_fn( max_clients_per_stack, federating_factory) executor_list = flat_stack_fn({placement_literals.CLIENTS: num_clients}) self.assertLen(executor_list, math.ceil(num_clients / max_clients_per_stack))
def test_create_executor_with_client_mgpu(self, tf_device): tf_devices = tf.config.list_logical_devices(tf_device) server_tf_device = None if not tf_devices else tf_devices[0] gpu_devices = tf.config.list_logical_devices('GPU') unplaced_factory = executor_stacks.UnplacedExecutorFactory( use_caching=True, server_device=server_tf_device, client_devices=gpu_devices) unplaced_executor = unplaced_factory.create_executor() self.assertIsInstance(unplaced_executor, executor_base.Executor)
def test_constructs_executor_factory_with_child_executors(self): unplaced_factory = executor_stacks.UnplacedExecutorFactory(use_caching=True) child_executors = [unplaced_factory.create_executor() for _ in range(5)] flat_stack_fn = lambda _: child_executors composing_ex_factory = executor_stacks.ComposingExecutorFactory( max_fanout=2, unplaced_ex_factory=unplaced_factory, flat_stack_fn=flat_stack_fn, ) self.assertIsInstance(composing_ex_factory, executor_factory.ExecutorFactory)
def test_constructs_executor_factory_with_federated_factory(self): unplaced_factory = executor_stacks.UnplacedExecutorFactory( use_caching=True) federating_factory = executor_stacks.FederatingExecutorFactory( clients_per_thread=1, unplaced_ex_factory=unplaced_factory) composing_ex_factory = executor_stacks.ComposingExecutorFactory( max_fanout=2, unplaced_ex_factory=unplaced_factory, federated_stack_factory=federating_factory) self.assertIsInstance(composing_ex_factory, executor_factory.ExecutorFactory)
def test_constructs_as_many_sizing_executors_as_client_executors(self): unplaced_factory = executor_stacks.UnplacedExecutorFactory(use_caching=True) federating_factory = executor_stacks.FederatingExecutorFactory( clients_per_thread=2, unplaced_ex_factory=unplaced_factory, use_sizing=True) federating_factory.create_executor( cardinalities={placement_literals.CLIENTS: 10}) sizing_ex_list = federating_factory.sizing_executors self.assertIsInstance(sizing_ex_list, list) self.assertLen(sizing_ex_list, 5)
def test_creates_executor_with_large_fanout(self): unplaced_factory = executor_stacks.UnplacedExecutorFactory( use_caching=True) federating_factory = executor_stacks.FederatingExecutorFactory( clients_per_thread=1, unplaced_ex_factory=unplaced_factory) composing_ex_factory = executor_stacks.ComposingExecutorFactory( max_fanout=200, unplaced_ex_factory=unplaced_factory, federated_stack_factory=federating_factory) ex = composing_ex_factory.create_executor( {placement_literals.CLIENTS: 10}) self.assertIsInstance(ex, executor_base.Executor)
def test_creates_executor_with_small_fanout(self): unplaced_factory = executor_stacks.UnplacedExecutorFactory(use_caching=True) federating_factory = executor_stacks.FederatingExecutorFactory( clients_per_thread=1, unplaced_ex_factory=unplaced_factory) flat_stack_fn = executor_stacks.create_minimal_length_flat_stack_fn( 2, federating_factory) composing_ex_factory = executor_stacks.ComposingExecutorFactory( max_fanout=2, unplaced_ex_factory=unplaced_factory, flat_stack_fn=flat_stack_fn) ex = composing_ex_factory.create_executor({placement_literals.CLIENTS: 10}) self.assertIsInstance(ex, executor_base.Executor)
def test_reinvocation_of_create_executor_extends_sizing_executors(self): unplaced_factory = executor_stacks.UnplacedExecutorFactory(use_caching=True) federating_factory = executor_stacks.FederatingExecutorFactory( clients_per_thread=2, unplaced_ex_factory=unplaced_factory, use_sizing=True) federating_factory.create_executor( cardinalities={placement_literals.CLIENTS: 10}) federating_factory.create_executor( cardinalities={placement_literals.CLIENTS: 12}) sizing_ex_list = federating_factory.sizing_executors self.assertIsInstance(sizing_ex_list, list) self.assertLen(sizing_ex_list, 5 + 6)
def test_construction_raises_with_both_child_executors_and_federated_factory( self): unplaced_factory = executor_stacks.UnplacedExecutorFactory( use_caching=True) federating_factory = executor_stacks.FederatingExecutorFactory( clients_per_thread=1, unplaced_ex_factory=unplaced_factory) child_executors = [ unplaced_factory.create_executor() for _ in range(5) ] with self.assertRaisesRegex(ValueError, 'Exactly one'): executor_stacks.ComposingExecutorFactory( max_fanout=2, unplaced_ex_factory=unplaced_factory, federated_stack_factory=federating_factory, child_executors=child_executors, )
def test_executor_factory( num_clients: Optional[int] = None, clients_per_thread: int = 1, *, default_num_clients: int = 0) -> executor_factory.ExecutorFactory: """Constructs a test execution stack to execute local computations. This factory is similar to `tff.framework.thread_debugging_executor_factory` except that it is configured to delegate the implementation of federated intrinsics to a `federated_strategy.TestFederatedStrategy`. This execution stack can be useful when testing federated algorithms that require unique implementations for the intrinsics provided by TFF. Args: num_clients: (Deprecated) The number of clients. If specified, the executor factory returned by `local_executor_factory` will be configured to have exactly `num_clients` clients. If unspecified (`None`), then the function returned will attempt to infer cardinalities of all placements for which it is passed values. clients_per_thread: Integer number of clients for each of TFF's threads to run in sequence. Increasing `clients_per_thread` therefore reduces the concurrency of the TFF runtime, which can be useful if client work is very lightweight or models are very large and multiple copies cannot fit in memory. default_num_clients: The number of clients to run by default if cardinality cannot be inferred from arguments. Returns: An `executor_factory.ExecutorFactory`. """ unplaced_ex_factory = executor_stacks.UnplacedExecutorFactory( use_caching=False, can_resolve_references=True, ) num_clients = executor_stacks.normalize_num_clients_and_default_num_clients( num_clients, default_num_clients) federating_executor_factory = executor_stacks.FederatingExecutorFactory( clients_per_thread=clients_per_thread, unplaced_ex_factory=unplaced_ex_factory, default_num_clients=default_num_clients, use_sizing=False, federated_strategy_factory=federated_strategy.TestFederatedStrategy .factory) return executor_stacks.ResourceManagingExecutorFactory( federating_executor_factory.create_executor)
def test_executor_with_small_fanout_calls_correct_number_of_composing_strategies( self, composing_strategy_mock): num_clients = 10 max_fanout = 2 clients_per_thread = 1 unplaced_factory = executor_stacks.UnplacedExecutorFactory( use_caching=True) federating_factory = executor_stacks.FederatingExecutorFactory( clients_per_thread=clients_per_thread, unplaced_ex_factory=unplaced_factory) composing_ex_factory = executor_stacks.ComposingExecutorFactory( max_fanout=max_fanout, unplaced_ex_factory=unplaced_factory, federated_stack_factory=federating_factory) composing_ex_factory.create_executor( {placement_literals.CLIENTS: num_clients}) args_list = composing_strategy_mock.call_args_list # 5 at the first layer, 1 at the second self.assertLen(args_list, 6)
def test_create_executor_with_client_devices(self, tf_device): tf_devices = tf.config.list_logical_devices(tf_device) unplaced_factory = executor_stacks.UnplacedExecutorFactory( use_caching=False, client_devices=tf_devices) unplaced_executor = unplaced_factory.create_executor() self.assertIsInstance(unplaced_executor, executor_base.Executor)
def test_create_executor_raises_with_nonempty_cardinalitites(self): unplaced_factory = executor_stacks.UnplacedExecutorFactory( use_caching=True) with self.assertRaises(ValueError): unplaced_factory.create_executor( cardinalities={placements.SERVER: 1})
def test_create_executor_returns_executor(self): unplaced_factory = executor_stacks.UnplacedExecutorFactory( use_caching=True) unplaced_executor = unplaced_factory.create_executor(cardinalities={}) self.assertIsInstance(unplaced_executor, executor_base.Executor)
def test_constructs_executor_factory_without_caching(self): unplaced_factory_no_caching = executor_stacks.UnplacedExecutorFactory( use_caching=False) self.assertIsInstance(unplaced_factory_no_caching, executor_factory.ExecutorFactory)
def test_constructs_executor_factory(self): unplaced_factory = executor_stacks.UnplacedExecutorFactory( use_caching=True) self.assertIsInstance(unplaced_factory, executor_factory.ExecutorFactory)