flwr-nightly 1.8.0.dev20240311__py3-none-any.whl → 1.8.0.dev20240312__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of flwr-nightly might be problematic. Click here for more details.
- flwr/client/mod/secure_aggregation/secaggplus_mod.py +31 -40
- flwr/common/pyproject.py +41 -0
- flwr/server/workflow/default_workflows.py +3 -3
- flwr/server/workflow/secure_aggregation/secaggplus_workflow.py +20 -23
- {flwr_nightly-1.8.0.dev20240311.dist-info → flwr_nightly-1.8.0.dev20240312.dist-info}/METADATA +1 -1
- {flwr_nightly-1.8.0.dev20240311.dist-info → flwr_nightly-1.8.0.dev20240312.dist-info}/RECORD +9 -8
- {flwr_nightly-1.8.0.dev20240311.dist-info → flwr_nightly-1.8.0.dev20240312.dist-info}/LICENSE +0 -0
- {flwr_nightly-1.8.0.dev20240311.dist-info → flwr_nightly-1.8.0.dev20240312.dist-info}/WHEEL +0 -0
- {flwr_nightly-1.8.0.dev20240311.dist-info → flwr_nightly-1.8.0.dev20240312.dist-info}/entry_points.txt +0 -0
@@ -12,19 +12,20 @@
|
|
12
12
|
# See the License for the specific language governing permissions and
|
13
13
|
# limitations under the License.
|
14
14
|
# ==============================================================================
|
15
|
-
"""
|
15
|
+
"""Modifier for the SecAgg+ protocol."""
|
16
16
|
|
17
17
|
|
18
18
|
import os
|
19
19
|
from dataclasses import dataclass, field
|
20
|
-
from logging import
|
21
|
-
from typing import Any,
|
20
|
+
from logging import DEBUG, WARNING
|
21
|
+
from typing import Any, Dict, List, Tuple, cast
|
22
22
|
|
23
23
|
from flwr.client.typing import ClientAppCallable
|
24
24
|
from flwr.common import (
|
25
25
|
ConfigsRecord,
|
26
26
|
Context,
|
27
27
|
Message,
|
28
|
+
Parameters,
|
28
29
|
RecordSet,
|
29
30
|
ndarray_to_bytes,
|
30
31
|
parameters_to_ndarrays,
|
@@ -62,7 +63,7 @@ from flwr.common.secure_aggregation.secaggplus_utils import (
|
|
62
63
|
share_keys_plaintext_concat,
|
63
64
|
share_keys_plaintext_separate,
|
64
65
|
)
|
65
|
-
from flwr.common.typing import ConfigsRecordValues
|
66
|
+
from flwr.common.typing import ConfigsRecordValues
|
66
67
|
|
67
68
|
|
68
69
|
@dataclass
|
@@ -132,18 +133,6 @@ class SecAggPlusState:
|
|
132
133
|
return ret
|
133
134
|
|
134
135
|
|
135
|
-
def _get_fit_fn(
|
136
|
-
msg: Message, ctxt: Context, call_next: ClientAppCallable
|
137
|
-
) -> Callable[[], FitRes]:
|
138
|
-
"""Get the fit function."""
|
139
|
-
|
140
|
-
def fit() -> FitRes:
|
141
|
-
out_msg = call_next(msg, ctxt)
|
142
|
-
return compat.recordset_to_fitres(out_msg.content, keep_input=False)
|
143
|
-
|
144
|
-
return fit
|
145
|
-
|
146
|
-
|
147
136
|
def secaggplus_mod(
|
148
137
|
msg: Message,
|
149
138
|
ctxt: Context,
|
@@ -173,25 +162,32 @@ def secaggplus_mod(
|
|
173
162
|
check_configs(state.current_stage, configs)
|
174
163
|
|
175
164
|
# Execute
|
165
|
+
out_content = RecordSet()
|
176
166
|
if state.current_stage == Stage.SETUP:
|
177
167
|
state.nid = msg.metadata.dst_node_id
|
178
168
|
res = _setup(state, configs)
|
179
169
|
elif state.current_stage == Stage.SHARE_KEYS:
|
180
170
|
res = _share_keys(state, configs)
|
181
171
|
elif state.current_stage == Stage.COLLECT_MASKED_VECTORS:
|
182
|
-
|
183
|
-
|
172
|
+
out_msg = call_next(msg, ctxt)
|
173
|
+
out_content = out_msg.content
|
174
|
+
fitres = compat.recordset_to_fitres(out_content, keep_input=True)
|
175
|
+
res = _collect_masked_vectors(
|
176
|
+
state, configs, fitres.num_examples, fitres.parameters
|
177
|
+
)
|
178
|
+
for p_record in out_content.parameters_records.values():
|
179
|
+
p_record.clear()
|
184
180
|
elif state.current_stage == Stage.UNMASK:
|
185
181
|
res = _unmask(state, configs)
|
186
182
|
else:
|
187
|
-
raise ValueError(f"Unknown
|
183
|
+
raise ValueError(f"Unknown SecAgg/SecAgg+ stage: {state.current_stage}")
|
188
184
|
|
189
185
|
# Save state
|
190
186
|
ctxt.state.configs_records[RECORD_KEY_STATE] = ConfigsRecord(state.to_dict())
|
191
187
|
|
192
188
|
# Return message
|
193
|
-
|
194
|
-
return msg.create_reply(
|
189
|
+
out_content.configs_records[RECORD_KEY_CONFIGS] = ConfigsRecord(res, False)
|
190
|
+
return msg.create_reply(out_content, ttl="")
|
195
191
|
|
196
192
|
|
197
193
|
def check_stage(current_stage: str, configs: ConfigsRecord) -> None:
|
@@ -322,7 +318,7 @@ def _setup(
|
|
322
318
|
# Assigning parameter values to object fields
|
323
319
|
sec_agg_param_dict = configs
|
324
320
|
state.sample_num = cast(int, sec_agg_param_dict[Key.SAMPLE_NUMBER])
|
325
|
-
log(
|
321
|
+
log(DEBUG, "Node %d: starting stage 0...", state.nid)
|
326
322
|
|
327
323
|
state.share_num = cast(int, sec_agg_param_dict[Key.SHARE_NUMBER])
|
328
324
|
state.threshold = cast(int, sec_agg_param_dict[Key.THRESHOLD])
|
@@ -347,7 +343,7 @@ def _setup(
|
|
347
343
|
|
348
344
|
state.sk1, state.pk1 = private_key_to_bytes(sk1), public_key_to_bytes(pk1)
|
349
345
|
state.sk2, state.pk2 = private_key_to_bytes(sk2), public_key_to_bytes(pk2)
|
350
|
-
log(
|
346
|
+
log(DEBUG, "Node %d: stage 0 completes. uploading public keys...", state.nid)
|
351
347
|
return {Key.PUBLIC_KEY_1: state.pk1, Key.PUBLIC_KEY_2: state.pk2}
|
352
348
|
|
353
349
|
|
@@ -357,7 +353,7 @@ def _share_keys(
|
|
357
353
|
) -> Dict[str, ConfigsRecordValues]:
|
358
354
|
named_bytes_tuples = cast(Dict[str, Tuple[bytes, bytes]], configs)
|
359
355
|
key_dict = {int(sid): (pk1, pk2) for sid, (pk1, pk2) in named_bytes_tuples.items()}
|
360
|
-
log(
|
356
|
+
log(DEBUG, "Node %d: starting stage 1...", state.nid)
|
361
357
|
state.public_keys_dict = key_dict
|
362
358
|
|
363
359
|
# Check if the size is larger than threshold
|
@@ -409,7 +405,7 @@ def _share_keys(
|
|
409
405
|
dsts.append(nid)
|
410
406
|
ciphertexts.append(ciphertext)
|
411
407
|
|
412
|
-
log(
|
408
|
+
log(DEBUG, "Node %d: stage 1 completes. uploading key shares...", state.nid)
|
413
409
|
return {Key.DESTINATION_LIST: dsts, Key.CIPHERTEXT_LIST: ciphertexts}
|
414
410
|
|
415
411
|
|
@@ -417,9 +413,10 @@ def _share_keys(
|
|
417
413
|
def _collect_masked_vectors(
|
418
414
|
state: SecAggPlusState,
|
419
415
|
configs: ConfigsRecord,
|
420
|
-
|
416
|
+
num_examples: int,
|
417
|
+
updated_parameters: Parameters,
|
421
418
|
) -> Dict[str, ConfigsRecordValues]:
|
422
|
-
log(
|
419
|
+
log(DEBUG, "Node %d: starting stage 2...", state.nid)
|
423
420
|
available_clients: List[int] = []
|
424
421
|
ciphertexts = cast(List[bytes], configs[Key.CIPHERTEXT_LIST])
|
425
422
|
srcs = cast(List[int], configs[Key.SOURCE_LIST])
|
@@ -447,26 +444,20 @@ def _collect_masked_vectors(
|
|
447
444
|
state.rd_seed_share_dict[src] = rd_seed_share
|
448
445
|
state.sk1_share_dict[src] = sk1_share
|
449
446
|
|
450
|
-
# Fit
|
451
|
-
|
452
|
-
if len(fit_res.metrics) > 0:
|
453
|
-
log(
|
454
|
-
WARNING,
|
455
|
-
"The metrics in FitRes will not be preserved or sent to the server.",
|
456
|
-
)
|
457
|
-
ratio = fit_res.num_examples / state.max_weight
|
447
|
+
# Fit
|
448
|
+
ratio = num_examples / state.max_weight
|
458
449
|
if ratio > 1:
|
459
450
|
log(
|
460
451
|
WARNING,
|
461
452
|
"Potential overflow warning: the provided weight (%s) exceeds the specified"
|
462
453
|
" max_weight (%s). This may lead to overflow issues.",
|
463
|
-
|
454
|
+
num_examples,
|
464
455
|
state.max_weight,
|
465
456
|
)
|
466
457
|
q_ratio = round(ratio * state.target_range)
|
467
458
|
dq_ratio = q_ratio / state.target_range
|
468
459
|
|
469
|
-
parameters = parameters_to_ndarrays(
|
460
|
+
parameters = parameters_to_ndarrays(updated_parameters)
|
470
461
|
parameters = parameters_multiply(parameters, dq_ratio)
|
471
462
|
|
472
463
|
# Quantize parameter update (vector)
|
@@ -500,7 +491,7 @@ def _collect_masked_vectors(
|
|
500
491
|
|
501
492
|
# Take mod of final weight update vector and return to server
|
502
493
|
quantized_parameters = parameters_mod(quantized_parameters, state.mod_range)
|
503
|
-
log(
|
494
|
+
log(DEBUG, "Node %d: stage 2 completed, uploading masked parameters...", state.nid)
|
504
495
|
return {
|
505
496
|
Key.MASKED_PARAMETERS: [ndarray_to_bytes(arr) for arr in quantized_parameters]
|
506
497
|
}
|
@@ -509,7 +500,7 @@ def _collect_masked_vectors(
|
|
509
500
|
def _unmask(
|
510
501
|
state: SecAggPlusState, configs: ConfigsRecord
|
511
502
|
) -> Dict[str, ConfigsRecordValues]:
|
512
|
-
log(
|
503
|
+
log(DEBUG, "Node %d: starting stage 3...", state.nid)
|
513
504
|
|
514
505
|
active_nids = cast(List[int], configs[Key.ACTIVE_NODE_ID_LIST])
|
515
506
|
dead_nids = cast(List[int], configs[Key.DEAD_NODE_ID_LIST])
|
@@ -523,5 +514,5 @@ def _unmask(
|
|
523
514
|
shares += [state.rd_seed_share_dict[nid] for nid in active_nids]
|
524
515
|
shares += [state.sk1_share_dict[nid] for nid in dead_nids]
|
525
516
|
|
526
|
-
log(
|
517
|
+
log(DEBUG, "Node %d: stage 3 completes. uploading key shares...", state.nid)
|
527
518
|
return {Key.NODE_ID_LIST: all_nids, Key.SHARE_LIST: shares}
|
flwr/common/pyproject.py
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
# Copyright 2024 Flower Labs GmbH. All Rights Reserved.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
# ==============================================================================
|
15
|
+
"""Validates the project's name property."""
|
16
|
+
|
17
|
+
import re
|
18
|
+
|
19
|
+
|
20
|
+
def validate_project_name(name: str) -> bool:
|
21
|
+
"""Validate the project name against PEP 621 and PEP 503 specifications.
|
22
|
+
|
23
|
+
Conventions at a glance:
|
24
|
+
- Must be lowercase
|
25
|
+
- Must not contain special characters
|
26
|
+
- Must use hyphens(recommended) or underscores. No spaces.
|
27
|
+
- Recommended to be no more than 40 characters long (But it can be)
|
28
|
+
|
29
|
+
Parameters
|
30
|
+
----------
|
31
|
+
name : str
|
32
|
+
The project name to validate.
|
33
|
+
|
34
|
+
Returns
|
35
|
+
-------
|
36
|
+
bool
|
37
|
+
True if the name is valid, False otherwise.
|
38
|
+
"""
|
39
|
+
if not name or len(name) > 40 or not re.match(r"^[a-z0-9-_]+$", name):
|
40
|
+
return False
|
41
|
+
return True
|
@@ -127,7 +127,7 @@ def default_init_params_workflow(driver: Driver, context: Context) -> None:
|
|
127
127
|
content=content,
|
128
128
|
message_type=MessageTypeLegacy.GET_PARAMETERS,
|
129
129
|
dst_node_id=random_client.node_id,
|
130
|
-
group_id="",
|
130
|
+
group_id="0",
|
131
131
|
ttl="",
|
132
132
|
)
|
133
133
|
]
|
@@ -226,7 +226,7 @@ def default_fit_workflow( # pylint: disable=R0914
|
|
226
226
|
content=compat.fitins_to_recordset(fitins, True),
|
227
227
|
message_type=MessageType.TRAIN,
|
228
228
|
dst_node_id=proxy.node_id,
|
229
|
-
group_id=
|
229
|
+
group_id=str(current_round),
|
230
230
|
ttl="",
|
231
231
|
)
|
232
232
|
for proxy, fitins in client_instructions
|
@@ -306,7 +306,7 @@ def default_evaluate_workflow(driver: Driver, context: Context) -> None:
|
|
306
306
|
content=compat.evaluateins_to_recordset(evalins, True),
|
307
307
|
message_type=MessageType.EVALUATE,
|
308
308
|
dst_node_id=proxy.node_id,
|
309
|
-
group_id=
|
309
|
+
group_id=str(current_round),
|
310
310
|
ttl="",
|
311
311
|
)
|
312
312
|
for proxy, evalins in client_instructions
|
@@ -18,11 +18,10 @@
|
|
18
18
|
import random
|
19
19
|
from dataclasses import dataclass, field
|
20
20
|
from logging import DEBUG, ERROR, INFO, WARN
|
21
|
-
from typing import Dict, List, Optional, Set, Union, cast
|
21
|
+
from typing import Dict, List, Optional, Set, Tuple, Union, cast
|
22
22
|
|
23
23
|
import flwr.common.recordset_compat as compat
|
24
24
|
from flwr.common import (
|
25
|
-
Code,
|
26
25
|
ConfigsRecord,
|
27
26
|
Context,
|
28
27
|
FitRes,
|
@@ -30,7 +29,6 @@ from flwr.common import (
|
|
30
29
|
MessageType,
|
31
30
|
NDArrays,
|
32
31
|
RecordSet,
|
33
|
-
Status,
|
34
32
|
bytes_to_ndarray,
|
35
33
|
log,
|
36
34
|
ndarrays_to_parameters,
|
@@ -55,7 +53,7 @@ from flwr.common.secure_aggregation.secaggplus_constants import (
|
|
55
53
|
Stage,
|
56
54
|
)
|
57
55
|
from flwr.common.secure_aggregation.secaggplus_utils import pseudo_rand_gen
|
58
|
-
from flwr.server.
|
56
|
+
from flwr.server.client_proxy import ClientProxy
|
59
57
|
from flwr.server.compat.legacy_context import LegacyContext
|
60
58
|
from flwr.server.driver import Driver
|
61
59
|
|
@@ -67,6 +65,7 @@ from ..constant import Key as WorkflowKey
|
|
67
65
|
class WorkflowState: # pylint: disable=R0902
|
68
66
|
"""The state of the SecAgg+ protocol."""
|
69
67
|
|
68
|
+
nid_to_proxies: Dict[int, ClientProxy] = field(default_factory=dict)
|
70
69
|
nid_to_fitins: Dict[int, RecordSet] = field(default_factory=dict)
|
71
70
|
sampled_node_ids: Set[int] = field(default_factory=set)
|
72
71
|
active_node_ids: Set[int] = field(default_factory=set)
|
@@ -81,6 +80,7 @@ class WorkflowState: # pylint: disable=R0902
|
|
81
80
|
forward_srcs: Dict[int, List[int]] = field(default_factory=dict)
|
82
81
|
forward_ciphertexts: Dict[int, List[bytes]] = field(default_factory=dict)
|
83
82
|
aggregate_ndarrays: NDArrays = field(default_factory=list)
|
83
|
+
legacy_results: List[Tuple[ClientProxy, FitRes]] = field(default_factory=list)
|
84
84
|
|
85
85
|
|
86
86
|
class SecAggPlusWorkflow:
|
@@ -301,9 +301,10 @@ class SecAggPlusWorkflow:
|
|
301
301
|
)
|
302
302
|
|
303
303
|
state.nid_to_fitins = {
|
304
|
-
proxy.node_id: compat.fitins_to_recordset(fitins,
|
304
|
+
proxy.node_id: compat.fitins_to_recordset(fitins, True)
|
305
305
|
for proxy, fitins in proxy_fitins_lst
|
306
306
|
}
|
307
|
+
state.nid_to_proxies = {proxy.node_id: proxy for proxy, _ in proxy_fitins_lst}
|
307
308
|
|
308
309
|
# Protocol config
|
309
310
|
sampled_node_ids = list(state.nid_to_fitins.keys())
|
@@ -528,6 +529,12 @@ class SecAggPlusWorkflow:
|
|
528
529
|
masked_vector = parameters_mod(masked_vector, state.mod_range)
|
529
530
|
state.aggregate_ndarrays = masked_vector
|
530
531
|
|
532
|
+
# Backward compatibility with Strategy
|
533
|
+
for msg in msgs:
|
534
|
+
fitres = compat.recordset_to_fitres(msg.content, True)
|
535
|
+
proxy = state.nid_to_proxies[msg.metadata.src_node_id]
|
536
|
+
state.legacy_results.append((proxy, fitres))
|
537
|
+
|
531
538
|
return self._check_threshold(state)
|
532
539
|
|
533
540
|
def unmask_stage( # pylint: disable=R0912, R0914, R0915
|
@@ -637,31 +644,21 @@ class SecAggPlusWorkflow:
|
|
637
644
|
for vec in aggregated_vector:
|
638
645
|
vec += offset
|
639
646
|
vec *= inv_dq_total_ratio
|
640
|
-
|
647
|
+
|
648
|
+
# Backward compatibility with Strategy
|
649
|
+
results = state.legacy_results
|
650
|
+
parameters = ndarrays_to_parameters(aggregated_vector)
|
651
|
+
for _, fitres in results:
|
652
|
+
fitres.parameters = parameters
|
641
653
|
|
642
654
|
# No exception/failure handling currently
|
643
655
|
log(
|
644
656
|
INFO,
|
645
657
|
"aggregate_fit: received %s results and %s failures",
|
646
|
-
|
647
|
-
0,
|
648
|
-
)
|
649
|
-
|
650
|
-
final_fitres = FitRes(
|
651
|
-
status=Status(code=Code.OK, message=""),
|
652
|
-
parameters=ndarrays_to_parameters(aggregated_vector),
|
653
|
-
num_examples=round(state.max_weight / inv_dq_total_ratio),
|
654
|
-
metrics={},
|
655
|
-
)
|
656
|
-
empty_proxy = DriverClientProxy(
|
658
|
+
len(results),
|
657
659
|
0,
|
658
|
-
driver.grpc_driver, # type: ignore
|
659
|
-
False,
|
660
|
-
driver.run_id, # type: ignore
|
661
|
-
)
|
662
|
-
aggregated_result = context.strategy.aggregate_fit(
|
663
|
-
current_round, [(empty_proxy, final_fitres)], []
|
664
660
|
)
|
661
|
+
aggregated_result = context.strategy.aggregate_fit(current_round, results, [])
|
665
662
|
parameters_aggregated, metrics_aggregated = aggregated_result
|
666
663
|
|
667
664
|
# Update the parameters and write history
|
{flwr_nightly-1.8.0.dev20240311.dist-info → flwr_nightly-1.8.0.dev20240312.dist-info}/RECORD
RENAMED
@@ -42,7 +42,7 @@ flwr/client/mod/centraldp_mods.py,sha256=8Jiy42idsYs_gF6g5kZpjeyG98vyuSoYq9E-Oib
|
|
42
42
|
flwr/client/mod/localdp_mod.py,sha256=fFLtqHAzWuMG5tL2O_Q4nrkqwGR6AzHkA82Avkajrdc,4492
|
43
43
|
flwr/client/mod/secure_aggregation/__init__.py,sha256=Qo2R-NqsyoP0oX73TyDfQRu9P6DCNXhgqGbhmGIBaJA,849
|
44
44
|
flwr/client/mod/secure_aggregation/secagg_mod.py,sha256=wI9tuIEvMUETz-wVIEbPYvh-1nK9CEylBLGoVpNhL94,1095
|
45
|
-
flwr/client/mod/secure_aggregation/secaggplus_mod.py,sha256=
|
45
|
+
flwr/client/mod/secure_aggregation/secaggplus_mod.py,sha256=RGQAHJbCduUUkusfcjh-GI-gyDOLW5vEXVXLvwNW2Ik,19707
|
46
46
|
flwr/client/mod/utils.py,sha256=lvETHcCYsSWz7h8I772hCV_kZspxqlMqzriMZ-SxmKc,1226
|
47
47
|
flwr/client/node_state.py,sha256=KTTs_l4I0jBM7IsSsbAGjhfL_yZC3QANbzyvyfZBRDM,1778
|
48
48
|
flwr/client/node_state_tests.py,sha256=gPwz0zf2iuDSa11jedkur_u3Xm7lokIDG5ALD2MCvSw,2195
|
@@ -64,6 +64,7 @@ flwr/common/logger.py,sha256=Plhm9fsi4ewb90eGALQZ9xBkR0cGEsckX5RLSMEaS3M,6118
|
|
64
64
|
flwr/common/message.py,sha256=Z-k3a1HgoyWBm3NS0_bphfYbJtJ8YqxfXR68AvXXkuA,9808
|
65
65
|
flwr/common/object_ref.py,sha256=ELoUCAFO-vbjJC41CGpa-WBG2SLYe3ErW-d9YCG3zqA,4961
|
66
66
|
flwr/common/parameter.py,sha256=-bFAUayToYDF50FZGrBC1hQYJCQDtB2bbr3ZuVLMtdE,2095
|
67
|
+
flwr/common/pyproject.py,sha256=EI_ovbCHGmhYrdPx0RSDi5EkFZFof-8m1PA54c0ZTjc,1385
|
67
68
|
flwr/common/record/__init__.py,sha256=33OaDW2bvaW952DFHH1amHclv4AuDZu385jXjHhXoog,1054
|
68
69
|
flwr/common/record/configsrecord.py,sha256=qL-hQ6ZFOOWJYCUHeFiao2vcO5rnk585Ns5Yxfb1sp4,3378
|
69
70
|
flwr/common/record/conversion_utils.py,sha256=n3I3SI2P6hUjyxbWNc0QAch-SEhfMK6Hm-UUaplAlUc,1393
|
@@ -189,10 +190,10 @@ flwr/server/utils/tensorboard.py,sha256=k0G6bqsLx7wfYbH2KtXsDYcOCfyIeE12-hefXA7l
|
|
189
190
|
flwr/server/utils/validator.py,sha256=IJN2475yyD_i_9kg_SJ_JodIuZh58ufpWGUDQRAqu2s,4740
|
190
191
|
flwr/server/workflow/__init__.py,sha256=SXY0XkwbkezFBxxrFB5hKUtmtAgnYISBkPouR1V71ss,902
|
191
192
|
flwr/server/workflow/constant.py,sha256=q4DLdR8Krlxuewq2AQjwTL75hphxE5ODNz4AhViHMXk,1082
|
192
|
-
flwr/server/workflow/default_workflows.py,sha256
|
193
|
+
flwr/server/workflow/default_workflows.py,sha256=-_AiUWFrbFGHtGsQXVIrzxDnaFnFcbrqYWdTMs-zels,12634
|
193
194
|
flwr/server/workflow/secure_aggregation/__init__.py,sha256=3XlgDOjD_hcukTGl6Bc1B-8M_dPlVSJuTbvXIbiO-Ic,880
|
194
195
|
flwr/server/workflow/secure_aggregation/secagg_workflow.py,sha256=wpAkYPId0nfK6SgpUAtsCni4_MQLd-uqJ81tUKu3xlI,5838
|
195
|
-
flwr/server/workflow/secure_aggregation/secaggplus_workflow.py,sha256=
|
196
|
+
flwr/server/workflow/secure_aggregation/secaggplus_workflow.py,sha256=1ObaDAf6sliwGc3HZL1zUnnjJHxdd-mSWR-ED4qSguM,29134
|
196
197
|
flwr/simulation/__init__.py,sha256=hpoKzdovrH0_Cf8HIcXxQxyUUb3BiSk-WUNLf5STHcc,1400
|
197
198
|
flwr/simulation/app.py,sha256=WqJxdXTEuehwMW605p5NMmvBbKYx5tuqnV3Mp7jSWXM,13904
|
198
199
|
flwr/simulation/ray_transport/__init__.py,sha256=FsaAnzC4cw4DqoouBCix6496k29jACkfeIam55BvW9g,734
|
@@ -200,8 +201,8 @@ flwr/simulation/ray_transport/ray_actor.py,sha256=zRETW_xuCAOLRFaYnQ-q3IBSz0LIv_
|
|
200
201
|
flwr/simulation/ray_transport/ray_client_proxy.py,sha256=L49gtigsf4vTQgRiqzOgcPEuS_l-EuTj29Ohw6ekbSI,6721
|
201
202
|
flwr/simulation/ray_transport/utils.py,sha256=TYdtfg1P9VfTdLMOJlifInGpxWHYs9UfUqIv2wfkRLA,2392
|
202
203
|
flwr/simulation/run_simulation.py,sha256=1JMP5nYFeGrZzcpw_Q0aDvyla2AvRz5aFJw1i1InSvs,15681
|
203
|
-
flwr_nightly-1.8.0.
|
204
|
-
flwr_nightly-1.8.0.
|
205
|
-
flwr_nightly-1.8.0.
|
206
|
-
flwr_nightly-1.8.0.
|
207
|
-
flwr_nightly-1.8.0.
|
204
|
+
flwr_nightly-1.8.0.dev20240312.dist-info/LICENSE,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
|
205
|
+
flwr_nightly-1.8.0.dev20240312.dist-info/METADATA,sha256=Iyf-vlQlVXKCq7K5cxyRSHx9QVkZbsrSFGQKM8pTK6s,15257
|
206
|
+
flwr_nightly-1.8.0.dev20240312.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
|
207
|
+
flwr_nightly-1.8.0.dev20240312.dist-info/entry_points.txt,sha256=utu2wybGyYJSTtsB2ktY_gmy-XtMFo9EFZdishX0zR4,320
|
208
|
+
flwr_nightly-1.8.0.dev20240312.dist-info/RECORD,,
|
{flwr_nightly-1.8.0.dev20240311.dist-info → flwr_nightly-1.8.0.dev20240312.dist-info}/LICENSE
RENAMED
File without changes
|
File without changes
|
File without changes
|