Commit 74a9f167 authored by Jonas Kaufmann's avatar Jonas Kaufmann Committed by Antoine Kaufmann
Browse files

move all class attributes to __init__

parent f08c4bc2
...@@ -27,6 +27,7 @@ import re ...@@ -27,6 +27,7 @@ import re
import shlex import shlex
import shutil import shutil
import signal import signal
import typing as tp
from asyncio.subprocess import Process from asyncio.subprocess import Process
...@@ -45,8 +46,6 @@ class HostConfig(object): ...@@ -45,8 +46,6 @@ class HostConfig(object):
class Component(object): class Component(object):
proc: Process
terminate_future: asyncio.Task[int]
def __init__(self, cmd_parts, with_stdin=False): def __init__(self, cmd_parts, with_stdin=False):
self.is_ready = False self.is_ready = False
...@@ -58,6 +57,9 @@ class Component(object): ...@@ -58,6 +57,9 @@ class Component(object):
#print(cmd_parts) #print(cmd_parts)
self.with_stdin = with_stdin self.with_stdin = with_stdin
self._proc: tp.Optional[Process] = None
self._terminate_future: tp.Optional[asyncio.Task[int]] = None
def _parse_buf(self, buf, data): def _parse_buf(self, buf, data):
if data is not None: if data is not None:
buf.extend(data) buf.extend(data)
...@@ -100,19 +102,19 @@ class Component(object): ...@@ -100,19 +102,19 @@ class Component(object):
async def _waiter(self): async def _waiter(self):
out_handlers = asyncio.ensure_future( out_handlers = asyncio.ensure_future(
asyncio.wait([ asyncio.wait([
self._read_stream(self.proc.stdout, self._consume_out), self._read_stream(self._proc.stdout, self._consume_out),
self._read_stream(self.proc.stderr, self._consume_err) self._read_stream(self._proc.stderr, self._consume_err)
]) ])
) )
rc = await self.proc.wait() rc = await self._proc.wait()
await out_handlers await out_handlers
await self.terminated(rc) await self.terminated(rc)
return rc return rc
async def send_input(self, bs, eof=False): async def send_input(self, bs, eof=False):
self.proc.stdin.write(bs) self._proc.stdin.write(bs)
if eof: if eof:
self.proc.stdin.close() self._proc.stdin.close()
async def start(self): async def start(self):
if self.with_stdin: if self.with_stdin:
...@@ -120,38 +122,38 @@ class Component(object): ...@@ -120,38 +122,38 @@ class Component(object):
else: else:
stdin = None stdin = None
self.proc = await asyncio.create_subprocess_exec( self._proc = await asyncio.create_subprocess_exec(
*self.cmd_parts, *self.cmd_parts,
stdout=asyncio.subprocess.PIPE, stdout=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE,
stdin=stdin, stdin=stdin,
) )
self.terminate_future = asyncio.ensure_future(self._waiter()) self._terminate_future = asyncio.ensure_future(self._waiter())
await self.started() await self.started()
async def wait(self): async def wait(self):
await self.terminate_future await self._terminate_future
async def interrupt(self): async def interrupt(self):
if self.terminate_future.done(): if self._terminate_future.done():
return return
self.proc.send_signal(signal.SIGINT) self._proc.send_signal(signal.SIGINT)
async def terminate(self): async def terminate(self):
if self.terminate_future.done(): if self._terminate_future.done():
return return
self.proc.terminate() self._proc.terminate()
async def kill(self): async def kill(self):
self.proc.kill() self._proc.kill()
async def int_term_kill(self, delay=5): async def int_term_kill(self, delay=5):
await self.interrupt() await self.interrupt()
_, pending = await asyncio.wait([self.terminate_future], timeout=delay) _, pending = await asyncio.wait([self._terminate_future], timeout=delay)
if len(pending) != 0: if len(pending) != 0:
print('terminating') print('terminating')
await self.terminate() await self.terminate()
_,pending = await asyncio.wait([self.terminate_future], _,pending = await asyncio.wait([self._terminate_future],
timeout=delay) timeout=delay)
if len(pending) != 0: if len(pending) != 0:
print('killing') print('killing')
...@@ -199,7 +201,6 @@ class SimpleComponent(Component): ...@@ -199,7 +201,6 @@ class SimpleComponent(Component):
class SimpleRemoteComponent(SimpleComponent): class SimpleRemoteComponent(SimpleComponent):
pid_fut: asyncio.Future
def __init__( def __init__(
self, self,
...@@ -231,8 +232,11 @@ class SimpleRemoteComponent(SimpleComponent): ...@@ -231,8 +232,11 @@ class SimpleRemoteComponent(SimpleComponent):
# wrap up command in ssh invocation # wrap up command in ssh invocation
parts = self._ssh_cmd(remote_parts) parts = self._ssh_cmd(remote_parts)
super().__init__(label, parts, *args, **kwargs) super().__init__(label, parts, *args, **kwargs)
self._pid_fut: tp.Optional[asyncio.Future] = None
def _ssh_cmd(self, parts): def _ssh_cmd(self, parts):
"""SSH invocation of command for this host.""" """SSH invocation of command for this host."""
return [ return [
...@@ -245,34 +249,34 @@ class SimpleRemoteComponent(SimpleComponent): ...@@ -245,34 +249,34 @@ class SimpleRemoteComponent(SimpleComponent):
async def start(self): async def start(self):
"""Start this command (includes waiting for its pid.""" """Start this command (includes waiting for its pid."""
self.pid_fut = asyncio.get_running_loop().create_future() self._pid_fut = asyncio.get_running_loop().create_future()
await super().start() await super().start()
await self.pid_fut await self._pid_fut
async def process_out(self, lines, eof): async def process_out(self, lines, eof):
"""Scans output and set PID future once PID line found.""" """Scans output and set PID future once PID line found."""
if not self.pid_fut.done(): if not self._pid_fut.done():
newlines = [] newlines = []
pid_re = re.compile(r'^PID\s+(\d+)\s*$') pid_re = re.compile(r'^PID\s+(\d+)\s*$')
for l in lines: for l in lines:
m = pid_re.match(l) m = pid_re.match(l)
if m: if m:
pid = int(m.group(1)) pid = int(m.group(1))
self.pid_fut.set_result(pid) self._pid_fut.set_result(pid)
else: else:
newlines.append(l) newlines.append(l)
lines = newlines lines = newlines
if eof and not self.pid_fut.done(): if eof and not self._pid_fut.done():
# cancel PID future if it's not going to happen # cancel PID future if it's not going to happen
print('PID not found but EOF already found:', self.label) print('PID not found but EOF already found:', self.label)
self.pid_fut.cancel() self._pid_fut.cancel()
await super().process_out(lines, eof) await super().process_out(lines, eof)
async def _kill_cmd(self, sig): async def _kill_cmd(self, sig):
"""Send signal to command by running ssh kill -$sig $PID.""" """Send signal to command by running ssh kill -$sig $PID."""
cmd_parts = self._ssh_cmd([ cmd_parts = self._ssh_cmd([
'kill', '-' + sig, str(self.pid_fut.result()) 'kill', '-' + sig, str(self._pid_fut.result())
]) ])
proc = await asyncio.create_subprocess_exec(*cmd_parts) proc = await asyncio.create_subprocess_exec(*cmd_parts)
await proc.wait() await proc.wait()
...@@ -288,7 +292,9 @@ class SimpleRemoteComponent(SimpleComponent): ...@@ -288,7 +292,9 @@ class SimpleRemoteComponent(SimpleComponent):
class Executor(object): class Executor(object):
ip = None
def __init__(self):
self.ip = None
def create_component(self, label, parts, **kwargs) -> SimpleComponent: def create_component(self, label, parts, **kwargs) -> SimpleComponent:
raise NotImplementedError('Please Implement this method') raise NotImplementedError('Please Implement this method')
...@@ -354,6 +360,8 @@ class LocalExecutor(Executor): ...@@ -354,6 +360,8 @@ class LocalExecutor(Executor):
class RemoteExecutor(Executor): class RemoteExecutor(Executor):
def __init__(self, host_name, workdir): def __init__(self, host_name, workdir):
super().__init__()
self.host_name = host_name self.host_name = host_name
self.cwd = workdir self.cwd = workdir
self.ssh_extra_args = [] self.ssh_extra_args = []
......
...@@ -29,7 +29,7 @@ import typing as tp ...@@ -29,7 +29,7 @@ import typing as tp
from simbricks.exectools import Executor, SimpleComponent from simbricks.exectools import Executor, SimpleComponent
from simbricks.experiment.experiment_environment import ExpEnv from simbricks.experiment.experiment_environment import ExpEnv
from simbricks.experiment.experiment_output import ExpOutput from simbricks.experiment.experiment_output import ExpOutput
from simbricks.proxy import NetProxyConnecter, NetProxyListener, SimProxy from simbricks.proxy import NetProxyConnecter, NetProxyListener
from simbricks.simulators import ( from simbricks.simulators import (
HostSim, I40eMultiNIC, NetSim, NICSim, PCIDevSim, Simulator HostSim, I40eMultiNIC, NetSim, NICSim, PCIDevSim, Simulator
) )
...@@ -43,27 +43,29 @@ class Experiment(object): ...@@ -43,27 +43,29 @@ class Experiment(object):
Holds information about the simulators to run and paramaters to configure Holds information about the simulators to run and paramaters to configure
the experiment. the experiment.
""" """
name: str
"""This experiment's name. Can be used to filter multiple experiments to be def __init__(self, name: str, timeout: int = 0):
run."""
timeout: int
"""Timeout for experiment in seconds."""
checkpoint = False
"""Whether to use checkpoints in experiment.
Can for example be used to speed up booting a host simulator by first
running in a less accurate mode. Before we then start the application we are
interested in, a checkpoint is taken and the simulator shut down. Then, the
simulator is restored in the accurate mode using this checkpoint."""
no_simbricks = False
"""`true` - No simbricks adapters are used in the simulators."""
hosts: tp.List[HostSim] = []
pcidevs: tp.List[PCIDevSim] = []
networks: tp.List[NetSim] = []
metadata = {}
def __init__(self, name: str):
self.name = name self.name = name
"""
This experiment's name. Can be used to filter multiple experiments to be
run.
"""
self.timeout = timeout
"""Timeout for experiment in seconds."""
self.checkpoint = False
"""Whether to use checkpoints in experiment.
Can for example be used to speed up booting a host simulator by first
running in a less accurate mode. Before we then start the application we
are interested in, a checkpoint is taken and the simulator shut down.
Then, the simulator is restored in the accurate mode using this
checkpoint."""
self.no_simbricks = False
"""`true` - No simbricks adapters are used in the simulators."""
self.hosts: tp.List[HostSim] = []
self.pcidevs: tp.List[PCIDevSim] = []
self.networks: tp.List[NetSim] = []
self.metadata = {}
def add_host(self, sim: HostSim): def add_host(self, sim: HostSim):
for h in self.hosts: for h in self.hosts:
...@@ -108,25 +110,21 @@ class Experiment(object): ...@@ -108,25 +110,21 @@ class Experiment(object):
class DistributedExperiment(Experiment): class DistributedExperiment(Experiment):
"""Describes a distributed simulation experiment.""" """Describes a distributed simulation experiment."""
num_hosts = 1
"""Number of hosts to use."""
host_mapping: tp.Dict[Simulator, int]
"""Mapping from simulator to host ID."""
proxies_listen: tp.List[NetProxyListener]
proxies_connect: tp.List[NetProxyConnecter]
def __init__(self, name: str, num_hosts: int): def __init__(self, name: str, num_hosts: int):
self.num_hosts = num_hosts
self.host_mapping = {}
self.proxies_listen = []
self.proxies_connect = []
super().__init__(name) super().__init__(name)
self.num_hosts = num_hosts
"""Number of hosts to use."""
self.host_mapping: tp.Dict[Simulator, int] = {}
"""Mapping from simulator to host ID."""
self.proxies_listen: tp.List[NetProxyListener] = []
self.proxies_connect: tp.List[NetProxyConnecter] = []
def add_proxy(self, proxy: SimProxy): def add_proxy(self, proxy: tp.Union[NetProxyListener, NetProxyConnecter]):
if proxy.listen: if proxy.listen:
self.proxies_listen.append(proxy) self.proxies_listen.append(tp.cast(NetProxyListener, proxy))
else: else:
self.proxies_connect.append(proxy) self.proxies_connect.append(tp.cast(NetProxyConnecter, proxy))
def all_simulators(self): def all_simulators(self):
return itertools.chain( return itertools.chain(
...@@ -152,7 +150,7 @@ T = tp.TypeVar('T', bound=Experiment) ...@@ -152,7 +150,7 @@ T = tp.TypeVar('T', bound=Experiment)
class ExperimentBaseRunner(tp.Generic[T]): class ExperimentBaseRunner(tp.Generic[T]):
def __init__(self, exp: T, env: ExpEnv, verbose: bool): def __init__(self, exp: T, env: ExpEnv, verbose: bool):
self.exp = exp self.exp: T = exp
self.env = env self.env = env
self.verbose = verbose self.verbose = verbose
self.out = ExpOutput(exp) self.out = ExpOutput(exp)
......
...@@ -24,6 +24,7 @@ from __future__ import annotations ...@@ -24,6 +24,7 @@ from __future__ import annotations
import io import io
import tarfile import tarfile
import typing as tp
class AppConfig(object): class AppConfig(object):
...@@ -47,25 +48,27 @@ class AppConfig(object): ...@@ -47,25 +48,27 @@ class AppConfig(object):
class NodeConfig(object): class NodeConfig(object):
"""Manages the configuration for a node."""
sim = 'qemu' def __init__(self):
"""Name of simulator to run.""" """Manages the configuration for a node."""
ip = '10.0.0.1' self.sim = 'qemu'
"""IP address.""" """Name of simulator to run."""
prefix = 24 self.ip = '10.0.0.1'
"""IP prefix.""" """IP address."""
cores = 1 self.prefix = 24
"""Number of cores to be simulated.""" """IP prefix."""
memory = 8 * 1024 self.cores = 1
"""Amount of system memory in MB.""" """Number of cores to be simulated."""
disk_image = 'base' self.memory = 8 * 1024
"""Disk image to use.""" """Amount of system memory in MB."""
app: AppConfig = None self.disk_image = 'base'
"""App to be run on simulated host.""" """Disk image to use."""
mtu = 1500 self.mtu = 1500
"""Networking MTU.""" """Networking MTU."""
nockp = 0 self.nockp = 0
"""Do not make checkpoint in Gem5.""" """Do not make checkpoint in Gem5."""
self.app: tp.Optional[AppConfig] = None
"""App to be run on simulated host."""
def config_str(self): def config_str(self):
if self.sim == 'qemu': if self.sim == 'qemu':
...@@ -131,9 +134,10 @@ class NodeConfig(object): ...@@ -131,9 +134,10 @@ class NodeConfig(object):
class LinuxNode(NodeConfig): class LinuxNode(NodeConfig):
ifname = 'eth0'
def __init__(self): def __init__(self):
super().__init__()
self.ifname = 'eth0'
self.drivers = [] self.drivers = []
self.force_mac_addr = None self.force_mac_addr = None
...@@ -181,10 +185,13 @@ class E1000LinuxNode(LinuxNode): ...@@ -181,10 +185,13 @@ class E1000LinuxNode(LinuxNode):
class MtcpNode(NodeConfig): class MtcpNode(NodeConfig):
disk_image = 'mtcp'
pci_dev = '0000:00:02.0' def __init__(self):
memory = 16 * 1024 super().__init__()
num_hugepages = 4096 self.disk_image = 'mtcp'
self.pci_dev = '0000:00:02.0'
self.memory = 16 * 1024
self.num_hugepages = 4096
def prepare_pre_cp(self): def prepare_pre_cp(self):
return super().prepare_pre_cp() + [ return super().prepare_pre_cp() + [
...@@ -231,12 +238,15 @@ class MtcpNode(NodeConfig): ...@@ -231,12 +238,15 @@ class MtcpNode(NodeConfig):
class TASNode(NodeConfig): class TASNode(NodeConfig):
disk_image = 'tas'
pci_dev = '0000:00:02.0' def __init__(self):
memory = 16 * 1024 super().__init__()
num_hugepages = 4096 self.disk_image = 'tas'
fp_cores = 1 self.pci_dev = '0000:00:02.0'
preload = True self.memory = 16 * 1024
self.num_hugepages = 4096
self.fp_cores = 1
self.preload = True
def prepare_pre_cp(self): def prepare_pre_cp(self):
return super().prepare_pre_cp() + [ return super().prepare_pre_cp() + [
...@@ -325,6 +335,7 @@ class CorundumDCTCPNode(NodeConfig): ...@@ -325,6 +335,7 @@ class CorundumDCTCPNode(NodeConfig):
class LinuxFEMUNode(NodeConfig): class LinuxFEMUNode(NodeConfig):
def __init__(self): def __init__(self):
super().__init__()
self.drivers = ['nvme'] self.drivers = ['nvme']
def prepare_post_cp(self): def prepare_post_cp(self):
...@@ -355,8 +366,11 @@ class DctcpServer(AppConfig): ...@@ -355,8 +366,11 @@ class DctcpServer(AppConfig):
class DctcpClient(AppConfig): class DctcpClient(AppConfig):
server_ip = '192.168.64.1'
is_last = False def __init__(self):
super().__init__()
self.server_ip = '192.168.64.1'
self.is_last = False
def run_cmds(self, node): def run_cmds(self, node):
if self.is_last: if self.is_last:
...@@ -374,7 +388,10 @@ class DctcpClient(AppConfig): ...@@ -374,7 +388,10 @@ class DctcpClient(AppConfig):
class PingClient(AppConfig): class PingClient(AppConfig):
server_ip = '192.168.64.1'
def __init__(self):
super().__init__()
self.server_ip = '192.168.64.1'
def run_cmds(self, node): def run_cmds(self, node):
return [f'ping {self.server_ip} -c 100'] return [f'ping {self.server_ip} -c 100']
...@@ -393,9 +410,12 @@ class IperfUDPServer(AppConfig): ...@@ -393,9 +410,12 @@ class IperfUDPServer(AppConfig):
class IperfTCPClient(AppConfig): class IperfTCPClient(AppConfig):
server_ip = '10.0.0.1'
procs = 1 def __init__(self):
is_last = False super().__init__()
self.server_ip = '10.0.0.1'
self.procs = 1
self.is_last = False
def run_cmds(self, node): def run_cmds(self, node):
...@@ -412,9 +432,12 @@ class IperfTCPClient(AppConfig): ...@@ -412,9 +432,12 @@ class IperfTCPClient(AppConfig):
class IperfUDPClient(AppConfig): class IperfUDPClient(AppConfig):
server_ip = '10.0.0.1'
rate = '150m' def __init__(self):
is_last = False super().__init__()
self.server_ip = '10.0.0.1'
self.rate = '150m'
self.is_last = False
def run_cmds(self, node): def run_cmds(self, node):
cmds = [ cmds = [
...@@ -431,9 +454,12 @@ class IperfUDPClient(AppConfig): ...@@ -431,9 +454,12 @@ class IperfUDPClient(AppConfig):
class IperfUDPShortClient(AppConfig): class IperfUDPShortClient(AppConfig):
server_ip = '10.0.0.1'
rate = '150m' def __init__(self):
is_last = False super().__init__()
self.server_ip = '10.0.0.1'
self.rate = '150m'
self.is_last = False
def run_cmds(self, node): def run_cmds(self, node):
cmds = ['sleep 1', 'iperf -c ' + self.server_ip + ' -u -n 1 '] cmds = ['sleep 1', 'iperf -c ' + self.server_ip + ' -u -n 1 ']
...@@ -442,16 +468,22 @@ class IperfUDPShortClient(AppConfig): ...@@ -442,16 +468,22 @@ class IperfUDPShortClient(AppConfig):
class IperfUDPClientSleep(AppConfig): class IperfUDPClientSleep(AppConfig):
server_ip = '10.0.0.1'
rate = '150m' def __init__(self):
super().__init__()
self.server_ip = '10.0.0.1'
self.rate = '150m'
def run_cmds(self, node): def run_cmds(self, node):
return ['sleep 1', 'sleep 10'] return ['sleep 1', 'sleep 10']
class NoTraffic(AppConfig): class NoTraffic(AppConfig):
is_sleep = 1
is_server = 0 def __init__(self):
super().__init__()
self.is_sleep = 1
self.is_server = 0
def run_cmds(self, node): def run_cmds(self, node):
cmds = [] cmds = []
...@@ -474,9 +506,12 @@ class NetperfServer(AppConfig): ...@@ -474,9 +506,12 @@ class NetperfServer(AppConfig):
class NetperfClient(AppConfig): class NetperfClient(AppConfig):
server_ip = '10.0.0.1'
duration_tp = 10 def __init__(self):
duration_lat = 10 super().__init__()
self.server_ip = '10.0.0.1'
self.duration_tp = 10
self.duration_lat = 10
def run_cmds(self, node): def run_cmds(self, node):
return [ return [
...@@ -491,7 +526,10 @@ class NetperfClient(AppConfig): ...@@ -491,7 +526,10 @@ class NetperfClient(AppConfig):
class VRReplica(AppConfig): class VRReplica(AppConfig):
index = 0
def __init__(self):
super().__init__()
self.index = 0
def run_cmds(self, node): def run_cmds(self, node):
return [ return [
...@@ -501,7 +539,10 @@ class VRReplica(AppConfig): ...@@ -501,7 +539,10 @@ class VRReplica(AppConfig):
class VRClient(AppConfig): class VRClient(AppConfig):
server_ips = []
def __init__(self):
super().__init__()
self.server_ips = []
def run_cmds(self, node): def run_cmds(self, node):
cmds = [] cmds = []
...@@ -515,7 +556,10 @@ class VRClient(AppConfig): ...@@ -515,7 +556,10 @@ class VRClient(AppConfig):
class NOPaxosReplica(AppConfig): class NOPaxosReplica(AppConfig):
index = 0
def __init__(self):
super().__init__()
self.index = 0
def run_cmds(self, node): def run_cmds(self, node):
return [ return [
...@@ -525,9 +569,12 @@ class NOPaxosReplica(AppConfig): ...@@ -525,9 +569,12 @@ class NOPaxosReplica(AppConfig):
class NOPaxosClient(AppConfig): class NOPaxosClient(AppConfig):
server_ips = []
is_last = False def __init__(self):
use_ehseq = False super().__init__()
self.server_ips = []
self.is_last = False
self.use_ehseq = False
def run_cmds(self, node): def run_cmds(self, node):
cmds = [] cmds = []
...@@ -555,10 +602,13 @@ class NOPaxosSequencer(AppConfig): ...@@ -555,10 +602,13 @@ class NOPaxosSequencer(AppConfig):
class RPCServer(AppConfig): class RPCServer(AppConfig):
port = 1234
threads = 1 def __init__(self):
max_flows = 1234 super().__init__()
max_bytes = 1024 self.port = 1234
self.threads = 1
self.max_flows = 1234
self.max_bytes = 1024
def run_cmds(self, node): def run_cmds(self, node):
exe = 'echoserver_linux' if not isinstance(node, MtcpNode) else \ exe = 'echoserver_linux' if not isinstance(node, MtcpNode) else \
...@@ -573,16 +623,19 @@ class RPCServer(AppConfig): ...@@ -573,16 +623,19 @@ class RPCServer(AppConfig):
class RPCClient(AppConfig): class RPCClient(AppConfig):
server_ip = '10.0.0.1'
port = 1234 def __init__(self):
threads = 1 super().__init__()
max_flows = 128 self.server_ip = '10.0.0.1'
max_bytes = 1024 self.port = 1234
max_pending = 1 self.threads = 1
openall_delay = 2 self.max_flows = 128
max_msgs_conn = 0 self.max_bytes = 1024
max_pend_conns = 8 self.max_pending = 1
time = 25 self.openall_delay = 2
self.max_msgs_conn = 0
self.max_pend_conns = 8
self.time = 25
def run_cmds(self, node): def run_cmds(self, node):
exe = 'testclient_linux' if not isinstance(node, MtcpNode) else \ exe = 'testclient_linux' if not isinstance(node, MtcpNode) else \
...@@ -603,10 +656,13 @@ class RPCClient(AppConfig): ...@@ -603,10 +656,13 @@ class RPCClient(AppConfig):
class HTTPD(AppConfig): class HTTPD(AppConfig):
threads = 1
file_size = 64 def __init__(self):
mtcp_config = 'lighttpd.conf' super().__init__()
httpd_dir: str # TODO added because doesn't originally exist self.threads = 1
self.file_size = 64
self.mtcp_config = 'lighttpd.conf'
self.httpd_dir = '' # TODO added because doesn't originally exist
def prepare_pre_cp(self): def prepare_pre_cp(self):
return [ return [
...@@ -628,16 +684,25 @@ class HTTPD(AppConfig): ...@@ -628,16 +684,25 @@ class HTTPD(AppConfig):
class HTTPDLinux(HTTPD): class HTTPDLinux(HTTPD):
httpd_dir = '/root/mtcp/apps/lighttpd-mtlinux'
def __init__(self):
super().__init__()
self.httpd_dir = '/root/mtcp/apps/lighttpd-mtlinux'
class HTTPDLinuxRPO(HTTPD): class HTTPDLinuxRPO(HTTPD):
httpd_dir = '/root/mtcp/apps/lighttpd-mtlinux-rop'
def __init__(self):
super().__init__()
self.httpd_dir = '/root/mtcp/apps/lighttpd-mtlinux-rop'
class HTTPDMtcp(HTTPD): class HTTPDMtcp(HTTPD):
httpd_dir = '/root/mtcp/apps/lighttpd-mtcp'
mtcp_config = 'm-lighttpd.conf' def __init__(self):
super().__init__()
self.httpd_dir = '/root/mtcp/apps/lighttpd-mtcp'
self.mtcp_config = 'm-lighttpd.conf'
def prepare_pre_cp(self): def prepare_pre_cp(self):
return super().prepare_pre_cp() + [ return super().prepare_pre_cp() + [
...@@ -651,13 +716,16 @@ class HTTPDMtcp(HTTPD): ...@@ -651,13 +716,16 @@ class HTTPDMtcp(HTTPD):
class HTTPC(AppConfig): class HTTPC(AppConfig):
server_ip = '10.0.0.1'
conns = 1000 def __init__(self):
#requests = 10000000 super().__init__()
requests = 10000 self.server_ip = '10.0.0.1'
threads = 1 self.conns = 1000
url = '/file' #self.requests = 10000000
ab_dir: str # TODO added because doesn't originally exist self.requests = 10000
self.threads = 1
self.url = '/file'
self.ab_dir = '' # TODO added because doesn't originally exist
def run_cmds(self, node): def run_cmds(self, node):
return [ return [
...@@ -670,11 +738,17 @@ class HTTPC(AppConfig): ...@@ -670,11 +738,17 @@ class HTTPC(AppConfig):
class HTTPCLinux(HTTPC): class HTTPCLinux(HTTPC):
ab_dir = '/root/mtcp/apps/ab-linux'
def __init__(self):
super().__init__()
self.ab_dir = '/root/mtcp/apps/ab-linux'
class HTTPCMtcp(HTTPC): class HTTPCMtcp(HTTPC):
ab_dir = '/root/mtcp/apps/ab-mtcp'
def __init__(self):
super().__init__()
self.ab_dir = '/root/mtcp/apps/ab-mtcp'
def prepare_pre_cp(self): def prepare_pre_cp(self):
return super().prepare_pre_cp() + [ return super().prepare_pre_cp() + [
...@@ -690,10 +764,13 @@ class MemcachedServer(AppConfig): ...@@ -690,10 +764,13 @@ class MemcachedServer(AppConfig):
class MemcachedClient(AppConfig): class MemcachedClient(AppConfig):
server_ips = ['10.0.0.1']
threads = 1 def __init__(self):
concurrency = 1 super().__init__()
throughput = '1k' self.server_ips = ['10.0.0.1']
self.threads = 1
self.concurrency = 1
self.throughput = '1k'
def run_cmds(self, node): def run_cmds(self, node):
servers = [ip + ':11211' for ip in self.server_ips] servers = [ip + ':11211' for ip in self.server_ips]
......
...@@ -20,14 +20,19 @@ ...@@ -20,14 +20,19 @@
# 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.
from simbricks.simulators import Simulator import typing as tp
from simbricks.simulators import NICSim, Simulator
class SimProxy(Simulator): class SimProxy(Simulator):
name = ''
# set by the experiment runner def __init__(self):
ip = '' super().__init__()
listen = False self.name = ''
# set by the experiment runner
self.ip = ''
self.listen = False
def full_name(self): def full_name(self):
return 'proxy.' + self.name return 'proxy.' + self.name
...@@ -35,29 +40,29 @@ class SimProxy(Simulator): ...@@ -35,29 +40,29 @@ class SimProxy(Simulator):
class NetProxy(SimProxy): class NetProxy(SimProxy):
"""Proxy for connections between NICs and networks.""" """Proxy for connections between NICs and networks."""
# List of tuples (nic, with_listener)
nics = None
# List of tuples ((netL,netC), with_listener) def __init__(self):
n2ns = None super().__init__()
self.nics: tp.List[tp.Tuple[NICSim, bool]] = []
# Shared memory size in GB """List of tuples (nic, with_listener)"""
shm_size = 2048 self.n2ns: tp.List[tp.Tuple[tp.Tuple[NetProxyListener,
NetProxyConnecter],
bool]] = []
"""List of tuples ((netL,netC), with_listener)"""
self.shm_size = 2048
"""Shared memory size in GB"""
def start_delay(self): def start_delay(self):
return 10 return 10
class NetProxyListener(NetProxy): class NetProxyListener(NetProxy):
port = 12345
connecter = None
listen = True
def __init__(self): def __init__(self):
super().__init__() super().__init__()
self.port = 12345
self.connecter = None
self.listen = True self.listen = True
self.nics = []
self.n2ns = []
def add_nic(self, nic): def add_nic(self, nic):
self.nics.append((nic, True)) self.nics.append((nic, True))
...@@ -119,9 +124,8 @@ class NetProxyListener(NetProxy): ...@@ -119,9 +124,8 @@ class NetProxyListener(NetProxy):
class NetProxyConnecter(NetProxy): class NetProxyConnecter(NetProxy):
listener = None
def __init__(self, listener): def __init__(self, listener: NetProxyListener):
super().__init__() super().__init__()
self.listener = listener self.listener = listener
listener.connecter = self listener.connecter = self
......
...@@ -80,11 +80,16 @@ class Simulator(object): ...@@ -80,11 +80,16 @@ class Simulator(object):
class PCIDevSim(Simulator): class PCIDevSim(Simulator):
name = '' """Base class for PCIe device simulators."""
sync_mode = 0
start_tick = 0 def __init__(self):
sync_period = 500 super().__init__()
pci_latency = 500
self.name = ''
self.sync_mode = 0
self.start_tick = 0
self.sync_period = 500
self.pci_latency = 500
def full_name(self): def full_name(self):
return 'dev.' + self.name return 'dev.' + self.name
...@@ -97,9 +102,14 @@ class PCIDevSim(Simulator): ...@@ -97,9 +102,14 @@ class PCIDevSim(Simulator):
class NICSim(PCIDevSim): class NICSim(PCIDevSim):
network = None """Base class for NIC simulators."""
mac = None
eth_latency = 500 def __init__(self):
super().__init__()
self.network: tp.Optional[NetSim] = None
self.mac: tp.Optional[str] = None
self.eth_latency = 500
def set_network(self, net: NetSim): def set_network(self, net: NetSim):
self.network = net self.network = net
...@@ -134,15 +144,19 @@ class NICSim(PCIDevSim): ...@@ -134,15 +144,19 @@ class NICSim(PCIDevSim):
class NetSim(Simulator): class NetSim(Simulator):
"""Base class for network simulators.""" """Base class for network simulators."""
name = ''
opt = '' def __init__(self):
sync_mode = 0 super().__init__()
sync_period = 500
eth_latency = 500 self.name = ''
nics: list[NICSim] = [] self.opt = ''
hosts_direct: list[HostSim] = [] self.sync_mode = 0
net_listen: list[NetSim] = [] self.sync_period = 500
net_connect: list[NetSim] = [] self.eth_latency = 500
self.nics: list[NICSim] = []
self.hosts_direct: list[HostSim] = []
self.net_listen: list[NetSim] = []
self.net_connect: list[NetSim] = []
def full_name(self): def full_name(self):
return 'net.' + self.name return 'net.' + self.name
...@@ -179,25 +193,27 @@ class NetSim(Simulator): ...@@ -179,25 +193,27 @@ class NetSim(Simulator):
class HostSim(Simulator): class HostSim(Simulator):
node_config: NodeConfig """Base class for host simulators."""
"""Config for the simulated host. """
name = ''
wait = False
"""
`True` - Wait for process of simulator to exit.
`False` - Don't wait and instead stop the process.
"""
sleep = 0
cpu_freq = '8GHz'
sync_mode = 0
sync_period = 500
pci_latency = 500
def __init__(self): def __init__(self):
super().__init__()
self.node_config: tp.Optional[NodeConfig] = None
"""Config for the simulated host. """
self.name = ''
self.wait = False
"""
`True` - Wait for process of simulator to exit.
`False` - Don't wait and instead stop the process.
"""
self.sleep = 0
self.cpu_freq = '8GHz'
self.sync_mode = 0
self.sync_period = 500
self.pci_latency = 500
self.pcidevs: tp.List[PCIDevSim] = [] self.pcidevs: tp.List[PCIDevSim] = []
self.net_directs: tp.List[NetSim] = [] self.net_directs: tp.List[NetSim] = []
super().__init__()
def full_name(self): def full_name(self):
return 'host.' + self.name return 'host.' + self.name
...@@ -229,8 +245,13 @@ class HostSim(Simulator): ...@@ -229,8 +245,13 @@ class HostSim(Simulator):
class QemuHost(HostSim): class QemuHost(HostSim):
sync = False """Qemu host simulator."""
cpu_freq = '4GHz'
def __init__(self):
super().__init__()
self.sync = False
self.cpu_freq = '4GHz'
def resreq_cores(self): def resreq_cores(self):
if self.sync: if self.sync:
...@@ -291,12 +312,13 @@ class QemuHost(HostSim): ...@@ -291,12 +312,13 @@ class QemuHost(HostSim):
class Gem5Host(HostSim): class Gem5Host(HostSim):
cpu_type_cp = 'X86KvmCPU' """Gem5 host simulator."""
cpu_type = 'TimingSimpleCPU'
sys_clock = '1GHz'
def __init__(self): def __init__(self):
super().__init__() super().__init__()
self.cpu_type_cp = 'X86KvmCPU'
self.cpu_type = 'TimingSimpleCPU'
self.sys_clock = '1GHz'
self.extra_main_args = [] self.extra_main_args = []
self.extra_config_args = [] self.extra_config_args = []
self.variant = 'fast' self.variant = 'fast'
...@@ -369,7 +391,10 @@ class Gem5Host(HostSim): ...@@ -369,7 +391,10 @@ class Gem5Host(HostSim):
class CorundumVerilatorNIC(NICSim): class CorundumVerilatorNIC(NICSim):
clock_freq = 250 # MHz
def __init__(self):
super().__init__()
self.clock_freq = 250 # MHz
def resreq_mem(self): def resreq_mem(self):
# this is a guess # this is a guess
...@@ -394,7 +419,10 @@ class I40eNIC(NICSim): ...@@ -394,7 +419,10 @@ class I40eNIC(NICSim):
class E1000NIC(NICSim): class E1000NIC(NICSim):
debug = False
def __init__(self):
super().__init__()
self.debug = False
def run_cmd(self, env): def run_cmd(self, env):
cmd = self.basic_run_cmd(env, '/e1000_gem5/e1000_gem5') cmd = self.basic_run_cmd(env, '/e1000_gem5/e1000_gem5')
...@@ -404,12 +432,11 @@ class E1000NIC(NICSim): ...@@ -404,12 +432,11 @@ class E1000NIC(NICSim):
class MultiSubNIC(NICSim): class MultiSubNIC(NICSim):
name = ''
multinic = None
def __init__(self, mn): def __init__(self, mn):
self.multinic = mn
super().__init__() super().__init__()
self.name = ''
self.multinic = mn
def full_name(self): def full_name(self):
return self.multinic.full_name() + '.' + self.name return self.multinic.full_name() + '.' + self.name
...@@ -422,11 +449,11 @@ class MultiSubNIC(NICSim): ...@@ -422,11 +449,11 @@ class MultiSubNIC(NICSim):
class I40eMultiNIC(Simulator): class I40eMultiNIC(Simulator):
name = ''
def __init__(self): def __init__(self):
self.subnics = []
super().__init__() super().__init__()
self.subnics = []
self.name = ''
def create_subnic(self): def create_subnic(self):
sn = MultiSubNIC(self) sn = MultiSubNIC(self)
...@@ -475,7 +502,10 @@ class WireNet(NetSim): ...@@ -475,7 +502,10 @@ class WireNet(NetSim):
class SwitchNet(NetSim): class SwitchNet(NetSim):
sync = True
def __init__(self):
super().__init__()
self.sync = True
def run_cmd(self, env): def run_cmd(self, env):
cmd = env.repodir + '/sims/net/switch/net_switch' cmd = env.repodir + '/sims/net/switch/net_switch'
...@@ -503,8 +533,11 @@ class SwitchNet(NetSim): ...@@ -503,8 +533,11 @@ class SwitchNet(NetSim):
class TofinoNet(NetSim): class TofinoNet(NetSim):
tofino_log_path = '/tmp/model.ldjson'
sync = True def __init__(self):
super().__init__()
self.tofino_log_path = '/tmp/model.ldjson'
self.sync = True
def run_cmd(self, env): def run_cmd(self, env):
cmd = f'{env.repodir}/sims/net/tofino/tofino' cmd = f'{env.repodir}/sims/net/tofino/tofino'
......
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