xref: /netbsd-src/external/mit/isl/dist/isl_test_python.py (revision 5971e316fdea024efff6be8f03536623db06833e)
1*5971e316Smrg# Copyright 2016-2017 Tobias Grosser
2*5971e316Smrg#
3*5971e316Smrg# Use of this software is governed by the MIT license
4*5971e316Smrg#
5*5971e316Smrg# Written by Tobias Grosser, Weststrasse 47, CH-8003, Zurich
6*5971e316Smrg
7*5971e316Smrgimport sys
8*5971e316Smrgimport isl
9*5971e316Smrg
10*5971e316Smrg# Test that isl objects can be constructed.
11*5971e316Smrg#
12*5971e316Smrg# This tests:
13*5971e316Smrg#  - construction from a string
14*5971e316Smrg#  - construction from an integer
15*5971e316Smrg#  - static constructor without a parameter
16*5971e316Smrg#  - conversion construction
17*5971e316Smrg#  - construction of empty union set
18*5971e316Smrg#
19*5971e316Smrg#  The tests to construct from integers and strings cover functionality that
20*5971e316Smrg#  is also tested in the parameter type tests, but here the presence of
21*5971e316Smrg#  multiple overloaded constructors and overload resolution is tested.
22*5971e316Smrg#
23*5971e316Smrgdef test_constructors():
24*5971e316Smrg	zero1 = isl.val("0")
25*5971e316Smrg	assert(zero1.is_zero())
26*5971e316Smrg
27*5971e316Smrg	zero2 = isl.val(0)
28*5971e316Smrg	assert(zero2.is_zero())
29*5971e316Smrg
30*5971e316Smrg	zero3 = isl.val.zero()
31*5971e316Smrg	assert(zero3.is_zero())
32*5971e316Smrg
33*5971e316Smrg	bs = isl.basic_set("{ [1] }")
34*5971e316Smrg	result = isl.set("{ [1] }")
35*5971e316Smrg	s = isl.set(bs)
36*5971e316Smrg	assert(s.is_equal(result))
37*5971e316Smrg
38*5971e316Smrg	us = isl.union_set("{ A[1]; B[2, 3] }")
39*5971e316Smrg	empty = isl.union_set.empty()
40*5971e316Smrg	assert(us.is_equal(us.union(empty)))
41*5971e316Smrg
42*5971e316Smrg# Test integer function parameters for a particular integer value.
43*5971e316Smrg#
44*5971e316Smrgdef test_int(i):
45*5971e316Smrg	val_int = isl.val(i)
46*5971e316Smrg	val_str = isl.val(str(i))
47*5971e316Smrg	assert(val_int.eq(val_str))
48*5971e316Smrg
49*5971e316Smrg# Test integer function parameters.
50*5971e316Smrg#
51*5971e316Smrg# Verify that extreme values and zero work.
52*5971e316Smrg#
53*5971e316Smrgdef test_parameters_int():
54*5971e316Smrg	test_int(sys.maxsize)
55*5971e316Smrg	test_int(-sys.maxsize - 1)
56*5971e316Smrg	test_int(0)
57*5971e316Smrg
58*5971e316Smrg# Test isl objects parameters.
59*5971e316Smrg#
60*5971e316Smrg# Verify that isl objects can be passed as lvalue and rvalue parameters.
61*5971e316Smrg# Also verify that isl object parameters are automatically type converted if
62*5971e316Smrg# there is an inheritance relation. Finally, test function calls without
63*5971e316Smrg# any additional parameters, apart from the isl object on which
64*5971e316Smrg# the method is called.
65*5971e316Smrg#
66*5971e316Smrgdef test_parameters_obj():
67*5971e316Smrg	a = isl.set("{ [0] }")
68*5971e316Smrg	b = isl.set("{ [1] }")
69*5971e316Smrg	c = isl.set("{ [2] }")
70*5971e316Smrg	expected = isl.set("{ [i] : 0 <= i <= 2 }")
71*5971e316Smrg
72*5971e316Smrg	tmp = a.union(b)
73*5971e316Smrg	res_lvalue_param = tmp.union(c)
74*5971e316Smrg	assert(res_lvalue_param.is_equal(expected))
75*5971e316Smrg
76*5971e316Smrg	res_rvalue_param = a.union(b).union(c)
77*5971e316Smrg	assert(res_rvalue_param.is_equal(expected))
78*5971e316Smrg
79*5971e316Smrg	a2 = isl.basic_set("{ [0] }")
80*5971e316Smrg	assert(a.is_equal(a2))
81*5971e316Smrg
82*5971e316Smrg	two = isl.val(2)
83*5971e316Smrg	half = isl.val("1/2")
84*5971e316Smrg	res_only_this_param = two.inv()
85*5971e316Smrg	assert(res_only_this_param.eq(half))
86*5971e316Smrg
87*5971e316Smrg# Test different kinds of parameters to be passed to functions.
88*5971e316Smrg#
89*5971e316Smrg# This includes integer and isl object parameters.
90*5971e316Smrg#
91*5971e316Smrgdef test_parameters():
92*5971e316Smrg	test_parameters_int()
93*5971e316Smrg	test_parameters_obj()
94*5971e316Smrg
95*5971e316Smrg# Test that isl objects are returned correctly.
96*5971e316Smrg#
97*5971e316Smrg# This only tests that after combining two objects, the result is successfully
98*5971e316Smrg# returned.
99*5971e316Smrg#
100*5971e316Smrgdef test_return_obj():
101*5971e316Smrg	one = isl.val("1")
102*5971e316Smrg	two = isl.val("2")
103*5971e316Smrg	three = isl.val("3")
104*5971e316Smrg
105*5971e316Smrg	res = one.add(two)
106*5971e316Smrg
107*5971e316Smrg	assert(res.eq(three))
108*5971e316Smrg
109*5971e316Smrg# Test that integer values are returned correctly.
110*5971e316Smrg#
111*5971e316Smrgdef test_return_int():
112*5971e316Smrg	one = isl.val("1")
113*5971e316Smrg	neg_one = isl.val("-1")
114*5971e316Smrg	zero = isl.val("0")
115*5971e316Smrg
116*5971e316Smrg	assert(one.sgn() > 0)
117*5971e316Smrg	assert(neg_one.sgn() < 0)
118*5971e316Smrg	assert(zero.sgn() == 0)
119*5971e316Smrg
120*5971e316Smrg# Test that isl_bool values are returned correctly.
121*5971e316Smrg#
122*5971e316Smrg# In particular, check the conversion to bool in case of true and false.
123*5971e316Smrg#
124*5971e316Smrgdef test_return_bool():
125*5971e316Smrg	empty = isl.set("{ : false }")
126*5971e316Smrg	univ = isl.set("{ : }")
127*5971e316Smrg
128*5971e316Smrg	b_true = empty.is_empty()
129*5971e316Smrg	b_false = univ.is_empty()
130*5971e316Smrg
131*5971e316Smrg	assert(b_true)
132*5971e316Smrg	assert(not b_false)
133*5971e316Smrg
134*5971e316Smrg# Test that strings are returned correctly.
135*5971e316Smrg# Do so by calling overloaded isl.ast_build.from_expr methods.
136*5971e316Smrg#
137*5971e316Smrgdef test_return_string():
138*5971e316Smrg	context = isl.set("[n] -> { : }")
139*5971e316Smrg	build = isl.ast_build.from_context(context)
140*5971e316Smrg	pw_aff = isl.pw_aff("[n] -> { [n] }")
141*5971e316Smrg	set = isl.set("[n] -> { : n >= 0 }")
142*5971e316Smrg
143*5971e316Smrg	expr = build.expr_from(pw_aff)
144*5971e316Smrg	expected_string = "n"
145*5971e316Smrg	assert(expected_string == expr.to_C_str())
146*5971e316Smrg
147*5971e316Smrg	expr = build.expr_from(set)
148*5971e316Smrg	expected_string = "n >= 0"
149*5971e316Smrg	assert(expected_string == expr.to_C_str())
150*5971e316Smrg
151*5971e316Smrg# Test that return values are handled correctly.
152*5971e316Smrg#
153*5971e316Smrg# Test that isl objects, integers, boolean values, and strings are
154*5971e316Smrg# returned correctly.
155*5971e316Smrg#
156*5971e316Smrgdef test_return():
157*5971e316Smrg	test_return_obj()
158*5971e316Smrg	test_return_int()
159*5971e316Smrg	test_return_bool()
160*5971e316Smrg	test_return_string()
161*5971e316Smrg
162*5971e316Smrg# A class that is used to test isl.id.user.
163*5971e316Smrg#
164*5971e316Smrgclass S:
165*5971e316Smrg	def __init__(self):
166*5971e316Smrg		self.value = 42
167*5971e316Smrg
168*5971e316Smrg# Test isl.id.user.
169*5971e316Smrg#
170*5971e316Smrg# In particular, check that the object attached to an identifier
171*5971e316Smrg# can be retrieved again.
172*5971e316Smrg#
173*5971e316Smrgdef test_user():
174*5971e316Smrg	id = isl.id("test", 5)
175*5971e316Smrg	id2 = isl.id("test2")
176*5971e316Smrg	id3 = isl.id("S", S())
177*5971e316Smrg	assert id.user() == 5, f"unexpected user object {id.user()}"
178*5971e316Smrg	assert id2.user() is None, f"unexpected user object {id2.user()}"
179*5971e316Smrg	s = id3.user()
180*5971e316Smrg	assert isinstance(s, S), f"unexpected user object {s}"
181*5971e316Smrg	assert s.value == 42, f"unexpected user object {s}"
182*5971e316Smrg
183*5971e316Smrg# Test that foreach functions are modeled correctly.
184*5971e316Smrg#
185*5971e316Smrg# Verify that closures are correctly called as callback of a 'foreach'
186*5971e316Smrg# function and that variables captured by the closure work correctly. Also
187*5971e316Smrg# check that the foreach function handles exceptions thrown from
188*5971e316Smrg# the closure and that it propagates the exception.
189*5971e316Smrg#
190*5971e316Smrgdef test_foreach():
191*5971e316Smrg	s = isl.set("{ [0]; [1]; [2] }")
192*5971e316Smrg
193*5971e316Smrg	list = []
194*5971e316Smrg	def add(bs):
195*5971e316Smrg		list.append(bs)
196*5971e316Smrg	s.foreach_basic_set(add)
197*5971e316Smrg
198*5971e316Smrg	assert(len(list) == 3)
199*5971e316Smrg	assert(list[0].is_subset(s))
200*5971e316Smrg	assert(list[1].is_subset(s))
201*5971e316Smrg	assert(list[2].is_subset(s))
202*5971e316Smrg	assert(not list[0].is_equal(list[1]))
203*5971e316Smrg	assert(not list[0].is_equal(list[2]))
204*5971e316Smrg	assert(not list[1].is_equal(list[2]))
205*5971e316Smrg
206*5971e316Smrg	def fail(bs):
207*5971e316Smrg		raise Exception("fail")
208*5971e316Smrg
209*5971e316Smrg	caught = False
210*5971e316Smrg	try:
211*5971e316Smrg		s.foreach_basic_set(fail)
212*5971e316Smrg	except:
213*5971e316Smrg		caught = True
214*5971e316Smrg	assert(caught)
215*5971e316Smrg
216*5971e316Smrg# Test the functionality of "foreach_scc" functions.
217*5971e316Smrg#
218*5971e316Smrg# In particular, test it on a list of elements that can be completely sorted
219*5971e316Smrg# but where two of the elements ("a" and "b") are incomparable.
220*5971e316Smrg#
221*5971e316Smrgdef test_foreach_scc():
222*5971e316Smrg	list = isl.id_list(3)
223*5971e316Smrg	sorted = [isl.id_list(3)]
224*5971e316Smrg	data = {
225*5971e316Smrg		'a' : isl.map("{ [0] -> [1] }"),
226*5971e316Smrg		'b' : isl.map("{ [1] -> [0] }"),
227*5971e316Smrg		'c' : isl.map("{ [i = 0:1] -> [i] }"),
228*5971e316Smrg	}
229*5971e316Smrg	for k, v in data.items():
230*5971e316Smrg		list = list.add(k)
231*5971e316Smrg	id = data['a'].space().domain().identity_multi_pw_aff_on_domain()
232*5971e316Smrg	def follows(a, b):
233*5971e316Smrg		map = data[b.name()].apply_domain(data[a.name()])
234*5971e316Smrg		return not map.lex_ge_at(id).is_empty()
235*5971e316Smrg
236*5971e316Smrg	def add_single(scc):
237*5971e316Smrg		assert(scc.size() == 1)
238*5971e316Smrg		sorted[0] = sorted[0].concat(scc)
239*5971e316Smrg
240*5971e316Smrg	list.foreach_scc(follows, add_single)
241*5971e316Smrg	assert(sorted[0].size() == 3)
242*5971e316Smrg	assert(sorted[0].at(0).name() == "b")
243*5971e316Smrg	assert(sorted[0].at(1).name() == "c")
244*5971e316Smrg	assert(sorted[0].at(2).name() == "a")
245*5971e316Smrg
246*5971e316Smrg# Test the functionality of "every" functions.
247*5971e316Smrg#
248*5971e316Smrg# In particular, test the generic functionality and
249*5971e316Smrg# test that exceptions are properly propagated.
250*5971e316Smrg#
251*5971e316Smrgdef test_every():
252*5971e316Smrg	us = isl.union_set("{ A[i]; B[j] }")
253*5971e316Smrg
254*5971e316Smrg	def is_empty(s):
255*5971e316Smrg		return s.is_empty()
256*5971e316Smrg	assert(not us.every_set(is_empty))
257*5971e316Smrg
258*5971e316Smrg	def is_non_empty(s):
259*5971e316Smrg		return not s.is_empty()
260*5971e316Smrg	assert(us.every_set(is_non_empty))
261*5971e316Smrg
262*5971e316Smrg	def in_A(s):
263*5971e316Smrg		return s.is_subset(isl.set("{ A[x] }"))
264*5971e316Smrg	assert(not us.every_set(in_A))
265*5971e316Smrg
266*5971e316Smrg	def not_in_A(s):
267*5971e316Smrg		return not s.is_subset(isl.set("{ A[x] }"))
268*5971e316Smrg	assert(not us.every_set(not_in_A))
269*5971e316Smrg
270*5971e316Smrg	def fail(s):
271*5971e316Smrg		raise Exception("fail")
272*5971e316Smrg
273*5971e316Smrg	caught = False
274*5971e316Smrg	try:
275*5971e316Smrg		us.ever_set(fail)
276*5971e316Smrg	except:
277*5971e316Smrg		caught = True
278*5971e316Smrg	assert(caught)
279*5971e316Smrg
280*5971e316Smrg# Check basic construction of spaces.
281*5971e316Smrg#
282*5971e316Smrgdef test_space():
283*5971e316Smrg	unit = isl.space.unit()
284*5971e316Smrg	set_space = unit.add_named_tuple("A", 3)
285*5971e316Smrg	map_space = set_space.add_named_tuple("B", 2)
286*5971e316Smrg
287*5971e316Smrg	set = isl.set.universe(set_space)
288*5971e316Smrg	map = isl.map.universe(map_space)
289*5971e316Smrg	assert(set.is_equal(isl.set("{ A[*,*,*] }")))
290*5971e316Smrg	assert(map.is_equal(isl.map("{ A[*,*,*] -> B[*,*] }")))
291*5971e316Smrg
292*5971e316Smrg# Construct a simple schedule tree with an outer sequence node and
293*5971e316Smrg# a single-dimensional band node in each branch, with one of them
294*5971e316Smrg# marked coincident.
295*5971e316Smrg#
296*5971e316Smrgdef construct_schedule_tree():
297*5971e316Smrg	A = isl.union_set("{ A[i] : 0 <= i < 10 }")
298*5971e316Smrg	B = isl.union_set("{ B[i] : 0 <= i < 20 }")
299*5971e316Smrg
300*5971e316Smrg	node = isl.schedule_node.from_domain(A.union(B))
301*5971e316Smrg	node = node.child(0)
302*5971e316Smrg
303*5971e316Smrg	filters = isl.union_set_list(A).add(B)
304*5971e316Smrg	node = node.insert_sequence(filters)
305*5971e316Smrg
306*5971e316Smrg	f_A = isl.multi_union_pw_aff("[ { A[i] -> [i] } ]")
307*5971e316Smrg	node = node.child(0)
308*5971e316Smrg	node = node.child(0)
309*5971e316Smrg	node = node.insert_partial_schedule(f_A)
310*5971e316Smrg	node = node.member_set_coincident(0, True)
311*5971e316Smrg	node = node.ancestor(2)
312*5971e316Smrg
313*5971e316Smrg	f_B = isl.multi_union_pw_aff("[ { B[i] -> [i] } ]")
314*5971e316Smrg	node = node.child(1)
315*5971e316Smrg	node = node.child(0)
316*5971e316Smrg	node = node.insert_partial_schedule(f_B)
317*5971e316Smrg	node = node.ancestor(2)
318*5971e316Smrg
319*5971e316Smrg	return node.schedule()
320*5971e316Smrg
321*5971e316Smrg# Test basic schedule tree functionality.
322*5971e316Smrg#
323*5971e316Smrg# In particular, create a simple schedule tree and
324*5971e316Smrg# - check that the root node is a domain node
325*5971e316Smrg# - test map_descendant_bottom_up
326*5971e316Smrg# - test foreach_descendant_top_down
327*5971e316Smrg# - test every_descendant
328*5971e316Smrg#
329*5971e316Smrgdef test_schedule_tree():
330*5971e316Smrg	schedule = construct_schedule_tree()
331*5971e316Smrg	root = schedule.root()
332*5971e316Smrg
333*5971e316Smrg	assert(type(root) == isl.schedule_node_domain)
334*5971e316Smrg
335*5971e316Smrg	count = [0]
336*5971e316Smrg	def inc_count(node):
337*5971e316Smrg		count[0] += 1
338*5971e316Smrg		return node
339*5971e316Smrg	root = root.map_descendant_bottom_up(inc_count)
340*5971e316Smrg	assert(count[0] == 8)
341*5971e316Smrg
342*5971e316Smrg	def fail_map(node):
343*5971e316Smrg		raise Exception("fail")
344*5971e316Smrg		return node
345*5971e316Smrg	caught = False
346*5971e316Smrg	try:
347*5971e316Smrg		root.map_descendant_bottom_up(fail_map)
348*5971e316Smrg	except:
349*5971e316Smrg		caught = True
350*5971e316Smrg	assert(caught)
351*5971e316Smrg
352*5971e316Smrg	count = [0]
353*5971e316Smrg	def inc_count(node):
354*5971e316Smrg		count[0] += 1
355*5971e316Smrg		return True
356*5971e316Smrg	root.foreach_descendant_top_down(inc_count)
357*5971e316Smrg	assert(count[0] == 8)
358*5971e316Smrg
359*5971e316Smrg	count = [0]
360*5971e316Smrg	def inc_count(node):
361*5971e316Smrg		count[0] += 1
362*5971e316Smrg		return False
363*5971e316Smrg	root.foreach_descendant_top_down(inc_count)
364*5971e316Smrg	assert(count[0] == 1)
365*5971e316Smrg
366*5971e316Smrg	def is_not_domain(node):
367*5971e316Smrg		return type(node) != isl.schedule_node_domain
368*5971e316Smrg	assert(root.child(0).every_descendant(is_not_domain))
369*5971e316Smrg	assert(not root.every_descendant(is_not_domain))
370*5971e316Smrg
371*5971e316Smrg	def fail(node):
372*5971e316Smrg		raise Exception("fail")
373*5971e316Smrg	caught = False
374*5971e316Smrg	try:
375*5971e316Smrg		root.every_descendant(fail)
376*5971e316Smrg	except:
377*5971e316Smrg		caught = True
378*5971e316Smrg	assert(caught)
379*5971e316Smrg
380*5971e316Smrg	domain = root.domain()
381*5971e316Smrg	filters = [isl.union_set("{}")]
382*5971e316Smrg	def collect_filters(node):
383*5971e316Smrg		if type(node) == isl.schedule_node_filter:
384*5971e316Smrg			filters[0] = filters[0].union(node.filter())
385*5971e316Smrg		return True
386*5971e316Smrg	root.every_descendant(collect_filters)
387*5971e316Smrg	assert(domain.is_equal(filters[0]))
388*5971e316Smrg
389*5971e316Smrg# Test marking band members for unrolling.
390*5971e316Smrg# "schedule" is the schedule created by construct_schedule_tree.
391*5971e316Smrg# It schedules two statements, with 10 and 20 instances, respectively.
392*5971e316Smrg# Unrolling all band members therefore results in 30 at-domain calls
393*5971e316Smrg# by the AST generator.
394*5971e316Smrg#
395*5971e316Smrgdef test_ast_build_unroll(schedule):
396*5971e316Smrg	root = schedule.root()
397*5971e316Smrg	def mark_unroll(node):
398*5971e316Smrg		if type(node) == isl.schedule_node_band:
399*5971e316Smrg			node = node.member_set_ast_loop_unroll(0)
400*5971e316Smrg		return node
401*5971e316Smrg	root = root.map_descendant_bottom_up(mark_unroll)
402*5971e316Smrg	schedule = root.schedule()
403*5971e316Smrg
404*5971e316Smrg	count_ast = [0]
405*5971e316Smrg	def inc_count_ast(node, build):
406*5971e316Smrg		count_ast[0] += 1
407*5971e316Smrg		return node
408*5971e316Smrg
409*5971e316Smrg	build = isl.ast_build()
410*5971e316Smrg	build = build.set_at_each_domain(inc_count_ast)
411*5971e316Smrg	ast = build.node_from(schedule)
412*5971e316Smrg	assert(count_ast[0] == 30)
413*5971e316Smrg
414*5971e316Smrg# Test basic AST generation from a schedule tree.
415*5971e316Smrg#
416*5971e316Smrg# In particular, create a simple schedule tree and
417*5971e316Smrg# - generate an AST from the schedule tree
418*5971e316Smrg# - test at_each_domain
419*5971e316Smrg# - test unrolling
420*5971e316Smrg#
421*5971e316Smrgdef test_ast_build():
422*5971e316Smrg	schedule = construct_schedule_tree()
423*5971e316Smrg
424*5971e316Smrg	count_ast = [0]
425*5971e316Smrg	def inc_count_ast(node, build):
426*5971e316Smrg		count_ast[0] += 1
427*5971e316Smrg		return node
428*5971e316Smrg
429*5971e316Smrg	build = isl.ast_build()
430*5971e316Smrg	build_copy = build.set_at_each_domain(inc_count_ast)
431*5971e316Smrg	ast = build.node_from(schedule)
432*5971e316Smrg	assert(count_ast[0] == 0)
433*5971e316Smrg	count_ast[0] = 0
434*5971e316Smrg	ast = build_copy.node_from(schedule)
435*5971e316Smrg	assert(count_ast[0] == 2)
436*5971e316Smrg	build = build_copy
437*5971e316Smrg	count_ast[0] = 0
438*5971e316Smrg	ast = build.node_from(schedule)
439*5971e316Smrg	assert(count_ast[0] == 2)
440*5971e316Smrg
441*5971e316Smrg	do_fail = True
442*5971e316Smrg	count_ast_fail = [0]
443*5971e316Smrg	def fail_inc_count_ast(node, build):
444*5971e316Smrg		count_ast_fail[0] += 1
445*5971e316Smrg		if do_fail:
446*5971e316Smrg			raise Exception("fail")
447*5971e316Smrg		return node
448*5971e316Smrg	build = isl.ast_build()
449*5971e316Smrg	build = build.set_at_each_domain(fail_inc_count_ast)
450*5971e316Smrg	caught = False
451*5971e316Smrg	try:
452*5971e316Smrg		ast = build.node_from(schedule)
453*5971e316Smrg	except:
454*5971e316Smrg		caught = True
455*5971e316Smrg	assert(caught)
456*5971e316Smrg	assert(count_ast_fail[0] > 0)
457*5971e316Smrg	build_copy = build
458*5971e316Smrg	build_copy = build_copy.set_at_each_domain(inc_count_ast)
459*5971e316Smrg	count_ast[0] = 0
460*5971e316Smrg	ast = build_copy.node_from(schedule)
461*5971e316Smrg	assert(count_ast[0] == 2)
462*5971e316Smrg	count_ast_fail[0] = 0
463*5971e316Smrg	do_fail = False
464*5971e316Smrg	ast = build.node_from(schedule)
465*5971e316Smrg	assert(count_ast_fail[0] == 2)
466*5971e316Smrg
467*5971e316Smrg	test_ast_build_unroll(schedule)
468*5971e316Smrg
469*5971e316Smrg# Test basic AST expression generation from an affine expression.
470*5971e316Smrg#
471*5971e316Smrgdef test_ast_build_expr():
472*5971e316Smrg	pa = isl.pw_aff("[n] -> { [n + 1] }")
473*5971e316Smrg	build = isl.ast_build.from_context(pa.domain())
474*5971e316Smrg
475*5971e316Smrg	op = build.expr_from(pa)
476*5971e316Smrg	assert(type(op) == isl.ast_expr_op_add)
477*5971e316Smrg	assert(op.n_arg() == 2)
478*5971e316Smrg
479*5971e316Smrg# Test the isl Python interface
480*5971e316Smrg#
481*5971e316Smrg# This includes:
482*5971e316Smrg#  - Object construction
483*5971e316Smrg#  - Different parameter types
484*5971e316Smrg#  - Different return types
485*5971e316Smrg#  - isl.id.user
486*5971e316Smrg#  - Foreach functions
487*5971e316Smrg#  - Foreach SCC function
488*5971e316Smrg#  - Every functions
489*5971e316Smrg#  - Spaces
490*5971e316Smrg#  - Schedule trees
491*5971e316Smrg#  - AST generation
492*5971e316Smrg#  - AST expression generation
493*5971e316Smrg#
494*5971e316Smrgtest_constructors()
495*5971e316Smrgtest_parameters()
496*5971e316Smrgtest_return()
497*5971e316Smrgtest_user()
498*5971e316Smrgtest_foreach()
499*5971e316Smrgtest_foreach_scc()
500*5971e316Smrgtest_every()
501*5971e316Smrgtest_space()
502*5971e316Smrgtest_schedule_tree()
503*5971e316Smrgtest_ast_build()
504*5971e316Smrgtest_ast_build_expr()
505