flwr-nightly 1.13.0.dev20241022__py3-none-any.whl → 1.13.0.dev20241024__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/client/app.py +2 -3
- flwr/client/supernode/app.py +6 -8
- flwr/common/constant.py +29 -0
- flwr/common/typing.py +9 -0
- flwr/proto/driver_pb2.py +24 -15
- flwr/proto/driver_pb2.pyi +59 -0
- flwr/proto/driver_pb2_grpc.py +68 -0
- flwr/proto/driver_pb2_grpc.pyi +26 -0
- flwr/server/app.py +74 -3
- flwr/server/run_serverapp.py +13 -9
- flwr/server/serverapp/app.py +59 -1
- flwr/server/superlink/driver/driver_servicer.py +16 -0
- flwr/server/superlink/linkstate/in_memory_linkstate.py +113 -12
- flwr/server/superlink/linkstate/linkstate.py +78 -1
- flwr/server/superlink/linkstate/sqlite_linkstate.py +173 -27
- flwr/server/superlink/linkstate/utils.py +69 -2
- flwr/simulation/run_simulation.py +23 -7
- flwr/superexec/app.py +3 -138
- flwr/superexec/deployment.py +34 -25
- flwr/superexec/exec_grpc.py +15 -8
- flwr/superexec/exec_servicer.py +11 -1
- flwr/superexec/executor.py +19 -0
- flwr/superexec/simulation.py +8 -0
- {flwr_nightly-1.13.0.dev20241022.dist-info → flwr_nightly-1.13.0.dev20241024.dist-info}/METADATA +1 -1
- {flwr_nightly-1.13.0.dev20241022.dist-info → flwr_nightly-1.13.0.dev20241024.dist-info}/RECORD +28 -29
- flwr/client/node_state_tests.py +0 -65
- {flwr_nightly-1.13.0.dev20241022.dist-info → flwr_nightly-1.13.0.dev20241024.dist-info}/LICENSE +0 -0
- {flwr_nightly-1.13.0.dev20241022.dist-info → flwr_nightly-1.13.0.dev20241024.dist-info}/WHEEL +0 -0
- {flwr_nightly-1.13.0.dev20241022.dist-info → flwr_nightly-1.13.0.dev20241024.dist-info}/entry_points.txt +0 -0
|
@@ -29,22 +29,23 @@ from typing import Any, Optional
|
|
|
29
29
|
|
|
30
30
|
from flwr.cli.config_utils import load_and_validate
|
|
31
31
|
from flwr.client import ClientApp
|
|
32
|
-
from flwr.common import EventType, event, log
|
|
32
|
+
from flwr.common import Context, EventType, RecordSet, event, log, now
|
|
33
33
|
from flwr.common.config import get_fused_config_from_dir, parse_config_args
|
|
34
|
-
from flwr.common.constant import RUN_ID_NUM_BYTES
|
|
34
|
+
from flwr.common.constant import RUN_ID_NUM_BYTES, Status
|
|
35
35
|
from flwr.common.logger import (
|
|
36
36
|
set_logger_propagation,
|
|
37
37
|
update_console_handler,
|
|
38
38
|
warn_deprecated_feature,
|
|
39
39
|
warn_deprecated_feature_with_example,
|
|
40
40
|
)
|
|
41
|
-
from flwr.common.typing import Run, UserConfig
|
|
41
|
+
from flwr.common.typing import Run, RunStatus, UserConfig
|
|
42
42
|
from flwr.server.driver import Driver, InMemoryDriver
|
|
43
|
-
from flwr.server.run_serverapp import run as
|
|
43
|
+
from flwr.server.run_serverapp import run as _run
|
|
44
44
|
from flwr.server.server_app import ServerApp
|
|
45
45
|
from flwr.server.superlink.fleet import vce
|
|
46
46
|
from flwr.server.superlink.fleet.vce.backend.backend import BackendConfig
|
|
47
47
|
from flwr.server.superlink.linkstate import LinkStateFactory
|
|
48
|
+
from flwr.server.superlink.linkstate.in_memory_linkstate import RunRecord
|
|
48
49
|
from flwr.server.superlink.linkstate.utils import generate_rand_int_from_bytes
|
|
49
50
|
from flwr.simulation.ray_transport.utils import (
|
|
50
51
|
enable_tf_gpu_growth as enable_gpu_growth,
|
|
@@ -332,11 +333,19 @@ def run_serverapp_th(
|
|
|
332
333
|
log(INFO, "Enabling GPU growth for Tensorflow on the server thread.")
|
|
333
334
|
enable_gpu_growth()
|
|
334
335
|
|
|
336
|
+
# Initialize Context
|
|
337
|
+
context = Context(
|
|
338
|
+
node_id=0,
|
|
339
|
+
node_config={},
|
|
340
|
+
state=RecordSet(),
|
|
341
|
+
run_config=_server_app_run_config,
|
|
342
|
+
)
|
|
343
|
+
|
|
335
344
|
# Run ServerApp
|
|
336
|
-
|
|
345
|
+
_run(
|
|
337
346
|
driver=_driver,
|
|
347
|
+
context=context,
|
|
338
348
|
server_app_dir=_server_app_dir,
|
|
339
|
-
server_app_run_config=_server_app_run_config,
|
|
340
349
|
server_app_attr=_server_app_attr,
|
|
341
350
|
loaded_server_app=_server_app,
|
|
342
351
|
)
|
|
@@ -399,7 +408,14 @@ def _main_loop(
|
|
|
399
408
|
try:
|
|
400
409
|
# Register run
|
|
401
410
|
log(DEBUG, "Pre-registering run with id %s", run.run_id)
|
|
402
|
-
|
|
411
|
+
init_status = RunStatus(Status.RUNNING, "", "")
|
|
412
|
+
state_factory.state().run_ids[run.run_id] = RunRecord( # type: ignore
|
|
413
|
+
run=run,
|
|
414
|
+
status=init_status,
|
|
415
|
+
starting_at=now().isoformat(),
|
|
416
|
+
running_at=now().isoformat(),
|
|
417
|
+
finished_at="",
|
|
418
|
+
)
|
|
403
419
|
|
|
404
420
|
if server_app_run_config is None:
|
|
405
421
|
server_app_run_config = {}
|
flwr/superexec/app.py
CHANGED
|
@@ -16,21 +16,11 @@
|
|
|
16
16
|
|
|
17
17
|
import argparse
|
|
18
18
|
import sys
|
|
19
|
-
from logging import INFO
|
|
20
|
-
from pathlib import Path
|
|
21
|
-
from typing import Optional
|
|
19
|
+
from logging import INFO
|
|
22
20
|
|
|
23
|
-
import
|
|
24
|
-
|
|
25
|
-
from flwr.common import EventType, event, log
|
|
26
|
-
from flwr.common.address import parse_address
|
|
27
|
-
from flwr.common.config import parse_config_args
|
|
28
|
-
from flwr.common.constant import EXEC_API_DEFAULT_ADDRESS
|
|
29
|
-
from flwr.common.exit_handlers import register_exit_handlers
|
|
30
|
-
from flwr.common.logger import warn_deprecated_feature
|
|
21
|
+
from flwr.common import log
|
|
31
22
|
from flwr.common.object_ref import load_app, validate
|
|
32
23
|
|
|
33
|
-
from .exec_grpc import run_superexec_api_grpc
|
|
34
24
|
from .executor import Executor
|
|
35
25
|
|
|
36
26
|
|
|
@@ -38,137 +28,12 @@ def run_superexec() -> None:
|
|
|
38
28
|
"""Run Flower SuperExec."""
|
|
39
29
|
log(INFO, "Starting Flower SuperExec")
|
|
40
30
|
|
|
41
|
-
|
|
31
|
+
sys.exit(
|
|
42
32
|
"Manually launching the SuperExec is deprecated. Since `flwr 1.13.0` "
|
|
43
33
|
"the executor service runs in the SuperLink. Launching it manually is not "
|
|
44
34
|
"recommended."
|
|
45
35
|
)
|
|
46
36
|
|
|
47
|
-
event(EventType.RUN_SUPEREXEC_ENTER)
|
|
48
|
-
|
|
49
|
-
args = _parse_args_run_superexec().parse_args()
|
|
50
|
-
|
|
51
|
-
# Parse IP address
|
|
52
|
-
parsed_address = parse_address(args.address)
|
|
53
|
-
if not parsed_address:
|
|
54
|
-
sys.exit(f"SuperExec IP address ({args.address}) cannot be parsed.")
|
|
55
|
-
host, port, is_v6 = parsed_address
|
|
56
|
-
address = f"[{host}]:{port}" if is_v6 else f"{host}:{port}"
|
|
57
|
-
|
|
58
|
-
# Obtain certificates
|
|
59
|
-
certificates = _try_obtain_certificates(args)
|
|
60
|
-
|
|
61
|
-
# Start SuperExec API
|
|
62
|
-
superexec_server: grpc.Server = run_superexec_api_grpc(
|
|
63
|
-
address=address,
|
|
64
|
-
executor=load_executor(args),
|
|
65
|
-
certificates=certificates,
|
|
66
|
-
config=parse_config_args(
|
|
67
|
-
[args.executor_config] if args.executor_config else args.executor_config
|
|
68
|
-
),
|
|
69
|
-
)
|
|
70
|
-
|
|
71
|
-
grpc_servers = [superexec_server]
|
|
72
|
-
|
|
73
|
-
# Graceful shutdown
|
|
74
|
-
register_exit_handlers(
|
|
75
|
-
event_type=EventType.RUN_SUPEREXEC_LEAVE,
|
|
76
|
-
grpc_servers=grpc_servers,
|
|
77
|
-
bckg_threads=None,
|
|
78
|
-
)
|
|
79
|
-
|
|
80
|
-
superexec_server.wait_for_termination()
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
def _parse_args_run_superexec() -> argparse.ArgumentParser:
|
|
84
|
-
"""Parse command line arguments for SuperExec."""
|
|
85
|
-
parser = argparse.ArgumentParser(
|
|
86
|
-
description="Start a Flower SuperExec",
|
|
87
|
-
)
|
|
88
|
-
parser.add_argument(
|
|
89
|
-
"--address",
|
|
90
|
-
help="SuperExec (gRPC) server address (IPv4, IPv6, or a domain name)",
|
|
91
|
-
default=EXEC_API_DEFAULT_ADDRESS,
|
|
92
|
-
)
|
|
93
|
-
parser.add_argument(
|
|
94
|
-
"--executor",
|
|
95
|
-
help="For example: `deployment:exec` or `project.package.module:wrapper.exec`.",
|
|
96
|
-
default="flwr.superexec.deployment:executor",
|
|
97
|
-
)
|
|
98
|
-
parser.add_argument(
|
|
99
|
-
"--executor-dir",
|
|
100
|
-
help="The directory for the executor.",
|
|
101
|
-
default=".",
|
|
102
|
-
)
|
|
103
|
-
parser.add_argument(
|
|
104
|
-
"--executor-config",
|
|
105
|
-
help="Key-value pairs for the executor config, separated by spaces. "
|
|
106
|
-
'For example:\n\n`--executor-config \'superlink="superlink:9091" '
|
|
107
|
-
'root-certificates="certificates/superlink-ca.crt"\'`',
|
|
108
|
-
)
|
|
109
|
-
parser.add_argument(
|
|
110
|
-
"--insecure",
|
|
111
|
-
action="store_true",
|
|
112
|
-
help="Run the SuperExec without HTTPS, regardless of whether certificate "
|
|
113
|
-
"paths are provided. By default, the server runs with HTTPS enabled. "
|
|
114
|
-
"Use this flag only if you understand the risks.",
|
|
115
|
-
)
|
|
116
|
-
parser.add_argument(
|
|
117
|
-
"--ssl-certfile",
|
|
118
|
-
help="SuperExec server SSL certificate file (as a path str) "
|
|
119
|
-
"to create a secure connection.",
|
|
120
|
-
type=str,
|
|
121
|
-
default=None,
|
|
122
|
-
)
|
|
123
|
-
parser.add_argument(
|
|
124
|
-
"--ssl-keyfile",
|
|
125
|
-
help="SuperExec server SSL private key file (as a path str) "
|
|
126
|
-
"to create a secure connection.",
|
|
127
|
-
type=str,
|
|
128
|
-
)
|
|
129
|
-
parser.add_argument(
|
|
130
|
-
"--ssl-ca-certfile",
|
|
131
|
-
help="SuperExec server SSL CA certificate file (as a path str) "
|
|
132
|
-
"to create a secure connection.",
|
|
133
|
-
type=str,
|
|
134
|
-
)
|
|
135
|
-
return parser
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
def _try_obtain_certificates(
|
|
139
|
-
args: argparse.Namespace,
|
|
140
|
-
) -> Optional[tuple[bytes, bytes, bytes]]:
|
|
141
|
-
# Obtain certificates
|
|
142
|
-
if args.insecure:
|
|
143
|
-
log(WARN, "Option `--insecure` was set. Starting insecure HTTP server.")
|
|
144
|
-
return None
|
|
145
|
-
# Check if certificates are provided
|
|
146
|
-
if args.ssl_certfile and args.ssl_keyfile and args.ssl_ca_certfile:
|
|
147
|
-
if not Path(args.ssl_ca_certfile).is_file():
|
|
148
|
-
sys.exit("Path argument `--ssl-ca-certfile` does not point to a file.")
|
|
149
|
-
if not Path(args.ssl_certfile).is_file():
|
|
150
|
-
sys.exit("Path argument `--ssl-certfile` does not point to a file.")
|
|
151
|
-
if not Path(args.ssl_keyfile).is_file():
|
|
152
|
-
sys.exit("Path argument `--ssl-keyfile` does not point to a file.")
|
|
153
|
-
certificates = (
|
|
154
|
-
Path(args.ssl_ca_certfile).read_bytes(), # CA certificate
|
|
155
|
-
Path(args.ssl_certfile).read_bytes(), # server certificate
|
|
156
|
-
Path(args.ssl_keyfile).read_bytes(), # server private key
|
|
157
|
-
)
|
|
158
|
-
return certificates
|
|
159
|
-
if args.ssl_certfile or args.ssl_keyfile or args.ssl_ca_certfile:
|
|
160
|
-
sys.exit(
|
|
161
|
-
"You need to provide valid file paths to `--ssl-certfile`, "
|
|
162
|
-
"`--ssl-keyfile`, and `—-ssl-ca-certfile` to create a secure "
|
|
163
|
-
"connection in SuperExec server (gRPC-rere)."
|
|
164
|
-
)
|
|
165
|
-
sys.exit(
|
|
166
|
-
"Certificates are required unless running in insecure mode. "
|
|
167
|
-
"Please provide certificate paths to `--ssl-certfile`, "
|
|
168
|
-
"`--ssl-keyfile`, and `—-ssl-ca-certfile` or run the server "
|
|
169
|
-
"in insecure mode using '--insecure' if you understand the risks."
|
|
170
|
-
)
|
|
171
|
-
|
|
172
37
|
|
|
173
38
|
def load_executor(
|
|
174
39
|
args: argparse.Namespace,
|
flwr/superexec/deployment.py
CHANGED
|
@@ -24,12 +24,11 @@ from typing_extensions import override
|
|
|
24
24
|
|
|
25
25
|
from flwr.cli.install import install_from_fab
|
|
26
26
|
from flwr.common.constant import DRIVER_API_DEFAULT_ADDRESS
|
|
27
|
-
from flwr.common.grpc import create_channel
|
|
28
27
|
from flwr.common.logger import log
|
|
29
|
-
from flwr.common.serde import fab_to_proto, user_config_to_proto
|
|
30
28
|
from flwr.common.typing import Fab, UserConfig
|
|
31
|
-
from flwr.
|
|
32
|
-
from flwr.
|
|
29
|
+
from flwr.server.superlink.ffs import Ffs
|
|
30
|
+
from flwr.server.superlink.ffs.ffs_factory import FfsFactory
|
|
31
|
+
from flwr.server.superlink.linkstate import LinkState, LinkStateFactory
|
|
33
32
|
|
|
34
33
|
from .executor import Executor, RunTracker
|
|
35
34
|
|
|
@@ -62,7 +61,30 @@ class DeploymentEngine(Executor):
|
|
|
62
61
|
self.root_certificates = root_certificates
|
|
63
62
|
self.root_certificates_bytes = Path(root_certificates).read_bytes()
|
|
64
63
|
self.flwr_dir = flwr_dir
|
|
65
|
-
self.
|
|
64
|
+
self.linkstate_factory: Optional[LinkStateFactory] = None
|
|
65
|
+
self.ffs_factory: Optional[FfsFactory] = None
|
|
66
|
+
|
|
67
|
+
@override
|
|
68
|
+
def initialize(
|
|
69
|
+
self, linkstate_factory: LinkStateFactory, ffs_factory: FfsFactory
|
|
70
|
+
) -> None:
|
|
71
|
+
"""Initialize the executor with the necessary factories."""
|
|
72
|
+
self.linkstate_factory = linkstate_factory
|
|
73
|
+
self.ffs_factory = ffs_factory
|
|
74
|
+
|
|
75
|
+
@property
|
|
76
|
+
def linkstate(self) -> LinkState:
|
|
77
|
+
"""Return the LinkState."""
|
|
78
|
+
if self.linkstate_factory is None:
|
|
79
|
+
raise RuntimeError("Executor is not initialized.")
|
|
80
|
+
return self.linkstate_factory.state()
|
|
81
|
+
|
|
82
|
+
@property
|
|
83
|
+
def ffs(self) -> Ffs:
|
|
84
|
+
"""Return the Flower File Storage (FFS)."""
|
|
85
|
+
if self.ffs_factory is None:
|
|
86
|
+
raise RuntimeError("Executor is not initialized.")
|
|
87
|
+
return self.ffs_factory.ffs()
|
|
66
88
|
|
|
67
89
|
@override
|
|
68
90
|
def set_config(
|
|
@@ -101,32 +123,19 @@ class DeploymentEngine(Executor):
|
|
|
101
123
|
raise ValueError("The `flwr-dir` value should be of type `str`.")
|
|
102
124
|
self.flwr_dir = str(flwr_dir)
|
|
103
125
|
|
|
104
|
-
def _connect(self) -> None:
|
|
105
|
-
if self.stub is not None:
|
|
106
|
-
return
|
|
107
|
-
channel = create_channel(
|
|
108
|
-
server_address=self.superlink,
|
|
109
|
-
insecure=(self.root_certificates_bytes is None),
|
|
110
|
-
root_certificates=self.root_certificates_bytes,
|
|
111
|
-
)
|
|
112
|
-
self.stub = DriverStub(channel)
|
|
113
|
-
|
|
114
126
|
def _create_run(
|
|
115
127
|
self,
|
|
116
128
|
fab: Fab,
|
|
117
129
|
override_config: UserConfig,
|
|
118
130
|
) -> int:
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
131
|
+
fab_hash = self.ffs.put(fab.content, {})
|
|
132
|
+
if fab_hash != fab.hash_str:
|
|
133
|
+
raise RuntimeError(
|
|
134
|
+
f"FAB ({fab.hash_str}) hash from request doesn't match contents"
|
|
135
|
+
)
|
|
123
136
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
override_config=user_config_to_proto(override_config),
|
|
127
|
-
)
|
|
128
|
-
res = self.stub.CreateRun(request=req)
|
|
129
|
-
return int(res.run_id)
|
|
137
|
+
run_id = self.linkstate.create_run(None, None, fab_hash, override_config)
|
|
138
|
+
return run_id
|
|
130
139
|
|
|
131
140
|
@override
|
|
132
141
|
def start_run(
|
flwr/superexec/exec_grpc.py
CHANGED
|
@@ -23,33 +23,40 @@ from flwr.common import GRPC_MAX_MESSAGE_LENGTH
|
|
|
23
23
|
from flwr.common.logger import log
|
|
24
24
|
from flwr.common.typing import UserConfig
|
|
25
25
|
from flwr.proto.exec_pb2_grpc import add_ExecServicer_to_server
|
|
26
|
+
from flwr.server.superlink.ffs.ffs_factory import FfsFactory
|
|
26
27
|
from flwr.server.superlink.fleet.grpc_bidi.grpc_server import generic_create_grpc_server
|
|
28
|
+
from flwr.server.superlink.linkstate import LinkStateFactory
|
|
27
29
|
|
|
28
30
|
from .exec_servicer import ExecServicer
|
|
29
31
|
from .executor import Executor
|
|
30
32
|
|
|
31
33
|
|
|
32
|
-
|
|
34
|
+
# pylint: disable-next=too-many-arguments, too-many-positional-arguments
|
|
35
|
+
def run_exec_api_grpc(
|
|
33
36
|
address: str,
|
|
34
37
|
executor: Executor,
|
|
38
|
+
state_factory: LinkStateFactory,
|
|
39
|
+
ffs_factory: FfsFactory,
|
|
35
40
|
certificates: Optional[tuple[bytes, bytes, bytes]],
|
|
36
41
|
config: UserConfig,
|
|
37
42
|
) -> grpc.Server:
|
|
38
|
-
"""Run
|
|
43
|
+
"""Run Exec API (gRPC, request-response)."""
|
|
39
44
|
executor.set_config(config)
|
|
40
45
|
|
|
41
46
|
exec_servicer: grpc.Server = ExecServicer(
|
|
47
|
+
linkstate_factory=state_factory,
|
|
48
|
+
ffs_factory=ffs_factory,
|
|
42
49
|
executor=executor,
|
|
43
50
|
)
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
servicer_and_add_fn=(exec_servicer,
|
|
51
|
+
exec_add_servicer_to_server_fn = add_ExecServicer_to_server
|
|
52
|
+
exec_grpc_server = generic_create_grpc_server(
|
|
53
|
+
servicer_and_add_fn=(exec_servicer, exec_add_servicer_to_server_fn),
|
|
47
54
|
server_address=address,
|
|
48
55
|
max_message_length=GRPC_MAX_MESSAGE_LENGTH,
|
|
49
56
|
certificates=certificates,
|
|
50
57
|
)
|
|
51
58
|
|
|
52
|
-
log(INFO, "
|
|
53
|
-
|
|
59
|
+
log(INFO, "Flower Deployment Engine: Starting Exec API on %s", address)
|
|
60
|
+
exec_grpc_server.start()
|
|
54
61
|
|
|
55
|
-
return
|
|
62
|
+
return exec_grpc_server
|
flwr/superexec/exec_servicer.py
CHANGED
|
@@ -34,6 +34,8 @@ from flwr.proto.exec_pb2 import ( # pylint: disable=E0611
|
|
|
34
34
|
StreamLogsRequest,
|
|
35
35
|
StreamLogsResponse,
|
|
36
36
|
)
|
|
37
|
+
from flwr.server.superlink.ffs.ffs_factory import FfsFactory
|
|
38
|
+
from flwr.server.superlink.linkstate import LinkStateFactory
|
|
37
39
|
|
|
38
40
|
from .executor import Executor, RunTracker
|
|
39
41
|
|
|
@@ -43,8 +45,16 @@ SELECT_TIMEOUT = 1 # Timeout for selecting ready-to-read file descriptors (in s
|
|
|
43
45
|
class ExecServicer(exec_pb2_grpc.ExecServicer):
|
|
44
46
|
"""SuperExec API servicer."""
|
|
45
47
|
|
|
46
|
-
def __init__(
|
|
48
|
+
def __init__(
|
|
49
|
+
self,
|
|
50
|
+
linkstate_factory: LinkStateFactory,
|
|
51
|
+
ffs_factory: FfsFactory,
|
|
52
|
+
executor: Executor,
|
|
53
|
+
) -> None:
|
|
54
|
+
self.linkstate_factory = linkstate_factory
|
|
55
|
+
self.ffs_factory = ffs_factory
|
|
47
56
|
self.executor = executor
|
|
57
|
+
self.executor.initialize(linkstate_factory, ffs_factory)
|
|
48
58
|
self.runs: dict[int, RunTracker] = {}
|
|
49
59
|
|
|
50
60
|
def StartRun(
|
flwr/superexec/executor.py
CHANGED
|
@@ -20,6 +20,8 @@ from subprocess import Popen
|
|
|
20
20
|
from typing import Optional
|
|
21
21
|
|
|
22
22
|
from flwr.common.typing import UserConfig
|
|
23
|
+
from flwr.server.superlink.ffs.ffs_factory import FfsFactory
|
|
24
|
+
from flwr.server.superlink.linkstate import LinkStateFactory
|
|
23
25
|
|
|
24
26
|
|
|
25
27
|
@dataclass
|
|
@@ -34,6 +36,23 @@ class RunTracker:
|
|
|
34
36
|
class Executor(ABC):
|
|
35
37
|
"""Execute and monitor a Flower run."""
|
|
36
38
|
|
|
39
|
+
@abstractmethod
|
|
40
|
+
def initialize(
|
|
41
|
+
self, linkstate_factory: LinkStateFactory, ffs_factory: FfsFactory
|
|
42
|
+
) -> None:
|
|
43
|
+
"""Initialize the executor with the necessary factories.
|
|
44
|
+
|
|
45
|
+
This method sets up the executor by providing it with the factories required
|
|
46
|
+
to access the LinkState and the Flower File Storage (FFS) in the SuperLink.
|
|
47
|
+
|
|
48
|
+
Parameters
|
|
49
|
+
----------
|
|
50
|
+
linkstate_factory : LinkStateFactory
|
|
51
|
+
The factory to create access to the LinkState.
|
|
52
|
+
ffs_factory : FfsFactory
|
|
53
|
+
The factory to create access to the Flower File Storage (FFS).
|
|
54
|
+
"""
|
|
55
|
+
|
|
37
56
|
@abstractmethod
|
|
38
57
|
def set_config(
|
|
39
58
|
self,
|
flwr/superexec/simulation.py
CHANGED
|
@@ -29,6 +29,8 @@ from flwr.common.config import unflatten_dict
|
|
|
29
29
|
from flwr.common.constant import RUN_ID_NUM_BYTES
|
|
30
30
|
from flwr.common.logger import log
|
|
31
31
|
from flwr.common.typing import UserConfig
|
|
32
|
+
from flwr.server.superlink.ffs.ffs_factory import FfsFactory
|
|
33
|
+
from flwr.server.superlink.linkstate import LinkStateFactory
|
|
32
34
|
from flwr.server.superlink.linkstate.utils import generate_rand_int_from_bytes
|
|
33
35
|
|
|
34
36
|
from .executor import Executor, RunTracker
|
|
@@ -70,6 +72,12 @@ class SimulationEngine(Executor):
|
|
|
70
72
|
self.num_supernodes = num_supernodes
|
|
71
73
|
self.verbose = verbose
|
|
72
74
|
|
|
75
|
+
@override
|
|
76
|
+
def initialize(
|
|
77
|
+
self, linkstate_factory: LinkStateFactory, ffs_factory: FfsFactory
|
|
78
|
+
) -> None:
|
|
79
|
+
"""Initialize the executor with the necessary factories."""
|
|
80
|
+
|
|
73
81
|
@override
|
|
74
82
|
def set_config(
|
|
75
83
|
self,
|
{flwr_nightly-1.13.0.dev20241022.dist-info → flwr_nightly-1.13.0.dev20241024.dist-info}/RECORD
RENAMED
|
@@ -64,7 +64,7 @@ flwr/cli/run/__init__.py,sha256=oCd6HmQDx-sqver1gecgx-uMA38BLTSiiKpl7RGNceg,789
|
|
|
64
64
|
flwr/cli/run/run.py,sha256=NMCeDfImxta1VEeBqqkP05xsuBK6YWFTd7Qj_bIEA2Y,8394
|
|
65
65
|
flwr/cli/utils.py,sha256=emMUdthvoHBTB0iGQp-oFBmA5wV46lw3y3FmfXQPCsc,4500
|
|
66
66
|
flwr/client/__init__.py,sha256=DGDoO0AEAfz-0CUFmLdyUUweAS64-07AOnmDfWUefK4,1192
|
|
67
|
-
flwr/client/app.py,sha256=
|
|
67
|
+
flwr/client/app.py,sha256=fEUTXz_uNwZe-otCbUf5F3sJozGfvkrMNS3u7DE6sOo,32808
|
|
68
68
|
flwr/client/client.py,sha256=gy6WVlMUFAp8oevN4xpQPX30vPOIYGVqdbuFlTWkyG4,9080
|
|
69
69
|
flwr/client/client_app.py,sha256=cTig-N00YzTucbo9zNi6I21J8PlbflU_8J_f5CI-Wpw,10390
|
|
70
70
|
flwr/client/clientapp/__init__.py,sha256=kZqChGnTChQ1WGSUkIlW2S5bc0d0mzDubCAmZUGRpEY,800
|
|
@@ -92,18 +92,17 @@ flwr/client/mod/secure_aggregation/__init__.py,sha256=A7DzZ3uvXTUkuHBzrxJMWQQD4R
|
|
|
92
92
|
flwr/client/mod/secure_aggregation/secagg_mod.py,sha256=wI9tuIEvMUETz-wVIEbPYvh-1nK9CEylBLGoVpNhL94,1095
|
|
93
93
|
flwr/client/mod/secure_aggregation/secaggplus_mod.py,sha256=7cNXsY07ZA0M5_9VSc52F8JUoAoGaraNDA2rgaLvvFo,19680
|
|
94
94
|
flwr/client/mod/utils.py,sha256=dFcTHOjUuuiw34fcQlvyzytYD0sCv1w9x8fQX1Yo8Oc,1201
|
|
95
|
-
flwr/client/node_state_tests.py,sha256=28HzAxcxF-mhzPisJMCUczrLz1KfxtTkKZ5tvQgq-gM,2291
|
|
96
95
|
flwr/client/numpy_client.py,sha256=tqGyhIkeeZQGr65BR03B7TWgx4rW3FA7G2874D8z_VU,11167
|
|
97
96
|
flwr/client/rest_client/__init__.py,sha256=5KGlp7pjc1dhNRkKlaNtUfQmg8wrRFh9lS3P3uRS-7Q,735
|
|
98
97
|
flwr/client/rest_client/connection.py,sha256=k-RqgUFqidACAGlMFPIUM8aawXI5h2LvKUri2OAK7Bg,12817
|
|
99
98
|
flwr/client/run_info_store.py,sha256=SKpvq8vvNJgB7LDd-DLMndH99kNRztg2UXvnMh8fOEU,4005
|
|
100
99
|
flwr/client/supernode/__init__.py,sha256=SUhWOzcgXRNXk1V9UgB5-FaWukqqrOEajVUHEcPkwyQ,865
|
|
101
|
-
flwr/client/supernode/app.py,sha256=
|
|
100
|
+
flwr/client/supernode/app.py,sha256=JN24tRBHLbFJ0KeCTA8eS24KUJHCl9J2xGwWjyPQ7Vg,12239
|
|
102
101
|
flwr/client/typing.py,sha256=dxoTBnTMfqXr5J7G3y-uNjqxYCddvxhu89spfj4Lm2U,1048
|
|
103
102
|
flwr/common/__init__.py,sha256=TVaoFEJE158aui1TPZQiJCDZX4RNHRyI8I55VC80HhI,3901
|
|
104
103
|
flwr/common/address.py,sha256=7kM2Rqjw86-c8aKwAvrXerWqznnVv4TFJ62aSAeTn10,3017
|
|
105
104
|
flwr/common/config.py,sha256=nYA1vjiiqSWx5JjSdlQd1i_0N_Dh9kEGUse1Qze3JMs,7803
|
|
106
|
-
flwr/common/constant.py,sha256=
|
|
105
|
+
flwr/common/constant.py,sha256=iv2O8vQdrIqsGy-RFluRDd0R0oaqWO046KPm14yPzw0,4376
|
|
107
106
|
flwr/common/context.py,sha256=5Bd9RCrhLkYZOVR7vr97OVhzVBHQkS1fUsYiIKTwpxU,2239
|
|
108
107
|
flwr/common/date.py,sha256=OcQuwpb2HxcblTqYm6H223ufop5UZw5N_fzalbpOVzY,891
|
|
109
108
|
flwr/common/differential_privacy.py,sha256=XwcJ3rWr8S8BZUocc76vLSJAXIf6OHnWkBV6-xlIRuw,6106
|
|
@@ -135,7 +134,7 @@ flwr/common/secure_aggregation/secaggplus_constants.py,sha256=9MF-oQh62uD7rt9VeN
|
|
|
135
134
|
flwr/common/secure_aggregation/secaggplus_utils.py,sha256=o7IhHH6J9xqinhQy3TdPgQpoj1XyEpyv3OQFyx81RVQ,3193
|
|
136
135
|
flwr/common/serde.py,sha256=74nN5uqASdqfykSWPOhaTJARA07Iznyg3Nyr-dh-uy4,29918
|
|
137
136
|
flwr/common/telemetry.py,sha256=PvdlipCPYciqEgmXRwQ1HklP1uyECcNqt9HTBzthmAg,8904
|
|
138
|
-
flwr/common/typing.py,sha256=
|
|
137
|
+
flwr/common/typing.py,sha256=fS_KmVdg0c1B87yMnccIPfjBzQ3CTRwYJcaWfmvZzEA,5103
|
|
139
138
|
flwr/common/version.py,sha256=tCcl_FvxVK206C1dxIJCs4TjL06WmyaODBP19FRHE1c,1324
|
|
140
139
|
flwr/proto/__init__.py,sha256=hbY7JYakwZwCkYgCNlmHdc8rtvfoJbAZLalMdc--CGc,683
|
|
141
140
|
flwr/proto/clientappio_pb2.py,sha256=Y3PMv-JMaBGehpslgbvGY6l2u5vNpfCTFWu-fmAmBJ4,3703
|
|
@@ -150,10 +149,10 @@ flwr/proto/control_pb2.py,sha256=yaUkwY2J9uo-fdUIB5aHwVSDOuGunxaUr4ZlggifA_M,143
|
|
|
150
149
|
flwr/proto/control_pb2.pyi,sha256=XbFvpZvvrS7QcH5AFXfpRGl4hQvhd3QdKO6x0oTlCCU,165
|
|
151
150
|
flwr/proto/control_pb2_grpc.py,sha256=FFE21nZvEILWpe1WCR5vAwgYEtpzrdG78-_SsU0gZ7w,5783
|
|
152
151
|
flwr/proto/control_pb2_grpc.pyi,sha256=9DU4sgkzJ497a4Nq6kitZWEG4g_5MO8MevichnO0oAg,1672
|
|
153
|
-
flwr/proto/driver_pb2.py,sha256=
|
|
154
|
-
flwr/proto/driver_pb2.pyi,sha256=
|
|
155
|
-
flwr/proto/driver_pb2_grpc.py,sha256=
|
|
156
|
-
flwr/proto/driver_pb2_grpc.pyi,sha256=
|
|
152
|
+
flwr/proto/driver_pb2.py,sha256=8WmaJ3F5iPuHeiFkfkf_9Pa86qgoUYLPaIL-9igdcIk,4528
|
|
153
|
+
flwr/proto/driver_pb2.pyi,sha256=Mq4xZ5Hn55CrUVLu4kvNZylKtF9AQ9NomOv1qJ3Py4Q,6636
|
|
154
|
+
flwr/proto/driver_pb2_grpc.py,sha256=KgJNfvIkTX4z3u9jU05z3GvyCx39cQ1r_OgiD3zoinw,13886
|
|
155
|
+
flwr/proto/driver_pb2_grpc.pyi,sha256=_aiUW3TsX1jPL7WqdUhiAPK_6bK8Cv5Flo_SntmlL44,3766
|
|
157
156
|
flwr/proto/error_pb2.py,sha256=LarjKL90LbwkXKlhzNrDssgl4DXcvIPve8NVCXHpsKA,1084
|
|
158
157
|
flwr/proto/error_pb2.pyi,sha256=ZNH4HhJTU_KfMXlyCeg8FwU-fcUYxTqEmoJPtWtHikc,734
|
|
159
158
|
flwr/proto/error_pb2_grpc.py,sha256=1oboBPFxaTEXt9Aw7EAj8gXHDCNMhZD2VXqocC9l_gk,159
|
|
@@ -200,7 +199,7 @@ flwr/proto/transport_pb2_grpc.py,sha256=vLN3EHtx2aEEMCO4f1Upu-l27BPzd3-5pV-u8wPc
|
|
|
200
199
|
flwr/proto/transport_pb2_grpc.pyi,sha256=AGXf8RiIiW2J5IKMlm_3qT3AzcDa4F3P5IqUjve_esA,766
|
|
201
200
|
flwr/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
202
201
|
flwr/server/__init__.py,sha256=cEg1oecBu4cKB69iJCqWEylC8b5XW47bl7rQiJsdTvM,1528
|
|
203
|
-
flwr/server/app.py,sha256=
|
|
202
|
+
flwr/server/app.py,sha256=p3uTuj4tIRK67d6FCyNIwEVKkfhZBIuuhZt86gDqmv8,28315
|
|
204
203
|
flwr/server/client_manager.py,sha256=7Ese0tgrH-i-ms363feYZJKwB8gWnXSmg_hYF2Bju4U,6227
|
|
205
204
|
flwr/server/client_proxy.py,sha256=4G-oTwhb45sfWLx2uZdcXD98IZwdTS6F88xe3akCdUg,2399
|
|
206
205
|
flwr/server/compat/__init__.py,sha256=VxnJtJyOjNFQXMNi9hIuzNlZM5n0Hj1p3aq_Pm2udw4,892
|
|
@@ -214,12 +213,12 @@ flwr/server/driver/driver.py,sha256=KpLrWeF0zP9HBdo_mucPlNVj5eS0K8DDHRRY_58E1BM,
|
|
|
214
213
|
flwr/server/driver/grpc_driver.py,sha256=AhkqfXBSv8TnqBGxqj1nhkOxp6HVU0WaJq4YlqIz8Hw,9687
|
|
215
214
|
flwr/server/driver/inmemory_driver.py,sha256=7gw1zRgNvmy2FWCEOMs8udpc2HQsxURrIwbpKv5VyoE,6656
|
|
216
215
|
flwr/server/history.py,sha256=qSb5_pPTrwofpSYGsZWzMPkl_4uJ4mJFWesxXDrEvDU,5026
|
|
217
|
-
flwr/server/run_serverapp.py,sha256=
|
|
216
|
+
flwr/server/run_serverapp.py,sha256=_i0kBRrSzeR4-DDswysoWYertdAq7-LfrSAJ2n-GB8Q,10530
|
|
218
217
|
flwr/server/server.py,sha256=1ZsFEptmAV-L2vP2etNC9Ed5CLSxpuKzUFkAPQ4l5Xc,17893
|
|
219
218
|
flwr/server/server_app.py,sha256=RsgS6PRS5Z74cMUAHzsm8r3LWddwn00MjRs6rlacHt8,6297
|
|
220
219
|
flwr/server/server_config.py,sha256=CZaHVAsMvGLjpWVcLPkiYxgJN4xfIyAiUrCI3fETKY4,1349
|
|
221
220
|
flwr/server/serverapp/__init__.py,sha256=L0K-94UDdTyEZ8LDtYybGIIIv3HW6AhSVjXMUfYJQnQ,800
|
|
222
|
-
flwr/server/serverapp/app.py,sha256=
|
|
221
|
+
flwr/server/serverapp/app.py,sha256=qrkJVCORJbDQN0I5JR_7t26GGwLLlApELQBWdbgButo,2353
|
|
223
222
|
flwr/server/serverapp_components.py,sha256=-IV_CitOfrJclJj2jNdbN1Q65PyFmtKtrTIg1hc6WQw,2118
|
|
224
223
|
flwr/server/strategy/__init__.py,sha256=tQer2SwjDnvgFFuJMZM-S01Z615N5XK6MaCvpm4BMU0,2836
|
|
225
224
|
flwr/server/strategy/aggregate.py,sha256=iFZ8lp7PV_a2m9kywV-FK0iM33ofxavOs5TIaEQY8nU,13961
|
|
@@ -248,7 +247,7 @@ flwr/server/strategy/strategy.py,sha256=cXapkD5uDrt5C-RbmWDn9FLoap3Q41i7GKvbmfbC
|
|
|
248
247
|
flwr/server/superlink/__init__.py,sha256=8tHYCfodUlRD8PCP9fHgvu8cz5N31A2QoRVL0jDJ15E,707
|
|
249
248
|
flwr/server/superlink/driver/__init__.py,sha256=_JaRW-FdyikHc7souUrnk3mwTGViraEJCeUBY_M_ocs,712
|
|
250
249
|
flwr/server/superlink/driver/driver_grpc.py,sha256=melAgaV37Y0B9bZe5bRWQOobItZZ9DIzlcbVE8B01wo,2060
|
|
251
|
-
flwr/server/superlink/driver/driver_servicer.py,sha256
|
|
250
|
+
flwr/server/superlink/driver/driver_servicer.py,sha256=hA997-qPu9RxLFsiK-Jn4tDv7VZFHz1ayv5a4cOZGsA,7601
|
|
252
251
|
flwr/server/superlink/ffs/__init__.py,sha256=FAY-zShcfPmOxosok2QyT6hTNMNctG8cH9s_nIl8jkI,840
|
|
253
252
|
flwr/server/superlink/ffs/disk_ffs.py,sha256=yCN6CCzegnJIOaHr5nIu49wZQa4g5BByiSKshz50RKU,3296
|
|
254
253
|
flwr/server/superlink/ffs/ffs.py,sha256=qLI1UfosJugu2BKOJWqHIhafTm-YiuKqGf3OGWPH0NM,2395
|
|
@@ -274,11 +273,11 @@ flwr/server/superlink/fleet/vce/backend/backend.py,sha256=LBAQxnbfPAphVOVIvYMj0Q
|
|
|
274
273
|
flwr/server/superlink/fleet/vce/backend/raybackend.py,sha256=7kB3re3mR53b7E6L6DPSioTSKD3YGtS3uJsPD7Hn2Fw,7155
|
|
275
274
|
flwr/server/superlink/fleet/vce/vce_api.py,sha256=VL6e_Jwf4uxA-X1EelxJZMv6Eji-_p2J9D0MdHG10a4,13029
|
|
276
275
|
flwr/server/superlink/linkstate/__init__.py,sha256=v-2JyJlCB3qyhMNwMjmcNVOq4rkooqFU0LHH8Zo1jls,1064
|
|
277
|
-
flwr/server/superlink/linkstate/in_memory_linkstate.py,sha256=
|
|
278
|
-
flwr/server/superlink/linkstate/linkstate.py,sha256=
|
|
276
|
+
flwr/server/superlink/linkstate/in_memory_linkstate.py,sha256=guqspi2WYyAXZKIxXCApuJZsuraNEVvb7aredtlXzRw,19327
|
|
277
|
+
flwr/server/superlink/linkstate/linkstate.py,sha256=A0LCOH0xpq9_mTPrO1LB0MDWKhfUcOSnkKeC3-AeFHU,10256
|
|
279
278
|
flwr/server/superlink/linkstate/linkstate_factory.py,sha256=ISSMjDlwuN7swxjOeYlTNpI_kuZ8PGkMcJnf1dbhUSE,2069
|
|
280
|
-
flwr/server/superlink/linkstate/sqlite_linkstate.py,sha256
|
|
281
|
-
flwr/server/superlink/linkstate/utils.py,sha256=
|
|
279
|
+
flwr/server/superlink/linkstate/sqlite_linkstate.py,sha256=JhP6DtM0xBYtT0B0b1lwy96fY6i_C_Zm6Iq_t3VVQ5o,41245
|
|
280
|
+
flwr/server/superlink/linkstate/utils.py,sha256=ukrMlSv0mNFd0YSpyPDpq_ND90SBkwuKgw3FFux3lqs,6914
|
|
282
281
|
flwr/server/typing.py,sha256=5kaRLZuxTEse9A0g7aVna2VhYxU3wTq1f3d3mtw7kXs,1019
|
|
283
282
|
flwr/server/utils/__init__.py,sha256=pltsPHJoXmUIr3utjwwYxu7_ZAGy5u4MVHzv9iA5Un8,908
|
|
284
283
|
flwr/server/utils/tensorboard.py,sha256=gEBD8w_5uaIfp5aw5RYH66lYZpd_SfkObHQ7eDd9MUk,5466
|
|
@@ -295,16 +294,16 @@ flwr/simulation/ray_transport/__init__.py,sha256=wzcEEwUUlulnXsg6raCA1nGpP3LlAQD
|
|
|
295
294
|
flwr/simulation/ray_transport/ray_actor.py,sha256=9-XBguAm5IFqm2ddPFsQtnuuFN6lzqdb00SnCxGUGBo,18996
|
|
296
295
|
flwr/simulation/ray_transport/ray_client_proxy.py,sha256=2vjOKoom3B74C6XU-jC3N6DwYmsLdB-lmkHZ_Xrv96o,7367
|
|
297
296
|
flwr/simulation/ray_transport/utils.py,sha256=TYdtfg1P9VfTdLMOJlifInGpxWHYs9UfUqIv2wfkRLA,2392
|
|
298
|
-
flwr/simulation/run_simulation.py,sha256=
|
|
297
|
+
flwr/simulation/run_simulation.py,sha256=nVLoP5rzH3bmZQ-pW9Nka2m0M1pFIEFODtIY7nHY0jQ,23412
|
|
299
298
|
flwr/superexec/__init__.py,sha256=fcj366jh4RFby_vDwLroU4kepzqbnJgseZD_jUr_Mko,715
|
|
300
|
-
flwr/superexec/app.py,sha256=
|
|
301
|
-
flwr/superexec/deployment.py,sha256=
|
|
302
|
-
flwr/superexec/exec_grpc.py,sha256=
|
|
303
|
-
flwr/superexec/exec_servicer.py,sha256=
|
|
304
|
-
flwr/superexec/executor.py,sha256
|
|
305
|
-
flwr/superexec/simulation.py,sha256=
|
|
306
|
-
flwr_nightly-1.13.0.
|
|
307
|
-
flwr_nightly-1.13.0.
|
|
308
|
-
flwr_nightly-1.13.0.
|
|
309
|
-
flwr_nightly-1.13.0.
|
|
310
|
-
flwr_nightly-1.13.0.
|
|
299
|
+
flwr/superexec/app.py,sha256=Tt3GonnTwHrMmicwx9XaP-crP78-bf4DUWl-N5cG6zY,1841
|
|
300
|
+
flwr/superexec/deployment.py,sha256=3uAauE8mI4bHwVF4_Rp26mXy18QnnIRlQD_yDo_Xs00,6780
|
|
301
|
+
flwr/superexec/exec_grpc.py,sha256=OuhBAk7hiky9rjGceinLGIXqchtzGPQThZnwyYv6Ei0,2241
|
|
302
|
+
flwr/superexec/exec_servicer.py,sha256=9MdFODQkLK_942XwaqwwIi1OP0Tiv3Mh7smj4mbreBE,5124
|
|
303
|
+
flwr/superexec/executor.py,sha256=125FvdpjT_awBCREm_YkLMg0YgToarVg7Y3wPt5tXQA,3126
|
|
304
|
+
flwr/superexec/simulation.py,sha256=PGADPXcfFVOss4uwPvFq_6vrIlkxezHppnBPAYWUBuU,7739
|
|
305
|
+
flwr_nightly-1.13.0.dev20241024.dist-info/LICENSE,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
|
|
306
|
+
flwr_nightly-1.13.0.dev20241024.dist-info/METADATA,sha256=qKxbod-8iSCiu3FrCRwd9YDAZTsOl6yfqP7Ty4HVf7A,15618
|
|
307
|
+
flwr_nightly-1.13.0.dev20241024.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
|
|
308
|
+
flwr_nightly-1.13.0.dev20241024.dist-info/entry_points.txt,sha256=FxJQ96pmcNF2OvkTH6XF-Ip2PNrHvykjArkvkjQC7Mk,486
|
|
309
|
+
flwr_nightly-1.13.0.dev20241024.dist-info/RECORD,,
|
flwr/client/node_state_tests.py
DELETED
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
# Copyright 2023 Flower Labs GmbH. All Rights Reserved.
|
|
2
|
-
#
|
|
3
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
-
# you may not use this file except in compliance with the License.
|
|
5
|
-
# You may obtain a copy of the License at
|
|
6
|
-
#
|
|
7
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
-
#
|
|
9
|
-
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
-
# See the License for the specific language governing permissions and
|
|
13
|
-
# limitations under the License.
|
|
14
|
-
# ==============================================================================
|
|
15
|
-
"""Node state tests."""
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
from typing import cast
|
|
19
|
-
|
|
20
|
-
from flwr.client.run_info_store import DeprecatedRunInfoStore
|
|
21
|
-
from flwr.common import ConfigsRecord, Context
|
|
22
|
-
from flwr.proto.task_pb2 import TaskIns # pylint: disable=E0611
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
def _run_dummy_task(context: Context) -> Context:
|
|
26
|
-
counter_value: str = "1"
|
|
27
|
-
if "counter" in context.state.configs_records.keys():
|
|
28
|
-
counter_value = cast(str, context.state.configs_records["counter"]["count"])
|
|
29
|
-
counter_value += "1"
|
|
30
|
-
|
|
31
|
-
context.state.configs_records["counter"] = ConfigsRecord({"count": counter_value})
|
|
32
|
-
|
|
33
|
-
return context
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
def test_multirun_in_node_state() -> None:
|
|
37
|
-
"""Test basic DeprecatedRunInfoStore logic."""
|
|
38
|
-
# Tasks to perform
|
|
39
|
-
tasks = [TaskIns(run_id=run_id) for run_id in [0, 1, 1, 2, 3, 2, 1, 5]]
|
|
40
|
-
# the "tasks" is to count how many times each run is executed
|
|
41
|
-
expected_values = {0: "1", 1: "1" * 3, 2: "1" * 2, 3: "1", 5: "1"}
|
|
42
|
-
|
|
43
|
-
node_info_store = DeprecatedRunInfoStore(node_id=0, node_config={})
|
|
44
|
-
|
|
45
|
-
for task in tasks:
|
|
46
|
-
run_id = task.run_id
|
|
47
|
-
|
|
48
|
-
# Register
|
|
49
|
-
node_info_store.register_context(run_id=run_id)
|
|
50
|
-
|
|
51
|
-
# Get run state
|
|
52
|
-
context = node_info_store.retrieve_context(run_id=run_id)
|
|
53
|
-
|
|
54
|
-
# Run "task"
|
|
55
|
-
updated_state = _run_dummy_task(context)
|
|
56
|
-
|
|
57
|
-
# Update run state
|
|
58
|
-
node_info_store.update_context(run_id=run_id, context=updated_state)
|
|
59
|
-
|
|
60
|
-
# Verify values
|
|
61
|
-
for run_id, run_info in node_info_store.run_infos.items():
|
|
62
|
-
assert (
|
|
63
|
-
run_info.context.state.configs_records["counter"]["count"]
|
|
64
|
-
== expected_values[run_id]
|
|
65
|
-
)
|
{flwr_nightly-1.13.0.dev20241022.dist-info → flwr_nightly-1.13.0.dev20241024.dist-info}/LICENSE
RENAMED
|
File without changes
|
{flwr_nightly-1.13.0.dev20241022.dist-info → flwr_nightly-1.13.0.dev20241024.dist-info}/WHEEL
RENAMED
|
File without changes
|