flwr-nightly 1.7.0.dev20240124__py3-none-any.whl → 1.7.0.dev20240126__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.
- flwr/client/app.py +5 -5
- flwr/client/client.py +8 -8
- flwr/client/flower.py +3 -3
- flwr/client/message_handler/message_handler.py +15 -15
- flwr/client/node_state.py +16 -15
- flwr/client/node_state_tests.py +18 -13
- flwr/client/numpy_client.py +16 -16
- flwr/client/typing.py +3 -3
- flwr/{client/run_state.py → common/context.py} +19 -6
- flwr/common/{flowercontext.py → message.py} +6 -19
- flwr/common/recordset_compat.py +22 -14
- flwr/common/serde.py +79 -7
- flwr/simulation/ray_transport/ray_actor.py +19 -19
- flwr/simulation/ray_transport/ray_client_proxy.py +4 -4
- {flwr_nightly-1.7.0.dev20240124.dist-info → flwr_nightly-1.7.0.dev20240126.dist-info}/METADATA +2 -1
- {flwr_nightly-1.7.0.dev20240124.dist-info → flwr_nightly-1.7.0.dev20240126.dist-info}/RECORD +19 -19
- {flwr_nightly-1.7.0.dev20240124.dist-info → flwr_nightly-1.7.0.dev20240126.dist-info}/LICENSE +0 -0
- {flwr_nightly-1.7.0.dev20240124.dist-info → flwr_nightly-1.7.0.dev20240126.dist-info}/WHEEL +0 -0
- {flwr_nightly-1.7.0.dev20240124.dist-info → flwr_nightly-1.7.0.dev20240126.dist-info}/entry_points.txt +0 -0
flwr/client/app.py
CHANGED
@@ -352,7 +352,7 @@ def _start_client_internal(
|
|
352
352
|
break
|
353
353
|
|
354
354
|
# Register state
|
355
|
-
node_state.
|
355
|
+
node_state.register_context(run_id=task_ins.run_id)
|
356
356
|
|
357
357
|
# Load app
|
358
358
|
app: Flower = load_flower_callable_fn()
|
@@ -360,14 +360,14 @@ def _start_client_internal(
|
|
360
360
|
# Handle task message
|
361
361
|
fwd_msg: Fwd = Fwd(
|
362
362
|
task_ins=task_ins,
|
363
|
-
|
363
|
+
context=node_state.retrieve_context(run_id=task_ins.run_id),
|
364
364
|
)
|
365
365
|
bwd_msg: Bwd = app(fwd=fwd_msg)
|
366
366
|
|
367
367
|
# Update node state
|
368
|
-
node_state.
|
369
|
-
run_id=
|
370
|
-
|
368
|
+
node_state.update_context(
|
369
|
+
run_id=fwd_msg.task_ins.run_id,
|
370
|
+
context=bwd_msg.context,
|
371
371
|
)
|
372
372
|
|
373
373
|
# Send
|
flwr/client/client.py
CHANGED
@@ -19,7 +19,6 @@ from __future__ import annotations
|
|
19
19
|
|
20
20
|
from abc import ABC
|
21
21
|
|
22
|
-
from flwr.client.run_state import RunState
|
23
22
|
from flwr.common import (
|
24
23
|
Code,
|
25
24
|
EvaluateIns,
|
@@ -33,12 +32,13 @@ from flwr.common import (
|
|
33
32
|
Parameters,
|
34
33
|
Status,
|
35
34
|
)
|
35
|
+
from flwr.common.context import Context
|
36
36
|
|
37
37
|
|
38
38
|
class Client(ABC):
|
39
39
|
"""Abstract base class for Flower clients."""
|
40
40
|
|
41
|
-
|
41
|
+
context: Context
|
42
42
|
|
43
43
|
def get_properties(self, ins: GetPropertiesIns) -> GetPropertiesRes:
|
44
44
|
"""Return set of client's properties.
|
@@ -141,13 +141,13 @@ class Client(ABC):
|
|
141
141
|
metrics={},
|
142
142
|
)
|
143
143
|
|
144
|
-
def
|
145
|
-
"""Get the run
|
146
|
-
return self.
|
144
|
+
def get_context(self) -> Context:
|
145
|
+
"""Get the run context from this client."""
|
146
|
+
return self.context
|
147
147
|
|
148
|
-
def
|
149
|
-
"""Apply a run
|
150
|
-
self.
|
148
|
+
def set_context(self, context: Context) -> None:
|
149
|
+
"""Apply a run context to this client."""
|
150
|
+
self.context = context
|
151
151
|
|
152
152
|
def to_client(self) -> Client:
|
153
153
|
"""Return client (itself)."""
|
flwr/client/flower.py
CHANGED
@@ -56,12 +56,12 @@ class Flower:
|
|
56
56
|
) -> None:
|
57
57
|
# Create wrapper function for `handle`
|
58
58
|
def ffn(fwd: Fwd) -> Bwd: # pylint: disable=invalid-name
|
59
|
-
task_res,
|
59
|
+
task_res, context_updated = handle(
|
60
60
|
client_fn=client_fn,
|
61
|
-
|
61
|
+
context=fwd.context,
|
62
62
|
task_ins=fwd.task_ins,
|
63
63
|
)
|
64
|
-
return Bwd(task_res=task_res,
|
64
|
+
return Bwd(task_res=task_res, context=context_updated)
|
65
65
|
|
66
66
|
# Wrap middleware layers around the wrapped handle function
|
67
67
|
self._call = make_ffn(ffn, layers if layers is not None else [])
|
@@ -28,10 +28,10 @@ from flwr.client.message_handler.task_handler import (
|
|
28
28
|
get_server_message_from_task_ins,
|
29
29
|
wrap_client_message_in_task_res,
|
30
30
|
)
|
31
|
-
from flwr.client.run_state import RunState
|
32
31
|
from flwr.client.secure_aggregation import SecureAggregationHandler
|
33
32
|
from flwr.client.typing import ClientFn
|
34
33
|
from flwr.common import serde
|
34
|
+
from flwr.common.context import Context
|
35
35
|
from flwr.proto.task_pb2 import ( # pylint: disable=E0611
|
36
36
|
SecureAggregation,
|
37
37
|
Task,
|
@@ -88,16 +88,16 @@ def handle_control_message(task_ins: TaskIns) -> Tuple[Optional[TaskRes], int]:
|
|
88
88
|
|
89
89
|
|
90
90
|
def handle(
|
91
|
-
client_fn: ClientFn,
|
92
|
-
) -> Tuple[TaskRes,
|
91
|
+
client_fn: ClientFn, context: Context, task_ins: TaskIns
|
92
|
+
) -> Tuple[TaskRes, Context]:
|
93
93
|
"""Handle incoming TaskIns from the server.
|
94
94
|
|
95
95
|
Parameters
|
96
96
|
----------
|
97
97
|
client_fn : ClientFn
|
98
98
|
A callable that instantiates a Client.
|
99
|
-
|
100
|
-
A dataclass storing the
|
99
|
+
context : Context
|
100
|
+
A dataclass storing the context for the run being executed by the client.
|
101
101
|
task_ins: TaskIns
|
102
102
|
The task instruction coming from the server, to be processed by the client.
|
103
103
|
|
@@ -110,7 +110,7 @@ def handle(
|
|
110
110
|
if server_msg is None:
|
111
111
|
# Instantiate the client
|
112
112
|
client = client_fn("-1")
|
113
|
-
client.
|
113
|
+
client.set_context(context)
|
114
114
|
# Secure Aggregation
|
115
115
|
if task_ins.task.HasField("sa") and isinstance(
|
116
116
|
client, SecureAggregationHandler
|
@@ -127,24 +127,24 @@ def handle(
|
|
127
127
|
sa=SecureAggregation(named_values=serde.named_values_to_proto(res)),
|
128
128
|
),
|
129
129
|
)
|
130
|
-
return task_res, client.
|
130
|
+
return task_res, client.get_context()
|
131
131
|
raise NotImplementedError()
|
132
|
-
client_msg,
|
132
|
+
client_msg, updated_context = handle_legacy_message(client_fn, context, server_msg)
|
133
133
|
task_res = wrap_client_message_in_task_res(client_msg)
|
134
|
-
return task_res,
|
134
|
+
return task_res, updated_context
|
135
135
|
|
136
136
|
|
137
137
|
def handle_legacy_message(
|
138
|
-
client_fn: ClientFn,
|
139
|
-
) -> Tuple[ClientMessage,
|
138
|
+
client_fn: ClientFn, context: Context, server_msg: ServerMessage
|
139
|
+
) -> Tuple[ClientMessage, Context]:
|
140
140
|
"""Handle incoming messages from the server.
|
141
141
|
|
142
142
|
Parameters
|
143
143
|
----------
|
144
144
|
client_fn : ClientFn
|
145
145
|
A callable that instantiates a Client.
|
146
|
-
|
147
|
-
A dataclass storing the
|
146
|
+
context : Context
|
147
|
+
A dataclass storing the context for the run being executed by the client.
|
148
148
|
server_msg: ServerMessage
|
149
149
|
The message coming from the server, to be processed by the client.
|
150
150
|
|
@@ -161,7 +161,7 @@ def handle_legacy_message(
|
|
161
161
|
|
162
162
|
# Instantiate the client
|
163
163
|
client = client_fn("-1")
|
164
|
-
client.
|
164
|
+
client.set_context(context)
|
165
165
|
# Execute task
|
166
166
|
message = None
|
167
167
|
if field == "get_properties_ins":
|
@@ -173,7 +173,7 @@ def handle_legacy_message(
|
|
173
173
|
if field == "evaluate_ins":
|
174
174
|
message = _evaluate(client, server_msg.evaluate_ins)
|
175
175
|
if message:
|
176
|
-
return message, client.
|
176
|
+
return message, client.get_context()
|
177
177
|
raise UnknownServerMessage()
|
178
178
|
|
179
179
|
|
flwr/client/node_state.py
CHANGED
@@ -17,7 +17,8 @@
|
|
17
17
|
|
18
18
|
from typing import Any, Dict
|
19
19
|
|
20
|
-
from flwr.
|
20
|
+
from flwr.common.context import Context
|
21
|
+
from flwr.common.recordset import RecordSet
|
21
22
|
|
22
23
|
|
23
24
|
class NodeState:
|
@@ -25,24 +26,24 @@ class NodeState:
|
|
25
26
|
|
26
27
|
def __init__(self) -> None:
|
27
28
|
self._meta: Dict[str, Any] = {} # holds metadata about the node
|
28
|
-
self.
|
29
|
+
self.run_contexts: Dict[int, Context] = {}
|
29
30
|
|
30
|
-
def
|
31
|
-
"""Register new run
|
32
|
-
if run_id not in self.
|
33
|
-
self.
|
31
|
+
def register_context(self, run_id: int) -> None:
|
32
|
+
"""Register new run context for this node."""
|
33
|
+
if run_id not in self.run_contexts:
|
34
|
+
self.run_contexts[run_id] = Context(state=RecordSet())
|
34
35
|
|
35
|
-
def
|
36
|
-
"""Get run
|
37
|
-
if run_id in self.
|
38
|
-
return self.
|
36
|
+
def retrieve_context(self, run_id: int) -> Context:
|
37
|
+
"""Get run context given a run_id."""
|
38
|
+
if run_id in self.run_contexts:
|
39
|
+
return self.run_contexts[run_id]
|
39
40
|
|
40
41
|
raise RuntimeError(
|
41
|
-
f"
|
42
|
-
" A run must be registered before it can be retrieved or updated "
|
42
|
+
f"Context for run_id={run_id} doesn't exist."
|
43
|
+
" A run context must be registered before it can be retrieved or updated "
|
43
44
|
" by a client."
|
44
45
|
)
|
45
46
|
|
46
|
-
def
|
47
|
-
"""Update run
|
48
|
-
self.
|
47
|
+
def update_context(self, run_id: int, context: Context) -> None:
|
48
|
+
"""Update run context."""
|
49
|
+
self.run_contexts[run_id] = context
|
flwr/client/node_state_tests.py
CHANGED
@@ -16,17 +16,22 @@
|
|
16
16
|
|
17
17
|
|
18
18
|
from flwr.client.node_state import NodeState
|
19
|
-
from flwr.
|
19
|
+
from flwr.common.configsrecord import ConfigsRecord
|
20
|
+
from flwr.common.context import Context
|
20
21
|
from flwr.proto.task_pb2 import TaskIns # pylint: disable=E0611
|
21
22
|
|
22
23
|
|
23
|
-
def _run_dummy_task(
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
24
|
+
def _run_dummy_task(context: Context) -> Context:
|
25
|
+
counter_value: str = "1"
|
26
|
+
if "counter" in context.state.configs.keys():
|
27
|
+
counter_value = context.get_configs("counter")["count"] # type: ignore
|
28
|
+
counter_value += "1"
|
28
29
|
|
29
|
-
|
30
|
+
context.state.set_configs(
|
31
|
+
name="counter", record=ConfigsRecord({"count": counter_value})
|
32
|
+
)
|
33
|
+
|
34
|
+
return context
|
30
35
|
|
31
36
|
|
32
37
|
def test_multirun_in_node_state() -> None:
|
@@ -43,17 +48,17 @@ def test_multirun_in_node_state() -> None:
|
|
43
48
|
run_id = task.run_id
|
44
49
|
|
45
50
|
# Register
|
46
|
-
node_state.
|
51
|
+
node_state.register_context(run_id=run_id)
|
47
52
|
|
48
53
|
# Get run state
|
49
|
-
|
54
|
+
context = node_state.retrieve_context(run_id=run_id)
|
50
55
|
|
51
56
|
# Run "task"
|
52
|
-
updated_state = _run_dummy_task(
|
57
|
+
updated_state = _run_dummy_task(context)
|
53
58
|
|
54
59
|
# Update run state
|
55
|
-
node_state.
|
60
|
+
node_state.update_context(run_id=run_id, context=updated_state)
|
56
61
|
|
57
62
|
# Verify values
|
58
|
-
for run_id,
|
59
|
-
assert state.
|
63
|
+
for run_id, context in node_state.run_contexts.items():
|
64
|
+
assert context.state.get_configs("counter")["count"] == expected_values[run_id]
|
flwr/client/numpy_client.py
CHANGED
@@ -19,7 +19,6 @@ from abc import ABC
|
|
19
19
|
from typing import Callable, Dict, Tuple
|
20
20
|
|
21
21
|
from flwr.client.client import Client
|
22
|
-
from flwr.client.run_state import RunState
|
23
22
|
from flwr.common import (
|
24
23
|
Config,
|
25
24
|
NDArrays,
|
@@ -27,6 +26,7 @@ from flwr.common import (
|
|
27
26
|
ndarrays_to_parameters,
|
28
27
|
parameters_to_ndarrays,
|
29
28
|
)
|
29
|
+
from flwr.common.context import Context
|
30
30
|
from flwr.common.typing import (
|
31
31
|
Code,
|
32
32
|
EvaluateIns,
|
@@ -70,7 +70,7 @@ Example
|
|
70
70
|
class NumPyClient(ABC):
|
71
71
|
"""Abstract base class for Flower clients using NumPy."""
|
72
72
|
|
73
|
-
|
73
|
+
context: Context
|
74
74
|
|
75
75
|
def get_properties(self, config: Config) -> Dict[str, Scalar]:
|
76
76
|
"""Return a client's set of properties.
|
@@ -174,13 +174,13 @@ class NumPyClient(ABC):
|
|
174
174
|
_ = (self, parameters, config)
|
175
175
|
return 0.0, 0, {}
|
176
176
|
|
177
|
-
def
|
178
|
-
"""Get the run
|
179
|
-
return self.
|
177
|
+
def get_context(self) -> Context:
|
178
|
+
"""Get the run context from this client."""
|
179
|
+
return self.context
|
180
180
|
|
181
|
-
def
|
182
|
-
"""Apply a run
|
183
|
-
self.
|
181
|
+
def set_context(self, context: Context) -> None:
|
182
|
+
"""Apply a run context to this client."""
|
183
|
+
self.context = context
|
184
184
|
|
185
185
|
def to_client(self) -> Client:
|
186
186
|
"""Convert to object to Client type and return it."""
|
@@ -278,21 +278,21 @@ def _evaluate(self: Client, ins: EvaluateIns) -> EvaluateRes:
|
|
278
278
|
)
|
279
279
|
|
280
280
|
|
281
|
-
def
|
282
|
-
"""Return
|
283
|
-
return self.numpy_client.
|
281
|
+
def _get_context(self: Client) -> Context:
|
282
|
+
"""Return context of underlying NumPyClient."""
|
283
|
+
return self.numpy_client.get_context() # type: ignore
|
284
284
|
|
285
285
|
|
286
|
-
def
|
287
|
-
"""Apply
|
288
|
-
self.numpy_client.
|
286
|
+
def _set_context(self: Client, context: Context) -> None:
|
287
|
+
"""Apply context to underlying NumPyClient."""
|
288
|
+
self.numpy_client.set_context(context) # type: ignore
|
289
289
|
|
290
290
|
|
291
291
|
def _wrap_numpy_client(client: NumPyClient) -> Client:
|
292
292
|
member_dict: Dict[str, Callable] = { # type: ignore
|
293
293
|
"__init__": _constructor,
|
294
|
-
"
|
295
|
-
"
|
294
|
+
"get_context": _get_context,
|
295
|
+
"set_context": _set_context,
|
296
296
|
}
|
297
297
|
|
298
298
|
# Add wrapper type methods (if overridden)
|
flwr/client/typing.py
CHANGED
@@ -17,7 +17,7 @@
|
|
17
17
|
from dataclasses import dataclass
|
18
18
|
from typing import Callable
|
19
19
|
|
20
|
-
from flwr.
|
20
|
+
from flwr.common.context import Context
|
21
21
|
from flwr.proto.task_pb2 import TaskIns, TaskRes # pylint: disable=E0611
|
22
22
|
|
23
23
|
from .client import Client as Client
|
@@ -28,7 +28,7 @@ class Fwd:
|
|
28
28
|
"""."""
|
29
29
|
|
30
30
|
task_ins: TaskIns
|
31
|
-
|
31
|
+
context: Context
|
32
32
|
|
33
33
|
|
34
34
|
@dataclass
|
@@ -36,7 +36,7 @@ class Bwd:
|
|
36
36
|
"""."""
|
37
37
|
|
38
38
|
task_res: TaskRes
|
39
|
-
|
39
|
+
context: Context
|
40
40
|
|
41
41
|
|
42
42
|
FlowerCallable = Callable[[Fwd], Bwd]
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright
|
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.
|
@@ -12,14 +12,27 @@
|
|
12
12
|
# See the License for the specific language governing permissions and
|
13
13
|
# limitations under the License.
|
14
14
|
# ==============================================================================
|
15
|
-
"""
|
15
|
+
"""Context."""
|
16
|
+
|
16
17
|
|
17
18
|
from dataclasses import dataclass
|
18
|
-
|
19
|
+
|
20
|
+
from .recordset import RecordSet
|
19
21
|
|
20
22
|
|
21
23
|
@dataclass
|
22
|
-
class
|
23
|
-
"""State of
|
24
|
+
class Context:
|
25
|
+
"""State of your run.
|
26
|
+
|
27
|
+
Parameters
|
28
|
+
----------
|
29
|
+
state : RecordSet
|
30
|
+
Holds records added by the entity in a given run and that will stay local.
|
31
|
+
This means that the data it holds will never leave the system it's running from.
|
32
|
+
This can be used as an intermediate storage or scratchpad when
|
33
|
+
executing middleware layers. It can also be used as a memory to access
|
34
|
+
at different points during the lifecycle of this entity (e.g. across
|
35
|
+
multiple rounds)
|
36
|
+
"""
|
24
37
|
|
25
|
-
state:
|
38
|
+
state: RecordSet
|
@@ -12,7 +12,7 @@
|
|
12
12
|
# See the License for the specific language governing permissions and
|
13
13
|
# limitations under the License.
|
14
14
|
# ==============================================================================
|
15
|
-
"""
|
15
|
+
"""Message."""
|
16
16
|
|
17
17
|
|
18
18
|
from dataclasses import dataclass
|
@@ -48,30 +48,17 @@ class Metadata:
|
|
48
48
|
|
49
49
|
|
50
50
|
@dataclass
|
51
|
-
class
|
51
|
+
class Message:
|
52
52
|
"""State of your application from the viewpoint of the entity using it.
|
53
53
|
|
54
54
|
Parameters
|
55
55
|
----------
|
56
|
-
in_message : RecordSet
|
57
|
-
Holds records sent by another entity (e.g. sent by the server-side
|
58
|
-
logic to a client, or vice-versa)
|
59
|
-
out_message : RecordSet
|
60
|
-
Holds records added by the current entity. This `RecordSet` will
|
61
|
-
be sent out (e.g. back to the server-side for aggregation of
|
62
|
-
parameter, or to the client to perform a certain task)
|
63
|
-
local : RecordSet
|
64
|
-
Holds record added by the current entity and that will stay local.
|
65
|
-
This means that the data it holds will never leave the system it's running from.
|
66
|
-
This can be used as an intermediate storage or scratchpad when
|
67
|
-
executing middleware layers. It can also be used as a memory to access
|
68
|
-
at different points during the lifecycle of this entity (e.g. across
|
69
|
-
multiple rounds)
|
70
56
|
metadata : Metadata
|
71
57
|
A dataclass including information about the task to be executed.
|
58
|
+
message : RecordSet
|
59
|
+
Holds records either sent by another entity (e.g. sent by the server-side
|
60
|
+
logic to a client, or vice-versa) or that will be sent to it.
|
72
61
|
"""
|
73
62
|
|
74
|
-
in_message: RecordSet
|
75
|
-
out_message: RecordSet
|
76
|
-
local: RecordSet
|
77
63
|
metadata: Metadata
|
64
|
+
message: RecordSet
|
flwr/common/recordset_compat.py
CHANGED
@@ -40,20 +40,22 @@ from .typing import (
|
|
40
40
|
|
41
41
|
|
42
42
|
def parametersrecord_to_parameters(
|
43
|
-
record: ParametersRecord, keep_input: bool
|
43
|
+
record: ParametersRecord, keep_input: bool
|
44
44
|
) -> Parameters:
|
45
45
|
"""Convert ParameterRecord to legacy Parameters.
|
46
46
|
|
47
|
-
|
47
|
+
Warnings
|
48
|
+
--------
|
49
|
+
Because `Arrays` in `ParametersRecord` encode more information of the
|
48
50
|
array-like or tensor-like data (e.g their datatype, shape) than `Parameters` it
|
49
51
|
might not be possible to reconstruct such data structures from `Parameters` objects
|
50
|
-
alone. Additional information or
|
52
|
+
alone. Additional information or metadata must be provided from elsewhere.
|
51
53
|
|
52
54
|
Parameters
|
53
55
|
----------
|
54
56
|
record : ParametersRecord
|
55
57
|
The record to be conveted into Parameters.
|
56
|
-
keep_input : bool
|
58
|
+
keep_input : bool
|
57
59
|
A boolean indicating whether entries in the record should be deleted from the
|
58
60
|
input dictionary immediately after adding them to the record.
|
59
61
|
"""
|
@@ -74,7 +76,7 @@ def parametersrecord_to_parameters(
|
|
74
76
|
|
75
77
|
|
76
78
|
def parameters_to_parametersrecord(
|
77
|
-
parameters: Parameters, keep_input: bool
|
79
|
+
parameters: Parameters, keep_input: bool
|
78
80
|
) -> ParametersRecord:
|
79
81
|
"""Convert legacy Parameters into a single ParametersRecord.
|
80
82
|
|
@@ -86,7 +88,7 @@ def parameters_to_parametersrecord(
|
|
86
88
|
----------
|
87
89
|
parameters : Parameters
|
88
90
|
Parameters object to be represented as a ParametersRecord.
|
89
|
-
keep_input : bool
|
91
|
+
keep_input : bool
|
90
92
|
A boolean indicating whether parameters should be deleted from the input
|
91
93
|
Parameters object (i.e. a list of serialized NumPy arrays) immediately after
|
92
94
|
adding them to the record.
|
@@ -96,17 +98,17 @@ def parameters_to_parametersrecord(
|
|
96
98
|
p_record = ParametersRecord()
|
97
99
|
|
98
100
|
num_arrays = len(parameters.tensors)
|
101
|
+
ordered_dict = OrderedDict()
|
99
102
|
for idx in range(num_arrays):
|
100
103
|
if keep_input:
|
101
104
|
tensor = parameters.tensors[idx]
|
102
105
|
else:
|
103
106
|
tensor = parameters.tensors.pop(0)
|
104
|
-
|
105
|
-
|
106
|
-
{str(idx): Array(data=tensor, dtype="", stype=tensor_type, shape=[])}
|
107
|
-
)
|
107
|
+
ordered_dict[str(idx)] = Array(
|
108
|
+
data=tensor, dtype="", stype=tensor_type, shape=[]
|
108
109
|
)
|
109
110
|
|
111
|
+
p_record.set_parameters(ordered_dict, keep_input=keep_input)
|
110
112
|
return p_record
|
111
113
|
|
112
114
|
|
@@ -330,11 +332,15 @@ def getparametersins_to_recordset(getparameters_ins: GetParametersIns) -> Record
|
|
330
332
|
return recordset
|
331
333
|
|
332
334
|
|
333
|
-
def getparametersres_to_recordset(
|
335
|
+
def getparametersres_to_recordset(
|
336
|
+
getparametersres: GetParametersRes, keep_input: bool
|
337
|
+
) -> RecordSet:
|
334
338
|
"""Construct a RecordSet from a GetParametersRes object."""
|
335
339
|
recordset = RecordSet()
|
336
340
|
res_str = "getparametersres"
|
337
|
-
parameters_record = parameters_to_parametersrecord(
|
341
|
+
parameters_record = parameters_to_parametersrecord(
|
342
|
+
getparametersres.parameters, keep_input=keep_input
|
343
|
+
)
|
338
344
|
recordset.set_parameters(f"{res_str}.parameters", parameters_record)
|
339
345
|
|
340
346
|
# status
|
@@ -345,11 +351,13 @@ def getparametersres_to_recordset(getparametersres: GetParametersRes) -> RecordS
|
|
345
351
|
return recordset
|
346
352
|
|
347
353
|
|
348
|
-
def recordset_to_getparametersres(
|
354
|
+
def recordset_to_getparametersres(
|
355
|
+
recordset: RecordSet, keep_input: bool
|
356
|
+
) -> GetParametersRes:
|
349
357
|
"""Derive GetParametersRes from a RecordSet object."""
|
350
358
|
res_str = "getparametersres"
|
351
359
|
parameters = parametersrecord_to_parameters(
|
352
|
-
recordset.get_parameters(f"{res_str}.parameters")
|
360
|
+
recordset.get_parameters(f"{res_str}.parameters"), keep_input=keep_input
|
353
361
|
)
|
354
362
|
|
355
363
|
status = _extract_status_from_recordset(res_str, recordset)
|
flwr/common/serde.py
CHANGED
@@ -17,7 +17,7 @@
|
|
17
17
|
|
18
18
|
from typing import Any, Dict, List, MutableMapping, OrderedDict, Type, TypeVar, cast
|
19
19
|
|
20
|
-
from google.protobuf.message import Message
|
20
|
+
from google.protobuf.message import Message as GrpcMessage
|
21
21
|
|
22
22
|
# pylint: disable=E0611
|
23
23
|
from flwr.proto.recordset_pb2 import Array as ProtoArray
|
@@ -30,7 +30,7 @@ from flwr.proto.recordset_pb2 import MetricsRecordValue as ProtoMetricsRecordVal
|
|
30
30
|
from flwr.proto.recordset_pb2 import ParametersRecord as ProtoParametersRecord
|
31
31
|
from flwr.proto.recordset_pb2 import RecordSet as ProtoRecordSet
|
32
32
|
from flwr.proto.recordset_pb2 import Sint64List, StringList
|
33
|
-
from flwr.proto.task_pb2 import Value
|
33
|
+
from flwr.proto.task_pb2 import Task, TaskIns, TaskRes, Value
|
34
34
|
from flwr.proto.transport_pb2 import (
|
35
35
|
ClientMessage,
|
36
36
|
Code,
|
@@ -44,6 +44,7 @@ from flwr.proto.transport_pb2 import (
|
|
44
44
|
# pylint: enable=E0611
|
45
45
|
from . import typing
|
46
46
|
from .configsrecord import ConfigsRecord
|
47
|
+
from .message import Message, Metadata
|
47
48
|
from .metricsrecord import MetricsRecord
|
48
49
|
from .parametersrecord import Array, ParametersRecord
|
49
50
|
from .recordset import RecordSet
|
@@ -600,12 +601,15 @@ T = TypeVar("T")
|
|
600
601
|
def _record_value_to_proto(
|
601
602
|
value: Any, allowed_types: List[type], proto_class: Type[T]
|
602
603
|
) -> T:
|
603
|
-
"""Serialize `*RecordValue` to ProtoBuf.
|
604
|
+
"""Serialize `*RecordValue` to ProtoBuf.
|
605
|
+
|
606
|
+
Note: `bool` MUST be put in the front of allowd_types if it exists.
|
607
|
+
"""
|
604
608
|
arg = {}
|
605
609
|
for t in allowed_types:
|
606
610
|
# Single element
|
607
611
|
# Note: `isinstance(False, int) == True`.
|
608
|
-
if
|
612
|
+
if isinstance(value, t):
|
609
613
|
arg[_type_to_field[t]] = value
|
610
614
|
return proto_class(**arg)
|
611
615
|
# List
|
@@ -620,7 +624,7 @@ def _record_value_to_proto(
|
|
620
624
|
)
|
621
625
|
|
622
626
|
|
623
|
-
def _record_value_from_proto(value_proto:
|
627
|
+
def _record_value_from_proto(value_proto: GrpcMessage) -> Any:
|
624
628
|
"""Deserialize `*RecordValue` from ProtoBuf."""
|
625
629
|
value_field = cast(str, value_proto.WhichOneof("value"))
|
626
630
|
if value_field.endswith("list"):
|
@@ -633,7 +637,14 @@ def _record_value_from_proto(value_proto: Message) -> Any:
|
|
633
637
|
def _record_value_dict_to_proto(
|
634
638
|
value_dict: Dict[str, Any], allowed_types: List[type], value_proto_class: Type[T]
|
635
639
|
) -> Dict[str, T]:
|
636
|
-
"""Serialize the record value dict to ProtoBuf.
|
640
|
+
"""Serialize the record value dict to ProtoBuf.
|
641
|
+
|
642
|
+
Note: `bool` MUST be put in the front of allowd_types if it exists.
|
643
|
+
"""
|
644
|
+
# Move bool to the front
|
645
|
+
if bool in allowed_types and allowed_types[0] != bool:
|
646
|
+
allowed_types.remove(bool)
|
647
|
+
allowed_types.insert(0, bool)
|
637
648
|
|
638
649
|
def proto(_v: Any) -> T:
|
639
650
|
return _record_value_to_proto(_v, allowed_types, value_proto_class)
|
@@ -707,7 +718,7 @@ def configs_record_to_proto(record: ConfigsRecord) -> ProtoConfigsRecord:
|
|
707
718
|
"""Serialize ConfigsRecord to ProtoBuf."""
|
708
719
|
return ProtoConfigsRecord(
|
709
720
|
data=_record_value_dict_to_proto(
|
710
|
-
record.data, [int, float,
|
721
|
+
record.data, [bool, int, float, str, bytes], ProtoConfigsRecordValue
|
711
722
|
)
|
712
723
|
)
|
713
724
|
|
@@ -751,3 +762,64 @@ def recordset_from_proto(recordset_proto: ProtoRecordSet) -> RecordSet:
|
|
751
762
|
k: configs_record_from_proto(v) for k, v in recordset_proto.configs.items()
|
752
763
|
},
|
753
764
|
)
|
765
|
+
|
766
|
+
|
767
|
+
# === Message ===
|
768
|
+
|
769
|
+
|
770
|
+
def message_to_taskins(message: Message) -> TaskIns:
|
771
|
+
"""Create a TaskIns from the Message."""
|
772
|
+
return TaskIns(
|
773
|
+
task=Task(
|
774
|
+
ttl=message.metadata.ttl,
|
775
|
+
task_type=message.metadata.task_type,
|
776
|
+
recordset=recordset_to_proto(message.message),
|
777
|
+
),
|
778
|
+
)
|
779
|
+
|
780
|
+
|
781
|
+
def message_from_taskins(taskins: TaskIns) -> Message:
|
782
|
+
"""Create a Message from the TaskIns."""
|
783
|
+
# Retrieve the Metadata
|
784
|
+
metadata = Metadata(
|
785
|
+
run_id=taskins.run_id,
|
786
|
+
task_id=taskins.task_id,
|
787
|
+
group_id=taskins.group_id,
|
788
|
+
ttl=taskins.task.ttl,
|
789
|
+
task_type=taskins.task.task_type,
|
790
|
+
)
|
791
|
+
|
792
|
+
# Return the Message
|
793
|
+
return Message(
|
794
|
+
metadata=metadata,
|
795
|
+
message=recordset_from_proto(taskins.task.recordset),
|
796
|
+
)
|
797
|
+
|
798
|
+
|
799
|
+
def message_to_taskres(message: Message) -> TaskRes:
|
800
|
+
"""Create a TaskRes from the Message."""
|
801
|
+
return TaskRes(
|
802
|
+
task=Task(
|
803
|
+
ttl=message.metadata.ttl,
|
804
|
+
task_type=message.metadata.task_type,
|
805
|
+
recordset=recordset_to_proto(message.message),
|
806
|
+
),
|
807
|
+
)
|
808
|
+
|
809
|
+
|
810
|
+
def message_from_taskres(taskres: TaskRes) -> Message:
|
811
|
+
"""Create a Message from the TaskIns."""
|
812
|
+
# Retrieve the MetaData
|
813
|
+
metadata = Metadata(
|
814
|
+
run_id=taskres.run_id,
|
815
|
+
task_id=taskres.task_id,
|
816
|
+
group_id=taskres.group_id,
|
817
|
+
ttl=taskres.task.ttl,
|
818
|
+
task_type=taskres.task.task_type,
|
819
|
+
)
|
820
|
+
|
821
|
+
# Return the Message
|
822
|
+
return Message(
|
823
|
+
metadata=metadata,
|
824
|
+
message=recordset_from_proto(taskres.task.recordset),
|
825
|
+
)
|
@@ -27,7 +27,7 @@ from ray.util.actor_pool import ActorPool
|
|
27
27
|
|
28
28
|
from flwr import common
|
29
29
|
from flwr.client import Client, ClientFn
|
30
|
-
from flwr.
|
30
|
+
from flwr.common.context import Context
|
31
31
|
from flwr.common.logger import log
|
32
32
|
from flwr.simulation.ray_transport.utils import check_clientfn_returns_client
|
33
33
|
|
@@ -61,8 +61,8 @@ class VirtualClientEngineActor(ABC):
|
|
61
61
|
client_fn: ClientFn,
|
62
62
|
job_fn: JobFn,
|
63
63
|
cid: str,
|
64
|
-
|
65
|
-
) -> Tuple[str, ClientRes,
|
64
|
+
context: Context,
|
65
|
+
) -> Tuple[str, ClientRes, Context]:
|
66
66
|
"""Run a client run."""
|
67
67
|
# Execute tasks and return result
|
68
68
|
# return also cid which is needed to ensure results
|
@@ -70,12 +70,12 @@ class VirtualClientEngineActor(ABC):
|
|
70
70
|
try:
|
71
71
|
# Instantiate client (check 'Client' type is returned)
|
72
72
|
client = check_clientfn_returns_client(client_fn(cid))
|
73
|
-
# Inject
|
74
|
-
client.
|
73
|
+
# Inject context
|
74
|
+
client.set_context(context)
|
75
75
|
# Run client job
|
76
76
|
job_results = job_fn(client)
|
77
|
-
# Retrieve
|
78
|
-
|
77
|
+
# Retrieve context (potentially updated)
|
78
|
+
updated_context = client.get_context()
|
79
79
|
except Exception as ex:
|
80
80
|
client_trace = traceback.format_exc()
|
81
81
|
message = (
|
@@ -89,7 +89,7 @@ class VirtualClientEngineActor(ABC):
|
|
89
89
|
)
|
90
90
|
raise ClientException(str(message)) from ex
|
91
91
|
|
92
|
-
return cid, job_results,
|
92
|
+
return cid, job_results, updated_context
|
93
93
|
|
94
94
|
|
95
95
|
@ray.remote
|
@@ -237,16 +237,16 @@ class VirtualClientEngineActorPool(ActorPool):
|
|
237
237
|
self._idle_actors.extend(new_actors)
|
238
238
|
self.num_actors += num_actors
|
239
239
|
|
240
|
-
def submit(self, fn: Any, value: Tuple[ClientFn, JobFn, str,
|
240
|
+
def submit(self, fn: Any, value: Tuple[ClientFn, JobFn, str, Context]) -> None:
|
241
241
|
"""Take idle actor and assign it a client run.
|
242
242
|
|
243
243
|
Submit a job to an actor by first removing it from the list of idle actors, then
|
244
244
|
check if this actor was flagged to be removed from the pool
|
245
245
|
"""
|
246
|
-
client_fn, job_fn, cid,
|
246
|
+
client_fn, job_fn, cid, context = value
|
247
247
|
actor = self._idle_actors.pop()
|
248
248
|
if self._check_and_remove_actor_from_pool(actor):
|
249
|
-
future = fn(actor, client_fn, job_fn, cid,
|
249
|
+
future = fn(actor, client_fn, job_fn, cid, context)
|
250
250
|
future_key = tuple(future) if isinstance(future, List) else future
|
251
251
|
self._future_to_actor[future_key] = (self._next_task_index, actor, cid)
|
252
252
|
self._next_task_index += 1
|
@@ -255,7 +255,7 @@ class VirtualClientEngineActorPool(ActorPool):
|
|
255
255
|
self._cid_to_future[cid]["future"] = future_key
|
256
256
|
|
257
257
|
def submit_client_job(
|
258
|
-
self, actor_fn: Any, job: Tuple[ClientFn, JobFn, str,
|
258
|
+
self, actor_fn: Any, job: Tuple[ClientFn, JobFn, str, Context]
|
259
259
|
) -> None:
|
260
260
|
"""Submit a job while tracking client ids."""
|
261
261
|
_, _, cid, _ = job
|
@@ -295,17 +295,17 @@ class VirtualClientEngineActorPool(ActorPool):
|
|
295
295
|
|
296
296
|
return self._cid_to_future[cid]["ready"] # type: ignore
|
297
297
|
|
298
|
-
def _fetch_future_result(self, cid: str) -> Tuple[ClientRes,
|
299
|
-
"""Fetch result and updated
|
298
|
+
def _fetch_future_result(self, cid: str) -> Tuple[ClientRes, Context]:
|
299
|
+
"""Fetch result and updated context for a VirtualClient from Object Store.
|
300
300
|
|
301
301
|
The job submitted by the ClientProxy interfacing with client with cid=cid is
|
302
302
|
ready. Here we fetch it from the object store and return.
|
303
303
|
"""
|
304
304
|
try:
|
305
305
|
future: ObjectRef[Any] = self._cid_to_future[cid]["future"] # type: ignore
|
306
|
-
res_cid, res,
|
306
|
+
res_cid, res, updated_context = ray.get(
|
307
307
|
future
|
308
|
-
) # type: (str, ClientRes,
|
308
|
+
) # type: (str, ClientRes, Context)
|
309
309
|
except ray.exceptions.RayActorError as ex:
|
310
310
|
log(ERROR, ex)
|
311
311
|
if hasattr(ex, "actor_id"):
|
@@ -322,7 +322,7 @@ class VirtualClientEngineActorPool(ActorPool):
|
|
322
322
|
# Reset mapping
|
323
323
|
self._reset_cid_to_future_dict(cid)
|
324
324
|
|
325
|
-
return res,
|
325
|
+
return res, updated_context
|
326
326
|
|
327
327
|
def _flag_actor_for_removal(self, actor_id_hex: str) -> None:
|
328
328
|
"""Flag actor that should be removed from pool."""
|
@@ -409,7 +409,7 @@ class VirtualClientEngineActorPool(ActorPool):
|
|
409
409
|
|
410
410
|
def get_client_result(
|
411
411
|
self, cid: str, timeout: Optional[float]
|
412
|
-
) -> Tuple[ClientRes,
|
412
|
+
) -> Tuple[ClientRes, Context]:
|
413
413
|
"""Get result from VirtualClient with specific cid."""
|
414
414
|
# Loop until all jobs submitted to the pool are completed. Break early
|
415
415
|
# if the result for the ClientProxy calling this method is ready
|
@@ -421,5 +421,5 @@ class VirtualClientEngineActorPool(ActorPool):
|
|
421
421
|
break
|
422
422
|
|
423
423
|
# Fetch result belonging to the VirtualClient calling this method
|
424
|
-
# Return both result from tasks and (potentially) updated run
|
424
|
+
# Return both result from tasks and (potentially) updated run context
|
425
425
|
return self._fetch_future_result(cid)
|
@@ -138,20 +138,20 @@ class RayActorClientProxy(ClientProxy):
|
|
138
138
|
run_id = 0
|
139
139
|
|
140
140
|
# Register state
|
141
|
-
self.proxy_state.
|
141
|
+
self.proxy_state.register_context(run_id=run_id)
|
142
142
|
|
143
143
|
# Retrieve state
|
144
|
-
state = self.proxy_state.
|
144
|
+
state = self.proxy_state.retrieve_context(run_id=run_id)
|
145
145
|
|
146
146
|
try:
|
147
147
|
self.actor_pool.submit_client_job(
|
148
148
|
lambda a, c_fn, j_fn, cid, state: a.run.remote(c_fn, j_fn, cid, state),
|
149
149
|
(self.client_fn, job_fn, self.cid, state),
|
150
150
|
)
|
151
|
-
res,
|
151
|
+
res, updated_context = self.actor_pool.get_client_result(self.cid, timeout)
|
152
152
|
|
153
153
|
# Update state
|
154
|
-
self.proxy_state.
|
154
|
+
self.proxy_state.update_context(run_id=run_id, context=updated_context)
|
155
155
|
|
156
156
|
except Exception as ex:
|
157
157
|
if self.actor_pool.num_actors == 0:
|
{flwr_nightly-1.7.0.dev20240124.dist-info → flwr_nightly-1.7.0.dev20240126.dist-info}/METADATA
RENAMED
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: flwr-nightly
|
3
|
-
Version: 1.7.0.
|
3
|
+
Version: 1.7.0.dev20240126
|
4
4
|
Summary: Flower: A Friendly Federated Learning Framework
|
5
5
|
Home-page: https://flower.dev
|
6
6
|
License: Apache-2.0
|
@@ -184,6 +184,7 @@ Other [examples](https://github.com/adap/flower/tree/main/examples):
|
|
184
184
|
- [Advanced Flower with TensorFlow/Keras](https://github.com/adap/flower/tree/main/examples/advanced-tensorflow)
|
185
185
|
- [Advanced Flower with PyTorch](https://github.com/adap/flower/tree/main/examples/advanced-pytorch)
|
186
186
|
- Single-Machine Simulation of Federated Learning Systems ([PyTorch](https://github.com/adap/flower/tree/main/examples/simulation_pytorch)) ([Tensorflow](https://github.com/adap/flower/tree/main/examples/simulation_tensorflow))
|
187
|
+
- [Flower through Docker Compose and with Grafana dashboard](https://github.com/adap/flower/tree/main/examples/flower-via-docker-compose)
|
187
188
|
|
188
189
|
## Community
|
189
190
|
|
{flwr_nightly-1.7.0.dev20240124.dist-info → flwr_nightly-1.7.0.dev20240126.dist-info}/RECORD
RENAMED
@@ -1,42 +1,42 @@
|
|
1
1
|
flwr/__init__.py,sha256=6zbcS7z2q-VUdmpFppLH6BacsE-ZFmfq6OvtKNOyYE0,981
|
2
2
|
flwr/client/__init__.py,sha256=2T4enmlE4PsoKiGTvXwBKSlhOjZ7MXRy5oCGNf0UH9Y,1111
|
3
|
-
flwr/client/app.py,sha256=
|
4
|
-
flwr/client/client.py,sha256=
|
3
|
+
flwr/client/app.py,sha256=B0pa8BZ5oLYRs1Fs7KhqYOxM3Sy6w9LmUt-hQfjTlBA,19242
|
4
|
+
flwr/client/client.py,sha256=ATcsqAMS9zpMBJ9ZUbBeB7BEPWX_VWISONy0p6Wxl5g,8210
|
5
5
|
flwr/client/dpfedavg_numpy_client.py,sha256=0XryFdCMM_RLiNLCr6evLp-6R7ZjeMmRUROIgzRmtmc,7215
|
6
|
-
flwr/client/flower.py,sha256=
|
6
|
+
flwr/client/flower.py,sha256=Xh3v7NgAliaLEjwMC6hhq_E0YxaVbHqwEd0HqwWe2lo,4059
|
7
7
|
flwr/client/grpc_client/__init__.py,sha256=LsnbqXiJhgQcB0XzAlUQgPx011Uf7Y7yabIC1HxivJ8,735
|
8
8
|
flwr/client/grpc_client/connection.py,sha256=WJazRjWZuSLnE4jsGtJ86g9THewbAfspQ-XtmfGR8uQ,5115
|
9
9
|
flwr/client/grpc_rere_client/__init__.py,sha256=avn6W_vHEM_yZEB1S7hCZgnTbXb6ZujqRP_vAzyXu-0,752
|
10
10
|
flwr/client/grpc_rere_client/connection.py,sha256=NtYxwJCucI9RYieU9rVMi5wzrnvLNxhSWYmi5IiWAtc,6660
|
11
11
|
flwr/client/message_handler/__init__.py,sha256=abHvBRJJiiaAMNgeILQbMOa6h8WqMK2BcnvxwQZFpic,719
|
12
|
-
flwr/client/message_handler/message_handler.py,sha256=
|
12
|
+
flwr/client/message_handler/message_handler.py,sha256=vhVhFdohM3q6xz5bqcDLSTyR9viFUAkbBKHCTiB4qyQ,8414
|
13
13
|
flwr/client/message_handler/task_handler.py,sha256=36g-gP7oH_VDpsjW2P9LH4uzlDkygY8S9FyGxjbSw34,5823
|
14
14
|
flwr/client/middleware/__init__.py,sha256=Eo3JvAV5XqmyRySNqeiw93YNETmmP5ixEOMeBA6ah4w,769
|
15
15
|
flwr/client/middleware/utils.py,sha256=QUghso_SWsKTUPfKwrtBwPyyJoEI9AV9hRY2acu1TYE,1168
|
16
|
-
flwr/client/node_state.py,sha256=
|
17
|
-
flwr/client/node_state_tests.py,sha256=
|
18
|
-
flwr/client/numpy_client.py,sha256=
|
16
|
+
flwr/client/node_state.py,sha256=0hk1RZuFZ3_S7Y8Q0BCP60NljxnT9vqPmIflvCCGxnQ,1819
|
17
|
+
flwr/client/node_state_tests.py,sha256=H3sO526boAlDS491fO5xvZhl5XNDzzl-I8DiaVmnsXM,2195
|
18
|
+
flwr/client/numpy_client.py,sha256=42e8_gZU5gwzpvVXQr6LEWEGfpWYTcQ0MY0F0owNlAc,10310
|
19
19
|
flwr/client/rest_client/__init__.py,sha256=ThwOnkMdzxo_UuyTI47Q7y9oSpuTgNT2OuFvJCfuDiw,735
|
20
20
|
flwr/client/rest_client/connection.py,sha256=j8BpGRM4mGJrkw7Yncpwk-BJ6KOw0C3PS3tqLfsUUes,11762
|
21
|
-
flwr/client/run_state.py,sha256=d4UmHLt9zMd0sTgnVdRsLgr1QEx0l5PtJ0dPv2NSVVw,867
|
22
21
|
flwr/client/secure_aggregation/__init__.py,sha256=XCDycteBTivym0zwkwqXhFMCAoDoHBZQg5GxdMnFCfA,888
|
23
22
|
flwr/client/secure_aggregation/handler.py,sha256=oRyGCerz92aED7UydYwJ7OFVxUwHqedG3PshHrdZq-Y,1522
|
24
23
|
flwr/client/secure_aggregation/secaggplus_handler.py,sha256=2jKtRhoJaVRmMJgJ2v8VRUCw2ko7uhTL2_h8CZVFwZA,18928
|
25
|
-
flwr/client/typing.py,sha256=
|
24
|
+
flwr/client/typing.py,sha256=F6E2sDRrUirWdGQlfBR4YOaAJ-TYn7XiLuQMG6bMXrI,1218
|
26
25
|
flwr/common/__init__.py,sha256=qttep0POwoigzB5pcraZa4YMt9jsCSfeibcrTQMUjIc,2884
|
27
26
|
flwr/common/address.py,sha256=iTAN9jtmIGMrWFnx9XZQl45ZEtQJVZZLYPRBSNVARGI,1882
|
28
27
|
flwr/common/configsrecord.py,sha256=i41syiXeG4CyWr4ujOCxTDBZKiClNnNgR4xbufxThh0,4799
|
29
28
|
flwr/common/constant.py,sha256=J-BpHv6OFmrA37SeS4En8Nsy7yJdoNJWHCtbdnjIxSc,1120
|
29
|
+
flwr/common/context.py,sha256=OP4mTxsCdU2LS63TegdLHaEDpxULZ4AQ4ybZl7jEdDU,1329
|
30
30
|
flwr/common/date.py,sha256=UWhBZj49yX9LD4BmatS_ZFZu_-kweGh0KQJ1djyWWH4,891
|
31
31
|
flwr/common/dp.py,sha256=hF45cPElXxcQsh4AoquAyaTrNi0xCrIcKx7xOcV_1XU,1782
|
32
|
-
flwr/common/flowercontext.py,sha256=pC8Vjw9ToNX4i8oMuvSSJrZEccJhPN9i60b1apQnQWE,2562
|
33
32
|
flwr/common/grpc.py,sha256=qVLB0d6bCuaBRW5YB0vEZXsR7Bo3R2lh4ONiCocqwRI,2270
|
34
33
|
flwr/common/logger.py,sha256=qX_gqEyrmGOH0x_r8uQ1Vskz4fGvEij9asdo4DUOPY8,4135
|
34
|
+
flwr/common/message.py,sha256=GQuhFmvJIrCG6h4L-jQMsn6KYh-nmNqNNo5qVe7ye5w,1847
|
35
35
|
flwr/common/metricsrecord.py,sha256=n9789VVdjEPX0o7Je_1wRuzs7LkLh5d37QRyN0iVmRY,4783
|
36
36
|
flwr/common/parameter.py,sha256=-bFAUayToYDF50FZGrBC1hQYJCQDtB2bbr3ZuVLMtdE,2095
|
37
37
|
flwr/common/parametersrecord.py,sha256=v5RmvJI1Y5iJhgIhdatZj7FItRRuaEmTKkCGDRFPQDU,4413
|
38
38
|
flwr/common/recordset.py,sha256=OeRcBMGqx9vutWRz1xkujBPHlVpU58R1EcFRHEQrePo,2351
|
39
|
-
flwr/common/recordset_compat.py,sha256=
|
39
|
+
flwr/common/recordset_compat.py,sha256=4tbpHIPZM9V-DuVFuTdLbdb8N7-rMT0nT0uj22gaS7g,13730
|
40
40
|
flwr/common/retry_invoker.py,sha256=H_hKqKaEI8vZPywWmoAtJYkcUnKhlYc4kV63zRY0kWA,10856
|
41
41
|
flwr/common/secure_aggregation/__init__.py,sha256=29nHIUO2L8-KhNHQ2KmIgRo_4CPkq4LgLCUN0on5FgI,731
|
42
42
|
flwr/common/secure_aggregation/crypto/__init__.py,sha256=dz7pVx2aPrHxr_AwgO5mIiTzu4PcvUxRq9NLBbFcsf8,738
|
@@ -46,7 +46,7 @@ flwr/common/secure_aggregation/ndarrays_arithmetic.py,sha256=KAHCEHGSTJ6mCgnC8dT
|
|
46
46
|
flwr/common/secure_aggregation/quantization.py,sha256=appui7GGrkRPsupF59TkapeV4Na_CyPi73JtJ1pimdI,2310
|
47
47
|
flwr/common/secure_aggregation/secaggplus_constants.py,sha256=m5UDo7IgRkMS3yixhzz7DhhAv6VAQMCghglMygSPU_k,1606
|
48
48
|
flwr/common/secure_aggregation/secaggplus_utils.py,sha256=PleDyDu7jHNAfbRoEaoQiOjxG6iMl9yA8rNKYTfnyFw,3155
|
49
|
-
flwr/common/serde.py,sha256=
|
49
|
+
flwr/common/serde.py,sha256=mI4K91XJ2lnxbdLSK93djkdrQmc_iZENvH_yKKSHo-E,26794
|
50
50
|
flwr/common/telemetry.py,sha256=se_-pHgEWcmN09ChSpTeek72l1UJHf7GbwXBB1KXBjQ,7683
|
51
51
|
flwr/common/typing.py,sha256=3Wu6Ol1Ja6Gb0WdlcXVEn1EHYJbc4oRRJA81vEegxBo,4382
|
52
52
|
flwr/common/version.py,sha256=A0MKvyKPrV8wLg0YCAODTqM71v26NEH36c6JYtfgg0o,667
|
@@ -138,11 +138,11 @@ flwr/server/utils/validator.py,sha256=b_3ahGkSPn4M3TPYaNiY5DyJmnkQHJsyarccPgrhFo
|
|
138
138
|
flwr/simulation/__init__.py,sha256=E2eD5FlTmZZ80u21FmWCkacrM7O4mrEHD8iXqeCaBUQ,1278
|
139
139
|
flwr/simulation/app.py,sha256=pbkldpm3Uc9_0M2R5-8Ako26g9WxNhZW4fLJY-4YtJY,13879
|
140
140
|
flwr/simulation/ray_transport/__init__.py,sha256=FsaAnzC4cw4DqoouBCix6496k29jACkfeIam55BvW9g,734
|
141
|
-
flwr/simulation/ray_transport/ray_actor.py,sha256=
|
142
|
-
flwr/simulation/ray_transport/ray_client_proxy.py,sha256=
|
141
|
+
flwr/simulation/ray_transport/ray_actor.py,sha256=G_g50ISt3Knf0zuX1wmw39gsDXSoMI5f3rmYZWGrUh4,17062
|
142
|
+
flwr/simulation/ray_transport/ray_client_proxy.py,sha256=UxQEzWmklp3WO2V7LH5vNyAgYL7KYFFZQa1HTUSgEqY,9429
|
143
143
|
flwr/simulation/ray_transport/utils.py,sha256=e0mkFOgOXSJHSQdiipoggF-DLBXaJZVytx9auQ35fCg,3368
|
144
|
-
flwr_nightly-1.7.0.
|
145
|
-
flwr_nightly-1.7.0.
|
146
|
-
flwr_nightly-1.7.0.
|
147
|
-
flwr_nightly-1.7.0.
|
148
|
-
flwr_nightly-1.7.0.
|
144
|
+
flwr_nightly-1.7.0.dev20240126.dist-info/LICENSE,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
|
145
|
+
flwr_nightly-1.7.0.dev20240126.dist-info/METADATA,sha256=kigwmhoqGNgCqt0T-xOjxzJDhDvu4ycW1vttbQpB5lk,13578
|
146
|
+
flwr_nightly-1.7.0.dev20240126.dist-info/WHEEL,sha256=Zb28QaM1gQi8f4VCBhsUklF61CTlNYfs9YAZn-TOGFk,88
|
147
|
+
flwr_nightly-1.7.0.dev20240126.dist-info/entry_points.txt,sha256=1uLlD5tIunkzALMfMWnqjdE_D5hRUX_I1iMmOMv6tZI,181
|
148
|
+
flwr_nightly-1.7.0.dev20240126.dist-info/RECORD,,
|
{flwr_nightly-1.7.0.dev20240124.dist-info → flwr_nightly-1.7.0.dev20240126.dist-info}/LICENSE
RENAMED
File without changes
|
File without changes
|
File without changes
|