flwr-nightly 1.22.0.dev20250916__py3-none-any.whl → 1.22.0.dev20250918__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/cli/app.py +2 -0
- flwr/cli/new/new.py +4 -2
- flwr/cli/new/templates/app/README.flowertune.md.tpl +1 -1
- flwr/cli/new/templates/app/code/client.baseline.py.tpl +64 -47
- flwr/cli/new/templates/app/code/client.xgboost.py.tpl +110 -0
- flwr/cli/new/templates/app/code/flwr_tune/client_app.py.tpl +56 -90
- flwr/cli/new/templates/app/code/flwr_tune/models.py.tpl +1 -23
- flwr/cli/new/templates/app/code/flwr_tune/server_app.py.tpl +37 -58
- flwr/cli/new/templates/app/code/flwr_tune/strategy.py.tpl +39 -44
- flwr/cli/new/templates/app/code/model.baseline.py.tpl +0 -14
- flwr/cli/new/templates/app/code/server.baseline.py.tpl +27 -29
- flwr/cli/new/templates/app/code/server.xgboost.py.tpl +56 -0
- flwr/cli/new/templates/app/code/task.xgboost.py.tpl +67 -0
- flwr/cli/new/templates/app/pyproject.baseline.toml.tpl +3 -3
- flwr/cli/new/templates/app/pyproject.flowertune.toml.tpl +1 -1
- flwr/cli/new/templates/app/pyproject.xgboost.toml.tpl +61 -0
- flwr/cli/pull.py +100 -0
- flwr/cli/utils.py +17 -0
- flwr/common/constant.py +2 -0
- flwr/common/exit/exit_code.py +4 -0
- flwr/proto/control_pb2.py +7 -3
- flwr/proto/control_pb2.pyi +24 -0
- flwr/proto/control_pb2_grpc.py +34 -0
- flwr/proto/control_pb2_grpc.pyi +13 -0
- flwr/server/app.py +13 -0
- flwr/serverapp/strategy/__init__.py +4 -0
- flwr/serverapp/strategy/fedprox.py +174 -0
- flwr/serverapp/strategy/fedxgb_cyclic.py +220 -0
- flwr/simulation/app.py +1 -1
- flwr/simulation/run_simulation.py +25 -30
- flwr/supercore/cli/flower_superexec.py +26 -1
- flwr/supercore/constant.py +19 -0
- flwr/supercore/superexec/plugin/exec_plugin.py +11 -1
- flwr/supercore/superexec/run_superexec.py +16 -2
- flwr/superlink/artifact_provider/__init__.py +22 -0
- flwr/superlink/artifact_provider/artifact_provider.py +37 -0
- flwr/superlink/servicer/control/control_grpc.py +3 -0
- flwr/superlink/servicer/control/control_servicer.py +59 -2
- {flwr_nightly-1.22.0.dev20250916.dist-info → flwr_nightly-1.22.0.dev20250918.dist-info}/METADATA +1 -1
- {flwr_nightly-1.22.0.dev20250916.dist-info → flwr_nightly-1.22.0.dev20250918.dist-info}/RECORD +42 -33
- flwr/serverapp/strategy/strategy_utils_tests.py +0 -323
- {flwr_nightly-1.22.0.dev20250916.dist-info → flwr_nightly-1.22.0.dev20250918.dist-info}/WHEEL +0 -0
- {flwr_nightly-1.22.0.dev20250916.dist-info → flwr_nightly-1.22.0.dev20250918.dist-info}/entry_points.txt +0 -0
{flwr_nightly-1.22.0.dev20250916.dist-info → flwr_nightly-1.22.0.dev20250918.dist-info}/RECORD
RENAMED
@@ -4,7 +4,7 @@ flwr/app/error.py,sha256=0PwA-E_CAs5P_nWAA0kksVO1A44t4CNLEf7u-Su-uJ0,2342
|
|
4
4
|
flwr/app/exception.py,sha256=WX45Yviu_CmYrYd8JHNjRkSsb-g4Br7XvVLKuVxwSdI,1298
|
5
5
|
flwr/app/metadata.py,sha256=rdMBn0zhIOYmCvmGENQWSQqDwcxwsMJzCle4PQdlc_Y,7331
|
6
6
|
flwr/cli/__init__.py,sha256=EfMGmHoobET6P2blBt_eOByXL8299MgFfB7XNdaPQ6I,720
|
7
|
-
flwr/cli/app.py,sha256=
|
7
|
+
flwr/cli/app.py,sha256=qYMZtPXzDXZpigmerRz4WF3lA3D0Y1lVufzgWB8Nd9A,1899
|
8
8
|
flwr/cli/auth_plugin/__init__.py,sha256=FyaoqPzcxlBTFfJ2sBRC5USwQLmAhFr5KuBwfMO4bmo,1052
|
9
9
|
flwr/cli/auth_plugin/oidc_cli_plugin.py,sha256=kQteGRB9-DmC7K5F9TBmUc8ndSBR7WyT27ygWUUuX_g,5402
|
10
10
|
flwr/cli/build.py,sha256=hE54Q_eMdWLpVKSVC2aQaUxVaiUlWnAosGNvIPSEg6Y,7284
|
@@ -18,19 +18,19 @@ flwr/cli/login/__init__.py,sha256=B1SXKU3HCQhWfFDMJhlC7FOl8UsvH4mxysxeBnrfyUE,80
|
|
18
18
|
flwr/cli/login/login.py,sha256=RM1Jiv_VFm3oz4rTHSr3D87X90lW3WzErjBBU7WviWY,4309
|
19
19
|
flwr/cli/ls.py,sha256=3YK7cpoImJ7PbjlP_JgYRQWz1GymX2q7Reu-mKJEpao,10957
|
20
20
|
flwr/cli/new/__init__.py,sha256=QA1E2QtzPvFCjLTUHnFnJbufuFiGyT_0Y53Wpbvg1F0,790
|
21
|
-
flwr/cli/new/new.py,sha256=
|
21
|
+
flwr/cli/new/new.py,sha256=nIuUrQSGDjI4kqnymlq-rOT0RU3AHwZrat3abqHhCwM,10598
|
22
22
|
flwr/cli/new/templates/__init__.py,sha256=FpjWCfIySU2DB4kh0HOXLAjlZNNFDTVU4w3HoE2TzcI,725
|
23
23
|
flwr/cli/new/templates/app/.gitignore.tpl,sha256=HZJcGQoxp7aUzaPg8Uqch3kNrIESwr9yjimDxJYgXVY,3104
|
24
24
|
flwr/cli/new/templates/app/LICENSE.tpl,sha256=WNHhf_5RCaeuKWyq_K39vmp9F28LxKsB4SpomwSZ2L0,11357
|
25
25
|
flwr/cli/new/templates/app/README.baseline.md.tpl,sha256=oClo5eR0iLuPzBT7uS3ikhNRAnySz_lhkHFElixKyJM,9640
|
26
|
-
flwr/cli/new/templates/app/README.flowertune.md.tpl,sha256=
|
26
|
+
flwr/cli/new/templates/app/README.flowertune.md.tpl,sha256=2-W0HAseLWOe1JJU0TsNocp63D14N7jLwWhtYjxlfxs,3494
|
27
27
|
flwr/cli/new/templates/app/README.md.tpl,sha256=uI8vUMCEGA1-WJ8-9EUFCnNtofWFkJNOxaR1V6r_Su4,1908
|
28
28
|
flwr/cli/new/templates/app/__init__.py,sha256=LbR0ksGiF566JcHM_H5m1Tc4-oYUEilWFlcXR-Oe6bI,729
|
29
29
|
flwr/cli/new/templates/app/code/__init__.baseline.py.tpl,sha256=YkHAgppUeD2BnBoGfVB6dEvBfjuIPGsU1gw4CiUi3qA,40
|
30
30
|
flwr/cli/new/templates/app/code/__init__.py,sha256=zXa2YU1swzHxOKDQbwlDMEwVPOUswVeosjkiXNMTgFo,736
|
31
31
|
flwr/cli/new/templates/app/code/__init__.py.tpl,sha256=J0Gn74E7khpLyKJVNqOPu7ev93vkcu1PZugsbxtABMw,52
|
32
32
|
flwr/cli/new/templates/app/code/__init__.pytorch_legacy_api.py.tpl,sha256=mKIS8MK_X8T9NlmcX1-_c9Bbexc-ueqDIBI7uN6c4dE,45
|
33
|
-
flwr/cli/new/templates/app/code/client.baseline.py.tpl,sha256=
|
33
|
+
flwr/cli/new/templates/app/code/client.baseline.py.tpl,sha256=w8xYWhVAb5AFDLj206Nxz5U-xbzDBv0px2FFvE5wRTM,2438
|
34
34
|
flwr/cli/new/templates/app/code/client.huggingface.py.tpl,sha256=SIZZ3s-6u8IU8cFfsqu6ZU8zjhfI1m1SWauOSUcW8TA,3015
|
35
35
|
flwr/cli/new/templates/app/code/client.jax.py.tpl,sha256=uFCIPwAHYiRAgh2W3nRni_Oig02ZzRF-ofUG5O19zcE,2125
|
36
36
|
flwr/cli/new/templates/app/code/client.mlx.py.tpl,sha256=CHU2IBIzI2YENZZuvTsAlSdL94DK19wMYMIhr-JgwZ8,3422
|
@@ -39,15 +39,16 @@ flwr/cli/new/templates/app/code/client.pytorch.py.tpl,sha256=fYoh-dTu07LkqNYvwcx
|
|
39
39
|
flwr/cli/new/templates/app/code/client.pytorch_legacy_api.py.tpl,sha256=fuxVmZpjHIueNy_aHWF81531vmi8DGu4CYjYDqmUwWo,1705
|
40
40
|
flwr/cli/new/templates/app/code/client.sklearn.py.tpl,sha256=0qqEe-RRjkHGOH8gsD9e83ae-kyyYixhyBgzVHjYpzk,3500
|
41
41
|
flwr/cli/new/templates/app/code/client.tensorflow.py.tpl,sha256=8o55KXpsbF_rv6o98ZNYJDCazjwMp_RPTaSzDfT7Qlw,2682
|
42
|
+
flwr/cli/new/templates/app/code/client.xgboost.py.tpl,sha256=-ipRV8gqpbEg7Mht77Yyqs1viL-3JYSVZR47I7xeG4c,3493
|
42
43
|
flwr/cli/new/templates/app/code/dataset.baseline.py.tpl,sha256=jbd_exHAk2-Blu_kVutjPO6a_dkJQWb232zxSeXIZ1k,1453
|
43
44
|
flwr/cli/new/templates/app/code/flwr_tune/__init__.py,sha256=Xq5fEn5yZkw6HAJi10T_3HRBoqN5_5pNqJHY4wXvD5k,748
|
44
|
-
flwr/cli/new/templates/app/code/flwr_tune/client_app.py.tpl,sha256=
|
45
|
+
flwr/cli/new/templates/app/code/flwr_tune/client_app.py.tpl,sha256=p6BzTbP-mXkFANiVC7iz3YlskOidWaLC341IJyrUotQ,2951
|
45
46
|
flwr/cli/new/templates/app/code/flwr_tune/dataset.py.tpl,sha256=1NA2Sf-EviNtOaYN4dnFk6v2tcZVsY3-eXY84wOXVng,3059
|
46
|
-
flwr/cli/new/templates/app/code/flwr_tune/models.py.tpl,sha256=
|
47
|
-
flwr/cli/new/templates/app/code/flwr_tune/server_app.py.tpl,sha256=
|
48
|
-
flwr/cli/new/templates/app/code/flwr_tune/strategy.py.tpl,sha256=
|
49
|
-
flwr/cli/new/templates/app/code/model.baseline.py.tpl,sha256=
|
50
|
-
flwr/cli/new/templates/app/code/server.baseline.py.tpl,sha256=
|
47
|
+
flwr/cli/new/templates/app/code/flwr_tune/models.py.tpl,sha256=UCLEKUpXarkz9tMFtDrxmLv6QuKe5zCimTuoopQedUM,1717
|
48
|
+
flwr/cli/new/templates/app/code/flwr_tune/server_app.py.tpl,sha256=qe9Om3P2ERvvSj2NN5RSEKgNgztWatCpWtC8SkS_T_M,2420
|
49
|
+
flwr/cli/new/templates/app/code/flwr_tune/strategy.py.tpl,sha256=M6CzBY-gtIqLOu2xTtABXOVgBnqKOu7d6Vn2sazmYuI,2444
|
50
|
+
flwr/cli/new/templates/app/code/model.baseline.py.tpl,sha256=P6jTuN9reJfdthiN3mOUHiA4xrtDh5TTUcAV6210-hU,2104
|
51
|
+
flwr/cli/new/templates/app/code/server.baseline.py.tpl,sha256=hliBSfHSzg4bi6PxMlj4oGFfvzvi-4DzoaI67VZbJeQ,1111
|
51
52
|
flwr/cli/new/templates/app/code/server.huggingface.py.tpl,sha256=_2Mv-SqGSMf7sMdbMEmvROzedvNaVHvhIIO3eYAhVYU,1252
|
52
53
|
flwr/cli/new/templates/app/code/server.jax.py.tpl,sha256=RW-rh7ogcJ3_BD66bJxTw-ZoP7c-4SK8hVHc-e0SSVY,1029
|
53
54
|
flwr/cli/new/templates/app/code/server.mlx.py.tpl,sha256=J8rIe6RL2ndODVJD79xShRKBH70HljFSCi4s_RJ-xLQ,1200
|
@@ -56,6 +57,7 @@ flwr/cli/new/templates/app/code/server.pytorch.py.tpl,sha256=epARqfcQ-EQsdZwaaaU
|
|
56
57
|
flwr/cli/new/templates/app/code/server.pytorch_legacy_api.py.tpl,sha256=gvBsGA_Jg9kAH8xTxjzTjMcvBtciuccOwQFbO7ey8tU,916
|
57
58
|
flwr/cli/new/templates/app/code/server.sklearn.py.tpl,sha256=ehQ5VRgBn92WeFl6kupwJnuxSNkKvE-EvKde6A9mNQo,1377
|
58
59
|
flwr/cli/new/templates/app/code/server.tensorflow.py.tpl,sha256=2-WTOPd-ewdLd9QmSlflIH7ix7zxAzPEOZoyiPBOy8c,1010
|
60
|
+
flwr/cli/new/templates/app/code/server.xgboost.py.tpl,sha256=fwtCRyCG2hDSH1zVMyZv7zA7wsdKNPfpugDSZjxCs5Q,1746
|
59
61
|
flwr/cli/new/templates/app/code/strategy.baseline.py.tpl,sha256=YkHAgppUeD2BnBoGfVB6dEvBfjuIPGsU1gw4CiUi3qA,40
|
60
62
|
flwr/cli/new/templates/app/code/task.huggingface.py.tpl,sha256=piBbY3Dg60bQnCg15uzMw0QiL5SDOYX4YhQouy-X2zI,3164
|
61
63
|
flwr/cli/new/templates/app/code/task.jax.py.tpl,sha256=Fb0XgdTAQplM-ZCusI081XA9asO3gHptH772S-Xcyy8,1525
|
@@ -65,9 +67,10 @@ flwr/cli/new/templates/app/code/task.pytorch.py.tpl,sha256=RKA5lV6O6OnVKZ2r75pbz
|
|
65
67
|
flwr/cli/new/templates/app/code/task.pytorch_legacy_api.py.tpl,sha256=XlJqA4Ix_PloO_zJLhjiN5vDj16w3I4CPVGdmbe8asE,3800
|
66
68
|
flwr/cli/new/templates/app/code/task.sklearn.py.tpl,sha256=vHdhtMp0FHxbYafXyhDT9aKmmmA0Jvpx5Oum1Yu9lWY,1850
|
67
69
|
flwr/cli/new/templates/app/code/task.tensorflow.py.tpl,sha256=impgWN7MfztmcWF4xh1llcZGsgTvrb1HD5ZE0t-8U08,1731
|
70
|
+
flwr/cli/new/templates/app/code/task.xgboost.py.tpl,sha256=0xO8jQvrHuB1llVDopQPOmt5Hn6rBw8umzoNwiZZs-o,2135
|
68
71
|
flwr/cli/new/templates/app/code/utils.baseline.py.tpl,sha256=YkHAgppUeD2BnBoGfVB6dEvBfjuIPGsU1gw4CiUi3qA,40
|
69
|
-
flwr/cli/new/templates/app/pyproject.baseline.toml.tpl,sha256=
|
70
|
-
flwr/cli/new/templates/app/pyproject.flowertune.toml.tpl,sha256=
|
72
|
+
flwr/cli/new/templates/app/pyproject.baseline.toml.tpl,sha256=mPIMPfneVYV03l8jWRgWZ0V5Kh_pJw-AMUvkhcKkmL8,3182
|
73
|
+
flwr/cli/new/templates/app/pyproject.flowertune.toml.tpl,sha256=wqYW4bWcf12m0U2njR995lySSesFvnHB-eSkPWz-QdM,2501
|
71
74
|
flwr/cli/new/templates/app/pyproject.huggingface.toml.tpl,sha256=xHGF38i7oFpvnFvqfqLdtc08CkHRYsenbLz3q1dhCXk,2020
|
72
75
|
flwr/cli/new/templates/app/pyproject.jax.toml.tpl,sha256=fdDhwmPoMirJ095cU_vFCBf0ILQlAoa1fdnHb2LM1yk,1471
|
73
76
|
flwr/cli/new/templates/app/pyproject.mlx.toml.tpl,sha256=PAjPT2v06sBZxacNiyMJloDwocCK5tFcGQmMXOoBqc8,1542
|
@@ -76,10 +79,12 @@ flwr/cli/new/templates/app/pyproject.pytorch.toml.tpl,sha256=SE4H23OFkQbqNU64nYf
|
|
76
79
|
flwr/cli/new/templates/app/pyproject.pytorch_legacy_api.toml.tpl,sha256=docQbs3MuRR-yT24lVz7N2sQL3Sj49EHuOCuRj_0djQ,1508
|
77
80
|
flwr/cli/new/templates/app/pyproject.sklearn.toml.tpl,sha256=apauU_PUmLEbt2rjckKniEbzdRs1EnMri_qgtHtBJZ8,1484
|
78
81
|
flwr/cli/new/templates/app/pyproject.tensorflow.toml.tpl,sha256=LQpDKJTEnRKj5Ygn5FkT44SxlnLVprkPlbrGaFf5Q50,1508
|
82
|
+
flwr/cli/new/templates/app/pyproject.xgboost.toml.tpl,sha256=504pHibNRGFe-DLnzqHLYhKeF_n8BPMv0Xog5EfnZ0M,1661
|
83
|
+
flwr/cli/pull.py,sha256=dHiMe6x8w8yRoFNKpjA-eiPD6eFiHz4Vah5HZrqNpuo,3364
|
79
84
|
flwr/cli/run/__init__.py,sha256=RPyB7KbYTFl6YRiilCch6oezxrLQrl1kijV7BMGkLbA,790
|
80
85
|
flwr/cli/run/run.py,sha256=ECa0kup9dn15O70H74QdgUsEaeErbzDqVX_U0zZO5IM,8173
|
81
86
|
flwr/cli/stop.py,sha256=TR9F61suTxNUzGIktUdoBhXwdRtCdvzGhy3qCuvcfBg,5000
|
82
|
-
flwr/cli/utils.py,sha256=
|
87
|
+
flwr/cli/utils.py,sha256=sMctnDYHv-zu9FG67aV0vy_zs3gkkXclQicBD_67WWg,13805
|
83
88
|
flwr/client/__init__.py,sha256=boIhKaK6I977zrILmoTutNx94x5jB0e6F1gnAjaRJnI,1250
|
84
89
|
flwr/client/client.py,sha256=3HAchxvknKG9jYbB7swNyDj-e5vUWDuMKoLvbT7jCVM,7895
|
85
90
|
flwr/client/client_app.py,sha256=zVhi-l3chAb06ozFsKwix3hU_RpOLjST13Ha50AVIPE,16918
|
@@ -116,7 +121,7 @@ flwr/common/args.py,sha256=Nq2u4yePbkSY0CWFamn0hZY6Rms8G1xYDeDGIcLIITE,5849
|
|
116
121
|
flwr/common/auth_plugin/__init__.py,sha256=DktrRcGZrRarLf7Jb_UlHtOyLp9_-kEplyq6PS5-vOA,988
|
117
122
|
flwr/common/auth_plugin/auth_plugin.py,sha256=mM7SuphO4OsVAVJR1GErYVgYT83ZjxDzS_gha12bT9E,4855
|
118
123
|
flwr/common/config.py,sha256=glcZDjco-amw1YfQcYTFJ4S1pt9APoexT-mf1QscuHs,13960
|
119
|
-
flwr/common/constant.py,sha256=
|
124
|
+
flwr/common/constant.py,sha256=zopMTlEgz8TxMSh59ueef6VutHSdfb3XRStl1W5yBZ4,9013
|
120
125
|
flwr/common/context.py,sha256=Be8obQR_OvEDy1OmshuUKxGRQ7Qx89mf5F4xlhkR10s,2407
|
121
126
|
flwr/common/date.py,sha256=1ZT2cRSpC2DJqprOVTLXYCR_O2_OZR0zXO_brJ3LqWc,1554
|
122
127
|
flwr/common/differential_privacy.py,sha256=FdlpdpPl_H_2HJa8CQM1iCUGBBQ5Dc8CzxmHERM-EoE,6148
|
@@ -126,7 +131,7 @@ flwr/common/event_log_plugin/__init__.py,sha256=ts3VAL3Fk6Grp1EK_1Qg_V-BfOof9F86
|
|
126
131
|
flwr/common/event_log_plugin/event_log_plugin.py,sha256=4SkVa1Ic-sPlICJShBuggXmXDcQtWQ1KDby4kthFNF0,2064
|
127
132
|
flwr/common/exit/__init__.py,sha256=8W7xaO1iw0vacgmQW7FTFbSh7csNv6XfsgIlnIbNF6U,978
|
128
133
|
flwr/common/exit/exit.py,sha256=DcXJfbpW1g-pQJqSZmps-1MZydd7T7RaarghIf2e4tU,3636
|
129
|
-
flwr/common/exit/exit_code.py,sha256=
|
134
|
+
flwr/common/exit/exit_code.py,sha256=Xa1NFGny2cefZ62kZZOfT8eii__PolMWCHxYmxoSQ2s,5416
|
130
135
|
flwr/common/exit/exit_handler.py,sha256=uzDdWwhKgc1w5csZS52b86kjmEApmDZKwMn_X0zDZZo,2126
|
131
136
|
flwr/common/exit/signal_handler.py,sha256=wqxykrwgmpFzmEMhpnlM7RtO0PnqIvYiSB1qYahZ5Sk,3710
|
132
137
|
flwr/common/grpc.py,sha256=nHnFC7E84pZVTvd6BhcSYWnGd0jf8t5UmGea04qvilM,9806
|
@@ -181,10 +186,10 @@ flwr/proto/clientappio_pb2.py,sha256=vJjzwWydhg7LruK8cvRAeVQeHPsJztgdIW9nyiPBZF0
|
|
181
186
|
flwr/proto/clientappio_pb2.pyi,sha256=XbFvpZvvrS7QcH5AFXfpRGl4hQvhd3QdKO6x0oTlCCU,165
|
182
187
|
flwr/proto/clientappio_pb2_grpc.py,sha256=iobNROP0qvn5zddx7k-uIi_dJWP3T_BRp_kbKq086i8,17550
|
183
188
|
flwr/proto/clientappio_pb2_grpc.pyi,sha256=Ytf1O1ktKB0Vsuc3AWLIErGjIJYokzKYzi2uA7mdMeg,4785
|
184
|
-
flwr/proto/control_pb2.py,sha256=
|
185
|
-
flwr/proto/control_pb2.pyi,sha256=
|
186
|
-
flwr/proto/control_pb2_grpc.py,sha256=
|
187
|
-
flwr/proto/control_pb2_grpc.pyi,sha256=
|
189
|
+
flwr/proto/control_pb2.py,sha256=Sz7PTdb7YGBs2N-FX6GiOVueY9PN0cF85XbwBkK9_BE,6183
|
190
|
+
flwr/proto/control_pb2.pyi,sha256=2OLPt6ztVcLzzISqfRqW4yrA-nawIPLwVDoTjBnSS5U,10592
|
191
|
+
flwr/proto/control_pb2_grpc.py,sha256=R4ykPqGblqEpOdVskoSfMeS-pZdyMT3CMBQUtTzHbgQ,12282
|
192
|
+
flwr/proto/control_pb2_grpc.pyi,sha256=7U9aOP4dYamnc4ZtTrEQEYYz0kFNI_fT88LRxwClA0U,3504
|
188
193
|
flwr/proto/error_pb2.py,sha256=PQVWrfjVPo88ql_KgV9nCxyQNCcV9PVfmcw7sOzTMro,1084
|
189
194
|
flwr/proto/error_pb2.pyi,sha256=ZNH4HhJTU_KfMXlyCeg8FwU-fcUYxTqEmoJPtWtHikc,734
|
190
195
|
flwr/proto/error_pb2_grpc.py,sha256=1oboBPFxaTEXt9Aw7EAj8gXHDCNMhZD2VXqocC9l_gk,159
|
@@ -239,7 +244,7 @@ flwr/proto/transport_pb2_grpc.py,sha256=vLN3EHtx2aEEMCO4f1Upu-l27BPzd3-5pV-u8wPc
|
|
239
244
|
flwr/proto/transport_pb2_grpc.pyi,sha256=AGXf8RiIiW2J5IKMlm_3qT3AzcDa4F3P5IqUjve_esA,766
|
240
245
|
flwr/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
241
246
|
flwr/server/__init__.py,sha256=LQQHiuL2jy7TpNaKastRdGsexlxSt5ZWAQNVqitDnrY,1598
|
242
|
-
flwr/server/app.py,sha256=
|
247
|
+
flwr/server/app.py,sha256=SUWdNUcl-Sy8h2MiC8Etr50GDJuGq58Ekqtr5XQ-Xrg,29951
|
243
248
|
flwr/server/client_manager.py,sha256=5jCGavVli7XdupvWWo7ru3PdFTlRU8IGvHFSSoUVLRs,6227
|
244
249
|
flwr/server/client_proxy.py,sha256=sv0E9AldBYOvc3pusqFh-GnyreeMfsXQ1cuTtxTq_wY,2399
|
245
250
|
flwr/server/compat/__init__.py,sha256=0IsttWvY15qO98_1GyzVC-vR1e_ZPXOdu2qUlOkYMPE,886
|
@@ -332,7 +337,7 @@ flwr/server/workflow/secure_aggregation/secaggplus_workflow.py,sha256=DkayCsnlAy
|
|
332
337
|
flwr/serverapp/__init__.py,sha256=ZujKNXULwhWYQhFnxOOT5Wi9MRq2JCWFhAAj7ouiQ78,884
|
333
338
|
flwr/serverapp/dp_fixed_clipping.py,sha256=wbP4W7CaUHXdll8ZSVUnTBSEWrnWM00CGk63rOR-Q2s,12133
|
334
339
|
flwr/serverapp/exception.py,sha256=5cuH-2AafvihzosWDdDjuMmHdDqZ1XxHvCqZXNBVklw,1334
|
335
|
-
flwr/serverapp/strategy/__init__.py,sha256=
|
340
|
+
flwr/serverapp/strategy/__init__.py,sha256=mt2l31EAQ9oSvBcQhk4Jj4SvTePmWzBHQxZqL1v0uhE,1552
|
336
341
|
flwr/serverapp/strategy/dp_fixed_clipping.py,sha256=wbP4W7CaUHXdll8ZSVUnTBSEWrnWM00CGk63rOR-Q2s,12133
|
337
342
|
flwr/serverapp/strategy/fedadagrad.py,sha256=fD65P6OEERa_pxq847e1UZpA083AcWR44XavYB0naGM,6343
|
338
343
|
flwr/serverapp/strategy/fedadam.py,sha256=s3xPIqhopy6yPTeFxevSPnc7a6BcKnKsvo2AaO6Z_xs,7138
|
@@ -340,26 +345,28 @@ flwr/serverapp/strategy/fedavg.py,sha256=Bq_nlmngzJbjqX1fF1mevXGVN6-pwglHv-6yNrs
|
|
340
345
|
flwr/serverapp/strategy/fedavgm.py,sha256=VlByltWzUYCoiVIWPFRqsqLKNWjlOlO2INK8SUxEjzk,8327
|
341
346
|
flwr/serverapp/strategy/fedmedian.py,sha256=b31Dk0LQBbQxi_f-jeSbWHI7iOBugcuBSN2Az-_a75E,2596
|
342
347
|
flwr/serverapp/strategy/fedopt.py,sha256=kqT0uV2IUE93O72XEVa1JJo61dcwbZEoT9KmYTjR2tE,8477
|
348
|
+
flwr/serverapp/strategy/fedprox.py,sha256=XkkLTk3XpXAj0QoAzHqAvcAlPjrNlX11ISAu5u2x6X8,7026
|
343
349
|
flwr/serverapp/strategy/fedtrimmedavg.py,sha256=4-QxgAQGo_7vB_L7qDYy28d95OBt9MeDa92yaTRMHqk,7166
|
344
350
|
flwr/serverapp/strategy/fedxgb_bagging.py,sha256=ktDjzov4y0BRecioq788umCEtcuwElou9olBizQKOnM,3282
|
351
|
+
flwr/serverapp/strategy/fedxgb_cyclic.py,sha256=8H8WoLdG4Fy1_dtLLE4AYiidC-Cvaw2GxySfzAb7Xj0,8774
|
345
352
|
flwr/serverapp/strategy/fedyogi.py,sha256=1Ripr4Hi2cdeTOLiFOXtMKvOxR3BsUQwc7bbTrXN4LM,6653
|
346
353
|
flwr/serverapp/strategy/result.py,sha256=E0Hl2VLnZAgQJjE2GDoKsK7JX-kPPU2KXc47Axt6hGw,4295
|
347
354
|
flwr/serverapp/strategy/strategy.py,sha256=8uJGGm1ROLZERQ_dkRS7Z_rs-yK6XCE0UxXtIdFiEWk,10789
|
348
355
|
flwr/serverapp/strategy/strategy_utils.py,sha256=hiwS7k-Hx6_c4NZXoKpHucS5CBKb7f8GppXRBSMt3Us,10851
|
349
|
-
flwr/serverapp/strategy/strategy_utils_tests.py,sha256=_adS23Lrv1QA6V_3oZ7P_csMd8RqDObFeIhOkFnNtTg,10690
|
350
356
|
flwr/simulation/__init__.py,sha256=Gg6OsP1Z-ixc3-xxzvl7j7rz2Fijy9rzyEPpxgAQCeM,1556
|
351
|
-
flwr/simulation/app.py,sha256=
|
357
|
+
flwr/simulation/app.py,sha256=b_bDyZFwBf2zpKs37Vmd5cFJSzDRE0fL-8uqA0UkAv4,10393
|
352
358
|
flwr/simulation/legacy_app.py,sha256=nMISQqW0otJL1-2Kfd94O6BLlGS2IEmEPKTM2WGKrIs,15861
|
353
359
|
flwr/simulation/ray_transport/__init__.py,sha256=ogd-0AMv2U-wBZ1r3sHWaDIOIrVqr88Xi6C8o4Dviy0,734
|
354
360
|
flwr/simulation/ray_transport/ray_actor.py,sha256=JN3xTqFIr5Z750k92CcA_uavzOHhSWDwE2WCaecvpks,19147
|
355
361
|
flwr/simulation/ray_transport/ray_client_proxy.py,sha256=2kVUDrJe2ViOJEuB0v_Xb3XUwK9yKNwDwrYQXTJDdco,7506
|
356
362
|
flwr/simulation/ray_transport/utils.py,sha256=KrexpWYCF-dAF3UHc9yDbPQWO-ahMT-BbD8nURLgiHk,2393
|
357
|
-
flwr/simulation/run_simulation.py,sha256
|
363
|
+
flwr/simulation/run_simulation.py,sha256=LrM5iI0Rf_QqrnqvJ1muKxKFlrInA3I8-SF-uIIsPik,20666
|
358
364
|
flwr/simulation/simulationio_connection.py,sha256=mzS1C6EEREwQDPceDo30anAasmTDLb9qqV2tXlBhOUA,3494
|
359
365
|
flwr/supercore/__init__.py,sha256=pqkFoow_E6UhbBlhmoD1gmTH-33yJRhBsIZqxRPFZ7U,755
|
360
366
|
flwr/supercore/app_utils.py,sha256=K76Zt6R670b1hUmxOsNc1WUCVYvF7lejXPcCO9K0Q0g,1753
|
361
367
|
flwr/supercore/cli/__init__.py,sha256=EDl2aO-fuQfxSbL-T1W9RAfA2N0hpWHmqX_GSwblJbQ,845
|
362
|
-
flwr/supercore/cli/flower_superexec.py,sha256=
|
368
|
+
flwr/supercore/cli/flower_superexec.py,sha256=JtqYrEWVu3BxLkjavsdohTOwvMwzuFqWP5j4Mo9dqsk,6155
|
369
|
+
flwr/supercore/constant.py,sha256=F9kRjisedaZcoyGvUITSDmIG12QDSCpo2LlM_l-q6jM,820
|
363
370
|
flwr/supercore/corestate/__init__.py,sha256=Vau6-L_JG5QzNqtCTa9xCKGGljc09wY8avZmIjSJemg,774
|
364
371
|
flwr/supercore/corestate/corestate.py,sha256=rDAWWeG5DcpCyQso9Z3RhwL4zr2IroPlRMcDzqoSu8s,2328
|
365
372
|
flwr/supercore/ffs/__init__.py,sha256=U3KXwG_SplEvchat27K0LYPoPHzh-cwwT_NHsGlYMt8,908
|
@@ -380,18 +387,20 @@ flwr/supercore/superexec/__init__.py,sha256=XKX208hZ6a9gZ4KT9kMqfpCtp_8VGxekzKFf
|
|
380
387
|
flwr/supercore/superexec/plugin/__init__.py,sha256=GNwq8uNdE8RB7ywEFRAvKjLFzgS3YXgz39-HBGsemWw,1035
|
381
388
|
flwr/supercore/superexec/plugin/base_exec_plugin.py,sha256=fL-Ufc9Dp56OhWOzNSJUc7HumbkuSDYqZKwde2opG4g,2074
|
382
389
|
flwr/supercore/superexec/plugin/clientapp_exec_plugin.py,sha256=9FT6ufEqV5K9g4FaAB9lVDbIv-VCH5LcxT4YKy23roE,1035
|
383
|
-
flwr/supercore/superexec/plugin/exec_plugin.py,sha256=
|
390
|
+
flwr/supercore/superexec/plugin/exec_plugin.py,sha256=4WtCQ4bsuFRlfCbg91ZcPAsX8htrCCo_fFh1DKo3cCQ,2764
|
384
391
|
flwr/supercore/superexec/plugin/serverapp_exec_plugin.py,sha256=IwRzdPV-cSKwrP2krGh0De4IkAuxsmgK0WU6J-2GXqM,1035
|
385
392
|
flwr/supercore/superexec/plugin/simulation_exec_plugin.py,sha256=upn5zE-YKkl_jTw8RzmeyQ58PU_UAlQ7CqnBXXdng8I,1060
|
386
|
-
flwr/supercore/superexec/run_superexec.py,sha256=
|
393
|
+
flwr/supercore/superexec/run_superexec.py,sha256=JiwKq9s_WPpk0S9MSi1lIgMZU120NOZLf4GlObHzI_k,7217
|
387
394
|
flwr/supercore/utils.py,sha256=ebuHMbeA8eXisX0oMPqBK3hk7uVnIE_yiqWVz8YbkpQ,1324
|
388
395
|
flwr/superlink/__init__.py,sha256=GNSuJ4-N6Z8wun2iZNlXqENt5beUyzC0Gi_tN396bbM,707
|
396
|
+
flwr/superlink/artifact_provider/__init__.py,sha256=pgZEcVPKRE874LSu3cgy0HbwSJBIpVy_HxQOmne4PAs,810
|
397
|
+
flwr/superlink/artifact_provider/artifact_provider.py,sha256=Gnlg2M2SOqCruji2B0U3ov68NJWKin9scmnWJTiSnNA,1267
|
389
398
|
flwr/superlink/servicer/__init__.py,sha256=ZC-kILcUGeh6IxJsfu24cTzUqIGXmQfEKsGfhsnhBpM,717
|
390
399
|
flwr/superlink/servicer/control/__init__.py,sha256=qhUTMt_Mg4lxslCJYn5hDSrA-lXf5ya3617BT8kR-2Y,803
|
391
400
|
flwr/superlink/servicer/control/control_event_log_interceptor.py,sha256=HauUd7Xq-b1TFZmZVl9wpBITfDttn8-1_KhlEq-HJ8M,5966
|
392
|
-
flwr/superlink/servicer/control/control_grpc.py,sha256=
|
401
|
+
flwr/superlink/servicer/control/control_grpc.py,sha256=BYm2QELbUAV_mHr0K-ZU726jjgoFXTo4M0-C6MXFzTg,4244
|
393
402
|
flwr/superlink/servicer/control/control_license_interceptor.py,sha256=T3AzmRt-PPwyTq3hrdpmZHQd5_CpPOk7TtnFZrB-JRY,3349
|
394
|
-
flwr/superlink/servicer/control/control_servicer.py,sha256=
|
403
|
+
flwr/superlink/servicer/control/control_servicer.py,sha256=zY1ARksabr776eLQDy48wDmEx9t-VXTOnHq1h5Mt61U,16143
|
395
404
|
flwr/superlink/servicer/control/control_user_auth_interceptor.py,sha256=9Aqhrt_UX80FXbIQVXUrqDHs5rD5CA7vEn0Bh-zPiYU,6232
|
396
405
|
flwr/supernode/__init__.py,sha256=KgeCaVvXWrU3rptNR1y0oBp4YtXbAcrnCcJAiOoWkI4,707
|
397
406
|
flwr/supernode/cli/__init__.py,sha256=JuEMr0-s9zv-PEWKuLB9tj1ocNfroSyNJ-oyv7ati9A,887
|
@@ -407,7 +416,7 @@ flwr/supernode/servicer/__init__.py,sha256=lucTzre5WPK7G1YLCfaqg3rbFWdNSb7ZTt-ca
|
|
407
416
|
flwr/supernode/servicer/clientappio/__init__.py,sha256=7Oy62Y_oijqF7Dxi6tpcUQyOpLc_QpIRZ83NvwmB0Yg,813
|
408
417
|
flwr/supernode/servicer/clientappio/clientappio_servicer.py,sha256=nIHRu38EWK-rpNOkcgBRAAKwYQQWFeCwu0lkO7OPZGQ,10239
|
409
418
|
flwr/supernode/start_client_internal.py,sha256=Y9S1-QlO2WP6eo4JvWzIpfaCoh2aoE7bjEYyxNNnlyg,20777
|
410
|
-
flwr_nightly-1.22.0.
|
411
|
-
flwr_nightly-1.22.0.
|
412
|
-
flwr_nightly-1.22.0.
|
413
|
-
flwr_nightly-1.22.0.
|
419
|
+
flwr_nightly-1.22.0.dev20250918.dist-info/METADATA,sha256=XdvpDYzZ_dWvMX49Pwi2gOUo0qLtrt466UABjDeyavg,14559
|
420
|
+
flwr_nightly-1.22.0.dev20250918.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
421
|
+
flwr_nightly-1.22.0.dev20250918.dist-info/entry_points.txt,sha256=hxHD2ixb_vJFDOlZV-zB4Ao32_BQlL34ftsDh1GXv14,420
|
422
|
+
flwr_nightly-1.22.0.dev20250918.dist-info/RECORD,,
|
@@ -1,323 +0,0 @@
|
|
1
|
-
# Copyright 2025 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
|
-
"""Tests for message-based strategy utilities."""
|
16
|
-
|
17
|
-
|
18
|
-
from collections import OrderedDict
|
19
|
-
from unittest.mock import Mock
|
20
|
-
|
21
|
-
import numpy as np
|
22
|
-
import pytest
|
23
|
-
from parameterized import parameterized
|
24
|
-
|
25
|
-
from flwr.common import (
|
26
|
-
Array,
|
27
|
-
ArrayRecord,
|
28
|
-
ConfigRecord,
|
29
|
-
Message,
|
30
|
-
MetricRecord,
|
31
|
-
RecordDict,
|
32
|
-
)
|
33
|
-
from flwr.serverapp.exception import InconsistentMessageReplies
|
34
|
-
|
35
|
-
from .strategy_utils import (
|
36
|
-
aggregate_arrayrecords,
|
37
|
-
aggregate_metricrecords,
|
38
|
-
config_to_str,
|
39
|
-
validate_message_reply_consistency,
|
40
|
-
)
|
41
|
-
|
42
|
-
|
43
|
-
def create_mock_reply(arrays: ArrayRecord, num_examples: float) -> Message:
|
44
|
-
"""Create a mock reply Message with default keys."""
|
45
|
-
message = Mock(spec=Message)
|
46
|
-
message.content = RecordDict(
|
47
|
-
{"arrays": arrays, "metrics": MetricRecord({"num-examples": num_examples})}
|
48
|
-
)
|
49
|
-
message.has_error.side_effect = lambda: False
|
50
|
-
message.has_content.side_effect = lambda: True
|
51
|
-
return message
|
52
|
-
|
53
|
-
|
54
|
-
def test_config_to_str() -> None:
|
55
|
-
"""Test that items of types bytes are masked out."""
|
56
|
-
config = ConfigRecord({"a": 123, "b": [1, 2, 3], "c": b"bytes"})
|
57
|
-
expected_str = "{'a': 123, 'b': [1, 2, 3], 'c': <bytes>}"
|
58
|
-
assert config_to_str(config) == expected_str
|
59
|
-
|
60
|
-
|
61
|
-
def test_arrayrecords_aggregation() -> None:
|
62
|
-
"""Test aggregation of ArrayRecords."""
|
63
|
-
num_replies = 3
|
64
|
-
num_arrays = 4
|
65
|
-
weights = [0.25, 0.4, 0.35]
|
66
|
-
np_arrays = [
|
67
|
-
[np.random.randn(7, 3) for _ in range(num_arrays)] for _ in range(num_replies)
|
68
|
-
]
|
69
|
-
|
70
|
-
avg_list = [
|
71
|
-
np.average([lst[i] for lst in np_arrays], axis=0, weights=weights)
|
72
|
-
for i in range(num_arrays)
|
73
|
-
]
|
74
|
-
|
75
|
-
# Construct RecordDicts (mimicing replies)
|
76
|
-
records = [
|
77
|
-
RecordDict(
|
78
|
-
{
|
79
|
-
"arrays": ArrayRecord(np_arrays[i]),
|
80
|
-
"metrics": MetricRecord({"weight": weights[i]}),
|
81
|
-
}
|
82
|
-
)
|
83
|
-
for i in range(num_replies)
|
84
|
-
]
|
85
|
-
# Execute aggregate
|
86
|
-
aggrd = aggregate_arrayrecords(records, weighting_metric_name="weight")
|
87
|
-
|
88
|
-
# Assert consistency
|
89
|
-
assert all(np.allclose(a, b) for a, b in zip(aggrd.to_numpy_ndarrays(), avg_list))
|
90
|
-
assert aggrd.object_id == ArrayRecord(avg_list).object_id
|
91
|
-
|
92
|
-
|
93
|
-
def test_arrayrecords_aggregation_with_ndim_zero() -> None:
|
94
|
-
"""Test aggregation of ArrayRecords with 0-dim arrays."""
|
95
|
-
num_replies = 3
|
96
|
-
weights = [0.25, 0.4, 0.35]
|
97
|
-
np_arrays = [np.array(np.random.randn()) for _ in range(num_replies)]
|
98
|
-
|
99
|
-
# For 0-dimensional arrays, we just compute the weighted average directly
|
100
|
-
avg_list = [np.average(np_arrays, axis=0, weights=weights)]
|
101
|
-
|
102
|
-
# Construct RecordDicts (mimicing replies)
|
103
|
-
records = [
|
104
|
-
RecordDict(
|
105
|
-
{
|
106
|
-
"arrays": ArrayRecord([np_arrays[i]]),
|
107
|
-
"metrics": MetricRecord({"weight": weights[i]}),
|
108
|
-
}
|
109
|
-
)
|
110
|
-
for i in range(num_replies)
|
111
|
-
]
|
112
|
-
# Execute aggregate
|
113
|
-
aggrd = aggregate_arrayrecords(records, weighting_metric_name="weight")
|
114
|
-
|
115
|
-
# Assert consistency
|
116
|
-
assert np.isclose(aggrd.to_numpy_ndarrays()[0], avg_list[0])
|
117
|
-
assert aggrd.object_id == ArrayRecord([np.array(avg_list[0])]).object_id
|
118
|
-
|
119
|
-
|
120
|
-
def test_metricrecords_aggregation() -> None:
|
121
|
-
"""Test aggregation of MetricRecords."""
|
122
|
-
num_replies = 3
|
123
|
-
weights = [0.25, 0.4, 0.35]
|
124
|
-
metric_records = [
|
125
|
-
MetricRecord({"a": 1, "b": 2.0, "c": np.random.randn(3).tolist()})
|
126
|
-
for _ in range(num_replies)
|
127
|
-
]
|
128
|
-
|
129
|
-
# Compute expected aggregated MetricRecord.
|
130
|
-
# For ease, we convert everything into numpy arrays, then aggregate
|
131
|
-
as_np_entries = [
|
132
|
-
{
|
133
|
-
k: np.array(v) if isinstance(v, (int, float, list)) else v
|
134
|
-
for k, v in record.items()
|
135
|
-
}
|
136
|
-
for record in metric_records
|
137
|
-
]
|
138
|
-
avg_list = [
|
139
|
-
np.average(
|
140
|
-
[list(entries.values())[i] for entries in as_np_entries],
|
141
|
-
axis=0,
|
142
|
-
weights=weights,
|
143
|
-
).tolist()
|
144
|
-
for i in range(len(as_np_entries[0]))
|
145
|
-
]
|
146
|
-
expected_record = MetricRecord(dict(zip(as_np_entries[0].keys(), avg_list)))
|
147
|
-
expected_record["a"] = float(expected_record["a"]) # type: ignore
|
148
|
-
expected_record["b"] = float(expected_record["b"]) # type: ignore
|
149
|
-
|
150
|
-
# Construct RecordDicts (mimicing replies)
|
151
|
-
# Inject weighting factor
|
152
|
-
records = [
|
153
|
-
RecordDict(
|
154
|
-
{
|
155
|
-
"metrics": MetricRecord(
|
156
|
-
record.__dict__["_data"] | {"weight": weights[i]}
|
157
|
-
),
|
158
|
-
}
|
159
|
-
)
|
160
|
-
for i, record in enumerate(metric_records)
|
161
|
-
]
|
162
|
-
|
163
|
-
# Execute aggregate
|
164
|
-
aggrd = aggregate_metricrecords(records, weighting_metric_name="weight")
|
165
|
-
# Assert
|
166
|
-
assert expected_record.object_id == aggrd.object_id
|
167
|
-
|
168
|
-
|
169
|
-
@parameterized.expand( # type: ignore
|
170
|
-
[
|
171
|
-
(
|
172
|
-
True,
|
173
|
-
RecordDict(
|
174
|
-
{
|
175
|
-
"global-model": ArrayRecord([np.random.randn(7, 3)]),
|
176
|
-
"metrics": MetricRecord({"weight": 0.123}),
|
177
|
-
}
|
178
|
-
),
|
179
|
-
), # Compliant
|
180
|
-
(
|
181
|
-
False,
|
182
|
-
RecordDict(
|
183
|
-
{
|
184
|
-
"global-model": ArrayRecord([np.random.randn(7, 3)]),
|
185
|
-
"metrics": MetricRecord({"weight": [0.123]}),
|
186
|
-
}
|
187
|
-
),
|
188
|
-
), # Weighting key is not a scalar (BAD)
|
189
|
-
(
|
190
|
-
False,
|
191
|
-
RecordDict(
|
192
|
-
{
|
193
|
-
"global-model": ArrayRecord([np.random.randn(7, 3)]),
|
194
|
-
"metrics": MetricRecord({"loss": 0.01}),
|
195
|
-
}
|
196
|
-
),
|
197
|
-
), # No weighting key in MetricRecord (BAD)
|
198
|
-
(
|
199
|
-
False,
|
200
|
-
RecordDict({"global-model": ArrayRecord([np.random.randn(7, 3)])}),
|
201
|
-
), # No MetricsRecord (BAD)
|
202
|
-
(
|
203
|
-
False,
|
204
|
-
RecordDict(
|
205
|
-
{
|
206
|
-
"global-model": ArrayRecord([np.random.randn(7, 3)]),
|
207
|
-
"another-model": ArrayRecord([np.random.randn(7, 3)]),
|
208
|
-
}
|
209
|
-
),
|
210
|
-
), # Two ArrayRecords (BAD)
|
211
|
-
(
|
212
|
-
False,
|
213
|
-
RecordDict(
|
214
|
-
{
|
215
|
-
"global-model": ArrayRecord([np.random.randn(7, 3)]),
|
216
|
-
"metrics": MetricRecord({"weight": 0.123}),
|
217
|
-
"more-metrics": MetricRecord({"loss": 0.321}),
|
218
|
-
}
|
219
|
-
),
|
220
|
-
), # Two MetricRecords (BAD)
|
221
|
-
]
|
222
|
-
)
|
223
|
-
def test_consistency_of_replies_with_matching_keys(
|
224
|
-
is_valid: bool, recorddict: RecordDict
|
225
|
-
) -> None:
|
226
|
-
"""Test consistency in replies."""
|
227
|
-
# Create dummy records
|
228
|
-
records = [recorddict for _ in range(3)]
|
229
|
-
|
230
|
-
if not is_valid:
|
231
|
-
# Should raise InconsistentMessageReplies exception
|
232
|
-
with pytest.raises(InconsistentMessageReplies):
|
233
|
-
validate_message_reply_consistency(
|
234
|
-
records, weighted_by_key="weight", check_arrayrecord=True
|
235
|
-
)
|
236
|
-
else:
|
237
|
-
# Should not raise an exception
|
238
|
-
validate_message_reply_consistency(
|
239
|
-
records, weighted_by_key="weight", check_arrayrecord=True
|
240
|
-
)
|
241
|
-
|
242
|
-
|
243
|
-
@parameterized.expand( # type: ignore
|
244
|
-
[
|
245
|
-
(
|
246
|
-
[
|
247
|
-
RecordDict(
|
248
|
-
{
|
249
|
-
"global-model": ArrayRecord([np.random.randn(7, 3)]),
|
250
|
-
"metrics": MetricRecord({"weight": 0.123}),
|
251
|
-
}
|
252
|
-
),
|
253
|
-
RecordDict(
|
254
|
-
{
|
255
|
-
"model": ArrayRecord([np.random.randn(7, 3)]),
|
256
|
-
"metrics": MetricRecord({"weight": 0.123}),
|
257
|
-
}
|
258
|
-
),
|
259
|
-
],
|
260
|
-
), # top-level keys don't match for ArrayRecords
|
261
|
-
(
|
262
|
-
[
|
263
|
-
RecordDict(
|
264
|
-
{
|
265
|
-
"global-model": ArrayRecord(
|
266
|
-
OrderedDict({"a": Array(np.random.randn(7, 3))})
|
267
|
-
),
|
268
|
-
"metrics": MetricRecord({"weight": 0.123}),
|
269
|
-
}
|
270
|
-
),
|
271
|
-
RecordDict(
|
272
|
-
{
|
273
|
-
"global-model": ArrayRecord(
|
274
|
-
OrderedDict({"b": Array(np.random.randn(7, 3))})
|
275
|
-
),
|
276
|
-
"metrics": MetricRecord({"weight": 0.123}),
|
277
|
-
}
|
278
|
-
),
|
279
|
-
],
|
280
|
-
), # top-level keys match for ArrayRecords but not those for Arrays
|
281
|
-
(
|
282
|
-
[
|
283
|
-
RecordDict(
|
284
|
-
{
|
285
|
-
"global-model": ArrayRecord([np.random.randn(7, 3)]),
|
286
|
-
"metrics": MetricRecord({"weight": 0.123}),
|
287
|
-
}
|
288
|
-
),
|
289
|
-
RecordDict(
|
290
|
-
{
|
291
|
-
"global-model": ArrayRecord([np.random.randn(7, 3)]),
|
292
|
-
"my-metrics": MetricRecord({"weight": 0.123}),
|
293
|
-
}
|
294
|
-
),
|
295
|
-
],
|
296
|
-
), # top-level keys don't match for MetricRecords
|
297
|
-
(
|
298
|
-
[
|
299
|
-
RecordDict(
|
300
|
-
{
|
301
|
-
"global-model": ArrayRecord([np.random.randn(7, 3)]),
|
302
|
-
"metrics": MetricRecord({"weight": 0.123}),
|
303
|
-
}
|
304
|
-
),
|
305
|
-
RecordDict(
|
306
|
-
{
|
307
|
-
"global-model": ArrayRecord([np.random.randn(7, 3)]),
|
308
|
-
"my-metrics": MetricRecord({"my-weights": 0.123}),
|
309
|
-
}
|
310
|
-
),
|
311
|
-
],
|
312
|
-
), # top-level keys match for MetricRecords but not inner ones
|
313
|
-
]
|
314
|
-
)
|
315
|
-
def test_consistency_of_replies_with_different_keys(
|
316
|
-
list_records: list[RecordDict],
|
317
|
-
) -> None:
|
318
|
-
"""Test consistency in replies when records don't have matching keys."""
|
319
|
-
# All test cases expect InconsistentMessageReplies exception to be raised
|
320
|
-
with pytest.raises(InconsistentMessageReplies):
|
321
|
-
validate_message_reply_consistency(
|
322
|
-
list_records, weighted_by_key="weight", check_arrayrecord=True
|
323
|
-
)
|
{flwr_nightly-1.22.0.dev20250916.dist-info → flwr_nightly-1.22.0.dev20250918.dist-info}/WHEEL
RENAMED
File without changes
|
File without changes
|