Tensor Comprehensions
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
islpp.h
Go to the documentation of this file.
1 
16 #pragma once
17 
18 #include <cassert>
19 #include <exception>
20 #include <iostream>
21 #include <string>
22 #include <unordered_map>
23 #include <vector>
24 
25 #include <glog/logging.h>
26 
27 #include <isl/interface/isl.h>
28 
29 #include "tc/core/islpp_wrap.h"
30 
31 namespace isl {
32 
33 //
34 // A bunch of isl utility functions and helpers that have not yet graduated to
35 // the official ISL C++ bindings.
36 //
37 
38 template <typename T>
39 inline T operator-(T a, T b) {
40  return a.sub(b);
41 }
42 
43 inline isl::val operator*(isl::val l, isl::val r) {
44  return l.mul(r);
45 }
46 
47 inline isl::val operator*(isl::val v, long i) {
48  return v.mul(isl::val(v.get_ctx(), i));
49 }
50 
51 inline isl::val operator*(long i, isl::val v) {
52  return v * i;
53 }
54 
55 inline isl::val operator+(isl::val l, isl::val r) {
56  return l.add(r);
57 }
58 
59 inline isl::val operator+(isl::val v, long i) {
60  return v.add(isl::val(v.get_ctx(), i));
61 }
62 
63 inline isl::val operator+(long i, isl::val v) {
64  return v + i;
65 }
66 
67 inline isl::val operator-(isl::val v, long i) {
68  return v.sub(isl::val(v.get_ctx(), i));
69 }
70 
71 inline isl::val operator-(long i, isl::val v) {
72  return isl::val(v.get_ctx(), i).sub(v);
73 }
74 
75 inline bool operator<(isl::val l, isl::val r) {
76  return l.lt(r);
77 }
78 
79 inline bool operator<=(isl::val l, isl::val r) {
80  return l.le(r);
81 }
82 
83 inline bool operator>(isl::val l, isl::val r) {
84  return l.gt(r);
85 }
86 
87 inline bool operator>=(isl::val l, isl::val r) {
88  return l.ge(r);
89 }
90 
91 inline bool operator==(isl::val v, long i) {
92  return v.eq(isl::val(v.get_ctx(), i));
93 }
94 
95 inline bool operator==(long i, isl::val v) {
96  return v == i;
97 }
98 
99 inline bool operator==(isl::val v1, isl::val v2) {
100  return v1.eq(v2);
101 }
102 
103 inline bool operator!=(isl::val v, long i) {
104  return !(v == i);
105 }
106 
107 inline bool operator!=(long i, isl::val v) {
108  return !(v == i);
109 }
110 
111 inline bool operator!=(isl::val v1, isl::val v2) {
112  return !(v1 == v2);
113 }
114 
116 // Operations on isl::aff to perform arithmetic and create/combine with sets
118 isl::aff operator*(int i, isl::aff A);
119 isl::aff operator*(isl::aff A, int i);
120 isl::aff operator*(isl::aff A, isl::val V);
121 isl::aff operator*(isl::val V, isl::aff A);
122 
123 isl::aff operator/(isl::aff A, int i);
124 
125 isl::aff operator+(int i, isl::aff A);
126 isl::aff operator+(isl::aff A, isl::aff B);
127 isl::aff operator+(isl::aff A, int i);
128 isl::aff operator+(isl::aff A, isl::val v);
129 isl::aff operator+(isl::val v, isl::aff A);
130 
131 isl::aff operator-(isl::aff A, int i);
132 isl::aff operator-(int i, isl::aff A);
133 
134 // Thin wrapper around aff to disambiguate types for operators and avoid case
135 // where return type overloading occurs
136 struct aff_set {
137  isl::aff aff;
138  aff_set(isl::aff a) : aff(a) {}
139 };
140 
141 isl::set operator>=(isl::aff_set A, int i);
142 isl::set operator>=(isl::aff_set A, isl::val v);
143 isl::set operator>=(int i, isl::aff_set A);
144 isl::set operator>=(isl::aff_set A, isl::aff B);
145 isl::set operator>=(isl::aff A, isl::aff_set B);
146 isl::set operator>(isl::aff_set A, int i);
147 isl::set operator>(int i, isl::aff_set A);
148 isl::set operator>(isl::aff_set A, isl::aff B);
149 isl::set operator>(isl::aff A, isl::aff_set B);
150 
151 isl::set operator<=(isl::aff_set A, int i);
152 isl::set operator<=(isl::aff_set A, isl::val v);
153 isl::set operator<=(int i, isl::aff_set A);
154 isl::set operator<=(isl::aff_set A, isl::aff B);
155 isl::set operator<=(isl::aff_set A, isl::aff_set B);
156 isl::set operator<(isl::aff_set A, int i);
157 isl::set operator<(isl::aff_set A, isl::val v);
158 isl::set operator<(int i, isl::aff_set A);
159 isl::set operator<(isl::aff_set A, isl::aff B);
160 isl::set operator<(isl::aff_set A, isl::aff_set B);
161 
162 isl::set operator==(isl::aff_set A, int i);
163 isl::set operator==(int i, isl::aff_set A);
164 isl::set operator==(isl::aff_set A, isl::aff B);
165 isl::set operator==(isl::aff A, isl::aff_set B);
166 
167 // Thin wrapper around aff to disambiguate types for operators and avoid case
168 // where return type overloading occurs
169 struct aff_map {
170  isl::aff aff;
171  aff_map(isl::aff a) : aff(a) {}
172 };
173 
174 isl::map operator>=(isl::aff_map A, isl::aff B);
175 isl::map operator<=(isl::aff_map A, isl::aff B);
176 isl::map operator>(isl::aff_map A, isl::aff B);
177 isl::map operator<(isl::aff_map A, isl::aff B);
178 
180 // Operations on isl::set and isl::union_set
182 isl::set operator&(isl::set S1, isl::set S2);
183 isl::union_set operator&(isl::union_set S1, isl::set S2);
184 isl::union_set operator&(isl::set S1, isl::union_set S2);
185 isl::union_set operator&(isl::union_set S1, isl::union_set S2);
186 
188 // Operations on isl::set and isl::point
190 isl::set operator&(isl::set S1, isl::point P2);
191 isl::set operator&(isl::point P1, isl::set S2);
192 
193 inline isl::map operator&(isl::map m1, isl::map m2) {
194  return m1.intersect(m2);
195 }
196 
197 inline isl::map operator|(isl::map m1, isl::map m2) {
198  return m1.unite(m2);
199 }
200 
201 namespace detail {
202 
203 inline isl::set extractFromUnion(isl::union_set uset, isl::space dim) {
204  return uset.extract_set(dim);
205 }
206 
207 inline isl::map extractFromUnion(isl::union_map umap, isl::space dim) {
208  return umap.extract_map(dim);
209 }
210 
211 inline int nElement(isl::union_set uset) {
212  return uset.n_set();
213 }
214 
215 inline int nElement(isl::union_map umap) {
216  return umap.n_map();
217 }
218 
219 inline void foreachElement(
220  const std::function<void(isl::set)>& fun,
221  isl::union_set uset) {
222  uset.foreach_set(fun);
223 }
224 
225 inline void foreachElement(
226  const std::function<void(isl::map)>& fun,
227  isl::union_map umap) {
228  umap.foreach_map(fun);
229 }
230 
231 inline isl::union_set addElement(isl::union_set uset, isl::set set) {
232  return uset.add_set(set);
233 }
234 
235 inline isl::union_map addElement(isl::union_map umap, isl::map map) {
236  return umap.add_map(map);
237 }
238 } // namespace detail
239 
240 template <typename Composite>
242  : std::vector<decltype(
243  detail::extractFromUnion(Composite(), isl::space()))> {
244  using Element = decltype(detail::extractFromUnion(Composite(), isl::space()));
246  UnionAsVector(Composite composite) {
247  this->reserve(detail::nElement(composite));
249  [&](Element e) -> void { this->push_back(e); }, composite);
250  }
251  Composite asUnion() {
252  Composite res((*this)[0]);
253  for (int i = 1; i < this->size(); ++i) {
254  res = detail::addElement(res, (*this)[i]);
255  }
256  return res;
257  }
258 };
259 
260 struct IslIdIslHash {
261  size_t operator()(const isl::id& id) const {
262  return id.get_hash();
263  }
264 };
265 
267 // Helper functions
269 template <typename T>
270 inline T dropDimsPreserveTuple(T t, isl::dim_type type, int from, int length) {
271  auto id = t.get_tuple_id(type);
272  t = t.drop_dims(type, from, length);
273  return t.set_tuple_id(type, id);
274 }
275 
276 // Given a space and a list of values, this returns the corresponding multi_val.
277 template <typename T>
278 isl::multi_val makeMultiVal(isl::space s, const std::vector<T>& vals) {
279  isl::multi_val mv = isl::multi_val::zero(s);
280  CHECK_EQ(vals.size(), s.dim(isl::dim_type::set));
281  for (size_t i = 0; i < vals.size(); ++i) {
282  mv = mv.set_val(i, isl::val(s.get_ctx(), vals[i]));
283  }
284  return mv;
285 }
286 
287 // Takes a space of parameters, a range of (ids, extent)-pairs and returns
288 // the set such that:
289 // 1. the space is paramSpace extended by all the ids (enforced to not be
290 // present in the original space)
291 // 2. each new parameter dimension p(i) is bounded to be in [0, e(i) - 1]
292 // 3. if e (i) == 0 then no constraint is set on the corresponding id(i)
293 template <typename IterPair>
294 inline isl::set makeParameterContext(
295  isl::space paramSpace,
296  const IterPair begin,
297  const IterPair end) {
298  for (auto it = begin; it != end; ++it) {
299  paramSpace = paramSpace.add_param(it->first);
300  }
301  isl::set res(isl::set::universe(paramSpace));
302  for (auto it = begin; it != end; ++it) {
303  isl::aff a(isl::aff::param_on_domain_space(paramSpace, it->first));
304  res = res & (isl::aff_set(a) >= 0) & (isl::aff_set(a) < it->second);
305  }
306  return res;
307 }
308 
309 // Given a space and values for parameters, this function creates the set
310 // that ties the space parameter to the values.
311 // This assumes space.dim(isl::dim_type::param) == paramValues.size()
312 //
313 template <typename T>
314 inline isl::set makeSpecializationSet(
315  isl::space space,
316  const std::unordered_map<int, T>& paramValues) {
317  CHECK_GE(space.dim(isl::dim_type::param), paramValues.size());
318  auto lspace = isl::local_space(space);
319  auto set = isl::set::universe(space);
320  for (auto kvp : paramValues) {
321  auto affParam = isl::aff(lspace, isl::dim_type::param, kvp.first);
322  set = set & (isl::aff_set(affParam) == kvp.second);
323  }
324  return set;
325 }
326 
327 template <typename T>
328 inline isl::set makeSpecializationSet(
329  isl::space space,
330  const std::unordered_map<std::string, T>& paramValues) {
331  CHECK_GE(space.dim(isl::dim_type::param), paramValues.size());
332  std::unordered_map<int, T> aux;
333  for (auto kvp : paramValues) {
334  auto pos = space.find_dim_by_name(isl::dim_type::param, kvp.first);
335  CHECK_LE(0, pos) << "No " << kvp.first << " in: " << space;
336  CHECK_EQ(0, aux.count(pos));
337  aux[pos] = kvp.second;
338  }
339  return makeSpecializationSet(space, aux);
340 }
341 
342 // WARNING: this version relies on parameter ordering, be sure you know what
343 // you are doing.
344 template <typename T>
345 inline isl::set makeSpecializationSet(
346  isl::space space,
347  const std::vector<T>& paramValues) {
348  CHECK_EQ(space.dim(isl::dim_type::param), paramValues.size());
349  std::unordered_map<int, T> paramValuesMap;
350  for (int i = 0; i < paramValues.size(); ++i) {
351  paramValuesMap[i] = paramValues[i];
352  }
353  return makeSpecializationSet(space, paramValuesMap);
354 }
355 
356 } // namespace isl
357 
358 namespace isl {
359 namespace with_exceptions {
360 
361 enum struct IslCtxOption : int { Uninitialized = -1, Default = 0 };
362 
364  void operator()(ctx* c) {
365  isl_ctx_free(c->release());
366  delete c;
367  }
368 };
369 typedef std::unique_ptr<ctx, CtxUPtrDeleter> CtxUPtr;
370 
371 // C++11 thread-safe init
373 
374 } // namespace with_exceptions
375 } // namespace isl
376 
isl::aff aff
Definition: islpp.h:170
isl::set operator==(isl::aff_set A, int i)
Definition: islpp-inl.h:155
isl::set operator<=(isl::aff_set A, int i)
Definition: islpp-inl.h:115
UnionAsVector(Composite composite)
Definition: islpp.h:246
isl::set makeParameterContext(isl::space paramSpace, const IterPair begin, const IterPair end)
Definition: islpp.h:294
isl::aff operator+(int i, isl::aff A)
Definition: islpp-inl.h:47
void foreachElement(const std::function< void(isl::set)> &fun, isl::union_set uset)
Definition: islpp.h:219
IslCtxOption
Definition: islpp.h:361
Definition: islpp.h:241
aff_set(isl::aff a)
Definition: islpp.h:138
UnionAsVector()
Definition: islpp.h:245
isl::set makeSpecializationSet(isl::space space, const std::unordered_map< int, T > &paramValues)
Definition: islpp.h:314
decltype(detail::extractFromUnion(Composite(), isl::space())) Element
Definition: islpp.h:244
Composite asUnion()
Definition: islpp.h:251
size_t operator()(const isl::id &id) const
Definition: islpp.h:261
isl::set operator<(isl::aff_set A, int i)
Definition: islpp-inl.h:135
isl::aff operator-(isl::aff A, int i)
Definition: islpp-inl.h:69
std::unique_ptr< ctx, CtxUPtrDeleter > CtxUPtr
Definition: islpp.h:369
isl::set operator&(isl::set S1, isl::set S2)
Definition: islpp-inl.h:194
isl::ctx globalIslCtx(IslCtxOption options=IslCtxOption::Default)
isl::map operator|(isl::map m1, isl::map m2)
Definition: islpp.h:197
int nElement(isl::union_set uset)
Definition: islpp.h:211
isl::aff aff
Definition: islpp.h:137
isl::set operator>=(isl::aff_set A, isl::val v)
Definition: islpp-inl.h:77
void operator()(ctx *c)
Definition: islpp.h:364
isl::multi_val makeMultiVal(isl::space s, const std::vector< T > &vals)
Definition: islpp.h:278
isl::aff operator/(isl::aff A, int i)
Definition: islpp-inl.h:41
isl::aff operator*(int i, isl::aff A)
Definition: islpp-inl.h:23
isl::set operator>(isl::aff_set A, int i)
Definition: islpp-inl.h:99
Definition: islpp.h:169
aff_map(isl::aff a)
Definition: islpp.h:171
bool operator!=(isl::val v, long i)
Definition: islpp.h:103
isl::set extractFromUnion(isl::union_set uset, isl::space dim)
Definition: islpp.h:203
T dropDimsPreserveTuple(T t, isl::dim_type type, int from, int length)
Definition: islpp.h:270
isl::union_set addElement(isl::union_set uset, isl::set set)
Definition: islpp.h:231
Definition: islpp.h:136
Definition: islpp.h:260