simulators.py 7.83 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Simulator(object):
    # number of cores required for this simulator
    def resreq_cores(self):
        return 1

    # memory required for this simulator (in MB)
    def resreq_mem(self):
        return 64

    def prep_cmds(self, env):
        return []

    def run_cmd(self, env):
        pass

class HostSim(Simulator):
    node_config = None
    name = ''
    wait = False
20
    sleep = 0
21
    cpu_freq = '3GHz'
22
23
24
25
26

    def __init__(self):
        self.nics = []

    def full_name(self):
27
        return 'host.' + self.name
28
29

    def add_nic(self, nic):
30
        nic.name = self.name + '.' + nic.name
31
32
        self.nics.append(nic)

33
34
35
    def set_config(self, nc):
        self.node_config = nc

36
37
38
39
40
41
42
43
44
45
46
47
48
49
class NICSim(Simulator):
    network = None
    name = ''

    def set_network(self, net):
        self.network = net
        net.nics.append(self)

    def basic_run_cmd(self, env, name):
        return '%s/%s %s %s %s' % \
            (env.repodir, name, env.nic_pci_path(self), env.nic_eth_path(self),
                    env.nic_shm_path(self))

    def full_name(self):
50
        return 'nic.' + self.name
51
52
53

class NetSim(Simulator):
    name = ''
54
    opt = ''
55
56
57
58
59

    def __init__(self):
        self.nics = []

    def full_name(self):
60
        return 'net.' + self.name
61
62
63


class QemuHost(HostSim):
64
    sync = False
65
66
67
68
69
70
71
72
73
    def resreq_cores(self):
        return self.node_config.cores + 1

    def resreq_mem(self):
        return 4096

    def prep_cmds(self, env):
        to_path = env.hdcopy_path(self)
        return [f'{env.qemu_img_path} create -f qcow2 -o '
74
            f'backing_file="{env.hd_path(self.node_config.disk_image)}" '
75
76
77
            f'{env.hdcopy_path(self)}']

    def run_cmd(self, env):
78
79
        cmd = (f'{env.qemu_path} -machine q35 -serial mon:stdio '
            '-display none -nic none '
80
81
82
83
84
85
            f'-kernel {env.qemu_kernel_path} '
            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,'
                'driver=raw '
            '-append "earlyprintk=ttyS0 console=ttyS0 root=/dev/sda1 '
                'init=/home/ubuntu/guestinit.sh rw" '
86
            f'-m {self.node_config.memory} -smp {self.node_config.cores} ')
87
88
89
90
91
92

        if self.sync:
            cmd += ' -cpu Skylake-Server -icount shift=0,sleep=off '
        else:
            cmd += ' -cpu host -enable-kvm '

93
94
95
96
        if len(self.nics) > 0:
            assert len(self.nics) == 1
            cmd += f'-chardev socket,path={env.nic_pci_path(self.nics[0])},'
            cmd += 'id=cosimcd '
97
98
            sync_onoff = 'on' if self.sync else 'off'
            cmd += f'-device cosim-pci,chardev=cosimcd,sync={sync_onoff} '
99
100
101
102
103
104
        return cmd

class Gem5Host(HostSim):
    cpu_type_cp = 'X86KvmCPU'
    cpu_type = 'TimingSimpleCPU'

105

106
107
108
109
    def set_config(self, nc):
        nc.sim = 'gem5'
        super().set_config(nc)

110
111
112
113
114
115
    def resreq_cores(self):
        return 1

    def resreq_mem(self):
        return 4096

116
117
    def prep_cmds(self, env):
        return [f'mkdir -p {env.gem5_cpdir(self)}']
118
119
120
121
122
123
124
125
126

    def run_cmd(self, env):
        cpu_type = self.cpu_type
        if env.create_cp:
            cpu_type = self.cpu_type_cp

        cmd = (f'{env.gem5_path} --outdir={env.gem5_outdir(self)} '
            f'{env.gem5_py_path} --caches --l2cache --l3cache '
            '--l1d_size=32kB --l1i_size=32kB --l2_size=2MB --l3_size=32MB '
127
            f'--cacheline_size=64 --cpu-clock={self.cpu_freq} '
128
129
            f'--checkpoint-dir={env.gem5_cpdir(self)} '
            f'--kernel={env.gem5_kernel_path} '
130
            f'--disk-image={env.hd_raw_path(self.node_config.disk_image)} '
131
            f'--disk-image={env.cfgtar_path(self)} '
132
            f'--cpu-type={cpu_type} --mem-size={self.node_config.memory}MB '
133
            f'--num-cpus={self.node_config.cores} '
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
            '--ddio-enabled --ddio-way-part=8 --mem-type=DDR4_2400_16x4 ')

        if env.restore_cp:
            cmd += '-r 0 '

        if len(self.nics) > 0:
            assert len(self.nics) == 1
            nic = self.nics[0]
            cmd += f'--cosim-pci={env.nic_pci_path(nic)} '
            cmd += f'--cosim-shm={env.nic_shm_path(nic)} '
            if cpu_type == 'TimingSimpleCPU':
                cmd += '--cosim-sync '
            if isinstance(nic, I40eNIC):
                cmd += '--cosim-type=i40e '
        return cmd



