Skip to content

Commit

Permalink
[SAI-PTF] Convert generated enum code from ctypesgen into pythoon enu…
Browse files Browse the repository at this point in the history
…m class

why
When ctypesgen generated the python code for c++ enum, the python cannot be logged by it enum name, we need to change it to enum class.
the code like
```C++
/**
 * @brief SAI common API type
 */
typedef enum _sai_common_api_t
{
    SAI_COMMON_API_CREATE      = 0,
    SAI_COMMON_API_REMOVE      = 1,
    SAI_COMMON_API_SET         = 2,
    SAI_COMMON_API_GET         = 3,
    SAI_COMMON_API_BULK_CREATE = 4,
    SAI_COMMON_API_BULK_REMOVE = 5,
    SAI_COMMON_API_BULK_SET    = 6,
    SAI_COMMON_API_BULK_GET    = 7,
    SAI_COMMON_API_MAX         = 8,
} sai_common_api_t;
```
original converted by ctypesgen
```
enum__sai_common_api_t = c_int# /usr/include/sai/saitypes.h: 183

SAI_COMMON_API_CREATE = 0# /usr/include/sai/saitypes.h: 183

SAI_COMMON_API_REMOVE = 1# /usr/include/sai/saitypes.h: 183

SAI_COMMON_API_SET = 2# /usr/include/sai/saitypes.h: 183

SAI_COMMON_API_GET = 3# /usr/include/sai/saitypes.h: 183

SAI_COMMON_API_BULK_CREATE = 4# /usr/include/sai/saitypes.h: 183

SAI_COMMON_API_BULK_REMOVE = 5# /usr/include/sai/saitypes.h: 183

SAI_COMMON_API_BULK_SET = 6# /usr/include/sai/saitypes.h: 183

SAI_COMMON_API_BULK_GET = 7# /usr/include/sai/saitypes.h: 183

SAI_COMMON_API_MAX = 8# /usr/include/sai/saitypes.h: 183

sai_common_api_t = enum__sai_common_api_t# /usr/include/sai/saitypes.h: 183

enum__sai_object_type_t = c_int# /usr/include/sai/saitypes.h: 294
```
new code
```
class sai_common_api(SAIEnum):

    SAI_COMMON_API_CREATE = 0# /usr/include/sai/saitypes.h: 183

    SAI_COMMON_API_REMOVE = 1# /usr/include/sai/saitypes.h: 183

    SAI_COMMON_API_SET = 2# /usr/include/sai/saitypes.h: 183

    SAI_COMMON_API_GET = 3# /usr/include/sai/saitypes.h: 183

    SAI_COMMON_API_BULK_CREATE = 4# /usr/include/sai/saitypes.h: 183

    SAI_COMMON_API_BULK_REMOVE = 5# /usr/include/sai/saitypes.h: 183

    SAI_COMMON_API_BULK_SET = 6# /usr/include/sai/saitypes.h: 183

    SAI_COMMON_API_BULK_GET = 7# /usr/include/sai/saitypes.h: 183

    SAI_COMMON_API_MAX = 8# /usr/include/sai/saitypes.h: 183

SAI_COMMON_API_CREATE = sai_common_api.SAI_COMMON_API_CREATE
SAI_COMMON_API_REMOVE = sai_common_api.SAI_COMMON_API_REMOVE
SAI_COMMON_API_SET = sai_common_api.SAI_COMMON_API_SET
SAI_COMMON_API_GET = sai_common_api.SAI_COMMON_API_GET
SAI_COMMON_API_BULK_CREATE = sai_common_api.SAI_COMMON_API_BULK_CREATE
SAI_COMMON_API_BULK_REMOVE = sai_common_api.SAI_COMMON_API_BULK_REMOVE
SAI_COMMON_API_BULK_SET = sai_common_api.SAI_COMMON_API_BULK_SET
SAI_COMMON_API_BULK_GET = sai_common_api.SAI_COMMON_API_BULK_GET
SAI_COMMON_API_MAX = sai_common_api.SAI_COMMON_API_MAX
```

how
Convert the python code after generated from ctypesgen

verify
pipeline
local testing

Signed-off-by: richardyu-ms <richard.yu@microsoft.com>
  • Loading branch information
richardyu-ms committed Feb 24, 2023
1 parent f12d9e3 commit 8fda361
Show file tree
Hide file tree
Showing 3 changed files with 149 additions and 1 deletion.
3 changes: 2 additions & 1 deletion meta/templates/sai_adapter_utils.tt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ from functools import wraps
[%- BLOCK invocation_logger_imports %]
import inspect
import logging
from functools import wraps
[% END -%]

