40
40
)
41
41
42
42
from executorch .backends .arm .vgf_partitioner import VgfPartitioner
43
+
44
+ # To use Cortex-M backend
45
+ from executorch .backends .cortex_m .passes .replace_quant_nodes_pass import (
46
+ ReplaceQuantNodesPass ,
47
+ )
43
48
from executorch .devtools .backend_debug import get_delegation_info
44
49
from executorch .devtools .bundled_program .config import MethodTestCase , MethodTestSuite
45
50
59
64
from ..models import MODEL_NAME_TO_MODEL
60
65
from ..models .model_factory import EagerModelFactory
61
66
67
+
62
68
FORMAT = "[%(levelname)s %(asctime)s %(filename)s:%(lineno)s] %(message)s"
63
69
logging .basicConfig (level = logging .WARNING , format = FORMAT )
64
70
@@ -216,6 +222,54 @@ def forward(self, x, y):
216
222
can_delegate = True
217
223
218
224
225
+ class QuantAddTest (torch .nn .Module ):
226
+ def __init__ (self ):
227
+ super ().__init__ ()
228
+
229
+ def forward (self , a ):
230
+ return a + a
231
+
232
+ example_input = (torch .rand ([13 , 3 ], dtype = torch .float32 ),) # a - normal values
233
+ can_delegate = True # when quantized
234
+
235
+
236
+ class QuantAddTest2 (torch .nn .Module ):
237
+ def __init__ (self ):
238
+ super ().__init__ ()
239
+
240
+ def forward (self , a , b ):
241
+ p = a + a
242
+ q = b + b
243
+ r = p + q
244
+ return p , q , r
245
+
246
+ example_input = (
247
+ torch .randn ([13 , 7 , 3 ], dtype = torch .float32 ),
248
+ torch .randn ([13 , 7 , 3 ], dtype = torch .float32 ),
249
+ )
250
+ can_delegate = True # when quantized
251
+
252
+
253
+ class QuantOpTest (torch .nn .Module ):
254
+ def __init__ (self ):
255
+ super ().__init__ ()
256
+
257
+ def forward (self , w , x , y , z ):
258
+ o1 = w - x
259
+ o2 = o1 + y
260
+ o3 = o2 * z
261
+ return o1 , o2 , o3
262
+
263
+ example_input = (
264
+ torch .randn ([3 , 1 , 2 ], dtype = torch .float32 ), # w - normal values
265
+ torch .randn ([3 , 5 , 2 ], dtype = torch .float32 ), # x - normal values
266
+ torch .randn ([3 , 5 , 1 ], dtype = torch .float32 )
267
+ * - 0.000001 , # y - small -ve values, needs to be calibration for tests
268
+ torch .randn ([3 , 5 , 2 ], dtype = torch .float32 ) * 1000 , # z - large values
269
+ )
270
+ can_delegate = True # when quantized
271
+
272
+
219
273
class SoftmaxModule (torch .nn .Module ):
220
274
def __init__ (self ):
221
275
super ().__init__ ()
@@ -241,6 +295,9 @@ def forward(self, x: torch.Tensor, y: torch.Tensor):
241
295
"add" : AddModule ,
242
296
"add2" : AddModule2 ,
243
297
"add3" : AddModule3 ,
298
+ "qadd" : QuantAddTest ,
299
+ "qadd2" : QuantAddTest2 ,
300
+ "qops" : QuantOpTest ,
244
301
"softmax" : SoftmaxModule ,
245
302
"MultipleOutputsModule" : MultipleOutputsModule ,
246
303
}
@@ -255,6 +312,17 @@ def forward(self, x: torch.Tensor, y: torch.Tensor):
255
312
torch .randn (32 , 5 ),
256
313
torch .randn (32 , 5 ),
257
314
),
315
+ "qadd" : (torch .randn (32 , 2 , 1 ),),
316
+ "qadd2" : (
317
+ torch .randn (32 , 2 , 1 ),
318
+ torch .randn (32 , 2 , 1 ),
319
+ ),
320
+ "qops" : (
321
+ torch .randn (32 , 2 , 1 ),
322
+ torch .randn (32 , 2 , 1 ),
323
+ torch .randn (32 , 2 , 1 ) * - 0.000001 ,
324
+ torch .randn (32 , 2 , 1 ) * 1000 ,
325
+ ),
258
326
"softmax" : (torch .randn (32 , 2 , 2 ),),
259
327
}
260
328
@@ -656,6 +724,7 @@ def to_edge_TOSA_delegate(
656
724
_check_ir_validity = False ,
657
725
),
658
726
)
727
+
659
728
return model_int8 , edge
660
729
661
730
@@ -681,9 +750,18 @@ def to_edge_no_delegate(exported_program, args, model: torch.nn.Module, example_
681
750
_check_ir_validity = False ,
682
751
),
683
752
)
753
+
684
754
return model_int8 , edge
685
755
686
756
757
+ def transform_for_cortex_m_backend (edge ):
758
+ # Let's make sure we are using optimized Cortex M backend
759
+ # NB: If we can't find and replace ops those are expected to be replaced,
760
+ # bad things will happen at runtime, like "missing operator" errors!
761
+ edge = edge .transform ([ReplaceQuantNodesPass ()])
762
+ return edge
763
+
764
+
687
765
if __name__ == "__main__" : # noqa: C901
688
766
args = get_args ()
689
767
@@ -715,6 +793,9 @@ def to_edge_no_delegate(exported_program, args, model: torch.nn.Module, example_
715
793
exported_program , args , model , example_inputs
716
794
)
717
795
796
+ # Transform so we can use ops from the Cortex M backend
797
+ edge = transform_for_cortex_m_backend (edge )
798
+
718
799
dump_delegation_info (edge , args .intermediates )
719
800
720
801
try :
0 commit comments