diff --git a/src/server/offloading_algo/offloading_algo.py b/src/server/offloading_algo/offloading_algo.py index c62bb38..d2ebcfc 100644 --- a/src/server/offloading_algo/offloading_algo.py +++ b/src/server/offloading_algo/offloading_algo.py @@ -1,3 +1,4 @@ +import itertools import json import logging from pathlib import Path @@ -149,8 +150,6 @@ def mixed_computation_evaluation(self): # ── OPTIMIZATION: Use prefix sums to avoid recomputing sum() per layer ── # This reduces the inner loop from O(N²) to O(N). - import itertools - device_prefix = list(itertools.accumulate(self.inference_time_device)) edge_prefix = list(itertools.accumulate(self.inference_time_edge)) total_edge = edge_prefix[self.num_layers - 1] if self.num_layers > 0 else 0 @@ -190,7 +189,10 @@ def device_only_evaluation(self): if _DEBUG_ENABLED: logger.debug("Performing Device Only Offloading") initial_cost = sum(self.inference_time_device[: self.num_layers]) - layer_data_size = self.layers_sizes[self.num_layers - 1] + # A fully local inference never transmits intermediate layer data + # over the network, so no network cost applies here (unlike the + # split strategies, which do send data to the edge). + layer_data_size = 0 edge_computation_cost = 0 # No Offloading: Device Only Computation @@ -204,7 +206,7 @@ def device_only_evaluation(self): strategy="device_only", layer=self.num_layers - 1, device_compute_cost=initial_cost, - network_cost=layer_data_size / (self.avg_speed or 1), + network_cost=0, edge_compute_cost=edge_computation_cost, estimated_total_cost=last_evaluation, considered_for_selection=True, diff --git a/tests/test_offloading_algo/test_offloading_algo.py b/tests/test_offloading_algo/test_offloading_algo.py index 0d1d7a4..3139c31 100644 --- a/tests/test_offloading_algo/test_offloading_algo.py +++ b/tests/test_offloading_algo/test_offloading_algo.py @@ -41,5 +41,28 @@ def test_offloading_fixture_falls_back_when_sample_file_is_missing(): assert _load_sample_values("test_samples/missing.json", [1.0, 2.0]) == [1.0, 2.0] +def test_device_only_evaluation_has_no_network_cost(): + # A fully local (device-only) inference never transmits intermediate + # layer data over the network, so it must not incur a network cost. + offloading_algo = OffloadingAlgo( + avg_speed=10.0, + num_layers=3, + layers_sizes=[100, 200, 300], + inference_time_device=[1.0, 1.0, 1.0], + inference_time_edge=[1.0, 1.0, 1.0], + ) + offloading_algo.device_only_evaluation() + + device_only_candidate = next( + c + for c in offloading_algo.candidate_evaluations + if c["strategy"] == "device_only" + ) + assert device_only_candidate["network_cost"] == 0 + assert device_only_candidate["estimated_total_cost"] == sum( + [1.0, 1.0, 1.0] + ) + + if __name__ == "__main__": pytest.main()