diff --git a/CHANGELOG b/CHANGELOG index 46c726b24039613f57bd4ab676a9f833702d03cb..6b09adac23e519d74ccedd12605f913da9dd3084 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,5 @@ +# Version 0.2.1 (January 31, 2025) + # Version 0.2.0 (december 6, 2024) # Version 0.0.1 (January 23, 2024) diff --git a/aidge_export_cpp/__init__.py b/aidge_export_cpp/__init__.py index 99df1302f6183eb1301fe6863824e7a0bd67c229..4eff59883e4b197f1710560cbc9bdefe15f0b586 100644 --- a/aidge_export_cpp/__init__.py +++ b/aidge_export_cpp/__init__.py @@ -2,15 +2,9 @@ r""" Aidge Export for CPP standalone projects """ +from .utils import ROOT from .export_registry import ExportLibCpp - from .operators import * from collections import defaultdict -import aidge_core - -from aidge_export_cpp.utils import ROOT - -from ._version import * - from .export import * diff --git a/aidge_export_cpp/export.py b/aidge_export_cpp/export.py index ebac7a809caef0b192bf030de9c98a9d18af9f34..42bf90f30eda3a2110cab5c8f0a315824f57d522 100644 --- a/aidge_export_cpp/export.py +++ b/aidge_export_cpp/export.py @@ -1,131 +1,15 @@ -import re -import os -import numpy as np - import aidge_core - -from aidge_core.export_utils.code_generation import * -from aidge_core.mem_info import compute_default_mem_info - -from aidge_export_cpp.utils import ROOT -from aidge_export_cpp.utils.converter import numpy_dtype2ctype from aidge_export_cpp import ExportLibCpp -from aidge_export_cpp.utils.generation import * -# from aidge_export_cpp.memory import * - - -def generate_input_file(export_folder:str, - array_name:str, - array: np.ndarray): - - # If directory doesn't exist, create it - if not os.path.exists(export_folder): - os.makedirs(export_folder) - - generate_file( - file_path=f"{export_folder}/{array_name}.h", - template_path=str(ROOT / "templates" / "data" / "inputs.jinja"), - dims = array.shape, - data_t = numpy_dtype2ctype(array.dtype), - name = array_name, - values = array.tolist() - ) - def export(export_folder_name, graphview, scheduler, mem_wrapping=False): + print("Warning: This function is deprecated, check tutorial https://eclipse.dev/aidge/source/Tutorial/export_cpp.html to find the new way to generate a C++ export.") aidge_core.export_utils.scheduler_export( scheduler, export_folder_name, ExportLibCpp, - memory_manager=compute_default_mem_info + memory_manager=aidge_core.mem_info.generate_optimized_memory_info, + memory_manager_args={ + "stats_folder": f"{export_folder_name}/stats", + "wrapping": mem_wrapping + } ) - - # export_folder = Path().absolute() / export_folder_name - - # os.makedirs(str(export_folder), exist_ok=True) - - # dnn_folder = export_folder / "dnn" - # os.makedirs(str(dnn_folder), exist_ok=True) - - # list_actions = [] - # list_configs = [] - # peak_mem, mem_info = compute_default_mem_info(scheduler) - # list_forward_nodes = scheduler.get_static_scheduling() - - # for node in list_forward_nodes: - # if ExportLibCpp.exportable(node): - # op = ExportLibCpp.get_export_node(node)(node, mem_info[node]) - # # For configuration files - # list_configs = op.export(dnn_folder, list_configs) - - # # For forward file - # list_actions = op.forward(list_actions) - # else: - # raise RuntimeError(f"Operator not supported: {node.type()} !") - - # # Memory management - # # stats_folder = export_folder / "statistics" - # # os.makedirs(str(stats_folder), exist_ok=True) - # # mem_size, mem_info = generate_optimized_memory_info(stats_folder, scheduler, mem_wrapping) - # # peak_mem, mem_info = compute_default_mem_info(scheduler) - - # # Generate the memory file - # # generate_file( - # # str(dnn_folder / "memory" / "mem_info.h"), - # # str(ROOT / "templates" / "memory" / "mem_info.jinja"), - # # mem_size = mem_size, - # # mem_info_legends = MEMORY_INFO_TEMPLATE, - # # mem_info = mem_info - # # ) - # # list_configs.append("memory/mem_info.h") - - # # Get entry nodes - # # Store the datatype & name - # list_inputs_name = [] - # for node in graphview.get_input_nodes(): - # for idx, node_input_tuple in enumerate(node.inputs()): - # node_input, _ = node_input_tuple - # if node_input is None: - # export_type = aidge2c(node.get_operator().get_output(0).dtype()) - # list_inputs_name.append((export_type, f"{node.name()}_input_{idx}")) - # elif node_input not in graphview.get_nodes(): - # export_type = aidge2c(node_input.get_operator().get_output(0).dtype()) - # list_inputs_name.append((export_type, node_input.name())) - - - # # Get output nodes - # # Store the datatype & name, like entry nodes - # list_outputs_name = [] - # for node in graphview.get_nodes(): - # if len(node.get_children()) == 0: - # export_type = aidge2c(node.get_operator().get_output(0).dtype()) - # list_outputs_name.append((export_type, f"{node.name()}_output_0")) - - # # Generate forward file - # # TODO: for now the mem type is bound for all intermediate results, should change. - # # Note that we may have all inputs constants, hence select output type - # assert len(list_outputs_name) >= 1, f"TODO: requires some output to determine mem type" - # mem_ctype = list_outputs_name[0][0] - # generate_file( - # str(dnn_folder / "src" / "forward.cpp"), - # str(ROOT / "templates" / "network" / "network_forward.jinja"), - # headers=set(list_configs), - # actions=list_actions, - # inputs= list_inputs_name, - # outputs=list_outputs_name, - # mem_ctype=mem_ctype, - # peak_mem=peak_mem - # ) - - # # Generate dnn API - # generate_file( - # str(dnn_folder / "include" / "dnn.hpp"), - # str(ROOT / "templates" / "network" / "dnn_header.jinja"), - # libraries=[], - # functions=get_functions_from_c_file(str(dnn_folder / "src" / "forward.cpp")), - # ) - - # # Copy all static files in the export - # shutil.copy(str(ROOT / "static" / "main.cpp"), str(export_folder)) - # shutil.copy(str(ROOT / "static" / "Makefile"), str(export_folder)) - # shutil.copytree(str(ROOT / "static" / "include"), str(dnn_folder / "include"), dirs_exist_ok=True) diff --git a/aidge_export_cpp/export_registry.py b/aidge_export_cpp/export_registry.py index f1aa83b3beeb4cffa3d3076b28df7c8745c0b457..876e4ffcfba3b4491737707fb42a75e8e20d3f51 100644 --- a/aidge_export_cpp/export_registry.py +++ b/aidge_export_cpp/export_registry.py @@ -1,5 +1,5 @@ from aidge_core.export_utils import ExportLib -from aidge_export_cpp.utils import ROOT +from aidge_export_cpp import ROOT class ExportLibCpp(ExportLib): _name="export_cpp" diff --git a/aidge_export_cpp/operators.py b/aidge_export_cpp/operators.py index 9654a20d3be3c258c195f6f6f35b706f56ccdda7..f04dbb3bd134fbb517f677649b05032e5944f886 100644 --- a/aidge_export_cpp/operators.py +++ b/aidge_export_cpp/operators.py @@ -4,12 +4,27 @@ from pathlib import Path import aidge_core from aidge_core.export_utils import ExportNode, ExportNodeCpp, generate_file from aidge_export_cpp.utils import ROOT -from aidge_export_cpp.utils.converter import numpy_dtype2ctype from aidge_export_cpp import ExportLibCpp ############################################## ############## Export functions ############## ############################################## +def numpy_dtype2ctype(dtype): + if dtype == np.int8: + return "int8_t" + elif dtype == np.int16: + return "int16_t" + elif dtype == np.int32: + return "int32_t" + elif dtype == np.int64: + return "int64_t" + elif dtype == np.float32: + return "float" + elif dtype == np.float64: + return "double" + # Add more dtype mappings as needed + else: + raise ValueError(f"Unsupported {dtype} dtype") def export_params(name: str, array: np.ndarray, diff --git a/aidge_export_cpp/utils.py b/aidge_export_cpp/utils.py new file mode 100644 index 0000000000000000000000000000000000000000..915c2c63f9dee838a0dc77ca6304cbf56720a9bf --- /dev/null +++ b/aidge_export_cpp/utils.py @@ -0,0 +1,14 @@ +from pathlib import Path +from importlib.metadata import version + +# Constants +FILE = Path(__file__).resolve() +ROOT = FILE.parents[0] + + +def show_version(): + version_aidge_export_cpp = version("aidge_export_cpp") + print(f"Aidge Export CPP: {version_aidge_export_cpp}") + +def get_project_version()->str: + return version("aidge_export_cpp") diff --git a/aidge_export_cpp/utils/__init__.py b/aidge_export_cpp/utils/__init__.py deleted file mode 100644 index 0728388bec9ae3f7241392b2b9c88c2c61cd1ed7..0000000000000000000000000000000000000000 --- a/aidge_export_cpp/utils/__init__.py +++ /dev/null @@ -1,27 +0,0 @@ -from pathlib import Path -import os - -# Constants -FILE = Path(__file__).resolve() -ROOT = FILE.parents[1] - - -OPERATORS_REGISTRY = {} - -def operator_register(*args): - - key_list = [arg for arg in args] - - def decorator(operator): - class Wrapper(operator): - def __init__(self, *args, **kwargs): - return operator(*args, **kwargs) - - for key in key_list: - OPERATORS_REGISTRY[key] = operator - - return Wrapper - return decorator - -def supported_operators(): - return list(OPERATORS_REGISTRY.keys()) diff --git a/aidge_export_cpp/utils/converter.py b/aidge_export_cpp/utils/converter.py deleted file mode 100644 index d4af124280e2c89ec44123c90ee509347003f960..0000000000000000000000000000000000000000 --- a/aidge_export_cpp/utils/converter.py +++ /dev/null @@ -1,18 +0,0 @@ -import numpy as np - -def numpy_dtype2ctype(dtype): - if dtype == np.int8: - return "int8_t" - elif dtype == np.int16: - return "int16_t" - elif dtype == np.int32: - return "int32_t" - elif dtype == np.int64: - return "int64_t" - elif dtype == np.float32: - return "float" - elif dtype == np.float64: - return "double" - # Add more dtype mappings as needed - else: - raise ValueError(f"Unsupported {dtype} dtype") diff --git a/aidge_export_cpp/utils/generation.py b/aidge_export_cpp/utils/generation.py deleted file mode 100644 index 4478ef7d664b3c59bd3499b0377d698da6cce834..0000000000000000000000000000000000000000 --- a/aidge_export_cpp/utils/generation.py +++ /dev/null @@ -1,51 +0,0 @@ -import re -import os -import shutil -from jinja2 import Environment, FileSystemLoader - - -def get_functions_from_c_file(file_path): - functions = [] - pattern = r'\w+\s+(\w+)\s*\(([^)]*)\)\s*{' - - with open(file_path, 'r') as file: - file_content = file.read() - - matches = re.findall(pattern, file_content) - for match in matches: - function_name = match[0] - arguments = match[1].split(',') - arguments = [arg.strip() for arg in arguments] - - return_type = get_return_type(file_content, function_name) - - function_string = f"{return_type} {function_name}({', '.join(arguments)});" - functions.append(function_string) - - return functions - - -def get_return_type(file_content, function_name): - pattern = rf'\w+\s+{function_name}\s*\([^)]*\)\s*{{' - return_type = re.search(pattern, file_content).group() - return_type = return_type.split()[0].strip() - return return_type - - -def get_functions_from_c_folder(folder_path): - functions = [] - - for _, _, files in os.walk(folder_path): - for file in files: - functions += get_functions_from_c_file(os.path.join(folder_path, file)) - - return functions - - -def copyfile(filename, dst_folder): - - # If directory doesn't exist, create it - if not os.path.exists(dst_folder): - os.makedirs(dst_folder) - - shutil.copy(filename, dst_folder) diff --git a/pyproject.toml b/pyproject.toml index 870f193d2f3f2849fc8c928fc6cf694cf894272a..42868218454abd6f96872aa4f51b220c9975386e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,10 +6,10 @@ dependencies = [ "Jinja2>=3.1.3", ] -requires-python = ">= 3.7" +requires-python = ">= 3.8" readme = "README.md" license = { file = "LICENSE" } -classifiers = [ +classifiers = [ "Development Status :: 2 - Pre-Alpha", "Intended Audience :: Developers", "Intended Audience :: Education", @@ -18,15 +18,25 @@ classifiers = [ "Programming Language :: C++", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", "Programming Language :: Python :: 3 :: Only", "Topic :: Scientific/Engineering", "Topic :: Scientific/Engineering :: Artificial Intelligence", "Topic :: Software Development" ] -dynamic = ["version"] # defined in tool.setuptools_scm +dynamic = ["version"] # defined by pbr + +[project.urls] +Homepage = "https://www.deepgreen.ai/en/platform" +Documentation = "https://eclipse-aidge.readthedocs.io/en/latest/" +Repository = "https://gitlab.eclipse.org/eclipse/aidge/aidge_export_cpp" +Issues = "https://gitlab.eclipse.org/eclipse/aidge/aidge_export_cpp/-/issues/" +Changelog = "https://gitlab.eclipse.org/eclipse/aidge/aidge_export_cpp/-/releases" [project.optional-dependencies] test = ["pytest"] @@ -34,7 +44,7 @@ test = ["pytest"] [build-system] requires = [ "setuptools>=64", - "setuptools_scm[toml]==7.1.0" + "pbr" ] build-backend = "setuptools.build_meta" @@ -45,8 +55,8 @@ build-backend = "setuptools.build_meta" where = ["."] # list of folders that contain the packages (["."] by default) include = ["aidge_export_cpp"] # package names should match these glob patterns (["*"] by default) namespaces = false # to disable scanning PEP 420 namespaces (true by default) +[tool.setuptools.package-data] +'aidge_export_cpp' = ['**/*'] [tool.setuptools.exclude-package-data] aidge_export_cpp = ["unit_tests*"] # exclude unit_tests which may be included as data -# SETUPTOOLS_SCM -[tool.setuptools_scm] -write_to = "aidge_export_cpp/_version.py" + diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 0000000000000000000000000000000000000000..bb5e12488f7053454949b9f86cce7bbb11231e62 --- /dev/null +++ b/setup.cfg @@ -0,0 +1,4 @@ + +# pbr file +[metadata] +version = file: version.txt diff --git a/version.txt b/version.txt index 5faa42c8a89ea0f5ab797259dce62bb190eb28c6..cf74bd305353dff0240e9b8a5513959be87cf768 100644 --- a/version.txt +++ b/version.txt @@ -1,2 +1,2 @@ -0.2.0 +0.2.1