44# LICENSE file in the root directory of this source tree.
55
66import numpy as np
7+
8+ # noinspection PyUnusedImports
79import pytest
810import torch
911
1012from executorch .backends .nxp .backend .edge_program_converter import (
1113 EdgeProgramToIRConverter ,
1214)
15+ from executorch .backends .nxp .tests .dataset_creator import RandomDatasetCreator
1316from executorch .backends .nxp .tests .executorch_pipeline import to_quantized_edge_program
1417from executorch .backends .nxp .tests .executors import (
1518 convert_run_compare ,
1619 graph_contains_any_of_ops ,
1720)
18- from executorch .exir .dialects ._ops import ops as exir_ops
21+ from executorch .backends .nxp .tests .graph_verifier import DetailedGraphVerifier
22+ from executorch .backends .nxp .tests .nsys_testing import lower_run_compare
23+ from executorch .backends .nxp .tests .ops_aliases import ExecutorchDelegateCall , LeakyRelu
24+ from executorch .backends .nxp .tests .use_qat import * # noqa F403
1925
2026
2127@pytest .fixture (autouse = True )
@@ -24,17 +30,13 @@ def reseed_model_per_test_run():
2430 np .random .seed (23 )
2531
2632
27- ExecutorchDelegateCall = torch .ops .higher_order .executorch_call_delegate
28- LeakyRelu2D = exir_ops .edge .aten .leaky_relu .default
29-
30-
3133def _assert_successful_delegation (model , input_shape , mocker , atol = 0 ):
3234 converter_spy = mocker .spy (EdgeProgramToIRConverter , "convert_program" )
3335 delegated_ep = to_quantized_edge_program (model , input_shape ).exported_program ()
3436
3537 # Make sure the `leaky_relu` was delegated.
3638 assert graph_contains_any_of_ops (delegated_ep .graph , [ExecutorchDelegateCall ])
37- assert not graph_contains_any_of_ops (delegated_ep .graph , [LeakyRelu2D ])
39+ assert not graph_contains_any_of_ops (delegated_ep .graph , [LeakyRelu ])
3840
3941 # Verify correct behavior of the converted NeutronIR model.
4042 intermediate_ep = converter_spy .call_args .args [1 ]
@@ -45,7 +47,7 @@ def _assert_successful_delegation(model, input_shape, mocker, atol=0):
4547 ).astype (np .int8 )
4648
4749 # Make sure the tested program contains the `leaky_relu`.
48- assert graph_contains_any_of_ops (intermediate_ep .graph , [LeakyRelu2D ])
50+ assert graph_contains_any_of_ops (intermediate_ep .graph , [LeakyRelu ])
4951
5052 convert_run_compare (
5153 intermediate_ep , tfl_model = neutron_ir_model , input_data = input_data , atol = atol
@@ -121,3 +123,62 @@ def test_convert_leaky_relu__ranks(mocker, input_shape: tuple[int, ...]):
121123 mocker ,
122124 atol = 1 , # Common quantization rounding error.
123125 )
126+
127+
128+ class TestLeakyReluNewNeutronFlow :
129+ # noinspection PyMethodMayBeStatic
130+ def assert_delegated (self , model , input_shape , mocker , use_qat = False ):
131+ graph_verifier = DetailedGraphVerifier (
132+ mocker ,
133+ expected_delegated_ops = {LeakyRelu : 1 },
134+ expected_non_delegated_ops = {},
135+ )
136+
137+ # Create a RandomDatasetCreator that covers also negative numbers to properly test the operator.
138+ dataset_creator = RandomDatasetCreator (low = - 2 , high = 2 )
139+
140+ lower_run_compare (
141+ model ,
142+ input_shape ,
143+ graph_verifier ,
144+ dataset_creator ,
145+ use_qat = use_qat ,
146+ use_new_flow_neutron_c = True , # Use the new flow.
147+ )
148+
149+ @pytest .mark .parametrize (
150+ "input_shape" ,
151+ [
152+ (2 ,),
153+ (2 , 3 ),
154+ (2 , 3 , 4 ),
155+ (2 , 3 , 4 , 5 ),
156+ (2 , 3 , 4 , 5 , 6 ),
157+ ],
158+ ids = lambda shape : f"{ len (shape )} D" ,
159+ )
160+ def test__default_alpha__input_shapes (self , mocker , input_shape ):
161+ model = LeakyReluModule ()
162+ self .assert_delegated (model , input_shape , mocker )
163+
164+ def test__default_alpha__qat (self , mocker , use_qat ):
165+ model = LeakyReluModule ()
166+ input_shape = (23 ,)
167+ self .assert_delegated (model , input_shape , mocker , use_qat )
168+
169+ @pytest .mark .parametrize (
170+ "alpha" ,
171+ [0.01 , 3.14159 , 0 , 1 , float ("inf" )],
172+ ids = lambda alpha : f"alpha = { alpha } " ,
173+ )
174+ def test__specific_alpha (self , mocker , alpha ):
175+ model = LeakyReluModule (negative_slope = alpha )
176+ self .assert_delegated (model , (23 ,), mocker )
177+
178+ def test__inplace (self , mocker ):
179+ model = LeakyReluModule (inplace = True )
180+ self .assert_delegated (
181+ model ,
182+ (23 ,),
183+ mocker ,
184+ )
0 commit comments