def test_pass_numpy_int(): np = pytest.importorskip("numpy") s = isl.BasicMap("{[i,j]: 0<=i,j<15}") c0 = s.get_constraints()[0] c1 = c0.set_constant_val(np.int32(5)) print(c1)
def test_align_spaces(): m1 = isl.BasicMap("[m,n] -> {[i,j,k]->[l,o]:}") m2 = isl.BasicMap("[m,n] -> {[j,k,l,i]->[o]:}") result = isl.align_spaces(m1, m2) assert result.get_var_dict() == m2.get_var_dict() a1 = isl.Aff("[t0, t1, t2] -> { [(32)] }") a2 = isl.Aff("[t1, t0] -> { [(0)] }") with pytest.raises(isl.Error): a1_aligned = isl.align_spaces(a1, a2) a1_aligned = isl.align_spaces(a1, a2, obj_bigger_ok=True) a2_aligned = isl.align_spaces(a2, a1) assert a1_aligned == isl.Aff("[t1, t0, t2] -> { [(32)] }") assert a2_aligned == isl.Aff("[t1, t0, t2] -> { [(0)] }")
def test_diamond_tiling(ctx_factory, interactive=False): ctx = ctx_factory() queue = cl.CommandQueue(ctx) ref_knl = lp.make_kernel( "[nx,nt] -> {[ix, it]: 1<=ix<nx-1 and 0<=it<nt}", """ u[ix, it+2] = ( 2*u[ix, it+1] + dt**2/dx**2 * (u[ix+1, it+1] - 2*u[ix, it+1] + u[ix-1, it+1]) - u[ix, it]) """) knl_for_transform = ref_knl ref_knl = lp.prioritize_loops(ref_knl, "it, ix") import islpy as isl m = isl.BasicMap( "[nx,nt] -> {[ix, it] -> [tx, tt, tparity, itt, itx]: " "16*(tx - tt) + itx - itt = ix - it and " "16*(tx + tt + tparity) + itt + itx = ix + it and " "0<=tparity<2 and 0 <= itx - itt < 16 and 0 <= itt+itx < 16}") knl = lp.map_domain(knl_for_transform, m) knl = lp.prioritize_loops(knl, "tt,tparity,tx,itt,itx") if interactive: nx = 43 u = np.zeros((nx, 200)) x = np.linspace(-1, 1, nx) dx = x[1] - x[0] u[:, 0] = u[:, 1] = np.exp(-100 * x**2) u_dev = cl.array.to_device(queue, u) knl(queue, u=u_dev, dx=dx, dt=dx) u = u_dev.get() import matplotlib.pyplot as plt plt.imshow(u.T) plt.show() else: types = {"dt,dx,u": np.float64} knl = lp.add_and_infer_dtypes(knl, types) ref_knl = lp.add_and_infer_dtypes(ref_knl, types) lp.auto_test_vs_ref(ref_knl, ctx, knl, parameters={ "nx": 200, "nt": 300, "dx": 1, "dt": 1 })
def islApiExamples(): ctx = isl.Context() ## Spaces names = ['s\'', 'x1', 'x2'] space1 = isl.Space.create_from_names(ctx, set = names) names = ['s', 'y1', 'y2'] space2 = isl.Space.create_from_names(ctx, set = names) #Spaces are equal when their dimensions are equal print space1.is_equal(space2) #isl dim type can be set/in/out/param/all print space1.find_dim_by_name(isl._isl.dim_type.all,'x2') #print space1.get_id_dict(isl._isl.dim_type.set) newid = isl.Id(context = ctx, name = 'x0') space1 = space1.set_dim_id(isl._isl.dim_type.set, 1, newid) print space1.get_dim_id(isl._isl.dim_type.set, 1) #Looks like get_id_dict does not work as expected #print space1.get_id_dict(isl._isl.dim_type.set) print space1.get_var_dict() ## Sets space = isl.Space.create_from_names(ctx, set=["i", "j"]) bset1 = (isl.BasicSet.universe(space) .add_constraint(isl.Constraint.ineq_from_names(space, {1: -1, "i": 1})) .add_constraint(isl.Constraint.ineq_from_names(space, {1: 5, "i": -1})) .add_constraint(isl.Constraint.ineq_from_names(space, {1: -1, "j": 1})) .add_constraint(isl.Constraint.ineq_from_names(space, {1: 5, "j": -1}))) print bset1 bset2 = isl.BasicSet("[N]->{[x, y] : x >= 0 and x < 5 and y >= 0 and y < N+4 and N >= 0 and N < 10}") print bset2 print bset2.polyhedral_hull() print bset2.lexmax() print bset2.lexmin() print bset2.lexmin().is_singleton() ## Points points = [] bset1.foreach_point(points.append) print points point = points[0].get_coordinate_val(isl._isl.dim_type.all, 0) pointx = point.get_num_si()/point.get_num_si() # The same thing can be achieved with to_python() provided by islpy print point.to_python() point = points[0].get_coordinate_val(isl._isl.dim_type.all, 1) pointy = point.get_num_si()/point.get_num_si() print (pointx, pointy) ## Dependence computation mapspace = isl.Space.create_from_names(ctx, in_=["i", "j"], out = ["i1", "j1"], params = ["N"]) ## Schedule and AST # Creating an identity schedule bmap = (isl.BasicMap.identity(mapspace) .add_constraint(isl.Constraint.ineq_from_names(mapspace, {1: -1, "i": 1})) .add_constraint(isl.Constraint.ineq_from_names(mapspace, {"N": 1, "i": -1})) .add_constraint(isl.Constraint.ineq_from_names(mapspace, {1: -1, "j": 1})) .add_constraint(isl.Constraint.ineq_from_names(mapspace, {"N": 1, "j": -1}))) #bmap = bmap.insert_dims(isl._isl.dim_type.out, 0, 1) #name = bmap.get_dim_name(isl._isl.dim_type.out, 1) #bmap = bmap.set_dim_name(isl._isl.dim_type.out, dim, 'S_' + name) print bmap astbld = isl.AstBuild.from_context(isl.BasicSet("[N] -> { : }")) astbld = astbld.set_options(isl.UnionMap("{}")) # Printing is strange printer = isl.Printer.to_str(ctx) printer = printer.set_output_format(isl.format.C) printer = (isl.AstBuild.ast_from_schedule(astbld, isl.UnionMap.from_map(bmap))).print_(printer, isl.AstPrintOptions.alloc(ctx)) print printer.get_str() extSet = isl.BasicSet("[n] -> { [i] : exists (a = [i/10] : 0 <= i and i <= n and i - 10 a <= 6) }") print extSet print extSet.get_local_space() print extSet.get_local_space().get_div(0) extMap = isl.BasicMap.from_domain_and_range(extSet, extSet) astbld = isl.AstBuild.from_context(isl.BasicSet("[n] -> { : }")) astbld = astbld.set_options(isl.UnionMap("{}")) # Printing is strange printer = isl.Printer.to_str(ctx) printer = printer.set_output_format(isl.format.C) printer = (isl.AstBuild.ast_from_schedule(astbld, isl.UnionMap.from_map(extMap))).print_(printer, isl.AstPrintOptions.alloc(ctx)) print printer.get_str() gen = isl.BasicMap("[C, R] -> { Ixx[x, y] -> [Dir_i0', T_i0', Dir_i1', T_i1', t, i0', i1'] : t = 0 and i0' = x and i1' = y and x >= 1 and x <= R and y >= 1 and y <= C and R >= 1 and C >= 1 and 64T_i0' <= x and 64T_i0' >= -63 + x and 64T_i0' <= -32 + x - 64Dir_i0' and 64T_i0' >= -95 + x - 64Dir_i0' and Dir_i0' >= -1 and Dir_i0' <= 0 and 64T_i1' <= y and 64T_i1' >= -63 + y and 64T_i1' <= -32 + y - 64Dir_i1' and 64T_i1' >= -95 + y - 64Dir_i1' and Dir_i1' >= -1 and Dir_i1' <= 0 }") #gen = isl.UnionMap("[R, C] -> { harris[x, y] -> [1, x, y] : C = 10 and R = 10 and x >= 2 and x <= 9 and y >= 2 and y <= 9; Iyy[x, y] -> [0, x, y] : C = 10 and R = 10 and x >= 1 and x <= 10 and y >= 1 and y <= 10}") genbld = isl.AstBuild.from_context(isl.BasicSet("[C, R]->{: R > 1 and C > 1}")) #genbld = astbld.set_options(isl.UnionMap("{[i,j] -> unroll[0] : i < 4 or i > 99996}")) id_ = isl.Id.alloc(ctx, "Test1", "FakeObj") gen = gen.set_tuple_id(isl._isl.dim_type.in_, id_) #id_ = isl.Id.alloc(ctx, "Test2", "FakeObj") #print gen.get_tuple_name(isl._isl.dim_type.out) genbld = genbld.set_options(isl.UnionMap("[C, R] -> { [Dir_i0', T_i0', Dir_i1', T_i1', t, i0', i1'] -> unroll[x] : x = 0 or x = 2}")) idl = isl.IdList.alloc(ctx, 3) print idl idl = idl.add(isl.Id.alloc(ctx, 'Dir_i0', None)) idl = idl.add(isl.Id.alloc(ctx, 'T_i0', None)) idl = idl.add(isl.Id.alloc(ctx, 'Dir_i1', None)) idl = idl.add(isl.Id.alloc(ctx, 'T_i1', None)) idl = idl.add(isl.Id.alloc(ctx, 't', None)) idl = idl.add(isl.Id.alloc(ctx, 'i0', None)) idl = idl.add(isl.Id.alloc(ctx, 'i1', None)) genbld = genbld.set_iterators(idl) printer = isl.Printer.to_str(ctx) printer = printer.set_output_format(isl.format.C) #astRoot = isl.AstBuild.ast_from_schedule(genbld, isl.UnionMap.from_map(gen)) print genbld.get_schedule_space() astRoot = genbld.ast_from_schedule(isl.UnionMap.from_map(gen)) print genbld.get_schedule_space() printer = astRoot.print_(printer, isl.AstPrintOptions.alloc(ctx)) print printer.get_str() applyBase = isl.BasicMap("[rows, cols] -> { Dx_2_img2[c, x, y] -> [3, c, x, y] : c >= 0 and c <= 2 and x >= 2 and 4x <= 4 + rows and y >= 2 and 2y <= 2 + cols and rows >= 1 and cols >= 1 }") align = isl.BasicMap("[rows, cols]->{[a, b, c, d] -> [a, d, b, c]}") print applyBase.apply_range(align) mem = isl.BasicMap("[cols, rows] -> { Uy_2_img2[c, x, y] -> [c, T_i1', T_i2', 7, 4x, 4y] : c >= 0 and c <= 2 and x >= 2 and 4x <= 4 + rows and y >= 2 and 4y <= 4 + cols and rows >= 1 and cols >= 1 and 64T_i1' <= -2 + x and 64T_i1' >= -70 + x and 64T_i2' <= -2 + y and 64T_i2' >= -73 + y }") acc = isl.BasicMap("[cols, rows] -> { Uy_2_img2[c, x, y] -> [c, T_i1', T_i2', 7, x-64T_i1', y-64T_i2'] : c >= 0 and c <= 2 and x >= 2 and 4x <= 4 + rows and y >= 2 and 4y <= 4 + cols and rows >= 1 and cols >= 1 and 64T_i1' <= -2 + x and 64T_i1' >= -70 + x and 64T_i2' <= -2 + y and 64T_i2' >= -73 + y and rows >= 256 and cols >= 256}") print acc.range().dim_min(4), acc.range().dim_max(4) split = isl.BasicMap("[cols, rows] -> { Uy_0_img1[c, x, y, _Mul_x, _Mul_y] -> [_T_i1, _T_i2, 1, 5, c, x, y] : exists (e0 = floor((-1 + y)/2): rows = 768 and 64_T_i1 = x - _Mul_x and 64_T_i2 = y - _Mul_y and cols = 1024 and 2e0 = -1 + y and c >= 0 and c <= 2 and x >= 2 and x <= 769 and y >= 2 and y <= 1025) }") print split
def test_align_spaces(): m1 = isl.BasicMap("[m,n] -> {[i,j,k]->[l,o]:}") m2 = isl.BasicMap("[m,n] -> {[j,k,l,i]->[o]:}") result = isl.align_spaces(m1, m2) assert result.get_var_dict() == m2.get_var_dict()
def test_map_domain_transform_map_validity_and_errors(ctx_factory): # {{{ Make kernel knl = lp.make_kernel( [ "[nx,nt] -> {[x, y, z, t]: 0 <= x,y,z < nx and 0 <= t < nt}", "[m] -> {[j]: 0 <= j < m}", ], """ a[y,x,t,z] = b[y,x,t,z] {id=stmta} for j <>temp = j {dep=stmta} end """, lang_version=(2018, 2), ) knl = lp.add_and_infer_dtypes(knl, {"b": np.float32}) ref_knl = knl # }}} # {{{ Make sure map_domain *succeeds* when map includes 2 of 4 dims in one # domain. # {{{ Apply domain change mapping that splits t and renames y; (similar to # split_iname test above, but doesn't hurt to test this slightly different # scenario) knl_map_dom = ref_knl # Create map_domain mapping that only includes t and y # (x and z should be unaffected) import islpy as isl transform_map = isl.BasicMap( "[nx,nt] -> {[t, y] -> [t_outer, t_inner, y_new]: " "0 <= t_inner < 16 and " "16*t_outer + t_inner = t and " "0 <= 16*t_outer + t_inner < nt and " "y = y_new" "}") # Call map_domain to transform kernel; this should *not* produce an error knl_map_dom = lp.map_domain(knl_map_dom, transform_map) # Prioritize loops desired_prio = "x, t_outer, t_inner, z, y_new" # Use constrain_loop_nesting if it's available cln_attr = getattr(lp, "constrain_loop_nesting", None) if cln_attr is not None: knl_map_dom = lp.constrain_loop_nesting( # noqa pylint:disable=no-member knl_map_dom, desired_prio) else: knl_map_dom = lp.prioritize_loops(knl_map_dom, desired_prio) # Get a linearization proc_knl_map_dom = lp.preprocess_kernel(knl_map_dom) lin_knl_map_dom = lp.get_one_linearized_kernel( proc_knl_map_dom["loopy_kernel"], proc_knl_map_dom.callables_table) # }}} # {{{ Use split_iname and rename_iname, and make sure we get the same result knl_split_iname = ref_knl knl_split_iname = lp.split_iname(knl_split_iname, "t", 16) knl_split_iname = lp.rename_iname(knl_split_iname, "y", "y_new") try: # Use constrain_loop_nesting if it's available knl_split_iname = lp.constrain_loop_nesting(knl_split_iname, desired_prio) except AttributeError: knl_split_iname = lp.prioritize_loops(knl_split_iname, desired_prio) proc_knl_split_iname = lp.preprocess_kernel(knl_split_iname) lin_knl_split_iname = lp.get_one_linearized_kernel( proc_knl_split_iname["loopy_kernel"], proc_knl_split_iname.callables_table) for d_map_domain, d_split_iname in zip( knl_map_dom["loopy_kernel"].domains, knl_split_iname["loopy_kernel"].domains): d_map_domain_aligned = _ensure_dim_names_match_and_align( d_map_domain, d_split_iname) assert d_map_domain_aligned == d_split_iname for litem_map_domain, litem_split_iname in zip( lin_knl_map_dom.linearization, lin_knl_split_iname.linearization): assert litem_map_domain == litem_split_iname # Can't easily compare instructions because equivalent subscript # expressions may have different orders lp.auto_test_vs_ref(proc_knl_split_iname, ctx_factory(), proc_knl_map_dom, parameters={ "nx": 32, "nt": 32, "m": 32 }) # }}} # }}} # {{{ Make sure we error on a map that is not bijective # Not bijective transform_map = isl.BasicMap( "[nx,nt] -> {[t, y, rogue] -> [t_new, y_new]: " "y = y_new and t = t_new" "}") from loopy.diagnostic import LoopyError knl = ref_knl try: knl = lp.map_domain(knl, transform_map) raise AssertionError() except LoopyError as err: assert "map must be bijective" in str(err) # }}} # {{{ Make sure there's an error if transform map does not apply to # exactly one domain. test_maps = [ # Map where some inames match exactly one domain but there's also a # rogue dim isl.BasicMap("[nx,nt] -> {[t, y, rogue] -> [t_new, y_new, rogue_new]: " "y = y_new and t = t_new and rogue = rogue_new" "}"), # Map where all inames match exactly one domain but there's also a # rogue dim isl.BasicMap("[nx,nt] -> {[t, y, x, z, rogue] -> " "[t_new, y_new, x_new, z_new, rogue_new]: " "y = y_new and t = t_new and x = x_new and z = z_new " "and rogue = rogue_new" "}"), # Map where no inames match any domain isl.BasicMap("[nx,nt] -> {[rogue] -> [rogue_new]: " "rogue = rogue_new" "}"), ] for transform_map in test_maps: try: knl = lp.map_domain(knl, transform_map) raise AssertionError() except LoopyError as err: assert ("was not applicable to any domain. " "Transform map must be applicable to exactly one domain." in str(err)) # }}} # {{{ Make sure there's an error if we try to map inames in priorities knl = ref_knl knl = lp.prioritize_loops(knl, "y, z") knl = lp.prioritize_loops(knl, "x, z") try: transform_map = isl.BasicMap("[nx,nt] -> {[t, y] -> [t_new, y_new]: " "y = y_new and t = t_new }") knl = lp.map_domain(knl, transform_map) raise AssertionError() except ValueError as err: assert ("Loop priority ('y', 'z') contains iname(s) " "transformed by map" in str(err)) # }}} # {{{ Make sure we error when stmt.within_inames contains at least one but # not all mapped inames # {{{ Make potentially problematic kernel knl = lp.make_kernel( [ "[n, m] -> { [i, j]: 0 <= i < n and 0 <= j < m }", "[ell] -> { [k]: 0 <= k < ell }", ], """ for i <>t0 = i {id=stmt0} for j <>t1 = j {id=stmt1, dep=stmt0} end <>t2 = i + 1 {id=stmt2, dep=stmt1} end for k <>t3 = k {id=stmt3, dep=stmt2} end """, lang_version=(2018, 2), ) # }}} # This should fail: try: transform_map = isl.BasicMap("[n, m] -> {[i, j] -> [i_new, j_new]: " "i_new = i + j and j_new = 2 + i }") knl = lp.map_domain(knl, transform_map) raise AssertionError() except LoopyError as err: assert ("Statements must be within all or none of the mapped inames" in str(err)) # This should succeed: transform_map = isl.BasicMap("[n, m] -> {[i] -> [i_new]: i_new = i + 2 }") knl = lp.map_domain(knl, transform_map)
def test_map_domain_vs_split_iname(ctx_factory): # {{{ Make kernel knl = lp.make_kernel( [ "[nx,nt] -> {[x, t]: 0 <= x < nx and 0 <= t < nt}", "[ni] -> {[i]: 0 <= i < ni}", ], """ a[x,t] = b[x,t] {id=stmta} c[x,t] = d[x,t] {id=stmtc} e[i] = f[i] """, lang_version=(2018, 2), ) knl = lp.add_and_infer_dtypes(knl, {"b,d,f": np.float32}) ref_knl = knl # }}} # {{{ Apply domain change mapping knl_map_dom = ref_knl # Create map_domain mapping: import islpy as isl transform_map = isl.BasicMap("[nt] -> {[t] -> [t_outer, t_inner]: " "0 <= t_inner < 32 and " "32*t_outer + t_inner = t and " "0 <= 32*t_outer + t_inner < nt}") # Call map_domain to transform kernel knl_map_dom = lp.map_domain(knl_map_dom, transform_map) # Prioritize loops (prio should eventually be updated in map_domain?) loop_priority = "x, t_outer, t_inner" knl_map_dom = lp.prioritize_loops(knl_map_dom, loop_priority) # Get a linearization proc_knl_map_dom = lp.preprocess_kernel(knl_map_dom) lin_knl_map_dom = lp.get_one_linearized_kernel( proc_knl_map_dom["loopy_kernel"], proc_knl_map_dom.callables_table) # }}} # {{{ Split iname and see if we get the same result knl_split_iname = ref_knl knl_split_iname = lp.split_iname(knl_split_iname, "t", 32) knl_split_iname = lp.prioritize_loops(knl_split_iname, loop_priority) proc_knl_split_iname = lp.preprocess_kernel(knl_split_iname) lin_knl_split_iname = lp.get_one_linearized_kernel( proc_knl_split_iname["loopy_kernel"], proc_knl_split_iname.callables_table) for d_map_domain, d_split_iname in zip( knl_map_dom["loopy_kernel"].domains, knl_split_iname["loopy_kernel"].domains): d_map_domain_aligned = _ensure_dim_names_match_and_align( d_map_domain, d_split_iname) assert d_map_domain_aligned == d_split_iname for litem_map_domain, litem_split_iname in zip( lin_knl_map_dom.linearization, lin_knl_split_iname.linearization): assert litem_map_domain == litem_split_iname # Can't easily compare instructions because equivalent subscript # expressions may have different orders lp.auto_test_vs_ref(proc_knl_split_iname, ctx_factory(), proc_knl_map_dom, parameters={ "nx": 128, "nt": 128, "ni": 128 })