"...git@developer.sourcefind.cn:OpenDAS/mmdetection3d.git" did not exist on "23071a560eda671f8324337c6688a74d9896c47e"
Unverified Commit bebefc61 authored by Jakob Görgen's avatar Jakob Görgen
Browse files

added ns3 dumbbell net + ns3 brisge net support + socket creation while...

added ns3 dumbbell net + ns3 brisge net support + socket creation while creating sim dependency graph
parent 96ac5be2
...@@ -19,8 +19,8 @@ experiments = [] ...@@ -19,8 +19,8 @@ experiments = []
sys = system.System() sys = system.System()
# create a host instance and a NIC instance then install the NIC on the host # create a host instance and a NIC instance then install the NIC on the host
host0 = system.CorundumLinuxHost(sys) # host0 = system.CorundumLinuxHost(sys)
# host0 = system.I40ELinuxHost(sys) host0 = system.I40ELinuxHost(sys)
pcie0 = system.PCIeHostInterface(host0) pcie0 = system.PCIeHostInterface(host0)
cfg_disk0 = system.DistroDiskImage(h=host0, name="base") cfg_disk0 = system.DistroDiskImage(h=host0, name="base")
host0.add_disk(cfg_disk0) host0.add_disk(cfg_disk0)
...@@ -28,8 +28,8 @@ tar_disk0 = system.LinuxConfigDiskImage(h=host0) ...@@ -28,8 +28,8 @@ tar_disk0 = system.LinuxConfigDiskImage(h=host0)
host0.add_disk(tar_disk0) host0.add_disk(tar_disk0)
host0.add_if(pcie0) host0.add_if(pcie0)
nic0 = system.CorundumNIC(sys) # nic0 = system.CorundumNIC(sys)
# nic0 = system.IntelI40eNIC(sys) nic0 = system.IntelI40eNIC(sys)
nic0.add_ipv4("10.0.0.1") nic0.add_ipv4("10.0.0.1")
pcichannel0 = system.PCIeChannel(pcie0, nic0._pci_if) pcichannel0 = system.PCIeChannel(pcie0, nic0._pci_if)
...@@ -46,17 +46,32 @@ nic1 = system.IntelI40eNIC(sys) ...@@ -46,17 +46,32 @@ nic1 = system.IntelI40eNIC(sys)
nic1.add_ipv4("10.0.0.2") nic1.add_ipv4("10.0.0.2")
pcichannel1 = system.PCIeChannel(pcie1, nic1._pci_if) pcichannel1 = system.PCIeChannel(pcie1, nic1._pci_if)
# create switch and its ports # # create switch and its ports
switch = system.EthSwitch(sys) # switch = system.EthSwitch(sys)
netif0 = system.EthInterface(switch) # netif0 = system.EthInterface(switch)
switch.add_if(netif0) # switch.add_if(netif0)
netif1 = system.EthInterface(switch) # netif1 = system.EthInterface(switch)
switch.add_if(netif1) # switch.add_if(netif1)
# # create channels and connect the switch to the host nics
# ethchannel0 = system.EthChannel(switch.eth_ifs[0], nic0._eth_if)
# create channels and connect the switch to the host nics # ethchannel1 = system.EthChannel(switch.eth_ifs[1], nic1._eth_if)
ethchannel0 = system.EthChannel(switch.eth_ifs[0], nic0._eth_if)
ethchannel1 = system.EthChannel(switch.eth_ifs[1], nic1._eth_if) switch0 = system.EthSwitch(sys)
switch1 = system.EthSwitch(sys)
# connect first switch to client nic
switch0_for_nic = system.EthInterface(switch0)
switch0.add_if(switch0_for_nic)
nic0_switch0_chan = system.EthChannel(nic0._eth_if, switch0_for_nic)
# connect second switch to server nic
switch1_for_nic = system.EthInterface(switch1)
switch1.add_if(switch1_for_nic)
nic1_switch1_chan = system.EthChannel(nic1._eth_if, switch1_for_nic)
# connect first switch to second switch
switch0_for_net = system.EthInterface(switch0)
switch0.add_if(switch0_for_net)
switch1_for_net = system.EthInterface(switch1)
switch1.add_if(switch1_for_net)
switch0_switch1_chan = system.EthChannel(switch0_for_net, switch1_for_net)
# configure the software to run on the host # configure the software to run on the host
# host0.add_app(system.NetperfClient(host0, nic1._ip)) # host0.add_app(system.NetperfClient(host0, nic1._ip))
...@@ -108,28 +123,35 @@ for host_type in host_types: ...@@ -108,28 +123,35 @@ for host_type in host_types:
host_inst0 = sim.QemuSim(simulation) host_inst0 = sim.QemuSim(simulation)
host_inst0.add(host0) host_inst0.add(host0)
host_inst0.name = "Client-Host"
# host_inst0.wait_terminate = True # host_inst0.wait_terminate = True
# host_inst0.cpu_type = 'X86KvmCPU' # host_inst0.cpu_type = 'X86KvmCPU'
# host_inst1 = sim.Gem5Sim(simulation) # host_inst1 = sim.Gem5Sim(simulation)
host_inst1 = sim.QemuSim(simulation) host_inst1 = sim.QemuSim(simulation)
host_inst1.name = "Server-Simulator"
host_inst1.add(host1) host_inst1.add(host1)
# host_inst1.cpu_type = 'X86KvmCPU' # host_inst1.cpu_type = 'X86KvmCPU'
# nic_inst0 = sim.I40eNicSim(simulation=simulation) nic_inst0 = sim.I40eNicSim(simulation=simulation)
# nic_inst0 = sim.CorundumBMNICSim(simulation) # nic_inst0 = sim.CorundumBMNICSim(simulation)
nic_inst0 = sim.CorundumVerilatorNICSim(simulation) # nic_inst0 = sim.CorundumVerilatorNICSim(simulation)
nic_inst0.add(nic0) nic_inst0.add(nic0)
nic_inst1 = sim.I40eNicSim(simulation=simulation) nic_inst1 = sim.I40eNicSim(simulation=simulation)
nic_inst1.add(nic1) nic_inst1.add(nic1)
net_inst = sim.SwitchNet(simulation) # net_inst = sim.SwitchNet(simulation)
net_inst.add(switch) # net_inst = sim.NS3BridgeNet(simulation=simulation)
# net_inst.add(switch)
net_inst = sim.NS3DumbbellNet(simulation=simulation)
net_inst.add(left=switch0, right=switch1)
sim_helpers.enable_sync_simulation( sim_helpers.enable_sync_simulation(
simulation=simulation, amount=500, ratio=sim.Time.Nanoseconds simulation=simulation, amount=500, ratio=sim.Time.Nanoseconds
) )
# sim_helpers.disalbe_sync_simulation(simulation=simulation)
print(simulation.name + " all simulators:") print(simulation.name + " all simulators:")
sims = simulation.all_simulators() sims = simulation.all_simulators()
......
...@@ -210,28 +210,32 @@ class Instantiation(util_base.IdObj): ...@@ -210,28 +210,32 @@ class Instantiation(util_base.IdObj):
enforce_existence=False, enforce_existence=False,
) )
def _create_opposing_socket( def _create_opposing_socket(self, socket: Socket, socket_type: SockType) -> Socket:
self, socket: Socket, supported_sock_types: set[SockType] = set()
) -> Socket:
new_ty = ( new_ty = (
SockType.LISTEN if socket._type == SockType.CONNECT else SockType.CONNECT SockType.LISTEN if socket._type == SockType.CONNECT else SockType.CONNECT
) )
if new_ty not in supported_sock_types: if new_ty != socket_type:
raise Exception( raise Exception(
f"cannot create opposing socket, as required type is not supported: required={new_ty.name}, supported={','.join(supported_sock_types)}" f"cannot create opposing socket, as required type is not supported: required={new_ty.name}, supported={socket_type.name}"
) )
new_path = socket._path new_path = socket._path
new_socket = Socket(path=new_path, ty=new_ty) new_socket = Socket(path=new_path, ty=new_ty)
return new_socket return new_socket
def get_socket( def get_socket(self, interface: sys_base.Interface) -> Socket | None:
self, socket = self._get_socket_by_interface(interface=interface)
interface: sys_base.Interface, if socket:
supported_sock_types: set[SockType] = set(), return socket
return None
def _get_socket(
self, interface: sys_base.Interface, socket_type: SockType
) -> Socket: ) -> Socket:
if self._opposing_interface_within_same_sim(interface=interface): if self._opposing_interface_within_same_sim(interface=interface):
raise Exception("interface does not need a socket") raise Exception(
"we do not create a socket for interfacces taht both beloing to the same simulator"
)
# check if already a socket is associated with this interface # check if already a socket is associated with this interface
socket = self._get_socket_by_interface(interface=interface) socket = self._get_socket_by_interface(interface=interface)
...@@ -242,26 +246,15 @@ class Instantiation(util_base.IdObj): ...@@ -242,26 +246,15 @@ class Instantiation(util_base.IdObj):
socket = self._get_opposing_socket_by_interface(interface=interface) socket = self._get_opposing_socket_by_interface(interface=interface)
if socket is not None: if socket is not None:
new_socket = self._create_opposing_socket( new_socket = self._create_opposing_socket(
socket=socket, supported_sock_types=supported_sock_types socket=socket, socket_type=socket_type
) )
self._updated_tracker_mapping(interface=interface, socket=new_socket) self._updated_tracker_mapping(interface=interface, socket=new_socket)
print(f"created socket: {new_socket._path}") print(f"created socket: {new_socket._path}")
return new_socket return new_socket
# neither connecting nor listening side already created a socket, thus we # create socket if opposing socket was not created yet
# create a completely new 'CONNECT' socket
if len(supported_sock_types) < 1 or (
SockType.LISTEN not in supported_sock_types
and SockType.CONNECT not in supported_sock_types
):
raise Exception("cannot create a socket if no socket type is supported")
sock_type = (
SockType.CONNECT
if SockType.CONNECT in supported_sock_types
else SockType.LISTEN
)
sock_path = self._interface_to_sock_path(interface=interface) sock_path = self._interface_to_sock_path(interface=interface)
new_socket = Socket(path=sock_path, ty=sock_type) new_socket = Socket(path=sock_path, ty=socket_type)
self._updated_tracker_mapping(interface=interface, socket=new_socket) self._updated_tracker_mapping(interface=interface, socket=new_socket)
print(f"created socket: {new_socket._path}") print(f"created socket: {new_socket._path}")
return new_socket return new_socket
...@@ -274,7 +267,11 @@ class Instantiation(util_base.IdObj): ...@@ -274,7 +267,11 @@ class Instantiation(util_base.IdObj):
sim_a: sim_base.Simulator, depends_on: sim_base.Simulator sim_a: sim_base.Simulator, depends_on: sim_base.Simulator
): ):
if depends_on in sim_dependency: if depends_on in sim_dependency:
assert sim_a not in sim_dependency[depends_on] if sim_a in sim_dependency[depends_on]:
# TODO: FIXME
raise Exception(
"detected cylic dependency, this is currently not supported"
)
a_dependencies = set() a_dependencies = set()
if sim_a in sim_dependency: if sim_a in sim_dependency:
...@@ -283,41 +280,44 @@ class Instantiation(util_base.IdObj): ...@@ -283,41 +280,44 @@ class Instantiation(util_base.IdObj):
a_dependencies.add(depends_on) a_dependencies.add(depends_on)
sim_dependency[sim_a] = a_dependencies sim_dependency[sim_a] = a_dependencies
def update_a_depends_on_b(sim_a: sim_base.Simulator, sim_b: sim_base.Simulator): def update_a_depends_on_b(inf_a: sys_base.Interface, inf_b: sys_base.Interface):
a_sock: set[SockType] = sim_a.supported_socket_types() sim_a = self.find_sim_by_interface(interface=inf_a)
b_sock: set[SockType] = sim_b.supported_socket_types() sim_b = self.find_sim_by_interface(interface=inf_b)
a_sock: set[SockType] = sim_a.supported_socket_types(interface=inf_a)
b_sock: set[SockType] = sim_b.supported_socket_types(interface=inf_b)
if a_sock != b_sock: if a_sock != b_sock:
if len(a_sock) == 0 or len(b_sock) == 0: if len(a_sock) == 0 or len(b_sock) == 0:
raise Exception( raise Exception(
"cannot solve if one simulator doesnt support any socket type" "cannot create socket and resolve dependency if no socket type is supported for an interface"
) )
if SockType.CONNECT in a_sock: if SockType.CONNECT in a_sock:
assert SockType.LISTEN in b_sock assert SockType.LISTEN in b_sock
insert_dependency(sim_a, depends_on=sim_b) insert_dependency(sim_a, depends_on=sim_b)
self._get_socket(interface=inf_a, socket_type=SockType.CONNECT)
self._get_socket(interface=inf_b, socket_type=SockType.LISTEN)
else: else:
assert SockType.CONNECT in b_sock assert SockType.CONNECT in b_sock
insert_dependency(sim_b, depends_on=sim_a) insert_dependency(sim_b, depends_on=sim_a)
self._get_socket(interface=inf_b, socket_type=SockType.CONNECT)
self._get_socket(interface=inf_a, socket_type=SockType.LISTEN)
else: else:
# deadlock? # deadlock?
if len(a_sock) != 2 or len(b_sock) != 2: if len(a_sock) != 2 or len(b_sock) != 2:
raise Exception("cannot solve deadlock") raise Exception("cannot solve deadlock")
# both support both we just pick an order # both support both we just pick an order
insert_dependency(sim_a, depends_on=sim_b) insert_dependency(sim_a, depends_on=sim_b)
self._get_socket(interface=sim_a, socket_type=SockType.CONNECT)
self._get_socket(interface=sim_b, socket_type=SockType.LISTEN)
# TODO: pre-calculate the socket paths and whether they are listening or connecting sockets in here! # build dependency graph
for sim in self._simulation.all_simulators(): for sim in self._simulation.all_simulators():
for comp in sim._components: for comp in sim._components:
for sim_inf in comp.interfaces(): for sim_inf in comp.interfaces():
# no dependency here? a.k.a both interfaces within the same simulator?
if self._opposing_interface_within_same_sim(interface=sim_inf): if self._opposing_interface_within_same_sim(interface=sim_inf):
continue continue
opposing_inf = self._get_opposing_interface(interface=sim_inf) opposing_inf = self._get_opposing_interface(interface=sim_inf)
opposing_sim = self.find_sim_by_spec(spec=opposing_inf.component) update_a_depends_on_b(inf_a=sim_inf, inf_b=opposing_inf)
assert sim != opposing_sim
update_a_depends_on_b(sim, opposing_sim)
self._sim_dependency = sim_dependency self._sim_dependency = sim_dependency
...@@ -347,7 +347,7 @@ class Instantiation(util_base.IdObj): ...@@ -347,7 +347,7 @@ class Instantiation(util_base.IdObj):
await self.executor.await_files(wait_socks, verbose=True) await self.executor.await_files(wait_socks, verbose=True)
# 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
# TODO: fix paths to support mutliple exeriment runs etc. # TODO: fix paths to support mutliple exeriment runs etc.
def wrkdir(self) -> str: def wrkdir(self) -> str:
return pathlib.Path(self._env._workdir).resolve() return pathlib.Path(self._env._workdir).resolve()
...@@ -406,6 +406,9 @@ class Instantiation(util_base.IdObj): ...@@ -406,6 +406,9 @@ class Instantiation(util_base.IdObj):
await self._simulation.prepare(inst=self) await self._simulation.prepare(inst=self)
async def cleanup(self) -> None:
pass # TODO: implement cleanup functionality (e.g. delete )
def _join_paths( def _join_paths(
self, base: str = "", relative_path: str = "", enforce_existence=False self, base: str = "", relative_path: str = "", enforce_existence=False
) -> str: ) -> str:
...@@ -486,6 +489,11 @@ class Instantiation(util_base.IdObj): ...@@ -486,6 +489,11 @@ class Instantiation(util_base.IdObj):
relative_path=f"out-{run_number}.json", relative_path=f"out-{run_number}.json",
) )
def find_sim_by_interface(
self, interface: sys_base.Interface
) -> sim_base.Simulator:
return self.find_sim_by_spec(spec=interface.component)
def find_sim_by_spec(self, spec: sys_base.Component) -> sim_base.Simulator: def find_sim_by_spec(self, spec: sys_base.Component) -> sim_base.Simulator:
util_base.has_expected_type(spec, sys_base.Component) util_base.has_expected_type(spec, sys_base.Component)
return self._simulation.find_sim(spec) return self._simulation.find_sim(spec)
...@@ -184,46 +184,64 @@ class Simulator(utils_base.IdObj): ...@@ -184,46 +184,64 @@ class Simulator(utils_base.IdObj):
return False return False
return True return True
def _get_my_interface(self, chan: sys_conf.Channel) -> sys_conf.Interface: # # TODO: remove
interface = None # def _get_my_interface(self, chan: sys_conf.Channel) -> sys_conf.Interface:
for inter in chan.interfaces(): # interface = None
if inter.component in self._components: # for inter in chan.interfaces():
assert interface is None # if inter.component in self._components:
interface = inter # assert interface is None
if interface is None: # interface = inter
raise Exception( # if interface is None:
"unable to find channel interface for simulators specification" # raise Exception(
) # "unable to find channel interface for simulators specification"
return interface # )
# return interface
def _get_socket(
self, inst: inst_base.Instantiation, interface: sys_conf.Interface # # TODO: remove
) -> inst_base.Socket | None: # def _get_socket(
# get the channel associated with this interface # self, inst: inst_base.Instantiation, interface: sys_conf.Interface
chan = interface.get_chan_raise() # ) -> inst_base.Socket | None:
# check if interfaces channel is simulator internal, i.e. doesnt need an instanciation # if not self._chan_needs_instance(chan=interface.get_chan_raise()):
if not self._chan_needs_instance(chan): # return None
return None # return inst.get_socket(
# create the socket to listen on or connect to # interface=interface, supported_sock_types=self.supported_socket_types()
socket = inst.get_socket( # )
interface=interface, supported_sock_types=self.supported_socket_types()
) # # TODO: remove
return socket # def _get_sockets(self, inst: inst_base.Instantiation) -> list[inst_base.Socket]:
# sockets = []
def _get_sockets(self, inst: inst_base.Instantiation) -> list[inst_base.Socket]: # for comp_spec in self._components:
# for interface in comp_spec.interfaces():
# socket = self._get_socket(inst=inst, interface=interface)
# if socket is None:
# continue
# sockets.append(socket)
# return sockets
def _get_socks_by_comp(
self, inst: inst_base.Instantiation, comp: sys_conf.Component
) -> list[inst_base.Socket]:
if comp not in self._components:
raise Exception("comp must be a simulators component")
sockets = [] sockets = []
for comp_spec in self._components: for interface in comp.interfaces():
for interface in comp_spec.interfaces(): socket = inst.get_socket(interface=interface)
socket = self._get_socket(inst=inst, interface=interface) if socket:
if socket is None:
continue
sockets.append(socket) sockets.append(socket)
return sockets return sockets
def _get_socks_by_all_comp(
self, inst: inst_base.Instantiation
) -> list[inst_base.Socket]:
sockets = []
for comp in self._components:
sockets.extend(self._get_socks_by_comp(inst=inst, comp=comp))
return sockets
def _get_all_sockets_by_type( def _get_all_sockets_by_type(
self, inst: inst_base.Instantiation, sock_type: inst_base.SockType self, inst: inst_base.Instantiation, sock_type: inst_base.SockType
) -> list[inst_base.Socket]: ) -> list[inst_base.Socket]:
sockets = self._get_sockets(inst=inst) sockets = self._get_socks_by_all_comp(inst=inst)
sockets = Simulator.filter_sockets(sockets=sockets, filter_type=sock_type) sockets = Simulator.filter_sockets(sockets=sockets, filter_type=sock_type)
return sockets return sockets
...@@ -247,7 +265,7 @@ class Simulator(utils_base.IdObj): ...@@ -247,7 +265,7 @@ class Simulator(utils_base.IdObj):
@abc.abstractmethod @abc.abstractmethod
def run_cmd(self, inst: inst_base.Instantiation) -> str: def run_cmd(self, inst: inst_base.Instantiation) -> str:
"""Command to execute this simulator.""" """Command to execute this simulator."""
return "" raise Exception("must be implemented in sub-class")
def checkpoint_commands(self) -> list[str]: def checkpoint_commands(self) -> list[str]:
return [] return []
...@@ -256,7 +274,9 @@ class Simulator(utils_base.IdObj): ...@@ -256,7 +274,9 @@ class Simulator(utils_base.IdObj):
return [] return []
@abc.abstractmethod @abc.abstractmethod
def supported_socket_types(self) -> set[inst_base.SockType]: def supported_socket_types(
self, interface: sys_conf.Interface
) -> set[inst_base.SockType]:
return [] return []
# Sockets to be cleaned up: always the CONNECTING sockets # Sockets to be cleaned up: always the CONNECTING sockets
......
...@@ -50,7 +50,9 @@ class HostSim(sim_base.Simulator): ...@@ -50,7 +50,9 @@ class HostSim(sim_base.Simulator):
def supported_image_formats(self) -> list[str]: def supported_image_formats(self) -> list[str]:
raise Exception("implement me") raise Exception("implement me")
def supported_socket_types(self) -> set[inst_base.SockType]: def supported_socket_types(
self, interface: system.Interface
) -> set[inst_base.SockType]:
return [inst_base.SockType.CONNECT] return [inst_base.SockType.CONNECT]
...@@ -142,7 +144,7 @@ class Gem5Sim(HostSim): ...@@ -142,7 +144,7 @@ class Gem5Sim(HostSim):
interfaces=fsh_interfaces, ty=sys_pcie.PCIeHostInterface interfaces=fsh_interfaces, ty=sys_pcie.PCIeHostInterface
) )
for inf in pci_interfaces: for inf in pci_interfaces:
socket = self._get_socket(inst=inst, interface=inf) socket = inst.get_socket(interface=inf)
if socket is None: if socket is None:
continue continue
assert socket._type == inst_base.SockType.CONNECT assert socket._type == inst_base.SockType.CONNECT
...@@ -159,7 +161,7 @@ class Gem5Sim(HostSim): ...@@ -159,7 +161,7 @@ class Gem5Sim(HostSim):
interfaces=fsh_interfaces, ty=sys_mem.MemHostInterface interfaces=fsh_interfaces, ty=sys_mem.MemHostInterface
) )
for inf in mem_interfaces: for inf in mem_interfaces:
socket = self._get_socket(inst=inst, interface=inf) socket = inst.get_socket(interface=inf)
if socket is None: if socket is None:
continue continue
assert socket._type == inst_base.SockType.CONNECT assert socket._type == inst_base.SockType.CONNECT
...@@ -201,7 +203,7 @@ class QemuSim(HostSim): ...@@ -201,7 +203,7 @@ class QemuSim(HostSim):
executable="sims/external/qemu/build/x86_64-softmmu/qemu-system-x86_64", executable="sims/external/qemu/build/x86_64-softmmu/qemu-system-x86_64",
) )
self.name = f"QemuSim-{self._id}" self.name = f"QemuSim-{self._id}"
self._disks: list[tuple[str, str]] = [] # [(path, format)] self._disks: list[tuple[str, str]] = [] # [(path, format)]
def resreq_cores(self) -> int: def resreq_cores(self) -> int:
return 1 return 1
...@@ -222,7 +224,9 @@ class QemuSim(HostSim): ...@@ -222,7 +224,9 @@ class QemuSim(HostSim):
d = [] d = []
for disk in full_sys_hosts[0].disks: for disk in full_sys_hosts[0].disks:
format = ( format = (
"qcow2" if not isinstance(disk, sys_host.LinuxConfigDiskImage) else "raw" "qcow2"
if not isinstance(disk, sys_host.LinuxConfigDiskImage)
else "raw"
) )
copy_path = await disk.make_qcow_copy( copy_path = await disk.make_qcow_copy(
inst=inst, inst=inst,
...@@ -236,7 +240,7 @@ class QemuSim(HostSim): ...@@ -236,7 +240,7 @@ class QemuSim(HostSim):
return [] return []
def cleanup_commands(self) -> list[str]: def cleanup_commands(self) -> list[str]:
return [] return ["poweroff -f"]
def run_cmd(self, inst: inst_base.Instantiation) -> str: def run_cmd(self, inst: inst_base.Instantiation) -> str:
...@@ -287,7 +291,7 @@ class QemuSim(HostSim): ...@@ -287,7 +291,7 @@ class QemuSim(HostSim):
interfaces=fsh_interfaces, ty=sys_pcie.PCIeHostInterface interfaces=fsh_interfaces, ty=sys_pcie.PCIeHostInterface
) )
for inf in pci_interfaces: for inf in pci_interfaces:
socket = self._get_socket(inst=inst, interface=inf) socket = inst.get_socket(interface=inf)
if socket is None: if socket is None:
continue continue
assert socket._type is inst_base.SockType.CONNECT assert socket._type is inst_base.SockType.CONNECT
......
...@@ -20,12 +20,10 @@ ...@@ -20,12 +20,10 @@
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
import abc from simbricks.orchestration.system import base as sys_base
import sys from simbricks.orchestration.system import eth as sys_eth
import simbricks.orchestration.simulation.base as sim_base from simbricks.orchestration.simulation import base as sim_base
from simbricks.orchestration.system import eth
from simbricks.orchestration.instantiation import base as inst_base from simbricks.orchestration.instantiation import base as inst_base
from simbricks.orchestration.experiment.experiment_environment_new import ExpEnv
from simbricks.orchestration.utils import base as base_utils from simbricks.orchestration.utils import base as base_utils
...@@ -46,7 +44,9 @@ class NetSim(sim_base.Simulator): ...@@ -46,7 +44,9 @@ class NetSim(sim_base.Simulator):
def init_network(self) -> None: def init_network(self) -> None:
pass pass
def supported_socket_types(self) -> set[inst_base.SockType]: def supported_socket_types(
self, interface: sys_base.Interface
) -> set[inst_base.SockType]:
return [inst_base.SockType.CONNECT] return [inst_base.SockType.CONNECT]
...@@ -59,11 +59,11 @@ class WireNet(NetSim): ...@@ -59,11 +59,11 @@ class WireNet(NetSim):
simulation=simulation, simulation=simulation,
executable="sims/net/wire/net_wire", executable="sims/net/wire/net_wire",
) )
self.name=f"WireNet-{self._id}" self.name = f"WireNet-{self._id}"
self._relative_pcap_file_path: str | None = relative_pcap_filepath self._relative_pcap_file_path: str | None = relative_pcap_filepath
def add(self, wire: eth.EthWire): def add(self, wire: sys_eth.EthWire):
base_utils.has_expected_type(wire, eth.EthWire) base_utils.has_expected_type(wire, sys_eth.EthWire)
if len(self._components) > 1: if len(self._components) > 1:
raise Exception( raise Exception(
"can only add a single wire component to the WireNet simulator" "can only add a single wire component to the WireNet simulator"
...@@ -76,7 +76,7 @@ class WireNet(NetSim): ...@@ -76,7 +76,7 @@ class WireNet(NetSim):
sim_base.Simulator.get_unique_latency_period_sync(channels=channels) sim_base.Simulator.get_unique_latency_period_sync(channels=channels)
) )
sockets = self._get_sockets(inst=inst) sockets = self._get_socks_by_all_comp(inst=inst)
assert len(sockets) == 2 assert len(sockets) == 2
cmd = inst.join_repo_base(self._executable) cmd = inst.join_repo_base(self._executable)
...@@ -102,11 +102,11 @@ class SwitchNet(NetSim): ...@@ -102,11 +102,11 @@ class SwitchNet(NetSim):
simulation=simulation, simulation=simulation,
executable=executable, executable=executable,
) )
self.name=f"SwitchNet-{self._id}" self.name = f"SwitchNet-{self._id}"
self._relative_pcap_file_path: str | None = relative_pcap_filepath self._relative_pcap_file_path: str | None = relative_pcap_filepath
def add(self, switch_spec: eth.EthSwitch): def add(self, switch_spec: sys_eth.EthSwitch):
base_utils.has_expected_type(switch_spec, eth.EthSwitch) base_utils.has_expected_type(switch_spec, sys_eth.EthSwitch)
if len(self._components) > 1: if len(self._components) > 1:
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)
...@@ -129,7 +129,7 @@ class SwitchNet(NetSim): ...@@ -129,7 +129,7 @@ class SwitchNet(NetSim):
) )
cmd += " " + pcap_file cmd += " " + pcap_file
sockets = self._get_sockets(inst=inst) sockets = self._get_socks_by_all_comp(inst=inst)
listen, connect = sim_base.Simulator.split_sockets_by_type(sockets) listen, connect = sim_base.Simulator.split_sockets_by_type(sockets)
for sock in connect: for sock in connect:
...@@ -165,3 +165,98 @@ class MemSwitchNet(SwitchNet): ...@@ -165,3 +165,98 @@ class MemSwitchNet(SwitchNet):
cmd += f",{m[4]}" cmd += f",{m[4]}"
return cmd return cmd
class SimpleNS3Sim(NetSim):
def __init__(
self,
simulation: sim_base.Simulation,
name: str = "SimpleNS3Sim",
ns3_run_script: str = "",
) -> None:
super().__init__(
simulation=simulation,
executable="sims/external/ns-3/simbricks-run.sh",
name=name,
)
self._ns3_run_script: str = ns3_run_script
def run_cmd(self, inst: inst_base.Instantiation) -> str:
return f"{inst.join_repo_base(self._executable)} {self._ns3_run_script} "
class NS3DumbbellNet(SimpleNS3Sim):
def __init__(self, simulation: sim_base.Simulation) -> None:
super().__init__(
simulation=simulation,
ns3_run_script="simbricks-dumbbell-example",
)
self.name = f"NS3DumbbellNet-{self._id}"
self._left: sys_eth.EthSwitch | None = None
self._right: sys_eth.EthSwitch | None = None
def add(self, left: sys_eth.EthSwitch, right: sys_eth.EthSwitch):
base_utils.has_expected_type(left, sys_eth.EthSwitch)
base_utils.has_expected_type(right, sys_eth.EthSwitch)
if (
len(self._components) > 2
or self._left is not None
or self._right is not None
):
raise Exception("NS3DumbbellNet can only simulate two switches")
super().add(comp=left)
super().add(comp=right)
self._left = left
self._right = right
def run_cmd(self, inst: inst_base.Instantiation) -> str:
cmd = super().run_cmd(inst=inst)
left_socks = self._get_socks_by_comp(inst=inst, comp=self._left)
for sock in left_socks:
assert sock._type == inst_base.SockType.CONNECT
cmd += f"--SimbricksPortLeft={sock._path} "
right_sockets = self._get_socks_by_comp(inst=inst, comp=self._right)
for sock in right_sockets:
assert sock._type == inst_base.SockType.CONNECT
cmd += f"--SimbricksPortRight={sock._path} "
# TODO cmd += f"{self.opt}"
print(
f"!!!!!!!!!!!!!!!!!!!!!! NS3DumbbellNet run_cmd: {cmd} !!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
)
return cmd
class NS3BridgeNet(SimpleNS3Sim):
def __init__(self, simulation: sim_base.Simulation) -> None:
super().__init__(
simulation=simulation,
ns3_run_script="simbricks-bridge-example",
)
self.name = f"NS3BridgeNet-{self._id}"
def add(self, switch_comp: sys_eth.EthSwitch):
base_utils.has_expected_type(switch_comp, sys_eth.EthSwitch)
if len(self._components) > 1:
raise Exception("NS3BridgeNet can only simulate one switch/bridge")
super().add(comp=switch_comp)
def run_cmd(self, inst: inst_base.Instantiation) -> str:
cmd = super().run_cmd(inst=inst)
sockets = self._get_socks_by_all_comp(inst=inst)
for sock in sockets:
cmd += f"--SimbricksPort={sock._path} "
# TODO cmd += f"{self.opt}"
print(
f"!!!!!!!!!!!!!!!!!!!!!! NS3BridgeNet run_cmd: {cmd} !!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
)
return cmd
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
from __future__ import annotations from __future__ import annotations
import typing as tp from simbricks.orchestration.system import base as sys_base
from simbricks.orchestration.system import pcie as sys_pcie from simbricks.orchestration.system import pcie as sys_pcie
from simbricks.orchestration.system import eth as sys_eth from simbricks.orchestration.system import eth as sys_eth
from simbricks.orchestration.system import nic as sys_nic from simbricks.orchestration.system import nic as sys_nic
...@@ -41,7 +41,9 @@ class PCIDevSim(sim_base.Simulator): ...@@ -41,7 +41,9 @@ class PCIDevSim(sim_base.Simulator):
def full_name(self) -> str: def full_name(self) -> str:
return "dev." + self.name return "dev." + self.name
def supported_socket_types(self) -> set[inst_base.SockType]: def supported_socket_types(
self, interface: sys_base.Interface
) -> set[inst_base.SockType]:
return [inst_base.SockType.LISTEN] return [inst_base.SockType.LISTEN]
...@@ -70,13 +72,13 @@ class NICSim(PCIDevSim): ...@@ -70,13 +72,13 @@ class NICSim(PCIDevSim):
pci_devices = self.filter_components_by_type(ty=sys_pcie.PCIeSimpleDevice) pci_devices = self.filter_components_by_type(ty=sys_pcie.PCIeSimpleDevice)
assert len(pci_devices) == 1 assert len(pci_devices) == 1
socket = self._get_socket(inst=inst, interface=pci_devices[0]._pci_if) socket = inst.get_socket(interface=pci_devices[0]._pci_if)
assert socket is not None and socket._type == inst_base.SockType.LISTEN assert socket is not None and socket._type == inst_base.SockType.LISTEN
cmd += f"{socket._path} " cmd += f"{socket._path} "
eth_devices = self.filter_components_by_type(ty=sys_eth.EthSimpleNIC) eth_devices = self.filter_components_by_type(ty=sys_eth.EthSimpleNIC)
assert len(eth_devices) == 1 assert len(eth_devices) == 1
socket = self._get_socket(inst=inst, interface=eth_devices[0]._eth_if) socket = inst.get_socket(interface=eth_devices[0]._eth_if)
assert socket is not None and socket._type == inst_base.SockType.LISTEN assert socket is not None and socket._type == inst_base.SockType.LISTEN
cmd += f"{socket._path} " cmd += f"{socket._path} "
...@@ -95,13 +97,13 @@ class NICSim(PCIDevSim): ...@@ -95,13 +97,13 @@ class NICSim(PCIDevSim):
class I40eNicSim(NICSim): class I40eNicSim(NICSim):
def __init__(self, simulation: sim_base.Simulation): def __init__(self, simulation: sim_base.Simulation):
super().__init__( super().__init__(
simulation=simulation, simulation=simulation,
executable="sims/nic/i40e_bm/i40e_bm", executable="sims/nic/i40e_bm/i40e_bm",
) )
self.name=f"NICSim-{self._id}" self.name = f"NICSim-{self._id}"
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)
...@@ -113,7 +115,7 @@ class CorundumBMNICSim(NICSim): ...@@ -113,7 +115,7 @@ class CorundumBMNICSim(NICSim):
simulation=simulation, simulation=simulation,
executable="sims/nic/corundum_bm/corundum_bm", executable="sims/nic/corundum_bm/corundum_bm",
) )
self.name=f"CorundumBMNICSim-{self._id}" self.name = f"CorundumBMNICSim-{self._id}"
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)
...@@ -127,7 +129,7 @@ class CorundumVerilatorNICSim(NICSim): ...@@ -127,7 +129,7 @@ class CorundumVerilatorNICSim(NICSim):
simulation=simulation, simulation=simulation,
executable="sims/nic/corundum/corundum_verilator", executable="sims/nic/corundum/corundum_verilator",
) )
self.name=f"CorundumVerilatorNICSim-{self._id}" self.name = f"CorundumVerilatorNICSim-{self._id}"
self.clock_freq = 250 # MHz self.clock_freq = 250 # MHz
def resreq_mem(self) -> int: def resreq_mem(self) -> int:
......
...@@ -55,7 +55,7 @@ class EthSimpleNIC(base.Component): ...@@ -55,7 +55,7 @@ class EthSimpleNIC(base.Component):
class BaseEthNetComponent(base.Component): class BaseEthNetComponent(base.Component):
def __init__(self, s: base.System) -> None: def __init__(self, s: base.System) -> None:
super().__init__(s) super().__init__(s)
self.eth_ifs: EthInterface = [] self.eth_ifs: list[EthInterface] = []
def add_if(self, i: EthInterface) -> None: def add_if(self, i: EthInterface) -> None:
self.eth_ifs.append(i) self.eth_ifs.append(i)
......
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