From 03d7957cf5190ae99bf5cbf92e7a9307a7532c14 Mon Sep 17 00:00:00 2001 From: jafermarq Date: Mon, 16 Dec 2024 14:31:35 +0000 Subject: [PATCH 01/15] init --- src/py/flwr/common/telemetry.py | 4 ++++ src/py/flwr/simulation/app.py | 12 ++++++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/py/flwr/common/telemetry.py b/src/py/flwr/common/telemetry.py index 9f6a51901f54..2018dd0a0455 100644 --- a/src/py/flwr/common/telemetry.py +++ b/src/py/flwr/common/telemetry.py @@ -157,6 +157,10 @@ def _generate_next_value_(name: str, start: int, count: int, last_values: list[A CLI_FLOWER_SIMULATION_ENTER = auto() CLI_FLOWER_SIMULATION_LEAVE = auto() + # CLI: flwr-simulation + RUN_SIMULATION_ENTER = auto() + RUN_SIMULATION_LEAVE = auto() + # Python API: `run_simulation` PYTHON_API_RUN_SIMULATION_ENTER = auto() PYTHON_API_RUN_SIMULATION_LEAVE = auto() diff --git a/src/py/flwr/simulation/app.py b/src/py/flwr/simulation/app.py index ebcb275b6052..25460fcf5643 100644 --- a/src/py/flwr/simulation/app.py +++ b/src/py/flwr/simulation/app.py @@ -24,7 +24,7 @@ from flwr.cli.config_utils import get_fab_metadata from flwr.cli.install import install_from_fab -from flwr.common import EventType +from flwr.common import EventType, event from flwr.common.args import add_args_flwr_app_common from flwr.common.config import ( get_flwr_dir, @@ -201,6 +201,14 @@ def run_simulation_process( # pylint: disable=R0914, disable=W0212, disable=R09 verbose: bool = fed_opt.get("verbose", False) enable_tf_gpu_growth: bool = fed_opt.get("enable_tf_gpu_growth", False) + event( + EventType.RUN_SIMULATION_ENTER, + event_details={ + "backend": "ray", + "num-supernodes": num_supernodes, + }, + ) + # Launch the simulation _run_simulation( server_app_attr=server_app_attr, @@ -213,7 +221,7 @@ def run_simulation_process( # pylint: disable=R0914, disable=W0212, disable=R09 verbose_logging=verbose, server_app_run_config=fused_config, is_app=True, - exit_event=EventType.CLI_FLOWER_SIMULATION_LEAVE, + exit_event=EventType.RUN_SIMULATION_LEAVE, ) # Send resulting context From 63447c94965ad92f28adcea667e52b7881a0754f Mon Sep 17 00:00:00 2001 From: "Daniel J. Beutel" Date: Thu, 19 Dec 2024 13:20:17 +0100 Subject: [PATCH 02/15] Move deprecated events to deprecated section --- src/py/flwr/common/telemetry.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/py/flwr/common/telemetry.py b/src/py/flwr/common/telemetry.py index 2018dd0a0455..64ba776e9654 100644 --- a/src/py/flwr/common/telemetry.py +++ b/src/py/flwr/common/telemetry.py @@ -175,12 +175,12 @@ def _generate_next_value_(name: str, start: int, count: int, last_values: list[A RUN_SUPERNODE_ENTER = auto() RUN_SUPERNODE_LEAVE = auto() + # --- DEPRECATED ------------------------------------------------------------------- + # CLI: `flower-server-app` RUN_SERVER_APP_ENTER = auto() RUN_SERVER_APP_LEAVE = auto() - # --- DEPRECATED ------------------------------------------------------------------- - # [DEPRECATED] CLI: `flower-client-app` RUN_CLIENT_APP_ENTER = auto() RUN_CLIENT_APP_LEAVE = auto() From f3696ad0a9124d9da0906728d38098c6450caa6b Mon Sep 17 00:00:00 2001 From: "Daniel J. Beutel" Date: Thu, 19 Dec 2024 13:40:49 +0100 Subject: [PATCH 03/15] Align deprectated CLI entrypoints --- src/py/flwr/client/supernode/app.py | 3 +-- src/py/flwr/server/run_serverapp.py | 14 +++++++------- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/py/flwr/client/supernode/app.py b/src/py/flwr/client/supernode/app.py index 0aad227695b9..c7dad2dfd426 100644 --- a/src/py/flwr/client/supernode/app.py +++ b/src/py/flwr/client/supernode/app.py @@ -114,9 +114,8 @@ def run_client_app() -> None: event(EventType.RUN_CLIENT_APP_ENTER) log( ERROR, - "The command `flower-client-app` has been replaced by `flower-supernode`.", + "The command `flower-client-app` has been replaced by `flwr run`.", ) - log(INFO, "Execute `flower-supernode --help` to learn how to use it.") register_exit_handlers(event_type=EventType.RUN_CLIENT_APP_LEAVE) diff --git a/src/py/flwr/server/run_serverapp.py b/src/py/flwr/server/run_serverapp.py index 23d4102e77dd..f0bd1e6301e3 100644 --- a/src/py/flwr/server/run_serverapp.py +++ b/src/py/flwr/server/run_serverapp.py @@ -19,7 +19,8 @@ from logging import DEBUG, ERROR from typing import Optional -from flwr.common import Context +from flwr.common import Context, EventType, event +from flwr.common.exit_handlers import register_exit_handlers from flwr.common.logger import log, warn_unsupported_feature from flwr.common.object_ref import load_app @@ -66,12 +67,11 @@ def _load() -> ServerApp: return context -# pylint: disable-next=too-many-branches,too-many-statements,too-many-locals def run_server_app() -> None: """Run Flower server app.""" - warn_unsupported_feature( - "The command `flower-server-app` is deprecated and no longer in use. " - "Use the `flwr-serverapp` exclusively instead." + event(EventType.RUN_SERVER_APP_ENTER) + log( + ERROR, + "The command `flower-server-app` has been replaced by `flwr run`.", ) - log(ERROR, "`flower-server-app` used.") - sys.exit() + register_exit_handlers(event_type=EventType.RUN_SERVER_APP_LEAVE) From 5394a8ecd40f1649a08ac6f46cd1a7889b7ea7dd Mon Sep 17 00:00:00 2001 From: "Daniel J. Beutel" Date: Thu, 19 Dec 2024 13:41:55 +0100 Subject: [PATCH 04/15] Update comment --- src/py/flwr/common/telemetry.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/py/flwr/common/telemetry.py b/src/py/flwr/common/telemetry.py index 64ba776e9654..851e2432cf7e 100644 --- a/src/py/flwr/common/telemetry.py +++ b/src/py/flwr/common/telemetry.py @@ -177,7 +177,7 @@ def _generate_next_value_(name: str, start: int, count: int, last_values: list[A # --- DEPRECATED ------------------------------------------------------------------- - # CLI: `flower-server-app` + # [DEPRECATED] CLI: `flower-server-app` RUN_SERVER_APP_ENTER = auto() RUN_SERVER_APP_LEAVE = auto() From 7898c33611aa2e6601205a278c6eb1eea5d4dc1d Mon Sep 17 00:00:00 2001 From: Chong Shen Ng Date: Thu, 19 Dec 2024 13:14:24 +0000 Subject: [PATCH 05/15] Add serverapp events --- src/py/flwr/cli/utils.py | 19 +++++++++++-------- src/py/flwr/common/telemetry.py | 4 ++++ src/py/flwr/server/serverapp/app.py | 15 +++++++++++++-- src/py/flwr/simulation/app.py | 4 ++++ src/py/flwr/simulation/run_simulation.py | 6 +++++- 5 files changed, 37 insertions(+), 11 deletions(-) diff --git a/src/py/flwr/cli/utils.py b/src/py/flwr/cli/utils.py index 9968895ef73b..e7148f7f285d 100644 --- a/src/py/flwr/cli/utils.py +++ b/src/py/flwr/cli/utils.py @@ -22,7 +22,7 @@ from contextlib import contextmanager from logging import DEBUG from pathlib import Path -from typing import Any, Callable, Optional, cast +from typing import Any, Callable, Optional, Union, cast import grpc import typer @@ -148,15 +148,18 @@ def sanitize_project_name(name: str) -> str: return sanitized_name -def get_sha256_hash(file_path: Path) -> str: +def get_sha256_hash(file_path_or_int: Union[Path | int]) -> str: """Calculate the SHA-256 hash of a file.""" sha256 = hashlib.sha256() - with open(file_path, "rb") as f: - while True: - data = f.read(65536) # Read in 64kB blocks - if not data: - break - sha256.update(data) + if isinstance(file_path_or_int, Path): + with open(file_path_or_int, "rb") as f: + while True: + data = f.read(65536) # Read in 64kB blocks + if not data: + break + sha256.update(data) + elif isinstance(file_path_or_int, int): + sha256.update(str(file_path_or_int).encode()) return sha256.hexdigest() diff --git a/src/py/flwr/common/telemetry.py b/src/py/flwr/common/telemetry.py index 851e2432cf7e..b39e63e35bc7 100644 --- a/src/py/flwr/common/telemetry.py +++ b/src/py/flwr/common/telemetry.py @@ -175,6 +175,10 @@ def _generate_next_value_(name: str, start: int, count: int, last_values: list[A RUN_SUPERNODE_ENTER = auto() RUN_SUPERNODE_LEAVE = auto() + # CLI: flwr-serverapp + RUN_SERVERAPP_ENTER = auto() + RUN_SERVERAPP_LEAVE = auto() + # --- DEPRECATED ------------------------------------------------------------------- # [DEPRECATED] CLI: `flower-server-app` diff --git a/src/py/flwr/server/serverapp/app.py b/src/py/flwr/server/serverapp/app.py index 8fbfec00272d..3b97e8d64d1d 100644 --- a/src/py/flwr/server/serverapp/app.py +++ b/src/py/flwr/server/serverapp/app.py @@ -25,6 +25,7 @@ from flwr.cli.config_utils import get_fab_metadata from flwr.cli.install import install_from_fab +from flwr.cli.utils import get_sha256_hash from flwr.common.args import add_args_flwr_app_common from flwr.common.config import ( get_flwr_dir, @@ -51,6 +52,7 @@ run_from_proto, run_status_to_proto, ) +from flwr.common.telemetry import EventType, event from flwr.common.typing import RunNotRunningException, RunStatus from flwr.proto.run_pb2 import UpdateRunStatusRequest # pylint: disable=E0611 from flwr.proto.serverappio_pb2 import ( # pylint: disable=E0611 @@ -113,7 +115,7 @@ def run_serverapp( # pylint: disable=R0914, disable=W0212, disable=R0915 # Resolve directory where FABs are installed flwr_dir_ = get_flwr_dir(flwr_dir) log_uploader = None - + success = True while True: try: @@ -129,6 +131,8 @@ def run_serverapp( # pylint: disable=R0914, disable=W0212, disable=R0915 run = run_from_proto(res.run) fab = fab_from_proto(res.fab) + hash_run_id = get_sha256_hash(run.run_id) + driver.set_run(run.run_id) # Start log uploader for this run @@ -171,6 +175,8 @@ def run_serverapp( # pylint: disable=R0914, disable=W0212, disable=R0915 UpdateRunStatusRequest(run_id=run.run_id, run_status=run_status_proto) ) + event(EventType.RUN_SERVERAPP_ENTER, event_details={"run-id": hash_run_id}) + # Load and run the ServerApp with the Driver updated_context = run_( driver=driver, @@ -187,17 +193,18 @@ def run_serverapp( # pylint: disable=R0914, disable=W0212, disable=R0915 _ = driver._stub.PushServerAppOutputs(out_req) run_status = RunStatus(Status.FINISHED, SubStatus.COMPLETED, "") - except RunNotRunningException: log(INFO, "") log(INFO, "Run ID %s stopped.", run.run_id) log(INFO, "") run_status = None + success = False except Exception as ex: # pylint: disable=broad-exception-caught exc_entity = "ServerApp" log(ERROR, "%s raised an exception", exc_entity, exc_info=ex) run_status = RunStatus(Status.FINISHED, SubStatus.FAILED, str(ex)) + success = False finally: # Stop log uploader for this run and upload final logs @@ -213,6 +220,10 @@ def run_serverapp( # pylint: disable=R0914, disable=W0212, disable=R0915 run_id=run.run_id, run_status=run_status_proto ) ) + event( + EventType.RUN_SERVERAPP_LEAVE, + event_details={"run-id": hash_run_id, "success": success}, + ) # Stop the loop if `flwr-serverapp` is expected to process a single run if run_once: diff --git a/src/py/flwr/simulation/app.py b/src/py/flwr/simulation/app.py index a594903f9fab..710343221f6d 100644 --- a/src/py/flwr/simulation/app.py +++ b/src/py/flwr/simulation/app.py @@ -24,6 +24,7 @@ from flwr.cli.config_utils import get_fab_metadata from flwr.cli.install import install_from_fab +from flwr.cli.utils import get_sha256_hash from flwr.common import EventType, event from flwr.common.args import add_args_flwr_app_common from flwr.common.config import ( @@ -137,6 +138,8 @@ def run_simulation_process( # pylint: disable=R0914, disable=W0212, disable=R09 run = run_from_proto(res.run) fab = fab_from_proto(res.fab) + hash_run_id = get_sha256_hash(run.run_id) + # Start log uploader for this run log_uploader = start_log_uploader( log_queue=log_queue, @@ -207,6 +210,7 @@ def run_simulation_process( # pylint: disable=R0914, disable=W0212, disable=R09 event_details={ "backend": "ray", "num-supernodes": num_supernodes, + "run-id": hash_run_id, }, ) diff --git a/src/py/flwr/simulation/run_simulation.py b/src/py/flwr/simulation/run_simulation.py index cc8844405b0b..629f5fde5ac3 100644 --- a/src/py/flwr/simulation/run_simulation.py +++ b/src/py/flwr/simulation/run_simulation.py @@ -28,6 +28,7 @@ from typing import Any, Optional from flwr.cli.config_utils import load_and_validate +from flwr.cli.utils import get_sha256_hash from flwr.client import ClientApp from flwr.common import Context, EventType, RecordSet, event, log, now from flwr.common.config import get_fused_config_from_dir, parse_config_args @@ -394,7 +395,10 @@ def _main_loop( finally: # Trigger stop event f_stop.set() - event(exit_event, event_details={"success": success}) + event( + exit_event, + event_details={"run-id": get_sha256_hash(run.run_id), "success": success}, + ) if serverapp_th: serverapp_th.join() if server_app_thread_has_exception.is_set(): From 78b318f8269bf19bce3fc8dbfe6c739ac0cdf6b9 Mon Sep 17 00:00:00 2001 From: Chong Shen Ng Date: Thu, 19 Dec 2024 14:02:29 +0000 Subject: [PATCH 06/15] Comma --- src/py/flwr/cli/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/py/flwr/cli/utils.py b/src/py/flwr/cli/utils.py index e7148f7f285d..e01a0439c9da 100644 --- a/src/py/flwr/cli/utils.py +++ b/src/py/flwr/cli/utils.py @@ -148,7 +148,7 @@ def sanitize_project_name(name: str) -> str: return sanitized_name -def get_sha256_hash(file_path_or_int: Union[Path | int]) -> str: +def get_sha256_hash(file_path_or_int: Union[Path, int]) -> str: """Calculate the SHA-256 hash of a file.""" sha256 = hashlib.sha256() if isinstance(file_path_or_int, Path): From f372de7a531242b108c8f01979c833f8e0a4052e Mon Sep 17 00:00:00 2001 From: Chong Shen Ng Date: Thu, 19 Dec 2024 14:17:03 +0000 Subject: [PATCH 07/15] Extend get_sha256 and add test --- src/py/flwr/cli/utils.py | 19 +++--- src/py/flwr/cli/utils_test.py | 109 ++++++++++++++++++++++++++++++++++ 2 files changed, 120 insertions(+), 8 deletions(-) create mode 100644 src/py/flwr/cli/utils_test.py diff --git a/src/py/flwr/cli/utils.py b/src/py/flwr/cli/utils.py index 9968895ef73b..e01a0439c9da 100644 --- a/src/py/flwr/cli/utils.py +++ b/src/py/flwr/cli/utils.py @@ -22,7 +22,7 @@ from contextlib import contextmanager from logging import DEBUG from pathlib import Path -from typing import Any, Callable, Optional, cast +from typing import Any, Callable, Optional, Union, cast import grpc import typer @@ -148,15 +148,18 @@ def sanitize_project_name(name: str) -> str: return sanitized_name -def get_sha256_hash(file_path: Path) -> str: +def get_sha256_hash(file_path_or_int: Union[Path, int]) -> str: """Calculate the SHA-256 hash of a file.""" sha256 = hashlib.sha256() - with open(file_path, "rb") as f: - while True: - data = f.read(65536) # Read in 64kB blocks - if not data: - break - sha256.update(data) + if isinstance(file_path_or_int, Path): + with open(file_path_or_int, "rb") as f: + while True: + data = f.read(65536) # Read in 64kB blocks + if not data: + break + sha256.update(data) + elif isinstance(file_path_or_int, int): + sha256.update(str(file_path_or_int).encode()) return sha256.hexdigest() diff --git a/src/py/flwr/cli/utils_test.py b/src/py/flwr/cli/utils_test.py new file mode 100644 index 000000000000..e722dee70c3c --- /dev/null +++ b/src/py/flwr/cli/utils_test.py @@ -0,0 +1,109 @@ +# Copyright 2024 Flower Labs GmbH. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Test for Flower command line interface utils.""" + + +import hashlib +import os +import tempfile +import unittest +from pathlib import Path + +from flwr.cli.utils import get_sha256_hash + + +class TestGetSHA256Hash(unittest.TestCase): + """Unit tests for `get_sha256_hash` function.""" + + def test_hash_with_integer(self) -> None: + """Test the SHA-256 hash calculation when input is an integer.""" + # Prepare + test_int = 13413 + expected_hash = hashlib.sha256(str(test_int).encode()).hexdigest() + + # Execute + result = get_sha256_hash(test_int) + + # Assert + self.assertEqual(result, expected_hash) + + def test_hash_with_file(self) -> None: + """Test the SHA-256 hash calculation when input is a file path.""" + # Prepare - Create a temporary file with known content + with tempfile.NamedTemporaryFile(delete=False) as temp_file: + temp_file.write(b"Test content for SHA-256 hashing.") + temp_file_path = Path(temp_file.name) + + try: + # Execute + sha256 = hashlib.sha256() + with open(temp_file_path, "rb") as f: + while True: + data = f.read(65536) + if not data: + break + sha256.update(data) + expected_hash = sha256.hexdigest() + + result = get_sha256_hash(temp_file_path) + + # Assert + self.assertEqual(result, expected_hash) + finally: + # Clean up the temporary file + os.remove(temp_file_path) + + def test_empty_file(self) -> None: + """Test the SHA-256 hash calculation for an empty file.""" + # Prepare + with tempfile.NamedTemporaryFile(delete=False) as temp_file: + temp_file_path = Path(temp_file.name) + + try: + # Execute + expected_hash = hashlib.sha256(b"").hexdigest() + result = get_sha256_hash(temp_file_path) + + # Assert + self.assertEqual(result, expected_hash) + finally: + os.remove(temp_file_path) + + def test_large_file(self) -> None: + """Test the SHA-256 hash calculation for a large file.""" + # Prepare - Generate large data (e.g., 10 MB) + large_data = b"a" * (10 * 1024 * 1024) # 10 MB of 'a's + with tempfile.NamedTemporaryFile(delete=False) as temp_file: + temp_file.write(large_data) + temp_file_path = Path(temp_file.name) + + try: + expected_hash = hashlib.sha256(large_data).hexdigest() + # Execute + result = get_sha256_hash(temp_file_path) + + # Assert + self.assertEqual(result, expected_hash) + finally: + os.remove(temp_file_path) + + def test_nonexistent_file(self) -> None: + """Test the SHA-256 hash calculation when the file does not exist.""" + # Prepare + nonexistent_path = Path("/path/to/nonexistent/file.txt") + + # Execute & assert + with self.assertRaises(FileNotFoundError): + get_sha256_hash(nonexistent_path) From 465a59d6d1b6da7994e7c2a87b948d36842c8d66 Mon Sep 17 00:00:00 2001 From: Chong Shen Ng Date: Thu, 19 Dec 2024 14:27:43 +0000 Subject: [PATCH 08/15] Removed unused imports --- src/py/flwr/server/run_serverapp.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/py/flwr/server/run_serverapp.py b/src/py/flwr/server/run_serverapp.py index f0bd1e6301e3..49660c5ff077 100644 --- a/src/py/flwr/server/run_serverapp.py +++ b/src/py/flwr/server/run_serverapp.py @@ -15,13 +15,12 @@ """Run ServerApp.""" -import sys from logging import DEBUG, ERROR from typing import Optional from flwr.common import Context, EventType, event from flwr.common.exit_handlers import register_exit_handlers -from flwr.common.logger import log, warn_unsupported_feature +from flwr.common.logger import log from flwr.common.object_ref import load_app from .driver import Driver From 6836d5fa15a18a52a555ef1fcffadfd9bae5c5a2 Mon Sep 17 00:00:00 2001 From: "Daniel J. Beutel" Date: Fri, 20 Dec 2024 10:26:50 +0100 Subject: [PATCH 09/15] Create new section --- src/py/flwr/common/telemetry.py | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/py/flwr/common/telemetry.py b/src/py/flwr/common/telemetry.py index b39e63e35bc7..8894e8218fd9 100644 --- a/src/py/flwr/common/telemetry.py +++ b/src/py/flwr/common/telemetry.py @@ -151,16 +151,22 @@ def _generate_next_value_(name: str, start: int, count: int, last_values: list[A # Not yet implemented + # --- `flwr-*` commands ------------------------------------------------------------ + + # CLI: flwr-simulation + RUN_SIMULATION_ENTER = auto() + RUN_SIMULATION_LEAVE = auto() + + # CLI: flwr-serverapp + RUN_SERVERAPP_ENTER = auto() + RUN_SERVERAPP_LEAVE = auto() + # --- Simulation Engine ------------------------------------------------------------ # CLI: flower-simulation CLI_FLOWER_SIMULATION_ENTER = auto() CLI_FLOWER_SIMULATION_LEAVE = auto() - # CLI: flwr-simulation - RUN_SIMULATION_ENTER = auto() - RUN_SIMULATION_LEAVE = auto() - # Python API: `run_simulation` PYTHON_API_RUN_SIMULATION_ENTER = auto() PYTHON_API_RUN_SIMULATION_LEAVE = auto() @@ -175,10 +181,6 @@ def _generate_next_value_(name: str, start: int, count: int, last_values: list[A RUN_SUPERNODE_ENTER = auto() RUN_SUPERNODE_LEAVE = auto() - # CLI: flwr-serverapp - RUN_SERVERAPP_ENTER = auto() - RUN_SERVERAPP_LEAVE = auto() - # --- DEPRECATED ------------------------------------------------------------------- # [DEPRECATED] CLI: `flower-server-app` From f4d9720d1bcf75bf8c78aebf1ba00bee68b3d3f1 Mon Sep 17 00:00:00 2001 From: "Daniel J. Beutel" Date: Fri, 20 Dec 2024 10:31:03 +0100 Subject: [PATCH 10/15] Rename events --- src/py/flwr/common/telemetry.py | 8 ++++---- src/py/flwr/server/serverapp/app.py | 4 ++-- src/py/flwr/simulation/app.py | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/py/flwr/common/telemetry.py b/src/py/flwr/common/telemetry.py index 8894e8218fd9..3c7a6ecdf483 100644 --- a/src/py/flwr/common/telemetry.py +++ b/src/py/flwr/common/telemetry.py @@ -154,12 +154,12 @@ def _generate_next_value_(name: str, start: int, count: int, last_values: list[A # --- `flwr-*` commands ------------------------------------------------------------ # CLI: flwr-simulation - RUN_SIMULATION_ENTER = auto() - RUN_SIMULATION_LEAVE = auto() + FLWR_SIMULATION_ENTER = auto() + FLWR_SIMULATION_LEAVE = auto() # CLI: flwr-serverapp - RUN_SERVERAPP_ENTER = auto() - RUN_SERVERAPP_LEAVE = auto() + FLWR_SERVERAPP_ENTER = auto() + FLWR_SERVERAPP_LEAVE = auto() # --- Simulation Engine ------------------------------------------------------------ diff --git a/src/py/flwr/server/serverapp/app.py b/src/py/flwr/server/serverapp/app.py index 3b97e8d64d1d..aff51ebd2736 100644 --- a/src/py/flwr/server/serverapp/app.py +++ b/src/py/flwr/server/serverapp/app.py @@ -175,7 +175,7 @@ def run_serverapp( # pylint: disable=R0914, disable=W0212, disable=R0915 UpdateRunStatusRequest(run_id=run.run_id, run_status=run_status_proto) ) - event(EventType.RUN_SERVERAPP_ENTER, event_details={"run-id": hash_run_id}) + event(EventType.FLWR_SERVERAPP_ENTER, event_details={"run-id": hash_run_id}) # Load and run the ServerApp with the Driver updated_context = run_( @@ -221,7 +221,7 @@ def run_serverapp( # pylint: disable=R0914, disable=W0212, disable=R0915 ) ) event( - EventType.RUN_SERVERAPP_LEAVE, + EventType.FLWR_SERVERAPP_LEAVE, event_details={"run-id": hash_run_id, "success": success}, ) diff --git a/src/py/flwr/simulation/app.py b/src/py/flwr/simulation/app.py index 710343221f6d..dc8555c8a8ef 100644 --- a/src/py/flwr/simulation/app.py +++ b/src/py/flwr/simulation/app.py @@ -206,7 +206,7 @@ def run_simulation_process( # pylint: disable=R0914, disable=W0212, disable=R09 enable_tf_gpu_growth: bool = fed_opt.get("enable_tf_gpu_growth", False) event( - EventType.RUN_SIMULATION_ENTER, + EventType.FLWR_SIMULATION_ENTER, event_details={ "backend": "ray", "num-supernodes": num_supernodes, @@ -226,7 +226,7 @@ def run_simulation_process( # pylint: disable=R0914, disable=W0212, disable=R09 verbose_logging=verbose, server_app_run_config=fused_config, is_app=True, - exit_event=EventType.RUN_SIMULATION_LEAVE, + exit_event=EventType.FLWR_SIMULATION_LEAVE, ) # Send resulting context From f327c01424893a9dd642ed5786fecc2528d9d633 Mon Sep 17 00:00:00 2001 From: "Daniel J. Beutel" Date: Fri, 20 Dec 2024 10:33:57 +0100 Subject: [PATCH 11/15] Update src/py/flwr/simulation/app.py --- src/py/flwr/simulation/app.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/py/flwr/simulation/app.py b/src/py/flwr/simulation/app.py index dc8555c8a8ef..74e0390d88e4 100644 --- a/src/py/flwr/simulation/app.py +++ b/src/py/flwr/simulation/app.py @@ -210,7 +210,7 @@ def run_simulation_process( # pylint: disable=R0914, disable=W0212, disable=R09 event_details={ "backend": "ray", "num-supernodes": num_supernodes, - "run-id": hash_run_id, + "run-id-hash": hash_run_id, }, ) From 944a95aaf52f67955ef10db5b23ea2dbdcaedad2 Mon Sep 17 00:00:00 2001 From: "Daniel J. Beutel" Date: Fri, 20 Dec 2024 10:34:06 +0100 Subject: [PATCH 12/15] Update src/py/flwr/simulation/run_simulation.py --- src/py/flwr/simulation/run_simulation.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/py/flwr/simulation/run_simulation.py b/src/py/flwr/simulation/run_simulation.py index 629f5fde5ac3..aa837f9a64c3 100644 --- a/src/py/flwr/simulation/run_simulation.py +++ b/src/py/flwr/simulation/run_simulation.py @@ -397,7 +397,7 @@ def _main_loop( f_stop.set() event( exit_event, - event_details={"run-id": get_sha256_hash(run.run_id), "success": success}, + event_details={"run-id-hash": get_sha256_hash(run.run_id), "success": success}, ) if serverapp_th: serverapp_th.join() From 23ce4ae81af9817424a565ef5d6a9e478003e585 Mon Sep 17 00:00:00 2001 From: "Daniel J. Beutel" Date: Fri, 20 Dec 2024 10:38:49 +0100 Subject: [PATCH 13/15] Refactor --- src/py/flwr/simulation/app.py | 4 +--- src/py/flwr/simulation/run_simulation.py | 5 ++++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/py/flwr/simulation/app.py b/src/py/flwr/simulation/app.py index 74e0390d88e4..55782b48581e 100644 --- a/src/py/flwr/simulation/app.py +++ b/src/py/flwr/simulation/app.py @@ -138,8 +138,6 @@ def run_simulation_process( # pylint: disable=R0914, disable=W0212, disable=R09 run = run_from_proto(res.run) fab = fab_from_proto(res.fab) - hash_run_id = get_sha256_hash(run.run_id) - # Start log uploader for this run log_uploader = start_log_uploader( log_queue=log_queue, @@ -210,7 +208,7 @@ def run_simulation_process( # pylint: disable=R0914, disable=W0212, disable=R09 event_details={ "backend": "ray", "num-supernodes": num_supernodes, - "run-id-hash": hash_run_id, + "run-id-hash": get_sha256_hash(run.run_id), }, ) diff --git a/src/py/flwr/simulation/run_simulation.py b/src/py/flwr/simulation/run_simulation.py index aa837f9a64c3..1c53ff2a93e9 100644 --- a/src/py/flwr/simulation/run_simulation.py +++ b/src/py/flwr/simulation/run_simulation.py @@ -397,7 +397,10 @@ def _main_loop( f_stop.set() event( exit_event, - event_details={"run-id-hash": get_sha256_hash(run.run_id), "success": success}, + event_details={ + "run-id-hash": get_sha256_hash(run.run_id), + "success": success, + }, ) if serverapp_th: serverapp_th.join() From f17fb9539b073449b7ebb76799f0cddf2510438e Mon Sep 17 00:00:00 2001 From: "Daniel J. Beutel" Date: Fri, 20 Dec 2024 11:13:46 +0100 Subject: [PATCH 14/15] Rename key --- src/py/flwr/server/serverapp/app.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/py/flwr/server/serverapp/app.py b/src/py/flwr/server/serverapp/app.py index aff51ebd2736..3f0217dc0042 100644 --- a/src/py/flwr/server/serverapp/app.py +++ b/src/py/flwr/server/serverapp/app.py @@ -175,7 +175,10 @@ def run_serverapp( # pylint: disable=R0914, disable=W0212, disable=R0915 UpdateRunStatusRequest(run_id=run.run_id, run_status=run_status_proto) ) - event(EventType.FLWR_SERVERAPP_ENTER, event_details={"run-id": hash_run_id}) + event( + EventType.FLWR_SERVERAPP_ENTER, + event_details={"run-id-hash": hash_run_id}, + ) # Load and run the ServerApp with the Driver updated_context = run_( @@ -222,7 +225,7 @@ def run_serverapp( # pylint: disable=R0914, disable=W0212, disable=R0915 ) event( EventType.FLWR_SERVERAPP_LEAVE, - event_details={"run-id": hash_run_id, "success": success}, + event_details={"run-id-hash": hash_run_id, "success": success}, ) # Stop the loop if `flwr-serverapp` is expected to process a single run From cd504c9ae96f0b1c0525964514492f0808ae72ae Mon Sep 17 00:00:00 2001 From: "Daniel J. Beutel" Date: Fri, 20 Dec 2024 11:17:47 +0100 Subject: [PATCH 15/15] Rename events --- src/py/flwr/common/telemetry.py | 8 ++++---- src/py/flwr/server/serverapp/app.py | 4 ++-- src/py/flwr/simulation/app.py | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/py/flwr/common/telemetry.py b/src/py/flwr/common/telemetry.py index 3c7a6ecdf483..53c32d64ce5f 100644 --- a/src/py/flwr/common/telemetry.py +++ b/src/py/flwr/common/telemetry.py @@ -154,12 +154,12 @@ def _generate_next_value_(name: str, start: int, count: int, last_values: list[A # --- `flwr-*` commands ------------------------------------------------------------ # CLI: flwr-simulation - FLWR_SIMULATION_ENTER = auto() - FLWR_SIMULATION_LEAVE = auto() + FLWR_SIMULATION_RUN_ENTER = auto() + FLWR_SIMULATION_RUN_LEAVE = auto() # CLI: flwr-serverapp - FLWR_SERVERAPP_ENTER = auto() - FLWR_SERVERAPP_LEAVE = auto() + FLWR_SERVERAPP_RUN_ENTER = auto() + FLWR_SERVERAPP_RUN_LEAVE = auto() # --- Simulation Engine ------------------------------------------------------------ diff --git a/src/py/flwr/server/serverapp/app.py b/src/py/flwr/server/serverapp/app.py index 3f0217dc0042..70b0308da2b0 100644 --- a/src/py/flwr/server/serverapp/app.py +++ b/src/py/flwr/server/serverapp/app.py @@ -176,7 +176,7 @@ def run_serverapp( # pylint: disable=R0914, disable=W0212, disable=R0915 ) event( - EventType.FLWR_SERVERAPP_ENTER, + EventType.FLWR_SERVERAPP_RUN_ENTER, event_details={"run-id-hash": hash_run_id}, ) @@ -224,7 +224,7 @@ def run_serverapp( # pylint: disable=R0914, disable=W0212, disable=R0915 ) ) event( - EventType.FLWR_SERVERAPP_LEAVE, + EventType.FLWR_SERVERAPP_RUN_LEAVE, event_details={"run-id-hash": hash_run_id, "success": success}, ) diff --git a/src/py/flwr/simulation/app.py b/src/py/flwr/simulation/app.py index 55782b48581e..a60b9a5e9150 100644 --- a/src/py/flwr/simulation/app.py +++ b/src/py/flwr/simulation/app.py @@ -204,7 +204,7 @@ def run_simulation_process( # pylint: disable=R0914, disable=W0212, disable=R09 enable_tf_gpu_growth: bool = fed_opt.get("enable_tf_gpu_growth", False) event( - EventType.FLWR_SIMULATION_ENTER, + EventType.FLWR_SIMULATION_RUN_ENTER, event_details={ "backend": "ray", "num-supernodes": num_supernodes, @@ -224,7 +224,7 @@ def run_simulation_process( # pylint: disable=R0914, disable=W0212, disable=R09 verbose_logging=verbose, server_app_run_config=fused_config, is_app=True, - exit_event=EventType.FLWR_SIMULATION_LEAVE, + exit_event=EventType.FLWR_SIMULATION_RUN_LEAVE, ) # Send resulting context