Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use input size limits for constant folding #1903

Merged
merged 4 commits into from
Oct 12, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 17 additions & 1 deletion onnxscript/optimizer/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,17 +111,33 @@ def optimize(
return model


_DEFAULT_CONSTANT_FOLD_INPUT_SIZE_LIMIT = (
_constant_folding._DEFAULT_CONSTANT_FOLD_INPUT_SIZE_LIMIT
)

_DEFAULT_CONSTANT_FOLD_OUTPUT_SIZE_LIMIT = (
_constant_folding._DEFAULT_CONSTANT_FOLD_OUTPUT_SIZE_LIMIT
)


def optimize_ir(
model: ir.Model,
num_iterations: int = 2,
*,
onnx_shape_inference: bool = True,
stop_if_no_change: bool = True,
input_size_limit: int = _DEFAULT_CONSTANT_FOLD_INPUT_SIZE_LIMIT,
output_size_limit: int = _DEFAULT_CONSTANT_FOLD_OUTPUT_SIZE_LIMIT,
gramalingam marked this conversation as resolved.
Show resolved Hide resolved
) -> None:
del stop_if_no_change # Looks like rewriter doesn't support this yet.
_inliner.inline(model)
for _ in range(num_iterations):
_constant_folding.fold_constants(model, onnx_shape_inference=onnx_shape_inference)
_constant_folding.fold_constants(
model,
onnx_shape_inference=onnx_shape_inference,
input_size_limit=input_size_limit,
output_size_limit=output_size_limit,
)
rewriter.rewrite(model, pattern_rewrite_rules=_DEFAULT_REWRITE_RULES)
remove_unused_nodes(model)

Expand Down
33 changes: 26 additions & 7 deletions onnxscript/optimizer/_constant_folding.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,9 @@
)


_DEFAULT_CONSTANT_FOLD_SIZE_LIMIT = constant_folding._DEFAULT_CONSTANT_FOLD_SIZE_LIMIT
_DEFAULT_CONSTANT_FOLD_INPUT_SIZE_LIMIT = 1024

_DEFAULT_CONSTANT_FOLD_OUTPUT_SIZE_LIMIT = constant_folding._DEFAULT_CONSTANT_FOLD_SIZE_LIMIT

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -550,11 +552,16 @@

def __init__(
self,
*,
external_data_folder: str,
do_shape_inference: bool,
shape_inference: bool,
input_size_limit: int,
output_size_limit: int,
) -> None:
self._external_data_folder = external_data_folder
self._do_shape_inference = do_shape_inference
self._shape_inference = shape_inference
self._input_size_limit = input_size_limit
self._output_size_limit = output_size_limit
self._init()

def _init(self) -> None:
Expand Down Expand Up @@ -632,7 +639,7 @@

irvalue.const_value = _convenience.tensor(value)

if value.nbytes > _DEFAULT_CONSTANT_FOLD_SIZE_LIMIT:
if value.nbytes > self._output_size_limit:
logger.info(
"Skip storing constant folded nvalue %s due to large size %s.",
irvalue.name,
Expand Down Expand Up @@ -667,7 +674,7 @@
# TODO(rama): consider merging type/other info from both values

# Do incremental shape inference
if self._do_shape_inference and not is_control_flow_op(node):
if self._shape_inference and not is_control_flow_op(node):
self._do_inference(node)

if node.domain not in self.opset_imports:
Expand Down Expand Up @@ -696,6 +703,14 @@
if any(x is None for x in input_values):
return None

if any(input.size > self._input_size_limit for input in input_values):
Fixed Show fixed Hide fixed
gramalingam marked this conversation as resolved.
Show resolved Hide resolved
if logger.isEnabledFor(logging.DEBUG):
input_sizes = [input.size for input in input_values]
Fixed Show fixed Hide fixed
logger.debug(

Check warning on line 709 in onnxscript/optimizer/_constant_folding.py

View check run for this annotation

Codecov / codecov/patch

onnxscript/optimizer/_constant_folding.py#L708-L709

Added lines #L708 - L709 were not covered by tests
f"Skipping constant folding for op {node.op_type} due to large input size: {input_sizes}"
Fixed Show fixed Hide fixed
gramalingam marked this conversation as resolved.
Show resolved Hide resolved
)
return None

Check warning on line 712 in onnxscript/optimizer/_constant_folding.py

View check run for this annotation

Codecov / codecov/patch

onnxscript/optimizer/_constant_folding.py#L712

Added line #L712 was not covered by tests

# Filter out bfloat16 cases?
def convert(av):
if av.type == ir.AttributeType.TENSOR:
Expand Down Expand Up @@ -770,14 +785,18 @@
external_data_folder: str = "",
*,
onnx_shape_inference: bool = False,
input_size_limit: int = _DEFAULT_CONSTANT_FOLD_INPUT_SIZE_LIMIT,
output_size_limit: int = _DEFAULT_CONSTANT_FOLD_OUTPUT_SIZE_LIMIT,
) -> bool:
"""
Applies constant folding optimization to the model.
Returns true iff the model was modified.
"""
folder = ConstantFolder(
external_data_folder,
onnx_shape_inference,
external_data_folder=external_data_folder,
shape_inference=onnx_shape_inference,
input_size_limit=input_size_limit,
output_size_limit=output_size_limit,
)
folder.visit_model(model)
for op in folder.counts:
Expand Down
Loading