diff --git a/aidge_core/__init__.py b/aidge_core/__init__.py
index 00556a025372f5ab02a051b16a4e5f171a84905f..f677ff73facb3ba64487dc09e87f0a7629ba701b 100644
--- a/aidge_core/__init__.py
+++ b/aidge_core/__init__.py
@@ -12,4 +12,4 @@ from aidge_core.aidge_core import * # import so generated by PyBind
 import aidge_core.export_utils
 
 import aidge_core.utils
-import aidge_core.aidge_export_aidge
+from aidge_core.aidge_export_aidge import serialize_to_cpp
diff --git a/aidge_core/aidge_export_aidge/__init__.py b/aidge_core/aidge_export_aidge/__init__.py
index c5d6f96b3300c0e86147baac30d7cae8a3a0b798..9f042cdbcfff071dabc9a31817bf8e2e95c36ad9 100644
--- a/aidge_core/aidge_export_aidge/__init__.py
+++ b/aidge_core/aidge_export_aidge/__init__.py
@@ -5,4 +5,4 @@ FILE = Path(__file__).resolve()
 ROOT_EXPORT = FILE.parents[0]
 
 from .operator_export import *
-from .export import export
+from .export import serialize_to_cpp
diff --git a/aidge_core/aidge_export_aidge/export.py b/aidge_core/aidge_export_aidge/export.py
index a5b9df0c8efd0d10802d353468274d13005762f8..cb5aa3ef2edc7d3624a91c15f7eda9845b95ec55 100644
--- a/aidge_core/aidge_export_aidge/export.py
+++ b/aidge_core/aidge_export_aidge/export.py
@@ -2,15 +2,14 @@ import aidge_core
 import shutil
 import os
 from pathlib import Path
-from .utils import supported_operators, OPERATORS_REGISTRY
-from . import ROOT_EXPORT
 
+import aidge_core.export_utils
+from . import ROOT_EXPORT
+from aidge_core.aidge_export_aidge.registry import ExportSerialize
 
 from aidge_core.export_utils  import ExportNode, generate_file
 
