Export 101#

Binder

Install requirements#

Ensure that the Aidge modules are properly installed in the current environment. If it is the case, the following setup steps can be skipped.
Note: When running this notebook on Binder, all required components are pre-installed.
[ ]:
%pip install aidge-core \
    aidge-backend-cpu \
    aidge-export-cpp \
    aidge-onnx
[1]:
%pip install requests numpy ipywidgets ipycanvas
Requirement already satisfied: requests in /local/home/id280155/.virtualenvs/tuto_expstm32fp32/lib/python3.12/site-packages (2.32.4)
Requirement already satisfied: numpy in /local/home/id280155/.virtualenvs/tuto_expstm32fp32/lib/python3.12/site-packages (2.3.1)
Requirement already satisfied: ipywidgets in /local/home/id280155/.virtualenvs/tuto_expstm32fp32/lib/python3.12/site-packages (8.1.7)
Requirement already satisfied: ipycanvas in /local/home/id280155/.virtualenvs/tuto_expstm32fp32/lib/python3.12/site-packages (0.13.3)
Requirement already satisfied: charset_normalizer<4,>=2 in /local/home/id280155/.virtualenvs/tuto_expstm32fp32/lib/python3.12/site-packages (from requests) (3.4.2)
Requirement already satisfied: idna<4,>=2.5 in /local/home/id280155/.virtualenvs/tuto_expstm32fp32/lib/python3.12/site-packages (from requests) (3.10)
Requirement already satisfied: urllib3<3,>=1.21.1 in /local/home/id280155/.virtualenvs/tuto_expstm32fp32/lib/python3.12/site-packages (from requests) (2.5.0)
Requirement already satisfied: certifi>=2017.4.17 in /local/home/id280155/.virtualenvs/tuto_expstm32fp32/lib/python3.12/site-packages (from requests) (2025.7.14)
Requirement already satisfied: comm>=0.1.3 in /local/home/id280155/.virtualenvs/tuto_expstm32fp32/lib/python3.12/site-packages (from ipywidgets) (0.2.2)
Requirement already satisfied: ipython>=6.1.0 in /local/home/id280155/.virtualenvs/tuto_expstm32fp32/lib/python3.12/site-packages (from ipywidgets) (9.4.0)
Requirement already satisfied: traitlets>=4.3.1 in /local/home/id280155/.virtualenvs/tuto_expstm32fp32/lib/python3.12/site-packages (from ipywidgets) (5.14.3)
Requirement already satisfied: widgetsnbextension~=4.0.14 in /local/home/id280155/.virtualenvs/tuto_expstm32fp32/lib/python3.12/site-packages (from ipywidgets) (4.0.14)
Requirement already satisfied: jupyterlab_widgets~=3.0.15 in /local/home/id280155/.virtualenvs/tuto_expstm32fp32/lib/python3.12/site-packages (from ipywidgets) (3.0.15)
Requirement already satisfied: pillow>=6.0 in /local/home/id280155/.virtualenvs/tuto_expstm32fp32/lib/python3.12/site-packages (from ipycanvas) (11.3.0)
Requirement already satisfied: decorator in /local/home/id280155/.virtualenvs/tuto_expstm32fp32/lib/python3.12/site-packages (from ipython>=6.1.0->ipywidgets) (5.2.1)
Requirement already satisfied: ipython-pygments-lexers in /local/home/id280155/.virtualenvs/tuto_expstm32fp32/lib/python3.12/site-packages (from ipython>=6.1.0->ipywidgets) (1.1.1)
Requirement already satisfied: jedi>=0.16 in /local/home/id280155/.virtualenvs/tuto_expstm32fp32/lib/python3.12/site-packages (from ipython>=6.1.0->ipywidgets) (0.19.2)
Requirement already satisfied: matplotlib-inline in /local/home/id280155/.virtualenvs/tuto_expstm32fp32/lib/python3.12/site-packages (from ipython>=6.1.0->ipywidgets) (0.1.7)
Requirement already satisfied: pexpect>4.3 in /local/home/id280155/.virtualenvs/tuto_expstm32fp32/lib/python3.12/site-packages (from ipython>=6.1.0->ipywidgets) (4.9.0)
Requirement already satisfied: prompt_toolkit<3.1.0,>=3.0.41 in /local/home/id280155/.virtualenvs/tuto_expstm32fp32/lib/python3.12/site-packages (from ipython>=6.1.0->ipywidgets) (3.0.51)
Requirement already satisfied: pygments>=2.4.0 in /local/home/id280155/.virtualenvs/tuto_expstm32fp32/lib/python3.12/site-packages (from ipython>=6.1.0->ipywidgets) (2.19.2)
Requirement already satisfied: stack_data in /local/home/id280155/.virtualenvs/tuto_expstm32fp32/lib/python3.12/site-packages (from ipython>=6.1.0->ipywidgets) (0.6.3)
Requirement already satisfied: wcwidth in /local/home/id280155/.virtualenvs/tuto_expstm32fp32/lib/python3.12/site-packages (from prompt_toolkit<3.1.0,>=3.0.41->ipython>=6.1.0->ipywidgets) (0.2.13)
Requirement already satisfied: parso<0.9.0,>=0.8.4 in /local/home/id280155/.virtualenvs/tuto_expstm32fp32/lib/python3.12/site-packages (from jedi>=0.16->ipython>=6.1.0->ipywidgets) (0.8.4)
Requirement already satisfied: ptyprocess>=0.5 in /local/home/id280155/.virtualenvs/tuto_expstm32fp32/lib/python3.12/site-packages (from pexpect>4.3->ipython>=6.1.0->ipywidgets) (0.7.0)
Requirement already satisfied: executing>=1.2.0 in /local/home/id280155/.virtualenvs/tuto_expstm32fp32/lib/python3.12/site-packages (from stack_data->ipython>=6.1.0->ipywidgets) (2.2.0)
Requirement already satisfied: asttokens>=2.1.0 in /local/home/id280155/.virtualenvs/tuto_expstm32fp32/lib/python3.12/site-packages (from stack_data->ipython>=6.1.0->ipywidgets) (3.0.0)
Requirement already satisfied: pure-eval in /local/home/id280155/.virtualenvs/tuto_expstm32fp32/lib/python3.12/site-packages (from stack_data->ipython>=6.1.0->ipywidgets) (0.2.3)
Note: you may need to restart the kernel to use updated packages.
[ ]:

