Commit 7549fa9e authored by Jonas Kaufmann's avatar Jonas Kaufmann Committed by Antoine Kaufmann
Browse files

pre-commit run -a

parent aac98df8
...@@ -23,15 +23,16 @@ ...@@ -23,15 +23,16 @@
# Allow own class to be used as type for a method's argument # Allow own class to be used as type for a method's argument
from __future__ import annotations from __future__ import annotations
from abc import ABCMeta, abstractmethod
import shutil
import pathlib import pathlib
import shutil
import typing as tp import typing as tp
from abc import ABCMeta, abstractmethod
import simbricks.exectools as exectools
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.experiments import Experiment from simbricks.experiments import Experiment
import simbricks.exectools as exectools
class Run(object): class Run(object):
...@@ -82,4 +83,4 @@ class Runtime(metaclass=ABCMeta): ...@@ -82,4 +83,4 @@ class Runtime(metaclass=ABCMeta):
@abstractmethod @abstractmethod
def start(self): def start(self):
pass pass
\ No newline at end of file
...@@ -23,12 +23,15 @@ ...@@ -23,12 +23,15 @@
import asyncio import asyncio
import pathlib import pathlib
import simbricks.proxy as proxy
from simbricks.exectools import Executor from simbricks.exectools import Executor
from simbricks.runtime.common import * from simbricks.runtime.common import *
import simbricks.experiments as exp import simbricks.experiments as exp
import simbricks.proxy as proxy
class DistributedSimpleRuntime(Runtime): class DistributedSimpleRuntime(Runtime):
def __init__(self, execs, verbose=False): def __init__(self, execs, verbose=False):
self.runnable = [] self.runnable = []
self.complete = [] self.complete = []
...@@ -42,8 +45,9 @@ class DistributedSimpleRuntime(Runtime): ...@@ -42,8 +45,9 @@ class DistributedSimpleRuntime(Runtime):
self.runnable.append(run) self.runnable.append(run)
async def do_run(self, run: Run): async def do_run(self, run: Run):
runner = exp.ExperimentDistributedRunner(self.execs, run.experiment, runner = exp.ExperimentDistributedRunner(
run.env, self.verbose) self.execs, run.experiment, run.env, self.verbose
)
for exec in self.execs: for exec in self.execs:
await run.prep_dirs(exec) await run.prep_dirs(exec)
await runner.prepare() await runner.prepare()
...@@ -62,9 +66,11 @@ class DistributedSimpleRuntime(Runtime): ...@@ -62,9 +66,11 @@ class DistributedSimpleRuntime(Runtime):
def auto_dist( def auto_dist(
e: Experiment, execs: tp.List[Executor], proxy_type: str = 'sockets' e: Experiment, execs: tp.List[Executor], proxy_type: str = 'sockets'
): ):
""" Converts an Experiment into a DistributedExperiment. Assigns network to """
executor zero, and then round-robin assignment of hosts to executors, Converts an Experiment into a DistributedExperiment.
while also assigning all nics for a host to the same executor.
Assigns network to executor zero, and then round-robin assignment of hosts
to executors, while also assigning all nics for a host to the same executor.
""" """
if len(execs) < 2: if len(execs) < 2:
...@@ -120,4 +126,4 @@ def auto_dist( ...@@ -120,4 +126,4 @@ def auto_dist(
for nic in e.nics: # TODO: e.nics does not exist in class Experiment for nic in e.nics: # TODO: e.nics does not exist in class Experiment
de.add_nic(nic) de.add_nic(nic)
return de return de
\ No newline at end of file
...@@ -24,9 +24,10 @@ import asyncio ...@@ -24,9 +24,10 @@ import asyncio
import pathlib import pathlib
from typing import Optional from typing import Optional
import simbricks.exectools as exectools
from simbricks.runtime.common import * from simbricks.runtime.common import *
import simbricks.experiments as exp import simbricks.experiments as exp
import simbricks.exectools as exectools
class LocalSimpleRuntime(Runtime): class LocalSimpleRuntime(Runtime):
......
...@@ -20,14 +20,16 @@ ...@@ -20,14 +20,16 @@
# 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 pickle
import os import os
import pathlib import pathlib
import pickle
import re import re
from simbricks.runtime.common import * from simbricks.runtime.common import *
class SlurmRuntime(Runtime): class SlurmRuntime(Runtime):
def __init__(self, slurmdir, args, verbose=False, cleanup=True): def __init__(self, slurmdir, args, verbose=False, cleanup=True):
self.runnable = [] self.runnable = []
self.slurmdir = slurmdir self.slurmdir = slurmdir
...@@ -42,7 +44,7 @@ class SlurmRuntime(Runtime): ...@@ -42,7 +44,7 @@ class SlurmRuntime(Runtime):
exp = run.experiment exp = run.experiment
e_idx = exp.name + f'-{run.index}' + '.exp' e_idx = exp.name + f'-{run.index}' + '.exp'
exp_path = os.path.join(self.slurmdir, e_idx) exp_path = os.path.join(self.slurmdir, e_idx)
log_idx = exp.name + f'-{run.index}' + '.log' log_idx = exp.name + f'-{run.index}' + '.log'
exp_log = os.path.join(self.slurmdir, log_idx) exp_log = os.path.join(self.slurmdir, log_idx)
...@@ -51,10 +53,10 @@ class SlurmRuntime(Runtime): ...@@ -51,10 +53,10 @@ class SlurmRuntime(Runtime):
print(exp_path) print(exp_path)
print(exp_log) print(exp_log)
print(exp_script) print(exp_script)
# write out pickled run # write out pickled run
with open(exp_path, 'wb') as f: with open(exp_path, 'wb') as f:
run.prereq = None # we don't want to pull in the prereq too run.prereq = None # we don't want to pull in the prereq too
pickle.dump(run, f) pickle.dump(run, f)
# create slurm batch script # create slurm batch script
......
...@@ -23,9 +23,10 @@ ...@@ -23,9 +23,10 @@
import typing as tp import typing as tp
from simbricks.nodeconfig import AppConfig, NodeConfig
from simbricks.simulators import HostSim, I40eMultiNIC, NetSim, NICSim
from simbricks.experiments import Experiment from simbricks.experiments import Experiment
from simbricks.nodeconfig import NodeConfig, AppConfig
from simbricks.simulators import NetSim, NICSim, HostSim, I40eMultiNIC
def create_basic_hosts( def create_basic_hosts(
...@@ -40,8 +41,10 @@ def create_basic_hosts( ...@@ -40,8 +41,10 @@ def create_basic_hosts(
ip_start: int = 1, ip_start: int = 1,
ip_prefix: int = 24 ip_prefix: int = 24
): ):
"""Creates and configures multiple hosts to be simulated using the given parameters. """
Creates and configures multiple hosts to be simulated using the given
parameters.
Args: Args:
`num`: number of hosts to create `num`: number of hosts to create
""" """
...@@ -82,8 +85,10 @@ def create_multinic_hosts( ...@@ -82,8 +85,10 @@ def create_multinic_hosts(
ip_start: int = 1, ip_start: int = 1,
ip_prefix: int = 24 ip_prefix: int = 24
): ):
"""Creates and configures multiple hosts to be simulated using the given parameters. These hosts use multiple NICs. """
Creates and configures multiple hosts to be simulated using the given
parameters. These hosts use multiple NICs.
Args: Args:
num: number of hosts to create num: number of hosts to create
""" """
...@@ -130,8 +135,10 @@ def create_dctcp_hosts( ...@@ -130,8 +135,10 @@ def create_dctcp_hosts(
mtu: int, mtu: int,
ip_start: int = 1 ip_start: int = 1
): ):
"""Creates and configures multiple hosts to be simulated in a DCTCP experiment using the given parameters. """
Creates and configures multiple hosts to be simulated in a DCTCP experiment
using the given parameters.
Args: Args:
num: number of hosts to create num: number of hosts to create
cpu_freq: CPU frequency to simulate, e.g. '5GHz' cpu_freq: CPU frequency to simulate, e.g. '5GHz'
...@@ -158,4 +165,4 @@ def create_dctcp_hosts( ...@@ -158,4 +165,4 @@ def create_dctcp_hosts(
hosts.append(host) hosts.append(host)
return hosts return hosts
\ No newline at end of file
...@@ -26,8 +26,8 @@ from __future__ import annotations ...@@ -26,8 +26,8 @@ from __future__ import annotations
import math import math
import typing as tp import typing as tp
from simbricks.nodeconfig import NodeConfig
from simbricks.experiment.experiment_environment import ExpEnv from simbricks.experiment.experiment_environment import ExpEnv
from simbricks.nodeconfig import NodeConfig
class Simulator(object): class Simulator(object):
...@@ -134,6 +134,7 @@ class NICSim(PCIDevSim): ...@@ -134,6 +134,7 @@ class NICSim(PCIDevSim):
def sockets_wait(self, env): def sockets_wait(self, env):
return super().sockets_wait(env) + [env.nic_eth_path(self)] return super().sockets_wait(env) + [env.nic_eth_path(self)]
class NetSim(Simulator): class NetSim(Simulator):
"""Base class for network simulators.""" """Base class for network simulators."""
name = '' name = ''
...@@ -174,10 +175,10 @@ class NetSim(Simulator): ...@@ -174,10 +175,10 @@ class NetSim(Simulator):
return self.nics + self.net_connect + self.hosts_direct return self.nics + self.net_connect + self.hosts_direct
def sockets_cleanup(self, env: ExpEnv): def sockets_cleanup(self, env: ExpEnv):
return [s for (_,s) in self.listen_sockets(env)] return [s for (_, s) in self.listen_sockets(env)]
def sockets_wait(self, env: ExpEnv): def sockets_wait(self, env: ExpEnv):
return [s for (_,s) in self.listen_sockets(env)] return [s for (_, s) in self.listen_sockets(env)]
class HostSim(Simulator): class HostSim(Simulator):
...@@ -248,21 +249,25 @@ class QemuHost(HostSim): ...@@ -248,21 +249,25 @@ class QemuHost(HostSim):
def prep_cmds(self, env): def prep_cmds(self, env):
to_path = env.hdcopy_path(self) to_path = env.hdcopy_path(self)
return [f'{env.qemu_img_path} create -f qcow2 -o ' return [
f'{env.qemu_img_path} create -f qcow2 -o '
f'backing_file="{env.hd_path(self.node_config.disk_image)}" ' f'backing_file="{env.hd_path(self.node_config.disk_image)}" '
f'{env.hdcopy_path(self)}'] f'{env.hdcopy_path(self)}'
]
def run_cmd(self, env): def run_cmd(self, env):
accel = ',accel=kvm:tcg' if not self.sync else '' accel = ',accel=kvm:tcg' if not self.sync else ''
cmd = (f'{env.qemu_path} -machine q35{accel} -serial mon:stdio ' cmd = (
f'{env.qemu_path} -machine q35{accel} -serial mon:stdio '
'-cpu Skylake-Server -display none -nic none ' '-cpu Skylake-Server -display none -nic none '
f'-kernel {env.qemu_kernel_path} ' f'-kernel {env.qemu_kernel_path} '
f'-drive file={env.hdcopy_path(self)},if=ide,index=0,media=disk ' f'-drive file={env.hdcopy_path(self)},if=ide,index=0,media=disk '
f'-drive file={env.cfgtar_path(self)},if=ide,index=1,media=disk,' f'-drive file={env.cfgtar_path(self)},if=ide,index=1,media=disk,'
'driver=raw ' 'driver=raw '
'-append "earlyprintk=ttyS0 console=ttyS0 root=/dev/sda1 ' '-append "earlyprintk=ttyS0 console=ttyS0 root=/dev/sda1 '
'init=/home/ubuntu/guestinit.sh rw" ' 'init=/home/ubuntu/guestinit.sh rw" '
f'-m {self.node_config.memory} -smp {self.node_config.cores} ') f'-m {self.node_config.memory} -smp {self.node_config.cores} '
)
if self.sync: if self.sync:
unit = self.cpu_freq[-3:] unit = self.cpu_freq[-3:]
...@@ -288,9 +293,10 @@ class QemuHost(HostSim): ...@@ -288,9 +293,10 @@ class QemuHost(HostSim):
cmd += ' ' cmd += ' '
# qemu does not currently support net direct ports # qemu does not currently support net direct ports
assert(len(self.net_directs) == 0) assert (len(self.net_directs) == 0)
return cmd return cmd
class Gem5Host(HostSim): class Gem5Host(HostSim):
cpu_type_cp = 'X86KvmCPU' cpu_type_cp = 'X86KvmCPU'
cpu_type = 'TimingSimpleCPU' cpu_type = 'TimingSimpleCPU'
...@@ -322,7 +328,8 @@ class Gem5Host(HostSim): ...@@ -322,7 +328,8 @@ class Gem5Host(HostSim):
cmd = f'{env.gem5_path(self.variant)} --outdir={env.gem5_outdir(self)} ' cmd = f'{env.gem5_path(self.variant)} --outdir={env.gem5_outdir(self)} '
cmd += ' '.join(self.extra_main_args) cmd += ' '.join(self.extra_main_args)
cmd += (f' {env.gem5_py_path} --caches --l2cache --l3cache ' cmd += (
f' {env.gem5_py_path} --caches --l2cache --l3cache '
'--l1d_size=32kB --l1i_size=32kB --l2_size=2MB --l3_size=32MB ' '--l1d_size=32kB --l1i_size=32kB --l2_size=2MB --l3_size=32MB '
'--l1d_assoc=8 --l1i_assoc=8 --l2_assoc=4 --l3_assoc=16 ' '--l1d_assoc=8 --l1i_assoc=8 --l2_assoc=4 --l3_assoc=16 '
f'--cacheline_size=64 --cpu-clock={self.cpu_freq} --sys-clock={self.sys_clock} ' f'--cacheline_size=64 --cpu-clock={self.cpu_freq} --sys-clock={self.sys_clock} '
...@@ -332,7 +339,8 @@ class Gem5Host(HostSim): ...@@ -332,7 +339,8 @@ class Gem5Host(HostSim):
f'--disk-image={env.cfgtar_path(self)} ' f'--disk-image={env.cfgtar_path(self)} '
f'--cpu-type={cpu_type} --mem-size={self.node_config.memory}MB ' f'--cpu-type={cpu_type} --mem-size={self.node_config.memory}MB '
f'--num-cpus={self.node_config.cores} ' f'--num-cpus={self.node_config.cores} '
'--ddio-enabled --ddio-way-part=8 --mem-type=DDR4_2400_16x4 ') '--ddio-enabled --ddio-way-part=8 --mem-type=DDR4_2400_16x4 '
)
if env.create_cp: if env.create_cp:
cmd += '--max-checkpoints=1 ' cmd += '--max-checkpoints=1 '
...@@ -341,30 +349,33 @@ class Gem5Host(HostSim): ...@@ -341,30 +349,33 @@ class Gem5Host(HostSim):
cmd += '-r 1 ' cmd += '-r 1 '
for dev in self.pcidevs: for dev in self.pcidevs:
cmd += (f'--simbricks-pci=connect:{env.dev_pci_path(dev)}' cmd += (
f':latency={self.pci_latency}ns' f'--simbricks-pci=connect:{env.dev_pci_path(dev)}'
f':sync_interval={self.sync_period}ns') f':latency={self.pci_latency}ns'
f':sync_interval={self.sync_period}ns'
)
if cpu_type == 'TimingSimpleCPU': if cpu_type == 'TimingSimpleCPU':
cmd += ':sync' cmd += ':sync'
cmd +=' ' cmd += ' '
for net in self.net_directs: for net in self.net_directs:
cmd += ('--simbricks-eth-e1000=listen' cmd += (
f':{env.net2host_eth_path(net, self)}' '--simbricks-eth-e1000=listen'
f':{env.net2host_shm_path(net, self)}' f':{env.net2host_eth_path(net, self)}'
f':latency={net.eth_latency}ns' f':{env.net2host_shm_path(net, self)}'
f':sync_interval={net.sync_period}ns') f':latency={net.eth_latency}ns'
f':sync_interval={net.sync_period}ns'
)
if cpu_type == 'TimingSimpleCPU': if cpu_type == 'TimingSimpleCPU':
cmd += ':sync' cmd += ':sync'
cmd +=' ' cmd += ' '
cmd += ' '.join(self.extra_config_args) cmd += ' '.join(self.extra_config_args)
return cmd return cmd
class CorundumVerilatorNIC(NICSim): class CorundumVerilatorNIC(NICSim):
clock_freq = 250 # MHz clock_freq = 250 # MHz
def __init__(self): def __init__(self):
super().__init__() super().__init__()
...@@ -374,25 +385,32 @@ class CorundumVerilatorNIC(NICSim): ...@@ -374,25 +385,32 @@ class CorundumVerilatorNIC(NICSim):
return 512 return 512
def run_cmd(self, env): def run_cmd(self, env):
return self.basic_run_cmd(env, '/corundum/corundum_verilator', return self.basic_run_cmd(
str(self.clock_freq)) env, '/corundum/corundum_verilator', str(self.clock_freq)
)
class CorundumBMNIC(NICSim): class CorundumBMNIC(NICSim):
def __init__(self): def __init__(self):
super().__init__() super().__init__()
def run_cmd(self, env): def run_cmd(self, env):
return self.basic_run_cmd(env, '/corundum_bm/corundum_bm') return self.basic_run_cmd(env, '/corundum_bm/corundum_bm')
class I40eNIC(NICSim): class I40eNIC(NICSim):
def __init__(self): def __init__(self):
super().__init__() super().__init__()
def run_cmd(self, env): def run_cmd(self, env):
return self.basic_run_cmd(env, '/i40e_bm/i40e_bm') return self.basic_run_cmd(env, '/i40e_bm/i40e_bm')
class E1000NIC(NICSim): class E1000NIC(NICSim):
debug = False debug = False
def __init__(self): def __init__(self):
super().__init__() super().__init__()
...@@ -402,6 +420,7 @@ class E1000NIC(NICSim): ...@@ -402,6 +420,7 @@ class E1000NIC(NICSim):
cmd = 'env E1000_DEBUG=1 ' + cmd cmd = 'env E1000_DEBUG=1 ' + cmd
return cmd return cmd
class MultiSubNIC(NICSim): class MultiSubNIC(NICSim):
name = '' name = ''
multinic = None multinic = None
...@@ -419,6 +438,7 @@ class MultiSubNIC(NICSim): ...@@ -419,6 +438,7 @@ class MultiSubNIC(NICSim):
def start_delay(self): def start_delay(self):
return 0 return 0
class I40eMultiNIC(Simulator): class I40eMultiNIC(Simulator):
name = '' name = ''
...@@ -458,6 +478,7 @@ class I40eMultiNIC(Simulator): ...@@ -458,6 +478,7 @@ class I40eMultiNIC(Simulator):
class WireNet(NetSim): class WireNet(NetSim):
def __init__(self): def __init__(self):
super().__init__() super().__init__()
...@@ -472,6 +493,7 @@ class WireNet(NetSim): ...@@ -472,6 +493,7 @@ class WireNet(NetSim):
cmd += ' ' + env.pcap_file cmd += ' ' + env.pcap_file
return cmd return cmd
class SwitchNet(NetSim): class SwitchNet(NetSim):
sync = True sync = True
...@@ -487,9 +509,9 @@ class SwitchNet(NetSim): ...@@ -487,9 +509,9 @@ class SwitchNet(NetSim):
if len(env.pcap_file) > 0: if len(env.pcap_file) > 0:
cmd += ' -p ' + env.pcap_file cmd += ' -p ' + env.pcap_file
for (_,n) in self.connect_sockets(env): for (_, n) in self.connect_sockets(env):
cmd += ' -s ' + n cmd += ' -s ' + n
for (_,n) in self.listen_sockets(env): for (_, n) in self.listen_sockets(env):
cmd += ' -h ' + n cmd += ' -h ' + n
return cmd return cmd
...@@ -502,6 +524,7 @@ class SwitchNet(NetSim): ...@@ -502,6 +524,7 @@ class SwitchNet(NetSim):
cleanup.append(s + '-shm') cleanup.append(s + '-shm')
return cleanup return cleanup
class TofinoNet(NetSim): class TofinoNet(NetSim):
tofino_log_path = '/tmp/model.ldjson' tofino_log_path = '/tmp/model.ldjson'
sync = True sync = True
...@@ -514,17 +537,19 @@ class TofinoNet(NetSim): ...@@ -514,17 +537,19 @@ class TofinoNet(NetSim):
cmd += f' -S {self.sync_period} -E {self.eth_latency} -t {self.tofino_log_path}' cmd += f' -S {self.sync_period} -E {self.eth_latency} -t {self.tofino_log_path}'
if not self.sync: if not self.sync:
cmd += ' -u' cmd += ' -u'
for (_,n) in self.connect_sockets(env): for (_, n) in self.connect_sockets(env):
cmd += ' -s ' + n cmd += ' -s ' + n
return cmd return cmd
class NS3DumbbellNet(NetSim): class NS3DumbbellNet(NetSim):
def __init__(self): def __init__(self):
super().__init__() super().__init__()
def run_cmd(self, env): def run_cmd(self, env):
ports = '' ports = ''
for (n,s) in self.connect_sockets(env): for (n, s) in self.connect_sockets(env):
if 'server' in n.name: if 'server' in n.name:
ports += '--CosimPortLeft=' + s + ' ' ports += '--CosimPortLeft=' + s + ' '
else: else:
...@@ -535,13 +560,15 @@ class NS3DumbbellNet(NetSim): ...@@ -535,13 +560,15 @@ class NS3DumbbellNet(NetSim):
return cmd return cmd
class NS3BridgeNet(NetSim): class NS3BridgeNet(NetSim):
def __init__(self): def __init__(self):
super().__init__() super().__init__()
def run_cmd(self, env): def run_cmd(self, env):
ports = '' ports = ''
for (_,n) in self.connect_sockets(env): for (_, n) in self.connect_sockets(env):
ports += '--CosimPort=' + n + ' ' ports += '--CosimPort=' + n + ' '
cmd = env.repodir + '/sims/external/ns-3' + '/cosim-run.sh cosim cosim-bridge-example ' + ports + ' ' + self.opt cmd = env.repodir + '/sims/external/ns-3' + '/cosim-run.sh cosim cosim-bridge-example ' + ports + ' ' + self.opt
...@@ -549,13 +576,15 @@ class NS3BridgeNet(NetSim): ...@@ -549,13 +576,15 @@ class NS3BridgeNet(NetSim):
return cmd return cmd
class NS3SequencerNet(NetSim): class NS3SequencerNet(NetSim):
def __init__(self): def __init__(self):
super().__init__() super().__init__()
def run_cmd(self, env): def run_cmd(self, env):
ports = '' ports = ''
for (n,s) in self.connect_sockets(env): for (n, s) in self.connect_sockets(env):
if 'client' in n.name: if 'client' in n.name:
ports += '--ClientPort=' + s + ' ' ports += '--ClientPort=' + s + ' '
elif 'replica' in n.name: elif 'replica' in n.name:
...@@ -569,6 +598,7 @@ class NS3SequencerNet(NetSim): ...@@ -569,6 +598,7 @@ class NS3SequencerNet(NetSim):
class FEMUDev(PCIDevSim): class FEMUDev(PCIDevSim):
def __init__(self): def __init__(self):
super().__init__() super().__init__()
......
...@@ -20,11 +20,11 @@ ...@@ -20,11 +20,11 @@
# 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 sys import json
import os import os
import pathlib import pathlib
import shutil import shutil
import json import sys
if len(sys.argv) != 2: if len(sys.argv) != 2:
print('Usage: udp_scale.py OUTDIR') print('Usage: udp_scale.py OUTDIR')
...@@ -43,12 +43,10 @@ for cl in types_of_client: ...@@ -43,12 +43,10 @@ for cl in types_of_client:
diff_time = '' diff_time = ''
else: else:
exp_log = json.load(log) exp_log = json.load(log)
start_time = exp_log["start_time"] start_time = exp_log['start_time']
end_time = exp_log["end_time"] end_time = exp_log['end_time']
diff_time = (end_time - start_time)/60 #min diff_time = (end_time - start_time) / 60 #min
diff_time = str(diff_time) diff_time = str(diff_time)
log.close() log.close()
print('%d\t%s' % (cl, diff_time)) print('%d\t%s' % (cl, diff_time))
...@@ -20,12 +20,12 @@ ...@@ -20,12 +20,12 @@
# 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 sys import json
import math
import os import os
import pathlib import pathlib
import shutil import shutil
import json import sys
import math
num_runs = 3 num_runs = 3
if len(sys.argv) != 2: if len(sys.argv) != 2:
...@@ -42,14 +42,14 @@ for bw in types_of_bw: ...@@ -42,14 +42,14 @@ for bw in types_of_bw:
avg_time = 0 avg_time = 0
std = 0 std = 0
all_time = [] all_time = []
for i in range(1, num_runs+1): for i in range(1, num_runs + 1):
log_path = '%sgt-ib-sw-Load-%dm-%d.json' % (basedir, bw, i) log_path = '%sgt-ib-sw-Load-%dm-%d.json' % (basedir, bw, i)
if os.path.exists(log_path): if os.path.exists(log_path):
log = open(log_path, 'r') log = open(log_path, 'r')
exp_log = json.load(log) exp_log = json.load(log)
start_time = exp_log["start_time"] start_time = exp_log['start_time']
end_time = exp_log["end_time"] end_time = exp_log['end_time']
diff_time = (end_time - start_time)/60 #min diff_time = (end_time - start_time) / 60 #min
total_time += diff_time total_time += diff_time
all_time.append(diff_time) all_time.append(diff_time)
diff_time = str(diff_time) diff_time = str(diff_time)
...@@ -60,16 +60,13 @@ for bw in types_of_bw: ...@@ -60,16 +60,13 @@ for bw in types_of_bw:
#print('%d\t%s' % (bw, diff_time)) #print('%d\t%s' % (bw, diff_time))
avg_time = total_time/num_runs avg_time = total_time / num_runs
#print('avg_time: ' + str(avg_time)) #print('avg_time: ' + str(avg_time))
for i in range(0, num_runs): for i in range(0, num_runs):
std += (all_time[i] - avg_time) * (all_time[i] - avg_time) std += (all_time[i] - avg_time) * (all_time[i] - avg_time)
std = std/num_runs std = std / num_runs
std = math.sqrt(std) std = math.sqrt(std)
#print(str(std)) #print(str(std))
print('%d %s %f' % (bw, avg_time, std)) print('%d %s %f' % (bw, avg_time, std))
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
import itertools import itertools
import sys import sys
import utils.iperf import utils.iperf
if len(sys.argv) != 2: if len(sys.argv) != 2:
...@@ -39,7 +40,6 @@ configs = list(itertools.product(types_of_host, mtus)) ...@@ -39,7 +40,6 @@ configs = list(itertools.product(types_of_host, mtus))
confignames = [h + '-' + str(mtu) for h, mtu in configs] confignames = [h + '-' + str(mtu) for h, mtu in configs]
print('\t'.join(['threshold'] + confignames)) print('\t'.join(['threshold'] + confignames))
for k_val in range(0, max_k + 1, k_step): for k_val in range(0, max_k + 1, k_step):
line = [str(k_val)] line = [str(k_val)]
for h, mtu in configs: for h, mtu in configs:
......
...@@ -19,12 +19,15 @@ ...@@ -19,12 +19,15 @@
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
# 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.
""" Generates data file for dist_memcache scalability graph. First column is """
the number of hosts, second column the qemu timing simulation time in hours, Generates data file for dist_memcache scalability graph.
and the third column is the gem5 simulation time."""
First column is the number of hosts, second column the qemu timing simulation
time in hours, and the third column is the gem5 simulation time.
"""
import sys
import json import json
import sys
if len(sys.argv) != 2: if len(sys.argv) != 2:
print('Usage: dist_memcache.py OUTDIR') print('Usage: dist_memcache.py OUTDIR')
...@@ -36,22 +39,21 @@ racks = [1, 5, 10, 15, 25] ...@@ -36,22 +39,21 @@ racks = [1, 5, 10, 15, 25]
host_types = ['qt', 'gem5'] host_types = ['qt', 'gem5']
for n_racks in racks: for n_racks in racks:
l = str(n_racks * n_hosts_per_rack) l = str(n_racks * n_hosts_per_rack)
for host_type in host_types: for host_type in host_types:
log_path = '%sdist_memcache-%s-%d-%d-1.json' % (basedir, host_type, log_path = '%sdist_memcache-%s-%d-%d-1.json' % (
n_racks, n_hosts_per_rack) basedir, host_type, n_racks, n_hosts_per_rack
try: )
log = open(log_path, 'r') try:
except: log = open(log_path, 'r')
diff_time = '' except:
else: diff_time = ''
exp_log = json.load(log) else:
start_time = exp_log["start_time"] exp_log = json.load(log)
end_time = exp_log["end_time"] start_time = exp_log['start_time']
diff_time = float(end_time - start_time)/60/60 end_time = exp_log['end_time']
diff_time = float(end_time - start_time) / 60 / 60
l += '\t' + str(diff_time)
l += '\t' + str(diff_time)
print(l)
print(l)
...@@ -20,23 +20,23 @@ ...@@ -20,23 +20,23 @@
# 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 sys import json
import os import os
import pathlib import pathlib
import shutil import shutil
import json import sys
# How to use # How to use
# $ python3 modetcp.py paper_data/modetcp # $ python3 modetcp.py paper_data/modetcp
# #
mode = ['0', '1'] mode = ['0', '1']
nics = ['cb', 'cv', 'ib'] nics = ['cb', 'cv', 'ib']
num_client = ['1', '4'] num_client = ['1', '4']
outdir = sys.argv[1] outdir = sys.argv[1]
def parse_sim_time(path): def parse_sim_time(path):
ret = {} ret = {}
if not os.path.exists(path): if not os.path.exists(path):
...@@ -44,7 +44,7 @@ def parse_sim_time(path): ...@@ -44,7 +44,7 @@ def parse_sim_time(path):
with open(path, 'r') as f: with open(path, 'r') as f:
data = json.load(f) data = json.load(f)
ret['simtime'] = (data['end_time'] - data['start_time'])/60 ret['simtime'] = (data['end_time'] - data['start_time']) / 60
f.close() f.close()
return ret return ret
...@@ -62,5 +62,3 @@ for c in num_client: ...@@ -62,5 +62,3 @@ for c in num_client:
t = '' t = ''
line = line + ' ' + f'{t}' line = line + ' ' + f'{t}'
print(line) print(line)
...@@ -20,21 +20,21 @@ ...@@ -20,21 +20,21 @@
# 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 sys import json
import os import os
import pathlib import pathlib
import shutil import shutil
import json import sys
# How to use # How to use
# $ python3 modetcp.py paper_data/modetcp # $ python3 modetcp.py paper_data/modetcp
# #
num_runs = 8 num_runs = 8
outdir = sys.argv[1] outdir = sys.argv[1]
def parse_sim_time(path): def parse_sim_time(path):
ret = {} ret = {}
if not os.path.exists(path): if not os.path.exists(path):
...@@ -42,13 +42,14 @@ def parse_sim_time(path): ...@@ -42,13 +42,14 @@ def parse_sim_time(path):
with open(path, 'r') as f: with open(path, 'r') as f:
data = json.load(f) data = json.load(f)
ret['simtime'] = (data['end_time'] - data['start_time'])/60 ret['simtime'] = (data['end_time'] - data['start_time']) / 60
f.close() f.close()
return ret return ret
total_time = 0 total_time = 0
for n in range (1, num_runs+1): for n in range(1, num_runs + 1):
path = '%s/p8-gt-ib-sw-Host-1000m-1-%s.json' % (outdir, n) path = '%s/p8-gt-ib-sw-Host-1000m-1-%s.json' % (outdir, n)
data = parse_sim_time(path) data = parse_sim_time(path)
...@@ -58,10 +59,5 @@ for n in range (1, num_runs+1): ...@@ -58,10 +59,5 @@ for n in range (1, num_runs+1):
else: else:
t = '' t = ''
print(t) print(t)
avg = total_time/num_runs avg = total_time / num_runs
print('avg: ' + str(avg)) print('avg: ' + str(avg))
...@@ -20,10 +20,10 @@ ...@@ -20,10 +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.
from utils.netperf import *
import sys import sys
from time import strftime from time import gmtime, strftime
from time import gmtime
from utils.netperf import *
def fmt_lat(lat): def fmt_lat(lat):
...@@ -60,7 +60,7 @@ for (h, h_l) in hosts: ...@@ -60,7 +60,7 @@ for (h, h_l) in hosts:
path = '%s/netperf-%s-%s-%s-1.json' % (outdir, h, net, nic) path = '%s/netperf-%s-%s-%s-1.json' % (outdir, h, net, nic)
data = parse_netperf_run(path) data = parse_netperf_run(path)
if 'simtime' in data: if 'simtime' in data:
t = strftime("%H:%M:%S", gmtime(data['simtime'])) t = strftime('%H:%M:%S', gmtime(data['simtime']))
else: else:
t = '' t = ''
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
import itertools import itertools
import sys import sys
import utils.parse_nopaxos import utils.parse_nopaxos
if len(sys.argv) != 2: if len(sys.argv) != 2:
...@@ -33,14 +34,14 @@ basedir = sys.argv[1] + '/' ...@@ -33,14 +34,14 @@ basedir = sys.argv[1] + '/'
types_of_seq = ['ehseq', 'swseq'] types_of_seq = ['ehseq', 'swseq']
num_clients = [1, 2, 3, 4, 5, 6, 7, 8, 10, 12] num_clients = [1, 2, 3, 4, 5, 6, 7, 8, 10, 12]
print(
'num_client ehseq-tput(req/sec) ehseq-lat(us) swseq-tput(req/sec) swseq-lat(us)\n'
print('num_client ehseq-tput(req/sec) ehseq-lat(us) swseq-tput(req/sec) swseq-lat(us)\n') )
for num_c in num_clients: for num_c in num_clients:
line = [str(num_c)] line = [str(num_c)]
for seq in types_of_seq: for seq in types_of_seq:
path_pat = '%snopaxos-gt-ib-%s-%d-1.json' % (basedir, seq, num_c) path_pat = '%snopaxos-gt-ib-%s-%d-1.json' % (basedir, seq, num_c)
res = utils.parse_nopaxos.parse_nopaxos_run(num_c, seq, path_pat) res = utils.parse_nopaxos.parse_nopaxos_run(num_c, seq, path_pat)
#print(path_pat) #print(path_pat)
...@@ -57,5 +58,4 @@ for num_c in num_clients: ...@@ -57,5 +58,4 @@ for num_c in num_clients:
line.append('%.2f' % (tput)) line.append('%.2f' % (tput))
line.append(f'{lat}') line.append(f'{lat}')
print(' '.join(line)) print(' '.join(line))
...@@ -20,16 +20,19 @@ ...@@ -20,16 +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.
import fnmatch
import glob import glob
import itertools
import json import json
import os import os
import fnmatch
import re import re
import itertools
import sys import sys
def parse_iperf_run(data, skip=1, use=8): def parse_iperf_run(data, skip=1, use=8):
tp_pat = re.compile(r'\[ *\d*\] *([0-9\.]*)- *([0-9\.]*) sec.*Bytes *([0-9\.]*) ([GM])bits.*') tp_pat = re.compile(
r'\[ *\d*\] *([0-9\.]*)- *([0-9\.]*) sec.*Bytes *([0-9\.]*) ([GM])bits.*'
)
tps_time = {} tps_time = {}
for hn in fnmatch.filter(data['sims'].keys(), 'host.client.*'): for hn in fnmatch.filter(data['sims'].keys(), 'host.client.*'):
sim = data['sims'][hn] sim = data['sims'][hn]
...@@ -50,7 +53,7 @@ def parse_iperf_run(data, skip=1, use=8): ...@@ -50,7 +53,7 @@ def parse_iperf_run(data, skip=1, use=8):
if m.group(4) == 'G': if m.group(4) == 'G':
tps_time[time].append(float(m.group(3))) tps_time[time].append(float(m.group(3)))
elif m.group(4) == 'M': elif m.group(4) == 'M':
m_tps = float(m.group(3))/1000 m_tps = float(m.group(3)) / 1000
tps_time[time].append(m_tps) tps_time[time].append(m_tps)
tps = [] tps = []
...@@ -58,11 +61,11 @@ def parse_iperf_run(data, skip=1, use=8): ...@@ -58,11 +61,11 @@ def parse_iperf_run(data, skip=1, use=8):
x = sum(tps_time[t]) x = sum(tps_time[t])
tps.append(x) tps.append(x)
if len(tps) == 0: if len(tps) == 0:
return None return None
return sum(tps) / len(tps) return sum(tps) / len(tps)
def parse_iperf(basename, skip=1, use=8): def parse_iperf(basename, skip=1, use=8):
runs = [] runs = []
for path in glob.glob(basename + '-*.json'): for path in glob.glob(basename + '-*.json'):
...@@ -79,6 +82,7 @@ def parse_iperf(basename, skip=1, use=8): ...@@ -79,6 +82,7 @@ def parse_iperf(basename, skip=1, use=8):
if not runs: if not runs:
return {'avg': None, 'min': None, 'max': None} return {'avg': None, 'min': None, 'max': None}
else: else:
return {'avg': sum(runs) / len(runs), 'min': min(runs), return {
'max': max(runs)} 'avg': sum(runs) / len(runs), 'min': min(runs), 'max': max(runs)
}
result = {} result = {}
...@@ -20,9 +20,10 @@ ...@@ -20,9 +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 sys
import re
import json import json
import re
import sys
def transform_internal(ts, component, msg): def transform_internal(ts, component, msg):
if not component.startswith('system.pc.simbricks_0'): if not component.startswith('system.pc.simbricks_0'):
...@@ -40,6 +41,7 @@ def transform_internal(ts, component, msg): ...@@ -40,6 +41,7 @@ def transform_internal(ts, component, msg):
return (ts + ' ' + msg) return (ts + ' ' + msg)
def transform_external(ts, component, msg): def transform_external(ts, component, msg):
if msg.startswith('igbe: requesting restart clock:') or \ if msg.startswith('igbe: requesting restart clock:') or \
msg == 'igbe: scheduled' or \ msg == 'igbe: scheduled' or \
...@@ -49,9 +51,9 @@ def transform_external(ts, component, msg): ...@@ -49,9 +51,9 @@ def transform_external(ts, component, msg):
elif msg.startswith('[rxdesc]') or msg.startswith('[txdesc]'): elif msg.startswith('[rxdesc]') or msg.startswith('[txdesc]'):
msg = msg[9:] msg = msg[9:]
return (ts + ' ' + msg) return (ts + ' ' + msg)
if len(sys.argv) != 3: if len(sys.argv) != 3:
print('Usage: pci_validation.py JSON-DIR VARIANT') print('Usage: pci_validation.py JSON-DIR VARIANT')
print(' VARIANT can be internal or external') print(' VARIANT can be internal or external')
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
import itertools import itertools
import sys import sys
import utils.iperf import utils.iperf
if len(sys.argv) != 2: if len(sys.argv) != 2:
...@@ -41,7 +42,7 @@ configs = [ ...@@ -41,7 +42,7 @@ configs = [
print('\t'.join(['config'] + list(map(str, lats)))) print('\t'.join(['config'] + list(map(str, lats))))
for (ht,nt,lab) in configs: for (ht, nt, lab) in configs:
cols = [str(lab)] cols = [str(lab)]
for lat in lats: for lat in lats:
path_pat = '%spcilat-%s-%s-switch-%d' % (basedir, ht, nt, lat) path_pat = '%spcilat-%s-%s-switch-%d' % (basedir, ht, nt, lat)
......
...@@ -20,22 +20,22 @@ ...@@ -20,22 +20,22 @@
# 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 sys import json
import os import os
import pathlib import pathlib
import shutil import shutil
import json import sys
# How to use # How to use
# $ python3 modetcp.py paper_data/modetcp # $ python3 modetcp.py paper_data/modetcp
# #
mode = ['no_simb-gt', 'noTraf-gt-ib-sw'] mode = ['no_simb-gt', 'noTraf-gt-ib-sw']
cmd = ['sleep', 'busy'] cmd = ['sleep', 'busy']
outdir = sys.argv[1] outdir = sys.argv[1]
def parse_sim_time(path): def parse_sim_time(path):
ret = {} ret = {}
if not os.path.exists(path): if not os.path.exists(path):
...@@ -43,7 +43,7 @@ def parse_sim_time(path): ...@@ -43,7 +43,7 @@ def parse_sim_time(path):
with open(path, 'r') as f: with open(path, 'r') as f:
data = json.load(f) data = json.load(f)
ret['simtime'] = (data['end_time'] - data['start_time'])/60 ret['simtime'] = (data['end_time'] - data['start_time']) / 60
f.close() f.close()
return ret return ret
...@@ -60,5 +60,3 @@ for m in mode: ...@@ -60,5 +60,3 @@ for m in mode:
t = '' t = ''
line = line + ' ' + f'{t}' line = line + ' ' + f'{t}'
print(line) print(line)
...@@ -20,16 +20,19 @@ ...@@ -20,16 +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.
import fnmatch
import glob import glob
import itertools
import json import json
import os import os
import fnmatch
import re import re
import itertools
import sys import sys
def parse_iperf_run(data, skip=1, use=8): def parse_iperf_run(data, skip=1, use=8):
tp_pat = re.compile(r'\[ *\d*\] *([0-9\.]*)- *([0-9\.]*) sec.*Bytes *([0-9\.]*) ([GM])bits.*') tp_pat = re.compile(
r'\[ *\d*\] *([0-9\.]*)- *([0-9\.]*) sec.*Bytes *([0-9\.]*) ([GM])bits.*'
)
tps_time = {} tps_time = {}
for hn in fnmatch.filter(data['sims'].keys(), 'host.client.*'): for hn in fnmatch.filter(data['sims'].keys(), 'host.client.*'):
sim = data['sims'][hn] sim = data['sims'][hn]
...@@ -50,7 +53,7 @@ def parse_iperf_run(data, skip=1, use=8): ...@@ -50,7 +53,7 @@ def parse_iperf_run(data, skip=1, use=8):
if m.group(4) == 'G': if m.group(4) == 'G':
tps_time[time].append(float(m.group(3))) tps_time[time].append(float(m.group(3)))
elif m.group(4) == 'M': elif m.group(4) == 'M':
m_tps = float(m.group(3))/1000 m_tps = float(m.group(3)) / 1000
tps_time[time].append(m_tps) tps_time[time].append(m_tps)
tps = [] tps = []
...@@ -58,11 +61,11 @@ def parse_iperf_run(data, skip=1, use=8): ...@@ -58,11 +61,11 @@ def parse_iperf_run(data, skip=1, use=8):
x = sum(tps_time[t]) x = sum(tps_time[t])
tps.append(x) tps.append(x)
if len(tps) == 0: if len(tps) == 0:
return None return None
return sum(tps) / len(tps) return sum(tps) / len(tps)
def parse_iperf(basename, skip=1, use=8): def parse_iperf(basename, skip=1, use=8):
runs = [] runs = []
for path in glob.glob(basename + '-*.json'): for path in glob.glob(basename + '-*.json'):
...@@ -79,6 +82,7 @@ def parse_iperf(basename, skip=1, use=8): ...@@ -79,6 +82,7 @@ def parse_iperf(basename, skip=1, use=8):
if not runs: if not runs:
return {'avg': None, 'min': None, 'max': None} return {'avg': None, 'min': None, 'max': None}
else: else:
return {'avg': sum(runs) / len(runs), 'min': min(runs), return {
'max': max(runs)} 'avg': sum(runs) / len(runs), 'min': min(runs), 'max': max(runs)
}
result = {} result = {}
...@@ -21,8 +21,9 @@ ...@@ -21,8 +21,9 @@
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
import json import json
import re
import os import os
import re
def parse_netperf_run(path): def parse_netperf_run(path):
ret = {} ret = {}
...@@ -50,8 +51,6 @@ def parse_netperf_run(path): ...@@ -50,8 +51,6 @@ def parse_netperf_run(path):
m = tp_pat.match(tp_line) m = tp_pat.match(tp_line)
ret['throughput'] = float(m.group(1)) ret['throughput'] = float(m.group(1))
lath_pat = re.compile(r'\s*Mean Latency.*') lath_pat = re.compile(r'\s*Mean Latency.*')
start = None start = None
i = 0 i = 0
...@@ -64,7 +63,9 @@ def parse_netperf_run(path): ...@@ -64,7 +63,9 @@ def parse_netperf_run(path):
if start is not None: if start is not None:
lat_line = lines[start + 1] lat_line = lines[start + 1]
lat_pat = re.compile(r'\s*([-0-9\.]*),([-0-9\.]*),([-0-9\.]*),([-0-9\.]*).*') lat_pat = re.compile(
r'\s*([-0-9\.]*),([-0-9\.]*),([-0-9\.]*),([-0-9\.]*).*'
)
m = lat_pat.match(lat_line) m = lat_pat.match(lat_line)
ret['latenyMean'] = float(m.group(1)) ret['latenyMean'] = float(m.group(1))
ret['latenyTail'] = float(m.group(4)) ret['latenyTail'] = float(m.group(4))
......
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