flwr-nightly 1.8.0.dev20240310__tar.gz → 1.8.0.dev20240311__tar.gz

Sign up to get free protection for your applications and to get access to all the features.
Files changed (206) hide show
  1. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/PKG-INFO +1 -1
  2. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/pyproject.toml +1 -1
  3. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/cli/new/new.py +6 -3
  4. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/cli/utils.py +14 -1
  5. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/client/app.py +25 -2
  6. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/client/mod/__init__.py +2 -1
  7. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/client/mod/secure_aggregation/__init__.py +2 -0
  8. flwr_nightly-1.8.0.dev20240311/src/py/flwr/client/mod/secure_aggregation/secagg_mod.py +30 -0
  9. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/client/mod/secure_aggregation/secaggplus_mod.py +12 -12
  10. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/common/logger.py +6 -8
  11. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/common/secure_aggregation/secaggplus_constants.py +2 -2
  12. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/server/superlink/state/in_memory_state.py +34 -32
  13. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/server/workflow/__init__.py +2 -1
  14. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/server/workflow/default_workflows.py +36 -37
  15. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/server/workflow/secure_aggregation/__init__.py +2 -0
  16. flwr_nightly-1.8.0.dev20240311/src/py/flwr/server/workflow/secure_aggregation/secagg_workflow.py +112 -0
  17. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/server/workflow/secure_aggregation/secaggplus_workflow.py +85 -10
  18. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/LICENSE +0 -0
  19. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/README.md +0 -0
  20. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/__init__.py +0 -0
  21. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/cli/__init__.py +0 -0
  22. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/cli/app.py +0 -0
  23. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/cli/example.py +0 -0
  24. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/cli/flower_toml.py +0 -0
  25. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/cli/new/__init__.py +0 -0
  26. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/cli/new/templates/__init__.py +0 -0
  27. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/cli/new/templates/app/README.md.tpl +0 -0
  28. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/cli/new/templates/app/__init__.py +0 -0
  29. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/cli/new/templates/app/code/__init__.py +0 -0
  30. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/cli/new/templates/app/code/__init__.py.tpl +0 -0
  31. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/cli/new/templates/app/code/client.numpy.py.tpl +0 -0
  32. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/cli/new/templates/app/code/client.pytorch.py.tpl +0 -0
  33. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/cli/new/templates/app/code/client.tensorflow.py.tpl +0 -0
  34. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/cli/new/templates/app/code/server.numpy.py.tpl +0 -0
  35. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/cli/new/templates/app/code/server.pytorch.py.tpl +0 -0
  36. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/cli/new/templates/app/code/server.tensorflow.py.tpl +0 -0
  37. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/cli/new/templates/app/code/task.pytorch.py.tpl +0 -0
  38. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/cli/new/templates/app/flower.toml.tpl +0 -0
  39. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/cli/new/templates/app/pyproject.toml.tpl +0 -0
  40. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/cli/new/templates/app/requirements.numpy.txt.tpl +0 -0
  41. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/cli/new/templates/app/requirements.pytorch.txt.tpl +0 -0
  42. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/cli/new/templates/app/requirements.tensorflow.txt.tpl +0 -0
  43. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/cli/run/__init__.py +0 -0
  44. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/cli/run/run.py +0 -0
  45. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/client/__init__.py +0 -0
  46. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/client/client.py +0 -0
  47. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/client/client_app.py +0 -0
  48. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/client/dpfedavg_numpy_client.py +0 -0
  49. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/client/grpc_client/__init__.py +0 -0
  50. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/client/grpc_client/connection.py +0 -0
  51. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/client/grpc_rere_client/__init__.py +0 -0
  52. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/client/grpc_rere_client/connection.py +0 -0
  53. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/client/message_handler/__init__.py +0 -0
  54. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/client/message_handler/message_handler.py +0 -0
  55. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/client/message_handler/task_handler.py +0 -0
  56. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/client/mod/centraldp_mods.py +0 -0
  57. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/client/mod/localdp_mod.py +0 -0
  58. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/client/mod/utils.py +0 -0
  59. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/client/node_state.py +0 -0
  60. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/client/node_state_tests.py +0 -0
  61. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/client/numpy_client.py +0 -0
  62. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/client/rest_client/__init__.py +0 -0
  63. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/client/rest_client/connection.py +0 -0
  64. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/client/typing.py +0 -0
  65. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/common/__init__.py +0 -0
  66. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/common/address.py +0 -0
  67. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/common/constant.py +0 -0
  68. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/common/context.py +0 -0
  69. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/common/date.py +0 -0
  70. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/common/differential_privacy.py +0 -0
  71. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/common/differential_privacy_constants.py +0 -0
  72. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/common/dp.py +0 -0
  73. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/common/exit_handlers.py +0 -0
  74. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/common/grpc.py +0 -0
  75. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/common/message.py +0 -0
  76. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/common/object_ref.py +0 -0
  77. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/common/parameter.py +0 -0
  78. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/common/record/__init__.py +0 -0
  79. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/common/record/configsrecord.py +0 -0
  80. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/common/record/conversion_utils.py +0 -0
  81. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/common/record/metricsrecord.py +0 -0
  82. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/common/record/parametersrecord.py +0 -0
  83. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/common/record/recordset.py +0 -0
  84. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/common/record/typeddict.py +0 -0
  85. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/common/recordset_compat.py +0 -0
  86. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/common/retry_invoker.py +0 -0
  87. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/common/secure_aggregation/__init__.py +0 -0
  88. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/common/secure_aggregation/crypto/__init__.py +0 -0
  89. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/common/secure_aggregation/crypto/shamir.py +0 -0
  90. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/common/secure_aggregation/crypto/symmetric_encryption.py +0 -0
  91. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/common/secure_aggregation/ndarrays_arithmetic.py +0 -0
  92. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/common/secure_aggregation/quantization.py +0 -0
  93. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/common/secure_aggregation/secaggplus_utils.py +0 -0
  94. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/common/serde.py +0 -0
  95. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/common/telemetry.py +0 -0
  96. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/common/typing.py +0 -0
  97. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/common/version.py +0 -0
  98. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/proto/__init__.py +0 -0
  99. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/proto/driver_pb2.py +0 -0
  100. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/proto/driver_pb2.pyi +0 -0
  101. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/proto/driver_pb2_grpc.py +0 -0
  102. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/proto/driver_pb2_grpc.pyi +0 -0
  103. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/proto/error_pb2.py +0 -0
  104. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/proto/error_pb2.pyi +0 -0
  105. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/proto/error_pb2_grpc.py +0 -0
  106. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/proto/error_pb2_grpc.pyi +0 -0
  107. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/proto/fleet_pb2.py +0 -0
  108. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/proto/fleet_pb2.pyi +0 -0
  109. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/proto/fleet_pb2_grpc.py +0 -0
  110. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/proto/fleet_pb2_grpc.pyi +0 -0
  111. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/proto/node_pb2.py +0 -0
  112. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/proto/node_pb2.pyi +0 -0
  113. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/proto/node_pb2_grpc.py +0 -0
  114. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/proto/node_pb2_grpc.pyi +0 -0
  115. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/proto/recordset_pb2.py +0 -0
  116. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/proto/recordset_pb2.pyi +0 -0
  117. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/proto/recordset_pb2_grpc.py +0 -0
  118. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/proto/recordset_pb2_grpc.pyi +0 -0
  119. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/proto/task_pb2.py +0 -0
  120. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/proto/task_pb2.pyi +0 -0
  121. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/proto/task_pb2_grpc.py +0 -0
  122. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/proto/task_pb2_grpc.pyi +0 -0
  123. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/proto/transport_pb2.py +0 -0
  124. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/proto/transport_pb2.pyi +0 -0
  125. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/proto/transport_pb2_grpc.py +0 -0
  126. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/proto/transport_pb2_grpc.pyi +0 -0
  127. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/py.typed +0 -0
  128. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/server/__init__.py +0 -0
  129. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/server/app.py +0 -0
  130. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/server/client_manager.py +0 -0
  131. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/server/client_proxy.py +0 -0
  132. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/server/compat/__init__.py +0 -0
  133. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/server/compat/app.py +0 -0
  134. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/server/compat/app_utils.py +0 -0
  135. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/server/compat/driver_client_proxy.py +0 -0
  136. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/server/compat/legacy_context.py +0 -0
  137. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/server/criterion.py +0 -0
  138. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/server/driver/__init__.py +0 -0
  139. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/server/driver/driver.py +0 -0
  140. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/server/driver/grpc_driver.py +0 -0
  141. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/server/history.py +0 -0
  142. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/server/run_serverapp.py +0 -0
  143. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/server/server.py +0 -0
  144. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/server/server_app.py +0 -0
  145. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/server/server_config.py +0 -0
  146. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/server/strategy/__init__.py +0 -0
  147. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/server/strategy/aggregate.py +0 -0
  148. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/server/strategy/bulyan.py +0 -0
  149. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/server/strategy/dp_adaptive_clipping.py +0 -0
  150. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/server/strategy/dp_fixed_clipping.py +0 -0
  151. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/server/strategy/dpfedavg_adaptive.py +0 -0
  152. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/server/strategy/dpfedavg_fixed.py +0 -0
  153. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/server/strategy/fault_tolerant_fedavg.py +0 -0
  154. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/server/strategy/fedadagrad.py +0 -0
  155. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/server/strategy/fedadam.py +0 -0
  156. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/server/strategy/fedavg.py +0 -0
  157. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/server/strategy/fedavg_android.py +0 -0
  158. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/server/strategy/fedavgm.py +0 -0
  159. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/server/strategy/fedmedian.py +0 -0
  160. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/server/strategy/fedopt.py +0 -0
  161. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/server/strategy/fedprox.py +0 -0
  162. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/server/strategy/fedtrimmedavg.py +0 -0
  163. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/server/strategy/fedxgb_bagging.py +0 -0
  164. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/server/strategy/fedxgb_cyclic.py +0 -0
  165. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/server/strategy/fedxgb_nn_avg.py +0 -0
  166. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/server/strategy/fedyogi.py +0 -0
  167. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/server/strategy/krum.py +0 -0
  168. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/server/strategy/qfedavg.py +0 -0
  169. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/server/strategy/strategy.py +0 -0
  170. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/server/superlink/__init__.py +0 -0
  171. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/server/superlink/driver/__init__.py +0 -0
  172. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/server/superlink/driver/driver_grpc.py +0 -0
  173. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/server/superlink/driver/driver_servicer.py +0 -0
  174. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/server/superlink/fleet/__init__.py +0 -0
  175. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/server/superlink/fleet/grpc_bidi/__init__.py +0 -0
  176. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/server/superlink/fleet/grpc_bidi/flower_service_servicer.py +0 -0
  177. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/server/superlink/fleet/grpc_bidi/grpc_bridge.py +0 -0
  178. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/server/superlink/fleet/grpc_bidi/grpc_client_proxy.py +0 -0
  179. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/server/superlink/fleet/grpc_bidi/grpc_server.py +0 -0
  180. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/server/superlink/fleet/grpc_rere/__init__.py +0 -0
  181. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/server/superlink/fleet/grpc_rere/fleet_servicer.py +0 -0
  182. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/server/superlink/fleet/message_handler/__init__.py +0 -0
  183. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/server/superlink/fleet/message_handler/message_handler.py +0 -0
  184. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/server/superlink/fleet/rest_rere/__init__.py +0 -0
  185. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/server/superlink/fleet/rest_rere/rest_api.py +0 -0
  186. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/server/superlink/fleet/vce/__init__.py +0 -0
  187. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/server/superlink/fleet/vce/backend/__init__.py +0 -0
  188. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/server/superlink/fleet/vce/backend/backend.py +0 -0
  189. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/server/superlink/fleet/vce/backend/raybackend.py +0 -0
  190. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/server/superlink/fleet/vce/vce_api.py +0 -0
  191. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/server/superlink/state/__init__.py +0 -0
  192. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/server/superlink/state/sqlite_state.py +0 -0
  193. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/server/superlink/state/state.py +0 -0
  194. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/server/superlink/state/state_factory.py +0 -0
  195. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/server/typing.py +0 -0
  196. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/server/utils/__init__.py +0 -0
  197. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/server/utils/tensorboard.py +0 -0
  198. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/server/utils/validator.py +0 -0
  199. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/server/workflow/constant.py +0 -0
  200. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/simulation/__init__.py +0 -0
  201. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/simulation/app.py +0 -0
  202. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/simulation/ray_transport/__init__.py +0 -0
  203. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/simulation/ray_transport/ray_actor.py +0 -0
  204. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/simulation/ray_transport/ray_client_proxy.py +0 -0
  205. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/simulation/ray_transport/utils.py +0 -0
  206. {flwr_nightly-1.8.0.dev20240310 → flwr_nightly-1.8.0.dev20240311}/src/py/flwr/simulation/run_simulation.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: flwr-nightly
3
- Version: 1.8.0.dev20240310
3
+ Version: 1.8.0.dev20240311
4
4
  Summary: Flower: A Friendly Federated Learning Framework
5
5
  Home-page: https://flower.ai
6
6
  License: Apache-2.0
@@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api"
4
4
 
5
5
  [tool.poetry]
6
6
  name = "flwr-nightly"
7
- version = "1.8.0-dev20240310"
7
+ version = "1.8.0-dev20240311"
8
8
  description = "Flower: A Friendly Federated Learning Framework"
9
9
  license = "Apache-2.0"
10
10
  authors = ["The Flower Authors <hello@flower.ai>"]
@@ -22,7 +22,7 @@ from typing import Dict, Optional
22
22
  import typer
23
23
  from typing_extensions import Annotated
24
24
 
25
- from ..utils import prompt_options
25
+ from ..utils import prompt_options, prompt_text
26
26
 
27
27
 
28
28
  class MlFramework(str, Enum):
@@ -72,9 +72,9 @@ def render_and_create(file_path: str, template: str, context: Dict[str, str]) ->
72
72
 
73
73
  def new(
74
74
  project_name: Annotated[
75
- str,
75
+ Optional[str],
76
76
  typer.Argument(metavar="project_name", help="The name of the project"),
77
- ],
77
+ ] = None,
78
78
  framework: Annotated[
79
79
  Optional[MlFramework],
80
80
  typer.Option(case_sensitive=False, help="The ML framework to use"),
@@ -83,6 +83,9 @@ def new(
83
83
  """Create new Flower project."""
84
84
  print(f"Creating Flower project {project_name}...")
85
85
 
86
+ if project_name is None:
87
+ project_name = prompt_text("Please provide project name")
88
+
86
89
  if framework is not None:
87
90
  framework_str = str(framework.value)
88
91
  else:
@@ -14,11 +14,24 @@
14
14
  # ==============================================================================
15
15
  """Flower command line interface utils."""
16
16
 
17
- from typing import List
17
+ from typing import List, cast
18
18
 
19
19
  import typer
20
20
 
21
21
 
22
+ def prompt_text(text: str) -> str:
23
+ """Ask user to enter text input."""
24
+ while True:
25
+ result = typer.prompt(
26
+ typer.style(f"\n💬 {text}", fg=typer.colors.MAGENTA, bold=True)
27
+ )
28
+ if len(result) > 0:
29
+ break
30
+ print(typer.style("❌ Invalid entry", fg=typer.colors.RED, bold=True))
31
+
32
+ return cast(str, result)
33
+
34
+
22
35
  def prompt_options(text: str, options: List[str]) -> str:
23
36
  """Ask user to select one of the given options and return the selected item."""
24
37
  # Turn options into a list with index as in " [ 0] quickstart-pytorch"
@@ -456,7 +456,19 @@ def _start_client_internal(
456
456
  time.sleep(3) # Wait for 3s before asking again
457
457
  continue
458
458
 
459
- log(INFO, "Received message")
459
+ log(INFO, "")
460
+ log(
461
+ INFO,
462
+ "[RUN %s, ROUND %s]",
463
+ message.metadata.run_id,
464
+ message.metadata.group_id,
465
+ )
466
+ log(
467
+ INFO,
468
+ "Received: %s message %s",
469
+ message.metadata.message_type,
470
+ message.metadata.message_id,
471
+ )
460
472
 
461
473
  # Handle control message
462
474
  out_message, sleep_duration = handle_control_message(message)
@@ -484,7 +496,18 @@ def _start_client_internal(
484
496
 
485
497
  # Send
486
498
  send(out_message)
487
- log(INFO, "Sent reply")
499
+ log(
500
+ INFO,
501
+ "[RUN %s, ROUND %s]",
502
+ out_message.metadata.run_id,
503
+ out_message.metadata.group_id,
504
+ )
505
+ log(
506
+ INFO,
507
+ "Sent: %s reply to message %s",
508
+ out_message.metadata.message_type,
509
+ message.metadata.message_id,
510
+ )
488
511
 
489
512
  # Unregister node
490
513
  if delete_node is not None:
@@ -17,7 +17,7 @@
17
17
 
18
18
  from .centraldp_mods import adaptiveclipping_mod, fixedclipping_mod
19
19
  from .localdp_mod import LocalDpMod
20
- from .secure_aggregation.secaggplus_mod import secaggplus_mod
20
+ from .secure_aggregation import secagg_mod, secaggplus_mod
21
21
  from .utils import make_ffn
22
22
 
23
23
  __all__ = [
@@ -25,5 +25,6 @@ __all__ = [
25
25
  "fixedclipping_mod",
26
26
  "LocalDpMod",
27
27
  "make_ffn",
28
+ "secagg_mod",
28
29
  "secaggplus_mod",
29
30
  ]
@@ -15,8 +15,10 @@
15
15
  """Secure Aggregation mods."""
16
16
 
17
17
 
18
+ from .secagg_mod import secagg_mod
18
19
  from .secaggplus_mod import secaggplus_mod
19
20
 
20
21
  __all__ = [
22
+ "secagg_mod",
21
23
  "secaggplus_mod",
22
24
  ]
@@ -0,0 +1,30 @@
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
+ """Modifier for the SecAgg protocol."""
16
+
17
+
18
+ from flwr.client.typing import ClientAppCallable
19
+ from flwr.common import Context, Message
20
+
21
+ from .secaggplus_mod import secaggplus_mod
22
+
23
+
24
+ def secagg_mod(
25
+ msg: Message,
26
+ ctxt: Context,
27
+ call_next: ClientAppCallable,
28
+ ) -> Message:
29
+ """Handle incoming message and return results, following the SecAgg protocol."""
30
+ return secaggplus_mod(msg, ctxt, call_next)
@@ -178,9 +178,9 @@ def secaggplus_mod(
178
178
  res = _setup(state, configs)
179
179
  elif state.current_stage == Stage.SHARE_KEYS:
180
180
  res = _share_keys(state, configs)
181
- elif state.current_stage == Stage.COLLECT_MASKED_INPUT:
181
+ elif state.current_stage == Stage.COLLECT_MASKED_VECTORS:
182
182
  fit = _get_fit_fn(msg, ctxt, call_next)
183
- res = _collect_masked_input(state, configs, fit)
183
+ res = _collect_masked_vectors(state, configs, fit)
184
184
  elif state.current_stage == Stage.UNMASK:
185
185
  res = _unmask(state, configs)
186
186
  else:
@@ -199,7 +199,7 @@ def check_stage(current_stage: str, configs: ConfigsRecord) -> None:
199
199
  # Check the existence of Config.STAGE
200
200
  if Key.STAGE not in configs:
201
201
  raise KeyError(
202
- f"The required key '{Key.STAGE}' is missing from the input `named_values`."
202
+ f"The required key '{Key.STAGE}' is missing from the ConfigsRecord."
203
203
  )
204
204
 
205
205
  # Check the value type of the Config.STAGE
@@ -215,7 +215,7 @@ def check_stage(current_stage: str, configs: ConfigsRecord) -> None:
215
215
  if current_stage != Stage.UNMASK:
216
216
  log(WARNING, "Restart from the setup stage")
217
217
  # If stage is not "setup",
218
- # the stage from `named_values` should be the expected next stage
218
+ # the stage from configs should be the expected next stage
219
219
  else:
220
220
  stages = Stage.all()
221
221
  expected_next_stage = stages[(stages.index(current_stage) + 1) % len(stages)]
@@ -229,7 +229,7 @@ def check_stage(current_stage: str, configs: ConfigsRecord) -> None:
229
229
  # pylint: disable-next=too-many-branches
230
230
  def check_configs(stage: str, configs: ConfigsRecord) -> None:
231
231
  """Check the validity of the configs."""
232
- # Check `named_values` for the setup stage
232
+ # Check configs for the setup stage
233
233
  if stage == Stage.SETUP:
234
234
  key_type_pairs = [
235
235
  (Key.SAMPLE_NUMBER, int),
@@ -243,7 +243,7 @@ def check_configs(stage: str, configs: ConfigsRecord) -> None:
243
243
  if key not in configs:
244
244
  raise KeyError(
245
245
  f"Stage {Stage.SETUP}: the required key '{key}' is "
246
- "missing from the input `named_values`."
246
+ "missing from the ConfigsRecord."
247
247
  )
248
248
  # Bool is a subclass of int in Python,
249
249
  # so `isinstance(v, int)` will return True even if v is a boolean.
@@ -266,7 +266,7 @@ def check_configs(stage: str, configs: ConfigsRecord) -> None:
266
266
  f"Stage {Stage.SHARE_KEYS}: "
267
267
  f"the value for the key '{key}' must be a list of two bytes."
268
268
  )
269
- elif stage == Stage.COLLECT_MASKED_INPUT:
269
+ elif stage == Stage.COLLECT_MASKED_VECTORS:
270
270
  key_type_pairs = [
271
271
  (Key.CIPHERTEXT_LIST, bytes),
272
272
  (Key.SOURCE_LIST, int),
@@ -274,9 +274,9 @@ def check_configs(stage: str, configs: ConfigsRecord) -> None:
274
274
  for key, expected_type in key_type_pairs:
275
275
  if key not in configs:
276
276
  raise KeyError(
277
- f"Stage {Stage.COLLECT_MASKED_INPUT}: "
277
+ f"Stage {Stage.COLLECT_MASKED_VECTORS}: "
278
278
  f"the required key '{key}' is "
279
- "missing from the input `named_values`."
279
+ "missing from the ConfigsRecord."
280
280
  )
281
281
  if not isinstance(configs[key], list) or any(
282
282
  elm
@@ -285,7 +285,7 @@ def check_configs(stage: str, configs: ConfigsRecord) -> None:
285
285
  if type(elm) is not expected_type
286
286
  ):
287
287
  raise TypeError(
288
- f"Stage {Stage.COLLECT_MASKED_INPUT}: "
288
+ f"Stage {Stage.COLLECT_MASKED_VECTORS}: "
289
289
  f"the value for the key '{key}' "
290
290
  f"must be of type List[{expected_type.__name__}]"
291
291
  )
@@ -299,7 +299,7 @@ def check_configs(stage: str, configs: ConfigsRecord) -> None:
299
299
  raise KeyError(
300
300
  f"Stage {Stage.UNMASK}: "
301
301
  f"the required key '{key}' is "
302
- "missing from the input `named_values`."
302
+ "missing from the ConfigsRecord."
303
303
  )
304
304
  if not isinstance(configs[key], list) or any(
305
305
  elm
@@ -414,7 +414,7 @@ def _share_keys(
414
414
 
415
415
 
416
416
  # pylint: disable-next=too-many-locals
417
- def _collect_masked_input(
417
+ def _collect_masked_vectors(
418
418
  state: SecAggPlusState,
419
419
  configs: ConfigsRecord,
420
420
  fit: Callable[[], FitRes],
@@ -168,11 +168,10 @@ def warn_experimental_feature(name: str) -> None:
168
168
  """Warn the user when they use an experimental feature."""
169
169
  log(
170
170
  WARN,
171
- """
172
- EXPERIMENTAL FEATURE: %s
171
+ """EXPERIMENTAL FEATURE: %s
173
172
 
174
- This is an experimental feature. It could change significantly or be removed
175
- entirely in future versions of Flower.
173
+ This is an experimental feature. It could change significantly or be removed
174
+ entirely in future versions of Flower.
176
175
  """,
177
176
  name,
178
177
  )
@@ -182,11 +181,10 @@ def warn_deprecated_feature(name: str) -> None:
182
181
  """Warn the user when they use a deprecated feature."""
183
182
  log(
184
183
  WARN,
185
- """
186
- DEPRECATED FEATURE: %s
184
+ """DEPRECATED FEATURE: %s
187
185
 
188
- This is a deprecated feature. It will be removed
189
- entirely in future versions of Flower.
186
+ This is a deprecated feature. It will be removed
187
+ entirely in future versions of Flower.
190
188
  """,
191
189
  name,
192
190
  )
@@ -27,9 +27,9 @@ class Stage:
27
27
 
28
28
  SETUP = "setup"
29
29
  SHARE_KEYS = "share_keys"
30
- COLLECT_MASKED_INPUT = "collect_masked_input"
30
+ COLLECT_MASKED_VECTORS = "collect_masked_vectors"
31
31
  UNMASK = "unmask"
32
- _stages = (SETUP, SHARE_KEYS, COLLECT_MASKED_INPUT, UNMASK)
32
+ _stages = (SETUP, SHARE_KEYS, COLLECT_MASKED_VECTORS, UNMASK)
33
33
 
34
34
  @classmethod
35
35
  def all(cls) -> tuple[str, str, str, str]:
@@ -122,7 +122,8 @@ class InMemoryState(State):
122
122
  task_res.task_id = str(task_id)
123
123
  task_res.task.created_at = created_at.isoformat()
124
124
  task_res.task.ttl = ttl.isoformat()
125
- self.task_res_store[task_id] = task_res
125
+ with self.lock:
126
+ self.task_res_store[task_id] = task_res
126
127
 
127
128
  # Return the new task_id
128
129
  return task_id
@@ -132,46 +133,47 @@ class InMemoryState(State):
132
133
  if limit is not None and limit < 1:
133
134
  raise AssertionError("`limit` must be >= 1")
134
135
 
135
- # Find TaskRes that were not delivered yet
136
- task_res_list: List[TaskRes] = []
137
- for _, task_res in self.task_res_store.items():
138
- if (
139
- UUID(task_res.task.ancestry[0]) in task_ids
140
- and task_res.task.delivered_at == ""
141
- ):
142
- task_res_list.append(task_res)
143
- if limit and len(task_res_list) == limit:
144
- break
136
+ with self.lock:
137
+ # Find TaskRes that were not delivered yet
138
+ task_res_list: List[TaskRes] = []
139
+ for _, task_res in self.task_res_store.items():
140
+ if (
141
+ UUID(task_res.task.ancestry[0]) in task_ids
142
+ and task_res.task.delivered_at == ""
143
+ ):
144
+ task_res_list.append(task_res)
145
+ if limit and len(task_res_list) == limit:
146
+ break
145
147
 
146
- # Mark all of them as delivered
147
- delivered_at = now().isoformat()
148
- for task_res in task_res_list:
149
- task_res.task.delivered_at = delivered_at
148
+ # Mark all of them as delivered
149
+ delivered_at = now().isoformat()
150
+ for task_res in task_res_list:
151
+ task_res.task.delivered_at = delivered_at
150
152
 
151
- # Return TaskRes
152
- return task_res_list
153
+ # Return TaskRes
154
+ return task_res_list
153
155
 
154
156
  def delete_tasks(self, task_ids: Set[UUID]) -> None:
155
157
  """Delete all delivered TaskIns/TaskRes pairs."""
156
158
  task_ins_to_be_deleted: Set[UUID] = set()
157
159
  task_res_to_be_deleted: Set[UUID] = set()
158
160
 
159
- for task_ins_id in task_ids:
160
- # Find the task_id of the matching task_res
161
- for task_res_id, task_res in self.task_res_store.items():
162
- if UUID(task_res.task.ancestry[0]) != task_ins_id:
163
- continue
164
- if task_res.task.delivered_at == "":
165
- continue
166
-
167
- task_ins_to_be_deleted.add(task_ins_id)
168
- task_res_to_be_deleted.add(task_res_id)
169
-
170
- for task_id in task_ins_to_be_deleted:
171
- with self.lock:
161
+ with self.lock:
162
+ for task_ins_id in task_ids:
163
+ # Find the task_id of the matching task_res
164
+ for task_res_id, task_res in self.task_res_store.items():
165
+ if UUID(task_res.task.ancestry[0]) != task_ins_id:
166
+ continue
167
+ if task_res.task.delivered_at == "":
168
+ continue
169
+
170
+ task_ins_to_be_deleted.add(task_ins_id)
171
+ task_res_to_be_deleted.add(task_res_id)
172
+
173
+ for task_id in task_ins_to_be_deleted:
172
174
  del self.task_ins_store[task_id]
173
- for task_id in task_res_to_be_deleted:
174
- del self.task_res_store[task_id]
175
+ for task_id in task_res_to_be_deleted:
176
+ del self.task_res_store[task_id]
175
177
 
176
178
  def num_task_ins(self) -> int:
177
179
  """Calculate the number of task_ins in store.
@@ -16,9 +16,10 @@
16
16
 
17
17
 
18
18
  from .default_workflows import DefaultWorkflow
19
- from .secure_aggregation import SecAggPlusWorkflow
19
+ from .secure_aggregation import SecAggPlusWorkflow, SecAggWorkflow
20
20
 
21
21
  __all__ = [
22
22
  "DefaultWorkflow",
23
23
  "SecAggPlusWorkflow",
24
+ "SecAggWorkflow",
24
25
  ]
@@ -15,8 +15,9 @@
15
15
  """Legacy default workflows."""
16
16
 
17
17
 
18
+ import io
18
19
  import timeit
19
- from logging import DEBUG, INFO
20
+ from logging import INFO
20
21
  from typing import Optional, cast
21
22
 
22
23
  import flwr.common.recordset_compat as compat
@@ -58,16 +59,18 @@ class DefaultWorkflow:
58
59
  )
59
60
 
60
61
  # Initialize parameters
62
+ log(INFO, "[INIT]")
61
63
  default_init_params_workflow(driver, context)
62
64
 
63
65
  # Run federated learning for num_rounds
64
- log(INFO, "FL starting")
65
66
  start_time = timeit.default_timer()
66
67
  cfg = ConfigsRecord()
67
68
  cfg[Key.START_TIME] = start_time
68
69
  context.state.configs_records[MAIN_CONFIGS_RECORD] = cfg
69
70
 
70
71
  for current_round in range(1, context.config.num_rounds + 1):
72
+ log(INFO, "")
73
+ log(INFO, "[ROUND %s]", current_round)
71
74
  cfg[Key.CURRENT_ROUND] = current_round
72
75
 
73
76
  # Fit round
@@ -79,22 +82,19 @@ class DefaultWorkflow:
79
82
  # Evaluate round
80
83
  self.evaluate_workflow(driver, context)
81
84
 
82
- # Bookkeeping
85
+ # Bookkeeping and log results
83
86
  end_time = timeit.default_timer()
84
87
  elapsed = end_time - start_time
85
- log(INFO, "FL finished in %s", elapsed)
86
-
87
- # Log results
88
88
  hist = context.history
89
- log(INFO, "app_fit: losses_distributed %s", str(hist.losses_distributed))
90
- log(
91
- INFO,
92
- "app_fit: metrics_distributed_fit %s",
93
- str(hist.metrics_distributed_fit),
94
- )
95
- log(INFO, "app_fit: metrics_distributed %s", str(hist.metrics_distributed))
96
- log(INFO, "app_fit: losses_centralized %s", str(hist.losses_centralized))
97
- log(INFO, "app_fit: metrics_centralized %s", str(hist.metrics_centralized))
89
+ log(INFO, "")
90
+ log(INFO, "[SUMMARY]")
91
+ log(INFO, "Run finished %s rounds in %.2fs", context.config.num_rounds, elapsed)
92
+ for idx, line in enumerate(io.StringIO(str(hist))):
93
+ if idx == 0:
94
+ log(INFO, "%s", line.strip("\n"))
95
+ else:
96
+ log(INFO, "\t%s", line.strip("\n"))
97
+ log(INFO, "")
98
98
 
99
99
  # Terminate the thread
100
100
  f_stop.set()
@@ -107,12 +107,11 @@ def default_init_params_workflow(driver: Driver, context: Context) -> None:
107
107
  if not isinstance(context, LegacyContext):
108
108
  raise TypeError(f"Expect a LegacyContext, but get {type(context).__name__}.")
109
109
 
110
- log(INFO, "Initializing global parameters")
111
110
  parameters = context.strategy.initialize_parameters(
112
111
  client_manager=context.client_manager
113
112
  )
114
113
  if parameters is not None:
115
- log(INFO, "Using initial parameters provided by strategy")
114
+ log(INFO, "Using initial global parameters provided by strategy")
116
115
  paramsrecord = compat.parameters_to_parametersrecord(
117
116
  parameters, keep_input=True
118
117
  )
@@ -140,7 +139,7 @@ def default_init_params_workflow(driver: Driver, context: Context) -> None:
140
139
  context.state.parameters_records[MAIN_PARAMS_RECORD] = paramsrecord
141
140
 
142
141
  # Evaluate initial parameters
143
- log(INFO, "Evaluating initial parameters")
142
+ log(INFO, "Evaluating initial global parameters")
144
143
  parameters = compat.parametersrecord_to_parameters(paramsrecord, keep_input=True)
145
144
  res = context.strategy.evaluate(0, parameters=parameters)
146
145
  if res is not None:
@@ -186,7 +185,9 @@ def default_centralized_evaluation_workflow(_: Driver, context: Context) -> None
186
185
  )
187
186
 
188
187
 
189
- def default_fit_workflow(driver: Driver, context: Context) -> None:
188
+ def default_fit_workflow( # pylint: disable=R0914
189
+ driver: Driver, context: Context
190
+ ) -> None:
190
191
  """Execute the default workflow for a single fit round."""
191
192
  if not isinstance(context, LegacyContext):
192
193
  raise TypeError(f"Expect a LegacyContext, but get {type(context).__name__}.")
@@ -207,12 +208,11 @@ def default_fit_workflow(driver: Driver, context: Context) -> None:
207
208
  )
208
209
 
209
210
  if not client_instructions:
210
- log(INFO, "fit_round %s: no clients selected, cancel", current_round)
211
+ log(INFO, "configure_fit: no clients selected, cancel")
211
212
  return
212
213
  log(
213
- DEBUG,
214
- "fit_round %s: strategy sampled %s clients (out of %s)",
215
- current_round,
214
+ INFO,
215
+ "configure_fit: strategy sampled %s clients (out of %s)",
216
216
  len(client_instructions),
217
217
  context.client_manager.num_available(),
218
218
  )
@@ -236,14 +236,14 @@ def default_fit_workflow(driver: Driver, context: Context) -> None:
236
236
  # collect `fit` results from all clients participating in this round
237
237
  messages = list(driver.send_and_receive(out_messages))
238
238
  del out_messages
239
+ num_failures = len([msg for msg in messages if msg.has_error()])
239
240
 
240
241
  # No exception/failure handling currently
241
242
  log(
242
- DEBUG,
243
- "fit_round %s received %s results and %s failures",
244
- current_round,
245
- len(messages),
246
- 0,
243
+ INFO,
244
+ "aggregate_fit: received %s results and %s failures",
245
+ len(messages) - num_failures,
246
+ num_failures,
247
247
  )
248
248
 
249
249
  # Aggregate training results
@@ -288,12 +288,11 @@ def default_evaluate_workflow(driver: Driver, context: Context) -> None:
288
288
  client_manager=context.client_manager,
289
289
  )
290
290
  if not client_instructions:
291
- log(INFO, "evaluate_round %s: no clients selected, cancel", current_round)
291
+ log(INFO, "configure_evaluate: no clients selected, skipping evaluation")
292
292
  return
293
293
  log(
294
- DEBUG,
295
- "evaluate_round %s: strategy sampled %s clients (out of %s)",
296
- current_round,
294
+ INFO,
295
+ "configure_evaluate: strategy sampled %s clients (out of %s)",
297
296
  len(client_instructions),
298
297
  context.client_manager.num_available(),
299
298
  )
@@ -317,14 +316,14 @@ def default_evaluate_workflow(driver: Driver, context: Context) -> None:
317
316
  # collect `evaluate` results from all clients participating in this round
318
317
  messages = list(driver.send_and_receive(out_messages))
319
318
  del out_messages
319
+ num_failures = len([msg for msg in messages if msg.has_error()])
320
320
 
321
321
  # No exception/failure handling currently
322
322
  log(
323
- DEBUG,
324
- "evaluate_round %s received %s results and %s failures",
325
- current_round,
326
- len(messages),
327
- 0,
323
+ INFO,
324
+ "aggregate_evaluate: received %s results and %s failures",
325
+ len(messages) - num_failures,
326
+ num_failures,
328
327
  )
329
328
 
330
329
  # Aggregate the evaluation results
@@ -15,8 +15,10 @@
15
15
  """Secure Aggregation workflows."""
16
16
 
17
17
 
18
+ from .secagg_workflow import SecAggWorkflow
18
19
  from .secaggplus_workflow import SecAggPlusWorkflow
19
20
 
20
21
  __all__ = [
21
22
  "SecAggPlusWorkflow",
23
+ "SecAggWorkflow",
22
24
  ]