Download the model#

[ ]:
import aidge_core

file_url = "https://huggingface.co/EclipseAidge/LeNet/resolve/main/lenet_mnist.onnx?download=true"
file_path = "lenet_mnist.onnx"

aidge_core.utils.download_file(file_path, file_url)

Load the model in Aidge and manipulate it#

[ ]:
import aidge_backend_cpu
import aidge_onnx
import aidge_export_cpp
[ ]:
model = aidge_onnx.load_onnx("lenet_mnist.onnx")
[ ]:
# Remove Flatten node, useless in the CPP export
aidge_core.remove_flatten(model)

# Configuration for the model + forward dimensions
model.compile("cpu", aidge_core.dtype.float32, dims=[[1, 1, 28, 28]])
[ ]:
# Generate scheduling of the model
scheduler = aidge_core.SequentialScheduler(model)
scheduler.generate_scheduling()

Export the model#

[ ]:
# Adapt the graph to the NHWC format
model.set_dataformat(aidge_core.dformat.nhwc)
model.set_backend(aidge_export_cpp.ExportLibCpp._name)
aidge_core.adapt_to_backend(model)
aidge_core.adapt_fc_params_format(model)
model.forward_dims()
scheduler.reset_scheduling()
scheduler.generate_scheduling()
[ ]:
export_folder = "lenet_export_fp32"

aidge_core.export_utils.scheduler_export(
        scheduler,
        export_folder,
        aidge_export_cpp.ExportLibCpp,
        memory_manager=aidge_core.mem_info.generate_optimized_memory_info,
        memory_manager_args={"stats_folder": f"{export_folder}/stats", "wrapping": False }
)

Draw your own number#

[ ]:
from ipywidgets import HBox, VBox, Button, Layout
from ipycanvas import RoughCanvas, hold_canvas

img_name = "my_number.png"

canvas = RoughCanvas(width=28, height=28, sync_image_data=True)

button_gen = Button(description="Generate PNG")
button_clear = Button(description="Clear")

drawing = False
position = None
shape = []

def on_erase_button_clicked(b):
    canvas.clear()

def on_generate_button_clicked(b):
    try:
        canvas.to_file(img_name)
        print(f"Image generated to {img_name} !")
    except:
        print("Draw a number before generating the image.")

button_clear.on_click(on_erase_button_clicked)
button_gen.on_click(on_generate_button_clicked)

def on_mouse_down(x, y):
    global drawing
    global position
    global shape

    drawing = True
    position = (x, y)
    shape = [position]

def on_mouse_move(x, y):
    global drawing
    global position
    global shape

    if not drawing:
        return

    with hold_canvas():
        canvas.stroke_line(position[0], position[1], x, y)
        position = (x, y)

    shape.append(position)

def on_mouse_up(x, y):
    global drawing
    global position
    global shape

    drawing = False

    with hold_canvas():
        canvas.stroke_line(position[0], position[1], x, y)

    shape = []

canvas.on_mouse_down(on_mouse_down)
canvas.on_mouse_move(on_mouse_move)
canvas.on_mouse_up(on_mouse_up)

canvas.stroke_style = "#000000"

VBox((canvas, HBox((button_gen, button_clear))),
     layout=Layout(height='auto', width="300px"))

Generate inputs for testing the model from your drawing#

[ ]:
aidge_tensor = None
try:
    number_np = canvas.get_image_data()
    # We got a numpy array with the shape of (28,28,4)
    # Transform it to (28,28)
    x = number_np[:, :, 3].astype("float32")
    aidge_tensor = aidge_core.Tensor(x / 255)
except:
    print("Please draw a number in the previous cell before running this one.")

Generate a main that will do an inference on the drawing.

[ ]:
if aidge_tensor:
    aidge_core.export_utils.generate_main_cpp(export_folder, model, inputs_tensor=aidge_tensor)
else:
    print("Please draw a number before generating the export.")

Compile the export and test it#

[ ]:
!cd lenet_export_fp32 && make
[ ]:
!./lenet_export_fp32/bin/run_export