To add your own in-network ML algorithm, there are two things to be considered, which are P4 file generation and M/A table entries generation. The main procedure can be generalized into creating a <model_name> folder under the directory ./src/models. Then, in the model folder, create a variation folder, e.g., Type_n. In the Type_n folder, create dedicated_p4.py file for model training and conversion, and table_generator.py for generating the model related tables. The following is a detailed explanation.
In table_generator.py, there are two compulsory functions to be written, run_model(*) & test_tables(*):
- The overview of
run_model(*)functiondef run_model(train_X, train_y, test_X, test_y, used_features): # 1. Model Training # 2. Model Testing # 3. Model Conversion (M/A table entries generation). return sklearn_test_y - The input of
run_model(*)functiontrain_X # data frame/ndarray/list # training data # generate from <dataset_name>_dataset.py train_y # data frame/ndarray/list # the training labels # generate from <dataset_name>_dataset.py test_X # data frame/ndarray/list # testing data # generate from <dataset_name>_dataset.py test_y # data frame/ndarray/list # testing labels # generate from <dataset_name>_dataset.py used_features # int, # number of used features # input in Planter.py - The output (return) of
run_model(*)functionsklearn_test_y # data frame/ndarray/list # sklearn (baseline) inference result (output labels)
- The overview of
test_tables(*)functiondef test_tables(sklearn_test_y, test_X, test_y): # 1. Test the generated M/A table entries based on the pipeline # logic. return - The input of
test_tables(*)functionsklearn_test_y # data frame/ndarray/list # sklearn (baseline) inference result (output labels) # generated by funtion test_tables(*) test_X # data frame/ndarray/list # testing data # generate from <dataset_name>_dataset.py test_y # data frame/ndarray/list # testing labels # generate from <dataset_name>_dataset.py
In dedicated_p4.py, we can define functions to write M/A pipeline logic into P4 files. This file requires some key functions:
- The overview of
load_config(*)functiondef load_config(fname): # 1. load the config files. return config, Planter_config - The input of
load_config(*)functionfname # str # config file directory # generate from p4_generator.py - The output (return) of
load_config(*)functionconfig # dict # P4 generator's configs - Planter_config['p4 config'] Planter_config # dict # Planter's standard configs
- The overview of
add_model_intro(*)functiondef add_model_intro(fname, config): # 1. Write intro (header in comment format) in P4 files. with open(fname, 'a') as intro: intro.write("// ...\n") return - The input of
add_model_intro(*)functionfname # str # P4 file directory # generate from p4_generator.py config # dict # P4 generator's configs - Planter_config['p4 config'] # generated by function load_config(*)
- The overview of
separate_metadata(*)functiondef separate_metadata(fname, config): # 1. Write model related meta data. with open(fname, 'a') as file: file.write("...\n") return - The input of
separate_metadata(*)functionfname # str # P4 file directory # generate from p4_generator.py config # dict # P4 generator's configs - Planter_config['p4 config'] # generated by function load_config(*)
- The overview of
separate_logics(*)functiondef separate_logics(fname, config): # 1. Write model related apply() logic in ingress pipeline. with open(fname, 'a') as file: file.write("...\n") return - The input of
separate_logics(*)functionfname # str # P4 file directory # generate from p4_generator.py config # dict # P4 generator's configs - Planter_config['p4 config'] # generated by function load_config(*)
- The overview of
separate_tables(*)functiondef separate_tables(fname, config): # 1. Write model related tables, actions, and definitions in ingress. with open(fname, 'a') as file: file.write("...\n") return - The input of
separate_tables(*)functionfname # str # P4 file directory # generate from p4_generator.py config # dict # P4 generator's configs - Planter_config['p4 config'] # generated by function load_config(*)
- The overview of
create_load_tables(*)functiondef create_load_tables(fname, fjson, config, Planter_config, file_name): # 1. Prepare load data files for bfrt. # varies from different targets return - The input of
create_load_tables(*)functionfname # str # P4 file directory # generate from p4_generator.py fjson # str # M/A table file directory # generate from p4_generator.py config # dict # P4 generator's configs - Planter_config['p4 config'] # generated by function load_config(*) Planter_config # dict # Planter's standard configs # generate from anywhere file_name # str # P4 file name # generate from p4_generator.py
