[export_cpp] Duplicate activation layer in model_forward for MobileNetV1 network
Problem description
When exporting to CPP a mobilenetV1 network from an onnx file, the model_forward function has too many activation_forward functions, and the names of the input and output arrays do not fit with those of the onnx file.
Reproducible example code
Here is the onnx file: MobileNetV1_CIFAR100.onnx
The code for the export is:
import aidge_core
import aidge_backend_cpu
import aidge_onnx
import aidge_export_cpp
import os
import requests
from pathlib import Path
MODEL_PATH = Path("models")
ONNX_NAME = "MobileNetV1_CIFAR100.onnx"
channels = 3
size = 32
ONNX_PATH = MODEL_PATH / ONNX_NAME
model = aidge_onnx.load_onnx(ONNX_PATH)
# Remove Flatten node, useless in the CPP export
print('Removing flatten')
aidge_core.remove_flatten(model)
print(aidge_onnx.native_coverage_report(model))
# Freeze the model by setting constants to parameters producers
for node in model.get_nodes():
if node.type() == "Producer":
# node.get_operator().set_attr("Constant", True)
node.get_operator().attr.constant = True
# Create Producer Node for the Graph
input_node = aidge_core.Producer([1, channels, size, size], "input")
input_node.add_child(model)
model.add(input_node)
# Configuration for the model + forward dimensions
print('Compiling model')
model.compile("cpu", aidge_core.dtype.float32)
# Generate scheduling of the model
print('Generating scheduler')
scheduler = aidge_core.SequentialScheduler(model)
scheduler.generate_scheduling()
# model.save("test")
# Export the model
exportFolder = ONNX_NAME.split('_')[0] + "_export_fp32"
print(f'Exporting model to folder: {exportFolder}')
aidge_export_cpp.export(exportFolder, model, scheduler)
And the generated model_forward function begins with:
void model_forward(const float* input, float* output)
{
float* model_model_0_model_0_0_Conv_output_0 = (float*) mem + MODEL_MODEL_0_MODEL_0_0_CONV_OUTPUT_0_OFFSET;
convolution_forward<MODEL_MODEL_0_MODEL_0_0_CONV_OUTPUT_0_NB_CHANNELS,
MODEL_MODEL_0_MODEL_0_0_CONV_OUTPUT_0_CHANNELS_HEIGHT,
MODEL_MODEL_0_MODEL_0_0_CONV_OUTPUT_0_CHANNELS_WIDTH,
MODEL_MODEL_0_MODEL_0_0_CONV_OUTPUT_0_NB_OUTPUTS,
MODEL_MODEL_0_MODEL_0_0_CONV_OUTPUT_0_OUTPUTS_HEIGHT,
MODEL_MODEL_0_MODEL_0_0_CONV_OUTPUT_0_OUTPUTS_WIDTH,
MODEL_MODEL_0_MODEL_0_0_CONV_OUTPUT_0_PADDING_Y,
MODEL_MODEL_0_MODEL_0_0_CONV_OUTPUT_0_PADDING_X,
MODEL_MODEL_0_MODEL_0_0_CONV_OUTPUT_0_STRIDE_Y,
MODEL_MODEL_0_MODEL_0_0_CONV_OUTPUT_0_STRIDE_X,
MODEL_MODEL_0_MODEL_0_0_CONV_OUTPUT_0_DILATION_Y,
MODEL_MODEL_0_MODEL_0_0_CONV_OUTPUT_0_DILATION_X,
MODEL_MODEL_0_MODEL_0_0_CONV_OUTPUT_0_KERNEL_HEIGHT,
MODEL_MODEL_0_MODEL_0_0_CONV_OUTPUT_0_KERNEL_WIDTH,
MODEL_MODEL_0_MODEL_0_0_CONV_OUTPUT_0_ACTIVATION>
(input, model_model_0_model_0_0_Conv_output_0, onnx__Conv_250, onnx__Conv_251, MODEL_MODEL_0_MODEL_0_0_CONV_OUTPUT_0_RESCALING);
float* model_model_0_model_0_2_Relu = (float*) mem + MODEL_MODEL_0_MODEL_0_2_RELU_OFFSET;
activation_forward<MODEL_MODEL_0_MODEL_0_2_RELU_NB_DATA,
MODEL_MODEL_0_MODEL_0_2_RELU_ACTIVATION>
(model_model_0_model_0_0_Conv_output_0, model_model_0_model_0_2_Relu, MODEL_MODEL_0_MODEL_0_2_RELU_RESCALING);
float* model_model_1_model_1_2_Relu = (float*) mem + MODEL_MODEL_1_MODEL_1_2_RELU_OFFSET;
activation_forward<MODEL_MODEL_1_MODEL_1_2_RELU_NB_DATA,
MODEL_MODEL_1_MODEL_1_2_RELU_ACTIVATION>
(model_model_1_model_1_0_Conv_output_0, model_model_1_model_1_2_Relu, MODEL_MODEL_1_MODEL_1_2_RELU_RESCALING);
The file is attached below: forward.cpp
Here is a view from Netron of the first activation layer:
The first activation_forward call seems correct, except for the name of the output array, but the second call should definitely not exist.