Skip to content
Snippets Groups Projects
Commit 45d12a67 authored by Cyril Moineau's avatar Cyril Moineau
Browse files

Merge branch 'IntroduceUnitTest' into 'dev'

Add a first instance of unit test for Cpp export.

See merge request !34
parents 58c0e326 f02e2c5c
No related branches found
No related tags found
2 merge requests!39Update 0.2.1 -> 0.3.0,!34Add a first instance of unit test for Cpp export.
Pipeline #70592 passed
# Ignore
/*_test/
\ No newline at end of file
......@@ -4,18 +4,130 @@ import aidge_backend_cpu
import aidge_export_cpp
import numpy as np
import subprocess
import re
from aidge_core.utils import run_command
def initFiller(model):
# Initialize parameters (weights and biases)
for node in model.get_nodes():
if node.type() == "Producer":
prod_op = node.get_operator()
value = prod_op.get_output(0)
value.set_backend("cpu")
tuple_out = node.output(0)[0]
# No conv in current network
if tuple_out[0].type() == "Conv" and tuple_out[1] == 1:
# Conv weight
aidge_core.xavier_uniform_filler(value)
elif tuple_out[0].type() == "Conv" and tuple_out[1] == 2:
# Conv bias
aidge_core.constant_filler(value, 0.01)
elif tuple_out[0].type() == "FC" and tuple_out[1] == 1:
# FC weight
aidge_core.normal_filler(value)
elif tuple_out[0].type() == "FC" and tuple_out[1] == 2:
# FC bias
aidge_core.constant_filler(value, 0.01)
else:
pass
class test_operator_export(unittest.TestCase):
class test_export(unittest.TestCase):
"""Test tensor binding
"""
def setUp(self):
pass
# TODO change seed at each test ?
RNG_SEED = 1234
np.random.seed(RNG_SEED)
aidge_core.random.Generator.set_seed(RNG_SEED)
def tearDown(self):
pass
def test_export_cpp(self):
print("Export test to do")
def unit_test_export(self, graph_view, op_name, in_dims):
"""
TODO:
* Handle multiple dataformat
* Handle multiple datatype (currently only float32)
Here are the following steps of this test:
1- Generate random inputs
2- Forward random inputs to the graph
3- Generate Cpp export with a main that compare the result of the inference with the result obtained at step 2.
4- Retrieve standard output and using regex to now if the results are the same
"""
graph_view.compile("cpu", aidge_core.dtype.float32, dims=in_dims)
scheduler = aidge_core.SequentialScheduler(graph_view)
in_tensor = [aidge_core.Tensor(np.random.random(in_dim).astype(np.float32)) for in_dim in in_dims]
scheduler.forward(data=in_tensor)
# Note the convention ``<op_name>_test`` is useful for gitignore to avoid pushing generated export by accident.
export_folder = op_name + "_test"
# Export the model in C++ standalone
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 }
)
aidge_core.export_utils.generate_main_compare_cpp(export_folder, graph_view)
print("COMPILATION")
try:
for std_line in run_command(["make"], cwd=export_folder):
print(std_line, end="")
except subprocess.CalledProcessError as e:
self.assertTrue(1, f"An error occurred: {e}\nFailed to generate export.")
print("RUN EXPORT")
pattern = r"Number of equal outputs: (\d+) / (\d+)"
comparison_matched = False
result = False
try:
for std_line in run_command(["./bin/run_export"], cwd=export_folder):
print(std_line, end="")
matches = re.findall(pattern, std_line)
if matches:
self.assertFalse(comparison_matched, "Two comparison matched found!")
expected, infered = map(int, matches[0])
result = (expected == infered)
comparison_matched = True
except subprocess.CalledProcessError as e:
self.assertTrue(1, f"An error occurred: {e}\nFailed to run export for comparison.")
self.assertTrue(comparison_matched, "No comparison matched found!")
self.assertTrue(result, "Export result are different than backend ones.")
def test_export_FC_flatten_in(self):
"""Test exporting a FC operator with a flattened input.
"""
model = aidge_core.sequential([
aidge_core.FC(in_channels=6, out_channels=6, name="InputNode")
])
initFiller(model)
self.unit_test_export(model, "FC_flat", [[1, 6, 1, 1]])
@unittest.skip("Currently this test is failing")
def test_export_FC_image_in(self):
"""Test exporting a FC operator with a HWC input.
"""
model = aidge_core.sequential([
aidge_core.FC(in_channels=12, out_channels=6, name="InputNode")
])
initFiller(model)
self.unit_test_export(model, "FC_img", [[1, 3, 2, 2]])
def test_export_Conv(self):
model = aidge_core.sequential([
aidge_core.Conv2D(1, 1, [3, 3], name="InputNode")
])
initFiller(model)
self.unit_test_export(model, "Conv", [[1, 1, 9, 9]])
if __name__ == '__main__':
unittest.main()
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