flwr-nightly 1.5.0.dev20230608__py3-none-any.whl → 1.5.0.dev20230615__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. flwr/client/app.py +0 -3
  2. flwr/client/client.py +0 -4
  3. flwr/client/dpfedavg_numpy_client.py +97 -0
  4. flwr/client/grpc_rere_client/connection.py +0 -2
  5. flwr/client/message_handler/task_handler.py +0 -1
  6. flwr/client/numpy_client.py +1 -1
  7. flwr/client/rest_client/connection.py +0 -3
  8. flwr/common/address.py +1 -1
  9. flwr/common/dp.py +1 -2
  10. flwr/common/grpc.py +0 -1
  11. flwr/common/logger.py +0 -1
  12. flwr/common/serde.py +0 -1
  13. flwr/driver/driver.py +0 -3
  14. flwr/driver/driver_client_manager.py +9 -0
  15. flwr/driver/driver_client_proxy.py +1 -1
  16. flwr/proto/task_pb2.py +94 -6
  17. flwr/proto/task_pb2.pyi +137 -2
  18. flwr/server/app.py +4 -11
  19. flwr/server/client_manager.py +7 -0
  20. flwr/server/client_proxy.py +1 -1
  21. flwr/server/criterion.py +1 -2
  22. flwr/server/fleet/grpc_bidi/flower_service_servicer.py +3 -1
  23. flwr/server/fleet/grpc_bidi/grpc_bridge.py +1 -2
  24. flwr/server/fleet/grpc_bidi/grpc_client_proxy.py +1 -1
  25. flwr/server/fleet/grpc_bidi/grpc_server.py +1 -3
  26. flwr/server/fleet/grpc_bidi/ins_scheduler.py +0 -1
  27. flwr/server/fleet/message_handler/message_handler.py +0 -2
  28. flwr/server/history.py +15 -0
  29. flwr/server/server.py +0 -5
  30. flwr/server/state/in_memory_state.py +8 -5
  31. flwr/server/state/sqlite_state.py +4 -5
  32. flwr/server/state/state.py +2 -2
  33. flwr/server/state/state_factory.py +0 -1
  34. flwr/server/strategy/dpfedavg_adaptive.py +1 -1
  35. flwr/server/strategy/dpfedavg_fixed.py +46 -2
  36. flwr/server/strategy/fedadagrad.py +4 -4
  37. flwr/server/strategy/fedadam.py +3 -4
  38. flwr/server/strategy/fedavg.py +1 -2
  39. flwr/server/strategy/fedavg_android.py +1 -2
  40. flwr/server/strategy/fedopt.py +1 -2
  41. flwr/server/strategy/fedxgb_nn_avg.py +2 -2
  42. flwr/server/strategy/fedyogi.py +3 -4
  43. flwr/server/strategy/qfedavg.py +1 -2
  44. flwr/server/utils/tensorboard.py +2 -4
  45. flwr/server/utils/validator.py +0 -1
  46. flwr/simulation/app.py +4 -5
  47. flwr/simulation/ray_transport/ray_client_proxy.py +13 -13
  48. {flwr_nightly-1.5.0.dev20230608.dist-info → flwr_nightly-1.5.0.dev20230615.dist-info}/METADATA +1 -1
  49. {flwr_nightly-1.5.0.dev20230608.dist-info → flwr_nightly-1.5.0.dev20230615.dist-info}/RECORD +52 -52
  50. {flwr_nightly-1.5.0.dev20230608.dist-info → flwr_nightly-1.5.0.dev20230615.dist-info}/LICENSE +0 -0
  51. {flwr_nightly-1.5.0.dev20230608.dist-info → flwr_nightly-1.5.0.dev20230615.dist-info}/WHEEL +0 -0
  52. {flwr_nightly-1.5.0.dev20230608.dist-info → flwr_nightly-1.5.0.dev20230615.dist-info}/entry_points.txt +0 -0
flwr/server/app.py CHANGED
@@ -66,8 +66,8 @@ DATABASE = ":flwr-in-memory-state:"
66
66
  class ServerConfig:
