flwr-nightly 1.10.0.dev20240619__py3-none-any.whl → 1.10.0.dev20240621__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.

Potentially problematic release.


This version of flwr-nightly might be problematic. Click here for more details.

Files changed (98) hide show
  1. flwr/cli/app.py +3 -0
  2. flwr/cli/build.py +3 -7
  3. flwr/cli/new/new.py +104 -28
  4. flwr/cli/new/templates/app/README.flowertune.md.tpl +56 -0
  5. flwr/cli/new/templates/app/code/flwr_tune/__init__.py +15 -0
  6. flwr/cli/new/templates/app/code/flwr_tune/app.py.tpl +86 -0
  7. flwr/cli/new/templates/app/code/flwr_tune/client.py.tpl +124 -0
  8. flwr/cli/new/templates/app/code/flwr_tune/config.yaml.tpl +34 -0
  9. flwr/cli/new/templates/app/code/flwr_tune/dataset.py.tpl +57 -0
  10. flwr/cli/new/templates/app/code/flwr_tune/models.py.tpl +59 -0
  11. flwr/cli/new/templates/app/code/flwr_tune/server.py.tpl +48 -0
  12. flwr/cli/new/templates/app/code/flwr_tune/static_config.yaml.tpl +11 -0
  13. flwr/cli/new/templates/app/pyproject.flowertune.toml.tpl +42 -0
  14. flwr/cli/run/run.py +8 -1
  15. flwr/client/client_app.py +1 -1
  16. flwr/client/dpfedavg_numpy_client.py +1 -1
  17. flwr/client/grpc_rere_client/__init__.py +1 -1
  18. flwr/client/grpc_rere_client/connection.py +1 -1
  19. flwr/client/message_handler/__init__.py +1 -1
  20. flwr/client/message_handler/message_handler.py +1 -1
  21. flwr/client/mod/__init__.py +1 -1
  22. flwr/client/mod/secure_aggregation/__init__.py +1 -1
  23. flwr/client/mod/utils.py +1 -1
  24. flwr/client/rest_client/__init__.py +1 -1
  25. flwr/client/rest_client/connection.py +1 -1
  26. flwr/client/supernode/app.py +1 -1
  27. flwr/common/address.py +1 -1
  28. flwr/common/config.py +8 -6
  29. flwr/common/constant.py +1 -1
  30. flwr/common/date.py +1 -1
  31. flwr/common/dp.py +1 -1
  32. flwr/common/grpc.py +1 -1
  33. flwr/common/secure_aggregation/__init__.py +1 -1
  34. flwr/common/secure_aggregation/crypto/__init__.py +1 -1
  35. flwr/common/secure_aggregation/crypto/shamir.py +1 -1
  36. flwr/common/secure_aggregation/crypto/symmetric_encryption.py +1 -1
  37. flwr/common/secure_aggregation/ndarrays_arithmetic.py +1 -1
  38. flwr/common/secure_aggregation/quantization.py +1 -1
  39. flwr/common/secure_aggregation/secaggplus_constants.py +1 -1
  40. flwr/common/secure_aggregation/secaggplus_utils.py +1 -1
  41. flwr/common/version.py +14 -0
  42. flwr/server/compat/app.py +1 -1
  43. flwr/server/compat/app_utils.py +1 -1
  44. flwr/server/compat/driver_client_proxy.py +1 -1
  45. flwr/server/driver/driver.py +6 -0
  46. flwr/server/driver/grpc_driver.py +85 -63
  47. flwr/server/driver/inmemory_driver.py +28 -26
  48. flwr/server/run_serverapp.py +61 -18
  49. flwr/server/strategy/bulyan.py +1 -1
  50. flwr/server/strategy/dpfedavg_adaptive.py +1 -1
  51. flwr/server/strategy/dpfedavg_fixed.py +1 -1
  52. flwr/server/strategy/fedadagrad.py +1 -1
  53. flwr/server/strategy/fedadam.py +1 -1
  54. flwr/server/strategy/fedavg_android.py +1 -1
  55. flwr/server/strategy/fedavgm.py +1 -1
  56. flwr/server/strategy/fedmedian.py +1 -1
  57. flwr/server/strategy/fedopt.py +1 -1
  58. flwr/server/strategy/fedprox.py +1 -1
  59. flwr/server/strategy/fedxgb_bagging.py +1 -1
  60. flwr/server/strategy/fedxgb_cyclic.py +1 -1
  61. flwr/server/strategy/fedxgb_nn_avg.py +1 -1
  62. flwr/server/strategy/fedyogi.py +1 -1
  63. flwr/server/strategy/krum.py +1 -1
  64. flwr/server/strategy/qfedavg.py +1 -1
  65. flwr/server/superlink/driver/__init__.py +1 -1
  66. flwr/server/superlink/driver/driver_grpc.py +1 -1
  67. flwr/server/superlink/driver/driver_servicer.py +15 -3
  68. flwr/server/superlink/fleet/__init__.py +1 -1
  69. flwr/server/superlink/fleet/grpc_bidi/__init__.py +1 -1
  70. flwr/server/superlink/fleet/grpc_bidi/flower_service_servicer.py +1 -1
  71. flwr/server/superlink/fleet/grpc_bidi/grpc_bridge.py +1 -1
  72. flwr/server/superlink/fleet/grpc_bidi/grpc_client_proxy.py +1 -1
  73. flwr/server/superlink/fleet/grpc_bidi/grpc_server.py +1 -1
  74. flwr/server/superlink/fleet/grpc_rere/__init__.py +1 -1
  75. flwr/server/superlink/fleet/grpc_rere/fleet_servicer.py +1 -1
  76. flwr/server/superlink/fleet/message_handler/__init__.py +1 -1
  77. flwr/server/superlink/fleet/message_handler/message_handler.py +1 -1
  78. flwr/server/superlink/fleet/rest_rere/__init__.py +1 -1
  79. flwr/server/superlink/fleet/rest_rere/rest_api.py +1 -1
  80. flwr/server/superlink/fleet/vce/backend/raybackend.py +44 -25
  81. flwr/server/superlink/state/__init__.py +1 -1
  82. flwr/server/superlink/state/in_memory_state.py +1 -1
  83. flwr/server/superlink/state/sqlite_state.py +1 -1
  84. flwr/server/superlink/state/state.py +1 -1
  85. flwr/server/superlink/state/state_factory.py +11 -2
  86. flwr/server/utils/__init__.py +1 -1
  87. flwr/server/utils/tensorboard.py +1 -1
  88. flwr/simulation/__init__.py +1 -1
  89. flwr/simulation/app.py +1 -1
  90. flwr/simulation/ray_transport/__init__.py +1 -1
  91. flwr/simulation/ray_transport/ray_actor.py +0 -6
  92. flwr/simulation/ray_transport/ray_client_proxy.py +1 -1
  93. flwr/simulation/run_simulation.py +47 -28
  94. {flwr_nightly-1.10.0.dev20240619.dist-info → flwr_nightly-1.10.0.dev20240621.dist-info}/METADATA +2 -1
  95. {flwr_nightly-1.10.0.dev20240619.dist-info → flwr_nightly-1.10.0.dev20240621.dist-info}/RECORD +98 -88
  96. {flwr_nightly-1.10.0.dev20240619.dist-info → flwr_nightly-1.10.0.dev20240621.dist-info}/LICENSE +0 -0
  97. {flwr_nightly-1.10.0.dev20240619.dist-info → flwr_nightly-1.10.0.dev20240621.dist-info}/WHEEL +0 -0
  98. {flwr_nightly-1.10.0.dev20240619.dist-info → flwr_nightly-1.10.0.dev20240621.dist-info}/entry_points.txt +0 -0
