From e0e7f5ff1e2393311a7caea1f08fef48adacffb6 Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Fri, 27 Jul 2018 10:52:42 +0200 Subject: [PATCH 001/102] fix return type of operator+(int i, T A) This was missing from 9904d3017 (generalize operator+(int i, T A) to template form, Tue Jul 24 17:45:43 2018 +0200). --- tc/external/detail/islpp-inl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tc/external/detail/islpp-inl.h b/tc/external/detail/islpp-inl.h index 6991d257a..d6bb2eb9e 100644 --- a/tc/external/detail/islpp-inl.h +++ b/tc/external/detail/islpp-inl.h @@ -42,7 +42,7 @@ inline isl::aff operator/(isl::aff A, int i) { } template -inline isl::aff operator+(int i, T A) { +inline T operator+(int i, T A) { return A.add_constant_si(i); } From b4ee22e125c45e9b07f5708e6a82a22bb6e35be2 Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Fri, 27 Jul 2018 10:54:37 +0200 Subject: [PATCH 002/102] generalize operator+(T A, int i) to template form This will ensure that it also applies to templated isl types derived from isl::aff. Make sure the template type T has an add_constant_si method to avoid the template operator getting triggered on vector types. --- tc/external/detail/islpp-inl.h | 3 ++- tc/external/detail/islpp.h | 1 - 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tc/external/detail/islpp-inl.h b/tc/external/detail/islpp-inl.h index d6bb2eb9e..f2f778efe 100644 --- a/tc/external/detail/islpp-inl.h +++ b/tc/external/detail/islpp-inl.h @@ -55,7 +55,8 @@ inline isl::aff operator+(isl::val v, isl::aff A) { return A + v; } -inline isl::aff operator+(isl::aff A, int i) { +template +inline auto operator+(T A, int i) -> decltype(A.add_constant_si(i)) { return i + A; } diff --git a/tc/external/detail/islpp.h b/tc/external/detail/islpp.h index 96fa168ff..8e64bac0c 100644 --- a/tc/external/detail/islpp.h +++ b/tc/external/detail/islpp.h @@ -128,7 +128,6 @@ isl::aff operator*(isl::val V, isl::aff A); isl::aff operator/(isl::aff A, int i); -isl::aff operator+(isl::aff A, int i); isl::aff operator+(isl::aff A, isl::val v); isl::aff operator+(isl::val v, isl::aff A); From 017f6b218783e49a59b60f9292b223966e87d9ac Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Tue, 31 Jul 2018 12:36:08 +0200 Subject: [PATCH 003/102] generalize operator-(T A, int i) to template form This will ensure that it also applies to templated isl types derived from isl::aff. Make sure the template type T has an add_constant_si method to avoid the template operator getting triggered on vector types. --- tc/external/detail/islpp-inl.h | 3 ++- tc/external/detail/islpp.h | 1 - 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tc/external/detail/islpp-inl.h b/tc/external/detail/islpp-inl.h index f2f778efe..5342998e9 100644 --- a/tc/external/detail/islpp-inl.h +++ b/tc/external/detail/islpp-inl.h @@ -60,7 +60,8 @@ inline auto operator+(T A, int i) -> decltype(A.add_constant_si(i)) { return i + A; } -inline isl::aff operator-(isl::aff A, int i) { +template +inline auto operator-(T A, int i) -> decltype(A.add_constant_si(i)) { return A + (-i); } diff --git a/tc/external/detail/islpp.h b/tc/external/detail/islpp.h index 8e64bac0c..d902cfc5d 100644 --- a/tc/external/detail/islpp.h +++ b/tc/external/detail/islpp.h @@ -131,7 +131,6 @@ isl::aff operator/(isl::aff A, int i); isl::aff operator+(isl::aff A, isl::val v); isl::aff operator+(isl::val v, isl::aff A); -isl::aff operator-(isl::aff A, int i); isl::aff operator-(int i, isl::aff A); // Thin wrapper around aff to disambiguate types for operators and avoid case From c6edb23263083aaef9b5a822806c5452e8f42514 Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Tue, 31 Jul 2018 15:38:17 +0200 Subject: [PATCH 004/102] generalize operator-(int i, T A) to template form This will ensure that it also applies to templated isl types derived from isl::aff. Make sure the template type T has an add_constant_si method to avoid the template operator getting triggered on vector types. --- tc/external/detail/islpp-inl.h | 5 +++-- tc/external/detail/islpp.h | 2 -- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/tc/external/detail/islpp-inl.h b/tc/external/detail/islpp-inl.h index 5342998e9..005358acc 100644 --- a/tc/external/detail/islpp-inl.h +++ b/tc/external/detail/islpp-inl.h @@ -65,8 +65,9 @@ inline auto operator-(T A, int i) -> decltype(A.add_constant_si(i)) { return A + (-i); } -inline isl::aff operator-(int i, isl::aff A) { - return (A + (-i)).neg(); +template +inline auto operator-(int i, T A) -> decltype(A.add_constant_si(i)) { + return i + A.neg(); } inline isl::set operator>=(isl::aff_set A, isl::val v) { diff --git a/tc/external/detail/islpp.h b/tc/external/detail/islpp.h index d902cfc5d..406fd49d7 100644 --- a/tc/external/detail/islpp.h +++ b/tc/external/detail/islpp.h @@ -131,8 +131,6 @@ isl::aff operator/(isl::aff A, int i); isl::aff operator+(isl::aff A, isl::val v); isl::aff operator+(isl::val v, isl::aff A); -isl::aff operator-(int i, isl::aff A); - // Thin wrapper around aff to disambiguate types for operators and avoid case // where return type overloading occurs struct aff_set { From 4cd6b798338960bdbcfa27a4147c8c97044d38a2 Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Mon, 30 Jul 2018 17:55:52 +0200 Subject: [PATCH 005/102] generalize operator/(S left, T right) to template form This will ensure that it also applies to templated isl types derived from isl::multi_aff and isl::multi_val. Make sure the template type T has a scale_down method to avoid the template operator getting triggered on other types. --- tc/external/detail/islpp-inl.h | 3 ++- tc/external/detail/islpp.h | 5 ----- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/tc/external/detail/islpp-inl.h b/tc/external/detail/islpp-inl.h index 005358acc..999eaff29 100644 --- a/tc/external/detail/islpp-inl.h +++ b/tc/external/detail/islpp-inl.h @@ -187,7 +187,8 @@ inline isl::map operator<=(isl::aff_map A, isl::aff B) { /////////////////////////////////////////////////////////////////////////////// // Operations on isl::multi_aff /////////////////////////////////////////////////////////////////////////////// -inline isl::multi_aff operator/(isl::multi_aff left, isl::multi_val right) { +template +inline auto operator/(S left, T right) -> decltype(left.scale_down(right)) { return left.scale_down(right); } diff --git a/tc/external/detail/islpp.h b/tc/external/detail/islpp.h index 406fd49d7..59afd5c1f 100644 --- a/tc/external/detail/islpp.h +++ b/tc/external/detail/islpp.h @@ -176,11 +176,6 @@ isl::map operator<=(isl::aff_map A, isl::aff B); isl::map operator>(isl::aff_map A, isl::aff B); isl::map operator<(isl::aff_map A, isl::aff B); -/////////////////////////////////////////////////////////////////////////////// -// Operations on isl::multi_aff -/////////////////////////////////////////////////////////////////////////////// -isl::multi_aff operator/(isl::multi_aff left, isl::multi_val right); - /////////////////////////////////////////////////////////////////////////////// // Operations on isl::set and isl::union_set /////////////////////////////////////////////////////////////////////////////// From 940516d0baa8783213b92461e3c13d232afe4044 Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Thu, 26 Jul 2018 09:18:39 +0200 Subject: [PATCH 006/102] bump isl for export of isl_aff_add_constant_val --- isl_interface/include/isl/cpp.h | 26 ++++++++++++++++++++++++++ third-party/islpp | 2 +- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/isl_interface/include/isl/cpp.h b/isl_interface/include/isl/cpp.h index aa9ce0a00..0a77dcf19 100644 --- a/isl_interface/include/isl/cpp.h +++ b/isl_interface/include/isl/cpp.h @@ -318,6 +318,7 @@ class aff { inline std::string to_str() const; inline isl::aff add(isl::aff aff2) const; + inline isl::aff add_constant(isl::val v) const; inline isl::aff add_constant_si(int v) const; inline isl::aff ceil() const; inline isl::aff div(isl::aff aff2) const; @@ -2166,6 +2167,7 @@ class pw_aff { inline isl::pw_aff neg() const; inline isl::set nonneg_set() const; inline isl::set params() const; + inline isl::set pos_set() const; inline isl::pw_aff project_domain_on_params() const; inline isl::pw_aff pullback(isl::multi_aff ma) const; inline isl::pw_aff pullback(isl::pw_multi_aff pma) const; @@ -3593,6 +3595,18 @@ isl::aff aff::add(isl::aff aff2) const return manage(res); } +isl::aff aff::add_constant(isl::val v) const +{ + if (!ptr || v.is_null()) + throw isl::exception::create(isl_error_invalid, + "NULL input", __FILE__, __LINE__); + options_scoped_set_on_error saved_on_error(get_ctx(), ISL_ON_ERROR_CONTINUE); + auto res = isl_aff_add_constant_val(copy(), v.release()); + if (!res) + throw exception::create_from_last_error(get_ctx()); + return manage(res); +} + isl::aff aff::add_constant_si(int v) const { if (!ptr) @@ -13082,6 +13096,18 @@ isl::set pw_aff::params() const return manage(res); } +isl::set pw_aff::pos_set() const +{ + if (!ptr) + throw isl::exception::create(isl_error_invalid, + "NULL input", __FILE__, __LINE__); + options_scoped_set_on_error saved_on_error(get_ctx(), ISL_ON_ERROR_CONTINUE); + auto res = isl_pw_aff_pos_set(copy()); + if (!res) + throw exception::create_from_last_error(get_ctx()); + return manage(res); +} + isl::pw_aff pw_aff::project_domain_on_params() const { if (!ptr) diff --git a/third-party/islpp b/third-party/islpp index 35748a0c1..6771372d7 160000 --- a/third-party/islpp +++ b/third-party/islpp @@ -1 +1 @@ -Subproject commit 35748a0c1fc63ea3ba7296f8b4e40346426f53b3 +Subproject commit 6771372d7b0f792f05609b2da9a84a71af3aac05 From dd5952aa5803bd7d87acd290bb6c7e15d15bf756 Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Fri, 3 Aug 2018 11:26:12 +0200 Subject: [PATCH 007/102] operator+(isl::aff A, isl::val v): call isl::aff::add_constant There is no need to create an extra isl::aff object here. --- tc/external/detail/islpp-inl.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tc/external/detail/islpp-inl.h b/tc/external/detail/islpp-inl.h index 999eaff29..e9cc4a4ec 100644 --- a/tc/external/detail/islpp-inl.h +++ b/tc/external/detail/islpp-inl.h @@ -47,8 +47,7 @@ inline T operator+(int i, T A) { } inline isl::aff operator+(isl::aff A, isl::val v) { - isl::aff T(isl::local_space(A.get_space().domain()), v); - return A.add(T); + return A.add_constant(v); } inline isl::aff operator+(isl::val v, isl::aff A) { From 877508220413837b1a61a7d0e6dec295d9d67871 Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Fri, 3 Aug 2018 11:33:14 +0200 Subject: [PATCH 008/102] generalize operator+(T A, isl::val v) to template form This will ensure that it also applies to templated isl types derived from isl::aff. Make sure the template type T has an add_constant method to avoid the template operator getting triggered on other types. --- tc/external/detail/islpp-inl.h | 3 ++- tc/external/detail/islpp.h | 1 - 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tc/external/detail/islpp-inl.h b/tc/external/detail/islpp-inl.h index e9cc4a4ec..2e57812c3 100644 --- a/tc/external/detail/islpp-inl.h +++ b/tc/external/detail/islpp-inl.h @@ -46,7 +46,8 @@ inline T operator+(int i, T A) { return A.add_constant_si(i); } -inline isl::aff operator+(isl::aff A, isl::val v) { +template +inline auto operator+(T A, isl::val v) -> decltype(A.add_constant(v)) { return A.add_constant(v); } diff --git a/tc/external/detail/islpp.h b/tc/external/detail/islpp.h index 59afd5c1f..df19643a5 100644 --- a/tc/external/detail/islpp.h +++ b/tc/external/detail/islpp.h @@ -128,7 +128,6 @@ isl::aff operator*(isl::val V, isl::aff A); isl::aff operator/(isl::aff A, int i); -isl::aff operator+(isl::aff A, isl::val v); isl::aff operator+(isl::val v, isl::aff A); // Thin wrapper around aff to disambiguate types for operators and avoid case From 7789b79a2328029e7044f0ff18be976f6eaecaf0 Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Fri, 3 Aug 2018 10:57:55 +0200 Subject: [PATCH 009/102] generalize operator*(T A, isl::val v) to template form This will ensure that it also applies to templated isl types derived from isl::aff. Make sure the template type T has a scale method to avoid the template operator getting triggered on other types. --- tc/external/detail/islpp-inl.h | 18 ++++++++++-------- tc/external/detail/islpp.h | 2 -- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/tc/external/detail/islpp-inl.h b/tc/external/detail/islpp-inl.h index 2e57812c3..8ce3579f9 100644 --- a/tc/external/detail/islpp-inl.h +++ b/tc/external/detail/islpp-inl.h @@ -20,6 +20,16 @@ namespace isl { /////////////////////////////////////////////////////////////////////////////// // Operations on isl::aff to perform arithmetic and create/combine with sets /////////////////////////////////////////////////////////////////////////////// +template +inline auto operator*(isl::val V, T A) -> decltype(A.scale(V)) { + return A.scale(V); +} + +template +inline auto operator*(T A, isl::val V) -> decltype(A.scale(V)) { + return V * A; +} + inline isl::aff operator*(int i, isl::aff A) { isl::val V(isl::val(A.get_ctx(), i)); return A * V; @@ -29,14 +39,6 @@ inline isl::aff operator*(isl::aff A, int i) { return i * A; } -inline isl::aff operator*(isl::val V, isl::aff A) { - return A.scale(V); -} - -inline isl::aff operator*(isl::aff A, isl::val V) { - return V * A; -} - inline isl::aff operator/(isl::aff A, int i) { return A.scale_down(isl::val(A.get_ctx(), i)); } diff --git a/tc/external/detail/islpp.h b/tc/external/detail/islpp.h index df19643a5..612957080 100644 --- a/tc/external/detail/islpp.h +++ b/tc/external/detail/islpp.h @@ -123,8 +123,6 @@ inline bool operator!=(isl::val v1, isl::val v2) { /////////////////////////////////////////////////////////////////////////////// isl::aff operator*(int i, isl::aff A); isl::aff operator*(isl::aff A, int i); -isl::aff operator*(isl::aff A, isl::val V); -isl::aff operator*(isl::val V, isl::aff A); isl::aff operator/(isl::aff A, int i); From 3be2511e3751d366324d1fc3fc0e71aa5c93a168 Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Thu, 26 Jul 2018 09:39:09 +0200 Subject: [PATCH 010/102] MappedScop::insertMappingContext: drop redundant universe() call --- tc/core/polyhedral/cuda/mapped_scop.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tc/core/polyhedral/cuda/mapped_scop.cc b/tc/core/polyhedral/cuda/mapped_scop.cc index 02e603b2a..930c92aa3 100644 --- a/tc/core/polyhedral/cuda/mapped_scop.cc +++ b/tc/core/polyhedral/cuda/mapped_scop.cc @@ -862,7 +862,7 @@ void MappedScop::insertMappingContext() { {TX, TX.mappingSize(block)}, {TY, TY.mappingSize(block)}, {TZ, TZ.mappingSize(block)}}; - auto space = scop.domain().universe().get_space(); + auto space = scop.domain().get_space(); auto mappingContext = makeParameterContext( space, mappingIdsWithSizes.begin(), mappingIdsWithSizes.end()); updateTopLevelContext(scop.scheduleRoot(), mappingContext.from_params()); From ed82d3e0afd82619a52a38357622330099df044b Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Fri, 27 Jul 2018 16:06:14 +0200 Subject: [PATCH 011/102] ScheduleTreeBand::drop: do not call domain() on a set space The space of an isl_multi_union_pw_aff is the common range space, i.e., a set space. The current version of isl tolerates calling domain() on a set space, but it is technically incorrect. Call params() instead. Moving to templated isl types will make this issue more evident. --- tc/core/polyhedral/schedule_tree_elem.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tc/core/polyhedral/schedule_tree_elem.cc b/tc/core/polyhedral/schedule_tree_elem.cc index 77db24859..442d805ab 100644 --- a/tc/core/polyhedral/schedule_tree_elem.cc +++ b/tc/core/polyhedral/schedule_tree_elem.cc @@ -235,7 +235,7 @@ void ScheduleTreeBand::drop(size_t pos, size_t n) { auto nBegin = nMember(); auto list = mupa_.get_union_pw_aff_list(); - auto space = mupa_.get_space().domain(); + auto space = mupa_.get_space().params(); list = list.drop(pos, n); space = space.add_unnamed_tuple_ui(list.size()); mupa_ = isl::multi_union_pw_aff(space, list); From a6adf84cecc58fac0de64e66588eaff91d102f9e Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Thu, 2 Aug 2018 12:01:26 +0200 Subject: [PATCH 012/102] memory_promotion.cc: referenceOriginalAccessesImpl: add missing params() call In theory, the isl::union_map::empty factory method expects a parameter space. In practice, isl acceps any kind of space (from which it extracts a parameter space). For switching to templated isl types, it is better to use a consistent type of space. --- tc/core/polyhedral/memory_promotion.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tc/core/polyhedral/memory_promotion.cc b/tc/core/polyhedral/memory_promotion.cc index b1b947c00..ebc7e421f 100644 --- a/tc/core/polyhedral/memory_promotion.cc +++ b/tc/core/polyhedral/memory_promotion.cc @@ -218,7 +218,7 @@ isl::union_map referenceOriginalAccessesImpl( throw promotion::GroupingError("no references in the group"); } auto accesses = isl::union_map::empty( - group.references.front()->originalAccess.get_space()); + group.references.front()->originalAccess.get_space().params()); for (const auto& ref : group.references) { if (ref->type != type) { From 5900b0665fa4c4fee95ac290549180302d0bcd23 Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Tue, 31 Jul 2018 11:16:31 +0200 Subject: [PATCH 013/102] Scop::makeScop: automatically deduce type of space variable This will make it easier to switch to templated isl types. --- tc/core/polyhedral/scop.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tc/core/polyhedral/scop.cc b/tc/core/polyhedral/scop.cc index 71d3bc176..41cc17448 100644 --- a/tc/core/polyhedral/scop.cc +++ b/tc/core/polyhedral/scop.cc @@ -51,7 +51,7 @@ ScopUPtr Scop::makeScop( halide2isl::SymbolTable sym = halide2isl::makeSymbolTable(components); - isl::space paramSpace = halide2isl::makeParamSpace(ctx, sym.params); + auto paramSpace = halide2isl::makeParamSpace(ctx, sym.params); ScopUPtr scop(new Scop()); scop->halide.params = sym.params; From 340abcfd0c7b671a14c40f6ee06abcee0d8bec34 Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Thu, 21 Jun 2018 12:05:24 +0200 Subject: [PATCH 014/102] halide2isl.cc: extractAccess: automatically deduce type of space variables This will make it easier to switch to templated isl types. --- tc/core/halide2isl.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tc/core/halide2isl.cc b/tc/core/halide2isl.cc index dbc7e60f2..cb46434ba 100644 --- a/tc/core/halide2isl.cc +++ b/tc/core/halide2isl.cc @@ -292,8 +292,8 @@ isl::map extractAccess( std::string tag = "__tc_ref_" + std::to_string(accesses->size()); isl::id tagID(domain.paramSpace.get_ctx(), tag); accesses->emplace(op, tagID); - isl::space domainSpace = map.get_space().domain(); - isl::space tagSpace = domainSpace.params().add_named_tuple_id_ui(tagID, 0); + auto domainSpace = map.get_space().domain(); + auto tagSpace = domainSpace.params().add_named_tuple_id_ui(tagID, 0); domainSpace = domainSpace.product(tagSpace).unwrap(); map = map.preimage_domain(isl::multi_aff::domain_map(domainSpace)); From 3a8e6223541fdeeed7e6624f69b95b3ec59dc866 Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Fri, 27 Jul 2018 10:57:56 +0200 Subject: [PATCH 015/102] promotionImprovesCoalescing: use get_map_list This will make it easier to switch to templated types. --- tc/core/polyhedral/cuda/memory_promotion_heuristic.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tc/core/polyhedral/cuda/memory_promotion_heuristic.cc b/tc/core/polyhedral/cuda/memory_promotion_heuristic.cc index b1bca6923..928ee904a 100644 --- a/tc/core/polyhedral/cuda/memory_promotion_heuristic.cc +++ b/tc/core/polyhedral/cuda/memory_promotion_heuristic.cc @@ -227,7 +227,7 @@ bool promotionImprovesCoalescing( auto localAccesses = originalAccesses.intersect_domain(activePoints); auto schedule = prefixSchedule(root, marker); auto scheduledAccesses = localAccesses.apply_domain(schedule); - for (auto access : isl::UnionAsVector(scheduledAccesses)) { + for (auto access : scheduledAccesses.get_map_list()) { auto scheduleSpace = access.get_space().domain(); auto tensorSpace = access.get_space().range(); auto elementToNext = makeNextElementMap(tensorSpace, tensorDim - 1); From 5651b42704dd0714431ddb53a79ad87c3020fcbc Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Fri, 27 Jul 2018 21:48:13 +0200 Subject: [PATCH 016/102] addSingletonReferenceGroups: use get_map_list This will make it easier to switch to templated types. --- tc/core/polyhedral/memory_promotion.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tc/core/polyhedral/memory_promotion.cc b/tc/core/polyhedral/memory_promotion.cc index ebc7e421f..37656f09a 100644 --- a/tc/core/polyhedral/memory_promotion.cc +++ b/tc/core/polyhedral/memory_promotion.cc @@ -302,7 +302,7 @@ void addSingletonReferenceGroups( // use currying to isolate the D part before intersecting with the domain // Compute initial groups with single reference per group. std::unordered_set unapproximatable; - for (auto a : isl::UnionAsVector(accesses)) { + for (auto a : accesses.get_map_list()) { if (isl::union_map(a.curry()).intersect_domain(domain).is_empty()) { continue; } From e3131775ed67d438405eb3e9c69ae3fd3885fb6f Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Thu, 26 Jul 2018 09:18:39 +0200 Subject: [PATCH 017/102] bump isl for export of isl_map_zip --- isl_interface/include/isl/cpp.h | 13 +++++++++++++ third-party/islpp | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/isl_interface/include/isl/cpp.h b/isl_interface/include/isl/cpp.h index 0a77dcf19..70217ac36 100644 --- a/isl_interface/include/isl/cpp.h +++ b/isl_interface/include/isl/cpp.h @@ -1705,6 +1705,7 @@ class map { static inline isl::map universe(isl::space space); inline isl::basic_map unshifted_simple_hull() const; inline isl::set wrap() const; + inline isl::map zip() const; typedef isl_map* isl_ptr_t; }; @@ -9748,6 +9749,18 @@ isl::set map::wrap() const return manage(res); } +isl::map map::zip() const +{ + if (!ptr) + throw isl::exception::create(isl_error_invalid, + "NULL input", __FILE__, __LINE__); + options_scoped_set_on_error saved_on_error(get_ctx(), ISL_ON_ERROR_CONTINUE); + auto res = isl_map_zip(copy()); + if (!res) + throw exception::create_from_last_error(get_ctx()); + return manage(res); +} + // implementations for isl::map_list isl::map_list manage(__isl_take isl_map_list *ptr) { if (!ptr) diff --git a/third-party/islpp b/third-party/islpp index 6771372d7..e1f96fb82 160000 --- a/third-party/islpp +++ b/third-party/islpp @@ -1 +1 @@ -Subproject commit 6771372d7b0f792f05609b2da9a84a71af3aac05 +Subproject commit e1f96fb82746f01cad0f345fa105dafe255df80e From dbe1c2296fc482b43567922bd82af85cd0e5b2db Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Wed, 1 Aug 2018 15:17:06 +0200 Subject: [PATCH 018/102] build generate_isl_cpp_h unconditionally In particular, also build this target when WITH_BINDINGS is not set. In this case, it currently does nothing and does not depend on anything, but the availability of an unconditional target will make it possible to reuse this target to also build the templated isl header in the next commit, independently of the WITH_BINDINGS setting. --- CMakeLists.txt | 10 ++++++++++ isl_interface/CMakeLists.txt | 6 ++---- tc/core/CMakeLists.txt | 4 +--- test/CMakeLists.txt | 4 +--- 4 files changed, 14 insertions(+), 10 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2dd1d46e0..30a6e721c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -334,6 +334,16 @@ else() message(STATUS "Not building benchmarks, caffe2 or CUDA not available") endif() +SET(ISL_CPP_H "${CMAKE_CURRENT_LIST_DIR}/isl_interface/include/isl/cpp.h") + if (WITH_BINDINGS) add_subdirectory(isl_interface) + + # generate_isl_cpp_h is the dependency that should be used + # by code that depends on the isl C++ bindings. + add_custom_target(generate_isl_cpp_h + DEPENDS generate_isl_cpp_h_core) +else() + add_custom_target(generate_isl_cpp_h + DEPENDS) endif() diff --git a/isl_interface/CMakeLists.txt b/isl_interface/CMakeLists.txt index e51621299..5c0772f16 100644 --- a/isl_interface/CMakeLists.txt +++ b/isl_interface/CMakeLists.txt @@ -86,7 +86,6 @@ target_link_libraries(extract_isl_interface # Dummy library to ensure that C++ bindings depend on contents of header files. add_library(isl_all_h_dep STATIC ${ISL_DIR}/all.c) -SET(ISL_CPP_H "${CMAKE_CURRENT_LIST_DIR}/include/isl/cpp.h") add_custom_command( OUTPUT ${ISL_CPP_H} DEPENDS isl_all_h_dep @@ -106,6 +105,5 @@ add_custom_command( COMMAND cat ${ISL_DIR}/cpp/cpp.h.bot >> ${ISL_CPP_H} || exit 1 DEPENDS extract_isl_interface ) -# generate_isl_cpp_h is the dependency that should be used -# by code that depends on the isl C++ bindings. -add_custom_target(generate_isl_cpp_h DEPENDS ${ISL_CPP_H}) + +add_custom_target(generate_isl_cpp_h_core DEPENDS ${ISL_CPP_H}) diff --git a/tc/core/CMakeLists.txt b/tc/core/CMakeLists.txt index 504dea4e6..8842ff7cf 100644 --- a/tc/core/CMakeLists.txt +++ b/tc/core/CMakeLists.txt @@ -51,9 +51,7 @@ target_link_libraries( tc_version tc_proto ) -if (WITH_BINDINGS) - add_dependencies(tc_core generate_isl_cpp_h) -endif() +add_dependencies(tc_core generate_isl_cpp_h) install( TARGETS tc_core diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 5f18be9c6..f97eeb01f 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -13,9 +13,7 @@ set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) add_executable(test_basic test_basic.cc) add_test(test_basic test_basic) target_link_libraries(test_basic ${GOOGLE_LIBRARIES} ${ISL_LIBRARIES} ${ATEN_LIBRARIES} pthread) -if (WITH_BINDINGS) - add_dependencies(test_basic generate_isl_cpp_h) -endif() +add_dependencies(test_basic generate_isl_cpp_h) ################################################################################ # Core library only tests From dddbdec7c71848248ce76acfac9e2479a7d498e9 Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Thu, 19 Jul 2018 17:20:28 +0200 Subject: [PATCH 019/102] generate templated isl types --- CMakeLists.txt | 23 +- isl_interface/generate_template_isl.cc | 1135 ++++++++++++++++++++++++ tc/external/detail/islpp.h | 2 + 3 files changed, 1158 insertions(+), 2 deletions(-) create mode 100644 isl_interface/generate_template_isl.cc diff --git a/CMakeLists.txt b/CMakeLists.txt index 30a6e721c..3666cbd9d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -225,6 +225,7 @@ message(STATUS "Found ATen.so file: ${ATEN_LIBRARIES}") ################################################################################ # use locally generated C++ bindings include_directories(AFTER ${PROJECT_SOURCE_DIR}/isl_interface/include) +include_directories(AFTER ${CMAKE_CURRENT_BINARY_DIR}/isl_interface/include) include_directories(AFTER ${PROJECT_SOURCE_DIR}/third-party/islpp/include) include_directories(AFTER ${CMAKE_CURRENT_BINARY_DIR}/third-party/islpp/include) add_subdirectory(external/isl) @@ -336,14 +337,32 @@ endif() SET(ISL_CPP_H "${CMAKE_CURRENT_LIST_DIR}/isl_interface/include/isl/cpp.h") +add_executable(generate_template_isl isl_interface/generate_template_isl.cc) + +find_program(CLANG_FORMAT_BIN clang-format PATHS ${CLANG_PREFIX} + PATH_SUFFIXES bin + NO_DEFAULT_PATH) + +SET(ISL_TEMPLATE_CPP_DIR + "${CMAKE_CURRENT_BINARY_DIR}/isl_interface/include/isl") +SET(ISL_TEMPLATE_CPP_H "${ISL_TEMPLATE_CPP_DIR}/template_cpp.h") +add_custom_command( + OUTPUT ${ISL_TEMPLATE_CPP_H} + DEPENDS ${ISL_CPP_H} + DEPENDS generate_template_isl + COMMAND mkdir -p ${ISL_TEMPLATE_CPP_DIR} + COMMAND generate_template_isl < ${ISL_CPP_H} > ${ISL_TEMPLATE_CPP_H} + COMMAND ${CLANG_FORMAT_BIN} -i ${ISL_TEMPLATE_CPP_H} +) + if (WITH_BINDINGS) add_subdirectory(isl_interface) # generate_isl_cpp_h is the dependency that should be used # by code that depends on the isl C++ bindings. add_custom_target(generate_isl_cpp_h - DEPENDS generate_isl_cpp_h_core) + DEPENDS generate_isl_cpp_h_core ${ISL_TEMPLATE_CPP_H}) else() add_custom_target(generate_isl_cpp_h - DEPENDS) + DEPENDS ${ISL_TEMPLATE_CPP_H}) endif() diff --git a/isl_interface/generate_template_isl.cc b/isl_interface/generate_template_isl.cc new file mode 100644 index 000000000..7a8d9393e --- /dev/null +++ b/isl_interface/generate_template_isl.cc @@ -0,0 +1,1135 @@ +/** + * Copyright (c) 2018, Facebook, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +constexpr auto header = R"CPP( +struct Anonymous; + +template +struct NamedPair; + +template +using Pair = NamedPair; +)CPP"; + +constexpr auto footer = R"CPP( +template +using AffOn = Aff; + +template +using PwAffOn = PwAff; + +template +using UnionPwAffOn = UnionPwAff; + +template +using AffListOn = AffList; + +template +using PwAffListOn = PwAffList; + +template +using UnionPwAffListOn = UnionPwAffList; +)CPP"; + +static std::string dropIslNamespace(std::string type) { + return std::regex_replace(type, std::regex("isl::"), ""); +} + +template +struct Signature { + Type returnType; + std::vector argTypes; +}; + +using Type = std::string; +struct BaseKind { + BaseKind(const char* name) : name(name) {} + BaseKind(std::initializer_list c) : children(c) { + if (c.size() == 2) { + children.insert(children.begin(), "Anonymous"); + } + if (children.size() != 3) { + abort(); + } + } + std::string name; + std::vector children; + bool operator<(const BaseKind& other) const { + if (children.size() != other.children.size()) { + return children.size() < other.children.size(); + } + if (children.size() == 0) { + return name < other.name; + } + for (size_t i = 0; i < children.size(); ++i) { + if (children[i] != other.children[i]) { + return children[i] < other.children[i]; + } + } + return false; + } + bool operator==(const BaseKind& other) const { + return name == other.name && children == other.children; + } + bool operator!=(const BaseKind& other) const { + return !(*this == other); + } +}; +using Kind = std::vector; + +struct Method { + std::string name; + Signature signature; +}; + +using Exported = std::unordered_map>; + +struct Class { + std::string name; + std::vector kinds; +}; + +static Kind params_type() { + return {}; +} + +static Kind set_type() { + return {"Domain"}; +} + +static Kind map_type() { + return {"Domain", "Range"}; +} + +static const std::unordered_map classes{ + {"space", {"Space", {params_type(), set_type(), map_type()}}}, + {"multi_id", {"MultiId", {set_type()}}}, + {"multi_val", {"MultiVal", {set_type()}}}, + {"set", {"Set", {params_type(), set_type()}}}, + {"map", {"Map", {map_type()}}}, + {"aff", {"Aff", {set_type(), map_type()}}}, + {"aff_list", {"AffList", {set_type(), map_type()}}}, + {"pw_aff", {"PwAff", {set_type(), map_type()}}}, + {"union_pw_aff", {"UnionPwAff", {set_type(), map_type()}}}, + {"multi_aff", {"MultiAff", {map_type()}}}, + {"pw_aff_list", {"PwAffList", {set_type(), map_type()}}}, + {"union_pw_aff_list", {"UnionPwAffList", {set_type(), map_type()}}}, + {"multi_union_pw_aff", {"MultiUnionPwAff", {map_type()}}}, + {"union_pw_multi_aff", {"UnionPwMultiAff", {map_type()}}}, + {"union_set", {"UnionSet", {params_type(), set_type()}}}, + {"union_map", {"UnionMap", {map_type()}}}, + {"map_list", {"MapList", {map_type()}}}, + {"union_access_info", {"UnionAccessInfo", {map_type()}}}, + {"union_flow", {"UnionFlow", {map_type()}}}, + {"stride_info", {"StrideInfo", {map_type()}}}, + {"fixed_box", {"FixedBox", {map_type()}}}, +}; + +static Signature create_params() { + return {{}, {}}; +} + +static Signature create_set() { + return {{"Domain"}, {}}; +} + +static Signature change_set() { + return {{"ModifiedDomain"}, {{"Domain"}}}; +} + +static Signature change_wrapped_set() { + return {{{"ModifiedWrap", "WrappedDomain", "WrappedRange"}}, + {{{"Wrap", "WrappedDomain", "WrappedRange"}}}}; +} + +static Signature change_range() { + return {{"Domain", "ModifiedRange"}, {{"Domain", "Range"}}}; +} + +static Signature create_map() { + return {{"Domain", "Range"}, {}}; +} + +static Signature apply_set() { + return {{"Range"}, {{"Domain"}, {"Domain", "Range"}}}; +} + +static Signature apply_domain() { + return {{"Range3", "Range"}, {{"Domain", "Range"}, {"Domain", "Range3"}}}; +} + +static Signature preimage_domain() { + return {{"Domain2", "Range"}, {{"Domain", "Range"}, {"Domain2", "Domain"}}}; +} + +static Signature apply_range() { + return {{"Domain", "Range2"}, {{"Domain", "Range"}, {"Range", "Range2"}}}; +} + +static Signature modify_params_unary() { + return {{}, {{}}}; +} + +static Signature modify_params_binary() { + return {{}, {{}, {}}}; +} + +static Signature modify_set_params() { + return {{"Domain"}, {{"Domain"}, {}}}; +} + +static Signature modify_set_unary() { + return {{"Domain"}, {{"Domain"}}}; +} + +static Signature modify_set_binary() { + return {{"Domain"}, {{"Domain"}, {"Domain"}}}; +} + +static Signature modify_domain() { + return {{"Domain", "Range"}, {{"Domain", "Range"}, {"Domain"}}}; +} + +static Signature modify_range() { + return {{"Domain", "Range"}, {{"Domain", "Range"}, {"Range"}}}; +} + +static Signature modify_map_params() { + return {{"Domain", "Range"}, {{"Domain", "Range"}, {}}}; +} + +static Signature modify_map() { + return {{"Domain", "Range"}, {{"Domain", "Range"}, {"Domain", "Range"}}}; +} + +static Signature modify_map_unary() { + return {{"Domain", "Range"}, {{"Domain", "Range"}}}; +} + +static Signature map_from_set() { + return {{"Domain", "Domain"}, {{"Domain"}}}; +} + +static Signature map_on_domain() { + return {{"Domain", "Domain"}, {{"Domain", "Range"}}}; +} + +static Signature map_from_domain() { + return {{"Domain", "Range"}, {{"Domain"}}}; +} + +static Signature set_from_params() { + return {{"Domain"}, {{}}}; +} + +static Signature map_from_params() { + return {{"Domain", "Range"}, {{}}}; +} + +static Signature set_params() { + return {{}, {{"Domain"}}}; +} + +static Signature map_params() { + return {{}, {{"Domain", "Range"}}}; +} + +static Signature set_binary_params() { + return {{}, {{"Domain"}, {"Domain"}}}; +} + +static Signature domain() { + return {{"Domain"}, {{"Domain", "Range"}}}; +} + +static Signature domain_map() { + return {{{"Domain", "Range"}, "Domain"}, {{"Domain", "Range"}}}; +} + +static Signature static_domain_map() { + return {{{"Range", "Domain2"}, "Range"}, {{"Range", "Domain2"}}}; +} + +static Signature static_range_map() { + return {{{"Domain2", "Range"}, "Range"}, {{"Domain2", "Range"}}}; +} + +static Signature static_wrapped_range_map() { + return {{{"Wrap", "WrappedDomain", "WrappedRange"}, "WrappedRange"}, + {{{"Wrap", "WrappedDomain", "WrappedRange"}}}}; +} + +static Signature domain_binary() { + return {{"Domain"}, {{"Domain", "Range"}, {"Domain", "Range"}}}; +} + +static Signature domain_binary_map() { + return {{"Domain", "Domain2"}, {{"Domain", "Range"}, {"Domain2", "Range"}}}; +} + +static Signature range() { + return {{"Range"}, {{"Domain", "Range"}}}; +} + +static Signature from_domain_and_range() { + return {{"Domain", "Range"}, {{"Domain"}, {"Range"}}}; +} + +static Signature from_range_and_domain() { + return {{"Domain2", "Domain"}, {{"Domain"}, {"Domain2"}}}; +} + +static Signature reverse() { + return {{"Range", "Domain"}, {{"Domain", "Range"}}}; +} + +static Signature test_map() { + return {{"Domain", "Domain"}, {{"Domain", "Domain"}, {"Domain", "Range2"}}}; +} + +static Signature range_product() { + return {{"Domain", {"Range", "Range3"}}, + {{"Domain", "Range"}, {"Domain", "Range3"}}}; +} + +static Signature flat_range_product() { + return {{"Domain", "Range2"}, {{"Domain", "Range"}, {"Domain", "Range3"}}}; +} + +static Signature curry() { + return {{"Domain2", {"Range2", "Range"}}, {{{"Domain2", "Range2"}, "Range"}}}; +} + +static Signature uncurry() { + return {{{"Domain", "Domain2"}, "Range2"}, + {{"Domain", {"Domain2", "Range2"}}}}; +} + +static Signature domain_factor_domain() { + return {{"Domain2", "Range"}, {{{"Domain2", "Range2"}, "Range"}}}; +} + +static Signature wrap() { + return {{{"Domain", "Range"}}, {{"Domain", "Range"}}}; +} + +static Signature wrap_binary() { + return {{{"Domain", "Range"}}, {{"Domain"}, {"Range"}}}; +} + +static Signature unwrap() { + return {{"MapDomain", "MapRange"}, {{{"MapDomain", "MapRange"}}}}; +} + +static Signature zip() { + return {{{"WrappedDomain1", "WrappedDomain2"}, + {"WrappedRange1", "WrappedRange2"}}, + {{{"WrappedDomain1", "WrappedRange1"}, + {"WrappedDomain2", "WrappedRange2"}}}}; +} + +static Signature get_map_anonymous() { + return {{"Domain", "Anonymous"}, {{"Domain", "Range"}}}; +} + +static Signature add_map_anonymous() { + return {{"Domain", "Range"}, {{"Domain", "Range"}, {"Domain", "Anonymous"}}}; +} + +static Signature add_range_anonymous() { + return {{"Domain", "Range"}, {{"Range"}, {"Domain", "Anonymous"}}}; +} + +static const std::unordered_map>> + signatures{ + {"add_param", {modify_params_unary(), modify_set_unary()}}, + {"align_params", {modify_set_params(), modify_map_params()}}, + {"apply", {apply_set(), apply_range()}}, + {"apply_domain", {apply_domain()}}, + {"preimage_domain", {preimage_domain()}}, + {"pullback", {preimage_domain()}}, + {"apply_range", {apply_range()}}, + {"coalesce", + {modify_params_unary(), modify_set_unary(), modify_map_unary()}}, + {"eq_at", {test_map()}}, + {"ge_set", {set_binary_params()}}, + {"get_space", + {modify_params_unary(), modify_set_unary(), modify_map_unary()}}, + {"gist", {modify_set_binary(), modify_map()}}, + {"intersect", + {modify_params_binary(), modify_set_binary(), modify_map()}}, + {"intersect_domain", {modify_domain()}}, + {"intersect_range", {modify_range()}}, + {"intersect_params", {modify_set_params(), modify_map_params()}}, + {"lt_set", {domain_binary()}}, + {"le_set", {domain_binary()}}, + {"eq_set", {domain_binary()}}, + {"lt_map", {domain_binary_map()}}, + {"gt_map", {domain_binary_map()}}, + {"params", {set_params(), map_params()}}, + {"from_params", {set_from_params()}}, + {"map_from_set", {map_from_set()}}, + {"add_named_tuple_id_ui", {set_from_params()}}, + {"add_unnamed_tuple_ui", {set_from_params(), map_from_domain()}}, + {"product", {wrap_binary()}}, + {"map_from_domain_and_range", {from_domain_and_range()}}, + {"domain", {domain()}}, + {"domain_map", {domain_map()}}, + {"range", {range()}}, + {"reverse", {reverse()}}, + {"subtract", {modify_set_binary(), modify_map()}}, + {"unbind_params_insert_domain", {from_range_and_domain()}}, + {"sum", {modify_map()}}, + {"unite", {modify_set_binary(), modify_map()}}, + {"union_add", {modify_map()}}, + {"range_product", {range_product()}}, + {"flat_range_product", {flat_range_product()}}, + {"curry", {curry()}}, + {"uncurry", {uncurry()}}, + {"domain_factor_domain", {domain_factor_domain()}}, + {"wrap", {wrap()}}, + {"unwrap", {unwrap()}}, + {"zip", {zip()}}, + {"add", {modify_set_binary(), modify_map()}}, + {"sub", {modify_set_binary(), modify_map()}}, + {"mul", {modify_set_binary()}}, + {"div", {modify_set_binary()}}, + {"mod", + {modify_set_binary(), + modify_map(), + modify_set_unary(), + modify_map_unary()}}, + {"get_at", {modify_set_unary(), modify_map_unary()}}, + {"get_map_list", {modify_map_unary()}}, + {"get_aff", {get_map_anonymous()}}, + {"set_aff", {add_map_anonymous()}}, + {"get_aff_list", {get_map_anonymous()}}, + {"get_union_pw_aff", {get_map_anonymous()}}, + {"set_union_pw_aff", {add_map_anonymous()}}, + {"get_union_pw_aff_list", {get_map_anonymous()}}, + {"pos_set", {set_params(), domain()}}, + {"nonneg_set", {set_params(), domain()}}, + {"zero_set", {set_params(), domain()}}, + {"zero_union_set", {set_params(), domain()}}, + {"add_constant", {modify_set_unary(), modify_map_unary()}}, + {"add_constant_si", {modify_set_unary(), modify_map_unary()}}, + {"set_val", {modify_set_unary()}}, + {"floor", {modify_map_unary()}}, + {"neg", {modify_set_unary(), modify_map_unary()}}, + {"drop", {modify_map_unary()}}, + {"scale", {modify_map_unary(), modify_range()}}, + {"scale_down", {modify_map_unary(), modify_range()}}, + {"set_set_tuple_id", {change_wrapped_set(), change_set()}}, + {"set_tuple_id", {change_wrapped_set(), change_set()}}, + {"set_range_tuple_id", {change_set(), change_range()}}, + {"get_range_stride_info", {get_map_anonymous()}}, + {"get_offset", {modify_map_unary()}}, + {"get_range_simple_fixed_box_hull", {modify_map_unary()}}, + {"set_may_source", {modify_map()}}, + {"set_schedule", {modify_map_unary()}}, + {"compute_flow", {modify_map_unary()}}, + {"get_may_dependence", {map_on_domain()}}, + }; + +static const std:: + map, std::vector>> + specificSignatures{ + {{"set", "identity"}, {map_from_set()}}, + {{"union_set", "get_space"}, {set_params()}}, + {{"union_map", "get_space"}, {set_params()}}, + {{"union_pw_aff", "get_space"}, {set_params()}}, + {{"union_pw_multi_aff", "get_space"}, {set_params()}}, + {{"union_set", "universe"}, {modify_set_unary()}}, + {{"union_map", "universe"}, {modify_map_unary()}}, + // should be called "gist_domain" + {{"multi_union_pw_aff", "gist"}, {modify_domain()}}, + {{"multi_union_pw_aff", "get_space"}, {range()}}, + {{"aff_list", "reverse"}, {modify_map_unary()}}, + {{"pw_aff_list", "reverse"}, {modify_map_unary()}}, + {{"union_pw_aff_list", "reverse"}, {modify_map_unary()}}, + {{"map_list", "reverse"}, {modify_map_unary()}}, + }; + +static const std::unordered_map>> + staticSignatures{ + {"from", {modify_map_unary()}}, + {"identity", {modify_map_unary()}}, + {"param_on_domain_space", {set_from_params()}}, + {"param_on_domain", {map_from_domain()}}, + {"empty", + {modify_params_unary(), modify_set_unary(), modify_map_unary()}}, + {"universe", + {modify_params_unary(), modify_set_unary(), modify_map_unary()}}, + {"zero", {modify_set_unary(), modify_map_unary()}}, + {"zero_on_domain", {map_from_domain()}}, + {"from_domain", {map_from_domain()}}, + }; + +static const std:: + map, std::vector>> + specificStaticSignatures{ + {{"multi_aff", "domain_map"}, {static_domain_map()}}, + {{"multi_aff", "range_map"}, {static_range_map()}}, + {{"multi_aff", "wrapped_range_map"}, {static_wrapped_range_map()}}, + {{"union_set", "empty"}, {set_from_params()}}, + {{"union_map", "empty"}, {map_from_params()}}, + }; + +struct Constructor { + std::vector argTypes; + std::vector> signatures; +}; + +static const std::unordered_map> + constructors{ + {"multi_id", {{{"space", "id_list"}, {modify_set_unary()}}}}, + {"multi_val", {{{"space", "val_list"}, {modify_set_unary()}}}}, + {"multi_aff", {{{"space", "aff_list"}, {add_map_anonymous()}}}}, + {"union_pw_aff", {{{"union_set", "val"}, {map_from_domain()}}}}, + {"multi_union_pw_aff", + {{{"space", "union_pw_aff_list"}, {add_range_anonymous()}}, + {{"union_set", "multi_val"}, {from_domain_and_range()}}}}, + {"map", {{{"multi_aff"}, {modify_map_unary()}}}}, + {"union_map", {{{"map"}, {modify_map_unary()}}}}, + {"union_set", {{{"set"}, {modify_set_unary()}}}}, + {"pw_aff", {{{"aff"}, {modify_set_unary(), modify_map_unary()}}}}, + {"aff_list", + {{{"aff"}, {modify_set_unary(), modify_map_unary()}}, + {{"ctx", "int"}, {create_set(), create_map()}}}}, + // should be replaced by constructor without int argument + {"space", {{{"ctx", "int"}, {create_params()}}}}, + {"union_pw_aff_list", {{{"ctx", "int"}, {create_set(), create_map()}}}}, + {"union_access_info", {{{"union_map"}, {modify_map_unary()}}}}, + }; + +static bool isForeach(const std::string& name) { + return name.find("foreach_") != std::string::npos; +} + +using Subs = std::map; + +static std::set +collect(const Kind& kind, const Subs& subs, std::set set = {}); + +static std::set collect( + const BaseKind& base, + const Subs& subs, + std::set set = {}) { + if (base.children.size() == 0) { + if (subs.count(base.name) != 0) { + set = collect(subs.at(base.name), {}, set); + } else if (base.name != "Anonymous") { + set.insert(base.name); + } + } else { + for (const auto& el : base.children) { + set = collect(el, subs, set); + } + } + return set; +} + +static std::set +collect(const Kind& kind, const Subs& subs, std::set set) { + for (auto base : kind) { + set = collect(base, subs, set); + } + return set; +} + +static std::set collect( + const Signature& signature, + const Subs& subs) { + auto set = collect(signature.returnType, subs); + for (auto arg : signature.argTypes) { + set = collect(arg, subs, set); + } + return set; +} + +static void printTemplateList( + const std::set set, + const std::string& qualifier) { + std::cout << "<"; + bool first = true; + for (auto s : set) { + if (!first) { + std::cout << ", "; + } + std::cout << qualifier << s; + first = false; + } + std::cout << ">"; +} + +static void +print(std::ostream& os, const BaseKind& base, const Subs& subs = {}); + +static void +print(std::ostream& os, const std::string& s, const Subs& subs = {}) { + if (subs.count(s) != 0) { + print(os, subs.at(s)); + } else { + os << s; + } +} + +static void print(std::ostream& os, const BaseKind& base, const Subs& subs) { + if (base.children.size() == 3) { + if (base.children[0] == "Anonymous") { + os << "Pair<"; + } else { + os << "NamedPair<"; + print(os, base.children[0], subs); + os << ","; + } + print(os, base.children[1], subs); + os << ","; + print(os, base.children[2], subs); + os << ">"; + } else { + print(os, base.name, subs); + } +} + +template +static void printTemplateList( + const std::vector list, + const std::string& qualifier, + const Subs& subs = {}) { + std::cout << "<"; + for (unsigned i = 0; i < list.size(); ++i) { + if (i > 0) { + std::cout << ", "; + } + std::cout << qualifier; + print(std::cout, list[i], subs); + } + std::cout << ">"; +} + +template +static void printTemplate(const T& t) { + std::cout << "template "; + printTemplateList(t, "typename "); + std::cout << "\n"; +} + +static void printClassDeclaration(const std::string& name, const Kind& kind) { + printTemplate(collect(kind, {})); + std::cout << "struct " << name; + printTemplateList(kind, ""); +} + +static void printForwardDeclarations() { + for (auto kvp : classes) { + std::cout << "\n"; + std::cout << "template \n"; + std::cout << "struct " << kvp.second.name; + std::cout << ";\n"; + } +} + +static BaseKind specialize(const BaseKind& base, const Subs& subs) { + if (base.children.size() == 0) { + if (subs.count(base.name) != 0) { + return subs.at(base.name); + } else { + return base; + } + } else { + return BaseKind{specialize(base.children[0], subs), + specialize(base.children[1], subs), + specialize(base.children[2], subs)}; + } +} + +static Kind specialize(const Kind& kind, const Subs& subs) { + if (subs.size() == 0) { + return kind; + } + Kind specialized; + for (auto base : kind) { + specialized.emplace_back(specialize(base, subs)); + } + return specialized; +} + +static std::vector specialize( + const std::vector& vector, + const Subs& subs) { + std::vector specialized; + for (auto kind : vector) { + specialized.emplace_back(specialize(kind, subs)); + } + return specialized; +} + +static Signature specialize( + const Signature& signature, + const Subs& subs) { + return {specialize(signature.returnType, subs), + specialize(signature.argTypes, subs)}; +} + +static void printExtraTemplate( + const Kind& classKind, + const Signature& signature, + const Subs& subs, + bool isStatic) { + auto classBase = collect(classKind, {}); + classBase.insert("Anonymous"); + auto signatureBase = collect(signature, subs); + std::vector extra; + for (auto base : signatureBase) { + if (classBase.count(base) == 0) { + extra.emplace_back(base); + } + } + if (extra.size() != 0) { + printTemplate(extra); + } +} + +static void +printType(const Type& type, const Kind& kind, const Subs& subs = {}) { + if (classes.count(type) == 0) { + std::cout << type; + } else { + const auto& returnType = classes.at(type); + std::cout << returnType.name; + printTemplateList(kind, "", subs); + } +} + +static void printReturnType( + const Signature& signature, + const Method& method, + const Subs& subs = {}) { + printType(method.signature.returnType, signature.returnType, subs); +} + +static Subs specializer( + const std::vector& dst, + const std::vector& src, + Subs subs = {}) { + for (size_t i = 0; i < src.size(); ++i) { + if (src[i].children.size() == 0) { + subs.emplace(src[i].name, dst[i]); + } else if (src[i].children.size() == dst[i].children.size()) { + subs = specializer(dst[i].children, src[i].children, subs); + } + } + return subs; +} + +static Signature specialize( + const Signature& signature, + const Kind& classKind) { + Subs subs = specializer(classKind, signature.argTypes[0]); + return specialize(signature, subs); +} + +static bool printMethod( + const std::string& base, + const Kind& classKind, + const Signature& signature, + const Method& method, + const Subs& subs, + bool isStatic = false) { + auto specializedSignature = + isStatic ? signature : specialize(signature, classKind); + const auto& match = isStatic ? specializedSignature.returnType + : specializedSignature.argTypes[0]; + auto specializedMatch = specialize(match, subs); + if (specializedMatch != classKind) { + return false; + } + printExtraTemplate(classKind, specializedSignature, subs, isStatic); + if (isStatic) { + std::cout << "static "; + } + std::cout << "inline "; + printReturnType(specializedSignature, method, subs); + std::cout << " "; + std::cout << method.name; + std::cout << "("; + size_t j = isStatic ? 0 : 1; + for (size_t i = 0; i < method.signature.argTypes.size(); ++i) { + if (i > 0) { + std::cout << ", "; + } + std::cout << "const "; + const Type& type = method.signature.argTypes[i]; + if (classes.count(type) == 0) { + std::cout << type; + } else { + printType(type, specializedSignature.argTypes[j++], subs); + } + std::cout << "& arg" << i; + } + std::cout << ")"; + if (!isStatic) { + std::cout << " const"; + } + std::cout << " {\n"; + std::cout << "auto res = "; + if (!isStatic) { + std::cout << "this->"; + } + std::cout << base << "::" << method.name << "("; + for (size_t i = 0; i < method.signature.argTypes.size(); ++i) { + if (i > 0) { + std::cout << ", "; + } + std::cout << "arg" << i; + } + std::cout << ");\n"; + std::cout << "return "; + printReturnType(specializedSignature, method, subs); + std::cout << "(res);\n"; + std::cout << "}\n"; + return true; +} + +static void printTo( + const Signature& signature, + const Method& method, + const Subs& subs) { + std::cout << "inline "; + printReturnType(signature, method, subs); + std::cout << " to" << classes.at(method.signature.returnType).name + << "() const {\n"; + std::cout << "return "; + printReturnType(signature, method, subs); + std::cout << "::from(*this);\n"; + std::cout << "}\n"; +} + +static void printAs( + const Signature& signature, + const Method& method, + const Subs& subs) { + std::cout << "inline "; + printReturnType(signature, method, subs); + std::cout << " as" << classes.at(method.signature.returnType).name + << "() const {\n"; + std::cout << "return "; + printReturnType(signature, method, subs); + std::cout << "(*this);\n"; + std::cout << "}\n"; +} + +static void printForeach( + const std::string& base, + const Kind& classKind, + const Method& method) { + const auto& fn = method.signature.argTypes[0]; + auto open = fn.find("("); + auto close = fn.find(")", open + 1); + if (close == std::string::npos) { + return; + } + auto argType = fn.substr(open + 1, close - (open + 1)); + if (classes.count(argType) == 0) { + return; + } + std::cout << "inline void " << method.name << "("; + std::cout << fn.substr(0, open + 1); + printType(argType, classKind); + std::cout << fn.substr(close); + std::cout << "& fn) const {\n"; + std::cout << "auto lambda = [fn](" << argType << " arg) -> void {\n"; + std::cout << "fn("; + printType(argType, classKind); + std::cout << "(arg));"; + std::cout << "};\n"; + std::cout << "this->" << base << "::" << method.name << "(lambda);\n"; + std::cout << "}\n"; +} + +static bool matches( + const Kind& classKind, + const Signature& signature, + const Method& method) { + if (signature.argTypes[0].size() != classKind.size()) { + return false; + } + size_t count = 0; + for (const auto& type : method.signature.argTypes) { + if (classes.count(type) != 0) { + ++count; + } + } + return signature.argTypes.size() == 1 + count; +} + +static void printMethods( + const std::string& base, + const Kind& classKind, + const std::vector& methods, + const Subs& subs) { + for (auto method : methods) { + if (specificSignatures.count({base, method.name}) != 0) { + for (const auto& signature : specificSignatures.at({base, method.name})) { + if (matches(classKind, signature, method)) { + printMethod(base, classKind, signature, method, subs); + } + } + } else if (specificStaticSignatures.count({base, method.name}) != 0) { + for (const auto& signature : + specificStaticSignatures.at({base, method.name})) { + if (signature.returnType.size() == classKind.size()) { + printMethod(base, classKind, signature, method, subs, true); + } + } + } else if (signatures.count(method.name) != 0) { + for (const auto& signature : signatures.at(method.name)) { + if (matches(classKind, signature, method)) { + if (printMethod(base, classKind, signature, method, subs)) { + break; + } + } + } + } else if (staticSignatures.count(method.name) != 0) { + for (const auto& signature : staticSignatures.at(method.name)) { + if (signature.returnType.size() == classKind.size()) { + printMethod(base, classKind, signature, method, subs, true); + } + } + } else if ( + method.name == "#to" && + classes.count(method.signature.returnType) == 1) { + for (auto returnKind : classes.at(method.signature.returnType).kinds) { + if (classKind.size() == 2 && returnKind.size() == 2) { + printTo(modify_map_unary(), method, subs); + } + } + } else if ( + method.name == "#as" && + classes.count(method.signature.returnType) == 1) { + for (auto returnKind : classes.at(method.signature.returnType).kinds) { + if (classKind.size() == returnKind.size()) { + for (const auto& constructor : + constructors.at(method.signature.returnType)) { + for (const auto& signature : constructor.signatures) { + if (constructor.argTypes[0] == base && + signature.returnType.size() == classKind.size()) { + printAs(signature, method, subs); + } + } + } + } + } + } else if (isForeach(method.name)) { + printForeach(base, classKind, method); + } + } +} + +static void printConstructor( + const std::string& base, + const std::string& className, + const Kind& classKind, + const std::vector& argTypes, + const Signature& signature, + const Subs& subs) { + std::cout << className << "("; + for (size_t i = 0; i < argTypes.size(); ++i) { + if (i > 0) { + std::cout << ", "; + } + std::cout << "const "; + printType(argTypes[i], signature.argTypes[i], subs); + std::cout << "& arg" << i; + } + std::cout << ") : " << base << "("; + for (size_t i = 0; i < argTypes.size(); ++i) { + if (i > 0) { + std::cout << ", "; + } + std::cout << "arg" << i; + } + std::cout << ") {}\n"; +} + +static void printOneDefinition( + const std::string& base, + const std::string& className, + const Kind& classKind, + const Exported& exported, + const Subs& subs) { + std::cout << "\n"; + printClassDeclaration(className, classKind); + std::cout << " : public " << base << " {\n"; + std::cout << className << "() = default;\n"; + std::cout << "explicit " << className << "(const " << base + << "& obj) : " << base << "(obj) {}\n"; + if (constructors.count(base) != 0) { + for (const auto& constructor : constructors.at(base)) { + for (const auto& signature : constructor.signatures) { + if (classKind.size() == signature.returnType.size()) { + printConstructor( + base, + className, + classKind, + constructor.argTypes, + signature, + subs); + } + } + } + } + if (exported.count(base) != 0) { + printMethods(base, classKind, exported.at(base), subs); + } + std::cout << "};\n"; +} + +static void printDefinition( + const std::string& base, + const std::string& className, + const Kind& classKind, + const Exported& exported) { + std::set kinds{classKind}; + if (exported.count(base) != 0) { + for (auto method : exported.at(base)) { + if (specificStaticSignatures.count({base, method.name}) != 0) { + for (const auto& signature : + specificStaticSignatures.at({base, method.name})) { + if (signature.returnType.size() == classKind.size() && + signature.returnType != classKind) { + kinds.emplace(signature.returnType); + } + } + } else if (signatures.count(method.name) != 0) { + for (const auto& signature : signatures.at(method.name)) { + if (matches(classKind, signature, method) && + signature.argTypes[0] != classKind) { + kinds.emplace(signature.argTypes[0]); + } + } + } + } + } + for (auto kind : kinds) { + Subs subs; + for (size_t i = 0; i < classKind.size(); ++i) { + if (classKind[i] != kind[i]) { + subs.emplace(classKind[i].name, kind[i]); + } + } + printOneDefinition(base, className, kind, exported, subs); + } +} + +static void printDefinitions(const Exported& exported) { + printDefinition("space", "Space", params_type(), exported); + printDefinition("set", "Set", params_type(), exported); + for (auto kvp : classes) { + for (auto kind : kvp.second.kinds) { + if (kind.size() == 0 && kvp.first != "space" && kvp.first != "set") { + printDefinition(kvp.first, kvp.second.name, kind, exported); + } + } + } + for (auto kvp : classes) { + for (auto kind : kvp.second.kinds) { + if (kind.size() != 0) { + printDefinition(kvp.first, kvp.second.name, kind, exported); + } + } + } +} + +static std::string extractArg(std::string arg) { + size_t start = 0; + constexpr auto constStr = "const "; + if (arg.find(constStr) != std::string::npos) { + start += strlen(constStr); + } + return dropIslNamespace(arg.substr(0, arg.find(" ", start))); +} + +static std::vector splitArgs(const std::string& args) { + std::vector list; + size_t pos, old = 0; + + while ((pos = args.find(", ", old)) != std::string::npos) { + list.emplace_back(extractArg(args.substr(old, pos))); + old = pos + 2; + } + if (args.length() > 0) { + list.emplace_back(extractArg(args.substr(old))); + } + return list; +} + +int main(int argc, char** argv) { + Exported exported; + for (std::string line; std::getline(std::cin, line);) { + std::regex declaration("^([a-z_:]+) (.*)::([a-z_]+)\\((.*)\\)(.*const)?$"); + std::smatch match; + if (!std::regex_match(line, match, declaration)) { + continue; + } + + auto retType = dropIslNamespace(match[1].str()); + auto className = dropIslNamespace(match[2].str()); + auto name = match[3].str(); + auto args = splitArgs(match[4].str()); + + if (name == "from" && args.size() == 1) { + exported[args[0]].emplace_back(Method{"#to", {retType, args}}); + } + if (signatures.count(name) == 0 && + specificSignatures.count({className, name}) == 0 && + staticSignatures.count(name) == 0 && + specificStaticSignatures.count({className, name}) == 0 && + !isForeach(name)) { + continue; + } + + exported[className].emplace_back(Method{name, {retType, args}}); + } + for (auto kvp : constructors) { + for (const auto& constructor : kvp.second) { + const auto& args = constructor.argTypes; + if (args.size() == 1) { + exported[args[0]].emplace_back(Method{"#as", {kvp.first, args}}); + } + } + } + + std::cout << header; + printForwardDeclarations(); + printDefinitions(exported); + std::cout << footer; + + return EXIT_SUCCESS; +} diff --git a/tc/external/detail/islpp.h b/tc/external/detail/islpp.h index 612957080..67dc450a4 100644 --- a/tc/external/detail/islpp.h +++ b/tc/external/detail/islpp.h @@ -252,6 +252,8 @@ struct UnionAsVector } }; +#include + struct IslIdIslHash { size_t operator()(const isl::id& id) const { return isl_id_get_hash(id.get()); From ddf9d550d1cb65ff79017ade151d8335f9475d35 Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Wed, 18 Jul 2018 15:29:20 +0200 Subject: [PATCH 020/102] inline extractDomainToIds This function will be templated on the mapping type and therefore needs to move to a header file. First move it in its original form to make it easier to see the differences later on. --- tc/core/polyhedral/schedule_utils-inl.h | 76 +++++++++++++++++++++++++ tc/core/polyhedral/schedule_utils.cc | 49 ---------------- tc/core/polyhedral/schedule_utils.h | 2 + 3 files changed, 78 insertions(+), 49 deletions(-) create mode 100644 tc/core/polyhedral/schedule_utils-inl.h diff --git a/tc/core/polyhedral/schedule_utils-inl.h b/tc/core/polyhedral/schedule_utils-inl.h new file mode 100644 index 000000000..e1adb7298 --- /dev/null +++ b/tc/core/polyhedral/schedule_utils-inl.h @@ -0,0 +1,76 @@ +/** + * Copyright (c) 2017-2018, Facebook, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#pragma once + +#include "tc/core/check.h" +#include "tc/core/polyhedral/schedule_tree.h" +#include "tc/core/polyhedral/schedule_tree_elem.h" +#include "tc/external/isl.h" + +namespace tc { +namespace polyhedral { + +/* + * Extract a mapping from the domain elements active at "tree" + * to identifiers "ids", where all branches in "tree" + * are assumed to have been mapped to these identifiers. + * The result lives in a space of the form "tupleId"["ids"...]. + */ +inline isl::multi_union_pw_aff extractDomainToIds( + const detail::ScheduleTree* root, + const detail::ScheduleTree* tree, + const std::vector& ids, + isl::id tupleId) { + using namespace polyhedral::detail; + + auto space = isl::space(tree->ctx_, 0); + auto empty = isl::union_set::empty(space); + space = space.add_named_tuple_id_ui(tupleId, ids.size()); + auto zero = isl::multi_val::zero(space); + auto domainToIds = isl::multi_union_pw_aff(empty, zero); + + for (auto mapping : tree->collect(tree, ScheduleTreeType::Mapping)) { + auto mappingNode = mapping->as(); + auto list = isl::union_pw_aff_list(tree->ctx_, ids.size()); + for (auto id : ids) { + if (mappingNode->mapping.count(id) == 0) { + break; + } + auto idMap = mappingNode->mapping.at(id); + list = list.add(idMap); + } + // Ignore this node if it does not map to all required ids. + if (static_cast(list.size()) != ids.size()) { + continue; + } + auto nodeToIds = isl::multi_union_pw_aff(space, list); + auto active = activeDomainPoints(root, mapping); + TC_CHECK(active.intersect(domainToIds.domain()).is_empty()) + << "conflicting mappings; are the filters in the tree disjoint?"; + nodeToIds = nodeToIds.intersect_domain(active); + domainToIds = domainToIds.union_add(nodeToIds); + } + + auto active = activeDomainPoints(root, tree); + TC_CHECK(active.is_subset(domainToIds.domain())) + << "not all domain points of\n" + << active << "\nwere mapped to the required ids"; + + return domainToIds; +} + +} // namespace polyhedral +} // namespace tc diff --git a/tc/core/polyhedral/schedule_utils.cc b/tc/core/polyhedral/schedule_utils.cc index 37a1a7d96..618a536f1 100644 --- a/tc/core/polyhedral/schedule_utils.cc +++ b/tc/core/polyhedral/schedule_utils.cc @@ -243,54 +243,5 @@ isl::multi_union_pw_aff partialScheduleMupa( return band ? prefix.flat_range_product(band->mupa_) : prefix; } -/* - * Extract a mapping from the domain elements active at "tree" - * to identifiers "ids", where all branches in "tree" - * are assumed to have been mapped to these identifiers. - * The result lives in a space of the form "tupleId"["ids"...]. - */ -isl::multi_union_pw_aff extractDomainToIds( - const detail::ScheduleTree* root, - const detail::ScheduleTree* tree, - const std::vector& ids, - isl::id tupleId) { - using namespace polyhedral::detail; - - auto space = isl::space(tree->ctx_, 0); - auto empty = isl::union_set::empty(space); - space = space.add_named_tuple_id_ui(tupleId, ids.size()); - auto zero = isl::multi_val::zero(space); - auto domainToIds = isl::multi_union_pw_aff(empty, zero); - - for (auto mapping : tree->collect(tree, ScheduleTreeType::Mapping)) { - auto mappingNode = mapping->as(); - auto list = isl::union_pw_aff_list(tree->ctx_, ids.size()); - for (auto id : ids) { - if (mappingNode->mapping.count(id) == 0) { - break; - } - auto idMap = mappingNode->mapping.at(id); - list = list.add(idMap); - } - // Ignore this node if it does not map to all required ids. - if (static_cast(list.size()) != ids.size()) { - continue; - } - auto nodeToIds = isl::multi_union_pw_aff(space, list); - auto active = activeDomainPoints(root, mapping); - TC_CHECK(active.intersect(domainToIds.domain()).is_empty()) - << "conflicting mappings; are the filters in the tree disjoint?"; - nodeToIds = nodeToIds.intersect_domain(active); - domainToIds = domainToIds.union_add(nodeToIds); - } - - auto active = activeDomainPoints(root, tree); - TC_CHECK(active.is_subset(domainToIds.domain())) - << "not all domain points of\n" - << active << "\nwere mapped to the required ids"; - - return domainToIds; -} - } // namespace polyhedral } // namespace tc diff --git a/tc/core/polyhedral/schedule_utils.h b/tc/core/polyhedral/schedule_utils.h index adca3decf..93bcff92d 100644 --- a/tc/core/polyhedral/schedule_utils.h +++ b/tc/core/polyhedral/schedule_utils.h @@ -140,3 +140,5 @@ bool isMappingTo(const detail::ScheduleTree* tree) { } // namespace polyhedral } // namespace tc + +#include "tc/core/polyhedral/schedule_utils-inl.h" From c56c67d7b116e77ca421024af57599014640040b Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Wed, 25 Jul 2018 12:26:49 +0200 Subject: [PATCH 021/102] inline isSingleReductionWithin This function will be templated on the prefix type and therefore needs to move to a header file. First move it in its original form to make it easier to see the differences later on. --- tc/core/polyhedral/reduction_matcher.cc | 11 ----------- tc/core/polyhedral/schedule_tree_matcher-inl.h | 11 +++++++++++ 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/tc/core/polyhedral/reduction_matcher.cc b/tc/core/polyhedral/reduction_matcher.cc index 8b21f4023..59aeaf13f 100644 --- a/tc/core/polyhedral/reduction_matcher.cc +++ b/tc/core/polyhedral/reduction_matcher.cc @@ -66,16 +66,5 @@ isl::union_set reductionUpdates(isl::union_set domain, const Scop& scop) { return update; } -bool isSingleReductionWithin( - isl::union_set domain, - isl::multi_union_pw_aff prefix, - const Scop& scop) { - auto reductions = scop.body.reductions; - reductions = reductions.intersect_domain(domain); - auto prefixMap = isl::union_map::from(prefix); - auto prefixToReduction = reductions.apply_domain(prefixMap); - return prefixToReduction.is_single_valued(); -} - } // namespace polyhedral } // namespace tc diff --git a/tc/core/polyhedral/schedule_tree_matcher-inl.h b/tc/core/polyhedral/schedule_tree_matcher-inl.h index 41a4ba434..8a2b2196c 100644 --- a/tc/core/polyhedral/schedule_tree_matcher-inl.h +++ b/tc/core/polyhedral/schedule_tree_matcher-inl.h @@ -291,5 +291,16 @@ inline std::vector match( return matchDFSPreorder(matcher, tree); } +inline bool isSingleReductionWithin( + isl::union_set domain, + isl::multi_union_pw_aff prefix, + const Scop& scop) { + auto reductions = scop.body.reductions; + reductions = reductions.intersect_domain(domain); + auto prefixMap = isl::union_map::from(prefix); + auto prefixToReduction = reductions.apply_domain(prefixMap); + return prefixToReduction.is_single_valued(); +} + } // namespace polyhedral } // namespace tc From 608dc2ee4a47c8e0473ffabd4c3258170dea2f00 Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Wed, 25 Jul 2018 16:29:04 +0200 Subject: [PATCH 022/102] inline ScheduleTreeBand::memberRange This function will be templated on the target type and therefore needs to move to a header file. First move it in its original form to make it easier to see the differences later on. --- tc/core/polyhedral/schedule_tree_elem.cc | 11 ----------- tc/core/polyhedral/schedule_tree_elem.h | 10 +++++++++- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/tc/core/polyhedral/schedule_tree_elem.cc b/tc/core/polyhedral/schedule_tree_elem.cc index 442d805ab..9cee3ecac 100644 --- a/tc/core/polyhedral/schedule_tree_elem.cc +++ b/tc/core/polyhedral/schedule_tree_elem.cc @@ -250,17 +250,6 @@ void ScheduleTreeBand::drop(size_t pos, size_t n) { TC_CHECK_EQ(nBegin - n, nMember()); } -isl::multi_union_pw_aff ScheduleTreeBand::memberRange(size_t first, size_t n) - const { - auto list = mupa_.get_union_pw_aff_list(); - auto space = mupa_.get_space().params().add_unnamed_tuple_ui(n); - auto end = first + n; - TC_CHECK_LE(end, nMember()); - list = list.drop(end, nMember() - end); - list = list.drop(0, first); - return isl::multi_union_pw_aff(space, list); -} - std::unique_ptr ScheduleTreeThreadSpecificMarker::make( isl::ctx ctx, diff --git a/tc/core/polyhedral/schedule_tree_elem.h b/tc/core/polyhedral/schedule_tree_elem.h index 5d782049d..91cc61444 100644 --- a/tc/core/polyhedral/schedule_tree_elem.h +++ b/tc/core/polyhedral/schedule_tree_elem.h @@ -331,7 +331,15 @@ struct ScheduleTreeBand : public ScheduleTree { // Extract the range of "n" members starting at "first" // (in an anonymous space). - isl::multi_union_pw_aff memberRange(size_t first, size_t n) const; + isl::multi_union_pw_aff memberRange(size_t first, size_t n) const { + auto list = mupa_.get_union_pw_aff_list(); + auto space = mupa_.get_space().params().add_unnamed_tuple_ui(n); + auto end = first + n; + TC_CHECK_LE(end, nMember()); + list = list.drop(end, nMember() - end); + list = list.drop(0, first); + return isl::multi_union_pw_aff(space, list); + } public: bool permutable_{false}; From a191681040f1817e376d21a3da998bca71702c45 Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Wed, 1 Aug 2018 09:36:16 +0200 Subject: [PATCH 023/102] inline partialScheduleMupa This function will be templated on the schedule type and therefore needs to move to a header file. First move it in its original form (with an extra "using") to make it easier to see the differences later on. --- tc/core/polyhedral/schedule_utils-inl.h | 10 ++++++++++ tc/core/polyhedral/schedule_utils.cc | 8 -------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/tc/core/polyhedral/schedule_utils-inl.h b/tc/core/polyhedral/schedule_utils-inl.h index e1adb7298..a50a50346 100644 --- a/tc/core/polyhedral/schedule_utils-inl.h +++ b/tc/core/polyhedral/schedule_utils-inl.h @@ -23,6 +23,16 @@ namespace tc { namespace polyhedral { +inline isl::multi_union_pw_aff partialScheduleMupa( + const detail::ScheduleTree* root, + const detail::ScheduleTree* tree) { + using namespace polyhedral::detail; + + auto prefix = prefixScheduleMupa(root, tree); + auto band = tree->as(); + return band ? prefix.flat_range_product(band->mupa_) : prefix; +} + /* * Extract a mapping from the domain elements active at "tree" * to identifiers "ids", where all branches in "tree" diff --git a/tc/core/polyhedral/schedule_utils.cc b/tc/core/polyhedral/schedule_utils.cc index 618a536f1..82ec9fac0 100644 --- a/tc/core/polyhedral/schedule_utils.cc +++ b/tc/core/polyhedral/schedule_utils.cc @@ -235,13 +235,5 @@ isl::multi_union_pw_aff prefixScheduleMupa( return infixScheduleMupa(root, root, tree); } -isl::multi_union_pw_aff partialScheduleMupa( - const detail::ScheduleTree* root, - const detail::ScheduleTree* tree) { - auto prefix = prefixScheduleMupa(root, tree); - auto band = tree->as(); - return band ? prefix.flat_range_product(band->mupa_) : prefix; -} - } // namespace polyhedral } // namespace tc From fd8c91f9a0df4056702b41a43f63988ec498dc62 Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Wed, 1 Aug 2018 09:39:13 +0200 Subject: [PATCH 024/102] inline prefixScheduleMupa This function will be templated on the schedule type and therefore needs to move to a header file. First move it in its original form to make it easier to see the differences later on. --- tc/core/polyhedral/schedule_utils-inl.h | 6 ++++++ tc/core/polyhedral/schedule_utils.cc | 6 ------ 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tc/core/polyhedral/schedule_utils-inl.h b/tc/core/polyhedral/schedule_utils-inl.h index a50a50346..1f4bd7b22 100644 --- a/tc/core/polyhedral/schedule_utils-inl.h +++ b/tc/core/polyhedral/schedule_utils-inl.h @@ -23,6 +23,12 @@ namespace tc { namespace polyhedral { +inline isl::multi_union_pw_aff prefixScheduleMupa( + const detail::ScheduleTree* root, + const detail::ScheduleTree* tree) { + return infixScheduleMupa(root, root, tree); +} + inline isl::multi_union_pw_aff partialScheduleMupa( const detail::ScheduleTree* root, const detail::ScheduleTree* tree) { diff --git a/tc/core/polyhedral/schedule_utils.cc b/tc/core/polyhedral/schedule_utils.cc index 82ec9fac0..fb5f38d1d 100644 --- a/tc/core/polyhedral/schedule_utils.cc +++ b/tc/core/polyhedral/schedule_utils.cc @@ -229,11 +229,5 @@ isl::multi_union_pw_aff infixScheduleMupa( return prefix; } -isl::multi_union_pw_aff prefixScheduleMupa( - const ScheduleTree* root, - const ScheduleTree* tree) { - return infixScheduleMupa(root, root, tree); -} - } // namespace polyhedral } // namespace tc From 8e51befbf04b4f6785828215c338efa32bb24123 Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Wed, 1 Aug 2018 09:44:30 +0200 Subject: [PATCH 025/102] inline infixScheduleMupa This function will be templated on the schedule type and therefore needs to move to a header file. First move it in its original form (with an extra "using") to make it easier to see the differences later on. --- tc/core/polyhedral/schedule_utils-inl.h | 49 +++++++++++++++++++++++++ tc/core/polyhedral/schedule_utils.cc | 43 ---------------------- 2 files changed, 49 insertions(+), 43 deletions(-) diff --git a/tc/core/polyhedral/schedule_utils-inl.h b/tc/core/polyhedral/schedule_utils-inl.h index 1f4bd7b22..0e6305799 100644 --- a/tc/core/polyhedral/schedule_utils-inl.h +++ b/tc/core/polyhedral/schedule_utils-inl.h @@ -15,6 +15,8 @@ */ #pragma once +#include + #include "tc/core/check.h" #include "tc/core/polyhedral/schedule_tree.h" #include "tc/core/polyhedral/schedule_tree_elem.h" @@ -23,6 +25,53 @@ namespace tc { namespace polyhedral { +namespace detail { + +template +inline std::vector filterType( + const std::vector& vec) { + std::vector result; + for (auto e : vec) { + if (e->as()) { + result.push_back(e); + } + } + return result; +} + +template +inline T +foldl(const std::vector vec, Func op, T init = T()) { + T value = init; + for (auto st : vec) { + value = op(st, value); + } + return value; +} + +} // namespace detail + +inline isl::multi_union_pw_aff infixScheduleMupa( + const detail::ScheduleTree* root, + const detail::ScheduleTree* relativeRoot, + const detail::ScheduleTree* tree) { + using namespace polyhedral::detail; + + auto domainElem = root->as(); + TC_CHECK(domainElem); + auto domain = domainElem->domain_.universe(); + auto zero = isl::multi_val::zero(domain.get_space().set_from_params()); + auto prefix = isl::multi_union_pw_aff(domain, zero); + prefix = foldl( + filterType(tree->ancestors(relativeRoot)), + [](const ScheduleTree* st, isl::multi_union_pw_aff pref) { + auto mupa = st->as()->mupa_; + return pref.flat_range_product(mupa); + }, + prefix); + return prefix; +} + inline isl::multi_union_pw_aff prefixScheduleMupa( const detail::ScheduleTree* root, const detail::ScheduleTree* tree) { diff --git a/tc/core/polyhedral/schedule_utils.cc b/tc/core/polyhedral/schedule_utils.cc index fb5f38d1d..1f82bfaab 100644 --- a/tc/core/polyhedral/schedule_utils.cc +++ b/tc/core/polyhedral/schedule_utils.cc @@ -186,48 +186,5 @@ vector collectScheduleTreesPath( return res; } -namespace { - -template -vector filterType(const vector& vec) { - vector result; - for (auto e : vec) { - if (e->as()) { - result.push_back(e); - } - } - return result; -} - -template -T foldl(const vector vec, Func op, T init = T()) { - T value = init; - for (auto st : vec) { - value = op(st, value); - } - return value; -} - -} // namespace - -isl::multi_union_pw_aff infixScheduleMupa( - const ScheduleTree* root, - const ScheduleTree* relativeRoot, - const ScheduleTree* tree) { - auto domainElem = root->as(); - TC_CHECK(domainElem); - auto domain = domainElem->domain_.universe(); - auto zero = isl::multi_val::zero(domain.get_space().set_from_params()); - auto prefix = isl::multi_union_pw_aff(domain, zero); - prefix = foldl( - filterType(tree->ancestors(relativeRoot)), - [](const ScheduleTree* st, isl::multi_union_pw_aff pref) { - auto mupa = st->as()->mupa_; - return pref.flat_range_product(mupa); - }, - prefix); - return prefix; -} - } // namespace polyhedral } // namespace tc From 6074215b2cb5678cc41dc088689e3d5e1f350bec Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Wed, 1 Aug 2018 10:47:55 +0200 Subject: [PATCH 026/102] inline prefixSchedule and partialSchedule These functions will be templated on the schedule type and therefore need to move to a header file. First move them in their original form to make it easier to see the differences later on. --- tc/core/polyhedral/schedule_utils-inl.h | 36 +++++++++++++++++++++++++ tc/core/polyhedral/schedule_utils.cc | 36 ------------------------- 2 files changed, 36 insertions(+), 36 deletions(-) diff --git a/tc/core/polyhedral/schedule_utils-inl.h b/tc/core/polyhedral/schedule_utils-inl.h index 0e6305799..1be023d59 100644 --- a/tc/core/polyhedral/schedule_utils-inl.h +++ b/tc/core/polyhedral/schedule_utils-inl.h @@ -25,6 +25,42 @@ namespace tc { namespace polyhedral { +namespace detail { +inline isl::union_map partialScheduleImpl( + const ScheduleTree* root, + const ScheduleTree* node, + bool useNode) { + auto nodes = node->ancestors(root); + if (useNode) { + nodes.push_back(node); + } + TC_CHECK_GT(nodes.size(), 0u) << "root node does not have a prefix schedule"; + auto domain = root->as(); + TC_CHECK(domain); + auto schedule = isl::union_map::from_domain(domain->domain_); + for (auto anc : nodes) { + if (anc->as()) { + TC_CHECK(anc == root); + } else { + schedule = extendSchedule(anc, schedule); + } + } + return schedule; +} +} // namespace detail + +inline isl::union_map prefixSchedule( + const detail::ScheduleTree* root, + const detail::ScheduleTree* node) { + return detail::partialScheduleImpl(root, node, false); +} + +inline isl::union_map partialSchedule( + const detail::ScheduleTree* root, + const detail::ScheduleTree* node) { + return detail::partialScheduleImpl(root, node, true); +} + namespace detail { template diff --git a/tc/core/polyhedral/schedule_utils.cc b/tc/core/polyhedral/schedule_utils.cc index 1f82bfaab..4622bf45c 100644 --- a/tc/core/polyhedral/schedule_utils.cc +++ b/tc/core/polyhedral/schedule_utils.cc @@ -49,42 +49,6 @@ isl::union_map extendSchedule( return schedule; } -namespace { -isl::union_map partialScheduleImpl( - const ScheduleTree* root, - const ScheduleTree* node, - bool useNode) { - auto nodes = node->ancestors(root); - if (useNode) { - nodes.push_back(node); - } - TC_CHECK_GT(nodes.size(), 0u) << "root node does not have a prefix schedule"; - auto domain = root->as(); - TC_CHECK(domain); - auto schedule = isl::union_map::from_domain(domain->domain_); - for (auto anc : nodes) { - if (anc->as()) { - TC_CHECK(anc == root); - } else { - schedule = extendSchedule(anc, schedule); - } - } - return schedule; -} -} // namespace - -isl::union_map prefixSchedule( - const ScheduleTree* root, - const ScheduleTree* node) { - return partialScheduleImpl(root, node, false); -} - -isl::union_map partialSchedule( - const ScheduleTree* root, - const ScheduleTree* node) { - return partialScheduleImpl(root, node, true); -} - namespace { /* * If "node" is any filter, then intersect "domain" with that filter. From d4c18a96b80ef8919e4be8e29bc9bbc67a16de45 Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Thu, 2 Aug 2018 10:39:36 +0200 Subject: [PATCH 027/102] inline extendSchedule This function will be templated on the schedule type and therefore needs to move to a header file. First move it in its original form (with an extra "using") to make it easier to see the differences later on. --- tc/core/polyhedral/schedule_utils-inl.h | 23 +++++++++++++++++++++++ tc/core/polyhedral/schedule_utils.cc | 21 --------------------- 2 files changed, 23 insertions(+), 21 deletions(-) diff --git a/tc/core/polyhedral/schedule_utils-inl.h b/tc/core/polyhedral/schedule_utils-inl.h index 1be023d59..3c6be4645 100644 --- a/tc/core/polyhedral/schedule_utils-inl.h +++ b/tc/core/polyhedral/schedule_utils-inl.h @@ -25,6 +25,29 @@ namespace tc { namespace polyhedral { +inline isl::union_map extendSchedule( + const detail::ScheduleTree* node, + isl::union_map schedule) { + using namespace polyhedral::detail; + + if (auto bandElem = node->as()) { + if (bandElem->nMember() > 0) { + schedule = + schedule.flat_range_product(isl::union_map::from(bandElem->mupa_)); + } + } else if (auto filterElem = node->as()) { + schedule = schedule.intersect_domain(filterElem->filter_); + } else if (auto extensionElem = node->as()) { + // FIXME: we may need to restrict the range of reversed extension map to + // schedule values that correspond to active domain elements at this + // point. + schedule = schedule.unite( + extensionElem->extension_.reverse().intersect_range(schedule.range())); + } + + return schedule; +} + namespace detail { inline isl::union_map partialScheduleImpl( const ScheduleTree* root, diff --git a/tc/core/polyhedral/schedule_utils.cc b/tc/core/polyhedral/schedule_utils.cc index 4622bf45c..1b5da0dfe 100644 --- a/tc/core/polyhedral/schedule_utils.cc +++ b/tc/core/polyhedral/schedule_utils.cc @@ -28,27 +28,6 @@ using namespace detail; using std::ostream; using std::vector; -isl::union_map extendSchedule( - const ScheduleTree* node, - isl::union_map schedule) { - if (auto bandElem = node->as()) { - if (bandElem->nMember() > 0) { - schedule = - schedule.flat_range_product(isl::union_map::from(bandElem->mupa_)); - } - } else if (auto filterElem = node->as()) { - schedule = schedule.intersect_domain(filterElem->filter_); - } else if (auto extensionElem = node->as()) { - // FIXME: we may need to restrict the range of reversed extension map to - // schedule values that correspond to active domain elements at this - // point. - schedule = schedule.unite( - extensionElem->extension_.reverse().intersect_range(schedule.range())); - } - - return schedule; -} - namespace { /* * If "node" is any filter, then intersect "domain" with that filter. From 723df7270d934e2923e3955fe0af01f37a3f972e Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Thu, 21 Jun 2018 12:05:24 +0200 Subject: [PATCH 028/102] halide2isl.cc: extractAccess: explicitly cast space to isl::Space<> This will make it easier to gradually introduce the use of templated isl types by breaking a cycle. The explicit cast will be removed again after the core halide2isl has been converted to templated isl types. --- tc/core/halide2isl.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tc/core/halide2isl.cc b/tc/core/halide2isl.cc index cb46434ba..e166141ba 100644 --- a/tc/core/halide2isl.cc +++ b/tc/core/halide2isl.cc @@ -258,7 +258,7 @@ isl::map extractAccess( // to the outer loop iterators) and then convert this set // into a map in terms of the iteration domain. - isl::space paramSpace = domain.paramSpace; + auto paramSpace = isl::Space<>(domain.paramSpace); isl::id tensorID(paramSpace.get_ctx(), tensor); auto tensorTuple = constructTensorTuple(paramSpace, tensorID, args.size()); auto tensorSpace = tensorTuple.get_space(); From 9377e791017a69598ede01a43a979520524ebb37 Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Thu, 21 Jun 2018 12:05:24 +0200 Subject: [PATCH 029/102] memory_promotion.cc: tensorElementsSet: explicitly cast space to isl::Space<> This will make it easier to gradually introduce the use of templated isl types by breaking a cycle. The explicit cast will be removed again after Scop::Domain() has been converted to templated isl types. --- tc/core/polyhedral/memory_promotion.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tc/core/polyhedral/memory_promotion.cc b/tc/core/polyhedral/memory_promotion.cc index 37656f09a..324dc6efd 100644 --- a/tc/core/polyhedral/memory_promotion.cc +++ b/tc/core/polyhedral/memory_promotion.cc @@ -410,7 +410,7 @@ namespace { // context of the scop. isl::set tensorElementsSet(const Scop& scop, isl::id tensorId) { auto halideParameter = scop.findArgument(tensorId).parameter(); - auto space = scop.domain().get_space(); + auto space = isl::Space<>(scop.domain().get_space()); auto nDim = halideParameter.dimensions(); auto tensorTuple = constructTensorTuple(space, tensorId, nDim); auto tensorSpace = tensorTuple.get_space(); From 818355581ce2007aced08f534ec6a4450295638b Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Thu, 21 Jun 2018 12:05:24 +0200 Subject: [PATCH 030/102] constructTensorTuple: use templated isl types --- tc/core/polyhedral/domain_types.h | 7 +++++++ tc/core/polyhedral/utils.cc | 10 ++++++---- tc/core/polyhedral/utils.h | 5 +++-- 3 files changed, 16 insertions(+), 6 deletions(-) create mode 100644 tc/core/polyhedral/domain_types.h diff --git a/tc/core/polyhedral/domain_types.h b/tc/core/polyhedral/domain_types.h new file mode 100644 index 000000000..ed15b2fcb --- /dev/null +++ b/tc/core/polyhedral/domain_types.h @@ -0,0 +1,7 @@ +namespace tc { +namespace polyhedral { + +struct Tensor; + +} // namespace polyhedral +} // namespace tc diff --git a/tc/core/polyhedral/utils.cc b/tc/core/polyhedral/utils.cc index 80cf11f78..07e1b83ee 100644 --- a/tc/core/polyhedral/utils.cc +++ b/tc/core/polyhedral/utils.cc @@ -15,6 +15,8 @@ */ #include "tc/core/polyhedral/utils.h" +#include "tc/core/polyhedral/domain_types.h" + namespace tc { namespace polyhedral { @@ -24,15 +26,15 @@ namespace polyhedral { * of the user. * Since some names are required, use names of the form "__tc_tensor_arg*". */ -isl::multi_id -constructTensorTuple(isl::space paramSpace, isl::id tensorId, size_t dim) { - auto tensorSpace = paramSpace.add_named_tuple_id_ui(tensorId, dim); +isl::MultiId +constructTensorTuple(isl::Space<> paramSpace, isl::id tensorId, size_t dim) { + auto tensorSpace = paramSpace.add_named_tuple_id_ui(tensorId, dim); isl::id_list tensorArgs(paramSpace.get_ctx(), 0); for (size_t i = 0; i < dim; ++i) { auto name = std::string("__tc_tensor_arg") + std::to_string(i); tensorArgs = tensorArgs.add(isl::id(paramSpace.get_ctx(), name)); } - return isl::multi_id(tensorSpace, tensorArgs); + return isl::MultiId(tensorSpace, tensorArgs); } } // namespace polyhedral diff --git a/tc/core/polyhedral/utils.h b/tc/core/polyhedral/utils.h index 459bca648..31512f9f3 100644 --- a/tc/core/polyhedral/utils.h +++ b/tc/core/polyhedral/utils.h @@ -15,6 +15,7 @@ */ #pragma once +#include "tc/core/polyhedral/domain_types.h" #include "tc/external/isl.h" namespace tc { @@ -24,8 +25,8 @@ namespace polyhedral { * dimension "dim" from the parameter space "paramSpace", * without any specific names for the indices. */ -isl::multi_id -constructTensorTuple(isl::space paramSpace, isl::id tensorId, size_t dim); +isl::MultiId +constructTensorTuple(isl::Space<> paramSpace, isl::id tensorId, size_t dim); } // namespace polyhedral } // namespace tc From 8a9e8f8e293c01d827203704516e422646330c0d Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Thu, 21 Jun 2018 12:05:24 +0200 Subject: [PATCH 031/102] Scop::makeContext: explicitly cast space to isl::Space<> This will make it easier to gradually introduce the use of templated isl types by breaking a cycle. The explicit cast will be removed again after Scop::Domain() has been converted to templated isl types. --- tc/core/polyhedral/scop.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tc/core/polyhedral/scop.h b/tc/core/polyhedral/scop.h index 796974d9f..a05bbe7d2 100644 --- a/tc/core/polyhedral/scop.h +++ b/tc/core/polyhedral/scop.h @@ -134,7 +134,7 @@ struct Scop { isl::set makeContext( const std::unordered_map& sizes = std::unordered_map()) const { - auto s = domain().get_space(); + auto s = isl::Space<>(domain().get_space()); return makeSpecializationSet(s, sizes); } From f815eaa669f4acf3643d6c4a93c5fe612c5564be Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Thu, 21 Jun 2018 12:05:24 +0200 Subject: [PATCH 032/102] makeSpecializationSet: use templated isl types Use explicit API calls instead of operators because the use of aff_set is confusing (at least to the author of this commit). The conversion to an isl::PwAff is needed because, unlike the Python bindings, the C++ bindings do not have a class hierarchy. The conversion could also be avoided by introducing an isl_aff_zero_set in isl. --- tc/external/detail/islpp.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tc/external/detail/islpp.h b/tc/external/detail/islpp.h index 67dc450a4..1d730d6b7 100644 --- a/tc/external/detail/islpp.h +++ b/tc/external/detail/islpp.h @@ -310,18 +310,18 @@ inline isl::set makeParameterContext( // that ties the space parameter to the values. // template -inline isl::set makeSpecializationSet( - isl::space space, +inline isl::Set<> makeSpecializationSet( + isl::Space<> space, const std::unordered_map& paramValues) { auto ctx = space.get_ctx(); for (auto kvp : paramValues) { space = space.add_param(isl::id(ctx, kvp.first)); } - auto set = isl::set::universe(space); + auto set = isl::Set<>::universe(space); for (auto kvp : paramValues) { auto id = isl::id(ctx, kvp.first); - isl::aff affParam(isl::aff::param_on_domain_space(space, id)); - set = set & (isl::aff_set(affParam) == kvp.second); + auto affParam(isl::AffOn<>::param_on_domain_space(space, id)); + set = set & (affParam - kvp.second).asPwAff().zero_set(); } return set; } From 235197154d7fa1a6a4d308e08e11a669b365fa5c Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Thu, 21 Jun 2018 12:05:24 +0200 Subject: [PATCH 033/102] Scop::makeContext: use templated isl types --- tc/core/polyhedral/scop.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tc/core/polyhedral/scop.h b/tc/core/polyhedral/scop.h index a05bbe7d2..d1eedc6f4 100644 --- a/tc/core/polyhedral/scop.h +++ b/tc/core/polyhedral/scop.h @@ -131,7 +131,7 @@ struct Scop { // Returns a set that specializes the named scop's subset of // parameter space to the integer values passed to the function. template - isl::set makeContext( + isl::Set<> makeContext( const std::unordered_map& sizes = std::unordered_map()) const { auto s = isl::Space<>(domain().get_space()); From 14359e4b9e2e72b3e157ec6a07d8a84f7b8cfb8c Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Thu, 21 Jun 2018 12:05:24 +0200 Subject: [PATCH 034/102] Scop::context(): use templated isl types --- tc/core/polyhedral/cuda/mapped_scop.cc | 3 ++- tc/core/polyhedral/domain_types.h | 1 + tc/core/polyhedral/scop.h | 4 ++-- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/tc/core/polyhedral/cuda/mapped_scop.cc b/tc/core/polyhedral/cuda/mapped_scop.cc index 930c92aa3..eb555d94f 100644 --- a/tc/core/polyhedral/cuda/mapped_scop.cc +++ b/tc/core/polyhedral/cuda/mapped_scop.cc @@ -32,6 +32,7 @@ #include "tc/core/polyhedral/cuda/mapping_types.h" #include "tc/core/polyhedral/cuda/memory_promotion_heuristic.h" #include "tc/core/polyhedral/cuda/tighten_launch_bounds.h" +#include "tc/core/polyhedral/domain_types.h" #include "tc/core/polyhedral/exceptions.h" #include "tc/core/polyhedral/schedule_transforms.h" #include "tc/core/polyhedral/schedule_tree_matcher.h" @@ -895,7 +896,7 @@ std::unique_ptr makeSpecializedMappedScop( // outer schedule dimensions, so the space of a parameter context code is that // of a zero-dimensional space. auto root = scop->scheduleRoot(); - updateTopLevelContext(root, scop->context().from_params()); + updateTopLevelContext(root, scop->context().from_params()); tc::Grid grid = mappedScop.numBlocks; tc::Block block = mappedScop.numThreads; diff --git a/tc/core/polyhedral/domain_types.h b/tc/core/polyhedral/domain_types.h index ed15b2fcb..96b740bd2 100644 --- a/tc/core/polyhedral/domain_types.h +++ b/tc/core/polyhedral/domain_types.h @@ -1,6 +1,7 @@ namespace tc { namespace polyhedral { +struct Prefix; struct Tensor; } // namespace polyhedral diff --git a/tc/core/polyhedral/scop.h b/tc/core/polyhedral/scop.h index d1eedc6f4..c91863308 100644 --- a/tc/core/polyhedral/scop.h +++ b/tc/core/polyhedral/scop.h @@ -92,10 +92,10 @@ struct Scop { // The schedule tree of the scop does not necessarily have // a context node. Call updateTopLevelContext on the schedule tree // to introduce or refine such a context node. - isl::set context() const { + isl::Set<> context() const { auto ctx = domain().get_ctx(); auto context = halide2isl::makeParamContext(ctx, halide.params); - return context.intersect(makeContext(parameterValues)); + return isl::Set<>(context.intersect(makeContext(parameterValues))); } // Specialize a Scop by fixing the given parameters to the given sizes. From 9b532d619f864dafdd71492cf36b0b2fd0909c9b Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Thu, 21 Jun 2018 12:05:24 +0200 Subject: [PATCH 035/102] codegen_llvm.cc: getTensorSize: use templated isl types --- tc/core/polyhedral/codegen_llvm.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tc/core/polyhedral/codegen_llvm.cc b/tc/core/polyhedral/codegen_llvm.cc index c87289d1f..2942b7ff7 100644 --- a/tc/core/polyhedral/codegen_llvm.cc +++ b/tc/core/polyhedral/codegen_llvm.cc @@ -70,7 +70,7 @@ int64_t toSInt(isl::val v) { return v.get_num_si(); } -int64_t getTensorSize(isl::set context, const Halide::Expr& e) { +int64_t getTensorSize(isl::Set<> context, const Halide::Expr& e) { // isl will take care of substituting parameter values if they are known and // simplifying the expression. auto aff = halide2isl::makeIslAffFromExpr(context.get_space(), e); @@ -81,7 +81,7 @@ int64_t getTensorSize(isl::set context, const Halide::Expr& e) { std::vector getTensorSizesWithoutLeadingDim( const Halide::OutputImageParam& t, - isl::set context) { + isl::Set<> context) { auto dims = t.dimensions(); std::vector sizes; sizes.reserve(dims); From e5dad4fd40d243c65b2f84e10d52bd3eaa82673a Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Wed, 25 Jul 2018 09:52:11 +0200 Subject: [PATCH 036/102] memory_promotion.cc: tensorElementsSet: temporarily remove type deduction This allows halide2isl::makeIslAffFromExpr to be converted to templated isl types without having to convert tensorElementsSet at the same time. Automatic type deduction will be reintroduced when tensorElementsSet is converted. --- tc/core/polyhedral/memory_promotion.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tc/core/polyhedral/memory_promotion.cc b/tc/core/polyhedral/memory_promotion.cc index 324dc6efd..1cacd0e7b 100644 --- a/tc/core/polyhedral/memory_promotion.cc +++ b/tc/core/polyhedral/memory_promotion.cc @@ -418,9 +418,9 @@ isl::set tensorElementsSet(const Scop& scop, isl::id tensorId) { auto tensorElements = isl::set::universe(tensorSpace); auto identity = isl::multi_aff::identity(tensorSpace.map_from_set()); for (int i = 0; i < nDim; ++i) { - auto minAff = halide2isl::makeIslAffFromExpr( + isl::aff minAff = halide2isl::makeIslAffFromExpr( space, halideParameter.min_constraint(i)); - auto extentAff = halide2isl::makeIslAffFromExpr( + isl::aff extentAff = halide2isl::makeIslAffFromExpr( space, halideParameter.extent_constraint(i)); minAff = minAff.unbind_params_insert_domain(tensorTuple); extentAff = extentAff.unbind_params_insert_domain(tensorTuple); From 9186ed08178f0cd40d1a11df6c2f938762bb07ea Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Wed, 25 Jul 2018 09:52:18 +0200 Subject: [PATCH 037/102] Scop::makeIslAffFromStmtExpr: temporarily remove type deduction This allows halide2isl::makeIslAffFromExpr to be converted to templated isl types without having to convert Scop::makeIslAffFromStmtExpr at the same time. Automatic type deduction will be reintroduced when Scop::makeIslAffFromStmtExpr is converted. --- tc/core/polyhedral/scop.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tc/core/polyhedral/scop.cc b/tc/core/polyhedral/scop.cc index 41cc17448..5edb94455 100644 --- a/tc/core/polyhedral/scop.cc +++ b/tc/core/polyhedral/scop.cc @@ -518,7 +518,7 @@ const Halide::OutputImageParam& Scop::findArgument(isl::id id) const { isl::aff Scop::makeIslAffFromStmtExpr(isl::id stmtId, const Halide::Expr& e) const { auto domain = halide.domains.at(stmtId); - auto aff = halide2isl::makeIslAffFromExpr(domain.paramSpace, e); + isl::aff aff = halide2isl::makeIslAffFromExpr(domain.paramSpace, e); aff = aff.unbind_params_insert_domain(domain.tuple); return aff; } From 7a039878e963520520d53e0c357fa1baa5d5bf9a Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Thu, 21 Jun 2018 12:05:24 +0200 Subject: [PATCH 038/102] core halide2isl: use templated isl types --- tc/core/halide2isl.cc | 130 +++++++++++++++++------------- tc/core/halide2isl.h | 15 ++-- tc/core/polyhedral/domain_types.h | 3 + 3 files changed, 85 insertions(+), 63 deletions(-) diff --git a/tc/core/halide2isl.cc b/tc/core/halide2isl.cc index e166141ba..912231fae 100644 --- a/tc/core/halide2isl.cc +++ b/tc/core/halide2isl.cc @@ -21,6 +21,7 @@ #include "tc/core/check.h" #include "tc/core/constants.h" #include "tc/core/polyhedral/body.h" +#include "tc/core/polyhedral/domain_types.h" #include "tc/core/polyhedral/schedule_isl_conversion.h" #include "tc/core/polyhedral/schedule_transforms.h" #include "tc/core/polyhedral/schedule_tree.h" @@ -80,13 +81,13 @@ SymbolTable makeSymbolTable(const tc2halide::HalideComponents& components) { return builder.table; } -isl::aff makeIslAffFromInt(isl::space space, int64_t val) { +isl::AffOn<> makeIslAffFromInt(isl::Space<> space, int64_t val) { isl::val v = isl::val(space.get_ctx(), val); - return isl::aff(isl::local_space(space), v); + return isl::AffOn<>(isl::aff(isl::local_space(space), v)); } -std::vector makeIslAffBoundsFromExpr( - isl::space space, +std::vector> makeIslAffBoundsFromExpr( + isl::Space<> space, const Expr& e, bool allowMin, bool allowMax); @@ -101,9 +102,9 @@ namespace { * x > max(a,max(b,c)) <=> x > a AND x > b AND x > c */ template -inline std::vector -concatAffs(isl::space space, T op, bool allowMin, bool allowMax) { - std::vector result; +inline std::vector> +concatAffs(isl::Space<> space, T op, bool allowMin, bool allowMax) { + std::vector> result; for (const auto& aff : makeIslAffBoundsFromExpr(space, op->a, allowMin, allowMax)) { @@ -129,10 +130,10 @@ concatAffs(isl::space space, T op, bool allowMin, bool allowMax) { * x < a + max(b,c) NOT <=> x < a + b AND x < a + c for negative values. */ template -inline std::vector combineSingleAffs( - isl::space space, +inline std::vector> combineSingleAffs( + isl::Space<> space, T op, - isl::aff (isl::aff::*combine)(isl::aff) const) { + isl::AffOn<> (isl::AffOn<>::*combine)(const isl::AffOn<>&) const) { auto left = makeIslAffBoundsFromExpr(space, op->a, false, false); auto right = makeIslAffBoundsFromExpr(space, op->b, false, false); TC_CHECK_LE(left.size(), 1u); @@ -162,8 +163,8 @@ inline std::vector combineSingleAffs( * If a Halide expression cannot be converted into a list of affine expressions, * return an empty list. */ -std::vector makeIslAffBoundsFromExpr( - isl::space space, +std::vector> makeIslAffBoundsFromExpr( + isl::Space<> space, const Expr& e, bool allowMin, bool allowMax) { @@ -178,7 +179,7 @@ std::vector makeIslAffBoundsFromExpr( if (const Variable* op = e.as()) { isl::id id(space.get_ctx(), op->name); if (space.has_param(id)) { - return {isl::aff::param_on_domain_space(space, id)}; + return {isl::AffOn<>::param_on_domain_space(space, id)}; } LOG(FATAL) << "Variable not found in isl::space: " << space << ": " << op << ": " << op->name << '\n'; @@ -188,13 +189,13 @@ std::vector makeIslAffBoundsFromExpr( } else if (maxOp != nullptr && allowMax) { return concatAffs(space, maxOp, allowMin, allowMax); } else if (const Add* op = e.as()) { - return combineSingleAffs(space, op, &isl::aff::add); + return combineSingleAffs(space, op, &isl::AffOn<>::add); } else if (const Sub* op = e.as()) { - return combineSingleAffs(space, op, &isl::aff::sub); + return combineSingleAffs(space, op, &isl::AffOn<>::sub); } else if (const Mul* op = e.as()) { - return combineSingleAffs(space, op, &isl::aff::mul); + return combineSingleAffs(space, op, &isl::AffOn<>::mul); } else if (const Div* op = e.as
()) { - return combineSingleAffs(space, op, &isl::aff::div); + return combineSingleAffs(space, op, &isl::AffOn<>::div); } else if (const Mod* op = e.as()) { std::vector result; // We cannot span multiple constraints if a modulo operation is involved. @@ -211,7 +212,7 @@ std::vector makeIslAffBoundsFromExpr( return {}; } -isl::aff makeIslAffFromExpr(isl::space space, const Expr& e) { +isl::AffOn<> makeIslAffFromExpr(isl::Space<> space, const Expr& e) { auto list = makeIslAffBoundsFromExpr(space, e, false, false); TC_CHECK_LE(list.size(), 1u) << "Halide expr " << e << " unrolled into more than 1 isl aff" @@ -219,13 +220,13 @@ isl::aff makeIslAffFromExpr(isl::space space, const Expr& e) { // Non-affine if (list.size() == 0) { - return isl::aff(); + return isl::AffOn<>(); } return list[0]; } -isl::space makeParamSpace(isl::ctx ctx, const ParameterVector& params) { - auto space = isl::space(ctx, 0); +isl::Space<> makeParamSpace(isl::ctx ctx, const ParameterVector& params) { + auto space = isl::Space<>(ctx, 0); // set parameter names for (auto p : params) { space = space.add_param(isl::id(ctx, p.name())); @@ -233,19 +234,29 @@ isl::space makeParamSpace(isl::ctx ctx, const ParameterVector& params) { return space; } -isl::set makeParamContext(isl::ctx ctx, const ParameterVector& params) { +isl::Set<> makeParamContext(isl::ctx ctx, const ParameterVector& params) { auto space = makeParamSpace(ctx, params); - auto context = isl::set::universe(space); + auto context = isl::Set<>::universe(space); for (auto p : params) { - isl::aff a(isl::aff::param_on_domain_space(space, isl::id(ctx, p.name()))); - context = context & (a >= 0); + auto a(isl::AffOn<>::param_on_domain_space(space, isl::id(ctx, p.name()))); + context = context & a.asPwAff().nonneg_set(); } return context; } namespace { -isl::map extractAccess( +/* + * Call the domain_map factory method of the isl::MultiAff + * with appropriate template arguments. + */ +template +static isl::MultiAff, Domain> domainMap( + isl::Space space) { + return isl::MultiAff, Domain>::domain_map(space); +} + +isl::Map, Tensor> extractAccess( const IterationDomain& domain, const IRNode* op, const std::string& tensor, @@ -258,16 +269,17 @@ isl::map extractAccess( // to the outer loop iterators) and then convert this set // into a map in terms of the iteration domain. - auto paramSpace = isl::Space<>(domain.paramSpace); + auto paramSpace = domain.paramSpace; isl::id tensorID(paramSpace.get_ctx(), tensor); auto tensorTuple = constructTensorTuple(paramSpace, tensorID, args.size()); auto tensorSpace = tensorTuple.get_space(); // Start with a totally unconstrained set - every point in // the allocation could be accessed. - isl::set access = isl::set::universe(tensorSpace); + auto access = isl::Set::universe(tensorSpace); - auto identity = isl::multi_aff::identity(tensorSpace.map_from_set()); + auto identity = + isl::MultiAff::identity(tensorSpace.map_from_set()); for (size_t i = 0; i < args.size(); i++) { // Then add one equality constraint per dimension to encode the // point in the allocation actually read/written for each point in @@ -277,9 +289,9 @@ isl::map extractAccess( // The coordinate written to in the range ... auto rangePoint = identity.get_aff(i); // ... equals the coordinate accessed as a function of the parameters. - auto domainPoint = halide2isl::makeIslAffFromExpr(paramSpace, args[i]); - if (!domainPoint.is_null()) { - domainPoint = domainPoint.unbind_params_insert_domain(tensorTuple); + auto paramPoint = halide2isl::makeIslAffFromExpr(paramSpace, args[i]); + if (!paramPoint.is_null()) { + auto domainPoint = paramPoint.unbind_params_insert_domain(tensorTuple); access = access.intersect(domainPoint.eq_set(rangePoint)); } } @@ -293,14 +305,15 @@ isl::map extractAccess( isl::id tagID(domain.paramSpace.get_ctx(), tag); accesses->emplace(op, tagID); auto domainSpace = map.get_space().domain(); - auto tagSpace = domainSpace.params().add_named_tuple_id_ui(tagID, 0); - domainSpace = domainSpace.product(tagSpace).unwrap(); - map = map.preimage_domain(isl::multi_aff::domain_map(domainSpace)); - - return map; + auto tagSpace = domainSpace.params().add_named_tuple_id_ui(tagID, 0); + auto taggedSpace = domainSpace.product(tagSpace).unwrap(); + return map.preimage_domain(domainMap(taggedSpace)); } -std::pair extractAccesses( +std::pair< + isl::UnionMap, Tensor>, + isl::UnionMap, Tensor>> +extractAccesses( const IterationDomain& domain, const Stmt& s, AccessMap* accesses) { @@ -325,7 +338,7 @@ std::pair extractAccesses( AccessMap* accesses; public: - isl::union_map reads, writes; + isl::UnionMap, Tensor> reads, writes; FindAccesses(const IterationDomain& domain, AccessMap* accesses) : domain(domain), @@ -355,24 +368,26 @@ bool isReductionUpdate(const Provide* op) { * then converted into an expression on that iteration domain * by reinterpreting the parameters as input dimensions. */ -static isl::multi_aff mapToOther( +template +static isl::MultiAff mapToOther( const IterationDomain& iterationDomain, std::unordered_set skip, isl::id id) { auto ctx = iterationDomain.tuple.get_ctx(); - auto list = isl::aff_list(ctx, 0); + auto list = isl::AffListOn(ctx, 0); for (auto id : iterationDomain.tuple.get_id_list()) { if (skip.count(id.get_name()) == 1) { continue; } - auto aff = isl::aff::param_on_domain_space(iterationDomain.paramSpace, id); - aff = aff.unbind_params_insert_domain(iterationDomain.tuple); - list = list.add(aff); + auto aff = + isl::AffOn<>::param_on_domain_space(iterationDomain.paramSpace, id); + list = list.add(aff.unbind_params_insert_domain(iterationDomain.tuple)); } auto domainSpace = iterationDomain.tuple.get_space(); - auto space = domainSpace.params().add_named_tuple_id_ui(id, list.size()); - space = domainSpace.product(space).unwrap(); - return isl::multi_aff(space, list); + auto space = + domainSpace.params().add_named_tuple_id_ui(id, list.size()); + auto productSpace = domainSpace.product(space).unwrap(); + return isl::MultiAff(productSpace, list); } /* @@ -417,7 +432,8 @@ isl::union_map extractReduction( } auto ctx = iterationDomain.tuple.get_ctx(); isl::id id(ctx, kReductionLabel + op->name + "_" + std::to_string(index)); - auto reduction = mapToOther(iterationDomain, finder.reductionVars, id); + auto reduction = + mapToOther(iterationDomain, finder.reductionVars, id); return isl::union_map(isl::map(reduction)); } @@ -458,7 +474,7 @@ onDomains(isl::aff f, isl::union_set domain, const IterationDomainMap& map) { */ isl::schedule makeScheduleTreeHelper( const Stmt& s, - isl::set set, + isl::Set<> set, isl::id_list outer, Body* body, AccessMap* accesses, @@ -472,7 +488,7 @@ isl::schedule makeScheduleTreeHelper( // Construct a variable (affine function) that references // the new parameter. - auto loopVar = isl::aff::param_on_domain_space(space, id); + auto loopVar = isl::AffOn<>::param_on_domain_space(space, id); // Then we add our new loop bound constraints. auto lbs = @@ -527,16 +543,16 @@ isl::schedule makeScheduleTreeHelper( size_t stmtIndex = statements->size(); isl::id id(set.get_ctx(), kStatementLabel + std::to_string(stmtIndex)); statements->emplace(id, op); - auto tupleSpace = isl::space(set.get_ctx(), 0); - tupleSpace = tupleSpace.add_named_tuple_id_ui(id, outer.size()); + auto space = isl::Space<>(set.get_ctx(), 0); + auto tupleSpace = space.add_named_tuple_id_ui(id, outer.size()); IterationDomain iterationDomain; iterationDomain.paramSpace = set.get_space(); - iterationDomain.tuple = isl::multi_id(tupleSpace, outer); + iterationDomain.tuple = isl::MultiId(tupleSpace, outer); domains->emplace(id, iterationDomain); auto domain = set.unbind_params(iterationDomain.tuple); schedule = isl::schedule::from_domain(domain); - isl::union_map newReads, newWrites; + isl::UnionMap, Tensor> newReads, newWrites; std::tie(newReads, newWrites) = extractAccesses(iterationDomain, op, accesses); // A tensor may be involved in multiple reductions. @@ -553,7 +569,9 @@ isl::schedule makeScheduleTreeHelper( return schedule; }; -ScheduleTreeAndAccesses makeScheduleTree(isl::space paramSpace, const Stmt& s) { +ScheduleTreeAndAccesses makeScheduleTree( + isl::Space<> paramSpace, + const Stmt& s) { ScheduleTreeAndAccesses result; Body body(paramSpace); @@ -562,7 +580,7 @@ ScheduleTreeAndAccesses makeScheduleTree(isl::space paramSpace, const Stmt& s) { isl::id_list outer(paramSpace.get_ctx(), 0); auto schedule = makeScheduleTreeHelper( s, - isl::set::universe(paramSpace), + isl::Set<>::universe(paramSpace), outer, &body, &result.accesses, diff --git a/tc/core/halide2isl.h b/tc/core/halide2isl.h index b3ecc95ce..f735846a1 100644 --- a/tc/core/halide2isl.h +++ b/tc/core/halide2isl.h @@ -23,6 +23,7 @@ #include #include "tc/core/polyhedral/body.h" +#include "tc/core/polyhedral/domain_types.h" #include "tc/core/polyhedral/schedule_tree.h" #include "tc/core/tc2halide.h" #include "tc/external/isl.h" @@ -43,14 +44,14 @@ struct SymbolTable { SymbolTable makeSymbolTable(const tc2halide::HalideComponents& components); /// Make the space of all given parameter values -isl::space makeParamSpace(isl::ctx ctx, const ParameterVector& params); +isl::Space<> makeParamSpace(isl::ctx ctx, const ParameterVector& params); /// Make the parameter set marking all given parameters /// as non-negative. -isl::set makeParamContext(isl::ctx ctx, const ParameterVector& params); +isl::Set<> makeParamContext(isl::ctx ctx, const ParameterVector& params); /// Make a constant-valued affine function over a space. -isl::aff makeIslAffFromInt(isl::space space, int64_t i); +isl::AffOn<> makeIslAffFromInt(isl::Space<> space, int64_t i); // Make an affine function over a space from a Halide Expr. Returns a // null isl::aff if the expression is not affine. Fails if Variable @@ -58,17 +59,17 @@ isl::aff makeIslAffFromInt(isl::space space, int64_t i); // Note that the input space can be either a parameter space or // a set space, but the expression can only reference // the parameters in the space. -isl::aff makeIslAffFromExpr(isl::space space, const Halide::Expr& e); +isl::AffOn<> makeIslAffFromExpr(isl::Space<> space, const Halide::Expr& e); // Iteration domain information associated to a statement identifier. struct IterationDomain { // All parameters active at the point where the iteration domain // was created, including those corresponding to outer loop iterators. - isl::space paramSpace; + isl::Space<> paramSpace; // The identifier tuple corresponding to the iteration domain. // The identifiers in the tuple are the outer loop iterators, // from outermost to innermost. - isl::multi_id tuple; + isl::MultiId tuple; }; typedef std::unordered_map @@ -102,7 +103,7 @@ struct ScheduleTreeAndAccesses { /// Make a schedule tree from a Halide Stmt, along with auxiliary data /// structures describing the memory access patterns. ScheduleTreeAndAccesses makeScheduleTree( - isl::space paramSpace, + isl::Space<> paramSpace, const Halide::Internal::Stmt& s); } // namespace halide2isl diff --git a/tc/core/polyhedral/domain_types.h b/tc/core/polyhedral/domain_types.h index 96b740bd2..433666c25 100644 --- a/tc/core/polyhedral/domain_types.h +++ b/tc/core/polyhedral/domain_types.h @@ -2,6 +2,9 @@ namespace tc { namespace polyhedral { struct Prefix; +struct Reduction; +struct Statement; +struct Tag; struct Tensor; } // namespace polyhedral From 5582763d2be6d0a8571149919ecd1cabdad32d0f Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Thu, 21 Jun 2018 12:05:24 +0200 Subject: [PATCH 039/102] halide2isl.cc: extractReduction: use templated isl types --- tc/core/halide2isl.cc | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/tc/core/halide2isl.cc b/tc/core/halide2isl.cc index 912231fae..fef70e0fe 100644 --- a/tc/core/halide2isl.cc +++ b/tc/core/halide2isl.cc @@ -407,7 +407,7 @@ static isl::MultiAff mapToOther( * that all statement instances that belong to the same reduction * write to the same tensor element. */ -isl::union_map extractReduction( +isl::UnionMap extractReduction( const IterationDomain& iterationDomain, const Provide* op, size_t index) { @@ -424,17 +424,19 @@ isl::union_map extractReduction( } finder; if (!isReductionUpdate(op)) { - return isl::union_map::empty(iterationDomain.tuple.get_space().params()); + auto space = iterationDomain.tuple.get_space().params(); + return isl::UnionMap::empty(space); } op->accept(&finder); if (finder.reductionVars.size() == 0) { - return isl::union_map::empty(iterationDomain.tuple.get_space().params()); + auto space = iterationDomain.tuple.get_space().params(); + return isl::UnionMap(isl::union_map::empty(space)); } auto ctx = iterationDomain.tuple.get_ctx(); isl::id id(ctx, kReductionLabel + op->name + "_" + std::to_string(index)); auto reduction = mapToOther(iterationDomain, finder.reductionVars, id); - return isl::union_map(isl::map(reduction)); + return reduction.asMap().asUnionMap(); } /* From bee3fae89d65d63b6a58fcbe42dae22587fa861c Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Thu, 21 Jun 2018 12:05:24 +0200 Subject: [PATCH 040/102] Scop::context: remove explicit cast Now that halide2isl::makeParamContext has been converted to templated isl types, the cast is no longer required. --- tc/core/polyhedral/scop.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tc/core/polyhedral/scop.h b/tc/core/polyhedral/scop.h index c91863308..c62e4d22a 100644 --- a/tc/core/polyhedral/scop.h +++ b/tc/core/polyhedral/scop.h @@ -95,7 +95,7 @@ struct Scop { isl::Set<> context() const { auto ctx = domain().get_ctx(); auto context = halide2isl::makeParamContext(ctx, halide.params); - return isl::Set<>(context.intersect(makeContext(parameterValues))); + return context.intersect(makeContext(parameterValues)); } // Specialize a Scop by fixing the given parameters to the given sizes. From d49748688a0fda0161ffdaf49ebf504abc565799 Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Thu, 21 Jun 2018 12:05:24 +0200 Subject: [PATCH 041/102] Scop::domain(): use templated isl types This commit introduces a cast, which will be removed after schedule trees have been converted to templated isl types. --- tc/core/polyhedral/scop.cc | 5 +++-- tc/core/polyhedral/scop.h | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/tc/core/polyhedral/scop.cc b/tc/core/polyhedral/scop.cc index 5edb94455..e7fbe191c 100644 --- a/tc/core/polyhedral/scop.cc +++ b/tc/core/polyhedral/scop.cc @@ -27,6 +27,7 @@ #include "tc/core/functional.h" #include "tc/core/halide2isl.h" #include "tc/core/polyhedral/body.h" +#include "tc/core/polyhedral/domain_types.h" #include "tc/core/polyhedral/memory_promotion.h" #include "tc/core/polyhedral/schedule_isl_conversion.h" #include "tc/core/polyhedral/schedule_transforms.h" @@ -97,8 +98,8 @@ isl::union_set& Scop::domainRef() { return dom->domain_; } -const isl::union_set Scop::domain() const { - return const_cast(this)->domainRef(); +const isl::UnionSet Scop::domain() const { + return isl::UnionSet(const_cast(this)->domainRef()); } std::ostream& operator<<(std::ostream& os, const Scop& s) { diff --git a/tc/core/polyhedral/scop.h b/tc/core/polyhedral/scop.h index c62e4d22a..f54374131 100644 --- a/tc/core/polyhedral/scop.h +++ b/tc/core/polyhedral/scop.h @@ -27,6 +27,7 @@ #include "tc/core/halide2isl.h" #include "tc/core/mapping_options.h" #include "tc/core/polyhedral/body.h" +#include "tc/core/polyhedral/domain_types.h" #include "tc/core/polyhedral/schedule_transforms.h" #include "tc/core/polyhedral/schedule_tree.h" #include "tc/core/tc2halide.h" @@ -508,7 +509,7 @@ struct Scop { isl::union_set& domainRef(); public: - const isl::union_set domain() const; + const isl::UnionSet domain() const; // The parameter values of a specialized Scop. std::unordered_map parameterValues; From e8b4b23fa72d5a6da67e63fce1c1016180d030eb Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Thu, 21 Jun 2018 12:05:24 +0200 Subject: [PATCH 042/102] memory_promotion.cc: tensorElementsSet: remove explicit cast Now that Scop::Domain() has been converted to templated isl types, the cast is no longer required. --- tc/core/polyhedral/memory_promotion.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tc/core/polyhedral/memory_promotion.cc b/tc/core/polyhedral/memory_promotion.cc index 1cacd0e7b..e5741c5b4 100644 --- a/tc/core/polyhedral/memory_promotion.cc +++ b/tc/core/polyhedral/memory_promotion.cc @@ -410,7 +410,7 @@ namespace { // context of the scop. isl::set tensorElementsSet(const Scop& scop, isl::id tensorId) { auto halideParameter = scop.findArgument(tensorId).parameter(); - auto space = isl::Space<>(scop.domain().get_space()); + auto space = scop.domain().get_space(); auto nDim = halideParameter.dimensions(); auto tensorTuple = constructTensorTuple(space, tensorId, nDim); auto tensorSpace = tensorTuple.get_space(); From 8bd2230a61bfee944950623c45b9e7098bfa839a Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Thu, 21 Jun 2018 12:05:24 +0200 Subject: [PATCH 043/102] Scop::makeContext: remove explicit cast Now that Scop::Domain() has been converted to templated isl types, the cast is no longer required. --- tc/core/polyhedral/scop.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tc/core/polyhedral/scop.h b/tc/core/polyhedral/scop.h index f54374131..dd463be9f 100644 --- a/tc/core/polyhedral/scop.h +++ b/tc/core/polyhedral/scop.h @@ -135,7 +135,7 @@ struct Scop { isl::Set<> makeContext( const std::unordered_map& sizes = std::unordered_map()) const { - auto s = isl::Space<>(domain().get_space()); + auto s = domain().get_space(); return makeSpecializationSet(s, sizes); } From 1a53ca0187cc391e0185246da88092a7859c04da Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Thu, 21 Jun 2018 12:05:24 +0200 Subject: [PATCH 044/102] makeParameterContext: use templated isl types Use explicit API calls instead of operators because the use of aff_set is confusing (at least to the author of this commit). The conversions to isl::PwAff are needed because, unlike the Python bindings, the C++ bindings do not have a class hierarchy. The conversions could also be avoided by introducing an isl_aff_nonneg_set and an isl_aff_pos_set in isl. --- tc/core/polyhedral/cuda/mapped_scop.cc | 3 ++- tc/external/detail/islpp.h | 10 +++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/tc/core/polyhedral/cuda/mapped_scop.cc b/tc/core/polyhedral/cuda/mapped_scop.cc index eb555d94f..2594a00e4 100644 --- a/tc/core/polyhedral/cuda/mapped_scop.cc +++ b/tc/core/polyhedral/cuda/mapped_scop.cc @@ -866,7 +866,8 @@ void MappedScop::insertMappingContext() { auto space = scop.domain().get_space(); auto mappingContext = makeParameterContext( space, mappingIdsWithSizes.begin(), mappingIdsWithSizes.end()); - updateTopLevelContext(scop.scheduleRoot(), mappingContext.from_params()); + updateTopLevelContext( + scop.scheduleRoot(), mappingContext.from_params()); } namespace { diff --git a/tc/external/detail/islpp.h b/tc/external/detail/islpp.h index 1d730d6b7..d527c4192 100644 --- a/tc/external/detail/islpp.h +++ b/tc/external/detail/islpp.h @@ -291,17 +291,17 @@ isl::multi_val makeMultiVal(isl::space s, const std::vector& vals) { // 2. each new parameter dimension p(i) is bounded to be in [0, e(i) - 1] // 3. if e (i) == 0 then no constraint is set on the corresponding id(i) template -inline isl::set makeParameterContext( - isl::space paramSpace, +inline isl::Set<> makeParameterContext( + isl::Space<> paramSpace, const IterPair begin, const IterPair end) { for (auto it = begin; it != end; ++it) { paramSpace = paramSpace.add_param(it->first); } - isl::set res(isl::set::universe(paramSpace)); + auto res(isl::Set<>::universe(paramSpace)); for (auto it = begin; it != end; ++it) { - isl::aff a(isl::aff::param_on_domain_space(paramSpace, it->first)); - res = res & (isl::aff_set(a) >= 0) & (isl::aff_set(a) < it->second); + auto a(isl::AffOn<>::param_on_domain_space(paramSpace, it->first)); + res = res & a.asPwAff().nonneg_set() & (it->second - a).asPwAff().pos_set(); } return res; } From 7bea0466b514ddcb567e71e4af01f80ac8a2e179 Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Thu, 21 Jun 2018 12:05:24 +0200 Subject: [PATCH 045/102] partialScheduleMupa: use templated isl types An explicit cast is introduced in partialScheduleMupa, which will be removed after the schedule tree has been converted to templated isl types. Automatic type deduction is temporarily turned off in promoteToSharedBelow to avoid having to convert the entire promoteToSharedBelow together with partialScheduleMupa. It will be reintroduced after the schedule tree has been converted to templated isl types. --- tc/core/polyhedral/cuda/memory_promotion_heuristic.cc | 6 ++++-- tc/core/polyhedral/schedule_utils-inl.h | 9 ++++++--- tc/core/polyhedral/schedule_utils.h | 4 +++- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/tc/core/polyhedral/cuda/memory_promotion_heuristic.cc b/tc/core/polyhedral/cuda/memory_promotion_heuristic.cc index 928ee904a..f44ab4251 100644 --- a/tc/core/polyhedral/cuda/memory_promotion_heuristic.cc +++ b/tc/core/polyhedral/cuda/memory_promotion_heuristic.cc @@ -19,6 +19,7 @@ #include "tc/core/polyhedral/cuda/mapped_scop.h" #include "tc/core/polyhedral/cuda/mapping_types.h" +#include "tc/core/polyhedral/domain_types.h" #include "tc/core/polyhedral/exceptions.h" #include "tc/core/polyhedral/memory_promotion.h" #include "tc/core/polyhedral/schedule_tree.h" @@ -477,7 +478,7 @@ void promoteToSharedBelow( auto groupMap = TensorReferenceGroup::accessedWithin( partialSched.intersect_domain(mapping), scop.body); // Pure affine schedule without (mapping) filters. - auto partialSchedMupa = partialScheduleMupa(root, node); + auto partialSchedMupa = partialScheduleMupa(root, node); // Prepare groups for sorting, to have specified order necessary for // reproducibility and tests. @@ -653,7 +654,8 @@ void promoteToRegistersBelow(MappedScop& mscop, detail::ScheduleTree* scope) { auto blockSchedule = mscop.blockMappingSchedule(mscop.schedule()); // Pure affine schedule without (mapping) filters. - auto partialSchedMupa = partialScheduleMupa(root, scope); + isl::multi_union_pw_aff partialSchedMupa = + partialScheduleMupa(root, scope); // Schedule with block mapping filter. auto partialSched = isl::union_map::from(partialSchedMupa).intersect_domain(blockMapping); diff --git a/tc/core/polyhedral/schedule_utils-inl.h b/tc/core/polyhedral/schedule_utils-inl.h index 3c6be4645..65aad9bbd 100644 --- a/tc/core/polyhedral/schedule_utils-inl.h +++ b/tc/core/polyhedral/schedule_utils-inl.h @@ -18,6 +18,7 @@ #include #include "tc/core/check.h" +#include "tc/core/polyhedral/domain_types.h" #include "tc/core/polyhedral/schedule_tree.h" #include "tc/core/polyhedral/schedule_tree_elem.h" #include "tc/external/isl.h" @@ -137,14 +138,16 @@ inline isl::multi_union_pw_aff prefixScheduleMupa( return infixScheduleMupa(root, root, tree); } -inline isl::multi_union_pw_aff partialScheduleMupa( +template +inline isl::MultiUnionPwAff partialScheduleMupa( const detail::ScheduleTree* root, const detail::ScheduleTree* tree) { using namespace polyhedral::detail; auto prefix = prefixScheduleMupa(root, tree); - auto band = tree->as(); - return band ? prefix.flat_range_product(band->mupa_) : prefix; + auto band = tree->as(); + auto partial = band ? prefix.flat_range_product(band->mupa_) : prefix; + return isl::MultiUnionPwAff(partial); } /* diff --git a/tc/core/polyhedral/schedule_utils.h b/tc/core/polyhedral/schedule_utils.h index 93bcff92d..5ced261b0 100644 --- a/tc/core/polyhedral/schedule_utils.h +++ b/tc/core/polyhedral/schedule_utils.h @@ -19,6 +19,7 @@ #include "tc/core/check.h" #include "tc/core/constants.h" +#include "tc/core/polyhedral/domain_types.h" #include "tc/core/polyhedral/schedule_tree.h" #include "tc/core/polyhedral/schedule_tree_elem.h" @@ -86,7 +87,8 @@ isl::multi_union_pw_aff prefixScheduleMupa( // including that of the node itself. // Note that this function does not take into account // any intermediate filter nodes. -isl::multi_union_pw_aff partialScheduleMupa( +template +isl::MultiUnionPwAff partialScheduleMupa( const detail::ScheduleTree* root, const detail::ScheduleTree* tree); From 1902ff1c0872cfae6fea471c0c3d93c3a8588c29 Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Thu, 21 Jun 2018 12:05:24 +0200 Subject: [PATCH 046/102] prefixScheduleMupa: use templated isl types An explicit cast is introduced in prefixScheduleMupa, which will be removed when infixScheduleMupa is converted to templated isl types. Automatic type deduction is temporarily turned off in MappedScop::detectReductions to avoid having to convert the entire MappedScop::detectReductions together with prefixScheduleMupa. It will be reintroduced which will be removed when memberRange is converted to templated isl types. Automatic type deduction is also temporarily turned off in partialScheduleMupa. It will be reintroduced after the schedule tree has been converted to templated isl types. --- tc/core/polyhedral/cuda/mapped_scop.cc | 4 ++-- tc/core/polyhedral/schedule_transforms.cc | 4 ++-- tc/core/polyhedral/schedule_utils-inl.h | 8 +++++--- tc/core/polyhedral/schedule_utils.h | 3 ++- tc/core/polyhedral/scop.cc | 4 ++-- 5 files changed, 13 insertions(+), 10 deletions(-) diff --git a/tc/core/polyhedral/cuda/mapped_scop.cc b/tc/core/polyhedral/cuda/mapped_scop.cc index 2594a00e4..dbe0538a7 100644 --- a/tc/core/polyhedral/cuda/mapped_scop.cc +++ b/tc/core/polyhedral/cuda/mapped_scop.cc @@ -296,7 +296,7 @@ bool MappedScop::detectReductions(ScheduleTree* tree) { }); // The outer (coincident) members, together with the prefix schedule, // need to determine a single reduction. - auto prefix = prefixScheduleMupa(schedule(), tree); + isl::multi_union_pw_aff prefix = prefixScheduleMupa(schedule(), tree); prefix = prefix.range_product(band->memberRange(0, nCoincident)); if (!isSingleReductionWithin(updates, prefix, scop())) { return false; @@ -342,7 +342,7 @@ ScheduleTree* MappedScop::separateReduction(ScheduleTree* st) { auto root = scop_->scheduleRoot(); auto domain = activeDomainPoints(root, st); - auto prefixSchedule = prefixScheduleMupa(root, st); + auto prefixSchedule = prefixScheduleMupa(root, st); auto reductionSchedule = reductionMapSchedule(st); auto space = reductionSchedule.get_space(); auto size = isl::multi_val::zero(space); diff --git a/tc/core/polyhedral/schedule_transforms.cc b/tc/core/polyhedral/schedule_transforms.cc index 2aee2e095..082235496 100644 --- a/tc/core/polyhedral/schedule_transforms.cc +++ b/tc/core/polyhedral/schedule_transforms.cc @@ -363,9 +363,9 @@ detail::ScheduleTree* insertEmptyExtensionAbove( * with the given identifier. */ isl::map labelExtension(ScheduleTree* root, ScheduleTree* tree, isl::id id) { - auto prefix = prefixScheduleMupa(root, tree); + auto prefix = prefixScheduleMupa(root, tree); auto scheduleSpace = prefix.get_space(); - auto space = scheduleSpace.params().add_named_tuple_id_ui(id, 0); + auto space = scheduleSpace.params().add_named_tuple_id_ui(id, 0); auto extensionSpace = scheduleSpace.map_from_domain_and_range(space); return isl::map::universe(extensionSpace); } diff --git a/tc/core/polyhedral/schedule_utils-inl.h b/tc/core/polyhedral/schedule_utils-inl.h index 65aad9bbd..6f868c70c 100644 --- a/tc/core/polyhedral/schedule_utils-inl.h +++ b/tc/core/polyhedral/schedule_utils-inl.h @@ -132,10 +132,12 @@ inline isl::multi_union_pw_aff infixScheduleMupa( return prefix; } -inline isl::multi_union_pw_aff prefixScheduleMupa( +template +inline isl::MultiUnionPwAff prefixScheduleMupa( const detail::ScheduleTree* root, const detail::ScheduleTree* tree) { - return infixScheduleMupa(root, root, tree); + auto prefix = infixScheduleMupa(root, root, tree); + return isl::MultiUnionPwAff(prefix); } template @@ -144,7 +146,7 @@ inline isl::MultiUnionPwAff partialScheduleMupa( const detail::ScheduleTree* tree) { using namespace polyhedral::detail; - auto prefix = prefixScheduleMupa(root, tree); + isl::multi_union_pw_aff prefix = prefixScheduleMupa(root, tree); auto band = tree->as(); auto partial = band ? prefix.flat_range_product(band->mupa_) : prefix; return isl::MultiUnionPwAff(partial); diff --git a/tc/core/polyhedral/schedule_utils.h b/tc/core/polyhedral/schedule_utils.h index 5ced261b0..36e77fd40 100644 --- a/tc/core/polyhedral/schedule_utils.h +++ b/tc/core/polyhedral/schedule_utils.h @@ -79,7 +79,8 @@ isl::multi_union_pw_aff infixScheduleMupa( // function on the universe domain of the schedule tree. // Note that unlike isl_schedule_node_get_prefix_schedule_multi_union_pw_aff, // this function does not take into account any intermediate filter nodes. -isl::multi_union_pw_aff prefixScheduleMupa( +template +isl::MultiUnionPwAff prefixScheduleMupa( const detail::ScheduleTree* root, const detail::ScheduleTree* tree); diff --git a/tc/core/polyhedral/scop.cc b/tc/core/polyhedral/scop.cc index e7fbe191c..791cb138e 100644 --- a/tc/core/polyhedral/scop.cc +++ b/tc/core/polyhedral/scop.cc @@ -370,7 +370,7 @@ void Scop::computeAllDependences() { } isl::union_map Scop::activeDependences(detail::ScheduleTree* tree) { - auto prefix = prefixScheduleMupa(scheduleRoot(), tree); + auto prefix = prefixScheduleMupa(scheduleRoot(), tree); auto domain = activeDomainPoints(scheduleRoot(), tree); auto active = dependences; active = active.intersect_domain(domain); @@ -485,7 +485,7 @@ void Scop::reschedule( auto parentTree = tree->ancestor(root, 1); auto treePos = tree->positionInParent(parentTree); auto domain = activeDomainPoints(root, tree); - auto prefix = prefixScheduleMupa(root, tree); + auto prefix = prefixScheduleMupa(root, tree); // Restrict the constraints to domain points reachable from point loops // and update the current prefix. From 91487b6a231af0f663b6369ac919908f8a174a15 Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Thu, 21 Jun 2018 12:05:24 +0200 Subject: [PATCH 047/102] memberRange: use templated isl types An explicit cast is introduced in memberRange, which will be removed when schedule trees are converted to templated isl types. --- tc/core/polyhedral/cuda/mapped_scop.cc | 6 +++--- tc/core/polyhedral/domain_types.h | 2 ++ tc/core/polyhedral/schedule_tree_elem.h | 8 ++++++-- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/tc/core/polyhedral/cuda/mapped_scop.cc b/tc/core/polyhedral/cuda/mapped_scop.cc index dbe0538a7..a406c195a 100644 --- a/tc/core/polyhedral/cuda/mapped_scop.cc +++ b/tc/core/polyhedral/cuda/mapped_scop.cc @@ -296,8 +296,8 @@ bool MappedScop::detectReductions(ScheduleTree* tree) { }); // The outer (coincident) members, together with the prefix schedule, // need to determine a single reduction. - isl::multi_union_pw_aff prefix = prefixScheduleMupa(schedule(), tree); - prefix = prefix.range_product(band->memberRange(0, nCoincident)); + auto prefix = prefixScheduleMupa(schedule(), tree) + .range_product(band->memberRange(0, nCoincident)); if (!isSingleReductionWithin(updates, prefix, scop())) { return false; } @@ -331,7 +331,7 @@ isl::multi_union_pw_aff MappedScop::reductionMapSchedule( TC_CHECK_GE(nMember, reductionDim + 1); auto first = reductionDim + 1 - nMappedThreads; - return reductionBand->memberRange(first, nMappedThreads); + return reductionBand->memberRange(first, nMappedThreads); } ScheduleTree* MappedScop::separateReduction(ScheduleTree* st) { diff --git a/tc/core/polyhedral/domain_types.h b/tc/core/polyhedral/domain_types.h index 433666c25..9fba84e32 100644 --- a/tc/core/polyhedral/domain_types.h +++ b/tc/core/polyhedral/domain_types.h @@ -1,8 +1,10 @@ namespace tc { namespace polyhedral { +struct Band; struct Prefix; struct Reduction; +struct ReductionSchedule; struct Statement; struct Tag; struct Tensor; diff --git a/tc/core/polyhedral/schedule_tree_elem.h b/tc/core/polyhedral/schedule_tree_elem.h index 91cc61444..a912fab5c 100644 --- a/tc/core/polyhedral/schedule_tree_elem.h +++ b/tc/core/polyhedral/schedule_tree_elem.h @@ -23,6 +23,7 @@ #include "tc/external/isl.h" #include "tc/core/check.h" +#include "tc/core/polyhedral/domain_types.h" #include "tc/core/polyhedral/mapping_types.h" #include "tc/core/polyhedral/schedule_tree.h" @@ -331,14 +332,17 @@ struct ScheduleTreeBand : public ScheduleTree { // Extract the range of "n" members starting at "first" // (in an anonymous space). - isl::multi_union_pw_aff memberRange(size_t first, size_t n) const { + template + isl::MultiUnionPwAff memberRange(size_t first, size_t n) + const { auto list = mupa_.get_union_pw_aff_list(); auto space = mupa_.get_space().params().add_unnamed_tuple_ui(n); auto end = first + n; TC_CHECK_LE(end, nMember()); list = list.drop(end, nMember() - end); list = list.drop(0, first); - return isl::multi_union_pw_aff(space, list); + return isl::MultiUnionPwAff( + isl::multi_union_pw_aff(space, list)); } public: From e847e763f91069a548febce042fd3d78609e0fdf Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Thu, 21 Jun 2018 12:05:24 +0200 Subject: [PATCH 048/102] reductionUpdates: use templated isl types An explicit cast is introduced in reductionUpdates, which will be removed when Body is converted to templated isl types. --- tc/core/polyhedral/reduction_matcher.cc | 7 +++++-- tc/core/polyhedral/schedule_tree_matcher.h | 5 ++++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/tc/core/polyhedral/reduction_matcher.cc b/tc/core/polyhedral/reduction_matcher.cc index 59aeaf13f..64efc852b 100644 --- a/tc/core/polyhedral/reduction_matcher.cc +++ b/tc/core/polyhedral/reduction_matcher.cc @@ -18,6 +18,7 @@ #include #include "tc/core/check.h" +#include "tc/core/polyhedral/domain_types.h" #include "tc/core/polyhedral/schedule_tree.h" #include "tc/core/polyhedral/scop.h" #include "tc/external/isl.h" @@ -54,7 +55,9 @@ bool isSupportedReductionUpdateId(isl::id id, const Scop& scop) { } // namespace -isl::union_set reductionUpdates(isl::union_set domain, const Scop& scop) { +isl::UnionSet reductionUpdates( + isl::union_set domain, + const Scop& scop) { domain = scop.body.reductions.intersect_domain(domain).domain(); auto update = isl::union_set::empty(domain.get_space()); domain.foreach_set([&update, &scop](isl::set set) { @@ -63,7 +66,7 @@ isl::union_set reductionUpdates(isl::union_set domain, const Scop& scop) { update = update.unite(set); } }); - return update; + return isl::UnionSet(update); } } // namespace polyhedral diff --git a/tc/core/polyhedral/schedule_tree_matcher.h b/tc/core/polyhedral/schedule_tree_matcher.h index fd4b986a9..173cfee95 100644 --- a/tc/core/polyhedral/schedule_tree_matcher.h +++ b/tc/core/polyhedral/schedule_tree_matcher.h @@ -19,6 +19,7 @@ #include #include +#include "tc/core/polyhedral/domain_types.h" #include "tc/core/polyhedral/schedule_tree.h" #include "tc/core/polyhedral/scop.h" @@ -27,7 +28,9 @@ namespace polyhedral { // Return the union of the reduction update statements // that appear in "domain". -isl::union_set reductionUpdates(isl::union_set domain, const Scop& scop); +isl::UnionSet reductionUpdates( + isl::union_set domain, + const Scop& scop); // Does "prefix" partition "domain" into individual reductions? // In particular, do the elements of "domain" access a single tensor From 9ec451d890870ef18bf0532714145d9bb30ba416 Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Thu, 21 Jun 2018 12:05:24 +0200 Subject: [PATCH 049/102] isSingleReductionWithin: use templated isl types An explicit cast is introduced in MappedScop::detectReductions, which will be removed after the schedule tree has been converted to templated isl types. --- tc/core/polyhedral/cuda/mapped_scop.cc | 2 +- tc/core/polyhedral/schedule_tree_matcher-inl.h | 8 +++++--- tc/core/polyhedral/schedule_tree_matcher.h | 5 +++-- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/tc/core/polyhedral/cuda/mapped_scop.cc b/tc/core/polyhedral/cuda/mapped_scop.cc index a406c195a..f503c84ad 100644 --- a/tc/core/polyhedral/cuda/mapped_scop.cc +++ b/tc/core/polyhedral/cuda/mapped_scop.cc @@ -285,7 +285,7 @@ bool MappedScop::detectReductions(ScheduleTree* tree) { // a single reduction for now. // Support for multiple reductions would require a check // that these reductions do not interfere with each other. - auto domain = band->mupa_.domain(); + auto domain = isl::UnionSet(band->mupa_.domain()); auto updates = reductionUpdates(domain, scop()); if (updates.n_set() != 1) { return false; diff --git a/tc/core/polyhedral/schedule_tree_matcher-inl.h b/tc/core/polyhedral/schedule_tree_matcher-inl.h index 8a2b2196c..1a83746cd 100644 --- a/tc/core/polyhedral/schedule_tree_matcher-inl.h +++ b/tc/core/polyhedral/schedule_tree_matcher-inl.h @@ -16,6 +16,7 @@ #pragma once #include "tc/core/check.h" +#include "tc/core/polyhedral/domain_types.h" #include "tc/core/polyhedral/schedule_tree.h" #include "tc/core/polyhedral/schedule_tree_elem.h" @@ -291,13 +292,14 @@ inline std::vector match( return matchDFSPreorder(matcher, tree); } +template inline bool isSingleReductionWithin( - isl::union_set domain, - isl::multi_union_pw_aff prefix, + isl::UnionSet domain, + isl::MultiUnionPwAff prefix, const Scop& scop) { auto reductions = scop.body.reductions; reductions = reductions.intersect_domain(domain); - auto prefixMap = isl::union_map::from(prefix); + auto prefixMap = prefix.toUnionMap(); auto prefixToReduction = reductions.apply_domain(prefixMap); return prefixToReduction.is_single_valued(); } diff --git a/tc/core/polyhedral/schedule_tree_matcher.h b/tc/core/polyhedral/schedule_tree_matcher.h index 173cfee95..9827c0b80 100644 --- a/tc/core/polyhedral/schedule_tree_matcher.h +++ b/tc/core/polyhedral/schedule_tree_matcher.h @@ -35,9 +35,10 @@ isl::UnionSet reductionUpdates( // Does "prefix" partition "domain" into individual reductions? // In particular, do the elements of "domain" access a single tensor // element within "prefix"? +template bool isSingleReductionWithin( - isl::union_set domain, - isl::multi_union_pw_aff prefix, + isl::UnionSet domain, + isl::MultiUnionPwAff prefix, const Scop& scop); } // namespace polyhedral From 1c3f269cd450dcad45a6bc153da9089e80a12a48 Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Thu, 21 Jun 2018 12:05:24 +0200 Subject: [PATCH 050/102] Body: use templated isl types --- tc/core/polyhedral/body.h | 11 +++++++---- tc/core/polyhedral/reduction_matcher.cc | 8 ++++---- tc/core/polyhedral/schedule_tree_matcher.h | 2 +- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/tc/core/polyhedral/body.h b/tc/core/polyhedral/body.h index 7461a5cc9..7186cacdd 100644 --- a/tc/core/polyhedral/body.h +++ b/tc/core/polyhedral/body.h @@ -17,6 +17,7 @@ #include +#include "tc/core/polyhedral/domain_types.h" #include "tc/external/isl.h" namespace tc { @@ -26,11 +27,13 @@ namespace polyhedral { struct Body { Body() = default; Body(isl::space paramSpace) { - reductions = writes = reads = isl::union_map::empty(paramSpace); + auto empty = isl::union_map::empty(paramSpace); + writes = reads = isl::UnionMap, Tensor>(empty); + reductions = isl::UnionMap(empty); } // Specialize to the given context. - void specialize(isl::set context) { + void specialize(isl::Set<> context) { reads = reads.intersect_params(context); writes = writes.intersect_params(context); reductions = reductions.intersect_params(context); @@ -39,7 +42,7 @@ struct Body { // Union maps describing the reads and writes done. Uses the ids in // the schedule tree to denote the containing Stmt, and tags each // access with a unique reference id of the form __tc_ref_N. - isl::union_map reads, writes; + isl::UnionMap, Tensor> reads, writes; // A function on reduction update statement instances that partitions them // into individual reductions, where each reduction consists of @@ -73,7 +76,7 @@ struct Body { // That is, in the example above, it would just be // // { S[i] -> R[] : 0 <= i < 4 } - isl::union_map reductions; + isl::UnionMap reductions; }; std::ostream& operator<<(std::ostream& os, const Body& body); diff --git a/tc/core/polyhedral/reduction_matcher.cc b/tc/core/polyhedral/reduction_matcher.cc index 64efc852b..318e9bd6f 100644 --- a/tc/core/polyhedral/reduction_matcher.cc +++ b/tc/core/polyhedral/reduction_matcher.cc @@ -56,17 +56,17 @@ bool isSupportedReductionUpdateId(isl::id id, const Scop& scop) { } // namespace isl::UnionSet reductionUpdates( - isl::union_set domain, + isl::UnionSet domain, const Scop& scop) { domain = scop.body.reductions.intersect_domain(domain).domain(); - auto update = isl::union_set::empty(domain.get_space()); - domain.foreach_set([&update, &scop](isl::set set) { + auto update = isl::UnionSet::empty(domain.get_space()); + domain.foreach_set([&update, &scop](isl::Set set) { auto setId = set.get_tuple_id(); if (isSupportedReductionUpdateId(setId, scop)) { update = update.unite(set); } }); - return isl::UnionSet(update); + return update; } } // namespace polyhedral diff --git a/tc/core/polyhedral/schedule_tree_matcher.h b/tc/core/polyhedral/schedule_tree_matcher.h index 9827c0b80..8b51f9ce9 100644 --- a/tc/core/polyhedral/schedule_tree_matcher.h +++ b/tc/core/polyhedral/schedule_tree_matcher.h @@ -29,7 +29,7 @@ namespace polyhedral { // Return the union of the reduction update statements // that appear in "domain". isl::UnionSet reductionUpdates( - isl::union_set domain, + isl::UnionSet domain, const Scop& scop); // Does "prefix" partition "domain" into individual reductions? From 5c0c100ee4f4f7d006edf3d7825413714edeb199 Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Thu, 21 Jun 2018 12:05:24 +0200 Subject: [PATCH 051/102] reductionMapSchedule: use templated isl types --- tc/core/polyhedral/cuda/mapped_scop.cc | 6 +++--- tc/core/polyhedral/cuda/mapped_scop.h | 4 +++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/tc/core/polyhedral/cuda/mapped_scop.cc b/tc/core/polyhedral/cuda/mapped_scop.cc index f503c84ad..6ce5993b2 100644 --- a/tc/core/polyhedral/cuda/mapped_scop.cc +++ b/tc/core/polyhedral/cuda/mapped_scop.cc @@ -319,8 +319,8 @@ bool MappedScop::needReductionSeparation(const ScheduleTree* st) { return !reductionBandUpdates_.at(st).separated; } -isl::multi_union_pw_aff MappedScop::reductionMapSchedule( - const ScheduleTree* st) { +isl::MultiUnionPwAff +MappedScop::reductionMapSchedule(const ScheduleTree* st) { TC_CHECK(reductionBandUpdates_.count(st) == 1); auto reductionBand = st->as(); TC_CHECK(reductionBand); @@ -345,7 +345,7 @@ ScheduleTree* MappedScop::separateReduction(ScheduleTree* st) { auto prefixSchedule = prefixScheduleMupa(root, st); auto reductionSchedule = reductionMapSchedule(st); auto space = reductionSchedule.get_space(); - auto size = isl::multi_val::zero(space); + auto size = isl::MultiVal::zero(space); for (size_t i = 0; i < numThreads.view.size(); ++i) { auto pos = numThreads.view.size() - 1 - i; size = size.set_val(pos, isl::val(st->ctx_, numThreads.view[i])); diff --git a/tc/core/polyhedral/cuda/mapped_scop.h b/tc/core/polyhedral/cuda/mapped_scop.h index 47aef39c6..37c5426e0 100644 --- a/tc/core/polyhedral/cuda/mapped_scop.h +++ b/tc/core/polyhedral/cuda/mapped_scop.h @@ -24,6 +24,7 @@ #include "tc/core/cuda/cuda_mapping_options.h" #include "tc/core/polyhedral/cuda/mapping_types.h" #include "tc/core/polyhedral/cuda/memory_promotion_heuristic.h" +#include "tc/core/polyhedral/domain_types.h" #include "tc/core/polyhedral/scop.h" #include "tc/core/tensor.h" #include "tc/external/isl.h" @@ -171,7 +172,8 @@ class MappedScop { // Return the schedule that will be used by mapInnermostBandsToThreads // for mapping to thread identifiers, with the last function // corresponding to thread identifier x. - isl::multi_union_pw_aff reductionMapSchedule(const detail::ScheduleTree* st); + isl::MultiUnionPwAff reductionMapSchedule( + const detail::ScheduleTree* st); // Separate out reductions that can be mapped to an entire block. // The remaining parts, if any, are no longer considered for replacement // by a library call. From cba1479400ccbe95cd2db726a8134ab42dee8e69 Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Thu, 21 Jun 2018 12:05:24 +0200 Subject: [PATCH 052/102] separatedOut: use templated isl types --- tc/core/polyhedral/cuda/mapped_scop.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tc/core/polyhedral/cuda/mapped_scop.cc b/tc/core/polyhedral/cuda/mapped_scop.cc index 6ce5993b2..bdafd9900 100644 --- a/tc/core/polyhedral/cuda/mapped_scop.cc +++ b/tc/core/polyhedral/cuda/mapped_scop.cc @@ -226,7 +226,10 @@ void fixThreadsBelow(MappedScop& mscop, ScheduleTree* tree, size_t begin) { * Anything that depends on an update statement is ordered after * the update statements. Anything else is ordered before. */ -bool separatedOut(Scop& scop, ScheduleTree* tree, isl::union_set updates) { +bool separatedOut( + Scop& scop, + ScheduleTree* tree, + isl::UnionSet updates) { auto domain = activeDomainPoints(scop.scheduleRoot(), tree); auto other = domain.subtract(updates); if (other.is_empty()) { From 9e51b3760a43c58c976222ee62d3c8e0c23a025d Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Thu, 21 Jun 2018 12:05:24 +0200 Subject: [PATCH 053/102] constructThreadToWarp: use templated isl types --- tc/core/polyhedral/cuda/mapped_scop.cc | 15 ++++++++------- tc/core/polyhedral/domain_types.h | 2 ++ 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/tc/core/polyhedral/cuda/mapped_scop.cc b/tc/core/polyhedral/cuda/mapped_scop.cc index bdafd9900..35523d0db 100644 --- a/tc/core/polyhedral/cuda/mapped_scop.cc +++ b/tc/core/polyhedral/cuda/mapped_scop.cc @@ -505,18 +505,19 @@ constexpr auto kWarp = "warp"; * (of size "warpSize") to a warp identifier, * based on the thread sizes s_x, s_y up to s_z in "block". */ -isl::multi_aff constructThreadToWarp( +isl::MultiAff constructThreadToWarp( isl::ctx ctx, const unsigned warpSize, const Block& block) { - auto space = isl::space(ctx, 0); + auto space = isl::Space<>(ctx, 0); auto id = isl::id(ctx, kBlock); - auto blockSpace = space.add_named_tuple_id_ui(id, block.view.size()); - auto warpSpace = space.add_named_tuple_id_ui(isl::id(ctx, kWarp), 1); - auto aff = isl::aff::zero_on_domain(blockSpace); + auto blockSpace = space.add_named_tuple_id_ui(id, block.view.size()); + auto warpSpace = space.add_named_tuple_id_ui(isl::id(ctx, kWarp), 1); + auto aff = isl::AffOn::zero_on_domain(blockSpace); auto nThread = block.view.size(); - auto identity = isl::multi_aff::identity(blockSpace.map_from_set()); + auto identity = + isl::MultiAff::identity(blockSpace.map_from_set()); for (int i = nThread - 1; i >= 0; --i) { aff = aff.scale(isl::val(ctx, block.view[i])); aff = aff.add(identity.get_aff(i)); @@ -524,7 +525,7 @@ isl::multi_aff constructThreadToWarp( aff = aff.scale_down(isl::val(ctx, warpSize)).floor(); auto mapSpace = blockSpace.product(warpSpace).unwrap(); - return isl::multi_aff(mapSpace, isl::aff_list(aff)); + return isl::MultiAff(mapSpace, aff.asAffList()); } } // namespace diff --git a/tc/core/polyhedral/domain_types.h b/tc/core/polyhedral/domain_types.h index 9fba84e32..b627e53eb 100644 --- a/tc/core/polyhedral/domain_types.h +++ b/tc/core/polyhedral/domain_types.h @@ -8,6 +8,8 @@ struct ReductionSchedule; struct Statement; struct Tag; struct Tensor; +struct Thread; +struct Warp; } // namespace polyhedral } // namespace tc From baf7371d0f66d9c86e8ba35b011c1c4ca59ab7a1 Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Thu, 21 Jun 2018 12:05:24 +0200 Subject: [PATCH 054/102] prefixSchedule: use templated isl types An explicit cast is introduced in prefixSchedule, which will be removed after the schedule tree has been converted to templated isl types. Automatic type deduction is temporarily turned off in collectDomain and unroll to avoid having to convert these entire functions together with prefixSchedule. It will be reintroduced when the schedule tree is converted to templated isl types. --- tc/core/polyhedral/cuda/memory_promotion_heuristic.cc | 2 +- tc/core/polyhedral/schedule_utils-inl.h | 6 ++++-- tc/core/polyhedral/schedule_utils.cc | 2 +- tc/core/polyhedral/schedule_utils.h | 3 ++- tc/core/polyhedral/unroll.cc | 2 +- 5 files changed, 9 insertions(+), 6 deletions(-) diff --git a/tc/core/polyhedral/cuda/memory_promotion_heuristic.cc b/tc/core/polyhedral/cuda/memory_promotion_heuristic.cc index f44ab4251..3dc7dbf2b 100644 --- a/tc/core/polyhedral/cuda/memory_promotion_heuristic.cc +++ b/tc/core/polyhedral/cuda/memory_promotion_heuristic.cc @@ -226,7 +226,7 @@ bool promotionImprovesCoalescing( auto depth = marker->scheduleDepth(root); auto activePoints = activeDomainPoints(root, mapping); auto localAccesses = originalAccesses.intersect_domain(activePoints); - auto schedule = prefixSchedule(root, marker); + auto schedule = prefixSchedule(root, marker); auto scheduledAccesses = localAccesses.apply_domain(schedule); for (auto access : scheduledAccesses.get_map_list()) { auto scheduleSpace = access.get_space().domain(); diff --git a/tc/core/polyhedral/schedule_utils-inl.h b/tc/core/polyhedral/schedule_utils-inl.h index 6f868c70c..4e9d5e026 100644 --- a/tc/core/polyhedral/schedule_utils-inl.h +++ b/tc/core/polyhedral/schedule_utils-inl.h @@ -73,10 +73,12 @@ inline isl::union_map partialScheduleImpl( } } // namespace detail -inline isl::union_map prefixSchedule( +template +inline isl::UnionMap prefixSchedule( const detail::ScheduleTree* root, const detail::ScheduleTree* node) { - return detail::partialScheduleImpl(root, node, false); + auto prefix = detail::partialScheduleImpl(root, node, false); + return isl::UnionMap(prefix); } inline isl::union_map partialSchedule( diff --git a/tc/core/polyhedral/schedule_utils.cc b/tc/core/polyhedral/schedule_utils.cc index 1b5da0dfe..6ff67fa95 100644 --- a/tc/core/polyhedral/schedule_utils.cc +++ b/tc/core/polyhedral/schedule_utils.cc @@ -67,7 +67,7 @@ isl::union_set collectDomain( for (auto anc : nodes) { domain = filter(domain, anc); if (auto extensionElem = anc->as()) { - auto parentSchedule = prefixSchedule(root, anc); + isl::union_map parentSchedule = prefixSchedule(root, anc); auto extension = extensionElem->extension_; TC_CHECK(parentSchedule) << "missing root domain node"; parentSchedule = parentSchedule.intersect_domain(domain); diff --git a/tc/core/polyhedral/schedule_utils.h b/tc/core/polyhedral/schedule_utils.h index 36e77fd40..a734e66a6 100644 --- a/tc/core/polyhedral/schedule_utils.h +++ b/tc/core/polyhedral/schedule_utils.h @@ -58,7 +58,8 @@ isl::union_map partialSchedule( const detail::ScheduleTree* node); // Return the schedule defined by the ancestors of the given node. -isl::union_map prefixSchedule( +template +isl::UnionMap prefixSchedule( const detail::ScheduleTree* root, const detail::ScheduleTree* node); diff --git a/tc/core/polyhedral/unroll.cc b/tc/core/polyhedral/unroll.cc index e90e78f16..916253c27 100644 --- a/tc/core/polyhedral/unroll.cc +++ b/tc/core/polyhedral/unroll.cc @@ -184,7 +184,7 @@ void markUnroll( } auto unrollVal = isl::val(st->ctx_, unroll); - auto prefix = prefixSchedule(root, st); + isl::union_map prefix = prefixSchedule(root, st); prefix = prefix.intersect_domain(prefixMappingFilter(root, st)); boundInstancesAndMarkUnroll(st, prefix, unrollVal); } From cedd9417bdbb43d548998f9f7396d36d5b934a16 Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Thu, 21 Jun 2018 12:05:24 +0200 Subject: [PATCH 055/102] labelExtension: use templated isl types --- tc/core/polyhedral/schedule_transforms.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tc/core/polyhedral/schedule_transforms.cc b/tc/core/polyhedral/schedule_transforms.cc index 082235496..4f2700b15 100644 --- a/tc/core/polyhedral/schedule_transforms.cc +++ b/tc/core/polyhedral/schedule_transforms.cc @@ -362,12 +362,13 @@ detail::ScheduleTree* insertEmptyExtensionAbove( * Construct an extension map for a zero-dimensional statement * with the given identifier. */ -isl::map labelExtension(ScheduleTree* root, ScheduleTree* tree, isl::id id) { +isl::Map +labelExtension(ScheduleTree* root, ScheduleTree* tree, isl::id id) { auto prefix = prefixScheduleMupa(root, tree); auto scheduleSpace = prefix.get_space(); auto space = scheduleSpace.params().add_named_tuple_id_ui(id, 0); auto extensionSpace = scheduleSpace.map_from_domain_and_range(space); - return isl::map::universe(extensionSpace); + return isl::Map::universe(extensionSpace); } /* From d48d6357ec710df01ef1866ed297663db8306f69 Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Thu, 21 Jun 2018 12:05:24 +0200 Subject: [PATCH 056/102] labelFilterFromExtension: use templated isl types --- tc/core/polyhedral/schedule_transforms.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tc/core/polyhedral/schedule_transforms.cc b/tc/core/polyhedral/schedule_transforms.cc index 4f2700b15..bd054cfd2 100644 --- a/tc/core/polyhedral/schedule_transforms.cc +++ b/tc/core/polyhedral/schedule_transforms.cc @@ -375,7 +375,8 @@ labelExtension(ScheduleTree* root, ScheduleTree* tree, isl::id id) { * Construct a filter node for a zero-dimensional extension statement * with the given extension map. */ -ScheduleTreeUPtr labelFilterFromExtension(isl::map extension) { +ScheduleTreeUPtr labelFilterFromExtension( + isl::Map extension) { return detail::ScheduleTree::makeFilter(extension.range()); } From fe17582de044bb6e7f5241da9671fcdd76399925 Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Thu, 21 Jun 2018 12:05:24 +0200 Subject: [PATCH 057/102] findCorePositions: use templated isl types --- tc/core/polyhedral/schedule_isl_conversion.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tc/core/polyhedral/schedule_isl_conversion.cc b/tc/core/polyhedral/schedule_isl_conversion.cc index 2b01979b9..505dc6acc 100644 --- a/tc/core/polyhedral/schedule_isl_conversion.cc +++ b/tc/core/polyhedral/schedule_isl_conversion.cc @@ -23,6 +23,7 @@ #include "tc/core/check.h" #include "tc/core/flags.h" +#include "tc/core/polyhedral/domain_types.h" #include "tc/core/polyhedral/schedule_transforms.h" #include "tc/external/isl.h" @@ -81,7 +82,7 @@ isl::schedule_node insertBranch( */ std::vector findCorePositions( const ScheduleTree* st, - isl::union_set domain) { + isl::UnionSet domain) { std::vector positions; TC_CHECK(st->as()); for (size_t i = 0; i < st->numChildren(); ++i) { @@ -125,7 +126,7 @@ isl::schedule_node insertExtension( isl::schedule_node node, const ScheduleTree* st) { auto depth0 = node.get_tree_depth(); - auto domain = node.get_universe_domain(); + auto domain = isl::UnionSet(node.get_universe_domain()); auto child = st->child({0}); auto corePos = findCorePositions(child, domain); TC_CHECK(!corePos.empty()); From 77722246a60ca6db113c70c77bf925077f06b31e Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Thu, 21 Jun 2018 12:05:24 +0200 Subject: [PATCH 058/102] partialSchedule: use templated isl types An explicit cast is introduced in partialSchedule, which will be removed after the schedule tree has been converted to templated isl types. Automatic type deduction is temporarily turned off in promoteToSharedBelow and promoteToRegistersBelow to avoid having to convert these entire functions together with partialSchedule. It will be reintroduced when collectMappingsTo is converted to templated isl types. --- tc/core/polyhedral/cuda/memory_promotion_heuristic.cc | 4 ++-- tc/core/polyhedral/schedule_utils-inl.h | 6 ++++-- tc/core/polyhedral/schedule_utils.h | 3 ++- tc/core/polyhedral/scop.cc | 2 +- test/test_cuda_mapper_memory_promotion.cc | 6 +++--- 5 files changed, 12 insertions(+), 9 deletions(-) diff --git a/tc/core/polyhedral/cuda/memory_promotion_heuristic.cc b/tc/core/polyhedral/cuda/memory_promotion_heuristic.cc index 3dc7dbf2b..5a9ba792f 100644 --- a/tc/core/polyhedral/cuda/memory_promotion_heuristic.cc +++ b/tc/core/polyhedral/cuda/memory_promotion_heuristic.cc @@ -472,7 +472,7 @@ void promoteToSharedBelow( throw promotion::IncorrectScope("cannot promote below a sequence/set node"); } - auto partialSched = partialSchedule(root, node); + isl::union_map partialSched = partialSchedule(root, node); auto mapping = collectMappingsTo(scop); auto groupMap = TensorReferenceGroup::accessedWithin( @@ -646,7 +646,7 @@ void promoteToRegistersBelow(MappedScop& mscop, detail::ScheduleTree* scope) { auto blockMapping = collectMappingsTo(scop); auto mapping = collectMappingsTo(scop).intersect(blockMapping); - auto schedule = partialSchedule(scop.scheduleRoot(), scope); + isl::union_map schedule = partialSchedule(scop.scheduleRoot(), scope); auto groupMap = TensorReferenceGroup::accessedWithin( schedule.intersect_domain(mapping), scop.body); diff --git a/tc/core/polyhedral/schedule_utils-inl.h b/tc/core/polyhedral/schedule_utils-inl.h index 4e9d5e026..bacb9ccc4 100644 --- a/tc/core/polyhedral/schedule_utils-inl.h +++ b/tc/core/polyhedral/schedule_utils-inl.h @@ -81,10 +81,12 @@ inline isl::UnionMap prefixSchedule( return isl::UnionMap(prefix); } -inline isl::union_map partialSchedule( +template +inline isl::UnionMap partialSchedule( const detail::ScheduleTree* root, const detail::ScheduleTree* node) { - return detail::partialScheduleImpl(root, node, true); + auto prefix = detail::partialScheduleImpl(root, node, true); + return isl::UnionMap(prefix); } namespace detail { diff --git a/tc/core/polyhedral/schedule_utils.h b/tc/core/polyhedral/schedule_utils.h index a734e66a6..989df9da2 100644 --- a/tc/core/polyhedral/schedule_utils.h +++ b/tc/core/polyhedral/schedule_utils.h @@ -53,7 +53,8 @@ isl::union_map extendSchedule( // Get the partial schedule defined by ancestors of the given node and the node // itself. -isl::union_map partialSchedule( +template +isl::UnionMap partialSchedule( const detail::ScheduleTree* root, const detail::ScheduleTree* node); diff --git a/tc/core/polyhedral/scop.cc b/tc/core/polyhedral/scop.cc index 791cb138e..5490a32cb 100644 --- a/tc/core/polyhedral/scop.cc +++ b/tc/core/polyhedral/scop.cc @@ -265,7 +265,7 @@ void Scop::promoteEverythingAt(std::vector pos) { auto tree = scheduleRoot()->child(pos); checkFiltersDisjointStatements(scheduleRoot()); - auto schedule = partialSchedule(root, tree); + auto schedule = partialSchedule(root, tree); auto groupMap = TensorReferenceGroup::accessedWithin(schedule, body); for (auto& p : groupMap) { diff --git a/test/test_cuda_mapper_memory_promotion.cc b/test/test_cuda_mapper_memory_promotion.cc index 0fb7405b8..8cf0bc05f 100644 --- a/test/test_cuda_mapper_memory_promotion.cc +++ b/test/test_cuda_mapper_memory_promotion.cc @@ -64,7 +64,7 @@ class TestMapper : public ::testing::Test { TensorGroups accessedBySubtree( const polyhedral::detail::ScheduleTree* tree, const Scop& scop) { - auto schedule = partialSchedule(scop.scheduleRoot(), tree); + auto schedule = partialSchedule(scop.scheduleRoot(), tree); return TensorReferenceGroup::accessedWithin(schedule, scop.body); } }; @@ -309,7 +309,7 @@ def fun(float(N, M) A, float(N, M) B) -> (C) { EXPECT_EQ( np, std::min(tile1, problemSize1) * std::min(tile2, problemSize2)); - auto schedule = partialSchedule( + auto schedule = partialSchedule( scop.scheduleRoot(), scop.scheduleRoot()->child(childPos)); auto scopedAccess = oneGroup->originalAccesses().apply_domain(schedule); TC_CHECK(scopedAccess.is_equal(oneGroup->scopedAccesses())) @@ -376,7 +376,7 @@ def fun(float(N, M) A) -> (B, C) { auto active = activeDomainPoints(scop.scheduleRoot(), t); LOG(INFO) << "Active: " << active; - auto schedule = partialSchedule(scop.scheduleRoot(), t); + auto schedule = partialSchedule(scop.scheduleRoot(), t); auto scopedAccess = groupsB[0]->originalAccesses().apply_domain(schedule); TC_CHECK(scopedAccess.is_equal(groupsB[0]->scopedAccesses())) << "expected original accesses " << groupsB[0]->originalAccesses() From b567e9857f93fae0f015570bbebca5a1d8ac9dd5 Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Wed, 1 Aug 2018 17:05:38 +0200 Subject: [PATCH 059/102] ScheduleTree::makeMappingUnsafe: explicitly cast mapping This will make it easier to gradually introduce the use of templated isl types by breaking a cycle. The explicit cast will be removed again when makeMapping is converted to templated isl types. --- tc/core/polyhedral/schedule_tree.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tc/core/polyhedral/schedule_tree.cc b/tc/core/polyhedral/schedule_tree.cc index c17c2542a..1c7779d8f 100644 --- a/tc/core/polyhedral/schedule_tree.cc +++ b/tc/core/polyhedral/schedule_tree.cc @@ -30,6 +30,7 @@ #include "tc/core/check.h" #include "tc/core/constants.h" #include "tc/core/functional.h" +#include "tc/core/polyhedral/domain_types.h" #include "tc/core/polyhedral/schedule_tree_elem.h" #include "tc/core/scope_guard.h" #include "tc/external/isl.h" @@ -243,7 +244,8 @@ std::unique_ptr ScheduleTree::makeMappingUnsafe( << "expected as many mapped ids as affs"; ScheduleTreeMapping::Mapping mapping; for (size_t i = 0, n = mappedAffs.size(); i < n; ++i) { - mapping.emplace(mappedIds.at(i), mappedAffs.get_at(i)); + auto aff = isl::UnionPwAffOn(mappedAffs.get_at(i)); + mapping.emplace(mappedIds.at(i), aff); } TC_CHECK_GE(mapping.size(), 1u) << "empty mapping"; TC_CHECK_EQ(mappedIds.size(), mapping.size()) From 58a0b42ebd1664f5938f550cddb19ebc955cd38b Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Thu, 21 Jun 2018 12:05:24 +0200 Subject: [PATCH 060/102] ScheduleTreeMapping::Mapping: use templated isl types --- tc/core/polyhedral/schedule_tree_elem.cc | 3 ++- tc/core/polyhedral/schedule_tree_elem.h | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/tc/core/polyhedral/schedule_tree_elem.cc b/tc/core/polyhedral/schedule_tree_elem.cc index 9cee3ecac..3653d0cf5 100644 --- a/tc/core/polyhedral/schedule_tree_elem.cc +++ b/tc/core/polyhedral/schedule_tree_elem.cc @@ -144,7 +144,8 @@ ScheduleTreeMapping::ScheduleTreeMapping( auto id = kvp.first; // Create mapping filter by equating the // parameter mappedIds[i] to the "i"-th affine function. - upa = upa.sub(isl::union_pw_aff::param_on_domain(domain.universe(), id)); + upa = upa.sub( + isl::UnionPwAffOn::param_on_domain(domain.universe(), id)); filter_ = filter_.intersect(upa.zero_union_set()); } } diff --git a/tc/core/polyhedral/schedule_tree_elem.h b/tc/core/polyhedral/schedule_tree_elem.h index a912fab5c..f32cca862 100644 --- a/tc/core/polyhedral/schedule_tree_elem.h +++ b/tc/core/polyhedral/schedule_tree_elem.h @@ -179,7 +179,7 @@ struct ScheduleTreeMapping : public ScheduleTree { public: using Mapping = std::unordered_map< mapping::MappingId, - isl::union_pw_aff, + isl::UnionPwAffOn, typename mapping::MappingId::Hash>; static constexpr detail::ScheduleTreeType NodeType = From 0585703232677da169894f961d30c5f81994ccc3 Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Thu, 21 Jun 2018 12:05:24 +0200 Subject: [PATCH 061/102] extractDomainToIds: use templated isl types --- tc/core/polyhedral/cuda/mapped_scop.cc | 4 ++-- tc/core/polyhedral/schedule_utils-inl.h | 20 +++++++++++--------- tc/core/polyhedral/schedule_utils.h | 3 ++- 3 files changed, 15 insertions(+), 12 deletions(-) diff --git a/tc/core/polyhedral/cuda/mapped_scop.cc b/tc/core/polyhedral/cuda/mapped_scop.cc index 35523d0db..863e94f6a 100644 --- a/tc/core/polyhedral/cuda/mapped_scop.cc +++ b/tc/core/polyhedral/cuda/mapped_scop.cc @@ -536,7 +536,7 @@ isl::multi_union_pw_aff MappedScop::threadMappingSchedule( ids.emplace_back(mapping::ThreadId::makeId(i)); } auto tupleId = isl::id(tree->ctx_, kBlock); - return extractDomainToIds(scop_->scheduleRoot(), tree, ids, tupleId); + return extractDomainToIds(scop_->scheduleRoot(), tree, ids, tupleId); } isl::multi_union_pw_aff MappedScop::blockMappingSchedule( @@ -546,7 +546,7 @@ isl::multi_union_pw_aff MappedScop::blockMappingSchedule( ids.emplace_back(mapping::BlockId::makeId(i)); } auto tupleId = isl::id(tree->ctx_, kGrid); - return extractDomainToIds(scop_->scheduleRoot(), tree, ids, tupleId); + return extractDomainToIds(scop_->scheduleRoot(), tree, ids, tupleId); } Scop::SyncLevel MappedScop::findBestSync( diff --git a/tc/core/polyhedral/schedule_utils-inl.h b/tc/core/polyhedral/schedule_utils-inl.h index bacb9ccc4..f3eb0efdf 100644 --- a/tc/core/polyhedral/schedule_utils-inl.h +++ b/tc/core/polyhedral/schedule_utils-inl.h @@ -162,22 +162,24 @@ inline isl::MultiUnionPwAff partialScheduleMupa( * are assumed to have been mapped to these identifiers. * The result lives in a space of the form "tupleId"["ids"...]. */ -inline isl::multi_union_pw_aff extractDomainToIds( +template +isl::MultiUnionPwAff extractDomainToIds( const detail::ScheduleTree* root, const detail::ScheduleTree* tree, const std::vector& ids, isl::id tupleId) { using namespace polyhedral::detail; - auto space = isl::space(tree->ctx_, 0); - auto empty = isl::union_set::empty(space); - space = space.add_named_tuple_id_ui(tupleId, ids.size()); - auto zero = isl::multi_val::zero(space); - auto domainToIds = isl::multi_union_pw_aff(empty, zero); + auto paramSpace = isl::Space<>(tree->ctx_, 0); + auto empty = isl::UnionSet::empty(paramSpace); + auto space = + paramSpace.add_named_tuple_id_ui(tupleId, ids.size()); + auto zero = isl::MultiVal::zero(space); + auto domainToIds = isl::MultiUnionPwAff(empty, zero); for (auto mapping : tree->collect(tree, ScheduleTreeType::Mapping)) { auto mappingNode = mapping->as(); - auto list = isl::union_pw_aff_list(tree->ctx_, ids.size()); + auto list = isl::UnionPwAffListOn(tree->ctx_, ids.size()); for (auto id : ids) { if (mappingNode->mapping.count(id) == 0) { break; @@ -189,8 +191,8 @@ inline isl::multi_union_pw_aff extractDomainToIds( if (static_cast(list.size()) != ids.size()) { continue; } - auto nodeToIds = isl::multi_union_pw_aff(space, list); - auto active = activeDomainPoints(root, mapping); + auto nodeToIds = isl::MultiUnionPwAff(space, list); + auto active = isl::UnionSet(activeDomainPoints(root, mapping)); TC_CHECK(active.intersect(domainToIds.domain()).is_empty()) << "conflicting mappings; are the filters in the tree disjoint?"; nodeToIds = nodeToIds.intersect_domain(active); diff --git a/tc/core/polyhedral/schedule_utils.h b/tc/core/polyhedral/schedule_utils.h index 989df9da2..2b5829412 100644 --- a/tc/core/polyhedral/schedule_utils.h +++ b/tc/core/polyhedral/schedule_utils.h @@ -121,7 +121,8 @@ isl::union_set prefixMappingFilter( // rooted at "root") to identifiers "ids", where all branches in "tree" are // assumed to have been mapped to these identifiers. The result lives in a // space of the form "tupleId"["ids"...]. -isl::multi_union_pw_aff extractDomainToIds( +template +isl::MultiUnionPwAff extractDomainToIds( const detail::ScheduleTree* root, const detail::ScheduleTree* tree, const std::vector& ids, From fe907e5fccd5bdb7d4d9bd0e09247bf85d1b2c43 Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Thu, 21 Jun 2018 12:05:24 +0200 Subject: [PATCH 062/102] MappedScop::threadMappingSchedule: use templated isl types --- tc/core/polyhedral/cuda/mapped_scop.cc | 2 +- tc/core/polyhedral/cuda/mapped_scop.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tc/core/polyhedral/cuda/mapped_scop.cc b/tc/core/polyhedral/cuda/mapped_scop.cc index 863e94f6a..721c1ec83 100644 --- a/tc/core/polyhedral/cuda/mapped_scop.cc +++ b/tc/core/polyhedral/cuda/mapped_scop.cc @@ -529,7 +529,7 @@ isl::MultiAff constructThreadToWarp( } } // namespace -isl::multi_union_pw_aff MappedScop::threadMappingSchedule( +isl::MultiUnionPwAff MappedScop::threadMappingSchedule( const ScheduleTree* tree) const { std::vector ids; for (size_t i = 0; i < numThreads.view.size(); ++i) { diff --git a/tc/core/polyhedral/cuda/mapped_scop.h b/tc/core/polyhedral/cuda/mapped_scop.h index 37c5426e0..0da838973 100644 --- a/tc/core/polyhedral/cuda/mapped_scop.h +++ b/tc/core/polyhedral/cuda/mapped_scop.h @@ -210,7 +210,7 @@ class MappedScop { // to the thread identifiers, where all branches in "tree" // are assumed to have been mapped to thread identifiers. // The result lives in a space of the form block[x, ...]. - isl::multi_union_pw_aff threadMappingSchedule( + isl::MultiUnionPwAff threadMappingSchedule( const detail::ScheduleTree* tree) const; // Extract a mapping from the domain elements active at "tree" From 3cb83a77f7329e9453230f4fe85bac4ca7d80d4e Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Thu, 21 Jun 2018 12:05:24 +0200 Subject: [PATCH 063/102] MappedScop::blockMappingSchedule: use templated isl types --- tc/core/polyhedral/cuda/mapped_scop.cc | 2 +- tc/core/polyhedral/cuda/mapped_scop.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tc/core/polyhedral/cuda/mapped_scop.cc b/tc/core/polyhedral/cuda/mapped_scop.cc index 721c1ec83..16a500010 100644 --- a/tc/core/polyhedral/cuda/mapped_scop.cc +++ b/tc/core/polyhedral/cuda/mapped_scop.cc @@ -539,7 +539,7 @@ isl::MultiUnionPwAff MappedScop::threadMappingSchedule( return extractDomainToIds(scop_->scheduleRoot(), tree, ids, tupleId); } -isl::multi_union_pw_aff MappedScop::blockMappingSchedule( +isl::MultiUnionPwAff MappedScop::blockMappingSchedule( const ScheduleTree* tree) const { std::vector ids; for (size_t i = 0; i < numBlocks.view.size(); ++i) { diff --git a/tc/core/polyhedral/cuda/mapped_scop.h b/tc/core/polyhedral/cuda/mapped_scop.h index 0da838973..c971b80e9 100644 --- a/tc/core/polyhedral/cuda/mapped_scop.h +++ b/tc/core/polyhedral/cuda/mapped_scop.h @@ -217,7 +217,7 @@ class MappedScop { // to the block identifiers, where all branches in "tree" // are assumed to have been mapped to block identifiers. // The result lives in a space of the form grid[x, ...]. - isl::multi_union_pw_aff blockMappingSchedule( + isl::MultiUnionPwAff blockMappingSchedule( const detail::ScheduleTree* tree) const; private: From 93988fbf923b0bbbd52dd3f8345ad3a84d5fe2d5 Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Thu, 21 Jun 2018 12:05:24 +0200 Subject: [PATCH 064/102] Scop::makeIslAffFromStmtExpr: use templated isl types --- tc/core/polyhedral/scop.cc | 10 +++++----- tc/core/polyhedral/scop.h | 4 +++- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/tc/core/polyhedral/scop.cc b/tc/core/polyhedral/scop.cc index 5490a32cb..e8ac4c0e1 100644 --- a/tc/core/polyhedral/scop.cc +++ b/tc/core/polyhedral/scop.cc @@ -516,12 +516,12 @@ const Halide::OutputImageParam& Scop::findArgument(isl::id id) const { return *halide.inputs.begin(); } -isl::aff Scop::makeIslAffFromStmtExpr(isl::id stmtId, const Halide::Expr& e) - const { +isl::AffOn Scop::makeIslAffFromStmtExpr( + isl::id stmtId, + const Halide::Expr& e) const { auto domain = halide.domains.at(stmtId); - isl::aff aff = halide2isl::makeIslAffFromExpr(domain.paramSpace, e); - aff = aff.unbind_params_insert_domain(domain.tuple); - return aff; + auto aff = halide2isl::makeIslAffFromExpr(domain.paramSpace, e); + return aff.unbind_params_insert_domain(domain.tuple); } } // namespace polyhedral diff --git a/tc/core/polyhedral/scop.h b/tc/core/polyhedral/scop.h index dd463be9f..25f8b6879 100644 --- a/tc/core/polyhedral/scop.h +++ b/tc/core/polyhedral/scop.h @@ -422,7 +422,9 @@ struct Scop { // Return a null isl::aff if the expression is not affine. Fail if any // of the variables does not correspond to a parameter or // an instance identifier of the statement. - isl::aff makeIslAffFromStmtExpr(isl::id stmtId, const Halide::Expr& e) const; + isl::AffOn makeIslAffFromStmtExpr( + isl::id stmtId, + const Halide::Expr& e) const; // Promote a tensor reference group to a storage of a given "kind", // inserting the copy From 11a55735dc0e38e50ea4c9370a4b5e7a3edea96a Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Thu, 21 Jun 2018 12:05:24 +0200 Subject: [PATCH 065/102] activeDomainPoints: cast result to templated isl type At the same time, turn off automatic type deduction in the callers of activeDomainPoints. This allows these callers to gradually move to templated isl types. The cast itself is removed after the schedule tree has been converted to templated isl types. --- tc/core/polyhedral/cuda/mapped_scop.cc | 4 ++-- tc/core/polyhedral/schedule_transforms.cc | 12 ++++++++---- tc/core/polyhedral/schedule_utils-inl.h | 2 +- tc/core/polyhedral/schedule_utils.cc | 5 +++-- tc/core/polyhedral/schedule_utils.h | 2 +- 5 files changed, 15 insertions(+), 10 deletions(-) diff --git a/tc/core/polyhedral/cuda/mapped_scop.cc b/tc/core/polyhedral/cuda/mapped_scop.cc index 16a500010..df70b7a69 100644 --- a/tc/core/polyhedral/cuda/mapped_scop.cc +++ b/tc/core/polyhedral/cuda/mapped_scop.cc @@ -230,7 +230,7 @@ bool separatedOut( Scop& scop, ScheduleTree* tree, isl::UnionSet updates) { - auto domain = activeDomainPoints(scop.scheduleRoot(), tree); + isl::union_set domain = activeDomainPoints(scop.scheduleRoot(), tree); auto other = domain.subtract(updates); if (other.is_empty()) { return true; @@ -344,7 +344,7 @@ ScheduleTree* MappedScop::separateReduction(ScheduleTree* st) { reductionBandUpdates_.at(reduction).separated = true; auto root = scop_->scheduleRoot(); - auto domain = activeDomainPoints(root, st); + isl::union_set domain = activeDomainPoints(root, st); auto prefixSchedule = prefixScheduleMupa(root, st); auto reductionSchedule = reductionMapSchedule(st); auto space = reductionSchedule.get_space(); diff --git a/tc/core/polyhedral/schedule_transforms.cc b/tc/core/polyhedral/schedule_transforms.cc index bd054cfd2..8fb19387f 100644 --- a/tc/core/polyhedral/schedule_transforms.cc +++ b/tc/core/polyhedral/schedule_transforms.cc @@ -570,7 +570,8 @@ bool canOrderBefore( ScheduleTree* tree, isl::union_set filter, isl::union_map dependences) { - auto other = activeDomainPoints(root, tree).subtract(filter); + isl::union_set active = activeDomainPoints(root, tree); + auto other = active.subtract(filter); return canOrder(filter, other, dependences); } @@ -579,7 +580,8 @@ bool canOrderAfter( ScheduleTree* tree, isl::union_set filter, isl::union_map dependences) { - auto other = activeDomainPoints(root, tree).subtract(filter); + isl::union_set active = activeDomainPoints(root, tree); + auto other = active.subtract(filter); return canOrder(other, filter, dependences); } @@ -587,7 +589,8 @@ void orderBefore( ScheduleTree* root, ScheduleTree* tree, isl::union_set filter) { - auto other = activeDomainPoints(root, tree).subtract(filter); + isl::union_set active = activeDomainPoints(root, tree); + auto other = active.subtract(filter); auto seq = ScheduleTree::makeSequence( gistedFilter(filter, ScheduleTree::makeScheduleTree(*tree))); auto parent = tree->ancestor(root, 1); @@ -597,7 +600,8 @@ void orderBefore( } void orderAfter(ScheduleTree* root, ScheduleTree* tree, isl::union_set filter) { - auto other = activeDomainPoints(root, tree).subtract(filter); + isl::union_set active = activeDomainPoints(root, tree); + auto other = active.subtract(filter); auto seq = ScheduleTree::makeSequence( gistedFilter(filter, ScheduleTree::makeScheduleTree(*tree))); auto parent = tree->ancestor(root, 1); diff --git a/tc/core/polyhedral/schedule_utils-inl.h b/tc/core/polyhedral/schedule_utils-inl.h index f3eb0efdf..e3e096144 100644 --- a/tc/core/polyhedral/schedule_utils-inl.h +++ b/tc/core/polyhedral/schedule_utils-inl.h @@ -192,7 +192,7 @@ isl::MultiUnionPwAff extractDomainToIds( continue; } auto nodeToIds = isl::MultiUnionPwAff(space, list); - auto active = isl::UnionSet(activeDomainPoints(root, mapping)); + auto active = activeDomainPoints(root, mapping); TC_CHECK(active.intersect(domainToIds.domain()).is_empty()) << "conflicting mappings; are the filters in the tree disjoint?"; nodeToIds = nodeToIds.intersect_domain(active); diff --git a/tc/core/polyhedral/schedule_utils.cc b/tc/core/polyhedral/schedule_utils.cc index 6ff67fa95..0576231b3 100644 --- a/tc/core/polyhedral/schedule_utils.cc +++ b/tc/core/polyhedral/schedule_utils.cc @@ -93,10 +93,11 @@ isl::union_set prefixMappingFilter( return collectDomain(root, node->ancestors(root), &applyMapping); } -isl::union_set activeDomainPoints( +isl::UnionSet activeDomainPoints( const ScheduleTree* root, const ScheduleTree* node) { - return activeDomainPointsHelper(root, node->ancestors(root)); + return isl::UnionSet( + activeDomainPointsHelper(root, node->ancestors(root))); } isl::union_set activeDomainPointsBelow( diff --git a/tc/core/polyhedral/schedule_utils.h b/tc/core/polyhedral/schedule_utils.h index 2b5829412..ac627e1cf 100644 --- a/tc/core/polyhedral/schedule_utils.h +++ b/tc/core/polyhedral/schedule_utils.h @@ -99,7 +99,7 @@ isl::MultiUnionPwAff partialScheduleMupa( // point is active if it was not filtered away on the path from the // root to the node. The root must be a domain element, otherwise no // elements would be considered active. -isl::union_set activeDomainPoints( +isl::UnionSet activeDomainPoints( const detail::ScheduleTree* root, const detail::ScheduleTree* node); From 9a07caa68c76632e14ebec041f78336c6e01bc54 Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Thu, 21 Jun 2018 12:05:24 +0200 Subject: [PATCH 066/102] activeDomainPointsBelow: cast result to templated isl type At the same time, turn off automatic type deduction in the accessSubscriptsAreUnrolledLoops caller of activeDomainPointsBelow. This allows this caller to move to templated isl types separately. The cast itself is removed after the schedule tree has been converted to templated isl types. --- tc/core/polyhedral/cuda/memory_promotion_heuristic.cc | 2 +- tc/core/polyhedral/schedule_utils.cc | 4 ++-- tc/core/polyhedral/schedule_utils.h | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tc/core/polyhedral/cuda/memory_promotion_heuristic.cc b/tc/core/polyhedral/cuda/memory_promotion_heuristic.cc index 5a9ba792f..576e28305 100644 --- a/tc/core/polyhedral/cuda/memory_promotion_heuristic.cc +++ b/tc/core/polyhedral/cuda/memory_promotion_heuristic.cc @@ -312,7 +312,7 @@ bool accessSubscriptsAreUnrolledLoops( for (auto leaf : leaves) { auto ancestors = leaf->ancestors(root); ancestors.push_back(leaf); - auto subdomain = activeDomainPointsBelow(root, leaf); + isl::union_set subdomain = activeDomainPointsBelow(root, leaf); auto unrolledDims = isl::union_pw_aff_list(leaf->ctx_, 1); for (auto node : ancestors) { diff --git a/tc/core/polyhedral/schedule_utils.cc b/tc/core/polyhedral/schedule_utils.cc index 0576231b3..e6b1745cf 100644 --- a/tc/core/polyhedral/schedule_utils.cc +++ b/tc/core/polyhedral/schedule_utils.cc @@ -100,12 +100,12 @@ isl::UnionSet activeDomainPoints( activeDomainPointsHelper(root, node->ancestors(root))); } -isl::union_set activeDomainPointsBelow( +isl::UnionSet activeDomainPointsBelow( const ScheduleTree* root, const ScheduleTree* node) { auto ancestors = node->ancestors(root); ancestors.emplace_back(node); - return activeDomainPointsHelper(root, ancestors); + return isl::UnionSet(activeDomainPointsHelper(root, ancestors)); } vector collectScheduleTreesPath( diff --git a/tc/core/polyhedral/schedule_utils.h b/tc/core/polyhedral/schedule_utils.h index ac627e1cf..f09f8c1b6 100644 --- a/tc/core/polyhedral/schedule_utils.h +++ b/tc/core/polyhedral/schedule_utils.h @@ -107,7 +107,7 @@ isl::UnionSet activeDomainPoints( // point is active if it was not filtered away on the path from the // root to the node. The root must be a domain element, otherwise no // elements would be considered active. -isl::union_set activeDomainPointsBelow( +isl::UnionSet activeDomainPointsBelow( const detail::ScheduleTree* root, const detail::ScheduleTree* node); From 746e9eaf8dcdcd02f1d7f55023aae36866af2db1 Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Thu, 21 Jun 2018 12:05:24 +0200 Subject: [PATCH 067/102] MappedScop::findBestSync: temporarily remove type deduction This allows Scop::dependences to be converted to templated isl types without having to convert MappedScop::findBestSync at the same time. Automatic type deduction will be reintroduced when MappedScop::findBestSync is converted. --- tc/core/polyhedral/cuda/mapped_scop.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tc/core/polyhedral/cuda/mapped_scop.cc b/tc/core/polyhedral/cuda/mapped_scop.cc index df70b7a69..5432a40e2 100644 --- a/tc/core/polyhedral/cuda/mapped_scop.cc +++ b/tc/core/polyhedral/cuda/mapped_scop.cc @@ -560,7 +560,7 @@ Scop::SyncLevel MappedScop::findBestSync( auto activePoints2 = activeDomainPointsBelow(stRoot, st2); // The dependences between the two schedule trees - auto dependences = scop_->dependences; + isl::union_map dependences = scop_->dependences; dependences = dependences.intersect_domain(activePoints1); dependences = dependences.intersect_range(activePoints2); if (dependences.is_empty()) { From 18c298aafc62918b69e7b78c01dd45d4caf0436e Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Thu, 21 Jun 2018 12:05:24 +0200 Subject: [PATCH 068/102] Scop::dependences: use templated isl types --- tc/core/polyhedral/cuda/mapped_scop.cc | 2 +- tc/core/polyhedral/scop.cc | 11 ++++++----- tc/core/polyhedral/scop.h | 5 +++-- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/tc/core/polyhedral/cuda/mapped_scop.cc b/tc/core/polyhedral/cuda/mapped_scop.cc index 5432a40e2..adf52600e 100644 --- a/tc/core/polyhedral/cuda/mapped_scop.cc +++ b/tc/core/polyhedral/cuda/mapped_scop.cc @@ -230,7 +230,7 @@ bool separatedOut( Scop& scop, ScheduleTree* tree, isl::UnionSet updates) { - isl::union_set domain = activeDomainPoints(scop.scheduleRoot(), tree); + auto domain = activeDomainPoints(scop.scheduleRoot(), tree); auto other = domain.subtract(updates); if (other.is_empty()) { return true; diff --git a/tc/core/polyhedral/scop.cc b/tc/core/polyhedral/scop.cc index e8ac4c0e1..2158a1be0 100644 --- a/tc/core/polyhedral/scop.cc +++ b/tc/core/polyhedral/scop.cc @@ -300,11 +300,11 @@ namespace { using namespace tc::polyhedral; -isl::union_map computeDependences( - isl::union_map sources, - isl::union_map sinks, +isl::UnionMap computeDependences( + isl::UnionMap sources, + isl::UnionMap sinks, isl::schedule schedule) { - auto uai = isl::union_access_info(sinks); + auto uai = sinks.asUnionAccessInfo(); uai = uai.set_may_source(sources); uai = uai.set_schedule(schedule); auto flow = uai.compute_flow(); @@ -369,7 +369,8 @@ void Scop::computeAllDependences() { dependences = flowDeps.unite(falseDeps).coalesce(); } -isl::union_map Scop::activeDependences(detail::ScheduleTree* tree) { +isl::UnionMap Scop::activeDependences( + detail::ScheduleTree* tree) { auto prefix = prefixScheduleMupa(scheduleRoot(), tree); auto domain = activeDomainPoints(scheduleRoot(), tree); auto active = dependences; diff --git a/tc/core/polyhedral/scop.h b/tc/core/polyhedral/scop.h index 25f8b6879..d51f16048 100644 --- a/tc/core/polyhedral/scop.h +++ b/tc/core/polyhedral/scop.h @@ -486,7 +486,8 @@ struct Scop { void computeAllDependences(); // Return the set of dependences that are active // at the given position. - isl::union_map activeDependences(detail::ScheduleTree* tree); + isl::UnionMap activeDependences( + detail::ScheduleTree* tree); public: // Halide stuff @@ -518,7 +519,7 @@ struct Scop { Body body; // RAW, WAR, and WAW dependences - isl::union_map dependences; + isl::UnionMap dependences; private: // By analogy with generalized functions, a ScheduleTree is a (piecewise From 77787cf287291a9d11b1e10c69c8f25329374b72 Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Thu, 21 Jun 2018 12:05:24 +0200 Subject: [PATCH 069/102] partialTargetTiles: use templated isl types --- tc/core/CMakeLists.txt | 1 - tc/core/polyhedral/cuda/mapped_scop.cc | 2 +- .../{separation.cc => separation-inl.h} | 24 ++++++++++--------- tc/core/polyhedral/separation.h | 15 ++++++++---- 4 files changed, 24 insertions(+), 18 deletions(-) rename tc/core/polyhedral/{separation.cc => separation-inl.h} (75%) diff --git a/tc/core/CMakeLists.txt b/tc/core/CMakeLists.txt index 8842ff7cf..61ff92d8c 100644 --- a/tc/core/CMakeLists.txt +++ b/tc/core/CMakeLists.txt @@ -32,7 +32,6 @@ add_library( polyhedral/schedule_print.cc polyhedral/schedule_utils.cc polyhedral/scop.cc - polyhedral/separation.cc polyhedral/unroll.cc polyhedral/utils.cc ) diff --git a/tc/core/polyhedral/cuda/mapped_scop.cc b/tc/core/polyhedral/cuda/mapped_scop.cc index adf52600e..623626369 100644 --- a/tc/core/polyhedral/cuda/mapped_scop.cc +++ b/tc/core/polyhedral/cuda/mapped_scop.cc @@ -344,7 +344,7 @@ ScheduleTree* MappedScop::separateReduction(ScheduleTree* st) { reductionBandUpdates_.at(reduction).separated = true; auto root = scop_->scheduleRoot(); - isl::union_set domain = activeDomainPoints(root, st); + auto domain = activeDomainPoints(root, st); auto prefixSchedule = prefixScheduleMupa(root, st); auto reductionSchedule = reductionMapSchedule(st); auto space = reductionSchedule.get_space(); diff --git a/tc/core/polyhedral/separation.cc b/tc/core/polyhedral/separation-inl.h similarity index 75% rename from tc/core/polyhedral/separation.cc rename to tc/core/polyhedral/separation-inl.h index c5d38436e..d9d62c44f 100644 --- a/tc/core/polyhedral/separation.cc +++ b/tc/core/polyhedral/separation-inl.h @@ -13,35 +13,37 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#pragma once -#include "tc/core/polyhedral/separation.h" #include "tc/core/check.h" +#include "tc/core/polyhedral/domain_types.h" #include "tc/external/isl.h" namespace tc { namespace polyhedral { -isl::union_set partialTargetTiles( - isl::union_set domain, - isl::multi_union_pw_aff prefix, - isl::multi_union_pw_aff pretile, - isl::multi_val size) { +template +isl::UnionSet partialTargetTiles( + isl::UnionSet domain, + isl::MultiUnionPwAff prefix, + isl::MultiUnionPwAff pretile, + isl::MultiVal size) { auto space = pretile.get_space(); - auto tile = isl::multi_aff::identity(space.map_from_set()); + auto tile = isl::MultiAff::identity(space.map_from_set()); tile = tile.scale_down(size).floor(); - auto tileMap = isl::map(tile); + auto tileMap = tile.asMap(); // Relation between pairs of elements in the same target tile. - auto sameTile = isl::union_map(tileMap.apply_range(tileMap.reverse())); + auto sameTile = tileMap.apply_range(tileMap.reverse()).asUnionMap(); // Mapping between domain elements and pairs of prefix and target values. // D -> [P -> T] auto schedule = prefix.range_product(pretile); - auto scheduleMap = isl::union_map::from(schedule); + auto scheduleMap = schedule.toUnionMap(); // Mapping between prefix values and target values // for some common domain element // P -> T TC_CHECK(domain.is_subset(scheduleMap.domain())); - auto target = domain.apply(scheduleMap).unwrap(); + auto target = domain.apply(scheduleMap).template unwrap(); // Mapping between prefix values and target values // for some common domain element, extended to complete target tiles. // P -> Tc diff --git a/tc/core/polyhedral/separation.h b/tc/core/polyhedral/separation.h index 668db7c93..a08c8b50d 100644 --- a/tc/core/polyhedral/separation.h +++ b/tc/core/polyhedral/separation.h @@ -15,6 +15,8 @@ */ #pragma once +#include "tc/core/polyhedral/domain_types.h" + #include "tc/external/isl.h" namespace tc { @@ -25,11 +27,14 @@ namespace polyhedral { * Return the elements in "domain" that map to partial tiles * in this space for fixed values of "prefix". */ -isl::union_set partialTargetTiles( - isl::union_set domain, - isl::multi_union_pw_aff prefix, - isl::multi_union_pw_aff pretile, - isl::multi_val size); +template +isl::UnionSet partialTargetTiles( + isl::UnionSet domain, + isl::MultiUnionPwAff prefix, + isl::MultiUnionPwAff pretile, + isl::MultiVal size); } // namespace polyhedral } // namespace tc + +#include "tc/core/polyhedral/separation-inl.h" From cd905a5c19a9265a6c55ed6b0f8f7a8e0ed2767e Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Thu, 21 Jun 2018 12:05:24 +0200 Subject: [PATCH 070/102] canOrder*: use templated isl types --- tc/core/polyhedral/schedule_transforms.cc | 28 ++++++++++++----------- tc/core/polyhedral/schedule_transforms.h | 9 ++++---- 2 files changed, 20 insertions(+), 17 deletions(-) diff --git a/tc/core/polyhedral/schedule_transforms.cc b/tc/core/polyhedral/schedule_transforms.cc index 8fb19387f..a90972294 100644 --- a/tc/core/polyhedral/schedule_transforms.cc +++ b/tc/core/polyhedral/schedule_transforms.cc @@ -31,6 +31,7 @@ #include "tc/core/check.h" #include "tc/core/constants.h" #include "tc/core/functional.h" +#include "tc/core/polyhedral/domain_types.h" #include "tc/core/polyhedral/mapping_types.h" #include "tc/core/polyhedral/schedule_tree_elem.h" #include "tc/core/polyhedral/schedule_tree_matcher.h" @@ -544,19 +545,20 @@ ScheduleTreeUPtr gistedFilter(isl::union_set filter, ScheduleTreeUPtr child) { * without violating any of the (active) "dependences"? */ bool canOrder( - isl::union_set first, - isl::union_set second, - isl::union_map dependences) { + isl::UnionSet first, + isl::UnionSet second, + isl::UnionMap dependences) { if (first.is_empty() || second.is_empty()) { return true; } // Create an ordering schedule function first -> 0; second -> 1. auto ctx = dependences.get_ctx(); - auto space = isl::space(ctx, 0).add_unnamed_tuple_ui(1); - auto zero = isl::multi_val::zero(space); + auto space = isl::Space<>(ctx, 0).add_unnamed_tuple_ui(1); + auto zero = isl::MultiVal::zero(space); auto one = zero.set_val(0, isl::val::one(ctx)); - auto order = isl::multi_union_pw_aff(first, zero); - order = order.union_add(isl::multi_union_pw_aff(second, one)); + auto order = isl::MultiUnionPwAff(first, zero); + order = order.union_add( + isl::MultiUnionPwAff(second, one)); // Check that this ordering preserves all dependences. auto preserved = dependences.lex_lt_at(order).unite(dependences.eq_at(order)); @@ -568,9 +570,9 @@ bool canOrder( bool canOrderBefore( ScheduleTree* root, ScheduleTree* tree, - isl::union_set filter, - isl::union_map dependences) { - isl::union_set active = activeDomainPoints(root, tree); + isl::UnionSet filter, + isl::UnionMap dependences) { + auto active = activeDomainPoints(root, tree); auto other = active.subtract(filter); return canOrder(filter, other, dependences); } @@ -578,9 +580,9 @@ bool canOrderBefore( bool canOrderAfter( ScheduleTree* root, ScheduleTree* tree, - isl::union_set filter, - isl::union_map dependences) { - isl::union_set active = activeDomainPoints(root, tree); + isl::UnionSet filter, + isl::UnionMap dependences) { + auto active = activeDomainPoints(root, tree); auto other = active.subtract(filter); return canOrder(other, filter, dependences); } diff --git a/tc/core/polyhedral/schedule_transforms.h b/tc/core/polyhedral/schedule_transforms.h index add33d7f2..4f743d2c7 100644 --- a/tc/core/polyhedral/schedule_transforms.h +++ b/tc/core/polyhedral/schedule_transforms.h @@ -22,6 +22,7 @@ #include #include "tc/core/functional.h" +#include "tc/core/polyhedral/domain_types.h" #include "tc/core/polyhedral/mapping_types.h" #include "tc/core/polyhedral/options.h" #include "tc/core/polyhedral/schedule_tree.h" @@ -233,16 +234,16 @@ void insertExtensionLabelAfter( bool canOrderBefore( detail::ScheduleTree* root, detail::ScheduleTree* tree, - isl::union_set filter, - isl::union_map dependences); + isl::UnionSet filter, + isl::UnionMap dependences); // Is it possible to order the elements in the given filter // after the other active elements without violating // any of the given dependences? bool canOrderAfter( detail::ScheduleTree* root, detail::ScheduleTree* tree, - isl::union_set filter, - isl::union_map dependences); + isl::UnionSet filter, + isl::UnionMap dependences); // Insert a sequence to ensure that the active domain elements // in the given filter are executed before the other active domain elements. From 00cdedf63e232dd43bdd58960a5b2103ea79b574 Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Thu, 21 Jun 2018 12:05:24 +0200 Subject: [PATCH 071/102] order*: use templated isl types --- tc/core/polyhedral/schedule_transforms.cc | 11 +++++++---- tc/core/polyhedral/schedule_transforms.h | 4 ++-- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/tc/core/polyhedral/schedule_transforms.cc b/tc/core/polyhedral/schedule_transforms.cc index a90972294..c8f4d6f20 100644 --- a/tc/core/polyhedral/schedule_transforms.cc +++ b/tc/core/polyhedral/schedule_transforms.cc @@ -590,8 +590,8 @@ bool canOrderAfter( void orderBefore( ScheduleTree* root, ScheduleTree* tree, - isl::union_set filter) { - isl::union_set active = activeDomainPoints(root, tree); + isl::UnionSet filter) { + auto active = activeDomainPoints(root, tree); auto other = active.subtract(filter); auto seq = ScheduleTree::makeSequence( gistedFilter(filter, ScheduleTree::makeScheduleTree(*tree))); @@ -601,8 +601,11 @@ void orderBefore( parent->insertChild(childPos, std::move(seq)); } -void orderAfter(ScheduleTree* root, ScheduleTree* tree, isl::union_set filter) { - isl::union_set active = activeDomainPoints(root, tree); +void orderAfter( + ScheduleTree* root, + ScheduleTree* tree, + isl::UnionSet filter) { + auto active = activeDomainPoints(root, tree); auto other = active.subtract(filter); auto seq = ScheduleTree::makeSequence( gistedFilter(filter, ScheduleTree::makeScheduleTree(*tree))); diff --git a/tc/core/polyhedral/schedule_transforms.h b/tc/core/polyhedral/schedule_transforms.h index 4f743d2c7..6820792b4 100644 --- a/tc/core/polyhedral/schedule_transforms.h +++ b/tc/core/polyhedral/schedule_transforms.h @@ -250,13 +250,13 @@ bool canOrderAfter( void orderBefore( detail::ScheduleTree* root, detail::ScheduleTree* tree, - isl::union_set filter); + isl::UnionSet filter); // Insert a sequence to ensure that the active domain elements // in the given filter are executed after the other active domain elements. void orderAfter( detail::ScheduleTree* root, detail::ScheduleTree* tree, - isl::union_set filter); + isl::UnionSet filter); } // namespace polyhedral } // namespace tc From 7e088a82c151b16407e9de2e5974ac13c421c8b3 Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Fri, 27 Jul 2018 16:38:16 +0200 Subject: [PATCH 072/102] collectMappingsTo: cast result to templated isl type This allows callers of collectMappingsTo to move to templated isl types. The case will be removed after the schedule tree has been converted to templated isl types. --- tc/core/polyhedral/cuda/memory_promotion_heuristic.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tc/core/polyhedral/cuda/memory_promotion_heuristic.cc b/tc/core/polyhedral/cuda/memory_promotion_heuristic.cc index 576e28305..375a78c40 100644 --- a/tc/core/polyhedral/cuda/memory_promotion_heuristic.cc +++ b/tc/core/polyhedral/cuda/memory_promotion_heuristic.cc @@ -248,7 +248,7 @@ bool promotionImprovesCoalescing( * Returns the union of all mapping filters to "MappingType" in "scop". */ template -isl::union_set collectMappingsTo(const Scop& scop) { +isl::UnionSet collectMappingsTo(const Scop& scop) { auto root = scop.scheduleRoot(); auto domain = scop.domain(); auto mappingFilters = @@ -260,7 +260,7 @@ isl::union_set collectMappingsTo(const Scop& scop) { auto filter = filterNode->filter_.intersect(activeDomainPoints(root, mf)); mapping = mapping.unite(filterNode->filter_); } - return mapping; + return isl::UnionSet(mapping); } /* @@ -472,7 +472,7 @@ void promoteToSharedBelow( throw promotion::IncorrectScope("cannot promote below a sequence/set node"); } - isl::union_map partialSched = partialSchedule(root, node); + auto partialSched = partialSchedule(root, node); auto mapping = collectMappingsTo(scop); auto groupMap = TensorReferenceGroup::accessedWithin( @@ -646,7 +646,7 @@ void promoteToRegistersBelow(MappedScop& mscop, detail::ScheduleTree* scope) { auto blockMapping = collectMappingsTo(scop); auto mapping = collectMappingsTo(scop).intersect(blockMapping); - isl::union_map schedule = partialSchedule(scop.scheduleRoot(), scope); + auto schedule = partialSchedule(scop.scheduleRoot(), scope); auto groupMap = TensorReferenceGroup::accessedWithin( schedule.intersect_domain(mapping), scop.body); From d0eb24608834afefb8cada1575168cb5f3c28501 Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Fri, 27 Jul 2018 21:42:34 +0200 Subject: [PATCH 073/102] accessedWithin: use templated isl types --- tc/core/polyhedral/memory_promotion.cc | 3 ++- tc/core/polyhedral/memory_promotion.h | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/tc/core/polyhedral/memory_promotion.cc b/tc/core/polyhedral/memory_promotion.cc index e5741c5b4..a5a8c7cfb 100644 --- a/tc/core/polyhedral/memory_promotion.cc +++ b/tc/core/polyhedral/memory_promotion.cc @@ -22,6 +22,7 @@ #include "tc/core/check.h" #include "tc/core/polyhedral/body.h" +#include "tc/core/polyhedral/domain_types.h" #include "tc/core/polyhedral/exceptions.h" #include "tc/core/polyhedral/schedule_tree.h" #include "tc/core/polyhedral/scop.h" @@ -342,7 +343,7 @@ void addSingletonReferenceGroups( // TensorReferenceGroup, with each group potentially containing multiple // references. TensorGroups TensorReferenceGroup::accessedWithin( - isl::union_map outerSchedule, + isl::UnionMap outerSchedule, const Body& body) { TensorGroups tensorGroups; auto domain = outerSchedule.domain(); diff --git a/tc/core/polyhedral/memory_promotion.h b/tc/core/polyhedral/memory_promotion.h index 8ada806aa..cc402a6c8 100644 --- a/tc/core/polyhedral/memory_promotion.h +++ b/tc/core/polyhedral/memory_promotion.h @@ -17,6 +17,7 @@ #include +#include "tc/core/polyhedral/domain_types.h" #include "tc/core/polyhedral/schedule_tree.h" #include "tc/core/polyhedral/scop.h" #include "tc/external/isl.h" @@ -112,7 +113,7 @@ class TensorReferenceGroup { public: static TensorGroups accessedWithin( - isl::union_map outerSchedule, + isl::UnionMap outerSchedule, const Body& body); bool isReadOnly() const; From f9ebd3d12d196e414db8cc55d82c582c1db56327 Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Mon, 30 Jul 2018 14:56:17 +0200 Subject: [PATCH 074/102] addSingletonReferenceGroups: use templated isl types --- tc/core/polyhedral/memory_promotion.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tc/core/polyhedral/memory_promotion.cc b/tc/core/polyhedral/memory_promotion.cc index a5a8c7cfb..498f21a9f 100644 --- a/tc/core/polyhedral/memory_promotion.cc +++ b/tc/core/polyhedral/memory_promotion.cc @@ -295,16 +295,16 @@ void addSingletonReferenceGroup( void addSingletonReferenceGroups( TensorGroups& tensorGroups, - isl::union_map accesses, - isl::union_set domain, - isl::union_map schedule, + isl::UnionMap, Tensor> accesses, + isl::UnionSet domain, + isl::UnionMap schedule, AccessType type) { // access relations have a shape :: [D -> ref] -> O // use currying to isolate the D part before intersecting with the domain // Compute initial groups with single reference per group. std::unordered_set unapproximatable; for (auto a : accesses.get_map_list()) { - if (isl::union_map(a.curry()).intersect_domain(domain).is_empty()) { + if (a.curry().asUnionMap().intersect_domain(domain).is_empty()) { continue; } From 7571d6880cbcd2e6078d10a89232f2bf3c42a82d Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Mon, 30 Jul 2018 15:33:51 +0200 Subject: [PATCH 075/102] addSingletonReferenceGroup: use templated isl types --- tc/core/polyhedral/memory_promotion.cc | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/tc/core/polyhedral/memory_promotion.cc b/tc/core/polyhedral/memory_promotion.cc index 498f21a9f..c598f8bfc 100644 --- a/tc/core/polyhedral/memory_promotion.cc +++ b/tc/core/polyhedral/memory_promotion.cc @@ -282,13 +282,12 @@ void joinOverlappingWrites( void addSingletonReferenceGroup( TensorGroups& tensorGroups, isl::id targetTensor, - isl::union_map schedule, - isl::map access, + isl::UnionMap schedule, + isl::Map, Tensor> access, AccessType type) { - auto scopedUnionAccess = isl::union_map(access.curry()); - scopedUnionAccess = scopedUnionAccess.apply_domain(schedule); - auto scopedAccess = isl::map::from(scopedUnionAccess); - scopedAccess = scopedAccess.uncurry(); + auto unionAccess = access.curry().asUnionMap(); + auto scopedUnionAccess = unionAccess.apply_domain(schedule); + auto scopedAccess = scopedUnionAccess.toMap().uncurry(); tensorGroups[targetTensor].push_back( TensorReferenceGroup::makeSingleton(access, scopedAccess, type)); } From a6fac0d538a4980b169470cea408a381872e7873 Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Mon, 30 Jul 2018 15:51:01 +0200 Subject: [PATCH 076/102] makeSingleton: use templated isl types --- tc/core/polyhedral/memory_promotion.cc | 8 ++++---- tc/core/polyhedral/memory_promotion.h | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tc/core/polyhedral/memory_promotion.cc b/tc/core/polyhedral/memory_promotion.cc index c598f8bfc..ffcba9e31 100644 --- a/tc/core/polyhedral/memory_promotion.cc +++ b/tc/core/polyhedral/memory_promotion.cc @@ -85,13 +85,13 @@ ScopedFootprint outputRanges(isl::map access) { // Access has the shape :: [S -> ref] -> O // Extract the reference ID, store it separately and simplify the access. std::unique_ptr TensorReferenceGroup::makeSingleton( - isl::map originalAccess, - isl::map scopedAccess, + isl::Map, Tensor> originalAccess, + isl::Map, Tensor> scopedTaggedAccess, AccessType type) { auto ref = std::unique_ptr(new TensorReference); auto refId = - scopedAccess.get_space().domain().unwrap().get_map_range_tuple_id(); - scopedAccess = scopedAccess.domain_factor_domain(); + scopedTaggedAccess.get_space().domain().unwrap().get_map_range_tuple_id(); + auto scopedAccess = scopedTaggedAccess.domain_factor_domain(); ref->originalAccess = originalAccess.domain_factor_domain(); ref->scopedAccess = scopedAccess; ref->type = type; diff --git a/tc/core/polyhedral/memory_promotion.h b/tc/core/polyhedral/memory_promotion.h index cc402a6c8..b0e4dea56 100644 --- a/tc/core/polyhedral/memory_promotion.h +++ b/tc/core/polyhedral/memory_promotion.h @@ -156,8 +156,8 @@ class TensorReferenceGroup { std::unique_ptr&& g1, std::unique_ptr&& g2); static std::unique_ptr makeSingleton( - isl::map originalAccess, - isl::map scopedAccess, + isl::Map, Tensor> originalAccess, + isl::Map, Tensor> scopedAccess, AccessType type); public: From 6ca1fa6e96a210bde1be2e50d4a97c82dd951ca5 Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Mon, 30 Jul 2018 15:56:42 +0200 Subject: [PATCH 077/102] TensorReference: use templated isl types --- tc/core/polyhedral/memory_promotion.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tc/core/polyhedral/memory_promotion.h b/tc/core/polyhedral/memory_promotion.h index b0e4dea56..dd8ec9c89 100644 --- a/tc/core/polyhedral/memory_promotion.h +++ b/tc/core/polyhedral/memory_promotion.h @@ -81,11 +81,11 @@ class TensorReference { public: // Original access relation in terms of the Scop domain. - isl::map originalAccess; + isl::Map originalAccess; // Access relation in terms of partial schedule at the point where the // reference group is introduced in the tree. - isl::map scopedAccess; + isl::Map scopedAccess; // Access direction (read or write). AccessType type; From b6fae4d31bc54a4cf9b1d4536fd5d7b481463088 Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Thu, 21 Jun 2018 12:05:24 +0200 Subject: [PATCH 078/102] tensorElementsSet: use templated isl types --- tc/core/polyhedral/memory_promotion.cc | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/tc/core/polyhedral/memory_promotion.cc b/tc/core/polyhedral/memory_promotion.cc index ffcba9e31..841b9882f 100644 --- a/tc/core/polyhedral/memory_promotion.cc +++ b/tc/core/polyhedral/memory_promotion.cc @@ -408,25 +408,26 @@ namespace { // each dimension of the tensor is contrained by the min_aff on the left and // by the min_aff + extent_aff on the right. Intersect this set with the // context of the scop. -isl::set tensorElementsSet(const Scop& scop, isl::id tensorId) { +isl::Set tensorElementsSet(const Scop& scop, isl::id tensorId) { auto halideParameter = scop.findArgument(tensorId).parameter(); auto space = scop.domain().get_space(); auto nDim = halideParameter.dimensions(); auto tensorTuple = constructTensorTuple(space, tensorId, nDim); auto tensorSpace = tensorTuple.get_space(); - auto tensorElements = isl::set::universe(tensorSpace); - auto identity = isl::multi_aff::identity(tensorSpace.map_from_set()); + auto tensorElements = isl::Set::universe(tensorSpace); + auto identity = + isl::MultiAff::identity(tensorSpace.map_from_set()); for (int i = 0; i < nDim; ++i) { - isl::aff minAff = halide2isl::makeIslAffFromExpr( + auto minAff = halide2isl::makeIslAffFromExpr( space, halideParameter.min_constraint(i)); - isl::aff extentAff = halide2isl::makeIslAffFromExpr( + auto extentAff = halide2isl::makeIslAffFromExpr( space, halideParameter.extent_constraint(i)); - minAff = minAff.unbind_params_insert_domain(tensorTuple); - extentAff = extentAff.unbind_params_insert_domain(tensorTuple); + auto minAff2 = minAff.unbind_params_insert_domain(tensorTuple); + auto extentAff2 = extentAff.unbind_params_insert_domain(tensorTuple); auto aff = identity.get_aff(i); - tensorElements = tensorElements & (minAff <= isl::aff_set(aff)) & - (isl::aff_set(aff) < (minAff + extentAff)); + tensorElements = tensorElements & (minAff2.le_set(aff)) & + (aff.lt_set(minAff2 + extentAff2)); } tensorElements = tensorElements.intersect_params(scop.context()); From f021617762544e49f5b992ab018cee672fd15581 Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Mon, 30 Jul 2018 16:40:50 +0200 Subject: [PATCH 079/102] promotedFootprint: use templated isl types --- tc/core/polyhedral/domain_types.h | 1 + tc/core/polyhedral/memory_promotion.cc | 30 ++++++++++++++------------ tc/core/polyhedral/memory_promotion.h | 8 +++---- tc/external/detail/islpp.h | 5 +++++ 4 files changed, 26 insertions(+), 18 deletions(-) diff --git a/tc/core/polyhedral/domain_types.h b/tc/core/polyhedral/domain_types.h index b627e53eb..8c3410672 100644 --- a/tc/core/polyhedral/domain_types.h +++ b/tc/core/polyhedral/domain_types.h @@ -3,6 +3,7 @@ namespace polyhedral { struct Band; struct Prefix; +struct Promoted; struct Reduction; struct ReductionSchedule; struct Statement; diff --git a/tc/core/polyhedral/memory_promotion.cc b/tc/core/polyhedral/memory_promotion.cc index 841b9882f..d804d37a2 100644 --- a/tc/core/polyhedral/memory_promotion.cc +++ b/tc/core/polyhedral/memory_promotion.cc @@ -147,20 +147,20 @@ bool TensorReferenceGroup::isReadOnly() const { return result; } -isl::set TensorReferenceGroup::promotedFootprint() const { +isl::Set TensorReferenceGroup::promotedFootprint() const { auto space = scopedAccesses().get_space().range(); auto sizes = approximation.box.get_size(); if (!sizes.get_space().has_equal_tuples(space)) { throw promotion::GroupingError("unexpected dimensionality mismatch"); } - isl::set footprint = isl::set::universe(space); - auto identity = isl::multi_aff::identity(space.map_from_set()); + isl::Set footprint = isl::Set::universe(space); + auto identity = isl::MultiAff::identity(space.map_from_set()); for (size_t i = 0, e = sizes.size(); i < e; ++i) { auto aff = identity.get_aff(i); auto size = sizes.get_val(i); - footprint = - footprint & (isl::aff_set(aff) >= 0) & (isl::aff_set(aff) < size); + footprint = footprint & aff.asPwAff().nonneg_set() & + (size - aff).asPwAff().pos_set(); } return footprint; } @@ -175,14 +175,14 @@ std::vector TensorReferenceGroup::approximationSizes() const { } namespace { -isl::map referenceScopedAccessesImpl( +isl::Map referenceScopedAccessesImpl( const TensorReferenceGroup& group, AccessType type) { if (group.references.size() == 0) { throw promotion::GroupingError("no references in the group"); } - auto accesses = - isl::map::empty(group.references.front()->scopedAccess.get_space()); + auto accesses = isl::Map::empty( + group.references.front()->scopedAccess.get_space()); for (const auto& ref : group.references) { if (ref->type != type) { @@ -203,11 +203,11 @@ isl::set TensorReferenceGroup::readFootprint() const { return referenceScopedAccessesImpl(*this, AccessType::Read).range(); } -isl::map TensorReferenceGroup::scopedWrites() const { +isl::Map TensorReferenceGroup::scopedWrites() const { return referenceScopedAccessesImpl(*this, AccessType::Write); } -isl::map TensorReferenceGroup::scopedReads() const { +isl::Map TensorReferenceGroup::scopedReads() const { return referenceScopedAccessesImpl(*this, AccessType::Read); } @@ -509,7 +509,8 @@ ScheduleTree* insertCopiesUnder( // control flow, but we should only write back elements that are actually // written to. In any case, intersect the footprint with the set of existing // tensor elements. - auto promotedFootprint = group.promotedFootprint().set_tuple_id(groupId); + auto promotedFootprint = + group.promotedFootprint().set_tuple_id(groupId); auto scheduleUniverse = isl::set::universe(promotionSpace.domain().unwrap().domain()); auto arrayId = promotionSpace.domain().unwrap().get_map_range_tuple_id(); @@ -518,9 +519,10 @@ ScheduleTree* insertCopiesUnder( approximatedRead = approximatedRead.product(promotedFootprint); auto readExtension = extension.intersect_range(approximatedRead).set_range_tuple_id(readId); - auto writtenElements = - group.scopedWrites().intersect_range(tensorElements).wrap(); - writtenElements = writtenElements.product(promotedFootprint); + auto writtenElements = group.scopedWrites() + .intersect_range(tensorElements) + .wrap() + .product(promotedFootprint); auto writeExtension = extension.intersect_range(writtenElements).set_range_tuple_id(writeId); diff --git a/tc/core/polyhedral/memory_promotion.h b/tc/core/polyhedral/memory_promotion.h index dd8ec9c89..ddc61c6fb 100644 --- a/tc/core/polyhedral/memory_promotion.h +++ b/tc/core/polyhedral/memory_promotion.h @@ -126,9 +126,9 @@ class TensorReferenceGroup { } // Access relations in terms of partial schedule of the scoping point. - isl::map scopedWrites() const; - isl::map scopedReads() const; - isl::map scopedAccesses() const { + isl::Map scopedWrites() const; + isl::Map scopedReads() const; + isl::Map scopedAccesses() const { return scopedWrites().unite(scopedReads()); } @@ -146,7 +146,7 @@ class TensorReferenceGroup { isl::map approximateScopedAccesses() const; isl::multi_aff promotion() const; - isl::set promotedFootprint() const; + isl::Set promotedFootprint() const; std::vector approximationSizes() const; diff --git a/tc/external/detail/islpp.h b/tc/external/detail/islpp.h index d527c4192..d83714286 100644 --- a/tc/external/detail/islpp.h +++ b/tc/external/detail/islpp.h @@ -45,6 +45,11 @@ inline T operator-(T a, T b) { return a.sub(b); } +template +inline auto operator-(isl::val a, T b) -> decltype(b.add_constant(a)) { + return b.neg().add_constant(a); +} + template inline T operator&(T S1, T S2) { return S1.intersect(S2); From ca62f4515ab3a2a010e95726fbb6c0a943b9d9eb Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Mon, 30 Jul 2018 17:57:03 +0200 Subject: [PATCH 080/102] TensorReferenceGroup::promotion: temporarily remove type deduction This allows outputRanges to be converted to templated isl types without having to convert TensorReferenceGroup::promotion at the same time. Automatic type deduction will be reintroduced when TensorReferenceGroup::promotion is converted. --- tc/core/polyhedral/memory_promotion.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tc/core/polyhedral/memory_promotion.cc b/tc/core/polyhedral/memory_promotion.cc index d804d37a2..f83d882a1 100644 --- a/tc/core/polyhedral/memory_promotion.cc +++ b/tc/core/polyhedral/memory_promotion.cc @@ -379,9 +379,10 @@ isl::multi_aff TensorReferenceGroup::promotion() const { auto originalSpaceInserter = isl::multi_aff::domain_map(accessSpace); // Lower bounds and offsets space is S -> O; transform into [S -> O] -> O. - auto lowerBounds = + isl::multi_aff lowerBounds = approximation.lowerBounds().pullback(originalSpaceInserter); - auto offsets = approximation.strideOffsets.pullback(originalSpaceInserter); + isl::multi_aff offsets = + approximation.strideOffsets.pullback(originalSpaceInserter); // Create promotion starting by identity in [S -> O] -> O. auto original = isl::multi_aff::range_map(accessSpace); From 28de59dd6cd337cdedb105e19fc12ff93b3ae5a6 Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Mon, 30 Jul 2018 17:57:03 +0200 Subject: [PATCH 081/102] outputRanges: use templated isl types Since removeRangeStrides has not been converted yet, a separate variable is introduced to store its result. Since ScopedFootprint::strideOffsets is modified, TensorReferenceGroup::promotion needs some modifications too. --- tc/core/polyhedral/memory_promotion.cc | 17 ++++++++++------- tc/core/polyhedral/memory_promotion.h | 4 ++-- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/tc/core/polyhedral/memory_promotion.cc b/tc/core/polyhedral/memory_promotion.cc index f83d882a1..b9564618c 100644 --- a/tc/core/polyhedral/memory_promotion.cc +++ b/tc/core/polyhedral/memory_promotion.cc @@ -61,10 +61,12 @@ isl::map removeRangeStrides( // Compute a box approximation of the range of the given relation, // including the lower bounds, the box sizes, and the strides. // If the range has strides, remove them first. -ScopedFootprint outputRanges(isl::map access) { +ScopedFootprint outputRanges(isl::Map access) { ScopedFootprint footprint; - footprint.strideValues = isl::multi_val::zero(access.get_space().range()); - footprint.strideOffsets = isl::multi_aff::zero(access.get_space()); + footprint.strideValues = + isl::MultiVal::zero(access.get_space().range()); + footprint.strideOffsets = + isl::MultiAff::zero(access.get_space()); int nSubscripts = footprint.strideValues.size(); for (int i = 0; i < nSubscripts; ++i) { @@ -74,10 +76,10 @@ ScopedFootprint outputRanges(isl::map access) { footprint.strideOffsets.set_aff(i, si.get_offset()); } - access = removeRangeStrides( + auto accessNoStrides = removeRangeStrides( access, footprint.strideValues, footprint.strideOffsets); - footprint.box = access.get_range_simple_fixed_box_hull(); + footprint.box = accessNoStrides.get_range_simple_fixed_box_hull(); return footprint; } } // namespace @@ -371,12 +373,13 @@ TensorGroups TensorReferenceGroup::accessedWithin( // outer schedule dimensions. isl::multi_aff TensorReferenceGroup::promotion() const { // access space is S -> O - isl::map map = scopedAccesses(); + auto map = scopedAccesses(); auto accessSpace = map.get_space(); // Construct a projection multi-aff in [S -> O] -> S // for further precomposition. - auto originalSpaceInserter = isl::multi_aff::domain_map(accessSpace); + auto originalSpaceInserter = + isl::MultiAff, Prefix>::domain_map(accessSpace); // Lower bounds and offsets space is S -> O; transform into [S -> O] -> O. isl::multi_aff lowerBounds = diff --git a/tc/core/polyhedral/memory_promotion.h b/tc/core/polyhedral/memory_promotion.h index ddc61c6fb..4909c8655 100644 --- a/tc/core/polyhedral/memory_promotion.h +++ b/tc/core/polyhedral/memory_promotion.h @@ -59,8 +59,8 @@ struct ScopedFootprint { } isl::fixed_box box; - isl::multi_val strideValues; - isl::multi_aff strideOffsets; + isl::MultiVal strideValues; + isl::MultiAff strideOffsets; isl::multi_aff lowerBounds() const; }; From 568715012e8ab211c928e4af4a985cec685504f2 Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Mon, 30 Jul 2018 17:57:03 +0200 Subject: [PATCH 082/102] removeRangeStrides: use templated isl types --- tc/core/polyhedral/memory_promotion.cc | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/tc/core/polyhedral/memory_promotion.cc b/tc/core/polyhedral/memory_promotion.cc index b9564618c..7c906369c 100644 --- a/tc/core/polyhedral/memory_promotion.cc +++ b/tc/core/polyhedral/memory_promotion.cc @@ -45,17 +45,19 @@ namespace { // D -> O: o_i = f(D) // // by subtracting "offsets" and by dividing the result by "strides". -isl::map removeRangeStrides( - isl::map relation, - isl::multi_val strides, - isl::multi_aff offsets) { +template +isl::Map removeRangeStrides( + isl::Map relation, + isl::MultiVal strides, + isl::MultiAff offsets) { TC_CHECK_EQ(strides.size(), offsets.size()); auto space = relation.get_space(); - auto stridesMA = isl::multi_aff::identity(space.range().map_from_set()); + auto stridesMA = + isl::MultiAff::identity(space.range().map_from_set()); stridesMA = stridesMA / strides; - return relation.sum(isl::map(offsets.neg())).apply_range(isl::map(stridesMA)); + return relation.sum(offsets.neg().asMap()).apply_range(stridesMA.asMap()); } // Compute a box approximation of the range of the given relation, From 1dfc84eb13b1c2b89bf27e3d02113c1f4eee59a9 Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Mon, 30 Jul 2018 18:09:02 +0200 Subject: [PATCH 083/102] ScopedFootprint.box: use templated isl types --- tc/core/polyhedral/memory_promotion.cc | 2 +- tc/core/polyhedral/memory_promotion.h | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tc/core/polyhedral/memory_promotion.cc b/tc/core/polyhedral/memory_promotion.cc index 7c906369c..c59b96963 100644 --- a/tc/core/polyhedral/memory_promotion.cc +++ b/tc/core/polyhedral/memory_promotion.cc @@ -136,7 +136,7 @@ isl::map TensorReferenceGroup::approximateScopedAccesses() const { return accessed; } -isl::multi_aff ScopedFootprint::lowerBounds() const { +isl::MultiAff ScopedFootprint::lowerBounds() const { if (dim() == 0) { throw promotion::PromotionNYI("promotion for scalars"); } diff --git a/tc/core/polyhedral/memory_promotion.h b/tc/core/polyhedral/memory_promotion.h index 4909c8655..3cfe2c629 100644 --- a/tc/core/polyhedral/memory_promotion.h +++ b/tc/core/polyhedral/memory_promotion.h @@ -48,21 +48,21 @@ struct ScopedFootprint { isl::val size(size_t pos) const { return box.get_size().get_val(pos); } - isl::aff lowerBound(size_t pos) const { + isl::AffOn lowerBound(size_t pos) const { return box.get_offset().get_aff(pos); } isl::val stride(size_t pos) const { return strideValues.get_val(pos); } - isl::aff strideOffset(size_t pos) const { + isl::AffOn strideOffset(size_t pos) const { return strideOffsets.get_aff(pos); } - isl::fixed_box box; + isl::FixedBox box; isl::MultiVal strideValues; isl::MultiAff strideOffsets; - isl::multi_aff lowerBounds() const; + isl::MultiAff lowerBounds() const; }; // Descriptor of tensor reference in a Scop. From 5b1818890fe9ed89889a518a9b44dc7a59be7170 Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Tue, 31 Jul 2018 09:23:43 +0200 Subject: [PATCH 084/102] TensorReferenceGroup::promotion: use templated isl types --- tc/core/polyhedral/cuda/codegen.cc | 5 +++-- tc/core/polyhedral/memory_promotion.cc | 11 ++++++----- tc/core/polyhedral/memory_promotion.h | 2 +- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/tc/core/polyhedral/cuda/codegen.cc b/tc/core/polyhedral/cuda/codegen.cc index 606cd235c..1aafa3f75 100644 --- a/tc/core/polyhedral/cuda/codegen.cc +++ b/tc/core/polyhedral/cuda/codegen.cc @@ -723,8 +723,9 @@ void emitMappedTensorAccess( // MA = multi_aff, PMA = pw_multi_aff auto access = makeMultiAffAccess(tensorId, subscripts, context); // MA :: D -> O - auto promotion = promotionInfo.group->promotion(); // MA :: [S -> O] -> P - promotion = promotion.set_range_tuple_id(promotionInfo.groupId); + auto prePromotion = promotionInfo.group->promotion(); // MA :: [S -> O] -> P + auto promotion = + prePromotion.set_range_tuple_id(promotionInfo.groupId); auto iteratorMap = context.iteratorMap(); // PMA :: A -> D auto schedule = isl::map::from(promotionInfo.outerSchedule.intersect_domain( context.domain())); // map :: D -> S diff --git a/tc/core/polyhedral/memory_promotion.cc b/tc/core/polyhedral/memory_promotion.cc index c59b96963..95b1485ac 100644 --- a/tc/core/polyhedral/memory_promotion.cc +++ b/tc/core/polyhedral/memory_promotion.cc @@ -373,7 +373,8 @@ TensorGroups TensorReferenceGroup::accessedWithin( // elements of the promoted array get assigned different values of the original // array in different outer loop iterations; it's impossible to project out the // outer schedule dimensions. -isl::multi_aff TensorReferenceGroup::promotion() const { +isl::MultiAff, Tensor> +TensorReferenceGroup::promotion() const { // access space is S -> O auto map = scopedAccesses(); auto accessSpace = map.get_space(); @@ -384,13 +385,13 @@ isl::multi_aff TensorReferenceGroup::promotion() const { isl::MultiAff, Prefix>::domain_map(accessSpace); // Lower bounds and offsets space is S -> O; transform into [S -> O] -> O. - isl::multi_aff lowerBounds = + auto lowerBounds = approximation.lowerBounds().pullback(originalSpaceInserter); - isl::multi_aff offsets = - approximation.strideOffsets.pullback(originalSpaceInserter); + auto offsets = approximation.strideOffsets.pullback(originalSpaceInserter); // Create promotion starting by identity in [S -> O] -> O. - auto original = isl::multi_aff::range_map(accessSpace); + auto original = + isl::MultiAff, Tensor>::range_map(accessSpace); auto promotion = (original - offsets) / approximation.strideValues - lowerBounds; diff --git a/tc/core/polyhedral/memory_promotion.h b/tc/core/polyhedral/memory_promotion.h index 3cfe2c629..cbf5890cb 100644 --- a/tc/core/polyhedral/memory_promotion.h +++ b/tc/core/polyhedral/memory_promotion.h @@ -145,7 +145,7 @@ class TensorReferenceGroup { // and relative to the scoping point. isl::map approximateScopedAccesses() const; - isl::multi_aff promotion() const; + isl::MultiAff, Tensor> promotion() const; isl::Set promotedFootprint() const; std::vector approximationSizes() const; From 08bc1a27508efa6e2675b45f99afbd14c550d09c Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Thu, 21 Jun 2018 12:05:24 +0200 Subject: [PATCH 085/102] use templated isl types in schedule tree --- tc/core/polyhedral/cuda/mapped_scop.cc | 2 +- tc/core/polyhedral/memory_promotion.cc | 14 +++++++--- tc/core/polyhedral/schedule_isl_conversion.cc | 6 ++--- tc/core/polyhedral/schedule_transforms.cc | 19 ++++++++----- tc/core/polyhedral/schedule_transforms.h | 8 +++--- tc/core/polyhedral/schedule_tree.cc | 10 +++---- tc/core/polyhedral/schedule_tree.h | 9 ++++--- tc/core/polyhedral/schedule_tree_elem.cc | 7 ++--- tc/core/polyhedral/schedule_tree_elem.h | 19 +++++++------ tc/core/polyhedral/schedule_utils-inl.h | 27 ++++++++++--------- tc/core/polyhedral/schedule_utils.cc | 17 +++++++----- tc/core/polyhedral/schedule_utils.h | 7 ++--- tc/core/polyhedral/unroll.cc | 10 +++---- tc/external/detail/islpp.h | 8 +++--- 14 files changed, 94 insertions(+), 69 deletions(-) diff --git a/tc/core/polyhedral/cuda/mapped_scop.cc b/tc/core/polyhedral/cuda/mapped_scop.cc index 623626369..bcc7a6e44 100644 --- a/tc/core/polyhedral/cuda/mapped_scop.cc +++ b/tc/core/polyhedral/cuda/mapped_scop.cc @@ -288,7 +288,7 @@ bool MappedScop::detectReductions(ScheduleTree* tree) { // a single reduction for now. // Support for multiple reductions would require a check // that these reductions do not interfere with each other. - auto domain = isl::UnionSet(band->mupa_.domain()); + auto domain = band->mupa_.domain(); auto updates = reductionUpdates(domain, scop()); if (updates.n_set() != 1) { return false; diff --git a/tc/core/polyhedral/memory_promotion.cc b/tc/core/polyhedral/memory_promotion.cc index 95b1485ac..252e5781c 100644 --- a/tc/core/polyhedral/memory_promotion.cc +++ b/tc/core/polyhedral/memory_promotion.cc @@ -501,8 +501,10 @@ ScheduleTree* insertCopiesUnder( auto writeSchedule = isl::multi_union_pw_aff(identityCopySchedule.pullback( isl::multi_aff::wrapped_range_map(writeSpace))); - auto readBandNode = ScheduleTree::makeBand(readSchedule); - auto writeBandNode = ScheduleTree::makeBand(writeSchedule); + auto readBandNode = ScheduleTree::makeBand( + isl::MultiUnionPwAff(readSchedule)); + auto writeBandNode = ScheduleTree::makeBand( + isl::MultiUnionPwAff(writeSchedule)); if (unrollAllCopies) { unrollAllMembers(readBandNode->as()); @@ -552,14 +554,18 @@ ScheduleTree* insertCopiesUnder( if (reads) { insertExtensionBefore( - root, tree, tree->child({0}), readExtension, std::move(readFilterNode)); + root, + tree, + tree->child({0}), + isl::UnionMap(readExtension), + std::move(readFilterNode)); } if (writes) { insertExtensionAfter( root, tree, tree->child({0}), - writeExtension, + isl::UnionMap(writeExtension), std::move(writeFilterNode)); } diff --git a/tc/core/polyhedral/schedule_isl_conversion.cc b/tc/core/polyhedral/schedule_isl_conversion.cc index 505dc6acc..28f1fa1de 100644 --- a/tc/core/polyhedral/schedule_isl_conversion.cc +++ b/tc/core/polyhedral/schedule_isl_conversion.cc @@ -243,8 +243,8 @@ std::unique_ptr fromIslScheduleNodeBand( for (size_t i = 0; i < n; ++i) { coincident[i] = b.member_get_coincident(i); } - return ScheduleTreeBand::make( - b.get_partial_schedule(), b.get_permutable(), coincident, unroll); + auto mupa = isl::MultiUnionPwAff(b.get_partial_schedule()); + return ScheduleTreeBand::make(mupa, b.get_permutable(), coincident, unroll); } std::unique_ptr elemFromIslScheduleNode(isl::schedule_node node) { @@ -252,7 +252,7 @@ std::unique_ptr elemFromIslScheduleNode(isl::schedule_node node) { if (auto band = node.as()) { return fromIslScheduleNodeBand(band); } else if (auto context = node.as()) { - auto c = context.get_context(); + auto c = isl::Set(context.get_context()); return ScheduleTreeContext::make(c); } else if (auto domain = node.as()) { auto c = domain.get_domain(); diff --git a/tc/core/polyhedral/schedule_transforms.cc b/tc/core/polyhedral/schedule_transforms.cc index c8f4d6f20..9bdc99f28 100644 --- a/tc/core/polyhedral/schedule_transforms.cc +++ b/tc/core/polyhedral/schedule_transforms.cc @@ -89,7 +89,8 @@ ScheduleTree* joinBandsHelper(ScheduleTree* st, bool& moveChildren) { auto& partialSchedule = eb->mupa_; auto& partialScheduleChild = ebChild->mupa_; - partialSchedule = partialSchedule.flat_range_product(partialScheduleChild); + partialSchedule = + partialSchedule.flat_range_product(partialScheduleChild); eb->coincident_.resize( eb->coincident_.size() + ebChild->coincident_.size(), false); eb->unroll_.insert( @@ -285,7 +286,9 @@ ScheduleTree* insertTopLevelEmptyBand(ScheduleTree* root) { return insertNodeBelow(node, ScheduleTree::makeEmptyBand(root)); } -void updateTopLevelContext(detail::ScheduleTree* root, isl::set context) { +void updateTopLevelContext( + detail::ScheduleTree* root, + isl::Set context) { if (!matchOne(tc::polyhedral::domain(tc::polyhedral::context(any())), root)) { root->appendChild( ScheduleTree::makeContext(context, root->detachChildren())); @@ -394,7 +397,7 @@ void insertExtensionAt( ScheduleTree* relativeRoot, ScheduleTree* seqNode, size_t pos, - isl::union_map extension, + isl::UnionMap extension, ScheduleTreeUPtr&& filterNode) { auto extensionTree = seqNode->ancestor(relativeRoot, 1); auto extensionNode = extensionTree->as(); @@ -413,7 +416,7 @@ void insertExtensionBefore( const ScheduleTree* root, ScheduleTree* relativeRoot, ScheduleTree* tree, - isl::union_map extension, + isl::UnionMap extension, ScheduleTreeUPtr&& filterNode) { size_t pos; auto parent = tree->ancestor(relativeRoot, 1); @@ -442,7 +445,7 @@ void insertExtensionAfter( const ScheduleTree* root, ScheduleTree* relativeRoot, ScheduleTree* tree, - isl::union_map extension, + isl::UnionMap extension, ScheduleTreeUPtr&& filterNode) { size_t pos; auto parent = tree->ancestor(relativeRoot, 1); @@ -504,7 +507,7 @@ namespace { * of band node partial schedules. * Elements of a sequence that end up with an empty filter are removed. */ -void gist(ScheduleTree* tree, isl::union_set context) { +void gist(ScheduleTree* tree, isl::UnionSet context) { if (auto bandElem = tree->as()) { bandElem->mupa_ = bandElem->mupa_.gist(context); } else if (auto filterElem = tree->as()) { @@ -534,7 +537,9 @@ void gist(ScheduleTree* tree, isl::union_set context) { * Create a filter node with the given filter and single child node, * after simplifying the child node in the context of the filter. */ -ScheduleTreeUPtr gistedFilter(isl::union_set filter, ScheduleTreeUPtr child) { +ScheduleTreeUPtr gistedFilter( + isl::UnionSet filter, + ScheduleTreeUPtr child) { gist(child.get(), filter); return ScheduleTree::makeFilter(filter, std::move(child)); } diff --git a/tc/core/polyhedral/schedule_transforms.h b/tc/core/polyhedral/schedule_transforms.h index 6820792b4..4fa1f71d2 100644 --- a/tc/core/polyhedral/schedule_transforms.h +++ b/tc/core/polyhedral/schedule_transforms.h @@ -111,7 +111,9 @@ detail::ScheduleTree* insertTopLevelEmptyBand(detail::ScheduleTree* root); // Update the top-level context node by intersecting it with "context". The // top-level context node must be located directly under the root of the tree. // If there is no such node, insert one first. -void updateTopLevelContext(detail::ScheduleTree* root, isl::set context); +void updateTopLevelContext( + detail::ScheduleTree* root, + isl::Set context); // In a tree starting at "root", insert a sequence node with // as only child the node identified by "tree". @@ -175,7 +177,7 @@ void insertExtensionBefore( const detail::ScheduleTree* root, detail::ScheduleTree* relativeRoot, detail::ScheduleTree* tree, - isl::union_map extension, + isl::UnionMap extension, ScheduleTreeUPtr&& filterNode); // Insert an extension with the given extension map and extension filter node @@ -190,7 +192,7 @@ void insertExtensionAfter( const detail::ScheduleTree* root, detail::ScheduleTree* relativeRoot, detail::ScheduleTree* tree, - isl::union_map extension, + isl::UnionMap extension, ScheduleTreeUPtr&& filterNode); // Given a sequence node in the schedule tree, insert diff --git a/tc/core/polyhedral/schedule_tree.cc b/tc/core/polyhedral/schedule_tree.cc index 1c7779d8f..441da9bdf 100644 --- a/tc/core/polyhedral/schedule_tree.cc +++ b/tc/core/polyhedral/schedule_tree.cc @@ -200,7 +200,7 @@ size_t ScheduleTree::scheduleDepth(const ScheduleTree* relativeRoot) const { } std::unique_ptr ScheduleTree::makeBand( - isl::multi_union_pw_aff mupa, + isl::MultiUnionPwAff mupa, std::vector&& children) { std::vector coincident(mupa.size(), false); std::vector unroll(mupa.size(), false); @@ -212,9 +212,9 @@ std::unique_ptr ScheduleTree::makeBand( ScheduleTreeUPtr ScheduleTree::makeEmptyBand(const ScheduleTree* root) { auto domain = root->as(); TC_CHECK(domain); - auto space = domain->domain_.get_space().set_from_params(); - auto mv = isl::multi_val::zero(space); - auto zero = isl::multi_union_pw_aff(domain->domain_, mv); + auto space = domain->domain_.get_space().add_unnamed_tuple_ui(0); + auto mv = isl::MultiVal::zero(space); + auto zero = isl::MultiUnionPwAff(domain->domain_, mv); return ScheduleTree::makeBand(zero); } @@ -225,7 +225,7 @@ std::unique_ptr ScheduleTree::makeDomain( } std::unique_ptr ScheduleTree::makeContext( - isl::set context, + isl::Set context, std::vector&& children) { return ScheduleTreeContext::make(context, std::move(children)); } diff --git a/tc/core/polyhedral/schedule_tree.h b/tc/core/polyhedral/schedule_tree.h index 403dd0210..bfe82504e 100644 --- a/tc/core/polyhedral/schedule_tree.h +++ b/tc/core/polyhedral/schedule_tree.h @@ -21,6 +21,7 @@ #include #include "tc/core/check.h" +#include "tc/core/polyhedral/domain_types.h" #include "tc/core/polyhedral/mapping_types.h" #include "tc/core/polyhedral/options.h" #include "tc/core/utils/vararg.h" @@ -280,7 +281,7 @@ struct ScheduleTree { // Factory functions // static ScheduleTreeUPtr makeBand( - isl::multi_union_pw_aff mupa, + isl::MultiUnionPwAff mupa, std::vector&& children = {}); // Return a zero-dimensional band for use in a tree with the given root. @@ -291,7 +292,7 @@ struct ScheduleTree { std::vector&& children = {}); static ScheduleTreeUPtr makeContext( - isl::set context, + isl::Set context, std::vector&& children = {}); static ScheduleTreeUPtr makeFilter( @@ -332,7 +333,7 @@ struct ScheduleTree { template static ScheduleTreeUPtr makeBand( - isl::multi_union_pw_aff mupa, + isl::MultiUnionPwAff mupa, Args&&... args) { return makeBand( mupa, vectorFromArgs(std::forward(args)...)); @@ -345,7 +346,7 @@ struct ScheduleTree { } template - static ScheduleTreeUPtr makeContext(isl::set context, Args&&... args) { + static ScheduleTreeUPtr makeContext(isl::Set<> context, Args&&... args) { return makeContext( context, vectorFromArgs(std::forward(args)...)); } diff --git a/tc/core/polyhedral/schedule_tree_elem.cc b/tc/core/polyhedral/schedule_tree_elem.cc index 3653d0cf5..a0a244610 100644 --- a/tc/core/polyhedral/schedule_tree_elem.cc +++ b/tc/core/polyhedral/schedule_tree_elem.cc @@ -26,6 +26,7 @@ #include "tc/core/check.h" #include "tc/core/constants.h" #include "tc/core/flags.h" +#include "tc/core/polyhedral/domain_types.h" #include "tc/core/polyhedral/schedule_isl_conversion.h" #include "tc/core/polyhedral/schedule_tree.h" #include "tc/core/scope_guard.h" @@ -185,7 +186,7 @@ std::unique_ptr ScheduleTreeSet::make( } std::unique_ptr ScheduleTreeBand::make( - isl::multi_union_pw_aff mupa, + isl::MultiUnionPwAff mupa, bool permutable, std::vector coincident, std::vector unroll, @@ -238,8 +239,8 @@ void ScheduleTreeBand::drop(size_t pos, size_t n) { auto list = mupa_.get_union_pw_aff_list(); auto space = mupa_.get_space().params(); list = list.drop(pos, n); - space = space.add_unnamed_tuple_ui(list.size()); - mupa_ = isl::multi_union_pw_aff(space, list); + auto spaceBand = space.add_unnamed_tuple_ui(list.size()); + mupa_ = isl::MultiUnionPwAff(spaceBand, list); std::copy( coincident_.begin() + pos + n, diff --git a/tc/core/polyhedral/schedule_tree_elem.h b/tc/core/polyhedral/schedule_tree_elem.h index f32cca862..3e1dd42aa 100644 --- a/tc/core/polyhedral/schedule_tree_elem.h +++ b/tc/core/polyhedral/schedule_tree_elem.h @@ -64,7 +64,7 @@ struct ScheduleTreeContext : public ScheduleTree { } public: - isl::set context_; + isl::Set context_; }; struct ScheduleTreeDomain : public ScheduleTree { @@ -100,7 +100,7 @@ struct ScheduleTreeDomain : public ScheduleTree { } public: - isl::union_set domain_; + isl::UnionSet domain_; }; struct ScheduleTreeExtension : public ScheduleTree { @@ -136,7 +136,7 @@ struct ScheduleTreeExtension : public ScheduleTree { } public: - isl::union_map extension_; + isl::UnionMap extension_; }; struct ScheduleTreeFilter : public ScheduleTree { @@ -172,7 +172,7 @@ struct ScheduleTreeFilter : public ScheduleTree { } public: - isl::union_set filter_; + isl::UnionSet filter_; }; struct ScheduleTreeMapping : public ScheduleTree { @@ -216,7 +216,7 @@ struct ScheduleTreeMapping : public ScheduleTree { // Mapping from identifiers to affine functions on domain elements. const Mapping mapping; // Assignment of the affine functions to the identifiers as parameters. - isl::union_set filter_; + isl::UnionSet filter_; }; struct ScheduleTreeSequence : public ScheduleTree { @@ -310,7 +310,7 @@ struct ScheduleTreeBand : public ScheduleTree { // Replace "mupa" by its greatest integer part to ensure that the // schedule is always integral. static std::unique_ptr make( - isl::multi_union_pw_aff mupa, + isl::MultiUnionPwAff mupa, bool permutable, std::vector coincident, std::vector unroll, @@ -336,18 +336,17 @@ struct ScheduleTreeBand : public ScheduleTree { isl::MultiUnionPwAff memberRange(size_t first, size_t n) const { auto list = mupa_.get_union_pw_aff_list(); - auto space = mupa_.get_space().params().add_unnamed_tuple_ui(n); + auto space = mupa_.get_space().params().add_unnamed_tuple_ui(n); auto end = first + n; TC_CHECK_LE(end, nMember()); list = list.drop(end, nMember() - end); list = list.drop(0, first); - return isl::MultiUnionPwAff( - isl::multi_union_pw_aff(space, list)); + return isl::MultiUnionPwAff(space, list); } public: bool permutable_{false}; - isl::multi_union_pw_aff mupa_; + isl::MultiUnionPwAff mupa_; std::vector coincident_; // For each member, should the corresponding loop in the generated code diff --git a/tc/core/polyhedral/schedule_utils-inl.h b/tc/core/polyhedral/schedule_utils-inl.h index e3e096144..4ef8cb834 100644 --- a/tc/core/polyhedral/schedule_utils-inl.h +++ b/tc/core/polyhedral/schedule_utils-inl.h @@ -26,15 +26,16 @@ namespace tc { namespace polyhedral { -inline isl::union_map extendSchedule( +template +isl::UnionMap extendSchedule( const detail::ScheduleTree* node, - isl::union_map schedule) { + isl::UnionMap schedule) { using namespace polyhedral::detail; if (auto bandElem = node->as()) { if (bandElem->nMember() > 0) { - schedule = - schedule.flat_range_product(isl::union_map::from(bandElem->mupa_)); + schedule = schedule.template flat_range_product( + bandElem->mupa_.toUnionMap()); } } else if (auto filterElem = node->as()) { schedule = schedule.intersect_domain(filterElem->filter_); @@ -42,15 +43,18 @@ inline isl::union_map extendSchedule( // FIXME: we may need to restrict the range of reversed extension map to // schedule values that correspond to active domain elements at this // point. - schedule = schedule.unite( - extensionElem->extension_.reverse().intersect_range(schedule.range())); + auto extension = extensionElem->extension_.reverse(); + auto specializedExtension = isl::UnionMap(extension); + schedule = + schedule.unite(specializedExtension.intersect_range(schedule.range())); } return schedule; } namespace detail { -inline isl::union_map partialScheduleImpl( +template +inline isl::UnionMap partialScheduleImpl( const ScheduleTree* root, const ScheduleTree* node, bool useNode) { @@ -61,7 +65,8 @@ inline isl::union_map partialScheduleImpl( TC_CHECK_GT(nodes.size(), 0u) << "root node does not have a prefix schedule"; auto domain = root->as(); TC_CHECK(domain); - auto schedule = isl::union_map::from_domain(domain->domain_); + auto schedule = + isl::UnionMap::from_domain(domain->domain_); for (auto anc : nodes) { if (anc->as()) { TC_CHECK(anc == root); @@ -77,16 +82,14 @@ template inline isl::UnionMap prefixSchedule( const detail::ScheduleTree* root, const detail::ScheduleTree* node) { - auto prefix = detail::partialScheduleImpl(root, node, false); - return isl::UnionMap(prefix); + return detail::partialScheduleImpl(root, node, false); } template inline isl::UnionMap partialSchedule( const detail::ScheduleTree* root, const detail::ScheduleTree* node) { - auto prefix = detail::partialScheduleImpl(root, node, true); - return isl::UnionMap(prefix); + return detail::partialScheduleImpl(root, node, true); } namespace detail { diff --git a/tc/core/polyhedral/schedule_utils.cc b/tc/core/polyhedral/schedule_utils.cc index e6b1745cf..cc8d51889 100644 --- a/tc/core/polyhedral/schedule_utils.cc +++ b/tc/core/polyhedral/schedule_utils.cc @@ -32,7 +32,9 @@ namespace { /* * If "node" is any filter, then intersect "domain" with that filter. */ -isl::union_set applyFilter(isl::union_set domain, const ScheduleTree* node) { +isl::UnionSet applyFilter( + isl::UnionSet domain, + const ScheduleTree* node) { if (auto filterElem = node->as()) { return domain.intersect(filterElem->filter_); } @@ -42,7 +44,9 @@ isl::union_set applyFilter(isl::union_set domain, const ScheduleTree* node) { /* * If "node" is a mapping, then intersect "domain" with its filter. */ -isl::union_set applyMapping(isl::union_set domain, const ScheduleTree* node) { +isl::UnionSet applyMapping( + isl::UnionSet domain, + const ScheduleTree* node) { if (auto filterElem = node->as()) { return domain.intersect(filterElem->filter_); } @@ -55,10 +59,11 @@ isl::union_set applyMapping(isl::union_set domain, const ScheduleTree* node) { // Domain elements are introduced by the root domain node. Some nodes // refine this set of elements based on "filter". Extension nodes // are considered to introduce additional domain points. -isl::union_set collectDomain( +isl::UnionSet collectDomain( const ScheduleTree* root, const vector& nodes, - isl::union_set (*filter)(isl::union_set domain, const ScheduleTree* node)) { + isl::UnionSet ( + *filter)(isl::UnionSet domain, const ScheduleTree* node)) { auto domainElem = root->as(); TC_CHECK(domainElem) << "root must be a Domain node" << *root; @@ -67,7 +72,7 @@ isl::union_set collectDomain( for (auto anc : nodes) { domain = filter(domain, anc); if (auto extensionElem = anc->as()) { - isl::union_map parentSchedule = prefixSchedule(root, anc); + auto parentSchedule = prefixSchedule(root, anc); auto extension = extensionElem->extension_; TC_CHECK(parentSchedule) << "missing root domain node"; parentSchedule = parentSchedule.intersect_domain(domain); @@ -87,7 +92,7 @@ isl::union_set activeDomainPointsHelper( } // namespace -isl::union_set prefixMappingFilter( +isl::UnionSet prefixMappingFilter( const ScheduleTree* root, const ScheduleTree* node) { return collectDomain(root, node->ancestors(root), &applyMapping); diff --git a/tc/core/polyhedral/schedule_utils.h b/tc/core/polyhedral/schedule_utils.h index f09f8c1b6..7a4d9b201 100644 --- a/tc/core/polyhedral/schedule_utils.h +++ b/tc/core/polyhedral/schedule_utils.h @@ -47,9 +47,10 @@ std::vector collectScheduleTreesPath( // Given a schedule defined by the ancestors of the given node, // extend it to a schedule that also covers the node itself. -isl::union_map extendSchedule( +template +isl::UnionMap extendSchedule( const detail::ScheduleTree* node, - isl::union_map schedule); + isl::UnionMap schedule); // Get the partial schedule defined by ancestors of the given node and the node // itself. @@ -113,7 +114,7 @@ isl::UnionSet activeDomainPointsBelow( // Collect the outer block/thread identifier mappings // into a filter on the active domain elements. -isl::union_set prefixMappingFilter( +isl::UnionSet prefixMappingFilter( const detail::ScheduleTree* root, const detail::ScheduleTree* node); diff --git a/tc/core/polyhedral/unroll.cc b/tc/core/polyhedral/unroll.cc index 916253c27..8353699d7 100644 --- a/tc/core/polyhedral/unroll.cc +++ b/tc/core/polyhedral/unroll.cc @@ -100,7 +100,7 @@ isl::val boundInstancesAndMarkUnroll( auto outerMap = prefix; if (i > 0) { list = list.drop(i, 1); - auto outerSpace = space.add_unnamed_tuple_ui(list.size()); + auto outerSpace = space.add_unnamed_tuple_ui(list.size()); auto outer = isl::multi_union_pw_aff(outerSpace, list); outerMap = outerMap.flat_range_product(isl::union_map::from(outer)); } @@ -116,7 +116,7 @@ isl::val boundInstancesAndMarkUnroll( isl::val boundInstancesAndMarkUnroll( detail::ScheduleTree* st, - isl::union_map prefix, + isl::UnionMap prefix, isl::val unrollFactor); /* @@ -134,7 +134,7 @@ isl::val boundInstancesAndMarkUnroll( */ isl::val boundChildrenInstancesAndMarkUnroll( detail::ScheduleTree* st, - isl::union_map prefix, + isl::UnionMap prefix, isl::val unrollFactor) { if (st->children().size() == 0) { return isl::val::one(unrollFactor.get_ctx()); @@ -163,7 +163,7 @@ isl::val boundChildrenInstancesAndMarkUnroll( */ isl::val boundInstancesAndMarkUnroll( detail::ScheduleTree* st, - isl::union_map prefix, + isl::UnionMap prefix, isl::val unrollFactor) { auto bound = boundChildrenInstancesAndMarkUnroll(st, prefix, unrollFactor); @@ -184,7 +184,7 @@ void markUnroll( } auto unrollVal = isl::val(st->ctx_, unroll); - isl::union_map prefix = prefixSchedule(root, st); + auto prefix = prefixSchedule(root, st); prefix = prefix.intersect_domain(prefixMappingFilter(root, st)); boundInstancesAndMarkUnroll(st, prefix, unrollVal); } diff --git a/tc/external/detail/islpp.h b/tc/external/detail/islpp.h index d83714286..114646ff0 100644 --- a/tc/external/detail/islpp.h +++ b/tc/external/detail/islpp.h @@ -279,9 +279,11 @@ inline bool operator!=(const isl::id& id1, const isl::id& id2) { /////////////////////////////////////////////////////////////////////////////// // Given a space and a list of values, this returns the corresponding multi_val. -template -isl::multi_val makeMultiVal(isl::space s, const std::vector& vals) { - isl::multi_val mv = isl::multi_val::zero(s); +template +isl::MultiVal makeMultiVal( + isl::Space s, + const std::vector& vals) { + isl::MultiVal mv = isl::MultiVal::zero(s); TC_CHECK_EQ(vals.size(), static_cast(mv.size())); for (size_t i = 0; i < vals.size(); ++i) { mv = mv.set_val(i, isl::val(s.get_ctx(), vals[i])); From 125cdb54ae63c3335d5293cae5df7cfdf2907244 Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Wed, 1 Aug 2018 17:24:26 +0200 Subject: [PATCH 086/102] MappedScop::map: use templated isl types --- tc/core/polyhedral/cuda/mapped_scop.cc | 10 ++++++---- tc/core/polyhedral/cuda/mapped_scop.h | 2 +- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/tc/core/polyhedral/cuda/mapped_scop.cc b/tc/core/polyhedral/cuda/mapped_scop.cc index bcc7a6e44..c5001cab3 100644 --- a/tc/core/polyhedral/cuda/mapped_scop.cc +++ b/tc/core/polyhedral/cuda/mapped_scop.cc @@ -136,7 +136,9 @@ const CudaDim& mappingSize(const MappedScop* mscop) { // Return a pointer to the updated node (below the inserted filter) // for call chaining purposes. template -ScheduleTree* MappedScop::map(ScheduleTree* tree, isl::union_pw_aff_list list) { +ScheduleTree* MappedScop::map( + ScheduleTree* tree, + isl::UnionPwAffListOn list) { size_t nToMap = list.size(); const auto& extent = mappingSize(this).view; TC_CHECK_LE(nToMap, extent.size()) << "dimension overflow"; @@ -146,7 +148,7 @@ ScheduleTree* MappedScop::map(ScheduleTree* tree, isl::union_pw_aff_list list) { auto universe = domain.universe(); std::vector idList; - auto affList = isl::union_pw_aff_list(list.get_ctx(), 0); + auto affList = isl::UnionPwAffListOn(list.get_ctx(), 0); for (size_t i = 0; i < nToMap; ++i) { auto id = MappingTypeId::makeId(i); auto upa = list.get_at(i); @@ -158,8 +160,8 @@ ScheduleTree* MappedScop::map(ScheduleTree* tree, isl::union_pw_aff_list list) { for (size_t i = nToMap; i < extent.size(); ++i) { auto id = MappingTypeId::makeId(i); - affList = affList.add( - isl::union_pw_aff(universe, isl::val::zero(domain.get_ctx()))); + affList = affList.add(isl::UnionPwAffOn( + universe, isl::val::zero(domain.get_ctx()))); idList.emplace_back(id); } diff --git a/tc/core/polyhedral/cuda/mapped_scop.h b/tc/core/polyhedral/cuda/mapped_scop.h index c971b80e9..31058c3a7 100644 --- a/tc/core/polyhedral/cuda/mapped_scop.h +++ b/tc/core/polyhedral/cuda/mapped_scop.h @@ -151,7 +151,7 @@ class MappedScop { template detail::ScheduleTree* map( detail::ScheduleTree* tree, - isl::union_pw_aff_list list); + isl::UnionPwAffListOn list); // Map "band" to block identifiers and then scale // the band members by "tileSizes". void mapToBlocksAndScaleBand( From 23a82a766a571345a8cc2f903666f4edb45a542c Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Wed, 1 Aug 2018 17:08:25 +0200 Subject: [PATCH 087/102] makeMapping: use templated isl types --- tc/core/polyhedral/schedule_tree.cc | 5 ++--- tc/core/polyhedral/schedule_tree.h | 4 ++-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/tc/core/polyhedral/schedule_tree.cc b/tc/core/polyhedral/schedule_tree.cc index 441da9bdf..fe5763cb2 100644 --- a/tc/core/polyhedral/schedule_tree.cc +++ b/tc/core/polyhedral/schedule_tree.cc @@ -238,14 +238,13 @@ std::unique_ptr ScheduleTree::makeFilter( std::unique_ptr ScheduleTree::makeMappingUnsafe( const std::vector& mappedIds, - isl::union_pw_aff_list mappedAffs, + isl::UnionPwAffListOn mappedAffs, std::vector&& children) { TC_CHECK_EQ(mappedIds.size(), static_cast(mappedAffs.size())) << "expected as many mapped ids as affs"; ScheduleTreeMapping::Mapping mapping; for (size_t i = 0, n = mappedAffs.size(); i < n; ++i) { - auto aff = isl::UnionPwAffOn(mappedAffs.get_at(i)); - mapping.emplace(mappedIds.at(i), aff); + mapping.emplace(mappedIds.at(i), mappedAffs.get_at(i)); } TC_CHECK_GE(mapping.size(), 1u) << "empty mapping"; TC_CHECK_EQ(mappedIds.size(), mapping.size()) diff --git a/tc/core/polyhedral/schedule_tree.h b/tc/core/polyhedral/schedule_tree.h index bfe82504e..485d2fb65 100644 --- a/tc/core/polyhedral/schedule_tree.h +++ b/tc/core/polyhedral/schedule_tree.h @@ -302,7 +302,7 @@ struct ScheduleTree { template static inline ScheduleTreeUPtr makeMapping( const std::vector& mappedIds, - isl::union_pw_aff_list mappedAffs, + isl::UnionPwAffListOn mappedAffs, std::vector&& children = {}) { static_assert( std::is_base_of::value, @@ -319,7 +319,7 @@ struct ScheduleTree { // Internal type-unsafe function to construct mappings. static ScheduleTreeUPtr makeMappingUnsafe( const std::vector& mappedIds, - isl::union_pw_aff_list mappedAffs, + isl::UnionPwAffListOn mappedAffs, std::vector&& children); public: From f9ffa2b3b8cace544a035fa156643654afeffce4 Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Tue, 31 Jul 2018 16:30:37 +0200 Subject: [PATCH 088/102] infixScheduleMupa: use templated isl types --- tc/core/polyhedral/schedule_utils-inl.h | 16 +++++++++------- tc/core/polyhedral/schedule_utils.h | 3 ++- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/tc/core/polyhedral/schedule_utils-inl.h b/tc/core/polyhedral/schedule_utils-inl.h index 4ef8cb834..bd7ca4ec1 100644 --- a/tc/core/polyhedral/schedule_utils-inl.h +++ b/tc/core/polyhedral/schedule_utils-inl.h @@ -118,7 +118,8 @@ foldl(const std::vector vec, Func op, T init = T()) { } // namespace detail -inline isl::multi_union_pw_aff infixScheduleMupa( +template +inline isl::MultiUnionPwAff infixScheduleMupa( const detail::ScheduleTree* root, const detail::ScheduleTree* relativeRoot, const detail::ScheduleTree* tree) { @@ -127,13 +128,15 @@ inline isl::multi_union_pw_aff infixScheduleMupa( auto domainElem = root->as(); TC_CHECK(domainElem); auto domain = domainElem->domain_.universe(); - auto zero = isl::multi_val::zero(domain.get_space().set_from_params()); - auto prefix = isl::multi_union_pw_aff(domain, zero); + auto zero = isl::MultiVal::zero( + domain.get_space().add_unnamed_tuple_ui(0)); + auto prefix = isl::MultiUnionPwAff(domain, zero); prefix = foldl( filterType(tree->ancestors(relativeRoot)), - [](const ScheduleTree* st, isl::multi_union_pw_aff pref) { + [](const ScheduleTree* st, + isl::MultiUnionPwAff pref) { auto mupa = st->as()->mupa_; - return pref.flat_range_product(mupa); + return pref.template flat_range_product(mupa); }, prefix); return prefix; @@ -143,8 +146,7 @@ template inline isl::MultiUnionPwAff prefixScheduleMupa( const detail::ScheduleTree* root, const detail::ScheduleTree* tree) { - auto prefix = infixScheduleMupa(root, root, tree); - return isl::MultiUnionPwAff(prefix); + return infixScheduleMupa(root, root, tree); } template diff --git a/tc/core/polyhedral/schedule_utils.h b/tc/core/polyhedral/schedule_utils.h index 7a4d9b201..26ffb04b4 100644 --- a/tc/core/polyhedral/schedule_utils.h +++ b/tc/core/polyhedral/schedule_utils.h @@ -72,7 +72,8 @@ isl::UnionMap prefixSchedule( // function on the universe domain of the schedule tree. // Note that this function does not take into account // any intermediate filter nodes. -isl::multi_union_pw_aff infixScheduleMupa( +template +isl::MultiUnionPwAff infixScheduleMupa( const detail::ScheduleTree* root, const detail::ScheduleTree* relativeRoot, const detail::ScheduleTree* tree); From 26d5f4a030e99120375370c44d7c68c0e2dd663c Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Thu, 21 Jun 2018 12:05:24 +0200 Subject: [PATCH 089/102] MappedScop::findBestSync: use templated isl types --- tc/core/polyhedral/cuda/mapped_scop.cc | 6 +++--- tc/core/polyhedral/cuda/mapped_scop.h | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tc/core/polyhedral/cuda/mapped_scop.cc b/tc/core/polyhedral/cuda/mapped_scop.cc index c5001cab3..e00a947e5 100644 --- a/tc/core/polyhedral/cuda/mapped_scop.cc +++ b/tc/core/polyhedral/cuda/mapped_scop.cc @@ -554,15 +554,15 @@ isl::MultiUnionPwAff MappedScop::blockMappingSchedule( Scop::SyncLevel MappedScop::findBestSync( ScheduleTree* st1, ScheduleTree* st2, - isl::multi_union_pw_aff domainToThread, - isl::multi_union_pw_aff domainToWarp) { + isl::MultiUnionPwAff domainToThread, + isl::MultiUnionPwAff domainToWarp) { // Active points in the two schedule trees auto stRoot = scop_->scheduleRoot(); auto activePoints1 = activeDomainPointsBelow(stRoot, st1); auto activePoints2 = activeDomainPointsBelow(stRoot, st2); // The dependences between the two schedule trees - isl::union_map dependences = scop_->dependences; + auto dependences = scop_->dependences; dependences = dependences.intersect_domain(activePoints1); dependences = dependences.intersect_range(activePoints2); if (dependences.is_empty()) { diff --git a/tc/core/polyhedral/cuda/mapped_scop.h b/tc/core/polyhedral/cuda/mapped_scop.h index 31058c3a7..fc92a2932 100644 --- a/tc/core/polyhedral/cuda/mapped_scop.h +++ b/tc/core/polyhedral/cuda/mapped_scop.h @@ -188,8 +188,8 @@ class MappedScop { Scop::SyncLevel findBestSync( detail::ScheduleTree* st1, detail::ScheduleTree* st2, - isl::multi_union_pw_aff domainToThread, - isl::multi_union_pw_aff domainToWarp); + isl::MultiUnionPwAff domainToThread, + isl::MultiUnionPwAff domainToWarp); public: // Find best configuration of synchronizations in a sequence, minimizing From cae6a9ade2f853349c85e5abe14ad31fc954112c Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Thu, 21 Jun 2018 12:05:24 +0200 Subject: [PATCH 090/102] Scop::domainRef: use templated isl types --- tc/core/polyhedral/scop.cc | 4 ++-- tc/core/polyhedral/scop.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tc/core/polyhedral/scop.cc b/tc/core/polyhedral/scop.cc index 2158a1be0..4046dedd4 100644 --- a/tc/core/polyhedral/scop.cc +++ b/tc/core/polyhedral/scop.cc @@ -85,7 +85,7 @@ ScopUPtr Scop::makeScop( return makeScop(ctx, tc2halide::translate(ctx, treeRef, compilerOptions)); } -isl::union_set& Scop::domainRef() { +isl::UnionSet& Scop::domainRef() { auto dom = scheduleRoot()->as(); TC_CHECK(dom) << "root is not a domain in: " << *scheduleRoot(); // TODO: activate this when the invariant has a chance of working (i.e. we @@ -99,7 +99,7 @@ isl::union_set& Scop::domainRef() { } const isl::UnionSet Scop::domain() const { - return isl::UnionSet(const_cast(this)->domainRef()); + return const_cast(this)->domainRef(); } std::ostream& operator<<(std::ostream& os, const Scop& s) { diff --git a/tc/core/polyhedral/scop.h b/tc/core/polyhedral/scop.h index d51f16048..572fb833a 100644 --- a/tc/core/polyhedral/scop.h +++ b/tc/core/polyhedral/scop.h @@ -509,7 +509,7 @@ struct Scop { // By analogy with generalized functions, the domain is the "support" part // of the ScheduleTree "function". private: - isl::union_set& domainRef(); + isl::UnionSet& domainRef(); public: const isl::UnionSet domain() const; From 589ba9ed58e77fd841ca73a2df9a7ed3f4c76a16 Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Thu, 21 Jun 2018 12:05:24 +0200 Subject: [PATCH 091/102] promoteToRegistersBelow: use templated isl types --- tc/core/polyhedral/cuda/memory_promotion_heuristic.cc | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/tc/core/polyhedral/cuda/memory_promotion_heuristic.cc b/tc/core/polyhedral/cuda/memory_promotion_heuristic.cc index 375a78c40..13407c944 100644 --- a/tc/core/polyhedral/cuda/memory_promotion_heuristic.cc +++ b/tc/core/polyhedral/cuda/memory_promotion_heuristic.cc @@ -654,8 +654,7 @@ void promoteToRegistersBelow(MappedScop& mscop, detail::ScheduleTree* scope) { auto blockSchedule = mscop.blockMappingSchedule(mscop.schedule()); // Pure affine schedule without (mapping) filters. - isl::multi_union_pw_aff partialSchedMupa = - partialScheduleMupa(root, scope); + auto partialSchedMupa = partialScheduleMupa(root, scope); // Schedule with block mapping filter. auto partialSched = isl::union_map::from(partialSchedMupa).intersect_domain(blockMapping); @@ -663,7 +662,7 @@ void promoteToRegistersBelow(MappedScop& mscop, detail::ScheduleTree* scope) { // performed with respect to the block mapping, so append the block schedule. // If the partial schedule contains it already, it will just end up with // identical dimensions without affecting the result of the checks. - partialSchedMupa = partialSchedMupa.flat_range_product(blockSchedule); + auto partialSchedBlockMupa = partialSchedMupa.range_product(blockSchedule); for (auto& tensorGroups : groupMap) { auto tensorId = tensorGroups.first; @@ -677,11 +676,11 @@ void promoteToRegistersBelow(MappedScop& mscop, detail::ScheduleTree* scope) { continue; } if (!isPromotableToRegistersBelow( - *group, root, scope, partialSchedMupa, threadSchedule)) { + *group, root, scope, partialSchedBlockMupa, threadSchedule)) { continue; } // Check reuse within threads. - auto schedule = partialSchedMupa.flat_range_product(threadSchedule); + auto schedule = partialSchedBlockMupa.range_product(threadSchedule); if (!hasReuseWithin(*group, schedule)) { continue; } From 84d1363a9759a6a67ecba1bd2bd8939f24fc7db1 Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Thu, 21 Jun 2018 12:05:24 +0200 Subject: [PATCH 092/102] partialScheduleMupa: use templated isl types --- tc/core/polyhedral/schedule_utils-inl.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tc/core/polyhedral/schedule_utils-inl.h b/tc/core/polyhedral/schedule_utils-inl.h index bd7ca4ec1..416f0111c 100644 --- a/tc/core/polyhedral/schedule_utils-inl.h +++ b/tc/core/polyhedral/schedule_utils-inl.h @@ -155,10 +155,10 @@ inline isl::MultiUnionPwAff partialScheduleMupa( const detail::ScheduleTree* tree) { using namespace polyhedral::detail; - isl::multi_union_pw_aff prefix = prefixScheduleMupa(root, tree); + auto prefix = prefixScheduleMupa(root, tree); auto band = tree->as(); - auto partial = band ? prefix.flat_range_product(band->mupa_) : prefix; - return isl::MultiUnionPwAff(partial); + return band ? prefix.template flat_range_product(band->mupa_) + : prefix; } /* From b29660478b20a0f62fa472b31629ab04f74fce6a Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Thu, 21 Jun 2018 12:05:24 +0200 Subject: [PATCH 093/102] activeDomainPointsHelper: use templated isl types --- tc/core/polyhedral/schedule_utils.cc | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/tc/core/polyhedral/schedule_utils.cc b/tc/core/polyhedral/schedule_utils.cc index cc8d51889..8e6f26bad 100644 --- a/tc/core/polyhedral/schedule_utils.cc +++ b/tc/core/polyhedral/schedule_utils.cc @@ -84,7 +84,7 @@ isl::UnionSet collectDomain( // Get the set of domain elements that are active below // the given branch of nodes. -isl::union_set activeDomainPointsHelper( +isl::UnionSet activeDomainPointsHelper( const ScheduleTree* root, const vector& nodes) { return collectDomain(root, nodes, &applyFilter); @@ -101,8 +101,7 @@ isl::UnionSet prefixMappingFilter( isl::UnionSet activeDomainPoints( const ScheduleTree* root, const ScheduleTree* node) { - return isl::UnionSet( - activeDomainPointsHelper(root, node->ancestors(root))); + return activeDomainPointsHelper(root, node->ancestors(root)); } isl::UnionSet activeDomainPointsBelow( @@ -110,7 +109,7 @@ isl::UnionSet activeDomainPointsBelow( const ScheduleTree* node) { auto ancestors = node->ancestors(root); ancestors.emplace_back(node); - return isl::UnionSet(activeDomainPointsHelper(root, ancestors)); + return activeDomainPointsHelper(root, ancestors); } vector collectScheduleTreesPath( From 8dc1271aeec19a113c21a227e0a0650d25d1a1de Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Thu, 21 Jun 2018 12:05:24 +0200 Subject: [PATCH 094/102] accessSubscriptsAreUnrolledLoops: temporarily remove type deduction This allows TensorReferenceGroup.originalAccesses() to be converted to templated isl types without having to convert accessSubscriptsAreUnrolledLoops at the same time. Automatic type deduction will be reintroduced when accessSubscriptsAreUnrolledLoops is converted. --- tc/core/polyhedral/cuda/memory_promotion_heuristic.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tc/core/polyhedral/cuda/memory_promotion_heuristic.cc b/tc/core/polyhedral/cuda/memory_promotion_heuristic.cc index 13407c944..47dbbe7a0 100644 --- a/tc/core/polyhedral/cuda/memory_promotion_heuristic.cc +++ b/tc/core/polyhedral/cuda/memory_promotion_heuristic.cc @@ -341,7 +341,7 @@ bool accessSubscriptsAreUnrolledLoops( unrolledDimsMupa = unrolledDimsMupa.intersect_domain(group.originalAccesses().domain()); - auto accesses = group.originalAccesses(); + isl::union_map accesses = group.originalAccesses(); auto schedule = outerSchedule.flat_range_product(unrolledDimsMupa); accesses = accesses.apply_domain(isl::union_map::from(schedule)); From b7f2fcc19757417e0981c7a17667be87d90e5e1d Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Thu, 21 Jun 2018 12:05:24 +0200 Subject: [PATCH 095/102] TensorReferenceGroup::originalAccesses use templated isl types --- tc/core/polyhedral/memory_promotion.cc | 10 +++++----- tc/core/polyhedral/memory_promotion.h | 6 +++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/tc/core/polyhedral/memory_promotion.cc b/tc/core/polyhedral/memory_promotion.cc index 252e5781c..2ff1a5bfc 100644 --- a/tc/core/polyhedral/memory_promotion.cc +++ b/tc/core/polyhedral/memory_promotion.cc @@ -216,13 +216,13 @@ isl::Map TensorReferenceGroup::scopedReads() const { } namespace { -isl::union_map referenceOriginalAccessesImpl( +isl::UnionMap referenceOriginalAccessesImpl( const TensorReferenceGroup& group, AccessType type) { if (group.references.size() == 0) { throw promotion::GroupingError("no references in the group"); } - auto accesses = isl::union_map::empty( + auto accesses = isl::UnionMap::empty( group.references.front()->originalAccess.get_space().params()); for (const auto& ref : group.references) { @@ -230,17 +230,17 @@ isl::union_map referenceOriginalAccessesImpl( continue; } auto current = ref->originalAccess; - accesses = accesses.unite(isl::union_map(current)); + accesses = accesses.unite(current.asUnionMap()); } return accesses; } } // namespace -isl::union_map TensorReferenceGroup::originalWrites() const { +isl::UnionMap TensorReferenceGroup::originalWrites() const { return referenceOriginalAccessesImpl(*this, AccessType::Write); } -isl::union_map TensorReferenceGroup::originalReads() const { +isl::UnionMap TensorReferenceGroup::originalReads() const { return referenceOriginalAccessesImpl(*this, AccessType::Read); } diff --git a/tc/core/polyhedral/memory_promotion.h b/tc/core/polyhedral/memory_promotion.h index cbf5890cb..fd2ee993d 100644 --- a/tc/core/polyhedral/memory_promotion.h +++ b/tc/core/polyhedral/memory_promotion.h @@ -135,9 +135,9 @@ class TensorReferenceGroup { // Access relations in terms of Scop domain elements. // The resulting union relations have different domain spaces but identical // range spaces. - isl::union_map originalWrites() const; - isl::union_map originalReads() const; - isl::union_map originalAccesses() const { + isl::UnionMap originalWrites() const; + isl::UnionMap originalReads() const; + isl::UnionMap originalAccesses() const { return originalWrites().unite(originalReads()); } From fea7e37fb952274434b0b90c02b243ec67db75ca Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Fri, 27 Jul 2018 10:58:45 +0200 Subject: [PATCH 096/102] makeNextElementMap: use templated isl types --- tc/core/polyhedral/cuda/memory_promotion_heuristic.cc | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/tc/core/polyhedral/cuda/memory_promotion_heuristic.cc b/tc/core/polyhedral/cuda/memory_promotion_heuristic.cc index 47dbbe7a0..920dcdbff 100644 --- a/tc/core/polyhedral/cuda/memory_promotion_heuristic.cc +++ b/tc/core/polyhedral/cuda/memory_promotion_heuristic.cc @@ -154,9 +154,12 @@ bool hasReuseWithin( * Create a map that increments the "dim"-th dimension and keeps all other * dimensions unchanged. */ -isl::map makeNextElementMap(isl::space setSpace, unsigned dim) { +template +isl::Map makeNextElementMap( + isl::Space setSpace, + unsigned dim) { auto mapSpace = setSpace.map_from_set(); - auto identityMA = isl::multi_aff::identity(mapSpace); + auto identityMA = isl::MultiAff::identity(mapSpace); size_t size = identityMA.size(); if (dim < 0 || dim >= size) { @@ -167,7 +170,7 @@ isl::map makeNextElementMap(isl::space setSpace, unsigned dim) { auto aff = identityMA.get_aff(dim); identityMA = identityMA.set_aff(dim, aff + 1); - return isl::map(identityMA); + return identityMA.asMap(); } /* From 78c61db9a5244fb98252abc5ed2c50db4fff3d14 Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Fri, 27 Jul 2018 12:16:06 +0200 Subject: [PATCH 097/102] hasReuseWithin: use templated isl types --- tc/core/polyhedral/cuda/memory_promotion_heuristic.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tc/core/polyhedral/cuda/memory_promotion_heuristic.cc b/tc/core/polyhedral/cuda/memory_promotion_heuristic.cc index 920dcdbff..d062f97a5 100644 --- a/tc/core/polyhedral/cuda/memory_promotion_heuristic.cc +++ b/tc/core/polyhedral/cuda/memory_promotion_heuristic.cc @@ -142,11 +142,11 @@ std::vector collectBranchMarkers(T root, T node) { * In other words, check that the mapping from statement instances * to pairs of outer schedule points and group elements is not injective. */ +template bool hasReuseWithin( const TensorReferenceGroup& group, - isl::multi_union_pw_aff outer) { - auto map = isl::union_map::from(outer); - map = map.range_product(group.originalAccesses()); + isl::MultiUnionPwAff outer) { + auto map = outer.toUnionMap().range_product(group.originalAccesses()); return !map.is_injective(); } From 4b8db9fd3cf7af905c8094b5bf87923113e550cb Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Thu, 21 Jun 2018 12:05:24 +0200 Subject: [PATCH 098/102] isPromotableToRegistersBelow: use templated isl types --- .../polyhedral/cuda/memory_promotion_heuristic.cc | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/tc/core/polyhedral/cuda/memory_promotion_heuristic.cc b/tc/core/polyhedral/cuda/memory_promotion_heuristic.cc index d062f97a5..ec2754cdb 100644 --- a/tc/core/polyhedral/cuda/memory_promotion_heuristic.cc +++ b/tc/core/polyhedral/cuda/memory_promotion_heuristic.cc @@ -368,23 +368,24 @@ bool accessSubscriptsAreUnrolledLoops( * thread associated to a given pair of tensor element and outer schedule * iteration. */ +template bool isPromotableToRegistersBelow( const TensorReferenceGroup& group, const detail::ScheduleTree* root, const detail::ScheduleTree* scope, - isl::multi_union_pw_aff outer, - isl::multi_union_pw_aff thread) { + isl::MultiUnionPwAff outer, + isl::MultiUnionPwAff thread) { if (!accessSubscriptsAreUnrolledLoops( - group, root, scope, outer.flat_range_product(thread))) { + group, root, scope, outer.range_product(thread))) { return false; } auto originalAccesses = group.originalAccesses(); - auto map = isl::union_map::from(outer); - map = map.range_product(originalAccesses); - map = map.apply_domain(isl::union_map::from(thread)); + auto outerMap = outer.toUnionMap(); + auto pair = outerMap.range_product(originalAccesses); + auto threadToPair = pair.apply_domain(thread.toUnionMap()); - return map.is_injective(); + return threadToPair.is_injective(); } /* From 6440b033075d0a3a04d02d1528bb2a6c9988209e Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Thu, 21 Jun 2018 12:05:24 +0200 Subject: [PATCH 099/102] accessSubscriptsAreUnrolledLoops: use templated isl types --- .../cuda/memory_promotion_heuristic.cc | 27 ++++++++++--------- tc/core/polyhedral/domain_types.h | 1 + 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/tc/core/polyhedral/cuda/memory_promotion_heuristic.cc b/tc/core/polyhedral/cuda/memory_promotion_heuristic.cc index ec2754cdb..e37d8bdc6 100644 --- a/tc/core/polyhedral/cuda/memory_promotion_heuristic.cc +++ b/tc/core/polyhedral/cuda/memory_promotion_heuristic.cc @@ -296,11 +296,12 @@ isl::UnionSet collectMappingsTo(const Scop& scop) { * different references may have different values, but all of them remain * independent of non-unrolled loop iterators. */ +template bool accessSubscriptsAreUnrolledLoops( const TensorReferenceGroup& group, const detail::ScheduleTree* root, const detail::ScheduleTree* scope, - isl::multi_union_pw_aff outerSchedule) { + isl::MultiUnionPwAff outerSchedule) { using namespace detail; auto nodes = ScheduleTree::collect(scope); @@ -315,16 +316,16 @@ bool accessSubscriptsAreUnrolledLoops( for (auto leaf : leaves) { auto ancestors = leaf->ancestors(root); ancestors.push_back(leaf); - isl::union_set subdomain = activeDomainPointsBelow(root, leaf); + auto subdomain = activeDomainPointsBelow(root, leaf); - auto unrolledDims = isl::union_pw_aff_list(leaf->ctx_, 1); + auto unrolledDims = isl::UnionPwAffListOn(leaf->ctx_, 1); for (auto node : ancestors) { - auto band = node->as(); + auto band = node->template as(); if (!band) { continue; } - isl::multi_union_pw_aff schedule = band->mupa_; + auto schedule = band->mupa_; schedule = schedule.intersect_domain(subdomain); for (size_t i = 0, e = band->nMember(); i < e; ++i) { if (!band->unroll_[i]) { @@ -334,9 +335,10 @@ bool accessSubscriptsAreUnrolledLoops( } } - auto space = - subdomain.get_space().add_unnamed_tuple_ui(unrolledDims.size()); - auto unrolledDimsMupa = isl::multi_union_pw_aff(space, unrolledDims); + auto space = subdomain.get_space().template add_unnamed_tuple_ui( + unrolledDims.size()); + auto unrolledDimsMupa = + isl::MultiUnionPwAff(space, unrolledDims); // It is possible that no loops are unrolled, in which case // unrolledDimsMupa is zero-dimensional and needs an explicit domain @@ -344,11 +346,12 @@ bool accessSubscriptsAreUnrolledLoops( unrolledDimsMupa = unrolledDimsMupa.intersect_domain(group.originalAccesses().domain()); - isl::union_map accesses = group.originalAccesses(); - auto schedule = outerSchedule.flat_range_product(unrolledDimsMupa); - accesses = accesses.apply_domain(isl::union_map::from(schedule)); + auto accesses = group.originalAccesses(); + auto schedule = outerSchedule.range_product(unrolledDimsMupa); + auto scheduleMap = schedule.toUnionMap(); + auto scheduledAccesses = accesses.apply_domain(scheduleMap); - if (!accesses.is_single_valued()) { + if (!scheduledAccesses.is_single_valued()) { return false; } } diff --git a/tc/core/polyhedral/domain_types.h b/tc/core/polyhedral/domain_types.h index 8c3410672..95f942d87 100644 --- a/tc/core/polyhedral/domain_types.h +++ b/tc/core/polyhedral/domain_types.h @@ -10,6 +10,7 @@ struct Statement; struct Tag; struct Tensor; struct Thread; +struct Unrolled; struct Warp; } // namespace polyhedral From 229a69846a671d6cb9079a9c434683bd7c978d68 Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Fri, 27 Jul 2018 16:38:16 +0200 Subject: [PATCH 100/102] collectMappingsTo: use templated isl types --- tc/core/polyhedral/cuda/memory_promotion_heuristic.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tc/core/polyhedral/cuda/memory_promotion_heuristic.cc b/tc/core/polyhedral/cuda/memory_promotion_heuristic.cc index e37d8bdc6..2b142763f 100644 --- a/tc/core/polyhedral/cuda/memory_promotion_heuristic.cc +++ b/tc/core/polyhedral/cuda/memory_promotion_heuristic.cc @@ -257,13 +257,13 @@ isl::UnionSet collectMappingsTo(const Scop& scop) { auto mappingFilters = detail::ScheduleTree::collect(root, detail::ScheduleTreeType::Mapping); mappingFilters = functional::Filter(isMappingTo, mappingFilters); - auto mapping = isl::union_set::empty(domain.get_space()); + auto mapping = isl::UnionSet::empty(domain.get_space()); for (auto mf : mappingFilters) { auto filterNode = mf->as(); auto filter = filterNode->filter_.intersect(activeDomainPoints(root, mf)); mapping = mapping.unite(filterNode->filter_); } - return isl::UnionSet(mapping); + return mapping; } /* From d0e4d1b234a7bf544fa6b6f2371ed1ca8d35fa65 Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Fri, 3 Aug 2018 10:58:33 +0200 Subject: [PATCH 101/102] TensorReferenceGroup::approximateScopedAccesses: use templated isl types --- tc/core/polyhedral/memory_promotion.cc | 17 ++++++++++------- tc/core/polyhedral/memory_promotion.h | 2 +- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/tc/core/polyhedral/memory_promotion.cc b/tc/core/polyhedral/memory_promotion.cc index 2ff1a5bfc..17cd7d4cb 100644 --- a/tc/core/polyhedral/memory_promotion.cc +++ b/tc/core/polyhedral/memory_promotion.cc @@ -114,12 +114,15 @@ std::unique_ptr TensorReferenceGroup::makeSingleton( return group; } -isl::map TensorReferenceGroup::approximateScopedAccesses() const { +isl::Map TensorReferenceGroup::approximateScopedAccesses() + const { auto scopedDomain = scopedAccesses().domain(); auto space = approximation.box.get_space(); - auto accessed = isl::map::universe(space).intersect_domain(scopedDomain); + auto accessed = + isl::Map::universe(space).intersect_domain(scopedDomain); - auto identity = isl::multi_aff::identity(space.range().map_from_set()); + auto identity = + isl::MultiAff::identity(space.range().map_from_set()); for (size_t i = 0; i < approximation.dim(); ++i) { auto offset = approximation.lowerBound(i); auto stride = approximation.stride(i); @@ -128,8 +131,8 @@ isl::map TensorReferenceGroup::approximateScopedAccesses() const { auto rhs = identity.get_aff(i); auto lowerBound = offset * stride + strideOffset; auto upperBound = (offset + size) * stride + strideOffset; - auto partial = - (isl::aff_map(lowerBound) <= rhs) & (isl::aff_map(upperBound) > rhs); + auto partial = lowerBound.asPwAff().lt_map((rhs + 1).asPwAff()) & + upperBound.asPwAff().gt_map(rhs.asPwAff()); accessed = accessed & partial; } @@ -525,9 +528,9 @@ ScheduleTree* insertCopiesUnder( auto arrayId = promotionSpace.domain().unwrap().get_map_range_tuple_id(); auto approximatedRead = group.approximateScopedAccesses().intersect_range(tensorElements).wrap(); - approximatedRead = approximatedRead.product(promotedFootprint); + auto product = approximatedRead.product(promotedFootprint); auto readExtension = - extension.intersect_range(approximatedRead).set_range_tuple_id(readId); + extension.intersect_range(product).set_range_tuple_id(readId); auto writtenElements = group.scopedWrites() .intersect_range(tensorElements) .wrap() diff --git a/tc/core/polyhedral/memory_promotion.h b/tc/core/polyhedral/memory_promotion.h index fd2ee993d..236c391d7 100644 --- a/tc/core/polyhedral/memory_promotion.h +++ b/tc/core/polyhedral/memory_promotion.h @@ -143,7 +143,7 @@ class TensorReferenceGroup { // Rectangular overapproximation of the set of tensor elements accessed below // and relative to the scoping point. - isl::map approximateScopedAccesses() const; + isl::Map approximateScopedAccesses() const; isl::MultiAff, Tensor> promotion() const; isl::Set promotedFootprint() const; From dbc73918ec3fa3c4036b32d7d9ce521b9f15188a Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Thu, 2 Aug 2018 19:46:20 +0200 Subject: [PATCH 102/102] insertCopiesUnder: use templated isl types --- tc/core/polyhedral/memory_promotion.cc | 46 ++++++++++++++------------ 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/tc/core/polyhedral/memory_promotion.cc b/tc/core/polyhedral/memory_promotion.cc index 17cd7d4cb..84224cd03 100644 --- a/tc/core/polyhedral/memory_promotion.cc +++ b/tc/core/polyhedral/memory_promotion.cc @@ -451,11 +451,12 @@ isl::Set tensorElementsSet(const Scop& scop, isl::id tensorId) { * Note that this function drops the name of the target space of "schedule", * but this space is irrelevant for the caller. */ -isl::multi_aff dropDummyTensorDimensions( - isl::multi_aff schedule, +template +isl::MultiAff dropDummyTensorDimensions( + isl::MultiAff schedule, const Scop::PromotedDecl& decl) { auto list = schedule.get_aff_list(); - auto space = schedule.get_space().domain(); + auto domainSpace = schedule.get_space().domain(); auto n = list.size(); for (int i = n - 1; i >= 0; --i) { @@ -464,8 +465,8 @@ isl::multi_aff dropDummyTensorDimensions( } } - space = space.add_unnamed_tuple_ui(list.size()); - return isl::multi_aff(space, list); + auto space = domainSpace.template add_unnamed_tuple_ui(list.size()); + return isl::MultiAff(space, list); } inline void unrollAllMembers(detail::ScheduleTreeBand* band) { @@ -489,20 +490,25 @@ ScheduleTree* insertCopiesUnder( // Take the set of all tensor elements. auto tensorElements = tensorElementsSet(scop, tensorId); - auto promotion = isl::map(group.promotion()).set_range_tuple_id(groupId); + auto promotion = + group.promotion().asMap().set_range_tuple_id(groupId); auto promotionSpace = promotion.get_space(); - auto identityCopySchedule = - isl::multi_aff::identity(promotionSpace.range().map_from_set()); + auto identityCopySchedule = isl::MultiAff::identity( + promotionSpace.range().map_from_set()); // Only iterate over significant tensor dimensions. auto decl = scop.promotedDecl(groupId); identityCopySchedule = dropDummyTensorDimensions(identityCopySchedule, decl); - auto readSpace = promotionSpace.wrap().set_set_tuple_id(readId); - auto writeSpace = promotionSpace.wrap().set_set_tuple_id(writeId); + auto readSpace = promotionSpace.wrap().set_set_tuple_id(readId); + auto writeSpace = promotionSpace.wrap().set_set_tuple_id(writeId); auto readSchedule = isl::multi_union_pw_aff(identityCopySchedule.pullback( - isl::multi_aff::wrapped_range_map(readSpace))); + isl::MultiAff< + isl::NamedPair, Promoted>, + Promoted>::wrapped_range_map(readSpace))); auto writeSchedule = isl::multi_union_pw_aff(identityCopySchedule.pullback( - isl::multi_aff::wrapped_range_map(writeSpace))); + isl::MultiAff< + isl::NamedPair, Promoted>, + Promoted>::wrapped_range_map(writeSpace))); auto readBandNode = ScheduleTree::makeBand( isl::MultiUnionPwAff(readSchedule)); @@ -524,19 +530,19 @@ ScheduleTree* insertCopiesUnder( auto promotedFootprint = group.promotedFootprint().set_tuple_id(groupId); auto scheduleUniverse = - isl::set::universe(promotionSpace.domain().unwrap().domain()); + isl::Set::universe(promotionSpace.domain().unwrap().domain()); auto arrayId = promotionSpace.domain().unwrap().get_map_range_tuple_id(); auto approximatedRead = group.approximateScopedAccesses().intersect_range(tensorElements).wrap(); auto product = approximatedRead.product(promotedFootprint); auto readExtension = - extension.intersect_range(product).set_range_tuple_id(readId); + extension.intersect_range(product).set_range_tuple_id(readId); auto writtenElements = group.scopedWrites() .intersect_range(tensorElements) .wrap() .product(promotedFootprint); - auto writeExtension = - extension.intersect_range(writtenElements).set_range_tuple_id(writeId); + auto writeExtension = extension.intersect_range(writtenElements) + .set_range_tuple_id(writeId); auto readFilterNode = ScheduleTree::makeFilter( isl::set::universe(readExtension.get_space().range()), @@ -557,18 +563,14 @@ ScheduleTree* insertCopiesUnder( if (reads) { insertExtensionBefore( - root, - tree, - tree->child({0}), - isl::UnionMap(readExtension), - std::move(readFilterNode)); + root, tree, tree->child({0}), readExtension, std::move(readFilterNode)); } if (writes) { insertExtensionAfter( root, tree, tree->child({0}), - isl::UnionMap(writeExtension), + writeExtension, std::move(writeFilterNode)); }