Skip to content

Commit d5f9324

Browse files
committed
Update base for Update on "Support export program in intermediate numeric discrepancy detector"
This diff enables intermediate numeric discrepancy detector to leverage export program as label. More specific, if user creates etrecord with exported program, and the exported program is one of the exported programs in the export flow, then our numeric discrepancy detector will use it as label. Otherwise, we will continue use edge dialect graph as label. Differential Revision: [D78298935](https://our.internmc.facebook.com/intern/diff/D78298935/) [ghstack-poisoned]
2 parents d2c0f58 + e44da93 commit d5f9324

File tree

38 files changed

+815
-796
lines changed

38 files changed

+815
-796
lines changed
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
ab43fe4bdf5ccd82897f0e982c451a0127bd175e
1+
2dccff7dcf56b0d168ebfd7ca08bdeca37273c56

backends/arm/arm_backend.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ def ethosu_compile_spec(
128128
self.compiler_flags.append("--output-format=raw")
129129
self.compiler_flags.append("--debug-force-regor")
130130

131-
base_tosa_version = "TOSA-0.80+BI"
131+
base_tosa_version = "TOSA-1.0+INT"
132132
if "u55" in target:
133133
# Add the Ethos-U55 extension marker
134134
base_tosa_version += "+u55"

backends/arm/quantizer/arm_quantizer_utils.py

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,22 +18,21 @@
1818
from torch.fx import GraphModule, Node
1919

2020
from torchao.quantization.pt2e.quantizer import QuantizationAnnotation
21+
from torchao.quantization.pt2e.quantizer.quantizer import Q_ANNOTATION_KEY
2122

2223

2324
def is_annotated(node: Node) -> bool:
2425
"""Given a node return whether the node is annotated."""
2526
return (
26-
"quantization_annotation" in node.meta
27-
and cast(
28-
QuantizationAnnotation, node.meta["quantization_annotation"]
29-
)._annotated
27+
Q_ANNOTATION_KEY in node.meta
28+
and cast(QuantizationAnnotation, node.meta[Q_ANNOTATION_KEY])._annotated
3029
)
3130

3231

3332
def is_output_annotated(node: Node) -> bool:
3433
"""Given a node, return whether the output of the node is annotated."""
35-
if "quantization_annotation" in node.meta:
36-
annotation = cast(QuantizationAnnotation, node.meta["quantization_annotation"])
34+
if Q_ANNOTATION_KEY in node.meta:
35+
annotation = cast(QuantizationAnnotation, node.meta[Q_ANNOTATION_KEY])
3736
return annotation._annotated and annotation.output_qspec is not None
3837
else:
3938
return False
@@ -43,9 +42,9 @@ def mark_node_as_annotated(node: Node) -> None:
4342
"""Marks node as annotated. If needed, an empty QuantizationAnnotation is added
4443
to the quantization_annotation node meta entry.
4544
"""
46-
if "quantization_annotation" not in node.meta:
47-
node.meta["quantization_annotation"] = QuantizationAnnotation()
48-
node.meta["quantization_annotation"]._annotated = True
45+
if Q_ANNOTATION_KEY not in node.meta:
46+
node.meta[Q_ANNOTATION_KEY] = QuantizationAnnotation()
47+
node.meta[Q_ANNOTATION_KEY]._annotated = True
4948

5049

5150
def is_ok_for_quantization(node: Node, gm: GraphModule):

backends/arm/test/test_arm_baremetal.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ test_models_ethos-u85() { # End to End model tests using model_test.py
228228
python3 backends/arm/test/test_model.py --test_output=arm_test/test_model --target=ethos-u85-256 --model=mv2 --extra_flags="-DET_ATOL=2.00 -DET_RTOL=2.00"
229229
python3 backends/arm/test/test_model.py --test_output=arm_test/test_model --target=ethos-u85-512 --model=mv3 --extra_flags="-DET_ATOL=5.00 -DET_RTOL=5.00"
230230
python3 backends/arm/test/test_model.py --test_output=arm_test/test_model --target=ethos-u85-128 --model=lstm --extra_flags="-DET_ATOL=0.03 -DET_RTOL=0.03"
231-
python3 backends/arm/test/test_model.py --test_output=arm_test/test_model --target=ethos-u85-128 --model=w2l --extra_flags="-DET_ATOL=0.01 -DET_RTOL=0.01"
231+
#python3 backends/arm/test/test_model.py --test_output=arm_test/test_model --target=ethos-u85-128 --model=w2l --extra_flags="-DET_ATOL=0.01 -DET_RTOL=0.01" # Takes long time to run
232232
python3 backends/arm/test/test_model.py --test_output=arm_test/test_model --target=ethos-u85-256 --model=ic4 --extra_flags="-DET_ATOL=0.8 -DET_RTOL=0.8" --timeout=2400
233233
python3 backends/arm/test/test_model.py --test_output=arm_test/test_model --target=ethos-u85-128 --model=resnet18 --extra_flags="-DET_ATOL=0.2 -DET_RTOL=0.2"
234234
python3 backends/arm/test/test_model.py --test_output=arm_test/test_model --target=ethos-u85-128 --model=resnet50 --extra_flags="-DET_ATOL=0.2 -DET_RTOL=0.2"

backends/cadence/aot/compiler.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,9 @@ def _lower_ep_to_edge(
228228
"""
229229
Lower an ExportedProgram to an EdgeProgramManager (in edge IR).
230230
"""
231+
# Apply passes which transform the ExportedProgram before it gets lowered to edge.
232+
expo_program = apply_torch_ops_passes(expo_program)
233+
231234
# Call to_edge to convert the graph to edge IR.
232235
# Note: dim_order is skipped (https://github.com/pytorch/executorch/issues/3704)
233236
edge_prog_manager = to_edge(
@@ -263,9 +266,6 @@ def export_to_edge(
263266
# Export the model into an ExportedProgram.
264267
expo_program = trace(model, inputs)
265268

266-
# Apply passes which transform the ExportedProgram before it gets lowered to edge.
267-
expo_program = apply_torch_ops_passes(expo_program)
268-
269269
# Lower the model to edge IR.
270270
edge_prog_manager = _lower_ep_to_edge(
271271
expo_program, dump_graphs, constant_methods, core_aten_exceptions

backends/cadence/aot/ops_registrations.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,14 @@
276276
"requantize.per_tensor_out(Tensor input, float in_scale, int in_zero_point, float out_scale, "
277277
"int out_zero_point, ScalarType out_dtype, *, Tensor(a!) out) -> Tensor(a!)"
278278
)
279+
lib.define(
280+
"roi_align_box_processor.out(Tensor rois, int output_size_h, int output_size_w, "
281+
"int sampling_ratio, bool aligned, *, Tensor(a!) out) -> Tensor(a!)"
282+
)
283+
lib.define(
284+
"roi_align_box_processor(Tensor rois, int output_size_h, int output_size_w, "
285+
"int sampling_ratio, bool aligned) -> (Tensor out)"
286+
)
279287

280288
# Custom ops with aten namespace. Need to specify the lib var as FRAGMENT type as aten library is already defined
281289
aten_lib = Library("aten", "FRAGMENT")
@@ -1038,3 +1046,14 @@ def idma_store_impl(
10381046
channel: int = 0,
10391047
) -> torch.Tensor:
10401048
return copy_idma_copy_impl(src, task_num, channel)
1049+
1050+
1051+
@register_fake("cadence::roi_align_box_processor")
1052+
def roi_align_box_processor_meta(
1053+
rois: torch.Tensor,
1054+
output_size_h: int,
1055+
output_size_w: int,
1056+
sampling_ratio: int,
1057+
aligned: bool,
1058+
) -> torch.Tensor:
1059+
return rois.new_empty((rois.shape[0], 80), dtype=torch.uint8)

backends/cadence/aot/quantizer/quantizer.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
QuantizationSpec,
4343
Quantizer,
4444
)
45+
from torchao.quantization.pt2e.quantizer.quantizer import Q_ANNOTATION_KEY
4546

4647

4748
act_qspec_asym8s = QuantizationSpec(
@@ -127,7 +128,7 @@ def annotate(self, model: torch.fx.GraphModule) -> torch.fx.GraphModule:
127128

128129
for output, *custom_spec in anchors.output:
129130
# pyre-ignore[16]: no attribute
130-
output.meta["quantization_annotation"] = QuantizationAnnotation(
131+
output.meta[Q_ANNOTATION_KEY] = QuantizationAnnotation(
131132
# pyre-ignore[6]: incompatible parameter type
132133
output_qspec=(custom_spec[0] if custom_spec else output_act_qspec),
133134
_annotated=True,
@@ -143,7 +144,7 @@ def annotate_inputs(
143144
for node, idx, *custom_spec in inputs:
144145
# pyre-ignore[16]: no attribute
145146
annotation = node.meta.get(
146-
"quantization_annotation",
147+
Q_ANNOTATION_KEY,
147148
QuantizationAnnotation(_annotated=True),
148149
)
149150
arg = (
@@ -157,21 +158,21 @@ def annotate_inputs(
157158
custom_spec[0] if custom_spec else spec
158159
)
159160
# pyre-ignore[16]: no attribute
160-
node.meta["quantization_annotation"] = annotation
161+
node.meta[Q_ANNOTATION_KEY] = annotation
161162

162163
def annotate_weights_or_biases(
163164
weights_or_biases: List[Tuple[fx.Node, int]],
164165
spec: Optional[QuantizationSpec],
165166
) -> None:
166167
for node, idx, *custom_spec in weights_or_biases:
167168
annotation = node.meta.get(
168-
"quantization_annotation",
169+
Q_ANNOTATION_KEY,
169170
QuantizationAnnotation(_annotated=True),
170171
)
171172
annotation.input_qspec_map[node.args[idx]] = (
172173
custom_spec[0] if custom_spec else spec
173174
)
174-
node.meta["quantization_annotation"] = annotation
175+
node.meta[Q_ANNOTATION_KEY] = annotation
175176

176177
# pyre-ignore[6]: incompatible parameter type
177178
annotate_inputs(anchors.inputs, input_act_qspec)

backends/cadence/aot/quantizer/utils.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
SourcePartition,
2222
)
2323
from torchao.quantization.pt2e import ObserverOrFakeQuantize
24+
from torchao.quantization.pt2e.quantizer.quantizer import Q_ANNOTATION_KEY
2425

2526

2627
def quantize_tensor_multiplier(
@@ -88,8 +89,7 @@ def is_annotated(nodes: List[fx.Node]) -> bool:
8889
annotated = False
8990
for node in nodes:
9091
annotated = annotated or (
91-
"quantization_annotation" in node.meta
92-
and node.meta["quantization_annotation"]._annotated
92+
Q_ANNOTATION_KEY in node.meta and node.meta[Q_ANNOTATION_KEY]._annotated
9393
)
9494
return annotated
9595

backends/cadence/aot/replace_ops.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2328,12 +2328,15 @@ def call(self, graph_module: torch.fx.GraphModule) -> PassResult:
23282328

23292329
# Extract an argument to a separate full op.
23302330
with graph_module.graph.inserting_before(mul_node):
2331-
full_tensor = graph_module.graph.call_function(
2331+
full_node = graph_module.graph.call_function(
23322332
torch.ops.aten.full.default, args=([1], full_arg)
23332333
)
2334+
full_node.meta = mul_node.meta
2335+
full_node.meta["val"] = [1]
23342336
new_mul_node = graph_module.graph.call_function(
2335-
torch.ops.aten.mul.Tensor, args=(x_arg, full_tensor)
2337+
torch.ops.aten.mul.Tensor, args=(x_arg, full_node)
23362338
)
2339+
new_mul_node.meta = mul_node.meta
23372340
# Replace the old mul with a newly created mul.
23382341
mul_node.replace_all_uses_with(new_mul_node)
23392342
graph_module.graph.erase_node(mul_node)

backends/cortex_m/test/test_replace_quant_nodes.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
QuantizationSpec,
2626
Quantizer,
2727
)
28+
from torchao.quantization.pt2e.quantizer.quantizer import Q_ANNOTATION_KEY
2829

2930

3031
@dataclass(eq=True, frozen=True)
@@ -67,18 +68,15 @@ def annotate(self, model: GraphModule):
6768
]:
6869
continue
6970

70-
if (
71-
"quantization_annotation" in node.meta
72-
and node.meta["quantization_annotation"]._annotated
73-
):
71+
if Q_ANNOTATION_KEY in node.meta and node.meta[Q_ANNOTATION_KEY]._annotated:
7472
continue
7573

7674
input_qspec_map = {
7775
node.args[0]: config.input_activation,
7876
node.args[1]: config.input_activation,
7977
}
8078

81-
node.meta["quantization_annotation"] = QuantizationAnnotation(
79+
node.meta[Q_ANNOTATION_KEY] = QuantizationAnnotation(
8280
input_qspec_map=input_qspec_map,
8381
output_qspec=config.output_activation,
8482
_annotated=True,

0 commit comments

Comments
 (0)