flwr-nightly 1.17.0.dev20250317__py3-none-any.whl → 1.17.0.dev20250318__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/common/constant.py +3 -0
- flwr/common/record/parametersrecord.py +336 -92
- flwr/server/__init__.py +1 -1
- flwr/server/app.py +1 -1
- flwr/server/compat/app.py +1 -1
- flwr/server/compat/app_utils.py +2 -2
- flwr/server/compat/{driver_client_proxy.py → grid_client_proxy.py} +2 -2
- flwr/server/{driver → grid}/__init__.py +4 -4
- flwr/server/{driver/driver.py → grid/grid.py} +1 -1
- flwr/server/{driver/grpc_driver.py → grid/grpc_grid.py} +2 -11
- flwr/server/{driver/inmemory_driver.py → grid/inmemory_grid.py} +2 -10
- flwr/server/run_serverapp.py +1 -1
- flwr/server/server_app.py +2 -2
- flwr/server/serverapp/app.py +1 -1
- flwr/server/superlink/{driver → serverappio}/__init__.py +1 -1
- flwr/server/superlink/{driver → serverappio}/serverappio_grpc.py +1 -1
- flwr/server/superlink/{driver → serverappio}/serverappio_servicer.py +1 -1
- flwr/server/typing.py +1 -1
- flwr/server/workflow/default_workflows.py +1 -1
- flwr/server/workflow/secure_aggregation/secaggplus_workflow.py +1 -1
- flwr/simulation/run_simulation.py +1 -1
- {flwr_nightly-1.17.0.dev20250317.dist-info → flwr_nightly-1.17.0.dev20250318.dist-info}/METADATA +1 -1
- {flwr_nightly-1.17.0.dev20250317.dist-info → flwr_nightly-1.17.0.dev20250318.dist-info}/RECORD +26 -26
- {flwr_nightly-1.17.0.dev20250317.dist-info → flwr_nightly-1.17.0.dev20250318.dist-info}/LICENSE +0 -0
- {flwr_nightly-1.17.0.dev20250317.dist-info → flwr_nightly-1.17.0.dev20250318.dist-info}/WHEEL +0 -0
- {flwr_nightly-1.17.0.dev20250317.dist-info → flwr_nightly-1.17.0.dev20250318.dist-info}/entry_points.txt +0 -0
flwr/common/constant.py
CHANGED
@@ -120,6 +120,9 @@ TIMESTAMP_HEADER = "flwr-timestamp"
|
|
120
120
|
TIMESTAMP_TOLERANCE = 10 # General tolerance for timestamp verification
|
121
121
|
SYSTEM_TIME_TOLERANCE = 5 # Allowance for system time drift
|
122
122
|
|
123
|
+
# Constants for ParametersRecord
|
124
|
+
GC_THRESHOLD = 200_000_000 # 200 MB
|
125
|
+
|
123
126
|
|
124
127
|
class MessageType:
|
125
128
|
"""Message type."""
|
@@ -17,22 +17,36 @@
|
|
17
17
|
|
18
18
|
from __future__ import annotations
|
19
19
|
|
20
|
+
import gc
|
21
|
+
import sys
|
20
22
|
from collections import OrderedDict
|
21
23
|
from dataclasses import dataclass
|
22
24
|
from io import BytesIO
|
23
|
-
from typing import Any, cast, overload
|
25
|
+
from typing import TYPE_CHECKING, Any, cast, overload
|
24
26
|
|
25
27
|
import numpy as np
|
26
28
|
|
27
|
-
from ..constant import SType
|
29
|
+
from ..constant import GC_THRESHOLD, SType
|
28
30
|
from ..typing import NDArray
|
29
31
|
from .typeddict import TypedDict
|
30
32
|
|
33
|
+
if TYPE_CHECKING:
|
34
|
+
import torch
|
35
|
+
|
31
36
|
|
32
37
|
def _raise_array_init_error() -> None:
|
33
38
|
raise TypeError(
|
34
39
|
f"Invalid arguments for {Array.__qualname__}. Expected either a "
|
35
|
-
"NumPy ndarray, or explicit
|
40
|
+
"PyTorch tensor, a NumPy ndarray, or explicit"
|
41
|
+
" dtype/shape/stype/data values."
|
42
|
+
)
|
43
|
+
|
44
|
+
|
45
|
+
def _raise_parameters_record_init_error() -> None:
|
46
|
+
raise TypeError(
|
47
|
+
f"Invalid arguments for {ParametersRecord.__qualname__}. Expected either "
|
48
|
+
"a list of NumPy ndarrays, a PyTorch state_dict, or a dictionary of Arrays. "
|
49
|
+
"The `keep_input` argument is keyword-only."
|
36
50
|
)
|
37
51
|
|
38
52
|
|
@@ -41,37 +55,43 @@ class Array:
|
|
41
55
|
"""Array type.
|
42
56
|
|
43
57
|
A dataclass containing serialized data from an array-like or tensor-like object
|
44
|
-
along with metadata about it. The class can be initialized in one of
|
58
|
+
along with metadata about it. The class can be initialized in one of three ways:
|
45
59
|
|
46
60
|
1. By specifying explicit values for `dtype`, `shape`, `stype`, and `data`.
|
47
61
|
2. By providing a NumPy ndarray (via the `ndarray` argument).
|
62
|
+
3. By providing a PyTorch tensor (via the `torch_tensor` argument).
|
48
63
|
|
49
|
-
In
|
64
|
+
In scenarios (2)-(3), the `dtype`, `shape`, `stype`, and `data` are automatically
|
50
65
|
derived from the input. In scenario (1), these fields must be specified manually.
|
51
66
|
|
52
67
|
Parameters
|
53
68
|
----------
|
54
69
|
dtype : Optional[str] (default: None)
|
55
70
|
A string representing the data type of the serialized object (e.g. `"float32"`).
|
56
|
-
Only required if you are not passing in a ndarray.
|
71
|
+
Only required if you are not passing in a ndarray or a tensor.
|
57
72
|
|
58
73
|
shape : Optional[list[int]] (default: None)
|
59
74
|
A list representing the shape of the unserialized array-like object. Only
|
60
|
-
required if you are not passing in a ndarray.
|
75
|
+
required if you are not passing in a ndarray or a tensor.
|
61
76
|
|
62
77
|
stype : Optional[str] (default: None)
|
63
78
|
A string indicating the serialization mechanism used to generate the bytes in
|
64
79
|
`data` from an array-like or tensor-like object. Only required if you are not
|
65
|
-
passing in a ndarray.
|
80
|
+
passing in a ndarray or a tensor.
|
66
81
|
|
67
82
|
data : Optional[bytes] (default: None)
|
68
83
|
A buffer of bytes containing the data. Only required if you are not passing in
|
69
|
-
a ndarray.
|
84
|
+
a ndarray or a tensor.
|
70
85
|
|
71
86
|
ndarray : Optional[NDArray] (default: None)
|
72
87
|
A NumPy ndarray. If provided, the `dtype`, `shape`, `stype`, and `data`
|
73
88
|
fields are derived automatically from it.
|
74
89
|
|
90
|
+
torch_tensor : Optional[torch.Tensor] (default: None)
|
91
|
+
A PyTorch tensor. If provided, it will be **detached and moved to CPU**
|
92
|
+
before conversion, and the `dtype`, `shape`, `stype`, and `data` fields
|
93
|
+
will be derived automatically from it.
|
94
|
+
|
75
95
|
Examples
|
76
96
|
--------
|
77
97
|
Initializing by specifying all fields directly:
|
@@ -87,6 +107,11 @@ class Array:
|
|
87
107
|
|
88
108
|
>>> import numpy as np
|
89
109
|
>>> arr2 = Array(np.random.randn(3, 3))
|
110
|
+
|
111
|
+
Initializing with a PyTorch tensor:
|
112
|
+
|
113
|
+
>>> import torch
|
114
|
+
>>> arr3 = Array(torch.randn(3, 3))
|
90
115
|
"""
|
91
116
|
|
92
117
|
dtype: str
|
@@ -102,6 +127,9 @@ class Array:
|
|
102
127
|
@overload
|
103
128
|
def __init__(self, ndarray: NDArray) -> None: ... # noqa: E704
|
104
129
|
|
130
|
+
@overload
|
131
|
+
def __init__(self, torch_tensor: torch.Tensor) -> None: ... # noqa: E704
|
132
|
+
|
105
133
|
def __init__( # pylint: disable=too-many-arguments, too-many-locals
|
106
134
|
self,
|
107
135
|
*args: Any,
|
@@ -110,11 +138,13 @@ class Array:
|
|
110
138
|
stype: str | None = None,
|
111
139
|
data: bytes | None = None,
|
112
140
|
ndarray: NDArray | None = None,
|
141
|
+
torch_tensor: torch.Tensor | None = None,
|
113
142
|
) -> None:
|
114
143
|
# Determine the initialization method and validate input arguments.
|
115
|
-
# Support
|
144
|
+
# Support three initialization formats:
|
116
145
|
# 1. Array(dtype: str, shape: list[int], stype: str, data: bytes)
|
117
146
|
# 2. Array(ndarray: NDArray)
|
147
|
+
# 3. Array(torch_tensor: torch.Tensor)
|
118
148
|
|
119
149
|
# Initialize all arguments
|
120
150
|
# If more than 4 positional arguments are provided, raise an error.
|
@@ -149,6 +179,7 @@ class Array:
|
|
149
179
|
_try_set_arg(2, stype, "direct")
|
150
180
|
_try_set_arg(3, data, "direct")
|
151
181
|
_try_set_arg(0, ndarray, "ndarray")
|
182
|
+
_try_set_arg(0, torch_tensor, "torch_tensor")
|
152
183
|
|
153
184
|
# Check if all arguments are correctly set
|
154
185
|
all_args = [arg for arg in all_args if arg is not None]
|
@@ -172,6 +203,16 @@ class Array:
|
|
172
203
|
self.__dict__.update(self.from_numpy_ndarray(all_args[0]).__dict__)
|
173
204
|
return
|
174
205
|
|
206
|
+
# Handle PyTorch tensor
|
207
|
+
if not init_method or init_method == "torch_tensor":
|
208
|
+
if (
|
209
|
+
len(all_args) == 1
|
210
|
+
and "torch" in sys.modules
|
211
|
+
and isinstance(all_args[0], sys.modules["torch"].Tensor)
|
212
|
+
):
|
213
|
+
self.__dict__.update(self.from_torch_tensor(all_args[0]).__dict__)
|
214
|
+
return
|
215
|
+
|
175
216
|
_raise_array_init_error()
|
176
217
|
|
177
218
|
@classmethod
|
@@ -193,6 +234,19 @@ class Array:
|
|
193
234
|
data=data,
|
194
235
|
)
|
195
236
|
|
237
|
+
@classmethod
|
238
|
+
def from_torch_tensor(cls, tensor: torch.Tensor) -> Array:
|
239
|
+
"""Create Array from PyTorch tensor."""
|
240
|
+
if not (torch := sys.modules.get("torch")):
|
241
|
+
raise RuntimeError(
|
242
|
+
f"PyTorch is required to use {cls.from_torch_tensor.__name__}"
|
243
|
+
)
|
244
|
+
|
245
|
+
assert isinstance(
|
246
|
+
tensor, torch.Tensor
|
247
|
+
), f"Expected PyTorch Tensor, got {type(tensor)}"
|
248
|
+
return cls.from_numpy_ndarray(tensor.detach().cpu().numpy())
|
249
|
+
|
196
250
|
def numpy(self) -> NDArray:
|
197
251
|
"""Return the array as a NumPy array."""
|
198
252
|
if self.stype != SType.NUMPY:
|
@@ -223,103 +277,293 @@ def _check_value(value: Array) -> None:
|
|
223
277
|
class ParametersRecord(TypedDict[str, Array]):
|
224
278
|
r"""Parameters record.
|
225
279
|
|
226
|
-
A
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
280
|
+
A typed dictionary (``str`` to :class:`Array`) that can store named parameters
|
281
|
+
as serialized tensors. Internally, this behaves similarly to an
|
282
|
+
``OrderedDict[str, Array]``. A ``ParametersRecord`` can be viewed as an
|
283
|
+
equivalent to PyTorch's ``state_dict``, but it holds arrays in serialized form.
|
284
|
+
|
285
|
+
This object is one of the record types supported by :class:`RecordSet` and can
|
286
|
+
therefore be stored in the ``content`` of a :class:`Message` or the ``state``
|
287
|
+
of a :class:`Context`.
|
288
|
+
|
289
|
+
This class can be instantiated in multiple ways:
|
290
|
+
|
291
|
+
1. By providing nothing (empty container).
|
292
|
+
2. By providing a dictionary of :class:`Array` (via the ``array_dict`` argument).
|
293
|
+
3. By providing a list of NumPy ``ndarray`` (via the ``numpy_ndarrays`` argument).
|
294
|
+
4. By providing a PyTorch ``state_dict`` (via the ``torch_state_dict`` argument).
|
232
295
|
|
233
296
|
Parameters
|
234
297
|
----------
|
235
|
-
array_dict : Optional[OrderedDict[str, Array]]
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
298
|
+
array_dict : Optional[OrderedDict[str, Array]] (default: None)
|
299
|
+
An existing dictionary containing named :class:`Array` instances. If
|
300
|
+
provided, these entries will be used directly to populate the record.
|
301
|
+
numpy_ndarrays : Optional[list[NDArray]] (default: None)
|
302
|
+
A list of NumPy arrays. Each array will be automatically converted
|
303
|
+
into an :class:`Array` and stored in this record with generated keys.
|
304
|
+
torch_state_dict : Optional[OrderedDict[str, torch.Tensor]] (default: None)
|
305
|
+
A PyTorch ``state_dict`` (``str`` keys to ``torch.Tensor`` values). Each
|
306
|
+
tensor will be converted into an :class:`Array` and stored in this record.
|
307
|
+
keep_input : bool (default: True)
|
308
|
+
If ``False``, entries from the input are removed after being added to
|
309
|
+
this record to free up memory. If ``True``, the input remains unchanged.
|
310
|
+
Regardless of this value, no duplicate memory is used if the input is a
|
311
|
+
dictionary of :class:`Array`, i.e., ``array_dict``.
|
245
312
|
|
246
313
|
Examples
|
247
314
|
--------
|
248
|
-
|
249
|
-
|
250
|
-
|
315
|
+
Initializing an empty ParametersRecord:
|
316
|
+
|
317
|
+
>>> p_record = ParametersRecord()
|
318
|
+
|
319
|
+
Initializing with a dictionary of :class:`Array`:
|
320
|
+
|
321
|
+
>>> arr = Array("float32", [5, 5], "numpy.ndarray", b"serialized_data...")
|
322
|
+
>>> p_record = ParametersRecord({"weight": arr})
|
251
323
|
|
252
|
-
|
324
|
+
Initializing with a list of NumPy arrays:
|
253
325
|
|
254
326
|
>>> import numpy as np
|
255
|
-
>>>
|
256
|
-
>>>
|
257
|
-
>>>
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
>>>
|
262
|
-
>>>
|
263
|
-
>>>
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
>>>
|
268
|
-
>>>
|
269
|
-
>>>
|
270
|
-
>>>
|
271
|
-
>>> # Adding it to a ParametersRecord:
|
272
|
-
>>> p_record = ParametersRecord({"my_array": arr})
|
273
|
-
|
274
|
-
Now that the NumPy array is embedded into a :code:`ParametersRecord` it could be
|
275
|
-
sent if added as part of a :code:`common.Message` or it could be saved as a
|
276
|
-
persistent state of a :code:`ClientApp` via its context. Regardless of the usecase,
|
277
|
-
we will sooner or later want to recover the array in its original NumPy
|
278
|
-
representation. For the example above, where the array was serialized using the
|
279
|
-
built-in utility function, deserialization can be done as follows:
|
280
|
-
|
281
|
-
>>> # Use the Array's built-in method
|
282
|
-
>>> arr_np_d = arr.numpy()
|
283
|
-
>>>
|
284
|
-
>>> # If printed, it will show the exact same data as above:
|
285
|
-
>>> array([[-1.84242409, -1.01539537, -0.46528405],
|
286
|
-
>>> [ 0.32991896, 0.55540414, 0.44085534],
|
287
|
-
>>> [-0.10758364, 1.97619858, -0.37120501]])
|
288
|
-
|
289
|
-
If you need finer control on how your arrays are serialized and deserialized, you
|
290
|
-
can construct :code:`Array` objects directly like this:
|
291
|
-
|
292
|
-
>>> from flwr.common import Array
|
293
|
-
>>> # Serialize your array and construct Array object
|
294
|
-
>>> arr = Array(
|
295
|
-
>>> data=ndarray.tobytes(),
|
296
|
-
>>> dtype=str(ndarray.dtype),
|
297
|
-
>>> stype="", # Could be used in a deserialization function
|
298
|
-
>>> shape=list(ndarray.shape),
|
299
|
-
>>> )
|
300
|
-
>>>
|
301
|
-
>>> # Then you can deserialize it like this
|
302
|
-
>>> arr_np_d = np.frombuffer(
|
303
|
-
>>> buffer=array.data,
|
304
|
-
>>> dtype=array.dtype,
|
305
|
-
>>> ).reshape(array.shape)
|
306
|
-
|
307
|
-
Note that different arrays (e.g. from PyTorch, Tensorflow) might require different
|
308
|
-
serialization mechanism. Howerver, they often support a conversion to NumPy,
|
309
|
-
therefore allowing to use the same or similar steps as in the example above.
|
327
|
+
>>> arr1 = np.random.randn(3, 3)
|
328
|
+
>>> arr2 = np.random.randn(2, 2)
|
329
|
+
>>> p_record = ParametersRecord([arr1, arr2])
|
330
|
+
|
331
|
+
Initializing with a PyTorch model state_dict:
|
332
|
+
|
333
|
+
>>> import torch.nn as nn
|
334
|
+
>>> model = nn.Linear(10, 5)
|
335
|
+
>>> p_record = ParametersRecord(model.state_dict())
|
336
|
+
|
337
|
+
Initializing with a TensorFlow model weights (a list of NumPy arrays):
|
338
|
+
|
339
|
+
>>> import tensorflow as tf
|
340
|
+
>>> model = tf.keras.Sequential([tf.keras.layers.Dense(5, input_shape=(10,))])
|
341
|
+
>>> p_record = ParametersRecord(model.get_weights())
|
310
342
|
"""
|
311
343
|
|
312
|
-
|
344
|
+
@overload
|
345
|
+
def __init__(self) -> None: ... # noqa: E704
|
346
|
+
|
347
|
+
@overload
|
348
|
+
def __init__( # noqa: E704
|
349
|
+
self, array_dict: OrderedDict[str, Array], *, keep_input: bool = True
|
350
|
+
) -> None: ...
|
351
|
+
|
352
|
+
@overload
|
353
|
+
def __init__( # noqa: E704
|
354
|
+
self, numpy_ndarrays: list[NDArray], *, keep_input: bool = True
|
355
|
+
) -> None: ...
|
356
|
+
|
357
|
+
@overload
|
358
|
+
def __init__( # noqa: E704
|
359
|
+
self,
|
360
|
+
torch_state_dict: OrderedDict[str, torch.Tensor],
|
361
|
+
*,
|
362
|
+
keep_input: bool = True,
|
363
|
+
) -> None: ...
|
364
|
+
|
365
|
+
def __init__( # pylint: disable=too-many-arguments
|
313
366
|
self,
|
367
|
+
*args: Any,
|
368
|
+
numpy_ndarrays: list[NDArray] | None = None,
|
369
|
+
torch_state_dict: OrderedDict[str, torch.Tensor] | None = None,
|
314
370
|
array_dict: OrderedDict[str, Array] | None = None,
|
315
|
-
keep_input: bool =
|
371
|
+
keep_input: bool = True,
|
316
372
|
) -> None:
|
317
373
|
super().__init__(_check_key, _check_value)
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
374
|
+
|
375
|
+
# Determine the initialization method and validates input arguments.
|
376
|
+
# Support the following initialization formats:
|
377
|
+
# 1. cls(array_dict: OrderedDict[str, Array], keep_input: bool)
|
378
|
+
# 2. cls(numpy_ndarrays: list[NDArray], keep_input: bool)
|
379
|
+
# 3. cls(torch_state_dict: dict[str, torch.Tensor], keep_input: bool)
|
380
|
+
|
381
|
+
# Init the argument
|
382
|
+
if len(args) > 1:
|
383
|
+
_raise_parameters_record_init_error()
|
384
|
+
arg = args[0] if args else None
|
385
|
+
init_method: str | None = None # Track which init method is being used
|
386
|
+
|
387
|
+
# Try to assign a value to arg if it's not already set.
|
388
|
+
# If an initialization method is provided, update init_method.
|
389
|
+
def _try_set_arg(_arg: Any, method: str) -> None:
|
390
|
+
# Skip if _arg is None
|
391
|
+
if _arg is None:
|
392
|
+
return
|
393
|
+
nonlocal arg, init_method
|
394
|
+
# Raise an error if arg is already set
|
395
|
+
if arg is not None:
|
396
|
+
_raise_parameters_record_init_error()
|
397
|
+
# Raise an error if a different initialization method is already set
|
398
|
+
if init_method is not None:
|
399
|
+
_raise_parameters_record_init_error()
|
400
|
+
# Set init_method and arg
|
401
|
+
if init_method is None:
|
402
|
+
init_method = method
|
403
|
+
arg = _arg
|
404
|
+
|
405
|
+
# Try to set keyword arguments
|
406
|
+
_try_set_arg(array_dict, "array_dict")
|
407
|
+
_try_set_arg(numpy_ndarrays, "numpy_ndarrays")
|
408
|
+
_try_set_arg(torch_state_dict, "state_dict")
|
409
|
+
|
410
|
+
# If no arguments are provided, return and keep self empty
|
411
|
+
if arg is None:
|
412
|
+
return
|
413
|
+
|
414
|
+
# Handle dictionary of Arrays
|
415
|
+
if not init_method or init_method == "array_dict":
|
416
|
+
# Type check the input
|
417
|
+
if (
|
418
|
+
isinstance(arg, dict)
|
419
|
+
and all(isinstance(k, str) for k in arg.keys())
|
420
|
+
and all(isinstance(v, Array) for v in arg.values())
|
421
|
+
):
|
422
|
+
array_dict = cast(OrderedDict[str, Array], arg)
|
423
|
+
converted = self.from_array_dict(array_dict, keep_input=keep_input)
|
424
|
+
self.__dict__.update(converted.__dict__)
|
425
|
+
return
|
426
|
+
|
427
|
+
# Handle NumPy ndarrays
|
428
|
+
if not init_method or init_method == "numpy_ndarrays":
|
429
|
+
# Type check the input
|
430
|
+
# pylint: disable-next=not-an-iterable
|
431
|
+
if isinstance(arg, list) and all(isinstance(v, np.ndarray) for v in arg):
|
432
|
+
numpy_ndarrays = cast(list[NDArray], arg)
|
433
|
+
converted = self.from_numpy_ndarrays(
|
434
|
+
numpy_ndarrays, keep_input=keep_input
|
435
|
+
)
|
436
|
+
self.__dict__.update(converted.__dict__)
|
437
|
+
return
|
438
|
+
|
439
|
+
# Handle PyTorch state_dict
|
440
|
+
if not init_method or init_method == "state_dict":
|
441
|
+
# Type check the input
|
442
|
+
if (
|
443
|
+
(torch := sys.modules.get("torch")) is not None
|
444
|
+
and isinstance(arg, dict)
|
445
|
+
and all(isinstance(k, str) for k in arg.keys())
|
446
|
+
and all(isinstance(v, torch.Tensor) for v in arg.values())
|
447
|
+
):
|
448
|
+
torch_state_dict = cast(
|
449
|
+
OrderedDict[str, torch.Tensor], arg # type: ignore
|
450
|
+
)
|
451
|
+
converted = self.from_torch_state_dict(
|
452
|
+
torch_state_dict, keep_input=keep_input
|
453
|
+
)
|
454
|
+
self.__dict__.update(converted.__dict__)
|
455
|
+
return
|
456
|
+
|
457
|
+
_raise_parameters_record_init_error()
|
458
|
+
|
459
|
+
@classmethod
|
460
|
+
def from_array_dict(
|
461
|
+
cls,
|
462
|
+
array_dict: OrderedDict[str, Array],
|
463
|
+
*,
|
464
|
+
keep_input: bool = True,
|
465
|
+
) -> ParametersRecord:
|
466
|
+
"""Create ParametersRecord from a dictionary of :class:`Array`."""
|
467
|
+
record = ParametersRecord()
|
468
|
+
for k, v in array_dict.items():
|
469
|
+
record[k] = Array(
|
470
|
+
dtype=v.dtype, shape=list(v.shape), stype=v.stype, data=v.data
|
471
|
+
)
|
472
|
+
if not keep_input:
|
473
|
+
array_dict.clear()
|
474
|
+
return record
|
475
|
+
|
476
|
+
@classmethod
|
477
|
+
def from_numpy_ndarrays(
|
478
|
+
cls,
|
479
|
+
ndarrays: list[NDArray],
|
480
|
+
*,
|
481
|
+
keep_input: bool = True,
|
482
|
+
) -> ParametersRecord:
|
483
|
+
"""Create ParametersRecord from a list of NumPy ``ndarray``."""
|
484
|
+
record = ParametersRecord()
|
485
|
+
total_serialized_bytes = 0
|
486
|
+
|
487
|
+
for i in range(len(ndarrays)): # pylint: disable=C0200
|
488
|
+
record[str(i)] = Array.from_numpy_ndarray(ndarrays[i])
|
489
|
+
|
490
|
+
if not keep_input:
|
491
|
+
# Remove the reference
|
492
|
+
ndarrays[i] = None # type: ignore
|
493
|
+
total_serialized_bytes += len(record[str(i)].data)
|
494
|
+
|
495
|
+
# If total serialized data exceeds the threshold, trigger GC
|
496
|
+
if total_serialized_bytes > GC_THRESHOLD:
|
497
|
+
total_serialized_bytes = 0
|
498
|
+
gc.collect()
|
499
|
+
|
500
|
+
if not keep_input:
|
501
|
+
# Clear the entire list to remove all references and force GC
|
502
|
+
ndarrays.clear()
|
503
|
+
gc.collect()
|
504
|
+
return record
|
505
|
+
|
506
|
+
@classmethod
|
507
|
+
def from_torch_state_dict(
|
508
|
+
cls,
|
509
|
+
state_dict: OrderedDict[str, torch.Tensor],
|
510
|
+
*,
|
511
|
+
keep_input: bool = True,
|
512
|
+
) -> ParametersRecord:
|
513
|
+
"""Create ParametersRecord from PyTorch ``state_dict``."""
|
514
|
+
if "torch" not in sys.modules:
|
515
|
+
raise RuntimeError(
|
516
|
+
f"PyTorch is required to use {cls.from_torch_state_dict.__name__}"
|
517
|
+
)
|
518
|
+
|
519
|
+
record = ParametersRecord()
|
520
|
+
|
521
|
+
for k in list(state_dict.keys()):
|
522
|
+
v = state_dict[k] if keep_input else state_dict.pop(k)
|
523
|
+
record[k] = Array.from_numpy_ndarray(v.detach().cpu().numpy())
|
524
|
+
|
525
|
+
return record
|
526
|
+
|
527
|
+
def to_numpy_ndarrays(self, *, keep_input: bool = True) -> list[NDArray]:
|
528
|
+
"""Return the ParametersRecord as a list of NumPy ``ndarray``."""
|
529
|
+
if keep_input:
|
530
|
+
return [v.numpy() for v in self.values()]
|
531
|
+
|
532
|
+
# Clear the record and return the list of NumPy arrays
|
533
|
+
ret: list[NDArray] = []
|
534
|
+
total_serialized_bytes = 0
|
535
|
+
for k in list(self.keys()):
|
536
|
+
arr = self.pop(k)
|
537
|
+
ret.append(arr.numpy())
|
538
|
+
total_serialized_bytes += len(arr.data)
|
539
|
+
del arr
|
540
|
+
|
541
|
+
# If total serialized data exceeds the threshold, trigger GC
|
542
|
+
if total_serialized_bytes > GC_THRESHOLD:
|
543
|
+
total_serialized_bytes = 0
|
544
|
+
gc.collect()
|
545
|
+
|
546
|
+
if not keep_input:
|
547
|
+
# Force GC
|
548
|
+
gc.collect()
|
549
|
+
return ret
|
550
|
+
|
551
|
+
def to_torch_state_dict(
|
552
|
+
self, *, keep_input: bool = True
|
553
|
+
) -> OrderedDict[str, torch.Tensor]:
|
554
|
+
"""Return the ParametersRecord as a PyTorch ``state_dict``."""
|
555
|
+
if not (torch := sys.modules.get("torch")):
|
556
|
+
raise RuntimeError(
|
557
|
+
f"PyTorch is required to use {self.to_torch_state_dict.__name__}"
|
558
|
+
)
|
559
|
+
|
560
|
+
state_dict = OrderedDict()
|
561
|
+
|
562
|
+
for k in list(self.keys()):
|
563
|
+
arr = self[k] if keep_input else self.pop(k)
|
564
|
+
state_dict[k] = torch.from_numpy(arr.numpy())
|
565
|
+
|
566
|
+
return state_dict
|
323
567
|
|
324
568
|
def count_bytes(self) -> int:
|
325
569
|
"""Return number of Bytes stored in this object.
|
flwr/server/__init__.py
CHANGED
@@ -21,7 +21,7 @@ from .app import start_server as start_server
|
|
21
21
|
from .client_manager import ClientManager as ClientManager
|
22
22
|
from .client_manager import SimpleClientManager as SimpleClientManager
|
23
23
|
from .compat import LegacyContext as LegacyContext
|
24
|
-
from .
|
24
|
+
from .grid import Driver as Driver
|
25
25
|
from .history import History as History
|
26
26
|
from .server import Server as Server
|
27
27
|
from .server_app import ServerApp as ServerApp
|
flwr/server/app.py
CHANGED
@@ -79,13 +79,13 @@ from .history import History
|
|
79
79
|
from .server import Server, init_defaults, run_fl
|
80
80
|
from .server_config import ServerConfig
|
81
81
|
from .strategy import Strategy
|
82
|
-
from .superlink.driver.serverappio_grpc import run_serverappio_api_grpc
|
83
82
|
from .superlink.ffs.ffs_factory import FfsFactory
|
84
83
|
from .superlink.fleet.grpc_adapter.grpc_adapter_servicer import GrpcAdapterServicer
|
85
84
|
from .superlink.fleet.grpc_bidi.grpc_server import start_grpc_server
|
86
85
|
from .superlink.fleet.grpc_rere.fleet_servicer import FleetServicer
|
87
86
|
from .superlink.fleet.grpc_rere.server_interceptor import AuthenticateServerInterceptor
|
88
87
|
from .superlink.linkstate import LinkStateFactory
|
88
|
+
from .superlink.serverappio.serverappio_grpc import run_serverappio_api_grpc
|
89
89
|
from .superlink.simulation.simulationio_grpc import run_simulationio_api_grpc
|
90
90
|
|
91
91
|
DATABASE = ":flwr-in-memory-state:"
|
flwr/server/compat/app.py
CHANGED
@@ -25,7 +25,7 @@ from flwr.server.server import Server, init_defaults, run_fl
|
|
25
25
|
from flwr.server.server_config import ServerConfig
|
26
26
|
from flwr.server.strategy import Strategy
|
27
27
|
|
28
|
-
from ..
|
28
|
+
from ..grid import Driver
|
29
29
|
from .app_utils import start_update_client_manager_thread
|
30
30
|
|
31
31
|
|
flwr/server/compat/app_utils.py
CHANGED
@@ -20,8 +20,8 @@ import threading
|
|
20
20
|
from flwr.common.typing import RunNotRunningException
|
21
21
|
|
22
22
|
from ..client_manager import ClientManager
|
23
|
-
from ..
|
24
|
-
from
|
23
|
+
from ..grid import Driver
|
24
|
+
from .grid_client_proxy import DriverClientProxy
|
25
25
|
|
26
26
|
|
27
27
|
def start_update_client_manager_thread(
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright
|
1
|
+
# Copyright 2025 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.
|
@@ -22,7 +22,7 @@ from flwr.common import Message, MessageType, MessageTypeLegacy, RecordSet
|
|
22
22
|
from flwr.common import recordset_compat as compat
|
23
23
|
from flwr.server.client_proxy import ClientProxy
|
24
24
|
|
25
|
-
from ..
|
25
|
+
from ..grid.grid import Driver
|
26
26
|
|
27
27
|
|
28
28
|
class DriverClientProxy(ClientProxy):
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright
|
1
|
+
# Copyright 2025 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.
|
@@ -15,9 +15,9 @@
|
|
15
15
|
"""Flower driver SDK."""
|
16
16
|
|
17
17
|
|
18
|
-
from .
|
19
|
-
from .
|
20
|
-
from .
|
18
|
+
from .grid import Driver
|
19
|
+
from .grpc_grid import GrpcDriver
|
20
|
+
from .inmemory_grid import InMemoryDriver
|
21
21
|
|
22
22
|
__all__ = [
|
23
23
|
"Driver",
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright
|
1
|
+
# Copyright 2025 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.
|
@@ -16,7 +16,6 @@
|
|
16
16
|
|
17
17
|
|
18
18
|
import time
|
19
|
-
import warnings
|
20
19
|
from collections.abc import Iterable
|
21
20
|
from logging import DEBUG, ERROR, WARNING
|
22
21
|
from typing import Optional, cast
|
@@ -46,7 +45,7 @@ from flwr.proto.serverappio_pb2 import ( # pylint: disable=E0611
|
|
46
45
|
)
|
47
46
|
from flwr.proto.serverappio_pb2_grpc import ServerAppIoStub # pylint: disable=E0611
|
48
47
|
|
49
|
-
from .
|
48
|
+
from .grid import Driver
|
50
49
|
|
51
50
|
ERROR_MESSAGE_PUSH_MESSAGES_RESOURCE_EXHAUSTED = """
|
52
51
|
|
@@ -183,14 +182,6 @@ class GrpcDriver(Driver):
|
|
183
182
|
This method constructs a new `Message` with given content and metadata.
|
184
183
|
The `run_id` and `src_node_id` will be set automatically.
|
185
184
|
"""
|
186
|
-
if ttl:
|
187
|
-
warnings.warn(
|
188
|
-
"A custom TTL was set, but note that the SuperLink does not enforce "
|
189
|
-
"the TTL yet. The SuperLink will start enforcing the TTL in a future "
|
190
|
-
"version of Flower.",
|
191
|
-
stacklevel=2,
|
192
|
-
)
|
193
|
-
|
194
185
|
ttl_ = DEFAULT_TTL if ttl is None else ttl
|
195
186
|
metadata = Metadata(
|
196
187
|
run_id=cast(Run, self._run).run_id,
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright
|
1
|
+
# Copyright 2025 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.
|
@@ -16,7 +16,6 @@
|
|
16
16
|
|
17
17
|
|
18
18
|
import time
|
19
|
-
import warnings
|
20
19
|
from collections.abc import Iterable
|
21
20
|
from typing import Optional, cast
|
22
21
|
from uuid import UUID
|
@@ -27,7 +26,7 @@ from flwr.common.typing import Run
|
|
27
26
|
from flwr.proto.node_pb2 import Node # pylint: disable=E0611
|
28
27
|
from flwr.server.superlink.linkstate import LinkStateFactory
|
29
28
|
|
30
|
-
from .
|
29
|
+
from .grid import Driver
|
31
30
|
|
32
31
|
|
33
32
|
class InMemoryDriver(Driver):
|
@@ -88,13 +87,6 @@ class InMemoryDriver(Driver):
|
|
88
87
|
This method constructs a new `Message` with given content and metadata.
|
89
88
|
The `run_id` and `src_node_id` will be set automatically.
|
90
89
|
"""
|
91
|
-
if ttl:
|
92
|
-
warnings.warn(
|
93
|
-
"A custom TTL was set, but note that the SuperLink does not enforce "
|
94
|
-
"the TTL yet. The SuperLink will start enforcing the TTL in a future "
|
95
|
-
"version of Flower.",
|
96
|
-
stacklevel=2,
|
97
|
-
)
|
98
90
|
ttl_ = DEFAULT_TTL if ttl is None else ttl
|
99
91
|
|
100
92
|
metadata = Metadata(
|
flwr/server/run_serverapp.py
CHANGED
flwr/server/server_app.py
CHANGED
@@ -25,7 +25,7 @@ from flwr.server.strategy import Strategy
|
|
25
25
|
|
26
26
|
from .client_manager import ClientManager
|
27
27
|
from .compat import start_driver
|
28
|
-
from .
|
28
|
+
from .grid import Driver
|
29
29
|
from .server import Server
|
30
30
|
from .server_config import ServerConfig
|
31
31
|
from .typing import ServerAppCallable, ServerFn
|
@@ -207,7 +207,7 @@ class ServerApp: # pylint: disable=too-many-instance-attributes
|
|
207
207
|
"""
|
208
208
|
|
209
209
|
def lifespan_decorator(
|
210
|
-
lifespan_fn: Callable[[Context], Iterator[None]]
|
210
|
+
lifespan_fn: Callable[[Context], Iterator[None]],
|
211
211
|
) -> Callable[[Context], Iterator[None]]:
|
212
212
|
"""Register the lifespan fn with the ServerApp object."""
|
213
213
|
|
flwr/server/serverapp/app.py
CHANGED
@@ -60,7 +60,7 @@ from flwr.proto.serverappio_pb2 import ( # pylint: disable=E0611
|
|
60
60
|
PullServerAppInputsResponse,
|
61
61
|
PushServerAppOutputsRequest,
|
62
62
|
)
|
63
|
-
from flwr.server.
|
63
|
+
from flwr.server.grid.grpc_grid import GrpcDriver
|
64
64
|
from flwr.server.run_serverapp import run as run_
|
65
65
|
|
66
66
|
|
flwr/server/typing.py
CHANGED
@@ -36,7 +36,7 @@ from flwr.common.constant import MessageType, MessageTypeLegacy
|
|
36
36
|
from ..client_proxy import ClientProxy
|
37
37
|
from ..compat.app_utils import start_update_client_manager_thread
|
38
38
|
from ..compat.legacy_context import LegacyContext
|
39
|
-
from ..
|
39
|
+
from ..grid import Driver
|
40
40
|
from ..typing import Workflow
|
41
41
|
from .constant import MAIN_CONFIGS_RECORD, MAIN_PARAMS_RECORD, Key
|
42
42
|
|
@@ -55,7 +55,7 @@ from flwr.common.secure_aggregation.secaggplus_constants import (
|
|
55
55
|
from flwr.common.secure_aggregation.secaggplus_utils import pseudo_rand_gen
|
56
56
|
from flwr.server.client_proxy import ClientProxy
|
57
57
|
from flwr.server.compat.legacy_context import LegacyContext
|
58
|
-
from flwr.server.
|
58
|
+
from flwr.server.grid import Driver
|
59
59
|
|
60
60
|
from ..constant import MAIN_CONFIGS_RECORD, MAIN_PARAMS_RECORD
|
61
61
|
from ..constant import Key as WorkflowKey
|
@@ -39,7 +39,7 @@ from flwr.common.logger import (
|
|
39
39
|
warn_deprecated_feature_with_example,
|
40
40
|
)
|
41
41
|
from flwr.common.typing import Run, RunStatus, UserConfig
|
42
|
-
from flwr.server.
|
42
|
+
from flwr.server.grid import Driver, InMemoryDriver
|
43
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
|
{flwr_nightly-1.17.0.dev20250317.dist-info → flwr_nightly-1.17.0.dev20250318.dist-info}/RECORD
RENAMED
@@ -116,7 +116,7 @@ flwr/common/args.py,sha256=2gGT2a3SPJ0-LTNKnhBsZ-ESIoW9FGpw-9xkUSs8qwk,5417
|
|
116
116
|
flwr/common/auth_plugin/__init__.py,sha256=1Y8Oj3iB49IHDu9tvDih1J74Ygu7k85V9s2A4WORPyA,887
|
117
117
|
flwr/common/auth_plugin/auth_plugin.py,sha256=dQU5U4uJIA5XqgOJ3PankHWq-uXCaMvO74khaMPGdiU,3938
|
118
118
|
flwr/common/config.py,sha256=SAkG3BztnA6iupXxF3GAIpGmWVVCH0ptyMpC9yjr_14,13965
|
119
|
-
flwr/common/constant.py,sha256=
|
119
|
+
flwr/common/constant.py,sha256=PvW7StHhK4QuqyDlDpsvLbCxVGG2Dau6z6s1m8MGvfU,6946
|
120
120
|
flwr/common/context.py,sha256=uJ-mnoC_8y_udEb3kAX-r8CPphNTWM72z1AlsvQEu54,2403
|
121
121
|
flwr/common/date.py,sha256=NHHpESce5wYqEwoDXf09gp9U9l_5Bmlh2BsOcwS-kDM,1554
|
122
122
|
flwr/common/differential_privacy.py,sha256=YA01NqjddKNAEVmf7hXmOVxOjhekgzvJudk3mBGq-2k,6148
|
@@ -138,7 +138,7 @@ flwr/common/record/__init__.py,sha256=LUixpq0Z-lMJwCIu1-4u5HfvRPjRMRgoAc6YJQ6UEO
|
|
138
138
|
flwr/common/record/configsrecord.py,sha256=i40jOzBx04ysZKECwaw4FdUXMdY9HgdY8GAqKdTO1Lw,6486
|
139
139
|
flwr/common/record/conversion_utils.py,sha256=ZcsM-vTm_rVtLXLFD2RY3N47V_hUr3ywTdtnpVXnOGU,1202
|
140
140
|
flwr/common/record/metricsrecord.py,sha256=UywkEPbifiu_IyPUFoDJCi8WEVLujlqZERUWAWpc3vs,5752
|
141
|
-
flwr/common/record/parametersrecord.py,sha256=
|
141
|
+
flwr/common/record/parametersrecord.py,sha256=EGnpnfw68P22qqbUWuDFjURMqDOvSUkfZGq7lYQLbUI,21597
|
142
142
|
flwr/common/record/recordset.py,sha256=ambtB74uF1pooQTfcBt1_xWsjvyDjGMc6awEt20ur2A,8547
|
143
143
|
flwr/common/record/typeddict.py,sha256=q5hL2xkXymuiCprHWb69mUmLpWQk_XXQq0hGQ69YPaw,3599
|
144
144
|
flwr/common/recordset_compat.py,sha256=ViSwA26h6Q55ZmV1LLjSJpcKiipV-p_JpCj4wxdE-Ow,14230
|
@@ -213,28 +213,28 @@ flwr/proto/transport_pb2.pyi,sha256=ipHQ03eFBqsxtAuAVefZ2lVr04BZ4YifJCS2eauNmy8,
|
|
213
213
|
flwr/proto/transport_pb2_grpc.py,sha256=vLN3EHtx2aEEMCO4f1Upu-l27BPzd3-5pV-u8wPcosk,2598
|
214
214
|
flwr/proto/transport_pb2_grpc.pyi,sha256=AGXf8RiIiW2J5IKMlm_3qT3AzcDa4F3P5IqUjve_esA,766
|
215
215
|
flwr/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
216
|
-
flwr/server/__init__.py,sha256=
|
217
|
-
flwr/server/app.py,sha256=
|
216
|
+
flwr/server/__init__.py,sha256=ISimHyzdi2Xnh-WObEdqOwRmhZ7xZzgqWddcq9ixZ3M,1526
|
217
|
+
flwr/server/app.py,sha256=Hc5FIcGPoeKk7D2Mqp-qgDJUHh-I3uAWG7MDuqeasUo,33619
|
218
218
|
flwr/server/client_manager.py,sha256=7Ese0tgrH-i-ms363feYZJKwB8gWnXSmg_hYF2Bju4U,6227
|
219
219
|
flwr/server/client_proxy.py,sha256=4G-oTwhb45sfWLx2uZdcXD98IZwdTS6F88xe3akCdUg,2399
|
220
220
|
flwr/server/compat/__init__.py,sha256=VxnJtJyOjNFQXMNi9hIuzNlZM5n0Hj1p3aq_Pm2udw4,892
|
221
|
-
flwr/server/compat/app.py,sha256=
|
222
|
-
flwr/server/compat/app_utils.py,sha256=
|
223
|
-
flwr/server/compat/
|
221
|
+
flwr/server/compat/app.py,sha256=dBxWAkPy4Bc1ExDemdDaZt3xu5osVSOur0YvETgQT4w,3367
|
222
|
+
flwr/server/compat/app_utils.py,sha256=fTuoCe-3IAgHRhbIy2JL0M2_v_jR6HwAAs6R2yZ7uPQ,3812
|
223
|
+
flwr/server/compat/grid_client_proxy.py,sha256=fiibkMOk_gbX1SMm16H5DPwpjirD5uq423wMn56b_bQ,4960
|
224
224
|
flwr/server/compat/legacy_context.py,sha256=wBzBcfV6YO6IQGriM_FdJ5XZfiBBEEJdS_OdAiF47dY,1804
|
225
225
|
flwr/server/criterion.py,sha256=ypbAexbztzGUxNen9RCHF91QeqiEQix4t4Ih3E-42MM,1061
|
226
|
-
flwr/server/driver/__init__.py,sha256=bikRv6CjTwSvYh7tf10gziU5o2YotOWhhftz2tr3KDc,886
|
227
|
-
flwr/server/driver/driver.py,sha256=X072eFWl8Kx-aZbahTkpAc1wwoojr8A4uO2yozwwSbE,5705
|
228
|
-
flwr/server/driver/grpc_driver.py,sha256=rbSqFhT2ULLQhgIeX24Yt1wZje4bzV4EUoOmbIuVYro,11507
|
229
|
-
flwr/server/driver/inmemory_driver.py,sha256=p6p9RykDfoty94izzD4i11Xp7A8t1KUaHpbKbbVZAdU,6407
|
230
226
|
flwr/server/fleet_event_log_interceptor.py,sha256=AkL7Y5d3xm2vRhL3ahmEVVoOvAP7PA7dRgB-je4v-Ys,3774
|
227
|
+
flwr/server/grid/__init__.py,sha256=AiZbyU5kWlpjmI-eDWqztz6EBKoTm0kvRphydiibi08,880
|
228
|
+
flwr/server/grid/grid.py,sha256=fnHtnReACB7aUxcWmbGfI2elHsk5HOp7q8BpbwWMfvc,5705
|
229
|
+
flwr/server/grid/grpc_grid.py,sha256=OR9AxXn1YI5SilROntnpduoOoZzE3eDjM-JCqetHfHM,11190
|
230
|
+
flwr/server/grid/inmemory_grid.py,sha256=ClnJwdFTnTyAKN7M2jsd2ZKArgslySkcwFab2kXAND0,6091
|
231
231
|
flwr/server/history.py,sha256=qSb5_pPTrwofpSYGsZWzMPkl_4uJ4mJFWesxXDrEvDU,5026
|
232
|
-
flwr/server/run_serverapp.py,sha256=
|
232
|
+
flwr/server/run_serverapp.py,sha256=LxHIeMLKXbzt2V5vK2x8wJLZt1dQ_0YiMD1lP0PZ27I,2075
|
233
233
|
flwr/server/server.py,sha256=1ZsFEptmAV-L2vP2etNC9Ed5CLSxpuKzUFkAPQ4l5Xc,17893
|
234
|
-
flwr/server/server_app.py,sha256=
|
234
|
+
flwr/server/server_app.py,sha256=WOCUOB_Onf_p5qp_QBaRu-LmsMpFIn-Hd4HcWIxN1YE,8856
|
235
235
|
flwr/server/server_config.py,sha256=CZaHVAsMvGLjpWVcLPkiYxgJN4xfIyAiUrCI3fETKY4,1349
|
236
236
|
flwr/server/serverapp/__init__.py,sha256=L0K-94UDdTyEZ8LDtYybGIIIv3HW6AhSVjXMUfYJQnQ,800
|
237
|
-
flwr/server/serverapp/app.py,sha256=
|
237
|
+
flwr/server/serverapp/app.py,sha256=NoBpAokHP5-Gw8-wrm0H1Pqf_VXZLs9yp7RM13f4I9Y,8647
|
238
238
|
flwr/server/serverapp_components.py,sha256=-IV_CitOfrJclJj2jNdbN1Q65PyFmtKtrTIg1hc6WQw,2118
|
239
239
|
flwr/server/strategy/__init__.py,sha256=tQer2SwjDnvgFFuJMZM-S01Z615N5XK6MaCvpm4BMU0,2836
|
240
240
|
flwr/server/strategy/aggregate.py,sha256=PDvekufza13s9AsVmz9WASunaBs3yCtl8JVliFx9j6Q,13978
|
@@ -261,9 +261,6 @@ flwr/server/strategy/krum.py,sha256=Gct2OdnvZEnCPKMyIC330baOKabpDrKiCfVXIkr4S0c,
|
|
261
261
|
flwr/server/strategy/qfedavg.py,sha256=2ijNNc2vVODWLAaoYo9PCoaFvlanq0lbJ7I7Albdudg,10131
|
262
262
|
flwr/server/strategy/strategy.py,sha256=cXapkD5uDrt5C-RbmWDn9FLoap3Q41i7GKvbmfbCKtk,7524
|
263
263
|
flwr/server/superlink/__init__.py,sha256=8tHYCfodUlRD8PCP9fHgvu8cz5N31A2QoRVL0jDJ15E,707
|
264
|
-
flwr/server/superlink/driver/__init__.py,sha256=5soEK5QSvxNjmJQ-CGTWROc4alSAeU0e9Ad9RDhsd3E,717
|
265
|
-
flwr/server/superlink/driver/serverappio_grpc.py,sha256=UzHwo6qYZMeOhr7nn1iZbcyDSmwvnq_kpYH0mEAndW0,2173
|
266
|
-
flwr/server/superlink/driver/serverappio_servicer.py,sha256=Y-L0SiaP1p4yEi6r6MWOMiW10nsu_TlAcj_0miaEYSo,13121
|
267
264
|
flwr/server/superlink/ffs/__init__.py,sha256=FAY-zShcfPmOxosok2QyT6hTNMNctG8cH9s_nIl8jkI,840
|
268
265
|
flwr/server/superlink/ffs/disk_ffs.py,sha256=n_Ah0sQwXGVQ9wj5965nLjdkQQbpoHCljjXKFnwftsU,3297
|
269
266
|
flwr/server/superlink/ffs/ffs.py,sha256=qLI1UfosJugu2BKOJWqHIhafTm-YiuKqGf3OGWPH0NM,2395
|
@@ -294,20 +291,23 @@ flwr/server/superlink/linkstate/linkstate.py,sha256=YB3SryGNvt-bE-unYjoloJt9d3xA
|
|
294
291
|
flwr/server/superlink/linkstate/linkstate_factory.py,sha256=ISSMjDlwuN7swxjOeYlTNpI_kuZ8PGkMcJnf1dbhUSE,2069
|
295
292
|
flwr/server/superlink/linkstate/sqlite_linkstate.py,sha256=Wsx5gD6WRIMLlKarvVV1_dlS7jmfno-yTVW1-rgcIto,38276
|
296
293
|
flwr/server/superlink/linkstate/utils.py,sha256=b26MJdMQyt83EDnhB7FAiq8BFttV_qNHF_E_3d3oBlA,12739
|
294
|
+
flwr/server/superlink/serverappio/__init__.py,sha256=Fy4zJuoccZe5mZSEIpOmQvU6YeXFBa1M4eZuXXmJcn8,717
|
295
|
+
flwr/server/superlink/serverappio/serverappio_grpc.py,sha256=opJ6SYwIAbu4NWEo3K-VxFO-tMSFmE4H3i2HwHIVRzw,2173
|
296
|
+
flwr/server/superlink/serverappio/serverappio_servicer.py,sha256=71s1SijefpTpJC2mZD3Y0CZBK9PtK0Yxc4aXawdvEDQ,13121
|
297
297
|
flwr/server/superlink/simulation/__init__.py,sha256=mg-oapC9dkzEfjXPQFior5lpWj4g9kwbLovptyYM_g0,718
|
298
298
|
flwr/server/superlink/simulation/simulationio_grpc.py,sha256=8aUrZZLdvprKUfLLqFID4aItus9beU6m1qLQYIPB7k0,2224
|
299
299
|
flwr/server/superlink/simulation/simulationio_servicer.py,sha256=J_TmdqM-Bxgp-iPEI3tvCuBpykw1UX0FouMQalEYAF4,6907
|
300
300
|
flwr/server/superlink/utils.py,sha256=KVb3K_g2vYfu9TnftcN0ewmev133WZcjuEePMm8d7GE,2137
|
301
|
-
flwr/server/typing.py,sha256=
|
301
|
+
flwr/server/typing.py,sha256=Xhcda1Bg2w8C2nZAdoMWsZqQibzJrnLBP60yzyRa7QE,1017
|
302
302
|
flwr/server/utils/__init__.py,sha256=vnS9EAyVUsBOmWeYZXMoBcjeEFhqN4_KQQVk5EBiWG0,884
|
303
303
|
flwr/server/utils/tensorboard.py,sha256=gEBD8w_5uaIfp5aw5RYH66lYZpd_SfkObHQ7eDd9MUk,5466
|
304
304
|
flwr/server/utils/validator.py,sha256=11olMv1UyeaxLa1ci5gsJ0WALk7VwWGCQYCvLsZ56LY,3604
|
305
305
|
flwr/server/workflow/__init__.py,sha256=SXY0XkwbkezFBxxrFB5hKUtmtAgnYISBkPouR1V71ss,902
|
306
306
|
flwr/server/workflow/constant.py,sha256=q4DLdR8Krlxuewq2AQjwTL75hphxE5ODNz4AhViHMXk,1082
|
307
|
-
flwr/server/workflow/default_workflows.py,sha256=
|
307
|
+
flwr/server/workflow/default_workflows.py,sha256=2c_T5NxjIn--zBWAcVWLKHJ9001qV92nCGNvbok_ooo,14150
|
308
308
|
flwr/server/workflow/secure_aggregation/__init__.py,sha256=3XlgDOjD_hcukTGl6Bc1B-8M_dPlVSJuTbvXIbiO-Ic,880
|
309
309
|
flwr/server/workflow/secure_aggregation/secagg_workflow.py,sha256=l2IdMdJjs1bgHs5vQgLSOVzar7v2oxUn46oCrnVE1rM,5839
|
310
|
-
flwr/server/workflow/secure_aggregation/secaggplus_workflow.py,sha256=
|
310
|
+
flwr/server/workflow/secure_aggregation/secaggplus_workflow.py,sha256=SmZnmmQv4D85NwqFhXfycrgSxZ3sGLJCdbI4bUKhM3E,29621
|
311
311
|
flwr/simulation/__init__.py,sha256=5UcDVJNjFoSwWqHbGM1hKfTTUUNdwAtuoNvNrfvdkUY,1556
|
312
312
|
flwr/simulation/app.py,sha256=xRVSJBnTXQUqWIYOzENfTnJlZ24CSNhWkhVEFxIu4I0,9758
|
313
313
|
flwr/simulation/legacy_app.py,sha256=qpZI4Vvzr5TyWSLTRrMP-jN4rH2C25JI9nVSSjhFwSQ,15861
|
@@ -315,7 +315,7 @@ flwr/simulation/ray_transport/__init__.py,sha256=wzcEEwUUlulnXsg6raCA1nGpP3LlAQD
|
|
315
315
|
flwr/simulation/ray_transport/ray_actor.py,sha256=k11yoAPQzFGQU-KnCCP0ZrfPPdUPXXrBe-1DKM5VdW4,18997
|
316
316
|
flwr/simulation/ray_transport/ray_client_proxy.py,sha256=2vjOKoom3B74C6XU-jC3N6DwYmsLdB-lmkHZ_Xrv96o,7367
|
317
317
|
flwr/simulation/ray_transport/utils.py,sha256=wtbQhKQ4jGoiQDLJNQP17m1DSfL22ERhDBGuoeUFaAQ,2393
|
318
|
-
flwr/simulation/run_simulation.py,sha256=
|
318
|
+
flwr/simulation/run_simulation.py,sha256=SmhU83eQKwGcf4qZy4drXptGRhGQHNd38LpK0qrOvUU,20334
|
319
319
|
flwr/simulation/simulationio_connection.py,sha256=lcbEmdjb9RVEF2W5vSbf_J1zlTuv_ZAT_HLox1mqcfY,3494
|
320
320
|
flwr/superexec/__init__.py,sha256=fcj366jh4RFby_vDwLroU4kepzqbnJgseZD_jUr_Mko,715
|
321
321
|
flwr/superexec/app.py,sha256=C0T2LMjuyF__I5V1FKfjtWtbsQPxK_EgL4vuhWIwG8s,1465
|
@@ -326,8 +326,8 @@ flwr/superexec/exec_servicer.py,sha256=4UpzJqPUHkBG2PZNe2lrX7XFVDOL6yw_HcoBHxuXE
|
|
326
326
|
flwr/superexec/exec_user_auth_interceptor.py,sha256=2kXjjJcrZyff893QTFLQD6zxC4pdVwtN4Rc66jHptfE,4440
|
327
327
|
flwr/superexec/executor.py,sha256=_B55WW2TD1fBINpabSSDRenVHXYmvlfhv-k8hJKU4lQ,3115
|
328
328
|
flwr/superexec/simulation.py,sha256=WQDon15oqpMopAZnwRZoTICYCfHqtkvFSqiTQ2hLD_g,4088
|
329
|
-
flwr_nightly-1.17.0.
|
330
|
-
flwr_nightly-1.17.0.
|
331
|
-
flwr_nightly-1.17.0.
|
332
|
-
flwr_nightly-1.17.0.
|
333
|
-
flwr_nightly-1.17.0.
|
329
|
+
flwr_nightly-1.17.0.dev20250318.dist-info/LICENSE,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
|
330
|
+
flwr_nightly-1.17.0.dev20250318.dist-info/METADATA,sha256=b0bYyeMvfyIYiTRIxjtTqkYBBt2zsXMF_J8XhVGEuAc,15878
|
331
|
+
flwr_nightly-1.17.0.dev20250318.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
|
332
|
+
flwr_nightly-1.17.0.dev20250318.dist-info/entry_points.txt,sha256=2-1L-GNKhwGw2_7_RoH55vHw2SIHjdAQy3HAVAWl9PY,374
|
333
|
+
flwr_nightly-1.17.0.dev20250318.dist-info/RECORD,,
|
{flwr_nightly-1.17.0.dev20250317.dist-info → flwr_nightly-1.17.0.dev20250318.dist-info}/LICENSE
RENAMED
File without changes
|
{flwr_nightly-1.17.0.dev20250317.dist-info → flwr_nightly-1.17.0.dev20250318.dist-info}/WHEEL
RENAMED
File without changes
|
File without changes
|