67
67
  """Flower server config.
68
68
 
69
- All attributes have default values which allows users to configure
70
- just the ones they care about.
69
+ All attributes have default values which allows users to configure just the ones
70
+ they care about.
71
71
  """
72
72
 
73
73
  num_rounds: int = 1
@@ -236,7 +236,6 @@ def run_fl(
236
236
 
237
237
  def run_driver_api() -> None:
238
238
  """Run Flower server (Driver API)."""
239
-
240
239
  log(INFO, "Starting Flower server (Driver API)")
241
240
  event(EventType.RUN_DRIVER_API_ENTER)
242
241
  args = _parse_args_driver().parse_args()
@@ -270,7 +269,6 @@ def run_driver_api() -> None:
270
269
 
271
270
  def run_fleet_api() -> None:
272
271
  """Run Flower server (Fleet API)."""
273
-
274
272
  log(INFO, "Starting Flower server (Fleet API)")
275
273
  event(EventType.RUN_FLEET_API_ENTER)
276
274
  args = _parse_args_fleet().parse_args()
@@ -352,7 +350,6 @@ def run_fleet_api() -> None:
352
350
  # pylint: disable=too-many-branches
353
351
  def run_server() -> None:
354
352
  """Run Flower server (Driver API and Fleet API)."""
355
-
356
353
  log(INFO, "Starting Flower server")
357
354
  event(EventType.RUN_SERVER_ENTER)
358
355
  args = _parse_args_server().parse_args()
@@ -462,10 +459,9 @@ def _register_exit_handlers(
462
459
  ) -> None:
463
460
  """Exit handler to be registered with signal.signal.
464
461
 
465
- When called will reset signal handler to original signal handler
466
- from default_handlers.
462
+ When called will reset signal handler to original signal handler from
463
+ default_handlers.
467
464
  """
468
-
469
465
  # Reset to default handler
470
466
  signal(signalnum, default_handlers[signalnum])
471
467
 
@@ -498,7 +494,6 @@ def _run_driver_api_grpc(
498
494
  state_factory: StateFactory,
499
495
  ) -> grpc.Server:
500
496
  """Run Driver API (gRPC, request-response)."""
501
-
502
497
  # Create Driver API gRPC server
503
498
  driver_servicer: grpc.Server = DriverServicer(
504
499
  state_factory=state_factory,
@@ -522,7 +517,6 @@ def _run_fleet_api_grpc_bidi(
522
517
  state_factory: StateFactory,
523
518
  ) -> grpc.Server:
524
519
  """Run Fleet API (gRPC, bidirectional streaming)."""
525
-
526
520
  # DriverClientManager
527
521
  driver_client_manager = DriverClientManager(
528
522
  state_factory=state_factory,
@@ -551,7 +545,6 @@ def _run_fleet_api_grpc_rere(
551
545
  state_factory: StateFactory,
552
546
  ) -> grpc.Server:
553
547
  """Run Fleet API (gRPC, request-response)."""
554
-
555
548
  # Create Fleet API gRPC server
556
549
  fleet_servicer = FleetServicer(
557
550
  state=state_factory.state(),
@@ -92,6 +92,13 @@ class SimpleClientManager(ClientManager):
92
92
  self._cv = threading.Condition()
93
93
 
94
94
  def __len__(self) -> int:
95
+ """Return the number of available clients.
96
+
97
+ Returns
98
+ -------
99
+ num_available : int
100
+ The number of currently available clients.
101
+ """
95
102
  return len(self.clients)
96
103
 
97
104
  def num_available(self) -> int:
@@ -48,7 +48,7 @@ class ClientProxy(ABC):
48
48
  ins: GetPropertiesIns,
49
49
  timeout: Optional[float],
50
50
  ) -> GetPropertiesRes:
51
- """Returns the client's properties."""
51
+ """Return the client's properties."""
52
52
 
53
53
  @abstractmethod
54
54
  def get_parameters(
flwr/server/criterion.py CHANGED
@@ -21,8 +21,7 @@ from .client_proxy import ClientProxy
21
21
 
22
22
 
23
23
  class Criterion(ABC):
24
- """Abstract class which allows subclasses to implement criterion
25
- sampling."""
24
+ """Abstract class which allows subclasses to implement criterion sampling."""
26
25
 
27
26
  @abstractmethod
28
27
  def select(self, client: ClientProxy) -> bool:
@@ -78,7 +78,9 @@ class FlowerServiceServicer(transport_pb2_grpc.FlowerServiceServicer):
78
78
  request_iterator: Iterator[ClientMessage],
79
79
  context: grpc.ServicerContext,
80
80
  ) -> Iterator[ServerMessage]:
81
- """Invoked by each gRPC client which participates in the network.
81
+ """Facilitate bi-directional streaming of messages between server and client.
82
+
83
+ Invoked by each gRPC client which participates in the network.
82
84
 
83
85
  Protocol:
84
86
  - The first message is sent from the server to the client
@@ -80,8 +80,7 @@ class GrpcBridge:
80
80
  def _transition(self, next_status: Status) -> None:
81
81
  """Validate status transition and set next status.
82
82
 
83
- The caller of the transition method will have to aquire
84
- conditional variable.
83
+ The caller of the transition method will have to aquire conditional variable.
85
84
  """
86
85
  if next_status == Status.CLOSED:
87
86
  self._status = next_status
@@ -40,7 +40,7 @@ class GrpcClientProxy(ClientProxy):
40
40
  ins: common.GetPropertiesIns,
41
41
  timeout: Optional[float],
42
42
  ) -> common.GetPropertiesRes:
43
- """Requests client's set of internal properties."""
43
+ """Request client's set of internal properties."""
44
44
  get_properties_msg = serde.get_properties_ins_to_proto(ins)
45
45
  res_wrapper: ResWrapper = self.bridge.request(
46
46
  ins_wrapper=InsWrapper(
@@ -130,7 +130,6 @@ def start_grpc_server( # pylint: disable=too-many-arguments
130
130
  >>> ),
131
131
  >>> )
132
132
  """
133
-
134
133
  servicer = FlowerServiceServicer(client_manager)
135
134
  add_servicer_to_server_fn = add_FlowerServiceServicer_to_server
136
135
 
@@ -160,7 +159,7 @@ def generic_create_grpc_server( # pylint: disable=too-many-arguments
160
159
  keepalive_time_ms: int = 210000,
161
160
  certificates: Optional[Tuple[bytes, bytes, bytes]] = None,
162
161
  ) -> grpc.Server:
163
- """Generic function to create a gRPC server with a single servicer.
162
+ """Create a gRPC server with a single servicer.
164
163
 
165
164
  Parameters
166
165
  ----------
@@ -210,7 +209,6 @@ def generic_create_grpc_server( # pylint: disable=too-many-arguments
210
209
  server : grpc.Server
211
210
  A non-running instance of a gRPC server.
212
211
  """
213
-
214
212
  # Deconstruct tuple into servicer and function
215
213
  servicer, add_servicer_to_server_fn = servicer_and_add_fn
216
214
 
@@ -123,7 +123,6 @@ def _call_client_proxy(
123
123
  client_proxy: ClientProxy, server_message: ServerMessage, timeout: Optional[float]
124
124
  ) -> ClientMessage:
125
125
  """."""
126
-
127
126
  # pylint: disable=too-many-locals
128
127
 
129
128
  field = server_message.WhichOneof("msg")
@@ -31,7 +31,6 @@ from flwr.server.state import State
31
31
 
32
32
  def pull_task_ins(request: PullTaskInsRequest, state: State) -> PullTaskInsResponse:
33
33
  """Pull TaskIns handler."""
34
-
35
34
  # Get node_id if client node is not anonymous
36
35
  node = request.node # pylint: disable=no-member
37
36
  node_id: Optional[int] = None if node.anonymous else node.node_id
@@ -48,7 +47,6 @@ def pull_task_ins(request: PullTaskInsRequest, state: State) -> PullTaskInsRespo
48
47
 
49
48
  def push_task_res(request: PushTaskResRequest, state: State) -> PushTaskResResponse:
50
49
  """Push TaskRes handler."""
51
-
52
50
  # pylint: disable=no-member
53
51
  task_res: TaskRes = request.task_res_list[0]
54
52
  # pylint: enable=no-member
flwr/server/history.py CHANGED
@@ -73,6 +73,21 @@ class History:
73
73
  self.metrics_centralized[key].append((server_round, metrics[key]))
74
74
 
75
75
  def __repr__(self) -> str:
76
+ """Create a representation of History.
77
+
78
+ The representation consists of the following data (for each round) if present:
79
+
80
+ * distributed loss.
81
+ * centralized loss.
82
+ * distributed training metrics.
83
+ * distributed evaluation metrics.
84
+ * centralized metrics.
85
+
86
+ Returns
87
+ -------
88
+ representation : str
89
+ The string representation of the history object.
90
+ """
76
91
  rep = ""
77
92
  if self.losses_distributed:
78
93
  rep += "History (loss, distributed):\n" + reduce(
flwr/server/server.py CHANGED
@@ -161,7 +161,6 @@ class Server:
161
161
  Tuple[Optional[float], Dict[str, Scalar], EvaluateResultsAndFailures]
162
162
  ]:
163
163
  """Validate current global model on a number of clients."""
164
-
165
164
  # Get clients and their respective instructions from strategy
166
165
  client_instructions = self.strategy.configure_evaluate(
167
166
  server_round=server_round,
@@ -210,7 +209,6 @@ class Server:
210
209
  Tuple[Optional[Parameters], Dict[str, Scalar], FitResultsAndFailures]
211
210
  ]:
212
211
  """Perform a single round of federated averaging."""
213
-
214
212
  # Get clients and their respective instructions from strategy
215
213
  client_instructions = self.strategy.configure_fit(
216
214
  server_round=server_round,
@@ -266,7 +264,6 @@ class Server:
266
264
 
267
265
  def _get_initial_parameters(self, timeout: Optional[float]) -> Parameters:
268
266
  """Get initial parameters from one of the available clients."""
269
-
270
267
  # Server-side parameter initialization
271
268
  parameters: Optional[Parameters] = self.strategy.initialize_parameters(
272
269
  client_manager=self._client_manager
@@ -366,7 +363,6 @@ def _handle_finished_future_after_fit(
366
363
  failures: List[Union[Tuple[ClientProxy, FitRes], BaseException]],
367
364
  ) -> None:
368
365
  """Convert finished future into either a result or a failure."""
369
-
370
366
  # Check if there was an exception
371
367
  failure = future.exception()
372
368
  if failure is not None:
@@ -428,7 +424,6 @@ def _handle_finished_future_after_evaluate(
428
424
  failures: List[Union[Tuple[ClientProxy, EvaluateRes], BaseException]],
429
425
  ) -> None:
430
426
  """Convert finished future into either a result or a failure."""
431
-
432
427
  # Check if there was an exception
433
428
  failure = future.exception()
434
429
  if failure is not None:
@@ -36,7 +36,6 @@ class InMemoryState(State):
36
36
 
37
37
  def store_task_ins(self, task_ins: TaskIns) -> Optional[UUID]:
38
38
  """Store one TaskIns."""
39
-
40
39
  # Validate task
41
40
  errors = validate_task_ins_or_res(task_ins)
42
41
  if any(errors):
@@ -61,7 +60,6 @@ class InMemoryState(State):
61
60
  self, node_id: Optional[int], limit: Optional[int]
62
61
  ) -> List[TaskIns]:
63
62
  """Get all TaskIns that have not been delivered yet."""
64
-
65
63
  if limit is not None and limit < 1:
66
64
  raise AssertionError("`limit` must be >= 1")
67
65
 
@@ -94,7 +92,6 @@ class InMemoryState(State):
94
92
 
95
93
  def store_task_res(self, task_res: TaskRes) -> Optional[UUID]:
96
94
  """Store one TaskRes."""
97
-
98
95
  # Validate task
99
96
  errors = validate_task_ins_or_res(task_res)
100
97
  if any(errors):
@@ -117,7 +114,6 @@ class InMemoryState(State):
117
114
 
118
115
  def get_task_res(self, task_ids: Set[UUID], limit: Optional[int]) -> List[TaskRes]:
119
116
  """Get all TaskRes that have not been delivered yet."""
120
-
121
117
  if limit is not None and limit < 1:
122
118
  raise AssertionError("`limit` must be >= 1")
123
119
 
@@ -142,7 +138,6 @@ class InMemoryState(State):
142
138
 
143
139
  def delete_tasks(self, task_ids: Set[UUID]) -> None:
144
140
  """Delete all delivered TaskIns/TaskRes pairs."""
145
-
146
141
  task_ins_to_be_deleted: Set[UUID] = set()
147
142
  task_res_to_be_deleted: Set[UUID] = set()
148
143
 
@@ -163,9 +158,17 @@ class InMemoryState(State):
163
158
  del self.task_res_store[task_id]
164
159
 
165
160
  def num_task_ins(self) -> int:
161
+ """Calculate the number of task_ins in store.
162
+
163
+ This includes delivered but not yet deleted task_ins.
164
+ """
166
165
  return len(self.task_ins_store)
167
166
 
168
167
  def num_task_res(self) -> int:
168
+ """Calculate the number of task_res in store.
169
+
170
+ This includes delivered but not yet deleted task_res.
171
+ """
169
172
  return len(self.task_res_store)
170
173
 
171
174
  def register_node(self, node_id: int) -> None:
@@ -390,7 +390,7 @@ class SqliteState(State):
390
390
  return result
391
391
 
392
392
  def num_task_ins(self) -> int:
393
- """Number of task_ins in store.
393
+ """Calculate the number of task_ins in store.
394
394
 
395
395
  This includes delivered but not yet deleted task_ins.
396
396
  """
@@ -401,7 +401,7 @@ class SqliteState(State):
401
401
  return num
402
402
 
403
403
  def num_task_res(self) -> int:
404
- """Number of task_res in store.
404
+ """Calculate the number of task_res in store.
405
405
 
406
406
  This includes delivered but not yet deleted task_res.
407
407
  """
@@ -469,10 +469,9 @@ def dict_factory(
469
469
  cursor: sqlite3.Cursor,
470
470
  row: sqlite3.Row,
471
471
  ) -> Dict[str, Any]:
472
- """Used to turn SQLite results into dicts.
472
+ """Turn SQLite results into dicts.
473
473
 
474
- Less efficent for retrival of large amounts of data but easier to
475
- use.
474
+ Less efficent for retrival of large amounts of data but easier to use.
476
475
  """
477
476
  fields = [column[0] for column in cursor.description]
478
477
  return dict(zip(fields, row))
@@ -109,14 +109,14 @@ class State(abc.ABC):
109
109
 
110
110
  @abc.abstractmethod
111
111
  def num_task_ins(self) -> int:
112
- """Number of task_ins in store.
112
+ """Calculate the number of task_ins in store.
113
113
 
114
114
  This includes delivered but not yet deleted task_ins.
115
115
  """
116
116
 
117
117
  @abc.abstractmethod
118
118
  def num_task_res(self) -> int:
119
- """Number of task_res in store.
119
+ """Calculate the number of task_res in store.
120
120
 
121
121
  This includes delivered but not yet deleted task_res.
122
122
  """
@@ -34,7 +34,6 @@ class StateFactory:
34
34
 
35
35
  def state(self) -> State:
36
36
  """Return a State instance and create it, if necessary."""
37
-
38
37
  # InMemoryState
39
38
  if self.database == ":flwr-in-memory-state:":
40
39
  if self.state_instance is None:
@@ -74,7 +74,6 @@ class DPFedAvgAdaptive(DPFedAvgFixed):
74
74
  self, server_round: int, parameters: Parameters, client_manager: ClientManager
75
75
  ) -> List[Tuple[ClientProxy, FitIns]]:
76
76
  """Configure the next round of training."""
77
-
78
77
  additional_config = {"dpfedavg_adaptive_clip_enabled": True}
79
78
 
80
79
  client_instructions = super().configure_fit(
@@ -114,6 +113,7 @@ class DPFedAvgAdaptive(DPFedAvgFixed):
114
113
  results: List[Tuple[ClientProxy, FitRes]],
115
114
  failures: List[Union[Tuple[ClientProxy, FitRes], BaseException]],
116
115
  ) -> Tuple[Optional[Parameters], Dict[str, Scalar]]:
116
+ """Aggregate training results as in DPFedAvgFixed and update clip norms."""
117
117
  if failures:
118
118
  return None, {}
119
119
  new_global_model = super().aggregate_fit(server_round, results, failures)
@@ -67,13 +67,34 @@ class DPFedAvgFixed(Strategy):
67
67
  def initialize_parameters(
68
68
  self, client_manager: ClientManager
69
69
  ) -> Optional[Parameters]:
70
+ """Initialize global model parameters using given strategy."""
70
71
  return self.strategy.initialize_parameters(client_manager)
71
72
 
72
73
  def configure_fit(
73
74
  self, server_round: int, parameters: Parameters, client_manager: ClientManager
74
75
  ) -> List[Tuple[ClientProxy, FitIns]]:
75
- """Configure the next round of training."""
76
-
76
+ """Configure the next round of training incorporating Differential Privacy (DP).
77
+
78
+ Configuration of the next training round includes information related to DP,
79
+ such as clip norm and noise stddev.
80
+
81
+ Parameters
82
+ ----------
83
+ server_round : int
84
+ The current round of federated learning.
85
+ parameters : Parameters
86
+ The current (global) model parameters.
87
+ client_manager : ClientManager
88
+ The client manager which holds all currently connected clients.
89
+
90
+ Returns
91
+ -------
92
+ fit_configuration : List[Tuple[ClientProxy, FitIns]]
93
+ A list of tuples. Each tuple in the list identifies a `ClientProxy` and the
94
+ `FitIns` for this particular `ClientProxy`. If a particular `ClientProxy`
95
+ is not included in this list, it means that this `ClientProxy`
96
+ will not participate in the next round of federated learning.
97
+ """
77
98
  additional_config = {"dpfedavg_clip_norm": self.clip_norm}
78
99
  if not self.server_side_noising:
79
100
  additional_config[
@@ -92,6 +113,26 @@ class DPFedAvgFixed(Strategy):
92
113
  def configure_evaluate(
93
114
  self, server_round: int, parameters: Parameters, client_manager: ClientManager
94
115
  ) -> List[Tuple[ClientProxy, EvaluateIns]]:
116
+ """Configure the next round of evaluation using the specified strategy.
117
+
118
+ Parameters
119
+ ----------
120
+ server_round : int
121
+ The current round of federated learning.
122
+ parameters : Parameters
123
+ The current (global) model parameters.
124
+ client_manager : ClientManager
125
+ The client manager which holds all currently connected clients.
126
+
127
+ Returns
128
+ -------
129
+ evaluate_configuration : List[Tuple[ClientProxy, EvaluateIns]]
130
+ A list of tuples. Each tuple in the list identifies a `ClientProxy` and the
131
+ `EvaluateIns` for this particular `ClientProxy`. If a particular
132
+ `ClientProxy` is not included in this list, it means that this
133
+ `ClientProxy` will not participate in the next round of federated
134
+ evaluation.
135
+ """
95
136
  return self.strategy.configure_evaluate(
96
137
  server_round, parameters, client_manager
97
138
  )
@@ -102,6 +143,7 @@ class DPFedAvgFixed(Strategy):
102
143
  results: List[Tuple[ClientProxy, FitRes]],
103
144
  failures: List[Union[Tuple[ClientProxy, FitRes], BaseException]],
104
145
  ) -> Tuple[Optional[Parameters], Dict[str, Scalar]]:
146
+ """Aggregate training results using unweighted aggregation."""
105
147
  if failures:
106
148
  return None, {}
107
149
  # Forcing unweighted aggregation, as in https://arxiv.org/abs/1905.03871.
@@ -122,9 +164,11 @@ class DPFedAvgFixed(Strategy):
122
164
  results: List[Tuple[ClientProxy, EvaluateRes]],
123
165
  failures: List[Union[Tuple[ClientProxy, EvaluateRes], BaseException]],
124
166
  ) -> Tuple[Optional[float], Dict[str, Scalar]]:
167
+ """Aggregate evaluation losses using the given strategy."""
125
168
  return self.strategy.aggregate_evaluate(server_round, results, failures)
126
169
 
127
170
  def evaluate(
128
171
  self, server_round: int, parameters: Parameters
129
172
  ) -> Optional[Tuple[float, Dict[str, Scalar]]]:
173
+ """Evaluate model parameters using an evaluation function from the strategy."""
130
174
  return self.strategy.evaluate(server_round, parameters)
@@ -12,8 +12,8 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
  # ==============================================================================
15
- """Adaptive Federated Optimization using Adagrad (FedAdagrad) [Reddi et al.,
16
- 2020] strategy.
15
+ """Adaptive Federated Optimization using Adagrad (FedAdagrad) [Reddi et al., 2020]
16
+ strategy.
17
17
 
18
18
  Paper: arxiv.org/abs/2003.00295
19
19
  """
@@ -39,8 +39,8 @@ from .fedopt import FedOpt
39
39
 
40
40
  # flake8: noqa: E501
41
41
  class FedAdagrad(FedOpt):
42
- """Adaptive Federated Optimization using Adagrad (FedAdagrad) [Reddi et
43
- al., 2020] strategy.
42
+ """Adaptive Federated Optimization using Adagrad (FedAdagrad) [Reddi et al., 2020]
43
+ strategy.
44
44
 
45
45
  Paper: https://arxiv.org/abs/2003.00295
46
46
  """
@@ -12,8 +12,7 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
  # ==============================================================================
15
- """Adaptive Federated Optimization using Adam (FedAdam) [Reddi et al., 2020]
16
- strategy.
15
+ """Adaptive Federated Optimization using Adam (FedAdam) [Reddi et al., 2020] strategy.
17
16
 
18
17
  Paper: arxiv.org/abs/2003.00295
19
18
  """
@@ -39,8 +38,8 @@ from .fedopt import FedOpt
39
38
 
40
39
  # flake8: noqa: E501
41
40
  class FedAdam(FedOpt):
42
- """Adaptive Federated Optimization using Adam (FedAdam) [Reddi et al.,
43
- 2020] strategy.
41
+ """Adaptive Federated Optimization using Adam (FedAdam) [Reddi et al., 2020]
42
+ strategy.
44
43
 
45
44
  Paper: https://arxiv.org/abs/2003.00295
46
45
  """
@@ -135,8 +135,7 @@ class FedAvg(Strategy):
135
135
  return rep
136
136
 
137
137
  def num_fit_clients(self, num_available_clients: int) -> Tuple[int, int]:
138
- """Return the sample size and the required number of available
139
- clients."""
138
+ """Return the sample size and the required number of available clients."""
140
139
  num_clients = int(num_available_clients * self.fraction_fit)
141
140
  return max(num_clients, self.min_fit_clients), self.min_available_clients
142
141
 
@@ -109,8 +109,7 @@ class FedAvgAndroid(Strategy):
109
109
  return rep
110
110
 
111
111
  def num_fit_clients(self, num_available_clients: int) -> Tuple[int, int]:
112
- """Return the sample size and the required number of available
113
- clients."""
112
+ """Return the sample size and the required number of available clients."""
114
113
  num_clients = int(num_available_clients * self.fraction_fit)
115
114
  return max(num_clients, self.min_fit_clients), self.min_available_clients
116
115
 
@@ -12,8 +12,7 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
  # ==============================================================================
15
- """Adaptive Federated Optimization (FedOpt) [Reddi et al., 2020] abstract
16
- strategy.
15
+ """Adaptive Federated Optimization (FedOpt) [Reddi et al., 2020] abstract strategy.
17
16
 
18
17
  Paper: arxiv.org/abs/2003.00295
19
18
  """
@@ -12,8 +12,8 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
  # ==============================================================================
15
- """Federated XGBoost in the horizontal setting based on building Neural Network
16
- and averaging on prediction outcomes [Ma et al., 2023].
15
+ """Federated XGBoost in the horizontal setting based on building Neural Network and
16
+ averaging on prediction outcomes [Ma et al., 2023].
17
17
 
18
18
  Paper: Coming
19
19
  """
@@ -12,8 +12,7 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
  # ==============================================================================
15
- """Adaptive Federated Optimization using Yogi (FedYogi) [Reddi et al., 2020]
16
- strategy.
15
+ """Adaptive Federated Optimization using Yogi (FedYogi) [Reddi et al., 2020] strategy.
17
16
 
18
17
  Paper: arxiv.org/abs/2003.00295
19
18
  """
@@ -39,8 +38,8 @@ from .fedopt import FedOpt
39
38
 
40
39
  # flake8: noqa: E501
41
40
  class FedYogi(FedOpt):
42
- """Adaptive Federated Optimization using Yogi (FedYogi) [Reddi et al.,
43
- 2020] strategy.
41
+ """Adaptive Federated Optimization using Yogi (FedYogi) [Reddi et al., 2020]
42
+ strategy.
44
43
 
45
44
  Paper: https://arxiv.org/abs/2003.00295
46
45
  """
@@ -96,8 +96,7 @@ class QFedAvg(FedAvg):
96
96
  return rep
97
97
 
98
98
  def num_fit_clients(self, num_available_clients: int) -> Tuple[int, int]:
99
- """Return the sample size and the required number of available
100
- clients."""
99
+ """Return the sample size and the required number of available clients."""
101
100
  num_clients = int(num_available_clients * self.fraction_fit)
102
101
  return max(num_clients, self.min_fit_clients), self.min_available_clients
103
102
 
@@ -73,8 +73,7 @@ def tensorboard(logdir: str) -> Callable[[Strategy], Strategy]:
73
73
  """Return overloaded Strategy Wrapper."""
74
74
 
75
75
  class TBWrapper(strategy_class): # type: ignore
76
- """Strategy wrapper which hooks into some methods for TensorBoard
77
- logging."""
76
+ """Strategy wrapper that hooks into some methods for TensorBoard logging."""
78
77
 
79
78
  def aggregate_evaluate(
80
79
  self,
@@ -82,8 +81,7 @@ def tensorboard(logdir: str) -> Callable[[Strategy], Strategy]:
82
81
  results: List[Tuple[ClientProxy, EvaluateRes]],
83
82
  failures: List[Union[Tuple[ClientProxy, EvaluateRes], BaseException]],
84
83
  ) -> Tuple[Optional[float], Dict[str, Scalar]]:
85
- """Hooks into aggregate_evaluate for TensorBoard logging
86
- purpose."""
84
+ """Hooks into aggregate_evaluate for TensorBoard logging purpose."""
87
85
  # Execute decorated function and extract results for logging
88
86
  # They will be returned at the end of this function but also
89
87
  # used for logging
@@ -23,7 +23,6 @@ from flwr.proto.task_pb2 import TaskIns, TaskRes
23
23
  # pylint: disable-next=too-many-branches
24
24
  def validate_task_ins_or_res(tasks_ins_res: Union[TaskIns, TaskRes]) -> List[str]:
25
25
  """Validate a TaskIns or TaskRes."""
26
-
27
26
  validation_errors = []
28
27
 
29
28
  if tasks_ins_res.task_id != "":
flwr/simulation/app.py CHANGED
@@ -129,7 +129,6 @@ def start_simulation( # pylint: disable=too-many-arguments
129
129
  hist : flwr.server.history.History
130
130
  Object containing metrics from training.
131
131
  """
132
-
133
132
  # pylint: disable-msg=too-many-locals
134
133
  event(
135
134
  EventType.START_SIMULATION_ENTER,
@@ -172,15 +171,15 @@ def start_simulation( # pylint: disable=too-many-arguments
172
171
  }
173
172
 
174
173
  # Shut down Ray if it has already been initialized (unless asked not to)
175
- if ray.is_initialized() and not keep_initialised:
176
- ray.shutdown()
174
+ if ray.is_initialized() and not keep_initialised: # type: ignore
175
+ ray.shutdown() # type: ignore
177
176
 
178
177
  # Initialize Ray
179
- ray.init(**ray_init_args)
178
+ ray.init(**ray_init_args) # type: ignore
180
179
  log(
181
180
  INFO,
182
181
  "Flower VCE: Ray initialized with resources: %s",
183
- ray.cluster_resources(),
182
+ ray.cluster_resources(), # type: ignore
184
183
  )
185
184
 
186
185
  # Register one RayClientProxy object for each client with the ClientManager