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