[%- ######################################################################## -%]
Expand Down Expand Up @@ -180,7 +181,7 @@ def invocation_logger(func):
SAI interface invocation logger.
Use it to log all the invocated method in this sai_adapater.
"""

@wraps(func)
def inner_logger(*args, **kwargs):

args_name = inspect.getargspec(func)[0]
Expand Down
3 changes: 3 additions & 0 deletions test/saithriftv2/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,9 @@ $(PY_SOURCES): $(METADIR)sai.thrift

$(SAI_PY_HEADERS): $(SAI_HEADERS)
$(CTYPESGEN) --output-language=py32 -I/usr/include -I$(SAI_HEADER_DIR) -I../../experimental --include /usr/include/linux/limits.h $^ -o $@
python3 convert_header.py -i $(SAI_PY_HEADERS) -o ./new_header.py
mv $(SAI_PY_HEADERS) ./sai_headers.py.bk
mv ./new_header.py $(SAI_PY_HEADERS)

$(ODIR)/%.o: gen-cpp/%.cpp meta
$(CXX) $(CPPFLAGS) -c $< -o $@ -I../../meta
Expand Down
144 changes: 144 additions & 0 deletions test/saithriftv2/convert_header.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
import logging
import argparse

"""
Convert the generated code in sai_header.py.
For the generated code from c++ enum, convert it to python enum class.
the code like
```C++
/**
* @brief SAI common API type
*/
typedef enum _sai_common_api_t
{
SAI_COMMON_API_CREATE = 0,
SAI_COMMON_API_REMOVE = 1,
...
} sai_common_api_t;
```
original converted by ctypesgen
```
enum__sai_common_api_t = c_int# /usr/include/sai/saitypes.h: 183
SAI_COMMON_API_CREATE = 0# /usr/include/sai/saitypes.h: 183
SAI_COMMON_API_REMOVE = 1# /usr/include/sai/saitypes.h: 183
...
```
new code
```
class sai_common_api(SAIEnum):
SAI_COMMON_API_CREATE = 0# /usr/include/sai/saitypes.h: 183
SAI_COMMON_API_REMOVE = 1# /usr/include/sai/saitypes.h: 183
...
SAI_COMMON_API_CREATE = sai_common_api.SAI_COMMON_API_CREATE
SAI_COMMON_API_REMOVE = sai_common_api.SAI_COMMON_API_REMOVE
...
```
"""

def parse_param():
'''
Parse param.
'''
parser = argparse.ArgumentParser(
description="""
Convert python file after ctypesgen convert.
"""
)

parser.add_argument(
"-i", type=str, dest="input_file",
help="input file name", required=True)
parser.add_argument(
"-o", type=str, dest="output_file",
help="output file name", required=True)
return parser.parse_args()

def import_and_enum_define():
"""
import and add the enum class definitation.
"""
def_str = "import enum\r\nclass SAIEnum(enum.IntEnum):\r\n def __str__(self):\r\n return super().__str__().split(\".\")[1]\r\n"
return def_str

def convert_enum_start_to_class(line):
"""
Convert the enum to class.
args:
line: input
"""
class_name = line.strip("enum__").split("_t = c_int", 1)[0]
return class_name

def convert_file(input_file_name, output_file_name):
"""
Convert the input file to a output file.
"""
input_file = open(input_file_name, 'r')
output_file = open(output_file_name, 'w')
enum_times = 0
enum_items = []
enum_start = False
class_name = None

Lines = input_file.readlines()
for line in Lines:
if not enum_start and enum_times == 0 and "enum__sai_" in line and "= c_int" in line:
# first time hit a enum
# add import
output_file.write(import_and_enum_define())
enum_times= enum_times + 1
enum_start = True
enum_items = []
output_file.write("\n")
class_name = convert_enum_start_to_class(line)
output_file.writelines("class {}(SAIEnum):\n".format(class_name))
output_file.flush()
continue
elif not enum_start and enum_times > 0 and "enum__sai_" in line and "= c_int" in line:
enum_times= enum_times + 1
enum_start = True
enum_items = []
output_file.write("\n")
class_name = convert_enum_start_to_class(line)
output_file.writelines("class {}(SAIEnum):\n".format(class_name))
output_file.flush()
continue
elif enum_start and " = enum__sai_" not in line and "SAI" in line:
line = line.split("\n", 1)[0]
enum_name = line.split(" =", 1)[0]
enum_items.append(enum_name)
output_file.write(" {}\n".format(line))
output_file.flush()
continue
elif " = enum__sai_" in line:
enum_start = False
output_file.write("\n")
for item in enum_items:
output_file.write("{} = {}.{}".format(item, class_name, item))
output_file.write("\n")
output_file.write("\n")
output_file.flush()
continue
else:
output_file.writelines(line)


output_file.flush()
input_file.close()
output_file.close()


if __name__ == "__main__":
'''
For the generated code from c++ enum, convert it to python enum class.
'''
args = parse_param()
convert_file(args.input_file, args.output_file)

0 comments on commit 8fda361

Please sign in to comment.