From bedf9b2ef3c5781d7b38ab5feff34d0640238a16 Mon Sep 17 00:00:00 2001 From: Youngjoon Lee <5462944+youngjoon-lee@users.noreply.github.com> Date: Tue, 13 Aug 2024 01:26:57 +0900 Subject: [PATCH] store topology to csv file --- mixnet/queuesim/queuesim.py | 14 ++++++++++---- mixnet/queuesim/simulation.py | 16 +++++++++++----- mixnet/sim/topology.py | 2 -- 3 files changed, 21 insertions(+), 11 deletions(-) diff --git a/mixnet/queuesim/queuesim.py b/mixnet/queuesim/queuesim.py index 3272d91..945ab28 100644 --- a/mixnet/queuesim/queuesim.py +++ b/mixnet/queuesim/queuesim.py @@ -209,15 +209,20 @@ def _submit_iterations( # Submit the iteration to the executor out_csv_path = f"{outdir}/__WIP__iteration_{i}.csv" err_path = f"{outdir}/iteration_{i}.err" - future = executor.submit(_run_iteration, iter_cfg, out_csv_path, err_path) + topology_path = f"{outdir}/iteration_{i}_topology.csv" + future = executor.submit( + _run_iteration, iter_cfg, out_csv_path, err_path, topology_path + ) future_map[future] = IterationInfo( - paramset_id, paramset, i, out_csv_path, err_path + paramset_id, paramset, i, out_csv_path, err_path, topology_path ) return future_map -def _run_iteration(cfg: Config, out_csv_path: str, err_path: str) -> tuple[bool, float]: +def _run_iteration( + cfg: Config, out_csv_path: str, err_path: str, topology_path: str +) -> tuple[bool, float]: """ Run a single iteration of a certain parameter set. The iteration uses the independent uSim instance. @@ -226,7 +231,7 @@ def _run_iteration(cfg: Config, out_csv_path: str, err_path: str) -> tuple[bool, start_time = time.time() try: sim = Simulation(cfg) - usim.run(sim.run(out_csv_path)) + usim.run(sim.run(out_csv_path, topology_path)) return True, time.time() - start_time except BaseException as e: with open(err_path, "w") as f: @@ -241,3 +246,4 @@ class IterationInfo: iteration_idx: int out_csv_path: str err_path: str + topology_path: str diff --git a/mixnet/queuesim/simulation.py b/mixnet/queuesim/simulation.py index 43229a0..9fdf6c9 100644 --- a/mixnet/queuesim/simulation.py +++ b/mixnet/queuesim/simulation.py @@ -3,6 +3,7 @@ import struct from dataclasses import dataclass from typing import Counter, Self +import pandas as pd import usim from framework.framework import Queue @@ -22,19 +23,19 @@ class Simulation: def __init__(self, config: Config): self.config = config - async def run(self, out_csv_path: str): + async def run(self, out_csv_path: str, topology_path: str): async with usim.Scope() as scope: self.framework = Framework(scope) self.message_builder = MessageBuilder(self.framework) - await self.__run(out_csv_path) + await self.__run(out_csv_path, topology_path) self.framework.stop_tasks() - async def __run(self, out_csv_path: str): + async def __run(self, out_csv_path: str, topology_path: str): self.received_msg_queue: Queue[tuple[float, bytes]] = self.framework.queue() # Run and connect nodes nodes = self.__run_nodes() - self.__connect_nodes(nodes) + self.__connect_nodes(nodes, topology_path) # Choose and start senders senders = self.config.sender_generator.sample(nodes, k=self.config.num_senders) @@ -83,12 +84,17 @@ class Simulation: # The received time is also included in the notification. await self.received_msg_queue.put((self.framework.now(), msg)) - def __connect_nodes(self, nodes: list[Node]): + def __connect_nodes(self, nodes: list[Node], topology_path: str): topology = build_full_random_topology( rng=self.config.topology.seed, num_nodes=len(nodes), peering_degree=self.config.nomssip.peering_degree, ) + # Store the topology to a CSV file for later analysis + pd.DataFrame( + [(node, len(peers), list(peers)) for node, peers in topology.items()], + columns=pd.Series(["node", "num_peers", "peers"]), + ).to_csv(topology_path, index=False) # Sort the topology by node index for the connection RULE defined below. for node_idx, peer_indices in sorted(topology.items()): for peer_idx in peer_indices: diff --git a/mixnet/sim/topology.py b/mixnet/sim/topology.py index b6167f2..9364f9d 100644 --- a/mixnet/sim/topology.py +++ b/mixnet/sim/topology.py @@ -3,8 +3,6 @@ from __future__ import annotations import random from collections import defaultdict -from protocol.node import Node - Topology = dict[int, set[int]]