howto.rst 8.61 KB
Newer Older
Antoine Kaufmann's avatar
Antoine Kaufmann committed
1
..
Antoine Kaufmann's avatar
Antoine Kaufmann committed
2
  Copyright 2022 Max Planck Institute for Software Systems, and
Antoine Kaufmann's avatar
Antoine Kaufmann committed
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
  National University of Singapore
..
  Permission is hereby granted, free of charge, to any person obtaining
  a copy of this software and associated documentation files (the
  "Software"), to deal in the Software without restriction, including
  without limitation the rights to use, copy, modify, merge, publish,
  distribute, sublicense, and/or sell copies of the Software, and to
  permit persons to whom the Software is furnished to do so, subject to
  the following conditions:
..
  The above copyright notice and this permission notice shall be
  included in all copies or substantial portions of the Software.
..
  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

24
25
.. _sec-howto:

26
###################################
Antoine Kaufmann's avatar
Antoine Kaufmann committed
27
How To
28
29
30
###################################


31
32
.. _sec-howto-createrun:

33
******************************
Antoine Kaufmann's avatar
Antoine Kaufmann committed
34
Create and Run an Experiment
35
36
******************************

37
38
39
Experiments are defined in a declarative fashion inside Python modules using
classes. Basically, create a `.py` file and add a global variable
``experiments``, a list which contains multiple instances of the class
40
:class:`~simbricks.orchestration.experiments.Experiment`, each one describing a
41
42
standalone experiment. This is very helpful if you wish to evaluate your work in
different environments, for example, you may want to swap out some simulator or
43
investigate multiple topologies with different scale. 
44
45
46

The class :class:`~simbricks.orchestration.experiments.Experiment` provides
methods to add the simulators you wish to run. All available simulators can be
47
found in the module :mod-orchestration:`simulators.py`. Instantiating
48
49
:class:`~simbricks.orchestration.simulators.HostSim` requires you to specify a
:class:`~simbricks.orchestration.nodeconfig.NodeConfig`, which contains the
50
51
configuration for your host, for example, its networking settings, how much
system memory it should have, and most importantly, which applications to run by
52
53
assigning an :class:`~simbricks.orchestration.nodeconfig.AppConfig`. You can
find predefined classes for node and app configs in the module
54
55
56
:mod-orchestration:`nodeconfig.py`. Feel free to add new ones or just create a
new class locally in your experiment's module. For more details, see
:ref:`sec-orchestration`.
57
58
59
60

The last step to complete your virtual testbed is to specify which virtual
components connect to each other. You do this by invoking the respective methods
on the simulators you have instantiated. See the different simulator types' base
61
62
63
classes in the module :mod-orchestration:`simulators.py` for more information. A
simple and complete experiment module in which a client host pings a server can
be found :ref:`below <simple_ping_experiment>`.
64
65

If you plan to simulate a topology with multiple hosts, it may be helpful to
66
67
take a look at the module :mod-orchestration:`simulator_utils.py` in which we
provide some helper functions to reduce the amount of code you have to write.
68

69
70
71
72
Finally, to run your experiment, invoke
:simbricks-repo:`experiments/run.py </blob/main/experiments/run.py>`
and provide the path to your experiment module. In our docker containers, you
can also just use the following command from anywhere:
73
74
75
76
77

.. code-block:: bash

  $ simbricks-run --verbose --force <path_to_your_module.py>

78
``--verbose`` prints all simulators' output to the terminal and ``--force``
79
80
forces execution even if there already exist result files for the experiment. If
``simbricks-run`` is not available, you can always do 
81
82
83
84
85
86

.. code-block:: bash
  
  $ cd experiments
  $ python run.py --verbose --force <path_to_your_module.py>

87
While running, you can interrupt the experiment using Ctrl+C in your terminal.
88
89
90
This will cleanly stop all simulators and collect their output in a JSON file in
the directory ``experiments/out/<experiment_name>``. These are the necessary
basics to create and run your first experiment. Have fun.
91
92
93

.. literalinclude:: /../experiments/pyexps/simple_ping.py
  :linenos:
94
  :lines: 29-
95
96
  :language: python
  :name: simple_ping_experiment
97
98
99
  :caption: A simple experiment with a client host pinging a server, both are
    connected through a network switch. The setup of the two hosts could be
    simplified by using
100
    :func:`simbricks.orchestration.simulator_utils.create_basic_hosts`.
101
102
103