-
-
-def export(export_folder: str,
+def serialize_to_cpp(export_folder: str,
            graph_view: aidge_core.GraphView,
            enable_python_binding: bool = True,
            ):
@@ -59,7 +58,6 @@ def export(export_folder: str,
     open_nodes = list(graph_view.get_input_nodes())
     # List of Aidge nodes already explored
     closed_nodes = []
-
     while open_nodes:
         node = open_nodes.pop(0)
         if node in closed_nodes:
@@ -81,21 +79,22 @@ def export(export_folder: str,
         # Next nodes to treat are children of current node
         open_nodes += list(node.get_children())
 
-        if node.type() in supported_operators():
-            set_operator.add(node.type())
-            op = OPERATORS_REGISTRY[node.type()](node)
+        if not ExportSerialize.exportable(node):
+            #raise RuntimeError
+            print(f"Node {node.name()} (of type [{node.type()}]) is not exportable !")
+        op = ExportSerialize.get_export_node(node)(node)
+        set_operator.add(node.type())
 
-            # TODO: list_configs and list_actions don't need to be passed by argument
-            # Export the configuration
-            list_configs = op.export(export_folder_path, list_configs)
+        # TODO: list_configs and list_actions don't need to be passed by argument
+        # Export the configuration
+        list_configs += op.export(export_folder_path)
 
-            # Add forward kernel
-            list_actions = op.forward(list_actions)
-        else:
-            raise RuntimeError(f"Operator: {node.type()} is not supported")
+        # Add forward kernel
+        list_actions += op.forward()
         closed_nodes.append(node)
+
     # Generate full dnn.cpp
-    aidge_core.generate_file(
+    aidge_core.export_utils.generate_file(
         export_folder_path / "src/dnn.cpp",
         ROOT_EXPORT / "templates/dnn.jinja",
         headers=list_configs,
diff --git a/aidge_core/aidge_export_aidge/operator_export/conv.py b/aidge_core/aidge_export_aidge/operator_export/conv.py
index ee38fe72ee6ea61ea9c27cfbdb4368dc136cb2f7..1b97d0b418f36be2cd944bdcf8001025108be3b0 100644
--- a/aidge_core/aidge_export_aidge/operator_export/conv.py
+++ b/aidge_core/aidge_export_aidge/operator_export/conv.py
@@ -1,31 +1,41 @@
-from aidge_core.aidge_export_aidge.utils import operator_register, parse_node_input
+from aidge_core.aidge_export_aidge.registry import ExportSerialize
 from aidge_core.aidge_export_aidge import ROOT_EXPORT
-from aidge_core.export_utils import ExportNode, generate_file, generate_str
-from pathlib import Path
+from aidge_core.export_utils import ExportNodeCpp, operator_register
 
-@operator_register("Conv")
-class Conv(ExportNode):
+@operator_register(ExportSerialize, "Conv")
+class Conv(ExportNodeCpp):
     def __init__(self, node):
         super().__init__(node)
+        self.config_template = str(
+            ROOT_EXPORT / "templates/attributes/conv.jinja")
+        self.forward_template = str(
+            ROOT_EXPORT /"templates/graph_ctor/conv.jinja")
+        self.include_list = []
+        self.kernels_to_copy = []
+        self.config_path = "include/parameters"
+        self.config_extension = "hpp"
+    @classmethod
+    def exportable(cls, node):
+        return True
 
-    def export(self, export_folder:Path, list_configs:list):
-        include_path = f"attributes/{self.name}.hpp"
-        filepath = export_folder / f"include/{include_path}"
+    # def export(self, export_folder:Path, list_configs:list):
+    #     include_path = f"attributes/{self.name}.hpp"
+    #     filepath = export_folder / f"include/{include_path}"
 
-        generate_file(
-            filepath,
-            ROOT_EXPORT / "templates/attributes/conv.jinja",
-            name=self.name,
-            **self.attributes
-        )
-        list_configs.append(include_path)
-        return list_configs
+    #     generate_file(
+    #         filepath,
+    #         ROOT_EXPORT / "templates/attributes/conv.jinja",
+    #         name=self.name,
+    #         **self.attributes
+    #     )
+    #     list_configs.append(include_path)
+    #     return list_configs
 
-    def forward(self, list_actions:list):
-        list_actions.append(generate_str(
-            ROOT_EXPORT /"templates/graph_ctor/conv.jinja",
-            name=self.name,
-            inputs=parse_node_input(self.node.inputs()),
-            **self.attributes
-        ))
-        return list_actions
+    # def forward(self, list_actions:list):
+    #     list_actions.append(generate_str(
+    #         ROOT_EXPORT /"templates/graph_ctor/conv.jinja",
+    #         name=self.name,
+    #         inputs=parse_node_input(self.node.inputs()),
+    #         **self.attributes
+    #     ))
+    #     return list_actions
diff --git a/aidge_core/aidge_export_aidge/operator_export/fc.py b/aidge_core/aidge_export_aidge/operator_export/fc.py
index c72fe7648822cbf2e04642dd68a0d7a6b1dd9f46..8161eada96df8500193de598fdb7332abf372542 100644
--- a/aidge_core/aidge_export_aidge/operator_export/fc.py
+++ b/aidge_core/aidge_export_aidge/operator_export/fc.py
@@ -1,37 +1,48 @@
-from aidge_core.aidge_export_aidge.utils import operator_register,parse_node_input
 from aidge_core.aidge_export_aidge import ROOT_EXPORT
-from aidge_core.export_utils import ExportNode, generate_file, generate_str
+from aidge_core.aidge_export_aidge.registry import ExportSerialize
+
+from aidge_core.export_utils import ExportNodeCpp, operator_register
 from pathlib import Path
 
-@operator_register("FC")
-class FC(ExportNode):
+@operator_register(ExportSerialize, "FC")
+class FC(ExportNodeCpp):
     def __init__(self, node):
         super().__init__(node)
-
-
-    def export(self, export_folder:Path, list_configs:list):
-
-
-        include_path = f"attributes/{self.name}.hpp"
-        filepath = export_folder / f"include/{include_path}"
-
-
-        generate_file(
-            filepath,
-            ROOT_EXPORT / "templates/attributes/fc.jinja",
-            name=self.name,
-            InChannels=self.inputs_dims[1][1],
-            OutChannels=self.operator.out_channels(),
-            **self.attributes
-        )
-        list_configs.append(include_path)
-        return list_configs
-
-    def forward(self, list_actions:list):
-        list_actions.append(generate_str(
-            ROOT_EXPORT / "templates/graph_ctor/fc.jinja",
-            name=self.name,
-            inputs=parse_node_input(self.node.inputs()),
-            **self.attributes
-        ))
-        return list_actions
+        self.config_template = str(
+            ROOT_EXPORT / "templates/attributes/fc.jinja")
+        self.forward_template = str(
+            ROOT_EXPORT / "templates/graph_ctor/fc.jinja")
+        self.include_list = []
+        self.kernels_to_copy = []
+        self.config_path = "include/parameters"
+        self.config_extension = "hpp"
+    @classmethod
+    def exportable(cls, node):
+        return True
+
+    # def export(self, export_folder:Path, list_configs:list):
+
+
+    #     include_path = f"attributes/{self.name}.hpp"
+    #     filepath = export_folder / f"include/{include_path}"
+
+
+    #     generate_file(
+    #         filepath,
+    #         ROOT_EXPORT / "templates/attributes/fc.jinja",
+    #         name=self.name,
+    #         InChannels=self.inputs_dims[1][1],
+    #         OutChannels=self.operator.out_channels(),
+    #         **self.attributes
+    #     )
+    #     list_configs.append(include_path)
+    #     return list_configs
+
+    # def forward(self, list_actions:list):
+    #     list_actions.append(generate_str(
+    #         ROOT_EXPORT / "templates/graph_ctor/fc.jinja",
+    #         name=self.name,
+    #         inputs=parse_node_input(self.node.inputs()),
+    #         **self.attributes
+    #     ))
+    #     return list_actions
diff --git a/aidge_core/aidge_export_aidge/operator_export/maxpooling.py b/aidge_core/aidge_export_aidge/operator_export/maxpooling.py
index ef996e6e6310521482fcede7aedf8ab643537ffc..571c72a01cbd24c51de41f3af506be6fa73d0659 100644
--- a/aidge_core/aidge_export_aidge/operator_export/maxpooling.py
+++ b/aidge_core/aidge_export_aidge/operator_export/maxpooling.py
@@ -1,32 +1,41 @@
-from aidge_core.aidge_export_aidge.utils import operator_register, parse_node_input
+from aidge_core.aidge_export_aidge.registry import ExportSerialize
 from aidge_core.aidge_export_aidge import ROOT_EXPORT
-from aidge_core.export_utils import ExportNode, generate_file, generate_str
-from pathlib import Path
+from aidge_core.export_utils import ExportNodeCpp, operator_register
 
-@operator_register("MaxPooling")
-class MaxPooling(ExportNode):
+@operator_register(ExportSerialize,"MaxPooling")
+class MaxPooling(ExportNodeCpp):
     def __init__(self, node):
         super().__init__(node)
+        self.config_template = str(
+            ROOT_EXPORT / "templates/attributes/maxpooling.jinja")
+        self.forward_template = str(
+            ROOT_EXPORT / "templates/graph_ctor/maxpooling.jinja")
+        self.include_list = []
+        self.kernels_to_copy = []
+        self.config_path = "include/parameters"
+        self.config_extension = "hpp"
+    @classmethod
+    def exportable(cls, node):
+        return True
 
+    # def export(self, export_folder:Path, list_configs:list):
+    #     include_path = f"attributes/{self.name}.hpp"
+    #     filepath = export_folder / f"include/{include_path}"
 
-    def export(self, export_folder:Path, list_configs:list):
-        include_path = f"attributes/{self.name}.hpp"
-        filepath = export_folder / f"include/{include_path}"
+    #     generate_file(
+    #         filepath,
+    #         ROOT_EXPORT / "templates/attributes/maxpooling.jinja",
+    #         name=self.name,
+    #         **self.attributes
+    #     )
+    #     list_configs.append(include_path)
+    #     return list_configs
 
-        generate_file(
-            filepath,
-            ROOT_EXPORT / "templates/attributes/maxpooling.jinja",
-            name=self.name,
-            **self.attributes
-        )
-        list_configs.append(include_path)
-        return list_configs
-
-    def forward(self, list_actions:list):
-        list_actions.append(generate_str(
-            ROOT_EXPORT / "templates/graph_ctor/maxpooling.jinja",
-            name=self.name,
-            inputs=parse_node_input(self.node.inputs()),
-            **self.attributes
-        ))
-        return list_actions
+    # def forward(self, list_actions:list):
+    #     list_actions.append(generate_str(
+    #         ROOT_EXPORT / "templates/graph_ctor/maxpooling.jinja",
+    #         name=self.name,
+    #         inputs=parse_node_input(self.node.inputs()),
+    #         **self.attributes
+    #     ))
+    #     return list_actions
diff --git a/aidge_core/aidge_export_aidge/operator_export/producer.py b/aidge_core/aidge_export_aidge/operator_export/producer.py
index 3886cffa0b1cc8bc9c4c13e95301f3647954bb43..c6ace522fa835878f44f403434eca1da061c3c5f 100644
--- a/aidge_core/aidge_export_aidge/operator_export/producer.py
+++ b/aidge_core/aidge_export_aidge/operator_export/producer.py
@@ -1,14 +1,11 @@
-from aidge_core.aidge_export_aidge.utils import operator_register
-from aidge_core.export_utils.data_conversion import aidge2c
-
 from aidge_core.aidge_export_aidge import ROOT_EXPORT
-from aidge_core.export_utils import ExportNode, generate_file, generate_str
+from aidge_core.aidge_export_aidge.registry import ExportSerialize
+from aidge_core.export_utils import ExportNodeCpp, operator_register
 import numpy as np
-from pathlib import Path
 
 
-@operator_register("Producer")
-class Producer(ExportNode):
+@operator_register(ExportSerialize, "Producer")
+class Producer(ExportNodeCpp):
     """
     If there is a standardization of the export operators
     then this class should be just a inheritance of ProducerCPP
@@ -16,33 +13,47 @@ class Producer(ExportNode):
     def __init__(self, node):
         super().__init__(node)
         child, in_idx = self.node.output(0)[0]
-        self.tensor_name = f"{child.name()}_{in_idx}"
+
         self.values = np.array(self.operator.get_output(0))
 
-    def export(self, export_folder:Path, list_configs:list):
-        assert(len(self.node.output(0)) == 1)
-
-        include_path = f"parameters/{self.tensor_name}.hpp"
-        filepath = export_folder / f"include/{include_path}"
-
-        aidge_tensor = self.operator.get_output(0)
-        datatype = aidge2c(aidge_tensor.dtype())
-        generate_file(
-            filepath,
-            ROOT_EXPORT / "templates/parameter.jinja",
-            dims = aidge_tensor.dims(),
-            data_t = datatype,
-            name = self.tensor_name,
-            values = str(aidge_tensor)
-        )
-        list_configs.append(include_path)
-        return list_configs
-
-    def forward(self, list_actions:list):
-        list_actions.append(generate_str(
-            ROOT_EXPORT / "templates/graph_ctor/producer.jinja",
-            name=self.name,
-            tensor_name=self.tensor_name,
-            **self.attributes
-        ))
-        return list_actions
+        self.config_template = str(
+            ROOT_EXPORT / "templates/parameter.jinja")
+        self.forward_template = str(
+            ROOT_EXPORT / "templates/graph_ctor/producer.jinja")
+        self.attributes["tensor_name"] = f"{child.name()}_{in_idx}"
+        self.attributes["values"] = str(self.operator.get_output(0))
+        self.include_list = []
+        self.kernels_to_copy = []
+        self.config_path = "include/parameters"
+        self.config_extension = "hpp"
+    @classmethod
+    def exportable(cls, node):
+        return True
+
+    # def export(self, export_folder:Path, list_configs:list):
+    #     assert(len(self.node.output(0)) == 1)
+
+    #     include_path = f"parameters/{self.tensor_name}.hpp"
+    #     filepath = export_folder / f"include/{include_path}"
+
+    #     aidge_tensor = self.operator.get_output(0)
+    #     datatype = aidge2c(aidge_tensor.dtype())
+    #     generate_file(
+    #         filepath,
+    #         ROOT_EXPORT / "templates/parameter.jinja",
+    #         dims = aidge_tensor.dims(),
+    #         data_t = datatype,
+    #         name = self.tensor_name,
+    #         values = str(aidge_tensor)
+    #     )
+    #     list_configs.append(include_path)
+    #     return list_configs
+
+    # def forward(self, list_actions:list):
+    #     list_actions.append(generate_str(
+    #         ROOT_EXPORT / "templates/graph_ctor/producer.jinja",
+    #         name=self.name,
+    #         tensor_name=self.tensor_name,
+    #         **self.attributes
+    #     ))
+    #     return list_actions
diff --git a/aidge_core/aidge_export_aidge/operator_export/relu.py b/aidge_core/aidge_export_aidge/operator_export/relu.py
index 21b368dfade9b0d83cf3919e770b886f4e18b958..8012b2d040f4d74315094f989b78f196d641c36b 100644
--- a/aidge_core/aidge_export_aidge/operator_export/relu.py
+++ b/aidge_core/aidge_export_aidge/operator_export/relu.py
@@ -1,21 +1,27 @@
-from aidge_core.aidge_export_aidge.utils import operator_register, parse_node_input
-from aidge_core.export_utils  import ExportNode, generate_str
+from aidge_core.aidge_export_aidge.registry import ExportSerialize
 from aidge_core.aidge_export_aidge import ROOT_EXPORT
-from pathlib import Path
+from aidge_core.export_utils import ExportNodeCpp, operator_register
 
-@operator_register("ReLU")
-class ReLU(ExportNode):
+@operator_register(ExportSerialize, "ReLU")
+class ReLU(ExportNodeCpp):
     def __init__(self, node):
         super().__init__(node)
+        self.config_template = ""
+        self.forward_template = str(
+            ROOT_EXPORT / "templates/graph_ctor/relu.jinja")
+        self.include_list = []
+        self.kernels_to_copy = []
+    @classmethod
+    def exportable(cls, node):
+        return True
+    # def export(self, export_folder:Path, list_configs:list):
+    #     return list_configs
 
-    def export(self, export_folder:Path, list_configs:list):
-        return list_configs
-
-    def forward(self, list_actions:list):
-        list_actions.append(generate_str(
-            ROOT_EXPORT / "templates/graph_ctor/relu.jinja",
-            name=self.name,
-            inputs=parse_node_input(self.node.inputs()),
-            **self.attributes
-        ))
-        return list_actions
+    # def forward(self, list_actions:list):
+    #     list_actions.append(generate_str(
+    #         ROOT_EXPORT / "templates/graph_ctor/relu.jinja",
+    #         name=self.name,
+    #         inputs=parse_node_input(self.node.inputs()),
+    #         **self.attributes
+    #     ))
+    #     return list_actions
diff --git a/aidge_core/aidge_export_aidge/operator_export/sub.py b/aidge_core/aidge_export_aidge/operator_export/sub.py
index 24315c921554cb6ac06545dd7961b3c9e767104c..80a96c7eee3189cfab8503977a083bb0db2fba10 100644
--- a/aidge_core/aidge_export_aidge/operator_export/sub.py
+++ b/aidge_core/aidge_export_aidge/operator_export/sub.py
@@ -1,21 +1,29 @@
-from aidge_core.aidge_export_aidge.utils import operator_register, parse_node_input
-from aidge_core.export_utils  import ExportNode, generate_str
+from aidge_core.aidge_export_aidge.registry import ExportSerialize
 from aidge_core.aidge_export_aidge import ROOT_EXPORT
-from pathlib import Path
+from aidge_core.export_utils import ExportNodeCpp, operator_register
 
-@operator_register("Sub")
-class Sub(ExportNode):
+@operator_register(ExportSerialize, "Sub")
+class Sub(ExportNodeCpp):
     def __init__(self, node):
         super().__init__(node)
+        self.config_template = ""
+        self.forward_template = str(
+            ROOT_EXPORT / "templates/graph_ctor/sub.jinja")
+        self.include_list = []
+        self.kernels_to_copy = []
 
-    def export(self, export_folder:Path, list_configs:list):
-        return list_configs
+    @classmethod
+    def exportable(cls, node):
+        return True
 
-    def forward(self, list_actions:list):
-        list_actions.append(generate_str(
-            ROOT_EXPORT / "templates/graph_ctor/sub.jinja",
-            name=self.name,
-            inputs=parse_node_input(self.node.inputs()),
-            **self.attributes
-        ))
-        return list_actions
+    # def export(self, export_folder:Path, list_configs:list):
+    #     return list_configs
+
+    # def forward(self, list_actions:list):
+    #     list_actions.append(generate_str(
+    #         ROOT_EXPORT / "templates/graph_ctor/sub.jinja",
+    #         name=self.name,
+    #         inputs=parse_node_input(self.node.inputs()),
+    #         **self.attributes
+    #     ))
+    #     return list_actions
diff --git a/aidge_core/aidge_export_aidge/registry.py b/aidge_core/aidge_export_aidge/registry.py
new file mode 100644
index 0000000000000000000000000000000000000000..477dc583dbe566677881d67da4c89b856a22d98a
--- /dev/null
+++ b/aidge_core/aidge_export_aidge/registry.py
@@ -0,0 +1,6 @@
+from aidge_core.export_utils import ExportLib
+from . import ROOT_EXPORT
+
+class ExportSerialize(ExportLib):
+    name="export_serialize"
+
diff --git a/aidge_core/aidge_export_aidge/templates/attributes/conv.jinja b/aidge_core/aidge_export_aidge/templates/attributes/conv.jinja
index 48d07e8db8d5fb116148e9d41100fffa01fcf622..58c52abec545f8e62e21dfb35c9f4a5d652f681e 100644
--- a/aidge_core/aidge_export_aidge/templates/attributes/conv.jinja
+++ b/aidge_core/aidge_export_aidge/templates/attributes/conv.jinja
@@ -1,17 +1,17 @@
 #ifndef EXPORT_ATTRIBUTES_{{name|upper}}_H
 #define EXPORT_ATTRIBUTES_{{name|upper}}_H
 
-#define _{{name|upper}}_IN_CHANNELS  {{InChannels}}
-#define _{{name|upper}}_OUT_CHANNELS {{OutChannels}}
+#define _{{name|upper}}_IN_CHANNELS  {{in_chan[0]}}
+#define _{{name|upper}}_OUT_CHANNELS {{out_chan[0]}}
 
-{% for i in range(KernelDims|length) %}
-#define _{{name|upper}}_KERNEL_{{i}} {{KernelDims[i]}}
+{% for i in range(kernel_dims|length) %}
+#define _{{name|upper}}_KERNEL_{{i}} {{kernel_dims[i]}}
 {%- endfor %}
-{% for i in range(StrideDims|length) %}
-#define _{{name|upper}}_STRIDE_{{i}} {{StrideDims[i]}}
+{% for i in range(stride_dims|length) %}
+#define _{{name|upper}}_STRIDE_{{i}} {{stride_dims[i]}}
 {%- endfor %}
-{% for i in range(DilationDims|length) %}
-#define _{{name|upper}}_DILATION_{{i}} {{DilationDims[i]}}
+{% for i in range(dilation_dims|length) %}
+#define _{{name|upper}}_DILATION_{{i}} {{dilation_dims[i]}}
 {%- endfor %}
 
 #endif /* EXPORT_ATTRIBUTES_{{name|upper}}_H */
diff --git a/aidge_core/aidge_export_aidge/templates/attributes/fc.jinja b/aidge_core/aidge_export_aidge/templates/attributes/fc.jinja
index e292f9b611978877c47b15e91f926f30d27a1cc5..32f4d00515b1ced28b5e49889c09759f0f0dd0db 100644
--- a/aidge_core/aidge_export_aidge/templates/attributes/fc.jinja
+++ b/aidge_core/aidge_export_aidge/templates/attributes/fc.jinja
@@ -1,7 +1,7 @@
 #ifndef EXPORT_ATTRIBUTES_{{name|upper}}_H
 #define EXPORT_ATTRIBUTES_{{name|upper}}_H
 
-#define _{{name|upper}}_IN_CHANNELS  {{InChannels}}
-#define _{{name|upper}}_OUT_CHANNELS {{OutChannels}}
+#define _{{name|upper}}_IN_CHANNELS  {{in_chan[0]}}
+#define _{{name|upper}}_OUT_CHANNELS {{out_chan[0]}}
 
 #endif /* EXPORT_ATTRIBUTES_{{name|upper}}_H */
diff --git a/aidge_core/aidge_export_aidge/templates/attributes/maxpooling.jinja b/aidge_core/aidge_export_aidge/templates/attributes/maxpooling.jinja
index d258f580e6ff9c523a87b834fdccf2f3b14fb133..96de14b01167a2f4267343594ded8df6f4b5576d 100644
--- a/aidge_core/aidge_export_aidge/templates/attributes/maxpooling.jinja
+++ b/aidge_core/aidge_export_aidge/templates/attributes/maxpooling.jinja
@@ -1,13 +1,13 @@
 #ifndef EXPORT_ATTRIBUTES_{{name|upper}}_H
 #define EXPORT_ATTRIBUTES_{{name|upper}}_H
 
-{% for i in range(KernelDims|length) %}
-#define _{{name|upper}}_KERNEL_{{i}} {{KernelDims[i]}}
+{% for i in range(kernel_dims|length) %}
+#define _{{name|upper}}_KERNEL_{{i}} {{kernel_dims[i]}}
 {%- endfor %}
-{% for i in range(StrideDims|length) %}
-#define _{{name|upper}}_STRIDE_{{i}} {{StrideDims[i]}}
+{% for i in range(stride_dims|length) %}
+#define _{{name|upper}}_STRIDE_{{i}} {{stride_dims[i]}}
 {%- endfor %}
 
-#define _{{name|upper}}_CEIL_MODE {{CeilMode|int}}
+#define _{{name|upper}}_CEIL_MODE {{ceil_mode|int}}
 
 #endif /* EXPORT_ATTRIBUTES_{{name|upper}}_H */
diff --git a/aidge_core/aidge_export_aidge/templates/dnn.jinja b/aidge_core/aidge_export_aidge/templates/dnn.jinja
index 5da46b2d8a439a359dfb1c7ec8ebc18e8d516767..bb8faff4a800d9676317f5c0301827e21d19df6d 100644
--- a/aidge_core/aidge_export_aidge/templates/dnn.jinja
+++ b/aidge_core/aidge_export_aidge/templates/dnn.jinja
@@ -17,7 +17,7 @@
 
 /*** OPERATOR ATTRIBUTES & PARAMETERS ***/
 {%- for header in headers %}
-#include "{{ header }}"
+#include "{{ header | replace('include/', '') }}"
 {%- endfor %}
 
 /*** HEADER ***/
diff --git a/aidge_core/aidge_export_aidge/templates/graph_ctor/_set_input.jinja b/aidge_core/aidge_export_aidge/templates/graph_ctor/_set_input.jinja
index 8e841ea2a10c71b884736dcbd7cfd03b52c5ad4f..d9f59a94663692b00594f0ecf5f452cc8e2132ca 100644
--- a/aidge_core/aidge_export_aidge/templates/graph_ctor/_set_input.jinja
+++ b/aidge_core/aidge_export_aidge/templates/graph_ctor/_set_input.jinja
@@ -1,7 +1,7 @@
 {# NOTE: Trying a shorter notation like {%- for input in inputs if input[0] %}
 will mess up loop.index as the input set up at None will not increment ! #}
-{%- for input in inputs %}
-{%- if input[0] %}
-{{input[0]}}->addChild({{name}}, {{input[1]}}, {{loop.index - 1}}); {# NOTE: loop.index begin at 1 #}
+{%- for input_node, out_id in node.inputs() %}
+{%- if input_node %}
+{{input_node.name()}}->addChild({{name}}, {{out_id}}, {{loop.index - 1}}); {# NOTE: loop.index begin at 1 #}
 {%- endif %}
 {%- endfor %}
diff --git a/aidge_core/aidge_export_aidge/templates/graph_ctor/conv.jinja b/aidge_core/aidge_export_aidge/templates/graph_ctor/conv.jinja
index a805f8065e87244bf0546ca42d294b86f144a26d..bd4eed2d39f0872759f568b6cc54b8abe3792db7 100644
--- a/aidge_core/aidge_export_aidge/templates/graph_ctor/conv.jinja
+++ b/aidge_core/aidge_export_aidge/templates/graph_ctor/conv.jinja
@@ -5,18 +5,18 @@ std::shared_ptr<Aidge::Node> {{name}} =
             _{{name|upper}}_IN_CHANNELS,
             _{{name|upper}}_OUT_CHANNELS,
             {
-            {%- for i in range(KernelDims|length) -%}
+            {%- for i in range(kernel_dims|length) -%}
                 _{{name|upper}}_KERNEL_{{i}}{%- if not loop.last %}, {% endif -%}
             {%- endfor -%}
             },
             "{{name}}",
             {
-            {%- for i in range(StrideDims|length) -%}
+            {%- for i in range(stride_dims|length) -%}
                 _{{name|upper}}_STRIDE_{{i}} {%- if not loop.last %}, {% endif -%}
             {%- endfor -%}
             },
             {
-            {%- for i in range(DilationDims|length) -%}
+            {%- for i in range(dilation_dims|length) -%}
                 _{{name|upper}}_DILATION_{{i}} {%- if not loop.last %}, {% endif -%}
             {%- endfor -%}
             }
diff --git a/aidge_core/aidge_export_aidge/templates/graph_ctor/maxpooling.jinja b/aidge_core/aidge_export_aidge/templates/graph_ctor/maxpooling.jinja
index c6587c128509712e1a8e903e7484476548e9347d..ceb4784a0942e91b44fe6956833dafda26a2e314 100644
--- a/aidge_core/aidge_export_aidge/templates/graph_ctor/maxpooling.jinja
+++ b/aidge_core/aidge_export_aidge/templates/graph_ctor/maxpooling.jinja
@@ -3,13 +3,13 @@
 std::shared_ptr<Aidge::Node> {{name}} =
         Aidge::MaxPooling(
             {
-            {%- for i in range(KernelDims|length) -%}
+            {%- for i in range(kernel_dims|length) -%}
                 _{{name|upper}}_KERNEL_{{i}}{%- if not loop.last %}, {% endif -%}
             {%- endfor -%}
             },
             "{{name}}",
             {
-            {%- for i in range(StrideDims|length) -%}
+            {%- for i in range(stride_dims|length) -%}
                 _{{name|upper}}_STRIDE_{{i}} {%- if not loop.last %}, {% endif -%}
             {%- endfor -%}
             },
diff --git a/aidge_core/aidge_export_aidge/templates/parameter.jinja b/aidge_core/aidge_export_aidge/templates/parameter.jinja
index 11a407cc89f72f24167871a594decc6d90ab489d..0ff9634d98c57ad84dabc30625e660ca404612f6 100644
--- a/aidge_core/aidge_export_aidge/templates/parameter.jinja
+++ b/aidge_core/aidge_export_aidge/templates/parameter.jinja
@@ -4,7 +4,7 @@
 #include <aidge/data/Tensor.hpp>
 #include <memory>
 
-std::shared_ptr<Aidge::Tensor> {{name}} = std::make_shared<Aidge::Tensor>(Aidge::Array{{dims|length}}D<{{data_t}}, {{ dims|join(", ") }}> {
+std::shared_ptr<Aidge::Tensor> {{tensor_name}} = std::make_shared<Aidge::Tensor>(Aidge::Array{{out_dims[0]|length}}D<{{out_cdtype[0]}}, {{ out_dims[0]|join(", ") }}> {
 {{ values }}
 });
 
diff --git a/aidge_core/export_utils/__init__.py b/aidge_core/export_utils/__init__.py
index 403036030b1ac90cec7f307ae7f7907559ac7bc6..f2394808122fbe161d8e342da1335f6441e8ec56 100644
--- a/aidge_core/export_utils/__init__.py
+++ b/aidge_core/export_utils/__init__.py
@@ -1,4 +1,4 @@
 from .node_export import ExportNode, ExportNodeCpp
 from .code_generation import generate_file, generate_str, copy_file
 from .export_registry import ExportLib, operator_register
-from .scheduler_export import ExportScheduler
+from .scheduler_export import scheduler_export
diff --git a/aidge_core/export_utils/export_registry.py b/aidge_core/export_utils/export_registry.py
index 1d6dcde88a45fe8a84dbc92315c9b6dc32dc44e1..50699b4842b495ff6ead06b9da8d6e9d5d29cf79 100644
--- a/aidge_core/export_utils/export_registry.py
+++ b/aidge_core/export_utils/export_registry.py
@@ -26,9 +26,6 @@ class ExportLib(): # Should be abstract ?
     _language: LANGUAGE = None
     _compilo:str = None
 
-
-
-
     def __init__(self) -> None:
          raise RuntimeError("ExportLib should not be instanciated")
     @classmethod
@@ -63,7 +60,7 @@ class ExportLib(): # Should be abstract ?
         :rtype: ExportNode
         """
         if not cls.exportable(node):
-            raise ValueError(f"Node {node.type()} is not exportable by ExportLib {cls._name} !")
+            raise ValueError(f"Node {node.type()} is not exportable by ExportLib {cls.name} !")
         if len(cls._export_node_registry[node.type()]) != 1:
             raise RuntimeError("ExportLib registry doesn't support when multiple export node are available yet ...")
         else:
diff --git a/aidge_core/export_utils/node_export.py b/aidge_core/export_utils/node_export.py
index 581e9070b409621c845e69c5316c3f6597237434..79a3dd140d4d06b7195b1102ad10dca3298af253 100644
--- a/aidge_core/export_utils/node_export.py
+++ b/aidge_core/export_utils/node_export.py
@@ -123,6 +123,7 @@ class ExportNode(ABC):
         # Attributes are auto fetched from aidge operators
         self.attributes = self.operator.attr.dict(
         ) if self.operator.attr is not None else {}
+        self.attributes["node"] = self.node
         self.attributes["name"] = self.node.name()
         self.attributes["nb_in"] = self.node.get_nb_inputs()
         self.attributes["nb_out"] = self.node.get_nb_outputs()
@@ -159,7 +160,7 @@ class ExportNode(ABC):
         # Producer don't have meminfo
         # TODO: document this attribute
         # true if node have meminfo else false
-        self.attributes["meminfo"] = mem_info or self.node.type() != "Producer"
+        self.attributes["meminfo"] = mem_info is not None and self.node.type() != "Producer"
         if self.attributes["meminfo"]:
             self.attributes["mem_info_size"] = [None] * self.attributes["nb_out"]
             self.attributes["mem_info_offset"] = [None] * self.attributes["nb_out"]
@@ -266,9 +267,12 @@ class ExportNodeCpp(ExportNode):
     # kernels are copied in str(export_folder / "include" / "kernels")
     # They are automatically added to the include list.
     kernels_to_copy: list = None
-    # Path where all the kernels are stored in the export (prefixed by export_root/include)
-    kernels_path: str = "kernels"
-
+    # Path where all the kernels are stored in the export (prefixed by export_root)
+    kernels_path: str = "include/kernels"
+    # Path of config folders
+    config_path: str = "include/layers"
+    # Config_folder_extension
+    config_extension: str = "h"
     def export(self, export_folder: str):
         """Define how to export the node definition.
         """
@@ -277,25 +281,26 @@ class ExportNodeCpp(ExportNode):
         if self.include_list is None:
             raise ValueError("include_list have not been defined")
         if self.kernels_to_copy is None:
-            raise ValueError("required_kernels have not been defined")
+            raise ValueError("kernels_to_copy have not been defined")
 
         kernel_include_list = []
         for kernel in self.kernels_to_copy:
             kernel_path = Path(kernel)
             code_generation.copy_file(
                 kernel_path,
-                str(export_folder / "include" / self.kernels_path)
+                str(export_folder / self.kernels_path)
             )
             kernel_include_list.append(
                 self.kernels_path + "/" + kernel_path.stem + kernel_path.suffix)
-        path_to_definition = f"include/layers/{self.attributes['name']}.h"
-        code_generation.generate_file(
-            str(export_folder / path_to_definition),
-            self.config_template,
-            **self.attributes
-        )
 
-        kernel_include_list.append(path_to_definition)
+        if self.config_template != "":
+            path_to_definition = f"{self.config_path}/{self.attributes['name']}.{self.config_extension}"
+            code_generation.generate_file(
+                str(export_folder / path_to_definition),
+                self.config_template,
+                **self.attributes
+            )
+            kernel_include_list.append(path_to_definition)
 
         return self.include_list + kernel_include_list
 
diff --git a/aidge_core/export_utils/scheduler_export.py b/aidge_core/export_utils/scheduler_export.py
index c12f15ab72baafd4c64d62506ab9bad62486a62e..5e44bb30d54ce0ecb7acbddf96fe1b34acd70416 100644
--- a/aidge_core/export_utils/scheduler_export.py
+++ b/aidge_core/export_utils/scheduler_export.py
@@ -6,7 +6,7 @@ from aidge_core.export_utils import ExportLib, generate_file, copy_file
 from typing import List, Tuple
 
 
-def export(scheduler, export_folder_path: str, export_lib: ExportLib = None, memory_manager=None, memory_manager_args=None) -> None:
+def scheduler_export(scheduler, export_folder_path: str, export_lib: ExportLib = None, memory_manager=None, memory_manager_args=None) -> None:
         graphview = scheduler.graph_view()
         export_folder = Path().absolute() / export_folder_path