Commit 0225a17b authored by Hejing Li's avatar Hejing Li Committed by Jonas Kaufmann
Browse files

add run object to link specification and simulator class

parent f819b1f1
import simbricks.orchestration.experiments as exp
import simbricks.splitsim.specification as spec
import simbricks.splitsim.impl as impl
import simbricks.splitsim.runobj as runobj
"""
Netperf Example:
One Client: Host_0, One Server: Host1 connected through a switch
HOST0 -- NIC0 ------ SWITCH ------ NIC1 -- HOST1
This scripts generates the experiments with all the combinations of different execution modes
"""
# host_types = ['qemu', 'gem5', 'qt']
host_types = ['qemu']
nic_types = ['bm', 'vr']
net_types = ['switch']
experiments = []
system = spec.System()
# create a host instance and a NIC instance then install the NIC on the host
host0 = spec.LinuxHost(system)
nic0 = spec.CorundumNIC(system)
host0.nic_driver = ['/tmp/guest/mqnic.ko']
host0.ip = '10.0.0.1'
pcichannel0 = spec.PCI(system)
pcichannel0.install(host0, nic0)
host1 = spec.LinuxHost(system)
nic1 = spec.CorundumNIC(system)
host1.nic_driver = ['/tmp/guest/mqnic.ko']
host1.ip = '10.0.0.2'
pcichannel1 = spec.PCI(system)
pcichannel1.install(host1, nic1)
port0 = spec.NetDev()
port1 = spec.NetDev()
switch = spec.Switch(system)
switch.install_netdev(port0)
switch.install_netdev(port1)
ethchannel0 = spec.Eth(system)
ethchannel0.install(nic0, port0)
ethchannel1 = spec.Eth(system)
ethchannel1.install(nic1, port1)
# configure the software to run on the host
host0.app = spec.NetperfClient('10.0.0.2')
host1.app = spec.NetperfServer()
"""
Execution Config
"""
for host_type in host_types:
for nic_type in nic_types:
for net_type in net_types:
e = exp.Experiment(
'n-' + host_type + '-' + nic_type + '-' + net_type
)
allobj = runobj.AllObj()
# Host
if host_type == 'gem5':
host_sim = impl.Gem5Sim
elif host_type == 'qemu':
def qemu_sim(e):
h = impl.QemuSim(e)
h.sync = False
return h
host_sim = qemu_sim
elif host_type == 'qt':
host_sim = impl.QemuSim
else:
raise NameError(host_type)
# NIC
if nic_type == 'bm':
nic_sim = impl.CorundumBMNICSim
elif nic_type == 'vr':
nic_sim = impl.CorundumVerilatorNICSim
else:
raise NameError(nic_type)
# Net
if net_type == 'switch':
net_sim = impl.SwitchBMSim
else:
raise NameError(net_type)
host_inst0 = host_sim(e, allobj)
host_inst0.add(host0)
host_inst1 = host_sim(e, allobj)
host_inst1.add(host1)
nic_inst0 = nic_sim(e, allobj)
nic_inst0.add(nic0)
nic_inst1 = nic_sim(e, allobj)
nic_inst1.add(nic1)
net_inst = net_sim(e, allobj)
net_inst.add(switch)
print(e.name + " all simulators:")
sims = e.all_simulators()
for sim in sims:
print(sim)
experiments.append(e)
\ No newline at end of file
......@@ -60,6 +60,7 @@ class ExperimentBaseRunner(ABC):
graph = {}
for sim in sims:
deps = sim.dependencies() + sim.extra_deps
print(f'deps of {sim}: {sim.dependencies()}')
graph[sim] = set()
for d in deps:
graph[sim].add(d)
......@@ -196,6 +197,7 @@ class ExperimentBaseRunner(ABC):
try:
self.out.set_start()
graph = self.sim_graph()
print(graph)
ts = graphlib.TopologicalSorter(graph)
ts.prepare()
while ts.is_active():
......
......@@ -5,6 +5,7 @@ import itertools
import simbricks.splitsim.specification as spec
import simbricks.orchestration.experiments as exp
from simbricks.orchestration.experiment.experiment_environment_new import ExpEnv
import tarfile
class Simulator(object):
"""Base class for all simulators."""
......@@ -102,7 +103,7 @@ class NICSim(PCIDevSim):
def add(self, nic: spec.NIC):
self.nics.append(nic)
nic.sim = self
# nic.sim = self
self.experiment.add_nic(self)
self.name = f'{nic.id}'
......@@ -178,7 +179,7 @@ class HostSim(Simulator):
def __init__(self, e: exp.Experiment):
super().__init__(e)
self.experiment = e
self.hosts: tp.List[spec.Host] = []
self.hosts: spec.Host = []
# need to change type of list to PCI dev
self.pcidevs: tp.List[spec.NIC] = []
......@@ -197,19 +198,44 @@ class HostSim(Simulator):
for h in self.hosts:
for dev in h.nics:
deps.append(dev.sim)
print(f'host deps: {deps}')
return deps
def add(self, host: spec.Host):
self.hosts.append(host)
self.hosts = host
self.pcidevs = host.nics
host.sim = self
self.name = f'{self.hosts[0].id}'
# host.sim = self
self.name = f'{self.hosts.id}'
self.sync_period = host.sync_period
self.pci_latency = host.pci_channel.latency
self.sync = host.sync
self.experiment.add_host(self)
def config_str(self) -> str:
return []
def make_tar(self, path: str) -> None:
with tarfile.open(path, 'w:') as tar:
# add main run script
cfg_i = tarfile.TarInfo('guest/run.sh')
cfg_i.mode = 0o777
cfg_f = self.strfile(self.config_str())
cfg_f.seek(0, io.SEEK_END)
cfg_i.size = cfg_f.tell()
cfg_f.seek(0, io.SEEK_SET)
tar.addfile(tarinfo=cfg_i, fileobj=cfg_f)
cfg_f.close()
# add additional config files
for (n, f) in self.hosts.config_files().items():
f_i = tarfile.TarInfo('guest/' + n)
f_i.mode = 0o777
f.seek(0, io.SEEK_END)
f_i.size = f.tell()
f.seek(0, io.SEEK_SET)
tar.addfile(tarinfo=f_i, fileobj=f)
f.close()
def wait_terminate(self) -> bool:
return self.wait
......@@ -239,6 +265,15 @@ class Gem5Sim(HostSim):
def resreq_mem(self) -> int:
return 4096
def config_str(self) -> str:
cp_es = [] if self.nockp else ['m5 checkpoint']
exit_es = ['m5 exit']
es = self.hosts.prepare_pre_cp() + self.hosts.app.prepare_pre_cp(self) + cp_es + \
self.hosts.prepare_post_cp() + self.hosts.app.prepare_post_cp(self) + \
self.hosts.run_cmds() + self.hosts.cleanup_cmds() + exit_es
return '\n'.join(es)
def prep_cmds(self, env: ExpEnv) -> tp.List[str]:
cmds = [f'mkdir -p {env.gem5_cpdir(self)}']
if env.restore_cp and self.modify_checkpoint_tick:
......@@ -304,6 +339,14 @@ class QemuSim(HostSim):
def resreq_mem(self) -> int:
return 8192
def config_str(self) -> str:
cp_es = ['echo ready to checkpoint']
exit_es = ['poweroff -f']
es = self.hosts.prepare_pre_cp() + self.hosts.app.prepare_pre_cp(self) + cp_es + \
self.hosts.prepare_post_cp() + self.hosts.app.prepare_post_cp(self) + \
self.hosts.run_cmds() + self.hosts.cleanup_cmds() + exit_es
return '\n'.join(es)
def prep_cmds(self, env: ExpEnv) -> tp.List[str]:
return [
......@@ -375,13 +418,14 @@ class NetSim(Simulator):
def add(self, switch: spec.Switch):
self.switches.append(switch)
switch.sim = self
# switch.sim = self
self.experiment.add_network(self)
self.name = f'{switch.id}'
for s in self.switches:
for n in s.netdevs:
self.nicSim.append(n.net[0].sim)
for ndev in switch.netdevs:
self.nicSim.append(n.net[0].sim)
def connect_sockets(self, env: ExpEnv) -> tp.List[tp.Tuple[Simulator, str]]:
sockets = []
......
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] = []
......@@ -67,7 +67,7 @@ class Host(SimObject):
self.pci_channel: PCI = None
self.nics: tp.List[NIC] = []
self.sim = None
# self.sim = None
self.nic_driver = ['i40e']
self.sync = True
......@@ -99,43 +99,6 @@ class Host(SimObject):
self.nockp = 0
"""Do not create a checkpoint in Gem5."""
def config_str(self) -> str:
import simbricks.splitsim.impl as impl
if type(self.sim) is impl.Gem5Sim :
cp_es = [] if self.nockp else ['m5 checkpoint']
exit_es = ['m5 exit']
else:
cp_es = ['echo ready to checkpoint']
exit_es = ['poweroff -f']
es = self.prepare_pre_cp() + self.app.prepare_pre_cp(self) + cp_es + \
self.prepare_post_cp() + self.app.prepare_post_cp(self) + \
self.run_cmds() + self.cleanup_cmds() + exit_es
return '\n'.join(es)
def make_tar(self, path: str) -> None:
with tarfile.open(path, 'w:') as tar:
# add main run script
cfg_i = tarfile.TarInfo('guest/run.sh')
cfg_i.mode = 0o777
cfg_f = self.strfile(self.config_str())
cfg_f.seek(0, io.SEEK_END)
cfg_i.size = cfg_f.tell()
cfg_f.seek(0, io.SEEK_SET)
tar.addfile(tarinfo=cfg_i, fileobj=cfg_f)
cfg_f.close()
# add additional config files
for (n, f) in self.config_files().items():
f_i = tarfile.TarInfo('guest/' + n)
f_i.mode = 0o777
f.seek(0, io.SEEK_END)
f_i.size = f.tell()
f.seek(0, io.SEEK_SET)
tar.addfile(tarinfo=f_i, fileobj=f)
f.close()
def run_cmds(self) -> tp.List[str]:
"""Commands to run on node."""
......@@ -205,7 +168,7 @@ class LinuxHost(Host):
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')}
......@@ -229,7 +192,7 @@ class NIC(SimObject):
self.mac: tp.Optional[str] = None
self.host: tp.List[Host] = []
self.net = [] # NIC or NetDev connected through eth channel
self.sim = None
# self.sim = None
class i40eNIC(NIC):
......@@ -256,7 +219,7 @@ class NetDev(SimObject):
self.mac: tp.Optional[str] = None
self.ip: tp.Optional[str] = None
self.net = [] # NIC or NetDev connected through eth channel
self.sim = None
# self.sim = None
class Switch(SimObject):
......@@ -271,7 +234,7 @@ class Switch(SimObject):
self.eth_latency = 500 # ns second
###
self.netdevs : tp.List[NetDev] = []
self.sim = None
# self.sim = None
def install_netdev(self, netdev: NetDev):
......
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