@@ -1,4 +1,4 @@
1
- # Copyright 2020 Flower Labs GmbH. All Rights Reserved.
1
+ # Copyright 2024 Flower Labs GmbH. All Rights Reserved.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -35,7 +35,11 @@ from flwr.proto.driver_pb2 import ( # pylint: disable=E0611
35
35
  PushTaskInsResponse,
36
36
  )
37
37
  from flwr.proto.node_pb2 import Node # pylint: disable=E0611
38
- from flwr.proto.run_pb2 import GetRunRequest, GetRunResponse # pylint: disable=E0611
38
+ from flwr.proto.run_pb2 import ( # pylint: disable=E0611
39
+ GetRunRequest,
40
+ GetRunResponse,
41
+ Run,
42
+ )
39
43
  from flwr.proto.task_pb2 import TaskRes # pylint: disable=E0611
40
44
  from flwr.server.superlink.state import State, StateFactory
41
45
  from flwr.server.utils.validator import validate_task_ins_or_res
@@ -134,7 +138,15 @@ class DriverServicer(driver_pb2_grpc.DriverServicer):
134
138
  self, request: GetRunRequest, context: grpc.ServicerContext
135
139
  ) -> GetRunResponse:
136
140
  """Get run information."""
137
- raise NotImplementedError
141
+ log(DEBUG, "DriverServicer.GetRun")
142
+
143
+ # Init state
144
+ state: State = self.state_factory.state()
145
+
146
+ # Retrieve run information
147
+ run = state.get_run(request.run_id)
148
+ run_proto = None if run is None else Run(**vars(run))
149
+ return GetRunResponse(run=run_proto)
138
150
 
139
151
 
140
152
  def _raise_if(validation_error: bool, detail: str) -> None:
@@ -1,4 +1,4 @@
1
- # Copyright 2022 Flower Labs GmbH. All Rights Reserved.
1
+ # Copyright 2024 Flower Labs GmbH. All Rights Reserved.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright 2020 Flower Labs GmbH. All Rights Reserved.
1
+ # Copyright 2024 Flower Labs GmbH. All Rights Reserved.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright 2020 Flower Labs GmbH. All Rights Reserved.
1
+ # Copyright 2024 Flower Labs GmbH. All Rights Reserved.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright 2020 Flower Labs GmbH. All Rights Reserved.
1
+ # Copyright 2024 Flower Labs GmbH. All Rights Reserved.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright 2020 Flower Labs GmbH. All Rights Reserved.
1
+ # Copyright 2024 Flower Labs GmbH. All Rights Reserved.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright 2020 Flower Labs GmbH. All Rights Reserved.
1
+ # Copyright 2024 Flower Labs GmbH. All Rights Reserved.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright 2020 Flower Labs GmbH. All Rights Reserved.
1
+ # Copyright 2024 Flower Labs GmbH. All Rights Reserved.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright 2020 Flower Labs GmbH. All Rights Reserved.
1
+ # Copyright 2024 Flower Labs GmbH. All Rights Reserved.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright 2020 Flower Labs GmbH. All Rights Reserved.
1
+ # Copyright 2024 Flower Labs GmbH. All Rights Reserved.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright 2020 Flower Labs GmbH. All Rights Reserved.
1
+ # Copyright 2024 Flower Labs GmbH. All Rights Reserved.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright 2020 Flower Labs GmbH. All Rights Reserved.
1
+ # Copyright 2024 Flower Labs GmbH. All Rights Reserved.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright 2020 Flower Labs GmbH. All Rights Reserved.
1
+ # Copyright 2024 Flower Labs GmbH. All Rights Reserved.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -15,7 +15,7 @@
15
15
  """Ray backend for the Fleet API using the Simulation Engine."""
16
16
 
17
17
  import pathlib
18
- from logging import DEBUG, ERROR, WARNING
18
+ from logging import DEBUG, ERROR
19
19
  from typing import Callable, Dict, List, Tuple, Union
20
20
 
21
21
  import ray
@@ -24,16 +24,15 @@ from flwr.client.client_app import ClientApp
24
24
  from flwr.common.context import Context
25
25
  from flwr.common.logger import log
26
26
  from flwr.common.message import Message
