flwr-nightly 1.7.0.dev20240124__py3-none-any.whl → 1.7.0.dev20240126__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- 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
|