Commit ea3a5300 authored by Antoine Kaufmann's avatar Antoine Kaufmann
Browse files

rename modules

parent 0225a17b
# Copyright 2022 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.
# 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 math import math
import io import io
import typing as tp import typing as tp
......
# Copyright 2022 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 simbricks.splitsim.specification as spec
import simbricks.splitsim.impl as impl
import typing as tp
"""
RunObj class stores a mapping between a specification instance and the simulator instance
"""
class RunObj(object):
def __init__(self) -> None:
self.sim_inst: impl.Simulator = None
self.spec_inst: spec.SimObject = None
"""
Allobj class stores all the mappings for an experiment
"""
class AllObj(object):
def __init__(self) -> None:
self.all_obj: tp.List[RunObj] = []
import io
import typing as tp
import tarfile
import itertools
class System():
""" Defines System configuration of the whole simulation """
def __init__(self) -> None:
self.hosts: tp.List[Host] = []
self.nics: tp.List[NIC] = []
self.switches: tp.List[Switch] = []
self.pci_channels: tp.List[PCI] = []
self.eth_channels: tp.List[Eth] = []
class SimObject():
def __init__(self) -> None:
self.sync_period = 500 #nano second
class Channel(SimObject):
def __init__(self) -> None:
super().__init__()
self.latency = 500 # nano second
def install(self, end_point0, end_point1) -> None:
return
class PCI(Channel):
def __init__(self, sys) -> None:
super().__init__()
self.end_point_host = None
self.end_point_dev = None
sys.pci_channels.append(self)
def install(self, host, dev) -> None:
self.end_point_host = host
self.end_point_dev = dev
host.nics.append(dev)
host.pci_channel = self
dev.host.append(host)
dev.pci_channel = self
class Eth(Channel):
def __init__(self, sys) -> None:
super().__init__()
self.end_point_netdev0 = None
self.end_point_netdev1 = None
sys.eth_channels.append(self)
def install(self, netdev0, netdev1):
self.end_point_netdev0 = netdev0
self.end_point_netdev1 = netdev1
netdev0.net.append(netdev1)
netdev0.eth_channel = self
netdev1.net.append(netdev0)
netdev1.eth_channel = self
class Host(SimObject):
id_iter = itertools.count()
def __init__(self, sys) -> None:
super().__init__()
self.id = next(self.id_iter)
sys.hosts.append(self)
self.pci_channel: PCI = None
self.nics: tp.List[NIC] = []
# self.sim = None
self.nic_driver = ['i40e']
self.sync = True
"""Synchronization mode. False is running unsynchronized, True synchronized."""
self.cpu_freq = '3GHz'
"""Simulated host frequency"""
self.ip = '10.0.0.1'
"""IP address."""
self.prefix = 24
"""IP prefix."""
self.cores = 1
"""Number of CPU cores."""
self.threads = 1
"""Number of threads per CPU core."""
self.memory = 512
"""Amount of system memory in MB."""
self.disk_image = 'base'
"""Name of disk image to use."""
self.mtu = 1500
"""Networking MTU."""
self.sys_clock = '1GHz'
"""system bus clock"""
self.tcp_congestion_control = 'bic'
"""TCP Congestion Control algorithm to use."""
self.app: tp.Optional[AppConfig] = None
"""Application to run on simulated host."""
self.kcmd_append = ''
"""String to be appended to kernel command line."""
self.nockp = 0
"""Do not create a checkpoint in Gem5."""
def run_cmds(self) -> tp.List[str]:
"""Commands to run on node."""
return self.app.run_cmds(self)
def cleanup_cmds(self) -> tp.List[str]:
"""Commands to run to cleanup node."""
return []
def config_files(self) -> tp.Dict[str, tp.IO]:
"""
Additional files to put inside the node, which are mounted under
`/tmp/guest/`.
Specified in the following format: `filename_inside_node`:
`IO_handle_of_file`
"""
return self.app.config_files()
def prepare_pre_cp(self) -> tp.List[str]:
"""Commands to run to prepare node before checkpointing."""
return [
'set -x',
'export HOME=/root',
'export LANG=en_US',
'export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:' + \
'/usr/bin:/sbin:/bin:/usr/games:/usr/local/games"'
]
def prepare_post_cp(self) -> tp.List[str]:
"""Commands to run to prepare node after checkpoint restore."""
return []
def strfile(self, s: str) -> io.BytesIO:
"""
Helper function to convert a string to an IO handle for usage in
`config_files()`.
Using this, you can create a file with the string as its content on the
simulated node.
"""
return io.BytesIO(bytes(s, encoding='UTF-8'))
class LinuxHost(Host):
def __init__(self, sys) -> None:
super().__init__(sys)
self.ifname = 'eth0'
self.force_mac_addr: tp.Optional[str] = None
def prepare_post_cp(self) -> tp.List[str]:
l = []
for d in self.nic_driver:
if d[0] == '/':
l.append('insmod ' + d)
else:
l.append('modprobe ' + d)
if self.force_mac_addr:
l.append(
'ip link set dev ' + self.ifname + ' address ' +
self.force_mac_addr
)
l.append('ip link set dev ' + self.ifname + ' up')
l.append(f'ip addr add {self.ip}/{self.prefix} dev {self.ifname}')
return super().prepare_post_cp() + l
def config_files(self) -> tp.Dict[str, tp.IO]:
m = {}
for d in self.nic_driver:
if d[0] == '/':
m = {'mqnic.ko': open('../images/mqnic/mqnic.ko', 'rb')}
return {**m, **super().config_files()}
"""
Pci device NIC
It has both pci and eth channel
"""
class NIC(SimObject):
id_iter = itertools.count()
def __init__(self, sys) -> None:
super().__init__()
self.id = next(self.id_iter)
sys.nics.append(self)
self.sync = True
self.pci_channel: PCI = None
self.eth_channel: Eth = None
self.frequency = '1Ghz'
self.mac: tp.Optional[str] = None
self.host: tp.List[Host] = []
self.net = [] # NIC or NetDev connected through eth channel
# self.sim = None
class i40eNIC(NIC):
def __init__(self, sys) -> None:
super().__init__(sys)
self.type = 'i40e'
class CorundumNIC(NIC):
def __init__(self, sys) -> None:
super().__init__(sys)
self.type = 'corundum_bm'
"""
Network device
It only has eth channel
"""
class NetDev(SimObject):
id_iter = itertools.count()
def __init__(self) -> None:
super().__init__()
self.id = next(self.id_iter)
self.switch: Switch = None
self.sync = True
self.eth_channel: Eth = None
self.mac: tp.Optional[str] = None
self.ip: tp.Optional[str] = None
self.net = [] # NIC or NetDev connected through eth channel
# self.sim = None
class Switch(SimObject):
id_iter = itertools.count()
def __init__(self, sys) -> None:
super().__init__()
self.id = next(self.id_iter)
sys.switches.append(self)
self.sync = True
# these two: set it when install the channel
self.sync_period = 500 # ns second
self.eth_latency = 500 # ns second
###
self.netdevs : tp.List[NetDev] = []
# self.sim = None
def install_netdev(self, netdev: NetDev):
self.netdevs.append(netdev)
netdev.switch = self
class AppConfig():
"""Defines the application to run on a node or host."""
""" Commands for detailed Host"""
def run_cmds(self, node: Host) -> tp.List[str]:
"""Commands to run for this application."""
return []
def prepare_pre_cp(self, node: Host) -> tp.List[str]:
"""Commands to run to prepare this application before checkpointing."""
return []
def prepare_post_cp(self, node: Host) -> tp.List[str]:
"""Commands to run to prepare this application after the checkpoint is
restored."""
return []
def config_files(self) -> tp.Dict[str, tp.IO]:
"""
Additional files to put inside the node, which are mounted under
`/tmp/guest/`.
Specified in the following format: `filename_inside_node`:
`IO_handle_of_file`
"""
return {}
def strfile(self, s: str) -> io.BytesIO:
"""
Helper function to convert a string to an IO handle for usage in
`config_files()`.
Using this, you can create a file with the string as its content on the
simulated node.
"""
return io.BytesIO(bytes(s, encoding='UTF-8'))
""" Commands for dummy Host (e.g. app names for ns-3)"""
class PingClient(AppConfig):
def __init__(self, server_ip: str = '192.168.64.1') -> None:
super().__init__()
self.server_ip = server_ip
def run_cmds(self, node: Host) -> tp.List[str]:
return [f'ping {self.server_ip} -c 10']
### add commands for dummy Hosts here
class Sleep(AppConfig):
def __init__(self, server_ip: str = '192.168.64.2') -> None:
super().__init__()
self.server_ip = server_ip
def run_cmds(self, node: Host) -> tp.List[str]:
return ['sleep 10']
class NetperfServer(AppConfig):
def run_cmds(self, node: Host) -> tp.List[str]:
return ['netserver', 'sleep infinity']
class NetperfClient(AppConfig):
def __init__(self, server_ip: str = '192.168.64.1') -> None:
super().__init__()
self.server_ip = server_ip
self.duration_tp = 10
self.duration_lat = 10
def run_cmds(self, node: Host) -> tp.List[str]:
return [
'netserver',
'sleep 0.5',
f'netperf -H {self.server_ip} -l {self.duration_tp}',
(
f'netperf -H {self.server_ip} -l {self.duration_lat} -t TCP_RR'
' -- -o mean_latency,p50_latency,p90_latency,p99_latency'
)
]
\ No newline at end of file
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