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.

Files changed (99) hide show
  1. flwr/cli/build.py +16 -2
  2. flwr/cli/config_utils.py +47 -27
  3. flwr/cli/install.py +17 -1
  4. flwr/cli/new/new.py +32 -21
  5. flwr/cli/new/templates/app/code/{client.hf.py.tpl → client.huggingface.py.tpl} +15 -5
  6. flwr/cli/new/templates/app/code/client.jax.py.tpl +2 -1
  7. flwr/cli/new/templates/app/code/client.mlx.py.tpl +36 -13
  8. flwr/cli/new/templates/app/code/client.numpy.py.tpl +2 -1
  9. flwr/cli/new/templates/app/code/client.pytorch.py.tpl +16 -5
  10. flwr/cli/new/templates/app/code/client.sklearn.py.tpl +6 -3
  11. flwr/cli/new/templates/app/code/client.tensorflow.py.tpl +25 -5
  12. flwr/cli/new/templates/app/code/flwr_tune/app.py.tpl +22 -19
  13. flwr/cli/new/templates/app/code/flwr_tune/client.py.tpl +5 -3
  14. flwr/cli/new/templates/app/code/flwr_tune/server.py.tpl +1 -1
  15. flwr/cli/new/templates/app/code/server.huggingface.py.tpl +23 -0
  16. flwr/cli/new/templates/app/code/server.jax.py.tpl +16 -8
  17. flwr/cli/new/templates/app/code/server.mlx.py.tpl +12 -7
  18. flwr/cli/new/templates/app/code/server.numpy.py.tpl +16 -8
  19. flwr/cli/new/templates/app/code/server.pytorch.py.tpl +15 -13
  20. flwr/cli/new/templates/app/code/server.sklearn.py.tpl +17 -10
  21. flwr/cli/new/templates/app/code/server.tensorflow.py.tpl +16 -13
  22. flwr/cli/new/templates/app/code/{task.hf.py.tpl → task.huggingface.py.tpl} +14 -2
  23. flwr/cli/new/templates/app/code/task.mlx.py.tpl +14 -2
  24. flwr/cli/new/templates/app/code/task.pytorch.py.tpl +14 -3
  25. flwr/cli/new/templates/app/code/task.tensorflow.py.tpl +13 -1
  26. flwr/cli/new/templates/app/pyproject.flowertune.toml.tpl +9 -12
  27. flwr/cli/new/templates/app/pyproject.huggingface.toml.tpl +38 -0
  28. flwr/cli/new/templates/app/pyproject.jax.toml.tpl +17 -11
  29. flwr/cli/new/templates/app/pyproject.mlx.toml.tpl +17 -12
  30. flwr/cli/new/templates/app/pyproject.numpy.toml.tpl +12 -12
  31. flwr/cli/new/templates/app/pyproject.pytorch.toml.tpl +13 -12
  32. flwr/cli/new/templates/app/pyproject.sklearn.toml.tpl +12 -12
  33. flwr/cli/new/templates/app/pyproject.tensorflow.toml.tpl +15 -12
  34. flwr/cli/run/run.py +133 -54
  35. flwr/client/app.py +56 -24
  36. flwr/client/client_app.py +28 -8
  37. flwr/client/grpc_adapter_client/connection.py +3 -2
  38. flwr/client/grpc_client/connection.py +3 -2
  39. flwr/client/grpc_rere_client/connection.py +17 -6
  40. flwr/client/message_handler/message_handler.py +1 -1
  41. flwr/client/node_state.py +59 -12
  42. flwr/client/node_state_tests.py +4 -3
  43. flwr/client/rest_client/connection.py +19 -8
  44. flwr/client/supernode/app.py +39 -39
  45. flwr/client/typing.py +2 -2
  46. flwr/common/config.py +92 -2
  47. flwr/common/constant.py +3 -0
  48. flwr/common/context.py +24 -9
  49. flwr/common/logger.py +25 -0
  50. flwr/common/object_ref.py +84 -21
  51. flwr/common/serde.py +45 -0
  52. flwr/common/telemetry.py +17 -0
  53. flwr/common/typing.py +5 -0
  54. flwr/proto/common_pb2.py +36 -0
  55. flwr/proto/common_pb2.pyi +121 -0
  56. flwr/proto/common_pb2_grpc.py +4 -0
  57. flwr/proto/common_pb2_grpc.pyi +4 -0
  58. flwr/proto/driver_pb2.py +24 -19
  59. flwr/proto/driver_pb2.pyi +21 -1
  60. flwr/proto/exec_pb2.py +20 -11
  61. flwr/proto/exec_pb2.pyi +41 -1
  62. flwr/proto/run_pb2.py +12 -7
  63. flwr/proto/run_pb2.pyi +22 -1
  64. flwr/proto/task_pb2.py +7 -8
  65. flwr/server/__init__.py +2 -0
  66. flwr/server/compat/legacy_context.py +5 -4
  67. flwr/server/driver/grpc_driver.py +82 -140
  68. flwr/server/run_serverapp.py +40 -18
  69. flwr/server/server_app.py +56 -10
  70. flwr/server/serverapp_components.py +52 -0
  71. flwr/server/superlink/driver/driver_servicer.py +18 -3
  72. flwr/server/superlink/fleet/message_handler/message_handler.py +13 -2
  73. flwr/server/superlink/fleet/vce/backend/__init__.py +1 -1
  74. flwr/server/superlink/fleet/vce/backend/backend.py +4 -4
  75. flwr/server/superlink/fleet/vce/backend/raybackend.py +10 -10
  76. flwr/server/superlink/fleet/vce/vce_api.py +149 -117
  77. flwr/server/superlink/state/in_memory_state.py +11 -3
  78. flwr/server/superlink/state/sqlite_state.py +23 -8
  79. flwr/server/superlink/state/state.py +7 -2
  80. flwr/server/typing.py +2 -0
  81. flwr/server/workflow/secure_aggregation/secaggplus_workflow.py +18 -2
  82. flwr/simulation/__init__.py +1 -1
  83. flwr/simulation/app.py +4 -3
  84. flwr/simulation/ray_transport/ray_actor.py +15 -19
  85. flwr/simulation/ray_transport/ray_client_proxy.py +22 -9
  86. flwr/simulation/run_simulation.py +269 -70
  87. flwr/superexec/app.py +17 -11
  88. flwr/superexec/deployment.py +111 -35
  89. flwr/superexec/exec_grpc.py +5 -1
  90. flwr/superexec/exec_servicer.py +6 -1
  91. flwr/superexec/executor.py +21 -0
  92. flwr/superexec/simulation.py +181 -0
  93. {flwr_nightly-1.10.0.dev20240707.dist-info → flwr_nightly-1.11.0.dev20240724.dist-info}/METADATA +3 -2
  94. {flwr_nightly-1.10.0.dev20240707.dist-info → flwr_nightly-1.11.0.dev20240724.dist-info}/RECORD +97 -91
  95. flwr/cli/new/templates/app/code/server.hf.py.tpl +0 -17
  96. flwr/cli/new/templates/app/pyproject.hf.toml.tpl +0 -37
  97. {flwr_nightly-1.10.0.dev20240707.dist-info → flwr_nightly-1.11.0.dev20240724.dist-info}/LICENSE +0 -0
  98. {flwr_nightly-1.10.0.dev20240707.dist-info → flwr_nightly-1.11.0.dev20240724.dist-info}/WHEEL +0 -0
  99. {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: "asyncio.Queue[Type[VirtualClientEngineActor]]" = asyncio.Queue(
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, Type[VirtualClientEngineActor]] = {}
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.qsize() > 0
431
+ return len(self.pool) > 0
435
432
 
436
- async def add_actors_to_pool(self, num_actors: int) -> None:
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
- await self.pool.put(self.create_actor_fn()) # type: ignore
440
+ self.pool.append(self.create_actor_fn()) # type: ignore
444
441
  self.num_actors += num_actors
445
442
 
446
- async def terminate_all_actors(self) -> None:
443
+ def terminate_all_actors(self) -> None:
447
444
  """Terminate actors in pool."""
448
445
  num_terminated = 0
449
- while self.pool.qsize():
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
- async def submit(
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 = await self.pool.get()
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
- async def add_actor_back_to_pool(self, future: Any) -> None:
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
- await self.pool.put(actor)
469
+ self.pool.append(actor)
474
470
 
475
- async def fetch_result_and_return_actor_to_pool(
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 = await future
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 MessageType, MessageTypeLegacy
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(partition_id=self.partition_id)
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 state
72
- state = self.proxy_state.retrieve_context(run_id=run_id)
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, state: a.run.remote(
77
- a_fn, mssg, partition_id, state
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, str(self.partition_id), state),
92
+ (self.app_fn, message, partition_id_str, context),
80
93
  )
81
94
  out_mssg, updated_context = self.actor_pool.get_client_result(
82
- str(self.partition_id), timeout
95
+ partition_id_str, timeout
83
96
  )
84
97
 
85
98
  # Update state