"...composable_kernel.git" did not exist on "ccd26cbda240e61c60bad7c1f926cb0a60436fad"
Unverified Commit 26511db0 authored by Jakob Görgen's avatar Jakob Görgen
Browse files

added logic for creating socket paths

parent bdea721b
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
from simbricks.orchestration import simulation from simbricks.orchestration import simulation
from simbricks.orchestration import system
import enum import enum
import pathlib import pathlib
...@@ -44,11 +45,13 @@ class InstantiationEnvironment: ...@@ -44,11 +45,13 @@ class InstantiationEnvironment:
repo_path: str = pathlib.Path(__file__).parents[3].resolve(), repo_path: str = pathlib.Path(__file__).parents[3].resolve(),
workdir: str = pathlib.Path(), workdir: str = pathlib.Path(),
cpdir: str = pathlib.Path(), cpdir: str = pathlib.Path(),
shm_base: str = pathlib.Path(),
): ):
# TODO: add more parameters that wont change during instantiation # TODO: add more parameters that wont change during instantiation
self._repodir: str = pathlib.Path(repo_path).absolute() self._repodir: str = pathlib.Path(repo_path).absolute()
self._workdir: str = pathlib.Path(workdir).absolute() self._workdir: str = pathlib.Path(workdir).absolute()
self._cpdir: str = pathlib.Path(cpdir).absolute() self._cpdir: str = pathlib.Path(cpdir).absolute()
self._shm_base = pathlib.Path(workdir).joinpath(shm_base).absolute()
class Instantiation: class Instantiation:
...@@ -60,23 +63,70 @@ class Instantiation: ...@@ -60,23 +63,70 @@ class Instantiation:
self._env: InstantiationEnvironment = env self._env: InstantiationEnvironment = env
self._socket_tracker: set[tuple[simulation.channel.Channel, SockType]] = set() self._socket_tracker: set[tuple[simulation.channel.Channel, SockType]] = set()
def get_socket_path(self, chan: simulation.channel.Channel) -> Socket: @staticmethod
def is_absolute_exists(path: str) -> bool:
path = pathlib.Path(path)
return path.is_absolute() and path.is_file()
# def dev_pci_path(self, sim) -> str:
# return f"{self.workdir}/dev.pci.{sim.name}"
#
# def dev_mem_path(self, sim: "simulators.Simulator") -> str:
# return f"{self.workdir}/dev.mem.{sim.name}"
#
# def nic_eth_path(self, sim: "simulators.Simulator") -> str:
# return f"{self.workdir}/nic.eth.{sim.name}"
#
# def dev_shm_path(self, sim: "simulators.Simulator") -> str:
# return f"{self.shm_base}/dev.shm.{sim.name}"
#
# def n2n_eth_path(
# self, sim_l: "simulators.Simulator", sim_c: "simulators.Simulator", suffix=""
# ) -> str:
# return f"{self.workdir}/n2n.eth.{sim_l.name}.{sim_c.name}.{suffix}"
#
# def net2host_eth_path(self, sim_n, sim_h) -> str:
# return f"{self.workdir}/n2h.eth.{sim_n.name}.{sim_h.name}"
#
# def net2host_shm_path(
# self, sim_n: "simulators.Simulator", sim_h: "simulators.Simulator"
# ) -> str:
# return f"{self.workdir}/n2h.shm.{sim_n.name}.{sim_h.name}"
#
# def proxy_shm_path(self, sim: "simulators.Simulator") -> str:
# return f"{self.shm_base}/proxy.shm.{sim.name}"
def _interface_to_sock_path(self, interface: system.base.Interface) -> str:
basepath = pathlib.Path(self._env._workdir)
match interface:
case PCIeHostInterface() | PCIeDeviceInterface():
return f"{self._env._shm_base}/shm.pci/{interface.component.name}.{interface._id}"
case MemDeviceInterface() | MemHostInterface():
return f"{self._env._shm_base}/shm.mem/{interface.component.name}.{interface._id}"
case EthInterface():
return f"{self._env._shm_base}/shm.eth/{interface.component.name}.{interface._id}"
case _:
raise Exception("cannot create socket path for given interface type")
def get_socket(self, interface: system.base.Interface) -> Socket:
# TODO: use self._socket_tracker to determine socket type that is needed # TODO: use self._socket_tracker to determine socket type that is needed
sock_type = SockType.LISTEN sock_type = SockType.LISTEN
# TODO: generate socket path # TODO: generate socket path
sock_path = "" sock_path = self._interface_to_sock_path(interface=interface)
return Socket(sock_path, sock_type) return Socket(sock_path, sock_type)
@staticmethod
def is_absolute_exists(path: str) -> bool:
path = pathlib.Path(path)
return path.is_absolute() and path.is_file()
# TODO: add more methods constructing paths as required by methods in simulators or image handling classes # TODO: add more methods constructing paths as required by methods in simulators or image handling classes
def join_repo_base(self, relative_path: str) -> str:
path = pathlib.Path(self._env._repodir)
path.joinpath(relative_path)
if not path.exists():
raise Exception(f"couldn't join {self._env._repodir} and {relative_path}")
return path.absolute()
def hd_path(self, hd_name_or_path: str) -> str: def hd_path(self, hd_name_or_path: str) -> str:
if Instantiation.is_absolute_exists(hd_name_or_path): if Instantiation.is_absolute_exists(hd_name_or_path):
return hd_name_or_path return hd_name_or_path
......
...@@ -37,6 +37,26 @@ class Simulator(abc.ABC): ...@@ -37,6 +37,26 @@ class Simulator(abc.ABC):
self.experiment = e self.experiment = e
self._components: set[sys_base.Component] = [] self._components: set[sys_base.Component] = []
@staticmethod
def filter_sockets(
sockets: list[inst_base.Socket],
filter_type: inst_base.SockType = inst_base.SockType.LISTEN,
) -> list[inst_base.Socket]:
res = filter(lambda sock: sock._type == filter_type, sockets)
return res
@staticmethod
def split_sockets_by_type(
sockets: list[inst_base.Socket],
) -> tuple[sockets : list[inst_base.Socket], sockets : list[inst_base.Socket]]:
listen = Simulator.filter_sockets(
sockets=sockets, filter_type=inst_base.SockType.LISTEN
)
connect = Simulator.filter_sockets(
sockets=sockets, filter_type=inst_base.SockType.CONNECT
)
return listen, connect
def resreq_cores(self) -> int: def resreq_cores(self) -> int:
""" """
Number of cores this simulator requires during execution. Number of cores this simulator requires during execution.
...@@ -64,6 +84,8 @@ class Simulator(abc.ABC): ...@@ -64,6 +84,8 @@ class Simulator(abc.ABC):
# TODO: call this in subclasses # TODO: call this in subclasses
def _add_component(self, comp: sys_base.Channel) -> None: def _add_component(self, comp: sys_base.Channel) -> None:
if comp in self._components:
raise Exception("cannot add the same specification twice to a simulator")
self._components.add(comp) self._components.add(comp)
def _chan_needs_instance(self, chan: sys_base.Channel) -> bool: def _chan_needs_instance(self, chan: sys_base.Channel) -> bool:
...@@ -74,13 +96,35 @@ class Simulator(abc.ABC): ...@@ -74,13 +96,35 @@ class Simulator(abc.ABC):
return False return False
return True return True
def _get_sock_path( def _get_my_interface(self, chan: sys_base.Channel) -> sys_base.Interface:
interface = None
for inter in chan.interfaces():
if inter.component in self._components:
assert interface is None
interface = inter
if interface is None:
raise Exception(
"unable to find channel interface for simulators specification"
)
return interface
def _get_socket_and_chan(
self, inst: inst_base.Instantiation, chan: sys_base.Channel self, inst: inst_base.Instantiation, chan: sys_base.Channel
) -> tuple[sim_chan.Channel, inst_base.Socket] | tuple[None, None]: ) -> tuple[sim_chan.Channel, inst_base.Socket] | tuple[None, None]:
# check if this channel is simulator internal, i.e. doesn't need a shared memory queue
if not self._chan_needs_instance(chan): if not self._chan_needs_instance(chan):
return None, None return None, None
# create channel simualtion object
channel = self.experiment.retrieve_or_create_channel(chan) channel = self.experiment.retrieve_or_create_channel(chan)
return channel, inst.get_socket_path(channel)
# create the socket to listen on or connect to
my_interface = self._get_my_interface(chan)
socket = inst.get_socket(my_interface)
return (channel, socket)
# pylint: disable=unused-argument # pylint: disable=unused-argument
@abc.abstractmethod @abc.abstractmethod
......
...@@ -22,7 +22,6 @@ ...@@ -22,7 +22,6 @@
import abc import abc
import sys import sys
from
from simbricks.orchestration import experiments from simbricks.orchestration import experiments
from simbricks.orchestration.simulation import base from simbricks.orchestration.simulation import base
from simbricks.orchestration.system import eth from simbricks.orchestration.system import eth
...@@ -52,7 +51,7 @@ class NetSim(base.Simulator): ...@@ -52,7 +51,7 @@ class NetSim(base.Simulator):
# TODO # TODO
def sockets_cleanup(self, env: exp_env.ExpEnv) -> list[str]: def sockets_cleanup(self, env: exp_env.ExpEnv) -> list[str]:
pass pass
# TODO # TODO
def sockets_wait(self, env: exp_env.ExpEnv) -> list[str]: def sockets_wait(self, env: exp_env.ExpEnv) -> list[str]:
pass pass
...@@ -93,10 +92,10 @@ class SwitchNet(NetSim): ...@@ -93,10 +92,10 @@ class SwitchNet(NetSim):
run_sync = False run_sync = False
sockets: list[inst_base.Socket] = [] sockets: list[inst_base.Socket] = []
for chan in self._switch_spec.channels(): for chan in self._switch_spec.channels():
channel, socket = self._get_sock_path(inst=inst, chan=chan) channel, socket = self._get_socket_and_chan(inst=inst, chan=chan)
if channel is None or socket is None: if channel is None or socket is None:
continue continue
sync_period = min(sync_period, channel.sync_period) sync_period = min(sync_period, channel.sync_period)
run_sync = run_sync or channel._synchronized run_sync = run_sync or channel._synchronized
sock_paths.append(socket) sock_paths.append(socket)
...@@ -104,25 +103,23 @@ class SwitchNet(NetSim): ...@@ -104,25 +103,23 @@ class SwitchNet(NetSim):
assert sync_period is not None assert sync_period is not None
assert eth_latency is not None assert eth_latency is not None
cmd = env.repodir + "/sims/net/switch/net_switch" cmd = inst.join_repo_base("/sims/net/switch/net_switch")
cmd += f" -S {sync_period} -E {eth_latency}" cmd += f" -S {sync_period} -E {eth_latency}"
if not run_sync: if not run_sync:
cmd += " -u" cmd += " -u"
# TODO: pcap_file --> no env!!!
if len(env.pcap_file) > 0: if len(env.pcap_file) > 0:
cmd += " -p " + env.pcap_file cmd += " -p " + env.pcap_file
connect = '' listen, connect = base.Simulator.split_sockets_by_type(sockets)
listen = ''
for sock in sockets: for sock in connect:
if sock._type == inst_base.SockType.LISTEN: cmd += " -s " + sock._path
listen += " -h " + sock._path
else:
connect += " -s " + sock._path
cmd += connect for sock in listen:
cmd += listen cmd += " -h " + sock._path
return cmd return cmd
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
import abc import abc
import itertools
class System: class System:
...@@ -33,11 +34,20 @@ class System: ...@@ -33,11 +34,20 @@ class System:
assert c.system == self assert c.system == self
class Component(abc.ABC): class IdObj(abc.ABC):
__id_iter = itertools.count()
def __init__(self):
self._id = next(self.__id_iter)
class Component(IdObj):
def __init__(self, s: System) -> None: def __init__(self, s: System) -> None:
s.system = s s.system = s
s.parameters = {} s.parameters = {}
s.add_component(self) s.add_component(self)
self.name: str = ""
@abc.abstractmethod @abc.abstractmethod
def interfaces(self) -> list[Interface]: def interfaces(self) -> list[Interface]:
...@@ -47,7 +57,7 @@ class Component(abc.ABC): ...@@ -47,7 +57,7 @@ class Component(abc.ABC):
return [i.channel for i in self.interfaces() if i.is_connected()] return [i.channel for i in self.interfaces() if i.is_connected()]
class Interface(abc.ABC): class Interface(IdObj):
def __init__(self, c: Component) -> None: def __init__(self, c: Component) -> None:
self.component = c self.component = c
self.channel: Channel | None = None self.channel: Channel | None = None
...@@ -63,7 +73,7 @@ class Interface(abc.ABC): ...@@ -63,7 +73,7 @@ class Interface(abc.ABC):
self.channel = c self.channel = c
class Channel(abc.ABC): class Channel(IdObj):
def __init__(self, a: Interface, b: Interface) -> None: def __init__(self, a: Interface, b: Interface) -> None:
self.latency = 500 self.latency = 500
self.a: Interface = a self.a: Interface = a
......
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