phyelds 2.2.0__tar.gz → 2.3.0__tar.gz
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.
- {phyelds-2.2.0 → phyelds-2.3.0}/PKG-INFO +3 -1
- {phyelds-2.2.0 → phyelds-2.3.0}/pyproject.toml +3 -2
- {phyelds-2.2.0 → phyelds-2.3.0}/src/phyelds/libraries/device.py +5 -5
- phyelds-2.3.0/src/phyelds/simulator/exporter.py +75 -0
- {phyelds-2.2.0 → phyelds-2.3.0}/src/phyelds/simulator/runner.py +2 -1
- {phyelds-2.2.0 → phyelds-2.3.0}/LICENSE +0 -0
- {phyelds-2.2.0 → phyelds-2.3.0}/README.md +0 -0
- {phyelds-2.2.0 → phyelds-2.3.0}/src/phyelds/__init__.py +0 -0
- {phyelds-2.2.0 → phyelds-2.3.0}/src/phyelds/abstractions/__init__.py +0 -0
- {phyelds-2.2.0 → phyelds-2.3.0}/src/phyelds/calculus/__init__.py +0 -0
- {phyelds-2.2.0 → phyelds-2.3.0}/src/phyelds/calculus/align.py +0 -0
- {phyelds-2.2.0 → phyelds-2.3.0}/src/phyelds/data/__init__.py +0 -0
- {phyelds-2.2.0 → phyelds-2.3.0}/src/phyelds/internal/__init__.py +0 -0
- {phyelds-2.2.0 → phyelds-2.3.0}/src/phyelds/libraries/__init__.py +0 -0
- {phyelds-2.2.0 → phyelds-2.3.0}/src/phyelds/libraries/collect.py +0 -0
- {phyelds-2.2.0 → phyelds-2.3.0}/src/phyelds/libraries/distances.py +0 -0
- {phyelds-2.2.0 → phyelds-2.3.0}/src/phyelds/libraries/leader_election.py +0 -0
- {phyelds-2.2.0 → phyelds-2.3.0}/src/phyelds/libraries/spreading.py +0 -0
- {phyelds-2.2.0 → phyelds-2.3.0}/src/phyelds/libraries/time.py +0 -0
- {phyelds-2.2.0 → phyelds-2.3.0}/src/phyelds/libraries/utils.py +0 -0
- {phyelds-2.2.0 → phyelds-2.3.0}/src/phyelds/simulator/__init__.py +0 -0
- {phyelds-2.2.0 → phyelds-2.3.0}/src/phyelds/simulator/actions.py +0 -0
- {phyelds-2.2.0 → phyelds-2.3.0}/src/phyelds/simulator/deployments.py +0 -0
- {phyelds-2.2.0 → phyelds-2.3.0}/src/phyelds/simulator/neighborhood.py +0 -0
- {phyelds-2.2.0 → phyelds-2.3.0}/src/phyelds/simulator/render.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: phyelds
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.3.0
|
|
4
4
|
Summary: A lightweight Python library to support aggregate computing!
|
|
5
5
|
Home-page: https://github.com/phyelds/phyelds
|
|
6
6
|
License: Apache-2.0
|
|
@@ -12,6 +12,8 @@ Classifier: Operating System :: OS Independent
|
|
|
12
12
|
Classifier: Programming Language :: Python :: 3
|
|
13
13
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
14
14
|
Requires-Dist: matplotlib (>=3.10.1,<3.11.0)
|
|
15
|
+
Requires-Dist: pandas (>=2.2.3,<3.0.0)
|
|
16
|
+
Requires-Dist: pre-commit (>=4.2.0,<5.0.0)
|
|
15
17
|
Requires-Dist: wrapt (>=1.17.2,<1.18.0)
|
|
16
18
|
Project-URL: Changelog, https://github.com/phyelds/phyelds/blob/master/CHANGELOG.md
|
|
17
19
|
Project-URL: Repository, https://github.com/phyelds/phyelds
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "phyelds"
|
|
3
|
-
version = "2.
|
|
3
|
+
version = "2.3.0"
|
|
4
4
|
description = "A lightweight Python library to support aggregate computing!"
|
|
5
5
|
license = "Apache-2.0"
|
|
6
6
|
authors = [
|
|
@@ -39,6 +39,8 @@ build-backend = "poetry.core.masonry.api"
|
|
|
39
39
|
python = "^3.13"
|
|
40
40
|
wrapt = ">=1.17.2,<1.18.0"
|
|
41
41
|
matplotlib = ">=3.10.1,<3.11.0"
|
|
42
|
+
pre-commit = "^4.2.0"
|
|
43
|
+
pandas = "^2.2.3"
|
|
42
44
|
|
|
43
45
|
[tool.poetry.group.dev.dependencies]
|
|
44
46
|
pytest = "^8.0.0"
|
|
@@ -46,4 +48,3 @@ pylint = "^3.0.0"
|
|
|
46
48
|
pytest-cov = "^3.0.0"
|
|
47
49
|
ruff = "^0.3.0"
|
|
48
50
|
flake8 = "^7.0.0"
|
|
49
|
-
|
|
@@ -30,11 +30,11 @@ def local_position():
|
|
|
30
30
|
return engine.get().node_context.position()
|
|
31
31
|
|
|
32
32
|
|
|
33
|
-
def store(
|
|
33
|
+
def store(output: str, value: any):
|
|
34
34
|
"""
|
|
35
|
-
Store the value
|
|
36
|
-
:param
|
|
37
|
-
:param value: The value
|
|
35
|
+
Store the value in the context.
|
|
36
|
+
:param output: The name of the stored value.
|
|
37
|
+
:param value: The value to be stored.
|
|
38
38
|
:return:
|
|
39
39
|
"""
|
|
40
|
-
engine.get().node_context.store(
|
|
40
|
+
engine.get().node_context.store(output, value)
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"""Exporter module for saving simulation metrics to CSV during simulation."""
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
import itertools
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
from dataclasses import dataclass, replace
|
|
7
|
+
import pandas as pd
|
|
8
|
+
from phyelds.simulator import Simulator
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
__all__ = ["csv_exporter", "ExporterConfig"]
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@dataclass
|
|
15
|
+
class ExporterConfig:
|
|
16
|
+
"""Configuration for CSV exporting of simulation metrics."""
|
|
17
|
+
output_directory: str
|
|
18
|
+
experiment_name: str
|
|
19
|
+
metrics: list[str]
|
|
20
|
+
aggregators: list[str]
|
|
21
|
+
precision: int
|
|
22
|
+
initial: bool = True
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def csv_exporter(
|
|
26
|
+
simulator: Simulator, time_delta: float, config: ExporterConfig, **kwargs
|
|
27
|
+
):
|
|
28
|
+
"""Exporter module for saving simulation metrics to CSV."""
|
|
29
|
+
file_path = f'{config.output_directory}{config.experiment_name}.csv'
|
|
30
|
+
if not os.path.exists(file_path) or config.initial:
|
|
31
|
+
Path(config.output_directory).mkdir(parents=True, exist_ok=True)
|
|
32
|
+
df = init_dataframe(config, file_path)
|
|
33
|
+
else:
|
|
34
|
+
df = pd.read_csv(file_path)
|
|
35
|
+
new_data = {}
|
|
36
|
+
nodes = simulator.environment.nodes.values()
|
|
37
|
+
for metric in config.metrics:
|
|
38
|
+
nodes_data = [node.data['outputs'][metric] for node in nodes]
|
|
39
|
+
for aggregator in config.aggregators:
|
|
40
|
+
column = f'{metric}_{aggregator}'
|
|
41
|
+
new_data[column] = aggregate_values(nodes_data, config.precision, aggregator)
|
|
42
|
+
print(new_data)
|
|
43
|
+
df = pd.concat([df, pd.DataFrame([new_data])], ignore_index=True)
|
|
44
|
+
df.to_csv(file_path, mode='w', index=False)
|
|
45
|
+
config = replace(config, initial=False)
|
|
46
|
+
simulator.schedule_event(
|
|
47
|
+
time_delta, csv_exporter, simulator, time_delta, config, **kwargs
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def aggregate_values(values: list[float], precision, aggregator: str):
|
|
52
|
+
"""Aggregates a list of values using the given method and rounds to the specified precision."""
|
|
53
|
+
if aggregator == "mean":
|
|
54
|
+
value = sum(values) / len(values)
|
|
55
|
+
elif aggregator == "std":
|
|
56
|
+
mean = sum(values) / len(values)
|
|
57
|
+
value = sum((v - mean) ** 2 for v in values) / len(values)
|
|
58
|
+
elif aggregator == "min":
|
|
59
|
+
value = min(values)
|
|
60
|
+
elif aggregator == "max":
|
|
61
|
+
value = max(values)
|
|
62
|
+
else:
|
|
63
|
+
raise ValueError(f"Invalid aggregator: {aggregator}")
|
|
64
|
+
return round(value, precision)
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def init_dataframe(config, file_path):
|
|
68
|
+
"""Initializes an empty DataFrame with appropriate columns based on config."""
|
|
69
|
+
columns = list(f'{s}_{a}' for s, a in itertools.product(config.metrics, config.aggregators))
|
|
70
|
+
print(columns)
|
|
71
|
+
try:
|
|
72
|
+
os.remove(file_path)
|
|
73
|
+
except OSError:
|
|
74
|
+
pass
|
|
75
|
+
return pd.DataFrame(columns=columns).astype('float64')
|
|
@@ -55,8 +55,9 @@ def aggregate_program_runner(
|
|
|
55
55
|
node.data["result"] = result
|
|
56
56
|
node.data["messages"] = engine.get().cooldown()
|
|
57
57
|
node.data["state"] = engine.get().state_trace()
|
|
58
|
+
node.data["outputs"] = engine.get().node_context.outputs
|
|
58
59
|
simulator.schedule_event(
|
|
59
|
-
time_delta, aggregate_program_runner, simulator, time_delta, node, program
|
|
60
|
+
time_delta, aggregate_program_runner, simulator, time_delta, node, program, **kwargs
|
|
60
61
|
)
|
|
61
62
|
|
|
62
63
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|