├── .gitignore
├── DINC.py
├── LICENSE
├── P4
├── Node_0.p4
├── Node_1.p4
├── Node_2.p4
├── Node_3.p4
├── Node_4.p4
├── Node_5.p4
└── Node_6.p4
├── README.md
└── src
├── architecture
├── tna
│ └── p4_generator.py
└── v1model
│ └── p4_generator.py
├── code_generator
├── exact
│ └── unified_generation_controller.py
├── readme.txt
└── v1model
│ └── unified_generation_controller.py
├── configs
├── DINC_config.json
├── Network_Topology.json
└── requirements_Python3_10_8.txt
├── eval
├── BT-Topology
│ ├── BT-UK-Topology_withoutUK.py
│ └── load_BT.py
├── Baseline Comparison
│ ├── Duplication.py
│ ├── Hop.py
│ └── Node.py
├── Coefficent-Res
│ ├── BT-Coefficent-Res-Lat.py
│ └── Clos-Coefficent-Res-Lat.py
├── Configurations
│ ├── Table3_DINC_config_pegasus_sliced.json
│ ├── Table3_DINC_config_pint_sliced.json
│ ├── Table3_DT_DINC_config.json
│ ├── Table3_NB_DINC_config.json
│ ├── Table3_RF_DINC_config.json
│ ├── Table3_SVM_DINC_config.json
│ └── Table3_XGB_DINC_config.json
├── Hops-CDF
│ ├── Setups_BT-Hops.py
│ ├── Setups_Clos-Hops.py
│ └── Setups_label.py
├── Split Overhead
│ ├── Mem.py
│ ├── Stage.py
│ └── with_switchp4.py
├── Throughput-Latency
│ ├── Model_name-Latency.py
│ └── Model_name-Throughput.py
├── Time-Path_Segments
│ ├── Time-Edge_Clos.py
│ ├── Time-Segments_BT.py
│ ├── Time-Segments_Clos.py
│ └── Time-Tier1_BT.py
├── evaluation.md
└── figures
│ ├── BT-UK-topo-nouk_v2.png
│ ├── Coefficent-hops_BT.pdf
│ ├── Coefficent-hops_Clos.pdf
│ ├── DINC_Flightplan_Dup.pdf
│ ├── DINC_Flightplan_Hop.pdf
│ ├── DINC_Flightplan_Node.pdf
│ ├── Segment-Latency.pdf
│ ├── Segment-Throughput.pdf
│ ├── Setup-Hops_BT.pdf
│ ├── Setup-Hops_Clos.pdf
│ ├── Setups_label.pdf
│ ├── Split_mem.pdf
│ ├── Split_stage.pdf
│ ├── Split_stage_with_switch_p4.pdf
│ ├── Time-Edge_clos.pdf
│ ├── Time-Segment_Fat-Tree.pdf
│ ├── Time-Tier1_BT.pdf
│ ├── Time_Segments_BT.pdf
│ ├── Time_Segments_clos.pdf
│ ├── ml_scaling.pdf
│ └── rare_heatmap_v3.pdf
├── functions
├── add_license.py
├── cmd_related.py
├── config_modification.py
├── directory_management.py
├── figure_to_ASCII.py
├── input_CLI.py
├── json_encoder.py
└── write_file.py
├── help
├── DINC_Supports
│ ├── DINC_Supported_Architectures.md
│ ├── DINC_Supported_Topologies.md
│ └── DINC_Supported_Use_Cases.md
├── Sample_Tutorial
│ └── DINC_Tutorial.md
└── Zheng_et_al_2023_DINC_toward_distributed.pdf
├── images
├── BT-UK-topo.png
├── DINC_framework.png
├── logo.png
├── sample_marking.png
└── topos.png
├── logs
└── DT_performance_Iris_Fat-Tree_3depth_2branch.pdf
├── sample
├── PINT
│ └── pint_sliced.p4
├── Planter_Bayes
│ ├── Bayes_performance_UNSW_5_tuple.p4
│ └── Bayes_performance_UNSW_5_tuple_2.p4
├── Planter_DT
│ ├── DT_performance_Iris.p4
│ └── DT_performance_Iris_2.p4
├── Planter_RF
│ ├── RF_performance_UNSW_5_tuple copy.p4
│ ├── RF_performance_UNSW_5_tuple.p4
│ ├── RF_performance_UNSW_5_tuple_2.p4
│ ├── RF_performance_UNSW_5_tuple_3.p4
│ ├── RF_performance_UNSW_5_tuple_4.p4
│ ├── RF_performance_UNSW_5_tuple_5.p4
│ └── RF_performance_UNSW_5_tuple_6.p4
├── Planter_SVM
│ ├── SVM_performance_UNSW_5_tuple.p4
│ ├── SVM_performance_UNSW_5_tuple_2.p4
│ └── SVM_performance_UNSW_5_tuple_3.p4
├── Planter_XGB
│ ├── XGB_performance_UNSW_5_tuple.p4
│ ├── XGB_performance_UNSW_5_tuple_3.p4
│ └── XGB_performance_UNSW_5_tuple_4.p4
├── RF_hardware
│ └── RF_performance_UNSW_5_tuple.p4
└── pegasus_tofino
│ ├── pegasus_sliced.p4
│ ├── pred_load.p4
│ ├── qlen.p4
│ ├── rr.p4
│ └── server_load.p4
├── slicing
└── Manually
│ └── p4_slicing.py
├── solver
└── ILP
│ └── Type_1
│ └── do_optimization.py
├── temp
└── P4
│ ├── E0_control-apply.p4
│ ├── E0_control.p4
│ ├── E1_control-apply.p4
│ ├── E1_control.p4
│ ├── E2_control-apply.p4
│ └── E2_control.p4
├── test
└── BMv2
│ ├── run_test.py
│ ├── test_environment
│ ├── Makefile
│ ├── P4
│ │ ├── s0.p4
│ │ ├── s1.p4
│ │ ├── s10.p4
│ │ ├── s11.p4
│ │ ├── s12.p4
│ │ ├── s13.p4
│ │ ├── s14.p4
│ │ ├── s2.p4
│ │ ├── s3.p4
│ │ ├── s4.p4
│ │ ├── s5.p4
│ │ ├── s6.p4
│ │ ├── s7.p4
│ │ ├── s8.p4
│ │ └── s9.p4
│ ├── commands
│ │ ├── s0.txt
│ │ ├── s1.txt
│ │ ├── s10.txt
│ │ ├── s11.txt
│ │ ├── s12.txt
│ │ ├── s13.txt
│ │ ├── s14.txt
│ │ ├── s2.txt
│ │ ├── s3.txt
│ │ ├── s4.txt
│ │ ├── s5.txt
│ │ ├── s6.txt
│ │ ├── s7.txt
│ │ ├── s8.txt
│ │ └── s9.txt
│ ├── insert_rules.sh
│ ├── main.py
│ ├── run_demo.sh
│ └── temp
│ │ └── BMv2_network_config.json
│ └── utils
│ ├── Makefile
│ ├── architecture
│ ├── psa
│ │ └── Makefile
│ └── v1model
│ │ └── Makefile
│ ├── cheat_sheet_src
│ ├── main.tex
│ └── src
│ │ ├── actions.txt
│ │ ├── adv_parsing.txt
│ │ ├── architecture.txt
│ │ ├── control_flow.txt
│ │ ├── counters.txt
│ │ ├── data_types.txt
│ │ ├── deparsing.txt
│ │ ├── expressions.txt
│ │ ├── header_stack.txt
│ │ ├── parsers.txt
│ │ ├── tables.txt
│ │ └── v1model_std_metadata.txt
│ ├── mininet
│ ├── appcontroller.py
│ ├── apptopo.py
│ ├── multi_switch_mininet.py
│ ├── p4_mininet.py
│ ├── shortest_path.py
│ └── single_switch_mininet.py
│ ├── netstat.py
│ ├── p4_mininet.py
│ ├── p4_program.py
│ ├── p4app_util.py
│ ├── p4apprunner.py
│ ├── p4runtime_lib
│ ├── __init__.py
│ ├── bmv2.py
│ ├── convert-modified.py
│ ├── convert.py
│ ├── error_utils.py
│ ├── helper.py
│ ├── simple_controller.py
│ └── switch.py
│ ├── p4runtime_switch.py
│ └── run_exercise.py
├── topologies
├── BT-ASP
│ └── network_topology.py
├── BT-All
│ └── network_topology.py
├── BT
│ └── network_topology.py
├── Fat-Tree
│ └── network_topology.py
├── Folded-Clos-ASP
│ └── network_topology.py
├── Folded-Clos-All
│ └── network_topology.py
└── Folded-Clos
│ └── network_topology.py
└── use_cases
├── standard_block
└── common_p4.py
└── standard_classification
└── common_p4.py
/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | # Byte-compiled / optimized / DLL files
3 | __pycache__/
4 | *.py[cod]
5 | *$py.class
6 | # C extensions
7 | *.so
8 | # Distribution / packaging
9 | .Python
10 | build/
11 | develop-eggs/
12 | dist/
13 | downloads/
14 | eggs/
15 | .eggs/
16 | lib/
17 | lib64/
18 | parts/
19 | sdist/
20 | var/
21 | wheels/
22 | share/python-wheels/
23 | *.egg-info/
24 | .installed.cfg
25 | *.egg
26 | MANIFEST
27 | # PyInstaller
28 | # Usually these files are written by a python script from a template
29 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
30 | *.manifest
31 | *.spec
32 | # Installer logs
33 | pip-log.txt
34 | pip-delete-this-directory.txt
35 | # Unit test / coverage reports
36 | htmlcov/
37 | .tox/
38 | .nox/
39 | .coverage
40 | .coverage.*
41 | .cache
42 | nosetests.xml
43 | coverage.xml
44 | *.cover
45 | *.py,cover
46 | .hypothesis/
47 | .pytest_cache/
48 | cover/
49 | # Translations
50 | *.mo
51 | *.pot
52 | # Django stuff:
53 | *.log
54 | local_settings.py
55 | db.sqlite3
56 | db.sqlite3-journal
57 | # Flask stuff:
58 | instance/
59 | .webassets-cache
60 | # Scrapy stuff:
61 | .scrapy
62 | # Sphinx documentation
63 | docs/_build/
64 | # PyBuilder
65 | .pybuilder/
66 | target/
67 | # Jupyter Notebook
68 | .ipynb_checkpoints
69 | # IPython
70 | profile_default/
71 | ipython_config.py
72 | # pyenv
73 | # For a library or package, you might want to ignore these files since the code is
74 | # intended to run in multiple environments; otherwise, check them in:
75 | # .python-version
76 | # pipenv
77 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
78 | # However, in case of collaboration, if having platform-specific dependencies or dependencies
79 | # having no cross-platform support, pipenv may install dependencies that don't work, or not
80 | # install all needed dependencies.
81 | #Pipfile.lock
82 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow
83 | __pypackages__/
84 | # Celery stuff
85 | celerybeat-schedule
86 | celerybeat.pid
87 | # SageMath parsed files
88 | *.sage.py
89 | # Environments
90 | .env
91 | .venv
92 | env/
93 | venv/
94 | ENV/
95 | env.bak/
96 | venv.bak/
97 | # Spyder project settings
98 | .spyderproject
99 | .spyproject
100 | # Rope project settings
101 | .ropeproject
102 | # mkdocs documentation
103 | /site
104 | # mypy
105 | .mypy_cache/
106 | .dmypy.json
107 | dmypy.json
108 | # Pyre type checker
109 | .pyre/
110 | # pytype static type analyzer
111 | .pytype/
112 | # Cython debug symbols
113 | cython_debug/
114 | # OSX
115 | .DS_Store
116 | .idea/
117 | .ide
118 |
119 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Distributed In-Network Computing (DINC)
2 | 
3 | [](https://opensource.org/licenses/Apache-2.0)
4 | 
5 |
6 | ## Introducing DINC
7 | DINC is a framework to provide automating distributed in-network computing services. This repo is the artifact for the paper "DINC: Toward Distributed In-Network Computing" [PDF](./src/help/Zheng_et_al_2023_DINC_toward_distributed.pdf) in ACM CoNEXT '23.
8 |
9 | ## Setting up the DINC environment
10 |
11 | DINC requires python 3.10 or above, with the packages listed in [requirements\_Python3\_10\_8.txt](./src/configs/requirements_Python3_10_8.txt). To install the aforementioned packages, start your working environment and execute the following command:
12 |
13 | ```
14 | pip3 install -r ./src/configs/requirements_Python3_10_8.txt
15 | ```
16 |
17 | ## Getting started with DINC
18 |
19 | First, prepare a working environment as described in the previous section [Link](#environment).
20 |
21 | Run the following command to start DINC in manual configuration mode ```-m``` with target in-network computing program directory after ```-d```. Use help model with ```-h``` command to see additional options.
22 |
23 | ```
24 | python3 DINC.py -m -d
25 | ```
26 |
27 | 💡 A detailed getting started tutorial [Link: "Please click me!"](./src/help/Sample_Tutorial/DINC_Tutorial.md) (**Strongly Recommended**).
28 |
29 | ## DINC Supports
30 | DINC supports a wide range of modules mainly including modular Topologies, Architectures, and Usecases:
31 |
32 | - DINC Supported Topologies [wiki](./src/help/DINC_Supports/DINC_Supported_Topologies.md)
33 | - DINC Supported Architectures [wiki](./src/help/DINC_Supports/DINC_Supported_Architectures.md)
34 | - DINC Supported Usecases [wiki](./src/help/DINC_Supports/DINC_Supported_Use_Cases.md)
35 |
36 | DINC also supports modular [Slicer](./src/slicing)s, [Solver](./src/solver)s, [Code Generator](./src/code_generator)s, [Test Controller](./src/test)s, etc.
37 |
38 |
39 | ## How to manually mark P4 grogram for DINC
40 | The following figure gives a general outlook of how P4 programs are sliced in the current P4 slicer module ([Manually](./src/slicing/Manually)).
41 |
42 |
43 |
44 |
45 |
46 | ## The DINC Framework
47 | 
48 |
49 | ## DINC's Availability
50 |
51 | If you're interested in this work and find anything unclear, please feel free to contact me at ```changgang.zheng@eng.ox.ac.uk```. **_We are welcoming collaborations._** It can be exciting to collaborate, if you think in-network machine learning is helpful to your research or use case. If there are any potential interests, please feel free to contact PI ```noa.zilberman@eng.ox.ac.uk``` and project lead ```changgang.zheng@eng.ox.ac.uk```.
52 |
53 | ## License
54 |
55 | The files are licensed under Apache License: [LICENSE](./LICENSE). The text of the license can also be found in the LICENSE file.
56 |
57 | ## Citation
58 | ```
59 | @article{zheng2023dinc,
60 | title={DINC: Toward Distributed In-Network Computing},
61 | author={Zheng, Changgang and Tang, Haoyue and Zang, Mingyuan and Hong, Xinpeng and Feng, Aosong and Tassiulas, Leandros and Zilberman, Noa},
62 | journal={Proceedings of the ACM on Networking},
63 | volume={1},
64 | number={CoNEXT3},
65 | pages={1--25},
66 | year={2023},
67 | publisher={ACM New York, NY, USA}
68 | }
69 | ```
70 |
71 | We are also excited to introduce several DINC related papers ([Planter](https://arxiv.org/pdf/2205.08824.pdf), [Planter poster](https://dl.acm.org/doi/10.1145/3472716.3472846), [IIsy](https://arxiv.org/pdf/2205.08243.pdf), [Linnet](https://changgang-zheng.github.io/Home-Page/papers/Linnet%20Limit%20Order%20Books%20Within%20Switches.pdf), and [P4Pir](https://changgang-zheng.github.io/Home-Page/papers/P4Pir%20In-Network%20Analysis%20for%20Smart%20IoT%20Gateways.pdf)):
72 |
73 | ```
74 | @article{zheng2022automating,
75 | title={Automating In-Network Machine Learning},
76 | author={Zheng, Changgang and Zang, Mingyuan and Hong, Xinpeng and Bensoussane, Riyad and Vargaftik, Shay and Ben-Itzhak, Yaniv and Zilberman, Noa},
77 | journal={arXiv preprint arXiv:2205.08824},
78 | year={2022}
79 | }
80 |
81 | @incollection{zheng2021planter,
82 | title={Planter: seeding trees within switches},
83 | author={Zheng, Changgang and Zilberman, Noa},
84 | booktitle={Proceedings of the SIGCOMM'21 Poster and Demo Sessions},
85 | pages={12--14},
86 | year={2021}
87 | }
88 |
89 | @article{zheng2022iisy,
90 | title={IIsy: Practical In-Network Classification},
91 | author={Zheng, Changgang and Xiong, Zhaoqi and Bui, Thanh T and Kaupmees, Siim and Bensoussane, Riyad and Bernabeu, Antoine and Vargaftik, Shay and Ben-Itzhak, Yaniv and Zilberman, Noa},
92 | journal={arXiv preprint arXiv:2205.08243},
93 | year={2022}
94 | }
95 |
96 | @incollection{hong2022linnet,
97 | title={Linnet: Limit Order Books Within Switches},
98 | author={Hong, Xinpeng and Zheng, Changgang and Zohren, Stefan and Zilberman, Noa},
99 | booktitle={Proceedings of the SIGCOMM'22 Poster and Demo Sessions},
100 | year={2022}
101 | }
102 |
103 | @incollection{zang2022p4pir,
104 | title={P4Pir: In-Network Analysis for Smart IoT Gateways},
105 | author={Zang, Mingyuan and Zheng, Changgang and Stoyanov, Radostin and Dittmann, Lars and Zilberman, Noa},
106 | booktitle={Proceedings of the SIGCOMM'22 Poster and Demo Sessions},
107 | year={2022}
108 | }
109 | ```
110 |
111 | Planter builds upon [IIsy](https://github.com/cucl-srg/IIsy) and is further inspired by [SwitchTree](https://github.com/ksingh25/SwitchTree), [Qin](https://github.com/vxxx03/IFIPNetworking20), and [Clustreams](https://dl.acm.org/doi/pdf/10.1145/3482898.3483356).
112 |
113 |
114 | ## Acknowledgments
115 | This paper complies with all applicable ethical standards of the authors’ home institution. This
116 | work was partly funded by VMware, EU Horizon SMARTEDGE (101092908, UKRI 10056403), ARO
117 | W911NF-23-1-0088 and W911NF-23-1-0064. We acknowledge support from Intel. For the purpose
118 | of Open Access, the author has applied a CC-BY public copyright license to any Author Accepted
119 | Manuscript (AAM) version arising from this submission.
--------------------------------------------------------------------------------
/src/code_generator/readme.txt:
--------------------------------------------------------------------------------
1 | This part decides how we do metadata supplement.
--------------------------------------------------------------------------------
/src/configs/DINC_config.json:
--------------------------------------------------------------------------------
1 | {
2 | "directory config": {
3 | "work": "/home/jesu3779/Documents/GitHub/DINC",
4 | "log plot file name": "Fat-Tree_3depth_2branch.pdf",
5 | "p4 file": "./src/sample/Planter_DT/DT_performance_Iris.p4",
6 | "BMv2": "/home/jesu3779/mysde/behavioral-model-1.15.0"
7 | },
8 | "network config": {
9 | "topology": "Fat-Tree",
10 | "n_depth": 3,
11 | "n_branch": 2,
12 | "input device list": [
13 | 2,
14 | 3,
15 | 5,
16 | 6
17 | ],
18 | "output device list": [
19 | 0
20 | ],
21 | "resources list": [
22 | "stage",
23 | "memory"
24 | ],
25 | "stage": [
26 | 5,
27 | 5,
28 | 5,
29 | 5,
30 | 5,
31 | 5,
32 | 5
33 | ],
34 | "memory": [
35 | 5,
36 | 5,
37 | 5,
38 | 5,
39 | 5,
40 | 5,
41 | 5
42 | ],
43 | "architectures": [
44 | "v1model",
45 | "v1model",
46 | "v1model",
47 | "v1model",
48 | "v1model",
49 | "v1model",
50 | "v1model"
51 | ],
52 | "use cases": [
53 | "standard_block",
54 | "standard_block",
55 | "standard_block",
56 | "standard_block",
57 | "standard_block",
58 | "standard_block",
59 | "standard_block"
60 | ],
61 | "targets": [
62 | "bmv2",
63 | "bmv2",
64 | "bmv2",
65 | "bmv2",
66 | "bmv2",
67 | "bmv2",
68 | "bmv2"
69 | ]
70 | },
71 | "operation config": {
72 | "display plot": false,
73 | "test ILP": false
74 | },
75 | "p4 config": {
76 | "slicing method": "Manually",
77 | "start marker": "@!",
78 | "end marker": "!@",
79 | "key element info": [
80 | "slice",
81 | "position"
82 | ],
83 | "existed sliced p4 file": [
84 | "/home/jesu3779/Documents/GitHub/DINC/src/temp/P4/E0_control.p4",
85 | "/home/jesu3779/Documents/GitHub/DINC/src/temp/P4/E1_control.p4",
86 | "/home/jesu3779/Documents/GitHub/DINC/src/temp/P4/E2_control.p4",
87 | "/home/jesu3779/Documents/GitHub/DINC/src/temp/P4/E0_control-apply.p4",
88 | "/home/jesu3779/Documents/GitHub/DINC/src/temp/P4/E1_control-apply.p4",
89 | "/home/jesu3779/Documents/GitHub/DINC/src/temp/P4/E2_control-apply.p4"
90 | ],
91 | "stage": [
92 | 5,
93 | 5,
94 | 5
95 | ],
96 | "memory": [
97 | 5,
98 | 5,
99 | 5
100 | ],
101 | "generator": "exact",
102 | "begin test": "T"
103 | },
104 | "solver config": {
105 | "solver type": "ILP",
106 | "solver variation": "Type_1"
107 | },
108 | "test config": {
109 | "if test": "Y",
110 | "targets": "BMv2"
111 | }
112 | }
--------------------------------------------------------------------------------
/src/configs/Network_Topology.json:
--------------------------------------------------------------------------------
1 | {
2 | "device_list": {
3 | "0": [
4 | 0,
5 | 0
6 | ],
7 | "1": [
8 | 1,
9 | 0
10 | ],
11 | "2": [
12 | 2,
13 | 0
14 | ],
15 | "3": [
16 | 2,
17 | 1
18 | ],
19 | "4": [
20 | 1,
21 | 1
22 | ],
23 | "5": [
24 | 2,
25 | 2
26 | ],
27 | "6": [
28 | 2,
29 | 3
30 | ]
31 | },
32 | "adjacent_matrix": [
33 | [
34 | 0.0,
35 | 1.0,
36 | 0.0,
37 | 0.0,
38 | 1.0,
39 | 0.0,
40 | 0.0
41 | ],
42 | [
43 | 1.0,
44 | 0.0,
45 | 1.0,
46 | 1.0,
47 | 0.0,
48 | 0.0,
49 | 0.0
50 | ],
51 | [
52 | 0.0,
53 | 1.0,
54 | 0.0,
55 | 0.0,
56 | 0.0,
57 | 0.0,
58 | 0.0
59 | ],
60 | [
61 | 0.0,
62 | 1.0,
63 | 0.0,
64 | 0.0,
65 | 0.0,
66 | 0.0,
67 | 0.0
68 | ],
69 | [
70 | 1.0,
71 | 0.0,
72 | 0.0,
73 | 0.0,
74 | 0.0,
75 | 1.0,
76 | 1.0
77 | ],
78 | [
79 | 0.0,
80 | 0.0,
81 | 0.0,
82 | 0.0,
83 | 1.0,
84 | 0.0,
85 | 0.0
86 | ],
87 | [
88 | 0.0,
89 | 0.0,
90 | 0.0,
91 | 0.0,
92 | 1.0,
93 | 0.0,
94 | 0.0
95 | ]
96 | ],
97 | "input device list": [
98 | 2,
99 | 3,
100 | 5,
101 | 6
102 | ],
103 | "output device list": [
104 | 0
105 | ],
106 | "resources list": [
107 | "stage",
108 | "memory"
109 | ],
110 | "stage": [
111 | 5,
112 | 5,
113 | 5,
114 | 5,
115 | 5,
116 | 5,
117 | 5
118 | ],
119 | "memory": [
120 | 5,
121 | 5,
122 | 5,
123 | 5,
124 | 5,
125 | 5,
126 | 5
127 | ],
128 | "Path": {
129 | "0": [
130 | 2,
131 | 1,
132 | 0
133 | ],
134 | "1": [
135 | 3,
136 | 1,
137 | 0
138 | ],
139 | "2": [
140 | 5,
141 | 4,
142 | 0
143 | ],
144 | "3": [
145 | 6,
146 | 4,
147 | 0
148 | ]
149 | }
150 | }
--------------------------------------------------------------------------------
/src/configs/requirements_Python3_10_8.txt:
--------------------------------------------------------------------------------
1 | networkx==2.8.8
2 | numpy==1.23.5
3 | matplotlib==3.6.2
4 | pandas==1.5.2
5 | scipy==1.9.3
6 |
--------------------------------------------------------------------------------
/src/eval/BT-Topology/BT-UK-Topology_withoutUK.py:
--------------------------------------------------------------------------------
1 | import matplotlib.pyplot as plt
2 | import cartopy.crs as ccrs
3 | import cartopy.io.img_tiles as cimgt
4 | import cartopy.feature as cfeature
5 | from matplotlib.offsetbox import AnchoredText
6 | from load_BT import *
7 | from convertbng.util import convert_bng, convert_lonlat
8 | import time
9 |
10 | rotated_pole = ccrs.RotatedPole(pole_latitude=45, pole_longitude=180)
11 |
12 | fig = plt.figure()
13 | ax = fig.add_subplot(1, 1, 1, projection=rotated_pole)
14 | ax.set_extent([-10.2, 2, 49.5, 59.5], crs=ccrs.PlateCarree())
15 | # ax.add_feature(cfeature.LAND)
16 | # ax.add_feature(cfeature.OCEAN)
17 | # ax.add_feature(cfeature.COASTLINE)
18 | # ax.add_feature(cfeature.BORDERS, linestyle=':')
19 | # ax.add_feature(cfeature.LAKES, alpha=0.5)
20 | # ax.add_feature(cfeature.RIVERS)
21 | # stamen_terrain = cimgt.Stamen('terrain-background')
22 | # ax.add_image(stamen_terrain, 6)
23 | # stamen_terrain = cimgt.Stamen('toner-hybrid')
24 | # ax.add_image(stamen_terrain, 6)
25 | # stamen_terrain = cimgt.Stamen('toner-lite')
26 | # ax.add_image(stamen_terrain, 6)
27 | # stamen_terrain = cimgt.Stamen('toner-lines')
28 | # ax.add_image(stamen_terrain, 6)
29 | # stamen_terrain = cimgt.Stamen('toner-labels')
30 | # ax.add_image(stamen_terrain, 6)
31 | # ax.gridlines(draw_labels=False, dms=True, x_inline=False, y_inline=False)
32 | # Put a background image on for nice sea rendering.
33 | # ax.stock_img()
34 |
35 |
36 |
37 | D, adjacent_matrix, Level_dict = load_data(Reload=True)
38 | num_d = len(D.keys())
39 | x_lon_list = []
40 | x_lat_list = []
41 |
42 | x_oc_lon_list = []
43 | x_oc_lat_list = []
44 |
45 | x_ic_lon_list = []
46 | x_ic_lat_list = []
47 |
48 | x_metro_lon_list = []
49 | x_metro_lat_list = []
50 |
51 | x_tier1_lon_list = []
52 | x_tier1_lat_list = []
53 |
54 | for x in range(num_d):
55 | print('\rProcessing BT raw data [' + str(int(100 * np.round(x / len(D), 2))) + '%], plotting connections...',
56 | end='')
57 | for y in range(x):
58 | if x == y or adjacent_matrix[x][y] != 1:
59 | continue
60 | # print(adjacent_matrix[x][y])
61 | eastings = [D[str(x)]['E'],D[str(y)]['E']]
62 | northings = [D[str(x)]['N'],D[str(y)]['N']]
63 | res_list_en = convert_lonlat(eastings, northings)
64 | x_lon = res_list_en[0][0]
65 | x_lat = res_list_en[1][0]
66 | y_lon = res_list_en[0][1]
67 | y_lat = res_list_en[1][1]
68 | plt.plot([y_lon, x_lon], [y_lat, x_lat], color='gray', linewidth=0.08, transform=ccrs.PlateCarree(), alpha=0.8,
69 | zorder=2)
70 |
71 |
72 | eastings = [D[str(x)]['E']]
73 | northings = [D[str(x)]['N']]
74 | res_list_en = convert_lonlat(eastings, northings)
75 | x_lon = res_list_en[0][0]
76 | x_lat = res_list_en[1][0]
77 | x_lon_list += [res_list_en[0][0]]
78 | x_lat_list += [res_list_en[1][0]]
79 | if x in Level_dict['tier_1']:
80 | x_tier1_lon_list += [res_list_en[0][0]]
81 | x_tier1_lat_list += [res_list_en[1][0]]
82 | elif x in Level_dict['inner core']:
83 | x_ic_lon_list += [res_list_en[0][0]]
84 | x_ic_lat_list += [res_list_en[1][0]]
85 | elif x in Level_dict['metro']:
86 | x_metro_lon_list += [res_list_en[0][0]]
87 | x_metro_lat_list += [res_list_en[1][0]]
88 | elif x in Level_dict['outer core']:
89 | x_oc_lon_list += [res_list_en[0][0]]
90 | x_oc_lat_list += [res_list_en[1][0]]
91 | else:
92 | print('error')
93 |
94 | # time.sleep(0.00001)
95 |
96 |
97 | # plt.plot([y_lon,x_lon], [y_lat, x_lat], color='gray',linewidth =0.08, marker='.', markerfacecolor='lightskyblue', ms=3, markeredgecolor='black', markeredgewidth=0.2, transform=ccrs.PlateCarree(),alpha=0.8 )
98 | # plt.scatter(x_lon_list, x_lat_list, color='palevioletred', marker='.', s = 6, linewidths=0.1, edgecolors='black', transform=ccrs.PlateCarree(), zorder=2 )
99 | plt.scatter(x_tier1_lon_list, x_tier1_lat_list, color='palevioletred', marker='.', s = 6, linewidths=0.1, edgecolors='black', transform=ccrs.PlateCarree(), zorder=2, label='Tier 1')
100 | plt.scatter(x_metro_lon_list, x_metro_lat_list, color='lightskyblue', marker='.', s = 6, linewidths=0.1, edgecolors='black', transform=ccrs.PlateCarree(), zorder=3, label='Metro' )
101 | plt.scatter(x_oc_lon_list, x_oc_lat_list, color='lightskyblue', marker='.', s = 6, linewidths=0.1, edgecolors='black', transform=ccrs.PlateCarree(), zorder=4 , label='Outer Core')
102 | plt.scatter(x_ic_lon_list, x_ic_lat_list, color='mediumseagreen', marker='.', s = 6, linewidths=0.1, edgecolors='black', transform=ccrs.PlateCarree(), zorder=5 , label='Inner Core')
103 |
104 |
105 | # Create a feature for States/Admin 1 regions at 1:50m from Natural Earth
106 | # states_provinces = cfeature.NaturalEarthFeature(
107 | # category='cultural',
108 | # name='admin_1_states_provinces_lines',
109 | # scale='50m',
110 | # facecolor='none')
111 |
112 | SOURCE = 'Natural Earth'
113 | LICENSE = 'public domain'
114 |
115 | states = cfeature.NaturalEarthFeature('cultural', 'admin_1_states_provinces', '10m', edgecolor='gray',facecolor='none')
116 | ax.add_feature(states, linewidth = 0.1, linestyle='-')
117 | ax.add_feature(cfeature.LAND)
118 | # ax.add_feature(cfeature.COASTLINE)
119 | # ax.add_feature(states_provinces, edgecolor='gray')
120 |
121 | # Add a text annotation for the license information to the
122 | # the bottom right corner.
123 | text = AnchoredText('\u00A9 {}; license: {}'
124 | ''.format(SOURCE, LICENSE),
125 | loc=4, prop={'size': 5}, frameon=True)
126 | ax.add_artist(text)
127 | plt.legend(loc = "upper right", ncol=1, fontsize=5)
128 | print(' Done')
129 | plt.savefig('../figures/BT-UK-topo-nouk.png',dpi=600,format='png', bbox_inches='tight')
130 | # plt.savefig('../figures/BT-UK-topo.pdf',dpi=600,format='pdf', bbox_inches='tight')
131 |
132 | plt.show()
133 |
134 |
--------------------------------------------------------------------------------
/src/eval/Baseline Comparison/Duplication.py:
--------------------------------------------------------------------------------
1 | import matplotlib.pyplot as plt
2 | import warnings
3 | # warnings.filterwarnings('ignore')
4 | import matplotlib
5 | import numpy as np
6 | import json
7 | from math import sqrt
8 |
9 |
10 |
11 | x = [2,3]
12 | DINC = [33, 405]
13 | flightplan = [ 51, 1901]
14 |
15 | fig, ax = plt.subplots(figsize=(3, 3))
16 | # plt.rcParams['font.sans-serif'] = 'Times New Roman'
17 | matplotlib.rcParams['pdf.fonttype'] = 42
18 | matplotlib.rcParams['ps.fonttype'] = 42
19 | width = 0.3
20 |
21 | x_n = [i-0.65*width for i in x]
22 | plt.bar(x_n, flightplan,width=width, label='Flightplan', color="pink" ,linewidth = 1,edgecolor = 'black')
23 |
24 | x_n = [i+0.65*width for i in x]
25 | plt.bar(x_n, DINC, width= width, label='DINC', color="lightskyblue",linewidth = 1,edgecolor = 'black')
26 |
27 | fsize =25
28 | plt.ylabel('Duplications', fontsize=fsize)
29 | plt.yscale('log')
30 | plt.yticks([1,10,100,1000] ,fontsize=fsize-1)
31 | plt.xticks(x, labels=['Clos', 'BT'], fontsize=fsize-1)
32 | # plt.ylim(0.2,5000)
33 | plt.ylim(0.1,10000)
34 | plt.xlim(1.4,3.6)
35 | leg = plt.legend(loc='lower center', fontsize=fsize-8)
36 | plt.grid(which ='major',linestyle= ':', axis="y") #'major', 'minor', 'both'
37 | plt.savefig('../figures/DINC_Flightplan_Dup.pdf',dpi=600,format='pdf', bbox_inches='tight')
38 |
39 |
--------------------------------------------------------------------------------
/src/eval/Baseline Comparison/Hop.py:
--------------------------------------------------------------------------------
1 | import matplotlib.pyplot as plt
2 | import warnings
3 | # warnings.filterwarnings('ignore')
4 | import matplotlib
5 | import numpy as np
6 | import json
7 | from math import sqrt
8 |
9 |
10 |
11 | x = [2,3]
12 | DINC = [100*2/3, 100*3.11/3.81]
13 | flightplan = [100*2/3 , 100*3.11/3.81]
14 | fig, ax = plt.subplots(figsize=(3, 3))
15 | # plt.rcParams['font.sans-serif'] = 'Times New Roman'
16 | matplotlib.rcParams['pdf.fonttype'] = 42
17 | matplotlib.rcParams['ps.fonttype'] = 42
18 | width = 0.3
19 |
20 | x_n = [i-0.65*width for i in x]
21 | plt.bar(x_n, flightplan,width=width, label='Flightplan', color="pink" ,linewidth = 1,edgecolor = 'black')
22 |
23 | x_n = [i+0.65*width for i in x]
24 | plt.bar(x_n, DINC, width= width, label='DINC', color="lightskyblue",linewidth = 1,edgecolor = 'black')
25 |
26 | fsize =25
27 | # plt.ylabel('Nodes', fontsize=fsize)
28 | plt.ylabel('Hops (%)', fontsize=fsize)
29 | # plt.yscale('log')
30 | # plt.yticks([0.2,0.4,0.6,0.8] ,fontsize=fsize-1)
31 | plt.yticks([20,40,60,80] ,fontsize=fsize-1)
32 | plt.xticks(x, labels=['Clos', 'BT'], fontsize=fsize-1)
33 | # plt.ylim(0,1)
34 | plt.ylim(0,100)
35 | plt.xlim(1.4,3.6)
36 | leg = plt.legend(loc='lower center', fontsize=fsize-8)
37 | plt.grid(which ='major',linestyle= ':', axis="y") #'major', 'minor', 'both'
38 | plt.savefig('../figures/DINC_Flightplan_Hop.pdf',dpi=600,format='pdf', bbox_inches='tight')
39 |
40 |
--------------------------------------------------------------------------------
/src/eval/Baseline Comparison/Node.py:
--------------------------------------------------------------------------------
1 | import matplotlib.pyplot as plt
2 | import warnings
3 | # warnings.filterwarnings('ignore')
4 | import matplotlib
5 | import numpy as np
6 | import json
7 | from math import sqrt
8 |
9 |
10 |
11 | x = [2,3]
12 | # DINC = [30/33, 400/1008]
13 | # flightplan = [30/33 , 971/1008]
14 | DINC = [100*30/33, 100*400/1008]
15 | flightplan = [100*30/33 , 100*971/1008]
16 | fig, ax = plt.subplots(figsize=(3, 3))
17 | # plt.rcParams['font.sans-serif'] = 'Times New Roman'
18 | matplotlib.rcParams['pdf.fonttype'] = 42
19 | matplotlib.rcParams['ps.fonttype'] = 42
20 | width = 0.3
21 |
22 | x_n = [i-0.65*width for i in x]
23 | plt.bar(x_n, flightplan,width=width, label='Flightplan', color="pink" ,linewidth = 1,edgecolor = 'black')
24 |
25 | x_n = [i+0.65*width for i in x]
26 | plt.bar(x_n, DINC, width= width, label='DINC', color="lightskyblue",linewidth = 1,edgecolor = 'black')
27 |
28 | fsize =25
29 | # plt.ylabel('Nodes', fontsize=fsize)
30 | plt.ylabel('Nodes (%)', fontsize=fsize)
31 | # plt.yscale('log')
32 | # plt.yticks([0.2,0.4,0.6,0.8] ,fontsize=fsize-1)
33 | plt.yticks([20,40,60,80] ,fontsize=fsize-1)
34 | plt.xticks(x, labels=['Clos', 'BT'], fontsize=fsize-1)
35 | # plt.ylim(0,1)
36 | plt.ylim(0,100)
37 | plt.xlim(1.4,3.6)
38 | leg = plt.legend(loc='lower center', fontsize=fsize-8)
39 | plt.grid(which ='major',linestyle= ':', axis="y") #'major', 'minor', 'both'
40 | plt.savefig('../figures/DINC_Flightplan_Node.pdf',dpi=600,format='pdf', bbox_inches='tight')
41 |
42 |
--------------------------------------------------------------------------------
/src/eval/Coefficent-Res/BT-Coefficent-Res-Lat.py:
--------------------------------------------------------------------------------
1 | import matplotlib.pyplot as plt
2 | import warnings
3 | import matplotlib
4 | import numpy as np
5 | import json
6 | from math import sqrt
7 |
8 | fsize =25
9 | lw=2
10 | ms = 6
11 | mes = 1
12 | lw=2
13 |
14 |
15 |
16 |
17 | # model = ['-2', '-1', '0', '1', '2']
18 | # x = [-2, -1, 0, 1, 2]
19 | # hops = [2, 3.11, 3.11, 3.11, 3.11]
20 | # var = [0, 0.575, 0.575, 0.575, 0.575 ]
21 | # segment = [1169,416,416,416,416]
22 | model = ['1', '2', '3', '4', '5']
23 | x = [1, 2, 3, 4, 5]
24 | hops = [3.11, 2, 2, 2, 2]
25 | var = [0.575, 0, 0, 0, 0]
26 | segment = [416, 1169,1169,1169,1169]
27 |
28 |
29 |
30 |
31 | fig, ax1 = plt.subplots(figsize=(5, 3))
32 | ax2 = ax1.twinx()
33 | matplotlib.rcParams['pdf.fonttype'] = 42
34 | matplotlib.rcParams['ps.fonttype'] = 42
35 | # plt.rcParams['font.sans-serif'] = 'Times New Roman'
36 | # plt.rcParams['mathtext.fontset']= 'custom'
37 | width = 0.26
38 | # cm stic stixsans custom
39 | x_n = [i-0*width for i in x]
40 | ax1.bar(x_n,hops ,width=width, label='Hops', color="lightskyblue" ,linewidth = 1,edgecolor = 'black' ,yerr=var, error_kw=dict(lw=1, capsize=2.5, capthick=1))
41 |
42 |
43 |
44 | l1 = ax2.plot(x, segment, '--', label='Segments', marker = 's', ms=ms, markeredgecolor='black', markeredgewidth=mes, color="#ff7f0e",linewidth = lw)
45 |
46 |
47 |
48 |
49 | fsize+=2
50 | plt.xlabel('Model', fontsize=fsize+1)
51 | ax1.set_xticks(x)
52 | ax1.set_xticklabels(labels=model,rotation=-0, fontsize=fsize+1)
53 | ax1.set_xlabel('Relative Weight', fontsize=fsize+1)
54 |
55 | # ax1.set_yscale('log')
56 | ax1.set_ylabel('Hops (s)', fontsize=fsize+1)
57 | ax1.set_yticks([1,2,3,4])
58 | ax1.set_yticklabels(labels=['1','2','3','4'], fontsize=fsize+1)
59 | ax1.set_ylim(0,5)
60 |
61 |
62 | ax2.set_ylabel('Segments', fontsize=fsize+1)
63 | ax2.set_yticks([450,700,950,1200])
64 | ax2.set_yticklabels(labels=['450','700','950', '1.2k'], fontsize=fsize+1)
65 | ax2.set_ylim(200,1450)
66 |
67 |
68 | plt.xlim(0.3, 5.7)
69 |
70 |
71 | lines, labels = ax1.get_legend_handles_labels()
72 | lines2, labels2 = ax2.get_legend_handles_labels()
73 | f_line = lines + lines2
74 | # f_line[1] = lines[0]
75 | # f_line[0] = lines2[0]
76 | # f_line[3] = lines[1]
77 | # f_line[2] = lines2[1]
78 | f_lable = labels + labels2
79 | # f_lable[1] = labels[0]
80 | # f_lable[0] = labels2[0]
81 | # f_lable[3] = labels[1]
82 | # f_lable[2] = labels2[1]
83 | ax2.legend(f_line, f_lable, fancybox=True, fontsize=fsize-8,loc = "upper right", ncol=1)
84 |
85 | plt.grid(which ='major',linestyle= ':') #'major', 'minor' , 'both'
86 | plt.savefig('../figures/Coefficent-hops_BT.pdf',dpi=600,format='pdf', bbox_inches='tight')
87 | # plt.show()
88 |
--------------------------------------------------------------------------------
/src/eval/Coefficent-Res/Clos-Coefficent-Res-Lat.py:
--------------------------------------------------------------------------------
1 | import matplotlib.pyplot as plt
2 | import warnings
3 | import matplotlib
4 | import numpy as np
5 | import json
6 | from math import sqrt
7 |
8 | fsize =25
9 | lw=2
10 | ms = 6
11 | mes = 1
12 | lw=2
13 |
14 |
15 |
16 |
17 | # model = ['-2', '-1', '0', '1', '2']
18 | # x = [-2, -1, 0, 1, 2]
19 | # hops = [2, 3, 2, 2, 2]
20 | # var = [0, 0, 0, 0, 0 ]
21 | # segment = [45,15,42,42,42]
22 | model = ['1', '2', '3', '4', '5']
23 | x = [1, 2, 3, 4, 5]
24 | hops = [3, 2, 2, 2, 2]
25 | var = [0, 0, 0, 0, 0 ]
26 | segment = [15, 45, 45, 45, 45]
27 |
28 |
29 |
30 | fig, ax1 = plt.subplots(figsize=(5, 3))
31 | ax2 = ax1.twinx()
32 | matplotlib.rcParams['pdf.fonttype'] = 42
33 | matplotlib.rcParams['ps.fonttype'] = 42
34 | # plt.rcParams['font.sans-serif'] = 'Times New Roman'
35 | # plt.rcParams['mathtext.fontset']= 'custom'
36 | width = 0.26
37 | # cm stic stixsans custom
38 | x_n = [i-0*width for i in x]
39 | ax1.bar(x_n,hops ,width=width, label='Hops', color="lightskyblue" ,linewidth = 1,edgecolor = 'black' ,yerr=var, error_kw=dict(lw=1, capsize=2.5, capthick=1))
40 |
41 |
42 |
43 | l1 = ax2.plot(x, segment, '--', label='Segments', marker = 's', ms=ms, markeredgecolor='black', markeredgewidth=mes, color="#ff7f0e",linewidth = lw)
44 |
45 |
46 |
47 |
48 | fsize+=2
49 | plt.xlabel('Model', fontsize=fsize+1)
50 | ax1.set_xticks(x)
51 | ax1.set_xticklabels(labels=model,rotation=-0, fontsize=fsize+1)
52 | ax1.set_xlabel('Relative Weight', fontsize=fsize+1)
53 |
54 | # ax1.set_yscale('log')
55 | ax1.set_ylabel('Hops (s)', fontsize=fsize+1)
56 | ax1.set_yticks([1,2,3,4])
57 | ax1.set_yticklabels(labels=['1','2','3','4'], fontsize=fsize+1)
58 | ax1.set_ylim(0,5)
59 |
60 |
61 | ax2.set_ylabel('Segments', fontsize=fsize+1)
62 | ax2.set_yticks([25, 50, 75, 100])
63 | ax2.set_yticklabels(labels=['25','50','75','100'], fontsize=fsize+1)
64 | ax2.set_ylim(0,125)
65 |
66 |
67 | plt.xlim(0.3,5.7)
68 |
69 |
70 | lines, labels = ax1.get_legend_handles_labels()
71 | lines2, labels2 = ax2.get_legend_handles_labels()
72 | f_line = lines + lines2
73 | # f_line[1] = lines[0]
74 | # f_line[0] = lines2[0]
75 | # f_line[3] = lines[1]
76 | # f_line[2] = lines2[1]
77 | f_lable = labels + labels2
78 | # f_lable[1] = labels[0]
79 | # f_lable[0] = labels2[0]
80 | # f_lable[3] = labels[1]
81 | # f_lable[2] = labels2[1]
82 | ax2.legend(f_line, f_lable, fancybox=True, fontsize=fsize-8,loc = "upper right", ncol=1)
83 |
84 | plt.grid(which ='major',linestyle= ':') #'major', 'minor' , 'both'
85 | plt.savefig('../figures/Coefficent-hops_Clos.pdf',dpi=600,format='pdf', bbox_inches='tight')
86 | # plt.show()
87 |
--------------------------------------------------------------------------------
/src/eval/Configurations/Table3_DINC_config_pegasus_sliced.json:
--------------------------------------------------------------------------------
1 | {
2 | "directory config": {
3 | "work": "/home/p4/DINC_oct",
4 | "log plot file name": "Folded-Clos_3core_6aggregation_24access.pdf",
5 | "p4 file": "./src/sample/pegasus_tofino/pegasus_sliced.p4"
6 | },
7 | "network config": {
8 | "topology": "Folded-Clos",
9 | "n_core": 3,
10 | "n_aggregation": 6,
11 | "n_access": 24,
12 | "input device list": [
13 | 9,
14 | 10,
15 | 11,
16 | 12,
17 | 13,
18 | 14,
19 | 15,
20 | 16,
21 | 17,
22 | 18,
23 | 19,
24 | 20,
25 | 21,
26 | 22,
27 | 23,
28 | 24,
29 | 25,
30 | 26,
31 | 27,
32 | 28,
33 | 29,
34 | 30,
35 | 31,
36 | 32
37 | ],
38 | "output device list": [
39 | 0,
40 | 1,
41 | 2
42 | ],
43 | "resources list": [
44 | "stage",
45 | "memory"
46 | ],
47 | "stage": [
48 | 5,
49 | 5,
50 | 5,
51 | 5,
52 | 5,
53 | 5,
54 | 5,
55 | 5,
56 | 5,
57 | 5,
58 | 5,
59 | 5,
60 | 5,
61 | 5,
62 | 5,
63 | 5,
64 | 5,
65 | 5,
66 | 5,
67 | 5,
68 | 5,
69 | 5,
70 | 5,
71 | 5,
72 | 5,
73 | 5,
74 | 5,
75 | 5,
76 | 5,
77 | 5,
78 | 5,
79 | 5,
80 | 5
81 | ],
82 | "memory": [
83 | 5,
84 | 5,
85 | 5,
86 | 5,
87 | 5,
88 | 5,
89 | 5,
90 | 5,
91 | 5,
92 | 5,
93 | 5,
94 | 5,
95 | 5,
96 | 5,
97 | 5,
98 | 5,
99 | 5,
100 | 5,
101 | 5,
102 | 5,
103 | 5,
104 | 5,
105 | 5,
106 | 5,
107 | 5,
108 | 5,
109 | 5,
110 | 5,
111 | 5,
112 | 5,
113 | 5,
114 | 5,
115 | 5
116 | ]
117 | },
118 | "operation config": {
119 | "display plot": false,
120 | "test ILP": "True",
121 | "test details": false
122 | },
123 | "p4 config": {
124 | "slicing method": "Manually",
125 | "start marker": "@!",
126 | "end marker": "!@",
127 | "key element info": [
128 | "slice",
129 | "position"
130 | ],
131 | "existed sliced p4 file": [
132 | "/home/p4/DINC_oct/src/temp/P4/E3_control.p4",
133 | "/home/p4/DINC_oct/src/temp/P4/E0_control.p4",
134 | "/home/p4/DINC_oct/src/temp/P4/E1_control.p4",
135 | "/home/p4/DINC_oct/src/temp/P4/E0_control-apply.p4",
136 | "/home/p4/DINC_oct/src/temp/P4/E1_control-apply.p4",
137 | "/home/p4/DINC_oct/src/temp/P4/E2_control-apply.p4",
138 | "/home/p4/DINC_oct/src/temp/P4/E3_control-apply.p4"
139 | ],
140 | "stage": [
141 | 1,
142 | 4,
143 | 2,
144 | 1
145 | ],
146 | "memory": [
147 | 1,
148 | 4,
149 | 2,
150 | 1
151 | ]
152 | },
153 | "solver config": {
154 | "solver type": "ILP",
155 | "solver variation": "Type_1"
156 | }
157 | }
--------------------------------------------------------------------------------
/src/eval/Configurations/Table3_DINC_config_pint_sliced.json:
--------------------------------------------------------------------------------
1 | {
2 | "directory config": {
3 | "work": "/home/p4/DINC_oct",
4 | "log plot file name": "Folded-Clos_3core_6aggregation_24access.pdf",
5 | "p4 file": "./src/sample/PINT/pint_sliced.p4"
6 | },
7 | "network config": {
8 | "topology": "Folded-Clos",
9 | "n_core": 3,
10 | "n_aggregation": 6,
11 | "n_access": 24,
12 | "input device list": [
13 | 0,
14 | 1,
15 | 2
16 | ],
17 | "output device list": [
18 | 9
19 | ],
20 | "resources list": [
21 | "stage",
22 | "memory"
23 | ],
24 | "stage": [
25 | 5,
26 | 5,
27 | 5,
28 | 5,
29 | 5,
30 | 5,
31 | 5,
32 | 5,
33 | 5,
34 | 5,
35 | 5,
36 | 5,
37 | 5,
38 | 5,
39 | 5,
40 | 5,
41 | 5,
42 | 5,
43 | 5,
44 | 5,
45 | 5,
46 | 5,
47 | 5,
48 | 5,
49 | 5,
50 | 5,
51 | 5,
52 | 5,
53 | 5,
54 | 5,
55 | 5,
56 | 5,
57 | 5
58 | ],
59 | "memory": [
60 | 5,
61 | 5,
62 | 5,
63 | 5,
64 | 5,
65 | 5,
66 | 5,
67 | 5,
68 | 5,
69 | 5,
70 | 5,
71 | 5,
72 | 5,
73 | 5,
74 | 5,
75 | 5,
76 | 5,
77 | 5,
78 | 5,
79 | 5,
80 | 5,
81 | 5,
82 | 5,
83 | 5,
84 | 5,
85 | 5,
86 | 5,
87 | 5,
88 | 5,
89 | 5,
90 | 5,
91 | 5,
92 | 5
93 | ]
94 | },
95 | "operation config": {
96 | "display plot": false,
97 | "test ILP": "True",
98 | "test details": false
99 | },
100 | "p4 config": {
101 | "slicing method": "Manually",
102 | "start marker": "@!",
103 | "end marker": "!@",
104 | "key element info": [
105 | "slice",
106 | "position"
107 | ],
108 | "existed sliced p4 file": [
109 | "/home/p4/DINC_oct/src/temp/P4/E0_control.p4",
110 | "/home/p4/DINC_oct/src/temp/P4/E1_control.p4",
111 | "/home/p4/DINC_oct/src/temp/P4/E2_control.p4",
112 | "/home/p4/DINC_oct/src/temp/P4/E3_control.p4",
113 | "/home/p4/DINC_oct/src/temp/P4/E0_control-apply.p4",
114 | "/home/p4/DINC_oct/src/temp/P4/E1_control-apply.p4",
115 | "/home/p4/DINC_oct/src/temp/P4/E2_control-apply.p4",
116 | "/home/p4/DINC_oct/src/temp/P4/E3_control-apply.p4",
117 | "/home/p4/DINC_oct/src/temp/P4/E4_control-apply.p4"
118 | ],
119 | "stage": [
120 | 1,
121 | 1,
122 | 5,
123 | 3,
124 | 1
125 | ],
126 | "memory": [
127 | 1,
128 | 1,
129 | 5,
130 | 3,
131 | 1
132 | ]
133 | },
134 | "solver config": {
135 | "solver type": "ILP",
136 | "solver variation": "Type_1"
137 | }
138 | }
--------------------------------------------------------------------------------
/src/eval/Configurations/Table3_DT_DINC_config.json:
--------------------------------------------------------------------------------
1 | {
2 | "directory config": {
3 | "work": "/home/jesu3779/Documents/DINC/DINC_OSR_1.1",
4 | "log plot file name": "Folded-Clos-ASP_3core_6aggregation_24access.pdf",
5 | "p4 file": "./src/sample/Planter_DT/DT_performance_Iris_2.p4"
6 | },
7 | "network config": {
8 | "topology": "Folded-Clos-ASP",
9 | "n_core": 3,
10 | "n_aggregation": 6,
11 | "n_access": 24,
12 | "input device list": [
13 | 9
14 | ],
15 | "output device list": [
16 | 0,
17 | 1,
18 | 2
19 | ],
20 | "resources list": [
21 | "stage",
22 | "memory"
23 | ],
24 | "stage": [
25 | 5,
26 | 5,
27 | 5,
28 | 5,
29 | 5,
30 | 5,
31 | 5,
32 | 5,
33 | 5,
34 | 5,
35 | 5,
36 | 5,
37 | 5,
38 | 5,
39 | 5,
40 | 5,
41 | 5,
42 | 5,
43 | 5,
44 | 5,
45 | 5,
46 | 5,
47 | 5,
48 | 5,
49 | 5,
50 | 5,
51 | 5,
52 | 5,
53 | 5,
54 | 5,
55 | 5,
56 | 5,
57 | 5
58 | ],
59 | "memory": [
60 | 5,
61 | 5,
62 | 5,
63 | 5,
64 | 5,
65 | 5,
66 | 5,
67 | 5,
68 | 5,
69 | 5,
70 | 5,
71 | 5,
72 | 5,
73 | 5,
74 | 5,
75 | 5,
76 | 5,
77 | 5,
78 | 5,
79 | 5,
80 | 5,
81 | 5,
82 | 5,
83 | 5,
84 | 5,
85 | 5,
86 | 5,
87 | 5,
88 | 5,
89 | 5,
90 | 5,
91 | 5,
92 | 5
93 | ]
94 | },
95 | "operation config": {
96 | "display plot": false,
97 | "test ILP": "True",
98 | "test details": "True"
99 | },
100 | "p4 config": {
101 | "slicing method": "Manually",
102 | "start marker": "@!",
103 | "end marker": "!@",
104 | "key element info": [
105 | "slice",
106 | "position"
107 | ],
108 | "existed sliced p4 file": [
109 | "/home/jesu3779/Documents/DINC/DINC_OSR_1.1/src/temp/P4/E0_control.p4",
110 | "/home/jesu3779/Documents/DINC/DINC_OSR_1.1/src/temp/P4/E1_control.p4",
111 | "/home/jesu3779/Documents/DINC/DINC_OSR_1.1/src/temp/P4/E0_control-apply.p4",
112 | "/home/jesu3779/Documents/DINC/DINC_OSR_1.1/src/temp/P4/E1_control-apply.p4"
113 | ],
114 | "stage": [
115 | 1,
116 | 1
117 | ],
118 | "memory": [
119 | 1,
120 | 1
121 | ]
122 | },
123 | "solver config": {
124 | "solver type": "ILP",
125 | "solver variation": "Type_1"
126 | }
127 | }
--------------------------------------------------------------------------------
/src/eval/Configurations/Table3_NB_DINC_config.json:
--------------------------------------------------------------------------------
1 | {
2 | "directory config": {
3 | "work": "/home/jesu3779/Documents/DINC/DINC_OSR_1.1",
4 | "log plot file name": "Folded-Clos-ASP_3core_6aggregation_24access.pdf",
5 | "p4 file": "./src/sample/Planter_Bayes/Bayes_performance_UNSW_5_tuple_2.p4"
6 | },
7 | "network config": {
8 | "topology": "Folded-Clos-ASP",
9 | "n_core": 3,
10 | "n_aggregation": 6,
11 | "n_access": 24,
12 | "input device list": [
13 | 0,
14 | 1,
15 | 2
16 | ],
17 | "output device list": [
18 | 9,
19 | 10,
20 | 11,
21 | 12,
22 | 13,
23 | 14,
24 | 15,
25 | 16,
26 | 17,
27 | 18,
28 | 19,
29 | 20,
30 | 21,
31 | 22,
32 | 23,
33 | 24,
34 | 25,
35 | 26,
36 | 27,
37 | 28,
38 | 29,
39 | 30,
40 | 31,
41 | 32
42 | ],
43 | "resources list": [
44 | "stage",
45 | "memory"
46 | ],
47 | "stage": [
48 | 5,
49 | 5,
50 | 5,
51 | 5,
52 | 5,
53 | 5,
54 | 5,
55 | 5,
56 | 5,
57 | 5,
58 | 5,
59 | 5,
60 | 5,
61 | 5,
62 | 5,
63 | 5,
64 | 5,
65 | 5,
66 | 5,
67 | 5,
68 | 5,
69 | 5,
70 | 5,
71 | 5,
72 | 5,
73 | 5,
74 | 5,
75 | 5,
76 | 5,
77 | 5,
78 | 5,
79 | 5,
80 | 5
81 | ],
82 | "memory": [
83 | 5,
84 | 5,
85 | 5,
86 | 5,
87 | 5,
88 | 5,
89 | 5,
90 | 5,
91 | 5,
92 | 5,
93 | 5,
94 | 5,
95 | 5,
96 | 5,
97 | 5,
98 | 5,
99 | 5,
100 | 5,
101 | 5,
102 | 5,
103 | 5,
104 | 5,
105 | 5,
106 | 5,
107 | 5,
108 | 5,
109 | 5,
110 | 5,
111 | 5,
112 | 5,
113 | 5,
114 | 5,
115 | 5
116 | ]
117 | },
118 | "operation config": {
119 | "display plot": false,
120 | "test ILP": "True",
121 | "test details": "True"
122 | },
123 | "p4 config": {
124 | "slicing method": "Manually",
125 | "start marker": "@!",
126 | "end marker": "!@",
127 | "key element info": [
128 | "slice",
129 | "position"
130 | ],
131 | "existed sliced p4 file": [
132 | "/home/jesu3779/Documents/DINC/DINC_OSR_1.1/src/temp/P4/E0_control.p4",
133 | "/home/jesu3779/Documents/DINC/DINC_OSR_1.1/src/temp/P4/E1_control.p4",
134 | "/home/jesu3779/Documents/DINC/DINC_OSR_1.1/src/temp/P4/E0_control-apply.p4",
135 | "/home/jesu3779/Documents/DINC/DINC_OSR_1.1/src/temp/P4/E1_control-apply.p4"
136 | ],
137 | "stage": [
138 | 4,
139 | 4
140 | ],
141 | "memory": [
142 | 1,
143 | 1
144 | ]
145 | },
146 | "solver config": {
147 | "solver type": "ILP",
148 | "solver variation": "Type_1"
149 | }
150 | }
--------------------------------------------------------------------------------
/src/eval/Configurations/Table3_RF_DINC_config.json:
--------------------------------------------------------------------------------
1 | {
2 | "directory config": {
3 | "work": "/home/jesu3779/Documents/DINC/DINC_OSR_1.1",
4 | "log plot file name": "Folded-Clos-ASP_3core_6aggregation_24access.pdf",
5 | "p4 file": "./src/sample/Planter_RF/RF_performance_UNSW_5_tuple_3.p4"
6 | },
7 | "network config": {
8 | "topology": "Folded-Clos-ASP",
9 | "n_core": 3,
10 | "n_aggregation": 6,
11 | "n_access": 24,
12 | "input device list": [
13 | 9,
14 | 10,
15 | 11,
16 | 12,
17 | 13,
18 | 14,
19 | 15,
20 | 16,
21 | 17,
22 | 18,
23 | 19,
24 | 20,
25 | 21,
26 | 22,
27 | 23,
28 | 24,
29 | 25,
30 | 26,
31 | 27,
32 | 28,
33 | 29,
34 | 30,
35 | 31,
36 | 32
37 | ],
38 | "output device list": [
39 | 0,
40 | 1,
41 | 2
42 | ],
43 | "resources list": [
44 | "stage",
45 | "memory"
46 | ],
47 | "stage": [
48 | 5,
49 | 5,
50 | 5,
51 | 5,
52 | 5,
53 | 5,
54 | 5,
55 | 5,
56 | 5,
57 | 5,
58 | 5,
59 | 5,
60 | 5,
61 | 5,
62 | 5,
63 | 5,
64 | 5,
65 | 5,
66 | 5,
67 | 5,
68 | 5,
69 | 5,
70 | 5,
71 | 5,
72 | 5,
73 | 5,
74 | 5,
75 | 5,
76 | 5,
77 | 5,
78 | 5,
79 | 5,
80 | 5
81 | ],
82 | "memory": [
83 | 5,
84 | 5,
85 | 5,
86 | 5,
87 | 5,
88 | 5,
89 | 5,
90 | 5,
91 | 5,
92 | 5,
93 | 5,
94 | 5,
95 | 5,
96 | 5,
97 | 5,
98 | 5,
99 | 5,
100 | 5,
101 | 5,
102 | 5,
103 | 5,
104 | 5,
105 | 5,
106 | 5,
107 | 5,
108 | 5,
109 | 5,
110 | 5,
111 | 5,
112 | 5,
113 | 5,
114 | 5,
115 | 5
116 | ]
117 | },
118 | "operation config": {
119 | "display plot": false,
120 | "test ILP": "True",
121 | "test details": "True"
122 | },
123 | "p4 config": {
124 | "slicing method": "Manually",
125 | "start marker": "@!",
126 | "end marker": "!@",
127 | "key element info": [
128 | "slice",
129 | "position"
130 | ],
131 | "existed sliced p4 file": [
132 | "/home/jesu3779/Documents/DINC/DINC_OSR_1.1/src/temp/P4/E0_control-apply.p4",
133 | "/home/jesu3779/Documents/DINC/DINC_OSR_1.1/src/temp/P4/E1_control-apply.p4",
134 | "/home/jesu3779/Documents/DINC/DINC_OSR_1.1/src/temp/P4/E2_control-apply.p4"
135 | ],
136 | "stage": [
137 | 3,
138 | 2,
139 | 1
140 | ],
141 | "memory": [
142 | 3,
143 | 2,
144 | 1
145 | ]
146 | },
147 | "solver config": {
148 | "solver type": "ILP",
149 | "solver variation": "Type_1"
150 | }
151 | }
--------------------------------------------------------------------------------
/src/eval/Configurations/Table3_SVM_DINC_config.json:
--------------------------------------------------------------------------------
1 | {
2 | "directory config": {
3 | "work": "/home/jesu3779/Documents/DINC/DINC_OSR_1.1",
4 | "log plot file name": "Folded-Clos-ASP_3core_6aggregation_24access.pdf",
5 | "p4 file": "./src/sample/Planter_SVM/SVM_performance_UNSW_5_tuple_3.p4"
6 | },
7 | "network config": {
8 | "topology": "Folded-Clos-ASP",
9 | "n_core": 3,
10 | "n_aggregation": 6,
11 | "n_access": 24,
12 | "input device list": [
13 | 9
14 | ],
15 | "output device list": [
16 | 32
17 | ],
18 | "resources list": [
19 | "stage",
20 | "memory"
21 | ],
22 | "stage": [
23 | 5,
24 | 5,
25 | 5,
26 | 5,
27 | 5,
28 | 5,
29 | 5,
30 | 5,
31 | 5,
32 | 5,
33 | 5,
34 | 5,
35 | 5,
36 | 5,
37 | 5,
38 | 5,
39 | 5,
40 | 5,
41 | 5,
42 | 5,
43 | 5,
44 | 5,
45 | 5,
46 | 5,
47 | 5,
48 | 5,
49 | 5,
50 | 5,
51 | 5,
52 | 5,
53 | 5,
54 | 5,
55 | 5
56 | ],
57 | "memory": [
58 | 5,
59 | 5,
60 | 5,
61 | 5,
62 | 5,
63 | 5,
64 | 5,
65 | 5,
66 | 5,
67 | 5,
68 | 5,
69 | 5,
70 | 5,
71 | 5,
72 | 5,
73 | 5,
74 | 5,
75 | 5,
76 | 5,
77 | 5,
78 | 5,
79 | 5,
80 | 5,
81 | 5,
82 | 5,
83 | 5,
84 | 5,
85 | 5,
86 | 5,
87 | 5,
88 | 5,
89 | 5,
90 | 5
91 | ]
92 | },
93 | "operation config": {
94 | "display plot": false,
95 | "test ILP": "True",
96 | "test details": "True"
97 | },
98 | "p4 config": {
99 | "slicing method": "Manually",
100 | "start marker": "@!",
101 | "end marker": "!@",
102 | "key element info": [
103 | "slice",
104 | "position"
105 | ],
106 | "existed sliced p4 file": [
107 | "/home/jesu3779/Documents/DINC/DINC_OSR_1.1/src/temp/P4/E0_control.p4",
108 | "/home/jesu3779/Documents/DINC/DINC_OSR_1.1/src/temp/P4/E1_control.p4",
109 | "/home/jesu3779/Documents/DINC/DINC_OSR_1.1/src/temp/P4/E0_control-apply.p4",
110 | "/home/jesu3779/Documents/DINC/DINC_OSR_1.1/src/temp/P4/E1_control-apply.p4",
111 | "/home/jesu3779/Documents/DINC/DINC_OSR_1.1/src/temp/P4/E2_control-apply.p4"
112 | ],
113 | "stage": [
114 | 3,
115 | 3,
116 | 3
117 | ],
118 | "memory": [
119 | 1,
120 | 1,
121 | 1
122 | ]
123 | },
124 | "solver config": {
125 | "solver type": "ILP",
126 | "solver variation": "Type_1"
127 | }
128 | }
--------------------------------------------------------------------------------
/src/eval/Configurations/Table3_XGB_DINC_config.json:
--------------------------------------------------------------------------------
1 | {
2 | "directory config": {
3 | "work": "/home/jesu3779/Documents/DINC/DINC_OSR_1.1",
4 | "log plot file name": "Folded-Clos-ASP_3core_6aggregation_24access.pdf",
5 | "p4 file": "./src/sample/Planter_XGB/XGB_performance_UNSW_5_tuple_4.p4"
6 | },
7 | "network config": {
8 | "topology": "Folded-Clos-ASP",
9 | "n_core": 3,
10 | "n_aggregation": 6,
11 | "n_access": 24,
12 | "input device list": [
13 | 0,
14 | 1,
15 | 2
16 | ],
17 | "output device list": [
18 | 9,
19 | 10,
20 | 11,
21 | 12,
22 | 13,
23 | 14,
24 | 15,
25 | 16,
26 | 17,
27 | 18,
28 | 19,
29 | 20,
30 | 21,
31 | 22,
32 | 23,
33 | 24,
34 | 25,
35 | 26,
36 | 27,
37 | 28,
38 | 29,
39 | 30,
40 | 31,
41 | 32
42 | ],
43 | "resources list": [
44 | "stage",
45 | "memory"
46 | ],
47 | "stage": [
48 | 5,
49 | 5,
50 | 5,
51 | 5,
52 | 5,
53 | 5,
54 | 5,
55 | 5,
56 | 5,
57 | 5,
58 | 5,
59 | 5,
60 | 5,
61 | 5,
62 | 5,
63 | 5,
64 | 5,
65 | 5,
66 | 5,
67 | 5,
68 | 5,
69 | 5,
70 | 5,
71 | 5,
72 | 5,
73 | 5,
74 | 5,
75 | 5,
76 | 5,
77 | 5,
78 | 5,
79 | 5,
80 | 5
81 | ],
82 | "memory": [
83 | 5,
84 | 5,
85 | 5,
86 | 5,
87 | 5,
88 | 5,
89 | 5,
90 | 5,
91 | 5,
92 | 5,
93 | 5,
94 | 5,
95 | 5,
96 | 5,
97 | 5,
98 | 5,
99 | 5,
100 | 5,
101 | 5,
102 | 5,
103 | 5,
104 | 5,
105 | 5,
106 | 5,
107 | 5,
108 | 5,
109 | 5,
110 | 5,
111 | 5,
112 | 5,
113 | 5,
114 | 5,
115 | 5
116 | ]
117 | },
118 | "operation config": {
119 | "display plot": false,
120 | "test ILP": "True",
121 | "test details": "True"
122 | },
123 | "p4 config": {
124 | "slicing method": "Manually",
125 | "start marker": "@!",
126 | "end marker": "!@",
127 | "key element info": [
128 | "slice",
129 | "position"
130 | ],
131 | "existed sliced p4 file": [
132 | "/home/jesu3779/Documents/DINC/DINC_OSR_1.1/src/temp/P4/E0_control-apply.p4",
133 | "/home/jesu3779/Documents/DINC/DINC_OSR_1.1/src/temp/P4/E1_control-apply.p4",
134 | "/home/jesu3779/Documents/DINC/DINC_OSR_1.1/src/temp/P4/E2_control-apply.p4",
135 | "/home/jesu3779/Documents/DINC/DINC_OSR_1.1/src/temp/P4/E3_control-apply.p4"
136 | ],
137 | "stage": [
138 | 1,
139 | 2,
140 | 2,
141 | 1
142 | ],
143 | "memory": [
144 | 1,
145 | 1,
146 | 1,
147 | 1
148 | ]
149 | },
150 | "solver config": {
151 | "solver type": "ILP",
152 | "solver variation": "Type_1"
153 | }
154 | }
--------------------------------------------------------------------------------
/src/eval/Hops-CDF/Setups_BT-Hops.py:
--------------------------------------------------------------------------------
1 | import matplotlib.pyplot as plt
2 | import numpy as np
3 | # import seaborn as sns
4 |
5 |
6 | x = [1,2,3,4,5]
7 | y1 = [0, 0.10538624, 0.7928108, 0.98947646, 1]
8 | y2 = [0, 0.24792547, 0.993965, 1, 1]
9 | y3 = [0, 1, 1, 1,1]
10 | y4 = [0, 0.08333333, 1, 1, 1]
11 | y5 = [0, 1, 1, 1, 1,]
12 |
13 | y1 = [i*100 for i in y1]
14 | y2 = [i*100 for i in y2]
15 | y3 = [i*100 for i in y3]
16 | y4 = [i*100 for i in y4]
17 | y5 = [i*100 for i in y5]
18 | distance = 0
19 | x1 = x
20 | x2 = [i-distance for i in x]
21 | x3 = [i-2*distance for i in x]
22 | x4 = [i+distance for i in x]
23 | x5 = [i+2*distance for i in x]
24 |
25 |
26 | fsize =25
27 | lw=2
28 | ms = 6
29 | mes = 1
30 | lw=2
31 |
32 | fig, ax1 = plt.subplots(figsize=(5.5, 3))
33 | plt.rcParams['pdf.fonttype'] = 42
34 | plt.rcParams['ps.fonttype'] = 42
35 | # plt.rcParams['font.sans-serif'] = 'Times New Roman'
36 | # plt.rcParams['mathtext.fontset']= 'custom'
37 | plt.step(x5, y5, marker = '^',color="dodgerblue",linewidth = lw , ms=ms, markeredgecolor='black', markeredgewidth=mes, where='post', label='post')
38 | plt.step(x3, y3, marker = 'd',color="mediumslateblue",linewidth = lw , ms=ms, markeredgecolor='black', markeredgewidth=mes, where='post', label='post')
39 | plt.step(x2, y2, marker = 'p',color="mediumseagreen",linewidth = lw , ms=ms, markeredgecolor='black', markeredgewidth=mes, where='post', label='post')
40 | plt.step(x4, y4, marker = 'H',color="firebrick",linewidth = lw , ms=ms, markeredgecolor='black', markeredgewidth=mes, where='post', label='post')
41 | plt.step(x1, y1, marker = 's',color="palevioletred",linewidth = lw , ms=ms, markeredgecolor='black', markeredgewidth=mes, where='post', label='post')
42 |
43 |
44 | plt.xlabel('Number of Hops', fontsize=fsize)
45 | plt.ylabel('CDF', fontsize=fsize)
46 |
47 |
48 |
49 | plt.yticks([ 0,30,60,90],labels=['0.1','0.3','0.6','0.9'], fontsize=fsize-1)
50 | plt.xticks([1,2,3,4,5], fontsize=fsize-1)
51 | plt.ylim(-15,115)
52 | plt.xlim(0.5,5.5)
53 | # plt.legend(loc = "upper left", ncol=1, fontsize=fsize-8)
54 |
55 | plt.grid(which ='major',linestyle= ':') #'major', 'minor' , 'both'
56 | plt.savefig('../figures/Setup-Hops_BT.pdf',dpi=600,format='pdf', bbox_inches='tight')
57 |
--------------------------------------------------------------------------------
/src/eval/Hops-CDF/Setups_Clos-Hops.py:
--------------------------------------------------------------------------------
1 | import matplotlib.pyplot as plt
2 | import numpy as np
3 | # import seaborn as sns
4 |
5 |
6 | x = [1,2,3,4,5]
7 | y1 = [0, 1, 1, 1, 1,]
8 | y2 = [0, 1, 1, 1, 1,]
9 | y3 = [0, 1, 1, 1, 1,]
10 | y4 = [0, 1, 1, 1, 1,]
11 | y5 = [0, 1, 1, 1, 1,]
12 |
13 | y1 = [i*100 for i in y1]
14 | y2 = [i*100 for i in y2]
15 | y3 = [i*100 for i in y3]
16 | y4 = [i*100 for i in y4]
17 | y5 = [i*100 for i in y5]
18 | distance = 0
19 | x1 = x
20 | x2 = [i-distance for i in x]
21 | x3 = [i-2*distance for i in x]
22 | x4 = [i+distance for i in x]
23 | x5 = [i+2*distance for i in x]
24 |
25 |
26 | fsize =25
27 | lw=2
28 | ms = 6
29 | mes = 1
30 | lw=2
31 |
32 | fig, ax1 = plt.subplots(figsize=(5.5, 3))
33 | plt.rcParams['pdf.fonttype'] = 42
34 | plt.rcParams['ps.fonttype'] = 42
35 | # plt.rcParams['font.sans-serif'] = 'Times New Roman'
36 | # plt.rcParams['mathtext.fontset']= 'custom'
37 |
38 | plt.step(x3, y3, marker = 'd',color="mediumslateblue",linewidth = lw , ms=ms, markeredgecolor='black', markeredgewidth=mes, where='post', label='post')
39 | plt.step(x2, y2, marker = 'p',color="mediumseagreen",linewidth = lw , ms=ms, markeredgecolor='black', markeredgewidth=mes, where='post', label='post')
40 | plt.step(x1, y1, marker = 's',color="palevioletred",linewidth = lw , ms=ms, markeredgecolor='black', markeredgewidth=mes, where='post', label='post')
41 | plt.step(x5, y5, marker = '^',color="dodgerblue",linewidth = lw , ms=ms, markeredgecolor='black', markeredgewidth=mes, where='post', label='post')
42 | plt.step(x4, y4, marker = 'H',color="firebrick",linewidth = lw , ms=ms, markeredgecolor='black', markeredgewidth=mes, where='post', label='post')
43 |
44 |
45 | plt.xlabel('Number of Hops', fontsize=fsize)
46 | plt.ylabel('CDF', fontsize=fsize)
47 |
48 |
49 |
50 | plt.yticks([ 0,30,60,90],labels=['0.1','0.3','0.6','0.9'], fontsize=fsize-1)
51 | plt.xticks([1,2,3,4,5], fontsize=fsize-1)
52 | plt.ylim(-15,115)
53 | plt.xlim(0.5,5.5)
54 | # plt.legend(loc = "upper left", ncol=1, fontsize=fsize-8)
55 |
56 | plt.grid(which ='major',linestyle= ':') #'major', 'minor' , 'both'
57 | plt.savefig('../figures/Setup-Hops_Clos.pdf',dpi=600,format='pdf', bbox_inches='tight')
58 |
--------------------------------------------------------------------------------
/src/eval/Hops-CDF/Setups_label.py:
--------------------------------------------------------------------------------
1 | import matplotlib.pyplot as plt
2 | import numpy as np
3 | # import seaborn as sns
4 |
5 |
6 | x = [1,2,3,4,5]
7 | y1 = [0, 1, 1, 1, 1,]
8 | y2 = [0, 1, 1, 1, 1,]
9 | y3 = [0, 1, 1, 1, 1,]
10 | y4 = [0, 1, 1, 1, 1,]
11 | y5 = [0, 1, 1, 1, 1,]
12 |
13 | y1 = [i*100 for i in y1]
14 | y2 = [i*100 for i in y2]
15 | y3 = [i*100 for i in y3]
16 | y4 = [i*100 for i in y4]
17 | y5 = [i*100 for i in y5]
18 | distance = 0.03
19 | x1 = x
20 | x2 = [i-distance for i in x]
21 | x3 = [i-2*distance for i in x]
22 | x4 = [i+distance for i in x]
23 | x5 = [i+2*distance for i in x]
24 |
25 |
26 | fsize =25
27 | lw=2
28 | ms = 6
29 | mes = 1
30 | lw=2
31 |
32 | fig, ax1 = plt.subplots(figsize=(5, 3))
33 | plt.rcParams['pdf.fonttype'] = 42
34 | plt.rcParams['ps.fonttype'] = 42
35 | # plt.rcParams['font.sans-serif'] = 'Times New Roman'
36 | # plt.rcParams['mathtext.fontset']= 'custom'
37 |
38 | plt.step(x1, y1, marker = 's',color="palevioletred",linewidth = lw , ms=ms, markeredgecolor='black', markeredgewidth=mes, where='post', label='Setup 1')
39 | plt.step(x2, y2, marker = 'p',color="mediumseagreen",linewidth = lw , ms=ms, markeredgecolor='black', markeredgewidth=mes, where='post', label='Setup 2')
40 | plt.step(x3, y3, marker = 'd',color="mediumslateblue",linewidth = lw , ms=ms, markeredgecolor='black', markeredgewidth=mes, where='post', label='Setup 3')
41 | plt.step(x4, y4, marker = 'H',color="firebrick",linewidth = lw , ms=ms, markeredgecolor='black', markeredgewidth=mes, where='post', label='Setup 4')
42 | plt.step(x5, y5, marker = '^',color="dodgerblue",linewidth = lw , ms=ms, markeredgecolor='black', markeredgewidth=mes, where='post', label='Setup 5')
43 |
44 |
45 |
46 | plt.xlabel('Number of Hops', fontsize=fsize)
47 | plt.ylabel('CDF Percent (%)', fontsize=fsize)
48 |
49 |
50 |
51 | plt.yticks([ 0,30,60,90], fontsize=fsize-1)
52 | plt.xticks([1,2,3,4,5], fontsize=fsize-1)
53 | plt.ylim(-15,115)
54 | plt.xlim(0.5,5.5)
55 | plt.legend(bbox_to_anchor=(1.05, 0), loc=3,ncol=5, labelspacing=0.4,columnspacing=0.4, borderaxespad=0, fontsize=fsize-8)
56 | plt.grid(which ='major',linestyle= ':') #'major', 'minor' , 'both'
57 | plt.savefig('../figures/Setups_label.pdf',dpi=600,format='pdf', bbox_inches='tight')
58 |
--------------------------------------------------------------------------------
/src/eval/Split Overhead/Mem.py:
--------------------------------------------------------------------------------
1 | import matplotlib.pyplot as plt
2 | import warnings
3 | # warnings.filterwarnings('ignore')
4 | import matplotlib
5 | import numpy as np
6 | import json
7 | from math import sqrt
8 |
9 |
10 |
11 | x = [2,3]
12 |
13 | DINC = [1700 , 600000]
14 | standalone = [1700 , 600000]
15 | fig, ax = plt.subplots(figsize=(3, 3))
16 | # plt.rcParams['font.sans-serif'] = 'Times New Roman'
17 | plt.rcParams['pdf.fonttype'] = 42
18 | plt.rcParams['ps.fonttype'] = 42
19 | width = 0.3
20 |
21 | x_n = [i-0.65*width for i in x]
22 | plt.bar(x_n, standalone,width=width, label='Seg. Ideal', color="pink" ,linewidth = 1,edgecolor = 'black')
23 |
24 | x_n = [i+0.65*width for i in x]
25 | plt.bar(x_n, DINC, width= width, label='Seg. DINC', color="lightskyblue",linewidth = 1,edgecolor = 'black')
26 |
27 | fsize =25
28 | # plt.ylabel('Nodes', fontsize=fsize)
29 | plt.ylabel('Entries', fontsize=fsize)
30 | plt.yscale('log')
31 | # plt.yticks([0.2,0.4,0.6,0.8] ,fontsize=fsize-1)
32 | plt.yticks([100,1000,10000,100000] ,fontsize=fsize-1)
33 | plt.xticks(x, labels=['Node 1', 'Node 2'], fontsize=fsize-1)
34 |
35 | plt.ylim(10,1000000)
36 | plt.xlim(1.4,3.6)
37 | #leg = plt.legend(loc='lower center', fontsize=fsize-8, handlelength=1)
38 | leg = plt.legend(loc='lower center', fontsize=fsize-8)
39 | plt.grid(which ='major',linestyle= ':', axis="y") #'major', 'minor', 'both'
40 | plt.savefig('../figures/Split_mem.pdf',dpi=600,format='pdf', bbox_inches='tight')
41 |
42 |
--------------------------------------------------------------------------------
/src/eval/Split Overhead/Stage.py:
--------------------------------------------------------------------------------
1 | import matplotlib.pyplot as plt
2 | import warnings
3 | # warnings.filterwarnings('ignore')
4 | import matplotlib
5 | import numpy as np
6 | import json
7 | from math import sqrt
8 |
9 |
10 |
11 | x = [2,3]
12 |
13 | DINC = [3 , 5]
14 | standalone = [2, 4]
15 | fig, ax = plt.subplots(figsize=(3, 3))
16 | # plt.rcParams['font.sans-serif'] = 'Times New Roman'
17 | plt.rcParams['pdf.fonttype'] = 42
18 | plt.rcParams['ps.fonttype'] = 42
19 | width = 0.3
20 |
21 | x_n = [i-0.65*width for i in x]
22 | plt.bar(x_n, standalone,width=width, label='Seg. Ideal', color="pink" ,linewidth = 1,edgecolor = 'black')
23 |
24 | x_n = [i+0.65*width for i in x]
25 | plt.bar(x_n, DINC, width= width, label='Seg. DINC', color="lightskyblue",linewidth = 1,edgecolor = 'black')
26 |
27 | fsize =25
28 | # plt.ylabel('Nodes', fontsize=fsize)
29 | plt.ylabel('Stage', fontsize=fsize)
30 | # plt.yscale('log')
31 | # plt.yticks([0.2,0.4,0.6,0.8] ,fontsize=fsize-1)
32 | plt.yticks([1.5,2.5,3.5,4.5] ,fontsize=fsize-1)
33 | plt.xticks(x, labels=['Node 1', 'Node 2'], fontsize=fsize-1)
34 | # plt.ylim(0,1)
35 | plt.ylim(0.5,5.5)
36 | plt.xlim(1.4,3.6)
37 | # leg = plt.legend(loc='lower center', fontsize=fsize-8, handlelength=1)
38 | leg = plt.legend(loc='lower center', fontsize=fsize-8)
39 | plt.grid(which ='major',linestyle= ':', axis="y") #'major', 'minor', 'both'
40 | plt.savefig('../figures/Split_stage.pdf',dpi=600,format='pdf', bbox_inches='tight')
41 |
42 |
--------------------------------------------------------------------------------
/src/eval/Split Overhead/with_switchp4.py:
--------------------------------------------------------------------------------
1 | import matplotlib.pyplot as plt
2 | import warnings
3 | # warnings.filterwarnings('ignore')
4 | import matplotlib
5 | import numpy as np
6 | import json
7 | from math import sqrt
8 |
9 |
10 |
11 | x = [2,3]
12 |
13 | DINC = [11, 12]
14 | standalone = [11 , 11]
15 | fig, ax = plt.subplots(figsize=(3, 3))
16 | # plt.rcParams['font.sans-serif'] = 'Times New Roman'
17 | plt.rcParams['pdf.fonttype'] = 42
18 | plt.rcParams['ps.fonttype'] = 42
19 | width = 0.3
20 |
21 | x_n = [i-0.65*width for i in x]
22 | plt.bar(x_n, standalone,width=width, label='Switch.p4', color="pink" ,linewidth = 1,edgecolor = 'black')
23 |
24 | x_n = [i+0.65*width for i in x]
25 | plt.bar(x_n, DINC, width= width, label='Seg.+Switch.p4', color="lightskyblue",linewidth = 1,edgecolor = 'black')
26 |
27 | fsize =25
28 | # plt.ylabel('Nodes', fontsize=fsize)
29 | plt.ylabel('Stage', fontsize=fsize)
30 | # plt.yscale('log')
31 | # plt.yticks([0.2,0.4,0.6,0.8] ,fontsize=fsize-1)
32 | plt.yticks([9,10,11,12] ,fontsize=fsize-1)
33 | plt.xticks(x, labels=['Node 1', 'Node 2'], fontsize=fsize-1)
34 | # plt.ylim(0,1)
35 | plt.ylim(8,13)
36 | plt.xlim(1.4,3.6)
37 | leg = plt.legend(loc='lower center', fontsize=fsize-8, handlelength=1)
38 | plt.grid(which ='major',linestyle= ':', axis="y") #'major', 'minor', 'both'
39 | plt.savefig('../figures/Split_stage_with_switch_p4.pdf',dpi=600,format='pdf', bbox_inches='tight')
40 |
41 |
--------------------------------------------------------------------------------
/src/eval/Throughput-Latency/Model_name-Latency.py:
--------------------------------------------------------------------------------
1 | import matplotlib.pyplot as plt
2 | import warnings
3 |
4 | # warnings.filterwarnings('ignore')
5 | import matplotlib
6 | import numpy as np
7 | import json
8 | from math import sqrt
9 | # warnings.filterwarnings('ignore')
10 |
11 |
12 | titles=[]
13 | latency=[]
14 | srams=[]
15 | tcams=[]
16 | memory=[]
17 |
18 | config = {}
19 | config['list of files'] = []
20 | config['list of files'] += [['sample', './Logs/switch_p4_metrics.json']]
21 | config['list of files'] +=[['seg0', './Logs/metrics0.json']]
22 | config['list of files'] +=[['seg1', './Logs/metrics1.json']]
23 | config['list of files'] +=[['seg2', './Logs/metrics2.json']]
24 | config['list of files'] +=[['seg3', './Logs/metrics3.json']]
25 | config['list of files'] +=[['switch', './Logs/metrics_switch.json']]
26 |
27 | for i in range(0,len(config['list of files'])):
28 | titles.append(config['list of files'][i][0])
29 | resources=json.load(open(config['list of files'][i][1],'r'))
30 | # print(resources['mau']['latency'][0]['cycles'])
31 | if (i==0):
32 | srams.append(1)
33 | tcams.append(1)
34 | sram_baseline=int(resources['mau']['srams'])
35 | tcam_baseline=int(resources['mau']['tcams'])
36 | memory.append(1)
37 | latency.append(1)
38 | latency_baseline=int(resources['mau']['latency'][0]['cycles'])
39 | else:
40 | sram=int(resources['mau']['srams'])/sram_baseline
41 | srams.append(sram)
42 | tcam=int(resources['mau']['tcams'])/tcam_baseline
43 | tcams.append(tcam)
44 | mems=(sram+tcam)/2
45 | memory.append(mems)
46 | lat=int(resources['mau']['latency'][0]['cycles'])/latency_baseline
47 | latency.append(lat)
48 | print("App: "+config['list of files'][i][0]+" Latency: "+str(lat)+" Memory: "+str(mems)+" SRAM: "+str(sram)+" TCAM: "+str(tcam))
49 |
50 |
51 |
52 | model = ['Seg0', 'Seg1', 'Seg2', 'Seg3' , 'RARE' ]
53 | x = [1,2,3,4]
54 |
55 | seg0 = latency[1]*100
56 | seg1 = latency[2]*100
57 | seg2 = latency[3]*100
58 | seg3 = latency[4]*100
59 |
60 | switch = latency[5]*100
61 |
62 | ASIC = [seg0, seg1,seg2, seg3]
63 |
64 | fig, ax = plt.subplots(figsize=(6.2, 3))
65 | plt.rcParams['pdf.fonttype'] = 42
66 | plt.rcParams['ps.fonttype'] = 42
67 | # plt.rcParams['font.sans-serif'] = 'Times New Roman'
68 | width = 0.26
69 |
70 | x_n = [i-0*width for i in x]
71 | plt.bar(x_n,ASIC , width= width, label='Coexist with RARE',color = 'lightskyblue', linewidth = 1,edgecolor = 'black')
72 |
73 |
74 | plt.bar([5],[switch] , width= width, label='Standalone RARE', color="silver",linewidth = 1,edgecolor = 'black')
75 |
76 |
77 |
78 |
79 | fsize =25
80 |
81 |
82 | # plt.grid(True) #'major', 'minor', 'both'
83 |
84 | # plt.xlabel('Model', fontsize=fsize)
85 | plt.ylabel('R-Latency (%)', fontsize=fsize)
86 | # plt.yscale('log')
87 | plt.yticks([15,30,45,60], fontsize=fsize-1)
88 | plt.xticks([1,2,3,4,5],labels=model,rotation=-20, fontsize=fsize-1)
89 | plt.xlim(0.3,5.7)
90 | plt.ylim(0,75)
91 | plt.legend(loc='lower right', ncol=1, fontsize=fsize-8)
92 | #
93 |
94 | # plt.legend(bbox_to_anchor=(1.05, 0), loc=3,ncol=5, borderaxespad=0, fontsize=fsize)
95 | plt.grid(which ='major', axis='y',linestyle= ':') #'major', 'minor' , 'both'
96 | plt.savefig('../figures/Segment-Latency.pdf',dpi=600,format='pdf', bbox_inches='tight')
97 |
--------------------------------------------------------------------------------
/src/eval/Throughput-Latency/Model_name-Throughput.py:
--------------------------------------------------------------------------------
1 | import matplotlib.pyplot as plt
2 | import warnings
3 |
4 | # warnings.filterwarnings('ignore')
5 | import matplotlib
6 | import numpy as np
7 | import json
8 | from math import sqrt
9 | # warnings.filterwarnings('ignore')
10 |
11 |
12 |
13 | fsize =25
14 |
15 | model = ['Seg0', 'Seg1', 'Seg2', 'Seg3' , 'RARE' ]
16 | x = [1,2,3,4]
17 |
18 | seg0 = (1596590+1596481+1596436+1596594)/1000000
19 | seg1 = (1596392+1596402+1596475+1596385)/1000000
20 | seg2 = (1596490+1596531+1596532+1596485)/1000000
21 | seg3 = (1596242+1596400+1596387+1596204)/1000000
22 |
23 | switch = (1596380+1596393+1596439+1596345)/1000000
24 |
25 | ASIC = [seg0, seg1,seg2, seg3]
26 |
27 | fig, ax = plt.subplots(figsize=(6, 3))
28 | plt.rcParams['pdf.fonttype'] = 42
29 | plt.rcParams['ps.fonttype'] = 42
30 | # plt.rcParams['font.sans-serif'] = 'Times New Roman'
31 |
32 |
33 | plt.hlines(6.4,0,6, linestyle="--" , color = 'red')
34 | plt.text(3.9, 6.6, 'Line rate', fontsize=fsize-1 , color = 'red')
35 |
36 | width = 0.26
37 | x_n = [i-0*width for i in x]
38 | plt.bar(x_n,ASIC , width= width, label='Coexist with RARE',color = 'lightskyblue', linewidth = 1,edgecolor = 'black')
39 |
40 |
41 | plt.bar([5],[switch] , width= width, label='Standalone RARE', color="silver",linewidth = 1,edgecolor = 'black')
42 |
43 |
44 |
45 |
46 |
47 |
48 | # plt.grid(True) #'major', 'minor', 'both'
49 |
50 | # plt.xlabel('Model', fontsize=fsize)
51 | plt.ylabel('Throughput', fontsize=fsize-1)
52 | # plt.yscale('log')
53 | plt.yticks([1.5,3,4.5,6], fontsize=fsize-1)
54 | plt.xticks([1,2,3,4,5],labels=model,rotation=-20, fontsize=fsize-1)
55 | plt.xlim(0.3,5.7)
56 | plt.ylim(0,7.5)
57 | plt.legend(loc='lower right', ncol=1, fontsize=fsize-8)
58 | #
59 |
60 | # plt.legend(bbox_to_anchor=(1.05, 0), loc=3,ncol=5, borderaxespad=0, fontsize=fsize)
61 | plt.grid(which ='major', axis='y',linestyle= ':') #'major', 'minor' , 'both'
62 | plt.savefig('../figures/Segment-Throughput.pdf',dpi=600,format='pdf', bbox_inches='tight')
63 |
--------------------------------------------------------------------------------
/src/eval/Time-Path_Segments/Time-Edge_Clos.py:
--------------------------------------------------------------------------------
1 | import matplotlib.pyplot as plt
2 | import warnings
3 | import matplotlib
4 | import numpy as np
5 | import json
6 | from math import sqrt
7 |
8 | fsize =25
9 | lw=2
10 | ms = 6
11 | mes = 1
12 | lw=2
13 |
14 |
15 |
16 |
17 | model = ['1', '2', '3', '4', '5']
18 | x = [1,2,3,4,5]
19 |
20 | # 0.10952112674713135, 0.12678711414337157, 0.13884289264678956, 0.16474764347076415, 0.17274291515350343]
21 | # 0.0032471952915711067, 0.0006922912296972685, 0.001049483076647019, 0.004338363073341647, 0.0010001896391073721]
22 | # 36,72,108,140,172
23 |
24 |
25 | time = [0.0030060768127441405, 0.004389834403991699, 0.005976200103759766, 0.007393336296081543, 0.008810830116271973]
26 |
27 | var = [0.00021867281575554406, 0.00019698073314995026, 0.0003215019508841349, 0.0002193663278438717, 0.00029543081091567815]
28 |
29 |
30 | path = [18,36,54,72,90]
31 |
32 | fig, ax1 = plt.subplots(figsize=(5, 3))
33 | ax2 = ax1.twinx()
34 | # plt.rcParams['font.sans-serif'] = 'Times New Roman'
35 | # plt.rcParams['mathtext.fontset']= 'custom'
36 | plt.rcParams['pdf.fonttype'] = 42
37 | plt.rcParams['ps.fonttype'] = 42
38 | width = 0.26
39 | # cm stic stixsans custom
40 | x_n = [i-0*width for i in x]
41 | ax1.bar(x_n,time ,width=width, label='Time (s)', color="lightskyblue" ,linewidth = 1,edgecolor = 'black' ,yerr=var, error_kw=dict(lw=1, capsize=2.5, capthick=1))
42 |
43 |
44 |
45 | l1 = ax2.plot(x, path, '--', label='Paths', marker = 's', ms=ms, markeredgecolor='black', markeredgewidth=mes, color="#ff7f0e",linewidth = lw)
46 |
47 |
48 |
49 |
50 | fsize+=2
51 | plt.xlabel('Model', fontsize=fsize+1)
52 | ax1.set_xticks(x)
53 | ax1.set_xticklabels(labels=model,rotation=-0, fontsize=fsize+1)
54 | ax1.set_xlabel('Num of Edge Nodes', fontsize=fsize+1)
55 |
56 | ax1.set_yscale('log')
57 | ax1.set_ylabel('Time (s)', fontsize=fsize+1)
58 | ax1.set_yticks([10**-3,10**-2,10**-1,10**0])
59 | ax1.set_yticklabels(labels=['10$^{-3}$','10$^{-2}$','10$^{-1}$','10$^{-0}$'], fontsize=fsize+1)
60 | ax1.set_ylim(10**-4,10**1)
61 |
62 |
63 | ax2.set_ylabel('Paths', fontsize=fsize+1)
64 | ax2.set_yticks([50,100,150,200])
65 | ax2.set_yticklabels(labels=['30','50','70','90'], fontsize=fsize+1)
66 | ax2.set_ylim(0,250)
67 |
68 |
69 | plt.xlim(0.3,5.7)
70 |
71 |
72 | lines, labels = ax1.get_legend_handles_labels()
73 | lines2, labels2 = ax2.get_legend_handles_labels()
74 | f_line = lines + lines2
75 | # f_line[1] = lines[0]
76 | # f_line[0] = lines2[0]
77 | # f_line[3] = lines[1]
78 | # f_line[2] = lines2[1]
79 | f_lable = labels + labels2
80 | # f_lable[1] = labels[0]
81 | # f_lable[0] = labels2[0]
82 | # f_lable[3] = labels[1]
83 | # f_lable[2] = labels2[1]
84 | ax2.legend(f_line, f_lable, fancybox=True, fontsize=fsize-8,loc = "upper left", ncol=1)
85 |
86 | plt.grid(which ='major', linestyle= ':') #'major', 'minor' , 'both'
87 | plt.savefig('../figures/Time-Edge_clos.pdf',dpi=600,format='pdf', bbox_inches='tight')
88 | # plt.show()
89 |
--------------------------------------------------------------------------------
/src/eval/Time-Path_Segments/Time-Segments_BT.py:
--------------------------------------------------------------------------------
1 | import matplotlib.pyplot as plt
2 | import warnings
3 | import matplotlib
4 | import numpy as np
5 | import json
6 | from math import sqrt
7 |
8 | fsize =25
9 | lw=2
10 | ms = 6
11 | mes = 1
12 | lw=2
13 |
14 |
15 |
16 |
17 | model = ['2', '3', '4', '5', '6']
18 | x = [2,3,4,5,6]
19 |
20 |
21 |
22 |
23 |
24 | # 2.585120415687561, 9.731816864013672, 16.573393726348876, 29.22371470928192, 56.68120107650757,
25 | # 0.005196774484805836, 0.23781882269492483, 0.9169319803730787, 2.6102297522511937, 0.5890758830975283,
26 | # 26512, 26512, 26512,26512,26512
27 |
28 | time = [2.585120415687561, 9.731816864013672, 16.573393726348876, 29.22371470928192, 56.68120107650757]
29 |
30 | var = [0.005196774484805836, 0.23781882269492483, 0.9169319803730787, 2.6102297522511937, 0.5890758830975283]
31 |
32 |
33 | path = [26512, 26512, 26512,26512,26512]
34 |
35 | fig, ax1 = plt.subplots(figsize=(5, 3))
36 | ax2 = ax1.twinx()
37 | plt.rcParams['pdf.fonttype'] = 42
38 | plt.rcParams['ps.fonttype'] = 42
39 | # plt.rcParams['font.sans-serif'] = 'Times New Roman'
40 | # plt.rcParams['mathtext.fontset']= 'custom'
41 | width = 0.26
42 | # cm stic stixsans custom
43 | x_n = [i-0*width for i in x]
44 | ax1.bar(x_n,time ,width=width, label='Time (s)', color="lightskyblue" ,linewidth = 1,edgecolor = 'black' ,yerr=var, error_kw=dict(lw=1, capsize=2.5, capthick=1))
45 |
46 |
47 |
48 | l1 = ax2.plot(x, path, '--', label='Paths', marker = 's', ms=ms, markeredgecolor='black', markeredgewidth=mes, color="#ff7f0e",linewidth = lw)
49 |
50 |
51 |
52 |
53 | fsize+=2
54 | plt.xlabel('Model', fontsize=fsize+1)
55 | ax1.set_xticks(x)
56 | ax1.set_xticklabels(labels=model,rotation=-0, fontsize=fsize+1)
57 | ax1.set_xlabel('Num of Segments', fontsize=fsize+1)
58 |
59 | ax1.set_yscale('log')
60 | ax1.set_ylabel('Time (s)', fontsize=fsize+1)
61 | ax1.set_yticks([10**-2,10**-1,10**-0,10**1])
62 | ax1.set_yticklabels(labels=['10$^{-2}$','10$^{-1}$','10$^{-0}$','10$^{+1}$'], fontsize=fsize+1)
63 | ax1.set_ylim(10**-3,10**2)
64 |
65 |
66 | ax2.set_ylabel('Paths', fontsize=fsize+1)
67 | ax2.set_yticks([8000,16000,24000,32000])
68 | ax2.set_yticklabels(labels=['8k','16k','24k','32k'], fontsize=fsize+1)
69 | ax2.set_ylim(0,40000)
70 |
71 |
72 | plt.xlim(1.3,6.7)
73 |
74 |
75 | lines, labels = ax1.get_legend_handles_labels()
76 | lines2, labels2 = ax2.get_legend_handles_labels()
77 | f_line = lines + lines2
78 | # f_line[1] = lines[0]
79 | # f_line[0] = lines2[0]
80 | # f_line[3] = lines[1]
81 | # f_line[2] = lines2[1]
82 | f_lable = labels + labels2
83 | # f_lable[1] = labels[0]
84 | # f_lable[0] = labels2[0]
85 | # f_lable[3] = labels[1]
86 | # f_lable[2] = labels2[1]
87 | ax2.legend(f_line, f_lable, fancybox=True, fontsize=fsize-8,loc = "upper left", ncol=1)
88 |
89 | plt.grid(which ='major',linestyle= ':') #'major', 'minor' , 'both'
90 | plt.savefig('../figures/Time_Segments_BT.pdf',dpi=600,format='pdf', bbox_inches='tight')
91 | # plt.show()
92 |
--------------------------------------------------------------------------------
/src/eval/Time-Path_Segments/Time-Segments_Clos.py:
--------------------------------------------------------------------------------
1 | import matplotlib.pyplot as plt
2 | import warnings
3 | import matplotlib
4 | import numpy as np
5 | import json
6 | from math import sqrt
7 |
8 | fsize =25
9 | lw=2
10 | ms = 6
11 | mes = 1
12 | lw=2
13 |
14 |
15 |
16 |
17 | model = ['2', '3', '4', '5', '6']
18 | x = [2,3,4,5,6]
19 |
20 |
21 |
22 |
23 |
24 | # 2.585120415687561, 9.731816864013672, 16.573393726348876, 29.22371470928192, 56.68120107650757,
25 | # 0.005196774484805836, 0.23781882269492483, 0.9169319803730787, 2.6102297522511937, 0.5890758830975283,
26 | # 26512, 26512, 26512,26512,26512
27 |
28 | time = [0.018982672691345216, 0.03157079219818115, 0.056016731262207034, 0.6151327133178711, 0.46450252532958985]
29 |
30 | var = [0.002364916477176542, 0.00048190334584875144, 0.00046240761646514295, 0.0022740877306276484, 0.00422413055839856]
31 |
32 |
33 | path = [432,432,432,432,432]
34 |
35 | fig, ax1 = plt.subplots(figsize=(5, 3))
36 | ax2 = ax1.twinx()
37 | # plt.rcParams['font.sans-serif'] = 'Times New Roman'
38 | # plt.rcParams['mathtext.fontset']= 'custom'
39 | plt.rcParams['pdf.fonttype'] = 42
40 | plt.rcParams['ps.fonttype'] = 42
41 | width = 0.26
42 | # cm stic stixsans custom
43 | x_n = [i-0*width for i in x]
44 | ax1.bar(x_n,time ,width=width, label='Time (s)', color="lightskyblue" ,linewidth = 1,edgecolor = 'black' ,yerr=var, error_kw=dict(lw=1, capsize=2.5, capthick=1))
45 |
46 |
47 |
48 | l1 = ax2.plot(x, path, '--', label='Paths', marker = 's', ms=ms, markeredgecolor='black', markeredgewidth=mes, color="#ff7f0e",linewidth = lw)
49 |
50 |
51 |
52 |
53 | fsize+=2
54 | plt.xlabel('Model', fontsize=fsize+1)
55 | ax1.set_xticks(x)
56 | ax1.set_xticklabels(labels=model,rotation=-0, fontsize=fsize+1)
57 | ax1.set_xlabel('Num of Segments', fontsize=fsize+1)
58 |
59 | ax1.set_yscale('log')
60 | ax1.set_ylabel('Time (s)', fontsize=fsize+1)
61 | ax1.set_yticks([10**-2,10**-1,10**-0,10**1])
62 | ax1.set_yticklabels(labels=['10$^{-2}$','10$^{-1}$','10$^{-0}$','10$^{+1}$'], fontsize=fsize+1)
63 | ax1.set_ylim(10**-3,10**2)
64 |
65 |
66 | ax2.set_ylabel('Paths', fontsize=fsize+1)
67 | ax2.set_yticks([8000,16000,24000,32000])
68 | ax2.set_yticklabels(labels=['8k','16k','24k','32k'], fontsize=fsize+1)
69 | ax2.set_ylim(0,40000)
70 |
71 |
72 | plt.xlim(1.3,6.7)
73 |
74 |
75 | lines, labels = ax1.get_legend_handles_labels()
76 | lines2, labels2 = ax2.get_legend_handles_labels()
77 | f_line = lines + lines2
78 | # f_line[1] = lines[0]
79 | # f_line[0] = lines2[0]
80 | # f_line[3] = lines[1]
81 | # f_line[2] = lines2[1]
82 | f_lable = labels + labels2
83 | # f_lable[1] = labels[0]
84 | # f_lable[0] = labels2[0]
85 | # f_lable[3] = labels[1]
86 | # f_lable[2] = labels2[1]
87 | ax2.legend(f_line, f_lable, fancybox=True, fontsize=fsize-8,loc = "upper left", ncol=1)
88 |
89 | plt.grid(which ='major',linestyle= ':') #'major', 'minor' , 'both'
90 | plt.savefig('../figures/Time_Segments_clos.pdf',dpi=600,format='pdf', bbox_inches='tight')
91 | # plt.show()
92 |
--------------------------------------------------------------------------------
/src/eval/Time-Path_Segments/Time-Tier1_BT.py:
--------------------------------------------------------------------------------
1 | import matplotlib.pyplot as plt
2 | import warnings
3 | import matplotlib
4 | import numpy as np
5 | import json
6 | from math import sqrt
7 |
8 | fsize =25
9 | lw=2
10 | ms = 6
11 | mes = 1
12 | lw=2
13 |
14 |
15 |
16 |
17 | model = ['1', '2', '3', '4', '5']
18 | x = [1,2,3,4,5]
19 |
20 | # 0.10952112674713135, 0.12678711414337157, 0.13884289264678956, 0.16474764347076415, 0.17274291515350343]
21 | # 0.0032471952915711067, 0.0006922912296972685, 0.001049483076647019, 0.004338363073341647, 0.0010001896391073721]
22 | # 36,72,108,140,172
23 |
24 |
25 | time = [0.10952112674713135, 0.12678711414337157, 0.13884289264678956, 0.16474764347076415, 0.17274291515350343]
26 |
27 | var = [0.0032471952915711067, 0.0006922912296972685, 0.001049483076647019, 0.004338363073341647, 0.0010001896391073721]
28 |
29 |
30 | path = [36,72,108,140,172]
31 |
32 | fig, ax1 = plt.subplots(figsize=(5, 3))
33 | ax2 = ax1.twinx()
34 | # plt.rcParams['font.sans-serif'] = 'Times New Roman'
35 | # plt.rcParams['mathtext.fontset']= 'custom'
36 | plt.rcParams['pdf.fonttype'] = 42
37 | plt.rcParams['ps.fonttype'] = 42
38 | width = 0.26
39 | # cm stic stixsans custom
40 | x_n = [i-0*width for i in x]
41 | ax1.bar(x_n,time ,width=width, label='Time (s)', color="lightskyblue" ,linewidth = 1,edgecolor = 'black' ,yerr=var, error_kw=dict(lw=1, capsize=2.5, capthick=1))
42 |
43 |
44 |
45 | l1 = ax2.plot(x, path, '--', label='Paths', marker = 's', ms=ms, markeredgecolor='black', markeredgewidth=mes, color="#ff7f0e",linewidth = lw)
46 |
47 |
48 |
49 |
50 | fsize+=2
51 | plt.xlabel('Model', fontsize=fsize+1)
52 | ax1.set_xticks(x)
53 | ax1.set_xticklabels(labels=model,rotation=-0, fontsize=fsize+1)
54 | ax1.set_xlabel('Num of Tier 1 Nodes', fontsize=fsize+1)
55 |
56 | ax1.set_yscale('log')
57 | ax1.set_ylabel('Time (s)', fontsize=fsize+1)
58 | ax1.set_yticks([10**-3,10**-2,10**-1,10**0])
59 | ax1.set_yticklabels(labels=['10$^{-3}$','10$^{-2}$','10$^{-1}$','10$^{-0}$'], fontsize=fsize+1)
60 | ax1.set_ylim(10**-4,10**1)
61 |
62 |
63 | ax2.set_ylabel('Paths', fontsize=fsize+1)
64 | ax2.set_yticks([50,100,150,200])
65 | ax2.set_yticklabels(labels=['30','50','70','90'], fontsize=fsize+1)
66 | ax2.set_ylim(0,250)
67 |
68 |
69 |
70 | plt.xlim(0.3,5.7)
71 |
72 |
73 | lines, labels = ax1.get_legend_handles_labels()
74 | lines2, labels2 = ax2.get_legend_handles_labels()
75 | f_line = lines + lines2
76 | # f_line[1] = lines[0]
77 | # f_line[0] = lines2[0]
78 | # f_line[3] = lines[1]
79 | # f_line[2] = lines2[1]
80 | f_lable = labels + labels2
81 | # f_lable[1] = labels[0]
82 | # f_lable[0] = labels2[0]
83 | # f_lable[3] = labels[1]
84 | # f_lable[2] = labels2[1]
85 | ax2.legend(f_line, f_lable, fancybox=True, fontsize=fsize-8,loc = "upper left", ncol=1)
86 |
87 | plt.grid(which ='major',linestyle= ':') #'major', 'minor' , 'both'
88 | plt.savefig('../figures/Time-Tier1_BT.pdf',dpi=600,format='pdf', bbox_inches='tight')
89 | # plt.show()
90 |
--------------------------------------------------------------------------------
/src/eval/evaluation.md:
--------------------------------------------------------------------------------
1 | # DINC Supports
2 | 
3 |
4 | ## A Guide to Evaluation Reproduction.
5 |
6 | All figures (Figure 12-
7 | 17 and Table 3) can be generated by the Python files in ```./src/eva/*/*.py```, where the raw experiment data is hardcoded directly. All data can be generated by DINC, with detailed instructions available in ```./README.md```. A detailed explanation of the DINC's configuration for each experiment is provided below, aiding in the replication of the results used in the figures and tables.
8 |
9 | There are two options to reproduce the evaluation, use the predefined configuration file or manually input all the configurations:
10 |
11 | ### Option I. Utilise The Predefined Configuration File (without -m).
12 | Some of the already filled configuration files are under ```./src/eva/Configurations/``` (e.g., ```Table3_RF_DINC_config.json```), please use them to replace ```./src/configs/DINC_config.json```. Before running the framework, change the ```work``` under ```directory config``` in the JSON file. After preparing, activate the DINC framework by using ```python3 DINC.py``` directly. Please note that ```-m``` is not needed if you use the predefined configurations.
13 |
14 |
15 | ### Option II. Manually Input Configuration by Using DINC CLI (with -m)
16 | **Important Configurations:** For most of unmentioned configurations, please use the default option.
17 |
18 | * **Topology**: Please use ```BT-ASP``` and ```Folded-Clos-ASP``` for evaluation. When slecting BT topology, please select ```False``` in _display plot_. When select Clos topology, apply switch number```3```, ```6```, and ```24``` in each layer.
19 | * **Planner**: Please use ```ILP``` and ```Type_1```.
20 | * **Input & Output Device List**: For the BT topology, please follows the guide from the CLI. For the Folded Clos topology (as shown in the Figure (a) and (b) below), _all C_ means ```[0,1,2]``` and _all E_ meanse ```[9,10,...,32]```. For the case of _any C_ or _E_, random slect one from previous list repectively. The input device list refers to nodes that have packets come in and the output device list shows packet egress nodes in the topology.
21 | * **Resources should be considered? (stage/memory?)**: Please use the default number from the framework.
22 | * **Result**: Choose ```True``` in _test ILP_ to display results.
23 | * **Example Algorithms**: Example algorithms are provided under ```./src/sample/*/*.p4```. All these algorithms are annotated with basic manually added markers. Beyond the generation of deployment strategy, to ensure the distributed in-network computing program works, for most of the provided example p4 programs, more comprehensive annotations should be added, and the generated program should be manually debugged.
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/src/eval/figures/BT-UK-topo-nouk_v2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/In-Network-Machine-Learning/DINC/9f0b89dd239a097954fb0d302c45be23f7b53ad2/src/eval/figures/BT-UK-topo-nouk_v2.png
--------------------------------------------------------------------------------
/src/eval/figures/Coefficent-hops_BT.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/In-Network-Machine-Learning/DINC/9f0b89dd239a097954fb0d302c45be23f7b53ad2/src/eval/figures/Coefficent-hops_BT.pdf
--------------------------------------------------------------------------------
/src/eval/figures/Coefficent-hops_Clos.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/In-Network-Machine-Learning/DINC/9f0b89dd239a097954fb0d302c45be23f7b53ad2/src/eval/figures/Coefficent-hops_Clos.pdf
--------------------------------------------------------------------------------
/src/eval/figures/DINC_Flightplan_Dup.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/In-Network-Machine-Learning/DINC/9f0b89dd239a097954fb0d302c45be23f7b53ad2/src/eval/figures/DINC_Flightplan_Dup.pdf
--------------------------------------------------------------------------------
/src/eval/figures/DINC_Flightplan_Hop.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/In-Network-Machine-Learning/DINC/9f0b89dd239a097954fb0d302c45be23f7b53ad2/src/eval/figures/DINC_Flightplan_Hop.pdf
--------------------------------------------------------------------------------
/src/eval/figures/DINC_Flightplan_Node.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/In-Network-Machine-Learning/DINC/9f0b89dd239a097954fb0d302c45be23f7b53ad2/src/eval/figures/DINC_Flightplan_Node.pdf
--------------------------------------------------------------------------------
/src/eval/figures/Segment-Latency.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/In-Network-Machine-Learning/DINC/9f0b89dd239a097954fb0d302c45be23f7b53ad2/src/eval/figures/Segment-Latency.pdf
--------------------------------------------------------------------------------
/src/eval/figures/Segment-Throughput.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/In-Network-Machine-Learning/DINC/9f0b89dd239a097954fb0d302c45be23f7b53ad2/src/eval/figures/Segment-Throughput.pdf
--------------------------------------------------------------------------------
/src/eval/figures/Setup-Hops_BT.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/In-Network-Machine-Learning/DINC/9f0b89dd239a097954fb0d302c45be23f7b53ad2/src/eval/figures/Setup-Hops_BT.pdf
--------------------------------------------------------------------------------
/src/eval/figures/Setup-Hops_Clos.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/In-Network-Machine-Learning/DINC/9f0b89dd239a097954fb0d302c45be23f7b53ad2/src/eval/figures/Setup-Hops_Clos.pdf
--------------------------------------------------------------------------------
/src/eval/figures/Setups_label.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/In-Network-Machine-Learning/DINC/9f0b89dd239a097954fb0d302c45be23f7b53ad2/src/eval/figures/Setups_label.pdf
--------------------------------------------------------------------------------
/src/eval/figures/Split_mem.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/In-Network-Machine-Learning/DINC/9f0b89dd239a097954fb0d302c45be23f7b53ad2/src/eval/figures/Split_mem.pdf
--------------------------------------------------------------------------------
/src/eval/figures/Split_stage.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/In-Network-Machine-Learning/DINC/9f0b89dd239a097954fb0d302c45be23f7b53ad2/src/eval/figures/Split_stage.pdf
--------------------------------------------------------------------------------
/src/eval/figures/Split_stage_with_switch_p4.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/In-Network-Machine-Learning/DINC/9f0b89dd239a097954fb0d302c45be23f7b53ad2/src/eval/figures/Split_stage_with_switch_p4.pdf
--------------------------------------------------------------------------------
/src/eval/figures/Time-Edge_clos.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/In-Network-Machine-Learning/DINC/9f0b89dd239a097954fb0d302c45be23f7b53ad2/src/eval/figures/Time-Edge_clos.pdf
--------------------------------------------------------------------------------
/src/eval/figures/Time-Segment_Fat-Tree.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/In-Network-Machine-Learning/DINC/9f0b89dd239a097954fb0d302c45be23f7b53ad2/src/eval/figures/Time-Segment_Fat-Tree.pdf
--------------------------------------------------------------------------------
/src/eval/figures/Time-Tier1_BT.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/In-Network-Machine-Learning/DINC/9f0b89dd239a097954fb0d302c45be23f7b53ad2/src/eval/figures/Time-Tier1_BT.pdf
--------------------------------------------------------------------------------
/src/eval/figures/Time_Segments_BT.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/In-Network-Machine-Learning/DINC/9f0b89dd239a097954fb0d302c45be23f7b53ad2/src/eval/figures/Time_Segments_BT.pdf
--------------------------------------------------------------------------------
/src/eval/figures/Time_Segments_clos.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/In-Network-Machine-Learning/DINC/9f0b89dd239a097954fb0d302c45be23f7b53ad2/src/eval/figures/Time_Segments_clos.pdf
--------------------------------------------------------------------------------
/src/eval/figures/ml_scaling.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/In-Network-Machine-Learning/DINC/9f0b89dd239a097954fb0d302c45be23f7b53ad2/src/eval/figures/ml_scaling.pdf
--------------------------------------------------------------------------------
/src/eval/figures/rare_heatmap_v3.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/In-Network-Machine-Learning/DINC/9f0b89dd239a097954fb0d302c45be23f7b53ad2/src/eval/figures/rare_heatmap_v3.pdf
--------------------------------------------------------------------------------
/src/functions/add_license.py:
--------------------------------------------------------------------------------
1 | def add_license(fname, first_line = True):
2 | if first_line:
3 | operation = 'w'
4 | else:
5 | operation = 'a'
6 | with open(fname, operation) as file:
7 | file.write("########################################################################\n"
8 | "# This program is a free software tool, which does ensemble in-network machine learning.\n"
9 | "# licensed under Apache-2.0\n"
10 | "#\n"
11 | "# Copyright (c) 2020-2021 Changgang Zheng\n"
12 | "# Copyright (c) Computing Infrastructure Group, Department of Engineering Science, University of Oxford & YINS, Yale University\n"
13 | "# E-mail: changgang.zheng@eng.ox.ac.uk (valid until July 2024),\n"
14 | "# changgang.zheng@yale.edu (valid until October 2022) or changgangzheng@qq.com (no expiration date)\n"
15 | "#########################################################################\n"
16 | "# This file was autogenerated\n\n"
17 | )
--------------------------------------------------------------------------------
/src/functions/cmd_related.py:
--------------------------------------------------------------------------------
1 | # This file is part of the Planter extend project: DINC.
2 | # This program is a free software tool, which does ensemble in-network machine learning.
3 | # licensed under Apache-2.0
4 | #
5 | # Copyright (c) 2020-2021 Changgang Zheng
6 | # Copyright (c) Computing Infrastructure Group, Department of Engineering Science, University of Oxford & Yale University
7 | # E-mail: changgang.zheng@eng.ox.ac.uk (valid until July 2024),
8 | # changgang.zheng@yale.edu (valid until October 2022) or changgangzheng@qq.com (no expiration date)
9 | import json
10 | import os
11 | import time
12 | import subprocess as sub
13 |
14 | def run_command(command, root):
15 | sub.run(command, cwd = root)
16 |
17 | def print_log_file(file_name):
18 | while True:
19 | if os.path.exists(file_name):
20 | time.sleep(1)
21 | break
22 | with open(file_name, 'r') as file:
23 | for i, line in enumerate(file.readlines()):
24 | print(line, end="")
--------------------------------------------------------------------------------
/src/functions/config_modification.py:
--------------------------------------------------------------------------------
1 | # This file is part of the Planter extend project: DINC.
2 | # This program is a free software tool, which does ensemble in-network machine learning.
3 | # licensed under Apache-2.0
4 | #
5 | # Copyright (c) 2020-2021 Changgang Zheng
6 | # Copyright (c) Computing Infrastructure Group, Department of Engineering Science, University of Oxford & Yale University
7 | # E-mail: changgang.zheng@eng.ox.ac.uk (valid until July 2024),
8 | # changgang.zheng@yale.edu (valid until October 2022) or changgangzheng@qq.com (no expiration date)
9 |
10 | import os
11 | import json
12 | from src.functions.json_encoder import *
13 |
14 | def reload_DINC_config(config_file_dir):
15 | if os.path.exists(config_file_dir):
16 | DINC_config = json.load(open(config_file_dir, 'r'))
17 | else:
18 | DINC_config = {}
19 | return DINC_config
20 |
21 |
22 | def dump_DINC_config(DINC_config, config_file_dir, print_log = False):
23 | json.dump(DINC_config, open(config_file_dir, 'w'), indent=4, cls=NpEncoder)
24 | if print_log:
25 | print('Dump the targets info to '+config_file_dir)
--------------------------------------------------------------------------------
/src/functions/directory_management.py:
--------------------------------------------------------------------------------
1 | # This file is part of the Planter project.
2 | # This program is a free software tool, which does ensemble in-network machine learning.
3 | # licensed under Apache-2.0
4 | #
5 | # Copyright (c) 2020-2021 Changgang Zheng
6 | # Copyright (c) Computing Infrastructure Group, Department of Engineering Science, University of Oxford
7 | # E-mail: changgang.zheng@eng.ox.ac.uk (valid until July 2024),
8 | # changgang.zheng@yale.edu (valid until October 2022) or changgangzheng@qq.com (no expiration date)
9 |
10 | import os
11 |
12 | def find_folder_options(f):
13 | fs = os.listdir(f)
14 | print(" What option is available: ",end="")
15 | first = True
16 | for f1 in fs:
17 | tmp_path = os.path.join(f, f1)
18 | if os.path.isdir(tmp_path):
19 | if "__" not in f1:
20 | if first:
21 | print(f1,end="")
22 | first=False
23 | else:
24 | print(", "+f1,end="")
25 | print(".")
26 |
27 |
28 | def find_file_options(f):
29 | fs = os.listdir(f)
30 | print(" What option is available: ",end="")
31 | first = True
32 | for f1 in fs:
33 | tmp_path = os.path.join(f, f1)
34 | if not os.path.isdir(tmp_path):
35 | if first:
36 | print(f1,end="")
37 | first=False
38 | else:
39 | print(", "+f1,end="")
40 | print(" ")
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/src/functions/figure_to_ASCII.py:
--------------------------------------------------------------------------------
1 | def print_logo():
2 | print("\n ,---, ,---, ,--.'| ,----.. \n"
3 | " .' .' `\ ,`--.' | ,--,: : | / / \\ \n"
4 | ",---.' \ | : : ,`--.'`| ' : | : : \n"
5 | "| | .`\ | : | ' | : : | | . | ;. / \n"
6 | ": : | ' | | : | : | \ | : . ; /--` \n"
7 | "| ' ' ; : ' ' ; | : ' '; | ; | ; \n"
8 | "' | ; . | | | | ' ' ;. ; | : | \n"
9 | "| | : | ' ' : ; | | | \ | . | '___ \n"
10 | "' : | / ; | | ' ' : | ; .' ' ; : .'| \n"
11 | "| | '` ,/ ' : | | | '`--' ' | '/ : \n"
12 | "; : .' ; |.' ' : | | : / \n"
13 | "| ,.' '---' ; |.' \ \ .' \n"
14 | "'---' '---' `---` DINC version 0 \n")
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/src/functions/input_CLI.py:
--------------------------------------------------------------------------------
1 | # This file is part of the Planter extend project: DINC.
2 | # This program is a free software tool, which does ensemble in-network machine learning.
3 | # licensed under Apache-2.0
4 | #
5 | # Copyright (c) 2020-2021 Changgang Zheng
6 | # Copyright (c) Computing Infrastructure Group, Department of Engineering Science, University of Oxford & Yale University
7 | # E-mail: changgang.zheng@eng.ox.ac.uk (valid until July 2024),
8 | # changgang.zheng@yale.edu (valid until October 2022) or changgangzheng@qq.com (no expiration date)
9 |
10 | import os
11 | import copy
12 | import numpy as np
13 | from src.functions.directory_management import *
14 |
15 | def CLI_loop(question, default, check_dir_existance, check_available_options, option_address):
16 | while True:
17 | if check_available_options:
18 | CLI_input = input('+ ' + question + ' (default = ' + str(default) + ' | options = -h) ') or default
19 | else:
20 | CLI_input = input('+ ' + question + ' (default = ' + str(default) + ') ') or default
21 | if check_dir_existance:
22 | if not check_available_options:
23 | if not os.path.exists(CLI_input):
24 | print(' Warning! The input does not exist, please input again.')
25 | else:
26 | break
27 | else:
28 | input_dir = os.getcwd() + option_address + '/' + CLI_input
29 | if not os.path.exists(input_dir):
30 | if CLI_input != "-h":
31 | print(' Warning! The input: ' + CLI_input + ' does not available, please input again.')
32 | find_folder_options(os.getcwd() + option_address)
33 | else:
34 | break
35 | else:
36 | break
37 | return CLI_input
38 |
39 |
40 | def take_CLI_input(DINC_config, config_type, config_name, question, default, manully_input, check_dir_existance = False, check_available_options = False, option_address = '', numeric = False):
41 | if not manully_input:
42 | try:
43 | CLI_input = DINC_config[config_type][config_name]
44 | print('= Config type: \''+config_type+'\' config name: \''+config_name+'\' is auto filled with: ' + str(CLI_input))
45 | except Exception as e:
46 | try:
47 | _ = DINC_config[config_type]
48 | except Exception as e:
49 | DINC_config[config_type] = {}
50 | CLI_input = CLI_loop(question, default, check_dir_existance, check_available_options, option_address)
51 | else:
52 | try:
53 | _ = DINC_config[config_type]
54 | except Exception as e:
55 | DINC_config[config_type] = {}
56 | CLI_input = CLI_loop(question, default, check_dir_existance, check_available_options, option_address)
57 | if numeric:
58 | CLI_input = int(CLI_input)
59 | DINC_config[config_type][config_name] = CLI_input
60 | return DINC_config
61 |
62 |
63 | def try_convert_str_input_to_int(input):
64 | if input.isdigit():
65 | return copy.deepcopy(int(input))
66 | return copy.deepcopy(input)
67 |
68 | def str_to_array(input, margine = 1, marker = ','):
69 | if type(input) == str:
70 | if margine != 0:
71 | input = input[margine:-margine].split(marker)
72 | else:
73 | input = input.split(marker)
74 | for i, content in enumerate(input):
75 | input[i] = content.lstrip().rstrip()
76 | if input[i].isdigit():
77 | input[i] = int(input[i])
78 | return copy.deepcopy(input)
--------------------------------------------------------------------------------
/src/functions/json_encoder.py:
--------------------------------------------------------------------------------
1 | import json
2 | import numpy as np
3 |
4 | class NpEncoder(json.JSONEncoder):
5 | def default(self, obj):
6 | if isinstance(obj, np.integer):
7 | return int(obj)
8 | if isinstance(obj, np.floating):
9 | return float(obj)
10 | if isinstance(obj, np.ndarray):
11 | return obj.tolist()
12 | return super(NpEncoder, self).default(obj)
--------------------------------------------------------------------------------
/src/functions/write_file.py:
--------------------------------------------------------------------------------
1 | # This file is part of the Planter project.
2 | # This program is a free software tool, which does ensemble in-network machine learning.
3 | # licensed under Apache-2.0
4 | #
5 | # Copyright (c) 2020-2021 Changgang Zheng
6 | # Copyright (c) Computing Infrastructure Group, Department of Engineering Science, University of Oxford
7 | # E-mail: changgang.zheng@eng.ox.ac.uk (valid until July 2024),
8 | # changgang.zheng@yale.edu (valid until October 2022) or changgangzheng@qq.com (no expiration date)
9 |
10 | import os
11 | import glob
12 | from src.functions.add_license import *
13 |
14 | def open_new_file(fname):
15 | with open(fname, 'w') as file:
16 | file.write("")
17 |
18 | def write_line(line, file_name, first_line_of_file = False, add_license_txt = False):
19 | if first_line_of_file:
20 | open_new_file(file_name)
21 | if add_license_txt:
22 | add_license(file_name, first_line = first_line_of_file)
23 | with open(file_name, 'a') as file:
24 | file.write(line)
25 |
26 | def clean_dir(dir, type = '.p4'):
27 | files = glob.glob(dir+'/*'+type, recursive=True)
28 | for f in files:
29 | try:
30 | print('- Remove file: '+f)
31 | os.remove(f)
32 | except OSError as e:
33 | print("Error: %s : %s" % (f, e.strerror))
34 |
35 |
36 | def write_p4_file_with_space(p4_file_name, before_p4_leading_space, space_gap, target_file):
37 | with open(p4_file_name, 'r') as file:
38 | First_Line = True
39 | for line_idx, line in enumerate(file.readlines()):
40 | # if 'default_class' in line:
41 | # pass
42 | if First_Line:
43 | p4_leading_space = len(line) - len(line.lstrip(' '))
44 | extra_space = space_gap + before_p4_leading_space - p4_leading_space
45 | if len(set(line)) > 1:
46 | First_Line = False
47 | # if extra_space == 4:
48 | # pass
49 |
50 | # print(extra_space, space_gap, before_p4_leading_space, p4_leading_space)
51 | # print(line)
52 | if extra_space < 0:
53 | target_file.write(line[abs(extra_space):])
54 | else:
55 | target_file.write(extra_space * ' ' + line)
--------------------------------------------------------------------------------
/src/help/DINC_Supports/DINC_Supported_Architectures.md:
--------------------------------------------------------------------------------
1 | # DINC Supports
2 | 
3 |
7 |
8 | ## Supported Architectures
9 | The architectures here are indicative of the architecture used in your p4 file (e.g., ```#include ```). It is located under the ```./src/architectures/``` folder. Recommended architectures are marked with 🔥.
10 |
11 |
12 | **1. TNA 🔥** [Folder](../../architecture/tna) - The Tofino Native Architecture (TNA) [Link](https://github.com/barefootnetworks/Open-Tofino/blob/master/PUBLIC_Tofino-Native-Arch-Document.pdf) is an architecture designed for Intel Tofino harware and emulation targets. One example is the Tofino Switch.
13 |
14 | **2. v1model 🔥** [Folder](../../architecture/v1model) - The v1model [Link](https://sdn.systemsapproach.org/switch.html) was originally designed to support P414 and later to support P416. It is used in BMv2, P4Pi-enabled BMv2, and P4Pi-enabled T4P4S.
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/src/help/DINC_Supports/DINC_Supported_Topologies.md:
--------------------------------------------------------------------------------
1 | # DINC Supports
2 | 
3 |
7 |
8 |
9 | ## Supported Network Topologies
10 |
11 |
14 |
15 | The recommended variation for each model is marked with 🔥.
16 |
17 | **1. Fat Tree Topology**
18 |
19 | - **Fat-Tree [[Folder]](../../topologies/Fat-Tree):** This case using `nx.all_simple_paths()` funtion to find the paths.
20 |
21 | We will mainly shows the piecture of Folded-Clos and BT ISP topology, as shown in the picture below:
22 |
23 |
24 | **2. Folded Clos Topology**
25 |
26 | - **Folded-Clos-All:** All possible none loop paths with out duplication nodes. This case using `nx.all_simple_paths()` funtion to find the paths.
27 | - **Folded-Clos [[Folder]](../../topologies/Folded-Clos) 🔥:** Only sigle direction from device-to-core/core-to-device and avioid valley free routing for device to device case. This case using `nx.all_simple_paths()` funtion to find the paths.
28 | - **Folded-Clos-ASP** Same as Folded-Clos but using `nx.all_shortest_paths()` funtion to find the paths.
29 |
30 | **3. BT Topology**
31 |
32 | - **BT [[Folder]](../../topologies/BT) 🔥:** This case using `nx.all_simple_paths()` funtion to find the paths.
33 | - **BT-ASP** Same as BT but using `nx.all_shortest_paths()` funtion to find the paths.
34 |
35 | We also shows a detailed aerial view of the BT ISP topology.
36 |
37 |
--------------------------------------------------------------------------------
/src/help/DINC_Supports/DINC_Supported_Use_Cases.md:
--------------------------------------------------------------------------------
1 | # DINC Supports
2 | 
3 |
7 |
8 |
9 | ## Supported use cases
10 | DINC currently support three use cases. Hot use cases are marked with 🔥.
11 |
12 | **1. Standard Block 🔥** [Folder](../../use_cases/standard_block) - This use case is for functionality verification. In this case, the switching functionality will be simple ipv4 forwarding table.
13 |
14 | **2. switch.p4** - This use case is for functionality verification. In this case, the distributed segmentations will coexist with an L2/L3 reference designed by Intel Tofino.
15 |
16 | **3. RARE** - This use case is for functionality verification. In this case, the distributed segmentations will coexist with the RARE open-source router [Link](http://docs.freertr.org/).
17 |
--------------------------------------------------------------------------------
/src/help/Zheng_et_al_2023_DINC_toward_distributed.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/In-Network-Machine-Learning/DINC/9f0b89dd239a097954fb0d302c45be23f7b53ad2/src/help/Zheng_et_al_2023_DINC_toward_distributed.pdf
--------------------------------------------------------------------------------
/src/images/BT-UK-topo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/In-Network-Machine-Learning/DINC/9f0b89dd239a097954fb0d302c45be23f7b53ad2/src/images/BT-UK-topo.png
--------------------------------------------------------------------------------
/src/images/DINC_framework.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/In-Network-Machine-Learning/DINC/9f0b89dd239a097954fb0d302c45be23f7b53ad2/src/images/DINC_framework.png
--------------------------------------------------------------------------------
/src/images/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/In-Network-Machine-Learning/DINC/9f0b89dd239a097954fb0d302c45be23f7b53ad2/src/images/logo.png
--------------------------------------------------------------------------------
/src/images/sample_marking.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/In-Network-Machine-Learning/DINC/9f0b89dd239a097954fb0d302c45be23f7b53ad2/src/images/sample_marking.png
--------------------------------------------------------------------------------
/src/images/topos.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/In-Network-Machine-Learning/DINC/9f0b89dd239a097954fb0d302c45be23f7b53ad2/src/images/topos.png
--------------------------------------------------------------------------------
/src/logs/DT_performance_Iris_Fat-Tree_3depth_2branch.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/In-Network-Machine-Learning/DINC/9f0b89dd239a097954fb0d302c45be23f7b53ad2/src/logs/DT_performance_Iris_Fat-Tree_3depth_2branch.pdf
--------------------------------------------------------------------------------
/src/temp/P4/E0_control-apply.p4:
--------------------------------------------------------------------------------
1 | lookup_feature0.apply();
2 | lookup_feature1.apply();
3 |
--------------------------------------------------------------------------------
/src/temp/P4/E0_control.p4:
--------------------------------------------------------------------------------
1 | action extract_feature0(out bit<1> meta_code, bit<1> tree){
2 | meta_code = tree;
3 | }
4 | action extract_feature1(out bit<2> meta_code, bit<2> tree){
5 | meta_code = tree;
6 | }
7 |
8 |
9 |
10 |
11 |
12 | table lookup_feature0 {
13 | key = { meta.feature0:ternary; }
14 | actions = {
15 | extract_feature0(meta.code_f0);
16 | NoAction;
17 | }
18 | size = 8;
19 | default_action = NoAction;
20 | }
21 |
22 | table lookup_feature1 {
23 | key = { meta.feature1:ternary; }
24 | actions = {
25 | extract_feature1(meta.code_f1);
26 | NoAction;
27 | }
28 | size = 7;
29 | default_action = NoAction;
30 | }
31 |
--------------------------------------------------------------------------------
/src/temp/P4/E1_control-apply.p4:
--------------------------------------------------------------------------------
1 | lookup_feature2.apply();
2 | lookup_feature3.apply();
3 |
--------------------------------------------------------------------------------
/src/temp/P4/E1_control.p4:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | action extract_feature2(out bit<3> meta_code, bit<3> tree){
5 | meta_code = tree;
6 | }
7 |
8 | action extract_feature3(out bit<3> meta_code, bit<3> tree){
9 | meta_code = tree;
10 | }
11 |
12 |
13 | table lookup_feature2 {
14 | key = { meta.feature2:ternary; }
15 | actions = {
16 | extract_feature2(meta.code_f2);
17 | NoAction;
18 | }
19 | size = 15;
20 | default_action = NoAction;
21 | }
22 |
23 | table lookup_feature3 {
24 | key = { meta.feature3:ternary; }
25 | actions = {
26 | extract_feature3(meta.code_f3);
27 | NoAction;
28 | }
29 | size = 10;
30 | default_action = NoAction;
31 | }
32 |
33 |
--------------------------------------------------------------------------------
/src/temp/P4/E2_control-apply.p4:
--------------------------------------------------------------------------------
1 | decision.apply();
2 |
--------------------------------------------------------------------------------
/src/temp/P4/E2_control.p4:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | action write_default_class() {
5 | meta.result = 1;
6 | }
7 |
8 | action read_lable(bit<32> label){
9 | meta.result = label;
10 | }
11 |
12 | table decision {
13 | key = { meta.code_f0[0:0]:exact;
14 | meta.code_f1[1:0]:exact;
15 | meta.code_f2[2:0]:exact;
16 | meta.code_f3[2:0]:exact;
17 | }
18 | actions={
19 | read_lable;
20 | write_default_class;
21 | }
22 | size = 13;
23 | default_action = write_default_class;
24 | }
25 |
--------------------------------------------------------------------------------
/src/test/BMv2/test_environment/Makefile:
--------------------------------------------------------------------------------
1 | BMV2_SWITCH_EXE = simple_switch_grpc
2 |
3 |
4 | include ../utils/Makefile
5 |
--------------------------------------------------------------------------------
/src/test/BMv2/test_environment/P4/s10.p4:
--------------------------------------------------------------------------------
1 | ########################################################################
2 | # This program is a free software tool, which does ensemble in-network machine learning.
3 | # licensed under Apache-2.0
4 | #
5 | # Copyright (c) 2020-2021 Changgang Zheng
6 | # Copyright (c) Computing Infrastructure Group, Department of Engineering Science, University of Oxford & YINS, Yale University
7 | # E-mail: changgang.zheng@eng.ox.ac.uk (valid until July 2024),
8 | # changgang.zheng@yale.edu (valid until October 2022) or changgangzheng@qq.com (no expiration date)
9 | #########################################################################
10 | # This file was autogenerated
11 |
12 | #include
13 | #include
14 |
15 | /*************************************************************************
16 | ***************************** constants **********************************
17 | *************************************************************************/
18 |
19 | const bit<16> TYPE_IPV4 = 0x800;
20 |
21 | typedef bit<9> egressSpec_t;
22 | typedef bit<48> macAddr_t;
23 | typedef bit<32> ip4Addr_t;
24 |
25 | /*************************************************************************
26 | ****************************** headers ***********************************
27 | *************************************************************************/
28 |
29 | header ethernet_h {
30 | macAddr_t dstAddr;
31 | macAddr_t srcAddr;
32 | bit<16> etherType;
33 | }
34 |
35 | header ipv4_h{
36 | bit < 4 > version;
37 | bit < 4 > ihl;
38 | bit < 8 > diffserv;
39 | bit < 16 > totalLen;
40 | bit < 16 > identification;
41 | bit < 3 > flags;
42 | bit < 13 > fragOffset;
43 | bit < 8 > ttl;
44 | bit < 8 > protocol;
45 | bit < 16 > hdrChecksum;
46 | ip4Addr_t srcAddr;
47 | ip4Addr_t dstAddr;
48 | }
49 |
50 | struct header_t {
51 | ethernet_h ethernet;
52 | ipv4_h ipv4;
53 | }
54 |
55 | /*************************************************************************
56 | ***************************** metadata **********************************
57 | *************************************************************************/
58 |
59 | struct metadata_t {
60 | }
61 |
62 | /*************************************************************************
63 | *********************** Ingress Parser ***********************************
64 | *************************************************************************/
65 |
66 | parser SwitchParser(
67 | packet_in pkt,
68 | out header_t hdr,
69 | inout metadata_t meta,
70 | inout standard_metadata_t ig_intr_md) {
71 |
72 | state start {
73 | transition parse_ethernet;
74 | }
75 |
76 | state parse_ethernet {
77 | pkt.extract(hdr.ethernet);
78 | transition select(hdr.ethernet.etherType) {
79 | TYPE_IPV4 : parse_ipv4;
80 | default : accept;
81 | }
82 | }
83 |
84 | state parse_ipv4 {
85 | pkt.extract(hdr.ipv4);
86 | transition accept;
87 | }
88 |
89 | }
90 |
91 | /*************************************************************************
92 | *********************** Egress Deparser *********************************
93 | **************************************************************************/
94 |
95 | control SwitchDeparser(
96 | packet_out pkt,
97 | in header_t hdr) {
98 | apply {
99 | pkt.emit(hdr);
100 | }
101 | }
102 |
103 | /*************************************************************************
104 | ********************** Checksum Verification *****************************
105 | *************************************************************************/
106 |
107 | control SwitchVerifyChecksum(inout header_t hdr,
108 | inout metadata_t meta) {
109 | apply {}
110 | }
111 | /*************************************************************************
112 | ********************** Checksum Computation ******************************
113 | *************************************************************************/
114 |
115 | control SwitchComputeChecksum(inout header_t hdr,
116 | inout metadata_t meta) {
117 | apply {
118 | update_checksum(
119 | hdr.ipv4.isValid(),
120 | { hdr.ipv4.version,
121 | hdr.ipv4.ihl,
122 | hdr.ipv4.diffserv,
123 | hdr.ipv4.totalLen,
124 | hdr.ipv4.identification,
125 | hdr.ipv4.flags,
126 | hdr.ipv4.fragOffset,
127 | hdr.ipv4.ttl,
128 | hdr.ipv4.protocol,
129 | hdr.ipv4.srcAddr,
130 | hdr.ipv4.dstAddr },
131 | hdr.ipv4.hdrChecksum,
132 | HashAlgorithm.csum16);
133 | }
134 | }
135 | /*************************************************************************
136 | *********************** Ingress Processing********************************
137 | **************************************************************************/
138 |
139 | control SwitchIngress(
140 | inout header_t hdr,
141 | inout metadata_t meta,
142 | inout standard_metadata_t ig_intr_md) {
143 |
144 | action drop() {
145 | mark_to_drop(ig_intr_md);
146 | }
147 |
148 | action ipv4_forward(macAddr_t dstAddr, egressSpec_t port) {
149 | ig_intr_md.egress_spec = port;
150 | hdr.ethernet.srcAddr = hdr.ethernet.dstAddr;
151 | hdr.ethernet.dstAddr = dstAddr;
152 | hdr.ipv4.ttl = hdr.ipv4.ttl - 1;
153 | }
154 |
155 | table ipv4_lpm {
156 | key = {
157 | hdr.ipv4.dstAddr: lpm;
158 | }
159 | actions = {
160 | ipv4_forward;
161 | drop;
162 | NoAction;
163 | }
164 | size = 1024;
165 | default_action = drop();
166 | }
167 |
168 | apply{
169 | if (hdr.ipv4.isValid() && hdr.ipv4.ttl > 0) {
170 | ipv4_lpm.apply();
171 | }
172 |
173 | }
174 | }
175 | /*************************************************************************
176 | *********************** egress Processing********************************
177 | **************************************************************************/
178 |
179 | control SwitchEgress(inout header_t hdr,
180 | inout metadata_t meta,
181 | inout standard_metadata_t eg_intr_md) {
182 | apply {
183 | }
184 | }
185 | /*************************************************************************
186 | *********************** S W I T C H ************************************
187 | *************************************************************************/
188 |
189 | V1Switch(
190 | SwitchParser(),
191 | SwitchVerifyChecksum(),
192 | SwitchIngress(),
193 | SwitchEgress(),
194 | SwitchComputeChecksum(),
195 | SwitchDeparser()
196 | ) main;
--------------------------------------------------------------------------------
/src/test/BMv2/test_environment/P4/s11.p4:
--------------------------------------------------------------------------------
1 | ########################################################################
2 | # This program is a free software tool, which does ensemble in-network machine learning.
3 | # licensed under Apache-2.0
4 | #
5 | # Copyright (c) 2020-2021 Changgang Zheng
6 | # Copyright (c) Computing Infrastructure Group, Department of Engineering Science, University of Oxford & YINS, Yale University
7 | # E-mail: changgang.zheng@eng.ox.ac.uk (valid until July 2024),
8 | # changgang.zheng@yale.edu (valid until October 2022) or changgangzheng@qq.com (no expiration date)
9 | #########################################################################
10 | # This file was autogenerated
11 |
12 | #include
13 | #include
14 |
15 | /*************************************************************************
16 | ***************************** constants **********************************
17 | *************************************************************************/
18 |
19 | const bit<16> TYPE_IPV4 = 0x800;
20 |
21 | typedef bit<9> egressSpec_t;
22 | typedef bit<48> macAddr_t;
23 | typedef bit<32> ip4Addr_t;
24 |
25 | /*************************************************************************
26 | ****************************** headers ***********************************
27 | *************************************************************************/
28 |
29 | header ethernet_h {
30 | macAddr_t dstAddr;
31 | macAddr_t srcAddr;
32 | bit<16> etherType;
33 | }
34 |
35 | header ipv4_h{
36 | bit < 4 > version;
37 | bit < 4 > ihl;
38 | bit < 8 > diffserv;
39 | bit < 16 > totalLen;
40 | bit < 16 > identification;
41 | bit < 3 > flags;
42 | bit < 13 > fragOffset;
43 | bit < 8 > ttl;
44 | bit < 8 > protocol;
45 | bit < 16 > hdrChecksum;
46 | ip4Addr_t srcAddr;
47 | ip4Addr_t dstAddr;
48 | }
49 |
50 | struct header_t {
51 | ethernet_h ethernet;
52 | ipv4_h ipv4;
53 | }
54 |
55 | /*************************************************************************
56 | ***************************** metadata **********************************
57 | *************************************************************************/
58 |
59 | struct metadata_t {
60 | }
61 |
62 | /*************************************************************************
63 | *********************** Ingress Parser ***********************************
64 | *************************************************************************/
65 |
66 | parser SwitchParser(
67 | packet_in pkt,
68 | out header_t hdr,
69 | inout metadata_t meta,
70 | inout standard_metadata_t ig_intr_md) {
71 |
72 | state start {
73 | transition parse_ethernet;
74 | }
75 |
76 | state parse_ethernet {
77 | pkt.extract(hdr.ethernet);
78 | transition select(hdr.ethernet.etherType) {
79 | TYPE_IPV4 : parse_ipv4;
80 | default : accept;
81 | }
82 | }
83 |
84 | state parse_ipv4 {
85 | pkt.extract(hdr.ipv4);
86 | transition accept;
87 | }
88 |
89 | }
90 |
91 | /*************************************************************************
92 | *********************** Egress Deparser *********************************
93 | **************************************************************************/
94 |
95 | control SwitchDeparser(
96 | packet_out pkt,
97 | in header_t hdr) {
98 | apply {
99 | pkt.emit(hdr);
100 | }
101 | }
102 |
103 | /*************************************************************************
104 | ********************** Checksum Verification *****************************
105 | *************************************************************************/
106 |
107 | control SwitchVerifyChecksum(inout header_t hdr,
108 | inout metadata_t meta) {
109 | apply {}
110 | }
111 | /*************************************************************************
112 | ********************** Checksum Computation ******************************
113 | *************************************************************************/
114 |
115 | control SwitchComputeChecksum(inout header_t hdr,
116 | inout metadata_t meta) {
117 | apply {
118 | update_checksum(
119 | hdr.ipv4.isValid(),
120 | { hdr.ipv4.version,
121 | hdr.ipv4.ihl,
122 | hdr.ipv4.diffserv,
123 | hdr.ipv4.totalLen,
124 | hdr.ipv4.identification,
125 | hdr.ipv4.flags,
126 | hdr.ipv4.fragOffset,
127 | hdr.ipv4.ttl,
128 | hdr.ipv4.protocol,
129 | hdr.ipv4.srcAddr,
130 | hdr.ipv4.dstAddr },
131 | hdr.ipv4.hdrChecksum,
132 | HashAlgorithm.csum16);
133 | }
134 | }
135 | /*************************************************************************
136 | *********************** Ingress Processing********************************
137 | **************************************************************************/
138 |
139 | control SwitchIngress(
140 | inout header_t hdr,
141 | inout metadata_t meta,
142 | inout standard_metadata_t ig_intr_md) {
143 |
144 | action drop() {
145 | mark_to_drop(ig_intr_md);
146 | }
147 |
148 | action ipv4_forward(macAddr_t dstAddr, egressSpec_t port) {
149 | ig_intr_md.egress_spec = port;
150 | hdr.ethernet.srcAddr = hdr.ethernet.dstAddr;
151 | hdr.ethernet.dstAddr = dstAddr;
152 | hdr.ipv4.ttl = hdr.ipv4.ttl - 1;
153 | }
154 |
155 | table ipv4_lpm {
156 | key = {
157 | hdr.ipv4.dstAddr: lpm;
158 | }
159 | actions = {
160 | ipv4_forward;
161 | drop;
162 | NoAction;
163 | }
164 | size = 1024;
165 | default_action = drop();
166 | }
167 |
168 | apply{
169 | if (hdr.ipv4.isValid() && hdr.ipv4.ttl > 0) {
170 | ipv4_lpm.apply();
171 | }
172 |
173 | }
174 | }
175 | /*************************************************************************
176 | *********************** egress Processing********************************
177 | **************************************************************************/
178 |
179 | control SwitchEgress(inout header_t hdr,
180 | inout metadata_t meta,
181 | inout standard_metadata_t eg_intr_md) {
182 | apply {
183 | }
184 | }
185 | /*************************************************************************
186 | *********************** S W I T C H ************************************
187 | *************************************************************************/
188 |
189 | V1Switch(
190 | SwitchParser(),
191 | SwitchVerifyChecksum(),
192 | SwitchIngress(),
193 | SwitchEgress(),
194 | SwitchComputeChecksum(),
195 | SwitchDeparser()
196 | ) main;
--------------------------------------------------------------------------------
/src/test/BMv2/test_environment/P4/s12.p4:
--------------------------------------------------------------------------------
1 | ########################################################################
2 | # This program is a free software tool, which does ensemble in-network machine learning.
3 | # licensed under Apache-2.0
4 | #
5 | # Copyright (c) 2020-2021 Changgang Zheng
6 | # Copyright (c) Computing Infrastructure Group, Department of Engineering Science, University of Oxford & YINS, Yale University
7 | # E-mail: changgang.zheng@eng.ox.ac.uk (valid until July 2024),
8 | # changgang.zheng@yale.edu (valid until October 2022) or changgangzheng@qq.com (no expiration date)
9 | #########################################################################
10 | # This file was autogenerated
11 |
12 | #include
13 | #include
14 |
15 | /*************************************************************************
16 | ***************************** constants **********************************
17 | *************************************************************************/
18 |
19 | const bit<16> TYPE_IPV4 = 0x800;
20 |
21 | typedef bit<9> egressSpec_t;
22 | typedef bit<48> macAddr_t;
23 | typedef bit<32> ip4Addr_t;
24 |
25 | /*************************************************************************
26 | ****************************** headers ***********************************
27 | *************************************************************************/
28 |
29 | header ethernet_h {
30 | macAddr_t dstAddr;
31 | macAddr_t srcAddr;
32 | bit<16> etherType;
33 | }
34 |
35 | header ipv4_h{
36 | bit < 4 > version;
37 | bit < 4 > ihl;
38 | bit < 8 > diffserv;
39 | bit < 16 > totalLen;
40 | bit < 16 > identification;
41 | bit < 3 > flags;
42 | bit < 13 > fragOffset;
43 | bit < 8 > ttl;
44 | bit < 8 > protocol;
45 | bit < 16 > hdrChecksum;
46 | ip4Addr_t srcAddr;
47 | ip4Addr_t dstAddr;
48 | }
49 |
50 | struct header_t {
51 | ethernet_h ethernet;
52 | ipv4_h ipv4;
53 | }
54 |
55 | /*************************************************************************
56 | ***************************** metadata **********************************
57 | *************************************************************************/
58 |
59 | struct metadata_t {
60 | }
61 |
62 | /*************************************************************************
63 | *********************** Ingress Parser ***********************************
64 | *************************************************************************/
65 |
66 | parser SwitchParser(
67 | packet_in pkt,
68 | out header_t hdr,
69 | inout metadata_t meta,
70 | inout standard_metadata_t ig_intr_md) {
71 |
72 | state start {
73 | transition parse_ethernet;
74 | }
75 |
76 | state parse_ethernet {
77 | pkt.extract(hdr.ethernet);
78 | transition select(hdr.ethernet.etherType) {
79 | TYPE_IPV4 : parse_ipv4;
80 | default : accept;
81 | }
82 | }
83 |
84 | state parse_ipv4 {
85 | pkt.extract(hdr.ipv4);
86 | transition accept;
87 | }
88 |
89 | }
90 |
91 | /*************************************************************************
92 | *********************** Egress Deparser *********************************
93 | **************************************************************************/
94 |
95 | control SwitchDeparser(
96 | packet_out pkt,
97 | in header_t hdr) {
98 | apply {
99 | pkt.emit(hdr);
100 | }
101 | }
102 |
103 | /*************************************************************************
104 | ********************** Checksum Verification *****************************
105 | *************************************************************************/
106 |
107 | control SwitchVerifyChecksum(inout header_t hdr,
108 | inout metadata_t meta) {
109 | apply {}
110 | }
111 | /*************************************************************************
112 | ********************** Checksum Computation ******************************
113 | *************************************************************************/
114 |
115 | control SwitchComputeChecksum(inout header_t hdr,
116 | inout metadata_t meta) {
117 | apply {
118 | update_checksum(
119 | hdr.ipv4.isValid(),
120 | { hdr.ipv4.version,
121 | hdr.ipv4.ihl,
122 | hdr.ipv4.diffserv,
123 | hdr.ipv4.totalLen,
124 | hdr.ipv4.identification,
125 | hdr.ipv4.flags,
126 | hdr.ipv4.fragOffset,
127 | hdr.ipv4.ttl,
128 | hdr.ipv4.protocol,
129 | hdr.ipv4.srcAddr,
130 | hdr.ipv4.dstAddr },
131 | hdr.ipv4.hdrChecksum,
132 | HashAlgorithm.csum16);
133 | }
134 | }
135 | /*************************************************************************
136 | *********************** Ingress Processing********************************
137 | **************************************************************************/
138 |
139 | control SwitchIngress(
140 | inout header_t hdr,
141 | inout metadata_t meta,
142 | inout standard_metadata_t ig_intr_md) {
143 |
144 | action drop() {
145 | mark_to_drop(ig_intr_md);
146 | }
147 |
148 | action ipv4_forward(macAddr_t dstAddr, egressSpec_t port) {
149 | ig_intr_md.egress_spec = port;
150 | hdr.ethernet.srcAddr = hdr.ethernet.dstAddr;
151 | hdr.ethernet.dstAddr = dstAddr;
152 | hdr.ipv4.ttl = hdr.ipv4.ttl - 1;
153 | }
154 |
155 | table ipv4_lpm {
156 | key = {
157 | hdr.ipv4.dstAddr: lpm;
158 | }
159 | actions = {
160 | ipv4_forward;
161 | drop;
162 | NoAction;
163 | }
164 | size = 1024;
165 | default_action = drop();
166 | }
167 |
168 | apply{
169 | if (hdr.ipv4.isValid() && hdr.ipv4.ttl > 0) {
170 | ipv4_lpm.apply();
171 | }
172 |
173 | }
174 | }
175 | /*************************************************************************
176 | *********************** egress Processing********************************
177 | **************************************************************************/
178 |
179 | control SwitchEgress(inout header_t hdr,
180 | inout metadata_t meta,
181 | inout standard_metadata_t eg_intr_md) {
182 | apply {
183 | }
184 | }
185 | /*************************************************************************
186 | *********************** S W I T C H ************************************
187 | *************************************************************************/
188 |
189 | V1Switch(
190 | SwitchParser(),
191 | SwitchVerifyChecksum(),
192 | SwitchIngress(),
193 | SwitchEgress(),
194 | SwitchComputeChecksum(),
195 | SwitchDeparser()
196 | ) main;
--------------------------------------------------------------------------------
/src/test/BMv2/test_environment/P4/s13.p4:
--------------------------------------------------------------------------------
1 | ########################################################################
2 | # This program is a free software tool, which does ensemble in-network machine learning.
3 | # licensed under Apache-2.0
4 | #
5 | # Copyright (c) 2020-2021 Changgang Zheng
6 | # Copyright (c) Computing Infrastructure Group, Department of Engineering Science, University of Oxford & YINS, Yale University
7 | # E-mail: changgang.zheng@eng.ox.ac.uk (valid until July 2024),
8 | # changgang.zheng@yale.edu (valid until October 2022) or changgangzheng@qq.com (no expiration date)
9 | #########################################################################
10 | # This file was autogenerated
11 |
12 | #include
13 | #include
14 |
15 | /*************************************************************************
16 | ***************************** constants **********************************
17 | *************************************************************************/
18 |
19 | const bit<16> TYPE_IPV4 = 0x800;
20 |
21 | typedef bit<9> egressSpec_t;
22 | typedef bit<48> macAddr_t;
23 | typedef bit<32> ip4Addr_t;
24 |
25 | /*************************************************************************
26 | ****************************** headers ***********************************
27 | *************************************************************************/
28 |
29 | header ethernet_h {
30 | macAddr_t dstAddr;
31 | macAddr_t srcAddr;
32 | bit<16> etherType;
33 | }
34 |
35 | header ipv4_h{
36 | bit < 4 > version;
37 | bit < 4 > ihl;
38 | bit < 8 > diffserv;
39 | bit < 16 > totalLen;
40 | bit < 16 > identification;
41 | bit < 3 > flags;
42 | bit < 13 > fragOffset;
43 | bit < 8 > ttl;
44 | bit < 8 > protocol;
45 | bit < 16 > hdrChecksum;
46 | ip4Addr_t srcAddr;
47 | ip4Addr_t dstAddr;
48 | }
49 |
50 | struct header_t {
51 | ethernet_h ethernet;
52 | ipv4_h ipv4;
53 | }
54 |
55 | /*************************************************************************
56 | ***************************** metadata **********************************
57 | *************************************************************************/
58 |
59 | struct metadata_t {
60 | }
61 |
62 | /*************************************************************************
63 | *********************** Ingress Parser ***********************************
64 | *************************************************************************/
65 |
66 | parser SwitchParser(
67 | packet_in pkt,
68 | out header_t hdr,
69 | inout metadata_t meta,
70 | inout standard_metadata_t ig_intr_md) {
71 |
72 | state start {
73 | transition parse_ethernet;
74 | }
75 |
76 | state parse_ethernet {
77 | pkt.extract(hdr.ethernet);
78 | transition select(hdr.ethernet.etherType) {
79 | TYPE_IPV4 : parse_ipv4;
80 | default : accept;
81 | }
82 | }
83 |
84 | state parse_ipv4 {
85 | pkt.extract(hdr.ipv4);
86 | transition accept;
87 | }
88 |
89 | }
90 |
91 | /*************************************************************************
92 | *********************** Egress Deparser *********************************
93 | **************************************************************************/
94 |
95 | control SwitchDeparser(
96 | packet_out pkt,
97 | in header_t hdr) {
98 | apply {
99 | pkt.emit(hdr);
100 | }
101 | }
102 |
103 | /*************************************************************************
104 | ********************** Checksum Verification *****************************
105 | *************************************************************************/
106 |
107 | control SwitchVerifyChecksum(inout header_t hdr,
108 | inout metadata_t meta) {
109 | apply {}
110 | }
111 | /*************************************************************************
112 | ********************** Checksum Computation ******************************
113 | *************************************************************************/
114 |
115 | control SwitchComputeChecksum(inout header_t hdr,
116 | inout metadata_t meta) {
117 | apply {
118 | update_checksum(
119 | hdr.ipv4.isValid(),
120 | { hdr.ipv4.version,
121 | hdr.ipv4.ihl,
122 | hdr.ipv4.diffserv,
123 | hdr.ipv4.totalLen,
124 | hdr.ipv4.identification,
125 | hdr.ipv4.flags,
126 | hdr.ipv4.fragOffset,
127 | hdr.ipv4.ttl,
128 | hdr.ipv4.protocol,
129 | hdr.ipv4.srcAddr,
130 | hdr.ipv4.dstAddr },
131 | hdr.ipv4.hdrChecksum,
132 | HashAlgorithm.csum16);
133 | }
134 | }
135 | /*************************************************************************
136 | *********************** Ingress Processing********************************
137 | **************************************************************************/
138 |
139 | control SwitchIngress(
140 | inout header_t hdr,
141 | inout metadata_t meta,
142 | inout standard_metadata_t ig_intr_md) {
143 |
144 | action drop() {
145 | mark_to_drop(ig_intr_md);
146 | }
147 |
148 | action ipv4_forward(macAddr_t dstAddr, egressSpec_t port) {
149 | ig_intr_md.egress_spec = port;
150 | hdr.ethernet.srcAddr = hdr.ethernet.dstAddr;
151 | hdr.ethernet.dstAddr = dstAddr;
152 | hdr.ipv4.ttl = hdr.ipv4.ttl - 1;
153 | }
154 |
155 | table ipv4_lpm {
156 | key = {
157 | hdr.ipv4.dstAddr: lpm;
158 | }
159 | actions = {
160 | ipv4_forward;
161 | drop;
162 | NoAction;
163 | }
164 | size = 1024;
165 | default_action = drop();
166 | }
167 |
168 | apply{
169 | if (hdr.ipv4.isValid() && hdr.ipv4.ttl > 0) {
170 | ipv4_lpm.apply();
171 | }
172 |
173 | }
174 | }
175 | /*************************************************************************
176 | *********************** egress Processing********************************
177 | **************************************************************************/
178 |
179 | control SwitchEgress(inout header_t hdr,
180 | inout metadata_t meta,
181 | inout standard_metadata_t eg_intr_md) {
182 | apply {
183 | }
184 | }
185 | /*************************************************************************
186 | *********************** S W I T C H ************************************
187 | *************************************************************************/
188 |
189 | V1Switch(
190 | SwitchParser(),
191 | SwitchVerifyChecksum(),
192 | SwitchIngress(),
193 | SwitchEgress(),
194 | SwitchComputeChecksum(),
195 | SwitchDeparser()
196 | ) main;
--------------------------------------------------------------------------------
/src/test/BMv2/test_environment/P4/s14.p4:
--------------------------------------------------------------------------------
1 | ########################################################################
2 | # This program is a free software tool, which does ensemble in-network machine learning.
3 | # licensed under Apache-2.0
4 | #
5 | # Copyright (c) 2020-2021 Changgang Zheng
6 | # Copyright (c) Computing Infrastructure Group, Department of Engineering Science, University of Oxford & YINS, Yale University
7 | # E-mail: changgang.zheng@eng.ox.ac.uk (valid until July 2024),
8 | # changgang.zheng@yale.edu (valid until October 2022) or changgangzheng@qq.com (no expiration date)
9 | #########################################################################
10 | # This file was autogenerated
11 |
12 | #include
13 | #include
14 |
15 | /*************************************************************************
16 | ***************************** constants **********************************
17 | *************************************************************************/
18 |
19 | const bit<16> TYPE_IPV4 = 0x800;
20 |
21 | typedef bit<9> egressSpec_t;
22 | typedef bit<48> macAddr_t;
23 | typedef bit<32> ip4Addr_t;
24 |
25 | /*************************************************************************
26 | ****************************** headers ***********************************
27 | *************************************************************************/
28 |
29 | header ethernet_h {
30 | macAddr_t dstAddr;
31 | macAddr_t srcAddr;
32 | bit<16> etherType;
33 | }
34 |
35 | header ipv4_h{
36 | bit < 4 > version;
37 | bit < 4 > ihl;
38 | bit < 8 > diffserv;
39 | bit < 16 > totalLen;
40 | bit < 16 > identification;
41 | bit < 3 > flags;
42 | bit < 13 > fragOffset;
43 | bit < 8 > ttl;
44 | bit < 8 > protocol;
45 | bit < 16 > hdrChecksum;
46 | ip4Addr_t srcAddr;
47 | ip4Addr_t dstAddr;
48 | }
49 |
50 | struct header_t {
51 | ethernet_h ethernet;
52 | ipv4_h ipv4;
53 | }
54 |
55 | /*************************************************************************
56 | ***************************** metadata **********************************
57 | *************************************************************************/
58 |
59 | struct metadata_t {
60 | }
61 |
62 | /*************************************************************************
63 | *********************** Ingress Parser ***********************************
64 | *************************************************************************/
65 |
66 | parser SwitchParser(
67 | packet_in pkt,
68 | out header_t hdr,
69 | inout metadata_t meta,
70 | inout standard_metadata_t ig_intr_md) {
71 |
72 | state start {
73 | transition parse_ethernet;
74 | }
75 |
76 | state parse_ethernet {
77 | pkt.extract(hdr.ethernet);
78 | transition select(hdr.ethernet.etherType) {
79 | TYPE_IPV4 : parse_ipv4;
80 | default : accept;
81 | }
82 | }
83 |
84 | state parse_ipv4 {
85 | pkt.extract(hdr.ipv4);
86 | transition accept;
87 | }
88 |
89 | }
90 |
91 | /*************************************************************************
92 | *********************** Egress Deparser *********************************
93 | **************************************************************************/
94 |
95 | control SwitchDeparser(
96 | packet_out pkt,
97 | in header_t hdr) {
98 | apply {
99 | pkt.emit(hdr);
100 | }
101 | }
102 |
103 | /*************************************************************************
104 | ********************** Checksum Verification *****************************
105 | *************************************************************************/
106 |
107 | control SwitchVerifyChecksum(inout header_t hdr,
108 | inout metadata_t meta) {
109 | apply {}
110 | }
111 | /*************************************************************************
112 | ********************** Checksum Computation ******************************
113 | *************************************************************************/
114 |
115 | control SwitchComputeChecksum(inout header_t hdr,
116 | inout metadata_t meta) {
117 | apply {
118 | update_checksum(
119 | hdr.ipv4.isValid(),
120 | { hdr.ipv4.version,
121 | hdr.ipv4.ihl,
122 | hdr.ipv4.diffserv,
123 | hdr.ipv4.totalLen,
124 | hdr.ipv4.identification,
125 | hdr.ipv4.flags,
126 | hdr.ipv4.fragOffset,
127 | hdr.ipv4.ttl,
128 | hdr.ipv4.protocol,
129 | hdr.ipv4.srcAddr,
130 | hdr.ipv4.dstAddr },
131 | hdr.ipv4.hdrChecksum,
132 | HashAlgorithm.csum16);
133 | }
134 | }
135 | /*************************************************************************
136 | *********************** Ingress Processing********************************
137 | **************************************************************************/
138 |
139 | control SwitchIngress(
140 | inout header_t hdr,
141 | inout metadata_t meta,
142 | inout standard_metadata_t ig_intr_md) {
143 |
144 | action drop() {
145 | mark_to_drop(ig_intr_md);
146 | }
147 |
148 | action ipv4_forward(macAddr_t dstAddr, egressSpec_t port) {
149 | ig_intr_md.egress_spec = port;
150 | hdr.ethernet.srcAddr = hdr.ethernet.dstAddr;
151 | hdr.ethernet.dstAddr = dstAddr;
152 | hdr.ipv4.ttl = hdr.ipv4.ttl - 1;
153 | }
154 |
155 | table ipv4_lpm {
156 | key = {
157 | hdr.ipv4.dstAddr: lpm;
158 | }
159 | actions = {
160 | ipv4_forward;
161 | drop;
162 | NoAction;
163 | }
164 | size = 1024;
165 | default_action = drop();
166 | }
167 |
168 | apply{
169 | if (hdr.ipv4.isValid() && hdr.ipv4.ttl > 0) {
170 | ipv4_lpm.apply();
171 | }
172 |
173 | }
174 | }
175 | /*************************************************************************
176 | *********************** egress Processing********************************
177 | **************************************************************************/
178 |
179 | control SwitchEgress(inout header_t hdr,
180 | inout metadata_t meta,
181 | inout standard_metadata_t eg_intr_md) {
182 | apply {
183 | }
184 | }
185 | /*************************************************************************
186 | *********************** S W I T C H ************************************
187 | *************************************************************************/
188 |
189 | V1Switch(
190 | SwitchParser(),
191 | SwitchVerifyChecksum(),
192 | SwitchIngress(),
193 | SwitchEgress(),
194 | SwitchComputeChecksum(),
195 | SwitchDeparser()
196 | ) main;
--------------------------------------------------------------------------------
/src/test/BMv2/test_environment/commands/s0.txt:
--------------------------------------------------------------------------------
1 | table_add SwitchIngress.ipv4_lpm SwitchIngress.ipv4_forward 10.0.0.254/32 => 10:00:00:00:00:00 88
2 | table_add SwitchIngress.ipv4_lpm SwitchIngress.ipv4_forward 10.0.0.2/32 => c8:00:00:00:01:01 1
3 | table_add SwitchIngress.ipv4_lpm SwitchIngress.ipv4_forward 10.0.0.3/32 => c8:00:00:00:01:01 1
4 | table_add SwitchIngress.ipv4_lpm SwitchIngress.ipv4_forward 10.0.0.5/32 => c8:00:00:00:01:04 2
5 | table_add SwitchIngress.ipv4_lpm SwitchIngress.ipv4_forward 10.0.0.6/32 => c8:00:00:00:01:04 2
6 |
--------------------------------------------------------------------------------
/src/test/BMv2/test_environment/commands/s1.txt:
--------------------------------------------------------------------------------
1 | table_add SwitchIngress.ipv4_lpm SwitchIngress.ipv4_forward 10.0.0.254/32 => c8:00:00:00:01:00 1
2 | table_add SwitchIngress.ipv4_lpm SwitchIngress.ipv4_forward 10.0.0.2/32 => c8:00:00:00:01:02 2
3 | table_add SwitchIngress.ipv4_lpm SwitchIngress.ipv4_forward 10.0.0.3/32 => c8:00:00:00:01:03 3
4 | table_add SwitchIngress.ipv4_lpm SwitchIngress.ipv4_forward 10.0.0.5/32 => c8:00:00:00:01:00 1
5 | table_add SwitchIngress.ipv4_lpm SwitchIngress.ipv4_forward 10.0.0.6/32 => c8:00:00:00:01:00 1
6 |
--------------------------------------------------------------------------------
/src/test/BMv2/test_environment/commands/s10.txt:
--------------------------------------------------------------------------------
1 | table_add SwitchIngress.ipv4_lpm SwitchIngress.ipv4_forward 10.0.0.254/32 => c8:00:00:00:02:09 1
2 | table_add SwitchIngress.ipv4_lpm SwitchIngress.ipv4_forward 10.0.0.4/32 => c8:00:00:00:02:09 1
3 | table_add SwitchIngress.ipv4_lpm SwitchIngress.ipv4_forward 10.0.0.5/32 => c8:00:00:00:02:09 1
4 | table_add SwitchIngress.ipv4_lpm SwitchIngress.ipv4_forward 10.0.0.7/32 => c8:00:00:00:02:09 1
5 |
--------------------------------------------------------------------------------
/src/test/BMv2/test_environment/commands/s11.txt:
--------------------------------------------------------------------------------
1 | table_add SwitchIngress.ipv4_lpm SwitchIngress.ipv4_forward 10.0.0.254/32 => c8:00:00:00:03:09 1
2 | table_add SwitchIngress.ipv4_lpm SwitchIngress.ipv4_forward 10.0.0.4/32 => c8:00:00:00:03:09 1
3 | table_add SwitchIngress.ipv4_lpm SwitchIngress.ipv4_forward 10.0.0.5/32 => c8:00:00:00:03:09 1
4 | table_add SwitchIngress.ipv4_lpm SwitchIngress.ipv4_forward 10.0.0.7/32 => c8:00:00:00:03:09 1
5 |
--------------------------------------------------------------------------------
/src/test/BMv2/test_environment/commands/s12.txt:
--------------------------------------------------------------------------------
1 | table_add SwitchIngress.ipv4_lpm SwitchIngress.ipv4_forward 10.0.0.254/32 => c8:00:00:00:03:08 1
2 | table_add SwitchIngress.ipv4_lpm SwitchIngress.ipv4_forward 10.0.0.4/32 => c8:00:00:00:03:08 1
3 | table_add SwitchIngress.ipv4_lpm SwitchIngress.ipv4_forward 10.0.0.5/32 => c8:00:00:00:03:08 1
4 | table_add SwitchIngress.ipv4_lpm SwitchIngress.ipv4_forward 10.0.0.7/32 => c8:00:00:00:03:08 1
5 |
--------------------------------------------------------------------------------
/src/test/BMv2/test_environment/commands/s13.txt:
--------------------------------------------------------------------------------
1 | table_add SwitchIngress.ipv4_lpm SwitchIngress.ipv4_forward 10.0.0.254/32 => c8:00:00:00:02:0c 1
2 | table_add SwitchIngress.ipv4_lpm SwitchIngress.ipv4_forward 10.0.0.4/32 => c8:00:00:00:02:0c 1
3 | table_add SwitchIngress.ipv4_lpm SwitchIngress.ipv4_forward 10.0.0.5/32 => c8:00:00:00:02:0c 1
4 | table_add SwitchIngress.ipv4_lpm SwitchIngress.ipv4_forward 10.0.0.7/32 => c8:00:00:00:02:0c 1
5 |
--------------------------------------------------------------------------------
/src/test/BMv2/test_environment/commands/s14.txt:
--------------------------------------------------------------------------------
1 | table_add SwitchIngress.ipv4_lpm SwitchIngress.ipv4_forward 10.0.0.254/32 => c8:00:00:00:03:0c 1
2 | table_add SwitchIngress.ipv4_lpm SwitchIngress.ipv4_forward 10.0.0.4/32 => c8:00:00:00:03:0c 1
3 | table_add SwitchIngress.ipv4_lpm SwitchIngress.ipv4_forward 10.0.0.5/32 => c8:00:00:00:03:0c 1
4 | table_add SwitchIngress.ipv4_lpm SwitchIngress.ipv4_forward 10.0.0.7/32 => c8:00:00:00:03:0c 1
5 |
--------------------------------------------------------------------------------
/src/test/BMv2/test_environment/commands/s2.txt:
--------------------------------------------------------------------------------
1 | table_add SwitchIngress.ipv4_lpm SwitchIngress.ipv4_forward 10.0.0.254/32 => c8:00:00:00:02:01 1
2 | table_add SwitchIngress.ipv4_lpm SwitchIngress.ipv4_forward 10.0.0.2/32 => 10:00:00:00:00:02 88
3 | table_add SwitchIngress.ipv4_lpm SwitchIngress.ipv4_forward 10.0.0.3/32 => c8:00:00:00:02:01 1
4 | table_add SwitchIngress.ipv4_lpm SwitchIngress.ipv4_forward 10.0.0.5/32 => c8:00:00:00:02:01 1
5 | table_add SwitchIngress.ipv4_lpm SwitchIngress.ipv4_forward 10.0.0.6/32 => c8:00:00:00:02:01 1
6 |
--------------------------------------------------------------------------------
/src/test/BMv2/test_environment/commands/s3.txt:
--------------------------------------------------------------------------------
1 | table_add SwitchIngress.ipv4_lpm SwitchIngress.ipv4_forward 10.0.0.254/32 => c8:00:00:00:03:01 1
2 | table_add SwitchIngress.ipv4_lpm SwitchIngress.ipv4_forward 10.0.0.2/32 => c8:00:00:00:03:01 1
3 | table_add SwitchIngress.ipv4_lpm SwitchIngress.ipv4_forward 10.0.0.3/32 => 10:00:00:00:00:03 88
4 | table_add SwitchIngress.ipv4_lpm SwitchIngress.ipv4_forward 10.0.0.5/32 => c8:00:00:00:03:01 1
5 | table_add SwitchIngress.ipv4_lpm SwitchIngress.ipv4_forward 10.0.0.6/32 => c8:00:00:00:03:01 1
6 |
--------------------------------------------------------------------------------
/src/test/BMv2/test_environment/commands/s4.txt:
--------------------------------------------------------------------------------
1 | table_add SwitchIngress.ipv4_lpm SwitchIngress.ipv4_forward 10.0.0.254/32 => c8:00:00:00:02:00 1
2 | table_add SwitchIngress.ipv4_lpm SwitchIngress.ipv4_forward 10.0.0.2/32 => c8:00:00:00:02:00 1
3 | table_add SwitchIngress.ipv4_lpm SwitchIngress.ipv4_forward 10.0.0.3/32 => c8:00:00:00:02:00 1
4 | table_add SwitchIngress.ipv4_lpm SwitchIngress.ipv4_forward 10.0.0.5/32 => c8:00:00:00:01:05 2
5 | table_add SwitchIngress.ipv4_lpm SwitchIngress.ipv4_forward 10.0.0.6/32 => c8:00:00:00:01:06 3
6 |
--------------------------------------------------------------------------------
/src/test/BMv2/test_environment/commands/s5.txt:
--------------------------------------------------------------------------------
1 | table_add SwitchIngress.ipv4_lpm SwitchIngress.ipv4_forward 10.0.0.254/32 => c8:00:00:00:02:04 1
2 | table_add SwitchIngress.ipv4_lpm SwitchIngress.ipv4_forward 10.0.0.2/32 => c8:00:00:00:02:04 1
3 | table_add SwitchIngress.ipv4_lpm SwitchIngress.ipv4_forward 10.0.0.3/32 => c8:00:00:00:02:04 1
4 | table_add SwitchIngress.ipv4_lpm SwitchIngress.ipv4_forward 10.0.0.5/32 => 10:00:00:00:00:05 88
5 | table_add SwitchIngress.ipv4_lpm SwitchIngress.ipv4_forward 10.0.0.6/32 => c8:00:00:00:02:04 1
6 |
--------------------------------------------------------------------------------
/src/test/BMv2/test_environment/commands/s6.txt:
--------------------------------------------------------------------------------
1 | table_add SwitchIngress.ipv4_lpm SwitchIngress.ipv4_forward 10.0.0.254/32 => c8:00:00:00:03:04 1
2 | table_add SwitchIngress.ipv4_lpm SwitchIngress.ipv4_forward 10.0.0.2/32 => c8:00:00:00:03:04 1
3 | table_add SwitchIngress.ipv4_lpm SwitchIngress.ipv4_forward 10.0.0.3/32 => c8:00:00:00:03:04 1
4 | table_add SwitchIngress.ipv4_lpm SwitchIngress.ipv4_forward 10.0.0.5/32 => c8:00:00:00:03:04 1
5 | table_add SwitchIngress.ipv4_lpm SwitchIngress.ipv4_forward 10.0.0.6/32 => 10:00:00:00:00:06 88
6 |
--------------------------------------------------------------------------------
/src/test/BMv2/test_environment/commands/s7.txt:
--------------------------------------------------------------------------------
1 | table_add SwitchIngress.ipv4_lpm SwitchIngress.ipv4_forward 10.0.0.254/32 => c8:00:00:00:03:05 1
2 | table_add SwitchIngress.ipv4_lpm SwitchIngress.ipv4_forward 10.0.0.4/32 => c8:00:00:00:03:05 1
3 | table_add SwitchIngress.ipv4_lpm SwitchIngress.ipv4_forward 10.0.0.5/32 => c8:00:00:00:03:05 1
4 | table_add SwitchIngress.ipv4_lpm SwitchIngress.ipv4_forward 10.0.0.7/32 => 10:00:00:00:00:07 88
5 |
--------------------------------------------------------------------------------
/src/test/BMv2/test_environment/commands/s8.txt:
--------------------------------------------------------------------------------
1 | table_add SwitchIngress.ipv4_lpm SwitchIngress.ipv4_forward 10.0.0.254/32 => c8:00:00:00:02:00 1
2 | table_add SwitchIngress.ipv4_lpm SwitchIngress.ipv4_forward 10.0.0.4/32 => c8:00:00:00:02:00 1
3 | table_add SwitchIngress.ipv4_lpm SwitchIngress.ipv4_forward 10.0.0.5/32 => c8:00:00:00:02:00 1
4 | table_add SwitchIngress.ipv4_lpm SwitchIngress.ipv4_forward 10.0.0.7/32 => c8:00:00:00:02:00 1
5 |
--------------------------------------------------------------------------------
/src/test/BMv2/test_environment/commands/s9.txt:
--------------------------------------------------------------------------------
1 | table_add SwitchIngress.ipv4_lpm SwitchIngress.ipv4_forward 10.0.0.254/32 => c8:00:00:00:02:08 1
2 | table_add SwitchIngress.ipv4_lpm SwitchIngress.ipv4_forward 10.0.0.4/32 => c8:00:00:00:02:08 1
3 | table_add SwitchIngress.ipv4_lpm SwitchIngress.ipv4_forward 10.0.0.5/32 => c8:00:00:00:02:08 1
4 | table_add SwitchIngress.ipv4_lpm SwitchIngress.ipv4_forward 10.0.0.7/32 => c8:00:00:00:02:08 1
5 |
--------------------------------------------------------------------------------
/src/test/BMv2/test_environment/insert_rules.sh:
--------------------------------------------------------------------------------
1 | simple_switch_CLI --thrift-port 9090 < ./commands/s0.txt
2 | simple_switch_CLI --thrift-port 9091 < ./commands/s1.txt
3 | simple_switch_CLI --thrift-port 9092 < ./commands/s2.txt
4 | simple_switch_CLI --thrift-port 9093 < ./commands/s3.txt
5 | simple_switch_CLI --thrift-port 9094 < ./commands/s4.txt
6 | simple_switch_CLI --thrift-port 9095 < ./commands/s5.txt
7 | simple_switch_CLI --thrift-port 9096 < ./commands/s6.txt
8 |
--------------------------------------------------------------------------------
/src/test/BMv2/test_environment/run_demo.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | BMV2_PATH=/home/jesu3779/mysde/behavioral-model-1.15.0
3 | SWITCH_PATH=$BMV2_PATH/targets/simple_switch/simple_switch
4 | echo 'passcode' | sudo -S $SWITCH_PATH >/dev/null 2>&1
5 | sudo make clean
6 | sudo PYTHONPATH=$PYTHONPATH:$BMV2_PATH/mininet/ python3 main.py --behavioral-exe $SWITCH_PATH
7 |
--------------------------------------------------------------------------------
/src/test/BMv2/utils/Makefile:
--------------------------------------------------------------------------------
1 | BUILD_DIR = build
2 | PCAP_DIR = pcaps
3 | LOG_DIR = logs
4 |
5 | P4C = p4c-bm2-ss
6 | P4C_ARGS += --p4runtime-files $(BUILD_DIR)/$(basename $@).p4.p4info.txt
7 |
8 | RUN_SCRIPT = ../../utils/run_exercise.py
9 |
10 | ifndef TOPO
11 | TOPO = topology.json
12 | endif
13 |
14 | source = $(wildcard *.p4)
15 | compiled_json := $(source:.p4=.json)
16 |
17 | ifndef DEFAULT_PROG
18 | DEFAULT_PROG = $(wildcard *.p4)
19 | endif
20 | DEFAULT_JSON = $(BUILD_DIR)/$(DEFAULT_PROG:.p4=.json)
21 |
22 | # Define NO_P4 to start BMv2 without a program
23 | ifndef NO_P4
24 | run_args += -j $(DEFAULT_JSON)
25 | endif
26 |
27 | # Set BMV2_SWITCH_EXE to override the BMv2 target
28 | ifdef BMV2_SWITCH_EXE
29 | run_args += -b $(BMV2_SWITCH_EXE)
30 | endif
31 |
32 | all: run
33 |
34 | run: build
35 | sudo python3 $(RUN_SCRIPT) -t $(TOPO) $(run_args)
36 |
37 | stop:
38 | sudo mn -c
39 |
40 | build: dirs $(compiled_json)
41 |
42 | %.json: %.p4
43 | $(P4C) --p4v 16 $(P4C_ARGS) -o $(BUILD_DIR)/$@ $<
44 |
45 | dirs:
46 | mkdir -p $(BUILD_DIR) $(PCAP_DIR) $(LOG_DIR)
47 |
48 | clean: stop
49 | rm -f *.pcap
50 | rm -rf $(BUILD_DIR) $(PCAP_DIR) $(LOG_DIR)
51 |
--------------------------------------------------------------------------------
/src/test/BMv2/utils/architecture/psa/Makefile:
--------------------------------------------------------------------------------
1 | BUILD_DIR = build
2 | PCAP_DIR = pcaps
3 | LOG_DIR = logs
4 |
5 | P4C = p4c-bm2-psa
6 | P4C_ARGS += --p4runtime-files $(BUILD_DIR)/$(basename $@).p4.p4info.txt
7 |
8 | RUN_SCRIPT = ../../utils/run_exercise.py
9 |
10 | ifndef TOPO
11 | TOPO = topology.json
12 | endif
13 |
14 | source = $(wildcard *.p4)
15 | compiled_json := $(source:.p4=.json)
16 |
17 | ifndef DEFAULT_PROG
18 | DEFAULT_PROG = $(wildcard *.p4)
19 | endif
20 | DEFAULT_JSON = $(BUILD_DIR)/$(DEFAULT_PROG:.p4=.json)
21 |
22 | # Define NO_P4 to start BMv2 without a program
23 | ifndef NO_P4
24 | run_args += -j $(DEFAULT_JSON)
25 | endif
26 |
27 | # Set BMV2_SWITCH_EXE to override the BMv2 target
28 | ifdef BMV2_SWITCH_EXE
29 | run_args += -b $(BMV2_SWITCH_EXE)
30 | endif
31 |
32 | all: run
33 |
34 | run: build
35 | sudo python3 $(RUN_SCRIPT) -t $(TOPO) $(run_args)
36 |
37 | stop:
38 | sudo mn -c
39 |
40 | build: dirs $(compiled_json)
41 |
42 | %.json: %.p4
43 | $(P4C) --p4v 16 $(P4C_ARGS) -o $(BUILD_DIR)/$@ $<
44 |
45 | dirs:
46 | mkdir -p $(BUILD_DIR) $(PCAP_DIR) $(LOG_DIR)
47 |
48 | clean: stop
49 | rm -f *.pcap
50 | rm -rf $(BUILD_DIR) $(PCAP_DIR) $(LOG_DIR)
51 |
--------------------------------------------------------------------------------
/src/test/BMv2/utils/architecture/v1model/Makefile:
--------------------------------------------------------------------------------
1 | BUILD_DIR = build
2 | PCAP_DIR = pcaps
3 | LOG_DIR = logs
4 |
5 | P4C = p4c-bm2-ss
6 | P4C_ARGS += --p4runtime-files $(BUILD_DIR)/$(basename $@).p4.p4info.txt
7 |
8 | RUN_SCRIPT = ../../utils/run_exercise.py
9 |
10 | ifndef TOPO
11 | TOPO = topology.json
12 | endif
13 |
14 | source = $(wildcard *.p4)
15 | compiled_json := $(source:.p4=.json)
16 |
17 | ifndef DEFAULT_PROG
18 | DEFAULT_PROG = $(wildcard *.p4)
19 | endif
20 | DEFAULT_JSON = $(BUILD_DIR)/$(DEFAULT_PROG:.p4=.json)
21 |
22 | # Define NO_P4 to start BMv2 without a program
23 | ifndef NO_P4
24 | run_args += -j $(DEFAULT_JSON)
25 | endif
26 |
27 | # Set BMV2_SWITCH_EXE to override the BMv2 target
28 | ifdef BMV2_SWITCH_EXE
29 | run_args += -b $(BMV2_SWITCH_EXE)
30 | endif
31 |
32 | all: run
33 |
34 | run: build
35 | sudo python3 $(RUN_SCRIPT) -t $(TOPO) $(run_args)
36 |
37 | stop:
38 | sudo mn -c
39 |
40 | build: dirs $(compiled_json)
41 |
42 | %.json: %.p4
43 | $(P4C) --p4v 16 $(P4C_ARGS) -o $(BUILD_DIR)/$@ $<
44 |
45 | dirs:
46 | mkdir -p $(BUILD_DIR) $(PCAP_DIR) $(LOG_DIR)
47 |
48 | clean: stop
49 | rm -f *.pcap
50 | rm -rf $(BUILD_DIR) $(PCAP_DIR) $(LOG_DIR)
51 |
--------------------------------------------------------------------------------
/src/test/BMv2/utils/cheat_sheet_src/src/actions.txt:
--------------------------------------------------------------------------------
1 | // Inputs provided by control-plane
2 | action set_next_hop(bit<32> next_hop) {
3 | if (next_hop == 0) {
4 | metadata.next_hop = hdr.ipv4.dst;
5 | } else {
6 | metadata.next_hop = next_hop;
7 | }
8 | }
9 |
10 | // Inputs provided by data-plane
11 | action swap_mac(inout bit<48> x,
12 | inout bit<48> y) {
13 | bit<48> tmp = x;
14 | x = y;
15 | y = tmp;
16 | }
17 |
18 | // Inputs provided by control/data-plane
19 | action forward(in bit<9> p, bit<48> d) {
20 | standard_metadata.egress_spec = p;
21 | headers.ethernet.dstAddr = d;
22 | }
23 |
24 | // Remove header from packet
25 | action decap_ip_ip() {
26 | hdr.ipv4 = hdr.inner_ipv4;
27 | hdr.inner_ipv4.setInvalid();
28 | }
29 |
--------------------------------------------------------------------------------
/src/test/BMv2/utils/cheat_sheet_src/src/adv_parsing.txt:
--------------------------------------------------------------------------------
1 | // common defns for IPv4 and IPv6
2 | header ip46_t {
3 | bit<4> version;
4 | bit<4> reserved;
5 | }
6 |
7 | // header stack parsing
8 | state parse_labels {
9 | packet.extract(hdr.labels.next);
10 | transition select(hdr.labels.last.bos) {
11 | 0: parse_labels; // create loop
12 | 1: guess_labels_payload;
13 | }
14 | }
15 |
16 | // lookahead parsing
17 | state guess_labels_payload {
18 | transition select(packet.lookahead().version) {
19 | 4 : parse_inner_ipv4;
20 | 6 : parse_inner_ipv6;
21 | default : parse_inner_ethernet;
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/test/BMv2/utils/cheat_sheet_src/src/architecture.txt:
--------------------------------------------------------------------------------
1 | // common externs
2 | extern void truncate(in bit<32> length);
3 | extern void resubmit(in T x);
4 | extern void recirculate(in T x);
5 | enum CloneType { I2E, E2I }
6 | extern void clone(in CloneType type,
7 | in bit<32> session);
8 |
9 | // v1model pipeline elements
10 | parser Parser(
11 | packet_in pkt,
12 | out H hdr,
13 | inout M meta,
14 | inout standard_metadata_t std_meta
15 | );
16 | control VerifyChecksum(
17 | inout H hdr,
18 | inout M meta
19 | );
20 | control Ingress(
21 | inout H hdr,
22 | inout M meta,
23 | inout standard_metadata_t std_meta
24 | );
25 | control Egress(
26 | inout H hdr,
27 | inout M meta,
28 | inout standard_metadata_t std_meta
29 | );
30 | control ComputeChecksum(
31 | inout H hdr,
32 | inout M meta
33 | );
34 | control Deparser(
35 | packet_out b, in H hdr
36 | );
37 |
38 | // v1model switch
39 | package V1Switch(
40 | Parser p,
41 | VerifyChecksum vr,
42 | Ingress ig,
43 | Egress eg,
44 | ComputeChecksum ck,
45 | Deparser d
46 | );
47 |
--------------------------------------------------------------------------------
/src/test/BMv2/utils/cheat_sheet_src/src/control_flow.txt:
--------------------------------------------------------------------------------
1 | apply {
2 | // branch on header validity
3 | if (hdr.ipv4.isValid()) {
4 | ipv4_lpm.apply();
5 | }
6 | // branch on table hit result
7 | if (local_ip_table.apply().hit) {
8 | send_to_cpu();
9 | }
10 | // branch on table action invocation
11 | switch (table1.apply().action_run) {
12 | action1: { table2.apply(); }
13 | action2: { table3.apply(); }
14 | }
15 | }
--------------------------------------------------------------------------------
/src/test/BMv2/utils/cheat_sheet_src/src/counters.txt:
--------------------------------------------------------------------------------
1 | // counters
2 | counter(8192, CounterType.packets) c;
3 |
4 | action count(bit<32> index) {
5 | //increment counter at index
6 | c.count(index);
7 | }
8 |
9 | // registers
10 | register>(16384) r;
11 |
12 | action ipg(out bit<48> ival, bit<32> x) {
13 | bit<48> last;
14 | bit<48> now;
15 | r.read(last, x);
16 | now = std_meta.ingress_global_timestamp;
17 | ival = now - last;
18 | r.write(x, now);
19 | }
20 |
--------------------------------------------------------------------------------
/src/test/BMv2/utils/cheat_sheet_src/src/data_types.txt:
--------------------------------------------------------------------------------
1 | // typedef: introduces alternate type name
2 | typedef bit<48> macAddr_t;
3 | typedef bit<32> ip4Addr_t;
4 |
5 | // headers: ordered collection of members
6 | // operations test and set validity bits:
7 | // isValid(), setValid(), setInvalid()
8 | header ethernet_t {
9 | macAddr_t dstAddr;
10 | macAddr_t srcAddr;
11 | bit<16> type;
12 | }
13 |
14 | // variable declaration and member access
15 | ethernet_t ethernet;
16 | macAddr_t src = ethernet.srcAddr;
17 |
18 | // struct: unordered collection of members
19 | struct headers_t {
20 | ethernet_t ethernet;
21 | }
22 |
23 |
--------------------------------------------------------------------------------
/src/test/BMv2/utils/cheat_sheet_src/src/deparsing.txt:
--------------------------------------------------------------------------------
1 | // packet_out: extern for output packet
2 | extern packet_out {
3 | void emit(in T hdr);
4 | }
5 |
6 | apply {
7 | // insert headers into pkt if valid
8 | packet.emit(hdr.ethernet);
9 | }
--------------------------------------------------------------------------------
/src/test/BMv2/utils/cheat_sheet_src/src/expressions.txt:
--------------------------------------------------------------------------------
1 | // Local metadata declaration, assignment
2 | bit<16> tmp1; bit<16> tmp2;
3 | tmp1 = hdr.ethernet.type;
4 |
5 | // bit slicing, concatenation
6 | tmp2 = tmp1[7:0] ++ tmp1[15:8];
7 |
8 | // addition, subtraction, casts
9 | tmp2 = tmp1 + tmp1 - (bit<16>)tmp1[7:0];
10 |
11 | // bitwise operators
12 | tmp2 = (~tmp1 & tmp1) | (tmp1 ^ tmp1);
13 | tmp2 = tmp1 << 3;
--------------------------------------------------------------------------------
/src/test/BMv2/utils/cheat_sheet_src/src/header_stack.txt:
--------------------------------------------------------------------------------
1 | // header stack declaration
2 | header label_t {
3 | bit<20> label;
4 | bit bos;
5 | }
6 | struct header_t {
7 | label_t[10] labels;
8 | }
9 | header_t hdr;
10 |
11 | // remove from header stack
12 | action pop_label() {
13 | hdr.labels.pop_front(1);
14 | }
15 |
16 | // add to header stack
17 | action push_label(in bit<20> label) {
18 | hdr.labels.push_front(1);
19 | hdr.labels[0].setValid();
20 | hdr.labels[0] = { label, 0};
21 | }
22 |
--------------------------------------------------------------------------------
/src/test/BMv2/utils/cheat_sheet_src/src/parsers.txt:
--------------------------------------------------------------------------------
1 | // packet_in: extern for input packet
2 | extern packet_in {
3 | void extract(out T hdr);
4 | void extract(out T hdr,in bit<32> n);
5 | T lookahead();
6 | void advance(in bit<32> n);
7 | bit<32> length();
8 | }
9 |
10 | // parser: begins in special "start" state
11 | state start {
12 | transition parse_ethernet;
13 | }
14 |
15 | // User-defined parser state
16 | state parse_ethernet {
17 | packet.extract(hdr.ethernet);
18 | transition select(hdr.ethernet.type) {
19 | 0x800: parse_ipv4;
20 | default: accept;
21 | }
22 | }
--------------------------------------------------------------------------------
/src/test/BMv2/utils/cheat_sheet_src/src/tables.txt:
--------------------------------------------------------------------------------
1 | table ipv4_lpm {
2 | key = {
3 | hdr.ipv4.dstAddr : lpm;
4 | // standard match kinds:
5 | // exact, ternary, lpm
6 | }
7 | // actions that can be invoked
8 | actions = {
9 | ipv4_forward;
10 | drop;
11 | NoAction;
12 | }
13 | // table properties
14 | size = 1024;
15 | default_action = NoAction();
16 | }
--------------------------------------------------------------------------------
/src/test/BMv2/utils/cheat_sheet_src/src/v1model_std_metadata.txt:
--------------------------------------------------------------------------------
1 | struct standard_metadata_t {
2 | // For more details see docs/simple_switch.md
3 | // in https://github.com/p4lang/behavioral-model
4 |
5 | // Should only read, ingress or egress
6 | bit<9> ingress_port;
7 | bit<32> instance_type;
8 | bit<32> packet_length;
9 | bit<48> ingress_global_timestamp;
10 | bit<1> checksum_error;
11 | error parser_error;
12 |
13 | // In ingress, read or write.
14 | // In egress, should only read.
15 | bit<9> egress_spec;
16 | bit<16> mcast_grp;
17 |
18 | // Should only read, only in egress
19 | bit<9> egress_port;
20 | bit<16> egress_rid;
21 | bit<48> egress_global_timestamp;
22 | bit<32> enq_timestamp;
23 | bit<19> enq_qdepth;
24 | bit<32> deq_timedelta;
25 | bit<19> deq_qdepth;
26 | }
27 |
--------------------------------------------------------------------------------
/src/test/BMv2/utils/mininet/appcontroller.py:
--------------------------------------------------------------------------------
1 | import subprocess
2 |
3 | from shortest_path import ShortestPath
4 |
5 | class AppController:
6 |
7 | def __init__(self, manifest=None, target=None, topo=None, net=None, links=None):
8 | self.manifest = manifest
9 | self.target = target
10 | self.conf = manifest['targets'][target]
11 | self.topo = topo
12 | self.net = net
13 | self.links = links
14 |
15 | def read_entries(self, filename):
16 | entries = []
17 | with open(filename, 'r') as f:
18 | for line in f:
19 | line = line.strip()
20 | if line == '': continue
21 | entries.append(line)
22 | return entries
23 |
24 | def add_entries(self, thrift_port=9090, sw=None, entries=None):
25 | assert entries
26 | if sw: thrift_port = sw.thrift_port
27 |
28 | print('\n'.join(entries))
29 | p = subprocess.Popen(['simple_switch_CLI', '--thrift-port', str(thrift_port)], stdin=subprocess.PIPE)
30 | p.communicate(input='\n'.join(entries))
31 |
32 | def read_register(self, register, idx, thrift_port=9090, sw=None):
33 | if sw: thrift_port = sw.thrift_port
34 | p = subprocess.Popen(['simple_switch_CLI', '--thrift-port', str(thrift_port)], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
35 | stdout, stderr = p.communicate(input="register_read %s %d" % (register, idx))
36 | reg_val = [l for l in stdout.split('\n') if ' %s[%d]' % (register, idx) in l][0].split('= ', 1)[1]
37 | return int(reg_val)
38 |
39 | def start(self):
40 | shortestpath = ShortestPath(self.links)
41 | entries = {}
42 | for sw in self.topo.switches():
43 | entries[sw] = []
44 | if 'switches' in self.conf and sw in self.conf['switches'] and 'entries' in self.conf['switches'][sw]:
45 | extra_entries = self.conf['switches'][sw]['entries']
46 | if type(extra_entries) == list: # array of entries
47 | entries[sw] += extra_entries
48 | else: # path to file that contains entries
49 | entries[sw] += self.read_entries(extra_entries)
50 | #entries[sw] += [
51 | # 'table_set_default send_frame _drop',
52 | # 'table_set_default forward _drop',
53 | # 'table_set_default ipv4_lpm _drop']
54 |
55 | for host_name in self.topo._host_links:
56 | h = self.net.get(host_name)
57 | for link in list(self.topo._host_links[host_name].values()):
58 | sw = link['sw']
59 | #entries[sw].append('table_add send_frame rewrite_mac %d => %s' % (link['sw_port'], link['sw_mac']))
60 | #entries[sw].append('table_add forward set_dmac %s => %s' % (link['host_ip'], link['host_mac']))
61 | #entries[sw].append('table_add ipv4_lpm set_nhop %s/32 => %s %d' % (link['host_ip'], link['host_ip'], link['sw_port']))
62 | iface = h.intfNames()[link['idx']]
63 | # use mininet to set ip and mac to let it know the change
64 | h.setIP(link['host_ip'], 24)
65 | h.setMAC(link['host_mac'])
66 | #h.cmd('ifconfig %s %s hw ether %s' % (iface, link['host_ip'], link['host_mac']))
67 | h.cmd('arp -i %s -s %s %s' % (iface, link['sw_ip'], link['sw_mac']))
68 | h.cmd('ethtool --offload %s rx off tx off' % iface)
69 | h.cmd('ip route add %s dev %s' % (link['sw_ip'], iface))
70 | h.setDefaultRoute("via %s" % link['sw_ip'])
71 |
72 | for h in self.net.hosts:
73 | h_link = list(self.topo._host_links[h.name].values())[0]
74 | for sw in self.net.switches:
75 | path = shortestpath.get(sw.name, h.name, exclude=lambda n: n[0]=='h')
76 | if not path: continue
77 | if not path[1][0] == 's': continue # next hop is a switch
78 | sw_link = self.topo._sw_links[sw.name][path[1]]
79 | #entries[sw.name].append('table_add send_frame rewrite_mac %d => %s' % (sw_link[0]['port'], sw_link[0]['mac']))
80 | #entries[sw.name].append('table_add forward set_dmac %s => %s' % (h_link['host_ip'], sw_link[1]['mac']))
81 | #entries[sw.name].append('table_add ipv4_lpm set_nhop %s/32 => %s %d' % (h_link['host_ip'], h_link['host_ip'], sw_link[0]['port']))
82 |
83 | for h2 in self.net.hosts:
84 | if h == h2: continue
85 | path = shortestpath.get(h.name, h2.name, exclude=lambda n: n[0]=='h')
86 | if not path: continue
87 | h_link = self.topo._host_links[h.name][path[1]]
88 | h2_link = list(self.topo._host_links[h2.name].values())[0]
89 | h.cmd('ip route add %s via %s' % (h2_link['host_ip'], h_link['sw_ip']))
90 |
91 |
92 | print("**********")
93 | print("Configuring entries in p4 tables")
94 | for sw_name in entries:
95 | print()
96 | print("Configuring switch... %s" % sw_name)
97 | sw = self.net.get(sw_name)
98 | if entries[sw_name]:
99 | self.add_entries(sw=sw, entries=entries[sw_name])
100 | print("Configuration complete.")
101 | print("**********")
102 |
103 | def stop(self):
104 | pass
105 |
--------------------------------------------------------------------------------
/src/test/BMv2/utils/mininet/apptopo.py:
--------------------------------------------------------------------------------
1 | from mininet.topo import Topo
2 |
3 | class AppTopo(Topo):
4 |
5 | def __init__(self, links, latencies={}, manifest=None, target=None,
6 | log_dir="/tmp", bws={}, **opts):
7 | Topo.__init__(self, **opts)
8 |
9 | nodes = sum(list(map(list, list(zip(*links)))), [])
10 | host_names = sorted(list(set([n for n in nodes if n[0] == 'h'])))
11 | sw_names = sorted(list(set([n for n in nodes if n[0] == 's'])))
12 | sw_ports = dict([(sw, []) for sw in sw_names])
13 |
14 | self._host_links = {}
15 | self._sw_links = dict([(sw, {}) for sw in sw_names])
16 |
17 | for sw_name in sw_names:
18 | self.addSwitch(sw_name, log_file="%s/%s.log" %(log_dir, sw_name))
19 |
20 | for host_name in host_names:
21 | host_num = int(host_name[1:])
22 |
23 | self.addHost(host_name)
24 |
25 | self._host_links[host_name] = {}
26 | host_links = [l for l in links if l[0]==host_name or l[1]==host_name]
27 |
28 | sw_idx = 0
29 | for link in host_links:
30 | sw = link[0] if link[0] != host_name else link[1]
31 | sw_num = int(sw[1:])
32 | assert sw[0]=='s', "Hosts should be connected to switches, not " + str(sw)
33 | host_ip = "10.0.%d.%d" % (sw_num, host_num)
34 | host_mac = '00:00:00:00:%02x:%02x' % (sw_num, host_num)
35 | delay_key = ''.join([host_name, sw])
36 | delay = latencies[delay_key] if delay_key in latencies else '0ms'
37 | bw = bws[delay_key] if delay_key in bws else None
38 | sw_ports[sw].append(host_name)
39 | self._host_links[host_name][sw] = dict(
40 | idx=sw_idx,
41 | host_mac = host_mac,
42 | host_ip = host_ip,
43 | sw = sw,
44 | sw_mac = "00:00:00:00:%02x:%02x" % (sw_num, host_num),
45 | sw_ip = "10.0.%d.%d" % (sw_num, 254),
46 | sw_port = sw_ports[sw].index(host_name)+1
47 | )
48 | self.addLink(host_name, sw, delay=delay, bw=bw,
49 | addr1=host_mac, addr2=self._host_links[host_name][sw]['sw_mac'])
50 | sw_idx += 1
51 |
52 | for link in links: # only check switch-switch links
53 | sw1, sw2 = link
54 | if sw1[0] != 's' or sw2[0] != 's': continue
55 |
56 | delay_key = ''.join(sorted([sw1, sw2]))
57 | delay = latencies[delay_key] if delay_key in latencies else '0ms'
58 | bw = bws[delay_key] if delay_key in bws else None
59 |
60 | self.addLink(sw1, sw2, delay=delay, bw=bw)#, max_queue_size=10)
61 | sw_ports[sw1].append(sw2)
62 | sw_ports[sw2].append(sw1)
63 |
64 | sw1_num, sw2_num = int(sw1[1:]), int(sw2[1:])
65 | sw1_port = dict(mac="00:00:00:%02x:%02x:00" % (sw1_num, sw2_num), port=sw_ports[sw1].index(sw2)+1)
66 | sw2_port = dict(mac="00:00:00:%02x:%02x:00" % (sw2_num, sw1_num), port=sw_ports[sw2].index(sw1)+1)
67 |
68 | self._sw_links[sw1][sw2] = [sw1_port, sw2_port]
69 | self._sw_links[sw2][sw1] = [sw2_port, sw1_port]
70 |
71 |
--------------------------------------------------------------------------------
/src/test/BMv2/utils/mininet/p4_mininet.py:
--------------------------------------------------------------------------------
1 | # Copyright 2013-present Barefoot Networks, Inc.
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 | #
15 |
16 | from mininet.net import Mininet
17 | from mininet.node import Switch, Host
18 | from mininet.log import setLogLevel, info, error, debug
19 | from mininet.moduledeps import pathCheck
20 | from sys import exit
21 | from time import sleep
22 | import os
23 | import tempfile
24 | import socket
25 |
26 | class P4Host(Host):
27 | def config(self, **params):
28 | r = super(P4Host, self).config(**params)
29 |
30 | for off in ["rx", "tx", "sg"]:
31 | cmd = "/sbin/ethtool --offload %s %s off" % (self.defaultIntf().name, off)
32 | self.cmd(cmd)
33 |
34 | # disable IPv6
35 | self.cmd("sysctl -w net.ipv6.conf.all.disable_ipv6=1")
36 | self.cmd("sysctl -w net.ipv6.conf.default.disable_ipv6=1")
37 | self.cmd("sysctl -w net.ipv6.conf.lo.disable_ipv6=1")
38 |
39 | return r
40 |
41 | def describe(self, sw_addr=None, sw_mac=None):
42 | print("**********")
43 | print("Network configuration for: %s" % self.name)
44 | print("Default interface: %s\t%s\t%s" %(
45 | self.defaultIntf().name,
46 | self.defaultIntf().IP(),
47 | self.defaultIntf().MAC()
48 | ))
49 | if sw_addr is not None or sw_mac is not None:
50 | print("Default route to switch: %s (%s)" % (sw_addr, sw_mac))
51 | print("**********")
52 |
53 | class P4Switch(Switch):
54 | """P4 virtual switch"""
55 | device_id = 0
56 |
57 | def __init__(self, name, sw_path = None, json_path = None,
58 | log_file = None,
59 | thrift_port = None,
60 | pcap_dump = False,
61 | log_console = False,
62 | verbose = False,
63 | device_id = None,
64 | enable_debugger = False,
65 | **kwargs):
66 | Switch.__init__(self, name, **kwargs)
67 | assert(sw_path)
68 | assert(json_path)
69 | # make sure that the provided sw_path is valid
70 | pathCheck(sw_path)
71 | # make sure that the provided JSON file exists
72 | if not os.path.isfile(json_path):
73 | error("Invalid JSON file.\n")
74 | exit(1)
75 | self.sw_path = sw_path
76 | self.json_path = json_path
77 | self.verbose = verbose
78 | self.log_file = log_file
79 | if self.log_file is None:
80 | self.log_file = "/tmp/p4s.{}.log".format(self.name)
81 | self.output = open(self.log_file, 'w')
82 | self.thrift_port = thrift_port
83 | self.pcap_dump = pcap_dump
84 | self.enable_debugger = enable_debugger
85 | self.log_console = log_console
86 | if device_id is not None:
87 | self.device_id = device_id
88 | P4Switch.device_id = max(P4Switch.device_id, device_id)
89 | else:
90 | self.device_id = P4Switch.device_id
91 | P4Switch.device_id += 1
92 | self.nanomsg = "ipc:///tmp/bm-{}-log.ipc".format(self.device_id)
93 |
94 | @classmethod
95 | def setup(cls):
96 | pass
97 |
98 | def check_switch_started(self, pid):
99 | """While the process is running (pid exists), we check if the Thrift
100 | server has been started. If the Thrift server is ready, we assume that
101 | the switch was started successfully. This is only reliable if the Thrift
102 | server is started at the end of the init process"""
103 | while True:
104 | if not os.path.exists(os.path.join("/proc", str(pid))):
105 | return False
106 | sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
107 | sock.settimeout(0.5)
108 | result = sock.connect_ex(("localhost", self.thrift_port))
109 | if result == 0:
110 | return True
111 |
112 | def start(self, controllers):
113 | "Start up a new P4 switch"
114 | info("Starting P4 switch {}.\n".format(self.name))
115 | args = [self.sw_path]
116 | for port, intf in list(self.intfs.items()):
117 | if not intf.IP():
118 | args.extend(['-i', str(port) + "@" + intf.name])
119 | if self.pcap_dump:
120 | args.append("--pcap")
121 | # args.append("--useFiles")
122 | if self.thrift_port:
123 | args.extend(['--thrift-port', str(self.thrift_port)])
124 | if self.nanomsg:
125 | args.extend(['--nanolog', self.nanomsg])
126 | args.extend(['--device-id', str(self.device_id)])
127 | P4Switch.device_id += 1
128 | args.append(self.json_path)
129 | if self.enable_debugger:
130 | args.append("--debugger")
131 | if self.log_console:
132 | args.append("--log-console")
133 | info(' '.join(args) + "\n")
134 |
135 | pid = None
136 | with tempfile.NamedTemporaryFile() as f:
137 | # self.cmd(' '.join(args) + ' > /dev/null 2>&1 &')
138 | self.cmd(' '.join(args) + ' >' + self.log_file + ' 2>&1 & echo $! >> ' + f.name)
139 | pid = int(f.read())
140 | debug("P4 switch {} PID is {}.\n".format(self.name, pid))
141 | sleep(1)
142 | if not self.check_switch_started(pid):
143 | error("P4 switch {} did not start correctly."
144 | "Check the switch log file.\n".format(self.name))
145 | exit(1)
146 | info("P4 switch {} has been started.\n".format(self.name))
147 |
148 | def stop(self):
149 | "Terminate P4 switch."
150 | self.output.flush()
151 | self.cmd('kill %' + self.sw_path)
152 | self.cmd('wait')
153 | self.deleteIntfs()
154 |
155 | def attach(self, intf):
156 | "Connect a data port"
157 | assert(0)
158 |
159 | def detach(self, intf):
160 | "Disconnect a data port"
161 | assert(0)
162 |
--------------------------------------------------------------------------------
/src/test/BMv2/utils/mininet/shortest_path.py:
--------------------------------------------------------------------------------
1 | class ShortestPath:
2 |
3 | def __init__(self, edges=[]):
4 | self.neighbors = {}
5 | for edge in edges:
6 | self.addEdge(*edge)
7 |
8 | def addEdge(self, a, b):
9 | if a not in self.neighbors: self.neighbors[a] = []
10 | if b not in self.neighbors[a]: self.neighbors[a].append(b)
11 |
12 | if b not in self.neighbors: self.neighbors[b] = []
13 | if a not in self.neighbors[b]: self.neighbors[b].append(a)
14 |
15 | def get(self, a, b, exclude=lambda node: False):
16 | # Shortest path from a to b
17 | return self._recPath(a, b, [], exclude)
18 |
19 | def _recPath(self, a, b, visited, exclude):
20 | if a == b: return [a]
21 | new_visited = visited + [a]
22 | paths = []
23 | for neighbor in self.neighbors[a]:
24 | if neighbor in new_visited: continue
25 | if exclude(neighbor) and neighbor != b: continue
26 | path = self._recPath(neighbor, b, new_visited, exclude)
27 | if path: paths.append(path)
28 |
29 | paths.sort(key=len)
30 | return [a] + paths[0] if len(paths) else None
31 |
32 | if __name__ == '__main__':
33 |
34 | edges = [
35 | (1, 2),
36 | (1, 3),
37 | (1, 5),
38 | (2, 4),
39 | (3, 4),
40 | (3, 5),
41 | (3, 6),
42 | (4, 6),
43 | (5, 6),
44 | (7, 8)
45 |
46 | ]
47 | sp = ShortestPath(edges)
48 |
49 | assert sp.get(1, 1) == [1]
50 | assert sp.get(2, 2) == [2]
51 |
52 | assert sp.get(1, 2) == [1, 2]
53 | assert sp.get(2, 1) == [2, 1]
54 |
55 | assert sp.get(1, 3) == [1, 3]
56 | assert sp.get(3, 1) == [3, 1]
57 |
58 | assert sp.get(4, 6) == [4, 6]
59 | assert sp.get(6, 4) == [6, 4]
60 |
61 | assert sp.get(2, 6) == [2, 4, 6]
62 | assert sp.get(6, 2) == [6, 4, 2]
63 |
64 | assert sp.get(1, 6) in [[1, 3, 6], [1, 5, 6]]
65 | assert sp.get(6, 1) in [[6, 3, 1], [6, 5, 1]]
66 |
67 | assert sp.get(2, 5) == [2, 1, 5]
68 | assert sp.get(5, 2) == [5, 1, 2]
69 |
70 | assert sp.get(4, 5) in [[4, 3, 5], [4, 6, 5]]
71 | assert sp.get(5, 4) in [[5, 3, 4], [6, 6, 4]]
72 |
73 | assert sp.get(7, 8) == [7, 8]
74 | assert sp.get(8, 7) == [8, 7]
75 |
76 | assert sp.get(1, 7) == None
77 | assert sp.get(7, 2) == None
78 |
79 |
--------------------------------------------------------------------------------
/src/test/BMv2/utils/mininet/single_switch_mininet.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | # Copyright 2013-present Barefoot Networks, Inc.
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 | #
17 |
18 | from mininet.net import Mininet
19 | from mininet.topo import Topo
20 | from mininet.log import setLogLevel, info
21 | from mininet.cli import CLI
22 |
23 | from p4_mininet import P4Switch, P4Host
24 |
25 | import argparse
26 | from subprocess import PIPE, Popen
27 | from time import sleep
28 |
29 | parser = argparse.ArgumentParser(description='Mininet demo')
30 | parser.add_argument('--behavioral-exe', help='Path to behavioral executable',
31 | type=str, action="store", required=True)
32 | parser.add_argument('--thrift-port', help='Thrift server port for table updates',
33 | type=int, action="store", default=9090)
34 | parser.add_argument('--num-hosts', help='Number of hosts to connect to switch',
35 | type=int, action="store", default=2)
36 | parser.add_argument('--mode', choices=['l2', 'l3'], type=str, default='l3')
37 | parser.add_argument('--json', help='Path to JSON config file',
38 | type=str, action="store", required=True)
39 | parser.add_argument('--log-file', help='Path to write the switch log file',
40 | type=str, action="store", required=False)
41 | parser.add_argument('--pcap-dump', help='Dump packets on interfaces to pcap files',
42 | type=str, action="store", required=False, default=False)
43 | parser.add_argument('--switch-config', help='simple_switch_CLI script to configure switch',
44 | type=str, action="store", required=False, default=False)
45 | parser.add_argument('--cli-message', help='Message to print before starting CLI',
46 | type=str, action="store", required=False, default=False)
47 |
48 | args = parser.parse_args()
49 |
50 |
51 | class SingleSwitchTopo(Topo):
52 | "Single switch connected to n (< 256) hosts."
53 | def __init__(self, sw_path, json_path, log_file,
54 | thrift_port, pcap_dump, n, **opts):
55 | # Initialize topology and default options
56 | Topo.__init__(self, **opts)
57 |
58 | switch = self.addSwitch('s1',
59 | sw_path = sw_path,
60 | json_path = json_path,
61 | log_console = True,
62 | log_file = log_file,
63 | thrift_port = thrift_port,
64 | enable_debugger = False,
65 | pcap_dump = pcap_dump)
66 |
67 | for h in range(n):
68 | host = self.addHost('h%d' % (h + 1),
69 | ip = "10.0.%d.10/24" % h,
70 | mac = '00:04:00:00:00:%02x' %h)
71 | print("Adding host", str(host))
72 | self.addLink(host, switch)
73 |
74 | def main():
75 | num_hosts = args.num_hosts
76 | mode = args.mode
77 |
78 | topo = SingleSwitchTopo(args.behavioral_exe,
79 | args.json,
80 | args.log_file,
81 | args.thrift_port,
82 | args.pcap_dump,
83 | num_hosts)
84 | net = Mininet(topo = topo,
85 | host = P4Host,
86 | switch = P4Switch,
87 | controller = None)
88 | net.start()
89 |
90 |
91 | sw_mac = ["00:aa:bb:00:00:%02x" % n for n in range(num_hosts)]
92 |
93 | sw_addr = ["10.0.%d.1" % n for n in range(num_hosts)]
94 |
95 | for n in range(num_hosts):
96 | h = net.get('h%d' % (n + 1))
97 | if mode == "l2":
98 | h.setDefaultRoute("dev %s" % h.defaultIntf().name)
99 | else:
100 | h.setARP(sw_addr[n], sw_mac[n])
101 | h.setDefaultRoute("dev %s via %s" % (h.defaultIntf().name, sw_addr[n]))
102 |
103 | for n in range(num_hosts):
104 | h = net.get('h%d' % (n + 1))
105 | h.describe(sw_addr[n], sw_mac[n])
106 |
107 | sleep(1)
108 |
109 | if args.switch_config is not None:
110 | print()
111 | print("Reading switch configuration script:", args.switch_config)
112 | with open(args.switch_config, 'r') as config_file:
113 | switch_config = config_file.read()
114 |
115 | print("Configuring switch...")
116 | proc = Popen(["simple_switch_CLI"], stdin=PIPE)
117 | proc.communicate(input=switch_config)
118 |
119 | print("Configuration complete.")
120 | print()
121 |
122 | print("Ready !")
123 |
124 | if args.cli_message is not None:
125 | with open(args.cli_message, 'r') as message_file:
126 | print(message_file.read())
127 |
128 | CLI( net )
129 | net.stop()
130 |
131 | if __name__ == '__main__':
132 | setLogLevel( 'info' )
133 | main()
134 |
--------------------------------------------------------------------------------
/src/test/BMv2/utils/netstat.py:
--------------------------------------------------------------------------------
1 | # Copyright 2017-present Open Networking Foundation
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 | #
15 |
16 | import psutil
17 | def check_listening_on_port(port):
18 | for c in psutil.net_connections(kind='inet'):
19 | if c.status == 'LISTEN' and c.laddr[1] == port:
20 | return True
21 | return False
22 |
--------------------------------------------------------------------------------
/src/test/BMv2/utils/p4_mininet.py:
--------------------------------------------------------------------------------
1 | # Copyright 2013-present Barefoot Networks, Inc.
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 | #
15 |
16 | from mininet.net import Mininet
17 | from mininet.node import Switch, Host
18 | from mininet.log import setLogLevel, info, error, debug
19 | from mininet.moduledeps import pathCheck
20 | from sys import exit
21 | import os
22 | import tempfile
23 | import socket
24 | from time import sleep
25 |
26 | from netstat import check_listening_on_port
27 |
28 | SWITCH_START_TIMEOUT = 10 # seconds
29 |
30 | class P4Host(Host):
31 | def config(self, **params):
32 | r = super(Host, self).config(**params)
33 |
34 | self.defaultIntf().rename("eth0")
35 |
36 | for off in ["rx", "tx", "sg"]:
37 | cmd = "/sbin/ethtool --offload eth0 %s off" % off
38 | self.cmd(cmd)
39 |
40 | # disable IPv6
41 | self.cmd("sysctl -w net.ipv6.conf.all.disable_ipv6=1")
42 | self.cmd("sysctl -w net.ipv6.conf.default.disable_ipv6=1")
43 | self.cmd("sysctl -w net.ipv6.conf.lo.disable_ipv6=1")
44 |
45 | return r
46 |
47 | def describe(self):
48 | print("**********")
49 | print(self.name)
50 | print("default interface: %s\t%s\t%s" %(
51 | self.defaultIntf().name,
52 | self.defaultIntf().IP(),
53 | self.defaultIntf().MAC()
54 | ))
55 | print("**********")
56 |
57 | class P4Switch(Switch):
58 | """P4 virtual switch"""
59 | device_id = 0
60 |
61 | def __init__(self, name, sw_path = None, json_path = None,
62 | thrift_port = None,
63 | pcap_dump = False,
64 | log_console = False,
65 | log_file = None,
66 | verbose = False,
67 | device_id = None,
68 | enable_debugger = False,
69 | **kwargs):
70 | Switch.__init__(self, name, **kwargs)
71 | assert(sw_path)
72 | assert(json_path)
73 | # make sure that the provided sw_path is valid
74 | pathCheck(sw_path)
75 | # make sure that the provided JSON file exists
76 | if not os.path.isfile(json_path):
77 | error("Invalid JSON file.\n")
78 | exit(1)
79 | self.sw_path = sw_path
80 | self.json_path = json_path
81 | self.verbose = verbose
82 | logfile = "/tmp/p4s.{}.log".format(self.name)
83 | self.output = open(logfile, 'w')
84 | self.thrift_port = thrift_port
85 | if check_listening_on_port(self.thrift_port):
86 | error('%s cannot bind port %d because it is bound by another process\n' % (self.name, self.grpc_port))
87 | exit(1)
88 | self.pcap_dump = pcap_dump
89 | self.enable_debugger = enable_debugger
90 | self.log_console = log_console
91 | if log_file is not None:
92 | self.log_file = log_file
93 | else:
94 | self.log_file = "/tmp/p4s.{}.log".format(self.name)
95 | if device_id is not None:
96 | self.device_id = device_id
97 | P4Switch.device_id = max(P4Switch.device_id, device_id)
98 | else:
99 | self.device_id = P4Switch.device_id
100 | P4Switch.device_id += 1
101 | self.nanomsg = "ipc:///tmp/bm-{}-log.ipc".format(self.device_id)
102 |
103 | @classmethod
104 | def setup(cls):
105 | pass
106 |
107 | def check_switch_started(self, pid):
108 | """While the process is running (pid exists), we check if the Thrift
109 | server has been started. If the Thrift server is ready, we assume that
110 | the switch was started successfully. This is only reliable if the Thrift
111 | server is started at the end of the init process"""
112 | while True:
113 | if not os.path.exists(os.path.join("/proc", str(pid))):
114 | return False
115 | if check_listening_on_port(self.thrift_port):
116 | return True
117 | sleep(0.5)
118 |
119 | def start(self, controllers):
120 | "Start up a new P4 switch"
121 | info("Starting P4 switch {}.\n".format(self.name))
122 | args = [self.sw_path]
123 | for port, intf in list(self.intfs.items()):
124 | if not intf.IP():
125 | args.extend(['-i', str(port) + "@" + intf.name])
126 | if self.pcap_dump:
127 | args.append("--pcap %s" % self.pcap_dump)
128 | if self.thrift_port:
129 | args.extend(['--thrift-port', str(self.thrift_port)])
130 | if self.nanomsg:
131 | args.extend(['--nanolog', self.nanomsg])
132 | args.extend(['--device-id', str(self.device_id)])
133 | P4Switch.device_id += 1
134 | args.append(self.json_path)
135 | if self.enable_debugger:
136 | args.append("--debugger")
137 | if self.log_console:
138 | args.append("--log-console")
139 | info(' '.join(args) + "\n")
140 |
141 | pid = None
142 | with tempfile.NamedTemporaryFile() as f:
143 | # self.cmd(' '.join(args) + ' > /dev/null 2>&1 &')
144 | self.cmd(' '.join(args) + ' >' + self.log_file + ' 2>&1 & echo $! >> ' + f.name)
145 | pid = int(f.read())
146 | debug("P4 switch {} PID is {}.\n".format(self.name, pid))
147 | if not self.check_switch_started(pid):
148 | error("P4 switch {} did not start correctly.\n".format(self.name))
149 | exit(1)
150 | info("P4 switch {} has been started.\n".format(self.name))
151 |
152 | def stop(self):
153 | "Terminate P4 switch."
154 | self.output.flush()
155 | self.cmd('kill %' + self.sw_path)
156 | self.cmd('wait')
157 | self.deleteIntfs()
158 |
159 | def attach(self, intf):
160 | "Connect a data port"
161 | assert(0)
162 |
163 | def detach(self, intf):
164 | "Disconnect a data port"
165 | assert(0)
166 |
--------------------------------------------------------------------------------
/src/test/BMv2/utils/p4_program.py:
--------------------------------------------------------------------------------
1 | import os
2 | from p4app_util import run_command
3 |
4 | class P4Program:
5 |
6 | def __init__(self, prog_filename, version=16, compile_flags=[]):
7 | self.prog_filename = os.path.join('/p4app', prog_filename)
8 |
9 | assert isinstance(version, str) or isinstance(version, int)
10 | if version in [14, '14', 'P4_14']:
11 | self.version = 14
12 | elif version in [16, '16', 'P4_16']:
13 | self.version = 16
14 | else:
15 | raise Exception("Unrecognized P4 version: " + str(version))
16 |
17 | self.compile_flags = compile_flags
18 | assert isinstance(compile_flags, list)
19 | self._json_path = None
20 | self._p4info_path = None
21 |
22 | def name(self):
23 | return os.path.basename(self.prog_filename).rstrip('.p4')
24 |
25 | def compile(self):
26 | compiler_args = []
27 |
28 | compiler_args.append('--std p4-%d' % self.version)
29 |
30 | compiler_args.extend(self.compile_flags)
31 |
32 | # Compile the program.
33 | self._json_path = os.path.join('/tmp/p4app-logs', self.name() + '.json')
34 | compiler_args.append('"%s"' % self.prog_filename)
35 | compiler_args.append('-o "%s"' % self._json_path)
36 | if self.supportsP4Runtime():
37 | self._p4info_path = os.path.join('/tmp/p4app-logs', self.name() + '.p4info.txt')
38 | compiler_args.append('--p4runtime-files "%s"' % self._p4info_path)
39 | rv = run_command('p4c-bm2-ss %s' % ' '.join(compiler_args))
40 |
41 | if rv != 0:
42 | raise Exception("Compile failed. Compiler return value: %d" % rv)
43 |
44 | def json(self):
45 | if self._json_path is None:
46 | self.compile()
47 | return self._json_path
48 |
49 | def p4info(self):
50 | if not self.supportsP4Runtime(): return None
51 | if self._p4info_path is None:
52 | self.compile()
53 | return self._p4info_path
54 |
55 | def supportsP4Runtime(self):
56 | return self.version == 16
57 |
--------------------------------------------------------------------------------
/src/test/BMv2/utils/p4app_util.py:
--------------------------------------------------------------------------------
1 | from __future__ import print_function
2 | import os
3 |
4 | def log(*items):
5 | print(*items)
6 |
7 | def log_error(*items):
8 | print(*items, file=sys.stderr)
9 |
10 | def run_command(command):
11 | log('>', command)
12 | return os.WEXITSTATUS(os.system(command))
13 |
14 |
--------------------------------------------------------------------------------
/src/test/BMv2/utils/p4runtime_lib/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/In-Network-Machine-Learning/DINC/9f0b89dd239a097954fb0d302c45be23f7b53ad2/src/test/BMv2/utils/p4runtime_lib/__init__.py
--------------------------------------------------------------------------------
/src/test/BMv2/utils/p4runtime_lib/bmv2.py:
--------------------------------------------------------------------------------
1 | # Copyright 2017-present Open Networking Foundation
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 | #
15 | from . import switch
16 | from .switch import SwitchConnection
17 | from p4.tmp import p4config_pb2
18 |
19 |
20 | def buildDeviceConfig(bmv2_json_file_path=None):
21 | "Builds the device config for BMv2"
22 | device_config = p4config_pb2.P4DeviceConfig()
23 | device_config.reassign = True
24 | with open(bmv2_json_file_path) as f:
25 | device_config.device_data = f.read().encode('utf-8')
26 | return device_config
27 |
28 |
29 | class Bmv2SwitchConnection(SwitchConnection):
30 | def buildDeviceConfig(self, **kwargs):
31 | return buildDeviceConfig(**kwargs)
32 |
--------------------------------------------------------------------------------
/src/test/BMv2/utils/p4runtime_lib/convert-modified.py:
--------------------------------------------------------------------------------
1 | # Copyright 2017-present Open Networking Foundation
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 | #
15 | import re
16 | import socket
17 |
18 | import math
19 |
20 | '''
21 | This package contains several helper functions for encoding to and decoding from byte strings:
22 | - integers
23 | - IPv4 address strings
24 | - Ethernet address strings
25 | '''
26 |
27 | mac_pattern = re.compile('^([\da-fA-F]{2}:){5}([\da-fA-F]{2})$')
28 | def matchesMac(mac_addr_string):
29 | return mac_pattern.match(mac_addr_string) is not None
30 |
31 | def encodeMac(mac_addr_string):
32 | return bytes.fromhex(mac_addr_string.replace(':', ''))
33 |
34 | def decodeMac(encoded_mac_addr):
35 | return ':'.join(s.hex() for s in encoded_mac_addr)
36 |
37 | ip_pattern = re.compile('^(\d{1,3}\.){3}(\d{1,3})$')
38 | def matchesIPv4(ip_addr_string):
39 | return ip_pattern.match(ip_addr_string) is not None
40 |
41 | def encodeIPv4(ip_addr_string):
42 | return socket.inet_aton(ip_addr_string)
43 |
44 | def decodeIPv4(encoded_ip_addr):
45 | return socket.inet_ntoa(encoded_ip_addr)
46 |
47 | def bitwidthToBytes(bitwidth):
48 | return int(math.ceil(bitwidth / 8.0))
49 |
50 | def encodeNum(number, bitwidth):
51 | byte_len = bitwidthToBytes(bitwidth)
52 | num_str = '%x' % number
53 | print (number)
54 | if number >= 2 ** bitwidth:
55 | raise Exception("Number, %d, does not fit in %d bits" % (number, bitwidth))
56 | return ('0' * (byte_len * 2 - len(num_str)) + num_str).encode()#.decode('hex')
57 |
58 | def decodeNum(encoded_number):
59 | return int(encoded_number.encode('hex'), 16)
60 |
61 | def encode(x, bitwidth):
62 | 'Tries to infer the type of `x` and encode it'
63 | byte_len = bitwidthToBytes(bitwidth)
64 | if (type(x) == list or type(x) == tuple) and len(x) == 1:
65 | x = x[0]
66 | encoded_bytes = None
67 | if type(x) == str:
68 | if matchesMac(x):
69 | encoded_bytes = encodeMac(x)
70 | elif matchesIPv4(x):
71 | encoded_bytes = encodeIPv4(x)
72 | else:
73 | # Assume that the string is already encoded
74 | encoded_bytes = x
75 | elif type(x) == int:
76 | encoded_bytes = encodeNum(x, bitwidth)
77 | print ("Convert the entered valus to hexadecimal: ", encoded_bytes)
78 | print ("Length after encoding: ", len(encoded_bytes))
79 | print ("Length of the header", byte_len)
80 | else:
81 | raise Exception("Encoding objects of %r is not supported" % type(x))
82 | assert(len(encoded_bytes) == byte_len)
83 | return encoded_bytes
84 |
85 |
86 | if __name__ == '__main__':
87 | # TODO These tests should be moved out of main eventually
88 | mac = "aa:bb:cc:dd:ee:ff"
89 | enc_mac = encodeMac(mac)
90 | assert(enc_mac == '\xaa\xbb\xcc\xdd\xee\xff')
91 | dec_mac = decodeMac(enc_mac)
92 | assert(mac == dec_mac)
93 |
94 | ip = "10.0.0.1"
95 | enc_ip = encodeIPv4(ip)
96 | assert(enc_ip == '\x0a\x00\x00\x01')
97 | dec_ip = decodeIPv4(enc_ip)
98 | assert(ip == dec_ip)
99 |
100 | num = 1337
101 | byte_len = 5
102 | enc_num = encodeNum(num, byte_len * 8)
103 | assert(enc_num == '\x00\x00\x00\x05\x39')
104 | dec_num = decodeNum(enc_num)
105 | assert(num == dec_num)
106 |
107 | assert(matchesIPv4('10.0.0.1'))
108 | assert(not matchesIPv4('10.0.0.1.5'))
109 | assert(not matchesIPv4('1000.0.0.1'))
110 | assert(not matchesIPv4('10001'))
111 |
112 | assert(encode(mac, 6 * 8) == enc_mac)
113 | assert(encode(ip, 4 * 8) == enc_ip)
114 | assert(encode(num, 5 * 8) == enc_num)
115 | assert(encode((num,), 5 * 8) == enc_num)
116 | assert(encode([num], 5 * 8) == enc_num)
117 |
118 | num = 256
119 | byte_len = 2
120 | try:
121 | enc_num = encodeNum(num, 8)
122 | raise Exception("expected exception")
123 | except Exception as e:
124 | print(e)
125 |
--------------------------------------------------------------------------------
/src/test/BMv2/utils/p4runtime_lib/convert.py:
--------------------------------------------------------------------------------
1 | # Copyright 2017-present Open Networking Foundation
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 | #
15 | import re
16 | import socket
17 |
18 | import math
19 |
20 | '''
21 | This package contains several helper functions for encoding to and decoding from byte strings:
22 | - integers
23 | - IPv4 address strings
24 | - Ethernet address strings
25 | '''
26 |
27 | mac_pattern = re.compile('^([\da-fA-F]{2}:){5}([\da-fA-F]{2})$')
28 | def matchesMac(mac_addr_string):
29 | return mac_pattern.match(mac_addr_string) is not None
30 |
31 | def encodeMac(mac_addr_string):
32 | return bytes.fromhex(mac_addr_string.replace(':', ''))
33 |
34 | def decodeMac(encoded_mac_addr):
35 | return ':'.join(s.hex() for s in encoded_mac_addr)
36 |
37 | ip_pattern = re.compile('^(\d{1,3}\.){3}(\d{1,3})$')
38 | def matchesIPv4(ip_addr_string):
39 | return ip_pattern.match(ip_addr_string) is not None
40 |
41 | def encodeIPv4(ip_addr_string):
42 | return socket.inet_aton(ip_addr_string)
43 |
44 | def decodeIPv4(encoded_ip_addr):
45 | return socket.inet_ntoa(encoded_ip_addr)
46 |
47 | def bitwidthToBytes(bitwidth):
48 | return int(math.ceil(bitwidth / 8.0))
49 |
50 | def encodeNum(number, bitwidth):
51 | byte_len = bitwidthToBytes(bitwidth)
52 | num_str = '%x' % number
53 | if number >= 2 ** bitwidth:
54 | raise Exception("Number, %d, does not fit in %d bits" % (number, bitwidth))
55 | return bytes.fromhex('0' * (byte_len * 2 - len(num_str)) + num_str)
56 |
57 | def decodeNum(encoded_number):
58 | return int(encoded_number.hex(), 16)
59 |
60 | def encode(x, bitwidth):
61 | 'Tries to infer the type of `x` and encode it'
62 | byte_len = bitwidthToBytes(bitwidth)
63 | if (type(x) == list or type(x) == tuple) and len(x) == 1:
64 | x = x[0]
65 | encoded_bytes = None
66 | if type(x) == str:
67 | if matchesMac(x):
68 | encoded_bytes = encodeMac(x)
69 | # print("x1 ", x)
70 | elif matchesIPv4(x):
71 | encoded_bytes = encodeIPv4(x)
72 | # print("x2 ", x)
73 | else:
74 | # Assume that the string is already encoded
75 | encoded_bytes = x
76 | # print("x3 ", x)
77 | elif type(x) == int:
78 | encoded_bytes = encodeNum(x, bitwidth)
79 | # print("x4 ", x)
80 | else:
81 | raise Exception("Encoding objects of %r is not supported" % type(x))
82 |
83 | # print ("Convert the entered valus to hexadecimal: ", encoded_bytes)
84 | # print ("Length after encoding: ", len(encoded_bytes))
85 | # print ("Length of the header", byte_len)
86 | assert(len(encoded_bytes) == byte_len)
87 | return encoded_bytes
88 |
89 | if __name__ == '__main__':
90 | # TODO These tests should be moved out of main eventually
91 | mac = "aa:bb:cc:dd:ee:ff"
92 | enc_mac = encodeMac(mac)
93 | assert(enc_mac == '\xaa\xbb\xcc\xdd\xee\xff')
94 | dec_mac = decodeMac(enc_mac)
95 | assert(mac == dec_mac)
96 |
97 | ip = "10.0.0.1"
98 | enc_ip = encodeIPv4(ip)
99 | assert(enc_ip == '\x0a\x00\x00\x01')
100 | dec_ip = decodeIPv4(enc_ip)
101 | assert(ip == dec_ip)
102 |
103 | num = 1337
104 | byte_len = 5
105 | enc_num = encodeNum(num, byte_len * 8)
106 | assert(enc_num == '\x00\x00\x00\x05\x39')
107 | dec_num = decodeNum(enc_num)
108 | assert(num == dec_num)
109 |
110 | assert(matchesIPv4('10.0.0.1'))
111 | assert(not matchesIPv4('10.0.0.1.5'))
112 | assert(not matchesIPv4('1000.0.0.1'))
113 | assert(not matchesIPv4('10001'))
114 |
115 | assert(encode(mac, 6 * 8) == enc_mac)
116 | assert(encode(ip, 4 * 8) == enc_ip)
117 | assert(encode(num, 5 * 8) == enc_num)
118 | assert(encode((num,), 5 * 8) == enc_num)
119 | assert(encode([num], 5 * 8) == enc_num)
120 |
121 | num = 256
122 | byte_len = 2
123 | try:
124 | enc_num = encodeNum(num, 8)
125 | raise Exception("expected exception")
126 | except Exception as e:
127 | print(e)
128 |
--------------------------------------------------------------------------------
/src/test/BMv2/utils/p4runtime_lib/error_utils.py:
--------------------------------------------------------------------------------
1 | # Copyright 2013-present Barefoot Networks, Inc.
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 | #
15 |
16 | import sys
17 |
18 | from google.rpc import status_pb2, code_pb2
19 | import grpc
20 | from p4.v1 import p4runtime_pb2
21 | from p4.v1 import p4runtime_pb2_grpc
22 |
23 | # Used to indicate that the gRPC error Status object returned by the server has
24 | # an incorrect format.
25 | class P4RuntimeErrorFormatException(Exception):
26 | def __init__(self, message):
27 | super(P4RuntimeErrorFormatException, self).__init__(message)
28 |
29 |
30 | # Parse the binary details of the gRPC error. This is required to print some
31 | # helpful debugging information in tha case of batched Write / Read
32 | # requests. Returns None if there are no useful binary details and throws
33 | # P4RuntimeErrorFormatException if the error is not formatted
34 | # properly. Otherwise, returns a list of tuples with the first element being the
35 | # index of the operation in the batch that failed and the second element being
36 | # the p4.Error Protobuf message.
37 | def parseGrpcErrorBinaryDetails(grpc_error):
38 | if grpc_error.code() != grpc.StatusCode.UNKNOWN:
39 | return None
40 |
41 | error = None
42 | # The gRPC Python package does not have a convenient way to access the
43 | # binary details for the error: they are treated as trailing metadata.
44 | for meta in grpc_error.trailing_metadata():
45 | if meta[0] == "grpc-status-details-bin":
46 | error = status_pb2.Status()
47 | error.ParseFromString(meta[1])
48 | break
49 | if error is None: # no binary details field
50 | return None
51 | if len(error.details) == 0:
52 | # binary details field has empty Any details repeated field
53 | return None
54 |
55 | indexed_p4_errors = []
56 | for idx, one_error_any in enumerate(error.details):
57 | p4_error = p4runtime_pb2.Error()
58 | if not one_error_any.Unpack(p4_error):
59 | raise P4RuntimeErrorFormatException(
60 | "Cannot convert Any message to p4.Error")
61 | if p4_error.canonical_code == code_pb2.OK:
62 | continue
63 | indexed_p4_errors += [(idx, p4_error)]
64 |
65 | return indexed_p4_errors
66 |
67 |
68 | # P4Runtime uses a 3-level message in case of an error during the processing of
69 | # a write batch. This means that some care is required when printing the
70 | # exception if we do not want to end-up with a non-helpful message in case of
71 | # failure as only the first level will be printed. In this function, we extract
72 | # the nested error message when present (one for each operation included in the
73 | # batch) in order to print error code + user-facing message. See P4Runtime
74 | # documentation for more details on error-reporting.
75 | def printGrpcError(grpc_error):
76 | print("gRPC Error", grpc_error.details(), end=' ')
77 | status_code = grpc_error.code()
78 | print("({})".format(status_code.name), end=' ')
79 | traceback = sys.exc_info()[2]
80 | print("[{}:{}]".format(
81 | traceback.tb_frame.f_code.co_filename, traceback.tb_lineno))
82 | if status_code != grpc.StatusCode.UNKNOWN:
83 | return
84 | p4_errors = parseGrpcErrorBinaryDetails(grpc_error)
85 | if p4_errors is None:
86 | return
87 | print("Errors in batch:")
88 | for idx, p4_error in p4_errors:
89 | code_name = code_pb2._CODE.values_by_number[
90 | p4_error.canonical_code].name
91 | print("\t* At index {}: {}, '{}'\n".format(
92 | idx, code_name, p4_error.message))
93 |
--------------------------------------------------------------------------------
/src/test/BMv2/utils/p4runtime_switch.py:
--------------------------------------------------------------------------------
1 | # Copyright 2017-present Barefoot Networks, Inc.
2 | # Copyright 2017-present Open Networking Foundation
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License");
5 | # you may not use this file except in compliance with the License.
6 | # You may obtain a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 | #
16 |
17 | import sys, os, tempfile, socket
18 | from time import sleep
19 |
20 | from mininet.node import Switch
21 | from mininet.moduledeps import pathCheck
22 | from mininet.log import info, error, debug
23 |
24 | from p4_mininet import P4Switch, SWITCH_START_TIMEOUT
25 | from netstat import check_listening_on_port
26 |
27 | class P4RuntimeSwitch(P4Switch):
28 | "BMv2 switch with gRPC support"
29 | next_grpc_port = 50051
30 | next_thrift_port = 9090
31 |
32 | def __init__(self, name, sw_path = None, json_path = None,
33 | grpc_port = None,
34 | thrift_port = None,
35 | pcap_dump = False,
36 | log_console = False,
37 | verbose = False,
38 | device_id = None,
39 | enable_debugger = False,
40 | log_file = None,
41 | **kwargs):
42 | Switch.__init__(self, name, **kwargs)
43 | assert (sw_path)
44 | self.sw_path = sw_path
45 | # make sure that the provided sw_path is valid
46 | pathCheck(sw_path)
47 |
48 | if json_path is not None:
49 | # make sure that the provided JSON file exists
50 | if not os.path.isfile(json_path):
51 | error("Invalid JSON file: {}\n".format(json_path))
52 | exit(1)
53 | self.json_path = json_path
54 | else:
55 | self.json_path = None
56 |
57 | if grpc_port is not None:
58 | self.grpc_port = grpc_port
59 | else:
60 | self.grpc_port = P4RuntimeSwitch.next_grpc_port
61 | P4RuntimeSwitch.next_grpc_port += 1
62 |
63 | if thrift_port is not None:
64 | self.thrift_port = thrift_port
65 | else:
66 | self.thrift_port = P4RuntimeSwitch.next_thrift_port
67 | P4RuntimeSwitch.next_thrift_port += 1
68 |
69 | if check_listening_on_port(self.grpc_port):
70 | error('%s cannot bind port %d because it is bound by another process\n' % (self.name, self.grpc_port))
71 | exit(1)
72 |
73 | self.verbose = verbose
74 | logfile = "/tmp/p4s.{}.log".format(self.name)
75 | self.output = open(logfile, 'w')
76 | self.pcap_dump = pcap_dump
77 | self.enable_debugger = enable_debugger
78 | self.log_console = log_console
79 | if log_file is not None:
80 | self.log_file = log_file
81 | else:
82 | self.log_file = "/tmp/p4s.{}.log".format(self.name)
83 | if device_id is not None:
84 | self.device_id = device_id
85 | P4Switch.device_id = max(P4Switch.device_id, device_id)
86 | else:
87 | self.device_id = P4Switch.device_id
88 | P4Switch.device_id += 1
89 | self.nanomsg = "ipc:///tmp/bm-{}-log.ipc".format(self.device_id)
90 |
91 |
92 | def check_switch_started(self, pid):
93 | for _ in range(SWITCH_START_TIMEOUT * 2):
94 | if not os.path.exists(os.path.join("/proc", str(pid))):
95 | return False
96 | if check_listening_on_port(self.grpc_port):
97 | return True
98 | sleep(0.5)
99 |
100 | def start(self, controllers):
101 | info("Starting P4 switch {}.\n".format(self.name))
102 | args = [self.sw_path]
103 | for port, intf in list(self.intfs.items()):
104 | if not intf.IP():
105 | args.extend(['-i', str(port) + "@" + intf.name])
106 | if self.pcap_dump:
107 | args.append("--pcap %s" % self.pcap_dump)
108 | if self.nanomsg:
109 | args.extend(['--nanolog', self.nanomsg])
110 | args.extend(['--device-id', str(self.device_id)])
111 | P4Switch.device_id += 1
112 | if self.json_path:
113 | args.append(self.json_path)
114 | else:
115 | args.append("--no-p4")
116 | if self.enable_debugger:
117 | args.append("--debugger")
118 | if self.log_console:
119 | args.append("--log-console")
120 | if self.thrift_port:
121 | args.append('--thrift-port ' + str(self.thrift_port))
122 | if self.grpc_port:
123 | args.append("-- --grpc-server-addr 0.0.0.0:" + str(self.grpc_port))
124 | cmd = ' '.join(args)
125 | info(cmd + "\n")
126 |
127 |
128 | pid = None
129 | with tempfile.NamedTemporaryFile() as f:
130 | self.cmd(cmd + ' >' + self.log_file + ' 2>&1 & echo $! >> ' + f.name)
131 | pid = int(f.read())
132 | debug("P4 switch {} PID is {}.\n".format(self.name, pid))
133 | if not self.check_switch_started(pid):
134 | error("P4 switch {} did not start correctly.\n".format(self.name))
135 | exit(1)
136 | info("P4 switch {} has been started.\n".format(self.name))
137 |
138 |
--------------------------------------------------------------------------------