27
- from flwr.simulation.ray_transport.ray_actor import (
28
- BasicActorPool,
29
- ClientAppActor,
30
- init_ray,
31
- )
27
+ from flwr.common.typing import ConfigsRecordValues
28
+ from flwr.simulation.ray_transport.ray_actor import BasicActorPool, ClientAppActor
32
29
  from flwr.simulation.ray_transport.utils import enable_tf_gpu_growth
33
30
 
34
31
  from .backend import Backend, BackendConfig
35
32
 
36
33
  ClientResourcesDict = Dict[str, Union[int, float]]
34
+ ActorArgsDict = Dict[str, Union[int, float, Callable[[], None]]]
35
+ RunTimeEnvDict = Dict[str, Union[str, List[str]]]
37
36
 
38
37
 
39
38
  class RayBackend(Backend):
@@ -51,40 +50,29 @@ class RayBackend(Backend):
51
50
  if not pathlib.Path(work_dir).exists():
52
51
  raise ValueError(f"Specified work_dir {work_dir} does not exist.")
53
52
 
54
- # Init ray and append working dir if needed
55
- runtime_env = (
56
- self._configure_runtime_env(work_dir=work_dir) if work_dir else None
57
- )
58
-
59
- if backend_config.get("mute_logging", False):
60
- init_ray(
61
- logging_level=WARNING, log_to_driver=False, runtime_env=runtime_env
62
- )
63
- elif backend_config.get("silent", False):
64
- init_ray(logging_level=WARNING, log_to_driver=True, runtime_env=runtime_env)
65
- else:
66
- init_ray(runtime_env=runtime_env)
53
+ # Initialise ray
54
+ self.init_args_key = "init_args"
55
+ self.init_ray(backend_config, work_dir)
67
56
 
68
57
  # Validate client resources
69
58
  self.client_resources_key = "client_resources"
59
+ client_resources = self._validate_client_resources(config=backend_config)
70
60
 
71
61
  # Create actor pool
72
- use_tf = backend_config.get("tensorflow", False)
73
- actor_kwargs = {"on_actor_init_fn": enable_tf_gpu_growth} if use_tf else {}
62
+ actor_kwargs = self._validate_actor_arguments(config=backend_config)
74
63
 
75
- client_resources = self._validate_client_resources(config=backend_config)
76
64
  self.pool = BasicActorPool(
77
65
  actor_type=ClientAppActor,
78
66
  client_resources=client_resources,
79
67
  actor_kwargs=actor_kwargs,
80
68
  )
81
69
 
82
- def _configure_runtime_env(self, work_dir: str) -> Dict[str, Union[str, List[str]]]:
70
+ def _configure_runtime_env(self, work_dir: str) -> RunTimeEnvDict:
83
71
  """Return list of files/subdirectories to exclude relative to work_dir.
84
72
 
85
73
  Without this, Ray will push everything to the Ray Cluster.
86
74
  """
87
- runtime_env: Dict[str, Union[str, List[str]]] = {"working_dir": work_dir}
75
+ runtime_env: RunTimeEnvDict = {"working_dir": work_dir}
88
76
 
89
77
  excludes = []
90
78
  path = pathlib.Path(work_dir)
@@ -125,6 +113,37 @@ class RayBackend(Backend):
125
113
 
126
114
  return client_resources
127
115
 
116
+ def _validate_actor_arguments(self, config: BackendConfig) -> ActorArgsDict:
117
+ actor_args_config = config.get("actor", False)
118
+ actor_args: ActorArgsDict = {}
119
+ if actor_args_config:
120
+ use_tf = actor_args.get("tensorflow", False)
121
+ if use_tf:
122
+ actor_args["on_actor_init_fn"] = enable_tf_gpu_growth
123
+ return actor_args
124
+
125
+ def init_ray(self, backend_config: BackendConfig, work_dir: str) -> None:
126
+ """Intialises Ray if not already initialised."""
127
+ if not ray.is_initialized():
128
+ # Init ray and append working dir if needed
129
+ runtime_env = (
130
+ self._configure_runtime_env(work_dir=work_dir) if work_dir else None
131
+ )
132
+
133
+ ray_init_args: Dict[
134
+ str,
135
+ Union[ConfigsRecordValues, RunTimeEnvDict],
136
+ ] = {}
137
+
138
+ if backend_config.get(self.init_args_key):
139
+ for k, v in backend_config[self.init_args_key].items():
140
+ ray_init_args[k] = v
141
+
142
+ if runtime_env is not None:
143
+ ray_init_args["runtime_env"] = runtime_env
144
+
145
+ ray.init(**ray_init_args)
146
+
128
147
  @property
