1#ifndef FREE_TENSOR_BOUNDS_H
2#define FREE_TENSOR_BOUNDS_H
6#include <unordered_set>
19 std::optional<std::unordered_set<std::string>> allNames_;
29 const std::unordered_set<std::string> &
allNames();
39 std::optional<std::unordered_set<std::string>> allNames_;
48 const std::unordered_set<std::string> &
allNames();
56UpperBound add(
const UpperBound &b1,
const UpperBound &b2);
57LowerBound add(
const LowerBound &b1,
const LowerBound &b2);
59UpperBound sub(
const UpperBound &b1,
const LowerBound &b2);
60LowerBound sub(
const LowerBound &b1,
const UpperBound &b2);
64UpperBound mul(
const UpperBound &b,
int k);
65LowerBound mul(
const LowerBound &b,
int k);
69UpperBound floorDiv(
const UpperBound &b,
int k);
70LowerBound floorDiv(
const LowerBound &b,
int k);
71UpperBound ceilDiv(
const UpperBound &b,
int k);
72LowerBound ceilDiv(
const LowerBound &b,
int k);
74bool alwaysLT(
const UpperBound &b1,
const LowerBound &b2);
75bool alwaysLE(
const UpperBound &b1,
const LowerBound &b2);
83std::pair<std::optional<LowerBound>, std::optional<UpperBound>>
85 typedef std::pair<std::optional<LowerBound>, std::optional<UpperBound>>
91 std::optional<Rational<int64_t>> selfK;
94 for (
auto &&[k, a] : _lin.
coeff_) {
96 ASSERT(!selfK.has_value());
97 selfK = std::make_optional<Rational<int64_t>>(k);
102 if (!selfK.has_value() || *selfK == 0) {
103 return RetType(std::nullopt, std::nullopt);
109 cmp = detail::reverseCmp(cmp);
111 lin.
bias_ /= -*selfK;
112 for (
auto &item : lin.
coeff_) {
121 case ASTNodeType::LE:
122 return RetType(std::nullopt, std::make_optional<UpperBound>(lin));
123 case ASTNodeType::LT:
128 case ASTNodeType::GE:
129 return RetType(std::make_optional<LowerBound>(lin), std::nullopt);
130 case ASTNodeType::GT:
135 case ASTNodeType::EQ:
136 return RetType(std::make_optional<LowerBound>(lin),
137 std::make_optional<UpperBound>(lin));
139 return RetType(std::nullopt, std::nullopt);
147 case ASTNodeType::LT:
148 return ASTNodeType::GT;
149 case ASTNodeType::LE:
150 return ASTNodeType::GE;
151 case ASTNodeType::GT:
152 return ASTNodeType::LT;
153 case ASTNodeType::GE:
154 return ASTNodeType::LE;
155 case ASTNodeType::EQ:
156 return ASTNodeType::EQ;
157 case ASTNodeType::NE:
158 return ASTNodeType::NE;
LowerBound(const Expr &expr)
Definition: bounds.h:43
friend std::ostream & operator<<(std::ostream &os, const LowerBound &u)
Definition: bounds.h:51
LowerBound(const LinearExpr< Rational< int64_t > > &lin)
Definition: bounds.h:44
const LinearExpr< Rational< int64_t > > & lin() const
Definition: bounds.h:49
LowerBound(LinearExpr< Rational< int64_t > > &&lin)
Definition: bounds.h:45
friend std::ostream & operator<<(std::ostream &os, const UpperBound &b)
Definition: bounds.h:32
UpperBound(LinearExpr< Rational< int64_t > > &&lin)
Definition: bounds.h:26
const Expr & expr()
Definition: bounds.cc:131
UpperBound(const Expr &expr)
Definition: bounds.h:23
const LinearExpr< Rational< int64_t > > & lin() const
Definition: bounds.h:30
UpperBound(const LinearExpr< Rational< int64_t > > &lin)
Definition: bounds.h:25
#define ASSERT(expr)
Definition: except.h:152
ASTNodeType reverseCmp(ASTNodeType type)
Definition: bounds.h:145
Definition: allocator.h:9
std::pair< std::optional< LowerBound >, std::optional< UpperBound > > lin2bounds(const LinearExpr< T > &_lin, ASTNodeType cmp, const Expr &x)
Definition: bounds.h:84
Expr deepCopy(const Expr &op)
Definition: ast.cc:364
std::unordered_set< std::string > allNames(const AST &op, bool noRecurseIdx=false, bool noRecurseSubStmt=false)
Definition: all_uses.h:134
ASTNodeType
Definition: ast.h:20
freetensor::Rational< T > abs(const freetensor::Rational< T > &x)
Definition: rational.h:85
T bias_
Definition: linear.h:28
std::vector< Scale< T > > coeff_
Definition: linear.h:27