3131from tests .fixtures .fp8 import ParametrizedFP8Configs
3232from tests .fixtures .quantization import (
3333 ParametrizedQuantConfigs ,
34+ make_graph_mode_composite_boundary_config ,
3435 make_graph_mode_ptq_config ,
3536)
3637from tests .models .composite import (
@@ -452,47 +453,66 @@ def test_integer_quant_minval_export(
452453
453454# Composite-op externalize export coverage
454455
456+ # (model, externalize spec, composite submodule path, expected coreai.quantize count
457+ # per config kind)
458+ _EXTERNALIZE_EXPORT_CASES = [
459+ pytest .param (
460+ CompositeRMSNormModel ,
461+ rmsnorm_externalize_spec (),
462+ "norm" ,
463+ {"w8" : 0 , "w8a8" : 4 , "w8a8-boundary" : 6 },
464+ id = "rmsnorm" ,
465+ ),
466+ pytest .param (
467+ CompositeSDPAModel ,
468+ sdpa_externalize_spec (),
469+ "composite" ,
470+ {"w8" : 0 , "w8a8" : 4 , "w8a8-boundary" : 8 },
471+ id = "sdpa" ,
472+ ),
473+ ]
455474
475+
476+ @pytest .mark .parametrize ("config_kind" , ["w8" , "w8a8" , "w8a8-boundary" ])
456477@pytest .mark .parametrize (
457- "quantize_activations, expected_quantize_count" ,
458- [
459- pytest .param (False , 0 , id = "w8-weight-only" ),
460- pytest .param (True , 4 , id = "w8a8" ),
461- ],
462- )
463- @pytest .mark .parametrize (
464- "model_cls, externalize_spec" ,
465- [
466- pytest .param (CompositeRMSNormModel , rmsnorm_externalize_spec (), id = "rmsnorm" ),
467- pytest .param (CompositeSDPAModel , sdpa_externalize_spec (), id = "sdpa" ),
468- ],
478+ "model_cls, externalize_spec, composite_module, expected_quantize_counts" ,
479+ _EXTERNALIZE_EXPORT_CASES ,
469480)
470481def test_composite_externalize_export (
471482 model_cls : type [torch .nn .Module ],
472483 externalize_spec : ExternalizeSpec ,
473- quantize_activations : bool ,
474- expected_quantize_count : int ,
484+ composite_module : str ,
485+ expected_quantize_counts : Mapping [str , int ],
486+ config_kind : str ,
475487) -> None :
476488 """End-to-end CoreAI export of a model with an externalized composite op.
477489
478- Marks the composite op for externalization, runs graph-mode PTQ
479- (w8 weight-only or w8a8), then lowers the finalized graph to a
480- .aimodel and runs it. ``convert_and_verify`` handles SNR / PSNR
481- on the runtime output and op-count verification on the exported
482- program (``constexpr_blockwise_shift_scale`` for weight quantizers
483- and ``quantize`` / ``dequantize`` for activation quantizers).
490+ Marks the composite op for externalization, runs graph-mode PTQ, then lowers the
491+ finalized graph to a .aimodel and runs it. ``convert_and_verify`` handles SNR /
492+ PSNR on the runtime output and op-count verification on the exported program
493+ (``constexpr_blockwise_shift_scale`` for weight quantizers and ``quantize`` /
494+ ``dequantize`` for activation quantizers).
495+
496+ Three configs:
497+
498+ - ``w8`` / ``w8a8``: global config only.
499+ - ``w8a8-boundary``: adds a module-scoped ``module_input_spec`` /
500+ ``module_output_spec`` so the composite op's i/o edges are quantized
484501 """
485502 model = model_cls ().eval ().half ()
486503 input_data = torch .randn (2 , 4 , 32 , dtype = torch .float16 )
487504
488505 _patch_model_for_externalization (model , [externalize_spec ])
489506
490- quantizer = Quantizer (
491- model , make_graph_mode_ptq_config (quantize_activations = quantize_activations )
492- )
507+ if config_kind == "w8a8-boundary" :
508+ config = make_graph_mode_composite_boundary_config (module_name = composite_module )
509+ else :
510+ config = make_graph_mode_ptq_config (quantize_activations = config_kind == "w8a8" )
511+
512+ quantizer = Quantizer (model , config )
493513 prepared_model = quantizer .prepare ((input_data ,))
494514
495- if quantize_activations :
515+ if config_kind != "w8" :
496516 with quantizer .calibration_mode (), torch .no_grad ():
497517 prepared_model (input_data )
498518
@@ -501,6 +521,7 @@ def test_composite_externalize_export(
501521
502522 finalized_model = quantizer .finalize (backend = ExportBackend .CoreAI )
503523
524+ expected_quantize_count = expected_quantize_counts [config_kind ]
504525 export_utils .convert_and_verify (
505526 finalized_model = finalized_model ,
506527 input_data = input_data ,
0 commit comments