129
148
  def num_workers(self) -> int:
130
149
  """Return number of actors in pool."""
@@ -152,7 +171,7 @@ class RayBackend(Backend):
152
171
  partition_id = message.metadata.partition_id
153
172
 
154
173
  try:
155
- # Submite a task to the pool
174
+ # Submit a task to the pool
156
175
  future = await self.pool.submit(
157
176
  lambda a, a_fn, mssg, cid, state: a.run.remote(a_fn, mssg, cid, state),
158
177
  (app, message, str(partition_id), context),
@@ -1,4 +1,4 @@
1
- # Copyright 2023 Flower Labs GmbH. All Rights Reserved.
1
+ # Copyright 2024 Flower Labs GmbH. All Rights Reserved.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright 2023 Flower Labs GmbH. All Rights Reserved.
1
+ # Copyright 2024 Flower Labs GmbH. All Rights Reserved.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright 2023 Flower Labs GmbH. All Rights Reserved.
1
+ # Copyright 2024 Flower Labs GmbH. All Rights Reserved.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright 2022 Flower Labs GmbH. All Rights Reserved.
1
+ # Copyright 2024 Flower Labs GmbH. All Rights Reserved.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright 2022 Flower Labs GmbH. All Rights Reserved.
1
+ # Copyright 2024 Flower Labs GmbH. All Rights Reserved.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -26,7 +26,16 @@ from .state import State
26
26
 
27
27
 
28
28
  class StateFactory:
29
- """Factory class that creates State instances."""
29
+ """Factory class that creates State instances.
30
+
31
+ Parameters
32
+ ----------
33
+ database : str
34
+ A string representing the path to the database file that will be opened.
35
+ Note that passing ':memory:' will open a connection to a database that is
36
+ in RAM, instead of on disk. For more information on special in-memory
37
+ databases, please refer to https://sqlite.org/inmemorydb.html.
38
+ """
30
39
 
31
40
  def __init__(self, database: str) -> None:
32
41
  self.database = database
@@ -1,4 +1,4 @@
1
- # Copyright 2020 Flower Labs GmbH. All Rights Reserved.
1
+ # Copyright 2021 Flower Labs GmbH. All Rights Reserved.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright 2020 Flower Labs GmbH. All Rights Reserved.
1
+ # Copyright 2021 Flower Labs GmbH. All Rights Reserved.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright 2020 Flower Labs GmbH. All Rights Reserved.
1
+ # Copyright 2021 Flower Labs GmbH. All Rights Reserved.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
flwr/simulation/app.py CHANGED
@@ -1,4 +1,4 @@
1
- # Copyright 2020 Flower Labs GmbH. All Rights Reserved.
1
+ # Copyright 2021 Flower Labs GmbH. All Rights Reserved.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright 2020 Flower Labs GmbH. All Rights Reserved.
1
+ # Copyright 2021 Flower Labs GmbH. All Rights Reserved.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -399,12 +399,6 @@ class VirtualClientEngineActorPool(ActorPool):
399
399
  return self._fetch_future_result(cid)
400
400
 
401
401
 
402
- def init_ray(*args: Any, **kwargs: Any) -> None:
403
- """Intialises Ray if not already initialised."""
404
- if not ray.is_initialized():
405
- ray.init(*args, **kwargs)
406
-
407
-
408
402
  class BasicActorPool:
409
403
  """A basic actor pool."""
410
404
 
@@ -1,4 +1,4 @@
1
- # Copyright 2020 Flower Labs GmbH. All Rights Reserved.
1
+ # Copyright 2021 Flower Labs GmbH. All Rights Reserved.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -22,16 +22,17 @@ import threading
22
22
  import traceback
23
23
  from logging import DEBUG, ERROR, INFO, WARNING
24
24
  from time import sleep
25
- from typing import Dict, Optional
25
+ from typing import Optional
26
26
 
27
27
  from flwr.client import ClientApp
28
28
  from flwr.common import EventType, event, log
29
29
  from flwr.common.logger import set_logger_propagation, update_console_handler
30
- from flwr.common.typing import ConfigsRecordValues
30
+ from flwr.common.typing import Run
31
31
  from flwr.server.driver import Driver, InMemoryDriver
32
32
  from flwr.server.run_serverapp import run
33
33
  from flwr.server.server_app import ServerApp
34
34
  from flwr.server.superlink.fleet import vce
35
+ from flwr.server.superlink.fleet.vce.backend.backend import BackendConfig
35
36
  from flwr.server.superlink.state import StateFactory
36
37
  from flwr.simulation.ray_transport.utils import (
37
38
  enable_tf_gpu_growth as enable_gpu_growth,
@@ -66,7 +67,7 @@ def run_simulation(
66
67
  client_app: ClientApp,
67
68
  num_supernodes: int,
68
69
  backend_name: str = "ray",
69
- backend_config: Optional[Dict[str, ConfigsRecordValues]] = None,
70
+ backend_config: Optional[BackendConfig] = None,
70
71
  enable_tf_gpu_growth: bool = False,
71
72
  verbose_logging: bool = False,
72
73
  ) -> None:
@@ -90,9 +91,12 @@ def run_simulation(
90
91
  backend_name : str (default: ray)
91
92
  A simulation backend that runs `ClientApp`s.
92
93
 
93
- backend_config : Optional[Dict[str, ConfigsRecordValues]]
94
- 'A dictionary, e.g {"<keyA>": <value>, "<keyB>": <value>} to configure a
95
- backend. Values supported in <value> are those included by
94
+ backend_config : Optional[BackendConfig]
95
+ 'A dictionary to configure a backend. Separate dictionaries to configure
96
+ different elements of backend. Supported top-level keys are `init_args`
97
+ for values parsed to initialisation of backend, `client_resources`
98
+ to define the resources for clients, and `actor` to define the actor
99
+ parameters. Values supported in <value> are those included by
96
100
  `flwr.common.typing.ConfigsRecordValues`.
97
101
 
98
102
  enable_tf_gpu_growth : bool (default: False)
@@ -104,7 +108,7 @@ def run_simulation(
104
108
  works in the TensorFlow documentation: https://www.tensorflow.org/api/stable.
105
109
 
106
110
  verbose_logging : bool (default: False)
107
- When diabled, only INFO, WARNING and ERROR log messages will be shown. If
111
+ When disabled, only INFO, WARNING and ERROR log messages will be shown. If
108
112
  enabled, DEBUG-level logs will be displayed.
109
113
  """
110
114
  _run_simulation(
@@ -133,7 +137,7 @@ def run_serverapp_th(
133
137
  def server_th_with_start_checks( # type: ignore
134
138
  tf_gpu_growth: bool, stop_event: asyncio.Event, **kwargs
135
139
  ) -> None:
136
- """Run SeverApp, after check if GPU memory grouwth has to be set.
140
+ """Run SeverApp, after check if GPU memory growth has to be set.
137
141
 
138
142
  Upon exception, trigger stop event for Simulation Engine.
139
143
  """
@@ -169,11 +173,14 @@ def run_serverapp_th(
169
173
  return serverapp_th
170
174
 
171
175
 
172
- def _init_run_id(driver: InMemoryDriver, state: StateFactory, run_id: int) -> None:
173
- """Create a run with a given `run_id`."""
176
+ def _override_run_id(state: StateFactory, run_id_to_replace: int, run_id: int) -> None:
177
+ """Override the run_id of an existing Run."""
174
178
  log(DEBUG, "Pre-registering run with id %s", run_id)
175
- state.state().run_ids[run_id] = ("", "") # type: ignore
176
- driver.run_id = run_id
179
+ # Remove run
180
+ run_info: Run = state.state().run_ids.pop(run_id_to_replace) # type: ignore
181
+ # Update with new run_id and insert back in state
182
+ run_info.run_id = run_id
183
+ state.state().run_ids[run_id] = run_info # type: ignore
177
184
 
178
185
 
179
186
  # pylint: disable=too-many-locals
@@ -191,7 +198,7 @@ def _main_loop(
191
198
  ) -> None:
192
199
  """Launch SuperLink with Simulation Engine, then ServerApp on a separate thread.
193
200
 
194
- Everything runs on the main thread or a separate one, depening on whether the main
201
+ Everything runs on the main thread or a separate one, depending on whether the main
195
202
  thread already contains a running Asyncio event loop. This is the case if running
196
203
  the Simulation Engine on a Jupyter/Colab notebook.
197
204
  """
@@ -201,11 +208,15 @@ def _main_loop(
201
208
  f_stop = asyncio.Event()
202
209
  serverapp_th = None
203
210
  try:
204
- # Initialize Driver
205
- driver = InMemoryDriver(state_factory)
211
+ # Create run (with empty fab_id and fab_version)
212
+ run_id_ = state_factory.state().create_run("", "")
206
213
 
207
214
  if run_id:
208
- _init_run_id(driver, state_factory, run_id)
215
+ _override_run_id(state_factory, run_id_to_replace=run_id_, run_id=run_id)
216
+ run_id_ = run_id
217
+
218
+ # Initialize Driver
219
+ driver = InMemoryDriver(run_id=run_id_, state_factory=state_factory)
209
220
 
210
221
  # Get and run ServerApp thread
211
222
  serverapp_th = run_serverapp_th(
@@ -252,7 +263,7 @@ def _run_simulation(
252
263
  client_app: Optional[ClientApp] = None,
253
264
  server_app: Optional[ServerApp] = None,
254
265
  backend_name: str = "ray",
255
- backend_config: Optional[Dict[str, ConfigsRecordValues]] = None,
266
+ backend_config: Optional[BackendConfig] = None,
256
267
  client_app_attr: Optional[str] = None,
257
268
  server_app_attr: Optional[str] = None,
258
269
  app_dir: str = "",
@@ -279,9 +290,12 @@ def _run_simulation(
279
290
  backend_name : str (default: ray)
280
291
  A simulation backend that runs `ClientApp`s.
281
292
 
282
- backend_config : Optional[Dict[str, ConfigsRecordValues]]
283
- 'A dictionary, e.g {"<keyA>":<value>, "<keyB>":<value>} to configure a
284
- backend. Values supported in <value> are those included by
293
+ backend_config : Optional[BackendConfig]
294
+ 'A dictionary to configure a backend. Separate dictionaries to configure
295
+ different elements of backend. Supported top-level keys are `init_args`
296
+ for values parsed to initialisation of backend, `client_resources`
297
+ to define the resources for clients, and `actor` to define the actor
298
+ parameters. Values supported in <value> are those included by
285
299
  `flwr.common.typing.ConfigsRecordValues`.
286
300
 
287
301
  client_app_attr : str
@@ -303,30 +317,34 @@ def _run_simulation(
303
317
  A boolean to indicate whether to enable GPU growth on the main thread. This is
304
318
  desirable if you make use of a TensorFlow model on your `ServerApp` while
305
319
  having your `ClientApp` running on the same GPU. Without enabling this, you
306
- might encounter an out-of-memory error becasue TensorFlow by default allocates
320
+ might encounter an out-of-memory error because TensorFlow by default allocates
307
321
  all GPU memory. Read mor about how `tf.config.experimental.set_memory_growth()`
308
322
  works in the TensorFlow documentation: https://www.tensorflow.org/api/stable.
309
323
 
310
324
  verbose_logging : bool (default: False)
311
- When diabled, only INFO, WARNING and ERROR log messages will be shown. If
325
+ When disabled, only INFO, WARNING and ERROR log messages will be shown. If
312
326
  enabled, DEBUG-level logs will be displayed.
313
327
  """
314
328
  if backend_config is None:
315
329
  backend_config = {}
316
330
 
331
+ if "init_args" not in backend_config:
332
+ backend_config["init_args"] = {}
333
+
317
334
  # Set logging level
318
335
  logger = logging.getLogger("flwr")
319
336
  if verbose_logging:
320
337
  update_console_handler(level=DEBUG, timestamps=True, colored=True)
321
338
  else:
322
- backend_config["silent"] = True
339
+ backend_config["init_args"]["logging_level"] = WARNING
340
+ backend_config["init_args"]["log_to_driver"] = True
323
341
 
324
342
  if enable_tf_gpu_growth:
325
343
  # Check that Backend config has also enabled using GPU growth
326
- use_tf = backend_config.get("tensorflow", False)
344
+ use_tf = backend_config.get("actor", {}).get("tensorflow", False)
327
345
  if not use_tf:
328
346
  log(WARNING, "Enabling GPU growth for your backend.")
329
- backend_config["tensorflow"] = True
347
+ backend_config["actor"]["tensorflow"] = True
330
348
 
331
349
  # Convert config to original JSON-stream format
332
350
  backend_config_stream = json.dumps(backend_config)
@@ -345,7 +363,7 @@ def _run_simulation(
345
363
  server_app_attr,
346
364
  )
347
365
  # Detect if there is an Asyncio event loop already running.
348
- # If yes, run everything on a separate thread. In environmnets
366
+ # If yes, run everything on a separate thread. In environments
349
367
  # like Jupyter/Colab notebooks, there is an event loop present.
350
368
  run_in_thread = False
351
369
  try:
@@ -357,7 +375,7 @@ def _run_simulation(
357
375
  run_in_thread = True
358
376
 
359
377
  except RuntimeError:
360
- log(DEBUG, "No asyncio event loop runnig")
378
+ log(DEBUG, "No asyncio event loop running")
361
379
 
362
380
  finally:
363
381
  if run_in_thread:
@@ -402,7 +420,8 @@ def _parse_args_run_simulation() -> argparse.ArgumentParser:
402
420
  parser.add_argument(
403
421
  "--backend-config",
404
422
  type=str,
405
- default='{"client_resources": {"num_cpus":2, "num_gpus":0.0}, "tensorflow": 0}',
423
+ default='{"client_resources": {"num_cpus":2, "num_gpus":0.0},'
424
+ '"actor": {"tensorflow": 0}}',
406
425
  help='A JSON formatted stream, e.g \'{"<keyA>":<value>, "<keyB>":<value>}\' to '
407
426
  "configure a backend. Values supported in <value> are those included by "
408
427
  "`flwr.common.typing.ConfigsRecordValues`. ",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: flwr-nightly
3
- Version: 1.10.0.dev20240619
3
+ Version: 1.10.0.dev20240621
4
4
  Summary: Flower: A Friendly Federated Learning Framework
5
5
  Home-page: https://flower.ai
6
6
  License: Apache-2.0
@@ -204,6 +204,7 @@ Other [examples](https://github.com/adap/flower/tree/main/examples):
204
204
  - [Flower with KaplanMeierFitter from the lifelines library](https://github.com/adap/flower/tree/main/examples/federated-kaplan-meier-fitter)
205
205
  - [Sample Level Privacy with Opacus](https://github.com/adap/flower/tree/main/examples/opacus)
206
206
  - [Sample Level Privacy with TensorFlow-Privacy](https://github.com/adap/flower/tree/main/examples/tensorflow-privacy)
207
+ - [Flower with a Tabular Dataset](https://github.com/adap/flower/tree/main/examples/fl-tabular)
207
208
 
208
209
  ## Community
209
210