FreeTensor
Loading...
Searching...
No Matches
presburger.h
Go to the documentation of this file.
1#ifndef FREE_TENSOR_PRESBURGER_H
2#define FREE_TENSOR_PRESBURGER_H
3
4#include <cstddef>
5#include <iostream>
6#include <isl/id_type.h>
7#include <string>
8#include <unordered_set>
9#include <vector>
10
11#include <isl/aff.h>
12#include <isl/ctx.h>
13#include <isl/id.h>
14#include <isl/ilp.h>
15#include <isl/map.h>
16#include <isl/options.h>
17#include <isl/set.h>
18#include <isl/space.h>
19#include <isl/space_type.h>
20#include <isl/val.h>
21
22#include <debug.h>
23#include <debug/profile.h>
24#include <except.h>
25#include <ref.h>
26#include <serialize/to_string.h>
27#include <timeout.h>
28
29namespace freetensor {
30
31// Presburger arithmetic, currently implemented with ISL
32
33template <class T> T *GET_ISL_PTR(T *ptr) {
34 ASSERT(ptr != nullptr);
35 return ptr;
36}
37
38#define COPY_ISL_PTR(ptr, type) _COPY_ISL_PTR(ptr, isl_##type##_copy)
39template <class T> T *_COPY_ISL_PTR(const T *ptr, T *(copy)(T *)) {
40 ASSERT(ptr != nullptr);
41 return copy(const_cast<T *>(ptr));
42}
43
44template <class T> T *MOVE_ISL_PTR(T *&ptr) {
45 ASSERT(ptr != nullptr);
46 auto ret = ptr;
47 ptr = nullptr;
48 return ret;
49}
50
58class PBCtx {
59 isl_ctx *ctx_ = nullptr;
60
61 public:
62 PBCtx() : ctx_(isl_ctx_alloc()) {
63 isl_options_set_on_error(ctx_, ISL_ON_ERROR_ABORT);
64 }
65 ~PBCtx() { isl_ctx_free(ctx_); }
66
67 PBCtx(const PBCtx &other) = delete;
68 PBCtx &operator=(const PBCtx &other) = delete;
69 PBCtx(PBCtx &&other) = delete;
70 PBCtx &operator=(PBCtx &&other) = delete;
71
72 isl_ctx *get() const { return GET_ISL_PTR(ctx_); }
73};
74
75class PBMap {
76 Ref<PBCtx> ctx_;
77 isl_map *map_ = nullptr;
78
79 public:
80 PBMap() {}
81 PBMap(const Ref<PBCtx> &ctx, isl_map *map) : ctx_(ctx), map_(map) {}
82 PBMap(const Ref<PBCtx> &ctx, const std::string &str)
83 : ctx_(ctx), map_(isl_map_read_from_str(ctx->get(), str.c_str())) {
84 if (map_ == nullptr) {
85 ERROR("Unable to construct an PBMap from " + str);
86 }
87 }
89 if (map_ != nullptr) {
90 isl_map_free(map_);
91 }
92 }
93
94 PBMap(const PBMap &other) : ctx_(other.ctx_), map_(other.copy()) {}
95 PBMap &operator=(const PBMap &other) {
96 ctx_ = other.ctx_;
97 if (map_ != nullptr) {
98 isl_map_free(map_);
99 }
100 map_ = other.copy();
101 return *this;
102 }
103
104 PBMap(PBMap &&other) : ctx_(std::move(other.ctx_)), map_(other.move()) {}
106 ctx_ = std::move(other.ctx_);
107 if (map_ != nullptr) {
108 isl_map_free(map_);
109 }
110 map_ = other.move();
111 return *this;
112 }
113
114 bool isValid() const { return map_ != nullptr; }
115
116 const auto &ctx() const { return ctx_; }
117 auto &ctx() { return ctx_; }
118
119 isl_map *get() const { return GET_ISL_PTR(map_); }
120 isl_map *copy() const { return COPY_ISL_PTR(map_, map); }
121 isl_map *move() { return MOVE_ISL_PTR(map_); }
122
124 std::string data_;
125
126 public:
128 Serialized(const std::string &data) : data_(data) {}
129 PBMap to(const Ref<PBCtx> &ctx) const { return {ctx, data_}; }
130 bool isValid() const { return !data_.empty(); }
131 const auto &data() const { return data_; }
132 friend std::ostream &operator<<(std::ostream &os, const Serialized &s) {
133 return os << s.data_;
134 }
135 };
136 Serialized toSerialized() const { return {isl_map_to_str(get())}; }
137 PBMap to(const Ref<PBCtx> &ctx) const { return toSerialized().to(ctx); }
138
139 bool empty() const {
140 DEBUG_PROFILE("empty");
141 return isl_map_is_empty(get());
142 }
143 bool isSingleValued() const { return isl_map_is_single_valued(get()); }
144 bool isBijective() const { return isl_map_is_bijective(get()); }
145
146 isl_size nBasic() const { return isl_map_n_basic_map(get()); }
147
148 isl_size nInDims() const { return isl_map_dim(get(), isl_dim_in); }
149 isl_size nOutDims() const { return isl_map_dim(get(), isl_dim_out); }
150 isl_size nParamDims() const { return isl_map_dim(get(), isl_dim_param); }
151
152 const char *nameInDim(unsigned i) const {
153 return isl_map_get_dim_name(get(), isl_dim_in, i);
154 }
155 const char *nameOutDim(unsigned i) const {
156 return isl_map_get_dim_name(get(), isl_dim_out, i);
157 }
158 const char *nameParamDim(unsigned i) const {
159 return isl_map_get_dim_name(get(), isl_dim_param, i);
160 }
161
162 friend std::ostream &operator<<(std::ostream &os, const PBMap &map) {
163 return os << isl_map_to_str(map.map_);
164 }
165};
166
167class PBVal {
168 Ref<PBCtx> ctx_;
169 isl_val *val_ = nullptr;
170
171 public:
172 PBVal() {}
173 PBVal(const Ref<PBCtx> &ctx, isl_val *val) : ctx_(ctx), val_(val) {}
175 if (val_ != nullptr) {
176 isl_val_free(val_);
177 }
178 }
179
180 PBVal(const PBVal &other) : ctx_(other.ctx_), val_(other.copy()) {}
181 PBVal &operator=(const PBVal &other) {
182 ctx_ = other.ctx_;
183 if (val_ != nullptr) {
184 isl_val_free(val_);
185 }
186 val_ = other.copy();
187 return *this;
188 }
189
190 PBVal(PBVal &&other) : ctx_(std::move(other.ctx_)), val_(other.move()) {}
192 ctx_ = std::move(other.ctx_);
193 if (val_ != nullptr) {
194 isl_val_free(val_);
195 }
196 val_ = other.move();
197 return *this;
198 }
199
200 bool isValid() const { return val_ != nullptr; }
201
202 const auto &ctx() const { return ctx_; }
203 auto &ctx() { return ctx_; }
204
205 isl_val *get() const { return GET_ISL_PTR(val_); }
206 isl_val *copy() const { return COPY_ISL_PTR(val_, val); }
207 isl_val *move() { return MOVE_ISL_PTR(val_); }
208
209 bool isNaN() const { return isl_val_is_nan(get()); }
210 bool isRat() const { return isl_val_is_rat(get()); }
211 bool isInt() const { return isl_val_is_int(get()); }
212 bool isInf() const { return isl_val_is_infty(get()); }
213 bool isNegInf() const { return isl_val_is_neginfty(get()); }
214
215 int numSi() const { return isl_val_get_num_si(get()); }
216 int denSi() const { return isl_val_get_den_si(get()); }
217
218 friend std::ostream &operator<<(std::ostream &os, const PBVal &val) {
219 return os << isl_val_to_str(val.val_);
220 }
221};
222
223class PBSet {
224 Ref<PBCtx> ctx_;
225 isl_set *set_ = nullptr;
226
227 public:
228 PBSet() {}
229 PBSet(const Ref<PBCtx> &ctx, isl_set *set) : ctx_(ctx), set_(set) {}
230 PBSet(const Ref<PBCtx> &ctx, const std::string &str)
231 : ctx_(ctx), set_(isl_set_read_from_str(ctx->get(), str.c_str())) {
232 if (set_ == nullptr) {
233 ERROR("Unable to construct an PBSet from " + str);
234 }
235 }
237 if (set_ != nullptr) {
238 isl_set_free(set_);
239 }
240 }
241
242 PBSet(const PBSet &other) : ctx_(other.ctx_), set_(other.copy()) {}
243 PBSet &operator=(const PBSet &other) {
244 ctx_ = other.ctx_;
245 if (set_ != nullptr) {
246 isl_set_free(set_);
247 }
248 set_ = other.copy();
249 return *this;
250 }
251
252 PBSet(PBSet &&other) : ctx_(std::move(other.ctx_)), set_(other.move()) {}
254 ctx_ = std::move(other.ctx_);
255 if (set_ != nullptr) {
256 isl_set_free(set_);
257 }
258 set_ = other.move();
259 return *this;
260 }
261
262 bool isValid() const { return set_ != nullptr; }
263
264 const auto &ctx() const { return ctx_; }
265 auto &ctx() { return ctx_; }
266
267 isl_set *get() const { return GET_ISL_PTR(set_); }
268 isl_set *copy() const { return COPY_ISL_PTR(set_, set); }
269 isl_set *move() { return MOVE_ISL_PTR(set_); }
270
272 std::string data_;
273
274 public:
276 Serialized(const std::string &data) : data_(data) {}
277 PBSet to(const Ref<PBCtx> &ctx) const { return {ctx, data_}; }
278 bool isValid() const { return !data_.empty(); }
279 const auto &data() const { return data_; }
280 friend std::ostream &operator<<(std::ostream &os, const Serialized &s) {
281 return os << s.data_;
282 }
283 };
284 Serialized toSerialized() const { return {isl_set_to_str(get())}; }
285 PBSet to(const Ref<PBCtx> &ctx) const { return toSerialized().to(ctx); }
286
287 bool empty() const {
288 DEBUG_PROFILE("empty");
289 return isl_set_is_empty(get());
290 }
291
292 bool isSingleValued() const { return isl_set_is_singleton(get()); }
293
294 isl_size nBasic() const { return isl_set_n_basic_set(set_); }
295
296 isl_size nDims() const { return isl_set_dim(get(), isl_dim_set); }
297 isl_size nParamDims() const { return isl_set_dim(get(), isl_dim_param); }
298
299 const char *nameDim(unsigned i) const {
300 return isl_set_get_dim_name(get(), isl_dim_set, i);
301 }
302 const char *nameParamDim(unsigned i) const {
303 return isl_set_get_dim_name(get(), isl_dim_param, i);
304 }
305
306 bool hasLowerBound(unsigned i) const {
307 return isl_set_dim_has_lower_bound(get(), isl_dim_set, i);
308 }
309 bool hasUpperBound(unsigned i) const {
310 return isl_set_dim_has_upper_bound(get(), isl_dim_set, i);
311 }
312
313 friend std::ostream &operator<<(std::ostream &os, const PBSet &set) {
314 return os << isl_set_to_str(set.set_);
315 }
316};
317
318class PBSpace {
319 Ref<PBCtx> ctx_;
320 isl_space *space_ = nullptr;
321
322 public:
324 PBSpace(const Ref<PBCtx> &ctx, isl_space *space)
325 : ctx_(ctx), space_(space) {}
326 PBSpace(const PBSet &set)
327 : ctx_(set.ctx()), space_(isl_set_get_space(set.get())) {}
328 PBSpace(const PBMap &map)
329 : ctx_(map.ctx()), space_(isl_map_get_space(map.get())) {}
331 if (space_ != nullptr) {
332 isl_space_free(space_);
333 }
334 }
335
336 PBSpace(const PBSpace &other) : ctx_(other.ctx_), space_(other.copy()) {}
337 PBSpace &operator=(const PBSpace &other) {
338 ctx_ = other.ctx_;
339 if (space_ != nullptr) {
340 isl_space_free(space_);
341 }
342 space_ = other.copy();
343 return *this;
344 }
345
347 : ctx_(std::move(other.ctx_)), space_(other.move()) {}
349 ctx_ = std::move(other.ctx_);
350 if (space_ != nullptr) {
351 isl_space_free(space_);
352 }
353 space_ = other.move();
354 return *this;
355 }
356
357 bool isValid() const { return space_ != nullptr; }
358
359 const auto &ctx() const { return ctx_; }
360 auto &ctx() { return ctx_; }
361
362 isl_space *get() const { return GET_ISL_PTR(space_); }
363 isl_space *copy() const { return COPY_ISL_PTR(space_, space); }
364 isl_space *move() { return MOVE_ISL_PTR(space_); }
365
366 bool operator==(const PBSpace &other) const {
367 if (space_ == nullptr || other.space_ == nullptr)
368 return space_ == other.space_;
369 return isl_space_is_equal(get(), other.get());
370 }
371
372 friend std::ostream &operator<<(std::ostream &os, const PBSpace &space) {
373 return os << isl_space_to_str(space.space_);
374 }
375};
376
378 Ref<PBCtx> ctx_;
379 isl_pw_aff *func_ = nullptr;
380
381 public:
383 PBSingleFunc(const Ref<PBCtx> &ctx, isl_pw_aff *func)
384 : ctx_(ctx), func_(func) {}
385 PBSingleFunc(const Ref<PBCtx> &ctx, const std::string &str)
386 : ctx_(ctx), func_(isl_pw_aff_read_from_str(ctx->get(), str.c_str())) {
387 if (func_ == nullptr) {
388 ERROR("Unable to construct an PBSingleFunc from " + str);
389 }
390 }
391 explicit PBSingleFunc(const Ref<PBCtx> &ctx, isl_aff *func)
392 : ctx_(ctx), func_(isl_pw_aff_from_aff(func)) {}
393
395 if (func_ != nullptr) {
396 isl_pw_aff_free(func_);
397 }
398 }
399
401 : ctx_(other.ctx_), func_(other.copy()) {}
403 ctx_ = other.ctx_;
404 if (func_ != nullptr) {
405 isl_pw_aff_free(func_);
406 }
407 func_ = other.copy();
408 return *this;
409 }
410
412 : ctx_(std::move(other.ctx_)), func_(other.move()) {}
414 ctx_ = std::move(other.ctx_);
415 if (func_ != nullptr) {
416 isl_pw_aff_free(func_);
417 }
418 func_ = other.move();
419 return *this;
420 }
421
422 bool isValid() const { return func_ != nullptr; }
423
424 const auto &ctx() const { return ctx_; }
425 auto &ctx() { return ctx_; }
426
427 isl_pw_aff *get() const { return GET_ISL_PTR(func_); }
428 isl_pw_aff *copy() const { return COPY_ISL_PTR(func_, pw_aff); }
429 isl_pw_aff *move() { return MOVE_ISL_PTR(func_); }
430
432 std::string data_;
433
434 public:
436 Serialized(const std::string &data) : data_(data) {}
437 PBSingleFunc to(const Ref<PBCtx> &ctx) const { return {ctx, data_}; }
438 bool isValid() const { return !data_.empty(); }
439 const auto &data() const { return data_; }
440 friend std::ostream &operator<<(std::ostream &os, const Serialized &s) {
441 return os << s.data_;
442 }
443 };
444 Serialized toSerialized() const { return {isl_pw_aff_to_str(get())}; }
446 return toSerialized().to(ctx);
447 }
448
449 isl_size nInDims() const { return isl_pw_aff_dim(get(), isl_dim_in); }
450
451 std::vector<std::pair<PBSet, PBSingleFunc>> pieces() const {
452 typedef std::vector<std::pair<PBSet, PBSingleFunc>> Result;
453 std::pair<Result, Ref<PBCtx>> userData;
454 isl_pw_aff_foreach_piece(
455 get(),
456 [](isl_set *set, isl_aff *piece, void *userDataRaw) {
457 auto &[result, ctx] =
458 *(std::pair<Result, Ref<PBCtx>> *)userDataRaw;
459 result.emplace_back(
460 PBSet(ctx, set),
461 PBSingleFunc(ctx, isl_pw_aff_from_aff(piece)));
462 return isl_stat_ok;
463 },
464 &userData);
465 return userData.first;
466 }
467
468 friend std::ostream &operator<<(std::ostream &os,
469 const PBSingleFunc &func) {
470 return os << isl_pw_aff_to_str(func.func_);
471 }
472};
473
474class PBFunc {
475 Ref<PBCtx> ctx_;
476 isl_pw_multi_aff *func_ = nullptr;
477
478 public:
480 PBFunc(const Ref<PBCtx> &ctx, isl_pw_multi_aff *func)
481 : ctx_(ctx), func_(func) {}
482 PBFunc(const Ref<PBCtx> &ctx, const std::string &str)
483 : ctx_(ctx),
484 func_(isl_pw_multi_aff_read_from_str(ctx->get(), str.c_str())) {
485 if (func_ == nullptr) {
486 ERROR("Unable to construct an PBFunc from " + str);
487 }
488 }
489
490 PBFunc(const PBSingleFunc &singleFunc)
491 : ctx_(singleFunc.ctx()),
492 func_(isl_pw_multi_aff_from_pw_aff(singleFunc.copy())) {}
493 PBFunc(PBSingleFunc &&singleFunc)
494 : ctx_(std::move(singleFunc.ctx())),
495 func_(isl_pw_multi_aff_from_pw_aff(singleFunc.move())) {}
496
497 PBFunc(const PBMap &map)
498 : ctx_(map.ctx()), func_(isl_pw_multi_aff_from_map(map.copy())) {}
500 : ctx_(std::move(map.ctx())),
501 func_(isl_pw_multi_aff_from_map(map.move())) {}
502
503 PBFunc(const PBSet &set)
504 : ctx_(set.ctx()), func_(isl_pw_multi_aff_from_set(set.copy())) {}
506 : ctx_(std::move(set.ctx())),
507 func_(isl_pw_multi_aff_from_set(set.move())) {}
508
510 if (func_ != nullptr) {
511 isl_pw_multi_aff_free(func_);
512 }
513 }
514
515 PBFunc(const PBFunc &other) : ctx_(other.ctx_), func_(other.copy()) {}
516 PBFunc &operator=(const PBFunc &other) {
517 ctx_ = other.ctx_;
518 if (func_ != nullptr) {
519 isl_pw_multi_aff_free(func_);
520 }
521 func_ = other.copy();
522 return *this;
523 }
524
525 PBFunc(PBFunc &&other) : ctx_(std::move(other.ctx_)), func_(other.move()) {}
527 ctx_ = std::move(other.ctx_);
528 if (func_ != nullptr) {
529 isl_pw_multi_aff_free(func_);
530 }
531 func_ = other.move();
532 return *this;
533 }
534
535 bool isValid() const { return func_ != nullptr; }
536
537 const auto &ctx() const { return ctx_; }
538 auto &ctx() { return ctx_; }
539
540 isl_pw_multi_aff *get() const { return GET_ISL_PTR(func_); }
541 isl_pw_multi_aff *copy() const { return COPY_ISL_PTR(func_, pw_multi_aff); }
542 isl_pw_multi_aff *move() { return MOVE_ISL_PTR(func_); }
543
545 std::string data_;
546
547 public:
549 Serialized(const std::string &data) : data_(data) {}
550 PBFunc to(const Ref<PBCtx> &ctx) const { return {ctx, data_}; }
551 bool isValid() const { return !data_.empty(); }
552 const auto &data() const { return data_; }
553 friend std::ostream &operator<<(std::ostream &os, const Serialized &s) {
554 return os << s.data_;
555 }
556 };
557 Serialized toSerialized() const { return {isl_pw_multi_aff_to_str(get())}; }
558 PBFunc to(const Ref<PBCtx> &ctx) const { return toSerialized().to(ctx); }
559
560 isl_size nInDims() const { return isl_pw_multi_aff_dim(get(), isl_dim_in); }
561 isl_size nOutDims() const {
562 return isl_pw_multi_aff_dim(get(), isl_dim_out);
563 }
564
565 PBSingleFunc operator[](isl_size i) const {
566 return {ctx_, isl_pw_multi_aff_get_pw_aff(get(), 0)};
567 }
568
569 std::vector<std::pair<PBSet, PBFunc>> pieces() const {
570 typedef std::vector<std::pair<PBSet, PBFunc>> Result;
571 std::pair<Result, Ref<PBCtx>> userData;
572 isl_pw_multi_aff_foreach_piece(
573 get(),
574 [](isl_set *set, isl_multi_aff *piece, void *userDataRaw) {
575 auto &[result, ctx] =
576 *(std::pair<Result, Ref<PBCtx>> *)userDataRaw;
577 result.emplace_back(
578 PBSet(ctx, set),
579 PBFunc(ctx, isl_pw_multi_aff_from_multi_aff(piece)));
580 return isl_stat_ok;
581 },
582 &userData);
583 return userData.first;
584 }
585
586 friend std::ostream &operator<<(std::ostream &os, const PBFunc &func) {
587 return os << isl_pw_multi_aff_to_str(func.func_);
588 }
589};
590
591class PBPoint {
592 Ref<PBCtx> ctx_;
593 isl_point *point_ = nullptr;
594
595 public:
597 PBPoint(const Ref<PBCtx> &ctx, isl_point *point)
598 : ctx_(ctx), point_(point) {}
599
601 if (point_ != nullptr) {
602 isl_point_free(point_);
603 }
604 }
605
606 PBPoint(const PBPoint &other) : ctx_(other.ctx_), point_(other.copy()) {}
607 PBPoint &operator=(const PBPoint &other) {
608 ctx_ = other.ctx_;
609 if (point_ != nullptr) {
610 isl_point_free(point_);
611 }
612 point_ = other.copy();
613 return *this;
614 }
615
617 : ctx_(std::move(other.ctx_)), point_(other.move()) {}
619 ctx_ = std::move(other.ctx_);
620 if (point_ != nullptr) {
621 isl_point_free(point_);
622 }
623 point_ = other.move();
624 return *this;
625 }
626
627 bool isValid() const { return point_ != nullptr; }
628
629 isl_point *get() const { return GET_ISL_PTR(point_); }
630 isl_point *copy() const { return COPY_ISL_PTR(point_, point); }
631 isl_point *move() { return MOVE_ISL_PTR(point_); }
632
633 bool isVoid() const { return isl_point_is_void(point_); }
634
635 const auto &ctx() const { return ctx_; }
636 auto &ctx() { return ctx_; }
637
638 std::vector<PBVal> coordinates() const {
639 ASSERT(!isVoid());
640 std::vector<PBVal> result;
641 isl_size nCoord = isl_space_dim(
642 PBSpace(ctx_, isl_point_get_space(point_)).get(), isl_dim_set);
643 for (isl_size i = 0; i < nCoord; ++i)
644 result.emplace_back(
645 ctx_, isl_point_get_coordinate_val(point_, isl_dim_set, i));
646 return result;
647 }
648};
649
650template <typename T>
651concept PBMapRef = std::same_as<PBMap, std::decay_t<T>>;
652template <typename T>
653concept PBValRef = std::same_as<PBVal, std::decay_t<T>>;
654template <typename T>
655concept PBSetRef = std::same_as<PBSet, std::decay_t<T>>;
656template <typename T>
657concept PBSpaceRef = std::same_as<PBSpace, std::decay_t<T>>;
658template <typename T>
659concept PBFuncRef = std::same_as<PBFunc, std::decay_t<T>>;
660template <typename T>
661concept PBSingleFuncRef = std::same_as<PBSingleFunc, std::decay_t<T>>;
662
663template <typename T> auto PBRefTake(std::remove_reference_t<T> &t) {
664 return t.copy();
665}
666template <typename T> auto PBRefTake(std::remove_reference_t<T> &&t) {
667 static_assert(!std::is_lvalue_reference_v<T>); // similar to std::forward
668 return t.move();
669}
670
671Ref<PBCtx> commonCtx(const auto &lhs, const auto &rhs) {
672 if (lhs.ctx()->get() != rhs.ctx()->get()) {
673 ERROR(
674 "Operands of a Presburger operation should be on the same context");
675 }
676 return lhs.ctx();
677}
678
679template <PBSetRef T> PBSet projectOutAllParams(T &&set) {
680 return {set.ctx(), isl_set_project_out_all_params(PBRefTake<T>(set))};
681}
682template <PBMapRef T> PBMap projectOutAllParams(T &&map) {
683 return {map.ctx(), isl_map_project_out_all_params(PBRefTake<T>(map))};
684}
685
686template <PBSetRef T>
687PBSet projectOutParamById(T &&set, const std::string &name) {
688 return {set.ctx(),
689 isl_set_project_out_param_id(
690 PBRefTake<T>(set),
691 isl_id_alloc(set.ctx()->get(), name.c_str(), nullptr))};
692}
693template <PBSetRef T>
694PBSet projectOutParamDims(T &&set, unsigned first, unsigned n) {
695 return {set.ctx(),
696 isl_set_project_out(PBRefTake<T>(set), isl_dim_param, first, n)};
697}
698template <PBSetRef T>
699PBSet projectOutDims(T &&set, unsigned first, unsigned n) {
700 return {set.ctx(),
701 isl_set_project_out(PBRefTake<T>(set), isl_dim_set, first, n)};
702}
703
704template <PBMapRef T>
705PBMap projectOutParamById(T &&map, const std::string &name) {
706 return {map.ctx(),
707 isl_map_project_out_param_id(
708 PBRefTake<T>(map),
709 isl_id_alloc(map.ctx()->get(), name.c_str(), nullptr))};
710}
711template <PBMapRef T>
712PBMap projectOutParamDims(T &&map, unsigned first, unsigned n) {
713 return {map.ctx(),
714 isl_map_project_out(PBRefTake<T>(map), isl_dim_param, first, n)};
715}
716template <PBMapRef T>
717PBMap projectOutInputDims(T &&map, unsigned first, unsigned n) {
718 return {map.ctx(),
719 isl_map_project_out(PBRefTake<T>(map), isl_dim_in, first, n)};
720}
721template <PBMapRef T>
722PBMap projectOutOutputDims(T &&map, unsigned first, unsigned n) {
723 return {map.ctx(),
724 isl_map_project_out(PBRefTake<T>(map), isl_dim_out, first, n)};
725}
726
727template <PBSetRef T> PBSet insertDims(T &&set, unsigned first, unsigned n) {
728 return {set.ctx(),
729 isl_set_insert_dims(PBRefTake<T>(set), isl_dim_set, first, n)};
730}
731template <PBMapRef T>
732PBMap insertInputDims(T &&map, unsigned first, unsigned n) {
733 return {map.ctx(),
734 isl_map_insert_dims(PBRefTake<T>(map), isl_dim_in, first, n)};
735}
736template <PBMapRef T>
737PBMap insertOutputDims(T &&map, unsigned first, unsigned n) {
738 return {map.ctx(),
739 isl_map_insert_dims(PBRefTake<T>(map), isl_dim_out, first, n)};
740}
741
742template <PBSetRef T> PBSet fixDim(T &&set, unsigned pos, int x) {
743 return {set.ctx(), isl_set_fix_si(PBRefTake<T>(set), isl_dim_set, pos, x)};
744}
745template <PBMapRef T> PBMap fixInputDim(T &&map, unsigned pos, int x) {
746 return {map.set(), isl_map_fix_si(PBRefTake<T>(map), isl_dim_in, pos, x)};
747}
748template <PBMapRef T> PBMap fixOutputDim(T &&map, unsigned pos, int x) {
749 return {map.ctx(), isl_map_fix_si(PBRefTake<T>(map), isl_dim_out, pos, x)};
750}
751
752template <PBSetRef T> PBSet lowerBoundDim(T &&set, unsigned pos, int x) {
753 return {set.ctx(),
754 isl_set_lower_bound_si(PBRefTake<T>(set), isl_dim_set, pos, x)};
755}
756template <PBMapRef T> PBMap lowerBoundInputDim(T &&map, unsigned pos, int x) {
757 return {map.ctx(),
758 isl_map_lower_bound_si(PBRefTake<T>(map), isl_dim_in, pos, x)};
759}
760template <PBMapRef T> PBMap lowerBoundOutputDim(T &&map, unsigned pos, int x) {
761 return {map.ctx(),
762 isl_map_lower_bound_si(PBRefTake<T>(map), isl_dim_out, pos, x)};
763}
764
765template <PBSetRef T> PBSet upperBoundDim(T &&set, unsigned pos, int x) {
766 return {set.ctx(),
767 isl_set_upper_bound_si(PBRefTake<T>(set), isl_dim_set, pos, x)};
768}
769template <PBMapRef T> PBMap upperBoundInputDim(T &&map, unsigned pos, int x) {
770 return {map.ctx(),
771 isl_map_upper_bound_si(PBRefTake<T>(map), isl_dim_in, pos, x)};
772}
773template <PBMapRef T> PBMap upperBoundOutputDim(T &&map, unsigned pos, int x) {
774 return {map.ctx(),
775 isl_map_upper_bound_si(PBRefTake<T>(map), isl_dim_out, pos, x)};
776}
777
778template <PBSetRef T> PBMap newDomainOnlyMap(T &&set) {
779 return {set.ctx(), isl_map_from_domain(PBRefTake(set))};
780}
781template <PBSetRef T> PBMap newRangeOnlyMap(T &&set) {
782 return {set.ctx(), isl_map_from_range(PBRefTake(set))};
783}
784
785template <PBMapRef T>
786PBMap moveDimsInputToOutput(T &&map, unsigned first, unsigned n,
787 unsigned target) {
788 return {map.ctx(), isl_map_move_dims(PBRefTake<T>(map), isl_dim_out, target,
789 isl_dim_in, first, n)};
790}
791template <PBMapRef T>
792PBMap moveDimsOutputToInput(T &&map, unsigned first, unsigned n,
793 unsigned target) {
794 return {map.ctx(), isl_map_move_dims(PBRefTake<T>(map), isl_dim_in, target,
795 isl_dim_out, first, n)};
796}
806template <PBMapRef T>
807PBMap moveDimsInputToParam(T &&map, unsigned first, unsigned n,
808 unsigned target) {
809 return {map.ctx(), isl_map_move_dims(PBRefTake<T>(map), isl_dim_param,
810 target, isl_dim_in, first, n)};
811}
812template <PBMapRef T>
813PBMap moveDimsOutputToParam(T &&map, unsigned first, unsigned n,
814 unsigned target) {
815 return {map.ctx(), isl_map_move_dims(PBRefTake<T>(map), isl_dim_param,
816 target, isl_dim_out, first, n)};
817}
819template <PBMapRef T>
820PBMap moveDimsParamToInput(T &&map, unsigned first, unsigned n,
821 unsigned target) {
822 return {map.ctx(), isl_map_move_dims(PBRefTake<T>(map), isl_dim_in, target,
823 isl_dim_param, first, n)};
824}
825template <PBMapRef T>
826PBMap moveDimsParamToOutput(T &&map, unsigned first, unsigned n,
827 unsigned target) {
828 return {map.ctx(), isl_map_move_dims(PBRefTake<T>(map), isl_dim_out, target,
829 isl_dim_param, first, n)};
830}
831
832template <PBSetRef T>
833PBSet moveDimsSetToParam(T &&set, unsigned first, unsigned n, unsigned target) {
834 return {set.ctx(), isl_set_move_dims(PBRefTake<T>(set), isl_dim_param,
835 target, isl_dim_set, first, n)};
836}
837template <PBSetRef T>
838PBSet moveDimsParamToSet(T &&set, unsigned first, unsigned n, unsigned target) {
839 return {set.ctx(), isl_set_move_dims(PBRefTake<T>(set), isl_dim_set, target,
840 isl_dim_param, first, n)};
841}
842
843template <PBSetRef T, PBSetRef U>
844std::pair<PBSet, PBSet> padToSameDims(T &&lhs, U &&rhs) {
845 auto n = std::max(lhs.nDims(), rhs.nDims());
846 return std::make_pair(
847 insertDims(std::forward<T>(lhs), lhs.nDims(), n - lhs.nDims()),
848 insertDims(std::forward<T>(rhs), rhs.nDims(), n - rhs.nDims()));
849}
850
851template <PBSetRef T> PBSet complement(T &&set) {
852 DEBUG_PROFILE("complement");
853 return {set.ctx(), isl_set_complement(PBRefTake<T>(set))};
854}
855template <PBMapRef T> PBMap complement(T &&map) {
856 DEBUG_PROFILE("complement");
857 return {map.ctx(), isl_map_complement(PBRefTake<T>(map))};
858}
859
860template <PBMapRef T> PBMap reverse(T &&map) {
861 DEBUG_PROFILE("reverse");
862 return {map.ctx(), isl_map_reverse(PBRefTake<T>(map))};
863}
864
865template <PBMapRef T, PBMapRef U> PBMap subtract(T &&lhs, U &&rhs) {
866 DEBUG_PROFILE_VERBOSE("subtract", "nBasic=" + std::to_string(lhs.nBasic()) +
867 "," + std::to_string(rhs.nBasic()));
868 return {commonCtx(lhs, rhs),
869 isl_map_subtract(PBRefTake<T>(lhs), PBRefTake<U>(rhs))};
870}
871template <PBSetRef T, PBSetRef U> PBSet subtract(T &&lhs, U &&rhs) {
872 DEBUG_PROFILE_VERBOSE("subtract", "nBasic=" + std::to_string(lhs.nBasic()) +
873 "," + std::to_string(rhs.nBasic()));
874 return {commonCtx(lhs, rhs),
875 isl_set_subtract(PBRefTake<T>(lhs), PBRefTake<U>(rhs))};
876}
877
878template <PBMapRef T, PBMapRef U> PBMap intersect(T &&lhs, U &&rhs) {
879 DEBUG_PROFILE_VERBOSE("intersect",
880 "nBasic=" + std::to_string(lhs.nBasic()) + "," +
881 std::to_string(rhs.nBasic()));
882 return {commonCtx(lhs, rhs),
883 isl_map_intersect(PBRefTake<T>(lhs), PBRefTake<U>(rhs))};
884}
885template <PBSetRef T, PBSetRef U> PBSet intersect(T &&lhs, U &&rhs) {
886 DEBUG_PROFILE_VERBOSE("intersect",
887 "nBasic=" + std::to_string(lhs.nBasic()) + "," +
888 std::to_string(rhs.nBasic()));
889 return {commonCtx(lhs, rhs),
890 isl_set_intersect(PBRefTake<T>(lhs), PBRefTake<U>(rhs))};
891}
892
893template <PBMapRef T, PBSetRef U> PBMap intersectDomain(T &&lhs, U &&rhs) {
894 DEBUG_PROFILE_VERBOSE("intersectDomain",
895 "nBasic=" + std::to_string(lhs.nBasic()) + "," +
896 std::to_string(rhs.nBasic()));
897 return {commonCtx(lhs, rhs),
898 isl_map_intersect_domain(PBRefTake<T>(lhs), PBRefTake<U>(rhs))};
899}
900template <PBMapRef T, PBSetRef U> PBMap intersectRange(T &&lhs, U &&rhs) {
901 DEBUG_PROFILE_VERBOSE("intersectRange",
902 "nBasic=" + std::to_string(lhs.nBasic()) + "," +
903 std::to_string(rhs.nBasic()));
904 return {commonCtx(lhs, rhs),
905 isl_map_intersect_range(PBRefTake<T>(lhs), PBRefTake<U>(rhs))};
906}
907
908template <PBSingleFuncRef T, PBSetRef U>
910 return {commonCtx(lhs, rhs),
911 isl_pw_aff_intersect_domain(PBRefTake<T>(lhs), PBRefTake<U>(rhs))};
912}
913template <PBFuncRef T, PBSetRef U> PBFunc intersectDomain(T &&lhs, U &&rhs) {
914 return {commonCtx(lhs, rhs), isl_multi_pw_aff_intersect_domain(
915 PBRefTake<T>(lhs), PBRefTake<U>(rhs))};
916}
917
918template <PBSetRef T, PBSetRef U> PBSet intersectParams(T &&lhs, U &&rhs) {
919 return {commonCtx(lhs, rhs),
920 isl_set_intersect_params(PBRefTake<T>(lhs), PBRefTake<U>(rhs))};
921}
922template <PBMapRef T, PBSetRef U> PBMap intersectParams(T &&lhs, U &&rhs) {
923 return {commonCtx(lhs, rhs),
924 isl_map_intersect_params(PBRefTake<T>(lhs), PBRefTake<U>(rhs))};
925}
926
927template <PBMapRef T, PBMapRef U> PBMap uni(T &&lhs, U &&rhs) {
928 DEBUG_PROFILE_VERBOSE("uni", "nBasic=" + std::to_string(lhs.nBasic()) +
929 "," + std::to_string(rhs.nBasic()));
930 return {commonCtx(lhs, rhs),
931 isl_map_union(PBRefTake<T>(lhs), PBRefTake<U>(rhs))};
932}
933
934template <PBSetRef T, PBSetRef U> PBSet uni(T &&lhs, U &&rhs) {
935 DEBUG_PROFILE_VERBOSE("uni", "nBasic=" + std::to_string(lhs.nBasic()) +
936 "," + std::to_string(rhs.nBasic()));
937 return {commonCtx(lhs, rhs),
938 isl_set_union(PBRefTake<T>(lhs), PBRefTake<U>(rhs))};
939}
940
941template <PBSetRef T, PBMapRef U> PBSet apply(T &&lhs, U &&rhs) {
942 DEBUG_PROFILE("apply");
943 return {commonCtx(lhs, rhs),
944 isl_set_apply(PBRefTake<T>(lhs), PBRefTake<U>(rhs))};
945}
946
947template <PBMapRef T, PBMapRef U> PBMap applyDomain(T &&lhs, U &&rhs) {
948 DEBUG_PROFILE("applyDomain");
949 return {commonCtx(lhs, rhs),
950 isl_map_apply_domain(PBRefTake<T>(lhs), PBRefTake<U>(rhs))};
951}
952
953template <PBMapRef T, PBMapRef U> PBMap applyRange(T &&lhs, U &&rhs) {
954 DEBUG_PROFILE("applyRange");
955 return {commonCtx(lhs, rhs),
956 isl_map_apply_range(PBRefTake<T>(lhs), PBRefTake<U>(rhs))};
957}
958
959template <PBMapRef T, PBMapRef U> PBMap sum(T &&lhs, U &&rhs) {
960 DEBUG_PROFILE("sum");
961 return {commonCtx(lhs, rhs),
962 isl_map_sum(PBRefTake<T>(lhs), PBRefTake<U>(rhs))};
963}
964template <PBSetRef T, PBSetRef U> PBSet sum(T &&lhs, U &&rhs) {
965 DEBUG_PROFILE("sum");
966 return {commonCtx(lhs, rhs),
967 isl_set_sum(PBRefTake<T>(lhs), PBRefTake<U>(rhs))};
968}
969
970template <PBMapRef T> PBMap neg(T &&map) {
971 DEBUG_PROFILE("neg");
972 return {map.ctx(), isl_map_neg(PBRefTake<T>(map))};
973}
974template <PBSetRef T> PBSet neg(T &&set) {
975 DEBUG_PROFILE("neg");
976 return {set.ctx(), isl_set_neg(PBRefTake<T>(set))};
977}
978
979template <PBMapRef T> PBMap lexmax(T &&map) {
980 DEBUG_PROFILE_VERBOSE("lexmax", "nBasic=" + std::to_string(map.nBasic()));
981 return {map.ctx(), isl_map_lexmax(PBRefTake<T>(map))};
982}
983
984template <PBMapRef T> PBMap lexmin(T &&map) {
985 DEBUG_PROFILE_VERBOSE("lexmin", "nBasic=" + std::to_string(map.nBasic()));
986 return {map.ctx(), isl_map_lexmin(PBRefTake<T>(map))};
987}
988
989template <PBSetRef T> PBSet lexmax(T &&set) {
990 DEBUG_PROFILE_VERBOSE("lexmax", "nBasic=" + std::to_string(set.nBasic()));
991 return {set.ctx(), isl_set_lexmax(PBRefTake<T>(set))};
992}
993
994template <PBSetRef T> PBSet lexmin(T &&set) {
995 DEBUG_PROFILE_VERBOSE("lexmin", "nBasic=" + std::to_string(set.nBasic()));
996 return {set.ctx(), isl_set_lexmin(PBRefTake<T>(set))};
997}
998
999template <PBSpaceRef T> PBMap identity(T &&space) {
1000 DEBUG_PROFILE("identity");
1001 return {space.ctx(), isl_map_identity(PBRefTake<T>(space))};
1002}
1003
1004template <PBSpaceRef T> PBMap lexGE(T &&space) {
1005 DEBUG_PROFILE("lexGE");
1006 return {space.ctx(), isl_map_lex_ge(PBRefTake<T>(space))};
1007}
1008
1009template <PBSpaceRef T> PBMap lexGT(T &&space) {
1010 DEBUG_PROFILE("lexGT");
1011 return {space.ctx(), isl_map_lex_gt(PBRefTake<T>(space))};
1012}
1013
1014template <PBSpaceRef T> PBMap lexLE(T &&space) {
1015 DEBUG_PROFILE("lexLE");
1016 return {space.ctx(), isl_map_lex_le(PBRefTake<T>(space))};
1017}
1018
1019template <PBSpaceRef T> PBMap lexLT(T &&space) {
1020 DEBUG_PROFILE("lexLT");
1021 return {space.ctx(), isl_map_lex_lt(PBRefTake<T>(space))};
1022}
1023
1024inline PBSpace spaceAlloc(const Ref<PBCtx> &ctx, unsigned nparam, unsigned nIn,
1025 unsigned nOut) {
1026 return {ctx, isl_space_alloc(ctx->get(), nparam, nIn, nOut)};
1027}
1028
1029inline PBSpace spaceSetAlloc(const Ref<PBCtx> &ctx, unsigned nparam,
1030 unsigned dim) {
1031 return {ctx, isl_space_set_alloc(ctx->get(), nparam, dim)};
1032}
1033
1034template <PBSpaceRef T> PBSet emptySet(T &&space) {
1035 return {space.ctx(), isl_set_empty(PBRefTake<T>(space))};
1036}
1037
1038template <PBSpaceRef T> PBMap emptyMap(T &&space) {
1039 return {space.ctx(), isl_map_empty(PBRefTake<T>(space))};
1040}
1041
1042template <PBSpaceRef T> PBSet universeSet(T &&space) {
1043 return {space.ctx(), isl_set_universe(PBRefTake<T>(space))};
1044}
1045
1046template <PBSpaceRef T> PBMap universeMap(T &&space) {
1047 return {space.ctx(), isl_map_universe(PBRefTake<T>(space))};
1048}
1049
1050template <PBMapRef T> PBSet domain(T &&map) {
1051 return {map.ctx(), isl_map_domain(PBRefTake<T>(map))};
1052}
1053
1054template <PBMapRef T> PBSet range(T &&map) {
1055 return {map.ctx(), isl_map_range(PBRefTake<T>(map))};
1056}
1057
1058template <PBSingleFuncRef T> PBSet domain(T &&func) {
1059 return {func.ctx(), isl_pw_aff_domain(PBRefTake<T>(func))};
1060}
1061template <PBFuncRef T> PBSet domain(T &&func) {
1062 return {func.ctx(), isl_multi_pw_aff_domain(PBRefTake<T>(func))};
1063}
1064
1065template <PBSetRef T> PBSet params(T &&set) {
1066 return {set.ctx(), isl_set_params(PBRefTake<T>(set))};
1067}
1068template <PBMapRef T> PBSet params(T &&map) {
1069 return {map.ctx(), isl_map_params(PBRefTake<T>(map))};
1070}
1071
1072template <PBSetRef T> PBSet coalesce(T &&set) {
1073 DEBUG_PROFILE("coalesce");
1074 return {set.ctx(), isl_set_coalesce(PBRefTake<T>(set))};
1075}
1076
1077template <PBMapRef T> PBMap coalesce(T &&map) {
1078 DEBUG_PROFILE("coalesce");
1079 return {map.ctx(), isl_map_coalesce(PBRefTake<T>(map))};
1080}
1081
1082template <PBSetRef T, PBSetRef U> PBSet cartesianProduct(T &&lhs, U &&rhs) {
1083 return {commonCtx(lhs, rhs),
1084 isl_set_flat_product(PBRefTake<T>(lhs), PBRefTake<U>(rhs))};
1085}
1086
1087template <PBSetRef T> PBVal dimMaxVal(T &&set, int pos) {
1088 return {set.ctx(), isl_set_dim_max_val(PBRefTake<T>(set), pos)};
1089}
1090
1091template <PBSetRef T> PBVal dimMinVal(T &&set, int pos) {
1092 return {set.ctx(), isl_set_dim_min_val(PBRefTake<T>(set), pos)};
1093}
1094
1095inline PBVal dimFixVal(const PBSet &set, int pos) {
1096 return {set.ctx(),
1097 isl_set_plain_get_val_if_fixed(set.get(), isl_dim_set, pos)};
1098}
1099
1100template <PBSpaceRef T> PBSpace spaceMapFromSet(T &&space) {
1101 return {space.ctx(), isl_space_map_from_set(PBRefTake<T>(space))};
1102}
1103
1104template <PBMapRef T> PBSet wrap(T &&map) {
1105 return {map.ctx(), isl_map_wrap(PBRefTake<T>(map))};
1106}
1107
1108template <PBSetRef T> PBMap unwrap(T &&set) {
1109 return {set.ctx(), isl_set_unwrap(PBRefTake<T>(set))};
1110}
1111
1112template <PBSetRef T> PBSet flatten(T &&set) {
1113 return {set.ctx(), isl_set_flatten(PBRefTake<T>(set))};
1114}
1115template <PBMapRef T> PBMap flattenDomain(T &&map) {
1116 return {map.ctx(), isl_map_flatten_domain(PBRefTake<T>(map))};
1117}
1118template <PBMapRef T> PBMap flattenRange(T &&map) {
1119 return {map.ctx(), isl_map_flatten_range(PBRefTake<T>(map))};
1120}
1121
1122template <PBMapRef T> PBSet flattenMapToSet(T &&map) {
1123 return flatten(wrap(std::forward<T>(map)));
1124}
1125
1126template <PBSetRef T> PBPoint sample(T &&set) {
1127 return {set.ctx(), isl_set_sample_point(PBRefTake<T>(set))};
1128}
1129
1130template <PBSingleFuncRef T, PBSingleFuncRef U>
1132 return {commonCtx(lhs, rhs),
1133 isl_pw_aff_min(PBRefTake<T>(lhs), PBRefTake<U>(rhs))};
1134}
1135
1136template <PBSingleFuncRef T, PBSingleFuncRef U>
1138 return {commonCtx(lhs, rhs),
1139 isl_pw_aff_max(PBRefTake<T>(lhs), PBRefTake<U>(rhs))};
1140}
1141
1155template <PBSetRef T> PBSet coefficients(T &&set, int64_t c = 0) {
1156 // ISL coefficients applies Farkas lemma which disallows intermediate
1157 // variables introduced by division/modulo constraints. The best we can do
1158 // is to remove such constraints and provide a slightly relaxed bound for
1159 // the coefficients, so remove_divs first.
1160 auto coefficientsMap = isl_map_from_basic_map(isl_basic_set_unwrap(
1161 isl_set_coefficients(isl_set_remove_divs(PBRefTake<T>(set)))));
1162 auto ctx = isl_map_get_ctx(coefficientsMap);
1163 auto paramsSpace = isl_space_domain(isl_map_get_space(coefficientsMap));
1164 auto nParams = isl_space_dim(paramsSpace, isl_dim_set);
1165 auto cPoint = isl_point_zero(paramsSpace);
1166 isl_point_set_coordinate_val(cPoint, isl_dim_set, nParams - 1,
1167 isl_val_int_from_si(ctx, -c));
1168 return apply(PBSet(set.ctx(), isl_set_from_point(cPoint)),
1169 PBMap(set.ctx(), coefficientsMap));
1170}
1171
1172inline bool isSubset(const PBSet &small, const PBSet &big) {
1173 return isl_set_is_subset(small.get(), big.get());
1174}
1175inline bool isSubset(const PBMap &small, const PBMap &big) {
1176 return isl_map_is_subset(small.get(), big.get());
1177}
1178
1179inline bool operator==(const PBSet &lhs, const PBSet &rhs) {
1180 DEBUG_PROFILE_VERBOSE("equal", "nBasic=" + std::to_string(lhs.nBasic()) +
1181 "," + std::to_string(rhs.nBasic()));
1182 return isl_set_is_equal(lhs.get(), rhs.get());
1183}
1184
1185inline bool operator==(const PBMap &lhs, const PBMap &rhs) {
1186 DEBUG_PROFILE_VERBOSE("equal", "nBasic=" + std::to_string(lhs.nBasic()) +
1187 "," + std::to_string(rhs.nBasic()));
1188 return isl_map_is_equal(lhs.get(), rhs.get());
1189}
1190
1191inline bool operator==(const PBSingleFunc &lhs, const PBSingleFunc &rhs) {
1192 return isl_pw_aff_is_equal(lhs.get(), rhs.get());
1193}
1194
1195inline bool operator==(const PBFunc &lhs, const PBFunc &rhs) {
1196 return isl_pw_multi_aff_is_equal(lhs.get(), rhs.get());
1197}
1198
1200 std::string expr_;
1201 explicit PBBuildExpr(const std::string &expr) : expr_(expr) {}
1202 friend class PBBuilder;
1203
1204 public:
1205 PBBuildExpr() = default;
1206 PBBuildExpr(const PBBuildExpr &) = default;
1208 PBBuildExpr &operator=(const PBBuildExpr &) = default;
1210
1211 PBBuildExpr(bool b) : expr_(b ? "true" : "false") {}
1212 PBBuildExpr(std::integral auto i) : expr_(toString(i)) {}
1213
1214 friend PBBuildExpr operator+(const PBBuildExpr &a, const PBBuildExpr &b) {
1215 return PBBuildExpr("(" + a.expr_ + " + " + b.expr_ + ")");
1216 }
1218 return *this = *this + other;
1219 }
1220
1221 PBBuildExpr operator-() const { return PBBuildExpr("(-" + expr_ + ")"); }
1222 friend PBBuildExpr operator-(const PBBuildExpr &a, const PBBuildExpr &b) {
1223 return PBBuildExpr("(" + a.expr_ + " - " + b.expr_ + ")");
1224 }
1226 return *this = *this - other;
1227 }
1228
1229 friend PBBuildExpr operator*(const PBBuildExpr &a, const PBBuildExpr &b) {
1230 return PBBuildExpr("(" + a.expr_ + " * " + b.expr_ + ")");
1231 }
1233 return *this = *this * other;
1234 }
1235
1236 friend PBBuildExpr operator/(const PBBuildExpr &a, const PBBuildExpr &b) {
1237 return PBBuildExpr("(" + a.expr_ + " / " + b.expr_ + ")");
1238 }
1240 return *this = *this / other;
1241 }
1242
1243 friend PBBuildExpr ceilDiv(const PBBuildExpr &a, const PBBuildExpr &b) {
1244 return PBBuildExpr("ceil(" + a.expr_ + " / " + b.expr_ + ")");
1245 }
1246 friend PBBuildExpr floorDiv(const PBBuildExpr &a, const PBBuildExpr &b) {
1247 return PBBuildExpr("floor(" + a.expr_ + " / " + b.expr_ + ")");
1248 }
1249
1250 friend PBBuildExpr operator%(const PBBuildExpr &a, const PBBuildExpr &b) {
1251 return PBBuildExpr("(" + a.expr_ + " % " + b.expr_ + ")");
1252 }
1254 return *this = *this % other;
1255 }
1256
1257 friend PBBuildExpr operator<(const PBBuildExpr &a, const PBBuildExpr &b) {
1258 return PBBuildExpr("(" + a.expr_ + " < " + b.expr_ + ")");
1259 }
1260
1261 friend PBBuildExpr operator<=(const PBBuildExpr &a, const PBBuildExpr &b) {
1262 return PBBuildExpr("(" + a.expr_ + " <= " + b.expr_ + ")");
1263 }
1264
1265 friend PBBuildExpr operator>(const PBBuildExpr &a, const PBBuildExpr &b) {
1266 return PBBuildExpr("(" + a.expr_ + " > " + b.expr_ + ")");
1267 }
1268
1269 friend PBBuildExpr operator>=(const PBBuildExpr &a, const PBBuildExpr &b) {
1270 return PBBuildExpr("(" + a.expr_ + " >= " + b.expr_ + ")");
1271 }
1272
1273 friend PBBuildExpr operator==(const PBBuildExpr &a, const PBBuildExpr &b) {
1274 return PBBuildExpr("(" + a.expr_ + " = " + b.expr_ + ")");
1275 }
1276
1277 friend PBBuildExpr operator!=(const PBBuildExpr &a, const PBBuildExpr &b) {
1278 return PBBuildExpr("(" + a.expr_ + " != " + b.expr_ + ")");
1279 }
1280
1281 friend PBBuildExpr operator&&(const PBBuildExpr &a, const PBBuildExpr &b) {
1282 return PBBuildExpr("(" + a.expr_ + " and " + b.expr_ + ")");
1283 }
1284
1285 friend PBBuildExpr operator||(const PBBuildExpr &a, const PBBuildExpr &b) {
1286 return PBBuildExpr("(" + a.expr_ + " or " + b.expr_ + ")");
1287 }
1288
1289 friend PBBuildExpr max(const PBBuildExpr &a, const PBBuildExpr &b) {
1290 return PBBuildExpr("max(" + a.expr_ + ", " + b.expr_ + ")");
1291 }
1292
1293 friend PBBuildExpr min(const PBBuildExpr &a, const PBBuildExpr &b) {
1294 return PBBuildExpr("min(" + a.expr_ + ", " + b.expr_ + ")");
1295 }
1296
1297 friend std::ostream &operator<<(std::ostream &os, const PBBuildExpr &e);
1298};
1299
1301 int anonVarNum_ = 0;
1302 std::unordered_set<std::string> namedVars;
1303
1304 std::vector<PBBuildExpr> constraints_;
1305
1306 protected:
1307 PBBuildExpr newVar(const std::string &name = "");
1308 std::vector<PBBuildExpr> newVars(int n, const std::string &prefix = "");
1309
1310 std::string getConstraintsStr() const;
1311
1312 public:
1313 PBBuilder() = default;
1314 PBBuilder(const PBBuilder &) = default;
1315 PBBuilder(PBBuilder &&) = default;
1316 PBBuilder &operator=(const PBBuilder &) = default;
1318
1319 void addConstraint(const PBBuildExpr &constraint);
1320 void addConstraint(PBBuildExpr &&constraint);
1321 template <typename T = std::initializer_list<PBBuildExpr>>
1323 for (auto &&c : constraints)
1324 addConstraint(c);
1325 }
1326 const std::vector<PBBuildExpr> &constraints() const { return constraints_; }
1327 void clearConstraints() { constraints_.clear(); };
1328};
1329
1330class PBMapBuilder : public PBBuilder {
1331 std::vector<PBBuildExpr> inputs_;
1332 std::vector<PBBuildExpr> outputs_;
1333
1334 public:
1335 PBMapBuilder() = default;
1336 PBMapBuilder(const PBMapBuilder &) = default;
1340
1341 void addInput(const PBBuildExpr &expr);
1342 void addInputs(auto &&exprs) {
1343 for (auto &&e : exprs)
1344 addInput(e);
1345 }
1346 PBBuildExpr newInput(const std::string &name);
1347 std::vector<PBBuildExpr> newInputs(int n, const std::string &prefix = "");
1348 const std::vector<PBBuildExpr> &inputs() const { return inputs_; }
1349 void clearInputs() { inputs_.clear(); }
1350
1351 void addOutput(const PBBuildExpr &expr);
1352 void addOutputs(auto &&exprs) {
1353 for (auto &&e : exprs)
1354 addOutput(e);
1355 }
1356 PBBuildExpr newOutput(const std::string &name);
1357 std::vector<PBBuildExpr> newOutputs(int n, const std::string &prefix = "");
1358 const std::vector<PBBuildExpr> &outputs() const { return outputs_; }
1359 void clearOutputs() { outputs_.clear(); }
1360
1361 PBMap build(const Ref<PBCtx> &ctx) const;
1362};
1363
1364class PBSetBuilder : public PBBuilder {
1365 std::vector<PBBuildExpr> vars_;
1366
1367 public:
1368 PBSetBuilder() = default;
1369 PBSetBuilder(const PBSetBuilder &) = default;
1373
1374 void addVar(const PBBuildExpr &expr);
1375 void addVars(auto &&exprs) {
1376 for (auto &&e : exprs)
1377 addVar(e);
1378 }
1379 PBBuildExpr newVar(const std::string &name);
1380 std::vector<PBBuildExpr> newVars(int n, const std::string &prefix = "");
1381 const std::vector<PBBuildExpr> &vars() const { return vars_; }
1382 void clearVars() { vars_.clear(); }
1383
1384 PBSet build(const Ref<PBCtx> &ctx) const;
1385};
1386
1387auto pbFuncWithTimeout(const auto &func, int seconds, const auto &...args)
1388 -> std::optional<decltype(func(args...))> {
1389 decltype(func(args...)) ret;
1390 if (timeout([&]() { ret = func(args...); }, seconds)) {
1391 return ret;
1392 } else {
1393 return std::nullopt;
1394 }
1395}
1396
1397} // namespace freetensor
1398
1399#endif // FREE_TENSOR_PRESBURGER_H
Definition: presburger.h:1199
friend std::ostream & operator<<(std::ostream &os, const PBBuildExpr &e)
Definition: presburger.cc:6
friend PBBuildExpr ceilDiv(const PBBuildExpr &a, const PBBuildExpr &b)
Definition: presburger.h:1243
friend PBBuildExpr operator-(const PBBuildExpr &a, const PBBuildExpr &b)
Definition: presburger.h:1222
PBBuildExpr(bool b)
Definition: presburger.h:1211
PBBuildExpr operator-() const
Definition: presburger.h:1221
PBBuildExpr(std::integral auto i)
Definition: presburger.h:1212
friend PBBuildExpr operator/(const PBBuildExpr &a, const PBBuildExpr &b)
Definition: presburger.h:1236
friend PBBuildExpr operator>=(const PBBuildExpr &a, const PBBuildExpr &b)
Definition: presburger.h:1269
friend PBBuildExpr max(const PBBuildExpr &a, const PBBuildExpr &b)
Definition: presburger.h:1289
friend PBBuildExpr floorDiv(const PBBuildExpr &a, const PBBuildExpr &b)
Definition: presburger.h:1246
PBBuildExpr & operator-=(const PBBuildExpr &other)
Definition: presburger.h:1225
PBBuildExpr & operator/=(const PBBuildExpr &other)
Definition: presburger.h:1239
friend PBBuildExpr operator<(const PBBuildExpr &a, const PBBuildExpr &b)
Definition: presburger.h:1257
friend PBBuildExpr operator>(const PBBuildExpr &a, const PBBuildExpr &b)
Definition: presburger.h:1265
PBBuildExpr & operator*=(const PBBuildExpr &other)
Definition: presburger.h:1232
PBBuildExpr(PBBuildExpr &&)=default
friend PBBuildExpr operator*(const PBBuildExpr &a, const PBBuildExpr &b)
Definition: presburger.h:1229
friend PBBuildExpr operator&&(const PBBuildExpr &a, const PBBuildExpr &b)
Definition: presburger.h:1281
friend PBBuildExpr operator==(const PBBuildExpr &a, const PBBuildExpr &b)
Definition: presburger.h:1273
PBBuildExpr & operator=(const PBBuildExpr &)=default
friend PBBuildExpr operator%(const PBBuildExpr &a, const PBBuildExpr &b)
Definition: presburger.h:1250
friend PBBuildExpr operator+(const PBBuildExpr &a, const PBBuildExpr &b)
Definition: presburger.h:1214
friend PBBuildExpr operator<=(const PBBuildExpr &a, const PBBuildExpr &b)
Definition: presburger.h:1261
PBBuildExpr(const PBBuildExpr &)=default
friend PBBuildExpr operator!=(const PBBuildExpr &a, const PBBuildExpr &b)
Definition: presburger.h:1277
friend PBBuildExpr min(const PBBuildExpr &a, const PBBuildExpr &b)
Definition: presburger.h:1293
friend PBBuildExpr operator||(const PBBuildExpr &a, const PBBuildExpr &b)
Definition: presburger.h:1285
PBBuildExpr & operator=(PBBuildExpr &&)=default
PBBuildExpr & operator%=(const PBBuildExpr &other)
Definition: presburger.h:1253
PBBuildExpr & operator+=(const PBBuildExpr &other)
Definition: presburger.h:1217
Definition: presburger.h:1300
PBBuilder(PBBuilder &&)=default
PBBuilder & operator=(PBBuilder &&)=default
void clearConstraints()
Definition: presburger.h:1327
void addConstraint(const PBBuildExpr &constraint)
Definition: presburger.cc:33
std::string getConstraintsStr() const
Definition: presburger.cc:29
const std::vector< PBBuildExpr > & constraints() const
Definition: presburger.h:1326
void addConstraints(T &&constraints)
Definition: presburger.h:1322
PBBuildExpr newVar(const std::string &name="")
Definition: presburger.cc:11
std::vector< PBBuildExpr > newVars(int n, const std::string &prefix="")
Definition: presburger.cc:21
PBBuilder(const PBBuilder &)=default
PBBuilder & operator=(const PBBuilder &)=default
Definition: presburger.h:58
isl_ctx * get() const
Definition: presburger.h:72
PBCtx(const PBCtx &other)=delete
PBCtx()
Definition: presburger.h:62
~PBCtx()
Definition: presburger.h:65
PBCtx & operator=(const PBCtx &other)=delete
PBCtx(PBCtx &&other)=delete
PBCtx & operator=(PBCtx &&other)=delete
Definition: presburger.h:544
const auto & data() const
Definition: presburger.h:552
Serialized(const std::string &data)
Definition: presburger.h:549
bool isValid() const
Definition: presburger.h:551
friend std::ostream & operator<<(std::ostream &os, const Serialized &s)
Definition: presburger.h:553
PBFunc to(const Ref< PBCtx > &ctx) const
Definition: presburger.h:550
Serialized()
Definition: presburger.h:548
Definition: presburger.h:474
std::vector< std::pair< PBSet, PBFunc > > pieces() const
Definition: presburger.h:569
isl_pw_multi_aff * move()
Definition: presburger.h:542
~PBFunc()
Definition: presburger.h:509
PBSingleFunc operator[](isl_size i) const
Definition: presburger.h:565
const auto & ctx() const
Definition: presburger.h:537
PBFunc to(const Ref< PBCtx > &ctx) const
Definition: presburger.h:558
PBFunc & operator=(PBFunc &&other)
Definition: presburger.h:526
friend std::ostream & operator<<(std::ostream &os, const PBFunc &func)
Definition: presburger.h:586
PBFunc(const PBMap &map)
Definition: presburger.h:497
isl_size nOutDims() const
Definition: presburger.h:561
Serialized toSerialized() const
Definition: presburger.h:557
PBFunc(PBFunc &&other)
Definition: presburger.h:525
PBFunc & operator=(const PBFunc &other)
Definition: presburger.h:516
isl_size nInDims() const
Definition: presburger.h:560
isl_pw_multi_aff * copy() const
Definition: presburger.h:541
auto & ctx()
Definition: presburger.h:538
PBFunc(PBMap &&map)
Definition: presburger.h:499
PBFunc(const Ref< PBCtx > &ctx, isl_pw_multi_aff *func)
Definition: presburger.h:480
PBFunc(const Ref< PBCtx > &ctx, const std::string &str)
Definition: presburger.h:482
PBFunc(const PBSet &set)
Definition: presburger.h:503
PBFunc(const PBSingleFunc &singleFunc)
Definition: presburger.h:490
PBFunc(PBSet &&set)
Definition: presburger.h:505
bool isValid() const
Definition: presburger.h:535
isl_pw_multi_aff * get() const
Definition: presburger.h:540
PBFunc()
Definition: presburger.h:479
PBFunc(const PBFunc &other)
Definition: presburger.h:515
PBFunc(PBSingleFunc &&singleFunc)
Definition: presburger.h:493
Definition: presburger.h:1330
void addOutputs(auto &&exprs)
Definition: presburger.h:1352
PBBuildExpr newOutput(const std::string &name)
Definition: presburger.cc:60
void addInput(const PBBuildExpr &expr)
Definition: presburger.cc:41
PBBuildExpr newInput(const std::string &name)
Definition: presburger.cc:44
PBMapBuilder(PBMapBuilder &&)=default
std::vector< PBBuildExpr > newInputs(int n, const std::string &prefix="")
Definition: presburger.cc:49
const std::vector< PBBuildExpr > & inputs() const
Definition: presburger.h:1348
PBMapBuilder & operator=(PBMapBuilder &&)=default
void addOutput(const PBBuildExpr &expr)
Definition: presburger.cc:57
std::vector< PBBuildExpr > newOutputs(int n, const std::string &prefix="")
Definition: presburger.cc:65
void clearOutputs()
Definition: presburger.h:1359
PBMapBuilder & operator=(const PBMapBuilder &)=default
PBMap build(const Ref< PBCtx > &ctx) const
Definition: presburger.cc:73
PBMapBuilder(const PBMapBuilder &)=default
void addInputs(auto &&exprs)
Definition: presburger.h:1342
void clearInputs()
Definition: presburger.h:1349
const std::vector< PBBuildExpr > & outputs() const
Definition: presburger.h:1358
Definition: presburger.h:123
const auto & data() const
Definition: presburger.h:131
PBMap to(const Ref< PBCtx > &ctx) const
Definition: presburger.h:129
Serialized()
Definition: presburger.h:127
friend std::ostream & operator<<(std::ostream &os, const Serialized &s)
Definition: presburger.h:132
bool isValid() const
Definition: presburger.h:130
Serialized(const std::string &data)
Definition: presburger.h:128
Definition: presburger.h:75
auto & ctx()
Definition: presburger.h:117
bool isValid() const
Definition: presburger.h:114
PBMap()
Definition: presburger.h:80
isl_map * move()
Definition: presburger.h:121
PBMap(PBMap &&other)
Definition: presburger.h:104
const char * nameParamDim(unsigned i) const
Definition: presburger.h:158
const char * nameOutDim(unsigned i) const
Definition: presburger.h:155
bool isBijective() const
Definition: presburger.h:144
isl_size nParamDims() const
Definition: presburger.h:150
Serialized toSerialized() const
Definition: presburger.h:136
isl_size nBasic() const
Definition: presburger.h:146
isl_size nInDims() const
Definition: presburger.h:148
isl_size nOutDims() const
Definition: presburger.h:149
isl_map * get() const
Definition: presburger.h:119
bool empty() const
Definition: presburger.h:139
bool isSingleValued() const
Definition: presburger.h:143
PBMap to(const Ref< PBCtx > &ctx) const
Definition: presburger.h:137
PBMap(const Ref< PBCtx > &ctx, isl_map *map)
Definition: presburger.h:81
isl_map * copy() const
Definition: presburger.h:120
PBMap & operator=(PBMap &&other)
Definition: presburger.h:105
PBMap & operator=(const PBMap &other)
Definition: presburger.h:95
PBMap(const PBMap &other)
Definition: presburger.h:94
friend std::ostream & operator<<(std::ostream &os, const PBMap &map)
Definition: presburger.h:162
~PBMap()
Definition: presburger.h:88
const char * nameInDim(unsigned i) const
Definition: presburger.h:152
PBMap(const Ref< PBCtx > &ctx, const std::string &str)
Definition: presburger.h:82
const auto & ctx() const
Definition: presburger.h:116
Definition: presburger.h:591
auto & ctx()
Definition: presburger.h:636
const auto & ctx() const
Definition: presburger.h:635
std::vector< PBVal > coordinates() const
Definition: presburger.h:638
bool isValid() const
Definition: presburger.h:627
~PBPoint()
Definition: presburger.h:600
isl_point * copy() const
Definition: presburger.h:630
bool isVoid() const
Definition: presburger.h:633
PBPoint()
Definition: presburger.h:596
PBPoint(const PBPoint &other)
Definition: presburger.h:606
isl_point * get() const
Definition: presburger.h:629
PBPoint & operator=(const PBPoint &other)
Definition: presburger.h:607
PBPoint(const Ref< PBCtx > &ctx, isl_point *point)
Definition: presburger.h:597
PBPoint & operator=(PBPoint &&other)
Definition: presburger.h:618
isl_point * move()
Definition: presburger.h:631
PBPoint(PBPoint &&other)
Definition: presburger.h:616
Definition: presburger.h:1364
void addVars(auto &&exprs)
Definition: presburger.h:1375
void addVar(const PBBuildExpr &expr)
Definition: presburger.cc:78
PBSetBuilder(PBSetBuilder &&)=default
void clearVars()
Definition: presburger.h:1382
std::vector< PBBuildExpr > newVars(int n, const std::string &prefix="")
Definition: presburger.cc:84
PBSetBuilder & operator=(const PBSetBuilder &)=default
PBSetBuilder(const PBSetBuilder &)=default
const std::vector< PBBuildExpr > & vars() const
Definition: presburger.h:1381
PBSetBuilder & operator=(PBSetBuilder &&)=default
PBSet build(const Ref< PBCtx > &ctx) const
Definition: presburger.cc:92
PBBuildExpr newVar(const std::string &name)
Definition: presburger.cc:79
Definition: presburger.h:271
const auto & data() const
Definition: presburger.h:279
Serialized(const std::string &data)
Definition: presburger.h:276
friend std::ostream & operator<<(std::ostream &os, const Serialized &s)
Definition: presburger.h:280
Serialized()
Definition: presburger.h:275
PBSet to(const Ref< PBCtx > &ctx) const
Definition: presburger.h:277
bool isValid() const
Definition: presburger.h:278
Definition: presburger.h:223
auto & ctx()
Definition: presburger.h:265
PBSet & operator=(PBSet &&other)
Definition: presburger.h:253
PBSet()
Definition: presburger.h:228
const char * nameParamDim(unsigned i) const
Definition: presburger.h:302
PBSet(const Ref< PBCtx > &ctx, const std::string &str)
Definition: presburger.h:230
isl_size nParamDims() const
Definition: presburger.h:297
isl_set * move()
Definition: presburger.h:269
bool isSingleValued() const
Definition: presburger.h:292
friend std::ostream & operator<<(std::ostream &os, const PBSet &set)
Definition: presburger.h:313
bool empty() const
Definition: presburger.h:287
bool isValid() const
Definition: presburger.h:262
const char * nameDim(unsigned i) const
Definition: presburger.h:299
bool hasUpperBound(unsigned i) const
Definition: presburger.h:309
PBSet & operator=(const PBSet &other)
Definition: presburger.h:243
isl_set * get() const
Definition: presburger.h:267
isl_size nBasic() const
Definition: presburger.h:294
PBSet(const Ref< PBCtx > &ctx, isl_set *set)
Definition: presburger.h:229
PBSet(const PBSet &other)
Definition: presburger.h:242
PBSet to(const Ref< PBCtx > &ctx) const
Definition: presburger.h:285
const auto & ctx() const
Definition: presburger.h:264
PBSet(PBSet &&other)
Definition: presburger.h:252
bool hasLowerBound(unsigned i) const
Definition: presburger.h:306
isl_set * copy() const
Definition: presburger.h:268
~PBSet()
Definition: presburger.h:236
isl_size nDims() const
Definition: presburger.h:296
Serialized toSerialized() const
Definition: presburger.h:284
Definition: presburger.h:431
const auto & data() const
Definition: presburger.h:439
bool isValid() const
Definition: presburger.h:438
PBSingleFunc to(const Ref< PBCtx > &ctx) const
Definition: presburger.h:437
Serialized()
Definition: presburger.h:435
Serialized(const std::string &data)
Definition: presburger.h:436
friend std::ostream & operator<<(std::ostream &os, const Serialized &s)
Definition: presburger.h:440
Definition: presburger.h:377
PBSingleFunc(const Ref< PBCtx > &ctx, isl_pw_aff *func)
Definition: presburger.h:383
PBSingleFunc & operator=(const PBSingleFunc &other)
Definition: presburger.h:402
const auto & ctx() const
Definition: presburger.h:424
~PBSingleFunc()
Definition: presburger.h:394
isl_pw_aff * get() const
Definition: presburger.h:427
PBSingleFunc(const Ref< PBCtx > &ctx, isl_aff *func)
Definition: presburger.h:391
std::vector< std::pair< PBSet, PBSingleFunc > > pieces() const
Definition: presburger.h:451
auto & ctx()
Definition: presburger.h:425
isl_pw_aff * move()
Definition: presburger.h:429
bool isValid() const
Definition: presburger.h:422
PBSingleFunc(PBSingleFunc &&other)
Definition: presburger.h:411
friend std::ostream & operator<<(std::ostream &os, const PBSingleFunc &func)
Definition: presburger.h:468
isl_size nInDims() const
Definition: presburger.h:449
PBSingleFunc(const PBSingleFunc &other)
Definition: presburger.h:400
PBSingleFunc(const Ref< PBCtx > &ctx, const std::string &str)
Definition: presburger.h:385
Serialized toSerialized() const
Definition: presburger.h:444
isl_pw_aff * copy() const
Definition: presburger.h:428
PBSingleFunc()
Definition: presburger.h:382
PBSingleFunc & operator=(PBSingleFunc &&other)
Definition: presburger.h:413
PBSingleFunc to(const Ref< PBCtx > &ctx) const
Definition: presburger.h:445
Definition: presburger.h:318
const auto & ctx() const
Definition: presburger.h:359
friend std::ostream & operator<<(std::ostream &os, const PBSpace &space)
Definition: presburger.h:372
isl_space * move()
Definition: presburger.h:364
PBSpace(PBSpace &&other)
Definition: presburger.h:346
bool operator==(const PBSpace &other) const
Definition: presburger.h:366
PBSpace & operator=(PBSpace &&other)
Definition: presburger.h:348
PBSpace(const Ref< PBCtx > &ctx, isl_space *space)
Definition: presburger.h:324
PBSpace(const PBMap &map)
Definition: presburger.h:328
PBSpace(const PBSpace &other)
Definition: presburger.h:336
PBSpace(const PBSet &set)
Definition: presburger.h:326
PBSpace()
Definition: presburger.h:323
auto & ctx()
Definition: presburger.h:360
isl_space * get() const
Definition: presburger.h:362
PBSpace & operator=(const PBSpace &other)
Definition: presburger.h:337
isl_space * copy() const
Definition: presburger.h:363
~PBSpace()
Definition: presburger.h:330
bool isValid() const
Definition: presburger.h:357
Definition: presburger.h:167
PBVal(PBVal &&other)
Definition: presburger.h:190
auto & ctx()
Definition: presburger.h:203
PBVal()
Definition: presburger.h:172
bool isValid() const
Definition: presburger.h:200
isl_val * move()
Definition: presburger.h:207
PBVal & operator=(PBVal &&other)
Definition: presburger.h:191
bool isNaN() const
Definition: presburger.h:209
PBVal(const Ref< PBCtx > &ctx, isl_val *val)
Definition: presburger.h:173
bool isNegInf() const
Definition: presburger.h:213
PBVal(const PBVal &other)
Definition: presburger.h:180
friend std::ostream & operator<<(std::ostream &os, const PBVal &val)
Definition: presburger.h:218
int numSi() const
Definition: presburger.h:215
bool isInt() const
Definition: presburger.h:211
bool isInf() const
Definition: presburger.h:212
const auto & ctx() const
Definition: presburger.h:202
bool isRat() const
Definition: presburger.h:210
PBVal & operator=(const PBVal &other)
Definition: presburger.h:181
isl_val * get() const
Definition: presburger.h:205
~PBVal()
Definition: presburger.h:174
isl_val * copy() const
Definition: presburger.h:206
int denSi() const
Definition: presburger.h:216
Definition: ref.h:24
T * get() const
Definition: ref.h:101
Definition: presburger.h:659
Definition: presburger.h:651
Definition: presburger.h:655
Definition: presburger.h:661
Definition: presburger.h:657
Definition: presburger.h:653
#define ASSERT(expr)
Definition: except.h:152
#define ERROR(msg)
Definition: except.h:141
int n
Definition: metadata.cc:15
Definition: allocator.h:9
PBMap moveDimsInputToParam(T &&map, unsigned first, unsigned n, unsigned target)
Definition: presburger.h:807
PBMap moveDimsInputToOutput(T &&map, unsigned first, unsigned n, unsigned target)
Definition: presburger.h:786
T * _COPY_ISL_PTR(const T *ptr, T *(copy)(T *))
Definition: presburger.h:39
PBMap sum(T &&lhs, U &&rhs)
Definition: presburger.h:959
PBMap intersectDomain(T &&lhs, U &&rhs)
Definition: presburger.h:893
auto pbFuncWithTimeout(const auto &func, int seconds, const auto &...args) -> std::optional< decltype(func(args...))>
Definition: presburger.h:1387
PBMap unwrap(T &&set)
Definition: presburger.h:1108
auto PBRefTake(std::remove_reference_t< T > &t)
Definition: presburger.h:663
auto && lhs
Definition: const_fold.cc:70
PBSpace spaceAlloc(const Ref< PBCtx > &ctx, unsigned nparam, unsigned nIn, unsigned nOut)
Definition: presburger.h:1024
PBSingleFunc max(T &&lhs, U &&rhs)
Definition: presburger.h:1137
PBMap applyRange(T &&lhs, U &&rhs)
Definition: presburger.h:953
PBSet params(T &&set)
Definition: presburger.h:1065
PBMap moveDimsParamToOutput(T &&map, unsigned first, unsigned n, unsigned target)
Definition: presburger.h:826
PBSet projectOutParamDims(T &&set, unsigned first, unsigned n)
Definition: presburger.h:694
PBMap projectOutOutputDims(T &&map, unsigned first, unsigned n)
Definition: presburger.h:722
PBMap insertOutputDims(T &&map, unsigned first, unsigned n)
Definition: presburger.h:737
PBMap upperBoundOutputDim(T &&map, unsigned pos, int x)
Definition: presburger.h:773
PBMap flattenDomain(T &&map)
Definition: presburger.h:1115
std::string toString(const AST &op)
Definition: print_ast.cc:784
PBSet insertDims(T &&set, unsigned first, unsigned n)
Definition: presburger.h:727
PBMap moveDimsOutputToParam(T &&map, unsigned first, unsigned n, unsigned target)
Definition: presburger.h:813
PBMap identity(T &&space)
Definition: presburger.h:999
PBMap projectOutInputDims(T &&map, unsigned first, unsigned n)
Definition: presburger.h:717
PBSet flatten(T &&set)
Definition: presburger.h:1112
PBSet domain(T &&map)
Definition: presburger.h:1050
PBSet moveDimsParamToSet(T &&set, unsigned first, unsigned n, unsigned target)
Definition: presburger.h:838
bool operator==(const Allocator< T > &lhs, const Allocator< T > &rhs)
Definition: allocator.h:100
PBMap moveDimsOutputToInput(T &&map, unsigned first, unsigned n, unsigned target)
Definition: presburger.h:792
T * MOVE_ISL_PTR(T *&ptr)
Definition: presburger.h:44
PBMap flattenRange(T &&map)
Definition: presburger.h:1118
PBMap insertInputDims(T &&map, unsigned first, unsigned n)
Definition: presburger.h:732
PBMap lexGT(T &&space)
Definition: presburger.h:1009
PBSet flattenMapToSet(T &&map)
Definition: presburger.h:1122
PBSet projectOutAllParams(T &&set)
Definition: presburger.h:679
PBMap lexLE(T &&space)
Definition: presburger.h:1014
PBSpace spaceSetAlloc(const Ref< PBCtx > &ctx, unsigned nparam, unsigned dim)
Definition: presburger.h:1029
PBSet projectOutDims(T &&set, unsigned first, unsigned n)
Definition: presburger.h:699
PBMap lowerBoundInputDim(T &&map, unsigned pos, int x)
Definition: presburger.h:756
PBSet moveDimsSetToParam(T &&set, unsigned first, unsigned n, unsigned target)
Definition: presburger.h:833
PBSet apply(T &&lhs, U &&rhs)
Definition: presburger.h:941
PBSet wrap(T &&map)
Definition: presburger.h:1104
PBVal dimMinVal(T &&set, int pos)
Definition: presburger.h:1091
PBSpace spaceMapFromSet(T &&space)
Definition: presburger.h:1100
PBSet lowerBoundDim(T &&set, unsigned pos, int x)
Definition: presburger.h:752
PBMap applyDomain(T &&lhs, U &&rhs)
Definition: presburger.h:947
PBSet complement(T &&set)
Definition: presburger.h:851
PBMap emptyMap(T &&space)
Definition: presburger.h:1038
PBMap fixInputDim(T &&map, unsigned pos, int x)
Definition: presburger.h:745
PBMap fixOutputDim(T &&map, unsigned pos, int x)
Definition: presburger.h:748
PBMap neg(T &&map)
Definition: presburger.h:970
PBMap lexmax(T &&map)
Definition: presburger.h:979
PBSet coefficients(T &&set, int64_t c=0)
Definition: presburger.h:1155
PBSet universeSet(T &&space)
Definition: presburger.h:1042
PBMap subtract(T &&lhs, U &&rhs)
Definition: presburger.h:865
std::vector< T > uni(const std::vector< T > &lhs, const std::vector< T > &rhs)
Definition: container_utils.h:85
PBMap lexGE(T &&space)
Definition: presburger.h:1004
auto auto && rhs
Definition: const_fold.cc:70
PBPoint sample(T &&set)
Definition: presburger.h:1126
Ref< PBCtx > commonCtx(const auto &lhs, const auto &rhs)
Definition: presburger.h:671
PBSet fixDim(T &&set, unsigned pos, int x)
Definition: presburger.h:742
PBMap lexmin(T &&map)
Definition: presburger.h:984
PBMap reverse(T &&map)
Definition: presburger.h:860
PBSet upperBoundDim(T &&set, unsigned pos, int x)
Definition: presburger.h:765
PBMap universeMap(T &&space)
Definition: presburger.h:1046
PBMap upperBoundInputDim(T &&map, unsigned pos, int x)
Definition: presburger.h:769
PBMap moveDimsParamToInput(T &&map, unsigned first, unsigned n, unsigned target)
Definition: presburger.h:820
PBSet projectOutParamById(T &&set, const std::string &name)
Definition: presburger.h:687
PBSet range(T &&map)
Definition: presburger.h:1054
PBSet emptySet(T &&space)
Definition: presburger.h:1034
PBMap lexLT(T &&space)
Definition: presburger.h:1019
PBVal dimMaxVal(T &&set, int pos)
Definition: presburger.h:1087
bool timeout(const std::function< void()> &func, int seconds)
Definition: timeout.cc:36
PBMap intersectRange(T &&lhs, U &&rhs)
Definition: presburger.h:900
PBSingleFunc min(T &&lhs, U &&rhs)
Definition: presburger.h:1131
PBMap newDomainOnlyMap(T &&set)
Definition: presburger.h:778
std::pair< PBSet, PBSet > padToSameDims(T &&lhs, U &&rhs)
Definition: presburger.h:844
PBSet intersectParams(T &&lhs, U &&rhs)
Definition: presburger.h:918
PBMap lowerBoundOutputDim(T &&map, unsigned pos, int x)
Definition: presburger.h:760
PBSet cartesianProduct(T &&lhs, U &&rhs)
Definition: presburger.h:1082
PBVal dimFixVal(const PBSet &set, int pos)
Definition: presburger.h:1095
std::unordered_map< T, std::pair< V1, V2 >, Hash, KeyEqual > intersect(const std::unordered_map< T, V1, Hash, KeyEqual > &lhs, const std::unordered_map< T, V2, Hash, KeyEqual > &rhs)
Definition: container_utils.h:24
PBSet coalesce(T &&set)
Definition: presburger.h:1072
bool isSubset(const PBSet &small, const PBSet &big)
Definition: presburger.h:1172
T * GET_ISL_PTR(T *ptr)
Definition: presburger.h:33
PBMap newRangeOnlyMap(T &&set)
Definition: presburger.h:781
STL namespace.
std::vector< Expr > vars_
Definition: pluto.cc:250
#define COPY_ISL_PTR(ptr, type)
Definition: presburger.h:38
#define DEBUG_PROFILE_VERBOSE(name, detail)
Definition: profile.h:45
#define DEBUG_PROFILE(name)
Definition: profile.h:43
PBFunc::Serialized func_
Definition: prop_one_time_use.cc:22