@@ -293,6 +293,50 @@ def test_has_expected_ops_and_op_counts(self):
293293 for op , _op_info in delegation_info .delegation_by_operator .items ():
294294 self .assertTrue (op not in UNWANTED_OPS )
295295
296+ def test_xnnpack_extended_ops_defaults_on (self ):
297+ args = build_args_parser ().parse_args ([])
298+ self .assertTrue (args .xnnpack_extended_ops )
299+ self .assertTrue (LlmConfig .from_args (args ).backend .xnnpack .extended_ops )
300+
301+ def test_no_xnnpack_extended_ops_opts_out (self ):
302+ args = build_args_parser ().parse_args (["--no-xnnpack-extended-ops" ])
303+ self .assertFalse (args .xnnpack_extended_ops )
304+ self .assertFalse (LlmConfig .from_args (args ).backend .xnnpack .extended_ops )
305+
306+ def test_no_xnnpack_extended_ops_builds_dq_partitioner_only (self ):
307+ # Covers the multimethod path. _to_edge_and_lower_llama_xnnpack gates on
308+ # the same flag and is exercised by the full-export tests in this file.
309+ from executorch .backends .xnnpack .partition .config .xnnpack_config import (
310+ ConfigPrecisionType ,
311+ )
312+ from executorch .backends .xnnpack .partition .xnnpack_partitioner import (
313+ XnnpackDynamicallyQuantizedPartitioner ,
314+ )
315+
316+ def build (argv ):
317+ args = build_args_parser ().parse_args (["-X" , * argv ])
318+ return export_llama_lib ._get_xnnpack_partitioners (LlmConfig .from_args (args ))
319+
320+ def precisions (partitioner ):
321+ return {
322+ precision
323+ for config in partitioner .target_partitioner_configs .values ()
324+ for precision in config .enabled_precision_types
325+ }
326+
327+ dq_only = build (["--no-xnnpack-extended-ops" ])
328+ self .assertEqual (len (dq_only ), 1 )
329+ self .assertIsInstance (dq_only [0 ], XnnpackDynamicallyQuantizedPartitioner )
330+ self .assertEqual (precisions (dq_only [0 ]), {ConfigPrecisionType .DYNAMIC_QUANT })
331+
332+ # The default adds a second, general partitioner. It is not a subclass
333+ # instance, and it enables precisions the dynamic-quant one cannot.
334+ both = build ([])
335+ self .assertEqual (len (both ), 2 )
336+ self .assertIsInstance (both [0 ], XnnpackDynamicallyQuantizedPartitioner )
337+ self .assertNotIsInstance (both [1 ], XnnpackDynamicallyQuantizedPartitioner )
338+ self .assertIn (ConfigPrecisionType .FP32 , precisions (both [1 ]))
339+
296340 def test_bf16_xnnpack_delegates_linears_when_enabled (self ):
297341 parser = build_args_parser ()
298342 args = parser .parse_args ([])
0 commit comments