.. _sec-howto-nodeconfig:

Antoine Kaufmann's avatar
Antoine Kaufmann committed
104
105
106
********************************
Add a Node or Application Config
********************************
107

108
109
A host's configuration and the workload to run are defined via
:ref:`sec-node_app_config`. SimBricks already comes with a few examples in the
110
111
112
113
114
module :mod-orchestration:`nodeconfig.py`. If they don't fit your use-case, you
need to add your own by overriding the pre-defined member functions of
:class:`~simbricks.orchestration.nodeconfig.NodeConfig` and
:class:`~simbricks.orchestration.nodeconfig.AppConfig`. The most important one
is :meth:`~simbricks.orchestration.nodeconfig.AppConfig.run_cmds`, which defines
115
the commands to execute for your workload/application. Further information can
116
be found in the module :mod-orchestration:`nodeconfig.py` directly.
117
118
119

.. _sec-howto-custom_image:

120
******************************
Antoine Kaufmann's avatar
Antoine Kaufmann committed
121
Add a Custom Image
122
123
******************************

124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
First off, make sure you actually need a custom image. You can find more
information on this under :ref:`sec-images`. We have a tutorial in our
:simbricks-examples:`examples repository <>` that highlights how to add a
custom, out-of-tree image for a simple Memcached experiment. Further, we are
currently reworking our orchestration framework to greatly simplify the process
of defining your own custom image, abstracting away the need to manually build
and manage it.

For the moment, here is some additional information on the inner details of the
image building process: We use `Packer <https://www.packer.io/>`_, which
essentially starts a QEMU VM with internet access, boots up the kernel and then
runs an installation script inside to change configs and install required
packages either through ``apt`` or from source. You can find examples of
installation scripts for our in-tree images under
:simbricks-repo:`images/scripts </blob/main/images/scripts>`. The commands for
building them reside in the file :simbricks-repo:`images/rules.mk
</blob/main/images/rules.mk>`.

The produced images are stored as ``images/output-<image_name>/<image-name>``.
By default, we produce disk images in the compressed ``qcow2`` format. Some of
our host simulators, e.g. gem5 and Simics, require raw disk images though, which
are substantially larger. The ``qcow2`` can be easily converted to raw with
``qemu-img convert``. For our in-tree images there's a Makefile target for this,
which stores the converted images as
``images/output-<image_name>/<image-name>.raw``.

.. code-block:: bash

  $ make convert-images-raw

154
******************************
Antoine Kaufmann's avatar
Antoine Kaufmann committed
155
Integrate a New Simulator
156
157
******************************

158
159
160
161
162
163
164
165
166
167
168
169
170
The first step is to implement a SimBricks adapter in the simulator you want to
integrate. This adapter on one side uses the simulator's extension API to act as
a native device and on the other side sends and receives SimBricks messages. You
can find more information on adapters in our :ref:`page-architectural-overview`.

To make running experiments and setting up the SimBricks communication channels
to other simulators convenient, add a class for the simulator in
:mod-orchestration:`simulators.py`` that inherits either from
:class:`~simbricks.orchestration.simulators.Simulator` or one of the more
specialized base classes in. In this class, you define the command(s) to execute
the simulator together with further parameters, for example, to connect to the
communication channels with other simulators. Below is an example of what this
looks like.
171

Jonas Kaufmann's avatar
Jonas Kaufmann committed
172
.. code-block:: python
173
  :linenos:
174
175
  :caption: Orchestration framework class for WireNet, a simple Ethernet wire
    that attaches to the SimBricks Ethernet adapters of two simulators.
Jonas Kaufmann's avatar
Jonas Kaufmann committed
176

177
  class WireNet(NetSim):
Jonas Kaufmann's avatar
Jonas Kaufmann committed
178
179

    def run_cmd(self, env):
180
181
        connects = self.connect_sockets(env)
        assert len(connects) == 2
Jonas Kaufmann's avatar
Jonas Kaufmann committed
182
        cmd = (
183
184
185
            f'{env.repodir}/sims/net/wire/net_wire {connects[0][1]}'
            f' {connects[1][1]} {self.sync_mode} {self.sync_period}'
            f' {self.eth_latency}'
Jonas Kaufmann's avatar
Jonas Kaufmann committed
186
        )
187
188
189
        if env.pcap_file:
            cmd += ' ' + env.pcap_file
        
Jonas Kaufmann's avatar
Jonas Kaufmann committed
190
        return cmd
191