class CorundumVerilatorNIC(NICSim):
    def resreq_mem(self):
        # this is a guess
        return 512

    def run_cmd(self, env):
        return self.basic_run_cmd(env, 'corundum/corundum_verilator')

class CorundumBMNIC(NICSim):
    def run_cmd(self, env):
        return self.basic_run_cmd(env, 'corundum_bm/corundum_bm')

class I40eNIC(NICSim):
    def run_cmd(self, env):
        return self.basic_run_cmd(env, 'i40e_bm/i40e_bm')



class WireNet(NetSim):
    def run_cmd(self, env):
        assert len(self.nics) == 2
        return '%s/net_wire/net_wire %s %s' % \
                (env.repodir, env.nic_eth_path(self.nics[0]),
                        env.nic_eth_path(self.nics[1]))

class SwitchNet(NetSim):
    def run_cmd(self, env):
        cmd = env.repodir + '/net_switch/net_switch'
        for n in self.nics:
            cmd += ' -s ' + env.nic_eth_path(n)
        return cmd
183
184


185
186
187
188
189
190
191
192
193
194
195
196
197
198
class NS3DumbbellNet(NetSim):
    def run_cmd(self, env):
        ports = ''
        for n in self.nics:
            if 'server' in n.name:
                ports += '--CosimPortLeft=' + env.nic_eth_path(n) + ' '
            else:
                ports += '--CosimPortRight=' + env.nic_eth_path(n) + ' '

        cmd = env.repodir + '/ns-3' + '/cosim-run.sh cosim cosim-dumbbell-example ' + ports + ' ' + self.opt
        print(cmd)

        return cmd

199
200
201
202
203
204
205
206
207
208
class NS3BridgeNet(NetSim):
    def run_cmd(self, env):
        ports = ''
        for n in self.nics:
            ports += '--CosimPort=' + env.nic_eth_path(n) + ' '

        cmd = env.repodir + '/ns-3' + '/cosim-run.sh cosim cosim-bridge-example ' + ports + ' ' + self.opt
        print(cmd)

        return cmd
209

210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
class NS3SequencerNet(NetSim):
    def run_cmd(self, env):
        ports = ''
        for n in self.nics:
            if 'client' in n.name:
                ports += '--ClientPort=' + env.nic_eth_path(n) + ' '
            elif 'replica' in n.name:
                ports += '--ServerPort=' + env.nic_eth_path(n) + ' '
            elif 'sequencer' in n.name:
                ports += '--EndhostSequencerPort=' + env.nic_eth_path(n) + ' '
            else:
                raise Exception('Wrong NIC type')
        cmd = env.repodir + '/ns-3' + '/cosim-run.sh sequencer sequencer-single-switch-example ' + ports + ' ' + self.opt
        return cmd


226
227
228
229
230
def create_basic_hosts(e, num, name_prefix, net, nic_class, host_class,
        nc_class, app_class, ip_start=1):
    hosts = []
    for i in range(0, num):
        nic = nic_class()
231
        #nic.name = '%s.%d' % (name_prefix, i)
232
233
234
235
        nic.set_network(net)

        host = host_class()
        host.name = '%s.%d' % (name_prefix, i)
236
237
238
239
240
241

        node_config = nc_class()
        node_config.ip = '10.0.0.%d' % (ip_start + i)
        node_config.app = app_class()
        host.set_config(node_config)

242
243
244
245
246
247
248
        host.add_nic(nic)
        e.add_nic(nic)
        e.add_host(host)

        hosts.append(host)

    return hosts
249
250
251
252
253
254
255
256
257
258
259
260


def create_dctcp_hosts(e, num, name_prefix, net, nic_class, host_class,
        nc_class, app_class, cpu_freq, mtu, ip_start=1):
    hosts = []
    for i in range(0, num):
        nic = nic_class()
        #nic.name = '%s.%d' % (name_prefix, i)
        nic.set_network(net)

        host = host_class()
        host.name = '%s.%d' % (name_prefix, i)
Hejing Li's avatar
Hejing Li committed
261
        host.cpu_freq = cpu_freq
262
263
264
265
266
267
268
269
270
271
272
273
274
275

        node_config = nc_class()
        node_config.mtu = mtu
        node_config.ip = '192.168.64.%d' % (ip_start + i)
        node_config.app = app_class()
        host.set_config(node_config)

        host.add_nic(nic)
        e.add_nic(nic)
        e.add_host(host)

        hosts.append(host)

    return hosts