flwr-nightly 1.10.0.dev20240707__py3-none-any.whl → 1.11.0.dev20240724__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.
- flwr/cli/build.py +16 -2
- flwr/cli/config_utils.py +47 -27
- flwr/cli/install.py +17 -1
- flwr/cli/new/new.py +32 -21
- flwr/cli/new/templates/app/code/{client.hf.py.tpl → client.huggingface.py.tpl} +15 -5
- flwr/cli/new/templates/app/code/client.jax.py.tpl +2 -1
- flwr/cli/new/templates/app/code/client.mlx.py.tpl +36 -13
- flwr/cli/new/templates/app/code/client.numpy.py.tpl +2 -1
- flwr/cli/new/templates/app/code/client.pytorch.py.tpl +16 -5
- flwr/cli/new/templates/app/code/client.sklearn.py.tpl +6 -3
- flwr/cli/new/templates/app/code/client.tensorflow.py.tpl +25 -5
- flwr/cli/new/templates/app/code/flwr_tune/app.py.tpl +22 -19
- flwr/cli/new/templates/app/code/flwr_tune/client.py.tpl +5 -3
- flwr/cli/new/templates/app/code/flwr_tune/server.py.tpl +1 -1
- flwr/cli/new/templates/app/code/server.huggingface.py.tpl +23 -0
- flwr/cli/new/templates/app/code/server.jax.py.tpl +16 -8
- flwr/cli/new/templates/app/code/server.mlx.py.tpl +12 -7
- flwr/cli/new/templates/app/code/server.numpy.py.tpl +16 -8
- flwr/cli/new/templates/app/code/server.pytorch.py.tpl +15 -13
- flwr/cli/new/templates/app/code/server.sklearn.py.tpl +17 -10
- flwr/cli/new/templates/app/code/server.tensorflow.py.tpl +16 -13
- flwr/cli/new/templates/app/code/{task.hf.py.tpl → task.huggingface.py.tpl} +14 -2
- flwr/cli/new/templates/app/code/task.mlx.py.tpl +14 -2
- flwr/cli/new/templates/app/code/task.pytorch.py.tpl +14 -3
- flwr/cli/new/templates/app/code/task.tensorflow.py.tpl +13 -1
- flwr/cli/new/templates/app/pyproject.flowertune.toml.tpl +9 -12
- flwr/cli/new/templates/app/pyproject.huggingface.toml.tpl +38 -0
- flwr/cli/new/templates/app/pyproject.jax.toml.tpl +17 -11
- flwr/cli/new/templates/app/pyproject.mlx.toml.tpl +17 -12
- flwr/cli/new/templates/app/pyproject.numpy.toml.tpl +12 -12
- flwr/cli/new/templates/app/pyproject.pytorch.toml.tpl +13 -12
- flwr/cli/new/templates/app/pyproject.sklearn.toml.tpl +12 -12
- flwr/cli/new/templates/app/pyproject.tensorflow.toml.tpl +15 -12
- flwr/cli/run/run.py +133 -54
- flwr/client/app.py +56 -24
- flwr/client/client_app.py +28 -8
- flwr/client/grpc_adapter_client/connection.py +3 -2
- flwr/client/grpc_client/connection.py +3 -2
- flwr/client/grpc_rere_client/connection.py +17 -6
- flwr/client/message_handler/message_handler.py +1 -1
- flwr/client/node_state.py +59 -12
- flwr/client/node_state_tests.py +4 -3
- flwr/client/rest_client/connection.py +19 -8
- flwr/client/supernode/app.py +39 -39
- flwr/client/typing.py +2 -2
- flwr/common/config.py +92 -2
- flwr/common/constant.py +3 -0
- flwr/common/context.py +24 -9
- flwr/common/logger.py +25 -0
- flwr/common/object_ref.py +84 -21
- flwr/common/serde.py +45 -0
- flwr/common/telemetry.py +17 -0
- flwr/common/typing.py +5 -0
- flwr/proto/common_pb2.py +36 -0
- flwr/proto/common_pb2.pyi +121 -0
- flwr/proto/common_pb2_grpc.py +4 -0
- flwr/proto/common_pb2_grpc.pyi +4 -0
- flwr/proto/driver_pb2.py +24 -19
- flwr/proto/driver_pb2.pyi +21 -1
- flwr/proto/exec_pb2.py +20 -11
- flwr/proto/exec_pb2.pyi +41 -1
- flwr/proto/run_pb2.py +12 -7
- flwr/proto/run_pb2.pyi +22 -1
- flwr/proto/task_pb2.py +7 -8
- flwr/server/__init__.py +2 -0
- flwr/server/compat/legacy_context.py +5 -4
- flwr/server/driver/grpc_driver.py +82 -140
- flwr/server/run_serverapp.py +40 -18
- flwr/server/server_app.py +56 -10
- flwr/server/serverapp_components.py +52 -0
- flwr/server/superlink/driver/driver_servicer.py +18 -3
- flwr/server/superlink/fleet/message_handler/message_handler.py +13 -2
- flwr/server/superlink/fleet/vce/backend/__init__.py +1 -1
- flwr/server/superlink/fleet/vce/backend/backend.py +4 -4
- flwr/server/superlink/fleet/vce/backend/raybackend.py +10 -10
- flwr/server/superlink/fleet/vce/vce_api.py +149 -117
- flwr/server/superlink/state/in_memory_state.py +11 -3
- flwr/server/superlink/state/sqlite_state.py +23 -8
- flwr/server/superlink/state/state.py +7 -2
- flwr/server/typing.py +2 -0
- flwr/server/workflow/secure_aggregation/secaggplus_workflow.py +18 -2
- flwr/simulation/__init__.py +1 -1
- flwr/simulation/app.py +4 -3
- flwr/simulation/ray_transport/ray_actor.py +15 -19
- flwr/simulation/ray_transport/ray_client_proxy.py +22 -9
- flwr/simulation/run_simulation.py +269 -70
- flwr/superexec/app.py +17 -11
- flwr/superexec/deployment.py +111 -35
- flwr/superexec/exec_grpc.py +5 -1
- flwr/superexec/exec_servicer.py +6 -1
- flwr/superexec/executor.py +21 -0
- flwr/superexec/simulation.py +181 -0
- {flwr_nightly-1.10.0.dev20240707.dist-info → flwr_nightly-1.11.0.dev20240724.dist-info}/METADATA +3 -2
- {flwr_nightly-1.10.0.dev20240707.dist-info → flwr_nightly-1.11.0.dev20240724.dist-info}/RECORD +97 -91
- flwr/cli/new/templates/app/code/server.hf.py.tpl +0 -17
- flwr/cli/new/templates/app/pyproject.hf.toml.tpl +0 -37
- {flwr_nightly-1.10.0.dev20240707.dist-info → flwr_nightly-1.11.0.dev20240724.dist-info}/LICENSE +0 -0
- {flwr_nightly-1.10.0.dev20240707.dist-info → flwr_nightly-1.11.0.dev20240724.dist-info}/WHEEL +0 -0
- {flwr_nightly-1.10.0.dev20240707.dist-info → flwr_nightly-1.11.0.dev20240724.dist-info}/entry_points.txt +0 -0
|
@@ -14,7 +14,6 @@
|
|
|
14
14
|
# ==============================================================================
|
|
15
15
|
"""Ray-based Flower Actor and ActorPool implementation."""
|
|
16
16
|
|
|
17
|
-
import asyncio
|
|
18
17
|
import threading
|
|
19
18
|
from abc import ABC
|
|
20
19
|
from logging import DEBUG, ERROR, WARNING
|
|
@@ -411,9 +410,7 @@ class BasicActorPool:
|
|
|
411
410
|
self.client_resources = client_resources
|
|
412
411
|
|
|
413
412
|
# Queue of idle actors
|
|
414
|
-
self.pool:
|
|
415
|
-
maxsize=1024
|
|
416
|
-
)
|
|
413
|
+
self.pool: List[VirtualClientEngineActor] = []
|
|
417
414
|
self.num_actors = 0
|
|
418
415
|
|
|
419
416
|
# Resolve arguments to pass during actor init
|
|
@@ -427,38 +424,37 @@ class BasicActorPool:
|
|
|
427
424
|
# Figure out how many actors can be created given the cluster resources
|
|
428
425
|
# and the resources the user indicates each VirtualClient will need
|
|
429
426
|
self.actors_capacity = pool_size_from_resources(client_resources)
|
|
430
|
-
self._future_to_actor: Dict[Any,
|
|
427
|
+
self._future_to_actor: Dict[Any, VirtualClientEngineActor] = {}
|
|
431
428
|
|
|
432
429
|
def is_actor_available(self) -> bool:
|
|
433
430
|
"""Return true if there is an idle actor."""
|
|
434
|
-
return self.pool
|
|
431
|
+
return len(self.pool) > 0
|
|
435
432
|
|
|
436
|
-
|
|
433
|
+
def add_actors_to_pool(self, num_actors: int) -> None:
|
|
437
434
|
"""Add actors to the pool.
|
|
438
435
|
|
|
439
436
|
This method may be executed also if new resources are added to your Ray cluster
|
|
440
437
|
(e.g. you add a new node).
|
|
441
438
|
"""
|
|
442
439
|
for _ in range(num_actors):
|
|
443
|
-
|
|
440
|
+
self.pool.append(self.create_actor_fn()) # type: ignore
|
|
444
441
|
self.num_actors += num_actors
|
|
445
442
|
|
|
446
|
-
|
|
443
|
+
def terminate_all_actors(self) -> None:
|
|
447
444
|
"""Terminate actors in pool."""
|
|
448
445
|
num_terminated = 0
|
|
449
|
-
|
|
450
|
-
actor = await self.pool.get()
|
|
446
|
+
for actor in self.pool:
|
|
451
447
|
actor.terminate.remote() # type: ignore
|
|
452
448
|
num_terminated += 1
|
|
453
449
|
|
|
454
450
|
log(DEBUG, "Terminated %i actors", num_terminated)
|
|
455
451
|
|
|
456
|
-
|
|
452
|
+
def submit(
|
|
457
453
|
self, actor_fn: Any, job: Tuple[ClientAppFn, Message, str, Context]
|
|
458
454
|
) -> Any:
|
|
459
455
|
"""On idle actor, submit job and return future."""
|
|
460
456
|
# Remove idle actor from pool
|
|
461
|
-
actor =
|
|
457
|
+
actor = self.pool.pop()
|
|
462
458
|
# Submit job to actor
|
|
463
459
|
app_fn, mssg, cid, context = job
|
|
464
460
|
future = actor_fn(actor, app_fn, mssg, cid, context)
|
|
@@ -467,18 +463,18 @@ class BasicActorPool:
|
|
|
467
463
|
self._future_to_actor[future] = actor
|
|
468
464
|
return future
|
|
469
465
|
|
|
470
|
-
|
|
466
|
+
def add_actor_back_to_pool(self, future: Any) -> None:
|
|
471
467
|
"""Ad actor assigned to run future back into the pool."""
|
|
472
468
|
actor = self._future_to_actor.pop(future)
|
|
473
|
-
|
|
469
|
+
self.pool.append(actor)
|
|
474
470
|
|
|
475
|
-
|
|
471
|
+
def fetch_result_and_return_actor_to_pool(
|
|
476
472
|
self, future: Any
|
|
477
473
|
) -> Tuple[Message, Context]:
|
|
478
474
|
"""Pull result given a future and add actor back to pool."""
|
|
479
|
-
# Get actor that ran job
|
|
480
|
-
await self.add_actor_back_to_pool(future)
|
|
481
475
|
# Retrieve result for object store
|
|
482
476
|
# Instead of doing ray.get(future) we await it
|
|
483
|
-
_, out_mssg, updated_context =
|
|
477
|
+
_, out_mssg, updated_context = ray.get(future)
|
|
478
|
+
# Get actor that ran job
|
|
479
|
+
self.add_actor_back_to_pool(future)
|
|
484
480
|
return out_mssg, updated_context
|
|
@@ -24,7 +24,12 @@ from flwr.client import ClientFnExt
|
|
|
24
24
|
from flwr.client.client_app import ClientApp
|
|
25
25
|
from flwr.client.node_state import NodeState
|
|
26
26
|
from flwr.common import DEFAULT_TTL, Message, Metadata, RecordSet
|
|
27
|
-
from flwr.common.constant import
|
|
27
|
+
from flwr.common.constant import (
|
|
28
|
+
NUM_PARTITIONS_KEY,
|
|
29
|
+
PARTITION_ID_KEY,
|
|
30
|
+
MessageType,
|
|
31
|
+
MessageTypeLegacy,
|
|
32
|
+
)
|
|
28
33
|
from flwr.common.logger import log
|
|
29
34
|
from flwr.common.recordset_compat import (
|
|
30
35
|
evaluateins_to_recordset,
|
|
@@ -43,11 +48,12 @@ from flwr.simulation.ray_transport.ray_actor import VirtualClientEngineActorPool
|
|
|
43
48
|
class RayActorClientProxy(ClientProxy):
|
|
44
49
|
"""Flower client proxy which delegates work using Ray."""
|
|
45
50
|
|
|
46
|
-
def __init__(
|
|
51
|
+
def __init__( # pylint: disable=too-many-arguments
|
|
47
52
|
self,
|
|
48
53
|
client_fn: ClientFnExt,
|
|
49
54
|
node_id: int,
|
|
50
55
|
partition_id: int,
|
|
56
|
+
num_partitions: int,
|
|
51
57
|
actor_pool: VirtualClientEngineActorPool,
|
|
52
58
|
):
|
|
53
59
|
super().__init__(cid=str(node_id))
|
|
@@ -59,7 +65,13 @@ class RayActorClientProxy(ClientProxy):
|
|
|
59
65
|
|
|
60
66
|
self.app_fn = _load_app
|
|
61
67
|
self.actor_pool = actor_pool
|
|
62
|
-
self.proxy_state = NodeState(
|
|
68
|
+
self.proxy_state = NodeState(
|
|
69
|
+
node_id=node_id,
|
|
70
|
+
node_config={
|
|
71
|
+
PARTITION_ID_KEY: str(partition_id),
|
|
72
|
+
NUM_PARTITIONS_KEY: str(num_partitions),
|
|
73
|
+
},
|
|
74
|
+
)
|
|
63
75
|
|
|
64
76
|
def _submit_job(self, message: Message, timeout: Optional[float]) -> Message:
|
|
65
77
|
"""Sumbit a message to the ActorPool."""
|
|
@@ -68,18 +80,19 @@ class RayActorClientProxy(ClientProxy):
|
|
|
68
80
|
# Register state
|
|
69
81
|
self.proxy_state.register_context(run_id=run_id)
|
|
70
82
|
|
|
71
|
-
# Retrieve
|
|
72
|
-
|
|
83
|
+
# Retrieve context
|
|
84
|
+
context = self.proxy_state.retrieve_context(run_id=run_id)
|
|
85
|
+
partition_id_str = str(context.node_config[PARTITION_ID_KEY])
|
|
73
86
|
|
|
74
87
|
try:
|
|
75
88
|
self.actor_pool.submit_client_job(
|
|
76
|
-
lambda a, a_fn, mssg, partition_id,
|
|
77
|
-
a_fn, mssg, partition_id,
|
|
89
|
+
lambda a, a_fn, mssg, partition_id, context: a.run.remote(
|
|
90
|
+
a_fn, mssg, partition_id, context
|
|
78
91
|
),
|
|
79
|
-
(self.app_fn, message,
|
|
92
|
+
(self.app_fn, message, partition_id_str, context),
|
|
80
93
|
)
|
|
81
94
|
out_mssg, updated_context = self.actor_pool.get_client_result(
|
|
82
|
-
|
|
95
|
+
partition_id_str, timeout
|
|
83
96
|
)
|
|
84
97
|
|
|
85
98
|
# Update state
|