Package: coord-sim
Simulation: Inter-node service coordination and flow schedulingSimulate flow-level, inter-node network coordination including scaling and placement of services and scheduling/balancing traffic between them.Features:Simulate any given network topology with arbitrary node and link capacities and link delaysSimulate any given network service consisting of linearly chained SFs/VNFsVNFs can specify arbitrary resource consumption as function of their load using Python modules. Also VNF delay can be specified individually and may be normally distributed.Simulate network traffic in the form of flow arrivals at various ingress nodes with varying arrival rate, flow length, volume, etc according to stochastic distributionsSimple and clear interface to run algorithms for scaling, placement, and scheduling/load balancing of these incoming flows across the nodes in the network. Coordination within each node is out of scope.Interface allows easy integration with OpenAI Gym to enable training and evaluating reinforcement learning algorithmsCollection of metrics like successful/dropped flows, end-to-end delay, resource consumption, etc over time. Easily extensible.Discrete event simulation to evaluate coordination over time with SimPyGraceful adjustment of placements: When VNFs are removed from a placement by an algorithm. Currently processing flows are allowed to finish processing before the VNF is completely removed (see PR#78and#81).Projects Using coord-simDeepCoord: Centralized Deep Reinforcement Learning (DRL) ApproachDistributed DRL ApproachB-JointSP: Centralized Heuristic Approach(correspondingadapter code)Two Fully Distributed Heuristic ApproachesSimple baselines for comparisonFeel free to open a pull request and add your own project if you use coord-sim!SetupInstall with (ideally usingvirtualenv):pipinstall.# For dev install: pip install -e .UsageTypecoord-sim -hfor help using the simulator. For now, this should print$ coord-sim -h
usage: coord-sim [-h] -d DURATION -sf SF [-sfr SFR] -n NETWORK -c CONFIG
                 [-t TRACE] [-s SEED]

Coordination-Simulation tool

optional arguments:
  -h, --help            show this help message and exit
  -d DURATION, --duration DURATION
                        The duration of the simulation (simulates
                        milliseconds).
  -sf SF, --sf SF       VNF file which contains the SFCs and their respective
                        SFs and their properties.
  -sfr SFR, --sfr SFR   Path which contains the SF resource consumption
                        functions.
  -n NETWORK, --network NETWORK
                        The GraphML network file that specifies the nodes and
                        edges of the network.
  -c CONFIG, --config CONFIG
                        Path to the simulator config file.
  -t TRACE, --trace TRACE
                        Provide a CSV trace file to configure the traffic the
                        simulator is generating.
  -s SEED, --seed SEED  Random seedYou can use the following command as an example (run from the root project folder)coord-sim-d20-nparams/networks/triangle.graphml-sfparams/services/abc.yaml-sfrparams/services/resource_functions-cparams/config/sim_config.yamlThis will run a simulation on a provided GraphML network file and a YAML placement file for a duration of 20 timesteps.Dynamic SF resource consumptionBy default, all SFs have a node resource consumption, which exactly equals the aggregated traffic that they have to handle.It is possible to specify arbitrary other resource consumption models simply by implementing a python module with a
functionresource_function(load)(see exampleshere).To use these modules, they need to be referenced in the service file:sf_list:
    a:
      processing_delay_mean: 5.0
      processing_delay_stdev: 0.0
      resource_function_id: AAnd the path to the folder with the Python modules needs to be passed via the-sfrargument.See PRhttps://github.com/RealVNF/coordination-simulation/pull/78for details.Egress nodesA node can be set to be aEgressnode in theNodeTypeattribute of the network fileIf some nodes are set asEgressthen only the simulator will randomly choose one of them as the Egress node for each flow in the networkIf some nodes are set to be Egress then once the flow is processed we check if for the flow,current node == egress node. If Yes then we depart , otherwise we forward the flow to the egress_node using the shortest_path routing.Todo: Ideally the coordination algorithms should keep the path(Ingress to Egress) of the flow in view while creating the schedule/placement.SeePR 137for details.Conversion of real world traffic tracesReal World traffic traces are available atsndlibunder 'Dynamic traffic' at the left. They contain the data rate for every pair of node in a network for every 5 minutes for a timespan of six months. Available data formats are xml and another "native sndlib format". For usage in the simulator this data has to be converted into inter_arrival_mean. A script for that (which works with the xml files) you find herecoord-sim/params/convert_traces/convert_traces.py. In the same folder you also find an example configuration for the script and an example data set for the first try.coord-sim/params/convert_traces$tree
.
├──abilene_node_name_map.yaml
├──convert_traces.py
├──directed-abilene-zhang-5min-over-6months-ALL
│├──demandMatrix-abilene-zhang-5min-20040302-1830.xml
│├──demandMatrix-abilene-zhang-5min-20040305-0150.xml
│├──demandMatrix-abilene-zhang-5min-20040411-0520.xml
│├──demandMatrix-abilene-zhang-5min-20040626-0345.xml
│├──demandMatrix-abilene-zhang-5min-20040630-2150.xml
│├──demandMatrix-abilene-zhang-5min-20040704-2020.xml
│├──demandMatrix-abilene-zhang-5min-20040808-0140.xml
│├──demandMatrix-abilene-zhang-5min-20040812-1415.xml
│├──demandMatrix-abilene-zhang-5min-20040819-2305.xml
│└──demandMatrix-abilene-zhang-5min-20040907-0905.xml
└──trace_xml_reader_config.yamlThe folderdirected-abilene-zhang-5min-over-6months-ALLcontains 10 xml files from sndlib each standing for traffic in one 5min timespan.
The configuration you find intrace_xml_reader_config.yaml. It contains:source:"directed-abilene-zhang-5min-over-6months-ALL"# result_trace_filename: <>  # default  = f'{directory}_{_from}-{to}_trace.csv'# intermediate_result_filename: <>  # default  = result_trace_filename + "_intermediate# _from: 0 # default 0# to: 100  # default None, means slice is [_from:]node_name_map:abilene_node_name_map.yaml# default None, means leave the namesrun_duration:100# default 100scale_factor:0.001# default 0.001change_rate:2# default 2#ingress_nodes:  # default None, means choose all nodes#  - pop0#  - pop1Parametersourcepoints to the folder with the xml files. Execute:coord-sim/params/convert_traces$python3convert_traces.py--config_filetrace_xml_reader_config.yaml[...]23:20:54:10filesindirectory23:20:54:Chosenfiles:os.listdir(directed-abilene-zhang-5min-over-6months-ALL)[0:][...]23:21:00:Writtentodirected-abilene-zhang-5min-over-6months-ALL_0-None_trace.csv.Lasttimestep1800[...]23:21:00:inter_arrival_meanrange:0.323815912931867,36.44721446514131523:21:00:...mean:7.38194781861677823:21:00:...median:5.64632736419829123:21:00:...std:5.661472126922231The converted trace is written todirected-abilene-zhang-5min-over-6months-ALL_0-None_trace.csv. Reading the files takes most of the time. That's why the script writes some intermediate data to another csv file (in this case it is nameddirected-abilene-zhang-5min-over-6months-ALL_0-None_intermediate.csv). You can reuse it with different parameters by setting thesourceparameter to the filename of the intermediate. For example we want to include not all ingress nodes:trace_xml_reader_config.yaml:source:directed-abilene-zhang-5min-over-6months-ALL_0-None_intermediate.csvresult_trace_filename:ing_pop0_pop1.csv[...]ingress_nodes:# default None, means choose all nodes-pop0-pop1We also give the resulting trace_file another filename to avoid overwriting:coord-sim/params/convert_traces$python3convert_traces.py--config_filetrace_xml_reader_config.yamlThe script will work on the data from the intermediate file. By default filenames are constructed from the directory the arguments_fromandto. You also can assign filenames to to the intermediate and the results file:trace_xml_reader_config.yaml:source:"directed-abilene-zhang-5min-over-6months-ALL"intermediate_result_filename:directed-abilene-zhang-5min-over-6months-ALL_0-None_intermediate.csvresult_trace_filename:ing_pop0_pop1.csv[...]Since a batch from sndlib contains so many files you can choose a sample of them with arguments_fromandto, which defines a slice. The script calls:os.listdir(source)[_from:to]if source is a directory. That way you can limit the number of files to read. Ifsourceis set to an intermediate file it will be also sliced according to those parameters.The node names in our network files differ from those in sndlib. To change them a yaml file is assigned. In the above config example parameternode_name_mapwas set toabilene_node_name_map.yaml, which looks like this:# defines how to rename nodes (from keys to values). If a node is set to null it will be removed from the# dataframe. If a node is not mentioned in the yaml it will be ignored, the name will be kept.ATLAM5:null# this node is removed and does not appear even in the intermediateATLAng:pop9# renamed from ATLAng to pop9CHINng:pop1DNVRng:pop6HSTNng:pop8IPLSng:pop10KSCYng:pop7LOSAng:pop5NYCMng:pop0SNVAng:pop4STTLng:pop3WASHng:pop2Save plots of thedata_rateor theinter_arrival_mean:coord-sim/params/convert_traces$python3convert_traces.py--config_filetrace_xml_reader_config.yaml--save_plotsdata_rateinter_arrival_mean
coord-sim/params/convert_traces$tree
.
├──abilene_node_name_map.yaml
├──convert_traces.py
├──directed-abilene-zhang-5min-over-6months-ALL
│├──demandMatrix-abilene-zhang-5min-20040302-1830.xml
│├──[...]│└──demandMatrix-abilene-zhang-5min-20040907-0905.xml
├──directed-abilene-zhang-5min-over-6months-ALL_0-None_intermediate.csv
├──directed-abilene-zhang-5min-over-6months-ALL_0-None_trace.csv
├──directed-abilene-zhang-5min-over-6months-ALL_0-None_trace_data_rate.png<---
├──directed-abilene-zhang-5min-over-6months-ALL_0-None_trace_inter_arrival_mean.png<---
├──directed-abilene-zhang-5min-over-6months-ALL_0-None_trace_meta.yaml
└──trace_xml_reader_config.yamlSave plots as pdf:coord-sim/params/convert_traces$python3convert_traces.py--config_filetrace_xml_reader_config.yaml--save_plotsdata_rateinter_arrival_mean--plot_formatpdfShow plots in the end of the script by calling plt.show():coord-sim/params/convert_traces$python3convert_traces.py--config_filetrace_xml_reader_config.yaml--plotdata_rateinter_arrival_meanFor more information look at the doctrings in the script or the comments in the example config.Overall abilene intermediate fileWe have an intermediate csv-fileoverall_abilene_intermediate.csv, which contains the whole abilene batch from sndlib with 48 thousand time step. It is recommended to use it for producing traces for the abilenme network by setting thesourceparameter in config to it.Create Episode AnimationsAnother way to analyse results is to create animation, which shows the placement in a single test episode changing over time. Use commandanimationfor that:Create animation from the first test directory from a results directory:animation --results_dir <>To show all available test directories in a results directory:animation --results_dir <> --show_testsCreate animation from test directory:animation --test_dir <>Show animation in the end (by calling plt.show()):animation --test_dir <> --showSave animation as html video:animation --test_dir <> --save <possible values: html, git, both>You can limit the amount of data to process by setting--sample_rate:animation --test_dir <> --sample_rate 5Default is 1
Thus for example every fifth point in time will be taken into the animation. Resolution will be worse, of course. But it is useful if the scenario is to big
Set interval between frames:animation --test_dir <> --interval 100Default is 100Create an animation not from cli, but as python code with the PlacementAnime class:pa=PlacementAnime(test_dir)pa.create_animation()pa.animation# animation objectpa.fig# figure objectpa.ax# Axis object (network, placement etc)pa.ingress_traffic_ax# Axis object (ingress_traffic)Maybe you will need the tkinter module installed for that:sudo apt install python3-tkLSTM Traffic PredictionThe simulator has an LSTM module to predict traffic based on the traffic traces mentioned above.The LSTM module must be trained separately, to do so,lstm_predictionmust be enabled in the simulator config file. Additionally,lstm_weightsmust be set to the directory where the desired location to save the weights within the current working directory. This will also be used during the running of the simulator to load the weights.To train the LSTM nerual network:Use thelstm-predictmodule similar to the example below. The module takes one argument — the simulator config file that will be used during the actual simulation.lstm-predict -c <PATH-TO-CONFIG-FILE>This will train the LSTM network based on the trace specified in thetrace_pathin the config file, then save the weights to the weights directory specified in the config file.Afterwards, use the same configuration file when using the simulator to make sure that weights are correctly loaded in the simulator later on.Tests# style checkflake8src# testsnose2AcknowledgementThis project has received funding from German Federal Ministry of Education and Research (BMBF) through Software Campus grant 01IS17046 (RealVNF).