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

[TIR][Arith] Prove conditionals by transitively applying knowns #12863

Merged
merged 20 commits into from
Oct 7, 2022

Conversation

Lunderberg
Copy link
Contributor

@Lunderberg Lunderberg commented Sep 21, 2022

This commit adds a new sub-analyzer, TransitiveComparisonAnalyzer, which attempts to apply multiple known comparisons to prove an unknown. For example, a <= b and b <= c imply that a <= c. These simplifications are necessary for simplifying conditionals resulting from padded layout transformations (#12261).

While some of these conditions may be proven using ConstIntBoundAnalyzer or IntSetAnalyzer, each has some limitations. ConstIntBoundAnalyzer can only compare against a constant, IntSetAnalyzer internally calls RewriteSimplifier which can result in infinite recursion, and neither can handle not-equal conditions because it would require tracking multiple intervals per expression. Therefore, introducing a new sub-analyzer for these simplifications.

@Lunderberg Lunderberg force-pushed the transitive_comparisons branch 2 times, most recently from 5e267d7 to edd1994 Compare September 22, 2022 17:07
This commit adds a new sub-analyzer, `TransitiveComparisonAnalyzer`,
which attempts to apply multiple known comparisons to prove an
unknown.  For example, `a <= b` and `b <= c` imply that `a <= c`.
These simplifications are necessary for simplifying conditionals
resulting from padded layout
transformations (apache#12261).

While some of these conditions may be proven using
`ConstIntBoundAnalyzer` or `IntSetAnalyzer`, each has some
limitations.  `ConstIntBoundAnalyzer` can only compare against a
constant, `IntSetAnalyzer` internally calls `RewriteSimplifier` which
can result in infinite recursion, and neither can handle not-equal
conditions because it would require tracking multiple intervals per
expression.  Therefore, introducing a new sub-analyzer for these
simplifications.
In g++ 7, defining a default constructor attempts to define the
destructor, which fails because `Impl` is an incomplete type.  As far
as I should tell, the destructor should only be defined at the point
where `~TransitiveComparisonAnalyzer` is defined, at which point
`Impl` has a full definition.  This issue does not occur in g++ 10.
@Lunderberg
Copy link
Contributor Author

Current failures are timeouts during apps/microtvm/ethosu/run_demo.sh. The demo passes locally, but the runtime has increased from 1m22s to 5m48s, which would make it trip the timeout in tests/scripts/task_demo_microtvm.sh. Prior to merging this commit, the additional simplifications should be explicitly enabled.

@Lunderberg
Copy link
Contributor Author

The additional simplifications are now optional, and can be opted-in either through explicit flags with RewriteSimplifier::SetEnabledFeatures, or through a PassContext when using tir::transform::Simplify. Each currently supports only a single flag for the transitive search through inequalities, but will have additional flags added for simplifications required by #12261.

Copy link
Contributor

@csullivan csullivan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a very cool analyzer, I really like how clean the implementation ended up being!

include/tvm/arith/analyzer.h Show resolved Hide resolved
include/tvm/arith/analyzer.h Outdated Show resolved Hide resolved
include/tvm/arith/analyzer.h Outdated Show resolved Hide resolved
include/tvm/arith/analyzer.h Outdated Show resolved Hide resolved
src/arith/transitive_comparison_analyzer.cc Outdated Show resolved Hide resolved
src/arith/transitive_comparison_analyzer.cc Outdated Show resolved Hide resolved
src/arith/transitive_comparison_analyzer.cc Outdated Show resolved Hide resolved
src/arith/transitive_comparison_analyzer.cc Show resolved Hide resolved
return output;
}

CompareResult TransitiveComparisonAnalyzer::Impl::TryCompareFromLHS(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: TryCompareFromLHS is a bit long

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, good point. Renamed to DFSFromLHS, which hopefully works with the updated documentation to reduce the verbosity.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh shoot sorry I was meaning the function length was quite long and could be easier to understand if factored but it was completely a nitpick and not necessary given everything else looks good now. But I do like the new name too!

Copy link
Contributor

@csullivan csullivan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thank you @Lunderberg!

@csullivan csullivan merged commit fc333f9 into apache:main Oct 7, 2022
@Lunderberg Lunderberg deleted the transitive_comparisons branch October 7, 2022 17:59
Lunderberg added a commit to Lunderberg/tvm that referenced this pull request Oct 10, 2022
Previously, the checks for a literal constraint would find exact
matches for an inequality, but any alterations to the conditional
would break this exact matching.  This commit introduces checks for
constant offsets relative to a known value.  These checks are not
always expressible using the existing `ConstIntSetAnalyzer`, which
represents allowed values using a single contiguous
region.  (e.g. `i!=5` is not representable, because it requires a
region for `i<5` and another for `i>5`.)

This implementation reuses the internal representation for
inequalities introduced in apache#12863,
along with much of its implementation.  However, the indirect
comparisons (e.g. using `a < b` and `b < c` to prove that `a < c`)
introduced in that PR still require an explicit flag to be used.
Lunderberg added a commit to Lunderberg/tvm that referenced this pull request Oct 14, 2022
Previously, the checks for a literal constraint would find exact
matches for an inequality, but any alterations to the conditional
would break this exact matching.  This commit introduces checks for
constant offsets relative to a known value.  These checks are not
always expressible using the existing `ConstIntSetAnalyzer`, which
represents allowed values using a single contiguous
region.  (e.g. `i!=5` is not representable, because it requires a
region for `i<5` and another for `i>5`.)

This implementation reuses the internal representation for
inequalities introduced in apache#12863,
along with much of its implementation.  However, the indirect
comparisons (e.g. using `a < b` and `b < c` to prove that `a < c`)
introduced in that PR still require an explicit flag to be used.
Lunderberg added a commit to Lunderberg/tvm that referenced this pull request Oct 18, 2022
Previously, the checks for a literal constraint would find exact
matches for an inequality, but any alterations to the conditional
would break this exact matching.  This commit introduces checks for
constant offsets relative to a known value.  These checks are not
always expressible using the existing `ConstIntSetAnalyzer`, which
represents allowed values using a single contiguous
region.  (e.g. `i!=5` is not representable, because it requires a
region for `i<5` and another for `i>5`.)

This implementation reuses the internal representation for
inequalities introduced in apache#12863,
along with much of its implementation.  However, the indirect
comparisons (e.g. using `a < b` and `b < c` to prove that `a < c`)
introduced in that PR still require an explicit flag to be used.
Lunderberg added a commit to Lunderberg/tvm that referenced this pull request Oct 19, 2022
…straints

Previously, the checks for a literal constraint would find exact
matches for an inequality, but any alterations to the conditional
would break this exact matching.  This commit introduces checks for
constant offsets relative to a known value.  These checks are not
always expressible using the existing `ConstIntSetAnalyzer`, which
represents allowed values using a single contiguous
region.  (e.g. `i!=5` is not representable, because it requires a
region for `i<5` and another for `i>5`.)

This implementation reuses the internal representation for
inequalities introduced in apache#12863,
along with much of its implementation.  However, the indirect
comparisons (e.g. using `a < b` and `b < c` to prove that `a < c`)
introduced in that PR still require an explicit flag to be used.
Lunderberg added a commit to Lunderberg/tvm that referenced this pull request Oct 28, 2022
Previously, the checks for a literal constraint would find exact
matches for an inequality, but any alterations to the conditional
would break this exact matching.  This commit introduces checks for
constant offsets relative to a known value.  These checks are not
always expressible using the existing `ConstIntSetAnalyzer`, which
represents allowed values using a single contiguous
region.  (e.g. `i!=5` is not representable, because it requires a
region for `i<5` and another for `i>5`.)

This implementation reuses the internal representation for
inequalities introduced in apache#12863,
along with much of its implementation.  However, the indirect
comparisons (e.g. using `a < b` and `b < c` to prove that `a < c`)
introduced in that PR still require an explicit flag to be used.
Lunderberg added a commit to Lunderberg/tvm that referenced this pull request Oct 28, 2022
Previously, the checks for a literal constraint would find exact
matches for an inequality, but any alterations to the conditional
would break this exact matching.  This commit introduces checks for
constant offsets relative to a known value.  These checks are not
always expressible using the existing `ConstIntSetAnalyzer`, which
represents allowed values using a single contiguous
region.  (e.g. `i!=5` is not representable, because it requires a
region for `i<5` and another for `i>5`.)

This implementation reuses the internal representation for
inequalities introduced in apache#12863,
along with much of its implementation.  However, the indirect
comparisons (e.g. using `a < b` and `b < c` to prove that `a < c`)
introduced in that PR still require an explicit flag to be used.
Lunderberg added a commit to Lunderberg/tvm that referenced this pull request Oct 28, 2022
…straints

Previously, the checks for a literal constraint would find exact
matches for an inequality, but any alterations to the conditional
would break this exact matching.  This commit introduces checks for
constant offsets relative to a known value.  These checks are not
always expressible using the existing `ConstIntSetAnalyzer`, which
represents allowed values using a single contiguous
region.  (e.g. `i!=5` is not representable, because it requires a
region for `i<5` and another for `i>5`.)

This implementation reuses the internal representation for
inequalities introduced in apache#12863,
along with much of its implementation.  However, the indirect
comparisons (e.g. using `a < b` and `b < c` to prove that `a < c`)
introduced in that PR still require an explicit flag to be used.
csullivan pushed a commit that referenced this pull request Oct 29, 2022
…13023)

Previously, the checks for a literal constraint would find exact
matches for an inequality, but any alterations to the conditional
would break this exact matching.  This commit introduces checks for
constant offsets relative to a known value.  These checks are not
always expressible using the existing `ConstIntSetAnalyzer`, which
represents allowed values using a single contiguous
region.  (e.g. `i!=5` is not representable, because it requires a
region for `i<5` and another for `i>5`.)

This implementation reuses the internal representation for
inequalities introduced in #12863,
along with much of its implementation.  However, the indirect
comparisons (e.g. using `a < b` and `b < c` to prove that `a < c`)
introduced in that PR still require an explicit flag to be used.
xinetzone pushed a commit to daobook/tvm that referenced this pull request Nov 10, 2022
…pache#13023)

Previously, the checks for a literal constraint would find exact
matches for an inequality, but any alterations to the conditional
would break this exact matching.  This commit introduces checks for
constant offsets relative to a known value.  These checks are not
always expressible using the existing `ConstIntSetAnalyzer`, which
represents allowed values using a single contiguous
region.  (e.g. `i!=5` is not representable, because it requires a
region for `i<5` and another for `i>5`.)

This implementation reuses the internal representation for
inequalities introduced in apache#12863,
along with much of its implementation.  However, the indirect
comparisons (e.g. using `a < b` and `b < c` to prove that `a < c`)
introduced in that PR still require an explicit flag to be used.
xinetzone pushed a commit to daobook/tvm that referenced this pull request Nov 25, 2022
…he#12863)

This commit adds a new sub-analyzer, `TransitiveComparisonAnalyzer`,
which attempts to apply multiple known comparisons to prove an
unknown.  For example, `a <= b` and `b <= c` imply that `a <= c`.
These simplifications are necessary for simplifying conditionals
resulting from padded layout
transformations (apache#12261).

While some of these conditions may be proven using
`ConstIntBoundAnalyzer` or `IntSetAnalyzer`, each has some
limitations.  `ConstIntBoundAnalyzer` can only compare against a
constant, `IntSetAnalyzer` internally calls `RewriteSimplifier` which
can result in infinite recursion, and neither can handle not-equal
conditions because it would require tracking multiple intervals per
expression.  Therefore, introducing a new sub-analyzer for these
simplifications.

* Change mutable reference to mutable pointer

* Remove nullptr default on Impl unique_ptr

In g++ 7, defining a default constructor attempts to define the
destructor, which fails because `Impl` is an incomplete type.  As far
as I should tell, the destructor should only be defined at the point
where `~TransitiveComparisonAnalyzer` is defined, at which point
`Impl` has a full definition.  This issue does not occur in g++ 10.

* Require opt-in for CPU-intensive simplifications

* Document the intent of using bitflags

* Rename "Feature" to "Extension"

* Use TVM_DLL on new public member functions

* Remove duplicate BaseBeforeAfter.transform definition

* Explicitly enable extension for unit tests that require it

* Fix accidentally duplicate test case

* Improve TryCompareFromLHS documentation

* Update wording to distinguish `knowns_` and `scoped_knowns_`

* Better documentation for Key enum

* Document the normalization of LT/GT

* Removed unused PrimExpr temp

* Call out modifications of the `compared_to_x` contents

* Pointed to `Comparison::Comparison` for normalization details

* Updated to clarify right/RHS.

* Rename TryCompareFromLHS to DFSFromLHS
xinetzone pushed a commit to daobook/tvm that referenced this pull request Nov 25, 2022
…pache#13023)

Previously, the checks for a literal constraint would find exact
matches for an inequality, but any alterations to the conditional
would break this exact matching.  This commit introduces checks for
constant offsets relative to a known value.  These checks are not
always expressible using the existing `ConstIntSetAnalyzer`, which
represents allowed values using a single contiguous
region.  (e.g. `i!=5` is not representable, because it requires a
region for `i<5` and another for `i>5`.)

This implementation reuses the internal representation for
inequalities introduced in apache#12863,
along with much of its implementation.  However, the indirect
comparisons (e.g. using `a < b` and `b < c` to prove that `a < c`)
introduced in that PR still require an explicit flag to be used.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants