Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ycai
simbricks
Commits
79b2ee78
Unverified
Commit
79b2ee78
authored
Nov 28, 2024
by
Jakob Görgen
Browse files
deserialization of simulation json
parent
f779730a
Changes
6
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
189 additions
and
77 deletions
+189
-77
experiments/simbricks/orchestration/simulation/base.py
experiments/simbricks/orchestration/simulation/base.py
+85
-22
experiments/simbricks/orchestration/simulation/channel.py
experiments/simbricks/orchestration/simulation/channel.py
+15
-4
experiments/simbricks/orchestration/simulation/host.py
experiments/simbricks/orchestration/simulation/host.py
+25
-8
experiments/simbricks/orchestration/simulation/net/net_base.py
...iments/simbricks/orchestration/simulation/net/net_base.py
+41
-27
experiments/simbricks/orchestration/simulation/pcidev.py
experiments/simbricks/orchestration/simulation/pcidev.py
+14
-13
experiments/simbricks/orchestration/system/base.py
experiments/simbricks/orchestration/system/base.py
+9
-3
No files found.
experiments/simbricks/orchestration/simulation/base.py
View file @
79b2ee78
...
...
@@ -48,11 +48,11 @@ class Simulator(utils_base.IdObj):
)
->
None
:
super
().
__init__
()
self
.
name
:
str
=
name
self
.
_executable
=
executable
self
.
_executable
:
str
=
executable
self
.
_simulation
:
sim_base
.
Simulation
=
simulation
self
.
_components
:
set
[
sys_conf
.
Component
]
=
set
()
self
.
_wait
:
bool
=
False
self
.
_start_tick
=
0
self
.
_start_tick
:
int
=
0
"""The timestamp at which to start the simulation. This is useful when
the simulator is only attached at a later point in time and needs to
synchronize with connected simulators. For example, this could be used
...
...
@@ -116,14 +116,33 @@ class Simulator(utils_base.IdObj):
json_obj
[
"wait"
]
=
self
.
_wait
json_obj
[
"start_tick"
]
=
self
.
_start_tick
if
self
.
_extra_args
:
json_obj
[
"extra_args"
]
=
self
.
_extra_args
return
json_obj
@
staticmethod
def
fromJSON
(
json_obj
):
# TODO: FIXME
pass
@
classmethod
def
fromJSON
(
cls
,
simulation
:
Simulation
,
json_obj
:
dict
)
->
Simulator
:
instance
=
super
().
fromJSON
(
json_obj
)
instance
.
name
=
utils_base
.
get_json_attr_top
(
json_obj
,
"name"
)
instance
.
_executable
=
utils_base
.
get_json_attr_top
(
json_obj
,
"executable"
)
sim_id
=
int
(
utils_base
.
get_json_attr_top
(
json_obj
,
"simulation"
))
assert
sim_id
==
simulation
.
id
()
instance
.
_simulation
=
simulation
instance
.
_components
=
set
()
components_json
=
utils_base
.
get_json_attr_top
(
json_obj
,
"components"
)
for
comp_id
in
components_json
:
component
=
simulation
.
system
.
get_comp
(
comp_id
)
Simulator
.
add
(
instance
,
component
)
# instance.add(component)
instance
.
_wait
=
bool
(
utils_base
.
get_json_attr_top
(
json_obj
,
"wait"
))
instance
.
_start_tick
=
int
(
utils_base
.
get_json_attr_top
(
json_obj
,
"start_tick"
))
instance
.
_extra_args
=
utils_base
.
get_json_attr_top_or_none
(
json_obj
,
"extra_args"
)
return
instance
@
staticmethod
def
filter_sockets
(
...
...
@@ -329,7 +348,6 @@ class Simulation(utils_base.IdObj):
json_obj
[
"name"
]
=
self
.
name
json_obj
[
"system"
]
=
self
.
system
.
id
()
if
self
.
timeout
:
json_obj
[
"timeout"
]
=
self
.
timeout
simulators_json
=
[]
...
...
@@ -339,11 +357,12 @@ class Simulation(utils_base.IdObj):
json_obj
[
"sim_list"
]
=
simulators_json
sys_sim_map_json
=
[]
for
comp
,
sim
in
self
.
_sys_sim_map
.
items
():
sys_sim_map_json
.
append
({
comp
.
id
():
sim
.
id
()})
# TODO: we do not need this --> we can create it implicitly when deserializing because the simulators store a list of components themselves
# sys_sim_map_json = []
# for comp, sim in self._sys_sim_map.items():
# sys_sim_map_json.append([comp.id(), sim.id()])
json_obj
[
"sys_sim_map"
]
=
sys_sim_map_json
#
json_obj["sys_sim_map"] = sys_sim_map_json
chan_map_json
=
[]
chan_json
=
[]
...
...
@@ -351,19 +370,54 @@ class Simulation(utils_base.IdObj):
sys_chan
,
sim_chan
,
)
in
self
.
_chan_map
.
items
():
chan_map_json
.
append
({
sys_chan
.
id
():
sim_chan
.
id
()})
utils_base
.
has_attribute
(
sim_chan
,
"toJSON"
)
chan_json
.
append
(
sim_chan
.
toJSON
())
chan_json
=
sim_chan
.
toJSON
()
chan_map_json
.
append
([
sys_chan
.
id
(),
chan_json
])
# chan_json.append(sim_chan.toJSON())
json_obj
[
"chan_map"
]
=
chan_map_json
json_obj
[
"simulation_channels"
]
=
chan_json
#
json_obj["simulation_channels"] = chan_json
return
json_obj
@
staticmethod
def
fromJSON
(
json_obj
):
# TODO: FIXME
pass
@
classmethod
def
fromJSON
(
cls
,
system
:
sys_conf
.
System
,
json_obj
:
dict
)
->
Simulation
:
instance
=
super
().
fromJSON
(
json_obj
)
instance
.
name
=
utils_base
.
get_json_attr_top
(
json_obj
,
"name"
)
system_id
=
int
(
utils_base
.
get_json_attr_top
(
json_obj
,
"system"
))
assert
system_id
==
system
.
id
()
instance
.
system
=
system
instance
.
timeout
=
utils_base
.
get_json_attr_top_or_none
(
json_obj
,
"timeout"
)
instance
.
_sim_list
=
[]
instance
.
_sys_sim_map
=
{}
simulators_json
=
utils_base
.
get_json_attr_top
(
json_obj
,
"sim_list"
)
for
sim_json
in
simulators_json
:
sim_class
=
utils_base
.
get_cls_by_json
(
sim_json
)
utils_base
.
has_attribute
(
sim_class
,
"fromJSON"
)
sim
=
sim_class
.
fromJSON
(
instance
,
sim_json
)
instance
.
_sim_list
.
append
(
sim
)
# TODO: probably do not need this --> we create it when deserializing the simulators that store a list of components themselves
# instance._sys_sim_map: dict[sys_conf.Component, Simulator] = {}
# sys_sim_map_json = utils_base.get_json_attr_top(json_obj, "sys_sim_map")
# print(sys_sim_map_json)
# for sys_id, sim_id in sys_sim_map_json:
# print(f"{sys_id} --> {sim_id}")
# # TODO
# pass
instance
.
_chan_map
=
{}
chan_map_json
=
utils_base
.
get_json_attr_top
(
json_obj
,
"chan_map"
)
for
sys_id
,
chan_json
in
chan_map_json
:
chan_class
=
utils_base
.
get_cls_by_json
(
chan_json
)
utils_base
.
has_attribute
(
chan_class
,
"fromJSON"
)
sim_chan
=
chan_class
.
fromJSON
(
instance
,
chan_json
)
sys_chan
=
instance
.
system
.
get_chan
(
sys_id
)
instance
.
update_channel_mapping
(
sys_chan
=
sys_chan
,
sim_chan
=
sim_chan
)
return
instance
def
add_sim
(
self
,
sim
:
Simulator
):
if
sim
in
self
.
_sim_list
:
...
...
@@ -379,12 +433,21 @@ class Simulation(utils_base.IdObj):
def
is_channel_instantiated
(
self
,
chan
:
sys_conf
.
Channel
)
->
bool
:
return
chan
in
self
.
_chan_map
def
update_channel_mapping
(
self
,
sys_chan
:
sys_conf
.
Channel
,
sim_chan
:
sim_chan
.
Channel
)
->
None
:
if
self
.
is_channel_instantiated
(
sys_chan
):
raise
Exception
(
f
"channel
{
sys_chan
}
is already mapped. Cannot insert mapping
{
sys_chan
.
id
()
}
->
{
sim_chan
.
id
()
}
"
)
self
.
_chan_map
[
sys_chan
]
=
sim_chan
def
retrieve_or_create_channel
(
self
,
chan
:
sys_conf
.
Channel
)
->
sim_chan
.
Channel
:
if
self
.
is_channel_instantiated
(
chan
):
return
self
.
_chan_map
[
chan
]
channel
=
sim_chan
.
Channel
(
chan
)
self
.
_chan_map
[
chan
]
=
channel
self
.
update
_chan
nel
_map
ping
(
sys_chan
=
chan
,
sim_chan
=
channel
)
return
channel
def
all_simulators
(
self
)
->
list
[
Simulator
]:
...
...
experiments/simbricks/orchestration/simulation/channel.py
View file @
79b2ee78
...
...
@@ -20,8 +20,11 @@
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
from
__future__
import
annotations
import
enum
from
simbricks.orchestration.simulation
import
base
as
sim_base
from
simbricks.orchestration.system
import
base
as
system_base
from
simbricks.orchestration.utils
import
base
as
utils_base
...
...
@@ -51,10 +54,18 @@ class Channel(utils_base.IdObj):
json_obj
[
"sys_channel"
]
=
self
.
sys_channel
.
id
()
return
json_obj
@
staticmethod
def
fromJSON
(
json_obj
):
# TODO
pass
@
classmethod
def
fromJSON
(
cls
,
simulation
:
sim_base
.
Simulation
,
json_obj
:
dict
)
->
Channel
:
instance
=
super
().
fromJSON
(
json_obj
)
instance
.
_synchronized
=
bool
(
utils_base
.
get_json_attr_top
(
json_obj
,
"synchronized"
)
)
instance
.
sync_period
=
int
(
utils_base
.
get_json_attr_top
(
json_obj
,
"sync_period"
)
)
chan_id
=
int
(
utils_base
.
get_json_attr_top
(
json_obj
,
"sys_channel"
))
instance
.
sys_channel
=
simulation
.
system
.
get_chan
(
chan_id
)
return
instance
def
full_name
(
self
)
->
str
:
return
"channel."
+
self
.
name
...
...
experiments/simbricks/orchestration/simulation/host.py
View file @
79b2ee78
...
...
@@ -38,6 +38,13 @@ class HostSim(sim_base.Simulator):
def
__init__
(
self
,
simulation
:
sim_base
.
Simulation
,
executable
:
str
,
name
=
""
):
super
().
__init__
(
simulation
=
simulation
,
executable
=
executable
,
name
=
name
)
def
toJSON
(
self
)
->
dict
:
return
super
().
toJSON
()
@
classmethod
def
fromJSON
(
cls
,
simulation
:
sim_base
.
Simulation
,
json_obj
:
dict
)
->
Gem5Sim
:
return
super
().
fromJSON
(
simulation
,
json_obj
)
def
full_name
(
self
)
->
str
:
return
"host."
+
self
.
name
...
...
@@ -92,10 +99,20 @@ class Gem5Sim(HostSim):
json_obj
[
"_sys_clock"
]
=
self
.
_sys_clock
return
json_obj
@
staticmethod
def
fromJSON
(
json_obj
):
# TODO: FIXME
pass
@
classmethod
def
fromJSON
(
cls
,
simulation
:
sim_base
.
Simulation
,
json_obj
:
dict
)
->
Gem5Sim
:
instance
=
super
().
fromJSON
(
simulation
,
json_obj
)
instance
.
cpu_type_cp
=
utils_base
.
get_json_attr_top
(
json_obj
,
"cpu_type_cp"
)
instance
.
cpu_type
=
utils_base
.
get_json_attr_top
(
json_obj
,
"cpu_type"
)
instance
.
extra_main_args
=
utils_base
.
get_json_attr_top
(
json_obj
,
"extra_main_args"
)
instance
.
extra_config_args
=
utils_base
.
get_json_attr_top
(
json_obj
,
"extra_config_args"
)
instance
.
_variant
=
utils_base
.
get_json_attr_top
(
json_obj
,
"_variant"
)
instance
.
_sys_clock
=
utils_base
.
get_json_attr_top
(
json_obj
,
"_sys_clock"
)
return
instance
async
def
prepare
(
self
,
inst
:
inst_base
.
Instantiation
)
->
None
:
await
super
().
prepare
(
inst
=
inst
)
...
...
@@ -237,10 +254,9 @@ class QemuSim(HostSim):
# disks is created upon invocation of "prepare", hence we do not need to serialize it
return
json_obj
@
staticmethod
def
fromJSON
(
json_obj
):
# TODO: FIXME
pass
@
classmethod
def
fromJSON
(
cls
,
simulation
:
sim_base
.
Simulation
,
json_obj
:
dict
)
->
QemuSim
:
return
super
().
fromJSON
(
simulation
,
json_obj
)
async
def
prepare
(
self
,
inst
:
inst_base
.
Instantiation
)
->
None
:
await
super
().
prepare
(
inst
=
inst
)
...
...
@@ -331,4 +347,5 @@ class QemuSim(HostSim):
cmd
+=
",sync=off"
cmd
+=
" "
print
(
cmd
)
return
cmd
experiments/simbricks/orchestration/simulation/net/net_base.py
View file @
79b2ee78
...
...
@@ -20,6 +20,8 @@
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
from
__future__
import
annotations
from
simbricks.orchestration.system
import
base
as
sys_base
from
simbricks.orchestration.system
import
eth
as
sys_eth
from
simbricks.orchestration.simulation
import
base
as
sim_base
...
...
@@ -51,13 +53,11 @@ class NetSim(sim_base.Simulator):
def
toJSON
(
self
)
->
dict
:
json_obj
=
super
().
toJSON
()
# TODO: FIXME
return
json_obj
@
staticmethod
def
fromJSON
(
json_obj
):
# TODO: FIXME
pass
@
classmethod
def
fromJSON
(
cls
,
simulation
:
sim_base
.
Simulation
,
json_obj
:
dict
)
->
NetSim
:
return
super
().
fromJSON
(
simulation
,
json_obj
)
class
WireNet
(
NetSim
):
...
...
@@ -85,10 +85,11 @@ class WireNet(NetSim):
json_obj
[
"relative_pcap_file_path"
]
=
self
.
_relative_pcap_file_path
return
json_obj
@
staticmethod
def
fromJSON
(
json_obj
):
@
classmethod
def
fromJSON
(
cls
,
simulation
:
sim_base
.
Simulation
,
json_obj
:
dict
)
->
WireNet
:
instance
=
super
().
fromJSON
(
simulation
,
json_obj
)
# TODO: FIXME
pass
return
instance
def
run_cmd
(
self
,
inst
:
inst_base
.
Instantiation
)
->
str
:
channels
=
self
.
get_channels
()
...
...
@@ -136,10 +137,11 @@ class SwitchNet(NetSim):
json_obj
[
"relative_pcap_file_path"
]
=
self
.
_relative_pcap_file_path
return
json_obj
@
staticmethod
def
fromJSON
(
json_obj
):
@
classmethod
def
fromJSON
(
cls
,
simulation
:
sim_base
.
Simulation
,
json_obj
:
dict
)
->
SwitchNet
:
instance
=
super
().
fromJSON
(
simulation
,
json_obj
)
# TODO: FIXME
pass
return
instance
def
run_cmd
(
self
,
inst
:
inst_base
.
Instantiation
)
->
str
:
channels
=
self
.
get_channels
()
...
...
@@ -189,10 +191,11 @@ class MemSwitchNet(SwitchNet):
json_obj
=
super
().
toJSON
()
return
json_obj
@
staticmethod
def
fromJSON
(
json_obj
):
@
classmethod
def
fromJSON
(
cls
,
simulation
:
sim_base
.
Simulation
,
json_obj
:
dict
)
->
MemSwitchNet
:
instance
=
super
().
fromJSON
(
simulation
,
json_obj
)
# TODO: FIXME
pass
return
instance
def
run_cmd
(
self
,
inst
:
inst_base
.
Instantiation
)
->
str
:
cmd
=
super
().
run_cmd
(
inst
)
...
...
@@ -224,14 +227,17 @@ class SimpleNS3Sim(NetSim):
def
toJSON
(
self
)
->
dict
:
json_obj
=
super
().
toJSON
()
json_obj
[
"ns3_run_script"
]
=
self
.
_ns3_run_script
if
self
.
opt
:
json_obj
[
"opt"
]
=
self
.
opt
return
json_obj
@
staticmethod
def
fromJSON
(
json_obj
):
# TODO: FIXME
pass
@
classmethod
def
fromJSON
(
cls
,
simulation
:
sim_base
.
Simulation
,
json_obj
:
dict
)
->
SimpleNS3Sim
:
instance
=
super
().
fromJSON
(
simulation
,
json_obj
)
instance
.
_ns3_run_script
=
base_utils
.
get_json_attr_top
(
json_obj
,
"ns3_run_script"
)
instance
.
opt
=
base_utils
.
get_json_attr_top_or_none
(
json_obj
,
"opt"
)
return
instance
def
run_cmd
(
self
,
inst
:
inst_base
.
Instantiation
)
->
str
:
return
f
"
{
inst
.
join_repo_base
(
self
.
_executable
)
}
{
self
.
_ns3_run_script
}
"
...
...
@@ -270,10 +276,16 @@ class NS3DumbbellNet(SimpleNS3Sim):
json_obj
[
"right"
]
=
self
.
_right
.
id
()
return
json_obj
@
staticmethod
def
fromJSON
(
json_obj
):
# TODO: FIXME
pass
@
classmethod
def
fromJSON
(
cls
,
simulation
:
sim_base
.
Simulation
,
json_obj
:
dict
)
->
NS3DumbbellNet
:
instance
=
super
().
fromJSON
(
simulation
,
json_obj
)
left_id
=
int
(
base_utils
.
get_json_attr_top
(
json_obj
,
"left"
))
instance
.
_left
=
json_obj
[
"left"
]
=
simulation
.
system
.
get_comp
(
left_id
)
right_id
=
int
(
base_utils
.
get_json_attr_top
(
json_obj
,
"right"
))
instance
.
_right
=
json_obj
[
"right"
]
=
simulation
.
system
.
get_comp
(
right_id
)
return
instance
def
run_cmd
(
self
,
inst
:
inst_base
.
Instantiation
)
->
str
:
cmd
=
super
().
run_cmd
(
inst
=
inst
)
...
...
@@ -291,6 +303,7 @@ class NS3DumbbellNet(SimpleNS3Sim):
if
self
.
opt
is
not
None
:
cmd
+=
f
"
{
self
.
opt
}
"
print
(
cmd
)
return
cmd
...
...
@@ -313,10 +326,11 @@ class NS3BridgeNet(SimpleNS3Sim):
json_obj
=
super
().
toJSON
()
return
json_obj
@
staticmethod
def
fromJSON
(
json_obj
):
@
classmethod
def
fromJSON
(
cls
,
simulation
:
sim_base
.
Simulation
,
json_obj
:
dict
)
->
NS3BridgeNet
:
instance
=
super
().
fromJSON
(
simulation
,
json_obj
)
# TODO: FIXME
pass
return
instance
def
run_cmd
(
self
,
inst
:
inst_base
.
Instantiation
)
->
str
:
cmd
=
super
().
run_cmd
(
inst
=
inst
)
...
...
experiments/simbricks/orchestration/simulation/pcidev.py
View file @
79b2ee78
...
...
@@ -110,10 +110,9 @@ class I40eNicSim(NICSim):
json_obj
=
super
().
toJSON
()
return
json_obj
@
staticmethod
def
fromJSON
(
json_obj
):
# TODO: FIXME
pass
@
classmethod
def
fromJSON
(
cls
,
simulation
:
sim_base
.
Simulation
,
json_obj
:
dict
)
->
I40eNicSim
:
return
super
().
fromJSON
(
simulation
,
json_obj
)
def
run_cmd
(
self
,
inst
:
inst_base
.
Instantiation
)
->
str
:
return
super
().
run_cmd
(
inst
=
inst
)
...
...
@@ -131,10 +130,11 @@ class CorundumBMNICSim(NICSim):
json_obj
=
super
().
toJSON
()
return
json_obj
@
staticmethod
def
fromJSON
(
json_obj
):
# TODO: FIXME
pass
@
classmethod
def
fromJSON
(
cls
,
simulation
:
sim_base
.
Simulation
,
json_obj
:
dict
)
->
CorundumBMNICSim
:
return
super
().
fromJSON
(
simulation
,
json_obj
)
def
run_cmd
(
self
,
inst
:
inst_base
.
Instantiation
)
->
str
:
cmd
=
super
().
run_cmd
(
inst
=
inst
)
...
...
@@ -160,10 +160,11 @@ class CorundumVerilatorNICSim(NICSim):
json_obj
[
"clock_freq"
]
=
self
.
clock_freq
return
json_obj
@
staticmethod
def
fromJSON
(
json_obj
):
# TODO: FIXME
pass
@
classmethod
def
fromJSON
(
cls
,
simulation
:
sim_base
.
Simulation
,
json_obj
:
dict
)
->
CorundumVerilatorNICSim
:
return
super
().
fromJSON
(
simulation
,
json_obj
)
def
run_cmd
(
self
,
inst
:
inst_base
.
Instantiation
)
->
str
:
cmd
=
super
().
run_cmd
(
inst
=
inst
)
...
...
experiments/simbricks/orchestration/system/base.py
View file @
79b2ee78
...
...
@@ -45,7 +45,9 @@ class System(util_base.IdObj):
self
.
_all_components
[
c
.
id
()]
=
c
def
get_comp
(
self
,
ident
:
int
)
->
Component
:
assert
ident
in
self
.
_all_components
if
ident
not
in
self
.
_all_components
:
raise
Exception
(
f
"system object does not store component with id
{
ident
}
"
)
return
self
.
_all_components
[
ident
]
def
_add_interface
(
self
,
i
:
Interface
)
->
None
:
...
...
@@ -54,7 +56,9 @@ class System(util_base.IdObj):
self
.
_all_interfaces
[
i
.
id
()]
=
i
def
get_inf
(
self
,
ident
:
int
)
->
Interface
:
assert
ident
in
self
.
_all_interfaces
if
ident
not
in
self
.
_all_interfaces
:
raise
Exception
(
f
"system object does not store interface with id
{
ident
}
"
)
return
self
.
_all_interfaces
[
ident
]
def
_add_channel
(
self
,
c
:
Channel
)
->
None
:
...
...
@@ -63,7 +67,9 @@ class System(util_base.IdObj):
self
.
_all_channels
[
c
.
id
()]
=
c
def
get_chan
(
self
,
ident
:
int
)
->
Channel
:
assert
ident
in
self
.
_all_channels
if
ident
not
in
self
.
_all_channels
:
raise
Exception
(
f
"system does not store channel with id
{
ident
}
"
)
return
self
.
_all_channels
[
ident
]
def
toJSON
(
self
)
->
dict
:
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment