Unverified Commit b470b12c authored by Jakob Görgen's avatar Jakob Görgen
Browse files

added toJSON to simualtion module

parent facea554
...@@ -101,6 +101,30 @@ class Simulator(utils_base.IdObj): ...@@ -101,6 +101,30 @@ class Simulator(utils_base.IdObj):
def wait_terminate(self, wait: bool): def wait_terminate(self, wait: bool):
self._wait = wait self._wait = wait
def toJSON(self) -> dict:
json_obj = super().toJSON()
json_obj["type"] = self.__class__.__name__
json_obj["module"] = self.__class__.__module__
json_obj["name"] = self.name
json_obj["executable"] = self._executable
json_obj["simulation"] = self._simulation.id()
components_json = []
for comp in self._components:
components_json.append(comp.id())
json_obj["components"] = components_json
json_obj["wait"] = self._wait
json_obj["start_tick"] = self._start_tick
if self._extra_args:
json_obj["extra_args"] = self._extra_args
return json_obj
@staticmethod
def fromJSON(json_obj):
# TODO: FIXME
pass
@staticmethod @staticmethod
def filter_sockets( def filter_sockets(
sockets: list[inst_base.Socket], sockets: list[inst_base.Socket],
...@@ -292,12 +316,54 @@ class Simulation(utils_base.IdObj): ...@@ -292,12 +316,54 @@ class Simulation(utils_base.IdObj):
self._sys_sim_map: dict[sys_conf.Component, Simulator] = {} self._sys_sim_map: dict[sys_conf.Component, Simulator] = {}
"""System component and its simulator pairs""" """System component and its simulator pairs"""
self._sim_list: list[Simulator] = []
"""Channel spec and its instanciation"""
self._chan_map: dict[sys_conf.Channel, sim_chan.Channel] = {} self._chan_map: dict[sys_conf.Channel, sim_chan.Channel] = {}
"""Channel spec and its instanciation""" """Channel spec and its instanciation"""
self._sim_list: list[Simulator] = [] def toJSON(self) -> dict:
"""Channel spec and its instanciation""" json_obj = super().toJSON()
json_obj["type"] = self.__class__.__name__
json_obj["module"] = self.__class__.__module__
json_obj["name"] = self.name
json_obj["system"] = self.system.id()
if self.timeout:
json_obj["timeout"] = self.timeout
simulators_json = []
for sim in self._sim_list:
utils_base.has_attribute(sim, "toJSON")
simulators_json.append(sim.toJSON())
json_obj["sim_list"] = simulators_json
sys_sim_map_json = []
for comp, sim in self._sys_sim_map.items():
sys_sim_map_json.append({comp.id(): sim.id()})
json_obj["sys_sim_map"] = sys_sim_map_json
chan_map_json = []
chan_json = []
for (
sys_chan,
sim_chan,
) in self._chan_map.items():
chan_map_json.append({sys_chan.id(): sim_chan.id()})
utils_base.has_attribute(sim_chan, "toJSON")
chan_json.append(sim_chan.toJSON())
json_obj["chan_map"] = chan_map_json
json_obj["simulation_channels"] = chan_json
return json_obj
@staticmethod
def fromJSON(json_obj):
# TODO: FIXME
pass
def add_sim(self, sim: Simulator): def add_sim(self, sim: Simulator):
if sim in self._sim_list: if sim in self._sim_list:
......
...@@ -34,13 +34,26 @@ class Time(enum.IntEnum): ...@@ -34,13 +34,26 @@ class Time(enum.IntEnum):
Seconds = 10 ** (9) Seconds = 10 ** (9)
class Channel: class Channel(utils_base.IdObj):
def __init__(self, chan: system_base.Channel): def __init__(self, chan: system_base.Channel):
super().__init__()
self._synchronized: bool = False self._synchronized: bool = False
self.sync_period: int = 500 # nano seconds self.sync_period: int = 500 # nano seconds
self.sys_channel: system_base.Channel = chan self.sys_channel: system_base.Channel = chan
def toJSON(self):
json_obj = super().toJSON()
json_obj["synchronized"] = self._synchronized
json_obj["sync_period"] = self.sync_period
json_obj["sys_channel"] = self.sys_channel.id()
return json_obj
@staticmethod
def fromJSON(json_obj):
# TODO
pass
def full_name(self) -> str: def full_name(self) -> str:
return "channel." + self.name return "channel." + self.name
......
...@@ -82,6 +82,21 @@ class Gem5Sim(HostSim): ...@@ -82,6 +82,21 @@ class Gem5Sim(HostSim):
def supported_image_formats(self) -> list[str]: def supported_image_formats(self) -> list[str]:
return ["raw"] return ["raw"]
def toJSON(self) -> dict:
json_obj = super().toJSON()
json_obj["cpu_type_cp"] = self.cpu_type_cp
json_obj["cpu_type"] = self.cpu_type
json_obj["extra_main_args"] = self.extra_main_args
json_obj["extra_config_args"] = self.extra_config_args
json_obj["_variant"] = self._variant
json_obj["_sys_clock"] = self._sys_clock
return json_obj
@staticmethod
def fromJSON(json_obj):
# TODO: FIXME
pass
async def prepare(self, inst: inst_base.Instantiation) -> None: async def prepare(self, inst: inst_base.Instantiation) -> None:
await super().prepare(inst=inst) await super().prepare(inst=inst)
...@@ -217,6 +232,16 @@ class QemuSim(HostSim): ...@@ -217,6 +232,16 @@ class QemuSim(HostSim):
def supported_image_formats(self) -> list[str]: def supported_image_formats(self) -> list[str]:
return ["raw", "qcow"] return ["raw", "qcow"]
def toJSON(self) -> dict:
json_obj = super().toJSON()
# disks is created upon invocation of "prepare", hence we do not need to serialize it
return json_obj
@staticmethod
def fromJSON(json_obj):
# TODO: FIXME
pass
async def prepare(self, inst: inst_base.Instantiation) -> None: async def prepare(self, inst: inst_base.Instantiation) -> None:
await super().prepare(inst=inst) await super().prepare(inst=inst)
......
...@@ -49,6 +49,16 @@ class NetSim(sim_base.Simulator): ...@@ -49,6 +49,16 @@ class NetSim(sim_base.Simulator):
) -> set[inst_base.SockType]: ) -> set[inst_base.SockType]:
return [inst_base.SockType.CONNECT] return [inst_base.SockType.CONNECT]
def toJSON(self) -> dict:
json_obj = super().toJSON()
# TODO: FIXME
return json_obj
@staticmethod
def fromJSON(json_obj):
# TODO: FIXME
pass
class WireNet(NetSim): class WireNet(NetSim):
...@@ -70,6 +80,16 @@ class WireNet(NetSim): ...@@ -70,6 +80,16 @@ class WireNet(NetSim):
) )
super().add(wire) super().add(wire)
def toJSON(self) -> dict:
json_obj = super().toJSON()
json_obj["relative_pcap_file_path"] = self._relative_pcap_file_path
return json_obj
@staticmethod
def fromJSON(json_obj):
# TODO: FIXME
pass
def run_cmd(self, inst: inst_base.Instantiation) -> str: def run_cmd(self, inst: inst_base.Instantiation) -> str:
channels = self.get_channels() channels = self.get_channels()
eth_latency, sync_period, run_sync = ( eth_latency, sync_period, run_sync = (
...@@ -111,6 +131,16 @@ class SwitchNet(NetSim): ...@@ -111,6 +131,16 @@ class SwitchNet(NetSim):
raise Exception("can only add a single switch component to the SwitchNet") raise Exception("can only add a single switch component to the SwitchNet")
super().add(switch_spec) super().add(switch_spec)
def toJSON(self) -> dict:
json_obj = super().toJSON()
json_obj["relative_pcap_file_path"] = self._relative_pcap_file_path
return json_obj
@staticmethod
def fromJSON(json_obj):
# TODO: FIXME
pass
def run_cmd(self, inst: inst_base.Instantiation) -> str: def run_cmd(self, inst: inst_base.Instantiation) -> str:
channels = self.get_channels() channels = self.get_channels()
eth_latency, sync_period, run_sync = ( eth_latency, sync_period, run_sync = (
...@@ -155,6 +185,15 @@ class MemSwitchNet(SwitchNet): ...@@ -155,6 +185,15 @@ class MemSwitchNet(SwitchNet):
"""AS_ID,VADDR_START,VADDR_END,MEMNODE_MAC,PHYS_START.""" """AS_ID,VADDR_START,VADDR_END,MEMNODE_MAC,PHYS_START."""
self.mem_map = [] self.mem_map = []
def toJSON(self) -> dict:
json_obj = super().toJSON()
return json_obj
@staticmethod
def fromJSON(json_obj):
# TODO: FIXME
pass
def run_cmd(self, inst: inst_base.Instantiation) -> str: def run_cmd(self, inst: inst_base.Instantiation) -> str:
cmd = super().run_cmd(inst) cmd = super().run_cmd(inst)
...@@ -182,6 +221,18 @@ class SimpleNS3Sim(NetSim): ...@@ -182,6 +221,18 @@ class SimpleNS3Sim(NetSim):
self._ns3_run_script: str = ns3_run_script self._ns3_run_script: str = ns3_run_script
self.opt: str | None = None self.opt: str | None = None
def toJSON(self) -> dict:
json_obj = super().toJSON()
json_obj["ns3_run_script"] = self._ns3_run_script
if self.opt:
json_obj["opt"] = self.opt
return json_obj
@staticmethod
def fromJSON(json_obj):
# TODO: FIXME
pass
def run_cmd(self, inst: inst_base.Instantiation) -> str: def run_cmd(self, inst: inst_base.Instantiation) -> str:
return f"{inst.join_repo_base(self._executable)} {self._ns3_run_script} " return f"{inst.join_repo_base(self._executable)} {self._ns3_run_script} "
...@@ -213,6 +264,17 @@ class NS3DumbbellNet(SimpleNS3Sim): ...@@ -213,6 +264,17 @@ class NS3DumbbellNet(SimpleNS3Sim):
self._left = left self._left = left
self._right = right self._right = right
def toJSON(self) -> dict:
json_obj = super().toJSON()
json_obj["left"] = self._left.id()
json_obj["right"] = self._right.id()
return json_obj
@staticmethod
def fromJSON(json_obj):
# TODO: FIXME
pass
def run_cmd(self, inst: inst_base.Instantiation) -> str: def run_cmd(self, inst: inst_base.Instantiation) -> str:
cmd = super().run_cmd(inst=inst) cmd = super().run_cmd(inst=inst)
...@@ -247,6 +309,15 @@ class NS3BridgeNet(SimpleNS3Sim): ...@@ -247,6 +309,15 @@ class NS3BridgeNet(SimpleNS3Sim):
raise Exception("NS3BridgeNet can only simulate one switch/bridge") raise Exception("NS3BridgeNet can only simulate one switch/bridge")
super().add(comp=switch_comp) super().add(comp=switch_comp)
def toJSON(self) -> dict:
json_obj = super().toJSON()
return json_obj
@staticmethod
def fromJSON(json_obj):
# TODO: FIXME
pass
def run_cmd(self, inst: inst_base.Instantiation) -> str: def run_cmd(self, inst: inst_base.Instantiation) -> str:
cmd = super().run_cmd(inst=inst) cmd = super().run_cmd(inst=inst)
......
...@@ -50,14 +50,14 @@ class PCIDevSim(sim_base.Simulator): ...@@ -50,14 +50,14 @@ class PCIDevSim(sim_base.Simulator):
class NICSim(PCIDevSim): class NICSim(PCIDevSim):
"""Base class for NIC simulators.""" """Base class for NIC simulators."""
def full_name(self) -> str:
return "nic." + self.name
def __init__( def __init__(
self, simulation: sim_base.Simulation, executable: str, name: str = "" self, simulation: sim_base.Simulation, executable: str, name: str = ""
) -> None: ) -> None:
super().__init__(simulation=simulation, executable=executable, name=name) super().__init__(simulation=simulation, executable=executable, name=name)
def full_name(self) -> str:
return "nic." + self.name
def add(self, nic: sys_nic.SimplePCIeNIC): def add(self, nic: sys_nic.SimplePCIeNIC):
assert len(self._components) < 1 assert len(self._components) < 1
super().add(nic) super().add(nic)
...@@ -105,6 +105,15 @@ class I40eNicSim(NICSim): ...@@ -105,6 +105,15 @@ class I40eNicSim(NICSim):
) )
self.name = f"NICSim-{self._id}" self.name = f"NICSim-{self._id}"
def toJSON(self) -> dict:
json_obj = super().toJSON()
return json_obj
@staticmethod
def fromJSON(json_obj):
# TODO: FIXME
pass
def run_cmd(self, inst: inst_base.Instantiation) -> str: def run_cmd(self, inst: inst_base.Instantiation) -> str:
return super().run_cmd(inst=inst) return super().run_cmd(inst=inst)
...@@ -117,6 +126,15 @@ class CorundumBMNICSim(NICSim): ...@@ -117,6 +126,15 @@ class CorundumBMNICSim(NICSim):
) )
self.name = f"CorundumBMNICSim-{self._id}" self.name = f"CorundumBMNICSim-{self._id}"
def toJSON(self) -> dict:
json_obj = super().toJSON()
return json_obj
@staticmethod
def fromJSON(json_obj):
# TODO: FIXME
pass
def run_cmd(self, inst: inst_base.Instantiation) -> str: def run_cmd(self, inst: inst_base.Instantiation) -> str:
cmd = super().run_cmd(inst=inst) cmd = super().run_cmd(inst=inst)
return cmd return cmd
...@@ -136,6 +154,16 @@ class CorundumVerilatorNICSim(NICSim): ...@@ -136,6 +154,16 @@ class CorundumVerilatorNICSim(NICSim):
# this is a guess # this is a guess
return 512 return 512
def toJSON(self) -> dict:
json_obj = super().toJSON()
json_obj["clock_freq"] = self.clock_freq
return json_obj
@staticmethod
def fromJSON(json_obj):
# TODO: FIXME
pass
def run_cmd(self, inst: inst_base.Instantiation) -> str: def run_cmd(self, inst: inst_base.Instantiation) -> str:
cmd = super().run_cmd(inst=inst) cmd = super().run_cmd(inst=inst)
cmd += f" {self.clock_freq}" cmd += f" {self.clock_freq}"
......
...@@ -29,6 +29,7 @@ from simbricks.orchestration.utils import base as util_base ...@@ -29,6 +29,7 @@ from simbricks.orchestration.utils import base as util_base
if tp.TYPE_CHECKING: if tp.TYPE_CHECKING:
from simbricks.orchestration.instantiation import base as inst_base from simbricks.orchestration.instantiation import base as inst_base
class System(util_base.IdObj): class System(util_base.IdObj):
"""Defines System configuration of the whole simulation""" """Defines System configuration of the whole simulation"""
...@@ -46,12 +47,24 @@ class System(util_base.IdObj): ...@@ -46,12 +47,24 @@ class System(util_base.IdObj):
json_obj["module"] = self.__class__.__module__ json_obj["module"] = self.__class__.__module__
components_json = [] components_json = []
channels: set[Channel] = set()
for comp in self.all_component: for comp in self.all_component:
util_base.has_attribute(comp, 'toJSON') util_base.has_attribute(comp, "toJSON")
comp_json = comp.toJSON() comp_json = comp.toJSON()
components_json.append(comp_json) components_json.append(comp_json)
for inf in comp.interfaces():
channels.add(inf.channel)
json_obj["all_component"] = components_json json_obj["all_component"] = components_json
channels_json = []
for chan in channels:
util_base.has_attribute(chan, "toJSON")
channels_json.append(chan.toJSON())
json_obj["channels"] = channels_json
return json_obj return json_obj
@staticmethod @staticmethod
...@@ -92,7 +105,7 @@ class Component(util_base.IdObj): ...@@ -92,7 +105,7 @@ class Component(util_base.IdObj):
interfaces_json = [] interfaces_json = []
for inf in self.interfaces(): for inf in self.interfaces():
util_base.has_attribute(inf, 'toJSON') util_base.has_attribute(inf, "toJSON")
interfaces_json.append(inf.toJSON()) interfaces_json.append(inf.toJSON())
json_obj["interfaces"] = interfaces_json json_obj["interfaces"] = interfaces_json
......
# Copyright 2024 Max Planck Institute for Software Systems, and
# National University of Singapore
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
import json
from simbricks.orchestration.utils import base as util_base
from simbricks.orchestration.system import base as sys_base
def toJSON(system: sys_base.System) -> dict:
json_obj = {}
util_base.has_attribute(system, "toJSON")
json_obj["system"] = system.toJSON()
channels: set[sys_base.Channel] = set()
for comp in system.all_component:
for inf in comp.interfaces():
channels.add(inf.channel)
channels_json = []
for chan in channels:
util_base.has_attribute(chan, "toJSON")
channels_json.append(chan.toJSON())
json_obj["channels"] = channels_json
return json.dumps({"specification": json_obj})
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment