Skip to content
Snippets Groups Projects
Commit 3d166034 authored by Axel Farrugia's avatar Axel Farrugia
Browse files

[Refactor] Add a new way to handle the aidge cmp feature by using an intermediat json file

parent 9ec8701f
No related branches found
No related tags found
2 merge requests!710.4.0,!58Fix the aidge_cmp feature
......@@ -3,13 +3,14 @@ import shutil
import numpy as np
from pathlib import Path
from typing import List, Union
import json
import aidge_core
from aidge_core.mem_info import generate_optimized_memory_info
from aidge_core.export_utils import scheduler_export, generate_main_cpp, aidge2c, generate_file
from aidge_core.export_utils import scheduler_export, generate_main_cpp
from aidge_export_cpp import ExportLibCpp, ROOT
from aidge_export_cpp.export_utils import read_log_file
from aidge_export_cpp import ExportLibCpp
from aidge_export_cpp.export_utils import export_aidge_ifmaps
def export(export_folder_name: str,
......@@ -59,6 +60,25 @@ def export(export_folder_name: str,
aidge_core.adapt_fc_params_format(graphview)
graphview.forward_dims(dims=[inputs_tensor.dims()] if inputs_tensor is not None else [])
# --------------------------------------------------------------
# AIDGE CMP
# --------------------------------------------------------------
"""
If the --aidge_cmp option is enabled, the feature maps generated by aidge with the
backend cpu will be exported in the generated export. It will be used as reference
to verify that the results with the optimized kernels are correct for the exported
model.
This option has to be passed to each node in order to be used within the Export Nodes.
(JConv, JPad, ...) that you can find in the "operators" folder.
"""
if aidge_cmp:
for node in graphview.get_nodes():
node.attributes().aidge_cmp = True
graphview.save("exported_model")
scheduler.reset_scheduling()
scheduler.generate_scheduling()
......@@ -85,25 +105,5 @@ def export(export_folder_name: str,
generate_main_cpp(export_folder_name, graphview, labels=labels, inputs_tensor=inputs_tensor)
# Generate log files (aidge_cmp option)
"""
If the aidge_cmp option has been enabled, the generated log_outputs will
be copied into the generated export in order to be used as reference.
"""
if aidge_cmp:
ranked_nodes = graphview.get_ranked_nodes_name("{0}[{1}#{3}]")
os.makedirs(export_folder_name / "data" / "aidge_outputs")
os.makedirs(export_folder_name / "data" / "export_outputs")
for node in graphview.get_nodes():
if node.type() != "Producer":
file_path = 'log_outputs/' + ranked_nodes[node] + '/output_0.log'
data_t = aidge2c(node.get_operator().get_output(0).dtype())
name = node.name() + '_output_0_aidge'
dims = node.get_operator().get_output(0).dims()
values = read_log_file(file_path)
generate_file(export_folder_name / "data" / "aidge_outputs" / (node.name() + ".hpp"),
ROOT / "templates" / "data" / "aidge_tensor.jinja",
data_t=data_t,
name=name,
dims=dims,
values=values)
export_aidge_ifmaps(export_folder_name)
import os
import json
import numpy as np
from collections import OrderedDict
import aidge_core
from aidge_core.export_utils import get_node_from_metaop
from aidge_core.export_utils import get_node_from_metaop, aidge2c, generate_file
from aidge_export_cpp import ROOT
def cpp_fuse_to_metaops(graph_view: aidge_core.GraphView):
"""
Fuse nodes into metaops adapted for the CPP Export
TODO: These recipes should be into aidge_core
TODO: These recipes should be in aidge_core
:param graph_view: An instance of :py:class:`aidge_core.GraphView`, providing access to nodes and
ordered input/output data within the computational graph.
......@@ -152,25 +156,6 @@ def set_nodes_datatypes(graph_view: aidge_core.GraphView):
def read_log_file(file_path: str):
""" Read log file
Used to read the aidge generated log files containing the intermediate
tensors of the exported model.
:param file_path: Path to the file to read.
:type file_path: str
"""
# Check if the file exists
if not os.path.isfile(file_path):
print(f"File not found: {file_path}")
return None
with open(file_path, 'r') as file:
content = file.read()
return content
def exclude_unwanted_producers(model):
""" Exclude some producers not needed for the export
......@@ -226,3 +211,48 @@ def normalize(array):
array = (array - array.min()) / (array.max() - array.min())
return 2 * array - 1
def generate_aidge_ifmaps(model):
json_nodes = []
for node in model.get_nodes():
if node.type() != "Producer":
output = node.get_operator().get_output(0)
data = {
"name": node.name(),
"dims": output.dims(),
"dtype": aidge2c(output.dtype()),
"values": np.array(output).tolist()
}
json_nodes.append(data)
# Write the entire list to the JSON file after the loop
with open('aidge_output.json', 'w') as file:
json.dump(json_nodes, file, indent=2, separators=(",", ": "))
def export_aidge_ifmaps(export_folder_name):
os.makedirs(export_folder_name / "data" / "aidge_outputs")
os.makedirs(export_folder_name / "data" / "export_outputs")
# Load the JSON data from the file
with open('aidge_output.json', 'r') as file:
json_nodes = json.load(file)
# Access the data
for node in json_nodes:
name = node["name"]
dims = node["dims"]
dtype = node["dtype"]
values = node["values"]
generate_file(export_folder_name / "data" / "aidge_outputs" / (name + ".hpp"),
ROOT / "templates" / "data" / "aidge_tensor.jinja",
data_t=dtype,
name=name + "_output_0_aidge",
dims=dims,
values=values)
......@@ -18,11 +18,7 @@ import aidge_backend_cpu
import aidge_quantization
import aidge_export_cpp
from aidge_export_cpp.export_utils import (
cpp_fuse_to_metaops,
set_nodes_names,
set_nodes_datatypes,
exclude_unwanted_producers)
from aidge_export_cpp.export_utils import *
from aidge_core.export_utils import remove_optional_inputs, get_node_from_metaop
......@@ -442,9 +438,8 @@ Once the tensors have been casted, the log_outputs() function can be
called to store their values into log files.
"""
if os.path.isdir("log_outputs"):
shutil.rmtree("log_outputs")
model.log_outputs("log_outputs")
if AIDGE_CMP:
generate_aidge_ifmaps(model)
# --------------------------------------------------------------
# TEST MODE
......@@ -461,29 +456,10 @@ changing the inputs of the layer, to isolate the source of the issue.
for node in model.get_nodes():
node.attributes().dev_mode = DEV_MODE
# --------------------------------------------------------------
# AIDGE CMP
# --------------------------------------------------------------
"""
If the --aidge_cmp option is enabled, the feature maps generated by aidge with the
backend cpu will be exported in the generated export. It will be used as reference
to verify that the results with the optimized kernels are correct for the exported
model.
This option has to be passed to each node in order to be used within the Export Nodes.
(JConv, JPad, ...) that you can find in the "operators" folder.
"""
if AIDGE_CMP:
for node in model.get_nodes():
node.attributes().aidge_cmp = True
# --------------------------------------------------------------
# EXPORT THE MODEL
# --------------------------------------------------------------
model.save("exported_model")
aidge_export_cpp.export(EXPORT_FOLDER,
model,
scheduler,
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment