diff --git a/aidge_export_cpp/unit_tests/test_examples.py b/aidge_export_cpp/unit_tests/test_examples.py new file mode 100644 index 0000000000000000000000000000000000000000..1ddf6590acf26b0a4f5e31b43900176551c77a7f --- /dev/null +++ b/aidge_export_cpp/unit_tests/test_examples.py @@ -0,0 +1,46 @@ +import subprocess +import sys +import os +import pytest +from pathlib import Path + +CURRENT_DIR = Path(__file__).parent +EXAMPLES_DIR = CURRENT_DIR / "../../examples" + +# Dictionary of test cases: {id: (script_name, script_args)} +TEST_CASES = { + "lenet-int8-no-args": ("export_LeNet/lenet.py", []), + "resnet18-int8-no-args": ("export_ResNet18/resnet18.py", ["--mock_db"]) +} + +def generate_test_cases(): + """Parse TEST_CASES to provide valid pytest params. + """ + for test_id, (script, args) in TEST_CASES.items(): + yield pytest.param(script, args, id=test_id) + +@pytest.mark.parametrize(("script_name", "script_args"), generate_test_cases()) +def test_example_scripts_run_without_error(script_name, script_args): + """Basic test to verify that examples script run withoput raising an Error. + This test DO NOT check that the examples are working only that they are not broken. + """ + script_path = os.path.join(EXAMPLES_DIR, script_name) + result = subprocess.run( + [sys.executable, script_path] + script_args, # Or any lightweight args + capture_output=True, + text=True + ) + assert result.returncode == 0, f"{script_name} failed with error: {result.stderr}" + + +def main(): + import sys + + print( + f"{sys.argv[0]}: Warning: skipped: run with: pytest {sys.argv[0]}", + file=sys.stderr, +) + + +if __name__ == "__main__": + main() diff --git a/examples/export_ResNet18/resnet18.py b/examples/export_ResNet18/resnet18.py index 07127368eaacb173ad27d3d6f83d0e9605563a03..948a60fa7d56f4624a7941ab696af9e82102f54d 100644 --- a/examples/export_ResNet18/resnet18.py +++ b/examples/export_ResNet18/resnet18.py @@ -16,6 +16,7 @@ from PIL import Image import requests from pathlib import Path import subprocess +from random import randint # Aidge Modules import aidge_core import aidge_onnx @@ -63,6 +64,10 @@ parser.add_argument( "DEBUG < INFO < NOTICE < WARN < ERROR < FATAL." ) ) + +parser.add_argument("--mock_db", action="store_true", help="Use a mock database instead of real one (TEST ONLY).") + + parser.add_argument( "--imagenet_path", type=str, @@ -187,6 +192,7 @@ def print_cfg(): print(' DEV_MODE = ', DEV_MODE) print(' IMAGENET_PATH = ', IMAGENET_PATH) print(' LABEL_PATH = ', LABEL_PATH) + print(' MOCK_DB = ', args.mock_db) print_cfg() @@ -194,59 +200,68 @@ torch.manual_seed(RNG_SEED) random.seed(RNG_SEED) np.random.seed(RNG_SEED) -backend = "cuda" if USE_CUDA else "cpu" - -image_label_pairs = [] -with open(LABEL_PATH, 'r') as f: - for line in f: - parts = line.strip().split() - if len(parts) == 2: - image_name, label = parts - image_label_pairs.append((image_name, int(label))) - -np.random.seed(RNG_SEED) -NB_SELECT = max(NB_TEST, NB_CALIB) # Check that NB_TEST and NB_CALIB are fixed -selected_pairs = image_label_pairs[:NB_SELECT] - -# -------------------------------------------------------------- -# CREATE THE SAMPLES -# -------------------------------------------------------------- - -transform_val = transforms.Compose([transforms.Resize(256), - transforms.CenterCrop(224), - transforms.ToTensor(), - transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) - ]) - -tensors = [] -labels = [] -paths = [] -index = 0 - -for image_name, label in selected_pairs: - image_path = os.path.join(IMAGENET_PATH, image_name) - if os.path.exists(image_path): - try: - image = Image.open(image_path) - if image.mode != 'RGB': - image = image.convert('RGB') - tensor = transform_val(image) - tensors.append(tensor) - labels.append(label) - paths.append(image_path) - except Exception as e: - print(f"Error with image {image_path}: {e}") - backend = "cuda" if USE_CUDA else "cpu" aidge_tensors = [] -for tensor in tensors: - array = tensor.numpy() - array = np.reshape(array, (1, 3, 224, 224)) - array = normalize(array) - aidge_tensor = aidge_core.Tensor(array) - aidge_tensor.set_backend(backend) - aidge_tensor.set_datatype(aidge_core.dtype.float32) - aidge_tensors.append(aidge_tensor) +labels = [] +if args.mock_db: + for i in range(NB_TEST): + aidge_tensor = aidge_core.Tensor(dims=(1, 3, 224, 224)) + aidge_tensor.set_backend(backend) + aidge_tensor.set_datatype(aidge_core.dtype.float32) + aidge_core.uniform_filler(aidge_tensor, -1.0, 1.0) + aidge_tensors.append(aidge_tensor) + labels.append(randint(1, 1000)) +else: + image_label_pairs = [] + with open(LABEL_PATH, 'r') as f: + for line in f: + parts = line.strip().split() + if len(parts) == 2: + image_name, label = parts + image_label_pairs.append((image_name, int(label))) + + np.random.seed(RNG_SEED) + NB_SELECT = max(NB_TEST, NB_CALIB) # Check that NB_TEST and NB_CALIB are fixed + selected_pairs = image_label_pairs[:NB_SELECT] + + # -------------------------------------------------------------- + # CREATE THE SAMPLES + # -------------------------------------------------------------- + + transform_val = transforms.Compose([transforms.Resize(256), + transforms.CenterCrop(224), + transforms.ToTensor(), + transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) + ]) + + tensors = [] + labels = [] + paths = [] + index = 0 + + for image_name, label in selected_pairs: + image_path = os.path.join(IMAGENET_PATH, image_name) + if os.path.exists(image_path): + try: + image = Image.open(image_path) + if image.mode != 'RGB': + image = image.convert('RGB') + tensor = transform_val(image) + tensors.append(tensor) + labels.append(label) + paths.append(image_path) + except Exception as e: + print(f"Error with image {image_path}: {e}") + + + for tensor in tensors: + array = tensor.numpy() + array = np.reshape(array, (1, 3, 224, 224)) + array = normalize(array) + aidge_tensor = aidge_core.Tensor(array) + aidge_tensor.set_backend(backend) + aidge_tensor.set_datatype(aidge_core.dtype.float32) + aidge_tensors.append(aidge_tensor) # -------------------------------------------------------------- @@ -260,7 +275,6 @@ Load the .onnx model and perform some usual graph modifications : - Expand the metaOperators to perform the desired fusions. """ - # Define the target path and filename file_url = "https://huggingface.co/EclipseAidge/resnet18/resolve/main/resnet18_imagenet_1k.onnx?download=true" file_path = Path(MODEL_NAME + "_imagenet_1k.onnx")